Native code compiler is functional same level as byte code

Runs all the autotests now in byte code and native code
This commit is contained in:
drmortalwombat 2021-09-11 22:21:57 +02:00
parent 897de02adf
commit 82d499fdae
9 changed files with 383 additions and 71 deletions

View File

@ -3,45 +3,87 @@
..\release\oscar64 -i=../include -rt=../include/crt.c -e stdlibtest.c ..\release\oscar64 -i=../include -rt=../include/crt.c -e stdlibtest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n stdlibtest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e testint16.c ..\release\oscar64 -i=../include -rt=../include/crt.c -e testint16.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n testint16.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e recursiontest.c ..\release\oscar64 -i=../include -rt=../include/crt.c -e recursiontest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n recursiontest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e strcmptest.c ..\release\oscar64 -i=../include -rt=../include/crt.c -e strcmptest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n strcmptest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e arraytest.c ..\release\oscar64 -i=../include -rt=../include/crt.c -e arraytest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n arraytest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e arraytestfloat.c ..\release\oscar64 -i=../include -rt=../include/crt.c -e arraytestfloat.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n arraytestfloat.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e optiontest.c ..\release\oscar64 -i=../include -rt=../include/crt.c -e optiontest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n optiontest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e floatcmptest.c ..\release\oscar64 -i=../include -rt=../include/crt.c -e floatcmptest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n floatcmptest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e floatmultest.c ..\release\oscar64 -i=../include -rt=../include/crt.c -e floatmultest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n floatmultest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e staticconsttest.c ..\release\oscar64 -i=../include -rt=../include/crt.c -e staticconsttest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n staticconsttest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e arrayinittest.c ..\release\oscar64 -i=../include -rt=../include/crt.c -e arrayinittest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n arrayinittest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e array2stringinittest.c ..\release\oscar64 -i=../include -rt=../include/crt.c -e array2stringinittest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n array2stringinittest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e testint16cmp.c ..\release\oscar64 -i=../include -rt=../include/crt.c -e testint16cmp.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n testint16cmp.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e floatstringtest.c ..\release\oscar64 -i=../include -rt=../include/crt.c -e floatstringtest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e -n floatstringtest.c
if %errorlevel% neq 0 goto :error
exit /b 0 exit /b 0
:error :error
echo Failed with error #%errorlevel%. echo Failed with error #%errorlevel%.

View File

@ -4,6 +4,9 @@
int main(void) int main(void)
{ {
printf("%f\n", 0.0);
float x = 1.0, y = 1.0; float x = 1.0, y = 1.0;
char xb[20], yb[20]; char xb[20], yb[20];
@ -12,7 +15,7 @@ int main(void)
ftoa(x, xb); float xr = atof(xb); ftoa(x, xb); float xr = atof(xb);
ftoa(y, yb); float yr = atof(yb); ftoa(y, yb); float yr = atof(yb);
// printf("%20g (%s) %20g : %20g (%s) %20g : %10f %10f \n", x, xb, xr, y, yb, y, fabs(x - xr) / x, fabs(y - yr) / y); printf("%20g (%s) %20g : %20g (%s) %20g : %10f %10f \n", x, xb, xr, y, yb, y, fabs(x - xr) / x, fabs(y - yr) / y);
if (fabs(x - xr) / x > 0.00001 || fabs(y - yr) / y > 0.00001) if (fabs(x - xr) / x > 0.00001 || fabs(y - yr) / y > 0.00001)
return -1; return -1;
@ -23,3 +26,7 @@ int main(void)
return 0; return 0;
} }

View File

@ -9,7 +9,7 @@
#include <stdio.h> #include <stdio.h>
Compiler::Compiler(void) Compiler::Compiler(void)
: mByteCodeFunctions(nullptr) : mByteCodeFunctions(nullptr), mNativeCode(false)
{ {
mErrors = new Errors(); mErrors = new Errors();
mCompilationUnits = new CompilationUnits(mErrors); mCompilationUnits = new CompilationUnits(mErrors);
@ -24,6 +24,11 @@ Compiler::~Compiler(void)
} }
void Compiler::ForceNativeCode(bool native)
{
mNativeCode = native;
}
bool Compiler::ParseSource(void) bool Compiler::ParseSource(void)
{ {
CompilationUnit* cunit; CompilationUnit* cunit;
@ -90,6 +95,9 @@ bool Compiler::GenerateCode(void)
proc->ReduceTemporaries(); proc->ReduceTemporaries();
if (mNativeCode)
proc->mNativeProcedure = true;
#if _DEBUG #if _DEBUG
proc->Disassemble("final"); proc->Disassemble("final");
#endif #endif

View File

@ -21,8 +21,12 @@ public:
GrowingArray<ByteCodeProcedure*> mByteCodeFunctions; GrowingArray<ByteCodeProcedure*> mByteCodeFunctions;
bool mNativeCode;
bool ParseSource(void); bool ParseSource(void);
bool GenerateCode(void); bool GenerateCode(void);
bool WriteOutputFile(const char* targetPath); bool WriteOutputFile(const char* targetPath);
int ExecuteCode(void); int ExecuteCode(void);
void ForceNativeCode(bool native);
}; };

View File

@ -8,6 +8,14 @@ static const int CPU_REG_Z = 260;
static const int NUM_REGS = 261; static const int NUM_REGS = 261;
static const uint32 LIVE_CPU_REG_A = 0x00000001;
static const uint32 LIVE_CPU_REG_X = 0x00000002;
static const uint32 LIVE_CPU_REG_Y = 0x00000004;
static const uint32 LIVE_CPU_REG_C = 0x00000008;
static const uint32 LIVE_CPU_REG_Z = 0x00000010;
static const uint32 LIVE_MEM = 0x00000020;
NativeRegisterData::NativeRegisterData(void) NativeRegisterData::NativeRegisterData(void)
: mImmediate(false), mZeroPage(false) : mImmediate(false), mZeroPage(false)
{ {
@ -52,6 +60,20 @@ bool NativeCodeInstruction::IsUsedResultInstructions(NumberSet& requiredTemps)
{ {
bool used = false; bool used = false;
mLive = 0;
if (requiredTemps[CPU_REG_A])
mLive |= LIVE_CPU_REG_A;
if (requiredTemps[CPU_REG_X])
mLive |= LIVE_CPU_REG_X;
if (requiredTemps[CPU_REG_Y])
mLive |= LIVE_CPU_REG_Y;
if (requiredTemps[CPU_REG_Z])
mLive |= LIVE_CPU_REG_Z;
if (requiredTemps[CPU_REG_C])
mLive |= LIVE_CPU_REG_C;
if (mMode == ASMIM_ZERO_PAGE)
mLive |= LIVE_MEM;
if (mType == ASMIT_JSR) if (mType == ASMIT_JSR)
{ {
requiredTemps -= CPU_REG_C; requiredTemps -= CPU_REG_C;
@ -66,6 +88,9 @@ bool NativeCodeInstruction::IsUsedResultInstructions(NumberSet& requiredTemps)
requiredTemps += BC_REG_WORK + i; requiredTemps += BC_REG_WORK + i;
} }
requiredTemps += BC_REG_LOCALS;
requiredTemps += BC_REG_LOCALS + 1;
return true; return true;
} }
@ -414,7 +439,7 @@ bool NativeCodeInstruction::LoadsAccu(void) const
bool NativeCodeInstruction::ChangesAddress(void) const bool NativeCodeInstruction::ChangesAddress(void) const
{ {
if (mMode != ASMIM_IMPLIED) if (mMode != ASMIM_IMPLIED)
return mType == ASMIT_INC || mType == ASMIT_DEC || mType == ASMIT_ASL || mType == ASMIT_LSR || mType == ASMIT_ROL || mType == ASMIT_ROR; return mType == ASMIT_INC || mType == ASMIT_DEC || mType == ASMIT_ASL || mType == ASMIT_LSR || mType == ASMIT_ROL || mType == ASMIT_ROR || mType == ASMIT_STA || mType == ASMIT_STX || mType == ASMIT_STY;
else else
return false; return false;
} }
@ -436,6 +461,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
{ {
data.ResetZeroPage(BC_REG_ACCU + i); data.ResetZeroPage(BC_REG_ACCU + i);
data.ResetZeroPage(BC_REG_WORK + i); data.ResetZeroPage(BC_REG_WORK + i);
data.ResetZeroPage(BC_REG_ADDR + i);
} }
return false; return false;
@ -726,6 +752,9 @@ void NativeCodeInstruction::FilterRegUsage(NumberSet& requiredTemps, NumberSet&
if (!providedTemps[BC_REG_WORK + i]) if (!providedTemps[BC_REG_WORK + i])
requiredTemps += BC_REG_WORK + i; requiredTemps += BC_REG_WORK + i;
providedTemps += BC_REG_WORK + i; providedTemps += BC_REG_WORK + i;
if (!providedTemps[BC_REG_ADDR + i])
requiredTemps += BC_REG_ADDR + i;
providedTemps += BC_REG_ADDR + i;
} }
providedTemps += CPU_REG_A; providedTemps += CPU_REG_A;
@ -1163,24 +1192,35 @@ void NativeCodeBasicBlock::LoadConstantToReg(InterCodeProcedure * proc, const In
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM) else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{ {
int index = ins.mIntValue; int index = ins.mIntValue;
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins.mMemory == IM_LOCAL) if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset; index += proc->mLocalVars[ins.mVarIndex].mOffset;
else else
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
CheckFrameIndex(areg, index, 2);
if (index != 0) if (index != 0)
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, areg));
if (index != 0) if (index != 0)
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, (mNoFrame ? BC_REG_STACK : BC_REG_LOCALS) + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, areg + 1));
if (index != 0) if (index != 0)
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
} }
else if (ins.mMemory == IM_PROCEDURE) else if (ins.mMemory == IM_PROCEDURE)
{ {
NativeCodeInstruction lins(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins.mSIntConst[0], ins.mVarIndex, true, false);
lins.mFunction = ins.mMemory == IM_PROCEDURE;
NativeCodeInstruction hins(ASMIT_LDA, ASMIM_IMMEDIATE_ADDRESS, ins.mSIntConst[0], ins.mVarIndex, false, true);
hins.mFunction = ins.mMemory == IM_PROCEDURE;
mIns.Push(lins);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(hins);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
} }
} }
else else
@ -1198,6 +1238,22 @@ void NativeCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterIns
LoadConstantToReg(proc, ins, ins.mTType, BC_REG_TMP + proc->mTempOffset[ins.mTTemp]); LoadConstantToReg(proc, ins, ins.mTType, BC_REG_TMP + proc->mTempOffset[ins.mTTemp]);
} }
void NativeCodeBasicBlock::CheckFrameIndex(int& reg, int& index, int size)
{
if (index + size > 256)
{
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, index & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, reg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, (index >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ADDR + 1));
index = 0;
reg = BC_REG_ADDR;
}
}
void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstruction& ins) void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstruction& ins)
{ {
if (ins.mSType[0] == IT_FLOAT) if (ins.mSType[0] == IT_FLOAT)
@ -1234,23 +1290,25 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM) else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{ {
int index = ins.mSIntConst[1]; int index = ins.mSIntConst[1];
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins.mMemory == IM_LOCAL) if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset; index += proc->mLocalVars[ins.mVarIndex].mOffset;
else else
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
CheckFrameIndex(reg, index, 4);
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 & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
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_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
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_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
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_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
} }
else if (ins.mMemory == IM_FRAME) else if (ins.mMemory == IM_FRAME)
{ {
@ -1306,23 +1364,25 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM) else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{ {
int index = ins.mSIntConst[1]; int index = ins.mSIntConst[1];
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins.mMemory == IM_LOCAL) if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset; index += proc->mLocalVars[ins.mVarIndex].mOffset;
else else
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
CheckFrameIndex(reg, index, 4);
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
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_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
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_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
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_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
} }
else if (ins.mMemory == IM_FRAME) else if (ins.mMemory == IM_FRAME)
{ {
@ -1406,17 +1466,19 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM) else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{ {
int index = ins.mSIntConst[1]; int index = ins.mSIntConst[1];
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins.mMemory == IM_LOCAL) if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset; index += proc->mLocalVars[ins.mVarIndex].mOffset;
else else
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
CheckFrameIndex(reg, index, 2);
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
} }
else if (ins.mMemory == IM_FRAME) else if (ins.mMemory == IM_FRAME)
{ {
@ -1449,17 +1511,19 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM) else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{ {
int index = ins.mSIntConst[1]; int index = ins.mSIntConst[1];
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins.mMemory == IM_LOCAL) if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset; index += proc->mLocalVars[ins.mVarIndex].mOffset;
else else
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
CheckFrameIndex(reg, index, 2);
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.mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
} }
else if (ins.mMemory == IM_FRAME) else if (ins.mMemory == IM_FRAME)
{ {
@ -1523,17 +1587,24 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM) else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{ {
int index = ins.mSIntConst[1]; int index = ins.mSIntConst[1];
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins.mMemory == IM_LOCAL) if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset; index += proc->mLocalVars[ins.mVarIndex].mOffset;
else else
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
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.mSIntConst[0] & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
} }
else if (ins.mMemory == IM_FRAME) else if (ins.mMemory == IM_FRAME)
{ {
int index = ins.mVarIndex + ins.mSIntConst[1] + 2;
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
} }
} }
else if (ins.mOperandSize == 2) else if (ins.mOperandSize == 2)
@ -1555,17 +1626,19 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM) else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{ {
int index = ins.mSIntConst[1]; int index = ins.mSIntConst[1];
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins.mMemory == IM_LOCAL) if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset; index += proc->mLocalVars[ins.mVarIndex].mOffset;
else else
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
CheckFrameIndex(reg, index, 2);
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 8) & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
} }
else if (ins.mMemory == IM_FRAME) else if (ins.mMemory == IM_FRAME)
{ {
@ -1597,14 +1670,16 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM) else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{ {
int index = ins.mSIntConst[1]; int index = ins.mSIntConst[1];
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins.mMemory == IM_LOCAL) if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset; index += proc->mLocalVars[ins.mVarIndex].mOffset;
else else
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
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.mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
} }
else if (ins.mMemory == IM_FRAME) else if (ins.mMemory == IM_FRAME)
{ {
@ -1634,17 +1709,20 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM) else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{ {
int index = ins.mSIntConst[1]; int index = ins.mSIntConst[1];
int reg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins.mMemory == IM_LOCAL) if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset; index += proc->mLocalVars[ins.mVarIndex].mOffset;
else else
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
CheckFrameIndex(reg, index, 2);
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.mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, reg));
} }
else if (ins.mMemory == IM_FRAME) else if (ins.mMemory == IM_FRAME)
{ {
@ -1728,13 +1806,15 @@ void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterI
else if (rins.mMemory == IM_LOCAL || rins.mMemory == IM_PARAM) else if (rins.mMemory == IM_LOCAL || rins.mMemory == IM_PARAM)
{ {
int index = rins.mSIntConst[0]; int index = rins.mSIntConst[0];
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (rins.mMemory == IM_LOCAL) if (rins.mMemory == IM_LOCAL)
index += proc->mLocalVars[rins.mVarIndex].mOffset; index += proc->mLocalVars[rins.mVarIndex].mOffset;
else else
index += rins.mVarIndex + proc->mLocalSize + 2; index += rins.mVarIndex + proc->mLocalSize + 2;
CheckFrameIndex(areg, index, 4);
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
} }
} }
else else
@ -1742,7 +1822,7 @@ void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterI
if (rins.mMemory == IM_INDIRECT) if (rins.mMemory == IM_INDIRECT)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[wins.mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[rins.mSTemp[0]]));
} }
} }
@ -1759,16 +1839,22 @@ void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterI
else if (wins.mMemory == IM_LOCAL || wins.mMemory == IM_PARAM) else if (wins.mMemory == IM_LOCAL || wins.mMemory == IM_PARAM)
{ {
int index = wins.mSIntConst[1]; int index = wins.mSIntConst[1];
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (wins.mMemory == IM_LOCAL) if (wins.mMemory == IM_LOCAL)
index += proc->mLocalVars[wins.mVarIndex].mOffset; index += proc->mLocalVars[wins.mVarIndex].mOffset;
else else
index += wins.mVarIndex + proc->mLocalSize + 2; index += wins.mVarIndex + proc->mLocalSize + 2;
CheckFrameIndex(areg, index, 1);
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, areg));
} }
else if (wins.mMemory == IM_FRAME) else if (wins.mMemory == IM_FRAME)
{ {
int index = wins.mVarIndex + wins.mSIntConst[1] + 2;
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
} }
} }
else else
@ -1814,22 +1900,24 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM) else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{ {
int index = ins.mSIntConst[0]; int index = ins.mSIntConst[0];
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins.mMemory == IM_LOCAL) if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset; index += proc->mLocalVars[ins.mVarIndex].mOffset;
else else
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
CheckFrameIndex(areg, index, 4);
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3));
} }
} }
@ -1859,7 +1947,14 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
if (ins.mMemory == IM_GLOBAL) if (ins.mMemory == IM_GLOBAL)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0], ins.mVarIndex)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0], ins.mVarIndex));
if (ainsl) mIns.Push(*ainsl); 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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0] + 1, ins.mVarIndex)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0] + 1, ins.mVarIndex));
if (ainsh) mIns.Push(*ainsh); if (ainsh) mIns.Push(*ainsh);
@ -1868,7 +1963,14 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
else if (ins.mMemory == IM_ABSOLUTE) else if (ins.mMemory == IM_ABSOLUTE)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0]));
if (ainsl) mIns.Push(*ainsl); 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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0] + 1));
if (ainsh) mIns.Push(*ainsh); if (ainsh) mIns.Push(*ainsh);
@ -1877,17 +1979,26 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM) else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{ {
int index = ins.mSIntConst[0]; int index = ins.mSIntConst[0];
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins.mMemory == IM_LOCAL) if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset; index += proc->mLocalVars[ins.mVarIndex].mOffset;
else else
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
CheckFrameIndex(areg, index, 2);
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
if (ainsl) mIns.Push(*ainsl); 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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
if (ainsh) mIns.Push(*ainsh); if (ainsh) mIns.Push(*ainsh);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
} }
@ -1896,14 +2007,27 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
{ {
if (ins.mMemory == IM_INDIRECT) if (ins.mMemory == IM_INDIRECT)
{ {
int src = BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]];
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, src));
if (ainsl) mIns.Push(*ainsl); if (ainsl)
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); {
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 (reg == src)
mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED));
else
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, src));
if (ainsh) mIns.Push(*ainsh); if (ainsh) mIns.Push(*ainsh);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
if (reg == src)
mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, reg));
} }
} }
} }
@ -1927,16 +2051,25 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM) else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{ {
int index = ins.mSIntConst[0]; int index = ins.mSIntConst[0];
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins.mMemory == IM_LOCAL) if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset; index += proc->mLocalVars[ins.mVarIndex].mOffset;
else else
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
CheckFrameIndex(areg, index, 2);
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
} }
if (ainsl) mIns.Push(*ainsl); 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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
if (ins.mTType == IT_SIGNED) if (ins.mTType == IT_SIGNED)
{ {
@ -1956,7 +2089,14 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
if (ins.mMemory == IM_GLOBAL) if (ins.mMemory == IM_GLOBAL)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0], ins.mVarIndex)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0], ins.mVarIndex));
if (ainsl) mIns.Push(*ainsl); 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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0] + 1, ins.mVarIndex)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0] + 1, ins.mVarIndex));
if (ainsh) mIns.Push(*ainsh); if (ainsh) mIns.Push(*ainsh);
@ -1965,7 +2105,14 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
else if (ins.mMemory == IM_ABSOLUTE) else if (ins.mMemory == IM_ABSOLUTE)
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0]));
if (ainsl) mIns.Push(*ainsl); 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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0] + 1));
if (ainsh) mIns.Push(*ainsh); if (ainsh) mIns.Push(*ainsh);
@ -1974,17 +2121,26 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM) else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{ {
int index = ins.mSIntConst[0]; int index = ins.mSIntConst[0];
int areg = mNoFrame ? BC_REG_STACK : BC_REG_LOCALS;
if (ins.mMemory == IM_LOCAL) if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset; index += proc->mLocalVars[ins.mVarIndex].mOffset;
else else
index += ins.mVarIndex + proc->mLocalSize + 2; index += ins.mVarIndex + proc->mLocalSize + 2;
CheckFrameIndex(areg, index, 2);
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
if (ainsl) mIns.Push(*ainsl); 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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, areg));
if (ainsh) mIns.Push(*ainsh); if (ainsh) mIns.Push(*ainsh);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
} }
@ -1998,7 +2154,14 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
{ {
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
if (ainsl) mIns.Push(*ainsl); 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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
if (ins.mTType == IT_SIGNED) if (ins.mTType == IT_SIGNED)
{ {
@ -2015,14 +2178,29 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
} }
else if (ins.mOperandSize == 2) else if (ins.mOperandSize == 2)
{ {
int src = BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]];
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, src));
if (ainsl) mIns.Push(*ainsl); if (ainsl)
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg)); {
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 (reg == src)
mIns.Push(NativeCodeInstruction(ASMIT_TAX, ASMIM_IMPLIED));
else
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, src));
if (ainsh) mIns.Push(*ainsh); if (ainsh) mIns.Push(*ainsh);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
if (reg == src)
mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, reg));
} }
} }
} }
@ -2034,6 +2212,42 @@ void NativeCodeBasicBlock::LoadValue(InterCodeProcedure* proc, const InterInstru
LoadValueToReg(proc, ins, BC_REG_TMP + proc->mTempOffset[ins.mTTemp], nullptr, nullptr); LoadValueToReg(proc, ins, BC_REG_TMP + proc->mTempOffset[ins.mTTemp], nullptr, nullptr);
} }
void NativeCodeBasicBlock::CopyValue(InterCodeProcedure* proc, const InterInstruction& ins, NativeCodeProcedure* nproc)
{
int sreg = BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]], dreg = BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]];
int size = ins.mOperandSize;
if (size < 4)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
for (int i = 0; i < size; i++)
{
if (i > 0)
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg));
}
}
else if (size < 128)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, size - 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg));
mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, -7));
}
else if (size <= 256)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, size - 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg));
mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_BNE, ASMIM_RELATIVE, -7));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, sreg));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, dreg));
}
}
bool NativeCodeBasicBlock::CheckPredAccuStore(int reg) bool NativeCodeBasicBlock::CheckPredAccuStore(int reg)
{ {
if (mIns.Size() < 8) if (mIns.Size() < 8)
@ -2289,7 +2503,6 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
{ {
case IA_ADD: case IA_ADD:
atype = ASMIT_ADC; atype = ASMIT_ADC;
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
break; break;
case IA_OR: case IA_OR:
atype = ASMIT_ORA; atype = ASMIT_ORA;
@ -2310,6 +2523,8 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
LoadValueToReg(proc, *sins0, treg, &insl, &insh); LoadValueToReg(proc, *sins0, treg, &insl, &insh);
else else
{ {
if (ins.mOperator == IA_ADD)
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(insl); mIns.Push(insl);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
@ -2326,6 +2541,8 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
LoadValueToReg(proc, *sins1, treg, &insl, &insh); LoadValueToReg(proc, *sins1, treg, &insl, &insh);
else else
{ {
if (ins.mOperator == IA_ADD)
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]));
mIns.Push(insl); mIns.Push(insl);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
@ -2360,6 +2577,8 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
} }
else else
{ {
if (ins.mOperator == IA_ADD)
mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]));
mIns.Push(NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]])); mIns.Push(NativeCodeInstruction(atype, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
@ -2374,7 +2593,6 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
{ {
NativeCodeInstruction insl, insh; NativeCodeInstruction insl, insh;
mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
if (ins.mSTemp[0] < 0) if (ins.mSTemp[0] < 0)
{ {
insl = NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff); insl = NativeCodeInstruction(ASMIT_SBC, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff);
@ -2383,6 +2601,7 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
LoadValueToReg(proc, *sins1, treg, &insl, &insh); LoadValueToReg(proc, *sins1, treg, &insl, &insh);
else else
{ {
mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]));
mIns.Push(insl); mIns.Push(insl);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
@ -2407,6 +2626,7 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
} }
else else
{ {
mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[1] & 0xff)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[1] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]])); mIns.Push(NativeCodeInstruction(ASMIT_SBC, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
@ -2436,6 +2656,7 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
} }
else else
{ {
mIns.Push(NativeCodeInstruction(ASMIT_SEC, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]])); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]));
mIns.Push(insl); mIns.Push(insl);
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg));
@ -3424,6 +3645,8 @@ bool NativeCodeBasicBlock::MoveLoadStoreUp(int at)
return false; return false;
if (mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at].mAddress && mIns[j].ChangesAddress()) if (mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at].mAddress && mIns[j].ChangesAddress())
return false; return false;
if (mIns[j].mMode == ASMIM_ABSOLUTE_Y && mIns[j].mAddress <= mIns[at + 1].mAddress && mIns[j].mType == ASMIT_LDA && mIns[j].mVarIndex < 0)
return false;
if (mIns[j].mType == ASMIT_JSR) if (mIns[j].mType == ASMIT_JSR)
return false; return false;
} }
@ -3443,10 +3666,12 @@ bool NativeCodeBasicBlock::MoveLoadStoreUp(int at)
return false; return false;
} }
void NativeCodeBasicBlock::PeepHoleOptimizer(void) bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
{ {
if (!mVisited) if (!mVisited)
{ {
bool changed = false;
mVisited = true; mVisited = true;
NativeRegisterDataSet data; NativeRegisterDataSet data;
@ -3460,8 +3685,11 @@ void NativeCodeBasicBlock::PeepHoleOptimizer(void)
for (int i = 2; i + 2 < mIns.Size(); i++) for (int i = 2; i + 2 < mIns.Size(); i++)
{ {
if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].LoadsAccu()) if (mIns[i].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mType == ASMIT_STA && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && (mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) == 0)
MoveLoadStoreUp(i); {
if (MoveLoadStoreUp(i))
changed = true;
}
} }
bool progress = false; bool progress = false;
@ -3482,6 +3710,8 @@ void NativeCodeBasicBlock::PeepHoleOptimizer(void)
} }
i++; i++;
} }
if (j != i)
changed = true;
mIns.SetSize(j); mIns.SetSize(j);
for (int i = 0; i < mIns.Size(); i++) for (int i = 0; i < mIns.Size(); i++)
@ -3491,7 +3721,7 @@ void NativeCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i].mType = ASMIT_LDA; mIns[i].mType = ASMIT_LDA;
progress = true; progress = true;
} }
else if (mIns[i].mType == ASMIT_AND && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i].mAddress == 0xff) else if (mIns[i].mType == ASMIT_AND && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i].mAddress == 0xff && (mIns[i].mLive & LIVE_CPU_REG_Z) == 0)
{ {
mIns[i].mType = ASMIT_NOP; mIns[i].mType = ASMIT_NOP;
progress = true; progress = true;
@ -3501,7 +3731,7 @@ void NativeCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i].mType = ASMIT_LDA; mIns[i].mType = ASMIT_LDA;
progress = true; progress = true;
} }
else if (mIns[i].mType == ASMIT_ORA && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i].mAddress == 0x00) else if (mIns[i].mType == ASMIT_ORA && mIns[i].mMode == ASMIM_IMMEDIATE && mIns[i].mAddress == 0x00 && (mIns[i].mLive & LIVE_CPU_REG_Z) == 0)
{ {
mIns[i].mType = ASMIT_NOP; mIns[i].mType = ASMIT_NOP;
progress = true; progress = true;
@ -3519,7 +3749,7 @@ void NativeCodeBasicBlock::PeepHoleOptimizer(void)
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mType = ASMIT_NOP;
progress = true; progress = true;
} }
else if (mIns[i].mType == ASMIT_STA && mIns[i + 1].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[i + 1].mAddress) else if (mIns[i].mType == ASMIT_STA && mIns[i + 1].mType == ASMIT_LDA && mIns[i].mMode == ASMIM_ZERO_PAGE && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && mIns[i].mAddress == mIns[i + 1].mAddress && (mIns[i + 1].mLive & LIVE_CPU_REG_Z) == 0)
{ {
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mType = ASMIT_NOP;
progress = true; progress = true;
@ -3566,13 +3796,20 @@ void NativeCodeBasicBlock::PeepHoleOptimizer(void)
} }
} }
if (progress)
changed = true;
} while (progress); } while (progress);
if (this->mTrueJump) if (this->mTrueJump && this->mTrueJump->PeepHoleOptimizer())
this->mTrueJump->PeepHoleOptimizer(); changed = true;
if (this->mFalseJump) if (this->mFalseJump && this->mFalseJump->PeepHoleOptimizer())
this->mFalseJump->PeepHoleOptimizer(); changed = true;
return changed;
} }
return false;
} }
void NativeCodeBasicBlock::Assemble(void) void NativeCodeBasicBlock::Assemble(void)
@ -3851,7 +4088,7 @@ void NativeCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedu
int tempSave = proc->mTempSize > 16 ? proc->mTempSize - 16 : 0; int tempSave = proc->mTempSize > 16 ? proc->mTempSize - 16 : 0;
int stackExpand = tempSave + proc->mLocalSize + 2; int stackExpand = tempSave + proc->mLocalSize + 2;
mNoFrame = proc->mLocalSize == 0 && tempSave == 0; mNoFrame = proc->mLocalSize == 0 && tempSave == 0 && proc->mLeafProcedure;
entryBlock = new NativeCodeBasicBlock(); entryBlock = new NativeCodeBasicBlock();
mBlocks.Push(entryBlock); mBlocks.Push(entryBlock);
@ -3963,14 +4200,19 @@ void NativeCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedu
CompileInterBlock(proc, proc->mBlocks[0], entryBlock); CompileInterBlock(proc, proc->mBlocks[0], entryBlock);
#if 1 #if 1
bool changed;
do do
{ {
ResetVisited();
entryBlock->PeepHoleOptimizer();
BuildDataFlowSets(); BuildDataFlowSets();
ResetVisited(); ResetVisited();
} while (entryBlock->RemoveUnusedResultInstructions());
changed = entryBlock->RemoveUnusedResultInstructions();
ResetVisited();
if (entryBlock->PeepHoleOptimizer())
changed = true;
} while (changed);
ResetVisited(); ResetVisited();
entryBlock->PeepHoleOptimizer(); entryBlock->PeepHoleOptimizer();
@ -4124,7 +4366,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
block->LoadValue(iproc, ins); block->LoadValue(iproc, ins);
break; break;
case IC_COPY: case IC_COPY:
// CopyValue(iproc, ins); block->CopyValue(iproc, ins, this);
break; break;
case IC_LOAD_TEMPORARY: case IC_LOAD_TEMPORARY:
{ {

View File

@ -37,6 +37,7 @@ public:
int mAddress, mVarIndex; int mAddress, mVarIndex;
bool mLower, mUpper, mFunction; bool mLower, mUpper, mFunction;
const char * mRuntime; const char * mRuntime;
uint32 mLive;
void Assemble(NativeCodeBasicBlock* block); void Assemble(NativeCodeBasicBlock* block);
void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps); void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
@ -75,11 +76,12 @@ public:
void Assemble(void); void Assemble(void);
void Close(NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump, AsmInsType branch); void Close(NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump, AsmInsType branch);
void PeepHoleOptimizer(void); bool PeepHoleOptimizer(void);
void PutByte(uint8 code); void PutByte(uint8 code);
void PutWord(uint16 code); void PutWord(uint16 code);
void CheckFrameIndex(int & reg, int & index, int size);
void LoadValueToReg(InterCodeProcedure* proc, const InterInstruction& ins, int reg, const NativeCodeInstruction * ainsl, const NativeCodeInstruction* ainsh); void LoadValueToReg(InterCodeProcedure* proc, const InterInstruction& ins, int reg, const NativeCodeInstruction * ainsl, const NativeCodeInstruction* ainsh);
void LoadConstantToReg(InterCodeProcedure* proc, const InterInstruction& ins, InterType type, int reg); void LoadConstantToReg(InterCodeProcedure* proc, const InterInstruction& ins, InterType type, int reg);
@ -92,6 +94,7 @@ public:
void RelationalOperator(InterCodeProcedure* proc, const InterInstruction& ins, NativeCodeProcedure * nproc, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump); void RelationalOperator(InterCodeProcedure* proc, const InterInstruction& ins, NativeCodeProcedure * nproc, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump);
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction& ins); void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction& ins);
void NumericConversion(InterCodeProcedure* proc, const InterInstruction& ins); void NumericConversion(InterCodeProcedure* proc, const InterInstruction& ins);
void CopyValue(InterCodeProcedure* proc, const InterInstruction& ins, NativeCodeProcedure* nproc);
void CallAssembler(InterCodeProcedure* proc, const InterInstruction& ins); void CallAssembler(InterCodeProcedure* proc, const InterInstruction& ins);
void CallFunction(InterCodeProcedure* proc, const InterInstruction& ins); void CallFunction(InterCodeProcedure* proc, const InterInstruction& ins);

View File

@ -1906,6 +1906,8 @@ Expression* Parser::ParseAssemblerOperand(void)
} }
else else
mErrors->Error(mScanner->mLocation, "Constant for upper byte operator expected"); mErrors->Error(mScanner->mLocation, "Constant for upper byte operator expected");
return exp;
} }
else else
return ParseAssemblerAddOperand(); return ParseAssemblerAddOperand();

View File

@ -111,6 +111,10 @@ int main(int argc, const char** argv)
{ {
strcpy_s(crtPath, arg + 4); strcpy_s(crtPath, arg + 4);
} }
else if (arg[1] == 'n')
{
compiler->ForceNativeCode(true);
}
else if (arg[1] == 'e') else if (arg[1] == 'e')
{ {
emulate = true; emulate = true;