diff options
Diffstat (limited to 'llvm/lib/Target/WebAssembly')
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td | 5 | ||||
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td | 115 |
3 files changed, 121 insertions, 2 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp index c783d4bac84..b3cd27b1b8f 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp @@ -124,6 +124,9 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering( } } + // There is no i64x2.mul instruction + setOperationAction(ISD::MUL, MVT::v2i64, Expand); + // As a special case, these operators use the type to mean the type to // sign-extend from. setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td index c99b20b60bc..08cb184cca3 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrFormats.td @@ -119,7 +119,7 @@ multiclass BinaryFP<SDNode node, string name, bits<32> f32Inst, !strconcat("f64.", !strconcat(name, "\t$dst, $lhs, $rhs")), !strconcat("f64.", name), f64Inst>; } -multiclass SIMDBinaryInt<SDNode node, string name, bits<32> baseInst> { +multiclass SIMDBinaryIntNoI64x2<SDNode node, string name, bits<32> baseInst> { defm _I8x16 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs), (outs), (ins), [(set (v16i8 V128:$dst), (node V128:$lhs, V128:$rhs))], @@ -138,6 +138,9 @@ multiclass SIMDBinaryInt<SDNode node, string name, bits<32> baseInst> { !strconcat("i32x4.", !strconcat(name, "\t$dst, $lhs, $rhs")), !strconcat("i32x4.", name), !add(baseInst, 2)>; +} +multiclass SIMDBinaryInt<SDNode node, string name, bits<32> baseInst> { + defm "" : SIMDBinaryIntNoI64x2<node, name, baseInst>; defm _I64x2 : SIMD_I<(outs V128:$dst), (ins V128:$lhs, V128:$rhs), (outs), (ins), [(set (v2i64 V128:$dst), (node V128:$lhs, V128:$rhs))], diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td index 08b925aeee9..fc8944ee898 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td +++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td @@ -169,13 +169,126 @@ defm "" : Splat<v4f32, "f32x4", F32, splat4, 7>; defm "" : Splat<v2f64, "f64x2", F64, splat2, 8>; } // Defs = [ARGUMENTS] +// arbitrary other BUILD_VECTOR patterns +def : Pat<(v16i8 (build_vector + (i32 I32:$x0), (i32 I32:$x1), (i32 I32:$x2), (i32 I32:$x3), + (i32 I32:$x4), (i32 I32:$x5), (i32 I32:$x6), (i32 I32:$x7), + (i32 I32:$x8), (i32 I32:$x9), (i32 I32:$x10), (i32 I32:$x11), + (i32 I32:$x12), (i32 I32:$x13), (i32 I32:$x14), (i32 I32:$x15) + )), + (v16i8 (REPLACE_LANE_v16i8 + (v16i8 (REPLACE_LANE_v16i8 + (v16i8 (REPLACE_LANE_v16i8 + (v16i8 (REPLACE_LANE_v16i8 + (v16i8 (REPLACE_LANE_v16i8 + (v16i8 (REPLACE_LANE_v16i8 + (v16i8 (REPLACE_LANE_v16i8 + (v16i8 (REPLACE_LANE_v16i8 + (v16i8 (REPLACE_LANE_v16i8 + (v16i8 (REPLACE_LANE_v16i8 + (v16i8 (REPLACE_LANE_v16i8 + (v16i8 (REPLACE_LANE_v16i8 + (v16i8 (REPLACE_LANE_v16i8 + (v16i8 (REPLACE_LANE_v16i8 + (v16i8 (REPLACE_LANE_v16i8 + (v16i8 (SPLAT_v16i8 (i32 I32:$x0))), + 1, I32:$x1 + )), + 2, I32:$x2 + )), + 3, I32:$x3 + )), + 4, I32:$x4 + )), + 5, I32:$x5 + )), + 6, I32:$x6 + )), + 7, I32:$x7 + )), + 8, I32:$x8 + )), + 9, I32:$x9 + )), + 10, I32:$x10 + )), + 11, I32:$x11 + )), + 12, I32:$x12 + )), + 13, I32:$x13 + )), + 14, I32:$x14 + )), + 15, I32:$x15 + ))>; +def : Pat<(v8i16 (build_vector + (i32 I32:$x0), (i32 I32:$x1), (i32 I32:$x2), (i32 I32:$x3), + (i32 I32:$x4), (i32 I32:$x5), (i32 I32:$x6), (i32 I32:$x7) + )), + (v8i16 (REPLACE_LANE_v8i16 + (v8i16 (REPLACE_LANE_v8i16 + (v8i16 (REPLACE_LANE_v8i16 + (v8i16 (REPLACE_LANE_v8i16 + (v8i16 (REPLACE_LANE_v8i16 + (v8i16 (REPLACE_LANE_v8i16 + (v8i16 (REPLACE_LANE_v8i16 + (v8i16 (SPLAT_v8i16 (i32 I32:$x0))), + 1, I32:$x1 + )), + 2, I32:$x2 + )), + 3, I32:$x3 + )), + 4, I32:$x4 + )), + 5, I32:$x5 + )), + 6, I32:$x6 + )), + 7, I32:$x7 + ))>; +def : Pat<(v4i32 (build_vector + (i32 I32:$x0), (i32 I32:$x1), (i32 I32:$x2), (i32 I32:$x3) + )), + (v4i32 (REPLACE_LANE_v4i32 + (v4i32 (REPLACE_LANE_v4i32 + (v4i32 (REPLACE_LANE_v4i32 + (v4i32 (SPLAT_v4i32 (i32 I32:$x0))), + 1, I32:$x1 + )), + 2, I32:$x2 + )), + 3, I32:$x3 + ))>; +def : Pat<(v2i64 (build_vector (i64 I64:$x0), (i64 I64:$x1))), + (v2i64 (REPLACE_LANE_v2i64 + (v2i64 (SPLAT_v2i64 (i64 I64:$x0))), 1, I64:$x1))>; +def : Pat<(v4f32 (build_vector + (f32 F32:$x0), (f32 F32:$x1), (f32 F32:$x2), (f32 F32:$x3) + )), + (v4f32 (REPLACE_LANE_v4f32 + (v4f32 (REPLACE_LANE_v4f32 + (v4f32 (REPLACE_LANE_v4f32 + (v4f32 (SPLAT_v4f32 (f32 F32:$x0))), + 1, F32:$x1 + )), + 2, F32:$x2 + )), + 3, F32:$x3 + ))>; +def : Pat<(v2f64 (build_vector (f64 F64:$x0), (f64 F64:$x1))), + (v2f64 (REPLACE_LANE_v2f64 + (v2f64 (SPLAT_v2f64 (f64 F64:$x0))), 1, F64:$x1))>; + // arithmetic let Defs = [ARGUMENTS] in { let isCommutable = 1 in defm ADD : SIMDBinaryInt<add, "add ", 24>; defm SUB : SIMDBinaryInt<sub, "sub ", 28>; let isCommutable = 1 in -defm MUL : SIMDBinaryInt<mul, "mul ", 32>; +defm MUL : SIMDBinaryIntNoI64x2<mul, "mul ", 32>; + let isCommutable = 1 in defm ADD : SIMDBinaryFP<fadd, "add ", 122>; defm SUB : SIMDBinaryFP<fsub, "sub ", 124>; |