diff options
| author | noone <you@example.com> | 2024-07-31 20:53:42 -0500 |
|---|---|---|
| committer | Alexander Taylor <alex@vector35.com> | 2024-08-12 15:50:55 -0400 |
| commit | 0b3adba96944076c8b1e4110f1698553bdfc265d (patch) | |
| tree | 1ef913856012cec85819f0bb8513b6fe6d685e6c /arch/mips/il.cpp | |
| parent | bdc1c7134e14fc18182e33dfa3fe98ba10c38acf (diff) | |
Sign-extend results of 32-bit operations on HI, LO
For 64-bit architectures, the results weren't properly sign-extended when
they were supposed to be for 32-bit operations.
This doesn't change the fact that the source of the register size is
still suspect, and this new sign extension may not properly take place for
64-bit architectures using 32-bit addresses, but solving that will take a
bit more examination in general.
Diffstat (limited to 'arch/mips/il.cpp')
| -rw-r--r-- | arch/mips/il.cpp | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/arch/mips/il.cpp b/arch/mips/il.cpp index 9719c4f5..d5bc1421 100644 --- a/arch/mips/il.cpp +++ b/arch/mips/il.cpp @@ -782,6 +782,20 @@ static ExprId Concat3to256(LowLevelILFunction& il, uint32_t regHi, uint32_t regM ); } +static void SignExtendHiLo(LowLevelILFunction& il, size_t registerSize) +{ + if (registerSize == 8) + { + il.AddInstruction(il.SetRegister(8, REG_HI, + il.SignExtend(8, il.LowPart(4, il.Register(registerSize, REG_HI))) + )); + + il.AddInstruction(il.SetRegister(8, REG_LO, + il.SignExtend(8, il.LowPart(4, il.Register(registerSize, REG_LO))) + )); + } +} + bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFunction& il, Instruction& instr, size_t addrSize, uint32_t decomposeFlags) { LowLevelILLabel trueLabel, falseLabel, doneLabel, dirFlagSet, dirFlagClear, dirFlagDone; @@ -855,6 +869,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu il.ModSigned(4, ReadILOperand(il, instr, 1, registerSize, 4), ReadILOperand(il, instr, 2, registerSize, 4)))); + SignExtendHiLo(il, registerSize); break; case MIPS_DIVU: il.AddInstruction(il.SetRegister(4, REG_LO, @@ -865,6 +880,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu il.ModUnsigned(4, ReadILOperand(il, instr, 1, registerSize, 4), ReadILOperand(il, instr, 2, registerSize, 4)))); + SignExtendHiLo(il, registerSize); break; case MIPS_DDIV: il.AddInstruction(il.SetRegister(8, REG_LO, @@ -1146,6 +1162,8 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu il.AddInstruction(il.SetRegisterSplit(4, REG_HI, REG_LO, il.Sub(8, il.Register(8, LLIL_TEMP(0)), il.MultDoublePrecSigned(4, ReadILOperand(il, instr, 1, registerSize), ReadILOperand(il, instr, 2, registerSize))))); + + SignExtendHiLo(il, registerSize); break; case MIPS_MSUBU: //(HI,LO) = (HI,LO) - (GPR[rs] x GPR[rt]) @@ -1157,12 +1175,16 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu il.AddInstruction(il.SetRegisterSplit(4, REG_HI, REG_LO, il.Sub(8, il.Register(8, LLIL_TEMP(0)), il.MultDoublePrecUnsigned(8, ReadILOperand(il, instr, 1, registerSize), ReadILOperand(il, instr, 2, registerSize))))); + + SignExtendHiLo(il, registerSize); break; case MIPS_MULT: il.AddInstruction(il.SetRegisterSplit(4, REG_HI, REG_LO, il.MultDoublePrecSigned(8, ReadILOperand(il, instr, 1, registerSize), ReadILOperand(il, instr, 2, registerSize)))); + SignExtendHiLo(il, registerSize); break; case MIPS_MULTU: il.AddInstruction(il.SetRegisterSplit(4, REG_HI, REG_LO, il.MultDoublePrecUnsigned(8, ReadILOperand(il, instr, 1, registerSize), ReadILOperand(il, instr, 2, registerSize)))); + SignExtendHiLo(il, registerSize); break; case MIPS_DMULT: il.AddInstruction(il.SetRegisterSplit(8, REG_HI, REG_LO, il.MultDoublePrecSigned(16, ReadILOperand(il, instr, 1, registerSize), ReadILOperand(il, instr, 2, registerSize)))); @@ -1561,16 +1583,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu ) )); - if (registerSize == 8) - { - il.AddInstruction(il.SetRegister(8, REG_HI, - il.SignExtend(8, il.LowPart(4, il.Register(registerSize, REG_HI))) - )); - - il.AddInstruction(il.SetRegister(8, REG_LO, - il.SignExtend(8, il.LowPart(4, il.Register(registerSize, REG_LO))) - )); - } + SignExtendHiLo(il, registerSize); break; case MIPS_MADDU: il.AddInstruction(il.SetRegisterSplit(4, REG_HI, REG_LO, @@ -1583,16 +1596,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu ) )); - if (registerSize == 8) - { - il.AddInstruction(il.SetRegister(8, REG_HI, - il.SignExtend(8, il.LowPart(4, il.Register(registerSize, REG_HI))) - )); - - il.AddInstruction(il.SetRegister(8, REG_LO, - il.SignExtend(8, il.LowPart(4, il.Register(registerSize, REG_LO))) - )); - } + SignExtendHiLo(il, registerSize); break; case MIPS_ROTR: case MIPS_ROTRV: |
