diff --git a/cranelift/codegen/src/isa/pulley_shared/lower.isle b/cranelift/codegen/src/isa/pulley_shared/lower.isle index 03bacddc78ed..15133e563edc 100644 --- a/cranelift/codegen/src/isa/pulley_shared/lower.isle +++ b/cranelift/codegen/src/isa/pulley_shared/lower.isle @@ -1162,6 +1162,13 @@ (rule 0 (lower (has_type (fits_in_32 _) (ineg a))) (pulley_xneg32 (sext32 a))) (rule 1 (lower (has_type $I64 (ineg a))) (pulley_xneg64 a)) +;; vector negation + +(rule 1 (lower (has_type $I8X16 (ineg a))) (pulley_vneg8x16 a)) +(rule 1 (lower (has_type $I16X8 (ineg a))) (pulley_vneg16x8 a)) +(rule 1 (lower (has_type $I32X4 (ineg a))) (pulley_vneg32x4 a)) +(rule 1 (lower (has_type $I64X2 (ineg a))) (pulley_vneg64x2 a)) + ;;;; Rules for `fabs` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (rule (lower (has_type $F32 (fabs a))) (pulley_fabs32 a)) diff --git a/cranelift/filetests/filetests/runtests/simd-ineg.clif b/cranelift/filetests/filetests/runtests/simd-ineg.clif index 8c23c7e09f1e..8246bd77f122 100644 --- a/cranelift/filetests/filetests/runtests/simd-ineg.clif +++ b/cranelift/filetests/filetests/runtests/simd-ineg.clif @@ -7,6 +7,10 @@ target x86_64 skylake set enable_multi_ret_implicit_sret target riscv64 has_v target riscv64 has_v has_c has_zcb +target pulley32 +target pulley32be +target pulley64 +target pulley64be function %ineg_i8x16(i8x16) -> i8x16 { block0(v0: i8x16): diff --git a/crates/wast-util/src/lib.rs b/crates/wast-util/src/lib.rs index e57484dc8181..5ab270879069 100644 --- a/crates/wast-util/src/lib.rs +++ b/crates/wast-util/src/lib.rs @@ -428,20 +428,16 @@ impl WastTest { "spec_testsuite/simd_f64x2_cmp.wast", "spec_testsuite/simd_f64x2_pmin_pmax.wast", "spec_testsuite/simd_f64x2_rounding.wast", - "spec_testsuite/simd_i16x8_arith.wast", "spec_testsuite/simd_i16x8_arith2.wast", "spec_testsuite/simd_i16x8_extadd_pairwise_i8x16.wast", "spec_testsuite/simd_i16x8_q15mulr_sat_s.wast", "spec_testsuite/simd_i16x8_sat_arith.wast", - "spec_testsuite/simd_i32x4_arith.wast", "spec_testsuite/simd_i32x4_arith2.wast", "spec_testsuite/simd_i32x4_dot_i16x8.wast", "spec_testsuite/simd_i32x4_extadd_pairwise_i16x8.wast", "spec_testsuite/simd_i32x4_trunc_sat_f32x4.wast", "spec_testsuite/simd_i32x4_trunc_sat_f64x2.wast", - "spec_testsuite/simd_i64x2_arith.wast", "spec_testsuite/simd_i64x2_arith2.wast", - "spec_testsuite/simd_i8x16_arith.wast", "spec_testsuite/simd_i8x16_arith2.wast", "spec_testsuite/simd_i8x16_sat_arith.wast", "spec_testsuite/simd_lane.wast", diff --git a/pulley/src/interp.rs b/pulley/src/interp.rs index fe32ea75d6ac..e9e902f1f151 100644 --- a/pulley/src/interp.rs +++ b/pulley/src/interp.rs @@ -4011,4 +4011,28 @@ impl ExtendedOpVisitor for Interpreter<'_> { self.state[operands.dst].set_u64x2(c); ControlFlow::Continue(()) } + + fn vneg8x16(&mut self, dst: VReg, src: VReg) -> ControlFlow { + let a = self.state[src].get_i8x16(); + self.state[dst].set_i8x16(a.map(|i| i.wrapping_neg())); + ControlFlow::Continue(()) + } + + fn vneg16x8(&mut self, dst: VReg, src: VReg) -> ControlFlow { + let a = self.state[src].get_i16x8(); + self.state[dst].set_i16x8(a.map(|i| i.wrapping_neg())); + ControlFlow::Continue(()) + } + + fn vneg32x4(&mut self, dst: VReg, src: VReg) -> ControlFlow { + let a = self.state[src].get_i32x4(); + self.state[dst].set_i32x4(a.map(|i| i.wrapping_neg())); + ControlFlow::Continue(()) + } + + fn vneg64x2(&mut self, dst: VReg, src: VReg) -> ControlFlow { + let a = self.state[src].get_i64x2(); + self.state[dst].set_i64x2(a.map(|i| i.wrapping_neg())); + ControlFlow::Continue(()) + } } diff --git a/pulley/src/lib.rs b/pulley/src/lib.rs index f87388f2f59c..f8225e3174b4 100644 --- a/pulley/src/lib.rs +++ b/pulley/src/lib.rs @@ -1097,6 +1097,15 @@ macro_rules! for_each_extended_op { vult64x2 = Vult64x2 { operands: BinaryOperands }; /// `dst = src <= dst` (unsigned) vulteq64x2 = Vulteq64x2 { operands: BinaryOperands }; + + /// `dst = -src` + vneg8x16 = Vneg8x16 { dst: VReg, src: VReg }; + /// `dst = -src` + vneg16x8 = Vneg16x8 { dst: VReg, src: VReg }; + /// `dst = -src` + vneg32x4 = Vneg32x4 { dst: VReg, src: VReg }; + /// `dst = -src` + vneg64x2 = Vneg64x2 { dst: VReg, src: VReg }; } }; }