Optimize size of generated byte code

This commit is contained in:
drmortalwombat 2022-01-09 19:00:02 +01:00
parent 640007546f
commit 68f8628409
7 changed files with 301 additions and 133 deletions

View File

@ -2049,6 +2049,7 @@ inp_binop_cmpi_u8:
lda (ip), y
cmp accu
cmp_check:
bne cmpne
cmp_eq:
lda #0
@ -2084,6 +2085,19 @@ inp_binop_cmpi_s8:
#pragma bytecode(BC_BINOP_CMPUR_8, cmp8.inp_binop_cmpr_u8)
#pragma bytecode(BC_BINOP_CMPUI_8, cmp8.inp_binop_cmpi_u8)
__asm loopu8
{
lda (ip),y
tax
inc $00, x
iny
lda (ip), y
cmp $00, x
jmp cmp8.cmp_check
}
#pragma bytecode(BC_LOOP_U8, loopu8)
__asm bra
{
inp_jumps:
@ -2142,58 +2156,6 @@ inp_branchs_le:
#pragma bytecode(BC_BRANCHS_LT, bra.inp_branchs_lt)
#pragma bytecode(BC_BRANCHS_LE, bra.inp_branchs_le)
__asm set
{
set_false:
lda #0
byt $2c
set_true:
lda #1
sta accu
lda #0
sta accu + 1
jmp startup.exec
inp_set_eq:
lda accu
ora accu + 1
beq set_true
bne set_false
inp_set_ne:
lda accu
ora accu + 1
bne set_true
beq set_false
inp_set_gt:
lda accu + 1
bmi set_false
ora accu
bne set_true
beq set_false
inp_set_ge:
lda accu + 1
bpl set_true
bmi set_false
inp_set_lt:
lda accu + 1
bmi set_true
bpl set_false
inp_set_le:
lda accu + 1
bmi set_true
ora accu
beq set_true
bne set_false
}
#pragma bytecode(BC_SET_EQ, set.inp_set_eq)
#pragma bytecode(BC_SET_NE, set.inp_set_ne)
#pragma bytecode(BC_SET_GT, set.inp_set_gt)
#pragma bytecode(BC_SET_GE, set.inp_set_ge)
#pragma bytecode(BC_SET_LT, set.inp_set_lt)
#pragma bytecode(BC_SET_LE, set.inp_set_le)
__asm braf
{
inp_jumpf:

View File

@ -141,12 +141,12 @@ enum ByteCode
BC_BRANCHF_LT,
BC_BRANCHF_LE,
BC_SET_EQ,
BC_SET_NE,
BC_SET_GT,
BC_SET_GE,
BC_SET_LT,
BC_SET_LE,
BC_LOOP_U8,
BC_UNUSED_2,
BC_UNUSED_3,
BC_UNUSED_4,
BC_UNUSED_5,
BC_UNUSED_6,
BC_JSR,

View File

@ -141,12 +141,12 @@ static const char* ByteCodeNames[] = {
"BRANCHF_LT",
"BRANCHF_LE",
"SET_EQ",
"SET_NE",
"SET_GT",
"SET_GE",
"SET_LT",
"SET_LE",
"LOOP_U8",
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
"JSR", //114
@ -534,13 +534,14 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used)
case BC_BINOP_ANDI_8:
case BC_BINOP_ORI_8:
case BC_BINOP_SHLI_16:
case BC_OP_NEGATE_16:
case BC_OP_INVERT_16:
break;
case BC_BINOP_CMPUR_16:
case BC_BINOP_CMPSR_16:
case BC_BINOP_CMPUI_16:
case BC_BINOP_CMPSI_16:
case BC_OP_NEGATE_16:
case BC_OP_INVERT_16:
break;
case BC_BINOP_DIVR_U16:
case BC_BINOP_MODR_U16:
@ -553,6 +554,10 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used)
used |= 0x0000ffff;
break;
case BC_LOOP_U8:
used = 0;
break;
case BC_BINOP_ADDA_16:
used |= 0x0000ffff;
break;
@ -623,12 +628,6 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used)
case BC_BRANCHF_GE:
case BC_BRANCHF_LT:
case BC_BRANCHF_LE:
case BC_SET_EQ:
case BC_SET_NE:
case BC_SET_GT:
case BC_SET_GE:
case BC_SET_LT:
case BC_SET_LE:
case BC_CONV_I16_I32:
case BC_CONV_U16_U32:
used = 0x0000ffff;
@ -741,6 +740,9 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const
if (mCode == BC_BINOP_ADDA_16)
return true;
if (mCode == BC_LOOP_U8)
return true;
}
if (reg == BC_REG_ACCU)
@ -762,8 +764,6 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const
return true;
if (mCode >= BC_BINOP_SHLI_16 && mCode <= BC_BINOP_SHRI_I16)
return true;
if (mCode >= BC_SET_EQ && mCode <= BC_SET_LE)
return true;
if (mCode >= BC_CONV_I16_I32 && mCode <= BC_BINOP_CMP_S32)
return true;
if (mCode == BC_LEA_ACCU_INDEX)
@ -810,6 +810,8 @@ bool ByteCodeInstruction::ChangesRegister(uint32 reg) const
return true;
if (mCode == BC_BINOP_ADDA_16)
return true;
if (mCode == BC_LOOP_U8)
return true;
}
if (reg >= BC_REG_WORK && reg < BC_REG_FPARAMS_END || reg >= BC_REG_TMP && reg < BC_REG_TMP_SAVED)
@ -836,12 +838,12 @@ bool ByteCodeInstruction::ChangesRegister(uint32 reg) const
return true;
if (mCode >= BC_BINOP_SHLI_16 && mCode <= BC_BINOP_SHRI_I16)
return true;
if (mCode >= BC_SET_EQ && mCode <= BC_SET_LE)
return true;
if (mCode == BC_JSR || mCode == BC_CALL_ADDR || mCode == BC_CALL_ABS)
return true;
if (mCode >= BC_CONV_I16_I32 && mCode <= BC_BINOP_CMP_S32)
return true;
if (mCode == BC_LOOP_U8)
return true;
}
if (reg == BC_REG_ADDR)
@ -1079,6 +1081,12 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
block->PutByte(uint8(mValue));
break;
case BC_LOOP_U8:
block->PutCode(generator, mCode);
block->PutByte(mRegister);
block->PutByte(uint8(mValue));
break;
case BC_OP_NEGATE_16:
case BC_OP_INVERT_16:
block->PutCode(generator, mCode);
@ -1129,15 +1137,6 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
assert(false);
break;
case BC_SET_EQ:
case BC_SET_NE:
case BC_SET_GT:
case BC_SET_GE:
case BC_SET_LT:
case BC_SET_LE:
block->PutCode(generator, mCode);
break;
case BC_ENTER:
case BC_RETURN:
assert(false);
@ -3004,7 +3003,7 @@ void ByteCodeBasicBlock::CallNative(InterCodeProcedure* proc, const InterInstruc
}
}
ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const InterInstruction * ins)
ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const InterInstruction * ins, bool optzero)
{
ByteCode code;
bool csigned = false;
@ -3126,7 +3125,7 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
}
else
{
if (ins->mSrc[1].mIntConst == 0)
if (optzero && ins->mSrc[1].mIntConst == 0)
{
switch (ins->mOperator)
{
@ -3158,7 +3157,7 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
mIns.Push(lins);
if (csigned)
{
if (ins->mSrc[0].mIntConst == 0)
if (optzero && ins->mSrc[0].mIntConst == 0)
{
ByteCodeInstruction cins(BC_CONV_I8_I16);
cins.mRegister = BC_REG_ACCU;
@ -3189,7 +3188,7 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
}
else
{
if (ins->mSrc[0].mIntConst == 0)
if (optzero && ins->mSrc[0].mIntConst == 0)
{
switch (ins->mOperator)
{
@ -3265,7 +3264,7 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
mIns.Push(lins);
if (csigned)
{
if (ins->mSrc[0].mIntConst == 0)
if (optzero && ins->mSrc[0].mIntConst == 0)
{
switch (ins->mOperator)
{
@ -3283,6 +3282,12 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
return BC_BRANCHS_LT;
}
}
else if (ins->mSrc[1].IsUByte())
{
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
cins.mValue = ins->mSrc[0].mIntConst;
mIns.Push(cins);
}
else
{
ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
@ -3292,7 +3297,7 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
}
else
{
if (ins->mSrc[0].mIntConst == 0)
if (optzero && ins->mSrc[0].mIntConst == 0)
{
switch (ins->mOperator)
{
@ -3308,6 +3313,12 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
return BC_NOP;
}
}
else if (ins->mSrc[1].IsUByte())
{
ByteCodeInstruction cins(BC_BINOP_CMPUI_8);
cins.mValue = ins->mSrc[0].mIntConst;
mIns.Push(cins);
}
else
{
ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
@ -4164,14 +4175,14 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p
case IC_RELATIONAL_OPERATOR:
if (i + 1 < sblock->mInstructions.Size() && sblock->mInstructions[i + 1]->mCode == IC_BRANCH && sblock->mInstructions[i + 1]->mSrc[0].mFinal)
{
ByteCode code = RelationalOperator(iproc, ins);
ByteCode code = RelationalOperator(iproc, ins, true);
this->Close(proc->CompileBlock(iproc, sblock->mTrueJump), proc->CompileBlock(iproc, sblock->mFalseJump), code);
i++;
return;
}
else
{
ByteCode code = RelationalOperator(iproc, ins);
ByteCode code = RelationalOperator(iproc, ins, false);
if (code == BC_JUMPS)
{
IntConstToAccu(1);
@ -4182,8 +4193,57 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p
}
else
{
ByteCodeInstruction bins(ByteCode(code - BC_BRANCHS_EQ + BC_SET_EQ));
mIns.Push(bins);
switch (code)
{
case BC_BRANCHS_EQ:
{
ByteCodeInstruction iins(BC_OP_INVERT_16);
mIns.Push(iins);
ByteCodeInstruction bins(BC_BINOP_ANDI_16);
bins.mRegister = BC_REG_ACCU;
bins.mValue = 1;
mIns.Push(bins);
} break;
case BC_BRANCHS_NE:
{
ByteCodeInstruction bins(BC_BINOP_ANDI_16);
bins.mRegister = BC_REG_ACCU;
bins.mValue = 1;
mIns.Push(bins);
} break;
case BC_BRANCHS_GT:
{
ByteCodeInstruction ains(BC_BINOP_ADDI_16);
ains.mRegister = BC_REG_ACCU;
ains.mValue = 1;
mIns.Push(ains);
ByteCodeInstruction sins(BC_BINOP_SHRI_U16);
sins.mValue = 1;
mIns.Push(sins);
} break;
case BC_BRANCHS_GE:
{
ByteCodeInstruction sins(BC_BINOP_CMPUI_8);
sins.mValue = 0xff;
mIns.Push(sins);
} break;
case BC_BRANCHS_LT:
{
ByteCodeInstruction sins(BC_BINOP_SHRI_U16);
sins.mValue = 1;
mIns.Push(sins);
ByteCodeInstruction bins(BC_BINOP_ANDI_16);
bins.mRegister = BC_REG_ACCU;
bins.mValue = 1;
mIns.Push(bins);
} break;
case BC_BRANCHS_LE:
{
ByteCodeInstruction sins(BC_BINOP_CMPSI_8);
sins.mValue = 1;
mIns.Push(sins);
} break;
}
}
ByteCodeInstruction sins(StoreTypedTmpCodes[ins->mDst.mType]);
sins.mRegister = BC_REG_TMP + iproc->mTempOffset[ins->mDst.mTemp];
@ -4755,13 +4815,6 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
mIns[i + 2].mCode = BC_NOP;
progress = true;
}
else if (mIns[i + 0].mCode >= BC_SET_EQ && mIns[i + 0].mCode <= BC_SET_LE &&
mIns[i + 1].mCode == BC_STORE_REG_8 &&
mIns[i + 2].mCode == BC_LOAD_REG_8 && mIns[i + 1].mRegister == mIns[i + 2].mRegister)
{
mIns[i + 2].mCode = BC_NOP;
progress = true;
}
else if (mIns[i + 0].IsLocalStore() && mIns[i + 2].IsSame(mIns[i + 0]) && !mIns[i + 1].IsLocalAccess() && mIns[i + 1].mCode != BC_JSR)
{
mIns[i + 0].mCode = BC_NOP;
@ -4983,6 +5036,32 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
mIns[i + 2].mCode = BC_NOP;
progress = true;
}
#if 1
else if (
mIns[i + 0].mCode == BC_LOAD_REG_8 &&
mIns[i + 1].mCode == BC_LEA_ABS &&
mIns[i + 2].mCode == BC_LEA_ACCU_INDEX && mIns[i + 1].mRegister == mIns[i + 2].mRegister && mIns[i + 2].mRegisterFinal && !(mIns[i + 2].mLive & LIVE_ACCU))
{
mIns[i + 0].mCode = BC_NOP;
mIns[i + 1].mCode = BC_LEA_ABS_INDEX_U8;
mIns[i + 2].mCode = BC_NOP;
mIns[i + 1].mRegister = mIns[i + 0].mRegister;
progress = true;
}
#endif
else if (
mIns[i + 0].mCode == BC_BINOP_ADDI_8 && mIns[i + 0].mValue == 1 &&
mIns[i + 1].mCode == BC_LOAD_REG_8 && mIns[i + 1].mRegister == mIns[i + 0].mRegister &&
mIns[i + 2].mCode == BC_BINOP_CMPUI_8)
{
mIns[i + 2].mCode = BC_LOOP_U8;
mIns[i + 2].mRegister = mIns[i + 0].mRegister;
mIns[i + 0].mCode = BC_NOP;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
#if 1
else if (
i + 3 == mIns.Size() && mFalseJump &&
@ -5294,6 +5373,16 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
#endif
#if 1
else if (
mIns[i + 0].mCode == BC_BINOP_ADDA_16 &&
mIns[i + 1].mCode == BC_ADDR_REG && mIns[i + 1].mRegister == mIns[i + 0].mRegister && mIns[i + 1].mRegisterFinal)
{
mIns[i + 0].mCode = BC_NOP;
mIns[i + 1].mCode = BC_LEA_ACCU_INDEX;
progress = true;
}
#endif
else if (
mIns[i + 0].mCode == BC_LOAD_LOCAL_8 &&
@ -5349,7 +5438,51 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
progress = true;
}
#endif
else if (
(mIns[i + 0].mCode == BC_LOAD_ADDR_U8 || mIns[i + 0].mCode == BC_LOAD_ABS_U8 || mIns[i + 0].mCode == BC_LOAD_LOCAL_U8) &&
mIns[i + 1].mCode == BC_BINOP_ANDI_16 && mIns[i + 0].mRegister == mIns[i + 1].mRegister)
{
// upper byte is already zero
mIns[i + 1].mCode = BC_BINOP_ANDI_8;
progress = true;
}
else if (
mIns[i + 0].mCode == BC_BINOP_ORI_16 &&
mIns[i + 1].mCode == BC_STORE_ADDR_8 && mIns[i + 0].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
{
mIns[i + 0].mCode = BC_BINOP_ORI_8;
progress = true;
}
else if (
mIns[i + 0].mCode == BC_BINOP_ANDI_16 &&
mIns[i + 1].mCode == BC_STORE_ADDR_8 && mIns[i + 0].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
{
mIns[i + 0].mCode = BC_BINOP_ANDI_8;
progress = true;
}
else if (
mIns[i + 0].mCode == BC_LEA_ABS &&
mIns[i + 1].mCode == BC_LEA_ACCU_INDEX && mIns[i + 0].mRegister == mIns[i + 1].mRegister && mIns[i + 1].mRegisterFinal)
{
mIns[i + 0].mCode = BC_LEA_ABS_INDEX;
mIns[i + 0].mRegister = BC_REG_ACCU;
mIns[i + 1].mCode = BC_NOP;
progress = true;
}
#if 1
else if (
mIns[i + 0].mCode == BC_LEA_ABS && mIns[i + 0].mRegister == BC_REG_ACCU &&
mIns[i + 1].mCode == BC_LEA_ACCU_INDEX && !(mIns[i + 1].mLive & LIVE_ACCU))
{
mIns[i + 0].mCode = BC_NOP;
mIns[i + 1].mCode = BC_LEA_ABS_INDEX;
mIns[i + 1].mLinkerObject = mIns[i + 0].mLinkerObject;
mIns[i + 1].mValue = mIns[i + 0].mValue;
mIns[i + 1].mRelocate = mIns[i + 0].mRelocate;
progress = true;
}
#endif
#if 1
else if (
i + 2 == mIns.Size() && mFalseJump &&
@ -5375,6 +5508,18 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
#endif
}
if (mIns[i].mCode == BC_BINOP_ORI_16 && !(mIns[i].mValue & 0xff00))
{
mIns[i].mCode = BC_BINOP_ORI_8;
progress = true;
}
if (mIns[i].mCode == BC_BINOP_ANDI_16 && (mIns[i].mValue & 0xff00) == 0xff00)
{
mIns[i].mCode = BC_BINOP_ANDI_8;
progress = true;
}
if (mIns[i].mCode == BC_BINOP_ANDI_16 && mIns[i].mRegister == BC_REG_ACCU && mIns[i].mValue == 0x00ff)
{
mIns[i].mCode = BC_LOAD_REG_8;

View File

@ -142,12 +142,12 @@ enum ByteCode
BC_BRANCHF_LT,
BC_BRANCHF_LE,
BC_SET_EQ,
BC_SET_NE,
BC_SET_GT,
BC_SET_GE,
BC_SET_LT,
BC_SET_LE,
BC_LOOP_U8,
BC_UNUSED_2,
BC_UNUSED_3,
BC_UNUSED_4,
BC_UNUSED_5,
BC_UNUSED_6,
BC_JSR,
@ -294,7 +294,7 @@ public:
void BinaryOperator(InterCodeProcedure* proc, const InterInstruction * ins);
void UnaryOperator(InterCodeProcedure* proc, const InterInstruction * ins);
void BinaryRROperator(InterCodeProcedure* proc, const InterInstruction * ins);
ByteCode RelationalOperator(InterCodeProcedure* proc, const InterInstruction * ins);
ByteCode RelationalOperator(InterCodeProcedure* proc, const InterInstruction * ins, bool optzero);
void BinaryIntOperator(InterCodeProcedure* proc, const InterInstruction * ins, ByteCode code);
void NumericConversion(InterCodeProcedure* proc, const InterInstruction * ins);

View File

@ -337,6 +337,11 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star
i += 2;
break;
case BC_LOOP_U8:
fprintf(file, "LOOPB\t%s, #$%02X", TempName(memory[start + i + 0], tbuffer, proc), memory[start + i + 1]);
i += 2;
break;
case BC_CONV_I8_I16:
fprintf(file, "SEXT8\t%s", TempName(memory[start + i + 0], tbuffer, proc));
i++;
@ -517,25 +522,6 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star
i += 2;
break;
case BC_SET_EQ:
fprintf(file, "SEQ");
break;
case BC_SET_NE:
fprintf(file, "SNE");
break;
case BC_SET_GT:
fprintf(file, "SGT");
break;
case BC_SET_GE:
fprintf(file, "SGE");
break;
case BC_SET_LT:
fprintf(file, "SLT");
break;
case BC_SET_LE:
fprintf(file, "SLE");
break;
case BC_ENTER:
fprintf(file, "ENTER\t%d, %d", memory[start + i + 2], uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 3;

View File

@ -3461,6 +3461,13 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
mInstructions[i + 0] = ins;
}
}
#if 1
if (mInstructions[i]->mCode == IC_CONVERSION_OPERATOR && mInstructions[i]->mOperator == IA_EXT8TO16S &&
mInstructions[i]->mSrc[0].IsUByte() && mInstructions[i]->mSrc[0].mRange.mMaxValue < 128)
{
mInstructions[i]->mOperator = IA_EXT8TO16U;
}
#endif
}
#endif
if (mTrueJump)
@ -3546,6 +3553,17 @@ static int64 SignedTypeMax(InterType type)
}
}
static int64 BuildLowerBitsMask(int64 v)
{
v |= v >> 32;
v |= v >> 16;
v |= v >> 8;
v |= v >> 4;
v |= v >> 2;
v |= v >> 1;
return v;
}
void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
{
mLocalValueRange = mEntryValueRange;
@ -3710,7 +3728,23 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
vr.mMinValue = ins->mSrc[1].mIntConst - maxv;
}
else
vr.mMaxState = vr.mMinState = IntegerValueRange::S_UNBOUND;
{
if (ins->mSrc[0].mRange.mMinState == IntegerValueRange::S_BOUND && ins->mSrc[1].mRange.mMaxState == IntegerValueRange::S_BOUND)
{
vr.mMaxState = IntegerValueRange::S_BOUND;
vr.mMaxValue = ins->mSrc[1].mRange.mMaxValue - ins->mSrc[0].mRange.mMinValue;
}
else
vr.mMaxState = IntegerValueRange::S_UNBOUND;
if (ins->mSrc[0].mRange.mMaxState == IntegerValueRange::S_BOUND && ins->mSrc[1].mRange.mMinState == IntegerValueRange::S_BOUND)
{
vr.mMinState = IntegerValueRange::S_BOUND;
vr.mMinValue = ins->mSrc[1].mRange.mMinValue - ins->mSrc[0].mRange.mMaxValue;
}
else
vr.mMinState = IntegerValueRange::S_UNBOUND;
}
break;
case IA_MUL:
@ -3887,6 +3921,40 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
vr.mMinValue = 0;
}
}
else if (ins->mSrc[0].IsUnsigned() && ins->mSrc[1].IsUnsigned())
{
vr.mMaxState = vr.mMinState = IntegerValueRange::S_BOUND;
int64 v0 = (ins->mSrc[0].mRange.mMaxValue & BuildLowerBitsMask(ins->mSrc[1].mRange.mMaxValue));
int64 v1 = (ins->mSrc[1].mRange.mMaxValue & BuildLowerBitsMask(ins->mSrc[0].mRange.mMaxValue));
vr.mMaxValue = (v0 > v1) ? v0 : v1;
vr.mMinValue = 0;
}
else
vr.mMaxState = vr.mMinState = IntegerValueRange::S_UNBOUND;
break;
case IA_OR:
case IA_XOR:
if (ins->mSrc[0].mTemp < 0)
{
vr = mLocalValueRange[ins->mSrc[1].mTemp];
int64 v = vr.mMaxValue;
v |= v >> 16;
v |= v >> 8;
v |= v >> 4;
v |= v >> 2;
v |= v >> 1;
if (vr.mMaxState == IntegerValueRange::S_BOUND && ins->mSrc[0].mIntConst >= 0)
vr.mMaxValue = BuildLowerBitsMask(vr.mMaxValue) | ins->mSrc[0].mIntConst;
}
else if (ins->mSrc[1].mTemp < 0)
{
vr = mLocalValueRange[ins->mSrc[0].mTemp];
if (vr.mMaxState == IntegerValueRange::S_BOUND && ins->mSrc[0].mIntConst >= 0)
vr.mMaxValue = BuildLowerBitsMask(vr.mMaxValue) | ins->mSrc[0].mIntConst;
}
else
vr.mMaxState = vr.mMinState = IntegerValueRange::S_UNBOUND;
break;
@ -6972,8 +7040,6 @@ void InterCodeProcedure::BuildTraces(bool expand)
for (int i = 0; i < mBlocks.Size(); i++)
mBlocks[i]->mNumEntries = 0;
mEntryBlock->CollectEntries();
DisassembleDebug("BuildTraces");
}
void InterCodeProcedure::BuildDataFlowSets(void)
@ -7417,6 +7483,11 @@ void InterCodeProcedure::Close(void)
ResetVisited();
mEntryBlock->OptimizeIntervalCompare();
ResetVisited();
for (int i = 0; i < mBlocks.Size(); i++)
mBlocks[i]->mNumEntries = 0;
mEntryBlock->CollectEntries();
DisassembleDebug("interval compare");
BuildDataFlowSets();

View File

@ -1056,7 +1056,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else
{
Declaration * otype = vll.mType;
if (exp->mToken != TK_ADD && exp->mToken != TK_SUB && otype->mSize < 2)
#if 1
if ((exp->mRight->mType != EX_CONSTANT || (exp->mToken != TK_ASSIGN_ADD && exp->mToken != TK_ASSIGN_SUB && exp->mToken != TK_ASSIGN_AND && exp->mToken != TK_ASSIGN_OR)) && otype->mSize < 2)
#else
if (otype->mSize < 2)
#endif
{
if ((vll.mType->mFlags | vr.mType->mFlags) & DTF_SIGNED)
otype = TheSignedIntTypeDeclaration;