From 4538f0295d4cff2e3f2e404110b9291f2cbb8bd8 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 20 Mar 2022 21:33:58 +0100 Subject: [PATCH] Fix byte to long conversion --- oscar64/ByteCodeGenerator.cpp | 40 +++++++++++++++++++++++++- oscar64/InterCode.cpp | 21 ++++++++++---- oscar64/InterCodeGenerator.cpp | 27 ++++++++++++++++++ oscar64/NativeCodeGenerator.cpp | 50 ++++++++++++++++++++++++++++++++- 4 files changed, 131 insertions(+), 7 deletions(-) diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index 14530f2..71340ee 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -3664,6 +3664,44 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]; mIns.Push(sins); } break; + + + case IA_EXT8TO32S: + { + ByteCodeInstruction lins(BC_LOAD_REG_8); + lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; + lins.mRegisterFinal = ins->mSrc[0].mFinal; + mIns.Push(lins); + + ByteCodeInstruction cins0(BC_CONV_I8_I16); + cins0.mRegister = BC_REG_ACCU; + mIns.Push(cins0); + + ByteCodeInstruction cins1(BC_CONV_I16_I32); + cins1.mRegister = 0; + mIns.Push(cins1); + + ByteCodeInstruction sins(BC_STORE_REG_32); + sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]; + mIns.Push(sins); + } break; + + case IA_EXT8TO32U: + { + ByteCodeInstruction lins(BC_LOAD_REG_8); + lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; + lins.mRegisterFinal = ins->mSrc[0].mFinal; + mIns.Push(lins); + + ByteCodeInstruction cins(BC_CONV_U16_U32); + cins.mRuntime = "lextu16"; + cins.mRegister = 0; + mIns.Push(cins); + + ByteCodeInstruction sins(BC_STORE_REG_32); + sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp]; + mIns.Push(sins); + } break; } } @@ -6300,11 +6338,11 @@ void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure entryBlock->Compile(proc, this, proc->mBlocks[0]); -#if 1 bool progress = false; entryBlock->mLocked = true; exitBlock->mLocked = true; +#if 1 int phase = 0; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index fe11613..a8b7f25 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -6379,13 +6379,24 @@ void InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray& { int j = 0, k = 0; - while (j < mLoadStoreInstructions.Size()) - { - if (!CollidingMem(ins->mSrc[1], mLoadStoreInstructions[j])) - mLoadStoreInstructions[k++] = mLoadStoreInstructions[j]; + while (j < mLoadStoreInstructions.Size() && !SameMem(ins->mSrc[1], mLoadStoreInstructions[j])) j++; + + if (!ins->mVolatile && j < mLoadStoreInstructions.Size() && mLoadStoreInstructions[j]->mCode == IC_LOAD && ins->mSrc[0].mTemp == mLoadStoreInstructions[j]->mDst.mTemp) + { + ins->mCode = IC_NONE; + ins->mNumOperands = 0; + } + else + { + while (j < mLoadStoreInstructions.Size()) + { + if (!CollidingMem(ins->mSrc[1], mLoadStoreInstructions[j])) + mLoadStoreInstructions[k++] = mLoadStoreInstructions[j]; + j++; + } + mLoadStoreInstructions.SetSize(k); } - mLoadStoreInstructions.SetSize(k); if (!ins->mVolatile) nins = ins; diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index d576073..c81f203 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -179,6 +179,33 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p stemp = xins->mDst.mTemp; } } + else if (v.mType->mSize == 1 && type->mSize == 4) + { + if (v.mType->mFlags & DTF_SIGNED) + { + InterInstruction* xins = new InterInstruction(); + xins->mCode = IC_CONVERSION_OPERATOR; + xins->mOperator = IA_EXT8TO32S; + xins->mSrc[0].mType = IT_INT8; + xins->mSrc[0].mTemp = stemp; + xins->mDst.mType = IT_INT32; + xins->mDst.mTemp = proc->AddTemporary(IT_INT32); + block->Append(xins); + stemp = xins->mDst.mTemp; + } + else + { + InterInstruction* xins = new InterInstruction(); + xins->mCode = IC_CONVERSION_OPERATOR; + xins->mOperator = IA_EXT8TO32U; + xins->mSrc[0].mType = IT_INT8; + xins->mSrc[0].mTemp = stemp; + xins->mDst.mType = IT_INT32; + xins->mDst.mTemp = proc->AddTemporary(IT_INT32); + block->Append(xins); + stemp = xins->mDst.mTemp; + } + } v.mTemp = stemp; v.mType = type; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 6cedba7..6d69416 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -6576,7 +6576,7 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p case IA_AND: case IA_XOR: { - if (ins->mOperator == IA_ADD && ( + if (ins->mOperator == IA_ADD && InterTypeSize[ins->mDst.mType] == 1 && ( ins->mSrc[0].mTemp < 0 && ins->mSrc[0].mIntConst == 1 && !sins1 && ins->mSrc[1].mTemp == ins->mDst.mTemp || ins->mSrc[1].mTemp < 0 && ins->mSrc[1].mIntConst == 1 && !sins0 && ins->mSrc[0].mTemp == ins->mDst.mTemp)) { @@ -7898,6 +7898,29 @@ void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, NativeCod mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 2)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 3)); break; + case IA_EXT8TO32S: + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + if (ins->mSrc[0].mTemp != ins->mDst.mTemp) + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0x00)); + mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 3)); + break; + case IA_EXT8TO32U: + if (ins->mSrc[0].mTemp != ins->mDst.mTemp) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp])); + } + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 3)); + break; } } @@ -17111,6 +17134,19 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 0].mType = ASMIT_LSR; progress = true; } + else if ( + mIns[i + 0].IsShift() && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && + !mIns[i + 1].ReferencesAccu() && (mIns[i + 1].mMode != ASMIM_ZERO_PAGE || mIns[i + 1].mAddress != mIns[i + 0].mAddress) && + mIns[i + 2].mType == ASMIT_LDA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress && !(mIns[i + 2].mLive & (LIVE_MEM | LIVE_CPU_REG_Z))) + { + NativeCodeInstruction ins = mIns[i + 2]; + mIns.Remove(i + 2); + + mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_A; + mIns[i + 1].mLive |= LIVE_CPU_REG_A; + mIns.Insert(i, ins); + progress = true; + } #if 1 @@ -17962,6 +17998,18 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass progress = true; } } + else if ( + mIns[i + 0].mType == ASMIT_STA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && + mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ABSOLUTE) + { + proc->ResetPatched(); + if (CheckSingleUseGlobalLoad(mIns[i + 0].mAddress, i + 2, mIns[i + 1], 2)) + { + proc->ResetPatched(); + if (PatchSingleUseGlobalLoad(mIns[i + 0].mAddress, i + 2, mIns[i + 1])) + progress = true; + } + } } if (i + 5 < mIns.Size())