def : Pat<(i32 (vector_extract (v8i16 V128:$vec), (i32 LaneIdx8:$idx))),
(EXTRACT_LANE_U_I16x8 V128:$vec, (i32 LaneIdx8:$idx))>;
+
+// splats
+def splat2 : PatFrag<(ops node:$x), (build_vector node:$x, node:$x)>;
+def splat4 : PatFrag<(ops node:$x), (build_vector
+ node:$x, node:$x, node:$x, node:$x)>;
+def splat8 : PatFrag<(ops node:$x), (build_vector
+ node:$x, node:$x, node:$x, node:$x,
+ node:$x, node:$x, node:$x, node:$x)>;
+def splat16 : PatFrag<(ops node:$x), (build_vector
+ node:$x, node:$x, node:$x, node:$x,
+ node:$x, node:$x, node:$x, node:$x,
+ node:$x, node:$x, node:$x, node:$x,
+ node:$x, node:$x, node:$x, node:$x)>;
+multiclass Splat<ValueType vec_t, string name, WebAssemblyRegClass reg_t,
+ PatFrag splat_pat, bits<32> simdop> {
+ defm SPLAT_#vec_t : SIMD_I<(outs V128:$dst), (ins reg_t:$x), (outs), (ins),
+ [(set (vec_t V128:$dst), (splat_pat reg_t:$x))],
+ name#".splat\t$dst, $x", name#".splat", simdop>;
+}
+let Defs = [ARGUMENTS] in {
+defm "" : Splat<v16i8, "i8x16", I32, splat16, 3>;
+defm "" : Splat<v8i16, "i16x8", I32, splat8, 4>;
+defm "" : Splat<v4i32, "i32x4", I32, splat4, 5>;
+defm "" : Splat<v2i64, "i64x2", I64, splat2, 6>;
+defm "" : Splat<v4f32, "f32x4", F32, splat4, 7>;
+defm "" : Splat<v2f64, "f64x2", F64, splat2, 8>;
+}
+
// arithmetic
let Defs = [ARGUMENTS] in {
let isCommutable = 1 in
; ==============================================================================
; 16 x i8
; ==============================================================================
+; CHECK-LABEL: splat_v16i8:
+; NO-SIMD128-NOT: i8x16
+; SIMD128: .param i32{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: i8x16.splat $push0=, $0 # encoding: [0xfd,0x03]{{$}}
+; SIMD128: return $pop0 # encoding: [0x0f]{{$}}
+define <16 x i8> @splat_v16i8(i8 %x) {
+ %v = insertelement <16 x i8> undef, i8 %x, i32 0
+ %res = shufflevector <16 x i8> %v, <16 x i8> undef,
+ <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0,
+ i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
+ ret <16 x i8> %res
+}
+
; CHECK-LABEL: extract_v16i8_s:
; NO-SIMD128-NOT: i8x16
; SIMD128: .param v128{{$}}
; ==============================================================================
; 8 x i16
; ==============================================================================
+; CHECK-LABEL: splat_v8i16:
+; NO-SIMD128-NOT: i16x8
+; SIMD128: .param i32{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: i16x8.splat $push0=, $0 # encoding: [0xfd,0x04]{{$}}
+; SIMD128: return $pop0 # encoding: [0x0f]{{$}}
+define <8 x i16> @splat_v8i16(i16 %x) {
+ %v = insertelement <8 x i16> undef, i16 %x, i32 0
+ %res = shufflevector <8 x i16> %v, <8 x i16> undef,
+ <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0>
+ ret <8 x i16> %res
+}
+
; CHECK-LABEL: extract_v8i16_s:
; NO-SIMD128-NOT: i16x8
; SIMD128: .param v128{{$}}
; ==============================================================================
; 4 x i32
; ==============================================================================
+; CHECK-LABEL: splat_v4i32:
+; NO-SIMD128-NOT: i32x4
+; SIMD128: .param i32{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: i32x4.splat $push0=, $0 # encoding: [0xfd,0x05]{{$}}
+; SIMD128: return $pop0 # encoding: [0x0f]{{$}}
+define <4 x i32> @splat_v4i32(i32 %x) {
+ %v = insertelement <4 x i32> undef, i32 %x, i32 0
+ %res = shufflevector <4 x i32> %v, <4 x i32> undef,
+ <4 x i32> <i32 0, i32 0, i32 0, i32 0>
+ ret <4 x i32> %res
+}
+
; CHECK-LABEL: extract_v4i32:
; NO-SIMD128-NOT: i32x4
; SIMD128: .param v128{{$}}
; ==============================================================================
; 2 x i64
; ==============================================================================
+; CHECK-LABEL: splat_v2i64:
+; NO-SIMD128-NOT: i64x2
+; SIMD128-VM-NOT: i64x2
+; SIMD128: .param i64{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: i64x2.splat $push0=, $0 # encoding: [0xfd,0x06]{{$}}
+; SIMD128: return $pop0 # encoding: [0x0f]{{$}}
+define <2 x i64> @splat_v2i64(i64 %x) {
+ %t1 = insertelement <2 x i64> zeroinitializer, i64 %x, i32 0
+ %res = insertelement <2 x i64> %t1, i64 %x, i32 1
+ ret <2 x i64> %res
+}
+
; CHECK-LABEL: extract_v2i64:
; NO-SIMD128-NOT: i64x2
; SIMD128-VM-NOT: i64x2
; ==============================================================================
; 4 x f32
; ==============================================================================
+; CHECK-LABEL: splat_v4f32:
+; NO-SIMD128-NOT: f32x4
+; SIMD128: .param f32{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: f32x4.splat $push0=, $0 # encoding: [0xfd,0x07]{{$}}
+; SIMD128: return $pop0 # encoding: [0x0f]{{$}}
+define <4 x float> @splat_v4f32(float %x) {
+ %v = insertelement <4 x float> undef, float %x, i32 0
+ %res = shufflevector <4 x float> %v, <4 x float> undef,
+ <4 x i32> <i32 0, i32 0, i32 0, i32 0>
+ ret <4 x float> %res
+}
+
; CHECK-LABEL: extract_v4f32:
; NO-SIMD128-NOT: f32x4
; SIMD128: .param v128{{$}}
; ==============================================================================
; 2 x f64
; ==============================================================================
+; CHECK-LABEL: splat_v2f64:
+; NO-SIMD128-NOT: f64x2
+; SIMD128-VM-NOT: f64x2
+; SIMD128: .param f64{{$}}
+; SIMD128: .result v128{{$}}
+; SIMD128: f64x2.splat $push0=, $0 # encoding: [0xfd,0x08]{{$}}
+; SIMD128: return $pop0 # encoding: [0x0f]{{$}}
+define <2 x double> @splat_v2f64(double %x) {
+ %t1 = insertelement <2 x double> zeroinitializer, double %x, i3 0
+ %res = insertelement <2 x double> %t1, double %x, i32 1
+ ret <2 x double> %res
+}
+
; CHECK-LABEL: extract_v2f64:
; NO-SIMD128-NOT: f64x2
; SIMD128-VM-NOT: f64x2