diff --git a/src/elements/mod.rs b/src/elements/mod.rs index 9e9c785..bb3c189 100644 --- a/src/elements/mod.rs +++ b/src/elements/mod.rs @@ -111,6 +111,8 @@ pub enum Error { UnknownInternalKind(u8), /// Unknown opcode encountered UnknownOpcode(u8), + /// Unknown SIMD opcode encountered + UnknownSimdOpcode(u32), /// Invalid VarUint1 value InvalidVarUint1(u8), /// Invalid VarInt32 value @@ -158,6 +160,7 @@ impl fmt::Display for Error { Error::UnknownExternalKind(kind) => write!(f, "Unknown external kind {}", kind), Error::UnknownInternalKind(kind) => write!(f, "Unknown internal kind {}", kind), Error::UnknownOpcode(opcode) => write!(f, "Unknown opcode {}", opcode), + Error::UnknownSimdOpcode(opcode) => write!(f, "Unknown SIMD opcode {}", opcode), Error::InvalidVarUint1(val) => write!(f, "Not an unsigned 1-bit integer: {}", val), Error::InvalidVarInt7(val) => write!(f, "Not a signed 7-bit integer: {}", val), Error::InvalidVarInt32 => write!(f, "Not a signed 32-bit integer"), @@ -192,6 +195,7 @@ impl ::std::error::Error for Error { Error::UnknownExternalKind(_) => "Unknown external kind", Error::UnknownInternalKind(_) => "Unknown internal kind", Error::UnknownOpcode(_) => "Unknown opcode", + Error::UnknownSimdOpcode(_) => "Unknown SIMD opcode", Error::InvalidVarUint1(_) => "Not an unsigned 1-bit integer", Error::InvalidVarInt32 => "Not a signed 32-bit integer", Error::InvalidVarInt7(_) => "Not a signed 7-bit integer", diff --git a/src/elements/ops.rs b/src/elements/ops.rs index 56d6829..9a8e3f2 100644 --- a/src/elements/ops.rs +++ b/src/elements/ops.rs @@ -115,7 +115,7 @@ pub enum Instruction { End, Br(u32), BrIf(u32), - BrTable(Box<[u32]>, u32), + BrTable(Box), Return, Call(u32), @@ -369,6 +369,158 @@ pub enum Instruction { I64AtomicRmwCmpxchg8u(MemArg), I64AtomicRmwCmpxchg16u(MemArg), I64AtomicRmwCmpxchg32u(MemArg), + + V128Const(Box<[u8; 16]>), + V128Load(MemArg), + V128Store(MemArg), + I8x16Splat, + I16x8Splat, + I32x4Splat, + I64x2Splat, + F32x4Splat, + F64x2Splat, + I8x16ExtractLaneS(u8), + I8x16ExtractLaneU(u8), + I16x8ExtractLaneS(u8), + I16x8ExtractLaneU(u8), + I32x4ExtractLane(u8), + I64x2ExtractLane(u8), + F32x4ExtractLane(u8), + F64x2ExtractLane(u8), + I8x16ReplaceLane(u8), + I16x8ReplaceLane(u8), + I32x4ReplaceLane(u8), + I64x2ReplaceLane(u8), + F32x4ReplaceLane(u8), + F64x2ReplaceLane(u8), + V8x16Shuffle(Box<[u8; 16]>), + I8x16Add, + I16x8Add, + I32x4Add, + I64x2Add, + I8x16Sub, + I16x8Sub, + I32x4Sub, + I64x2Sub, + I8x16Mul, + I16x8Mul, + I32x4Mul, + // I64x2Mul, + I8x16Neg, + I16x8Neg, + I32x4Neg, + I64x2Neg, + I8x16AddSaturateS, + I8x16AddSaturateU, + I16x8AddSaturateS, + I16x8AddSaturateU, + I8x16SubSaturateS, + I8x16SubSaturateU, + I16x8SubSaturateS, + I16x8SubSaturateU, + I8x16Shl, + I16x8Shl, + I32x4Shl, + I64x2Shl, + I8x16ShrS, + I8x16ShrU, + I16x8ShrS, + I16x8ShrU, + I32x4ShrS, + I32x4ShrU, + I64x2ShrS, + I64x2ShrU, + V128And, + V128Or, + V128Xor, + V128Not, + V128Bitselect, + I8x16AnyTrue, + I16x8AnyTrue, + I32x4AnyTrue, + I64x2AnyTrue, + I8x16AllTrue, + I16x8AllTrue, + I32x4AllTrue, + I64x2AllTrue, + I8x16Eq, + I16x8Eq, + I32x4Eq, + // I64x2Eq, + F32x4Eq, + F64x2Eq, + I8x16Ne, + I16x8Ne, + I32x4Ne, + // I64x2Ne, + F32x4Ne, + F64x2Ne, + I8x16LtS, + I8x16LtU, + I16x8LtS, + I16x8LtU, + I32x4LtS, + I32x4LtU, + // I64x2LtS, + // I64x2LtU, + F32x4Lt, + F64x2Lt, + I8x16LeS, + I8x16LeU, + I16x8LeS, + I16x8LeU, + I32x4LeS, + I32x4LeU, + // I64x2LeS, + // I64x2LeU, + F32x4Le, + F64x2Le, + I8x16GtS, + I8x16GtU, + I16x8GtS, + I16x8GtU, + I32x4GtS, + I32x4GtU, + // I64x2GtS, + // I64x2GtU, + F32x4Gt, + F64x2Gt, + I8x16GeS, + I8x16GeU, + I16x8GeS, + I16x8GeU, + I32x4GeS, + I32x4GeU, + // I64x2GeS, + // I64x2GeU, + F32x4Ge, + F64x2Ge, + F32x4Neg, + F64x2Neg, + F32x4Abs, + F64x2Abs, + F32x4Min, + F64x2Min, + F32x4Max, + F64x2Max, + F32x4Add, + F64x2Add, + F32x4Sub, + F64x2Sub, + F32x4Div, + F64x2Div, + F32x4Mul, + F64x2Mul, + F32x4Sqrt, + F64x2Sqrt, + F32x4ConvertSI32x4, + F32x4ConvertUI32x4, + F64x2ConvertSI64x2, + F64x2ConvertUI64x2, + I32x4TruncSF32x4Sat, + I32x4TruncUF32x4Sat, + I64x2TruncSF64x2Sat, + I64x2TruncUF64x2Sat, } #[derive(Clone, Debug, PartialEq)] @@ -378,6 +530,13 @@ pub struct MemArg { pub offset: u32, } +#[derive(Clone, Debug, PartialEq)] +#[allow(missing_docs)] +pub struct BrTableData { + pub table: Box<[u32]>, + pub default: u32, +} + impl Instruction { /// Is this instruction starts the new block (which should end with terminal instruction). pub fn is_block(&self) -> bool { @@ -653,6 +812,162 @@ pub mod opcodes { pub const I64_ATOMIC_RMW_CMPXCHG8U: u8 = 0x4c; pub const I64_ATOMIC_RMW_CMPXCHG16U: u8 = 0x4d; pub const I64_ATOMIC_RMW_CMPXCHG32U: u8 = 0x4e; + + // https://github.com/WebAssembly/simd/blob/master/proposals/simd/BinarySIMD.md + pub const SIMD_PREFIX: u8 = 0xfd; + + pub const V128_CONST: u32 = 0; + pub const V128_LOAD: u32 = 1; + pub const V128_STORE: u32 = 2; + pub const I8X16_SPLAT: u32 = 3; + pub const I16X8_SPLAT: u32 = 4; + pub const I32X4_SPLAT: u32 = 5; + pub const I64X2_SPLAT: u32 = 6; + pub const F32X4_SPLAT: u32 = 7; + pub const F64X2_SPLAT: u32 = 8; + pub const I8X16_EXTRACT_LANE_S: u32 = 9; + pub const I8X16_EXTRACT_LANE_U: u32 = 10; + pub const I16X8_EXTRACT_LANE_S: u32 = 11; + pub const I16X8_EXTRACT_LANE_U: u32 = 12; + pub const I32X4_EXTRACT_LANE: u32 = 13; + pub const I64X2_EXTRACT_LANE: u32 = 14; + pub const F32X4_EXTRACT_LANE: u32 = 15; + pub const F64X2_EXTRACT_LANE: u32 = 16; + pub const I8X16_REPLACE_LANE: u32 = 17; + pub const I16X8_REPLACE_LANE: u32 = 18; + pub const I32X4_REPLACE_LANE: u32 = 19; + pub const I64X2_REPLACE_LANE: u32 = 20; + pub const F32X4_REPLACE_LANE: u32 = 21; + pub const F64X2_REPLACE_LANE: u32 = 22; + pub const V8X16_SHUFFLE: u32 = 23; + pub const I8X16_ADD: u32 = 24; + pub const I16X8_ADD: u32 = 25; + pub const I32X4_ADD: u32 = 26; + pub const I64X2_ADD: u32 = 27; + pub const I8X16_SUB: u32 = 28; + pub const I16X8_SUB: u32 = 29; + pub const I32X4_SUB: u32 = 30; + pub const I64X2_SUB: u32 = 31; + pub const I8X16_MUL: u32 = 32; + pub const I16X8_MUL: u32 = 33; + pub const I32X4_MUL: u32 = 34; + // pub const I64X2_MUL: u32 = 35; + pub const I8X16_NEG: u32 = 36; + pub const I16X8_NEG: u32 = 37; + pub const I32X4_NEG: u32 = 38; + pub const I64X2_NEG: u32 = 39; + + pub const I8X16_ADD_SATURATE_S: u32 = 40; + pub const I8X16_ADD_SATURATE_U: u32 = 41; + pub const I16X8_ADD_SATURATE_S: u32 = 42; + pub const I16X8_ADD_SATURATE_U: u32 = 43; + pub const I8X16_SUB_SATURATE_S: u32 = 44; + pub const I8X16_SUB_SATURATE_U: u32 = 45; + pub const I16X8_SUB_SATURATE_S: u32 = 46; + pub const I16X8_SUB_SATURATE_U: u32 = 47; + pub const I8X16_SHL: u32 = 48; + pub const I16X8_SHL: u32 = 49; + pub const I32X4_SHL: u32 = 50; + pub const I64X2_SHL: u32 = 51; + pub const I8X16_SHR_S: u32 = 52; + pub const I8X16_SHR_U: u32 = 53; + pub const I16X8_SHR_S: u32 = 54; + pub const I16X8_SHR_U: u32 = 55; + pub const I32X4_SHR_S: u32 = 56; + pub const I32X4_SHR_U: u32 = 57; + pub const I64X2_SHR_S: u32 = 58; + pub const I64X2_SHR_U: u32 = 59; + pub const V128_AND: u32 = 60; + pub const V128_OR: u32 = 61; + pub const V128_XOR: u32 = 62; + pub const V128_NOT: u32 = 63; + pub const V128_BITSELECT: u32 = 64; + pub const I8X16_ANY_TRUE: u32 = 65; + pub const I16X8_ANY_TRUE: u32 = 66; + pub const I32X4_ANY_TRUE: u32 = 67; + pub const I64X2_ANY_TRUE: u32 = 68; + pub const I8X16_ALL_TRUE: u32 = 69; + pub const I16X8_ALL_TRUE: u32 = 70; + pub const I32X4_ALL_TRUE: u32 = 71; + pub const I64X2_ALL_TRUE: u32 = 72; + pub const I8X16_EQ: u32 = 73; + pub const I16X8_EQ: u32 = 74; + pub const I32X4_EQ: u32 = 75; + // pub const I64X2_EQ: u32 = 76; + pub const F32X4_EQ: u32 = 77; + pub const F64X2_EQ: u32 = 78; + pub const I8X16_NE: u32 = 79; + pub const I16X8_NE: u32 = 80; + pub const I32X4_NE: u32 = 81; + // pub const I64X2_NE: u32 = 82; + pub const F32X4_NE: u32 = 83; + pub const F64X2_NE: u32 = 84; + pub const I8X16_LT_S: u32 = 85; + pub const I8X16_LT_U: u32 = 86; + pub const I16X8_LT_S: u32 = 87; + pub const I16X8_LT_U: u32 = 88; + pub const I32X4_LT_S: u32 = 89; + pub const I32X4_LT_U: u32 = 90; + pub const I64X2_LT_S: u32 = 91; + pub const I64X2_LT_U: u32 = 92; + pub const F32X4_LT: u32 = 93; + pub const F64X2_LT: u32 = 94; + pub const I8X16_LE_S: u32 = 95; + pub const I8X16_LE_U: u32 = 96; + pub const I16X8_LE_S: u32 = 97; + pub const I16X8_LE_U: u32 = 98; + pub const I32X4_LE_S: u32 = 99; + pub const I32X4_LE_U: u32 = 100; + pub const I64X2_LE_S: u32 = 101; + pub const I64X2_LE_U: u32 = 102; + pub const F32X4_LE: u32 = 103; + pub const F64X2_LE: u32 = 104; + pub const I8X16_GT_S: u32 = 105; + pub const I8X16_GT_U: u32 = 106; + pub const I16X8_GT_S: u32 = 107; + pub const I16X8_GT_U: u32 = 108; + pub const I32X4_GT_S: u32 = 109; + pub const I32X4_GT_U: u32 = 110; + pub const I64X2_GT_S: u32 = 111; + pub const I64X2_GT_U: u32 = 112; + pub const F32X4_GT: u32 = 113; + pub const F64X2_GT: u32 = 114; + pub const I8X16_GE_S: u32 = 115; + pub const I8X16_GE_U: u32 = 116; + pub const I16X8_GE_S: u32 = 117; + pub const I16X8_GE_U: u32 = 118; + pub const I32X4_GE_S: u32 = 119; + pub const I32X4_GE_U: u32 = 120; + pub const I64X2_GE_S: u32 = 121; + pub const I64X2_GE_U: u32 = 122; + pub const F32X4_GE: u32 = 123; + pub const F64X2_GE: u32 = 124; + pub const F32X4_NEG: u32 = 125; + pub const F64X2_NEG: u32 = 126; + pub const F32X4_ABS: u32 = 127; + pub const F64X2_ABS: u32 = 128; + pub const F32X4_MIN: u32 = 129; + pub const F64X2_MIN: u32 = 130; + pub const F32X4_MAX: u32 = 131; + pub const F64X2_MAX: u32 = 132; + pub const F32X4_ADD: u32 = 133; + pub const F64X2_ADD: u32 = 134; + pub const F32X4_SUB: u32 = 135; + pub const F64X2_SUB: u32 = 136; + pub const F32X4_DIV: u32 = 137; + pub const F64X2_DIV: u32 = 138; + pub const F32X4_MUL: u32 = 139; + pub const F64X2_MUL: u32 = 140; + pub const F32X4_SQRT: u32 = 141; + pub const F64X2_SQRT: u32 = 142; + pub const F32X4_CONVERT_S_I32X4: u32 = 143; + pub const F32X4_CONVERT_U_I32X4: u32 = 144; + pub const F64X2_CONVERT_S_I64X2: u32 = 145; + pub const F64X2_CONVERT_U_I64X2: u32 = 146; + pub const I32X4_TRUNC_S_F32X4_SAT: u32 = 147; + pub const I32X4_TRUNC_U_F32X4_SAT: u32 = 148; + pub const I64X2_TRUNC_S_F64X2_SAT: u32 = 149; + pub const I64X2_TRUNC_U_F64X2_SAT: u32 = 150; } impl Deserialize for Instruction { @@ -683,7 +998,10 @@ impl Deserialize for Instruction { .map(Into::into) .collect(); - BrTable(t1.into_boxed_slice(), VarUint32::deserialize(reader)?.into()) + BrTable(Box::new(BrTableData { + table: t1.into_boxed_slice(), + default: VarUint32::deserialize(reader)?.into(), + })) }, RETURN => Return, CALL => Call(VarUint32::deserialize(reader)?.into()), @@ -946,6 +1264,7 @@ impl Deserialize for Instruction { F64REINTERPRETI64 => F64ReinterpretI64, ATOMIC_PREFIX => return deserialize_atomic(reader), + SIMD_PREFIX => return deserialize_simd(reader), _ => { return Err(Error::UnknownOpcode(val)); } } @@ -1030,6 +1349,177 @@ fn deserialize_atomic(reader: &mut R) -> Result }) } +fn deserialize_simd(reader: &mut R) -> Result { + use self::Instruction::*; + use self::opcodes::*; + + let val = VarUint32::deserialize(reader)?.into(); + Ok(match val { + V128_CONST => { + let mut buf = [0; 16]; + reader.read(&mut buf)?; + V128Const(Box::new(buf)) + } + V128_LOAD => V128Load(MemArg::deserialize(reader)?), + V128_STORE => V128Store(MemArg::deserialize(reader)?), + I8X16_SPLAT => I8x16Splat, + I16X8_SPLAT => I16x8Splat, + I32X4_SPLAT => I32x4Splat, + I64X2_SPLAT => I64x2Splat, + F32X4_SPLAT => F32x4Splat, + F64X2_SPLAT => F64x2Splat, + I8X16_EXTRACT_LANE_S => I8x16ExtractLaneS(Uint8::deserialize(reader)?.into()), + I8X16_EXTRACT_LANE_U => I8x16ExtractLaneU(Uint8::deserialize(reader)?.into()), + I16X8_EXTRACT_LANE_S => I16x8ExtractLaneS(Uint8::deserialize(reader)?.into()), + I16X8_EXTRACT_LANE_U => I16x8ExtractLaneU(Uint8::deserialize(reader)?.into()), + I32X4_EXTRACT_LANE => I32x4ExtractLane(Uint8::deserialize(reader)?.into()), + I64X2_EXTRACT_LANE => I64x2ExtractLane(Uint8::deserialize(reader)?.into()), + F32X4_EXTRACT_LANE => F32x4ExtractLane(Uint8::deserialize(reader)?.into()), + F64X2_EXTRACT_LANE => F64x2ExtractLane(Uint8::deserialize(reader)?.into()), + I8X16_REPLACE_LANE => I8x16ReplaceLane(Uint8::deserialize(reader)?.into()), + I16X8_REPLACE_LANE => I16x8ReplaceLane(Uint8::deserialize(reader)?.into()), + I32X4_REPLACE_LANE => I32x4ReplaceLane(Uint8::deserialize(reader)?.into()), + I64X2_REPLACE_LANE => I64x2ReplaceLane(Uint8::deserialize(reader)?.into()), + F32X4_REPLACE_LANE => F32x4ReplaceLane(Uint8::deserialize(reader)?.into()), + F64X2_REPLACE_LANE => F64x2ReplaceLane(Uint8::deserialize(reader)?.into()), + V8X16_SHUFFLE => { + let mut buf = [0; 16]; + reader.read(&mut buf)?; + V8x16Shuffle(Box::new(buf)) + } + I8X16_ADD => I8x16Add, + I16X8_ADD => I16x8Add, + I32X4_ADD => I32x4Add, + I64X2_ADD => I64x2Add, + I8X16_SUB => I8x16Sub, + I16X8_SUB => I16x8Sub, + I32X4_SUB => I32x4Sub, + I64X2_SUB => I64x2Sub, + I8X16_MUL => I8x16Mul, + I16X8_MUL => I16x8Mul, + I32X4_MUL => I32x4Mul, + // I64X2_MUL => I64x2Mul, + I8X16_NEG => I8x16Neg, + I16X8_NEG => I16x8Neg, + I32X4_NEG => I32x4Neg, + I64X2_NEG => I64x2Neg, + + I8X16_ADD_SATURATE_S => I8x16AddSaturateS, + I8X16_ADD_SATURATE_U => I8x16AddSaturateU, + I16X8_ADD_SATURATE_S => I16x8AddSaturateS, + I16X8_ADD_SATURATE_U => I16x8AddSaturateU, + I8X16_SUB_SATURATE_S => I8x16SubSaturateS, + I8X16_SUB_SATURATE_U => I8x16SubSaturateU, + I16X8_SUB_SATURATE_S => I16x8SubSaturateS, + I16X8_SUB_SATURATE_U => I16x8SubSaturateU, + I8X16_SHL => I8x16Shl, + I16X8_SHL => I16x8Shl, + I32X4_SHL => I32x4Shl, + I64X2_SHL => I64x2Shl, + I8X16_SHR_S => I8x16ShrS, + I8X16_SHR_U => I8x16ShrU, + I16X8_SHR_S => I16x8ShrS, + I16X8_SHR_U => I16x8ShrU, + I32X4_SHR_S => I32x4ShrS, + I32X4_SHR_U => I32x4ShrU, + I64X2_SHR_S => I64x2ShrS, + I64X2_SHR_U => I64x2ShrU, + V128_AND => V128And, + V128_OR => V128Or, + V128_XOR => V128Xor, + V128_NOT => V128Not, + V128_BITSELECT => V128Bitselect, + I8X16_ANY_TRUE => I8x16AnyTrue, + I16X8_ANY_TRUE => I16x8AnyTrue, + I32X4_ANY_TRUE => I32x4AnyTrue, + I64X2_ANY_TRUE => I64x2AnyTrue, + I8X16_ALL_TRUE => I8x16AllTrue, + I16X8_ALL_TRUE => I16x8AllTrue, + I32X4_ALL_TRUE => I32x4AllTrue, + I64X2_ALL_TRUE => I64x2AllTrue, + I8X16_EQ => I8x16Eq, + I16X8_EQ => I16x8Eq, + I32X4_EQ => I32x4Eq, + // I64X2_EQ => I64x2Eq, + F32X4_EQ => F32x4Eq, + F64X2_EQ => F64x2Eq, + I8X16_NE => I8x16Ne, + I16X8_NE => I16x8Ne, + I32X4_NE => I32x4Ne, + // I64X2_NE => I64x2Ne, + F32X4_NE => F32x4Ne, + F64X2_NE => F64x2Ne, + I8X16_LT_S => I8x16LtS, + I8X16_LT_U => I8x16LtU, + I16X8_LT_S => I16x8LtS, + I16X8_LT_U => I16x8LtU, + I32X4_LT_S => I32x4LtS, + I32X4_LT_U => I32x4LtU, + // I64X2_LT_S => I64x2LtS, + // I64X2_LT_U => I64x2LtU, + F32X4_LT => F32x4Lt, + F64X2_LT => F64x2Lt, + I8X16_LE_S => I8x16LeS, + I8X16_LE_U => I8x16LeU, + I16X8_LE_S => I16x8LeS, + I16X8_LE_U => I16x8LeU, + I32X4_LE_S => I32x4LeS, + I32X4_LE_U => I32x4LeU, + // I64X2_LE_S => I64x2LeS, + // I64X2_LE_U => I64x2LeU, + F32X4_LE => F32x4Le, + F64X2_LE => F64x2Le, + I8X16_GT_S => I8x16GtS, + I8X16_GT_U => I8x16GtU, + I16X8_GT_S => I16x8GtS, + I16X8_GT_U => I16x8GtU, + I32X4_GT_S => I32x4GtS, + I32X4_GT_U => I32x4GtU, + // I64X2_GT_S => I64x2GtS, + // I64X2_GT_U => I64x2GtU, + F32X4_GT => F32x4Gt, + F64X2_GT => F64x2Gt, + I8X16_GE_S => I8x16GeS, + I8X16_GE_U => I8x16GeU, + I16X8_GE_S => I16x8GeS, + I16X8_GE_U => I16x8GeU, + I32X4_GE_S => I32x4GeS, + I32X4_GE_U => I32x4GeU, + // I64X2_GE_S => I64x2GeS, + // I64X2_GE_U => I64x2GeU, + F32X4_GE => F32x4Ge, + F64X2_GE => F64x2Ge, + F32X4_NEG => F32x4Neg, + F64X2_NEG => F64x2Neg, + F32X4_ABS => F32x4Abs, + F64X2_ABS => F64x2Abs, + F32X4_MIN => F32x4Min, + F64X2_MIN => F64x2Min, + F32X4_MAX => F32x4Max, + F64X2_MAX => F64x2Max, + F32X4_ADD => F32x4Add, + F64X2_ADD => F64x2Add, + F32X4_SUB => F32x4Sub, + F64X2_SUB => F64x2Sub, + F32X4_DIV => F32x4Div, + F64X2_DIV => F64x2Div, + F32X4_MUL => F32x4Mul, + F64X2_MUL => F64x2Mul, + F32X4_SQRT => F32x4Sqrt, + F64X2_SQRT => F64x2Sqrt, + F32X4_CONVERT_S_I32X4 => F32x4ConvertSI32x4, + F32X4_CONVERT_U_I32X4 => F32x4ConvertUI32x4, + F64X2_CONVERT_S_I64X2 => F64x2ConvertSI64x2, + F64X2_CONVERT_U_I64X2 => F64x2ConvertUI64x2, + I32X4_TRUNC_S_F32X4_SAT => I32x4TruncSF32x4Sat, + I32X4_TRUNC_U_F32X4_SAT => I32x4TruncUF32x4Sat, + I64X2_TRUNC_S_F64X2_SAT => I64x2TruncSF64x2Sat, + I64X2_TRUNC_U_F64X2_SAT => I64x2TruncUF64x2Sat, + + _ => return Err(Error::UnknownSimdOpcode(val)), + }) +} + impl Deserialize for MemArg { type Error = Error; @@ -1058,6 +1548,14 @@ macro_rules! atomic { }); } +macro_rules! simd { + ($writer: expr, $byte: expr, $other:expr) => ({ + $writer.write(&[SIMD_PREFIX])?; + VarUint32::from($byte).serialize($writer)?; + $other; + }); +} + impl Serialize for Instruction { type Error = Error; @@ -1085,13 +1583,13 @@ impl Serialize for Instruction { BrIf(idx) => op!(writer, BRIF, { VarUint32::from(idx).serialize(writer)?; }), - BrTable(table, default) => op!(writer, BRTABLE, { + BrTable(ref table) => op!(writer, BRTABLE, { let list_writer = CountedListWriter::( - table.len(), - table.into_iter().map(|x| VarUint32::from(*x)), + table.table.len(), + table.table.into_iter().map(|x| VarUint32::from(*x)), ); list_writer.serialize(writer)?; - VarUint32::from(default).serialize(writer)?; + VarUint32::from(table.default).serialize(writer)?; }), Return => op!(writer, RETURN), Call(index) => op!(writer, CALL, { @@ -1433,6 +1931,158 @@ impl Serialize for Instruction { I64AtomicRmwCmpxchg8u(m) => atomic!(writer, I64_ATOMIC_RMW_CMPXCHG8U, m), I64AtomicRmwCmpxchg16u(m) => atomic!(writer, I64_ATOMIC_RMW_CMPXCHG16U, m), I64AtomicRmwCmpxchg32u(m) => atomic!(writer, I64_ATOMIC_RMW_CMPXCHG32U, m), + + V128Const(ref c) => simd!(writer, opcodes::V128_CONST, writer.write(&c[..])?), + V128Load(m) => simd!(writer, opcodes::V128_LOAD, MemArg::serialize(m, writer)?), + V128Store(m) => simd!(writer, opcodes::V128_STORE, MemArg::serialize(m, writer)?), + I8x16Splat => simd!(writer, opcodes::I8X16_SPLAT, ()), + I16x8Splat => simd!(writer, opcodes::I16X8_SPLAT, ()), + I32x4Splat => simd!(writer, opcodes::I32X4_SPLAT, ()), + I64x2Splat => simd!(writer, opcodes::I64X2_SPLAT, ()), + F32x4Splat => simd!(writer, opcodes::F32X4_SPLAT, ()), + F64x2Splat => simd!(writer, opcodes::F64X2_SPLAT, ()), + I8x16ExtractLaneS(i) => simd!(writer, opcodes::I8X16_EXTRACT_LANE_S, writer.write(&[i])?), + I8x16ExtractLaneU(i) => simd!(writer, opcodes::I8X16_EXTRACT_LANE_U, writer.write(&[i])?), + I16x8ExtractLaneS(i) => simd!(writer, opcodes::I16X8_EXTRACT_LANE_S, writer.write(&[i])?), + I16x8ExtractLaneU(i) => simd!(writer, opcodes::I16X8_EXTRACT_LANE_U, writer.write(&[i])?), + I32x4ExtractLane(i) => simd!(writer, opcodes::I32X4_EXTRACT_LANE, writer.write(&[i])?), + I64x2ExtractLane(i) => simd!(writer, opcodes::I64X2_EXTRACT_LANE, writer.write(&[i])?), + F32x4ExtractLane(i) => simd!(writer, opcodes::F32X4_EXTRACT_LANE, writer.write(&[i])?), + F64x2ExtractLane(i) => simd!(writer, opcodes::F64X2_EXTRACT_LANE, writer.write(&[i])?), + I8x16ReplaceLane(i) => simd!(writer, opcodes::I8X16_REPLACE_LANE, writer.write(&[i])?), + I16x8ReplaceLane(i) => simd!(writer, opcodes::I16X8_REPLACE_LANE, writer.write(&[i])?), + I32x4ReplaceLane(i) => simd!(writer, opcodes::I32X4_REPLACE_LANE, writer.write(&[i])?), + I64x2ReplaceLane(i) => simd!(writer, opcodes::I64X2_REPLACE_LANE, writer.write(&[i])?), + F32x4ReplaceLane(i) => simd!(writer, opcodes::F32X4_REPLACE_LANE, writer.write(&[i])?), + F64x2ReplaceLane(i) => simd!(writer, opcodes::F64X2_REPLACE_LANE, writer.write(&[i])?), + V8x16Shuffle(ref i) => simd!(writer, opcodes::V8X16_SHUFFLE, writer.write(&i[..])?), + I8x16Add => simd!(writer, opcodes::I8X16_ADD, ()), + I16x8Add => simd!(writer, opcodes::I16X8_ADD, ()), + I32x4Add => simd!(writer, opcodes::I32X4_ADD, ()), + I64x2Add => simd!(writer, opcodes::I64X2_ADD, ()), + I8x16Sub => simd!(writer, opcodes::I8X16_SUB, ()), + I16x8Sub => simd!(writer, opcodes::I16X8_SUB, ()), + I32x4Sub => simd!(writer, opcodes::I32X4_SUB, ()), + I64x2Sub => simd!(writer, opcodes::I64X2_SUB, ()), + I8x16Mul => simd!(writer, opcodes::I8X16_MUL, ()), + I16x8Mul => simd!(writer, opcodes::I16X8_MUL, ()), + I32x4Mul => simd!(writer, opcodes::I32X4_MUL, ()), + // I64x2Mul => simd!(writer, opcodes::I64X2_MUL, ()), + I8x16Neg => simd!(writer, opcodes::I8X16_NEG, ()), + I16x8Neg => simd!(writer, opcodes::I16X8_NEG, ()), + I32x4Neg => simd!(writer, opcodes::I32X4_NEG, ()), + I64x2Neg => simd!(writer, opcodes::I64X2_NEG, ()), + I8x16AddSaturateS => simd!(writer, opcodes::I8X16_ADD_SATURATE_S, ()), + I8x16AddSaturateU => simd!(writer, opcodes::I8X16_ADD_SATURATE_U, ()), + I16x8AddSaturateS => simd!(writer, opcodes::I16X8_ADD_SATURATE_S, ()), + I16x8AddSaturateU => simd!(writer, opcodes::I16X8_ADD_SATURATE_U, ()), + I8x16SubSaturateS => simd!(writer, opcodes::I8X16_SUB_SATURATE_S, ()), + I8x16SubSaturateU => simd!(writer, opcodes::I8X16_SUB_SATURATE_U, ()), + I16x8SubSaturateS => simd!(writer, opcodes::I16X8_SUB_SATURATE_S, ()), + I16x8SubSaturateU => simd!(writer, opcodes::I16X8_SUB_SATURATE_U, ()), + I8x16Shl => simd!(writer, opcodes::I8X16_SHL, ()), + I16x8Shl => simd!(writer, opcodes::I16X8_SHL, ()), + I32x4Shl => simd!(writer, opcodes::I32X4_SHL, ()), + I64x2Shl => simd!(writer, opcodes::I64X2_SHL, ()), + I8x16ShrS => simd!(writer, opcodes::I8X16_SHR_S, ()), + I8x16ShrU => simd!(writer, opcodes::I8X16_SHR_U, ()), + I16x8ShrS => simd!(writer, opcodes::I16X8_SHR_S, ()), + I16x8ShrU => simd!(writer, opcodes::I16X8_SHR_U, ()), + I32x4ShrU => simd!(writer, opcodes::I32X4_SHR_U, ()), + I32x4ShrS => simd!(writer, opcodes::I32X4_SHR_S, ()), + I64x2ShrU => simd!(writer, opcodes::I64X2_SHR_U, ()), + I64x2ShrS => simd!(writer, opcodes::I64X2_SHR_S, ()), + V128And => simd!(writer, opcodes::V128_AND, ()), + V128Or => simd!(writer, opcodes::V128_OR, ()), + V128Xor => simd!(writer, opcodes::V128_XOR, ()), + V128Not => simd!(writer, opcodes::V128_NOT, ()), + V128Bitselect => simd!(writer, opcodes::V128_BITSELECT, ()), + I8x16AnyTrue => simd!(writer, opcodes::I8X16_ANY_TRUE, ()), + I16x8AnyTrue => simd!(writer, opcodes::I16X8_ANY_TRUE, ()), + I32x4AnyTrue => simd!(writer, opcodes::I32X4_ANY_TRUE, ()), + I64x2AnyTrue => simd!(writer, opcodes::I64X2_ANY_TRUE, ()), + I8x16AllTrue => simd!(writer, opcodes::I8X16_ALL_TRUE, ()), + I16x8AllTrue => simd!(writer, opcodes::I16X8_ALL_TRUE, ()), + I32x4AllTrue => simd!(writer, opcodes::I32X4_ALL_TRUE, ()), + I64x2AllTrue => simd!(writer, opcodes::I64X2_ALL_TRUE, ()), + I8x16Eq => simd!(writer, opcodes::I8X16_EQ, ()), + I16x8Eq => simd!(writer, opcodes::I16X8_EQ, ()), + I32x4Eq => simd!(writer, opcodes::I32X4_EQ, ()), + // I64x2Eq => simd!(writer, opcodes::I64X2_EQ, ()), + F32x4Eq => simd!(writer, opcodes::F32X4_EQ, ()), + F64x2Eq => simd!(writer, opcodes::F64X2_EQ, ()), + I8x16Ne => simd!(writer, opcodes::I8X16_NE, ()), + I16x8Ne => simd!(writer, opcodes::I16X8_NE, ()), + I32x4Ne => simd!(writer, opcodes::I32X4_NE, ()), + // I64x2Ne => simd!(writer, opcodes::I64X2_NE, ()), + F32x4Ne => simd!(writer, opcodes::F32X4_NE, ()), + F64x2Ne => simd!(writer, opcodes::F64X2_NE, ()), + I8x16LtS => simd!(writer, opcodes::I8X16_LT_S, ()), + I8x16LtU => simd!(writer, opcodes::I8X16_LT_U, ()), + I16x8LtS => simd!(writer, opcodes::I16X8_LT_S, ()), + I16x8LtU => simd!(writer, opcodes::I16X8_LT_U, ()), + I32x4LtS => simd!(writer, opcodes::I32X4_LT_S, ()), + I32x4LtU => simd!(writer, opcodes::I32X4_LT_U, ()), + // I64x2LtS => simd!(writer, opcodes::I64X2_LT_S, ()), + // I64x2LtU => simd!(writer, opcodes::I64X2_LT_U, ()), + F32x4Lt => simd!(writer, opcodes::F32X4_LT, ()), + F64x2Lt => simd!(writer, opcodes::F64X2_LT, ()), + I8x16LeS => simd!(writer, opcodes::I8X16_LE_S, ()), + I8x16LeU => simd!(writer, opcodes::I8X16_LE_U, ()), + I16x8LeS => simd!(writer, opcodes::I16X8_LE_S, ()), + I16x8LeU => simd!(writer, opcodes::I16X8_LE_U, ()), + I32x4LeS => simd!(writer, opcodes::I32X4_LE_S, ()), + I32x4LeU => simd!(writer, opcodes::I32X4_LE_U, ()), + // I64x2LeS => simd!(writer, opcodes::I64X2_LE_S, ()), + // I64x2LeU => simd!(writer, opcodes::I64X2_LE_U, ()), + F32x4Le => simd!(writer, opcodes::F32X4_LE, ()), + F64x2Le => simd!(writer, opcodes::F64X2_LE, ()), + I8x16GtS => simd!(writer, opcodes::I8X16_GT_S, ()), + I8x16GtU => simd!(writer, opcodes::I8X16_GT_U, ()), + I16x8GtS => simd!(writer, opcodes::I16X8_GT_S, ()), + I16x8GtU => simd!(writer, opcodes::I16X8_GT_U, ()), + I32x4GtS => simd!(writer, opcodes::I32X4_GT_S, ()), + I32x4GtU => simd!(writer, opcodes::I32X4_GT_U, ()), + // I64x2GtS => simd!(writer, opcodes::I64X2_GT_S, ()), + // I64x2GtU => simd!(writer, opcodes::I64X2_GT_U, ()), + F32x4Gt => simd!(writer, opcodes::F32X4_GT, ()), + F64x2Gt => simd!(writer, opcodes::F64X2_GT, ()), + I8x16GeS => simd!(writer, opcodes::I8X16_GE_S, ()), + I8x16GeU => simd!(writer, opcodes::I8X16_GE_U, ()), + I16x8GeS => simd!(writer, opcodes::I16X8_GE_S, ()), + I16x8GeU => simd!(writer, opcodes::I16X8_GE_U, ()), + I32x4GeS => simd!(writer, opcodes::I32X4_GE_S, ()), + I32x4GeU => simd!(writer, opcodes::I32X4_GE_U, ()), + // I64x2GeS => simd!(writer, opcodes::I64X2_GE_S, ()), + // I64x2GeU => simd!(writer, opcodes::I64X2_GE_U, ()), + F32x4Ge => simd!(writer, opcodes::F32X4_GE, ()), + F64x2Ge => simd!(writer, opcodes::F64X2_GE, ()), + F32x4Neg => simd!(writer, opcodes::F32X4_NEG, ()), + F64x2Neg => simd!(writer, opcodes::F64X2_NEG, ()), + F32x4Abs => simd!(writer, opcodes::F32X4_ABS, ()), + F64x2Abs => simd!(writer, opcodes::F64X2_ABS, ()), + F32x4Min => simd!(writer, opcodes::F32X4_MIN, ()), + F64x2Min => simd!(writer, opcodes::F64X2_MIN, ()), + F32x4Max => simd!(writer, opcodes::F32X4_MAX, ()), + F64x2Max => simd!(writer, opcodes::F64X2_MAX, ()), + F32x4Add => simd!(writer, opcodes::F32X4_ADD, ()), + F64x2Add => simd!(writer, opcodes::F64X2_ADD, ()), + F32x4Sub => simd!(writer, opcodes::F32X4_SUB, ()), + F64x2Sub => simd!(writer, opcodes::F64X2_SUB, ()), + F32x4Div => simd!(writer, opcodes::F32X4_DIV, ()), + F64x2Div => simd!(writer, opcodes::F64X2_DIV, ()), + F32x4Mul => simd!(writer, opcodes::F32X4_MUL, ()), + F64x2Mul => simd!(writer, opcodes::F64X2_MUL, ()), + F32x4Sqrt => simd!(writer, opcodes::F32X4_SQRT, ()), + F64x2Sqrt => simd!(writer, opcodes::F64X2_SQRT, ()), + F32x4ConvertSI32x4 => simd!(writer, opcodes::F32X4_CONVERT_S_I32X4, ()), + F32x4ConvertUI32x4 => simd!(writer, opcodes::F32X4_CONVERT_U_I32X4, ()), + F64x2ConvertSI64x2 => simd!(writer, opcodes::F64X2_CONVERT_S_I64X2, ()), + F64x2ConvertUI64x2 => simd!(writer, opcodes::F64X2_CONVERT_U_I64X2, ()), + I32x4TruncSF32x4Sat => simd!(writer, opcodes::I32X4_TRUNC_S_F32X4_SAT, ()), + I32x4TruncUF32x4Sat => simd!(writer, opcodes::I32X4_TRUNC_U_F32X4_SAT, ()), + I64x2TruncSF64x2Sat => simd!(writer, opcodes::I64X2_TRUNC_S_F64X2_SAT, ()), + I64x2TruncUF64x2Sat => simd!(writer, opcodes::I64X2_TRUNC_U_F64X2_SAT, ()), } Ok(()) @@ -1479,7 +2129,7 @@ impl fmt::Display for Instruction { End => fmt_op!(f, "end"), Br(idx) => fmt_op!(f, "br", idx), BrIf(idx) => fmt_op!(f, "br_if", idx), - BrTable(_, default) => fmt_op!(f, "br_table", default), + BrTable(ref table) => fmt_op!(f, "br_table", table.default), Return => fmt_op!(f, "return"), Call(index) => fmt_op!(f, "call", index), CallIndirect(index, _) => fmt_op!(f, "call_indirect", index), @@ -1779,6 +2429,158 @@ impl fmt::Display for Instruction { I64AtomicRmwCmpxchg8u(_) => write!(f, "i64.atomic.rmw8_u.cmpxchg"), I64AtomicRmwCmpxchg16u(_) => write!(f, "i64.atomic.rmw16_u.cmpxchg"), I64AtomicRmwCmpxchg32u(_) => write!(f, "i64.atomic.rmw32_u.cmpxchg"), + + V128Const(_) => write!(f, "v128.const"), + V128Load(_) => write!(f, "v128.load"), + V128Store(_) => write!(f, "v128.store"), + I8x16Splat => write!(f, "i8x16.splat"), + I16x8Splat => write!(f, "i16x8.splat"), + I32x4Splat => write!(f, "i32x4.splat"), + I64x2Splat => write!(f, "i64x2.splat"), + F32x4Splat => write!(f, "f32x4.splat"), + F64x2Splat => write!(f, "f64x2.splat"), + I8x16ExtractLaneS(_) => write!(f, "i8x16.extract_lane_s"), + I8x16ExtractLaneU(_) => write!(f, "i8x16.extract_lane_u"), + I16x8ExtractLaneS(_) => write!(f, "i16x8.extract_lane_s"), + I16x8ExtractLaneU(_) => write!(f, "i16x8.extract_lane_u"), + I32x4ExtractLane(_) => write!(f, "i32x4.extract_lane"), + I64x2ExtractLane(_) => write!(f, "i64x2.extract_lane"), + F32x4ExtractLane(_) => write!(f, "f32x4.extract_lane"), + F64x2ExtractLane(_) => write!(f, "f64x2.extract_lane"), + I8x16ReplaceLane(_) => write!(f, "i8x16.replace_lane"), + I16x8ReplaceLane(_) => write!(f, "i16x8.replace_lane"), + I32x4ReplaceLane(_) => write!(f, "i32x4.replace_lane"), + I64x2ReplaceLane(_) => write!(f, "i64x2.replace_lane"), + F32x4ReplaceLane(_) => write!(f, "f32x4.replace_lane"), + F64x2ReplaceLane(_) => write!(f, "f64x2.replace_lane"), + V8x16Shuffle(_) => write!(f, "v8x16.shuffle"), + I8x16Add => write!(f, "i8x16.add"), + I16x8Add => write!(f, "i16x8.add"), + I32x4Add => write!(f, "i32x4.add"), + I64x2Add => write!(f, "i64x2.add"), + I8x16Sub => write!(f, "i8x16.sub"), + I16x8Sub => write!(f, "i16x8.sub"), + I32x4Sub => write!(f, "i32x4.sub"), + I64x2Sub => write!(f, "i64x2.sub"), + I8x16Mul => write!(f, "i8x16.mul"), + I16x8Mul => write!(f, "i16x8.mul"), + I32x4Mul => write!(f, "i32x4.mul"), + // I64x2Mul => write!(f, "i64x2.mul"), + I8x16Neg => write!(f, "i8x16.neg"), + I16x8Neg => write!(f, "i16x8.neg"), + I32x4Neg => write!(f, "i32x4.neg"), + I64x2Neg => write!(f, "i64x2.neg"), + I8x16AddSaturateS => write!(f, "i8x16.add_saturate_s"), + I8x16AddSaturateU => write!(f, "i8x16.add_saturate_u"), + I16x8AddSaturateS => write!(f, "i16x8.add_saturate_S"), + I16x8AddSaturateU => write!(f, "i16x8.add_saturate_u"), + I8x16SubSaturateS => write!(f, "i8x16.sub_saturate_S"), + I8x16SubSaturateU => write!(f, "i8x16.sub_saturate_u"), + I16x8SubSaturateS => write!(f, "i16x8.sub_saturate_S"), + I16x8SubSaturateU => write!(f, "i16x8.sub_saturate_u"), + I8x16Shl => write!(f, "i8x16.shl"), + I16x8Shl => write!(f, "i16x8.shl"), + I32x4Shl => write!(f, "i32x4.shl"), + I64x2Shl => write!(f, "i64x2.shl"), + I8x16ShrS => write!(f, "i8x16.shr_s"), + I8x16ShrU => write!(f, "i8x16.shr_u"), + I16x8ShrS => write!(f, "i16x8.shr_s"), + I16x8ShrU => write!(f, "i16x8.shr_u"), + I32x4ShrS => write!(f, "i32x4.shr_s"), + I32x4ShrU => write!(f, "i32x4.shr_u"), + I64x2ShrS => write!(f, "i64x2.shr_s"), + I64x2ShrU => write!(f, "i64x2.shr_u"), + V128And => write!(f, "v128.and"), + V128Or => write!(f, "v128.or"), + V128Xor => write!(f, "v128.xor"), + V128Not => write!(f, "v128.not"), + V128Bitselect => write!(f, "v128.bitselect"), + I8x16AnyTrue => write!(f, "i8x16.any_true"), + I16x8AnyTrue => write!(f, "i16x8.any_true"), + I32x4AnyTrue => write!(f, "i32x4.any_true"), + I64x2AnyTrue => write!(f, "i64x2.any_true"), + I8x16AllTrue => write!(f, "i8x16.all_true"), + I16x8AllTrue => write!(f, "i16x8.all_true"), + I32x4AllTrue => write!(f, "i32x4.all_true"), + I64x2AllTrue => write!(f, "i64x2.all_true"), + I8x16Eq => write!(f, "i8x16.eq"), + I16x8Eq => write!(f, "i16x8.eq"), + I32x4Eq => write!(f, "i32x4.eq"), + // I64x2Eq => write!(f, "i64x2.eq"), + F32x4Eq => write!(f, "f32x4.eq"), + F64x2Eq => write!(f, "f64x2.eq"), + I8x16Ne => write!(f, "i8x16.ne"), + I16x8Ne => write!(f, "i16x8.ne"), + I32x4Ne => write!(f, "i32x4.ne"), + // I64x2Ne => write!(f, "i64x2.ne"), + F32x4Ne => write!(f, "f32x4.ne"), + F64x2Ne => write!(f, "f64x2.ne"), + I8x16LtS => write!(f, "i8x16.lt_s"), + I8x16LtU => write!(f, "i8x16.lt_u"), + I16x8LtS => write!(f, "i16x8.lt_s"), + I16x8LtU => write!(f, "i16x8.lt_u"), + I32x4LtS => write!(f, "i32x4.lt_s"), + I32x4LtU => write!(f, "i32x4.lt_u"), + // I64x2LtS => write!(f, "// I64x2.lt_s"), + // I64x2LtU => write!(f, "// I64x2.lt_u"), + F32x4Lt => write!(f, "f32x4.lt"), + F64x2Lt => write!(f, "f64x2.lt"), + I8x16LeS => write!(f, "i8x16.le_s"), + I8x16LeU => write!(f, "i8x16.le_u"), + I16x8LeS => write!(f, "i16x8.le_s"), + I16x8LeU => write!(f, "i16x8.le_u"), + I32x4LeS => write!(f, "i32x4.le_s"), + I32x4LeU => write!(f, "i32x4.le_u"), + // I64x2LeS => write!(f, "// I64x2.le_s"), + // I64x2LeU => write!(f, "// I64x2.le_u"), + F32x4Le => write!(f, "f32x4.le"), + F64x2Le => write!(f, "f64x2.le"), + I8x16GtS => write!(f, "i8x16.gt_s"), + I8x16GtU => write!(f, "i8x16.gt_u"), + I16x8GtS => write!(f, "i16x8.gt_s"), + I16x8GtU => write!(f, "i16x8.gt_u"), + I32x4GtS => write!(f, "i32x4.gt_s"), + I32x4GtU => write!(f, "i32x4.gt_u"), + // I64x2GtS => write!(f, "// I64x2.gt_s"), + // I64x2GtU => write!(f, "// I64x2.gt_u"), + F32x4Gt => write!(f, "f32x4.gt"), + F64x2Gt => write!(f, "f64x2.gt"), + I8x16GeS => write!(f, "i8x16.ge_s"), + I8x16GeU => write!(f, "i8x16.ge_u"), + I16x8GeS => write!(f, "i16x8.ge_s"), + I16x8GeU => write!(f, "i16x8.ge_u"), + I32x4GeS => write!(f, "i32x4.ge_s"), + I32x4GeU => write!(f, "i32x4.ge_u"), + // I64x2GeS => write!(f, "// I64x2.ge_s"), + // I64x2GeU => write!(f, "// I64x2.ge_u"), + F32x4Ge => write!(f, "f32x4.ge"), + F64x2Ge => write!(f, "f64x2.ge"), + F32x4Neg => write!(f, "f32x4.neg"), + F64x2Neg => write!(f, "f64x2.neg"), + F32x4Abs => write!(f, "f32x4.abs"), + F64x2Abs => write!(f, "f64x2.abs"), + F32x4Min => write!(f, "f32x4.min"), + F64x2Min => write!(f, "f64x2.min"), + F32x4Max => write!(f, "f32x4.max"), + F64x2Max => write!(f, "f64x2.max"), + F32x4Add => write!(f, "f32x4.add"), + F64x2Add => write!(f, "f64x2.add"), + F32x4Sub => write!(f, "f32x4.sub"), + F64x2Sub => write!(f, "f64x2.sub"), + F32x4Div => write!(f, "f32x4.div"), + F64x2Div => write!(f, "f64x2.div"), + F32x4Mul => write!(f, "f32x4.mul"), + F64x2Mul => write!(f, "f64x2.mul"), + F32x4Sqrt => write!(f, "f32x4.sqrt"), + F64x2Sqrt => write!(f, "f64x2.sqrt"), + F32x4ConvertSI32x4 => write!(f, "f32x4.convert_s/i32x4"), + F32x4ConvertUI32x4 => write!(f, "f32x4.convert_u/i32x4"), + F64x2ConvertSI64x2 => write!(f, "f64x2.convert_s/i64x2"), + F64x2ConvertUI64x2 => write!(f, "f64x2.convert_u/i64x2"), + I32x4TruncSF32x4Sat => write!(f, "i32x4.trunc_s/f32x4:sat"), + I32x4TruncUF32x4Sat => write!(f, "i32x4.trunc_u/f32x4:sat"), + I64x2TruncSF64x2Sat => write!(f, "i64x2.trunc_s/f64x2:sat"), + I64x2TruncUF64x2Sat => write!(f, "i64x2.trunc_u/f64x2:sat"), } } } diff --git a/src/elements/types.rs b/src/elements/types.rs index 7d79f14..fade103 100644 --- a/src/elements/types.rs +++ b/src/elements/types.rs @@ -42,6 +42,8 @@ pub enum ValueType { F32, /// 64-bit float F64, + /// 128-bit SIMD register + V128, } impl Deserialize for ValueType { @@ -55,6 +57,7 @@ impl Deserialize for ValueType { -0x02 => Ok(ValueType::I64), -0x03 => Ok(ValueType::F32), -0x04 => Ok(ValueType::F64), + -0x05 => Ok(ValueType::V128), _ => Err(Error::UnknownValueType(val.into())), } } @@ -69,6 +72,7 @@ impl Serialize for ValueType { ValueType::I64 => -0x02, ValueType::F32 => -0x03, ValueType::F64 => -0x04, + ValueType::V128 => -0x05, }.into(); val.serialize(writer)?; Ok(()) @@ -82,6 +86,7 @@ impl fmt::Display for ValueType { ValueType::I64 => write!(f, "i64"), ValueType::F32 => write!(f, "f32"), ValueType::F64 => write!(f, "f64"), + ValueType::V128 => write!(f, "v128"), } } } @@ -106,6 +111,7 @@ impl Deserialize for BlockType { -0x02 => Ok(BlockType::Value(ValueType::I64)), -0x03 => Ok(BlockType::Value(ValueType::F32)), -0x04 => Ok(BlockType::Value(ValueType::F64)), + 0x7b => Ok(BlockType::Value(ValueType::V128)), -0x40 => Ok(BlockType::NoResult), _ => Err(Error::UnknownValueType(val.into())), } @@ -122,6 +128,7 @@ impl Serialize for BlockType { BlockType::Value(ValueType::I64) => -0x02, BlockType::Value(ValueType::F32) => -0x03, BlockType::Value(ValueType::F64) => -0x04, + BlockType::Value(ValueType::V128) => 0x7b, }.into(); val.serialize(writer)?; Ok(())