Add float long conversion
This commit is contained in:
parent
ce0ac30280
commit
ce710fca5d
|
@ -117,6 +117,9 @@ rem @echo off
|
|||
@call :test floatmultest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test floatinttest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
@call :test staticconsttest.c
|
||||
@if %errorlevel% neq 0 goto :error
|
||||
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
float a;
|
||||
int i;
|
||||
long li;
|
||||
unsigned u;
|
||||
unsigned long lu;
|
||||
|
||||
a = 1.0;
|
||||
i = 1;
|
||||
for(int j=0; j<15; j++)
|
||||
{
|
||||
assert(i == (int)a);
|
||||
assert(a == (float)i);
|
||||
a *= 2.0;
|
||||
i <<= 1;
|
||||
}
|
||||
|
||||
a = -1.0;
|
||||
i = -1;
|
||||
for(int j=0; j<15; j++)
|
||||
{
|
||||
assert(i == (int)a);
|
||||
assert(a == (float)i);
|
||||
a *= 2.0;
|
||||
i <<= 1;
|
||||
}
|
||||
|
||||
a = 1.0;
|
||||
u = 1;
|
||||
for(int j=0; j<16; j++)
|
||||
{
|
||||
assert(u == (unsigned)a);
|
||||
assert(a == (float)u);
|
||||
a *= 2.0;
|
||||
u <<= 1;
|
||||
}
|
||||
|
||||
a = 1.0;
|
||||
li = 1;
|
||||
for(int j=0; j<31; j++)
|
||||
{
|
||||
assert(li == (long)a);
|
||||
assert(a == (float)li);
|
||||
a *= 2.0;
|
||||
li <<= 1;
|
||||
}
|
||||
|
||||
a = -1.0;
|
||||
li = -1;
|
||||
for(int j=0; j<31; j++)
|
||||
{
|
||||
assert(li == (long)a);
|
||||
assert(a == (float)li);
|
||||
a *= 2.0;
|
||||
li <<= 1;
|
||||
}
|
||||
|
||||
a = 1.0;
|
||||
lu = 1;
|
||||
for(int j=0; j<32; j++)
|
||||
{
|
||||
assert(lu == (unsigned long)a);
|
||||
assert(a == (float)lu);
|
||||
a *= 2.0;
|
||||
lu <<= 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
184
include/crt.c
184
include/crt.c
|
@ -3518,6 +3518,102 @@ __asm inp_conv_i16_f32
|
|||
|
||||
#pragma bytecode(BC_CONV_I16_F32, inp_conv_i16_f32)
|
||||
|
||||
__asm uint32_to_float
|
||||
{
|
||||
lda accu
|
||||
ora accu + 1
|
||||
ora accu + 2
|
||||
ora accu + 3
|
||||
bne W1
|
||||
rts
|
||||
W1:
|
||||
ldx #$9e
|
||||
lda accu + 3
|
||||
bmi W2
|
||||
L1:
|
||||
dex
|
||||
asl accu
|
||||
rol accu + 1
|
||||
rol accu + 2
|
||||
rol
|
||||
bpl L1
|
||||
W2:
|
||||
bit accu
|
||||
bpl W3
|
||||
// check rounding
|
||||
inc accu + 1
|
||||
bne W3
|
||||
inc accu + 2
|
||||
bne W3
|
||||
clc
|
||||
adc #1
|
||||
bcc W3
|
||||
lsr
|
||||
ror accu + 2
|
||||
ror accu + 1
|
||||
inx
|
||||
W3:
|
||||
asl
|
||||
ldy accu + 1
|
||||
sty accu
|
||||
ldy accu + 2
|
||||
sty accu + 1
|
||||
sta accu + 2
|
||||
|
||||
txa
|
||||
lsr
|
||||
sta accu + 3
|
||||
ror accu + 2
|
||||
rts
|
||||
}
|
||||
|
||||
__asm sint32_to_float
|
||||
{
|
||||
bit accu + 3
|
||||
bmi W1
|
||||
jmp uint32_to_float
|
||||
W1:
|
||||
sec
|
||||
lda #0
|
||||
sbc accu
|
||||
sta accu
|
||||
lda #0
|
||||
sbc accu + 1
|
||||
sta accu + 1
|
||||
lda #0
|
||||
sbc accu + 2
|
||||
sta accu + 2
|
||||
lda #0
|
||||
sbc accu + 3
|
||||
sta accu + 3
|
||||
jsr uint32_to_float
|
||||
lda accu + 3
|
||||
ora #$80
|
||||
sta accu + 3
|
||||
rts
|
||||
}
|
||||
|
||||
|
||||
__asm inp_conv_u32_f32
|
||||
{
|
||||
sty tmpy
|
||||
jsr uint32_to_float
|
||||
ldy tmpy
|
||||
rts
|
||||
}
|
||||
|
||||
#pragma bytecode(BC_CONV_U32_F32, inp_conv_u32_f32)
|
||||
|
||||
__asm inp_conv_i32_f32
|
||||
{
|
||||
sty tmpy
|
||||
jsr sint32_to_float
|
||||
ldy tmpy
|
||||
rts
|
||||
}
|
||||
|
||||
#pragma bytecode(BC_CONV_I32_F32, inp_conv_i32_f32)
|
||||
|
||||
__asm f32_to_i16
|
||||
{
|
||||
jsr freg.split_aexp
|
||||
|
@ -3615,6 +3711,90 @@ __asm inp_conv_f32_u16
|
|||
|
||||
#pragma bytecode(BC_CONV_F32_U16, inp_conv_f32_u16)
|
||||
|
||||
__asm f32_to_u32
|
||||
{
|
||||
jsr freg.split_aexp
|
||||
lda tmp + 4
|
||||
cmp #$7f
|
||||
bcs W1
|
||||
lda #0
|
||||
F0:
|
||||
sta accu
|
||||
sta accu + 1
|
||||
sta accu + 2
|
||||
sta accu + 3
|
||||
rts
|
||||
W1:
|
||||
sec
|
||||
sbc #$9e
|
||||
beq W2
|
||||
bcc W3
|
||||
lda #$ff
|
||||
bne F0
|
||||
|
||||
W3:
|
||||
tax
|
||||
|
||||
lda #0
|
||||
L1:
|
||||
lsr accu + 2
|
||||
ror accu + 1
|
||||
ror accu + 0
|
||||
ror
|
||||
inx
|
||||
bne L1
|
||||
|
||||
W2:
|
||||
ldx accu + 2
|
||||
stx accu + 3
|
||||
ldx accu + 1
|
||||
stx accu + 2
|
||||
ldx accu
|
||||
stx accu + 1
|
||||
sta accu
|
||||
|
||||
rts
|
||||
}
|
||||
|
||||
__asm f32_to_i32
|
||||
{
|
||||
lda accu + 3
|
||||
bmi W1
|
||||
jmp f32_to_u32
|
||||
W1:
|
||||
jsr f32_to_u32
|
||||
|
||||
sec
|
||||
lda #0
|
||||
sbc accu
|
||||
sta accu
|
||||
lda #0
|
||||
sbc accu + 1
|
||||
sta accu + 1
|
||||
lda #0
|
||||
sbc accu + 2
|
||||
sta accu + 2
|
||||
lda #0
|
||||
sbc accu + 3
|
||||
sta accu + 3
|
||||
|
||||
rts
|
||||
}
|
||||
|
||||
__asm inp_conv_f32_i32
|
||||
{
|
||||
jmp f32_to_i32
|
||||
}
|
||||
|
||||
#pragma bytecode(BC_CONV_F32_I32, inp_conv_f32_i32)
|
||||
|
||||
__asm inp_conv_f32_u32
|
||||
{
|
||||
jmp f32_to_u32
|
||||
}
|
||||
|
||||
#pragma bytecode(BC_CONV_F32_U32, inp_conv_f32_u32)
|
||||
|
||||
__asm inp_op_abs_f32
|
||||
{
|
||||
lda accu + 3
|
||||
|
@ -3809,6 +3989,10 @@ fru3:
|
|||
#pragma runtime(ftou, f32_to_u16)
|
||||
#pragma runtime(ffloor, fround.ffloor)
|
||||
#pragma runtime(fceil, fround.fceil)
|
||||
#pragma runtime(ffromli, sint32_to_float)
|
||||
#pragma runtime(ffromlu, uint32_to_float)
|
||||
#pragma runtime(ftoli, f32_to_i32)
|
||||
#pragma runtime(ftolu, f32_to_u32)
|
||||
|
||||
__asm inp_op_floor_f32
|
||||
{
|
||||
|
|
|
@ -186,6 +186,11 @@ enum ByteCode
|
|||
BC_BINOP_SHR_I32,
|
||||
BC_BINOP_CMP_U32,
|
||||
BC_BINOP_CMP_S32,
|
||||
|
||||
BC_CONV_U32_F32,
|
||||
BC_CONV_I32_F32,
|
||||
BC_CONV_F32_U32,
|
||||
BC_CONV_F32_I32,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -623,6 +623,10 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used)
|
|||
case BC_OP_CEIL_F32:
|
||||
case BC_CONV_F32_U16:
|
||||
case BC_CONV_F32_I16:
|
||||
case BC_CONV_U32_F32:
|
||||
case BC_CONV_I32_F32:
|
||||
case BC_CONV_F32_U32:
|
||||
case BC_CONV_F32_I32:
|
||||
used = 0xffffffff;
|
||||
break;
|
||||
|
||||
|
@ -1278,6 +1282,23 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
|
|||
block->PutByte(mRegister);
|
||||
break;
|
||||
}
|
||||
case BC_CONV_U32_F32:
|
||||
case BC_CONV_I32_F32:
|
||||
case BC_CONV_F32_U32:
|
||||
case BC_CONV_F32_I32:
|
||||
{
|
||||
block->PutCode(generator, BC_EXTRT);
|
||||
|
||||
LinkerReference rl;
|
||||
rl.mOffset = block->mCode.Size();
|
||||
rl.mFlags = LREF_HIGHBYTE | LREF_LOWBYTE;
|
||||
rl.mRefObject = generator->mExtByteCodes[mCode - 128];
|
||||
rl.mRefOffset = 0;
|
||||
block->mRelocations.Push(rl);
|
||||
block->PutWord(0);
|
||||
block->PutByte(mRegister);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
|
@ -3721,6 +3742,67 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter
|
|||
|
||||
} break;
|
||||
|
||||
case IA_FLOAT2LINT:
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_32);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
|
||||
ByteCodeInstruction bins(BC_CONV_F32_I32);
|
||||
mIns.Push(bins);
|
||||
|
||||
ByteCodeInstruction sins(BC_STORE_REG_32);
|
||||
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
|
||||
mIns.Push(sins);
|
||||
|
||||
} break;
|
||||
case IA_LINT2FLOAT:
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_32);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
|
||||
ByteCodeInstruction bins(BC_CONV_I32_F32);
|
||||
mIns.Push(bins);
|
||||
|
||||
ByteCodeInstruction sins(BC_STORE_REG_32);
|
||||
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
|
||||
mIns.Push(sins);
|
||||
|
||||
} break;
|
||||
case IA_FLOAT2LUINT:
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_32);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
|
||||
ByteCodeInstruction bins(BC_CONV_F32_U32);
|
||||
mIns.Push(bins);
|
||||
|
||||
ByteCodeInstruction sins(BC_STORE_REG_32);
|
||||
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
|
||||
mIns.Push(sins);
|
||||
|
||||
} break;
|
||||
case IA_LUINT2FLOAT:
|
||||
{
|
||||
ByteCodeInstruction lins(BC_LOAD_REG_32);
|
||||
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp];
|
||||
lins.mRegisterFinal = ins->mSrc[0].mFinal;
|
||||
mIns.Push(lins);
|
||||
|
||||
ByteCodeInstruction bins(BC_CONV_U32_F32);
|
||||
mIns.Push(bins);
|
||||
|
||||
ByteCodeInstruction sins(BC_STORE_REG_32);
|
||||
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp];
|
||||
mIns.Push(sins);
|
||||
|
||||
} break;
|
||||
|
||||
case IA_EXT8TO16S:
|
||||
{
|
||||
if (ins->mSrc[0].mTemp == ins->mDst.mTemp)
|
||||
|
|
|
@ -186,7 +186,12 @@ enum ByteCode
|
|||
BC_BINOP_SHR_U32,
|
||||
BC_BINOP_SHR_I32,
|
||||
BC_BINOP_CMP_U32,
|
||||
BC_BINOP_CMP_S32
|
||||
BC_BINOP_CMP_S32,
|
||||
|
||||
BC_CONV_U32_F32,
|
||||
BC_CONV_I32_F32,
|
||||
BC_CONV_F32_U32,
|
||||
BC_CONV_F32_I32,
|
||||
};
|
||||
|
||||
class ByteCodeProcedure;
|
||||
|
|
|
@ -950,8 +950,12 @@ bool Compiler::GenerateCode(void)
|
|||
RegisterRuntime(loc, Ident::Unique("fceil"));
|
||||
RegisterRuntime(loc, Ident::Unique("ftoi"));
|
||||
RegisterRuntime(loc, Ident::Unique("ftou"));
|
||||
RegisterRuntime(loc, Ident::Unique("ftoli"));
|
||||
RegisterRuntime(loc, Ident::Unique("ftolu"));
|
||||
RegisterRuntime(loc, Ident::Unique("ffromi"));
|
||||
RegisterRuntime(loc, Ident::Unique("ffromu"));
|
||||
RegisterRuntime(loc, Ident::Unique("ffromli"));
|
||||
RegisterRuntime(loc, Ident::Unique("ffromlu"));
|
||||
RegisterRuntime(loc, Ident::Unique("fcmp"));
|
||||
RegisterRuntime(loc, Ident::Unique("bcexec"));
|
||||
RegisterRuntime(loc, Ident::Unique("jmpaddr"));
|
||||
|
|
|
@ -484,6 +484,19 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int bank
|
|||
fprintf(file, "CNVFS\tACCU");
|
||||
break;
|
||||
|
||||
case BC_CONV_U32_F32:
|
||||
fprintf(file, "CNVLUF\tACCU");
|
||||
break;
|
||||
case BC_CONV_I32_F32:
|
||||
fprintf(file, "CNVLSF\tACCU");
|
||||
break;
|
||||
case BC_CONV_F32_U32:
|
||||
fprintf(file, "CNVFLU\tACCU");
|
||||
break;
|
||||
case BC_CONV_F32_I32:
|
||||
fprintf(file, "CNVFLS\tACCU");
|
||||
break;
|
||||
|
||||
case BC_MALLOC:
|
||||
fprintf(file, "MALLOC\tACCU");
|
||||
break;
|
||||
|
|
|
@ -3074,6 +3074,8 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
|||
ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONVERSION_OPERATOR &&
|
||||
tvalue[ins->mSrc[1].mTemp]->mOperator != IA_FLOAT2INT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_INT2FLOAT &&
|
||||
tvalue[ins->mSrc[1].mTemp]->mOperator != IA_FLOAT2UINT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_UINT2FLOAT &&
|
||||
tvalue[ins->mSrc[1].mTemp]->mOperator != IA_FLOAT2LINT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_LINT2FLOAT &&
|
||||
tvalue[ins->mSrc[1].mTemp]->mOperator != IA_FLOAT2LUINT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_LUINT2FLOAT &&
|
||||
tvalue[ins->mSrc[0].mTemp]->mOperator == tvalue[ins->mSrc[1].mTemp]->mOperator)
|
||||
{
|
||||
ins->mSrc[0].mType = tvalue[ins->mSrc[0].mTemp]->mSrc[0].mType;
|
||||
|
@ -3086,7 +3088,9 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
|||
else if (ins->mSrc[1].mTemp >= 0 && tvalue[ins->mSrc[1].mTemp] && tvalue[ins->mSrc[1].mTemp]->mCode == IC_CONVERSION_OPERATOR &&
|
||||
ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT &&
|
||||
tvalue[ins->mSrc[1].mTemp]->mOperator != IA_FLOAT2INT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_INT2FLOAT &&
|
||||
tvalue[ins->mSrc[1].mTemp]->mOperator != IA_FLOAT2UINT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_UINT2FLOAT)
|
||||
tvalue[ins->mSrc[1].mTemp]->mOperator != IA_FLOAT2UINT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_UINT2FLOAT &&
|
||||
tvalue[ins->mSrc[1].mTemp]->mOperator != IA_FLOAT2LINT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_LINT2FLOAT &&
|
||||
tvalue[ins->mSrc[1].mTemp]->mOperator != IA_FLOAT2LUINT && tvalue[ins->mSrc[1].mTemp]->mOperator != IA_LUINT2FLOAT)
|
||||
{
|
||||
bool toconst = false;
|
||||
int cvalue = 0;
|
||||
|
@ -3287,8 +3291,10 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
|
|||
else if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONVERSION_OPERATOR &&
|
||||
ins->mSrc[1].mTemp >= 0 && tvalue[ins->mSrc[1].mTemp] && tvalue[ins->mSrc[1].mTemp]->mCode == IC_CONSTANT &&
|
||||
tvalue[ins->mSrc[0].mTemp]->mOperator != IA_FLOAT2INT && tvalue[ins->mSrc[0].mTemp]->mOperator != IA_INT2FLOAT &&
|
||||
tvalue[ins->mSrc[0].mTemp]->mOperator != IA_FLOAT2UINT && tvalue[ins->mSrc[0].mTemp]->mOperator != IA_UINT2FLOAT)
|
||||
{
|
||||
tvalue[ins->mSrc[0].mTemp]->mOperator != IA_FLOAT2UINT && tvalue[ins->mSrc[0].mTemp]->mOperator != IA_UINT2FLOAT &&
|
||||
tvalue[ins->mSrc[0].mTemp]->mOperator != IA_FLOAT2LINT && tvalue[ins->mSrc[0].mTemp]->mOperator != IA_LINT2FLOAT &&
|
||||
tvalue[ins->mSrc[0].mTemp]->mOperator != IA_FLOAT2LUINT && tvalue[ins->mSrc[0].mTemp]->mOperator != IA_LUINT2FLOAT)
|
||||
{
|
||||
bool toconst = false;
|
||||
int cvalue = 0;
|
||||
|
||||
|
@ -20393,7 +20399,7 @@ void InterCodeBasicBlock::PeepholeOptimization(const GrowingVariableArray& stati
|
|||
for (int i = 1; i < mInstructions.Size(); i++)
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
if (ins->mCode == IC_CONVERSION_OPERATOR && (ins->mOperator == IA_FLOAT2INT || ins->mOperator == IA_FLOAT2UINT) && ins->mSrc[0].mFinal)
|
||||
if (ins->mCode == IC_CONVERSION_OPERATOR && (ins->mOperator == IA_FLOAT2INT || ins->mOperator == IA_FLOAT2UINT || ins->mOperator == IA_FLOAT2LINT || ins->mOperator == IA_FLOAT2LUINT) && ins->mSrc[0].mFinal)
|
||||
{
|
||||
int j = i - 1;
|
||||
while (j > 0 && CanSwapInstructions(ins, mInstructions[j]))
|
||||
|
|
|
@ -105,10 +105,15 @@ enum InterOperator
|
|||
IA_CMPLEU,
|
||||
IA_CMPGU,
|
||||
IA_CMPLU,
|
||||
|
||||
IA_FLOAT2INT,
|
||||
IA_INT2FLOAT,
|
||||
IA_FLOAT2UINT,
|
||||
IA_UINT2FLOAT,
|
||||
IA_FLOAT2LINT,
|
||||
IA_LINT2FLOAT,
|
||||
IA_FLOAT2LUINT,
|
||||
IA_LUINT2FLOAT,
|
||||
|
||||
IA_EXT8TO16U,
|
||||
IA_EXT8TO32U,
|
||||
|
|
|
@ -349,8 +349,16 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p
|
|||
}
|
||||
|
||||
InterInstruction * cins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONVERSION_OPERATOR);
|
||||
cins->mOperator = (v.mType->mFlags & DTF_SIGNED) ? IA_INT2FLOAT : IA_UINT2FLOAT;
|
||||
cins->mSrc[0].mType = IT_INT16;
|
||||
if (v.mType->mSize <= 2)
|
||||
{
|
||||
cins->mOperator = (v.mType->mFlags & DTF_SIGNED) ? IA_INT2FLOAT : IA_UINT2FLOAT;
|
||||
cins->mSrc[0].mType = IT_INT16;
|
||||
}
|
||||
else
|
||||
{
|
||||
cins->mOperator = (v.mType->mFlags & DTF_SIGNED) ? IA_LINT2FLOAT : IA_LUINT2FLOAT;
|
||||
cins->mSrc[0].mType = IT_INT32;
|
||||
}
|
||||
cins->mSrc[0].mTemp = stemp;
|
||||
cins->mDst.mType = IT_FLOAT;
|
||||
cins->mDst.mTemp = proc->AddTemporary(IT_FLOAT);
|
||||
|
@ -364,11 +372,28 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p
|
|||
mErrors->Error(exp->mLocation, EWARN_FLOAT_TO_INT, "Float to int conversion, potential loss of precision");
|
||||
|
||||
InterInstruction * cins = new InterInstruction(MapLocation(exp, inlineMapper), IC_CONVERSION_OPERATOR);
|
||||
cins->mOperator = IA_FLOAT2INT;
|
||||
|
||||
if (type->mSize <= 2)
|
||||
{
|
||||
cins->mDst.mType = IT_INT16;
|
||||
if (type->mFlags & DTF_SIGNED)
|
||||
cins->mOperator = IA_FLOAT2INT;
|
||||
else
|
||||
cins->mOperator = IA_FLOAT2UINT;
|
||||
}
|
||||
else
|
||||
{
|
||||
cins->mDst.mType = IT_INT32;
|
||||
if (type->mFlags & DTF_SIGNED)
|
||||
cins->mOperator = IA_FLOAT2LINT;
|
||||
else
|
||||
cins->mOperator = IA_FLOAT2LUINT;
|
||||
}
|
||||
|
||||
cins->mSrc[0].mType = IT_FLOAT;
|
||||
cins->mSrc[0].mTemp = v.mTemp;
|
||||
cins->mDst.mType = IT_INT16;
|
||||
cins->mDst.mTemp = proc->AddTemporary(IT_INT16);
|
||||
|
||||
cins->mDst.mTemp = proc->AddTemporary(cins->mDst.mType);
|
||||
block->Append(cins);
|
||||
v.mTemp = cins->mDst.mTemp;
|
||||
v.mType = type;
|
||||
|
@ -4845,8 +4870,17 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
}
|
||||
}
|
||||
|
||||
ins->mOperator = (vr.mType->mFlags & DTF_SIGNED) ? IA_INT2FLOAT : IA_UINT2FLOAT;
|
||||
ins->mSrc[0].mType = IT_INT16;
|
||||
if (vr.mType->mSize <= 2)
|
||||
{
|
||||
ins->mOperator = (vr.mType->mFlags & DTF_SIGNED) ? IA_INT2FLOAT : IA_UINT2FLOAT;
|
||||
ins->mSrc[0].mType = IT_INT16;
|
||||
}
|
||||
else
|
||||
{
|
||||
ins->mOperator = (vr.mType->mFlags & DTF_SIGNED) ? IA_LINT2FLOAT : IA_LUINT2FLOAT;
|
||||
ins->mSrc[0].mType = IT_INT32;
|
||||
}
|
||||
|
||||
ins->mSrc[0].mTemp = stemp;
|
||||
ins->mDst.mType = InterTypeOf(exp->mDecType);
|
||||
ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
|
||||
|
@ -4855,11 +4889,20 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
else if (exp->mDecType->IsIntegerType() && vr.mType->mType == DT_TYPE_FLOAT)
|
||||
{
|
||||
vr = Dereference(proc, exp, block, inlineMapper, vr);
|
||||
ins->mOperator = (exp->mDecType->mFlags & DTF_SIGNED) ? IA_FLOAT2INT : IA_FLOAT2UINT;
|
||||
if (exp->mDecType->mSize <= 2)
|
||||
{
|
||||
ins->mOperator = (exp->mDecType->mFlags & DTF_SIGNED) ? IA_FLOAT2INT : IA_FLOAT2UINT;
|
||||
ins->mDst.mType = IT_INT16;
|
||||
}
|
||||
else
|
||||
{
|
||||
ins->mOperator = (exp->mDecType->mFlags & DTF_SIGNED) ? IA_FLOAT2LINT : IA_FLOAT2LUINT;
|
||||
ins->mDst.mType = IT_INT32;
|
||||
}
|
||||
|
||||
ins->mSrc[0].mType = InterTypeOf(vr.mType);
|
||||
ins->mSrc[0].mTemp = vr.mTemp;
|
||||
ins->mDst.mType = IT_INT16;
|
||||
ins->mDst.mTemp = proc->AddTemporary(IT_INT16);
|
||||
ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
|
||||
block->Append(ins);
|
||||
|
||||
if (exp->mDecType->mSize == 1)
|
||||
|
|
|
@ -12201,6 +12201,102 @@ void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, NativeCod
|
|||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 3));
|
||||
|
||||
} break;
|
||||
case IA_FLOAT2LINT:
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 3));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
|
||||
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("ftoli")));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_LOWER | NCIF_UPPER));
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 3));
|
||||
|
||||
} break;
|
||||
case IA_LINT2FLOAT:
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 3));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
|
||||
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("ffromli")));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_LOWER | NCIF_UPPER));
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 3));
|
||||
|
||||
} break;
|
||||
case IA_FLOAT2LUINT:
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 3));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
|
||||
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("ftolu")));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_LOWER | NCIF_UPPER));
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 3));
|
||||
|
||||
} break;
|
||||
case IA_LUINT2FLOAT:
|
||||
{
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp] + 3));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
|
||||
|
||||
NativeCodeGenerator::Runtime& frt(nproc->mGenerator->ResolveRuntime(Ident::Unique("ffromlu")));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_JSR, ASMIM_ABSOLUTE, frt.mOffset, frt.mLinkerObject, NCIF_RUNTIME | NCIF_LOWER | NCIF_UPPER));
|
||||
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 0));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 1));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 2));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mDst.mTemp] + 3));
|
||||
|
||||
} break;
|
||||
case IA_EXT8TO16S:
|
||||
mIns.Push(NativeCodeInstruction(ins, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins->mSrc[0].mTemp]));
|
||||
|
|
Loading…
Reference in New Issue