More native code compiler additions

This commit is contained in:
drmortalwombat 2021-09-08 22:04:01 +02:00
parent 056df56eef
commit fcedf69aff
12 changed files with 1205 additions and 278 deletions

View File

@ -36,6 +36,9 @@ if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e array2stringinittest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -i=../include -rt=../include/crt.c -e testint16cmp.c
if %errorlevel% neq 0 goto :error
exit /b 0
:error
echo Failed with error #%errorlevel%.

147
autotest/testint16cmp.c Normal file
View File

@ -0,0 +1,147 @@
#include <stdio.h>
#include <assert.h>
bool beq(int a, int b)
{
return a == b;
}
bool blt(int a, int b)
{
return a < b;
}
bool bgt(int a, int b)
{
return a > b;
}
bool ble(int a, int b)
{
return a <= b;
}
bool bge(int a, int b)
{
return a >= b;
}
bool neq(int a, int b)
{
return a == b;
}
#pragma native(neq)
bool nlt(int a, int b)
{
return a < b;
}
#pragma native(nlt)
bool ngt(int a, int b)
{
return a > b;
}
#pragma native(ngt)
bool nle(int a, int b)
{
return a <= b;
}
#pragma native(nlt)
bool nge(int a, int b)
{
return a >= b;
}
#pragma native(ngt)
void cmp(int a, int b)
{
bool beqf = beq(a, b), bltf = blt(a, b), bgtf = bgt(a, b), blef = blt(a, b), bgef = bgt(a, b);
bool neqf = neq(a, b), nltf = nlt(a, b), ngtf = ngt(a, b), nlef = nlt(a, b), ngef = ngt(a, b);
// printf("BYTE %d, %d : EQ %d LT %d GT %d\r", a, b, beqf, bltf, bgtf);
// printf("NATIVE %d, %d : 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);
}
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( 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);
return 0;
}

View File

@ -38,7 +38,31 @@ incip:
#pragma startup(startup)
// divide accu by tmp
__asm negaccu
{
sec
lda #0
sbc accu
sta accu
lda #0
sbc accu + 1
sta accu + 1
rts
}
__asm negtmp
{
sec
lda #0
sbc tmp
sta tmp
lda #0
sbc tmp + 1
sta tmp + 1
rts
}
// divide accu by tmp result in accu, remainder in tmp + 2
__asm divmod
{
@ -68,6 +92,77 @@ W1: dey
ldy tmpy
rts
}
// Multiply accu by tmp result in tmp + 2
__asm mul16
{
lda #0
sta tmp + 2
sta tmp + 3
ldx #16
L1: lsr tmp + 1
ror tmp
bcc W1
clc
lda tmp + 2
adc accu
sta tmp + 2
lda tmp + 3
adc accu + 1
sta tmp + 3
W1: asl accu
rol accu + 1
dex
bne L1
rts
}
__asm divs16
{
bit accu + 1
bpl L1
jsr negaccu
bit tmp + 1
bpl L2
jsr negtmp
L3: jmp divmod
L1: bit tmp + 1
bpl L3
jsr negtmp
L2: jsr divmod
jmp negaccu
}
__asm mods16
{
bit accu + 1
bpl L1
jsr negaccu
bit tmp + 1
bpl L2
jsr negtmp
L3: jmp divmod
L1: bit tmp + 1
bpl L3
jsr negtmp
L2: jsr divmod
sec
lda #0
sbc tmp + 2
sta tmp + 2
lda #0
sbc tmp + 3
sta tmp + 3
rts
}
#pragma runtime(mul16, mul16);
#pragma runtime(divu16, divmod);
#pragma runtime(modu16, divmod);
#pragma runtime(divs16, divs16);
#pragma runtime(mods16, mods16);
/*
!align 255, 0
@ -983,30 +1078,6 @@ __asm inp_binop_modr_u16
#pragma bytecode(BC_BINOP_MODR_U16, inp_binop_modr_u16)
__asm negaccu
{
sec
lda #0
sbc accu
sta accu
lda #0
sbc accu + 1
sta accu + 1
rts
}
__asm negtmp
{
sec
lda #0
sbc tmp
sta tmp
lda #0
sbc tmp + 1
sta tmp + 1
rts
}
__asm inp_binop_divr_s16
{
lda (ip), y

View File

@ -187,6 +187,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
rl.mUpper = true;
rl.mIndex = mVIndex;
rl.mOffset = mValue;
rl.mRuntime = nullptr;
block->mRelocations.Push(rl);
block->PutWord(0);
}
@ -233,6 +234,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
rl.mUpper = true;
rl.mIndex = mVIndex;
rl.mOffset = mValue;
rl.mRuntime = nullptr;
block->mRelocations.Push(rl);
block->PutWord(0);
}
@ -253,6 +255,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
rl.mUpper = true;
rl.mIndex = mVIndex;
rl.mOffset = mValue;
rl.mRuntime = nullptr;
block->mRelocations.Push(rl);
block->PutWord(0);
}
@ -410,6 +413,7 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
rl.mUpper = true;
rl.mIndex = mVIndex;
rl.mOffset = 0;
rl.mRuntime = nullptr;
block->mRelocations.Push(rl);
block->PutWord(0);
@ -1484,6 +1488,22 @@ void ByteCodeBasicBlock::CallAssembler(InterCodeProcedure* proc, const InterInst
bins.mFunction = ins.mMemory == IM_PROCEDURE;
mIns.Push(bins);
}
if (ins.mTTemp >= 0)
{
if (ins.mTType == IT_FLOAT)
{
ByteCodeInstruction bins(BC_STORE_REG_32);
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
mIns.Push(bins);
}
else
{
ByteCodeInstruction bins(BC_STORE_REG_16);
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
mIns.Push(bins);
}
}
}
ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const InterInstruction& ins)

View File

@ -143,9 +143,10 @@ class ByteCodeGenerator;
class ByteCodeRelocation
{
public:
uint16 mAddr;
bool mFunction, mLower, mUpper;
uint16 mIndex, mOffset;
uint16 mAddr;
bool mFunction, mLower, mUpper;
uint16 mIndex, mOffset;
const char * mRuntime;
};
class ByteCodeBasicBlock;

View File

@ -9,6 +9,7 @@ CompilationUnits::CompilationUnits(Errors * errors)
mCompilationUnits = nullptr;
mPendingUnits = nullptr;
mScope = new DeclarationScope(nullptr);
mRuntimeScope = new DeclarationScope(nullptr);
mStartup = nullptr;
for (int i = 0; i < 128; i++)

View File

@ -24,6 +24,8 @@ public:
Declaration* mStartup;
Declaration* mByteCodes[128];
DeclarationScope* mRuntimeScope;
bool AddUnit(Location & location, const char* name, const char * from);
CompilationUnit* PendingUnit(void);
protected:

View File

@ -120,6 +120,45 @@ bool Compiler::GenerateCode(void)
}
}
// Compile used runtime functions
for (int i = 0; i < mByteCodeGenerator->mRelocations.Size(); i++)
{
if (mByteCodeGenerator->mRelocations[i].mRuntime)
{
Declaration* bcdec = mCompilationUnits->mRuntimeScope->Lookup(Ident::Unique(mByteCodeGenerator->mRelocations[i].mRuntime));
if (bcdec)
{
int index = -1, offset = 0;
if (bcdec->mType == DT_CONST_ASSEMBLER)
{
if (bcdec->mVarIndex < 0)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mValue);
index = bcdec->mVarIndex;
}
else if (bcdec->mType == DT_LABEL)
{
if (bcdec->mBase->mVarIndex < 0)
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, bcdec->mBase->mValue);
index = bcdec->mBase->mVarIndex;
offset = bcdec->mInteger;
}
assert(index > 0);
mInterCodeModule->UseGlobal(index);
mByteCodeGenerator->mRelocations[i].mIndex = index;
mByteCodeGenerator->mRelocations[i].mOffset = offset;
}
else
{
mErrors->Error(loc, "Missing runtime code implementation", mByteCodeGenerator->mRelocations[i].mRuntime);
}
}
}
// Compile used byte code functions
for (int i = 0; i < 128; i++)
{
if (mByteCodeGenerator->mByteCodeUsed[i])
@ -152,8 +191,15 @@ bool Compiler::GenerateCode(void)
rel.mUpper = true;
rel.mIndex = index;
rel.mOffset = offset;
rel.mRuntime = nullptr;
mByteCodeGenerator->mRelocations.Push(rel);
}
else
{
char n[10];
sprintf_s(n, "%d", i);
mErrors->Error(loc, "Missing byte code implementation", n);
}
}
}
@ -177,6 +223,7 @@ bool Compiler::GenerateCode(void)
rel.mUpper = ref.mUpper;
rel.mIndex = ref.mIndex;
rel.mOffset = ref.mOffset;
rel.mRuntime = nullptr;
mByteCodeGenerator->mRelocations.Push(rel);
}
}

View File

@ -7,6 +7,7 @@ typedef signed char int8;
typedef signed short int16;
typedef signed short int32;
static const uint8 BC_REG_WORK = 0x03;
static const uint8 BC_REG_IP = 0x19;
static const uint8 BC_REG_ACCU = 0x1b;
static const uint8 BC_REG_ADDR = 0x1f;

File diff suppressed because it is too large Load Diff

View File

@ -10,12 +10,14 @@ 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(const char* runtime);
AsmInsType mType;
AsmInsMode mMode;
int mAddress, mVarIndex;
bool mLower, mUpper;
const char * mRuntime;
void Assemble(NativeCodeBasicBlock* block);
};
@ -46,17 +48,18 @@ public:
void CopyCode(NativeCodeProcedure* proc, uint8* target);
void Assemble(void);
void Compile(InterCodeProcedure* iproc, NativeCodeProcedure* proc, InterCodeBasicBlock* block);
void Close(NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump, AsmInsType branch);
void PutByte(uint8 code);
void PutWord(uint16 code);
void LoadValueToReg(InterCodeProcedure* proc, const InterInstruction& ins, int reg, const NativeCodeInstruction * ainsl, const NativeCodeInstruction* ainsh);
void LoadConstant(InterCodeProcedure* proc, const InterInstruction& ins);
void StoreValue(InterCodeProcedure* proc, const InterInstruction& ins);
void LoadValue(InterCodeProcedure* proc, const InterInstruction& ins);
void LoadStoreValue(InterCodeProcedure* proc, const InterInstruction& rins, const InterInstruction& wins);
void BinaryOperator(InterCodeProcedure* proc, const InterInstruction& ins);
void BinaryOperator(InterCodeProcedure* proc, const InterInstruction& ins, const InterInstruction* sins1, const InterInstruction* sins0);
void UnaryOperator(InterCodeProcedure* proc, const InterInstruction& ins);
void RelationalOperator(InterCodeProcedure* proc, const InterInstruction& ins, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump);
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction& ins);
@ -73,12 +76,17 @@ class NativeCodeProcedure
int mProgStart, mProgSize, mIndex;
bool mNoFrame;
int mTempBlocks;
GrowingArray<ByteCodeRelocation> mRelocations;
void Compile( ByteCodeGenerator * generator, InterCodeProcedure* proc);
NativeCodeBasicBlock* CompileBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* block);
NativeCodeBasicBlock* AllocateBlock(void);
NativeCodeBasicBlock* TransientBlock(void);
void CompileInterBlock(InterCodeProcedure* iproc, InterCodeBasicBlock* iblock, NativeCodeBasicBlock*block);
};

View File

@ -2186,6 +2186,56 @@ void Parser::ParsePragma(void)
}
ConsumeToken(TK_CLOSE_PARENTHESIS);
}
else if (!strcmp(mScanner->mTokenIdent->mString, "runtime"))
{
mScanner->NextToken();
ConsumeToken(TK_OPEN_PARENTHESIS);
const Ident* rtident = nullptr;
if (mScanner->mToken == TK_IDENT)
{
rtident = mScanner->mTokenIdent;
mScanner->NextToken();
}
else
mErrors->Error(mScanner->mLocation, "Identifier expected");
ConsumeToken(TK_COMMA);
if (mScanner->mToken == TK_IDENT)
{
Declaration* dec = mGlobals->Lookup(mScanner->mTokenIdent);
if (dec && dec->mType == DT_CONST_ASSEMBLER)
{
mScanner->NextToken();
if (ConsumeTokenIf(TK_DOT))
{
if (mScanner->mToken == TK_IDENT)
{
Declaration* ndec = dec->mBase->mScope->Lookup(mScanner->mTokenIdent);
if (ndec)
dec = ndec;
else
mErrors->Error(mScanner->mLocation, "Label not found in assembler code");
mScanner->NextToken();
}
else
mErrors->Error(mScanner->mLocation, "Identifier expected");
}
if (rtident)
{
mCompilationUnits->mRuntimeScope->Insert(rtident, dec);
}
}
else
{
mErrors->Error(mScanner->mLocation, "Runtime function not found");
mScanner->NextToken();
}
}
ConsumeToken(TK_CLOSE_PARENTHESIS);
}
else
{
mScanner->NextToken();