summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyISD.def4
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp26
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td15
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>;
OpenPOWER on IntegriCloud