From 4ca77ba41a0a4dd52313d6c88f0f0837d5473d8c Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Wed, 22 Sep 2021 22:49:52 +0200 Subject: [PATCH] Byte operand sizes fixes and optimizations --- autotest/switchlooptest.c | 48 ++++ include/stdio.c | 2 +- oscar64/ByteCodeGenerator.cpp | 471 +++++++++++++++++--------------- oscar64/ByteCodeGenerator.h | 11 +- oscar64/InterCode.cpp | 19 +- oscar64/InterCodeGenerator.cpp | 2 + oscar64/NativeCodeGenerator.cpp | 152 ++++++++--- oscar64/NativeCodeGenerator.h | 1 + 8 files changed, 449 insertions(+), 257 deletions(-) create mode 100644 autotest/switchlooptest.c diff --git a/autotest/switchlooptest.c b/autotest/switchlooptest.c new file mode 100644 index 0000000..9c4c38c --- /dev/null +++ b/autotest/switchlooptest.c @@ -0,0 +1,48 @@ +#include +#include +#include + +int main(void) +{ + char text[14]; + + for(char i=0; i<12; i++) + { + switch (i) + { + case 0: + text[i] = 'H'; + break; + case 1: + text[i] = 'E'; + break; + case 2: + case 3: + case 9: + text[i] = 'L'; + break; + case 4: + case 7: + text[i] = 'O'; + break; + case 5: + text[i] = ' '; + break; + case 6: + text[i] = 'W'; + break; + case 8: + text[i] = 'R'; + break; + case 10: + text[i] = 'D'; + break; + default: + text[i] = 0; + } + } + + printf("<%s>\n", text); + + return 0; +} diff --git a/include/stdio.c b/include/stdio.c index a92edd8..3582946 100644 --- a/include/stdio.c +++ b/include/stdio.c @@ -287,7 +287,7 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print) { const char * p = fmt; char c; - int bi = 0; + char bi = 0; sinfo si; while (c = *p++) diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index 22d688c..0875475 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -47,6 +47,7 @@ ByteCodeInstruction::ByteCodeInstruction(ByteCode code) { } + bool ByteCodeInstruction::IsStore(void) const { return @@ -2506,241 +2507,259 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p this->Close(proc->CompileBlock(iproc, sblock->mTrueJump), nullptr, BC_JUMPS); } -void ByteCodeBasicBlock::PeepHoleOptimizer(void) + +bool ByteCodeBasicBlock::PeepHoleOptimizer(void) { - int accuReg = -1; + bool changed = false; - bool progress = false; - do { - progress = false; + if (!mVisited) + { + mVisited = true; - int i = 0; - int j = 0; - while (i < mIns.Size()) - { - if (mIns[i].mCode == BC_NOP) - ; - else + int accuReg = -1; + + bool progress = false; + do { + progress = false; + + int i = 0; + int j = 0; + while (i < mIns.Size()) { - if (i != j) - mIns[j] = mIns[i]; - j++; + if (mIns[i].mCode == BC_NOP) + ; + else + { + if (i != j) + mIns[j] = mIns[i]; + j++; + } + i++; } - i++; - } - mIns.SetSize(j); - - int accuTemp = -1, addrTemp = -1; + mIns.SetSize(j); - for (int i = 0; i < mIns.Size(); i++) - { - if (i + 2 < mIns.Size()) + int accuTemp = -1, addrTemp = -1; + + for (int i = 0; i < mIns.Size(); i++) { - if (mIns[i].mCode == BC_LOAD_LOCAL_16 && - mIns[i + 1].mCode == BC_LOAD_LOCAL_16 && mIns[i + 1].mRegister != BC_REG_ACCU && mIns[i + 1].mRegister != mIns[i].mRegister && - mIns[i + 2].mCode == BC_LOAD_REG_16 && mIns[i + 2].mRegister == mIns[i].mRegister && mIns[i + 2].mRegisterFinal) + if (i + 2 < mIns.Size()) { - mIns[i].mRegister = BC_REG_ACCU; - mIns[i + 2].mCode = BC_NOP; - progress = true; - } - else if (mIns[i].mCode == BC_STORE_REG_16 && - !mIns[i + 1].ChangesAccu() && mIns[i + 1].mRegister != mIns[i].mRegister && - mIns[i + 2].mCode == BC_LOAD_REG_16 && mIns[i].mRegister == mIns[i + 2].mRegister) - { - mIns[i + 2].mCode = BC_NOP; - if (mIns[i + 2].mRegisterFinal) + if (mIns[i].mCode == BC_LOAD_LOCAL_16 && + mIns[i + 1].mCode == BC_LOAD_LOCAL_16 && mIns[i + 1].mRegister != BC_REG_ACCU && mIns[i + 1].mRegister != mIns[i].mRegister && + mIns[i + 2].mCode == BC_LOAD_REG_16 && mIns[i + 2].mRegister == mIns[i].mRegister && mIns[i + 2].mRegisterFinal) + { + mIns[i].mRegister = BC_REG_ACCU; + mIns[i + 2].mCode = BC_NOP; + progress = true; + } + else if (mIns[i].mCode == BC_STORE_REG_16 && + !mIns[i + 1].ChangesAccu() && mIns[i + 1].mRegister != mIns[i].mRegister && + mIns[i + 2].mCode == BC_LOAD_REG_16 && mIns[i].mRegister == mIns[i + 2].mRegister) + { + mIns[i + 2].mCode = BC_NOP; + if (mIns[i + 2].mRegisterFinal) + mIns[i].mCode = BC_NOP; + } + else if (mIns[i].mCode == BC_STORE_REG_32 && + !mIns[i + 1].ChangesAccu() && mIns[i + 1].mRegister != mIns[i].mRegister && + mIns[i + 2].mCode == BC_LOAD_REG_32 && mIns[i].mRegister == mIns[i + 2].mRegister) + { + mIns[i + 2].mCode = BC_NOP; + if (mIns[i + 2].mRegisterFinal) + mIns[i].mCode = BC_NOP; + } + else if (mIns[i].mCode == BC_STORE_REG_16 && + !mIns[i + 1].ChangesAccu() && mIns[i + 1].mRegister != mIns[i].mRegister && + mIns[i + 2].IsStore() && mIns[i].mRegister == mIns[i + 2].mRegister && mIns[i + 2].mRegisterFinal) + { mIns[i].mCode = BC_NOP; - } - else if (mIns[i].mCode == BC_STORE_REG_32 && - !mIns[i + 1].ChangesAccu() && mIns[i + 1].mRegister != mIns[i].mRegister && - mIns[i + 2].mCode == BC_LOAD_REG_32 && mIns[i].mRegister == mIns[i + 2].mRegister) - { - mIns[i + 2].mCode = BC_NOP; - if (mIns[i + 2].mRegisterFinal) - mIns[i].mCode = BC_NOP; - } - else if (mIns[i].mCode == BC_STORE_REG_16 && - !mIns[i + 1].ChangesAccu() && mIns[i + 1].mRegister != mIns[i].mRegister && - mIns[i + 2].IsStore() && mIns[i].mRegister == mIns[i + 2].mRegister && mIns[i + 2].mRegisterFinal) - { - mIns[i].mCode = BC_NOP; - mIns[i + 2].mRegister = BC_REG_ACCU; - } - else if (mIns[i].mCode == BC_STORE_REG_16 && - !mIns[i + 1].ChangesAddr() && mIns[i + 1].mRegister != mIns[i].mRegister && - mIns[i + 2].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 2].mRegister && mIns[i + 2].mRegisterFinal) - { - mIns[i].mCode = BC_ADDR_REG; - mIns[i].mRegister = BC_REG_ACCU; - mIns[i + 2].mCode = BC_NOP; - } - else if ( - mIns[i + 2].mCode == BC_BINOP_ADDR_16 && - mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i + 1].mRegister != mIns[i + 2].mRegister && - mIns[i + 0].LoadsRegister(mIns[i + 2].mRegister) && mIns[i + 2].mRegisterFinal) - { - mIns[i + 0].mRegister = BC_REG_ACCU; - mIns[i + 1].mCode = mIns[i + 2].mCode; - mIns[i + 2].mCode = BC_NOP; - } - else if ( - mIns[i + 2].mCode == BC_BINOP_ADDR_16 && - mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i + 1].mRegister != mIns[i + 2].mRegister && - mIns[i + 0].mCode == BC_STORE_REG_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister && mIns[i + 2].mRegisterFinal) - { - mIns[i + 0].mCode = BC_NOP;; - mIns[i + 1].mCode = mIns[i + 2].mCode; - mIns[i + 2].mCode = BC_NOP; - } - else if (mIns[i].mCode == BC_STORE_REG_32 && - mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i + 1].mRegister != mIns[i + 2].mRegister && - mIns[i + 2].IsCommutative() && mIns[i].mRegister == mIns[i + 2].mRegister) - { - if (mIns[i + 2].mRegisterFinal) + mIns[i + 2].mRegister = BC_REG_ACCU; + } + else if (mIns[i].mCode == BC_STORE_REG_16 && + !mIns[i + 1].ChangesAddr() && mIns[i + 1].mRegister != mIns[i].mRegister && + mIns[i + 2].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 2].mRegister && mIns[i + 2].mRegisterFinal) + { + mIns[i].mCode = BC_ADDR_REG; + mIns[i].mRegister = BC_REG_ACCU; + mIns[i + 2].mCode = BC_NOP; + } + else if ( + mIns[i + 2].mCode == BC_BINOP_ADDR_16 && + mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i + 1].mRegister != mIns[i + 2].mRegister && + mIns[i + 0].LoadsRegister(mIns[i + 2].mRegister) && mIns[i + 2].mRegisterFinal) + { + mIns[i + 0].mRegister = BC_REG_ACCU; + mIns[i + 1].mCode = mIns[i + 2].mCode; + mIns[i + 2].mCode = BC_NOP; + } + else if ( + mIns[i + 2].mCode == BC_BINOP_ADDR_16 && + mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i + 1].mRegister != mIns[i + 2].mRegister && + mIns[i + 0].mCode == BC_STORE_REG_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister && mIns[i + 2].mRegisterFinal) + { + mIns[i + 0].mCode = BC_NOP;; + mIns[i + 1].mCode = mIns[i + 2].mCode; + mIns[i + 2].mCode = BC_NOP; + } + else if (mIns[i].mCode == BC_STORE_REG_32 && + mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i + 1].mRegister != mIns[i + 2].mRegister && + mIns[i + 2].IsCommutative() && mIns[i].mRegister == mIns[i + 2].mRegister) + { + if (mIns[i + 2].mRegisterFinal) + mIns[i + 0].mCode = BC_NOP; + mIns[i + 1].mCode = BC_NOP; + mIns[i + 2].mRegister = mIns[i + 1].mRegister; + mIns[i + 2].mRegisterFinal = mIns[i + 1].mRegisterFinal; + } + else if (mIns[i].mCode == BC_STORE_REG_16 && + mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i + 1].mRegister != mIns[i + 2].mRegister && + mIns[i + 2].IsCommutative() && mIns[i].mRegister == mIns[i + 2].mRegister) + { + if (mIns[i + 2].mRegisterFinal) + mIns[i + 0].mCode = BC_NOP; + mIns[i + 1].mCode = BC_NOP; + mIns[i + 2].mRegister = mIns[i + 1].mRegister; + mIns[i + 2].mRegisterFinal = mIns[i + 1].mRegisterFinal; + } + else if (mIns[i + 0].mCode == BC_STORE_REG_32 && + mIns[i + 2].mCode == BC_BINOP_CMP_F32 && mIns[i + 2].mRegister == mIns[i + 0].mRegister && mIns[i + 2].mRegisterFinal && + mIns[i + 1].LoadsRegister(BC_REG_ACCU) && i + 3 == mIns.Size()) + { + mIns[i + 1].mRegister = mIns[i + 0].mRegister; mIns[i + 0].mCode = BC_NOP; - mIns[i + 1].mCode = BC_NOP; - mIns[i + 2].mRegister = mIns[i + 1].mRegister; - mIns[i + 2].mRegisterFinal = mIns[i + 1].mRegisterFinal; + mBranch = TransposeBranchCondition(mBranch); + } + else if (mIns[i + 0].mCode == BC_LOAD_REG_16 && + mIns[i + 1].mCode == BC_STORE_REG_16 && + mIns[i + 2].mCode == BC_LOAD_REG_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister) + { + mIns[i + 2].mCode = BC_NOP; + } + else if (mIns[i + 0].mCode == BC_CONST_16 && mIns[i + 2].mCode == BC_CONST_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister && mIns[i + 0].mValue == mIns[i + 2].mValue && !mIns[i + 1].ChangesRegister(mIns[i + 0].mRegister)) + { + mIns[i + 2].mCode = BC_NOP; + } } - else if (mIns[i].mCode == BC_STORE_REG_16 && - mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i + 1].mRegister != mIns[i + 2].mRegister && - mIns[i + 2].IsCommutative() && mIns[i].mRegister == mIns[i + 2].mRegister) + if (i + 1 < mIns.Size()) { - if (mIns[i + 2].mRegisterFinal) - mIns[i + 0].mCode = BC_NOP; - mIns[i + 1].mCode = BC_NOP; - mIns[i + 2].mRegister = mIns[i + 1].mRegister; - mIns[i + 2].mRegisterFinal = mIns[i + 1].mRegisterFinal; - } - else if (mIns[i + 0].mCode == BC_STORE_REG_32 && - mIns[i + 2].mCode == BC_BINOP_CMP_F32 && mIns[i + 2].mRegister == mIns[i + 0].mRegister && mIns[i + 2].mRegisterFinal && - mIns[i + 1].LoadsRegister(BC_REG_ACCU) && i + 3 == mIns.Size()) - { - mIns[i + 1].mRegister = mIns[i + 0].mRegister; - mIns[i + 0].mCode = BC_NOP; - mBranch = TransposeBranchCondition(mBranch); - } - else if (mIns[i + 0].mCode == BC_LOAD_REG_16 && - mIns[i + 1].mCode == BC_STORE_REG_16 && - mIns[i + 2].mCode == BC_LOAD_REG_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister) - { - mIns[i + 2].mCode = BC_NOP; - } - else if (mIns[i + 0].mCode == BC_CONST_16 && mIns[i + 2].mCode == BC_CONST_16 && mIns[i + 0].mRegister == mIns[i + 2].mRegister && mIns[i + 0].mValue == mIns[i + 2].mValue && !mIns[i + 1].ChangesRegister(mIns[i + 0].mRegister)) - { - mIns[i + 2].mCode = BC_NOP; - } - } - if (i + 1 < mIns.Size()) - { - if (mIns[i].mCode == BC_STORE_REG_16 && mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i].mRegister == mIns[i + 1].mRegister) - { - mIns[i + 1].mCode = BC_NOP; - if (mIns[i + 1].mRegisterFinal) + if (mIns[i].mCode == BC_STORE_REG_16 && mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i].mRegister == mIns[i + 1].mRegister) + { + mIns[i + 1].mCode = BC_NOP; + if (mIns[i + 1].mRegisterFinal) + mIns[i].mCode = BC_NOP; + progress = true; + } + else if (mIns[i].mCode == BC_LOAD_REG_16 && mIns[i + 1].mCode == BC_STORE_REG_16 && mIns[i].mRegister == mIns[i + 1].mRegister) + { + mIns[i + 1].mCode = BC_NOP; + progress = true; + } + else if (mIns[i].mCode == BC_STORE_REG_32 && mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i].mRegister == mIns[i + 1].mRegister) + { + mIns[i + 1].mCode = BC_NOP; + if (mIns[i + 1].mRegisterFinal) + mIns[i].mCode = BC_NOP; + progress = true; + } + else if (mIns[i].mCode == BC_LOAD_REG_32 && mIns[i + 1].mCode == BC_STORE_REG_32 && mIns[i].mRegister == mIns[i + 1].mRegister) + { + mIns[i + 1].mCode = BC_NOP; + progress = true; + } + else if (mIns[i].mCode == BC_STORE_REG_16 && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal) + { + mIns[i].mCode = BC_ADDR_REG; + mIns[i].mRegister = BC_REG_ACCU; + mIns[i + 1].mCode = BC_NOP; + progress = true; + } + else if (mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i].LoadsRegister(mIns[i + 1].mRegister) && mIns[i + 1].mRegisterFinal) + { + mIns[i].mRegister = BC_REG_ACCU; + mIns[i + 1].mCode = BC_NOP; + progress = true; + } + else if (mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i].LoadsRegister(mIns[i + 1].mRegister) && mIns[i + 1].mRegisterFinal) + { + mIns[i].mRegister = BC_REG_ACCU; + mIns[i + 1].mCode = BC_NOP; + progress = true; + } + else if (mIns[i].mCode == BC_STORE_REG_16 && mIns[i + 1].StoresRegister(mIns[i].mRegister) && mIns[i + 1].mRegisterFinal) + { + mIns[i + 1].mRegister = BC_REG_ACCU; mIns[i].mCode = BC_NOP; - progress = true; - } - else if (mIns[i].mCode == BC_LOAD_REG_16 && mIns[i + 1].mCode == BC_STORE_REG_16 && mIns[i].mRegister == mIns[i + 1].mRegister) - { - mIns[i + 1].mCode = BC_NOP; - progress = true; - } - else if (mIns[i].mCode == BC_STORE_REG_32 && mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i].mRegister == mIns[i + 1].mRegister) - { - mIns[i + 1].mCode = BC_NOP; - if (mIns[i + 1].mRegisterFinal) + progress = true; + } + else if (mIns[i].mCode == BC_STORE_REG_32 && mIns[i + 1].StoresRegister(mIns[i].mRegister) && mIns[i + 1].mRegisterFinal) + { + mIns[i + 1].mRegister = BC_REG_ACCU; mIns[i].mCode = BC_NOP; - progress = true; + progress = true; + } + else if (mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i].LoadsRegister(mIns[i + 1].mRegister) && mIns[i + 1].mRegisterFinal) + { + mIns[i].mRegister = BC_REG_ACCU; + mIns[i + 1].mCode = BC_NOP; + progress = true; + } + else if (mIns[i].mCode == BC_LOAD_LOCAL_16 && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal) + { + mIns[i].mRegister = BC_REG_ADDR; + mIns[i + 1].mCode = BC_NOP; + progress = true; + } + else if (mIns[i].mCode == BC_LOAD_ABS_U8 && mIns[i + 1].mCode == BC_CONV_I8_I16 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal) + { + mIns[i].mCode = BC_LOAD_ABS_I8; + mIns[i + 1].mCode = BC_NOP; + progress = true; + } + else if (mIns[i].mCode == BC_LOAD_LOCAL_U8 && mIns[i + 1].mCode == BC_CONV_I8_I16 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal) + { + mIns[i].mCode = BC_LOAD_LOCAL_I8; + mIns[i + 1].mCode = BC_NOP; + progress = true; + } + else if (mIns[i].mCode == BC_LOAD_ADDR_U8 && mIns[i + 1].mCode == BC_CONV_I8_I16 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal) + { + mIns[i].mCode = BC_LOAD_ADDR_I8; + mIns[i + 1].mCode = BC_NOP; + progress = true; + } } - else if (mIns[i].mCode == BC_LOAD_REG_32 && mIns[i + 1].mCode == BC_STORE_REG_32 && mIns[i].mRegister == mIns[i + 1].mRegister) - { - mIns[i + 1].mCode = BC_NOP; - progress = true; - } - else if (mIns[i].mCode == BC_STORE_REG_16 && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal) - { - mIns[i].mCode = BC_ADDR_REG; - mIns[i].mRegister = BC_REG_ACCU; - mIns[i + 1].mCode = BC_NOP; - progress = true; - } - else if (mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i].LoadsRegister(mIns[i + 1].mRegister) && mIns[i + 1].mRegisterFinal) - { - mIns[i].mRegister = BC_REG_ACCU; - mIns[i + 1].mCode = BC_NOP; - progress = true; - } - else if (mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i].LoadsRegister(mIns[i + 1].mRegister) && mIns[i + 1].mRegisterFinal) - { - mIns[i].mRegister = BC_REG_ACCU; - mIns[i + 1].mCode = BC_NOP; - progress = true; - } - else if (mIns[i].mCode == BC_STORE_REG_16 && mIns[i + 1].StoresRegister(mIns[i].mRegister) && mIns[i + 1].mRegisterFinal) - { - mIns[i + 1].mRegister = BC_REG_ACCU; + + if ((mIns[i].mCode == BC_LOAD_REG_16 || mIns[i].mCode == BC_STORE_REG_16 || mIns[i].mCode == BC_LOAD_REG_32 || mIns[i].mCode == BC_STORE_REG_32) && accuTemp == mIns[i].mRegister) mIns[i].mCode = BC_NOP; - progress = true; - } - else if (mIns[i].mCode == BC_STORE_REG_32 && mIns[i + 1].StoresRegister(mIns[i].mRegister) && mIns[i + 1].mRegisterFinal) - { - mIns[i + 1].mRegister = BC_REG_ACCU; + if (mIns[i].mCode == BC_ADDR_REG && mIns[i].mRegister == addrTemp) mIns[i].mCode = BC_NOP; - progress = true; - } - else if (mIns[i + 1].mCode == BC_LOAD_REG_32 && mIns[i].LoadsRegister(mIns[i + 1].mRegister) && mIns[i + 1].mRegisterFinal) - { - mIns[i].mRegister = BC_REG_ACCU; - mIns[i + 1].mCode = BC_NOP; - progress = true; - } - else if (mIns[i].mCode == BC_LOAD_LOCAL_16 && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal) - { - mIns[i].mRegister = BC_REG_ADDR; - mIns[i + 1].mCode = BC_NOP; - progress = true; - } - else if (mIns[i].mCode == BC_LOAD_ABS_U8 && mIns[i + 1].mCode == BC_CONV_I8_I16 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal) - { - mIns[i].mCode = BC_LOAD_ABS_I8; - mIns[i + 1].mCode = BC_NOP; - progress = true; - } - else if (mIns[i].mCode == BC_LOAD_LOCAL_U8 && mIns[i + 1].mCode == BC_CONV_I8_I16 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal) - { - mIns[i].mCode = BC_LOAD_LOCAL_I8; - mIns[i + 1].mCode = BC_NOP; - progress = true; - } - else if (mIns[i].mCode == BC_LOAD_ADDR_U8 && mIns[i + 1].mCode == BC_CONV_I8_I16 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal) - { - mIns[i].mCode = BC_LOAD_ADDR_I8; - mIns[i + 1].mCode = BC_NOP; - progress = true; - } + + if (mIns[i].ChangesAccu()) + accuTemp = -1; + if (mIns[i].ChangesAddr()) + addrTemp = -1; + if (accuTemp != -1 && mIns[i].ChangesRegister(accuTemp)) + accuTemp = -1; + if (addrTemp != -1 && mIns[i].ChangesRegister(addrTemp)) + addrTemp = -1; + + if (mIns[i].mCode == BC_LOAD_REG_16 || mIns[i].mCode == BC_STORE_REG_16 || mIns[i].mCode == BC_LOAD_REG_32 || mIns[i].mCode == BC_STORE_REG_32) + accuTemp = mIns[i].mRegister; + if (mIns[i].mCode == BC_ADDR_REG && mIns[i].mRegister != BC_REG_ACCU) + addrTemp = mIns[i].mRegister; } - if ((mIns[i].mCode == BC_LOAD_REG_16 || mIns[i].mCode == BC_STORE_REG_16 || mIns[i].mCode == BC_LOAD_REG_32 || mIns[i].mCode == BC_STORE_REG_32) && accuTemp == mIns[i].mRegister) - mIns[i].mCode = BC_NOP; - if (mIns[i].mCode == BC_ADDR_REG && mIns[i].mRegister == addrTemp) - mIns[i].mCode = BC_NOP; + if (progress) + changed = true; + } while (progress); - if (mIns[i].ChangesAccu()) - accuTemp = -1; - if (mIns[i].ChangesAddr()) - addrTemp = -1; - if (accuTemp != -1 && mIns[i].ChangesRegister(accuTemp)) - accuTemp = -1; - if (addrTemp != -1 && mIns[i].ChangesRegister(addrTemp)) - addrTemp = -1; + if (mTrueJump && mTrueJump->PeepHoleOptimizer()) + changed = true; + if (mFalseJump && mFalseJump->PeepHoleOptimizer()) + changed = true; + } - if (mIns[i].mCode == BC_LOAD_REG_16 || mIns[i].mCode == BC_STORE_REG_16 || mIns[i].mCode == BC_LOAD_REG_32 || mIns[i].mCode == BC_STORE_REG_32) - accuTemp = mIns[i].mRegister; - if (mIns[i].mCode == BC_ADDR_REG && mIns[i].mRegister != BC_REG_ACCU) - addrTemp = mIns[i].mRegister; - } - } while (progress); + return changed; } void ByteCodeBasicBlock::Assemble(ByteCodeGenerator* generator) @@ -2749,8 +2768,6 @@ void ByteCodeBasicBlock::Assemble(ByteCodeGenerator* generator) { mAssembled = true; - PeepHoleOptimizer(); - for (int i = 0; i < mIns.Size(); i++) mIns[i].Assemble(generator, this); @@ -2987,6 +3004,7 @@ void ByteCodeBasicBlock::CalculateOffset(int& total) } ByteCodeProcedure::ByteCodeProcedure(void) + : mBlocks(nullptr) { } @@ -3000,13 +3018,16 @@ void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure { mID = proc->mID; - tblocks = new ByteCodeBasicBlock * [proc->mBlocks.Size()]; - for (int i = 0; i < proc->mBlocks.Size(); i++) + mNumBlocks = proc->mBlocks.Size(); + + tblocks = new ByteCodeBasicBlock * [mNumBlocks]; + for (int i = 0; i < mNumBlocks; i++) tblocks[i] = nullptr; int tempSave = proc->mTempSize > 16 ? proc->mTempSize - 16 : 0; entryBlock = new ByteCodeBasicBlock(); + mBlocks.Push(entryBlock); entryBlock->PutCode(generator, BC_ENTER); entryBlock->PutWord(proc->mLocalSize + 2 + tempSave); entryBlock->PutByte(tempSave); if (!proc->mLeafProcedure) @@ -3018,6 +3039,7 @@ void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure tblocks[0] = entryBlock; exitBlock = new ByteCodeBasicBlock(); + mBlocks.Push(exitBlock); if (!proc->mLeafProcedure) { @@ -3027,6 +3049,11 @@ void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure exitBlock->PutCode(generator, BC_RETURN); exitBlock->PutByte(tempSave); exitBlock->PutWord(proc->mLocalSize + 2 + tempSave); entryBlock->Compile(proc, this, proc->mBlocks[0]); + + bool progress = false; + ResetVisited(); + progress = entryBlock->PeepHoleOptimizer(); + entryBlock->Assemble(generator); int total; @@ -3049,12 +3076,20 @@ ByteCodeBasicBlock* ByteCodeProcedure::CompileBlock(InterCodeProcedure* iproc, I return tblocks[sblock->mIndex]; ByteCodeBasicBlock * block = new ByteCodeBasicBlock(); + mBlocks.Push(block); tblocks[sblock->mIndex] = block; block->Compile(iproc, this, sblock); return block; } +void ByteCodeProcedure::ResetVisited(void) +{ + for (int i = 0; i < mBlocks.Size(); i++) + { + mBlocks[i]->mVisited = false; + } +} ByteCodeGenerator::ByteCodeGenerator(Errors* errors, Linker* linker) : mErrors(errors), mLinker(linker) diff --git a/oscar64/ByteCodeGenerator.h b/oscar64/ByteCodeGenerator.h index dc41421..e94da56 100644 --- a/oscar64/ByteCodeGenerator.h +++ b/oscar64/ByteCodeGenerator.h @@ -176,6 +176,8 @@ public: bool StoresRegister(uint32 reg) const; bool IsCommutative(void) const; + + bool ValueForwarding(ByteCodeInstruction*& accuIns, ByteCodeInstruction*& addrIns); }; class ByteCodeBasicBlock @@ -192,7 +194,7 @@ public: GrowingArray mRelocations; int mOffset, mSize; - bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled; + bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mVisited; ByteCodeBasicBlock(void); @@ -230,7 +232,7 @@ public: void BinaryIntOperator(InterCodeProcedure* proc, const InterInstruction * ins, ByteCode code); void NumericConversion(InterCodeProcedure* proc, const InterInstruction * ins); - void PeepHoleOptimizer(void); + bool PeepHoleOptimizer(void); }; class ByteCodeGenerator; @@ -243,12 +245,15 @@ public: ByteCodeBasicBlock * entryBlock, * exitBlock; ByteCodeBasicBlock ** tblocks; + GrowingArray < ByteCodeBasicBlock*> mBlocks; - int mProgSize, mID; + int mProgSize, mID, mNumBlocks; void Compile(ByteCodeGenerator* generator, InterCodeProcedure* proc); ByteCodeBasicBlock * CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block); + void ResetVisited(void); + protected: ByteCodeDisassembler mDisassembler; }; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 6885926..d1311b9 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -1387,7 +1387,8 @@ void InterInstruction::GlobalRenameRegister(const GrowingIntArray& renameTable, if (mTTemp >= 0) { mTTemp = renameTable[mTTemp]; - temporaries[mTTemp] = mTType; + if (InterTypeSize[mTType] > InterTypeSize[temporaries[mTTemp]]) + temporaries[mTTemp] = mTType; } } @@ -3529,7 +3530,7 @@ void InterCodeProcedure::RenameTemporaries(void) mGlobalRenameTable[i] = mGlobalRenameTable[j]; } - mTemporaries.SetSize(numRenamedTemps); + mTemporaries.SetSize(numRenamedTemps, true); // // Set global temporary IDs @@ -3794,7 +3795,7 @@ void InterCodeProcedure::Close(void) mBlocks[0]->CollectActiveTemporaries(activeSet); - mTemporaries.SetSize(activeSet.Num()); + mTemporaries.SetSize(activeSet.Num(), true); @@ -3892,7 +3893,7 @@ void InterCodeProcedure::ReduceTemporaries(void) if (j >= numRenamedTemps) numRenamedTemps = j + 1; } - mTemporaries.SetSize(numRenamedTemps); + mTemporaries.SetSize(numRenamedTemps, true); ResetVisited(); mBlocks[0]->GlobalRenameRegister(mRenameTable, mTemporaries); @@ -3960,6 +3961,16 @@ void InterCodeProcedure::Disassemble(const char* name, bool dumpSets) fprintf(file, "--------------------------------------------------------------------\n"); fprintf(file, "%s : %s:%d\n", name, mLocation.mFileName, mLocation.mLine); + if (mTempOffset.Size()) + { + static char typechars[] = "NBCILFP"; + for (int i = 0; i < mTemporaries.Size(); i++) + { + fprintf(file, "$%02x T%d(%c), ", mTempOffset[i], i, typechars[mTemporaries[i]]); + } + } + fprintf(file, "\n"); + ResetVisited(); mBlocks[0]->Disassemble(file, dumpSets); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 13ced78..8d95311 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -719,6 +719,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* cins->mTTemp = proc->AddTemporary(cins->mTType); block->Append(cins); + vr = CoerceType(proc, block, vr, TheSignedIntTypeDeclaration); + InterInstruction * mins = new InterInstruction(); mins->mCode = IC_BINARY_OPERATOR; mins->mOperator = IA_MUL; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index c549d68..9969903 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -183,6 +183,10 @@ bool NativeCodeInstruction::IsUsedResultInstructions(NumberSet& requiredTemps) case ASMIT_DEX: case ASMIT_INY: case ASMIT_DEY: + case ASMIT_TYA: + case ASMIT_TXA: + case ASMIT_TAY: + case ASMIT_TAX: used = true; break; } @@ -248,11 +252,6 @@ bool NativeCodeInstruction::IsUsedResultInstructions(NumberSet& requiredTemps) case ASMIT_LSR: case ASMIT_INC: case ASMIT_DEC: - case ASMIT_ADC: - case ASMIT_SBC: - case ASMIT_ORA: - case ASMIT_EOR: - case ASMIT_AND: case ASMIT_STA: case ASMIT_STX: case ASMIT_STY: @@ -2657,8 +2656,17 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr ins->mSTemp[1] < 0 && ins->mSIntConst[1] == 1 && !sins0 && ins->mSTemp[0] == ins->mTTemp)) { mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, treg)); - mIns.Push(NativeCodeInstruction(ASMIT_BNE, ASMIM_RELATIVE, 2)); - mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, treg + 1)); + if (InterTypeSize[ins->mTType] > 1) + { + mIns.Push(NativeCodeInstruction(ASMIT_BNE, ASMIM_RELATIVE, 2)); + mIns.Push(NativeCodeInstruction(ASMIT_INC, ASMIM_ZERO_PAGE, treg + 1)); + } + } + else if (ins->mOperator == IA_ADD && InterTypeSize[ins->mTType] == 1 && ( + ins->mSTemp[0] < 0 && ins->mSIntConst[0] == -1 && !sins1 && ins->mSTemp[1] == ins->mTTemp || + ins->mSTemp[1] < 0 && ins->mSIntConst[1] == -1 && !sins0 && ins->mSTemp[0] == ins->mTTemp)) + { + mIns.Push(NativeCodeInstruction(ASMIT_DEC, ASMIM_ZERO_PAGE, treg)); } else { @@ -2694,9 +2702,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]])); mIns.Push(insl); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1)); - mIns.Push(insh); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + if (InterTypeSize[ins->mTType] > 1) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1)); + mIns.Push(insh); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + } } } else if (ins->mSTemp[0] < 0) @@ -2712,9 +2723,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]])); mIns.Push(insl); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1)); - mIns.Push(insh); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + if (InterTypeSize[ins->mTType] > 1) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1)); + mIns.Push(insh); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + } } } else @@ -2748,9 +2762,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]])); mIns.Push(NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1)); - mIns.Push(NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + if (InterTypeSize[ins->mTType] > 1) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1)); + mIns.Push(NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + } } } } @@ -2759,7 +2776,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr { NativeCodeInstruction insl, insh; - if (ins->mSTemp[0] < 0) + if (InterTypeSize[ins->mTType] == 1 && + ins->mSTemp[1] < 0 && ins->mSIntConst[1] == 1 && !sins0 && ins->mSTemp[0] == ins->mTTemp) + { + mIns.Push(NativeCodeInstruction(ASMIT_DEC, ASMIM_ZERO_PAGE, treg)); + } + else if (ins->mSTemp[0] < 0) { insl = NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, ins->mSIntConst[0] & 0xff); insh = NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, (ins->mSIntConst[0] >> 8) & 0xff); @@ -2771,9 +2793,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]])); mIns.Push(insl); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1)); - mIns.Push(insh); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + if (InterTypeSize[ins->mTType] > 1) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1)); + mIns.Push(insh); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + } } } else if (ins->mSTemp[1] < 0) @@ -2786,9 +2811,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSIntConst[1] & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSIntConst[1] >> 8) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + if (InterTypeSize[ins->mTType] > 1) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSIntConst[1] >> 8) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, treg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + } } else { @@ -2796,9 +2824,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSIntConst[1] & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSIntConst[1] >> 8) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + if (InterTypeSize[ins->mTType] > 1) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSIntConst[1] >> 8) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + } } } else @@ -2826,9 +2857,12 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, NativeCodePr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]])); mIns.Push(insl); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1)); - mIns.Push(insh); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + if (InterTypeSize[ins->mTType] > 1) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[1]] + 1)); + mIns.Push(insh); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + } } } } break; @@ -3993,6 +4027,42 @@ bool NativeCodeBasicBlock::MergeBasicBlocks(void) return changed; } +bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int& breg, int& ireg) +{ + int j = at - 7; + while (j >= 0) + { + if ( + mIns[j + 0].mType == ASMIT_CLC && + mIns[j + 1].mType == ASMIT_LDA && mIns[j + 1].mMode == ASMIM_ZERO_PAGE && mIns[j + 1].mAddress != reg && + mIns[j + 2].mType == ASMIT_ADC && mIns[j + 2].mMode == ASMIM_ZERO_PAGE && + mIns[j + 3].mType == ASMIT_STA && mIns[j + 3].mMode == ASMIM_ZERO_PAGE && mIns[j + 3].mAddress == reg && + mIns[j + 4].mType == ASMIT_LDA && mIns[j + 4].mMode == ASMIM_ZERO_PAGE && mIns[j + 4].mAddress == mIns[j + 1].mAddress + 1 && + mIns[j + 5].mType == ASMIT_ADC && mIns[j + 5].mMode == ASMIM_IMMEDIATE && mIns[j + 5].mAddress == 0 && + mIns[j + 6].mType == ASMIT_STA && mIns[j + 6].mMode == ASMIM_ZERO_PAGE && mIns[j + 6].mAddress == reg + 1) + { + breg = mIns[j + 1].mAddress; + ireg = mIns[j + 2].mAddress; + + j = j + 7; + while (j < at) + { + if (mIns[j].mMode == ASMIM_ZERO_PAGE && (mIns[j].mAddress == breg || mIns[j].mAddress == breg + 1 || mIns[j].mAddress == ireg) && mIns[j].ChangesAddress()) + return false; + j++; + } + return true; + } + + if (mIns[j + 6].mMode == ASMIM_ZERO_PAGE && (mIns[j].mAddress == reg || mIns[j].mAddress == reg + 1) && mIns[j + 6].ChangesAddress()) + return false; + + j--; + } + + return false; +} + bool NativeCodeBasicBlock::MoveLoadStoreUp(int at) { int j = at; @@ -4259,6 +4329,23 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) mIns[i + 2].mType = ASMIT_NOP; progress = true; } + +#if 1 + if ( + mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && mIns[i + 0].mAddress == 0 && + mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode != ASMIM_INDIRECT_Y && mIns[i + 1].mMode != ASMIM_ABSOLUTE_Y && + mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_INDIRECT_Y && !(mIns[i + 2].mLive & (LIVE_MEM | LIVE_CPU_REG_Y))) + { + int breg, ireg; + if (FindAddressSumY(i, mIns[i + 2].mAddress, breg, ireg)) + { + mIns[i + 0].mMode = ASMIM_ZERO_PAGE; + mIns[i + 0].mAddress = ireg; + mIns[i + 2].mAddress = breg; + progress = true; + } + } +#endif } if (i + 3 < mIns.Size()) @@ -4911,8 +4998,11 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode { block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSTemp[0]])); block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mTTemp])); - block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSTemp[0]] + 1)); - block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mTTemp] + 1)); + if (InterTypeSize[ins->mTType] > 1) + { + block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSTemp[0]] + 1)); + block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mTTemp] + 1)); + } if (ins->mSType[0] == IT_FLOAT) { block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSTemp[0]] + 2)); diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index d3b258c..4eceea8 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -124,6 +124,7 @@ public: bool MergeBasicBlocks(void); bool MoveLoadStoreUp(int at); + bool FindAddressSumY(int at, int reg, int& breg, int& ireg); bool ValueForwarding(const NativeRegisterDataSet& data);