diff --git a/include/crt.c b/include/crt.c index 7dc59fc..82fe5d7 100644 --- a/include/crt.c +++ b/include/crt.c @@ -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: diff --git a/include/crt.h b/include/crt.h index f7766e7..5844f9c 100644 --- a/include/crt.h +++ b/include/crt.h @@ -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, diff --git a/oscar64/ByteCodeGenerator.cpp b/oscar64/ByteCodeGenerator.cpp index 57f8d82..c277c68 100644 --- a/oscar64/ByteCodeGenerator.cpp +++ b/oscar64/ByteCodeGenerator.cpp @@ -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; diff --git a/oscar64/ByteCodeGenerator.h b/oscar64/ByteCodeGenerator.h index 94cff38..9fa3c7d 100644 --- a/oscar64/ByteCodeGenerator.h +++ b/oscar64/ByteCodeGenerator.h @@ -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); diff --git a/oscar64/Disassembler.cpp b/oscar64/Disassembler.cpp index 8daa508..48b79fc 100644 --- a/oscar64/Disassembler.cpp +++ b/oscar64/Disassembler.cpp @@ -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; diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index a317fcb..057092f 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -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(); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index ebadc49..adb7ea7 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -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;