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 lda (ip), y
cmp accu cmp accu
cmp_check:
bne cmpne bne cmpne
cmp_eq: cmp_eq:
lda #0 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_CMPUR_8, cmp8.inp_binop_cmpr_u8)
#pragma bytecode(BC_BINOP_CMPUI_8, cmp8.inp_binop_cmpi_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 __asm bra
{ {
inp_jumps: inp_jumps:
@ -2142,58 +2156,6 @@ inp_branchs_le:
#pragma bytecode(BC_BRANCHS_LT, bra.inp_branchs_lt) #pragma bytecode(BC_BRANCHS_LT, bra.inp_branchs_lt)
#pragma bytecode(BC_BRANCHS_LE, bra.inp_branchs_le) #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 __asm braf
{ {
inp_jumpf: inp_jumpf:

View File

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

View File

@ -141,12 +141,12 @@ static const char* ByteCodeNames[] = {
"BRANCHF_LT", "BRANCHF_LT",
"BRANCHF_LE", "BRANCHF_LE",
"SET_EQ", "LOOP_U8",
"SET_NE", nullptr,
"SET_GT", nullptr,
"SET_GE", nullptr,
"SET_LT", nullptr,
"SET_LE", nullptr,
"JSR", //114 "JSR", //114
@ -534,13 +534,14 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used)
case BC_BINOP_ANDI_8: case BC_BINOP_ANDI_8:
case BC_BINOP_ORI_8: case BC_BINOP_ORI_8:
case BC_BINOP_SHLI_16: case BC_BINOP_SHLI_16:
case BC_OP_NEGATE_16:
case BC_OP_INVERT_16:
break;
case BC_BINOP_CMPUR_16: case BC_BINOP_CMPUR_16:
case BC_BINOP_CMPSR_16: case BC_BINOP_CMPSR_16:
case BC_BINOP_CMPUI_16: case BC_BINOP_CMPUI_16:
case BC_BINOP_CMPSI_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_DIVR_U16:
case BC_BINOP_MODR_U16: case BC_BINOP_MODR_U16:
@ -553,6 +554,10 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used)
used |= 0x0000ffff; used |= 0x0000ffff;
break; break;
case BC_LOOP_U8:
used = 0;
break;
case BC_BINOP_ADDA_16: case BC_BINOP_ADDA_16:
used |= 0x0000ffff; used |= 0x0000ffff;
break; break;
@ -623,12 +628,6 @@ bool ByteCodeInstruction::CheckAccuSize(uint32 & used)
case BC_BRANCHF_GE: case BC_BRANCHF_GE:
case BC_BRANCHF_LT: case BC_BRANCHF_LT:
case BC_BRANCHF_LE: 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_I16_I32:
case BC_CONV_U16_U32: case BC_CONV_U16_U32:
used = 0x0000ffff; used = 0x0000ffff;
@ -741,6 +740,9 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const
if (mCode == BC_BINOP_ADDA_16) if (mCode == BC_BINOP_ADDA_16)
return true; return true;
if (mCode == BC_LOOP_U8)
return true;
} }
if (reg == BC_REG_ACCU) if (reg == BC_REG_ACCU)
@ -762,8 +764,6 @@ bool ByteCodeInstruction::UsesRegister(uint32 reg) const
return true; return true;
if (mCode >= BC_BINOP_SHLI_16 && mCode <= BC_BINOP_SHRI_I16) if (mCode >= BC_BINOP_SHLI_16 && mCode <= BC_BINOP_SHRI_I16)
return true; return true;
if (mCode >= BC_SET_EQ && mCode <= BC_SET_LE)
return true;
if (mCode >= BC_CONV_I16_I32 && mCode <= BC_BINOP_CMP_S32) if (mCode >= BC_CONV_I16_I32 && mCode <= BC_BINOP_CMP_S32)
return true; return true;
if (mCode == BC_LEA_ACCU_INDEX) if (mCode == BC_LEA_ACCU_INDEX)
@ -810,6 +810,8 @@ bool ByteCodeInstruction::ChangesRegister(uint32 reg) const
return true; return true;
if (mCode == BC_BINOP_ADDA_16) if (mCode == BC_BINOP_ADDA_16)
return true; 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) 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; return true;
if (mCode >= BC_BINOP_SHLI_16 && mCode <= BC_BINOP_SHRI_I16) if (mCode >= BC_BINOP_SHLI_16 && mCode <= BC_BINOP_SHRI_I16)
return true; 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) if (mCode == BC_JSR || mCode == BC_CALL_ADDR || mCode == BC_CALL_ABS)
return true; return true;
if (mCode >= BC_CONV_I16_I32 && mCode <= BC_BINOP_CMP_S32) if (mCode >= BC_CONV_I16_I32 && mCode <= BC_BINOP_CMP_S32)
return true; return true;
if (mCode == BC_LOOP_U8)
return true;
} }
if (reg == BC_REG_ADDR) if (reg == BC_REG_ADDR)
@ -1079,6 +1081,12 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
block->PutByte(uint8(mValue)); block->PutByte(uint8(mValue));
break; 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_NEGATE_16:
case BC_OP_INVERT_16: case BC_OP_INVERT_16:
block->PutCode(generator, mCode); block->PutCode(generator, mCode);
@ -1129,15 +1137,6 @@ void ByteCodeInstruction::Assemble(ByteCodeGenerator* generator, ByteCodeBasicBl
assert(false); assert(false);
break; 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_ENTER:
case BC_RETURN: case BC_RETURN:
assert(false); 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; ByteCode code;
bool csigned = false; bool csigned = false;
@ -3126,7 +3125,7 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
} }
else else
{ {
if (ins->mSrc[1].mIntConst == 0) if (optzero && ins->mSrc[1].mIntConst == 0)
{ {
switch (ins->mOperator) switch (ins->mOperator)
{ {
@ -3158,7 +3157,7 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
mIns.Push(lins); mIns.Push(lins);
if (csigned) if (csigned)
{ {
if (ins->mSrc[0].mIntConst == 0) if (optzero && ins->mSrc[0].mIntConst == 0)
{ {
ByteCodeInstruction cins(BC_CONV_I8_I16); ByteCodeInstruction cins(BC_CONV_I8_I16);
cins.mRegister = BC_REG_ACCU; cins.mRegister = BC_REG_ACCU;
@ -3189,7 +3188,7 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
} }
else else
{ {
if (ins->mSrc[0].mIntConst == 0) if (optzero && ins->mSrc[0].mIntConst == 0)
{ {
switch (ins->mOperator) switch (ins->mOperator)
{ {
@ -3265,7 +3264,7 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
mIns.Push(lins); mIns.Push(lins);
if (csigned) if (csigned)
{ {
if (ins->mSrc[0].mIntConst == 0) if (optzero && ins->mSrc[0].mIntConst == 0)
{ {
switch (ins->mOperator) switch (ins->mOperator)
{ {
@ -3283,6 +3282,12 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
return BC_BRANCHS_LT; 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 else
{ {
ByteCodeInstruction cins(BC_BINOP_CMPSI_16); ByteCodeInstruction cins(BC_BINOP_CMPSI_16);
@ -3292,7 +3297,7 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
} }
else else
{ {
if (ins->mSrc[0].mIntConst == 0) if (optzero && ins->mSrc[0].mIntConst == 0)
{ {
switch (ins->mOperator) switch (ins->mOperator)
{ {
@ -3308,6 +3313,12 @@ ByteCode ByteCodeBasicBlock::RelationalOperator(InterCodeProcedure* proc, const
return BC_NOP; 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 else
{ {
ByteCodeInstruction cins(BC_BINOP_CMPUI_16); ByteCodeInstruction cins(BC_BINOP_CMPUI_16);
@ -4164,14 +4175,14 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p
case IC_RELATIONAL_OPERATOR: case IC_RELATIONAL_OPERATOR:
if (i + 1 < sblock->mInstructions.Size() && sblock->mInstructions[i + 1]->mCode == IC_BRANCH && sblock->mInstructions[i + 1]->mSrc[0].mFinal) 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); this->Close(proc->CompileBlock(iproc, sblock->mTrueJump), proc->CompileBlock(iproc, sblock->mFalseJump), code);
i++; i++;
return; return;
} }
else else
{ {
ByteCode code = RelationalOperator(iproc, ins); ByteCode code = RelationalOperator(iproc, ins, false);
if (code == BC_JUMPS) if (code == BC_JUMPS)
{ {
IntConstToAccu(1); IntConstToAccu(1);
@ -4182,8 +4193,57 @@ void ByteCodeBasicBlock::Compile(InterCodeProcedure* iproc, ByteCodeProcedure* p
} }
else else
{ {
ByteCodeInstruction bins(ByteCode(code - BC_BRANCHS_EQ + BC_SET_EQ)); switch (code)
mIns.Push(bins); {
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]); ByteCodeInstruction sins(StoreTypedTmpCodes[ins->mDst.mType]);
sins.mRegister = BC_REG_TMP + iproc->mTempOffset[ins->mDst.mTemp]; 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; mIns[i + 2].mCode = BC_NOP;
progress = true; 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) 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; mIns[i + 0].mCode = BC_NOP;
@ -4983,6 +5036,32 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
mIns[i + 2].mCode = BC_NOP; mIns[i + 2].mCode = BC_NOP;
progress = true; 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 #if 1
else if ( else if (
i + 3 == mIns.Size() && mFalseJump && i + 3 == mIns.Size() && mFalseJump &&
@ -5294,6 +5373,16 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
mIns[i + 1].mCode = BC_NOP; mIns[i + 1].mCode = BC_NOP;
progress = true; 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 #endif
else if ( else if (
mIns[i + 0].mCode == BC_LOAD_LOCAL_8 && mIns[i + 0].mCode == BC_LOAD_LOCAL_8 &&
@ -5349,7 +5438,51 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
progress = true; progress = true;
} }
#endif #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 #if 1
else if ( else if (
i + 2 == mIns.Size() && mFalseJump && i + 2 == mIns.Size() && mFalseJump &&
@ -5375,6 +5508,18 @@ bool ByteCodeBasicBlock::PeepHoleOptimizer(int phase)
#endif #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) 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; mIns[i].mCode = BC_LOAD_REG_8;

View File

@ -142,12 +142,12 @@ enum ByteCode
BC_BRANCHF_LT, BC_BRANCHF_LT,
BC_BRANCHF_LE, BC_BRANCHF_LE,
BC_SET_EQ, BC_LOOP_U8,
BC_SET_NE, BC_UNUSED_2,
BC_SET_GT, BC_UNUSED_3,
BC_SET_GE, BC_UNUSED_4,
BC_SET_LT, BC_UNUSED_5,
BC_SET_LE, BC_UNUSED_6,
BC_JSR, BC_JSR,
@ -294,7 +294,7 @@ public:
void BinaryOperator(InterCodeProcedure* proc, const InterInstruction * ins); void BinaryOperator(InterCodeProcedure* proc, const InterInstruction * ins);
void UnaryOperator(InterCodeProcedure* proc, const InterInstruction * ins); void UnaryOperator(InterCodeProcedure* proc, const InterInstruction * ins);
void BinaryRROperator(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 BinaryIntOperator(InterCodeProcedure* proc, const InterInstruction * ins, ByteCode code);
void NumericConversion(InterCodeProcedure* proc, const InterInstruction * ins); 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; i += 2;
break; 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: case BC_CONV_I8_I16:
fprintf(file, "SEXT8\t%s", TempName(memory[start + i + 0], tbuffer, proc)); fprintf(file, "SEXT8\t%s", TempName(memory[start + i + 0], tbuffer, proc));
i++; i++;
@ -517,25 +522,6 @@ void ByteCodeDisassembler::Disassemble(FILE* file, const uint8* memory, int star
i += 2; i += 2;
break; 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: case BC_ENTER:
fprintf(file, "ENTER\t%d, %d", memory[start + i + 2], uint16(memory[start + i + 0] + 256 * memory[start + i + 1])); fprintf(file, "ENTER\t%d, %d", memory[start + i + 2], uint16(memory[start + i + 0] + 256 * memory[start + i + 1]));
i += 3; i += 3;

View File

@ -3461,6 +3461,13 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
mInstructions[i + 0] = ins; 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 #endif
if (mTrueJump) 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) void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
{ {
mLocalValueRange = mEntryValueRange; mLocalValueRange = mEntryValueRange;
@ -3710,7 +3728,23 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
vr.mMinValue = ins->mSrc[1].mIntConst - maxv; vr.mMinValue = ins->mSrc[1].mIntConst - maxv;
} }
else 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; break;
case IA_MUL: case IA_MUL:
@ -3887,6 +3921,40 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(void)
vr.mMinValue = 0; 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 else
vr.mMaxState = vr.mMinState = IntegerValueRange::S_UNBOUND; vr.mMaxState = vr.mMinState = IntegerValueRange::S_UNBOUND;
break; break;
@ -6972,8 +7040,6 @@ void InterCodeProcedure::BuildTraces(bool expand)
for (int i = 0; i < mBlocks.Size(); i++) for (int i = 0; i < mBlocks.Size(); i++)
mBlocks[i]->mNumEntries = 0; mBlocks[i]->mNumEntries = 0;
mEntryBlock->CollectEntries(); mEntryBlock->CollectEntries();
DisassembleDebug("BuildTraces");
} }
void InterCodeProcedure::BuildDataFlowSets(void) void InterCodeProcedure::BuildDataFlowSets(void)
@ -7417,6 +7483,11 @@ void InterCodeProcedure::Close(void)
ResetVisited(); ResetVisited();
mEntryBlock->OptimizeIntervalCompare(); mEntryBlock->OptimizeIntervalCompare();
ResetVisited();
for (int i = 0; i < mBlocks.Size(); i++)
mBlocks[i]->mNumEntries = 0;
mEntryBlock->CollectEntries();
DisassembleDebug("interval compare"); DisassembleDebug("interval compare");
BuildDataFlowSets(); BuildDataFlowSets();

View File

@ -1056,7 +1056,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
else else
{ {
Declaration * otype = vll.mType; 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) if ((vll.mType->mFlags | vr.mType->mFlags) & DTF_SIGNED)
otype = TheSignedIntTypeDeclaration; otype = TheSignedIntTypeDeclaration;