diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyISD.def | 4 | ||||
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp | 26 | ||||
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td | 15 |
3 files changed, 45 insertions, 0 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISD.def b/llvm/lib/Target/WebAssembly/WebAssemblyISD.def index 9e1d198b079..f326d37944f 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISD.def +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISD.def @@ -25,5 +25,9 @@ HANDLE_NODETYPE(SHUFFLE) HANDLE_NODETYPE(ANYTRUE) HANDLE_NODETYPE(ALLTRUE) HANDLE_NODETYPE(BITSELECT) +HANDLE_NODETYPE(ADD_SAT_S) +HANDLE_NODETYPE(ADD_SAT_U) +HANDLE_NODETYPE(SUB_SAT_S) +HANDLE_NODETYPE(SUB_SAT_U) // add memory opcodes starting at ISD::FIRST_TARGET_MEMORY_OPCODE here... diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index d5dcbf1d699..4ecbf6d7487 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -966,6 +966,32 @@ WebAssemblyTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, default: return {}; // Don't custom lower most intrinsics. + case Intrinsic::wasm_add_saturate_signed: + case Intrinsic::wasm_add_saturate_unsigned: + case Intrinsic::wasm_sub_saturate_signed: + case Intrinsic::wasm_sub_saturate_unsigned: { + unsigned OpCode; + switch (IntNo) { + case Intrinsic::wasm_add_saturate_signed: + OpCode = WebAssemblyISD::ADD_SAT_S; + break; + case Intrinsic::wasm_add_saturate_unsigned: + OpCode = WebAssemblyISD::ADD_SAT_U; + break; + case Intrinsic::wasm_sub_saturate_signed: + OpCode = WebAssemblyISD::SUB_SAT_S; + break; + case Intrinsic::wasm_sub_saturate_unsigned: + OpCode = WebAssemblyISD::SUB_SAT_U; + break; + default: + llvm_unreachable("unexpected intrinsic id"); + break; + } + return DAG.getNode(OpCode, DL, Op.getValueType(), Op.getOperand(1), + Op.getOperand(2)); + } + case Intrinsic::wasm_bitselect: return DAG.getNode(WebAssemblyISD::BITSELECT, DL, Op.getValueType(), Op.getOperand(1), Op.getOperand(2), Op.getOperand(3)); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td index bf5582a11f0..55bac7971d7 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -20,11 +20,18 @@ def LaneIdx#SIZE : ImmLeaf<i32, "return 0 <= Imm && Imm < "#SIZE#";">; // Custom nodes for custom operations def wasm_shuffle_t : SDTypeProfile<1, 18, []>; +def wasm_saturate_t : SDTypeProfile<1, 2, + [SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>] +>; def wasm_bitselect_t : SDTypeProfile<1, 3, [SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>] >; def wasm_reduce_t : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVec<1>]>; def wasm_shuffle : SDNode<"WebAssemblyISD::SHUFFLE", wasm_shuffle_t>; +def wasm_add_sat_s : SDNode<"WebAssemblyISD::ADD_SAT_S", wasm_saturate_t>; +def wasm_add_sat_u : SDNode<"WebAssemblyISD::ADD_SAT_U", wasm_saturate_t>; +def wasm_sub_sat_s : SDNode<"WebAssemblyISD::SUB_SAT_S", wasm_saturate_t>; +def wasm_sub_sat_u : SDNode<"WebAssemblyISD::SUB_SAT_U", wasm_saturate_t>; def wasm_bitselect : SDNode<"WebAssemblyISD::BITSELECT", wasm_bitselect_t>; def wasm_anytrue : SDNode<"WebAssemblyISD::ANYTRUE", wasm_reduce_t>; def wasm_alltrue : SDNode<"WebAssemblyISD::ALLTRUE", wasm_reduce_t>; @@ -139,6 +146,10 @@ 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 SIMDBinarySat<SDNode node, string name, bits<32> baseInst> { + defm "" : SIMDBinary<v16i8, "i8x16", node, name, baseInst>; + defm "" : SIMDBinary<v8i16, "i16x8", node, name, !add(baseInst, 2)>; +} multiclass SIMDShift<ValueType vec_t, string vec, SDNode node, dag shift_vec, string name, bits<32> simdop> { defm _#vec_t : SIMD_I<(outs V128:$dst), (ins V128:$vec, I32:$x), @@ -366,10 +377,14 @@ defm ADD : SIMDBinaryInt<add, "add", 24>; defm ADD : SIMDBinaryFP<fadd, "add", 133>; defm MUL : SIMDBinaryIntNoI64x2<mul, "mul", 32>; defm MUL : SIMDBinaryFP<fmul, "mul", 139>; +defm ADD_SAT_S : SIMDBinarySat<wasm_add_sat_s, "add_saturate_s", 40>; +defm ADD_SAT_U : SIMDBinarySat<wasm_add_sat_u, "add_saturate_u", 41>; } // isCommutable = 1 defm SUB : SIMDBinaryInt<sub, "sub", 28>; defm SUB : SIMDBinaryFP<fsub, "sub", 135>; +defm SUB_SAT_S : SIMDBinarySat<wasm_sub_sat_s, "sub_saturate_s", 44>; +defm SUB_SAT_U : SIMDBinarySat<wasm_sub_sat_u, "sub_saturate_u", 45>; defm DIV : SIMDBinaryFP<fdiv, "div", 137>; defm "" : SIMDNegInt<v16i8, "i8x16", splat16, i32, 36>; |