Skip to content

Commit

Permalink
refactor BinInstrImm and BranchBinOpInstrImm
Browse files Browse the repository at this point in the history
This work was carried over from #794.
  • Loading branch information
Robbepop committed Nov 24, 2023
1 parent 5bea360 commit ec08d65
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 104 deletions.
11 changes: 6 additions & 5 deletions crates/wasmi/src/engine/regmach/bytecode/construct.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use super::{
utils::{BranchOffset16, CopysignImmInstr, Sign},
utils::{BranchOffset16, Sign},
AnyConst32,
BinInstr,
BinInstrImm,
BinInstrImm16,
BranchBinOpInstr,
BranchBinOpInstrImm,
BranchBinOpInstrImm16,
CallIndirectParams,
Const16,
Const32,
Expand Down Expand Up @@ -224,7 +225,7 @@ macro_rules! constructor_for_branch_binop_imm {
$(
#[doc = concat!("Creates a new [`Instruction::", stringify!($op_code), "`].")]
pub fn $name(lhs: Register, rhs: Const16<$ty>, offset: BranchOffset16) -> Self {
Self::$op_code(BranchBinOpInstrImm::new(lhs, rhs, offset))
Self::$op_code(BranchBinOpInstrImm16::new(lhs, rhs, offset))
}
)*
}
Expand Down Expand Up @@ -565,12 +566,12 @@ impl Instruction {

/// Creates a new [`Instruction::F32CopysignImm`] instruction.
pub fn f32_copysign_imm(result: Register, lhs: Register, rhs: Sign) -> Self {
Self::F32CopysignImm(CopysignImmInstr { result, lhs, rhs })
Self::F32CopysignImm(BinInstrImm::new(result, lhs, rhs))
}

/// Creates a new [`Instruction::F64CopysignImm`] instruction.
pub fn f64_copysign_imm(result: Register, lhs: Register, rhs: Sign) -> Self {
Self::F64CopysignImm(CopysignImmInstr { result, lhs, rhs })
Self::F64CopysignImm(BinInstrImm::new(result, lhs, rhs))
}

/// Creates a new [`Instruction::Select`].
Expand Down
59 changes: 30 additions & 29 deletions crates/wasmi/src/engine/regmach/bytecode/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ pub(crate) use self::{
provider::{Provider, ProviderSliceStack, UntypedProvider},
utils::{
BinInstr,
BinInstrImm,
BinInstrImm16,
BranchBinOpInstr,
BranchBinOpInstrImm,
BranchBinOpInstrImm16,
BranchOffset16,
CallIndirectParams,
CopysignImmInstr,
LoadAtInstr,
LoadInstr,
LoadOffset16Instr,
Expand Down Expand Up @@ -419,23 +420,23 @@ pub enum Instruction {
/// # Note
///
/// Variant of [`Instruction::BranchI32And`] with 16-bit encoded constant `rhs`.
BranchI32AndImm(BranchBinOpInstrImm<i32>),
BranchI32AndImm(BranchBinOpInstrImm16<i32>),
/// A fused [`Instruction::I32Or`] and [`Instruction::BranchI32Nez`] instruction.
BranchI32Or(BranchBinOpInstr),
/// A fused [`Instruction::I32Or`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI32Or`] with 16-bit encoded constant `rhs`.
BranchI32OrImm(BranchBinOpInstrImm<i32>),
BranchI32OrImm(BranchBinOpInstrImm16<i32>),
/// A fused [`Instruction::I32Xor`] and [`Instruction::BranchI32Nez`] instruction.
BranchI32Xor(BranchBinOpInstr),
/// A fused [`Instruction::I32Xor`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI32Xor`] with 16-bit encoded constant `rhs`.
BranchI32XorImm(BranchBinOpInstrImm<i32>),
BranchI32XorImm(BranchBinOpInstrImm16<i32>),

/// A fused not-[`Instruction::I32And`] and [`Instruction::BranchI32Nez`] instruction.
BranchI32AndEqz(BranchBinOpInstr),
Expand All @@ -444,23 +445,23 @@ pub enum Instruction {
/// # Note
///
/// Variant of [`Instruction::BranchI32AndEqz`] with 16-bit encoded constant `rhs`.
BranchI32AndEqzImm(BranchBinOpInstrImm<i32>),
BranchI32AndEqzImm(BranchBinOpInstrImm16<i32>),
/// A fused not-[`Instruction::I32Or`] and [`Instruction::BranchI32Nez`] instruction.
BranchI32OrEqz(BranchBinOpInstr),
/// A fused not-[`Instruction::I32Or`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI32OrEqz`] with 16-bit encoded constant `rhs`.
BranchI32OrEqzImm(BranchBinOpInstrImm<i32>),
BranchI32OrEqzImm(BranchBinOpInstrImm16<i32>),
/// A fused not-[`Instruction::I32Xor`] and [`Instruction::BranchI32Nez`] instruction.
BranchI32XorEqz(BranchBinOpInstr),
/// A fused not-[`Instruction::I32Xor`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI32XorEqz`] with 16-bit encoded constant `rhs`.
BranchI32XorEqzImm(BranchBinOpInstrImm<i32>),
BranchI32XorEqzImm(BranchBinOpInstrImm16<i32>),

/// A fused [`Instruction::I32Eq`] and [`Instruction::BranchI32Nez`] instruction.
BranchI32Eq(BranchBinOpInstr),
Expand All @@ -469,15 +470,15 @@ pub enum Instruction {
/// # Note
///
/// Variant of [`Instruction::BranchI32Eq`] with 16-bit encoded constant `rhs`.
BranchI32EqImm(BranchBinOpInstrImm<i32>),
BranchI32EqImm(BranchBinOpInstrImm16<i32>),
/// A fused [`Instruction::I32Ne`] and [`Instruction::BranchI32Nez`] instruction.
BranchI32Ne(BranchBinOpInstr),
/// A fused [`Instruction::I32Ne`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI32Ne`] with 16-bit encoded constant `rhs`.
BranchI32NeImm(BranchBinOpInstrImm<i32>),
BranchI32NeImm(BranchBinOpInstrImm16<i32>),

/// A fused [`Instruction::I32LtS`] and [`Instruction::BranchI32Nez`] instruction.
BranchI32LtS(BranchBinOpInstr),
Expand All @@ -486,63 +487,63 @@ pub enum Instruction {
/// # Note
///
/// Variant of [`Instruction::BranchI32LtS`] with 16-bit encoded constant `rhs`.
BranchI32LtSImm(BranchBinOpInstrImm<i32>),
BranchI32LtSImm(BranchBinOpInstrImm16<i32>),
/// A fused [`Instruction::I32LtU`] and [`Instruction::BranchI32Nez`] instruction.
BranchI32LtU(BranchBinOpInstr),
/// A fused [`Instruction::I32LtU`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI32LtU`] with 16-bit encoded constant `rhs`.
BranchI32LtUImm(BranchBinOpInstrImm<u32>),
BranchI32LtUImm(BranchBinOpInstrImm16<u32>),
/// A fused [`Instruction::I32LeS`] and [`Instruction::BranchI32Nez`] instruction.
BranchI32LeS(BranchBinOpInstr),
/// A fused [`Instruction::I32LeS`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI32LeS`] with 16-bit encoded constant `rhs`.
BranchI32LeSImm(BranchBinOpInstrImm<i32>),
BranchI32LeSImm(BranchBinOpInstrImm16<i32>),
/// A fused [`Instruction::I32LeU`] and [`Instruction::BranchI32Nez`] instruction.
BranchI32LeU(BranchBinOpInstr),
/// A fused [`Instruction::I32LeU`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI32LeU`] with 16-bit encoded constant `rhs`.
BranchI32LeUImm(BranchBinOpInstrImm<u32>),
BranchI32LeUImm(BranchBinOpInstrImm16<u32>),
/// A fused [`Instruction::I32GtS`] and [`Instruction::BranchI32Nez`] instruction.
BranchI32GtS(BranchBinOpInstr),
/// A fused [`Instruction::I32GtS`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI32GtS`] with 16-bit encoded constant `rhs`.
BranchI32GtSImm(BranchBinOpInstrImm<i32>),
BranchI32GtSImm(BranchBinOpInstrImm16<i32>),
/// A fused [`Instruction::I32GtU`] and [`Instruction::BranchI32Nez`] instruction.
BranchI32GtU(BranchBinOpInstr),
/// A fused [`Instruction::I32GtU`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI32GtU`] with 16-bit encoded constant `rhs`.
BranchI32GtUImm(BranchBinOpInstrImm<u32>),
BranchI32GtUImm(BranchBinOpInstrImm16<u32>),
/// A fused [`Instruction::I32GeS`] and [`Instruction::BranchI32Nez`] instruction.
BranchI32GeS(BranchBinOpInstr),
/// A fused [`Instruction::I32GeS`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI32GeS`] with 16-bit encoded constant `rhs`.
BranchI32GeSImm(BranchBinOpInstrImm<i32>),
BranchI32GeSImm(BranchBinOpInstrImm16<i32>),
/// A fused [`Instruction::I32GeU`] and [`Instruction::BranchI32Nez`] instruction.
BranchI32GeU(BranchBinOpInstr),
/// A fused [`Instruction::I32GeU`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI32GeU`] with 16-bit encoded constant `rhs`.
BranchI32GeUImm(BranchBinOpInstrImm<u32>),
BranchI32GeUImm(BranchBinOpInstrImm16<u32>),

/// A fused [`Instruction::I64Eq`] and [`Instruction::BranchI32Nez`] instruction.
BranchI64Eq(BranchBinOpInstr),
Expand All @@ -551,15 +552,15 @@ pub enum Instruction {
/// # Note
///
/// Variant of [`Instruction::BranchI64Eq`] with 16-bit encoded constant `rhs`.
BranchI64EqImm(BranchBinOpInstrImm<i64>),
BranchI64EqImm(BranchBinOpInstrImm16<i64>),
/// A fused [`Instruction::I64Ne`] and [`Instruction::BranchI32Nez`] instruction.
BranchI64Ne(BranchBinOpInstr),
/// A fused [`Instruction::I64Ne`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI64Ne`] with 16-bit encoded constant `rhs`.
BranchI64NeImm(BranchBinOpInstrImm<i64>),
BranchI64NeImm(BranchBinOpInstrImm16<i64>),

/// A fused [`Instruction::I64LtS`] and [`Instruction::BranchI32Nez`] instruction.
BranchI64LtS(BranchBinOpInstr),
Expand All @@ -568,63 +569,63 @@ pub enum Instruction {
/// # Note
///
/// Variant of [`Instruction::BranchI64LtS`] with 16-bit encoded constant `rhs`.
BranchI64LtSImm(BranchBinOpInstrImm<i64>),
BranchI64LtSImm(BranchBinOpInstrImm16<i64>),
/// A fused [`Instruction::I64LtU`] and [`Instruction::BranchI32Nez`] instruction.
BranchI64LtU(BranchBinOpInstr),
/// A fused [`Instruction::I64LtU`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI64LtU`] with 16-bit encoded constant `rhs`.
BranchI64LtUImm(BranchBinOpInstrImm<u64>),
BranchI64LtUImm(BranchBinOpInstrImm16<u64>),
/// A fused [`Instruction::I64LeS`] and [`Instruction::BranchI32Nez`] instruction.
BranchI64LeS(BranchBinOpInstr),
/// A fused [`Instruction::I64LeS`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI64LeS`] with 16-bit encoded constant `rhs`.
BranchI64LeSImm(BranchBinOpInstrImm<i64>),
BranchI64LeSImm(BranchBinOpInstrImm16<i64>),
/// A fused [`Instruction::I64LeU`] and [`Instruction::BranchI32Nez`] instruction.
BranchI64LeU(BranchBinOpInstr),
/// A fused [`Instruction::I64LeU`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI64LeU`] with 16-bit encoded constant `rhs`.
BranchI64LeUImm(BranchBinOpInstrImm<u64>),
BranchI64LeUImm(BranchBinOpInstrImm16<u64>),
/// A fused [`Instruction::I64GtS`] and [`Instruction::BranchI32Nez`] instruction.
BranchI64GtS(BranchBinOpInstr),
/// A fused [`Instruction::I64GtS`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI64GtS`] with 16-bit encoded constant `rhs`.
BranchI64GtSImm(BranchBinOpInstrImm<i64>),
BranchI64GtSImm(BranchBinOpInstrImm16<i64>),
/// A fused [`Instruction::I64GtU`] and [`Instruction::BranchI32Nez`] instruction.
BranchI64GtU(BranchBinOpInstr),
/// A fused [`Instruction::I64GtU`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI64GtU`] with 16-bit encoded constant `rhs`.
BranchI64GtUImm(BranchBinOpInstrImm<u64>),
BranchI64GtUImm(BranchBinOpInstrImm16<u64>),
/// A fused [`Instruction::I64GeS`] and [`Instruction::BranchI32Nez`] instruction.
BranchI64GeS(BranchBinOpInstr),
/// A fused [`Instruction::I64GeS`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI64GeS`] with 16-bit encoded constant `rhs`.
BranchI64GeSImm(BranchBinOpInstrImm<i64>),
BranchI64GeSImm(BranchBinOpInstrImm16<i64>),
/// A fused [`Instruction::I64GeU`] and [`Instruction::BranchI32Nez`] instruction.
BranchI64GeU(BranchBinOpInstr),
/// A fused [`Instruction::I64GeU`] and [`Instruction::BranchI32Nez`] instruction.
///
/// # Note
///
/// Variant of [`Instruction::BranchI64GeU`] with 16-bit encoded constant `rhs`.
BranchI64GeUImm(BranchBinOpInstrImm<u64>),
BranchI64GeUImm(BranchBinOpInstrImm16<u64>),

/// A fused [`Instruction::F32Eq`] and [`Instruction::BranchI32Nez`] instruction.
BranchF32Eq(BranchBinOpInstr),
Expand Down Expand Up @@ -3042,9 +3043,9 @@ pub enum Instruction {
/// Wasm `f64.copysign` instruction: `r0 = copysign(r1, r2)`
F64Copysign(BinInstr),
/// Wasm `f32.copysign` instruction with immediate: `r0 = copysign(r1, c0)`
F32CopysignImm(CopysignImmInstr),
F32CopysignImm(BinInstrImm<Sign>),
/// Wasm `f64.copysign` instruction with immediate: `r0 = copysign(r1, c0)`
F64CopysignImm(CopysignImmInstr),
F64CopysignImm(BinInstrImm<Sign>),

/// Wasm `i32.wrap_i64` instruction.
I32WrapI64(UnaryInstr),
Expand Down
47 changes: 30 additions & 17 deletions crates/wasmi/src/engine/regmach/bytecode/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,16 @@ impl BinInstr {
}
}

/// A binary instruction with an immediate right-hand side value.
/// A binary instruction with a 16-bit encoded immediate value.
pub type BinInstrImm16<T> = BinInstrImm<Const16<T>>;

/// A binary instruction with an immediate value.
///
/// # Note
///
/// Optimized for small constant values that fit into 16-bit.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct BinInstrImm16<T> {
pub struct BinInstrImm<T> {
/// The register storing the result of the computation.
pub result: Register,
/// The register holding one of the operands.
Expand All @@ -270,12 +273,12 @@ pub struct BinInstrImm16<T> {
///
/// The instruction decides if this operand is the left-hand or
/// right-hand operand for the computation.
pub imm_in: Const16<T>,
pub imm_in: T,
}

impl<T> BinInstrImm16<T> {
impl<T> BinInstrImm<T> {
/// Creates a new [`BinInstrImm16`].
pub fn new(result: Register, reg_in: Register, imm_in: Const16<T>) -> Self {
pub fn new(result: Register, reg_in: Register, imm_in: T) -> Self {
Self {
result,
reg_in,
Expand Down Expand Up @@ -447,15 +450,22 @@ pub enum Sign {
Neg,
}

/// The `f32.copysign` or `f64.copysign` instruction with an immediate value.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct CopysignImmInstr {
/// The result register.
pub result: Register,
/// The input register.
pub lhs: Register,
/// The sign to copy.
pub rhs: Sign,
impl Sign {
/// Converts the [`Sign`] into an `f32` value.
pub fn to_f32(self) -> f32 {
match self {
Self::Pos => 1.0_f32,
Self::Neg => -1.0_f32,
}
}

/// Converts the [`Sign`] into an `f64` value.
pub fn to_f64(self) -> f64 {
match self {
Self::Pos => 1.0_f64,
Self::Neg => -1.0_f64,
}
}
}

/// Auxiliary [`Instruction`] parameter to encode call parameters for indirect call instructions.
Expand Down Expand Up @@ -541,20 +551,23 @@ impl BranchBinOpInstr {
}
}

/// A generic fused comparison and conditional branch [`Instruction`].
/// A generic fused comparison and conditional branch [`Instruction`] with 16-bit immediate value.
pub type BranchBinOpInstrImm16<T> = BranchBinOpInstrImm<Const16<T>>;

/// A generic fused comparison and conditional branch [`Instruction`] with generic immediate value.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct BranchBinOpInstrImm<T> {
/// The left-hand side operand to the conditional operator.
pub lhs: Register,
/// The right-hand side operand to the conditional operator.
pub rhs: Const16<T>,
pub rhs: T,
/// The 16-bit encoded branch offset.
pub offset: BranchOffset16,
}

impl<T> BranchBinOpInstrImm<T> {
/// Creates a new [`BranchBinOpInstr`].
pub fn new(lhs: Register, rhs: Const16<T>, offset: BranchOffset16) -> Self {
pub fn new(lhs: Register, rhs: T, offset: BranchOffset16) -> Self {
Self { lhs, rhs, offset }
}
}
Loading

0 comments on commit ec08d65

Please sign in to comment.