Prepare byte level optimisations

This commit is contained in:
drmortalwombat 2021-09-14 16:34:48 +02:00
parent 9f8362255f
commit e2e20581a6
16 changed files with 762 additions and 379 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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,

View File

@ -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);
@ -1470,22 +1475,12 @@ void ByteCodeBasicBlock::LoadDirectValue(InterCodeProcedure* proc, const InterIn
mIns.Push(lins);
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);
}
}
else if (ins.mOperandSize == 2)
{
ByteCodeInstruction bins(BC_LOAD_ADDR_16);
@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -65,7 +65,7 @@ void Emulator::DumpCycles(void)
}
printf("Total Cycles %d\n", totalCycles);
// return;
return;
for (int i = 0; i < numTops; i++)
{

View File

@ -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)
{
ins.mCode = IC_CONSTANT;
ins.mFloatValue = (double)(tvalue[ins.mSTemp[0]]->mIntValue);
ins.mSTemp[0] = -1;
ConversionConstantFold(ins, tvalue[ins.mSTemp[0]]);
if (ins.mTType == IT_FLOAT)
{
i = 0;
while (i < mNum &&
(mInstructions[i]->mCode != IC_CONSTANT ||
@ -747,6 +771,11 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
}
}
else
{
InsertValue(ins);
}
}
else
{
i = 0;
while (i < mNum &&
@ -770,10 +799,6 @@ void ValueSet::UpdateValue(InterInstruction& ins, const GrowingInstructionPtrArr
InsertValue(ins);
}
}
}
else if (ins.mOperator == IA_FLOAT2INT)
{
}
break;
case IC_UNARY_OPERATOR:
@ -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,9 +1828,6 @@ 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.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,9 +1893,6 @@ 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.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;
}

View File

@ -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;

View File

@ -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->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");
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 = short(dec->mInteger);
}
else
{
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 (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);

View File

@ -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)
else
{
if (mMode != ASMIM_ZERO_PAGE)
data.mRegs[CPU_REG_A].Reset();
data.mRegs[CPU_REG_Z].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:
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)
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)
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));
}
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));
}
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(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(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;
} while (changed);
ResetVisited();
for (int i = 0; i < mBlocks.Size(); i++)
mBlocks[i]->mNumEntries = 0;
entryBlock->CountEntries();
ResetVisited();
entryBlock->PeepHoleOptimizer();
if (entryBlock->MergeBasicBlocks())
changed = true;
} while (changed);
#endif
entryBlock->Assemble();

View File

@ -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);
};

View File

@ -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();
}

View File

@ -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"))

View File

@ -21,6 +21,7 @@ enum Token
TK_CHAR,
TK_FLOAT,
TK_UNSIGNED,
TK_SIGNED,
TK_SWITCH,
TK_CASE,
TK_DEFAULT,