From 0c3e19741c7882315485fdbb45b3ba415af54ca8 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Tue, 16 Nov 2021 09:10:39 +0100 Subject: [PATCH] Optimize byte code size --- include/crt.c | 17 ++++ include/crt.h | 1 + oscar64/ByteCodeGenerator.cpp | 159 +++++++++++++++++++++++++++++++++- oscar64/ByteCodeGenerator.h | 1 + oscar64/Disassembler.cpp | 5 ++ 5 files changed, 181 insertions(+), 2 deletions(-) diff --git a/include/crt.c b/include/crt.c index 49e3ff4..facabb1 100644 --- a/include/crt.c +++ b/include/crt.c @@ -1193,6 +1193,23 @@ __asm inp_lea_abs_index_u8 } #pragma bytecode(BC_LEA_ABS_INDEX_U8, inp_lea_abs_index_u8) + +__asm inp_lea_accu_index +{ + lda (ip), y + tax + iny + clc + lda $00, x + adc accu + sta addr + lda $01, x + adc accu + 1 + sta addr + 1 + jmp startup.exec +} + +#pragma bytecode(BC_LEA_ACCU_INDEX, inp_lea_accu_index) __asm inp_load_local_16 { diff --git a/include/crt.h b/include/crt.h index 8b03994..c954327 100644 --- a/include/crt.h +++ b/include/crt.h @@ -34,6 +34,7 @@ enum ByteCode BC_LEA_ABS, BC_LEA_ABS_INDEX, BC_LEA_ABS_INDEX_U8, + BC_LEA_ACCU_INDEX, BC_LOAD_LOCAL_8, BC_LOAD_LOCAL_16, diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index 6020d28..7648943 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -348,7 +348,7 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const if (mRegister == reg) { - if (mCode == BC_LOAD_REG_8 || mCode == BC_LOAD_REG_16 || mCode == BC_LOAD_REG_32 || mCode == BC_ADDR_REG || mCode == BC_LEA_ABS_INDEX || mCode == BC_LEA_ABS_INDEX_U8) + if (mCode == BC_LOAD_REG_8 || mCode == BC_LOAD_REG_16 || mCode == BC_LOAD_REG_32 || mCode == BC_ADDR_REG || mCode == BC_LEA_ABS_INDEX || mCode == BC_LEA_ABS_INDEX_U8 || mCode == BC_LEA_ACCU_INDEX) return true; if (mCode >= BC_BINOP_ADDI_16 && mCode <= BC_BINOP_ORI_8) @@ -393,6 +393,8 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const return true; if (mCode >= BC_CONV_I16_I32 && mCode <= BC_BINOP_CMP_S32) return true; + if (mCode == BC_LEA_ACCU_INDEX) + return true; } if (reg == BC_REG_ADDR) @@ -467,7 +469,7 @@ bool ByteCodeInstruction::ChangesRegister(uint32 reg) const return true; if (mCode == BC_JSR || mCode == BC_CALL) return true; - if (mCode == BC_LEA_ABS_INDEX || mCode == BC_LEA_ABS_INDEX_U8) + if (mCode == BC_LEA_ABS_INDEX || mCode == BC_LEA_ABS_INDEX_U8 || mCode == BC_LEA_ACCU_INDEX) return true; } @@ -595,6 +597,11 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl block->PutWord(uint16(mValue)); break; + case BC_LEA_ACCU_INDEX: + block->PutCode(generator, mCode); + block->PutByte(mRegister); + break; + case BC_BINOP_ADDR_16: case BC_BINOP_SUBR_16: case BC_BINOP_ANDR_16: @@ -4017,6 +4024,20 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase) mIns[i + 3].mCode = BC_NOP; progress = true; } +#if 1 + else if ( + mIns[i + 0].mCode == BC_STORE_REG_16 && + !mIns[i + 1].ChangesAccu() && !mIns[i + 1].ChangesRegister(mIns[i + 0].mRegister) && + mIns[i + 2].mCode == BC_LOAD_REG_16 && + mIns[i + 3].IsCommutative() && mIns[i + 3].mRegister == mIns[i + 0].mRegister) + { + mIns[i + 2].mCode = mIns[i + 3].mCode; + mIns[i + 3].mCode = BC_NOP; + if (mIns[i + 3].mRegisterFinal && !mIns[i + 1].UsesRegister(mIns[i + 0].mRegister)) + mIns[i + 0].mCode = BC_NOP; + progress = true; + } +#endif } #endif #if 1 @@ -4146,6 +4167,8 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase) } 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)) { + if (mIns[i + 0].mRegister == BC_REG_ACCU) + mIns[i + 1].mLive |= LIVE_ACCU; mIns[i + 2].mCode = BC_NOP; progress = true; } @@ -4248,6 +4271,66 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase) mIns[i + 1].mCode = BC_NOP; progress = true; } + + else if ( + mIns[i + 0].mCode == BC_STORE_REG_16 && + (mIns[i + 1].mCode == BC_BINOP_MULI8_16 || mIns[i + 1].mCode == BC_BINOP_ADDI_16) && mIns[i + 1].mRegister == mIns[i + 0].mRegister && + (mIns[i + 2].mCode == BC_STORE_ABS_16 || mIns[i + 2].mCode == BC_STORE_LOCAL_16 || mIns[i + 2].mCode == BC_STORE_FRAME_16 || mIns[i + 2].mCode == BC_STORE_ADDR_16) && mIns[i + 2].mRegister == mIns[i + 0].mRegister && + mIns[i + 2].mRegisterFinal && !(mIns[i + 2].mLive & LIVE_ACCU)) + { + mIns[i + 0].mCode = BC_NOP; + mIns[i + 1].mRegister = BC_REG_ACCU; + mIns[i + 2].mRegister = BC_REG_ACCU; + mIns[i + 1].mLive |= LIVE_ACCU; + progress = true; + } + + else if ( + mIns[i + 0].mCode == BC_LOAD_REG_8 && + mIns[i + 1].mCode == BC_STORE_REG_16 && + mIns[i + 2].mCode == BC_BINOP_ANDI_16 && mIns[i + 2].mRegister == mIns[i + 1].mRegister && mIns[i + 2].mValue == 0x00ff) + { + mIns[i + 2].mCode = BC_STORE_REG_16; + mIns[i + 1].mCode = BC_NOP; + mIns[i + 0].mLive |= LIVE_ACCU; + progress = true; + } + + else if ( + mIns[i + 0].mCode == BC_STORE_REG_16 && + mIns[i + 1].mCode == BC_BINOP_ADDI_16 && mIns[i + 0].mRegister == mIns[i + 1].mRegister && + mIns[i + 2].mCode == BC_LOAD_REG_8 && mIns[i + 2].mRegister == mIns[i + 0].mRegister && mIns[i + 2].mRegisterFinal) + { + mIns[i + 0].mCode = BC_LOAD_REG_8; + mIns[i + 0].mRegister = BC_REG_ACCU; + mIns[i + 0].mLive |= LIVE_ACCU; + + mIns[i + 1].mCode = BC_BINOP_ADDI_8; + mIns[i + 1].mRegister = BC_REG_ACCU; + mIns[i + 1].mLive |= LIVE_ACCU; + + mIns[i + 2].mCode = BC_NOP; + + progress = true; + } + else if ( + mIns[i + 0].mCode == BC_LOAD_REG_8 && + mIns[i + 1].mCode == BC_BINOP_SHRI_U16 && + mIns[i + 2].mCode == BC_LOAD_REG_8 && mIns[i + 2].mRegister == BC_REG_ACCU) + { + mIns[i + 2].mCode = BC_NOP; + progress = true; + } + else if ( + mIns[i + 0].mCode == BC_LEA_ABS && + mIns[i + 1].mCode == BC_BINOP_ADDR_16 && mIns[i + 0].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal && + mIns[i + 2].mCode == BC_ADDR_REG && mIns[i + 2].mRegister == BC_REG_ACCU && !(mIns[i + 2].mLive & LIVE_ACCU)) + { + mIns[i + 0].mCode = BC_LEA_ABS_INDEX; + mIns[i + 0].mRegister = BC_REG_ACCU; + mIns[i + 1].mCode = BC_NOP; + mIns[i + 2].mCode = BC_NOP; + } } #endif #if 1 @@ -4382,6 +4465,34 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase) mIns[i + 1].mCode = BC_NOP; progress = true; } + else if ( + mIns[i + 0].mCode == BC_BINOP_ANDI_16 && mIns[i + 0].mValue == 0x00ff && + mIns[i + 1].mCode == BC_LOAD_REG_16 && mIns[i + 1].mRegister == mIns[i + 0].mRegister) + { + mIns[i + 0].mCode = BC_LOAD_REG_8; + mIns[i + 0].mLive |= LIVE_ACCU; + + if (!mIns[i + 1].mRegisterFinal) + mIns[i + 1].mCode = BC_STORE_REG_16; + else + mIns[i + 1].mCode = BC_NOP; + progress = true; + } + else if ( + mIns[i + 0].mCode == BC_LOAD_REG_8 && + mIns[i + 1].mCode == BC_LOAD_REG_8 && mIns[i + 1].mRegister == BC_REG_ACCU) + { + mIns[i + 1].mCode = BC_NOP; + progress = true; + } + else if ( + mIns[i + 0].mCode == BC_LOAD_REG_8 && + mIns[i + 1].mCode == BC_BINOP_SHRI_I16) + { + mIns[i + 1].mCode = BC_BINOP_SHRI_U16; + progress = true; + } + if ((mIns[i].mCode == BC_LOAD_ABS_U8 || mIns[i].mCode == BC_LOAD_ADDR_U8 || mIns[i].mCode == BC_LOAD_ABS_16 || mIns[i].mCode == BC_LOAD_ADDR_16) && mIns[i].mRegister == BC_REG_ACCU && mIns[i + 1].mCode == BC_STORE_REG_16 && !(mIns[i + 1].mLive & LIVE_ACCU)) @@ -4391,6 +4502,44 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase) progress = true; } #endif +#if 1 + else if ( + mIns[i + 0].mCode == BC_CONST_16 && mIns[i + 0].mRegister == BC_REG_ACCU && + mIns[i + 1].mCode == BC_STORE_REG_8 && !(mIns[i + 1].mLive & LIVE_ACCU)) + { + mIns[i + 0].mCode = BC_CONST_8; + mIns[i + 0].mRegister = mIns[i + 1].mRegister; + mIns[i + 1].mCode = BC_NOP; + progress = true; + } +#endif + else if ( + mIns[i + 0].mCode == BC_CONST_16 && mIns[i + 0].mRegister == BC_REG_ACCU && + mIns[i + 1].mCode == BC_STORE_REG_16 && !(mIns[i + 1].mLive & LIVE_ACCU)) + { + mIns[i + 0].mRegister = mIns[i + 1].mRegister; + mIns[i + 1].mCode = BC_NOP; + progress = true; + } + else if ( + (mIns[i + 0].mCode == BC_LEA_LOCAL || mIns[i + 0].mCode == BC_LEA_ABS || mIns[i + 0].mCode == BC_LEA_FRAME) && mIns[i + 0].mRegister == BC_REG_ACCU && + mIns[i + 1].mCode == BC_STORE_REG_16 && !(mIns[i + 1].mLive & LIVE_ACCU)) + { + mIns[i + 0].mRegister = mIns[i + 1].mRegister; + mIns[i + 1].mCode = BC_NOP; + progress = true; + } +#if 1 + else if ( + mIns[i + 0].mCode == BC_BINOP_ADDR_16 && + mIns[i + 1].mCode == BC_ADDR_REG && mIns[i + 1].mRegister == BC_REG_ACCU && !(mIns[i + 1].mLive & LIVE_ACCU)) + { + mIns[i + 0].mCode = BC_LEA_ACCU_INDEX; + mIns[i + 1].mCode = BC_NOP; + progress = true; + } +#endif + #if 0 else if ((mIns[i].mCode == BC_LOAD_LOCAL_16 || mIns[i].mCode == BC_LOAD_ABS_16) && mIns[i + 1].mCode == BC_ADDR_REG && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal) { @@ -4400,6 +4549,12 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase) } #endif } + + if (mIns[i].mCode == BC_BINOP_ANDI_16 && mIns[i].mRegister == BC_REG_ACCU && mIns[i].mValue == 0x00ff) + { + mIns[i].mCode = BC_LOAD_REG_8; + progress = true; + } #endif #if 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) diff --git a/oscar64/ByteCodeGenerator.h b/oscar64/ByteCodeGenerator.h index 48446ee..2779ae1 100644 --- a/oscar64/ByteCodeGenerator.h +++ b/oscar64/ByteCodeGenerator.h @@ -35,6 +35,7 @@ enum ByteCode BC_LEA_ABS, BC_LEA_ABS_INDEX, BC_LEA_ABS_INDEX_U8, + BC_LEA_ACCU_INDEX, BC_LOAD_LOCAL_8, BC_LOAD_LOCAL_16, diff --git a/oscar64/Disassembler.cpp b/oscar64/Disassembler.cpp index 3dc1926..34b9843 100644 --- a/oscar64/Disassembler.cpp +++ b/oscar64/Disassembler.cpp @@ -166,6 +166,11 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star i += 3; break; + case BC_LEA_ACCU_INDEX: + fprintf(file, "LEAX\tADDR, %s + ACCU", TempName(memory[start + i + 0], tbuffer, proc)); + i += 1; + break; + case BC_LEA_ABS_INDEX_U8: fprintf(file, "LEAXB\tADDR, %s + %s", AddrName(uint16(memory[start + i + 1] + 256 * memory[start + i + 2]), abuffer, linker), TempName(memory[start + i + 0], tbuffer, proc)); i += 3;