Exclude bss segment from prg file
This commit is contained in:
parent
9618762234
commit
330e022a43
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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%.
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
|
||||
void copyi(int * a, int * b, int n)
|
||||
{
|
||||
for(int i=0; i<n; i++)
|
||||
b[i] = a[i];
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int t[100], s[100];
|
||||
for(int i=0; i<100; i++)
|
||||
s[i] = i;
|
||||
copyi(s, t, 100);
|
||||
int sum = 0;
|
||||
for(int i=0; i<100; i++)
|
||||
sum += t[i];
|
||||
|
||||
return sum - 4950;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#include <assert.h>
|
||||
|
||||
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<i; j*=3)
|
||||
{
|
||||
unsigned q = i / j, r = i % j;
|
||||
|
||||
assert(q * j + r == i);
|
||||
assert(r >= 0 && r < j);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
|
||||
void incv(int * a, int n)
|
||||
{
|
||||
for(int i=0; i<n; i++)
|
||||
a[i] ++;
|
||||
}
|
||||
|
||||
int t[100];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
for(int i=0; i<100; i++)
|
||||
t[i] = i;
|
||||
incv(t, 100);
|
||||
int s = 0;
|
||||
for(int i=0; i<100; i++)
|
||||
s += t[i];
|
||||
|
||||
return s - 5050;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
struct A
|
||||
{
|
||||
int x;
|
||||
struct B
|
||||
{
|
||||
int m;
|
||||
struct C
|
||||
{
|
||||
int w;
|
||||
} c;
|
||||
} b;
|
||||
} q;
|
||||
|
||||
int test(A * a)
|
||||
{
|
||||
a->b.c.w = 1;
|
||||
return a->b.c.w;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return test(&q) - 1;
|
||||
}
|
||||
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
// crt.c
|
||||
#include <crt.h>
|
||||
|
||||
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
|
||||
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 #<BSSEnd
|
||||
sbc #<BSSStart
|
||||
beq w2
|
||||
tay
|
||||
lda #0
|
||||
l2: dey
|
||||
sta (ip), y
|
||||
bne l2
|
||||
w2:
|
||||
|
||||
// Init byte code
|
||||
|
||||
lda #<bcode
|
||||
sta ip
|
||||
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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#include "Emulator.h"
|
||||
#include "Linker.h"
|
||||
#include <stdio.h>
|
||||
|
||||
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<LinkerObject*> lobjs(nullptr);
|
||||
GrowingArray<int> 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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -34,7 +34,7 @@ protected:
|
|||
{
|
||||
GrowingArray<int> mParams;
|
||||
InterCodeBasicBlock * mReturn;
|
||||
int mResult, mDepth;
|
||||
int mResult, mDepth, mVarIndex;
|
||||
|
||||
InlineMapper(void)
|
||||
: mParams(-1), mResult(-1), mDepth(0)
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -41,7 +41,7 @@ class LinkerRegion
|
|||
public:
|
||||
const Ident* mIdent;
|
||||
|
||||
int mStart, mEnd, mUsed;
|
||||
int mStart, mEnd, mUsed, mNonzero;
|
||||
|
||||
GrowingArray<LinkerSection*> mSections;
|
||||
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ public:
|
|||
int mLocalIndex;
|
||||
CompilationUnits * mCompilationUnits;
|
||||
|
||||
LinkerSection * mCodeSection, * mDataSection;
|
||||
LinkerSection * mCodeSection, * mDataSection, * mBSSection;
|
||||
|
||||
void Parse(void);
|
||||
protected:
|
||||
|
|
Loading…
Reference in New Issue