diff --git a/include/crt.c b/include/crt.c index 19d1730..2139929 100644 --- a/include/crt.c +++ b/include/crt.c @@ -1383,6 +1383,49 @@ __asm inp_binop_addi_16 #pragma bytecode(BC_BINOP_ADDI_16, inp_binop_addi_16) +__asm inp_binop_addi_8 +{ + lda (ip), y + iny + tax + clc + lda $00, x + adc (ip), y + iny + sta $00, x + jmp startup.exec +} + +#pragma bytecode(BC_BINOP_ADDI_8, inp_binop_addi_8) + +__asm inp_binop_andi_8 +{ + lda (ip), y + iny + tax + lda $00, x + and (ip), y + iny + sta $00, x + jmp startup.exec +} + +#pragma bytecode(BC_BINOP_ANDI_8, inp_binop_andi_8) + +__asm inp_binop_ori_8 +{ + lda (ip), y + iny + tax + lda $00, x + ora (ip), y + iny + sta $00, x + jmp startup.exec +} + +#pragma bytecode(BC_BINOP_ORI_8, inp_binop_ori_8) + __asm inp_binop_subi_16 { lda (ip), y diff --git a/include/crt.h b/include/crt.h index ea432e1..f189141 100644 --- a/include/crt.h +++ b/include/crt.h @@ -93,6 +93,10 @@ enum ByteCode BC_BINOP_ORI_16, BC_BINOP_MULI8_16, + BC_BINOP_ADDI_8, + BC_BINOP_ANDI_8, + BC_BINOP_ORI_8, + BC_BINOP_SHLI_16, BC_BINOP_SHRI_U16, BC_BINOP_SHRI_I16, diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index 6a5eafb..9d16d80 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -139,7 +139,7 @@ bool ByteCodeInstruction::ChangesRegister(uint32 reg) const return true; if (mCode == BC_LEA_ABS || mCode == BC_LEA_LOCAL || mCode == BC_LEA_FRAME) return true; - if (mCode >= BC_BINOP_ADDI_16 && mCode <= BC_BINOP_MULI8_16) + if (mCode >= BC_BINOP_ADDI_16 && mCode <= BC_BINOP_ORI_8) return true; if (mCode == BC_CALL) return true; @@ -331,6 +331,9 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl block->PutWord(uint16(mValue)); break; case BC_BINOP_MULI8_16: + case BC_BINOP_ADDI_8: + case BC_BINOP_ANDI_8: + case BC_BINOP_ORI_8: block->PutCode(generator, mCode); block->PutByte(mRegister); block->PutByte(mValue); @@ -1799,7 +1802,25 @@ static ByteCode ByteCodeBinImmOperator(const InterInstruction * ins) case IA_ADD: return BC_BINOP_ADDI_16; case IA_SUB: return BC_BINOP_SUBI_16; case IA_AND: return BC_BINOP_ANDI_16; - case IA_OR: return BC_BINOP_ORI_16; + case IA_OR: return BC_BINOP_ORI_16; + case IA_SHL: return BC_BINOP_SHLI_16; + case IA_SHR: return BC_BINOP_SHRI_U16; + case IA_SAR: return BC_BINOP_SHRI_I16; + case IA_MUL: return BC_BINOP_MULI8_16; + + default: + return BC_EXIT; + } +} + +static ByteCode ByteCodeBinSizeImmOperator(const InterInstruction* ins) +{ + switch (ins->mOperator) + { + case IA_ADD: return InterTypeSize[ins->mTType] == 1 ? BC_BINOP_ADDI_8 : BC_BINOP_ADDI_16; + case IA_SUB: return BC_BINOP_SUBI_16; + case IA_AND: return InterTypeSize[ins->mTType] == 1 ? BC_BINOP_ANDI_8 : BC_BINOP_ANDI_16; + case IA_OR: return InterTypeSize[ins->mTType] == 1 ? BC_BINOP_ORI_8 : BC_BINOP_ORI_16; case IA_SHL: return BC_BINOP_SHLI_16; case IA_SHR: return BC_BINOP_SHRI_U16; case IA_SAR: return BC_BINOP_SHRI_I16; @@ -2009,12 +2030,13 @@ void ByteCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterIns { ByteCode bc = ByteCodeBinRegOperator(ins); ByteCode bci = ByteCodeBinImmOperator(ins); + ByteCode bcis = ByteCodeBinSizeImmOperator(ins); if (ins->mSTemp[1] < 0) { - if (ins->mSTemp[0] == ins->mTTemp && InterTypeSize[ins->mTType] == 2) + if (ins->mSTemp[0] == ins->mTTemp) { - ByteCodeInstruction bins(bci); + ByteCodeInstruction bins(bcis); bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; bins.mValue = ins->mSIntConst[1]; mIns.Push(bins); @@ -2033,9 +2055,9 @@ void ByteCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterIns } else if (ins->mSTemp[0] < 0) { - if (ins->mSTemp[1] == ins->mTTemp && InterTypeSize[ins->mTType] == 2) + if (ins->mSTemp[1] == ins->mTTemp) { - ByteCodeInstruction bins(bci); + ByteCodeInstruction bins(bcis); bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; bins.mValue = ins->mSIntConst[0]; mIns.Push(bins); @@ -2091,7 +2113,7 @@ void ByteCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterIns { if (ins->mSTemp[1] == ins->mTTemp) { - ByteCodeInstruction bins(BC_BINOP_ADDI_16); + ByteCodeInstruction bins(InterTypeSize[ins->mSType[0]] == 1 ? BC_BINOP_ADDI_8 : BC_BINOP_ADDI_16); bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mTTemp]; bins.mValue = - ins->mSIntConst[0]; mIns.Push(bins); @@ -2425,7 +2447,7 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p } break; case IC_RELATIONAL_OPERATOR: - if (sblock->mInstructions[i + 1]->mCode == IC_BRANCH) + if (sblock->mInstructions[i + 1]->mCode == IC_BRANCH && sblock->mInstructions[i + 1]->mSFinal[0]) { ByteCode code = RelationalOperator(iproc, ins); this->Close(proc->CompileBlock(iproc, sblock->mTrueJump), proc->CompileBlock(iproc, sblock->mFalseJump), code); @@ -2640,6 +2662,12 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(void) { mIns[i + 2].mCode = BC_NOP; } + else if (mIns[i + 0].mCode >= BC_SET_EQ && mIns[i + 0].mCode <= BC_SET_LE && + mIns[i + 1].mCode == BC_STORE_REG_8 && + mIns[i + 2].mCode == BC_LOAD_REG_8 && mIns[i + 1].mRegister == mIns[i + 2].mRegister) + { + mIns[i + 2].mCode = BC_NOP; + } } if (i + 1 < mIns.Size()) { diff --git a/oscar64/ByteCodeGenerator.h b/oscar64/ByteCodeGenerator.h index 1c22920..295b5bd 100644 --- a/oscar64/ByteCodeGenerator.h +++ b/oscar64/ByteCodeGenerator.h @@ -83,6 +83,10 @@ enum ByteCode BC_BINOP_ORI_16, BC_BINOP_MULI8_16, + BC_BINOP_ADDI_8, + BC_BINOP_ANDI_8, + BC_BINOP_ORI_8, + BC_BINOP_SHLI_16, BC_BINOP_SHRI_U16, BC_BINOP_SHRI_I16, diff --git a/oscar64/Disassembler.cpp b/oscar64/Disassembler.cpp index 4092ac7..394c91a 100644 --- a/oscar64/Disassembler.cpp +++ b/oscar64/Disassembler.cpp @@ -287,6 +287,19 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star i += 2; break; + case BC_BINOP_ADDI_8: + fprintf(file, "ADDB\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); + i += 2; + break; + case BC_BINOP_ANDI_8: + fprintf(file, "ANDB\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); + i += 2; + break; + case BC_BINOP_ORI_8: + fprintf(file, "ORB\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); + i += 2; + break; + case BC_CONV_I8_I16: fprintf(file, "SEXT8\t%s", TempName(memory[start + i + 0], tbuffer, proc)); i++; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 25b066b..2e98f3f 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -1498,7 +1498,7 @@ void InterInstruction::CollectSimpleLocals(FastNumberSet& complexLocals, FastNum { if (paramTypes[mVarIndex] == IT_NONE || paramTypes[mVarIndex] == mSType[0]) { - localTypes[mVarIndex] = mSType[0]; + paramTypes[mVarIndex] = mSType[0]; simpleParams += mVarIndex; } else diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 9c15143..e22772c 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -5390,7 +5390,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode } break; case IC_RELATIONAL_OPERATOR: - if (iblock->mInstructions[i + 1]->mCode == IC_BRANCH) + if (iblock->mInstructions[i + 1]->mCode == IC_BRANCH && iblock->mInstructions[i + 1]->mSFinal[0]) { block->RelationalOperator(iproc, ins, this, CompileBlock(iproc, iblock->mTrueJump), CompileBlock(iproc, iblock->mFalseJump)); return;