diff --git a/include/c64/vic.c b/include/c64/vic.c index ba602fa..af135df 100644 --- a/include/c64/vic.c +++ b/include/c64/vic.c @@ -94,4 +94,24 @@ void vic_waitLine(int line) } while ((vic.ctrl1 & VIC_CTRL1_RST8) != upper); } +void vic_waitBelow(int line) +{ + char upper = (char)(line >> 1) & VIC_CTRL1_RST8; + char lower = (char)line; + + if (upper) + { + do + { + while (vic.raster <= lower) + ; + } while (!(vic.ctrl1 & VIC_CTRL1_RST8)); + } + else + { + while (vic.raster <= lower) + ; + } +} + #pragma native(vic_waitLine) diff --git a/include/c64/vic.h b/include/c64/vic.h index d420778..aa470de 100644 --- a/include/c64/vic.h +++ b/include/c64/vic.h @@ -115,6 +115,9 @@ void vic_waitFrames(char n); // wait for a specific raster line void vic_waitLine(int line); +// wait for beam to be below a line +void vic_waitBelow(int line); + // reference to the VIC chip #define vic (*((struct VIC *)0xd000)) diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index a9130af..d066df7 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -14531,6 +14531,67 @@ static bool IsInsSrcModifiedInBlocks(const ExpandingArray& return false; } +void InterCodeBasicBlock::SingleLoopCountZeroCheck(void) +{ + if (!mVisited) + { + mVisited = true; + + if (mLoopHead && mEntryBlocks.Size() == 2 && mFalseJump && (mTrueJump == this || mFalseJump == this) && mInstructions.Size() > 3) + { + int nins = mInstructions.Size(); + + InterCodeBasicBlock * pblock = mEntryBlocks[0]; + if (pblock == this) + pblock = mEntryBlocks[1]; + while (pblock->mInstructions.Size() == 1 && pblock->mInstructions[0]->mCode == IC_JUMP && pblock->mEntryBlocks.Size() == 1) + pblock = pblock->mEntryBlocks[0]; + + if (mInstructions[nins - 1]->mCode == IC_BRANCH && + mInstructions[nins - 2]->mCode == IC_RELATIONAL_OPERATOR && + mInstructions[nins - 3]->mCode == IC_BINARY_OPERATOR && mInstructions[nins - 3]->mOperator == IA_ADD) + { + InterInstruction* ains = mInstructions[nins - 3]; + InterInstruction* cins = mInstructions[nins - 2]; + InterInstruction* bins = mInstructions[nins - 1]; + + if (bins->mSrc[0].mTemp == cins->mDst.mTemp && + cins->mSrc[1].mTemp == ains->mDst.mTemp && + cins->mSrc[0].mTemp < 0 && + ains->mSrc[1].mTemp == ains->mDst.mTemp && + ains->mSrc[0].mTemp < 0 && + cins->mOperator == IA_CMPGS && + ains->mSrc[0].mIntConst < -1 && + cins->mSrc[0].mIntConst > 0 && + cins->mSrc[0].mIntConst < - ains->mSrc[0].mIntConst && + !IsTempModifiedInRange(0, nins - 3, ains->mDst.mTemp)) + { + int pi = pblock->mInstructions.Size() - 1; + while (pi >= 0 && pblock->mInstructions[pi]->mDst.mTemp != ains->mDst.mTemp) + pi--; + if (pi >= 0 && pblock->mInstructions[pi]->mCode == IC_CONSTANT) + { + int64 istart = pblock->mInstructions[pi]->mConst.mIntConst; + if (istart > 0) + { + int64 iend = istart % -ains->mSrc[0].mIntConst; + + if (cins->mSrc[0].mIntConst < iend) + { + cins->mSrc[0].mIntConst = 0; + cins->mOperator = IA_CMPGES; + } + } + } + } + } + } + + if (mTrueJump) mTrueJump->SingleLoopCountZeroCheck(); + if (mFalseJump) mFalseJump->SingleLoopCountZeroCheck(); + } +} + bool InterCodeBasicBlock::MoveConditionOutOfLoop(void) { if (!mVisited) @@ -20208,6 +20269,9 @@ void InterCodeProcedure::Close(void) } #endif + ResetVisited(); + mEntryBlock->SingleLoopCountZeroCheck(); + RemoveUnusedPartialStoreInstructions(); MapVariables(); diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 0323825..5bdd41a 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -579,6 +579,7 @@ public: void InnerLoopOptimization(const NumberSet& aliasedParams); void PushMoveOutOfLoop(void); bool MoveConditionOutOfLoop(void); + void SingleLoopCountZeroCheck(void); void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue); void RemoveUnusedMallocs(void); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 8e4b0c6..9a41c65 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -14401,6 +14401,64 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full) yoffset = 2; changed = true; } + + else if (yoffset == 0xff && i + 1 < mIns.Size() && mIns[i + 1].mType == ASMIT_DEY) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + changed = true; + } + else if (yoffset == 0xff) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + + mIns[i + 0].mType = ASMIT_INY; mIns[i + 0].mMode = ASMIM_IMPLIED; + yoffset = 0; + changed = true; + } + else if (yoffset == 0xfe && i + 2 < mIns.Size() && mIns[i + 1].mType == ASMIT_DEY && mIns[i + 2].mType == ASMIT_DEY) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + changed = true; + } + else if (yoffset == 0xfe && i + 1 < mIns.Size() && mIns[i + 1].mType == ASMIT_DEY) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_INY; + changed = true; + } + else if (yoffset == 0xfd && i + 2 < mIns.Size() && mIns[i + 1].mType == ASMIT_DEY && mIns[i + 2].mType == ASMIT_DEY) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_INY; mIns[i + 2].mMode = ASMIM_IMPLIED; + changed = true; + } + else if (yoffset == 0xfd && i + 1 < mIns.Size() && mIns[i + 1].mType == ASMIT_DEY) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + + mIns[i + 0].mType = ASMIT_INY; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_INY; mIns[i + 1].mMode = ASMIM_IMPLIED; + yoffset = 0xfe; + changed = true; + } else yoffset = 0; ypred = i; @@ -14419,7 +14477,7 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full) mIns[j + 2].mType == ASMIT_STA && mIns[j + 2].mMode == ASMIM_ZERO_PAGE && mIns[j + 2].mAddress == yreg && !(mIns[j + 2].mLive & LIVE_CPU_REG_C)) { - if (mIns[j + 1].mAddress == yoffset + 1) + if (mIns[j + 1].mAddress == ((yoffset + 1) & 0xff)) { for (int k = ypred; k < i; k++) mIns[k].mLive |= LIVE_CPU_REG_Y; @@ -14432,6 +14490,19 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full) i += 2; changed = true; } + else if (mIns[j + 1].mAddress == ((yoffset - 1) & 0xff)) + { + for (int k = ypred; k < i; k++) + mIns[k].mLive |= LIVE_CPU_REG_Y; + + mIns.Remove(j + 2); + mIns.Remove(j + 1); + mIns.Remove(j - 1); + mIns.Insert(i, NativeCodeInstruction(mIns[i].mIns, ASMIT_DEY)); + mIns.Insert(i + 1, NativeCodeInstruction(mIns[i].mIns, ASMIT_STY, ASMIM_ZERO_PAGE, yreg)); + i += 2; + changed = true; + } } } @@ -14446,7 +14517,7 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full) mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mType == ASMIT_TAY) { - if (mIns[i + 1].mAddress == yreg && mIns[i + 2].mAddress == yoffset + 1 && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C))) + if (mIns[i + 1].mAddress == yreg && mIns[i + 2].mAddress == ((yoffset + 1) & 0xff) && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C))) { for (int j = ypred; j < i; j++) mIns[j].mLive |= LIVE_CPU_REG_Y; @@ -14456,6 +14527,16 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full) mIns[i + 3].mType = ASMIT_INY; changed = true; } + else if (mIns[i + 1].mAddress == yreg && mIns[i + 2].mAddress == ((yoffset - 1) & 0xff) && !(mIns[i + 3].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_C))) + { + for (int j = ypred; j < i; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y; + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + mIns[i + 3].mType = ASMIT_DEY; + changed = true; + } else { yreg = mIns[i + 1].mAddress; @@ -14467,18 +14548,18 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full) else if (i + 3 < mIns.Size() && mIns[i + 0].mType == ASMIT_CLC && mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == yreg && - mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == yoffset + 1 && + mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == ((yoffset + 1) & 0xff) && mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 3].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C))) { for (int j = ypred; j < i + 3; j++) - mIns[j].mLive |= LIVE_CPU_REG_Y; + mIns[j].mLive |= LIVE_CPU_REG_Y | (mIns[i + 3].mLive & LIVE_CPU_REG_Z); mIns[i + 0].mType = ASMIT_INY; mIns[i + 1].mType = ASMIT_STY; mIns[i + 1].mAddress = mIns[i + 3].mAddress; mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; ypred = i + 1; - yoffset++; + yoffset = (yoffset + 1) & 0xff; if (mIns[i + 3].mLive & LIVE_CPU_REG_A) { @@ -14495,18 +14576,46 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full) else if (i + 3 < mIns.Size() && mIns[i + 0].mType == ASMIT_CLC && mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == yreg && - mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == yoffset + 2 && + mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == ((yoffset - 1) & 0xff) && mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && !(mIns[i + 3].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C))) { for (int j = ypred; j < i + 3; j++) - mIns[j].mLive |= LIVE_CPU_REG_Y; + mIns[j].mLive |= LIVE_CPU_REG_Y | (mIns[i + 3].mLive & LIVE_CPU_REG_Z); + mIns[i + 0].mType = ASMIT_DEY; + mIns[i + 1].mType = ASMIT_STY; mIns[i + 1].mAddress = mIns[i + 3].mAddress; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + + ypred = i + 1; + yoffset = (yoffset - 1) & 0xff; + + if (mIns[i + 3].mLive & LIVE_CPU_REG_A) + { + mIns[i + 3].mType = ASMIT_TYA; + mIns[i + 3].mMode = ASMIM_IMPLIED; + } + else + { + mIns[i + 3].mType = ASMIT_NOP; + mIns[i + 3].mMode = ASMIM_IMPLIED; + } + changed = true; + } + else if (i + 3 < mIns.Size() && + mIns[i + 0].mType == ASMIT_CLC && + mIns[i + 1].mType == ASMIT_LDA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress == yreg && + mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress == ((yoffset + 2) & 0xff) && + mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && + !(mIns[i + 3].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C))) + { + for (int j = ypred; j < i + 3; j++) + mIns[j].mLive |= LIVE_CPU_REG_Y | (mIns[i + 3].mLive & LIVE_CPU_REG_Z); mIns[i + 0].mType = ASMIT_INY; mIns[i + 1].mType = ASMIT_INY; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 2].mType = ASMIT_STY; mIns[i + 2].CopyMode(mIns[i + 3]); ypred = i + 1; - yoffset++; + yoffset = (yoffset + 2) & 0xff; if (mIns[i + 3].mLive & LIVE_CPU_REG_A) { @@ -14531,7 +14640,7 @@ bool NativeCodeBasicBlock::ForwardZpYIndex(bool full) mIns[i + 1].mType = ASMIT_STY; ypred = i + 1; - yoffset++; + yoffset = (yoffset + 1) & 0xff; changed = true; } @@ -14898,7 +15007,7 @@ bool NativeCodeBasicBlock::JoinXYCascade(void) mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE) { - if (predXPos >= 0 && !(mIns[i + 2].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_C)) && mIns[predXPos + 2].mAddress + 1 == mIns[i + 2].mAddress) + if (predXPos >= 0 && !(mIns[i + 2].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_C)) && ((mIns[predXPos + 2].mAddress + 1) & 0xff) == mIns[i + 2].mAddress) { // Remove add mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; @@ -14918,6 +15027,26 @@ bool NativeCodeBasicBlock::JoinXYCascade(void) changed = true; } + else if (predXPos >= 0 && !(mIns[i + 2].mLive & (LIVE_CPU_REG_X | LIVE_CPU_REG_C)) && ((mIns[predXPos + 2].mAddress - 1) & 0xff) == mIns[i + 2].mAddress) + { + // Remove add + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + + // Insert DEX + mIns.Insert(i, NativeCodeInstruction(mIns[i].mIns, ASMIT_DEX)); + + // Insert TAX + mIns[predXPos + 2].mLive &= ~LIVE_CPU_REG_X; + mIns.Insert(predXPos + 3, NativeCodeInstruction(mIns[i].mIns, ASMIT_TAX)); + + // Restart + restart = true; + predXPos = -1; + predYPos = -1; + + changed = true; + } else predXPos = i; } @@ -14927,7 +15056,7 @@ bool NativeCodeBasicBlock::JoinXYCascade(void) mIns[i + 1].mType == ASMIT_CLC && mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE) { - if (predYPos >= 0 && !(mIns[i + 2].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C)) && mIns[predYPos + 2].mAddress + 1 == mIns[i + 2].mAddress) + if (predYPos >= 0 && !(mIns[i + 2].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C)) && ((mIns[predYPos + 2].mAddress + 1) & 0xff) == mIns[i + 2].mAddress) { // Remove add mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; @@ -14947,6 +15076,26 @@ bool NativeCodeBasicBlock::JoinXYCascade(void) changed = true; } + else if (predYPos >= 0 && !(mIns[i + 2].mLive & (LIVE_CPU_REG_Y | LIVE_CPU_REG_C)) && ((mIns[predYPos + 2].mAddress - 1) & 0xff) == mIns[i + 2].mAddress) + { + // Remove add + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + + // Insert DEY + mIns.Insert(i, NativeCodeInstruction(mIns[i].mIns, ASMIT_DEY)); + + // Insert TAX + mIns[predYPos + 2].mLive &= ~LIVE_CPU_REG_Y; + mIns.Insert(predYPos + 3, NativeCodeInstruction(mIns[i].mIns, ASMIT_TAY)); + + // Restart + restart = true; + predXPos = -1; + predYPos = -1; + + changed = true; + } else predYPos = i; } @@ -41436,6 +41585,25 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 3].mType = ASMIT_NOP; progress = true; } + else if ( + mIns[i + 0].mType == ASMIT_TXA && + mIns[i + 1].mType == ASMIT_CLC && + mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress >= 0xfe && + mIns[i + 3].mType == ASMIT_TAX && !(mIns[i + 3].mLive & LIVE_CPU_REG_C)) + { + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_DEX; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_X | LIVE_CPU_REG_Z; + if (mIns[i + 2].mAddress == 0xfe) + mIns[i + 2].mType = ASMIT_DEX; + else + mIns[i + 2].mType = ASMIT_NOP; + mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mLive |= LIVE_CPU_REG_X; + if (mIns[i + 3].mLive & LIVE_CPU_REG_A) + mIns[i + 3].mType = ASMIT_TXA; + else + mIns[i + 3].mType = ASMIT_NOP; + progress = true; + } #endif else if ( mIns[i + 0].mType == ASMIT_TXA && @@ -41474,6 +41642,25 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 3].mMode = ASMIM_IMPLIED; progress = true; } + else if ( + mIns[i + 0].mType == ASMIT_TYA && + mIns[i + 1].mType == ASMIT_CLC && + mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE && mIns[i + 2].mAddress >= 0xfe && + mIns[i + 3].mType == ASMIT_TAY && !(mIns[i + 3].mLive & LIVE_CPU_REG_C)) + { + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 1].mType = ASMIT_DEY; mIns[i + 1].mMode = ASMIM_IMPLIED; mIns[i + 1].mLive |= LIVE_CPU_REG_Y | LIVE_CPU_REG_Z; + if (mIns[i + 2].mAddress == 0xfe) + mIns[i + 2].mType = ASMIT_DEY; + else + mIns[i + 2].mType = ASMIT_NOP; + mIns[i + 2].mMode = ASMIM_IMPLIED; mIns[i + 2].mLive |= LIVE_CPU_REG_Y; + if (mIns[i + 3].mLive & LIVE_CPU_REG_A) + mIns[i + 3].mType = ASMIT_TYA; + else + mIns[i + 3].mType = ASMIT_NOP; + progress = true; + } else if ( mIns[i + 0].mType == ASMIT_TYA && mIns[i + 1].mType == ASMIT_SEC && @@ -45239,7 +45426,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) { mInterProc = proc; - CheckFunc = !strcmp(mInterProc->mIdent->mString, "check"); + CheckFunc = !strcmp(mInterProc->mIdent->mString, "test"); int nblocks = proc->mBlocks.Size(); tblocks = new NativeCodeBasicBlock * [nblocks]; @@ -47779,7 +47966,7 @@ void NativeCodeGenerator::BuildFunctionProxies(void) { if (ncp->mCount > 1) { - printf("RFC %s : %d\n", ncp->mLinkerObject->mIdent->mString, ncp->mCount); +// printf("RFC %s : %d\n", ncp->mLinkerObject->mIdent->mString, ncp->mCount); ncp->mProxyObject = mLinker->AddObject(ncp->mLinkerObject->mLocation, ncp->mLinkerObject->mIdent->Mangle("@proxy"), ncp->mLinkerObject->mSection, ncp->mLinkerObject->mType); ExpandingArray code; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index a65ad7c..c789772 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -8925,7 +8925,7 @@ Expression* Parser::ParseStatement(void) if ((initExp->mType == EX_ASSIGNMENT || initExp->mType == EX_INITIALIZATION) && initExp->mLeft->mType == EX_VARIABLE && initExp->mRight->mType == EX_CONSTANT && (iterateExp->mType == EX_POSTINCDEC || iterateExp->mType == EX_PREINCDEC || iterateExp->mType == EX_ASSIGNMENT && iterateExp->mToken == TK_ASSIGN_ADD && iterateExp->mRight->mType == EX_CONSTANT) && iterateExp->mLeft->IsSame(initExp->mLeft) && - conditionExp->mType == EX_RELATIONAL && (conditionExp->mToken == TK_LESS_THAN || conditionExp->mToken == TK_GREATER_THAN) && conditionExp->mLeft->IsSame(initExp->mLeft) && conditionExp->mRight->mType == EX_CONSTANT) + conditionExp->mType == EX_RELATIONAL && (conditionExp->mToken == TK_LESS_THAN || conditionExp->mToken == TK_GREATER_THAN || conditionExp->mToken == TK_LESS_EQUAL || conditionExp->mToken == TK_GREATER_EQUAL) && conditionExp->mLeft->IsSame(initExp->mLeft) && conditionExp->mRight->mType == EX_CONSTANT) { if (initExp->mRight->mDecValue->mType == DT_CONST_INTEGER && conditionExp->mRight->mDecValue->mType == DT_CONST_INTEGER) { @@ -8933,6 +8933,17 @@ Expression* Parser::ParseStatement(void) int endValue = int(conditionExp->mRight->mDecValue->mInteger); int stepValue = 1; + if (conditionExp->mToken == TK_LESS_EQUAL) + { + endValue++; + conditionExp->mToken = TK_LESS_THAN; + } + else if (conditionExp->mToken == TK_GREATER_EQUAL) + { + endValue--; + conditionExp->mToken = TK_GREATER_THAN; + } + if (iterateExp->mType == EX_ASSIGNMENT) stepValue = int(iterateExp->mRight->mDecValue->mInteger); else if (iterateExp->mToken == TK_DEC) @@ -9018,7 +9029,7 @@ Expression* Parser::ParseStatement(void) Expression* unrollBody = new Expression(mScanner->mLocation, EX_SEQUENCE); unrollBody->mLeft = bodyExp; Expression* bexp = unrollBody; - if (endValue > startValue) + if ((endValue - startValue) * stepValue > 0) { for (int i = 1; i < unrollLoop; i++) { @@ -9029,6 +9040,8 @@ Expression* Parser::ParseStatement(void) bexp = bexp->mRight; bexp->mLeft = bodyExp; } + + conditionExp->mRight->mDecValue->mInteger = endValue - stepValue * (unrollLoop - 1); } if (remain)