summaryrefslogtreecommitdiff
path: root/rust
diff options
context:
space:
mode:
authorMark Rowe <mark@vector35.com>2026-06-03 21:25:55 -0700
committerMark Rowe <mark@vector35.com>2026-06-04 14:31:09 -0700
commitd592ed6dafbb134553bf3a0b8ee70ff7f2049aba (patch)
tree1bfe7e335e5b4e21371cde4bf8858c6439bc3f18 /rust
parent9987102015875991813200116558306851763009 (diff)
Add bswap, popcnt, clz, ctz, cls, and rbit instructions
Diffstat (limited to 'rust')
-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
6 files changed, 137 insertions, 5 deletions
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()))]