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 = "printHexImm";
    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 = "printHexImm";
    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 = "printHexImm";
    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     bool ValidNamed;
    927     (void)AArch64PSBHint::PSBHintMapper().toString(MCOp.getImm(),
    928       STI.getFeatureBits(), ValidNamed);
    929     return ValidNamed;
    930   }];
    931 }
    932 
    933 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
    934                        "mrs", "\t$Rt, $systemreg"> {
    935   bits<16> systemreg;
    936   let Inst{20-5} = systemreg;
    937 }
    938 
    939 // FIXME: Some of these def NZCV, others don't. Best way to model that?
    940 // Explicitly modeling each of the system register as a register class
    941 // would do it, but feels like overkill at this point.
    942 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
    943                        "msr", "\t$systemreg, $Rt"> {
    944   bits<16> systemreg;
    945   let Inst{20-5} = systemreg;
    946 }
    947 
    948 def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
    949   let Name = "SystemPStateFieldWithImm0_15";
    950   let ParserMethod = "tryParseSysReg";
    951 }
    952 def pstatefield4_op : Operand<i32> {
    953   let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
    954   let PrintMethod = "printSystemPStateField";
    955 }
    956 
    957 let Defs = [NZCV] in
    958 class MSRpstateImm0_15
    959   : SimpleSystemI<0, (ins pstatefield4_op:$pstatefield, imm0_15:$imm),
    960                   "msr", "\t$pstatefield, $imm">,
    961     Sched<[WriteSys]> {
    962   bits<6> pstatefield;
    963   bits<4> imm;
    964   let Inst{20-19} = 0b00;
    965   let Inst{18-16} = pstatefield{5-3};
    966   let Inst{15-12} = 0b0100;
    967   let Inst{11-8} = imm;
    968   let Inst{7-5} = pstatefield{2-0};
    969 
    970   let DecoderMethod = "DecodeSystemPStateInstruction";
    971   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
    972   // Fail the decoder should attempt to decode the instruction as MSRI.
    973   let hasCompleteDecoder = 0;
    974 }
    975 
    976 def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
    977   let Name = "SystemPStateFieldWithImm0_1";
    978   let ParserMethod = "tryParseSysReg";
    979 }
    980 def pstatefield1_op : Operand<i32> {
    981   let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
    982   let PrintMethod = "printSystemPStateField";
    983 }
    984 
    985 let Defs = [NZCV] in
    986 class MSRpstateImm0_1
    987   : SimpleSystemI<0, (ins pstatefield1_op:$pstatefield, imm0_1:$imm),
    988                   "msr", "\t$pstatefield, $imm">,
    989     Sched<[WriteSys]> {
    990   bits<6> pstatefield;
    991   bit imm;
    992   let Inst{20-19} = 0b00;
    993   let Inst{18-16} = pstatefield{5-3};
    994   let Inst{15-9} = 0b0100000;
    995   let Inst{8} = imm;
    996   let Inst{7-5} = pstatefield{2-0};
    997 
    998   let DecoderMethod = "DecodeSystemPStateInstruction";
    999   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
   1000   // Fail the decoder should attempt to decode the instruction as MSRI.
   1001   let hasCompleteDecoder = 0;
   1002 }
   1003 
   1004 // SYS and SYSL generic system instructions.
   1005 def SysCRAsmOperand : AsmOperandClass {
   1006   let Name = "SysCR";
   1007   let ParserMethod = "tryParseSysCROperand";
   1008 }
   1009 
   1010 def sys_cr_op : Operand<i32> {
   1011   let PrintMethod = "printSysCROperand";
   1012   let ParserMatchClass = SysCRAsmOperand;
   1013 }
   1014 
   1015 class SystemXtI<bit L, string asm>
   1016   : RtSystemI<L, (outs),
   1017        (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
   1018        asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
   1019   bits<3> op1;
   1020   bits<4> Cn;
   1021   bits<4> Cm;
   1022   bits<3> op2;
   1023   let Inst{20-19} = 0b01;
   1024   let Inst{18-16} = op1;
   1025   let Inst{15-12} = Cn;
   1026   let Inst{11-8}  = Cm;
   1027   let Inst{7-5}   = op2;
   1028 }
   1029 
   1030 class SystemLXtI<bit L, string asm>
   1031   : RtSystemI<L, (outs),
   1032        (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
   1033        asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
   1034   bits<3> op1;
   1035   bits<4> Cn;
   1036   bits<4> Cm;
   1037   bits<3> op2;
   1038   let Inst{20-19} = 0b01;
   1039   let Inst{18-16} = op1;
   1040   let Inst{15-12} = Cn;
   1041   let Inst{11-8}  = Cm;
   1042   let Inst{7-5}   = op2;
   1043 }
   1044 
   1045 
   1046 // Branch (register) instructions:
   1047 //
   1048 //  case opc of
   1049 //    0001 blr
   1050 //    0000 br
   1051 //    0101 dret
   1052 //    0100 eret
   1053 //    0010 ret
   1054 //    otherwise UNDEFINED
   1055 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
   1056                     string operands, list<dag> pattern>
   1057     : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
   1058   let Inst{31-25} = 0b1101011;
   1059   let Inst{24-21} = opc;
   1060   let Inst{20-16} = 0b11111;
   1061   let Inst{15-10} = 0b000000;
   1062   let Inst{4-0}   = 0b00000;
   1063 }
   1064 
   1065 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
   1066     : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
   1067   bits<5> Rn;
   1068   let Inst{9-5} = Rn;
   1069 }
   1070 
   1071 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
   1072 class SpecialReturn<bits<4> opc, string asm>
   1073     : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
   1074   let Inst{9-5} = 0b11111;
   1075 }
   1076 
   1077 //---
   1078 // Conditional branch instruction.
   1079 //---
   1080 
   1081 // Condition code.
   1082 // 4-bit immediate. Pretty-printed as <cc>
   1083 def ccode : Operand<i32> {
   1084   let PrintMethod = "printCondCode";
   1085   let ParserMatchClass = CondCode;
   1086 }
   1087 def inv_ccode : Operand<i32> {
   1088   // AL and NV are invalid in the aliases which use inv_ccode
   1089   let PrintMethod = "printInverseCondCode";
   1090   let ParserMatchClass = CondCode;
   1091   let MCOperandPredicate = [{
   1092     return MCOp.isImm() &&
   1093            MCOp.getImm() != AArch64CC::AL &&
   1094            MCOp.getImm() != AArch64CC::NV;
   1095   }];
   1096 }
   1097 
   1098 // Conditional branch target. 19-bit immediate. The low two bits of the target
   1099 // offset are implied zero and so are not part of the immediate.
   1100 def PCRelLabel19Operand : AsmOperandClass {
   1101   let Name = "PCRelLabel19";
   1102   let DiagnosticType = "InvalidLabel";
   1103 }
   1104 def am_brcond : Operand<OtherVT> {
   1105   let EncoderMethod = "getCondBranchTargetOpValue";
   1106   let DecoderMethod = "DecodePCRelLabel19";
   1107   let PrintMethod = "printAlignedLabel";
   1108   let ParserMatchClass = PCRelLabel19Operand;
   1109 }
   1110 
   1111 class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
   1112                      "b", ".$cond\t$target", "",
   1113                      [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
   1114                    Sched<[WriteBr]> {
   1115   let isBranch = 1;
   1116   let isTerminator = 1;
   1117   let Uses = [NZCV];
   1118 
   1119   bits<4> cond;
   1120   bits<19> target;
   1121   let Inst{31-24} = 0b01010100;
   1122   let Inst{23-5} = target;
   1123   let Inst{4} = 0;
   1124   let Inst{3-0} = cond;
   1125 }
   1126 
   1127 //---
   1128 // Compare-and-branch instructions.
   1129 //---
   1130 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
   1131     : I<(outs), (ins regtype:$Rt, am_brcond:$target),
   1132          asm, "\t$Rt, $target", "",
   1133          [(node regtype:$Rt, bb:$target)]>,
   1134       Sched<[WriteBr]> {
   1135   let isBranch = 1;
   1136   let isTerminator = 1;
   1137 
   1138   bits<5> Rt;
   1139   bits<19> target;
   1140   let Inst{30-25} = 0b011010;
   1141   let Inst{24}    = op;
   1142   let Inst{23-5}  = target;
   1143   let Inst{4-0}   = Rt;
   1144 }
   1145 
   1146 multiclass CmpBranch<bit op, string asm, SDNode node> {
   1147   def W : BaseCmpBranch<GPR32, op, asm, node> {
   1148     let Inst{31} = 0;
   1149   }
   1150   def X : BaseCmpBranch<GPR64, op, asm, node> {
   1151     let Inst{31} = 1;
   1152   }
   1153 }
   1154 
   1155 //---
   1156 // Test-bit-and-branch instructions.
   1157 //---
   1158 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
   1159 // the target offset are implied zero and so are not part of the immediate.
   1160 def BranchTarget14Operand : AsmOperandClass {
   1161   let Name = "BranchTarget14";
   1162 }
   1163 def am_tbrcond : Operand<OtherVT> {
   1164   let EncoderMethod = "getTestBranchTargetOpValue";
   1165   let PrintMethod = "printAlignedLabel";
   1166   let ParserMatchClass = BranchTarget14Operand;
   1167 }
   1168 
   1169 // AsmOperand classes to emit (or not) special diagnostics
   1170 def TBZImm0_31Operand : AsmOperandClass {
   1171   let Name = "TBZImm0_31";
   1172   let PredicateMethod = "isImm0_31";
   1173   let RenderMethod = "addImm0_31Operands";
   1174 }
   1175 def TBZImm32_63Operand : AsmOperandClass {
   1176   let Name = "Imm32_63";
   1177   let DiagnosticType = "InvalidImm0_63";
   1178 }
   1179 
   1180 class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
   1181   return (((uint32_t)Imm) < 32);
   1182 }]> {
   1183   let ParserMatchClass = matcher;
   1184 }
   1185 
   1186 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
   1187 def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
   1188 
   1189 def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
   1190   return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
   1191 }]> {
   1192   let ParserMatchClass = TBZImm32_63Operand;
   1193 }
   1194 
   1195 class BaseTestBranch<RegisterClass regtype, Operand immtype,
   1196                      bit op, string asm, SDNode node>
   1197     : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
   1198        asm, "\t$Rt, $bit_off, $target", "",
   1199        [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
   1200       Sched<[WriteBr]> {
   1201   let isBranch = 1;
   1202   let isTerminator = 1;
   1203 
   1204   bits<5> Rt;
   1205   bits<6> bit_off;
   1206   bits<14> target;
   1207 
   1208   let Inst{30-25} = 0b011011;
   1209   let Inst{24}    = op;
   1210   let Inst{23-19} = bit_off{4-0};
   1211   let Inst{18-5}  = target;
   1212   let Inst{4-0}   = Rt;
   1213 
   1214   let DecoderMethod = "DecodeTestAndBranch";
   1215 }
   1216 
   1217 multiclass TestBranch<bit op, string asm, SDNode node> {
   1218   def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
   1219     let Inst{31} = 0;
   1220   }
   1221 
   1222   def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
   1223     let Inst{31} = 1;
   1224   }
   1225 
   1226   // Alias X-reg with 0-31 imm to W-Reg.
   1227   def : InstAlias<asm # "\t$Rd, $imm, $target",
   1228                   (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
   1229                   tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
   1230   def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
   1231             (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
   1232             tbz_imm0_31_diag:$imm, bb:$target)>;
   1233 }
   1234 
   1235 //---
   1236 // Unconditional branch (immediate) instructions.
   1237 //---
   1238 def BranchTarget26Operand : AsmOperandClass {
   1239   let Name = "BranchTarget26";
   1240   let DiagnosticType = "InvalidLabel";
   1241 }
   1242 def am_b_target : Operand<OtherVT> {
   1243   let EncoderMethod = "getBranchTargetOpValue";
   1244   let PrintMethod = "printAlignedLabel";
   1245   let ParserMatchClass = BranchTarget26Operand;
   1246 }
   1247 def am_bl_target : Operand<i64> {
   1248   let EncoderMethod = "getBranchTargetOpValue";
   1249   let PrintMethod = "printAlignedLabel";
   1250   let ParserMatchClass = BranchTarget26Operand;
   1251 }
   1252 
   1253 class BImm<bit op, dag iops, string asm, list<dag> pattern>
   1254     : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
   1255   bits<26> addr;
   1256   let Inst{31}    = op;
   1257   let Inst{30-26} = 0b00101;
   1258   let Inst{25-0}  = addr;
   1259 
   1260   let DecoderMethod = "DecodeUnconditionalBranch";
   1261 }
   1262 
   1263 class BranchImm<bit op, string asm, list<dag> pattern>
   1264     : BImm<op, (ins am_b_target:$addr), asm, pattern>;
   1265 class CallImm<bit op, string asm, list<dag> pattern>
   1266     : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
   1267 
   1268 //---
   1269 // Basic one-operand data processing instructions.
   1270 //---
   1271 
   1272 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   1273 class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
   1274                          SDPatternOperator node>
   1275   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
   1276       [(set regtype:$Rd, (node regtype:$Rn))]>,
   1277     Sched<[WriteI, ReadI]> {
   1278   bits<5> Rd;
   1279   bits<5> Rn;
   1280 
   1281   let Inst{30-13} = 0b101101011000000000;
   1282   let Inst{12-10} = opc;
   1283   let Inst{9-5}   = Rn;
   1284   let Inst{4-0}   = Rd;
   1285 }
   1286 
   1287 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   1288 multiclass OneOperandData<bits<3> opc, string asm,
   1289                           SDPatternOperator node = null_frag> {
   1290   def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
   1291     let Inst{31} = 0;
   1292   }
   1293 
   1294   def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
   1295     let Inst{31} = 1;
   1296   }
   1297 }
   1298 
   1299 class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
   1300     : BaseOneOperandData<opc, GPR32, asm, node> {
   1301   let Inst{31} = 0;
   1302 }
   1303 
   1304 class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
   1305     : BaseOneOperandData<opc, GPR64, asm, node> {
   1306   let Inst{31} = 1;
   1307 }
   1308 
   1309 //---
   1310 // Basic two-operand data processing instructions.
   1311 //---
   1312 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
   1313                           list<dag> pattern>
   1314     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
   1315         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
   1316       Sched<[WriteI, ReadI, ReadI]> {
   1317   let Uses = [NZCV];
   1318   bits<5> Rd;
   1319   bits<5> Rn;
   1320   bits<5> Rm;
   1321   let Inst{30}    = isSub;
   1322   let Inst{28-21} = 0b11010000;
   1323   let Inst{20-16} = Rm;
   1324   let Inst{15-10} = 0;
   1325   let Inst{9-5}   = Rn;
   1326   let Inst{4-0}   = Rd;
   1327 }
   1328 
   1329 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
   1330                       SDNode OpNode>
   1331     : BaseBaseAddSubCarry<isSub, regtype, asm,
   1332         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
   1333 
   1334 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
   1335                               SDNode OpNode>
   1336     : BaseBaseAddSubCarry<isSub, regtype, asm,
   1337         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
   1338          (implicit NZCV)]> {
   1339   let Defs = [NZCV];
   1340 }
   1341 
   1342 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
   1343                        SDNode OpNode, SDNode OpNode_setflags> {
   1344   def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
   1345     let Inst{31} = 0;
   1346     let Inst{29} = 0;
   1347   }
   1348   def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
   1349     let Inst{31} = 1;
   1350     let Inst{29} = 0;
   1351   }
   1352 
   1353   // Sets flags.
   1354   def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
   1355                                     OpNode_setflags> {
   1356     let Inst{31} = 0;
   1357     let Inst{29} = 1;
   1358   }
   1359   def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
   1360                                     OpNode_setflags> {
   1361     let Inst{31} = 1;
   1362     let Inst{29} = 1;
   1363   }
   1364 }
   1365 
   1366 class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
   1367                      SDPatternOperator OpNode>
   1368   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
   1369       asm, "\t$Rd, $Rn, $Rm", "",
   1370       [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
   1371   bits<5> Rd;
   1372   bits<5> Rn;
   1373   bits<5> Rm;
   1374   let Inst{30-21} = 0b0011010110;
   1375   let Inst{20-16} = Rm;
   1376   let Inst{15-14} = 0b00;
   1377   let Inst{13-10} = opc;
   1378   let Inst{9-5}   = Rn;
   1379   let Inst{4-0}   = Rd;
   1380 }
   1381 
   1382 class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
   1383               SDPatternOperator OpNode>
   1384     : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
   1385   let Inst{10}    = isSigned;
   1386 }
   1387 
   1388 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
   1389   def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
   1390            Sched<[WriteID32, ReadID, ReadID]> {
   1391     let Inst{31} = 0;
   1392   }
   1393   def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
   1394            Sched<[WriteID64, ReadID, ReadID]> {
   1395     let Inst{31} = 1;
   1396   }
   1397 }
   1398 
   1399 class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
   1400                 SDPatternOperator OpNode = null_frag>
   1401   : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
   1402     Sched<[WriteIS, ReadI]> {
   1403   let Inst{11-10} = shift_type;
   1404 }
   1405 
   1406 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
   1407   def Wr : BaseShift<shift_type, GPR32, asm> {
   1408     let Inst{31} = 0;
   1409   }
   1410 
   1411   def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
   1412     let Inst{31} = 1;
   1413   }
   1414 
   1415   def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
   1416             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
   1417                                              (EXTRACT_SUBREG i64:$Rm, sub_32))>;
   1418 
   1419   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
   1420             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
   1421 
   1422   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
   1423             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
   1424 
   1425   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
   1426             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
   1427 }
   1428 
   1429 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
   1430     : InstAlias<asm#"\t$dst, $src1, $src2",
   1431                 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
   1432 
   1433 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
   1434                        RegisterClass addtype, string asm,
   1435                        list<dag> pattern>
   1436   : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
   1437       asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
   1438   bits<5> Rd;
   1439   bits<5> Rn;
   1440   bits<5> Rm;
   1441   bits<5> Ra;
   1442   let Inst{30-24} = 0b0011011;
   1443   let Inst{23-21} = opc;
   1444   let Inst{20-16} = Rm;
   1445   let Inst{15}    = isSub;
   1446   let Inst{14-10} = Ra;
   1447   let Inst{9-5}   = Rn;
   1448   let Inst{4-0}   = Rd;
   1449 }
   1450 
   1451 multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
   1452   // MADD/MSUB generation is decided by MachineCombiner.cpp
   1453   def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
   1454       [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
   1455       Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
   1456     let Inst{31} = 0;
   1457   }
   1458 
   1459   def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
   1460       [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
   1461       Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
   1462     let Inst{31} = 1;
   1463   }
   1464 }
   1465 
   1466 class WideMulAccum<bit isSub, bits<3> opc, string asm,
   1467                    SDNode AccNode, SDNode ExtNode>
   1468   : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
   1469     [(set GPR64:$Rd, (AccNode GPR64:$Ra,
   1470                             (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
   1471     Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
   1472   let Inst{31} = 1;
   1473 }
   1474 
   1475 class MulHi<bits<3> opc, string asm, SDNode OpNode>
   1476   : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
   1477       asm, "\t$Rd, $Rn, $Rm", "",
   1478       [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
   1479     Sched<[WriteIM64, ReadIM, ReadIM]> {
   1480   bits<5> Rd;
   1481   bits<5> Rn;
   1482   bits<5> Rm;
   1483   let Inst{31-24} = 0b10011011;
   1484   let Inst{23-21} = opc;
   1485   let Inst{20-16} = Rm;
   1486   let Inst{15}    = 0;
   1487   let Inst{9-5}   = Rn;
   1488   let Inst{4-0}   = Rd;
   1489 
   1490   // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
   1491   // (i.e. all bits 1) but is ignored by the processor.
   1492   let PostEncoderMethod = "fixMulHigh";
   1493 }
   1494 
   1495 class MulAccumWAlias<string asm, Instruction inst>
   1496     : InstAlias<asm#"\t$dst, $src1, $src2",
   1497                 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
   1498 class MulAccumXAlias<string asm, Instruction inst>
   1499     : InstAlias<asm#"\t$dst, $src1, $src2",
   1500                 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
   1501 class WideMulAccumAlias<string asm, Instruction inst>
   1502     : InstAlias<asm#"\t$dst, $src1, $src2",
   1503                 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
   1504 
   1505 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
   1506               SDPatternOperator OpNode, string asm>
   1507   : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
   1508       asm, "\t$Rd, $Rn, $Rm", "",
   1509       [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
   1510     Sched<[WriteISReg, ReadI, ReadISReg]> {
   1511   bits<5> Rd;
   1512   bits<5> Rn;
   1513   bits<5> Rm;
   1514 
   1515   let Inst{31} = sf;
   1516   let Inst{30-21} = 0b0011010110;
   1517   let Inst{20-16} = Rm;
   1518   let Inst{15-13} = 0b010;
   1519   let Inst{12} = C;
   1520   let Inst{11-10} = sz;
   1521   let Inst{9-5} = Rn;
   1522   let Inst{4-0} = Rd;
   1523   let Predicates = [HasCRC];
   1524 }
   1525 
   1526 //---
   1527 // Address generation.
   1528 //---
   1529 
   1530 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
   1531     : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
   1532         pattern>,
   1533       Sched<[WriteI]> {
   1534   bits<5>  Xd;
   1535   bits<21> label;
   1536   let Inst{31}    = page;
   1537   let Inst{30-29} = label{1-0};
   1538   let Inst{28-24} = 0b10000;
   1539   let Inst{23-5}  = label{20-2};
   1540   let Inst{4-0}   = Xd;
   1541 
   1542   let DecoderMethod = "DecodeAdrInstruction";
   1543 }
   1544 
   1545 //---
   1546 // Move immediate.
   1547 //---
   1548 
   1549 def movimm32_imm : Operand<i32> {
   1550   let ParserMatchClass = Imm0_65535Operand;
   1551   let EncoderMethod = "getMoveWideImmOpValue";
   1552   let PrintMethod = "printHexImm";
   1553 }
   1554 def movimm32_shift : Operand<i32> {
   1555   let PrintMethod = "printShifter";
   1556   let ParserMatchClass = MovImm32ShifterOperand;
   1557 }
   1558 def movimm64_shift : Operand<i32> {
   1559   let PrintMethod = "printShifter";
   1560   let ParserMatchClass = MovImm64ShifterOperand;
   1561 }
   1562 
   1563 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   1564 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
   1565                         string asm>
   1566   : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
   1567        asm, "\t$Rd, $imm$shift", "", []>,
   1568     Sched<[WriteImm]> {
   1569   bits<5> Rd;
   1570   bits<16> imm;
   1571   bits<6> shift;
   1572   let Inst{30-29} = opc;
   1573   let Inst{28-23} = 0b100101;
   1574   let Inst{22-21} = shift{5-4};
   1575   let Inst{20-5}  = imm;
   1576   let Inst{4-0}   = Rd;
   1577 
   1578   let DecoderMethod = "DecodeMoveImmInstruction";
   1579 }
   1580 
   1581 multiclass MoveImmediate<bits<2> opc, string asm> {
   1582   def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
   1583     let Inst{31} = 0;
   1584   }
   1585 
   1586   def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
   1587     let Inst{31} = 1;
   1588   }
   1589 }
   1590 
   1591 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   1592 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
   1593                           string asm>
   1594   : I<(outs regtype:$Rd),
   1595       (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
   1596        asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
   1597     Sched<[WriteI, ReadI]> {
   1598   bits<5> Rd;
   1599   bits<16> imm;
   1600   bits<6> shift;
   1601   let Inst{30-29} = opc;
   1602   let Inst{28-23} = 0b100101;
   1603   let Inst{22-21} = shift{5-4};
   1604   let Inst{20-5}  = imm;
   1605   let Inst{4-0}   = Rd;
   1606 
   1607   let DecoderMethod = "DecodeMoveImmInstruction";
   1608 }
   1609 
   1610 multiclass InsertImmediate<bits<2> opc, string asm> {
   1611   def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
   1612     let Inst{31} = 0;
   1613   }
   1614 
   1615   def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
   1616     let Inst{31} = 1;
   1617   }
   1618 }
   1619 
   1620 //---
   1621 // Add/Subtract
   1622 //---
   1623 
   1624 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
   1625                     RegisterClass srcRegtype, addsub_shifted_imm immtype,
   1626                     string asm, SDPatternOperator OpNode>
   1627     : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
   1628         asm, "\t$Rd, $Rn, $imm", "",
   1629         [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
   1630       Sched<[WriteI, ReadI]>  {
   1631   bits<5>  Rd;
   1632   bits<5>  Rn;
   1633   bits<14> imm;
   1634   let Inst{30}    = isSub;
   1635   let Inst{29}    = setFlags;
   1636   let Inst{28-24} = 0b10001;
   1637   let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
   1638   let Inst{21-10} = imm{11-0};
   1639   let Inst{9-5}   = Rn;
   1640   let Inst{4-0}   = Rd;
   1641   let DecoderMethod = "DecodeBaseAddSubImm";
   1642 }
   1643 
   1644 class BaseAddSubRegPseudo<RegisterClass regtype,
   1645                           SDPatternOperator OpNode>
   1646     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
   1647              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
   1648       Sched<[WriteI, ReadI, ReadI]>;
   1649 
   1650 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
   1651                      arith_shifted_reg shifted_regtype, string asm,
   1652                      SDPatternOperator OpNode>
   1653     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
   1654         asm, "\t$Rd, $Rn, $Rm", "",
   1655         [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
   1656       Sched<[WriteISReg, ReadI, ReadISReg]> {
   1657   // The operands are in order to match the 'addr' MI operands, so we
   1658   // don't need an encoder method and by-name matching. Just use the default
   1659   // in-order handling. Since we're using by-order, make sure the names
   1660   // do not match.
   1661   bits<5> dst;
   1662   bits<5> src1;
   1663   bits<5> src2;
   1664   bits<8> shift;
   1665   let Inst{30}    = isSub;
   1666   let Inst{29}    = setFlags;
   1667   let Inst{28-24} = 0b01011;
   1668   let Inst{23-22} = shift{7-6};
   1669   let Inst{21}    = 0;
   1670   let Inst{20-16} = src2;
   1671   let Inst{15-10} = shift{5-0};
   1672   let Inst{9-5}   = src1;
   1673   let Inst{4-0}   = dst;
   1674 
   1675   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
   1676 }
   1677 
   1678 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
   1679                      RegisterClass src1Regtype, Operand src2Regtype,
   1680                      string asm, SDPatternOperator OpNode>
   1681     : I<(outs dstRegtype:$R1),
   1682         (ins src1Regtype:$R2, src2Regtype:$R3),
   1683         asm, "\t$R1, $R2, $R3", "",
   1684         [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
   1685       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
   1686   bits<5> Rd;
   1687   bits<5> Rn;
   1688   bits<5> Rm;
   1689   bits<6> ext;
   1690   let Inst{30}    = isSub;
   1691   let Inst{29}    = setFlags;
   1692   let Inst{28-24} = 0b01011;
   1693   let Inst{23-21} = 0b001;
   1694   let Inst{20-16} = Rm;
   1695   let Inst{15-13} = ext{5-3};
   1696   let Inst{12-10} = ext{2-0};
   1697   let Inst{9-5}   = Rn;
   1698   let Inst{4-0}   = Rd;
   1699 
   1700   let DecoderMethod = "DecodeAddSubERegInstruction";
   1701 }
   1702 
   1703 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   1704 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
   1705                        RegisterClass src1Regtype, RegisterClass src2Regtype,
   1706                        Operand ext_op, string asm>
   1707     : I<(outs dstRegtype:$Rd),
   1708         (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
   1709         asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
   1710       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
   1711   bits<5> Rd;
   1712   bits<5> Rn;
   1713   bits<5> Rm;
   1714   bits<6> ext;
   1715   let Inst{30}    = isSub;
   1716   let Inst{29}    = setFlags;
   1717   let Inst{28-24} = 0b01011;
   1718   let Inst{23-21} = 0b001;
   1719   let Inst{20-16} = Rm;
   1720   let Inst{15}    = ext{5};
   1721   let Inst{12-10} = ext{2-0};
   1722   let Inst{9-5}   = Rn;
   1723   let Inst{4-0}   = Rd;
   1724 
   1725   let DecoderMethod = "DecodeAddSubERegInstruction";
   1726 }
   1727 
   1728 // Aliases for register+register add/subtract.
   1729 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
   1730                      RegisterClass src1Regtype, RegisterClass src2Regtype,
   1731                      int shiftExt>
   1732     : InstAlias<asm#"\t$dst, $src1, $src2",
   1733                 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
   1734                       shiftExt)>;
   1735 
   1736 multiclass AddSub<bit isSub, string mnemonic, string alias,
   1737                   SDPatternOperator OpNode = null_frag> {
   1738   let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
   1739   // Add/Subtract immediate
   1740   // Increase the weight of the immediate variant to try to match it before
   1741   // the extended register variant.
   1742   // We used to match the register variant before the immediate when the
   1743   // register argument could be implicitly zero-extended.
   1744   let AddedComplexity = 6 in
   1745   def Wri  : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
   1746                            mnemonic, OpNode> {
   1747     let Inst{31} = 0;
   1748   }
   1749   let AddedComplexity = 6 in
   1750   def Xri  : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
   1751                            mnemonic, OpNode> {
   1752     let Inst{31} = 1;
   1753   }
   1754 
   1755   // Add/Subtract register - Only used for CodeGen
   1756   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
   1757   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
   1758 
   1759   // Add/Subtract shifted register
   1760   def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
   1761                            OpNode> {
   1762     let Inst{31} = 0;
   1763   }
   1764   def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
   1765                            OpNode> {
   1766     let Inst{31} = 1;
   1767   }
   1768   }
   1769 
   1770   // Add/Subtract extended register
   1771   let AddedComplexity = 1, hasSideEffects = 0 in {
   1772   def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
   1773                            arith_extended_reg32<i32>, mnemonic, OpNode> {
   1774     let Inst{31} = 0;
   1775   }
   1776   def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
   1777                            arith_extended_reg32to64<i64>, mnemonic, OpNode> {
   1778     let Inst{31} = 1;
   1779   }
   1780   }
   1781 
   1782   def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
   1783                                arith_extendlsl64, mnemonic> {
   1784     // UXTX and SXTX only.
   1785     let Inst{14-13} = 0b11;
   1786     let Inst{31} = 1;
   1787   }
   1788 
   1789   // add Rd, Rb, -imm -> sub Rd, Rn, imm
   1790   def : InstAlias<alias#"\t$Rd, $Rn, $imm",
   1791                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
   1792                       addsub_shifted_imm32_neg:$imm), 0>;
   1793   def : InstAlias<alias#"\t$Rd, $Rn, $imm",
   1794                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
   1795                        addsub_shifted_imm64_neg:$imm), 0>;
   1796 
   1797   // Register/register aliases with no shift when SP is not used.
   1798   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
   1799                        GPR32, GPR32, GPR32, 0>;
   1800   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
   1801                        GPR64, GPR64, GPR64, 0>;
   1802 
   1803   // Register/register aliases with no shift when either the destination or
   1804   // first source register is SP.
   1805   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
   1806                        GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
   1807   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
   1808                        GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
   1809   def : AddSubRegAlias<mnemonic,
   1810                        !cast<Instruction>(NAME#"Xrx64"),
   1811                        GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
   1812   def : AddSubRegAlias<mnemonic,
   1813                        !cast<Instruction>(NAME#"Xrx64"),
   1814                        GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
   1815 }
   1816 
   1817 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
   1818                    string alias, string cmpAlias> {
   1819   let isCompare = 1, Defs = [NZCV] in {
   1820   // Add/Subtract immediate
   1821   def Wri  : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
   1822                            mnemonic, OpNode> {
   1823     let Inst{31} = 0;
   1824   }
   1825   def Xri  : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
   1826                            mnemonic, OpNode> {
   1827     let Inst{31} = 1;
   1828   }
   1829 
   1830   // Add/Subtract register
   1831   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
   1832   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
   1833 
   1834   // Add/Subtract shifted register
   1835   def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
   1836                            OpNode> {
   1837     let Inst{31} = 0;
   1838   }
   1839   def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
   1840                            OpNode> {
   1841     let Inst{31} = 1;
   1842   }
   1843 
   1844   // Add/Subtract extended register
   1845   let AddedComplexity = 1 in {
   1846   def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
   1847                            arith_extended_reg32<i32>, mnemonic, OpNode> {
   1848     let Inst{31} = 0;
   1849   }
   1850   def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
   1851                            arith_extended_reg32<i64>, mnemonic, OpNode> {
   1852     let Inst{31} = 1;
   1853   }
   1854   }
   1855 
   1856   def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
   1857                                arith_extendlsl64, mnemonic> {
   1858     // UXTX and SXTX only.
   1859     let Inst{14-13} = 0b11;
   1860     let Inst{31} = 1;
   1861   }
   1862   } // Defs = [NZCV]
   1863 
   1864   // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
   1865   def : InstAlias<alias#"\t$Rd, $Rn, $imm",
   1866                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
   1867                       addsub_shifted_imm32_neg:$imm), 0>;
   1868   def : InstAlias<alias#"\t$Rd, $Rn, $imm",
   1869                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
   1870                        addsub_shifted_imm64_neg:$imm), 0>;
   1871 
   1872   // Compare aliases
   1873   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
   1874                   WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
   1875   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
   1876                   XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
   1877   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
   1878                   WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
   1879   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
   1880                   XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
   1881   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
   1882                   XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
   1883   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
   1884                   WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
   1885   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
   1886                   XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
   1887 
   1888   // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
   1889   def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
   1890                   WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
   1891   def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
   1892                   XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
   1893 
   1894   // Compare shorthands
   1895   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
   1896                   WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
   1897   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
   1898                   XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
   1899   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
   1900                   WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
   1901   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
   1902                   XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
   1903 
   1904   // Register/register aliases with no shift when SP is not used.
   1905   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
   1906                        GPR32, GPR32, GPR32, 0>;
   1907   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
   1908                        GPR64, GPR64, GPR64, 0>;
   1909 
   1910   // Register/register aliases with no shift when the first source register
   1911   // is SP.
   1912   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
   1913                        GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
   1914   def : AddSubRegAlias<mnemonic,
   1915                        !cast<Instruction>(NAME#"Xrx64"),
   1916                        GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
   1917 }
   1918 
   1919 //---
   1920 // Extract
   1921 //---
   1922 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
   1923                                       SDTCisPtrTy<3>]>;
   1924 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
   1925 
   1926 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
   1927                      list<dag> patterns>
   1928     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
   1929          asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
   1930       Sched<[WriteExtr, ReadExtrHi]> {
   1931   bits<5> Rd;
   1932   bits<5> Rn;
   1933   bits<5> Rm;
   1934   bits<6> imm;
   1935 
   1936   let Inst{30-23} = 0b00100111;
   1937   let Inst{21}    = 0;
   1938   let Inst{20-16} = Rm;
   1939   let Inst{15-10} = imm;
   1940   let Inst{9-5}   = Rn;
   1941   let Inst{4-0}   = Rd;
   1942 }
   1943 
   1944 multiclass ExtractImm<string asm> {
   1945   def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
   1946                       [(set GPR32:$Rd,
   1947                         (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
   1948     let Inst{31} = 0;
   1949     let Inst{22} = 0;
   1950     // imm<5> must be zero.
   1951     let imm{5}   = 0;
   1952   }
   1953   def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
   1954                       [(set GPR64:$Rd,
   1955                         (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
   1956 
   1957     let Inst{31} = 1;
   1958     let Inst{22} = 1;
   1959   }
   1960 }
   1961 
   1962 //---
   1963 // Bitfield
   1964 //---
   1965 
   1966 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   1967 class BaseBitfieldImm<bits<2> opc,
   1968                       RegisterClass regtype, Operand imm_type, string asm>
   1969     : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
   1970          asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
   1971       Sched<[WriteIS, ReadI]> {
   1972   bits<5> Rd;
   1973   bits<5> Rn;
   1974   bits<6> immr;
   1975   bits<6> imms;
   1976 
   1977   let Inst{30-29} = opc;
   1978   let Inst{28-23} = 0b100110;
   1979   let Inst{21-16} = immr;
   1980   let Inst{15-10} = imms;
   1981   let Inst{9-5}   = Rn;
   1982   let Inst{4-0}   = Rd;
   1983 }
   1984 
   1985 multiclass BitfieldImm<bits<2> opc, string asm> {
   1986   def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
   1987     let Inst{31} = 0;
   1988     let Inst{22} = 0;
   1989     // imms<5> and immr<5> must be zero, else ReservedValue().
   1990     let Inst{21} = 0;
   1991     let Inst{15} = 0;
   1992   }
   1993   def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
   1994     let Inst{31} = 1;
   1995     let Inst{22} = 1;
   1996   }
   1997 }
   1998 
   1999 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   2000 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
   2001                       RegisterClass regtype, Operand imm_type, string asm>
   2002     : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
   2003                              imm_type:$imms),
   2004          asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
   2005       Sched<[WriteIS, ReadI]> {
   2006   bits<5> Rd;
   2007   bits<5> Rn;
   2008   bits<6> immr;
   2009   bits<6> imms;
   2010 
   2011   let Inst{30-29} = opc;
   2012   let Inst{28-23} = 0b100110;
   2013   let Inst{21-16} = immr;
   2014   let Inst{15-10} = imms;
   2015   let Inst{9-5}   = Rn;
   2016   let Inst{4-0}   = Rd;
   2017 }
   2018 
   2019 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
   2020   def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
   2021     let Inst{31} = 0;
   2022     let Inst{22} = 0;
   2023     // imms<5> and immr<5> must be zero, else ReservedValue().
   2024     let Inst{21} = 0;
   2025     let Inst{15} = 0;
   2026   }
   2027   def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
   2028     let Inst{31} = 1;
   2029     let Inst{22} = 1;
   2030   }
   2031 }
   2032 
   2033 //---
   2034 // Logical
   2035 //---
   2036 
   2037 // Logical (immediate)
   2038 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
   2039                      RegisterClass sregtype, Operand imm_type, string asm,
   2040                      list<dag> pattern>
   2041     : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
   2042          asm, "\t$Rd, $Rn, $imm", "", pattern>,
   2043       Sched<[WriteI, ReadI]> {
   2044   bits<5>  Rd;
   2045   bits<5>  Rn;
   2046   bits<13> imm;
   2047   let Inst{30-29} = opc;
   2048   let Inst{28-23} = 0b100100;
   2049   let Inst{22}    = imm{12};
   2050   let Inst{21-16} = imm{11-6};
   2051   let Inst{15-10} = imm{5-0};
   2052   let Inst{9-5}   = Rn;
   2053   let Inst{4-0}   = Rd;
   2054 
   2055   let DecoderMethod = "DecodeLogicalImmInstruction";
   2056 }
   2057 
   2058 // Logical (shifted register)
   2059 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
   2060                       logical_shifted_reg shifted_regtype, string asm,
   2061                       list<dag> pattern>
   2062     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
   2063         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
   2064       Sched<[WriteISReg, ReadI, ReadISReg]> {
   2065   // The operands are in order to match the 'addr' MI operands, so we
   2066   // don't need an encoder method and by-name matching. Just use the default
   2067   // in-order handling. Since we're using by-order, make sure the names
   2068   // do not match.
   2069   bits<5> dst;
   2070   bits<5> src1;
   2071   bits<5> src2;
   2072   bits<8> shift;
   2073   let Inst{30-29} = opc;
   2074   let Inst{28-24} = 0b01010;
   2075   let Inst{23-22} = shift{7-6};
   2076   let Inst{21}    = N;
   2077   let Inst{20-16} = src2;
   2078   let Inst{15-10} = shift{5-0};
   2079   let Inst{9-5}   = src1;
   2080   let Inst{4-0}   = dst;
   2081 
   2082   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
   2083 }
   2084 
   2085 // Aliases for register+register logical instructions.
   2086 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
   2087     : InstAlias<asm#"\t$dst, $src1, $src2",
   2088                 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
   2089 
   2090 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
   2091                       string Alias> {
   2092   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
   2093   def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
   2094                            [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
   2095                                                logical_imm32:$imm))]> {
   2096     let Inst{31} = 0;
   2097     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
   2098   }
   2099   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
   2100   def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
   2101                            [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
   2102                                                logical_imm64:$imm))]> {
   2103     let Inst{31} = 1;
   2104   }
   2105 
   2106   def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
   2107                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
   2108                       logical_imm32_not:$imm), 0>;
   2109   def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
   2110                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
   2111                        logical_imm64_not:$imm), 0>;
   2112 }
   2113 
   2114 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
   2115                        string Alias> {
   2116   let isCompare = 1, Defs = [NZCV] in {
   2117   def Wri  : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
   2118       [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
   2119     let Inst{31} = 0;
   2120     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
   2121   }
   2122   def Xri  : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
   2123       [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
   2124     let Inst{31} = 1;
   2125   }
   2126   } // end Defs = [NZCV]
   2127 
   2128   def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
   2129                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
   2130                       logical_imm32_not:$imm), 0>;
   2131   def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
   2132                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
   2133                        logical_imm64_not:$imm), 0>;
   2134 }
   2135 
   2136 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
   2137     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
   2138              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
   2139       Sched<[WriteI, ReadI, ReadI]>;
   2140 
   2141 // Split from LogicalImm as not all instructions have both.
   2142 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
   2143                       SDPatternOperator OpNode> {
   2144   let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
   2145   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
   2146   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
   2147   }
   2148 
   2149   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
   2150                             [(set GPR32:$Rd, (OpNode GPR32:$Rn,
   2151                                                  logical_shifted_reg32:$Rm))]> {
   2152     let Inst{31} = 0;
   2153   }
   2154   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
   2155                             [(set GPR64:$Rd, (OpNode GPR64:$Rn,
   2156                                                  logical_shifted_reg64:$Rm))]> {
   2157     let Inst{31} = 1;
   2158   }
   2159 
   2160   def : LogicalRegAlias<mnemonic,
   2161                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
   2162   def : LogicalRegAlias<mnemonic,
   2163                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
   2164 }
   2165 
   2166 // Split from LogicalReg to allow setting NZCV Defs
   2167 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
   2168                        SDPatternOperator OpNode = null_frag> {
   2169   let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
   2170   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
   2171   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
   2172 
   2173   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
   2174             [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
   2175     let Inst{31} = 0;
   2176   }
   2177   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
   2178             [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
   2179     let Inst{31} = 1;
   2180   }
   2181   } // Defs = [NZCV]
   2182 
   2183   def : LogicalRegAlias<mnemonic,
   2184                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
   2185   def : LogicalRegAlias<mnemonic,
   2186                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
   2187 }
   2188 
   2189 //---
   2190 // Conditionally set flags
   2191 //---
   2192 
   2193 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   2194 class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
   2195                             string mnemonic, SDNode OpNode>
   2196     : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
   2197          mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
   2198          [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
   2199                              (i32 imm:$cond), NZCV))]>,
   2200       Sched<[WriteI, ReadI]> {
   2201   let Uses = [NZCV];
   2202   let Defs = [NZCV];
   2203 
   2204   bits<5> Rn;
   2205   bits<5> imm;
   2206   bits<4> nzcv;
   2207   bits<4> cond;
   2208 
   2209   let Inst{30}    = op;
   2210   let Inst{29-21} = 0b111010010;
   2211   let Inst{20-16} = imm;
   2212   let Inst{15-12} = cond;
   2213   let Inst{11-10} = 0b10;
   2214   let Inst{9-5}   = Rn;
   2215   let Inst{4}     = 0b0;
   2216   let Inst{3-0}   = nzcv;
   2217 }
   2218 
   2219 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   2220 class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
   2221                             SDNode OpNode>
   2222     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
   2223          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
   2224          [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
   2225                              (i32 imm:$cond), NZCV))]>,
   2226       Sched<[WriteI, ReadI, ReadI]> {
   2227   let Uses = [NZCV];
   2228   let Defs = [NZCV];
   2229 
   2230   bits<5> Rn;
   2231   bits<5> Rm;
   2232   bits<4> nzcv;
   2233   bits<4> cond;
   2234 
   2235   let Inst{30}    = op;
   2236   let Inst{29-21} = 0b111010010;
   2237   let Inst{20-16} = Rm;
   2238   let Inst{15-12} = cond;
   2239   let Inst{11-10} = 0b00;
   2240   let Inst{9-5}   = Rn;
   2241   let Inst{4}     = 0b0;
   2242   let Inst{3-0}   = nzcv;
   2243 }
   2244 
   2245 multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
   2246   // immediate operand variants
   2247   def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
   2248     let Inst{31} = 0;
   2249   }
   2250   def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
   2251     let Inst{31} = 1;
   2252   }
   2253   // register operand variants
   2254   def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
   2255     let Inst{31} = 0;
   2256   }
   2257   def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
   2258     let Inst{31} = 1;
   2259   }
   2260 }
   2261 
   2262 //---
   2263 // Conditional select
   2264 //---
   2265 
   2266 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
   2267     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
   2268          asm, "\t$Rd, $Rn, $Rm, $cond", "",
   2269          [(set regtype:$Rd,
   2270                (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
   2271       Sched<[WriteI, ReadI, ReadI]> {
   2272   let Uses = [NZCV];
   2273 
   2274   bits<5> Rd;
   2275   bits<5> Rn;
   2276   bits<5> Rm;
   2277   bits<4> cond;
   2278 
   2279   let Inst{30}    = op;
   2280   let Inst{29-21} = 0b011010100;
   2281   let Inst{20-16} = Rm;
   2282   let Inst{15-12} = cond;
   2283   let Inst{11-10} = op2;
   2284   let Inst{9-5}   = Rn;
   2285   let Inst{4-0}   = Rd;
   2286 }
   2287 
   2288 multiclass CondSelect<bit op, bits<2> op2, string asm> {
   2289   def Wr : BaseCondSelect<op, op2, GPR32, asm> {
   2290     let Inst{31} = 0;
   2291   }
   2292   def Xr : BaseCondSelect<op, op2, GPR64, asm> {
   2293     let Inst{31} = 1;
   2294   }
   2295 }
   2296 
   2297 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
   2298                        PatFrag frag>
   2299     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
   2300          asm, "\t$Rd, $Rn, $Rm, $cond", "",
   2301          [(set regtype:$Rd,
   2302                (AArch64csel regtype:$Rn, (frag regtype:$Rm),
   2303                (i32 imm:$cond), NZCV))]>,
   2304       Sched<[WriteI, ReadI, ReadI]> {
   2305   let Uses = [NZCV];
   2306 
   2307   bits<5> Rd;
   2308   bits<5> Rn;
   2309   bits<5> Rm;
   2310   bits<4> cond;
   2311 
   2312   let Inst{30}    = op;
   2313   let Inst{29-21} = 0b011010100;
   2314   let Inst{20-16} = Rm;
   2315   let Inst{15-12} = cond;
   2316   let Inst{11-10} = op2;
   2317   let Inst{9-5}   = Rn;
   2318   let Inst{4-0}   = Rd;
   2319 }
   2320 
   2321 def inv_cond_XFORM : SDNodeXForm<imm, [{
   2322   AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
   2323   return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
   2324                                    MVT::i32);
   2325 }]>;
   2326 
   2327 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
   2328   def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
   2329     let Inst{31} = 0;
   2330   }
   2331   def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
   2332     let Inst{31} = 1;
   2333   }
   2334 
   2335   def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
   2336             (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
   2337                                            (inv_cond_XFORM imm:$cond))>;
   2338 
   2339   def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
   2340             (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
   2341                                            (inv_cond_XFORM imm:$cond))>;
   2342 }
   2343 
   2344 //---
   2345 // Special Mask Value
   2346 //---
   2347 def maski8_or_more : Operand<i32>,
   2348   ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
   2349 }
   2350 def maski16_or_more : Operand<i32>,
   2351   ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
   2352 }
   2353 
   2354 
   2355 //---
   2356 // Load/store
   2357 //---
   2358 
   2359 // (unsigned immediate)
   2360 // Indexed for 8-bit registers. offset is in range [0,4095].
   2361 def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
   2362 def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
   2363 def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
   2364 def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
   2365 def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
   2366 
   2367 class UImm12OffsetOperand<int Scale> : AsmOperandClass {
   2368   let Name = "UImm12Offset" # Scale;
   2369   let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
   2370   let PredicateMethod = "isUImm12Offset<" # Scale # ">";
   2371   let DiagnosticType = "InvalidMemoryIndexed" # Scale;
   2372 }
   2373 
   2374 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
   2375 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
   2376 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
   2377 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
   2378 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
   2379 
   2380 class uimm12_scaled<int Scale> : Operand<i64> {
   2381   let ParserMatchClass
   2382    = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
   2383   let EncoderMethod
   2384    = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
   2385   let PrintMethod = "printUImm12Offset<" # Scale # ">";
   2386 }
   2387 
   2388 def uimm12s1 : uimm12_scaled<1>;
   2389 def uimm12s2 : uimm12_scaled<2>;
   2390 def uimm12s4 : uimm12_scaled<4>;
   2391 def uimm12s8 : uimm12_scaled<8>;
   2392 def uimm12s16 : uimm12_scaled<16>;
   2393 
   2394 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
   2395                       string asm, list<dag> pattern>
   2396     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
   2397   bits<5> Rt;
   2398 
   2399   bits<5> Rn;
   2400   bits<12> offset;
   2401 
   2402   let Inst{31-30} = sz;
   2403   let Inst{29-27} = 0b111;
   2404   let Inst{26}    = V;
   2405   let Inst{25-24} = 0b01;
   2406   let Inst{23-22} = opc;
   2407   let Inst{21-10} = offset;
   2408   let Inst{9-5}   = Rn;
   2409   let Inst{4-0}   = Rt;
   2410 
   2411   let DecoderMethod = "DecodeUnsignedLdStInstruction";
   2412 }
   2413 
   2414 multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2415                   Operand indextype, string asm, list<dag> pattern> {
   2416   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   2417   def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
   2418                            (ins GPR64sp:$Rn, indextype:$offset),
   2419                            asm, pattern>,
   2420            Sched<[WriteLD]>;
   2421 
   2422   def : InstAlias<asm # "\t$Rt, [$Rn]",
   2423                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
   2424 }
   2425 
   2426 multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2427              Operand indextype, string asm, list<dag> pattern> {
   2428   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   2429   def ui : BaseLoadStoreUI<sz, V, opc, (outs),
   2430                            (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
   2431                            asm, pattern>,
   2432            Sched<[WriteST]>;
   2433 
   2434   def : InstAlias<asm # "\t$Rt, [$Rn]",
   2435                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
   2436 }
   2437 
   2438 def PrefetchOperand : AsmOperandClass {
   2439   let Name = "Prefetch";
   2440   let ParserMethod = "tryParsePrefetch";
   2441 }
   2442 def prfop : Operand<i32> {
   2443   let PrintMethod = "printPrefetchOp";
   2444   let ParserMatchClass = PrefetchOperand;
   2445 }
   2446 
   2447 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
   2448 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
   2449     : BaseLoadStoreUI<sz, V, opc,
   2450                       (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
   2451                       asm, pat>,
   2452       Sched<[WriteLD]>;
   2453 
   2454 //---
   2455 // Load literal
   2456 //---
   2457 
   2458 // Load literal address: 19-bit immediate. The low two bits of the target
   2459 // offset are implied zero and so are not part of the immediate.
   2460 def am_ldrlit : Operand<OtherVT> {
   2461   let EncoderMethod = "getLoadLiteralOpValue";
   2462   let DecoderMethod = "DecodePCRelLabel19";
   2463   let PrintMethod = "printAlignedLabel";
   2464   let ParserMatchClass = PCRelLabel19Operand;
   2465 }
   2466 
   2467 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   2468 class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm>
   2469     : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
   2470         asm, "\t$Rt, $label", "", []>,
   2471       Sched<[WriteLD]> {
   2472   bits<5> Rt;
   2473   bits<19> label;
   2474   let Inst{31-30} = opc;
   2475   let Inst{29-27} = 0b011;
   2476   let Inst{26}    = V;
   2477   let Inst{25-24} = 0b00;
   2478   let Inst{23-5}  = label;
   2479   let Inst{4-0}   = Rt;
   2480 }
   2481 
   2482 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
   2483 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
   2484     : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
   2485         asm, "\t$Rt, $label", "", pat>,
   2486       Sched<[WriteLD]> {
   2487   bits<5> Rt;
   2488   bits<19> label;
   2489   let Inst{31-30} = opc;
   2490   let Inst{29-27} = 0b011;
   2491   let Inst{26}    = V;
   2492   let Inst{25-24} = 0b00;
   2493   let Inst{23-5}  = label;
   2494   let Inst{4-0}   = Rt;
   2495 }
   2496 
   2497 //---
   2498 // Load/store register offset
   2499 //---
   2500 
   2501 def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
   2502 def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
   2503 def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
   2504 def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
   2505 def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
   2506 
   2507 def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
   2508 def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
   2509 def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
   2510 def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
   2511 def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
   2512 
   2513 class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
   2514   let Name = "Mem" # Reg # "Extend" # Width;
   2515   let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
   2516   let RenderMethod = "addMemExtendOperands";
   2517   let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
   2518 }
   2519 
   2520 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
   2521   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
   2522   // the trivial shift.
   2523   let RenderMethod = "addMemExtend8Operands";
   2524 }
   2525 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
   2526 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
   2527 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
   2528 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
   2529 
   2530 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
   2531   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
   2532   // the trivial shift.
   2533   let RenderMethod = "addMemExtend8Operands";
   2534 }
   2535 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
   2536 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
   2537 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
   2538 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
   2539 
   2540 class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
   2541         : Operand<i32> {
   2542   let ParserMatchClass = ParserClass;
   2543   let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
   2544   let DecoderMethod = "DecodeMemExtend";
   2545   let EncoderMethod = "getMemExtendOpValue";
   2546   let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
   2547 }
   2548 
   2549 def ro_Wextend8   : ro_extend<MemWExtend8Operand,   "w", 8>;
   2550 def ro_Wextend16  : ro_extend<MemWExtend16Operand,  "w", 16>;
   2551 def ro_Wextend32  : ro_extend<MemWExtend32Operand,  "w", 32>;
   2552 def ro_Wextend64  : ro_extend<MemWExtend64Operand,  "w", 64>;
   2553 def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
   2554 
   2555 def ro_Xextend8   : ro_extend<MemXExtend8Operand,   "x", 8>;
   2556 def ro_Xextend16  : ro_extend<MemXExtend16Operand,  "x", 16>;
   2557 def ro_Xextend32  : ro_extend<MemXExtend32Operand,  "x", 32>;
   2558 def ro_Xextend64  : ro_extend<MemXExtend64Operand,  "x", 64>;
   2559 def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
   2560 
   2561 class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
   2562                   Operand wextend, Operand xextend>  {
   2563   // CodeGen-level pattern covering the entire addressing mode.
   2564   ComplexPattern Wpat = windex;
   2565   ComplexPattern Xpat = xindex;
   2566 
   2567   // Asm-level Operand covering the valid "uxtw #3" style syntax.
   2568   Operand Wext = wextend;
   2569   Operand Xext = xextend;
   2570 }
   2571 
   2572 def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
   2573 def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
   2574 def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
   2575 def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
   2576 def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
   2577                        ro_Xextend128>;
   2578 
   2579 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2580                       string asm, dag ins, dag outs, list<dag> pat>
   2581     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
   2582   bits<5> Rt;
   2583   bits<5> Rn;
   2584   bits<5> Rm;
   2585   bits<2> extend;
   2586   let Inst{31-30} = sz;
   2587   let Inst{29-27} = 0b111;
   2588   let Inst{26}    = V;
   2589   let Inst{25-24} = 0b00;
   2590   let Inst{23-22} = opc;
   2591   let Inst{21}    = 1;
   2592   let Inst{20-16} = Rm;
   2593   let Inst{15}    = extend{1}; // sign extend Rm?
   2594   let Inst{14}    = 1;
   2595   let Inst{12}    = extend{0}; // do shift?
   2596   let Inst{11-10} = 0b10;
   2597   let Inst{9-5}   = Rn;
   2598   let Inst{4-0}   = Rt;
   2599 }
   2600 
   2601 class ROInstAlias<string asm, RegisterClass regtype, Instruction INST>
   2602   : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
   2603               (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
   2604 
   2605 multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2606                    string asm, ValueType Ty, SDPatternOperator loadop> {
   2607   let AddedComplexity = 10 in
   2608   def roW : LoadStore8RO<sz, V, opc, regtype, asm,
   2609                  (outs regtype:$Rt),
   2610                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
   2611                  [(set (Ty regtype:$Rt),
   2612                        (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
   2613                                              ro_Wextend8:$extend)))]>,
   2614            Sched<[WriteLDIdx, ReadAdrBase]> {
   2615     let Inst{13} = 0b0;
   2616   }
   2617 
   2618   let AddedComplexity = 10 in
   2619   def roX : LoadStore8RO<sz, V, opc, regtype, asm,
   2620                  (outs regtype:$Rt),
   2621                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
   2622                  [(set (Ty regtype:$Rt),
   2623                        (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
   2624                                              ro_Xextend8:$extend)))]>,
   2625            Sched<[WriteLDIdx, ReadAdrBase]> {
   2626     let Inst{13} = 0b1;
   2627   }
   2628 
   2629   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2630 }
   2631 
   2632 multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2633                     string asm, ValueType Ty, SDPatternOperator storeop> {
   2634   let AddedComplexity = 10 in
   2635   def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
   2636                  (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
   2637                  [(storeop (Ty regtype:$Rt),
   2638                            (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
   2639                                          ro_Wextend8:$extend))]>,
   2640             Sched<[WriteSTIdx, ReadAdrBase]> {
   2641     let Inst{13} = 0b0;
   2642   }
   2643 
   2644   let AddedComplexity = 10 in
   2645   def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
   2646                  (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
   2647                  [(storeop (Ty regtype:$Rt),
   2648                            (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
   2649                                          ro_Xextend8:$extend))]>,
   2650             Sched<[WriteSTIdx, ReadAdrBase]> {
   2651     let Inst{13} = 0b1;
   2652   }
   2653 
   2654   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2655 }
   2656 
   2657 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2658                       string asm, dag ins, dag outs, list<dag> pat>
   2659     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
   2660   bits<5> Rt;
   2661   bits<5> Rn;
   2662   bits<5> Rm;
   2663   bits<2> extend;
   2664   let Inst{31-30} = sz;
   2665   let Inst{29-27} = 0b111;
   2666   let Inst{26}    = V;
   2667   let Inst{25-24} = 0b00;
   2668   let Inst{23-22} = opc;
   2669   let Inst{21}    = 1;
   2670   let Inst{20-16} = Rm;
   2671   let Inst{15}    = extend{1}; // sign extend Rm?
   2672   let Inst{14}    = 1;
   2673   let Inst{12}    = extend{0}; // do shift?
   2674   let Inst{11-10} = 0b10;
   2675   let Inst{9-5}   = Rn;
   2676   let Inst{4-0}   = Rt;
   2677 }
   2678 
   2679 multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2680                     string asm, ValueType Ty, SDPatternOperator loadop> {
   2681   let AddedComplexity = 10 in
   2682   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2683                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
   2684                  [(set (Ty regtype:$Rt),
   2685                        (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
   2686                                               ro_Wextend16:$extend)))]>,
   2687             Sched<[WriteLDIdx, ReadAdrBase]> {
   2688     let Inst{13} = 0b0;
   2689   }
   2690 
   2691   let AddedComplexity = 10 in
   2692   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2693                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
   2694                  [(set (Ty regtype:$Rt),
   2695                        (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
   2696                                              ro_Xextend16:$extend)))]>,
   2697             Sched<[WriteLDIdx, ReadAdrBase]> {
   2698     let Inst{13} = 0b1;
   2699   }
   2700 
   2701   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2702 }
   2703 
   2704 multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2705                      string asm, ValueType Ty, SDPatternOperator storeop> {
   2706   let AddedComplexity = 10 in
   2707   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
   2708                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
   2709                 [(storeop (Ty regtype:$Rt),
   2710                           (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
   2711                                          ro_Wextend16:$extend))]>,
   2712            Sched<[WriteSTIdx, ReadAdrBase]> {
   2713     let Inst{13} = 0b0;
   2714   }
   2715 
   2716   let AddedComplexity = 10 in
   2717   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
   2718                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
   2719                 [(storeop (Ty regtype:$Rt),
   2720                           (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
   2721                                          ro_Xextend16:$extend))]>,
   2722            Sched<[WriteSTIdx, ReadAdrBase]> {
   2723     let Inst{13} = 0b1;
   2724   }
   2725 
   2726   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2727 }
   2728 
   2729 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2730                       string asm, dag ins, dag outs, list<dag> pat>
   2731     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
   2732   bits<5> Rt;
   2733   bits<5> Rn;
   2734   bits<5> Rm;
   2735   bits<2> extend;
   2736   let Inst{31-30} = sz;
   2737   let Inst{29-27} = 0b111;
   2738   let Inst{26}    = V;
   2739   let Inst{25-24} = 0b00;
   2740   let Inst{23-22} = opc;
   2741   let Inst{21}    = 1;
   2742   let Inst{20-16} = Rm;
   2743   let Inst{15}    = extend{1}; // sign extend Rm?
   2744   let Inst{14}    = 1;
   2745   let Inst{12}    = extend{0}; // do shift?
   2746   let Inst{11-10} = 0b10;
   2747   let Inst{9-5}   = Rn;
   2748   let Inst{4-0}   = Rt;
   2749 }
   2750 
   2751 multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2752                     string asm, ValueType Ty, SDPatternOperator loadop> {
   2753   let AddedComplexity = 10 in
   2754   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2755                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
   2756                  [(set (Ty regtype:$Rt),
   2757                        (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
   2758                                               ro_Wextend32:$extend)))]>,
   2759            Sched<[WriteLDIdx, ReadAdrBase]> {
   2760     let Inst{13} = 0b0;
   2761   }
   2762 
   2763   let AddedComplexity = 10 in
   2764   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2765                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
   2766                  [(set (Ty regtype:$Rt),
   2767                        (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
   2768                                               ro_Xextend32:$extend)))]>,
   2769            Sched<[WriteLDIdx, ReadAdrBase]> {
   2770     let Inst{13} = 0b1;
   2771   }
   2772 
   2773   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2774 }
   2775 
   2776 multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2777                      string asm, ValueType Ty, SDPatternOperator storeop> {
   2778   let AddedComplexity = 10 in
   2779   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
   2780                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
   2781                 [(storeop (Ty regtype:$Rt),
   2782                           (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
   2783                                          ro_Wextend32:$extend))]>,
   2784             Sched<[WriteSTIdx, ReadAdrBase]> {
   2785     let Inst{13} = 0b0;
   2786   }
   2787 
   2788   let AddedComplexity = 10 in
   2789   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
   2790                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
   2791                 [(storeop (Ty regtype:$Rt),
   2792                           (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
   2793                                         ro_Xextend32:$extend))]>,
   2794             Sched<[WriteSTIdx, ReadAdrBase]> {
   2795     let Inst{13} = 0b1;
   2796   }
   2797 
   2798   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2799 }
   2800 
   2801 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2802                       string asm, dag ins, dag outs, list<dag> pat>
   2803     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
   2804   bits<5> Rt;
   2805   bits<5> Rn;
   2806   bits<5> Rm;
   2807   bits<2> extend;
   2808   let Inst{31-30} = sz;
   2809   let Inst{29-27} = 0b111;
   2810   let Inst{26}    = V;
   2811   let Inst{25-24} = 0b00;
   2812   let Inst{23-22} = opc;
   2813   let Inst{21}    = 1;
   2814   let Inst{20-16} = Rm;
   2815   let Inst{15}    = extend{1}; // sign extend Rm?
   2816   let Inst{14}    = 1;
   2817   let Inst{12}    = extend{0}; // do shift?
   2818   let Inst{11-10} = 0b10;
   2819   let Inst{9-5}   = Rn;
   2820   let Inst{4-0}   = Rt;
   2821 }
   2822 
   2823 multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2824                     string asm, ValueType Ty, SDPatternOperator loadop> {
   2825   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   2826   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2827                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
   2828                 [(set (Ty regtype:$Rt),
   2829                       (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
   2830                                              ro_Wextend64:$extend)))]>,
   2831            Sched<[WriteLDIdx, ReadAdrBase]> {
   2832     let Inst{13} = 0b0;
   2833   }
   2834 
   2835   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   2836   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2837                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
   2838                  [(set (Ty regtype:$Rt),
   2839                        (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
   2840                                               ro_Xextend64:$extend)))]>,
   2841            Sched<[WriteLDIdx, ReadAdrBase]> {
   2842     let Inst{13} = 0b1;
   2843   }
   2844 
   2845   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2846 }
   2847 
   2848 multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2849                      string asm, ValueType Ty, SDPatternOperator storeop> {
   2850   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   2851   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
   2852                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
   2853                 [(storeop (Ty regtype:$Rt),
   2854                           (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
   2855                                          ro_Wextend64:$extend))]>,
   2856             Sched<[WriteSTIdx, ReadAdrBase]> {
   2857     let Inst{13} = 0b0;
   2858   }
   2859 
   2860   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   2861   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
   2862                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
   2863                 [(storeop (Ty regtype:$Rt),
   2864                           (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
   2865                                          ro_Xextend64:$extend))]>,
   2866             Sched<[WriteSTIdx, ReadAdrBase]> {
   2867     let Inst{13} = 0b1;
   2868   }
   2869 
   2870   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2871 }
   2872 
   2873 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2874                       string asm, dag ins, dag outs, list<dag> pat>
   2875     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
   2876   bits<5> Rt;
   2877   bits<5> Rn;
   2878   bits<5> Rm;
   2879   bits<2> extend;
   2880   let Inst{31-30} = sz;
   2881   let Inst{29-27} = 0b111;
   2882   let Inst{26}    = V;
   2883   let Inst{25-24} = 0b00;
   2884   let Inst{23-22} = opc;
   2885   let Inst{21}    = 1;
   2886   let Inst{20-16} = Rm;
   2887   let Inst{15}    = extend{1}; // sign extend Rm?
   2888   let Inst{14}    = 1;
   2889   let Inst{12}    = extend{0}; // do shift?
   2890   let Inst{11-10} = 0b10;
   2891   let Inst{9-5}   = Rn;
   2892   let Inst{4-0}   = Rt;
   2893 }
   2894 
   2895 multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2896                      string asm, ValueType Ty, SDPatternOperator loadop> {
   2897   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   2898   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2899                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
   2900                  [(set (Ty regtype:$Rt),
   2901                        (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
   2902                                                ro_Wextend128:$extend)))]>,
   2903             Sched<[WriteLDIdx, ReadAdrBase]> {
   2904     let Inst{13} = 0b0;
   2905   }
   2906 
   2907   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   2908   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
   2909                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
   2910                  [(set (Ty regtype:$Rt),
   2911                        (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
   2912                                                ro_Xextend128:$extend)))]>,
   2913             Sched<[WriteLDIdx, ReadAdrBase]> {
   2914     let Inst{13} = 0b1;
   2915   }
   2916 
   2917   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2918 }
   2919 
   2920 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   2921                       string asm, ValueType Ty, SDPatternOperator storeop> {
   2922   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   2923   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
   2924                (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
   2925                 [(storeop (Ty regtype:$Rt),
   2926                           (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
   2927                                           ro_Wextend128:$extend))]>,
   2928             Sched<[WriteSTIdx, ReadAdrBase]> {
   2929     let Inst{13} = 0b0;
   2930   }
   2931 
   2932   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   2933   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
   2934                (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
   2935                 [(storeop (Ty regtype:$Rt),
   2936                           (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
   2937                                           ro_Xextend128:$extend))]>,
   2938             Sched<[WriteSTIdx, ReadAdrBase]> {
   2939     let Inst{13} = 0b1;
   2940   }
   2941 
   2942   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
   2943 }
   2944 
   2945 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
   2946 class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
   2947                      string asm, list<dag> pat>
   2948     : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
   2949       Sched<[WriteLD]> {
   2950   bits<5> Rt;
   2951   bits<5> Rn;
   2952   bits<5> Rm;
   2953   bits<2> extend;
   2954   let Inst{31-30} = sz;
   2955   let Inst{29-27} = 0b111;
   2956   let Inst{26}    = V;
   2957   let Inst{25-24} = 0b00;
   2958   let Inst{23-22} = opc;
   2959   let Inst{21}    = 1;
   2960   let Inst{20-16} = Rm;
   2961   let Inst{15}    = extend{1}; // sign extend Rm?
   2962   let Inst{14}    = 1;
   2963   let Inst{12}    = extend{0}; // do shift?
   2964   let Inst{11-10} = 0b10;
   2965   let Inst{9-5}   = Rn;
   2966   let Inst{4-0}   = Rt;
   2967 }
   2968 
   2969 multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
   2970   def roW : BasePrefetchRO<sz, V, opc, (outs),
   2971                 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
   2972                 asm, [(AArch64Prefetch imm:$Rt,
   2973                                      (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
   2974                                                     ro_Wextend64:$extend))]> {
   2975     let Inst{13} = 0b0;
   2976   }
   2977 
   2978   def roX : BasePrefetchRO<sz, V, opc, (outs),
   2979                 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
   2980                 asm,  [(AArch64Prefetch imm:$Rt,
   2981                                       (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
   2982                                                      ro_Xextend64:$extend))]> {
   2983     let Inst{13} = 0b1;
   2984   }
   2985 
   2986   def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
   2987                (!cast<Instruction>(NAME # "roX") prfop:$Rt,
   2988                                                  GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
   2989 }
   2990 
   2991 //---
   2992 // Load/store unscaled immediate
   2993 //---
   2994 
   2995 def am_unscaled8 :  ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
   2996 def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
   2997 def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
   2998 def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
   2999 def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
   3000 
   3001 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
   3002                            string asm, list<dag> pattern>
   3003     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
   3004   bits<5> Rt;
   3005   bits<5> Rn;
   3006   bits<9> offset;
   3007   let Inst{31-30} = sz;
   3008   let Inst{29-27} = 0b111;
   3009   let Inst{26}    = V;
   3010   let Inst{25-24} = 0b00;
   3011   let Inst{23-22} = opc;
   3012   let Inst{21}    = 0;
   3013   let Inst{20-12} = offset;
   3014   let Inst{11-10} = 0b00;
   3015   let Inst{9-5}   = Rn;
   3016   let Inst{4-0}   = Rt;
   3017 
   3018   let DecoderMethod = "DecodeSignedLdStInstruction";
   3019 }
   3020 
   3021 multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   3022                    string asm, list<dag> pattern> {
   3023   let AddedComplexity = 1 in // try this before LoadUI
   3024   def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
   3025                                (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
   3026           Sched<[WriteLD]>;
   3027 
   3028   def : InstAlias<asm # "\t$Rt, [$Rn]",
   3029                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
   3030 }
   3031 
   3032 multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   3033                          string asm, list<dag> pattern> {
   3034   let AddedComplexity = 1 in // try this before StoreUI
   3035   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
   3036                                (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
   3037                                asm, pattern>,
   3038           Sched<[WriteST]>;
   3039 
   3040   def : InstAlias<asm # "\t$Rt, [$Rn]",
   3041                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
   3042 }
   3043 
   3044 multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
   3045                             list<dag> pat> {
   3046   let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
   3047   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
   3048                                (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
   3049                                asm, pat>,
   3050           Sched<[WriteLD]>;
   3051 
   3052   def : InstAlias<asm # "\t$Rt, [$Rn]",
   3053                   (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
   3054 }
   3055 
   3056 //---
   3057 // Load/store unscaled immediate, unprivileged
   3058 //---
   3059 
   3060 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
   3061                                 dag oops, dag iops, string asm>
   3062     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
   3063   bits<5> Rt;
   3064   bits<5> Rn;
   3065   bits<9> offset;
   3066   let Inst{31-30} = sz;
   3067   let Inst{29-27} = 0b111;
   3068   let Inst{26}    = V;
   3069   let Inst{25-24} = 0b00;
   3070   let Inst{23-22} = opc;
   3071   let Inst{21}    = 0;
   3072   let Inst{20-12} = offset;
   3073   let Inst{11-10} = 0b10;
   3074   let Inst{9-5}   = Rn;
   3075   let Inst{4-0}   = Rt;
   3076 
   3077   let DecoderMethod = "DecodeSignedLdStInstruction";
   3078 }
   3079 
   3080 multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
   3081                             RegisterClass regtype, string asm> {
   3082   let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
   3083   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
   3084                                     (ins GPR64sp:$Rn, simm9:$offset), asm>,
   3085           Sched<[WriteLD]>;
   3086 
   3087   def : InstAlias<asm # "\t$Rt, [$Rn]",
   3088                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
   3089 }
   3090 
   3091 multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
   3092                              RegisterClass regtype, string asm> {
   3093   let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
   3094   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
   3095                                  (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
   3096                                  asm>,
   3097           Sched<[WriteST]>;
   3098 
   3099   def : InstAlias<asm # "\t$Rt, [$Rn]",
   3100                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
   3101 }
   3102 
   3103 //---
   3104 // Load/store pre-indexed
   3105 //---
   3106 
   3107 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
   3108                           string asm, string cstr, list<dag> pat>
   3109     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
   3110   bits<5> Rt;
   3111   bits<5> Rn;
   3112   bits<9> offset;
   3113   let Inst{31-30} = sz;
   3114   let Inst{29-27} = 0b111;
   3115   let Inst{26}    = V;
   3116   let Inst{25-24} = 0;
   3117   let Inst{23-22} = opc;
   3118   let Inst{21}    = 0;
   3119   let Inst{20-12} = offset;
   3120   let Inst{11-10} = 0b11;
   3121   let Inst{9-5}   = Rn;
   3122   let Inst{4-0}   = Rt;
   3123 
   3124   let DecoderMethod = "DecodeSignedLdStInstruction";
   3125 }
   3126 
   3127 let hasSideEffects = 0 in {
   3128 let mayStore = 0, mayLoad = 1 in
   3129 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   3130              string asm>
   3131     : BaseLoadStorePreIdx<sz, V, opc,
   3132                      (outs GPR64sp:$wback, regtype:$Rt),
   3133                      (ins GPR64sp:$Rn, simm9:$offset), asm,
   3134                      "$Rn = $wback,@earlyclobber $wback", []>,
   3135       Sched<[WriteLD, WriteAdr]>;
   3136 
   3137 let mayStore = 1, mayLoad = 0 in
   3138 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   3139                   string asm, SDPatternOperator storeop, ValueType Ty>
   3140     : BaseLoadStorePreIdx<sz, V, opc,
   3141                       (outs GPR64sp:$wback),
   3142                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
   3143                       asm, "$Rn = $wback,@earlyclobber $wback",
   3144       [(set GPR64sp:$wback,
   3145             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
   3146       Sched<[WriteAdr, WriteST]>;
   3147 } // hasSideEffects = 0
   3148 
   3149 //---
   3150 // Load/store post-indexed
   3151 //---
   3152 
   3153 class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
   3154                           string asm, string cstr, list<dag> pat>
   3155     : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
   3156   bits<5> Rt;
   3157   bits<5> Rn;
   3158   bits<9> offset;
   3159   let Inst{31-30} = sz;
   3160   let Inst{29-27} = 0b111;
   3161   let Inst{26}    = V;
   3162   let Inst{25-24} = 0b00;
   3163   let Inst{23-22} = opc;
   3164   let Inst{21}    = 0b0;
   3165   let Inst{20-12} = offset;
   3166   let Inst{11-10} = 0b01;
   3167   let Inst{9-5}   = Rn;
   3168   let Inst{4-0}   = Rt;
   3169 
   3170   let DecoderMethod = "DecodeSignedLdStInstruction";
   3171 }
   3172 
   3173 let hasSideEffects = 0 in {
   3174 let mayStore = 0, mayLoad = 1 in
   3175 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   3176              string asm>
   3177     : BaseLoadStorePostIdx<sz, V, opc,
   3178                       (outs GPR64sp:$wback, regtype:$Rt),
   3179                       (ins GPR64sp:$Rn, simm9:$offset),
   3180                       asm, "$Rn = $wback,@earlyclobber $wback", []>,
   3181       Sched<[WriteLD, WriteI]>;
   3182 
   3183 let mayStore = 1, mayLoad = 0 in
   3184 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
   3185                    string asm, SDPatternOperator storeop, ValueType Ty>
   3186     : BaseLoadStorePostIdx<sz, V, opc,
   3187                       (outs GPR64sp:$wback),
   3188                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
   3189                        asm, "$Rn = $wback,@earlyclobber $wback",
   3190       [(set GPR64sp:$wback,
   3191             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
   3192     Sched<[WriteAdr, WriteST, ReadAdrBase]>;
   3193 } // hasSideEffects = 0
   3194 
   3195 
   3196 //---
   3197 // Load/store pair
   3198 //---
   3199 
   3200 // (indexed, offset)
   3201 
   3202 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
   3203                               string asm>
   3204     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
   3205   bits<5> Rt;
   3206   bits<5> Rt2;
   3207   bits<5> Rn;
   3208   bits<7> offset;
   3209   let Inst{31-30} = opc;
   3210   let Inst{29-27} = 0b101;
   3211   let Inst{26}    = V;
   3212   let Inst{25-23} = 0b010;
   3213   let Inst{22}    = L;
   3214   let Inst{21-15} = offset;
   3215   let Inst{14-10} = Rt2;
   3216   let Inst{9-5}   = Rn;
   3217   let Inst{4-0}   = Rt;
   3218 
   3219   let DecoderMethod = "DecodePairLdStInstruction";
   3220 }
   3221 
   3222 multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype,
   3223                           Operand indextype, string asm> {
   3224   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
   3225   def i : BaseLoadStorePairOffset<opc, V, 1,
   3226                                   (outs regtype:$Rt, regtype:$Rt2),
   3227                                   (ins GPR64sp:$Rn, indextype:$offset), asm>,
   3228           Sched<[WriteLD, WriteLDHi]>;
   3229 
   3230   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
   3231                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
   3232                                                   GPR64sp:$Rn, 0)>;
   3233 }
   3234 
   3235 
   3236 multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype,
   3237                            Operand indextype, string asm> {
   3238   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
   3239   def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
   3240                                   (ins regtype:$Rt, regtype:$Rt2,
   3241                                        GPR64sp:$Rn, indextype:$offset),
   3242                                   asm>,
   3243           Sched<[WriteSTP]>;
   3244 
   3245   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
   3246                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
   3247                                                   GPR64sp:$Rn, 0)>;
   3248 }
   3249 
   3250 // (pre-indexed)
   3251 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
   3252                               string asm>
   3253     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
   3254   bits<5> Rt;
   3255   bits<5> Rt2;
   3256   bits<5> Rn;
   3257   bits<7> offset;
   3258   let Inst{31-30} = opc;
   3259   let Inst{29-27} = 0b101;
   3260   let Inst{26}    = V;
   3261   let Inst{25-23} = 0b011;
   3262   let Inst{22}    = L;
   3263   let Inst{21-15} = offset;
   3264   let Inst{14-10} = Rt2;
   3265   let Inst{9-5}   = Rn;
   3266   let Inst{4-0}   = Rt;
   3267 
   3268   let DecoderMethod = "DecodePairLdStInstruction";
   3269 }
   3270 
   3271 let hasSideEffects = 0 in {
   3272 let mayStore = 0, mayLoad = 1 in
   3273 class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
   3274                      Operand indextype, string asm>
   3275     : BaseLoadStorePairPreIdx<opc, V, 1,
   3276                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
   3277                               (ins GPR64sp:$Rn, indextype:$offset), asm>,
   3278       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
   3279 
   3280 let mayStore = 1, mayLoad = 0 in
   3281 class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
   3282                       Operand indextype, string asm>
   3283     : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
   3284                              (ins regtype:$Rt, regtype:$Rt2,
   3285                                   GPR64sp:$Rn, indextype:$offset),
   3286                              asm>,
   3287       Sched<[WriteAdr, WriteSTP]>;
   3288 } // hasSideEffects = 0
   3289 
   3290 // (post-indexed)
   3291 
   3292 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
   3293                               string asm>
   3294     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
   3295   bits<5> Rt;
   3296   bits<5> Rt2;
   3297   bits<5> Rn;
   3298   bits<7> offset;
   3299   let Inst{31-30} = opc;
   3300   let Inst{29-27} = 0b101;
   3301   let Inst{26}    = V;
   3302   let Inst{25-23} = 0b001;
   3303   let Inst{22}    = L;
   3304   let Inst{21-15} = offset;
   3305   let Inst{14-10} = Rt2;
   3306   let Inst{9-5}   = Rn;
   3307   let Inst{4-0}   = Rt;
   3308 
   3309   let DecoderMethod = "DecodePairLdStInstruction";
   3310 }
   3311 
   3312 let hasSideEffects = 0 in {
   3313 let mayStore = 0, mayLoad = 1 in
   3314 class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
   3315                       Operand idxtype, string asm>
   3316     : BaseLoadStorePairPostIdx<opc, V, 1,
   3317                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
   3318                               (ins GPR64sp:$Rn, idxtype:$offset), asm>,
   3319       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
   3320 
   3321 let mayStore = 1, mayLoad = 0 in
   3322 class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
   3323                        Operand idxtype, string asm>
   3324     : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
   3325                              (ins regtype:$Rt, regtype:$Rt2,
   3326                                   GPR64sp:$Rn, idxtype:$offset),
   3327                              asm>,
   3328       Sched<[WriteAdr, WriteSTP]>;
   3329 } // hasSideEffects = 0
   3330 
   3331 //  (no-allocate)
   3332 
   3333 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
   3334                               string asm>
   3335     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
   3336   bits<5> Rt;
   3337   bits<5> Rt2;
   3338   bits<5> Rn;
   3339   bits<7> offset;
   3340   let Inst{31-30} = opc;
   3341   let Inst{29-27} = 0b101;
   3342   let Inst{26}    = V;
   3343   let Inst{25-23} = 0b000;
   3344   let Inst{22}    = L;
   3345   let Inst{21-15} = offset;
   3346   let Inst{14-10} = Rt2;
   3347   let Inst{9-5}   = Rn;
   3348   let Inst{4-0}   = Rt;
   3349 
   3350   let DecoderMethod = "DecodePairLdStInstruction";
   3351 }
   3352 
   3353 multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
   3354                            Operand indextype, string asm> {
   3355   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
   3356   def i : BaseLoadStorePairNoAlloc<opc, V, 1,
   3357                                    (outs regtype:$Rt, regtype:$Rt2),
   3358                                    (ins GPR64sp:$Rn, indextype:$offset), asm>,
   3359           Sched<[WriteLD, WriteLDHi]>;
   3360 
   3361 
   3362   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
   3363                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
   3364                                                   GPR64sp:$Rn, 0)>;
   3365 }
   3366 
   3367 multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
   3368                       Operand indextype, string asm> {
   3369   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
   3370   def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
   3371                                    (ins regtype:$Rt, regtype:$Rt2,
   3372                                         GPR64sp:$Rn, indextype:$offset),
   3373                                    asm>,
   3374           Sched<[WriteSTP]>;
   3375 
   3376   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
   3377                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
   3378                                                   GPR64sp:$Rn, 0)>;
   3379 }
   3380 
   3381 //---
   3382 // Load/store exclusive
   3383 //---
   3384 
   3385 // True exclusive operations write to and/or read from the system's exclusive
   3386 // monitors, which as far as a compiler is concerned can be modelled as a
   3387 // random shared memory address. Hence LoadExclusive mayStore.
   3388 //
   3389 // Since these instructions have the undefined register bits set to 1 in
   3390 // their canonical form, we need a post encoder method to set those bits
   3391 // to 1 when encoding these instructions. We do this using the
   3392 // fixLoadStoreExclusive function. This function has template parameters:
   3393 //
   3394 // fixLoadStoreExclusive<int hasRs, int hasRt2>
   3395 //
   3396 // hasRs indicates that the instruction uses the Rs field, so we won't set
   3397 // it to 1 (and the same for Rt2). We don't need template parameters for
   3398 // the other register fields since Rt and Rn are always used.
   3399 //
   3400 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
   3401 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3402                              dag oops, dag iops, string asm, string operands>
   3403     : I<oops, iops, asm, operands, "", []> {
   3404   let Inst{31-30} = sz;
   3405   let Inst{29-24} = 0b001000;
   3406   let Inst{23}    = o2;
   3407   let Inst{22}    = L;
   3408   let Inst{21}    = o1;
   3409   let Inst{15}    = o0;
   3410 
   3411   let DecoderMethod = "DecodeExclusiveLdStInstruction";
   3412 }
   3413 
   3414 // Neither Rs nor Rt2 operands.
   3415 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3416                                dag oops, dag iops, string asm, string operands>
   3417     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
   3418   bits<5> Rt;
   3419   bits<5> Rn;
   3420   let Inst{20-16} = 0b11111;
   3421   let Unpredictable{20-16} = 0b11111;
   3422   let Inst{14-10} = 0b11111;
   3423   let Unpredictable{14-10} = 0b11111;
   3424   let Inst{9-5} = Rn;
   3425   let Inst{4-0} = Rt;
   3426 
   3427   let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
   3428 }
   3429 
   3430 // Simple load acquires don't set the exclusive monitor
   3431 let mayLoad = 1, mayStore = 0 in
   3432 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3433                   RegisterClass regtype, string asm>
   3434     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
   3435                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
   3436       Sched<[WriteLD]>;
   3437 
   3438 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3439                     RegisterClass regtype, string asm>
   3440     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
   3441                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
   3442       Sched<[WriteLD]>;
   3443 
   3444 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3445                        RegisterClass regtype, string asm>
   3446     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
   3447                              (outs regtype:$Rt, regtype:$Rt2),
   3448                              (ins GPR64sp0:$Rn), asm,
   3449                              "\t$Rt, $Rt2, [$Rn]">,
   3450       Sched<[WriteLD, WriteLDHi]> {
   3451   bits<5> Rt;
   3452   bits<5> Rt2;
   3453   bits<5> Rn;
   3454   let Inst{14-10} = Rt2;
   3455   let Inst{9-5} = Rn;
   3456   let Inst{4-0} = Rt;
   3457 
   3458   let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
   3459 }
   3460 
   3461 // Simple store release operations do not check the exclusive monitor.
   3462 let mayLoad = 0, mayStore = 1 in
   3463 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3464                    RegisterClass regtype, string asm>
   3465     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
   3466                                (ins regtype:$Rt, GPR64sp0:$Rn),
   3467                                asm, "\t$Rt, [$Rn]">,
   3468       Sched<[WriteST]>;
   3469 
   3470 let mayLoad = 1, mayStore = 1 in
   3471 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3472                      RegisterClass regtype, string asm>
   3473     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
   3474                              (ins regtype:$Rt, GPR64sp0:$Rn),
   3475                              asm, "\t$Ws, $Rt, [$Rn]">,
   3476       Sched<[WriteSTX]> {
   3477   bits<5> Ws;
   3478   bits<5> Rt;
   3479   bits<5> Rn;
   3480   let Inst{20-16} = Ws;
   3481   let Inst{9-5} = Rn;
   3482   let Inst{4-0} = Rt;
   3483 
   3484   let Constraints = "@earlyclobber $Ws";
   3485   let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
   3486 }
   3487 
   3488 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
   3489                          RegisterClass regtype, string asm>
   3490     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
   3491                              (outs GPR32:$Ws),
   3492                              (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
   3493                               asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
   3494       Sched<[WriteSTX]> {
   3495   bits<5> Ws;
   3496   bits<5> Rt;
   3497   bits<5> Rt2;
   3498   bits<5> Rn;
   3499   let Inst{20-16} = Ws;
   3500   let Inst{14-10} = Rt2;
   3501   let Inst{9-5} = Rn;
   3502   let Inst{4-0} = Rt;
   3503 
   3504   let Constraints = "@earlyclobber $Ws";
   3505 }
   3506 
   3507 //---
   3508 // Exception generation
   3509 //---
   3510 
   3511 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
   3512 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
   3513     : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
   3514       Sched<[WriteSys]> {
   3515   bits<16> imm;
   3516   let Inst{31-24} = 0b11010100;
   3517   let Inst{23-21} = op1;
   3518   let Inst{20-5}  = imm;
   3519   let Inst{4-2}   = 0b000;
   3520   let Inst{1-0}   = ll;
   3521 }
   3522 
   3523 let Predicates = [HasFPARMv8] in {
   3524 
   3525 //---
   3526 // Floating point to integer conversion
   3527 //---
   3528 
   3529 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
   3530                       RegisterClass srcType, RegisterClass dstType,
   3531                       string asm, list<dag> pattern>
   3532     : I<(outs dstType:$Rd), (ins srcType:$Rn),
   3533          asm, "\t$Rd, $Rn", "", pattern>,
   3534       Sched<[WriteFCvt]> {
   3535   bits<5> Rd;
   3536   bits<5> Rn;
   3537   let Inst{30-29} = 0b00;
   3538   let Inst{28-24} = 0b11110;
   3539   let Inst{23-22} = type;
   3540   let Inst{21}    = 1;
   3541   let Inst{20-19} = rmode;
   3542   let Inst{18-16} = opcode;
   3543   let Inst{15-10} = 0;
   3544   let Inst{9-5}   = Rn;
   3545   let Inst{4-0}   = Rd;
   3546 }
   3547 
   3548 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   3549 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
   3550                       RegisterClass srcType, RegisterClass dstType,
   3551                       Operand immType, string asm, list<dag> pattern>
   3552     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
   3553          asm, "\t$Rd, $Rn, $scale", "", pattern>,
   3554       Sched<[WriteFCvt]> {
   3555   bits<5> Rd;
   3556   bits<5> Rn;
   3557   bits<6> scale;
   3558   let Inst{30-29} = 0b00;
   3559   let Inst{28-24} = 0b11110;
   3560   let Inst{23-22} = type;
   3561   let Inst{21}    = 0;
   3562   let Inst{20-19} = rmode;
   3563   let Inst{18-16} = opcode;
   3564   let Inst{15-10} = scale;
   3565   let Inst{9-5}   = Rn;
   3566   let Inst{4-0}   = Rd;
   3567 }
   3568 
   3569 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
   3570            SDPatternOperator OpN> {
   3571   // Unscaled half-precision to 32-bit
   3572   def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,
   3573                                      [(set GPR32:$Rd, (OpN FPR16:$Rn))]> {
   3574     let Inst{31} = 0; // 32-bit GPR flag
   3575     let Predicates = [HasFullFP16];
   3576   }
   3577 
   3578   // Unscaled half-precision to 64-bit
   3579   def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,
   3580                                      [(set GPR64:$Rd, (OpN FPR16:$Rn))]> {
   3581     let Inst{31} = 1; // 64-bit GPR flag
   3582     let Predicates = [HasFullFP16];
   3583   }
   3584 
   3585   // Unscaled single-precision to 32-bit
   3586   def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
   3587                                      [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
   3588     let Inst{31} = 0; // 32-bit GPR flag
   3589   }
   3590 
   3591   // Unscaled single-precision to 64-bit
   3592   def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
   3593                                      [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
   3594     let Inst{31} = 1; // 64-bit GPR flag
   3595   }
   3596 
   3597   // Unscaled double-precision to 32-bit
   3598   def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
   3599                                      [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
   3600     let Inst{31} = 0; // 32-bit GPR flag
   3601   }
   3602 
   3603   // Unscaled double-precision to 64-bit
   3604   def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
   3605                                      [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
   3606     let Inst{31} = 1; // 64-bit GPR flag
   3607   }
   3608 }
   3609 
   3610 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
   3611                              SDPatternOperator OpN> {
   3612   // Scaled half-precision to 32-bit
   3613   def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,
   3614                               fixedpoint_f16_i32, asm,
   3615               [(set GPR32:$Rd, (OpN (fmul FPR16:$Rn,
   3616                                           fixedpoint_f16_i32:$scale)))]> {
   3617     let Inst{31} = 0; // 32-bit GPR flag
   3618     let scale{5} = 1;
   3619     let Predicates = [HasFullFP16];
   3620   }
   3621 
   3622   // Scaled half-precision to 64-bit
   3623   def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,
   3624                               fixedpoint_f16_i64, asm,
   3625               [(set GPR64:$Rd, (OpN (fmul FPR16:$Rn,
   3626                                           fixedpoint_f16_i64:$scale)))]> {
   3627     let Inst{31} = 1; // 64-bit GPR flag
   3628     let Predicates = [HasFullFP16];
   3629   }
   3630 
   3631   // Scaled single-precision to 32-bit
   3632   def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
   3633                               fixedpoint_f32_i32, asm,
   3634               [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
   3635                                           fixedpoint_f32_i32:$scale)))]> {
   3636     let Inst{31} = 0; // 32-bit GPR flag
   3637     let scale{5} = 1;
   3638   }
   3639 
   3640   // Scaled single-precision to 64-bit
   3641   def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
   3642                               fixedpoint_f32_i64, asm,
   3643               [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
   3644                                           fixedpoint_f32_i64:$scale)))]> {
   3645     let Inst{31} = 1; // 64-bit GPR flag
   3646   }
   3647 
   3648   // Scaled double-precision to 32-bit
   3649   def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
   3650                               fixedpoint_f64_i32, asm,
   3651               [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
   3652                                           fixedpoint_f64_i32:$scale)))]> {
   3653     let Inst{31} = 0; // 32-bit GPR flag
   3654     let scale{5} = 1;
   3655   }
   3656 
   3657   // Scaled double-precision to 64-bit
   3658   def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
   3659                               fixedpoint_f64_i64, asm,
   3660               [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
   3661                                           fixedpoint_f64_i64:$scale)))]> {
   3662     let Inst{31} = 1; // 64-bit GPR flag
   3663   }
   3664 }
   3665 
   3666 //---
   3667 // Integer to floating point conversion
   3668 //---
   3669 
   3670 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   3671 class BaseIntegerToFP<bit isUnsigned,
   3672                       RegisterClass srcType, RegisterClass dstType,
   3673                       Operand immType, string asm, list<dag> pattern>
   3674     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
   3675          asm, "\t$Rd, $Rn, $scale", "", pattern>,
   3676       Sched<[WriteFCvt]> {
   3677   bits<5> Rd;
   3678   bits<5> Rn;
   3679   bits<6> scale;
   3680   let Inst{30-24} = 0b0011110;
   3681   let Inst{21-17} = 0b00001;
   3682   let Inst{16}    = isUnsigned;
   3683   let Inst{15-10} = scale;
   3684   let Inst{9-5}   = Rn;
   3685   let Inst{4-0}   = Rd;
   3686 }
   3687 
   3688 class BaseIntegerToFPUnscaled<bit isUnsigned,
   3689                       RegisterClass srcType, RegisterClass dstType,
   3690                       ValueType dvt, string asm, SDNode node>
   3691     : I<(outs dstType:$Rd), (ins srcType:$Rn),
   3692          asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
   3693       Sched<[WriteFCvt]> {
   3694   bits<5> Rd;
   3695   bits<5> Rn;
   3696   bits<6> scale;
   3697   let Inst{30-24} = 0b0011110;
   3698   let Inst{21-17} = 0b10001;
   3699   let Inst{16}    = isUnsigned;
   3700   let Inst{15-10} = 0b000000;
   3701   let Inst{9-5}   = Rn;
   3702   let Inst{4-0}   = Rd;
   3703 }
   3704 
   3705 multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
   3706   // Unscaled
   3707   def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> {
   3708     let Inst{31} = 0; // 32-bit GPR flag
   3709     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3710     let Predicates = [HasFullFP16];
   3711   }
   3712 
   3713   def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
   3714     let Inst{31} = 0; // 32-bit GPR flag
   3715     let Inst{23-22} = 0b00; // 32-bit FPR flag
   3716   }
   3717 
   3718   def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
   3719     let Inst{31} = 0; // 32-bit GPR flag
   3720     let Inst{23-22} = 0b01; // 64-bit FPR flag
   3721   }
   3722 
   3723   def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> {
   3724     let Inst{31} = 1; // 64-bit GPR flag
   3725     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3726     let Predicates = [HasFullFP16];
   3727   }
   3728 
   3729   def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
   3730     let Inst{31} = 1; // 64-bit GPR flag
   3731     let Inst{23-22} = 0b00; // 32-bit FPR flag
   3732   }
   3733 
   3734   def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
   3735     let Inst{31} = 1; // 64-bit GPR flag
   3736     let Inst{23-22} = 0b01; // 64-bit FPR flag
   3737   }
   3738 
   3739   // Scaled
   3740   def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm,
   3741                              [(set FPR16:$Rd,
   3742                                    (fdiv (node GPR32:$Rn),
   3743                                          fixedpoint_f16_i32:$scale))]> {
   3744     let Inst{31} = 0; // 32-bit GPR flag
   3745     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3746     let scale{5} = 1;
   3747     let Predicates = [HasFullFP16];
   3748   }
   3749 
   3750   def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
   3751                              [(set FPR32:$Rd,
   3752                                    (fdiv (node GPR32:$Rn),
   3753                                          fixedpoint_f32_i32:$scale))]> {
   3754     let Inst{31} = 0; // 32-bit GPR flag
   3755     let Inst{23-22} = 0b00; // 32-bit FPR flag
   3756     let scale{5} = 1;
   3757   }
   3758 
   3759   def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
   3760                              [(set FPR64:$Rd,
   3761                                    (fdiv (node GPR32:$Rn),
   3762                                          fixedpoint_f64_i32:$scale))]> {
   3763     let Inst{31} = 0; // 32-bit GPR flag
   3764     let Inst{23-22} = 0b01; // 64-bit FPR flag
   3765     let scale{5} = 1;
   3766   }
   3767 
   3768   def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm,
   3769                              [(set FPR16:$Rd,
   3770                                    (fdiv (node GPR64:$Rn),
   3771                                          fixedpoint_f16_i64:$scale))]> {
   3772     let Inst{31} = 1; // 64-bit GPR flag
   3773     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3774     let Predicates = [HasFullFP16];
   3775   }
   3776 
   3777   def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
   3778                              [(set FPR32:$Rd,
   3779                                    (fdiv (node GPR64:$Rn),
   3780                                          fixedpoint_f32_i64:$scale))]> {
   3781     let Inst{31} = 1; // 64-bit GPR flag
   3782     let Inst{23-22} = 0b00; // 32-bit FPR flag
   3783   }
   3784 
   3785   def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
   3786                              [(set FPR64:$Rd,
   3787                                    (fdiv (node GPR64:$Rn),
   3788                                          fixedpoint_f64_i64:$scale))]> {
   3789     let Inst{31} = 1; // 64-bit GPR flag
   3790     let Inst{23-22} = 0b01; // 64-bit FPR flag
   3791   }
   3792 }
   3793 
   3794 //---
   3795 // Unscaled integer <-> floating point conversion (i.e. FMOV)
   3796 //---
   3797 
   3798 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   3799 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
   3800                       RegisterClass srcType, RegisterClass dstType,
   3801                       string asm>
   3802     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
   3803         // We use COPY_TO_REGCLASS for these bitconvert operations.
   3804         // copyPhysReg() expands the resultant COPY instructions after
   3805         // regalloc is done. This gives greater freedom for the allocator
   3806         // and related passes (coalescing, copy propagation, et. al.) to
   3807         // be more effective.
   3808         [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
   3809       Sched<[WriteFCopy]> {
   3810   bits<5> Rd;
   3811   bits<5> Rn;
   3812   let Inst{30-24} = 0b0011110;
   3813   let Inst{21}    = 1;
   3814   let Inst{20-19} = rmode;
   3815   let Inst{18-16} = opcode;
   3816   let Inst{15-10} = 0b000000;
   3817   let Inst{9-5}   = Rn;
   3818   let Inst{4-0}   = Rd;
   3819 }
   3820 
   3821 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   3822 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
   3823                      RegisterClass srcType, RegisterOperand dstType, string asm,
   3824                      string kind>
   3825     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
   3826         "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
   3827       Sched<[WriteFCopy]> {
   3828   bits<5> Rd;
   3829   bits<5> Rn;
   3830   let Inst{30-23} = 0b00111101;
   3831   let Inst{21}    = 1;
   3832   let Inst{20-19} = rmode;
   3833   let Inst{18-16} = opcode;
   3834   let Inst{15-10} = 0b000000;
   3835   let Inst{9-5}   = Rn;
   3836   let Inst{4-0}   = Rd;
   3837 
   3838   let DecoderMethod =  "DecodeFMOVLaneInstruction";
   3839 }
   3840 
   3841 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   3842 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
   3843                      RegisterOperand srcType, RegisterClass dstType, string asm,
   3844                      string kind>
   3845     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
   3846         "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
   3847       Sched<[WriteFCopy]> {
   3848   bits<5> Rd;
   3849   bits<5> Rn;
   3850   let Inst{30-23} = 0b00111101;
   3851   let Inst{21}    = 1;
   3852   let Inst{20-19} = rmode;
   3853   let Inst{18-16} = opcode;
   3854   let Inst{15-10} = 0b000000;
   3855   let Inst{9-5}   = Rn;
   3856   let Inst{4-0}   = Rd;
   3857 
   3858   let DecoderMethod =  "DecodeFMOVLaneInstruction";
   3859 }
   3860 
   3861 
   3862 multiclass UnscaledConversion<string asm> {
   3863   def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {
   3864     let Inst{31} = 0; // 32-bit GPR flag
   3865     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3866     let Predicates = [HasFullFP16];
   3867   }
   3868 
   3869   def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {
   3870     let Inst{31} = 1; // 64-bit GPR flag
   3871     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3872     let Predicates = [HasFullFP16];
   3873   }
   3874 
   3875   def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
   3876     let Inst{31} = 0; // 32-bit GPR flag
   3877     let Inst{23-22} = 0b00; // 32-bit FPR flag
   3878   }
   3879 
   3880   def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
   3881     let Inst{31} = 1; // 64-bit GPR flag
   3882     let Inst{23-22} = 0b01; // 64-bit FPR flag
   3883   }
   3884 
   3885   def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {
   3886     let Inst{31} = 0; // 32-bit GPR flag
   3887     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3888     let Predicates = [HasFullFP16];
   3889   }
   3890 
   3891   def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {
   3892     let Inst{31} = 1; // 64-bit GPR flag
   3893     let Inst{23-22} = 0b11; // 16-bit FPR flag
   3894     let Predicates = [HasFullFP16];
   3895   }
   3896 
   3897   def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
   3898     let Inst{31} = 0; // 32-bit GPR flag
   3899     let Inst{23-22} = 0b00; // 32-bit FPR flag
   3900   }
   3901 
   3902   def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
   3903     let Inst{31} = 1; // 64-bit GPR flag
   3904     let Inst{23-22} = 0b01; // 64-bit FPR flag
   3905   }
   3906 
   3907   def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
   3908                                              asm, ".d"> {
   3909     let Inst{31} = 1;
   3910     let Inst{22} = 0;
   3911   }
   3912 
   3913   def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
   3914                                                asm, ".d"> {
   3915     let Inst{31} = 1;
   3916     let Inst{22} = 0;
   3917   }
   3918 }
   3919 
   3920 //---
   3921 // Floating point conversion
   3922 //---
   3923 
   3924 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
   3925                        RegisterClass srcType, string asm, list<dag> pattern>
   3926     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
   3927       Sched<[WriteFCvt]> {
   3928   bits<5> Rd;
   3929   bits<5> Rn;
   3930   let Inst{31-24} = 0b00011110;
   3931   let Inst{23-22} = type;
   3932   let Inst{21-17} = 0b10001;
   3933   let Inst{16-15} = opcode;
   3934   let Inst{14-10} = 0b10000;
   3935   let Inst{9-5}   = Rn;
   3936   let Inst{4-0}   = Rd;
   3937 }
   3938 
   3939 multiclass FPConversion<string asm> {
   3940   // Double-precision to Half-precision
   3941   def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
   3942                              [(set FPR16:$Rd, (fround FPR64:$Rn))]>;
   3943 
   3944   // Double-precision to Single-precision
   3945   def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
   3946                              [(set FPR32:$Rd, (fround FPR64:$Rn))]>;
   3947 
   3948   // Half-precision to Double-precision
   3949   def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
   3950                              [(set FPR64:$Rd, (fextend FPR16:$Rn))]>;
   3951 
   3952   // Half-precision to Single-precision
   3953   def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
   3954                              [(set FPR32:$Rd, (fextend FPR16:$Rn))]>;
   3955 
   3956   // Single-precision to Double-precision
   3957   def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
   3958                              [(set FPR64:$Rd, (fextend FPR32:$Rn))]>;
   3959 
   3960   // Single-precision to Half-precision
   3961   def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
   3962                              [(set FPR16:$Rd, (fround FPR32:$Rn))]>;
   3963 }
   3964 
   3965 //---
   3966 // Single operand floating point data processing
   3967 //---
   3968 
   3969 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   3970 class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
   3971                               ValueType vt, string asm, SDPatternOperator node>
   3972     : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
   3973          [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
   3974       Sched<[WriteF]> {
   3975   bits<5> Rd;
   3976   bits<5> Rn;
   3977   let Inst{31-24} = 0b00011110;
   3978   let Inst{21-19} = 0b100;
   3979   let Inst{18-15} = opcode;
   3980   let Inst{14-10} = 0b10000;
   3981   let Inst{9-5}   = Rn;
   3982   let Inst{4-0}   = Rd;
   3983 }
   3984 
   3985 multiclass SingleOperandFPData<bits<4> opcode, string asm,
   3986                                SDPatternOperator node = null_frag> {
   3987   def Hr : BaseSingleOperandFPData<opcode, FPR16, f16, asm, node> {
   3988     let Inst{23-22} = 0b11; // 16-bit size flag
   3989     let Predicates = [HasFullFP16];
   3990   }
   3991 
   3992   def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
   3993     let Inst{23-22} = 0b00; // 32-bit size flag
   3994   }
   3995 
   3996   def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
   3997     let Inst{23-22} = 0b01; // 64-bit size flag
   3998   }
   3999 }
   4000 
   4001 //---
   4002 // Two operand floating point data processing
   4003 //---
   4004 
   4005 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4006 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
   4007                            string asm, list<dag> pat>
   4008     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
   4009          asm, "\t$Rd, $Rn, $Rm", "", pat>,
   4010       Sched<[WriteF]> {
   4011   bits<5> Rd;
   4012   bits<5> Rn;
   4013   bits<5> Rm;
   4014   let Inst{31-24} = 0b00011110;
   4015   let Inst{21}    = 1;
   4016   let Inst{20-16} = Rm;
   4017   let Inst{15-12} = opcode;
   4018   let Inst{11-10} = 0b10;
   4019   let Inst{9-5}   = Rn;
   4020   let Inst{4-0}   = Rd;
   4021 }
   4022 
   4023 multiclass TwoOperandFPData<bits<4> opcode, string asm,
   4024                             SDPatternOperator node = null_frag> {
   4025   def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
   4026                          [(set (f16 FPR16:$Rd),
   4027                                (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
   4028     let Inst{23-22} = 0b11; // 16-bit size flag
   4029     let Predicates = [HasFullFP16];
   4030   }
   4031 
   4032   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
   4033                          [(set (f32 FPR32:$Rd),
   4034                                (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
   4035     let Inst{23-22} = 0b00; // 32-bit size flag
   4036   }
   4037 
   4038   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
   4039                          [(set (f64 FPR64:$Rd),
   4040                                (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
   4041     let Inst{23-22} = 0b01; // 64-bit size flag
   4042   }
   4043 }
   4044 
   4045 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
   4046   def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
   4047                   [(set FPR16:$Rd, (fneg (node FPR16:$Rn, (f16 FPR16:$Rm))))]> {
   4048     let Inst{23-22} = 0b11; // 16-bit size flag
   4049     let Predicates = [HasFullFP16];
   4050   }
   4051 
   4052   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
   4053                   [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
   4054     let Inst{23-22} = 0b00; // 32-bit size flag
   4055   }
   4056 
   4057   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
   4058                   [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
   4059     let Inst{23-22} = 0b01; // 64-bit size flag
   4060   }
   4061 }
   4062 
   4063 
   4064 //---
   4065 // Three operand floating point data processing
   4066 //---
   4067 
   4068 class BaseThreeOperandFPData<bit isNegated, bit isSub,
   4069                              RegisterClass regtype, string asm, list<dag> pat>
   4070     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
   4071          asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
   4072       Sched<[WriteFMul]> {
   4073   bits<5> Rd;
   4074   bits<5> Rn;
   4075   bits<5> Rm;
   4076   bits<5> Ra;
   4077   let Inst{31-24} = 0b00011111;
   4078   let Inst{21}    = isNegated;
   4079   let Inst{20-16} = Rm;
   4080   let Inst{15}    = isSub;
   4081   let Inst{14-10} = Ra;
   4082   let Inst{9-5}   = Rn;
   4083   let Inst{4-0}   = Rd;
   4084 }
   4085 
   4086 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
   4087                               SDPatternOperator node> {
   4088   def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,
   4089             [(set FPR16:$Rd,
   4090                   (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {
   4091     let Inst{23-22} = 0b11; // 16-bit size flag
   4092     let Predicates = [HasFullFP16];
   4093   }
   4094 
   4095   def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
   4096             [(set FPR32:$Rd,
   4097                   (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
   4098     let Inst{23-22} = 0b00; // 32-bit size flag
   4099   }
   4100 
   4101   def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
   4102             [(set FPR64:$Rd,
   4103                   (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
   4104     let Inst{23-22} = 0b01; // 64-bit size flag
   4105   }
   4106 }
   4107 
   4108 //---
   4109 // Floating point data comparisons
   4110 //---
   4111 
   4112 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4113 class BaseOneOperandFPComparison<bit signalAllNans,
   4114                                  RegisterClass regtype, string asm,
   4115                                  list<dag> pat>
   4116     : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
   4117       Sched<[WriteFCmp]> {
   4118   bits<5> Rn;
   4119   let Inst{31-24} = 0b00011110;
   4120   let Inst{21}    = 1;
   4121 
   4122   let Inst{15-10} = 0b001000;
   4123   let Inst{9-5}   = Rn;
   4124   let Inst{4}     = signalAllNans;
   4125   let Inst{3-0}   = 0b1000;
   4126 
   4127   // Rm should be 0b00000 canonically, but we need to accept any value.
   4128   let PostEncoderMethod = "fixOneOperandFPComparison";
   4129 }
   4130 
   4131 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4132 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
   4133                                 string asm, list<dag> pat>
   4134     : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
   4135       Sched<[WriteFCmp]> {
   4136   bits<5> Rm;
   4137   bits<5> Rn;
   4138   let Inst{31-24} = 0b00011110;
   4139   let Inst{21}    = 1;
   4140   let Inst{20-16} = Rm;
   4141   let Inst{15-10} = 0b001000;
   4142   let Inst{9-5}   = Rn;
   4143   let Inst{4}     = signalAllNans;
   4144   let Inst{3-0}   = 0b0000;
   4145 }
   4146 
   4147 multiclass FPComparison<bit signalAllNans, string asm,
   4148                         SDPatternOperator OpNode = null_frag> {
   4149   let Defs = [NZCV] in {
   4150   def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
   4151       [(OpNode FPR16:$Rn, (f16 FPR16:$Rm)), (implicit NZCV)]> {
   4152     let Inst{23-22} = 0b11;
   4153     let Predicates = [HasFullFP16];
   4154   }
   4155 
   4156   def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,
   4157       [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> {
   4158     let Inst{23-22} = 0b11;
   4159     let Predicates = [HasFullFP16];
   4160   }
   4161 
   4162   def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
   4163       [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
   4164     let Inst{23-22} = 0b00;
   4165   }
   4166 
   4167   def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
   4168       [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
   4169     let Inst{23-22} = 0b00;
   4170   }
   4171 
   4172   def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
   4173       [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
   4174     let Inst{23-22} = 0b01;
   4175   }
   4176 
   4177   def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
   4178       [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
   4179     let Inst{23-22} = 0b01;
   4180   }
   4181   } // Defs = [NZCV]
   4182 }
   4183 
   4184 //---
   4185 // Floating point conditional comparisons
   4186 //---
   4187 
   4188 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4189 class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
   4190                            string mnemonic, list<dag> pat>
   4191     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
   4192          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
   4193       Sched<[WriteFCmp]> {
   4194   let Uses = [NZCV];
   4195   let Defs = [NZCV];
   4196 
   4197   bits<5> Rn;
   4198   bits<5> Rm;
   4199   bits<4> nzcv;
   4200   bits<4> cond;
   4201 
   4202   let Inst{31-24} = 0b00011110;
   4203   let Inst{21}    = 1;
   4204   let Inst{20-16} = Rm;
   4205   let Inst{15-12} = cond;
   4206   let Inst{11-10} = 0b01;
   4207   let Inst{9-5}   = Rn;
   4208   let Inst{4}     = signalAllNans;
   4209   let Inst{3-0}   = nzcv;
   4210 }
   4211 
   4212 multiclass FPCondComparison<bit signalAllNans, string mnemonic,
   4213                             SDPatternOperator OpNode = null_frag> {
   4214   def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, []> {
   4215     let Inst{23-22} = 0b11;
   4216     let Predicates = [HasFullFP16];
   4217   }
   4218 
   4219   def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
   4220       [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
   4221                           (i32 imm:$cond), NZCV))]> {
   4222     let Inst{23-22} = 0b00;
   4223   }
   4224 
   4225   def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
   4226       [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
   4227                           (i32 imm:$cond), NZCV))]> {
   4228     let Inst{23-22} = 0b01;
   4229   }
   4230 }
   4231 
   4232 //---
   4233 // Floating point conditional select
   4234 //---
   4235 
   4236 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
   4237     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
   4238          asm, "\t$Rd, $Rn, $Rm, $cond", "",
   4239          [(set regtype:$Rd,
   4240                (AArch64csel (vt regtype:$Rn), regtype:$Rm,
   4241                           (i32 imm:$cond), NZCV))]>,
   4242       Sched<[WriteF]> {
   4243   bits<5> Rd;
   4244   bits<5> Rn;
   4245   bits<5> Rm;
   4246   bits<4> cond;
   4247 
   4248   let Inst{31-24} = 0b00011110;
   4249   let Inst{21}    = 1;
   4250   let Inst{20-16} = Rm;
   4251   let Inst{15-12} = cond;
   4252   let Inst{11-10} = 0b11;
   4253   let Inst{9-5}   = Rn;
   4254   let Inst{4-0}   = Rd;
   4255 }
   4256 
   4257 multiclass FPCondSelect<string asm> {
   4258   let Uses = [NZCV] in {
   4259   def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
   4260     let Inst{23-22} = 0b11;
   4261     let Predicates = [HasFullFP16];
   4262   }
   4263 
   4264   def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
   4265     let Inst{23-22} = 0b00;
   4266   }
   4267 
   4268   def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
   4269     let Inst{23-22} = 0b01;
   4270   }
   4271   } // Uses = [NZCV]
   4272 }
   4273 
   4274 //---
   4275 // Floating move immediate
   4276 //---
   4277 
   4278 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
   4279   : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
   4280       [(set regtype:$Rd, fpimmtype:$imm)]>,
   4281     Sched<[WriteFImm]> {
   4282   bits<5> Rd;
   4283   bits<8> imm;
   4284   let Inst{31-24} = 0b00011110;
   4285   let Inst{21}    = 1;
   4286   let Inst{20-13} = imm;
   4287   let Inst{12-5}  = 0b10000000;
   4288   let Inst{4-0}   = Rd;
   4289 }
   4290 
   4291 multiclass FPMoveImmediate<string asm> {
   4292   def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
   4293     let Inst{23-22} = 0b11;
   4294     let Predicates = [HasFullFP16];
   4295   }
   4296 
   4297   def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
   4298     let Inst{23-22} = 0b00;
   4299   }
   4300 
   4301   def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
   4302     let Inst{23-22} = 0b01;
   4303   }
   4304 }
   4305 } // end of 'let Predicates = [HasFPARMv8]'
   4306 
   4307 //----------------------------------------------------------------------------
   4308 // AdvSIMD
   4309 //----------------------------------------------------------------------------
   4310 
   4311 let Predicates = [HasNEON] in {
   4312 
   4313 //----------------------------------------------------------------------------
   4314 // AdvSIMD three register vector instructions
   4315 //----------------------------------------------------------------------------
   4316 
   4317 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4318 class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,
   4319                         RegisterOperand regtype, string asm, string kind,
   4320                         list<dag> pattern>
   4321   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
   4322       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
   4323       "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
   4324     Sched<[WriteV]> {
   4325   bits<5> Rd;
   4326   bits<5> Rn;
   4327   bits<5> Rm;
   4328   let Inst{31}    = 0;
   4329   let Inst{30}    = Q;
   4330   let Inst{29}    = U;
   4331   let Inst{28-24} = 0b01110;
   4332   let Inst{23-21} = size;
   4333   let Inst{20-16} = Rm;
   4334   let Inst{15-11} = opcode;
   4335   let Inst{10}    = 1;
   4336   let Inst{9-5}   = Rn;
   4337   let Inst{4-0}   = Rd;
   4338 }
   4339 
   4340 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4341 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,
   4342                         RegisterOperand regtype, string asm, string kind,
   4343                         list<dag> pattern>
   4344   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
   4345       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
   4346       "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
   4347     Sched<[WriteV]> {
   4348   bits<5> Rd;
   4349   bits<5> Rn;
   4350   bits<5> Rm;
   4351   let Inst{31}    = 0;
   4352   let Inst{30}    = Q;
   4353   let Inst{29}    = U;
   4354   let Inst{28-24} = 0b01110;
   4355   let Inst{23-21} = size;
   4356   let Inst{20-16} = Rm;
   4357   let Inst{15-11} = opcode;
   4358   let Inst{10}    = 1;
   4359   let Inst{9-5}   = Rn;
   4360   let Inst{4-0}   = Rd;
   4361 }
   4362 
   4363 // All operand sizes distinguished in the encoding.
   4364 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
   4365                                SDPatternOperator OpNode> {
   4366   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
   4367                                       asm, ".8b",
   4368          [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
   4369   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
   4370                                       asm, ".16b",
   4371          [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
   4372   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
   4373                                       asm, ".4h",
   4374          [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
   4375   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
   4376                                       asm, ".8h",
   4377          [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
   4378   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
   4379                                       asm, ".2s",
   4380          [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
   4381   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
   4382                                       asm, ".4s",
   4383          [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
   4384   def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
   4385                                       asm, ".2d",
   4386          [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
   4387 }
   4388 
   4389 // As above, but D sized elements unsupported.
   4390 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
   4391                                   SDPatternOperator OpNode> {
   4392   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
   4393                                       asm, ".8b",
   4394         [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
   4395   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
   4396                                       asm, ".16b",
   4397         [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
   4398   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
   4399                                       asm, ".4h",
   4400         [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
   4401   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
   4402                                       asm, ".8h",
   4403         [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
   4404   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
   4405                                       asm, ".2s",
   4406         [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
   4407   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
   4408                                       asm, ".4s",
   4409         [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
   4410 }
   4411 
   4412 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
   4413                                   SDPatternOperator OpNode> {
   4414   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,
   4415                                       asm, ".8b",
   4416       [(set (v8i8 V64:$dst),
   4417             (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
   4418   def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,
   4419                                       asm, ".16b",
   4420       [(set (v16i8 V128:$dst),
   4421             (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
   4422   def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,
   4423                                       asm, ".4h",
   4424       [(set (v4i16 V64:$dst),
   4425             (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
   4426   def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,
   4427                                       asm, ".8h",
   4428       [(set (v8i16 V128:$dst),
   4429             (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
   4430   def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,
   4431                                       asm, ".2s",
   4432       [(set (v2i32 V64:$dst),
   4433             (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
   4434   def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,
   4435                                       asm, ".4s",
   4436       [(set (v4i32 V128:$dst),
   4437             (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
   4438 }
   4439 
   4440 // As above, but only B sized elements supported.
   4441 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
   4442                                 SDPatternOperator OpNode> {
   4443   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
   4444                                       asm, ".8b",
   4445     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
   4446   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
   4447                                       asm, ".16b",
   4448     [(set (v16i8 V128:$Rd),
   4449           (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
   4450 }
   4451 
   4452 // As above, but only floating point elements supported.
   4453 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,
   4454                                  string asm, SDPatternOperator OpNode> {
   4455   let Predicates = [HasNEON, HasFullFP16] in {
   4456   def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
   4457                                       asm, ".4h",
   4458         [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
   4459   def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
   4460                                       asm, ".8h",
   4461         [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
   4462   } // Predicates = [HasNEON, HasFullFP16]
   4463   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
   4464                                       asm, ".2s",
   4465         [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
   4466   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
   4467                                       asm, ".4s",
   4468         [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
   4469   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
   4470                                       asm, ".2d",
   4471         [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
   4472 }
   4473 
   4474 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,
   4475                                     string asm,
   4476                                     SDPatternOperator OpNode> {
   4477   let Predicates = [HasNEON, HasFullFP16] in {
   4478   def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
   4479                                       asm, ".4h",
   4480         [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
   4481   def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
   4482                                       asm, ".8h",
   4483         [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
   4484   } // Predicates = [HasNEON, HasFullFP16]
   4485   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
   4486                                       asm, ".2s",
   4487         [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
   4488   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
   4489                                       asm, ".4s",
   4490         [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
   4491   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
   4492                                       asm, ".2d",
   4493         [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
   4494 }
   4495 
   4496 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,
   4497                                  string asm, SDPatternOperator OpNode> {
   4498   let Predicates = [HasNEON, HasFullFP16] in {
   4499   def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,
   4500                                       asm, ".4h",
   4501      [(set (v4f16 V64:$dst),
   4502            (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
   4503   def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,
   4504                                       asm, ".8h",
   4505      [(set (v8f16 V128:$dst),
   4506            (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
   4507   } // Predicates = [HasNEON, HasFullFP16]
   4508   def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,
   4509                                       asm, ".2s",
   4510      [(set (v2f32 V64:$dst),
   4511            (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
   4512   def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,
   4513                                       asm, ".4s",
   4514      [(set (v4f32 V128:$dst),
   4515            (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
   4516   def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,
   4517                                       asm, ".2d",
   4518      [(set (v2f64 V128:$dst),
   4519            (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
   4520 }
   4521 
   4522 // As above, but D and B sized elements unsupported.
   4523 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
   4524                                 SDPatternOperator OpNode> {
   4525   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
   4526                                       asm, ".4h",
   4527         [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
   4528   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
   4529                                       asm, ".8h",
   4530         [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
   4531   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
   4532                                       asm, ".2s",
   4533         [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
   4534   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
   4535                                       asm, ".4s",
   4536         [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
   4537 }
   4538 
   4539 // Logical three vector ops share opcode bits, and only use B sized elements.
   4540 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
   4541                                   SDPatternOperator OpNode = null_frag> {
   4542   def v8i8  : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,
   4543                                      asm, ".8b",
   4544                          [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
   4545   def v16i8  : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
   4546                                      asm, ".16b",
   4547                          [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
   4548 
   4549   def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
   4550           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
   4551   def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
   4552           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
   4553   def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
   4554           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
   4555 
   4556   def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
   4557       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
   4558   def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
   4559       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
   4560   def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
   4561       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
   4562 }
   4563 
   4564 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
   4565                                   string asm, SDPatternOperator OpNode> {
   4566   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,
   4567                                      asm, ".8b",
   4568              [(set (v8i8 V64:$dst),
   4569                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
   4570   def v16i8  : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,
   4571                                      asm, ".16b",
   4572              [(set (v16i8 V128:$dst),
   4573                    (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
   4574                            (v16i8 V128:$Rm)))]>;
   4575 
   4576   def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
   4577                            (v4i16 V64:$RHS))),
   4578           (!cast<Instruction>(NAME#"v8i8")
   4579             V64:$LHS, V64:$MHS, V64:$RHS)>;
   4580   def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
   4581                            (v2i32 V64:$RHS))),
   4582           (!cast<Instruction>(NAME#"v8i8")
   4583             V64:$LHS, V64:$MHS, V64:$RHS)>;
   4584   def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
   4585                            (v1i64 V64:$RHS))),
   4586           (!cast<Instruction>(NAME#"v8i8")
   4587             V64:$LHS, V64:$MHS, V64:$RHS)>;
   4588 
   4589   def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
   4590                            (v8i16 V128:$RHS))),
   4591       (!cast<Instruction>(NAME#"v16i8")
   4592         V128:$LHS, V128:$MHS, V128:$RHS)>;
   4593   def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
   4594                            (v4i32 V128:$RHS))),
   4595       (!cast<Instruction>(NAME#"v16i8")
   4596         V128:$LHS, V128:$MHS, V128:$RHS)>;
   4597   def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
   4598                            (v2i64 V128:$RHS))),
   4599       (!cast<Instruction>(NAME#"v16i8")
   4600         V128:$LHS, V128:$MHS, V128:$RHS)>;
   4601 }
   4602 
   4603 
   4604 //----------------------------------------------------------------------------
   4605 // AdvSIMD two register vector instructions.
   4606 //----------------------------------------------------------------------------
   4607 
   4608 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4609 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
   4610                             bits<2> size2, RegisterOperand regtype, string asm,
   4611                             string dstkind, string srckind, list<dag> pattern>
   4612   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
   4613       "{\t$Rd" # dstkind # ", $Rn" # srckind #
   4614       "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
   4615     Sched<[WriteV]> {
   4616   bits<5> Rd;
   4617   bits<5> Rn;
   4618   let Inst{31}    = 0;
   4619   let Inst{30}    = Q;
   4620   let Inst{29}    = U;
   4621   let Inst{28-24} = 0b01110;
   4622   let Inst{23-22} = size;
   4623   let Inst{21} = 0b1;
   4624   let Inst{20-19} = size2;
   4625   let Inst{18-17} = 0b00;
   4626   let Inst{16-12} = opcode;
   4627   let Inst{11-10} = 0b10;
   4628   let Inst{9-5}   = Rn;
   4629   let Inst{4-0}   = Rd;
   4630 }
   4631 
   4632 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   4633 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
   4634                                 bits<2> size2, RegisterOperand regtype,
   4635                                 string asm, string dstkind, string srckind,
   4636                                 list<dag> pattern>
   4637   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
   4638       "{\t$Rd" # dstkind # ", $Rn" # srckind #
   4639       "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
   4640     Sched<[WriteV]> {
   4641   bits<5> Rd;
   4642   bits<5> Rn;
   4643   let Inst{31}    = 0;
   4644   let Inst{30}    = Q;
   4645   let Inst{29}    = U;
   4646   let Inst{28-24} = 0b01110;
   4647   let Inst{23-22} = size;
   4648   let Inst{21} = 0b1;
   4649   let Inst{20-19} = size2;
   4650   let Inst{18-17} = 0b00;
   4651   let Inst{16-12} = opcode;
   4652   let Inst{11-10} = 0b10;
   4653   let Inst{9-5}   = Rn;
   4654   let Inst{4-0}   = Rd;
   4655 }
   4656 
   4657 // Supports B, H, and S element sizes.
   4658 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
   4659                             SDPatternOperator OpNode> {
   4660   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
   4661                                       asm, ".8b", ".8b",
   4662                           [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
   4663   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
   4664                                       asm, ".16b", ".16b",
   4665                           [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
   4666   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
   4667                                       asm, ".4h", ".4h",
   4668                           [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
   4669   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
   4670                                       asm, ".8h", ".8h",
   4671                           [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
   4672   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
   4673                                       asm, ".2s", ".2s",
   4674                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
   4675   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
   4676                                       asm, ".4s", ".4s",
   4677                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
   4678 }
   4679 
   4680 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
   4681                             RegisterOperand regtype, string asm, string dstkind,
   4682                             string srckind, string amount>
   4683   : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
   4684       "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
   4685       "|" # dstkind # "\t$Rd, $Rn, #" #  amount # "}", "", []>,
   4686     Sched<[WriteV]> {
   4687   bits<5> Rd;
   4688   bits<5> Rn;
   4689   let Inst{31}    = 0;
   4690   let Inst{30}    = Q;
   4691   let Inst{29-24} = 0b101110;
   4692   let Inst{23-22} = size;
   4693   let Inst{21-10} = 0b100001001110;
   4694   let Inst{9-5}   = Rn;
   4695   let Inst{4-0}   = Rd;
   4696 }
   4697 
   4698 multiclass SIMDVectorLShiftLongBySizeBHS {
   4699   let hasSideEffects = 0 in {
   4700   def v8i8  : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
   4701                                              "shll", ".8h",  ".8b", "8">;
   4702   def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
   4703                                              "shll2", ".8h", ".16b", "8">;
   4704   def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
   4705                                              "shll", ".4s",  ".4h", "16">;
   4706   def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
   4707                                              "shll2", ".4s", ".8h", "16">;
   4708   def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
   4709                                              "shll", ".2d",  ".2s", "32">;
   4710   def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
   4711                                              "shll2", ".2d", ".4s", "32">;
   4712   }
   4713 }
   4714 
   4715 // Supports all element sizes.
   4716 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
   4717                              SDPatternOperator OpNode> {
   4718   def v8i8_v4i16  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
   4719                                       asm, ".4h", ".8b",
   4720                [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
   4721   def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
   4722                                       asm, ".8h", ".16b",
   4723                [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
   4724   def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
   4725                                       asm, ".2s", ".4h",
   4726                [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
   4727   def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
   4728                                       asm, ".4s", ".8h",
   4729                [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
   4730   def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
   4731                                       asm, ".1d", ".2s",
   4732                [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
   4733   def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
   4734                                       asm, ".2d", ".4s",
   4735                [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
   4736 }
   4737 
   4738 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
   4739                                  SDPatternOperator OpNode> {
   4740   def v8i8_v4i16  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
   4741                                           asm, ".4h", ".8b",
   4742       [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
   4743                                       (v8i8 V64:$Rn)))]>;
   4744   def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
   4745                                           asm, ".8h", ".16b",
   4746       [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
   4747                                       (v16i8 V128:$Rn)))]>;
   4748   def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
   4749                                           asm, ".2s", ".4h",
   4750       [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
   4751                                       (v4i16 V64:$Rn)))]>;
   4752   def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
   4753                                           asm, ".4s", ".8h",
   4754       [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
   4755                                       (v8i16 V128:$Rn)))]>;
   4756   def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
   4757                                           asm, ".1d", ".2s",
   4758       [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
   4759                                       (v2i32 V64:$Rn)))]>;
   4760   def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
   4761                                           asm, ".2d", ".4s",
   4762       [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
   4763                                       (v4i32 V128:$Rn)))]>;
   4764 }
   4765 
   4766 // Supports all element sizes, except 1xD.
   4767 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
   4768                                   SDPatternOperator OpNode> {
   4769   def v8i8  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
   4770                                     asm, ".8b", ".8b",
   4771     [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
   4772   def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
   4773                                     asm, ".16b", ".16b",
   4774     [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
   4775   def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
   4776                                     asm, ".4h", ".4h",
   4777     [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
   4778   def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
   4779                                     asm, ".8h", ".8h",
   4780     [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
   4781   def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
   4782                                     asm, ".2s", ".2s",
   4783     [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
   4784   def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
   4785                                     asm, ".4s", ".4s",
   4786     [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
   4787   def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
   4788                                     asm, ".2d", ".2d",
   4789     [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
   4790 }
   4791 
   4792 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
   4793                              SDPatternOperator OpNode = null_frag> {
   4794   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
   4795                                 asm, ".8b", ".8b",
   4796     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
   4797   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
   4798                                 asm, ".16b", ".16b",
   4799     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
   4800   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
   4801                                 asm, ".4h", ".4h",
   4802     [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
   4803   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
   4804                                 asm, ".8h", ".8h",
   4805     [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
   4806   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
   4807                                 asm, ".2s", ".2s",
   4808     [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
   4809   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
   4810                                 asm, ".4s", ".4s",
   4811     [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
   4812   def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
   4813                                 asm, ".2d", ".2d",
   4814     [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
   4815 }
   4816 
   4817 
   4818 // Supports only B element sizes.
   4819 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
   4820                           SDPatternOperator OpNode> {
   4821   def v8i8  : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,
   4822                                 asm, ".8b", ".8b",
   4823                     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
   4824   def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,
   4825                                 asm, ".16b", ".16b",
   4826                     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
   4827 
   4828 }
   4829 
   4830 // Supports only B and H element sizes.
   4831 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
   4832                                 SDPatternOperator OpNode> {
   4833   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
   4834                                 asm, ".8b", ".8b",
   4835                     [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
   4836   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
   4837                                 asm, ".16b", ".16b",
   4838                     [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
   4839   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
   4840                                 asm, ".4h", ".4h",
   4841                     [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
   4842   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
   4843                                 asm, ".8h", ".8h",
   4844                     [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
   4845 }
   4846 
   4847 // Supports only S and D element sizes, uses high bit of the size field
   4848 // as an extra opcode bit.
   4849 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
   4850                            SDPatternOperator OpNode> {
   4851   let Predicates = [HasNEON, HasFullFP16] in {
   4852   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
   4853                                 asm, ".4h", ".4h",
   4854                           [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
   4855   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
   4856                                 asm, ".8h", ".8h",
   4857                           [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
   4858   } // Predicates = [HasNEON, HasFullFP16]
   4859   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
   4860                                 asm, ".2s", ".2s",
   4861                           [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
   4862   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
   4863                                 asm, ".4s", ".4s",
   4864                           [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
   4865   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
   4866                                 asm, ".2d", ".2d",
   4867                           [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
   4868 }
   4869 
   4870 // Supports only S element size.
   4871 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
   4872                            SDPatternOperator OpNode> {
   4873   def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
   4874                                 asm, ".2s", ".2s",
   4875                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
   4876   def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
   4877                                 asm, ".4s", ".4s",
   4878                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
   4879 }
   4880 
   4881 
   4882 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
   4883                            SDPatternOperator OpNode> {
   4884   let Predicates = [HasNEON, HasFullFP16] in {
   4885   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
   4886                                 asm, ".4h", ".4h",
   4887                           [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
   4888   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
   4889                                 asm, ".8h", ".8h",
   4890                           [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
   4891   } // Predicates = [HasNEON, HasFullFP16]
   4892   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
   4893                                 asm, ".2s", ".2s",
   4894                           [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
   4895   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
   4896                                 asm, ".4s", ".4s",
   4897                           [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
   4898   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
   4899                                 asm, ".2d", ".2d",
   4900                           [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
   4901 }
   4902 
   4903 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
   4904                            SDPatternOperator OpNode> {
   4905   let Predicates = [HasNEON, HasFullFP16] in {
   4906   def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
   4907                                 asm, ".4h", ".4h",
   4908                           [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
   4909   def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
   4910                                 asm, ".8h", ".8h",
   4911                           [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
   4912   } // Predicates = [HasNEON, HasFullFP16]
   4913   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
   4914                                 asm, ".2s", ".2s",
   4915                           [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
   4916   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
   4917                                 asm, ".4s", ".4s",
   4918                           [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
   4919   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
   4920                                 asm, ".2d", ".2d",
   4921                           [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
   4922 }
   4923 
   4924 
   4925 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
   4926                            RegisterOperand inreg, RegisterOperand outreg,
   4927                            string asm, string outkind, string inkind,
   4928                            list<dag> pattern>
   4929   : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
   4930       "{\t$Rd" # outkind # ", $Rn" # inkind #
   4931       "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
   4932     Sched<[WriteV]> {
   4933   bits<5> Rd;
   4934   bits<5> Rn;
   4935   let Inst{31}    = 0;
   4936   let Inst{30}    = Q;
   4937   let Inst{29}    = U;
   4938   let Inst{28-24} = 0b01110;
   4939   let Inst{23-22} = size;
   4940   let Inst{21-17} = 0b10000;
   4941   let Inst{16-12} = opcode;
   4942   let Inst{11-10} = 0b10;
   4943   let Inst{9-5}   = Rn;
   4944   let Inst{4-0}   = Rd;
   4945 }
   4946 
   4947 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
   4948                            RegisterOperand inreg, RegisterOperand outreg,
   4949                            string asm, string outkind, string inkind,
   4950                            list<dag> pattern>
   4951   : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
   4952       "{\t$Rd" # outkind # ", $Rn" # inkind #
   4953       "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
   4954     Sched<[WriteV]> {
   4955   bits<5> Rd;
   4956   bits<5> Rn;
   4957   let Inst{31}    = 0;
   4958   let Inst{30}    = Q;
   4959   let Inst{29}    = U;
   4960   let Inst{28-24} = 0b01110;
   4961   let Inst{23-22} = size;
   4962   let Inst{21-17} = 0b10000;
   4963   let Inst{16-12} = opcode;
   4964   let Inst{11-10} = 0b10;
   4965   let Inst{9-5}   = Rn;
   4966   let Inst{4-0}   = Rd;
   4967 }
   4968 
   4969 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
   4970                               SDPatternOperator OpNode> {
   4971   def v8i8  : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
   4972                                       asm, ".8b", ".8h",
   4973         [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
   4974   def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
   4975                                       asm#"2", ".16b", ".8h", []>;
   4976   def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
   4977                                       asm, ".4h", ".4s",
   4978         [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
   4979   def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
   4980                                       asm#"2", ".8h", ".4s", []>;
   4981   def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
   4982                                       asm, ".2s", ".2d",
   4983         [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
   4984   def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
   4985                                       asm#"2", ".4s", ".2d", []>;
   4986 
   4987   def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
   4988             (!cast<Instruction>(NAME # "v16i8")
   4989                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
   4990   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
   4991             (!cast<Instruction>(NAME # "v8i16")
   4992                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
   4993   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
   4994             (!cast<Instruction>(NAME # "v4i32")
   4995                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
   4996 }
   4997 
   4998 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,
   4999                            bits<5> opcode, RegisterOperand regtype, string asm,
   5000                            string kind, string zero, ValueType dty,
   5001                            ValueType sty, SDNode OpNode>
   5002   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
   5003       "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
   5004       "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
   5005       [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
   5006     Sched<[WriteV]> {
   5007   bits<5> Rd;
   5008   bits<5> Rn;
   5009   let Inst{31}    = 0;
   5010   let Inst{30}    = Q;
   5011   let Inst{29}    = U;
   5012   let Inst{28-24} = 0b01110;
   5013   let Inst{23-22} = size;
   5014   let Inst{21} = 0b1;
   5015   let Inst{20-19} = size2;
   5016   let Inst{18-17} = 0b00;
   5017   let Inst{16-12} = opcode;
   5018   let Inst{11-10} = 0b10;
   5019   let Inst{9-5}   = Rn;
   5020   let Inst{4-0}   = Rd;
   5021 }
   5022 
   5023 // Comparisons support all element sizes, except 1xD.
   5024 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
   5025                             SDNode OpNode> {
   5026   def v8i8rz  : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
   5027                                      asm, ".8b", "0",
   5028                                      v8i8, v8i8, OpNode>;
   5029   def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
   5030                                      asm, ".16b", "0",
   5031                                      v16i8, v16i8, OpNode>;
   5032   def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
   5033                                      asm, ".4h", "0",
   5034                                      v4i16, v4i16, OpNode>;
   5035   def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
   5036                                      asm, ".8h", "0",
   5037                                      v8i16, v8i16, OpNode>;
   5038   def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
   5039                                      asm, ".2s", "0",
   5040                                      v2i32, v2i32, OpNode>;
   5041   def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
   5042                                      asm, ".4s", "0",
   5043                                      v4i32, v4i32, OpNode>;
   5044   def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
   5045                                      asm, ".2d", "0",
   5046                                      v2i64, v2i64, OpNode>;
   5047 }
   5048 
   5049 // FP Comparisons support only S and D element sizes (and H for v8.2a).
   5050 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
   5051                               string asm, SDNode OpNode> {
   5052 
   5053   let Predicates = [HasNEON, HasFullFP16] in {
   5054   def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,
   5055                                      asm, ".4h", "0.0",
   5056                                      v4i16, v4f16, OpNode>;
   5057   def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
   5058                                      asm, ".8h", "0.0",
   5059                                      v8i16, v8f16, OpNode>;
   5060   } // Predicates = [HasNEON, HasFullFP16]
   5061   def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
   5062                                      asm, ".2s", "0.0",
   5063                                      v2i32, v2f32, OpNode>;
   5064   def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
   5065                                      asm, ".4s", "0.0",
   5066                                      v4i32, v4f32, OpNode>;
   5067   def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
   5068                                      asm, ".2d", "0.0",
   5069                                      v2i64, v2f64, OpNode>;
   5070 
   5071   let Predicates = [HasNEON, HasFullFP16] in {
   5072   def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",
   5073                   (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
   5074   def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",
   5075                   (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
   5076   }
   5077   def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
   5078                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
   5079   def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
   5080                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
   5081   def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
   5082                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
   5083   let Predicates = [HasNEON, HasFullFP16] in {
   5084   def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",
   5085                   (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
   5086   def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",
   5087                   (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
   5088   }
   5089   def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
   5090                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
   5091   def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
   5092                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
   5093   def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
   5094                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
   5095 }
   5096 
   5097 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5098 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
   5099                              RegisterOperand outtype, RegisterOperand intype,
   5100                              string asm, string VdTy, string VnTy,
   5101                              list<dag> pattern>
   5102   : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
   5103       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
   5104     Sched<[WriteV]> {
   5105   bits<5> Rd;
   5106   bits<5> Rn;
   5107   let Inst{31}    = 0;
   5108   let Inst{30}    = Q;
   5109   let Inst{29}    = U;
   5110   let Inst{28-24} = 0b01110;
   5111   let Inst{23-22} = size;
   5112   let Inst{21-17} = 0b10000;
   5113   let Inst{16-12} = opcode;
   5114   let Inst{11-10} = 0b10;
   5115   let Inst{9-5}   = Rn;
   5116   let Inst{4-0}   = Rd;
   5117 }
   5118 
   5119 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
   5120                              RegisterOperand outtype, RegisterOperand intype,
   5121                              string asm, string VdTy, string VnTy,
   5122                              list<dag> pattern>
   5123   : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
   5124       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
   5125     Sched<[WriteV]> {
   5126   bits<5> Rd;
   5127   bits<5> Rn;
   5128   let Inst{31}    = 0;
   5129   let Inst{30}    = Q;
   5130   let Inst{29}    = U;
   5131   let Inst{28-24} = 0b01110;
   5132   let Inst{23-22} = size;
   5133   let Inst{21-17} = 0b10000;
   5134   let Inst{16-12} = opcode;
   5135   let Inst{11-10} = 0b10;
   5136   let Inst{9-5}   = Rn;
   5137   let Inst{4-0}   = Rd;
   5138 }
   5139 
   5140 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
   5141   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
   5142                                     asm, ".4s", ".4h", []>;
   5143   def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
   5144                                     asm#"2", ".4s", ".8h", []>;
   5145   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
   5146                                     asm, ".2d", ".2s", []>;
   5147   def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
   5148                                     asm#"2", ".2d", ".4s", []>;
   5149 }
   5150 
   5151 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
   5152   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
   5153                                     asm, ".4h", ".4s", []>;
   5154   def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
   5155                                     asm#"2", ".8h", ".4s", []>;
   5156   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
   5157                                     asm, ".2s", ".2d", []>;
   5158   def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
   5159                                     asm#"2", ".4s", ".2d", []>;
   5160 }
   5161 
   5162 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
   5163                                      Intrinsic OpNode> {
   5164   def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
   5165                                      asm, ".2s", ".2d",
   5166                           [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
   5167   def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
   5168                                     asm#"2", ".4s", ".2d", []>;
   5169 
   5170   def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
   5171             (!cast<Instruction>(NAME # "v4f32")
   5172                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
   5173 }
   5174 
   5175 //----------------------------------------------------------------------------
   5176 // AdvSIMD three register different-size vector instructions.
   5177 //----------------------------------------------------------------------------
   5178 
   5179 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5180 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
   5181                       RegisterOperand outtype, RegisterOperand intype1,
   5182                       RegisterOperand intype2, string asm,
   5183                       string outkind, string inkind1, string inkind2,
   5184                       list<dag> pattern>
   5185   : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
   5186       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
   5187       "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
   5188     Sched<[WriteV]> {
   5189   bits<5> Rd;
   5190   bits<5> Rn;
   5191   bits<5> Rm;
   5192   let Inst{31}    = 0;
   5193   let Inst{30}    = size{0};
   5194   let Inst{29}    = U;
   5195   let Inst{28-24} = 0b01110;
   5196   let Inst{23-22} = size{2-1};
   5197   let Inst{21}    = 1;
   5198   let Inst{20-16} = Rm;
   5199   let Inst{15-12} = opcode;
   5200   let Inst{11-10} = 0b00;
   5201   let Inst{9-5}   = Rn;
   5202   let Inst{4-0}   = Rd;
   5203 }
   5204 
   5205 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5206 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
   5207                       RegisterOperand outtype, RegisterOperand intype1,
   5208                       RegisterOperand intype2, string asm,
   5209                       string outkind, string inkind1, string inkind2,
   5210                       list<dag> pattern>
   5211   : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
   5212       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
   5213       "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
   5214     Sched<[WriteV]> {
   5215   bits<5> Rd;
   5216   bits<5> Rn;
   5217   bits<5> Rm;
   5218   let Inst{31}    = 0;
   5219   let Inst{30}    = size{0};
   5220   let Inst{29}    = U;
   5221   let Inst{28-24} = 0b01110;
   5222   let Inst{23-22} = size{2-1};
   5223   let Inst{21}    = 1;
   5224   let Inst{20-16} = Rm;
   5225   let Inst{15-12} = opcode;
   5226   let Inst{11-10} = 0b00;
   5227   let Inst{9-5}   = Rn;
   5228   let Inst{4-0}   = Rd;
   5229 }
   5230 
   5231 // FIXME: TableGen doesn't know how to deal with expanded types that also
   5232 //        change the element count (in this case, placing the results in
   5233 //        the high elements of the result register rather than the low
   5234 //        elements). Until that's fixed, we can't code-gen those.
   5235 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
   5236                                     Intrinsic IntOp> {
   5237   def v8i16_v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
   5238                                                   V64, V128, V128,
   5239                                                   asm, ".8b", ".8h", ".8h",
   5240      [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
   5241   def v8i16_v16i8  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
   5242                                                   V128, V128, V128,
   5243                                                   asm#"2", ".16b", ".8h", ".8h",
   5244      []>;
   5245   def v4i32_v4i16  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
   5246                                                   V64, V128, V128,
   5247                                                   asm, ".4h", ".4s", ".4s",
   5248      [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
   5249   def v4i32_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
   5250                                                   V128, V128, V128,
   5251                                                   asm#"2", ".8h", ".4s", ".4s",
   5252      []>;
   5253   def v2i64_v2i32  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
   5254                                                   V64, V128, V128,
   5255                                                   asm, ".2s", ".2d", ".2d",
   5256      [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
   5257   def v2i64_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
   5258                                                   V128, V128, V128,
   5259                                                   asm#"2", ".4s", ".2d", ".2d",
   5260      []>;
   5261 
   5262 
   5263   // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
   5264   // a version attached to an instruction.
   5265   def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
   5266                                                    (v8i16 V128:$Rm))),
   5267             (!cast<Instruction>(NAME # "v8i16_v16i8")
   5268                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
   5269                 V128:$Rn, V128:$Rm)>;
   5270   def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
   5271                                                     (v4i32 V128:$Rm))),
   5272             (!cast<Instruction>(NAME # "v4i32_v8i16")
   5273                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
   5274                 V128:$Rn, V128:$Rm)>;
   5275   def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
   5276                                                     (v2i64 V128:$Rm))),
   5277             (!cast<Instruction>(NAME # "v2i64_v4i32")
   5278                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
   5279                 V128:$Rn, V128:$Rm)>;
   5280 }
   5281 
   5282 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
   5283                                       Intrinsic IntOp> {
   5284   def v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
   5285                                             V128, V64, V64,
   5286                                             asm, ".8h", ".8b", ".8b",
   5287       [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
   5288   def v16i8  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
   5289                                             V128, V128, V128,
   5290                                             asm#"2", ".8h", ".16b", ".16b", []>;
   5291   let Predicates = [HasCrypto] in {
   5292     def v1i64  : BaseSIMDDifferentThreeVector<U, 0b110, opc,
   5293                                               V128, V64, V64,
   5294                                               asm, ".1q", ".1d", ".1d", []>;
   5295     def v2i64  : BaseSIMDDifferentThreeVector<U, 0b111, opc,
   5296                                               V128, V128, V128,
   5297                                               asm#"2", ".1q", ".2d", ".2d", []>;
   5298   }
   5299 
   5300   def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
   5301                           (v8i8 (extract_high_v16i8 V128:$Rm)))),
   5302       (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
   5303 }
   5304 
   5305 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
   5306                                  SDPatternOperator OpNode> {
   5307   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
   5308                                                   V128, V64, V64,
   5309                                                   asm, ".4s", ".4h", ".4h",
   5310       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
   5311   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
   5312                                                   V128, V128, V128,
   5313                                                   asm#"2", ".4s", ".8h", ".8h",
   5314       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
   5315                                       (extract_high_v8i16 V128:$Rm)))]>;
   5316   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
   5317                                                   V128, V64, V64,
   5318                                                   asm, ".2d", ".2s", ".2s",
   5319       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
   5320   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
   5321                                                   V128, V128, V128,
   5322                                                   asm#"2", ".2d", ".4s", ".4s",
   5323       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
   5324                                       (extract_high_v4i32 V128:$Rm)))]>;
   5325 }
   5326 
   5327 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
   5328                                   SDPatternOperator OpNode = null_frag> {
   5329   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
   5330                                                   V128, V64, V64,
   5331                                                   asm, ".8h", ".8b", ".8b",
   5332       [(set (v8i16 V128:$Rd),
   5333             (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
   5334   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
   5335                                                  V128, V128, V128,
   5336                                                  asm#"2", ".8h", ".16b", ".16b",
   5337       [(set (v8i16 V128:$Rd),
   5338             (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
   5339                                 (extract_high_v16i8 V128:$Rm)))))]>;
   5340   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
   5341                                                   V128, V64, V64,
   5342                                                   asm, ".4s", ".4h", ".4h",
   5343       [(set (v4i32 V128:$Rd),
   5344             (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
   5345   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
   5346                                                   V128, V128, V128,
   5347                                                   asm#"2", ".4s", ".8h", ".8h",
   5348       [(set (v4i32 V128:$Rd),
   5349             (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
   5350                                   (extract_high_v8i16 V128:$Rm)))))]>;
   5351   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
   5352                                                   V128, V64, V64,
   5353                                                   asm, ".2d", ".2s", ".2s",
   5354       [(set (v2i64 V128:$Rd),
   5355             (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
   5356   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
   5357                                                   V128, V128, V128,
   5358                                                   asm#"2", ".2d", ".4s", ".4s",
   5359       [(set (v2i64 V128:$Rd),
   5360             (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
   5361                                  (extract_high_v4i32 V128:$Rm)))))]>;
   5362 }
   5363 
   5364 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
   5365                                           string asm,
   5366                                           SDPatternOperator OpNode> {
   5367   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
   5368                                                   V128, V64, V64,
   5369                                                   asm, ".8h", ".8b", ".8b",
   5370     [(set (v8i16 V128:$dst),
   5371           (add (v8i16 V128:$Rd),
   5372                (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
   5373   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
   5374                                                  V128, V128, V128,
   5375                                                  asm#"2", ".8h", ".16b", ".16b",
   5376     [(set (v8i16 V128:$dst),
   5377           (add (v8i16 V128:$Rd),
   5378                (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
   5379                                    (extract_high_v16i8 V128:$Rm))))))]>;
   5380   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
   5381                                                   V128, V64, V64,
   5382                                                   asm, ".4s", ".4h", ".4h",
   5383     [(set (v4i32 V128:$dst),
   5384           (add (v4i32 V128:$Rd),
   5385                (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
   5386   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
   5387                                                   V128, V128, V128,
   5388                                                   asm#"2", ".4s", ".8h", ".8h",
   5389     [(set (v4i32 V128:$dst),
   5390           (add (v4i32 V128:$Rd),
   5391                (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
   5392                                     (extract_high_v8i16 V128:$Rm))))))]>;
   5393   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
   5394                                                   V128, V64, V64,
   5395                                                   asm, ".2d", ".2s", ".2s",
   5396     [(set (v2i64 V128:$dst),
   5397           (add (v2i64 V128:$Rd),
   5398                (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
   5399   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
   5400                                                   V128, V128, V128,
   5401                                                   asm#"2", ".2d", ".4s", ".4s",
   5402     [(set (v2i64 V128:$dst),
   5403           (add (v2i64 V128:$Rd),
   5404                (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
   5405                                     (extract_high_v4i32 V128:$Rm))))))]>;
   5406 }
   5407 
   5408 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
   5409                                   SDPatternOperator OpNode = null_frag> {
   5410   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
   5411                                                   V128, V64, V64,
   5412                                                   asm, ".8h", ".8b", ".8b",
   5413       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
   5414   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
   5415                                                  V128, V128, V128,
   5416                                                  asm#"2", ".8h", ".16b", ".16b",
   5417       [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
   5418                                       (extract_high_v16i8 V128:$Rm)))]>;
   5419   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
   5420                                                   V128, V64, V64,
   5421                                                   asm, ".4s", ".4h", ".4h",
   5422       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
   5423   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
   5424                                                   V128, V128, V128,
   5425                                                   asm#"2", ".4s", ".8h", ".8h",
   5426       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
   5427                                       (extract_high_v8i16 V128:$Rm)))]>;
   5428   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
   5429                                                   V128, V64, V64,
   5430                                                   asm, ".2d", ".2s", ".2s",
   5431       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
   5432   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
   5433                                                   V128, V128, V128,
   5434                                                   asm#"2", ".2d", ".4s", ".4s",
   5435       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
   5436                                       (extract_high_v4i32 V128:$Rm)))]>;
   5437 }
   5438 
   5439 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
   5440                                       string asm,
   5441                                       SDPatternOperator OpNode> {
   5442   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
   5443                                                   V128, V64, V64,
   5444                                                   asm, ".8h", ".8b", ".8b",
   5445     [(set (v8i16 V128:$dst),
   5446           (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
   5447   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
   5448                                                  V128, V128, V128,
   5449                                                  asm#"2", ".8h", ".16b", ".16b",
   5450     [(set (v8i16 V128:$dst),
   5451           (OpNode (v8i16 V128:$Rd),
   5452                   (extract_high_v16i8 V128:$Rn),
   5453                   (extract_high_v16i8 V128:$Rm)))]>;
   5454   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
   5455                                                   V128, V64, V64,
   5456                                                   asm, ".4s", ".4h", ".4h",
   5457     [(set (v4i32 V128:$dst),
   5458           (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
   5459   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
   5460                                                   V128, V128, V128,
   5461                                                   asm#"2", ".4s", ".8h", ".8h",
   5462     [(set (v4i32 V128:$dst),
   5463           (OpNode (v4i32 V128:$Rd),
   5464                   (extract_high_v8i16 V128:$Rn),
   5465                   (extract_high_v8i16 V128:$Rm)))]>;
   5466   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
   5467                                                   V128, V64, V64,
   5468                                                   asm, ".2d", ".2s", ".2s",
   5469     [(set (v2i64 V128:$dst),
   5470           (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
   5471   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
   5472                                                   V128, V128, V128,
   5473                                                   asm#"2", ".2d", ".4s", ".4s",
   5474     [(set (v2i64 V128:$dst),
   5475           (OpNode (v2i64 V128:$Rd),
   5476                   (extract_high_v4i32 V128:$Rn),
   5477                   (extract_high_v4i32 V128:$Rm)))]>;
   5478 }
   5479 
   5480 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
   5481                                            SDPatternOperator Accum> {
   5482   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
   5483                                                   V128, V64, V64,
   5484                                                   asm, ".4s", ".4h", ".4h",
   5485     [(set (v4i32 V128:$dst),
   5486           (Accum (v4i32 V128:$Rd),
   5487                  (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
   5488                                                 (v4i16 V64:$Rm)))))]>;
   5489   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
   5490                                                   V128, V128, V128,
   5491                                                   asm#"2", ".4s", ".8h", ".8h",
   5492     [(set (v4i32 V128:$dst),
   5493           (Accum (v4i32 V128:$Rd),
   5494                  (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
   5495                                             (extract_high_v8i16 V128:$Rm)))))]>;
   5496   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
   5497                                                   V128, V64, V64,
   5498                                                   asm, ".2d", ".2s", ".2s",
   5499     [(set (v2i64 V128:$dst),
   5500           (Accum (v2i64 V128:$Rd),
   5501                  (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
   5502                                                 (v2i32 V64:$Rm)))))]>;
   5503   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
   5504                                                   V128, V128, V128,
   5505                                                   asm#"2", ".2d", ".4s", ".4s",
   5506     [(set (v2i64 V128:$dst),
   5507           (Accum (v2i64 V128:$Rd),
   5508                  (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
   5509                                             (extract_high_v4i32 V128:$Rm)))))]>;
   5510 }
   5511 
   5512 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
   5513                                   SDPatternOperator OpNode> {
   5514   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
   5515                                                   V128, V128, V64,
   5516                                                   asm, ".8h", ".8h", ".8b",
   5517        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
   5518   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
   5519                                                   V128, V128, V128,
   5520                                                   asm#"2", ".8h", ".8h", ".16b",
   5521        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
   5522                                        (extract_high_v16i8 V128:$Rm)))]>;
   5523   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
   5524                                                   V128, V128, V64,
   5525                                                   asm, ".4s", ".4s", ".4h",
   5526        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
   5527   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
   5528                                                   V128, V128, V128,
   5529                                                   asm#"2", ".4s", ".4s", ".8h",
   5530        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
   5531                                        (extract_high_v8i16 V128:$Rm)))]>;
   5532   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
   5533                                                   V128, V128, V64,
   5534                                                   asm, ".2d", ".2d", ".2s",
   5535        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
   5536   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
   5537                                                   V128, V128, V128,
   5538                                                   asm#"2", ".2d", ".2d", ".4s",
   5539        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
   5540                                        (extract_high_v4i32 V128:$Rm)))]>;
   5541 }
   5542 
   5543 //----------------------------------------------------------------------------
   5544 // AdvSIMD bitwise extract from vector
   5545 //----------------------------------------------------------------------------
   5546 
   5547 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
   5548                              string asm, string kind>
   5549   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
   5550       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
   5551       "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
   5552       [(set (vty regtype:$Rd),
   5553             (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
   5554     Sched<[WriteV]> {
   5555   bits<5> Rd;
   5556   bits<5> Rn;
   5557   bits<5> Rm;
   5558   bits<4> imm;
   5559   let Inst{31}    = 0;
   5560   let Inst{30}    = size;
   5561   let Inst{29-21} = 0b101110000;
   5562   let Inst{20-16} = Rm;
   5563   let Inst{15}    = 0;
   5564   let Inst{14-11} = imm;
   5565   let Inst{10}    = 0;
   5566   let Inst{9-5}   = Rn;
   5567   let Inst{4-0}   = Rd;
   5568 }
   5569 
   5570 
   5571 multiclass SIMDBitwiseExtract<string asm> {
   5572   def v8i8  : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
   5573     let imm{3} = 0;
   5574   }
   5575   def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
   5576 }
   5577 
   5578 //----------------------------------------------------------------------------
   5579 // AdvSIMD zip vector
   5580 //----------------------------------------------------------------------------
   5581 
   5582 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
   5583                         string asm, string kind, SDNode OpNode, ValueType valty>
   5584   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
   5585       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
   5586       "|" # kind # "\t$Rd, $Rn, $Rm}", "",
   5587       [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
   5588     Sched<[WriteV]> {
   5589   bits<5> Rd;
   5590   bits<5> Rn;
   5591   bits<5> Rm;
   5592   let Inst{31}    = 0;
   5593   let Inst{30}    = size{0};
   5594   let Inst{29-24} = 0b001110;
   5595   let Inst{23-22} = size{2-1};
   5596   let Inst{21}    = 0;
   5597   let Inst{20-16} = Rm;
   5598   let Inst{15}    = 0;
   5599   let Inst{14-12} = opc;
   5600   let Inst{11-10} = 0b10;
   5601   let Inst{9-5}   = Rn;
   5602   let Inst{4-0}   = Rd;
   5603 }
   5604 
   5605 multiclass SIMDZipVector<bits<3>opc, string asm,
   5606                          SDNode OpNode> {
   5607   def v8i8   : BaseSIMDZipVector<0b000, opc, V64,
   5608       asm, ".8b", OpNode, v8i8>;
   5609   def v16i8  : BaseSIMDZipVector<0b001, opc, V128,
   5610       asm, ".16b", OpNode, v16i8>;
   5611   def v4i16  : BaseSIMDZipVector<0b010, opc, V64,
   5612       asm, ".4h", OpNode, v4i16>;
   5613   def v8i16  : BaseSIMDZipVector<0b011, opc, V128,
   5614       asm, ".8h", OpNode, v8i16>;
   5615   def v2i32  : BaseSIMDZipVector<0b100, opc, V64,
   5616       asm, ".2s", OpNode, v2i32>;
   5617   def v4i32  : BaseSIMDZipVector<0b101, opc, V128,
   5618       asm, ".4s", OpNode, v4i32>;
   5619   def v2i64  : BaseSIMDZipVector<0b111, opc, V128,
   5620       asm, ".2d", OpNode, v2i64>;
   5621 
   5622   def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
   5623         (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
   5624   def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
   5625         (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
   5626   def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
   5627         (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
   5628   def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
   5629         (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
   5630   def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
   5631         (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
   5632 }
   5633 
   5634 //----------------------------------------------------------------------------
   5635 // AdvSIMD three register scalar instructions
   5636 //----------------------------------------------------------------------------
   5637 
   5638 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   5639 class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,
   5640                         RegisterClass regtype, string asm,
   5641                         list<dag> pattern>
   5642   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
   5643       "\t$Rd, $Rn, $Rm", "", pattern>,
   5644     Sched<[WriteV]> {
   5645   bits<5> Rd;
   5646   bits<5> Rn;
   5647   bits<5> Rm;
   5648   let Inst{31-30} = 0b01;
   5649   let Inst{29}    = U;
   5650   let Inst{28-24} = 0b11110;
   5651   let Inst{23-21} = size;
   5652   let Inst{20-16} = Rm;
   5653   let Inst{15-11} = opcode;
   5654   let Inst{10}    = 1;
   5655   let Inst{9-5}   = Rn;
   5656   let Inst{4-0}   = Rd;
   5657 }
   5658 
   5659 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   5660 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
   5661                         dag oops, dag iops, string asm,
   5662             list<dag> pattern>
   5663   : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
   5664     Sched<[WriteV]> {
   5665   bits<5> Rd;
   5666   bits<5> Rn;
   5667   bits<5> Rm;
   5668   let Inst{31-30} = 0b01;
   5669   let Inst{29}    = U;
   5670   let Inst{28-24} = 0b11110;
   5671   let Inst{23-22} = size;
   5672   let Inst{21}    = R;
   5673   let Inst{20-16} = Rm;
   5674   let Inst{15-11} = opcode;
   5675   let Inst{10}    = 1;
   5676   let Inst{9-5}   = Rn;
   5677   let Inst{4-0}   = Rd;
   5678 }
   5679 
   5680 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
   5681                             SDPatternOperator OpNode> {
   5682   def v1i64  : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
   5683     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
   5684 }
   5685 
   5686 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
   5687                                SDPatternOperator OpNode> {
   5688   def v1i64  : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
   5689     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
   5690   def v1i32  : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;
   5691   def v1i16  : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
   5692   def v1i8   : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;
   5693 
   5694   def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
   5695             (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
   5696   def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
   5697             (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
   5698 }
   5699 
   5700 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
   5701                              SDPatternOperator OpNode> {
   5702   def v1i32  : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,
   5703                              [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
   5704   def v1i16  : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
   5705 }
   5706 
   5707 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
   5708                                  SDPatternOperator OpNode = null_frag> {
   5709   def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
   5710                                      (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 
   5711                                      asm, []>;
   5712   def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
   5713                                      (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 
   5714                                      asm, []>;
   5715 }
   5716 
   5717 multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,
   5718                              SDPatternOperator OpNode = null_frag> {
   5719   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
   5720     def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
   5721       [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
   5722     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
   5723       [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
   5724     let Predicates = [HasNEON, HasFullFP16] in {
   5725     def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
   5726       [(set FPR16:$Rd, (OpNode FPR16:$Rn, FPR16:$Rm))]>;
   5727     } // Predicates = [HasNEON, HasFullFP16]
   5728   }
   5729 
   5730   def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
   5731             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
   5732 }
   5733 
   5734 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,
   5735                                 SDPatternOperator OpNode = null_frag> {
   5736   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
   5737     def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
   5738       [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
   5739     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
   5740       [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
   5741     let Predicates = [HasNEON, HasFullFP16] in {
   5742     def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
   5743       []>;
   5744     } // Predicates = [HasNEON, HasFullFP16]
   5745   }
   5746 
   5747   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
   5748             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
   5749 }
   5750 
   5751 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
   5752               dag oops, dag iops, string asm, string cstr, list<dag> pat>
   5753   : I<oops, iops, asm,
   5754       "\t$Rd, $Rn, $Rm", cstr, pat>,
   5755     Sched<[WriteV]> {
   5756   bits<5> Rd;
   5757   bits<5> Rn;
   5758   bits<5> Rm;
   5759   let Inst{31-30} = 0b01;
   5760   let Inst{29}    = U;
   5761   let Inst{28-24} = 0b11110;
   5762   let Inst{23-22} = size;
   5763   let Inst{21}    = 1;
   5764   let Inst{20-16} = Rm;
   5765   let Inst{15-11} = opcode;
   5766   let Inst{10}    = 0;
   5767   let Inst{9-5}   = Rn;
   5768   let Inst{4-0}   = Rd;
   5769 }
   5770 
   5771 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5772 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
   5773                                   SDPatternOperator OpNode = null_frag> {
   5774   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
   5775                                       (outs FPR32:$Rd),
   5776                                       (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
   5777   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
   5778                                       (outs FPR64:$Rd),
   5779                                       (ins FPR32:$Rn, FPR32:$Rm), asm, "",
   5780             [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
   5781 }
   5782 
   5783 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5784 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
   5785                                   SDPatternOperator OpNode = null_frag> {
   5786   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
   5787                                       (outs FPR32:$dst),
   5788                                       (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
   5789                                       asm, "$Rd = $dst", []>;
   5790   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
   5791                                       (outs FPR64:$dst),
   5792                                       (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
   5793                                       asm, "$Rd = $dst",
   5794             [(set (i64 FPR64:$dst),
   5795                   (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
   5796 }
   5797 
   5798 //----------------------------------------------------------------------------
   5799 // AdvSIMD two register scalar instructions
   5800 //----------------------------------------------------------------------------
   5801 
   5802 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5803 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
   5804                         RegisterClass regtype, RegisterClass regtype2,
   5805                         string asm, list<dag> pat>
   5806   : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
   5807       "\t$Rd, $Rn", "", pat>,
   5808     Sched<[WriteV]> {
   5809   bits<5> Rd;
   5810   bits<5> Rn;
   5811   let Inst{31-30} = 0b01;
   5812   let Inst{29}    = U;
   5813   let Inst{28-24} = 0b11110;
   5814   let Inst{23-22} = size;
   5815   let Inst{21} = 0b1;
   5816   let Inst{20-19} = size2;
   5817   let Inst{18-17} = 0b00;
   5818   let Inst{16-12} = opcode;
   5819   let Inst{11-10} = 0b10;
   5820   let Inst{9-5}   = Rn;
   5821   let Inst{4-0}   = Rd;
   5822 }
   5823 
   5824 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5825 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
   5826                         RegisterClass regtype, RegisterClass regtype2,
   5827                         string asm, list<dag> pat>
   5828   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
   5829       "\t$Rd, $Rn", "$Rd = $dst", pat>,
   5830     Sched<[WriteV]> {
   5831   bits<5> Rd;
   5832   bits<5> Rn;
   5833   let Inst{31-30} = 0b01;
   5834   let Inst{29}    = U;
   5835   let Inst{28-24} = 0b11110;
   5836   let Inst{23-22} = size;
   5837   let Inst{21-17} = 0b10000;
   5838   let Inst{16-12} = opcode;
   5839   let Inst{11-10} = 0b10;
   5840   let Inst{9-5}   = Rn;
   5841   let Inst{4-0}   = Rd;
   5842 }
   5843 
   5844 
   5845 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5846 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
   5847                         RegisterClass regtype, string asm, string zero>
   5848   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
   5849       "\t$Rd, $Rn, #" # zero, "", []>,
   5850     Sched<[WriteV]> {
   5851   bits<5> Rd;
   5852   bits<5> Rn;
   5853   let Inst{31-30} = 0b01;
   5854   let Inst{29}    = U;
   5855   let Inst{28-24} = 0b11110;
   5856   let Inst{23-22} = size;
   5857   let Inst{21} = 0b1;
   5858   let Inst{20-19} = size2;
   5859   let Inst{18-17} = 0b00;
   5860   let Inst{16-12} = opcode;
   5861   let Inst{11-10} = 0b10;
   5862   let Inst{9-5}   = Rn;
   5863   let Inst{4-0}   = Rd;
   5864 }
   5865 
   5866 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
   5867   : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
   5868      [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
   5869     Sched<[WriteV]> {
   5870   bits<5> Rd;
   5871   bits<5> Rn;
   5872   let Inst{31-17} = 0b011111100110000;
   5873   let Inst{16-12} = opcode;
   5874   let Inst{11-10} = 0b10;
   5875   let Inst{9-5}   = Rn;
   5876   let Inst{4-0}   = Rd;
   5877 }
   5878 
   5879 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
   5880                              SDPatternOperator OpNode> {
   5881   def v1i64rz  : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;
   5882 
   5883   def : Pat<(v1i64 (OpNode FPR64:$Rn)),
   5884             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
   5885 }
   5886 
   5887 multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
   5888                               SDPatternOperator OpNode> {
   5889   def v1i64rz  : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;
   5890   def v1i32rz  : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;
   5891   let Predicates = [HasNEON, HasFullFP16] in {
   5892   def v1i16rz  : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;
   5893   }
   5894 
   5895   def : InstAlias<asm # "\t$Rd, $Rn, #0",
   5896                   (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
   5897   def : InstAlias<asm # "\t$Rd, $Rn, #0",
   5898                   (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
   5899   let Predicates = [HasNEON, HasFullFP16] in {
   5900   def : InstAlias<asm # "\t$Rd, $Rn, #0",
   5901                   (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;
   5902   }
   5903 
   5904   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
   5905             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
   5906 }
   5907 
   5908 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
   5909                           SDPatternOperator OpNode = null_frag> {
   5910   def v1i64       : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
   5911     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
   5912 
   5913   def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
   5914             (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
   5915 }
   5916 
   5917 multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
   5918   def v1i64       : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>;
   5919   def v1i32       : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>;
   5920   let Predicates = [HasNEON, HasFullFP16] in {
   5921   def v1f16       : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
   5922   }
   5923 }
   5924 
   5925 multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,
   5926                               SDPatternOperator OpNode> {
   5927   def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,
   5928                                 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
   5929   def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,
   5930                                 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
   5931   let Predicates = [HasNEON, HasFullFP16] in {
   5932   def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,
   5933                                 [(set FPR16:$Rd, (OpNode (f16 FPR16:$Rn)))]>;
   5934   }
   5935 }
   5936 
   5937 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
   5938                              SDPatternOperator OpNode = null_frag> {
   5939   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
   5940     def v1i64  : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
   5941            [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
   5942     def v1i32  : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,
   5943            [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
   5944     def v1i16  : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;
   5945     def v1i8   : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;
   5946   }
   5947 
   5948   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
   5949             (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
   5950 }
   5951 
   5952 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
   5953                                  Intrinsic OpNode> {
   5954   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
   5955     def v1i64  : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
   5956         [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
   5957     def v1i32  : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
   5958         [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
   5959     def v1i16  : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
   5960     def v1i8   : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
   5961   }
   5962 
   5963   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
   5964             (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
   5965 }
   5966 
   5967 
   5968 
   5969 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5970 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
   5971                                  SDPatternOperator OpNode = null_frag> {
   5972   def v1i32  : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,
   5973         [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
   5974   def v1i16  : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;
   5975   def v1i8   : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;
   5976 }
   5977 
   5978 //----------------------------------------------------------------------------
   5979 // AdvSIMD scalar pairwise instructions
   5980 //----------------------------------------------------------------------------
   5981 
   5982 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   5983 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
   5984                         RegisterOperand regtype, RegisterOperand vectype,
   5985                         string asm, string kind>
   5986   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
   5987       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
   5988     Sched<[WriteV]> {
   5989   bits<5> Rd;
   5990   bits<5> Rn;
   5991   let Inst{31-30} = 0b01;
   5992   let Inst{29}    = U;
   5993   let Inst{28-24} = 0b11110;
   5994   let Inst{23-22} = size;
   5995   let Inst{21-17} = 0b11000;
   5996   let Inst{16-12} = opcode;
   5997   let Inst{11-10} = 0b10;
   5998   let Inst{9-5}   = Rn;
   5999   let Inst{4-0}   = Rd;
   6000 }
   6001 
   6002 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
   6003   def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
   6004                                       asm, ".2d">;
   6005 }
   6006 
   6007 multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {
   6008   let Predicates = [HasNEON, HasFullFP16] in {
   6009   def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,
   6010                                       asm, ".2h">;
   6011   }
   6012   def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
   6013                                       asm, ".2s">;
   6014   def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
   6015                                       asm, ".2d">;
   6016 }
   6017 
   6018 //----------------------------------------------------------------------------
   6019 // AdvSIMD across lanes instructions
   6020 //----------------------------------------------------------------------------
   6021 
   6022 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   6023 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
   6024                           RegisterClass regtype, RegisterOperand vectype,
   6025                           string asm, string kind, list<dag> pattern>
   6026   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
   6027       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
   6028     Sched<[WriteV]> {
   6029   bits<5> Rd;
   6030   bits<5> Rn;
   6031   let Inst{31}    = 0;
   6032   let Inst{30}    = Q;
   6033   let Inst{29}    = U;
   6034   let Inst{28-24} = 0b01110;
   6035   let Inst{23-22} = size;
   6036   let Inst{21-17} = 0b11000;
   6037   let Inst{16-12} = opcode;
   6038   let Inst{11-10} = 0b10;
   6039   let Inst{9-5}   = Rn;
   6040   let Inst{4-0}   = Rd;
   6041 }
   6042 
   6043 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
   6044                               string asm> {
   6045   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8,  V64,
   6046                                    asm, ".8b", []>;
   6047   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8,  V128,
   6048                                    asm, ".16b", []>;
   6049   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
   6050                                    asm, ".4h", []>;
   6051   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
   6052                                    asm, ".8h", []>;
   6053   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
   6054                                    asm, ".4s", []>;
   6055 }
   6056 
   6057 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
   6058   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
   6059                                    asm, ".8b", []>;
   6060   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
   6061                                    asm, ".16b", []>;
   6062   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
   6063                                    asm, ".4h", []>;
   6064   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
   6065                                    asm, ".8h", []>;
   6066   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
   6067                                    asm, ".4s", []>;
   6068 }
   6069 
   6070 multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,
   6071                             Intrinsic intOp> {
   6072   let Predicates = [HasNEON, HasFullFP16] in {
   6073   def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,
   6074                                    asm, ".4h",
   6075         [(set FPR16:$Rd, (intOp (v4f16 V64:$Rn)))]>;
   6076   def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
   6077                                    asm, ".8h",
   6078         [(set FPR16:$Rd, (intOp (v8f16 V128:$Rn)))]>;
   6079   } // Predicates = [HasNEON, HasFullFP16]
   6080   def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
   6081                                    asm, ".4s",
   6082         [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
   6083 }
   6084 
   6085 //----------------------------------------------------------------------------
   6086 // AdvSIMD INS/DUP instructions
   6087 //----------------------------------------------------------------------------
   6088 
   6089 // FIXME: There has got to be a better way to factor these. ugh.
   6090 
   6091 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
   6092                      string operands, string constraints, list<dag> pattern>
   6093   : I<outs, ins, asm, operands, constraints, pattern>,
   6094     Sched<[WriteV]> {
   6095   bits<5> Rd;
   6096   bits<5> Rn;
   6097   let Inst{31} = 0;
   6098   let Inst{30} = Q;
   6099   let Inst{29} = op;
   6100   let Inst{28-21} = 0b01110000;
   6101   let Inst{15} = 0;
   6102   let Inst{10} = 1;
   6103   let Inst{9-5} = Rn;
   6104   let Inst{4-0} = Rd;
   6105 }
   6106 
   6107 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
   6108                       RegisterOperand vecreg, RegisterClass regtype>
   6109   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
   6110                    "{\t$Rd" # size # ", $Rn" #
   6111                    "|" # size # "\t$Rd, $Rn}", "",
   6112                    [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
   6113   let Inst{20-16} = imm5;
   6114   let Inst{14-11} = 0b0001;
   6115 }
   6116 
   6117 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
   6118                          ValueType vectype, ValueType insreg,
   6119                          RegisterOperand vecreg, Operand idxtype,
   6120                          ValueType elttype, SDNode OpNode>
   6121   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
   6122                    "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
   6123                    "|" # dstkind # "\t$Rd, $Rn$idx}", "",
   6124                  [(set (vectype vecreg:$Rd),
   6125                        (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
   6126   let Inst{14-11} = 0b0000;
   6127 }
   6128 
   6129 class SIMDDup64FromElement
   6130   : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
   6131                        VectorIndexD, i64, AArch64duplane64> {
   6132   bits<1> idx;
   6133   let Inst{20} = idx;
   6134   let Inst{19-16} = 0b1000;
   6135 }
   6136 
   6137 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
   6138                            RegisterOperand vecreg>
   6139   : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
   6140                        VectorIndexS, i64, AArch64duplane32> {
   6141   bits<2> idx;
   6142   let Inst{20-19} = idx;
   6143   let Inst{18-16} = 0b100;
   6144 }
   6145 
   6146 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
   6147                            RegisterOperand vecreg>
   6148   : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
   6149                        VectorIndexH, i64, AArch64duplane16> {
   6150   bits<3> idx;
   6151   let Inst{20-18} = idx;
   6152   let Inst{17-16} = 0b10;
   6153 }
   6154 
   6155 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
   6156                           RegisterOperand vecreg>
   6157   : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
   6158                        VectorIndexB, i64, AArch64duplane8> {
   6159   bits<4> idx;
   6160   let Inst{20-17} = idx;
   6161   let Inst{16} = 1;
   6162 }
   6163 
   6164 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
   6165                   Operand idxtype, string asm, list<dag> pattern>
   6166   : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
   6167                    "{\t$Rd, $Rn" # size # "$idx" #
   6168                    "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
   6169   let Inst{14-11} = imm4;
   6170 }
   6171 
   6172 class SIMDSMov<bit Q, string size, RegisterClass regtype,
   6173                Operand idxtype>
   6174   : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
   6175 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
   6176                Operand idxtype>
   6177   : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
   6178       [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
   6179 
   6180 class SIMDMovAlias<string asm, string size, Instruction inst,
   6181                    RegisterClass regtype, Operand idxtype>
   6182     : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
   6183                     "|" # size # "\t$dst, $src$idx}",
   6184                 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
   6185 
   6186 multiclass SMov {
   6187   def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
   6188     bits<4> idx;
   6189     let Inst{20-17} = idx;
   6190     let Inst{16} = 1;
   6191   }
   6192   def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
   6193     bits<4> idx;
   6194     let Inst{20-17} = idx;
   6195     let Inst{16} = 1;
   6196   }
   6197   def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
   6198     bits<3> idx;
   6199     let Inst{20-18} = idx;
   6200     let Inst{17-16} = 0b10;
   6201   }
   6202   def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
   6203     bits<3> idx;
   6204     let Inst{20-18} = idx;
   6205     let Inst{17-16} = 0b10;
   6206   }
   6207   def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
   6208     bits<2> idx;
   6209     let Inst{20-19} = idx;
   6210     let Inst{18-16} = 0b100;
   6211   }
   6212 }
   6213 
   6214 multiclass UMov {
   6215   def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
   6216     bits<4> idx;
   6217     let Inst{20-17} = idx;
   6218     let Inst{16} = 1;
   6219   }
   6220   def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
   6221     bits<3> idx;
   6222     let Inst{20-18} = idx;
   6223     let Inst{17-16} = 0b10;
   6224   }
   6225   def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
   6226     bits<2> idx;
   6227     let Inst{20-19} = idx;
   6228     let Inst{18-16} = 0b100;
   6229   }
   6230   def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
   6231     bits<1> idx;
   6232     let Inst{20} = idx;
   6233     let Inst{19-16} = 0b1000;
   6234   }
   6235   def : SIMDMovAlias<"mov", ".s",
   6236                      !cast<Instruction>(NAME#"vi32"),
   6237                      GPR32, VectorIndexS>;
   6238   def : SIMDMovAlias<"mov", ".d",
   6239                      !cast<Instruction>(NAME#"vi64"),
   6240                      GPR64, VectorIndexD>;
   6241 }
   6242 
   6243 class SIMDInsFromMain<string size, ValueType vectype,
   6244                       RegisterClass regtype, Operand idxtype>
   6245   : BaseSIMDInsDup<1, 0, (outs V128:$dst),
   6246                    (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
   6247                    "{\t$Rd" # size # "$idx, $Rn" #
   6248                    "|" # size # "\t$Rd$idx, $Rn}",
   6249                    "$Rd = $dst",
   6250             [(set V128:$dst,
   6251               (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
   6252   let Inst{14-11} = 0b0011;
   6253 }
   6254 
   6255 class SIMDInsFromElement<string size, ValueType vectype,
   6256                          ValueType elttype, Operand idxtype>
   6257   : BaseSIMDInsDup<1, 1, (outs V128:$dst),
   6258                    (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
   6259                    "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
   6260                    "|" # size # "\t$Rd$idx, $Rn$idx2}",
   6261                    "$Rd = $dst",
   6262          [(set V128:$dst,
   6263                (vector_insert
   6264                  (vectype V128:$Rd),
   6265                  (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
   6266                  idxtype:$idx))]>;
   6267 
   6268 class SIMDInsMainMovAlias<string size, Instruction inst,
   6269                           RegisterClass regtype, Operand idxtype>
   6270     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
   6271                         "|" # size #"\t$dst$idx, $src}",
   6272                 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
   6273 class SIMDInsElementMovAlias<string size, Instruction inst,
   6274                              Operand idxtype>
   6275     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
   6276                       # "|" # size #"\t$dst$idx, $src$idx2}",
   6277                 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
   6278 
   6279 
   6280 multiclass SIMDIns {
   6281   def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
   6282     bits<4> idx;
   6283     let Inst{20-17} = idx;
   6284     let Inst{16} = 1;
   6285   }
   6286   def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
   6287     bits<3> idx;
   6288     let Inst{20-18} = idx;
   6289     let Inst{17-16} = 0b10;
   6290   }
   6291   def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
   6292     bits<2> idx;
   6293     let Inst{20-19} = idx;
   6294     let Inst{18-16} = 0b100;
   6295   }
   6296   def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
   6297     bits<1> idx;
   6298     let Inst{20} = idx;
   6299     let Inst{19-16} = 0b1000;
   6300   }
   6301 
   6302   def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
   6303     bits<4> idx;
   6304     bits<4> idx2;
   6305     let Inst{20-17} = idx;
   6306     let Inst{16} = 1;
   6307     let Inst{14-11} = idx2;
   6308   }
   6309   def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
   6310     bits<3> idx;
   6311     bits<3> idx2;
   6312     let Inst{20-18} = idx;
   6313     let Inst{17-16} = 0b10;
   6314     let Inst{14-12} = idx2;
   6315     let Inst{11} = {?};
   6316   }
   6317   def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
   6318     bits<2> idx;
   6319     bits<2> idx2;
   6320     let Inst{20-19} = idx;
   6321     let Inst{18-16} = 0b100;
   6322     let Inst{14-13} = idx2;
   6323     let Inst{12-11} = {?,?};
   6324   }
   6325   def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
   6326     bits<1> idx;
   6327     bits<1> idx2;
   6328     let Inst{20} = idx;
   6329     let Inst{19-16} = 0b1000;
   6330     let Inst{14} = idx2;
   6331     let Inst{13-11} = {?,?,?};
   6332   }
   6333 
   6334   // For all forms of the INS instruction, the "mov" mnemonic is the
   6335   // preferred alias. Why they didn't just call the instruction "mov" in
   6336   // the first place is a very good question indeed...
   6337   def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
   6338                          GPR32, VectorIndexB>;
   6339   def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
   6340                          GPR32, VectorIndexH>;
   6341   def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
   6342                          GPR32, VectorIndexS>;
   6343   def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
   6344                          GPR64, VectorIndexD>;
   6345 
   6346   def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
   6347                          VectorIndexB>;
   6348   def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
   6349                          VectorIndexH>;
   6350   def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
   6351                          VectorIndexS>;
   6352   def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
   6353                          VectorIndexD>;
   6354 }
   6355 
   6356 //----------------------------------------------------------------------------
   6357 // AdvSIMD TBL/TBX
   6358 //----------------------------------------------------------------------------
   6359 
   6360 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   6361 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
   6362                           RegisterOperand listtype, string asm, string kind>
   6363   : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
   6364        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
   6365     Sched<[WriteV]> {
   6366   bits<5> Vd;
   6367   bits<5> Vn;
   6368   bits<5> Vm;
   6369   let Inst{31}    = 0;
   6370   let Inst{30}    = Q;
   6371   let Inst{29-21} = 0b001110000;
   6372   let Inst{20-16} = Vm;
   6373   let Inst{15}    = 0;
   6374   let Inst{14-13} = len;
   6375   let Inst{12}    = op;
   6376   let Inst{11-10} = 0b00;
   6377   let Inst{9-5}   = Vn;
   6378   let Inst{4-0}   = Vd;
   6379 }
   6380 
   6381 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   6382 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
   6383                           RegisterOperand listtype, string asm, string kind>
   6384   : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
   6385        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
   6386     Sched<[WriteV]> {
   6387   bits<5> Vd;
   6388   bits<5> Vn;
   6389   bits<5> Vm;
   6390   let Inst{31}    = 0;
   6391   let Inst{30}    = Q;
   6392   let Inst{29-21} = 0b001110000;
   6393   let Inst{20-16} = Vm;
   6394   let Inst{15}    = 0;
   6395   let Inst{14-13} = len;
   6396   let Inst{12}    = op;
   6397   let Inst{11-10} = 0b00;
   6398   let Inst{9-5}   = Vn;
   6399   let Inst{4-0}   = Vd;
   6400 }
   6401 
   6402 class SIMDTableLookupAlias<string asm, Instruction inst,
   6403                           RegisterOperand vectype, RegisterOperand listtype>
   6404     : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
   6405                 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
   6406 
   6407 multiclass SIMDTableLookup<bit op, string asm> {
   6408   def v8i8One   : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
   6409                                       asm, ".8b">;
   6410   def v8i8Two   : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
   6411                                       asm, ".8b">;
   6412   def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
   6413                                       asm, ".8b">;
   6414   def v8i8Four  : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
   6415                                       asm, ".8b">;
   6416   def v16i8One  : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
   6417                                       asm, ".16b">;
   6418   def v16i8Two  : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
   6419                                       asm, ".16b">;
   6420   def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
   6421                                       asm, ".16b">;
   6422   def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
   6423                                       asm, ".16b">;
   6424 
   6425   def : SIMDTableLookupAlias<asm # ".8b",
   6426                          !cast<Instruction>(NAME#"v8i8One"),
   6427                          V64, VecListOne128>;
   6428   def : SIMDTableLookupAlias<asm # ".8b",
   6429                          !cast<Instruction>(NAME#"v8i8Two"),
   6430                          V64, VecListTwo128>;
   6431   def : SIMDTableLookupAlias<asm # ".8b",
   6432                          !cast<Instruction>(NAME#"v8i8Three"),
   6433                          V64, VecListThree128>;
   6434   def : SIMDTableLookupAlias<asm # ".8b",
   6435                          !cast<Instruction>(NAME#"v8i8Four"),
   6436                          V64, VecListFour128>;
   6437   def : SIMDTableLookupAlias<asm # ".16b",
   6438                          !cast<Instruction>(NAME#"v16i8One"),
   6439                          V128, VecListOne128>;
   6440   def : SIMDTableLookupAlias<asm # ".16b",
   6441                          !cast<Instruction>(NAME#"v16i8Two"),
   6442                          V128, VecListTwo128>;
   6443   def : SIMDTableLookupAlias<asm # ".16b",
   6444                          !cast<Instruction>(NAME#"v16i8Three"),
   6445                          V128, VecListThree128>;
   6446   def : SIMDTableLookupAlias<asm # ".16b",
   6447                          !cast<Instruction>(NAME#"v16i8Four"),
   6448                          V128, VecListFour128>;
   6449 }
   6450 
   6451 multiclass SIMDTableLookupTied<bit op, string asm> {
   6452   def v8i8One   : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
   6453                                       asm, ".8b">;
   6454   def v8i8Two   : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
   6455                                       asm, ".8b">;
   6456   def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
   6457                                       asm, ".8b">;
   6458   def v8i8Four  : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
   6459                                       asm, ".8b">;
   6460   def v16i8One  : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
   6461                                       asm, ".16b">;
   6462   def v16i8Two  : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
   6463                                       asm, ".16b">;
   6464   def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
   6465                                       asm, ".16b">;
   6466   def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
   6467                                       asm, ".16b">;
   6468 
   6469   def : SIMDTableLookupAlias<asm # ".8b",
   6470                          !cast<Instruction>(NAME#"v8i8One"),
   6471                          V64, VecListOne128>;
   6472   def : SIMDTableLookupAlias<asm # ".8b",
   6473                          !cast<Instruction>(NAME#"v8i8Two"),
   6474                          V64, VecListTwo128>;
   6475   def : SIMDTableLookupAlias<asm # ".8b",
   6476                          !cast<Instruction>(NAME#"v8i8Three"),
   6477                          V64, VecListThree128>;
   6478   def : SIMDTableLookupAlias<asm # ".8b",
   6479                          !cast<Instruction>(NAME#"v8i8Four"),
   6480                          V64, VecListFour128>;
   6481   def : SIMDTableLookupAlias<asm # ".16b",
   6482                          !cast<Instruction>(NAME#"v16i8One"),
   6483                          V128, VecListOne128>;
   6484   def : SIMDTableLookupAlias<asm # ".16b",
   6485                          !cast<Instruction>(NAME#"v16i8Two"),
   6486                          V128, VecListTwo128>;
   6487   def : SIMDTableLookupAlias<asm # ".16b",
   6488                          !cast<Instruction>(NAME#"v16i8Three"),
   6489                          V128, VecListThree128>;
   6490   def : SIMDTableLookupAlias<asm # ".16b",
   6491                          !cast<Instruction>(NAME#"v16i8Four"),
   6492                          V128, VecListFour128>;
   6493 }
   6494 
   6495 
   6496 //----------------------------------------------------------------------------
   6497 // AdvSIMD scalar CPY
   6498 //----------------------------------------------------------------------------
   6499 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   6500 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
   6501                         string kind, Operand idxtype>
   6502   : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
   6503        "{\t$dst, $src" # kind # "$idx" #
   6504        "|\t$dst, $src$idx}", "", []>,
   6505     Sched<[WriteV]> {
   6506   bits<5> dst;
   6507   bits<5> src;
   6508   let Inst{31-21} = 0b01011110000;
   6509   let Inst{15-10} = 0b000001;
   6510   let Inst{9-5}   = src;
   6511   let Inst{4-0}   = dst;
   6512 }
   6513 
   6514 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
   6515       RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
   6516     : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
   6517                     # "|\t$dst, $src$index}",
   6518                 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
   6519 
   6520 
   6521 multiclass SIMDScalarCPY<string asm> {
   6522   def i8  : BaseSIMDScalarCPY<FPR8,  V128, ".b", VectorIndexB> {
   6523     bits<4> idx;
   6524     let Inst{20-17} = idx;
   6525     let Inst{16} = 1;
   6526   }
   6527   def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
   6528     bits<3> idx;
   6529     let Inst{20-18} = idx;
   6530     let Inst{17-16} = 0b10;
   6531   }
   6532   def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
   6533     bits<2> idx;
   6534     let Inst{20-19} = idx;
   6535     let Inst{18-16} = 0b100;
   6536   }
   6537   def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
   6538     bits<1> idx;
   6539     let Inst{20} = idx;
   6540     let Inst{19-16} = 0b1000;
   6541   }
   6542 
   6543   def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
   6544                                                           VectorIndexD:$idx)))),
   6545             (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
   6546 
   6547   // 'DUP' mnemonic aliases.
   6548   def : SIMDScalarCPYAlias<"dup", ".b",
   6549                            !cast<Instruction>(NAME#"i8"),
   6550                            FPR8, V128, VectorIndexB>;
   6551   def : SIMDScalarCPYAlias<"dup", ".h",
   6552                            !cast<Instruction>(NAME#"i16"),
   6553                            FPR16, V128, VectorIndexH>;
   6554   def : SIMDScalarCPYAlias<"dup", ".s",
   6555                            !cast<Instruction>(NAME#"i32"),
   6556                            FPR32, V128, VectorIndexS>;
   6557   def : SIMDScalarCPYAlias<"dup", ".d",
   6558                            !cast<Instruction>(NAME#"i64"),
   6559                            FPR64, V128, VectorIndexD>;
   6560 }
   6561 
   6562 //----------------------------------------------------------------------------
   6563 // AdvSIMD modified immediate instructions
   6564 //----------------------------------------------------------------------------
   6565 
   6566 class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,
   6567                           string asm, string op_string,
   6568                           string cstr, list<dag> pattern>
   6569   : I<oops, iops, asm, op_string, cstr, pattern>,
   6570     Sched<[WriteV]> {
   6571   bits<5> Rd;
   6572   bits<8> imm8;
   6573   let Inst{31}    = 0;
   6574   let Inst{30}    = Q;
   6575   let Inst{29}    = op;
   6576   let Inst{28-19} = 0b0111100000;
   6577   let Inst{18-16} = imm8{7-5};
   6578   let Inst{11} = op2;
   6579   let Inst{10} = 1;
   6580   let Inst{9-5}   = imm8{4-0};
   6581   let Inst{4-0}   = Rd;
   6582 }
   6583 
   6584 class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,
   6585                                 Operand immtype, dag opt_shift_iop,
   6586                                 string opt_shift, string asm, string kind,
   6587                                 list<dag> pattern>
   6588   : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),
   6589                         !con((ins immtype:$imm8), opt_shift_iop), asm,
   6590                         "{\t$Rd" # kind # ", $imm8" # opt_shift #
   6591                         "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
   6592                         "", pattern> {
   6593   let DecoderMethod = "DecodeModImmInstruction";
   6594 }
   6595 
   6596 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
   6597                                 Operand immtype, dag opt_shift_iop,
   6598                                 string opt_shift, string asm, string kind,
   6599                                 list<dag> pattern>
   6600   : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),
   6601                         !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
   6602                         asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
   6603                              "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
   6604                         "$Rd = $dst", pattern> {
   6605   let DecoderMethod = "DecodeModImmTiedInstruction";
   6606 }
   6607 
   6608 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
   6609                                      RegisterOperand vectype, string asm,
   6610                                      string kind, list<dag> pattern>
   6611   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
   6612                               (ins logical_vec_shift:$shift),
   6613                               "$shift", asm, kind, pattern> {
   6614   bits<2> shift;
   6615   let Inst{15}    = b15_b12{1};
   6616   let Inst{14-13} = shift;
   6617   let Inst{12}    = b15_b12{0};
   6618 }
   6619 
   6620 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
   6621                                      RegisterOperand vectype, string asm,
   6622                                      string kind, list<dag> pattern>
   6623   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
   6624                               (ins logical_vec_shift:$shift),
   6625                               "$shift", asm, kind, pattern> {
   6626   bits<2> shift;
   6627   let Inst{15}    = b15_b12{1};
   6628   let Inst{14-13} = shift;
   6629   let Inst{12}    = b15_b12{0};
   6630 }
   6631 
   6632 
   6633 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
   6634                                          RegisterOperand vectype, string asm,
   6635                                          string kind, list<dag> pattern>
   6636   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
   6637                               (ins logical_vec_hw_shift:$shift),
   6638                               "$shift", asm, kind, pattern> {
   6639   bits<2> shift;
   6640   let Inst{15} = b15_b12{1};
   6641   let Inst{14} = 0;
   6642   let Inst{13} = shift{0};
   6643   let Inst{12} = b15_b12{0};
   6644 }
   6645 
   6646 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
   6647                                          RegisterOperand vectype, string asm,
   6648                                          string kind, list<dag> pattern>
   6649   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
   6650                               (ins logical_vec_hw_shift:$shift),
   6651                               "$shift", asm, kind, pattern> {
   6652   bits<2> shift;
   6653   let Inst{15} = b15_b12{1};
   6654   let Inst{14} = 0;
   6655   let Inst{13} = shift{0};
   6656   let Inst{12} = b15_b12{0};
   6657 }
   6658 
   6659 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
   6660                                       string asm> {
   6661   def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
   6662                                                  asm, ".4h", []>;
   6663   def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
   6664                                                  asm, ".8h", []>;
   6665 
   6666   def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
   6667                                              asm, ".2s", []>;
   6668   def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
   6669                                              asm, ".4s", []>;
   6670 }
   6671 
   6672 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
   6673                                       bits<2> w_cmode, string asm,
   6674                                       SDNode OpNode> {
   6675   def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
   6676                                                  asm, ".4h",
   6677              [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
   6678                                              imm0_255:$imm8,
   6679                                              (i32 imm:$shift)))]>;
   6680   def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
   6681                                                  asm, ".8h",
   6682              [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
   6683                                               imm0_255:$imm8,
   6684                                               (i32 imm:$shift)))]>;
   6685 
   6686   def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
   6687                                              asm, ".2s",
   6688              [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
   6689                                              imm0_255:$imm8,
   6690                                              (i32 imm:$shift)))]>;
   6691   def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
   6692                                              asm, ".4s",
   6693              [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
   6694                                               imm0_255:$imm8,
   6695                                               (i32 imm:$shift)))]>;
   6696 }
   6697 
   6698 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
   6699                              RegisterOperand vectype, string asm,
   6700                              string kind, list<dag> pattern>
   6701   : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
   6702                               (ins move_vec_shift:$shift),
   6703                               "$shift", asm, kind, pattern> {
   6704   bits<1> shift;
   6705   let Inst{15-13} = cmode{3-1};
   6706   let Inst{12}    = shift;
   6707 }
   6708 
   6709 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,
   6710                                    RegisterOperand vectype,
   6711                                    Operand imm_type, string asm,
   6712                                    string kind, list<dag> pattern>
   6713   : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",
   6714                               asm, kind, pattern> {
   6715   let Inst{15-12} = cmode;
   6716 }
   6717 
   6718 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
   6719                                    list<dag> pattern>
   6720   : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
   6721                         "\t$Rd, $imm8", "", pattern> {
   6722   let Inst{15-12} = cmode;
   6723   let DecoderMethod = "DecodeModImmInstruction";
   6724 }
   6725 
   6726 //----------------------------------------------------------------------------
   6727 // AdvSIMD indexed element
   6728 //----------------------------------------------------------------------------
   6729 
   6730 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   6731 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
   6732                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
   6733                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
   6734                       string apple_kind, string dst_kind, string lhs_kind,
   6735                       string rhs_kind, list<dag> pattern>
   6736   : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
   6737       asm,
   6738       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
   6739       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
   6740     Sched<[WriteV]> {
   6741   bits<5> Rd;
   6742   bits<5> Rn;
   6743   bits<5> Rm;
   6744 
   6745   let Inst{31}    = 0;
   6746   let Inst{30}    = Q;
   6747   let Inst{29}    = U;
   6748   let Inst{28}    = Scalar;
   6749   let Inst{27-24} = 0b1111;
   6750   let Inst{23-22} = size;
   6751   // Bit 21 must be set by the derived class.
   6752   let Inst{20-16} = Rm;
   6753   let Inst{15-12} = opc;
   6754   // Bit 11 must be set by the derived class.
   6755   let Inst{10}    = 0;
   6756   let Inst{9-5}   = Rn;
   6757   let Inst{4-0}   = Rd;
   6758 }
   6759 
   6760 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   6761 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
   6762                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
   6763                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
   6764                       string apple_kind, string dst_kind, string lhs_kind,
   6765                       string rhs_kind, list<dag> pattern>
   6766   : I<(outs dst_reg:$dst),
   6767       (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
   6768       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
   6769       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
   6770     Sched<[WriteV]> {
   6771   bits<5> Rd;
   6772   bits<5> Rn;
   6773   bits<5> Rm;
   6774 
   6775   let Inst{31}    = 0;
   6776   let Inst{30}    = Q;
   6777   let Inst{29}    = U;
   6778   let Inst{28}    = Scalar;
   6779   let Inst{27-24} = 0b1111;
   6780   let Inst{23-22} = size;
   6781   // Bit 21 must be set by the derived class.
   6782   let Inst{20-16} = Rm;
   6783   let Inst{15-12} = opc;
   6784   // Bit 11 must be set by the derived class.
   6785   let Inst{10}    = 0;
   6786   let Inst{9-5}   = Rn;
   6787   let Inst{4-0}   = Rd;
   6788 }
   6789 
   6790 multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
   6791                          SDPatternOperator OpNode> {
   6792   let Predicates = [HasNEON, HasFullFP16] in {
   6793   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,
   6794                                       V64, V64,
   6795                                       V128_lo, VectorIndexH,
   6796                                       asm, ".4h", ".4h", ".4h", ".h",
   6797     [(set (v4f16 V64:$Rd),
   6798         (OpNode (v4f16 V64:$Rn),
   6799          (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   6800     bits<3> idx;
   6801     let Inst{11} = idx{2};
   6802     let Inst{21} = idx{1};
   6803     let Inst{20} = idx{0};
   6804   }
   6805 
   6806   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
   6807                                       V128, V128,
   6808                                       V128_lo, VectorIndexH,
   6809                                       asm, ".8h", ".8h", ".8h", ".h",
   6810     [(set (v8f16 V128:$Rd),
   6811         (OpNode (v8f16 V128:$Rn),
   6812          (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   6813     bits<3> idx;
   6814     let Inst{11} = idx{2};
   6815     let Inst{21} = idx{1};
   6816     let Inst{20} = idx{0};
   6817   }
   6818   } // Predicates = [HasNEON, HasFullFP16]
   6819 
   6820   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
   6821                                       V64, V64,
   6822                                       V128, VectorIndexS,
   6823                                       asm, ".2s", ".2s", ".2s", ".s",
   6824     [(set (v2f32 V64:$Rd),
   6825         (OpNode (v2f32 V64:$Rn),
   6826          (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
   6827     bits<2> idx;
   6828     let Inst{11} = idx{1};
   6829     let Inst{21} = idx{0};
   6830   }
   6831 
   6832   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
   6833                                       V128, V128,
   6834                                       V128, VectorIndexS,
   6835                                       asm, ".4s", ".4s", ".4s", ".s",
   6836     [(set (v4f32 V128:$Rd),
   6837         (OpNode (v4f32 V128:$Rn),
   6838          (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
   6839     bits<2> idx;
   6840     let Inst{11} = idx{1};
   6841     let Inst{21} = idx{0};
   6842   }
   6843 
   6844   def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
   6845                                       V128, V128,
   6846                                       V128, VectorIndexD,
   6847                                       asm, ".2d", ".2d", ".2d", ".d",
   6848     [(set (v2f64 V128:$Rd),
   6849         (OpNode (v2f64 V128:$Rn),
   6850          (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
   6851     bits<1> idx;
   6852     let Inst{11} = idx{0};
   6853     let Inst{21} = 0;
   6854   }
   6855 
   6856   let Predicates = [HasNEON, HasFullFP16] in {
   6857   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,
   6858                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
   6859                                       asm, ".h", "", "", ".h",
   6860     [(set (f16 FPR16Op:$Rd),
   6861           (OpNode (f16 FPR16Op:$Rn),
   6862                   (f16 (vector_extract (v8f16 V128_lo:$Rm),
   6863                                        VectorIndexH:$idx))))]> {
   6864     bits<3> idx;
   6865     let Inst{11} = idx{2};
   6866     let Inst{21} = idx{1};
   6867     let Inst{20} = idx{0};
   6868   }
   6869   } // Predicates = [HasNEON, HasFullFP16]
   6870 
   6871   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
   6872                                       FPR32Op, FPR32Op, V128, VectorIndexS,
   6873                                       asm, ".s", "", "", ".s",
   6874     [(set (f32 FPR32Op:$Rd),
   6875           (OpNode (f32 FPR32Op:$Rn),
   6876                   (f32 (vector_extract (v4f32 V128:$Rm),
   6877                                        VectorIndexS:$idx))))]> {
   6878     bits<2> idx;
   6879     let Inst{11} = idx{1};
   6880     let Inst{21} = idx{0};
   6881   }
   6882 
   6883   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
   6884                                       FPR64Op, FPR64Op, V128, VectorIndexD,
   6885                                       asm, ".d", "", "", ".d",
   6886     [(set (f64 FPR64Op:$Rd),
   6887           (OpNode (f64 FPR64Op:$Rn),
   6888                   (f64 (vector_extract (v2f64 V128:$Rm),
   6889                                        VectorIndexD:$idx))))]> {
   6890     bits<1> idx;
   6891     let Inst{11} = idx{0};
   6892     let Inst{21} = 0;
   6893   }
   6894 }
   6895 
   6896 multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
   6897   // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
   6898   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
   6899                            (AArch64duplane32 (v4f32 V128:$Rm),
   6900                                            VectorIndexS:$idx))),
   6901             (!cast<Instruction>(INST # v2i32_indexed)
   6902                 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
   6903   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
   6904                            (AArch64dup (f32 FPR32Op:$Rm)))),
   6905             (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
   6906                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
   6907 
   6908 
   6909   // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
   6910   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
   6911                            (AArch64duplane32 (v4f32 V128:$Rm),
   6912                                            VectorIndexS:$idx))),
   6913             (!cast<Instruction>(INST # "v4i32_indexed")
   6914                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
   6915   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
   6916                            (AArch64dup (f32 FPR32Op:$Rm)))),
   6917             (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
   6918                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
   6919 
   6920   // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
   6921   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
   6922                            (AArch64duplane64 (v2f64 V128:$Rm),
   6923                                            VectorIndexD:$idx))),
   6924             (!cast<Instruction>(INST # "v2i64_indexed")
   6925                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
   6926   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
   6927                            (AArch64dup (f64 FPR64Op:$Rm)))),
   6928             (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
   6929                 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
   6930 
   6931   // 2 variants for 32-bit scalar version: extract from .2s or from .4s
   6932   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
   6933                          (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
   6934             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
   6935                 V128:$Rm, VectorIndexS:$idx)>;
   6936   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
   6937                          (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
   6938             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
   6939                 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
   6940 
   6941   // 1 variant for 64-bit scalar version: extract from .1d or from .2d
   6942   def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
   6943                          (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
   6944             (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
   6945                 V128:$Rm, VectorIndexD:$idx)>;
   6946 }
   6947 
   6948 multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
   6949   let Predicates = [HasNEON, HasFullFP16] in {
   6950   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,
   6951                                           V128_lo, VectorIndexH,
   6952                                           asm, ".4h", ".4h", ".4h", ".h", []> {
   6953     bits<3> idx;
   6954     let Inst{11} = idx{2};
   6955     let Inst{21} = idx{1};
   6956     let Inst{20} = idx{0};
   6957   }
   6958 
   6959   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
   6960                                           V128, V128,
   6961                                           V128_lo, VectorIndexH,
   6962                                           asm, ".8h", ".8h", ".8h", ".h", []> {
   6963     bits<3> idx;
   6964     let Inst{11} = idx{2};
   6965     let Inst{21} = idx{1};
   6966     let Inst{20} = idx{0};
   6967   }
   6968   } // Predicates = [HasNEON, HasFullFP16]
   6969 
   6970   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
   6971                                           V128, VectorIndexS,
   6972                                           asm, ".2s", ".2s", ".2s", ".s", []> {
   6973     bits<2> idx;
   6974     let Inst{11} = idx{1};
   6975     let Inst{21} = idx{0};
   6976   }
   6977 
   6978   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
   6979                                       V128, V128,
   6980                                       V128, VectorIndexS,
   6981                                       asm, ".4s", ".4s", ".4s", ".s", []> {
   6982     bits<2> idx;
   6983     let Inst{11} = idx{1};
   6984     let Inst{21} = idx{0};
   6985   }
   6986 
   6987   def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
   6988                                       V128, V128,
   6989                                       V128, VectorIndexD,
   6990                                       asm, ".2d", ".2d", ".2d", ".d", []> {
   6991     bits<1> idx;
   6992     let Inst{11} = idx{0};
   6993     let Inst{21} = 0;
   6994   }
   6995 
   6996   let Predicates = [HasNEON, HasFullFP16] in {
   6997   def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,
   6998                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
   6999                                       asm, ".h", "", "", ".h", []> {
   7000     bits<3> idx;
   7001     let Inst{11} = idx{2};
   7002     let Inst{21} = idx{1};
   7003     let Inst{20} = idx{0};
   7004   }
   7005   } // Predicates = [HasNEON, HasFullFP16]
   7006 
   7007   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
   7008                                       FPR32Op, FPR32Op, V128, VectorIndexS,
   7009                                       asm, ".s", "", "", ".s", []> {
   7010     bits<2> idx;
   7011     let Inst{11} = idx{1};
   7012     let Inst{21} = idx{0};
   7013   }
   7014 
   7015   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
   7016                                       FPR64Op, FPR64Op, V128, VectorIndexD,
   7017                                       asm, ".d", "", "", ".d", []> {
   7018     bits<1> idx;
   7019     let Inst{11} = idx{0};
   7020     let Inst{21} = 0;
   7021   }
   7022 }
   7023 
   7024 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
   7025                          SDPatternOperator OpNode> {
   7026   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
   7027                                       V128_lo, VectorIndexH,
   7028                                       asm, ".4h", ".4h", ".4h", ".h",
   7029     [(set (v4i16 V64:$Rd),
   7030         (OpNode (v4i16 V64:$Rn),
   7031          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7032     bits<3> idx;
   7033     let Inst{11} = idx{2};
   7034     let Inst{21} = idx{1};
   7035     let Inst{20} = idx{0};
   7036   }
   7037 
   7038   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
   7039                                       V128, V128,
   7040                                       V128_lo, VectorIndexH,
   7041                                       asm, ".8h", ".8h", ".8h", ".h",
   7042     [(set (v8i16 V128:$Rd),
   7043        (OpNode (v8i16 V128:$Rn),
   7044          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7045     bits<3> idx;
   7046     let Inst{11} = idx{2};
   7047     let Inst{21} = idx{1};
   7048     let Inst{20} = idx{0};
   7049   }
   7050 
   7051   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
   7052                                       V64, V64,
   7053                                       V128, VectorIndexS,
   7054                                       asm, ".2s", ".2s", ".2s",  ".s",
   7055     [(set (v2i32 V64:$Rd),
   7056        (OpNode (v2i32 V64:$Rn),
   7057           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7058     bits<2> idx;
   7059     let Inst{11} = idx{1};
   7060     let Inst{21} = idx{0};
   7061   }
   7062 
   7063   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
   7064                                       V128, V128,
   7065                                       V128, VectorIndexS,
   7066                                       asm, ".4s", ".4s", ".4s", ".s",
   7067     [(set (v4i32 V128:$Rd),
   7068        (OpNode (v4i32 V128:$Rn),
   7069           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7070     bits<2> idx;
   7071     let Inst{11} = idx{1};
   7072     let Inst{21} = idx{0};
   7073   }
   7074 
   7075   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
   7076                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
   7077                                       asm, ".h", "", "", ".h", []> {
   7078     bits<3> idx;
   7079     let Inst{11} = idx{2};
   7080     let Inst{21} = idx{1};
   7081     let Inst{20} = idx{0};
   7082   }
   7083 
   7084   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
   7085                                       FPR32Op, FPR32Op, V128, VectorIndexS,
   7086                                       asm, ".s", "", "", ".s",
   7087       [(set (i32 FPR32Op:$Rd),
   7088             (OpNode FPR32Op:$Rn,
   7089                     (i32 (vector_extract (v4i32 V128:$Rm),
   7090                                          VectorIndexS:$idx))))]> {
   7091     bits<2> idx;
   7092     let Inst{11} = idx{1};
   7093     let Inst{21} = idx{0};
   7094   }
   7095 }
   7096 
   7097 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
   7098                                SDPatternOperator OpNode> {
   7099   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
   7100                                       V64, V64,
   7101                                       V128_lo, VectorIndexH,
   7102                                       asm, ".4h", ".4h", ".4h", ".h",
   7103     [(set (v4i16 V64:$Rd),
   7104         (OpNode (v4i16 V64:$Rn),
   7105          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7106     bits<3> idx;
   7107     let Inst{11} = idx{2};
   7108     let Inst{21} = idx{1};
   7109     let Inst{20} = idx{0};
   7110   }
   7111 
   7112   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
   7113                                       V128, V128,
   7114                                       V128_lo, VectorIndexH,
   7115                                       asm, ".8h", ".8h", ".8h", ".h",
   7116     [(set (v8i16 V128:$Rd),
   7117        (OpNode (v8i16 V128:$Rn),
   7118          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7119     bits<3> idx;
   7120     let Inst{11} = idx{2};
   7121     let Inst{21} = idx{1};
   7122     let Inst{20} = idx{0};
   7123   }
   7124 
   7125   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
   7126                                       V64, V64,
   7127                                       V128, VectorIndexS,
   7128                                       asm, ".2s", ".2s", ".2s", ".s",
   7129     [(set (v2i32 V64:$Rd),
   7130        (OpNode (v2i32 V64:$Rn),
   7131           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7132     bits<2> idx;
   7133     let Inst{11} = idx{1};
   7134     let Inst{21} = idx{0};
   7135   }
   7136 
   7137   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
   7138                                       V128, V128,
   7139                                       V128, VectorIndexS,
   7140                                       asm, ".4s", ".4s", ".4s", ".s",
   7141     [(set (v4i32 V128:$Rd),
   7142        (OpNode (v4i32 V128:$Rn),
   7143           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7144     bits<2> idx;
   7145     let Inst{11} = idx{1};
   7146     let Inst{21} = idx{0};
   7147   }
   7148 }
   7149 
   7150 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
   7151                                    SDPatternOperator OpNode> {
   7152   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
   7153                                           V128_lo, VectorIndexH,
   7154                                           asm, ".4h", ".4h", ".4h", ".h",
   7155     [(set (v4i16 V64:$dst),
   7156         (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
   7157          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7158     bits<3> idx;
   7159     let Inst{11} = idx{2};
   7160     let Inst{21} = idx{1};
   7161     let Inst{20} = idx{0};
   7162   }
   7163 
   7164   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
   7165                                       V128, V128,
   7166                                       V128_lo, VectorIndexH,
   7167                                       asm, ".8h", ".8h", ".8h", ".h",
   7168     [(set (v8i16 V128:$dst),
   7169        (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
   7170          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7171     bits<3> idx;
   7172     let Inst{11} = idx{2};
   7173     let Inst{21} = idx{1};
   7174     let Inst{20} = idx{0};
   7175   }
   7176 
   7177   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
   7178                                       V64, V64,
   7179                                       V128, VectorIndexS,
   7180                                       asm, ".2s", ".2s", ".2s", ".s",
   7181     [(set (v2i32 V64:$dst),
   7182        (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
   7183           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7184     bits<2> idx;
   7185     let Inst{11} = idx{1};
   7186     let Inst{21} = idx{0};
   7187   }
   7188 
   7189   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
   7190                                       V128, V128,
   7191                                       V128, VectorIndexS,
   7192                                       asm, ".4s", ".4s", ".4s", ".s",
   7193     [(set (v4i32 V128:$dst),
   7194        (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
   7195           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7196     bits<2> idx;
   7197     let Inst{11} = idx{1};
   7198     let Inst{21} = idx{0};
   7199   }
   7200 }
   7201 
   7202 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
   7203                              SDPatternOperator OpNode> {
   7204   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
   7205                                       V128, V64,
   7206                                       V128_lo, VectorIndexH,
   7207                                       asm, ".4s", ".4s", ".4h", ".h",
   7208     [(set (v4i32 V128:$Rd),
   7209         (OpNode (v4i16 V64:$Rn),
   7210          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7211     bits<3> idx;
   7212     let Inst{11} = idx{2};
   7213     let Inst{21} = idx{1};
   7214     let Inst{20} = idx{0};
   7215   }
   7216 
   7217   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
   7218                                       V128, V128,
   7219                                       V128_lo, VectorIndexH,
   7220                                       asm#"2", ".4s", ".4s", ".8h", ".h",
   7221     [(set (v4i32 V128:$Rd),
   7222           (OpNode (extract_high_v8i16 V128:$Rn),
   7223                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   7224                                                       VectorIndexH:$idx))))]> {
   7225 
   7226     bits<3> idx;
   7227     let Inst{11} = idx{2};
   7228     let Inst{21} = idx{1};
   7229     let Inst{20} = idx{0};
   7230   }
   7231 
   7232   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
   7233                                       V128, V64,
   7234                                       V128, VectorIndexS,
   7235                                       asm, ".2d", ".2d", ".2s", ".s",
   7236     [(set (v2i64 V128:$Rd),
   7237         (OpNode (v2i32 V64:$Rn),
   7238          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7239     bits<2> idx;
   7240     let Inst{11} = idx{1};
   7241     let Inst{21} = idx{0};
   7242   }
   7243 
   7244   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
   7245                                       V128, V128,
   7246                                       V128, VectorIndexS,
   7247                                       asm#"2", ".2d", ".2d", ".4s", ".s",
   7248     [(set (v2i64 V128:$Rd),
   7249           (OpNode (extract_high_v4i32 V128:$Rn),
   7250                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
   7251                                                       VectorIndexS:$idx))))]> {
   7252     bits<2> idx;
   7253     let Inst{11} = idx{1};
   7254     let Inst{21} = idx{0};
   7255   }
   7256 
   7257   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
   7258                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
   7259                                       asm, ".h", "", "", ".h", []> {
   7260     bits<3> idx;
   7261     let Inst{11} = idx{2};
   7262     let Inst{21} = idx{1};
   7263     let Inst{20} = idx{0};
   7264   }
   7265 
   7266   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
   7267                                       FPR64Op, FPR32Op, V128, VectorIndexS,
   7268                                       asm, ".s", "", "", ".s", []> {
   7269     bits<2> idx;
   7270     let Inst{11} = idx{1};
   7271     let Inst{21} = idx{0};
   7272   }
   7273 }
   7274 
   7275 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
   7276                                        SDPatternOperator Accum> {
   7277   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
   7278                                       V128, V64,
   7279                                       V128_lo, VectorIndexH,
   7280                                       asm, ".4s", ".4s", ".4h", ".h",
   7281     [(set (v4i32 V128:$dst),
   7282           (Accum (v4i32 V128:$Rd),
   7283                  (v4i32 (int_aarch64_neon_sqdmull
   7284                              (v4i16 V64:$Rn),
   7285                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   7286                                                     VectorIndexH:$idx))))))]> {
   7287     bits<3> idx;
   7288     let Inst{11} = idx{2};
   7289     let Inst{21} = idx{1};
   7290     let Inst{20} = idx{0};
   7291   }
   7292 
   7293   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
   7294   // intermediate EXTRACT_SUBREG would be untyped.
   7295   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
   7296                 (i32 (vector_extract (v4i32
   7297                          (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
   7298                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   7299                                                     VectorIndexH:$idx)))),
   7300                          (i64 0))))),
   7301             (EXTRACT_SUBREG
   7302                 (!cast<Instruction>(NAME # v4i16_indexed)
   7303                     (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
   7304                     V128_lo:$Rm, VectorIndexH:$idx),
   7305                 ssub)>;
   7306 
   7307   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
   7308                                       V128, V128,
   7309                                       V128_lo, VectorIndexH,
   7310                                       asm#"2", ".4s", ".4s", ".8h", ".h",
   7311     [(set (v4i32 V128:$dst),
   7312           (Accum (v4i32 V128:$Rd),
   7313                  (v4i32 (int_aarch64_neon_sqdmull
   7314                             (extract_high_v8i16 V128:$Rn),
   7315                             (extract_high_v8i16
   7316                                 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   7317                                                 VectorIndexH:$idx))))))]> {
   7318     bits<3> idx;
   7319     let Inst{11} = idx{2};
   7320     let Inst{21} = idx{1};
   7321     let Inst{20} = idx{0};
   7322   }
   7323 
   7324   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
   7325                                       V128, V64,
   7326                                       V128, VectorIndexS,
   7327                                       asm, ".2d", ".2d", ".2s", ".s",
   7328     [(set (v2i64 V128:$dst),
   7329         (Accum (v2i64 V128:$Rd),
   7330                (v2i64 (int_aarch64_neon_sqdmull
   7331                           (v2i32 V64:$Rn),
   7332                           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
   7333                                                  VectorIndexS:$idx))))))]> {
   7334     bits<2> idx;
   7335     let Inst{11} = idx{1};
   7336     let Inst{21} = idx{0};
   7337   }
   7338 
   7339   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
   7340                                       V128, V128,
   7341                                       V128, VectorIndexS,
   7342                                       asm#"2", ".2d", ".2d", ".4s", ".s",
   7343     [(set (v2i64 V128:$dst),
   7344           (Accum (v2i64 V128:$Rd),
   7345                  (v2i64 (int_aarch64_neon_sqdmull
   7346                             (extract_high_v4i32 V128:$Rn),
   7347                             (extract_high_v4i32
   7348                                 (AArch64duplane32 (v4i32 V128:$Rm),
   7349                                                 VectorIndexS:$idx))))))]> {
   7350     bits<2> idx;
   7351     let Inst{11} = idx{1};
   7352     let Inst{21} = idx{0};
   7353   }
   7354 
   7355   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
   7356                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
   7357                                       asm, ".h", "", "", ".h", []> {
   7358     bits<3> idx;
   7359     let Inst{11} = idx{2};
   7360     let Inst{21} = idx{1};
   7361     let Inst{20} = idx{0};
   7362   }
   7363 
   7364 
   7365   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
   7366                                       FPR64Op, FPR32Op, V128, VectorIndexS,
   7367                                       asm, ".s", "", "", ".s",
   7368     [(set (i64 FPR64Op:$dst),
   7369           (Accum (i64 FPR64Op:$Rd),
   7370                  (i64 (int_aarch64_neon_sqdmulls_scalar
   7371                             (i32 FPR32Op:$Rn),
   7372                             (i32 (vector_extract (v4i32 V128:$Rm),
   7373                                                  VectorIndexS:$idx))))))]> {
   7374 
   7375     bits<2> idx;
   7376     let Inst{11} = idx{1};
   7377     let Inst{21} = idx{0};
   7378   }
   7379 }
   7380 
   7381 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
   7382                                    SDPatternOperator OpNode> {
   7383   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
   7384   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
   7385                                       V128, V64,
   7386                                       V128_lo, VectorIndexH,
   7387                                       asm, ".4s", ".4s", ".4h", ".h",
   7388     [(set (v4i32 V128:$Rd),
   7389         (OpNode (v4i16 V64:$Rn),
   7390          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7391     bits<3> idx;
   7392     let Inst{11} = idx{2};
   7393     let Inst{21} = idx{1};
   7394     let Inst{20} = idx{0};
   7395   }
   7396 
   7397   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
   7398                                       V128, V128,
   7399                                       V128_lo, VectorIndexH,
   7400                                       asm#"2", ".4s", ".4s", ".8h", ".h",
   7401     [(set (v4i32 V128:$Rd),
   7402           (OpNode (extract_high_v8i16 V128:$Rn),
   7403                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   7404                                                       VectorIndexH:$idx))))]> {
   7405 
   7406     bits<3> idx;
   7407     let Inst{11} = idx{2};
   7408     let Inst{21} = idx{1};
   7409     let Inst{20} = idx{0};
   7410   }
   7411 
   7412   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
   7413                                       V128, V64,
   7414                                       V128, VectorIndexS,
   7415                                       asm, ".2d", ".2d", ".2s", ".s",
   7416     [(set (v2i64 V128:$Rd),
   7417         (OpNode (v2i32 V64:$Rn),
   7418          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7419     bits<2> idx;
   7420     let Inst{11} = idx{1};
   7421     let Inst{21} = idx{0};
   7422   }
   7423 
   7424   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
   7425                                       V128, V128,
   7426                                       V128, VectorIndexS,
   7427                                       asm#"2", ".2d", ".2d", ".4s", ".s",
   7428     [(set (v2i64 V128:$Rd),
   7429           (OpNode (extract_high_v4i32 V128:$Rn),
   7430                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
   7431                                                       VectorIndexS:$idx))))]> {
   7432     bits<2> idx;
   7433     let Inst{11} = idx{1};
   7434     let Inst{21} = idx{0};
   7435   }
   7436   }
   7437 }
   7438 
   7439 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
   7440                                        SDPatternOperator OpNode> {
   7441   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
   7442   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
   7443                                       V128, V64,
   7444                                       V128_lo, VectorIndexH,
   7445                                       asm, ".4s", ".4s", ".4h", ".h",
   7446     [(set (v4i32 V128:$dst),
   7447         (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
   7448          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
   7449     bits<3> idx;
   7450     let Inst{11} = idx{2};
   7451     let Inst{21} = idx{1};
   7452     let Inst{20} = idx{0};
   7453   }
   7454 
   7455   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
   7456                                       V128, V128,
   7457                                       V128_lo, VectorIndexH,
   7458                                       asm#"2", ".4s", ".4s", ".8h", ".h",
   7459     [(set (v4i32 V128:$dst),
   7460           (OpNode (v4i32 V128:$Rd),
   7461                   (extract_high_v8i16 V128:$Rn),
   7462                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   7463                                                       VectorIndexH:$idx))))]> {
   7464     bits<3> idx;
   7465     let Inst{11} = idx{2};
   7466     let Inst{21} = idx{1};
   7467     let Inst{20} = idx{0};
   7468   }
   7469 
   7470   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
   7471                                       V128, V64,
   7472                                       V128, VectorIndexS,
   7473                                       asm, ".2d", ".2d", ".2s", ".s",
   7474     [(set (v2i64 V128:$dst),
   7475         (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
   7476          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
   7477     bits<2> idx;
   7478     let Inst{11} = idx{1};
   7479     let Inst{21} = idx{0};
   7480   }
   7481 
   7482   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
   7483                                       V128, V128,
   7484                                       V128, VectorIndexS,
   7485                                       asm#"2", ".2d", ".2d", ".4s", ".s",
   7486     [(set (v2i64 V128:$dst),
   7487           (OpNode (v2i64 V128:$Rd),
   7488                   (extract_high_v4i32 V128:$Rn),
   7489                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
   7490                                                       VectorIndexS:$idx))))]> {
   7491     bits<2> idx;
   7492     let Inst{11} = idx{1};
   7493     let Inst{21} = idx{0};
   7494   }
   7495   }
   7496 }
   7497 
   7498 //----------------------------------------------------------------------------
   7499 // AdvSIMD scalar shift by immediate
   7500 //----------------------------------------------------------------------------
   7501 
   7502 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   7503 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
   7504                      RegisterClass regtype1, RegisterClass regtype2,
   7505                      Operand immtype, string asm, list<dag> pattern>
   7506   : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
   7507       asm, "\t$Rd, $Rn, $imm", "", pattern>,
   7508     Sched<[WriteV]> {
   7509   bits<5> Rd;
   7510   bits<5> Rn;
   7511   bits<7> imm;
   7512   let Inst{31-30} = 0b01;
   7513   let Inst{29}    = U;
   7514   let Inst{28-23} = 0b111110;
   7515   let Inst{22-16} = fixed_imm;
   7516   let Inst{15-11} = opc;
   7517   let Inst{10}    = 1;
   7518   let Inst{9-5} = Rn;
   7519   let Inst{4-0} = Rd;
   7520 }
   7521 
   7522 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   7523 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
   7524                      RegisterClass regtype1, RegisterClass regtype2,
   7525                      Operand immtype, string asm, list<dag> pattern>
   7526   : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
   7527       asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
   7528     Sched<[WriteV]> {
   7529   bits<5> Rd;
   7530   bits<5> Rn;
   7531   bits<7> imm;
   7532   let Inst{31-30} = 0b01;
   7533   let Inst{29}    = U;
   7534   let Inst{28-23} = 0b111110;
   7535   let Inst{22-16} = fixed_imm;
   7536   let Inst{15-11} = opc;
   7537   let Inst{10}    = 1;
   7538   let Inst{9-5} = Rn;
   7539   let Inst{4-0} = Rd;
   7540 }
   7541 
   7542 
   7543 multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {
   7544   let Predicates = [HasNEON, HasFullFP16] in {
   7545   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
   7546                               FPR16, FPR16, vecshiftR16, asm, []> {
   7547     let Inst{19-16} = imm{3-0};
   7548   }
   7549   } // Predicates = [HasNEON, HasFullFP16]
   7550   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
   7551                               FPR32, FPR32, vecshiftR32, asm, []> {
   7552     let Inst{20-16} = imm{4-0};
   7553   }
   7554 
   7555   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
   7556                               FPR64, FPR64, vecshiftR64, asm, []> {
   7557     let Inst{21-16} = imm{5-0};
   7558   }
   7559 }
   7560 
   7561 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
   7562                              SDPatternOperator OpNode> {
   7563   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
   7564                               FPR64, FPR64, vecshiftR64, asm,
   7565   [(set (i64 FPR64:$Rd),
   7566      (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
   7567     let Inst{21-16} = imm{5-0};
   7568   }
   7569 
   7570   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
   7571             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
   7572 }
   7573 
   7574 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
   7575                                  SDPatternOperator OpNode = null_frag> {
   7576   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
   7577                               FPR64, FPR64, vecshiftR64, asm,
   7578   [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
   7579                                                    (i32 vecshiftR64:$imm)))]> {
   7580     let Inst{21-16} = imm{5-0};
   7581   }
   7582 
   7583   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
   7584                            (i32 vecshiftR64:$imm))),
   7585             (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
   7586                                             vecshiftR64:$imm)>;
   7587 }
   7588 
   7589 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
   7590                              SDPatternOperator OpNode> {
   7591   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
   7592                               FPR64, FPR64, vecshiftL64, asm,
   7593     [(set (v1i64 FPR64:$Rd),
   7594        (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
   7595     let Inst{21-16} = imm{5-0};
   7596   }
   7597 }
   7598 
   7599 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   7600 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
   7601   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
   7602                               FPR64, FPR64, vecshiftL64, asm, []> {
   7603     let Inst{21-16} = imm{5-0};
   7604   }
   7605 }
   7606 
   7607 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   7608 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
   7609                                SDPatternOperator OpNode = null_frag> {
   7610   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
   7611                               FPR8, FPR16, vecshiftR8, asm, []> {
   7612     let Inst{18-16} = imm{2-0};
   7613   }
   7614 
   7615   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
   7616                               FPR16, FPR32, vecshiftR16, asm, []> {
   7617     let Inst{19-16} = imm{3-0};
   7618   }
   7619 
   7620   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
   7621                               FPR32, FPR64, vecshiftR32, asm,
   7622     [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
   7623     let Inst{20-16} = imm{4-0};
   7624   }
   7625 }
   7626 
   7627 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
   7628                                 SDPatternOperator OpNode> {
   7629   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
   7630                               FPR8, FPR8, vecshiftL8, asm, []> {
   7631     let Inst{18-16} = imm{2-0};
   7632   }
   7633 
   7634   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
   7635                               FPR16, FPR16, vecshiftL16, asm, []> {
   7636     let Inst{19-16} = imm{3-0};
   7637   }
   7638 
   7639   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
   7640                               FPR32, FPR32, vecshiftL32, asm,
   7641     [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
   7642     let Inst{20-16} = imm{4-0};
   7643   }
   7644 
   7645   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
   7646                               FPR64, FPR64, vecshiftL64, asm,
   7647     [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
   7648     let Inst{21-16} = imm{5-0};
   7649   }
   7650 
   7651   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
   7652             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
   7653 }
   7654 
   7655 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
   7656   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
   7657                               FPR8, FPR8, vecshiftR8, asm, []> {
   7658     let Inst{18-16} = imm{2-0};
   7659   }
   7660 
   7661   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
   7662                               FPR16, FPR16, vecshiftR16, asm, []> {
   7663     let Inst{19-16} = imm{3-0};
   7664   }
   7665 
   7666   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
   7667                               FPR32, FPR32, vecshiftR32, asm, []> {
   7668     let Inst{20-16} = imm{4-0};
   7669   }
   7670 
   7671   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
   7672                               FPR64, FPR64, vecshiftR64, asm, []> {
   7673     let Inst{21-16} = imm{5-0};
   7674   }
   7675 }
   7676 
   7677 //----------------------------------------------------------------------------
   7678 // AdvSIMD vector x indexed element
   7679 //----------------------------------------------------------------------------
   7680 
   7681 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   7682 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
   7683                      RegisterOperand dst_reg, RegisterOperand src_reg,
   7684                      Operand immtype,
   7685                      string asm, string dst_kind, string src_kind,
   7686                      list<dag> pattern>
   7687   : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
   7688       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
   7689            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
   7690     Sched<[WriteV]> {
   7691   bits<5> Rd;
   7692   bits<5> Rn;
   7693   let Inst{31}    = 0;
   7694   let Inst{30}    = Q;
   7695   let Inst{29}    = U;
   7696   let Inst{28-23} = 0b011110;
   7697   let Inst{22-16} = fixed_imm;
   7698   let Inst{15-11} = opc;
   7699   let Inst{10}    = 1;
   7700   let Inst{9-5}   = Rn;
   7701   let Inst{4-0}   = Rd;
   7702 }
   7703 
   7704 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
   7705 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
   7706                      RegisterOperand vectype1, RegisterOperand vectype2,
   7707                      Operand immtype,
   7708                      string asm, string dst_kind, string src_kind,
   7709                      list<dag> pattern>
   7710   : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
   7711       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
   7712            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
   7713     Sched<[WriteV]> {
   7714   bits<5> Rd;
   7715   bits<5> Rn;
   7716   let Inst{31}    = 0;
   7717   let Inst{30}    = Q;
   7718   let Inst{29}    = U;
   7719   let Inst{28-23} = 0b011110;
   7720   let Inst{22-16} = fixed_imm;
   7721   let Inst{15-11} = opc;
   7722   let Inst{10}    = 1;
   7723   let Inst{9-5}   = Rn;
   7724   let Inst{4-0}   = Rd;
   7725 }
   7726 
   7727 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
   7728                               Intrinsic OpNode> {
   7729   let Predicates = [HasNEON, HasFullFP16] in {
   7730   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
   7731                                   V64, V64, vecshiftR16,
   7732                                   asm, ".4h", ".4h",
   7733       [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
   7734     bits<4> imm;
   7735     let Inst{19-16} = imm;
   7736   }
   7737 
   7738   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
   7739                                   V128, V128, vecshiftR16,
   7740                                   asm, ".8h", ".8h",
   7741       [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
   7742     bits<4> imm;
   7743     let Inst{19-16} = imm;
   7744   }
   7745   } // Predicates = [HasNEON, HasFullFP16]
   7746   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
   7747                                   V64, V64, vecshiftR32,
   7748                                   asm, ".2s", ".2s",
   7749       [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
   7750     bits<5> imm;
   7751     let Inst{20-16} = imm;
   7752   }
   7753 
   7754   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
   7755                                   V128, V128, vecshiftR32,
   7756                                   asm, ".4s", ".4s",
   7757       [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
   7758     bits<5> imm;
   7759     let Inst{20-16} = imm;
   7760   }
   7761 
   7762   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
   7763                                   V128, V128, vecshiftR64,
   7764                                   asm, ".2d", ".2d",
   7765       [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
   7766     bits<6> imm;
   7767     let Inst{21-16} = imm;
   7768   }
   7769 }
   7770 
   7771 multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
   7772                                   Intrinsic OpNode> {
   7773   let Predicates = [HasNEON, HasFullFP16] in {
   7774   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
   7775                                   V64, V64, vecshiftR16,
   7776                                   asm, ".4h", ".4h",
   7777       [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
   7778     bits<4> imm;
   7779     let Inst{19-16} = imm;
   7780   }
   7781 
   7782   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
   7783                                   V128, V128, vecshiftR16,
   7784                                   asm, ".8h", ".8h",
   7785       [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
   7786     bits<4> imm;
   7787     let Inst{19-16} = imm;
   7788   }
   7789   } // Predicates = [HasNEON, HasFullFP16]
   7790 
   7791   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
   7792                                   V64, V64, vecshiftR32,
   7793                                   asm, ".2s", ".2s",
   7794       [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
   7795     bits<5> imm;
   7796     let Inst{20-16} = imm;
   7797   }
   7798 
   7799   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
   7800                                   V128, V128, vecshiftR32,
   7801                                   asm, ".4s", ".4s",
   7802       [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
   7803     bits<5> imm;
   7804     let Inst{20-16} = imm;
   7805   }
   7806 
   7807   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
   7808                                   V128, V128, vecshiftR64,
   7809                                   asm, ".2d", ".2d",
   7810       [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
   7811     bits<6> imm;
   7812     let Inst{21-16} = imm;
   7813   }
   7814 }
   7815 
   7816 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
   7817                                      SDPatternOperator OpNode> {
   7818   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
   7819                                   V64, V128, vecshiftR16Narrow,
   7820                                   asm, ".8b", ".8h",
   7821       [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
   7822     bits<3> imm;
   7823     let Inst{18-16} = imm;
   7824   }
   7825 
   7826   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
   7827                                   V128, V128, vecshiftR16Narrow,
   7828                                   asm#"2", ".16b", ".8h", []> {
   7829     bits<3> imm;
   7830     let Inst{18-16} = imm;
   7831     let hasSideEffects = 0;
   7832   }
   7833 
   7834   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
   7835                                   V64, V128, vecshiftR32Narrow,
   7836                                   asm, ".4h", ".4s",
   7837       [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
   7838     bits<4> imm;
   7839     let Inst{19-16} = imm;
   7840   }
   7841 
   7842   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
   7843                                   V128, V128, vecshiftR32Narrow,
   7844                                   asm#"2", ".8h", ".4s", []> {
   7845     bits<4> imm;
   7846     let Inst{19-16} = imm;
   7847     let hasSideEffects = 0;
   7848   }
   7849 
   7850   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
   7851                                   V64, V128, vecshiftR64Narrow,
   7852                                   asm, ".2s", ".2d",
   7853       [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
   7854     bits<5> imm;
   7855     let Inst{20-16} = imm;
   7856   }
   7857 
   7858   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
   7859                                   V128, V128, vecshiftR64Narrow,
   7860                                   asm#"2", ".4s", ".2d", []> {
   7861     bits<5> imm;
   7862     let Inst{20-16} = imm;
   7863     let hasSideEffects = 0;
   7864   }
   7865 
   7866   // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
   7867   // themselves, so put them here instead.
   7868 
   7869   // Patterns involving what's effectively an insert high and a normal
   7870   // intrinsic, represented by CONCAT_VECTORS.
   7871   def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
   7872                                                    vecshiftR16Narrow:$imm)),
   7873             (!cast<Instruction>(NAME # "v16i8_shift")
   7874                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
   7875                 V128:$Rn, vecshiftR16Narrow:$imm)>;
   7876   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
   7877                                                      vecshiftR32Narrow:$imm)),
   7878             (!cast<Instruction>(NAME # "v8i16_shift")
   7879                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
   7880                 V128:$Rn, vecshiftR32Narrow:$imm)>;
   7881   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
   7882                                                      vecshiftR64Narrow:$imm)),
   7883             (!cast<Instruction>(NAME # "v4i32_shift")
   7884                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
   7885                 V128:$Rn, vecshiftR64Narrow:$imm)>;
   7886 }
   7887 
   7888 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
   7889                                 SDPatternOperator OpNode> {
   7890   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
   7891                                   V64, V64, vecshiftL8,
   7892                                   asm, ".8b", ".8b",
   7893                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
   7894                        (i32 vecshiftL8:$imm)))]> {
   7895     bits<3> imm;
   7896     let Inst{18-16} = imm;
   7897   }
   7898 
   7899   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
   7900                                   V128, V128, vecshiftL8,
   7901                                   asm, ".16b", ".16b",
   7902              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
   7903                    (i32 vecshiftL8:$imm)))]> {
   7904     bits<3> imm;
   7905     let Inst{18-16} = imm;
   7906   }
   7907 
   7908   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
   7909                                   V64, V64, vecshiftL16,
   7910                                   asm, ".4h", ".4h",
   7911               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
   7912                     (i32 vecshiftL16:$imm)))]> {
   7913     bits<4> imm;
   7914     let Inst{19-16} = imm;
   7915   }
   7916 
   7917   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
   7918                                   V128, V128, vecshiftL16,
   7919                                   asm, ".8h", ".8h",
   7920             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
   7921                   (i32 vecshiftL16:$imm)))]> {
   7922     bits<4> imm;
   7923     let Inst{19-16} = imm;
   7924   }
   7925 
   7926   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
   7927                                   V64, V64, vecshiftL32,
   7928                                   asm, ".2s", ".2s",
   7929               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
   7930                     (i32 vecshiftL32:$imm)))]> {
   7931     bits<5> imm;
   7932     let Inst{20-16} = imm;
   7933   }
   7934 
   7935   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
   7936                                   V128, V128, vecshiftL32,
   7937                                   asm, ".4s", ".4s",
   7938             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
   7939                   (i32 vecshiftL32:$imm)))]> {
   7940     bits<5> imm;
   7941     let Inst{20-16} = imm;
   7942   }
   7943 
   7944   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
   7945                                   V128, V128, vecshiftL64,
   7946                                   asm, ".2d", ".2d",
   7947             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
   7948                   (i32 vecshiftL64:$imm)))]> {
   7949     bits<6> imm;
   7950     let Inst{21-16} = imm;
   7951   }
   7952 }
   7953 
   7954 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
   7955                                 SDPatternOperator OpNode> {
   7956   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
   7957                                   V64, V64, vecshiftR8,
   7958                                   asm, ".8b", ".8b",
   7959                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
   7960                        (i32 vecshiftR8:$imm)))]> {
   7961     bits<3> imm;
   7962     let Inst{18-16} = imm;
   7963   }
   7964 
   7965   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
   7966                                   V128, V128, vecshiftR8,
   7967                                   asm, ".16b", ".16b",
   7968              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
   7969                    (i32 vecshiftR8:$imm)))]> {
   7970     bits<3> imm;
   7971     let Inst{18-16} = imm;
   7972   }
   7973 
   7974   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
   7975                                   V64, V64, vecshiftR16,
   7976                                   asm, ".4h", ".4h",
   7977               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
   7978                     (i32 vecshiftR16:$imm)))]> {
   7979     bits<4> imm;
   7980     let Inst{19-16} = imm;
   7981   }
   7982 
   7983   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
   7984                                   V128, V128, vecshiftR16,
   7985                                   asm, ".8h", ".8h",
   7986             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
   7987                   (i32 vecshiftR16:$imm)))]> {
   7988     bits<4> imm;
   7989     let Inst{19-16} = imm;
   7990   }
   7991 
   7992   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
   7993                                   V64, V64, vecshiftR32,
   7994                                   asm, ".2s", ".2s",
   7995               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
   7996                     (i32 vecshiftR32:$imm)))]> {
   7997     bits<5> imm;
   7998     let Inst{20-16} = imm;
   7999   }
   8000 
   8001   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
   8002                                   V128, V128, vecshiftR32,
   8003                                   asm, ".4s", ".4s",
   8004             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
   8005                   (i32 vecshiftR32:$imm)))]> {
   8006     bits<5> imm;
   8007     let Inst{20-16} = imm;
   8008   }
   8009 
   8010   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
   8011                                   V128, V128, vecshiftR64,
   8012                                   asm, ".2d", ".2d",
   8013             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
   8014                   (i32 vecshiftR64:$imm)))]> {
   8015     bits<6> imm;
   8016     let Inst{21-16} = imm;
   8017   }
   8018 }
   8019 
   8020 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   8021 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
   8022                                     SDPatternOperator OpNode = null_frag> {
   8023   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
   8024                                   V64, V64, vecshiftR8, asm, ".8b", ".8b",
   8025                  [(set (v8i8 V64:$dst),
   8026                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
   8027                            (i32 vecshiftR8:$imm)))]> {
   8028     bits<3> imm;
   8029     let Inst{18-16} = imm;
   8030   }
   8031 
   8032   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
   8033                                   V128, V128, vecshiftR8, asm, ".16b", ".16b",
   8034              [(set (v16i8 V128:$dst),
   8035                (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
   8036                        (i32 vecshiftR8:$imm)))]> {
   8037     bits<3> imm;
   8038     let Inst{18-16} = imm;
   8039   }
   8040 
   8041   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
   8042                                   V64, V64, vecshiftR16, asm, ".4h", ".4h",
   8043               [(set (v4i16 V64:$dst),
   8044                 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
   8045                         (i32 vecshiftR16:$imm)))]> {
   8046     bits<4> imm;
   8047     let Inst{19-16} = imm;
   8048   }
   8049 
   8050   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
   8051                                   V128, V128, vecshiftR16, asm, ".8h", ".8h",
   8052             [(set (v8i16 V128:$dst),
   8053               (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
   8054                       (i32 vecshiftR16:$imm)))]> {
   8055     bits<4> imm;
   8056     let Inst{19-16} = imm;
   8057   }
   8058 
   8059   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
   8060                                   V64, V64, vecshiftR32, asm, ".2s", ".2s",
   8061               [(set (v2i32 V64:$dst),
   8062                 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
   8063                         (i32 vecshiftR32:$imm)))]> {
   8064     bits<5> imm;
   8065     let Inst{20-16} = imm;
   8066   }
   8067 
   8068   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
   8069                                   V128, V128, vecshiftR32, asm, ".4s", ".4s",
   8070             [(set (v4i32 V128:$dst),
   8071               (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
   8072                       (i32 vecshiftR32:$imm)))]> {
   8073     bits<5> imm;
   8074     let Inst{20-16} = imm;
   8075   }
   8076 
   8077   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
   8078                                   V128, V128, vecshiftR64,
   8079                                   asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
   8080               (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
   8081                       (i32 vecshiftR64:$imm)))]> {
   8082     bits<6> imm;
   8083     let Inst{21-16} = imm;
   8084   }
   8085 }
   8086 
   8087 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
   8088                                     SDPatternOperator OpNode = null_frag> {
   8089   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
   8090                                   V64, V64, vecshiftL8,
   8091                                   asm, ".8b", ".8b",
   8092                     [(set (v8i8 V64:$dst),
   8093                           (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
   8094                                   (i32 vecshiftL8:$imm)))]> {
   8095     bits<3> imm;
   8096     let Inst{18-16} = imm;
   8097   }
   8098 
   8099   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
   8100                                   V128, V128, vecshiftL8,
   8101                                   asm, ".16b", ".16b",
   8102                     [(set (v16i8 V128:$dst),
   8103                           (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
   8104                                   (i32 vecshiftL8:$imm)))]> {
   8105     bits<3> imm;
   8106     let Inst{18-16} = imm;
   8107   }
   8108 
   8109   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
   8110                                   V64, V64, vecshiftL16,
   8111                                   asm, ".4h", ".4h",
   8112                     [(set (v4i16 V64:$dst),
   8113                            (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
   8114                                    (i32 vecshiftL16:$imm)))]> {
   8115     bits<4> imm;
   8116     let Inst{19-16} = imm;
   8117   }
   8118 
   8119   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
   8120                                   V128, V128, vecshiftL16,
   8121                                   asm, ".8h", ".8h",
   8122                     [(set (v8i16 V128:$dst),
   8123                           (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
   8124                                   (i32 vecshiftL16:$imm)))]> {
   8125     bits<4> imm;
   8126     let Inst{19-16} = imm;
   8127   }
   8128 
   8129   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
   8130                                   V64, V64, vecshiftL32,
   8131                                   asm, ".2s", ".2s",
   8132                     [(set (v2i32 V64:$dst),
   8133                           (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
   8134                                   (i32 vecshiftL32:$imm)))]> {
   8135     bits<5> imm;
   8136     let Inst{20-16} = imm;
   8137   }
   8138 
   8139   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
   8140                                   V128, V128, vecshiftL32,
   8141                                   asm, ".4s", ".4s",
   8142                     [(set (v4i32 V128:$dst),
   8143                           (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
   8144                                   (i32 vecshiftL32:$imm)))]> {
   8145     bits<5> imm;
   8146     let Inst{20-16} = imm;
   8147   }
   8148 
   8149   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
   8150                                   V128, V128, vecshiftL64,
   8151                                   asm, ".2d", ".2d",
   8152                     [(set (v2i64 V128:$dst),
   8153                           (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
   8154                                   (i32 vecshiftL64:$imm)))]> {
   8155     bits<6> imm;
   8156     let Inst{21-16} = imm;
   8157   }
   8158 }
   8159 
   8160 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
   8161                                    SDPatternOperator OpNode> {
   8162   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
   8163                                   V128, V64, vecshiftL8, asm, ".8h", ".8b",
   8164       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
   8165     bits<3> imm;
   8166     let Inst{18-16} = imm;
   8167   }
   8168 
   8169   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
   8170                                   V128, V128, vecshiftL8,
   8171                                   asm#"2", ".8h", ".16b",
   8172       [(set (v8i16 V128:$Rd),
   8173             (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
   8174     bits<3> imm;
   8175     let Inst{18-16} = imm;
   8176   }
   8177 
   8178   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
   8179                                   V128, V64, vecshiftL16, asm, ".4s", ".4h",
   8180       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
   8181     bits<4> imm;
   8182     let Inst{19-16} = imm;
   8183   }
   8184 
   8185   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
   8186                                   V128, V128, vecshiftL16,
   8187                                   asm#"2", ".4s", ".8h",
   8188       [(set (v4i32 V128:$Rd),
   8189             (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
   8190 
   8191     bits<4> imm;
   8192     let Inst{19-16} = imm;
   8193   }
   8194 
   8195   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
   8196                                   V128, V64, vecshiftL32, asm, ".2d", ".2s",
   8197       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
   8198     bits<5> imm;
   8199     let Inst{20-16} = imm;
   8200   }
   8201 
   8202   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
   8203                                   V128, V128, vecshiftL32,
   8204                                   asm#"2", ".2d", ".4s",
   8205       [(set (v2i64 V128:$Rd),
   8206             (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
   8207     bits<5> imm;
   8208     let Inst{20-16} = imm;
   8209   }
   8210 }
   8211 
   8212 
   8213 //---
   8214 // Vector load/store
   8215 //---
   8216 // SIMD ldX/stX no-index memory references don't allow the optional
   8217 // ", #0" constant and handle post-indexing explicitly, so we use
   8218 // a more specialized parse method for them. Otherwise, it's the same as
   8219 // the general GPR64sp handling.
   8220 
   8221 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
   8222                    string asm, dag oops, dag iops, list<dag> pattern>
   8223   : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
   8224   bits<5> Vt;
   8225   bits<5> Rn;
   8226   let Inst{31} = 0;
   8227   let Inst{30} = Q;
   8228   let Inst{29-23} = 0b0011000;
   8229   let Inst{22} = L;
   8230   let Inst{21-16} = 0b000000;
   8231   let Inst{15-12} = opcode;
   8232   let Inst{11-10} = size;
   8233   let Inst{9-5} = Rn;
   8234   let Inst{4-0} = Vt;
   8235 }
   8236 
   8237 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
   8238                        string asm, dag oops, dag iops>
   8239   : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
   8240   bits<5> Vt;
   8241   bits<5> Rn;
   8242   bits<5> Xm;
   8243   let Inst{31} = 0;
   8244   let Inst{30} = Q;
   8245   let Inst{29-23} = 0b0011001;
   8246   let Inst{22} = L;
   8247   let Inst{21} = 0;
   8248   let Inst{20-16} = Xm;
   8249   let Inst{15-12} = opcode;
   8250   let Inst{11-10} = size;
   8251   let Inst{9-5} = Rn;
   8252   let Inst{4-0} = Vt;
   8253 }
   8254 
   8255 // The immediate form of AdvSIMD post-indexed addressing is encoded with
   8256 // register post-index addressing from the zero register.
   8257 multiclass SIMDLdStAliases<string asm, string layout, string Count,
   8258                            int Offset, int Size> {
   8259   // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
   8260   //      "ld1\t$Vt, [$Rn], #16"
   8261   // may get mapped to
   8262   //      (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
   8263   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
   8264                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
   8265                       GPR64sp:$Rn,
   8266                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
   8267                       XZR), 1>;
   8268 
   8269   // E.g. "ld1.8b { v0, v1 }, [x1], #16"
   8270   //      "ld1.8b\t$Vt, [$Rn], #16"
   8271   // may get mapped to
   8272   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
   8273   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
   8274                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
   8275                       GPR64sp:$Rn,
   8276                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
   8277                       XZR), 0>;
   8278 
   8279   // E.g. "ld1.8b { v0, v1 }, [x1]"
   8280   //      "ld1\t$Vt, [$Rn]"
   8281   // may get mapped to
   8282   //      (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
   8283   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
   8284                   (!cast<Instruction>(NAME # Count # "v" # layout)
   8285                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
   8286                       GPR64sp:$Rn), 0>;
   8287 
   8288   // E.g. "ld1.8b { v0, v1 }, [x1], x2"
   8289   //      "ld1\t$Vt, [$Rn], $Xm"
   8290   // may get mapped to
   8291   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
   8292   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
   8293                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
   8294                       GPR64sp:$Rn,
   8295                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
   8296                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
   8297 }
   8298 
   8299 multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
   8300                        int Offset64, bits<4> opcode> {
   8301   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
   8302     def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
   8303                            (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
   8304                            (ins GPR64sp:$Rn), []>;
   8305     def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
   8306                            (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
   8307                            (ins GPR64sp:$Rn), []>;
   8308     def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
   8309                            (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
   8310                            (ins GPR64sp:$Rn), []>;
   8311     def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
   8312                            (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
   8313                            (ins GPR64sp:$Rn), []>;
   8314     def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
   8315                            (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
   8316                            (ins GPR64sp:$Rn), []>;
   8317     def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
   8318                            (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
   8319                            (ins GPR64sp:$Rn), []>;
   8320     def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
   8321                            (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
   8322                            (ins GPR64sp:$Rn), []>;
   8323 
   8324 
   8325     def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
   8326                        (outs GPR64sp:$wback,
   8327                              !cast<RegisterOperand>(veclist # "16b"):$Vt),
   8328                        (ins GPR64sp:$Rn,
   8329                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8330     def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
   8331                        (outs GPR64sp:$wback,
   8332                              !cast<RegisterOperand>(veclist # "8h"):$Vt),
   8333                        (ins GPR64sp:$Rn,
   8334                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8335     def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
   8336                        (outs GPR64sp:$wback,
   8337                              !cast<RegisterOperand>(veclist # "4s"):$Vt),
   8338                        (ins GPR64sp:$Rn,
   8339                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8340     def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
   8341                        (outs GPR64sp:$wback,
   8342                              !cast<RegisterOperand>(veclist # "2d"):$Vt),
   8343                        (ins GPR64sp:$Rn,
   8344                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8345     def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
   8346                        (outs GPR64sp:$wback,
   8347                              !cast<RegisterOperand>(veclist # "8b"):$Vt),
   8348                        (ins GPR64sp:$Rn,
   8349                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8350     def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
   8351                        (outs GPR64sp:$wback,
   8352                              !cast<RegisterOperand>(veclist # "4h"):$Vt),
   8353                        (ins GPR64sp:$Rn,
   8354                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8355     def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
   8356                        (outs GPR64sp:$wback,
   8357                              !cast<RegisterOperand>(veclist # "2s"):$Vt),
   8358                        (ins GPR64sp:$Rn,
   8359                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8360   }
   8361 
   8362   defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
   8363   defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
   8364   defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
   8365   defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
   8366   defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
   8367   defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
   8368   defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
   8369 }
   8370 
   8371 // Only ld1/st1 has a v1d version.
   8372 multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
   8373                        int Offset64, bits<4> opcode> {
   8374   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
   8375     def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
   8376                             (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
   8377                                  GPR64sp:$Rn), []>;
   8378     def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
   8379                            (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
   8380                                 GPR64sp:$Rn), []>;
   8381     def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
   8382                            (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
   8383                                 GPR64sp:$Rn), []>;
   8384     def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
   8385                            (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
   8386                                 GPR64sp:$Rn), []>;
   8387     def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
   8388                            (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
   8389                                 GPR64sp:$Rn), []>;
   8390     def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
   8391                            (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
   8392                                 GPR64sp:$Rn), []>;
   8393     def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
   8394                            (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
   8395                                 GPR64sp:$Rn), []>;
   8396 
   8397     def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
   8398                        (outs GPR64sp:$wback),
   8399                        (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
   8400                             GPR64sp:$Rn,
   8401                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8402     def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
   8403                        (outs GPR64sp:$wback),
   8404                        (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
   8405                             GPR64sp:$Rn,
   8406                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8407     def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
   8408                        (outs GPR64sp:$wback),
   8409                        (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
   8410                             GPR64sp:$Rn,
   8411                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8412     def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
   8413                        (outs GPR64sp:$wback),
   8414                        (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
   8415                             GPR64sp:$Rn,
   8416                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
   8417     def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
   8418                        (outs GPR64sp:$wback),
   8419                        (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
   8420                             GPR64sp:$Rn,
   8421                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8422     def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
   8423                        (outs GPR64sp:$wback),
   8424                        (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
   8425                             GPR64sp:$Rn,
   8426                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8427     def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
   8428                        (outs GPR64sp:$wback),
   8429                        (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
   8430                             GPR64sp:$Rn,
   8431                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8432   }
   8433 
   8434   defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
   8435   defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
   8436   defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
   8437   defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
   8438   defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
   8439   defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
   8440   defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
   8441 }
   8442 
   8443 multiclass BaseSIMDLd1<string Count, string asm, string veclist,
   8444                        int Offset128, int Offset64, bits<4> opcode>
   8445   : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
   8446 
   8447   // LD1 instructions have extra "1d" variants.
   8448   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
   8449     def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
   8450                            (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
   8451                            (ins GPR64sp:$Rn), []>;
   8452 
   8453     def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
   8454                        (outs GPR64sp:$wback,
   8455                              !cast<RegisterOperand>(veclist # "1d"):$Vt),
   8456                        (ins GPR64sp:$Rn,
   8457                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8458   }
   8459 
   8460   defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
   8461 }
   8462 
   8463 multiclass BaseSIMDSt1<string Count, string asm, string veclist,
   8464                        int Offset128, int Offset64, bits<4> opcode>
   8465   : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
   8466 
   8467   // ST1 instructions have extra "1d" variants.
   8468   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
   8469     def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
   8470                            (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
   8471                                 GPR64sp:$Rn), []>;
   8472 
   8473     def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
   8474                        (outs GPR64sp:$wback),
   8475                        (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
   8476                             GPR64sp:$Rn,
   8477                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
   8478   }
   8479 
   8480   defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
   8481 }
   8482 
   8483 multiclass SIMDLd1Multiple<string asm> {
   8484   defm One   : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8,  0b0111>;
   8485   defm Two   : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
   8486   defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
   8487   defm Four  : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
   8488 }
   8489 
   8490 multiclass SIMDSt1Multiple<string asm> {
   8491   defm One   : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8,  0b0111>;
   8492   defm Two   : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
   8493   defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
   8494   defm Four  : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
   8495 }
   8496 
   8497 multiclass SIMDLd2Multiple<string asm> {
   8498   defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
   8499 }
   8500 
   8501 multiclass SIMDSt2Multiple<string asm> {
   8502   defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
   8503 }
   8504 
   8505 multiclass SIMDLd3Multiple<string asm> {
   8506   defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
   8507 }
   8508 
   8509 multiclass SIMDSt3Multiple<string asm> {
   8510   defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
   8511 }
   8512 
   8513 multiclass SIMDLd4Multiple<string asm> {
   8514   defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
   8515 }
   8516 
   8517 multiclass SIMDSt4Multiple<string asm> {
   8518   defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
   8519 }
   8520 
   8521 //---
   8522 // AdvSIMD Load/store single-element
   8523 //---
   8524 
   8525 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
   8526                          string asm, string operands, string cst,
   8527                          dag oops, dag iops, list<dag> pattern>
   8528   : I<oops, iops, asm, operands, cst, pattern> {
   8529   bits<5> Vt;
   8530   bits<5> Rn;
   8531   let Inst{31} = 0;
   8532   let Inst{29-24} = 0b001101;
   8533   let Inst{22} = L;
   8534   let Inst{21} = R;
   8535   let Inst{15-13} = opcode;
   8536   let Inst{9-5} = Rn;
   8537   let Inst{4-0} = Vt;
   8538 }
   8539 
   8540 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
   8541                          string asm, string operands, string cst,
   8542                          dag oops, dag iops, list<dag> pattern>
   8543   : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
   8544   bits<5> Vt;
   8545   bits<5> Rn;
   8546   let Inst{31} = 0;
   8547   let Inst{29-24} = 0b001101;
   8548   let Inst{22} = L;
   8549   let Inst{21} = R;
   8550   let Inst{15-13} = opcode;
   8551   let Inst{9-5} = Rn;
   8552   let Inst{4-0} = Vt;
   8553 }
   8554 
   8555 
   8556 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   8557 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
   8558                   Operand listtype>
   8559   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
   8560                        (outs listtype:$Vt), (ins GPR64sp:$Rn),
   8561                        []> {
   8562   let Inst{30} = Q;
   8563   let Inst{23} = 0;
   8564   let Inst{20-16} = 0b00000;
   8565   let Inst{12} = S;
   8566   let Inst{11-10} = size;
   8567 }
   8568 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   8569 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
   8570                       string asm, Operand listtype, Operand GPR64pi>
   8571   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
   8572                        "$Rn = $wback",
   8573                        (outs GPR64sp:$wback, listtype:$Vt),
   8574                        (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
   8575   bits<5> Xm;
   8576   let Inst{30} = Q;
   8577   let Inst{23} = 1;
   8578   let Inst{20-16} = Xm;
   8579   let Inst{12} = S;
   8580   let Inst{11-10} = size;
   8581 }
   8582 
   8583 multiclass SIMDLdrAliases<string asm, string layout, string Count,
   8584                           int Offset, int Size> {
   8585   // E.g. "ld1r { v0.8b }, [x1], #1"
   8586   //      "ld1r.8b\t$Vt, [$Rn], #1"
   8587   // may get mapped to
   8588   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
   8589   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
   8590                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
   8591                       GPR64sp:$Rn,
   8592                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
   8593                       XZR), 1>;
   8594 
   8595   // E.g. "ld1r.8b { v0 }, [x1], #1"
   8596   //      "ld1r.8b\t$Vt, [$Rn], #1"
   8597   // may get mapped to
   8598   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
   8599   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
   8600                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
   8601                       GPR64sp:$Rn,
   8602                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
   8603                       XZR), 0>;
   8604 
   8605   // E.g. "ld1r.8b { v0 }, [x1]"
   8606   //      "ld1r.8b\t$Vt, [$Rn]"
   8607   // may get mapped to
   8608   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
   8609   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
   8610                   (!cast<Instruction>(NAME # "v" # layout)
   8611                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
   8612                       GPR64sp:$Rn), 0>;
   8613 
   8614   // E.g. "ld1r.8b { v0 }, [x1], x2"
   8615   //      "ld1r.8b\t$Vt, [$Rn], $Xm"
   8616   // may get mapped to
   8617   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
   8618   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
   8619                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
   8620                       GPR64sp:$Rn,
   8621                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
   8622                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
   8623 }
   8624 
   8625 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
   8626   int Offset1, int Offset2, int Offset4, int Offset8> {
   8627   def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
   8628                         !cast<Operand>("VecList" # Count # "8b")>;
   8629   def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
   8630                         !cast<Operand>("VecList" # Count #"16b")>;
   8631   def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
   8632                         !cast<Operand>("VecList" # Count #"4h")>;
   8633   def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
   8634                         !cast<Operand>("VecList" # Count #"8h")>;
   8635   def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
   8636                         !cast<Operand>("VecList" # Count #"2s")>;
   8637   def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
   8638                         !cast<Operand>("VecList" # Count #"4s")>;
   8639   def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
   8640                         !cast<Operand>("VecList" # Count #"1d")>;
   8641   def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
   8642                         !cast<Operand>("VecList" # Count #"2d")>;
   8643 
   8644   def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
   8645                                  !cast<Operand>("VecList" # Count # "8b"),
   8646                                  !cast<Operand>("GPR64pi" # Offset1)>;
   8647   def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
   8648                                  !cast<Operand>("VecList" # Count # "16b"),
   8649                                  !cast<Operand>("GPR64pi" # Offset1)>;
   8650   def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
   8651                                  !cast<Operand>("VecList" # Count # "4h"),
   8652                                  !cast<Operand>("GPR64pi" # Offset2)>;
   8653   def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
   8654                                  !cast<Operand>("VecList" # Count # "8h"),
   8655                                  !cast<Operand>("GPR64pi" # Offset2)>;
   8656   def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
   8657                                  !cast<Operand>("VecList" # Count # "2s"),
   8658                                  !cast<Operand>("GPR64pi" # Offset4)>;
   8659   def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
   8660                                  !cast<Operand>("VecList" # Count # "4s"),
   8661                                  !cast<Operand>("GPR64pi" # Offset4)>;
   8662   def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
   8663                                  !cast<Operand>("VecList" # Count # "1d"),
   8664                                  !cast<Operand>("GPR64pi" # Offset8)>;
   8665   def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
   8666                                  !cast<Operand>("VecList" # Count # "2d"),
   8667                                  !cast<Operand>("GPR64pi" # Offset8)>;
   8668 
   8669   defm : SIMDLdrAliases<asm, "8b",  Count, Offset1,  64>;
   8670   defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
   8671   defm : SIMDLdrAliases<asm, "4h",  Count, Offset2,  64>;
   8672   defm : SIMDLdrAliases<asm, "8h",  Count, Offset2, 128>;
   8673   defm : SIMDLdrAliases<asm, "2s",  Count, Offset4,  64>;
   8674   defm : SIMDLdrAliases<asm, "4s",  Count, Offset4, 128>;
   8675   defm : SIMDLdrAliases<asm, "1d",  Count, Offset8,  64>;
   8676   defm : SIMDLdrAliases<asm, "2d",  Count, Offset8, 128>;
   8677 }
   8678 
   8679 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
   8680                       dag oops, dag iops, list<dag> pattern>
   8681   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
   8682                        pattern> {
   8683   // idx encoded in Q:S:size fields.
   8684   bits<4> idx;
   8685   let Inst{30} = idx{3};
   8686   let Inst{23} = 0;
   8687   let Inst{20-16} = 0b00000;
   8688   let Inst{12} = idx{2};
   8689   let Inst{11-10} = idx{1-0};
   8690 }
   8691 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
   8692                       dag oops, dag iops, list<dag> pattern>
   8693   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
   8694                            oops, iops, pattern> {
   8695   // idx encoded in Q:S:size fields.
   8696   bits<4> idx;
   8697   let Inst{30} = idx{3};
   8698   let Inst{23} = 0;
   8699   let Inst{20-16} = 0b00000;
   8700   let Inst{12} = idx{2};
   8701   let Inst{11-10} = idx{1-0};
   8702 }
   8703 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
   8704                           dag oops, dag iops>
   8705   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8706                        "$Rn = $wback", oops, iops, []> {
   8707   // idx encoded in Q:S:size fields.
   8708   bits<4> idx;
   8709   bits<5> Xm;
   8710   let Inst{30} = idx{3};
   8711   let Inst{23} = 1;
   8712   let Inst{20-16} = Xm;
   8713   let Inst{12} = idx{2};
   8714   let Inst{11-10} = idx{1-0};
   8715 }
   8716 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
   8717                           dag oops, dag iops>
   8718   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8719                            "$Rn = $wback", oops, iops, []> {
   8720   // idx encoded in Q:S:size fields.
   8721   bits<4> idx;
   8722   bits<5> Xm;
   8723   let Inst{30} = idx{3};
   8724   let Inst{23} = 1;
   8725   let Inst{20-16} = Xm;
   8726   let Inst{12} = idx{2};
   8727   let Inst{11-10} = idx{1-0};
   8728 }
   8729 
   8730 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
   8731                       dag oops, dag iops, list<dag> pattern>
   8732   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
   8733                        pattern> {
   8734   // idx encoded in Q:S:size<1> fields.
   8735   bits<3> idx;
   8736   let Inst{30} = idx{2};
   8737   let Inst{23} = 0;
   8738   let Inst{20-16} = 0b00000;
   8739   let Inst{12} = idx{1};
   8740   let Inst{11} = idx{0};
   8741   let Inst{10} = size;
   8742 }
   8743 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
   8744                       dag oops, dag iops, list<dag> pattern>
   8745   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
   8746                            oops, iops, pattern> {
   8747   // idx encoded in Q:S:size<1> fields.
   8748   bits<3> idx;
   8749   let Inst{30} = idx{2};
   8750   let Inst{23} = 0;
   8751   let Inst{20-16} = 0b00000;
   8752   let Inst{12} = idx{1};
   8753   let Inst{11} = idx{0};
   8754   let Inst{10} = size;
   8755 }
   8756 
   8757 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
   8758                           dag oops, dag iops>
   8759   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8760                        "$Rn = $wback", oops, iops, []> {
   8761   // idx encoded in Q:S:size<1> fields.
   8762   bits<3> idx;
   8763   bits<5> Xm;
   8764   let Inst{30} = idx{2};
   8765   let Inst{23} = 1;
   8766   let Inst{20-16} = Xm;
   8767   let Inst{12} = idx{1};
   8768   let Inst{11} = idx{0};
   8769   let Inst{10} = size;
   8770 }
   8771 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
   8772                           dag oops, dag iops>
   8773   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8774                            "$Rn = $wback", oops, iops, []> {
   8775   // idx encoded in Q:S:size<1> fields.
   8776   bits<3> idx;
   8777   bits<5> Xm;
   8778   let Inst{30} = idx{2};
   8779   let Inst{23} = 1;
   8780   let Inst{20-16} = Xm;
   8781   let Inst{12} = idx{1};
   8782   let Inst{11} = idx{0};
   8783   let Inst{10} = size;
   8784 }
   8785 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
   8786                       dag oops, dag iops, list<dag> pattern>
   8787   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
   8788                        pattern> {
   8789   // idx encoded in Q:S fields.
   8790   bits<2> idx;
   8791   let Inst{30} = idx{1};
   8792   let Inst{23} = 0;
   8793   let Inst{20-16} = 0b00000;
   8794   let Inst{12} = idx{0};
   8795   let Inst{11-10} = size;
   8796 }
   8797 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
   8798                       dag oops, dag iops, list<dag> pattern>
   8799   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
   8800                            oops, iops, pattern> {
   8801   // idx encoded in Q:S fields.
   8802   bits<2> idx;
   8803   let Inst{30} = idx{1};
   8804   let Inst{23} = 0;
   8805   let Inst{20-16} = 0b00000;
   8806   let Inst{12} = idx{0};
   8807   let Inst{11-10} = size;
   8808 }
   8809 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
   8810                           string asm, dag oops, dag iops>
   8811   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8812                        "$Rn = $wback", oops, iops, []> {
   8813   // idx encoded in Q:S fields.
   8814   bits<2> idx;
   8815   bits<5> Xm;
   8816   let Inst{30} = idx{1};
   8817   let Inst{23} = 1;
   8818   let Inst{20-16} = Xm;
   8819   let Inst{12} = idx{0};
   8820   let Inst{11-10} = size;
   8821 }
   8822 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
   8823                           string asm, dag oops, dag iops>
   8824   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8825                            "$Rn = $wback", oops, iops, []> {
   8826   // idx encoded in Q:S fields.
   8827   bits<2> idx;
   8828   bits<5> Xm;
   8829   let Inst{30} = idx{1};
   8830   let Inst{23} = 1;
   8831   let Inst{20-16} = Xm;
   8832   let Inst{12} = idx{0};
   8833   let Inst{11-10} = size;
   8834 }
   8835 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
   8836                       dag oops, dag iops, list<dag> pattern>
   8837   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
   8838                        pattern> {
   8839   // idx encoded in Q field.
   8840   bits<1> idx;
   8841   let Inst{30} = idx;
   8842   let Inst{23} = 0;
   8843   let Inst{20-16} = 0b00000;
   8844   let Inst{12} = 0;
   8845   let Inst{11-10} = size;
   8846 }
   8847 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
   8848                       dag oops, dag iops, list<dag> pattern>
   8849   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
   8850                            oops, iops, pattern> {
   8851   // idx encoded in Q field.
   8852   bits<1> idx;
   8853   let Inst{30} = idx;
   8854   let Inst{23} = 0;
   8855   let Inst{20-16} = 0b00000;
   8856   let Inst{12} = 0;
   8857   let Inst{11-10} = size;
   8858 }
   8859 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
   8860                           string asm, dag oops, dag iops>
   8861   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8862                        "$Rn = $wback", oops, iops, []> {
   8863   // idx encoded in Q field.
   8864   bits<1> idx;
   8865   bits<5> Xm;
   8866   let Inst{30} = idx;
   8867   let Inst{23} = 1;
   8868   let Inst{20-16} = Xm;
   8869   let Inst{12} = 0;
   8870   let Inst{11-10} = size;
   8871 }
   8872 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
   8873                           string asm, dag oops, dag iops>
   8874   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
   8875                            "$Rn = $wback", oops, iops, []> {
   8876   // idx encoded in Q field.
   8877   bits<1> idx;
   8878   bits<5> Xm;
   8879   let Inst{30} = idx;
   8880   let Inst{23} = 1;
   8881   let Inst{20-16} = Xm;
   8882   let Inst{12} = 0;
   8883   let Inst{11-10} = size;
   8884 }
   8885 
   8886 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   8887 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
   8888                          RegisterOperand listtype,
   8889                          RegisterOperand GPR64pi> {
   8890   def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
   8891                            (outs listtype:$dst),
   8892                            (ins listtype:$Vt, VectorIndexB:$idx,
   8893                                 GPR64sp:$Rn), []>;
   8894 
   8895   def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
   8896                             (outs GPR64sp:$wback, listtype:$dst),
   8897                             (ins listtype:$Vt, VectorIndexB:$idx,
   8898                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
   8899 }
   8900 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   8901 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
   8902                          RegisterOperand listtype,
   8903                          RegisterOperand GPR64pi> {
   8904   def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
   8905                             (outs listtype:$dst),
   8906                             (ins listtype:$Vt, VectorIndexH:$idx,
   8907                                  GPR64sp:$Rn), []>;
   8908 
   8909   def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
   8910                             (outs GPR64sp:$wback, listtype:$dst),
   8911                             (ins listtype:$Vt, VectorIndexH:$idx,
   8912                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
   8913 }
   8914 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   8915 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
   8916                          RegisterOperand listtype,
   8917                          RegisterOperand GPR64pi> {
   8918   def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
   8919                             (outs listtype:$dst),
   8920                             (ins listtype:$Vt, VectorIndexS:$idx,
   8921                                  GPR64sp:$Rn), []>;
   8922 
   8923   def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
   8924                             (outs GPR64sp:$wback, listtype:$dst),
   8925                             (ins listtype:$Vt, VectorIndexS:$idx,
   8926                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
   8927 }
   8928 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
   8929 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
   8930                          RegisterOperand listtype, RegisterOperand GPR64pi> {
   8931   def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
   8932                             (outs listtype:$dst),
   8933                             (ins listtype:$Vt, VectorIndexD:$idx,
   8934                                  GPR64sp:$Rn), []>;
   8935 
   8936   def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
   8937                             (outs GPR64sp:$wback, listtype:$dst),
   8938                             (ins listtype:$Vt, VectorIndexD:$idx,
   8939                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
   8940 }
   8941 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   8942 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
   8943                          RegisterOperand listtype, RegisterOperand GPR64pi> {
   8944   def i8 : SIMDLdStSingleB<0, R, opcode, asm,
   8945                            (outs), (ins listtype:$Vt, VectorIndexB:$idx,
   8946                                         GPR64sp:$Rn), []>;
   8947 
   8948   def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
   8949                                     (outs GPR64sp:$wback),
   8950                                     (ins listtype:$Vt, VectorIndexB:$idx,
   8951                                          GPR64sp:$Rn, GPR64pi:$Xm)>;
   8952 }
   8953 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   8954 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
   8955                          RegisterOperand listtype, RegisterOperand GPR64pi> {
   8956   def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
   8957                             (outs), (ins listtype:$Vt, VectorIndexH:$idx,
   8958                                          GPR64sp:$Rn), []>;
   8959 
   8960   def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
   8961                             (outs GPR64sp:$wback),
   8962                             (ins listtype:$Vt, VectorIndexH:$idx,
   8963                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
   8964 }
   8965 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   8966 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
   8967                          RegisterOperand listtype, RegisterOperand GPR64pi> {
   8968   def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
   8969                             (outs), (ins listtype:$Vt, VectorIndexS:$idx,
   8970                                          GPR64sp:$Rn), []>;
   8971 
   8972   def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
   8973                             (outs GPR64sp:$wback),
   8974                             (ins listtype:$Vt, VectorIndexS:$idx,
   8975                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
   8976 }
   8977 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
   8978 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
   8979                          RegisterOperand listtype, RegisterOperand GPR64pi> {
   8980   def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
   8981                             (outs), (ins listtype:$Vt, VectorIndexD:$idx,
   8982                                          GPR64sp:$Rn), []>;
   8983 
   8984   def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
   8985                             (outs GPR64sp:$wback),
   8986                             (ins listtype:$Vt, VectorIndexD:$idx,
   8987                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
   8988 }
   8989 
   8990 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
   8991                                  string Count, int Offset, Operand idxtype> {
   8992   // E.g. "ld1 { v0.8b }[0], [x1], #1"
   8993   //      "ld1\t$Vt, [$Rn], #1"
   8994   // may get mapped to
   8995   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
   8996   def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
   8997                   (!cast<Instruction>(NAME # Type  # "_POST")
   8998                       GPR64sp:$Rn,
   8999                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
   9000                       idxtype:$idx, XZR), 1>;
   9001 
   9002   // E.g. "ld1.8b { v0 }[0], [x1], #1"
   9003   //      "ld1.8b\t$Vt, [$Rn], #1"
   9004   // may get mapped to
   9005   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
   9006   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
   9007                   (!cast<Instruction>(NAME # Type # "_POST")
   9008                       GPR64sp:$Rn,
   9009                       !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
   9010                       idxtype:$idx, XZR), 0>;
   9011 
   9012   // E.g. "ld1.8b { v0 }[0], [x1]"
   9013   //      "ld1.8b\t$Vt, [$Rn]"
   9014   // may get mapped to
   9015   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
   9016   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
   9017                       (!cast<Instruction>(NAME # Type)
   9018                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
   9019                          idxtype:$idx, GPR64sp:$Rn), 0>;
   9020 
   9021   // E.g. "ld1.8b { v0 }[0], [x1], x2"
   9022   //      "ld1.8b\t$Vt, [$Rn], $Xm"
   9023   // may get mapped to
   9024   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
   9025   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
   9026                       (!cast<Instruction>(NAME # Type # "_POST")
   9027                          GPR64sp:$Rn,
   9028                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
   9029                          idxtype:$idx,
   9030                          !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
   9031 }
   9032 
   9033 multiclass SIMDLdSt1SingleAliases<string asm> {
   9034   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "One", 1, VectorIndexB>;
   9035   defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
   9036   defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
   9037   defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
   9038 }
   9039 
   9040 multiclass SIMDLdSt2SingleAliases<string asm> {
   9041   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Two", 2,  VectorIndexB>;
   9042   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4,  VectorIndexH>;
   9043   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8,  VectorIndexS>;
   9044   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
   9045 }
   9046 
   9047 multiclass SIMDLdSt3SingleAliases<string asm> {
   9048   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Three", 3,  VectorIndexB>;
   9049   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6,  VectorIndexH>;
   9050   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
   9051   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
   9052 }
   9053 
   9054 multiclass SIMDLdSt4SingleAliases<string asm> {
   9055   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Four", 4,  VectorIndexB>;
   9056   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8,  VectorIndexH>;
   9057   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
   9058   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
   9059 }
   9060 } // end of 'let Predicates = [HasNEON]'
   9061 
   9062 //----------------------------------------------------------------------------
   9063 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
   9064 //----------------------------------------------------------------------------
   9065 
   9066 let Predicates = [HasNEON, HasV8_1a] in {
   9067 
   9068 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
   9069                                     RegisterOperand regtype, string asm, 
   9070                                     string kind, list<dag> pattern>
   9071   : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind, 
   9072                                 pattern> {
   9073 }
   9074 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
   9075                                              SDPatternOperator Accum> {
   9076   def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
   9077     [(set (v4i16 V64:$dst),
   9078           (Accum (v4i16 V64:$Rd),
   9079                  (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
   9080                                                    (v4i16 V64:$Rm)))))]>;         
   9081   def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
   9082     [(set (v8i16 V128:$dst),
   9083           (Accum (v8i16 V128:$Rd),
   9084                  (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
   9085                                                    (v8i16 V128:$Rm)))))]>;
   9086   def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
   9087     [(set (v2i32 V64:$dst),
   9088           (Accum (v2i32 V64:$Rd),
   9089                  (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
   9090                                                    (v2i32 V64:$Rm)))))]>;
   9091   def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
   9092     [(set (v4i32 V128:$dst),
   9093           (Accum (v4i32 V128:$Rd),
   9094                  (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
   9095                                                    (v4i32 V128:$Rm)))))]>;
   9096 }
   9097 
   9098 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
   9099                                      SDPatternOperator Accum> {
   9100   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
   9101                                           V64, V64, V128_lo, VectorIndexH,
   9102                                           asm, ".4h", ".4h", ".4h", ".h",
   9103     [(set (v4i16 V64:$dst),
   9104           (Accum (v4i16 V64:$Rd),
   9105                  (v4i16 (int_aarch64_neon_sqrdmulh
   9106                           (v4i16 V64:$Rn),
   9107                           (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   9108                                                     VectorIndexH:$idx))))))]> {
   9109     bits<3> idx;
   9110     let Inst{11} = idx{2};
   9111     let Inst{21} = idx{1};
   9112     let Inst{20} = idx{0};
   9113   }
   9114 
   9115   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
   9116                                           V128, V128, V128_lo, VectorIndexH,
   9117                                           asm, ".8h", ".8h", ".8h", ".h",
   9118     [(set (v8i16 V128:$dst),
   9119           (Accum (v8i16 V128:$Rd),
   9120                  (v8i16 (int_aarch64_neon_sqrdmulh
   9121                           (v8i16 V128:$Rn),
   9122                           (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
   9123                                                    VectorIndexH:$idx))))))]> {
   9124     bits<3> idx;
   9125     let Inst{11} = idx{2};
   9126     let Inst{21} = idx{1};
   9127     let Inst{20} = idx{0};
   9128   }
   9129 
   9130   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
   9131                                           V64, V64, V128, VectorIndexS,
   9132                                           asm, ".2s", ".2s", ".2s", ".s",
   9133     [(set (v2i32 V64:$dst),
   9134         (Accum (v2i32 V64:$Rd),
   9135                (v2i32 (int_aarch64_neon_sqrdmulh
   9136                         (v2i32 V64:$Rn),
   9137                         (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
   9138                                                  VectorIndexS:$idx))))))]> {
   9139     bits<2> idx;
   9140     let Inst{11} = idx{1};
   9141     let Inst{21} = idx{0};
   9142   }
   9143 
   9144   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 
   9145   // an intermediate EXTRACT_SUBREG would be untyped.
   9146   // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we 
   9147   // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
   9148   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
   9149                        (i32 (vector_extract 
   9150                                (v4i32 (insert_subvector
   9151                                        (undef), 
   9152                                         (v2i32 (int_aarch64_neon_sqrdmulh 
   9153                                                  (v2i32 V64:$Rn),
   9154                                                  (v2i32 (AArch64duplane32 
   9155                                                           (v4i32 V128:$Rm),
   9156                                                           VectorIndexS:$idx)))),
   9157                                       (i32 0))),
   9158                                (i64 0))))),
   9159             (EXTRACT_SUBREG
   9160                 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
   9161                           (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), 
   9162                                                 FPR32Op:$Rd, 
   9163                                                 ssub)), 
   9164                           V64:$Rn,
   9165                           V128:$Rm, 
   9166                           VectorIndexS:$idx)),
   9167                 ssub)>;
   9168 
   9169   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
   9170                                           V128, V128, V128, VectorIndexS,
   9171                                           asm, ".4s", ".4s", ".4s", ".s",
   9172     [(set (v4i32 V128:$dst),
   9173           (Accum (v4i32 V128:$Rd),
   9174                  (v4i32 (int_aarch64_neon_sqrdmulh
   9175                           (v4i32 V128:$Rn),
   9176                           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
   9177                                                    VectorIndexS:$idx))))))]> {
   9178     bits<2> idx;
   9179     let Inst{11} = idx{1};
   9180     let Inst{21} = idx{0};
   9181   }
   9182 
   9183   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
   9184   // an intermediate EXTRACT_SUBREG would be untyped.
   9185   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
   9186                         (i32 (vector_extract 
   9187                                (v4i32 (int_aarch64_neon_sqrdmulh 
   9188                                         (v4i32 V128:$Rn),
   9189                                         (v4i32 (AArch64duplane32 
   9190                                                  (v4i32 V128:$Rm),
   9191                                                  VectorIndexS:$idx)))),
   9192                                (i64 0))))),
   9193             (EXTRACT_SUBREG
   9194                 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
   9195                          (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 
   9196                                                FPR32Op:$Rd, 
   9197                                                ssub)), 
   9198                          V128:$Rn,
   9199                          V128:$Rm, 
   9200                          VectorIndexS:$idx)),
   9201                 ssub)>;
   9202 
   9203   def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
   9204                                         FPR16Op, FPR16Op, V128_lo,
   9205                                         VectorIndexH, asm, ".h", "", "", ".h", 
   9206                                         []> {
   9207     bits<3> idx;
   9208     let Inst{11} = idx{2};
   9209     let Inst{21} = idx{1};
   9210     let Inst{20} = idx{0};
   9211   }
   9212 
   9213   def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
   9214                                         FPR32Op, FPR32Op, V128, VectorIndexS,
   9215                                         asm, ".s", "", "", ".s",
   9216     [(set (i32 FPR32Op:$dst),
   9217           (Accum (i32 FPR32Op:$Rd),
   9218                  (i32 (int_aarch64_neon_sqrdmulh
   9219                         (i32 FPR32Op:$Rn),
   9220                         (i32 (vector_extract (v4i32 V128:$Rm),
   9221                                              VectorIndexS:$idx))))))]> {
   9222     bits<2> idx;
   9223     let Inst{11} = idx{1};
   9224     let Inst{21} = idx{0};
   9225   }
   9226 }
   9227 } // let Predicates = [HasNeon, HasV8_1a]
   9228 
   9229 //----------------------------------------------------------------------------
   9230 // Crypto extensions
   9231 //----------------------------------------------------------------------------
   9232 
   9233 let Predicates = [HasCrypto] in {
   9234 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   9235 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
   9236               list<dag> pat>
   9237   : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
   9238     Sched<[WriteV]>{
   9239   bits<5> Rd;
   9240   bits<5> Rn;
   9241   let Inst{31-16} = 0b0100111000101000;
   9242   let Inst{15-12} = opc;
   9243   let Inst{11-10} = 0b10;
   9244   let Inst{9-5}   = Rn;
   9245   let Inst{4-0}   = Rd;
   9246 }
   9247 
   9248 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
   9249   : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
   9250             [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
   9251 
   9252 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
   9253   : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
   9254             "$Rd = $dst",
   9255             [(set (v16i8 V128:$dst),
   9256                   (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
   9257 
   9258 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   9259 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
   9260                      dag oops, dag iops, list<dag> pat>
   9261   : I<oops, iops, asm,
   9262       "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
   9263       "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
   9264     Sched<[WriteV]>{
   9265   bits<5> Rd;
   9266   bits<5> Rn;
   9267   bits<5> Rm;
   9268   let Inst{31-21} = 0b01011110000;
   9269   let Inst{20-16} = Rm;
   9270   let Inst{15}    = 0;
   9271   let Inst{14-12} = opc;
   9272   let Inst{11-10} = 0b00;
   9273   let Inst{9-5}   = Rn;
   9274   let Inst{4-0}   = Rd;
   9275 }
   9276 
   9277 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
   9278   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
   9279                    (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
   9280                    [(set (v4i32 FPR128:$dst),
   9281                          (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
   9282                                  (v4i32 V128:$Rm)))]>;
   9283 
   9284 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
   9285   : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
   9286                    (ins V128:$Rd, V128:$Rn, V128:$Rm),
   9287                    [(set (v4i32 V128:$dst),
   9288                          (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
   9289                                  (v4i32 V128:$Rm)))]>;
   9290 
   9291 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
   9292   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
   9293                    (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
   9294                    [(set (v4i32 FPR128:$dst),
   9295                          (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
   9296                                  (v4i32 V128:$Rm)))]>;
   9297 
   9298 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
   9299 class SHA2OpInst<bits<4> opc, string asm, string kind,
   9300                  string cstr, dag oops, dag iops,
   9301                  list<dag> pat>
   9302   : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
   9303                        "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
   9304     Sched<[WriteV]>{
   9305   bits<5> Rd;
   9306   bits<5> Rn;
   9307   let Inst{31-16} = 0b0101111000101000;
   9308   let Inst{15-12} = opc;
   9309   let Inst{11-10} = 0b10;
   9310   let Inst{9-5}   = Rn;
   9311   let Inst{4-0}   = Rd;
   9312 }
   9313 
   9314 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
   9315   : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
   9316                (ins V128:$Rd, V128:$Rn),
   9317                [(set (v4i32 V128:$dst),
   9318                      (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
   9319 
   9320 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
   9321   : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
   9322                [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
   9323 } // end of 'let Predicates = [HasCrypto]'
   9324 
   9325 //----------------------------------------------------------------------------
   9326 // v8.1 atomic instructions extension:
   9327 // * CAS
   9328 // * CASP
   9329 // * SWP
   9330 // * LDOPregister<OP>, and aliases STOPregister<OP>
   9331 
   9332 // Instruction encodings:
   9333 //
   9334 //      31 30|29  24|23|22|21|20 16|15|14  10|9 5|4 0
   9335 // CAS  SZ   |001000|1 |A |1 |Rs   |R |11111 |Rn |Rt
   9336 // CASP  0|SZ|001000|0 |A |1 |Rs   |R |11111 |Rn |Rt
   9337 // SWP  SZ   |111000|A |R |1 |Rs   |1 |OPC|00|Rn |Rt
   9338 // LD   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |Rt
   9339 // ST   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |11111
   9340 
   9341 // Instruction syntax:
   9342 //
   9343 // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
   9344 // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
   9345 // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
   9346 // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
   9347 // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
   9348 // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
   9349 // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
   9350 // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
   9351 // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
   9352 // ST<OP>{<order>} <Xs>, [<Xn|SP>]
   9353 
   9354 let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
   9355 class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
   9356                       string cstr, list<dag> pattern>
   9357       : I<oops, iops, asm, operands, cstr, pattern> {
   9358   bits<2> Sz;
   9359   bit NP;
   9360   bit Acq;
   9361   bit Rel;
   9362   bits<5> Rs;
   9363   bits<5> Rn;
   9364   bits<5> Rt;
   9365   let Inst{31-30} = Sz;
   9366   let Inst{29-24} = 0b001000;
   9367   let Inst{23} = NP;
   9368   let Inst{22} = Acq;
   9369   let Inst{21} = 0b1;
   9370   let Inst{20-16} = Rs;
   9371   let Inst{15} = Rel;
   9372   let Inst{14-10} = 0b11111;
   9373   let Inst{9-5} = Rn;
   9374   let Inst{4-0} = Rt;
   9375 }
   9376 
   9377 class BaseCAS<string order, string size, RegisterClass RC>
   9378       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
   9379                         "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
   9380                         "$out = $Rs",[]> {
   9381   let NP = 1;
   9382 }
   9383 
   9384 multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
   9385   let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseCAS<order, "b", GPR32>;
   9386   let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseCAS<order, "h", GPR32>;
   9387   let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseCAS<order, "", GPR32>;
   9388   let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseCAS<order, "", GPR64>;
   9389 }
   9390 
   9391 class BaseCASP<string order, string size, RegisterOperand RC>
   9392       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
   9393                         "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
   9394                         "$out = $Rs",[]> {
   9395   let NP = 0;
   9396 }
   9397 
   9398 multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
   9399   let Sz = 0b00, Acq = Acq, Rel = Rel in 
   9400     def s : BaseCASP<order, "", WSeqPairClassOperand>;
   9401   let Sz = 0b01, Acq = Acq, Rel = Rel in 
   9402     def d : BaseCASP<order, "", XSeqPairClassOperand>;
   9403 }
   9404 
   9405 let Predicates = [HasV8_1a] in
   9406 class BaseSWP<string order, string size, RegisterClass RC>
   9407       : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
   9408           "\t$Rs, $Rt, [$Rn]","",[]> {
   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   bits<2> Sz;
   9441   bit Acq;
   9442   bit Rel;
   9443   bits<5> Rs;
   9444   bits<3> opc;
   9445   bits<5> Rn;
   9446   bits<5> Rt;
   9447   let Inst{31-30} = Sz;
   9448   let Inst{29-24} = 0b111000;
   9449   let Inst{23} = Acq;
   9450   let Inst{22} = Rel;
   9451   let Inst{21} = 0b1;
   9452   let Inst{20-16} = Rs;
   9453   let Inst{15} = 0b0;
   9454   let Inst{14-12} = opc;
   9455   let Inst{11-10} = 0b00;
   9456   let Inst{9-5} = Rn;
   9457   let Inst{4-0} = Rt;
   9458 }
   9459 
   9460 multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 
   9461                         string order> {
   9462   let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 
   9463     def b : BaseLDOPregister<op, order, "b", GPR32>;
   9464   let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 
   9465     def h : BaseLDOPregister<op, order, "h", GPR32>;
   9466   let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 
   9467     def s : BaseLDOPregister<op, order, "", GPR32>;
   9468   let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 
   9469     def d : BaseLDOPregister<op, order, "", GPR64>;
   9470 }
   9471 
   9472 let Predicates = [HasV8_1a] in
   9473 class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
   9474                         Instruction inst> :
   9475       InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
   9476 
   9477 multiclass STOPregister<string asm, string instr> {
   9478   def : BaseSTOPregister<asm # "lb", GPR32, WZR, 
   9479                     !cast<Instruction>(instr # "Lb")>;
   9480   def : BaseSTOPregister<asm # "lh", GPR32, WZR, 
   9481                     !cast<Instruction>(instr # "Lh")>;
   9482   def : BaseSTOPregister<asm # "l",  GPR32, WZR, 
   9483                     !cast<Instruction>(instr # "Ls")>;
   9484   def : BaseSTOPregister<asm # "l",  GPR64, XZR, 
   9485                     !cast<Instruction>(instr # "Ld")>;
   9486   def : BaseSTOPregister<asm # "b",  GPR32, WZR, 
   9487                     !cast<Instruction>(instr # "b")>;
   9488   def : BaseSTOPregister<asm # "h",  GPR32, WZR, 
   9489                     !cast<Instruction>(instr # "h")>;
   9490   def : BaseSTOPregister<asm,        GPR32, WZR, 
   9491                     !cast<Instruction>(instr # "s")>;
   9492   def : BaseSTOPregister<asm,        GPR64, XZR, 
   9493                     !cast<Instruction>(instr # "d")>;
   9494 }
   9495 
   9496 //----------------------------------------------------------------------------
   9497 // Allow the size specifier tokens to be upper case, not just lower.
   9498 def : TokenAlias<".8B", ".8b">;
   9499 def : TokenAlias<".4H", ".4h">;
   9500 def : TokenAlias<".2S", ".2s">;
   9501 def : TokenAlias<".1D", ".1d">;
   9502 def : TokenAlias<".16B", ".16b">;
   9503 def : TokenAlias<".8H", ".8h">;
   9504 def : TokenAlias<".4S", ".4s">;
   9505 def : TokenAlias<".2D", ".2d">;
   9506 def : TokenAlias<".1Q", ".1q">;
   9507 def : TokenAlias<".2H", ".2h">;
   9508 def : TokenAlias<".B", ".b">;
   9509 def : TokenAlias<".H", ".h">;
   9510 def : TokenAlias<".S", ".s">;
   9511 def : TokenAlias<".D", ".d">;
   9512 def : TokenAlias<".Q", ".q">;
   9513