Prepare byte level optimisations
This commit is contained in:
parent
9f8362255f
commit
e2e20581a6
|
@ -8,6 +8,7 @@ float sum(float * a, int s)
|
||||||
{
|
{
|
||||||
sum += a[i];
|
sum += a[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +19,7 @@ int main(void)
|
||||||
{
|
{
|
||||||
a[i] = i % 10;
|
a[i] = i % 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(sum(a, 100) == 450);
|
assert(sum(a, 100) == 450);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -223,71 +223,6 @@ L2: jsr divmod
|
||||||
#pragma runtime(divs16, divs16);
|
#pragma runtime(divs16, divs16);
|
||||||
#pragma runtime(mods16, mods16);
|
#pragma runtime(mods16, mods16);
|
||||||
|
|
||||||
/*
|
|
||||||
!align 255, 0
|
|
||||||
inptable
|
|
||||||
!word inp_nop
|
|
||||||
!word inp_exit
|
|
||||||
|
|
||||||
!word inp_const_p8, inp_const_n8, inp_const_16, inp_const_32
|
|
||||||
|
|
||||||
!word inp_load_reg_16, inp_store_reg_16, inp_addr_reg, inp_load_reg_32, inp_store_reg_32
|
|
||||||
|
|
||||||
!word inp_load_abs_u8, inp_load_abs_s8, inp_load_abs_16, inp_load_abs_32
|
|
||||||
!word inp_store_abs_8, inp_store_abs_16, inp_store_abs_32
|
|
||||||
!word inp_lea_abs
|
|
||||||
|
|
||||||
!word inp_load_local_u8, inp_load_local_s8, inp_load_local_16, inp_load_local_32
|
|
||||||
!word inp_store_local_8, inp_store_local_16, inp_store_local_32
|
|
||||||
!word inp_lea_local
|
|
||||||
|
|
||||||
!word inp_store_frame_8, inp_store_frame_16, inp_store_frame_32
|
|
||||||
|
|
||||||
!word inp_load_addr_u8, inp_load_addr_s8, inp_load_addr_16, inp_load_addr_32
|
|
||||||
!word inp_store_addr_8, inp_store_addr_16, inp_store_addr_32
|
|
||||||
|
|
||||||
!word inp_binop_addr_16, inp_binop_subr_16
|
|
||||||
!word inp_binop_andr_16, inp_binop_orr_16, inp_binop_xorr_16
|
|
||||||
!word inp_binop_mulr_16, inp_binop_divr_u16, inp_binop_modr_u16, inp_binop_divr_s16, inp_binop_modr_s16
|
|
||||||
!word inp_binop_shlr_16, inp_binop_shrr_u16, inp_binop_shrr_s16
|
|
||||||
|
|
||||||
!word inp_binop_addi_16, inp_binop_subi_16, inp_binop_andi_16, inp_binop_ori_16, inp_binop_muli8_16
|
|
||||||
!word inp_binop_shli_16, inp_binop_shri_u16, inp_binop_shri_s16
|
|
||||||
|
|
||||||
!word inp_binop_cmpr_u16, inp_binop_cmpr_s16
|
|
||||||
!word inp_binop_cmpi_u16, inp_binop_cmpi_s16
|
|
||||||
|
|
||||||
!word inp_op_negate_16, inp_op_invert_16
|
|
||||||
|
|
||||||
!word inp_binop_add_f32, inp_binop_sub_f32, inp_binop_mul_f32, inp_binop_div_f32
|
|
||||||
!word inp_binop_cmp_f32
|
|
||||||
!word inp_op_negate_f32, inp_op_abs_f32, inp_op_floor_f32, inp_op_ceil_f32
|
|
||||||
|
|
||||||
!word inp_conv_u16_f32, inp_conv_i16_f32, inp_conv_f32_u16, inp_conv_f32_i16
|
|
||||||
|
|
||||||
!word inp_jumps
|
|
||||||
!word inp_branchs_eq, inp_branchs_ne
|
|
||||||
!word inp_branchs_gt, inp_branchs_ge
|
|
||||||
!word inp_branchs_lt, inp_branchs_le
|
|
||||||
|
|
||||||
!word inp_jumpf
|
|
||||||
!word inp_branchf_eq, inp_branchf_ne
|
|
||||||
!word inp_branchf_gt, inp_branchf_ge
|
|
||||||
!word inp_branchf_lt, inp_branchf_le
|
|
||||||
|
|
||||||
!word inp_set_eq, inp_set_ne
|
|
||||||
!word inp_set_gt, inp_set_ge
|
|
||||||
!word inp_set_lt, inp_set_le
|
|
||||||
|
|
||||||
!word inp_enter
|
|
||||||
!word inp_return
|
|
||||||
!word inp_call
|
|
||||||
!word inp_push_frame, inp_pop_frame
|
|
||||||
|
|
||||||
!word inp_jsr
|
|
||||||
|
|
||||||
!word inp_copy, inp_copyl
|
|
||||||
*/
|
|
||||||
|
|
||||||
__asm inp_nop
|
__asm inp_nop
|
||||||
{
|
{
|
||||||
|
@ -481,6 +416,21 @@ __asm inp_store_reg_32
|
||||||
|
|
||||||
#pragma bytecode(BC_STORE_REG_32, inp_store_reg_32)
|
#pragma bytecode(BC_STORE_REG_32, inp_store_reg_32)
|
||||||
|
|
||||||
|
__asm inp_conv_s8_s16
|
||||||
|
{
|
||||||
|
lda (ip), y
|
||||||
|
tax
|
||||||
|
iny
|
||||||
|
lda #$80
|
||||||
|
and $00, x
|
||||||
|
bpl W1
|
||||||
|
lda #$ff
|
||||||
|
W1: sta $01, x
|
||||||
|
jmp startup.exec
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma bytecode(BC_CONV_I8_I16, inp_conv_s8_s16)
|
||||||
|
|
||||||
__asm inp_addr_reg
|
__asm inp_addr_reg
|
||||||
{
|
{
|
||||||
lda (ip), y
|
lda (ip), y
|
||||||
|
|
|
@ -113,6 +113,8 @@ enum ByteCode
|
||||||
BC_CONV_F32_U16,
|
BC_CONV_F32_U16,
|
||||||
BC_CONV_F32_I16,
|
BC_CONV_F32_I16,
|
||||||
|
|
||||||
|
BC_CONV_I8_I16,
|
||||||
|
|
||||||
BC_JUMPS,
|
BC_JUMPS,
|
||||||
BC_BRANCHS_EQ,
|
BC_BRANCHS_EQ,
|
||||||
BC_BRANCHS_NE,
|
BC_BRANCHS_NE,
|
||||||
|
|
|
@ -364,6 +364,11 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
|
||||||
block->PutCode(generator, mCode);
|
block->PutCode(generator, mCode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BC_CONV_I8_I16:
|
||||||
|
block->PutCode(generator, mCode);
|
||||||
|
block->PutByte(mRegister);
|
||||||
|
break;
|
||||||
|
|
||||||
case BC_JUMPS:
|
case BC_JUMPS:
|
||||||
case BC_BRANCHS_EQ:
|
case BC_BRANCHS_EQ:
|
||||||
case BC_BRANCHS_NE:
|
case BC_BRANCHS_NE:
|
||||||
|
@ -1371,7 +1376,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
||||||
{
|
{
|
||||||
if (ins.mMemory == IM_GLOBAL)
|
if (ins.mMemory == IM_GLOBAL)
|
||||||
{
|
{
|
||||||
ByteCodeInstruction bins(ins.mTType == IT_SIGNED ? BC_LOAD_ABS_I8 : BC_LOAD_ABS_U8);
|
ByteCodeInstruction bins(BC_LOAD_ABS_U8);
|
||||||
bins.mRelocate = true;
|
bins.mRelocate = true;
|
||||||
bins.mVIndex = ins.mVarIndex;
|
bins.mVIndex = ins.mVarIndex;
|
||||||
bins.mValue = ins.mSIntConst[0];
|
bins.mValue = ins.mSIntConst[0];
|
||||||
|
@ -1380,7 +1385,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
||||||
}
|
}
|
||||||
else if (ins.mMemory == IM_ABSOLUTE)
|
else if (ins.mMemory == IM_ABSOLUTE)
|
||||||
{
|
{
|
||||||
ByteCodeInstruction bins(ins.mTType == IT_SIGNED ? BC_LOAD_ABS_I8 : BC_LOAD_ABS_U8);
|
ByteCodeInstruction bins(BC_LOAD_ABS_U8);
|
||||||
bins.mValue = ins.mSIntConst[0];
|
bins.mValue = ins.mSIntConst[0];
|
||||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
|
||||||
mIns.Push(bins);
|
mIns.Push(bins);
|
||||||
|
@ -1395,7 +1400,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
||||||
|
|
||||||
if (index <= 255)
|
if (index <= 255)
|
||||||
{
|
{
|
||||||
ByteCodeInstruction bins(ins.mTType == IT_SIGNED ? BC_LOAD_LOCAL_I8 : BC_LOAD_LOCAL_U8);
|
ByteCodeInstruction bins(BC_LOAD_LOCAL_U8);
|
||||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
|
||||||
bins.mValue = index;
|
bins.mValue = index;
|
||||||
mIns.Push(bins);
|
mIns.Push(bins);
|
||||||
|
@ -1406,7 +1411,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
||||||
lins.mRegister = BC_REG_ADDR;
|
lins.mRegister = BC_REG_ADDR;
|
||||||
lins.mValue = index;
|
lins.mValue = index;
|
||||||
mIns.Push(lins);
|
mIns.Push(lins);
|
||||||
ByteCodeInstruction bins(ins.mTType == IT_SIGNED ? BC_LOAD_ADDR_I8 : BC_LOAD_ADDR_U8);
|
ByteCodeInstruction bins(BC_LOAD_ADDR_U8);
|
||||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
|
||||||
bins.mValue = 0;
|
bins.mValue = 0;
|
||||||
mIns.Push(bins);
|
mIns.Push(bins);
|
||||||
|
@ -1471,20 +1476,10 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
||||||
|
|
||||||
if (ins.mOperandSize == 1)
|
if (ins.mOperandSize == 1)
|
||||||
{
|
{
|
||||||
if (ins.mTType == IT_SIGNED)
|
ByteCodeInstruction bins(BC_LOAD_ADDR_U8);
|
||||||
{
|
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
|
||||||
ByteCodeInstruction bins(BC_LOAD_ADDR_I8);
|
bins.mValue = ins.mSIntConst[0];
|
||||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
|
mIns.Push(bins);
|
||||||
bins.mValue = ins.mSIntConst[0];
|
|
||||||
mIns.Push(bins);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ByteCodeInstruction bins(BC_LOAD_ADDR_U8);
|
|
||||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
|
|
||||||
bins.mValue = ins.mSIntConst[0];
|
|
||||||
mIns.Push(bins);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (ins.mOperandSize == 2)
|
else if (ins.mOperandSize == 2)
|
||||||
{
|
{
|
||||||
|
@ -1820,7 +1815,8 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter
|
||||||
lins.mRegisterFinal = ins.mSFinal[0];
|
lins.mRegisterFinal = ins.mSFinal[0];
|
||||||
mIns.Push(lins);
|
mIns.Push(lins);
|
||||||
|
|
||||||
ByteCodeInstruction bins(ins.mTType == IT_SIGNED ? BC_CONV_F32_I16 : BC_CONV_F32_U16);
|
ByteCodeInstruction bins(BC_CONV_F32_I16);
|
||||||
|
// ByteCodeInstruction bins(ins.mTType == IT_SIGNED ? BC_CONV_F32_I16 : BC_CONV_F32_U16);
|
||||||
mIns.Push(bins);
|
mIns.Push(bins);
|
||||||
|
|
||||||
ByteCodeInstruction sins(BC_STORE_REG_16);
|
ByteCodeInstruction sins(BC_STORE_REG_16);
|
||||||
|
@ -1835,7 +1831,8 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter
|
||||||
lins.mRegisterFinal = ins.mSFinal[0];
|
lins.mRegisterFinal = ins.mSFinal[0];
|
||||||
mIns.Push(lins);
|
mIns.Push(lins);
|
||||||
|
|
||||||
ByteCodeInstruction bins(ins.mSType[0] == IT_SIGNED ? BC_CONV_I16_F32 : BC_CONV_U16_F32);
|
ByteCodeInstruction bins(BC_CONV_I16_F32);
|
||||||
|
// ByteCodeInstruction bins(ins.mSType[0] == IT_SIGNED ? BC_CONV_I16_F32 : BC_CONV_U16_F32);
|
||||||
mIns.Push(bins);
|
mIns.Push(bins);
|
||||||
|
|
||||||
ByteCodeInstruction sins(BC_STORE_REG_32);
|
ByteCodeInstruction sins(BC_STORE_REG_32);
|
||||||
|
@ -1843,6 +1840,59 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter
|
||||||
mIns.Push(sins);
|
mIns.Push(sins);
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
case IA_EXT8TO16S:
|
||||||
|
{
|
||||||
|
if (ins.mSTemp[0] == ins.mTTemp)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction cins(BC_CONV_I8_I16);
|
||||||
|
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
|
||||||
|
cins.mRegisterFinal = ins.mSFinal[0];
|
||||||
|
mIns.Push(cins);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||||
|
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]];
|
||||||
|
lins.mRegisterFinal = ins.mSFinal[0];
|
||||||
|
mIns.Push(lins);
|
||||||
|
|
||||||
|
ByteCodeInstruction cins(BC_CONV_I8_I16);
|
||||||
|
cins.mRegister = BC_REG_ACCU;
|
||||||
|
mIns.Push(cins);
|
||||||
|
|
||||||
|
ByteCodeInstruction sins(BC_STORE_REG_16);
|
||||||
|
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
|
||||||
|
mIns.Push(sins);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case IA_EXT8TO16U:
|
||||||
|
{
|
||||||
|
if (ins.mSTemp[0] == ins.mTTemp)
|
||||||
|
{
|
||||||
|
ByteCodeInstruction cins(BC_BINOP_ANDI_16);
|
||||||
|
cins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
|
||||||
|
cins.mRegisterFinal = ins.mSFinal[0];
|
||||||
|
cins.mValue = 0x00ff;
|
||||||
|
mIns.Push(cins);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ByteCodeInstruction lins(BC_LOAD_REG_16);
|
||||||
|
lins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]];
|
||||||
|
lins.mRegisterFinal = ins.mSFinal[0];
|
||||||
|
mIns.Push(lins);
|
||||||
|
|
||||||
|
ByteCodeInstruction cins(BC_BINOP_ANDI_16);
|
||||||
|
cins.mRegister = BC_REG_ACCU;
|
||||||
|
cins.mValue = 0x00ff;
|
||||||
|
mIns.Push(cins);
|
||||||
|
|
||||||
|
ByteCodeInstruction sins(BC_STORE_REG_16);
|
||||||
|
sins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
|
||||||
|
mIns.Push(sins);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2622,7 +2672,24 @@ void ByteCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
mIns[i + 1].mCode = BC_NOP;
|
mIns[i + 1].mCode = BC_NOP;
|
||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
else if (mIns[i].mCode == BC_LOAD_ABS_U8 && mIns[i + 1].mCode == BC_CONV_I8_I16 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
|
||||||
|
{
|
||||||
|
mIns[i].mCode = BC_LOAD_ABS_I8;
|
||||||
|
mIns[i + 1].mCode = BC_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (mIns[i].mCode == BC_LOAD_LOCAL_U8 && mIns[i + 1].mCode == BC_CONV_I8_I16 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
|
||||||
|
{
|
||||||
|
mIns[i].mCode = BC_LOAD_LOCAL_I8;
|
||||||
|
mIns[i + 1].mCode = BC_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
else if (mIns[i].mCode == BC_LOAD_ADDR_U8 && mIns[i + 1].mCode == BC_CONV_I8_I16 && mIns[i].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
|
||||||
|
{
|
||||||
|
mIns[i].mCode = BC_LOAD_ADDR_I8;
|
||||||
|
mIns[i + 1].mCode = BC_NOP;
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mIns[i].mCode == BC_LOAD_REG_16 || mIns[i].mCode == BC_STORE_REG_16 || mIns[i].mCode == BC_LOAD_REG_32 || mIns[i].mCode == BC_STORE_REG_32) && accuTemp == mIns[i].mRegister)
|
if ((mIns[i].mCode == BC_LOAD_REG_16 || mIns[i].mCode == BC_STORE_REG_16 || mIns[i].mCode == BC_LOAD_REG_32 || mIns[i].mCode == BC_STORE_REG_32) && accuTemp == mIns[i].mRegister)
|
||||||
|
@ -3206,6 +3273,11 @@ void ByteCodeProcedure::Disassemble(FILE * file, ByteCodeGenerator * generator,
|
||||||
i += 2;
|
i += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case BC_CONV_I8_I16:
|
||||||
|
fprintf(file, "SEXT8\t%s", TempName(generator->mMemory[mProgStart + i + 0], tbuffer, proc));
|
||||||
|
i ++;
|
||||||
|
break;
|
||||||
|
|
||||||
case BC_BINOP_SHLI_16:
|
case BC_BINOP_SHLI_16:
|
||||||
fprintf(file, "SHL\tACCU, #%d", uint8(generator->mMemory[mProgStart + i + 0]));
|
fprintf(file, "SHL\tACCU, #%d", uint8(generator->mMemory[mProgStart + i + 0]));
|
||||||
i += 1;
|
i += 1;
|
||||||
|
|
|
@ -102,6 +102,8 @@ enum ByteCode
|
||||||
BC_CONV_F32_U16,
|
BC_CONV_F32_U16,
|
||||||
BC_CONV_F32_I16,
|
BC_CONV_F32_I16,
|
||||||
|
|
||||||
|
BC_CONV_I8_I16,
|
||||||
|
|
||||||
BC_JUMPS,
|
BC_JUMPS,
|
||||||
BC_BRANCHS_EQ,
|
BC_BRANCHS_EQ,
|
||||||
BC_BRANCHS_NE,
|
BC_BRANCHS_NE,
|
||||||
|
|
|
@ -470,7 +470,7 @@ bool Declaration::IsNumericType(void) const
|
||||||
return mType == DT_TYPE_INTEGER || mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_ENUM;
|
return mType == DT_TYPE_INTEGER || mType == DT_TYPE_BOOL || mType == DT_TYPE_FLOAT || mType == DT_TYPE_ENUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstSignedCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration, * TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration;
|
Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstCharTypeDeclaration, * TheCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration, * TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration;
|
||||||
|
|
||||||
void InitDeclarations(void)
|
void InitDeclarations(void)
|
||||||
{
|
{
|
||||||
|
@ -495,13 +495,14 @@ void InitDeclarations(void)
|
||||||
TheSignedCharTypeDeclaration->mSize = 1;
|
TheSignedCharTypeDeclaration->mSize = 1;
|
||||||
TheSignedCharTypeDeclaration->mFlags = DTF_DEFINED | DTF_SIGNED;
|
TheSignedCharTypeDeclaration->mFlags = DTF_DEFINED | DTF_SIGNED;
|
||||||
|
|
||||||
TheConstSignedCharTypeDeclaration = new Declaration(noloc, DT_TYPE_INTEGER);
|
TheConstCharTypeDeclaration = new Declaration(noloc, DT_TYPE_INTEGER);
|
||||||
TheConstSignedCharTypeDeclaration->mSize = 1;
|
TheConstCharTypeDeclaration->mSize = 1;
|
||||||
TheConstSignedCharTypeDeclaration->mFlags = DTF_DEFINED | DTF_SIGNED | DTF_CONST;
|
TheConstCharTypeDeclaration->mFlags = DTF_DEFINED | DTF_CONST;
|
||||||
|
|
||||||
TheUnsignedCharTypeDeclaration = new Declaration(noloc, DT_TYPE_INTEGER);
|
TheUnsignedCharTypeDeclaration = new Declaration(noloc, DT_TYPE_INTEGER);
|
||||||
TheUnsignedCharTypeDeclaration->mSize = 1;
|
TheUnsignedCharTypeDeclaration->mSize = 1;
|
||||||
TheUnsignedCharTypeDeclaration->mFlags = DTF_DEFINED;
|
TheUnsignedCharTypeDeclaration->mFlags = DTF_DEFINED;
|
||||||
|
TheCharTypeDeclaration = TheUnsignedCharTypeDeclaration;
|
||||||
|
|
||||||
TheBoolTypeDeclaration = new Declaration(noloc, DT_TYPE_BOOL);
|
TheBoolTypeDeclaration = new Declaration(noloc, DT_TYPE_BOOL);
|
||||||
TheBoolTypeDeclaration->mSize = 1;
|
TheBoolTypeDeclaration->mSize = 1;
|
||||||
|
|
|
@ -166,4 +166,4 @@ public:
|
||||||
|
|
||||||
void InitDeclarations(void);
|
void InitDeclarations(void);
|
||||||
|
|
||||||
extern Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstSignedCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration, * TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration;
|
extern Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstCharTypeDeclaration, * TheCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration, * TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration;
|
||||||
|
|
|
@ -65,7 +65,7 @@ void Emulator::DumpCycles(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Total Cycles %d\n", totalCycles);
|
printf("Total Cycles %d\n", totalCycles);
|
||||||
// return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < numTops; i++)
|
for (int i = 0; i < numTops; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -226,6 +226,33 @@ static double ConstantFolding(InterOperator oper, double val1, double val2 = 0.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ConversionConstantFold(InterInstruction& ins, InterInstruction * cins)
|
||||||
|
{
|
||||||
|
switch (ins.mOperator)
|
||||||
|
{
|
||||||
|
case IA_INT2FLOAT:
|
||||||
|
ins.mCode = IC_CONSTANT;
|
||||||
|
ins.mFloatValue = (double)(cins->mIntValue);
|
||||||
|
ins.mSTemp[0] = -1;
|
||||||
|
break;
|
||||||
|
case IA_FLOAT2INT:
|
||||||
|
ins.mCode = IC_CONSTANT;
|
||||||
|
ins.mIntValue = (int)(cins->mFloatValue);
|
||||||
|
ins.mSTemp[0] = -1;
|
||||||
|
break;
|
||||||
|
case IA_EXT8TO16S:
|
||||||
|
ins.mCode = IC_CONSTANT;
|
||||||
|
ins.mIntValue = (char)(cins->mIntValue);
|
||||||
|
ins.mSTemp[0] = -1;
|
||||||
|
break;
|
||||||
|
case IA_EXT8TO16U:
|
||||||
|
ins.mCode = IC_CONSTANT;
|
||||||
|
ins.mIntValue = (unsigned char)(cins->mIntValue);
|
||||||
|
ins.mSTemp[0] = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ValueSet::InsertValue(InterInstruction& ins)
|
void ValueSet::InsertValue(InterInstruction& ins)
|
||||||
{
|
{
|
||||||
InterInstructionPtr* nins;
|
InterInstructionPtr* nins;
|
||||||
|
@ -717,14 +744,11 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IC_CONVERSION_OPERATOR:
|
case IC_CONVERSION_OPERATOR:
|
||||||
if (ins.mOperator == IA_INT2FLOAT)
|
if (ins.mSTemp[0] >= 0 && tvalue[ins.mSTemp[0]] && tvalue[ins.mSTemp[0]]->mCode == IC_CONSTANT)
|
||||||
{
|
{
|
||||||
if (ins.mSTemp[0] >= 0 && tvalue[ins.mSTemp[0]] && tvalue[ins.mSTemp[0]]->mCode == IC_CONSTANT)
|
ConversionConstantFold(ins, tvalue[ins.mSTemp[0]]);
|
||||||
|
if (ins.mTType == IT_FLOAT)
|
||||||
{
|
{
|
||||||
ins.mCode = IC_CONSTANT;
|
|
||||||
ins.mFloatValue = (double)(tvalue[ins.mSTemp[0]]->mIntValue);
|
|
||||||
ins.mSTemp[0] = -1;
|
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < mNum &&
|
while (i < mNum &&
|
||||||
(mInstructions[i]->mCode != IC_CONSTANT ||
|
(mInstructions[i]->mCode != IC_CONSTANT ||
|
||||||
|
@ -748,31 +772,32 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
i = 0;
|
InsertValue(ins);
|
||||||
while (i < mNum &&
|
|
||||||
(mInstructions[i]->mCode != IC_CONVERSION_OPERATOR ||
|
|
||||||
mInstructions[i]->mOperator != ins.mOperator ||
|
|
||||||
mInstructions[i]->mSTemp[0] != ins.mSTemp[0]))
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < mNum)
|
|
||||||
{
|
|
||||||
ins.mCode = IC_LOAD_TEMPORARY;
|
|
||||||
ins.mSTemp[0] = mInstructions[i]->mTTemp;
|
|
||||||
ins.mSType[0] = mInstructions[i]->mTType;
|
|
||||||
ins.mSTemp[1] = -1;
|
|
||||||
assert(ins.mSTemp[0] >= 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
InsertValue(ins);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ins.mOperator == IA_FLOAT2INT)
|
else
|
||||||
{
|
{
|
||||||
|
i = 0;
|
||||||
|
while (i < mNum &&
|
||||||
|
(mInstructions[i]->mCode != IC_CONVERSION_OPERATOR ||
|
||||||
|
mInstructions[i]->mOperator != ins.mOperator ||
|
||||||
|
mInstructions[i]->mSTemp[0] != ins.mSTemp[0]))
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < mNum)
|
||||||
|
{
|
||||||
|
ins.mCode = IC_LOAD_TEMPORARY;
|
||||||
|
ins.mSTemp[0] = mInstructions[i]->mTTemp;
|
||||||
|
ins.mSType[0] = mInstructions[i]->mTType;
|
||||||
|
ins.mSTemp[1] = -1;
|
||||||
|
assert(ins.mSTemp[0] >= 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InsertValue(ins);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -992,7 +1017,7 @@ void InterInstruction::SetCode(const Location& loc, InterCode code)
|
||||||
|
|
||||||
static bool TypeInteger(InterType t)
|
static bool TypeInteger(InterType t)
|
||||||
{
|
{
|
||||||
return t == IT_UNSIGNED || t == IT_SIGNED || t == IT_BOOL || t == IT_POINTER;
|
return t == IT_INT8 || t == IT_INT16 || t == IT_INT32 || t == IT_BOOL || t == IT_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool TypeCompatible(InterType t1, InterType t2)
|
static bool TypeCompatible(InterType t1, InterType t2)
|
||||||
|
@ -1002,7 +1027,7 @@ static bool TypeCompatible(InterType t1, InterType t2)
|
||||||
|
|
||||||
static bool TypeArithmetic(InterType t)
|
static bool TypeArithmetic(InterType t)
|
||||||
{
|
{
|
||||||
return t == IT_UNSIGNED || t == IT_SIGNED || t == IT_BOOL || t == IT_FLOAT;
|
return t == IT_INT8 || t == IT_INT16 || t == IT_INT32 || t == IT_BOOL || t == IT_FLOAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static InterType TypeCheckArithmecitResult(InterType t1, InterType t2)
|
static InterType TypeCheckArithmecitResult(InterType t1, InterType t2)
|
||||||
|
@ -1010,7 +1035,7 @@ static InterType TypeCheckArithmecitResult(InterType t1, InterType t2)
|
||||||
if (t1 == IT_FLOAT && t2 == IT_FLOAT)
|
if (t1 == IT_FLOAT && t2 == IT_FLOAT)
|
||||||
return IT_FLOAT;
|
return IT_FLOAT;
|
||||||
else if (TypeInteger(t1) && TypeInteger(t2))
|
else if (TypeInteger(t1) && TypeInteger(t2))
|
||||||
return IT_SIGNED;
|
return t1 > t2 ? t1 : t2;
|
||||||
else
|
else
|
||||||
throw InterCodeTypeMismatchException();
|
throw InterCodeTypeMismatchException();
|
||||||
}
|
}
|
||||||
|
@ -1068,7 +1093,7 @@ void InterInstruction::CollectLocalAddressTemps(GrowingIntArray& localTable, Gro
|
||||||
|
|
||||||
void InterInstruction::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams)
|
void InterInstruction::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams)
|
||||||
{
|
{
|
||||||
if (mCode == IC_STORE)
|
if (mCode == IC_STORE && mSTemp[0] >= 0)
|
||||||
{
|
{
|
||||||
int l = localTable[mSTemp[0]];
|
int l = localTable[mSTemp[0]];
|
||||||
if (l >= 0)
|
if (l >= 0)
|
||||||
|
@ -1578,7 +1603,7 @@ void InterInstruction::Disassemble(FILE* file)
|
||||||
fprintf(file, "RET");
|
fprintf(file, "RET");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
static char typechars[] = "NUSFPB";
|
static char typechars[] = "NBCILFP";
|
||||||
|
|
||||||
fprintf(file, "\t");
|
fprintf(file, "\t");
|
||||||
if (mTTemp >= 0) fprintf(file, "R%d(%c)", mTTemp, typechars[mTType]);
|
if (mTTemp >= 0) fprintf(file, "R%d(%c)", mTTemp, typechars[mTType]);
|
||||||
|
@ -1803,10 +1828,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
|
||||||
case IT_POINTER:
|
case IT_POINTER:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (ins.mSType[0] == IT_UNSIGNED)
|
ins.mSIntConst[0] = tvalue[ins.mSTemp[0]]->mIntValue;
|
||||||
ins.mSIntConst[0] = unsigned short (tvalue[ins.mSTemp[0]]->mIntValue);
|
|
||||||
else
|
|
||||||
ins.mSIntConst[0] = tvalue[ins.mSTemp[0]]->mIntValue;
|
|
||||||
ins.mSTemp[0] = -1;
|
ins.mSTemp[0] = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1823,6 +1845,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
|
||||||
ins.mMemory = tvalue[ins.mSTemp[1]]->mMemory;
|
ins.mMemory = tvalue[ins.mSTemp[1]]->mMemory;
|
||||||
ins.mVarIndex = tvalue[ins.mSTemp[1]]->mVarIndex;
|
ins.mVarIndex = tvalue[ins.mSTemp[1]]->mVarIndex;
|
||||||
ins.mIntValue = tvalue[ins.mSTemp[1]]->mIntValue + tvalue[ins.mSTemp[0]]->mIntValue;
|
ins.mIntValue = tvalue[ins.mSTemp[1]]->mIntValue + tvalue[ins.mSTemp[0]]->mIntValue;
|
||||||
|
ins.mOperandSize = tvalue[ins.mSTemp[1]]->mOperandSize;
|
||||||
ins.mSTemp[0] = -1;
|
ins.mSTemp[0] = -1;
|
||||||
ins.mSTemp[1] = -1;
|
ins.mSTemp[1] = -1;
|
||||||
}
|
}
|
||||||
|
@ -1847,7 +1870,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
|
||||||
ins.mCode = IC_LOAD_TEMPORARY;
|
ins.mCode = IC_LOAD_TEMPORARY;
|
||||||
assert(ins.mSTemp[0] >= 0);
|
assert(ins.mSTemp[0] >= 0);
|
||||||
}
|
}
|
||||||
else if ((ins.mSType[0] == IT_SIGNED || ins.mSType[0] == IT_UNSIGNED) && ins.mTType == IT_POINTER)
|
else if (TypeInteger(ins.mSType[0]) && ins.mTType == IT_POINTER)
|
||||||
{
|
{
|
||||||
if (ins.mSTemp[0] >= 0 && tvalue[ins.mSTemp[0]] && tvalue[ins.mSTemp[0]]->mCode == IC_CONSTANT)
|
if (ins.mSTemp[0] >= 0 && tvalue[ins.mSTemp[0]] && tvalue[ins.mSTemp[0]]->mCode == IC_CONSTANT)
|
||||||
{
|
{
|
||||||
|
@ -1870,10 +1893,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
|
||||||
case IT_POINTER:
|
case IT_POINTER:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (ins.mSType[0] == IT_UNSIGNED)
|
ins.mSIntConst[0] = tvalue[ins.mSTemp[0]]->mIntValue;
|
||||||
ins.mSIntConst[0] = unsigned short(tvalue[ins.mSTemp[0]]->mIntValue);
|
|
||||||
else
|
|
||||||
ins.mSIntConst[0] = tvalue[ins.mSTemp[0]]->mIntValue;
|
|
||||||
ins.mSTemp[0] = -1;
|
ins.mSTemp[0] = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2129,7 +2149,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
|
||||||
{
|
{
|
||||||
ins.mCode = IC_CONSTANT;
|
ins.mCode = IC_CONSTANT;
|
||||||
ins.mIntValue = ConstantRelationalFolding(ins.mOperator, tvalue[ins.mSTemp[1]]->mFloatValue, tvalue[ins.mSTemp[0]]->mFloatValue);
|
ins.mIntValue = ConstantRelationalFolding(ins.mOperator, tvalue[ins.mSTemp[1]]->mFloatValue, tvalue[ins.mSTemp[0]]->mFloatValue);
|
||||||
ins.mTType = IT_SIGNED;
|
ins.mTType = IT_BOOL;
|
||||||
ins.mSTemp[0] = -1;
|
ins.mSTemp[0] = -1;
|
||||||
ins.mSTemp[1] = -1;
|
ins.mSTemp[1] = -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,11 +37,12 @@ enum InterCode
|
||||||
enum InterType
|
enum InterType
|
||||||
{
|
{
|
||||||
IT_NONE,
|
IT_NONE,
|
||||||
IT_UNSIGNED,
|
IT_BOOL,
|
||||||
IT_SIGNED,
|
IT_INT8,
|
||||||
|
IT_INT16,
|
||||||
|
IT_INT32,
|
||||||
IT_FLOAT,
|
IT_FLOAT,
|
||||||
IT_POINTER,
|
IT_POINTER
|
||||||
IT_BOOL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum InterMemory
|
enum InterMemory
|
||||||
|
@ -89,7 +90,14 @@ enum InterOperator
|
||||||
IA_CMPGU,
|
IA_CMPGU,
|
||||||
IA_CMPLU,
|
IA_CMPLU,
|
||||||
IA_FLOAT2INT,
|
IA_FLOAT2INT,
|
||||||
IA_INT2FLOAT
|
IA_INT2FLOAT,
|
||||||
|
|
||||||
|
IA_EXT8TO16U,
|
||||||
|
IA_EXT8TO32U,
|
||||||
|
IA_EXT16TO32U,
|
||||||
|
IA_EXT8TO16S,
|
||||||
|
IA_EXT8TO32S,
|
||||||
|
IA_EXT16TO32S
|
||||||
};
|
};
|
||||||
|
|
||||||
class InterInstruction;
|
class InterInstruction;
|
||||||
|
|
|
@ -20,8 +20,14 @@ static inline InterType InterTypeOf(const Declaration* dec)
|
||||||
case DT_TYPE_VOID:
|
case DT_TYPE_VOID:
|
||||||
return IT_NONE;
|
return IT_NONE;
|
||||||
case DT_TYPE_INTEGER:
|
case DT_TYPE_INTEGER:
|
||||||
|
if (dec->mSize == 1)
|
||||||
|
return IT_INT8;
|
||||||
|
else if (dec->mSize == 2)
|
||||||
|
return IT_INT16;
|
||||||
|
else
|
||||||
|
return IT_INT32;
|
||||||
case DT_TYPE_ENUM:
|
case DT_TYPE_ENUM:
|
||||||
return (dec->mFlags & DTF_SIGNED) ? IT_SIGNED : IT_UNSIGNED;
|
return IT_INT8;
|
||||||
case DT_TYPE_BOOL:
|
case DT_TYPE_BOOL:
|
||||||
return IT_BOOL;
|
return IT_BOOL;
|
||||||
case DT_TYPE_FLOAT:
|
case DT_TYPE_FLOAT:
|
||||||
|
@ -55,31 +61,101 @@ InterCodeGenerator::ExValue InterCodeGenerator::Dereference(InterCodeProcedure*
|
||||||
|
|
||||||
InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* proc, InterCodeBasicBlock*& block, ExValue v, Declaration* type)
|
InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* proc, InterCodeBasicBlock*& block, ExValue v, Declaration* type)
|
||||||
{
|
{
|
||||||
|
int stemp = v.mTemp;
|
||||||
|
|
||||||
if (v.mType->IsIntegerType() && type->mType == DT_TYPE_FLOAT)
|
if (v.mType->IsIntegerType() && type->mType == DT_TYPE_FLOAT)
|
||||||
{
|
{
|
||||||
|
if (v.mType->mSize == 1)
|
||||||
|
{
|
||||||
|
if (v.mType->mFlags & DTF_SIGNED)
|
||||||
|
{
|
||||||
|
InterInstruction xins;
|
||||||
|
xins.mCode = IC_CONVERSION_OPERATOR;
|
||||||
|
xins.mOperator = IA_EXT8TO16S;
|
||||||
|
xins.mSType[0] = IT_INT8;
|
||||||
|
xins.mSTemp[0] = stemp;
|
||||||
|
xins.mTType = IT_INT16;
|
||||||
|
xins.mTTemp = proc->AddTemporary(IT_INT16);
|
||||||
|
block->Append(xins);
|
||||||
|
stemp = xins.mTTemp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InterInstruction xins;
|
||||||
|
xins.mCode = IC_CONVERSION_OPERATOR;
|
||||||
|
xins.mOperator = IA_EXT8TO16U;
|
||||||
|
xins.mSType[0] = IT_INT8;
|
||||||
|
xins.mSTemp[0] = stemp;
|
||||||
|
xins.mTType = IT_INT16;
|
||||||
|
xins.mTTemp = proc->AddTemporary(IT_INT16);
|
||||||
|
block->Append(xins);
|
||||||
|
stemp = xins.mTTemp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
InterInstruction cins;
|
InterInstruction cins;
|
||||||
cins.mCode = IC_CONVERSION_OPERATOR;
|
cins.mCode = IC_CONVERSION_OPERATOR;
|
||||||
cins.mOperator = IA_INT2FLOAT;
|
cins.mOperator = IA_INT2FLOAT;
|
||||||
cins.mSType[0] = InterTypeOf(v.mType);
|
cins.mSType[0] = IT_INT16;
|
||||||
cins.mSTemp[0] = v.mTemp;
|
cins.mSTemp[0] = stemp;
|
||||||
cins.mTType = IT_FLOAT;
|
cins.mTType = IT_FLOAT;
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
cins.mTTemp = proc->AddTemporary(IT_FLOAT);
|
||||||
|
block->Append(cins);
|
||||||
|
|
||||||
v.mTemp = cins.mTTemp;
|
v.mTemp = cins.mTTemp;
|
||||||
v.mType = type;
|
v.mType = type;
|
||||||
block->Append(cins);
|
|
||||||
}
|
}
|
||||||
else if (v.mType->mType == DT_TYPE_FLOAT && type->IsIntegerType())
|
else if (v.mType->mType == DT_TYPE_FLOAT && type->IsIntegerType())
|
||||||
{
|
{
|
||||||
InterInstruction cins;
|
InterInstruction cins;
|
||||||
cins.mCode = IC_CONVERSION_OPERATOR;
|
cins.mCode = IC_CONVERSION_OPERATOR;
|
||||||
cins.mOperator = IA_FLOAT2INT;
|
cins.mOperator = IA_FLOAT2INT;
|
||||||
cins.mSType[0] = InterTypeOf(v.mType);
|
cins.mSType[0] = IT_FLOAT;
|
||||||
cins.mSTemp[0] = v.mTemp;
|
cins.mSTemp[0] = v.mTemp;
|
||||||
cins.mTType = InterTypeOf(type);
|
cins.mTType = IT_INT16;
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
cins.mTTemp = proc->AddTemporary(IT_INT16);
|
||||||
|
block->Append(cins);
|
||||||
v.mTemp = cins.mTTemp;
|
v.mTemp = cins.mTTemp;
|
||||||
v.mType = type;
|
v.mType = type;
|
||||||
block->Append(cins);
|
}
|
||||||
|
else if (v.mType->mSize < type->mSize)
|
||||||
|
{
|
||||||
|
if (v.mType->mSize == 1 && type->mSize == 2)
|
||||||
|
{
|
||||||
|
if (v.mType->mFlags & DTF_SIGNED)
|
||||||
|
{
|
||||||
|
InterInstruction xins;
|
||||||
|
xins.mCode = IC_CONVERSION_OPERATOR;
|
||||||
|
xins.mOperator = IA_EXT8TO16S;
|
||||||
|
xins.mSType[0] = IT_INT8;
|
||||||
|
xins.mSTemp[0] = stemp;
|
||||||
|
xins.mTType = IT_INT16;
|
||||||
|
xins.mTTemp = proc->AddTemporary(IT_INT16);
|
||||||
|
block->Append(xins);
|
||||||
|
stemp = xins.mTTemp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InterInstruction xins;
|
||||||
|
xins.mCode = IC_CONVERSION_OPERATOR;
|
||||||
|
xins.mOperator = IA_EXT8TO16U;
|
||||||
|
xins.mSType[0] = IT_INT8;
|
||||||
|
xins.mSTemp[0] = stemp;
|
||||||
|
xins.mTType = IT_INT16;
|
||||||
|
xins.mTTemp = proc->AddTemporary(IT_INT16);
|
||||||
|
block->Append(xins);
|
||||||
|
stemp = xins.mTTemp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v.mTemp = stemp;
|
||||||
|
v.mType = type;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// ignore size reduction
|
||||||
|
|
||||||
|
v.mType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
@ -87,21 +163,21 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p
|
||||||
|
|
||||||
static inline bool InterTypeTypeInteger(InterType t)
|
static inline bool InterTypeTypeInteger(InterType t)
|
||||||
{
|
{
|
||||||
return t == IT_UNSIGNED || t == IT_SIGNED || t == IT_BOOL;
|
return t == IT_INT8 || t == IT_INT16 || t == IT_INT32 || t == IT_BOOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline InterType InterTypeOfArithmetic(InterType t1, InterType t2)
|
static inline InterType InterTypeOfArithmetic(InterType t1, InterType t2)
|
||||||
{
|
{
|
||||||
if (t1 == IT_FLOAT || t2 == IT_FLOAT)
|
if (t1 == IT_FLOAT || t2 == IT_FLOAT)
|
||||||
return IT_FLOAT;
|
return IT_FLOAT;
|
||||||
else if (t1 == IT_SIGNED && t2 == IT_SIGNED)
|
else if (InterTypeTypeInteger(t1) && InterTypeTypeInteger(t2))
|
||||||
return IT_SIGNED;
|
return t1 > t2 ? t1 : t2;
|
||||||
else if (t1 == IT_POINTER && t2 == IT_POINTER)
|
else if (t1 == IT_POINTER && t2 == IT_POINTER)
|
||||||
return IT_SIGNED;
|
return IT_INT16;
|
||||||
else if (t1 == IT_POINTER || t2 == IT_POINTER)
|
else if (t1 == IT_POINTER || t2 == IT_POINTER)
|
||||||
return IT_POINTER;
|
return IT_POINTER;
|
||||||
else
|
else
|
||||||
return IT_UNSIGNED;
|
return IT_INT16;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration* dec)
|
void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration* dec)
|
||||||
|
@ -360,17 +436,37 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
ins.mCode = IC_CONSTANT;
|
ins.mCode = IC_CONSTANT;
|
||||||
ins.mTType = InterTypeOf(dec->mBase);
|
ins.mTType = InterTypeOf(dec->mBase);
|
||||||
ins.mTTemp = proc->AddTemporary(ins.mTType);
|
ins.mTTemp = proc->AddTemporary(ins.mTType);
|
||||||
if (ins.mTType == IT_SIGNED)
|
if (ins.mTType == IT_INT8)
|
||||||
{
|
{
|
||||||
if (dec->mInteger < -32768 || dec->mInteger > 32767)
|
if (dec->mFlags & DTF_SIGNED)
|
||||||
mErrors->Warning(dec->mLocation, "Integer constant truncated");
|
{
|
||||||
|
if (dec->mInteger < -128 || dec->mInteger > 127)
|
||||||
|
mErrors->Warning(dec->mLocation, "Integer constant truncated");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dec->mInteger < 0 || dec->mInteger > 255)
|
||||||
|
mErrors->Warning(dec->mLocation, "Unsigned integer constant truncated");
|
||||||
|
}
|
||||||
|
ins.mIntValue = char(dec->mInteger);
|
||||||
|
}
|
||||||
|
else if (ins.mTType == IT_INT8)
|
||||||
|
{
|
||||||
|
if (dec->mFlags & DTF_SIGNED)
|
||||||
|
{
|
||||||
|
if (dec->mInteger < -32768 || dec->mInteger > 32767)
|
||||||
|
mErrors->Warning(dec->mLocation, "Integer constant truncated");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dec->mInteger < 0 || dec->mInteger > 65535)
|
||||||
|
mErrors->Warning(dec->mLocation, "Unsigned integer constant truncated");
|
||||||
|
}
|
||||||
ins.mIntValue = short(dec->mInteger);
|
ins.mIntValue = short(dec->mInteger);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (dec->mInteger < 0 || dec->mInteger > 65535)
|
ins.mIntValue = dec->mInteger;
|
||||||
mErrors->Warning(dec->mLocation, "Unsigned integer constant truncated");
|
|
||||||
ins.mIntValue = unsigned short(dec->mInteger);
|
|
||||||
}
|
}
|
||||||
block->Append(ins);
|
block->Append(ins);
|
||||||
return ExValue(dec->mBase, ins.mTTemp);
|
return ExValue(dec->mBase, ins.mTTemp);
|
||||||
|
@ -533,8 +629,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock);
|
vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock);
|
||||||
vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock);
|
vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock);
|
||||||
|
|
||||||
if (!vl.mType->CanAssign(vr.mType))
|
if (exp->mToken == TK_ASSIGN || !(vl.mType->mType == IT_POINTER && vr.mType->IsIntegerType() && (exp->mToken == TK_ASSIGN_ADD || exp->mToken == TK_ASSIGN_SUB)))
|
||||||
mErrors->Error(exp->mLocation, "Cannot assign incompatible types");
|
{
|
||||||
|
if (!vl.mType->CanAssign(vr.mType))
|
||||||
|
mErrors->Error(exp->mLocation, "Cannot assign incompatible types");
|
||||||
|
}
|
||||||
|
|
||||||
if (vl.mType->mFlags & DTF_CONST)
|
if (vl.mType->mFlags & DTF_CONST)
|
||||||
mErrors->Error(exp->mLocation, "Cannot assign to const type");
|
mErrors->Error(exp->mLocation, "Cannot assign to const type");
|
||||||
|
@ -597,31 +696,34 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
if (!vr.mType->IsIntegerType())
|
if (!vr.mType->IsIntegerType())
|
||||||
mErrors->Error(exp->mLocation, "Invalid argument for pointer inc/dec");
|
mErrors->Error(exp->mLocation, "Invalid argument for pointer inc/dec");
|
||||||
|
|
||||||
cins.mTType = IT_SIGNED;
|
cins.mTType = IT_INT16;
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||||
block->Append(cins);
|
block->Append(cins);
|
||||||
|
|
||||||
InterInstruction mins;
|
InterInstruction mins;
|
||||||
mins.mCode = IC_BINARY_OPERATOR;
|
mins.mCode = IC_BINARY_OPERATOR;
|
||||||
mins.mOperator = IA_MUL;
|
mins.mOperator = IA_MUL;
|
||||||
mins.mSType[0] = IT_SIGNED;
|
mins.mSType[0] = IT_INT16;
|
||||||
mins.mSTemp[0] = vr.mTemp;
|
mins.mSTemp[0] = vr.mTemp;
|
||||||
mins.mSType[1] = IT_SIGNED;
|
mins.mSType[1] = IT_INT16;
|
||||||
mins.mSTemp[1] = cins.mTTemp;
|
mins.mSTemp[1] = cins.mTTemp;
|
||||||
mins.mTType = IT_SIGNED;
|
mins.mTType = IT_INT16;
|
||||||
mins.mTTemp = proc->AddTemporary(mins.mTType);
|
mins.mTTemp = proc->AddTemporary(mins.mTType);
|
||||||
block->Append(mins);
|
block->Append(mins);
|
||||||
|
|
||||||
InterInstruction ains;
|
InterInstruction ains;
|
||||||
ains.mCode = IC_LEA;
|
ains.mCode = IC_LEA;
|
||||||
ains.mMemory = IM_INDIRECT;
|
ains.mMemory = IM_INDIRECT;
|
||||||
ains.mSType[0] = IT_SIGNED;
|
ains.mSType[0] = IT_INT16;
|
||||||
ains.mSTemp[0] = mins.mTTemp;
|
ains.mSTemp[0] = mins.mTTemp;
|
||||||
ains.mSType[1] = IT_POINTER;
|
ains.mSType[1] = IT_POINTER;
|
||||||
ains.mSTemp[1] = vl.mTemp;
|
ains.mSTemp[1] = vll.mTemp;
|
||||||
ains.mTType = IT_POINTER;
|
ains.mTType = IT_POINTER;
|
||||||
ains.mTTemp = proc->AddTemporary(ains.mTType);
|
ains.mTTemp = proc->AddTemporary(ains.mTType);
|
||||||
block->Append(ains);
|
block->Append(ains);
|
||||||
|
|
||||||
|
vr.mTemp = ains.mTTemp;
|
||||||
|
vr.mType = vll.mType;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -692,32 +794,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (vl.mType->IsIntegerType() && vr.mType->mType == DT_TYPE_FLOAT)
|
vr = CoerceType(proc, block, vr, vl.mType);
|
||||||
{
|
|
||||||
InterInstruction cins;
|
|
||||||
cins.mCode = IC_CONVERSION_OPERATOR;
|
|
||||||
cins.mOperator = IA_FLOAT2INT;
|
|
||||||
cins.mSType[0] = InterTypeOf(vr.mType);
|
|
||||||
cins.mSTemp[0] = vr.mTemp;
|
|
||||||
cins.mTType = InterTypeOf(vl.mType);
|
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
|
||||||
vr.mTemp = cins.mTTemp;
|
|
||||||
vr.mType = TheSignedIntTypeDeclaration;
|
|
||||||
block->Append(cins);
|
|
||||||
}
|
|
||||||
else if (vl.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(vl.mType);;
|
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
|
||||||
vr.mTemp = cins.mTTemp;
|
|
||||||
vr.mType = TheFloatTypeDeclaration;
|
|
||||||
block->Append(cins);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ins.mCode = IC_STORE;
|
ins.mCode = IC_STORE;
|
||||||
|
@ -750,25 +827,25 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
InterInstruction cins;
|
InterInstruction cins;
|
||||||
cins.mCode = IC_CONSTANT;
|
cins.mCode = IC_CONSTANT;
|
||||||
cins.mIntValue = vl.mType->mBase->mSize;
|
cins.mIntValue = vl.mType->mBase->mSize;
|
||||||
cins.mTType = IT_SIGNED;
|
cins.mTType = IT_INT16;
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||||
block->Append(cins);
|
block->Append(cins);
|
||||||
|
|
||||||
InterInstruction mins;
|
InterInstruction mins;
|
||||||
mins.mCode = IC_BINARY_OPERATOR;
|
mins.mCode = IC_BINARY_OPERATOR;
|
||||||
mins.mOperator = IA_MUL;
|
mins.mOperator = IA_MUL;
|
||||||
mins.mSType[0] = IT_SIGNED;
|
mins.mSType[0] = IT_INT16;
|
||||||
mins.mSTemp[0] = vr.mTemp;
|
mins.mSTemp[0] = vr.mTemp;
|
||||||
mins.mSType[1] = IT_SIGNED;
|
mins.mSType[1] = IT_INT16;
|
||||||
mins.mSTemp[1] = cins.mTTemp;
|
mins.mSTemp[1] = cins.mTTemp;
|
||||||
mins.mTType = IT_SIGNED;
|
mins.mTType = IT_INT16;
|
||||||
mins.mTTemp = proc->AddTemporary(mins.mTType);
|
mins.mTTemp = proc->AddTemporary(mins.mTType);
|
||||||
block->Append(mins);
|
block->Append(mins);
|
||||||
|
|
||||||
InterInstruction ains;
|
InterInstruction ains;
|
||||||
ains.mCode = IC_LEA;
|
ains.mCode = IC_LEA;
|
||||||
ains.mMemory = IM_INDIRECT;
|
ains.mMemory = IM_INDIRECT;
|
||||||
ains.mSType[0] = IT_SIGNED;
|
ains.mSType[0] = IT_INT16;
|
||||||
ains.mSTemp[0] = mins.mTTemp;
|
ains.mSTemp[0] = mins.mTTemp;
|
||||||
ains.mSType[1] = IT_POINTER;
|
ains.mSType[1] = IT_POINTER;
|
||||||
ains.mSTemp[1] = vl.mTemp;
|
ains.mSTemp[1] = vl.mTemp;
|
||||||
|
@ -790,14 +867,14 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
InterInstruction cins;
|
InterInstruction cins;
|
||||||
cins.mCode = IC_CONSTANT;
|
cins.mCode = IC_CONSTANT;
|
||||||
cins.mIntValue = exp->mDecValue->mOffset;
|
cins.mIntValue = exp->mDecValue->mOffset;
|
||||||
cins.mTType = IT_SIGNED;
|
cins.mTType = IT_INT16;
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||||
block->Append(cins);
|
block->Append(cins);
|
||||||
|
|
||||||
InterInstruction ains;
|
InterInstruction ains;
|
||||||
ains.mCode = IC_LEA;
|
ains.mCode = IC_LEA;
|
||||||
ains.mMemory = IM_INDIRECT;
|
ains.mMemory = IM_INDIRECT;
|
||||||
ains.mSType[0] = IT_SIGNED;
|
ains.mSType[0] = IT_INT16;
|
||||||
ains.mSTemp[0] = cins.mTTemp;
|
ains.mSTemp[0] = cins.mTTemp;
|
||||||
ains.mSType[1] = IT_POINTER;
|
ains.mSType[1] = IT_POINTER;
|
||||||
ains.mSTemp[1] = vl.mTemp;
|
ains.mSTemp[1] = vl.mTemp;
|
||||||
|
@ -846,24 +923,24 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
else
|
else
|
||||||
mErrors->Error(exp->mLocation, "Invalid pointer operation");
|
mErrors->Error(exp->mLocation, "Invalid pointer operation");
|
||||||
|
|
||||||
cins.mTType = IT_SIGNED;
|
cins.mTType = IT_INT16;
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||||
block->Append(cins);
|
block->Append(cins);
|
||||||
|
|
||||||
InterInstruction mins;
|
InterInstruction mins;
|
||||||
mins.mCode = IC_BINARY_OPERATOR;
|
mins.mCode = IC_BINARY_OPERATOR;
|
||||||
mins.mOperator = IA_MUL;
|
mins.mOperator = IA_MUL;
|
||||||
mins.mSType[0] = IT_SIGNED;
|
mins.mSType[0] = IT_INT16;
|
||||||
mins.mSTemp[0] = vr.mTemp;
|
mins.mSTemp[0] = vr.mTemp;
|
||||||
mins.mSType[1] = IT_SIGNED;
|
mins.mSType[1] = IT_INT16;
|
||||||
mins.mSTemp[1] = cins.mTTemp;
|
mins.mSTemp[1] = cins.mTTemp;
|
||||||
mins.mTType = IT_SIGNED;
|
mins.mTType = IT_INT16;
|
||||||
mins.mTTemp = proc->AddTemporary(mins.mTType);
|
mins.mTTemp = proc->AddTemporary(mins.mTType);
|
||||||
block->Append(mins);
|
block->Append(mins);
|
||||||
|
|
||||||
ins.mCode = IC_LEA;
|
ins.mCode = IC_LEA;
|
||||||
ins.mMemory = IM_INDIRECT;
|
ins.mMemory = IM_INDIRECT;
|
||||||
ins.mSType[0] = IT_SIGNED;
|
ins.mSType[0] = IT_INT16;
|
||||||
ins.mSTemp[0] = mins.mTTemp;
|
ins.mSTemp[0] = mins.mTTemp;
|
||||||
ins.mSType[1] = IT_POINTER;
|
ins.mSType[1] = IT_POINTER;
|
||||||
ins.mSTemp[1] = vl.mTemp;
|
ins.mSTemp[1] = vl.mTemp;
|
||||||
|
@ -879,42 +956,42 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
clins.mCode = IC_TYPECAST;
|
clins.mCode = IC_TYPECAST;
|
||||||
clins.mSTemp[0] = vl.mTemp;
|
clins.mSTemp[0] = vl.mTemp;
|
||||||
clins.mSType[0] = IT_POINTER;
|
clins.mSType[0] = IT_POINTER;
|
||||||
clins.mTType = IT_SIGNED;
|
clins.mTType = IT_INT16;
|
||||||
clins.mTTemp = proc->AddTemporary(clins.mTType);
|
clins.mTTemp = proc->AddTemporary(clins.mTType);
|
||||||
block->Append(clins);
|
block->Append(clins);
|
||||||
|
|
||||||
crins.mCode = IC_TYPECAST;
|
crins.mCode = IC_TYPECAST;
|
||||||
crins.mSTemp[0] = vr.mTemp;
|
crins.mSTemp[0] = vr.mTemp;
|
||||||
crins.mSType[0] = IT_POINTER;
|
crins.mSType[0] = IT_POINTER;
|
||||||
crins.mTType = IT_SIGNED;
|
crins.mTType = IT_INT16;
|
||||||
crins.mTTemp = proc->AddTemporary(crins.mTType);
|
crins.mTTemp = proc->AddTemporary(crins.mTType);
|
||||||
block->Append(crins);
|
block->Append(crins);
|
||||||
|
|
||||||
InterInstruction cins;
|
InterInstruction cins;
|
||||||
cins.mCode = IC_CONSTANT;
|
cins.mCode = IC_CONSTANT;
|
||||||
cins.mIntValue = vl.mType->mBase->mSize;
|
cins.mIntValue = vl.mType->mBase->mSize;
|
||||||
cins.mTType = IT_SIGNED;
|
cins.mTType = IT_INT16;
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||||
block->Append(cins);
|
block->Append(cins);
|
||||||
|
|
||||||
InterInstruction sins, dins;
|
InterInstruction sins, dins;
|
||||||
sins.mCode = IC_BINARY_OPERATOR;
|
sins.mCode = IC_BINARY_OPERATOR;
|
||||||
sins.mOperator = IA_SUB;
|
sins.mOperator = IA_SUB;
|
||||||
sins.mSType[0] = IT_SIGNED;
|
sins.mSType[0] = IT_INT16;
|
||||||
sins.mSTemp[0] = crins.mTTemp;
|
sins.mSTemp[0] = crins.mTTemp;
|
||||||
sins.mSType[1] = IT_SIGNED;
|
sins.mSType[1] = IT_INT16;
|
||||||
sins.mSTemp[1] = clins.mTTemp;
|
sins.mSTemp[1] = clins.mTTemp;
|
||||||
sins.mTType = IT_SIGNED;
|
sins.mTType = IT_INT16;
|
||||||
sins.mTTemp = proc->AddTemporary(sins.mTType);
|
sins.mTTemp = proc->AddTemporary(sins.mTType);
|
||||||
block->Append(sins);
|
block->Append(sins);
|
||||||
|
|
||||||
dins.mCode = IC_BINARY_OPERATOR;
|
dins.mCode = IC_BINARY_OPERATOR;
|
||||||
dins.mOperator = IA_DIVS;
|
dins.mOperator = IA_DIVS;
|
||||||
dins.mSType[0] = IT_SIGNED;
|
dins.mSType[0] = IT_INT16;
|
||||||
dins.mSTemp[0] = cins.mTTemp;
|
dins.mSTemp[0] = cins.mTTemp;
|
||||||
dins.mSType[1] = IT_SIGNED;
|
dins.mSType[1] = IT_INT16;
|
||||||
dins.mSTemp[1] = sins.mTTemp;
|
dins.mSTemp[1] = sins.mTTemp;
|
||||||
dins.mTType = IT_SIGNED;
|
dins.mTType = IT_INT16;
|
||||||
dins.mTTemp = proc->AddTemporary(dins.mTType);
|
dins.mTTemp = proc->AddTemporary(dins.mTType);
|
||||||
block->Append(dins);
|
block->Append(dins);
|
||||||
|
|
||||||
|
@ -933,34 +1010,22 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
if (!vr.mType->IsNumericType())
|
if (!vr.mType->IsNumericType())
|
||||||
mErrors->Error(exp->mLocation, "Right hand operand type is not numeric");
|
mErrors->Error(exp->mLocation, "Right hand operand type is not numeric");
|
||||||
|
|
||||||
if (vl.mType->IsIntegerType() && vr.mType->mType == DT_TYPE_FLOAT)
|
Declaration* dtype;
|
||||||
{
|
if (vr.mType->mType == DT_TYPE_FLOAT || vl.mType->mType == DT_TYPE_FLOAT)
|
||||||
InterInstruction cins;
|
dtype = TheFloatTypeDeclaration;
|
||||||
cins.mCode = IC_CONVERSION_OPERATOR;
|
else if (vr.mType->mSize < vl.mType->mSize && (vl.mType->mFlags & DTF_SIGNED))
|
||||||
cins.mOperator = IA_INT2FLOAT;
|
dtype = TheSignedIntTypeDeclaration;
|
||||||
cins.mSType[0] = InterTypeOf(vl.mType);
|
else if (vl.mType->mSize < vr.mType->mSize && (vr.mType->mFlags & DTF_SIGNED))
|
||||||
cins.mSTemp[0] = vl.mTemp;
|
dtype = TheSignedIntTypeDeclaration;
|
||||||
cins.mTType = IT_FLOAT;
|
else if ((vr.mType->mFlags & DTF_SIGNED) && (vl.mType->mFlags & DTF_SIGNED))
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
dtype = TheSignedIntTypeDeclaration;
|
||||||
vl.mTemp = cins.mTTemp;
|
else
|
||||||
vl.mType = TheFloatTypeDeclaration;
|
dtype = TheUnsignedIntTypeDeclaration;
|
||||||
block->Append(cins);
|
|
||||||
}
|
|
||||||
else if (vl.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 = IT_FLOAT;
|
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
|
||||||
vr.mTemp = cins.mTTemp;
|
|
||||||
vr.mType = TheFloatTypeDeclaration;
|
|
||||||
block->Append(cins);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool signedOP = (vl.mType->mFlags & DTF_SIGNED) && (vr.mType->mFlags & DTF_SIGNED);
|
vl = CoerceType(proc, block, vl, dtype);
|
||||||
|
vr = CoerceType(proc, block, vr, dtype);
|
||||||
|
|
||||||
|
bool signedOP = dtype->mFlags & DTF_SIGNED;
|
||||||
|
|
||||||
ins.mCode = IC_BINARY_OPERATOR;
|
ins.mCode = IC_BINARY_OPERATOR;
|
||||||
switch (exp->mToken)
|
switch (exp->mToken)
|
||||||
|
@ -1028,7 +1093,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
bool ftype = vl.mType->mType == DT_TYPE_FLOAT;
|
bool ftype = vl.mType->mType == DT_TYPE_FLOAT;
|
||||||
|
|
||||||
cins.mCode = IC_CONSTANT;
|
cins.mCode = IC_CONSTANT;
|
||||||
cins.mTType = ftype ? IT_FLOAT : IT_SIGNED;
|
cins.mTType = ftype ? IT_FLOAT : IT_INT16;
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||||
if (vdl.mType->mType == DT_TYPE_POINTER)
|
if (vdl.mType->mType == DT_TYPE_POINTER)
|
||||||
cins.mIntValue = exp->mToken == TK_INC ? vdl.mType->mBase->mSize : -(vdl.mType->mBase->mSize);
|
cins.mIntValue = exp->mToken == TK_INC ? vdl.mType->mBase->mSize : -(vdl.mType->mBase->mSize);
|
||||||
|
@ -1080,7 +1145,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
bool ftype = vl.mType->mType == DT_TYPE_FLOAT;
|
bool ftype = vl.mType->mType == DT_TYPE_FLOAT;
|
||||||
|
|
||||||
cins.mCode = IC_CONSTANT;
|
cins.mCode = IC_CONSTANT;
|
||||||
cins.mTType = ftype ? IT_FLOAT : IT_SIGNED;
|
cins.mTType = ftype ? IT_FLOAT : IT_INT16;
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||||
if (vdl.mType->mType == DT_TYPE_POINTER)
|
if (vdl.mType->mType == DT_TYPE_POINTER)
|
||||||
cins.mIntValue = exp->mToken == TK_INC ? vdl.mType->mBase->mSize : -(vdl.mType->mBase->mSize);
|
cins.mIntValue = exp->mToken == TK_INC ? vdl.mType->mBase->mSize : -(vdl.mType->mBase->mSize);
|
||||||
|
@ -1175,37 +1240,31 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
InterInstruction ins;
|
InterInstruction ins;
|
||||||
|
|
||||||
bool signedCompare = (vl.mType->mFlags & DTF_SIGNED) && (vr.mType->mFlags & DTF_SIGNED);
|
Declaration* dtype = TheSignedIntTypeDeclaration;
|
||||||
|
|
||||||
if (!(vl.mType->mType == DT_TYPE_POINTER || vl.mType->IsNumericType()))
|
if (vl.mType->mType == DT_TYPE_POINTER || vr.mType->mType == DT_TYPE_POINTER)
|
||||||
|
{
|
||||||
|
dtype = vl.mType;
|
||||||
|
if (!vl.mType->IsSame(vr.mType))
|
||||||
|
mErrors->Error(exp->mLocation, "Incompatible pointer types");
|
||||||
|
}
|
||||||
|
else if (!vl.mType->IsNumericType() || !vr.mType->IsNumericType())
|
||||||
mErrors->Error(exp->mLocation, "Not a numeric or pointer type");
|
mErrors->Error(exp->mLocation, "Not a numeric or pointer type");
|
||||||
|
else if (vr.mType->mType == DT_TYPE_FLOAT || vl.mType->mType == DT_TYPE_FLOAT)
|
||||||
|
dtype = TheFloatTypeDeclaration;
|
||||||
|
else if (vr.mType->mSize < vl.mType->mSize && (vl.mType->mFlags & DTF_SIGNED))
|
||||||
|
dtype = TheSignedIntTypeDeclaration;
|
||||||
|
else if (vl.mType->mSize < vr.mType->mSize && (vr.mType->mFlags & DTF_SIGNED))
|
||||||
|
dtype = TheSignedIntTypeDeclaration;
|
||||||
|
else if ((vr.mType->mFlags & DTF_SIGNED) && (vl.mType->mFlags & DTF_SIGNED))
|
||||||
|
dtype = TheSignedIntTypeDeclaration;
|
||||||
|
else
|
||||||
|
dtype = TheUnsignedIntTypeDeclaration;
|
||||||
|
|
||||||
if (vl.mType->IsIntegerType() && vr.mType->mType == DT_TYPE_FLOAT)
|
vl = CoerceType(proc, block, vl, dtype);
|
||||||
{
|
vr = CoerceType(proc, block, vr, dtype);
|
||||||
InterInstruction cins;
|
|
||||||
cins.mCode = IC_CONVERSION_OPERATOR;
|
bool signedCompare = dtype->mFlags & DTF_SIGNED;
|
||||||
cins.mOperator = IA_INT2FLOAT;
|
|
||||||
cins.mSType[0] = InterTypeOf(vl.mType);
|
|
||||||
cins.mSTemp[0] = vl.mTemp;
|
|
||||||
cins.mTType = IT_FLOAT;
|
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
|
||||||
vl.mTemp = cins.mTTemp;
|
|
||||||
vl.mType = TheFloatTypeDeclaration;
|
|
||||||
block->Append(cins);
|
|
||||||
}
|
|
||||||
else if (vl.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 = IT_FLOAT;
|
|
||||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
|
||||||
vr.mTemp = cins.mTTemp;
|
|
||||||
vr.mType = TheFloatTypeDeclaration;
|
|
||||||
block->Append(cins);
|
|
||||||
}
|
|
||||||
|
|
||||||
ins.mCode = IC_RELATIONAL_OPERATOR;
|
ins.mCode = IC_RELATIONAL_OPERATOR;
|
||||||
switch (exp->mToken)
|
switch (exp->mToken)
|
||||||
|
@ -1737,74 +1796,57 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
vr = Dereference(proc, fblock, vr);
|
vr = Dereference(proc, fblock, vr);
|
||||||
|
|
||||||
int ttemp;
|
int ttemp;
|
||||||
InterType ttype;
|
InterType ttype, stypel, styper;
|
||||||
|
|
||||||
|
stypel = InterTypeOf(vl.mType);
|
||||||
|
styper = InterTypeOf(vr.mType);
|
||||||
|
|
||||||
Declaration* dtype;
|
Declaration* dtype;
|
||||||
if (vl.mType->mType == DT_TYPE_FLOAT || vr.mType->mType == DT_TYPE_FLOAT)
|
if (stypel == IT_POINTER || styper == IT_POINTER)
|
||||||
{
|
|
||||||
ttype = IT_FLOAT;
|
|
||||||
dtype = TheFloatTypeDeclaration;
|
|
||||||
}
|
|
||||||
else if (vl.mType->IsIntegerType() && vr.mType->IsIntegerType())
|
|
||||||
{
|
|
||||||
ttype = ((vl.mType->mFlags & DTF_SIGNED) && (vr.mType->mFlags & DTF_SIGNED)) ? IT_SIGNED : IT_UNSIGNED;
|
|
||||||
dtype = vl.mType;
|
|
||||||
}
|
|
||||||
else if (vl.mType->mType == DT_TYPE_POINTER && vl.mType->IsSame(vr.mType))
|
|
||||||
{
|
{
|
||||||
|
if (!vl.mType->IsSame(vr.mType))
|
||||||
|
mErrors->Error(exp->mLocation, "Incompatible conditional types");
|
||||||
|
|
||||||
ttype = IT_POINTER;
|
ttype = IT_POINTER;
|
||||||
dtype = vl.mType;
|
dtype = vl.mType;
|
||||||
}
|
}
|
||||||
|
else if (stypel == styper)
|
||||||
|
{
|
||||||
|
ttype = stypel;
|
||||||
|
dtype = vl.mType;
|
||||||
|
}
|
||||||
|
else if (stypel > styper)
|
||||||
|
{
|
||||||
|
ttype = stypel;
|
||||||
|
dtype = vl.mType;
|
||||||
|
|
||||||
|
vr = CoerceType(proc, fblock, vr, dtype);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mErrors->Error(exp->mLocation, "Incompatible conditional types");
|
ttype = styper;
|
||||||
ttype = IT_SIGNED;
|
dtype = vr.mType;
|
||||||
dtype = TheVoidTypeDeclaration;
|
|
||||||
|
vl = CoerceType(proc, tblock, vl, dtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
ttemp = proc->AddTemporary(ttype);
|
ttemp = proc->AddTemporary(ttype);
|
||||||
|
|
||||||
if (ttype == IT_FLOAT && vr.mType->IsIntegerType())
|
InterInstruction rins;
|
||||||
{
|
rins.mCode = IC_LOAD_TEMPORARY;
|
||||||
InterInstruction ins;
|
rins.mSType[0] = InterTypeOf(vr.mType);
|
||||||
ins.mCode = IC_CONVERSION_OPERATOR;
|
rins.mSTemp[0] = vr.mTemp;
|
||||||
ins.mOperator = IA_INT2FLOAT;
|
rins.mTType = ttype;
|
||||||
ins.mSType[0] = InterTypeOf(vr.mType);
|
rins.mTTemp = ttemp;
|
||||||
ins.mSTemp[0] = vr.mTemp;
|
fblock->Append(rins);
|
||||||
ins.mTType = ttype;
|
|
||||||
ins.mTTemp = ttemp;
|
|
||||||
fblock->Append(ins);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
InterInstruction ins;
|
|
||||||
ins.mCode = IC_LOAD_TEMPORARY;
|
|
||||||
ins.mSType[0] = InterTypeOf(vr.mType);
|
|
||||||
ins.mSTemp[0] = vr.mTemp;
|
|
||||||
ins.mTType = ttype;
|
|
||||||
ins.mTTemp = ttemp;
|
|
||||||
fblock->Append(ins);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ttype == IT_FLOAT && vl.mType->IsIntegerType())
|
InterInstruction lins;
|
||||||
{
|
lins.mCode = IC_LOAD_TEMPORARY;
|
||||||
InterInstruction ins;
|
lins.mSType[0] = InterTypeOf(vl.mType);
|
||||||
ins.mCode = IC_CONVERSION_OPERATOR;
|
lins.mSTemp[0] = vl.mTemp;
|
||||||
ins.mOperator = IA_INT2FLOAT;
|
lins.mTType = ttype;
|
||||||
ins.mSType[0] = InterTypeOf(vl.mType);
|
lins.mTTemp = ttemp;
|
||||||
ins.mSTemp[0] = vl.mTemp;
|
tblock->Append(lins);
|
||||||
ins.mTType = ttype;
|
|
||||||
ins.mTTemp = ttemp;
|
|
||||||
tblock->Append(ins);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
InterInstruction ins;
|
|
||||||
ins.mCode = IC_LOAD_TEMPORARY;
|
|
||||||
ins.mSType[0] = InterTypeOf(vl.mType);
|
|
||||||
ins.mSTemp[0] = vl.mTemp;
|
|
||||||
ins.mTType = ttype;
|
|
||||||
ins.mTTemp = ttemp;
|
|
||||||
tblock->Append(ins);
|
|
||||||
}
|
|
||||||
|
|
||||||
tblock->Append(jins);
|
tblock->Append(jins);
|
||||||
tblock->Close(eblock, nullptr);
|
tblock->Close(eblock, nullptr);
|
||||||
|
|
|
@ -331,6 +331,8 @@ bool NativeCodeInstruction::IsUsedResultInstructions(NumberSet& requiredTemps)
|
||||||
case ASMIT_CPY:
|
case ASMIT_CPY:
|
||||||
case ASMIT_ASL:
|
case ASMIT_ASL:
|
||||||
case ASMIT_LSR:
|
case ASMIT_LSR:
|
||||||
|
case ASMIT_INC:
|
||||||
|
case ASMIT_DEC:
|
||||||
case ASMIT_ORA:
|
case ASMIT_ORA:
|
||||||
case ASMIT_EOR:
|
case ASMIT_EOR:
|
||||||
case ASMIT_AND:
|
case ASMIT_AND:
|
||||||
|
@ -497,12 +499,19 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
||||||
case ASMIT_LSR:
|
case ASMIT_LSR:
|
||||||
if (mMode == ASMIM_IMPLIED)
|
if (mMode == ASMIM_IMPLIED)
|
||||||
data.mRegs[CPU_REG_A].Reset();
|
data.mRegs[CPU_REG_A].Reset();
|
||||||
|
data.mRegs[CPU_REG_C].Reset();
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ASMIT_INC:
|
||||||
|
case ASMIT_DEC:
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ASMIT_LDA:
|
case ASMIT_LDA:
|
||||||
if (mMode == ASMIM_IMMEDIATE)
|
if (mMode == ASMIM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
if (data.mRegs[CPU_REG_A].mImmediate && data.mRegs[CPU_REG_A].mValue == mAddress)
|
if (data.mRegs[CPU_REG_A].mImmediate && data.mRegs[CPU_REG_A].mValue == mAddress && !(mLive & LIVE_CPU_REG_Z))
|
||||||
{
|
{
|
||||||
mType = ASMIT_NOP;
|
mType = ASMIT_NOP;
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -513,22 +522,93 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
||||||
data.mRegs[CPU_REG_A].mZeroPage = false;
|
data.mRegs[CPU_REG_A].mZeroPage = false;
|
||||||
data.mRegs[CPU_REG_A].mValue = mAddress;
|
data.mRegs[CPU_REG_A].mValue = mAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = mAddress;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (mMode != ASMIM_ZERO_PAGE)
|
||||||
|
data.mRegs[CPU_REG_A].Reset();
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
}
|
}
|
||||||
else if (mMode != ASMIM_ZERO_PAGE)
|
|
||||||
data.mRegs[CPU_REG_A].Reset();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ASMIT_ADC:
|
case ASMIT_ADC:
|
||||||
case ASMIT_SBC:
|
case ASMIT_SBC:
|
||||||
|
data.mRegs[CPU_REG_A].Reset();
|
||||||
|
data.mRegs[CPU_REG_C].Reset();
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
|
break;
|
||||||
|
case ASMIT_CMP:
|
||||||
|
if (mMode == ASMIM_IMMEDIATE && data.mRegs[CPU_REG_A].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mImmediate - mAddress;
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_C].mValue = data.mRegs[CPU_REG_A].mImmediate >= mAddress;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_C].Reset();
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ASMIT_CPX:
|
||||||
|
if (mMode == ASMIM_IMMEDIATE && data.mRegs[CPU_REG_X].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_X].mImmediate - mAddress;
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_C].mValue = data.mRegs[CPU_REG_X].mImmediate >= mAddress;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_C].Reset();
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ASMIT_CPY:
|
||||||
|
if (mMode == ASMIM_IMMEDIATE && data.mRegs[CPU_REG_Y].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_Y].mImmediate - mAddress;
|
||||||
|
data.mRegs[CPU_REG_C].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_C].mValue = data.mRegs[CPU_REG_Y].mImmediate >= mAddress;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_C].Reset();
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case ASMIT_ORA:
|
case ASMIT_ORA:
|
||||||
case ASMIT_EOR:
|
case ASMIT_EOR:
|
||||||
case ASMIT_AND:
|
case ASMIT_AND:
|
||||||
data.mRegs[CPU_REG_A].Reset();
|
if (mMode == ASMIM_IMMEDIATE && data.mRegs[CPU_REG_A].mImmediate)
|
||||||
|
{
|
||||||
|
if (mType == ASMIT_ORA)
|
||||||
|
mAddress |= data.mRegs[CPU_REG_A].mValue;
|
||||||
|
else if (mType == ASMIT_AND)
|
||||||
|
mAddress &= data.mRegs[CPU_REG_A].mValue;
|
||||||
|
else if (mType == ASMIT_EOR)
|
||||||
|
mAddress ^= data.mRegs[CPU_REG_A].mValue;
|
||||||
|
mType = ASMIT_LDA;
|
||||||
|
data.mRegs[CPU_REG_A].mValue = mAddress;
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = mAddress;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_A].Reset();
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ASMIT_LDX:
|
case ASMIT_LDX:
|
||||||
if (mMode == ASMIM_IMMEDIATE)
|
if (mMode == ASMIM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
if (data.mRegs[CPU_REG_X].mImmediate && data.mRegs[CPU_REG_X].mValue == mAddress)
|
if (data.mRegs[CPU_REG_X].mImmediate && data.mRegs[CPU_REG_X].mValue == mAddress && !(mLive & LIVE_CPU_REG_Z))
|
||||||
{
|
{
|
||||||
mType = ASMIT_NOP;
|
mType = ASMIT_NOP;
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -538,19 +618,27 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
||||||
data.mRegs[CPU_REG_X].mImmediate = true;
|
data.mRegs[CPU_REG_X].mImmediate = true;
|
||||||
data.mRegs[CPU_REG_X].mZeroPage = false;
|
data.mRegs[CPU_REG_X].mZeroPage = false;
|
||||||
data.mRegs[CPU_REG_X].mValue = mAddress;
|
data.mRegs[CPU_REG_X].mValue = mAddress;
|
||||||
|
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = mAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mMode != ASMIM_ZERO_PAGE)
|
else
|
||||||
data.mRegs[CPU_REG_X].Reset();
|
{
|
||||||
|
if (mMode != ASMIM_ZERO_PAGE)
|
||||||
|
data.mRegs[CPU_REG_X].Reset();
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ASMIT_INX:
|
case ASMIT_INX:
|
||||||
case ASMIT_DEX:
|
case ASMIT_DEX:
|
||||||
data.mRegs[CPU_REG_X].Reset();
|
data.mRegs[CPU_REG_X].Reset();
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
break;
|
break;
|
||||||
case ASMIT_LDY:
|
case ASMIT_LDY:
|
||||||
if (mMode == ASMIM_IMMEDIATE)
|
if (mMode == ASMIM_IMMEDIATE)
|
||||||
{
|
{
|
||||||
if (data.mRegs[CPU_REG_Y].mImmediate && data.mRegs[CPU_REG_Y].mValue == mAddress)
|
if (data.mRegs[CPU_REG_Y].mImmediate && data.mRegs[CPU_REG_Y].mValue == mAddress && !(mLive & LIVE_CPU_REG_Z))
|
||||||
{
|
{
|
||||||
mType = ASMIT_NOP;
|
mType = ASMIT_NOP;
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -560,27 +648,63 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
||||||
data.mRegs[CPU_REG_Y].mImmediate = true;
|
data.mRegs[CPU_REG_Y].mImmediate = true;
|
||||||
data.mRegs[CPU_REG_Y].mZeroPage = false;
|
data.mRegs[CPU_REG_Y].mZeroPage = false;
|
||||||
data.mRegs[CPU_REG_Y].mValue = mAddress;
|
data.mRegs[CPU_REG_Y].mValue = mAddress;
|
||||||
|
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = mAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mMode != ASMIM_ZERO_PAGE)
|
else
|
||||||
data.mRegs[CPU_REG_Y].Reset();
|
{
|
||||||
|
if (mMode != ASMIM_ZERO_PAGE)
|
||||||
|
data.mRegs[CPU_REG_Y].Reset();
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ASMIT_INY:
|
case ASMIT_INY:
|
||||||
case ASMIT_DEY:
|
case ASMIT_DEY:
|
||||||
data.mRegs[CPU_REG_Y].Reset();
|
data.mRegs[CPU_REG_Y].Reset();
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ASMIT_TXA:
|
case ASMIT_TXA:
|
||||||
data.mRegs[CPU_REG_A] = data.mRegs[CPU_REG_X];
|
data.mRegs[CPU_REG_A] = data.mRegs[CPU_REG_X];
|
||||||
|
if (data.mRegs[CPU_REG_A].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
break;
|
break;
|
||||||
case ASMIT_TYA:
|
case ASMIT_TYA:
|
||||||
data.mRegs[CPU_REG_A] = data.mRegs[CPU_REG_Y];
|
data.mRegs[CPU_REG_A] = data.mRegs[CPU_REG_Y];
|
||||||
|
if (data.mRegs[CPU_REG_A].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
break;
|
break;
|
||||||
case ASMIT_TAX:
|
case ASMIT_TAX:
|
||||||
data.mRegs[CPU_REG_X] = data.mRegs[CPU_REG_A];
|
data.mRegs[CPU_REG_X] = data.mRegs[CPU_REG_A];
|
||||||
|
if (data.mRegs[CPU_REG_A].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
break;
|
break;
|
||||||
case ASMIT_TAY:
|
case ASMIT_TAY:
|
||||||
data.mRegs[CPU_REG_Y] = data.mRegs[CPU_REG_A];
|
data.mRegs[CPU_REG_Y] = data.mRegs[CPU_REG_A];
|
||||||
|
if (data.mRegs[CPU_REG_A].mImmediate)
|
||||||
|
{
|
||||||
|
data.mRegs[CPU_REG_Z].mImmediate = true;
|
||||||
|
data.mRegs[CPU_REG_Z].mValue = data.mRegs[CPU_REG_A].mValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
data.mRegs[CPU_REG_Z].Reset();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,7 +713,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
||||||
switch (mType)
|
switch (mType)
|
||||||
{
|
{
|
||||||
case ASMIT_LDA:
|
case ASMIT_LDA:
|
||||||
if (data.mRegs[CPU_REG_A].mZeroPage && data.mRegs[CPU_REG_A].mValue == mAddress)
|
if (data.mRegs[CPU_REG_A].mZeroPage && data.mRegs[CPU_REG_A].mValue == mAddress && !(mLive & LIVE_CPU_REG_Z))
|
||||||
{
|
{
|
||||||
mType = ASMIT_NOP;
|
mType = ASMIT_NOP;
|
||||||
changed = true;
|
changed = true;
|
||||||
|
@ -2059,9 +2183,6 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
||||||
{
|
{
|
||||||
if (ins.mOperandSize == 1)
|
if (ins.mOperandSize == 1)
|
||||||
{
|
{
|
||||||
if (ins.mTType == IT_SIGNED)
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, 0));
|
|
||||||
|
|
||||||
if (ins.mMemory == IM_GLOBAL)
|
if (ins.mMemory == IM_GLOBAL)
|
||||||
{
|
{
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0], ins.mVarIndex));
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ABSOLUTE, ins.mSIntConst[0], ins.mVarIndex));
|
||||||
|
@ -2093,16 +2214,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
||||||
mIns.Push(*ainsl);
|
mIns.Push(*ainsl);
|
||||||
}
|
}
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
||||||
if (ins.mTType == IT_SIGNED)
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
{
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, 1));
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_TXA, ASMIM_IMPLIED));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
|
||||||
}
|
|
||||||
if (ainsh) mIns.Push(*ainsh);
|
if (ainsh) mIns.Push(*ainsh);
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
||||||
}
|
}
|
||||||
|
@ -2174,8 +2286,6 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
||||||
{
|
{
|
||||||
if (ins.mOperandSize == 1)
|
if (ins.mOperandSize == 1)
|
||||||
{
|
{
|
||||||
if (ins.mTType == IT_SIGNED)
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, 0));
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins.mSIntConst[0]));
|
mIns.Push(NativeCodeInstruction(ASMIT_LDY, ASMIM_IMMEDIATE, ins.mSIntConst[0]));
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
|
||||||
if (ainsl)
|
if (ainsl)
|
||||||
|
@ -2187,16 +2297,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
||||||
mIns.Push(*ainsl);
|
mIns.Push(*ainsl);
|
||||||
}
|
}
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
||||||
if (ins.mTType == IT_SIGNED)
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
{
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, 1));
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_TXA, ASMIM_IMPLIED));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
|
||||||
}
|
|
||||||
if (ainsh) mIns.Push(*ainsh);
|
if (ainsh) mIns.Push(*ainsh);
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg + 1));
|
||||||
}
|
}
|
||||||
|
@ -3192,10 +3293,7 @@ void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Int
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 3));
|
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));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
|
||||||
|
|
||||||
if (ins.mTType == IT_SIGNED)
|
mIns.Push(NativeCodeInstruction("ftoi"));
|
||||||
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_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_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 0));
|
||||||
|
@ -3210,10 +3308,7 @@ void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Int
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]] + 1));
|
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_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||||
|
|
||||||
if (ins.mSType[0] == IT_SIGNED)
|
mIns.Push(NativeCodeInstruction("ffromi"));
|
||||||
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_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_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 0));
|
||||||
|
@ -3225,6 +3320,24 @@ void NativeCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Int
|
||||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 3));
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 3));
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
case IA_EXT8TO16S:
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
|
||||||
|
if (ins.mSTemp[0] != ins.mTTemp)
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp]));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_BPL, ASMIM_RELATIVE, 1));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_DEX, ASMIM_IMPLIED));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STX, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 1));
|
||||||
|
break;
|
||||||
|
case IA_EXT8TO16U:
|
||||||
|
if (ins.mSTemp[0] != ins.mTTemp)
|
||||||
|
{
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp]));
|
||||||
|
}
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||||
|
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, BC_REG_TMP + proc->mTempOffset[ins.mTTemp] + 1));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3688,6 +3801,47 @@ bool NativeCodeBasicBlock::RemoveUnusedResultInstructions(void)
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeCodeBasicBlock::CountEntries(void)
|
||||||
|
{
|
||||||
|
mNumEntries++;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
if (mTrueJump)
|
||||||
|
mTrueJump->CountEntries();
|
||||||
|
if (mFalseJump)
|
||||||
|
mFalseJump->CountEntries();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NativeCodeBasicBlock::MergeBasicBlocks(void)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
if (!mVisited)
|
||||||
|
{
|
||||||
|
mVisited = true;
|
||||||
|
|
||||||
|
while (mTrueJump && !mFalseJump && mTrueJump->mNumEntries == 1 && mTrueJump != this)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < mTrueJump->mIns.Size(); i++)
|
||||||
|
mIns.Push(mTrueJump->mIns[i]);
|
||||||
|
mBranch = mTrueJump->mBranch;
|
||||||
|
mFalseJump = mTrueJump->mFalseJump;
|
||||||
|
mTrueJump = mTrueJump->mTrueJump;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mTrueJump)
|
||||||
|
mTrueJump->MergeBasicBlocks();
|
||||||
|
if (mFalseJump)
|
||||||
|
mFalseJump->MergeBasicBlocks();
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
bool NativeCodeBasicBlock::MoveLoadStoreUp(int at)
|
bool NativeCodeBasicBlock::MoveLoadStoreUp(int at)
|
||||||
{
|
{
|
||||||
int j = at;
|
int j = at;
|
||||||
|
@ -3734,6 +3888,73 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
||||||
mIns[i].ValueForwarding(data);
|
mIns[i].ValueForwarding(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mFalseJump)
|
||||||
|
{
|
||||||
|
switch (mBranch)
|
||||||
|
{
|
||||||
|
case ASMIT_BCS:
|
||||||
|
if (data.mRegs[CPU_REG_C].mImmediate)
|
||||||
|
{
|
||||||
|
mBranch = ASMIT_JMP;
|
||||||
|
if (!data.mRegs[CPU_REG_C].mValue)
|
||||||
|
mTrueJump = mFalseJump;
|
||||||
|
mFalseJump = nullptr;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ASMIT_BCC:
|
||||||
|
if (data.mRegs[CPU_REG_C].mImmediate)
|
||||||
|
{
|
||||||
|
mBranch = ASMIT_JMP;
|
||||||
|
if (data.mRegs[CPU_REG_C].mValue)
|
||||||
|
mTrueJump = mFalseJump;
|
||||||
|
mFalseJump = nullptr;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ASMIT_BNE:
|
||||||
|
if (data.mRegs[CPU_REG_Z].mImmediate)
|
||||||
|
{
|
||||||
|
mBranch = ASMIT_JMP;
|
||||||
|
if (data.mRegs[CPU_REG_Z].mValue)
|
||||||
|
mTrueJump = mFalseJump;
|
||||||
|
mFalseJump = nullptr;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ASMIT_BEQ:
|
||||||
|
if (data.mRegs[CPU_REG_Z].mImmediate)
|
||||||
|
{
|
||||||
|
mBranch = ASMIT_JMP;
|
||||||
|
if (!data.mRegs[CPU_REG_Z].mValue)
|
||||||
|
mTrueJump = mFalseJump;
|
||||||
|
mFalseJump = nullptr;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ASMIT_BPL:
|
||||||
|
if (data.mRegs[CPU_REG_Z].mImmediate)
|
||||||
|
{
|
||||||
|
mBranch = ASMIT_JMP;
|
||||||
|
if (!(data.mRegs[CPU_REG_Z].mValue & 0x80))
|
||||||
|
mTrueJump = mFalseJump;
|
||||||
|
mFalseJump = nullptr;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ASMIT_BMI:
|
||||||
|
if (data.mRegs[CPU_REG_Z].mImmediate)
|
||||||
|
{
|
||||||
|
mBranch = ASMIT_JMP;
|
||||||
|
if (data.mRegs[CPU_REG_Z].mValue & 0x80)
|
||||||
|
mTrueJump = mFalseJump;
|
||||||
|
mFalseJump = nullptr;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// move load store pairs up to initial store
|
// move load store pairs up to initial store
|
||||||
|
|
||||||
for (int i = 2; i + 2 < mIns.Size(); i++)
|
for (int i = 2; i + 2 < mIns.Size(); i++)
|
||||||
|
@ -4292,10 +4513,17 @@ void NativeCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedu
|
||||||
if (entryBlock->PeepHoleOptimizer())
|
if (entryBlock->PeepHoleOptimizer())
|
||||||
changed = true;
|
changed = true;
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
for (int i = 0; i < mBlocks.Size(); i++)
|
||||||
|
mBlocks[i]->mNumEntries = 0;
|
||||||
|
entryBlock->CountEntries();
|
||||||
|
|
||||||
|
ResetVisited();
|
||||||
|
if (entryBlock->MergeBasicBlocks())
|
||||||
|
changed = true;
|
||||||
|
|
||||||
} while (changed);
|
} while (changed);
|
||||||
|
|
||||||
ResetVisited();
|
|
||||||
entryBlock->PeepHoleOptimizer();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
entryBlock->Assemble();
|
entryBlock->Assemble();
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
GrowingArray<NativeCodeInstruction> mIns;
|
GrowingArray<NativeCodeInstruction> mIns;
|
||||||
GrowingArray<ByteCodeRelocation> mRelocations;
|
GrowingArray<ByteCodeRelocation> mRelocations;
|
||||||
|
|
||||||
int mOffset, mSize;
|
int mOffset, mSize, mNumEntries;
|
||||||
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited;
|
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited;
|
||||||
|
|
||||||
int PutBranch(NativeCodeProcedure* proc, AsmInsType code, int offset);
|
int PutBranch(NativeCodeProcedure* proc, AsmInsType code, int offset);
|
||||||
|
@ -114,6 +114,9 @@ public:
|
||||||
bool BuildGlobalRequiredRegSet(NumberSet& fromRequiredTemps);
|
bool BuildGlobalRequiredRegSet(NumberSet& fromRequiredTemps);
|
||||||
bool RemoveUnusedResultInstructions(void);
|
bool RemoveUnusedResultInstructions(void);
|
||||||
|
|
||||||
|
void CountEntries(void);
|
||||||
|
bool MergeBasicBlocks(void);
|
||||||
|
|
||||||
bool MoveLoadStoreUp(int at);
|
bool MoveLoadStoreUp(int at);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,29 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TK_SIGNED:
|
||||||
|
dec = new Declaration(mScanner->mLocation, DT_TYPE_INTEGER);
|
||||||
|
dec->mFlags = flags | DTF_DEFINED | DTF_SIGNED;
|
||||||
|
mScanner->NextToken();
|
||||||
|
if (mScanner->mToken == TK_INT || mScanner->mToken == TK_SHORT)
|
||||||
|
{
|
||||||
|
dec->mSize = 2;
|
||||||
|
mScanner->NextToken();
|
||||||
|
}
|
||||||
|
else if (mScanner->mToken == TK_LONG)
|
||||||
|
{
|
||||||
|
dec->mSize = 4;
|
||||||
|
mScanner->NextToken();
|
||||||
|
}
|
||||||
|
else if (mScanner->mToken == TK_CHAR)
|
||||||
|
{
|
||||||
|
dec->mSize = 1;
|
||||||
|
mScanner->NextToken();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dec->mSize = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
case TK_CONST:
|
case TK_CONST:
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
return ParseBaseTypeDeclaration(flags | DTF_CONST);
|
return ParseBaseTypeDeclaration(flags | DTF_CONST);
|
||||||
|
@ -157,14 +180,14 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
|
||||||
case TK_CHAR:
|
case TK_CHAR:
|
||||||
dec = new Declaration(mScanner->mLocation, DT_TYPE_INTEGER);
|
dec = new Declaration(mScanner->mLocation, DT_TYPE_INTEGER);
|
||||||
dec->mSize = 1;
|
dec->mSize = 1;
|
||||||
dec->mFlags = flags | DTF_DEFINED | DTF_SIGNED;
|
dec->mFlags = flags | DTF_DEFINED;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TK_BOOL:
|
case TK_BOOL:
|
||||||
dec = new Declaration(mScanner->mLocation, DT_TYPE_BOOL);
|
dec = new Declaration(mScanner->mLocation, DT_TYPE_BOOL);
|
||||||
dec->mSize = 1;
|
dec->mSize = 1;
|
||||||
dec->mFlags = flags | DTF_DEFINED | DTF_SIGNED;
|
dec->mFlags = flags | DTF_DEFINED;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -840,6 +863,7 @@ Expression* Parser::ParseSimpleExpression(void)
|
||||||
case TK_BOOL:
|
case TK_BOOL:
|
||||||
case TK_VOID:
|
case TK_VOID:
|
||||||
case TK_UNSIGNED:
|
case TK_UNSIGNED:
|
||||||
|
case TK_SIGNED:
|
||||||
case TK_CONST:
|
case TK_CONST:
|
||||||
case TK_VOLATILE:
|
case TK_VOLATILE:
|
||||||
case TK_STRUCT:
|
case TK_STRUCT:
|
||||||
|
@ -878,7 +902,7 @@ Expression* Parser::ParseSimpleExpression(void)
|
||||||
dec->mVarIndex = -1;
|
dec->mVarIndex = -1;
|
||||||
dec->mBase = new Declaration(mScanner->mLocation, DT_TYPE_ARRAY);
|
dec->mBase = new Declaration(mScanner->mLocation, DT_TYPE_ARRAY);
|
||||||
dec->mBase->mSize = dec->mSize;
|
dec->mBase->mSize = dec->mSize;
|
||||||
dec->mBase->mBase = TheConstSignedCharTypeDeclaration;
|
dec->mBase->mBase = TheConstCharTypeDeclaration;
|
||||||
dec->mBase->mFlags |= DTF_DEFINED;
|
dec->mBase->mFlags |= DTF_DEFINED;
|
||||||
uint8* d = new uint8[dec->mSize];
|
uint8* d = new uint8[dec->mSize];
|
||||||
dec->mData = d;
|
dec->mData = d;
|
||||||
|
@ -1206,6 +1230,12 @@ Expression* Parser::ParseMulExpression(void)
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = exp;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
nexp->mRight = ParsePrefixExpression();
|
nexp->mRight = ParsePrefixExpression();
|
||||||
|
|
||||||
|
if (nexp->mLeft->mDecType->mType == DT_TYPE_FLOAT || nexp->mRight->mDecType->mType == DT_TYPE_FLOAT)
|
||||||
|
nexp->mDecType = TheFloatTypeDeclaration;
|
||||||
|
else
|
||||||
|
nexp->mDecType = exp->mDecType;
|
||||||
|
|
||||||
exp = nexp->ConstantFold();
|
exp = nexp->ConstantFold();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1223,6 +1253,15 @@ Expression* Parser::ParseAddExpression(void)
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = exp;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
nexp->mRight = ParseMulExpression();
|
nexp->mRight = ParseMulExpression();
|
||||||
|
if (nexp->mLeft->mDecType->mType == DT_TYPE_POINTER && nexp->mRight->mDecType->IsIntegerType())
|
||||||
|
nexp->mDecType = nexp->mLeft->mDecType;
|
||||||
|
else if (nexp->mRight->mDecType->mType == DT_TYPE_POINTER && nexp->mLeft->mDecType->IsIntegerType())
|
||||||
|
nexp->mDecType = nexp->mRight->mDecType;
|
||||||
|
else if (nexp->mLeft->mDecType->mType == DT_TYPE_FLOAT || nexp->mRight->mDecType->mType == DT_TYPE_FLOAT)
|
||||||
|
nexp->mDecType = TheFloatTypeDeclaration;
|
||||||
|
else
|
||||||
|
nexp->mDecType = exp->mDecType;
|
||||||
|
|
||||||
exp = nexp->ConstantFold();
|
exp = nexp->ConstantFold();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1240,6 +1279,8 @@ Expression* Parser::ParseShiftExpression(void)
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = exp;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
nexp->mRight = ParseAddExpression();
|
nexp->mRight = ParseAddExpression();
|
||||||
|
nexp->mDecType = exp->mDecType;
|
||||||
|
|
||||||
exp = nexp->ConstantFold();
|
exp = nexp->ConstantFold();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1257,6 +1298,8 @@ Expression* Parser::ParseRelationalExpression(void)
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = exp;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
nexp->mRight = ParseShiftExpression();
|
nexp->mRight = ParseShiftExpression();
|
||||||
|
nexp->mDecType = TheBoolTypeDeclaration;
|
||||||
|
|
||||||
exp = nexp->ConstantFold();
|
exp = nexp->ConstantFold();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1274,6 +1317,8 @@ Expression* Parser::ParseBinaryAndExpression(void)
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = exp;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
nexp->mRight = ParseRelationalExpression();
|
nexp->mRight = ParseRelationalExpression();
|
||||||
|
nexp->mDecType = exp->mDecType;
|
||||||
|
|
||||||
exp = nexp->ConstantFold();
|
exp = nexp->ConstantFold();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1291,6 +1336,7 @@ Expression* Parser::ParseBinaryXorExpression(void)
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = exp;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
nexp->mRight = ParseBinaryAndExpression();
|
nexp->mRight = ParseBinaryAndExpression();
|
||||||
|
nexp->mDecType = exp->mDecType;
|
||||||
exp = nexp->ConstantFold();
|
exp = nexp->ConstantFold();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1308,6 +1354,7 @@ Expression* Parser::ParseBinaryOrExpression(void)
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = exp;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
nexp->mRight = ParseBinaryXorExpression();
|
nexp->mRight = ParseBinaryXorExpression();
|
||||||
|
nexp->mDecType = exp->mDecType;
|
||||||
exp = nexp->ConstantFold();
|
exp = nexp->ConstantFold();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1325,6 +1372,7 @@ Expression* Parser::ParseLogicAndExpression(void)
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = exp;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
nexp->mRight = ParseBinaryOrExpression();
|
nexp->mRight = ParseBinaryOrExpression();
|
||||||
|
nexp->mDecType = TheBoolTypeDeclaration;
|
||||||
exp = nexp->ConstantFold();
|
exp = nexp->ConstantFold();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1342,6 +1390,7 @@ Expression* Parser::ParseLogicOrExpression(void)
|
||||||
nexp->mLeft = exp;
|
nexp->mLeft = exp;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
nexp->mRight = ParseLogicAndExpression();
|
nexp->mRight = ParseLogicAndExpression();
|
||||||
|
nexp->mDecType = TheBoolTypeDeclaration;
|
||||||
exp = nexp->ConstantFold();
|
exp = nexp->ConstantFold();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ const char* TokenNames[] = {
|
||||||
"'char'",
|
"'char'",
|
||||||
"'float'",
|
"'float'",
|
||||||
"'unsigned'",
|
"'unsigned'",
|
||||||
|
"'signed'",
|
||||||
"'switch'",
|
"'switch'",
|
||||||
"'case'",
|
"'case'",
|
||||||
"'default'",
|
"'default'",
|
||||||
|
@ -922,6 +923,8 @@ void Scanner::NextRawToken(void)
|
||||||
mToken = TK_LONG;
|
mToken = TK_LONG;
|
||||||
else if (!strcmp(tkident, "unsigned"))
|
else if (!strcmp(tkident, "unsigned"))
|
||||||
mToken = TK_UNSIGNED;
|
mToken = TK_UNSIGNED;
|
||||||
|
else if (!strcmp(tkident, "signed"))
|
||||||
|
mToken = TK_SIGNED;
|
||||||
else if (!strcmp(tkident, "const"))
|
else if (!strcmp(tkident, "const"))
|
||||||
mToken = TK_CONST;
|
mToken = TK_CONST;
|
||||||
else if (!strcmp(tkident, "volatile"))
|
else if (!strcmp(tkident, "volatile"))
|
||||||
|
|
|
@ -21,6 +21,7 @@ enum Token
|
||||||
TK_CHAR,
|
TK_CHAR,
|
||||||
TK_FLOAT,
|
TK_FLOAT,
|
||||||
TK_UNSIGNED,
|
TK_UNSIGNED,
|
||||||
|
TK_SIGNED,
|
||||||
TK_SWITCH,
|
TK_SWITCH,
|
||||||
TK_CASE,
|
TK_CASE,
|
||||||
TK_DEFAULT,
|
TK_DEFAULT,
|
||||||
|
|
Loading…
Reference in New Issue