use crate::ir::{Expr, Program};
use crate::ops::primitive;
use crate::ops::{AlgebraicLaw, OpSpec, U32_OUTPUTS, U32_U32_INPUTS};
pub const LAWS: &[AlgebraicLaw] = &[
AlgebraicLaw::Bounded {
lo: 0,
hi: u32::MAX,
},
AlgebraicLaw::InverseOf {
op: "primitive.bitwise.rotr",
},
];
#[derive(Debug, Clone, Copy, Default)]
pub struct Rotl;
impl Rotl {
pub const SPEC: OpSpec = OpSpec::composition_inlinable(
"primitive.bitwise.rotl",
U32_U32_INPUTS,
U32_OUTPUTS,
LAWS,
Self::program,
);
#[must_use]
pub fn program() -> Program {
primitive::binary_u32_program(|a, b| {
let r = Expr::bitand(b, Expr::u32(31));
Expr::select(
Expr::eq(r.clone(), Expr::u32(0)),
a.clone(),
Expr::bitor(
Expr::shl(a.clone(), r.clone()),
Expr::shr(a, Expr::sub(Expr::u32(32), r)),
),
)
})
}
}