Add autotest for striped arrays

This commit is contained in:
drmortalwombat 2022-12-03 13:28:03 +01:00
parent 9c6b745993
commit 8b631d564e
7 changed files with 736 additions and 239 deletions

View File

@ -153,6 +153,9 @@ rem @echo off
@call :test cplxstructtest.c @call :test cplxstructtest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :testn stripedarraytest.c
@if %errorlevel% neq 0 goto :error
@exit /b 0 @exit /b 0
:error :error
@ -209,3 +212,21 @@ exit /b %errorlevel%
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@exit /b 0 @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

299
autotest/stripedarraytest.c Normal file
View File

@ -0,0 +1,299 @@
#include <assert.h>
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;
}

View File

@ -3083,10 +3083,11 @@ bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray&
} }
} }
return changed; return changed;
} }
bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars, NumberSet& requiredVars) bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariableArray& staticVars, NumberSet& requiredVars, GrowingInstructionPtrArray& storeIns)
{ {
bool changed = false; bool changed = false;
@ -3104,6 +3105,14 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariable
{ {
requiredVars += mSrc[0].mVarIndex; 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) else if (mCode == IC_STORE)
{ {
@ -3121,16 +3130,43 @@ bool InterInstruction::RemoveUnusedStaticStoreInstructions(const GrowingVariable
changed = true; 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) else if (mCode == IC_COPY || mCode == IC_STRCPY)
{ {
requiredVars.Fill(); 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) else if (mCode == IC_CALL || mCode == IC_CALL_NATIVE || mCode == IC_RETURN || mCode == IC_RETURN_STRUCT || mCode == IC_RETURN_VALUE)
{ {
requiredVars.Fill(); requiredVars.Fill();
storeIns.SetSize(0);
} }
if (mCode == IC_STORE)
storeIns.Push(this);
return changed; return changed;
} }
@ -6960,12 +6996,13 @@ bool InterCodeBasicBlock::RemoveUnusedStaticStoreInstructions(const GrowingVaria
mVisited = true; mVisited = true;
NumberSet requiredVars(mExitRequiredStatics); NumberSet requiredVars(mExitRequiredStatics);
GrowingInstructionPtrArray storeIns(nullptr);
int i; int i;
for (i = mInstructions.Size() - 1; i >= 0; i--) for (i = mInstructions.Size() - 1; i >= 0; i--)
{ {
if (mInstructions[i]->RemoveUnusedStaticStoreInstructions(staticVars, requiredVars)) if (mInstructions[i]->RemoveUnusedStaticStoreInstructions(staticVars, requiredVars, storeIns))
changed = true; changed = true;
} }

View File

@ -307,7 +307,7 @@ public:
bool RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps); bool RemoveUnusedResultInstructions(InterInstruction* pre, NumberSet& requiredTemps);
bool RemoveUnusedStoreInstructions(const GrowingVariableArray& localVars, NumberSet& requiredVars, const GrowingVariableArray& params, NumberSet& requiredParams, InterMemory paramMemory); 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 PerformValueForwarding(GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
void BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSet& callerSaveTemps); void BuildCallerSaveTempSet(NumberSet& requiredTemps, NumberSet& callerSaveTemps);

View File

@ -1059,11 +1059,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (exp->mToken == TK_ASSIGN_ADD) 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) else if (exp->mToken == TK_ASSIGN_SUB)
{ {
cins->mConst.mIntConst = -vl.mType->mBase->mSize; cins->mConst.mIntConst = -vl.mType->Stride();
} }
else else
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid pointer assignment"); 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); Declaration* ptype = new Declaration(exp->mLocation, DT_TYPE_POINTER);
ptype->mBase = vl.mType->mBase; ptype->mBase = vl.mType->mBase;
ptype->mSize = 2; ptype->mSize = 2;
ptype->mStride = vl.mType->mStride;
vl.mType = ptype; vl.mType = ptype;
} }
@ -1314,11 +1315,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (exp->mToken == TK_ADD) if (exp->mToken == TK_ADD)
{ {
cins->mConst.mIntConst = vl.mType->mBase->mSize; cins->mConst.mIntConst = vl.mType->Stride();
} }
else if (exp->mToken == TK_SUB) else if (exp->mToken == TK_SUB)
{ {
cins->mConst.mIntConst = -vl.mType->mBase->mSize; cins->mConst.mIntConst = -vl.mType->Stride();
} }
else else
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid pointer operation"); mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid pointer operation");
@ -1368,7 +1369,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
block->Append(crins); block->Append(crins);
InterInstruction * cins = new InterInstruction(exp->mLocation, IC_CONSTANT); 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.mType = IT_INT16;
cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType); cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType);
block->Append(cins); block->Append(cins);
@ -1420,7 +1421,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (exp->mToken == TK_ADD) if (exp->mToken == TK_ADD)
{ {
cins->mConst.mIntConst = vr.mType->mBase->mSize; cins->mConst.mIntConst = vr.mType->Stride();
} }
else else
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Invalid pointer operation"); 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.mType = ftype ? IT_FLOAT : IT_INT16;
cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType); cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType);
if (vdl.mType->mType == DT_TYPE_POINTER) 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()) else if (vdl.mType->IsNumericType())
cins->mConst.mIntConst = exp->mToken == TK_INC ? 1 : -1; cins->mConst.mIntConst = exp->mToken == TK_INC ? 1 : -1;
else else
@ -1663,7 +1664,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
cins->mDst.mType = ftype ? IT_FLOAT : IT_INT16; cins->mDst.mType = ftype ? IT_FLOAT : IT_INT16;
cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType); cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType);
if (vdl.mType->mType == DT_TYPE_POINTER) 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()) else if (vdl.mType->IsNumericType())
cins->mConst.mIntConst = exp->mToken == TK_INC ? 1 : -1; cins->mConst.mIntConst = exp->mToken == TK_INC ? 1 : -1;
else else
@ -1733,6 +1734,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
case TK_MUL: case TK_MUL:
if (vl.mType->mType != DT_TYPE_POINTER) if (vl.mType->mType != DT_TYPE_POINTER)
mErrors->Error(exp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Not a pointer type"); 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); return ExValue(vl.mType->mBase, vl.mTemp, vl.mReference + 1);
case TK_BINARY_AND: case TK_BINARY_AND:
{ {

View File

@ -244,6 +244,10 @@ NativeCodeInstruction::NativeCodeInstruction(AsmInsType type, AsmInsMode mode, i
assert((mFlags & (NCIF_LOWER | NCIF_UPPER)) != (NCIF_LOWER | NCIF_UPPER)); assert((mFlags & (NCIF_LOWER | NCIF_UPPER)) != (NCIF_LOWER | NCIF_UPPER));
assert(HasAsmInstructionMode(mType, ASMIM_IMMEDIATE)); assert(HasAsmInstructionMode(mType, ASMIM_IMMEDIATE));
} }
if (mode == ASMIM_IMMEDIATE)
{
assert(address >= 0 && address < 256);
}
} }
NativeCodeInstruction::NativeCodeInstruction(AsmInsType type, const NativeCodeInstruction& addr) NativeCodeInstruction::NativeCodeInstruction(AsmInsType type, const NativeCodeInstruction& addr)
@ -1326,6 +1330,8 @@ bool NativeCodeInstruction::MayBeSameAddress(const NativeCodeInstruction& ins, b
{ {
if (mLinkerObject != ins.mLinkerObject) if (mLinkerObject != ins.mLinkerObject)
return false; return false;
else if (mAddress >= ins.mAddress + 256 || ins.mAddress >= mAddress + 256)
return false;
else else
return mMode != ins.mMode || !sameXY || mAddress == ins.mAddress; 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) if (ins->mSrc[0].mType == IT_FLOAT)
{ {
int stride = ins->mSrc[1].mStride;
if (ins->mSrc[1].mTemp < 0) if (ins->mSrc[1].mTemp < 0)
{ {
if (ins->mSrc[0].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_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_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_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_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_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) else if (ins->mSrc[1].mMemory == IM_ABSOLUTE)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff)); 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_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, nullptr, flags));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff)); 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_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_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) 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_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_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_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_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_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) else if (ins->mSrc[1].mMemory == IM_ABSOLUTE)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); 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_STA, ASMIM_ABSOLUTE, ins->mSrc[1].mIntConst, nullptr, flags));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); 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_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_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) 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 reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
int index = ins->mSrc[1].mIntConst; 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);
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_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> (8 * i)) & 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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
index += stride;
}
}
} }
} }
else else
@ -4644,27 +4663,40 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
{ {
int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
int index = ins->mSrc[1].mIntConst; 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);
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_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_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + i));
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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
index += stride;
}
}
} }
} }
} }
} }
else if (ins->mSrc[0].mType == IT_POINTER) else if (ins->mSrc[0].mType == IT_POINTER)
{ {
int stride = ins->mSrc[1].mStride;
if (ins->mSrc[1].mTemp < 0) if (ins->mSrc[1].mTemp < 0)
{ {
if (ins->mSrc[0].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_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_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_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) else if (ins->mSrc[1].mMemory == IM_ABSOLUTE)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); 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_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_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) 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_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_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_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) 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_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_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_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) 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 reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
int index = ins->mSrc[1].mIntConst; 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);
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_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> (8 * i)) & 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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
index += stride;
}
}
} }
} }
else else
@ -4799,15 +4848,32 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
{ {
int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; int reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
int index = ins->mSrc[1].mIntConst; 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);
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_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_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + i));
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_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 reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
int index = ins->mSrc[1].mIntConst; 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 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)); CheckFrameIndex(reg, index, stride * size);
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff));
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)); 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)); for (int i = 0; i < size; i++)
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, 1);
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_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> (8 * i)) & 0xff));
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)); 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 reg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp];
int index = ins->mSrc[1].mIntConst; 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 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)); CheckFrameIndex(reg, index, stride * size);
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
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)); 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)); for (int i = 0; i < size; i++)
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, 1);
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_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + i));
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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
index += stride;
}
} }
} }
} }
@ -5377,33 +5441,35 @@ void NativeCodeBasicBlock::LoadStoreIndirectValue(InterCodeProcedure* proc, cons
break; 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++) 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) 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)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, rareg, nullptr, rflags));
} }
else if (rmode == ASMIM_ZERO_PAGE) else if (rmode == ASMIM_ZERO_PAGE)
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, rareg + i)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, rareg + i));
else 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) 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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, wareg, nullptr, wflags));
} }
else if (wmode == ASMIM_ZERO_PAGE) else if (wmode == ASMIM_ZERO_PAGE)
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, wareg + i)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, wareg + i));
else 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 rindex = rins->mSrc[0].mIntConst;
int rareg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS; int rareg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
int rstride = rins->mSrc[0].mStride;
switch (rins->mSrc[0].mMemory) switch (rins->mSrc[0].mMemory)
{ {
@ -5759,6 +5826,7 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co
int windex = wins->mSrc[1].mIntConst; int windex = wins->mSrc[1].mIntConst;
int wareg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS; int wareg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
int wstride = wins->mSrc[1].mStride;
switch (wins->mSrc[1].mMemory) switch (wins->mSrc[1].mMemory)
{ {
@ -5780,6 +5848,9 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co
return false; return false;
} }
if (rstride * size >= 256 || wstride * size >= 256)
return false;
uint32 rflags = NCIF_LOWER | NCIF_UPPER; uint32 rflags = NCIF_LOWER | NCIF_UPPER;
if (rins->mVolatile) if (rins->mVolatile)
rflags |= NCIF_VOLATILE; rflags |= NCIF_VOLATILE;
@ -5825,7 +5896,7 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co
if (ram == ASMIM_INDIRECT_Y) 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)); mIns.Push(NativeCodeInstruction(at, ram, rareg));
} }
else else
@ -5835,7 +5906,7 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co
{ {
if (ram == ASMIM_INDIRECT_Y) 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)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ram, rareg));
} }
else else
@ -5856,7 +5927,7 @@ bool NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, co
if (wam == ASMIM_INDIRECT_Y) if (wam == ASMIM_INDIRECT_Y)
{ {
if (ram != ASMIM_INDIRECT_Y || rindex != windex) 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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, wam, wareg));
} }
else else
@ -5874,28 +5945,30 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
if (ins->mDst.mType == IT_FLOAT) if (ins->mDst.mType == IT_FLOAT)
{ {
int stride = ins->mSrc[0].mStride;
if (ins->mSrc[0].mTemp < 0) if (ins->mSrc[0].mTemp < 0)
{ {
if (ins->mSrc[0].mMemory == IM_GLOBAL) 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_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_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_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_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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3));
} }
else if (ins->mSrc[0].mMemory == IM_ABSOLUTE) 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_LDA, ASMIM_ABSOLUTE, ins->mSrc[0].mIntConst, nullptr, flags));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); 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_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_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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3));
} }
else if (ins->mSrc[0].mMemory == IM_FPARAM) 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 areg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
int index = ins->mSrc[0].mIntConst; 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);
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_LDY, ASMIM_IMMEDIATE, index)); 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));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg)); index += stride;
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));
} }
} }
} }
@ -6276,13 +6359,23 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
{ {
int areg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]; int areg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
int index = ins->mSrc[0].mIntConst; 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 (size * stride <= 256)
if (InterTypeSize[ins->mDst.mType] == 1)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); CheckFrameIndex(areg, index, size * stride);
accu = reg == areg;
for (int i = 0; i < size; i++)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + i * stride));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
if (i == 0)
{
if (ainsl) if (ainsl)
{ {
if (ainsl->mType == ASMIT_ADC) if (ainsl->mType == ASMIT_ADC)
@ -6291,66 +6384,45 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
mIns.Push(*ainsl); 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 (ainsh)
else if (InterTypeSize[ins->mDst.mType] == 2) mIns.Push(*ainsh);
{
int stride = ins->mSrc[0].mStride;
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); if (accu)
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + i));
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);
}
if (InterTypeSize[ins->mDst.mType] > 1)
{
if (reg == areg)
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK_Y));
else else
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + i));
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1 * 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)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_WORK_Y));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
} }
} }
else else
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
}
else if (InterTypeSize[ins->mDst.mType] == 4)
{ {
int stride = ins->mSrc[0].mStride; assert(ainsl == nullptr && ainsh == nullptr);
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)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 1 * stride)); if (accu)
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + i));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); else
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index + 2 * stride)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + i));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg, nullptr, flags));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2)); index += stride;
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));
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; mIns[i + 5].mType = ASMIT_NOP; mIns[i + 5].mMode = ASMIM_IMPLIED;
proc->ResetPatched(); 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; 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 #endif
} }
@ -29336,7 +29423,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mType == ASMIT_ADC &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && 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 + 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].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)) !(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; mIns[i + 6].mType = ASMIT_NOP; mIns[i + 6].mMode = ASMIM_IMPLIED;
proc->ResetPatched(); 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; progress = true;
} }
else if (mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress != mIns[i + 3].mAddress) 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)) if (CheckGlobalAddressSumYPointer(this, mIns[i + 3].mAddress, mIns[i + 2].mAddress, i + 7, -1))
{ {
proc->ResetPatched(); 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; progress = true;
} }
} }
@ -29374,7 +29498,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mIns[i + 2].mType == ASMIT_ADC && mIns[i + 2].mType == ASMIT_ADC &&
mIns[i + 3].mType == ASMIT_STA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && 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 + 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].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)) !(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; mIns[i + 6].mType = ASMIT_NOP; mIns[i + 6].mMode = ASMIM_IMPLIED;
proc->ResetPatched(); 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; progress = true;
} }
} }
@ -31118,8 +31242,7 @@ void NativeCodeProcedure::RebuildEntry(void)
void NativeCodeProcedure::Optimize(void) void NativeCodeProcedure::Optimize(void)
{ {
CheckFunc = !strcmp(mInterProc->mIdent->mString, "menu_draw_color_line"); CheckFunc = !strcmp(mInterProc->mIdent->mString, "test_ab256");
#if 1 #if 1
int step = 0; int step = 0;
int cnt = 0; int cnt = 0;
@ -31199,7 +31322,15 @@ void NativeCodeProcedure::Optimize(void)
ResetVisited(); ResetVisited();
changed = mEntryBlock->RemoveUnusedResultInstructions(); changed = mEntryBlock->RemoveUnusedResultInstructions();
if (step == 0)
{
ResetVisited();
if (mEntryBlock->Propagate16BitSum())
changed = true;
}
if (!changed)
{
ResetVisited(); ResetVisited();
NativeRegisterDataSet data; NativeRegisterDataSet data;
if (mEntryBlock->ValueForwarding(data, step > 0, step == 7)) if (mEntryBlock->ValueForwarding(data, step > 0, step == 7))
@ -31219,11 +31350,6 @@ void NativeCodeProcedure::Optimize(void)
changed = true; changed = true;
} }
#endif #endif
if (!changed)
{
ResetVisited();
if (mEntryBlock->Propagate16BitSum())
changed = true;
} }
} }
@ -31810,6 +31936,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
} }
else if (i + 1 < iblock->mInstructions.Size() && else if (i + 1 < iblock->mInstructions.Size() &&
InterTypeSize[ins->mDst.mType] >= 2 && 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]->mCode == IC_BINARY_OPERATOR &&
iblock->mInstructions[i + 1]->mSrc[0].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[0].mFinal) iblock->mInstructions[i + 1]->mSrc[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() && else if (i + 1 < iblock->mInstructions.Size() &&
InterTypeSize[ins->mDst.mType] >= 2 && 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]->mCode == IC_BINARY_OPERATOR &&
iblock->mInstructions[i + 1]->mSrc[1].mTemp == ins->mDst.mTemp && iblock->mInstructions[i + 1]->mSrc[1].mFinal) 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() && else if (i + 2 < iblock->mInstructions.Size() &&
InterTypeSize[ins->mDst.mType] >= 2 && 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 && 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 + 1]->mDst.mTemp != ins->mDst.mTemp &&
iblock->mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR && 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 && 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() && else if (i + 2 < iblock->mInstructions.Size() &&
InterTypeSize[ins->mDst.mType] >= 2 && 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 && 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 + 1]->mDst.mTemp != ins->mDst.mTemp &&
iblock->mInstructions[i + 2]->mCode == IC_BINARY_OPERATOR && 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 && 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 && 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 && ins->mSrc[1].mTemp >= 0 && ins->mSrc[0].IsUByte() && ins->mSrc[0].mTemp >= 0 &&
iblock->mInstructions[i + 1]->mSrc[0].mIntConst == 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]); block->LoadByteIndexedValue(iproc, ins, iblock->mInstructions[i + 1]);
i++; i++;
@ -31942,7 +32075,8 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
else if (i + 1 < iblock->mInstructions.Size() && 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 && 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 && 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]); block->StoreByteIndexedValue(iproc, ins, iblock->mInstructions[i + 1]);
i++; i++;

View File

@ -1766,6 +1766,7 @@ Expression* Parser::ParsePrefixExpression(void)
Declaration* pdec = new Declaration(nexp->mLocation, DT_TYPE_POINTER); Declaration* pdec = new Declaration(nexp->mLocation, DT_TYPE_POINTER);
pdec->mBase = nexp->mLeft->mDecType; pdec->mBase = nexp->mLeft->mDecType;
pdec->mSize = 2; pdec->mSize = 2;
pdec->mFlags |= DTF_DEFINED;
nexp->mDecType = pdec; nexp->mDecType = pdec;
} }
else else
@ -1822,6 +1823,7 @@ Expression* Parser::ParseAddExpression(void)
dec->mBase = nexp->mLeft->mDecType->mBase; dec->mBase = nexp->mLeft->mDecType->mBase;
dec->mStride = nexp->mLeft->mDecType->mStride; dec->mStride = nexp->mLeft->mDecType->mStride;
dec->mStripe = nexp->mLeft->mDecType->mStripe; dec->mStripe = nexp->mLeft->mDecType->mStripe;
dec->mFlags |= DTF_DEFINED;
nexp->mDecType = dec; nexp->mDecType = dec;
} }
else if (nexp->mRight->mDecType->mType == DT_TYPE_ARRAY && nexp->mLeft->mDecType->IsIntegerType()) 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->mBase = nexp->mRight->mDecType->mBase;
dec->mStride = nexp->mRight->mDecType->mStride; dec->mStride = nexp->mRight->mDecType->mStride;
dec->mStripe = nexp->mRight->mDecType->mStripe; dec->mStripe = nexp->mRight->mDecType->mStripe;
dec->mFlags |= DTF_DEFINED;
nexp->mDecType = dec; nexp->mDecType = dec;
} }
else if (nexp->mLeft->mDecType->mType == DT_TYPE_FLOAT || nexp->mRight->mDecType->mType == DT_TYPE_FLOAT) else if (nexp->mLeft->mDecType->mType == DT_TYPE_FLOAT || nexp->mRight->mDecType->mType == DT_TYPE_FLOAT)