More native code generator
This commit is contained in:
parent
07f797e577
commit
93b6aca8a3
13
README.md
13
README.md
|
@ -51,6 +51,7 @@ The first release of the compiler is severely limited considering it is only two
|
||||||
* Missing livetime reduction of intermediates
|
* Missing livetime reduction of intermediates
|
||||||
* No block domination analysis
|
* No block domination analysis
|
||||||
* No register use for arguments
|
* No register use for arguments
|
||||||
|
* Auto variables places on fixed stack for known call sequence
|
||||||
|
|
||||||
### Intermediate code generation
|
### Intermediate code generation
|
||||||
|
|
||||||
|
@ -59,7 +60,8 @@ The first release of the compiler is severely limited considering it is only two
|
||||||
|
|
||||||
### Native code generation
|
### Native code generation
|
||||||
|
|
||||||
* Missing
|
* Calling non native functions missing
|
||||||
|
* More byte operation optimisation required
|
||||||
|
|
||||||
## Implementation Details
|
## Implementation Details
|
||||||
|
|
||||||
|
@ -109,6 +111,15 @@ The intermediate code generator assumes a large number of registers so the zero
|
||||||
* **0x43-0x52** caller saved registers
|
* **0x43-0x52** caller saved registers
|
||||||
* **0x53-0x8f** callee saved registers
|
* **0x53-0x8f** callee saved registers
|
||||||
|
|
||||||
|
Routines can be marked to be compiled to 6502 machine code with the native pragma:
|
||||||
|
|
||||||
|
void Plot(int x, int y)
|
||||||
|
{
|
||||||
|
(*Bitmap)[y >> 3][x >> 3][y & 7] |= 0x80 >> (x & 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma native(Plot)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,9 @@ if %errorlevel% neq 0 goto :error
|
||||||
..\release\oscar64 -i=../include -rt=../include/crt.c -e testint16cmp.c
|
..\release\oscar64 -i=../include -rt=../include/crt.c -e testint16cmp.c
|
||||||
if %errorlevel% neq 0 goto :error
|
if %errorlevel% neq 0 goto :error
|
||||||
|
|
||||||
|
..\release\oscar64 -i=../include -rt=../include/crt.c -e floatstringtest.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,94 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
unsigned shl1b(int n)
|
||||||
|
{
|
||||||
|
return 1 << n;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned shl1n(int n)
|
||||||
|
{
|
||||||
|
return 1 << n;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma native(shl1n)
|
||||||
|
|
||||||
|
unsigned shr1b(int n)
|
||||||
|
{
|
||||||
|
return 0x8000 >> n;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned shr1n(int n)
|
||||||
|
{
|
||||||
|
return 0x8000 >> n;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma native(shr1n)
|
||||||
|
|
||||||
|
unsigned shl4b(int n)
|
||||||
|
{
|
||||||
|
return 0x0010 << n;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned shl4n(int n)
|
||||||
|
{
|
||||||
|
return 0x0010 << n;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma native(shl4n)
|
||||||
|
|
||||||
|
unsigned shr4b(int n)
|
||||||
|
{
|
||||||
|
return 0x0800 >> n;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned shr4n(int n)
|
||||||
|
{
|
||||||
|
return 0x0800 >> n;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma native(shr4n)
|
||||||
|
|
||||||
|
|
||||||
|
unsigned shl8b(int n)
|
||||||
|
{
|
||||||
|
return 0x0100 << n;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned shl8n(int n)
|
||||||
|
{
|
||||||
|
return 0x0100 << n;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma native(shl8n)
|
||||||
|
|
||||||
|
unsigned shr8b(int n)
|
||||||
|
{
|
||||||
|
return 0x0080 >> n;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned shr8n(int n)
|
||||||
|
{
|
||||||
|
return 0x0080 >> n;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma native(shr8n)
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
for(int i=0; i<32; i++)
|
||||||
|
{
|
||||||
|
printf("1: %.4x : %.4x | %.4x : %.4x\n", shl1b(i), shl1n(i), shr1b(i), shr1n(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<32; i++)
|
||||||
|
{
|
||||||
|
printf("4: %.4x : %.4x | %.4x : %.4x\n", shl4b(i), shl4n(i), shr4b(i), shr4n(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<32; i++)
|
||||||
|
{
|
||||||
|
printf("8: %.4x : %.4x | %.4x : %.4x\n", shl8b(i), shl8n(i), shr8b(i), shr8n(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
float x = 1.0, y = 1.0;
|
||||||
|
|
||||||
|
char xb[20], yb[20];
|
||||||
|
for(int i=0; i<40; i++)
|
||||||
|
{
|
||||||
|
ftoa(x, xb); float xr = atof(xb);
|
||||||
|
ftoa(y, yb); float yr = atof(yb);
|
||||||
|
|
||||||
|
// printf("%20g (%s) %20g : %20g (%s) %20g : %10f %10f \n", x, xb, xr, y, yb, y, fabs(x - xr) / x, fabs(y - yr) / y);
|
||||||
|
|
||||||
|
if (fabs(x - xr) / x > 0.00001 || fabs(y - yr) / y > 0.00001)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
x *= 2.5;
|
||||||
|
y *= 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -295,6 +295,30 @@ P1:
|
||||||
}
|
}
|
||||||
#pragma bytecode(BC_JSR, inp_jsr)
|
#pragma bytecode(BC_JSR, inp_jsr)
|
||||||
|
|
||||||
|
__asm inp_native
|
||||||
|
{
|
||||||
|
tya
|
||||||
|
clc
|
||||||
|
adc ip
|
||||||
|
sta P1 + 1
|
||||||
|
lda ip + 1
|
||||||
|
adc #0
|
||||||
|
sta P1 + 2
|
||||||
|
P1:
|
||||||
|
jsr $0000
|
||||||
|
|
||||||
|
ldy #0
|
||||||
|
lda (sp), y
|
||||||
|
sta ip
|
||||||
|
iny
|
||||||
|
lda (sp), y
|
||||||
|
sta ip + 1
|
||||||
|
dey
|
||||||
|
jmp startup.exec
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_NATIVE, inp_native)
|
||||||
|
|
||||||
__asm inp_const_p8
|
__asm inp_const_p8
|
||||||
{
|
{
|
||||||
lda (ip), y
|
lda (ip), y
|
||||||
|
@ -2532,6 +2556,18 @@ __asm inp_op_abs_f32
|
||||||
|
|
||||||
unsigned char ubitmask[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
|
unsigned char ubitmask[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
|
||||||
|
|
||||||
|
unsigned char bitshift[56] = {
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma runtime(bitshift, bitshift)
|
||||||
|
|
||||||
__asm fround {
|
__asm fround {
|
||||||
ffloor:
|
ffloor:
|
||||||
bit accu + 3
|
bit accu + 3
|
||||||
|
|
|
@ -145,7 +145,9 @@ enum ByteCode
|
||||||
BC_JSR,
|
BC_JSR,
|
||||||
|
|
||||||
BC_COPY,
|
BC_COPY,
|
||||||
BC_COPY_LONG
|
BC_COPY_LONG,
|
||||||
|
|
||||||
|
BC_NATIVE = 0x75
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma compile("crt.c")
|
#pragma compile("crt.c")
|
||||||
|
|
|
@ -176,7 +176,7 @@ float log10(float f)
|
||||||
|
|
||||||
float pow(float p, float q)
|
float pow(float p, float q)
|
||||||
{
|
{
|
||||||
return exp(p * log(q));
|
return exp(q * log(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
float sqrt(float f)
|
float sqrt(float f)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "stdlib.h"
|
#include "stdlib.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
void itoa(int n, char * s, int radix)
|
void itoa(int n, char * s, int radix)
|
||||||
{
|
{
|
||||||
|
@ -164,6 +165,90 @@ int atoi(const char * s)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float tpow10[7] = {1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0};
|
||||||
|
|
||||||
|
float atof(const char * s)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
while ((c = *s++) <= ' ')
|
||||||
|
if (!c) return 0;
|
||||||
|
|
||||||
|
bool neg = false;
|
||||||
|
if (c == '-')
|
||||||
|
{
|
||||||
|
neg = true;
|
||||||
|
c = *s++;
|
||||||
|
}
|
||||||
|
else if (c == '+')
|
||||||
|
c = *s++;
|
||||||
|
|
||||||
|
float v = 0;
|
||||||
|
while (c >= '0' && c <= '9')
|
||||||
|
{
|
||||||
|
v = v * 10 + (c - '0');
|
||||||
|
c = *s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '.')
|
||||||
|
{
|
||||||
|
float d = 1.0;
|
||||||
|
c = *s++;
|
||||||
|
while (c >= '0' && c <= '9')
|
||||||
|
{
|
||||||
|
v = v * 10 + (c - '0');
|
||||||
|
d = d * 10;
|
||||||
|
c = *s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
v /= d;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == 'e' || c == 'E')
|
||||||
|
{
|
||||||
|
c = *s++;
|
||||||
|
bool eneg = false;
|
||||||
|
if (c == '-')
|
||||||
|
{
|
||||||
|
eneg = true;
|
||||||
|
c = *s++;
|
||||||
|
}
|
||||||
|
else if (c == '+')
|
||||||
|
c = *s++;
|
||||||
|
|
||||||
|
int e = 0;
|
||||||
|
while (c >= '0' && c <= '9')
|
||||||
|
{
|
||||||
|
e = e * 10 + (c - '0');
|
||||||
|
c = *s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eneg)
|
||||||
|
{
|
||||||
|
while (e > 6)
|
||||||
|
{
|
||||||
|
v /= 1000000.0;
|
||||||
|
e -= 6;
|
||||||
|
}
|
||||||
|
v /= tpow10[e];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (e > 6)
|
||||||
|
{
|
||||||
|
v *= 1000000.0;
|
||||||
|
e -= 6;
|
||||||
|
}
|
||||||
|
v *= tpow10[e];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (neg)
|
||||||
|
v = -v;
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
void exit(int status)
|
void exit(int status)
|
||||||
{
|
{
|
||||||
__asm {
|
__asm {
|
||||||
|
|
|
@ -9,6 +9,8 @@ void ftoa(float f, char * s);
|
||||||
|
|
||||||
int atoi(const char * s);
|
int atoi(const char * s);
|
||||||
|
|
||||||
|
float atof(const char * s);
|
||||||
|
|
||||||
void exit(int status);
|
void exit(int status);
|
||||||
|
|
||||||
void * malloc(unsigned int size);
|
void * malloc(unsigned int size);
|
||||||
|
|
|
@ -1556,6 +1556,7 @@ void ByteCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInst
|
||||||
bins.mRelocate = true;
|
bins.mRelocate = true;
|
||||||
bins.mVIndex = ins.mVarIndex;
|
bins.mVIndex = ins.mVarIndex;
|
||||||
bins.mFunction = ins.mMemory == IM_PROCEDURE;
|
bins.mFunction = ins.mMemory == IM_PROCEDURE;
|
||||||
|
bins.mValue = ins.mSIntConst[0];
|
||||||
mIns.Push(bins);
|
mIns.Push(bins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3546,51 +3547,51 @@ void ByteCodeGenerator::WriteAsmFile(FILE * file, Address & addr)
|
||||||
switch (d.mMode)
|
switch (d.mMode)
|
||||||
{
|
{
|
||||||
case ASMIM_IMPLIED:
|
case ASMIM_IMPLIED:
|
||||||
fprintf(file, "%04x : %02x __ __ %s\n", iip, mMemory[ip], AsmInstructionNames[d.mType]);
|
fprintf(file, "%04x : %02x __ __ %s\n", iip, mMemory[iip], AsmInstructionNames[d.mType]);
|
||||||
break;
|
break;
|
||||||
case ASMIM_IMMEDIATE:
|
case ASMIM_IMMEDIATE:
|
||||||
addr = mMemory[ip++];
|
addr = mMemory[ip++];
|
||||||
fprintf(file, "%04x : %02x %02x __ %s #$%02x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
fprintf(file, "%04x : %02x %02x __ %s #$%02x\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
|
||||||
break;
|
break;
|
||||||
case ASMIM_ZERO_PAGE:
|
case ASMIM_ZERO_PAGE:
|
||||||
addr = mMemory[ip++];
|
addr = mMemory[ip++];
|
||||||
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
|
||||||
break;
|
break;
|
||||||
case ASMIM_ZERO_PAGE_X:
|
case ASMIM_ZERO_PAGE_X:
|
||||||
addr = mMemory[ip++];
|
addr = mMemory[ip++];
|
||||||
fprintf(file, "%04x : %02x %02x __ %s $%02x,x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
fprintf(file, "%04x : %02x %02x __ %s $%02x,x\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
|
||||||
break;
|
break;
|
||||||
case ASMIM_ZERO_PAGE_Y:
|
case ASMIM_ZERO_PAGE_Y:
|
||||||
addr = mMemory[ip++];
|
addr = mMemory[ip++];
|
||||||
fprintf(file, "%04x : %02x %02x __ %s $%02x,y\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
fprintf(file, "%04x : %02x %02x __ %s $%02x,y\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
|
||||||
break;
|
break;
|
||||||
case ASMIM_ABSOLUTE:
|
case ASMIM_ABSOLUTE:
|
||||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||||
fprintf(file, "%04x : %02x %02x %02x %s $%04x\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
fprintf(file, "%04x : %02x %02x %02x %s $%04x\n", iip, mMemory[iip], mMemory[iip + 1], mMemory[iip + 2], AsmInstructionNames[d.mType], addr);
|
||||||
ip += 2;
|
ip += 2;
|
||||||
break;
|
break;
|
||||||
case ASMIM_ABSOLUTE_X:
|
case ASMIM_ABSOLUTE_X:
|
||||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||||
fprintf(file, "%04x : %02x %02x %02x %s $%04x,x\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
fprintf(file, "%04x : %02x %02x %02x %s $%04x,x\n", iip, mMemory[iip], mMemory[iip + 1], mMemory[iip + 2], AsmInstructionNames[d.mType], addr);
|
||||||
ip += 2;
|
ip += 2;
|
||||||
break;
|
break;
|
||||||
case ASMIM_ABSOLUTE_Y:
|
case ASMIM_ABSOLUTE_Y:
|
||||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||||
fprintf(file, "%04x : %02x %02x %02x %s $%04x,y\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
fprintf(file, "%04x : %02x %02x %02x %s $%04x,y\n", iip, mMemory[iip], mMemory[iip + 1], mMemory[iip + 2], AsmInstructionNames[d.mType], addr);
|
||||||
ip += 2;
|
ip += 2;
|
||||||
break;
|
break;
|
||||||
case ASMIM_INDIRECT:
|
case ASMIM_INDIRECT:
|
||||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||||
ip += 2;
|
ip += 2;
|
||||||
fprintf(file, "%04x : %02x %02x %02x %s ($%04x)\n", iip, mMemory[ip], mMemory[ip + 1], mMemory[ip + 2], AsmInstructionNames[d.mType], addr);
|
fprintf(file, "%04x : %02x %02x %02x %s ($%04x)\n", iip, mMemory[iip], mMemory[iip + 1], mMemory[iip + 2], AsmInstructionNames[d.mType], addr);
|
||||||
break;
|
break;
|
||||||
case ASMIM_INDIRECT_X:
|
case ASMIM_INDIRECT_X:
|
||||||
addr = mMemory[ip++];
|
addr = mMemory[ip++];
|
||||||
fprintf(file, "%04x : %02x %02x __ %s ($%02x,x)\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
fprintf(file, "%04x : %02x %02x __ %s ($%02x,x)\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
|
||||||
break;
|
break;
|
||||||
case ASMIM_INDIRECT_Y:
|
case ASMIM_INDIRECT_Y:
|
||||||
addr = mMemory[ip++];
|
addr = mMemory[ip++];
|
||||||
fprintf(file, "%04x : %02x %02x __ %s ($%02x),y\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
fprintf(file, "%04x : %02x %02x __ %s ($%02x),y\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
|
||||||
break;
|
break;
|
||||||
case ASMIM_RELATIVE:
|
case ASMIM_RELATIVE:
|
||||||
addr = mMemory[ip++];
|
addr = mMemory[ip++];
|
||||||
|
@ -3598,7 +3599,7 @@ void ByteCodeGenerator::WriteAsmFile(FILE * file, Address & addr)
|
||||||
addr = addr + ip - 256;
|
addr = addr + ip - 256;
|
||||||
else
|
else
|
||||||
addr = addr + ip;
|
addr = addr + ip;
|
||||||
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, mMemory[ip], mMemory[ip + 1], AsmInstructionNames[d.mType], addr);
|
fprintf(file, "%04x : %02x %02x __ %s $%02x\n", iip, mMemory[iip], mMemory[iip + 1], AsmInstructionNames[d.mType], addr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,9 @@ enum ByteCode
|
||||||
BC_JSR,
|
BC_JSR,
|
||||||
|
|
||||||
BC_COPY,
|
BC_COPY,
|
||||||
BC_COPY_LONG
|
BC_COPY_LONG,
|
||||||
|
|
||||||
|
BC_NATIVE = 0x75
|
||||||
};
|
};
|
||||||
|
|
||||||
class ByteCodeProcedure;
|
class ByteCodeProcedure;
|
||||||
|
|
|
@ -143,7 +143,13 @@ bool Compiler::GenerateCode(void)
|
||||||
index = bcdec->mBase->mVarIndex;
|
index = bcdec->mBase->mVarIndex;
|
||||||
offset = bcdec->mInteger;
|
offset = bcdec->mInteger;
|
||||||
}
|
}
|
||||||
|
else if (bcdec->mType == DT_VARIABLE)
|
||||||
|
{
|
||||||
|
if (bcdec->mBase->mVarIndex < 0)
|
||||||
|
mInterCodeGenerator->InitGlobalVariable(mInterCodeModule, bcdec);
|
||||||
|
index = bcdec->mVarIndex;
|
||||||
|
offset = bcdec->mOffset + mByteCodeGenerator->mRelocations[i].mOffset;
|
||||||
|
}
|
||||||
assert(index > 0);
|
assert(index > 0);
|
||||||
mInterCodeModule->UseGlobal(index);
|
mInterCodeModule->UseGlobal(index);
|
||||||
|
|
||||||
|
|
|
@ -1593,6 +1593,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
|
||||||
ins.mMemory = tvalue[ins.mSTemp[0]]->mMemory;
|
ins.mMemory = tvalue[ins.mSTemp[0]]->mMemory;
|
||||||
ins.mVarIndex = tvalue[ins.mSTemp[0]]->mVarIndex;
|
ins.mVarIndex = tvalue[ins.mSTemp[0]]->mVarIndex;
|
||||||
ins.mOperandSize = tvalue[ins.mSTemp[0]]->mOperandSize;
|
ins.mOperandSize = tvalue[ins.mSTemp[0]]->mOperandSize;
|
||||||
|
ins.mSIntConst[0] = tvalue[ins.mSTemp[0]]->mIntValue;
|
||||||
ins.mSTemp[0] = -1;
|
ins.mSTemp[0] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2708,6 +2709,9 @@ static bool CanBypassStore(const InterInstruction& sins, const InterInstruction&
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sins.mMemory == IM_FRAME && (bins.mCode == IC_PUSH_FRAME || bins.mCode == IC_POP_FRAME))
|
||||||
|
return false;
|
||||||
|
|
||||||
// Side effects
|
// Side effects
|
||||||
if (bins.mCode == IC_CALL || bins.mCode == IC_JSR)
|
if (bins.mCode == IC_CALL || bins.mCode == IC_JSR)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -341,9 +341,17 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
ins.mTType = InterTypeOf(dec->mBase);
|
ins.mTType = InterTypeOf(dec->mBase);
|
||||||
ins.mTTemp = proc->AddTemporary(ins.mTType);
|
ins.mTTemp = proc->AddTemporary(ins.mTType);
|
||||||
if (ins.mTType == IT_SIGNED)
|
if (ins.mTType == IT_SIGNED)
|
||||||
|
{
|
||||||
|
if (dec->mInteger < -32768 || dec->mInteger > 32767)
|
||||||
|
mErrors->Warning(dec->mLocation, "Integer constant truncated");
|
||||||
ins.mIntValue = short(dec->mInteger);
|
ins.mIntValue = short(dec->mInteger);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (dec->mInteger < 0 || dec->mInteger > 65535)
|
||||||
|
mErrors->Warning(dec->mLocation, "Unsigned integer constant truncated");
|
||||||
ins.mIntValue = unsigned short(dec->mInteger);
|
ins.mIntValue = unsigned short(dec->mInteger);
|
||||||
|
}
|
||||||
block->Append(ins);
|
block->Append(ins);
|
||||||
return ExValue(dec->mBase, ins.mTTemp);
|
return ExValue(dec->mBase, ins.mTTemp);
|
||||||
|
|
||||||
|
@ -597,32 +605,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (vll.mType->IsIntegerType() && vr.mType->mType == DT_TYPE_FLOAT)
|
vr = CoerceType(proc, block, vr, vll.mType);
|
||||||
{
|
|
||||||
InterInstruction cins;
|
|
||||||
cins.mCode = IC_CONVERSION_OPERATOR;
|
|
||||||
cins.mOperator = IA_FLOAT2INT;
|
|
||||||
cins.mSType[0] = InterTypeOf(vr.mType);
|
|
||||||
cins.mSTemp[0] = vr.mTemp;
|
|
||||||
cins.mTType = InterTypeOf(vll.mType);
|
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
|
||||||
vr.mTemp = cins.mTTemp;
|
|
||||||
vr.mType = TheSignedIntTypeDeclaration;
|
|
||||||
block->Append(cins);
|
|
||||||
}
|
|
||||||
else if (vll.mType->mType == DT_TYPE_FLOAT && vr.mType->IsIntegerType())
|
|
||||||
{
|
|
||||||
InterInstruction cins;
|
|
||||||
cins.mCode = IC_CONVERSION_OPERATOR;
|
|
||||||
cins.mOperator = IA_INT2FLOAT;
|
|
||||||
cins.mSType[0] = InterTypeOf(vr.mType);
|
|
||||||
cins.mSTemp[0] = vr.mTemp;
|
|
||||||
cins.mTType = InterTypeOf(vll.mType);;
|
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
|
||||||
vr.mTemp = cins.mTTemp;
|
|
||||||
vr.mType = TheFloatTypeDeclaration;
|
|
||||||
block->Append(cins);
|
|
||||||
}
|
|
||||||
|
|
||||||
InterInstruction oins;
|
InterInstruction oins;
|
||||||
oins.mCode = IC_BINARY_OPERATOR;
|
oins.mCode = IC_BINARY_OPERATOR;
|
||||||
|
@ -1406,7 +1389,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
mErrors->Error(exp->mLocation, "Not enough arguments for function call");
|
mErrors->Error(exp->mLocation, "Not enough arguments for function call");
|
||||||
|
|
||||||
InterInstruction cins;
|
InterInstruction cins;
|
||||||
if (exp->mLeft->mDecValue->mFlags & DTF_NATIVE)
|
if (exp->mLeft->mDecValue && exp->mLeft->mDecValue->mFlags & DTF_NATIVE)
|
||||||
cins.mCode = IC_JSR;
|
cins.mCode = IC_JSR;
|
||||||
else
|
else
|
||||||
cins.mCode = IC_CALL;
|
cins.mCode = IC_CALL;
|
||||||
|
@ -2139,10 +2122,27 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
|
||||||
__int64 t = cast.i;
|
__int64 t = cast.i;
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
dp[i] = t & 0xff;
|
dp[offset + i] = t & 0xff;
|
||||||
t >>= 8;
|
t >>= 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (data->mType == DT_CONST_FUNCTION)
|
||||||
|
{
|
||||||
|
if (data->mVarIndex < 0)
|
||||||
|
{
|
||||||
|
InterCodeProcedure* cproc = this->TranslateProcedure(mod, data->mValue, data);
|
||||||
|
cproc->ReduceTemporaries();
|
||||||
|
}
|
||||||
|
|
||||||
|
InterVariable::Reference ref;
|
||||||
|
ref.mAddr = offset;
|
||||||
|
ref.mLower = true;
|
||||||
|
ref.mUpper = true;
|
||||||
|
ref.mFunction = true;
|
||||||
|
ref.mIndex = data->mVarIndex;
|
||||||
|
ref.mOffset = 0;
|
||||||
|
references.Push(ref);
|
||||||
|
}
|
||||||
else if (data->mType == DT_CONST_POINTER)
|
else if (data->mType == DT_CONST_POINTER)
|
||||||
{
|
{
|
||||||
Expression* exp = data->mValue;
|
Expression* exp = data->mValue;
|
||||||
|
|
|
@ -22,6 +22,7 @@ public:
|
||||||
|
|
||||||
InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec);
|
InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec);
|
||||||
void TranslateAssembler(InterCodeModule* mod, Expression * exp);
|
void TranslateAssembler(InterCodeModule* mod, Expression * exp);
|
||||||
|
void InitGlobalVariable(InterCodeModule* mod, Declaration* dec);
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Errors* mErrors;
|
Errors* mErrors;
|
||||||
|
@ -30,7 +31,6 @@ protected:
|
||||||
ExValue CoerceType(InterCodeProcedure* proc, InterCodeBasicBlock*& block, ExValue v, Declaration * type);
|
ExValue CoerceType(InterCodeProcedure* proc, InterCodeBasicBlock*& block, ExValue v, Declaration * type);
|
||||||
ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock);
|
ExValue TranslateExpression(Declaration * procType, InterCodeProcedure * proc, InterCodeBasicBlock*& block, Expression* exp, InterCodeBasicBlock* breakBlock, InterCodeBasicBlock* continueBlock);
|
||||||
void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp);
|
void TranslateLogic(Declaration* procType, InterCodeProcedure* proc, InterCodeBasicBlock* block, InterCodeBasicBlock* tblock, InterCodeBasicBlock* fblock, Expression* exp);
|
||||||
void InitGlobalVariable(InterCodeModule* mod, Declaration* dec);
|
|
||||||
|
|
||||||
void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, GrowingArray<InterVariable::Reference> & references);
|
void BuildInitializer(InterCodeModule* mod, uint8 * dp, int offset, Declaration* data, GrowingArray<InterVariable::Reference> & references);
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -28,19 +28,23 @@ class NativeCodeInstruction
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NativeCodeInstruction(AsmInsType type = ASMIT_INV, AsmInsMode mode = ASMIM_IMPLIED, int address = 0, int varIndex = -1, bool lower = true, bool upper = true);
|
NativeCodeInstruction(AsmInsType type = ASMIT_INV, AsmInsMode mode = ASMIM_IMPLIED, int address = 0, int varIndex = -1, bool lower = true, bool upper = true);
|
||||||
|
NativeCodeInstruction(AsmInsType type, AsmInsMode mode, const char* runtime, int address = 0, bool lower = true, bool upper = true);
|
||||||
NativeCodeInstruction(const char* runtime);
|
NativeCodeInstruction(const char* runtime);
|
||||||
|
|
||||||
AsmInsType mType;
|
AsmInsType mType;
|
||||||
AsmInsMode mMode;
|
AsmInsMode mMode;
|
||||||
|
|
||||||
int mAddress, mVarIndex;
|
int mAddress, mVarIndex;
|
||||||
bool mLower, mUpper;
|
bool mLower, mUpper, mFunction;
|
||||||
const char * mRuntime;
|
const char * mRuntime;
|
||||||
|
|
||||||
void Assemble(NativeCodeBasicBlock* block);
|
void Assemble(NativeCodeBasicBlock* block);
|
||||||
void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
|
void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
|
||||||
bool IsUsedResultInstructions(NumberSet& requiredTemps);
|
bool IsUsedResultInstructions(NumberSet& requiredTemps);
|
||||||
bool ValueForwarding(NativeRegisterDataSet& data);
|
bool ValueForwarding(NativeRegisterDataSet& data);
|
||||||
|
|
||||||
|
bool LoadsAccu(void) const;
|
||||||
|
bool ChangesAddress(void) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NativeCodeBasicBlock
|
class NativeCodeBasicBlock
|
||||||
|
@ -77,6 +81,7 @@ public:
|
||||||
void PutWord(uint16 code);
|
void PutWord(uint16 code);
|
||||||
|
|
||||||
void LoadValueToReg(InterCodeProcedure* proc, const InterInstruction& ins, int reg, const NativeCodeInstruction * ainsl, const NativeCodeInstruction* ainsh);
|
void LoadValueToReg(InterCodeProcedure* proc, const InterInstruction& ins, int reg, const NativeCodeInstruction * ainsl, const NativeCodeInstruction* ainsh);
|
||||||
|
void LoadConstantToReg(InterCodeProcedure* proc, const InterInstruction& ins, InterType type, int reg);
|
||||||
|
|
||||||
void LoadConstant(InterCodeProcedure* proc, const InterInstruction& ins);
|
void LoadConstant(InterCodeProcedure* proc, const InterInstruction& ins);
|
||||||
void StoreValue(InterCodeProcedure* proc, const InterInstruction& ins);
|
void StoreValue(InterCodeProcedure* proc, const InterInstruction& ins);
|
||||||
|
@ -88,6 +93,12 @@ public:
|
||||||
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction& ins);
|
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction& ins);
|
||||||
void NumericConversion(InterCodeProcedure* proc, const InterInstruction& ins);
|
void NumericConversion(InterCodeProcedure* proc, const InterInstruction& ins);
|
||||||
|
|
||||||
|
void CallAssembler(InterCodeProcedure* proc, const InterInstruction& ins);
|
||||||
|
void CallFunction(InterCodeProcedure* proc, const InterInstruction& ins);
|
||||||
|
|
||||||
|
void ShiftRegisterLeft(InterCodeProcedure* proc, int reg, int shift);
|
||||||
|
int ShortMultiply(InterCodeProcedure* proc, const InterInstruction& ins, const InterInstruction* sins, int index, int mul);
|
||||||
|
|
||||||
bool CheckPredAccuStore(int reg);
|
bool CheckPredAccuStore(int reg);
|
||||||
|
|
||||||
NumberSet mLocalRequiredRegs, mLocalProvidedRegs;
|
NumberSet mLocalRequiredRegs, mLocalProvidedRegs;
|
||||||
|
@ -98,6 +109,8 @@ public:
|
||||||
void BuildGlobalProvidedRegSet(NumberSet fromProvidedTemps);
|
void BuildGlobalProvidedRegSet(NumberSet fromProvidedTemps);
|
||||||
bool BuildGlobalRequiredRegSet(NumberSet& fromRequiredTemps);
|
bool BuildGlobalRequiredRegSet(NumberSet& fromRequiredTemps);
|
||||||
bool RemoveUnusedResultInstructions(void);
|
bool RemoveUnusedResultInstructions(void);
|
||||||
|
|
||||||
|
bool MoveLoadStoreUp(int at);
|
||||||
};
|
};
|
||||||
|
|
||||||
class NativeCodeProcedure
|
class NativeCodeProcedure
|
||||||
|
|
|
@ -804,11 +804,11 @@ Expression* Parser::ParseSimpleExpression(void)
|
||||||
break;
|
break;
|
||||||
case TK_INTEGER:
|
case TK_INTEGER:
|
||||||
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||||
|
dec->mInteger = mScanner->mTokenInteger;
|
||||||
if (dec->mInteger < 32768)
|
if (dec->mInteger < 32768)
|
||||||
dec->mBase = TheSignedIntTypeDeclaration;
|
dec->mBase = TheSignedIntTypeDeclaration;
|
||||||
else
|
else
|
||||||
dec->mBase = TheUnsignedIntTypeDeclaration;
|
dec->mBase = TheUnsignedIntTypeDeclaration;
|
||||||
dec->mInteger = mScanner->mTokenInteger;
|
|
||||||
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||||
exp->mDecValue = dec;
|
exp->mDecValue = dec;
|
||||||
exp->mDecType = dec->mBase;
|
exp->mDecType = dec->mBase;
|
||||||
|
@ -993,6 +993,8 @@ Expression* Parser::ParsePostfixExpression(void)
|
||||||
else
|
else
|
||||||
mErrors->Error(mScanner->mLocation, "']' expected");
|
mErrors->Error(mScanner->mLocation, "']' expected");
|
||||||
nexp->mDecType = exp->mDecType->mBase;
|
nexp->mDecType = exp->mDecType->mBase;
|
||||||
|
if (!nexp->mDecType)
|
||||||
|
nexp->mDecType = TheVoidTypeDeclaration;
|
||||||
exp = nexp;
|
exp = nexp;
|
||||||
}
|
}
|
||||||
else if (mScanner->mToken == TK_OPEN_PARENTHESIS)
|
else if (mScanner->mToken == TK_OPEN_PARENTHESIS)
|
||||||
|
@ -2224,9 +2226,13 @@ void Parser::ParsePragma(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtident)
|
if (rtident)
|
||||||
{
|
|
||||||
mCompilationUnits->mRuntimeScope->Insert(rtident, dec);
|
mCompilationUnits->mRuntimeScope->Insert(rtident, dec);
|
||||||
}
|
}
|
||||||
|
else if (dec && dec->mType == DT_VARIABLE && (dec->mFlags & DTF_GLOBAL))
|
||||||
|
{
|
||||||
|
if (rtident)
|
||||||
|
mCompilationUnits->mRuntimeScope->Insert(rtident, dec);
|
||||||
|
mScanner->NextToken();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,0,23,0
|
FILEVERSION 1,0,24,0
|
||||||
PRODUCTVERSION 1,0,23,0
|
PRODUCTVERSION 1,0,24,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -43,12 +43,12 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "oscar64"
|
VALUE "CompanyName", "oscar64"
|
||||||
VALUE "FileDescription", "oscar64 compiler"
|
VALUE "FileDescription", "oscar64 compiler"
|
||||||
VALUE "FileVersion", "1.0.23.0"
|
VALUE "FileVersion", "1.0.24.0"
|
||||||
VALUE "InternalName", "oscar64.exe"
|
VALUE "InternalName", "oscar64.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||||
VALUE "OriginalFilename", "oscar64.exe"
|
VALUE "OriginalFilename", "oscar64.exe"
|
||||||
VALUE "ProductName", "oscar64"
|
VALUE "ProductName", "oscar64"
|
||||||
VALUE "ProductVersion", "1.0.23.0"
|
VALUE "ProductVersion", "1.0.24.0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -147,6 +147,14 @@
|
||||||
"PrerequisitesLocation" = "2:1"
|
"PrerequisitesLocation" = "2:1"
|
||||||
"Url" = "8:"
|
"Url" = "8:"
|
||||||
"ComponentsUrl" = "8:"
|
"ComponentsUrl" = "8:"
|
||||||
|
"Items"
|
||||||
|
{
|
||||||
|
"{EDC2488A-8267-493A-A98E-7D9C3B36CDF3}:.NETFramework,Version=v4.7.2"
|
||||||
|
{
|
||||||
|
"Name" = "8:Microsoft .NET Framework 4.7.2 (x86 and x64)"
|
||||||
|
"ProductCode" = "8:.NETFramework,Version=v4.7.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -496,15 +504,15 @@
|
||||||
{
|
{
|
||||||
"Name" = "8:Microsoft Visual Studio"
|
"Name" = "8:Microsoft Visual Studio"
|
||||||
"ProductName" = "8:oscar64"
|
"ProductName" = "8:oscar64"
|
||||||
"ProductCode" = "8:{468390A3-2F63-4CA4-9043-3B1AEEA1852F}"
|
"ProductCode" = "8:{B20D936B-B9E1-4135-B9AA-8C367043CF71}"
|
||||||
"PackageCode" = "8:{A55AE2BA-C814-4AD7-BBB6-00042C360D73}"
|
"PackageCode" = "8:{63E1E188-3AB3-4767-B84A-CDB7F9FC9E10}"
|
||||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||||
"AspNetVersion" = "8:2.0.50727.0"
|
"AspNetVersion" = "8:2.0.50727.0"
|
||||||
"RestartWWWService" = "11:FALSE"
|
"RestartWWWService" = "11:FALSE"
|
||||||
"RemovePreviousVersions" = "11:TRUE"
|
"RemovePreviousVersions" = "11:TRUE"
|
||||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||||
"InstallAllUsers" = "11:FALSE"
|
"InstallAllUsers" = "11:FALSE"
|
||||||
"ProductVersion" = "8:1.0.23"
|
"ProductVersion" = "8:1.0.24"
|
||||||
"Manufacturer" = "8:oscar64"
|
"Manufacturer" = "8:oscar64"
|
||||||
"ARPHELPTELEPHONE" = "8:"
|
"ARPHELPTELEPHONE" = "8:"
|
||||||
"ARPHELPLINK" = "8:"
|
"ARPHELPLINK" = "8:"
|
||||||
|
|
Loading…
Reference in New Issue