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
|
..\release\oscar64 -e -n bitshifttest.c
|
||||||
if %errorlevel% neq 0 goto :error
|
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
|
exit /b 0
|
||||||
:error
|
:error
|
||||||
echo Failed with error #%errorlevel%.
|
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
|
// crt.c
|
||||||
#include <crt.h>
|
#include <crt.h>
|
||||||
|
|
||||||
void StackStart, StackEnd;
|
void StackStart, StackEnd, BSSStart, BSSEnd;
|
||||||
|
|
||||||
#pragma section(stack, 0x0000, StackStart, StackEnd)
|
#pragma section(stack, 0x0000, StackStart, StackEnd)
|
||||||
|
#pragma section(bss, 0x0000, BSSStart, BSSEnd)
|
||||||
|
|
||||||
int main(void);
|
int main(void);
|
||||||
|
|
||||||
|
@ -22,6 +23,40 @@ __asm startup
|
||||||
byt 0x00
|
byt 0x00
|
||||||
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
|
lda #<bcode
|
||||||
sta ip
|
sta ip
|
||||||
lda #>bcode
|
lda #>bcode
|
||||||
|
@ -155,10 +190,67 @@ __asm negtmp32
|
||||||
|
|
||||||
__asm divmod
|
__asm divmod
|
||||||
{
|
{
|
||||||
sty tmpy
|
|
||||||
lda #0
|
lda #0
|
||||||
sta tmp + 2
|
sta tmp + 2
|
||||||
sta tmp + 3
|
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
|
ldy #16
|
||||||
clc
|
clc
|
||||||
L1: rol accu
|
L1: rol accu
|
||||||
|
|
|
@ -1,5 +1,39 @@
|
||||||
#include "string.h"
|
#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 * strcpy(char * dst, const char * src)
|
||||||
{
|
{
|
||||||
char * d = dst;
|
char * d = dst;
|
||||||
|
@ -9,6 +43,7 @@ char * strcpy(char * dst, const char * src)
|
||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int strcmp(const char * ptr1, const char * ptr2)
|
int strcmp(const char * ptr1, const char * ptr2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -326,7 +326,7 @@ int Compiler::ExecuteCode(void)
|
||||||
Location loc;
|
Location loc;
|
||||||
|
|
||||||
printf("Running emulation...\n");
|
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);
|
memcpy(emu->mMemory + mLinker->mProgramStart, mLinker->mMemory + mLinker->mProgramStart, mLinker->mProgramEnd - mLinker->mProgramStart);
|
||||||
emu->mMemory[0x2d] = mLinker->mProgramEnd & 0xff;
|
emu->mMemory[0x2d] = mLinker->mProgramEnd & 0xff;
|
||||||
emu->mMemory[0x2e] = mLinker->mProgramEnd >> 8;
|
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);
|
LinkerObject* obj = linker->FindObjectByAddr(addr);
|
||||||
if (obj && obj->mIdent)
|
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);
|
sprintf_s(buffer, 10, "$%04x", addr);
|
||||||
|
@ -59,7 +62,7 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star
|
||||||
else if (ident)
|
else if (ident)
|
||||||
fprintf(file, "%s:\n", ident->mString);
|
fprintf(file, "%s:\n", ident->mString);
|
||||||
|
|
||||||
char tbuffer[10], abuffer[10];
|
char tbuffer[10], 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]);
|
||||||
|
@ -581,7 +584,7 @@ void NativeCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int st
|
||||||
else if (ident)
|
else if (ident)
|
||||||
fprintf(file, "%s:\n", ident->mString);
|
fprintf(file, "%s:\n", ident->mString);
|
||||||
|
|
||||||
char tbuffer[10], abuffer[10];
|
char tbuffer[10], abuffer[100];
|
||||||
|
|
||||||
int ip = start;
|
int ip = start;
|
||||||
while (ip < start + size)
|
while (ip < start + size)
|
||||||
|
@ -659,7 +662,10 @@ const char* NativeCodeDisassembler::AddrName(int addr, char* buffer, Linker* lin
|
||||||
{
|
{
|
||||||
LinkerObject* obj = linker->FindObjectByAddr(addr);
|
LinkerObject* obj = linker->FindObjectByAddr(addr);
|
||||||
if (obj && obj->mIdent)
|
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);
|
sprintf_s(buffer, 10, "$%04x", addr);
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include "Emulator.h"
|
#include "Emulator.h"
|
||||||
|
#include "Linker.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
Emulator::Emulator(void)
|
Emulator::Emulator(Linker* linker)
|
||||||
|
: mLinker(linker)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 0x10000; i++)
|
for (int i = 0; i < 0x10000; i++)
|
||||||
mMemory[i] = 0;
|
mMemory[i] = 0;
|
||||||
|
@ -40,6 +42,9 @@ void Emulator::DumpCycles(void)
|
||||||
int topIP[101], topCycles[101];
|
int topIP[101], topCycles[101];
|
||||||
|
|
||||||
int totalCycles = 0;
|
int totalCycles = 0;
|
||||||
|
|
||||||
|
GrowingArray<LinkerObject*> lobjs(nullptr);
|
||||||
|
GrowingArray<int> lobjc(0);
|
||||||
|
|
||||||
for (int i = 0; i < 0x10000; i++)
|
for (int i = 0; i < 0x10000; i++)
|
||||||
{
|
{
|
||||||
|
@ -47,10 +52,18 @@ void Emulator::DumpCycles(void)
|
||||||
totalCycles += cycles;
|
totalCycles += cycles;
|
||||||
if (cycles > 0)
|
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;
|
int j = numTops;
|
||||||
while (j > 0 && topCycles[j-1] < cycles)
|
while (j > 0 && topCycles[j-1] < cycles)
|
||||||
{
|
{
|
||||||
|
@ -60,6 +73,9 @@ void Emulator::DumpCycles(void)
|
||||||
}
|
}
|
||||||
topCycles[j] = cycles;
|
topCycles[j] = cycles;
|
||||||
topIP[j] = i;
|
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]);
|
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)
|
bool Emulator::EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, int & cycles)
|
||||||
|
|
|
@ -3,10 +3,12 @@
|
||||||
#include "Assembler.h"
|
#include "Assembler.h"
|
||||||
#include "MachineTypes.h"
|
#include "MachineTypes.h"
|
||||||
|
|
||||||
|
class Linker;
|
||||||
|
|
||||||
class Emulator
|
class Emulator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Emulator(void);
|
Emulator(Linker * linker);
|
||||||
~Emulator(void);
|
~Emulator(void);
|
||||||
|
|
||||||
uint8 mMemory[0x10000];
|
uint8 mMemory[0x10000];
|
||||||
|
@ -15,6 +17,8 @@ public:
|
||||||
int mIP;
|
int mIP;
|
||||||
uint8 mRegA, mRegX, mRegY, mRegS, mRegP;
|
uint8 mRegA, mRegX, mRegY, mRegS, mRegP;
|
||||||
|
|
||||||
|
Linker* mLinker;
|
||||||
|
|
||||||
int Emulate(int startIP);
|
int Emulate(int startIP);
|
||||||
bool EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, int & cycles);
|
bool EmulateInstruction(AsmInsType type, AsmInsMode mode, int addr, int & cycles);
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -1752,21 +1752,21 @@ void InterCodeBasicBlock::GenerateTraces(void)
|
||||||
|
|
||||||
for (;;)
|
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->mNumEntries--;
|
||||||
mTrueJump = mTrueJump->mTrueJump;
|
mTrueJump = mTrueJump->mTrueJump;
|
||||||
if (mTrueJump)
|
if (mTrueJump)
|
||||||
mTrueJump->mNumEntries++;
|
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->mNumEntries--;
|
||||||
mFalseJump = mFalseJump->mTrueJump;
|
mFalseJump = mFalseJump->mTrueJump;
|
||||||
if (mFalseJump)
|
if (mFalseJump)
|
||||||
mFalseJump->mNumEntries++;
|
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--;
|
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;
|
int i;
|
||||||
|
|
||||||
|
@ -2742,12 +2742,169 @@ void InterCodeBasicBlock::PerformValueForwarding(const GrowingInstructionPtrArra
|
||||||
|
|
||||||
for (i = 0; i < mInstructions.Size(); i++)
|
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);
|
lvalues.UpdateValue(mInstructions[i], ltvalue, aliasedLocals, aliasedParams);
|
||||||
mInstructions[i]->PerformValueForwarding(ltvalue, tvalid);
|
mInstructions[i]->PerformValueForwarding(ltvalue, tvalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTrueJump) mTrueJump->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);
|
if (mFalseJump) mFalseJump->PerformValueForwarding(ltvalue, lvalues, tvalid, aliasedLocals, aliasedParams, spareTemps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3198,7 +3355,7 @@ bool IsMoveable(InterCode code)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterCodeBasicBlock::SingleBlockLoopOptimisation(void)
|
void InterCodeBasicBlock::SingleBlockLoopOptimisation(const NumberSet& aliasedParams)
|
||||||
{
|
{
|
||||||
if (!mVisited)
|
if (!mVisited)
|
||||||
{
|
{
|
||||||
|
@ -3228,7 +3385,8 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(void)
|
||||||
{
|
{
|
||||||
if (sins->mSTemp[1] >= 0)
|
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)
|
else if (ins->mMemory == sins->mMemory && ins->mVarIndex == sins->mVarIndex && ins->mLinkerObject == sins->mLinkerObject)
|
||||||
{
|
{
|
||||||
|
@ -3329,9 +3487,9 @@ void InterCodeBasicBlock::SingleBlockLoopOptimisation(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTrueJump)
|
if (mTrueJump)
|
||||||
mTrueJump->SingleBlockLoopOptimisation();
|
mTrueJump->SingleBlockLoopOptimisation(aliasedParams);
|
||||||
if (mFalseJump)
|
if (mFalseJump)
|
||||||
mFalseJump->SingleBlockLoopOptimisation();
|
mFalseJump->SingleBlockLoopOptimisation(aliasedParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3719,7 +3877,10 @@ void InterCodeProcedure::BuildTraces(void)
|
||||||
//
|
//
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
for (int i = 0; i < mBlocks.Size(); i++)
|
for (int i = 0; i < mBlocks.Size(); i++)
|
||||||
|
{
|
||||||
mBlocks[i]->mNumEntries = 0;
|
mBlocks[i]->mNumEntries = 0;
|
||||||
|
mBlocks[i]->mLoopHead = false;
|
||||||
|
}
|
||||||
mEntryBlock->CollectEntries();
|
mEntryBlock->CollectEntries();
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -3936,7 +4097,7 @@ void InterCodeProcedure::Close(void)
|
||||||
mEntryBlock->MarkAliasedLocalTemps(localTable, mLocalAliasedSet, paramTable, mParamAliasedSet);
|
mEntryBlock->MarkAliasedLocalTemps(localTable, mLocalAliasedSet, paramTable, mParamAliasedSet);
|
||||||
|
|
||||||
ValueSet valueSet;
|
ValueSet valueSet;
|
||||||
FastNumberSet tvalidSet(numTemps);
|
FastNumberSet tvalidSet(numTemps + 32);
|
||||||
|
|
||||||
|
|
||||||
bool eliminated;
|
bool eliminated;
|
||||||
|
@ -3946,26 +4107,30 @@ void InterCodeProcedure::Close(void)
|
||||||
do {
|
do {
|
||||||
valueSet.FlushAll();
|
valueSet.FlushAll();
|
||||||
mValueForwardingTable.SetSize(numTemps, true);
|
mValueForwardingTable.SetSize(numTemps, true);
|
||||||
tvalidSet.Clear();
|
tvalidSet.Reset(numTemps + 32);
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet);
|
mEntryBlock->PerformValueForwarding(mValueForwardingTable, valueSet, tvalidSet, mLocalAliasedSet, mParamAliasedSet, numTemps);
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
eliminated = mEntryBlock->EliminateDeadBranches();
|
eliminated = mEntryBlock->EliminateDeadBranches();
|
||||||
if (eliminated)
|
if (eliminated)
|
||||||
{
|
{
|
||||||
|
BuildTraces();
|
||||||
|
/*
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
for (int i = 0; i < mBlocks.Size(); i++)
|
for (int i = 0; i < mBlocks.Size(); i++)
|
||||||
mBlocks[i]->mNumEntries = 0;
|
mBlocks[i]->mNumEntries = 0;
|
||||||
mEntryBlock->CollectEntries();
|
mEntryBlock->CollectEntries();
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
} while (eliminated);
|
} while (eliminated);
|
||||||
|
|
||||||
|
|
||||||
DisassembleDebug("value forwarding");
|
DisassembleDebug("value forwarding");
|
||||||
|
|
||||||
mValueForwardingTable.Clear();
|
mValueForwardingTable.SetSize(numTemps, true);
|
||||||
|
mTemporaries.SetSize(numTemps, true);
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->PerformMachineSpecificValueUsageCheck(mValueForwardingTable, tvalidSet);
|
mEntryBlock->PerformMachineSpecificValueUsageCheck(mValueForwardingTable, tvalidSet);
|
||||||
|
@ -4103,7 +4268,7 @@ void InterCodeProcedure::Close(void)
|
||||||
DisassembleDebug("Peephole optimized");
|
DisassembleDebug("Peephole optimized");
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
mEntryBlock->SingleBlockLoopOptimisation();
|
mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet);
|
||||||
|
|
||||||
DisassembleDebug("single block loop opt");
|
DisassembleDebug("single block loop opt");
|
||||||
|
|
||||||
|
|
|
@ -441,7 +441,7 @@ public:
|
||||||
|
|
||||||
void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue);
|
void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue);
|
||||||
void PerformTempForwarding(TempForwardingTable& forwardingTable);
|
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);
|
void PerformMachineSpecificValueUsageCheck(const GrowingInstructionPtrArray& tvalue, FastNumberSet& tvalid);
|
||||||
bool EliminateDeadBranches(void);
|
bool EliminateDeadBranches(void);
|
||||||
|
|
||||||
|
@ -466,7 +466,7 @@ public:
|
||||||
bool IsLeafProcedure(void);
|
bool IsLeafProcedure(void);
|
||||||
|
|
||||||
void PeepholeOptimization(void);
|
void PeepholeOptimization(void);
|
||||||
void SingleBlockLoopOptimisation(void);
|
void SingleBlockLoopOptimisation(const NumberSet& aliasedParams);
|
||||||
|
|
||||||
InterCodeBasicBlock* PropagateDominator(InterCodeProcedure * proc);
|
InterCodeBasicBlock* PropagateDominator(InterCodeProcedure * proc);
|
||||||
};
|
};
|
||||||
|
@ -495,7 +495,7 @@ public:
|
||||||
InterCodeModule * mModule;
|
InterCodeModule * mModule;
|
||||||
int mID;
|
int mID;
|
||||||
|
|
||||||
int mLocalSize;
|
int mLocalSize, mNumLocals;
|
||||||
GrowingVariableArray mLocalVars;
|
GrowingVariableArray mLocalVars;
|
||||||
|
|
||||||
Location mLocation;
|
Location mLocation;
|
||||||
|
|
|
@ -732,7 +732,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
ins->mVarIndex = dec->mVarIndex;
|
ins->mVarIndex = dec->mVarIndex;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (inlineMapper)
|
||||||
|
ins->mVarIndex += inlineMapper->mVarIndex;
|
||||||
|
|
||||||
ins->mMemory = IM_LOCAL;
|
ins->mMemory = IM_LOCAL;
|
||||||
|
}
|
||||||
|
|
||||||
block->Append(ins);
|
block->Append(ins);
|
||||||
|
|
||||||
|
@ -1547,6 +1552,8 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
InlineMapper nmapper;
|
InlineMapper nmapper;
|
||||||
nmapper.mReturn = new InterCodeBasicBlock();
|
nmapper.mReturn = new InterCodeBasicBlock();
|
||||||
|
nmapper.mVarIndex = proc->mNumLocals;
|
||||||
|
proc->mNumLocals += fdec->mNumVars;
|
||||||
if (inlineMapper)
|
if (inlineMapper)
|
||||||
nmapper.mDepth = inlineMapper->mDepth + 1;
|
nmapper.mDepth = inlineMapper->mDepth + 1;
|
||||||
proc->Append(nmapper.mReturn);
|
proc->Append(nmapper.mReturn);
|
||||||
|
@ -1555,7 +1562,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
Expression* pex = exp->mRight;
|
Expression* pex = exp->mRight;
|
||||||
while (pex)
|
while (pex)
|
||||||
{
|
{
|
||||||
int nindex = fdec->mNumVars++;
|
int nindex = proc->mNumLocals++;
|
||||||
Declaration* vdec = new Declaration(pex->mLocation, DT_VARIABLE);
|
Declaration* vdec = new Declaration(pex->mLocation, DT_VARIABLE);
|
||||||
|
|
||||||
InterInstruction* ains = new InterInstruction();
|
InterInstruction* ains = new InterInstruction();
|
||||||
|
@ -1571,7 +1578,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
vdec->mVarIndex = nindex;
|
vdec->mVarIndex = nindex;
|
||||||
vdec->mBase = pdec->mBase;
|
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;
|
vdec->mIdent = pdec->mIdent;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1621,7 +1632,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
wins->mSType[1] = IT_POINTER;
|
wins->mSType[1] = IT_POINTER;
|
||||||
wins->mSTemp[1] = ains->mTTemp;
|
wins->mSTemp[1] = ains->mTTemp;
|
||||||
if (pdec)
|
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)
|
else if (vr.mType->mSize > 2 && vr.mType->mType != DT_TYPE_ARRAY)
|
||||||
wins->mOperandSize = vr.mType->mSize;
|
wins->mOperandSize = vr.mType->mSize;
|
||||||
else
|
else
|
||||||
|
@ -1638,7 +1654,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
Declaration* rdec = nullptr;
|
Declaration* rdec = nullptr;
|
||||||
if (ftype->mBase->mType != DT_TYPE_VOID)
|
if (ftype->mBase->mType != DT_TYPE_VOID)
|
||||||
{
|
{
|
||||||
int nindex = fdec->mNumVars++;
|
int nindex = proc->mNumLocals++;
|
||||||
nmapper.mResult = nindex;
|
nmapper.mResult = nindex;
|
||||||
|
|
||||||
rdec = new Declaration(ftype->mLocation, DT_VARIABLE);
|
rdec = new Declaration(ftype->mLocation, DT_VARIABLE);
|
||||||
|
@ -1647,7 +1663,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
rdec->mSize = rdec->mBase->mSize;
|
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();
|
InterInstruction* jins = new InterInstruction();
|
||||||
jins->mCode = IC_JUMP;
|
jins->mCode = IC_JUMP;
|
||||||
|
@ -1924,7 +1940,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
ins->mCode = IC_RETURN;
|
ins->mCode = IC_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
block->Append(ins);
|
if (ins->mCode != IC_NONE)
|
||||||
|
block->Append(ins);
|
||||||
|
|
||||||
if (inlineMapper)
|
if (inlineMapper)
|
||||||
{
|
{
|
||||||
InterInstruction* jins = new InterInstruction();
|
InterInstruction* jins = new InterInstruction();
|
||||||
|
@ -2144,9 +2162,50 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EX_LOGICAL_AND:
|
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:
|
case EX_WHILE:
|
||||||
{
|
{
|
||||||
InterInstruction * jins0 = new InterInstruction();
|
InterInstruction * jins0 = new InterInstruction();
|
||||||
|
@ -2553,6 +2612,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
||||||
|
|
||||||
dec->mVarIndex = proc->mID;
|
dec->mVarIndex = proc->mID;
|
||||||
dec->mLinkerObject = proc->mLinkerObject;
|
dec->mLinkerObject = proc->mLinkerObject;
|
||||||
|
proc->mNumLocals = dec->mNumVars;
|
||||||
|
|
||||||
if (mForceNativeCode)
|
if (mForceNativeCode)
|
||||||
dec->mFlags |= DTF_NATIVE;
|
dec->mFlags |= DTF_NATIVE;
|
||||||
|
|
|
@ -34,7 +34,7 @@ protected:
|
||||||
{
|
{
|
||||||
GrowingArray<int> mParams;
|
GrowingArray<int> mParams;
|
||||||
InterCodeBasicBlock * mReturn;
|
InterCodeBasicBlock * mReturn;
|
||||||
int mResult, mDepth;
|
int mResult, mDepth, mVarIndex;
|
||||||
|
|
||||||
InlineMapper(void)
|
InlineMapper(void)
|
||||||
: mParams(-1), mResult(-1), mDepth(0)
|
: mParams(-1), mResult(-1), mDepth(0)
|
||||||
|
|
|
@ -61,6 +61,7 @@ LinkerRegion* Linker::AddRegion(const Ident* region, int start, int end)
|
||||||
lrgn->mStart = start;
|
lrgn->mStart = start;
|
||||||
lrgn->mEnd = end;
|
lrgn->mEnd = end;
|
||||||
lrgn->mUsed = 0;
|
lrgn->mUsed = 0;
|
||||||
|
lrgn->mNonzero = 0;
|
||||||
mRegions.Push(lrgn);
|
mRegions.Push(lrgn);
|
||||||
return lrgn;
|
return lrgn;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +118,7 @@ LinkerObject* Linker::FindObjectByAddr(int addr)
|
||||||
LinkerObject* lobj = mObjects[i];
|
LinkerObject* lobj = mObjects[i];
|
||||||
if (lobj->mFlags & LOBJF_PLACED)
|
if (lobj->mFlags & LOBJF_PLACED)
|
||||||
{
|
{
|
||||||
if (lobj->mAddress == addr)
|
if (addr >= lobj->mAddress && addr < lobj->mAddress + lobj->mSize)
|
||||||
return lobj;
|
return lobj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,6 +196,9 @@ void Linker::Link(void)
|
||||||
lobj->mAddress = lrgn->mStart + lrgn->mUsed;
|
lobj->mAddress = lrgn->mStart + lrgn->mUsed;
|
||||||
lrgn->mUsed += lobj->mSize;
|
lrgn->mUsed += lobj->mSize;
|
||||||
|
|
||||||
|
if (lsec->mType == LST_DATA)
|
||||||
|
lrgn->mNonzero = lrgn->mUsed;
|
||||||
|
|
||||||
if (lobj->mAddress < lsec->mStart)
|
if (lobj->mAddress < lsec->mStart)
|
||||||
lsec->mStart = lobj->mAddress;
|
lsec->mStart = lobj->mAddress;
|
||||||
if (lobj->mAddress + lobj->mSize > lsec->mEnd)
|
if (lobj->mAddress + lobj->mSize > lsec->mEnd)
|
||||||
|
@ -212,9 +216,9 @@ void Linker::Link(void)
|
||||||
for (int i = 0; i < mRegions.Size(); i++)
|
for (int i = 0; i < mRegions.Size(); i++)
|
||||||
{
|
{
|
||||||
LinkerRegion* lrgn = mRegions[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;
|
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++)
|
for (int i = 0; i < mRegions.Size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -309,6 +313,14 @@ static const char * LinkerObjectTypeNames[] =
|
||||||
"END"
|
"END"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char* LinkerSectionTypeNames[] = {
|
||||||
|
"NONE",
|
||||||
|
"DATA",
|
||||||
|
"BSS",
|
||||||
|
"HEAP",
|
||||||
|
"STACK"
|
||||||
|
};
|
||||||
|
|
||||||
bool Linker::WritePrgFile(const char* filename)
|
bool Linker::WritePrgFile(const char* filename)
|
||||||
{
|
{
|
||||||
FILE* file;
|
FILE* file;
|
||||||
|
@ -332,6 +344,25 @@ bool Linker::WriteMapFile(const char* filename)
|
||||||
fopen_s(&file, filename, "wb");
|
fopen_s(&file, filename, "wb");
|
||||||
if (file)
|
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++)
|
for (int i = 0; i < mObjects.Size(); i++)
|
||||||
{
|
{
|
||||||
LinkerObject* obj = mObjects[i];
|
LinkerObject* obj = mObjects[i];
|
||||||
|
|
|
@ -41,7 +41,7 @@ class LinkerRegion
|
||||||
public:
|
public:
|
||||||
const Ident* mIdent;
|
const Ident* mIdent;
|
||||||
|
|
||||||
int mStart, mEnd, mUsed;
|
int mStart, mEnd, mUsed, mNonzero;
|
||||||
|
|
||||||
GrowingArray<LinkerSection*> mSections;
|
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)
|
void NativeCodeBasicBlock::LoadStoreValue(InterCodeProcedure* proc, const InterInstruction * rins, const InterInstruction * wins)
|
||||||
{
|
{
|
||||||
if (rins->mTType == IT_FLOAT)
|
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)
|
void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterInstruction * ins, int reg, const NativeCodeInstruction* ainsl, const NativeCodeInstruction* ainsh)
|
||||||
{
|
{
|
||||||
if (ins->mTType == IT_FLOAT)
|
if (ins->mTType == IT_FLOAT)
|
||||||
|
@ -5100,13 +5159,14 @@ void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, NativeCod
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case IA_EXT8TO16S:
|
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]]));
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]));
|
||||||
if (ins->mSTemp[0] != ins->mTTemp)
|
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_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp]));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, 1));
|
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0x00));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 1));
|
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;
|
break;
|
||||||
case IA_EXT8TO16U:
|
case IA_EXT8TO16U:
|
||||||
if (ins->mSTemp[0] != ins->mTTemp)
|
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));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 1));
|
||||||
break;
|
break;
|
||||||
case IA_EXT16TO32S:
|
case IA_EXT16TO32S:
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, 0));
|
|
||||||
if (ins->mSTemp[0] != ins->mTTemp)
|
if (ins->mSTemp[0] != ins->mTTemp)
|
||||||
{
|
{
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]]));
|
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));
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSTemp[0]] + 1));
|
||||||
if (ins->mSTemp[0] != ins->mTTemp)
|
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_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 1));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, 1));
|
mIns.Push(NativeCodeInstruction(ASMIT_ASL, ASMIM_IMPLIED));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0x00));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 2));
|
mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0xff));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mTTemp] + 3));
|
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;
|
break;
|
||||||
case IA_EXT16TO32U:
|
case IA_EXT16TO32U:
|
||||||
if (ins->mSTemp[0] != ins->mTTemp)
|
if (ins->mSTemp[0] != ins->mTTemp)
|
||||||
|
@ -7940,6 +8001,44 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
|
||||||
block->LoadStoreValue(iproc, ins, iblock->mInstructions[i + 1]);
|
block->LoadStoreValue(iproc, ins, iblock->mInstructions[i + 1]);
|
||||||
i++;
|
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() &&
|
else if (i + 1 < iblock->mInstructions.Size() &&
|
||||||
ins->mOperandSize >= 2 &&
|
ins->mOperandSize >= 2 &&
|
||||||
iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR &&
|
iblock->mInstructions[i + 1]->mCode == IC_BINARY_OPERATOR &&
|
||||||
|
|
|
@ -119,6 +119,8 @@ public:
|
||||||
void StoreValue(InterCodeProcedure* proc, const InterInstruction * ins);
|
void StoreValue(InterCodeProcedure* proc, const InterInstruction * ins);
|
||||||
void LoadValue(InterCodeProcedure* proc, const InterInstruction * ins);
|
void LoadValue(InterCodeProcedure* proc, const InterInstruction * ins);
|
||||||
void LoadStoreValue(InterCodeProcedure* proc, const InterInstruction * rins, const InterInstruction * wins);
|
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);
|
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 UnaryOperator(InterCodeProcedure* proc, NativeCodeProcedure* nproc, const InterInstruction * ins);
|
||||||
void RelationalOperator(InterCodeProcedure* proc, const InterInstruction * ins, NativeCodeProcedure * nproc, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump);
|
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)
|
inline FastNumberSet& FastNumberSet::operator+=(int elem)
|
||||||
{
|
{
|
||||||
|
assert(elem < size);
|
||||||
|
|
||||||
uint32 dw = buffer[size + elem];
|
uint32 dw = buffer[size + elem];
|
||||||
|
|
||||||
if (dw >= uint32(num) || buffer[dw] != elem)
|
if (dw >= uint32(num) || buffer[dw] != elem)
|
||||||
{
|
{
|
||||||
|
assert(num < size);
|
||||||
|
|
||||||
buffer[num] = elem;
|
buffer[num] = elem;
|
||||||
buffer[size + elem] = num;
|
buffer[size + elem] = num;
|
||||||
num++;
|
num++;
|
||||||
|
|
|
@ -11,6 +11,7 @@ Parser::Parser(Errors* errors, Scanner* scanner, CompilationUnits* compilationUn
|
||||||
|
|
||||||
mCodeSection = compilationUnits->mSectionCode;
|
mCodeSection = compilationUnits->mSectionCode;
|
||||||
mDataSection = compilationUnits->mSectionData;
|
mDataSection = compilationUnits->mSectionData;
|
||||||
|
mBSSection = compilationUnits->mSectionBSS;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::~Parser(void)
|
Parser::~Parser(void)
|
||||||
|
@ -230,8 +231,8 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
|
||||||
case TK_ENUM:
|
case TK_ENUM:
|
||||||
{
|
{
|
||||||
dec = new Declaration(mScanner->mLocation, DT_TYPE_ENUM);
|
dec = new Declaration(mScanner->mLocation, DT_TYPE_ENUM);
|
||||||
dec->mFlags = flags | DTF_SIGNED;
|
dec->mFlags = flags;
|
||||||
dec->mSize = 2;
|
dec->mSize = 1;
|
||||||
|
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
if (mScanner->mToken == TK_IDENT)
|
if (mScanner->mToken == TK_IDENT)
|
||||||
|
@ -271,6 +272,10 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
|
||||||
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_TYPE, "Integer constant expected");
|
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_TYPE, "Integer constant expected");
|
||||||
}
|
}
|
||||||
cdec->mInteger = nitem++;
|
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)
|
if (mScanner->mToken == TK_COMMA)
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
|
@ -340,7 +345,7 @@ Declaration* Parser::ParsePostfixDeclaration(void)
|
||||||
{
|
{
|
||||||
dec = new Declaration(mScanner->mLocation, DT_VARIABLE);
|
dec = new Declaration(mScanner->mLocation, DT_VARIABLE);
|
||||||
dec->mIdent = mScanner->mTokenIdent;
|
dec->mIdent = mScanner->mTokenIdent;
|
||||||
dec->mSection = mDataSection;
|
dec->mSection = mBSSection;
|
||||||
dec->mBase = nullptr;
|
dec->mBase = nullptr;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
}
|
}
|
||||||
|
@ -795,6 +800,8 @@ Declaration* Parser::ParseDeclaration(bool variable)
|
||||||
{
|
{
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
ndec->mValue = ParseInitExpression(ndec->mBase);
|
ndec->mValue = ParseInitExpression(ndec->mBase);
|
||||||
|
if (ndec->mFlags & DTF_GLOBAL)
|
||||||
|
ndec->mSection = mDataSection;
|
||||||
ndec->mSize = ndec->mBase->mSize;
|
ndec->mSize = ndec->mBase->mSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ public:
|
||||||
int mLocalIndex;
|
int mLocalIndex;
|
||||||
CompilationUnits * mCompilationUnits;
|
CompilationUnits * mCompilationUnits;
|
||||||
|
|
||||||
LinkerSection * mCodeSection, * mDataSection;
|
LinkerSection * mCodeSection, * mDataSection, * mBSSection;
|
||||||
|
|
||||||
void Parse(void);
|
void Parse(void);
|
||||||
protected:
|
protected:
|
||||||
|
|
Loading…
Reference in New Issue