Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions crates/ir2/build/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,9 @@ define_ident!(
NotLt: not_lt,
NotLe: not_le,

BitAnd: bit_and,
BitOr: bit_or,
BitXor: bit_xor,
BitAnd: bitand,
BitOr: bitor,
BitXor: bitxor,

Branch: branch,
BranchTable: branch_table,
Expand Down Expand Up @@ -209,6 +209,7 @@ define_ident!(
Value: value,
Result: result,
Results: results,
Params: params,
Len: len,
LenTargets: len_targets,
LenValues: len_values,
Expand Down Expand Up @@ -244,7 +245,7 @@ define_ident!(

I64Add128: i64_add128,
I64Sub128: i64_sub128,
S64MulWide: s64_mul_wide,
I64MulWide: i64_mul_wide,
U64MulWide: u64_mul_wide,

Lhs: lhs,
Expand All @@ -264,7 +265,10 @@ define_ident!(

V128: v128,
Lane: lane,
Splat: splat,
Splat8: splat8,
Splat16: splat16,
Splat32: splat32,
Splat64: splat64,
S8x16ExtractLane: s8x16_extract_lane,
U8x16ExtractLane: u8x16_extract_lane,
S16x8ExtractLane: s16x8_extract_lane,
Expand Down
67 changes: 25 additions & 42 deletions crates/ir2/build/isa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,41 +373,12 @@ fn add_store_ops(isa: &mut Isa) {
StoreOpKind::I64Store32,
];
for op in ops {
isa.push_op(StoreOp::new(
op,
OperandKind::Slot,
OperandKind::Slot,
false,
false,
));
isa.push_op(StoreOp::new(
op,
OperandKind::Slot,
OperandKind::Immediate,
false,
false,
));
isa.push_op(StoreOp::new(
op,
OperandKind::Immediate,
OperandKind::Slot,
false,
false,
));
isa.push_op(StoreOp::new(
op,
OperandKind::Slot,
OperandKind::Slot,
true,
true,
));
isa.push_op(StoreOp::new(
op,
OperandKind::Slot,
OperandKind::Immediate,
true,
true,
));
for value in [OperandKind::Slot, OperandKind::Immediate] {
for ptr in [OperandKind::Slot, OperandKind::Immediate] {
isa.push_op(StoreOp::new(op, ptr, value, false, false));
}
isa.push_op(StoreOp::new(op, OperandKind::Slot, value, true, true));
}
}
}

Expand Down Expand Up @@ -509,37 +480,44 @@ fn add_call_ops(isa: &mut Isa) {
Op::from(GenericOp::new(
Ident::CallInternal,
[
Field::new(Ident::Results, FieldTy::SlotSpan),
Field::new(Ident::Params, FieldTy::BoundedSlotSpan),
Field::new(Ident::Func, FieldTy::InternalFunc),
],
)),
Op::from(GenericOp::new(
Ident::CallImported,
[
Field::new(Ident::Results, FieldTy::SlotSpan),
Field::new(Ident::Params, FieldTy::BoundedSlotSpan),
Field::new(Ident::Func, FieldTy::Func),
],
)),
Op::from(GenericOp::new(
Ident::CallIndirect,
[
Field::new(Ident::Results, FieldTy::SlotSpan),
Field::new(Ident::Params, FieldTy::BoundedSlotSpan),
Field::new(Ident::Index, FieldTy::Slot),
Field::new(Ident::FuncType, FieldTy::FuncType),
Field::new(Ident::Table, FieldTy::Table),
],
)),
Op::from(GenericOp::new(
Ident::ReturnCallInternal,
[Field::new(Ident::Func, FieldTy::InternalFunc)],
[
Field::new(Ident::Params, FieldTy::BoundedSlotSpan),
Field::new(Ident::Func, FieldTy::InternalFunc),
],
)),
Op::from(GenericOp::new(
Ident::ReturnCallImported,
[Field::new(Ident::Func, FieldTy::Func)],
[
Field::new(Ident::Params, FieldTy::BoundedSlotSpan),
Field::new(Ident::Func, FieldTy::Func),
],
)),
Op::from(GenericOp::new(
Ident::ReturnCallIndirect,
[
Field::new(Ident::Params, FieldTy::BoundedSlotSpan),
Field::new(Ident::Index, FieldTy::Slot),
Field::new(Ident::FuncType, FieldTy::FuncType),
Field::new(Ident::Table, FieldTy::Table),
Expand Down Expand Up @@ -724,7 +702,7 @@ fn add_wide_arithmetic_ops(isa: &mut Isa) {
],
)),
Op::from(GenericOp::new(
Ident::S64MulWide,
Ident::I64MulWide,
[
Field::new(Ident::Results, FieldTy::FixedSlotSpan2),
Field::new(Ident::Lhs, FieldTy::Slot),
Expand Down Expand Up @@ -776,7 +754,12 @@ fn add_simd_ops(isa: &mut Isa, config: &Config) {
}

fn add_simd_splat_ops(isa: &mut Isa) {
let kinds = [UnaryOpKind::V128Splat32, UnaryOpKind::V128Splat64];
let kinds = [
UnaryOpKind::V128Splat8,
UnaryOpKind::V128Splat16,
UnaryOpKind::V128Splat32,
UnaryOpKind::V128Splat64,
];
for kind in kinds {
isa.push_op(UnaryOp::new(kind, OperandKind::Slot));
isa.push_op(UnaryOp::new(kind, OperandKind::Immediate));
Expand Down
35 changes: 32 additions & 3 deletions crates/ir2/build/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ pub enum UnaryOpKind {
F64ConvertU64,

// SIMD: Generic Unary Ops
V128Splat8,
V128Splat16,
V128Splat32,
V128Splat64,
V128Not,
Expand Down Expand Up @@ -287,6 +289,8 @@ pub enum UnaryOpKind {
impl UnaryOpKind {
pub fn is_conversion(&self) -> bool {
self.value_ty() != self.result_ty()
&& self.value_ty().is_wasm()
&& self.result_ty().is_wasm()
}

pub fn value_ty(&self) -> Ty {
Expand Down Expand Up @@ -328,6 +332,8 @@ impl UnaryOpKind {
| Self::F64ConvertU64 => Ty::U64,

// SIMD: Generic Unary Ops
| Self::V128Splat8 => Ty::B8,
| Self::V128Splat16 => Ty::B16,
| Self::V128Splat32 => Ty::B32,
| Self::V128Splat64 => Ty::B64,
| Self::V128Not | Self::V128AnyTrue => Ty::V128,
Expand Down Expand Up @@ -435,7 +441,12 @@ impl UnaryOpKind {
| Self::F64ConvertU64 => Ty::F64,

// SIMD: Generic Unary Ops
| Self::V128Splat32 | Self::V128Splat64 | Self::V128Not | Self::V128AnyTrue => Ty::V128,
| Self::V128Splat8
| Self::V128Splat16
| Self::V128Splat32
| Self::V128Splat64
| Self::V128Not
| Self::V128AnyTrue => Ty::V128,
// SIMD: `i8x16` Unary Ops
| Self::I8x16Abs
| Self::I8x16Neg
Expand Down Expand Up @@ -551,8 +562,10 @@ impl UnaryOpKind {
Self::F64ConvertU64 => Ident::Convert,

// SIMD: Generic Unary Ops
Self::V128Splat32 => Ident::Splat,
Self::V128Splat64 => Ident::Splat,
Self::V128Splat8 => Ident::Splat8,
Self::V128Splat16 => Ident::Splat16,
Self::V128Splat32 => Ident::Splat32,
Self::V128Splat64 => Ident::Splat64,
Self::V128Not => Ident::Not,
Self::V128AnyTrue => Ident::AnyTrue,
// SIMD: `i8x16` Unary Ops
Expand Down Expand Up @@ -1384,6 +1397,10 @@ pub enum Ty {
U32,
/// A unsigned 64-bit integer type.
U64,
/// A generic 8-bits value.
B8,
/// A generic 16-bits value.
B16,
/// A generic 32-bits value.
B32,
/// A generic 64-bits value.
Expand Down Expand Up @@ -1425,8 +1442,14 @@ pub enum Ty {
}

impl Ty {
pub fn is_wasm(&self) -> bool {
!matches!(self, Self::B8 | Self::B16 | Self::B32 | Self::B64)
}

pub fn to_field_ty(self) -> Option<FieldTy> {
let ty = match self {
| Ty::B8 => FieldTy::U8,
| Ty::B16 => FieldTy::U16,
| Ty::S32 | Ty::I32 => FieldTy::I32,
| Ty::S64 | Ty::I64 => FieldTy::I64,
| Ty::B32 | Ty::U32 => FieldTy::U32,
Expand All @@ -1448,6 +1471,8 @@ impl Display for Ty {
Ty::S64 => "i64",
Ty::U32 => "u32",
Ty::U64 => "u64",
Ty::B8 => "8",
Ty::B16 => "16",
Ty::B32 => "32",
Ty::B64 => "64",
Ty::F32 => "f32",
Expand Down Expand Up @@ -1487,6 +1512,8 @@ impl Display for CamelCase<Ty> {
Ty::S64 => "I64",
Ty::U32 => "U32",
Ty::U64 => "U64",
Ty::B8 => "8",
Ty::B16 => "16",
Ty::B32 => "32",
Ty::B64 => "64",
Ty::F32 => "F32",
Expand Down Expand Up @@ -1515,6 +1542,7 @@ impl Display for CamelCase<Ty> {
pub enum FieldTy {
Slot,
SlotSpan,
BoundedSlotSpan,
FixedSlotSpan2,
U8,
U16,
Expand Down Expand Up @@ -1557,6 +1585,7 @@ impl Display for FieldTy {
let s = match self {
Self::Slot => "Slot",
Self::SlotSpan => "SlotSpan",
Self::BoundedSlotSpan => "BoundedSlotSpan",
Self::FixedSlotSpan2 => "FixedSlotSpan<2>",
Self::U8 => "u8",
Self::U16 => "u16",
Expand Down
25 changes: 24 additions & 1 deletion crates/ir2/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub trait Encoder {

/// Registers an encoded [`BranchOffset`] to the encoder.
///
/// This is required in order to update the branch offsets of
/// branch operators once all forward branch offsets are known.
///
/// # Errors
///
/// If the encoder cannot register the `branch_offset`.
Expand All @@ -50,6 +53,16 @@ pub trait Encoder {
pos: Self::Pos,
branch_offset: BranchOffset,
) -> Result<(), Self::Error>;

/// Registers an encoded [`BlockFuel`] to the encoder.
///
/// This is required in order to update the consumed fuel of
/// [`Op::ConsumeFuel`] operators during translation.
///
/// # Errors
///
/// If the encoder cannot register the `block_fuel`.
fn block_fuel(&mut self, pos: Self::Pos, block_fuel: BlockFuel) -> Result<(), Self::Error>;
}

/// Types that can be encoded by types that implement [`Encoder`].
Expand Down Expand Up @@ -80,6 +93,17 @@ impl Encode for BranchOffset {
}
}

impl Encode for BlockFuel {
fn encode<E>(&self, encoder: &mut E) -> Result<E::Pos, E::Error>
where
E: Encoder,
{
let pos = u64::from(*self).encode(encoder)?;
encoder.block_fuel(pos, *self)?;
Ok(pos)
}
}

impl Encode for BoundedSlotSpan {
fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<E::Pos, E::Error> {
(self.span(), self.len()).encode(encoder)
Expand Down Expand Up @@ -128,7 +152,6 @@ macro_rules! impl_encode_using {
impl_encode_using! {
bool as u8 = Into::into,
Offset16 as u16 = Into::into,
BlockFuel as u64 = Into::into,
Address as u64 = Into::into,
Slot as u16 = Into::into,
Func as u32 = Into::into,
Expand Down
1 change: 1 addition & 0 deletions crates/ir2/src/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{
index::{Data, Elem, Func, FuncType, Global, InternalFunc, Memory, Table},
Address,
BlockFuel,
BoundedSlotSpan,
BranchOffset,
FixedSlotSpan,
Offset16,
Expand Down
Loading