diff options
| author | Mark Rowe <mark@vector35.com> | 2026-06-04 16:36:52 -0700 |
|---|---|---|
| committer | Mark Rowe <mark@vector35.com> | 2026-06-05 13:01:46 -0700 |
| commit | fde1241ce928d38c2031c827ae0ddee5c6f5af0f (patch) | |
| tree | 6711a47863332712eb5324e2c3ef1dffb843bb5d | |
| parent | fa09f36b5f47ed690dc029fe9f1ed9ad4ebce7c8 (diff) | |
Add abs, min, and max instructions
| -rw-r--r-- | binaryninjaapi.h | 64 | ||||
| -rw-r--r-- | binaryninjacore.h | 31 | ||||
| -rw-r--r-- | docs/dev/bnil-hlil.md | 5 | ||||
| -rw-r--r-- | docs/dev/bnil-llil.md | 5 | ||||
| -rw-r--r-- | docs/dev/bnil-mlil.md | 5 | ||||
| -rw-r--r-- | highlevelilinstruction.cpp | 50 | ||||
| -rw-r--r-- | highlevelilinstruction.h | 15 | ||||
| -rw-r--r-- | lang/c/pseudoc.cpp | 25 | ||||
| -rw-r--r-- | lang/rust/pseudorust.cpp | 26 | ||||
| -rw-r--r-- | lowlevelilinstruction.cpp | 45 | ||||
| -rw-r--r-- | lowlevelilinstruction.h | 15 | ||||
| -rw-r--r-- | mediumlevelilinstruction.cpp | 45 | ||||
| -rw-r--r-- | mediumlevelilinstruction.h | 15 | ||||
| -rw-r--r-- | python/highlevelil.py | 38 | ||||
| -rw-r--r-- | python/lowlevelil.py | 38 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 38 | ||||
| -rw-r--r-- | rust/src/high_level_il/instruction.rs | 29 | ||||
| -rw-r--r-- | rust/src/high_level_il/lift.rs | 15 | ||||
| -rw-r--r-- | rust/src/low_level_il/expression.rs | 27 | ||||
| -rw-r--r-- | rust/src/low_level_il/lifting.rs | 41 | ||||
| -rw-r--r-- | rust/src/medium_level_il/instruction.rs | 29 | ||||
| -rw-r--r-- | rust/src/medium_level_il/lift.rs | 15 |
22 files changed, 599 insertions, 17 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 82da9ea6..5afc8a42 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -15069,6 +15069,60 @@ namespace BinaryNinja { */ ExprId CountLeadingSigns(size_t size, ExprId a, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation()); + /*! Signed minimum of expressions \c left and \c right of size \c size potentially setting flags + + \param size The size of the result in bytes + \param left The left expression + \param right The right expression + \param flags Flags to set + \param loc Optional IL Location this expression was added from. + \return The expression <tt>mins.<size>{<flags>}(left, right)</tt> + */ + ExprId MinSigned(size_t size, ExprId left, ExprId right, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation()); + + /*! Signed maximum of expressions \c left and \c right of size \c size potentially setting flags + + \param size The size of the result in bytes + \param left The left expression + \param right The right expression + \param flags Flags to set + \param loc Optional IL Location this expression was added from. + \return The expression <tt>maxs.<size>{<flags>}(left, right)</tt> + */ + ExprId MaxSigned(size_t size, ExprId left, ExprId right, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation()); + + /*! Unsigned minimum of expressions \c left and \c right of size \c size potentially setting flags + + \param size The size of the result in bytes + \param left The left expression + \param right The right expression + \param flags Flags to set + \param loc Optional IL Location this expression was added from. + \return The expression <tt>minu.<size>{<flags>}(left, right)</tt> + */ + ExprId MinUnsigned(size_t size, ExprId left, ExprId right, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation()); + + /*! Unsigned maximum of expressions \c left and \c right of size \c size potentially setting flags + + \param size The size of the result in bytes + \param left The left expression + \param right The right expression + \param flags Flags to set + \param loc Optional IL Location this expression was added from. + \return The expression <tt>maxu.<size>{<flags>}(left, right)</tt> + */ + ExprId MaxUnsigned(size_t size, ExprId left, ExprId right, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation()); + + /*! Signed absolute value of expression \c value of size \c size potentially setting flags + + \param size The size of the result in bytes + \param a The expression to take the absolute value of + \param flags Flags to set + \param loc Optional IL Location this expression was added from. + \return The expression <tt>abs.<size>{<flags>}(value)</tt> + */ + ExprId AbsoluteValue(size_t size, ExprId a, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation()); + /*! Two's complement sign-extends the expression in \c value to \c size bytes \param size The size of the result in bytes @@ -15955,6 +16009,11 @@ namespace BinaryNinja { ExprId CountTrailingZeros(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); ExprId ReverseBits(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); ExprId CountLeadingSigns(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); + ExprId MinSigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation()); + ExprId MaxSigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation()); + ExprId MinUnsigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation()); + ExprId MaxUnsigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation()); + ExprId AbsoluteValue(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); ExprId SignExtend(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); ExprId ZeroExtend(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); ExprId LowPart(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); @@ -16362,6 +16421,11 @@ namespace BinaryNinja { ExprId CountTrailingZeros(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); ExprId ReverseBits(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); ExprId CountLeadingSigns(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); + ExprId MinSigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation()); + ExprId MaxSigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation()); + ExprId MinUnsigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation()); + ExprId MaxUnsigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation()); + ExprId AbsoluteValue(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); ExprId SignExtend(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); ExprId ZeroExtend(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); ExprId LowPart(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation()); diff --git a/binaryninjacore.h b/binaryninjacore.h index 55ef21a2..a37a260a 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -37,14 +37,14 @@ // Current ABI version for linking to the core. This is incremented any time // there are changes to the API that affect linking, including new functions, // new types, or modifications to existing functions or types. -#define BN_CURRENT_CORE_ABI_VERSION 173 +#define BN_CURRENT_CORE_ABI_VERSION 174 // Minimum ABI version that is supported for loading of plugins. Plugins that // are linked to an ABI version less than this will not be able to load and // will require rebuilding. The minimum version is increased when there are // incompatible changes that break binary compatibility, such as changes to // existing types or functions. -#define BN_MINIMUM_CORE_ABI_VERSION 173 +#define BN_MINIMUM_CORE_ABI_VERSION 174 #ifdef __GNUC__ #ifdef BINARYNINJACORE_LIBRARY @@ -770,7 +770,14 @@ extern "C" LLIL_CLZ, // Count leading zero bits; clz(0) == 8 * size LLIL_CTZ, // Count trailing zero bits; ctz(0) == 8 * size LLIL_RBIT, // Reverse bit order of the whole value - LLIL_CLS // Count leading sign bits; number of bits below the sign bit that match it + LLIL_CLS, // Count leading sign bits; number of bits below the sign bit that match it + + // Integer minimum, maximum and absolute value + LLIL_MINS, // Signed minimum of left and right + LLIL_MAXS, // Signed maximum of left and right + LLIL_MINU, // Unsigned minimum of left and right + LLIL_MAXU, // Unsigned maximum of left and right + LLIL_ABS // Signed absolute value of src; abs(INT_MIN) == INT_MIN }; BN_ENUM(uint8_t, BNLowLevelILFlagCondition) @@ -1556,7 +1563,14 @@ extern "C" MLIL_CLZ, // Count leading zero bits; clz(0) == 8 * size MLIL_CTZ, // Count trailing zero bits; ctz(0) == 8 * size MLIL_RBIT, // Reverse bit order of the whole value - MLIL_CLS // Count leading sign bits; number of bits below the sign bit that match it + MLIL_CLS, // Count leading sign bits; number of bits below the sign bit that match it + + // Integer minimum, maximum and absolute value + MLIL_MINS, // Signed minimum of left and right + MLIL_MAXS, // Signed maximum of left and right + MLIL_MINU, // Unsigned minimum of left and right + MLIL_MAXU, // Unsigned maximum of left and right + MLIL_ABS // Signed absolute value of src; abs(INT_MIN) == INT_MIN }; typedef struct BNMediumLevelILInstruction @@ -1738,7 +1752,14 @@ extern "C" HLIL_CLZ, // Count leading zero bits; clz(0) == 8 * size HLIL_CTZ, // Count trailing zero bits; ctz(0) == 8 * size HLIL_RBIT, // Reverse bit order of the whole value - HLIL_CLS // Count leading sign bits; number of bits below the sign bit that match it + HLIL_CLS, // Count leading sign bits; number of bits below the sign bit that match it + + // Integer minimum, maximum and absolute value + HLIL_MINS, // Signed minimum of left and right + HLIL_MAXS, // Signed maximum of left and right + HLIL_MINU, // Unsigned minimum of left and right + HLIL_MAXU, // Unsigned maximum of left and right + HLIL_ABS // Signed absolute value of src; abs(INT_MIN) == INT_MIN }; typedef struct BNHighLevelILInstruction diff --git a/docs/dev/bnil-hlil.md b/docs/dev/bnil-hlil.md index 1b2754e1..94c21a74 100644 --- a/docs/dev/bnil-hlil.md +++ b/docs/dev/bnil-hlil.md @@ -117,6 +117,11 @@ There are a number of properties that can be queried on the [`HighLevelILInstruc * `HLIL_CTZ` - Count trailing zero bits of `src` expression; the result is `8 * size` when `src` is zero * `HLIL_RBIT` - Reverse the bit order of `src` expression * `HLIL_CLS` - Count leading sign bits of `src` expression (the number of bits below the sign bit that match it) +* `HLIL_MINS` - Signed minimum of `left` expression and `right` expression +* `HLIL_MAXS` - Signed maximum of `left` expression and `right` expression +* `HLIL_MINU` - Unsigned minimum of `left` expression and `right` expression +* `HLIL_MAXU` - Unsigned maximum of `left` expression and `right` expression +* `HLIL_ABS` - Signed absolute value of `src` expression * `HLIL_FADD` - IEEE754 floating point addition of `left` expression with `right` expression * `HLIL_FSUB` - IEEE754 floating point subtraction of `left` expression with `right` expression * `HLIL_FMUL` - IEEE754 floating point multiplication of `left` expression with `right` expression diff --git a/docs/dev/bnil-llil.md b/docs/dev/bnil-llil.md index b3a4f906..db251ab3 100644 --- a/docs/dev/bnil-llil.md +++ b/docs/dev/bnil-llil.md @@ -263,6 +263,11 @@ The double precision instruction multiply, divide, modulus instructions are part * `LLIL_CTZ` - Count trailing zero bits of `src`; the result is `8 * size` when `src` is zero * `LLIL_RBIT` - Reverse the bit order of `src` * `LLIL_CLS` - Count leading sign bits of `src` (the number of bits below the sign bit that match it) +* `LLIL_MINS` - Signed minimum of `left` and `right` +* `LLIL_MAXS` - Signed maximum of `left` and `right` +* `LLIL_MINU` - Unsigned minimum of `left` and `right` +* `LLIL_MAXU` - Unsigned maximum of `left` and `right` +* `LLIL_ABS` - Signed absolute value of `src` * `LLIL_TEST_BIT ` - Test if bit `right` in expression `left` is set * `LLIL_BOOL_TO_INT ` - Converts a bool `src` to an integer diff --git a/docs/dev/bnil-mlil.md b/docs/dev/bnil-mlil.md index 8e796ec8..99c47f21 100644 --- a/docs/dev/bnil-mlil.md +++ b/docs/dev/bnil-mlil.md @@ -354,6 +354,11 @@ The parameter list can be accessed through the `params` property: * `MLIL_CTZ` - Count trailing zero bits of `src` expression; the result is `8 * size` when `src` is zero * `MLIL_RBIT` - Reverse the bit order of `src` expression * `MLIL_CLS` - Count leading sign bits of `src` expression (the number of bits below the sign bit that match it) +* `MLIL_MINS` - Signed minimum of `left` expression and `right` expression +* `MLIL_MAXS` - Signed maximum of `left` expression and `right` expression +* `MLIL_MINU` - Unsigned minimum of `left` expression and `right` expression +* `MLIL_MAXU` - Unsigned maximum of `left` expression and `right` expression +* `MLIL_ABS` - Signed absolute value of `src` expression * `MLIL_FADD` - IEEE754 floating point addition of `left` expression with `right` expression * `MLIL_FSUB` - IEEE754 floating point subtraction of `left` expression with `right` expression * `MLIL_FMUL` - IEEE754 floating point multiplication of `left` expression with `right` expression diff --git a/highlevelilinstruction.cpp b/highlevelilinstruction.cpp index 92312549..00f0e67a 100644 --- a/highlevelilinstruction.cpp +++ b/highlevelilinstruction.cpp @@ -266,6 +266,11 @@ static constexpr std::array s_instructionOperandUsage = { OperandUsage{HLIL_CTZ, {SourceExprHighLevelOperandUsage}}, OperandUsage{HLIL_RBIT, {SourceExprHighLevelOperandUsage}}, OperandUsage{HLIL_CLS, {SourceExprHighLevelOperandUsage}}, + OperandUsage{HLIL_MINS, {LeftExprHighLevelOperandUsage, RightExprHighLevelOperandUsage}}, + OperandUsage{HLIL_MAXS, {LeftExprHighLevelOperandUsage, RightExprHighLevelOperandUsage}}, + OperandUsage{HLIL_MINU, {LeftExprHighLevelOperandUsage, RightExprHighLevelOperandUsage}}, + OperandUsage{HLIL_MAXU, {LeftExprHighLevelOperandUsage, RightExprHighLevelOperandUsage}}, + OperandUsage{HLIL_ABS, {SourceExprHighLevelOperandUsage}}, }; @@ -1273,6 +1278,7 @@ void HighLevelILInstruction::CollectSubExprs(stack<size_t>& toProcess) const case HLIL_CTZ: case HLIL_RBIT: case HLIL_CLS: + case HLIL_ABS: case HLIL_SX: case HLIL_ZX: case HLIL_LOW_PART: @@ -1298,6 +1304,10 @@ void HighLevelILInstruction::CollectSubExprs(stack<size_t>& toProcess) const case HLIL_AND: case HLIL_OR: case HLIL_XOR: + case HLIL_MINS: + case HLIL_MAXS: + case HLIL_MINU: + case HLIL_MAXU: case HLIL_LSL: case HLIL_LSR: case HLIL_ASR: @@ -1587,6 +1597,7 @@ ExprId HighLevelILInstruction::CopyTo( case HLIL_CTZ: case HLIL_RBIT: case HLIL_CLS: + case HLIL_ABS: case HLIL_SX: case HLIL_ZX: case HLIL_LOW_PART: @@ -1611,6 +1622,10 @@ ExprId HighLevelILInstruction::CopyTo( case HLIL_AND: case HLIL_OR: case HLIL_XOR: + case HLIL_MINS: + case HLIL_MAXS: + case HLIL_MINU: + case HLIL_MAXU: case HLIL_LSL: case HLIL_LSR: case HLIL_ASR: @@ -2073,6 +2088,10 @@ bool HighLevelILInstruction::operator<(const HighLevelILInstruction& other) cons case HLIL_AND: case HLIL_OR: case HLIL_XOR: + case HLIL_MINS: + case HLIL_MAXS: + case HLIL_MINU: + case HLIL_MAXU: case HLIL_LSL: case HLIL_LSR: case HLIL_ASR: @@ -2154,6 +2173,7 @@ bool HighLevelILInstruction::operator<(const HighLevelILInstruction& other) cons case HLIL_CTZ: case HLIL_RBIT: case HLIL_CLS: + case HLIL_ABS: case HLIL_SX: case HLIL_ZX: case HLIL_LOW_PART: @@ -3157,6 +3177,36 @@ ExprId HighLevelILFunction::CountLeadingSigns(size_t size, ExprId src, const ILS } +ExprId HighLevelILFunction::MinSigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc) +{ + return AddExprWithLocation(HLIL_MINS, loc, size, left, right); +} + + +ExprId HighLevelILFunction::MaxSigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc) +{ + return AddExprWithLocation(HLIL_MAXS, loc, size, left, right); +} + + +ExprId HighLevelILFunction::MinUnsigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc) +{ + return AddExprWithLocation(HLIL_MINU, loc, size, left, right); +} + + +ExprId HighLevelILFunction::MaxUnsigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc) +{ + return AddExprWithLocation(HLIL_MAXU, loc, size, left, right); +} + + +ExprId HighLevelILFunction::AbsoluteValue(size_t size, ExprId src, const ILSourceLocation& loc) +{ + return AddExprWithLocation(HLIL_ABS, loc, size, src); +} + + ExprId HighLevelILFunction::SignExtend(size_t size, ExprId src, const ILSourceLocation& loc) { return AddExprWithLocation(HLIL_SX, loc, size, src); diff --git a/highlevelilinstruction.h b/highlevelilinstruction.h index 4272d2e2..6eac89da 100644 --- a/highlevelilinstruction.h +++ b/highlevelilinstruction.h @@ -1472,6 +1472,21 @@ namespace BinaryNinja struct HighLevelILInstructionAccessor<HLIL_CLS> : public HighLevelILOneOperandInstruction {}; template <> + struct HighLevelILInstructionAccessor<HLIL_MINS> : public HighLevelILTwoOperandInstruction + {}; + template <> + struct HighLevelILInstructionAccessor<HLIL_MAXS> : public HighLevelILTwoOperandInstruction + {}; + template <> + struct HighLevelILInstructionAccessor<HLIL_MINU> : public HighLevelILTwoOperandInstruction + {}; + template <> + struct HighLevelILInstructionAccessor<HLIL_MAXU> : public HighLevelILTwoOperandInstruction + {}; + template <> + struct HighLevelILInstructionAccessor<HLIL_ABS> : public HighLevelILOneOperandInstruction + {}; + template <> struct HighLevelILInstructionAccessor<HLIL_SX> : public HighLevelILOneOperandInstruction {}; template <> diff --git a/lang/c/pseudoc.cpp b/lang/c/pseudoc.cpp index dc37100e..81401b55 100644 --- a/lang/c/pseudoc.cpp +++ b/lang/c/pseudoc.cpp @@ -2490,6 +2490,31 @@ void PseudoCFunction::GetExprTextInternal(const HighLevelILInstruction& instr, H }(); break; + case HLIL_MINS: + case HLIL_MINU: + AppendTwoOperandFunction("min", instr, tokens, settings, false); + if (statement) + tokens.AppendSemicolon(); + break; + + case HLIL_MAXS: + case HLIL_MAXU: + AppendTwoOperandFunction("max", instr, tokens, settings, false); + if (statement) + tokens.AppendSemicolon(); + break; + + case HLIL_ABS: + [&]() { + tokens.Append(OperationToken, "abs"); + tokens.AppendOpenParen(); + GetExprTextInternal(instr.GetSourceExpr<HLIL_ABS>(), tokens, settings); + tokens.AppendCloseParen(); + if (statement) + tokens.AppendSemicolon(); + }(); + break; + case HLIL_FLOAT_CONV: [&]() { const auto srcExpr = instr.GetSourceExpr<HLIL_FLOAT_CONV>(); diff --git a/lang/rust/pseudorust.cpp b/lang/rust/pseudorust.cpp index de1acae1..7c831e47 100644 --- a/lang/rust/pseudorust.cpp +++ b/lang/rust/pseudorust.cpp @@ -2434,6 +2434,7 @@ void PseudoRustFunction::GetExprText(const HighLevelILInstruction& instr, HighLe case HLIL_CTZ: case HLIL_RBIT: case HLIL_CLS: + case HLIL_ABS: [&]() { const char* method; switch (instr.operation) @@ -2443,6 +2444,7 @@ void PseudoRustFunction::GetExprText(const HighLevelILInstruction& instr, HighLe case HLIL_CLZ: method = "leading_zeros"; break; case HLIL_CTZ: method = "trailing_zeros"; break; case HLIL_RBIT: method = "reverse_bits"; break; + case HLIL_ABS: method = "abs"; break; default: method = "leading_sign_bits"; break; } GetExprText(instr.GetSourceExpr(), tokens, settings, MemberAndFunctionOperatorPrecedence); @@ -2455,6 +2457,30 @@ void PseudoRustFunction::GetExprText(const HighLevelILInstruction& instr, HighLe }(); break; + case HLIL_MINS: + case HLIL_MAXS: + case HLIL_MINU: + case HLIL_MAXU: + [&]() { + const char* method; + switch (instr.operation) + { + case HLIL_MINS: + case HLIL_MINU: method = "min"; break; + default: method = "max"; break; + } + const auto& twoOperand = instr.AsTwoOperand(); + GetExprText(twoOperand.GetLeftExpr(), tokens, settings, MemberAndFunctionOperatorPrecedence); + tokens.Append(TextToken, "."); + tokens.Append(OperationToken, method); + tokens.AppendOpenParen(); + GetExprText(twoOperand.GetRightExpr(), tokens, settings); + tokens.AppendCloseParen(); + if (exprType != InnerExpression) + tokens.AppendSemicolon(); + }(); + break; + case HLIL_FLOAT_CONV: [&]() { const auto srcExpr = instr.GetSourceExpr<HLIL_FLOAT_CONV>(); diff --git a/lowlevelilinstruction.cpp b/lowlevelilinstruction.cpp index 5a100080..c306e571 100644 --- a/lowlevelilinstruction.cpp +++ b/lowlevelilinstruction.cpp @@ -338,6 +338,11 @@ static constexpr std::array s_instructionOperandUsage = { OperandUsage{LLIL_CTZ, {SourceExprLowLevelOperandUsage}}, OperandUsage{LLIL_RBIT, {SourceExprLowLevelOperandUsage}}, OperandUsage{LLIL_CLS, {SourceExprLowLevelOperandUsage}}, + OperandUsage{LLIL_MINS, {LeftExprLowLevelOperandUsage, RightExprLowLevelOperandUsage}}, + OperandUsage{LLIL_MAXS, {LeftExprLowLevelOperandUsage, RightExprLowLevelOperandUsage}}, + OperandUsage{LLIL_MINU, {LeftExprLowLevelOperandUsage, RightExprLowLevelOperandUsage}}, + OperandUsage{LLIL_MAXU, {LeftExprLowLevelOperandUsage, RightExprLowLevelOperandUsage}}, + OperandUsage{LLIL_ABS, {SourceExprLowLevelOperandUsage}}, }; @@ -1996,6 +2001,7 @@ void LowLevelILInstruction::VisitExprs(bn::base::function_ref<bool(const LowLeve case LLIL_CTZ: case LLIL_RBIT: case LLIL_CLS: + case LLIL_ABS: case LLIL_SX: case LLIL_ZX: case LLIL_LOW_PART: @@ -2018,6 +2024,10 @@ void LowLevelILInstruction::VisitExprs(bn::base::function_ref<bool(const LowLeve case LLIL_AND: case LLIL_OR: case LLIL_XOR: + case LLIL_MINS: + case LLIL_MAXS: + case LLIL_MINU: + case LLIL_MAXU: case LLIL_LSL: case LLIL_LSR: case LLIL_ASR: @@ -2319,6 +2329,7 @@ ExprId LowLevelILInstruction::CopyTo( case LLIL_CTZ: case LLIL_RBIT: case LLIL_CLS: + case LLIL_ABS: case LLIL_SX: case LLIL_ZX: case LLIL_LOW_PART: @@ -2340,6 +2351,10 @@ ExprId LowLevelILInstruction::CopyTo( case LLIL_AND: case LLIL_OR: case LLIL_XOR: + case LLIL_MINS: + case LLIL_MAXS: + case LLIL_MINU: + case LLIL_MAXU: case LLIL_LSL: case LLIL_LSR: case LLIL_ASR: @@ -3406,6 +3421,36 @@ ExprId LowLevelILFunction::CountLeadingSigns(size_t size, ExprId a, uint32_t fla } +ExprId LowLevelILFunction::MinSigned(size_t size, ExprId left, ExprId right, uint32_t flags, const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_MINS, loc, size, flags, left, right); +} + + +ExprId LowLevelILFunction::MaxSigned(size_t size, ExprId left, ExprId right, uint32_t flags, const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_MAXS, loc, size, flags, left, right); +} + + +ExprId LowLevelILFunction::MinUnsigned(size_t size, ExprId left, ExprId right, uint32_t flags, const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_MINU, loc, size, flags, left, right); +} + + +ExprId LowLevelILFunction::MaxUnsigned(size_t size, ExprId left, ExprId right, uint32_t flags, const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_MAXU, loc, size, flags, left, right); +} + + +ExprId LowLevelILFunction::AbsoluteValue(size_t size, ExprId a, uint32_t flags, const ILSourceLocation& loc) +{ + return AddExprWithLocation(LLIL_ABS, loc, size, flags, a); +} + + ExprId LowLevelILFunction::SignExtend(size_t size, ExprId a, uint32_t flags, const ILSourceLocation& loc) { return AddExprWithLocation(LLIL_SX, loc, size, flags, a); diff --git a/lowlevelilinstruction.h b/lowlevelilinstruction.h index 53e10b6c..0234ed7f 100644 --- a/lowlevelilinstruction.h +++ b/lowlevelilinstruction.h @@ -2072,6 +2072,21 @@ namespace BinaryNinja struct LowLevelILInstructionAccessor<LLIL_CLS> : public LowLevelILOneOperandInstruction {}; template <> + struct LowLevelILInstructionAccessor<LLIL_MINS> : public LowLevelILTwoOperandInstruction + {}; + template <> + struct LowLevelILInstructionAccessor<LLIL_MAXS> : public LowLevelILTwoOperandInstruction + {}; + template <> + struct LowLevelILInstructionAccessor<LLIL_MINU> : public LowLevelILTwoOperandInstruction + {}; + template <> + struct LowLevelILInstructionAccessor<LLIL_MAXU> : public LowLevelILTwoOperandInstruction + {}; + template <> + struct LowLevelILInstructionAccessor<LLIL_ABS> : public LowLevelILOneOperandInstruction + {}; + template <> struct LowLevelILInstructionAccessor<LLIL_SX> : public LowLevelILOneOperandInstruction {}; template <> diff --git a/mediumlevelilinstruction.cpp b/mediumlevelilinstruction.cpp index 18610a55..a6987fb1 100644 --- a/mediumlevelilinstruction.cpp +++ b/mediumlevelilinstruction.cpp @@ -310,6 +310,11 @@ static constexpr std::array s_instructionOperandUsage = { OperandUsage{MLIL_CTZ, {SourceExprMediumLevelOperandUsage}}, OperandUsage{MLIL_RBIT, {SourceExprMediumLevelOperandUsage}}, OperandUsage{MLIL_CLS, {SourceExprMediumLevelOperandUsage}}, + OperandUsage{MLIL_MINS, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}}, + OperandUsage{MLIL_MAXS, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}}, + OperandUsage{MLIL_MINU, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}}, + OperandUsage{MLIL_MAXU, {LeftExprMediumLevelOperandUsage, RightExprMediumLevelOperandUsage}}, + OperandUsage{MLIL_ABS, {SourceExprMediumLevelOperandUsage}}, }; VALIDATE_INSTRUCTION_ORDER(s_instructionOperandUsage); @@ -1526,6 +1531,7 @@ void MediumLevelILInstruction::VisitExprs(bn::base::function_ref<bool(const Medi case MLIL_CTZ: case MLIL_RBIT: case MLIL_CLS: + case MLIL_ABS: case MLIL_SX: case MLIL_ZX: case MLIL_LOW_PART: @@ -1558,6 +1564,10 @@ void MediumLevelILInstruction::VisitExprs(bn::base::function_ref<bool(const Medi case MLIL_AND: case MLIL_OR: case MLIL_XOR: + case MLIL_MINS: + case MLIL_MAXS: + case MLIL_MINU: + case MLIL_MAXU: case MLIL_LSL: case MLIL_LSR: case MLIL_ASR: @@ -1873,6 +1883,7 @@ ExprId MediumLevelILInstruction::CopyTo(MediumLevelILFunction* dest, case MLIL_CTZ: case MLIL_RBIT: case MLIL_CLS: + case MLIL_ABS: case MLIL_SX: case MLIL_ZX: case MLIL_LOW_PART: @@ -1898,6 +1909,10 @@ ExprId MediumLevelILInstruction::CopyTo(MediumLevelILFunction* dest, case MLIL_AND: case MLIL_OR: case MLIL_XOR: + case MLIL_MINS: + case MLIL_MAXS: + case MLIL_MINU: + case MLIL_MAXU: case MLIL_LSL: case MLIL_LSR: case MLIL_ASR: @@ -2918,6 +2933,36 @@ ExprId MediumLevelILFunction::CountLeadingSigns(size_t size, ExprId src, const I } +ExprId MediumLevelILFunction::MinSigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_MINS, loc, size, left, right); +} + + +ExprId MediumLevelILFunction::MaxSigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_MAXS, loc, size, left, right); +} + + +ExprId MediumLevelILFunction::MinUnsigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_MINU, loc, size, left, right); +} + + +ExprId MediumLevelILFunction::MaxUnsigned(size_t size, ExprId left, ExprId right, const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_MAXU, loc, size, left, right); +} + + +ExprId MediumLevelILFunction::AbsoluteValue(size_t size, ExprId src, const ILSourceLocation& loc) +{ + return AddExprWithLocation(MLIL_ABS, loc, size, src); +} + + ExprId MediumLevelILFunction::SignExtend(size_t size, ExprId src, const ILSourceLocation& loc) { return AddExprWithLocation(MLIL_SX, loc, size, src); diff --git a/mediumlevelilinstruction.h b/mediumlevelilinstruction.h index 41f154ba..00f705f6 100644 --- a/mediumlevelilinstruction.h +++ b/mediumlevelilinstruction.h @@ -1804,6 +1804,21 @@ namespace BinaryNinja struct MediumLevelILInstructionAccessor<MLIL_CLS> : public MediumLevelILOneOperandInstruction {}; template <> + struct MediumLevelILInstructionAccessor<MLIL_MINS> : public MediumLevelILTwoOperandInstruction + {}; + template <> + struct MediumLevelILInstructionAccessor<MLIL_MAXS> : public MediumLevelILTwoOperandInstruction + {}; + template <> + struct MediumLevelILInstructionAccessor<MLIL_MINU> : public MediumLevelILTwoOperandInstruction + {}; + template <> + struct MediumLevelILInstructionAccessor<MLIL_MAXU> : public MediumLevelILTwoOperandInstruction + {}; + template <> + struct MediumLevelILInstructionAccessor<MLIL_ABS> : public MediumLevelILOneOperandInstruction + {}; + template <> struct MediumLevelILInstructionAccessor<MLIL_SX> : public MediumLevelILOneOperandInstruction {}; template <> diff --git a/python/highlevelil.py b/python/highlevelil.py index bbeb0186..f990467c 100644 --- a/python/highlevelil.py +++ b/python/highlevelil.py @@ -254,7 +254,13 @@ class HighLevelILInstruction(BaseILInstruction): ("src", "expr") ], HighLevelILOperation.HLIL_CTZ: [("src", "expr")], HighLevelILOperation.HLIL_RBIT: [ ("src", "expr") - ], HighLevelILOperation.HLIL_CLS: [("src", "expr")], HighLevelILOperation.HLIL_SX: [ + ], HighLevelILOperation.HLIL_CLS: [("src", "expr")], HighLevelILOperation.HLIL_MINS: [ + ("left", "expr"), ("right", "expr") + ], HighLevelILOperation.HLIL_MAXS: [("left", "expr"), ("right", "expr")], HighLevelILOperation.HLIL_MINU: [ + ("left", "expr"), ("right", "expr") + ], HighLevelILOperation.HLIL_MAXU: [("left", "expr"), ("right", "expr")], HighLevelILOperation.HLIL_ABS: [ + ("src", "expr") + ], HighLevelILOperation.HLIL_SX: [ ("src", "expr") ], HighLevelILOperation.HLIL_ZX: [("src", "expr")], HighLevelILOperation.HLIL_LOW_PART: [ ("src", "expr") @@ -2020,6 +2026,31 @@ class HighLevelILCls(HighLevelILUnaryBase, Arithmetic): @dataclass(frozen=True, repr=False, eq=False) +class HighLevelILMins(HighLevelILBinaryBase, Arithmetic, Signed): + pass + + +@dataclass(frozen=True, repr=False, eq=False) +class HighLevelILMaxs(HighLevelILBinaryBase, Arithmetic, Signed): + pass + + +@dataclass(frozen=True, repr=False, eq=False) +class HighLevelILMinu(HighLevelILBinaryBase, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False, eq=False) +class HighLevelILMaxu(HighLevelILBinaryBase, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False, eq=False) +class HighLevelILAbs(HighLevelILUnaryBase, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False, eq=False) class HighLevelILSx(HighLevelILUnaryBase, Arithmetic): pass @@ -2520,6 +2551,11 @@ ILInstruction = { HighLevelILOperation.HLIL_CTZ: HighLevelILCtz, # ("src", "expr"), HighLevelILOperation.HLIL_RBIT: HighLevelILRbit, # ("src", "expr"), HighLevelILOperation.HLIL_CLS: HighLevelILCls, # ("src", "expr"), + HighLevelILOperation.HLIL_MINS: HighLevelILMins, # ("left", "expr"), ("right", "expr"), + HighLevelILOperation.HLIL_MAXS: HighLevelILMaxs, # ("left", "expr"), ("right", "expr"), + HighLevelILOperation.HLIL_MINU: HighLevelILMinu, # ("left", "expr"), ("right", "expr"), + HighLevelILOperation.HLIL_MAXU: HighLevelILMaxu, # ("left", "expr"), ("right", "expr"), + HighLevelILOperation.HLIL_ABS: HighLevelILAbs, # ("src", "expr"), HighLevelILOperation.HLIL_SX: HighLevelILSx, # ("src", "expr"), HighLevelILOperation.HLIL_ZX: HighLevelILZx, # ("src", "expr"), HighLevelILOperation.HLIL_LOW_PART: HighLevelILLowPart, # ("src", "expr"), diff --git a/python/lowlevelil.py b/python/lowlevelil.py index ce9770f2..9f601fd4 100644 --- a/python/lowlevelil.py +++ b/python/lowlevelil.py @@ -383,7 +383,13 @@ class LowLevelILInstruction(BaseILInstruction): ("src", "expr") ], LowLevelILOperation.LLIL_CTZ: [("src", "expr")], LowLevelILOperation.LLIL_RBIT: [ ("src", "expr") - ], LowLevelILOperation.LLIL_CLS: [("src", "expr")], LowLevelILOperation.LLIL_SX: [ + ], LowLevelILOperation.LLIL_CLS: [("src", "expr")], LowLevelILOperation.LLIL_MINS: [ + ("left", "expr"), ("right", "expr") + ], LowLevelILOperation.LLIL_MAXS: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_MINU: [ + ("left", "expr"), ("right", "expr") + ], LowLevelILOperation.LLIL_MAXU: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_ABS: [ + ("src", "expr") + ], LowLevelILOperation.LLIL_SX: [ ("src", "expr") ], LowLevelILOperation.LLIL_ZX: [("src", "expr")], LowLevelILOperation.LLIL_LOW_PART: [ ("src", "expr") @@ -1399,6 +1405,31 @@ class LowLevelILCls(LowLevelILUnaryBase, Arithmetic): @dataclass(frozen=True, repr=False, eq=False) +class LowLevelILMins(LowLevelILBinaryBase, Arithmetic, Signed): + pass + + +@dataclass(frozen=True, repr=False, eq=False) +class LowLevelILMaxs(LowLevelILBinaryBase, Arithmetic, Signed): + pass + + +@dataclass(frozen=True, repr=False, eq=False) +class LowLevelILMinu(LowLevelILBinaryBase, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False, eq=False) +class LowLevelILMaxu(LowLevelILBinaryBase, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False, eq=False) +class LowLevelILAbs(LowLevelILUnaryBase, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False, eq=False) class LowLevelILSx(LowLevelILUnaryBase, Arithmetic): pass @@ -3174,6 +3205,11 @@ ILInstruction:Dict[LowLevelILOperation, LowLevelILInstruction] = { # type: igno LowLevelILOperation.LLIL_CTZ: LowLevelILCtz, # [("src", "expr")], LowLevelILOperation.LLIL_RBIT: LowLevelILRbit, # [("src", "expr")], LowLevelILOperation.LLIL_CLS: LowLevelILCls, # [("src", "expr")], + LowLevelILOperation.LLIL_MINS: LowLevelILMins, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_MAXS: LowLevelILMaxs, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_MINU: LowLevelILMinu, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_MAXU: LowLevelILMaxu, # [("left", "expr"), ("right", "expr")], + LowLevelILOperation.LLIL_ABS: LowLevelILAbs, # [("src", "expr")], LowLevelILOperation.LLIL_SX: LowLevelILSx, # [("src", "expr")], LowLevelILOperation.LLIL_ZX: LowLevelILZx, # [("src", "expr")], LowLevelILOperation.LLIL_LOW_PART: LowLevelILLowPart, # [("src", "expr")], diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index 15db8ae1..018a817f 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -271,7 +271,13 @@ class MediumLevelILInstruction(BaseILInstruction): ("src", "expr") ], MediumLevelILOperation.MLIL_CTZ: [("src", "expr")], MediumLevelILOperation.MLIL_RBIT: [ ("src", "expr") - ], MediumLevelILOperation.MLIL_CLS: [("src", "expr")], MediumLevelILOperation.MLIL_SX: [ + ], MediumLevelILOperation.MLIL_CLS: [("src", "expr")], MediumLevelILOperation.MLIL_MINS: [ + ("left", "expr"), ("right", "expr") + ], MediumLevelILOperation.MLIL_MAXS: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_MINU: [ + ("left", "expr"), ("right", "expr") + ], MediumLevelILOperation.MLIL_MAXU: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_ABS: [ + ("src", "expr") + ], MediumLevelILOperation.MLIL_SX: [ ("src", "expr") ], MediumLevelILOperation.MLIL_ZX: [("src", "expr")], MediumLevelILOperation.MLIL_LOW_PART: [ ("src", "expr") @@ -1471,6 +1477,31 @@ class MediumLevelILCls(MediumLevelILUnaryBase, Arithmetic): @dataclass(frozen=True, repr=False, eq=False) +class MediumLevelILMins(MediumLevelILBinaryBase, Arithmetic, Signed): + pass + + +@dataclass(frozen=True, repr=False, eq=False) +class MediumLevelILMaxs(MediumLevelILBinaryBase, Arithmetic, Signed): + pass + + +@dataclass(frozen=True, repr=False, eq=False) +class MediumLevelILMinu(MediumLevelILBinaryBase, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False, eq=False) +class MediumLevelILMaxu(MediumLevelILBinaryBase, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False, eq=False) +class MediumLevelILAbs(MediumLevelILUnaryBase, Arithmetic): + pass + + +@dataclass(frozen=True, repr=False, eq=False) class MediumLevelILSx(MediumLevelILUnaryBase, Arithmetic): pass @@ -3486,6 +3517,11 @@ ILInstruction = { MediumLevelILOperation.MLIL_CTZ: MediumLevelILCtz, # [("src", "expr")], MediumLevelILOperation.MLIL_RBIT: MediumLevelILRbit, # [("src", "expr")], MediumLevelILOperation.MLIL_CLS: MediumLevelILCls, # [("src", "expr")], + MediumLevelILOperation.MLIL_MINS: MediumLevelILMins, # [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MAXS: MediumLevelILMaxs, # [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MINU: MediumLevelILMinu, # [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_MAXU: MediumLevelILMaxu, # [("left", "expr"), ("right", "expr")], + MediumLevelILOperation.MLIL_ABS: MediumLevelILAbs, # [("src", "expr")], MediumLevelILOperation.MLIL_SX: MediumLevelILSx, # [("src", "expr")], MediumLevelILOperation.MLIL_ZX: MediumLevelILZx, # [("src", "expr")], MediumLevelILOperation.MLIL_LOW_PART: MediumLevelILLowPart, # [("src", "expr")], diff --git a/rust/src/high_level_il/instruction.rs b/rust/src/high_level_il/instruction.rs index 0fbbb297..8b675657 100644 --- a/rust/src/high_level_il/instruction.rs +++ b/rust/src/high_level_il/instruction.rs @@ -227,6 +227,22 @@ impl HighLevelILInstruction { left: HighLevelExpressionIndex::from(op.operands[0]), right: HighLevelExpressionIndex::from(op.operands[1]), }), + HLIL_MINS => Op::MinSigned(BinaryOp { + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), + }), + HLIL_MAXS => Op::MaxSigned(BinaryOp { + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), + }), + HLIL_MINU => Op::MinUnsigned(BinaryOp { + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), + }), + HLIL_MAXU => Op::MaxUnsigned(BinaryOp { + left: HighLevelExpressionIndex::from(op.operands[0]), + right: HighLevelExpressionIndex::from(op.operands[1]), + }), HLIL_CMP_E => Op::CmpE(BinaryOp { left: HighLevelExpressionIndex::from(op.operands[0]), right: HighLevelExpressionIndex::from(op.operands[1]), @@ -430,6 +446,9 @@ impl HighLevelILInstruction { HLIL_CLS => Op::Cls(UnaryOp { src: HighLevelExpressionIndex::from(op.operands[0]), }), + HLIL_ABS => Op::Abs(UnaryOp { + src: HighLevelExpressionIndex::from(op.operands[0]), + }), HLIL_SX => Op::Sx(UnaryOp { src: HighLevelExpressionIndex::from(op.operands[0]), }), @@ -695,6 +714,10 @@ impl HighLevelILInstruction { ModuDp(op) => Lifted::ModuDp(self.lift_binary_op(op)), Mods(op) => Lifted::Mods(self.lift_binary_op(op)), ModsDp(op) => Lifted::ModsDp(self.lift_binary_op(op)), + MinSigned(op) => Lifted::MinSigned(self.lift_binary_op(op)), + MaxSigned(op) => Lifted::MaxSigned(self.lift_binary_op(op)), + MinUnsigned(op) => Lifted::MinUnsigned(self.lift_binary_op(op)), + MaxUnsigned(op) => Lifted::MaxUnsigned(self.lift_binary_op(op)), CmpE(op) => Lifted::CmpE(self.lift_binary_op(op)), CmpNe(op) => Lifted::CmpNe(self.lift_binary_op(op)), CmpSlt(op) => Lifted::CmpSlt(self.lift_binary_op(op)), @@ -818,6 +841,7 @@ impl HighLevelILInstruction { Ctz(op) => Lifted::Ctz(self.lift_unary_op(op)), Rbit(op) => Lifted::Rbit(self.lift_unary_op(op)), Cls(op) => Lifted::Cls(self.lift_unary_op(op)), + Abs(op) => Lifted::Abs(self.lift_unary_op(op)), Sx(op) => Lifted::Sx(self.lift_unary_op(op)), Zx(op) => Lifted::Zx(self.lift_unary_op(op)), LowPart(op) => Lifted::LowPart(self.lift_unary_op(op)), @@ -1152,6 +1176,10 @@ pub enum HighLevelILInstructionKind { ModuDp(BinaryOp), Mods(BinaryOp), ModsDp(BinaryOp), + MinSigned(BinaryOp), + MaxSigned(BinaryOp), + MinUnsigned(BinaryOp), + MaxUnsigned(BinaryOp), CmpE(BinaryOp), CmpNe(BinaryOp), CmpSlt(BinaryOp), @@ -1203,6 +1231,7 @@ pub enum HighLevelILInstructionKind { Ctz(UnaryOp), Rbit(UnaryOp), Cls(UnaryOp), + Abs(UnaryOp), Sx(UnaryOp), Zx(UnaryOp), LowPart(UnaryOp), diff --git a/rust/src/high_level_il/lift.rs b/rust/src/high_level_il/lift.rs index 3d32b369..1de6248a 100644 --- a/rust/src/high_level_il/lift.rs +++ b/rust/src/high_level_il/lift.rs @@ -71,6 +71,10 @@ pub enum HighLevelILLiftedInstructionKind { ModuDp(LiftedBinaryOp), Mods(LiftedBinaryOp), ModsDp(LiftedBinaryOp), + MinSigned(LiftedBinaryOp), + MaxSigned(LiftedBinaryOp), + MinUnsigned(LiftedBinaryOp), + MaxUnsigned(LiftedBinaryOp), CmpE(LiftedBinaryOp), CmpNe(LiftedBinaryOp), CmpSlt(LiftedBinaryOp), @@ -122,6 +126,7 @@ pub enum HighLevelILLiftedInstructionKind { Ctz(LiftedUnaryOp), Rbit(LiftedUnaryOp), Cls(LiftedUnaryOp), + Abs(LiftedUnaryOp), Sx(LiftedUnaryOp), Zx(LiftedUnaryOp), LowPart(LiftedUnaryOp), @@ -207,6 +212,10 @@ impl HighLevelILLiftedInstruction { ModuDp(_) => "ModuDp", Mods(_) => "Mods", ModsDp(_) => "ModsDp", + MinSigned(_) => "MinSigned", + MaxSigned(_) => "MaxSigned", + MinUnsigned(_) => "MinUnsigned", + MaxUnsigned(_) => "MaxUnsigned", CmpE(_) => "CmpE", CmpNe(_) => "CmpNe", CmpSlt(_) => "CmpSlt", @@ -258,6 +267,7 @@ impl HighLevelILLiftedInstruction { Ctz(_) => "Ctz", Rbit(_) => "Rbit", Cls(_) => "Cls", + Abs(_) => "Abs", Sx(_) => "Sx", Zx(_) => "Zx", LowPart(_) => "LowPart", @@ -319,7 +329,8 @@ impl HighLevelILLiftedInstruction { ], Add(op) | Sub(op) | And(op) | Or(op) | Xor(op) | Lsl(op) | Lsr(op) | Asr(op) | Rol(op) | Ror(op) | Mul(op) | MuluDp(op) | MulsDp(op) | Divu(op) | DivuDp(op) - | Divs(op) | DivsDp(op) | Modu(op) | ModuDp(op) | Mods(op) | ModsDp(op) | CmpE(op) + | Divs(op) | DivsDp(op) | Modu(op) | ModuDp(op) | Mods(op) | ModsDp(op) + | MinSigned(op) | MaxSigned(op) | MinUnsigned(op) | MaxUnsigned(op) | CmpE(op) | CmpNe(op) | CmpSlt(op) | CmpUlt(op) | CmpSle(op) | CmpUle(op) | CmpSge(op) | CmpUge(op) | CmpSgt(op) | CmpUgt(op) | TestBit(op) | AddOverflow(op) | Fadd(op) | Fsub(op) | Fmul(op) | Fdiv(op) | FcmpE(op) | FcmpNe(op) | FcmpLt(op) | FcmpLe(op) @@ -377,7 +388,7 @@ impl HighLevelILLiftedInstruction { Operand::ConstantData(op.constant_data.clone()), )], Deref(op) | AddressOf(op) | PassByRef(op) | ReturnByRef(op) | Neg(op) | Not(op) - | Bswap(op) | Popcnt(op) | Clz(op) | Ctz(op) | Rbit(op) | Cls(op) + | Bswap(op) | Popcnt(op) | Clz(op) | Ctz(op) | Rbit(op) | Cls(op) | Abs(op) | Sx(op) | Zx(op) | LowPart(op) | BoolToInt(op) | UnimplMem(op) | Fsqrt(op) | Fneg(op) | Fabs(op) | FloatToInt(op) | IntToFloat(op) | FloatConv(op) | RoundToInt(op) | Floor(op) | Ceil(op) | Ftrunc(op) => { diff --git a/rust/src/low_level_il/expression.rs b/rust/src/low_level_il/expression.rs index 92d57675..83e93375 100644 --- a/rust/src/low_level_il/expression.rs +++ b/rust/src/low_level_il/expression.rs @@ -315,6 +315,13 @@ where Ctz(Operation<'func, M, F, operation::UnaryOp>), Rbit(Operation<'func, M, F, operation::UnaryOp>), Cls(Operation<'func, M, F, operation::UnaryOp>), + + MinSigned(Operation<'func, M, F, operation::BinaryOp>), + MaxSigned(Operation<'func, M, F, operation::BinaryOp>), + MinUnsigned(Operation<'func, M, F, operation::BinaryOp>), + MaxUnsigned(Operation<'func, M, F, operation::BinaryOp>), + Abs(Operation<'func, M, F, operation::UnaryOp>), + Sx(Operation<'func, M, F, operation::UnaryOp>), Zx(Operation<'func, M, F, operation::UnaryOp>), LowPart(Operation<'func, M, F, operation::UnaryOp>), @@ -479,6 +486,12 @@ where LLIL_RBIT => LowLevelILExpressionKind::Rbit(Operation::new(function, op, index)), LLIL_CLS => LowLevelILExpressionKind::Cls(Operation::new(function, op, index)), + LLIL_MINS => LowLevelILExpressionKind::MinSigned(Operation::new(function, op, index)), + LLIL_MAXS => LowLevelILExpressionKind::MaxSigned(Operation::new(function, op, index)), + LLIL_MINU => LowLevelILExpressionKind::MinUnsigned(Operation::new(function, op, index)), + LLIL_MAXU => LowLevelILExpressionKind::MaxUnsigned(Operation::new(function, op, index)), + LLIL_ABS => LowLevelILExpressionKind::Abs(Operation::new(function, op, index)), + LLIL_SX => LowLevelILExpressionKind::Sx(Operation::new(function, op, index)), LLIL_ZX => LowLevelILExpressionKind::Zx(Operation::new(function, op, index)), LLIL_LOW_PART => LowLevelILExpressionKind::LowPart(Operation::new(function, op, index)), @@ -614,7 +627,8 @@ where | Lsr(ref op) | Asr(ref op) | Rol(ref op) | Ror(ref op) | Mul(ref op) | MulsDp(ref op) | MuluDp(ref op) | Divu(ref op) | Divs(ref op) | Modu(ref op) | Mods(ref op) | Fadd(ref op) | Fsub(ref op) | Fmul(ref op) | Fdiv(ref op) - | DivuDp(ref op) | DivsDp(ref op) | ModuDp(ref op) | ModsDp(ref op) => Some(op), + | DivuDp(ref op) | DivsDp(ref op) | ModuDp(ref op) | ModsDp(ref op) + | MinSigned(ref op) | MaxSigned(ref op) | MinUnsigned(ref op) | MaxUnsigned(ref op) => Some(op), _ => None, } } @@ -633,7 +647,7 @@ where match *self { Neg(ref op) | Not(ref op) | Bswap(ref op) | Popcnt(ref op) | Clz(ref op) | Ctz(ref op) - | Rbit(ref op) | Cls(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref op) + | Rbit(ref op) | Cls(ref op) | Abs(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref op) | BoolToInt(ref op) | Fsqrt(ref op) | Fneg(ref op) | Fabs(ref op) | FloatToInt(ref op) | IntToFloat(ref op) | FloatConv(ref op) | RoundToInt(ref op) | Floor(ref op) | Ceil(ref op) | Ftrunc(ref op) => Some(op), @@ -673,12 +687,13 @@ where | Mul(ref op) | MulsDp(ref op) | MuluDp(ref op) | Divu(ref op) | Divs(ref op) | Modu(ref op) | Mods(ref op) | Fadd(ref op) | Fsub(ref op) | Fmul(ref op) | DivuDp(ref op) | DivsDp(ref op) | ModuDp(ref op) | ModsDp(ref op) | Fdiv(ref op) + | MinSigned(ref op) | MaxSigned(ref op) | MinUnsigned(ref op) | MaxUnsigned(ref op) | TestBit(ref op) => { visit!(op.left()); visit!(op.right()); } Neg(ref op) | Not(ref op) | Bswap(ref op) | Popcnt(ref op) | Clz(ref op) | Ctz(ref op) - | Rbit(ref op) | Cls(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref op) + | Rbit(ref op) | Cls(ref op) | Abs(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref op) | BoolToInt(ref op) | Fsqrt(ref op) | Fneg(ref op) | Fabs(ref op) | FloatToInt(ref op) | IntToFloat(ref op) | FloatConv(ref op) | RoundToInt(ref op) | Floor(ref op) | Ceil(ref op) | Ftrunc(ref op) => { @@ -768,12 +783,13 @@ where | Xor(ref op) | Lsl(ref op) | Lsr(ref op) | Asr(ref op) | Rol(ref op) | Ror(ref op) | Mul(ref op) | MulsDp(ref op) | MuluDp(ref op) | Divu(ref op) | Divs(ref op) | Modu(ref op) | Mods(ref op) | Fadd(ref op) | Fsub(ref op) | Fmul(ref op) + | MinSigned(ref op) | MaxSigned(ref op) | MinUnsigned(ref op) | MaxUnsigned(ref op) | Fdiv(ref op) | TestBit(ref op) => &op.op, DivuDp(ref op) | DivsDp(ref op) | ModuDp(ref op) | ModsDp(ref op) => &op.op, Neg(ref op) | Not(ref op) | Bswap(ref op) | Popcnt(ref op) | Clz(ref op) | Ctz(ref op) - | Rbit(ref op) | Cls(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref op) + | Rbit(ref op) | Cls(ref op) | Abs(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref op) | BoolToInt(ref op) | Fsqrt(ref op) | Fneg(ref op) | Fabs(ref op) | FloatToInt(ref op) | IntToFloat(ref op) | FloatConv(ref op) | RoundToInt(ref op) | Floor(ref op) | Ceil(ref op) | Ftrunc(ref op) => &op.op, @@ -842,12 +858,13 @@ impl LowLevelILExpressionKind<'_, Mutable, NonSSA> { | Xor(ref op) | Lsl(ref op) | Lsr(ref op) | Asr(ref op) | Rol(ref op) | Ror(ref op) | Mul(ref op) | MulsDp(ref op) | MuluDp(ref op) | Divu(ref op) | Divs(ref op) | Modu(ref op) | Mods(ref op) | Fadd(ref op) | Fsub(ref op) | Fmul(ref op) + | MinSigned(ref op) | MaxSigned(ref op) | MinUnsigned(ref op) | MaxUnsigned(ref op) | Fdiv(ref op) | TestBit(ref op) => op.flag_write(), DivuDp(ref op) | DivsDp(ref op) | ModuDp(ref op) | ModsDp(ref op) => op.flag_write(), Neg(ref op) | Not(ref op) | Bswap(ref op) | Popcnt(ref op) | Clz(ref op) | Ctz(ref op) - | Rbit(ref op) | Cls(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref op) + | Rbit(ref op) | Cls(ref op) | Abs(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref op) | BoolToInt(ref op) | Fsqrt(ref op) | Fneg(ref op) | Fabs(ref op) | FloatToInt(ref op) | IntToFloat(ref op) | FloatConv(ref op) | RoundToInt(ref op) | Floor(ref op) | Ceil(ref op) | Ftrunc(ref op) => op.flag_write(), diff --git a/rust/src/low_level_il/lifting.rs b/rust/src/low_level_il/lifting.rs index ebd6e980..dcbc5198 100644 --- a/rust/src/low_level_il/lifting.rs +++ b/rust/src/low_level_il/lifting.rs @@ -100,6 +100,7 @@ pub enum LowLevelILFlagWriteOp<R: ArchReg> { Ctz(usize, LowLevelILRegisterOrConstant<R>), Rbit(usize, LowLevelILRegisterOrConstant<R>), Cls(usize, LowLevelILRegisterOrConstant<R>), + Abs(usize, LowLevelILRegisterOrConstant<R>), Sx(usize, LowLevelILRegisterOrConstant<R>), Zx(usize, LowLevelILRegisterOrConstant<R>), LowPart(usize, LowLevelILRegisterOrConstant<R>), @@ -187,6 +188,26 @@ pub enum LowLevelILFlagWriteOp<R: ArchReg> { LowLevelILRegisterOrConstant<R>, LowLevelILRegisterOrConstant<R>, ), + MinSigned( + usize, + LowLevelILRegisterOrConstant<R>, + LowLevelILRegisterOrConstant<R>, + ), + MaxSigned( + usize, + LowLevelILRegisterOrConstant<R>, + LowLevelILRegisterOrConstant<R>, + ), + MinUnsigned( + usize, + LowLevelILRegisterOrConstant<R>, + LowLevelILRegisterOrConstant<R>, + ), + MaxUnsigned( + usize, + LowLevelILRegisterOrConstant<R>, + LowLevelILRegisterOrConstant<R>, + ), DivuDp( usize, LowLevelILRegisterOrConstant<R>, @@ -305,6 +326,7 @@ impl<R: ArchReg> LowLevelILFlagWriteOp<R> { (1, LLIL_CTZ) => op!(Ctz, 0), (1, LLIL_RBIT) => op!(Rbit, 0), (1, LLIL_CLS) => op!(Cls, 0), + (1, LLIL_ABS) => op!(Abs, 0), (1, LLIL_SX) => op!(Sx, 0), (1, LLIL_ZX) => op!(Zx, 0), (1, LLIL_LOW_PART) => op!(LowPart, 0), @@ -328,6 +350,10 @@ impl<R: ArchReg> LowLevelILFlagWriteOp<R> { (2, LLIL_DIVS) => op!(Divs, 0, 1), (2, LLIL_MODU) => op!(Modu, 0, 1), (2, LLIL_MODS) => op!(Mods, 0, 1), + (2, LLIL_MINS) => op!(MinSigned, 0, 1), + (2, LLIL_MAXS) => op!(MaxSigned, 0, 1), + (2, LLIL_MINU) => op!(MinUnsigned, 0, 1), + (2, LLIL_MAXU) => op!(MaxUnsigned, 0, 1), (2, LLIL_DIVU_DP) => op!(DivuDp, 0, 1), (2, LLIL_DIVS_DP) => op!(DivsDp, 0, 1), (2, LLIL_MODU_DP) => op!(ModuDp, 0, 1), @@ -369,6 +395,7 @@ impl<R: ArchReg> LowLevelILFlagWriteOp<R> { Ctz(size, ..) => (size, LLIL_CTZ), Rbit(size, ..) => (size, LLIL_RBIT), Cls(size, ..) => (size, LLIL_CLS), + Abs(size, ..) => (size, LLIL_ABS), Sx(size, ..) => (size, LLIL_SX), Zx(size, ..) => (size, LLIL_ZX), LowPart(size, ..) => (size, LLIL_LOW_PART), @@ -392,6 +419,10 @@ impl<R: ArchReg> LowLevelILFlagWriteOp<R> { Divs(size, ..) => (size, LLIL_DIVS), Modu(size, ..) => (size, LLIL_MODU), Mods(size, ..) => (size, LLIL_MODS), + MinSigned(size, ..) => (size, LLIL_MINS), + MaxSigned(size, ..) => (size, LLIL_MAXS), + MinUnsigned(size, ..) => (size, LLIL_MINU), + MaxUnsigned(size, ..) => (size, LLIL_MAXU), DivuDp(size, ..) => (size, LLIL_DIVU_DP), DivsDp(size, ..) => (size, LLIL_DIVS_DP), ModuDp(size, ..) => (size, LLIL_MODU_DP), @@ -428,6 +459,7 @@ impl<R: ArchReg> LowLevelILFlagWriteOp<R> { | Ctz(_, op0) | Rbit(_, op0) | Cls(_, op0) + | Abs(_, op0) | Sx(_, op0) | Zx(_, op0) | LowPart(_, op0) @@ -456,6 +488,10 @@ impl<R: ArchReg> LowLevelILFlagWriteOp<R> { | Divs(_, op0, op1) | Modu(_, op0, op1) | Mods(_, op0, op1) + | MinSigned(_, op0, op1) + | MaxSigned(_, op0, op1) + | MinUnsigned(_, op0, op1) + | MaxUnsigned(_, op0, op1) | DivuDp(_, op0, op1) | DivsDp(_, op0, op1) | ModuDp(_, op0, op1) @@ -1452,6 +1488,7 @@ impl LowLevelILMutableFunction { sized_unary_op_lifter!(ctz, LLIL_CTZ, ValueExpr); sized_unary_op_lifter!(rbit, LLIL_RBIT, ValueExpr); sized_unary_op_lifter!(cls, LLIL_CLS, ValueExpr); + sized_unary_op_lifter!(abs, LLIL_ABS, ValueExpr); size_changing_unary_op_lifter!(sx, LLIL_SX, ValueExpr); size_changing_unary_op_lifter!(zx, LLIL_ZX, ValueExpr); @@ -1478,6 +1515,10 @@ impl LowLevelILMutableFunction { binary_op_lifter!(divu, LLIL_DIVU); binary_op_lifter!(mods, LLIL_MODS); binary_op_lifter!(modu, LLIL_MODU); + binary_op_lifter!(min_signed, LLIL_MINS); + binary_op_lifter!(max_signed, LLIL_MAXS); + binary_op_lifter!(min_unsigned, LLIL_MINU); + binary_op_lifter!(max_unsigned, LLIL_MAXU); binary_op_carry_lifter!(adc, LLIL_ADC); binary_op_carry_lifter!(sbb, LLIL_SBB); diff --git a/rust/src/medium_level_il/instruction.rs b/rust/src/medium_level_il/instruction.rs index 77a0be27..69936e60 100644 --- a/rust/src/medium_level_il/instruction.rs +++ b/rust/src/medium_level_il/instruction.rs @@ -334,6 +334,22 @@ impl MediumLevelILInstruction { left: MediumLevelExpressionIndex::from(op.operands[0]), right: MediumLevelExpressionIndex::from(op.operands[1]), }), + MLIL_MINS => Op::MinSigned(BinaryOp { + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), + }), + MLIL_MAXS => Op::MaxSigned(BinaryOp { + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), + }), + MLIL_MINU => Op::MinUnsigned(BinaryOp { + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), + }), + MLIL_MAXU => Op::MaxUnsigned(BinaryOp { + left: MediumLevelExpressionIndex::from(op.operands[0]), + right: MediumLevelExpressionIndex::from(op.operands[1]), + }), MLIL_CMP_E => Op::CmpE(BinaryOp { left: MediumLevelExpressionIndex::from(op.operands[0]), right: MediumLevelExpressionIndex::from(op.operands[1]), @@ -593,6 +609,9 @@ impl MediumLevelILInstruction { MLIL_CLS => Op::Cls(UnaryOp { src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), + MLIL_ABS => Op::Abs(UnaryOp { + src: MediumLevelExpressionIndex::from(op.operands[0] as usize), + }), MLIL_SX => Op::Sx(UnaryOp { src: MediumLevelExpressionIndex::from(op.operands[0] as usize), }), @@ -941,6 +960,10 @@ impl MediumLevelILInstruction { ModuDp(op) => Lifted::ModuDp(self.lift_binary_op(op)), Mods(op) => Lifted::Mods(self.lift_binary_op(op)), ModsDp(op) => Lifted::ModsDp(self.lift_binary_op(op)), + MinSigned(op) => Lifted::MinSigned(self.lift_binary_op(op)), + MaxSigned(op) => Lifted::MaxSigned(self.lift_binary_op(op)), + MinUnsigned(op) => Lifted::MinUnsigned(self.lift_binary_op(op)), + MaxUnsigned(op) => Lifted::MaxUnsigned(self.lift_binary_op(op)), CmpE(op) => Lifted::CmpE(self.lift_binary_op(op)), CmpNe(op) => Lifted::CmpNe(self.lift_binary_op(op)), CmpSlt(op) => Lifted::CmpSlt(self.lift_binary_op(op)), @@ -1123,6 +1146,7 @@ impl MediumLevelILInstruction { Ctz(op) => Lifted::Ctz(self.lift_unary_op(op)), Rbit(op) => Lifted::Rbit(self.lift_unary_op(op)), Cls(op) => Lifted::Cls(self.lift_unary_op(op)), + Abs(op) => Lifted::Abs(self.lift_unary_op(op)), Sx(op) => Lifted::Sx(self.lift_unary_op(op)), Zx(op) => Lifted::Zx(self.lift_unary_op(op)), LowPart(op) => Lifted::LowPart(self.lift_unary_op(op)), @@ -1843,6 +1867,10 @@ pub enum MediumLevelILInstructionKind { ModuDp(BinaryOp), Mods(BinaryOp), ModsDp(BinaryOp), + MinSigned(BinaryOp), + MaxSigned(BinaryOp), + MinUnsigned(BinaryOp), + MaxUnsigned(BinaryOp), CmpE(BinaryOp), CmpNe(BinaryOp), CmpSlt(BinaryOp), @@ -1904,6 +1932,7 @@ pub enum MediumLevelILInstructionKind { Ctz(UnaryOp), Rbit(UnaryOp), Cls(UnaryOp), + Abs(UnaryOp), Sx(UnaryOp), Zx(UnaryOp), LowPart(UnaryOp), diff --git a/rust/src/medium_level_il/lift.rs b/rust/src/medium_level_il/lift.rs index 2f0d6653..f886d93a 100644 --- a/rust/src/medium_level_il/lift.rs +++ b/rust/src/medium_level_il/lift.rs @@ -102,6 +102,10 @@ pub enum MediumLevelILLiftedInstructionKind { ModuDp(LiftedBinaryOp), Mods(LiftedBinaryOp), ModsDp(LiftedBinaryOp), + MinSigned(LiftedBinaryOp), + MaxSigned(LiftedBinaryOp), + MinUnsigned(LiftedBinaryOp), + MaxUnsigned(LiftedBinaryOp), CmpE(LiftedBinaryOp), CmpNe(LiftedBinaryOp), CmpSlt(LiftedBinaryOp), @@ -160,6 +164,7 @@ pub enum MediumLevelILLiftedInstructionKind { Ctz(LiftedUnaryOp), Rbit(LiftedUnaryOp), Cls(LiftedUnaryOp), + Abs(LiftedUnaryOp), Sx(LiftedUnaryOp), Zx(LiftedUnaryOp), LowPart(LiftedUnaryOp), @@ -264,6 +269,10 @@ impl MediumLevelILLiftedInstruction { ModuDp(_) => "ModuDp", Mods(_) => "Mods", ModsDp(_) => "ModsDp", + MinSigned(_) => "MinSigned", + MaxSigned(_) => "MaxSigned", + MinUnsigned(_) => "MinUnsigned", + MaxUnsigned(_) => "MaxUnsigned", CmpE(_) => "CmpE", CmpNe(_) => "CmpNe", CmpSlt(_) => "CmpSlt", @@ -325,6 +334,7 @@ impl MediumLevelILLiftedInstruction { Ctz(_) => "Ctz", Rbit(_) => "Rbit", Cls(_) => "Cls", + Abs(_) => "Abs", Sx(_) => "Sx", Zx(_) => "Zx", LowPart(_) => "LowPart", @@ -469,7 +479,8 @@ impl MediumLevelILLiftedInstruction { ], Add(op) | Sub(op) | And(op) | Or(op) | Xor(op) | Lsl(op) | Lsr(op) | Asr(op) | Rol(op) | Ror(op) | Mul(op) | MuluDp(op) | MulsDp(op) | Divu(op) | DivuDp(op) - | Divs(op) | DivsDp(op) | Modu(op) | ModuDp(op) | Mods(op) | ModsDp(op) | CmpE(op) + | Divs(op) | DivsDp(op) | Modu(op) | ModuDp(op) | Mods(op) | ModsDp(op) + | MinSigned(op) | MaxSigned(op) | MinUnsigned(op) | MaxUnsigned(op) | CmpE(op) | CmpNe(op) | CmpSlt(op) | CmpUlt(op) | CmpSle(op) | CmpUle(op) | CmpSge(op) | CmpUge(op) | CmpSgt(op) | CmpUgt(op) | TestBit(op) | AddOverflow(op) | FcmpE(op) | FcmpNe(op) | FcmpLt(op) | FcmpLe(op) | FcmpGe(op) | FcmpGt(op) | FcmpO(op) @@ -555,7 +566,7 @@ impl MediumLevelILLiftedInstruction { ("stack", Operand::Expr(*op.stack.clone())), ], Neg(op) | Not(op) | Bswap(op) | Popcnt(op) | Clz(op) | Ctz(op) | Rbit(op) | Cls(op) - | Sx(op) | Zx(op) | LowPart(op) | BoolToInt(op) | UnimplMem(op) + | Abs(op) | Sx(op) | Zx(op) | LowPart(op) | BoolToInt(op) | UnimplMem(op) | Fsqrt(op) | Fneg(op) | Fabs(op) | FloatToInt(op) | IntToFloat(op) | FloatConv(op) | RoundToInt(op) | Floor(op) | Ceil(op) | Ftrunc(op) | Load(op) => { vec![("src", Operand::Expr(*op.src.clone()))] |
