diff --git a/include/c64/asm6502.c b/include/c64/asm6502.c new file mode 100644 index 0000000..e60b06e --- /dev/null +++ b/include/c64/asm6502.c @@ -0,0 +1,94 @@ +#include "asm6502.h" + +inline byte asm_np(byte * ip, AsmIns ins) +{ + ip[0] = ins & 0xff; + return 1; +} + +inline byte asm_ac(byte * ip, AsmIns ins) +{ + ip[0] = (ins & 0xff) | 0x08; + return 1; +} + +inline byte asm_zp(byte * ip, AsmIns ins, byte addr) +{ + ip[0] = (ins & 0xff) | 0x04; + ip[1] = addr; + return 2; +} + +inline byte asm_rl(byte * ip, AsmIns ins, byte addr) +{ + ip[0] = ins & 0xff; + ip[1] = addr; + return 2; +} + +inline byte asm_im(byte * ip, AsmIns ins, byte value) +{ + ip[0] = (ins & 0xff) | ((ins & 0x01) << 3); + ip[1] = value; + return 2; +} + +inline byte asm_zx(byte * ip, AsmIns ins, byte addr) +{ + ip[0] = (ins & 0xff) | 0x05; + ip[1] = addr; + return 2; +} + +inline byte asm_zy(byte * ip, AsmIns ins, byte addr) +{ + ip[0] = (ins & 0xff) | 0x05; + ip[1] = addr; + return 2; +} + +inline byte asm_ab(byte * ip, AsmIns ins, unsigned addr) +{ + ip[0] = (ins & 0xff) ^ 0x0c; + ip[1] = addr & 0xff; + ip[2] = addr >> 8; + return 3; +} + +inline byte asm_in(byte * ip, AsmIns ins, unsigned addr) +{ + ip[0] = (ins & 0xff) ^ 0x2c; + ip[1] = addr & 0xff; + ip[2] = addr >> 8; + return 3; +} + +inline byte asm_ax(byte * ip, AsmIns ins, unsigned addr) +{ + ip[0] = (ins & 0xff) | 0x1c; + ip[1] = addr & 0xff; + ip[2] = addr >> 8; + return 3; +} + +inline byte asm_ay(byte * ip, AsmIns ins, unsigned addr) +{ + ip[0] = (ins & 0xff) | 0x18; + ip[1] = addr & 0xff; + ip[2] = addr >> 8; + return 3; +} + +inline byte asm_ix(byte * ip, AsmIns ins, byte addr) +{ + ip[0] = (ins & 0xff) | 0x00; + ip[1] = addr; + return 2; +} + +inline byte asm_iy(byte * ip, AsmIns ins, byte addr) +{ + ip[0] = (ins & 0xff) | 0x10; + ip[1] = addr; + return 2; +} diff --git a/include/c64/asm6502.h b/include/c64/asm6502.h index 61d1659..85f0124 100644 --- a/include/c64/asm6502.h +++ b/include/c64/asm6502.h @@ -82,98 +82,33 @@ enum AsmIns ASM_JSR = 0x2c }; -inline byte asm_np(byte * ip, AsmIns ins) -{ - ip[0] = ins & 0xff; - return 1; -} +inline byte asm_np(byte * ip, AsmIns ins); -inline byte asm_ac(byte * ip, AsmIns ins) -{ - ip[0] = (ins & 0xff) | 0x08; - return 1; -} +inline byte asm_ac(byte * ip, AsmIns ins); -inline byte asm_zp(byte * ip, AsmIns ins, byte addr) -{ - ip[0] = (ins & 0xff) | 0x04; - ip[1] = addr; - return 2; -} +inline byte asm_zp(byte * ip, AsmIns ins, byte addr); -inline byte asm_rl(byte * ip, AsmIns ins, byte addr) -{ - ip[0] = ins & 0xff; - ip[1] = addr; - return 2; -} +inline byte asm_rl(byte * ip, AsmIns ins, byte addr); -inline byte asm_im(byte * ip, AsmIns ins, byte value) -{ - ip[0] = (ins & 0xff) | ((ins & 0x01) << 3); - ip[1] = value; - return 2; -} +inline byte asm_im(byte * ip, AsmIns ins, byte value); -inline byte asm_zx(byte * ip, AsmIns ins, byte addr) -{ - ip[0] = (ins & 0xff) | 0x05; - ip[1] = addr; - return 2; -} +inline byte asm_zx(byte * ip, AsmIns ins, byte addr); -inline byte asm_zy(byte * ip, AsmIns ins, byte addr) -{ - ip[0] = (ins & 0xff) | 0x05; - ip[1] = addr; - return 2; -} +inline byte asm_zy(byte * ip, AsmIns ins, byte addr); -inline byte asm_ab(byte * ip, AsmIns ins, unsigned addr) -{ - ip[0] = (ins & 0xff) ^ 0x0c; - ip[1] = addr & 0xff; - ip[2] = addr >> 8; - return 3; -} +inline byte asm_ab(byte * ip, AsmIns ins, unsigned addr); -inline byte asm_in(byte * ip, AsmIns ins, unsigned addr) -{ - ip[0] = (ins & 0xff) ^ 0x2c; - ip[1] = addr & 0xff; - ip[2] = addr >> 8; - return 3; -} +inline byte asm_in(byte * ip, AsmIns ins, unsigned addr); -inline byte asm_ax(byte * ip, AsmIns ins, unsigned addr) -{ - ip[0] = (ins & 0xff) | 0x1c; - ip[1] = addr & 0xff; - ip[2] = addr >> 8; - return 3; -} +inline byte asm_ax(byte * ip, AsmIns ins, unsigned addr); -inline byte asm_ay(byte * ip, AsmIns ins, unsigned addr) -{ - ip[0] = (ins & 0xff) | 0x18; - ip[1] = addr & 0xff; - ip[2] = addr >> 8; - return 3; -} +inline byte asm_ay(byte * ip, AsmIns ins, unsigned addr); -inline byte asm_ix(byte * ip, AsmIns ins, byte addr) -{ - ip[0] = (ins & 0xff) | 0x00; - ip[1] = addr; - return 2; -} +inline byte asm_ix(byte * ip, AsmIns ins, byte addr); -inline byte asm_iy(byte * ip, AsmIns ins, byte addr) -{ - ip[0] = (ins & 0xff) | 0x10; - ip[1] = addr; - return 2; -} +inline byte asm_iy(byte * ip, AsmIns ins, byte addr); + +#pragma compile("asm6502.c") #endif diff --git a/include/c64/memmap.c b/include/c64/memmap.c new file mode 100644 index 0000000..7db319f --- /dev/null +++ b/include/c64/memmap.c @@ -0,0 +1,61 @@ +#include "memmap.h" + +char PLAShadow; + +__asm DoneTrampoline +{ + lda PLAShadow + sta $01 + pla + tax + pla + rti +} + +__asm IRQTrampoline +{ + pha + txa + pha + lda #$36 + sta $01 + + lda #>DoneTrampoline + pha + lda #DoneTrampoline + pha + lda #> 14) ^ 0x03); + vic.memptr = (((unsigned)text >> 6) & 0xf0) | (((unsigned)font >> 10) & 0x0e); +} diff --git a/include/c64/vic.h b/include/c64/vic.h index 0fb37c7..a1ee2d8 100644 --- a/include/c64/vic.h +++ b/include/c64/vic.h @@ -75,6 +75,17 @@ struct VIC void vic_setbank(char bank); +enum VicMode +{ + VICM_TEXT, + VICM_TEXT_MC, + VICM_TEXT_ECM, + VICM_HIRES, + VICM_HIRES_MC +}; + +void vic_setmode(VicMode mode, char * text, char * font); + inline void vic_sprxy(byte s, int x, int y); diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index b3a62bd..c4da221 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -368,7 +368,7 @@ Expression* Expression::ConstantFold(Errors * errors) } Declaration::Declaration(const Location& loc, DecType type) - : mLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0), mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr) + : mLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0), mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1) {} Declaration::~Declaration(void) diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 6c2e492..dbcedac 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -167,7 +167,7 @@ public: Declaration* mBase, *mParams, * mNext; Expression* mValue; DeclarationScope* mScope; - int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize; + int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment; int64 mInteger; double mNumber; uint32 mFlags; diff --git a/oscar64/GlobalAnalyzer.cpp b/oscar64/GlobalAnalyzer.cpp index 783dd69..27dc3cc 100644 --- a/oscar64/GlobalAnalyzer.cpp +++ b/oscar64/GlobalAnalyzer.cpp @@ -59,7 +59,7 @@ void GlobalAnalyzer::AutoInline(void) for (int i = 0; i < mFunctions.Size(); i++) { Declaration* f = mFunctions[i]; - if (!(f->mFlags & DTF_INLINE) && !(f->mBase->mFlags & DTF_VARIADIC) && !(f->mFlags & DTF_FUNC_VARIABLE) && !(f->mFlags & DTF_FUNC_ASSEMBLER) && !(f->mFlags & DTF_INTRINSIC) && !(f->mFlags & DTF_FUNC_RECURSIVE) && f->mLocalSize < 100) + if (!(f->mFlags & DTF_INLINE) && !(f->mBase->mFlags & DTF_VARIADIC) && !(f->mFlags & DTF_FUNC_VARIABLE) && !((f->mFlags & DTF_FUNC_ASSEMBLER) && !(f->mFlags & DTF_REQUEST_INLINE)) && !(f->mFlags & DTF_INTRINSIC) && !(f->mFlags & DTF_FUNC_RECURSIVE) && f->mLocalSize < 100) { int nparams = 0; Declaration* dec = f->mBase->mParams; diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index dd0ef61..c7007fd 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -214,7 +214,7 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration* InterVariable * var = new InterVariable(); var->mOffset = 0; var->mSize = dec->mSize; - var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA); + var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA, dec->mAlignment); var->mIdent = dec->mIdent; Declaration* type = dec->mBase; @@ -830,7 +830,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* var->mSize = dec->mSize; if ((dec->mFlags & DTF_VAR_ALIASING) || dec->mBase->mType == DT_TYPE_ARRAY) var->mAliased = true; - var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA); + var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA, dec->mAlignment); dec->mLinkerObject = var->mLinkerObject; var->mLinkerObject->AddData(dec->mData, dec->mSize); proc->mModule->mGlobalVars.Push(var); @@ -855,7 +855,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* InterVariable * var = new InterVariable(); var->mOffset = 0; var->mSize = dec->mSize; - var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA); + var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA, dec->mAlignment); dec->mLinkerObject = var->mLinkerObject; var->mIdent = dec->mIdent; dec->mVarIndex = proc->mModule->mGlobalVars.Size(); @@ -3222,7 +3222,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int var->mIndex = dec->mVarIndex; var->mOffset = 0; var->mSize = dec->mSize; - var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA); + var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA, dec->mAlignment); dec->mLinkerObject = var->mLinkerObject; var->mLinkerObject->AddData(dec->mData, dec->mSize); mod->mGlobalVars.Push(var); @@ -3233,6 +3233,21 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int variable->mLinkerObject->AddReference(ref); break; } + case DT_VARIABLE: + { + if (!dec->mLinkerObject) + { + InitGlobalVariable(mod, dec); + } + + LinkerReference ref; + ref.mObject = variable->mLinkerObject; + ref.mOffset = offset; + ref.mFlags = LREF_LOWBYTE | LREF_HIGHBYTE; + ref.mRefObject = dec->mLinkerObject; + ref.mRefOffset = 0; + variable->mLinkerObject->AddReference(ref); + } break; } } } diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp index 6ad56d4..b7ee445 100644 --- a/oscar64/Linker.cpp +++ b/oscar64/Linker.cpp @@ -12,7 +12,7 @@ LinkerSection::LinkerSection(void) {} LinkerObject::LinkerObject(void) - : mReferences(nullptr), mNumTemporaries(0) + : mReferences(nullptr), mNumTemporaries(0), mSize(0), mAlignment(1) {} LinkerObject::~LinkerObject(void) @@ -133,7 +133,7 @@ LinkerObject* Linker::FindObjectByAddr(int addr) return nullptr; } -LinkerObject * Linker::AddObject(const Location& location, const Ident* ident, LinkerSection * section, LinkerObjectType type) +LinkerObject * Linker::AddObject(const Location& location, const Ident* ident, LinkerSection * section, LinkerObjectType type, int alignment) { LinkerObject* obj = new LinkerObject; obj->mLocation = location; @@ -146,6 +146,7 @@ LinkerObject * Linker::AddObject(const Location& location, const Ident* ident, L obj->mRegion = nullptr; obj->mProc = nullptr; obj->mFlags = 0; + obj->mAlignment = alignment; section->mObjects.Push(obj); mObjects.Push(obj); return obj; @@ -201,8 +202,9 @@ void Linker::Link(void) if ((lobj->mFlags & LOBJF_REFERENCED) && !(lobj->mFlags & LOBJF_PLACED) && lrgn->mStart + lrgn->mUsed + lobj->mSize <= lrgn->mEnd) { lobj->mFlags |= LOBJF_PLACED; - lobj->mAddress = lrgn->mStart + lrgn->mUsed; - lrgn->mUsed += lobj->mSize; + lobj->mAddress = (lrgn->mStart + lrgn->mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1); + lrgn->mUsed = lobj->mAddress + lobj->mSize - lrgn->mStart; + lobj->mRegion = lrgn; if (lsec->mType == LST_DATA) diff --git a/oscar64/Linker.h b/oscar64/Linker.h index 66ecd86..a829a23 100644 --- a/oscar64/Linker.h +++ b/oscar64/Linker.h @@ -93,7 +93,7 @@ public: LinkerObjectType mType; int mID; int mAddress; - int mSize; + int mSize, mAlignment; LinkerSection * mSection; LinkerRegion * mRegion; uint8 * mData; @@ -129,7 +129,7 @@ public: bool IsSectionPlaced(LinkerSection* section); - LinkerObject * AddObject(const Location & location, const Ident* ident, LinkerSection * section, LinkerObjectType type); + LinkerObject * AddObject(const Location & location, const Ident* ident, LinkerSection * section, LinkerObjectType type, int alignment = 1); // void AddReference(const LinkerReference& ref); diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 6e46ab2..510178c 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -822,6 +822,12 @@ void NativeCodeInstruction::Simulate(NativeRegisterDataSet& data) data.mRegs[BC_REG_ADDR + i].Reset(); } data.mRegs[BC_REG_WORK_Y].Reset(); + + if (!(mFlags & NCIF_RUNTIME)) + { + for (int i = BC_REG_TMP; i < BC_REG_TMP_SAVED; i++) + data.mRegs[i].Reset(); + } break; case ASMIT_ROL: @@ -1455,6 +1461,12 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT } data.ResetZeroPage(BC_REG_WORK_Y); + if (!(mFlags & NCIF_RUNTIME)) + { + for (int i = BC_REG_TMP; i < BC_REG_TMP_SAVED; i++) + data.ResetZeroPage(i); + } + return false; } @@ -4972,34 +4984,75 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p if (ins->mSrc[0].mTemp < 0) { int shift = ins->mSrc[0].mIntConst & 31; + + int sreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; + + if (shift >= 24) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); + sreg = treg; + shift -= 24; + } + else if (shift >= 16) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + sreg = treg; + shift -= 16; + } + else if (shift >= 8) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); + sreg = treg; + shift -= 8; + } + if (shift == 0) { - if (ins->mSrc[1].mTemp != ins->mDst.mTemp) + if (sreg != treg) { - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); } } else if (shift == 1) { - if (ins->mSrc[1].mTemp != ins->mDst.mTemp) + if (sreg != treg) { - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); } @@ -5016,15 +5069,15 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p NativeCodeBasicBlock* lblock = nproc->AllocateBlock(); NativeCodeBasicBlock* eblock = nproc->AllocateBlock(); - if (ins->mSrc[1].mTemp != ins->mDst.mTemp) + if (sreg != treg) { - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); } else mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, treg + 3)); @@ -5100,34 +5153,75 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p if (ins->mSrc[0].mTemp < 0) { int shift = ins->mSrc[0].mIntConst & 31; + + int sreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; + + if (shift >= 24) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); + sreg = treg; + shift -= 24; + } + else if (shift >= 16) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); + sreg = treg; + shift -= 16; + } + else if (shift >= 8) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); + + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); + sreg = treg; + shift -= 8; + } + if (shift == 0) { - if (ins->mSrc[1].mTemp != ins->mDst.mTemp) + if (sreg != treg) { - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); } } else if (shift == 1) { - if (ins->mSrc[1].mTemp != ins->mDst.mTemp) + if (sreg != treg) { - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); mIns.Push(NativeCodeInstruction(ASMIT_LSR, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 0)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 0)); mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0)); } @@ -5144,15 +5238,15 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p NativeCodeBasicBlock* lblock = nproc->AllocateBlock(); NativeCodeBasicBlock* eblock = nproc->AllocateBlock(); - if (ins->mSrc[1].mTemp != ins->mDst.mTemp) + if (sreg != treg) { - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); } else mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, treg + 3)); @@ -5228,35 +5322,84 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p if (ins->mSrc[0].mTemp < 0) { int shift = ins->mSrc[0].mIntConst & 31; + + int sreg = BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp]; + + if (shift >= 24) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); + mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0x00)); + mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); + sreg = treg; + shift -= 24; + } + else if (shift >= 16) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0x00)); + mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); + sreg = treg; + shift -= 16; + } + else if (shift >= 8) + { + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0x00)); + mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 0xff)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); + sreg = treg; + shift -= 8; + } + if (shift == 0) { - if (ins->mSrc[1].mTemp != ins->mDst.mTemp) + if (sreg != treg) { - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); } } else if (shift == 1) { - if (ins->mSrc[1].mTemp != ins->mDst.mTemp) + if (sreg != treg) { - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); mIns.Push(NativeCodeInstruction(ASMIT_CMP, ASMIM_IMMEDIATE, 0x80)); mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 0)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 0)); mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0)); } @@ -5275,15 +5418,15 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p NativeCodeBasicBlock* lblock = nproc->AllocateBlock(); NativeCodeBasicBlock* eblock = nproc->AllocateBlock(); - if (ins->mSrc[1].mTemp != ins->mDst.mTemp) + if (sreg != treg) { - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp])); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 1)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 2)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[1].mTemp] + 3)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 3)); } else mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, treg + 3)); @@ -8087,6 +8230,34 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(void) } } + if (mTrueJump && mFalseJump && !mTrueJump->mFalseJump && !mFalseJump->mFalseJump) + { + if (mTrueJump->mIns.Size() > mFalseJump->mIns.Size()) + { + int i = 0, offset = mTrueJump->mIns.Size() - mFalseJump->mIns.Size(); + while (i < mFalseJump->mIns.Size() && mFalseJump->mIns[i].IsSame(mTrueJump->mIns[i + offset])) + i++; + if (i == mFalseJump->mIns.Size()) + { + mTrueJump->mTrueJump = mFalseJump; + mTrueJump->mIns.SetSize(offset); + changed = true; + } + } + else + { + int i = 0, offset = mFalseJump->mIns.Size() - mTrueJump->mIns.Size(); + while (i < mTrueJump->mIns.Size() && mTrueJump->mIns[i].IsSame(mFalseJump->mIns[i + offset])) + i++; + if (i == mTrueJump->mIns.Size()) + { + mFalseJump->mTrueJump = mTrueJump; + mFalseJump->mIns.SetSize(offset); + changed = true; + } + } + } + if (mTrueJump && mTrueJump->JoinTailCodeSequences()) changed = true; if (mFalseJump && mFalseJump->JoinTailCodeSequences()) @@ -8096,6 +8267,28 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(void) return changed; } +bool NativeCodeBasicBlock::FindPageStartAddress(int at, int reg, int& addr) +{ + int j = at - 2; + while (j >= 0) + { + if (mIns[j + 0].mType == ASMIT_LDA && mIns[j + 0].mMode == ASMIM_IMMEDIATE && + mIns[j + 1].mType == ASMIT_STA && mIns[j + 1].mMode == ASMIM_ZERO_PAGE && mIns[j + 1].mAddress == reg + 1) + { + addr = mIns[j + 0].mAddress << 8; + return true; + } + if (mIns[j + 1].mMode == ASMIM_ZERO_PAGE && (mIns[j + 1].mAddress == reg || mIns[j + 1].mAddress == reg + 1) && mIns[j + 1].ChangesAddress()) + return false; + + j--; + } + + if (mFromJump) + return mFromJump->FindPageStartAddress(mFromJump->mIns.Size(), reg, addr); + else + return false; +} bool NativeCodeBasicBlock::FindGlobalAddress(int at, int reg, int& apos) { @@ -8727,6 +8920,9 @@ bool NativeCodeBasicBlock::MoveLoadAddImmStoreUp(int at) { if (mIns[j].mType == ASMIT_STA && mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at + 1].mAddress) { + if (mIns[j].mLive & LIVE_CPU_REG_A) + return false; + mIns.Insert(j + 1, mIns[at + 3]); // STA mIns.Insert(j + 1, mIns[at + 3]); // ADC mIns.Insert(j + 1, mIns[at + 2]); // CLC @@ -9964,6 +10160,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) } #endif + #if 1 // move load - store (),y up to initial store // @@ -9992,6 +10189,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) } #endif + #if 1 // move load - add # - store up to initial store // @@ -10010,6 +10208,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) } #endif + #if 1 // move load - add ZP - store up to initial store // @@ -10168,6 +10367,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) } } #endif + bool progress = false; do { progress = false; @@ -10274,6 +10474,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) progress = true; } #endif + #if 1 if (mIns[i + 0].mMode == ASMIM_INDIRECT_Y && (mIns[i + 0].mFlags & NCIF_YZERO)) { @@ -10752,6 +10953,31 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) } } #endif +#if 1 + if (mIns[i + 0].mType == ASMIT_LDY && mIns[i + 0].mMode == ASMIM_IMMEDIATE && + mIns[i + 1].mMode == ASMIM_INDIRECT_Y) + { + int addr; + if (FindPageStartAddress(i, mIns[i + 1].mAddress, addr)) + { + if (mIns[i + 1].mLive & LIVE_CPU_REG_Y) + mIns.Insert(i + 2, mIns[i + 0]); + + int absaddr = addr + mIns[i + 0].mAddress; + + mIns[i + 0].mMode = ASMIM_ZERO_PAGE; + mIns[i + 0].mAddress = mIns[i + 1].mAddress; + + mIns[i + 1].mMode = ASMIM_ABSOLUTE_Y; + mIns[i + 1].mAddress = absaddr; + mIns[i + 1].mLinkerObject = nullptr; + + progress = true; + } + } +#endif + + #if 1 if ( mIns[i + 0].mMode == ASMIM_INDIRECT_Y && (mIns[i + 0].mFlags & NCIF_YZERO) && @@ -11452,6 +11678,21 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) progress = true; } #endif + else if ( + mIns[i + 0].mType == ASMIT_LDA && mIns[i + 0].mMode == ASMIM_ZERO_PAGE && + mIns[i + 1].IsShift() && mIns[i + 1].mMode == ASMIM_IMPLIED && + mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && mIns[i + 2].mAddress == mIns[i + 0].mAddress && + mIns[i + 3].mType == ASMIT_ORA && mIns[i + 3].mMode == ASMIM_IMMEDIATE && mIns[i + 3].mAddress == 0x00 && !(mIns[i + 3].mLive & LIVE_CPU_REG_A)) + { + mIns[i + 0].mType = mIns[i + 1].mType; + mIns[i + 0].mLive |= LIVE_MEM | LIVE_CPU_REG_C | LIVE_CPU_REG_Z; + + mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; + mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED; + mIns[i + 3].mType = ASMIT_NOP; mIns[i + 3].mMode = ASMIM_IMPLIED; + + progress = true; + } #if 1 if ( @@ -11560,6 +11801,38 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass) } #endif +#if 1 + if (i + 7 < mIns.Size()) + { + if ( + mIns[i + 0].mType == ASMIT_CLC && + mIns[i + 1].mType == ASMIT_ADC && mIns[i + 1].mMode == ASMIM_ZERO_PAGE && + mIns[i + 2].mType == ASMIT_STA && mIns[i + 2].mMode == ASMIM_ZERO_PAGE && + mIns[i + 3].mType == ASMIT_LDA && mIns[i + 3].mMode == ASMIM_ZERO_PAGE && mIns[i + 3].mAddress == mIns[i + 1].mAddress + 1 && + mIns[i + 4].mType == ASMIT_ADC && mIns[i + 4].mMode == ASMIM_IMMEDIATE && mIns[i + 4].mAddress == 0 && + mIns[i + 5].mType == ASMIT_STA && mIns[i + 5].mMode == ASMIM_ZERO_PAGE && mIns[i + 5].mAddress == mIns[i + 2].mAddress + 1 && + + mIns[i + 6].mType == ASMIT_LDY && mIns[i + 6].mMode == ASMIM_IMMEDIATE && mIns[i + 6].mAddress == 0 && + mIns[i + 7].mMode == ASMIM_INDIRECT_Y && mIns[i + 7].mAddress == mIns[i + 2].mAddress && !(mIns[i + 7].mLive & LIVE_MEM)) + { + for (int j = 0; j < 6; j++) + { + mIns[i + j].mType = ASMIT_NOP; mIns[i + j].mMode = ASMIM_IMPLIED; + } + + if (mIns[i + 7].mLive & LIVE_CPU_REG_Y) + { + mIns.Insert(i + 8, NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); + mIns[i + 8].mLive |= LIVE_CPU_REG_Y; + } + + mIns[i + 6].mType = ASMIT_TAY; + mIns[i + 6].mMode = ASMIM_IMPLIED; + mIns[i + 7].mAddress = mIns[i + 1].mAddress; + progress = true; + } + } +#endif #if 1 if (i + 9 < mIns.Size()) { @@ -12051,8 +12324,6 @@ NativeCodeProcedure::~NativeCodeProcedure(void) void NativeCodeProcedure::CompressTemporaries(void) { -// return; - if (mInterProc->mTempSize > 16) { ResetVisited(); @@ -12516,12 +12787,13 @@ void NativeCodeProcedure::Optimize(void) mBlocks[i]->mEntryBlocks.SetSize(0); mEntryBlock->CollectEntryBlocks(nullptr); +#if 1 if (step == 2) { if (MapFastParamsToTemps()) changed = true; } - +#endif if (step > 2) { ResetVisited(); @@ -12919,19 +13191,25 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode { block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins->mSrc[0].mIntConst & 0xff)); block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0)); - block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); - block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1)); - mExitBlock->mIns[0].mFlags |= NCIF_LOWER | NCIF_UPPER; + mExitBlock->mIns[0].mFlags |= NCIF_LOWER; - if (ins->mSrc[0].mType == IT_INT32) + if (InterTypeSize[ins->mSrc[0].mType] > 1) { - block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 16) & 0xff)); - block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2)); - block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 24) & 0xff)); - block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3)); + block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff)); + block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1)); - mExitBlock->mIns[0].mFlags |= NCIF_LONG; + mExitBlock->mIns[0].mFlags |= NCIF_UPPER; + + if (InterTypeSize[ins->mSrc[0].mType] > 2) + { + block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 16) & 0xff)); + block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2)); + block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 24) & 0xff)); + block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3)); + + mExitBlock->mIns[0].mFlags |= NCIF_LONG; + } } } } @@ -12939,19 +13217,25 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode { block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp])); block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU)); - block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp] + 1)); - block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1)); - mExitBlock->mIns[0].mFlags |= NCIF_LOWER | NCIF_UPPER; + mExitBlock->mIns[0].mFlags |= NCIF_LOWER; - if (ins->mSrc[0].mType == IT_FLOAT || ins->mSrc[0].mType == IT_INT32) + if (InterTypeSize[ins->mSrc[0].mType] > 1) { - block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp] + 2)); - block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2)); - block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp] + 3)); - block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3)); + block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp] + 1)); + block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1)); - mExitBlock->mIns[0].mFlags |= NCIF_LONG; + mExitBlock->mIns[0].mFlags |= NCIF_UPPER; + + if (InterTypeSize[ins->mSrc[0].mType] > 2) + { + block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp] + 2)); + block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2)); + block->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + iproc->mTempOffset[ins->mSrc[0].mTemp] + 3)); + block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3)); + + mExitBlock->mIns[0].mFlags |= NCIF_LONG; + } } } diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index ecbcee6..c1b0277 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -193,6 +193,7 @@ public: bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg); bool FindGlobalAddress(int at, int reg, int& apos); bool FindGlobalAddressSumY(int at, int reg, bool direct, int& apos, const NativeCodeInstruction * & ains, const NativeCodeInstruction*& iins, uint32 & flags); + bool FindPageStartAddress(int at, int reg, int& addr); bool MoveStoreXUp(int at); bool MoveStoreHighByteDown(int at); bool MoveAddHighByteDown(int at); diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 9bf64f0..5fe2f35 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -563,6 +563,18 @@ Declaration * Parser::CopyConstantInitializer(int offset, Declaration* dtype, Ex dec->mOffset = offset; } } + else if (dtype->mType == DT_TYPE_POINTER && dec->mType == DT_VARIABLE && dec->mBase->mType == DT_TYPE_ARRAY && (dec->mFlags & DTF_STATIC)) + { + if (dtype->CanAssign(exp->mDecType)) + { + Declaration * ndec = new Declaration(dec->mLocation, DT_CONST_POINTER); + ndec->mValue = exp; + ndec->mBase = dtype; + dec = ndec; + } + else + mErrors->Error(exp->mLocation, EERR_CONSTANT_INITIALIZER, "Incompatible constant initializer"); + } else mErrors->Error(exp->mLocation, EERR_CONSTANT_INITIALIZER, "Constant initializer expected"); @@ -3106,6 +3118,36 @@ void Parser::ParsePragma(void) ConsumeToken(TK_CLOSE_PARENTHESIS); } + else if (!strcmp(mScanner->mTokenIdent->mString, "align")) + { + mScanner->NextToken(); + ConsumeToken(TK_OPEN_PARENTHESIS); + + if (mScanner->mToken == TK_IDENT) + { + Declaration* dec = mGlobals->Lookup(mScanner->mTokenIdent); + if (dec && dec->mType == DT_VARIABLE && (dec->mFlags & DTF_STATIC)) + { + mScanner->NextToken(); + ConsumeToken(TK_COMMA); + + Expression * exp = ParseRExpression(); + if (exp->mType == EX_CONSTANT && exp->mDecValue->mType == DT_CONST_INTEGER) + dec->mAlignment = exp->mDecValue->mInteger; + else + mErrors->Error(mScanner->mLocation, EERR_PRAGMA_PARAMETER, "Integer number for alignment expected"); + } + else + { + mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Variable not found"); + mScanner->NextToken(); + } + } + else + mErrors->Error(mScanner->mLocation, EERR_PRAGMA_PARAMETER, "Variable name expected"); + + ConsumeToken(TK_CLOSE_PARENTHESIS); + } else { mScanner->NextToken();