From 8b631d564e41d07434fb133c126c4e25cfc865da Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Sat, 3 Dec 2022 13:28:03 +0100 Subject: [PATCH] Add autotest for striped arrays --- autotest/autotest.bat | 21 ++ autotest/stripedarraytest.c | 299 ++++++++++++++++ oscar64/InterCode.cpp | 47 ++- oscar64/InterCode.h | 2 +- oscar64/InterCodeGenerator.cpp | 19 +- oscar64/NativeCodeGenerator.cpp | 584 ++++++++++++++++++++------------ oscar64/Parser.cpp | 3 + 7 files changed, 736 insertions(+), 239 deletions(-) create mode 100644 autotest/stripedarraytest.c diff --git a/autotest/autotest.bat b/autotest/autotest.bat index cc582cc..83f9b59 100644 --- a/autotest/autotest.bat +++ b/autotest/autotest.bat @@ -153,6 +153,9 @@ rem @echo off @call :test cplxstructtest.c @if %errorlevel% neq 0 goto :error +@call :testn stripedarraytest.c +@if %errorlevel% neq 0 goto :error + @exit /b 0 :error @@ -209,3 +212,21 @@ exit /b %errorlevel% @if %errorlevel% neq 0 goto :error @exit /b 0 + +:testn +..\release\oscar64 -e -n %~1 +@if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -O2 -n %~1 +@if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -O0 -n %~1 +@if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -Os -n %~1 +@if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -O3 -n %~1 +@if %errorlevel% neq 0 goto :error + +@exit /b 0 diff --git a/autotest/stripedarraytest.c b/autotest/stripedarraytest.c new file mode 100644 index 0000000..cbbdc27 --- /dev/null +++ b/autotest/stripedarraytest.c @@ -0,0 +1,299 @@ +#include + + +int a100[100]; +__striped int b100[100]; +__striped int c100[100]; + +unsigned a256[256]; +__striped unsigned b256[256]; +__striped unsigned c256[256]; + +#pragma align(c100, 256) +#pragma align(c256, 256) + +void test_ab100(void) +{ + for(char i=0; i<100; i++) + { + a100[i] = i * i; + b100[i] = i * i; + c100[i] = i * i; + } + + a100[31] = 4711; + b100[31] = 4711; + c100[31] = 4711; + + + for(char i=0; i<100; i++) + { + a100[i] += i; a100[i] -= 5; a100[i] = a100[i] + a100[99 - i]; + b100[i] += i; b100[i] -= 5; b100[i] = b100[i] + b100[99 - i]; + c100[i] += i; c100[i] -= 5; c100[i] = c100[i] + c100[99 - i]; + } + + for(char i=0; i<100; i++) + { + assert(a100[i] == b100[i]); + assert(a100[i] == c100[i]); + } +} + +void test_ab256(void) +{ + for(unsigned i=0; i<256; i++) + { + a256[i] = i * i; + b256[i] = i * i; + c256[i] = i * i; + } + + a256[31] = 4711; + b256[31] = 4711; + c256[31] = 4711; + + for(unsigned i=0; i<256; i++) + { + a256[i] += i; a256[i] -= 5; a256[i] = a256[i] + a256[255 - i]; + b256[i] += i; b256[i] -= 5; b256[i] = b256[i] + b256[255 - i]; + c256[i] += i; c256[i] -= 5; c256[i] = c256[i] + c256[255 - i]; + } + + for(unsigned i=0; i<256; i++) + { + assert(a256[i] == b256[i]); + assert(a256[i] == c256[i]); + } +} + +long la50[50]; +__striped long lb50[50]; +__striped long lc50[50]; + +unsigned long la256[256]; +__striped unsigned long lb256[256]; +__striped unsigned long lc256[256]; + +#pragma align(lc50, 256) +#pragma align(lc256, 256) + +void test_lab50(void) +{ + for(char i=0; i<50; i++) + { + long j = i * i; + la50[i] = j * j; + lb50[i] = j * j; + lc50[i] = j * j; + } + + la50[31] = 47110815l; + lb50[31] = 47110815l; + lc50[31] = 47110815l; + + for(char i=0; i<50; i++) + { + la50[i] += i; la50[i] -= 12345678l; la50[i] = la50[i] + la50[49 - i]; + lb50[i] += i; lb50[i] -= 12345678l; lb50[i] = lb50[i] + lb50[49 - i]; + lc50[i] += i; lc50[i] -= 12345678l; lc50[i] = lc50[i] + lc50[49 - i]; + } + + for(char i=0; i<50; i++) + { + assert(la50[i] == lb50[i]); + assert(la50[i] == lc50[i]); + } +} + +void test_lab256(void) +{ + for(unsigned i=0; i<256; i++) + { + unsigned long j = i * i; + la256[i] = j * j; + lb256[i] = j * j; + lc256[i] = j * j; + } + + la256[31] = 47110815ul; + lb256[31] = 47110815ul; + lc256[31] = 47110815ul; + + for(unsigned i=0; i<256; i++) + { + la256[i] += i; la256[i] -= 12345678ul; la256[i] = la256[i] + la256[255 - i]; + lb256[i] += i; lb256[i] -= 12345678ul; lb256[i] = lb256[i] + lb256[255 - i]; + lc256[i] += i; lc256[i] -= 12345678ul; lc256[i] = lc256[i] + lc256[255 - i]; + } + + for(unsigned i=0; i<256; i++) + { + assert(la256[i] == lb256[i]); + assert(la256[i] == lc256[i]); + } +} + +float fa50[50]; +__striped float fb50[50]; +__striped float fc50[50]; + +float fa256[256]; +__striped float fb256[256]; +__striped float fc256[256]; + +#pragma align(fc50, 256) +#pragma align(fc256, 256) + +void test_fab50(void) +{ + for(char i=0; i<50; i++) + { + fa50[i] = i * i; + fb50[i] = i * i; + fc50[i] = i * i; + } + + fa50[31] = 4711.0815; + fb50[31] = 4711.0815; + fc50[31] = 4711.0815; + + for(char i=0; i<50; i++) + { + fa50[i] += i; fa50[i] -= 1234.5678; fa50[i] = fa50[i] + fa50[49 - i]; + fb50[i] += i; fb50[i] -= 1234.5678; fb50[i] = fb50[i] + fb50[49 - i]; + fc50[i] += i; fc50[i] -= 1234.5678; fc50[i] = fc50[i] + fc50[49 - i]; + } + + for(char i=0; i<50; i++) + { + assert(fa50[i] == fb50[i]); + assert(fa50[i] == fc50[i]); + } +} + +void test_fab256(void) +{ + for(unsigned i=0; i<256; i++) + { + fa256[i] = i * i; + fb256[i] = i * i; + fc256[i] = i * i; + } + + fa256[31] = 4711.0815; + fb256[31] = 4711.0815; + fc256[31] = 4711.0815; + + for(unsigned i=0; i<256; i++) + { + fa256[i] += i; fa256[i] -= 1234.5678; fa256[i] = fa256[i] + fa256[255 - i]; + fb256[i] += i; fb256[i] -= 1234.5678; fb256[i] = fb256[i] + fb256[255 - i]; + fc256[i] += i; fc256[i] -= 1234.5678; fc256[i] = fc256[i] + fc256[255 - i]; + } + + for(unsigned i=0; i<256; i++) + { + assert(fa256[i] == fb256[i]); + assert(fa256[i] == fc256[i]); + } +} + + +unsigned da50[50], db50[50], dc50[50]; + +unsigned * pa50[50]; +__striped unsigned * pb50[50]; +__striped unsigned * pc50[50]; + +#pragma align(pc50, 256) + +void test_pab50(void) +{ + for(char i=0; i<50; i++) + { + pa50[i] = da50 + (i * 17) % 50; + pb50[i] = db50 + (i * 17) % 50; + pc50[i] = dc50 + (i * 17) % 50; + } + + for(char i=0; i<50; i++) + { + *pa50[i] = i * i; + *pb50[i] = i * i; + *pc50[i] = i * i; + } + + for(char i=0; i<50; i++) + { + *pa50[i] += i; *pa50[i] -= 5; *pa50[i] = *pa50[i] + *pa50[49 - i]; + *pb50[i] += i; *pb50[i] -= 5; *pb50[i] = *pb50[i] + *pb50[49 - i]; + *pc50[i] += i; *pc50[i] -= 5; *pc50[i] = *pc50[i] + *pc50[49 - i]; + } + + for(char i=0; i<50; i++) + { + assert(*pa50[i] == *pb50[i]); + assert(*pa50[i] == *pc50[i]); + assert(da50[i] == db50[i]); + assert(da50[i] == dc50[i]); + } +} + +unsigned da50_4[50][4], db50_4[50][4], dc50_4[50][4]; + +void test_pab50_4(void) +{ + for(char i=0; i<50; i++) + { + pa50[i] = da50_4[(i * 17) % 50]; + pb50[i] = db50_4[(i * 17) % 50]; + pc50[i] = dc50_4[(i * 17) % 50]; + } + + for(char k=0; k<4; k++) + { + for(char i=0; i<50; i++) + { + pa50[i][k] = i * i; + pb50[i][k] = i * i; + pc50[i][k] = i * i; + } + } + + for(char k=0; k<4; k++) + { + for(char i=0; i<50; i++) + { + pa50[i][k] += i; pa50[i][k] -= 5; pa50[i][k] = pa50[i][k] + pa50[49 - i][k]; + pb50[i][k] += i; pb50[i][k] -= 5; pb50[i][k] = pb50[i][k] + pb50[49 - i][k]; + pc50[i][k] += i; pc50[i][k] -= 5; pc50[i][k] = pc50[i][k] + pc50[49 - i][k]; + } + } + + for(char k=0; k<4; k++) + { + for(char i=0; i<50; i++) + { + assert(pa50[i][k] == pb50[i][k]); + assert(pa50[i][k] == pc50[i][k]); + assert(da50_4[i][k] == db50_4[i][k]); + assert(da50_4[i][k] == dc50_4[i][k]); + } + } +} + + +int main(void) +{ + test_ab100(); + test_ab256(); + test_lab50(); + test_lab256(); + test_fab50(); + test_fab256(); + test_pab50(); + test_pab50_4(); + + return 0; +} diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 95760f5..4c13164 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -3083,10 +3083,11 @@ bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray& } } + return changed; } -bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars, NumberSet& requiredVars) +bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars, NumberSet& requiredVars, GrowingInstructionPtrArray& storeIns) { bool changed = false; @@ -3104,6 +3105,14 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariable { requiredVars += mSrc[0].mVarIndex; } + + int k = 0; + for (int i = 0; i < storeIns.Size(); i++) + { + if (!CollidingMem(this, storeIns[i], staticVars)) + storeIns[k++] = storeIns[i]; + } + storeIns.SetSize(k); } else if (mCode == IC_STORE) { @@ -3121,16 +3130,43 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariable changed = true; } } + else + { + int i = 0; + while (i < storeIns.Size() && !SameMem(mSrc[1], storeIns[i])) + i++; + if (!mVolatile && i < storeIns.Size()) + { + mCode = IC_NONE; + mNumOperands = 0; + changed = true; + } + else + { + int k = 0; + for (int i = 0; i < storeIns.Size(); i++) + { + if (!CollidingMem(this, storeIns[i], staticVars)) + storeIns[k++] = storeIns[i]; + } + storeIns.SetSize(k); + } + } } else if (mCode == IC_COPY || mCode == IC_STRCPY) { requiredVars.Fill(); + storeIns.SetSize(0); } else if (mCode == IC_CALL || mCode == IC_CALL_NATIVE || mCode == IC_RETURN || mCode == IC_RETURN_STRUCT || mCode == IC_RETURN_VALUE) { requiredVars.Fill(); + storeIns.SetSize(0); } + if (mCode == IC_STORE) + storeIns.Push(this); + return changed; } @@ -6959,13 +6995,14 @@ bool InterCodeBasicBlock::RemoveUnusedStaticStoreInstructions(const GrowingVaria { mVisited = true; - NumberSet requiredVars(mExitRequiredStatics); + NumberSet requiredVars(mExitRequiredStatics); + GrowingInstructionPtrArray storeIns(nullptr); int i; for (i = mInstructions.Size() - 1; i >= 0; i--) { - if (mInstructions[i]->RemoveUnusedStaticStoreInstructions(staticVars, requiredVars)) + if (mInstructions[i]->RemoveUnusedStaticStoreInstructions(staticVars, requiredVars, storeIns)) changed = true; } @@ -7084,8 +7121,8 @@ bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArr { mVisited = true; - NumberSet requiredVars(mExitRequiredVars); - NumberSet requiredParams(mExitRequiredParams); + NumberSet requiredVars(mExitRequiredVars); + NumberSet requiredParams(mExitRequiredParams); int i; diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index 6696952..e0b8737 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -307,7 +307,7 @@ public: bool RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps); bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredVars, const GrowingVariableArray& params, NumberSet& requiredParams, InterMemory paramMemory); - bool RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars, NumberSet& requiredVars); + bool RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars, NumberSet& requiredVars, GrowingInstructionPtrArray& storeIns); void PerformValueForwarding(GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid); void BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSet& callerSaveTemps); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 6653e15..472c140 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -1059,11 +1059,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* if (exp->mToken == TK_ASSIGN_ADD) { - cins->mConst.mIntConst = vl.mType->mBase->mSize; + cins->mConst.mIntConst = vl.mType->Stride(); } else if (exp->mToken == TK_ASSIGN_SUB) { - cins->mConst.mIntConst = -vl.mType->mBase->mSize; + cins->mConst.mIntConst = -vl.mType->Stride(); } else mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid pointer assignment"); @@ -1305,6 +1305,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* Declaration* ptype = new Declaration(exp->mLocation, DT_TYPE_POINTER); ptype->mBase = vl.mType->mBase; ptype->mSize = 2; + ptype->mStride = vl.mType->mStride; vl.mType = ptype; } @@ -1314,11 +1315,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* if (exp->mToken == TK_ADD) { - cins->mConst.mIntConst = vl.mType->mBase->mSize; + cins->mConst.mIntConst = vl.mType->Stride(); } else if (exp->mToken == TK_SUB) { - cins->mConst.mIntConst = -vl.mType->mBase->mSize; + cins->mConst.mIntConst = -vl.mType->Stride(); } else mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid pointer operation"); @@ -1368,7 +1369,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* block->Append(crins); InterInstruction * cins = new InterInstruction(exp->mLocation, IC_CONSTANT); - cins->mConst.mIntConst = vl.mType->mBase->mSize; + cins->mConst.mIntConst = vl.mType->Stride(); cins->mDst.mType = IT_INT16; cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType); block->Append(cins); @@ -1420,7 +1421,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* if (exp->mToken == TK_ADD) { - cins->mConst.mIntConst = vr.mType->mBase->mSize; + cins->mConst.mIntConst = vr.mType->Stride(); } else mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid pointer operation"); @@ -1602,7 +1603,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* cins->mDst.mType = ftype ? IT_FLOAT : IT_INT16; cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType); if (vdl.mType->mType == DT_TYPE_POINTER) - cins->mConst.mIntConst = exp->mToken == TK_INC ? vdl.mType->mBase->mSize : -(vdl.mType->mBase->mSize); + cins->mConst.mIntConst = exp->mToken == TK_INC ? vdl.mType->Stride() : -(vdl.mType->Stride()); else if (vdl.mType->IsNumericType()) cins->mConst.mIntConst = exp->mToken == TK_INC ? 1 : -1; else @@ -1663,7 +1664,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* cins->mDst.mType = ftype ? IT_FLOAT : IT_INT16; cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType); if (vdl.mType->mType == DT_TYPE_POINTER) - cins->mConst.mIntConst = exp->mToken == TK_INC ? vdl.mType->mBase->mSize : -(vdl.mType->mBase->mSize); + cins->mConst.mIntConst = exp->mToken == TK_INC ? vdl.mType->Stride() : -(vdl.mType->Stride()); else if (vdl.mType->IsNumericType()) cins->mConst.mIntConst = exp->mToken == TK_INC ? 1 : -1; else @@ -1733,6 +1734,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* case TK_MUL: if (vl.mType->mType != DT_TYPE_POINTER) mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Not a pointer type"); + if (vl.mType->mStride != 1) + vl = Dereference(proc, exp, block, vl, 0); return ExValue(vl.mType->mBase, vl.mTemp, vl.mReference + 1); case TK_BINARY_AND: { diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 83d0e21..ba6f949 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -244,6 +244,10 @@ NativeCodeInstruction::NativeCodeInstruction(AsmInsType type, AsmInsMode mode, i assert((mFlags & (NCIF_LOWER | NCIF_UPPER)) != (NCIF_LOWER | NCIF_UPPER)); assert(HasAsmInstructionMode(mType, ASMIM_IMMEDIATE)); } + if (mode == ASMIM_IMMEDIATE) + { + assert(address >= 0 && address < 256); + } } NativeCodeInstruction::NativeCodeInstruction(AsmInsType type, const NativeCodeInstruction& addr) @@ -1326,6 +1330,8 @@ bool NativeCodeInstruction::MayBeSameAddress(const NativeCodeInstruction& ins, b { if (mLinkerObject != ins.mLinkerObject) return false; + else if (mAddress >= ins.mAddress + 256 || ins.mAddress >= mAddress + 256) + return false; else return mMode != ins.mMode || !sameXY || mAddress == ins.mAddress; } @@ -4441,6 +4447,8 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr if (ins->mSrc[0].mType == IT_FLOAT) { + int stride = ins->mSrc[1].mStride; + if (ins->mSrc[1].mTemp < 0) { if (ins->mSrc[0].mTemp < 0) @@ -4453,22 +4461,22 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, ins->mSrc[1].mLinkerObject, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1 * stride, ins->mSrc[1].mLinkerObject, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2, ins->mSrc[1].mLinkerObject, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2 * stride, ins->mSrc[1].mLinkerObject, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3, ins->mSrc[1].mLinkerObject, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3 * stride, ins->mSrc[1].mLinkerObject, flags)); } else if (ins->mSrc[1].mMemory == IM_ABSOLUTE) { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, nullptr, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1 * stride, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2, nullptr, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2 * stride, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3, nullptr, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3 * stride, nullptr, flags)); } else if (ins->mSrc[1].mMemory == IM_FPARAM || ins->mSrc[1].mMemory == IM_FFRAME) { @@ -4539,22 +4547,22 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, ins->mSrc[1].mLinkerObject, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1 * stride, ins->mSrc[1].mLinkerObject, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2, ins->mSrc[1].mLinkerObject, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2 * stride, ins->mSrc[1].mLinkerObject, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3, ins->mSrc[1].mLinkerObject, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3 * stride, ins->mSrc[1].mLinkerObject, flags)); } else if (ins->mSrc[1].mMemory == IM_ABSOLUTE) { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, nullptr, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1 * stride, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2, nullptr, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 2 * stride, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3, nullptr, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 3 * stride, nullptr, flags)); } else if (ins->mSrc[1].mMemory == IM_FPARAM || ins->mSrc[1].mMemory == IM_FFRAME) { @@ -4621,21 +4629,32 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; int index = ins->mSrc[1].mIntConst; + int stride = ins->mSrc[1].mStride; - CheckFrameIndex(reg, index, 4); + if (stride * 4 <= 256) + { + CheckFrameIndex(reg, index, stride * 4); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 3)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + for (int i = 0; i < 4; i++) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> (8 * i)) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + } + } + else + { + for (int i = 0; i < 4; i++) + { + CheckFrameIndex(reg, index, 1); + + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> (8 * i)) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + + index += stride; + } + } } } else @@ -4644,27 +4663,40 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr { int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; int index = ins->mSrc[1].mIntConst; + int stride = ins->mSrc[1].mStride; - CheckFrameIndex(reg, index, 4); + if (stride * 4 <= 256) + { + CheckFrameIndex(reg, index, stride * 4); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 3)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 3)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + for (int i = 0; i < 4; i++) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + i)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + } + } + else + { + for (int i = 0; i < 4; i++) + { + CheckFrameIndex(reg, index, 1); + + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + i)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + + index += stride; + } + } } } } } else if (ins->mSrc[0].mType == IT_POINTER) { + int stride = ins->mSrc[1].mStride; + if (ins->mSrc[1].mTemp < 0) { if (ins->mSrc[0].mTemp < 0) @@ -4674,14 +4706,14 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, ins->mSrc[1].mLinkerObject, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + stride, ins->mSrc[1].mLinkerObject, flags)); } else if (ins->mSrc[1].mMemory == IM_ABSOLUTE) { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, nullptr, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + stride, nullptr, flags)); } else if (ins->mSrc[1].mMemory == IM_FPARAM || ins->mSrc[1].mMemory == IM_FFRAME) { @@ -4727,14 +4759,14 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, ins->mSrc[1].mLinkerObject, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, ins->mSrc[1].mLinkerObject, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + stride, ins->mSrc[1].mLinkerObject, flags)); } else if (ins->mSrc[1].mMemory == IM_ABSOLUTE) { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + 1, nullptr, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst + stride, nullptr, flags)); } else if (ins->mSrc[1].mMemory == IM_FPARAM || ins->mSrc[1].mMemory == IM_FFRAME) { @@ -4782,15 +4814,32 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr { int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; int index = ins->mSrc[1].mIntConst; + int stride = ins->mSrc[1].mStride; - CheckFrameIndex(reg, index, 2); + if (2 * stride <= 256) + { + CheckFrameIndex(reg, index, 2 * stride); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + for (int i = 0; i < 2; i++) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> (8 * i)) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + } + } + else + { + for (int i = 0; i < 2; i++) + { + CheckFrameIndex(reg, index, 1); + + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> (8 * i)) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + + index += stride; + } + } } } else @@ -4799,15 +4848,32 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr { int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; int index = ins->mSrc[1].mIntConst; + int stride = ins->mSrc[1].mStride; - CheckFrameIndex(reg, index, 2); + if (2 * stride <= 256) + { + CheckFrameIndex(reg, index, 2 * stride); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + for (int i = 0; i < 2; i++) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + i)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + } + } + else + { + for (int i = 0; i < 2; i++) + { + CheckFrameIndex(reg, index, 1); + + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + i)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + + index += stride; + } + } } } } @@ -5183,33 +5249,32 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr { int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; int index = ins->mSrc[1].mIntConst; - - CheckFrameIndex(reg, index, InterTypeSize[ins->mSrc[0].mType]); - - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); - - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); - int stride = ins->mSrc[1].mStride; + int size = InterTypeSize[ins->mSrc[0].mType]; - if (InterTypeSize[ins->mSrc[0].mType] == 2) + if (stride * size <= 256) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1 * stride)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + CheckFrameIndex(reg, index, stride * size); + + for (int i = 0; i < size; i++) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> (8 * i)) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + } } - else if (InterTypeSize[ins->mSrc[0].mType] == 4) + else { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1 * stride)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 2 * stride)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 16) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 3 * stride)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 24) & 0xff)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + for (int i = 0; i < size; i++) + { + CheckFrameIndex(reg, index, 1); + + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> (8 * i)) & 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + + index += stride; + } } } } @@ -5219,33 +5284,32 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr { int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; int index = ins->mSrc[1].mIntConst; - - CheckFrameIndex(reg, index, InterTypeSize[ins->mSrc[0].mType]); - - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); - - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp])); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); - int stride = ins->mSrc[1].mStride; + int size = InterTypeSize[ins->mSrc[0].mType]; - if (InterTypeSize[ins->mSrc[0].mType] == 2) + if (stride * size <= 256) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1 * stride)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + CheckFrameIndex(reg, index, stride * size); + + for (int i = 0; i < size; i++) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + i)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + } } - else if (InterTypeSize[ins->mSrc[0].mType] == 4) + else { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1 * stride)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 2 * stride)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 3 * stride)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 3)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + for (int i = 0; i < size; i++) + { + CheckFrameIndex(reg, index, 1); + + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + i)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); + + index += stride; + } } } } @@ -5377,33 +5441,35 @@ void NativeCodeBasicBlock::LoadStoreIndirectValue(InterCodeProcedure* proc, cons break; } - if (rmode == ASMIM_INDIRECT_Y) - CheckFrameIndex(rareg, rindex, size, BC_REG_ADDR); - - if (wmode == ASMIM_INDIRECT_Y) - CheckFrameIndex(wareg, windex, size, BC_REG_ACCU); - for (int i = 0; i < size; i++) { + if (rmode == ASMIM_INDIRECT_Y) + CheckFrameIndex(rareg, rindex, 1, BC_REG_ADDR); + if (wmode == ASMIM_INDIRECT_Y) + CheckFrameIndex(wareg, windex, 1, BC_REG_ACCU); + if (rmode == ASMIM_INDIRECT_Y) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rindex + i * rstride)); + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rindex)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, rareg, nullptr, rflags)); } else if (rmode == ASMIM_ZERO_PAGE) mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, rareg + i)); else - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, rindex + i * rstride, rlobject, rflags)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, rindex, rlobject, rflags)); if (wmode == ASMIM_INDIRECT_Y) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, windex + i * wstride)); + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, windex)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, wareg, nullptr, wflags)); } else if (wmode == ASMIM_ZERO_PAGE) mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, wareg + i)); else - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, windex + i * wstride, wlobject, wflags)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, windex, wlobject, wflags)); + + rindex += rstride; + windex += wstride; } } @@ -5736,6 +5802,7 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co int rindex = rins->mSrc[0].mIntConst; int rareg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS; + int rstride = rins->mSrc[0].mStride; switch (rins->mSrc[0].mMemory) { @@ -5759,6 +5826,7 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co int windex = wins->mSrc[1].mIntConst; int wareg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS; + int wstride = wins->mSrc[1].mStride; switch (wins->mSrc[1].mMemory) { @@ -5780,6 +5848,9 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co return false; } + if (rstride * size >= 256 || wstride * size >= 256) + return false; + uint32 rflags = NCIF_LOWER | NCIF_UPPER; if (rins->mVolatile) rflags |= NCIF_VOLATILE; @@ -5825,7 +5896,7 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co if (ram == ASMIM_INDIRECT_Y) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rindex + i)); + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rindex + i * rstride)); mIns.Push(NativeCodeInstruction(at, ram, rareg)); } else @@ -5835,7 +5906,7 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co { if (ram == ASMIM_INDIRECT_Y) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rindex + i)); + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, rindex + i * rstride)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ram, rareg)); } else @@ -5856,7 +5927,7 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co if (wam == ASMIM_INDIRECT_Y) { if (ram != ASMIM_INDIRECT_Y || rindex != windex) - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, windex + i)); + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, windex + i * wstride)); mIns.Push(NativeCodeInstruction(ASMIT_STA, wam, wareg)); } else @@ -5874,28 +5945,30 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI if (ins->mDst.mType == IT_FLOAT) { + int stride = ins->mSrc[0].mStride; + if (ins->mSrc[0].mTemp < 0) { if (ins->mSrc[0].mMemory == IM_GLOBAL) { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst, ins->mSrc[0].mLinkerObject, flags)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 1, ins->mSrc[0].mLinkerObject, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 1 * stride, ins->mSrc[0].mLinkerObject, flags)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 2, ins->mSrc[0].mLinkerObject, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 2 * stride, ins->mSrc[0].mLinkerObject, flags)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 3, ins->mSrc[0].mLinkerObject, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 3 * stride, ins->mSrc[0].mLinkerObject, flags)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3)); } else if (ins->mSrc[0].mMemory == IM_ABSOLUTE) { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 1, nullptr, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 1 * stride, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 2, nullptr, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 2 * stride, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 3, nullptr, flags)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst + 3 * stride, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3)); } else if (ins->mSrc[0].mMemory == IM_FPARAM) @@ -5940,22 +6013,32 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI { int areg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; int index = ins->mSrc[0].mIntConst; + int stride = ins->mSrc[0].mStride; - CheckFrameIndex(areg, index, 4); + if (stride * 4 <= 256) + { + CheckFrameIndex(areg, index, stride * 4); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + for (int i = 0; i < 4; i++) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + i)); + } + } + else + { + for (int i = 0; i < 4; i++) + { + CheckFrameIndex(areg, index, 1); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 3)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + i)); + + index += stride; + } + } } } } @@ -6274,83 +6357,72 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI { if (ins->mSrc[0].mMemory == IM_INDIRECT) { - int areg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; - int index = ins->mSrc[0].mIntConst; + int areg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; + int index = ins->mSrc[0].mIntConst; + int stride = ins->mSrc[0].mStride; + int size = InterTypeSize[ins->mDst.mType]; + bool accu = false; - CheckFrameIndex(areg, index, InterTypeSize[ins->mDst.mType]); - - if (InterTypeSize[ins->mDst.mType] == 1) + if (size * stride <= 256) { - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags)); - if (ainsl) - { - if (ainsl->mType == ASMIT_ADC) - mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); - else if (ainsl->mType == ASMIT_SBC) - mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED)); - mIns.Push(*ainsl); - } - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); - if (InterTypeSize[ins->mDst.mType] > 1) - { - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); - if (ainsh) mIns.Push(*ainsh); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); - } - } - else if (InterTypeSize[ins->mDst.mType] == 2) - { - int stride = ins->mSrc[0].mStride; + CheckFrameIndex(areg, index, size * stride); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags)); - if (ainsl) - { - if (ainsl->mType == ASMIT_ADC) - mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); - else if (ainsl->mType == ASMIT_SBC) - mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED)); - mIns.Push(*ainsl); - } + accu = reg == areg; - if (InterTypeSize[ins->mDst.mType] > 1) + for (int i = 0; i < size; i++) { - if (reg == areg) - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK_Y)); - else - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); - - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1 * stride)); + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags)); - if (ainsh) mIns.Push(*ainsh); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); - if (reg == areg) + + if (i == 0) { - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_WORK_Y)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); + if (ainsl) + { + if (ainsl->mType == ASMIT_ADC) + mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); + else if (ainsl->mType == ASMIT_SBC) + mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED)); + mIns.Push(*ainsl); + } } + else if (ainsh) + mIns.Push(*ainsh); + + if (accu) + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + i)); + else + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + i)); } - else - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); } - else if (InterTypeSize[ins->mDst.mType] == 4) + else { - int stride = ins->mSrc[0].mStride; + assert(ainsl == nullptr && ainsh == nullptr); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); + for (int i = 0; i < size; i++) + { + CheckFrameIndex(areg, index, i * stride); + if (reg == areg) + accu = true; - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1 * stride)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 2 * stride)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 3 * stride)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags)); - mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags)); + + if (accu) + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + i)); + else + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + i)); + + index += stride; + } + } + + if (accu) + { + for (int i = 0; i < size; i++) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + i)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + i)); + } } } } @@ -29218,7 +29290,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED; proc->ResetPatched(); - if (PatchGlobalAddressSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 2].mAddress, i + 6, -1, mIns[i + 3].mLinkerObject, mIns[i + 3].mAddress)) + if (PatchGlobalAddressSumYPointer(this, mIns[i + 2].mAddress, mIns[i + 2].mAddress, i + 6, -1, mIns[i + 3].mLinkerObject, mIns[i + 3].mAddress + mIns[i + 4].mAddress * 256)) progress = true; } } @@ -29266,6 +29338,21 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass } } +#endif +#if 1 + else if ( + mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 1].mFlags & NCIF_UPPER) && + mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && + !(mIns[i + 1].mLive & LIVE_CPU_REG_A)) + { + proc->ResetPatched(); + if (CheckGlobalAddressSumYPointer(this, mIns[i + 1].mAddress - 1, mIns[i + 1].mAddress - 1, i + 2, -1)) + { + proc->ResetPatched(); + if (PatchGlobalAddressSumYPointer(this, mIns[i + 1].mAddress - 1, mIns[i + 1].mAddress - 1, i + 2, -1, mIns[i + 0].mLinkerObject, mIns[i + 0].mAddress)) + progress = true; + } + } #endif } @@ -29336,7 +29423,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 2].mType == ASMIT_ADC && mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 4].mFlags & NCIF_UPPER) && mIns[i + 4].mLinkerObject == mIns[i + 1].mLinkerObject && mIns[i + 4].mAddress == mIns[i + 1].mAddress && - mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 && + mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 && !(mIns[i + 6].mLive & LIVE_CPU_REG_A)) { @@ -29351,7 +29438,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 6].mType = ASMIT_NOP; mIns[i + 6].mMode = ASMIM_IMPLIED; proc->ResetPatched(); - if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, i + 7, -1, mIns[i + 1].mLinkerObject, mIns[i + 1].mAddress)) + if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, i + 7, -1, mIns[i + 1].mLinkerObject, mIns[i + 1].mAddress + mIns[i + 5].mAddress * 256)) progress = true; } else if (mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress != mIns[i + 3].mAddress) @@ -29360,7 +29447,44 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass if (CheckGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, i + 7, -1)) { proc->ResetPatched(); - if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, i + 7, -1, mIns[i + 1].mLinkerObject, mIns[i + 1].mAddress)) + if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, i + 7, -1, mIns[i + 1].mLinkerObject, mIns[i + 1].mAddress + mIns[i + 5].mAddress * 256)) + progress = true; + } + } + } + +#endif +#if 1 + if (pass == 0 && + mIns[i + 0].mType == ASMIT_CLC && + mIns[i + 1].mType == ASMIT_LDA && + mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 2].mFlags & NCIF_LOWER) && + mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && + mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_IMMEDIATE && + mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE_ADDRESS && (mIns[i + 5].mFlags & NCIF_UPPER) && mIns[i + 5].mLinkerObject == mIns[i + 2].mLinkerObject && mIns[i + 5].mAddress == mIns[i + 2].mAddress && + mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 && + !(mIns[i + 6].mLive & LIVE_CPU_REG_A)) + { + proc->ResetPatched(); + if (CheckGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, i + 7, -1)) + { + mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + mIns[i + 4].mType = ASMIT_NOP; mIns[i + 4].mMode = ASMIM_IMPLIED; + mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED; + mIns[i + 6].mType = ASMIT_NOP; mIns[i + 6].mMode = ASMIM_IMPLIED; + + proc->ResetPatched(); + if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, i + 7, -1, mIns[i + 2].mLinkerObject, mIns[i + 2].mAddress + mIns[i + 4].mAddress * 256)) + progress = true; + } + else if (mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mAddress != mIns[i + 3].mAddress) + { + proc->ResetPatched(); + if (CheckGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, i + 7, -1)) + { + proc->ResetPatched(); + if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 1].mAddress, i + 7, -1, mIns[i + 2].mLinkerObject, mIns[i + 2].mAddress + mIns[i + 4].mAddress * 256)) progress = true; } } @@ -29374,7 +29498,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 2].mType == ASMIT_ADC && mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 4].mType == ASMIT_LDA && mIns[i + 4].mMode == ASMIM_IMMEDIATE && - mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 5].mAddress == 0 && + mIns[i + 5].mType == ASMIT_ADC && mIns[i + 5].mMode == ASMIM_IMMEDIATE && mIns[i + 6].mType == ASMIT_STA && mIns[i + 6].mMode == ASMIM_ZERO_PAGE && mIns[i + 6].mAddress == mIns[i + 3].mAddress + 1 && !(mIns[i + 6].mLive & LIVE_CPU_REG_A)) { @@ -29389,7 +29513,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass mIns[i + 6].mType = ASMIT_NOP; mIns[i + 6].mMode = ASMIM_IMPLIED; proc->ResetPatched(); - if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, i + 7, -1, nullptr, mIns[i + 1].mAddress + 256 * mIns[i + 4].mAddress)) + if (PatchGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 3].mAddress, i + 7, -1, nullptr, mIns[i + 1].mAddress + 256 * mIns[i + 4].mAddress + mIns[i + 5].mAddress * 25)) progress = true; } } @@ -31118,8 +31242,7 @@ void NativeCodeProcedure::RebuildEntry(void) void NativeCodeProcedure::Optimize(void) { - CheckFunc = !strcmp(mInterProc->mIdent->mString, "menu_draw_color_line"); - + CheckFunc = !strcmp(mInterProc->mIdent->mString, "test_ab256"); #if 1 int step = 0; int cnt = 0; @@ -31199,31 +31322,34 @@ void NativeCodeProcedure::Optimize(void) ResetVisited(); changed = mEntryBlock->RemoveUnusedResultInstructions(); - - ResetVisited(); - NativeRegisterDataSet data; - if (mEntryBlock->ValueForwarding(data, step > 0, step == 7)) + if (step == 0) { - changed = true; + ResetVisited(); + if (mEntryBlock->Propagate16BitSum()) + changed = true; } - else - { -#if 1 - ResetPatched(); - mEntryBlock->CheckVisited(); - if (step > 1) + if (!changed) + { + ResetVisited(); + NativeRegisterDataSet data; + if (mEntryBlock->ValueForwarding(data, step > 0, step == 7)) { - ResetVisited(); - if (mEntryBlock->GlobalValueForwarding()) - changed = true; + changed = true; } -#endif - if (!changed) + else { - ResetVisited(); - if (mEntryBlock->Propagate16BitSum()) - changed = true; +#if 1 + ResetPatched(); + mEntryBlock->CheckVisited(); + + if (step > 1) + { + ResetVisited(); + if (mEntryBlock->GlobalValueForwarding()) + changed = true; + } +#endif } } @@ -31810,6 +31936,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode } else if (i + 1 < iblock->mInstructions.Size() && InterTypeSize[ins->mDst.mType] >= 2 && + InterTypeSize[ins->mDst.mType] * ins->mSrc[0].mStride <= 256 && 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) { @@ -31818,6 +31945,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode } else if (i + 1 < iblock->mInstructions.Size() && InterTypeSize[ins->mDst.mType] >= 2 && + InterTypeSize[ins->mDst.mType] * ins->mSrc[0].mStride < 256 && iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && iblock->mInstructions[i + 1]->mSrc[1].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[1].mFinal) { @@ -31826,7 +31954,9 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode } else if (i + 2 < iblock->mInstructions.Size() && InterTypeSize[ins->mDst.mType] >= 2 && + InterTypeSize[ins->mDst.mType] * ins->mSrc[0].mStride <= 256 && iblock->mInstructions[i + 1]->mCode == IC_LOAD && InterTypeSize[iblock->mInstructions[i + 1]->mDst.mType] >= 2 && + InterTypeSize[iblock->mInstructions[i + 1]->mDst.mType] * iblock->mInstructions[i + 1]->mSrc[0].mStride <= 256 && iblock->mInstructions[i + 1]->mDst.mTemp != ins->mDst.mTemp && iblock->mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR && iblock->mInstructions[i + 2]->mSrc[0].mTemp == iblock->mInstructions[i + 1]->mDst.mTemp && iblock->mInstructions[i + 2]->mSrc[0].mFinal && @@ -31837,7 +31967,9 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode } else if (i + 2 < iblock->mInstructions.Size() && InterTypeSize[ins->mDst.mType] >= 2 && + InterTypeSize[ins->mDst.mType] * ins->mSrc[0].mStride <= 256 && iblock->mInstructions[i + 1]->mCode == IC_LOAD && InterTypeSize[iblock->mInstructions[i + 1]->mDst.mType] >= 2 && + InterTypeSize[iblock->mInstructions[i + 1]->mDst.mType] * iblock->mInstructions[i + 1]->mSrc[0].mStride <= 256 && iblock->mInstructions[i + 1]->mDst.mTemp != ins->mDst.mTemp && iblock->mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR && iblock->mInstructions[i + 2]->mSrc[1].mTemp == iblock->mInstructions[i + 1]->mDst.mTemp && iblock->mInstructions[i + 2]->mSrc[1].mFinal && @@ -31934,7 +32066,8 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode iblock->mInstructions[i + 1]->mCode == IC_LOAD && iblock->mInstructions[i + 1]->mSrc[0].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[0].mFinal && ins->mSrc[1].mTemp >= 0 && ins->mSrc[0].IsUByte() && ins->mSrc[0].mTemp >= 0 && iblock->mInstructions[i + 1]->mSrc[0].mIntConst == 0 && - (InterTypeSize[iblock->mInstructions[i + 1]->mDst.mType] == 1 || ins->mSrc[1].mTemp != iblock->mInstructions[i + 1]->mDst.mTemp)) + (InterTypeSize[iblock->mInstructions[i + 1]->mDst.mType] == 1 || ins->mSrc[1].mTemp != iblock->mInstructions[i + 1]->mDst.mTemp) && + (InterTypeSize[iblock->mInstructions[i + 1]->mDst.mType] == 1 || iblock->mInstructions[i + 1]->mSrc[0].mStride == 1)) { block->LoadByteIndexedValue(iproc, ins, iblock->mInstructions[i + 1]); i++; @@ -31942,7 +32075,8 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode else if (i + 1 < iblock->mInstructions.Size() && iblock->mInstructions[i + 1]->mCode == IC_STORE && iblock->mInstructions[i + 1]->mSrc[1].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[1].mFinal && ins->mSrc[1].mTemp >= 0 && ins->mSrc[0].IsUByte() && ins->mSrc[0].mTemp >= 0 && - iblock->mInstructions[i + 1]->mSrc[1].mIntConst == 0 && iblock->mInstructions[i + 1]->mSrc[0].mTemp >= 0) + iblock->mInstructions[i + 1]->mSrc[1].mIntConst == 0 && iblock->mInstructions[i + 1]->mSrc[0].mTemp >= 0 && + (InterTypeSize[iblock->mInstructions[i + 1]->mSrc[0].mType] == 1 || iblock->mInstructions[i + 1]->mSrc[1].mStride == 1)) { block->StoreByteIndexedValue(iproc, ins, iblock->mInstructions[i + 1]); i++; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 811a928..b3d2a60 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -1766,6 +1766,7 @@ Expression* Parser::ParsePrefixExpression(void) Declaration* pdec = new Declaration(nexp->mLocation, DT_TYPE_POINTER); pdec->mBase = nexp->mLeft->mDecType; pdec->mSize = 2; + pdec->mFlags |= DTF_DEFINED; nexp->mDecType = pdec; } else @@ -1822,6 +1823,7 @@ Expression* Parser::ParseAddExpression(void) dec->mBase = nexp->mLeft->mDecType->mBase; dec->mStride = nexp->mLeft->mDecType->mStride; dec->mStripe = nexp->mLeft->mDecType->mStripe; + dec->mFlags |= DTF_DEFINED; nexp->mDecType = dec; } else if (nexp->mRight->mDecType->mType == DT_TYPE_ARRAY && nexp->mLeft->mDecType->IsIntegerType()) @@ -1831,6 +1833,7 @@ Expression* Parser::ParseAddExpression(void) dec->mBase = nexp->mRight->mDecType->mBase; dec->mStride = nexp->mRight->mDecType->mStride; dec->mStripe = nexp->mRight->mDecType->mStripe; + dec->mFlags |= DTF_DEFINED; nexp->mDecType = dec; } else if (nexp->mLeft->mDecType->mType == DT_TYPE_FLOAT || nexp->mRight->mDecType->mType == DT_TYPE_FLOAT)