Dan Gohman | 10e730a | 2015-06-29 23:51:55 +0000 | [diff] [blame] | 1 | // WebAssemblyInstrSIMD.td - WebAssembly SIMD codegen support -*- tablegen -*-// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
JF Bastien | 5ca0bac | 2015-07-10 18:23:10 +0000 | [diff] [blame] | 9 | /// |
| 10 | /// \file |
Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 11 | /// WebAssembly SIMD operand code-gen constructs. |
JF Bastien | 5ca0bac | 2015-07-10 18:23:10 +0000 | [diff] [blame] | 12 | /// |
Dan Gohman | 10e730a | 2015-06-29 23:51:55 +0000 | [diff] [blame] | 13 | //===----------------------------------------------------------------------===// |
| 14 | |
Heejin Ahn | a0fd9c3 | 2018-08-14 18:53:27 +0000 | [diff] [blame^] | 15 | // Immediate argument types |
| 16 | def ImmByte : ImmLeaf<i32, [{ return 0 <= Imm && Imm < 256; }]>; |
| 17 | foreach SIZE = [2, 4, 8, 16, 32] in |
| 18 | def LaneIdx#SIZE : ImmLeaf<i32, "return 0 <= Imm && Imm < "#SIZE#";">; |
Derek Schuff | 51ed131 | 2018-08-07 21:24:01 +0000 | [diff] [blame] | 19 | |
Heejin Ahn | a0fd9c3 | 2018-08-14 18:53:27 +0000 | [diff] [blame^] | 20 | // lane extraction |
| 21 | multiclass ExtractLane<ValueType vec_t, ImmLeaf imm_t, |
| 22 | WebAssemblyRegClass reg_t, string name, bits<32> simdop, |
| 23 | SDNode extract = vector_extract> { |
| 24 | defm "" : SIMD_I<(outs reg_t:$dst), (ins V128:$vec, I32:$idx), |
| 25 | (outs), (ins I32:$idx), |
| 26 | [(set reg_t:$dst, |
| 27 | (extract (vec_t V128:$vec), (i32 imm_t:$idx)))], |
| 28 | name#"\t$dst, $vec, $idx", name#"\t$idx", simdop>; |
| 29 | } |
| 30 | multiclass ExtractPat<ValueType lane_t, int mask> { |
| 31 | def _s : PatFrag<(ops node:$vec, node:$idx), |
| 32 | (i32 (sext_inreg |
| 33 | (i32 (vector_extract |
| 34 | node:$vec, |
| 35 | node:$idx |
| 36 | )), |
| 37 | lane_t |
| 38 | ))>; |
| 39 | def _u : PatFrag<(ops node:$vec, node:$idx), |
| 40 | (i32 (and |
| 41 | (i32 (vector_extract |
| 42 | node:$vec, |
| 43 | node:$idx |
| 44 | )), |
| 45 | (i32 mask) |
| 46 | ))>; |
| 47 | } |
| 48 | defm extract_i8x16 : ExtractPat<i8, 0xff>; |
| 49 | defm extract_i16x8 : ExtractPat<i16, 0xffff>; |
| 50 | multiclass ExtractLaneExtended<string sign, bits<32> baseInst> { |
| 51 | defm _I8x16 : ExtractLane<v16i8, LaneIdx16, I32, "i8x16.extract_lane"#sign, |
| 52 | baseInst, !cast<PatFrag>("extract_i8x16"#sign)>; |
| 53 | defm _I16x8 : ExtractLane<v8i16, LaneIdx8, I32, "i16x8.extract_lane"#sign, |
| 54 | !add(baseInst, 2), |
| 55 | !cast<PatFrag>("extract_i16x8"#sign)>; |
| 56 | } |
| 57 | |
| 58 | let Defs = [ARGUMENTS] in { |
| 59 | defm EXTRACT_LANE_S : ExtractLaneExtended<"_s", 9>; |
| 60 | defm EXTRACT_LANE_U : ExtractLaneExtended<"_u", 10>; |
| 61 | defm EXTRACT_LANE_I32x4 : |
| 62 | ExtractLane<v4i32, LaneIdx4, I32, "i32x4.extract_lane", 13>; |
| 63 | defm EXTRACT_LANE_I64x2 : |
| 64 | ExtractLane<v2i64, LaneIdx2, I64, "i64x2.extract_lane", 14>; |
| 65 | defm EXTRACT_LANE_F32x4 : |
| 66 | ExtractLane<v4f32, LaneIdx4, F32, "f32x4.extract_lane", 15>; |
| 67 | defm EXTRACT_LANE_F64x2 : |
| 68 | ExtractLane<v2f64, LaneIdx2, F64, "f64x2.extract_lane", 16>; |
| 69 | } // Defs = [ARGUMENTS] |
| 70 | |
| 71 | // follow convention of making implicit expansions unsigned |
| 72 | def : Pat<(i32 (vector_extract (v16i8 V128:$vec), (i32 LaneIdx16:$idx))), |
| 73 | (EXTRACT_LANE_U_I8x16 V128:$vec, (i32 LaneIdx16:$idx))>; |
| 74 | def : Pat<(i32 (vector_extract (v8i16 V128:$vec), (i32 LaneIdx8:$idx))), |
| 75 | (EXTRACT_LANE_U_I16x8 V128:$vec, (i32 LaneIdx8:$idx))>; |
| 76 | |
| 77 | // arithmetic |
| 78 | let Defs = [ARGUMENTS] in { |
Derek Schuff | 51ed131 | 2018-08-07 21:24:01 +0000 | [diff] [blame] | 79 | let isCommutable = 1 in |
| 80 | defm ADD : SIMDBinaryInt<add, "add ", 24>; |
| 81 | defm SUB : SIMDBinaryInt<sub, "sub ", 28>; |
| 82 | let isCommutable = 1 in |
| 83 | defm MUL : SIMDBinaryInt<mul, "mul ", 32>; |
Derek Schuff | 51ed131 | 2018-08-07 21:24:01 +0000 | [diff] [blame] | 84 | let isCommutable = 1 in |
| 85 | defm ADD : SIMDBinaryFP<fadd, "add ", 122>; |
| 86 | defm SUB : SIMDBinaryFP<fsub, "sub ", 124>; |
| 87 | defm DIV : SIMDBinaryFP<fdiv, "div ", 126>; |
| 88 | let isCommutable = 1 in |
| 89 | defm MUL : SIMDBinaryFP<fmul, "mul ", 128>; |
Derek Schuff | 51ed131 | 2018-08-07 21:24:01 +0000 | [diff] [blame] | 90 | } // Defs = [ARGUMENTS] |