diff --git a/include/gfx/bitmap.c b/include/gfx/bitmap.c index 507bde8..07f7166 100644 --- a/include/gfx/bitmap.c +++ b/include/gfx/bitmap.c @@ -1162,8 +1162,11 @@ void bmu_bitblit(const Bitmap * dbm, int dx, int dy, const Bitmap * sbm, int sx, int sstride = 8 * sbm->cwidth - 8; int dstride = 8 * dbm->cwidth - 8; - if (pattern) + if (op & BLIT_SRC) { + if (!pattern) + pattern = sp; + if (reverse) { sstride = -sstride; @@ -1202,41 +1205,29 @@ void bmu_bitblit(const Bitmap * dbm, int dx, int dy, const Bitmap * sbm, int sx, } } } + else if (op & BLIT_PATTERN) + { + for(char y=h; y>0; y--) + { + char pi = (int)dp & 7; + + callddop(dp, dp, pat[pi]); + + dp++; + if (((int)dp & 7) == 0) + dp += dstride; + } + } else { - if (reverse) - { - sstride = -sstride; - dstride = -dstride; + for(char y=h; y>0; y--) + { + callddop(dp, dp, 0); - for(char y=h; y>0; y--) - { - if (((int)sp & 7) == 0) - sp += sstride; - sp--; - - if (((int)dp & 7) == 0) - dp += dstride; - dp--; - - callddop(sp, dp, 0); - } + dp++; + if (((int)dp & 7) == 0) + dp += dstride; } - else - { - for(char y=h; y>0; y--) - { - callddop(sp, dp, 0); - - sp++; - if (((int)sp & 7) == 0) - sp += sstride; - - dp++; - if (((int)dp & 7) == 0) - dp += dstride; - } - } } } @@ -1244,30 +1235,35 @@ void bmu_bitblit(const Bitmap * dbm, int dx, int dy, const Bitmap * sbm, int sx, void bm_bitblit(const Bitmap * dbm, const ClipRect * clip, int dx, int dy, const Bitmap * sbm, int sx, int sy, int w, int h, const char * pattern, BlitOp op) { - if (dx >= clip->right || dy >= clip->bottom) - return; + int d; - if (dx < clip->left) + d = dx - clip->left; + + if (d < 0) { - int d = clip->left - dx; - dx += d; - sx += d; - w -= d; + dx -= d; + sx -= d; + w += d; } - if (dy < clip->top) + d = dy - clip->top; + + if (d < 0) { - int d = clip->top - dy; - dy += d; - sy += d; - h -= d; + dy -= d; + sy -= d; + h += d; } - if (dx + w > clip->right) - w = clip->right - dx; + d = clip->right - dx - w; - if (dy + h > clip->bottom) - h = clip->bottom - dy; + if (d < 0) + w += d; + + d = clip->bottom - dy - h; + + if (d < 0) + h += d; if (w > 0 && h > 0) bmu_bitblit(dbm, dx, dy, sbm, sx, sy, w, h, pattern, op); diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index 125e699..5fa7c6d 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -160,8 +160,11 @@ void GlobalAnalyzer::CheckFastcall(Declaration* procDec) int numfpzero = BC_REG_FPARAMS_END - BC_REG_FPARAMS; int fplimit = numfpzero; - if (!(procDec->mFlags & DTF_FUNC_INTRCALLED)) - fplimit += 256; + if ((procDec->mFlags & DTF_NATIVE) || (mCompilerOptions & COPT_NATIVE)) + { + if (!(procDec->mFlags & DTF_FUNC_INTRCALLED)) + fplimit += 256; + } if (procDec->mBase->mBase->mType == DT_TYPE_STRUCT) { diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index c84585a..de49eff 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -1578,7 +1578,7 @@ bool InterInstruction::IsEqualSource(const InterInstruction* ins) const void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, const GrowingVariableArray& staticVars) { - int i, value, temp; + int i, temp; temp = ins->mDst.mTemp; @@ -3004,7 +3004,7 @@ bool InterInstruction::PropagateConstTemps(const GrowingInstructionPtrArray& cte return false; } -void InterInstruction::PerformTempForwarding(TempForwardingTable& forwardingTable) +void InterInstruction::PerformTempForwarding(TempForwardingTable& forwardingTable, bool reverse) { if (mCode != IC_NONE) { @@ -3014,7 +3014,10 @@ void InterInstruction::PerformTempForwarding(TempForwardingTable& forwardingTabl } if (mCode == IC_LOAD_TEMPORARY && mDst.mTemp != mSrc[0].mTemp) { - forwardingTable.Build(mDst.mTemp, mSrc[0].mTemp); + if (reverse) + forwardingTable.Build(mSrc[0].mTemp, mDst.mTemp); + else + forwardingTable.Build(mDst.mTemp, mSrc[0].mTemp); } } @@ -7050,7 +7053,7 @@ bool InterCodeBasicBlock::CalculateSingleAssignmentTemps(FastNumberSet& tassigne return changed; } -void InterCodeBasicBlock::PerformTempForwarding(const TempForwardingTable& forwardingTable) +void InterCodeBasicBlock::PerformTempForwarding(const TempForwardingTable& forwardingTable, bool reverse) { int i; @@ -7089,11 +7092,11 @@ void InterCodeBasicBlock::PerformTempForwarding(const TempForwardingTable& forwa for (i = 0; i < mInstructions.Size(); i++) { - mInstructions[i]->PerformTempForwarding(mMergeForwardingTable); + mInstructions[i]->PerformTempForwarding(mMergeForwardingTable, reverse); } - if (mTrueJump) mTrueJump->PerformTempForwarding(mMergeForwardingTable); - if (mFalseJump) mFalseJump->PerformTempForwarding(mMergeForwardingTable); + if (mTrueJump) mTrueJump->PerformTempForwarding(mMergeForwardingTable, reverse); + if (mFalseJump) mFalseJump->PerformTempForwarding(mMergeForwardingTable, reverse); } } @@ -9008,7 +9011,8 @@ void InterCodeBasicBlock::MapVariables(GrowingVariableArray& globalVars, Growing break; case IC_STORE: - if (mInstructions[i]->mSrc[1].mMemory == IM_LOCAL) + case IC_LEA: + if (mInstructions[i]->mSrc[1].mTemp < 0 && mInstructions[i]->mSrc[1].mMemory == IM_LOCAL) { localVars[mInstructions[i]->mSrc[1].mVarIndex]->mUsed = true; } @@ -9016,7 +9020,7 @@ void InterCodeBasicBlock::MapVariables(GrowingVariableArray& globalVars, Growing case IC_LOAD: case IC_CALL_NATIVE: - if (mInstructions[i]->mSrc[0].mMemory == IM_LOCAL) + if (mInstructions[i]->mSrc[0].mTemp < 0 && mInstructions[i]->mSrc[0].mMemory == IM_LOCAL) { localVars[mInstructions[i]->mSrc[0].mVarIndex]->mUsed = true; } @@ -9024,11 +9028,11 @@ void InterCodeBasicBlock::MapVariables(GrowingVariableArray& globalVars, Growing case IC_COPY: case IC_STRCPY: - if (mInstructions[i]->mSrc[0].mMemory == IM_LOCAL) + if (mInstructions[i]->mSrc[0].mTemp < 0 && mInstructions[i]->mSrc[0].mMemory == IM_LOCAL) { localVars[mInstructions[i]->mSrc[0].mVarIndex]->mUsed = true; } - if (mInstructions[i]->mSrc[1].mMemory == IM_LOCAL) + if (mInstructions[i]->mSrc[1].mTemp < 0 && mInstructions[i]->mSrc[1].mMemory == IM_LOCAL) { localVars[mInstructions[i]->mSrc[1].mVarIndex]->mUsed = true; } @@ -9687,8 +9691,6 @@ bool InterCodeBasicBlock::IsTempReferencedOnPath(int temp, int at) const bool InterCodeBasicBlock::PushSinglePathResultInstructions(void) { - int i; - bool changed = false; if (!mVisited) @@ -13451,7 +13453,7 @@ void InterCodeProcedure::WarnUsedUndefinedVariables(void) } -void InterCodeProcedure::TempForwarding(void) +void InterCodeProcedure::TempForwarding(bool reverse) { int numTemps = mTemporaries.Size(); @@ -13468,7 +13470,7 @@ void InterCodeProcedure::TempForwarding(void) mTempForwardingTable.Reset(); ResetVisited(); - mEntryBlock->PerformTempForwarding(mTempForwardingTable); + mEntryBlock->PerformTempForwarding(mTempForwardingTable, reverse); DisassembleDebug("temp forwarding"); } @@ -14000,7 +14002,7 @@ void InterCodeProcedure::Close(void) mTempForwardingTable.SetSize(numTemps); ResetVisited(); - mEntryBlock->PerformTempForwarding(mTempForwardingTable); + mEntryBlock->PerformTempForwarding(mTempForwardingTable, false); DisassembleDebug("temp forwarding 2"); @@ -14404,7 +14406,7 @@ void InterCodeProcedure::Close(void) #if 1 ResetVisited(); - if (!mInterruptCalled && mEntryBlock->CheckStaticStack()) + if (!mInterruptCalled && mNativeProcedure && mEntryBlock->CheckStaticStack()) { mLinkerObject->mFlags |= LOBJF_STATIC_STACK; mLinkerObject->mStackSection = mModule->mLinker->AddSection(mIdent->Mangle("@stack"), LST_STATIC_STACK); @@ -14467,10 +14469,22 @@ void InterCodeProcedure::Close(void) MergeBasicBlocks(); + DisassembleDebug("TempForward Rev 1"); + BuildDataFlowSets(); + TempForwarding(true); + + RemoveUnusedInstructions(); + + BuildDataFlowSets(); + + DisassembleDebug("TempForward Rev 2"); + TempForwarding(); + DisassembleDebug("TempForward Rev 3"); + BuildLoopPrefix(); BuildDataFlowSets(); @@ -14578,6 +14592,14 @@ void InterCodeProcedure::MapVariables(void) mLocalSize = 0; for (int i = 0; i < mLocalVars.Size(); i++) { +#if 0 + if (mLocalVars[i]) + { + printf("MapVars %s, %d: %s %d %d\n", + mIdent->mString, i, mLocalVars[i]->mIdent ? mLocalVars[i]->mIdent->mString : "?", + mLocalVars[i]->mUsed, mLocalVars[i]->mSize); + } +#endif if (mLocalVars[i] && mLocalVars[i]->mUsed && !mLocalVars[i]->mLinkerObject) { mLocalVars[i]->mOffset = mLocalSize; diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 429e249..ae84f9e 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -316,7 +316,7 @@ public: void LocalRenameRegister(GrowingIntArray& renameTable, int& num); void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); - void PerformTempForwarding(TempForwardingTable& forwardingTable); + void PerformTempForwarding(TempForwardingTable& forwardingTable, bool reverse); bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps); void BuildCollisionTable(NumberSet& liveTemps, NumberSet* collisionSets); @@ -435,7 +435,7 @@ public: void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars); - void PerformTempForwarding(const TempForwardingTable& forwardingTable); + void PerformTempForwarding(const TempForwardingTable& forwardingTable, bool reverse); void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int & spareTemps, const GrowingVariableArray& staticVars); void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid, const GrowingVariableArray& staticVars); bool EliminateDeadBranches(void); @@ -587,7 +587,7 @@ protected: void BuildTraces(bool expand, bool dominators = true, bool compact = false); void BuildDataFlowSets(void); void RenameTemporaries(void); - void TempForwarding(void); + void TempForwarding(bool reverse = false); void RemoveUnusedInstructions(void); bool GlobalConstantPropagation(void); bool PropagateNonLocalUsedTemps(void); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index ebf0be9..c0db621 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -713,7 +713,7 @@ bool NativeCodeInstruction::ChangesAccuAndFlag(void) const { if (mType == ASMIT_LDA || mType == ASMIT_TXA || mType == ASMIT_TYA || mType == ASMIT_ORA || mType == ASMIT_AND || mType == ASMIT_EOR || - mType == ASMIT_SBC || mType == ASMIT_ADC || mType == ASMIT_JSR) + mType == ASMIT_SBC || mType == ASMIT_ADC) return true; else if (mType == ASMIT_LSR || mType == ASMIT_ASL || mType == ASMIT_ROR || mType == ASMIT_ROL) return mMode == ASMIM_IMPLIED; @@ -721,6 +721,34 @@ bool NativeCodeInstruction::ChangesAccuAndFlag(void) const return false; } +uint32 NativeCodeInstruction::NeedsLive(void) const +{ + uint32 live = mLive; + if (mMode == ASMIM_ABSOLUTE_Y || mMode == ASMIM_INDIRECT_Y || mMode == ASMIM_ZERO_PAGE_Y) + live |= LIVE_CPU_REG_Y; + if (mMode == ASMIM_ABSOLUTE_X || mMode == ASMIM_INDIRECT_X || mMode == ASMIM_ZERO_PAGE_X) + live |= LIVE_CPU_REG_X; + + if (mType == ASMIT_TYA || mType == ASMIT_STY || mType == ASMIT_CPY || mType == ASMIT_INY || mType == ASMIT_DEY) + live |= LIVE_CPU_REG_Y; + if (mType == ASMIT_TXA || mType == ASMIT_STX || mType == ASMIT_CPX || mType == ASMIT_INX || mType == ASMIT_DEX) + live |= LIVE_CPU_REG_X; + + if (mMode == ASMIM_IMPLIED && (mType == ASMIT_TAX || mType == ASMIT_TAY || + mType == ASMIT_ASL || mType == ASMIT_LSR || mType == ASMIT_ROL || mType == ASMIT_ROR)) + live |= LIVE_CPU_REG_A; + + if (mType == ASMIT_STA || + mType == ASMIT_ORA || mType == ASMIT_AND || mType == ASMIT_EOR || + mType == ASMIT_SBC || mType == ASMIT_ADC || mType == ASMIT_CMP) + live |= LIVE_CPU_REG_A; + + if (mType == ASMIT_ADC || mType == ASMIT_SBC || mType == ASMIT_ROL || mType == ASMIT_ROR) + live |= LIVE_CPU_REG_C; + + return live; +} + bool NativeCodeInstruction::RequiresYReg(void) const { if (mMode == ASMIM_ABSOLUTE_Y || mMode == ASMIM_INDIRECT_Y || mMode == ASMIM_ZERO_PAGE_Y) @@ -6590,12 +6618,25 @@ NativeCodeBasicBlock * NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc, #if 1 if (ins->mSrc[0].mTemp < 0 && ins->mSrc[1].mTemp < 0) { - if (ins->mSrc[0].mMemory == IM_GLOBAL && ins->mSrc[1].mMemory == IM_FRAME) + if (ins->mSrc[0].mMemory == IM_GLOBAL && (ins->mSrc[1].mMemory == IM_FRAME || ins->mSrc[1].mMemory == IM_LOCAL || ins->mSrc[1].mMemory == IM_PARAM) && size < 256 && dstride == 1 && sstride == 1) { - int index = ins->mSrc[1].mVarIndex + ins->mSrc[1].mIntConst + 2; - int areg = BC_REG_STACK; - CheckFrameIndex(areg, index, size); + + int index = ins->mSrc[1].mIntConst; + if (ins->mSrc[1].mMemory == IM_FRAME) + index += ins->mSrc[1].mVarIndex + 2; + else + { + if (!mNoFrame) + areg = BC_REG_LOCALS; + + if (ins->mSrc[1].mMemory == IM_LOCAL) + index += proc->mLocalVars[ins->mSrc[1].mVarIndex]->mOffset; + else + index += ins->mSrc[1].mVarIndex + proc->mLocalSize + 2; + index += mFrameOffset; + } + CheckFrameIndex(areg, index, size, BC_REG_ADDR); if (size <= msize) { @@ -12173,11 +12214,15 @@ bool NativeCodeBasicBlock::ReduceLocalYPressure(void) { if (CanReplaceYRegWithXReg(0, mIns.Size())) { - mEntryRequiredRegs += CPU_REG_X; mEntryRequiredRegs -= CPU_REG_Y; - mExitRequiredRegs += CPU_REG_X; mExitRequiredRegs -= CPU_REG_Y; + mEntryRequiredRegs += CPU_REG_X; + mExitRequiredRegs += CPU_REG_X; pblock->mExitRequiredRegs += CPU_REG_X; pblock->mExitRequiredRegs -= CPU_REG_Y; ReplaceYRegWithXReg(0, mIns.Size()); + + mEntryRequiredRegs -= CPU_REG_Y; + mExitRequiredRegs -= CPU_REG_Y; + pblock->mIns[pz - 1].mType = ASMIT_LDX; changed = true; } @@ -14294,6 +14339,55 @@ bool NativeCodeBasicBlock::ExpandADCToBranch(NativeCodeProcedure* proc) mIns.SetSize(i + 1); break; } + else if (mIns[i + 5].mType == ASMIT_TAX && HasAsmInstructionMode(ASMIT_LDX, mIns[i + 11].mMode) && HasAsmInstructionMode(ASMIT_STX, mIns[i + 12].mMode)) + { + // Can't do direct inc, so fallback to x register + changed = true; + + NativeCodeBasicBlock* iblock = proc->AllocateBlock(); + NativeCodeBasicBlock* dblock = proc->AllocateBlock(); + NativeCodeBasicBlock* ablock = proc->AllocateBlock(); + NativeCodeBasicBlock* fblock = proc->AllocateBlock(); + + fblock->mTrueJump = mTrueJump; + fblock->mFalseJump = mFalseJump; + fblock->mBranch = mBranch; + + dblock->mIns.Push(NativeCodeInstruction(ASMIT_DEX)); + dblock->mTrueJump = ablock; + dblock->mBranch = ASMIT_JMP; + + ablock->mIns.Push(mIns[i + 7]); + ablock->mIns.Push(mIns[i + 8]); + ablock->mIns.Push(mIns[i + 9]); + if (mIns[i + 8].SameEffectiveAddress(mIns[i + 0])) + { + ablock->mIns[1].CopyMode(mIns[i + 6]); + } + + ablock->mBranch = ASMIT_BCC; + ablock->mTrueJump = fblock; + ablock->mFalseJump = iblock; + + iblock->mIns.Push(NativeCodeInstruction(ASMIT_INX)); + iblock->mTrueJump = fblock; + iblock->mBranch = ASMIT_JMP; + + mTrueJump = ablock; + mFalseJump = dblock; + mBranch = ASMIT_BPL; + + fblock->mIns.Push(NativeCodeInstruction(ASMIT_STX, mIns[i + 12])); + for (int j = i + 13; j < mIns.Size(); j++) + fblock->mIns.Push(mIns[j]); + + mIns.Insert(i, NativeCodeInstruction(ASMIT_LDX, mIns[i + 11])); + mIns[i + 1].mLive |= LIVE_CPU_REG_X; + mIns.SetSize(i + 2); + + break; + + } } } } @@ -15589,6 +15683,19 @@ static bool ChangedOnPath(const NativeCodeBasicBlock* block, int start, int end, return false; } +void NativeCodeBasicBlock::PrependInstruction(const NativeCodeInstruction& ins) +{ + mIns.Insert(0, ins); + if (mEntryRequiredRegs[CPU_REG_A]) + mIns[0].mLive |= LIVE_CPU_REG_A; + if (mEntryRequiredRegs[CPU_REG_X]) + mIns[0].mLive |= LIVE_CPU_REG_X; + if (mEntryRequiredRegs[CPU_REG_Y]) + mIns[0].mLive |= LIVE_CPU_REG_Y; + if (mEntryRequiredRegs[CPU_REG_C]) + mIns[0].mLive |= LIVE_CPU_REG_C; +} + bool NativeCodeBasicBlock::PropagateSinglePath(void) { bool changed = false; @@ -15620,9 +15727,9 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void) mFalseJump->mEntryRequiredRegs[addr] && !mTrueJump->mEntryRequiredRegs[addr] && mFalseJump->mNumEntries == 1 && !mFalseJump->mEntryRequiredRegs[CPU_REG_Z] && !mFalseJump->mEntryRequiredRegs[CPU_REG_C]) { if (mTrueJump->mEntryRequiredRegs[addr]) - mTrueJump->mIns.Insert(0, mIns[i]); + mTrueJump->PrependInstruction(mIns[i]); else - mFalseJump->mIns.Insert(0, mIns[i]); + mFalseJump->PrependInstruction(mIns[i]); mIns.Remove(i); } } @@ -15653,9 +15760,9 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void) if (mIns[i - 1].mMode == ASMIM_IMMEDIATE || (mIns[i - 1].mMode == ASMIM_ZERO_PAGE && !ChangedOnPath(this, i, mIns.Size(), mIns[i - 1].mAddress))) { if (mTrueJump->mEntryRequiredRegs[CPU_REG_X]) - mTrueJump->mIns.Insert(0, mIns[i - 1]); + mTrueJump->PrependInstruction(mIns[i - 1]); else - mFalseJump->mIns.Insert(0, mIns[i - 1]); + mFalseJump->PrependInstruction(mIns[i - 1]); mIns.Remove(i - 1); changed = true; } @@ -15672,9 +15779,9 @@ bool NativeCodeBasicBlock::PropagateSinglePath(void) if (mIns[i - 1].mMode == ASMIM_IMMEDIATE || (mIns[i - 1].mMode == ASMIM_ZERO_PAGE && !ChangedOnPath(this, i, mIns.Size(), mIns[i - 1].mAddress))) { if (mTrueJump->mEntryRequiredRegs[CPU_REG_Y]) - mTrueJump->mIns.Insert(0, mIns[i - 1]); + mTrueJump->PrependInstruction(mIns[i - 1]); else - mFalseJump->mIns.Insert(0, mIns[i - 1]); + mFalseJump->PrependInstruction(mIns[i - 1]); mIns.Remove(i - 1); changed = true; } @@ -16399,6 +16506,10 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool for (int i = index; i < mIns.Size(); i++) mIns[i].mLive |= LIVE_CPU_REG_X; mIns[index].mLive |= mIns[mIns.Size() - 1].mLive; + + mExitRequiredRegs += CPU_REG_X; + mTrueJump->mEntryRequiredRegs += CPU_REG_X; + mTrueJump->mIns.Insert(0, mIns[index]); mIns.Remove(index); changed = true; @@ -16413,6 +16524,10 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool for (int i = index; i < mIns.Size(); i++) mIns[i].mLive |= LIVE_CPU_REG_X; mIns[index].mLive |= mIns[mIns.Size() - 1].mLive; + + mExitRequiredRegs += CPU_REG_X; + mFalseJump->mEntryRequiredRegs += CPU_REG_X; + mFalseJump->mIns.Insert(0, mIns[index]); mIns.Remove(index); changed = true; @@ -16444,6 +16559,10 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool pblock->mIns.Push(mIns[0]); mIns.Remove(0); + pblock->mExitRequiredRegs += CPU_REG_Y; + mEntryRequiredRegs += CPU_REG_Y; + mExitRequiredRegs += CPU_REG_Y; + changed = true; } else if (lblock->mIns[ls - 1].mType == ASMIT_LDA && lblock->mIns[ls - 1].mMode == ASMIM_ZERO_PAGE && lblock->mIns[ls - 1].mAddress == mIns[0].mAddress && @@ -16456,6 +16575,10 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool pblock->mIns.Push(mIns[0]); mIns.Remove(0); + pblock->mExitRequiredRegs += CPU_REG_Y; + mEntryRequiredRegs += CPU_REG_Y; + mExitRequiredRegs += CPU_REG_Y; + changed = true; } } @@ -16472,6 +16595,10 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool pblock->mIns.Push(mIns[0]); mIns.Remove(0); + pblock->mExitRequiredRegs += CPU_REG_X; + mEntryRequiredRegs += CPU_REG_X; + mExitRequiredRegs += CPU_REG_X; + changed = true; } } @@ -16485,6 +16612,10 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool pblock->mIns.Push(mIns[0]); mIns.Remove(0); + pblock->mExitRequiredRegs += CPU_REG_A; + mEntryRequiredRegs += CPU_REG_A; + mExitRequiredRegs += CPU_REG_A; + lblock->mIns[ls - 1].mLive |= LIVE_CPU_REG_A; changed = true; @@ -22378,6 +22509,21 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo } } + else if (lins.mType == ASMIT_CPY && lins.mMode == ASMIM_IMMEDIATE) + { + mFDataSet.mRegs[CPU_REG_Y].mMode = NRDM_IMMEDIATE; + mFDataSet.mRegs[CPU_REG_Y].mValue = lins.mAddress; + } + else if (lins.mType == ASMIT_CPX && lins.mMode == ASMIM_IMMEDIATE) + { + mFDataSet.mRegs[CPU_REG_X].mMode = NRDM_IMMEDIATE; + mFDataSet.mRegs[CPU_REG_X].mValue = lins.mAddress; + } + else if (lins.mType == ASMIT_CMP && lins.mMode == ASMIM_IMMEDIATE) + { + mFDataSet.mRegs[CPU_REG_A].mMode = NRDM_IMMEDIATE; + mFDataSet.mRegs[CPU_REG_A].mValue = lins.mAddress; + } else if (lins.mType == ASMIT_TXA || lins.mType == ASMIT_TAX) { mFDataSet.mRegs[CPU_REG_A].mMode = NRDM_IMMEDIATE; @@ -22446,6 +22592,21 @@ bool NativeCodeBasicBlock::ValueForwarding(const NativeRegisterDataSet& data, bo mNDataSet.mRegs[lins.mAddress].mValue = 0; } } + else if (lins.mType == ASMIT_CPY && lins.mMode == ASMIM_IMMEDIATE) + { + mNDataSet.mRegs[CPU_REG_Y].mMode = NRDM_IMMEDIATE; + mNDataSet.mRegs[CPU_REG_Y].mValue = lins.mAddress; + } + else if (lins.mType == ASMIT_CPX && lins.mMode == ASMIM_IMMEDIATE) + { + mNDataSet.mRegs[CPU_REG_X].mMode = NRDM_IMMEDIATE; + mNDataSet.mRegs[CPU_REG_X].mValue = lins.mAddress; + } + else if (lins.mType == ASMIT_CMP && lins.mMode == ASMIM_IMMEDIATE) + { + mNDataSet.mRegs[CPU_REG_A].mMode = NRDM_IMMEDIATE; + mNDataSet.mRegs[CPU_REG_A].mValue = lins.mAddress; + } else if (lins.mType == ASMIT_TXA || lins.mType == ASMIT_TAX) { mNDataSet.mRegs[CPU_REG_A].mMode = NRDM_IMMEDIATE; @@ -32091,6 +32252,14 @@ void NativeCodeBasicBlock::CheckLive(void) if (mIns[j].RequiresCarry()) live |= LIVE_CPU_REG_C; } } + + if (mEntryRequiredRegs.Size() > 0) + { + if (live & LIVE_CPU_REG_X) + assert(mEntryRequiredRegs[CPU_REG_X]); + if (live & LIVE_CPU_REG_Y) + assert(mEntryRequiredRegs[CPU_REG_Y]); + } #endif } @@ -33121,7 +33290,7 @@ void NativeCodeProcedure::RebuildEntry(void) void NativeCodeProcedure::Optimize(void) { - CheckFunc = !strcmp(mInterProc->mIdent->mString, "checkKeys"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "hcw_irq"); #if 1 int step = 0; diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index f0d478b..e825ed6 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -153,6 +153,7 @@ public: void BuildCollisionTable(NumberSet& liveTemps, NumberSet* collisionSets); + uint32 NeedsLive(void) const; }; class NativeCodeBasicBlock @@ -198,6 +199,8 @@ public: void Assemble(void); void Close(NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump, AsmInsType branch); + void PrependInstruction(const NativeCodeInstruction& ins); + void ShortcutTailRecursion(); bool ReferencesAccu(int from = 0) const;