diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 73c13de..2c040ae 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -629,6 +629,26 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio { return mLeft->mLeft; } +#endif +#if 1 + else if (mType == EX_PREFIX && mToken == TK_BINARY_AND && + mLeft->mType == EX_QUALIFY && + mLeft->mLeft->mType == EX_PREFIX && mLeft->mLeft->mToken == TK_MUL && + mLeft->mLeft->mLeft->mType == EX_CONSTANT) + { + Expression* bex = mLeft->mLeft->mLeft; + if (bex->mDecValue->mType == DT_CONST_ADDRESS) + { + Expression* ex = new Expression(mLocation, EX_CONSTANT); + Declaration* dec = new Declaration(mLocation, DT_CONST_ADDRESS); + dec->mBase = mDecType; + dec->mInteger = bex->mDecValue->mInteger + mLeft->mDecValue->mOffset; + ex->mDecValue = dec; + ex->mDecType = mDecType; + return ex; + } + return mLeft; + } #endif else if (mType == EX_TYPECAST && mLeft->mType == EX_CONSTANT) { @@ -664,7 +684,7 @@ Expression* Expression::ConstantFold(Errors * errors, LinkerSection * dataSectio ex->mDecType = mDecType; return ex; } - else if (mLeft->mDecValue->mType == DT_CONST_INTEGER) + else if (mLeft->mDecValue->mType == DT_CONST_INTEGER || mLeft->mDecValue->mType == DT_CONST_ADDRESS) { int64 sval = 1ULL << (8 * mDecType->mSize); int64 v = mLeft->mDecValue->mInteger & (sval - 1); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index fb821fd..14031c2 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -4040,6 +4040,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* vins->mConst.mVarIndex = vdec->mVarIndex; vins->mConst.mOperandSize = vdec->mSize; vins->mConst.mIntConst = vdec->mOffset; + if (inlineMapper) + vins->mConst.mVarIndex += inlineMapper->mVarIndex; } block->Append(vins); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index bf02431..417a05a 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -23662,6 +23662,7 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool { if (mTrueJump->mEntryRequiredRegs[ins.mAddress] && !mFalseJump->mEntryRequiredRegs[ins.mAddress] && mTrueJump->mEntryBlocks.Size() == 1) { + mIns[ns - 1].mLive |= LIVE_CPU_REG_A; mTrueJump->mIns.Insert(0, ins); mTrueJump->mIns[0].mLive |= LIVE_CPU_REG_C | mIns[ns - 1].mLive; mIns.Remove(ns - 2); @@ -23672,6 +23673,7 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool } else if (mFalseJump->mEntryRequiredRegs[ins.mAddress] && !mTrueJump->mEntryRequiredRegs[ins.mAddress] && mFalseJump->mEntryBlocks.Size() == 1) { + mIns[ns - 1].mLive |= LIVE_CPU_REG_A; mFalseJump->mIns.Insert(0, ins); mFalseJump->mIns[0].mLive |= LIVE_CPU_REG_C | mIns[ns - 1].mLive; mIns.Remove(ns - 2); @@ -28993,6 +28995,53 @@ bool NativeCodeBasicBlock::FindExternAddressSumY(int at, int reg, int& breg, int } +bool NativeCodeBasicBlock::FindLoadAddressSumY(int at, int reg, int& apos, int& ireg) +{ + int j = at - 7; + while (j >= 0) + { + if (mIns[j + 0].mType == ASMIT_LDA && mIns[j + 0].mMode != ASMIM_ZERO_PAGE && + mIns[j + 1].mType == ASMIT_CLC && + 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 == mIns[j + 0].mMode && + 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) + { + ireg = mIns[j + 2].mAddress; + + int k = j + 7; + while (k < at) + { + if (mIns[k].mMode == ASMIM_ZERO_PAGE && mIns[k].mAddress == ireg && mIns[k].ChangesAddress()) + return false; + k++; + } + + apos = j; + return true; + } + + if (mIns[j + 6].mMode == ASMIM_ZERO_PAGE && (mIns[j + 6].mAddress == reg || mIns[j + 6].mAddress == reg + 1)) + return false; + if (mIns[j + 6].mMode == ASMIM_INDIRECT_Y && (mIns[j + 6].mAddress == reg || mIns[j + 6].mAddress + 1 == reg || mIns[j + 6].mAddress == reg + 1)) + return false; + if (mIns[j + 6].mType == ASMIT_JSR) + return false; + + j--; + } + return false; +} + +bool NativeCodeBasicBlock::PatchLoadAddressSumY(int at, int reg, int apos, int ireg) +{ + mIns[apos + 1].mType = ASMIT_NOP; mIns[apos + 1].mMode = ASMIM_IMPLIED; + mIns[apos + 2].mType = ASMIT_NOP; mIns[apos + 2].mMode = ASMIM_IMPLIED; + mIns[apos + 5].mType = ASMIT_NOP; mIns[apos + 5].mMode = ASMIM_IMPLIED; + return true; +} + bool NativeCodeBasicBlock::FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg) { int j = at - 7; @@ -40934,6 +40983,21 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass CheckLive(); #endif } + else if (!(mIns[i + 0].mLive & LIVE_MEM) && FindLoadAddressSumY(i, sreg, apos, ireg)) + { +#if 1 + RepairLoadYImmediate(i, 0); + PatchLoadAddressSumY(i, sreg, apos, ireg); + + mIns.Insert(i + 0, NativeCodeInstruction(mIns[i + 0].mIns, ASMIT_LDY, ASMIM_ZERO_PAGE, ireg)); + mIns[i + 0].mLive |= LIVE_CPU_REG_Y | LIVE_MEM; + + mIns[i + 1].mFlags &= ~NCIF_YZERO; + progress = true; + + CheckLive(); +#endif + } #if 1 @@ -41944,9 +42008,11 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass #if 1 if (i + 2 < mIns.Size()) { -// NativeCodeInstruction i0 = mIns[i]; -// NativeCodeInstruction i1 = mIns[i + 1]; -// NativeCodeInstruction i2 = mIns[i + 2]; +#if _DEBUG + NativeCodeInstruction i0 = mIns[i]; + NativeCodeInstruction i1 = mIns[i + 1]; + NativeCodeInstruction i2 = mIns[i + 2]; +#endif if (mIns[i].mType == ASMIT_LDA && mIns[i + 2].mType == ASMIT_LDA && (mIns[i + 1].mType == ASMIT_CLC || mIns[i + 1].mType == ASMIT_SEC)) { @@ -43200,6 +43266,9 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 2] = mIns[i + 1]; mIns[i + 0].mType = ASMIT_TXA; mIns[i + 0].mMode = ASMIM_IMPLIED; mIns[i + 0].mLive |= LIVE_CPU_REG_A; mIns[i + 1].mType = ASMIT_TAY; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_Y; + if (mIns[i + 2].ReferencesXReg()) + mIns[i + 1].mLive |= LIVE_CPU_REG_X; + mIns[i + 2].mLive |= LIVE_CPU_REG_Y; progress = true; } @@ -44430,6 +44499,11 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 2].mType = ASMIT_EOR; mIns[i + 2].mMode = ASMIM_IMMEDIATE; mIns[i + 2].mAddress = 0xff; mIns[i + 3].mType = ASMIT_ADC; + if (mIns[i + 3].ReferencesYReg()) + mIns[i + 2].mLive |= LIVE_CPU_REG_Y; + if (mIns[i + 3].ReferencesXReg()) + mIns[i + 2].mLive |= LIVE_CPU_REG_X; + mIns[i + 0].mLive |= LIVE_CPU_REG_A; mIns[i + 1].mLive |= LIVE_CPU_REG_A; @@ -44446,6 +44520,17 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 1].mType = ASMIT_EOR; mIns[i + 1].mMode = ASMIM_IMMEDIATE; mIns[i + 1].mAddress = 0xff; mIns[i + 3].mType = ASMIT_ADC; + if (mIns[i + 3].ReferencesYReg()) + { + mIns[i + 1].mLive |= LIVE_CPU_REG_Y; + mIns[i + 2].mLive |= LIVE_CPU_REG_Y; + } + if (mIns[i + 3].ReferencesXReg()) + { + mIns[i + 1].mLive |= LIVE_CPU_REG_X; + mIns[i + 2].mLive |= LIVE_CPU_REG_X; + } + mIns[i + 0].mLive |= LIVE_CPU_REG_A; mIns[i + 1].mLive |= LIVE_CPU_REG_A; @@ -47750,7 +47835,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) { mInterProc = proc; - CheckFunc = !strcmp(mInterProc->mIdent->mString, "window_mask3"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "enemies_move"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; @@ -48696,7 +48781,6 @@ void NativeCodeProcedure::Optimize(void) } - if (step > 2 && !changed) { ResetVisited(); @@ -49117,7 +49201,6 @@ void NativeCodeProcedure::Optimize(void) CheckBlocks(); - #if 1 if (step == 8) { @@ -49147,6 +49230,7 @@ void NativeCodeProcedure::Optimize(void) if (mEntryBlock->CrossBlock16BitFlood(this)) changed = true; } + #if 1 if (step >= 7) { @@ -49159,6 +49243,7 @@ void NativeCodeProcedure::Optimize(void) changed = true; } #endif + #if _DEBUG ResetVisited(); mEntryBlock->CheckAsmCode(); diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index 116ebde..cd669ba 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -443,6 +443,10 @@ public: bool PatchDirectAddressSumY(int at, int reg, int apos, int breg); bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg); bool PatchAddressSumY(int at, int reg, int apos, int breg, int ireg); + + bool FindLoadAddressSumY(int at, int reg, int& apos, int& ireg); + bool PatchLoadAddressSumY(int at, int reg, int apos, int ireg); + bool FindGlobalAddress(int at, int reg, int& apos); bool FindGlobalAddressSumY(int at, int reg, bool direct, int& apos, const NativeCodeInstruction * & ains, const NativeCodeInstruction*& iins, uint32 & flags, int & addr); bool FindExternAddressSumY(int at, int reg, int& breg, int& ireg); diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 3c50649..8ce2bf2 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -10367,6 +10367,39 @@ Expression* Parser::ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset) { exp->mDecType = dec->mBase; } + else if (dec->mType == DT_TYPE_STRUCT) + { + mScanner->NextToken(); + + int offset = 0; + while (dec->mType == DT_TYPE_STRUCT && ConsumeTokenIf(TK_COLCOLON)) + { + if (mScanner->mToken == TK_IDENT) + { + Declaration* edec = dec->mScope->Lookup(mScanner->mTokenIdent); + if (edec) + { + offset += edec->mOffset; + dec = edec->mBase; + } + else + mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Struct member not found", mScanner->mTokenIdent); + + mScanner->NextToken(); + } + else + mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Identifier for qualification expected"); + } + + dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); + dec->mInteger = offset; + dec->mBase = TheUnsignedIntTypeDeclaration; + exp = new Expression(mScanner->mLocation, EX_CONSTANT); + exp->mDecValue = dec; + exp->mDecType = dec->mBase; + + return exp; + } else exp->mDecType = TheUnsignedIntTypeDeclaration; }