Skip to content

Commit 0b3adba

Browse files
noonefuzyll
authored andcommitted
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.
1 parent bdc1c71 commit 0b3adba

File tree

1 file changed

+24
-20
lines changed

1 file changed

+24
-20
lines changed

arch/mips/il.cpp

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,20 @@ static ExprId Concat3to256(LowLevelILFunction& il, uint32_t regHi, uint32_t regM
782782
);
783783
}
784784

785+
static void SignExtendHiLo(LowLevelILFunction& il, size_t registerSize)
786+
{
787+
if (registerSize == 8)
788+
{
789+
il.AddInstruction(il.SetRegister(8, REG_HI,
790+
il.SignExtend(8, il.LowPart(4, il.Register(registerSize, REG_HI)))
791+
));
792+
793+
il.AddInstruction(il.SetRegister(8, REG_LO,
794+
il.SignExtend(8, il.LowPart(4, il.Register(registerSize, REG_LO)))
795+
));
796+
}
797+
}
798+
785799
bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFunction& il, Instruction& instr, size_t addrSize, uint32_t decomposeFlags)
786800
{
787801
LowLevelILLabel trueLabel, falseLabel, doneLabel, dirFlagSet, dirFlagClear, dirFlagDone;
@@ -855,6 +869,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
855869
il.ModSigned(4,
856870
ReadILOperand(il, instr, 1, registerSize, 4),
857871
ReadILOperand(il, instr, 2, registerSize, 4))));
872+
SignExtendHiLo(il, registerSize);
858873
break;
859874
case MIPS_DIVU:
860875
il.AddInstruction(il.SetRegister(4, REG_LO,
@@ -865,6 +880,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
865880
il.ModUnsigned(4,
866881
ReadILOperand(il, instr, 1, registerSize, 4),
867882
ReadILOperand(il, instr, 2, registerSize, 4))));
883+
SignExtendHiLo(il, registerSize);
868884
break;
869885
case MIPS_DDIV:
870886
il.AddInstruction(il.SetRegister(8, REG_LO,
@@ -1146,6 +1162,8 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
11461162
il.AddInstruction(il.SetRegisterSplit(4, REG_HI, REG_LO,
11471163
il.Sub(8, il.Register(8, LLIL_TEMP(0)),
11481164
il.MultDoublePrecSigned(4, ReadILOperand(il, instr, 1, registerSize), ReadILOperand(il, instr, 2, registerSize)))));
1165+
1166+
SignExtendHiLo(il, registerSize);
11491167
break;
11501168
case MIPS_MSUBU:
11511169
//(HI,LO) = (HI,LO) - (GPR[rs] x GPR[rt])
@@ -1157,12 +1175,16 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
11571175
il.AddInstruction(il.SetRegisterSplit(4, REG_HI, REG_LO,
11581176
il.Sub(8, il.Register(8, LLIL_TEMP(0)),
11591177
il.MultDoublePrecUnsigned(8, ReadILOperand(il, instr, 1, registerSize), ReadILOperand(il, instr, 2, registerSize)))));
1178+
1179+
SignExtendHiLo(il, registerSize);
11601180
break;
11611181
case MIPS_MULT:
11621182
il.AddInstruction(il.SetRegisterSplit(4, REG_HI, REG_LO, il.MultDoublePrecSigned(8, ReadILOperand(il, instr, 1, registerSize), ReadILOperand(il, instr, 2, registerSize))));
1183+
SignExtendHiLo(il, registerSize);
11631184
break;
11641185
case MIPS_MULTU:
11651186
il.AddInstruction(il.SetRegisterSplit(4, REG_HI, REG_LO, il.MultDoublePrecUnsigned(8, ReadILOperand(il, instr, 1, registerSize), ReadILOperand(il, instr, 2, registerSize))));
1187+
SignExtendHiLo(il, registerSize);
11661188
break;
11671189
case MIPS_DMULT:
11681190
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
15611583
)
15621584
));
15631585

1564-
if (registerSize == 8)
1565-
{
1566-
il.AddInstruction(il.SetRegister(8, REG_HI,
1567-
il.SignExtend(8, il.LowPart(4, il.Register(registerSize, REG_HI)))
1568-
));
1569-
1570-
il.AddInstruction(il.SetRegister(8, REG_LO,
1571-
il.SignExtend(8, il.LowPart(4, il.Register(registerSize, REG_LO)))
1572-
));
1573-
}
1586+
SignExtendHiLo(il, registerSize);
15741587
break;
15751588
case MIPS_MADDU:
15761589
il.AddInstruction(il.SetRegisterSplit(4, REG_HI, REG_LO,
@@ -1583,16 +1596,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
15831596
)
15841597
));
15851598

1586-
if (registerSize == 8)
1587-
{
1588-
il.AddInstruction(il.SetRegister(8, REG_HI,
1589-
il.SignExtend(8, il.LowPart(4, il.Register(registerSize, REG_HI)))
1590-
));
1591-
1592-
il.AddInstruction(il.SetRegister(8, REG_LO,
1593-
il.SignExtend(8, il.LowPart(4, il.Register(registerSize, REG_LO)))
1594-
));
1595-
}
1599+
SignExtendHiLo(il, registerSize);
15961600
break;
15971601
case MIPS_ROTR:
15981602
case MIPS_ROTRV:

0 commit comments

Comments
 (0)