summaryrefslogtreecommitdiff
path: root/arch/mips/il.cpp
diff options
context:
space:
mode:
authornoone <you@example.com>2024-07-31 20:53:42 -0500
committerAlexander Taylor <alex@vector35.com>2024-08-12 15:50:55 -0400
commit0b3adba96944076c8b1e4110f1698553bdfc265d (patch)
tree1ef913856012cec85819f0bb8513b6fe6d685e6c /arch/mips/il.cpp
parentbdc1c7134e14fc18182e33dfa3fe98ba10c38acf (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.cpp44
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: