Optimize 32bit shifts

This commit is contained in:
drmortalwombat 2021-12-18 22:21:39 +01:00
parent 178a5e23a8
commit 6d716b9478
15 changed files with 659 additions and 159 deletions

94
include/c64/asm6502.c Normal file
View File

@ -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;
}

View File

@ -82,98 +82,33 @@ enum AsmIns
ASM_JSR = 0x2c ASM_JSR = 0x2c
}; };
inline byte asm_np(byte * ip, AsmIns ins) inline byte asm_np(byte * ip, AsmIns ins);
{
ip[0] = ins & 0xff;
return 1;
}
inline byte asm_ac(byte * ip, AsmIns ins) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) inline byte asm_iy(byte * ip, AsmIns ins, byte addr);
{
ip[0] = (ins & 0xff) | 0x10; #pragma compile("asm6502.c")
ip[1] = addr;
return 2;
}
#endif #endif

61
include/c64/memmap.c Normal file
View File

@ -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
tsx
lda $0105, x
pha
jmp ($fffa)
}
__asm NMITrampoline
{
pha
txa
pha
lda #$36
sta $01
lda #>DoneTrampoline
pha
lda #<DoneTrampoline
pha
tsx
lda $0105, x
pha
jmp ($fffe)
}
void mmap_trampoline(void)
{
*((void **)0xfffa) = IRQTrampoline;
*((void **)0xfffe) = NMITrampoline;
}
void mmap_set(char pla)
{
PLAShadow = pla;
*((char *)0x01) = pla;
}

25
include/c64/memmap.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef MEMMAP_H
#define MEMMAP_H
#include "types.h"
#define MMAP_ROM 0x37
#define MMAP_NO_BASIC 0x36
#define MMAP_NO_ROM 0x35
#define MMAP_RAM 0x30
// Install an IRQ an NMI trampoline, that routes the kernal interrupts
// through an intermediate trampoline when the kernal ROM is not paged
// in. The trampoline enables the ROM, executes the interrupt and
// restores the memory map setting before returning.
void mmap_trampoline(void);
// Set the memory map in a way that is compatible with the IRQ
// trampoline
inline void mmap_set(char pla);
#pragma compile("memmap.c")
#endif

View File

@ -15,3 +15,33 @@ void vic_sprxy(byte s, int x, int y)
else else
vic.spr_msbx &= ~(1 << s); vic.spr_msbx &= ~(1 << s);
} }
void vic_setmode(VicMode mode, char * text, char * font)
{
switch (mode)
{
case VICM_TEXT:
vic.ctrl1 = VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3;
vic.ctrl2 = VIC_CTRL2_CSEL;
break;
case VICM_TEXT_MC:
vic.ctrl1 = VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3;
vic.ctrl2 = VIC_CTRL2_CSEL | VIC_CTRL2_MCM;
break;
case VICM_TEXT_ECM:
vic.ctrl1 = VIC_CTRL1_DEN | VIC_CTRL1_ECM | VIC_CTRL1_RSEL | 3;
vic.ctrl2 = VIC_CTRL2_CSEL;
break;
case VICM_HIRES:
vic.ctrl1 = VIC_CTRL1_BMM | VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3;
vic.ctrl2 = VIC_CTRL2_CSEL;
break;
case VICM_HIRES_MC:
vic.ctrl1 = VIC_CTRL1_BMM | VIC_CTRL1_DEN | VIC_CTRL1_RSEL | 3;
vic.ctrl2 = VIC_CTRL2_CSEL | VIC_CTRL2_MCM;
break;
}
cia2.pra = (cia2.pra & 0xfc) | (((unsigned)text >> 14) ^ 0x03);
vic.memptr = (((unsigned)text >> 6) & 0xf0) | (((unsigned)font >> 10) & 0x0e);
}

View File

@ -75,6 +75,17 @@ struct VIC
void vic_setbank(char bank); 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); inline void vic_sprxy(byte s, int x, int y);

View File

@ -368,7 +368,7 @@ Expression* Expression::ConstantFold(Errors * errors)
} }
Declaration::Declaration(const Location& loc, DecType type) 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) Declaration::~Declaration(void)

View File

@ -167,7 +167,7 @@ public:
Declaration* mBase, *mParams, * mNext; Declaration* mBase, *mParams, * mNext;
Expression* mValue; Expression* mValue;
DeclarationScope* mScope; DeclarationScope* mScope;
int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize; int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize, mAlignment;
int64 mInteger; int64 mInteger;
double mNumber; double mNumber;
uint32 mFlags; uint32 mFlags;

View File

@ -59,7 +59,7 @@ void GlobalAnalyzer::AutoInline(void)
for (int i = 0; i < mFunctions.Size(); i++) for (int i = 0; i < mFunctions.Size(); i++)
{ {
Declaration* f = mFunctions[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; int nparams = 0;
Declaration* dec = f->mBase->mParams; Declaration* dec = f->mBase->mParams;

View File

@ -214,7 +214,7 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration*
InterVariable * var = new InterVariable(); InterVariable * var = new InterVariable();
var->mOffset = 0; var->mOffset = 0;
var->mSize = dec->mSize; 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; var->mIdent = dec->mIdent;
Declaration* type = dec->mBase; Declaration* type = dec->mBase;
@ -830,7 +830,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
var->mSize = dec->mSize; var->mSize = dec->mSize;
if ((dec->mFlags & DTF_VAR_ALIASING) || dec->mBase->mType == DT_TYPE_ARRAY) if ((dec->mFlags & DTF_VAR_ALIASING) || dec->mBase->mType == DT_TYPE_ARRAY)
var->mAliased = true; 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; dec->mLinkerObject = var->mLinkerObject;
var->mLinkerObject->AddData(dec->mData, dec->mSize); var->mLinkerObject->AddData(dec->mData, dec->mSize);
proc->mModule->mGlobalVars.Push(var); proc->mModule->mGlobalVars.Push(var);
@ -855,7 +855,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
InterVariable * var = new InterVariable(); InterVariable * var = new InterVariable();
var->mOffset = 0; var->mOffset = 0;
var->mSize = dec->mSize; 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; dec->mLinkerObject = var->mLinkerObject;
var->mIdent = dec->mIdent; var->mIdent = dec->mIdent;
dec->mVarIndex = proc->mModule->mGlobalVars.Size(); dec->mVarIndex = proc->mModule->mGlobalVars.Size();
@ -3222,7 +3222,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
var->mIndex = dec->mVarIndex; var->mIndex = dec->mVarIndex;
var->mOffset = 0; var->mOffset = 0;
var->mSize = dec->mSize; 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; dec->mLinkerObject = var->mLinkerObject;
var->mLinkerObject->AddData(dec->mData, dec->mSize); var->mLinkerObject->AddData(dec->mData, dec->mSize);
mod->mGlobalVars.Push(var); mod->mGlobalVars.Push(var);
@ -3233,6 +3233,21 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
variable->mLinkerObject->AddReference(ref); variable->mLinkerObject->AddReference(ref);
break; 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;
} }
} }
} }

View File

@ -12,7 +12,7 @@ LinkerSection::LinkerSection(void)
{} {}
LinkerObject::LinkerObject(void) LinkerObject::LinkerObject(void)
: mReferences(nullptr), mNumTemporaries(0) : mReferences(nullptr), mNumTemporaries(0), mSize(0), mAlignment(1)
{} {}
LinkerObject::~LinkerObject(void) LinkerObject::~LinkerObject(void)
@ -133,7 +133,7 @@ LinkerObject* Linker::FindObjectByAddr(int addr)
return nullptr; 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; LinkerObject* obj = new LinkerObject;
obj->mLocation = location; obj->mLocation = location;
@ -146,6 +146,7 @@ LinkerObject * Linker::AddObject(const Location& location, const Ident* ident, L
obj->mRegion = nullptr; obj->mRegion = nullptr;
obj->mProc = nullptr; obj->mProc = nullptr;
obj->mFlags = 0; obj->mFlags = 0;
obj->mAlignment = alignment;
section->mObjects.Push(obj); section->mObjects.Push(obj);
mObjects.Push(obj); mObjects.Push(obj);
return 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) if ((lobj->mFlags & LOBJF_REFERENCED) && !(lobj->mFlags & LOBJF_PLACED) && lrgn->mStart + lrgn->mUsed + lobj->mSize <= lrgn->mEnd)
{ {
lobj->mFlags |= LOBJF_PLACED; lobj->mFlags |= LOBJF_PLACED;
lobj->mAddress = lrgn->mStart + lrgn->mUsed; lobj->mAddress = (lrgn->mStart + lrgn->mUsed + lobj->mAlignment - 1) & ~(lobj->mAlignment - 1);
lrgn->mUsed += lobj->mSize; lrgn->mUsed = lobj->mAddress + lobj->mSize - lrgn->mStart;
lobj->mRegion = lrgn; lobj->mRegion = lrgn;
if (lsec->mType == LST_DATA) if (lsec->mType == LST_DATA)

View File

@ -93,7 +93,7 @@ public:
LinkerObjectType mType; LinkerObjectType mType;
int mID; int mID;
int mAddress; int mAddress;
int mSize; int mSize, mAlignment;
LinkerSection * mSection; LinkerSection * mSection;
LinkerRegion * mRegion; LinkerRegion * mRegion;
uint8 * mData; uint8 * mData;
@ -129,7 +129,7 @@ public:
bool IsSectionPlaced(LinkerSection* section); 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); // void AddReference(const LinkerReference& ref);

View File

@ -822,6 +822,12 @@ void NativeCodeInstruction::Simulate(NativeRegisterDataSet& data)
data.mRegs[BC_REG_ADDR + i].Reset(); data.mRegs[BC_REG_ADDR + i].Reset();
} }
data.mRegs[BC_REG_WORK_Y].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; break;
case ASMIT_ROL: case ASMIT_ROL:
@ -1455,6 +1461,12 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data, AsmInsT
} }
data.ResetZeroPage(BC_REG_WORK_Y); 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; return false;
} }
@ -4972,34 +4984,75 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
if (ins->mSrc[0].mTemp < 0) if (ins->mSrc[0].mTemp < 0)
{ {
int shift = ins->mSrc[0].mIntConst & 31; 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 (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_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_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_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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3));
} }
} }
else if (shift == 1) 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_ASL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg)); 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_ROL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 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_ROL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 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_ROL, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3));
} }
@ -5016,15 +5069,15 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
NativeCodeBasicBlock* lblock = nproc->AllocateBlock(); NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
NativeCodeBasicBlock* eblock = 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_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_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_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 else
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, treg + 3)); 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) if (ins->mSrc[0].mTemp < 0)
{ {
int shift = ins->mSrc[0].mIntConst & 31; 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 (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_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_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_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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3));
} }
} }
else if (shift == 1) 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_LSR, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); 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_ROR, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 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] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 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] + 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 0));
mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
} }
@ -5144,15 +5238,15 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
NativeCodeBasicBlock* lblock = nproc->AllocateBlock(); NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
NativeCodeBasicBlock* eblock = 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_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_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_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 else
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, treg + 3)); 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) if (ins->mSrc[0].mTemp < 0)
{ {
int shift = ins->mSrc[0].mIntConst & 31; 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 (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_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_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_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)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3));
} }
} }
else if (shift == 1) 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_CMP, ASMIM_IMMEDIATE, 0x80));
mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 3)); 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_ROR, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 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] + 1)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 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] + 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, sreg + 0));
mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED)); mIns.Push(NativeCodeInstruction(ASMIT_ROR, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0)); mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, treg + 0));
} }
@ -5275,15 +5418,15 @@ NativeCodeBasicBlock* NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* p
NativeCodeBasicBlock* lblock = nproc->AllocateBlock(); NativeCodeBasicBlock* lblock = nproc->AllocateBlock();
NativeCodeBasicBlock* eblock = 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_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_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_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 else
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, treg + 3)); 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()) if (mTrueJump && mTrueJump->JoinTailCodeSequences())
changed = true; changed = true;
if (mFalseJump && mFalseJump->JoinTailCodeSequences()) if (mFalseJump && mFalseJump->JoinTailCodeSequences())
@ -8096,6 +8267,28 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(void)
return changed; 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) 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].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]); // STA
mIns.Insert(j + 1, mIns[at + 3]); // ADC mIns.Insert(j + 1, mIns[at + 3]); // ADC
mIns.Insert(j + 1, mIns[at + 2]); // CLC mIns.Insert(j + 1, mIns[at + 2]); // CLC
@ -9964,6 +10160,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
} }
#endif #endif
#if 1 #if 1
// move load - store (),y up to initial store // move load - store (),y up to initial store
// //
@ -9992,6 +10189,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
} }
#endif #endif
#if 1 #if 1
// move load - add # - store up to initial store // move load - add # - store up to initial store
// //
@ -10010,6 +10208,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
} }
#endif #endif
#if 1 #if 1
// move load - add ZP - store up to initial store // move load - add ZP - store up to initial store
// //
@ -10168,6 +10367,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
} }
} }
#endif #endif
bool progress = false; bool progress = false;
do { do {
progress = false; progress = false;
@ -10274,6 +10474,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
progress = true; progress = true;
} }
#endif #endif
#if 1 #if 1
if (mIns[i + 0].mMode == ASMIM_INDIRECT_Y && (mIns[i + 0].mFlags & NCIF_YZERO)) if (mIns[i + 0].mMode == ASMIM_INDIRECT_Y && (mIns[i + 0].mFlags & NCIF_YZERO))
{ {
@ -10752,6 +10953,31 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
} }
} }
#endif #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 1
if ( if (
mIns[i + 0].mMode == ASMIM_INDIRECT_Y && (mIns[i + 0].mFlags & NCIF_YZERO) && mIns[i + 0].mMode == ASMIM_INDIRECT_Y && (mIns[i + 0].mFlags & NCIF_YZERO) &&
@ -11452,6 +11678,21 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
progress = true; progress = true;
} }
#endif #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 1
if ( if (
@ -11560,6 +11801,38 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(int pass)
} }
#endif #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 1
if (i + 9 < mIns.Size()) if (i + 9 < mIns.Size())
{ {
@ -12051,8 +12324,6 @@ NativeCodeProcedure::~NativeCodeProcedure(void)
void NativeCodeProcedure::CompressTemporaries(void) void NativeCodeProcedure::CompressTemporaries(void)
{ {
// return;
if (mInterProc->mTempSize > 16) if (mInterProc->mTempSize > 16)
{ {
ResetVisited(); ResetVisited();
@ -12516,12 +12787,13 @@ void NativeCodeProcedure::Optimize(void)
mBlocks[i]->mEntryBlocks.SetSize(0); mBlocks[i]->mEntryBlocks.SetSize(0);
mEntryBlock->CollectEntryBlocks(nullptr); mEntryBlock->CollectEntryBlocks(nullptr);
#if 1
if (step == 2) if (step == 2)
{ {
if (MapFastParamsToTemps()) if (MapFastParamsToTemps())
changed = true; changed = true;
} }
#endif
if (step > 2) if (step > 2)
{ {
ResetVisited(); 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_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_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_LDA, ASMIM_IMMEDIATE, (ins->mSrc[0].mIntConst >> 8) & 0xff));
block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2)); block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
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; 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_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_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_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 + 2)); block->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
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; 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;
}
} }
} }

View File

@ -193,6 +193,7 @@ public:
bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg); bool FindAddressSumY(int at, int reg, int & apos, int& breg, int& ireg);
bool FindGlobalAddress(int at, int reg, int& apos); 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 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 MoveStoreXUp(int at);
bool MoveStoreHighByteDown(int at); bool MoveStoreHighByteDown(int at);
bool MoveAddHighByteDown(int at); bool MoveAddHighByteDown(int at);

View File

@ -563,6 +563,18 @@ Declaration * Parser::CopyConstantInitializer(int offset, Declaration* dtype, Ex
dec->mOffset = offset; 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 else
mErrors->Error(exp->mLocation, EERR_CONSTANT_INITIALIZER, "Constant initializer expected"); mErrors->Error(exp->mLocation, EERR_CONSTANT_INITIALIZER, "Constant initializer expected");
@ -3106,6 +3118,36 @@ void Parser::ParsePragma(void)
ConsumeToken(TK_CLOSE_PARENTHESIS); 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 else
{ {
mScanner->NextToken(); mScanner->NextToken();