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];
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
@ -18,6 +19,7 @@ int main(void)
|
|||
{
|
||||
a[i] = i % 10;
|
||||
}
|
||||
|
||||
assert(sum(a, 100) == 450);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -223,71 +223,6 @@ L2: jsr divmod
|
|||
#pragma runtime(divs16, divs16);
|
||||
#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
|
||||
{
|
||||
|
@ -481,6 +416,21 @@ __asm 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
|
||||
{
|
||||
lda (ip), y
|
||||
|
|
|
@ -113,6 +113,8 @@ enum ByteCode
|
|||
BC_CONV_F32_U16,
|
||||
BC_CONV_F32_I16,
|
||||
|
||||
BC_CONV_I8_I16,
|
||||
|
||||
BC_JUMPS,
|
||||
BC_BRANCHS_EQ,
|
||||
BC_BRANCHS_NE,
|
||||
|
|
|
@ -364,6 +364,11 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
|
|||
block->PutCode(generator, mCode);
|
||||
break;
|
||||
|
||||
case BC_CONV_I8_I16:
|
||||
block->PutCode(generator, mCode);
|
||||
block->PutByte(mRegister);
|
||||
break;
|
||||
|
||||
case BC_JUMPS:
|
||||
case BC_BRANCHS_EQ:
|
||||
case BC_BRANCHS_NE:
|
||||
|
@ -1371,7 +1376,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
|||
{
|
||||
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.mVIndex = ins.mVarIndex;
|
||||
bins.mValue = ins.mSIntConst[0];
|
||||
|
@ -1380,7 +1385,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
|||
}
|
||||
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.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
|
||||
mIns.Push(bins);
|
||||
|
@ -1395,7 +1400,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
|||
|
||||
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.mValue = index;
|
||||
mIns.Push(bins);
|
||||
|
@ -1406,7 +1411,7 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
|||
lins.mRegister = BC_REG_ADDR;
|
||||
lins.mValue = index;
|
||||
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.mValue = 0;
|
||||
mIns.Push(bins);
|
||||
|
@ -1471,20 +1476,10 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
|
|||
|
||||
if (ins.mOperandSize == 1)
|
||||
{
|
||||
if (ins.mTType == IT_SIGNED)
|
||||
{
|
||||
ByteCodeInstruction bins(BC_LOAD_ADDR_I8);
|
||||
bins.mRegister = BC_REG_TMP + proc->mTempOffset[ins.mTTemp];
|
||||
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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
|
@ -1820,7 +1815,8 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter
|
|||
lins.mRegisterFinal = ins.mSFinal[0];
|
||||
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);
|
||||
|
||||
ByteCodeInstruction sins(BC_STORE_REG_16);
|
||||
|
@ -1835,7 +1831,8 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter
|
|||
lins.mRegisterFinal = ins.mSFinal[0];
|
||||
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);
|
||||
|
||||
ByteCodeInstruction sins(BC_STORE_REG_32);
|
||||
|
@ -1843,6 +1840,59 @@ void ByteCodeBasicBlock::NumericConversion(InterCodeProcedure* proc, const Inter
|
|||
mIns.Push(sins);
|
||||
|
||||
} 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;
|
||||
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)
|
||||
|
@ -3206,6 +3273,11 @@ void ByteCodeProcedure::Disassemble(FILE * file, ByteCodeGenerator * generator,
|
|||
i += 2;
|
||||
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:
|
||||
fprintf(file, "SHL\tACCU, #%d", uint8(generator->mMemory[mProgStart + i + 0]));
|
||||
i += 1;
|
||||
|
|
|
@ -102,6 +102,8 @@ enum ByteCode
|
|||
BC_CONV_F32_U16,
|
||||
BC_CONV_F32_I16,
|
||||
|
||||
BC_CONV_I8_I16,
|
||||
|
||||
BC_JUMPS,
|
||||
BC_BRANCHS_EQ,
|
||||
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;
|
||||
}
|
||||
|
||||
Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstSignedCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration, * TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration;
|
||||
Declaration* TheVoidTypeDeclaration, * TheSignedIntTypeDeclaration, * TheUnsignedIntTypeDeclaration, * TheConstCharTypeDeclaration, * TheCharTypeDeclaration, * TheSignedCharTypeDeclaration, * TheUnsignedCharTypeDeclaration, * TheBoolTypeDeclaration, * TheFloatTypeDeclaration, * TheVoidPointerTypeDeclaration;
|
||||
|
||||
void InitDeclarations(void)
|
||||
{
|
||||
|
@ -495,13 +495,14 @@ void InitDeclarations(void)
|
|||
TheSignedCharTypeDeclaration->mSize = 1;
|
||||
TheSignedCharTypeDeclaration->mFlags = DTF_DEFINED | DTF_SIGNED;
|
||||
|
||||
TheConstSignedCharTypeDeclaration = new Declaration(noloc, DT_TYPE_INTEGER);
|
||||
TheConstSignedCharTypeDeclaration->mSize = 1;
|
||||
TheConstSignedCharTypeDeclaration->mFlags = DTF_DEFINED | DTF_SIGNED | DTF_CONST;
|
||||
TheConstCharTypeDeclaration = new Declaration(noloc, DT_TYPE_INTEGER);
|
||||
TheConstCharTypeDeclaration->mSize = 1;
|
||||
TheConstCharTypeDeclaration->mFlags = DTF_DEFINED | DTF_CONST;
|
||||
|
||||
TheUnsignedCharTypeDeclaration = new Declaration(noloc, DT_TYPE_INTEGER);
|
||||
TheUnsignedCharTypeDeclaration->mSize = 1;
|
||||
TheUnsignedCharTypeDeclaration->mFlags = DTF_DEFINED;
|
||||
TheCharTypeDeclaration = TheUnsignedCharTypeDeclaration;
|
||||
|
||||
TheBoolTypeDeclaration = new Declaration(noloc, DT_TYPE_BOOL);
|
||||
TheBoolTypeDeclaration->mSize = 1;
|
||||
|
|
|
@ -166,4 +166,4 @@ public:
|
|||
|
||||
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);
|
||||
// return;
|
||||
return;
|
||||
|
||||
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)
|
||||
{
|
||||
InterInstructionPtr* nins;
|
||||
|
@ -717,14 +744,11 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
|||
break;
|
||||
|
||||
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;
|
||||
while (i < mNum &&
|
||||
(mInstructions[i]->mCode != IC_CONSTANT ||
|
||||
|
@ -748,31 +772,32 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
|
|||
}
|
||||
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);
|
||||
}
|
||||
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;
|
||||
|
||||
|
@ -992,7 +1017,7 @@ void InterInstruction::SetCode(const Location& loc, InterCode code)
|
|||
|
||||
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)
|
||||
|
@ -1002,7 +1027,7 @@ static bool TypeCompatible(InterType t1, InterType t2)
|
|||
|
||||
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)
|
||||
|
@ -1010,7 +1035,7 @@ static InterType TypeCheckArithmecitResult(InterType t1, InterType t2)
|
|||
if (t1 == IT_FLOAT && t2 == IT_FLOAT)
|
||||
return IT_FLOAT;
|
||||
else if (TypeInteger(t1) && TypeInteger(t2))
|
||||
return IT_SIGNED;
|
||||
return t1 > t2 ? t1 : t2;
|
||||
else
|
||||
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)
|
||||
{
|
||||
if (mCode == IC_STORE)
|
||||
if (mCode == IC_STORE && mSTemp[0] >= 0)
|
||||
{
|
||||
int l = localTable[mSTemp[0]];
|
||||
if (l >= 0)
|
||||
|
@ -1578,7 +1603,7 @@ void InterInstruction::Disassemble(FILE* file)
|
|||
fprintf(file, "RET");
|
||||
break;
|
||||
}
|
||||
static char typechars[] = "NUSFPB";
|
||||
static char typechars[] = "NBCILFP";
|
||||
|
||||
fprintf(file, "\t");
|
||||
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:
|
||||
break;
|
||||
default:
|
||||
if (ins.mSType[0] == IT_UNSIGNED)
|
||||
ins.mSIntConst[0] = unsigned short (tvalue[ins.mSTemp[0]]->mIntValue);
|
||||
else
|
||||
ins.mSIntConst[0] = tvalue[ins.mSTemp[0]]->mIntValue;
|
||||
ins.mSIntConst[0] = tvalue[ins.mSTemp[0]]->mIntValue;
|
||||
ins.mSTemp[0] = -1;
|
||||
break;
|
||||
}
|
||||
|
@ -1823,6 +1845,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
|
|||
ins.mMemory = tvalue[ins.mSTemp[1]]->mMemory;
|
||||
ins.mVarIndex = tvalue[ins.mSTemp[1]]->mVarIndex;
|
||||
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[1] = -1;
|
||||
}
|
||||
|
@ -1847,7 +1870,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
|
|||
ins.mCode = IC_LOAD_TEMPORARY;
|
||||
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)
|
||||
{
|
||||
|
@ -1870,10 +1893,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
|
|||
case IT_POINTER:
|
||||
break;
|
||||
default:
|
||||
if (ins.mSType[0] == IT_UNSIGNED)
|
||||
ins.mSIntConst[0] = unsigned short(tvalue[ins.mSTemp[0]]->mIntValue);
|
||||
else
|
||||
ins.mSIntConst[0] = tvalue[ins.mSTemp[0]]->mIntValue;
|
||||
ins.mSIntConst[0] = tvalue[ins.mSTemp[0]]->mIntValue;
|
||||
ins.mSTemp[0] = -1;
|
||||
break;
|
||||
}
|
||||
|
@ -2129,7 +2149,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction& ins, const GrowingIn
|
|||
{
|
||||
ins.mCode = IC_CONSTANT;
|
||||
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[1] = -1;
|
||||
}
|
||||
|
|
|
@ -37,11 +37,12 @@ enum InterCode
|
|||
enum InterType
|
||||
{
|
||||
IT_NONE,
|
||||
IT_UNSIGNED,
|
||||
IT_SIGNED,
|
||||
IT_BOOL,
|
||||
IT_INT8,
|
||||
IT_INT16,
|
||||
IT_INT32,
|
||||
IT_FLOAT,
|
||||
IT_POINTER,
|
||||
IT_BOOL
|
||||
IT_POINTER
|
||||
};
|
||||
|
||||
enum InterMemory
|
||||
|
@ -89,7 +90,14 @@ enum InterOperator
|
|||
IA_CMPGU,
|
||||
IA_CMPLU,
|
||||
IA_FLOAT2INT,
|
||||
IA_INT2FLOAT
|
||||
IA_INT2FLOAT,
|
||||
|
||||
IA_EXT8TO16U,
|
||||
IA_EXT8TO32U,
|
||||
IA_EXT16TO32U,
|
||||
IA_EXT8TO16S,
|
||||
IA_EXT8TO32S,
|
||||
IA_EXT16TO32S
|
||||
};
|
||||
|
||||
class InterInstruction;
|
||||
|
|
|
@ -20,8 +20,14 @@ static inline InterType InterTypeOf(const Declaration* dec)
|
|||
case DT_TYPE_VOID:
|
||||
return IT_NONE;
|
||||
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:
|
||||
return (dec->mFlags & DTF_SIGNED) ? IT_SIGNED : IT_UNSIGNED;
|
||||
return IT_INT8;
|
||||
case DT_TYPE_BOOL:
|
||||
return IT_BOOL;
|
||||
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)
|
||||
{
|
||||
int stemp = v.mTemp;
|
||||
|
||||
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;
|
||||
cins.mCode = IC_CONVERSION_OPERATOR;
|
||||
cins.mOperator = IA_INT2FLOAT;
|
||||
cins.mSType[0] = InterTypeOf(v.mType);
|
||||
cins.mSTemp[0] = v.mTemp;
|
||||
cins.mSType[0] = IT_INT16;
|
||||
cins.mSTemp[0] = stemp;
|
||||
cins.mTType = IT_FLOAT;
|
||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||
cins.mTTemp = proc->AddTemporary(IT_FLOAT);
|
||||
block->Append(cins);
|
||||
|
||||
v.mTemp = cins.mTTemp;
|
||||
v.mType = type;
|
||||
block->Append(cins);
|
||||
}
|
||||
else if (v.mType->mType == DT_TYPE_FLOAT && type->IsIntegerType())
|
||||
{
|
||||
InterInstruction cins;
|
||||
cins.mCode = IC_CONVERSION_OPERATOR;
|
||||
cins.mOperator = IA_FLOAT2INT;
|
||||
cins.mSType[0] = InterTypeOf(v.mType);
|
||||
cins.mSType[0] = IT_FLOAT;
|
||||
cins.mSTemp[0] = v.mTemp;
|
||||
cins.mTType = InterTypeOf(type);
|
||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||
cins.mTType = IT_INT16;
|
||||
cins.mTTemp = proc->AddTemporary(IT_INT16);
|
||||
block->Append(cins);
|
||||
v.mTemp = cins.mTTemp;
|
||||
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;
|
||||
|
@ -87,21 +163,21 @@ InterCodeGenerator::ExValue InterCodeGenerator::CoerceType(InterCodeProcedure* p
|
|||
|
||||
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)
|
||||
{
|
||||
if (t1 == IT_FLOAT || t2 == IT_FLOAT)
|
||||
return IT_FLOAT;
|
||||
else if (t1 == IT_SIGNED && t2 == IT_SIGNED)
|
||||
return IT_SIGNED;
|
||||
else if (InterTypeTypeInteger(t1) && InterTypeTypeInteger(t2))
|
||||
return t1 > t2 ? t1 : t2;
|
||||
else if (t1 == IT_POINTER && t2 == IT_POINTER)
|
||||
return IT_SIGNED;
|
||||
return IT_INT16;
|
||||
else if (t1 == IT_POINTER || t2 == IT_POINTER)
|
||||
return IT_POINTER;
|
||||
else
|
||||
return IT_UNSIGNED;
|
||||
return IT_INT16;
|
||||
}
|
||||
|
||||
void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration* dec)
|
||||
|
@ -360,17 +436,37 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
ins.mCode = IC_CONSTANT;
|
||||
ins.mTType = InterTypeOf(dec->mBase);
|
||||
ins.mTTemp = proc->AddTemporary(ins.mTType);
|
||||
if (ins.mTType == IT_SIGNED)
|
||||
if (ins.mTType == IT_INT8)
|
||||
{
|
||||
if (dec->mInteger < -32768 || dec->mInteger > 32767)
|
||||
mErrors->Warning(dec->mLocation, "Integer constant truncated");
|
||||
if (dec->mFlags & DTF_SIGNED)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dec->mInteger < 0 || dec->mInteger > 65535)
|
||||
mErrors->Warning(dec->mLocation, "Unsigned integer constant truncated");
|
||||
ins.mIntValue = unsigned short(dec->mInteger);
|
||||
ins.mIntValue = dec->mInteger;
|
||||
}
|
||||
block->Append(ins);
|
||||
return ExValue(dec->mBase, ins.mTTemp);
|
||||
|
@ -533,8 +629,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
vr = TranslateExpression(procType, proc, block, exp->mRight, breakBlock, continueBlock);
|
||||
vl = TranslateExpression(procType, proc, block, exp->mLeft, breakBlock, continueBlock);
|
||||
|
||||
if (!vl.mType->CanAssign(vr.mType))
|
||||
mErrors->Error(exp->mLocation, "Cannot assign incompatible types");
|
||||
if (exp->mToken == TK_ASSIGN || !(vl.mType->mType == IT_POINTER && vr.mType->IsIntegerType() && (exp->mToken == TK_ASSIGN_ADD || exp->mToken == TK_ASSIGN_SUB)))
|
||||
{
|
||||
if (!vl.mType->CanAssign(vr.mType))
|
||||
mErrors->Error(exp->mLocation, "Cannot assign incompatible types");
|
||||
}
|
||||
|
||||
if (vl.mType->mFlags & DTF_CONST)
|
||||
mErrors->Error(exp->mLocation, "Cannot assign to const type");
|
||||
|
@ -597,31 +696,34 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
if (!vr.mType->IsIntegerType())
|
||||
mErrors->Error(exp->mLocation, "Invalid argument for pointer inc/dec");
|
||||
|
||||
cins.mTType = IT_SIGNED;
|
||||
cins.mTType = IT_INT16;
|
||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||
block->Append(cins);
|
||||
|
||||
InterInstruction mins;
|
||||
mins.mCode = IC_BINARY_OPERATOR;
|
||||
mins.mOperator = IA_MUL;
|
||||
mins.mSType[0] = IT_SIGNED;
|
||||
mins.mSType[0] = IT_INT16;
|
||||
mins.mSTemp[0] = vr.mTemp;
|
||||
mins.mSType[1] = IT_SIGNED;
|
||||
mins.mSType[1] = IT_INT16;
|
||||
mins.mSTemp[1] = cins.mTTemp;
|
||||
mins.mTType = IT_SIGNED;
|
||||
mins.mTType = IT_INT16;
|
||||
mins.mTTemp = proc->AddTemporary(mins.mTType);
|
||||
block->Append(mins);
|
||||
|
||||
InterInstruction ains;
|
||||
ains.mCode = IC_LEA;
|
||||
ains.mMemory = IM_INDIRECT;
|
||||
ains.mSType[0] = IT_SIGNED;
|
||||
ains.mSType[0] = IT_INT16;
|
||||
ains.mSTemp[0] = mins.mTTemp;
|
||||
ains.mSType[1] = IT_POINTER;
|
||||
ains.mSTemp[1] = vl.mTemp;
|
||||
ains.mSTemp[1] = vll.mTemp;
|
||||
ains.mTType = IT_POINTER;
|
||||
ains.mTTemp = proc->AddTemporary(ains.mTType);
|
||||
block->Append(ains);
|
||||
|
||||
vr.mTemp = ains.mTTemp;
|
||||
vr.mType = vll.mType;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -692,32 +794,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
}
|
||||
else
|
||||
{
|
||||
if (vl.mType->IsIntegerType() && vr.mType->mType == DT_TYPE_FLOAT)
|
||||
{
|
||||
InterInstruction cins;
|
||||
cins.mCode = IC_CONVERSION_OPERATOR;
|
||||
cins.mOperator = IA_FLOAT2INT;
|
||||
cins.mSType[0] = InterTypeOf(vr.mType);
|
||||
cins.mSTemp[0] = vr.mTemp;
|
||||
cins.mTType = InterTypeOf(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);
|
||||
}
|
||||
vr = CoerceType(proc, block, vr, vl.mType);
|
||||
}
|
||||
|
||||
ins.mCode = IC_STORE;
|
||||
|
@ -750,25 +827,25 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
InterInstruction cins;
|
||||
cins.mCode = IC_CONSTANT;
|
||||
cins.mIntValue = vl.mType->mBase->mSize;
|
||||
cins.mTType = IT_SIGNED;
|
||||
cins.mTType = IT_INT16;
|
||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||
block->Append(cins);
|
||||
|
||||
InterInstruction mins;
|
||||
mins.mCode = IC_BINARY_OPERATOR;
|
||||
mins.mOperator = IA_MUL;
|
||||
mins.mSType[0] = IT_SIGNED;
|
||||
mins.mSType[0] = IT_INT16;
|
||||
mins.mSTemp[0] = vr.mTemp;
|
||||
mins.mSType[1] = IT_SIGNED;
|
||||
mins.mSType[1] = IT_INT16;
|
||||
mins.mSTemp[1] = cins.mTTemp;
|
||||
mins.mTType = IT_SIGNED;
|
||||
mins.mTType = IT_INT16;
|
||||
mins.mTTemp = proc->AddTemporary(mins.mTType);
|
||||
block->Append(mins);
|
||||
|
||||
InterInstruction ains;
|
||||
ains.mCode = IC_LEA;
|
||||
ains.mMemory = IM_INDIRECT;
|
||||
ains.mSType[0] = IT_SIGNED;
|
||||
ains.mSType[0] = IT_INT16;
|
||||
ains.mSTemp[0] = mins.mTTemp;
|
||||
ains.mSType[1] = IT_POINTER;
|
||||
ains.mSTemp[1] = vl.mTemp;
|
||||
|
@ -790,14 +867,14 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
InterInstruction cins;
|
||||
cins.mCode = IC_CONSTANT;
|
||||
cins.mIntValue = exp->mDecValue->mOffset;
|
||||
cins.mTType = IT_SIGNED;
|
||||
cins.mTType = IT_INT16;
|
||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||
block->Append(cins);
|
||||
|
||||
InterInstruction ains;
|
||||
ains.mCode = IC_LEA;
|
||||
ains.mMemory = IM_INDIRECT;
|
||||
ains.mSType[0] = IT_SIGNED;
|
||||
ains.mSType[0] = IT_INT16;
|
||||
ains.mSTemp[0] = cins.mTTemp;
|
||||
ains.mSType[1] = IT_POINTER;
|
||||
ains.mSTemp[1] = vl.mTemp;
|
||||
|
@ -846,24 +923,24 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
else
|
||||
mErrors->Error(exp->mLocation, "Invalid pointer operation");
|
||||
|
||||
cins.mTType = IT_SIGNED;
|
||||
cins.mTType = IT_INT16;
|
||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||
block->Append(cins);
|
||||
|
||||
InterInstruction mins;
|
||||
mins.mCode = IC_BINARY_OPERATOR;
|
||||
mins.mOperator = IA_MUL;
|
||||
mins.mSType[0] = IT_SIGNED;
|
||||
mins.mSType[0] = IT_INT16;
|
||||
mins.mSTemp[0] = vr.mTemp;
|
||||
mins.mSType[1] = IT_SIGNED;
|
||||
mins.mSType[1] = IT_INT16;
|
||||
mins.mSTemp[1] = cins.mTTemp;
|
||||
mins.mTType = IT_SIGNED;
|
||||
mins.mTType = IT_INT16;
|
||||
mins.mTTemp = proc->AddTemporary(mins.mTType);
|
||||
block->Append(mins);
|
||||
|
||||
ins.mCode = IC_LEA;
|
||||
ins.mMemory = IM_INDIRECT;
|
||||
ins.mSType[0] = IT_SIGNED;
|
||||
ins.mSType[0] = IT_INT16;
|
||||
ins.mSTemp[0] = mins.mTTemp;
|
||||
ins.mSType[1] = IT_POINTER;
|
||||
ins.mSTemp[1] = vl.mTemp;
|
||||
|
@ -879,42 +956,42 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
clins.mCode = IC_TYPECAST;
|
||||
clins.mSTemp[0] = vl.mTemp;
|
||||
clins.mSType[0] = IT_POINTER;
|
||||
clins.mTType = IT_SIGNED;
|
||||
clins.mTType = IT_INT16;
|
||||
clins.mTTemp = proc->AddTemporary(clins.mTType);
|
||||
block->Append(clins);
|
||||
|
||||
crins.mCode = IC_TYPECAST;
|
||||
crins.mSTemp[0] = vr.mTemp;
|
||||
crins.mSType[0] = IT_POINTER;
|
||||
crins.mTType = IT_SIGNED;
|
||||
crins.mTType = IT_INT16;
|
||||
crins.mTTemp = proc->AddTemporary(crins.mTType);
|
||||
block->Append(crins);
|
||||
|
||||
InterInstruction cins;
|
||||
cins.mCode = IC_CONSTANT;
|
||||
cins.mIntValue = vl.mType->mBase->mSize;
|
||||
cins.mTType = IT_SIGNED;
|
||||
cins.mTType = IT_INT16;
|
||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||
block->Append(cins);
|
||||
|
||||
InterInstruction sins, dins;
|
||||
sins.mCode = IC_BINARY_OPERATOR;
|
||||
sins.mOperator = IA_SUB;
|
||||
sins.mSType[0] = IT_SIGNED;
|
||||
sins.mSType[0] = IT_INT16;
|
||||
sins.mSTemp[0] = crins.mTTemp;
|
||||
sins.mSType[1] = IT_SIGNED;
|
||||
sins.mSType[1] = IT_INT16;
|
||||
sins.mSTemp[1] = clins.mTTemp;
|
||||
sins.mTType = IT_SIGNED;
|
||||
sins.mTType = IT_INT16;
|
||||
sins.mTTemp = proc->AddTemporary(sins.mTType);
|
||||
block->Append(sins);
|
||||
|
||||
dins.mCode = IC_BINARY_OPERATOR;
|
||||
dins.mOperator = IA_DIVS;
|
||||
dins.mSType[0] = IT_SIGNED;
|
||||
dins.mSType[0] = IT_INT16;
|
||||
dins.mSTemp[0] = cins.mTTemp;
|
||||
dins.mSType[1] = IT_SIGNED;
|
||||
dins.mSType[1] = IT_INT16;
|
||||
dins.mSTemp[1] = sins.mTTemp;
|
||||
dins.mTType = IT_SIGNED;
|
||||
dins.mTType = IT_INT16;
|
||||
dins.mTTemp = proc->AddTemporary(dins.mTType);
|
||||
block->Append(dins);
|
||||
|
||||
|
@ -933,34 +1010,22 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
if (!vr.mType->IsNumericType())
|
||||
mErrors->Error(exp->mLocation, "Right hand operand type is not numeric");
|
||||
|
||||
if (vl.mType->IsIntegerType() && vr.mType->mType == DT_TYPE_FLOAT)
|
||||
{
|
||||
InterInstruction cins;
|
||||
cins.mCode = IC_CONVERSION_OPERATOR;
|
||||
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);
|
||||
}
|
||||
Declaration* dtype;
|
||||
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;
|
||||
|
||||
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;
|
||||
switch (exp->mToken)
|
||||
|
@ -1028,7 +1093,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
bool ftype = vl.mType->mType == DT_TYPE_FLOAT;
|
||||
|
||||
cins.mCode = IC_CONSTANT;
|
||||
cins.mTType = ftype ? IT_FLOAT : IT_SIGNED;
|
||||
cins.mTType = ftype ? IT_FLOAT : IT_INT16;
|
||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||
if (vdl.mType->mType == DT_TYPE_POINTER)
|
||||
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;
|
||||
|
||||
cins.mCode = IC_CONSTANT;
|
||||
cins.mTType = ftype ? IT_FLOAT : IT_SIGNED;
|
||||
cins.mTType = ftype ? IT_FLOAT : IT_INT16;
|
||||
cins.mTTemp = proc->AddTemporary(cins.mTType);
|
||||
if (vdl.mType->mType == DT_TYPE_POINTER)
|
||||
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;
|
||||
|
||||
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");
|
||||
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)
|
||||
{
|
||||
InterInstruction cins;
|
||||
cins.mCode = IC_CONVERSION_OPERATOR;
|
||||
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);
|
||||
}
|
||||
vl = CoerceType(proc, block, vl, dtype);
|
||||
vr = CoerceType(proc, block, vr, dtype);
|
||||
|
||||
bool signedCompare = dtype->mFlags & DTF_SIGNED;
|
||||
|
||||
ins.mCode = IC_RELATIONAL_OPERATOR;
|
||||
switch (exp->mToken)
|
||||
|
@ -1737,74 +1796,57 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
vr = Dereference(proc, fblock, vr);
|
||||
|
||||
int ttemp;
|
||||
InterType ttype;
|
||||
InterType ttype, stypel, styper;
|
||||
|
||||
stypel = InterTypeOf(vl.mType);
|
||||
styper = InterTypeOf(vr.mType);
|
||||
|
||||
Declaration* dtype;
|
||||
if (vl.mType->mType == DT_TYPE_FLOAT || vr.mType->mType == DT_TYPE_FLOAT)
|
||||
{
|
||||
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 (stypel == IT_POINTER || styper == IT_POINTER)
|
||||
{
|
||||
if (!vl.mType->IsSame(vr.mType))
|
||||
mErrors->Error(exp->mLocation, "Incompatible conditional types");
|
||||
|
||||
ttype = IT_POINTER;
|
||||
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
|
||||
{
|
||||
mErrors->Error(exp->mLocation, "Incompatible conditional types");
|
||||
ttype = IT_SIGNED;
|
||||
dtype = TheVoidTypeDeclaration;
|
||||
ttype = styper;
|
||||
dtype = vr.mType;
|
||||
|
||||
vl = CoerceType(proc, tblock, vl, dtype);
|
||||
}
|
||||
|
||||
ttemp = proc->AddTemporary(ttype);
|
||||
|
||||
if (ttype == IT_FLOAT && vr.mType->IsIntegerType())
|
||||
{
|
||||
InterInstruction ins;
|
||||
ins.mCode = IC_CONVERSION_OPERATOR;
|
||||
ins.mOperator = IA_INT2FLOAT;
|
||||
ins.mSType[0] = InterTypeOf(vr.mType);
|
||||
ins.mSTemp[0] = vr.mTemp;
|
||||
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);
|
||||
}
|
||||
InterInstruction rins;
|
||||
rins.mCode = IC_LOAD_TEMPORARY;
|
||||
rins.mSType[0] = InterTypeOf(vr.mType);
|
||||
rins.mSTemp[0] = vr.mTemp;
|
||||
rins.mTType = ttype;
|
||||
rins.mTTemp = ttemp;
|
||||
fblock->Append(rins);
|
||||
|
||||
if (ttype == IT_FLOAT && vl.mType->IsIntegerType())
|
||||
{
|
||||
InterInstruction ins;
|
||||
ins.mCode = IC_CONVERSION_OPERATOR;
|
||||
ins.mOperator = IA_INT2FLOAT;
|
||||
ins.mSType[0] = InterTypeOf(vl.mType);
|
||||
ins.mSTemp[0] = vl.mTemp;
|
||||
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);
|
||||
}
|
||||
InterInstruction lins;
|
||||
lins.mCode = IC_LOAD_TEMPORARY;
|
||||
lins.mSType[0] = InterTypeOf(vl.mType);
|
||||
lins.mSTemp[0] = vl.mTemp;
|
||||
lins.mTType = ttype;
|
||||
lins.mTTemp = ttemp;
|
||||
tblock->Append(lins);
|
||||
|
||||
tblock->Append(jins);
|
||||
tblock->Close(eblock, nullptr);
|
||||
|
|
|
@ -331,6 +331,8 @@ bool NativeCodeInstruction::IsUsedResultInstructions(NumberSet& requiredTemps)
|
|||
case ASMIT_CPY:
|
||||
case ASMIT_ASL:
|
||||
case ASMIT_LSR:
|
||||
case ASMIT_INC:
|
||||
case ASMIT_DEC:
|
||||
case ASMIT_ORA:
|
||||
case ASMIT_EOR:
|
||||
case ASMIT_AND:
|
||||
|
@ -497,12 +499,19 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
|||
case ASMIT_LSR:
|
||||
if (mMode == ASMIM_IMPLIED)
|
||||
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;
|
||||
|
||||
case ASMIT_LDA:
|
||||
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;
|
||||
changed = true;
|
||||
|
@ -513,22 +522,93 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
|||
data.mRegs[CPU_REG_A].mZeroPage = false;
|
||||
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;
|
||||
|
||||
case ASMIT_ADC:
|
||||
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_EOR:
|
||||
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;
|
||||
case ASMIT_LDX:
|
||||
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;
|
||||
changed = true;
|
||||
|
@ -538,19 +618,27 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
|||
data.mRegs[CPU_REG_X].mImmediate = true;
|
||||
data.mRegs[CPU_REG_X].mZeroPage = false;
|
||||
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)
|
||||
data.mRegs[CPU_REG_X].Reset();
|
||||
else
|
||||
{
|
||||
if (mMode != ASMIM_ZERO_PAGE)
|
||||
data.mRegs[CPU_REG_X].Reset();
|
||||
data.mRegs[CPU_REG_Z].Reset();
|
||||
}
|
||||
break;
|
||||
case ASMIT_INX:
|
||||
case ASMIT_DEX:
|
||||
data.mRegs[CPU_REG_X].Reset();
|
||||
data.mRegs[CPU_REG_Z].Reset();
|
||||
break;
|
||||
case ASMIT_LDY:
|
||||
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;
|
||||
changed = true;
|
||||
|
@ -560,27 +648,63 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
|||
data.mRegs[CPU_REG_Y].mImmediate = true;
|
||||
data.mRegs[CPU_REG_Y].mZeroPage = false;
|
||||
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)
|
||||
data.mRegs[CPU_REG_Y].Reset();
|
||||
else
|
||||
{
|
||||
if (mMode != ASMIM_ZERO_PAGE)
|
||||
data.mRegs[CPU_REG_Y].Reset();
|
||||
data.mRegs[CPU_REG_Z].Reset();
|
||||
}
|
||||
break;
|
||||
case ASMIT_INY:
|
||||
case ASMIT_DEY:
|
||||
data.mRegs[CPU_REG_Y].Reset();
|
||||
data.mRegs[CPU_REG_Z].Reset();
|
||||
break;
|
||||
|
||||
case ASMIT_TXA:
|
||||
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;
|
||||
case ASMIT_TYA:
|
||||
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;
|
||||
case ASMIT_TAX:
|
||||
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;
|
||||
case ASMIT_TAY:
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -589,7 +713,7 @@ bool NativeCodeInstruction::ValueForwarding(NativeRegisterDataSet& data)
|
|||
switch (mType)
|
||||
{
|
||||
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;
|
||||
changed = true;
|
||||
|
@ -2059,9 +2183,6 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|||
{
|
||||
if (ins.mOperandSize == 1)
|
||||
{
|
||||
if (ins.mTType == IT_SIGNED)
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDX, ASMIM_IMMEDIATE, 0));
|
||||
|
||||
if (ins.mMemory == IM_GLOBAL)
|
||||
{
|
||||
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(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
||||
if (ins.mTType == IT_SIGNED)
|
||||
{
|
||||
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));
|
||||
}
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
if (ainsh) mIns.Push(*ainsh);
|
||||
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.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_LDA, ASMIM_INDIRECT_Y, BC_REG_TMP + proc->mTempOffset[ins.mSTemp[0]]));
|
||||
if (ainsl)
|
||||
|
@ -2187,16 +2297,7 @@ void NativeCodeBasicBlock::LoadValueToReg(InterCodeProcedure* proc, const InterI
|
|||
mIns.Push(*ainsl);
|
||||
}
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_STA, ASMIM_ZERO_PAGE, reg));
|
||||
if (ins.mTType == IT_SIGNED)
|
||||
{
|
||||
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));
|
||||
}
|
||||
mIns.Push(NativeCodeInstruction(ASMIT_LDA, ASMIM_IMMEDIATE, 0));
|
||||
if (ainsh) mIns.Push(*ainsh);
|
||||
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_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 3));
|
||||
|
||||
if (ins.mTType == IT_SIGNED)
|
||||
mIns.Push(NativeCodeInstruction("ftoi"));
|
||||
else
|
||||
mIns.Push(NativeCodeInstruction("ftou"));
|
||||
mIns.Push(NativeCodeInstruction("ftoi"));
|
||||
|
||||
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));
|
||||
|
@ -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_STA, ASMIM_ZERO_PAGE, BC_REG_ACCU + 1));
|
||||
|
||||
if (ins.mSType[0] == IT_SIGNED)
|
||||
mIns.Push(NativeCodeInstruction("ffromi"));
|
||||
else
|
||||
mIns.Push(NativeCodeInstruction("fromu"));
|
||||
mIns.Push(NativeCodeInstruction("ffromi"));
|
||||
|
||||
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));
|
||||
|
@ -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));
|
||||
|
||||
} 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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int j = at;
|
||||
|
@ -3734,6 +3888,73 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(void)
|
|||
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
|
||||
|
||||
for (int i = 2; i + 2 < mIns.Size(); i++)
|
||||
|
@ -4292,10 +4513,17 @@ void NativeCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedu
|
|||
if (entryBlock->PeepHoleOptimizer())
|
||||
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);
|
||||
|
||||
ResetVisited();
|
||||
entryBlock->PeepHoleOptimizer();
|
||||
#endif
|
||||
|
||||
entryBlock->Assemble();
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
GrowingArray<NativeCodeInstruction> mIns;
|
||||
GrowingArray<ByteCodeRelocation> mRelocations;
|
||||
|
||||
int mOffset, mSize;
|
||||
int mOffset, mSize, mNumEntries;
|
||||
bool mPlaced, mCopied, mKnownShortBranch, mBypassed, mAssembled, mNoFrame, mVisited;
|
||||
|
||||
int PutBranch(NativeCodeProcedure* proc, AsmInsType code, int offset);
|
||||
|
@ -114,6 +114,9 @@ public:
|
|||
bool BuildGlobalRequiredRegSet(NumberSet& fromRequiredTemps);
|
||||
bool RemoveUnusedResultInstructions(void);
|
||||
|
||||
void CountEntries(void);
|
||||
bool MergeBasicBlocks(void);
|
||||
|
||||
bool MoveLoadStoreUp(int at);
|
||||
};
|
||||
|
||||
|
|
|
@ -131,6 +131,29 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
|
|||
|
||||
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:
|
||||
mScanner->NextToken();
|
||||
return ParseBaseTypeDeclaration(flags | DTF_CONST);
|
||||
|
@ -157,14 +180,14 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint32 flags)
|
|||
case TK_CHAR:
|
||||
dec = new Declaration(mScanner->mLocation, DT_TYPE_INTEGER);
|
||||
dec->mSize = 1;
|
||||
dec->mFlags = flags | DTF_DEFINED | DTF_SIGNED;
|
||||
dec->mFlags = flags | DTF_DEFINED;
|
||||
mScanner->NextToken();
|
||||
break;
|
||||
|
||||
case TK_BOOL:
|
||||
dec = new Declaration(mScanner->mLocation, DT_TYPE_BOOL);
|
||||
dec->mSize = 1;
|
||||
dec->mFlags = flags | DTF_DEFINED | DTF_SIGNED;
|
||||
dec->mFlags = flags | DTF_DEFINED;
|
||||
mScanner->NextToken();
|
||||
break;
|
||||
|
||||
|
@ -840,6 +863,7 @@ Expression* Parser::ParseSimpleExpression(void)
|
|||
case TK_BOOL:
|
||||
case TK_VOID:
|
||||
case TK_UNSIGNED:
|
||||
case TK_SIGNED:
|
||||
case TK_CONST:
|
||||
case TK_VOLATILE:
|
||||
case TK_STRUCT:
|
||||
|
@ -878,7 +902,7 @@ Expression* Parser::ParseSimpleExpression(void)
|
|||
dec->mVarIndex = -1;
|
||||
dec->mBase = new Declaration(mScanner->mLocation, DT_TYPE_ARRAY);
|
||||
dec->mBase->mSize = dec->mSize;
|
||||
dec->mBase->mBase = TheConstSignedCharTypeDeclaration;
|
||||
dec->mBase->mBase = TheConstCharTypeDeclaration;
|
||||
dec->mBase->mFlags |= DTF_DEFINED;
|
||||
uint8* d = new uint8[dec->mSize];
|
||||
dec->mData = d;
|
||||
|
@ -1206,6 +1230,12 @@ Expression* Parser::ParseMulExpression(void)
|
|||
nexp->mLeft = exp;
|
||||
mScanner->NextToken();
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -1223,6 +1253,15 @@ Expression* Parser::ParseAddExpression(void)
|
|||
nexp->mLeft = exp;
|
||||
mScanner->NextToken();
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -1240,6 +1279,8 @@ Expression* Parser::ParseShiftExpression(void)
|
|||
nexp->mLeft = exp;
|
||||
mScanner->NextToken();
|
||||
nexp->mRight = ParseAddExpression();
|
||||
nexp->mDecType = exp->mDecType;
|
||||
|
||||
exp = nexp->ConstantFold();
|
||||
}
|
||||
|
||||
|
@ -1257,6 +1298,8 @@ Expression* Parser::ParseRelationalExpression(void)
|
|||
nexp->mLeft = exp;
|
||||
mScanner->NextToken();
|
||||
nexp->mRight = ParseShiftExpression();
|
||||
nexp->mDecType = TheBoolTypeDeclaration;
|
||||
|
||||
exp = nexp->ConstantFold();
|
||||
}
|
||||
|
||||
|
@ -1274,6 +1317,8 @@ Expression* Parser::ParseBinaryAndExpression(void)
|
|||
nexp->mLeft = exp;
|
||||
mScanner->NextToken();
|
||||
nexp->mRight = ParseRelationalExpression();
|
||||
nexp->mDecType = exp->mDecType;
|
||||
|
||||
exp = nexp->ConstantFold();
|
||||
}
|
||||
|
||||
|
@ -1291,6 +1336,7 @@ Expression* Parser::ParseBinaryXorExpression(void)
|
|||
nexp->mLeft = exp;
|
||||
mScanner->NextToken();
|
||||
nexp->mRight = ParseBinaryAndExpression();
|
||||
nexp->mDecType = exp->mDecType;
|
||||
exp = nexp->ConstantFold();
|
||||
}
|
||||
|
||||
|
@ -1308,6 +1354,7 @@ Expression* Parser::ParseBinaryOrExpression(void)
|
|||
nexp->mLeft = exp;
|
||||
mScanner->NextToken();
|
||||
nexp->mRight = ParseBinaryXorExpression();
|
||||
nexp->mDecType = exp->mDecType;
|
||||
exp = nexp->ConstantFold();
|
||||
}
|
||||
|
||||
|
@ -1325,6 +1372,7 @@ Expression* Parser::ParseLogicAndExpression(void)
|
|||
nexp->mLeft = exp;
|
||||
mScanner->NextToken();
|
||||
nexp->mRight = ParseBinaryOrExpression();
|
||||
nexp->mDecType = TheBoolTypeDeclaration;
|
||||
exp = nexp->ConstantFold();
|
||||
}
|
||||
|
||||
|
@ -1342,6 +1390,7 @@ Expression* Parser::ParseLogicOrExpression(void)
|
|||
nexp->mLeft = exp;
|
||||
mScanner->NextToken();
|
||||
nexp->mRight = ParseLogicAndExpression();
|
||||
nexp->mDecType = TheBoolTypeDeclaration;
|
||||
exp = nexp->ConstantFold();
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ const char* TokenNames[] = {
|
|||
"'char'",
|
||||
"'float'",
|
||||
"'unsigned'",
|
||||
"'signed'",
|
||||
"'switch'",
|
||||
"'case'",
|
||||
"'default'",
|
||||
|
@ -922,6 +923,8 @@ void Scanner::NextRawToken(void)
|
|||
mToken = TK_LONG;
|
||||
else if (!strcmp(tkident, "unsigned"))
|
||||
mToken = TK_UNSIGNED;
|
||||
else if (!strcmp(tkident, "signed"))
|
||||
mToken = TK_SIGNED;
|
||||
else if (!strcmp(tkident, "const"))
|
||||
mToken = TK_CONST;
|
||||
else if (!strcmp(tkident, "volatile"))
|
||||
|
|
|
@ -21,6 +21,7 @@ enum Token
|
|||
TK_CHAR,
|
||||
TK_FLOAT,
|
||||
TK_UNSIGNED,
|
||||
TK_SIGNED,
|
||||
TK_SWITCH,
|
||||
TK_CASE,
|
||||
TK_DEFAULT,
|
||||
|
|
Loading…
Reference in New Issue