Home | History | Annotate | Download | only in AArch64
      1 //===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tblgen -*-===//
      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 //===----------------------------------------------------------------------===//
     11 //  Describe AArch64 instructions format here
     12 //
     13 
     14 // Format specifies the encoding used by the instruction.  This is part of the
     15 // ad-hoc solution used to emit machine instruction encodings by our machine
     16 // code emitter.
     17 class Format<bits<2> val> {
     18   bits<2> Value = val;
     19 }
     20 
     21 def PseudoFrm   : Format<0>;
     22 def NormalFrm   : Format<1>; // Do we need any others?
     23 
     24 // AArch64 Instruction Format
     25 class AArch64Inst<Format f, string cstr> : Instruction {
     26   field bits<32> Inst; // Instruction encoding.
     27   // Mask of bits that cause an encoding to be UNPREDICTABLE.
     28   // If a bit is set, then if the corresponding bit in the
     29   // target encoding differs from its value in the "Inst" field,
     30   // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
     31   field bits<32> Unpredictable = 0;
     32   // SoftFail is the generic name for this field, but we alias it so
     33   // as to make it more obvious what it means in ARM-land.
     34   field bits<32> SoftFail = Unpredictable;
     35   let Namespace   = "AArch64";
     36   Format F        = f;
     37   bits<2> Form    = F.Value;
     38   let Pattern     = [];
     39   let Constraints = cstr;
     40 }
     41 
     42 // Pseudo instructions (don't have encoding information)
     43 class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = "">
     44     : AArch64Inst<PseudoFrm, cstr> {
     45   dag OutOperandList = oops;
     46   dag InOperandList  = iops;
     47   let Pattern        = pattern;
     48   let isCodeGenOnly  = 1;
     49 }
     50 
     51 // Real instructions (have encoding information)
     52 class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> {
     53   let Pattern = pattern;
     54   let Size = 4;
     55 }
     56 
     57 // Normal instructions
     58 class I<dag oops, dag iops, string asm, string operands, string cstr,
     59         list<dag> pattern>
     60     : EncodedI<cstr, pattern> {
     61   dag OutOperandList = oops;
     62   dag InOperandList  = iops;
     63   let AsmString      = !strconcat(asm, operands);
     64 }
     65 
     66 class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>;
     67 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
     68 class UnOpFrag<dag res>  : PatFrag<(ops node:$LHS), res>;
     69 
     70 // Helper fragment for an extract of the high portion of a 128-bit vector.
     71 def extract_high_v16i8 :
     72    UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>;
     73 def extract_high_v8i16 :
     74    UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>;
     75 def extract_high_v4i32 :
     76    UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>;
     77 def extract_high_v2i64 :
     78    UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>;
     79 
     80 //===----------------------------------------------------------------------===//
     81 // Asm Operand Classes.
     82 //
     83 
     84 // Shifter operand for arithmetic shifted encodings.
     85 def ShifterOperand : AsmOperandClass {
     86   let Name = "Shifter";
     87 }
     88 
     89 // Shifter operand for mov immediate encodings.
     90 def MovImm32ShifterOperand : AsmOperandClass {
     91   let SuperClasses = [ShifterOperand];
     92   let Name = "MovImm32Shifter";
     93   let RenderMethod = "addShifterOperands";
     94   let DiagnosticType = "InvalidMovImm32Shift";
     95 }
     96 def MovImm64ShifterOperand : AsmOperandClass {
     97   let SuperClasses = [ShifterOperand];
     98   let Name = "MovImm64Shifter";
     99   let RenderMethod = "addShifterOperands";
    100   let DiagnosticType = "InvalidMovImm64Shift";
    101 }
    102 
    103 // Shifter operand for arithmetic register shifted encodings.
    104 class ArithmeticShifterOperand<int width> : AsmOperandClass {
    105   let SuperClasses = [ShifterOperand];
    106   let Name = "ArithmeticShifter" # width;
    107   let PredicateMethod = "isArithmeticShifter<" # width # ">";
    108   let RenderMethod = "addShifterOperands";
    109   let DiagnosticType = "AddSubRegShift" # width;
    110 }
    111 
    112 def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
    113 def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
    114 
    115 // Shifter operand for logical register shifted encodings.
    116 class LogicalShifterOperand<int width> : AsmOperandClass {
    117   let SuperClasses = [ShifterOperand];
    118   let Name = "LogicalShifter" # width;
    119   let PredicateMethod = "isLogicalShifter<" # width # ">";
    120   let RenderMethod = "addShifterOperands";
    121   let DiagnosticType = "AddSubRegShift" # width;
    122 }
    123 
    124 def LogicalShifterOperand32 : LogicalShifterOperand<32>;
    125 def LogicalShifterOperand64 : LogicalShifterOperand<64>;
    126 
    127 // Shifter operand for logical vector 128/64-bit shifted encodings.
    128 def LogicalVecShifterOperand : AsmOperandClass {
    129   let SuperClasses = [ShifterOperand];
    130   let Name = "LogicalVecShifter";
    131   let RenderMethod = "addShifterOperands";
    132 }
    133 def LogicalVecHalfWordShifterOperand : AsmOperandClass {
    134   let SuperClasses = [LogicalVecShifterOperand];
    135   let Name = "LogicalVecHalfWordShifter";
    136   let RenderMethod = "addShifterOperands";
    137 }
    138 
    139 // The "MSL" shifter on the vector MOVI instruction.
    140 def MoveVecShifterOperand : AsmOperandClass {
    141   let SuperClasses = [ShifterOperand];
    142   let Name = "MoveVecShifter";
    143   let RenderMethod = "addShifterOperands";
    144 }
    145 
    146 // Extend operand for arithmetic encodings.
    147 def ExtendOperand : AsmOperandClass {
    148   let Name = "Extend";
    149   let DiagnosticType = "AddSubRegExtendLarge";
    150 }
    151 def ExtendOperand64 : AsmOperandClass {
    152   let SuperClasses = [ExtendOperand];
    153   let Name = "Extend64";
    154   let DiagnosticType = "AddSubRegExtendSmall";
    155 }
    156 // 'extend' that's a lsl of a 64-bit register.
    157 def ExtendOperandLSL64 : AsmOperandClass {
    158   let SuperClasses = [ExtendOperand];
    159   let Name = "ExtendLSL64";
    160   let RenderMethod = "addExtend64Operands";
    161   let DiagnosticType = "AddSubRegExtendLarge";
    162 }
    163 
    164 // 8-bit floating-point immediate encodings.
    165 def FPImmOperand : AsmOperandClass {
    166   let Name = "FPImm";
    167   let ParserMethod = "tryParseFPImm";
    168   let DiagnosticType = "InvalidFPImm";
    169 }
    170 
    171 def CondCode : AsmOperandClass {
    172   let Name = "CondCode";
    173   let DiagnosticType = "InvalidCondCode";
    174 }
    175 
    176 // A 32-bit register pasrsed as 64-bit
    177 def GPR32as64Operand : AsmOperandClass {
    178   let Name = "GPR32as64";
    179 }
    180 def GPR32as64 : RegisterOperand<GPR32> {
    181   let ParserMatchClass = GPR32as64Operand;
    182 }
    183 
    184 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
    185 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
    186 // are encoded as the eight bit value 'abcdefgh'.
    187 def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
    188 
    189 
    190 //===----------------------------------------------------------------------===//
    191 // Operand Definitions.
    192 //
    193 
    194 // ADR[P] instruction labels.
    195 def AdrpOperand : AsmOperandClass {
    196   let Name = "AdrpLabel";
    197   let ParserMethod = "tryParseAdrpLabel";
    198   let DiagnosticType = "InvalidLabel";
    199 }
    200 def adrplabel : Operand<i64> {
    201   let EncoderMethod = "getAdrLabelOpValue";
    202   let PrintMethod = "printAdrpLabel";
    203   let ParserMatchClass = AdrpOperand;
    204 }
    205 
    206 def AdrOperand : AsmOperandClass {
    207   let Name = "AdrLabel";
    208   let ParserMethod = "tryParseAdrLabel";
    209   let DiagnosticType = "InvalidLabel";
    210 }
    211 def adrlabel : Operand<i64> {
    212   let EncoderMethod = "getAdrLabelOpValue";
    213   let ParserMatchClass = AdrOperand;
    214 }
    215 
    216 // simm9 predicate - True if the immediate is in the range [-256, 255].
    217 def SImm9Operand : AsmOperandClass {
    218   let Name = "SImm9";
    219   let DiagnosticType = "InvalidMemoryIndexedSImm9";
    220 }
    221 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
    222   let ParserMatchClass = SImm9Operand;
    223 }
    224 
    225 // simm7sN predicate - True if the immediate is a multiple of N in the range
    226 // [-64 * N, 63 * N].
    227 class SImm7Scaled<int Scale> : AsmOperandClass {
    228   let Name = "SImm7s" # Scale;
    229   let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm7";
    230 }
    231 
    232 def SImm7s4Operand : SImm7Scaled<4>;
    233 def SImm7s8Operand : SImm7Scaled<8>;
    234 def SImm7s16Operand : SImm7Scaled<16>;
    235 
    236 def simm7s4 : Operand<i32> {
    237   let ParserMatchClass = SImm7s4Operand;
    238   let PrintMethod = "printImmScale<4>";
    239 }
    240 
    241 def simm7s8 : Operand<i32> {
    242   let ParserMatchClass = SImm7s8Operand;
    243   let PrintMethod = "printImmScale<8>";
    244 }
    245 
    246 def simm7s16 : Operand<i32> {
    247   let ParserMatchClass = SImm7s16Operand;
    248   let PrintMethod = "printImmScale<16>";
    249 }
    250 
    251 def am_indexed7s8   : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>;
    252 def am_indexed7s16  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>;
    253 def am_indexed7s32  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>;
    254 def am_indexed7s64  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>;
    255 def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>;
    256 
    257 class AsmImmRange<int Low, int High> : AsmOperandClass {
    258   let Name = "Imm" # Low # "_" # High;
    259   let DiagnosticType = "InvalidImm" # Low # "_" # High;
    260 }
    261 
    262 def Imm1_8Operand : AsmImmRange<1, 8>;
    263 def Imm1_16Operand : AsmImmRange<1, 16>;
    264 def Imm1_32Operand : AsmImmRange<1, 32>;
    265 def Imm1_64Operand : AsmImmRange<1, 64>;
    266 
    267 def MovZSymbolG3AsmOperand : AsmOperandClass {
    268   let Name = "MovZSymbolG3";
    269   let RenderMethod = "addImmOperands";
    270 }
    271 
    272 def movz_symbol_g3 : Operand<i32> {
    273   let ParserMatchClass = MovZSymbolG3AsmOperand;
    274 }
    275 
    276 def MovZSymbolG2AsmOperand : AsmOperandClass {
    277   let Name = "MovZSymbolG2";
    278   let RenderMethod = "addImmOperands";
    279 }
    280 
    281 def movz_symbol_g2 : Operand<i32> {
    282   let ParserMatchClass = MovZSymbolG2AsmOperand;
    283 }
    284 
    285 def MovZSymbolG1AsmOperand : AsmOperandClass {
    286   let Name = "MovZSymbolG1";
    287   let RenderMethod = "addImmOperands";
    288 }
    289 
    290 def movz_symbol_g1 : Operand<i32> {
    291   let ParserMatchClass = MovZSymbolG1AsmOperand;
    292 }
    293 
    294 def MovZSymbolG0AsmOperand : AsmOperandClass {
    295   let Name = "MovZSymbolG0";
    296   let RenderMethod = "addImmOperands";
    297 }
    298 
    299 def movz_symbol_g0 : Operand<i32> {
    300   let ParserMatchClass = MovZSymbolG0AsmOperand;
    301 }
    302 
    303 def MovKSymbolG3AsmOperand : AsmOperandClass {
    304   let Name = "MovKSymbolG3";
    305   let RenderMethod = "addImmOperands";
    306 }
    307 
    308 def movk_symbol_g3 : Operand<i32> {
    309   let ParserMatchClass = MovKSymbolG3AsmOperand;
    310 }
    311 
    312 def MovKSymbolG2AsmOperand : AsmOperandClass {
    313   let Name = "MovKSymbolG2";
    314   let RenderMethod = "addImmOperands";
    315 }
    316 
    317 def movk_symbol_g2 : Operand<i32> {
    318   let ParserMatchClass = MovKSymbolG2AsmOperand;
    319 }
    320 
    321 def MovKSymbolG1AsmOperand : AsmOperandClass {
    322   let Name = "MovKSymbolG1";
    323   let RenderMethod = "addImmOperands";
    324 }
    325 
    326 def movk_symbol_g1 : Operand<i32> {
    327   let ParserMatchClass = MovKSymbolG1AsmOperand;
    328 }
    329 
    330 def MovKSymbolG0AsmOperand : AsmOperandClass {
    331   let Name = "MovKSymbolG0";
    332   let RenderMethod = "addImmOperands";
    333 }
    334 
    335 def movk_symbol_g0 : Operand<i32> {
    336   let ParserMatchClass = MovKSymbolG0AsmOperand;
    337 }
    338 
    339 class fixedpoint_i32<ValueType FloatVT>
    340   : Operand<FloatVT>,
    341     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
    342   let EncoderMethod = "getFixedPointScaleOpValue";
    343   let DecoderMethod = "DecodeFixedPointScaleImm32";
    344   let ParserMatchClass = Imm1_32Operand;
    345 }
    346 
    347 class fixedpoint_i64<ValueType FloatVT>
    348   : Operand<FloatVT>,
    349     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
    350   let EncoderMethod = "getFixedPointScaleOpValue";
    351   let DecoderMethod = "DecodeFixedPointScaleImm64";
    352   let ParserMatchClass = Imm1_64Operand;
    353 }
    354 
    355 def fixedpoint_f16_i32 : fixedpoint_i32<f16>;
    356 def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
    357 def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
    358 
    359 def fixedpoint_f16_i64 : fixedpoint_i64<f16>;
    360 def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
    361 def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
    362 
    363 def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
    364   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
    365 }]> {
    366   let EncoderMethod = "getVecShiftR8OpValue";
    367   let DecoderMethod = "DecodeVecShiftR8Imm";
    368   let ParserMatchClass = Imm1_8Operand;
    369 }
    370 def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
    371   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
    372 }]> {
    373   let EncoderMethod = "getVecShiftR16OpValue";
    374   let DecoderMethod = "DecodeVecShiftR16Imm";
    375   let ParserMatchClass = Imm1_16Operand;
    376 }
    377 def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
    378   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
    379 }]> {
    380   let EncoderMethod = "getVecShiftR16OpValue";
    381   let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
    382   let ParserMatchClass = Imm1_8Operand;
    383 }
    384 def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
    385   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
    386 }]> {
    387   let EncoderMethod = "getVecShiftR32OpValue";
    388   let DecoderMethod = "DecodeVecShiftR32Imm";
    389   let ParserMatchClass = Imm1_32Operand;
    390 }
    391 def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
    392   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
    393 }]> {
    394   let EncoderMethod = "getVecShiftR32OpValue";
    395   let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
    396   let ParserMatchClass = Imm1_16Operand;
    397 }
    398 def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
    399   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
    400 }]> {
    401   let EncoderMethod = "getVecShiftR64OpValue";
    402   let DecoderMethod = "DecodeVecShiftR64Imm";
    403   let ParserMatchClass = Imm1_64Operand;
    404 }
    405 def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
    406   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
    407 }]> {
    408   let EncoderMethod = "getVecShiftR64OpValue";
    409   let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
    410   let ParserMatchClass = Imm1_32Operand;
    411 }
    412 
    413 def Imm0_1Operand : AsmImmRange<0, 1>;
    414 def Imm0_7Operand : AsmImmRange<0, 7>;
    415 def Imm0_15Operand : AsmImmRange<0, 15>;
    416 def Imm0_31Operand : AsmImmRange<0, 31>;
    417 def Imm0_63Operand : AsmImmRange<0, 63>;
    418 
    419 def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
    420   return (((uint32_t)Imm) < 8);
    421 }]> {
    422   let EncoderMethod = "getVecShiftL8OpValue";
    423   let DecoderMethod = "DecodeVecShiftL8Imm";
    424   let ParserMatchClass = Imm0_7Operand;
    425 }
    426 def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
    427   return (((uint32_t)Imm) < 16);
    428 }]> {
    429   let EncoderMethod = "getVecShiftL16OpValue";
    430   let DecoderMethod = "DecodeVecShiftL16Imm";
    431   let ParserMatchClass = Imm0_15Operand;
    432 }
    433 def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
    434   return (((uint32_t)Imm) < 32);
    435 }]> {
    436   let EncoderMethod = "getVecShiftL32OpValue";
    437   let DecoderMethod = "DecodeVecShiftL32Imm";
    438   let ParserMatchClass = Imm0_31Operand;
    439 }
    440 def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
    441   return (((uint32_t)Imm) < 64);
    442 }]> {
    443   let EncoderMethod = "getVecShiftL64OpValue";
    444   let DecoderMethod = "DecodeVecShiftL64Imm";
    445   let ParserMatchClass = Imm0_63Operand;
    446 }
    447 
    448 
    449 // Crazy immediate formats used by 32-bit and 64-bit logical immediate
    450 // instructions for splatting repeating bit patterns across the immediate.
    451 def logical_imm32_XFORM : SDNodeXForm<imm, [{
    452   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
    453   return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
    454 }]>;
    455 def logical_imm64_XFORM : SDNodeXForm<imm, [{
    456   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
    457   return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
    458 }]>;
    459 
    460 let DiagnosticType = "LogicalSecondSource" in {
    461   def LogicalImm32Operand : AsmOperandClass {
    462     let Name = "LogicalImm32";
    463   }
    464   def LogicalImm64Operand : AsmOperandClass {
    465     let Name = "LogicalImm64";
    466   }
    467   def LogicalImm32NotOperand : AsmOperandClass {
    468     let Name = "LogicalImm32Not";
    469   }
    470   def LogicalImm64NotOperand : AsmOperandClass {
    471     let Name = "LogicalImm64Not";
    472   }
    473 }
    474 def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{
    475   return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 32);
    476 }], logical_imm32_XFORM> {
    477   let PrintMethod = "printLogicalImm32";
    478   let ParserMatchClass = LogicalImm32Operand;
    479 }
    480 def logical_imm64 : Operand<i64>, PatLeaf<(imm), [{
    481   return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 64);
    482 }], logical_imm64_XFORM> {
    483   let PrintMethod = "printLogicalImm64";
    484   let ParserMatchClass = LogicalImm64Operand;
    485 }
    486 def logical_imm32_not : Operand<i32> {
    487   let ParserMatchClass = LogicalImm32NotOperand;
    488 }
    489 def logical_imm64_not : Operand<i64> {
    490   let ParserMatchClass = LogicalImm64NotOperand;
    491 }
    492 
    493 // imm0_65535 predicate - True if the immediate is in the range [0,65535].
    494 def Imm0_65535Operand : AsmImmRange<0, 65535>;
    495 def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
    496   return ((uint32_t)Imm) < 65536;
    497 }]> {
    498   let ParserMatchClass = Imm0_65535Operand;
    499   let PrintMethod = "printImmHex";
    500 }
    501 
    502 // imm0_255 predicate - True if the immediate is in the range [0,255].
    503 def Imm0_255Operand : AsmOperandClass { let Name = "Imm0_255"; }
    504 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
    505   return ((uint32_t)Imm) < 256;
    506 }]> {
    507   let ParserMatchClass = Imm0_255Operand;
    508   let PrintMethod = "printImm";
    509 }
    510 
    511 // imm0_127 predicate - True if the immediate is in the range [0,127]
    512 def Imm0_127Operand : AsmImmRange<0, 127>;
    513 def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
    514   return ((uint32_t)Imm) < 128;
    515 }]> {
    516   let ParserMatchClass = Imm0_127Operand;
    517   let PrintMethod = "printImm";
    518 }
    519 
    520 // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
    521 // for all shift-amounts.
    522 
    523 // imm0_63 predicate - True if the immediate is in the range [0,63]
    524 def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
    525   return ((uint64_t)Imm) < 64;
    526 }]> {
    527   let ParserMatchClass = Imm0_63Operand;
    528 }
    529 
    530 // imm0_31 predicate - True if the immediate is in the range [0,31]
    531 def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
    532   return ((uint64_t)Imm) < 32;
    533 }]> {
    534   let ParserMatchClass = Imm0_31Operand;
    535 }
    536 
    537 // True if the 32-bit immediate is in the range [0,31]
    538 def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
    539   return ((uint64_t)Imm) < 32;
    540 }]> {
    541   let ParserMatchClass = Imm0_31Operand;
    542 }
    543 
    544 // imm0_1 predicate - True if the immediate is in the range [0,1]
    545 def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
    546   return ((uint64_t)Imm) < 2;
    547 }]> {
    548   let ParserMatchClass = Imm0_1Operand;
    549 }
    550 
    551 // imm0_15 predicate - True if the immediate is in the range [0,15]
    552 def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
    553   return ((uint64_t)Imm) < 16;
    554 }]> {
    555   let ParserMatchClass = Imm0_15Operand;
    556 }
    557 
    558 // imm0_7 predicate - True if the immediate is in the range [0,7]
    559 def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
    560   return ((uint64_t)Imm) < 8;
    561 }]> {
    562   let ParserMatchClass = Imm0_7Operand;
    563 }
    564 
    565 // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
    566 def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
    567   return ((uint32_t)Imm) < 16;
    568 }]> {
    569   let ParserMatchClass = Imm0_15Operand;
    570 }
    571 
    572 // An arithmetic shifter operand:
    573 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
    574 //  {5-0} - imm6
    575 class arith_shift<ValueType Ty, int width> : Operand<Ty> {
    576   let PrintMethod = "printShifter";
    577   let ParserMatchClass = !cast<AsmOperandClass>(
    578                          "ArithmeticShifterOperand" # width);
    579 }
    580 
    581 def arith_shift32 : arith_shift<i32, 32>;
    582 def arith_shift64 : arith_shift<i64, 64>;
    583 
    584 class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
    585     : Operand<Ty>,
    586       ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
    587   let PrintMethod = "printShiftedRegister";
    588   let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
    589 }
    590 
    591 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
    592 def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
    593 
    594 // An arithmetic shifter operand:
    595 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
    596 //  {5-0} - imm6
    597 class logical_shift<int width> : Operand<i32> {
    598   let PrintMethod = "printShifter";
    599   let ParserMatchClass = !cast<AsmOperandClass>(
    600                          "LogicalShifterOperand" # width);
    601 }
    602 
    603 def logical_shift32 : logical_shift<32>;
    604 def logical_shift64 : logical_shift<64>;
    605 
    606 class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
    607     : Operand<Ty>,
    608       ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
    609   let PrintMethod = "printShiftedRegister";
    610   let MIOperandInfo = (ops regclass, shiftop);
    611 }
    612 
    613 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
    614 def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
    615 
    616 // A logical vector shifter operand:
    617 //  {7-6} - shift type: 00 = lsl
    618 //  {5-0} - imm6: #0, #8, #16, or #24
    619 def logical_vec_shift : Operand<i32> {
    620   let PrintMethod = "printShifter";
    621   let EncoderMethod = "getVecShifterOpValue";
    622   let ParserMatchClass = LogicalVecShifterOperand;
    623 }
    624 
    625 // A logical vector half-word shifter operand:
    626 //  {7-6} - shift type: 00 = lsl
    627 //  {5-0} - imm6: #0 or #8
    628 def logical_vec_hw_shift : Operand<i32> {
    629   let PrintMethod = "printShifter";
    630   let EncoderMethod = "getVecShifterOpValue";
    631   let ParserMatchClass = LogicalVecHalfWordShifterOperand;
    632 }
    633 
    634 // A vector move shifter operand:
    635 //  {0} - imm1: #8 or #16
    636 def move_vec_shift : Operand<i32> {
    637   let PrintMethod = "printShifter";
    638   let EncoderMethod = "getMoveVecShifterOpValue";
    639   let ParserMatchClass = MoveVecShifterOperand;
    640 }
    641 
    642 let DiagnosticType = "AddSubSecondSource" in {
    643   def AddSubImmOperand : AsmOperandClass {
    644     let Name = "AddSubImm";
    645     let ParserMethod = "tryParseAddSubImm";
    646   }
    647   def AddSubImmNegOperand : AsmOperandClass {
    648     let Name = "AddSubImmNeg";
    649     let ParserMethod = "tryParseAddSubImm";
    650   }
    651 }
    652 // An ADD/SUB immediate shifter operand:
    653 //  second operand:
    654 //  {7-6} - shift type: 00 = lsl
    655 //  {5-0} - imm6: #0 or #12
    656 class addsub_shifted_imm<ValueType Ty>
    657     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
    658   let PrintMethod = "printAddSubImm";
    659   let EncoderMethod = "getAddSubImmOpValue";
    660   let ParserMatchClass = AddSubImmOperand;
    661   let MIOperandInfo = (ops i32imm, i32imm);
    662 }
    663 
    664 class addsub_shifted_imm_neg<ValueType Ty>
    665     : Operand<Ty> {
    666   let EncoderMethod = "getAddSubImmOpValue";
    667   let ParserMatchClass = AddSubImmNegOperand;
    668   let MIOperandInfo = (ops i32imm, i32imm);
    669 }
    670 
    671 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
    672 def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
    673 def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
    674 def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
    675 
    676 class neg_addsub_shifted_imm<ValueType Ty>
    677     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
    678   let PrintMethod = "printAddSubImm";
    679   let EncoderMethod = "getAddSubImmOpValue";
    680   let ParserMatchClass = AddSubImmOperand;
    681   let MIOperandInfo = (ops i32imm, i32imm);
    682 }
    683 
    684 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
    685 def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
    686 
    687 // An extend operand:
    688 //  {5-3} - extend type
    689 //  {2-0} - imm3
    690 def arith_extend : Operand<i32> {
    691   let PrintMethod = "printArithExtend";
    692   let ParserMatchClass = ExtendOperand;
    693 }
    694 def arith_extend64 : Operand<i32> {
    695   let PrintMethod = "printArithExtend";
    696   let ParserMatchClass = ExtendOperand64;
    697 }
    698 
    699 // 'extend' that's a lsl of a 64-bit register.
    700 def arith_extendlsl64 : Operand<i32> {
    701   let PrintMethod = "printArithExtend";
    702   let ParserMatchClass = ExtendOperandLSL64;
    703 }
    704 
    705 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
    706                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
    707   let PrintMethod = "printExtendedRegister";
    708   let MIOperandInfo = (ops GPR32, arith_extend);
    709 }
    710 
    711 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
    712                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
    713   let PrintMethod = "printExtendedRegister";
    714   let MIOperandInfo = (ops GPR32, arith_extend64);
    715 }
    716 
    717 // Floating-point immediate.
    718 def fpimm16 : Operand<f16>,
    719               PatLeaf<(f16 fpimm), [{
    720       return AArch64_AM::getFP16Imm(N->getValueAPF()) != -1;
    721     }], SDNodeXForm<fpimm, [{
    722       APFloat InVal = N->getValueAPF();
    723       uint32_t enc = AArch64_AM::getFP16Imm(InVal);
    724       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
    725     }]>> {
    726   let ParserMatchClass = FPImmOperand;
    727   let PrintMethod = "printFPImmOperand";
    728 }
    729 def fpimm32 : Operand<f32>,
    730               PatLeaf<(f32 fpimm), [{
    731       return AArch64_AM::getFP32Imm(N->getValueAPF()) != -1;
    732     }], SDNodeXForm<fpimm, [{
    733       APFloat InVal = N->getValueAPF();
    734       uint32_t enc = AArch64_AM::getFP32Imm(InVal);
    735       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
    736     }]>> {
    737   let ParserMatchClass = FPImmOperand;
    738   let PrintMethod = "printFPImmOperand";
    739 }
    740 def fpimm64 : Operand<f64>,
    741               PatLeaf<(f64 fpimm), [{
    742       return AArch64_AM::getFP64Imm(N->getValueAPF()) != -1;
    743     }], SDNodeXForm<fpimm, [{
    744       APFloat InVal = N->getValueAPF();
    745       uint32_t enc = AArch64_AM::getFP64Imm(InVal);
    746       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
    747     }]>> {
    748   let ParserMatchClass = FPImmOperand;
    749   let PrintMethod = "printFPImmOperand";
    750 }
    751 
    752 def fpimm8 : Operand<i32> {
    753   let ParserMatchClass = FPImmOperand;
    754   let PrintMethod = "printFPImmOperand";
    755 }
    756 
    757 def fpimm0 : PatLeaf<(fpimm), [{
    758   return N->isExactlyValue(+0.0);
    759 }]>;
    760 
    761 // Vector lane operands
    762 class AsmVectorIndex<string Suffix> : AsmOperandClass {
    763   let Name = "VectorIndex" # Suffix;
    764   let DiagnosticType = "InvalidIndex" # Suffix;
    765 }
    766 def VectorIndex1Operand : AsmVectorIndex<"1">;
    767 def VectorIndexBOperand : AsmVectorIndex<"B">;
    768 def VectorIndexHOperand : AsmVectorIndex<"H">;
    769 def VectorIndexSOperand : AsmVectorIndex<"S">;
    770 def VectorIndexDOperand : AsmVectorIndex<"D">;
    771 
    772 def VectorIndex1 : Operand<i64>, ImmLeaf<i64, [{
    773   return ((uint64_t)Imm) == 1;
    774 }]> {
    775   let ParserMatchClass = VectorIndex1Operand;
    776   let PrintMethod = "printVectorIndex";
    777   let MIOperandInfo = (ops i64imm);
    778 }
    779 def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
    780   return ((uint64_t)Imm) < 16;
    781 }]> {
    782   let ParserMatchClass = VectorIndexBOperand;
    783   let PrintMethod = "printVectorIndex";
    784   let MIOperandInfo = (ops i64imm);
    785 }
    786 def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
    787   return ((uint64_t)Imm) < 8;
    788 }]> {
    789   let ParserMatchClass = VectorIndexHOperand;
    790   let PrintMethod = "printVectorIndex";
    791   let MIOperandInfo = (ops i64imm);
    792 }
    793 def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
    794   return ((uint64_t)Imm) < 4;
    795 }]> {
    796   let ParserMatchClass = VectorIndexSOperand;
    797   let PrintMethod = "printVectorIndex";
    798   let MIOperandInfo = (ops i64imm);
    799 }
    800 def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
    801   return ((uint64_t)Imm) < 2;
    802 }]> {
    803   let ParserMatchClass = VectorIndexDOperand;
    804   let PrintMethod = "printVectorIndex";
    805   let MIOperandInfo = (ops i64imm);
    806 }
    807 
    808 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
    809 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
    810 // are encoded as the eight bit value 'abcdefgh'.
    811 def simdimmtype10 : Operand<i32>,
    812                     PatLeaf<(f64 fpimm), [{
    813       return AArch64_AM::isAdvSIMDModImmType10(N->getValueAPF()
    814                                                .bitcastToAPInt()
    815                                                .getZExtValue());
    816     }], SDNodeXForm<fpimm, [{
    817       APFloat InVal = N->getValueAPF();
    818       uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
    819                                                            .bitcastToAPInt()
    820                                                            .getZExtValue());
    821       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
    822     }]>> {
    823   let ParserMatchClass = SIMDImmType10Operand;
    824   let PrintMethod = "printSIMDType10Operand";
    825 }
    826 
    827 
    828 //---
    829 // System management
    830 //---
    831 
    832 // Base encoding for system instruction operands.
    833 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
    834 class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
    835                   list<dag> pattern = []>
    836     : I<oops, iops, asm, operands, "", pattern> {
    837   let Inst{31-22} = 0b1101010100;
    838   let Inst{21}    = L;
    839 }
    840 
    841 // System instructions which do not have an Rt register.
    842 class SimpleSystemI<bit L, dag iops, string asm, string operands,
    843                     list<dag> pattern = []>
    844     : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
    845   let Inst{4-0} = 0b11111;
    846 }
    847 
    848 // System instructions which have an Rt register.
    849 class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
    850     : BaseSystemI<L, oops, iops, asm, operands>,
    851       Sched<[WriteSys]> {
    852   bits<5> Rt;
    853   let Inst{4-0} = Rt;
    854 }
    855 
    856 // Hint instructions that take both a CRm and a 3-bit immediate.
    857 // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
    858 // model patterns with sufficiently fine granularity
    859 let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
    860   class HintI<string mnemonic>
    861       : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
    862                       [(int_aarch64_hint imm0_127:$imm)]>,
    863         Sched<[WriteHint]> {
    864     bits <7> imm;
    865     let Inst{20-12} = 0b000110010;
    866     let Inst{11-5} = imm;
    867   }
    868 
    869 // System instructions taking a single literal operand which encodes into
    870 // CRm. op2 differentiates the opcodes.
    871 def BarrierAsmOperand : AsmOperandClass {
    872   let Name = "Barrier";
    873   let ParserMethod = "tryParseBarrierOperand";
    874 }
    875 def barrier_op : Operand<i32> {
    876   let PrintMethod = "printBarrierOption";
    877   let ParserMatchClass = BarrierAsmOperand;
    878 }
    879 class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
    880                  list<dag> pattern = []>
    881     : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
    882       Sched<[WriteBarrier]> {
    883   bits<4> CRm;
    884   let Inst{20-12} = 0b000110011;
    885   let Inst{11-8} = CRm;
    886   let Inst{7-5} = opc;
    887 }
    888 
    889 // MRS/MSR system instructions. These have different operand classes because
    890 // a different subset of registers can be accessed through each instruction.
    891 def MRSSystemRegisterOperand : AsmOperandClass {
    892   let Name = "MRSSystemRegister";
    893   let ParserMethod = "tryParseSysReg";
    894   let DiagnosticType = "MRS";
    895 }
    896 // concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
    897 def mrs_sysreg_op : Operand<i32> {
    898   let ParserMatchClass = MRSSystemRegisterOperand;
    899   let DecoderMethod = "DecodeMRSSystemRegister";
    900   let PrintMethod = "printMRSSystemRegister";
    901 }
    902 
    903 def MSRSystemRegisterOperand : AsmOperandClass {
    904   let Name = "MSRSystemRegister";
    905   let ParserMethod = "tryParseSysReg";
    906   let DiagnosticType = "MSR";
    907 }
    908 def msr_sysreg_op : Operand<i32> {
    909   let ParserMatchClass = MSRSystemRegisterOperand;
    910   let DecoderMethod = "DecodeMSRSystemRegister";
    911   let PrintMethod = "printMSRSystemRegister";
    912 }
    913 
    914 def PSBHintOperand : AsmOperandClass {
    915   let Name = "PSBHint";
    916   let ParserMethod = "tryParsePSBHint";
    917 }
    918 def psbhint_op : Operand<i32> {
    919   let ParserMatchClass = PSBHintOperand;
    920   let PrintMethod = "printPSBHintOp";
    921   let MCOperandPredicate = [{
    922     // Check, if operand is valid, to fix exhaustive aliasing in disassembly.
    923     // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields.
    924     if (!MCOp.isImm())
    925       return false;
    926     return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
    927   }];
    928 }
    929 
    930 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
    931                        "mrs", "\t$Rt, $systemreg"> {
    932   bits<16> systemreg;
    933   let Inst{20-5} = systemreg;
    934 }
    935 
    936 // FIXME: Some of these def NZCV, others don't. Best way to model that?
    937 // Explicitly modeling each of the system register as a register class
    938 // would do it, but feels like overkill at this point.
    939 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
    940                        "msr", "\t$systemreg, $Rt"> {
    941   bits<16> systemreg;
    942   let Inst{20-5} = systemreg;
    943 }
    944 
    945 def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
    946   let Name = "SystemPStateFieldWithImm0_15";
    947   let ParserMethod = "tryParseSysReg";
    948 }
    949 def pstatefield4_op : Operand<i32> {
    950   let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
    951   let PrintMethod = "printSystemPStateField";
    952 }
    953 
    954 let Defs = [NZCV] in
    955 class MSRpstateImm0_15
    956   : SimpleSystemI<0, (ins pstatefield4_op:$pstatefield, imm0_15:$imm),
    957                   "msr", "\t$pstatefield, $imm">,
    958     Sched<[WriteSys]> {
    959   bits<6> pstatefield;
    960   bits<4> imm;
    961   let Inst{20-19} = 0b00;
    962   let Inst{18-16} = pstatefield{5-3};
    963   let Inst{15-12} = 0b0100;
    964   let Inst{11-8} = imm;
    965   let Inst{7-5} = pstatefield{2-0};
    966 
    967   let DecoderMethod = "DecodeSystemPStateInstruction";
    968   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
    969   // Fail the decoder should attempt to decode the instruction as MSRI.
    970   let hasCompleteDecoder = 0;
    971 }
    972 
    973 def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
    974   let Name = "SystemPStateFieldWithImm0_1";
    975   let ParserMethod = "tryParseSysReg";
    976 }
    977 def pstatefield1_op : Operand<i32> {
    978   let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
    979   let PrintMethod = "printSystemPStateField";
    980 }
    981 
    982 let Defs = [NZCV] in
    983 class MSRpstateImm0_1
    984   : SimpleSystemI<0, (ins pstatefield1_op:$pstatefield, imm0_1:$imm),
    985                   "msr", "\t$pstatefield, $imm">,
    986     Sched<[WriteSys]> {
    987   bits<6> pstatefield;
    988   bit imm;
    989   let Inst{20-19} = 0b00;
    990   let Inst{18-16} = pstatefield{5-3};
    991   let Inst{15-9} = 0b0100000;
    992   let Inst{8} = imm;
    993   let Inst{7-5} = pstatefield{2-0};
    994 
    995   let DecoderMethod = "DecodeSystemPStateInstruction";
    996   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
    997   // Fail the decoder should attempt to decode the instruction as MSRI.
    998   let hasCompleteDecoder = 0;
    999 }
   1000 
   1001 // SYS and SYSL generic system instructions.
   1002 def SysCRAsmOperand : AsmOperandClass {
   1003   let Name = "SysCR";
   1004   let ParserMethod = "tryParseSysCROperand";
   1005 }
   1006 
   1007 def sys_cr_op : Operand<i32> {
   1008   let PrintMethod = "printSysCROperand";
   1009   let ParserMatchClass = SysCRAsmOperand;
   1010 }
   1011 
   1012 class SystemXtI<bit L, string asm>
   1013   : RtSystemI<L, (outs),
   1014        (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
   1015        asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
   1016   bits<3> op1;
   1017   bits<4> Cn;
   1018   bits<4> Cm;
   1019   bits<3> op2;
   1020   let Inst{20-19} = 0b01;
   1021   let Inst{18-16} = op1;
   1022   let Inst{15-12} = Cn;
   1023   let Inst{11-8}  = Cm;
   1024   let Inst{7-5}   = op2;
   1025 }
   1026 
   1027 class SystemLXtI<bit L, string asm>
   1028   : RtSystemI<L, (outs),
   1029        (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
   1030        asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
   1031   bits<3> op1;
   1032   bits<4> Cn;
   1033   bits<4> Cm;
   1034   bits<3> op2;
   1035   let Inst{20-19} = 0b01;
   1036   let Inst{18-16} = op1;
   1037   let Inst{15-12} = Cn;
   1038   let Inst{11-8}  = Cm;
   1039   let Inst{7-5}   = op2;
   1040 }
   1041 
   1042 
   1043 // Branch (register) instructions:
   1044 //
   1045 //  case opc of
   1046 //    0001 blr
   1047 //    0000 br
   1048 //    0101 dret
   1049 //    0100 eret
   1050 //    0010 ret
   1051 //    otherwise UNDEFINED
   1052 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
   1053                     string operands, list<dag> pattern>
   1054     : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
   1055   let Inst{31-25} = 0b1101011;
   1056   let Inst{24-21} = opc;
   1057   let Inst{20-16} = 0b11111;
   1058   let Inst{15-10} = 0b000000;
   1059   let Inst{4-0}   = 0b00000;
   1060 }
   1061 
   1062 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
   1063     : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
   1064   bits<5> Rn;
   1065   let Inst{9-5} = Rn;
   1066 }
   1067 
   1068 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
   1069 class SpecialReturn<bits<4> opc, string asm>
   1070     : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
   1071   let Inst{9-5} = 0b11111;
   1072 }
   1073 
   1074 //---
   1075 // Conditional branch instruction.
   1076 //---
   1077 
   1078 // Condition code.
   1079 // 4-bit immediate. Pretty-printed as <cc>
   1080 def ccode : Operand<i32> {
   1081   let PrintMethod = "printCondCode";
   1082   let ParserMatchClass = CondCode;
   1083 }
   1084 def inv_ccode : Operand<i32> {
   1085   // AL and NV are invalid in the aliases which use inv_ccode
   1086   let PrintMethod = "printInverseCondCode";
   1087   let ParserMatchClass = CondCode;
   1088   let MCOperandPredicate = [{
   1089     return MCOp.isImm() &&
   1090            MCOp.getImm() != AArch64CC::AL &&
   1091            MCOp.getImm() != AArch64CC::NV;
   1092   }];
   1093 }
   1094 
   1095 // Conditional branch target. 19-bit immediate. The low two bits of the target
   1096 // offset are implied zero and so are not part of the immediate.
   1097 def PCRelLabel19Operand : AsmOperandClass {
   1098   let Name = "PCRelLabel19";
   1099   let DiagnosticType = "InvalidLabel";
   1100 }
   1101 def am_brcond : Operand<OtherVT> {
   1102   let EncoderMethod = "getCondBranchTargetOpValue";
   1103   let DecoderMethod = "DecodePCRelLabel19";
   1104   let PrintMethod = "printAlignedLabel";
   1105   let ParserMatchClass = PCRelLabel19Operand;
   1106 }
   1107 
   1108 class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
   1109                      "b", ".$cond\t$target", "",
   1110                      [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
   1111                    Sched<[WriteBr]> {
   1112   let isBranch = 1;
   1113   let isTerminator = 1;
   1114   let Uses = [NZCV];
   1115 
   1116   bits<4> cond;
   1117   bits<19> target;
   1118   let Inst{31-24} = 0b01010100;
   1119   let Inst{23-5} = target;
   1120   let Inst{4} = 0;
   1121   let Inst{3-0} = cond;
   1122 }
   1123 
   1124 //---
   1125 // Compare-and-branch instructions.
   1126 //---
   1127 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
   1128     : I<(outs), (ins regtype:$Rt, am_brcond:$target),
   1129          asm, "\t$Rt, $target", "",
   1130          [(node regtype:$Rt, bb:$target)]>,
   1131       Sched<[WriteBr]> {
   1132   let isBranch = 1;
   1133   let isTerminator = 1;
   1134 
   1135   bits<5> Rt;
   1136   bits<19> target;
   1137   let Inst{30-25} = 0b011010;
   1138   let Inst{24}    = op;
   1139   let Inst{23-5}  = target;
   1140   let Inst{4-0}   = Rt;
   1141 }
   1142 
   1143 multiclass CmpBranch<bit op, string asm, SDNode node> {
   1144   def W : BaseCmpBranch<GPR32, op, asm, node> {
   1145     let Inst{31} = 0;
   1146   }
   1147   def X : BaseCmpBranch<GPR64, op, asm, node> {
   1148     let Inst{31} = 1;
   1149   }
   1150 }
   1151 
   1152 //---
   1153 // Test-bit-and-branch instructions.
   1154 //---
   1155 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
   1156 // the target offset are implied zero and so are not part of the immediate.
   1157 def BranchTarget14Operand : AsmOperandClass {
   1158   let Name = "BranchTarget14";
   1159 }
   1160 def am_tbrcond : Operand<OtherVT> {
   1161   let EncoderMethod = "getTestBranchTargetOpValue";
   1162   let PrintMethod = "printAlignedLabel";
   1163   let ParserMatchClass = BranchTarget14Operand;
   1164 }
   1165 
   1166 // AsmOperand classes to emit (or not) special diagnostics
   1167 def TBZImm0_31Operand : AsmOperandClass {
   1168   let Name = "TBZImm0_31";
   1169   let PredicateMethod = "isImm0_31";
   1170   let RenderMethod = "addImm0_31Operands";
   1171 }
   1172 def TBZImm32_63Operand : AsmOperandClass {
   1173   let Name = "Imm32_63";
   1174   let DiagnosticType = "InvalidImm0_63";
   1175 }
   1176 
   1177 class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
   1178   return (((uint32_t)Imm) < 32);
   1179 }]> {
   1180   let ParserMatchClass = matcher;
   1181 }
   1182 
   1183 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
   1184 def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
   1185 
   1186 def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
   1187   return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
   1188 }]> {
   1189   let ParserMatchClass = TBZImm32_63Operand;
   1190 }
   1191 
   1192 class BaseTestBranch<RegisterClass regtype, Operand immtype,
   1193                      bit op, string asm, SDNode node>
   1194     : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
   1195        asm, "\t$Rt, $bit_off, $target", "",
   1196        [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
   1197       Sched<[WriteBr]> {
   1198   let isBranch = 1;
   1199   let isTerminator = 1;
   1200 
   1201   bits<5> Rt;
   1202   bits<6> bit_off;
   1203   bits<14> target;
   1204 
   1205   let Inst{30-25} = 0b011011;
   1206   let Inst{24}    = op;
   1207   let Inst{23-19} = bit_off{4-0};
   1208   let Inst{18-5}  = target;
   1209   let Inst{4-0}   = Rt;
   1210 
   1211   let DecoderMethod = "DecodeTestAndBranch";
   1212 }
   1213 
   1214 multiclass TestBranch<bit op, string asm, SDNode node> {
   1215   def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
   1216     let Inst{31} = 0;
   1217   }
   1218 
   1219   def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
   1220     let Inst{31} = 1;
   1221   }
   1222 
   1223   // Alias X-reg with 0-31 imm to W-Reg.
   1224   def : InstAlias<asm # "\t$Rd, $imm, $target",
   1225                   (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
   1226                   tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
   1227   def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
   1228             (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
   1229             tbz_imm0_31_diag:$imm, bb:$target)>;
   1230 }
   1231 
   1232 //---
   1233 // Unconditional branch (immediate) instructions.
   1234 //---
   1235 def BranchTarget26Operand : AsmOperandClass {
   1236   let Name = "BranchTarget26";
   1237   let DiagnosticType = "InvalidLabel";
   1238 }
   1239 def am_b_target : Operand<OtherVT> {
   1240   let EncoderMethod = "getBranchTargetOpValue";
   1241   let PrintMethod = "printAlignedLabel";
   1242   let ParserMatchClass = BranchTarget26Operand;
   1243 }
   1244 def am_bl_target : Operand<i64> {
   1245   let EncoderMethod = "getBranchTargetOpValue";
   1246   let PrintMethod = "printAlignedLabel";
   1247   let ParserMatchClass = BranchTarget26Operand;
   1248 }
   1249 
   1250 class BImm<bit op, dag iops, string asm, list<dag> pattern>
   1251     : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
   1252   bits<26> addr;
   1253   let Inst{31}    = op;
   1254   let Inst{30-26} = 0b00101;
   1255   let Inst{25-0}  = addr;
   1256 
   1257   let DecoderMethod = "DecodeUnconditionalBranch";
   1258 }
   1259 
   1260 class BranchImm<bit op, string asm, list<dag> pattern>
   1261     : BImm<op, (ins am_b_target:$addr), asm, pattern>;
   1262 class CallImm<bit op, string asm, list<dag> pattern>
   1263     : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
   1264 
   1265 //---
   1266 // Basic one-operand data processing instructions.
   1267 //---
   1268 
   1269 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   1270 class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
   1271                          SDPatternOperator node>
   1272   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
   1273       [(set regtype:$Rd, (node regtype:$Rn))]>,
   1274     Sched<[WriteI, ReadI]> {
   1275   bits<5> Rd;
   1276   bits<5> Rn;
   1277 
   1278   let Inst{30-13} = 0b101101011000000000;
   1279   let Inst{12-10} = opc;
   1280   let Inst{9-5}   = Rn;
   1281   let Inst{4-0}   = Rd;
   1282 }
   1283 
   1284 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   1285 multiclass OneOperandData<bits<3> opc, string asm,
   1286                           SDPatternOperator node = null_frag> {
   1287   def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
   1288     let Inst{31} = 0;
   1289   }
   1290 
   1291   def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
   1292     let Inst{31} = 1;
   1293   }
   1294 }
   1295 
   1296 class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
   1297     : BaseOneOperandData<opc, GPR32, asm, node> {
   1298   let Inst{31} = 0;
   1299 }
   1300 
   1301 class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
   1302     : BaseOneOperandData<opc, GPR64, asm, node> {
   1303   let Inst{31} = 1;
   1304 }
   1305 
   1306 //---
   1307 // Basic two-operand data processing instructions.
   1308 //---
   1309 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
   1310                           list<dag> pattern>
   1311     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
   1312         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
   1313       Sched<[WriteI, ReadI, ReadI]> {
   1314   let Uses = [NZCV];
   1315   bits<5> Rd;
   1316   bits<5> Rn;
   1317   bits<5> Rm;
   1318   let Inst{30}    = isSub;
   1319   let Inst{28-21} = 0b11010000;
   1320   let Inst{20-16} = Rm;
   1321   let Inst{15-10} = 0;
   1322   let Inst{9-5}   = Rn;
   1323   let Inst{4-0}   = Rd;
   1324 }
   1325 
   1326 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
   1327                       SDNode OpNode>
   1328     : BaseBaseAddSubCarry<isSub, regtype, asm,
   1329         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
   1330 
   1331 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
   1332                               SDNode OpNode>
   1333     : BaseBaseAddSubCarry<isSub, regtype, asm,
   1334         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
   1335          (implicit NZCV)]> {
   1336   let Defs = [NZCV];
   1337 }
   1338 
   1339 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
   1340                        SDNode OpNode, SDNode OpNode_setflags> {
   1341   def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
   1342     let Inst{31} = 0;
   1343     let Inst{29} = 0;
   1344   }
   1345   def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
   1346     let Inst{31} = 1;
   1347     let Inst{29} = 0;
   1348   }
   1349 
   1350   // Sets flags.
   1351   def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
   1352                                     OpNode_setflags> {
   1353     let Inst{31} = 0;
   1354     let Inst{29} = 1;
   1355   }
   1356   def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
   1357                                     OpNode_setflags> {
   1358     let Inst{31} = 1;
   1359     let Inst{29} = 1;
   1360   }
   1361 }
   1362 
   1363 class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
   1364                      SDPatternOperator OpNode>
   1365   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
   1366       asm, "\t$Rd, $Rn, $Rm", "",
   1367       [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
   1368   bits<5> Rd;
   1369   bits<5> Rn;
   1370   bits<5> Rm;
   1371   let Inst{30-21} = 0b0011010110;
   1372   let Inst{20-16} = Rm;
   1373   let Inst{15-14} = 0b00;
   1374   let Inst{13-10} = opc;
   1375   let Inst{9-5}   = Rn;
   1376   let Inst{4-0}   = Rd;
   1377 }
   1378 
   1379 class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
   1380               SDPatternOperator OpNode>
   1381     : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
   1382   let Inst{10}    = isSigned;
   1383 }
   1384 
   1385 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
   1386   def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
   1387            Sched<[WriteID32, ReadID, ReadID]> {
   1388     let Inst{31} = 0;
   1389   }
   1390   def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
   1391            Sched<[WriteID64, ReadID, ReadID]> {
   1392     let Inst{31} = 1;
   1393   }
   1394 }
   1395 
   1396 class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
   1397                 SDPatternOperator OpNode = null_frag>
   1398   : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
   1399     Sched<[WriteIS, ReadI]> {
   1400   let Inst{11-10} = shift_type;
   1401 }
   1402 
   1403 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
   1404   def Wr : BaseShift<shift_type, GPR32, asm> {
   1405     let Inst{31} = 0;
   1406   }
   1407 
   1408   def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
   1409     let Inst{31} = 1;
   1410   }
   1411 
   1412   def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
   1413             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
   1414                                              (EXTRACT_SUBREG i64:$Rm, sub_32))>;
   1415 
   1416   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
   1417             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
   1418 
   1419   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
   1420             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
   1421 
   1422   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
   1423             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
   1424 }
   1425 
   1426 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
   1427     : InstAlias<asm#"\t$dst, $src1, $src2",
   1428                 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
   1429 
   1430 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
   1431                        RegisterClass addtype, string asm,
   1432                        list<dag> pattern>
   1433   : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
   1434       asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
   1435   bits<5> Rd;
   1436   bits<5> Rn;
   1437   bits<5> Rm;
   1438   bits<5> Ra;
   1439   let Inst{30-24} = 0b0011011;
   1440   let Inst{23-21} = opc;
   1441   let Inst{20-16} = Rm;
   1442   let Inst{15}    = isSub;
   1443   let Inst{14-10} = Ra;
   1444   let Inst{9-5}   = Rn;
   1445   let Inst{4-0}   = Rd;
   1446 }
   1447 
   1448 multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
   1449   // MADD/MSUB generation is decided by MachineCombiner.cpp
   1450   def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
   1451       [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
   1452       Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
   1453     let Inst{31} = 0;
   1454   }
   1455 
   1456   def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
   1457       [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
   1458       Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
   1459     let Inst{31} = 1;
   1460   }
   1461 }
   1462 
   1463 class WideMulAccum<bit isSub, bits<3> opc, string asm,
   1464                    SDNode AccNode, SDNode ExtNode>
   1465   : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
   1466     [(set GPR64:$Rd, (AccNode GPR64:$Ra,
   1467                             (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
   1468     Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
   1469   let Inst{31} = 1;
   1470 }
   1471 
   1472 class MulHi<bits<3> opc, string asm, SDNode OpNode>
   1473   : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
   1474       asm, "\t$Rd, $Rn, $Rm", "",
   1475       [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
   1476     Sched<[WriteIM64, ReadIM, ReadIM]> {
   1477   bits<5> Rd;
   1478   bits<5> Rn;
   1479   bits<5> Rm;
   1480   let Inst{31-24} = 0b10011011;
   1481   let Inst{23-21} = opc;
   1482   let Inst{20-16} = Rm;
   1483   let Inst{15}    = 0;
   1484   let Inst{9-5}   = Rn;
   1485   let Inst{4-0}   = Rd;
   1486 
   1487   // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
   1488   // (i.e. all bits 1) but is ignored by the processor.
   1489   let PostEncoderMethod = "fixMulHigh";
   1490 }
   1491 
   1492 class MulAccumWAlias<string asm, Instruction inst>
   1493     : InstAlias<asm#"\t$dst, $src1, $src2",
   1494                 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
   1495 class MulAccumXAlias<string asm, Instruction inst>
   1496     : InstAlias<asm#"\t$dst, $src1, $src2",
   1497                 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
   1498 class WideMulAccumAlias<string asm, Instruction inst>
   1499     : InstAlias<asm#"\t$dst, $src1, $src2",
   1500                 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
   1501 
   1502 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
   1503               SDPatternOperator OpNode, string asm>
   1504   : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
   1505       asm, "\t$Rd, $Rn, $Rm", "",
   1506       [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
   1507     Sched<[WriteISReg, ReadI, ReadISReg]> {
   1508   bits<5> Rd;
   1509   bits<5> Rn;
   1510   bits<5> Rm;
   1511 
   1512   let Inst{31} = sf;
   1513   let Inst{30-21} = 0b0011010110;
   1514   let Inst{20-16} = Rm;
   1515   let Inst{15-13} = 0b010;
   1516   let Inst{12} = C;
   1517   let Inst{11-10} = sz;
   1518   let Inst{9-5} = Rn;
   1519   let Inst{4-0} = Rd;
   1520   let Predicates = [HasCRC];
   1521 }
   1522 
   1523 //---
   1524 // Address generation.
   1525 //---
   1526 
   1527 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
   1528     : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
   1529         pattern>,
   1530       Sched<[WriteI]> {
   1531   bits<5>  Xd;
   1532   bits<21> label;
   1533   let Inst{31}    = page;
   1534   let Inst{30-29} = label{1-0};
   1535   let Inst{28-24} = 0b10000;
   1536   let Inst{23-5}  = label{20-2};
   1537   let Inst{4-0}   = Xd;
   1538 
   1539   let DecoderMethod = "DecodeAdrInstruction";
   1540 }
   1541 
   1542 //---
   1543 // Move immediate.
   1544 //---
   1545 
   1546 def movimm32_imm : Operand<i32> {
   1547   let ParserMatchClass = Imm0_65535Operand;
   1548   let EncoderMethod = "getMoveWideImmOpValue";
   1549   let PrintMethod = "printImm";
   1550 }
   1551 def movimm32_shift : Operand<i32> {
   1552   let PrintMethod = "printShifter";
   1553   let ParserMatchClass = MovImm32ShifterOperand;
   1554 }
   1555 def movimm64_shift : Operand<i32> {
   1556   let PrintMethod = "printShifter";
   1557   let ParserMatchClass = MovImm64ShifterOperand;
   1558 }
   1559 
   1560 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   1561 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
   1562                         string asm>
   1563   : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
   1564        asm, "\t$Rd, $imm$shift", "", []>,
   1565     Sched<[WriteImm]> {
   1566   bits<5> Rd;
   1567   bits<16> imm;
   1568   bits<6> shift;
   1569   let Inst{30-29} = opc;
   1570   let Inst{28-23} = 0b100101;
   1571   let Inst{22-21} = shift{5-4};
   1572   let Inst{20-5}  = imm;
   1573   let Inst{4-0}   = Rd;
   1574 
   1575   let DecoderMethod = "DecodeMoveImmInstruction";
   1576 }
   1577 
   1578 multiclass MoveImmediate<bits<2> opc, string asm> {
   1579   def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
   1580     let Inst{31} = 0;
   1581   }
   1582 
   1583   def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
   1584     let Inst{31} = 1;
   1585   }
   1586 }
   1587 
   1588 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   1589 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
   1590                           string asm>
   1591   : I<(outs regtype:$Rd),
   1592       (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
   1593        asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
   1594     Sched<[WriteI, ReadI]> {
   1595   bits<5> Rd;
   1596   bits<16> imm;
   1597   bits<6> shift;
   1598   let Inst{30-29} = opc;
   1599   let Inst{28-23} = 0b100101;
   1600   let Inst{22-21} = shift{5-4};
   1601   let Inst{20-5}  = imm;
   1602   let Inst{4-0}   = Rd;
   1603 
   1604   let DecoderMethod = "DecodeMoveImmInstruction";
   1605 }
   1606 
   1607 multiclass InsertImmediate<bits<2> opc, string asm> {
   1608   def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
   1609     let Inst{31} = 0;
   1610   }
   1611 
   1612   def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
   1613     let Inst{31} = 1;
   1614   }
   1615 }
   1616 
   1617 //---
   1618 // Add/Subtract
   1619 //---
   1620 
   1621 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
   1622                     RegisterClass srcRegtype, addsub_shifted_imm immtype,
   1623                     string asm, SDPatternOperator OpNode>
   1624     : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
   1625         asm, "\t$Rd, $Rn, $imm", "",
   1626         [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
   1627       Sched<[WriteI, ReadI]>  {
   1628   bits<5>  Rd;
   1629   bits<5>  Rn;
   1630   bits<14> imm;
   1631   let Inst{30}    = isSub;
   1632   let Inst{29}    = setFlags;
   1633   let Inst{28-24} = 0b10001;
   1634   let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
   1635   let Inst{21-10} = imm{11-0};
   1636   let Inst{9-5}   = Rn;
   1637   let Inst{4-0}   = Rd;
   1638   let DecoderMethod = "DecodeBaseAddSubImm";
   1639 }
   1640 
   1641 class BaseAddSubRegPseudo<RegisterClass regtype,
   1642                           SDPatternOperator OpNode>
   1643     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
   1644              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
   1645       Sched<[WriteI, ReadI, ReadI]>;
   1646 
   1647 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
   1648                      arith_shifted_reg shifted_regtype, string asm,
   1649                      SDPatternOperator OpNode>
   1650     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
   1651         asm, "\t$Rd, $Rn, $Rm", "",
   1652         [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
   1653       Sched<[WriteISReg, ReadI, ReadISReg]> {
   1654   // The operands are in order to match the 'addr' MI operands, so we
   1655   // don't need an encoder method and by-name matching. Just use the default
   1656   // in-order handling. Since we're using by-order, make sure the names
   1657   // do not match.
   1658   bits<5> dst;
   1659   bits<5> src1;
   1660   bits<5> src2;
   1661   bits<8> shift;
   1662   let Inst{30}    = isSub;
   1663   let Inst{29}    = setFlags;
   1664   let Inst{28-24} = 0b01011;
   1665   let Inst{23-22} = shift{7-6};
   1666   let Inst{21}    = 0;
   1667   let Inst{20-16} = src2;
   1668   let Inst{15-10} = shift{5-0};
   1669   let Inst{9-5}   = src1;
   1670   let Inst{4-0}   = dst;
   1671 
   1672   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
   1673 }
   1674 
   1675 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
   1676                      RegisterClass src1Regtype, Operand src2Regtype,
   1677                      string asm, SDPatternOperator OpNode>
   1678     : I<(outs dstRegtype:$R1),
   1679         (ins src1Regtype:$R2, src2Regtype:$R3),
   1680         asm, "\t$R1, $R2, $R3", "",
   1681         [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
   1682       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
   1683   bits<5> Rd;
   1684   bits<5> Rn;
   1685   bits<5> Rm;
   1686   bits<6> ext;
   1687   let Inst{30}    = isSub;
   1688   let Inst{29}    = setFlags;
   1689   let Inst{28-24} = 0b01011;
   1690   let Inst{23-21} = 0b001;
   1691   let Inst{20-16} = Rm;
   1692   let Inst{15-13} = ext{5-3};
   1693   let Inst{12-10} = ext{2-0};
   1694   let Inst{9-5}   = Rn;
   1695   let Inst{4-0}   = Rd;
   1696 
   1697   let DecoderMethod = "DecodeAddSubERegInstruction";
   1698 }
   1699 
   1700 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   1701 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
   1702                        RegisterClass src1Regtype, RegisterClass src2Regtype,
   1703                        Operand ext_op, string asm>
   1704     : I<(outs dstRegtype:$Rd),
   1705         (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
   1706         asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
   1707       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
   1708   bits<5> Rd;
   1709   bits<5> Rn;
   1710   bits<5> Rm;
   1711   bits<6> ext;
   1712   let Inst{30}    = isSub;
   1713   let Inst{29}    = setFlags;
   1714   let Inst{28-24} = 0b01011;
   1715   let Inst{23-21} = 0b001;
   1716   let Inst{20-16} = Rm;
   1717   let Inst{15}    = ext{5};
   1718   let Inst{12-10} = ext{2-0};
   1719   let Inst{9-5}   = Rn;
   1720   let Inst{4-0}   = Rd;
   1721 
   1722   let DecoderMethod = "DecodeAddSubERegInstruction";
   1723 }
   1724 
   1725 // Aliases for register+register add/subtract.
   1726 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
   1727                      RegisterClass src1Regtype, RegisterClass src2Regtype,
   1728                      int shiftExt>
   1729     : InstAlias<asm#"\t$dst, $src1, $src2",
   1730                 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
   1731                       shiftExt)>;
   1732 
   1733 multiclass AddSub<bit isSub, string mnemonic, string alias,
   1734                   SDPatternOperator OpNode = null_frag> {
   1735   let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
   1736   // Add/Subtract immediate
   1737   // Increase the weight of the immediate variant to try to match it before
   1738   // the extended register variant.
   1739   // We used to match the register variant before the immediate when the
   1740   // register argument could be implicitly zero-extended.
   1741   let AddedComplexity = 6 in
   1742   def Wri  : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
   1743                            mnemonic, OpNode> {
   1744     let Inst{31} = 0;
   1745   }
   1746   let AddedComplexity = 6 in
   1747   def Xri  : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
   1748                            mnemonic, OpNode> {
   1749     let Inst{31} = 1;
   1750   }
   1751 
   1752   // Add/Subtract register - Only used for CodeGen
   1753   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
   1754   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
   1755 
   1756   // Add/Subtract shifted register
   1757   def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
   1758                            OpNode> {
   1759     let Inst{31} = 0;
   1760   }
   1761   def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
   1762                            OpNode> {
   1763     let Inst{31} = 1;
   1764   }
   1765   }
   1766 
   1767   // Add/Subtract extended register
   1768   let AddedComplexity = 1, hasSideEffects = 0 in {
   1769   def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
   1770                            arith_extended_reg32<i32>, mnemonic, OpNode> {
   1771     let Inst{31} = 0;
   1772   }
   1773   def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
   1774                            arith_extended_reg32to64<i64>, mnemonic, OpNode> {
   1775     let Inst{31} = 1;
   1776   }
   1777   }
   1778 
   1779   def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
   1780                                arith_extendlsl64, mnemonic> {
   1781     // UXTX and SXTX only.
   1782     let Inst{14-13} = 0b11;
   1783     let Inst{31} = 1;
   1784   }
   1785 
   1786   // add Rd, Rb, -imm -> sub Rd, Rn, imm
   1787   def : InstAlias<alias#"\t$Rd, $Rn, $imm",
   1788                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
   1789                       addsub_shifted_imm32_neg:$imm), 0>;
   1790   def : InstAlias<alias#"\t$Rd, $Rn, $imm",
   1791                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
   1792                        addsub_shifted_imm64_neg:$imm), 0>;
   1793 
   1794   // Register/register aliases with no shift when SP is not used.
   1795   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
   1796                        GPR32, GPR32, GPR32, 0>;
   1797   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
   1798                        GPR64, GPR64, GPR64, 0>;
   1799 
   1800   // Register/register aliases with no shift when either the destination or
   1801   // first source register is SP.
   1802   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
   1803                        GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
   1804   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
   1805                        GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
   1806   def : AddSubRegAlias<mnemonic,
   1807                        !cast<Instruction>(NAME#"Xrx64"),
   1808                        GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
   1809   def : AddSubRegAlias<mnemonic,
   1810                        !cast<Instruction>(NAME#"Xrx64"),
   1811                        GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
   1812 }
   1813 
   1814 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
   1815                    string alias, string cmpAlias> {
   1816   let isCompare = 1, Defs = [NZCV] in {
   1817   // Add/Subtract immediate
   1818   def Wri  : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
   1819                            mnemonic, OpNode> {
   1820     let Inst{31} = 0;
   1821   }
   1822   def Xri  : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
   1823                            mnemonic, OpNode> {
   1824     let Inst{31} = 1;
   1825   }
   1826 
   1827   // Add/Subtract register
   1828   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
   1829   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
   1830 
   1831   // Add/Subtract shifted register
   1832   def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
   1833                            OpNode> {
   1834     let Inst{31} = 0;
   1835   }
   1836   def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
   1837                            OpNode> {
   1838     let Inst{31} = 1;
   1839   }
   1840 
   1841   // Add/Subtract extended register
   1842   let AddedComplexity = 1 in {
   1843   def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
   1844                            arith_extended_reg32<i32>, mnemonic, OpNode> {
   1845     let Inst{31} = 0;
   1846   }
   1847   def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
   1848                            arith_extended_reg32<i64>, mnemonic, OpNode> {
   1849     let Inst{31} = 1;
   1850   }
   1851   }
   1852 
   1853   def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
   1854                                arith_extendlsl64, mnemonic> {
   1855     // UXTX and SXTX only.
   1856     let Inst{14-13} = 0b11;
   1857     let Inst{31} = 1;
   1858   }
   1859   } // Defs = [NZCV]
   1860 
   1861   // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
   1862   def : InstAlias<alias#"\t$Rd, $Rn, $imm",
   1863                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
   1864                       addsub_shifted_imm32_neg:$imm), 0>;
   1865   def : InstAlias<alias#"\t$Rd, $Rn, $imm",
   1866                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
   1867                        addsub_shifted_imm64_neg:$imm), 0>;
   1868 
   1869   // Compare aliases
   1870   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
   1871                   WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
   1872   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
   1873                   XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
   1874   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
   1875                   WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
   1876   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
   1877                   XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
   1878   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
   1879                   XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
   1880   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
   1881                   WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
   1882   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
   1883                   XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
   1884 
   1885   // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
   1886   def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
   1887                   WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
   1888   def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
   1889                   XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
   1890 
   1891   // Compare shorthands
   1892   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
   1893                   WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
   1894   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
   1895                   XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
   1896   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
   1897                   WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
   1898   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
   1899                   XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
   1900 
   1901   // Register/register aliases with no shift when SP is not used.
   1902   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
   1903                        GPR32, GPR32, GPR32, 0>;
   1904   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
   1905                        GPR64, GPR64, GPR64, 0>;
   1906 
   1907   // Register/register aliases with no shift when the first source register
   1908   // is SP.
   1909   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
   1910                        GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
   1911   def : AddSubRegAlias<mnemonic,
   1912                        !cast<Instruction>(NAME#"Xrx64"),
   1913                        GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
   1914 }
   1915 
   1916 //---
   1917 // Extract
   1918 //---
   1919 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
   1920                                       SDTCisPtrTy<3>]>;
   1921 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
   1922 
   1923 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
   1924                      list<dag> patterns>
   1925     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
   1926          asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
   1927       Sched<[WriteExtr, ReadExtrHi]> {
   1928   bits<5> Rd;
   1929   bits<5> Rn;
   1930   bits<5> Rm;
   1931   bits<6> imm;
   1932 
   1933   let Inst{30-23} = 0b00100111;
   1934   let Inst{21}    = 0;
   1935   let Inst{20-16} = Rm;
   1936   let Inst{15-10} = imm;
   1937   let Inst{9-5}   = Rn;
   1938   let Inst{4-0}   = Rd;
   1939 }
   1940 
   1941 multiclass ExtractImm<string asm> {
   1942   def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
   1943                       [(set GPR32:$Rd,
   1944                         (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
   1945     let Inst{31} = 0;
   1946     let Inst{22} = 0;
   1947     // imm<5> must be zero.
   1948     let imm{5}   = 0;
   1949   }
   1950   def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
   1951                       [(set GPR64:$Rd,
   1952                         (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
   1953 
   1954     let Inst{31} = 1;
   1955     let Inst{22} = 1;
   1956   }
   1957 }
   1958 
   1959 //---
   1960 // Bitfield
   1961 //---
   1962 
   1963 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   1964 class BaseBitfieldImm<bits<2> opc,
   1965                       RegisterClass regtype, Operand imm_type, string asm>
   1966     : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
   1967          asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
   1968       Sched<[WriteIS, ReadI]> {
   1969   bits<5> Rd;
   1970   bits<5> Rn;
   1971   bits<6> immr;
   1972   bits<6> imms;
   1973 
   1974   let Inst{30-29} = opc;
   1975   let Inst{28-23} = 0b100110;
   1976   let Inst{21-16} = immr;
   1977   let Inst{15-10} = imms;
   1978   let Inst{9-5}   = Rn;
   1979   let Inst{4-0}   = Rd;
   1980 }
   1981 
   1982 multiclass BitfieldImm<bits<2> opc, string asm> {
   1983   def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
   1984     let Inst{31} = 0;
   1985     let Inst{22} = 0;
   1986     // imms<5> and immr<5> must be zero, else ReservedValue().
   1987     let Inst{21} = 0;
   1988     let Inst{15} = 0;
   1989   }
   1990   def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
   1991     let Inst{31} = 1;
   1992     let Inst{22} = 1;
   1993   }
   1994 }
   1995 
   1996 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   1997 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
   1998                       RegisterClass regtype, Operand imm_type, string asm>
   1999     : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
   2000                              imm_type:$imms),
   2001          asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
   2002       Sched<[WriteIS, ReadI]> {
   2003   bits<5> Rd;
   2004   bits<5> Rn;
   2005   bits<6> immr;
   2006   bits<6> imms;
   2007 
   2008   let Inst{30-29} = opc;
   2009   let Inst{28-23} = 0b100110;
   2010   let Inst{21-16} = immr;
   2011   let Inst{15-10} = imms;
   2012   let Inst{9-5}   = Rn;
   2013   let Inst{4-0}   = Rd;
   2014 }
   2015 
   2016 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
   2017   def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
   2018     let Inst{31} = 0;
   2019     let Inst{22} = 0;
   2020     // imms<5> and immr<5> must be zero, else ReservedValue().
   2021     let Inst{21} = 0;
   2022     let Inst{15} = 0;
   2023   }
   2024   def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
   2025     let Inst{31} = 1;
   2026     let Inst{22} = 1;
   2027   }
   2028 }
   2029 
   2030 //---
   2031 // Logical
   2032 //---
   2033 
   2034 // Logical (immediate)
   2035 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
   2036                      RegisterClass sregtype, Operand imm_type, string asm,
   2037                      list<dag> pattern>
   2038     : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
   2039          asm, "\t$Rd, $Rn, $imm", "", pattern>,
   2040       Sched<[WriteI, ReadI]> {
   2041   bits<5>  Rd;
   2042   bits<5>  Rn;
   2043   bits<13> imm;
   2044   let Inst{30-29} = opc;
   2045   let Inst{28-23} = 0b100100;
   2046   let Inst{22}    = imm{12};
   2047   let Inst{21-16} = imm{11-6};
   2048   let Inst{15-10} = imm{5-0};
   2049   let Inst{9-5}   = Rn;
   2050   let Inst{4-0}   = Rd;
   2051 
   2052   let DecoderMethod = "DecodeLogicalImmInstruction";
   2053 }
   2054 
   2055 // Logical (shifted register)
   2056 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
   2057                       logical_shifted_reg shifted_regtype, string asm,
   2058                       list<dag> pattern>
   2059     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
   2060         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
   2061       Sched<[WriteISReg, ReadI, ReadISReg]> {
   2062   // The operands are in order to match the 'addr' MI operands, so we
   2063   // don't need an encoder method and by-name matching. Just use the default
   2064   // in-order handling. Since we're using by-order, make sure the names
   2065   // do not match.
   2066   bits<5> dst;
   2067   bits<5> src1;
   2068   bits<5> src2;
   2069   bits<8> shift;
   2070   let Inst{30-29} = opc;
   2071   let Inst{28-24} = 0b01010;
   2072   let Inst{23-22} = shift{7-6};
   2073   let Inst{21}    = N;
   2074   let Inst{20-16} = src2;
   2075   let Inst{15-10} = shift{5-0};
   2076   let Inst{9-5}   = src1;
   2077   let Inst{4-0}   = dst;
   2078 
   2079   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
   2080 }
   2081 
   2082 // Aliases for register+register logical instructions.
   2083 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
   2084     : InstAlias<asm#"\t$dst, $src1, $src2",
   2085                 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
   2086 
   2087 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
   2088                       string Alias> {
   2089   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
   2090   def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
   2091                            [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
   2092                                                logical_imm32:$imm))]> {
   2093     let Inst{31} = 0;
   2094     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
   2095   }
   2096   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
   2097   def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
   2098                            [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
   2099                                                logical_imm64:$imm))]> {
   2100     let Inst{31} = 1;
   2101   }
   2102 
   2103   def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
   2104                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
   2105                       logical_imm32_not:$imm), 0>;
   2106   def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
   2107                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
   2108                        logical_imm64_not:$imm), 0>;
   2109 }
   2110 
   2111 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
   2112                        string Alias> {
   2113   let isCompare = 1, Defs = [NZCV] in {
   2114   def Wri  : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
   2115       [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
   2116     let Inst{31} = 0;
   2117     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
   2118   }
   2119   def Xri  : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
   2120       [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
   2121     let Inst{31} = 1;
   2122   }
   2123   } // end Defs = [NZCV]
   2124 
   2125   def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
   2126                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
   2127                       logical_imm32_not:$imm), 0>;
   2128   def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
   2129                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
   2130                        logical_imm64_not:$imm), 0>;
   2131 }
   2132 
   2133 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
   2134     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
   2135              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
   2136       Sched<[WriteI, ReadI, ReadI]>;
   2137 
   2138 // Split from LogicalImm as not all instructions have both.
   2139 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
   2140                       SDPatternOperator OpNode> {
   2141   let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
   2142   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
   2143   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
   2144   }
   2145 
   2146   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
   2147                             [(set GPR32:$Rd, (OpNode GPR32:$Rn,
   2148                                                  logical_shifted_reg32:$Rm))]> {
   2149     let Inst{31} = 0;
   2150   }
   2151   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
   2152                             [(set GPR64:$Rd, (OpNode GPR64:$Rn,
   2153                                                  logical_shifted_reg64:$Rm))]> {
   2154     let Inst{31} = 1;
   2155   }
   2156 
   2157   def : LogicalRegAlias<mnemonic,
   2158                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
   2159   def : LogicalRegAlias<mnemonic,
   2160                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
   2161 }
   2162 
   2163 // Split from LogicalReg to allow setting NZCV Defs
   2164 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
   2165                        SDPatternOperator OpNode = null_frag> {
   2166   let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
   2167   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
   2168   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
   2169 
   2170   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
   2171             [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
   2172     let Inst{31} = 0;
   2173   }
   2174   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
   2175             [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
   2176     let Inst{31} = 1;
   2177   }
   2178   } // Defs = [NZCV]
   2179 
   2180   def : LogicalRegAlias<mnemonic,
   2181                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
   2182   def : LogicalRegAlias<mnemonic,
   2183                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
   2184 }
   2185 
   2186 //---
   2187 // Conditionally set flags
   2188 //---
   2189 
   2190 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   2191 class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
   2192                             string mnemonic, SDNode OpNode>
   2193     : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
   2194          mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
   2195          [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
   2196                              (i32 imm:$cond), NZCV))]>,
   2197       Sched<[WriteI, ReadI]> {
   2198   let Uses = [NZCV];
   2199   let Defs = [NZCV];
   2200 
   2201   bits<5> Rn;
   2202   bits<5> imm;
   2203   bits<4> nzcv;
   2204   bits<4> cond;
   2205 
   2206   let Inst{30}    = op;
   2207   let Inst{29-21} = 0b111010010;
   2208   let Inst{20-16} = imm;
   2209   let Inst{15-12} = cond;
   2210   let Inst{11-10} = 0b10;
   2211   let Inst{9-5}   = Rn;
   2212   let Inst{4}     = 0b0;
   2213   let Inst{3-0}   = nzcv;
   2214 }
   2215 
   2216 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   2217 class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
   2218                             SDNode OpNode>
   2219     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
   2220          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
   2221          [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
   2222                              (i32 imm:$cond), NZCV))]>,
   2223       Sched<[WriteI, ReadI, ReadI]> {
   2224   let Uses = [NZCV];
   2225   let Defs = [NZCV];
   2226 
   2227   bits<5> Rn;
   2228   bits<5> Rm;
   2229   bits<4> nzcv;
   2230   bits<4> cond;
   2231 
   2232   let Inst{30}    = op;
   2233   let Inst{29-21} = 0b111010010;
   2234   let Inst{20-16} = Rm;
   2235   let Inst{15-12} = cond;
   2236   let Inst{11-10} = 0b00;
   2237   let Inst{9-5}   = Rn;
   2238   let Inst{4}     = 0b0;
   2239   let Inst{3-0}   = nzcv;
   2240 }
   2241 
   2242 multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
   2243   // immediate operand variants
   2244   def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
   2245     let Inst{31} = 0;
   2246   }
   2247   def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
   2248     let Inst{31} = 1;
   2249   }
   2250   // register operand variants
   2251   def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
   2252     let Inst{31} = 0;
   2253   }
   2254   def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
   2255     let Inst{31} = 1;
   2256   }
   2257 }
   2258 
   2259 //---
   2260 // Conditional select
   2261 //---
   2262 
   2263 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
   2264     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
   2265          asm, "\t$Rd, $Rn, $Rm, $cond", "",
   2266          [(set regtype:$Rd,
   2267                (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
   2268       Sched<[WriteI, ReadI, ReadI]> {
   2269   let Uses = [NZCV];
   2270 
   2271   bits<5> Rd;
   2272   bits<5> Rn;
   2273   bits<5> Rm;
   2274   bits<4> cond;
   2275 
   2276   let Inst{30}    = op;
   2277   let Inst{29-21} = 0b011010100;
   2278   let Inst{20-16} = Rm;
   2279   let Inst{15-12} = cond;
   2280   let Inst{11-10} = op2;
   2281   let Inst{9-5}   = Rn;
   2282   let Inst{4-0}   = Rd;
   2283 }
   2284 
   2285 multiclass CondSelect<bit op, bits<2> op2, string asm> {
   2286   def Wr : BaseCondSelect<op, op2, GPR32, asm> {
   2287     let Inst{31} = 0;
   2288   }
   2289   def Xr : BaseCondSelect<op, op2, GPR64, asm> {
   2290     let Inst{31} = 1;
   2291   }
   2292 }
   2293 
   2294 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
   2295                        PatFrag frag>
   2296     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
   2297          asm, "\t$Rd, $Rn, $Rm, $cond", "",
   2298          [(set regtype:$Rd,
   2299                (AArch64csel regtype:$Rn, (frag regtype:$Rm),
   2300                (i32 imm:$cond), NZCV))]>,
   2301       Sched<[WriteI, ReadI, ReadI]> {
   2302   let Uses = [NZCV];
   2303 
   2304   bits<5> Rd;
   2305   bits<5> Rn;
   2306   bits<5> Rm;
   2307   bits<4> cond;
   2308 
   2309   let Inst{30}    = op;
   2310   let Inst{29-21} = 0b011010100;
   2311   let Inst{20-16} = Rm;
   2312   let Inst{15-12} = cond;
   2313   let Inst{11-10} = op2;
   2314   let Inst{9-5}   = Rn;
   2315   let Inst{4-0}   = Rd;
   2316 }
   2317 
   2318 def inv_cond_XFORM : SDNodeXForm<imm, [{
   2319   AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
   2320   return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
   2321                                    MVT::i32);
   2322 }]>;
   2323 
   2324 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
   2325   def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
   2326     let Inst{31} = 0;
   2327   }
   2328   def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
   2329     let Inst{31} = 1;
   2330   }
   2331 
   2332   def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
   2333             (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
   2334                                            (inv_cond_XFORM imm:$cond))>;
   2335 
   2336   def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
   2337             (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
   2338                                            (inv_cond_XFORM imm:$cond))>;
   2339 }
   2340 
   2341 //---
   2342 // Special Mask Value
   2343 //---
   2344 def maski8_or_more : Operand<i32>,
   2345   ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
   2346 }
   2347 def maski16_or_more : Operand<i32>,
   2348   ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
   2349 }
   2350 
   2351 
   2352 //---
   2353 // Load/store
   2354 //---
   2355 
   2356 // (unsigned immediate)
   2357 // Indexed for 8-bit registers. offset is in range [0,4095].
   2358 def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
   2359 def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
   2360 def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
   2361 def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
   2362 def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
   2363 
   2364 class UImm12OffsetOperand<int Scale> : AsmOperandClass {
   2365   let Name = "UImm12Offset" # Scale;
   2366   let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
   2367   let PredicateMethod = "isUImm12Offset<" # Scale # ">";
   2368   let DiagnosticType = "InvalidMemoryIndexed" # Scale;
   2369 }
   2370 
   2371 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
   2372 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
   2373 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
   2374 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
   2375 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
   2376 
   2377 class uimm12_scaled<int Scale> : Operand<i64> {
   2378   let ParserMatchClass
   2379    = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
   2380   let EncoderMethod
   2381    = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
   2382   let PrintMethod = "printUImm12Offset<" # Scale # ">";
   2383 }
   2384 
   2385 def uimm12s1 : uimm12_scaled<1>;
   2386 def uimm12s2 : uimm12_scaled<2>;
   2387 def uimm12s4 : uimm12_scaled<4>;
   2388 def uimm12s8 : uimm12_scaled<8>;
   2389 def uimm12s16 : uimm12_scaled<16>;
   2390 
   2391 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
   2392                       string asm, list<dag> pattern>
   2393     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
   2394   bits<5> Rt;
   2395 
   2396   bits<5> Rn;
   2397   bits<12> offset;
   2398 
   2399   let Inst{31-30} = sz;
   2400   let Inst{29-27} = 0b111;
   2401   let Inst{26}    = V;
   2402   let Inst{25-24} = 0b01;
   2403   let Inst{23-22} = opc;
   2404   let Inst{21-10} = offset;
   2405   let Inst{9-5}   = Rn;
   2406   let Inst{4-0}   = Rt;
   2407 
   2408   let DecoderMethod = "DecodeUnsignedLdStInstruction";
   2409 }
   2410 
   2411 multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2412                   Operand indextype, string asm, list<dag> pattern> {
   2413   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   2414   def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
   2415                            (ins GPR64sp:$Rn, indextype:$offset),
   2416                            asm, pattern>,
   2417            Sched<[WriteLD]>;
   2418 
   2419   def : InstAlias<asm # "\t$Rt, [$Rn]",
   2420                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
   2421 }
   2422 
   2423 multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2424              Operand indextype, string asm, list<dag> pattern> {
   2425   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   2426   def ui : BaseLoadStoreUI<sz, V, opc, (outs),
   2427                            (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
   2428                            asm, pattern>,
   2429            Sched<[WriteST]>;
   2430 
   2431   def : InstAlias<asm # "\t$Rt, [$Rn]",
   2432                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
   2433 }
   2434 
   2435 def PrefetchOperand : AsmOperandClass {
   2436   let Name = "Prefetch";
   2437   let ParserMethod = "tryParsePrefetch";
   2438 }
   2439 def prfop : Operand<i32> {
   2440   let PrintMethod = "printPrefetchOp";
   2441   let ParserMatchClass = PrefetchOperand;
   2442 }
   2443 
   2444 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
   2445 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
   2446     : BaseLoadStoreUI<sz, V, opc,
   2447                       (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
   2448                       asm, pat>,
   2449       Sched<[WriteLD]>;
   2450 
   2451 //---
   2452 // Load literal
   2453 //---
   2454 
   2455 // Load literal address: 19-bit immediate. The low two bits of the target
   2456 // offset are implied zero and so are not part of the immediate.
   2457 def am_ldrlit : Operand<OtherVT> {
   2458   let EncoderMethod = "getLoadLiteralOpValue";
   2459   let DecoderMethod = "DecodePCRelLabel19";
   2460   let PrintMethod = "printAlignedLabel";
   2461   let ParserMatchClass = PCRelLabel19Operand;
   2462 }
   2463 
   2464 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   2465 class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm>
   2466     : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
   2467         asm, "\t$Rt, $label", "", []>,
   2468       Sched<[WriteLD]> {
   2469   bits<5> Rt;
   2470   bits<19> label;
   2471   let Inst{31-30} = opc;
   2472   let Inst{29-27} = 0b011;
   2473   let Inst{26}    = V;
   2474   let Inst{25-24} = 0b00;
   2475   let Inst{23-5}  = label;
   2476   let Inst{4-0}   = Rt;
   2477 }
   2478 
   2479 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
   2480 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
   2481     : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
   2482         asm, "\t$Rt, $label", "", pat>,
   2483       Sched<[WriteLD]> {
   2484   bits<5> Rt;
   2485   bits<19> label;
   2486   let Inst{31-30} = opc;
   2487   let Inst{29-27} = 0b011;
   2488   let Inst{26}    = V;
   2489   let Inst{25-24} = 0b00;
   2490   let Inst{23-5}  = label;
   2491   let Inst{4-0}   = Rt;
   2492 }
   2493 
   2494 //---
   2495 // Load/store register offset
   2496 //---
   2497 
   2498 def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
   2499 def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
   2500 def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
   2501 def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
   2502 def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
   2503 
   2504 def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
   2505 def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
   2506 def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
   2507 def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
   2508 def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
   2509 
   2510 class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
   2511   let Name = "Mem" # Reg # "Extend" # Width;
   2512   let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
   2513   let RenderMethod = "addMemExtendOperands";
   2514   let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
   2515 }
   2516 
   2517 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
   2518   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
   2519   // the trivial shift.
   2520   let RenderMethod = "addMemExtend8Operands";
   2521 }
   2522 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
   2523 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
   2524 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
   2525 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
   2526 
   2527 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
   2528   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
   2529   // the trivial shift.
   2530   let RenderMethod = "addMemExtend8Operands";
   2531 }
   2532 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
   2533 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
   2534 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
   2535 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
   2536 
   2537 class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
   2538         : Operand<i32> {
   2539   let ParserMatchClass = ParserClass;
   2540   let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
   2541   let DecoderMethod = "DecodeMemExtend";
   2542   let EncoderMethod = "getMemExtendOpValue";
   2543   let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
   2544 }
   2545 
   2546 def ro_Wextend8   : ro_extend<MemWExtend8Operand,   "w", 8>;
   2547 def ro_Wextend16  : ro_extend<MemWExtend16Operand,  "w", 16>;
   2548 def ro_Wextend32  : ro_extend<MemWExtend32Operand,  "w", 32>;
   2549 def ro_Wextend64  : ro_extend<MemWExtend64Operand,  "w", 64>;
   2550 def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
   2551 
   2552 def ro_Xextend8   : ro_extend<MemXExtend8Operand,   "x", 8>;
   2553 def ro_Xextend16  : ro_extend<MemXExtend16Operand,  "x", 16>;
   2554 def ro_Xextend32  : ro_extend<MemXExtend32Operand,  "x", 32>;
   2555 def ro_Xextend64  : ro_extend<MemXExtend64Operand,  "x", 64>;
   2556 def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
   2557 
   2558 class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
   2559                   Operand wextend, Operand xextend>  {
   2560   // CodeGen-level pattern covering the entire addressing mode.
   2561   ComplexPattern Wpat = windex;
   2562   ComplexPattern Xpat = xindex;
   2563 
   2564   // Asm-level Operand covering the valid "uxtw #3" style syntax.
   2565   Operand Wext = wextend;
   2566   Operand Xext = xextend;
   2567 }
   2568 
   2569 def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
   2570 def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
   2571 def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
   2572 def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
   2573 def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
   2574                        ro_Xextend128>;
   2575 
   2576 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2577                       string asm, dag ins, dag outs, list<dag> pat>
   2578     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
   2579   bits<5> Rt;
   2580   bits<5> Rn;
   2581   bits<5> Rm;
   2582   bits<2> extend;
   2583   let Inst{31-30} = sz;
   2584   let Inst{29-27} = 0b111;
   2585   let Inst{26}    = V;
   2586   let Inst{25-24} = 0b00;
   2587   let Inst{23-22} = opc;
   2588   let Inst{21}    = 1;
   2589   let Inst{20-16} = Rm;
   2590   let Inst{15}    = extend{1}; // sign extend Rm?
   2591   let Inst{14}    = 1;
   2592   let Inst{12}    = extend{0}; // do shift?
   2593   let Inst{11-10} = 0b10;
   2594   let Inst{9-5}   = Rn;
   2595   let Inst{4-0}   = Rt;
   2596 }
   2597 
   2598 class ROInstAlias<string asm, RegisterClass regtype, Instruction INST>
   2599   : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
   2600               (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
   2601 
   2602 multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2603                    string asm, ValueType Ty, SDPatternOperator loadop> {
   2604   let AddedComplexity = 10 in
   2605   def roW : LoadStore8RO<sz, V, opc, regtype, asm,
   2606                  (outs regtype:$Rt),
   2607                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
   2608                  [(set (Ty regtype:$Rt),
   2609                        (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
   2610                                              ro_Wextend8:$extend)))]>,
   2611            Sched<[WriteLDIdx, ReadAdrBase]> {
   2612     let Inst{13} = 0b0;
   2613   }
   2614 
   2615   let AddedComplexity = 10 in
   2616   def roX : LoadStore8RO<sz, V, opc, regtype, asm,
   2617                  (outs regtype:$Rt),
   2618                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
   2619                  [(set (Ty regtype:$Rt),
   2620                        (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
   2621                                              ro_Xextend8:$extend)))]>,
   2622            Sched<[WriteLDIdx, ReadAdrBase]> {
   2623     let Inst{13} = 0b1;
   2624   }
   2625 
   2626   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2627 }
   2628 
   2629 multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2630                     string asm, ValueType Ty, SDPatternOperator storeop> {
   2631   let AddedComplexity = 10 in
   2632   def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
   2633                  (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
   2634                  [(storeop (Ty regtype:$Rt),
   2635                            (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
   2636                                          ro_Wextend8:$extend))]>,
   2637             Sched<[WriteSTIdx, ReadAdrBase]> {
   2638     let Inst{13} = 0b0;
   2639   }
   2640 
   2641   let AddedComplexity = 10 in
   2642   def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
   2643                  (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
   2644                  [(storeop (Ty regtype:$Rt),
   2645                            (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
   2646                                          ro_Xextend8:$extend))]>,
   2647             Sched<[WriteSTIdx, ReadAdrBase]> {
   2648     let Inst{13} = 0b1;
   2649   }
   2650 
   2651   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2652 }
   2653 
   2654 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2655                       string asm, dag ins, dag outs, list<dag> pat>
   2656     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
   2657   bits<5> Rt;
   2658   bits<5> Rn;
   2659   bits<5> Rm;
   2660   bits<2> extend;
   2661   let Inst{31-30} = sz;
   2662   let Inst{29-27} = 0b111;
   2663   let Inst{26}    = V;
   2664   let Inst{25-24} = 0b00;
   2665   let Inst{23-22} = opc;
   2666   let Inst{21}    = 1;
   2667   let Inst{20-16} = Rm;
   2668   let Inst{15}    = extend{1}; // sign extend Rm?
   2669   let Inst{14}    = 1;
   2670   let Inst{12}    = extend{0}; // do shift?
   2671   let Inst{11-10} = 0b10;
   2672   let Inst{9-5}   = Rn;
   2673   let Inst{4-0}   = Rt;
   2674 }
   2675 
   2676 multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2677                     string asm, ValueType Ty, SDPatternOperator loadop> {
   2678   let AddedComplexity = 10 in
   2679   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2680                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
   2681                  [(set (Ty regtype:$Rt),
   2682                        (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
   2683                                               ro_Wextend16:$extend)))]>,
   2684             Sched<[WriteLDIdx, ReadAdrBase]> {
   2685     let Inst{13} = 0b0;
   2686   }
   2687 
   2688   let AddedComplexity = 10 in
   2689   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2690                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
   2691                  [(set (Ty regtype:$Rt),
   2692                        (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
   2693                                              ro_Xextend16:$extend)))]>,
   2694             Sched<[WriteLDIdx, ReadAdrBase]> {
   2695     let Inst{13} = 0b1;
   2696   }
   2697 
   2698   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2699 }
   2700 
   2701 multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2702                      string asm, ValueType Ty, SDPatternOperator storeop> {
   2703   let AddedComplexity = 10 in
   2704   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
   2705                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
   2706                 [(storeop (Ty regtype:$Rt),
   2707                           (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
   2708                                          ro_Wextend16:$extend))]>,
   2709            Sched<[WriteSTIdx, ReadAdrBase]> {
   2710     let Inst{13} = 0b0;
   2711   }
   2712 
   2713   let AddedComplexity = 10 in
   2714   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
   2715                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
   2716                 [(storeop (Ty regtype:$Rt),
   2717                           (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
   2718                                          ro_Xextend16:$extend))]>,
   2719            Sched<[WriteSTIdx, ReadAdrBase]> {
   2720     let Inst{13} = 0b1;
   2721   }
   2722 
   2723   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2724 }
   2725 
   2726 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2727                       string asm, dag ins, dag outs, list<dag> pat>
   2728     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
   2729   bits<5> Rt;
   2730   bits<5> Rn;
   2731   bits<5> Rm;
   2732   bits<2> extend;
   2733   let Inst{31-30} = sz;
   2734   let Inst{29-27} = 0b111;
   2735   let Inst{26}    = V;
   2736   let Inst{25-24} = 0b00;
   2737   let Inst{23-22} = opc;
   2738   let Inst{21}    = 1;
   2739   let Inst{20-16} = Rm;
   2740   let Inst{15}    = extend{1}; // sign extend Rm?
   2741   let Inst{14}    = 1;
   2742   let Inst{12}    = extend{0}; // do shift?
   2743   let Inst{11-10} = 0b10;
   2744   let Inst{9-5}   = Rn;
   2745   let Inst{4-0}   = Rt;
   2746 }
   2747 
   2748 multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2749                     string asm, ValueType Ty, SDPatternOperator loadop> {
   2750   let AddedComplexity = 10 in
   2751   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2752                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
   2753                  [(set (Ty regtype:$Rt),
   2754                        (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
   2755                                               ro_Wextend32:$extend)))]>,
   2756            Sched<[WriteLDIdx, ReadAdrBase]> {
   2757     let Inst{13} = 0b0;
   2758   }
   2759 
   2760   let AddedComplexity = 10 in
   2761   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2762                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
   2763                  [(set (Ty regtype:$Rt),
   2764                        (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
   2765                                               ro_Xextend32:$extend)))]>,
   2766            Sched<[WriteLDIdx, ReadAdrBase]> {
   2767     let Inst{13} = 0b1;
   2768   }
   2769 
   2770   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2771 }
   2772 
   2773 multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2774                      string asm, ValueType Ty, SDPatternOperator storeop> {
   2775   let AddedComplexity = 10 in
   2776   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
   2777                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
   2778                 [(storeop (Ty regtype:$Rt),
   2779                           (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
   2780                                          ro_Wextend32:$extend))]>,
   2781             Sched<[WriteSTIdx, ReadAdrBase]> {
   2782     let Inst{13} = 0b0;
   2783   }
   2784 
   2785   let AddedComplexity = 10 in
   2786   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
   2787                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
   2788                 [(storeop (Ty regtype:$Rt),
   2789                           (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
   2790                                         ro_Xextend32:$extend))]>,
   2791             Sched<[WriteSTIdx, ReadAdrBase]> {
   2792     let Inst{13} = 0b1;
   2793   }
   2794 
   2795   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2796 }
   2797 
   2798 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2799                       string asm, dag ins, dag outs, list<dag> pat>
   2800     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
   2801   bits<5> Rt;
   2802   bits<5> Rn;
   2803   bits<5> Rm;
   2804   bits<2> extend;
   2805   let Inst{31-30} = sz;
   2806   let Inst{29-27} = 0b111;
   2807   let Inst{26}    = V;
   2808   let Inst{25-24} = 0b00;
   2809   let Inst{23-22} = opc;
   2810   let Inst{21}    = 1;
   2811   let Inst{20-16} = Rm;
   2812   let Inst{15}    = extend{1}; // sign extend Rm?
   2813   let Inst{14}    = 1;
   2814   let Inst{12}    = extend{0}; // do shift?
   2815   let Inst{11-10} = 0b10;
   2816   let Inst{9-5}   = Rn;
   2817   let Inst{4-0}   = Rt;
   2818 }
   2819 
   2820 multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2821                     string asm, ValueType Ty, SDPatternOperator loadop> {
   2822   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   2823   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2824                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
   2825                 [(set (Ty regtype:$Rt),
   2826                       (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
   2827                                              ro_Wextend64:$extend)))]>,
   2828            Sched<[WriteLDIdx, ReadAdrBase]> {
   2829     let Inst{13} = 0b0;
   2830   }
   2831 
   2832   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   2833   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2834                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
   2835                  [(set (Ty regtype:$Rt),
   2836                        (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
   2837                                               ro_Xextend64:$extend)))]>,
   2838            Sched<[WriteLDIdx, ReadAdrBase]> {
   2839     let Inst{13} = 0b1;
   2840   }
   2841 
   2842   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2843 }
   2844 
   2845 multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2846                      string asm, ValueType Ty, SDPatternOperator storeop> {
   2847   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   2848   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
   2849                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
   2850                 [(storeop (Ty regtype:$Rt),
   2851                           (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
   2852                                          ro_Wextend64:$extend))]>,
   2853             Sched<[WriteSTIdx, ReadAdrBase]> {
   2854     let Inst{13} = 0b0;
   2855   }
   2856 
   2857   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   2858   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
   2859                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
   2860                 [(storeop (Ty regtype:$Rt),
   2861                           (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
   2862                                          ro_Xextend64:$extend))]>,
   2863             Sched<[WriteSTIdx, ReadAdrBase]> {
   2864     let Inst{13} = 0b1;
   2865   }
   2866 
   2867   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2868 }
   2869 
   2870 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2871                       string asm, dag ins, dag outs, list<dag> pat>
   2872     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
   2873   bits<5> Rt;
   2874   bits<5> Rn;
   2875   bits<5> Rm;
   2876   bits<2> extend;
   2877   let Inst{31-30} = sz;
   2878   let Inst{29-27} = 0b111;
   2879   let Inst{26}    = V;
   2880   let Inst{25-24} = 0b00;
   2881   let Inst{23-22} = opc;
   2882   let Inst{21}    = 1;
   2883   let Inst{20-16} = Rm;
   2884   let Inst{15}    = extend{1}; // sign extend Rm?
   2885   let Inst{14}    = 1;
   2886   let Inst{12}    = extend{0}; // do shift?
   2887   let Inst{11-10} = 0b10;
   2888   let Inst{9-5}   = Rn;
   2889   let Inst{4-0}   = Rt;
   2890 }
   2891 
   2892 multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2893                      string asm, ValueType Ty, SDPatternOperator loadop> {
   2894   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   2895   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2896                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
   2897                  [(set (Ty regtype:$Rt),
   2898                        (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
   2899                                                ro_Wextend128:$extend)))]>,
   2900             Sched<[WriteLDIdx, ReadAdrBase]> {
   2901     let Inst{13} = 0b0;
   2902   }
   2903 
   2904   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   2905   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2906                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
   2907                  [(set (Ty regtype:$Rt),
   2908                        (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
   2909                                                ro_Xextend128:$extend)))]>,
   2910             Sched<[WriteLDIdx, ReadAdrBase]> {
   2911     let Inst{13} = 0b1;
   2912   }
   2913 
   2914   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2915 }
   2916 
   2917 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2918                       string asm, ValueType Ty, SDPatternOperator storeop> {
   2919   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   2920   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
   2921                (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
   2922                 [(storeop (Ty regtype:$Rt),
   2923                           (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
   2924                                           ro_Wextend128:$extend))]>,
   2925             Sched<[WriteSTIdx, ReadAdrBase]> {
   2926     let Inst{13} = 0b0;
   2927   }
   2928 
   2929   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   2930   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
   2931                (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
   2932                 [(storeop (Ty regtype:$Rt),
   2933                           (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
   2934                                           ro_Xextend128:$extend))]>,
   2935             Sched<[WriteSTIdx, ReadAdrBase]> {
   2936     let Inst{13} = 0b1;
   2937   }
   2938 
   2939   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2940 }
   2941 
   2942 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
   2943 class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
   2944                      string asm, list<dag> pat>
   2945     : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
   2946       Sched<[WriteLD]> {
   2947   bits<5> Rt;
   2948   bits<5> Rn;
   2949   bits<5> Rm;
   2950   bits<2> extend;
   2951   let Inst{31-30} = sz;
   2952   let Inst{29-27} = 0b111;
   2953   let Inst{26}    = V;
   2954   let Inst{25-24} = 0b00;
   2955   let Inst{23-22} = opc;
   2956   let Inst{21}    = 1;
   2957   let Inst{20-16} = Rm;
   2958   let Inst{15}    = extend{1}; // sign extend Rm?
   2959   let Inst{14}    = 1;
   2960   let Inst{12}    = extend{0}; // do shift?
   2961   let Inst{11-10} = 0b10;
   2962   let Inst{9-5}   = Rn;
   2963   let Inst{4-0}   = Rt;
   2964 }
   2965 
   2966 multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
   2967   def roW : BasePrefetchRO<sz, V, opc, (outs),
   2968                 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
   2969                 asm, [(AArch64Prefetch imm:$Rt,
   2970                                      (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
   2971                                                     ro_Wextend64:$extend))]> {
   2972     let Inst{13} = 0b0;
   2973   }
   2974 
   2975   def roX : BasePrefetchRO<sz, V, opc, (outs),
   2976                 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
   2977                 asm,  [(AArch64Prefetch imm:$Rt,
   2978                                       (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
   2979                                                      ro_Xextend64:$extend))]> {
   2980     let Inst{13} = 0b1;
   2981   }
   2982 
   2983   def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
   2984                (!cast<Instruction>(NAME # "roX") prfop:$Rt,
   2985                                                  GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
   2986 }
   2987 
   2988 //---
   2989 // Load/store unscaled immediate
   2990 //---
   2991 
   2992 def am_unscaled8 :  ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
   2993 def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
   2994 def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
   2995 def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
   2996 def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
   2997 
   2998 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
   2999                            string asm, list<dag> pattern>
   3000     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
   3001   bits<5> Rt;
   3002   bits<5> Rn;
   3003   bits<9> offset;
   3004   let Inst{31-30} = sz;
   3005   let Inst{29-27} = 0b111;
   3006   let Inst{26}    = V;
   3007   let Inst{25-24} = 0b00;
   3008   let Inst{23-22} = opc;
   3009   let Inst{21}    = 0;
   3010   let Inst{20-12} = offset;
   3011   let Inst{11-10} = 0b00;
   3012   let Inst{9-5}   = Rn;
   3013   let Inst{4-0}   = Rt;
   3014 
   3015   let DecoderMethod = "DecodeSignedLdStInstruction";
   3016 }
   3017 
   3018 multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   3019                    string asm, list<dag> pattern> {
   3020   let AddedComplexity = 1 in // try this before LoadUI
   3021   def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
   3022                                (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
   3023           Sched<[WriteLD]>;
   3024 
   3025   def : InstAlias<asm # "\t$Rt, [$Rn]",
   3026                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
   3027 }
   3028 
   3029 multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   3030                          string asm, list<dag> pattern> {
   3031   let AddedComplexity = 1 in // try this before StoreUI
   3032   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
   3033                                (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
   3034                                asm, pattern>,
   3035           Sched<[WriteST]>;
   3036 
   3037   def : InstAlias<asm # "\t$Rt, [$Rn]",
   3038                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
   3039 }
   3040 
   3041 multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
   3042                             list<dag> pat> {
   3043   let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
   3044   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
   3045                                (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
   3046                                asm, pat>,
   3047           Sched<[WriteLD]>;
   3048 
   3049   def : InstAlias<asm # "\t$Rt, [$Rn]",
   3050                   (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
   3051 }
   3052 
   3053 //---
   3054 // Load/store unscaled immediate, unprivileged
   3055 //---
   3056 
   3057 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
   3058                                 dag oops, dag iops, string asm>
   3059     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
   3060   bits<5> Rt;
   3061   bits<5> Rn;
   3062   bits<9> offset;
   3063   let Inst{31-30} = sz;
   3064   let Inst{29-27} = 0b111;
   3065   let Inst{26}    = V;
   3066   let Inst{25-24} = 0b00;
   3067   let Inst{23-22} = opc;
   3068   let Inst{21}    = 0;
   3069   let Inst{20-12} = offset;
   3070   let Inst{11-10} = 0b10;
   3071   let Inst{9-5}   = Rn;
   3072   let Inst{4-0}   = Rt;
   3073 
   3074   let DecoderMethod = "DecodeSignedLdStInstruction";
   3075 }
   3076 
   3077 multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
   3078                             RegisterClass regtype, string asm> {
   3079   let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
   3080   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
   3081                                     (ins GPR64sp:$Rn, simm9:$offset), asm>,
   3082           Sched<[WriteLD]>;
   3083 
   3084   def : InstAlias<asm # "\t$Rt, [$Rn]",
   3085                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
   3086 }
   3087 
   3088 multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
   3089                              RegisterClass regtype, string asm> {
   3090   let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
   3091   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
   3092                                  (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
   3093                                  asm>,
   3094           Sched<[WriteST]>;
   3095 
   3096   def : InstAlias<asm # "\t$Rt, [$Rn]",
   3097                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
   3098 }
   3099 
   3100 //---
   3101 // Load/store pre-indexed
   3102 //---
   3103 
   3104 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
   3105                           string asm, string cstr, list<dag> pat>
   3106     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
   3107   bits<5> Rt;
   3108   bits<5> Rn;
   3109   bits<9> offset;
   3110   let Inst{31-30} = sz;
   3111   let Inst{29-27} = 0b111;
   3112   let Inst{26}    = V;
   3113   let Inst{25-24} = 0;
   3114   let Inst{23-22} = opc;
   3115   let Inst{21}    = 0;
   3116   let Inst{20-12} = offset;
   3117   let Inst{11-10} = 0b11;
   3118   let Inst{9-5}   = Rn;
   3119   let Inst{4-0}   = Rt;
   3120 
   3121   let DecoderMethod = "DecodeSignedLdStInstruction";
   3122 }
   3123 
   3124 let hasSideEffects = 0 in {
   3125 let mayStore = 0, mayLoad = 1 in
   3126 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   3127              string asm>
   3128     : BaseLoadStorePreIdx<sz, V, opc,
   3129                      (outs GPR64sp:$wback, regtype:$Rt),
   3130                      (ins GPR64sp:$Rn, simm9:$offset), asm,
   3131                      "$Rn = $wback,@earlyclobber $wback", []>,
   3132       Sched<[WriteLD, WriteAdr]>;
   3133 
   3134 let mayStore = 1, mayLoad = 0 in
   3135 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   3136                   string asm, SDPatternOperator storeop, ValueType Ty>
   3137     : BaseLoadStorePreIdx<sz, V, opc,
   3138                       (outs GPR64sp:$wback),
   3139                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
   3140                       asm, "$Rn = $wback,@earlyclobber $wback",
   3141       [(set GPR64sp:$wback,
   3142             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
   3143       Sched<[WriteAdr, WriteST]>;
   3144 } // hasSideEffects = 0
   3145 
   3146 //---
   3147 // Load/store post-indexed
   3148 //---
   3149 
   3150 class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
   3151                           string asm, string cstr, list<dag> pat>
   3152     : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
   3153   bits<5> Rt;
   3154   bits<5> Rn;
   3155   bits<9> offset;
   3156   let Inst{31-30} = sz;
   3157   let Inst{29-27} = 0b111;
   3158   let Inst{26}    = V;
   3159   let Inst{25-24} = 0b00;
   3160   let Inst{23-22} = opc;
   3161   let Inst{21}    = 0b0;
   3162   let Inst{20-12} = offset;
   3163   let Inst{11-10} = 0b01;
   3164   let Inst{9-5}   = Rn;
   3165   let Inst{4-0}   = Rt;
   3166 
   3167   let DecoderMethod = "DecodeSignedLdStInstruction";
   3168 }
   3169 
   3170 let hasSideEffects = 0 in {
   3171 let mayStore = 0, mayLoad = 1 in
   3172 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   3173              string asm>
   3174     : BaseLoadStorePostIdx<sz, V, opc,
   3175                       (outs GPR64sp:$wback, regtype:$Rt),
   3176                       (ins GPR64sp:$Rn, simm9:$offset),
   3177                       asm, "$Rn = $wback,@earlyclobber $wback", []>,
   3178       Sched<[WriteLD, WriteI]>;
   3179 
   3180 let mayStore = 1, mayLoad = 0 in
   3181 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   3182                    string asm, SDPatternOperator storeop, ValueType Ty>
   3183     : BaseLoadStorePostIdx<sz, V, opc,
   3184                       (outs GPR64sp:$wback),
   3185                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
   3186                        asm, "$Rn = $wback,@earlyclobber $wback",
   3187       [(set GPR64sp:$wback,
   3188             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
   3189     Sched<[WriteAdr, WriteST, ReadAdrBase]>;
   3190 } // hasSideEffects = 0
   3191 
   3192 
   3193 //---
   3194 // Load/store pair
   3195 //---
   3196 
   3197 // (indexed, offset)
   3198 
   3199 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
   3200                               string asm>
   3201     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
   3202   bits<5> Rt;
   3203   bits<5> Rt2;
   3204   bits<5> Rn;
   3205   bits<7> offset;
   3206   let Inst{31-30} = opc;
   3207   let Inst{29-27} = 0b101;
   3208   let Inst{26}    = V;
   3209   let Inst{25-23} = 0b010;
   3210   let Inst{22}    = L;
   3211   let Inst{21-15} = offset;
   3212   let Inst{14-10} = Rt2;
   3213   let Inst{9-5}   = Rn;
   3214   let Inst{4-0}   = Rt;
   3215 
   3216   let DecoderMethod = "DecodePairLdStInstruction";
   3217 }
   3218 
   3219 multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype,
   3220                           Operand indextype, string asm> {
   3221   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
   3222   def i : BaseLoadStorePairOffset<opc, V, 1,
   3223                                   (outs regtype:$Rt, regtype:$Rt2),
   3224                                   (ins GPR64sp:$Rn, indextype:$offset), asm>,
   3225           Sched<[WriteLD, WriteLDHi]>;
   3226 
   3227   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
   3228                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
   3229                                                   GPR64sp:$Rn, 0)>;
   3230 }
   3231 
   3232 
   3233 multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype,
   3234                            Operand indextype, string asm> {
   3235   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
   3236   def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
   3237                                   (ins regtype:$Rt, regtype:$Rt2,
   3238                                        GPR64sp:$Rn, indextype:$offset),
   3239                                   asm>,
   3240           Sched<[WriteSTP]>;
   3241 
   3242   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
   3243                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
   3244                                                   GPR64sp:$Rn, 0)>;
   3245 }
   3246 
   3247 // (pre-indexed)
   3248 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
   3249                               string asm>
   3250     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
   3251   bits<5> Rt;
   3252   bits<5> Rt2;
   3253   bits<5> Rn;
   3254   bits<7> offset;
   3255   let Inst{31-30} = opc;
   3256   let Inst{29-27} = 0b101;
   3257   let Inst{26}    = V;
   3258   let Inst{25-23} = 0b011;
   3259   let Inst{22}    = L;
   3260   let Inst{21-15} = offset;
   3261   let Inst{14-10} = Rt2;
   3262   let Inst{9-5}   = Rn;
   3263   let Inst{4-0}   = Rt;
   3264 
   3265   let DecoderMethod = "DecodePairLdStInstruction";
   3266 }
   3267 
   3268 let hasSideEffects = 0 in {
   3269 let mayStore = 0, mayLoad = 1 in
   3270 class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
   3271                      Operand indextype, string asm>
   3272     : BaseLoadStorePairPreIdx<opc, V, 1,
   3273                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
   3274                               (ins GPR64sp:$Rn, indextype:$offset), asm>,
   3275       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
   3276 
   3277 let mayStore = 1, mayLoad = 0 in
   3278 class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
   3279                       Operand indextype, string asm>
   3280     : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
   3281                              (ins regtype:$Rt, regtype:$Rt2,
   3282                                   GPR64sp:$Rn, indextype:$offset),
   3283                              asm>,
   3284       Sched<[WriteAdr, WriteSTP]>;
   3285 } // hasSideEffects = 0
   3286 
   3287 // (post-indexed)
   3288 
   3289 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
   3290                               string asm>
   3291     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
   3292   bits<5> Rt;
   3293   bits<5> Rt2;
   3294   bits<5> Rn;
   3295   bits<7> offset;
   3296   let Inst{31-30} = opc;
   3297   let Inst{29-27} = 0b101;
   3298   let Inst{26}    = V;
   3299   let Inst{25-23} = 0b001;
   3300   let Inst{22}    = L;
   3301   let Inst{21-15} = offset;
   3302   let Inst{14-10} = Rt2;
   3303   let Inst{9-5}   = Rn;
   3304   let Inst{4-0}   = Rt;
   3305 
   3306   let DecoderMethod = "DecodePairLdStInstruction";
   3307 }
   3308 
   3309 let hasSideEffects = 0 in {
   3310 let mayStore = 0, mayLoad = 1 in
   3311 class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
   3312                       Operand idxtype, string asm>
   3313     : BaseLoadStorePairPostIdx<opc, V, 1,
   3314                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
   3315                               (ins GPR64sp:$Rn, idxtype:$offset), asm>,
   3316       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
   3317 
   3318 let mayStore = 1, mayLoad = 0 in
   3319 class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
   3320                        Operand idxtype, string asm>
   3321     : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
   3322                              (ins regtype:$Rt, regtype:$Rt2,
   3323                                   GPR64sp:$Rn, idxtype:$offset),
   3324                              asm>,
   3325       Sched<[WriteAdr, WriteSTP]>;
   3326 } // hasSideEffects = 0
   3327 
   3328 //  (no-allocate)
   3329 
   3330 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
   3331                               string asm>
   3332     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
   3333   bits<5> Rt;
   3334   bits<5> Rt2;
   3335   bits<5> Rn;
   3336   bits<7> offset;
   3337   let Inst{31-30} = opc;
   3338   let Inst{29-27} = 0b101;
   3339   let Inst{26}    = V;
   3340   let Inst{25-23} = 0b000;
   3341   let Inst{22}    = L;
   3342   let Inst{21-15} = offset;
   3343   let Inst{14-10} = Rt2;
   3344   let Inst{9-5}   = Rn;
   3345   let Inst{4-0}   = Rt;
   3346 
   3347   let DecoderMethod = "DecodePairLdStInstruction";
   3348 }
   3349 
   3350 multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
   3351                            Operand indextype, string asm> {
   3352   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
   3353   def i : BaseLoadStorePairNoAlloc<opc, V, 1,
   3354                                    (outs regtype:$Rt, regtype:$Rt2),
   3355                                    (ins GPR64sp:$Rn, indextype:$offset), asm>,
   3356           Sched<[WriteLD, WriteLDHi]>;
   3357 
   3358 
   3359   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
   3360                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
   3361                                                   GPR64sp:$Rn, 0)>;
   3362 }
   3363 
   3364 multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
   3365                       Operand indextype, string asm> {
   3366   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
   3367   def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
   3368                                    (ins regtype:$Rt, regtype:$Rt2,
   3369                                         GPR64sp:$Rn, indextype:$offset),
   3370                                    asm>,
   3371           Sched<[WriteSTP]>;
   3372 
   3373   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
   3374                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
   3375                                                   GPR64sp:$Rn, 0)>;
   3376 }
   3377 
   3378 //---
   3379 // Load/store exclusive
   3380 //---
   3381 
   3382 // True exclusive operations write to and/or read from the system's exclusive
   3383 // monitors, which as far as a compiler is concerned can be modelled as a
   3384 // random shared memory address. Hence LoadExclusive mayStore.
   3385 //
   3386 // Since these instructions have the undefined register bits set to 1 in
   3387 // their canonical form, we need a post encoder method to set those bits
   3388 // to 1 when encoding these instructions. We do this using the
   3389 // fixLoadStoreExclusive function. This function has template parameters:
   3390 //
   3391 // fixLoadStoreExclusive<int hasRs, int hasRt2>
   3392 //
   3393 // hasRs indicates that the instruction uses the Rs field, so we won't set
   3394 // it to 1 (and the same for Rt2). We don't need template parameters for
   3395 // the other register fields since Rt and Rn are always used.
   3396 //
   3397 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
   3398 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3399                              dag oops, dag iops, string asm, string operands>
   3400     : I<oops, iops, asm, operands, "", []> {
   3401   let Inst{31-30} = sz;
   3402   let Inst{29-24} = 0b001000;
   3403   let Inst{23}    = o2;
   3404   let Inst{22}    = L;
   3405   let Inst{21}    = o1;
   3406   let Inst{15}    = o0;
   3407 
   3408   let DecoderMethod = "DecodeExclusiveLdStInstruction";
   3409 }
   3410 
   3411 // Neither Rs nor Rt2 operands.
   3412 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3413                                dag oops, dag iops, string asm, string operands>
   3414     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
   3415   bits<5> Rt;
   3416   bits<5> Rn;
   3417   let Inst{20-16} = 0b11111;
   3418   let Unpredictable{20-16} = 0b11111;
   3419   let Inst{14-10} = 0b11111;
   3420   let Unpredictable{14-10} = 0b11111;
   3421   let Inst{9-5} = Rn;
   3422   let Inst{4-0} = Rt;
   3423 
   3424   let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
   3425 }
   3426 
   3427 // Simple load acquires don't set the exclusive monitor
   3428 let mayLoad = 1, mayStore = 0 in
   3429 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3430                   RegisterClass regtype, string asm>
   3431     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
   3432                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
   3433       Sched<[WriteLD]>;
   3434 
   3435 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3436                     RegisterClass regtype, string asm>
   3437     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
   3438                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
   3439       Sched<[WriteLD]>;
   3440 
   3441 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3442                        RegisterClass regtype, string asm>
   3443     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
   3444                              (outs regtype:$Rt, regtype:$Rt2),
   3445                              (ins GPR64sp0:$Rn), asm,
   3446                              "\t$Rt, $Rt2, [$Rn]">,
   3447       Sched<[WriteLD, WriteLDHi]> {
   3448   bits<5> Rt;
   3449   bits<5> Rt2;
   3450   bits<5> Rn;
   3451   let Inst{14-10} = Rt2;
   3452   let Inst{9-5} = Rn;
   3453   let Inst{4-0} = Rt;
   3454 
   3455   let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
   3456 }
   3457 
   3458 // Simple store release operations do not check the exclusive monitor.
   3459 let mayLoad = 0, mayStore = 1 in
   3460 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3461                    RegisterClass regtype, string asm>
   3462     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
   3463                                (ins regtype:$Rt, GPR64sp0:$Rn),
   3464                                asm, "\t$Rt, [$Rn]">,
   3465       Sched<[WriteST]>;
   3466 
   3467 let mayLoad = 1, mayStore = 1 in
   3468 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3469                      RegisterClass regtype, string asm>
   3470     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
   3471                              (ins regtype:$Rt, GPR64sp0:$Rn),
   3472                              asm, "\t$Ws, $Rt, [$Rn]">,
   3473       Sched<[WriteSTX]> {
   3474   bits<5> Ws;
   3475   bits<5> Rt;
   3476   bits<5> Rn;
   3477   let Inst{20-16} = Ws;
   3478   let Inst{9-5} = Rn;
   3479   let Inst{4-0} = Rt;
   3480 
   3481   let Constraints = "@earlyclobber $Ws";
   3482   let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
   3483 }
   3484 
   3485 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3486                          RegisterClass regtype, string asm>
   3487     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
   3488                              (outs GPR32:$Ws),
   3489                              (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
   3490                               asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
   3491       Sched<[WriteSTX]> {
   3492   bits<5> Ws;
   3493   bits<5> Rt;
   3494   bits<5> Rt2;
   3495   bits<5> Rn;
   3496   let Inst{20-16} = Ws;
   3497   let Inst{14-10} = Rt2;
   3498   let Inst{9-5} = Rn;
   3499   let Inst{4-0} = Rt;
   3500 
   3501   let Constraints = "@earlyclobber $Ws";
   3502 }
   3503 
   3504 //---
   3505 // Exception generation
   3506 //---
   3507 
   3508 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
   3509 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
   3510     : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
   3511       Sched<[WriteSys]> {
   3512   bits<16> imm;
   3513   let Inst{31-24} = 0b11010100;
   3514   let Inst{23-21} = op1;
   3515   let Inst{20-5}  = imm;
   3516   let Inst{4-2}   = 0b000;
   3517   let Inst{1-0}   = ll;
   3518 }
   3519 
   3520 let Predicates = [HasFPARMv8] in {
   3521 
   3522 //---
   3523 // Floating point to integer conversion
   3524 //---
   3525 
   3526 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
   3527                       RegisterClass srcType, RegisterClass dstType,
   3528                       string asm, list<dag> pattern>
   3529     : I<(outs dstType:$Rd), (ins srcType:$Rn),
   3530          asm, "\t$Rd, $Rn", "", pattern>,
   3531       Sched<[WriteFCvt]> {
   3532   bits<5> Rd;
   3533   bits<5> Rn;
   3534   let Inst{30-29} = 0b00;
   3535   let Inst{28-24} = 0b11110;
   3536   let Inst{23-22} = type;
   3537   let Inst{21}    = 1;
   3538   let Inst{20-19} = rmode;
   3539   let Inst{18-16} = opcode;
   3540   let Inst{15-10} = 0;
   3541   let Inst{9-5}   = Rn;
   3542   let Inst{4-0}   = Rd;
   3543 }
   3544 
   3545 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   3546 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
   3547                       RegisterClass srcType, RegisterClass dstType,
   3548                       Operand immType, string asm, list<dag> pattern>
   3549     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
   3550          asm, "\t$Rd, $Rn, $scale", "", pattern>,
   3551       Sched<[WriteFCvt]> {
   3552   bits<5> Rd;
   3553   bits<5> Rn;
   3554   bits<6> scale;
   3555   let Inst{30-29} = 0b00;
   3556   let Inst{28-24} = 0b11110;
   3557   let Inst{23-22} = type;
   3558   let Inst{21}    = 0;
   3559   let Inst{20-19} = rmode;
   3560   let Inst{18-16} = opcode;
   3561   let Inst{15-10} = scale;
   3562   let Inst{9-5}   = Rn;
   3563   let Inst{4-0}   = Rd;
   3564 }
   3565 
   3566 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
   3567            SDPatternOperator OpN> {
   3568   // Unscaled half-precision to 32-bit
   3569   def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,
   3570                                      [(set GPR32:$Rd, (OpN FPR16:$Rn))]> {
   3571     let Inst{31} = 0; // 32-bit GPR flag
   3572     let Predicates = [HasFullFP16];
   3573   }
   3574 
   3575   // Unscaled half-precision to 64-bit
   3576   def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,
   3577                                      [(set GPR64:$Rd, (OpN FPR16:$Rn))]> {
   3578     let Inst{31} = 1; // 64-bit GPR flag
   3579     let Predicates = [HasFullFP16];
   3580   }
   3581 
   3582   // Unscaled single-precision to 32-bit
   3583   def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
   3584                                      [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
   3585     let Inst{31} = 0; // 32-bit GPR flag
   3586   }
   3587 
   3588   // Unscaled single-precision to 64-bit
   3589   def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
   3590                                      [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
   3591     let Inst{31} = 1; // 64-bit GPR flag
   3592   }
   3593 
   3594   // Unscaled double-precision to 32-bit
   3595   def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
   3596                                      [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
   3597     let Inst{31} = 0; // 32-bit GPR flag
   3598   }
   3599 
   3600   // Unscaled double-precision to 64-bit
   3601   def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
   3602                                      [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
   3603     let Inst{31} = 1; // 64-bit GPR flag
   3604   }
   3605 }
   3606 
   3607 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
   3608                              SDPatternOperator OpN> {
   3609   // Scaled half-precision to 32-bit
   3610   def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,
   3611                               fixedpoint_f16_i32, asm,
   3612               [(set GPR32:$Rd, (OpN (fmul FPR16:$Rn,
   3613                                           fixedpoint_f16_i32:$scale)))]> {
   3614     let Inst{31} = 0; // 32-bit GPR flag
   3615     let scale{5} = 1;
   3616     let Predicates = [HasFullFP16];
   3617   }
   3618 
   3619   // Scaled half-precision to 64-bit
   3620   def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,
   3621                               fixedpoint_f16_i64, asm,
   3622               [(set GPR64:$Rd, (OpN (fmul FPR16:$Rn,
   3623                                           fixedpoint_f16_i64:$scale)))]> {
   3624     let Inst{31} = 1; // 64-bit GPR flag
   3625     let Predicates = [HasFullFP16];
   3626   }
   3627 
   3628   // Scaled single-precision to 32-bit
   3629   def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
   3630                               fixedpoint_f32_i32, asm,
   3631               [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
   3632                                           fixedpoint_f32_i32:$scale)))]> {
   3633     let Inst{31} = 0; // 32-bit GPR flag
   3634     let scale{5} = 1;
   3635   }
   3636 
   3637   // Scaled single-precision to 64-bit
   3638   def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
   3639                               fixedpoint_f32_i64, asm,
   3640               [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
   3641                                           fixedpoint_f32_i64:$scale)))]> {
   3642     let Inst{31} = 1; // 64-bit GPR flag
   3643   }
   3644 
   3645   // Scaled double-precision to 32-bit
   3646   def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
   3647                               fixedpoint_f64_i32, asm,
   3648               [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
   3649                                           fixedpoint_f64_i32:$scale)))]> {
   3650     let Inst{31} = 0; // 32-bit GPR flag
   3651     let scale{5} = 1;
   3652   }
   3653 
   3654   // Scaled double-precision to 64-bit
   3655   def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
   3656                               fixedpoint_f64_i64, asm,
   3657               [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
   3658                                           fixedpoint_f64_i64:$scale)))]> {
   3659     let Inst{31} = 1; // 64-bit GPR flag
   3660   }
   3661 }
   3662 
   3663 //---
   3664 // Integer to floating point conversion
   3665 //---
   3666 
   3667 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   3668 class BaseIntegerToFP<bit isUnsigned,
   3669                       RegisterClass srcType, RegisterClass dstType,
   3670                       Operand immType, string asm, list<dag> pattern>
   3671     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
   3672          asm, "\t$Rd, $Rn, $scale", "", pattern>,
   3673       Sched<[WriteFCvt]> {
   3674   bits<5> Rd;
   3675   bits<5> Rn;
   3676   bits<6> scale;
   3677   let Inst{30-24} = 0b0011110;
   3678   let Inst{21-17} = 0b00001;
   3679   let Inst{16}    = isUnsigned;
   3680   let Inst{15-10} = scale;
   3681   let Inst{9-5}   = Rn;
   3682   let Inst{4-0}   = Rd;
   3683 }
   3684 
   3685 class BaseIntegerToFPUnscaled<bit isUnsigned,
   3686                       RegisterClass srcType, RegisterClass dstType,
   3687                       ValueType dvt, string asm, SDNode node>
   3688     : I<(outs dstType:$Rd), (ins srcType:$Rn),
   3689          asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
   3690       Sched<[WriteFCvt]> {
   3691   bits<5> Rd;
   3692   bits<5> Rn;
   3693   bits<6> scale;
   3694   let Inst{30-24} = 0b0011110;
   3695   let Inst{21-17} = 0b10001;
   3696   let Inst{16}    = isUnsigned;
   3697   let Inst{15-10} = 0b000000;
   3698   let Inst{9-5}   = Rn;
   3699   let Inst{4-0}   = Rd;
   3700 }
   3701 
   3702 multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
   3703   // Unscaled
   3704   def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> {
   3705     let Inst{31} = 0; // 32-bit GPR flag
   3706     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3707     let Predicates = [HasFullFP16];
   3708   }
   3709 
   3710   def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
   3711     let Inst{31} = 0; // 32-bit GPR flag
   3712     let Inst{23-22} = 0b00; // 32-bit FPR flag
   3713   }
   3714 
   3715   def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
   3716     let Inst{31} = 0; // 32-bit GPR flag
   3717     let Inst{23-22} = 0b01; // 64-bit FPR flag
   3718   }
   3719 
   3720   def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> {
   3721     let Inst{31} = 1; // 64-bit GPR flag
   3722     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3723     let Predicates = [HasFullFP16];
   3724   }
   3725 
   3726   def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
   3727     let Inst{31} = 1; // 64-bit GPR flag
   3728     let Inst{23-22} = 0b00; // 32-bit FPR flag
   3729   }
   3730 
   3731   def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
   3732     let Inst{31} = 1; // 64-bit GPR flag
   3733     let Inst{23-22} = 0b01; // 64-bit FPR flag
   3734   }
   3735 
   3736   // Scaled
   3737   def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm,
   3738                              [(set FPR16:$Rd,
   3739                                    (fdiv (node GPR32:$Rn),
   3740                                          fixedpoint_f16_i32:$scale))]> {
   3741     let Inst{31} = 0; // 32-bit GPR flag
   3742     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3743     let scale{5} = 1;
   3744     let Predicates = [HasFullFP16];
   3745   }
   3746 
   3747   def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
   3748                              [(set FPR32:$Rd,
   3749                                    (fdiv (node GPR32:$Rn),
   3750                                          fixedpoint_f32_i32:$scale))]> {
   3751     let Inst{31} = 0; // 32-bit GPR flag
   3752     let Inst{23-22} = 0b00; // 32-bit FPR flag
   3753     let scale{5} = 1;
   3754   }
   3755 
   3756   def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
   3757                              [(set FPR64:$Rd,
   3758                                    (fdiv (node GPR32:$Rn),
   3759                                          fixedpoint_f64_i32:$scale))]> {
   3760     let Inst{31} = 0; // 32-bit GPR flag
   3761     let Inst{23-22} = 0b01; // 64-bit FPR flag
   3762     let scale{5} = 1;
   3763   }
   3764 
   3765   def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm,
   3766                              [(set FPR16:$Rd,
   3767                                    (fdiv (node GPR64:$Rn),
   3768                                          fixedpoint_f16_i64:$scale))]> {
   3769     let Inst{31} = 1; // 64-bit GPR flag
   3770     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3771     let Predicates = [HasFullFP16];
   3772   }
   3773 
   3774   def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
   3775                              [(set FPR32:$Rd,
   3776                                    (fdiv (node GPR64:$Rn),
   3777                                          fixedpoint_f32_i64:$scale))]> {
   3778     let Inst{31} = 1; // 64-bit GPR flag
   3779     let Inst{23-22} = 0b00; // 32-bit FPR flag
   3780   }
   3781 
   3782   def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
   3783                              [(set FPR64:$Rd,
   3784                                    (fdiv (node GPR64:$Rn),
   3785                                          fixedpoint_f64_i64:$scale))]> {
   3786     let Inst{31} = 1; // 64-bit GPR flag
   3787     let Inst{23-22} = 0b01; // 64-bit FPR flag
   3788   }
   3789 }
   3790 
   3791 //---
   3792 // Unscaled integer <-> floating point conversion (i.e. FMOV)
   3793 //---
   3794 
   3795 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   3796 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
   3797                       RegisterClass srcType, RegisterClass dstType,
   3798                       string asm>
   3799     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
   3800         // We use COPY_TO_REGCLASS for these bitconvert operations.
   3801         // copyPhysReg() expands the resultant COPY instructions after
   3802         // regalloc is done. This gives greater freedom for the allocator
   3803         // and related passes (coalescing, copy propagation, et. al.) to
   3804         // be more effective.
   3805         [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
   3806       Sched<[WriteFCopy]> {
   3807   bits<5> Rd;
   3808   bits<5> Rn;
   3809   let Inst{30-24} = 0b0011110;
   3810   let Inst{21}    = 1;
   3811   let Inst{20-19} = rmode;
   3812   let Inst{18-16} = opcode;
   3813   let Inst{15-10} = 0b000000;
   3814   let Inst{9-5}   = Rn;
   3815   let Inst{4-0}   = Rd;
   3816 }
   3817 
   3818 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   3819 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
   3820                      RegisterClass srcType, RegisterOperand dstType, string asm,
   3821                      string kind>
   3822     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
   3823         "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
   3824       Sched<[WriteFCopy]> {
   3825   bits<5> Rd;
   3826   bits<5> Rn;
   3827   let Inst{30-23} = 0b00111101;
   3828   let Inst{21}    = 1;
   3829   let Inst{20-19} = rmode;
   3830   let Inst{18-16} = opcode;
   3831   let Inst{15-10} = 0b000000;
   3832   let Inst{9-5}   = Rn;
   3833   let Inst{4-0}   = Rd;
   3834 
   3835   let DecoderMethod =  "DecodeFMOVLaneInstruction";
   3836 }
   3837 
   3838 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   3839 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
   3840                      RegisterOperand srcType, RegisterClass dstType, string asm,
   3841                      string kind>
   3842     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
   3843         "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
   3844       Sched<[WriteFCopy]> {
   3845   bits<5> Rd;
   3846   bits<5> Rn;
   3847   let Inst{30-23} = 0b00111101;
   3848   let Inst{21}    = 1;
   3849   let Inst{20-19} = rmode;
   3850   let Inst{18-16} = opcode;
   3851   let Inst{15-10} = 0b000000;
   3852   let Inst{9-5}   = Rn;
   3853   let Inst{4-0}   = Rd;
   3854 
   3855   let DecoderMethod =  "DecodeFMOVLaneInstruction";
   3856 }
   3857 
   3858 
   3859 multiclass UnscaledConversion<string asm> {
   3860   def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {
   3861     let Inst{31} = 0; // 32-bit GPR flag
   3862     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3863     let Predicates = [HasFullFP16];
   3864   }
   3865 
   3866   def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {
   3867     let Inst{31} = 1; // 64-bit GPR flag
   3868     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3869     let Predicates = [HasFullFP16];
   3870   }
   3871 
   3872   def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
   3873     let Inst{31} = 0; // 32-bit GPR flag
   3874     let Inst{23-22} = 0b00; // 32-bit FPR flag
   3875   }
   3876 
   3877   def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
   3878     let Inst{31} = 1; // 64-bit GPR flag
   3879     let Inst{23-22} = 0b01; // 64-bit FPR flag
   3880   }
   3881 
   3882   def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {
   3883     let Inst{31} = 0; // 32-bit GPR flag
   3884     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3885     let Predicates = [HasFullFP16];
   3886   }
   3887 
   3888   def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {
   3889     let Inst{31} = 1; // 64-bit GPR flag
   3890     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3891     let Predicates = [HasFullFP16];
   3892   }
   3893 
   3894   def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
   3895     let Inst{31} = 0; // 32-bit GPR flag
   3896     let Inst{23-22} = 0b00; // 32-bit FPR flag
   3897   }
   3898 
   3899   def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
   3900     let Inst{31} = 1; // 64-bit GPR flag
   3901     let Inst{23-22} = 0b01; // 64-bit FPR flag
   3902   }
   3903 
   3904   def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
   3905                                              asm, ".d"> {
   3906     let Inst{31} = 1;
   3907     let Inst{22} = 0;
   3908   }
   3909 
   3910   def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
   3911                                                asm, ".d"> {
   3912     let Inst{31} = 1;
   3913     let Inst{22} = 0;
   3914   }
   3915 }
   3916 
   3917 //---
   3918 // Floating point conversion
   3919 //---
   3920 
   3921 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
   3922                        RegisterClass srcType, string asm, list<dag> pattern>
   3923     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
   3924       Sched<[WriteFCvt]> {
   3925   bits<5> Rd;
   3926   bits<5> Rn;
   3927   let Inst{31-24} = 0b00011110;
   3928   let Inst{23-22} = type;
   3929   let Inst{21-17} = 0b10001;
   3930   let Inst{16-15} = opcode;
   3931   let Inst{14-10} = 0b10000;
   3932   let Inst{9-5}   = Rn;
   3933   let Inst{4-0}   = Rd;
   3934 }
   3935 
   3936 multiclass FPConversion<string asm> {
   3937   // Double-precision to Half-precision
   3938   def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
   3939                              [(set FPR16:$Rd, (fround FPR64:$Rn))]>;
   3940 
   3941   // Double-precision to Single-precision
   3942   def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
   3943                              [(set FPR32:$Rd, (fround FPR64:$Rn))]>;
   3944 
   3945   // Half-precision to Double-precision
   3946   def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
   3947                              [(set FPR64:$Rd, (fextend FPR16:$Rn))]>;
   3948 
   3949   // Half-precision to Single-precision
   3950   def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
   3951                              [(set FPR32:$Rd, (fextend FPR16:$Rn))]>;
   3952 
   3953   // Single-precision to Double-precision
   3954   def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
   3955                              [(set FPR64:$Rd, (fextend FPR32:$Rn))]>;
   3956 
   3957   // Single-precision to Half-precision
   3958   def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
   3959                              [(set FPR16:$Rd, (fround FPR32:$Rn))]>;
   3960 }
   3961 
   3962 //---
   3963 // Single operand floating point data processing
   3964 //---
   3965 
   3966 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   3967 class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
   3968                               ValueType vt, string asm, SDPatternOperator node>
   3969     : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
   3970          [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
   3971       Sched<[WriteF]> {
   3972   bits<5> Rd;
   3973   bits<5> Rn;
   3974   let Inst{31-24} = 0b00011110;
   3975   let Inst{21-19} = 0b100;
   3976   let Inst{18-15} = opcode;
   3977   let Inst{14-10} = 0b10000;
   3978   let Inst{9-5}   = Rn;
   3979   let Inst{4-0}   = Rd;
   3980 }
   3981 
   3982 multiclass SingleOperandFPData<bits<4> opcode, string asm,
   3983                                SDPatternOperator node = null_frag> {
   3984   def Hr : BaseSingleOperandFPData<opcode, FPR16, f16, asm, node> {
   3985     let Inst{23-22} = 0b11; // 16-bit size flag
   3986     let Predicates = [HasFullFP16];
   3987   }
   3988 
   3989   def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
   3990     let Inst{23-22} = 0b00; // 32-bit size flag
   3991   }
   3992 
   3993   def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
   3994     let Inst{23-22} = 0b01; // 64-bit size flag
   3995   }
   3996 }
   3997 
   3998 //---
   3999 // Two operand floating point data processing
   4000 //---
   4001 
   4002 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4003 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
   4004                            string asm, list<dag> pat>
   4005     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
   4006          asm, "\t$Rd, $Rn, $Rm", "", pat>,
   4007       Sched<[WriteF]> {
   4008   bits<5> Rd;
   4009   bits<5> Rn;
   4010   bits<5> Rm;
   4011   let Inst{31-24} = 0b00011110;
   4012   let Inst{21}    = 1;
   4013   let Inst{20-16} = Rm;
   4014   let Inst{15-12} = opcode;
   4015   let Inst{11-10} = 0b10;
   4016   let Inst{9-5}   = Rn;
   4017   let Inst{4-0}   = Rd;
   4018 }
   4019 
   4020 multiclass TwoOperandFPData<bits<4> opcode, string asm,
   4021                             SDPatternOperator node = null_frag> {
   4022   def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
   4023                          [(set (f16 FPR16:$Rd),
   4024                                (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
   4025     let Inst{23-22} = 0b11; // 16-bit size flag
   4026     let Predicates = [HasFullFP16];
   4027   }
   4028 
   4029   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
   4030                          [(set (f32 FPR32:$Rd),
   4031                                (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
   4032     let Inst{23-22} = 0b00; // 32-bit size flag
   4033   }
   4034 
   4035   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
   4036                          [(set (f64 FPR64:$Rd),
   4037                                (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
   4038     let Inst{23-22} = 0b01; // 64-bit size flag
   4039   }
   4040 }
   4041 
   4042 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
   4043   def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
   4044                   [(set FPR16:$Rd, (fneg (node FPR16:$Rn, (f16 FPR16:$Rm))))]> {
   4045     let Inst{23-22} = 0b11; // 16-bit size flag
   4046     let Predicates = [HasFullFP16];
   4047   }
   4048 
   4049   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
   4050                   [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
   4051     let Inst{23-22} = 0b00; // 32-bit size flag
   4052   }
   4053 
   4054   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
   4055                   [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
   4056     let Inst{23-22} = 0b01; // 64-bit size flag
   4057   }
   4058 }
   4059 
   4060 
   4061 //---
   4062 // Three operand floating point data processing
   4063 //---
   4064 
   4065 class BaseThreeOperandFPData<bit isNegated, bit isSub,
   4066                              RegisterClass regtype, string asm, list<dag> pat>
   4067     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
   4068          asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
   4069       Sched<[WriteFMul]> {
   4070   bits<5> Rd;
   4071   bits<5> Rn;
   4072   bits<5> Rm;
   4073   bits<5> Ra;
   4074   let Inst{31-24} = 0b00011111;
   4075   let Inst{21}    = isNegated;
   4076   let Inst{20-16} = Rm;
   4077   let Inst{15}    = isSub;
   4078   let Inst{14-10} = Ra;
   4079   let Inst{9-5}   = Rn;
   4080   let Inst{4-0}   = Rd;
   4081 }
   4082 
   4083 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
   4084                               SDPatternOperator node> {
   4085   def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,
   4086             [(set FPR16:$Rd,
   4087                   (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {
   4088     let Inst{23-22} = 0b11; // 16-bit size flag
   4089     let Predicates = [HasFullFP16];
   4090   }
   4091 
   4092   def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
   4093             [(set FPR32:$Rd,
   4094                   (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
   4095     let Inst{23-22} = 0b00; // 32-bit size flag
   4096   }
   4097 
   4098   def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
   4099             [(set FPR64:$Rd,
   4100                   (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
   4101     let Inst{23-22} = 0b01; // 64-bit size flag
   4102   }
   4103 }
   4104 
   4105 //---
   4106 // Floating point data comparisons
   4107 //---
   4108 
   4109 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4110 class BaseOneOperandFPComparison<bit signalAllNans,
   4111                                  RegisterClass regtype, string asm,
   4112                                  list<dag> pat>
   4113     : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
   4114       Sched<[WriteFCmp]> {
   4115   bits<5> Rn;
   4116   let Inst{31-24} = 0b00011110;
   4117   let Inst{21}    = 1;
   4118 
   4119   let Inst{15-10} = 0b001000;
   4120   let Inst{9-5}   = Rn;
   4121   let Inst{4}     = signalAllNans;
   4122   let Inst{3-0}   = 0b1000;
   4123 
   4124   // Rm should be 0b00000 canonically, but we need to accept any value.
   4125   let PostEncoderMethod = "fixOneOperandFPComparison";
   4126 }
   4127 
   4128 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4129 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
   4130                                 string asm, list<dag> pat>
   4131     : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
   4132       Sched<[WriteFCmp]> {
   4133   bits<5> Rm;
   4134   bits<5> Rn;
   4135   let Inst{31-24} = 0b00011110;
   4136   let Inst{21}    = 1;
   4137   let Inst{20-16} = Rm;
   4138   let Inst{15-10} = 0b001000;
   4139   let Inst{9-5}   = Rn;
   4140   let Inst{4}     = signalAllNans;
   4141   let Inst{3-0}   = 0b0000;
   4142 }
   4143 
   4144 multiclass FPComparison<bit signalAllNans, string asm,
   4145                         SDPatternOperator OpNode = null_frag> {
   4146   let Defs = [NZCV] in {
   4147   def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
   4148       [(OpNode FPR16:$Rn, (f16 FPR16:$Rm)), (implicit NZCV)]> {
   4149     let Inst{23-22} = 0b11;
   4150     let Predicates = [HasFullFP16];
   4151   }
   4152 
   4153   def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,
   4154       [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> {
   4155     let Inst{23-22} = 0b11;
   4156     let Predicates = [HasFullFP16];
   4157   }
   4158 
   4159   def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
   4160       [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
   4161     let Inst{23-22} = 0b00;
   4162   }
   4163 
   4164   def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
   4165       [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
   4166     let Inst{23-22} = 0b00;
   4167   }
   4168 
   4169   def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
   4170       [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
   4171     let Inst{23-22} = 0b01;
   4172   }
   4173 
   4174   def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
   4175       [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
   4176     let Inst{23-22} = 0b01;
   4177   }
   4178   } // Defs = [NZCV]
   4179 }
   4180 
   4181 //---
   4182 // Floating point conditional comparisons
   4183 //---
   4184 
   4185 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4186 class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
   4187                            string mnemonic, list<dag> pat>
   4188     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
   4189          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
   4190       Sched<[WriteFCmp]> {
   4191   let Uses = [NZCV];
   4192   let Defs = [NZCV];
   4193 
   4194   bits<5> Rn;
   4195   bits<5> Rm;
   4196   bits<4> nzcv;
   4197   bits<4> cond;
   4198 
   4199   let Inst{31-24} = 0b00011110;
   4200   let Inst{21}    = 1;
   4201   let Inst{20-16} = Rm;
   4202   let Inst{15-12} = cond;
   4203   let Inst{11-10} = 0b01;
   4204   let Inst{9-5}   = Rn;
   4205   let Inst{4}     = signalAllNans;
   4206   let Inst{3-0}   = nzcv;
   4207 }
   4208 
   4209 multiclass FPCondComparison<bit signalAllNans, string mnemonic,
   4210                             SDPatternOperator OpNode = null_frag> {
   4211   def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, []> {
   4212     let Inst{23-22} = 0b11;
   4213     let Predicates = [HasFullFP16];
   4214   }
   4215 
   4216   def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
   4217       [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
   4218                           (i32 imm:$cond), NZCV))]> {
   4219     let Inst{23-22} = 0b00;
   4220   }
   4221 
   4222   def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
   4223       [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
   4224                           (i32 imm:$cond), NZCV))]> {
   4225     let Inst{23-22} = 0b01;
   4226   }
   4227 }
   4228 
   4229 //---
   4230 // Floating point conditional select
   4231 //---
   4232 
   4233 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
   4234     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
   4235          asm, "\t$Rd, $Rn, $Rm, $cond", "",
   4236          [(set regtype:$Rd,
   4237                (AArch64csel (vt regtype:$Rn), regtype:$Rm,
   4238                           (i32 imm:$cond), NZCV))]>,
   4239       Sched<[WriteF]> {
   4240   bits<5> Rd;
   4241   bits<5> Rn;
   4242   bits<5> Rm;
   4243   bits<4> cond;
   4244 
   4245   let Inst{31-24} = 0b00011110;
   4246   let Inst{21}    = 1;
   4247   let Inst{20-16} = Rm;
   4248   let Inst{15-12} = cond;
   4249   let Inst{11-10} = 0b11;
   4250   let Inst{9-5}   = Rn;
   4251   let Inst{4-0}   = Rd;
   4252 }
   4253 
   4254 multiclass FPCondSelect<string asm> {
   4255   let Uses = [NZCV] in {
   4256   def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
   4257     let Inst{23-22} = 0b11;
   4258     let Predicates = [HasFullFP16];
   4259   }
   4260 
   4261   def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
   4262     let Inst{23-22} = 0b00;
   4263   }
   4264 
   4265   def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
   4266     let Inst{23-22} = 0b01;
   4267   }
   4268   } // Uses = [NZCV]
   4269 }
   4270 
   4271 //---
   4272 // Floating move immediate
   4273 //---
   4274 
   4275 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
   4276   : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
   4277       [(set regtype:$Rd, fpimmtype:$imm)]>,
   4278     Sched<[WriteFImm]> {
   4279   bits<5> Rd;
   4280   bits<8> imm;
   4281   let Inst{31-24} = 0b00011110;
   4282   let Inst{21}    = 1;
   4283   let Inst{20-13} = imm;
   4284   let Inst{12-5}  = 0b10000000;
   4285   let Inst{4-0}   = Rd;
   4286 }
   4287 
   4288 multiclass FPMoveImmediate<string asm> {
   4289   def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
   4290     let Inst{23-22} = 0b11;
   4291     let Predicates = [HasFullFP16];
   4292   }
   4293 
   4294   def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
   4295     let Inst{23-22} = 0b00;
   4296   }
   4297 
   4298   def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
   4299     let Inst{23-22} = 0b01;
   4300   }
   4301 }
   4302 } // end of 'let Predicates = [HasFPARMv8]'
   4303 
   4304 //----------------------------------------------------------------------------
   4305 // AdvSIMD
   4306 //----------------------------------------------------------------------------
   4307 
   4308 let Predicates = [HasNEON] in {
   4309 
   4310 //----------------------------------------------------------------------------
   4311 // AdvSIMD three register vector instructions
   4312 //----------------------------------------------------------------------------
   4313 
   4314 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4315 class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,
   4316                         RegisterOperand regtype, string asm, string kind,
   4317                         list<dag> pattern>
   4318   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
   4319       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
   4320       "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
   4321     Sched<[WriteV]> {
   4322   bits<5> Rd;
   4323   bits<5> Rn;
   4324   bits<5> Rm;
   4325   let Inst{31}    = 0;
   4326   let Inst{30}    = Q;
   4327   let Inst{29}    = U;
   4328   let Inst{28-24} = 0b01110;
   4329   let Inst{23-21} = size;
   4330   let Inst{20-16} = Rm;
   4331   let Inst{15-11} = opcode;
   4332   let Inst{10}    = 1;
   4333   let Inst{9-5}   = Rn;
   4334   let Inst{4-0}   = Rd;
   4335 }
   4336 
   4337 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4338 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,
   4339                         RegisterOperand regtype, string asm, string kind,
   4340                         list<dag> pattern>
   4341   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
   4342       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
   4343       "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
   4344     Sched<[WriteV]> {
   4345   bits<5> Rd;
   4346   bits<5> Rn;
   4347   bits<5> Rm;
   4348   let Inst{31}    = 0;
   4349   let Inst{30}    = Q;
   4350   let Inst{29}    = U;
   4351   let Inst{28-24} = 0b01110;
   4352   let Inst{23-21} = size;
   4353   let Inst{20-16} = Rm;
   4354   let Inst{15-11} = opcode;
   4355   let Inst{10}    = 1;
   4356   let Inst{9-5}   = Rn;
   4357   let Inst{4-0}   = Rd;
   4358 }
   4359 
   4360 // All operand sizes distinguished in the encoding.
   4361 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
   4362                                SDPatternOperator OpNode> {
   4363   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
   4364                                       asm, ".8b",
   4365          [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
   4366   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
   4367                                       asm, ".16b",
   4368          [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
   4369   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
   4370                                       asm, ".4h",
   4371          [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
   4372   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
   4373                                       asm, ".8h",
   4374          [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
   4375   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
   4376                                       asm, ".2s",
   4377          [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
   4378   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
   4379                                       asm, ".4s",
   4380          [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
   4381   def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
   4382                                       asm, ".2d",
   4383          [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
   4384 }
   4385 
   4386 // As above, but D sized elements unsupported.
   4387 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
   4388                                   SDPatternOperator OpNode> {
   4389   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
   4390                                       asm, ".8b",
   4391         [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
   4392   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
   4393                                       asm, ".16b",
   4394         [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
   4395   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
   4396                                       asm, ".4h",
   4397         [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
   4398   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
   4399                                       asm, ".8h",
   4400         [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
   4401   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
   4402                                       asm, ".2s",
   4403         [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
   4404   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
   4405                                       asm, ".4s",
   4406         [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
   4407 }
   4408 
   4409 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
   4410                                   SDPatternOperator OpNode> {
   4411   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,
   4412                                       asm, ".8b",
   4413       [(set (v8i8 V64:$dst),
   4414             (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
   4415   def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,
   4416                                       asm, ".16b",
   4417       [(set (v16i8 V128:$dst),
   4418             (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
   4419   def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,
   4420                                       asm, ".4h",
   4421       [(set (v4i16 V64:$dst),
   4422             (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
   4423   def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,
   4424                                       asm, ".8h",
   4425       [(set (v8i16 V128:$dst),
   4426             (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
   4427   def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,
   4428                                       asm, ".2s",
   4429       [(set (v2i32 V64:$dst),
   4430             (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
   4431   def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,
   4432                                       asm, ".4s",
   4433       [(set (v4i32 V128:$dst),
   4434             (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
   4435 }
   4436 
   4437 // As above, but only B sized elements supported.
   4438 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
   4439                                 SDPatternOperator OpNode> {
   4440   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
   4441                                       asm, ".8b",
   4442     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
   4443   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
   4444                                       asm, ".16b",
   4445     [(set (v16i8 V128:$Rd),
   4446           (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
   4447 }
   4448 
   4449 // As above, but only floating point elements supported.
   4450 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,
   4451                                  string asm, SDPatternOperator OpNode> {
   4452   let Predicates = [HasNEON, HasFullFP16] in {
   4453   def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
   4454                                       asm, ".4h",
   4455         [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
   4456   def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
   4457                                       asm, ".8h",
   4458         [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
   4459   } // Predicates = [HasNEON, HasFullFP16]
   4460   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
   4461                                       asm, ".2s",
   4462         [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
   4463   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
   4464                                       asm, ".4s",
   4465         [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
   4466   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
   4467                                       asm, ".2d",
   4468         [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
   4469 }
   4470 
   4471 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,
   4472                                     string asm,
   4473                                     SDPatternOperator OpNode> {
   4474   let Predicates = [HasNEON, HasFullFP16] in {
   4475   def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
   4476                                       asm, ".4h",
   4477         [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
   4478   def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
   4479                                       asm, ".8h",
   4480         [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
   4481   } // Predicates = [HasNEON, HasFullFP16]
   4482   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
   4483                                       asm, ".2s",
   4484         [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
   4485   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
   4486                                       asm, ".4s",
   4487         [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
   4488   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
   4489                                       asm, ".2d",
   4490         [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
   4491 }
   4492 
   4493 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,
   4494                                  string asm, SDPatternOperator OpNode> {
   4495   let Predicates = [HasNEON, HasFullFP16] in {
   4496   def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,
   4497                                       asm, ".4h",
   4498      [(set (v4f16 V64:$dst),
   4499            (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
   4500   def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,
   4501                                       asm, ".8h",
   4502      [(set (v8f16 V128:$dst),
   4503            (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
   4504   } // Predicates = [HasNEON, HasFullFP16]
   4505   def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,
   4506                                       asm, ".2s",
   4507      [(set (v2f32 V64:$dst),
   4508            (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
   4509   def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,
   4510                                       asm, ".4s",
   4511      [(set (v4f32 V128:$dst),
   4512            (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
   4513   def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,
   4514                                       asm, ".2d",
   4515      [(set (v2f64 V128:$dst),
   4516            (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
   4517 }
   4518 
   4519 // As above, but D and B sized elements unsupported.
   4520 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
   4521                                 SDPatternOperator OpNode> {
   4522   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
   4523                                       asm, ".4h",
   4524         [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
   4525   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
   4526                                       asm, ".8h",
   4527         [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
   4528   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
   4529                                       asm, ".2s",
   4530         [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
   4531   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
   4532                                       asm, ".4s",
   4533         [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
   4534 }
   4535 
   4536 // Logical three vector ops share opcode bits, and only use B sized elements.
   4537 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
   4538                                   SDPatternOperator OpNode = null_frag> {
   4539   def v8i8  : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,
   4540                                      asm, ".8b",
   4541                          [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
   4542   def v16i8  : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
   4543                                      asm, ".16b",
   4544                          [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
   4545 
   4546   def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
   4547           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
   4548   def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
   4549           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
   4550   def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
   4551           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
   4552 
   4553   def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
   4554       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
   4555   def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
   4556       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
   4557   def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
   4558       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
   4559 }
   4560 
   4561 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
   4562                                   string asm, SDPatternOperator OpNode> {
   4563   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,
   4564                                      asm, ".8b",
   4565              [(set (v8i8 V64:$dst),
   4566                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
   4567   def v16i8  : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,
   4568                                      asm, ".16b",
   4569              [(set (v16i8 V128:$dst),
   4570                    (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
   4571                            (v16i8 V128:$Rm)))]>;
   4572 
   4573   def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
   4574                            (v4i16 V64:$RHS))),
   4575           (!cast<Instruction>(NAME#"v8i8")
   4576             V64:$LHS, V64:$MHS, V64:$RHS)>;
   4577   def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
   4578                            (v2i32 V64:$RHS))),
   4579           (!cast<Instruction>(NAME#"v8i8")
   4580             V64:$LHS, V64:$MHS, V64:$RHS)>;
   4581   def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
   4582                            (v1i64 V64:$RHS))),
   4583           (!cast<Instruction>(NAME#"v8i8")
   4584             V64:$LHS, V64:$MHS, V64:$RHS)>;
   4585 
   4586   def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
   4587                            (v8i16 V128:$RHS))),
   4588       (!cast<Instruction>(NAME#"v16i8")
   4589         V128:$LHS, V128:$MHS, V128:$RHS)>;
   4590   def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
   4591                            (v4i32 V128:$RHS))),
   4592       (!cast<Instruction>(NAME#"v16i8")
   4593         V128:$LHS, V128:$MHS, V128:$RHS)>;
   4594   def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
   4595                            (v2i64 V128:$RHS))),
   4596       (!cast<Instruction>(NAME#"v16i8")
   4597         V128:$LHS, V128:$MHS, V128:$RHS)>;
   4598 }
   4599 
   4600 
   4601 //----------------------------------------------------------------------------
   4602 // AdvSIMD two register vector instructions.
   4603 //----------------------------------------------------------------------------
   4604 
   4605 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4606 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
   4607                             bits<2> size2, RegisterOperand regtype, string asm,
   4608                             string dstkind, string srckind, list<dag> pattern>
   4609   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
   4610       "{\t$Rd" # dstkind # ", $Rn" # srckind #
   4611       "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
   4612     Sched<[WriteV]> {
   4613   bits<5> Rd;
   4614   bits<5> Rn;
   4615   let Inst{31}    = 0;
   4616   let Inst{30}    = Q;
   4617   let Inst{29}    = U;
   4618   let Inst{28-24} = 0b01110;
   4619   let Inst{23-22} = size;
   4620   let Inst{21} = 0b1;
   4621   let Inst{20-19} = size2;
   4622   let Inst{18-17} = 0b00;
   4623   let Inst{16-12} = opcode;
   4624   let Inst{11-10} = 0b10;
   4625   let Inst{9-5}   = Rn;
   4626   let Inst{4-0}   = Rd;
   4627 }
   4628 
   4629 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4630 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
   4631                                 bits<2> size2, RegisterOperand regtype,
   4632                                 string asm, string dstkind, string srckind,
   4633                                 list<dag> pattern>
   4634   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
   4635       "{\t$Rd" # dstkind # ", $Rn" # srckind #
   4636       "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
   4637     Sched<[WriteV]> {
   4638   bits<5> Rd;
   4639   bits<5> Rn;
   4640   let Inst{31}    = 0;
   4641   let Inst{30}    = Q;
   4642   let Inst{29}    = U;
   4643   let Inst{28-24} = 0b01110;
   4644   let Inst{23-22} = size;
   4645   let Inst{21} = 0b1;
   4646   let Inst{20-19} = size2;
   4647   let Inst{18-17} = 0b00;
   4648   let Inst{16-12} = opcode;
   4649   let Inst{11-10} = 0b10;
   4650   let Inst{9-5}   = Rn;
   4651   let Inst{4-0}   = Rd;
   4652 }
   4653 
   4654 // Supports B, H, and S element sizes.
   4655 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
   4656                             SDPatternOperator OpNode> {
   4657   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
   4658                                       asm, ".8b", ".8b",
   4659                           [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
   4660   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
   4661                                       asm, ".16b", ".16b",
   4662                           [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
   4663   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
   4664                                       asm, ".4h", ".4h",
   4665                           [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
   4666   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
   4667                                       asm, ".8h", ".8h",
   4668                           [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
   4669   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
   4670                                       asm, ".2s", ".2s",
   4671                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
   4672   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
   4673                                       asm, ".4s", ".4s",
   4674                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
   4675 }
   4676 
   4677 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
   4678                             RegisterOperand regtype, string asm, string dstkind,
   4679                             string srckind, string amount>
   4680   : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
   4681       "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
   4682       "|" # dstkind # "\t$Rd, $Rn, #" #  amount # "}", "", []>,
   4683     Sched<[WriteV]> {
   4684   bits<5> Rd;
   4685   bits<5> Rn;
   4686   let Inst{31}    = 0;
   4687   let Inst{30}    = Q;
   4688   let Inst{29-24} = 0b101110;
   4689   let Inst{23-22} = size;
   4690   let Inst{21-10} = 0b100001001110;
   4691   let Inst{9-5}   = Rn;
   4692   let Inst{4-0}   = Rd;
   4693 }
   4694 
   4695 multiclass SIMDVectorLShiftLongBySizeBHS {
   4696   let hasSideEffects = 0 in {
   4697   def v8i8  : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
   4698                                              "shll", ".8h",  ".8b", "8">;
   4699   def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
   4700                                              "shll2", ".8h", ".16b", "8">;
   4701   def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
   4702                                              "shll", ".4s",  ".4h", "16">;
   4703   def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
   4704                                              "shll2", ".4s", ".8h", "16">;
   4705   def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
   4706                                              "shll", ".2d",  ".2s", "32">;
   4707   def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
   4708                                              "shll2", ".2d", ".4s", "32">;
   4709   }
   4710 }
   4711 
   4712 // Supports all element sizes.
   4713 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
   4714                              SDPatternOperator OpNode> {
   4715   def v8i8_v4i16  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
   4716                                       asm, ".4h", ".8b",
   4717                [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
   4718   def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
   4719                                       asm, ".8h", ".16b",
   4720                [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
   4721   def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
   4722                                       asm, ".2s", ".4h",
   4723                [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
   4724   def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
   4725                                       asm, ".4s", ".8h",
   4726                [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
   4727   def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
   4728                                       asm, ".1d", ".2s",
   4729                [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
   4730   def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
   4731                                       asm, ".2d", ".4s",
   4732                [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
   4733 }
   4734 
   4735 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
   4736                                  SDPatternOperator OpNode> {
   4737   def v8i8_v4i16  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
   4738                                           asm, ".4h", ".8b",
   4739       [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
   4740                                       (v8i8 V64:$Rn)))]>;
   4741   def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
   4742                                           asm, ".8h", ".16b",
   4743       [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
   4744                                       (v16i8 V128:$Rn)))]>;
   4745   def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
   4746                                           asm, ".2s", ".4h",
   4747       [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
   4748                                       (v4i16 V64:$Rn)))]>;
   4749   def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
   4750                                           asm, ".4s", ".8h",
   4751       [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
   4752                                       (v8i16 V128:$Rn)))]>;
   4753   def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
   4754                                           asm, ".1d", ".2s",
   4755       [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
   4756                                       (v2i32 V64:$Rn)))]>;
   4757   def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
   4758                                           asm, ".2d", ".4s",
   4759       [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
   4760                                       (v4i32 V128:$Rn)))]>;
   4761 }
   4762 
   4763 // Supports all element sizes, except 1xD.
   4764 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
   4765                                   SDPatternOperator OpNode> {
   4766   def v8i8  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
   4767                                     asm, ".8b", ".8b",
   4768     [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
   4769   def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
   4770                                     asm, ".16b", ".16b",
   4771     [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
   4772   def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
   4773                                     asm, ".4h", ".4h",
   4774     [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
   4775   def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
   4776                                     asm, ".8h", ".8h",
   4777     [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
   4778   def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
   4779                                     asm, ".2s", ".2s",
   4780     [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
   4781   def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
   4782                                     asm, ".4s", ".4s",
   4783     [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
   4784   def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
   4785                                     asm, ".2d", ".2d",
   4786     [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
   4787 }
   4788 
   4789 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
   4790                              SDPatternOperator OpNode = null_frag> {
   4791   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
   4792                                 asm, ".8b", ".8b",
   4793     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
   4794   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
   4795                                 asm, ".16b", ".16b",
   4796     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
   4797   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
   4798                                 asm, ".4h", ".4h",
   4799     [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
   4800   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
   4801                                 asm, ".8h", ".8h",
   4802     [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
   4803   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
   4804                                 asm, ".2s", ".2s",
   4805     [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
   4806   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
   4807                                 asm, ".4s", ".4s",
   4808     [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
   4809   def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
   4810                                 asm, ".2d", ".2d",
   4811     [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
   4812 }
   4813 
   4814 
   4815 // Supports only B element sizes.
   4816 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
   4817                           SDPatternOperator OpNode> {
   4818   def v8i8  : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,
   4819                                 asm, ".8b", ".8b",
   4820                     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
   4821   def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,
   4822                                 asm, ".16b", ".16b",
   4823                     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
   4824 
   4825 }
   4826 
   4827 // Supports only B and H element sizes.
   4828 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
   4829                                 SDPatternOperator OpNode> {
   4830   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
   4831                                 asm, ".8b", ".8b",
   4832                     [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
   4833   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
   4834                                 asm, ".16b", ".16b",
   4835                     [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
   4836   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
   4837                                 asm, ".4h", ".4h",
   4838                     [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
   4839   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
   4840                                 asm, ".8h", ".8h",
   4841                     [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
   4842 }
   4843 
   4844 // Supports only S and D element sizes, uses high bit of the size field
   4845 // as an extra opcode bit.
   4846 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
   4847                            SDPatternOperator OpNode> {
   4848   let Predicates = [HasNEON, HasFullFP16] in {
   4849   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
   4850                                 asm, ".4h", ".4h",
   4851                           [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
   4852   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
   4853                                 asm, ".8h", ".8h",
   4854                           [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
   4855   } // Predicates = [HasNEON, HasFullFP16]
   4856   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
   4857                                 asm, ".2s", ".2s",
   4858                           [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
   4859   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
   4860                                 asm, ".4s", ".4s",
   4861                           [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
   4862   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
   4863                                 asm, ".2d", ".2d",
   4864                           [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
   4865 }
   4866 
   4867 // Supports only S element size.
   4868 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
   4869                            SDPatternOperator OpNode> {
   4870   def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
   4871                                 asm, ".2s", ".2s",
   4872                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
   4873   def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
   4874                                 asm, ".4s", ".4s",
   4875                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
   4876 }
   4877 
   4878 
   4879 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
   4880                            SDPatternOperator OpNode> {
   4881   let Predicates = [HasNEON, HasFullFP16] in {
   4882   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
   4883                                 asm, ".4h", ".4h",
   4884                           [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
   4885   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
   4886                                 asm, ".8h", ".8h",
   4887                           [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
   4888   } // Predicates = [HasNEON, HasFullFP16]
   4889   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
   4890                                 asm, ".2s", ".2s",
   4891                           [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
   4892   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
   4893                                 asm, ".4s", ".4s",
   4894                           [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
   4895   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
   4896                                 asm, ".2d", ".2d",
   4897                           [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
   4898 }
   4899 
   4900 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
   4901                            SDPatternOperator OpNode> {
   4902   let Predicates = [HasNEON, HasFullFP16] in {
   4903   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
   4904                                 asm, ".4h", ".4h",
   4905                           [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
   4906   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
   4907                                 asm, ".8h", ".8h",
   4908                           [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
   4909   } // Predicates = [HasNEON, HasFullFP16]
   4910   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
   4911                                 asm, ".2s", ".2s",
   4912                           [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
   4913   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
   4914                                 asm, ".4s", ".4s",
   4915                           [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
   4916   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
   4917                                 asm, ".2d", ".2d",
   4918                           [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
   4919 }
   4920 
   4921 
   4922 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
   4923                            RegisterOperand inreg, RegisterOperand outreg,
   4924                            string asm, string outkind, string inkind,
   4925                            list<dag> pattern>
   4926   : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
   4927       "{\t$Rd" # outkind # ", $Rn" # inkind #
   4928       "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
   4929     Sched<[WriteV]> {
   4930   bits<5> Rd;
   4931   bits<5> Rn;
   4932   let Inst{31}    = 0;
   4933   let Inst{30}    = Q;
   4934   let Inst{29}    = U;
   4935   let Inst{28-24} = 0b01110;
   4936   let Inst{23-22} = size;
   4937   let Inst{21-17} = 0b10000;
   4938   let Inst{16-12} = opcode;
   4939   let Inst{11-10} = 0b10;
   4940   let Inst{9-5}   = Rn;
   4941   let Inst{4-0}   = Rd;
   4942 }
   4943 
   4944 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
   4945                            RegisterOperand inreg, RegisterOperand outreg,
   4946                            string asm, string outkind, string inkind,
   4947                            list<dag> pattern>
   4948   : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
   4949       "{\t$Rd" # outkind # ", $Rn" # inkind #
   4950       "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
   4951     Sched<[WriteV]> {
   4952   bits<5> Rd;
   4953   bits<5> Rn;
   4954   let Inst{31}    = 0;
   4955   let Inst{30}    = Q;
   4956   let Inst{29}    = U;
   4957   let Inst{28-24} = 0b01110;
   4958   let Inst{23-22} = size;
   4959   let Inst{21-17} = 0b10000;
   4960   let Inst{16-12} = opcode;
   4961   let Inst{11-10} = 0b10;
   4962   let Inst{9-5}   = Rn;
   4963   let Inst{4-0}   = Rd;
   4964 }
   4965 
   4966 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
   4967                               SDPatternOperator OpNode> {
   4968   def v8i8  : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
   4969                                       asm, ".8b", ".8h",
   4970         [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
   4971   def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
   4972                                       asm#"2", ".16b", ".8h", []>;
   4973   def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
   4974                                       asm, ".4h", ".4s",
   4975         [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
   4976   def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
   4977                                       asm#"2", ".8h", ".4s", []>;
   4978   def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
   4979                                       asm, ".2s", ".2d",
   4980         [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
   4981   def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
   4982                                       asm#"2", ".4s", ".2d", []>;
   4983 
   4984   def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
   4985             (!cast<Instruction>(NAME # "v16i8")
   4986                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
   4987   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
   4988             (!cast<Instruction>(NAME # "v8i16")
   4989                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
   4990   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
   4991             (!cast<Instruction>(NAME # "v4i32")
   4992                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
   4993 }
   4994 
   4995 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,
   4996                            bits<5> opcode, RegisterOperand regtype, string asm,
   4997                            string kind, string zero, ValueType dty,
   4998                            ValueType sty, SDNode OpNode>
   4999   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
   5000       "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
   5001       "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
   5002       [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
   5003     Sched<[WriteV]> {
   5004   bits<5> Rd;
   5005   bits<5> Rn;
   5006   let Inst{31}    = 0;
   5007   let Inst{30}    = Q;
   5008   let Inst{29}    = U;
   5009   let Inst{28-24} = 0b01110;
   5010   let Inst{23-22} = size;
   5011   let Inst{21} = 0b1;
   5012   let Inst{20-19} = size2;
   5013   let Inst{18-17} = 0b00;
   5014   let Inst{16-12} = opcode;
   5015   let Inst{11-10} = 0b10;
   5016   let Inst{9-5}   = Rn;
   5017   let Inst{4-0}   = Rd;
   5018 }
   5019 
   5020 // Comparisons support all element sizes, except 1xD.
   5021 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
   5022                             SDNode OpNode> {
   5023   def v8i8rz  : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
   5024                                      asm, ".8b", "0",
   5025                                      v8i8, v8i8, OpNode>;
   5026   def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
   5027                                      asm, ".16b", "0",
   5028                                      v16i8, v16i8, OpNode>;
   5029   def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
   5030                                      asm, ".4h", "0",
   5031                                      v4i16, v4i16, OpNode>;
   5032   def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
   5033                                      asm, ".8h", "0",
   5034                                      v8i16, v8i16, OpNode>;
   5035   def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
   5036                                      asm, ".2s", "0",
   5037                                      v2i32, v2i32, OpNode>;
   5038   def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
   5039                                      asm, ".4s", "0",
   5040                                      v4i32, v4i32, OpNode>;
   5041   def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
   5042                                      asm, ".2d", "0",
   5043                                      v2i64, v2i64, OpNode>;
   5044 }
   5045 
   5046 // FP Comparisons support only S and D element sizes (and H for v8.2a).
   5047 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
   5048                               string asm, SDNode OpNode> {
   5049 
   5050   let Predicates = [HasNEON, HasFullFP16] in {
   5051   def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,
   5052                                      asm, ".4h", "0.0",
   5053                                      v4i16, v4f16, OpNode>;
   5054   def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
   5055                                      asm, ".8h", "0.0",
   5056                                      v8i16, v8f16, OpNode>;
   5057   } // Predicates = [HasNEON, HasFullFP16]
   5058   def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
   5059                                      asm, ".2s", "0.0",
   5060                                      v2i32, v2f32, OpNode>;
   5061   def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
   5062                                      asm, ".4s", "0.0",
   5063                                      v4i32, v4f32, OpNode>;
   5064   def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
   5065                                      asm, ".2d", "0.0",
   5066                                      v2i64, v2f64, OpNode>;
   5067 
   5068   let Predicates = [HasNEON, HasFullFP16] in {
   5069   def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",
   5070                   (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
   5071   def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",
   5072                   (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
   5073   }
   5074   def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
   5075                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
   5076   def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
   5077                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
   5078   def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
   5079                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
   5080   let Predicates = [HasNEON, HasFullFP16] in {
   5081   def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",
   5082                   (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
   5083   def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",
   5084                   (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
   5085   }
   5086   def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
   5087                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
   5088   def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
   5089                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
   5090   def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
   5091                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
   5092 }
   5093 
   5094 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5095 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
   5096                              RegisterOperand outtype, RegisterOperand intype,
   5097                              string asm, string VdTy, string VnTy,
   5098                              list<dag> pattern>
   5099   : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
   5100       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
   5101     Sched<[WriteV]> {
   5102   bits<5> Rd;
   5103   bits<5> Rn;
   5104   let Inst{31}    = 0;
   5105   let Inst{30}    = Q;
   5106   let Inst{29}    = U;
   5107   let Inst{28-24} = 0b01110;
   5108   let Inst{23-22} = size;
   5109   let Inst{21-17} = 0b10000;
   5110   let Inst{16-12} = opcode;
   5111   let Inst{11-10} = 0b10;
   5112   let Inst{9-5}   = Rn;
   5113   let Inst{4-0}   = Rd;
   5114 }
   5115 
   5116 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
   5117                              RegisterOperand outtype, RegisterOperand intype,
   5118                              string asm, string VdTy, string VnTy,
   5119                              list<dag> pattern>
   5120   : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
   5121       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
   5122     Sched<[WriteV]> {
   5123   bits<5> Rd;
   5124   bits<5> Rn;
   5125   let Inst{31}    = 0;
   5126   let Inst{30}    = Q;
   5127   let Inst{29}    = U;
   5128   let Inst{28-24} = 0b01110;
   5129   let Inst{23-22} = size;
   5130   let Inst{21-17} = 0b10000;
   5131   let Inst{16-12} = opcode;
   5132   let Inst{11-10} = 0b10;
   5133   let Inst{9-5}   = Rn;
   5134   let Inst{4-0}   = Rd;
   5135 }
   5136 
   5137 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
   5138   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
   5139                                     asm, ".4s", ".4h", []>;
   5140   def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
   5141                                     asm#"2", ".4s", ".8h", []>;
   5142   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
   5143                                     asm, ".2d", ".2s", []>;
   5144   def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
   5145                                     asm#"2", ".2d", ".4s", []>;
   5146 }
   5147 
   5148 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
   5149   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
   5150                                     asm, ".4h", ".4s", []>;
   5151   def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
   5152                                     asm#"2", ".8h", ".4s", []>;
   5153   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
   5154                                     asm, ".2s", ".2d", []>;
   5155   def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
   5156                                     asm#"2", ".4s", ".2d", []>;
   5157 }
   5158 
   5159 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
   5160                                      Intrinsic OpNode> {
   5161   def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
   5162                                      asm, ".2s", ".2d",
   5163                           [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
   5164   def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
   5165                                     asm#"2", ".4s", ".2d", []>;
   5166 
   5167   def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
   5168             (!cast<Instruction>(NAME # "v4f32")
   5169                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
   5170 }
   5171 
   5172 //----------------------------------------------------------------------------
   5173 // AdvSIMD three register different-size vector instructions.
   5174 //----------------------------------------------------------------------------
   5175 
   5176 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5177 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
   5178                       RegisterOperand outtype, RegisterOperand intype1,
   5179                       RegisterOperand intype2, string asm,
   5180                       string outkind, string inkind1, string inkind2,
   5181                       list<dag> pattern>
   5182   : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
   5183       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
   5184       "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
   5185     Sched<[WriteV]> {
   5186   bits<5> Rd;
   5187   bits<5> Rn;
   5188   bits<5> Rm;
   5189   let Inst{31}    = 0;
   5190   let Inst{30}    = size{0};
   5191   let Inst{29}    = U;
   5192   let Inst{28-24} = 0b01110;
   5193   let Inst{23-22} = size{2-1};
   5194   let Inst{21}    = 1;
   5195   let Inst{20-16} = Rm;
   5196   let Inst{15-12} = opcode;
   5197   let Inst{11-10} = 0b00;
   5198   let Inst{9-5}   = Rn;
   5199   let Inst{4-0}   = Rd;
   5200 }
   5201 
   5202 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5203 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
   5204                       RegisterOperand outtype, RegisterOperand intype1,
   5205                       RegisterOperand intype2, string asm,
   5206                       string outkind, string inkind1, string inkind2,
   5207                       list<dag> pattern>
   5208   : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
   5209       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
   5210       "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
   5211     Sched<[WriteV]> {
   5212   bits<5> Rd;
   5213   bits<5> Rn;
   5214   bits<5> Rm;
   5215   let Inst{31}    = 0;
   5216   let Inst{30}    = size{0};
   5217   let Inst{29}    = U;
   5218   let Inst{28-24} = 0b01110;
   5219   let Inst{23-22} = size{2-1};
   5220   let Inst{21}    = 1;
   5221   let Inst{20-16} = Rm;
   5222   let Inst{15-12} = opcode;
   5223   let Inst{11-10} = 0b00;
   5224   let Inst{9-5}   = Rn;
   5225   let Inst{4-0}   = Rd;
   5226 }
   5227 
   5228 // FIXME: TableGen doesn't know how to deal with expanded types that also
   5229 //        change the element count (in this case, placing the results in
   5230 //        the high elements of the result register rather than the low
   5231 //        elements). Until that's fixed, we can't code-gen those.
   5232 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
   5233                                     Intrinsic IntOp> {
   5234   def v8i16_v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
   5235                                                   V64, V128, V128,
   5236                                                   asm, ".8b", ".8h", ".8h",
   5237      [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
   5238   def v8i16_v16i8  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
   5239                                                   V128, V128, V128,
   5240                                                   asm#"2", ".16b", ".8h", ".8h",
   5241      []>;
   5242   def v4i32_v4i16  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
   5243                                                   V64, V128, V128,
   5244                                                   asm, ".4h", ".4s", ".4s",
   5245      [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
   5246   def v4i32_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
   5247                                                   V128, V128, V128,
   5248                                                   asm#"2", ".8h", ".4s", ".4s",
   5249      []>;
   5250   def v2i64_v2i32  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
   5251                                                   V64, V128, V128,
   5252                                                   asm, ".2s", ".2d", ".2d",
   5253      [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
   5254   def v2i64_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
   5255                                                   V128, V128, V128,
   5256                                                   asm#"2", ".4s", ".2d", ".2d",
   5257      []>;
   5258 
   5259 
   5260   // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
   5261   // a version attached to an instruction.
   5262   def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
   5263                                                    (v8i16 V128:$Rm))),
   5264             (!cast<Instruction>(NAME # "v8i16_v16i8")
   5265                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
   5266                 V128:$Rn, V128:$Rm)>;
   5267   def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
   5268                                                     (v4i32 V128:$Rm))),
   5269             (!cast<Instruction>(NAME # "v4i32_v8i16")
   5270                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
   5271                 V128:$Rn, V128:$Rm)>;
   5272   def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
   5273                                                     (v2i64 V128:$Rm))),
   5274             (!cast<Instruction>(NAME # "v2i64_v4i32")
   5275                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
   5276                 V128:$Rn, V128:$Rm)>;
   5277 }
   5278 
   5279 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
   5280                                       Intrinsic IntOp> {
   5281   def v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
   5282                                             V128, V64, V64,
   5283                                             asm, ".8h", ".8b", ".8b",
   5284       [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
   5285   def v16i8  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
   5286                                             V128, V128, V128,
   5287                                             asm#"2", ".8h", ".16b", ".16b", []>;
   5288   let Predicates = [HasCrypto] in {
   5289     def v1i64  : BaseSIMDDifferentThreeVector<U, 0b110, opc,
   5290                                               V128, V64, V64,
   5291                                               asm, ".1q", ".1d", ".1d", []>;
   5292     def v2i64  : BaseSIMDDifferentThreeVector<U, 0b111, opc,
   5293                                               V128, V128, V128,
   5294                                               asm#"2", ".1q", ".2d", ".2d", []>;
   5295   }
   5296 
   5297   def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
   5298                           (v8i8 (extract_high_v16i8 V128:$Rm)))),
   5299       (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
   5300 }
   5301 
   5302 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
   5303                                  SDPatternOperator OpNode> {
   5304   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
   5305                                                   V128, V64, V64,
   5306                                                   asm, ".4s", ".4h", ".4h",
   5307       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
   5308   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
   5309                                                   V128, V128, V128,
   5310                                                   asm#"2", ".4s", ".8h", ".8h",
   5311       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
   5312                                       (extract_high_v8i16 V128:$Rm)))]>;
   5313   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
   5314                                                   V128, V64, V64,
   5315                                                   asm, ".2d", ".2s", ".2s",
   5316       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
   5317   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
   5318                                                   V128, V128, V128,
   5319                                                   asm#"2", ".2d", ".4s", ".4s",
   5320       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
   5321                                       (extract_high_v4i32 V128:$Rm)))]>;
   5322 }
   5323 
   5324 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
   5325                                   SDPatternOperator OpNode = null_frag> {
   5326   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
   5327                                                   V128, V64, V64,
   5328                                                   asm, ".8h", ".8b", ".8b",
   5329       [(set (v8i16 V128:$Rd),
   5330             (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
   5331   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
   5332                                                  V128, V128, V128,
   5333                                                  asm#"2", ".8h", ".16b", ".16b",
   5334       [(set (v8i16 V128:$Rd),
   5335             (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
   5336                                 (extract_high_v16i8 V128:$Rm)))))]>;
   5337   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
   5338                                                   V128, V64, V64,
   5339                                                   asm, ".4s", ".4h", ".4h",
   5340       [(set (v4i32 V128:$Rd),
   5341             (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
   5342   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
   5343                                                   V128, V128, V128,
   5344                                                   asm#"2", ".4s", ".8h", ".8h",
   5345       [(set (v4i32 V128:$Rd),
   5346             (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
   5347                                   (extract_high_v8i16 V128:$Rm)))))]>;
   5348   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
   5349                                                   V128, V64, V64,
   5350                                                   asm, ".2d", ".2s", ".2s",
   5351       [(set (v2i64 V128:$Rd),
   5352             (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
   5353   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
   5354                                                   V128, V128, V128,
   5355                                                   asm#"2", ".2d", ".4s", ".4s",
   5356       [(set (v2i64 V128:$Rd),
   5357             (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
   5358                                  (extract_high_v4i32 V128:$Rm)))))]>;
   5359 }
   5360 
   5361 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
   5362                                           string asm,
   5363                                           SDPatternOperator OpNode> {
   5364   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
   5365                                                   V128, V64, V64,
   5366                                                   asm, ".8h", ".8b", ".8b",
   5367     [(set (v8i16 V128:$dst),
   5368           (add (v8i16 V128:$Rd),
   5369                (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
   5370   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
   5371                                                  V128, V128, V128,
   5372                                                  asm#"2", ".8h", ".16b", ".16b",
   5373     [(set (v8i16 V128:$dst),
   5374           (add (v8i16 V128:$Rd),
   5375                (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
   5376                                    (extract_high_v16i8 V128:$Rm))))))]>;
   5377   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
   5378                                                   V128, V64, V64,
   5379                                                   asm, ".4s", ".4h", ".4h",
   5380     [(set (v4i32 V128:$dst),
   5381           (add (v4i32 V128:$Rd),
   5382                (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
   5383   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
   5384                                                   V128, V128, V128,
   5385                                                   asm#"2", ".4s", ".8h", ".8h",
   5386     [(set (v4i32 V128:$dst),
   5387           (add (v4i32 V128:$Rd),
   5388                (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
   5389                                     (extract_high_v8i16 V128:$Rm))))))]>;
   5390   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
   5391                                                   V128, V64, V64,
   5392                                                   asm, ".2d", ".2s", ".2s",
   5393     [(set (v2i64 V128:$dst),
   5394           (add (v2i64 V128:$Rd),
   5395                (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
   5396   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
   5397                                                   V128, V128, V128,
   5398                                                   asm#"2", ".2d", ".4s", ".4s",
   5399     [(set (v2i64 V128:$dst),
   5400           (add (v2i64 V128:$Rd),
   5401                (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
   5402                                     (extract_high_v4i32 V128:$Rm))))))]>;
   5403 }
   5404 
   5405 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
   5406                                   SDPatternOperator OpNode = null_frag> {
   5407   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
   5408                                                   V128, V64, V64,
   5409                                                   asm, ".8h", ".8b", ".8b",
   5410       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
   5411   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
   5412                                                  V128, V128, V128,
   5413                                                  asm#"2", ".8h", ".16b", ".16b",
   5414       [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
   5415                                       (extract_high_v16i8 V128:$Rm)))]>;
   5416   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
   5417                                                   V128, V64, V64,
   5418                                                   asm, ".4s", ".4h", ".4h",
   5419       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
   5420   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
   5421                                                   V128, V128, V128,
   5422                                                   asm#"2", ".4s", ".8h", ".8h",
   5423       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
   5424                                       (extract_high_v8i16 V128:$Rm)))]>;
   5425   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
   5426                                                   V128, V64, V64,
   5427                                                   asm, ".2d", ".2s", ".2s",
   5428       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
   5429   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
   5430                                                   V128, V128, V128,
   5431                                                   asm#"2", ".2d", ".4s", ".4s",
   5432       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
   5433                                       (extract_high_v4i32 V128:$Rm)))]>;
   5434 }
   5435 
   5436 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
   5437                                       string asm,
   5438                                       SDPatternOperator OpNode> {
   5439   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
   5440                                                   V128, V64, V64,
   5441                                                   asm, ".8h", ".8b", ".8b",
   5442     [(set (v8i16 V128:$dst),
   5443           (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
   5444   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
   5445                                                  V128, V128, V128,
   5446                                                  asm#"2", ".8h", ".16b", ".16b",
   5447     [(set (v8i16 V128:$dst),
   5448           (OpNode (v8i16 V128:$Rd),
   5449                   (extract_high_v16i8 V128:$Rn),
   5450                   (extract_high_v16i8 V128:$Rm)))]>;
   5451   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
   5452                                                   V128, V64, V64,
   5453                                                   asm, ".4s", ".4h", ".4h",
   5454     [(set (v4i32 V128:$dst),
   5455           (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
   5456   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
   5457                                                   V128, V128, V128,
   5458                                                   asm#"2", ".4s", ".8h", ".8h",
   5459     [(set (v4i32 V128:$dst),
   5460           (OpNode (v4i32 V128:$Rd),
   5461                   (extract_high_v8i16 V128:$Rn),
   5462                   (extract_high_v8i16 V128:$Rm)))]>;
   5463   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
   5464                                                   V128, V64, V64,
   5465                                                   asm, ".2d", ".2s", ".2s",
   5466     [(set (v2i64 V128:$dst),
   5467           (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
   5468   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
   5469                                                   V128, V128, V128,
   5470                                                   asm#"2", ".2d", ".4s", ".4s",
   5471     [(set (v2i64 V128:$dst),
   5472           (OpNode (v2i64 V128:$Rd),
   5473                   (extract_high_v4i32 V128:$Rn),
   5474                   (extract_high_v4i32 V128:$Rm)))]>;
   5475 }
   5476 
   5477 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
   5478                                            SDPatternOperator Accum> {
   5479   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
   5480                                                   V128, V64, V64,
   5481                                                   asm, ".4s", ".4h", ".4h",
   5482     [(set (v4i32 V128:$dst),
   5483           (Accum (v4i32 V128:$Rd),
   5484                  (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
   5485                                                 (v4i16 V64:$Rm)))))]>;
   5486   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
   5487                                                   V128, V128, V128,
   5488                                                   asm#"2", ".4s", ".8h", ".8h",
   5489     [(set (v4i32 V128:$dst),
   5490           (Accum (v4i32 V128:$Rd),
   5491                  (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
   5492                                             (extract_high_v8i16 V128:$Rm)))))]>;
   5493   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
   5494                                                   V128, V64, V64,
   5495                                                   asm, ".2d", ".2s", ".2s",
   5496     [(set (v2i64 V128:$dst),
   5497           (Accum (v2i64 V128:$Rd),
   5498                  (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
   5499                                                 (v2i32 V64:$Rm)))))]>;
   5500   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
   5501                                                   V128, V128, V128,
   5502                                                   asm#"2", ".2d", ".4s", ".4s",
   5503     [(set (v2i64 V128:$dst),
   5504           (Accum (v2i64 V128:$Rd),
   5505                  (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
   5506                                             (extract_high_v4i32 V128:$Rm)))))]>;
   5507 }
   5508 
   5509 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
   5510                                   SDPatternOperator OpNode> {
   5511   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
   5512                                                   V128, V128, V64,
   5513                                                   asm, ".8h", ".8h", ".8b",
   5514        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
   5515   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
   5516                                                   V128, V128, V128,
   5517                                                   asm#"2", ".8h", ".8h", ".16b",
   5518        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
   5519                                        (extract_high_v16i8 V128:$Rm)))]>;
   5520   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
   5521                                                   V128, V128, V64,
   5522                                                   asm, ".4s", ".4s", ".4h",
   5523        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
   5524   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
   5525                                                   V128, V128, V128,
   5526                                                   asm#"2", ".4s", ".4s", ".8h",
   5527        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
   5528                                        (extract_high_v8i16 V128:$Rm)))]>;
   5529   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
   5530                                                   V128, V128, V64,
   5531                                                   asm, ".2d", ".2d", ".2s",
   5532        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
   5533   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
   5534                                                   V128, V128, V128,
   5535                                                   asm#"2", ".2d", ".2d", ".4s",
   5536        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
   5537                                        (extract_high_v4i32 V128:$Rm)))]>;
   5538 }
   5539 
   5540 //----------------------------------------------------------------------------
   5541 // AdvSIMD bitwise extract from vector
   5542 //----------------------------------------------------------------------------
   5543 
   5544 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
   5545                              string asm, string kind>
   5546   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
   5547       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
   5548       "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
   5549       [(set (vty regtype:$Rd),
   5550             (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
   5551     Sched<[WriteV]> {
   5552   bits<5> Rd;
   5553   bits<5> Rn;
   5554   bits<5> Rm;
   5555   bits<4> imm;
   5556   let Inst{31}    = 0;
   5557   let Inst{30}    = size;
   5558   let Inst{29-21} = 0b101110000;
   5559   let Inst{20-16} = Rm;
   5560   let Inst{15}    = 0;
   5561   let Inst{14-11} = imm;
   5562   let Inst{10}    = 0;
   5563   let Inst{9-5}   = Rn;
   5564   let Inst{4-0}   = Rd;
   5565 }
   5566 
   5567 
   5568 multiclass SIMDBitwiseExtract<string asm> {
   5569   def v8i8  : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
   5570     let imm{3} = 0;
   5571   }
   5572   def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
   5573 }
   5574 
   5575 //----------------------------------------------------------------------------
   5576 // AdvSIMD zip vector
   5577 //----------------------------------------------------------------------------
   5578 
   5579 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
   5580                         string asm, string kind, SDNode OpNode, ValueType valty>
   5581   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
   5582       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
   5583       "|" # kind # "\t$Rd, $Rn, $Rm}", "",
   5584       [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
   5585     Sched<[WriteV]> {
   5586   bits<5> Rd;
   5587   bits<5> Rn;
   5588   bits<5> Rm;
   5589   let Inst{31}    = 0;
   5590   let Inst{30}    = size{0};
   5591   let Inst{29-24} = 0b001110;
   5592   let Inst{23-22} = size{2-1};
   5593   let Inst{21}    = 0;
   5594   let Inst{20-16} = Rm;
   5595   let Inst{15}    = 0;
   5596   let Inst{14-12} = opc;
   5597   let Inst{11-10} = 0b10;
   5598   let Inst{9-5}   = Rn;
   5599   let Inst{4-0}   = Rd;
   5600 }
   5601 
   5602 multiclass SIMDZipVector<bits<3>opc, string asm,
   5603                          SDNode OpNode> {
   5604   def v8i8   : BaseSIMDZipVector<0b000, opc, V64,
   5605       asm, ".8b", OpNode, v8i8>;
   5606   def v16i8  : BaseSIMDZipVector<0b001, opc, V128,
   5607       asm, ".16b", OpNode, v16i8>;
   5608   def v4i16  : BaseSIMDZipVector<0b010, opc, V64,
   5609       asm, ".4h", OpNode, v4i16>;
   5610   def v8i16  : BaseSIMDZipVector<0b011, opc, V128,
   5611       asm, ".8h", OpNode, v8i16>;
   5612   def v2i32  : BaseSIMDZipVector<0b100, opc, V64,
   5613       asm, ".2s", OpNode, v2i32>;
   5614   def v4i32  : BaseSIMDZipVector<0b101, opc, V128,
   5615       asm, ".4s", OpNode, v4i32>;
   5616   def v2i64  : BaseSIMDZipVector<0b111, opc, V128,
   5617       asm, ".2d", OpNode, v2i64>;
   5618 
   5619   def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
   5620         (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
   5621   def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
   5622         (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
   5623   def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
   5624         (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
   5625   def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
   5626         (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
   5627   def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
   5628         (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
   5629 }
   5630 
   5631 //----------------------------------------------------------------------------
   5632 // AdvSIMD three register scalar instructions
   5633 //----------------------------------------------------------------------------
   5634 
   5635 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   5636 class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,
   5637                         RegisterClass regtype, string asm,
   5638                         list<dag> pattern>
   5639   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
   5640       "\t$Rd, $Rn, $Rm", "", pattern>,
   5641     Sched<[WriteV]> {
   5642   bits<5> Rd;
   5643   bits<5> Rn;
   5644   bits<5> Rm;
   5645   let Inst{31-30} = 0b01;
   5646   let Inst{29}    = U;
   5647   let Inst{28-24} = 0b11110;
   5648   let Inst{23-21} = size;
   5649   let Inst{20-16} = Rm;
   5650   let Inst{15-11} = opcode;
   5651   let Inst{10}    = 1;
   5652   let Inst{9-5}   = Rn;
   5653   let Inst{4-0}   = Rd;
   5654 }
   5655 
   5656 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   5657 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
   5658                         dag oops, dag iops, string asm,
   5659             list<dag> pattern>
   5660   : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
   5661     Sched<[WriteV]> {
   5662   bits<5> Rd;
   5663   bits<5> Rn;
   5664   bits<5> Rm;
   5665   let Inst{31-30} = 0b01;
   5666   let Inst{29}    = U;
   5667   let Inst{28-24} = 0b11110;
   5668   let Inst{23-22} = size;
   5669   let Inst{21}    = R;
   5670   let Inst{20-16} = Rm;
   5671   let Inst{15-11} = opcode;
   5672   let Inst{10}    = 1;
   5673   let Inst{9-5}   = Rn;
   5674   let Inst{4-0}   = Rd;
   5675 }
   5676 
   5677 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
   5678                             SDPatternOperator OpNode> {
   5679   def v1i64  : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
   5680     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
   5681 }
   5682 
   5683 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
   5684                                SDPatternOperator OpNode> {
   5685   def v1i64  : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
   5686     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
   5687   def v1i32  : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;
   5688   def v1i16  : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
   5689   def v1i8   : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;
   5690 
   5691   def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
   5692             (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
   5693   def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
   5694             (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
   5695 }
   5696 
   5697 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
   5698                              SDPatternOperator OpNode> {
   5699   def v1i32  : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,
   5700                              [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
   5701   def v1i16  : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
   5702 }
   5703 
   5704 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
   5705                                  SDPatternOperator OpNode = null_frag> {
   5706   def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
   5707                                      (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 
   5708                                      asm, []>;
   5709   def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
   5710                                      (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 
   5711                                      asm, []>;
   5712 }
   5713 
   5714 multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,
   5715                              SDPatternOperator OpNode = null_frag> {
   5716   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
   5717     def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
   5718       [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
   5719     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
   5720       [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
   5721     let Predicates = [HasNEON, HasFullFP16] in {
   5722     def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
   5723       [(set FPR16:$Rd, (OpNode FPR16:$Rn, FPR16:$Rm))]>;
   5724     } // Predicates = [HasNEON, HasFullFP16]
   5725   }
   5726 
   5727   def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
   5728             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
   5729 }
   5730 
   5731 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,
   5732                                 SDPatternOperator OpNode = null_frag> {
   5733   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
   5734     def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
   5735       [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
   5736     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
   5737       [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
   5738     let Predicates = [HasNEON, HasFullFP16] in {
   5739     def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
   5740       []>;
   5741     } // Predicates = [HasNEON, HasFullFP16]
   5742   }
   5743 
   5744   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
   5745             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
   5746 }
   5747 
   5748 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
   5749               dag oops, dag iops, string asm, string cstr, list<dag> pat>
   5750   : I<oops, iops, asm,
   5751       "\t$Rd, $Rn, $Rm", cstr, pat>,
   5752     Sched<[WriteV]> {
   5753   bits<5> Rd;
   5754   bits<5> Rn;
   5755   bits<5> Rm;
   5756   let Inst{31-30} = 0b01;
   5757   let Inst{29}    = U;
   5758   let Inst{28-24} = 0b11110;
   5759   let Inst{23-22} = size;
   5760   let Inst{21}    = 1;
   5761   let Inst{20-16} = Rm;
   5762   let Inst{15-11} = opcode;
   5763   let Inst{10}    = 0;
   5764   let Inst{9-5}   = Rn;
   5765   let Inst{4-0}   = Rd;
   5766 }
   5767 
   5768 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5769 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
   5770                                   SDPatternOperator OpNode = null_frag> {
   5771   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
   5772                                       (outs FPR32:$Rd),
   5773                                       (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
   5774   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
   5775                                       (outs FPR64:$Rd),
   5776                                       (ins FPR32:$Rn, FPR32:$Rm), asm, "",
   5777             [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
   5778 }
   5779 
   5780 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5781 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
   5782                                   SDPatternOperator OpNode = null_frag> {
   5783   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
   5784                                       (outs FPR32:$dst),
   5785                                       (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
   5786                                       asm, "$Rd = $dst", []>;
   5787   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
   5788                                       (outs FPR64:$dst),
   5789                                       (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
   5790                                       asm, "$Rd = $dst",
   5791             [(set (i64 FPR64:$dst),
   5792                   (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
   5793 }
   5794 
   5795 //----------------------------------------------------------------------------
   5796 // AdvSIMD two register scalar instructions
   5797 //----------------------------------------------------------------------------
   5798 
   5799 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5800 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
   5801                         RegisterClass regtype, RegisterClass regtype2,
   5802                         string asm, list<dag> pat>
   5803   : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
   5804       "\t$Rd, $Rn", "", pat>,
   5805     Sched<[WriteV]> {
   5806   bits<5> Rd;
   5807   bits<5> Rn;
   5808   let Inst{31-30} = 0b01;
   5809   let Inst{29}    = U;
   5810   let Inst{28-24} = 0b11110;
   5811   let Inst{23-22} = size;
   5812   let Inst{21} = 0b1;
   5813   let Inst{20-19} = size2;
   5814   let Inst{18-17} = 0b00;
   5815   let Inst{16-12} = opcode;
   5816   let Inst{11-10} = 0b10;
   5817   let Inst{9-5}   = Rn;
   5818   let Inst{4-0}   = Rd;
   5819 }
   5820 
   5821 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5822 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
   5823                         RegisterClass regtype, RegisterClass regtype2,
   5824                         string asm, list<dag> pat>
   5825   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
   5826       "\t$Rd, $Rn", "$Rd = $dst", pat>,
   5827     Sched<[WriteV]> {
   5828   bits<5> Rd;
   5829   bits<5> Rn;
   5830   let Inst{31-30} = 0b01;
   5831   let Inst{29}    = U;
   5832   let Inst{28-24} = 0b11110;
   5833   let Inst{23-22} = size;
   5834   let Inst{21-17} = 0b10000;
   5835   let Inst{16-12} = opcode;
   5836   let Inst{11-10} = 0b10;
   5837   let Inst{9-5}   = Rn;
   5838   let Inst{4-0}   = Rd;
   5839 }
   5840 
   5841 
   5842 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5843 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
   5844                         RegisterClass regtype, string asm, string zero>
   5845   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
   5846       "\t$Rd, $Rn, #" # zero, "", []>,
   5847     Sched<[WriteV]> {
   5848   bits<5> Rd;
   5849   bits<5> Rn;
   5850   let Inst{31-30} = 0b01;
   5851   let Inst{29}    = U;
   5852   let Inst{28-24} = 0b11110;
   5853   let Inst{23-22} = size;
   5854   let Inst{21} = 0b1;
   5855   let Inst{20-19} = size2;
   5856   let Inst{18-17} = 0b00;
   5857   let Inst{16-12} = opcode;
   5858   let Inst{11-10} = 0b10;
   5859   let Inst{9-5}   = Rn;
   5860   let Inst{4-0}   = Rd;
   5861 }
   5862 
   5863 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
   5864   : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
   5865      [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
   5866     Sched<[WriteV]> {
   5867   bits<5> Rd;
   5868   bits<5> Rn;
   5869   let Inst{31-17} = 0b011111100110000;
   5870   let Inst{16-12} = opcode;
   5871   let Inst{11-10} = 0b10;
   5872   let Inst{9-5}   = Rn;
   5873   let Inst{4-0}   = Rd;
   5874 }
   5875 
   5876 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
   5877                              SDPatternOperator OpNode> {
   5878   def v1i64rz  : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;
   5879 
   5880   def : Pat<(v1i64 (OpNode FPR64:$Rn)),
   5881             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
   5882 }
   5883 
   5884 multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
   5885                               SDPatternOperator OpNode> {
   5886   def v1i64rz  : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;
   5887   def v1i32rz  : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;
   5888   let Predicates = [HasNEON, HasFullFP16] in {
   5889   def v1i16rz  : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;
   5890   }
   5891 
   5892   def : InstAlias<asm # "\t$Rd, $Rn, #0",
   5893                   (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
   5894   def : InstAlias<asm # "\t$Rd, $Rn, #0",
   5895                   (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
   5896   let Predicates = [HasNEON, HasFullFP16] in {
   5897   def : InstAlias<asm # "\t$Rd, $Rn, #0",
   5898                   (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;
   5899   }
   5900 
   5901   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
   5902             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
   5903 }
   5904 
   5905 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
   5906                           SDPatternOperator OpNode = null_frag> {
   5907   def v1i64       : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
   5908     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
   5909 
   5910   def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
   5911             (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
   5912 }
   5913 
   5914 multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
   5915   def v1i64       : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>;
   5916   def v1i32       : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>;
   5917   let Predicates = [HasNEON, HasFullFP16] in {
   5918   def v1f16       : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
   5919   }
   5920 }
   5921 
   5922 multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,
   5923                               SDPatternOperator OpNode> {
   5924   def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,
   5925                                 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
   5926   def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,
   5927                                 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
   5928   let Predicates = [HasNEON, HasFullFP16] in {
   5929   def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,
   5930                                 [(set FPR16:$Rd, (OpNode (f16 FPR16:$Rn)))]>;
   5931   }
   5932 }
   5933 
   5934 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
   5935                              SDPatternOperator OpNode = null_frag> {
   5936   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
   5937     def v1i64  : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
   5938            [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
   5939     def v1i32  : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,
   5940            [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
   5941     def v1i16  : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;
   5942     def v1i8   : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;
   5943   }
   5944 
   5945   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
   5946             (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
   5947 }
   5948 
   5949 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
   5950                                  Intrinsic OpNode> {
   5951   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
   5952     def v1i64  : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
   5953         [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
   5954     def v1i32  : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
   5955         [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
   5956     def v1i16  : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
   5957     def v1i8   : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
   5958   }
   5959 
   5960   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
   5961             (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
   5962 }
   5963 
   5964 
   5965 
   5966 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5967 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
   5968                                  SDPatternOperator OpNode = null_frag> {
   5969   def v1i32  : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,
   5970         [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
   5971   def v1i16  : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;
   5972   def v1i8   : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;
   5973 }
   5974 
   5975 //----------------------------------------------------------------------------
   5976 // AdvSIMD scalar pairwise instructions
   5977 //----------------------------------------------------------------------------
   5978 
   5979 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5980 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
   5981                         RegisterOperand regtype, RegisterOperand vectype,
   5982                         string asm, string kind>
   5983   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
   5984       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
   5985     Sched<[WriteV]> {
   5986   bits<5> Rd;
   5987   bits<5> Rn;
   5988   let Inst{31-30} = 0b01;
   5989   let Inst{29}    = U;
   5990   let Inst{28-24} = 0b11110;
   5991   let Inst{23-22} = size;
   5992   let Inst{21-17} = 0b11000;
   5993   let Inst{16-12} = opcode;
   5994   let Inst{11-10} = 0b10;
   5995   let Inst{9-5}   = Rn;
   5996   let Inst{4-0}   = Rd;
   5997 }
   5998 
   5999 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
   6000   def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
   6001                                       asm, ".2d">;
   6002 }
   6003 
   6004 multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {
   6005   let Predicates = [HasNEON, HasFullFP16] in {
   6006   def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,
   6007                                       asm, ".2h">;
   6008   }
   6009   def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
   6010                                       asm, ".2s">;
   6011   def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
   6012                                       asm, ".2d">;
   6013 }
   6014 
   6015 //----------------------------------------------------------------------------
   6016 // AdvSIMD across lanes instructions
   6017 //----------------------------------------------------------------------------
   6018 
   6019 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   6020 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
   6021                           RegisterClass regtype, RegisterOperand vectype,
   6022                           string asm, string kind, list<dag> pattern>
   6023   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
   6024       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
   6025     Sched<[WriteV]> {
   6026   bits<5> Rd;
   6027   bits<5> Rn;
   6028   let Inst{31}    = 0;
   6029   let Inst{30}    = Q;
   6030   let Inst{29}    = U;
   6031   let Inst{28-24} = 0b01110;
   6032   let Inst{23-22} = size;
   6033   let Inst{21-17} = 0b11000;
   6034   let Inst{16-12} = opcode;
   6035   let Inst{11-10} = 0b10;
   6036   let Inst{9-5}   = Rn;
   6037   let Inst{4-0}   = Rd;
   6038 }
   6039 
   6040 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
   6041                               string asm> {
   6042   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8,  V64,
   6043                                    asm, ".8b", []>;
   6044   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8,  V128,
   6045                                    asm, ".16b", []>;
   6046   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
   6047                                    asm, ".4h", []>;
   6048   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
   6049                                    asm, ".8h", []>;
   6050   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
   6051                                    asm, ".4s", []>;
   6052 }
   6053 
   6054 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
   6055   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
   6056                                    asm, ".8b", []>;
   6057   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
   6058                                    asm, ".16b", []>;
   6059   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
   6060                                    asm, ".4h", []>;
   6061   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
   6062                                    asm, ".8h", []>;
   6063   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
   6064                                    asm, ".4s", []>;
   6065 }
   6066 
   6067 multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,
   6068                             Intrinsic intOp> {
   6069   let Predicates = [HasNEON, HasFullFP16] in {
   6070   def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,
   6071                                    asm, ".4h",
   6072         [(set FPR16:$Rd, (intOp (v4f16 V64:$Rn)))]>;
   6073   def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
   6074                                    asm, ".8h",
   6075         [(set FPR16:$Rd, (intOp (v8f16 V128:$Rn)))]>;
   6076   } // Predicates = [HasNEON, HasFullFP16]
   6077   def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
   6078                                    asm, ".4s",
   6079         [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
   6080 }
   6081 
   6082 //----------------------------------------------------------------------------
   6083 // AdvSIMD INS/DUP instructions
   6084 //----------------------------------------------------------------------------
   6085 
   6086 // FIXME: There has got to be a better way to factor these. ugh.
   6087 
   6088 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
   6089                      string operands, string constraints, list<dag> pattern>
   6090   : I<outs, ins, asm, operands, constraints, pattern>,
   6091     Sched<[WriteV]> {
   6092   bits<5> Rd;
   6093   bits<5> Rn;
   6094   let Inst{31} = 0;
   6095   let Inst{30} = Q;
   6096   let Inst{29} = op;
   6097   let Inst{28-21} = 0b01110000;
   6098   let Inst{15} = 0;
   6099   let Inst{10} = 1;
   6100   let Inst{9-5} = Rn;
   6101   let Inst{4-0} = Rd;
   6102 }
   6103 
   6104 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
   6105                       RegisterOperand vecreg, RegisterClass regtype>
   6106   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
   6107                    "{\t$Rd" # size # ", $Rn" #
   6108                    "|" # size # "\t$Rd, $Rn}", "",
   6109                    [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
   6110   let Inst{20-16} = imm5;
   6111   let Inst{14-11} = 0b0001;
   6112 }
   6113 
   6114 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
   6115                          ValueType vectype, ValueType insreg,
   6116                          RegisterOperand vecreg, Operand idxtype,
   6117                          ValueType elttype, SDNode OpNode>
   6118   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
   6119                    "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
   6120                    "|" # dstkind # "\t$Rd, $Rn$idx}", "",
   6121                  [(set (vectype vecreg:$Rd),
   6122                        (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
   6123   let Inst{14-11} = 0b0000;
   6124 }
   6125 
   6126 class SIMDDup64FromElement
   6127   : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
   6128                        VectorIndexD, i64, AArch64duplane64> {
   6129   bits<1> idx;
   6130   let Inst{20} = idx;
   6131   let Inst{19-16} = 0b1000;
   6132 }
   6133 
   6134 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
   6135                            RegisterOperand vecreg>
   6136   : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
   6137                        VectorIndexS, i64, AArch64duplane32> {
   6138   bits<2> idx;
   6139   let Inst{20-19} = idx;
   6140   let Inst{18-16} = 0b100;
   6141 }
   6142 
   6143 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
   6144                            RegisterOperand vecreg>
   6145   : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
   6146                        VectorIndexH, i64, AArch64duplane16> {
   6147   bits<3> idx;
   6148   let Inst{20-18} = idx;
   6149   let Inst{17-16} = 0b10;
   6150 }
   6151 
   6152 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
   6153                           RegisterOperand vecreg>
   6154   : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
   6155                        VectorIndexB, i64, AArch64duplane8> {
   6156   bits<4> idx;
   6157   let Inst{20-17} = idx;
   6158   let Inst{16} = 1;
   6159 }
   6160 
   6161 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
   6162                   Operand idxtype, string asm, list<dag> pattern>
   6163   : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
   6164                    "{\t$Rd, $Rn" # size # "$idx" #
   6165                    "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
   6166   let Inst{14-11} = imm4;
   6167 }
   6168 
   6169 class SIMDSMov<bit Q, string size, RegisterClass regtype,
   6170                Operand idxtype>
   6171   : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
   6172 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
   6173                Operand idxtype>
   6174   : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
   6175       [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
   6176 
   6177 class SIMDMovAlias<string asm, string size, Instruction inst,
   6178                    RegisterClass regtype, Operand idxtype>
   6179     : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
   6180                     "|" # size # "\t$dst, $src$idx}",
   6181                 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
   6182 
   6183 multiclass SMov {
   6184   def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
   6185     bits<4> idx;
   6186     let Inst{20-17} = idx;
   6187     let Inst{16} = 1;
   6188   }
   6189   def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
   6190     bits<4> idx;
   6191     let Inst{20-17} = idx;
   6192     let Inst{16} = 1;
   6193   }
   6194   def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
   6195     bits<3> idx;
   6196     let Inst{20-18} = idx;
   6197     let Inst{17-16} = 0b10;
   6198   }
   6199   def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
   6200     bits<3> idx;
   6201     let Inst{20-18} = idx;
   6202     let Inst{17-16} = 0b10;
   6203   }
   6204   def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
   6205     bits<2> idx;
   6206     let Inst{20-19} = idx;
   6207     let Inst{18-16} = 0b100;
   6208   }
   6209 }
   6210 
   6211 multiclass UMov {
   6212   def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
   6213     bits<4> idx;
   6214     let Inst{20-17} = idx;
   6215     let Inst{16} = 1;
   6216   }
   6217   def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
   6218     bits<3> idx;
   6219     let Inst{20-18} = idx;
   6220     let Inst{17-16} = 0b10;
   6221   }
   6222   def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
   6223     bits<2> idx;
   6224     let Inst{20-19} = idx;
   6225     let Inst{18-16} = 0b100;
   6226   }
   6227   def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
   6228     bits<1> idx;
   6229     let Inst{20} = idx;
   6230     let Inst{19-16} = 0b1000;
   6231   }
   6232   def : SIMDMovAlias<"mov", ".s",
   6233                      !cast<Instruction>(NAME#"vi32"),
   6234                      GPR32, VectorIndexS>;
   6235   def : SIMDMovAlias<"mov", ".d",
   6236                      !cast<Instruction>(NAME#"vi64"),
   6237                      GPR64, VectorIndexD>;
   6238 }
   6239 
   6240 class SIMDInsFromMain<string size, ValueType vectype,
   6241                       RegisterClass regtype, Operand idxtype>
   6242   : BaseSIMDInsDup<1, 0, (outs V128:$dst),
   6243                    (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
   6244                    "{\t$Rd" # size # "$idx, $Rn" #
   6245                    "|" # size # "\t$Rd$idx, $Rn}",
   6246                    "$Rd = $dst",
   6247             [(set V128:$dst,
   6248               (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
   6249   let Inst{14-11} = 0b0011;
   6250 }
   6251 
   6252 class SIMDInsFromElement<string size, ValueType vectype,
   6253                          ValueType elttype, Operand idxtype>
   6254   : BaseSIMDInsDup<1, 1, (outs V128:$dst),
   6255                    (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
   6256                    "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
   6257                    "|" # size # "\t$Rd$idx, $Rn$idx2}",
   6258                    "$Rd = $dst",
   6259          [(set V128:$dst,
   6260                (vector_insert
   6261                  (vectype V128:$Rd),
   6262                  (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
   6263                  idxtype:$idx))]>;
   6264 
   6265 class SIMDInsMainMovAlias<string size, Instruction inst,
   6266                           RegisterClass regtype, Operand idxtype>
   6267     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
   6268                         "|" # size #"\t$dst$idx, $src}",
   6269                 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
   6270 class SIMDInsElementMovAlias<string size, Instruction inst,
   6271                              Operand idxtype>
   6272     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
   6273                       # "|" # size #"\t$dst$idx, $src$idx2}",
   6274                 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
   6275 
   6276 
   6277 multiclass SIMDIns {
   6278   def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
   6279     bits<4> idx;
   6280     let Inst{20-17} = idx;
   6281     let Inst{16} = 1;
   6282   }
   6283   def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
   6284     bits<3> idx;
   6285     let Inst{20-18} = idx;
   6286     let Inst{17-16} = 0b10;
   6287   }
   6288   def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
   6289     bits<2> idx;
   6290     let Inst{20-19} = idx;
   6291     let Inst{18-16} = 0b100;
   6292   }
   6293   def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
   6294     bits<1> idx;
   6295     let Inst{20} = idx;
   6296     let Inst{19-16} = 0b1000;
   6297   }
   6298 
   6299   def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
   6300     bits<4> idx;
   6301     bits<4> idx2;
   6302     let Inst{20-17} = idx;
   6303     let Inst{16} = 1;
   6304     let Inst{14-11} = idx2;
   6305   }
   6306   def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
   6307     bits<3> idx;
   6308     bits<3> idx2;
   6309     let Inst{20-18} = idx;
   6310     let Inst{17-16} = 0b10;
   6311     let Inst{14-12} = idx2;
   6312     let Inst{11} = {?};
   6313   }
   6314   def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
   6315     bits<2> idx;
   6316     bits<2> idx2;
   6317     let Inst{20-19} = idx;
   6318     let Inst{18-16} = 0b100;
   6319     let Inst{14-13} = idx2;
   6320     let Inst{12-11} = {?,?};
   6321   }
   6322   def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
   6323     bits<1> idx;
   6324     bits<1> idx2;
   6325     let Inst{20} = idx;
   6326     let Inst{19-16} = 0b1000;
   6327     let Inst{14} = idx2;
   6328     let Inst{13-11} = {?,?,?};
   6329   }
   6330 
   6331   // For all forms of the INS instruction, the "mov" mnemonic is the
   6332   // preferred alias. Why they didn't just call the instruction "mov" in
   6333   // the first place is a very good question indeed...
   6334   def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
   6335                          GPR32, VectorIndexB>;
   6336   def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
   6337                          GPR32, VectorIndexH>;
   6338   def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
   6339                          GPR32, VectorIndexS>;
   6340   def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
   6341                          GPR64, VectorIndexD>;
   6342 
   6343   def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
   6344                          VectorIndexB>;
   6345   def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
   6346                          VectorIndexH>;
   6347   def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
   6348                          VectorIndexS>;
   6349   def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
   6350                          VectorIndexD>;
   6351 }
   6352 
   6353 //----------------------------------------------------------------------------
   6354 // AdvSIMD TBL/TBX
   6355 //----------------------------------------------------------------------------
   6356 
   6357 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   6358 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
   6359                           RegisterOperand listtype, string asm, string kind>
   6360   : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
   6361        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
   6362     Sched<[WriteV]> {
   6363   bits<5> Vd;
   6364   bits<5> Vn;
   6365   bits<5> Vm;
   6366   let Inst{31}    = 0;
   6367   let Inst{30}    = Q;
   6368   let Inst{29-21} = 0b001110000;
   6369   let Inst{20-16} = Vm;
   6370   let Inst{15}    = 0;
   6371   let Inst{14-13} = len;
   6372   let Inst{12}    = op;
   6373   let Inst{11-10} = 0b00;
   6374   let Inst{9-5}   = Vn;
   6375   let Inst{4-0}   = Vd;
   6376 }
   6377 
   6378 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   6379 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
   6380                           RegisterOperand listtype, string asm, string kind>
   6381   : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
   6382        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
   6383     Sched<[WriteV]> {
   6384   bits<5> Vd;
   6385   bits<5> Vn;
   6386   bits<5> Vm;
   6387   let Inst{31}    = 0;
   6388   let Inst{30}    = Q;
   6389   let Inst{29-21} = 0b001110000;
   6390   let Inst{20-16} = Vm;
   6391   let Inst{15}    = 0;
   6392   let Inst{14-13} = len;
   6393   let Inst{12}    = op;
   6394   let Inst{11-10} = 0b00;
   6395   let Inst{9-5}   = Vn;
   6396   let Inst{4-0}   = Vd;
   6397 }
   6398 
   6399 class SIMDTableLookupAlias<string asm, Instruction inst,
   6400                           RegisterOperand vectype, RegisterOperand listtype>
   6401     : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
   6402                 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
   6403 
   6404 multiclass SIMDTableLookup<bit op, string asm> {
   6405   def v8i8One   : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
   6406                                       asm, ".8b">;
   6407   def v8i8Two   : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
   6408                                       asm, ".8b">;
   6409   def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
   6410                                       asm, ".8b">;
   6411   def v8i8Four  : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
   6412                                       asm, ".8b">;
   6413   def v16i8One  : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
   6414                                       asm, ".16b">;
   6415   def v16i8Two  : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
   6416                                       asm, ".16b">;
   6417   def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
   6418                                       asm, ".16b">;
   6419   def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
   6420                                       asm, ".16b">;
   6421 
   6422   def : SIMDTableLookupAlias<asm # ".8b",
   6423                          !cast<Instruction>(NAME#"v8i8One"),
   6424                          V64, VecListOne128>;
   6425   def : SIMDTableLookupAlias<asm # ".8b",
   6426                          !cast<Instruction>(NAME#"v8i8Two"),
   6427                          V64, VecListTwo128>;
   6428   def : SIMDTableLookupAlias<asm # ".8b",
   6429                          !cast<Instruction>(NAME#"v8i8Three"),
   6430                          V64, VecListThree128>;
   6431   def : SIMDTableLookupAlias<asm # ".8b",
   6432                          !cast<Instruction>(NAME#"v8i8Four"),
   6433                          V64, VecListFour128>;
   6434   def : SIMDTableLookupAlias<asm # ".16b",
   6435                          !cast<Instruction>(NAME#"v16i8One"),
   6436                          V128, VecListOne128>;
   6437   def : SIMDTableLookupAlias<asm # ".16b",
   6438                          !cast<Instruction>(NAME#"v16i8Two"),
   6439                          V128, VecListTwo128>;
   6440   def : SIMDTableLookupAlias<asm # ".16b",
   6441                          !cast<Instruction>(NAME#"v16i8Three"),
   6442                          V128, VecListThree128>;
   6443   def : SIMDTableLookupAlias<asm # ".16b",
   6444                          !cast<Instruction>(NAME#"v16i8Four"),
   6445                          V128, VecListFour128>;
   6446 }
   6447 
   6448 multiclass SIMDTableLookupTied<bit op, string asm> {
   6449   def v8i8One   : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
   6450                                       asm, ".8b">;
   6451   def v8i8Two   : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
   6452                                       asm, ".8b">;
   6453   def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
   6454                                       asm, ".8b">;
   6455   def v8i8Four  : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
   6456                                       asm, ".8b">;
   6457   def v16i8One  : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
   6458                                       asm, ".16b">;
   6459   def v16i8Two  : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
   6460                                       asm, ".16b">;
   6461   def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
   6462                                       asm, ".16b">;
   6463   def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
   6464                                       asm, ".16b">;
   6465 
   6466   def : SIMDTableLookupAlias<asm # ".8b",
   6467                          !cast<Instruction>(NAME#"v8i8One"),
   6468                          V64, VecListOne128>;
   6469   def : SIMDTableLookupAlias<asm # ".8b",
   6470                          !cast<Instruction>(NAME#"v8i8Two"),
   6471                          V64, VecListTwo128>;
   6472   def : SIMDTableLookupAlias<asm # ".8b",
   6473                          !cast<Instruction>(NAME#"v8i8Three"),
   6474                          V64, VecListThree128>;
   6475   def : SIMDTableLookupAlias<asm # ".8b",
   6476                          !cast<Instruction>(NAME#"v8i8Four"),
   6477                          V64, VecListFour128>;
   6478   def : SIMDTableLookupAlias<asm # ".16b",
   6479                          !cast<Instruction>(NAME#"v16i8One"),
   6480                          V128, VecListOne128>;
   6481   def : SIMDTableLookupAlias<asm # ".16b",
   6482                          !cast<Instruction>(NAME#"v16i8Two"),
   6483                          V128, VecListTwo128>;
   6484   def : SIMDTableLookupAlias<asm # ".16b",
   6485                          !cast<Instruction>(NAME#"v16i8Three"),
   6486                          V128, VecListThree128>;
   6487   def : SIMDTableLookupAlias<asm # ".16b",
   6488                          !cast<Instruction>(NAME#"v16i8Four"),
   6489                          V128, VecListFour128>;
   6490 }
   6491 
   6492 
   6493 //----------------------------------------------------------------------------
   6494 // AdvSIMD scalar CPY
   6495 //----------------------------------------------------------------------------
   6496 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   6497 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
   6498                         string kind, Operand idxtype>
   6499   : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
   6500        "{\t$dst, $src" # kind # "$idx" #
   6501        "|\t$dst, $src$idx}", "", []>,
   6502     Sched<[WriteV]> {
   6503   bits<5> dst;
   6504   bits<5> src;
   6505   let Inst{31-21} = 0b01011110000;
   6506   let Inst{15-10} = 0b000001;
   6507   let Inst{9-5}   = src;
   6508   let Inst{4-0}   = dst;
   6509 }
   6510 
   6511 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
   6512       RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
   6513     : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
   6514                     # "|\t$dst, $src$index}",
   6515                 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
   6516 
   6517 
   6518 multiclass SIMDScalarCPY<string asm> {
   6519   def i8  : BaseSIMDScalarCPY<FPR8,  V128, ".b", VectorIndexB> {
   6520     bits<4> idx;
   6521     let Inst{20-17} = idx;
   6522     let Inst{16} = 1;
   6523   }
   6524   def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
   6525     bits<3> idx;
   6526     let Inst{20-18} = idx;
   6527     let Inst{17-16} = 0b10;
   6528   }
   6529   def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
   6530     bits<2> idx;
   6531     let Inst{20-19} = idx;
   6532     let Inst{18-16} = 0b100;
   6533   }
   6534   def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
   6535     bits<1> idx;
   6536     let Inst{20} = idx;
   6537     let Inst{19-16} = 0b1000;
   6538   }
   6539 
   6540   def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
   6541                                                           VectorIndexD:$idx)))),
   6542             (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
   6543 
   6544   // 'DUP' mnemonic aliases.
   6545   def : SIMDScalarCPYAlias<"dup", ".b",
   6546                            !cast<Instruction>(NAME#"i8"),
   6547                            FPR8, V128, VectorIndexB>;
   6548   def : SIMDScalarCPYAlias<"dup", ".h",
   6549                            !cast<Instruction>(NAME#"i16"),
   6550                            FPR16, V128, VectorIndexH>;
   6551   def : SIMDScalarCPYAlias<"dup", ".s",
   6552                            !cast<Instruction>(NAME#"i32"),
   6553                            FPR32, V128, VectorIndexS>;
   6554   def : SIMDScalarCPYAlias<"dup", ".d",
   6555                            !cast<Instruction>(NAME#"i64"),
   6556                            FPR64, V128, VectorIndexD>;
   6557 }
   6558 
   6559 //----------------------------------------------------------------------------
   6560 // AdvSIMD modified immediate instructions
   6561 //----------------------------------------------------------------------------
   6562 
   6563 class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,
   6564                           string asm, string op_string,
   6565                           string cstr, list<dag> pattern>
   6566   : I<oops, iops, asm, op_string, cstr, pattern>,
   6567     Sched<[WriteV]> {
   6568   bits<5> Rd;
   6569   bits<8> imm8;
   6570   let Inst{31}    = 0;
   6571   let Inst{30}    = Q;
   6572   let Inst{29}    = op;
   6573   let Inst{28-19} = 0b0111100000;
   6574   let Inst{18-16} = imm8{7-5};
   6575   let Inst{11} = op2;
   6576   let Inst{10} = 1;
   6577   let Inst{9-5}   = imm8{4-0};
   6578   let Inst{4-0}   = Rd;
   6579 }
   6580 
   6581 class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,
   6582                                 Operand immtype, dag opt_shift_iop,
   6583                                 string opt_shift, string asm, string kind,
   6584                                 list<dag> pattern>
   6585   : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),
   6586                         !con((ins immtype:$imm8), opt_shift_iop), asm,
   6587                         "{\t$Rd" # kind # ", $imm8" # opt_shift #
   6588                         "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
   6589                         "", pattern> {
   6590   let DecoderMethod = "DecodeModImmInstruction";
   6591 }
   6592 
   6593 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
   6594                                 Operand immtype, dag opt_shift_iop,
   6595                                 string opt_shift, string asm, string kind,
   6596                                 list<dag> pattern>
   6597   : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),
   6598                         !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
   6599                         asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
   6600                              "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
   6601                         "$Rd = $dst", pattern> {
   6602   let DecoderMethod = "DecodeModImmTiedInstruction";
   6603 }
   6604 
   6605 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
   6606                                      RegisterOperand vectype, string asm,
   6607                                      string kind, list<dag> pattern>
   6608   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
   6609                               (ins logical_vec_shift:$shift),
   6610                               "$shift", asm, kind, pattern> {
   6611   bits<2> shift;
   6612   let Inst{15}    = b15_b12{1};
   6613   let Inst{14-13} = shift;
   6614   let Inst{12}    = b15_b12{0};
   6615 }
   6616 
   6617 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
   6618                                      RegisterOperand vectype, string asm,
   6619                                      string kind, list<dag> pattern>
   6620   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
   6621                               (ins logical_vec_shift:$shift),
   6622                               "$shift", asm, kind, pattern> {
   6623   bits<2> shift;
   6624   let Inst{15}    = b15_b12{1};
   6625   let Inst{14-13} = shift;
   6626   let Inst{12}    = b15_b12{0};
   6627 }
   6628 
   6629 
   6630 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
   6631                                          RegisterOperand vectype, string asm,
   6632                                          string kind, list<dag> pattern>
   6633   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
   6634                               (ins logical_vec_hw_shift:$shift),
   6635                               "$shift", asm, kind, pattern> {
   6636   bits<2> shift;
   6637   let Inst{15} = b15_b12{1};
   6638   let Inst{14} = 0;
   6639   let Inst{13} = shift{0};
   6640   let Inst{12} = b15_b12{0};
   6641 }
   6642 
   6643 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
   6644                                          RegisterOperand vectype, string asm,
   6645                                          string kind, list<dag> pattern>
   6646   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
   6647                               (ins logical_vec_hw_shift:$shift),
   6648                               "$shift", asm, kind, pattern> {
   6649   bits<2> shift;
   6650   let Inst{15} = b15_b12{1};
   6651   let Inst{14} = 0;
   6652   let Inst{13} = shift{0};
   6653   let Inst{12} = b15_b12{0};
   6654 }
   6655 
   6656 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
   6657                                       string asm> {
   6658   def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
   6659                                                  asm, ".4h", []>;
   6660   def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
   6661                                                  asm, ".8h", []>;
   6662 
   6663   def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
   6664                                              asm, ".2s", []>;
   6665   def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
   6666                                              asm, ".4s", []>;
   6667 }
   6668 
   6669 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
   6670                                       bits<2> w_cmode, string asm,
   6671                                       SDNode OpNode> {
   6672   def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
   6673                                                  asm, ".4h",
   6674              [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
   6675                                              imm0_255:$imm8,
   6676                                              (i32 imm:$shift)))]>;
   6677   def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
   6678                                                  asm, ".8h",
   6679              [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
   6680                                               imm0_255:$imm8,
   6681                                               (i32 imm:$shift)))]>;
   6682 
   6683   def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
   6684                                              asm, ".2s",
   6685              [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
   6686                                              imm0_255:$imm8,
   6687                                              (i32 imm:$shift)))]>;
   6688   def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
   6689                                              asm, ".4s",
   6690              [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
   6691                                               imm0_255:$imm8,
   6692                                               (i32 imm:$shift)))]>;
   6693 }
   6694 
   6695 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
   6696                              RegisterOperand vectype, string asm,
   6697                              string kind, list<dag> pattern>
   6698   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
   6699                               (ins move_vec_shift:$shift),
   6700                               "$shift", asm, kind, pattern> {
   6701   bits<1> shift;
   6702   let Inst{15-13} = cmode{3-1};
   6703   let Inst{12}    = shift;
   6704 }
   6705 
   6706 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,
   6707                                    RegisterOperand vectype,
   6708                                    Operand imm_type, string asm,
   6709                                    string kind, list<dag> pattern>
   6710   : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",
   6711                               asm, kind, pattern> {
   6712   let Inst{15-12} = cmode;
   6713 }
   6714 
   6715 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
   6716                                    list<dag> pattern>
   6717   : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
   6718                         "\t$Rd, $imm8", "", pattern> {
   6719   let Inst{15-12} = cmode;
   6720   let DecoderMethod = "DecodeModImmInstruction";
   6721 }
   6722 
   6723 //----------------------------------------------------------------------------
   6724 // AdvSIMD indexed element
   6725 //----------------------------------------------------------------------------
   6726 
   6727 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   6728 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
   6729                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
   6730                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
   6731                       string apple_kind, string dst_kind, string lhs_kind,
   6732                       string rhs_kind, list<dag> pattern>
   6733   : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
   6734       asm,
   6735       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
   6736       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
   6737     Sched<[WriteV]> {
   6738   bits<5> Rd;
   6739   bits<5> Rn;
   6740   bits<5> Rm;
   6741 
   6742   let Inst{31}    = 0;
   6743   let Inst{30}    = Q;
   6744   let Inst{29}    = U;
   6745   let Inst{28}    = Scalar;
   6746   let Inst{27-24} = 0b1111;
   6747   let Inst{23-22} = size;
   6748   // Bit 21 must be set by the derived class.
   6749   let Inst{20-16} = Rm;
   6750   let Inst{15-12} = opc;
   6751   // Bit 11 must be set by the derived class.
   6752   let Inst{10}    = 0;
   6753   let Inst{9-5}   = Rn;
   6754   let Inst{4-0}   = Rd;
   6755 }
   6756 
   6757 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   6758 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
   6759                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
   6760                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
   6761                       string apple_kind, string dst_kind, string lhs_kind,
   6762                       string rhs_kind, list<dag> pattern>
   6763   : I<(outs dst_reg:$dst),
   6764       (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
   6765       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
   6766       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
   6767     Sched<[WriteV]> {
   6768   bits<5> Rd;
   6769   bits<5> Rn;
   6770   bits<5> Rm;
   6771 
   6772   let Inst{31}    = 0;
   6773   let Inst{30}    = Q;
   6774   let Inst{29}    = U;
   6775   let Inst{28}    = Scalar;
   6776   let Inst{27-24} = 0b1111;
   6777   let Inst{23-22} = size;
   6778   // Bit 21 must be set by the derived class.
   6779   let Inst{20-16} = Rm;
   6780   let Inst{15-12} = opc;
   6781   // Bit 11 must be set by the derived class.
   6782   let Inst{10}    = 0;
   6783   let Inst{9-5}   = Rn;
   6784   let Inst{4-0}   = Rd;
   6785 }
   6786 
   6787 multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
   6788                          SDPatternOperator OpNode> {
   6789   let Predicates = [HasNEON, HasFullFP16] in {
   6790   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,
   6791                                       V64, V64,
   6792                                       V128_lo, VectorIndexH,
   6793                                       asm, ".4h", ".4h", ".4h", ".h",
   6794     [(set (v4f16 V64:$Rd),
   6795         (OpNode (v4f16 V64:$Rn),
   6796          (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   6797     bits<3> idx;
   6798     let Inst{11} = idx{2};
   6799     let Inst{21} = idx{1};
   6800     let Inst{20} = idx{0};
   6801   }
   6802 
   6803   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
   6804                                       V128, V128,
   6805                                       V128_lo, VectorIndexH,
   6806                                       asm, ".8h", ".8h", ".8h", ".h",
   6807     [(set (v8f16 V128:$Rd),
   6808         (OpNode (v8f16 V128:$Rn),
   6809          (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   6810     bits<3> idx;
   6811     let Inst{11} = idx{2};
   6812     let Inst{21} = idx{1};
   6813     let Inst{20} = idx{0};
   6814   }
   6815   } // Predicates = [HasNEON, HasFullFP16]
   6816 
   6817   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
   6818                                       V64, V64,
   6819                                       V128, VectorIndexS,
   6820                                       asm, ".2s", ".2s", ".2s", ".s",
   6821     [(set (v2f32 V64:$Rd),
   6822         (OpNode (v2f32 V64:$Rn),
   6823          (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
   6824     bits<2> idx;
   6825     let Inst{11} = idx{1};
   6826     let Inst{21} = idx{0};
   6827   }
   6828 
   6829   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
   6830                                       V128, V128,
   6831                                       V128, VectorIndexS,
   6832                                       asm, ".4s", ".4s", ".4s", ".s",
   6833     [(set (v4f32 V128:$Rd),
   6834         (OpNode (v4f32 V128:$Rn),
   6835          (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
   6836     bits<2> idx;
   6837     let Inst{11} = idx{1};
   6838     let Inst{21} = idx{0};
   6839   }
   6840 
   6841   def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
   6842                                       V128, V128,
   6843                                       V128, VectorIndexD,
   6844                                       asm, ".2d", ".2d", ".2d", ".d",
   6845     [(set (v2f64 V128:$Rd),
   6846         (OpNode (v2f64 V128:$Rn),
   6847          (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
   6848     bits<1> idx;
   6849     let Inst{11} = idx{0};
   6850     let Inst{21} = 0;
   6851   }
   6852 
   6853   let Predicates = [HasNEON, HasFullFP16] in {
   6854   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,
   6855                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
   6856                                       asm, ".h", "", "", ".h",
   6857     [(set (f16 FPR16Op:$Rd),
   6858           (OpNode (f16 FPR16Op:$Rn),
   6859                   (f16 (vector_extract (v8f16 V128_lo:$Rm),
   6860                                        VectorIndexH:$idx))))]> {
   6861     bits<3> idx;
   6862     let Inst{11} = idx{2};
   6863     let Inst{21} = idx{1};
   6864     let Inst{20} = idx{0};
   6865   }
   6866   } // Predicates = [HasNEON, HasFullFP16]
   6867 
   6868   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
   6869                                       FPR32Op, FPR32Op, V128, VectorIndexS,
   6870                                       asm, ".s", "", "", ".s",
   6871     [(set (f32 FPR32Op:$Rd),
   6872           (OpNode (f32 FPR32Op:$Rn),
   6873                   (f32 (vector_extract (v4f32 V128:$Rm),
   6874                                        VectorIndexS:$idx))))]> {
   6875     bits<2> idx;
   6876     let Inst{11} = idx{1};
   6877     let Inst{21} = idx{0};
   6878   }
   6879 
   6880   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
   6881                                       FPR64Op, FPR64Op, V128, VectorIndexD,
   6882                                       asm, ".d", "", "", ".d",
   6883     [(set (f64 FPR64Op:$Rd),
   6884           (OpNode (f64 FPR64Op:$Rn),
   6885                   (f64 (vector_extract (v2f64 V128:$Rm),
   6886                                        VectorIndexD:$idx))))]> {
   6887     bits<1> idx;
   6888     let Inst{11} = idx{0};
   6889     let Inst{21} = 0;
   6890   }
   6891 }
   6892 
   6893 multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
   6894   // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
   6895   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
   6896                            (AArch64duplane32 (v4f32 V128:$Rm),
   6897                                            VectorIndexS:$idx))),
   6898             (!cast<Instruction>(INST # v2i32_indexed)
   6899                 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
   6900   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
   6901                            (AArch64dup (f32 FPR32Op:$Rm)))),
   6902             (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
   6903                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
   6904 
   6905 
   6906   // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
   6907   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
   6908                            (AArch64duplane32 (v4f32 V128:$Rm),
   6909                                            VectorIndexS:$idx))),
   6910             (!cast<Instruction>(INST # "v4i32_indexed")
   6911                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
   6912   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
   6913                            (AArch64dup (f32 FPR32Op:$Rm)))),
   6914             (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
   6915                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
   6916 
   6917   // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
   6918   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
   6919                            (AArch64duplane64 (v2f64 V128:$Rm),
   6920                                            VectorIndexD:$idx))),
   6921             (!cast<Instruction>(INST # "v2i64_indexed")
   6922                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
   6923   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
   6924                            (AArch64dup (f64 FPR64Op:$Rm)))),
   6925             (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
   6926                 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
   6927 
   6928   // 2 variants for 32-bit scalar version: extract from .2s or from .4s
   6929   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
   6930                          (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
   6931             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
   6932                 V128:$Rm, VectorIndexS:$idx)>;
   6933   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
   6934                          (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
   6935             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
   6936                 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
   6937 
   6938   // 1 variant for 64-bit scalar version: extract from .1d or from .2d
   6939   def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
   6940                          (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
   6941             (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
   6942                 V128:$Rm, VectorIndexD:$idx)>;
   6943 }
   6944 
   6945 multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
   6946   let Predicates = [HasNEON, HasFullFP16] in {
   6947   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,
   6948                                           V128_lo, VectorIndexH,
   6949                                           asm, ".4h", ".4h", ".4h", ".h", []> {
   6950     bits<3> idx;
   6951     let Inst{11} = idx{2};
   6952     let Inst{21} = idx{1};
   6953     let Inst{20} = idx{0};
   6954   }
   6955 
   6956   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
   6957                                           V128, V128,
   6958                                           V128_lo, VectorIndexH,
   6959                                           asm, ".8h", ".8h", ".8h", ".h", []> {
   6960     bits<3> idx;
   6961     let Inst{11} = idx{2};
   6962     let Inst{21} = idx{1};
   6963     let Inst{20} = idx{0};
   6964   }
   6965   } // Predicates = [HasNEON, HasFullFP16]
   6966 
   6967   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
   6968                                           V128, VectorIndexS,
   6969                                           asm, ".2s", ".2s", ".2s", ".s", []> {
   6970     bits<2> idx;
   6971     let Inst{11} = idx{1};
   6972     let Inst{21} = idx{0};
   6973   }
   6974 
   6975   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
   6976                                       V128, V128,
   6977                                       V128, VectorIndexS,
   6978                                       asm, ".4s", ".4s", ".4s", ".s", []> {
   6979     bits<2> idx;
   6980     let Inst{11} = idx{1};
   6981     let Inst{21} = idx{0};
   6982   }
   6983 
   6984   def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
   6985                                       V128, V128,
   6986                                       V128, VectorIndexD,
   6987                                       asm, ".2d", ".2d", ".2d", ".d", []> {
   6988     bits<1> idx;
   6989     let Inst{11} = idx{0};
   6990     let Inst{21} = 0;
   6991   }
   6992 
   6993   let Predicates = [HasNEON, HasFullFP16] in {
   6994   def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,
   6995                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
   6996                                       asm, ".h", "", "", ".h", []> {
   6997     bits<3> idx;
   6998     let Inst{11} = idx{2};
   6999     let Inst{21} = idx{1};
   7000     let Inst{20} = idx{0};
   7001   }
   7002   } // Predicates = [HasNEON, HasFullFP16]
   7003 
   7004   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
   7005                                       FPR32Op, FPR32Op, V128, VectorIndexS,
   7006                                       asm, ".s", "", "", ".s", []> {
   7007     bits<2> idx;
   7008     let Inst{11} = idx{1};
   7009     let Inst{21} = idx{0};
   7010   }
   7011 
   7012   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
   7013                                       FPR64Op, FPR64Op, V128, VectorIndexD,
   7014                                       asm, ".d", "", "", ".d", []> {
   7015     bits<1> idx;
   7016     let Inst{11} = idx{0};
   7017     let Inst{21} = 0;
   7018   }
   7019 }
   7020 
   7021 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
   7022                          SDPatternOperator OpNode> {
   7023   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
   7024                                       V128_lo, VectorIndexH,
   7025                                       asm, ".4h", ".4h", ".4h", ".h",
   7026     [(set (v4i16 V64:$Rd),
   7027         (OpNode (v4i16 V64:$Rn),
   7028          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7029     bits<3> idx;
   7030     let Inst{11} = idx{2};
   7031     let Inst{21} = idx{1};
   7032     let Inst{20} = idx{0};
   7033   }
   7034 
   7035   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
   7036                                       V128, V128,
   7037                                       V128_lo, VectorIndexH,
   7038                                       asm, ".8h", ".8h", ".8h", ".h",
   7039     [(set (v8i16 V128:$Rd),
   7040        (OpNode (v8i16 V128:$Rn),
   7041          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7042     bits<3> idx;
   7043     let Inst{11} = idx{2};
   7044     let Inst{21} = idx{1};
   7045     let Inst{20} = idx{0};
   7046   }
   7047 
   7048   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
   7049                                       V64, V64,
   7050                                       V128, VectorIndexS,
   7051                                       asm, ".2s", ".2s", ".2s",  ".s",
   7052     [(set (v2i32 V64:$Rd),
   7053        (OpNode (v2i32 V64:$Rn),
   7054           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7055     bits<2> idx;
   7056     let Inst{11} = idx{1};
   7057     let Inst{21} = idx{0};
   7058   }
   7059 
   7060   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
   7061                                       V128, V128,
   7062                                       V128, VectorIndexS,
   7063                                       asm, ".4s", ".4s", ".4s", ".s",
   7064     [(set (v4i32 V128:$Rd),
   7065        (OpNode (v4i32 V128:$Rn),
   7066           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7067     bits<2> idx;
   7068     let Inst{11} = idx{1};
   7069     let Inst{21} = idx{0};
   7070   }
   7071 
   7072   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
   7073                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
   7074                                       asm, ".h", "", "", ".h", []> {
   7075     bits<3> idx;
   7076     let Inst{11} = idx{2};
   7077     let Inst{21} = idx{1};
   7078     let Inst{20} = idx{0};
   7079   }
   7080 
   7081   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
   7082                                       FPR32Op, FPR32Op, V128, VectorIndexS,
   7083                                       asm, ".s", "", "", ".s",
   7084       [(set (i32 FPR32Op:$Rd),
   7085             (OpNode FPR32Op:$Rn,
   7086                     (i32 (vector_extract (v4i32 V128:$Rm),
   7087                                          VectorIndexS:$idx))))]> {
   7088     bits<2> idx;
   7089     let Inst{11} = idx{1};
   7090     let Inst{21} = idx{0};
   7091   }
   7092 }
   7093 
   7094 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
   7095                                SDPatternOperator OpNode> {
   7096   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
   7097                                       V64, V64,
   7098                                       V128_lo, VectorIndexH,
   7099                                       asm, ".4h", ".4h", ".4h", ".h",
   7100     [(set (v4i16 V64:$Rd),
   7101         (OpNode (v4i16 V64:$Rn),
   7102          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7103     bits<3> idx;
   7104     let Inst{11} = idx{2};
   7105     let Inst{21} = idx{1};
   7106     let Inst{20} = idx{0};
   7107   }
   7108 
   7109   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
   7110                                       V128, V128,
   7111                                       V128_lo, VectorIndexH,
   7112                                       asm, ".8h", ".8h", ".8h", ".h",
   7113     [(set (v8i16 V128:$Rd),
   7114        (OpNode (v8i16 V128:$Rn),
   7115          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7116     bits<3> idx;
   7117     let Inst{11} = idx{2};
   7118     let Inst{21} = idx{1};
   7119     let Inst{20} = idx{0};
   7120   }
   7121 
   7122   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
   7123                                       V64, V64,
   7124                                       V128, VectorIndexS,
   7125                                       asm, ".2s", ".2s", ".2s", ".s",
   7126     [(set (v2i32 V64:$Rd),
   7127        (OpNode (v2i32 V64:$Rn),
   7128           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7129     bits<2> idx;
   7130     let Inst{11} = idx{1};
   7131     let Inst{21} = idx{0};
   7132   }
   7133 
   7134   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
   7135                                       V128, V128,
   7136                                       V128, VectorIndexS,
   7137                                       asm, ".4s", ".4s", ".4s", ".s",
   7138     [(set (v4i32 V128:$Rd),
   7139        (OpNode (v4i32 V128:$Rn),
   7140           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7141     bits<2> idx;
   7142     let Inst{11} = idx{1};
   7143     let Inst{21} = idx{0};
   7144   }
   7145 }
   7146 
   7147 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
   7148                                    SDPatternOperator OpNode> {
   7149   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
   7150                                           V128_lo, VectorIndexH,
   7151                                           asm, ".4h", ".4h", ".4h", ".h",
   7152     [(set (v4i16 V64:$dst),
   7153         (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
   7154          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7155     bits<3> idx;
   7156     let Inst{11} = idx{2};
   7157     let Inst{21} = idx{1};
   7158     let Inst{20} = idx{0};
   7159   }
   7160 
   7161   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
   7162                                       V128, V128,
   7163                                       V128_lo, VectorIndexH,
   7164                                       asm, ".8h", ".8h", ".8h", ".h",
   7165     [(set (v8i16 V128:$dst),
   7166        (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
   7167          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7168     bits<3> idx;
   7169     let Inst{11} = idx{2};
   7170     let Inst{21} = idx{1};
   7171     let Inst{20} = idx{0};
   7172   }
   7173 
   7174   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
   7175                                       V64, V64,
   7176                                       V128, VectorIndexS,
   7177                                       asm, ".2s", ".2s", ".2s", ".s",
   7178     [(set (v2i32 V64:$dst),
   7179        (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
   7180           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7181     bits<2> idx;
   7182     let Inst{11} = idx{1};
   7183     let Inst{21} = idx{0};
   7184   }
   7185 
   7186   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
   7187                                       V128, V128,
   7188                                       V128, VectorIndexS,
   7189                                       asm, ".4s", ".4s", ".4s", ".s",
   7190     [(set (v4i32 V128:$dst),
   7191        (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
   7192           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7193     bits<2> idx;
   7194     let Inst{11} = idx{1};
   7195     let Inst{21} = idx{0};
   7196   }
   7197 }
   7198 
   7199 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
   7200                              SDPatternOperator OpNode> {
   7201   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
   7202                                       V128, V64,
   7203                                       V128_lo, VectorIndexH,
   7204                                       asm, ".4s", ".4s", ".4h", ".h",
   7205     [(set (v4i32 V128:$Rd),
   7206         (OpNode (v4i16 V64:$Rn),
   7207          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7208     bits<3> idx;
   7209     let Inst{11} = idx{2};
   7210     let Inst{21} = idx{1};
   7211     let Inst{20} = idx{0};
   7212   }
   7213 
   7214   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
   7215                                       V128, V128,
   7216                                       V128_lo, VectorIndexH,
   7217                                       asm#"2", ".4s", ".4s", ".8h", ".h",
   7218     [(set (v4i32 V128:$Rd),
   7219           (OpNode (extract_high_v8i16 V128:$Rn),
   7220                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   7221                                                       VectorIndexH:$idx))))]> {
   7222 
   7223     bits<3> idx;
   7224     let Inst{11} = idx{2};
   7225     let Inst{21} = idx{1};
   7226     let Inst{20} = idx{0};
   7227   }
   7228 
   7229   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
   7230                                       V128, V64,
   7231                                       V128, VectorIndexS,
   7232                                       asm, ".2d", ".2d", ".2s", ".s",
   7233     [(set (v2i64 V128:$Rd),
   7234         (OpNode (v2i32 V64:$Rn),
   7235          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7236     bits<2> idx;
   7237     let Inst{11} = idx{1};
   7238     let Inst{21} = idx{0};
   7239   }
   7240 
   7241   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
   7242                                       V128, V128,
   7243                                       V128, VectorIndexS,
   7244                                       asm#"2", ".2d", ".2d", ".4s", ".s",
   7245     [(set (v2i64 V128:$Rd),
   7246           (OpNode (extract_high_v4i32 V128:$Rn),
   7247                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
   7248                                                       VectorIndexS:$idx))))]> {
   7249     bits<2> idx;
   7250     let Inst{11} = idx{1};
   7251     let Inst{21} = idx{0};
   7252   }
   7253 
   7254   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
   7255                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
   7256                                       asm, ".h", "", "", ".h", []> {
   7257     bits<3> idx;
   7258     let Inst{11} = idx{2};
   7259     let Inst{21} = idx{1};
   7260     let Inst{20} = idx{0};
   7261   }
   7262 
   7263   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
   7264                                       FPR64Op, FPR32Op, V128, VectorIndexS,
   7265                                       asm, ".s", "", "", ".s", []> {
   7266     bits<2> idx;
   7267     let Inst{11} = idx{1};
   7268     let Inst{21} = idx{0};
   7269   }
   7270 }
   7271 
   7272 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
   7273                                        SDPatternOperator Accum> {
   7274   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
   7275                                       V128, V64,
   7276                                       V128_lo, VectorIndexH,
   7277                                       asm, ".4s", ".4s", ".4h", ".h",
   7278     [(set (v4i32 V128:$dst),
   7279           (Accum (v4i32 V128:$Rd),
   7280                  (v4i32 (int_aarch64_neon_sqdmull
   7281                              (v4i16 V64:$Rn),
   7282                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   7283                                                     VectorIndexH:$idx))))))]> {
   7284     bits<3> idx;
   7285     let Inst{11} = idx{2};
   7286     let Inst{21} = idx{1};
   7287     let Inst{20} = idx{0};
   7288   }
   7289 
   7290   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
   7291   // intermediate EXTRACT_SUBREG would be untyped.
   7292   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
   7293                 (i32 (vector_extract (v4i32
   7294                          (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
   7295                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   7296                                                     VectorIndexH:$idx)))),
   7297                          (i64 0))))),
   7298             (EXTRACT_SUBREG
   7299                 (!cast<Instruction>(NAME # v4i16_indexed)
   7300                     (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
   7301                     V128_lo:$Rm, VectorIndexH:$idx),
   7302                 ssub)>;
   7303 
   7304   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
   7305                                       V128, V128,
   7306                                       V128_lo, VectorIndexH,
   7307                                       asm#"2", ".4s", ".4s", ".8h", ".h",
   7308     [(set (v4i32 V128:$dst),
   7309           (Accum (v4i32 V128:$Rd),
   7310                  (v4i32 (int_aarch64_neon_sqdmull
   7311                             (extract_high_v8i16 V128:$Rn),
   7312                             (extract_high_v8i16
   7313                                 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   7314                                                 VectorIndexH:$idx))))))]> {
   7315     bits<3> idx;
   7316     let Inst{11} = idx{2};
   7317     let Inst{21} = idx{1};
   7318     let Inst{20} = idx{0};
   7319   }
   7320 
   7321   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
   7322                                       V128, V64,
   7323                                       V128, VectorIndexS,
   7324                                       asm, ".2d", ".2d", ".2s", ".s",
   7325     [(set (v2i64 V128:$dst),
   7326         (Accum (v2i64 V128:$Rd),
   7327                (v2i64 (int_aarch64_neon_sqdmull
   7328                           (v2i32 V64:$Rn),
   7329                           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
   7330                                                  VectorIndexS:$idx))))))]> {
   7331     bits<2> idx;
   7332     let Inst{11} = idx{1};
   7333     let Inst{21} = idx{0};
   7334   }
   7335 
   7336   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
   7337                                       V128, V128,
   7338                                       V128, VectorIndexS,
   7339                                       asm#"2", ".2d", ".2d", ".4s", ".s",
   7340     [(set (v2i64 V128:$dst),
   7341           (Accum (v2i64 V128:$Rd),
   7342                  (v2i64 (int_aarch64_neon_sqdmull
   7343                             (extract_high_v4i32 V128:$Rn),
   7344                             (extract_high_v4i32
   7345                                 (AArch64duplane32 (v4i32 V128:$Rm),
   7346                                                 VectorIndexS:$idx))))))]> {
   7347     bits<2> idx;
   7348     let Inst{11} = idx{1};
   7349     let Inst{21} = idx{0};
   7350   }
   7351 
   7352   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
   7353                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
   7354                                       asm, ".h", "", "", ".h", []> {
   7355     bits<3> idx;
   7356     let Inst{11} = idx{2};
   7357     let Inst{21} = idx{1};
   7358     let Inst{20} = idx{0};
   7359   }
   7360 
   7361 
   7362   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
   7363                                       FPR64Op, FPR32Op, V128, VectorIndexS,
   7364                                       asm, ".s", "", "", ".s",
   7365     [(set (i64 FPR64Op:$dst),
   7366           (Accum (i64 FPR64Op:$Rd),
   7367                  (i64 (int_aarch64_neon_sqdmulls_scalar
   7368                             (i32 FPR32Op:$Rn),
   7369                             (i32 (vector_extract (v4i32 V128:$Rm),
   7370                                                  VectorIndexS:$idx))))))]> {
   7371 
   7372     bits<2> idx;
   7373     let Inst{11} = idx{1};
   7374     let Inst{21} = idx{0};
   7375   }
   7376 }
   7377 
   7378 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
   7379                                    SDPatternOperator OpNode> {
   7380   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
   7381   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
   7382                                       V128, V64,
   7383                                       V128_lo, VectorIndexH,
   7384                                       asm, ".4s", ".4s", ".4h", ".h",
   7385     [(set (v4i32 V128:$Rd),
   7386         (OpNode (v4i16 V64:$Rn),
   7387          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7388     bits<3> idx;
   7389     let Inst{11} = idx{2};
   7390     let Inst{21} = idx{1};
   7391     let Inst{20} = idx{0};
   7392   }
   7393 
   7394   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
   7395                                       V128, V128,
   7396                                       V128_lo, VectorIndexH,
   7397                                       asm#"2", ".4s", ".4s", ".8h", ".h",
   7398     [(set (v4i32 V128:$Rd),
   7399           (OpNode (extract_high_v8i16 V128:$Rn),
   7400                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   7401                                                       VectorIndexH:$idx))))]> {
   7402 
   7403     bits<3> idx;
   7404     let Inst{11} = idx{2};
   7405     let Inst{21} = idx{1};
   7406     let Inst{20} = idx{0};
   7407   }
   7408 
   7409   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
   7410                                       V128, V64,
   7411                                       V128, VectorIndexS,
   7412                                       asm, ".2d", ".2d", ".2s", ".s",
   7413     [(set (v2i64 V128:$Rd),
   7414         (OpNode (v2i32 V64:$Rn),
   7415          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7416     bits<2> idx;
   7417     let Inst{11} = idx{1};
   7418     let Inst{21} = idx{0};
   7419   }
   7420 
   7421   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
   7422                                       V128, V128,
   7423                                       V128, VectorIndexS,
   7424                                       asm#"2", ".2d", ".2d", ".4s", ".s",
   7425     [(set (v2i64 V128:$Rd),
   7426           (OpNode (extract_high_v4i32 V128:$Rn),
   7427                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
   7428                                                       VectorIndexS:$idx))))]> {
   7429     bits<2> idx;
   7430     let Inst{11} = idx{1};
   7431     let Inst{21} = idx{0};
   7432   }
   7433   }
   7434 }
   7435 
   7436 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
   7437                                        SDPatternOperator OpNode> {
   7438   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
   7439   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
   7440                                       V128, V64,
   7441                                       V128_lo, VectorIndexH,
   7442                                       asm, ".4s", ".4s", ".4h", ".h",
   7443     [(set (v4i32 V128:$dst),
   7444         (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
   7445          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7446     bits<3> idx;
   7447     let Inst{11} = idx{2};
   7448     let Inst{21} = idx{1};
   7449     let Inst{20} = idx{0};
   7450   }
   7451 
   7452   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
   7453                                       V128, V128,
   7454                                       V128_lo, VectorIndexH,
   7455                                       asm#"2", ".4s", ".4s", ".8h", ".h",
   7456     [(set (v4i32 V128:$dst),
   7457           (OpNode (v4i32 V128:$Rd),
   7458                   (extract_high_v8i16 V128:$Rn),
   7459                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   7460                                                       VectorIndexH:$idx))))]> {
   7461     bits<3> idx;
   7462     let Inst{11} = idx{2};
   7463     let Inst{21} = idx{1};
   7464     let Inst{20} = idx{0};
   7465   }
   7466 
   7467   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
   7468                                       V128, V64,
   7469                                       V128, VectorIndexS,
   7470                                       asm, ".2d", ".2d", ".2s", ".s",
   7471     [(set (v2i64 V128:$dst),
   7472         (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
   7473          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7474     bits<2> idx;
   7475     let Inst{11} = idx{1};
   7476     let Inst{21} = idx{0};
   7477   }
   7478 
   7479   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
   7480                                       V128, V128,
   7481                                       V128, VectorIndexS,
   7482                                       asm#"2", ".2d", ".2d", ".4s", ".s",
   7483     [(set (v2i64 V128:$dst),
   7484           (OpNode (v2i64 V128:$Rd),
   7485                   (extract_high_v4i32 V128:$Rn),
   7486                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
   7487                                                       VectorIndexS:$idx))))]> {
   7488     bits<2> idx;
   7489     let Inst{11} = idx{1};
   7490     let Inst{21} = idx{0};
   7491   }
   7492   }
   7493 }
   7494 
   7495 //----------------------------------------------------------------------------
   7496 // AdvSIMD scalar shift by immediate
   7497 //----------------------------------------------------------------------------
   7498 
   7499 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   7500 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
   7501                      RegisterClass regtype1, RegisterClass regtype2,
   7502                      Operand immtype, string asm, list<dag> pattern>
   7503   : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
   7504       asm, "\t$Rd, $Rn, $imm", "", pattern>,
   7505     Sched<[WriteV]> {
   7506   bits<5> Rd;
   7507   bits<5> Rn;
   7508   bits<7> imm;
   7509   let Inst{31-30} = 0b01;
   7510   let Inst{29}    = U;
   7511   let Inst{28-23} = 0b111110;
   7512   let Inst{22-16} = fixed_imm;
   7513   let Inst{15-11} = opc;
   7514   let Inst{10}    = 1;
   7515   let Inst{9-5} = Rn;
   7516   let Inst{4-0} = Rd;
   7517 }
   7518 
   7519 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   7520 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
   7521                      RegisterClass regtype1, RegisterClass regtype2,
   7522                      Operand immtype, string asm, list<dag> pattern>
   7523   : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
   7524       asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
   7525     Sched<[WriteV]> {
   7526   bits<5> Rd;
   7527   bits<5> Rn;
   7528   bits<7> imm;
   7529   let Inst{31-30} = 0b01;
   7530   let Inst{29}    = U;
   7531   let Inst{28-23} = 0b111110;
   7532   let Inst{22-16} = fixed_imm;
   7533   let Inst{15-11} = opc;
   7534   let Inst{10}    = 1;
   7535   let Inst{9-5} = Rn;
   7536   let Inst{4-0} = Rd;
   7537 }
   7538 
   7539 
   7540 multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {
   7541   let Predicates = [HasNEON, HasFullFP16] in {
   7542   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
   7543                               FPR16, FPR16, vecshiftR16, asm, []> {
   7544     let Inst{19-16} = imm{3-0};
   7545   }
   7546   } // Predicates = [HasNEON, HasFullFP16]
   7547   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
   7548                               FPR32, FPR32, vecshiftR32, asm, []> {
   7549     let Inst{20-16} = imm{4-0};
   7550   }
   7551 
   7552   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
   7553                               FPR64, FPR64, vecshiftR64, asm, []> {
   7554     let Inst{21-16} = imm{5-0};
   7555   }
   7556 }
   7557 
   7558 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
   7559                              SDPatternOperator OpNode> {
   7560   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
   7561                               FPR64, FPR64, vecshiftR64, asm,
   7562   [(set (i64 FPR64:$Rd),
   7563      (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
   7564     let Inst{21-16} = imm{5-0};
   7565   }
   7566 
   7567   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
   7568             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
   7569 }
   7570 
   7571 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
   7572                                  SDPatternOperator OpNode = null_frag> {
   7573   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
   7574                               FPR64, FPR64, vecshiftR64, asm,
   7575   [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
   7576                                                    (i32 vecshiftR64:$imm)))]> {
   7577     let Inst{21-16} = imm{5-0};
   7578   }
   7579 
   7580   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
   7581                            (i32 vecshiftR64:$imm))),
   7582             (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
   7583                                             vecshiftR64:$imm)>;
   7584 }
   7585 
   7586 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
   7587                              SDPatternOperator OpNode> {
   7588   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
   7589                               FPR64, FPR64, vecshiftL64, asm,
   7590     [(set (v1i64 FPR64:$Rd),
   7591        (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
   7592     let Inst{21-16} = imm{5-0};
   7593   }
   7594 }
   7595 
   7596 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   7597 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
   7598   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
   7599                               FPR64, FPR64, vecshiftL64, asm, []> {
   7600     let Inst{21-16} = imm{5-0};
   7601   }
   7602 }
   7603 
   7604 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   7605 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
   7606                                SDPatternOperator OpNode = null_frag> {
   7607   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
   7608                               FPR8, FPR16, vecshiftR8, asm, []> {
   7609     let Inst{18-16} = imm{2-0};
   7610   }
   7611 
   7612   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
   7613                               FPR16, FPR32, vecshiftR16, asm, []> {
   7614     let Inst{19-16} = imm{3-0};
   7615   }
   7616 
   7617   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
   7618                               FPR32, FPR64, vecshiftR32, asm,
   7619     [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
   7620     let Inst{20-16} = imm{4-0};
   7621   }
   7622 }
   7623 
   7624 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
   7625                                 SDPatternOperator OpNode> {
   7626   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
   7627                               FPR8, FPR8, vecshiftL8, asm, []> {
   7628     let Inst{18-16} = imm{2-0};
   7629   }
   7630 
   7631   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
   7632                               FPR16, FPR16, vecshiftL16, asm, []> {
   7633     let Inst{19-16} = imm{3-0};
   7634   }
   7635 
   7636   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
   7637                               FPR32, FPR32, vecshiftL32, asm,
   7638     [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
   7639     let Inst{20-16} = imm{4-0};
   7640   }
   7641 
   7642   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
   7643                               FPR64, FPR64, vecshiftL64, asm,
   7644     [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
   7645     let Inst{21-16} = imm{5-0};
   7646   }
   7647 
   7648   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
   7649             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
   7650 }
   7651 
   7652 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
   7653   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
   7654                               FPR8, FPR8, vecshiftR8, asm, []> {
   7655     let Inst{18-16} = imm{2-0};
   7656   }
   7657 
   7658   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
   7659                               FPR16, FPR16, vecshiftR16, asm, []> {
   7660     let Inst{19-16} = imm{3-0};
   7661   }
   7662 
   7663   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
   7664                               FPR32, FPR32, vecshiftR32, asm, []> {
   7665     let Inst{20-16} = imm{4-0};
   7666   }
   7667 
   7668   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
   7669                               FPR64, FPR64, vecshiftR64, asm, []> {
   7670     let Inst{21-16} = imm{5-0};
   7671   }
   7672 }
   7673 
   7674 //----------------------------------------------------------------------------
   7675 // AdvSIMD vector x indexed element
   7676 //----------------------------------------------------------------------------
   7677 
   7678 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   7679 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
   7680                      RegisterOperand dst_reg, RegisterOperand src_reg,
   7681                      Operand immtype,
   7682                      string asm, string dst_kind, string src_kind,
   7683                      list<dag> pattern>
   7684   : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
   7685       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
   7686            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
   7687     Sched<[WriteV]> {
   7688   bits<5> Rd;
   7689   bits<5> Rn;
   7690   let Inst{31}    = 0;
   7691   let Inst{30}    = Q;
   7692   let Inst{29}    = U;
   7693   let Inst{28-23} = 0b011110;
   7694   let Inst{22-16} = fixed_imm;
   7695   let Inst{15-11} = opc;
   7696   let Inst{10}    = 1;
   7697   let Inst{9-5}   = Rn;
   7698   let Inst{4-0}   = Rd;
   7699 }
   7700 
   7701 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   7702 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
   7703                      RegisterOperand vectype1, RegisterOperand vectype2,
   7704                      Operand immtype,
   7705                      string asm, string dst_kind, string src_kind,
   7706                      list<dag> pattern>
   7707   : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
   7708       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
   7709            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
   7710     Sched<[WriteV]> {
   7711   bits<5> Rd;
   7712   bits<5> Rn;
   7713   let Inst{31}    = 0;
   7714   let Inst{30}    = Q;
   7715   let Inst{29}    = U;
   7716   let Inst{28-23} = 0b011110;
   7717   let Inst{22-16} = fixed_imm;
   7718   let Inst{15-11} = opc;
   7719   let Inst{10}    = 1;
   7720   let Inst{9-5}   = Rn;
   7721   let Inst{4-0}   = Rd;
   7722 }
   7723 
   7724 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
   7725                               Intrinsic OpNode> {
   7726   let Predicates = [HasNEON, HasFullFP16] in {
   7727   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
   7728                                   V64, V64, vecshiftR16,
   7729                                   asm, ".4h", ".4h",
   7730       [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
   7731     bits<4> imm;
   7732     let Inst{19-16} = imm;
   7733   }
   7734 
   7735   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
   7736                                   V128, V128, vecshiftR16,
   7737                                   asm, ".8h", ".8h",
   7738       [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
   7739     bits<4> imm;
   7740     let Inst{19-16} = imm;
   7741   }
   7742   } // Predicates = [HasNEON, HasFullFP16]
   7743   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
   7744                                   V64, V64, vecshiftR32,
   7745                                   asm, ".2s", ".2s",
   7746       [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
   7747     bits<5> imm;
   7748     let Inst{20-16} = imm;
   7749   }
   7750 
   7751   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
   7752                                   V128, V128, vecshiftR32,
   7753                                   asm, ".4s", ".4s",
   7754       [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
   7755     bits<5> imm;
   7756     let Inst{20-16} = imm;
   7757   }
   7758 
   7759   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
   7760                                   V128, V128, vecshiftR64,
   7761                                   asm, ".2d", ".2d",
   7762       [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
   7763     bits<6> imm;
   7764     let Inst{21-16} = imm;
   7765   }
   7766 }
   7767 
   7768 multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
   7769                                   Intrinsic OpNode> {
   7770   let Predicates = [HasNEON, HasFullFP16] in {
   7771   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
   7772                                   V64, V64, vecshiftR16,
   7773                                   asm, ".4h", ".4h",
   7774       [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
   7775     bits<4> imm;
   7776     let Inst{19-16} = imm;
   7777   }
   7778 
   7779   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
   7780                                   V128, V128, vecshiftR16,
   7781                                   asm, ".8h", ".8h",
   7782       [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
   7783     bits<4> imm;
   7784     let Inst{19-16} = imm;
   7785   }
   7786   } // Predicates = [HasNEON, HasFullFP16]
   7787 
   7788   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
   7789                                   V64, V64, vecshiftR32,
   7790                                   asm, ".2s", ".2s",
   7791       [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
   7792     bits<5> imm;
   7793     let Inst{20-16} = imm;
   7794   }
   7795 
   7796   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
   7797                                   V128, V128, vecshiftR32,
   7798                                   asm, ".4s", ".4s",
   7799       [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
   7800     bits<5> imm;
   7801     let Inst{20-16} = imm;
   7802   }
   7803 
   7804   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
   7805                                   V128, V128, vecshiftR64,
   7806                                   asm, ".2d", ".2d",
   7807       [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
   7808     bits<6> imm;
   7809     let Inst{21-16} = imm;
   7810   }
   7811 }
   7812 
   7813 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
   7814                                      SDPatternOperator OpNode> {
   7815   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
   7816                                   V64, V128, vecshiftR16Narrow,
   7817                                   asm, ".8b", ".8h",
   7818       [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
   7819     bits<3> imm;
   7820     let Inst{18-16} = imm;
   7821   }
   7822 
   7823   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
   7824                                   V128, V128, vecshiftR16Narrow,
   7825                                   asm#"2", ".16b", ".8h", []> {
   7826     bits<3> imm;
   7827     let Inst{18-16} = imm;
   7828     let hasSideEffects = 0;
   7829   }
   7830 
   7831   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
   7832                                   V64, V128, vecshiftR32Narrow,
   7833                                   asm, ".4h", ".4s",
   7834       [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
   7835     bits<4> imm;
   7836     let Inst{19-16} = imm;
   7837   }
   7838 
   7839   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
   7840                                   V128, V128, vecshiftR32Narrow,
   7841                                   asm#"2", ".8h", ".4s", []> {
   7842     bits<4> imm;
   7843     let Inst{19-16} = imm;
   7844     let hasSideEffects = 0;
   7845   }
   7846 
   7847   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
   7848                                   V64, V128, vecshiftR64Narrow,
   7849                                   asm, ".2s", ".2d",
   7850       [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
   7851     bits<5> imm;
   7852     let Inst{20-16} = imm;
   7853   }
   7854 
   7855   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
   7856                                   V128, V128, vecshiftR64Narrow,
   7857                                   asm#"2", ".4s", ".2d", []> {
   7858     bits<5> imm;
   7859     let Inst{20-16} = imm;
   7860     let hasSideEffects = 0;
   7861   }
   7862 
   7863   // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
   7864   // themselves, so put them here instead.
   7865 
   7866   // Patterns involving what's effectively an insert high and a normal
   7867   // intrinsic, represented by CONCAT_VECTORS.
   7868   def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
   7869                                                    vecshiftR16Narrow:$imm)),
   7870             (!cast<Instruction>(NAME # "v16i8_shift")
   7871                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
   7872                 V128:$Rn, vecshiftR16Narrow:$imm)>;
   7873   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
   7874                                                      vecshiftR32Narrow:$imm)),
   7875             (!cast<Instruction>(NAME # "v8i16_shift")
   7876                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
   7877                 V128:$Rn, vecshiftR32Narrow:$imm)>;
   7878   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
   7879                                                      vecshiftR64Narrow:$imm)),
   7880             (!cast<Instruction>(NAME # "v4i32_shift")
   7881                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
   7882                 V128:$Rn, vecshiftR64Narrow:$imm)>;
   7883 }
   7884 
   7885 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
   7886                                 SDPatternOperator OpNode> {
   7887   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
   7888                                   V64, V64, vecshiftL8,
   7889                                   asm, ".8b", ".8b",
   7890                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
   7891                        (i32 vecshiftL8:$imm)))]> {
   7892     bits<3> imm;
   7893     let Inst{18-16} = imm;
   7894   }
   7895 
   7896   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
   7897                                   V128, V128, vecshiftL8,
   7898                                   asm, ".16b", ".16b",
   7899              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
   7900                    (i32 vecshiftL8:$imm)))]> {
   7901     bits<3> imm;
   7902     let Inst{18-16} = imm;
   7903   }
   7904 
   7905   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
   7906                                   V64, V64, vecshiftL16,
   7907                                   asm, ".4h", ".4h",
   7908               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
   7909                     (i32 vecshiftL16:$imm)))]> {
   7910     bits<4> imm;
   7911     let Inst{19-16} = imm;
   7912   }
   7913 
   7914   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
   7915                                   V128, V128, vecshiftL16,
   7916                                   asm, ".8h", ".8h",
   7917             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
   7918                   (i32 vecshiftL16:$imm)))]> {
   7919     bits<4> imm;
   7920     let Inst{19-16} = imm;
   7921   }
   7922 
   7923   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
   7924                                   V64, V64, vecshiftL32,
   7925                                   asm, ".2s", ".2s",
   7926               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
   7927                     (i32 vecshiftL32:$imm)))]> {
   7928     bits<5> imm;
   7929     let Inst{20-16} = imm;
   7930   }
   7931 
   7932   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
   7933                                   V128, V128, vecshiftL32,
   7934                                   asm, ".4s", ".4s",
   7935             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
   7936                   (i32 vecshiftL32:$imm)))]> {
   7937     bits<5> imm;
   7938     let Inst{20-16} = imm;
   7939   }
   7940 
   7941   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
   7942                                   V128, V128, vecshiftL64,
   7943                                   asm, ".2d", ".2d",
   7944             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
   7945                   (i32 vecshiftL64:$imm)))]> {
   7946     bits<6> imm;
   7947     let Inst{21-16} = imm;
   7948   }
   7949 }
   7950 
   7951 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
   7952                                 SDPatternOperator OpNode> {
   7953   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
   7954                                   V64, V64, vecshiftR8,
   7955                                   asm, ".8b", ".8b",
   7956                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
   7957                        (i32 vecshiftR8:$imm)))]> {
   7958     bits<3> imm;
   7959     let Inst{18-16} = imm;
   7960   }
   7961 
   7962   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
   7963                                   V128, V128, vecshiftR8,
   7964                                   asm, ".16b", ".16b",
   7965              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
   7966                    (i32 vecshiftR8:$imm)))]> {
   7967     bits<3> imm;
   7968     let Inst{18-16} = imm;
   7969   }
   7970 
   7971   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
   7972                                   V64, V64, vecshiftR16,
   7973                                   asm, ".4h", ".4h",
   7974               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
   7975                     (i32 vecshiftR16:$imm)))]> {
   7976     bits<4> imm;
   7977     let Inst{19-16} = imm;
   7978   }
   7979 
   7980   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
   7981                                   V128, V128, vecshiftR16,
   7982                                   asm, ".8h", ".8h",
   7983             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
   7984                   (i32 vecshiftR16:$imm)))]> {
   7985     bits<4> imm;
   7986     let Inst{19-16} = imm;
   7987   }
   7988 
   7989   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
   7990                                   V64, V64, vecshiftR32,
   7991                                   asm, ".2s", ".2s",
   7992               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
   7993                     (i32 vecshiftR32:$imm)))]> {
   7994     bits<5> imm;
   7995     let Inst{20-16} = imm;
   7996   }
   7997 
   7998   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
   7999                                   V128, V128, vecshiftR32,
   8000                                   asm, ".4s", ".4s",
   8001             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
   8002                   (i32 vecshiftR32:$imm)))]> {
   8003     bits<5> imm;
   8004     let Inst{20-16} = imm;
   8005   }
   8006 
   8007   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
   8008                                   V128, V128, vecshiftR64,
   8009                                   asm, ".2d", ".2d",
   8010             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
   8011                   (i32 vecshiftR64:$imm)))]> {
   8012     bits<6> imm;
   8013     let Inst{21-16} = imm;
   8014   }
   8015 }
   8016 
   8017 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   8018 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
   8019                                     SDPatternOperator OpNode = null_frag> {
   8020   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
   8021                                   V64, V64, vecshiftR8, asm, ".8b", ".8b",
   8022                  [(set (v8i8 V64:$dst),
   8023                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
   8024                            (i32 vecshiftR8:$imm)))]> {
   8025     bits<3> imm;
   8026     let Inst{18-16} = imm;
   8027   }
   8028 
   8029   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
   8030                                   V128, V128, vecshiftR8, asm, ".16b", ".16b",
   8031              [(set (v16i8 V128:$dst),
   8032                (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
   8033                        (i32 vecshiftR8:$imm)))]> {
   8034     bits<3> imm;
   8035     let Inst{18-16} = imm;
   8036   }
   8037 
   8038   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
   8039                                   V64, V64, vecshiftR16, asm, ".4h", ".4h",
   8040               [(set (v4i16 V64:$dst),
   8041                 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
   8042                         (i32 vecshiftR16:$imm)))]> {
   8043     bits<4> imm;
   8044     let Inst{19-16} = imm;
   8045   }
   8046 
   8047   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
   8048                                   V128, V128, vecshiftR16, asm, ".8h", ".8h",
   8049             [(set (v8i16 V128:$dst),
   8050               (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
   8051                       (i32 vecshiftR16:$imm)))]> {
   8052     bits<4> imm;
   8053     let Inst{19-16} = imm;
   8054   }
   8055 
   8056   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
   8057                                   V64, V64, vecshiftR32, asm, ".2s", ".2s",
   8058               [(set (v2i32 V64:$dst),
   8059                 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
   8060                         (i32 vecshiftR32:$imm)))]> {
   8061     bits<5> imm;
   8062     let Inst{20-16} = imm;
   8063   }
   8064 
   8065   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
   8066                                   V128, V128, vecshiftR32, asm, ".4s", ".4s",
   8067             [(set (v4i32 V128:$dst),
   8068               (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
   8069                       (i32 vecshiftR32:$imm)))]> {
   8070     bits<5> imm;
   8071     let Inst{20-16} = imm;
   8072   }
   8073 
   8074   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
   8075                                   V128, V128, vecshiftR64,
   8076                                   asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
   8077               (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
   8078                       (i32 vecshiftR64:$imm)))]> {
   8079     bits<6> imm;
   8080     let Inst{21-16} = imm;
   8081   }
   8082 }
   8083 
   8084 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
   8085                                     SDPatternOperator OpNode = null_frag> {
   8086   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
   8087                                   V64, V64, vecshiftL8,
   8088                                   asm, ".8b", ".8b",
   8089                     [(set (v8i8 V64:$dst),
   8090                           (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
   8091                                   (i32 vecshiftL8:$imm)))]> {
   8092     bits<3> imm;
   8093     let Inst{18-16} = imm;
   8094   }
   8095 
   8096   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
   8097                                   V128, V128, vecshiftL8,
   8098                                   asm, ".16b", ".16b",
   8099                     [(set (v16i8 V128:$dst),
   8100                           (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
   8101                                   (i32 vecshiftL8:$imm)))]> {
   8102     bits<3> imm;
   8103     let Inst{18-16} = imm;
   8104   }
   8105 
   8106   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
   8107                                   V64, V64, vecshiftL16,
   8108                                   asm, ".4h", ".4h",
   8109                     [(set (v4i16 V64:$dst),
   8110                            (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
   8111                                    (i32 vecshiftL16:$imm)))]> {
   8112     bits<4> imm;
   8113     let Inst{19-16} = imm;
   8114   }
   8115 
   8116   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
   8117                                   V128, V128, vecshiftL16,
   8118                                   asm, ".8h", ".8h",
   8119                     [(set (v8i16 V128:$dst),
   8120                           (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
   8121                                   (i32 vecshiftL16:$imm)))]> {
   8122     bits<4> imm;
   8123     let Inst{19-16} = imm;
   8124   }
   8125 
   8126   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
   8127                                   V64, V64, vecshiftL32,
   8128                                   asm, ".2s", ".2s",
   8129                     [(set (v2i32 V64:$dst),
   8130                           (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
   8131                                   (i32 vecshiftL32:$imm)))]> {
   8132     bits<5> imm;
   8133     let Inst{20-16} = imm;
   8134   }
   8135 
   8136   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
   8137                                   V128, V128, vecshiftL32,
   8138                                   asm, ".4s", ".4s",
   8139                     [(set (v4i32 V128:$dst),
   8140                           (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
   8141                                   (i32 vecshiftL32:$imm)))]> {
   8142     bits<5> imm;
   8143     let Inst{20-16} = imm;
   8144   }
   8145 
   8146   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
   8147                                   V128, V128, vecshiftL64,
   8148                                   asm, ".2d", ".2d",
   8149                     [(set (v2i64 V128:$dst),
   8150                           (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
   8151                                   (i32 vecshiftL64:$imm)))]> {
   8152     bits<6> imm;
   8153     let Inst{21-16} = imm;
   8154   }
   8155 }
   8156 
   8157 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
   8158                                    SDPatternOperator OpNode> {
   8159   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
   8160                                   V128, V64, vecshiftL8, asm, ".8h", ".8b",
   8161       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
   8162     bits<3> imm;
   8163     let Inst{18-16} = imm;
   8164   }
   8165 
   8166   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
   8167                                   V128, V128, vecshiftL8,
   8168                                   asm#"2", ".8h", ".16b",
   8169       [(set (v8i16 V128:$Rd),
   8170             (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
   8171     bits<3> imm;
   8172     let Inst{18-16} = imm;
   8173   }
   8174 
   8175   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
   8176                                   V128, V64, vecshiftL16, asm, ".4s", ".4h",
   8177       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
   8178     bits<4> imm;
   8179     let Inst{19-16} = imm;
   8180   }
   8181 
   8182   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
   8183                                   V128, V128, vecshiftL16,
   8184                                   asm#"2", ".4s", ".8h",
   8185       [(set (v4i32 V128:$Rd),
   8186             (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
   8187 
   8188     bits<4> imm;
   8189     let Inst{19-16} = imm;
   8190   }
   8191 
   8192   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
   8193                                   V128, V64, vecshiftL32, asm, ".2d", ".2s",
   8194       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
   8195     bits<5> imm;
   8196     let Inst{20-16} = imm;
   8197   }
   8198 
   8199   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
   8200                                   V128, V128, vecshiftL32,
   8201                                   asm#"2", ".2d", ".4s",
   8202       [(set (v2i64 V128:$Rd),
   8203             (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
   8204     bits<5> imm;
   8205     let Inst{20-16} = imm;
   8206   }
   8207 }
   8208 
   8209 
   8210 //---
   8211 // Vector load/store
   8212 //---
   8213 // SIMD ldX/stX no-index memory references don't allow the optional
   8214 // ", #0" constant and handle post-indexing explicitly, so we use
   8215 // a more specialized parse method for them. Otherwise, it's the same as
   8216 // the general GPR64sp handling.
   8217 
   8218 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
   8219                    string asm, dag oops, dag iops, list<dag> pattern>
   8220   : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
   8221   bits<5> Vt;
   8222   bits<5> Rn;
   8223   let Inst{31} = 0;
   8224   let Inst{30} = Q;
   8225   let Inst{29-23} = 0b0011000;
   8226   let Inst{22} = L;
   8227   let Inst{21-16} = 0b000000;
   8228   let Inst{15-12} = opcode;
   8229   let Inst{11-10} = size;
   8230   let Inst{9-5} = Rn;
   8231   let Inst{4-0} = Vt;
   8232 }
   8233 
   8234 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
   8235                        string asm, dag oops, dag iops>
   8236   : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
   8237   bits<5> Vt;
   8238   bits<5> Rn;
   8239   bits<5> Xm;
   8240   let Inst{31} = 0;
   8241   let Inst{30} = Q;
   8242   let Inst{29-23} = 0b0011001;
   8243   let Inst{22} = L;
   8244   let Inst{21} = 0;
   8245   let Inst{20-16} = Xm;
   8246   let Inst{15-12} = opcode;
   8247   let Inst{11-10} = size;
   8248   let Inst{9-5} = Rn;
   8249   let Inst{4-0} = Vt;
   8250 }
   8251 
   8252 // The immediate form of AdvSIMD post-indexed addressing is encoded with
   8253 // register post-index addressing from the zero register.
   8254 multiclass SIMDLdStAliases<string asm, string layout, string Count,
   8255                            int Offset, int Size> {
   8256   // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
   8257   //      "ld1\t$Vt, [$Rn], #16"
   8258   // may get mapped to
   8259   //      (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
   8260   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
   8261                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
   8262                       GPR64sp:$Rn,
   8263                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
   8264                       XZR), 1>;
   8265 
   8266   // E.g. "ld1.8b { v0, v1 }, [x1], #16"
   8267   //      "ld1.8b\t$Vt, [$Rn], #16"
   8268   // may get mapped to
   8269   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
   8270   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
   8271                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
   8272                       GPR64sp:$Rn,
   8273                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
   8274                       XZR), 0>;
   8275 
   8276   // E.g. "ld1.8b { v0, v1 }, [x1]"
   8277   //      "ld1\t$Vt, [$Rn]"
   8278   // may get mapped to
   8279   //      (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
   8280   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
   8281                   (!cast<Instruction>(NAME # Count # "v" # layout)
   8282                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
   8283                       GPR64sp:$Rn), 0>;
   8284 
   8285   // E.g. "ld1.8b { v0, v1 }, [x1], x2"
   8286   //      "ld1\t$Vt, [$Rn], $Xm"
   8287   // may get mapped to
   8288   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
   8289   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
   8290                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
   8291                       GPR64sp:$Rn,
   8292                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
   8293                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
   8294 }
   8295 
   8296 multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
   8297                        int Offset64, bits<4> opcode> {
   8298   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
   8299     def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
   8300                            (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
   8301                            (ins GPR64sp:$Rn), []>;
   8302     def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
   8303                            (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
   8304                            (ins GPR64sp:$Rn), []>;
   8305     def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
   8306                            (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
   8307                            (ins GPR64sp:$Rn), []>;
   8308     def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
   8309                            (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
   8310                            (ins GPR64sp:$Rn), []>;
   8311     def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
   8312                            (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
   8313                            (ins GPR64sp:$Rn), []>;
   8314     def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
   8315                            (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
   8316                            (ins GPR64sp:$Rn), []>;
   8317     def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
   8318                            (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
   8319                            (ins GPR64sp:$Rn), []>;
   8320 
   8321 
   8322     def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
   8323                        (outs GPR64sp:$wback,
   8324                              !cast<RegisterOperand>(veclist # "16b"):$Vt),
   8325                        (ins GPR64sp:$Rn,
   8326                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8327     def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
   8328                        (outs GPR64sp:$wback,
   8329                              !cast<RegisterOperand>(veclist # "8h"):$Vt),
   8330                        (ins GPR64sp:$Rn,
   8331                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8332     def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
   8333                        (outs GPR64sp:$wback,
   8334                              !cast<RegisterOperand>(veclist # "4s"):$Vt),
   8335                        (ins GPR64sp:$Rn,
   8336                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8337     def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
   8338                        (outs GPR64sp:$wback,
   8339                              !cast<RegisterOperand>(veclist # "2d"):$Vt),
   8340                        (ins GPR64sp:$Rn,
   8341                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8342     def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
   8343                        (outs GPR64sp:$wback,
   8344                              !cast<RegisterOperand>(veclist # "8b"):$Vt),
   8345                        (ins GPR64sp:$Rn,
   8346                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8347     def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
   8348                        (outs GPR64sp:$wback,
   8349                              !cast<RegisterOperand>(veclist # "4h"):$Vt),
   8350                        (ins GPR64sp:$Rn,
   8351                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8352     def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
   8353                        (outs GPR64sp:$wback,
   8354                              !cast<RegisterOperand>(veclist # "2s"):$Vt),
   8355                        (ins GPR64sp:$Rn,
   8356                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8357   }
   8358 
   8359   defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
   8360   defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
   8361   defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
   8362   defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
   8363   defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
   8364   defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
   8365   defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
   8366 }
   8367 
   8368 // Only ld1/st1 has a v1d version.
   8369 multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
   8370                        int Offset64, bits<4> opcode> {
   8371   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
   8372     def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
   8373                             (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
   8374                                  GPR64sp:$Rn), []>;
   8375     def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
   8376                            (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
   8377                                 GPR64sp:$Rn), []>;
   8378     def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
   8379                            (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
   8380                                 GPR64sp:$Rn), []>;
   8381     def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
   8382                            (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
   8383                                 GPR64sp:$Rn), []>;
   8384     def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
   8385                            (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
   8386                                 GPR64sp:$Rn), []>;
   8387     def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
   8388                            (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
   8389                                 GPR64sp:$Rn), []>;
   8390     def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
   8391                            (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
   8392                                 GPR64sp:$Rn), []>;
   8393 
   8394     def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
   8395                        (outs GPR64sp:$wback),
   8396                        (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
   8397                             GPR64sp:$Rn,
   8398                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8399     def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
   8400                        (outs GPR64sp:$wback),
   8401                        (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
   8402                             GPR64sp:$Rn,
   8403                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8404     def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
   8405                        (outs GPR64sp:$wback),
   8406                        (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
   8407                             GPR64sp:$Rn,
   8408                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8409     def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
   8410                        (outs GPR64sp:$wback),
   8411                        (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
   8412                             GPR64sp:$Rn,
   8413                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8414     def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
   8415                        (outs GPR64sp:$wback),
   8416                        (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
   8417                             GPR64sp:$Rn,
   8418                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8419     def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
   8420                        (outs GPR64sp:$wback),
   8421                        (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
   8422                             GPR64sp:$Rn,
   8423                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8424     def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
   8425                        (outs GPR64sp:$wback),
   8426                        (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
   8427                             GPR64sp:$Rn,
   8428                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8429   }
   8430 
   8431   defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
   8432   defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
   8433   defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
   8434   defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
   8435   defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
   8436   defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
   8437   defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
   8438 }
   8439 
   8440 multiclass BaseSIMDLd1<string Count, string asm, string veclist,
   8441                        int Offset128, int Offset64, bits<4> opcode>
   8442   : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
   8443 
   8444   // LD1 instructions have extra "1d" variants.
   8445   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
   8446     def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
   8447                            (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
   8448                            (ins GPR64sp:$Rn), []>;
   8449 
   8450     def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
   8451                        (outs GPR64sp:$wback,
   8452                              !cast<RegisterOperand>(veclist # "1d"):$Vt),
   8453                        (ins GPR64sp:$Rn,
   8454                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8455   }
   8456 
   8457   defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
   8458 }
   8459 
   8460 multiclass BaseSIMDSt1<string Count, string asm, string veclist,
   8461                        int Offset128, int Offset64, bits<4> opcode>
   8462   : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
   8463 
   8464   // ST1 instructions have extra "1d" variants.
   8465   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
   8466     def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
   8467                            (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
   8468                                 GPR64sp:$Rn), []>;
   8469 
   8470     def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
   8471                        (outs GPR64sp:$wback),
   8472                        (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
   8473                             GPR64sp:$Rn,
   8474                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8475   }
   8476 
   8477   defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
   8478 }
   8479 
   8480 multiclass SIMDLd1Multiple<string asm> {
   8481   defm One   : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8,  0b0111>;
   8482   defm Two   : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
   8483   defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
   8484   defm Four  : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
   8485 }
   8486 
   8487 multiclass SIMDSt1Multiple<string asm> {
   8488   defm One   : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8,  0b0111>;
   8489   defm Two   : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
   8490   defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
   8491   defm Four  : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
   8492 }
   8493 
   8494 multiclass SIMDLd2Multiple<string asm> {
   8495   defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
   8496 }
   8497 
   8498 multiclass SIMDSt2Multiple<string asm> {
   8499   defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
   8500 }
   8501 
   8502 multiclass SIMDLd3Multiple<string asm> {
   8503   defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
   8504 }
   8505 
   8506 multiclass SIMDSt3Multiple<string asm> {
   8507   defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
   8508 }
   8509 
   8510 multiclass SIMDLd4Multiple<string asm> {
   8511   defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
   8512 }
   8513 
   8514 multiclass SIMDSt4Multiple<string asm> {
   8515   defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
   8516 }
   8517 
   8518 //---
   8519 // AdvSIMD Load/store single-element
   8520 //---
   8521 
   8522 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
   8523                          string asm, string operands, string cst,
   8524                          dag oops, dag iops, list<dag> pattern>
   8525   : I<oops, iops, asm, operands, cst, pattern> {
   8526   bits<5> Vt;
   8527   bits<5> Rn;
   8528   let Inst{31} = 0;
   8529   let Inst{29-24} = 0b001101;
   8530   let Inst{22} = L;
   8531   let Inst{21} = R;
   8532   let Inst{15-13} = opcode;
   8533   let Inst{9-5} = Rn;
   8534   let Inst{4-0} = Vt;
   8535 }
   8536 
   8537 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
   8538                          string asm, string operands, string cst,
   8539                          dag oops, dag iops, list<dag> pattern>
   8540   : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
   8541   bits<5> Vt;
   8542   bits<5> Rn;
   8543   let Inst{31} = 0;
   8544   let Inst{29-24} = 0b001101;
   8545   let Inst{22} = L;
   8546   let Inst{21} = R;
   8547   let Inst{15-13} = opcode;
   8548   let Inst{9-5} = Rn;
   8549   let Inst{4-0} = Vt;
   8550 }
   8551 
   8552 
   8553 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   8554 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
   8555                   Operand listtype>
   8556   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
   8557                        (outs listtype:$Vt), (ins GPR64sp:$Rn),
   8558                        []> {
   8559   let Inst{30} = Q;
   8560   let Inst{23} = 0;
   8561   let Inst{20-16} = 0b00000;
   8562   let Inst{12} = S;
   8563   let Inst{11-10} = size;
   8564 }
   8565 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   8566 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
   8567                       string asm, Operand listtype, Operand GPR64pi>
   8568   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
   8569                        "$Rn = $wback",
   8570                        (outs GPR64sp:$wback, listtype:$Vt),
   8571                        (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
   8572   bits<5> Xm;
   8573   let Inst{30} = Q;
   8574   let Inst{23} = 1;
   8575   let Inst{20-16} = Xm;
   8576   let Inst{12} = S;
   8577   let Inst{11-10} = size;
   8578 }
   8579 
   8580 multiclass SIMDLdrAliases<string asm, string layout, string Count,
   8581                           int Offset, int Size> {
   8582   // E.g. "ld1r { v0.8b }, [x1], #1"
   8583   //      "ld1r.8b\t$Vt, [$Rn], #1"
   8584   // may get mapped to
   8585   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
   8586   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
   8587                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
   8588                       GPR64sp:$Rn,
   8589                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
   8590                       XZR), 1>;
   8591 
   8592   // E.g. "ld1r.8b { v0 }, [x1], #1"
   8593   //      "ld1r.8b\t$Vt, [$Rn], #1"
   8594   // may get mapped to
   8595   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
   8596   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
   8597                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
   8598                       GPR64sp:$Rn,
   8599                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
   8600                       XZR), 0>;
   8601 
   8602   // E.g. "ld1r.8b { v0 }, [x1]"
   8603   //      "ld1r.8b\t$Vt, [$Rn]"
   8604   // may get mapped to
   8605   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
   8606   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
   8607                   (!cast<Instruction>(NAME # "v" # layout)
   8608                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
   8609                       GPR64sp:$Rn), 0>;
   8610 
   8611   // E.g. "ld1r.8b { v0 }, [x1], x2"
   8612   //      "ld1r.8b\t$Vt, [$Rn], $Xm"
   8613   // may get mapped to
   8614   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
   8615   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
   8616                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
   8617                       GPR64sp:$Rn,
   8618                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
   8619                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
   8620 }
   8621 
   8622 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
   8623   int Offset1, int Offset2, int Offset4, int Offset8> {
   8624   def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
   8625                         !cast<Operand>("VecList" # Count # "8b")>;
   8626   def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
   8627                         !cast<Operand>("VecList" # Count #"16b")>;
   8628   def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
   8629                         !cast<Operand>("VecList" # Count #"4h")>;
   8630   def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
   8631                         !cast<Operand>("VecList" # Count #"8h")>;
   8632   def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
   8633                         !cast<Operand>("VecList" # Count #"2s")>;
   8634   def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
   8635                         !cast<Operand>("VecList" # Count #"4s")>;
   8636   def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
   8637                         !cast<Operand>("VecList" # Count #"1d")>;
   8638   def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
   8639                         !cast<Operand>("VecList" # Count #"2d")>;
   8640 
   8641   def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
   8642                                  !cast<Operand>("VecList" # Count # "8b"),
   8643                                  !cast<Operand>("GPR64pi" # Offset1)>;
   8644   def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
   8645                                  !cast<Operand>("VecList" # Count # "16b"),
   8646                                  !cast<Operand>("GPR64pi" # Offset1)>;
   8647   def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
   8648                                  !cast<Operand>("VecList" # Count # "4h"),
   8649                                  !cast<Operand>("GPR64pi" # Offset2)>;
   8650   def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
   8651                                  !cast<Operand>("VecList" # Count # "8h"),
   8652                                  !cast<Operand>("GPR64pi" # Offset2)>;
   8653   def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
   8654                                  !cast<Operand>("VecList" # Count # "2s"),
   8655                                  !cast<Operand>("GPR64pi" # Offset4)>;
   8656   def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
   8657                                  !cast<Operand>("VecList" # Count # "4s"),
   8658                                  !cast<Operand>("GPR64pi" # Offset4)>;
   8659   def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
   8660                                  !cast<Operand>("VecList" # Count # "1d"),
   8661                                  !cast<Operand>("GPR64pi" # Offset8)>;
   8662   def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
   8663                                  !cast<Operand>("VecList" # Count # "2d"),
   8664                                  !cast<Operand>("GPR64pi" # Offset8)>;
   8665 
   8666   defm : SIMDLdrAliases<asm, "8b",  Count, Offset1,  64>;
   8667   defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
   8668   defm : SIMDLdrAliases<asm, "4h",  Count, Offset2,  64>;
   8669   defm : SIMDLdrAliases<asm, "8h",  Count, Offset2, 128>;
   8670   defm : SIMDLdrAliases<asm, "2s",  Count, Offset4,  64>;
   8671   defm : SIMDLdrAliases<asm, "4s",  Count, Offset4, 128>;
   8672   defm : SIMDLdrAliases<asm, "1d",  Count, Offset8,  64>;
   8673   defm : SIMDLdrAliases<asm, "2d",  Count, Offset8, 128>;
   8674 }
   8675 
   8676 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
   8677                       dag oops, dag iops, list<dag> pattern>
   8678   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
   8679                        pattern> {
   8680   // idx encoded in Q:S:size fields.
   8681   bits<4> idx;
   8682   let Inst{30} = idx{3};
   8683   let Inst{23} = 0;
   8684   let Inst{20-16} = 0b00000;
   8685   let Inst{12} = idx{2};
   8686   let Inst{11-10} = idx{1-0};
   8687 }
   8688 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
   8689                       dag oops, dag iops, list<dag> pattern>
   8690   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
   8691                            oops, iops, pattern> {
   8692   // idx encoded in Q:S:size fields.
   8693   bits<4> idx;
   8694   let Inst{30} = idx{3};
   8695   let Inst{23} = 0;
   8696   let Inst{20-16} = 0b00000;
   8697   let Inst{12} = idx{2};
   8698   let Inst{11-10} = idx{1-0};
   8699 }
   8700 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
   8701                           dag oops, dag iops>
   8702   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8703                        "$Rn = $wback", oops, iops, []> {
   8704   // idx encoded in Q:S:size fields.
   8705   bits<4> idx;
   8706   bits<5> Xm;
   8707   let Inst{30} = idx{3};
   8708   let Inst{23} = 1;
   8709   let Inst{20-16} = Xm;
   8710   let Inst{12} = idx{2};
   8711   let Inst{11-10} = idx{1-0};
   8712 }
   8713 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
   8714                           dag oops, dag iops>
   8715   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8716                            "$Rn = $wback", oops, iops, []> {
   8717   // idx encoded in Q:S:size fields.
   8718   bits<4> idx;
   8719   bits<5> Xm;
   8720   let Inst{30} = idx{3};
   8721   let Inst{23} = 1;
   8722   let Inst{20-16} = Xm;
   8723   let Inst{12} = idx{2};
   8724   let Inst{11-10} = idx{1-0};
   8725 }
   8726 
   8727 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
   8728                       dag oops, dag iops, list<dag> pattern>
   8729   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
   8730                        pattern> {
   8731   // idx encoded in Q:S:size<1> fields.
   8732   bits<3> idx;
   8733   let Inst{30} = idx{2};
   8734   let Inst{23} = 0;
   8735   let Inst{20-16} = 0b00000;
   8736   let Inst{12} = idx{1};
   8737   let Inst{11} = idx{0};
   8738   let Inst{10} = size;
   8739 }
   8740 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
   8741                       dag oops, dag iops, list<dag> pattern>
   8742   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
   8743                            oops, iops, pattern> {
   8744   // idx encoded in Q:S:size<1> fields.
   8745   bits<3> idx;
   8746   let Inst{30} = idx{2};
   8747   let Inst{23} = 0;
   8748   let Inst{20-16} = 0b00000;
   8749   let Inst{12} = idx{1};
   8750   let Inst{11} = idx{0};
   8751   let Inst{10} = size;
   8752 }
   8753 
   8754 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
   8755                           dag oops, dag iops>
   8756   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8757                        "$Rn = $wback", oops, iops, []> {
   8758   // idx encoded in Q:S:size<1> fields.
   8759   bits<3> idx;
   8760   bits<5> Xm;
   8761   let Inst{30} = idx{2};
   8762   let Inst{23} = 1;
   8763   let Inst{20-16} = Xm;
   8764   let Inst{12} = idx{1};
   8765   let Inst{11} = idx{0};
   8766   let Inst{10} = size;
   8767 }
   8768 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
   8769                           dag oops, dag iops>
   8770   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8771                            "$Rn = $wback", oops, iops, []> {
   8772   // idx encoded in Q:S:size<1> fields.
   8773   bits<3> idx;
   8774   bits<5> Xm;
   8775   let Inst{30} = idx{2};
   8776   let Inst{23} = 1;
   8777   let Inst{20-16} = Xm;
   8778   let Inst{12} = idx{1};
   8779   let Inst{11} = idx{0};
   8780   let Inst{10} = size;
   8781 }
   8782 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
   8783                       dag oops, dag iops, list<dag> pattern>
   8784   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
   8785                        pattern> {
   8786   // idx encoded in Q:S fields.
   8787   bits<2> idx;
   8788   let Inst{30} = idx{1};
   8789   let Inst{23} = 0;
   8790   let Inst{20-16} = 0b00000;
   8791   let Inst{12} = idx{0};
   8792   let Inst{11-10} = size;
   8793 }
   8794 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
   8795                       dag oops, dag iops, list<dag> pattern>
   8796   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
   8797                            oops, iops, pattern> {
   8798   // idx encoded in Q:S fields.
   8799   bits<2> idx;
   8800   let Inst{30} = idx{1};
   8801   let Inst{23} = 0;
   8802   let Inst{20-16} = 0b00000;
   8803   let Inst{12} = idx{0};
   8804   let Inst{11-10} = size;
   8805 }
   8806 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
   8807                           string asm, dag oops, dag iops>
   8808   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8809                        "$Rn = $wback", oops, iops, []> {
   8810   // idx encoded in Q:S fields.
   8811   bits<2> idx;
   8812   bits<5> Xm;
   8813   let Inst{30} = idx{1};
   8814   let Inst{23} = 1;
   8815   let Inst{20-16} = Xm;
   8816   let Inst{12} = idx{0};
   8817   let Inst{11-10} = size;
   8818 }
   8819 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
   8820                           string asm, dag oops, dag iops>
   8821   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8822                            "$Rn = $wback", oops, iops, []> {
   8823   // idx encoded in Q:S fields.
   8824   bits<2> idx;
   8825   bits<5> Xm;
   8826   let Inst{30} = idx{1};
   8827   let Inst{23} = 1;
   8828   let Inst{20-16} = Xm;
   8829   let Inst{12} = idx{0};
   8830   let Inst{11-10} = size;
   8831 }
   8832 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
   8833                       dag oops, dag iops, list<dag> pattern>
   8834   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
   8835                        pattern> {
   8836   // idx encoded in Q field.
   8837   bits<1> idx;
   8838   let Inst{30} = idx;
   8839   let Inst{23} = 0;
   8840   let Inst{20-16} = 0b00000;
   8841   let Inst{12} = 0;
   8842   let Inst{11-10} = size;
   8843 }
   8844 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
   8845                       dag oops, dag iops, list<dag> pattern>
   8846   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
   8847                            oops, iops, pattern> {
   8848   // idx encoded in Q field.
   8849   bits<1> idx;
   8850   let Inst{30} = idx;
   8851   let Inst{23} = 0;
   8852   let Inst{20-16} = 0b00000;
   8853   let Inst{12} = 0;
   8854   let Inst{11-10} = size;
   8855 }
   8856 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
   8857                           string asm, dag oops, dag iops>
   8858   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8859                        "$Rn = $wback", oops, iops, []> {
   8860   // idx encoded in Q field.
   8861   bits<1> idx;
   8862   bits<5> Xm;
   8863   let Inst{30} = idx;
   8864   let Inst{23} = 1;
   8865   let Inst{20-16} = Xm;
   8866   let Inst{12} = 0;
   8867   let Inst{11-10} = size;
   8868 }
   8869 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
   8870                           string asm, dag oops, dag iops>
   8871   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8872                            "$Rn = $wback", oops, iops, []> {
   8873   // idx encoded in Q field.
   8874   bits<1> idx;
   8875   bits<5> Xm;
   8876   let Inst{30} = idx;
   8877   let Inst{23} = 1;
   8878   let Inst{20-16} = Xm;
   8879   let Inst{12} = 0;
   8880   let Inst{11-10} = size;
   8881 }
   8882 
   8883 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   8884 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
   8885                          RegisterOperand listtype,
   8886                          RegisterOperand GPR64pi> {
   8887   def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
   8888                            (outs listtype:$dst),
   8889                            (ins listtype:$Vt, VectorIndexB:$idx,
   8890                                 GPR64sp:$Rn), []>;
   8891 
   8892   def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
   8893                             (outs GPR64sp:$wback, listtype:$dst),
   8894                             (ins listtype:$Vt, VectorIndexB:$idx,
   8895                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
   8896 }
   8897 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   8898 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
   8899                          RegisterOperand listtype,
   8900                          RegisterOperand GPR64pi> {
   8901   def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
   8902                             (outs listtype:$dst),
   8903                             (ins listtype:$Vt, VectorIndexH:$idx,
   8904                                  GPR64sp:$Rn), []>;
   8905 
   8906   def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
   8907                             (outs GPR64sp:$wback, listtype:$dst),
   8908                             (ins listtype:$Vt, VectorIndexH:$idx,
   8909                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
   8910 }
   8911 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   8912 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
   8913                          RegisterOperand listtype,
   8914                          RegisterOperand GPR64pi> {
   8915   def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
   8916                             (outs listtype:$dst),
   8917                             (ins listtype:$Vt, VectorIndexS:$idx,
   8918                                  GPR64sp:$Rn), []>;
   8919 
   8920   def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
   8921                             (outs GPR64sp:$wback, listtype:$dst),
   8922                             (ins listtype:$Vt, VectorIndexS:$idx,
   8923                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
   8924 }
   8925 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   8926 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
   8927                          RegisterOperand listtype, RegisterOperand GPR64pi> {
   8928   def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
   8929                             (outs listtype:$dst),
   8930                             (ins listtype:$Vt, VectorIndexD:$idx,
   8931                                  GPR64sp:$Rn), []>;
   8932 
   8933   def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
   8934                             (outs GPR64sp:$wback, listtype:$dst),
   8935                             (ins listtype:$Vt, VectorIndexD:$idx,
   8936                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
   8937 }
   8938 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   8939 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
   8940                          RegisterOperand listtype, RegisterOperand GPR64pi> {
   8941   def i8 : SIMDLdStSingleB<0, R, opcode, asm,
   8942                            (outs), (ins listtype:$Vt, VectorIndexB:$idx,
   8943                                         GPR64sp:$Rn), []>;
   8944 
   8945   def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
   8946                                     (outs GPR64sp:$wback),
   8947                                     (ins listtype:$Vt, VectorIndexB:$idx,
   8948                                          GPR64sp:$Rn, GPR64pi:$Xm)>;
   8949 }
   8950 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   8951 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
   8952                          RegisterOperand listtype, RegisterOperand GPR64pi> {
   8953   def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
   8954                             (outs), (ins listtype:$Vt, VectorIndexH:$idx,
   8955                                          GPR64sp:$Rn), []>;
   8956 
   8957   def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
   8958                             (outs GPR64sp:$wback),
   8959                             (ins listtype:$Vt, VectorIndexH:$idx,
   8960                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
   8961 }
   8962 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   8963 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
   8964                          RegisterOperand listtype, RegisterOperand GPR64pi> {
   8965   def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
   8966                             (outs), (ins listtype:$Vt, VectorIndexS:$idx,
   8967                                          GPR64sp:$Rn), []>;
   8968 
   8969   def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
   8970                             (outs GPR64sp:$wback),
   8971                             (ins listtype:$Vt, VectorIndexS:$idx,
   8972                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
   8973 }
   8974 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   8975 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
   8976                          RegisterOperand listtype, RegisterOperand GPR64pi> {
   8977   def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
   8978                             (outs), (ins listtype:$Vt, VectorIndexD:$idx,
   8979                                          GPR64sp:$Rn), []>;
   8980 
   8981   def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
   8982                             (outs GPR64sp:$wback),
   8983                             (ins listtype:$Vt, VectorIndexD:$idx,
   8984                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
   8985 }
   8986 
   8987 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
   8988                                  string Count, int Offset, Operand idxtype> {
   8989   // E.g. "ld1 { v0.8b }[0], [x1], #1"
   8990   //      "ld1\t$Vt, [$Rn], #1"
   8991   // may get mapped to
   8992   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
   8993   def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
   8994                   (!cast<Instruction>(NAME # Type  # "_POST")
   8995                       GPR64sp:$Rn,
   8996                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
   8997                       idxtype:$idx, XZR), 1>;
   8998 
   8999   // E.g. "ld1.8b { v0 }[0], [x1], #1"
   9000   //      "ld1.8b\t$Vt, [$Rn], #1"
   9001   // may get mapped to
   9002   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
   9003   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
   9004                   (!cast<Instruction>(NAME # Type # "_POST")
   9005                       GPR64sp:$Rn,
   9006                       !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
   9007                       idxtype:$idx, XZR), 0>;
   9008 
   9009   // E.g. "ld1.8b { v0 }[0], [x1]"
   9010   //      "ld1.8b\t$Vt, [$Rn]"
   9011   // may get mapped to
   9012   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
   9013   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
   9014                       (!cast<Instruction>(NAME # Type)
   9015                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
   9016                          idxtype:$idx, GPR64sp:$Rn), 0>;
   9017 
   9018   // E.g. "ld1.8b { v0 }[0], [x1], x2"
   9019   //      "ld1.8b\t$Vt, [$Rn], $Xm"
   9020   // may get mapped to
   9021   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
   9022   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
   9023                       (!cast<Instruction>(NAME # Type # "_POST")
   9024                          GPR64sp:$Rn,
   9025                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
   9026                          idxtype:$idx,
   9027                          !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
   9028 }
   9029 
   9030 multiclass SIMDLdSt1SingleAliases<string asm> {
   9031   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "One", 1, VectorIndexB>;
   9032   defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
   9033   defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
   9034   defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
   9035 }
   9036 
   9037 multiclass SIMDLdSt2SingleAliases<string asm> {
   9038   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Two", 2,  VectorIndexB>;
   9039   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4,  VectorIndexH>;
   9040   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8,  VectorIndexS>;
   9041   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
   9042 }
   9043 
   9044 multiclass SIMDLdSt3SingleAliases<string asm> {
   9045   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Three", 3,  VectorIndexB>;
   9046   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6,  VectorIndexH>;
   9047   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
   9048   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
   9049 }
   9050 
   9051 multiclass SIMDLdSt4SingleAliases<string asm> {
   9052   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Four", 4,  VectorIndexB>;
   9053   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8,  VectorIndexH>;
   9054   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
   9055   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
   9056 }
   9057 } // end of 'let Predicates = [HasNEON]'
   9058 
   9059 //----------------------------------------------------------------------------
   9060 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
   9061 //----------------------------------------------------------------------------
   9062 
   9063 let Predicates = [HasNEON, HasV8_1a] in {
   9064 
   9065 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
   9066                                     RegisterOperand regtype, string asm, 
   9067                                     string kind, list<dag> pattern>
   9068   : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 
   9069                                 pattern> {
   9070 }
   9071 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
   9072                                              SDPatternOperator Accum> {
   9073   def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
   9074     [(set (v4i16 V64:$dst),
   9075           (Accum (v4i16 V64:$Rd),
   9076                  (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
   9077                                                    (v4i16 V64:$Rm)))))]>;         
   9078   def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
   9079     [(set (v8i16 V128:$dst),
   9080           (Accum (v8i16 V128:$Rd),
   9081                  (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
   9082                                                    (v8i16 V128:$Rm)))))]>;
   9083   def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
   9084     [(set (v2i32 V64:$dst),
   9085           (Accum (v2i32 V64:$Rd),
   9086                  (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
   9087                                                    (v2i32 V64:$Rm)))))]>;
   9088   def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
   9089     [(set (v4i32 V128:$dst),
   9090           (Accum (v4i32 V128:$Rd),
   9091                  (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
   9092                                                    (v4i32 V128:$Rm)))))]>;
   9093 }
   9094 
   9095 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
   9096                                      SDPatternOperator Accum> {
   9097   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
   9098                                           V64, V64, V128_lo, VectorIndexH,
   9099                                           asm, ".4h", ".4h", ".4h", ".h",
   9100     [(set (v4i16 V64:$dst),
   9101           (Accum (v4i16 V64:$Rd),
   9102                  (v4i16 (int_aarch64_neon_sqrdmulh
   9103                           (v4i16 V64:$Rn),
   9104                           (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   9105                                                     VectorIndexH:$idx))))))]> {
   9106     bits<3> idx;
   9107     let Inst{11} = idx{2};
   9108     let Inst{21} = idx{1};
   9109     let Inst{20} = idx{0};
   9110   }
   9111 
   9112   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
   9113                                           V128, V128, V128_lo, VectorIndexH,
   9114                                           asm, ".8h", ".8h", ".8h", ".h",
   9115     [(set (v8i16 V128:$dst),
   9116           (Accum (v8i16 V128:$Rd),
   9117                  (v8i16 (int_aarch64_neon_sqrdmulh
   9118                           (v8i16 V128:$Rn),
   9119                           (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   9120                                                    VectorIndexH:$idx))))))]> {
   9121     bits<3> idx;
   9122     let Inst{11} = idx{2};
   9123     let Inst{21} = idx{1};
   9124     let Inst{20} = idx{0};
   9125   }
   9126 
   9127   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
   9128                                           V64, V64, V128, VectorIndexS,
   9129                                           asm, ".2s", ".2s", ".2s", ".s",
   9130     [(set (v2i32 V64:$dst),
   9131         (Accum (v2i32 V64:$Rd),
   9132                (v2i32 (int_aarch64_neon_sqrdmulh
   9133                         (v2i32 V64:$Rn),
   9134                         (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
   9135                                                  VectorIndexS:$idx))))))]> {
   9136     bits<2> idx;
   9137     let Inst{11} = idx{1};
   9138     let Inst{21} = idx{0};
   9139   }
   9140 
   9141   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 
   9142   // an intermediate EXTRACT_SUBREG would be untyped.
   9143   // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we 
   9144   // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
   9145   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
   9146                        (i32 (vector_extract 
   9147                                (v4i32 (insert_subvector
   9148                                        (undef), 
   9149                                         (v2i32 (int_aarch64_neon_sqrdmulh 
   9150                                                  (v2i32 V64:$Rn),
   9151                                                  (v2i32 (AArch64duplane32 
   9152                                                           (v4i32 V128:$Rm),
   9153                                                           VectorIndexS:$idx)))),
   9154                                       (i32 0))),
   9155                                (i64 0))))),
   9156             (EXTRACT_SUBREG
   9157                 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
   9158                           (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), 
   9159                                                 FPR32Op:$Rd, 
   9160                                                 ssub)), 
   9161                           V64:$Rn,
   9162                           V128:$Rm, 
   9163                           VectorIndexS:$idx)),
   9164                 ssub)>;
   9165 
   9166   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
   9167                                           V128, V128, V128, VectorIndexS,
   9168                                           asm, ".4s", ".4s", ".4s", ".s",
   9169     [(set (v4i32 V128:$dst),
   9170           (Accum (v4i32 V128:$Rd),
   9171                  (v4i32 (int_aarch64_neon_sqrdmulh
   9172                           (v4i32 V128:$Rn),
   9173                           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
   9174                                                    VectorIndexS:$idx))))))]> {
   9175     bits<2> idx;
   9176     let Inst{11} = idx{1};
   9177     let Inst{21} = idx{0};
   9178   }
   9179 
   9180   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
   9181   // an intermediate EXTRACT_SUBREG would be untyped.
   9182   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
   9183                         (i32 (vector_extract 
   9184                                (v4i32 (int_aarch64_neon_sqrdmulh 
   9185                                         (v4i32 V128:$Rn),
   9186                                         (v4i32 (AArch64duplane32 
   9187                                                  (v4i32 V128:$Rm),
   9188                                                  VectorIndexS:$idx)))),
   9189                                (i64 0))))),
   9190             (EXTRACT_SUBREG
   9191                 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
   9192                          (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 
   9193                                                FPR32Op:$Rd, 
   9194                                                ssub)), 
   9195                          V128:$Rn,
   9196                          V128:$Rm, 
   9197                          VectorIndexS:$idx)),
   9198                 ssub)>;
   9199 
   9200   def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
   9201                                         FPR16Op, FPR16Op, V128_lo,
   9202                                         VectorIndexH, asm, ".h", "", "", ".h", 
   9203                                         []> {
   9204     bits<3> idx;
   9205     let Inst{11} = idx{2};
   9206     let Inst{21} = idx{1};
   9207     let Inst{20} = idx{0};
   9208   }
   9209 
   9210   def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
   9211                                         FPR32Op, FPR32Op, V128, VectorIndexS,
   9212                                         asm, ".s", "", "", ".s",
   9213     [(set (i32 FPR32Op:$dst),
   9214           (Accum (i32 FPR32Op:$Rd),
   9215                  (i32 (int_aarch64_neon_sqrdmulh
   9216                         (i32 FPR32Op:$Rn),
   9217                         (i32 (vector_extract (v4i32 V128:$Rm),
   9218                                              VectorIndexS:$idx))))))]> {
   9219     bits<2> idx;
   9220     let Inst{11} = idx{1};
   9221     let Inst{21} = idx{0};
   9222   }
   9223 }
   9224 } // let Predicates = [HasNeon, HasV8_1a]
   9225 
   9226 //----------------------------------------------------------------------------
   9227 // Crypto extensions
   9228 //----------------------------------------------------------------------------
   9229 
   9230 let Predicates = [HasCrypto] in {
   9231 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   9232 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
   9233               list<dag> pat>
   9234   : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
   9235     Sched<[WriteV]>{
   9236   bits<5> Rd;
   9237   bits<5> Rn;
   9238   let Inst{31-16} = 0b0100111000101000;
   9239   let Inst{15-12} = opc;
   9240   let Inst{11-10} = 0b10;
   9241   let Inst{9-5}   = Rn;
   9242   let Inst{4-0}   = Rd;
   9243 }
   9244 
   9245 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
   9246   : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
   9247             [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
   9248 
   9249 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
   9250   : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
   9251             "$Rd = $dst",
   9252             [(set (v16i8 V128:$dst),
   9253                   (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
   9254 
   9255 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   9256 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
   9257                      dag oops, dag iops, list<dag> pat>
   9258   : I<oops, iops, asm,
   9259       "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
   9260       "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
   9261     Sched<[WriteV]>{
   9262   bits<5> Rd;
   9263   bits<5> Rn;
   9264   bits<5> Rm;
   9265   let Inst{31-21} = 0b01011110000;
   9266   let Inst{20-16} = Rm;
   9267   let Inst{15}    = 0;
   9268   let Inst{14-12} = opc;
   9269   let Inst{11-10} = 0b00;
   9270   let Inst{9-5}   = Rn;
   9271   let Inst{4-0}   = Rd;
   9272 }
   9273 
   9274 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
   9275   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
   9276                    (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
   9277                    [(set (v4i32 FPR128:$dst),
   9278                          (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
   9279                                  (v4i32 V128:$Rm)))]>;
   9280 
   9281 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
   9282   : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
   9283                    (ins V128:$Rd, V128:$Rn, V128:$Rm),
   9284                    [(set (v4i32 V128:$dst),
   9285                          (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
   9286                                  (v4i32 V128:$Rm)))]>;
   9287 
   9288 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
   9289   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
   9290                    (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
   9291                    [(set (v4i32 FPR128:$dst),
   9292                          (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
   9293                                  (v4i32 V128:$Rm)))]>;
   9294 
   9295 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   9296 class SHA2OpInst<bits<4> opc, string asm, string kind,
   9297                  string cstr, dag oops, dag iops,
   9298                  list<dag> pat>
   9299   : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
   9300                        "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
   9301     Sched<[WriteV]>{
   9302   bits<5> Rd;
   9303   bits<5> Rn;
   9304   let Inst{31-16} = 0b0101111000101000;
   9305   let Inst{15-12} = opc;
   9306   let Inst{11-10} = 0b10;
   9307   let Inst{9-5}   = Rn;
   9308   let Inst{4-0}   = Rd;
   9309 }
   9310 
   9311 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
   9312   : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
   9313                (ins V128:$Rd, V128:$Rn),
   9314                [(set (v4i32 V128:$dst),
   9315                      (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
   9316 
   9317 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
   9318   : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
   9319                [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
   9320 } // end of 'let Predicates = [HasCrypto]'
   9321 
   9322 //----------------------------------------------------------------------------
   9323 // v8.1 atomic instructions extension:
   9324 // * CAS
   9325 // * CASP
   9326 // * SWP
   9327 // * LDOPregister<OP>, and aliases STOPregister<OP>
   9328 
   9329 // Instruction encodings:
   9330 //
   9331 //      31 30|29  24|23|22|21|20 16|15|14  10|9 5|4 0
   9332 // CAS  SZ   |001000|1 |A |1 |Rs   |R |11111 |Rn |Rt
   9333 // CASP  0|SZ|001000|0 |A |1 |Rs   |R |11111 |Rn |Rt
   9334 // SWP  SZ   |111000|A |R |1 |Rs   |1 |OPC|00|Rn |Rt
   9335 // LD   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |Rt
   9336 // ST   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |11111
   9337 
   9338 // Instruction syntax:
   9339 //
   9340 // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
   9341 // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
   9342 // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
   9343 // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
   9344 // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
   9345 // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
   9346 // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
   9347 // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
   9348 // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
   9349 // ST<OP>{<order>} <Xs>, [<Xn|SP>]
   9350 
   9351 let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
   9352 class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
   9353                       string cstr, list<dag> pattern>
   9354       : I<oops, iops, asm, operands, cstr, pattern> {
   9355   bits<2> Sz;
   9356   bit NP;
   9357   bit Acq;
   9358   bit Rel;
   9359   bits<5> Rs;
   9360   bits<5> Rn;
   9361   bits<5> Rt;
   9362   let Inst{31-30} = Sz;
   9363   let Inst{29-24} = 0b001000;
   9364   let Inst{23} = NP;
   9365   let Inst{22} = Acq;
   9366   let Inst{21} = 0b1;
   9367   let Inst{20-16} = Rs;
   9368   let Inst{15} = Rel;
   9369   let Inst{14-10} = 0b11111;
   9370   let Inst{9-5} = Rn;
   9371   let Inst{4-0} = Rt;
   9372 }
   9373 
   9374 class BaseCAS<string order, string size, RegisterClass RC>
   9375       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
   9376                         "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
   9377                         "$out = $Rs",[]>,
   9378         Sched<[WriteAtomic]> {
   9379   let NP = 1;
   9380 }
   9381 
   9382 multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
   9383   let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseCAS<order, "b", GPR32>;
   9384   let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseCAS<order, "h", GPR32>;
   9385   let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseCAS<order, "", GPR32>;
   9386   let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseCAS<order, "", GPR64>;
   9387 }
   9388 
   9389 class BaseCASP<string order, string size, RegisterOperand RC>
   9390       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
   9391                         "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
   9392                         "$out = $Rs",[]>,
   9393         Sched<[WriteAtomic]> {
   9394   let NP = 0;
   9395 }
   9396 
   9397 multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
   9398   let Sz = 0b00, Acq = Acq, Rel = Rel in 
   9399     def s : BaseCASP<order, "", WSeqPairClassOperand>;
   9400   let Sz = 0b01, Acq = Acq, Rel = Rel in 
   9401     def d : BaseCASP<order, "", XSeqPairClassOperand>;
   9402 }
   9403 
   9404 let Predicates = [HasV8_1a] in
   9405 class BaseSWP<string order, string size, RegisterClass RC>
   9406       : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
   9407           "\t$Rs, $Rt, [$Rn]","",[]>,
   9408         Sched<[WriteAtomic]> {
   9409   bits<2> Sz;
   9410   bit Acq;
   9411   bit Rel;
   9412   bits<5> Rs;
   9413   bits<3> opc = 0b000;
   9414   bits<5> Rn;
   9415   bits<5> Rt;
   9416   let Inst{31-30} = Sz;
   9417   let Inst{29-24} = 0b111000;
   9418   let Inst{23} = Acq;
   9419   let Inst{22} = Rel;
   9420   let Inst{21} = 0b1;
   9421   let Inst{20-16} = Rs;
   9422   let Inst{15} = 0b1;
   9423   let Inst{14-12} = opc;
   9424   let Inst{11-10} = 0b00;
   9425   let Inst{9-5} = Rn;
   9426   let Inst{4-0} = Rt;
   9427 }
   9428 
   9429 multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
   9430   let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseSWP<order, "b", GPR32>;
   9431   let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseSWP<order, "h", GPR32>;
   9432   let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseSWP<order, "", GPR32>;
   9433   let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseSWP<order, "", GPR64>;
   9434 }
   9435 
   9436 let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
   9437 class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
   9438       : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
   9439           "\t$Rs, $Rt, [$Rn]","",[]>,
   9440         Sched<[WriteAtomic]> {
   9441   bits<2> Sz;
   9442   bit Acq;
   9443   bit Rel;
   9444   bits<5> Rs;
   9445   bits<3> opc;
   9446   bits<5> Rn;
   9447   bits<5> Rt;
   9448   let Inst{31-30} = Sz;
   9449   let Inst{29-24} = 0b111000;
   9450   let Inst{23} = Acq;
   9451   let Inst{22} = Rel;
   9452   let Inst{21} = 0b1;
   9453   let Inst{20-16} = Rs;
   9454   let Inst{15} = 0b0;
   9455   let Inst{14-12} = opc;
   9456   let Inst{11-10} = 0b00;
   9457   let Inst{9-5} = Rn;
   9458   let Inst{4-0} = Rt;
   9459 }
   9460 
   9461 multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 
   9462                         string order> {
   9463   let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 
   9464     def b : BaseLDOPregister<op, order, "b", GPR32>;
   9465   let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 
   9466     def h : BaseLDOPregister<op, order, "h", GPR32>;
   9467   let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 
   9468     def s : BaseLDOPregister<op, order, "", GPR32>;
   9469   let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 
   9470     def d : BaseLDOPregister<op, order, "", GPR64>;
   9471 }
   9472 
   9473 let Predicates = [HasV8_1a] in
   9474 class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
   9475                         Instruction inst> :
   9476       InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
   9477 
   9478 multiclass STOPregister<string asm, string instr> {
   9479   def : BaseSTOPregister<asm # "lb", GPR32, WZR, 
   9480                     !cast<Instruction>(instr # "Lb")>;
   9481   def : BaseSTOPregister<asm # "lh", GPR32, WZR, 
   9482                     !cast<Instruction>(instr # "Lh")>;
   9483   def : BaseSTOPregister<asm # "l",  GPR32, WZR, 
   9484                     !cast<Instruction>(instr # "Ls")>;
   9485   def : BaseSTOPregister<asm # "l",  GPR64, XZR, 
   9486                     !cast<Instruction>(instr # "Ld")>;
   9487   def : BaseSTOPregister<asm # "b",  GPR32, WZR, 
   9488                     !cast<Instruction>(instr # "b")>;
   9489   def : BaseSTOPregister<asm # "h",  GPR32, WZR, 
   9490                     !cast<Instruction>(instr # "h")>;
   9491   def : BaseSTOPregister<asm,        GPR32, WZR, 
   9492                     !cast<Instruction>(instr # "s")>;
   9493   def : BaseSTOPregister<asm,        GPR64, XZR, 
   9494                     !cast<Instruction>(instr # "d")>;
   9495 }
   9496 
   9497 //----------------------------------------------------------------------------
   9498 // Allow the size specifier tokens to be upper case, not just lower.
   9499 def : TokenAlias<".8B", ".8b">;
   9500 def : TokenAlias<".4H", ".4h">;
   9501 def : TokenAlias<".2S", ".2s">;
   9502 def : TokenAlias<".1D", ".1d">;
   9503 def : TokenAlias<".16B", ".16b">;
   9504 def : TokenAlias<".8H", ".8h">;
   9505 def : TokenAlias<".4S", ".4s">;
   9506 def : TokenAlias<".2D", ".2d">;
   9507 def : TokenAlias<".1Q", ".1q">;
   9508 def : TokenAlias<".2H", ".2h">;
   9509 def : TokenAlias<".B", ".b">;
   9510 def : TokenAlias<".H", ".h">;
   9511 def : TokenAlias<".S", ".s">;
   9512 def : TokenAlias<".D", ".d">;
   9513 def : TokenAlias<".Q", ".q">;
   9514