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
|
||||
* No block domination analysis
|
||||
* No register use for arguments
|
||||
* Auto variables places on fixed stack for known call sequence
|
||||
|
||||
### Intermediate code generation
|
||||
|
||||
|
@ -59,7 +60,8 @@ The first release of the compiler is severely limited considering it is only two
|
|||
|
||||
### Native code generation
|
||||
|
||||
* Missing
|
||||
* Calling non native functions missing
|
||||
* More byte operation optimisation required
|
||||
|
||||
## Implementation Details
|
||||
|
||||
|
@ -109,6 +111,15 @@ The intermediate code generator assumes a large number of registers so the zero
|
|||
* **0x43-0x52** caller 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
|
||||
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
|
||||
:error
|
||||
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)
|
||||
|
||||
__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
|
||||
{
|
||||
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 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 {
|
||||
ffloor:
|
||||
bit accu + 3
|
||||
|
|
|
@ -145,7 +145,9 @@ enum ByteCode
|
|||
BC_JSR,
|
||||
|
||||
BC_COPY,
|
||||
BC_COPY_LONG
|
||||
BC_COPY_LONG,
|
||||
|
||||
BC_NATIVE = 0x75
|
||||
};
|
||||
|
||||
#pragma compile("crt.c")
|
||||
|
|
|
@ -176,7 +176,7 @@ float log10(float f)
|
|||
|
||||
float pow(float p, float q)
|
||||
{
|
||||
return exp(p * log(q));
|
||||
return exp(q * log(p));
|
||||
}
|
||||
|
||||
float sqrt(float f)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "stdlib.h"
|
||||
#include "string.h"
|
||||
#include "stdio.h"
|
||||
#include "math.h"
|
||||
|
||||
void itoa(int n, char * s, int radix)
|
||||
{
|
||||
|
@ -164,6 +165,90 @@ int atoi(const char * s)
|
|||
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)
|
||||
{
|
||||
__asm {
|
||||
|
|
|
@ -9,6 +9,8 @@ void ftoa(float f, char * s);
|
|||
|
||||
int atoi(const char * s);
|
||||
|
||||
float atof(const char * s);
|
||||
|
||||
void exit(int status);
|
||||
|
||||
void * malloc(unsigned int size);
|
||||
|
|
|
@ -1556,6 +1556,7 @@ void ByteCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInst
|
|||
bins.mRelocate = true;
|
||||
bins.mVIndex = ins.mVarIndex;
|
||||
bins.mFunction = ins.mMemory == IM_PROCEDURE;
|
||||
bins.mValue = ins.mSIntConst[0];
|
||||
mIns.Push(bins);
|
||||
}
|
||||
|
||||
|
@ -3546,51 +3547,51 @@ void ByteCodeGenerator::WriteAsmFile(FILE * file, Address & addr)
|
|||
switch (d.mMode)
|
||||
{
|
||||
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;
|
||||
case ASMIM_IMMEDIATE:
|
||||
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;
|
||||
case ASMIM_ZERO_PAGE:
|
||||
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;
|
||||
case ASMIM_ZERO_PAGE_X:
|
||||
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;
|
||||
case ASMIM_ZERO_PAGE_Y:
|
||||
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;
|
||||
case ASMIM_ABSOLUTE:
|
||||
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;
|
||||
break;
|
||||
case ASMIM_ABSOLUTE_X:
|
||||
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;
|
||||
break;
|
||||
case ASMIM_ABSOLUTE_Y:
|
||||
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;
|
||||
break;
|
||||
case ASMIM_INDIRECT:
|
||||
addr = mMemory[ip] + 256 * mMemory[ip + 1];
|
||||
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;
|
||||
case ASMIM_INDIRECT_X:
|
||||
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;
|
||||
case ASMIM_INDIRECT_Y:
|
||||
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;
|
||||
case ASMIM_RELATIVE:
|
||||
addr = mMemory[ip++];
|
||||
|
@ -3598,7 +3599,7 @@ void ByteCodeGenerator::WriteAsmFile(FILE * file, Address & addr)
|
|||
addr = addr + ip - 256;
|
||||
else
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,7 +134,9 @@ enum ByteCode
|
|||
BC_JSR,
|
||||
|
||||
BC_COPY,
|
||||
BC_COPY_LONG
|
||||
BC_COPY_LONG,
|
||||
|
||||
BC_NATIVE = 0x75
|
||||
};
|
||||
|
||||
class ByteCodeProcedure;
|
||||
|
|
|
@ -143,7 +143,13 @@ bool Compiler::GenerateCode(void)
|
|||
index = bcdec->mBase->mVarIndex;
|
||||
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);
|
||||
mInterCodeModule->UseGlobal(index);
|
||||
|
||||
|
|
|
@ -1593,6 +1593,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
|
|||
ins.mMemory = tvalue[ins.mSTemp[0]]->mMemory;
|
||||
ins.mVarIndex = tvalue[ins.mSTemp[0]]->mVarIndex;
|
||||
ins.mOperandSize = tvalue[ins.mSTemp[0]]->mOperandSize;
|
||||
ins.mSIntConst[0] = tvalue[ins.mSTemp[0]]->mIntValue;
|
||||
ins.mSTemp[0] = -1;
|
||||
}
|
||||
|
||||
|
@ -2708,6 +2709,9 @@ static bool CanBypassStore(const InterInstruction& sins, const InterInstruction&
|
|||
return false;
|
||||
}
|
||||
|
||||
if (sins.mMemory == IM_FRAME && (bins.mCode == IC_PUSH_FRAME || bins.mCode == IC_POP_FRAME))
|
||||
return false;
|
||||
|
||||
// Side effects
|
||||
if (bins.mCode == IC_CALL || bins.mCode == IC_JSR)
|
||||
return false;
|
||||
|
|
|
@ -341,9 +341,17 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins.mTType = InterTypeOf(dec->mBase);
|
||||
ins.mTTemp = proc->AddTemporary(ins.mTType);
|
||||
if (ins.mTType == IT_SIGNED)
|
||||
{
|
||||
if (dec->mInteger < -32768 || dec->mInteger > 32767)
|
||||
mErrors->Warning(dec->mLocation, "Integer constant truncated");
|
||||
ins.mIntValue = short(dec->mInteger);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dec->mInteger < 0 || dec->mInteger > 65535)
|
||||
mErrors->Warning(dec->mLocation, "Unsigned integer constant truncated");
|
||||
ins.mIntValue = unsigned short(dec->mInteger);
|
||||
}
|
||||
block->Append(ins);
|
||||
return ExValue(dec->mBase, ins.mTTemp);
|
||||
|
||||
|
@ -597,32 +605,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
}
|
||||
else
|
||||
{
|
||||
if (vll.mType->IsIntegerType() && vr.mType->mType == DT_TYPE_FLOAT)
|
||||
{
|
||||
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);
|
||||
}
|
||||
vr = CoerceType(proc, block, vr, vll.mType);
|
||||
|
||||
InterInstruction oins;
|
||||
oins.mCode = IC_BINARY_OPERATOR;
|
||||
|
@ -1406,7 +1389,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
mErrors->Error(exp->mLocation, "Not enough arguments for function call");
|
||||
|
||||
InterInstruction cins;
|
||||
if (exp->mLeft->mDecValue->mFlags & DTF_NATIVE)
|
||||
if (exp->mLeft->mDecValue && exp->mLeft->mDecValue->mFlags & DTF_NATIVE)
|
||||
cins.mCode = IC_JSR;
|
||||
else
|
||||
cins.mCode = IC_CALL;
|
||||
|
@ -2139,10 +2122,27 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
|
|||
__int64 t = cast.i;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
dp[i] = t & 0xff;
|
||||
dp[offset + i] = t & 0xff;
|
||||
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)
|
||||
{
|
||||
Expression* exp = data->mValue;
|
||||
|
|
|
@ -22,6 +22,7 @@ public:
|
|||
|
||||
InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec);
|
||||
void TranslateAssembler(InterCodeModule* mod, Expression * exp);
|
||||
void InitGlobalVariable(InterCodeModule* mod, Declaration* dec);
|
||||
protected:
|
||||
|
||||
Errors* mErrors;
|
||||
|
@ -30,7 +31,6 @@ protected:
|
|||
ExValue CoerceType(InterCodeProcedure* proc, InterCodeBasicBlock*& block, ExValue v, Declaration * type);
|
||||
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 InitGlobalVariable(InterCodeModule* mod, Declaration* dec);
|
||||
|
||||
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:
|
||||
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);
|
||||
|
||||
AsmInsType mType;
|
||||
AsmInsMode mMode;
|
||||
|
||||
int mAddress, mVarIndex;
|
||||
bool mLower, mUpper;
|
||||
bool mLower, mUpper, mFunction;
|
||||
const char * mRuntime;
|
||||
|
||||
void Assemble(NativeCodeBasicBlock* block);
|
||||
void FilterRegUsage(NumberSet& requiredTemps, NumberSet& providedTemps);
|
||||
bool IsUsedResultInstructions(NumberSet& requiredTemps);
|
||||
bool ValueForwarding(NativeRegisterDataSet& data);
|
||||
|
||||
bool LoadsAccu(void) const;
|
||||
bool ChangesAddress(void) const;
|
||||
};
|
||||
|
||||
class NativeCodeBasicBlock
|
||||
|
@ -77,6 +81,7 @@ public:
|
|||
void PutWord(uint16 code);
|
||||
|
||||
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 StoreValue(InterCodeProcedure* proc, const InterInstruction& ins);
|
||||
|
@ -88,6 +93,12 @@ public:
|
|||
void LoadEffectiveAddress(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);
|
||||
|
||||
NumberSet mLocalRequiredRegs, mLocalProvidedRegs;
|
||||
|
@ -98,6 +109,8 @@ public:
|
|||
void BuildGlobalProvidedRegSet(NumberSet fromProvidedTemps);
|
||||
bool BuildGlobalRequiredRegSet(NumberSet& fromRequiredTemps);
|
||||
bool RemoveUnusedResultInstructions(void);
|
||||
|
||||
bool MoveLoadStoreUp(int at);
|
||||
};
|
||||
|
||||
class NativeCodeProcedure
|
||||
|
|
|
@ -804,11 +804,11 @@ Expression* Parser::ParseSimpleExpression(void)
|
|||
break;
|
||||
case TK_INTEGER:
|
||||
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||
dec->mInteger = mScanner->mTokenInteger;
|
||||
if (dec->mInteger < 32768)
|
||||
dec->mBase = TheSignedIntTypeDeclaration;
|
||||
else
|
||||
dec->mBase = TheUnsignedIntTypeDeclaration;
|
||||
dec->mInteger = mScanner->mTokenInteger;
|
||||
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||
exp->mDecValue = dec;
|
||||
exp->mDecType = dec->mBase;
|
||||
|
@ -993,6 +993,8 @@ Expression* Parser::ParsePostfixExpression(void)
|
|||
else
|
||||
mErrors->Error(mScanner->mLocation, "']' expected");
|
||||
nexp->mDecType = exp->mDecType->mBase;
|
||||
if (!nexp->mDecType)
|
||||
nexp->mDecType = TheVoidTypeDeclaration;
|
||||
exp = nexp;
|
||||
}
|
||||
else if (mScanner->mToken == TK_OPEN_PARENTHESIS)
|
||||
|
@ -2224,9 +2226,13 @@ void Parser::ParsePragma(void)
|
|||
}
|
||||
|
||||
if (rtident)
|
||||
{
|
||||
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
|
||||
{
|
||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,23,0
|
||||
PRODUCTVERSION 1,0,23,0
|
||||
FILEVERSION 1,0,24,0
|
||||
PRODUCTVERSION 1,0,24,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -43,12 +43,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "oscar64"
|
||||
VALUE "FileDescription", "oscar64 compiler"
|
||||
VALUE "FileVersion", "1.0.23.0"
|
||||
VALUE "FileVersion", "1.0.24.0"
|
||||
VALUE "InternalName", "oscar64.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2021"
|
||||
VALUE "OriginalFilename", "oscar64.exe"
|
||||
VALUE "ProductName", "oscar64"
|
||||
VALUE "ProductVersion", "1.0.23.0"
|
||||
VALUE "ProductVersion", "1.0.24.0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -147,6 +147,14 @@
|
|||
"PrerequisitesLocation" = "2:1"
|
||||
"Url" = "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"
|
||||
"ProductName" = "8:oscar64"
|
||||
"ProductCode" = "8:{468390A3-2F63-4CA4-9043-3B1AEEA1852F}"
|
||||
"PackageCode" = "8:{A55AE2BA-C814-4AD7-BBB6-00042C360D73}"
|
||||
"ProductCode" = "8:{B20D936B-B9E1-4135-B9AA-8C367043CF71}"
|
||||
"PackageCode" = "8:{63E1E188-3AB3-4767-B84A-CDB7F9FC9E10}"
|
||||
"UpgradeCode" = "8:{9AB61EFF-ACAC-4079-9950-8D96615CD4EF}"
|
||||
"AspNetVersion" = "8:2.0.50727.0"
|
||||
"RestartWWWService" = "11:FALSE"
|
||||
"RemovePreviousVersions" = "11:TRUE"
|
||||
"DetectNewerInstalledVersion" = "11:TRUE"
|
||||
"InstallAllUsers" = "11:FALSE"
|
||||
"ProductVersion" = "8:1.0.23"
|
||||
"ProductVersion" = "8:1.0.24"
|
||||
"Manufacturer" = "8:oscar64"
|
||||
"ARPHELPTELEPHONE" = "8:"
|
||||
"ARPHELPLINK" = "8:"
|
||||
|
|
Loading…
Reference in New Issue