Fix unsigend int to/from float conversion

This commit is contained in:
drmortalwombat 2022-11-19 10:58:44 +01:00
parent 74f93ca4fb
commit c6d0f44364
6 changed files with 132 additions and 7 deletions

View File

@ -3568,7 +3568,6 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter
mIns.Push(lins);
ByteCodeInstruction bins(BC_CONV_F32_I16);
// ByteCodeInstruction bins(ins->mDst.mType == IT_SIGNED ? BC_CONV_F32_I16 : BC_CONV_F32_U16);
mIns.Push(bins);
ByteCodeInstruction sins(BC_STORE_REG_16);
@ -3584,7 +3583,6 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter
mIns.Push(lins);
ByteCodeInstruction bins(BC_CONV_I16_F32);
// ByteCodeInstruction bins(ins.mSType[0] == IT_SIGNED ? BC_CONV_I16_F32 : BC_CONV_U16_F32);
mIns.Push(bins);
ByteCodeInstruction sins(BC_STORE_REG_32);
@ -3592,6 +3590,37 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter
mIns.Push(sins);
} break;
case IA_FLOAT2UINT:
{
ByteCodeInstruction lins(BC_LOAD_REG_32);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
lins.mRegisterFinal = ins->mSrc[0].mFinal;
mIns.Push(lins);
ByteCodeInstruction bins(BC_CONV_F32_U16);
mIns.Push(bins);
ByteCodeInstruction sins(BC_STORE_REG_16);
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
mIns.Push(sins);
} break;
case IA_UINT2FLOAT:
{
ByteCodeInstruction lins(BC_LOAD_REG_16);
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
lins.mRegisterFinal = ins->mSrc[0].mFinal;
mIns.Push(lins);
ByteCodeInstruction bins(BC_CONV_U16_F32);
mIns.Push(bins);
ByteCodeInstruction sins(BC_STORE_REG_32);
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
mIns.Push(sins);
} break;
case IA_EXT8TO16S:
{
if (ins->mSrc[0].mTemp == ins->mDst.mTemp)

View File

@ -288,7 +288,9 @@ bool Compiler::GenerateCode(void)
RegisterRuntime(loc, Ident::Unique("ffloor"));
RegisterRuntime(loc, Ident::Unique("fceil"));
RegisterRuntime(loc, Ident::Unique("ftoi"));
RegisterRuntime(loc, Ident::Unique("ftou"));
RegisterRuntime(loc, Ident::Unique("ffromi"));
RegisterRuntime(loc, Ident::Unique("ffromu"));
RegisterRuntime(loc, Ident::Unique("fcmp"));
RegisterRuntime(loc, Ident::Unique("bcexec"));
RegisterRuntime(loc, Ident::Unique("jmpaddr"));

View File

@ -771,6 +771,20 @@ static void ConversionConstantFold(InterInstruction * ins, const InterOperand &
ins->mSrc[0].mTemp = -1;
ins->mNumOperands = 0;
break;
case IA_UINT2FLOAT:
ins->mCode = IC_CONSTANT;
ins->mConst.mFloatConst = (double)((uint16)cop.mIntConst);
ins->mConst.mType = IT_FLOAT;
ins->mSrc[0].mTemp = -1;
ins->mNumOperands = 0;
break;
case IA_FLOAT2UINT:
ins->mCode = IC_CONSTANT;
ins->mConst.mIntConst = (int)(cop.mFloatConst);
ins->mConst.mType = IT_INT16;
ins->mSrc[0].mTemp = -1;
ins->mNumOperands = 0;
break;
case IA_EXT8TO16S:
ins->mCode = IC_CONSTANT;
ins->mConst.mIntConst = (int8)(cop.mIntConst);
@ -2096,6 +2110,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
else if (ins->mSrc[1].mTemp >= 0 && tvalue[ins->mSrc[1].mTemp] && tvalue[ins->mSrc[1].mTemp]->mCode == IC_CONVERSION_OPERATOR &&
ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONVERSION_OPERATOR &&
tvalue[ins->mSrc[1].mTemp]->mOperator != IA_FLOAT2INT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_INT2FLOAT &&
tvalue[ins->mSrc[1].mTemp]->mOperator != IA_FLOAT2UINT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_UINT2FLOAT &&
tvalue[ins->mSrc[0].mTemp]->mOperator == tvalue[ins->mSrc[1].mTemp]->mOperator)
{
ins->mSrc[0].mType = tvalue[ins->mSrc[0].mTemp]->mSrc[0].mType;
@ -2107,7 +2122,8 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
}
else if (ins->mSrc[1].mTemp >= 0 && tvalue[ins->mSrc[1].mTemp] && tvalue[ins->mSrc[1].mTemp]->mCode == IC_CONVERSION_OPERATOR &&
ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT &&
tvalue[ins->mSrc[1].mTemp]->mOperator != IA_FLOAT2INT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_INT2FLOAT)
tvalue[ins->mSrc[1].mTemp]->mOperator != IA_FLOAT2INT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_INT2FLOAT &&
tvalue[ins->mSrc[1].mTemp]->mOperator != IA_FLOAT2UINT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_UINT2FLOAT)
{
bool toconst = false;
int cvalue = 0;
@ -2241,7 +2257,8 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
}
else if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONVERSION_OPERATOR &&
ins->mSrc[1].mTemp >= 0 && tvalue[ins->mSrc[1].mTemp] && tvalue[ins->mSrc[1].mTemp]->mCode == IC_CONSTANT &&
tvalue[ins->mSrc[0].mTemp]->mOperator != IA_FLOAT2INT && tvalue[ins->mSrc[0].mTemp]->mOperator != IA_INT2FLOAT)
tvalue[ins->mSrc[0].mTemp]->mOperator != IA_FLOAT2INT && tvalue[ins->mSrc[0].mTemp]->mOperator != IA_INT2FLOAT &&
tvalue[ins->mSrc[0].mTemp]->mOperator != IA_FLOAT2UINT && tvalue[ins->mSrc[0].mTemp]->mOperator != IA_UINT2FLOAT)
{
bool toconst = false;
int cvalue = 0;

View File

@ -101,6 +101,8 @@ enum InterOperator
IA_CMPLU,
IA_FLOAT2INT,
IA_INT2FLOAT,
IA_FLOAT2UINT,
IA_UINT2FLOAT,
IA_EXT8TO16U,
IA_EXT8TO32U,

View File

@ -98,7 +98,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p
}
InterInstruction * cins = new InterInstruction(exp->mLocation, IC_CONVERSION_OPERATOR);
cins->mOperator = IA_INT2FLOAT;
cins->mOperator = (v.mType->mFlags & DTF_SIGNED) ? IA_INT2FLOAT : IA_UINT2FLOAT;
cins->mSrc[0].mType = IT_INT16;
cins->mSrc[0].mTemp = stemp;
cins->mDst.mType = IT_FLOAT;
@ -3020,7 +3020,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
}
}
ins->mOperator = IA_INT2FLOAT;
ins->mOperator = (vr.mType->mFlags & DTF_SIGNED) ? IA_INT2FLOAT : IA_UINT2FLOAT;
ins->mSrc[0].mType = IT_INT16;
ins->mSrc[0].mTemp = stemp;
ins->mDst.mType = InterTypeOf(exp->mLeft->mDecType);
@ -3030,7 +3030,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else if (exp->mLeft->mDecType->IsIntegerType() && vr.mType->mType == DT_TYPE_FLOAT)
{
vr = Dereference(proc, exp, block, vr);
ins->mOperator = IA_FLOAT2INT;
ins->mOperator = (exp->mLeft->mDecType->mFlags & DTF_SIGNED) ? IA_FLOAT2INT : IA_FLOAT2UINT;
ins->mSrc[0].mType = InterTypeOf(vr.mType);
ins->mSrc[0].mTemp = vr.mTemp;
ins->mDst.mType = IT_INT16;

View File

@ -3587,6 +3587,14 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
}
changed = true;
}
else if (final && data.mRegs[CPU_REG_A].mMode == NRDM_ABSOLUTE && data.mRegs[CPU_REG_A].mLinkerObject == mLinkerObject && data.mRegs[CPU_REG_A].mValue == mAddress)
{
mType = ASMIT_TAY;
mMode = ASMIM_IMPLIED;
data.mRegs[CPU_REG_Y] = data.mRegs[CPU_REG_A];
changed = true;
}
else
{
data.mRegs[CPU_REG_Y].mMode = NRDM_ABSOLUTE;
@ -3610,6 +3618,14 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
}
changed = true;
}
else if (final && data.mRegs[CPU_REG_A].mMode == NRDM_ABSOLUTE && data.mRegs[CPU_REG_A].mLinkerObject == mLinkerObject && data.mRegs[CPU_REG_A].mValue == mAddress)
{
mType = ASMIT_TAX;
mMode = ASMIM_IMPLIED;
data.mRegs[CPU_REG_X] = data.mRegs[CPU_REG_A];
changed = true;
}
else
{
data.mRegs[CPU_REG_X].mMode = NRDM_ABSOLUTE;
@ -9591,6 +9607,46 @@ void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, NativeCod
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 3));
} break;
case IA_FLOAT2UINT:
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("ftou")));
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_LOWER | NCIF_UPPER));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
} break;
case IA_UINT2FLOAT:
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("ffromu")));
mIns.Push(NativeCodeInstruction(ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_LOWER | NCIF_UPPER));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 3));
} break;
case IA_EXT8TO16S:
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
@ -14785,6 +14841,25 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void)
}
}
}
if (mTrueJump->mEntryRequiredRegs[CPU_REG_Y] && !mFalseJump->mEntryRequiredRegs[CPU_REG_Y] && mTrueJump->mNumEntries == 1 && !mTrueJump->mEntryRequiredRegs[CPU_REG_Z] ||
mFalseJump->mEntryRequiredRegs[CPU_REG_Y] && !mTrueJump->mEntryRequiredRegs[CPU_REG_Y] && mFalseJump->mNumEntries == 1 && !mFalseJump->mEntryRequiredRegs[CPU_REG_Z])
{
int i = mIns.Size();
while (i > 0 && !mIns[i - 1].ReferencesYReg())
i--;
if (i > 0 && mIns[i - 1].mType == ASMIT_LDY && !(mIns[i - 1].mLive & LIVE_CPU_REG_Z))
{
if (mIns[i - 1].mMode == ASMIM_IMMEDIATE || (mIns[i - 1].mMode == ASMIM_ZERO_PAGE && !ChangedOnPath(this, i, mIns.Size(), mIns[i - 1].mAddress)))
{
if (mTrueJump->mEntryRequiredRegs[CPU_REG_Y])
mTrueJump->mIns.Insert(0, mIns[i - 1]);
else
mFalseJump->mIns.Insert(0, mIns[i - 1]);
mIns.Remove(i - 1);
changed = true;
}
}
}
}
#endif