summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binaryninjaapi.h75
-rw-r--r--binaryninjacore.h30
-rw-r--r--docs/dev/bnil-hlil.md6
-rw-r--r--docs/dev/bnil-llil.md6
-rw-r--r--docs/dev/bnil-mlil.md6
-rw-r--r--highlevelilinstruction.cpp60
-rw-r--r--highlevelilinstruction.h18
-rw-r--r--lang/c/pseudoc.cpp79
-rw-r--r--lang/rust/pseudorust.cpp27
-rw-r--r--lowlevelilinstruction.cpp54
-rw-r--r--lowlevelilinstruction.h18
-rw-r--r--mediumlevelilinstruction.cpp54
-rw-r--r--mediumlevelilinstruction.h18
-rw-r--r--python/highlevelil.py44
-rw-r--r--python/lowlevelil.py44
-rw-r--r--python/mediumlevelil.py44
-rw-r--r--rust/src/high_level_il/instruction.rs30
-rw-r--r--rust/src/high_level_il/lift.rs13
-rw-r--r--rust/src/low_level_il/expression.rs24
-rw-r--r--rust/src/low_level_il/lifting.rs30
-rw-r--r--rust/src/medium_level_il/instruction.rs30
-rw-r--r--rust/src/medium_level_il/lift.rs15
22 files changed, 714 insertions, 11 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index c42a25ba..82da9ea6 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -15006,6 +15006,69 @@ namespace BinaryNinja {
*/
ExprId Not(size_t size, ExprId a, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation());
+ /*! Reverse the byte order 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 byte swap
+ \param flags Flags to set
+ \param loc Optional IL Location this expression was added from.
+ \return The expression <tt>bswap.<size>{<flags>}(value)</tt>
+ */
+ ExprId ByteSwap(size_t size, ExprId a, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation());
+
+ /*! Count the number of set bits in expression \c value of size \c size potentially setting flags
+
+ \param size The size of the result in bytes
+ \param a The expression to count set bits in
+ \param flags Flags to set
+ \param loc Optional IL Location this expression was added from.
+ \return The expression <tt>popcnt.<size>{<flags>}(value)</tt>
+ */
+ ExprId PopulationCount(size_t size, ExprId a, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation());
+
+ /*! Count the number of leading zero bits in expression \c value of size \c size potentially setting flags.
+ The result is <tt>8 * size</tt> when \c value is zero.
+
+ \param size The size of the result in bytes
+ \param a The expression to count leading zeros in
+ \param flags Flags to set
+ \param loc Optional IL Location this expression was added from.
+ \return The expression <tt>clz.<size>{<flags>}(value)</tt>
+ */
+ ExprId CountLeadingZeros(size_t size, ExprId a, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation());
+
+ /*! Count the number of trailing zero bits in expression \c value of size \c size potentially setting flags.
+ The result is <tt>8 * size</tt> when \c value is zero.
+
+ \param size The size of the result in bytes
+ \param a The expression to count trailing zeros in
+ \param flags Flags to set
+ \param loc Optional IL Location this expression was added from.
+ \return The expression <tt>ctz.<size>{<flags>}(value)</tt>
+ */
+ ExprId CountTrailingZeros(size_t size, ExprId a, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation());
+
+ /*! Reverse the bit order 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 bit reverse
+ \param flags Flags to set
+ \param loc Optional IL Location this expression was added from.
+ \return The expression <tt>rbit.<size>{<flags>}(value)</tt>
+ */
+ ExprId ReverseBits(size_t size, ExprId a, uint32_t flags = 0, const ILSourceLocation& loc = ILSourceLocation());
+
+ /*! Count the number of leading bits that match the sign bit in expression \c value of size \c size,
+ not counting the sign bit itself, potentially setting flags
+
+ \param size The size of the result in bytes
+ \param a The expression to count leading sign bits in
+ \param flags Flags to set
+ \param loc Optional IL Location this expression was added from.
+ \return The expression <tt>cls.<size>{<flags>}(value)</tt>
+ */
+ ExprId CountLeadingSigns(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
@@ -15886,6 +15949,12 @@ namespace BinaryNinja {
size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation());
ExprId Neg(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
ExprId Not(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
+ ExprId ByteSwap(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
+ ExprId PopulationCount(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
+ ExprId CountLeadingZeros(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
+ 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 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());
@@ -16287,6 +16356,12 @@ namespace BinaryNinja {
size_t size, ExprId left, ExprId right, const ILSourceLocation& loc = ILSourceLocation());
ExprId Neg(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
ExprId Not(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
+ ExprId ByteSwap(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
+ ExprId PopulationCount(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
+ ExprId CountLeadingZeros(size_t size, ExprId src, const ILSourceLocation& loc = ILSourceLocation());
+ 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 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 d09690e5..428d7f82 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -762,7 +762,15 @@ extern "C"
LLIL_REG_PHI,
LLIL_REG_STACK_PHI,
LLIL_FLAG_PHI,
- LLIL_MEM_PHI
+ LLIL_MEM_PHI,
+
+ // Bit manipulation
+ LLIL_BSWAP, // Reverse byte order of the whole value
+ LLIL_POPCNT, // Population count (number of set bits)
+ 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
};
BN_ENUM(uint8_t, BNLowLevelILFlagCondition)
@@ -1540,7 +1548,15 @@ extern "C"
MLIL_VAR_PHI,
MLIL_MEM_PHI,
- MLIL_BLOCK_TO_EXPAND // Must be expanded by a future workflow step, used temporarily to insert instructions
+ MLIL_BLOCK_TO_EXPAND, // Must be expanded by a future workflow step, used temporarily to insert instructions
+
+ // Bit manipulation
+ MLIL_BSWAP, // Reverse byte order of the whole value
+ MLIL_POPCNT, // Population count (number of set bits)
+ 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
};
typedef struct BNMediumLevelILInstruction
@@ -1714,7 +1730,15 @@ extern "C"
HLIL_SYSCALL_SSA,
HLIL_INTRINSIC_SSA,
HLIL_VAR_PHI,
- HLIL_MEM_PHI
+ HLIL_MEM_PHI,
+
+ // Bit manipulation
+ HLIL_BSWAP, // Reverse byte order of the whole value
+ HLIL_POPCNT, // Population count (number of set bits)
+ 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
};
typedef struct BNHighLevelILInstruction
diff --git a/docs/dev/bnil-hlil.md b/docs/dev/bnil-hlil.md
index 03447eab..1b2754e1 100644
--- a/docs/dev/bnil-hlil.md
+++ b/docs/dev/bnil-hlil.md
@@ -111,6 +111,12 @@ There are a number of properties that can be queried on the [`HighLevelILInstruc
* `HLIL_MODS_DP` - Signed double-precision modulus of `left` expression by the `right` expression
* `HLIL_NEG` - Sign inversion of `src` expression
* `HLIL_NOT` - Bitwise inversion of `src` expression
+* `HLIL_BSWAP` - Reverse the byte order of `src` expression
+* `HLIL_POPCNT` - Population count (number of set bits) of `src` expression
+* `HLIL_CLZ` - Count leading zero bits of `src` expression; the result is `8 * size` when `src` is zero
+* `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_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 5509151e..b3a4f906 100644
--- a/docs/dev/bnil-llil.md
+++ b/docs/dev/bnil-llil.md
@@ -257,6 +257,12 @@ The double precision instruction multiply, divide, modulus instructions are part
* `LLIL_MODS_DP` - Signed modulus double precision
* `LLIL_NEG` - Sign negation
* `LLIL_NOT` - Bitwise complement
+* `LLIL_BSWAP` - Reverse the byte order of `src`
+* `LLIL_POPCNT` - Population count (number of set bits) of `src`
+* `LLIL_CLZ` - Count leading zero bits of `src`; the result is `8 * size` when `src` is zero
+* `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_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 51028131..8e796ec8 100644
--- a/docs/dev/bnil-mlil.md
+++ b/docs/dev/bnil-mlil.md
@@ -348,6 +348,12 @@ The parameter list can be accessed through the `params` property:
* `MLIL_MODS_DP` - Signed double-precision modulus of `left` expression by the `right` expression
* `MLIL_NEG` - Sign inversion of `src` expression
* `MLIL_NOT` - Bitwise inversion of `src` expression
+* `MLIL_BSWAP` - Reverse the byte order of `src` expression
+* `MLIL_POPCNT` - Population count (number of set bits) of `src` expression
+* `MLIL_CLZ` - Count leading zero bits of `src` expression; the result is `8 * size` when `src` is zero
+* `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_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 0ce32c27..92312549 100644
--- a/highlevelilinstruction.cpp
+++ b/highlevelilinstruction.cpp
@@ -260,6 +260,12 @@ static constexpr std::array s_instructionOperandUsage = {
OperandUsage{HLIL_INTRINSIC_SSA, {IntrinsicHighLevelOperandUsage, ParameterExprsHighLevelOperandUsage, DestMemoryVersionHighLevelOperandUsage, SourceMemoryVersionHighLevelOperandUsage}},
OperandUsage{HLIL_VAR_PHI, {DestSSAVariableHighLevelOperandUsage, SourceSSAVariablesHighLevelOperandUsage}},
OperandUsage{HLIL_MEM_PHI, {DestMemoryVersionHighLevelOperandUsage, SourceMemoryVersionsHighLevelOperandUsage}},
+ OperandUsage{HLIL_BSWAP, {SourceExprHighLevelOperandUsage}},
+ OperandUsage{HLIL_POPCNT, {SourceExprHighLevelOperandUsage}},
+ OperandUsage{HLIL_CLZ, {SourceExprHighLevelOperandUsage}},
+ OperandUsage{HLIL_CTZ, {SourceExprHighLevelOperandUsage}},
+ OperandUsage{HLIL_RBIT, {SourceExprHighLevelOperandUsage}},
+ OperandUsage{HLIL_CLS, {SourceExprHighLevelOperandUsage}},
};
@@ -1261,6 +1267,12 @@ void HighLevelILInstruction::CollectSubExprs(stack<size_t>& toProcess) const
case HLIL_ADDRESS_OF:
case HLIL_NEG:
case HLIL_NOT:
+ case HLIL_BSWAP:
+ case HLIL_POPCNT:
+ case HLIL_CLZ:
+ case HLIL_CTZ:
+ case HLIL_RBIT:
+ case HLIL_CLS:
case HLIL_SX:
case HLIL_ZX:
case HLIL_LOW_PART:
@@ -1569,6 +1581,12 @@ ExprId HighLevelILInstruction::CopyTo(
return dest->Unreachable(loc);
case HLIL_NEG:
case HLIL_NOT:
+ case HLIL_BSWAP:
+ case HLIL_POPCNT:
+ case HLIL_CLZ:
+ case HLIL_CTZ:
+ case HLIL_RBIT:
+ case HLIL_CLS:
case HLIL_SX:
case HLIL_ZX:
case HLIL_LOW_PART:
@@ -2130,6 +2148,12 @@ bool HighLevelILInstruction::operator<(const HighLevelILInstruction& other) cons
case HLIL_DEREF:
case HLIL_NEG:
case HLIL_NOT:
+ case HLIL_BSWAP:
+ case HLIL_POPCNT:
+ case HLIL_CLZ:
+ case HLIL_CTZ:
+ case HLIL_RBIT:
+ case HLIL_CLS:
case HLIL_SX:
case HLIL_ZX:
case HLIL_LOW_PART:
@@ -3097,6 +3121,42 @@ ExprId HighLevelILFunction::Not(size_t size, ExprId src, const ILSourceLocation&
}
+ExprId HighLevelILFunction::ByteSwap(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(HLIL_BSWAP, loc, size, src);
+}
+
+
+ExprId HighLevelILFunction::PopulationCount(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(HLIL_POPCNT, loc, size, src);
+}
+
+
+ExprId HighLevelILFunction::CountLeadingZeros(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(HLIL_CLZ, loc, size, src);
+}
+
+
+ExprId HighLevelILFunction::CountTrailingZeros(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(HLIL_CTZ, loc, size, src);
+}
+
+
+ExprId HighLevelILFunction::ReverseBits(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(HLIL_RBIT, loc, size, src);
+}
+
+
+ExprId HighLevelILFunction::CountLeadingSigns(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(HLIL_CLS, 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 7ec5d18c..4272d2e2 100644
--- a/highlevelilinstruction.h
+++ b/highlevelilinstruction.h
@@ -1454,6 +1454,24 @@ namespace BinaryNinja
struct HighLevelILInstructionAccessor<HLIL_NOT> : public HighLevelILOneOperandInstruction
{};
template <>
+ struct HighLevelILInstructionAccessor<HLIL_BSWAP> : public HighLevelILOneOperandInstruction
+ {};
+ template <>
+ struct HighLevelILInstructionAccessor<HLIL_POPCNT> : public HighLevelILOneOperandInstruction
+ {};
+ template <>
+ struct HighLevelILInstructionAccessor<HLIL_CLZ> : public HighLevelILOneOperandInstruction
+ {};
+ template <>
+ struct HighLevelILInstructionAccessor<HLIL_CTZ> : public HighLevelILOneOperandInstruction
+ {};
+ template <>
+ struct HighLevelILInstructionAccessor<HLIL_RBIT> : public HighLevelILOneOperandInstruction
+ {};
+ template <>
+ struct HighLevelILInstructionAccessor<HLIL_CLS> : public HighLevelILOneOperandInstruction
+ {};
+ template <>
struct HighLevelILInstructionAccessor<HLIL_SX> : public HighLevelILOneOperandInstruction
{};
template <>
diff --git a/lang/c/pseudoc.cpp b/lang/c/pseudoc.cpp
index 35966230..dc37100e 100644
--- a/lang/c/pseudoc.cpp
+++ b/lang/c/pseudoc.cpp
@@ -2411,6 +2411,85 @@ void PseudoCFunction::GetExprTextInternal(const HighLevelILInstruction& instr, H
}();
break;
+ case HLIL_BSWAP:
+ [&]() {
+ auto src = instr.GetSourceExpr<HLIL_BSWAP>();
+ string name;
+ if (src.size == 2)
+ name = "__builtin_bswap16";
+ else if (src.size == 4)
+ name = "__builtin_bswap32";
+ else if (src.size == 8)
+ name = "__builtin_bswap64";
+ else
+ name = "__builtin_bswap";
+ tokens.Append(OperationToken, name);
+ tokens.AppendOpenParen();
+ GetExprTextInternal(src, tokens, settings);
+ tokens.AppendCloseParen();
+ if (statement)
+ tokens.AppendSemicolon();
+ }();
+ break;
+
+ case HLIL_POPCNT:
+ [&]() {
+ auto src = instr.GetSourceExpr<HLIL_POPCNT>();
+ tokens.Append(OperationToken, src.size > 4 ? "__builtin_popcountll" : "__builtin_popcount");
+ tokens.AppendOpenParen();
+ GetExprTextInternal(src, tokens, settings);
+ tokens.AppendCloseParen();
+ if (statement)
+ tokens.AppendSemicolon();
+ }();
+ break;
+
+ case HLIL_CLZ:
+ [&]() {
+ auto src = instr.GetSourceExpr<HLIL_CLZ>();
+ tokens.Append(OperationToken, src.size > 4 ? "__builtin_clzll" : "__builtin_clz");
+ tokens.AppendOpenParen();
+ GetExprTextInternal(src, tokens, settings);
+ tokens.AppendCloseParen();
+ if (statement)
+ tokens.AppendSemicolon();
+ }();
+ break;
+
+ case HLIL_CTZ:
+ [&]() {
+ auto src = instr.GetSourceExpr<HLIL_CTZ>();
+ tokens.Append(OperationToken, src.size > 4 ? "__builtin_ctzll" : "__builtin_ctz");
+ tokens.AppendOpenParen();
+ GetExprTextInternal(src, tokens, settings);
+ tokens.AppendCloseParen();
+ if (statement)
+ tokens.AppendSemicolon();
+ }();
+ break;
+
+ case HLIL_RBIT:
+ [&]() {
+ tokens.Append(OperationToken, "__rbit");
+ tokens.AppendOpenParen();
+ GetExprTextInternal(instr.GetSourceExpr<HLIL_RBIT>(), tokens, settings);
+ tokens.AppendCloseParen();
+ if (statement)
+ tokens.AppendSemicolon();
+ }();
+ break;
+
+ case HLIL_CLS:
+ [&]() {
+ tokens.Append(OperationToken, "__cls");
+ tokens.AppendOpenParen();
+ GetExprTextInternal(instr.GetSourceExpr<HLIL_CLS>(), 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 2e233550..de1acae1 100644
--- a/lang/rust/pseudorust.cpp
+++ b/lang/rust/pseudorust.cpp
@@ -2428,6 +2428,33 @@ void PseudoRustFunction::GetExprText(const HighLevelILInstruction& instr, HighLe
}();
break;
+ case HLIL_BSWAP:
+ case HLIL_POPCNT:
+ case HLIL_CLZ:
+ case HLIL_CTZ:
+ case HLIL_RBIT:
+ case HLIL_CLS:
+ [&]() {
+ const char* method;
+ switch (instr.operation)
+ {
+ case HLIL_BSWAP: method = "swap_bytes"; break;
+ case HLIL_POPCNT: method = "count_ones"; break;
+ case HLIL_CLZ: method = "leading_zeros"; break;
+ case HLIL_CTZ: method = "trailing_zeros"; break;
+ case HLIL_RBIT: method = "reverse_bits"; break;
+ default: method = "leading_sign_bits"; break;
+ }
+ GetExprText(instr.GetSourceExpr(), tokens, settings, MemberAndFunctionOperatorPrecedence);
+ tokens.Append(TextToken, ".");
+ tokens.Append(OperationToken, method);
+ tokens.AppendOpenParen();
+ 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 228e8328..5a100080 100644
--- a/lowlevelilinstruction.cpp
+++ b/lowlevelilinstruction.cpp
@@ -332,6 +332,12 @@ static constexpr std::array s_instructionOperandUsage = {
OperandUsage{LLIL_REG_STACK_PHI, {DestSSARegisterStackLowLevelOperandUsage, SourceSSARegisterStacksLowLevelOperandUsage}},
OperandUsage{LLIL_FLAG_PHI, {DestSSAFlagLowLevelOperandUsage, SourceSSAFlagsLowLevelOperandUsage}},
OperandUsage{LLIL_MEM_PHI, {DestMemoryVersionLowLevelOperandUsage, SourceMemoryVersionsLowLevelOperandUsage}},
+ OperandUsage{LLIL_BSWAP, {SourceExprLowLevelOperandUsage}},
+ OperandUsage{LLIL_POPCNT, {SourceExprLowLevelOperandUsage}},
+ OperandUsage{LLIL_CLZ, {SourceExprLowLevelOperandUsage}},
+ OperandUsage{LLIL_CTZ, {SourceExprLowLevelOperandUsage}},
+ OperandUsage{LLIL_RBIT, {SourceExprLowLevelOperandUsage}},
+ OperandUsage{LLIL_CLS, {SourceExprLowLevelOperandUsage}},
};
@@ -1984,6 +1990,12 @@ void LowLevelILInstruction::VisitExprs(bn::base::function_ref<bool(const LowLeve
case LLIL_PUSH:
case LLIL_NEG:
case LLIL_NOT:
+ case LLIL_BSWAP:
+ case LLIL_POPCNT:
+ case LLIL_CLZ:
+ case LLIL_CTZ:
+ case LLIL_RBIT:
+ case LLIL_CLS:
case LLIL_SX:
case LLIL_ZX:
case LLIL_LOW_PART:
@@ -2301,6 +2313,12 @@ ExprId LowLevelILInstruction::CopyTo(
case LLIL_PUSH:
case LLIL_NEG:
case LLIL_NOT:
+ case LLIL_BSWAP:
+ case LLIL_POPCNT:
+ case LLIL_CLZ:
+ case LLIL_CTZ:
+ case LLIL_RBIT:
+ case LLIL_CLS:
case LLIL_SX:
case LLIL_ZX:
case LLIL_LOW_PART:
@@ -3352,6 +3370,42 @@ ExprId LowLevelILFunction::Not(size_t size, ExprId a, uint32_t flags, const ILSo
}
+ExprId LowLevelILFunction::ByteSwap(size_t size, ExprId a, uint32_t flags, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(LLIL_BSWAP, loc, size, flags, a);
+}
+
+
+ExprId LowLevelILFunction::PopulationCount(size_t size, ExprId a, uint32_t flags, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(LLIL_POPCNT, loc, size, flags, a);
+}
+
+
+ExprId LowLevelILFunction::CountLeadingZeros(size_t size, ExprId a, uint32_t flags, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(LLIL_CLZ, loc, size, flags, a);
+}
+
+
+ExprId LowLevelILFunction::CountTrailingZeros(size_t size, ExprId a, uint32_t flags, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(LLIL_CTZ, loc, size, flags, a);
+}
+
+
+ExprId LowLevelILFunction::ReverseBits(size_t size, ExprId a, uint32_t flags, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(LLIL_RBIT, loc, size, flags, a);
+}
+
+
+ExprId LowLevelILFunction::CountLeadingSigns(size_t size, ExprId a, uint32_t flags, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(LLIL_CLS, 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 c7bbc7f4..53e10b6c 100644
--- a/lowlevelilinstruction.h
+++ b/lowlevelilinstruction.h
@@ -2054,6 +2054,24 @@ namespace BinaryNinja
struct LowLevelILInstructionAccessor<LLIL_NOT> : public LowLevelILOneOperandInstruction
{};
template <>
+ struct LowLevelILInstructionAccessor<LLIL_BSWAP> : public LowLevelILOneOperandInstruction
+ {};
+ template <>
+ struct LowLevelILInstructionAccessor<LLIL_POPCNT> : public LowLevelILOneOperandInstruction
+ {};
+ template <>
+ struct LowLevelILInstructionAccessor<LLIL_CLZ> : public LowLevelILOneOperandInstruction
+ {};
+ template <>
+ struct LowLevelILInstructionAccessor<LLIL_CTZ> : public LowLevelILOneOperandInstruction
+ {};
+ template <>
+ struct LowLevelILInstructionAccessor<LLIL_RBIT> : public LowLevelILOneOperandInstruction
+ {};
+ template <>
+ struct LowLevelILInstructionAccessor<LLIL_CLS> : public LowLevelILOneOperandInstruction
+ {};
+ template <>
struct LowLevelILInstructionAccessor<LLIL_SX> : public LowLevelILOneOperandInstruction
{};
template <>
diff --git a/mediumlevelilinstruction.cpp b/mediumlevelilinstruction.cpp
index 37a102d8..18610a55 100644
--- a/mediumlevelilinstruction.cpp
+++ b/mediumlevelilinstruction.cpp
@@ -304,6 +304,12 @@ static constexpr std::array s_instructionOperandUsage = {
OperandUsage{MLIL_VAR_PHI, {DestSSAVariableMediumLevelOperandUsage, SourceSSAVariablesMediumLevelOperandUsages}},
OperandUsage{MLIL_MEM_PHI, {DestMemoryVersionMediumLevelOperandUsage, SourceMemoryVersionsMediumLevelOperandUsage}},
OperandUsage{MLIL_BLOCK_TO_EXPAND, {SourceExprsMediumLevelOperandUsage}},
+ OperandUsage{MLIL_BSWAP, {SourceExprMediumLevelOperandUsage}},
+ OperandUsage{MLIL_POPCNT, {SourceExprMediumLevelOperandUsage}},
+ OperandUsage{MLIL_CLZ, {SourceExprMediumLevelOperandUsage}},
+ OperandUsage{MLIL_CTZ, {SourceExprMediumLevelOperandUsage}},
+ OperandUsage{MLIL_RBIT, {SourceExprMediumLevelOperandUsage}},
+ OperandUsage{MLIL_CLS, {SourceExprMediumLevelOperandUsage}},
};
VALIDATE_INSTRUCTION_ORDER(s_instructionOperandUsage);
@@ -1514,6 +1520,12 @@ void MediumLevelILInstruction::VisitExprs(bn::base::function_ref<bool(const Medi
break;
case MLIL_NEG:
case MLIL_NOT:
+ case MLIL_BSWAP:
+ case MLIL_POPCNT:
+ case MLIL_CLZ:
+ case MLIL_CTZ:
+ case MLIL_RBIT:
+ case MLIL_CLS:
case MLIL_SX:
case MLIL_ZX:
case MLIL_LOW_PART:
@@ -1855,6 +1867,12 @@ ExprId MediumLevelILInstruction::CopyTo(MediumLevelILFunction* dest,
GetOffset<MLIL_LOAD_STRUCT_SSA>(), GetSourceMemoryVersion<MLIL_LOAD_STRUCT_SSA>(), loc);
case MLIL_NEG:
case MLIL_NOT:
+ case MLIL_BSWAP:
+ case MLIL_POPCNT:
+ case MLIL_CLZ:
+ case MLIL_CTZ:
+ case MLIL_RBIT:
+ case MLIL_CLS:
case MLIL_SX:
case MLIL_ZX:
case MLIL_LOW_PART:
@@ -2864,6 +2882,42 @@ ExprId MediumLevelILFunction::Not(size_t size, ExprId src, const ILSourceLocatio
}
+ExprId MediumLevelILFunction::ByteSwap(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_BSWAP, loc, size, src);
+}
+
+
+ExprId MediumLevelILFunction::PopulationCount(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_POPCNT, loc, size, src);
+}
+
+
+ExprId MediumLevelILFunction::CountLeadingZeros(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CLZ, loc, size, src);
+}
+
+
+ExprId MediumLevelILFunction::CountTrailingZeros(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CTZ, loc, size, src);
+}
+
+
+ExprId MediumLevelILFunction::ReverseBits(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_RBIT, loc, size, src);
+}
+
+
+ExprId MediumLevelILFunction::CountLeadingSigns(size_t size, ExprId src, const ILSourceLocation& loc)
+{
+ return AddExprWithLocation(MLIL_CLS, 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 3abe363e..41f154ba 100644
--- a/mediumlevelilinstruction.h
+++ b/mediumlevelilinstruction.h
@@ -1786,6 +1786,24 @@ namespace BinaryNinja
struct MediumLevelILInstructionAccessor<MLIL_NOT> : public MediumLevelILOneOperandInstruction
{};
template <>
+ struct MediumLevelILInstructionAccessor<MLIL_BSWAP> : public MediumLevelILOneOperandInstruction
+ {};
+ template <>
+ struct MediumLevelILInstructionAccessor<MLIL_POPCNT> : public MediumLevelILOneOperandInstruction
+ {};
+ template <>
+ struct MediumLevelILInstructionAccessor<MLIL_CLZ> : public MediumLevelILOneOperandInstruction
+ {};
+ template <>
+ struct MediumLevelILInstructionAccessor<MLIL_CTZ> : public MediumLevelILOneOperandInstruction
+ {};
+ template <>
+ struct MediumLevelILInstructionAccessor<MLIL_RBIT> : public MediumLevelILOneOperandInstruction
+ {};
+ template <>
+ struct MediumLevelILInstructionAccessor<MLIL_CLS> : public MediumLevelILOneOperandInstruction
+ {};
+ template <>
struct MediumLevelILInstructionAccessor<MLIL_SX> : public MediumLevelILOneOperandInstruction
{};
template <>
diff --git a/python/highlevelil.py b/python/highlevelil.py
index 4c81f687..bbeb0186 100644
--- a/python/highlevelil.py
+++ b/python/highlevelil.py
@@ -248,7 +248,13 @@ class HighLevelILInstruction(BaseILInstruction):
("left", "expr"), ("right", "expr")
], HighLevelILOperation.HLIL_MODS_DP: [("left", "expr"), ("right", "expr")], HighLevelILOperation.HLIL_NEG: [
("src", "expr")
- ], HighLevelILOperation.HLIL_NOT: [("src", "expr")], HighLevelILOperation.HLIL_SX: [
+ ], HighLevelILOperation.HLIL_NOT: [("src", "expr")], HighLevelILOperation.HLIL_BSWAP: [
+ ("src", "expr")
+ ], HighLevelILOperation.HLIL_POPCNT: [("src", "expr")], HighLevelILOperation.HLIL_CLZ: [
+ ("src", "expr")
+ ], HighLevelILOperation.HLIL_CTZ: [("src", "expr")], HighLevelILOperation.HLIL_RBIT: [
+ ("src", "expr")
+ ], HighLevelILOperation.HLIL_CLS: [("src", "expr")], HighLevelILOperation.HLIL_SX: [
("src", "expr")
], HighLevelILOperation.HLIL_ZX: [("src", "expr")], HighLevelILOperation.HLIL_LOW_PART: [
("src", "expr")
@@ -1984,6 +1990,36 @@ class HighLevelILNot(HighLevelILUnaryBase, Arithmetic):
@dataclass(frozen=True, repr=False, eq=False)
+class HighLevelILBswap(HighLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
+class HighLevelILPopcnt(HighLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
+class HighLevelILClz(HighLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
+class HighLevelILCtz(HighLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
+class HighLevelILRbit(HighLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
+class HighLevelILCls(HighLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
class HighLevelILSx(HighLevelILUnaryBase, Arithmetic):
pass
@@ -2478,6 +2514,12 @@ ILInstruction = {
HighLevelILOperation.HLIL_MODS_DP: HighLevelILModsDp, # ("left", "expr"), ("right", "expr"),
HighLevelILOperation.HLIL_NEG: HighLevelILNeg, # ("src", "expr"),
HighLevelILOperation.HLIL_NOT: HighLevelILNot, # ("src", "expr"),
+ HighLevelILOperation.HLIL_BSWAP: HighLevelILBswap, # ("src", "expr"),
+ HighLevelILOperation.HLIL_POPCNT: HighLevelILPopcnt, # ("src", "expr"),
+ HighLevelILOperation.HLIL_CLZ: HighLevelILClz, # ("src", "expr"),
+ HighLevelILOperation.HLIL_CTZ: HighLevelILCtz, # ("src", "expr"),
+ HighLevelILOperation.HLIL_RBIT: HighLevelILRbit, # ("src", "expr"),
+ HighLevelILOperation.HLIL_CLS: HighLevelILCls, # ("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 714b663d..ce9770f2 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -377,7 +377,13 @@ class LowLevelILInstruction(BaseILInstruction):
("left", "expr"), ("right", "expr")
], LowLevelILOperation.LLIL_MODS_DP: [("left", "expr"), ("right", "expr")], LowLevelILOperation.LLIL_NEG: [
("src", "expr")
- ], LowLevelILOperation.LLIL_NOT: [("src", "expr")], LowLevelILOperation.LLIL_SX: [
+ ], LowLevelILOperation.LLIL_NOT: [("src", "expr")], LowLevelILOperation.LLIL_BSWAP: [
+ ("src", "expr")
+ ], LowLevelILOperation.LLIL_POPCNT: [("src", "expr")], LowLevelILOperation.LLIL_CLZ: [
+ ("src", "expr")
+ ], LowLevelILOperation.LLIL_CTZ: [("src", "expr")], LowLevelILOperation.LLIL_RBIT: [
+ ("src", "expr")
+ ], LowLevelILOperation.LLIL_CLS: [("src", "expr")], LowLevelILOperation.LLIL_SX: [
("src", "expr")
], LowLevelILOperation.LLIL_ZX: [("src", "expr")], LowLevelILOperation.LLIL_LOW_PART: [
("src", "expr")
@@ -1363,6 +1369,36 @@ class LowLevelILNot(LowLevelILUnaryBase, Arithmetic):
@dataclass(frozen=True, repr=False, eq=False)
+class LowLevelILBswap(LowLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
+class LowLevelILPopcnt(LowLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
+class LowLevelILClz(LowLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
+class LowLevelILCtz(LowLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
+class LowLevelILRbit(LowLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
+class LowLevelILCls(LowLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
class LowLevelILSx(LowLevelILUnaryBase, Arithmetic):
pass
@@ -3132,6 +3168,12 @@ ILInstruction:Dict[LowLevelILOperation, LowLevelILInstruction] = { # type: igno
LowLevelILOperation.LLIL_MODS_DP: LowLevelILModsDp, # [("left", "expr"), ("right", "expr")],
LowLevelILOperation.LLIL_NEG: LowLevelILNeg, # [("src", "expr")],
LowLevelILOperation.LLIL_NOT: LowLevelILNot, # [("src", "expr")],
+ LowLevelILOperation.LLIL_BSWAP: LowLevelILBswap, # [("src", "expr")],
+ LowLevelILOperation.LLIL_POPCNT: LowLevelILPopcnt, # [("src", "expr")],
+ LowLevelILOperation.LLIL_CLZ: LowLevelILClz, # [("src", "expr")],
+ LowLevelILOperation.LLIL_CTZ: LowLevelILCtz, # [("src", "expr")],
+ LowLevelILOperation.LLIL_RBIT: LowLevelILRbit, # [("src", "expr")],
+ LowLevelILOperation.LLIL_CLS: LowLevelILCls, # [("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 155a3751..15db8ae1 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -265,7 +265,13 @@ class MediumLevelILInstruction(BaseILInstruction):
("right", "expr")],
MediumLevelILOperation.MLIL_MODS_DP: [("left", "expr"), ("right", "expr")], MediumLevelILOperation.MLIL_NEG: [
("src", "expr")
- ], MediumLevelILOperation.MLIL_NOT: [("src", "expr")], MediumLevelILOperation.MLIL_SX: [
+ ], MediumLevelILOperation.MLIL_NOT: [("src", "expr")], MediumLevelILOperation.MLIL_BSWAP: [
+ ("src", "expr")
+ ], MediumLevelILOperation.MLIL_POPCNT: [("src", "expr")], MediumLevelILOperation.MLIL_CLZ: [
+ ("src", "expr")
+ ], MediumLevelILOperation.MLIL_CTZ: [("src", "expr")], MediumLevelILOperation.MLIL_RBIT: [
+ ("src", "expr")
+ ], MediumLevelILOperation.MLIL_CLS: [("src", "expr")], MediumLevelILOperation.MLIL_SX: [
("src", "expr")
], MediumLevelILOperation.MLIL_ZX: [("src", "expr")], MediumLevelILOperation.MLIL_LOW_PART: [
("src", "expr")
@@ -1435,6 +1441,36 @@ class MediumLevelILNot(MediumLevelILUnaryBase, Arithmetic):
@dataclass(frozen=True, repr=False, eq=False)
+class MediumLevelILBswap(MediumLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
+class MediumLevelILPopcnt(MediumLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
+class MediumLevelILClz(MediumLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
+class MediumLevelILCtz(MediumLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
+class MediumLevelILRbit(MediumLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
+class MediumLevelILCls(MediumLevelILUnaryBase, Arithmetic):
+ pass
+
+
+@dataclass(frozen=True, repr=False, eq=False)
class MediumLevelILSx(MediumLevelILUnaryBase, Arithmetic):
pass
@@ -3444,6 +3480,12 @@ ILInstruction = {
MediumLevelILOperation.MLIL_MODS_DP: MediumLevelILModsDp, # [("left", "expr"), ("right", "expr")],
MediumLevelILOperation.MLIL_NEG: MediumLevelILNeg, # [("src", "expr")],
MediumLevelILOperation.MLIL_NOT: MediumLevelILNot, # [("src", "expr")],
+ MediumLevelILOperation.MLIL_BSWAP: MediumLevelILBswap, # [("src", "expr")],
+ MediumLevelILOperation.MLIL_POPCNT: MediumLevelILPopcnt, # [("src", "expr")],
+ MediumLevelILOperation.MLIL_CLZ: MediumLevelILClz, # [("src", "expr")],
+ MediumLevelILOperation.MLIL_CTZ: MediumLevelILCtz, # [("src", "expr")],
+ MediumLevelILOperation.MLIL_RBIT: MediumLevelILRbit, # [("src", "expr")],
+ MediumLevelILOperation.MLIL_CLS: MediumLevelILCls, # [("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 98839cae..0fbbb297 100644
--- a/rust/src/high_level_il/instruction.rs
+++ b/rust/src/high_level_il/instruction.rs
@@ -412,6 +412,24 @@ impl HighLevelILInstruction {
HLIL_NOT => Op::Not(UnaryOp {
src: HighLevelExpressionIndex::from(op.operands[0]),
}),
+ HLIL_BSWAP => Op::Bswap(UnaryOp {
+ src: HighLevelExpressionIndex::from(op.operands[0]),
+ }),
+ HLIL_POPCNT => Op::Popcnt(UnaryOp {
+ src: HighLevelExpressionIndex::from(op.operands[0]),
+ }),
+ HLIL_CLZ => Op::Clz(UnaryOp {
+ src: HighLevelExpressionIndex::from(op.operands[0]),
+ }),
+ HLIL_CTZ => Op::Ctz(UnaryOp {
+ src: HighLevelExpressionIndex::from(op.operands[0]),
+ }),
+ HLIL_RBIT => Op::Rbit(UnaryOp {
+ src: HighLevelExpressionIndex::from(op.operands[0]),
+ }),
+ HLIL_CLS => Op::Cls(UnaryOp {
+ src: HighLevelExpressionIndex::from(op.operands[0]),
+ }),
HLIL_SX => Op::Sx(UnaryOp {
src: HighLevelExpressionIndex::from(op.operands[0]),
}),
@@ -794,6 +812,12 @@ impl HighLevelILInstruction {
ReturnByRef(op) => Lifted::ReturnByRef(self.lift_unary_op(op)),
Neg(op) => Lifted::Neg(self.lift_unary_op(op)),
Not(op) => Lifted::Not(self.lift_unary_op(op)),
+ Bswap(op) => Lifted::Bswap(self.lift_unary_op(op)),
+ Popcnt(op) => Lifted::Popcnt(self.lift_unary_op(op)),
+ Clz(op) => Lifted::Clz(self.lift_unary_op(op)),
+ 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)),
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)),
@@ -1173,6 +1197,12 @@ pub enum HighLevelILInstructionKind {
ReturnByRef(UnaryOp),
Neg(UnaryOp),
Not(UnaryOp),
+ Bswap(UnaryOp),
+ Popcnt(UnaryOp),
+ Clz(UnaryOp),
+ Ctz(UnaryOp),
+ Rbit(UnaryOp),
+ Cls(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 e2ce3686..3d32b369 100644
--- a/rust/src/high_level_il/lift.rs
+++ b/rust/src/high_level_il/lift.rs
@@ -116,6 +116,12 @@ pub enum HighLevelILLiftedInstructionKind {
ReturnByRef(LiftedUnaryOp),
Neg(LiftedUnaryOp),
Not(LiftedUnaryOp),
+ Bswap(LiftedUnaryOp),
+ Popcnt(LiftedUnaryOp),
+ Clz(LiftedUnaryOp),
+ Ctz(LiftedUnaryOp),
+ Rbit(LiftedUnaryOp),
+ Cls(LiftedUnaryOp),
Sx(LiftedUnaryOp),
Zx(LiftedUnaryOp),
LowPart(LiftedUnaryOp),
@@ -246,6 +252,12 @@ impl HighLevelILLiftedInstruction {
ReturnByRef(_) => "ReturnByRef",
Neg(_) => "Neg",
Not(_) => "Not",
+ Bswap(_) => "Bswap",
+ Popcnt(_) => "Popcnt",
+ Clz(_) => "Clz",
+ Ctz(_) => "Ctz",
+ Rbit(_) => "Rbit",
+ Cls(_) => "Cls",
Sx(_) => "Sx",
Zx(_) => "Zx",
LowPart(_) => "LowPart",
@@ -365,6 +377,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)
| 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 8103518c..92d57675 100644
--- a/rust/src/low_level_il/expression.rs
+++ b/rust/src/low_level_il/expression.rs
@@ -309,6 +309,12 @@ where
Neg(Operation<'func, M, F, operation::UnaryOp>),
Not(Operation<'func, M, F, operation::UnaryOp>),
+ Bswap(Operation<'func, M, F, operation::UnaryOp>),
+ Popcnt(Operation<'func, M, F, operation::UnaryOp>),
+ Clz(Operation<'func, M, F, operation::UnaryOp>),
+ Ctz(Operation<'func, M, F, operation::UnaryOp>),
+ Rbit(Operation<'func, M, F, operation::UnaryOp>),
+ Cls(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>),
@@ -466,6 +472,12 @@ where
LLIL_NEG => LowLevelILExpressionKind::Neg(Operation::new(function, op, index)),
LLIL_NOT => LowLevelILExpressionKind::Not(Operation::new(function, op, index)),
+ LLIL_BSWAP => LowLevelILExpressionKind::Bswap(Operation::new(function, op, index)),
+ LLIL_POPCNT => LowLevelILExpressionKind::Popcnt(Operation::new(function, op, index)),
+ LLIL_CLZ => LowLevelILExpressionKind::Clz(Operation::new(function, op, index)),
+ LLIL_CTZ => LowLevelILExpressionKind::Ctz(Operation::new(function, op, index)),
+ LLIL_RBIT => LowLevelILExpressionKind::Rbit(Operation::new(function, op, index)),
+ LLIL_CLS => LowLevelILExpressionKind::Cls(Operation::new(function, op, index)),
LLIL_SX => LowLevelILExpressionKind::Sx(Operation::new(function, op, index)),
LLIL_ZX => LowLevelILExpressionKind::Zx(Operation::new(function, op, index)),
@@ -620,7 +632,8 @@ where
use self::LowLevelILExpressionKind::*;
match *self {
- Neg(ref op) | Not(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref 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)
| 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),
@@ -664,7 +677,8 @@ where
visit!(op.left());
visit!(op.right());
}
- Neg(ref op) | Not(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref 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)
| 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) => {
@@ -758,7 +772,8 @@ where
DivuDp(ref op) | DivsDp(ref op) | ModuDp(ref op) | ModsDp(ref op) => &op.op,
- Neg(ref op) | Not(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref 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)
| 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,
@@ -831,7 +846,8 @@ impl LowLevelILExpressionKind<'_, Mutable, NonSSA> {
DivuDp(ref op) | DivsDp(ref op) | ModuDp(ref op) | ModsDp(ref op) => op.flag_write(),
- Neg(ref op) | Not(ref op) | Sx(ref op) | Zx(ref op) | LowPart(ref 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)
| 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 202c9ed6..ebd6e980 100644
--- a/rust/src/low_level_il/lifting.rs
+++ b/rust/src/low_level_il/lifting.rs
@@ -94,6 +94,12 @@ pub enum LowLevelILFlagWriteOp<R: ArchReg> {
Push(usize, LowLevelILRegisterOrConstant<R>),
Neg(usize, LowLevelILRegisterOrConstant<R>),
Not(usize, LowLevelILRegisterOrConstant<R>),
+ Bswap(usize, LowLevelILRegisterOrConstant<R>),
+ Popcnt(usize, LowLevelILRegisterOrConstant<R>),
+ Clz(usize, LowLevelILRegisterOrConstant<R>),
+ Ctz(usize, LowLevelILRegisterOrConstant<R>),
+ Rbit(usize, LowLevelILRegisterOrConstant<R>),
+ Cls(usize, LowLevelILRegisterOrConstant<R>),
Sx(usize, LowLevelILRegisterOrConstant<R>),
Zx(usize, LowLevelILRegisterOrConstant<R>),
LowPart(usize, LowLevelILRegisterOrConstant<R>),
@@ -293,6 +299,12 @@ impl<R: ArchReg> LowLevelILFlagWriteOp<R> {
(1, LLIL_PUSH) => op!(Push, 0),
(1, LLIL_NEG) => op!(Neg, 0),
(1, LLIL_NOT) => op!(Not, 0),
+ (1, LLIL_BSWAP) => op!(Bswap, 0),
+ (1, LLIL_POPCNT) => op!(Popcnt, 0),
+ (1, LLIL_CLZ) => op!(Clz, 0),
+ (1, LLIL_CTZ) => op!(Ctz, 0),
+ (1, LLIL_RBIT) => op!(Rbit, 0),
+ (1, LLIL_CLS) => op!(Cls, 0),
(1, LLIL_SX) => op!(Sx, 0),
(1, LLIL_ZX) => op!(Zx, 0),
(1, LLIL_LOW_PART) => op!(LowPart, 0),
@@ -351,6 +363,12 @@ impl<R: ArchReg> LowLevelILFlagWriteOp<R> {
Push(size, ..) => (size, LLIL_PUSH),
Neg(size, ..) => (size, LLIL_NEG),
Not(size, ..) => (size, LLIL_NOT),
+ Bswap(size, ..) => (size, LLIL_BSWAP),
+ Popcnt(size, ..) => (size, LLIL_POPCNT),
+ Clz(size, ..) => (size, LLIL_CLZ),
+ Ctz(size, ..) => (size, LLIL_CTZ),
+ Rbit(size, ..) => (size, LLIL_RBIT),
+ Cls(size, ..) => (size, LLIL_CLS),
Sx(size, ..) => (size, LLIL_SX),
Zx(size, ..) => (size, LLIL_ZX),
LowPart(size, ..) => (size, LLIL_LOW_PART),
@@ -404,6 +422,12 @@ impl<R: ArchReg> LowLevelILFlagWriteOp<R> {
| Push(_, op0)
| Neg(_, op0)
| Not(_, op0)
+ | Bswap(_, op0)
+ | Popcnt(_, op0)
+ | Clz(_, op0)
+ | Ctz(_, op0)
+ | Rbit(_, op0)
+ | Cls(_, op0)
| Sx(_, op0)
| Zx(_, op0)
| LowPart(_, op0)
@@ -1422,6 +1446,12 @@ impl LowLevelILMutableFunction {
sized_unary_op_lifter!(neg, LLIL_NEG, ValueExpr);
sized_unary_op_lifter!(not, LLIL_NOT, ValueExpr);
+ sized_unary_op_lifter!(bswap, LLIL_BSWAP, ValueExpr);
+ sized_unary_op_lifter!(popcnt, LLIL_POPCNT, ValueExpr);
+ sized_unary_op_lifter!(clz, LLIL_CLZ, ValueExpr);
+ sized_unary_op_lifter!(ctz, LLIL_CTZ, ValueExpr);
+ sized_unary_op_lifter!(rbit, LLIL_RBIT, ValueExpr);
+ sized_unary_op_lifter!(cls, LLIL_CLS, ValueExpr);
size_changing_unary_op_lifter!(sx, LLIL_SX, ValueExpr);
size_changing_unary_op_lifter!(zx, LLIL_ZX, ValueExpr);
diff --git a/rust/src/medium_level_il/instruction.rs b/rust/src/medium_level_il/instruction.rs
index 41f2bbe4..77a0be27 100644
--- a/rust/src/medium_level_il/instruction.rs
+++ b/rust/src/medium_level_il/instruction.rs
@@ -575,6 +575,24 @@ impl MediumLevelILInstruction {
MLIL_NOT => Op::Not(UnaryOp {
src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
+ MLIL_BSWAP => Op::Bswap(UnaryOp {
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
+ }),
+ MLIL_POPCNT => Op::Popcnt(UnaryOp {
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
+ }),
+ MLIL_CLZ => Op::Clz(UnaryOp {
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
+ }),
+ MLIL_CTZ => Op::Ctz(UnaryOp {
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
+ }),
+ MLIL_RBIT => Op::Rbit(UnaryOp {
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
+ }),
+ MLIL_CLS => Op::Cls(UnaryOp {
+ src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
+ }),
MLIL_SX => Op::Sx(UnaryOp {
src: MediumLevelExpressionIndex::from(op.operands[0] as usize),
}),
@@ -1099,6 +1117,12 @@ impl MediumLevelILInstruction {
Neg(op) => Lifted::Neg(self.lift_unary_op(op)),
Not(op) => Lifted::Not(self.lift_unary_op(op)),
+ Bswap(op) => Lifted::Bswap(self.lift_unary_op(op)),
+ Popcnt(op) => Lifted::Popcnt(self.lift_unary_op(op)),
+ Clz(op) => Lifted::Clz(self.lift_unary_op(op)),
+ 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)),
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)),
@@ -1874,6 +1898,12 @@ pub enum MediumLevelILInstructionKind {
StoreOutput(StoreOutput),
Neg(UnaryOp),
Not(UnaryOp),
+ Bswap(UnaryOp),
+ Popcnt(UnaryOp),
+ Clz(UnaryOp),
+ Ctz(UnaryOp),
+ Rbit(UnaryOp),
+ Cls(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 aee8139f..2f0d6653 100644
--- a/rust/src/medium_level_il/lift.rs
+++ b/rust/src/medium_level_il/lift.rs
@@ -154,6 +154,12 @@ pub enum MediumLevelILLiftedInstructionKind {
SharedParamSlot(LiftedSharedParamSlot),
Neg(LiftedUnaryOp),
Not(LiftedUnaryOp),
+ Bswap(LiftedUnaryOp),
+ Popcnt(LiftedUnaryOp),
+ Clz(LiftedUnaryOp),
+ Ctz(LiftedUnaryOp),
+ Rbit(LiftedUnaryOp),
+ Cls(LiftedUnaryOp),
Sx(LiftedUnaryOp),
Zx(LiftedUnaryOp),
LowPart(LiftedUnaryOp),
@@ -313,6 +319,12 @@ impl MediumLevelILLiftedInstruction {
StoreOutput(_) => "StoreOutput",
Neg(_) => "Neg",
Not(_) => "Not",
+ Bswap(_) => "Bswap",
+ Popcnt(_) => "Popcnt",
+ Clz(_) => "Clz",
+ Ctz(_) => "Ctz",
+ Rbit(_) => "Rbit",
+ Cls(_) => "Cls",
Sx(_) => "Sx",
Zx(_) => "Zx",
LowPart(_) => "LowPart",
@@ -542,7 +554,8 @@ impl MediumLevelILLiftedInstruction {
("params", Operand::ExprList(op.params.clone())),
("stack", Operand::Expr(*op.stack.clone())),
],
- Neg(op) | Not(op) | Sx(op) | Zx(op) | LowPart(op) | BoolToInt(op) | UnimplMem(op)
+ 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)
| 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()))]