diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index e5bb949..29ff8d4 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -2903,7 +2903,7 @@ void ByteCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterIns { ByteCodeInstruction lins(InterTypeSize[ins->mSrc[1].mType] == 1 ? BC_LOAD_REG_8 : BC_LOAD_REG_16); lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; - lins.mRegisterFinal = ins->mSrc[1].mFinal; + lins.mRegisterFinal = ins->mSrc[1].mFinal && (ins->mSrc[1].mTemp != ins->mSrc[0].mTemp); mIns.Push(lins); ByteCodeInstruction bins(bc); @@ -2958,7 +2958,7 @@ void ByteCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterIns { ByteCodeInstruction lins(InterTypeSize[ins->mSrc[1].mType] == 1 ? BC_LOAD_REG_8 : BC_LOAD_REG_16); lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; - lins.mRegisterFinal = ins->mSrc[1].mFinal; + lins.mRegisterFinal = ins->mSrc[1].mFinal && (ins->mSrc[1].mTemp != ins->mSrc[0].mTemp);; mIns.Push(lins); ByteCodeInstruction bins(BC_BINOP_SUBR_16); @@ -3041,7 +3041,7 @@ void ByteCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterIns { ByteCodeInstruction lins(BC_LOAD_REG_16); lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; - lins.mRegisterFinal = ins->mSrc[1].mFinal; + lins.mRegisterFinal = ins->mSrc[1].mFinal && (ins->mSrc[1].mTemp != ins->mSrc[0].mTemp);; mIns.Push(lins); ByteCodeInstruction bins(bc); @@ -3073,7 +3073,7 @@ void ByteCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterIns { ByteCodeInstruction lins(BC_LOAD_REG_16); lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; - lins.mRegisterFinal = ins->mSrc[1].mFinal; + lins.mRegisterFinal = ins->mSrc[1].mFinal && (ins->mSrc[1].mTemp != ins->mSrc[0].mTemp);; mIns.Push(lins); ByteCodeInstruction bins(bc); @@ -3113,7 +3113,7 @@ void ByteCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterIns { ByteCodeInstruction lins(BC_LOAD_REG_16); lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; - lins.mRegisterFinal = ins->mSrc[1].mFinal; + lins.mRegisterFinal = ins->mSrc[1].mFinal && (ins->mSrc[1].mTemp != ins->mSrc[0].mTemp);; mIns.Push(lins); ByteCodeInstruction bins(bc); @@ -3154,7 +3154,7 @@ void ByteCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterIns { ByteCodeInstruction lins(BC_LOAD_REG_16); lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; - lins.mRegisterFinal = ins->mSrc[1].mFinal; + lins.mRegisterFinal = ins->mSrc[1].mFinal && (ins->mSrc[1].mTemp != ins->mSrc[0].mTemp);; mIns.Push(lins); ByteCodeInstruction bins(rbc); diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 7ae4c81..4fea317 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -4001,6 +4001,18 @@ void InterCodeBasicBlock::PeepholeOptimization(void) if (i != j) mInstructions[j] = ins; } + else if (mInstructions[i]->mCode == IC_LEA && mInstructions[i]->mSrc[0].mTemp == -1) + { + InterInstruction* ins(mInstructions[i]); + int j = i; + while (j < limit && CanBypass(ins, mInstructions[j + 1])) + { + mInstructions[j] = mInstructions[j + 1]; + j++; + } + if (i != j) + mInstructions[j] = ins; + } i--; } diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 17ad296..b9418ed 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -2682,10 +2682,41 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* if (exp->mLeft->mDecType->mType == DT_TYPE_FLOAT && vr.mType->IsIntegerType()) { vr = Dereference(proc, block, vr); + + int stemp = vr.mTemp; + + if (vr.mType->mSize == 1) + { + if (vr.mType->mFlags & DTF_SIGNED) + { + InterInstruction* xins = new InterInstruction(); + xins->mCode = IC_CONVERSION_OPERATOR; + xins->mOperator = IA_EXT8TO16S; + xins->mSrc[0].mType = IT_INT8; + xins->mSrc[0].mTemp = stemp; + xins->mDst.mType = IT_INT16; + xins->mDst.mTemp = proc->AddTemporary(IT_INT16); + block->Append(xins); + stemp = xins->mDst.mTemp; + } + else + { + InterInstruction* xins = new InterInstruction(); + xins->mCode = IC_CONVERSION_OPERATOR; + xins->mOperator = IA_EXT8TO16U; + xins->mSrc[0].mType = IT_INT8; + xins->mSrc[0].mTemp = stemp; + xins->mDst.mType = IT_INT16; + xins->mDst.mTemp = proc->AddTemporary(IT_INT16); + block->Append(xins); + stemp = xins->mDst.mTemp; + } + } + ins->mCode = IC_CONVERSION_OPERATOR; ins->mOperator = IA_INT2FLOAT; - ins->mSrc[0].mType = InterTypeOf(vr.mType); - ins->mSrc[0].mTemp = vr.mTemp; + ins->mSrc[0].mType = IT_INT16; + ins->mSrc[0].mTemp = stemp; ins->mDst.mType = InterTypeOf(exp->mLeft->mDecType); ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); block->Append(ins); @@ -2697,9 +2728,21 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ins->mOperator = IA_FLOAT2INT; ins->mSrc[0].mType = InterTypeOf(vr.mType); ins->mSrc[0].mTemp = vr.mTemp; - ins->mDst.mType = InterTypeOf(exp->mLeft->mDecType); - ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); + ins->mDst.mType = IT_INT16; + ins->mDst.mTemp = proc->AddTemporary(IT_INT16); block->Append(ins); + + if (exp->mLeft->mDecType->mSize == 1) + { + InterInstruction* xins = new InterInstruction(); + xins->mCode = IC_TYPECAST; + xins->mSrc[0].mType = IT_INT16; + xins->mSrc[0].mTemp = ins->mDst.mTemp; + xins->mDst.mType = InterTypeOf(exp->mLeft->mDecType); + xins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); + block->Append(xins); + ins = xins; + } } else if (exp->mLeft->mDecType->mType == DT_TYPE_POINTER && vr.mType->mType == DT_TYPE_POINTER) { diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 886e7ab..b80813c 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -1496,6 +1496,15 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data) break; case ASMIT_SBC: + if (data.mRegs[CPU_REG_C].mMode == NRDM_IMMEDIATE && data.mRegs[CPU_REG_C].mValue == 1) + { + if (mMode == ASMIM_IMMEDIATE && mAddress == 0) + { + mType = ASMIT_ORA; + changed = true; + } + } + data.mRegs[CPU_REG_A].Reset(); data.mRegs[CPU_REG_C].Reset(); data.mRegs[CPU_REG_Z].Reset(); @@ -5322,6 +5331,19 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_ZERO_PAGE, treg + 1)); } } + else if (shift == 7) + { + int sreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; + + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LSR, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 0)); + mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0x00)); + mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0)); + } else if (shift >= 8) { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); @@ -5540,6 +5562,55 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); } } + else if (shift == 7) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); + 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, treg + 1)); + } + else if (shift == 6) + { + int sreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; + if (sreg != treg) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); + mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); + + 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_ASL, ASMIM_ZERO_PAGE, treg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_ZERO_PAGE, treg)); + mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + } + else + { + mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_ZERO_PAGE, treg)); + mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_ZERO_PAGE, treg + 1)); + 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_ASL, ASMIM_ZERO_PAGE, treg)); + mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_ZERO_PAGE, treg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_ZERO_PAGE, treg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, treg)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + } + } else if (shift >= 8) { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1)); @@ -7800,7 +7871,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) #if 1 // move load store pairs up to initial store - for (int i = 2; i + 2 < mIns.Size(); i++) + for (int i = 2; i + 1 < mIns.Size(); i++) { if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && (mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) == 0) { @@ -7828,7 +7899,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) // move load - store abs up to initial store // - for (int i = 2; i + 2 < mIns.Size(); i++) + for (int i = 2; i + 1 < mIns.Size(); i++) { if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ABSOLUTE) { @@ -8358,6 +8429,33 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void) { mIns[i + 2].mType = ASMIT_NOP; } + else if ( + mIns[i + 0].mType == ASMIT_SEC && + mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_IMMEDIATE && + mIns[i + 2].mType == ASMIT_SBC && mIns[i + 2].mMode == ASMIM_IMMEDIATE) + { + int t = (mIns[i + 2].mAddress ^ 0xff) + mIns[i + 1].mAddress + 1; + + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_LDA; mIns[i + 2].mAddress = t & 0xff; + if (t < 256) + mIns[i + 0].mType = ASMIT_CLC; + progress = true; + } + else if ( + mIns[i + 0].mType == ASMIT_CLC && + mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_IMMEDIATE && + mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE) + { + int t = mIns[i + 2].mAddress + mIns[i + 1].mAddress; + + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_LDA; mIns[i + 2].mAddress = t & 0xff; + if (t >= 256) + mIns[i + 0].mType = ASMIT_SEC; + progress = true; + } + #if 1 else if ( mIns[i + 0].mType == ASMIT_ASL && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && @@ -9420,6 +9518,15 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode block->LoadOpStoreIndirectValue(iproc, ins, iblock->mInstructions[i + 1], 0, iblock->mInstructions[i + 2]); i += 2; } + else if (i + 1 < iblock->mInstructions.Size() && + InterTypeSize[ins->mDst.mType] >= 2 && + iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && + iblock->mInstructions[i + 1]->mSrc[0].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[0].mFinal && + iblock->mInstructions[i + 1]->mSrc[1].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[1].mFinal) + { + block = block->BinaryOperator(iproc, this, iblock->mInstructions[i + 1], ins, ins); + i++; + } else if (i + 1 < iblock->mInstructions.Size() && InterTypeSize[ins->mDst.mType] >= 2 && iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && @@ -9628,8 +9735,11 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode { block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp])); block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mDst.mTemp])); - block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp] + 1)); - block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mDst.mTemp] + 1)); + if (InterTypeSize[ins->mDst.mType] > 1) + { + block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp] + 1)); + block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mDst.mTemp] + 1)); + } } break;