Fix floating point native code generation

This commit is contained in:
drmortalwombat 2021-09-09 09:42:02 +02:00
parent fcedf69aff
commit 3442ee507a
4 changed files with 1089 additions and 471 deletions

View File

@ -1767,7 +1767,7 @@ split_exp:
sta tmp + 2 sta tmp + 2
lda $03, x lda $03, x
sta tmp + 3 sta tmp + 3
split_texp:
lda tmp + 2 lda tmp + 2
asl asl
lda tmp + 3 lda tmp + 3
@ -1805,10 +1805,8 @@ W1:
rts rts
} }
__asm inp_binop_add_f32 __asm faddsub
{ {
jsr freg.split_exp
faddsub:
sec sec
lda tmp + 4 lda tmp + 4
sbc tmp + 5 sbc tmp + 5
@ -1881,7 +1879,7 @@ fas_done:
and #$7f and #$7f
sta accu + 2 sta accu + 2
W2: W2:
jmp startup.exec rts
fas_sub: fas_sub:
sec sec
@ -1929,6 +1927,15 @@ fas_zero:
sta accu + 1 sta accu + 1
sta accu + 2 sta accu + 2
sta accu + 3 sta accu + 3
rts
}
__asm inp_binop_add_f32
{
jsr freg.split_exp
jsr faddsub
jmp startup.exec jmp startup.exec
} }
@ -1940,7 +1947,8 @@ __asm inp_binop_sub_f32
lda tmp + 3 lda tmp + 3
eor #$80 eor #$80
sta tmp + 3 sta tmp + 3
jmp inp_binop_add_f32.faddsub jsr faddsub
jmp startup.exec
} }
#pragma bytecode(BC_BINOP_SUB_F32, inp_binop_sub_f32) #pragma bytecode(BC_BINOP_SUB_F32, inp_binop_sub_f32)
@ -1979,16 +1987,14 @@ W1:
rts rts
} }
__asm inp_binop_mul_f32 __asm fmul
{ {
jsr freg.split_exp
lda accu lda accu
ora accu + 1 ora accu + 1
ora accu + 2 ora accu + 2
bne W1 bne W1
sta accu + 3 sta accu + 3
jmp startup.exec rts
W1: W1:
lda tmp lda tmp
ora tmp + 1 ora tmp + 1
@ -1998,7 +2004,7 @@ W1:
sta accu + 1 sta accu + 1
sta accu + 2 sta accu + 2
sta accu + 3 sta accu + 3
jmp startup.exec rts
W2: W2:
lda #0 lda #0
sta tmp + 6 sta tmp + 6
@ -2043,21 +2049,24 @@ W3: and #$7f
sta accu + 1 sta accu + 1
lda tmp + 6 lda tmp + 6
sta accu sta accu
rts
}
__asm inp_binop_mul_f32
{
jsr freg.split_exp
jsr fmul
jmp startup.exec jmp startup.exec
} }
#pragma bytecode(BC_BINOP_MUL_F32, inp_binop_mul_f32) __asm fdiv
__asm inp_binop_div_f32
{ {
jsr freg.split_exp
lda accu lda accu
ora accu + 1 ora accu + 1
ora accu + 2 ora accu + 2
bne W1 bne W1
sta accu + 3 sta accu + 3
jmp startup.exec rts
W1: W1:
lda accu + 3 lda accu + 3
eor tmp + 3 eor tmp + 3
@ -2131,12 +2140,84 @@ W4:
sta accu + 1 sta accu + 1
lda tmp + 6 lda tmp + 6
sta accu sta accu
rts
}
#pragma bytecode(BC_BINOP_MUL_F32, inp_binop_mul_f32)
__asm inp_binop_div_f32
{
jsr freg.split_exp
jsr fdiv
jmp startup.exec jmp startup.exec
} }
#pragma bytecode(BC_BINOP_DIV_F32, inp_binop_div_f32) #pragma bytecode(BC_BINOP_DIV_F32, inp_binop_div_f32)
__asm fcmp
{
lda accu + 3
eor tmp + 3
and #$80
beq W1
// different sig, check zero case
lda accu + 3
and #$7f
ora accu + 2
ora accu + 1
ora accu
bne W2
lda tmp + 3
and #$7f
ora tmp + 2
ora tmp + 1
ora tmp + 0
beq fcmpeq
W2: lda accu + 3
bmi fcmpgt
bpl fcmplt
W1:
// same sign
lda accu + 3
cmp tmp + 3
bne W3
lda accu + 2
cmp tmp + 2
bne W3
lda accu + 1
cmp tmp + 1
bne W3
lda accu
cmp tmp
bne W3
fcmpeq:
lda #0
rts
W3: bcs W4
bit accu + 3
bmi fcmplt
fcmpgt:
lda #1
rts
W4: bit accu + 3
bmi fcmpgt
fcmplt:
lda #$ff
rts
}
__asm inp_binop_cmp_f32 __asm inp_binop_cmp_f32
{ {
lda (ip), y lda (ip), y
@ -2223,7 +2304,7 @@ __asm inp_op_negate_f32
#pragma bytecode(BC_OP_NEGATE_F32, inp_op_negate_f32) #pragma bytecode(BC_OP_NEGATE_F32, inp_op_negate_f32)
__asm uin16_to_float __asm uint16_to_float
{ {
lda accu lda accu
ora accu + 1 ora accu + 1
@ -2256,20 +2337,11 @@ W2:
rts rts
} }
__asm inp_conv_u16_f32 __asm sint16_to_float
{
jsr uin16_to_float
jmp startup.exec
}
#pragma bytecode(BC_CONV_U16_F32, inp_conv_u16_f32)
__asm inp_conv_i16_f32
{ {
bit accu + 1 bit accu + 1
bmi W1 bmi W1
jsr uin16_to_float jmp uint16_to_float
jmp startup.exec
W1: W1:
sec sec
lda #0 lda #0
@ -2278,16 +2350,31 @@ W1:
lda #0 lda #0
sbc accu + 1 sbc accu + 1
sta accu + 1 sta accu + 1
jsr uin16_to_float jsr uint16_to_float
lda accu + 3 lda accu + 3
ora #$80 ora #$80
sta accu + 3 sta accu + 3
rts
}
__asm inp_conv_u16_f32
{
jsr uint16_to_float
jmp startup.exec
}
#pragma bytecode(BC_CONV_U16_F32, inp_conv_u16_f32)
__asm inp_conv_i16_f32
{
jsr sint16_to_float
jmp startup.exec jmp startup.exec
} }
#pragma bytecode(BC_CONV_I16_F32, inp_conv_i16_f32) #pragma bytecode(BC_CONV_I16_F32, inp_conv_i16_f32)
__asm inp_conv_f32_i16 __asm f32_to_i16
{ {
jsr freg.split_aexp jsr freg.split_aexp
lda tmp + 4 lda tmp + 4
@ -2296,7 +2383,7 @@ __asm inp_conv_f32_i16
lda #0 lda #0
sta accu sta accu
sta accu + 1 sta accu + 1
jmp startup.exec rts
W1: W1:
sec sec
sbc #$8e sbc #$8e
@ -2324,18 +2411,24 @@ W3:
lda #0 lda #0
sbc accu + 2 sbc accu + 2
sta accu + 1 sta accu + 1
jmp startup.exec rts
W4: W4:
lda accu + 1 lda accu + 1
sta accu sta accu
lda accu + 2 lda accu + 2
sta accu + 1 sta accu + 1
rts
}
__asm inp_conv_f32_i16
{
jsr f32_to_i16
jmp startup.exec jmp startup.exec
} }
#pragma bytecode(BC_CONV_F32_I16, inp_conv_f32_i16) #pragma bytecode(BC_CONV_F32_I16, inp_conv_f32_i16)
__asm inp_conv_f32_u16 __asm f32_to_u16
{ {
jsr freg.split_aexp jsr freg.split_aexp
lda tmp + 4 lda tmp + 4
@ -2344,7 +2437,7 @@ __asm inp_conv_f32_u16
lda #0 lda #0
sta accu sta accu
sta accu + 1 sta accu + 1
jmp startup.exec rts
W1: W1:
sec sec
sbc #$8e sbc #$8e
@ -2353,7 +2446,7 @@ W1:
lda #$ff lda #$ff
sta accu sta accu
sta accu + 1 sta accu + 1
jmp startup.exec rts
W3: W3:
tax tax
L1: L1:
@ -2367,6 +2460,25 @@ W2:
lda accu + 2 lda accu + 2
sta accu + 1 sta accu + 1
rts
}
#pragma runtime(fsplita, freg.split_aexp)
#pragma runtime(fsplitt, freg.split_texp)
#pragma runtime(fmergea, freg.merge_aexp)
#pragma runtime(faddsub, faddsub)
#pragma runtime(fmul, fmul)
#pragma runtime(fdiv, fdiv)
#pragma runtime(fcmp, fcmp)
#pragma runtime(ffromi, sint16_to_float)
#pragma runtime(ffromu, uint16_to_float)
#pragma runtime(ftoi, f32_to_i16)
#pragma runtime(ftou, f32_to_u16)
__asm inp_conv_f32_u16
{
jsr f32_to_u16
jmp startup.exec jmp startup.exec
} }
@ -2385,13 +2497,23 @@ __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};
__asm fround { __asm fround {
ffloor:
bit accu + 3
bpl frdown
bmi frup
fceil:
bit accu + 3
bmi frdown
bpl frup
frdzero: frdzero:
lda #0 lda #0
sta accu sta accu
sta accu + 1 sta accu + 1
sta accu + 2 sta accu + 2
sta accu + 3 sta accu + 3
jmp startup.exec rts
frdown: frdown:
lda tmp + 4 lda tmp + 4
@ -2437,8 +2559,7 @@ frd2:
jmp frd3 jmp frd3
frd3: frd3:
jsr freg.merge_aexp jmp freg.merge_aexp
jmp startup.exec
frone: frone:
lda #$7f lda #$7f
@ -2448,8 +2569,8 @@ frone:
sta accu + 1 sta accu + 1
lda #$80 lda #$80
sta accu + 2 sta accu + 2
jsr freg.merge_aexp jmp freg.merge_aexp
jmp startup.exec
frup: frup:
lda accu lda accu
ora accu + 1 ora accu + 1
@ -2528,17 +2649,32 @@ fru2:
W3: sta accu + 2 W3: sta accu + 2
jmp frdown jmp frdown
fru3: fru3:
jsr freg.merge_aexp jmp freg.merge_aexp
jmp startup.exec
} }
#pragma runtime(fsplita, freg.split_aexp)
#pragma runtime(fsplitt, freg.split_texp)
#pragma runtime(fmergea, freg.merge_aexp)
#pragma runtime(faddsub, faddsub)
#pragma runtime(fmul, fmul)
#pragma runtime(fdiv, fdiv)
#pragma runtime(fcmp, fcmp)
#pragma runtime(ffromi, sint16_to_float)
#pragma runtime(ffromu, uint16_to_float)
#pragma runtime(ftoi, f32_to_i16)
#pragma runtime(ftou, f32_to_u16)
#pragma runtime(ffloor, fround.ffloor)
#pragma runtime(fceil, fround.fceil)
__asm inp_op_floor_f32 __asm inp_op_floor_f32
{ {
jsr freg.split_aexp jsr freg.split_aexp
bit accu + 3 bit accu + 3
bpl W1 bpl W1
jmp fround.frup jsr fround.frup
W1: jmp fround.frdown jmp startup.exec
W1: jsr fround.frdown
jmp startup.exec
} }
#pragma bytecode(BC_OP_FLOOR_F32, inp_op_floor_f32) #pragma bytecode(BC_OP_FLOOR_F32, inp_op_floor_f32)
@ -2549,8 +2685,10 @@ __asm inp_op_ceil_f32
jsr freg.split_aexp jsr freg.split_aexp
bit accu + 3 bit accu + 3
bpl W1 bpl W1
jmp fround.frdown jsr fround.frdown
W1: jmp fround.frup jmp startup.exec
W1: jsr fround.frup
jmp startup.exec
} }
#pragma bytecode(BC_OP_CEIL_F32, inp_op_ceil_f32) #pragma bytecode(BC_OP_CEIL_F32, inp_op_ceil_f32)

View File

@ -2540,7 +2540,7 @@ ByteCodeBasicBlock* ByteCodeBasicBlock::BypassEmptyBlocks(void)
{ {
if (mBypassed) if (mBypassed)
return this; return this;
else if (!mFalseJump && mCode.Size() == 0) else if (!mFalseJump && mCode.Size() == 0 && this != mTrueJump)
return mTrueJump->BypassEmptyBlocks(); return mTrueJump->BypassEmptyBlocks();
else else
{ {
@ -2558,7 +2558,7 @@ ByteCodeBasicBlock* ByteCodeBasicBlock::BypassEmptyBlocks(void)
void ByteCodeBasicBlock::CopyCode(ByteCodeGenerator* generator, uint8 * target) void ByteCodeBasicBlock::CopyCode(ByteCodeGenerator* generator, uint8 * target)
{ {
int i; int i;
int next; int next, end;
int pos, at; int pos, at;
uint8 b; uint8 b;
@ -2573,7 +2573,8 @@ void ByteCodeBasicBlock::CopyCode(ByteCodeGenerator* generator, uint8 * target)
generator->mRelocations.Push(rl); generator->mRelocations.Push(rl);
} }
next = mOffset + mCode.Size(); end = mOffset + mCode.Size();
next = mOffset + mSize;
if (mFalseJump) if (mFalseJump)
{ {
@ -2581,29 +2582,29 @@ void ByteCodeBasicBlock::CopyCode(ByteCodeGenerator* generator, uint8 * target)
{ {
if (mTrueJump->mOffset <= mOffset) if (mTrueJump->mOffset <= mOffset)
{ {
next += PutBranch(generator, mBranch, mTrueJump->mOffset - next); end += PutBranch(generator, mBranch, mTrueJump->mOffset - end);
next += PutBranch(generator, BC_JUMPS, mFalseJump->mOffset - next); end += PutBranch(generator, BC_JUMPS, mFalseJump->mOffset - end);
} }
else else
{ {
next += PutBranch(generator, InvertBranchCondition(mBranch), mFalseJump->mOffset - next); end += PutBranch(generator, InvertBranchCondition(mBranch), mFalseJump->mOffset - end);
} }
} }
else else
{ {
next += PutBranch(generator, mBranch, mTrueJump->mOffset - next); end += PutBranch(generator, mBranch, mTrueJump->mOffset - end);
} }
} }
else if (mTrueJump) else if (mTrueJump)
{ {
if (mTrueJump->mOffset != next) if (mTrueJump->mOffset != next)
{ {
next += PutBranch(generator, BC_JUMPS, mTrueJump->mOffset - next); end += PutBranch(generator, BC_JUMPS, mTrueJump->mOffset - end);
} }
} }
assert(next - mOffset == mSize); assert(end == next);
for (i = 0; i < mCode.Size(); i++) for (i = 0; i < mCode.Size(); i++)
{ {

View File

@ -178,6 +178,17 @@ void NativeCodeBasicBlock::LoadConstant(InterCodeProcedure* proc, const InterIns
{ {
if (ins.mTType == IT_FLOAT) if (ins.mTType == IT_FLOAT)
{ {
union { float f; unsigned int v; } cc;
cc.f = ins.mFloatValue;
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, cc.v & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp]));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (cc.v >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 3));
} }
else if (ins.mTType == IT_POINTER) else if (ins.mTType == IT_POINTER)
{ {
@ -229,6 +240,146 @@ void NativeCodeBasicBlock::StoreValue(InterCodeProcedure* proc, const InterInstr
{ {
if (ins.mSType[0] == IT_FLOAT) if (ins.mSType[0] == IT_FLOAT)
{ {
if (ins.mSTemp[1] < 0)
{
if (ins.mSTemp[0] < 0)
{
if (ins.mMemory == IM_GLOBAL)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1], ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 1, ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 2, ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 3, ins.mVarIndex));
}
else if (ins.mMemory == IM_ABSOLUTE)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1]));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 3));
}
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{
int index = ins.mSIntConst[1];
if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset;
else
index += ins.mVarIndex + proc->mLocalSize + 2;
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
}
else if (ins.mMemory == IM_FRAME)
{
}
}
else
{
if (ins.mMemory == IM_GLOBAL)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1], ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 1, ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 2, ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 3, ins.mVarIndex));
}
else if (ins.mMemory == IM_ABSOLUTE)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1]));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE, ins.mSIntConst[1] + 3));
}
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{
int index = ins.mSIntConst[1];
if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset;
else
index += ins.mVarIndex + proc->mLocalSize + 2;
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
}
else if (ins.mMemory == IM_FRAME)
{
}
}
}
else
{
if (ins.mSTemp[0] < 0)
{
if (ins.mMemory == IM_INDIRECT)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]));
}
}
else
{
if (ins.mMemory == IM_INDIRECT)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]]));
}
}
}
} }
else if (ins.mSType[0] == IT_POINTER) else if (ins.mSType[0] == IT_POINTER)
{ {
@ -597,6 +748,70 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
{ {
if (ins.mTType == IT_FLOAT) if (ins.mTType == IT_FLOAT)
{ {
if (ins.mSTemp[0] < 0)
{
if (ins.mMemory == IM_GLOBAL)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0], ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0] + 1, ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0] + 2, ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0] + 3, ins.mVarIndex));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3));
}
else if (ins.mMemory == IM_ABSOLUTE)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0] + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3));
}
else if (ins.mMemory == IM_LOCAL || ins.mMemory == IM_PARAM)
{
int index = ins.mSIntConst[0];
if (ins.mMemory == IM_LOCAL)
index += proc->mLocalVars[ins.mVarIndex].mOffset;
else
index += ins.mVarIndex + proc->mLocalSize + 2;
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, index));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, mNoFrame ? BC_REG_STACK : BC_REG_LOCALS));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3));
}
}
else
{
if (ins.mMemory == IM_INDIRECT)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 2));
mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 3));
}
}
} }
else if (ins.mTType == IT_POINTER) else if (ins.mTType == IT_POINTER)
{ {
@ -784,6 +999,86 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
{ {
int treg = BC_REG_TMP + proc->mTempOffset[ins.mTTemp]; int treg = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
if (ins.mTType == IT_FLOAT)
{
if (ins.mSTemp[1] < 0)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[1] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[1] >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[1] >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[1] >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
}
else
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[1]] + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
}
if (ins.mSTemp[0] < 0)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[0] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[0] >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3));
}
else
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3));
}
mIns.Push(NativeCodeInstruction("fsplitt"));
switch (ins.mOperator)
{
case IA_ADD:
mIns.Push(NativeCodeInstruction("faddsub"));
break;
case IA_SUB:
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3));
mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 0x80));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3));
mIns.Push(NativeCodeInstruction("faddsub"));
break;
case IA_MUL:
mIns.Push(NativeCodeInstruction("fmul"));
break;
case IA_DIVS:
case IA_DIVU:
mIns.Push(NativeCodeInstruction("fdiv"));
break;
}
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 3));
}
else
{
switch (ins.mOperator) switch (ins.mOperator)
{ {
case IA_ADD: case IA_ADD:
@ -1183,6 +1478,7 @@ void NativeCodeBasicBlock::BinaryOperator(InterCodeProcedure* proc, const InterI
} break; } break;
} }
}
} }
void NativeCodeBasicBlock::UnaryOperator(InterCodeProcedure* proc, const InterInstruction& ins) void NativeCodeBasicBlock::UnaryOperator(InterCodeProcedure* proc, const InterInstruction& ins)
@ -1191,6 +1487,56 @@ void NativeCodeBasicBlock::UnaryOperator(InterCodeProcedure* proc, const InterIn
if (ins.mTType == IT_FLOAT) if (ins.mTType == IT_FLOAT)
{ {
switch (ins.mOperator)
{
case IA_NEG:
case IA_ABS:
if (ins.mSTemp[0] != ins.mTTemp)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 3));
}
else
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 3));
if (ins.mOperator == IA_NEG)
mIns.Push(NativeCodeInstruction(ASMIT_EOR, ASMIM_IMMEDIATE, 0x80));
else
mIns.Push(NativeCodeInstruction(ASMIT_AND, ASMIM_IMMEDIATE, 0x7f));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 3));
break;
case IA_FLOOR:
case IA_CEIL:
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
if (ins.mOperator == IA_FLOOR)
mIns.Push(NativeCodeInstruction("ffloor"));
else
mIns.Push(NativeCodeInstruction("fceil"));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 3));
break;
}
} }
else else
{ {
@ -1218,10 +1564,141 @@ void NativeCodeBasicBlock::UnaryOperator(InterCodeProcedure* proc, const InterIn
} }
} }
void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const InterInstruction& ins)
{
switch (ins.mOperator)
{
case IA_FLOAT2INT:
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
if (ins.mTType == IT_SIGNED)
mIns.Push(NativeCodeInstruction("ftoi"));
else
mIns.Push(NativeCodeInstruction("ftou"));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 1));
} break;
case IA_INT2FLOAT:
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
if (ins.mSType[0] == IT_SIGNED)
mIns.Push(NativeCodeInstruction("ffromi"));
else
mIns.Push(NativeCodeInstruction("fromu"));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 3));
} break;
}
}
void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const InterInstruction& ins, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump) void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const InterInstruction& ins, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock* falseJump)
{ {
InterOperator op = ins.mOperator; InterOperator op = ins.mOperator;
if (ins.mSType[0] == IT_FLOAT)
{
int li = 0, ri = 1;
if (op == IA_CMPLEU || op == IA_CMPGU || op == IA_CMPLES || op == IA_CMPGS)
{
li = 1; ri = 0;
}
if (ins.mSTemp[li] < 0)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[li] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[li] >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[li] >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[li] >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
}
else
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[li]] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[li]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[li]] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[li]] + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
}
if (ins.mSTemp[ri] < 0)
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, ins.mSIntConst[ri] & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[ri] >> 8) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[ri] >> 16) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, (ins.mSIntConst[ri] >> 24) & 0xff));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3));
}
else
{
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[ri]] + 0));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 0));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[ri]] + 1));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 1));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[ri]] + 2));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 2));
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[ri]] + 3));
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_WORK + 3));
}
mIns.Push(NativeCodeInstruction("fcmp"));
switch (op)
{
case IA_CMPEQ:
Close(trueJump, falseJump, ASMIT_BEQ);
break;
case IA_CMPNE:
Close(falseJump, trueJump, ASMIT_BEQ);
break;
case IA_CMPLU:
case IA_CMPLS:
case IA_CMPGU:
case IA_CMPGS:
Close(trueJump, falseJump, ASMIT_BMI);
break;
case IA_CMPLEU:
case IA_CMPLES:
case IA_CMPGEU:
case IA_CMPGES:
Close(falseJump, trueJump, ASMIT_BMI);
break;
}
}
else
{
NativeCodeBasicBlock* eblock = new NativeCodeBasicBlock(); NativeCodeBasicBlock* eblock = new NativeCodeBasicBlock();
eblock->mNoFrame = mNoFrame; eblock->mNoFrame = mNoFrame;
eblock->mIndex = 1000; eblock->mIndex = 1000;
@ -1307,6 +1784,7 @@ void NativeCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const In
break; break;
} }
}
} }
void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction& ins) void NativeCodeBasicBlock::LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction& ins)
@ -1629,12 +2107,12 @@ void NativeCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedu
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, tempSave + 2)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, tempSave + 2));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_STACK + 1));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_ADC, ASMIM_IMMEDIATE, 0));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
@ -1643,8 +2121,8 @@ void NativeCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedu
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED - 1)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED - 1));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_INDIRECT_Y, BC_REG_STACK));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BNE, ASMIM_RELATIVE, - 6)); entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BNE, ASMIM_RELATIVE, - 8));
} }
} }
@ -1656,24 +2134,24 @@ void NativeCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedu
if (!mNoFrame) if (!mNoFrame)
{ {
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, tempSave));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_INY, ASMIM_IMPLIED));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_LOCALS + 1));
if (tempSave) if (tempSave)
{ {
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_DEY, ASMIM_IMPLIED));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_BNE, ASMIM_RELATIVE, -6)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_BNE, ASMIM_RELATIVE, -8));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_STACK));
entryBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ABSOLUTE_Y, BC_REG_TMP_SAVED));
} }
exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED)); exitBlock->mIns.Push(NativeCodeInstruction(ASMIT_CLC, ASMIM_IMPLIED));
@ -1820,7 +2298,7 @@ void NativeCodeProcedure::CompileInterBlock(InterCodeProcedure* iproc, InterCode
block->UnaryOperator(iproc, ins); block->UnaryOperator(iproc, ins);
break; break;
case IC_CONVERSION_OPERATOR: case IC_CONVERSION_OPERATOR:
// NumericConversion(iproc, ins); block->NumericConversion(iproc, ins);
break; break;
case IC_LEA: case IC_LEA:
block->LoadEffectiveAddress(iproc, ins); block->LoadEffectiveAddress(iproc, ins);

View File

@ -63,6 +63,7 @@ public:
void UnaryOperator(InterCodeProcedure* proc, const InterInstruction& ins); void UnaryOperator(InterCodeProcedure* proc, const InterInstruction& ins);
void RelationalOperator(InterCodeProcedure* proc, const InterInstruction& ins, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump); void RelationalOperator(InterCodeProcedure* proc, const InterInstruction& ins, NativeCodeBasicBlock* trueJump, NativeCodeBasicBlock * falseJump);
void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction& ins); void LoadEffectiveAddress(InterCodeProcedure* proc, const InterInstruction& ins);
void NumericConversion(InterCodeProcedure* proc, const InterInstruction& ins);
}; };
class NativeCodeProcedure class NativeCodeProcedure