Skip to content

Commit 5c5845f

Browse files
authored
Add support for Relaxed SIMD proposal instructions (bytecodealliance#359)
1 parent f1199b9 commit 5c5845f

19 files changed

Lines changed: 429 additions & 14 deletions

File tree

crates/wasm-encoder/src/code.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,23 @@ pub enum Instruction<'a> {
664664
F64x2ConvertLowI32x4U,
665665
F32x4DemoteF64x2Zero,
666666
F64x2PromoteLowF32x4,
667+
I8x16SwizzleRelaxed,
668+
I32x4TruncSatF32x4SRelaxed,
669+
I32x4TruncSatF32x4URelaxed,
670+
I32x4TruncSatF64x2SZeroRelaxed,
671+
I32x4TruncSatF64x2UZeroRelaxed,
672+
F32x4FmaRelaxed,
673+
F32x4FmsRelaxed,
674+
F64x2FmaRelaxed,
675+
F64x2FmsRelaxed,
676+
I8x16LaneSelect,
677+
I16x8LaneSelect,
678+
I32x4LaneSelect,
679+
I64x2LaneSelect,
680+
F32x4MinRelaxed,
681+
F32x4MaxRelaxed,
682+
F64x2MinRelaxed,
683+
F64x2MaxRelaxed,
667684
}
668685

669686
impl Instruction<'_> {
@@ -2140,6 +2157,74 @@ impl Instruction<'_> {
21402157
bytes.push(0xFD);
21412158
bytes.extend(encoders::u32(0xDB));
21422159
}
2160+
Instruction::I8x16SwizzleRelaxed => {
2161+
bytes.push(0xFD);
2162+
bytes.extend(encoders::u32(0xA2));
2163+
}
2164+
Instruction::I32x4TruncSatF32x4SRelaxed => {
2165+
bytes.push(0xFD);
2166+
bytes.extend(encoders::u32(0xA5));
2167+
}
2168+
Instruction::I32x4TruncSatF32x4URelaxed => {
2169+
bytes.push(0xFD);
2170+
bytes.extend(encoders::u32(0xA6));
2171+
}
2172+
Instruction::I32x4TruncSatF64x2SZeroRelaxed => {
2173+
bytes.push(0xFD);
2174+
bytes.extend(encoders::u32(0xC5));
2175+
}
2176+
Instruction::I32x4TruncSatF64x2UZeroRelaxed => {
2177+
bytes.push(0xFD);
2178+
bytes.extend(encoders::u32(0xC6));
2179+
}
2180+
Instruction::F32x4FmaRelaxed => {
2181+
bytes.push(0xFD);
2182+
bytes.extend(encoders::u32(0xAF));
2183+
}
2184+
Instruction::F32x4FmsRelaxed => {
2185+
bytes.push(0xFD);
2186+
bytes.extend(encoders::u32(0xB0));
2187+
}
2188+
Instruction::F64x2FmaRelaxed => {
2189+
bytes.push(0xFD);
2190+
bytes.extend(encoders::u32(0xCF));
2191+
}
2192+
Instruction::F64x2FmsRelaxed => {
2193+
bytes.push(0xFD);
2194+
bytes.extend(encoders::u32(0xD0));
2195+
}
2196+
Instruction::I8x16LaneSelect => {
2197+
bytes.push(0xFD);
2198+
bytes.extend(encoders::u32(0xB2));
2199+
}
2200+
Instruction::I16x8LaneSelect => {
2201+
bytes.push(0xFD);
2202+
bytes.extend(encoders::u32(0xB3));
2203+
}
2204+
Instruction::I32x4LaneSelect => {
2205+
bytes.push(0xFD);
2206+
bytes.extend(encoders::u32(0xD2));
2207+
}
2208+
Instruction::I64x2LaneSelect => {
2209+
bytes.push(0xFD);
2210+
bytes.extend(encoders::u32(0xD3));
2211+
}
2212+
Instruction::F32x4MinRelaxed => {
2213+
bytes.push(0xFD);
2214+
bytes.extend(encoders::u32(0xB4));
2215+
}
2216+
Instruction::F32x4MaxRelaxed => {
2217+
bytes.push(0xFD);
2218+
bytes.extend(encoders::u32(0xE2));
2219+
}
2220+
Instruction::F64x2MinRelaxed => {
2221+
bytes.push(0xFD);
2222+
bytes.extend(encoders::u32(0xD4));
2223+
}
2224+
Instruction::F64x2MaxRelaxed => {
2225+
bytes.push(0xFD);
2226+
bytes.extend(encoders::u32(0xEE));
2227+
}
21432228
}
21442229
}
21452230
}

crates/wasm-smith/src/code_builder.rs

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -324,15 +324,19 @@ instructions! {
324324
(Some(simd_v128_f32_on_stack), f32x4_replace_lane),
325325
(Some(simd_v128_on_stack), f64x2_extract_lane),
326326
(Some(simd_v128_f64_on_stack), f64x2_replace_lane),
327-
(Some(simd_v128_v128_on_stack), i8x16_swizzle),
328327
(Some(simd_i32_on_stack), i8x16_splat),
329328
(Some(simd_i32_on_stack), i16x8_splat),
330329
(Some(simd_i32_on_stack), i32x4_splat),
331330
(Some(simd_i64_on_stack), i64x2_splat),
332331
(Some(simd_f32_on_stack), f32x4_splat),
333332
(Some(simd_f64_on_stack), f64x2_splat),
334333
(Some(simd_v128_v128_on_stack), i8x16_swizzle),
334+
(Some(simd_v128_v128_on_stack_relaxed), i8x16_swizzle_relaxed),
335335
(Some(simd_v128_v128_v128_on_stack), v128_bitselect),
336+
(Some(simd_v128_v128_v128_on_stack_relaxed), i8x16_laneselect),
337+
(Some(simd_v128_v128_v128_on_stack_relaxed), i16x8_laneselect),
338+
(Some(simd_v128_v128_v128_on_stack_relaxed), i32x4_laneselect),
339+
(Some(simd_v128_v128_v128_on_stack_relaxed), i64x2_laneselect),
336340
(Some(simd_v128_v128_on_stack), i8x16_eq),
337341
(Some(simd_v128_v128_on_stack), i8x16_ne),
338342
(Some(simd_v128_v128_on_stack), i8x16_lt_s),
@@ -523,6 +527,18 @@ instructions! {
523527
(Some(simd_v128_on_stack), f64x2_convert_low_i32x4u),
524528
(Some(simd_v128_on_stack), f32x4_demote_f64x2_zero),
525529
(Some(simd_v128_on_stack), f64x2_promote_low_f32x4),
530+
(Some(simd_v128_on_stack_relaxed), i32x4_trunc_sat_f32x4s_relaxed),
531+
(Some(simd_v128_on_stack_relaxed), i32x4_trunc_sat_f32x4u_relaxed),
532+
(Some(simd_v128_on_stack_relaxed), i32x4_trunc_sat_f64x2s_zero_relaxed),
533+
(Some(simd_v128_on_stack_relaxed), i32x4_trunc_sat_f64x2u_zero_relaxed),
534+
(Some(simd_v128_v128_on_stack_relaxed), f32x4_fma_relaxed),
535+
(Some(simd_v128_v128_on_stack_relaxed), f32x4_fms_relaxed),
536+
(Some(simd_v128_v128_on_stack_relaxed), f64x2_fma_relaxed),
537+
(Some(simd_v128_v128_on_stack_relaxed), f64x2_fms_relaxed),
538+
(Some(simd_v128_v128_on_stack_relaxed), f32x4_min_relaxed),
539+
(Some(simd_v128_v128_on_stack_relaxed), f32x4_max_relaxed),
540+
(Some(simd_v128_v128_on_stack_relaxed), f64x2_min_relaxed),
541+
(Some(simd_v128_v128_on_stack_relaxed), f64x2_max_relaxed),
526542
}
527543

528544
pub(crate) struct CodeBuilderAllocations {
@@ -3420,17 +3436,33 @@ fn simd_v128_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
34203436
module.config.simd_enabled() && builder.types_on_stack(&[ValType::V128])
34213437
}
34223438

3439+
#[inline]
3440+
fn simd_v128_on_stack_relaxed(module: &Module, builder: &mut CodeBuilder) -> bool {
3441+
module.config.relaxed_simd_enabled() && builder.types_on_stack(&[ValType::V128])
3442+
}
3443+
34233444
#[inline]
34243445
fn simd_v128_v128_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
34253446
module.config.simd_enabled() && builder.types_on_stack(&[ValType::V128, ValType::V128])
34263447
}
34273448

3449+
#[inline]
3450+
fn simd_v128_v128_on_stack_relaxed(module: &Module, builder: &mut CodeBuilder) -> bool {
3451+
module.config.relaxed_simd_enabled() && builder.types_on_stack(&[ValType::V128, ValType::V128])
3452+
}
3453+
34283454
#[inline]
34293455
fn simd_v128_v128_v128_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
34303456
module.config.simd_enabled()
34313457
&& builder.types_on_stack(&[ValType::V128, ValType::V128, ValType::V128])
34323458
}
34333459

3460+
#[inline]
3461+
fn simd_v128_v128_v128_on_stack_relaxed(module: &Module, builder: &mut CodeBuilder) -> bool {
3462+
module.config.relaxed_simd_enabled()
3463+
&& builder.types_on_stack(&[ValType::V128, ValType::V128, ValType::V128])
3464+
}
3465+
34343466
#[inline]
34353467
fn simd_v128_i32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
34363468
module.config.simd_enabled() && builder.types_on_stack(&[ValType::V128, ValType::I32])
@@ -3657,6 +3689,20 @@ macro_rules! simd_unop {
36573689
};
36583690
}
36593691

3692+
macro_rules! simd_ternop {
3693+
($instruction:ident, $generator_fn_name:ident) => {
3694+
fn $generator_fn_name(
3695+
_: &mut Unstructured,
3696+
_: &Module,
3697+
builder: &mut CodeBuilder,
3698+
) -> Result<Instruction> {
3699+
builder.pop_operands(&[ValType::V128, ValType::V128, ValType::V128]);
3700+
builder.push_operands(&[ValType::V128]);
3701+
Ok(Instruction::$instruction)
3702+
}
3703+
};
3704+
}
3705+
36603706
macro_rules! simd_shift {
36613707
($instruction:ident, $generator_fn_name:ident) => {
36623708
fn $generator_fn_name(
@@ -3868,13 +3914,27 @@ simd_unop!(F64x2ConvertLowI32x4S, f64x2_convert_low_i32x4s);
38683914
simd_unop!(F64x2ConvertLowI32x4U, f64x2_convert_low_i32x4u);
38693915
simd_unop!(F32x4DemoteF64x2Zero, f32x4_demote_f64x2_zero);
38703916
simd_unop!(F64x2PromoteLowF32x4, f64x2_promote_low_f32x4);
3871-
3872-
fn v128_bitselect(
3873-
_: &mut Unstructured,
3874-
_: &Module,
3875-
builder: &mut CodeBuilder,
3876-
) -> Result<Instruction> {
3877-
builder.pop_operands(&[ValType::V128, ValType::V128, ValType::V128]);
3878-
builder.push_operands(&[ValType::V128]);
3879-
Ok(Instruction::V128Bitselect)
3880-
}
3917+
simd_ternop!(V128Bitselect, v128_bitselect);
3918+
simd_binop!(I8x16SwizzleRelaxed, i8x16_swizzle_relaxed);
3919+
simd_unop!(I32x4TruncSatF32x4SRelaxed, i32x4_trunc_sat_f32x4s_relaxed);
3920+
simd_unop!(I32x4TruncSatF32x4URelaxed, i32x4_trunc_sat_f32x4u_relaxed);
3921+
simd_unop!(
3922+
I32x4TruncSatF64x2SZeroRelaxed,
3923+
i32x4_trunc_sat_f64x2s_zero_relaxed
3924+
);
3925+
simd_unop!(
3926+
I32x4TruncSatF64x2UZeroRelaxed,
3927+
i32x4_trunc_sat_f64x2u_zero_relaxed
3928+
);
3929+
simd_binop!(F32x4FmaRelaxed, f32x4_fma_relaxed);
3930+
simd_binop!(F32x4FmsRelaxed, f32x4_fms_relaxed);
3931+
simd_binop!(F64x2FmaRelaxed, f64x2_fma_relaxed);
3932+
simd_binop!(F64x2FmsRelaxed, f64x2_fms_relaxed);
3933+
simd_ternop!(I8x16LaneSelect, i8x16_laneselect);
3934+
simd_ternop!(I16x8LaneSelect, i16x8_laneselect);
3935+
simd_ternop!(I32x4LaneSelect, i32x4_laneselect);
3936+
simd_ternop!(I64x2LaneSelect, i64x2_laneselect);
3937+
simd_binop!(F32x4MinRelaxed, f32x4_min_relaxed);
3938+
simd_binop!(F32x4MaxRelaxed, f32x4_max_relaxed);
3939+
simd_binop!(F64x2MinRelaxed, f64x2_min_relaxed);
3940+
simd_binop!(F64x2MaxRelaxed, f64x2_max_relaxed);

crates/wasm-smith/src/config.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,12 @@ pub trait Config: 'static + std::fmt::Debug {
253253
false
254254
}
255255

256+
/// Determines whether the Relaxed SIMD proposal is enabled for
257+
/// generating insructions. Defaults to `false`.
258+
fn relaxed_simd_enabled(&self) -> bool {
259+
false
260+
}
261+
256262
/// Determines whether the exception-handling proposal is enabled for
257263
/// generating insructions. Defaults to `false`.
258264
fn exceptions_enabled(&self) -> bool {
@@ -376,6 +382,7 @@ pub struct SwarmConfig {
376382
pub memory_offset_choices: (u32, u32, u32),
377383
pub memory_max_size_required: bool,
378384
pub simd_enabled: bool,
385+
pub relaxed_simd_enabled: bool,
379386
pub exceptions_enabled: bool,
380387
pub allow_start_export: bool,
381388
pub max_type_size: u32,
@@ -429,6 +436,7 @@ impl<'a> Arbitrary<'a> for SwarmConfig {
429436
memory_offset_choices: (75, 24, 1),
430437
allow_start_export: true,
431438
simd_enabled: false,
439+
relaxed_simd_enabled: false,
432440
exceptions_enabled: false,
433441
memory64_enabled: false,
434442
max_type_size: 1000,
@@ -567,6 +575,10 @@ impl Config for SwarmConfig {
567575
self.simd_enabled
568576
}
569577

578+
fn relaxed_simd_enabled(&self) -> bool {
579+
self.relaxed_simd_enabled
580+
}
581+
570582
fn exceptions_enabled(&self) -> bool {
571583
self.exceptions_enabled
572584
}

crates/wasm-smith/src/encode.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,5 +903,22 @@ fn translate_instruction(inst: &Instruction) -> wasm_encoder::Instruction {
903903
F64x2ConvertLowI32x4U => wasm_encoder::Instruction::F64x2ConvertLowI32x4U,
904904
F32x4DemoteF64x2Zero => wasm_encoder::Instruction::F32x4DemoteF64x2Zero,
905905
F64x2PromoteLowF32x4 => wasm_encoder::Instruction::F64x2PromoteLowF32x4,
906+
I8x16SwizzleRelaxed => wasm_encoder::Instruction::I8x16SwizzleRelaxed,
907+
I32x4TruncSatF32x4SRelaxed => wasm_encoder::Instruction::I32x4TruncSatF32x4SRelaxed,
908+
I32x4TruncSatF32x4URelaxed => wasm_encoder::Instruction::I32x4TruncSatF32x4URelaxed,
909+
I32x4TruncSatF64x2SZeroRelaxed => wasm_encoder::Instruction::I32x4TruncSatF64x2SZeroRelaxed,
910+
I32x4TruncSatF64x2UZeroRelaxed => wasm_encoder::Instruction::I32x4TruncSatF64x2UZeroRelaxed,
911+
F32x4FmaRelaxed => wasm_encoder::Instruction::F32x4FmaRelaxed,
912+
F32x4FmsRelaxed => wasm_encoder::Instruction::F32x4FmsRelaxed,
913+
F64x2FmaRelaxed => wasm_encoder::Instruction::F64x2FmaRelaxed,
914+
F64x2FmsRelaxed => wasm_encoder::Instruction::F64x2FmsRelaxed,
915+
I8x16LaneSelect => wasm_encoder::Instruction::I8x16LaneSelect,
916+
I16x8LaneSelect => wasm_encoder::Instruction::I16x8LaneSelect,
917+
I32x4LaneSelect => wasm_encoder::Instruction::I32x4LaneSelect,
918+
I64x2LaneSelect => wasm_encoder::Instruction::I64x2LaneSelect,
919+
F32x4MinRelaxed => wasm_encoder::Instruction::F32x4MinRelaxed,
920+
F32x4MaxRelaxed => wasm_encoder::Instruction::F32x4MaxRelaxed,
921+
F64x2MinRelaxed => wasm_encoder::Instruction::F64x2MinRelaxed,
922+
F64x2MaxRelaxed => wasm_encoder::Instruction::F64x2MaxRelaxed,
906923
}
907924
}

crates/wasm-smith/src/lib.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,23 @@ enum Instruction {
965965
F64x2ConvertLowI32x4U,
966966
F32x4DemoteF64x2Zero,
967967
F64x2PromoteLowF32x4,
968+
I8x16SwizzleRelaxed,
969+
I32x4TruncSatF32x4SRelaxed,
970+
I32x4TruncSatF32x4URelaxed,
971+
I32x4TruncSatF64x2SZeroRelaxed,
972+
I32x4TruncSatF64x2UZeroRelaxed,
973+
F32x4FmaRelaxed,
974+
F32x4FmsRelaxed,
975+
F64x2FmaRelaxed,
976+
F64x2FmsRelaxed,
977+
I8x16LaneSelect,
978+
I16x8LaneSelect,
979+
I32x4LaneSelect,
980+
I64x2LaneSelect,
981+
F32x4MinRelaxed,
982+
F32x4MaxRelaxed,
983+
F64x2MinRelaxed,
984+
F64x2MaxRelaxed,
968985
}
969986

970987
#[derive(Debug)]
@@ -988,7 +1005,7 @@ impl Module {
9881005
self.valtypes.push(ValType::I64);
9891006
self.valtypes.push(ValType::F32);
9901007
self.valtypes.push(ValType::F64);
991-
if self.config.simd_enabled() {
1008+
if self.config.simd_enabled() || self.config.relaxed_simd_enabled() {
9921009
self.valtypes.push(ValType::V128);
9931010
}
9941011
if self.config.reference_types_enabled() {

crates/wasm-smith/tests/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ fn wasm_features() -> WasmFeatures {
1010
bulk_memory: true,
1111
reference_types: true,
1212
simd: true,
13+
relaxed_simd: true,
1314
memory64: true,
1415
exceptions: true,
1516
..WasmFeatures::default()

crates/wasmparser/benches/benchmark.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ fn validate_benchmark(c: &mut Criterion) {
210210
reference_types: true,
211211
multi_value: true,
212212
simd: true,
213+
relaxed_simd: true,
213214
exceptions: true,
214215
module_linking: true,
215216
bulk_memory: true,

0 commit comments

Comments
 (0)