Proposal for vector instructions IR

This proposal drops the memory alignment from u32
that is required by spec to a u16. But I think
u16 should be more than enough to represent any
real alignment.

Also this is closer to a custom asm than a IR but
whatever...
This commit is contained in:
Ernesto Lanchares 2025-03-24 17:41:18 +00:00 committed by Lorenzo Torres
parent 56559a9386
commit 942bb3525d

View file

@ -3,9 +3,20 @@ const Parser = @import("Parser.zig");
const Allocator = std.mem.Allocator;
const VectorIndex = packed struct {
opcode: VectorOpcode,
laneidx: u8,
memarg: Memarg,
};
const Memarg = packed struct {
offset: u32,
/// Accordng to spec this should be a `u32` but who the fuck needs that big of an alignment? Moreover
/// if we make this value bigger, then VectorIndex does not fit anymore :(
alignment: u16,
};
const DIndex = packed struct {
first: u32,
second: u32,
x: u32,
y: u32,
};
comptime {
// TODO: is this too big? we could do with 32 bits and a bit more indirection
@ -19,7 +30,10 @@ const Index = packed union {
i64: i64,
f32: f32,
f64: f64,
di: DIndex,
indirect: DIndex,
reftype: std.wasm.RefType,
memarg: Memarg,
vector: VectorIndex,
};
opcodes: []Opcode,
@ -27,9 +41,12 @@ opcodes: []Opcode,
/// Read the docs of each opcode to know what the index means.
indices: []Index,
// TODO: this could be a byte array and v128.const and i8x16.shuffle could live here too
select_valtypes: []Parser.Valtype,
/// Opcodes
/// Opcodes.
/// This is a mix of wasm opcodes mixed with a few of our own.
/// Mainly for `0xFC` opcodes we use `0xD3` to `0xF5`.
pub const Opcode = enum(u8) {
// CONTROL INSTRUCTIONS
// The rest of instructions should be implemented in terms of these ones
@ -42,21 +59,25 @@ pub const Opcode = enum(u8) {
/// TODO: this instruction (could be also implemented in terms of br and br_if)
br_table = 0x0E,
@"return" = 0x0F,
/// Index: `u64`. Meaning: The function index to call
/// Index: `u32`. Meaning: The function index to call
call = 0x10,
/// TODO: index (is it enough with using a double index here? if we consider it enough then the other indices should use u32)
/// Index: `DIndex`. Meaning: `DIndex.x` is the table index and `DIndex.y` is the typeindex
call_indirect = 0x11,
// REFERENCE INSTRUCTIONS
// This should be resolved at parse time and therefore not part of IR
/// Index: `Parser.Reftype`. Meaning: reftype
refnull = 0xD0,
refisnull = 0xD1,
/// Index: `u32`. Meaning: funcidx
reffunc = 0xD2,
// PARAMETRIC INSTRUCTIONS
// Select with no valtypes should be resolved at parse time
drop = 0x1A,
select = 0x1B,
/// Index: `DIndex`. Meaning:
/// `first` is the index into `select_valtypes` array and
/// `second` is the number of valtypes
select = 0x1C,
/// `DIndex.x` is the index into `select_valtypes` array and
/// `DIndex.y` is the number of valtypes
select_with_values = 0x1C,
// VARIABLE INSTRUCTIONS
/// Index: `u32`. Meaing: index into local variables
@ -75,202 +96,491 @@ pub const Opcode = enum(u8) {
tableget = 0x25,
/// Index: `u32`. Meaning: index into table index
tableset = 0x26,
/// TODO: table operation. Value in wasm: 0xFC. Note wher is 0x27?
tableop = 0xF0,
/// Index: `DIndex`. Meaning: TODO
tableinit = 0xD3,
/// Index: `u32`. Meaning: TODO
elemdrop = 0xD4,
/// Index: `DIndex`. Meaning: `DIndex.x` is destination `DIndex.y` is source
tablecopy = 0xD5,
/// Index: `u32`. Meaning: tableidx
tablegrow = 0xD6,
/// Index: `u32`. Meaning: tableidx
tablesize = 0xD7,
/// Index: `u32`. Meaning: tableidx
tablefill = 0xD8,
// MEMORY INSTRUCTIONS
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i32load = 0x28,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i64load = 0x29,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
f32load = 0x2A,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
f64load = 0x2B,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i32load8_s = 0x2C,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i32load8_u = 0x2D,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i32load16_s = 0x2E,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i32load16_u = 0x2F,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i64load8_s = 0x30,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i64load8_u = 0x31,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i64load16_s = 0x32,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i64load16_u = 0x33,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i64load32_s = 0x34,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i64load32_u = 0x35,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i32store = 0x36,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i64store = 0x37,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
f32store = 0x38,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
f64store = 0x39,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i32store8 = 0x3A,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i32store16 = 0x3B,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i64store8 = 0x3C,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i64store16 = 0x3D,
/// Index: `DIndex`. Meaning: `firts` is alignment, `second` is offset
i64store32 = 0x3E,
/// Index: `Memarg`. Meaning: memarg
i32_load = 0x28,
/// Index: `Memarg`. Meaning: memarg
i64_load = 0x29,
/// Index: `Memarg`. Meaning: memarg
f32_load = 0x2A,
/// Index: `Memarg`. Meaning: memarg
f64_load = 0x2B,
/// Index: `Memarg`. Meaning: memarg
i32_load8_s = 0x2C,
/// Index: `Memarg`. Meaning: memarg
i32_load8_u = 0x2D,
/// Index: `Memarg`. Meaning: memarg
i32_load16_s = 0x2E,
/// Index: `Memarg`. Meaning: memarg
i32_load16_u = 0x2F,
/// Index: `Memarg`. Meaning: memarg
i64_load8_s = 0x30,
/// Index: `Memarg`. Meaning: memarg
i64_load8_u = 0x31,
/// Index: `Memarg`. Meaning: memarg
i64_load16_s = 0x32,
/// Index: `Memarg`. Meaning: memarg
i64_load16_u = 0x33,
/// Index: `Memarg`. Meaning: memarg
i64_load32_s = 0x34,
/// Index: `Memarg`. Meaning: memarg
i64_load32_u = 0x35,
/// Index: `Memarg`. Meaning: memarg
i32_store = 0x36,
/// Index: `Memarg`. Meaning: memarg
i64_store = 0x37,
/// Index: `Memarg`. Meaning: memarg
f32_store = 0x38,
/// Index: `Memarg`. Meaning: memarg
f64_store = 0x39,
/// Index: `Memarg`. Meaning: memarg
i32_store8 = 0x3A,
/// Index: `Memarg`. Meaning: memarg
i32_store16 = 0x3B,
/// Index: `Memarg`. Meaning: memarg
i64_store8 = 0x3C,
/// Index: `Memarg`. Meaning: memarg
i64_store16 = 0x3D,
/// Index: `Memarg`. Meaning: memarg
i64_store32 = 0x3E,
memorysize = 0x3F,
memorygrow = 0x40,
/// TODO: memory operation. Value in wasm: 0xFC
memoryop = 0xF1,
/// Index: `u32`. Meaning: dataidx
memoryinit = 0xD9,
/// Index: `u32`. Meaning: dataidx
datadrop = 0xDA,
memorycopy = 0xDB,
memoryfill = 0xDC,
// NUMERIC INSTRUCTION
/// Index: `i32`. Meaning: constant
i32const = 0x41,
i32_const = 0x41,
/// Index: `i64`. Meaning: constant
i64const = 0x42,
i64_const = 0x42,
/// Index: `f32`. Meaning: constant
f32const = 0x43,
f32_const = 0x43,
/// Index: `f64`. Meaning: constant
f64const = 0x44,
i32eqz = 0x45,
i32eq = 0x46,
i32ne = 0x47,
i32lt_s = 0x48,
i32lt_u = 0x49,
i32gt_s = 0x4A,
i32gt_u = 0x4B,
i32le_s = 0x4C,
i32le_u = 0x4D,
i32ge_s = 0x4E,
i32ge_u = 0x4F,
i64eqz = 0x50,
i64eq = 0x51,
i64ne = 0x52,
i64lt_s = 0x53,
i64lt_u = 0x54,
i64gt_s = 0x55,
i64gt_u = 0x56,
i64le_s = 0x57,
i64le_u = 0x58,
i64ge_s = 0x59,
i64ge_u = 0x5A,
f32eq = 0x5B,
f32ne = 0x5C,
f32lt = 0x5D,
f32gt = 0x5E,
f32le = 0x5F,
f32ge = 0x60,
f64eq = 0x61,
f64ne = 0x62,
f64lt = 0x63,
f64gt = 0x64,
f64le = 0x65,
f64ge = 0x66,
i32clz = 0x67,
i32ctz = 0x68,
i32popcnt = 0x69,
i32add = 0x6A,
i32sub = 0x6B,
i32mul = 0x6C,
i32div_s = 0x6D,
i32div_u = 0x6E,
i32rem_s = 0x6F,
i32rem_u = 0x70,
i32and = 0x71,
i32or = 0x72,
i32xor = 0x73,
i32shl = 0x74,
i32shr_s = 0x75,
i32shr_u = 0x76,
i32rotl = 0x77,
i32rotr = 0x78,
i64clz = 0x79,
i64ctz = 0x7A,
i64popcnt = 0x7B,
i64add = 0x7C,
i64sub = 0x7D,
i64mul = 0x7E,
i64div_s = 0x7F,
i64div_u = 0x80,
i64rem_s = 0x81,
i64rem_u = 0x82,
i64and = 0x83,
i64or = 0x84,
i64xor = 0x85,
i64shl = 0x86,
i64shr_s = 0x87,
i64shr_u = 0x88,
i64rotl = 0x89,
i64rotr = 0x8A,
f32abs = 0x8B,
f32neg = 0x8C,
f32ceil = 0x8D,
f32floor = 0x8E,
f32trunc = 0x8F,
f32nearest = 0x90,
f32sqrt = 0x91,
f32add = 0x92,
f32sub = 0x93,
f32mul = 0x94,
f32div = 0x95,
f32min = 0x96,
f32max = 0x97,
f32copysign = 0x98,
f64abs = 0x99,
f64neg = 0x9A,
f64ceil = 0x9B,
f64floor = 0x9C,
f64trunc = 0x9D,
f64nearest = 0x9E,
f64sqrt = 0x9F,
f64add = 0xA0,
f64sub = 0xA1,
f64mul = 0xA2,
f64div = 0xA3,
f64min = 0xA4,
f64max = 0xA5,
f64copysign = 0xA6,
i32wrap_i64 = 0xA7,
i32trunc_f32_s = 0xA8,
i32trunc_f32_u = 0xA9,
i32trunc_f64_s = 0xAA,
i32trunc_f64_u = 0xAB,
i64extend_i32_s = 0xAC,
i64extend_i32_u = 0xAD,
i64trunc_f32_s = 0xAE,
i64trunc_f32_u = 0xAF,
i64trunc_f64_s = 0xB0,
i64trunc_f64_u = 0xB1,
f32convert_i32_s = 0xB2,
f32convert_i32_u = 0xB3,
f32convert_i64_s = 0xB4,
f32convert_i64_u = 0xB5,
f32demote_f64 = 0xB6,
f64convert_i32_s = 0xB7,
f64convert_i32_u = 0xB8,
f64convert_i64_s = 0xB9,
f64convert_i64_u = 0xBA,
f64promote_f32 = 0xBB,
i32reinterpret_f32 = 0xBC,
i64reinterpret_f64 = 0xBD,
f32reinterpret_i32 = 0xBE,
f64reinterpret_i64 = 0xBF,
i32extend8_s = 0xC0,
i32extend16_s = 0xC1,
i64extend8_s = 0xC2,
i64extend16_s = 0xC3,
i64extend32_s = 0xC4,
/// TODO: saturation truncation instructions. Value in wasm: 0xFC
sattrunc = 0xF2,
f64_const = 0x44,
i32_eqz = 0x45,
i32_eq = 0x46,
i32_ne = 0x47,
i32_lt_s = 0x48,
i32_lt_u = 0x49,
i32_gt_s = 0x4A,
i32_gt_u = 0x4B,
i32_le_s = 0x4C,
i32_le_u = 0x4D,
i32_ge_s = 0x4E,
i32_ge_u = 0x4F,
i64_eqz = 0x50,
i64_eq = 0x51,
i64_ne = 0x52,
i64_lt_s = 0x53,
i64_lt_u = 0x54,
i64_gt_s = 0x55,
i64_gt_u = 0x56,
i64_le_s = 0x57,
i64_le_u = 0x58,
i64_ge_s = 0x59,
i64_ge_u = 0x5A,
f32_eq = 0x5B,
f32_ne = 0x5C,
f32_lt = 0x5D,
f32_gt = 0x5E,
f32_le = 0x5F,
f32_ge = 0x60,
f64_eq = 0x61,
f64_ne = 0x62,
f64_lt = 0x63,
f64_gt = 0x64,
f64_le = 0x65,
f64_ge = 0x66,
i32_clz = 0x67,
i32_ctz = 0x68,
i32_popcnt = 0x69,
i32_add = 0x6A,
i32_sub = 0x6B,
i32_mul = 0x6C,
i32_div_s = 0x6D,
i32_div_u = 0x6E,
i32_rem_s = 0x6F,
i32_rem_u = 0x70,
i32_and = 0x71,
i32_or = 0x72,
i32_xor = 0x73,
i32_shl = 0x74,
i32_shr_s = 0x75,
i32_shr_u = 0x76,
i32_rotl = 0x77,
i32_rotr = 0x78,
i64_clz = 0x79,
i64_ctz = 0x7A,
i64_popcnt = 0x7B,
i64_add = 0x7C,
i64_sub = 0x7D,
i64_mul = 0x7E,
i64_div_s = 0x7F,
i64_div_u = 0x80,
i64_rem_s = 0x81,
i64_rem_u = 0x82,
i64_and = 0x83,
i64_or = 0x84,
i64_xor = 0x85,
i64_shl = 0x86,
i64_shr_s = 0x87,
i64_shr_u = 0x88,
i64_rotl = 0x89,
i64_rotr = 0x8A,
f32_abs = 0x8B,
f32_neg = 0x8C,
f32_ceil = 0x8D,
f32_floor = 0x8E,
f32_trunc = 0x8F,
f32_nearest = 0x90,
f32_sqrt = 0x91,
f32_add = 0x92,
f32_sub = 0x93,
f32_mul = 0x94,
f32_div = 0x95,
f32_min = 0x96,
f32_max = 0x97,
f32_copysign = 0x98,
f64_abs = 0x99,
f64_neg = 0x9A,
f64_ceil = 0x9B,
f64_floor = 0x9C,
f64_trunc = 0x9D,
f64_nearest = 0x9E,
f64_sqrt = 0x9F,
f64_add = 0xA0,
f64_sub = 0xA1,
f64_mul = 0xA2,
f64_div = 0xA3,
f64_min = 0xA4,
f64_max = 0xA5,
f64_copysign = 0xA6,
i32_wrap_i64 = 0xA7,
i32_trunc_f32_s = 0xA8,
i32_trunc_f32_u = 0xA9,
i32_trunc_f64_s = 0xAA,
i32_trunc_f64_u = 0xAB,
i64_extend_i32_s = 0xAC,
i64_extend_i32_u = 0xAD,
i64_trunc_f32_s = 0xAE,
i64_trunc_f32_u = 0xAF,
i64_trunc_f64_s = 0xB0,
i64_trunc_f64_u = 0xB1,
f32_convert_i32_s = 0xB2,
f32_convert_i32_u = 0xB3,
f32_convert_i64_s = 0xB4,
f32_convert_i64_u = 0xB5,
f32_demote_f64 = 0xB6,
f64_convert_i32_s = 0xB7,
f64_convert_i32_u = 0xB8,
f64_convert_i64_s = 0xB9,
f64_convert_i64_u = 0xBA,
f64_promote_f32 = 0xBB,
i32_reinterpret_f32 = 0xBC,
i64_reinterpret_f64 = 0xBD,
f32_reinterpret_i32 = 0xBE,
f64_reinterpret_i64 = 0xBF,
i32_extend8_s = 0xC0,
i32_extend16_s = 0xC1,
i64_extend8_s = 0xC2,
i64_extend16_s = 0xC3,
i64_extend32_s = 0xC4,
i32_trunc_sat_f32_s = 0xDD,
i32_trunc_sat_f32_u = 0xDF,
i32_trunc_sat_f64_s = 0xF0,
i32_trunc_sat_f64_u = 0xF1,
i64_trunc_sat_f32_s = 0xF2,
i64_trunc_sat_f32_u = 0xF3,
i64_trunc_sat_f64_s = 0xF4,
i64_trunc_sat_f64_u = 0xF5,
// VECTOR INSTRUCTIONS
/// TODO: vector instructions. Value in wasm: 0xFC. Note: there are opcodes available lol
vecinst = 0xF3,
/// Index: `VectorIndex`. Meaning: See `VectorOpcode`
vecinst = 0xFD,
};
const VectorOpcode = enum(u8) {
v128_load = 0,
v128_load8x8_s = 1,
v128_load8x8_u = 2,
v128_load16x4_s = 3,
v128_load16x4_u = 4,
v128_load32x2_s = 5,
v128_load32x2_u = 6,
v128_load8_splat = 7,
v128_load16_splat = 8,
v128_load32_splat = 9,
v128_load64_splat = 10,
v128_load32_zero = 92,
v128_load64_zero = 93,
v128_store = 11,
v128_load8_lane = 84,
v128_load16_lane = 85,
v128_load32_lane = 86,
v128_load64_lane = 87,
v128_store8_lane = 88,
v128_store16_lane = 89,
v128_store32_lane = 90,
v128_store64_lane = 91,
/// TODO
v128_const = 12,
/// TODO
i8x16_shuffle = 13,
i8x16_extract_lane_s = 21,
i8x16_extract_lane_u = 22,
i8x16_replace_lane = 23,
i16x8_extract_lane_s = 24,
i16x8_extract_lane_u = 25,
i16x8_replace_lane = 26,
i32x4_extract_lane = 27,
i32x4_replace_lane = 28,
i64x2_extract_lane = 29,
i64x2_replace_lane = 30,
f32x4_extract_lane = 31,
f32x4_replace_lane = 32,
f64x2_extract_lane = 33,
f64x2_replace_lane = 34,
i8x16_swizzle = 14,
i8x16_splat = 15,
i16x8_splat = 16,
i32x4_splat = 17,
i64x2_splat = 18,
f32x4_splat = 19,
f64x2_splat = 20,
i8x16_eq = 35,
i8x16_ne = 36,
i8x16_lt_s = 37,
i8x16_lt_u = 38,
i8x16_gt_s = 39,
i8x16_gt_u = 40,
i8x16_le_s = 41,
i8x16_le_u = 42,
i8x16_ge_s = 43,
i8x16_ge_u = 44,
i16x8_eq = 45,
i16x8_ne = 46,
i16x8_lt_s = 47,
i16x8_lt_u = 48,
i16x8_gt_s = 49,
i16x8_gt_u = 50,
i16x8_le_s = 51,
i16x8_le_u = 52,
i16x8_ge_s = 53,
i16x8_ge_u = 54,
i32x4_eq = 55,
i32x4_ne = 56,
i32x4_lt_s = 57,
i32x4_lt_u = 58,
i32x4_gt_s = 59,
i32x4_gt_u = 60,
i32x4_le_s = 61,
i32x4_le_u = 62,
i32x4_ge_s = 63,
i32x4_ge_u = 64,
i64x2_eq = 214,
i64x2_ne = 215,
i64x2_lt_s = 216,
i64x2_gt_s = 217,
i64x2_le_s = 218,
i64x2_ge_s = 219,
f32x4_eq = 65,
f32x4_ne = 66,
f32x4_lt = 67,
f32x4_gt = 68,
f32x4_le = 69,
f32x4_ge = 70,
f64x2_eq = 71,
f64x2_ne = 72,
f64x2_lt = 73,
f64x2_gt = 74,
f64x2_le = 75,
f64x2_ge = 76,
v128_not = 77,
v128_and = 78,
v128_andnot = 79,
v128_or = 80,
v128x_or = 81,
v128_bitselect = 82,
v128_any_true = 83,
i8x16_abs = 96,
i8x16_neg = 97,
i8x16_popcnt = 98,
i8x16_all_true = 99,
i8x16_bitmask = 100,
i8x16_narrow_i16x8_s = 101,
i8x16_narrow_i16x8_u = 102,
i8x16_shl = 107,
i8x16_shr_s = 108,
i8x16_shr_u = 109,
i8x16_add = 110,
i8x16_add_sat_s = 111,
i8x16_add_sat_u = 112,
i8x16_sub = 113,
i8x16_sub_sat_s = 114,
i8x16_sub_sat_u = 115,
i8x16_min_s = 118,
i8x16_min_u = 119,
i8x16_max_s = 120,
i8x16_max_u = 121,
i8x16_avgr_u = 123,
i16x8_extadd_pairwise_i8x16_s = 124,
i16x8_extadd_pairwise_i8x16_u = 125,
i16x8_abs = 128,
i16x8_neg = 129,
i16x8_q15mulr_sat_s = 130,
i16x8_all_true = 131,
i16x8_bitmask = 132,
i16x8_narrow_i32x4_s = 133,
i16x8_narrow_i32x4_u = 134,
i16x8_extend_low_i8x16_s = 135,
i16x8_extend_high_i8x16_s = 136,
i16x8_extend_low_i8x16_u = 137,
i16x8_extend_high_i8x16_u = 138,
i16x8_shl = 139,
i16x8_shr_s = 140,
i16x8_shr_u = 141,
i16x8_add = 142,
i16x8_add_sat_s = 143,
i16x8_add_sat_u = 144,
i16x8_sub = 145,
i16x8_sub_sat_s = 146,
i16x8_sub_sat_u = 147,
i16x8_mul = 149,
i16x8_min_s = 150,
i16x8_min_u = 151,
i16x8_max_s = 152,
i16x8_max_u = 153,
i16x8_avgr_u = 155,
i16x8_extmul_low_i8x16_s = 156,
i16x8_extmul_high_i8x16_s = 157,
i16x8_extmul_low_i8x16_u = 158,
i16x8_extmul_high_u8x16_u = 159,
i32x4_extadd_pairwise_i16x8_s = 126,
i32x4_extadd_pairwise_i16x8_u = 127,
i32x4_abs = 160,
i32x4_neg = 161,
i32x4_all_true = 163,
i32x4_bitmask = 164,
i32x4_extend_low_i16x8_s = 167,
i32x4_extend_high_i16x8_s = 168,
i32x4_extend_low_i16x8_u = 169,
i32x4_extend_high_i16x8_u = 170,
i32x4_shl = 171,
i32x4_shr_s = 172,
i32x4_shr_u = 173,
i32x4_add = 174,
i32x4_sib = 177,
i32x4_mul = 181,
i32x4_min_s = 182,
i32x4_min_u = 183,
i32x4_max_s = 184,
i32x4_max_u = 185,
i32x4_dot_i16x8_s = 186,
i32x4_extmul_low_i16x8_s = 188,
i32x4_extmul_high_i16x8_s = 189,
i32x4_extmul_los_i16x8_u = 190,
i32x4_extmul_high_i16x8_u = 191,
i64x2_abs = 192,
i64x2_neg = 193,
i64x2_all_true = 195,
i64x2_bitmask = 196,
i64x2_extend_low_i32x4_s = 199,
i64x2_extend_high_i32x4_s = 200,
i64x2_extend_low_i32x4_u = 201,
i64x2_extend_high_i32x4_u = 202,
i64x2_shl = 203,
i64x2_shr_s = 204,
i64x2_shr_u = 205,
i64x2_add = 206,
i64x2_sub = 209,
i64x2_mul = 213,
i64x2_extmul_low_i32x4_s = 220,
i64x2_extmul_high_i32x4_s = 221,
i64x2_extmul_low_i32x4_u = 222,
i64x2_extmul_high_i32x4_u = 223,
f32x4_ceil = 103,
f32x4_floor = 104,
f32x4_trunc = 105,
f32x4_nearest = 106,
f32x4_abs = 224,
f32x4_neg = 225,
f32x4_sqrt = 227,
f32x4_add = 228,
f32x4_sub = 229,
f32x4_mul = 230,
f32x4_div = 231,
f32x4_min = 232,
f32x4_max = 233,
f32x4_pmin = 234,
f32x4_pmax = 235,
f64x2_ceil = 116,
f64x2_floor = 117,
f64x2_trunc = 122,
f64x2_nearest = 148,
f64x2_abs = 236,
f64x2_neg = 237,
f64x2_sqrt = 239,
f64x2_add = 240,
f64x2_sub = 241,
f64x2_mul = 242,
f64x2_div = 243,
f64x2_min = 244,
f64x2_max = 245,
f64x2_pmin = 246,
f64x2_pmax = 247,
i32x4_trunc_sat_f32x4_s = 248,
i32x4_trunc_sat_f32x4_u = 249,
f32x4_convert_i32x4_s = 250,
f32x4_convert_i32x4_u = 251,
i32x4_trunc_sat_f64x2_s_zero = 252,
i32x4_trunc_sat_f64x2_u_zero = 253,
f64x2_convert_low_i32x4_s = 254,
f64x2_convert_low_i32x4_u = 255,
f32x4_demote_f64x2_zero = 94,
f64x2_promote_low_f32x4 = 95,
};