From 330e022a434825da4bde1c88d84742c5c71dfe6f Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Tue, 5 Oct 2021 18:24:03 +0200 Subject: [PATCH] Exclude bss segment from prg file --- autotest/arrayoffsetindex.c | 20 ++++ autotest/arrparam.c | 16 +++ autotest/autotest.bat | 44 +++++++ autotest/bsstest.c | 27 +++++ autotest/copyintvec.c | 20 ++++ autotest/divmodtest.c | 28 +++++ autotest/enumswitch.c | 23 ++++ autotest/incvector.c | 22 ++++ autotest/structoffsettest2.c | 25 ++++ include/crt.c | 96 +++++++++++++++- include/string.c | 35 ++++++ oscar64/Compiler.cpp | 2 +- oscar64/Disassembler.cpp | 14 ++- oscar64/Emulator.cpp | 53 ++++++++- oscar64/Emulator.h | 6 +- oscar64/InterCode.cpp | 195 +++++++++++++++++++++++++++++--- oscar64/InterCode.h | 6 +- oscar64/InterCodeGenerator.cpp | 74 ++++++++++-- oscar64/InterCodeGenerator.h | 2 +- oscar64/Linker.cpp | 39 ++++++- oscar64/Linker.h | 2 +- oscar64/NativeCodeGenerator.cpp | 117 +++++++++++++++++-- oscar64/NativeCodeGenerator.h | 2 + oscar64/NumberSet.h | 4 + oscar64/Parser.cpp | 13 ++- oscar64/Parser.h | 2 +- 26 files changed, 831 insertions(+), 56 deletions(-) create mode 100644 autotest/arrayoffsetindex.c create mode 100644 autotest/arrparam.c create mode 100644 autotest/bsstest.c create mode 100644 autotest/copyintvec.c create mode 100644 autotest/divmodtest.c create mode 100644 autotest/enumswitch.c create mode 100644 autotest/incvector.c create mode 100644 autotest/structoffsettest2.c diff --git a/autotest/arrayoffsetindex.c b/autotest/arrayoffsetindex.c new file mode 100644 index 0000000..d0db177 --- /dev/null +++ b/autotest/arrayoffsetindex.c @@ -0,0 +1,20 @@ + + +int a(int * p, int x) +{ + int y = x + 3; + + p[y] = 1; + p[y + 1] = 2; + p[y + 2] = 3; + p[y + 3] = 4; + + return p[y] + p[y + 1] + p[y + 2] + p[y + 3]; +} + +int main(void) +{ + int t[16]; + + return a(t, 4) - 10; +} diff --git a/autotest/arrparam.c b/autotest/arrparam.c new file mode 100644 index 0000000..21f814d --- /dev/null +++ b/autotest/arrparam.c @@ -0,0 +1,16 @@ + +int a(char p[100]) +{ + int s = 0; + for(int i=0; i<100; i++) + s += p[i]; + return s; +} + +int main(void) +{ + char c[100]; + for(int i=0; i<100; i++) + c[i] = i; + return a(c) - 4950; +} diff --git a/autotest/autotest.bat b/autotest/autotest.bat index c786a20..2392030 100644 --- a/autotest/autotest.bat +++ b/autotest/autotest.bat @@ -126,6 +126,50 @@ if %errorlevel% neq 0 goto :error ..\release\oscar64 -e -n bitshifttest.c if %errorlevel% neq 0 goto :error +..\release\oscar64 -e arrparam.c +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -n arrparam.c +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e bsstest.c +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -n bsstest.c +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e copyintvec.c +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -n copyintvec.c +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e divmodtest.c +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -n divmodtest.c +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e enumswitch.c +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -n enumswitch.c +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e incvector.c +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -n incvector.c +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e structoffsettest2.c +if %errorlevel% neq 0 goto :error + +..\release\oscar64 -e -n structoffsettest2.c +if %errorlevel% neq 0 goto :error + + + exit /b 0 :error echo Failed with error #%errorlevel%. diff --git a/autotest/bsstest.c b/autotest/bsstest.c new file mode 100644 index 0000000..8bc5ea2 --- /dev/null +++ b/autotest/bsstest.c @@ -0,0 +1,27 @@ + +#include + +char ch[100]; +char p[] = "HELLO"; +int v[10]; +int w[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + +int sum(int * k) +{ + int s = 0; + for(int i=0; i<10; i++) + s += k[i]; + return s; +} + +int main(void) +{ + strcpy(ch, p); + strcat(ch, " WORLD"); + + for(int i=0; i<10; i++) + v[i] = w[i]; + + return strcmp(ch, "HELLO WORLD") + sum(v) - 55; +} + diff --git a/autotest/copyintvec.c b/autotest/copyintvec.c new file mode 100644 index 0000000..0d9369e --- /dev/null +++ b/autotest/copyintvec.c @@ -0,0 +1,20 @@ + + +void copyi(int * a, int * b, int n) +{ + for(int i=0; i + +int main(void) +{ + for(unsigned i=0; i<256; i+=11) + { + for(unsigned j=1; j<256; j++) + { + unsigned q = i / j, r = i % j; + + assert(q * j + r == i); + assert(r >= 0 && r < j); + } + } + + for(unsigned i=0; i<7000; i+=11) + { + for(unsigned j=1; j= 0 && r < j); + } + } + + return 0; +} diff --git a/autotest/enumswitch.c b/autotest/enumswitch.c new file mode 100644 index 0000000..a3a62fc --- /dev/null +++ b/autotest/enumswitch.c @@ -0,0 +1,23 @@ +enum E { + e1, e2, e3, e4 +}; + +int check(E e) +{ + switch(e) + { + case e1: + return 10; + case e2: + return 20; + case e3: + return 30; + default: + return 100; + } +} + +int main(void) +{ + return check(e1) + check(e2) + check(e3) + check(e4) - 160; +} diff --git a/autotest/incvector.c b/autotest/incvector.c new file mode 100644 index 0000000..4757389 --- /dev/null +++ b/autotest/incvector.c @@ -0,0 +1,22 @@ + + +void incv(int * a, int n) +{ + for(int i=0; ib.c.w = 1; + return a->b.c.w; +} + +int main(void) +{ + return test(&q) - 1; +} + + diff --git a/include/crt.c b/include/crt.c index 742d2b2..2703bb5 100644 --- a/include/crt.c +++ b/include/crt.c @@ -1,9 +1,10 @@ // crt.c #include -void StackStart, StackEnd; +void StackStart, StackEnd, BSSStart, BSSEnd; #pragma section(stack, 0x0000, StackStart, StackEnd) +#pragma section(bss, 0x0000, BSSStart, BSSEnd) int main(void); @@ -22,6 +23,40 @@ __asm startup byt 0x00 byt 0x00 +// Clear BSS Segment + + lda #BSSStart + sta ip + 1 + + sec + lda #>BSSEnd + sbc #>BSSStart + beq w1 + tax + lda #0 + ldy #0 +l1: sta (ip), y + iny + bne l1 + inc ip + 1 + dex + bne l1 +w1: + sec + lda #bcode @@ -155,10 +190,67 @@ __asm negtmp32 __asm divmod { - sty tmpy lda #0 sta tmp + 2 sta tmp + 3 + + lda accu + 1 + bne WB + lda tmp + 1 + bne BW + +// byte / byte +BB: + lda #0 + ldx #8 + asl accu +LBB1: rol + cmp tmp + bcc WBB1 + sbc tmp +WBB1: rol accu + dex + bne LBB1 + sta tmp + 2 + rts + +// byte / word -> 0 +BW: + lda accu + sta tmp + 2 + lda accu + 1 + sta tmp + 3 + lda #0 + sta accu + sta accu + 1 + rts + +WB: + lda tmp + 1 + bne WW + lda tmp + bmi WW + +// word / byte + + lda #0 + ldx #16 + asl accu + rol accu + 1 +LWB1: rol + cmp tmp + bcc WWB1 + sbc tmp +WWB1: rol accu + rol accu + 1 + dex + bne LWB1 + sta tmp + 2 + rts + +// word / word +WW: + sty tmpy ldy #16 clc L1: rol accu diff --git a/include/string.c b/include/string.c index ba50754..174f3d7 100644 --- a/include/string.c +++ b/include/string.c @@ -1,5 +1,39 @@ #include "string.h" +#if 1 +char * strcpy(char * dst, const char * src) +{ + __asm + { + ldy #dst + lda (fp), y + sta $1f + iny + lda (fp), y + sta $20 + + ldy #src + lda (fp), y + sta $1b + iny + lda (fp), y + sta $1c + + ldy #0 + L1: lda ($1b), y + sta ($1f), y + beq W1 + iny + bne L1 + inc $1c + inc $20 + bne L1 + W1: + rts + + } +} +#else char * strcpy(char * dst, const char * src) { char * d = dst; @@ -9,6 +43,7 @@ char * strcpy(char * dst, const char * src) return dst; } +#endif int strcmp(const char * ptr1, const char * ptr2) { diff --git a/oscar64/Compiler.cpp b/oscar64/Compiler.cpp index 0baa0f7..7e6398a 100644 --- a/oscar64/Compiler.cpp +++ b/oscar64/Compiler.cpp @@ -326,7 +326,7 @@ int Compiler::ExecuteCode(void) Location loc; printf("Running emulation...\n"); - Emulator* emu = new Emulator(); + Emulator* emu = new Emulator(mLinker); memcpy(emu->mMemory + mLinker->mProgramStart, mLinker->mMemory + mLinker->mProgramStart, mLinker->mProgramEnd - mLinker->mProgramStart); emu->mMemory[0x2d] = mLinker->mProgramEnd & 0xff; emu->mMemory[0x2e] = mLinker->mProgramEnd >> 8; diff --git a/oscar64/Disassembler.cpp b/oscar64/Disassembler.cpp index e2a0691..391fa45 100644 --- a/oscar64/Disassembler.cpp +++ b/oscar64/Disassembler.cpp @@ -44,7 +44,10 @@ const char* ByteCodeDisassembler::AddrName(int addr, char* buffer, Linker* linke { LinkerObject* obj = linker->FindObjectByAddr(addr); if (obj && obj->mIdent) - return obj->mIdent->mString; + { + sprintf_s(buffer, 40, "%s + %d", obj->mIdent->mString, addr - obj->mAddress); + return buffer; + } } sprintf_s(buffer, 10, "$%04x", addr); @@ -59,7 +62,7 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star else if (ident) fprintf(file, "%s:\n", ident->mString); - char tbuffer[10], abuffer[10]; + char tbuffer[10], abuffer[100]; #if 0 for (int i = 0; i < proc->mTemporaries.Size(); i++) printf("T%d = $%.2x\n", i, BC_REG_TMP + proc->mTempOffset[i]); @@ -581,7 +584,7 @@ void NativeCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int st else if (ident) fprintf(file, "%s:\n", ident->mString); - char tbuffer[10], abuffer[10]; + char tbuffer[10], abuffer[100]; int ip = start; while (ip < start + size) @@ -659,7 +662,10 @@ const char* NativeCodeDisassembler::AddrName(int addr, char* buffer, Linker* lin { LinkerObject* obj = linker->FindObjectByAddr(addr); if (obj && obj->mIdent) - return obj->mIdent->mString; + { + sprintf_s(buffer, 40, "%s + %d", obj->mIdent->mString, addr - obj->mAddress); + return buffer; + } } sprintf_s(buffer, 10, "$%04x", addr); diff --git a/oscar64/Emulator.cpp b/oscar64/Emulator.cpp index 2fba59c..bb72285 100644 --- a/oscar64/Emulator.cpp +++ b/oscar64/Emulator.cpp @@ -1,7 +1,9 @@ #include "Emulator.h" +#include "Linker.h" #include -Emulator::Emulator(void) +Emulator::Emulator(Linker* linker) + : mLinker(linker) { for (int i = 0; i < 0x10000; i++) mMemory[i] = 0; @@ -40,6 +42,9 @@ void Emulator::DumpCycles(void) int topIP[101], topCycles[101]; int totalCycles = 0; + + GrowingArray lobjs(nullptr); + GrowingArray lobjc(0); for (int i = 0; i < 0x10000; i++) { @@ -47,10 +52,18 @@ void Emulator::DumpCycles(void) totalCycles += cycles; if (cycles > 0) { - if (numTops == 0 || cycles > topCycles[numTops]) + if (mLinker) + { + LinkerObject* lobj = mLinker->FindObjectByAddr(i); + if (lobj) + { + lobjs[lobj->mID] = lobj; + lobjc[lobj->mID] += cycles; + } + } + + if (numTops == 0 || cycles > topCycles[numTops - 1]) { - if (numTops < 40) - numTops++; int j = numTops; while (j > 0 && topCycles[j-1] < cycles) { @@ -60,6 +73,9 @@ void Emulator::DumpCycles(void) } topCycles[j] = cycles; topIP[j] = i; + + if (numTops < 40) + numTops++; } } } @@ -72,6 +88,35 @@ void Emulator::DumpCycles(void) printf(" %2d : %04x : %d\n", i, topIP[i], topCycles[i]); } + numTops = 0; + for (int i = 0; i < lobjc.Size(); i++) + { + int cycles = lobjc[i]; + if (cycles > 0) + { + if (numTops == 0 || cycles > topCycles[numTops - 1]) + { + int j = numTops; + while (j > 0 && topCycles[j - 1] < cycles) + { + topCycles[j] = topCycles[j - 1]; + topIP[j] = topIP[j - 1]; + j--; + } + topCycles[j] = cycles; + topIP[j] = i; + + if (numTops < 40) + numTops++; + } + } + + } + + for (int i = 0; i < numTops; i++) + { + printf(" %2d : %s : %d\n", i, lobjs[topIP[i]]->mIdent->mString, topCycles[i]); + } } bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, int & cycles) diff --git a/oscar64/Emulator.h b/oscar64/Emulator.h index bbf44a5..ae57920 100644 --- a/oscar64/Emulator.h +++ b/oscar64/Emulator.h @@ -3,10 +3,12 @@ #include "Assembler.h" #include "MachineTypes.h" +class Linker; + class Emulator { public: - Emulator(void); + Emulator(Linker * linker); ~Emulator(void); uint8 mMemory[0x10000]; @@ -15,6 +17,8 @@ public: int mIP; uint8 mRegA, mRegX, mRegY, mRegS, mRegP; + Linker* mLinker; + int Emulate(int startIP); bool EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, int & cycles); protected: diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 8a7d528..45e9325 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -1752,21 +1752,21 @@ void InterCodeBasicBlock::GenerateTraces(void) for (;;) { - if (mTrueJump && mTrueJump->mInstructions.Size() == 1 && mTrueJump->mInstructions[0]->mCode == IC_JUMP) + if (mTrueJump && mTrueJump->mInstructions.Size() == 1 && mTrueJump->mInstructions[0]->mCode == IC_JUMP && !mTrueJump->mLoopHead) { mTrueJump->mNumEntries--; mTrueJump = mTrueJump->mTrueJump; if (mTrueJump) mTrueJump->mNumEntries++; } - else if (mFalseJump && mFalseJump->mInstructions.Size() == 1 && mFalseJump->mInstructions[0]->mCode == IC_JUMP) + else if (mFalseJump && mFalseJump->mInstructions.Size() == 1 && mFalseJump->mInstructions[0]->mCode == IC_JUMP && !mFalseJump->mLoopHead) { mFalseJump->mNumEntries--; mFalseJump = mFalseJump->mTrueJump; if (mFalseJump) mFalseJump->mNumEntries++; } - else if (mTrueJump && !mFalseJump && ((mTrueJump->mInstructions.Size() < 10 && mTrueJump->mInstructions.Size() > 1) || mTrueJump->mNumEntries == 1)) + else if (mTrueJump && !mFalseJump && ((mTrueJump->mInstructions.Size() < 10 && mTrueJump->mInstructions.Size() > 1) || mTrueJump->mNumEntries == 1) && !mTrueJump->mLoopHead) { mTrueJump->mNumEntries--; @@ -2688,7 +2688,7 @@ bool InterCodeBasicBlock::RemoveUnusedStoreInstructions(const GrowingVariableArr } -void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams) +void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int& spareTemps) { int i; @@ -2742,12 +2742,169 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra for (i = 0; i < mInstructions.Size(); i++) { + InterInstruction* ins = mInstructions[i]; + +#if 1 + if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_MUL && ins->mTType == IT_INT16 && spareTemps + 1 < tvalid.Size()) + { + InterInstruction* mi0 = ltvalue[ins->mSTemp[0]], * mi1 = ltvalue[ins->mSTemp[1]]; + + if (mi0 && mi1 && mi1->mCode == IC_CONSTANT && mi0->mCode == IC_BINARY_OPERATOR && mi0->mOperator == IA_ADD) + { + InterInstruction* ai0 = ltvalue[mi0->mSTemp[0]], * ai1 = ltvalue[mi0->mSTemp[1]]; + if (ai0 && ai0->mCode == IC_CONSTANT) + { + InterInstruction* nai = new InterInstruction(); + nai->mCode = IC_BINARY_OPERATOR; + nai->mOperator = IA_MUL; + nai->mSTemp[0] = mi0->mSTemp[1]; + nai->mSType[0] = IT_INT16; + nai->mSTemp[1] = ins->mSTemp[1]; + nai->mSType[1] = IT_INT16; + nai->mTTemp = spareTemps++; + nai->mTType = IT_INT16; + mInstructions.Insert(i, nai); + + ltvalue[nai->mTTemp] = nullptr; + + InterInstruction* cai = new InterInstruction(); + cai->mCode = IC_CONSTANT; + cai->mTTemp = spareTemps++; + cai->mTType = IT_INT16; + cai->mIntValue = ai0->mIntValue * mi1->mIntValue; + mInstructions.Insert(i, cai); + + ltvalue[cai->mTTemp] = nullptr; + + ins->mOperator = IA_ADD; + ins->mSTemp[1] = nai->mTTemp; + ins->mSTemp[0] = cai->mTTemp; + + printf("MADD0\n"); + } + else if (ai1 && ai1->mCode == IC_CONSTANT) + { + printf("MADD1\n"); + } + } + } +#endif +#if 1 + if (ins->mCode == IC_BINARY_OPERATOR && ins->mOperator == IA_ADD && ins->mTType == IT_INT16 && spareTemps < tvalid.Size()) + { + InterInstruction* mi0 = ltvalue[ins->mSTemp[0]], * mi1 = ltvalue[ins->mSTemp[1]]; + + if (mi0 && mi1) + { + if (mi1->mCode == IC_CONSTANT && mi0->mCode == IC_BINARY_OPERATOR && mi0->mOperator == IA_ADD) + { + InterInstruction* ai0 = ltvalue[mi0->mSTemp[0]], * ai1 = ltvalue[mi0->mSTemp[1]]; + if (ai0 && ai1) + { + if (ai0 && ai0->mCode == IC_CONSTANT) + { + printf("ADDADD00\n"); + } + else if (ai1 && ai1->mCode == IC_CONSTANT) + { + printf("ADDADD01\n"); + } + } + } + else if (mi0->mCode == IC_CONSTANT && mi1->mCode == IC_BINARY_OPERATOR && mi1->mOperator == IA_ADD) + { + InterInstruction* ai0 = ltvalue[mi1->mSTemp[0]], * ai1 = ltvalue[mi1->mSTemp[1]]; + if (ai0 && ai1) + { + if (ai0 && ai0->mCode == IC_CONSTANT) + { + InterInstruction* cai = new InterInstruction(); + cai->mCode = IC_CONSTANT; + cai->mTTemp = spareTemps++; + cai->mTType = IT_INT16; + cai->mIntValue = ai0->mIntValue + mi0->mIntValue; + mInstructions.Insert(i, cai); + + ltvalue[cai->mTTemp] = nullptr; + + ins->mSTemp[1] = mi1->mSTemp[1]; + ins->mSTemp[0] = cai->mTTemp; + + printf("ADDADD10\n"); + } + else if (ai1 && ai1->mCode == IC_CONSTANT) + { + printf("ADDADD11\n"); + } + } + } + } + } + + if (ins->mCode == IC_LEA && spareTemps < tvalid.Size()) + { + InterInstruction* li0 = ltvalue[ins->mSTemp[0]], * li1 = ltvalue[ins->mSTemp[1]]; + + if (li0 && li1) + { + if (li1->mCode != IC_CONSTANT && li0->mCode == IC_BINARY_OPERATOR && li0->mOperator == IA_ADD) + { + InterInstruction* ai0 = ltvalue[li0->mSTemp[0]], * ai1 = ltvalue[li0->mSTemp[1]]; + if (ai0 && ai1 && ai0->mCode == IC_CONSTANT && ai0->mIntValue >= 0) + { + InterInstruction* nai = new InterInstruction(); + nai->mCode = IC_LEA; + nai->mMemory = IM_INDIRECT; + nai->mSTemp[0] = li0->mSTemp[1]; + nai->mSType[0] = IT_INT16; + nai->mSTemp[1] = ins->mSTemp[1]; + nai->mSType[1] = IT_POINTER; + nai->mTTemp = spareTemps++; + nai->mTType = IT_POINTER; + mInstructions.Insert(i, nai); + + ltvalue[nai->mTTemp] = nullptr; + + ins->mSTemp[1] = nai->mTTemp; + ins->mSTemp[0] = li0->mSTemp[0]; + + printf("LADD0 %d %x\n", mIndex, i); + } + else if (ai1 && ai1->mCode == IC_CONSTANT) + { + printf("LADD1\n"); + } + } + else if (li0->mCode == IC_CONSTANT && li1->mCode == IC_LEA) + { + InterInstruction* ai0 = ltvalue[li1->mSTemp[0]], * ai1 = ltvalue[li1->mSTemp[1]]; + if (ai0 && ai1 && ai0->mCode == IC_CONSTANT && ai0->mIntValue >= 0) + { + InterInstruction* cai = new InterInstruction(); + cai->mCode = IC_CONSTANT; + cai->mTTemp = spareTemps++; + cai->mTType = IT_INT16; + cai->mIntValue = ai0->mIntValue + li0->mIntValue; + mInstructions.Insert(i, cai); + + ins->mSTemp[0] = cai->mTTemp; + ins->mSTemp[1] = li1->mSTemp[1]; + + ltvalue[cai->mTTemp] = nullptr; + + printf("LEAEA %d %x\n", mIndex, i); + } + } + } + } + +#endif lvalues.UpdateValue(mInstructions[i], ltvalue, aliasedLocals, aliasedParams); mInstructions[i]->PerformValueForwarding(ltvalue, tvalid); } - if (mTrueJump) mTrueJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams); - if (mFalseJump) mFalseJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams); + if (mTrueJump) mTrueJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams, spareTemps); + if (mFalseJump) mFalseJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams, spareTemps); } } @@ -3198,7 +3355,7 @@ bool IsMoveable(InterCode code) return true; } -void InterCodeBasicBlock::SingleBlockLoopOptimisation(void) +void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedParams) { if (!mVisited) { @@ -3228,7 +3385,8 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(void) { if (sins->mSTemp[1] >= 0) { - ins->mInvariant = false; + if (ins->mMemory != IM_PARAM || aliasedParams[ins->mVarIndex]) + ins->mInvariant = false; } else if (ins->mMemory == sins->mMemory && ins->mVarIndex == sins->mVarIndex && ins->mLinkerObject == sins->mLinkerObject) { @@ -3329,9 +3487,9 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(void) } if (mTrueJump) - mTrueJump->SingleBlockLoopOptimisation(); + mTrueJump->SingleBlockLoopOptimisation(aliasedParams); if (mFalseJump) - mFalseJump->SingleBlockLoopOptimisation(); + mFalseJump->SingleBlockLoopOptimisation(aliasedParams); } } @@ -3719,7 +3877,10 @@ void InterCodeProcedure::BuildTraces(void) // ResetVisited(); for (int i = 0; i < mBlocks.Size(); i++) + { mBlocks[i]->mNumEntries = 0; + mBlocks[i]->mLoopHead = false; + } mEntryBlock->CollectEntries(); // @@ -3936,7 +4097,7 @@ void InterCodeProcedure::Close(void) mEntryBlock->MarkAliasedLocalTemps(localTable, mLocalAliasedSet, paramTable, mParamAliasedSet); ValueSet valueSet; - FastNumberSet tvalidSet(numTemps); + FastNumberSet tvalidSet(numTemps + 32); bool eliminated; @@ -3946,26 +4107,30 @@ void InterCodeProcedure::Close(void) do { valueSet.FlushAll(); mValueForwardingTable.SetSize(numTemps, true); - tvalidSet.Clear(); + tvalidSet.Reset(numTemps + 32); ResetVisited(); - mEntryBlock->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet); + mEntryBlock->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet, numTemps); ResetVisited(); eliminated = mEntryBlock->EliminateDeadBranches(); if (eliminated) { + BuildTraces(); + /* ResetVisited(); for (int i = 0; i < mBlocks.Size(); i++) mBlocks[i]->mNumEntries = 0; mEntryBlock->CollectEntries(); + */ } } while (eliminated); DisassembleDebug("value forwarding"); - mValueForwardingTable.Clear(); + mValueForwardingTable.SetSize(numTemps, true); + mTemporaries.SetSize(numTemps, true); ResetVisited(); mEntryBlock->PerformMachineSpecificValueUsageCheck(mValueForwardingTable, tvalidSet); @@ -4103,7 +4268,7 @@ void InterCodeProcedure::Close(void) DisassembleDebug("Peephole optimized"); ResetVisited(); - mEntryBlock->SingleBlockLoopOptimisation(); + mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet); DisassembleDebug("single block loop opt"); diff --git a/oscar64/InterCode.h b/oscar64/InterCode.h index d4f5fcd..f178ea4 100644 --- a/oscar64/InterCode.h +++ b/oscar64/InterCode.h @@ -441,7 +441,7 @@ public: void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue); void PerformTempForwarding(TempForwardingTable& forwardingTable); - void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams); + void PerformValueForwarding(const GrowingInstructionPtrArray& tvalue, const ValueSet& values, FastNumberSet& tvalid, const NumberSet& aliasedLocals, const NumberSet& aliasedParams, int & spareTemps); void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid); bool EliminateDeadBranches(void); @@ -466,7 +466,7 @@ public: bool IsLeafProcedure(void); void PeepholeOptimization(void); - void SingleBlockLoopOptimisation(void); + void SingleBlockLoopOptimisation(const NumberSet& aliasedParams); InterCodeBasicBlock* PropagateDominator(InterCodeProcedure * proc); }; @@ -495,7 +495,7 @@ public: InterCodeModule * mModule; int mID; - int mLocalSize; + int mLocalSize, mNumLocals; GrowingVariableArray mLocalVars; Location mLocation; diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index cb24125..533e631 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -732,7 +732,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ins->mVarIndex = dec->mVarIndex; } else + { + if (inlineMapper) + ins->mVarIndex += inlineMapper->mVarIndex; + ins->mMemory = IM_LOCAL; + } block->Append(ins); @@ -1547,6 +1552,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* InlineMapper nmapper; nmapper.mReturn = new InterCodeBasicBlock(); + nmapper.mVarIndex = proc->mNumLocals; + proc->mNumLocals += fdec->mNumVars; if (inlineMapper) nmapper.mDepth = inlineMapper->mDepth + 1; proc->Append(nmapper.mReturn); @@ -1555,7 +1562,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* Expression* pex = exp->mRight; while (pex) { - int nindex = fdec->mNumVars++; + int nindex = proc->mNumLocals++; Declaration* vdec = new Declaration(pex->mLocation, DT_VARIABLE); InterInstruction* ains = new InterInstruction(); @@ -1571,7 +1578,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* vdec->mVarIndex = nindex; vdec->mBase = pdec->mBase; - vdec->mSize = pdec->mSize; + if (pdec->mBase->mType == DT_TYPE_ARRAY) + ains->mOperandSize = 2; + else + ains->mOperandSize = pdec->mSize; + vdec->mSize = ains->mOperandSize; vdec->mIdent = pdec->mIdent; } else @@ -1621,7 +1632,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* wins->mSType[1] = IT_POINTER; wins->mSTemp[1] = ains->mTTemp; if (pdec) - wins->mOperandSize = pdec->mSize; + { + if (pdec->mBase->mType == DT_TYPE_ARRAY) + wins->mOperandSize = 2; + else + wins->mOperandSize = pdec->mSize; + } else if (vr.mType->mSize > 2 && vr.mType->mType != DT_TYPE_ARRAY) wins->mOperandSize = vr.mType->mSize; else @@ -1638,7 +1654,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* Declaration* rdec = nullptr; if (ftype->mBase->mType != DT_TYPE_VOID) { - int nindex = fdec->mNumVars++; + int nindex = proc->mNumLocals++; nmapper.mResult = nindex; rdec = new Declaration(ftype->mLocation, DT_VARIABLE); @@ -1647,7 +1663,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* rdec->mSize = rdec->mBase->mSize; } - vl = TranslateExpression(procType, proc, block, fexp, nullptr, nullptr, &nmapper); + vl = TranslateExpression(ftype, proc, block, fexp, nullptr, nullptr, &nmapper); InterInstruction* jins = new InterInstruction(); jins->mCode = IC_JUMP; @@ -1924,7 +1940,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* ins->mCode = IC_RETURN; } - block->Append(ins); + if (ins->mCode != IC_NONE) + block->Append(ins); + if (inlineMapper) { InterInstruction* jins = new InterInstruction(); @@ -2144,9 +2162,50 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration* break; case EX_LOGICAL_AND: + case EX_LOGICAL_OR: { + InterInstruction* jins0 = new InterInstruction(); + jins0->mCode = IC_JUMP; + InterInstruction* jins1 = new InterInstruction(); + jins1->mCode = IC_JUMP; + + InterCodeBasicBlock* tblock = new InterCodeBasicBlock(); + proc->Append(tblock); + InterCodeBasicBlock* fblock = new InterCodeBasicBlock(); + proc->Append(fblock); + InterCodeBasicBlock* eblock = new InterCodeBasicBlock(); + proc->Append(eblock); + + TranslateLogic(procType, proc, block, tblock, fblock, exp, inlineMapper); + + int ttemp = proc->AddTemporary(IT_BOOL); + + InterInstruction* tins = new InterInstruction(); + tins->mCode = IC_CONSTANT; + tins->mIntValue = 1; + tins->mTType = IT_BOOL; + tins->mTTemp = ttemp; + tblock->Append(tins); + + InterInstruction* fins = new InterInstruction(); + fins->mCode = IC_CONSTANT; + fins->mIntValue = 0; + fins->mTType = IT_BOOL; + fins->mTTemp = ttemp; + fblock->Append(fins); + + tblock->Append(jins0); + tblock->Close(eblock, nullptr); + + fblock->Append(jins1); + fblock->Close(eblock, nullptr); + + block = eblock; + + return ExValue(TheBoolTypeDeclaration, ttemp); + + } break; - } case EX_WHILE: { InterInstruction * jins0 = new InterInstruction(); @@ -2553,6 +2612,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod dec->mVarIndex = proc->mID; dec->mLinkerObject = proc->mLinkerObject; + proc->mNumLocals = dec->mNumVars; if (mForceNativeCode) dec->mFlags |= DTF_NATIVE; diff --git a/oscar64/InterCodeGenerator.h b/oscar64/InterCodeGenerator.h index 30d46a0..3da75a6 100644 --- a/oscar64/InterCodeGenerator.h +++ b/oscar64/InterCodeGenerator.h @@ -34,7 +34,7 @@ protected: { GrowingArray mParams; InterCodeBasicBlock * mReturn; - int mResult, mDepth; + int mResult, mDepth, mVarIndex; InlineMapper(void) : mParams(-1), mResult(-1), mDepth(0) diff --git a/oscar64/Linker.cpp b/oscar64/Linker.cpp index cbf3fe4..aa052ce 100644 --- a/oscar64/Linker.cpp +++ b/oscar64/Linker.cpp @@ -61,6 +61,7 @@ LinkerRegion* Linker::AddRegion(const Ident* region, int start, int end) lrgn->mStart = start; lrgn->mEnd = end; lrgn->mUsed = 0; + lrgn->mNonzero = 0; mRegions.Push(lrgn); return lrgn; } @@ -117,7 +118,7 @@ LinkerObject* Linker::FindObjectByAddr(int addr) LinkerObject* lobj = mObjects[i]; if (lobj->mFlags & LOBJF_PLACED) { - if (lobj->mAddress == addr) + if (addr >= lobj->mAddress && addr < lobj->mAddress + lobj->mSize) return lobj; } } @@ -195,6 +196,9 @@ void Linker::Link(void) lobj->mAddress = lrgn->mStart + lrgn->mUsed; lrgn->mUsed += lobj->mSize; + if (lsec->mType == LST_DATA) + lrgn->mNonzero = lrgn->mUsed; + if (lobj->mAddress < lsec->mStart) lsec->mStart = lobj->mAddress; if (lobj->mAddress + lobj->mSize > lsec->mEnd) @@ -212,9 +216,9 @@ void Linker::Link(void) for (int i = 0; i < mRegions.Size(); i++) { LinkerRegion* lrgn = mRegions[i]; - address = lrgn->mStart + lrgn->mUsed; + address = lrgn->mStart + lrgn->mNonzero; - if (lrgn->mUsed && address > mProgramEnd) + if (lrgn->mNonzero && address > mProgramEnd) mProgramEnd = address; } @@ -236,7 +240,7 @@ void Linker::Link(void) } } - // Now expand the heap section to cover the reaminder of the region + // Now expand the heap section to cover the remainder of the region for (int i = 0; i < mRegions.Size(); i++) { @@ -309,6 +313,14 @@ static const char * LinkerObjectTypeNames[] = "END" }; +static const char* LinkerSectionTypeNames[] = { + "NONE", + "DATA", + "BSS", + "HEAP", + "STACK" +}; + bool Linker::WritePrgFile(const char* filename) { FILE* file; @@ -332,6 +344,25 @@ bool Linker::WriteMapFile(const char* filename) fopen_s(&file, filename, "wb"); if (file) { + fprintf(file, "sections\n"); + for (int i = 0; i < mSections.Size(); i++) + { + LinkerSection* lsec = mSections[i]; + + fprintf(file, "%04x - %04x : %s, %s\n", lsec->mStart, lsec->mEnd, LinkerSectionTypeNames[lsec->mType], lsec->mIdent->mString); + } + + fprintf(file, "\nregions\n"); + + for (int i = 0; i < mRegions.Size(); i++) + { + LinkerRegion * lrgn = mRegions[i]; + + fprintf(file, "%04x - %04x : %04x, %04x, %s\n", lrgn->mStart, lrgn->mEnd, lrgn->mNonzero, lrgn->mUsed, lrgn->mIdent->mString); + } + + fprintf(file, "\nobjects\n"); + for (int i = 0; i < mObjects.Size(); i++) { LinkerObject* obj = mObjects[i]; diff --git a/oscar64/Linker.h b/oscar64/Linker.h index 6a74661..363efc7 100644 --- a/oscar64/Linker.h +++ b/oscar64/Linker.h @@ -41,7 +41,7 @@ class LinkerRegion public: const Ident* mIdent; - int mStart, mEnd, mUsed; + int mStart, mEnd, mUsed, mNonzero; GrowingArray mSections; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 817abc3..944ce53 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -2930,6 +2930,21 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr } +void NativeCodeBasicBlock::LoadStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* wins) +{ + int size = wins->mOperandSize; + + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[rins->mSTemp[0]])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[wins->mSTemp[1]])); + for (int i = 1; i < size; i++) + { + mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[rins->mSTemp[0]])); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[wins->mSTemp[1]])); + } +} + void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterInstruction * rins, const InterInstruction * wins) { if (rins->mTType == IT_FLOAT) @@ -3022,6 +3037,50 @@ void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterI } } +void NativeCodeBasicBlock::LoadOpStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* oins, int oindex, const InterInstruction* wins) +{ + int size = wins->mOperandSize; + + AsmInsType at = ASMIT_ADC; + + switch (oins->mOperator) + { + case IA_ADD: + mIns.Push(NativeCodeInstruction(ASMIT_CLC)); + at = ASMIT_ADC; + break; + case IA_SUB: + mIns.Push(NativeCodeInstruction(ASMIT_SEC)); + at = ASMIT_SBC; + break; + case IA_AND: + mIns.Push(NativeCodeInstruction(ASMIT_SEC)); + at = ASMIT_AND; + break; + case IA_OR: + mIns.Push(NativeCodeInstruction(ASMIT_SEC)); + at = ASMIT_ORA; + break; + case IA_XOR: + mIns.Push(NativeCodeInstruction(ASMIT_SEC)); + at = ASMIT_EOR; + break; + } + + mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0)); + for (int i = 0; i < size; i++) + { + if (i != 0) + mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); + mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[rins->mSTemp[0]])); + if (oins->mSTemp[oindex] < 0) + mIns.Push(NativeCodeInstruction(at, ASMIM_IMMEDIATE, (oins->mSIntConst[oindex] >> (8 * i)) & 0xff)); + else + mIns.Push(NativeCodeInstruction(at, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[oins->mSTemp[oindex]] + i)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[wins->mSTemp[1]])); + } +} + void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterInstruction * ins, int reg, const NativeCodeInstruction* ainsl, const NativeCodeInstruction* ainsh) { if (ins->mTType == IT_FLOAT) @@ -5100,13 +5159,14 @@ void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, NativeCod } break; case IA_EXT8TO16S: - mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, 0)); mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]])); if (ins->mSTemp[0] != ins->mTTemp) mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp])); - mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, 1)); - mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED)); - mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 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, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 1)); break; case IA_EXT8TO16U: if (ins->mSTemp[0] != ins->mTTemp) @@ -5118,7 +5178,6 @@ void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, NativeCod mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 1)); break; case IA_EXT16TO32S: - mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, 0)); if (ins->mSTemp[0] != ins->mTTemp) { mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]])); @@ -5127,10 +5186,12 @@ void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, NativeCod mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1)); if (ins->mSTemp[0] != ins->mTTemp) mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 1)); - mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, 1)); - mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED)); - mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 2)); - mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 3)); + 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, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 2)); + mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 3)); break; case IA_EXT16TO32U: if (ins->mSTemp[0] != ins->mTTemp) @@ -7940,6 +8001,44 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode block->LoadStoreValue(iproc, ins, iblock->mInstructions[i + 1]); i++; } + else if (i + 1 < iblock->mInstructions.Size() && + iblock->mInstructions[i + 1]->mCode == IC_STORE && + iblock->mInstructions[i + 1]->mSTemp[0] == ins->mTTemp && + iblock->mInstructions[i + 1]->mSFinal[0] && + ins->mMemory == IM_INDIRECT && iblock->mInstructions[i + 1]->mMemory == IM_INDIRECT && + ins->mSIntConst[0] == 0 && iblock->mInstructions[i + 1]->mSIntConst[1] == 0) + { + block->LoadStoreIndirectValue(iproc, ins, iblock->mInstructions[i + 1]); + i++; + } + else if (i + 2 < iblock->mInstructions.Size() && + (ins->mTType == IT_INT8 || ins->mTType == IT_INT16 || ins->mTType == IT_INT32) && + iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && + (iblock->mInstructions[i + 1]->mOperator == IA_ADD || iblock->mInstructions[i + 1]->mOperator == IA_SUB || + iblock->mInstructions[i + 1]->mOperator == IA_AND || iblock->mInstructions[i + 1]->mOperator == IA_OR || iblock->mInstructions[i + 1]->mOperator == IA_XOR) && + iblock->mInstructions[i + 1]->mSTemp[0] == ins->mTTemp && iblock->mInstructions[i + 1]->mSFinal[0] && + iblock->mInstructions[i + 2]->mCode == IC_STORE && + iblock->mInstructions[i + 2]->mSTemp[0] == iblock->mInstructions[i + 1]->mTTemp && iblock->mInstructions[i + 2]->mSFinal[0] && + ins->mMemory == IM_INDIRECT && iblock->mInstructions[i + 2]->mMemory == IM_INDIRECT && + ins->mSIntConst[0] == 0 && iblock->mInstructions[i + 2]->mSIntConst[1] == 0) + { + block->LoadOpStoreIndirectValue(iproc, ins, iblock->mInstructions[i + 1], 1, iblock->mInstructions[i + 2]); + i += 2; + } + else if (i + 2 < iblock->mInstructions.Size() && + (ins->mTType == IT_INT8 || ins->mTType == IT_INT16 || ins->mTType == IT_INT32) && + iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && + (iblock->mInstructions[i + 1]->mOperator == IA_ADD || iblock->mInstructions[i + 1]->mOperator == IA_SUB || + iblock->mInstructions[i + 1]->mOperator == IA_AND || iblock->mInstructions[i + 1]->mOperator == IA_OR || iblock->mInstructions[i + 1]->mOperator == IA_XOR) && + iblock->mInstructions[i + 1]->mSTemp[1] == ins->mTTemp && iblock->mInstructions[i + 1]->mSFinal[1] && + iblock->mInstructions[i + 2]->mCode == IC_STORE && + iblock->mInstructions[i + 2]->mSTemp[0] == iblock->mInstructions[i + 1]->mTTemp && iblock->mInstructions[i + 2]->mSFinal[0] && + ins->mMemory == IM_INDIRECT && iblock->mInstructions[i + 2]->mMemory == IM_INDIRECT && + ins->mSIntConst[0] == 0 && iblock->mInstructions[i + 2]->mSIntConst[1] == 0) + { + block->LoadOpStoreIndirectValue(iproc, ins, iblock->mInstructions[i + 1], 0, iblock->mInstructions[i + 2]); + i += 2; + } else if (i + 1 < iblock->mInstructions.Size() && ins->mOperandSize >= 2 && iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR && diff --git a/oscar64/NativeCodeGenerator.h b/oscar64/NativeCodeGenerator.h index ec41f1f..f891aac 100644 --- a/oscar64/NativeCodeGenerator.h +++ b/oscar64/NativeCodeGenerator.h @@ -119,6 +119,8 @@ public: void StoreValue(InterCodeProcedure* proc, const InterInstruction * ins); void LoadValue(InterCodeProcedure* proc, const InterInstruction * ins); void LoadStoreValue(InterCodeProcedure* proc, const InterInstruction * rins, const InterInstruction * wins); + void LoadOpStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* oins, int oindex, const InterInstruction* wins); + void LoadStoreIndirectValue(InterCodeProcedure* proc, const InterInstruction* rins, const InterInstruction* wins); NativeCodeBasicBlock* BinaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0); void UnaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins); void RelationalOperator(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure * nproc, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump); diff --git a/oscar64/NumberSet.h b/oscar64/NumberSet.h index e9b92cd..a66f411 100644 --- a/oscar64/NumberSet.h +++ b/oscar64/NumberSet.h @@ -97,10 +97,14 @@ inline bool FastNumberSet::operator[](int elem) inline FastNumberSet& FastNumberSet::operator+=(int elem) { + assert(elem < size); + uint32 dw = buffer[size + elem]; if (dw >= uint32(num) || buffer[dw] != elem) { + assert(num < size); + buffer[num] = elem; buffer[size + elem] = num; num++; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 5940266..f7fbb41 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -11,6 +11,7 @@ Parser::Parser(Errors* errors, Scanner* scanner, CompilationUnits* compilationUn mCodeSection = compilationUnits->mSectionCode; mDataSection = compilationUnits->mSectionData; + mBSSection = compilationUnits->mSectionBSS; } Parser::~Parser(void) @@ -230,8 +231,8 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags) case TK_ENUM: { dec = new Declaration(mScanner->mLocation, DT_TYPE_ENUM); - dec->mFlags = flags | DTF_SIGNED; - dec->mSize = 2; + dec->mFlags = flags; + dec->mSize = 1; mScanner->NextToken(); if (mScanner->mToken == TK_IDENT) @@ -271,6 +272,10 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags) mErrors->Error(mScanner->mLocation, EERR_CONSTANT_TYPE, "Integer constant expected"); } cdec->mInteger = nitem++; + if (dec->mInteger < 0) + dec->mFlags |= DTF_SIGNED; + if (cdec->mInteger < -128 || cdec->mInteger > 127) + dec->mSize = 2; if (mScanner->mToken == TK_COMMA) mScanner->NextToken(); @@ -340,7 +345,7 @@ Declaration* Parser::ParsePostfixDeclaration(void) { dec = new Declaration(mScanner->mLocation, DT_VARIABLE); dec->mIdent = mScanner->mTokenIdent; - dec->mSection = mDataSection; + dec->mSection = mBSSection; dec->mBase = nullptr; mScanner->NextToken(); } @@ -795,6 +800,8 @@ Declaration* Parser::ParseDeclaration(bool variable) { mScanner->NextToken(); ndec->mValue = ParseInitExpression(ndec->mBase); + if (ndec->mFlags & DTF_GLOBAL) + ndec->mSection = mDataSection; ndec->mSize = ndec->mBase->mSize; } } diff --git a/oscar64/Parser.h b/oscar64/Parser.h index e1c0629..19f1a29 100644 --- a/oscar64/Parser.h +++ b/oscar64/Parser.h @@ -14,7 +14,7 @@ public: int mLocalIndex; CompilationUnits * mCompilationUnits; - LinkerSection * mCodeSection, * mDataSection; + LinkerSection * mCodeSection, * mDataSection, * mBSSection; void Parse(void); protected: