diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index 3957890..5866ca7 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -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) diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index a630f44..81af7d1 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -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")); diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index e5a8f9d..65cb488 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -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; diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 211ff62..8e5dbf5 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -101,6 +101,8 @@ enum InterOperator IA_CMPLU, IA_FLOAT2INT, IA_INT2FLOAT, + IA_FLOAT2UINT, + IA_UINT2FLOAT, IA_EXT8TO16U, IA_EXT8TO32U, diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index c994a36..5bedcaf 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -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; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index da0a2a2..22bd818 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -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