Binary encoding of SIMD

This document describes the binary encoding of the SIMD value type and instructions.

SIMD value type

The v128 value type is encoded as 0x7b:

valtype ::= ...
          | 0x7B => v128

SIMD instruction encodings

All SIMD instructions are encoded as a 0xfd prefix byte followed by a SIMD-specific opcode in LEB128 format:

instr ::= ...
        | 0xFD simdop:varuint32 ...

Some SIMD instructions have additional immediate operands following simdop. These immediate operands are encoded as individual bytes. For example, the i8x16.shuffle instruction has 16 bytes after simdop.

In the description below, ImmLaneIdx{I} indicates the maximum value of the byte. For example, ImmLaneIdx16 is a byte with values in the range 0-15 (inclusive).

InstructionsimdopImmediate operands
v128.load0x00m:memarg
v128.load8x8_s0x01m:memarg
v128.load8x8_u0x02m:memarg
v128.load16x4_s0x03m:memarg
v128.load16x4_u0x04m:memarg
v128.load32x2_s0x05m:memarg
v128.load32x2_u0x06m:memarg
v128.load8_splat0x07m:memarg
v128.load16_splat0x08m:memarg
v128.load32_splat0x09m:memarg
v128.load64_splat0x0am:memarg
v128.store0x0bm:memarg
v128.const0x0ci:ImmByte[16]
i8x16.shuffle0x0ds:ImmLaneIdx32[16]
i8x16.swizzle0x0e-
i8x16.splat0x0f-
i16x8.splat0x10-
i32x4.splat0x11-
i64x2.splat0x12-
f32x4.splat0x13-
f64x2.splat0x14-
i8x16.extract_lane_s0x15i:ImmLaneIdx16
i8x16.extract_lane_u0x16i:ImmLaneIdx16
i8x16.replace_lane0x17i:ImmLaneIdx16
i16x8.extract_lane_s0x18i:ImmLaneIdx8
i16x8.extract_lane_u0x19i:ImmLaneIdx8
i16x8.replace_lane0x1ai:ImmLaneIdx8
i32x4.extract_lane0x1bi:ImmLaneIdx4
i32x4.replace_lane0x1ci:ImmLaneIdx4
i64x2.extract_lane0x1di:ImmLaneIdx2
i64x2.replace_lane0x1ei:ImmLaneIdx2
f32x4.extract_lane0x1fi:ImmLaneIdx4
f32x4.replace_lane0x20i:ImmLaneIdx4
f64x2.extract_lane0x21i:ImmLaneIdx2
f64x2.replace_lane0x22i:ImmLaneIdx2
i8x16.eq0x23-
i8x16.ne0x24-
i8x16.lt_s0x25-
i8x16.lt_u0x26-
i8x16.gt_s0x27-
i8x16.gt_u0x28-
i8x16.le_s0x29-
i8x16.le_u0x2a-
i8x16.ge_s0x2b-
i8x16.ge_u0x2c-
i16x8.eq0x2d-
i16x8.ne0x2e-
i16x8.lt_s0x2f-
i16x8.lt_u0x30-
i16x8.gt_s0x31-
i16x8.gt_u0x32-
i16x8.le_s0x33-
i16x8.le_u0x34-
i16x8.ge_s0x35-
i16x8.ge_u0x36-
i32x4.eq0x37-
i32x4.ne0x38-
i32x4.lt_s0x39-
i32x4.lt_u0x3a-
i32x4.gt_s0x3b-
i32x4.gt_u0x3c-
i32x4.le_s0x3d-
i32x4.le_u0x3e-
i32x4.ge_s0x3f-
i32x4.ge_u0x40-
f32x4.eq0x41-
f32x4.ne0x42-
f32x4.lt0x43-
f32x4.gt0x44-
f32x4.le0x45-
f32x4.ge0x46-
f64x2.eq0x47-
f64x2.ne0x48-
f64x2.lt0x49-
f64x2.gt0x4a-
f64x2.le0x4b-
f64x2.ge0x4c-
v128.not0x4d-
v128.and0x4e-
v128.andnot0x4f-
v128.or0x50-
v128.xor0x51-
v128.bitselect0x52-
i8x16.abs0x60-
i8x16.neg0x61-
i8x16.all_true0x63-
i8x16.bitmask0x64-
i8x16.narrow_i16x8_s0x65-
i8x16.narrow_i16x8_u0x66-
i8x16.shl0x6b-
i8x16.shr_s0x6c-
i8x16.shr_u0x6d-
i8x16.add0x6e-
i8x16.add_sat_s0x6f-
i8x16.add_sat_u0x70-
i8x16.sub0x71-
i8x16.sub_sat_s0x72-
i8x16.sub_sat_u0x73-
i8x16.min_s0x76-
i8x16.min_u0x77-
i8x16.max_s0x78-
i8x16.max_u0x79-
i8x16.avgr_u0x7b-
i16x8.abs0x80-
i16x8.neg0x81-
i16x8.all_true0x83-
i16x8.bitmask0x84-
i16x8.narrow_i32x4_s0x85-
i16x8.narrow_i32x4_u0x86-
i16x8.extend_low_i8x16_s0x87-
i16x8.extend_high_i8x16_s0x88-
i16x8.extend_low_i8x16_u0x89-
i16x8.extend_high_i8x16_u0x8a-
i16x8.shl0x8b-
i16x8.shr_s0x8c-
i16x8.shr_u0x8d-
i16x8.add0x8e-
i16x8.add_sat_s0x8f-
i16x8.add_sat_u0x90-
i16x8.sub0x91-
i16x8.sub_sat_s0x92-
i16x8.sub_sat_u0x93-
i16x8.mul0x95-
i16x8.min_s0x96-
i16x8.min_u0x97-
i16x8.max_s0x98-
i16x8.max_u0x99-
i16x8.avgr_u0x9b-
i32x4.abs0xa0-
i32x4.neg0xa1-
i32x4.all_true0xa3-
i32x4.bitmask0xa4-
i32x4.extend_low_i16x8_s0xa7-
i32x4.extend_high_i16x8_s0xa8-
i32x4.extend_low_i16x8_u0xa9-
i32x4.extend_high_i16x8_u0xaa-
i32x4.shl0xab-
i32x4.shr_s0xac-
i32x4.shr_u0xad-
i32x4.add0xae-
i32x4.sub0xb1-
i32x4.mul0xb5-
i32x4.min_s0xb6-
i32x4.min_u0xb7-
i32x4.max_s0xb8-
i32x4.max_u0xb9-
i32x4.dot_i16x8_s0xba-
i64x2.abs0xc0-
i64x2.neg0xc1-
i64x2.bitmask0xc4-
i64x2.extend_low_i32x4_s0xc7-
i64x2.extend_high_i32x4_s0xc8-
i64x2.extend_low_i32x4_u0xc9-
i64x2.extend_high_i32x4_u0xca-
i64x2.shl0xcb-
i64x2.shr_s0xcc-
i64x2.shr_u0xcd-
i64x2.add0xce-
i64x2.sub0xd1-
i64x2.mul0xd5-
f32x4.ceil0x67-
f32x4.floor0x68-
f32x4.trunc0x69-
f32x4.nearest0x6a-
f64x2.ceil0x74-
f64x2.floor0x75-
f64x2.trunc0x7a-
f64x2.nearest0x94-
f32x4.abs0xe0-
f32x4.neg0xe1-
f32x4.sqrt0xe3-
f32x4.add0xe4-
f32x4.sub0xe5-
f32x4.mul0xe6-
f32x4.div0xe7-
f32x4.min0xe8-
f32x4.max0xe9-
f32x4.pmin0xea-
f32x4.pmax0xeb-
f64x2.abs0xec-
f64x2.neg0xed-
f64x2.sqrt0xef-
f64x2.add0xf0-
f64x2.sub0xf1-
f64x2.mul0xf2-
f64x2.div0xf3-
f64x2.min0xf4-
f64x2.max0xf5-
f64x2.pmin0xf6-
f64x2.pmax0xf7-
i32x4.trunc_sat_f32x4_s0xf8-
i32x4.trunc_sat_f32x4_u0xf9-
f32x4.convert_i32x4_s0xfa-
f32x4.convert_i32x4_u0xfb-
v128.load32_zero0x5cm:memarg
v128.load64_zero0x5dm:memarg
i16x8.extmul_low_i8x16_s0x9c-
i16x8.extmul_high_i8x16_s0x9d-
i16x8.extmul_low_i8x16_u0x9e-
i16x8.extmul_high_i8x16_u0x9f-
i32x4.extmul_low_i16x8_s0xbc-
i32x4.extmul_high_i16x8_s0xbd-
i32x4.extmul_low_i16x8_u0xbe-
i32x4.extmul_high_i16x8_u0xbf-
i64x2.extmul_low_i32x4_s0xdc-
i64x2.extmul_high_i32x4_s0xdd-
i64x2.extmul_low_i32x4_u0xde-
i64x2.extmul_high_i32x4_u0xdf-
i16x8.q15mulr_sat_s0x82-
v128.any_true0x53-
v128.load8_lane0x54m:memarg, i:ImmLaneIdx16
v128.load16_lane0x55m:memarg, i:ImmLaneIdx8
v128.load32_lane0x56m:memarg, i:ImmLaneIdx4
v128.load64_lane0x57m:memarg, i:ImmLaneIdx2
v128.store8_lane0x58m:memarg, i:ImmLaneIdx16
v128.store16_lane0x59m:memarg, i:ImmLaneIdx8
v128.store32_lane0x5am:memarg, i:ImmLaneIdx4
v128.store64_lane0x5bm:memarg, i:ImmLaneIdx2
i64x2.eq0xd6-
i64x2.ne0xd7-
i64x2.lt_s0xd8-
i64x2.gt_s0xd9-
i64x2.le_s0xda-
i64x2.ge_s0xdb-
i64x2.all_true0xc3-
f64x2.convert_low_i32x4_s0xfe-
f64x2.convert_low_i32x4_u0xff-
i32x4.trunc_sat_f64x2_s_zero0xfc-
i32x4.trunc_sat_f64x2_u_zero0xfd-
f32x4.demote_f64x2_zero0x5e-
f64x2.promote_low_f32x40x5f-
i8x16.popcnt0x62-
i16x8.extadd_pairwise_i8x16_s0x7c-
i16x8.extadd_pairwise_i8x16_u0x7d-
i32x4.extadd_pairwise_i16x8_s0x7e-
i32x4.extadd_pairwise_i16x8_u0x7f-