Home | History | Annotate | Download | only in AArch64
      1 //===-- AArch64InstrNEON.td - NEON support for AArch64 -----*- 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 //===----------------------------------------------------------------------===//
      9 //
     10 // This file describes the AArch64 NEON instruction set.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 //===----------------------------------------------------------------------===//
     15 // NEON-specific DAG Nodes.
     16 //===----------------------------------------------------------------------===//
     17 def Neon_bsl       : SDNode<"AArch64ISD::NEON_BSL", SDTypeProfile<1, 3,
     18                       [SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
     19                       SDTCisSameAs<0, 3>]>>;
     20 
     21 // (outs Result), (ins Imm, OpCmode)
     22 def SDT_Neon_movi : SDTypeProfile<1, 2, [SDTCisVec<0>, SDTCisVT<1, i32>]>;
     23 
     24 def Neon_movi     : SDNode<"AArch64ISD::NEON_MOVIMM", SDT_Neon_movi>;
     25 
     26 def Neon_mvni     : SDNode<"AArch64ISD::NEON_MVNIMM", SDT_Neon_movi>;
     27 
     28 // (outs Result), (ins Imm)
     29 def Neon_fmovi : SDNode<"AArch64ISD::NEON_FMOVIMM", SDTypeProfile<1, 1,
     30                         [SDTCisVec<0>, SDTCisVT<1, i32>]>>;
     31 
     32 // (outs Result), (ins LHS, RHS, CondCode)
     33 def Neon_cmp : SDNode<"AArch64ISD::NEON_CMP", SDTypeProfile<1, 3,
     34                  [SDTCisVec<0>,  SDTCisSameAs<1, 2>]>>;
     35 
     36 // (outs Result), (ins LHS, 0/0.0 constant, CondCode)
     37 def Neon_cmpz : SDNode<"AArch64ISD::NEON_CMPZ", SDTypeProfile<1, 3,
     38                  [SDTCisVec<0>,  SDTCisVec<1>]>>;
     39 
     40 // (outs Result), (ins LHS, RHS)
     41 def Neon_tst : SDNode<"AArch64ISD::NEON_TST", SDTypeProfile<1, 2,
     42                  [SDTCisVec<0>,  SDTCisSameAs<1, 2>]>>;
     43 
     44 //===----------------------------------------------------------------------===//
     45 // Multiclasses
     46 //===----------------------------------------------------------------------===//
     47 
     48 multiclass NeonI_3VSame_B_sizes<bit u, bits<2> size,  bits<5> opcode,
     49                                 string asmop, SDPatternOperator opnode8B,
     50                                 SDPatternOperator opnode16B,
     51                                 bit Commutable = 0>
     52 {
     53   let isCommutable = Commutable in {
     54     def _8B :  NeonI_3VSame<0b0, u, size, opcode,
     55                (outs VPR64:$Rd), (ins VPR64:$Rn, VPR64:$Rm),
     56                asmop # "\t$Rd.8b, $Rn.8b, $Rm.8b",
     57                [(set (v8i8 VPR64:$Rd),
     58                   (v8i8 (opnode8B (v8i8 VPR64:$Rn), (v8i8 VPR64:$Rm))))],
     59                NoItinerary>;
     60 
     61     def _16B : NeonI_3VSame<0b1, u, size, opcode,
     62                (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm),
     63                asmop # "\t$Rd.16b, $Rn.16b, $Rm.16b",
     64                [(set (v16i8 VPR128:$Rd),
     65                   (v16i8 (opnode16B (v16i8 VPR128:$Rn), (v16i8 VPR128:$Rm))))],
     66                NoItinerary>;
     67   }
     68 
     69 }
     70 
     71 multiclass NeonI_3VSame_HS_sizes<bit u, bits<5> opcode,
     72                                   string asmop, SDPatternOperator opnode,
     73                                   bit Commutable = 0>
     74 {
     75   let isCommutable = Commutable in {
     76     def _4H : NeonI_3VSame<0b0, u, 0b01, opcode,
     77               (outs VPR64:$Rd), (ins VPR64:$Rn, VPR64:$Rm),
     78               asmop # "\t$Rd.4h, $Rn.4h, $Rm.4h",
     79               [(set (v4i16 VPR64:$Rd),
     80                  (v4i16 (opnode (v4i16 VPR64:$Rn), (v4i16 VPR64:$Rm))))],
     81               NoItinerary>;
     82 
     83     def _8H : NeonI_3VSame<0b1, u, 0b01, opcode,
     84               (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm),
     85               asmop # "\t$Rd.8h, $Rn.8h, $Rm.8h",
     86               [(set (v8i16 VPR128:$Rd),
     87                  (v8i16 (opnode (v8i16 VPR128:$Rn), (v8i16 VPR128:$Rm))))],
     88               NoItinerary>;
     89 
     90     def _2S : NeonI_3VSame<0b0, u, 0b10, opcode,
     91               (outs VPR64:$Rd), (ins VPR64:$Rn, VPR64:$Rm),
     92               asmop # "\t$Rd.2s, $Rn.2s, $Rm.2s",
     93               [(set (v2i32 VPR64:$Rd),
     94                  (v2i32 (opnode (v2i32 VPR64:$Rn), (v2i32 VPR64:$Rm))))],
     95               NoItinerary>;
     96 
     97     def _4S : NeonI_3VSame<0b1, u, 0b10, opcode,
     98               (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm),
     99               asmop # "\t$Rd.4s, $Rn.4s, $Rm.4s",
    100               [(set (v4i32 VPR128:$Rd),
    101                  (v4i32 (opnode (v4i32 VPR128:$Rn), (v4i32 VPR128:$Rm))))],
    102               NoItinerary>;
    103   }
    104 }
    105 multiclass NeonI_3VSame_BHS_sizes<bit u, bits<5> opcode,
    106                                   string asmop, SDPatternOperator opnode,
    107                                   bit Commutable = 0>
    108    : NeonI_3VSame_HS_sizes<u, opcode,  asmop, opnode, Commutable>
    109 {
    110   let isCommutable = Commutable in {
    111     def _8B :  NeonI_3VSame<0b0, u, 0b00, opcode,
    112                (outs VPR64:$Rd), (ins VPR64:$Rn, VPR64:$Rm),
    113                asmop # "\t$Rd.8b, $Rn.8b, $Rm.8b",
    114                [(set (v8i8 VPR64:$Rd),
    115                   (v8i8 (opnode (v8i8 VPR64:$Rn), (v8i8 VPR64:$Rm))))],
    116                NoItinerary>;
    117 
    118     def _16B : NeonI_3VSame<0b1, u, 0b00, opcode,
    119                (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm),
    120                asmop # "\t$Rd.16b, $Rn.16b, $Rm.16b",
    121                [(set (v16i8 VPR128:$Rd),
    122                   (v16i8 (opnode (v16i8 VPR128:$Rn), (v16i8 VPR128:$Rm))))],
    123                NoItinerary>;
    124   }
    125 }
    126 
    127 multiclass NeonI_3VSame_BHSD_sizes<bit u, bits<5> opcode,
    128                                    string asmop, SDPatternOperator opnode,
    129                                    bit Commutable = 0>
    130    : NeonI_3VSame_BHS_sizes<u, opcode,  asmop, opnode, Commutable>
    131 {
    132   let isCommutable = Commutable in {
    133     def _2D : NeonI_3VSame<0b1, u, 0b11, opcode,
    134               (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm),
    135               asmop # "\t$Rd.2d, $Rn.2d, $Rm.2d",
    136               [(set (v2i64 VPR128:$Rd),
    137                  (v2i64 (opnode (v2i64 VPR128:$Rn), (v2i64 VPR128:$Rm))))],
    138               NoItinerary>;
    139   }
    140 }
    141 
    142 // Multiclass NeonI_3VSame_SD_sizes: Operand types are floating point types,
    143 // but Result types can be integer or floating point types.
    144 multiclass NeonI_3VSame_SD_sizes<bit u, bit size, bits<5> opcode,
    145                                  string asmop, SDPatternOperator opnode2S,
    146                                  SDPatternOperator opnode4S,
    147                                  SDPatternOperator opnode2D,
    148                                  ValueType ResTy2S, ValueType ResTy4S,
    149                                  ValueType ResTy2D, bit Commutable = 0>
    150 {
    151   let isCommutable = Commutable in {
    152     def _2S : NeonI_3VSame<0b0, u, {size, 0b0}, opcode,
    153               (outs VPR64:$Rd), (ins VPR64:$Rn, VPR64:$Rm),
    154               asmop # "\t$Rd.2s, $Rn.2s, $Rm.2s",
    155               [(set (ResTy2S VPR64:$Rd),
    156                  (ResTy2S (opnode2S (v2f32 VPR64:$Rn), (v2f32 VPR64:$Rm))))],
    157               NoItinerary>;
    158 
    159     def _4S : NeonI_3VSame<0b1, u, {size, 0b0}, opcode,
    160               (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm),
    161               asmop # "\t$Rd.4s, $Rn.4s, $Rm.4s",
    162               [(set (ResTy4S VPR128:$Rd),
    163                  (ResTy4S (opnode4S (v4f32 VPR128:$Rn), (v4f32 VPR128:$Rm))))],
    164               NoItinerary>;
    165 
    166     def _2D : NeonI_3VSame<0b1, u, {size, 0b1}, opcode,
    167               (outs VPR128:$Rd), (ins VPR128:$Rn, VPR128:$Rm),
    168               asmop # "\t$Rd.2d, $Rn.2d, $Rm.2d",
    169               [(set (ResTy2D VPR128:$Rd),
    170                  (ResTy2D (opnode2D (v2f64 VPR128:$Rn), (v2f64 VPR128:$Rm))))],
    171                NoItinerary>;
    172   }
    173 }
    174 
    175 //===----------------------------------------------------------------------===//
    176 // Instruction Definitions
    177 //===----------------------------------------------------------------------===//
    178 
    179 // Vector Arithmetic Instructions
    180 
    181 // Vector Add (Integer and Floating-Point)
    182 
    183 defm ADDvvv :  NeonI_3VSame_BHSD_sizes<0b0, 0b10000, "add", add, 1>;
    184 defm FADDvvv : NeonI_3VSame_SD_sizes<0b0, 0b0, 0b11010, "fadd", fadd, fadd, fadd,
    185                                      v2f32, v4f32, v2f64, 1>;
    186 
    187 // Vector Sub (Integer and Floating-Point)
    188 
    189 defm SUBvvv :  NeonI_3VSame_BHSD_sizes<0b1, 0b10000, "sub", sub, 0>;
    190 defm FSUBvvv : NeonI_3VSame_SD_sizes<0b0, 0b1, 0b11010, "fsub", fsub, fsub, fsub,
    191                                      v2f32, v4f32, v2f64, 0>;
    192 
    193 // Vector Multiply (Integer and Floating-Point)
    194 
    195 defm MULvvv :  NeonI_3VSame_BHS_sizes<0b0, 0b10011, "mul", mul, 1>;
    196 defm FMULvvv : NeonI_3VSame_SD_sizes<0b1, 0b0, 0b11011, "fmul", fmul, fmul, fmul,
    197                                      v2f32, v4f32, v2f64, 1>;
    198 
    199 // Vector Multiply (Polynomial)
    200 
    201 defm PMULvvv : NeonI_3VSame_B_sizes<0b1, 0b00, 0b10011, "pmul",
    202                                     int_arm_neon_vmulp, int_arm_neon_vmulp, 1>;
    203 
    204 // Vector Multiply-accumulate and Multiply-subtract (Integer)
    205 
    206 // class NeonI_3VSame_Constraint_impl: NeonI_3VSame with no data type and
    207 // two operands constraints.
    208 class NeonI_3VSame_Constraint_impl<string asmop, string asmlane,
    209   RegisterClass VPRC, ValueType OpTy, bit q, bit u, bits<2> size, bits<5> opcode,
    210   SDPatternOperator opnode>
    211   : NeonI_3VSame<q, u, size, opcode,
    212     (outs VPRC:$Rd), (ins VPRC:$src, VPRC:$Rn, VPRC:$Rm),
    213     asmop # "\t$Rd" # asmlane # ", $Rn" # asmlane # ", $Rm" # asmlane,
    214     [(set (OpTy VPRC:$Rd),
    215        (OpTy (opnode (OpTy VPRC:$src), (OpTy VPRC:$Rn), (OpTy VPRC:$Rm))))],
    216     NoItinerary> {
    217   let Constraints = "$src = $Rd";
    218 }
    219 
    220 def Neon_mla : PatFrag<(ops node:$Ra, node:$Rn, node:$Rm),
    221                        (add node:$Ra, (mul node:$Rn, node:$Rm))>;
    222 
    223 def Neon_mls : PatFrag<(ops node:$Ra, node:$Rn, node:$Rm),
    224                        (sub node:$Ra, (mul node:$Rn, node:$Rm))>;
    225 
    226 
    227 def MLAvvv_8B:  NeonI_3VSame_Constraint_impl<"mla", ".8b",  VPR64,  v8i8,
    228                                              0b0, 0b0, 0b00, 0b10010, Neon_mla>;
    229 def MLAvvv_16B: NeonI_3VSame_Constraint_impl<"mla", ".16b", VPR128, v16i8,
    230                                              0b1, 0b0, 0b00, 0b10010, Neon_mla>;
    231 def MLAvvv_4H:  NeonI_3VSame_Constraint_impl<"mla", ".4h",  VPR64,  v4i16,
    232                                              0b0, 0b0, 0b01, 0b10010, Neon_mla>;
    233 def MLAvvv_8H:  NeonI_3VSame_Constraint_impl<"mla", ".8h",  VPR128, v8i16,
    234                                              0b1, 0b0, 0b01, 0b10010, Neon_mla>;
    235 def MLAvvv_2S:  NeonI_3VSame_Constraint_impl<"mla", ".2s",  VPR64,  v2i32,
    236                                              0b0, 0b0, 0b10, 0b10010, Neon_mla>;
    237 def MLAvvv_4S:  NeonI_3VSame_Constraint_impl<"mla", ".4s",  VPR128, v4i32,
    238                                              0b1, 0b0, 0b10, 0b10010, Neon_mla>;
    239 
    240 def MLSvvv_8B:  NeonI_3VSame_Constraint_impl<"mls", ".8b",  VPR64,  v8i8,
    241                                              0b0, 0b1, 0b00, 0b10010, Neon_mls>;
    242 def MLSvvv_16B: NeonI_3VSame_Constraint_impl<"mls", ".16b", VPR128, v16i8,
    243                                              0b1, 0b1, 0b00, 0b10010, Neon_mls>;
    244 def MLSvvv_4H:  NeonI_3VSame_Constraint_impl<"mls", ".4h",  VPR64,  v4i16,
    245                                              0b0, 0b1, 0b01, 0b10010, Neon_mls>;
    246 def MLSvvv_8H:  NeonI_3VSame_Constraint_impl<"mls", ".8h",  VPR128, v8i16,
    247                                              0b1, 0b1, 0b01, 0b10010, Neon_mls>;
    248 def MLSvvv_2S:  NeonI_3VSame_Constraint_impl<"mls", ".2s",  VPR64,  v2i32,
    249                                              0b0, 0b1, 0b10, 0b10010, Neon_mls>;
    250 def MLSvvv_4S:  NeonI_3VSame_Constraint_impl<"mls", ".4s",  VPR128, v4i32,
    251                                              0b1, 0b1, 0b10, 0b10010, Neon_mls>;
    252 
    253 // Vector Multiply-accumulate and Multiply-subtract (Floating Point)
    254 
    255 def Neon_fmla : PatFrag<(ops node:$Ra, node:$Rn, node:$Rm),
    256                         (fadd node:$Ra, (fmul node:$Rn, node:$Rm))>;
    257 
    258 def Neon_fmls : PatFrag<(ops node:$Ra, node:$Rn, node:$Rm),
    259                         (fsub node:$Ra, (fmul node:$Rn, node:$Rm))>;
    260 
    261 let Predicates = [HasNEON, UseFusedMAC] in {
    262 def FMLAvvv_2S: NeonI_3VSame_Constraint_impl<"fmla", ".2s",  VPR64,  v2f32,
    263                                              0b0, 0b0, 0b00, 0b11001, Neon_fmla>;
    264 def FMLAvvv_4S: NeonI_3VSame_Constraint_impl<"fmla", ".4s",  VPR128, v4f32,
    265                                              0b1, 0b0, 0b00, 0b11001, Neon_fmla>;
    266 def FMLAvvv_2D: NeonI_3VSame_Constraint_impl<"fmla", ".2d",  VPR128, v2f64,
    267                                              0b1, 0b0, 0b01, 0b11001, Neon_fmla>;
    268 
    269 def FMLSvvv_2S: NeonI_3VSame_Constraint_impl<"fmls", ".2s",  VPR64,  v2f32,
    270                                               0b0, 0b0, 0b10, 0b11001, Neon_fmls>;
    271 def FMLSvvv_4S: NeonI_3VSame_Constraint_impl<"fmls", ".4s",  VPR128, v4f32,
    272                                              0b1, 0b0, 0b10, 0b11001, Neon_fmls>;
    273 def FMLSvvv_2D: NeonI_3VSame_Constraint_impl<"fmls", ".2d",  VPR128, v2f64,
    274                                              0b1, 0b0, 0b11, 0b11001, Neon_fmls>;
    275 }
    276 
    277 // We're also allowed to match the fma instruction regardless of compile
    278 // options.
    279 def : Pat<(v2f32 (fma VPR64:$Rn, VPR64:$Rm, VPR64:$Ra)),
    280           (FMLAvvv_2S VPR64:$Ra, VPR64:$Rn, VPR64:$Rm)>;
    281 def : Pat<(v4f32 (fma VPR128:$Rn, VPR128:$Rm, VPR128:$Ra)),
    282           (FMLAvvv_4S VPR128:$Ra, VPR128:$Rn, VPR128:$Rm)>;
    283 def : Pat<(v2f64 (fma VPR128:$Rn, VPR128:$Rm, VPR128:$Ra)),
    284           (FMLAvvv_2D VPR128:$Ra, VPR128:$Rn, VPR128:$Rm)>;
    285 
    286 def : Pat<(v2f32 (fma (fneg VPR64:$Rn), VPR64:$Rm, VPR64:$Ra)),
    287           (FMLSvvv_2S VPR64:$Ra, VPR64:$Rn, VPR64:$Rm)>;
    288 def : Pat<(v4f32 (fma (fneg VPR128:$Rn), VPR128:$Rm, VPR128:$Ra)),
    289           (FMLSvvv_4S VPR128:$Ra, VPR128:$Rn, VPR128:$Rm)>;
    290 def : Pat<(v2f64 (fma (fneg VPR128:$Rn), VPR128:$Rm, VPR128:$Ra)),
    291           (FMLSvvv_2D VPR128:$Ra, VPR128:$Rn, VPR128:$Rm)>;
    292 
    293 // Vector Divide (Floating-Point)
    294 
    295 defm FDIVvvv : NeonI_3VSame_SD_sizes<0b1, 0b0, 0b11111, "fdiv", fdiv, fdiv, fdiv,
    296                                      v2f32, v4f32, v2f64, 0>;
    297 
    298 // Vector Bitwise Operations
    299 
    300 // Vector Bitwise AND
    301 
    302 defm ANDvvv : NeonI_3VSame_B_sizes<0b0, 0b00, 0b00011, "and", and, and, 1>;
    303 
    304 // Vector Bitwise Exclusive OR
    305 
    306 defm EORvvv : NeonI_3VSame_B_sizes<0b1, 0b00, 0b00011, "eor", xor, xor, 1>;
    307 
    308 // Vector Bitwise OR
    309 
    310 defm ORRvvv : NeonI_3VSame_B_sizes<0b0, 0b10, 0b00011, "orr", or, or, 1>;
    311 
    312 // ORR disassembled as MOV if Vn==Vm
    313 
    314 // Vector Move - register
    315 // Alias for ORR if Vn=Vm and it is the preferred syntax
    316 def : NeonInstAlias<"mov $Rd.8b, $Rn.8b",
    317                     (ORRvvv_8B VPR64:$Rd, VPR64:$Rn, VPR64:$Rn)>;
    318 def : NeonInstAlias<"mov $Rd.16b, $Rn.16b",
    319                     (ORRvvv_16B VPR128:$Rd, VPR128:$Rn, VPR128:$Rn)>;
    320 
    321 def Neon_immAllOnes: PatLeaf<(Neon_movi (i32 timm), (i32 imm)), [{
    322   ConstantSDNode *ImmConstVal = cast<ConstantSDNode>(N->getOperand(0));
    323   ConstantSDNode *OpCmodeConstVal = cast<ConstantSDNode>(N->getOperand(1));
    324   unsigned EltBits;
    325   uint64_t EltVal = A64Imms::decodeNeonModImm(ImmConstVal->getZExtValue(),
    326     OpCmodeConstVal->getZExtValue(), EltBits);
    327   return (EltBits == 8 && EltVal == 0xff);
    328 }]>;
    329 
    330 
    331 def Neon_not8B  : PatFrag<(ops node:$in),
    332                           (xor node:$in, (bitconvert (v8i8 Neon_immAllOnes)))>;
    333 def Neon_not16B : PatFrag<(ops node:$in),
    334                           (xor node:$in, (bitconvert (v16i8 Neon_immAllOnes)))>;
    335 
    336 def Neon_orn8B : PatFrag<(ops node:$Rn, node:$Rm),
    337                          (or node:$Rn, (Neon_not8B node:$Rm))>;
    338 
    339 def Neon_orn16B : PatFrag<(ops node:$Rn, node:$Rm),
    340                           (or node:$Rn, (Neon_not16B node:$Rm))>;
    341 
    342 def Neon_bic8B : PatFrag<(ops node:$Rn, node:$Rm),
    343                          (and node:$Rn, (Neon_not8B node:$Rm))>;
    344 
    345 def Neon_bic16B : PatFrag<(ops node:$Rn, node:$Rm),
    346                           (and node:$Rn, (Neon_not16B node:$Rm))>;
    347 
    348 
    349 // Vector Bitwise OR NOT - register
    350 
    351 defm ORNvvv : NeonI_3VSame_B_sizes<0b0, 0b11, 0b00011, "orn",
    352                                    Neon_orn8B, Neon_orn16B, 0>;
    353 
    354 // Vector Bitwise Bit Clear (AND NOT) - register
    355 
    356 defm BICvvv : NeonI_3VSame_B_sizes<0b0, 0b01, 0b00011, "bic",
    357                                    Neon_bic8B, Neon_bic16B, 0>;
    358 
    359 multiclass Neon_bitwise2V_patterns<SDPatternOperator opnode8B,
    360                                    SDPatternOperator opnode16B,
    361                                    Instruction INST8B,
    362                                    Instruction INST16B> {
    363   def : Pat<(v2i32 (opnode8B VPR64:$Rn, VPR64:$Rm)),
    364             (INST8B VPR64:$Rn, VPR64:$Rm)>;
    365   def : Pat<(v4i16 (opnode8B VPR64:$Rn, VPR64:$Rm)),
    366             (INST8B VPR64:$Rn, VPR64:$Rm)>;
    367   def : Pat<(v1i64 (opnode8B VPR64:$Rn, VPR64:$Rm)),
    368             (INST8B VPR64:$Rn, VPR64:$Rm)>;
    369   def : Pat<(v4i32 (opnode16B VPR128:$Rn, VPR128:$Rm)),
    370             (INST16B VPR128:$Rn, VPR128:$Rm)>;
    371   def : Pat<(v8i16 (opnode16B VPR128:$Rn, VPR128:$Rm)),
    372             (INST16B VPR128:$Rn, VPR128:$Rm)>;
    373   def : Pat<(v2i64 (opnode16B VPR128:$Rn, VPR128:$Rm)),
    374             (INST16B VPR128:$Rn, VPR128:$Rm)>;
    375 }
    376 
    377 // Additional patterns for bitwise instructions AND, EOR, ORR, BIC, ORN
    378 defm : Neon_bitwise2V_patterns<and, and, ANDvvv_8B, ANDvvv_16B>;
    379 defm : Neon_bitwise2V_patterns<or,  or,  ORRvvv_8B, ORRvvv_16B>;
    380 defm : Neon_bitwise2V_patterns<xor, xor, EORvvv_8B, EORvvv_16B>;
    381 defm : Neon_bitwise2V_patterns<Neon_bic8B, Neon_bic16B, BICvvv_8B, BICvvv_16B>;
    382 defm : Neon_bitwise2V_patterns<Neon_orn8B, Neon_orn16B, ORNvvv_8B, ORNvvv_16B>;
    383 
    384 //   Vector Bitwise Select
    385 def BSLvvv_8B  : NeonI_3VSame_Constraint_impl<"bsl", ".8b",  VPR64, v8i8,
    386                                               0b0, 0b1, 0b01, 0b00011, Neon_bsl>;
    387 
    388 def BSLvvv_16B : NeonI_3VSame_Constraint_impl<"bsl", ".16b", VPR128, v16i8,
    389                                               0b1, 0b1, 0b01, 0b00011, Neon_bsl>;
    390 
    391 multiclass Neon_bitwise3V_patterns<SDPatternOperator opnode,
    392                                    Instruction INST8B,
    393                                    Instruction INST16B> {
    394   // Disassociate type from instruction definition
    395   def : Pat<(v2i32 (opnode VPR64:$src,VPR64:$Rn, VPR64:$Rm)),
    396             (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>;
    397   def : Pat<(v4i16 (opnode VPR64:$src, VPR64:$Rn, VPR64:$Rm)),
    398             (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>;
    399   def : Pat<(v1i64 (opnode VPR64:$src, VPR64:$Rn, VPR64:$Rm)),
    400             (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>;
    401   def : Pat<(v4i32 (opnode VPR128:$src, VPR128:$Rn, VPR128:$Rm)),
    402             (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>;
    403   def : Pat<(v8i16 (opnode VPR128:$src, VPR128:$Rn, VPR128:$Rm)),
    404             (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>;
    405   def : Pat<(v2i64 (opnode VPR128:$src, VPR128:$Rn, VPR128:$Rm)),
    406             (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>;
    407 
    408   // Allow to match BSL instruction pattern with non-constant operand
    409   def : Pat<(v8i8 (or (and VPR64:$Rn, VPR64:$Rd),
    410                     (and VPR64:$Rm, (Neon_not8B VPR64:$Rd)))),
    411           (INST8B VPR64:$Rd, VPR64:$Rn, VPR64:$Rm)>;
    412   def : Pat<(v4i16 (or (and VPR64:$Rn, VPR64:$Rd),
    413                      (and VPR64:$Rm, (Neon_not8B VPR64:$Rd)))),
    414           (INST8B VPR64:$Rd, VPR64:$Rn, VPR64:$Rm)>;
    415   def : Pat<(v2i32 (or (and VPR64:$Rn, VPR64:$Rd),
    416                      (and VPR64:$Rm, (Neon_not8B VPR64:$Rd)))),
    417           (INST8B VPR64:$Rd, VPR64:$Rn, VPR64:$Rm)>;
    418   def : Pat<(v1i64 (or (and VPR64:$Rn, VPR64:$Rd),
    419                      (and VPR64:$Rm, (Neon_not8B VPR64:$Rd)))),
    420           (INST8B VPR64:$Rd, VPR64:$Rn, VPR64:$Rm)>;
    421   def : Pat<(v16i8 (or (and VPR128:$Rn, VPR128:$Rd),
    422                      (and VPR128:$Rm, (Neon_not16B VPR128:$Rd)))),
    423           (INST16B VPR128:$Rd, VPR128:$Rn, VPR128:$Rm)>;
    424   def : Pat<(v8i16 (or (and VPR128:$Rn, VPR128:$Rd),
    425                      (and VPR128:$Rm, (Neon_not16B VPR128:$Rd)))),
    426           (INST16B VPR128:$Rd, VPR128:$Rn, VPR128:$Rm)>;
    427   def : Pat<(v4i32 (or (and VPR128:$Rn, VPR128:$Rd),
    428                      (and VPR128:$Rm, (Neon_not16B VPR128:$Rd)))),
    429           (INST16B VPR128:$Rd, VPR128:$Rn, VPR128:$Rm)>;
    430   def : Pat<(v2i64 (or (and VPR128:$Rn, VPR128:$Rd),
    431                      (and VPR128:$Rm, (Neon_not16B VPR128:$Rd)))),
    432           (INST16B VPR128:$Rd, VPR128:$Rn, VPR128:$Rm)>;
    433 
    434   // Allow to match llvm.arm.* intrinsics.
    435   def : Pat<(v8i8 (int_arm_neon_vbsl (v8i8 VPR64:$src),
    436                     (v8i8 VPR64:$Rn), (v8i8 VPR64:$Rm))),
    437             (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>;
    438   def : Pat<(v4i16 (int_arm_neon_vbsl (v4i16 VPR64:$src),
    439                     (v4i16 VPR64:$Rn), (v4i16 VPR64:$Rm))),
    440             (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>;
    441   def : Pat<(v2i32 (int_arm_neon_vbsl (v2i32 VPR64:$src),
    442                     (v2i32 VPR64:$Rn), (v2i32 VPR64:$Rm))),
    443             (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>;
    444   def : Pat<(v1i64 (int_arm_neon_vbsl (v1i64 VPR64:$src),
    445                     (v1i64 VPR64:$Rn), (v1i64 VPR64:$Rm))),
    446             (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>;
    447   def : Pat<(v2f32 (int_arm_neon_vbsl (v2f32 VPR64:$src),
    448                     (v2f32 VPR64:$Rn), (v2f32 VPR64:$Rm))),
    449             (INST8B VPR64:$src, VPR64:$Rn, VPR64:$Rm)>;
    450   def : Pat<(v16i8 (int_arm_neon_vbsl (v16i8 VPR128:$src),
    451                     (v16i8 VPR128:$Rn), (v16i8 VPR128:$Rm))),
    452             (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>;
    453   def : Pat<(v8i16 (int_arm_neon_vbsl (v8i16 VPR128:$src),
    454                     (v8i16 VPR128:$Rn), (v8i16 VPR128:$Rm))),
    455             (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>;
    456   def : Pat<(v4i32 (int_arm_neon_vbsl (v4i32 VPR128:$src),
    457                     (v4i32 VPR128:$Rn), (v4i32 VPR128:$Rm))),
    458             (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>;
    459   def : Pat<(v2i64 (int_arm_neon_vbsl (v2i64 VPR128:$src),
    460                     (v2i64 VPR128:$Rn), (v2i64 VPR128:$Rm))),
    461             (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>;
    462   def : Pat<(v4f32 (int_arm_neon_vbsl (v4f32 VPR128:$src),
    463                     (v4f32 VPR128:$Rn), (v4f32 VPR128:$Rm))),
    464             (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>;
    465   def : Pat<(v2f64 (int_arm_neon_vbsl (v2f64 VPR128:$src),
    466                     (v2f64 VPR128:$Rn), (v2f64 VPR128:$Rm))),
    467             (INST16B VPR128:$src, VPR128:$Rn, VPR128:$Rm)>;
    468 }
    469 
    470 // Additional patterns for bitwise instruction BSL
    471 defm: Neon_bitwise3V_patterns<Neon_bsl, BSLvvv_8B, BSLvvv_16B>;
    472 
    473 def Neon_NoBSLop : PatFrag<(ops node:$src, node:$Rn, node:$Rm),
    474                            (Neon_bsl node:$src, node:$Rn, node:$Rm),
    475                            [{ (void)N; return false; }]>;
    476 
    477 // Vector Bitwise Insert if True
    478 
    479 def BITvvv_8B  : NeonI_3VSame_Constraint_impl<"bit", ".8b", VPR64,   v8i8,
    480                    0b0, 0b1, 0b10, 0b00011, Neon_NoBSLop>;
    481 def BITvvv_16B : NeonI_3VSame_Constraint_impl<"bit", ".16b", VPR128, v16i8,
    482                    0b1, 0b1, 0b10, 0b00011, Neon_NoBSLop>;
    483 
    484 // Vector Bitwise Insert if False
    485 
    486 def BIFvvv_8B  : NeonI_3VSame_Constraint_impl<"bif", ".8b", VPR64,  v8i8,
    487                                 0b0, 0b1, 0b11, 0b00011, Neon_NoBSLop>;
    488 def BIFvvv_16B : NeonI_3VSame_Constraint_impl<"bif", ".16b", VPR128, v16i8,
    489                                 0b1, 0b1, 0b11, 0b00011, Neon_NoBSLop>;
    490 
    491 // Vector Absolute Difference and Accumulate (Signed, Unsigned)
    492 
    493 def Neon_uaba : PatFrag<(ops node:$Ra, node:$Rn, node:$Rm),
    494                        (add node:$Ra, (int_arm_neon_vabdu node:$Rn, node:$Rm))>;
    495 def Neon_saba : PatFrag<(ops node:$Ra, node:$Rn, node:$Rm),
    496                        (add node:$Ra, (int_arm_neon_vabds node:$Rn, node:$Rm))>;
    497 
    498 // Vector Absolute Difference and Accumulate (Unsigned)
    499 def UABAvvv_8B :  NeonI_3VSame_Constraint_impl<"uaba", ".8b",  VPR64,  v8i8,
    500                     0b0, 0b1, 0b00, 0b01111, Neon_uaba>;
    501 def UABAvvv_16B : NeonI_3VSame_Constraint_impl<"uaba", ".16b", VPR128, v16i8,
    502                     0b1, 0b1, 0b00, 0b01111, Neon_uaba>;
    503 def UABAvvv_4H :  NeonI_3VSame_Constraint_impl<"uaba", ".4h",  VPR64,  v4i16,
    504                     0b0, 0b1, 0b01, 0b01111, Neon_uaba>;
    505 def UABAvvv_8H :  NeonI_3VSame_Constraint_impl<"uaba", ".8h",  VPR128, v8i16,
    506                     0b1, 0b1, 0b01, 0b01111, Neon_uaba>;
    507 def UABAvvv_2S :  NeonI_3VSame_Constraint_impl<"uaba", ".2s",  VPR64,  v2i32,
    508                     0b0, 0b1, 0b10, 0b01111, Neon_uaba>;
    509 def UABAvvv_4S :  NeonI_3VSame_Constraint_impl<"uaba", ".4s",  VPR128, v4i32,
    510                     0b1, 0b1, 0b10, 0b01111, Neon_uaba>;
    511 
    512 // Vector Absolute Difference and Accumulate (Signed)
    513 def SABAvvv_8B :  NeonI_3VSame_Constraint_impl<"saba", ".8b",  VPR64,  v8i8,
    514                     0b0, 0b0, 0b00, 0b01111, Neon_saba>;
    515 def SABAvvv_16B : NeonI_3VSame_Constraint_impl<"saba", ".16b", VPR128, v16i8,
    516                     0b1, 0b0, 0b00, 0b01111, Neon_saba>;
    517 def SABAvvv_4H :  NeonI_3VSame_Constraint_impl<"saba", ".4h",  VPR64,  v4i16,
    518                     0b0, 0b0, 0b01, 0b01111, Neon_saba>;
    519 def SABAvvv_8H :  NeonI_3VSame_Constraint_impl<"saba", ".8h",  VPR128, v8i16,
    520                     0b1, 0b0, 0b01, 0b01111, Neon_saba>;
    521 def SABAvvv_2S :  NeonI_3VSame_Constraint_impl<"saba", ".2s",  VPR64,  v2i32,
    522                     0b0, 0b0, 0b10, 0b01111, Neon_saba>;
    523 def SABAvvv_4S :  NeonI_3VSame_Constraint_impl<"saba", ".4s",  VPR128, v4i32,
    524                     0b1, 0b0, 0b10, 0b01111, Neon_saba>;
    525 
    526 
    527 // Vector Absolute Difference (Signed, Unsigned)
    528 defm UABDvvv : NeonI_3VSame_BHS_sizes<0b1, 0b01110, "uabd", int_arm_neon_vabdu, 0>;
    529 defm SABDvvv : NeonI_3VSame_BHS_sizes<0b0, 0b01110, "sabd", int_arm_neon_vabds, 0>;
    530 
    531 // Vector Absolute Difference (Floating Point)
    532 defm FABDvvv: NeonI_3VSame_SD_sizes<0b1, 0b1, 0b11010, "fabd",
    533                                     int_arm_neon_vabds, int_arm_neon_vabds,
    534                                     int_arm_neon_vabds, v2f32, v4f32, v2f64, 0>;
    535 
    536 // Vector Reciprocal Step (Floating Point)
    537 defm FRECPSvvv : NeonI_3VSame_SD_sizes<0b0, 0b0, 0b11111, "frecps",
    538                                        int_arm_neon_vrecps, int_arm_neon_vrecps,
    539                                        int_arm_neon_vrecps,
    540                                        v2f32, v4f32, v2f64, 0>;
    541 
    542 // Vector Reciprocal Square Root Step (Floating Point)
    543 defm FRSQRTSvvv : NeonI_3VSame_SD_sizes<0b0, 0b1, 0b11111, "frsqrts",
    544                                         int_arm_neon_vrsqrts,
    545                                         int_arm_neon_vrsqrts,
    546                                         int_arm_neon_vrsqrts,
    547                                         v2f32, v4f32, v2f64, 0>;
    548 
    549 // Vector Comparisons
    550 
    551 def Neon_cmeq : PatFrag<(ops node:$lhs, node:$rhs),
    552                         (Neon_cmp node:$lhs, node:$rhs, SETEQ)>;
    553 def Neon_cmphs : PatFrag<(ops node:$lhs, node:$rhs),
    554                          (Neon_cmp node:$lhs, node:$rhs, SETUGE)>;
    555 def Neon_cmge : PatFrag<(ops node:$lhs, node:$rhs),
    556                         (Neon_cmp node:$lhs, node:$rhs, SETGE)>;
    557 def Neon_cmhi : PatFrag<(ops node:$lhs, node:$rhs),
    558                         (Neon_cmp node:$lhs, node:$rhs, SETUGT)>;
    559 def Neon_cmgt : PatFrag<(ops node:$lhs, node:$rhs),
    560                         (Neon_cmp node:$lhs, node:$rhs, SETGT)>;
    561 
    562 // NeonI_compare_aliases class: swaps register operands to implement
    563 // comparison aliases, e.g., CMLE is alias for CMGE with operands reversed.
    564 class NeonI_compare_aliases<string asmop, string asmlane,
    565                             Instruction inst, RegisterClass VPRC>
    566   : NeonInstAlias<asmop # "\t$Rd" # asmlane #", $Rn" # asmlane #
    567                     ", $Rm" # asmlane,
    568                   (inst VPRC:$Rd, VPRC:$Rm, VPRC:$Rn), 0b0>;
    569 
    570 // Vector Comparisons (Integer)
    571 
    572 // Vector Compare Mask Equal (Integer)
    573 let isCommutable =1 in {
    574 defm CMEQvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b10001, "cmeq", Neon_cmeq, 0>;
    575 }
    576 
    577 // Vector Compare Mask Higher or Same (Unsigned Integer)
    578 defm CMHSvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b00111, "cmhs", Neon_cmphs, 0>;
    579 
    580 // Vector Compare Mask Greater Than or Equal (Integer)
    581 defm CMGEvvv : NeonI_3VSame_BHSD_sizes<0b0, 0b00111, "cmge", Neon_cmge, 0>;
    582 
    583 // Vector Compare Mask Higher (Unsigned Integer)
    584 defm CMHIvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b00110, "cmhi", Neon_cmhi, 0>;
    585 
    586 // Vector Compare Mask Greater Than (Integer)
    587 defm CMGTvvv : NeonI_3VSame_BHSD_sizes<0b0, 0b00110, "cmgt", Neon_cmgt, 0>;
    588 
    589 // Vector Compare Mask Bitwise Test (Integer)
    590 defm CMTSTvvv:  NeonI_3VSame_BHSD_sizes<0b0, 0b10001, "cmtst", Neon_tst, 0>;
    591 
    592 // Vector Compare Mask Less or Same (Unsigned Integer)
    593 // CMLS is alias for CMHS with operands reversed.
    594 def CMLSvvv_8B  : NeonI_compare_aliases<"cmls", ".8b",  CMHSvvv_8B,  VPR64>;
    595 def CMLSvvv_16B : NeonI_compare_aliases<"cmls", ".16b", CMHSvvv_16B, VPR128>;
    596 def CMLSvvv_4H  : NeonI_compare_aliases<"cmls", ".4h",  CMHSvvv_4H,  VPR64>;
    597 def CMLSvvv_8H  : NeonI_compare_aliases<"cmls", ".8h",  CMHSvvv_8H,  VPR128>;
    598 def CMLSvvv_2S  : NeonI_compare_aliases<"cmls", ".2s",  CMHSvvv_2S,  VPR64>;
    599 def CMLSvvv_4S  : NeonI_compare_aliases<"cmls", ".4s",  CMHSvvv_4S,  VPR128>;
    600 def CMLSvvv_2D  : NeonI_compare_aliases<"cmls", ".2d",  CMHSvvv_2D,  VPR128>;
    601 
    602 // Vector Compare Mask Less Than or Equal (Integer)
    603 // CMLE is alias for CMGE with operands reversed.
    604 def CMLEvvv_8B  : NeonI_compare_aliases<"cmle", ".8b",  CMGEvvv_8B,  VPR64>;
    605 def CMLEvvv_16B : NeonI_compare_aliases<"cmle", ".16b", CMGEvvv_16B, VPR128>;
    606 def CMLEvvv_4H  : NeonI_compare_aliases<"cmle", ".4h",  CMGEvvv_4H,  VPR64>;
    607 def CMLEvvv_8H  : NeonI_compare_aliases<"cmle", ".8h",  CMGEvvv_8H,  VPR128>;
    608 def CMLEvvv_2S  : NeonI_compare_aliases<"cmle", ".2s",  CMGEvvv_2S,  VPR64>;
    609 def CMLEvvv_4S  : NeonI_compare_aliases<"cmle", ".4s",  CMGEvvv_4S,  VPR128>;
    610 def CMLEvvv_2D  : NeonI_compare_aliases<"cmle", ".2d",  CMGEvvv_2D,  VPR128>;
    611 
    612 // Vector Compare Mask Lower (Unsigned Integer)
    613 // CMLO is alias for CMHI with operands reversed.
    614 def CMLOvvv_8B  : NeonI_compare_aliases<"cmlo", ".8b",  CMHIvvv_8B,  VPR64>;
    615 def CMLOvvv_16B : NeonI_compare_aliases<"cmlo", ".16b", CMHIvvv_16B, VPR128>;
    616 def CMLOvvv_4H  : NeonI_compare_aliases<"cmlo", ".4h",  CMHIvvv_4H,  VPR64>;
    617 def CMLOvvv_8H  : NeonI_compare_aliases<"cmlo", ".8h",  CMHIvvv_8H,  VPR128>;
    618 def CMLOvvv_2S  : NeonI_compare_aliases<"cmlo", ".2s",  CMHIvvv_2S,  VPR64>;
    619 def CMLOvvv_4S  : NeonI_compare_aliases<"cmlo", ".4s",  CMHIvvv_4S,  VPR128>;
    620 def CMLOvvv_2D  : NeonI_compare_aliases<"cmlo", ".2d",  CMHIvvv_2D,  VPR128>;
    621 
    622 // Vector Compare Mask Less Than (Integer)
    623 // CMLT is alias for CMGT with operands reversed.
    624 def CMLTvvv_8B  : NeonI_compare_aliases<"cmlt", ".8b",  CMGTvvv_8B,  VPR64>;
    625 def CMLTvvv_16B : NeonI_compare_aliases<"cmlt", ".16b", CMGTvvv_16B, VPR128>;
    626 def CMLTvvv_4H  : NeonI_compare_aliases<"cmlt", ".4h",  CMGTvvv_4H,  VPR64>;
    627 def CMLTvvv_8H  : NeonI_compare_aliases<"cmlt", ".8h",  CMGTvvv_8H,  VPR128>;
    628 def CMLTvvv_2S  : NeonI_compare_aliases<"cmlt", ".2s",  CMGTvvv_2S,  VPR64>;
    629 def CMLTvvv_4S  : NeonI_compare_aliases<"cmlt", ".4s",  CMGTvvv_4S,  VPR128>;
    630 def CMLTvvv_2D  : NeonI_compare_aliases<"cmlt", ".2d",  CMGTvvv_2D,  VPR128>;
    631 
    632 
    633 def neon_uimm0_asmoperand : AsmOperandClass
    634 {
    635   let Name = "UImm0";
    636   let PredicateMethod = "isUImm<0>";
    637   let RenderMethod = "addImmOperands";
    638 }
    639 
    640 def neon_uimm0 : Operand<i32>, ImmLeaf<i32, [{return Imm == 0;}]> {
    641   let ParserMatchClass = neon_uimm0_asmoperand;
    642   let PrintMethod = "printNeonUImm0Operand";
    643 
    644 }
    645 
    646 multiclass NeonI_cmpz_sizes<bit u, bits<5> opcode, string asmop, CondCode CC>
    647 {
    648   def _8B :  NeonI_2VMisc<0b0, u, 0b00, opcode,
    649              (outs VPR64:$Rd), (ins VPR64:$Rn, neon_uimm0:$Imm),
    650              asmop # "\t$Rd.8b, $Rn.8b, $Imm",
    651              [(set (v8i8 VPR64:$Rd),
    652                 (v8i8 (Neon_cmpz (v8i8 VPR64:$Rn), (i32 imm:$Imm), CC)))],
    653              NoItinerary>;
    654 
    655   def _16B : NeonI_2VMisc<0b1, u, 0b00, opcode,
    656              (outs VPR128:$Rd), (ins VPR128:$Rn, neon_uimm0:$Imm),
    657              asmop # "\t$Rd.16b, $Rn.16b, $Imm",
    658              [(set (v16i8 VPR128:$Rd),
    659                 (v16i8 (Neon_cmpz (v16i8 VPR128:$Rn), (i32 imm:$Imm), CC)))],
    660              NoItinerary>;
    661 
    662   def _4H : NeonI_2VMisc<0b0, u, 0b01, opcode,
    663             (outs VPR64:$Rd), (ins VPR64:$Rn, neon_uimm0:$Imm),
    664             asmop # "\t$Rd.4h, $Rn.4h, $Imm",
    665             [(set (v4i16 VPR64:$Rd),
    666                (v4i16 (Neon_cmpz (v4i16 VPR64:$Rn), (i32 imm:$Imm), CC)))],
    667             NoItinerary>;
    668 
    669   def _8H : NeonI_2VMisc<0b1, u, 0b01, opcode,
    670             (outs VPR128:$Rd), (ins VPR128:$Rn, neon_uimm0:$Imm),
    671             asmop # "\t$Rd.8h, $Rn.8h, $Imm",
    672             [(set (v8i16 VPR128:$Rd),
    673                (v8i16 (Neon_cmpz (v8i16 VPR128:$Rn), (i32 imm:$Imm), CC)))],
    674             NoItinerary>;
    675 
    676   def _2S : NeonI_2VMisc<0b0, u, 0b10, opcode,
    677             (outs VPR64:$Rd), (ins VPR64:$Rn, neon_uimm0:$Imm),
    678             asmop # "\t$Rd.2s, $Rn.2s, $Imm",
    679             [(set (v2i32 VPR64:$Rd),
    680                (v2i32 (Neon_cmpz (v2i32 VPR64:$Rn), (i32 imm:$Imm), CC)))],
    681             NoItinerary>;
    682 
    683   def _4S : NeonI_2VMisc<0b1, u, 0b10, opcode,
    684             (outs VPR128:$Rd), (ins VPR128:$Rn, neon_uimm0:$Imm),
    685             asmop # "\t$Rd.4s, $Rn.4s, $Imm",
    686             [(set (v4i32 VPR128:$Rd),
    687                (v4i32 (Neon_cmpz (v4i32 VPR128:$Rn), (i32 imm:$Imm), CC)))],
    688             NoItinerary>;
    689 
    690   def _2D : NeonI_2VMisc<0b1, u, 0b11, opcode,
    691             (outs VPR128:$Rd), (ins VPR128:$Rn, neon_uimm0:$Imm),
    692             asmop # "\t$Rd.2d, $Rn.2d, $Imm",
    693             [(set (v2i64 VPR128:$Rd),
    694                (v2i64 (Neon_cmpz (v2i64 VPR128:$Rn), (i32 imm:$Imm), CC)))],
    695             NoItinerary>;
    696 }
    697 
    698 // Vector Compare Mask Equal to Zero (Integer)
    699 defm CMEQvvi : NeonI_cmpz_sizes<0b0, 0b01001, "cmeq", SETEQ>;
    700 
    701 // Vector Compare Mask Greater Than or Equal to Zero (Signed Integer)
    702 defm CMGEvvi : NeonI_cmpz_sizes<0b1, 0b01000, "cmge", SETGE>;
    703 
    704 // Vector Compare Mask Greater Than Zero (Signed Integer)
    705 defm CMGTvvi : NeonI_cmpz_sizes<0b0, 0b01000, "cmgt", SETGT>;
    706 
    707 // Vector Compare Mask Less Than or Equal To Zero (Signed Integer)
    708 defm CMLEvvi : NeonI_cmpz_sizes<0b1, 0b01001, "cmle", SETLE>;
    709 
    710 // Vector Compare Mask Less Than Zero (Signed Integer)
    711 defm CMLTvvi : NeonI_cmpz_sizes<0b0, 0b01010, "cmlt", SETLT>;
    712 
    713 // Vector Comparisons (Floating Point)
    714 
    715 // Vector Compare Mask Equal (Floating Point)
    716 let isCommutable =1 in {
    717 defm FCMEQvvv : NeonI_3VSame_SD_sizes<0b0, 0b0, 0b11100, "fcmeq", Neon_cmeq,
    718                                       Neon_cmeq, Neon_cmeq,
    719                                       v2i32, v4i32, v2i64, 0>;
    720 }
    721 
    722 // Vector Compare Mask Greater Than Or Equal (Floating Point)
    723 defm FCMGEvvv : NeonI_3VSame_SD_sizes<0b1, 0b0, 0b11100, "fcmge", Neon_cmge,
    724                                       Neon_cmge, Neon_cmge,
    725                                       v2i32, v4i32, v2i64, 0>;
    726 
    727 // Vector Compare Mask Greater Than (Floating Point)
    728 defm FCMGTvvv : NeonI_3VSame_SD_sizes<0b1, 0b1, 0b11100, "fcmgt", Neon_cmgt,
    729                                       Neon_cmgt, Neon_cmgt,
    730                                       v2i32, v4i32, v2i64, 0>;
    731 
    732 // Vector Compare Mask Less Than Or Equal (Floating Point)
    733 // FCMLE is alias for FCMGE with operands reversed.
    734 def FCMLEvvv_2S  : NeonI_compare_aliases<"fcmle", ".2s",  FCMGEvvv_2S,  VPR64>;
    735 def FCMLEvvv_4S  : NeonI_compare_aliases<"fcmle", ".4s",  FCMGEvvv_4S,  VPR128>;
    736 def FCMLEvvv_2D  : NeonI_compare_aliases<"fcmle", ".2d",  FCMGEvvv_2D,  VPR128>;
    737 
    738 // Vector Compare Mask Less Than (Floating Point)
    739 // FCMLT is alias for FCMGT with operands reversed.
    740 def FCMLTvvv_2S  : NeonI_compare_aliases<"fcmlt", ".2s",  FCMGTvvv_2S,  VPR64>;
    741 def FCMLTvvv_4S  : NeonI_compare_aliases<"fcmlt", ".4s",  FCMGTvvv_4S,  VPR128>;
    742 def FCMLTvvv_2D  : NeonI_compare_aliases<"fcmlt", ".2d",  FCMGTvvv_2D,  VPR128>;
    743 
    744 
    745 multiclass NeonI_fpcmpz_sizes<bit u, bit size, bits<5> opcode,
    746                               string asmop, CondCode CC>
    747 {
    748   def _2S : NeonI_2VMisc<0b0, u, {size, 0b0}, opcode,
    749             (outs VPR64:$Rd), (ins VPR64:$Rn, fpz32:$FPImm),
    750             asmop # "\t$Rd.2s, $Rn.2s, $FPImm",
    751             [(set (v2i32 VPR64:$Rd),
    752                (v2i32 (Neon_cmpz (v2f32 VPR64:$Rn), (f32 fpimm:$FPImm), CC)))],
    753             NoItinerary>;
    754 
    755   def _4S : NeonI_2VMisc<0b1, u, {size, 0b0}, opcode,
    756             (outs VPR128:$Rd), (ins VPR128:$Rn, fpz32:$FPImm),
    757             asmop # "\t$Rd.4s, $Rn.4s, $FPImm",
    758             [(set (v4i32 VPR128:$Rd),
    759                (v4i32 (Neon_cmpz (v4f32 VPR128:$Rn), (f32 fpimm:$FPImm), CC)))],
    760             NoItinerary>;
    761 
    762   def _2D : NeonI_2VMisc<0b1, u, {size, 0b1}, opcode,
    763             (outs VPR128:$Rd), (ins VPR128:$Rn, fpz32:$FPImm),
    764             asmop # "\t$Rd.2d, $Rn.2d, $FPImm",
    765             [(set (v2i64 VPR128:$Rd),
    766                (v2i64 (Neon_cmpz (v2f64 VPR128:$Rn), (f32 fpimm:$FPImm), CC)))],
    767             NoItinerary>;
    768 }
    769 
    770 // Vector Compare Mask Equal to Zero (Floating Point)
    771 defm FCMEQvvi : NeonI_fpcmpz_sizes<0b0, 0b1, 0b01101, "fcmeq", SETEQ>;
    772 
    773 // Vector Compare Mask Greater Than or Equal to Zero (Floating Point)
    774 defm FCMGEvvi : NeonI_fpcmpz_sizes<0b1, 0b1, 0b01100, "fcmge", SETGE>;
    775 
    776 // Vector Compare Mask Greater Than Zero (Floating Point)
    777 defm FCMGTvvi : NeonI_fpcmpz_sizes<0b0, 0b1, 0b01100, "fcmgt", SETGT>;
    778 
    779 // Vector Compare Mask Less Than or Equal To Zero (Floating Point)
    780 defm FCMLEvvi : NeonI_fpcmpz_sizes<0b1, 0b1, 0b01101, "fcmle", SETLE>;
    781 
    782 // Vector Compare Mask Less Than Zero (Floating Point)
    783 defm FCMLTvvi : NeonI_fpcmpz_sizes<0b0, 0b1, 0b01110, "fcmlt", SETLT>;
    784 
    785 // Vector Absolute Comparisons (Floating Point)
    786 
    787 // Vector Absolute Compare Mask Greater Than Or Equal (Floating Point)
    788 defm FACGEvvv : NeonI_3VSame_SD_sizes<0b1, 0b0, 0b11101, "facge",
    789                                       int_arm_neon_vacged, int_arm_neon_vacgeq,
    790                                       int_aarch64_neon_vacgeq,
    791                                       v2i32, v4i32, v2i64, 0>;
    792 
    793 // Vector Absolute Compare Mask Greater Than (Floating Point)
    794 defm FACGTvvv : NeonI_3VSame_SD_sizes<0b1, 0b1, 0b11101, "facgt",
    795                                       int_arm_neon_vacgtd, int_arm_neon_vacgtq,
    796                                       int_aarch64_neon_vacgtq,
    797                                       v2i32, v4i32, v2i64, 0>;
    798 
    799 // Vector Absolute Compare Mask Less Than Or Equal (Floating Point)
    800 // FACLE is alias for FACGE with operands reversed.
    801 def FACLEvvv_2S  : NeonI_compare_aliases<"facle", ".2s",  FACGEvvv_2S,  VPR64>;
    802 def FACLEvvv_4S  : NeonI_compare_aliases<"facle", ".4s",  FACGEvvv_4S,  VPR128>;
    803 def FACLEvvv_2D  : NeonI_compare_aliases<"facle", ".2d",  FACGEvvv_2D,  VPR128>;
    804 
    805 // Vector Absolute Compare Mask Less Than (Floating Point)
    806 // FACLT is alias for FACGT with operands reversed.
    807 def FACLTvvv_2S  : NeonI_compare_aliases<"faclt", ".2s",  FACGTvvv_2S,  VPR64>;
    808 def FACLTvvv_4S  : NeonI_compare_aliases<"faclt", ".4s",  FACGTvvv_4S,  VPR128>;
    809 def FACLTvvv_2D  : NeonI_compare_aliases<"faclt", ".2d",  FACGTvvv_2D,  VPR128>;
    810 
    811 // Vector halving add (Integer Signed, Unsigned)
    812 defm SHADDvvv :  NeonI_3VSame_BHS_sizes<0b0, 0b00000, "shadd",
    813                                         int_arm_neon_vhadds, 1>;
    814 defm UHADDvvv :  NeonI_3VSame_BHS_sizes<0b1, 0b00000, "uhadd",
    815                                         int_arm_neon_vhaddu, 1>;
    816 
    817 // Vector halving sub (Integer Signed, Unsigned)
    818 defm SHSUBvvv :  NeonI_3VSame_BHS_sizes<0b0, 0b00100, "shsub",
    819                                         int_arm_neon_vhsubs, 0>;
    820 defm UHSUBvvv :  NeonI_3VSame_BHS_sizes<0b1, 0b00100, "uhsub",
    821                                         int_arm_neon_vhsubu, 0>;
    822 
    823 // Vector rouding halving add (Integer Signed, Unsigned)
    824 defm SRHADDvvv :  NeonI_3VSame_BHS_sizes<0b0, 0b00010, "srhadd",
    825                                          int_arm_neon_vrhadds, 1>;
    826 defm URHADDvvv :  NeonI_3VSame_BHS_sizes<0b1, 0b00010, "urhadd",
    827                                          int_arm_neon_vrhaddu, 1>;
    828 
    829 // Vector Saturating add (Integer Signed, Unsigned)
    830 defm SQADDvvv :  NeonI_3VSame_BHSD_sizes<0b0, 0b00001, "sqadd",
    831                    int_arm_neon_vqadds, 1>;
    832 defm UQADDvvv :  NeonI_3VSame_BHSD_sizes<0b1, 0b00001, "uqadd",
    833                    int_arm_neon_vqaddu, 1>;
    834 
    835 // Vector Saturating sub (Integer Signed, Unsigned)
    836 defm SQSUBvvv :  NeonI_3VSame_BHSD_sizes<0b0, 0b00101, "sqsub",
    837                    int_arm_neon_vqsubs, 1>;
    838 defm UQSUBvvv :  NeonI_3VSame_BHSD_sizes<0b1, 0b00101, "uqsub",
    839                    int_arm_neon_vqsubu, 1>;
    840 
    841 // Vector Shift Left (Signed and Unsigned Integer)
    842 defm SSHLvvv : NeonI_3VSame_BHSD_sizes<0b0, 0b01000, "sshl",
    843                  int_arm_neon_vshifts, 1>;
    844 defm USHLvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b01000, "ushl",
    845                  int_arm_neon_vshiftu, 1>;
    846 
    847 // Vector Saturating Shift Left (Signed and Unsigned Integer)
    848 defm SQSHLvvv : NeonI_3VSame_BHSD_sizes<0b0, 0b01001, "sqshl",
    849                   int_arm_neon_vqshifts, 1>;
    850 defm UQSHLvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b01001, "uqshl",
    851                   int_arm_neon_vqshiftu, 1>;
    852 
    853 // Vector Rouding Shift Left (Signed and Unsigned Integer)
    854 defm SRSHLvvv : NeonI_3VSame_BHSD_sizes<0b0, 0b01010, "srshl",
    855                   int_arm_neon_vrshifts, 1>;
    856 defm URSHLvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b01010, "urshl",
    857                   int_arm_neon_vrshiftu, 1>;
    858 
    859 // Vector Saturating Rouding Shift Left (Signed and Unsigned Integer)
    860 defm SQRSHLvvv : NeonI_3VSame_BHSD_sizes<0b0, 0b01011, "sqrshl",
    861                    int_arm_neon_vqrshifts, 1>;
    862 defm UQRSHLvvv : NeonI_3VSame_BHSD_sizes<0b1, 0b01011, "uqrshl",
    863                    int_arm_neon_vqrshiftu, 1>;
    864 
    865 // Vector Maximum (Signed and Unsigned Integer)
    866 defm SMAXvvv : NeonI_3VSame_BHS_sizes<0b0, 0b01100, "smax", int_arm_neon_vmaxs, 1>;
    867 defm UMAXvvv : NeonI_3VSame_BHS_sizes<0b1, 0b01100, "umax", int_arm_neon_vmaxu, 1>;
    868 
    869 // Vector Minimum (Signed and Unsigned Integer)
    870 defm SMINvvv : NeonI_3VSame_BHS_sizes<0b0, 0b01101, "smin", int_arm_neon_vmins, 1>;
    871 defm UMINvvv : NeonI_3VSame_BHS_sizes<0b1, 0b01101, "umin", int_arm_neon_vminu, 1>;
    872 
    873 // Vector Maximum (Floating Point)
    874 defm FMAXvvv : NeonI_3VSame_SD_sizes<0b0, 0b0, 0b11110, "fmax",
    875                                      int_arm_neon_vmaxs, int_arm_neon_vmaxs,
    876                                      int_arm_neon_vmaxs, v2f32, v4f32, v2f64, 1>;
    877 
    878 // Vector Minimum (Floating Point)
    879 defm FMINvvv : NeonI_3VSame_SD_sizes<0b0, 0b1, 0b11110, "fmin",
    880                                      int_arm_neon_vmins, int_arm_neon_vmins,
    881                                      int_arm_neon_vmins, v2f32, v4f32, v2f64, 1>;
    882 
    883 // Vector maxNum (Floating Point) -  prefer a number over a quiet NaN)
    884 defm FMAXNMvvv : NeonI_3VSame_SD_sizes<0b0, 0b0, 0b11000, "fmaxnm",
    885                                        int_aarch64_neon_vmaxnm,
    886                                        int_aarch64_neon_vmaxnm,
    887                                        int_aarch64_neon_vmaxnm,
    888                                        v2f32, v4f32, v2f64, 1>;
    889 
    890 // Vector minNum (Floating Point) - prefer a number over a quiet NaN)
    891 defm FMINNMvvv : NeonI_3VSame_SD_sizes<0b0, 0b1, 0b11000, "fminnm",
    892                                        int_aarch64_neon_vminnm,
    893                                        int_aarch64_neon_vminnm,
    894                                        int_aarch64_neon_vminnm,
    895                                        v2f32, v4f32, v2f64, 1>;
    896 
    897 // Vector Maximum Pairwise (Signed and Unsigned Integer)
    898 defm SMAXPvvv : NeonI_3VSame_BHS_sizes<0b0, 0b10100, "smaxp", int_arm_neon_vpmaxs, 1>;
    899 defm UMAXPvvv : NeonI_3VSame_BHS_sizes<0b1, 0b10100, "umaxp", int_arm_neon_vpmaxu, 1>;
    900 
    901 // Vector Minimum Pairwise (Signed and Unsigned Integer)
    902 defm SMINPvvv : NeonI_3VSame_BHS_sizes<0b0, 0b10101, "sminp", int_arm_neon_vpmins, 1>;
    903 defm UMINPvvv : NeonI_3VSame_BHS_sizes<0b1, 0b10101, "uminp", int_arm_neon_vpminu, 1>;
    904 
    905 // Vector Maximum Pairwise (Floating Point)
    906 defm FMAXPvvv : NeonI_3VSame_SD_sizes<0b1, 0b0, 0b11110, "fmaxp",
    907                                      int_arm_neon_vpmaxs, int_arm_neon_vpmaxs,
    908                                      int_arm_neon_vpmaxs, v2f32, v4f32, v2f64, 1>;
    909 
    910 // Vector Minimum Pairwise (Floating Point)
    911 defm FMINPvvv : NeonI_3VSame_SD_sizes<0b1, 0b1, 0b11110, "fminp",
    912                                      int_arm_neon_vpmins, int_arm_neon_vpmins,
    913                                      int_arm_neon_vpmins, v2f32, v4f32, v2f64, 1>;
    914 
    915 // Vector maxNum Pairwise (Floating Point) -  prefer a number over a quiet NaN)
    916 defm FMAXNMPvvv : NeonI_3VSame_SD_sizes<0b1, 0b0, 0b11000, "fmaxnmp",
    917                                        int_aarch64_neon_vpmaxnm,
    918                                        int_aarch64_neon_vpmaxnm,
    919                                        int_aarch64_neon_vpmaxnm,
    920                                        v2f32, v4f32, v2f64, 1>;
    921 
    922 // Vector minNum Pairwise (Floating Point) -  prefer a number over a quiet NaN)
    923 defm FMINNMPvvv : NeonI_3VSame_SD_sizes<0b1, 0b1, 0b11000, "fminnmp",
    924                                        int_aarch64_neon_vpminnm,
    925                                        int_aarch64_neon_vpminnm,
    926                                        int_aarch64_neon_vpminnm,
    927                                        v2f32, v4f32, v2f64, 1>;
    928 
    929 // Vector Addition Pairwise (Integer)
    930 defm ADDP : NeonI_3VSame_BHSD_sizes<0b0, 0b10111, "addp", int_arm_neon_vpadd, 1>;
    931 
    932 // Vector Addition Pairwise (Floating Point)
    933 defm FADDP : NeonI_3VSame_SD_sizes<0b1, 0b0, 0b11010, "faddp",
    934                                        int_arm_neon_vpadd,
    935                                        int_arm_neon_vpadd,
    936                                        int_arm_neon_vpadd,
    937                                        v2f32, v4f32, v2f64, 1>;
    938 
    939 // Vector Saturating Doubling Multiply High
    940 defm SQDMULHvvv : NeonI_3VSame_HS_sizes<0b0, 0b10110, "sqdmulh",
    941                     int_arm_neon_vqdmulh, 1>;
    942 
    943 // Vector Saturating Rouding Doubling Multiply High
    944 defm SQRDMULHvvv : NeonI_3VSame_HS_sizes<0b1, 0b10110, "sqrdmulh",
    945                      int_arm_neon_vqrdmulh, 1>;
    946 
    947 // Vector Multiply Extended (Floating Point)
    948 defm FMULXvvv : NeonI_3VSame_SD_sizes<0b0, 0b0, 0b11011, "fmulx",
    949                                       int_aarch64_neon_vmulx,
    950                                       int_aarch64_neon_vmulx,
    951                                       int_aarch64_neon_vmulx,
    952                                       v2f32, v4f32, v2f64, 1>;
    953 
    954 // Vector Immediate Instructions
    955 
    956 multiclass neon_mov_imm_shift_asmoperands<string PREFIX>
    957 {
    958   def _asmoperand : AsmOperandClass
    959     {
    960       let Name = "NeonMovImmShift" # PREFIX;
    961       let RenderMethod = "addNeonMovImmShift" # PREFIX # "Operands";
    962       let PredicateMethod = "isNeonMovImmShift" # PREFIX;
    963     }
    964 }
    965 
    966 // Definition of vector immediates shift operands
    967 
    968 // The selectable use-cases extract the shift operation
    969 // information from the OpCmode fields encoded in the immediate.
    970 def neon_mod_shift_imm_XFORM : SDNodeXForm<imm, [{
    971   uint64_t OpCmode = N->getZExtValue();
    972   unsigned ShiftImm;
    973   unsigned ShiftOnesIn;
    974   unsigned HasShift =
    975     A64Imms::decodeNeonModShiftImm(OpCmode, ShiftImm, ShiftOnesIn);
    976   if (!HasShift) return SDValue();
    977   return CurDAG->getTargetConstant(ShiftImm, MVT::i32);
    978 }]>;
    979 
    980 // Vector immediates shift operands which accept LSL and MSL
    981 // shift operators with shift value in the range of 0, 8, 16, 24 (LSL),
    982 // or 0, 8 (LSLH) or 8, 16 (MSL).
    983 defm neon_mov_imm_LSL : neon_mov_imm_shift_asmoperands<"LSL">;
    984 defm neon_mov_imm_MSL : neon_mov_imm_shift_asmoperands<"MSL">;
    985 // LSLH restricts shift amount to  0, 8 out of 0, 8, 16, 24
    986 defm neon_mov_imm_LSLH : neon_mov_imm_shift_asmoperands<"LSLH">;
    987 
    988 multiclass neon_mov_imm_shift_operands<string PREFIX,
    989                                        string HALF, string ISHALF, code pred>
    990 {
    991    def _operand : Operand<i32>, ImmLeaf<i32, pred, neon_mod_shift_imm_XFORM>
    992     {
    993       let PrintMethod =
    994         "printNeonMovImmShiftOperand<A64SE::" # PREFIX # ", " # ISHALF # ">";
    995       let DecoderMethod =
    996         "DecodeNeonMovImmShiftOperand<A64SE::" # PREFIX # ", " # ISHALF # ">";
    997       let ParserMatchClass =
    998         !cast<AsmOperandClass>("neon_mov_imm_" # PREFIX # HALF # "_asmoperand");
    999     }
   1000 }
   1001 
   1002 defm neon_mov_imm_LSL  : neon_mov_imm_shift_operands<"LSL", "", "false", [{
   1003   unsigned ShiftImm;
   1004   unsigned ShiftOnesIn;
   1005   unsigned HasShift =
   1006     A64Imms::decodeNeonModShiftImm(Imm, ShiftImm, ShiftOnesIn);
   1007   return (HasShift && !ShiftOnesIn);
   1008 }]>;
   1009 
   1010 defm neon_mov_imm_MSL  : neon_mov_imm_shift_operands<"MSL", "", "false", [{
   1011   unsigned ShiftImm;
   1012   unsigned ShiftOnesIn;
   1013   unsigned HasShift =
   1014     A64Imms::decodeNeonModShiftImm(Imm, ShiftImm, ShiftOnesIn);
   1015   return (HasShift && ShiftOnesIn);
   1016 }]>;
   1017 
   1018 defm neon_mov_imm_LSLH  : neon_mov_imm_shift_operands<"LSL", "H", "true", [{
   1019   unsigned ShiftImm;
   1020   unsigned ShiftOnesIn;
   1021   unsigned HasShift =
   1022     A64Imms::decodeNeonModShiftImm(Imm, ShiftImm, ShiftOnesIn);
   1023   return (HasShift && !ShiftOnesIn);
   1024 }]>;
   1025 
   1026 def neon_uimm8_asmoperand : AsmOperandClass
   1027 {
   1028   let Name = "UImm8";
   1029   let PredicateMethod = "isUImm<8>";
   1030   let RenderMethod = "addImmOperands";
   1031 }
   1032 
   1033 def neon_uimm8 : Operand<i32>, ImmLeaf<i32, [{(void)Imm; return true;}]> {
   1034   let ParserMatchClass = neon_uimm8_asmoperand;
   1035   let PrintMethod = "printNeonUImm8Operand";
   1036 }
   1037 
   1038 def neon_uimm64_mask_asmoperand : AsmOperandClass
   1039 {
   1040   let Name = "NeonUImm64Mask";
   1041   let PredicateMethod = "isNeonUImm64Mask";
   1042   let RenderMethod = "addNeonUImm64MaskOperands";
   1043 }
   1044 
   1045 // MCOperand for 64-bit bytemask with each byte having only the
   1046 // value 0x00 and 0xff is encoded as an unsigned 8-bit value
   1047 def neon_uimm64_mask : Operand<i32>, ImmLeaf<i32, [{(void)Imm; return true;}]> {
   1048   let ParserMatchClass = neon_uimm64_mask_asmoperand;
   1049   let PrintMethod = "printNeonUImm64MaskOperand";
   1050 }
   1051 
   1052 multiclass NeonI_mov_imm_lsl_sizes<string asmop, bit op,
   1053                                    SDPatternOperator opnode>
   1054 {
   1055     // shift zeros, per word
   1056     def _2S  : NeonI_1VModImm<0b0, op,
   1057                               (outs VPR64:$Rd),
   1058                               (ins neon_uimm8:$Imm,
   1059                                 neon_mov_imm_LSL_operand:$Simm),
   1060                               !strconcat(asmop, " $Rd.2s, $Imm$Simm"),
   1061                               [(set (v2i32 VPR64:$Rd),
   1062                                  (v2i32 (opnode (timm:$Imm),
   1063                                    (neon_mov_imm_LSL_operand:$Simm))))],
   1064                               NoItinerary> {
   1065        bits<2> Simm;
   1066        let cmode = {0b0, Simm{1}, Simm{0}, 0b0};
   1067      }
   1068 
   1069     def _4S  : NeonI_1VModImm<0b1, op,
   1070                               (outs VPR128:$Rd),
   1071                               (ins neon_uimm8:$Imm,
   1072                                 neon_mov_imm_LSL_operand:$Simm),
   1073                               !strconcat(asmop, " $Rd.4s, $Imm$Simm"),
   1074                               [(set (v4i32 VPR128:$Rd),
   1075                                  (v4i32 (opnode (timm:$Imm),
   1076                                    (neon_mov_imm_LSL_operand:$Simm))))],
   1077                               NoItinerary> {
   1078       bits<2> Simm;
   1079       let cmode = {0b0, Simm{1}, Simm{0}, 0b0};
   1080     }
   1081 
   1082     // shift zeros, per halfword
   1083     def _4H  : NeonI_1VModImm<0b0, op,
   1084                               (outs VPR64:$Rd),
   1085                               (ins neon_uimm8:$Imm,
   1086                                 neon_mov_imm_LSLH_operand:$Simm),
   1087                               !strconcat(asmop, " $Rd.4h, $Imm$Simm"),
   1088                               [(set (v4i16 VPR64:$Rd),
   1089                                  (v4i16 (opnode (timm:$Imm),
   1090                                    (neon_mov_imm_LSLH_operand:$Simm))))],
   1091                               NoItinerary> {
   1092       bit  Simm;
   1093       let cmode = {0b1, 0b0, Simm, 0b0};
   1094     }
   1095 
   1096     def _8H  : NeonI_1VModImm<0b1, op,
   1097                               (outs VPR128:$Rd),
   1098                               (ins neon_uimm8:$Imm,
   1099                                 neon_mov_imm_LSLH_operand:$Simm),
   1100                               !strconcat(asmop, " $Rd.8h, $Imm$Simm"),
   1101                               [(set (v8i16 VPR128:$Rd),
   1102                                  (v8i16 (opnode (timm:$Imm),
   1103                                    (neon_mov_imm_LSLH_operand:$Simm))))],
   1104                               NoItinerary> {
   1105       bit Simm;
   1106       let cmode = {0b1, 0b0, Simm, 0b0};
   1107      }
   1108 }
   1109 
   1110 multiclass NeonI_mov_imm_with_constraint_lsl_sizes<string asmop, bit op,
   1111                                                    SDPatternOperator opnode,
   1112                                                    SDPatternOperator neonopnode>
   1113 {
   1114   let Constraints = "$src = $Rd" in {
   1115     // shift zeros, per word
   1116     def _2S  : NeonI_1VModImm<0b0, op,
   1117                  (outs VPR64:$Rd),
   1118                  (ins VPR64:$src, neon_uimm8:$Imm,
   1119                    neon_mov_imm_LSL_operand:$Simm),
   1120                  !strconcat(asmop, " $Rd.2s, $Imm$Simm"),
   1121                  [(set (v2i32 VPR64:$Rd),
   1122                     (v2i32 (opnode (v2i32 VPR64:$src),
   1123                       (v2i32 (bitconvert (v2i32 (neonopnode timm:$Imm,
   1124                         neon_mov_imm_LSL_operand:$Simm)))))))],
   1125                  NoItinerary> {
   1126       bits<2> Simm;
   1127       let cmode = {0b0, Simm{1}, Simm{0}, 0b1};
   1128     }
   1129 
   1130     def _4S  : NeonI_1VModImm<0b1, op,
   1131                  (outs VPR128:$Rd),
   1132                  (ins VPR128:$src, neon_uimm8:$Imm,
   1133                    neon_mov_imm_LSL_operand:$Simm),
   1134                  !strconcat(asmop, " $Rd.4s, $Imm$Simm"),
   1135                  [(set (v4i32 VPR128:$Rd),
   1136                     (v4i32 (opnode (v4i32 VPR128:$src),
   1137                       (v4i32 (bitconvert (v4i32 (neonopnode timm:$Imm,
   1138                         neon_mov_imm_LSL_operand:$Simm)))))))],
   1139                  NoItinerary> {
   1140       bits<2> Simm;
   1141       let cmode = {0b0, Simm{1}, Simm{0}, 0b1};
   1142     }
   1143 
   1144     // shift zeros, per halfword
   1145     def _4H  : NeonI_1VModImm<0b0, op,
   1146                  (outs VPR64:$Rd),
   1147                  (ins VPR64:$src, neon_uimm8:$Imm,
   1148                    neon_mov_imm_LSLH_operand:$Simm),
   1149                  !strconcat(asmop, " $Rd.4h, $Imm$Simm"),
   1150                  [(set (v4i16 VPR64:$Rd),
   1151                     (v4i16 (opnode (v4i16 VPR64:$src),
   1152                        (v4i16 (bitconvert (v4i16 (neonopnode timm:$Imm,
   1153                           neon_mov_imm_LSL_operand:$Simm)))))))],
   1154                  NoItinerary> {
   1155       bit  Simm;
   1156       let cmode = {0b1, 0b0, Simm, 0b1};
   1157     }
   1158 
   1159     def _8H  : NeonI_1VModImm<0b1, op,
   1160                  (outs VPR128:$Rd),
   1161                  (ins VPR128:$src, neon_uimm8:$Imm,
   1162                    neon_mov_imm_LSLH_operand:$Simm),
   1163                  !strconcat(asmop, " $Rd.8h, $Imm$Simm"),
   1164                  [(set (v8i16 VPR128:$Rd),
   1165                     (v8i16 (opnode (v8i16 VPR128:$src),
   1166                       (v8i16 (bitconvert (v8i16 (neonopnode timm:$Imm,
   1167                         neon_mov_imm_LSL_operand:$Simm)))))))],
   1168                  NoItinerary> {
   1169       bit Simm;
   1170       let cmode = {0b1, 0b0, Simm, 0b1};
   1171     }
   1172   }
   1173 }
   1174 
   1175 multiclass NeonI_mov_imm_msl_sizes<string asmop, bit op,
   1176                                    SDPatternOperator opnode>
   1177 {
   1178     // shift ones, per word
   1179     def _2S  : NeonI_1VModImm<0b0, op,
   1180                              (outs VPR64:$Rd),
   1181                              (ins neon_uimm8:$Imm,
   1182                                neon_mov_imm_MSL_operand:$Simm),
   1183                              !strconcat(asmop, " $Rd.2s, $Imm$Simm"),
   1184                               [(set (v2i32 VPR64:$Rd),
   1185                                  (v2i32 (opnode (timm:$Imm),
   1186                                    (neon_mov_imm_MSL_operand:$Simm))))],
   1187                              NoItinerary> {
   1188        bit Simm;
   1189        let cmode = {0b1, 0b1, 0b0, Simm};
   1190      }
   1191 
   1192    def _4S  : NeonI_1VModImm<0b1, op,
   1193                               (outs VPR128:$Rd),
   1194                               (ins neon_uimm8:$Imm,
   1195                                 neon_mov_imm_MSL_operand:$Simm),
   1196                               !strconcat(asmop, " $Rd.4s, $Imm$Simm"),
   1197                               [(set (v4i32 VPR128:$Rd),
   1198                                  (v4i32 (opnode (timm:$Imm),
   1199                                    (neon_mov_imm_MSL_operand:$Simm))))],
   1200                               NoItinerary> {
   1201      bit Simm;
   1202      let cmode = {0b1, 0b1, 0b0, Simm};
   1203    }
   1204 }
   1205 
   1206 // Vector Move Immediate Shifted
   1207 let isReMaterializable = 1 in {
   1208 defm MOVIvi_lsl : NeonI_mov_imm_lsl_sizes<"movi", 0b0, Neon_movi>;
   1209 }
   1210 
   1211 // Vector Move Inverted Immediate Shifted
   1212 let isReMaterializable = 1 in {
   1213 defm MVNIvi_lsl : NeonI_mov_imm_lsl_sizes<"mvni", 0b1, Neon_mvni>;
   1214 }
   1215 
   1216 // Vector Bitwise Bit Clear (AND NOT) - immediate
   1217 let isReMaterializable = 1 in {
   1218 defm BICvi_lsl : NeonI_mov_imm_with_constraint_lsl_sizes<"bic", 0b1,
   1219                                                          and, Neon_mvni>;
   1220 }
   1221 
   1222 // Vector Bitwise OR - immedidate
   1223 
   1224 let isReMaterializable = 1 in {
   1225 defm ORRvi_lsl   : NeonI_mov_imm_with_constraint_lsl_sizes<"orr", 0b0,
   1226                                                            or, Neon_movi>;
   1227 }
   1228 
   1229 // Additional patterns for Vector Bitwise Bit Clear (AND NOT) - immedidate
   1230 // LowerBUILD_VECTOR favors lowering MOVI over MVNI.
   1231 // BIC immediate instructions selection requires additional patterns to
   1232 // transform Neon_movi operands into BIC immediate operands
   1233 
   1234 def neon_mov_imm_LSLH_transform_XFORM : SDNodeXForm<imm, [{
   1235   uint64_t OpCmode = N->getZExtValue();
   1236   unsigned ShiftImm;
   1237   unsigned ShiftOnesIn;
   1238   (void)A64Imms::decodeNeonModShiftImm(OpCmode, ShiftImm, ShiftOnesIn);
   1239   // LSLH restricts shift amount to  0, 8 which are encoded as 0 and 1
   1240   // Transform encoded shift amount 0 to 1 and 1 to 0.
   1241   return CurDAG->getTargetConstant(!ShiftImm, MVT::i32);
   1242 }]>;
   1243 
   1244 def neon_mov_imm_LSLH_transform_operand
   1245   : ImmLeaf<i32, [{
   1246     unsigned ShiftImm;
   1247     unsigned ShiftOnesIn;
   1248     unsigned HasShift =
   1249       A64Imms::decodeNeonModShiftImm(Imm, ShiftImm, ShiftOnesIn);
   1250     return (HasShift && !ShiftOnesIn); }],
   1251   neon_mov_imm_LSLH_transform_XFORM>;
   1252 
   1253 // Transform (and A, (4h Neon_movi 0xff)) -> BIC 4h (A, 0x00, LSL 8)
   1254 // Transform (and A, (4h Neon_movi 0xff LSL #8)) -> BIC 4h (A, 0x00)
   1255 def : Pat<(v4i16 (and VPR64:$src,
   1256             (v4i16 (Neon_movi 255, neon_mov_imm_LSLH_transform_operand:$Simm)))),
   1257           (BICvi_lsl_4H VPR64:$src, 0,
   1258             neon_mov_imm_LSLH_transform_operand:$Simm)>;
   1259 
   1260 // Transform (and A, (8h Neon_movi 8h 0xff)) -> BIC 8h (A, 0x00, LSL 8)
   1261 // Transform (and A, (8h Neon_movi 0xff LSL #8)) -> BIC 8h (A, 0x00)
   1262 def : Pat<(v8i16 (and VPR128:$src,
   1263             (v8i16 (Neon_movi 255, neon_mov_imm_LSLH_transform_operand:$Simm)))),
   1264           (BICvi_lsl_8H VPR128:$src, 0,
   1265             neon_mov_imm_LSLH_transform_operand:$Simm)>;
   1266 
   1267 
   1268 multiclass Neon_bitwiseVi_patterns<SDPatternOperator opnode,
   1269                                    SDPatternOperator neonopnode,
   1270                                    Instruction INST4H,
   1271                                    Instruction INST8H> {
   1272   def : Pat<(v8i8 (opnode VPR64:$src,
   1273                     (bitconvert(v4i16 (neonopnode timm:$Imm,
   1274                       neon_mov_imm_LSLH_operand:$Simm))))),
   1275             (INST4H VPR64:$src, neon_uimm8:$Imm,
   1276               neon_mov_imm_LSLH_operand:$Simm)>;
   1277   def : Pat<(v1i64 (opnode VPR64:$src,
   1278                   (bitconvert(v4i16 (neonopnode timm:$Imm,
   1279                     neon_mov_imm_LSLH_operand:$Simm))))),
   1280           (INST4H VPR64:$src, neon_uimm8:$Imm,
   1281             neon_mov_imm_LSLH_operand:$Simm)>;
   1282 
   1283   def : Pat<(v16i8 (opnode VPR128:$src,
   1284                    (bitconvert(v8i16 (neonopnode timm:$Imm,
   1285                      neon_mov_imm_LSLH_operand:$Simm))))),
   1286           (INST8H VPR128:$src, neon_uimm8:$Imm,
   1287             neon_mov_imm_LSLH_operand:$Simm)>;
   1288   def : Pat<(v4i32 (opnode VPR128:$src,
   1289                    (bitconvert(v8i16 (neonopnode timm:$Imm,
   1290                      neon_mov_imm_LSLH_operand:$Simm))))),
   1291           (INST8H VPR128:$src, neon_uimm8:$Imm,
   1292             neon_mov_imm_LSLH_operand:$Simm)>;
   1293   def : Pat<(v2i64 (opnode VPR128:$src,
   1294                    (bitconvert(v8i16 (neonopnode timm:$Imm,
   1295                      neon_mov_imm_LSLH_operand:$Simm))))),
   1296           (INST8H VPR128:$src, neon_uimm8:$Imm,
   1297             neon_mov_imm_LSLH_operand:$Simm)>;
   1298 }
   1299 
   1300 // Additional patterns for Vector Vector Bitwise Bit Clear (AND NOT) - immediate
   1301 defm : Neon_bitwiseVi_patterns<or, Neon_mvni, BICvi_lsl_4H, BICvi_lsl_8H>;
   1302 
   1303 // Additional patterns for Vector Bitwise OR - immedidate
   1304 defm : Neon_bitwiseVi_patterns<or, Neon_movi, ORRvi_lsl_4H, ORRvi_lsl_8H>;
   1305 
   1306 
   1307 // Vector Move Immediate Masked
   1308 let isReMaterializable = 1 in {
   1309 defm MOVIvi_msl : NeonI_mov_imm_msl_sizes<"movi", 0b0, Neon_movi>;
   1310 }
   1311 
   1312 // Vector Move Inverted Immediate Masked
   1313 let isReMaterializable = 1 in {
   1314 defm MVNIvi_msl : NeonI_mov_imm_msl_sizes<"mvni", 0b1, Neon_mvni>;
   1315 }
   1316 
   1317 class NeonI_mov_imm_lsl_aliases<string asmop, string asmlane,
   1318                                 Instruction inst, RegisterClass VPRC>
   1319   : NeonInstAlias<!strconcat(asmop, " $Rd," # asmlane # ", $Imm"),
   1320                         (inst VPRC:$Rd, neon_uimm8:$Imm,  0), 0b0>;
   1321 
   1322 // Aliases for Vector Move Immediate Shifted
   1323 def : NeonI_mov_imm_lsl_aliases<"movi", ".2s", MOVIvi_lsl_2S, VPR64>;
   1324 def : NeonI_mov_imm_lsl_aliases<"movi", ".4s", MOVIvi_lsl_4S, VPR128>;
   1325 def : NeonI_mov_imm_lsl_aliases<"movi", ".4h", MOVIvi_lsl_4H, VPR64>;
   1326 def : NeonI_mov_imm_lsl_aliases<"movi", ".8h", MOVIvi_lsl_8H, VPR128>;
   1327 
   1328 // Aliases for Vector Move Inverted Immediate Shifted
   1329 def : NeonI_mov_imm_lsl_aliases<"mvni", ".2s", MVNIvi_lsl_2S, VPR64>;
   1330 def : NeonI_mov_imm_lsl_aliases<"mvni", ".4s", MVNIvi_lsl_4S, VPR128>;
   1331 def : NeonI_mov_imm_lsl_aliases<"mvni", ".4h", MVNIvi_lsl_4H, VPR64>;
   1332 def : NeonI_mov_imm_lsl_aliases<"mvni", ".8h", MVNIvi_lsl_8H, VPR128>;
   1333 
   1334 // Aliases for Vector Bitwise Bit Clear (AND NOT) - immediate
   1335 def : NeonI_mov_imm_lsl_aliases<"bic", ".2s", BICvi_lsl_2S, VPR64>;
   1336 def : NeonI_mov_imm_lsl_aliases<"bic", ".4s", BICvi_lsl_4S, VPR128>;
   1337 def : NeonI_mov_imm_lsl_aliases<"bic", ".4h", BICvi_lsl_4H, VPR64>;
   1338 def : NeonI_mov_imm_lsl_aliases<"bic", ".8h", BICvi_lsl_8H, VPR128>;
   1339 
   1340 // Aliases for Vector Bitwise OR - immedidate
   1341 def : NeonI_mov_imm_lsl_aliases<"orr", ".2s", ORRvi_lsl_2S, VPR64>;
   1342 def : NeonI_mov_imm_lsl_aliases<"orr", ".4s", ORRvi_lsl_4S, VPR128>;
   1343 def : NeonI_mov_imm_lsl_aliases<"orr", ".4h", ORRvi_lsl_4H, VPR64>;
   1344 def : NeonI_mov_imm_lsl_aliases<"orr", ".8h", ORRvi_lsl_8H, VPR128>;
   1345 
   1346 //  Vector Move Immediate - per byte
   1347 let isReMaterializable = 1 in {
   1348 def MOVIvi_8B : NeonI_1VModImm<0b0, 0b0,
   1349                                (outs VPR64:$Rd), (ins neon_uimm8:$Imm),
   1350                                "movi\t$Rd.8b, $Imm",
   1351                                [(set (v8i8 VPR64:$Rd),
   1352                                   (v8i8 (Neon_movi (timm:$Imm), (i32 imm))))],
   1353                                 NoItinerary> {
   1354   let cmode = 0b1110;
   1355 }
   1356 
   1357 def MOVIvi_16B : NeonI_1VModImm<0b1, 0b0,
   1358                                 (outs VPR128:$Rd), (ins neon_uimm8:$Imm),
   1359                                 "movi\t$Rd.16b, $Imm",
   1360                                 [(set (v16i8 VPR128:$Rd),
   1361                                    (v16i8 (Neon_movi (timm:$Imm), (i32 imm))))],
   1362                                  NoItinerary> {
   1363   let cmode = 0b1110;
   1364 }
   1365 }
   1366 
   1367 // Vector Move Immediate - bytemask, per double word
   1368 let isReMaterializable = 1 in {
   1369 def MOVIvi_2D : NeonI_1VModImm<0b1, 0b1,
   1370                                (outs VPR128:$Rd), (ins neon_uimm64_mask:$Imm),
   1371                                "movi\t $Rd.2d, $Imm",
   1372                                [(set (v2i64 VPR128:$Rd),
   1373                                   (v2i64 (Neon_movi (timm:$Imm), (i32 imm))))],
   1374                                NoItinerary> {
   1375   let cmode = 0b1110;
   1376 }
   1377 }
   1378 
   1379 // Vector Move Immediate - bytemask, one doubleword
   1380 
   1381 let isReMaterializable = 1 in {
   1382 def MOVIdi : NeonI_1VModImm<0b0, 0b1,
   1383                            (outs FPR64:$Rd), (ins neon_uimm64_mask:$Imm),
   1384                            "movi\t $Rd, $Imm",
   1385                            [(set (f64 FPR64:$Rd),
   1386                               (f64 (bitconvert
   1387                                 (v1i64 (Neon_movi (timm:$Imm), (i32 imm))))))],
   1388                            NoItinerary> {
   1389   let cmode = 0b1110;
   1390 }
   1391 }
   1392 
   1393 // Vector Floating Point Move Immediate
   1394 
   1395 class NeonI_FMOV_impl<string asmlane, RegisterClass VPRC, ValueType OpTy,
   1396                       Operand immOpType, bit q, bit op>
   1397   : NeonI_1VModImm<q, op,
   1398                    (outs VPRC:$Rd), (ins immOpType:$Imm),
   1399                    "fmov\t$Rd" # asmlane # ", $Imm",
   1400                    [(set (OpTy VPRC:$Rd),
   1401                       (OpTy (Neon_fmovi (timm:$Imm))))],
   1402                    NoItinerary> {
   1403      let cmode = 0b1111;
   1404    }
   1405 
   1406 let isReMaterializable = 1 in {
   1407 def FMOVvi_2S : NeonI_FMOV_impl<".2s", VPR64,  v2f32, fmov32_operand, 0b0, 0b0>;
   1408 def FMOVvi_4S : NeonI_FMOV_impl<".4s", VPR128, v4f32, fmov32_operand, 0b1, 0b0>;
   1409 def FMOVvi_2D : NeonI_FMOV_impl<".2d", VPR128, v2f64, fmov64_operand, 0b1, 0b1>;
   1410 }
   1411 
   1412 // Scalar Arithmetic
   1413 
   1414 class NeonI_Scalar3Same_D_size<bit u, bits<5> opcode, string asmop>
   1415   : NeonI_Scalar3Same<u, 0b11, opcode,
   1416                 (outs FPR64:$Rd), (ins FPR64:$Rn, FPR64:$Rm),
   1417                 !strconcat(asmop, " $Rd, $Rn, $Rm"),
   1418                 [],
   1419                 NoItinerary>;
   1420 
   1421 multiclass NeonI_Scalar3Same_BHSD_sizes<bit u, bits<5> opcode,
   1422                                         string asmop, bit Commutable = 0>
   1423 {
   1424   let isCommutable = Commutable in {
   1425     def bbb : NeonI_Scalar3Same<u, 0b00, opcode,
   1426                                 (outs FPR8:$Rd), (ins FPR8:$Rn, FPR8:$Rm),
   1427                                 !strconcat(asmop, " $Rd, $Rn, $Rm"),
   1428                                 [],
   1429                                 NoItinerary>;
   1430     def hhh : NeonI_Scalar3Same<u, 0b01, opcode,
   1431                                 (outs FPR16:$Rd), (ins FPR16:$Rn, FPR16:$Rm),
   1432                                 !strconcat(asmop, " $Rd, $Rn, $Rm"),
   1433                                 [],
   1434                                 NoItinerary>;
   1435     def sss : NeonI_Scalar3Same<u, 0b10, opcode,
   1436                                 (outs FPR32:$Rd), (ins FPR32:$Rn, FPR32:$Rm),
   1437                                 !strconcat(asmop, " $Rd, $Rn, $Rm"),
   1438                                 [],
   1439                                 NoItinerary>;
   1440     def ddd : NeonI_Scalar3Same<u, 0b11, opcode,
   1441                                (outs FPR64:$Rd), (ins FPR64:$Rn, FPR64:$Rm),
   1442                                !strconcat(asmop, " $Rd, $Rn, $Rm"),
   1443                                [],
   1444                                NoItinerary>;
   1445   }
   1446 }
   1447 
   1448 class Neon_Scalar_D_size_patterns<SDPatternOperator opnode, Instruction INSTD>
   1449   : Pat<(v1i64 (opnode (v1i64 VPR64:$Rn), (v1i64 VPR64:$Rm))),
   1450         (SUBREG_TO_REG (i64 0),
   1451               (INSTD (EXTRACT_SUBREG VPR64:$Rn, sub_64),
   1452              (EXTRACT_SUBREG VPR64:$Rm, sub_64)),
   1453           sub_64)>;
   1454 
   1455 
   1456 // Scalar Integer Add
   1457 let isCommutable = 1 in {
   1458 def ADDddd : NeonI_Scalar3Same_D_size<0b0, 0b10000, "add">;
   1459 }
   1460 
   1461 // Scalar Integer Sub
   1462 def SUBddd : NeonI_Scalar3Same_D_size<0b1, 0b10000, "sub">;
   1463 
   1464 // Pattern for Scalar Integer Add and Sub with D register
   1465 def : Neon_Scalar_D_size_patterns<add, ADDddd>;
   1466 def : Neon_Scalar_D_size_patterns<sub, SUBddd>;
   1467 
   1468 // Scalar Integer Saturating Add (Signed, Unsigned)
   1469 defm SQADD : NeonI_Scalar3Same_BHSD_sizes<0b0, 0b00001, "sqadd", 1>;
   1470 defm UQADD : NeonI_Scalar3Same_BHSD_sizes<0b1, 0b00001, "uqadd", 1>;
   1471 
   1472 // Scalar Integer Saturating Sub (Signed, Unsigned)
   1473 defm SQSUB : NeonI_Scalar3Same_BHSD_sizes<0b0, 0b00101, "sqsub", 0>;
   1474 defm UQSUB : NeonI_Scalar3Same_BHSD_sizes<0b1, 0b00101, "uqsub", 0>;
   1475 
   1476 // Patterns for Scalar Integer Saturating Add, Sub with D register only
   1477 def : Neon_Scalar_D_size_patterns<int_arm_neon_vqadds, SQADDddd>;
   1478 def : Neon_Scalar_D_size_patterns<int_arm_neon_vqaddu, UQADDddd>;
   1479 def : Neon_Scalar_D_size_patterns<int_arm_neon_vqsubs, SQSUBddd>;
   1480 def : Neon_Scalar_D_size_patterns<int_arm_neon_vqsubu, UQSUBddd>;
   1481 
   1482 // Scalar Integer Shift Left (Signed, Unsigned)
   1483 def SSHLddd : NeonI_Scalar3Same_D_size<0b0, 0b01000, "sshl">;
   1484 def USHLddd : NeonI_Scalar3Same_D_size<0b1, 0b01000, "ushl">;
   1485 
   1486 // Scalar Integer Saturating Shift Left (Signed, Unsigned)
   1487 defm SQSHL: NeonI_Scalar3Same_BHSD_sizes<0b0, 0b01001, "sqshl", 0>;
   1488 defm UQSHL: NeonI_Scalar3Same_BHSD_sizes<0b1, 0b01001, "uqshl", 0>;
   1489 
   1490 // Scalar Integer Rouding Shift Left (Signed, Unsigned)
   1491 def SRSHLddd: NeonI_Scalar3Same_D_size<0b0, 0b01010, "srshl">;
   1492 def URSHLddd: NeonI_Scalar3Same_D_size<0b1, 0b01010, "urshl">;
   1493 
   1494 // Scalar Integer Saturating Rounding Shift Left (Signed, Unsigned)
   1495 defm SQRSHL: NeonI_Scalar3Same_BHSD_sizes<0b0, 0b01011, "sqrshl", 0>;
   1496 defm UQRSHL: NeonI_Scalar3Same_BHSD_sizes<0b1, 0b01011, "uqrshl", 0>;
   1497 
   1498 // Patterns for Scalar Integer Shift Lef, Saturating Shift Left,
   1499 // Rounding Shift Left, Rounding Saturating Shift Left with D register only
   1500 def : Neon_Scalar_D_size_patterns<int_arm_neon_vshifts, SSHLddd>;
   1501 def : Neon_Scalar_D_size_patterns<int_arm_neon_vshiftu, USHLddd>;
   1502 def : Neon_Scalar_D_size_patterns<shl, SSHLddd>;
   1503 def : Neon_Scalar_D_size_patterns<shl, USHLddd>;
   1504 def : Neon_Scalar_D_size_patterns<int_arm_neon_vqshifts, SQSHLddd>;
   1505 def : Neon_Scalar_D_size_patterns<int_arm_neon_vqshiftu, UQSHLddd>;
   1506 def : Neon_Scalar_D_size_patterns<int_arm_neon_vrshifts, SRSHLddd>;
   1507 def : Neon_Scalar_D_size_patterns<int_arm_neon_vrshiftu, URSHLddd>;
   1508 def : Neon_Scalar_D_size_patterns<int_arm_neon_vqrshifts, SQRSHLddd>;
   1509 def : Neon_Scalar_D_size_patterns<int_arm_neon_vqrshiftu, UQRSHLddd>;
   1510 
   1511 
   1512 //===----------------------------------------------------------------------===//
   1513 // Non-Instruction Patterns
   1514 //===----------------------------------------------------------------------===//
   1515 
   1516 // 64-bit vector bitcasts...
   1517 
   1518 def : Pat<(v1i64 (bitconvert (v8i8  VPR64:$src))), (v1i64 VPR64:$src)>;
   1519 def : Pat<(v2f32 (bitconvert (v8i8  VPR64:$src))), (v2f32 VPR64:$src)>;
   1520 def : Pat<(v2i32 (bitconvert (v8i8  VPR64:$src))), (v2i32 VPR64:$src)>;
   1521 def : Pat<(v4i16 (bitconvert (v8i8  VPR64:$src))), (v4i16 VPR64:$src)>;
   1522 
   1523 def : Pat<(v1i64 (bitconvert (v4i16  VPR64:$src))), (v1i64 VPR64:$src)>;
   1524 def : Pat<(v2i32 (bitconvert (v4i16  VPR64:$src))), (v2i32 VPR64:$src)>;
   1525 def : Pat<(v2f32 (bitconvert (v4i16  VPR64:$src))), (v2f32 VPR64:$src)>;
   1526 def : Pat<(v8i8  (bitconvert (v4i16  VPR64:$src))), (v8i8 VPR64:$src)>;
   1527 
   1528 def : Pat<(v1i64 (bitconvert (v2i32  VPR64:$src))), (v1i64 VPR64:$src)>;
   1529 def : Pat<(v2f32 (bitconvert (v2i32  VPR64:$src))), (v2f32 VPR64:$src)>;
   1530 def : Pat<(v4i16 (bitconvert (v2i32  VPR64:$src))), (v4i16 VPR64:$src)>;
   1531 def : Pat<(v8i8  (bitconvert (v2i32  VPR64:$src))), (v8i8 VPR64:$src)>;
   1532 
   1533 def : Pat<(v1i64 (bitconvert (v2f32  VPR64:$src))), (v1i64 VPR64:$src)>;
   1534 def : Pat<(v2i32 (bitconvert (v2f32  VPR64:$src))), (v2i32 VPR64:$src)>;
   1535 def : Pat<(v4i16 (bitconvert (v2f32  VPR64:$src))), (v4i16 VPR64:$src)>;
   1536 def : Pat<(v8i8  (bitconvert (v2f32  VPR64:$src))), (v8i8 VPR64:$src)>;
   1537 
   1538 def : Pat<(v2f32 (bitconvert (v1i64  VPR64:$src))), (v2f32 VPR64:$src)>;
   1539 def : Pat<(v2i32 (bitconvert (v1i64  VPR64:$src))), (v2i32 VPR64:$src)>;
   1540 def : Pat<(v4i16 (bitconvert (v1i64  VPR64:$src))), (v4i16 VPR64:$src)>;
   1541 def : Pat<(v8i8  (bitconvert (v1i64  VPR64:$src))), (v8i8 VPR64:$src)>;
   1542 
   1543 // ..and 128-bit vector bitcasts...
   1544 
   1545 def : Pat<(v2f64 (bitconvert (v16i8  VPR128:$src))), (v2f64 VPR128:$src)>;
   1546 def : Pat<(v2i64 (bitconvert (v16i8  VPR128:$src))), (v2i64 VPR128:$src)>;
   1547 def : Pat<(v4f32 (bitconvert (v16i8  VPR128:$src))), (v4f32 VPR128:$src)>;
   1548 def : Pat<(v4i32 (bitconvert (v16i8  VPR128:$src))), (v4i32 VPR128:$src)>;
   1549 def : Pat<(v8i16 (bitconvert (v16i8  VPR128:$src))), (v8i16 VPR128:$src)>;
   1550 
   1551 def : Pat<(v2f64 (bitconvert (v8i16  VPR128:$src))), (v2f64 VPR128:$src)>;
   1552 def : Pat<(v2i64 (bitconvert (v8i16  VPR128:$src))), (v2i64 VPR128:$src)>;
   1553 def : Pat<(v4i32 (bitconvert (v8i16  VPR128:$src))), (v4i32 VPR128:$src)>;
   1554 def : Pat<(v4f32 (bitconvert (v8i16  VPR128:$src))), (v4f32 VPR128:$src)>;
   1555 def : Pat<(v16i8 (bitconvert (v8i16  VPR128:$src))), (v16i8 VPR128:$src)>;
   1556 
   1557 def : Pat<(v2f64 (bitconvert (v4i32  VPR128:$src))), (v2f64 VPR128:$src)>;
   1558 def : Pat<(v2i64 (bitconvert (v4i32  VPR128:$src))), (v2i64 VPR128:$src)>;
   1559 def : Pat<(v4f32 (bitconvert (v4i32  VPR128:$src))), (v4f32 VPR128:$src)>;
   1560 def : Pat<(v8i16 (bitconvert (v4i32  VPR128:$src))), (v8i16 VPR128:$src)>;
   1561 def : Pat<(v16i8 (bitconvert (v4i32  VPR128:$src))), (v16i8 VPR128:$src)>;
   1562 
   1563 def : Pat<(v2f64 (bitconvert (v4f32  VPR128:$src))), (v2f64 VPR128:$src)>;
   1564 def : Pat<(v2i64 (bitconvert (v4f32  VPR128:$src))), (v2i64 VPR128:$src)>;
   1565 def : Pat<(v4i32 (bitconvert (v4f32  VPR128:$src))), (v4i32 VPR128:$src)>;
   1566 def : Pat<(v8i16 (bitconvert (v4f32  VPR128:$src))), (v8i16 VPR128:$src)>;
   1567 def : Pat<(v16i8 (bitconvert (v4f32  VPR128:$src))), (v16i8 VPR128:$src)>;
   1568 
   1569 def : Pat<(v2f64 (bitconvert (v2i64  VPR128:$src))), (v2f64 VPR128:$src)>;
   1570 def : Pat<(v4f32 (bitconvert (v2i64  VPR128:$src))), (v4f32 VPR128:$src)>;
   1571 def : Pat<(v4i32 (bitconvert (v2i64  VPR128:$src))), (v4i32 VPR128:$src)>;
   1572 def : Pat<(v8i16 (bitconvert (v2i64  VPR128:$src))), (v8i16 VPR128:$src)>;
   1573 def : Pat<(v16i8 (bitconvert (v2i64  VPR128:$src))), (v16i8 VPR128:$src)>;
   1574 
   1575 def : Pat<(v2i64 (bitconvert (v2f64  VPR128:$src))), (v2i64 VPR128:$src)>;
   1576 def : Pat<(v4f32 (bitconvert (v2f64  VPR128:$src))), (v4f32 VPR128:$src)>;
   1577 def : Pat<(v4i32 (bitconvert (v2f64  VPR128:$src))), (v4i32 VPR128:$src)>;
   1578 def : Pat<(v8i16 (bitconvert (v2f64  VPR128:$src))), (v8i16 VPR128:$src)>;
   1579 def : Pat<(v16i8 (bitconvert (v2f64  VPR128:$src))), (v16i8 VPR128:$src)>;
   1580 
   1581 
   1582 // ...and scalar bitcasts...
   1583 
   1584 def : Pat<(f64   (bitconvert (v8i8  VPR64:$src))),
   1585                  (f64 (EXTRACT_SUBREG (v8i8  VPR64:$src), sub_64))>;
   1586 def : Pat<(f64   (bitconvert (v4i16  VPR64:$src))),
   1587                  (f64 (EXTRACT_SUBREG (v4i16  VPR64:$src), sub_64))>;
   1588 def : Pat<(f64   (bitconvert (v2i32  VPR64:$src))),
   1589                  (f64 (EXTRACT_SUBREG (v2i32  VPR64:$src), sub_64))>;
   1590 def : Pat<(f64   (bitconvert (v2f32  VPR64:$src))),
   1591                  (f64 (EXTRACT_SUBREG (v2f32  VPR64:$src), sub_64))>;
   1592 def : Pat<(f64   (bitconvert (v1i64  VPR64:$src))),
   1593                  (f64 (EXTRACT_SUBREG (v1i64  VPR64:$src), sub_64))>;
   1594 def : Pat<(f128  (bitconvert (v16i8  VPR128:$src))),
   1595                  (f128 (EXTRACT_SUBREG (v16i8  VPR128:$src), sub_alias))>;
   1596 def : Pat<(f128  (bitconvert (v8i16  VPR128:$src))),
   1597                  (f128 (EXTRACT_SUBREG (v8i16  VPR128:$src), sub_alias))>;
   1598 def : Pat<(f128  (bitconvert (v4i32  VPR128:$src))),
   1599                  (f128 (EXTRACT_SUBREG (v4i32  VPR128:$src), sub_alias))>;
   1600 def : Pat<(f128  (bitconvert (v2i64  VPR128:$src))),
   1601                  (f128 (EXTRACT_SUBREG (v2i64  VPR128:$src), sub_alias))>;
   1602 def : Pat<(f128  (bitconvert (v4f32  VPR128:$src))),
   1603                  (f128 (EXTRACT_SUBREG (v4f32  VPR128:$src), sub_alias))>;
   1604 def : Pat<(f128  (bitconvert (v2f64  VPR128:$src))),
   1605                  (f128 (EXTRACT_SUBREG (v2f64  VPR128:$src), sub_alias))>;
   1606 
   1607 def : Pat<(v8i8   (bitconvert (f64   FPR64:$src))),
   1608                   (v8i8 (SUBREG_TO_REG (i64 0), (f64  FPR64:$src), sub_64))>;
   1609 def : Pat<(v4i16  (bitconvert (f64   FPR64:$src))),
   1610                   (v4i16 (SUBREG_TO_REG (i64 0), (f64  FPR64:$src), sub_64))>;
   1611 def : Pat<(v2i32  (bitconvert (f64   FPR64:$src))),
   1612                   (v2i32 (SUBREG_TO_REG (i64 0), (f64  FPR64:$src), sub_64))>;
   1613 def : Pat<(v2f32  (bitconvert (f64   FPR64:$src))),
   1614                   (v2f32 (SUBREG_TO_REG (i64 0), (f64  FPR64:$src), sub_64))>;
   1615 def : Pat<(v1i64  (bitconvert (f64   FPR64:$src))),
   1616                   (v1i64 (SUBREG_TO_REG (i64 0), (f64  FPR64:$src), sub_64))>;
   1617 def : Pat<(v16i8  (bitconvert (f128   FPR128:$src))),
   1618                   (v16i8 (SUBREG_TO_REG (i128 0), (f128  FPR128:$src),
   1619                   sub_alias))>;
   1620 def : Pat<(v8i16  (bitconvert (f128   FPR128:$src))),
   1621                   (v8i16 (SUBREG_TO_REG (i128 0), (f128  FPR128:$src),
   1622                   sub_alias))>;
   1623 def : Pat<(v4i32  (bitconvert (f128   FPR128:$src))),
   1624                   (v4i32 (SUBREG_TO_REG (i128 0), (f128  FPR128:$src),
   1625                   sub_alias))>;
   1626 def : Pat<(v2i64  (bitconvert (f128   FPR128:$src))),
   1627                   (v2i64 (SUBREG_TO_REG (i128 0), (f128  FPR128:$src),
   1628                   sub_alias))>;
   1629 def : Pat<(v4f32  (bitconvert (f128   FPR128:$src))),
   1630                   (v4f32 (SUBREG_TO_REG (i128 0), (f128  FPR128:$src),
   1631                   sub_alias))>;
   1632 def : Pat<(v2f64  (bitconvert (f128   FPR128:$src))),
   1633                   (v2f64 (SUBREG_TO_REG (i128 0), (f128  FPR128:$src),
   1634                   sub_alias))>;
   1635