Add long integer support in native and byte code

This commit is contained in:
drmortalwombat 2021-10-02 17:22:18 +02:00
parent 3d9302c90c
commit 30becb541e
19 changed files with 1823 additions and 89 deletions

View File

@ -27,14 +27,12 @@ After four weeks, the compiler has now matured significantly. There are still s
### Language ### Language
* No long integer
* No struct function return * No struct function return
* Missing const checks for structs and enums * Missing const checks for structs and enums
* Missing warnings for all kind of abuses * Missing warnings for all kind of abuses
### Linker ### Linker
* No explicit sections for code, data bss or stack
* No media file import * No media file import
### Standard Libraries ### Standard Libraries
@ -49,9 +47,7 @@ After four weeks, the compiler has now matured significantly. There are still s
### Optimizing ### Optimizing
* All global variables are considered volatile
* Simple loop opmtimization * Simple loop opmtimization
* Poor bookeeping of callee saved registers
* Partial block domination analysis * Partial block domination analysis
* No register use for arguments * No register use for arguments
* Auto variables placed on fixed stack for known call sequence * Auto variables placed on fixed stack for known call sequence
@ -74,13 +70,15 @@ The compiler is command line driven, and creates an executable .prg file.
* -i : additional include paths * -i : additional include paths
* -o : optional output file name * -o : optional output file name
* -cr : alternative runtime library, replaces the crt.c * -rt : alternative runtime library, replaces the crt.c
* -e : execute the result in the integrated emulator * -e : execute the result in the integrated emulator
* -n : create pure native code for all functions * -n : create pure native code for all functions
* -d : define a symbol (e.g. NOFLOAT to avoid float code in printf) * -d : define a symbol (e.g. NOFLOAT or NOLONG to avoid float/long code in printf)
A list of source files can be provided. A list of source files can be provided.
## Implementation Details ## Implementation Details
The compiler does a full program compile, the linker step is part of the compilation. It knows all functions during the compilation run and includes only reachable code in the output. Source files are added to the build with the help of a pragma: The compiler does a full program compile, the linker step is part of the compilation. It knows all functions during the compilation run and includes only reachable code in the output. Source files are added to the build with the help of a pragma:

View File

@ -12,6 +12,12 @@ if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n testint16.c ..\release\oscar64 -e -n testint16.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -e testint32.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n testint32.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e recursiontest.c ..\release\oscar64 -e recursiontest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
@ -78,6 +84,12 @@ if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n testint16cmp.c ..\release\oscar64 -e -n testint16cmp.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error
..\release\oscar64 -e testint32cmp.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n testint32cmp.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e floatstringtest.c ..\release\oscar64 -e floatstringtest.c
if %errorlevel% neq 0 goto :error if %errorlevel% neq 0 goto :error

View File

@ -149,6 +149,82 @@ void shr16n(unsigned xu, int xi)
#pragma native(shl16n) #pragma native(shl16n)
#pragma native(shr16n) #pragma native(shr16n)
void shl32b(unsigned long xu, long xi)
{
unsigned long ua[32];
long ia[32];
#assign s 0
#repeat
ua[s] = xu << s;
ia[s] = xi << s;
#assign s s + 1
#until s == 32
for(int i=0; i<32; i++)
{
assert(ua[i] == xu << i);
assert(ia[i] == xi << i);
}
}
void shr32b(unsigned long xu, long xi)
{
unsigned long ua[32];
long ia[32];
#assign s 0
#repeat
ua[s] = xu >> s;
ia[s] = xi >> s;
#assign s s + 1
#until s == 32
for(int i=0; i<32; i++)
{
assert(ua[i] == xu >> i);
assert(ia[i] == xi >> i);
}
}
void shl32n(unsigned long xu, long xi)
{
unsigned long ua[32];
long ia[32];
#assign s 0
#repeat
ua[s] = xu << s;
ia[s] = xi << s;
#assign s s + 1
#until s == 32
for(int i=0; i<32; i++)
{
assert(ua[i] == xu << i);
assert(ia[i] == xi << i);
}
}
void shr32n(unsigned long xu, long xi)
{
unsigned long ua[32];
long ia[32];
#assign s 0
#repeat
ua[s] = xu >> s;
ia[s] = xi >> s;
#assign s s + 1
#until s == 32
for(int i=0; i<32; i++)
{
assert(ua[i] == xu >> i);
assert(ia[i] == xi >> i);
}
}
#pragma native(shl32n)
#pragma native(shr32n)
int main(void) int main(void)
{ {
for(int i=0; i<32; i++) for(int i=0; i<32; i++)
@ -192,5 +268,25 @@ int main(void)
shr16n(0x1234, 0x1234); shr16n(0x1234, 0x1234);
shr16n(0xfedc, 0xfedc); shr16n(0xfedc, 0xfedc);
shl32b(0x00000000UL, 0x00000000L);
shl32b(0xffffffffUL, 0xffffffffL);
shl32b(0x12345678UL, 0x12345678L);
shl32b(0xfedcba98UL, 0xfedcba98L);
shr32b(0x00000000UL, 0x00000000L);
shr32b(0xffffffffUL, 0xffffffffL);
shr32b(0x12345678UL, 0x12345678L);
shr32b(0xfedcba98UL, 0xfedcba98L);
shl32n(0x00000000UL, 0x00000000L);
shl32n(0xffffffffUL, 0xffffffffL);
shl32n(0x12345678UL, 0x12345678L);
shl32n(0xfedcba98UL, 0xfedcba98L);
shr32n(0x00000000UL, 0x00000000L);
shr32n(0xffffffffUL, 0xffffffffL);
shr32n(0x12345678UL, 0x12345678L);
shr32n(0xfedcba98UL, 0xfedcba98L);
return 0; return 0;
} }

123
autotest/testint32.c Normal file
View File

@ -0,0 +1,123 @@
#include <assert.h>
void testmuli(long a, long b, long ab)
{
assert (a * b == ab);
}
void testdivi(long a, long b, long ab)
{
assert (a / b == ab);
}
void shltesti(long a, long b, long ab)
{
assert (a << b == ab);
}
void shrtesti(long a, long b, long ab)
{
assert (a >> b == ab);
}
long sieve(long size)
{
bool sieve[1000];
for(long i=0; i<size; i+=2)
{
sieve[i] = false;
sieve[i+1] = true;
}
sieve[2] = true;
for (long i = 3; i * i < size;)
{
long j = i * i;
while (j < size)
{
sieve[j] = false;
j += 2 * i;
}
do {i++;} while (i < size && !sieve[i]);
}
long num = 0;
for(long i=0; i<size; i++)
{
if (sieve[i])
num++;
}
return num;
}
int main(void)
{
testmuli(0, 0, 0);
testmuli(1, 0, 0);
testmuli(0, 1, 0);
testmuli( 1, 1, 1);
testmuli(-1, 1, -1);
testmuli(-1, -1, 1);
testmuli( 1, -1, -1);
testmuli(5, 5, 25);
testmuli( 127, 255, 32385);
testmuli(-127, 255, -32385);
testmuli( 127, -255, -32385);
testmuli(-127, -255, 32385);
testdivi( 1, 1, 1);
testdivi(-1, 1, -1);
testdivi( 1, -1, -1);
testdivi(-1, -1, 1);
testdivi( 11, 4, 2);
testdivi(-11, 4, -2);
testdivi( 11, -4, -2);
testdivi(-11, -4, 2);
shltesti( 17, 1, 34);
shltesti(-17, 1, -34);
shltesti( 1700, 1, 3400);
shltesti(-1700, 1, -3400);
shrtesti( 34, 1, 17);
shrtesti(-34, 1, -17);
shrtesti( 3400, 1, 1700);
shrtesti(-3400, 1, -1700);
shrtesti( -1, 15, -1);
shrtesti(32767, 15, 0);
shrtesti( -1, 14, -1);
shrtesti(32767, 14, 1);
shltesti( -1, 14, -16384);
shltesti( 1, 14, 16384);
assert(sieve(200) == 47);
assert(sieve(1000) == 169);
long a = 0, b = 0;
for(long i=0; i<10000; i++)
{
assert( 177 * i == a);
assert(-177 * i == b);
a += 177;
b -= 177;
}
long c = 0, d = 0;
for(long i=0; i<177; i++)
{
assert( 10000 * i == c);
assert(-10000 * i == d);
c += 10000;
d -= 10000;
}
return 0;
}

340
autotest/testint32cmp.c Normal file
View File

@ -0,0 +1,340 @@
#include <stdio.h>
#include <assert.h>
bool beq(long a, long b)
{
return a == b;
}
bool blt(long a, long b)
{
return a < b;
}
bool bgt(long a, long b)
{
return a > b;
}
bool ble(long a, long b)
{
return a <= b;
}
bool bge(long a, long b)
{
return a >= b;
}
bool neq(long a, long b)
{
return a == b;
}
#pragma native(neq)
bool nlt(long a, long b)
{
return a < b;
}
#pragma native(nlt)
bool ngt(long a, long b)
{
return a > b;
}
#pragma native(ngt)
bool nle(long a, long b)
{
return a <= b;
}
#pragma native(nle)
bool nge(long a, long b)
{
return a >= b;
}
#pragma native(nge)
bool beqz(long a)
{
return a == 0;
}
bool bltz(long a)
{
return a < 0;
}
bool bgtz(long a)
{
return a > 0;
}
bool blez(long a)
{
return a <= 0;
}
bool bgez(long a)
{
return a >= 0;
}
bool neqz(long a)
{
return a == 0;
}
#pragma native(neqz)
bool nltz(long a)
{
return a < 0;
}
#pragma native(nltz)
bool ngtz(long a)
{
return a > 0;
}
#pragma native(ngtz)
bool nlez(long a)
{
return a <= 0;
}
#pragma native(nlez)
bool ngez(long a)
{
return a >= 0;
}
#pragma native(ngez)
bool beq1(long a)
{
return a == 1;
}
bool blt1(long a)
{
return a < 1;
}
bool bgt1(long a)
{
return a > 1;
}
bool ble1(long a)
{
return a <= 1;
}
bool bge1(long a)
{
return a >= 1;
}
bool neq1(long a)
{
return a == 1;
}
#pragma native(neq1)
bool nlt1(long a)
{
return a < 1;
}
#pragma native(nlt1)
bool ngt1(long a)
{
return a > 1;
}
#pragma native(ngt1)
bool nle1(long a)
{
return a <= 1;
}
#pragma native(nle1)
bool nge1(long a)
{
return a >= 1;
}
#pragma native(nge1)
void cmp(long a, long b)
{
bool beqf = beq(a, b), bltf = blt(a, b), bgtf = bgt(a, b), blef = ble(a, b), bgef = bge(a, b);
bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nle(a, b), ngef = nge(a, b);
printf("BYTE %ld, %ld : EQ %d LT %d GT %d\r", a, b, beqf, bltf, bgtf);
printf("NATIVE %ld, %ld : EQ %d LT %d GT %d\r", a, b, neqf, nltf, ngtf);
assert(beqf == neqf);
assert(bltf == nltf);
assert(bgtf == ngtf);
assert(blef == nlef);
assert(bgef == ngef);
}
void cmpz(long a)
{
bool beqf = beqz(a), bltf = bltz(a), bgtf = bgtz(a), blef = blez(a), bgef = bgez(a);
bool neqf = neqz(a), nltf = nltz(a), ngtf = ngtz(a), nlef = nlez(a), ngef = ngez(a);
printf("BYTE %ld, 0 : EQ %d LT %d GT %d\r", a, beqf, bltf, bgtf);
printf("NATIVE %ld, 0 : EQ %d LT %d GT %d\r", a, neqf, nltf, ngtf);
assert(beqf == neqf);
assert(bltf == nltf);
assert(bgtf == ngtf);
assert(blef == nlef);
assert(bgef == ngef);
}
void cmp1(long a)
{
bool beqf = beq1(a), bltf = blt1(a), bgtf = bgt1(a), blef = ble1(a), bgef = bge1(a);
bool neqf = neq1(a), nltf = nlt1(a), ngtf = ngt1(a), nlef = nle1(a), ngef = nge1(a);
printf("BYTE %ld, 1 : EQ %d LT %d GT %d LE %d GE %d\r", a, beqf, bltf, bgtf, blef, bgef);
printf("NATIVE %ld, 1 : EQ %d LT %d GT %d LE %d GE %d\r", a, neqf, nltf, ngtf, nlef, ngef);
assert(beqf == neqf);
assert(bltf == nltf);
assert(bgtf == ngtf);
assert(blef == nlef);
assert(bgef == ngef);
}
int main(void)
{
cmp( 0, 1);
cmp( 0, -1);
cmp( 1, 0);
cmp(-1, 0);
cmp(1, 1);
cmp(1, 2);
cmp(2, 1);
cmp(-1, -1);
cmp(-1, -2);
cmp(-2, -1);
cmp( 1, -1);
cmp( 1, -2);
cmp( 2, -1);
cmp(-1, 1);
cmp(-1, 2);
cmp(-2, 1);
cmp( 0, 10000);
cmp( 0, -10000);
cmp( 10000, 0);
cmp(-10000, 0);
cmp(10000, 10000);
cmp(10000, 20000);
cmp(20000, 10000);
cmp(-10000, -10000);
cmp(-10000, -20000);
cmp(-20000, -10000);
cmp( 10000, -10000);
cmp( 10000, -20000);
cmp( 20000, -10000);
cmp(-10000, 10000);
cmp(-10000, 20000);
cmp(-20000, 10000);
cmp( 10000000L, -10000000L);
cmp( 10000000L, -20000000L);
cmp( 20000000L, -10000000L);
cmp(-10000000L, 10000000L);
cmp(-10000000L, 20000000L);
cmp(-20000000L, 10000000L);
cmp( 0, 1024);
cmp( 0, -1024);
cmp( 1024, 0);
cmp(-1024, 0);
cmp(1024, 1024);
cmp(1024, 1025);
cmp(1025, 1024);
cmp(-1024, -1024);
cmp(-1024, -1025);
cmp(-1025, -1024);
cmp( 1024, -1024);
cmp( 1024, -1025);
cmp( 1025, -1024);
cmp(-1024, 1024);
cmp(-1024, 1025);
cmp(-1025, 1024);
cmpz(0);
cmpz(1);
cmpz(255);
cmpz(256);
cmpz(10000);
cmpz(20000);
cmpz(-1);
cmpz(-255);
cmpz(-256);
cmpz(-10000);
cmpz(-20000);
cmp1(0);
cmp1(1);
cmp1(2);
cmp1(3);
cmp1(255);
cmp1(256);
cmp1(10000);
cmp1(20000);
cmp1(-1);
cmp1(-2);
cmp1(-3);
cmp1(-255);
cmp1(-256);
cmp1(-10000);
cmp1(-20000);
return 0;
}

View File

@ -114,6 +114,43 @@ __asm negtmp
rts rts
} }
__asm negaccu32
{
sec
lda #0
sbc accu
sta accu
lda #0
sbc accu + 1
sta accu + 1
lda #0
sbc accu + 2
sta accu + 2
lda #0
sbc accu + 3
sta accu + 3
rts
}
__asm negtmp32
{
sec
lda #0
sbc tmp
sta tmp
lda #0
sbc tmp + 1
sta tmp + 1
lda #0
sbc tmp + 2
sta tmp + 2
lda #0
sbc tmp + 3
sta tmp + 3
rts
}
// divide accu by tmp result in accu, remainder in tmp + 2 // divide accu by tmp result in accu, remainder in tmp + 2
__asm divmod __asm divmod
@ -223,6 +260,42 @@ W1: asl accu
rts rts
} }
__asm mul32
{
lda #0
sta tmp + 4
sta tmp + 5
sta tmp + 6
sta tmp + 7
ldx #32
L1: lsr tmp + 3
ror tmp + 2
ror tmp + 1
ror tmp + 0
bcc W1
clc
lda tmp + 4
adc accu
sta tmp + 4
lda tmp + 5
adc accu + 1
sta tmp + 5
lda tmp + 6
adc accu + 2
sta tmp + 6
lda tmp + 7
adc accu + 3
sta tmp + 7
W1: asl accu
rol accu + 1
rol accu + 2
rol accu + 3
dex
bne L1
rts
}
__asm mul16by8 __asm mul16by8
{ {
lda #0 lda #0
@ -290,6 +363,51 @@ L2: jsr divmod
rts rts
} }
__asm divs32
{
bit accu + 3
bpl L1
jsr negaccu32
bit tmp + 3
bpl L2
jsr negtmp32
L3: jmp divmod32
L1: bit tmp + 3
bpl L3
jsr negtmp32
L2: jsr divmod32
jmp negaccu32
}
__asm mods32
{
bit accu + 3
bpl L1
jsr negaccu32
bit tmp + 3
bpl L2
jsr negtmp32
L3: jmp divmod32
L1: bit tmp + 3
bpl L3
jsr negtmp32
L2: jsr divmod32
sec
lda #0
sbc tmp + 4
sta tmp + 4
lda #0
sbc tmp + 5
sta tmp + 5
lda #0
sbc tmp + 6
sta tmp + 6
lda #0
sbc tmp + 7
sta tmp + 7
rts
}
#pragma runtime(mul16, mul16); #pragma runtime(mul16, mul16);
#pragma runtime(mul16by8, mul16by8); #pragma runtime(mul16by8, mul16by8);
#pragma runtime(divu16, divmod); #pragma runtime(divu16, divmod);
@ -297,6 +415,13 @@ L2: jsr divmod
#pragma runtime(divs16, divs16); #pragma runtime(divs16, divs16);
#pragma runtime(mods16, mods16); #pragma runtime(mods16, mods16);
#pragma runtime(mul32, mul32);
#pragma runtime(divu32, divmod32);
#pragma runtime(modu32, divmod32);
#pragma runtime(divs32, divs32);
#pragma runtime(mods32, mods32);
__asm inp_nop __asm inp_nop
{ {
@ -3083,12 +3208,8 @@ __asm inp_op_invert_32
#pragma bytecode(BC_OP_INVERT_32, inp_op_invert_32) #pragma bytecode(BC_OP_INVERT_32, inp_op_invert_32)
__asm inp_op_negate_32
{
jmp negaccu
}
#pragma bytecode(BC_OP_NEGATE_32, inp_op_negate_32) #pragma bytecode(BC_OP_NEGATE_32, negaccu32)
__asm inp_op_addr_32 __asm inp_op_addr_32
@ -3236,42 +3357,6 @@ W1: asl accu
#pragma bytecode(BC_BINOP_MUL_L32, inp_op_mulr_32) #pragma bytecode(BC_BINOP_MUL_L32, inp_op_mulr_32)
__asm negaccu32
{
sec
lda #0
sbc accu
sta accu
lda #0
sbc accu + 1
sta accu + 1
lda #0
sbc accu + 2
sta accu + 2
lda #0
sbc accu + 3
sta accu + 3
rts
}
__asm negtmp32
{
sec
lda #0
sbc tmp
sta tmp
lda #0
sbc tmp + 1
sta tmp + 1
lda #0
sbc tmp + 2
sta tmp + 2
lda #0
sbc tmp + 3
sta tmp + 3
rts
}
__asm inp_binop_div_u32 __asm inp_binop_div_u32
{ {
lda $00, x lda $00, x

View File

@ -157,6 +157,57 @@ int nformi(const sinfo * si, char * str, int v, bool s)
return j; return j;
} }
int nforml(const sinfo * si, char * str, long v, bool s)
{
char * sp = str;
unsigned long u = v;
bool neg = false;
if (s && v < 0)
{
neg = true;
u = -v;
}
char i = 16;
while (u > 0)
{
int c = u % si->base;
if (c >= 10)
c += 'A' - 10;
else
c += '0';
sp[--i] = c;
u /= si->base;
}
char digits = si->precision != 255 ? 16 - si->precision : 15;
while (i > digits)
sp[--i] = '0';
if (si->prefix && si->base == 16)
{
sp[--i] = 'X';
sp[--i] = '0';
}
if (neg)
sp[--i] = '-';
else if (si->sign)
sp[--i] = '+';
while (i > 16 - si->width)
sp[--i] = si->fill;
char j = 0;
while (i < 16)
sp[j++] = sp[i++];
return j;
}
int nformf(const sinfo * si, char * str, float f, char type) int nformf(const sinfo * si, char * str, float f, char type)
{ {
char * sp = str; char * sp = str;
@ -366,6 +417,29 @@ char * sformat(char * buff, const char * fmt, int * fps, bool print)
si.base = 16; si.base = 16;
bi = nformi(&si, bp, *fps++, false); bi = nformi(&si, bp, *fps++, false);
} }
#ifndef NOLONG
else if (c == 'l')
{
long l = *(long *)fps;
fps ++;
fps ++;
c = *p++;
if (c == 'd')
{
bi = nforml(&si, bp, l, true);
}
else if (c == 'u')
{
bi = nforml(&si, bp, l, false);
}
else if (c == 'x')
{
si.base = 16;
bi = nforml(&si, bp, l, false);
}
}
#endif
#ifndef NOFLOAT #ifndef NOFLOAT
else if (c == 'f' || c == 'g' || c == 'e') else if (c == 'f' || c == 'g' || c == 'e')
{ {

View File

@ -2919,7 +2919,7 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p
case IC_RETURN_VALUE: case IC_RETURN_VALUE:
if (ins->mSTemp[0] < 0) if (ins->mSTemp[0] < 0)
IntConstToAccu(ins->mSIntConst[0]); IntConstToAccu(ins->mSIntConst[0]);
else if (ins->mSType[0] == IT_FLOAT) else if (ins->mSType[0] == IT_FLOAT || ins->mSType[0] == IT_INT32)
{ {
ByteCodeInstruction lins(BC_LOAD_REG_32); ByteCodeInstruction lins(BC_LOAD_REG_32);
lins.mRegister = BC_REG_TMP + iproc->mTempOffset[ins->mSTemp[0]]; lins.mRegister = BC_REG_TMP + iproc->mTempOffset[ins->mSTemp[0]];

View File

@ -182,6 +182,11 @@ bool Compiler::GenerateCode(void)
RegisterRuntime(loc, Ident::Unique("ffromi")); RegisterRuntime(loc, Ident::Unique("ffromi"));
RegisterRuntime(loc, Ident::Unique("fcmp")); RegisterRuntime(loc, Ident::Unique("fcmp"));
RegisterRuntime(loc, Ident::Unique("bcexec")); RegisterRuntime(loc, Ident::Unique("bcexec"));
RegisterRuntime(loc, Ident::Unique("mul32"));
RegisterRuntime(loc, Ident::Unique("divs32"));
RegisterRuntime(loc, Ident::Unique("mods32"));
RegisterRuntime(loc, Ident::Unique("divu32"));
RegisterRuntime(loc, Ident::Unique("modu32"));
// Register extended byte code functions // Register extended byte code functions

View File

@ -160,10 +160,13 @@ Expression* Expression::ConstantFold(void)
{ {
Expression* ex = new Expression(mLocation, EX_CONSTANT); Expression* ex = new Expression(mLocation, EX_CONSTANT);
Declaration * dec = new Declaration(mLocation, DT_CONST_INTEGER); Declaration * dec = new Declaration(mLocation, DT_CONST_INTEGER);
dec->mBase = TheSignedIntTypeDeclaration; if (mLeft->mDecValue->mBase->mSize <= 2)
dec->mBase = TheSignedIntTypeDeclaration;
else
dec->mBase = TheSignedLongTypeDeclaration;
dec->mInteger = - mLeft->mDecValue->mInteger; dec->mInteger = - mLeft->mDecValue->mInteger;
ex->mDecValue = dec; ex->mDecValue = dec;
ex->mDecType = TheSignedIntTypeDeclaration; ex->mDecType = dec->mBase;
return ex; return ex;
} }
case TK_BINARY_NOT: case TK_BINARY_NOT:
@ -286,7 +289,10 @@ Expression* Expression::ConstantFold(void)
Expression* ex = new Expression(mLocation, EX_CONSTANT); Expression* ex = new Expression(mLocation, EX_CONSTANT);
Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER); Declaration* dec = new Declaration(mLocation, DT_CONST_INTEGER);
dec->mBase = ival < 32768 ? TheSignedIntTypeDeclaration : TheUnsignedIntTypeDeclaration; if (mLeft->mDecValue->mBase->mSize <= 2 && mRight->mDecValue->mBase->mSize <= 2)
dec->mBase = ival < 32768 ? TheSignedIntTypeDeclaration : TheUnsignedIntTypeDeclaration;
else
dec->mBase = ival < 2147483648 ? TheSignedLongTypeDeclaration : TheUnsignedLongTypeDeclaration;
dec->mInteger = ival; dec->mInteger = ival;
ex->mDecValue = dec; ex->mDecValue = dec;
ex->mDecType = dec->mBase; ex->mDecType = dec->mBase;

View File

@ -2,6 +2,7 @@
#include "ByteCodeGenerator.h" #include "ByteCodeGenerator.h"
#include "Assembler.h" #include "Assembler.h"
#include "InterCode.h" #include "InterCode.h"
#include "Linker.h"
ByteCodeDisassembler::ByteCodeDisassembler(void) ByteCodeDisassembler::ByteCodeDisassembler(void)
{ {
@ -37,7 +38,20 @@ const char* ByteCodeDisassembler::TempName(uint8 tmp, char* buffer, InterCodePro
} }
} }
void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident) const char* ByteCodeDisassembler::AddrName(int addr, char* buffer, Linker* linker)
{
if (linker)
{
LinkerObject* obj = linker->FindObjectByAddr(addr);
if (obj && obj->mIdent)
return obj->mIdent->mString;
}
sprintf_s(buffer, 10, "$%04x", addr);
return buffer;
}
void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker)
{ {
fprintf(file, "--------------------------------------------------------------------\n"); fprintf(file, "--------------------------------------------------------------------\n");
if (proc && proc->mIdent) if (proc && proc->mIdent)
@ -45,7 +59,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]; char tbuffer[10], abuffer[10];
#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]);
@ -118,41 +132,41 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star
break; break;
case BC_LOAD_ABS_8: case BC_LOAD_ABS_8:
fprintf(file, "MOVUB\t%s, $%04x", TempName(memory[start + i + 2], tbuffer, proc), uint16(memory[start + i + 0] + 256 * memory[start + i + 1])); fprintf(file, "MOVUB\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3; i += 3;
break; break;
case BC_LOAD_ABS_U8: case BC_LOAD_ABS_U8:
fprintf(file, "MOVUB\t%s, $%04x", TempName(memory[start + i + 2], tbuffer, proc), uint16(memory[start + i + 0] + 256 * memory[start + i + 1])); fprintf(file, "MOVUB\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3; i += 3;
break; break;
case BC_LOAD_ABS_I8: case BC_LOAD_ABS_I8:
fprintf(file, "MOVSB\t%s, $%04x", TempName(memory[start + i + 2], tbuffer, proc), uint16(memory[start + i + 0] + 256 * memory[start + i + 1])); fprintf(file, "MOVSB\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3; i += 3;
break; break;
case BC_LOAD_ABS_16: case BC_LOAD_ABS_16:
fprintf(file, "MOV\t%s, $%04x", TempName(memory[start + i + 2], tbuffer, proc), uint16(memory[start + i + 0] + 256 * memory[start + i + 1])); fprintf(file, "MOV\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3; i += 3;
break; break;
case BC_LOAD_ABS_32: case BC_LOAD_ABS_32:
fprintf(file, "MOVD\t%s, $%04x", TempName(memory[start + i + 2], tbuffer, proc), uint16(memory[start + i + 0] + 256 * memory[start + i + 1])); fprintf(file, "MOVD\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3; i += 3;
break; break;
case BC_LEA_ABS: case BC_LEA_ABS:
fprintf(file, "LEA\t%s, $%04x", TempName(memory[start + i + 0], tbuffer, proc), uint16(memory[start + i + 1] + 256 * memory[start + i + 2])); fprintf(file, "LEA\t%s, %s", TempName(memory[start + i + 0], tbuffer, proc), AddrName(uint16(memory[start + i + 1] + 256 * memory[start + i + 2]), abuffer, linker));
i += 3; i += 3;
break; break;
case BC_STORE_ABS_8: case BC_STORE_ABS_8:
fprintf(file, "MOVB\t$%04x, %s", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), TempName(memory[start + i + 2], tbuffer, proc)); fprintf(file, "MOVB\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc));
i += 3; i += 3;
break; break;
case BC_STORE_ABS_16: case BC_STORE_ABS_16:
fprintf(file, "MOV\t$%04x, %s", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), TempName(memory[start + i + 2], tbuffer, proc)); fprintf(file, "MOV\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc));
i += 3; i += 3;
break; break;
case BC_STORE_ABS_32: case BC_STORE_ABS_32:
fprintf(file, "MOVD\t$%04x, %s", uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), TempName(memory[start + i + 2], tbuffer, proc)); fprintf(file, "MOVD\t%s, %s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker), TempName(memory[start + i + 2], tbuffer, proc));
i += 3; i += 3;
break; break;
@ -490,7 +504,7 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star
fprintf(file, "CALL"); fprintf(file, "CALL");
break; break;
case BC_JSR: case BC_JSR:
fprintf(file, "JSR\t$%04x", uint16(memory[start + i + 0] + 256 * memory[start + i + 1])); fprintf(file, "JSR\t%s", AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 2; i += 2;
break; break;
@ -539,7 +553,7 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star
break; break;
case BC_EXTRT: case BC_EXTRT:
fprintf(file, "EXTRT\t%s, %08x", TempName(memory[start + i + 2], tbuffer, proc), uint16(memory[start + i + 0] + 256 * memory[start + i + 1])); fprintf(file, "EXTRT\t%s, %s", TempName(memory[start + i + 2], tbuffer, proc), AddrName(uint16(memory[start + i + 0] + 256 * memory[start + i + 1]), abuffer, linker));
i += 3; i += 3;
break; break;
} }
@ -559,7 +573,7 @@ NativeCodeDisassembler::~NativeCodeDisassembler(void)
} }
void NativeCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident * ident) void NativeCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident * ident, Linker* linker)
{ {
fprintf(file, "--------------------------------------------------------------------\n"); fprintf(file, "--------------------------------------------------------------------\n");
if (proc && proc->mIdent) if (proc && proc->mIdent)

View File

@ -6,6 +6,7 @@
class ByteCodeGenerator; class ByteCodeGenerator;
class InterCodeProcedure; class InterCodeProcedure;
class Linker;
class ByteCodeDisassembler class ByteCodeDisassembler
{ {
@ -13,9 +14,10 @@ public:
ByteCodeDisassembler(void); ByteCodeDisassembler(void);
~ByteCodeDisassembler(void); ~ByteCodeDisassembler(void);
void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident); void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker * linker);
protected: protected:
const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc); const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc);
const char* AddrName(int addr, char* buffer, Linker* linker);
}; };
class NativeCodeDisassembler class NativeCodeDisassembler
@ -24,7 +26,7 @@ public:
NativeCodeDisassembler(void); NativeCodeDisassembler(void);
~NativeCodeDisassembler(void); ~NativeCodeDisassembler(void);
void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident); void Disassemble(FILE* file, const uint8* memory, int start, int size, InterCodeProcedure* proc, const Ident* ident, Linker* linker);
protected: protected:
const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc); const char* TempName(uint8 tmp, char* buffer, InterCodeProcedure* proc);
}; };

View File

@ -22,9 +22,9 @@ void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const char
} }
if (info) if (info)
printf("%s(%d, %d) : error %d: %s '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, eid, msg, info); printf("%s(%d, %d) : %s %d: %s '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level ,eid, msg, info);
else else
printf("%s(%d, %d) : error %d: %s\n", loc.mFileName, loc.mLine, loc.mColumn, eid, msg); printf("%s(%d, %d) : %s %d: %s\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg);
if (mErrorCount > 10) if (mErrorCount > 10)
exit(10); exit(10);

View File

@ -530,7 +530,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ins->mTTemp = proc->AddTemporary(ins->mTType); ins->mTTemp = proc->AddTemporary(ins->mTType);
if (ins->mTType == IT_INT8) if (ins->mTType == IT_INT8)
{ {
if (dec->mFlags & DTF_SIGNED) if (dec->mBase->mFlags & DTF_SIGNED)
{ {
if (dec->mInteger < -128 || dec->mInteger > 127) if (dec->mInteger < -128 || dec->mInteger > 127)
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated"); mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
@ -545,7 +545,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
} }
else if (ins->mTType == IT_INT16) else if (ins->mTType == IT_INT16)
{ {
if (dec->mFlags & DTF_SIGNED) if (dec->mBase->mFlags & DTF_SIGNED)
{ {
if (dec->mInteger < -32768 || dec->mInteger > 32767) if (dec->mInteger < -32768 || dec->mInteger > 32767)
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated"); mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");
@ -560,7 +560,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
} }
else if (ins->mTType == IT_INT32) else if (ins->mTType == IT_INT32)
{ {
if (dec->mFlags & DTF_SIGNED) if (dec->mBase->mFlags & DTF_SIGNED)
{ {
if (dec->mInteger < -2147483648LL || dec->mInteger > 2147483647LL) if (dec->mInteger < -2147483648LL || dec->mInteger > 2147483647LL)
mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated"); mErrors->Error(dec->mLocation, EWARN_CONSTANT_TRUNCATED, "Integer constant truncated");

View File

@ -110,6 +110,21 @@ bool Linker::IsSectionPlaced(LinkerSection* section)
return false; return false;
} }
LinkerObject* Linker::FindObjectByAddr(int addr)
{
for (int i = 0; i < mObjects.Size(); i++)
{
LinkerObject* lobj = mObjects[i];
if (lobj->mFlags & LOBJF_PLACED)
{
if (lobj->mAddress == addr)
return lobj;
}
}
return nullptr;
}
LinkerObject * Linker::AddObject(const Location& location, const Ident* ident, LinkerSection * section, LinkerObjectType type) LinkerObject * Linker::AddObject(const Location& location, const Ident* ident, LinkerSection * section, LinkerObjectType type)
{ {
LinkerObject* obj = new LinkerObject; LinkerObject* obj = new LinkerObject;
@ -353,10 +368,10 @@ bool Linker::WriteAsmFile(const char* filename)
switch (obj->mType) switch (obj->mType)
{ {
case LOT_BYTE_CODE: case LOT_BYTE_CODE:
mByteCodeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent); mByteCodeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this);
break; break;
case LOT_NATIVE_CODE: case LOT_NATIVE_CODE:
mNativeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent); mNativeDisassembler.Disassemble(file, mMemory, obj->mAddress, obj->mSize, obj->mProc, obj->mIdent, this);
break; break;
} }
} }

View File

@ -116,6 +116,8 @@ public:
LinkerSection * AddSection(const Ident* section, LinkerSectionType type); LinkerSection * AddSection(const Ident* section, LinkerSectionType type);
LinkerSection* FindSection(const Ident* section); LinkerSection* FindSection(const Ident* section);
LinkerObject* FindObjectByAddr(int addr);
bool IsSectionPlaced(LinkerSection* section); bool IsSectionPlaced(LinkerSection* section);
LinkerObject * AddObject(const Location & location, const Ident* ident, LinkerSection * section, LinkerObjectType type); LinkerObject * AddObject(const Location & location, const Ident* ident, LinkerSection * section, LinkerObjectType type);

File diff suppressed because it is too large Load Diff

View File

@ -118,7 +118,7 @@ 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 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);
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0); void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction * ins, const InterInstruction* sins1, const InterInstruction* sins0);

View File

@ -1367,13 +1367,27 @@ void Scanner::ParseNumberToken(void)
if (n == 0) if (n == 0)
Error("Missing digits in hex constant"); Error("Missing digits in hex constant");
if (mTokenChar == 'L' || mTokenChar == 'l') if (mTokenChar == 'U' || mTokenChar == 'u')
{ {
NextChar(); NextChar();
mToken = TK_INTEGERUL; if (mTokenChar == 'L' || mTokenChar == 'l')
{
NextChar();
mToken = TK_INTEGERUL;
}
else
mToken = TK_INTEGERU;
} }
else else
mToken = TK_INTEGERU; {
if (mTokenChar == 'L' || mTokenChar == 'l')
{
NextChar();
mToken = TK_INTEGERL;
}
else
mToken = TK_INTEGER;
}
mTokenInteger = mant; mTokenInteger = mant;
} }
@ -1392,13 +1406,27 @@ void Scanner::ParseNumberToken(void)
if (n == 0) if (n == 0)
Error("Missing digits in binary constant"); Error("Missing digits in binary constant");
if (mTokenChar == 'L' || mTokenChar == 'l') if (mTokenChar == 'U' || mTokenChar == 'u')
{ {
NextChar(); NextChar();
mToken = TK_INTEGERUL; if (mTokenChar == 'L' || mTokenChar == 'l')
{
NextChar();
mToken = TK_INTEGERUL;
}
else
mToken = TK_INTEGERU;
} }
else else
mToken = TK_INTEGERU; {
if (mTokenChar == 'L' || mTokenChar == 'l')
{
NextChar();
mToken = TK_INTEGERL;
}
else
mToken = TK_INTEGER;
}
mTokenInteger = mant; mTokenInteger = mant;
} }
else else