Skip to content

Commit 868ce1b

Browse files
xusheng6claude
andcommitted
[emulator] Mask arithmetic operands consistently up front
The basic two-operand arithmetic cases masked operands only when recording the flag context, while evaluating the operation on the raw operands, and the double-precision cases mask to sz/2 for unrelated reasons. This was noted as confusing in review. Mask both operands to sz once at the top of each case and use those masked values for both the computation and m_lastArithmetic, and add a comment explaining why the double-precision ops mask differently. No behavior change. Addresses bdash review comment on PR #8314. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 2e6f68f commit 868ce1b

1 file changed

Lines changed: 24 additions & 20 deletions

File tree

plugins/emulator/core/llilemulator.cpp

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -977,58 +977,62 @@ intx::uint512 LLILEmulator::EvalExpr(const LowLevelILInstruction& expr)
977977
}
978978

979979
// --- Two-operand arithmetic ---
980+
// Convention: operands are masked to the operation size `sz` up front, and the same
981+
// masked values are used both for the computation and for the flag context recorded in
982+
// m_lastArithmetic. (Double-precision ops below intentionally use sz/2-wide operands
983+
// producing an sz-wide result, which is why they mask differently.)
980984
case LLIL_ADD:
981985
{
982-
intx::uint512 left = EvalExpr(expr.GetRawOperandAsExpr(0));
983-
intx::uint512 right = EvalExpr(expr.GetRawOperandAsExpr(1));
986+
intx::uint512 left = MaskToSize(EvalExpr(expr.GetRawOperandAsExpr(0)), sz);
987+
intx::uint512 right = MaskToSize(EvalExpr(expr.GetRawOperandAsExpr(1)), sz);
984988
intx::uint512 result = MaskToSize(left + right, sz);
985-
m_lastArithmetic = {MaskToSize(left, sz), MaskToSize(right, sz), result, sz, LLIL_ADD, true};
989+
m_lastArithmetic = {left, right, result, sz, LLIL_ADD, true};
986990
return result;
987991
}
988992

989993
case LLIL_SUB:
990994
{
991-
intx::uint512 left = EvalExpr(expr.GetRawOperandAsExpr(0));
992-
intx::uint512 right = EvalExpr(expr.GetRawOperandAsExpr(1));
995+
intx::uint512 left = MaskToSize(EvalExpr(expr.GetRawOperandAsExpr(0)), sz);
996+
intx::uint512 right = MaskToSize(EvalExpr(expr.GetRawOperandAsExpr(1)), sz);
993997
intx::uint512 result = MaskToSize(left - right, sz);
994-
m_lastArithmetic = {MaskToSize(left, sz), MaskToSize(right, sz), result, sz, LLIL_SUB, true};
998+
m_lastArithmetic = {left, right, result, sz, LLIL_SUB, true};
995999
return result;
9961000
}
9971001

9981002
case LLIL_AND:
9991003
{
1000-
intx::uint512 left = EvalExpr(expr.GetRawOperandAsExpr(0));
1001-
intx::uint512 right = EvalExpr(expr.GetRawOperandAsExpr(1));
1004+
intx::uint512 left = MaskToSize(EvalExpr(expr.GetRawOperandAsExpr(0)), sz);
1005+
intx::uint512 right = MaskToSize(EvalExpr(expr.GetRawOperandAsExpr(1)), sz);
10021006
intx::uint512 result = MaskToSize(left & right, sz);
1003-
m_lastArithmetic = {MaskToSize(left, sz), MaskToSize(right, sz), result, sz, LLIL_AND, true};
1007+
m_lastArithmetic = {left, right, result, sz, LLIL_AND, true};
10041008
return result;
10051009
}
10061010

10071011
case LLIL_OR:
10081012
{
1009-
intx::uint512 left = EvalExpr(expr.GetRawOperandAsExpr(0));
1010-
intx::uint512 right = EvalExpr(expr.GetRawOperandAsExpr(1));
1013+
intx::uint512 left = MaskToSize(EvalExpr(expr.GetRawOperandAsExpr(0)), sz);
1014+
intx::uint512 right = MaskToSize(EvalExpr(expr.GetRawOperandAsExpr(1)), sz);
10111015
intx::uint512 result = MaskToSize(left | right, sz);
1012-
m_lastArithmetic = {MaskToSize(left, sz), MaskToSize(right, sz), result, sz, LLIL_OR, true};
1016+
m_lastArithmetic = {left, right, result, sz, LLIL_OR, true};
10131017
return result;
10141018
}
10151019

10161020
case LLIL_XOR:
10171021
{
1018-
intx::uint512 left = EvalExpr(expr.GetRawOperandAsExpr(0));
1019-
intx::uint512 right = EvalExpr(expr.GetRawOperandAsExpr(1));
1022+
intx::uint512 left = MaskToSize(EvalExpr(expr.GetRawOperandAsExpr(0)), sz);
1023+
intx::uint512 right = MaskToSize(EvalExpr(expr.GetRawOperandAsExpr(1)), sz);
10201024
intx::uint512 result = MaskToSize(left ^ right, sz);
1021-
m_lastArithmetic = {MaskToSize(left, sz), MaskToSize(right, sz), result, sz, LLIL_XOR, true};
1025+
m_lastArithmetic = {left, right, result, sz, LLIL_XOR, true};
10221026
return result;
10231027
}
10241028

10251029
case LLIL_LSL:
10261030
{
1027-
intx::uint512 left = EvalExpr(expr.GetRawOperandAsExpr(0));
1031+
intx::uint512 left = MaskToSize(EvalExpr(expr.GetRawOperandAsExpr(0)), sz);
10281032
intx::uint512 right = EvalExpr(expr.GetRawOperandAsExpr(1));
10291033
size_t shiftAmt = static_cast<uint64_t>(right) & (sz * 8 - 1);
10301034
intx::uint512 result = MaskToSize(left << shiftAmt, sz);
1031-
m_lastArithmetic = {MaskToSize(left, sz), right, result, sz, LLIL_LSL, true};
1035+
m_lastArithmetic = {left, right, result, sz, LLIL_LSL, true};
10321036
return result;
10331037
}
10341038

@@ -1080,10 +1084,10 @@ intx::uint512 LLILEmulator::EvalExpr(const LowLevelILInstruction& expr)
10801084

10811085
case LLIL_MUL:
10821086
{
1083-
intx::uint512 left = EvalExpr(expr.GetRawOperandAsExpr(0));
1084-
intx::uint512 right = EvalExpr(expr.GetRawOperandAsExpr(1));
1087+
intx::uint512 left = MaskToSize(EvalExpr(expr.GetRawOperandAsExpr(0)), sz);
1088+
intx::uint512 right = MaskToSize(EvalExpr(expr.GetRawOperandAsExpr(1)), sz);
10851089
intx::uint512 result = MaskToSize(left * right, sz);
1086-
m_lastArithmetic = {MaskToSize(left, sz), MaskToSize(right, sz), result, sz, LLIL_MUL, true};
1090+
m_lastArithmetic = {left, right, result, sz, LLIL_MUL, true};
10871091
return result;
10881092
}
10891093

0 commit comments

Comments
 (0)