Add experimental zero page allocation for global variables

This commit is contained in:
drmortalwombat 2022-04-06 19:16:44 +02:00
parent 27dee0223c
commit 72264109e9
14 changed files with 241 additions and 91 deletions

View File

@ -185,6 +185,12 @@ Or alternatively with a __native storage class specifier
(*Bitmap)[y >> 3][x >> 3][y & 7] |= 0x80 >> (x & 7); (*Bitmap)[y >> 3][x >> 3][y & 7] |= 0x80 >> (x & 7);
} }
### Usage of zero page
The compiler uses basic zero page space for temporaries, local variables and function arguments. Global and static variables are allocated in the data and bss segment in normal memory. The __zeropage storage class specifier can be applied to global variables and will be allocated in the zero page segment (usually 0x80 to 0xff). This is only useful when the kernal is not used. Zero page allocated global variables are not initialized.
__zeropage int a;
### Pre-Processor control ### Pre-Processor control
The pre processor has additional commands to control the scanner and allow for dynamic code generation including loops. The pre processor has additional commands to control the scanner and allow for dynamic code generation including loops.

View File

@ -28,7 +28,7 @@ public:
DeclarationScope* mRuntimeScope; DeclarationScope* mRuntimeScope;
LinkerSection* mSectionCode, * mSectionData, * mSectionBSS, * mSectionHeap, * mSectionStack; LinkerSection* mSectionCode, * mSectionData, * mSectionBSS, * mSectionHeap, * mSectionStack, * mSectionZeroPage;
Linker* mLinker; Linker* mLinker;
bool AddUnit(Location & location, const char* name, const char * from); bool AddUnit(Location & location, const char* name, const char * from);

View File

@ -21,6 +21,7 @@ Compiler::Compiler(void)
mCompilationUnits->mSectionBSS = mLinker->AddSection(Ident::Unique("bss"), LST_BSS); mCompilationUnits->mSectionBSS = mLinker->AddSection(Ident::Unique("bss"), LST_BSS);
mCompilationUnits->mSectionHeap = mLinker->AddSection(Ident::Unique("heap"), LST_HEAP); mCompilationUnits->mSectionHeap = mLinker->AddSection(Ident::Unique("heap"), LST_HEAP);
mCompilationUnits->mSectionStack = mLinker->AddSection(Ident::Unique("stack"), LST_STACK); mCompilationUnits->mSectionStack = mLinker->AddSection(Ident::Unique("stack"), LST_STACK);
mCompilationUnits->mSectionZeroPage = mLinker->AddSection(Ident::Unique("zeropage"), LST_ZEROPAGE);
mCompilationUnits->mSectionStack->mSize = 4096; mCompilationUnits->mSectionStack->mSize = 4096;
mPreprocessor = new Preprocessor(mErrors); mPreprocessor = new Preprocessor(mErrors);
@ -150,6 +151,13 @@ bool Compiler::GenerateCode(void)
const Ident* identBytecode = Ident::Unique("bytecode"); const Ident* identBytecode = Ident::Unique("bytecode");
const Ident* identMain = Ident::Unique("main"); const Ident* identMain = Ident::Unique("main");
const Ident* identCode = Ident::Unique("code"); const Ident* identCode = Ident::Unique("code");
const Ident* identZeroPage = Ident::Unique("zeropage");
LinkerRegion* regionZeroPage = mLinker->FindRegion(identZeroPage);
if (!regionZeroPage)
{
regionZeroPage = mLinker->AddRegion(identZeroPage, 0x0080, 0x00ff);
}
LinkerRegion* regionStartup = mLinker->FindRegion(identStartup); LinkerRegion* regionStartup = mLinker->FindRegion(identStartup);
if (!regionStartup) if (!regionStartup)
@ -179,6 +187,8 @@ bool Compiler::GenerateCode(void)
regionStartup->mSections.Push(sectionStartup); regionStartup->mSections.Push(sectionStartup);
regionZeroPage->mSections.Push(mCompilationUnits->mSectionZeroPage);
if (regionBytecode) if (regionBytecode)
regionBytecode->mSections.Push(sectionBytecode); regionBytecode->mSections.Push(sectionBytecode);

View File

@ -71,6 +71,7 @@ static const uint64 DTF_INTERRUPT = (1ULL << 18);
static const uint64 DTF_EXPORT = (1ULL << 19); static const uint64 DTF_EXPORT = (1ULL << 19);
static const uint64 DTF_HWINTERRUPT = (1ULL << 20); static const uint64 DTF_HWINTERRUPT = (1ULL << 20);
static const uint64 DTF_STACKCALL = (1ULL << 21); static const uint64 DTF_STACKCALL = (1ULL << 21);
static const uint64 DTF_ZEROPAGE = (1ULL << 22);
static const uint64 DTF_FUNC_VARIABLE = (1ULL << 32); static const uint64 DTF_FUNC_VARIABLE = (1ULL << 32);
static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 33); static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 33);

View File

@ -14,7 +14,7 @@ ByteCodeDisassembler::~ByteCodeDisassembler(void)
} }
const char* ByteCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc) const char* ByteCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc, Linker* linker)
{ {
if (tmp == BC_REG_ADDR) if (tmp == BC_REG_ADDR)
return "ADDR"; return "ADDR";
@ -36,6 +36,15 @@ const char* ByteCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodePro
sprintf_s(buffer, 10, "$%02x", tmp); sprintf_s(buffer, 10, "$%02x", tmp);
return buffer; return buffer;
} }
else if (linker)
{
LinkerObject* obj = linker->FindObjectByAddr(tmp);
if (obj && obj->mIdent)
sprintf_s(buffer, 40, "$%02x; %s + %d", tmp, obj->mIdent->mString, tmp - obj->mAddress);
else
sprintf_s(buffer, 10, "$%02x", tmp);
return buffer;
}
else else
{ {
sprintf_s(buffer, 10, "$%02x", tmp); sprintf_s(buffer, 10, "$%02x", tmp);
@ -67,7 +76,7 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank
else if (ident) else if (ident)
fprintf(file, "%s:\n", ident->mString); fprintf(file, "%s:\n", ident->mString);
char tbuffer[10], abuffer[100]; char tbuffer[100], abuffer[100];
#if 0 #if 0
for (int i = 0; i < proc->mTemporaries.Size(); i++) for (int i = 0; i < proc->mTemporaries.Size(); i++)
printf("T%d = $%.2x\n", i, BC_REG_TMP + proc->mTempOffset[i]); printf("T%d = $%.2x\n", i, BC_REG_TMP + proc->mTempOffset[i]);
@ -93,69 +102,69 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank
break; break;
case BC_CONST_8: case BC_CONST_8:
fprintf(file, "MOVB\t%s, #%d", TempName(memory[start + i], tbuffer, proc), memory[start + i + 1]); fprintf(file, "MOVB\t%s, #%d", TempName(memory[start + i], tbuffer, proc, linker), memory[start + i + 1]);
i += 2; i += 2;
break; break;
case BC_CONST_P8: case BC_CONST_P8:
fprintf(file, "MOV\t%s, #%d", TempName(memory[start + i], tbuffer, proc), memory[start + i + 1]); fprintf(file, "MOV\t%s, #%d", TempName(memory[start + i], tbuffer, proc, linker), memory[start + i + 1]);
i += 2; i += 2;
break; break;
case BC_CONST_N8: case BC_CONST_N8:
fprintf(file, "MOV\t%s, #%d", TempName(memory[start + i], tbuffer, proc), int(memory[start + i + 1]) - 0x100); fprintf(file, "MOV\t%s, #%d", TempName(memory[start + i], tbuffer, proc, linker), int(memory[start + i + 1]) - 0x100);
i += 2; i += 2;
break; break;
case BC_CONST_16: case BC_CONST_16:
fprintf(file, "MOV\t%s, #$%04x", TempName(memory[start + i], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2])); fprintf(file, "MOV\t%s, #$%04x", TempName(memory[start + i], tbuffer, proc, linker), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3; i += 3;
break; break;
case BC_CONST_32: case BC_CONST_32:
fprintf(file, "MOVD\t%s, #$%08x", TempName(memory[start + i], tbuffer, proc), uint32(memory[start + i + 1] + 256 * memory[start + i + 2] + 0x10000 * memory[start + i + 3] + 0x1000000 * memory[start + i + 4])); fprintf(file, "MOVD\t%s, #$%08x", TempName(memory[start + i], tbuffer, proc, linker), uint32(memory[start + i + 1] + 256 * memory[start + i + 2] + 0x10000 * memory[start + i + 3] + 0x1000000 * memory[start + i + 4]));
i += 5; i += 5;
break; break;
case BC_LOAD_REG_8: case BC_LOAD_REG_8:
fprintf(file, "MOVB\tACCU, %s", TempName(memory[start + i], tbuffer, proc)); fprintf(file, "MOVB\tACCU, %s", TempName(memory[start + i], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_STORE_REG_8: case BC_STORE_REG_8:
fprintf(file, "MOVB\t%s, ACCU", TempName(memory[start + i], tbuffer, proc)); fprintf(file, "MOVB\t%s, ACCU", TempName(memory[start + i], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_LOAD_REG_16: case BC_LOAD_REG_16:
fprintf(file, "MOV\tACCU, %s", TempName(memory[start + i], tbuffer, proc)); fprintf(file, "MOV\tACCU, %s", TempName(memory[start + i], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_STORE_REG_16: case BC_STORE_REG_16:
fprintf(file, "MOV\t%s, ACCU", TempName(memory[start + i], tbuffer, proc)); fprintf(file, "MOV\t%s, ACCU", TempName(memory[start + i], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_LOAD_REG_32: case BC_LOAD_REG_32:
fprintf(file, "MOVD\tACCU, %s", TempName(memory[start + i], tbuffer, proc)); fprintf(file, "MOVD\tACCU, %s", TempName(memory[start + i], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_STORE_REG_32: case BC_STORE_REG_32:
fprintf(file, "MOVD\t%s, ACCU", TempName(memory[start + i], tbuffer, proc)); fprintf(file, "MOVD\t%s, ACCU", TempName(memory[start + i], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_ADDR_REG: case BC_ADDR_REG:
fprintf(file, "MOV\tADDR, %s", TempName(memory[start + i], tbuffer, proc)); fprintf(file, "MOV\tADDR, %s", TempName(memory[start + i], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_LOAD_ABS_8: case BC_LOAD_ABS_8:
fprintf(file, "MOVB\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker)); fprintf(file, "MOVB\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc, linker), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3; i += 3;
break; break;
case BC_LOAD_ABS_U8: case BC_LOAD_ABS_U8:
fprintf(file, "MOVUB\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker)); fprintf(file, "MOVUB\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc, linker), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3; i += 3;
break; break;
case BC_LOAD_ABS_16: case BC_LOAD_ABS_16:
fprintf(file, "MOV\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker)); fprintf(file, "MOV\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc, linker), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3; i += 3;
break; break;
case BC_LOAD_ABS_32: case BC_LOAD_ABS_32:
fprintf(file, "MOVD\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker)); fprintf(file, "MOVD\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc, linker), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3; i += 3;
break; break;
case BC_LOAD_ABS_ADDR: case BC_LOAD_ABS_ADDR:
@ -164,189 +173,189 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank
break; break;
case BC_LEA_ABS: case BC_LEA_ABS:
fprintf(file, "LEA\t%s, %s", TempName(memory[start + i + 0], tbuffer, proc), AddrName(uint16(memory[start + i + 1] + 256 * memory[start + i + 2]), abuffer, linker)); fprintf(file, "LEA\t%s, %s", TempName(memory[start + i + 0], tbuffer, proc, linker), AddrName(uint16(memory[start + i + 1] + 256 * memory[start + i + 2]), abuffer, linker));
i += 3; i += 3;
break; break;
case BC_LEA_ABS_INDEX: case BC_LEA_ABS_INDEX:
fprintf(file, "LEAX\tADDR, %s + %s", AddrName(uint16(memory[start + i + 1] + 256 * memory[start + i + 2]), abuffer, linker), TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "LEAX\tADDR, %s + %s", AddrName(uint16(memory[start + i + 1] + 256 * memory[start + i + 2]), abuffer, linker), TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 3; i += 3;
break; break;
case BC_LEA_ACCU_INDEX: case BC_LEA_ACCU_INDEX:
fprintf(file, "LEAX\tADDR, %s + ACCU", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "LEAX\tADDR, %s + ACCU", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_LEA_ABS_INDEX_U8: case BC_LEA_ABS_INDEX_U8:
fprintf(file, "LEAXB\tADDR, %s + %s", AddrName(uint16(memory[start + i + 1] + 256 * memory[start + i + 2]), abuffer, linker), TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "LEAXB\tADDR, %s + %s", AddrName(uint16(memory[start + i + 1] + 256 * memory[start + i + 2]), abuffer, linker), TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 3; i += 3;
break; break;
case BC_STORE_ABS_8: case BC_STORE_ABS_8:
fprintf(file, "MOVB\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc)); fprintf(file, "MOVB\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc, linker));
i += 3; i += 3;
break; break;
case BC_STORE_ABS_16: case BC_STORE_ABS_16:
fprintf(file, "MOV\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc)); fprintf(file, "MOV\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc, linker));
i += 3; i += 3;
break; break;
case BC_STORE_ABS_32: case BC_STORE_ABS_32:
fprintf(file, "MOVD\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc)); fprintf(file, "MOVD\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc, linker));
i += 3; i += 3;
break; break;
case BC_LOAD_LOCAL_8: case BC_LOAD_LOCAL_8:
fprintf(file, "MOVB\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); fprintf(file, "MOVB\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2; i += 2;
break; break;
case BC_LOAD_LOCAL_U8: case BC_LOAD_LOCAL_U8:
fprintf(file, "MOVUB\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); fprintf(file, "MOVUB\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2; i += 2;
break; break;
case BC_LOAD_LOCAL_16: case BC_LOAD_LOCAL_16:
fprintf(file, "MOV\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); fprintf(file, "MOV\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2; i += 2;
break; break;
case BC_LOAD_LOCAL_32: case BC_LOAD_LOCAL_32:
fprintf(file, "MOVD\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); fprintf(file, "MOVD\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2; i += 2;
break; break;
case BC_STORE_LOCAL_8: case BC_STORE_LOCAL_8:
fprintf(file, "MOVB\t%d(FP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "MOVB\t%d(FP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2; i += 2;
break; break;
case BC_STORE_LOCAL_16: case BC_STORE_LOCAL_16:
fprintf(file, "MOV\t%d(FP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "MOV\t%d(FP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2; i += 2;
break; break;
case BC_STORE_LOCAL_32: case BC_STORE_LOCAL_32:
fprintf(file, "MOVD\t%d(FP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "MOVD\t%d(FP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2; i += 2;
break; break;
case BC_LEA_LOCAL: case BC_LEA_LOCAL:
fprintf(file, "LEA\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2])); fprintf(file, "LEA\t%s, %d(FP)", TempName(memory[start + i + 0], tbuffer, proc, linker), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3; i += 3;
break; break;
case BC_LEA_FRAME: case BC_LEA_FRAME:
fprintf(file, "LEA\t%s, %d(SP)", TempName(memory[start + i + 0], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2])); fprintf(file, "LEA\t%s, %d(SP)", TempName(memory[start + i + 0], tbuffer, proc, linker), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3; i += 3;
break; break;
case BC_STORE_FRAME_8: case BC_STORE_FRAME_8:
fprintf(file, "MOVB\t%d(SP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "MOVB\t%d(SP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2; i += 2;
break; break;
case BC_STORE_FRAME_16: case BC_STORE_FRAME_16:
fprintf(file, "MOV\t%d(SP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "MOV\t%d(SP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2; i += 2;
break; break;
case BC_STORE_FRAME_32: case BC_STORE_FRAME_32:
fprintf(file, "MOVD\t%d(SP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "MOVD\t%d(SP), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2; i += 2;
break; break;
case BC_BINOP_ADDR_16: case BC_BINOP_ADDR_16:
fprintf(file, "ADD\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "ADD\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_ADDA_16: case BC_BINOP_ADDA_16:
fprintf(file, "ADD\t%s, ACCU", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "ADD\t%s, ACCU", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_SUBR_16: case BC_BINOP_SUBR_16:
fprintf(file, "SUB\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "SUB\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_MULR_16: case BC_BINOP_MULR_16:
fprintf(file, "MUL\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "MUL\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_DIVR_U16: case BC_BINOP_DIVR_U16:
fprintf(file, "DIVU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "DIVU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_MODR_U16: case BC_BINOP_MODR_U16:
fprintf(file, "MODU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "MODU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_DIVR_I16: case BC_BINOP_DIVR_I16:
fprintf(file, "DIVS\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "DIVS\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_MODR_I16: case BC_BINOP_MODR_I16:
fprintf(file, "MODS\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "MODS\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_ANDR_16: case BC_BINOP_ANDR_16:
fprintf(file, "AND\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "AND\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_ORR_16: case BC_BINOP_ORR_16:
fprintf(file, "OR\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "OR\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_XORR_16: case BC_BINOP_XORR_16:
fprintf(file, "XOR\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "XOR\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_SHLR_16: case BC_BINOP_SHLR_16:
fprintf(file, "SHL\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "SHL\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_SHRR_I16: case BC_BINOP_SHRR_I16:
fprintf(file, "SHRU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "SHRU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_SHRR_U16: case BC_BINOP_SHRR_U16:
fprintf(file, "SHRI\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "SHRI\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_ADDI_16: case BC_BINOP_ADDI_16:
fprintf(file, "ADD\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2])); fprintf(file, "ADD\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc, linker), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3; i += 3;
break; break;
case BC_BINOP_SUBI_16: case BC_BINOP_SUBI_16:
fprintf(file, "SUBR\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2])); fprintf(file, "SUBR\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc, linker), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3; i += 3;
break; break;
case BC_BINOP_ANDI_16: case BC_BINOP_ANDI_16:
fprintf(file, "AND\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2])); fprintf(file, "AND\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc, linker), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3; i += 3;
break; break;
case BC_BINOP_ORI_16: case BC_BINOP_ORI_16:
fprintf(file, "OR\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2])); fprintf(file, "OR\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc, linker), uint16(memory[start + i + 1] + 256 * memory[start + i + 2]));
i += 3; i += 3;
break; break;
case BC_BINOP_MULI8_16: case BC_BINOP_MULI8_16:
fprintf(file, "MUL\t%s, #%d", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); fprintf(file, "MUL\t%s, #%d", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2; i += 2;
break; break;
case BC_BINOP_ADDI_8: case BC_BINOP_ADDI_8:
fprintf(file, "ADDB\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); fprintf(file, "ADDB\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2; i += 2;
break; break;
case BC_BINOP_ANDI_8: case BC_BINOP_ANDI_8:
fprintf(file, "ANDB\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); fprintf(file, "ANDB\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2; i += 2;
break; break;
case BC_BINOP_ORI_8: case BC_BINOP_ORI_8:
fprintf(file, "ORB\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); fprintf(file, "ORB\t%s, #$%04X", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2; i += 2;
break; break;
case BC_LOOP_U8: case BC_LOOP_U8:
fprintf(file, "LOOPB\t%s, #$%02X", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); fprintf(file, "LOOPB\t%s, #$%02X", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2; i += 2;
break; break;
case BC_CONV_I8_I16: case BC_CONV_I8_I16:
fprintf(file, "SEXT8\t%s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "SEXT8\t%s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i++; i++;
break; break;
@ -364,11 +373,11 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank
break; break;
case BC_BINOP_CMPUR_16: case BC_BINOP_CMPUR_16:
fprintf(file, "CMPU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "CMPU\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_CMPSR_16: case BC_BINOP_CMPSR_16:
fprintf(file, "CMPS\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "CMPS\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
@ -382,11 +391,11 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank
break; break;
case BC_BINOP_CMPUR_8: case BC_BINOP_CMPUR_8:
fprintf(file, "CMPUB\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "CMPUB\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_CMPSR_8: case BC_BINOP_CMPSR_8:
fprintf(file, "CMPSB\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "CMPSB\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
@ -400,23 +409,23 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank
break; break;
case BC_BINOP_ADD_F32: case BC_BINOP_ADD_F32:
fprintf(file, "ADDF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "ADDF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_SUB_F32: case BC_BINOP_SUB_F32:
fprintf(file, "SUBF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "SUBF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_MUL_F32: case BC_BINOP_MUL_F32:
fprintf(file, "MULF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "MULF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_DIV_F32: case BC_BINOP_DIV_F32:
fprintf(file, "DIVF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "DIVF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
case BC_BINOP_CMP_F32: case BC_BINOP_CMP_F32:
fprintf(file, "CMPF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "CMPF\tACCU, %s", TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 1; i += 1;
break; break;
@ -556,37 +565,37 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank
break; break;
case BC_LOAD_ADDR_8: case BC_LOAD_ADDR_8:
fprintf(file, "MOVB\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); fprintf(file, "MOVB\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2; i += 2;
break; break;
case BC_LOAD_ADDR_U8: case BC_LOAD_ADDR_U8:
fprintf(file, "MOVUB\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); fprintf(file, "MOVUB\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2; i += 2;
break; break;
case BC_LOAD_ADDR_16: case BC_LOAD_ADDR_16:
fprintf(file, "MOV\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); fprintf(file, "MOV\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2; i += 2;
break; break;
case BC_LOAD_ADDR_32: case BC_LOAD_ADDR_32:
fprintf(file, "MOVD\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]); fprintf(file, "MOVD\t%s, %d(ADDR)", TempName(memory[start + i + 0], tbuffer, proc, linker), memory[start + i + 1]);
i += 2; i += 2;
break; break;
case BC_STORE_ADDR_8: case BC_STORE_ADDR_8:
fprintf(file, "MOVB\t%d(ADDR), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "MOVB\t%d(ADDR), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2; i += 2;
break; break;
case BC_STORE_ADDR_16: case BC_STORE_ADDR_16:
fprintf(file, "MOV\t%d(ADDR), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "MOV\t%d(ADDR), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2; i += 2;
break; break;
case BC_STORE_ADDR_32: case BC_STORE_ADDR_32:
fprintf(file, "MOVD\t%d(ADDR), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "MOVD\t%d(ADDR), %s", memory[start + i + 1], TempName(memory[start + i + 0], tbuffer, proc, linker));
i += 2; i += 2;
break; break;
case BC_EXTRT: case BC_EXTRT:
fprintf(file, "EXTRT\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker)); fprintf(file, "EXTRT\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc, linker), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3; i += 3;
break; break;
} }
@ -665,7 +674,7 @@ void NativeCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int ba
else if (ident) else if (ident)
fprintf(file, "%s:\n", ident->mString); fprintf(file, "%s:\n", ident->mString);
char tbuffer[10], abuffer[100]; char tbuffer[100], abuffer[100];
int ip = start; int ip = start;
while (ip < start + size) while (ip < start + size)
@ -689,15 +698,15 @@ void NativeCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int ba
break; break;
case ASMIM_ZERO_PAGE: case ASMIM_ZERO_PAGE:
addr = memory[ip++]; addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s %s\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc)); fprintf(file, "%04x : %02x %02x __ %s %s\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc, linker));
break; break;
case ASMIM_ZERO_PAGE_X: case ASMIM_ZERO_PAGE_X:
addr = memory[ip++]; addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s %s,x\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc)); fprintf(file, "%04x : %02x %02x __ %s %s,x\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc, linker));
break; break;
case ASMIM_ZERO_PAGE_Y: case ASMIM_ZERO_PAGE_Y:
addr = memory[ip++]; addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s %s,y\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc)); fprintf(file, "%04x : %02x %02x __ %s %s,y\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc, linker));
break; break;
case ASMIM_ABSOLUTE: case ASMIM_ABSOLUTE:
addr = memory[ip] + 256 * memory[ip + 1]; addr = memory[ip] + 256 * memory[ip + 1];
@ -721,11 +730,11 @@ void NativeCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int ba
break; break;
case ASMIM_INDIRECT_X: case ASMIM_INDIRECT_X:
addr = memory[ip++]; addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s (%s,x)\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc)); fprintf(file, "%04x : %02x %02x __ %s (%s,x)\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc, linker));
break; break;
case ASMIM_INDIRECT_Y: case ASMIM_INDIRECT_Y:
addr = memory[ip++]; addr = memory[ip++];
fprintf(file, "%04x : %02x %02x __ %s (%s),y\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc)); fprintf(file, "%04x : %02x %02x __ %s (%s),y\n", iip, memory[iip], memory[iip + 1], AsmInstructionNames[d.mType], TempName(addr, tbuffer, proc, linker));
break; break;
case ASMIM_RELATIVE: case ASMIM_RELATIVE:
addr = memory[ip++]; addr = memory[ip++];
@ -756,7 +765,7 @@ const char* NativeCodeDisassembler::AddrName(int addr, char* buffer, Linker* lin
} }
const char* NativeCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc) const char* NativeCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc, Linker * linker)
{ {
if (tmp >= BC_REG_ADDR && tmp <= BC_REG_ADDR + 3) if (tmp >= BC_REG_ADDR && tmp <= BC_REG_ADDR + 3)
{ {
@ -804,6 +813,15 @@ const char* NativeCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodeP
sprintf_s(buffer, 10, "$%02x", tmp); sprintf_s(buffer, 10, "$%02x", tmp);
return buffer; return buffer;
} }
else if (linker)
{
LinkerObject* obj = linker->FindObjectByAddr(tmp);
if (obj && obj->mIdent)
sprintf_s(buffer, 40, "$%02x; (%s + %d)", tmp, obj->mIdent->mString, tmp - obj->mAddress);
else
sprintf_s(buffer, 10, "$%02x", tmp);
return buffer;
}
else else
{ {
sprintf_s(buffer, 10, "$%02x", tmp); sprintf_s(buffer, 10, "$%02x", tmp);

View File

@ -17,7 +17,7 @@ public:
void Disassemble(FILE* file, const uint8* memory, int bank, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker * linker); void Disassemble(FILE* file, const uint8* memory, int bank, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker * linker);
protected: protected:
const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc); const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc, Linker* linker);
const char* AddrName(int addr, char* buffer, Linker* linker); const char* AddrName(int addr, char* buffer, Linker* linker);
}; };
@ -30,7 +30,7 @@ public:
void Disassemble(FILE* file, const uint8* memory, int bank, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker); void Disassemble(FILE* file, const uint8* memory, int bank, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker);
void DumpMemory(FILE* file, const uint8* memory, int bank, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker, LinkerObject * lobj); void DumpMemory(FILE* file, const uint8* memory, int bank, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker, LinkerObject * lobj);
protected: protected:
const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc); const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc, Linker* linker);
const char* AddrName(int addr, char* buffer, Linker* linker); const char* AddrName(int addr, char* buffer, Linker* linker);
}; };

View File

@ -59,6 +59,7 @@ enum ErrorID
ERRR_INVALID_CASE, ERRR_INVALID_CASE,
ERRR_INSUFFICIENT_MEMORY, ERRR_INSUFFICIENT_MEMORY,
ERRR_INTERRUPT_TO_COMPLEX, ERRR_INTERRUPT_TO_COMPLEX,
ERRR_INVALID_STORAGE_TYPE,
EERR_INVALID_PREPROCESSOR, EERR_INVALID_PREPROCESSOR,
}; };

View File

@ -254,6 +254,8 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration*
type = type->mBase; type = type->mBase;
if (type->mFlags & DTF_CONST) if (type->mFlags & DTF_CONST)
var->mLinkerObject->mFlags |= LOBJF_CONST; var->mLinkerObject->mFlags |= LOBJF_CONST;
if (dec->mFlags & DTF_ZEROPAGE)
var->mLinkerObject->mFlags |= LOBJF_ZEROPAGE;
var->mIndex = mod->mGlobalVars.Size(); var->mIndex = mod->mGlobalVars.Size();
mod->mGlobalVars.Push(var); mod->mGlobalVars.Push(var);

View File

@ -490,7 +490,8 @@ static const char* LinkerSectionTypeNames[] = {
"BSS", "BSS",
"HEAP", "HEAP",
"STACK", "STACK",
"SSTACK" "SSTACK",
"ZEROPAGE"
}; };
bool Linker::WriteBinFile(const char* filename) bool Linker::WriteBinFile(const char* filename)

View File

@ -31,7 +31,8 @@ enum LinkerSectionType
LST_BSS, LST_BSS,
LST_HEAP, LST_HEAP,
LST_STACK, LST_STACK,
LST_STATIC_STACK LST_STATIC_STACK,
LST_ZEROPAGE
}; };
@ -130,6 +131,7 @@ static const uint32 LOBJF_CONST = 0x00000010;
static const uint32 LOBJF_RELEVANT = 0x00000020; static const uint32 LOBJF_RELEVANT = 0x00000020;
static const uint32 LOBJF_STATIC_STACK = 0x00000040; static const uint32 LOBJF_STATIC_STACK = 0x00000040;
static const uint32 LOBJF_NO_CROSS = 0x00000080; static const uint32 LOBJF_NO_CROSS = 0x00000080;
static const uint32 LOBJF_ZEROPAGE = 0x00000100;
class LinkerObject class LinkerObject
{ {

View File

@ -3002,6 +3002,14 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
mode = ASMIM_ZERO_PAGE; mode = ASMIM_ZERO_PAGE;
else if (mode == ASMIM_ABSOLUTE_X && !mLinkerObject && mAddress < 256 && HasAsmInstructionMode(mType, ASMIM_ZERO_PAGE_X)) else if (mode == ASMIM_ABSOLUTE_X && !mLinkerObject && mAddress < 256 && HasAsmInstructionMode(mType, ASMIM_ZERO_PAGE_X))
mode = ASMIM_ZERO_PAGE_X; mode = ASMIM_ZERO_PAGE_X;
else if (mode == ASMIM_ABSOLUTE_Y && !mLinkerObject && mAddress < 256 && HasAsmInstructionMode(mType, ASMIM_ZERO_PAGE_Y))
mode = ASMIM_ZERO_PAGE_Y;
else if (mode == ASMIM_ABSOLUTE && mLinkerObject && (mLinkerObject->mFlags & LOBJF_ZEROPAGE) && HasAsmInstructionMode(mType, ASMIM_ZERO_PAGE))
mode = ASMIM_ZERO_PAGE;
else if (mode == ASMIM_ABSOLUTE_X && mLinkerObject && (mLinkerObject->mFlags & LOBJF_ZEROPAGE) && HasAsmInstructionMode(mType, ASMIM_ZERO_PAGE_X))
mode = ASMIM_ZERO_PAGE_X;
else if (mode == ASMIM_ABSOLUTE_Y && mLinkerObject && (mLinkerObject->mFlags & LOBJF_ZEROPAGE) && HasAsmInstructionMode(mType, ASMIM_ZERO_PAGE_Y))
mode = ASMIM_ZERO_PAGE_Y;
if (mode == ASMIM_IMMEDIATE_ADDRESS) if (mode == ASMIM_IMMEDIATE_ADDRESS)
{ {
@ -3024,7 +3032,22 @@ void NativeCodeInstruction::Assemble(NativeCodeBasicBlock* block)
case ASMIM_ZERO_PAGE_Y: case ASMIM_ZERO_PAGE_Y:
case ASMIM_INDIRECT_X: case ASMIM_INDIRECT_X:
case ASMIM_INDIRECT_Y: case ASMIM_INDIRECT_Y:
if (mLinkerObject)
{
LinkerReference rl;
rl.mOffset = block->mCode.Size();
rl.mRefObject = mLinkerObject;
rl.mRefOffset = mAddress;
rl.mFlags = LREF_LOWBYTE;
block->mRelocations.Push(rl);
block->PutByte(0);
}
else
{
block->PutByte(uint8(mAddress)); block->PutByte(uint8(mAddress));
}
break; break;
case ASMIM_IMMEDIATE: case ASMIM_IMMEDIATE:
block->PutByte(uint16(mAddress)); block->PutByte(uint16(mAddress));
@ -9194,6 +9217,36 @@ bool NativeCodeBasicBlock::MergeBasicBlocks(void)
if (!mLocked) if (!mLocked)
{ {
if (mFalseJump)
{
if (mTrueJump->mIns.Size() == 0 && mTrueJump->mFalseJump)
{
if (mTrueJump->mBranch == mBranch)
{
mTrueJump = mTrueJump->mTrueJump;
changed = true;
}
else if (mTrueJump->mBranch == InvertBranchCondition(mBranch))
{
mTrueJump = mTrueJump->mFalseJump;
changed = true;
}
}
if (mFalseJump->mIns.Size() == 0 && mFalseJump->mFalseJump)
{
if (mFalseJump->mBranch == mBranch)
{
mFalseJump = mFalseJump->mFalseJump;
changed = true;
}
else if (mFalseJump->mBranch == InvertBranchCondition(mBranch))
{
mFalseJump = mFalseJump->mTrueJump;
changed = true;
}
}
}
while (mTrueJump && !mFalseJump && mTrueJump->mNumEntries == 1 && mTrueJump != this && !mTrueJump->mLocked) while (mTrueJump && !mFalseJump && mTrueJump->mNumEntries == 1 && mTrueJump != this && !mTrueJump->mLocked)
{ {
for (int i = 0; i < mTrueJump->mIns.Size(); i++) for (int i = 0; i < mTrueJump->mIns.Size(); i++)
@ -10758,6 +10811,19 @@ bool NativeCodeBasicBlock::JoinTailCodeSequences(NativeCodeProcedure* proc, bool
} }
} }
#endif #endif
if (mEntryBlocks.Size() == 1)
{
NativeCodeBasicBlock* eblock = mEntryBlocks[0];
if (mIns.Size() > 0 && eblock->mIns.Size() > 0)
{
if (mIns[0].mType == ASMIT_ORA && mIns[0].mMode == ASMIM_IMMEDIATE && mIns[0].mAddress == 0 && eblock->mIns.Last().ChangesAccuAndFlag())
{
eblock->mExitRequiredRegs += CPU_REG_Z;
mIns.Remove(0);
changed = true;
}
}
}
#if 1 #if 1
if (loops && mIns.Size() >= 1 && mEntryBlocks.Size() == 2) if (loops && mIns.Size() >= 1 && mEntryBlocks.Size() == 2)
{ {
@ -19419,6 +19485,29 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
mFalseJump = nullptr; mFalseJump = nullptr;
changed = true; changed = true;
} }
else if (mIns.Size() > 0 && mIns.Last().mType == ASMIT_LDA)
{
if (mBranch == ASMIT_BEQ && mTrueJump->mIns[0].mAddress == 1 && mFalseJump->mIns[0].mAddress == 0)
{
mIns.Insert(mIns.Size() - 1, NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns[mIns.Size() - 1].mType = ASMIT_CMP;
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mBranch = ASMIT_JMP;
mTrueJump = mTrueJump->mTrueJump;
mFalseJump = nullptr;
changed = true;
}
else if (mBranch == ASMIT_BNE && mTrueJump->mIns[0].mAddress == 0 && mFalseJump->mIns[0].mAddress == 1)
{
mIns.Insert(mIns.Size() - 1, NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
mIns[mIns.Size() - 1].mType = ASMIT_CMP;
mIns.Push(NativeCodeInstruction(ASMIT_ROL, ASMIM_IMPLIED));
mBranch = ASMIT_JMP;
mTrueJump = mTrueJump->mTrueJump;
mFalseJump = nullptr;
changed = true;
}
}
} }
#endif #endif
@ -20647,6 +20736,9 @@ void NativeCodeProcedure::Optimize(void)
cnt++; cnt++;
} while (changed); } while (changed);
ResetVisited();
mEntryBlock->ReduceLocalYPressure();
CompressTemporaries(); CompressTemporaries();
#if 1 #if 1

View File

@ -979,6 +979,11 @@ Declaration* Parser::ParseDeclaration(bool variable)
storageFlags |= DTF_EXTERN; storageFlags |= DTF_EXTERN;
mScanner->NextToken(); mScanner->NextToken();
} }
else if (mScanner->mToken == TK_ZEROPAGE)
{
storageFlags |= DTF_ZEROPAGE;
mScanner->NextToken();
}
else if (mScanner->mToken == TK_INLINE) else if (mScanner->mToken == TK_INLINE)
{ {
storageFlags |= DTF_REQUEST_INLINE; storageFlags |= DTF_REQUEST_INLINE;
@ -1073,6 +1078,14 @@ Declaration* Parser::ParseDeclaration(bool variable)
{ {
Declaration* pdec; Declaration* pdec;
if (storageFlags & DTF_ZEROPAGE)
{
if (ndec->mType == DT_VARIABLE)
ndec->mSection = mCompilationUnits->mSectionZeroPage;
else
mErrors->Error(ndec->mLocation, ERRR_INVALID_STORAGE_TYPE, "Invalid storage type", ndec->mIdent->mString);
}
if (mGlobals == mScope && !(storageFlags & DTF_STATIC)) if (mGlobals == mScope && !(storageFlags & DTF_STATIC))
{ {
pdec = mCompilationUnits->mScope->Insert(ndec->mIdent, ndec); pdec = mCompilationUnits->mScope->Insert(ndec->mIdent, ndec);

View File

@ -55,6 +55,7 @@ const char* TokenNames[] =
"__native", "__native",
"__fastcall", "__fastcall",
"__export", "__export",
"__zeropage",
"number", "number",
"char", "char",
@ -1313,6 +1314,8 @@ void Scanner::NextRawToken(void)
mToken = TK_FASTCALL; mToken = TK_FASTCALL;
else if (!strcmp(tkident, "__export")) else if (!strcmp(tkident, "__export"))
mToken = TK_EXPORT; mToken = TK_EXPORT;
else if (!strcmp(tkident, "__zeropage"))
mToken = TK_ZEROPAGE;
else else
{ {
mToken = TK_IDENT; mToken = TK_IDENT;

View File

@ -53,6 +53,7 @@ enum Token
TK_NATIVE, TK_NATIVE,
TK_FASTCALL, TK_FASTCALL,
TK_EXPORT, TK_EXPORT,
TK_ZEROPAGE,
TK_NUMBER, TK_NUMBER,
TK_CHARACTER, TK_CHARACTER,