summaryrefslogtreecommitdiff
path: root/rust/src/low_level_il
diff options
context:
space:
mode:
authorMark Rowe <mark@vector35.com>2026-06-04 16:36:52 -0700
committerMark Rowe <mark@vector35.com>2026-06-05 13:01:46 -0700
commitfde1241ce928d38c2031c827ae0ddee5c6f5af0f (patch)
tree6711a47863332712eb5324e2c3ef1dffb843bb5d /rust/src/low_level_il
parentfa09f36b5f47ed690dc029fe9f1ed9ad4ebce7c8 (diff)
Add abs, min, and max instructions
Diffstat (limited to 'rust/src/low_level_il')
-rw-r--r--rust/src/low_level_il/expression.rs27
-rw-r--r--rust/src/low_level_il/lifting.rs41
2 files changed, 63 insertions, 5 deletions
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);