From 0bc4e7cda61f9158eed68c9866739e7fb361cde5 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sun, 7 Jan 2024 16:13:01 +0100 Subject: [PATCH] Fix inc/mov of absolute values --- oscar64/Declaration.cpp | 21 ++++++++++++++++++ oscar64/Declaration.h | 1 + oscar64/Emulator.cpp | 16 +++++++------- oscar64/InterCodeGenerator.cpp | 39 ++++++++++++++++++--------------- oscar64/NativeCodeGenerator.cpp | 38 ++++++++++++++++++++++---------- oscar64/Parser.cpp | 3 +++ 6 files changed, 80 insertions(+), 38 deletions(-) diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 04d6a9d..dd0ed8d 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -1006,6 +1006,27 @@ int Declaration::Stride(void) const return 1; } +int Declaration::Alignment(void) const +{ + if (mType == DT_TYPE_ARRAY) + return mBase->Alignment(); + else if (mType == DT_TYPE_STRUCT) + { + int alignment = 0; + Declaration* dec = mParams; + while (dec) + { + alignment |= dec->mBase->Alignment() - 1; + dec = dec->mNext; + } + return alignment + 1; + } + else if (mType == DT_TYPE_INTEGER || mType == DT_TYPE_FLOAT || mType == DT_TYPE_POINTER) + return mSize; + else + return 1; +} + Declaration* Declaration::BuildConstPointer(const Location& loc) { Declaration* pdec = new Declaration(loc, DT_TYPE_POINTER); diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index ed6e699..f4accaa 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -347,6 +347,7 @@ public: const Ident* FullIdent(void); int Stride(void) const; + int Alignment(void) const; }; void InitDeclarations(void); diff --git a/oscar64/Emulator.cpp b/oscar64/Emulator.cpp index bc30247..1e4dd7f 100644 --- a/oscar64/Emulator.cpp +++ b/oscar64/Emulator.cpp @@ -579,27 +579,27 @@ int Emulator::Emulate(int startIP, int trace) case ASMIM_ZERO_PAGE: addr = mMemory[mIP++]; if (trace & 2) - printf("%04x : %04x %02x %02x __ %s $%02x (A:%02x X:%02x Y:%02x P:%02x S:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr, mRegA, mRegX, mRegY, mRegP, mRegS); + printf("%04x : %04x %02x %02x __ %s $%02x (A:%02x X:%02x Y:%02x P:%02x S:%02x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr, mRegA, mRegX, mRegY, mRegP, mRegS, mMemory[addr]); mCycles[ip] += 3; break; case ASMIM_ZERO_PAGE_X: taddr = mMemory[mIP++]; addr = (taddr + mRegX) & 0xff; if (trace & 2) - printf("%04x : %04x %02x %02x __ %s $%02x,x (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr); + printf("%04x : %04x %02x %02x __ %s $%02x,x (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr, mMemory[addr]); mCycles[ip] += 3; break; case ASMIM_ZERO_PAGE_Y: taddr = mMemory[mIP++]; addr = (taddr + mRegY) & 0xff; if (trace & 2) - printf("%04x : %04x %02x %02x __ %s $%02x,y (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr); + printf("%04x : %04x %02x %02x __ %s $%02x,y (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr, mMemory[addr]); mCycles[ip] += 3; break; case ASMIM_ABSOLUTE: addr = mMemory[mIP] + 256 * mMemory[mIP + 1]; if (trace & 2) - printf("%04x : %04x %02x %02x %02x %s $%04x (A:%02x X:%02x Y:%02x P:%02x S:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr, mRegA, mRegX, mRegY, mRegP, mRegS); + printf("%04x : %04x %02x %02x %02x %s $%04x (A:%02x X:%02x Y:%02x P:%02x S:%02x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr, mRegA, mRegX, mRegY, mRegP, mRegS, mMemory[addr]); mIP += 2; mCycles[ip] += 4; break; @@ -607,7 +607,7 @@ int Emulator::Emulate(int startIP, int trace) taddr = mMemory[mIP] + 256 * mMemory[mIP + 1]; addr = (taddr + mRegX) & 0xffff; if (trace & 2) - printf("%04x : %04x %02x %02x %02x %s $%04x,x (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr); + printf("%04x : %04x %02x %02x %02x %s $%04x,x (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr, mMemory[addr]); mIP += 2; mCycles[ip] += 5; break; @@ -615,7 +615,7 @@ int Emulator::Emulate(int startIP, int trace) taddr = mMemory[mIP] + 256 * mMemory[mIP + 1]; addr = (taddr + mRegY) & 0xffff; if (trace & 2) - printf("%04x : %04x %02x %02x %02x %s $%04x,y (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr); + printf("%04x : %04x %02x %02x %02x %s $%04x,y (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr, mMemory[addr]); mIP += 2; mCycles[ip] += 5; break; @@ -631,14 +631,14 @@ int Emulator::Emulate(int startIP, int trace) taddr = (mMemory[mIP++] + mRegX) & 0xff; addr = mMemory[taddr] + 256 * mMemory[taddr + 1]; if (trace & 2) - printf("%04x : %04x %02x %02x __ %s ($%02x,x) (A:%02x X:%02x Y:%02x P:%02x S:%02x %02x %04x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], mMemory[ip + 1], mRegA, mRegX, mRegY, mRegP, mRegS, taddr, addr); + printf("%04x : %04x %02x %02x __ %s ($%02x,x) (A:%02x X:%02x Y:%02x P:%02x S:%02x %02x %04x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], mMemory[ip + 1], mRegA, mRegX, mRegY, mRegP, mRegS, taddr, addr, mMemory[addr]); mCycles[ip] += 6; break; case ASMIM_INDIRECT_Y: taddr = mMemory[mIP++]; addr = (mMemory[taddr] + 256 * mMemory[taddr + 1] + mRegY) & 0xffff; if (trace & 2) - printf("%04x : %04x %02x %02x __ %s ($%02x),y (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr); + printf("%04x : %04x %02x %02x __ %s ($%02x),y (A:%02x X:%02x Y:%02x P:%02x S:%02x %04x M:%02x)\n", iip, ip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], taddr, mRegA, mRegX, mRegY, mRegP, mRegS, addr, mMemory[addr]); mCycles[ip] += 6; break; case ASMIM_RELATIVE: diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index d7dfbc1..819a83f 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -5203,27 +5203,30 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod Declaration* pdec = dec->mBase->mParams; while (pdec) { - int start = pdec->mVarIndex + BC_REG_FPARAMS, end = start + pdec->mSize; - if (start < BC_REG_FPARAMS_END) + if (!(pdec->mFlags & DTF_FPARAM_UNUSED)) { - if (end > BC_REG_FPARAMS_END) - end = BC_REG_FPARAMS_END; + int start = pdec->mVarIndex + BC_REG_FPARAMS, end = start + pdec->mSize; + if (start < BC_REG_FPARAMS_END) + { + if (end > BC_REG_FPARAMS_END) + end = BC_REG_FPARAMS_END; - int i = 0; - while (i < dec->mLinkerObject->mNumTemporaries && (dec->mLinkerObject->mTemporaries[i] > end || dec->mLinkerObject->mTemporaries[i] + dec->mLinkerObject->mTempSizes[i] < start)) - i++; - if (i < dec->mLinkerObject->mNumTemporaries) - { - if (dec->mLinkerObject->mTemporaries[i] > start) + int i = 0; + while (i < dec->mLinkerObject->mNumTemporaries && (dec->mLinkerObject->mTemporaries[i] > end || dec->mLinkerObject->mTemporaries[i] + dec->mLinkerObject->mTempSizes[i] < start)) + i++; + if (i < dec->mLinkerObject->mNumTemporaries) + { + if (dec->mLinkerObject->mTemporaries[i] > start) + dec->mLinkerObject->mTemporaries[i] = start; + if (dec->mLinkerObject->mTemporaries[i] + dec->mLinkerObject->mTempSizes[i] < end) + dec->mLinkerObject->mTempSizes[i] = end - dec->mLinkerObject->mTemporaries[i]; + } + else + { dec->mLinkerObject->mTemporaries[i] = start; - if (dec->mLinkerObject->mTemporaries[i] + dec->mLinkerObject->mTempSizes[i] < end) - dec->mLinkerObject->mTempSizes[i] = end - dec->mLinkerObject->mTemporaries[i]; - } - else - { - dec->mLinkerObject->mTemporaries[i] = start; - dec->mLinkerObject->mTempSizes[i] = end - start; - dec->mLinkerObject->mNumTemporaries++; + dec->mLinkerObject->mTempSizes[i] = end - start; + dec->mLinkerObject->mNumTemporaries++; + } } } pdec = pdec->mNext; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index b82173c..85162fb 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -31369,7 +31369,20 @@ bool NativeCodeBasicBlock::GlobalValueForwarding(NativeCodeProcedure* proc, bool for (int i = 0; i < mIns.Size(); i++) { AsmInsType carryop; - +#if 1 + if (i + 1 < mIns.Size() && + mIns[i].mType == ASMIT_INC && mIns[i].mMode == ASMIM_ABSOLUTE && + mIns[i + 1].mType == ASMIT_LDA && mIns[i].SameEffectiveAddress(mIns[i + 1]) && + mDataSet.mRegs[CPU_REG_A].mMode == NRDM_ABSOLUTE && + mDataSet.mRegs[CPU_REG_A].mLinkerObject == mIns[i].mLinkerObject && + mDataSet.mRegs[CPU_REG_A].mValue == mIns[i].mAddress) + { + mIns[i + 1].mType = ASMIT_STA; + mIns[i + 0].mType = ASMIT_ADC; mIns[i + 0].mMode = ASMIM_IMMEDIATE; mIns[i + 0].mAddress = 1; + mIns.Insert(i, NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_CLC)); + changed = true; + } +#endif if (mIns[i].ValueForwarding(mDataSet, carryop, true, final, proc->mFastCallBase)) changed = true; if (carryop != ASMIT_NOP) @@ -40765,7 +40778,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass } else if ( (mIns[i + 0].mType == ASMIT_INC || mIns[i + 0].mType == ASMIT_DEC) && - (mIns[i + 0].mMode == ASMIM_ZERO_PAGE || mIns[i + 0].mMode == ASMIM_ABSOLUTE) && + mIns[i + 0].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].SameEffectiveAddress(mIns[i + 0]) && !(mIns[i + 1].mLive & LIVE_MEM) && mIns[i + 2].mType == ASMIT_STA && !(mIns[i + 2].mLive & LIVE_CPU_REG_A) && (mIns[i + 2].mMode == ASMIM_ZERO_PAGE || mIns[i + 2].mMode == ASMIM_ABSOLUTE) && @@ -40981,7 +40994,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass HasAsmInstructionMode(ASMIT_INC, mIns[i + 0].mMode) && (mIns[i + 3].mLive & LIVE_CPU_REG_C) == 0) { - mIns[i + 0].mType = ASMIT_INC; + mIns[i + 0].mType = ASMIT_INC; mIns[i + 0].mLive |= LIVE_MEM; mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 3].mType = ASMIT_LDA; mIns[i + 3].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_Z; @@ -40992,7 +41005,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass HasAsmInstructionMode(ASMIT_DEC, mIns[i + 0].mMode) && (mIns[i + 3].mLive & LIVE_CPU_REG_C) == 0) { - mIns[i + 0].mType = ASMIT_DEC; + mIns[i + 0].mType = ASMIT_DEC; mIns[i + 0].mLive |= LIVE_MEM; mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 3].mType = ASMIT_LDA; mIns[i + 3].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_Z; @@ -41004,7 +41017,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass (mIns[i + 3].mLive & LIVE_CPU_REG_C) == 0) { mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; - mIns[i + 1].mType = ASMIT_INC; + mIns[i + 1].mType = ASMIT_INC; mIns[i + 1].mLive |= LIVE_MEM; mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 3].mType = ASMIT_LDA; mIns[i + 3].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_Z; progress = true; @@ -41015,7 +41028,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass (mIns[i + 3].mLive & LIVE_CPU_REG_C) == 0) { mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; - mIns[i + 1].mType = ASMIT_DEC; + mIns[i + 1].mType = ASMIT_DEC; mIns[i + 1].mLive |= LIVE_MEM; mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 3].mType = ASMIT_LDA; mIns[i + 3].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_Z; progress = true; @@ -41026,7 +41039,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass HasAsmInstructionMode(ASMIT_DEC, mIns[i + 0].mMode) && (mIns[i + 3].mLive & LIVE_CPU_REG_C) == 0) { - mIns[i + 0].mType = ASMIT_DEC; + mIns[i + 0].mType = ASMIT_DEC; mIns[i + 0].mLive |= LIVE_MEM; mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 3].mType = ASMIT_LDA; mIns[i + 3].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_Z; @@ -41037,7 +41050,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass HasAsmInstructionMode(ASMIT_INC, mIns[i + 0].mMode) && (mIns[i + 3].mLive & LIVE_CPU_REG_C) == 0) { - mIns[i + 0].mType = ASMIT_INC; + mIns[i + 0].mType = ASMIT_INC; mIns[i + 0].mLive |= LIVE_MEM; mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 3].mType = ASMIT_LDA; mIns[i + 3].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_Z; @@ -41049,7 +41062,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass (mIns[i + 3].mLive & LIVE_CPU_REG_C) == 0) { mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; - mIns[i + 1].mType = ASMIT_DEC; + mIns[i + 1].mType = ASMIT_DEC; mIns[i + 1].mLive |= LIVE_MEM; mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 3].mType = ASMIT_LDA; mIns[i + 3].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_Z; progress = true; @@ -41060,7 +41073,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass (mIns[i + 3].mLive & LIVE_CPU_REG_C) == 0) { mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; - mIns[i + 1].mType = ASMIT_INC; + mIns[i + 1].mType = ASMIT_INC; mIns[i + 1].mLive |= LIVE_MEM; mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 3].mType = ASMIT_LDA; mIns[i + 3].mLive |= LIVE_CPU_REG_A | LIVE_CPU_REG_Z; progress = true; @@ -45171,7 +45184,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) { mInterProc = proc; - CheckFunc = !strcmp(mInterProc->mIdent->mString, "player_move"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "check"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; @@ -45924,6 +45937,7 @@ void NativeCodeProcedure::Optimize(void) } while (changed && t < 20); #endif + BuildDataFlowSets(); ResetVisited(); mEntryBlock->RemoveUnusedResultInstructions(); @@ -45972,12 +45986,12 @@ void NativeCodeProcedure::Optimize(void) #if 1 + ResetVisited(); if (mEntryBlock->PeepHoleOptimizer(this, step)) changed = true; #endif - if (step == 2) { ResetVisited(); diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 0cae9ec..700f925 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -4513,6 +4513,9 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex if (mScope->mLevel < SLEVEL_FUNCTION || (ndec->mFlags & DTF_STATIC)) { + if (ndec->mSize >= 256) + ndec->mAlignment = ndec->mBase->Alignment(); + ndec->mFlags |= DTF_GLOBAL; ndec->mVarIndex = -1; }