diff options
| -rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td | 18 | ||||
| -rw-r--r-- | llvm/test/CodeGen/WebAssembly/simd-arith.ll | 132 |
2 files changed, 150 insertions, 0 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td index a2c5e61685b..07d3dbc8abb 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -110,6 +110,12 @@ multiclass SIMDBinaryFP<SDNode node, string name, bits<32> baseInst> { defm "" : SIMDBinary<v4f32, "f32x4", node, name, baseInst>; defm "" : SIMDBinary<v2f64, "f64x2", node, name, !add(baseInst, 1)>; } +multiclass SIMDBitwise<SDNode node, string name, bits<32> simdop> { + defm "" : SIMDBinary<v16i8, "v128", node, name, simdop>; + defm "" : SIMDBinary<v8i16, "v128", node, name, simdop>; + defm "" : SIMDBinary<v4i32, "v128", node, name, simdop>; + defm "" : SIMDBinary<v2i64, "v128", node, name, simdop>; +} let Defs = [ARGUMENTS] in { defm "" : ConstVec<v16i8, @@ -156,33 +162,45 @@ defm "" : ConstVec<v2f64, (ins f64imm_op:$i0, f64imm_op:$i1), (build_vector (f64 fpimm:$i0), (f64 fpimm:$i1)), "$i0, $i1">; + defm "" : ExtractLaneExtended<"_s", 9>; defm "" : ExtractLaneExtended<"_u", 10>; defm "" : ExtractLane<v4i32, "i32x4", LaneIdx4, I32, 13>; defm "" : ExtractLane<v2i64, "i64x2", LaneIdx2, I64, 14>; defm "" : ExtractLane<v4f32, "f32x4", LaneIdx4, F32, 15>; defm "" : ExtractLane<v2f64, "f64x2", LaneIdx2, F64, 16>; + defm "" : ReplaceLane<v16i8, "i8x16", LaneIdx16, I32, i32, 17>; defm "" : ReplaceLane<v8i16, "i16x8", LaneIdx8, I32, i32, 18>; defm "" : ReplaceLane<v4i32, "i32x4", LaneIdx4, I32, i32, 19>; defm "" : ReplaceLane<v2i64, "i64x2", LaneIdx2, I64, i64, 20>; defm "" : ReplaceLane<v4f32, "f32x4", LaneIdx4, F32, f32, 21>; defm "" : ReplaceLane<v2f64, "f64x2", LaneIdx2, F64, f64, 22>; + 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>; + let isCommutable = 1 in { defm ADD : SIMDBinaryInt<add, "add", 24>; defm ADD : SIMDBinaryFP<fadd, "add", 122>; defm MUL : SIMDBinaryIntNoI64x2<mul, "mul", 32>; defm MUL : SIMDBinaryFP<fmul, "mul", 128>; } // isCommutable = 1 + defm SUB : SIMDBinaryInt<sub, "sub", 28>; defm SUB : SIMDBinaryFP<fsub, "sub", 124>; defm DIV : SIMDBinaryFP<fdiv, "div", 126>; + +let isCommutable = 1 in { +defm AND : SIMDBitwise<and, "and", 59>; +defm OR : SIMDBitwise<or, "or", 60>; +defm XOR : SIMDBitwise<xor, "xor", 61>; +} // isCommutable = 1 + } // Defs = [ARGUMENTS] // follow convention of making implicit expansions unsigned diff --git a/llvm/test/CodeGen/WebAssembly/simd-arith.ll b/llvm/test/CodeGen/WebAssembly/simd-arith.ll index 0039e3d7090..b60fd88d1aa 100644 --- a/llvm/test/CodeGen/WebAssembly/simd-arith.ll +++ b/llvm/test/CodeGen/WebAssembly/simd-arith.ll @@ -46,6 +46,39 @@ define <16 x i8> @mul_v16i8(<16 x i8> %x, <16 x i8> %y) { ret <16 x i8> %a } +; CHECK-LABEL: and_v16i8 +; NO-SIMD128-NOT: i8x16 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.and $push0=, $0, $1 # encoding: [0xfd,0x3b]{{$}} +; SIMD128: return $pop0 # +define <16 x i8> @and_v16i8(<16 x i8> %x, <16 x i8> %y) { + %a = and <16 x i8> %x, %y + ret <16 x i8> %a +} + +; CHECK-LABEL: or_v16i8 +; NO-SIMD128-NOT: i8x16 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.or $push0=, $0, $1 # encoding: [0xfd,0x3c]{{$}} +; SIMD128: return $pop0 # +define <16 x i8> @or_v16i8(<16 x i8> %x, <16 x i8> %y) { + %a = or <16 x i8> %x, %y + ret <16 x i8> %a +} + +; CHECK-LABEL: xor_v16i8 +; NO-SIMD128-NOT: i8x16 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.xor $push0=, $0, $1 # encoding: [0xfd,0x3d]{{$}} +; SIMD128: return $pop0 # +define <16 x i8> @xor_v16i8(<16 x i8> %x, <16 x i8> %y) { + %a = xor <16 x i8> %x, %y + ret <16 x i8> %a +} + ; ============================================================================== ; 8 x i16 ; ============================================================================== @@ -82,6 +115,39 @@ define <8 x i16> @mul_v8i16(<8 x i16> %x, <8 x i16> %y) { ret <8 x i16> %a } +; CHECK-LABEL: and_v8i16 +; NO-SIMD128-NOT: i16x8 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.and $push0=, $0, $1 # encoding: [0xfd,0x3b]{{$}} +; SIMD128: return $pop0 # +define <8 x i16> @and_v8i16(<8 x i16> %x, <8 x i16> %y) { + %a = and <8 x i16> %x, %y + ret <8 x i16> %a +} + +; CHECK-LABEL: or_v8i16 +; NO-SIMD128-NOT: i16x8 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.or $push0=, $0, $1 # encoding: [0xfd,0x3c]{{$}} +; SIMD128: return $pop0 # +define <8 x i16> @or_v8i16(<8 x i16> %x, <8 x i16> %y) { + %a = or <8 x i16> %x, %y + ret <8 x i16> %a +} + +; CHECK-LABEL: xor_v8i16 +; NO-SIMD128-NOT: i16x8 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.xor $push0=, $0, $1 # encoding: [0xfd,0x3d]{{$}} +; SIMD128: return $pop0 # +define <8 x i16> @xor_v8i16(<8 x i16> %x, <8 x i16> %y) { + %a = xor <8 x i16> %x, %y + ret <8 x i16> %a +} + ; ============================================================================== ; 4 x i32 ; ============================================================================== @@ -118,6 +184,39 @@ define <4 x i32> @mul_v4i32(<4 x i32> %x, <4 x i32> %y) { ret <4 x i32> %a } +; CHECK-LABEL: and_v4i32 +; NO-SIMD128-NOT: i32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.and $push0=, $0, $1 # encoding: [0xfd,0x3b]{{$}} +; SIMD128: return $pop0 # +define <4 x i32> @and_v4i32(<4 x i32> %x, <4 x i32> %y) { + %a = and <4 x i32> %x, %y + ret <4 x i32> %a +} + +; CHECK-LABEL: or_v4i32 +; NO-SIMD128-NOT: i32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.or $push0=, $0, $1 # encoding: [0xfd,0x3c]{{$}} +; SIMD128: return $pop0 # +define <4 x i32> @or_v4i32(<4 x i32> %x, <4 x i32> %y) { + %a = or <4 x i32> %x, %y + ret <4 x i32> %a +} + +; CHECK-LABEL: xor_v4i32 +; NO-SIMD128-NOT: i32x4 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.xor $push0=, $0, $1 # encoding: [0xfd,0x3d]{{$}} +; SIMD128: return $pop0 # +define <4 x i32> @xor_v4i32(<4 x i32> %x, <4 x i32> %y) { + %a = xor <4 x i32> %x, %y + ret <4 x i32> %a +} + ; ============================================================================== ; 2 x i64 ; ============================================================================== @@ -157,6 +256,39 @@ define <2 x i64> @mul_v2i64(<2 x i64> %x, <2 x i64> %y) { ret <2 x i64> %a } +; CHECK-LABEL: and_v2i64 +; NO-SIMD128-NOT: i64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.and $push0=, $0, $1 # encoding: [0xfd,0x3b]{{$}} +; SIMD128: return $pop0 # +define <2 x i64> @and_v2i64(<2 x i64> %x, <2 x i64> %y) { + %a = and <2 x i64> %x, %y + ret <2 x i64> %a +} + +; CHECK-LABEL: or_v2i64 +; NO-SIMD128-NOT: i64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.or $push0=, $0, $1 # encoding: [0xfd,0x3c]{{$}} +; SIMD128: return $pop0 # +define <2 x i64> @or_v2i64(<2 x i64> %x, <2 x i64> %y) { + %a = or <2 x i64> %x, %y + ret <2 x i64> %a +} + +; CHECK-LABEL: xor_v2i64 +; NO-SIMD128-NOT: i64x2 +; SIMD128: .param v128, v128{{$}} +; SIMD128: .result v128{{$}} +; SIMD128: v128.xor $push0=, $0, $1 # encoding: [0xfd,0x3d]{{$}} +; SIMD128: return $pop0 # +define <2 x i64> @xor_v2i64(<2 x i64> %x, <2 x i64> %y) { + %a = xor <2 x i64> %x, %y + ret <2 x i64> %a +} + ; ============================================================================== ; 4 x float ; ============================================================================== |

