Home | History | Annotate | Download | only in ARM
      1 //===-- ARMInstrVFP.td - VFP support for ARM ---------------*- tablegen -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file describes the ARM VFP instruction set.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 def SDT_CMPFP0  : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
     15 def SDT_VMOVDRR : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>,
     16                                        SDTCisSameAs<1, 2>]>;
     17 
     18 def arm_fmstat : SDNode<"ARMISD::FMSTAT",  SDTNone, [SDNPInGlue, SDNPOutGlue]>;
     19 def arm_cmpfp  : SDNode<"ARMISD::CMPFP",   SDT_ARMCmp, [SDNPOutGlue]>;
     20 def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0", SDT_CMPFP0, [SDNPOutGlue]>;
     21 def arm_fmdrr  : SDNode<"ARMISD::VMOVDRR", SDT_VMOVDRR>;
     22 
     23 //===----------------------------------------------------------------------===//
     24 // Operand Definitions.
     25 //
     26 
     27 // 8-bit floating-point immediate encodings.
     28 def FPImmOperand : AsmOperandClass {
     29   let Name = "FPImm";
     30   let ParserMethod = "parseFPImm";
     31 }
     32 
     33 def vfp_f16imm : Operand<f16>,
     34                  PatLeaf<(f16 fpimm), [{
     35       return ARM_AM::getFP16Imm(N->getValueAPF()) != -1;
     36     }], SDNodeXForm<fpimm, [{
     37       APFloat InVal = N->getValueAPF();
     38       uint32_t enc = ARM_AM::getFP16Imm(InVal);
     39       return CurDAG->getTargetConstant(enc, MVT::i32);
     40     }]>> {
     41   let PrintMethod = "printFPImmOperand";
     42   let ParserMatchClass = FPImmOperand;
     43 }
     44 
     45 def vfp_f32imm : Operand<f32>,
     46                  PatLeaf<(f32 fpimm), [{
     47       return ARM_AM::getFP32Imm(N->getValueAPF()) != -1;
     48     }], SDNodeXForm<fpimm, [{
     49       APFloat InVal = N->getValueAPF();
     50       uint32_t enc = ARM_AM::getFP32Imm(InVal);
     51       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
     52     }]>> {
     53   let PrintMethod = "printFPImmOperand";
     54   let ParserMatchClass = FPImmOperand;
     55 }
     56 
     57 def vfp_f64imm : Operand<f64>,
     58                  PatLeaf<(f64 fpimm), [{
     59       return ARM_AM::getFP64Imm(N->getValueAPF()) != -1;
     60     }], SDNodeXForm<fpimm, [{
     61       APFloat InVal = N->getValueAPF();
     62       uint32_t enc = ARM_AM::getFP64Imm(InVal);
     63       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
     64     }]>> {
     65   let PrintMethod = "printFPImmOperand";
     66   let ParserMatchClass = FPImmOperand;
     67 }
     68 
     69 def alignedload32 : PatFrag<(ops node:$ptr), (load node:$ptr), [{
     70   return cast<LoadSDNode>(N)->getAlignment() >= 4;
     71 }]>;
     72 
     73 def alignedstore32 : PatFrag<(ops node:$val, node:$ptr),
     74                              (store node:$val, node:$ptr), [{
     75   return cast<StoreSDNode>(N)->getAlignment() >= 4;
     76 }]>;
     77 
     78 // The VCVT to/from fixed-point instructions encode the 'fbits' operand
     79 // (the number of fixed bits) differently than it appears in the assembly
     80 // source. It's encoded as "Size - fbits" where Size is the size of the
     81 // fixed-point representation (32 or 16) and fbits is the value appearing
     82 // in the assembly source, an integer in [0,16] or (0,32], depending on size.
     83 def fbits32_asm_operand : AsmOperandClass { let Name = "FBits32"; }
     84 def fbits32 : Operand<i32> {
     85   let PrintMethod = "printFBits32";
     86   let ParserMatchClass = fbits32_asm_operand;
     87 }
     88 
     89 def fbits16_asm_operand : AsmOperandClass { let Name = "FBits16"; }
     90 def fbits16 : Operand<i32> {
     91   let PrintMethod = "printFBits16";
     92   let ParserMatchClass = fbits16_asm_operand;
     93 }
     94 
     95 //===----------------------------------------------------------------------===//
     96 //  Load / store Instructions.
     97 //
     98 
     99 let canFoldAsLoad = 1, isReMaterializable = 1 in {
    100 
    101 def VLDRD : ADI5<0b1101, 0b01, (outs DPR:$Dd), (ins addrmode5:$addr),
    102                  IIC_fpLoad64, "vldr", "\t$Dd, $addr",
    103                  [(set DPR:$Dd, (f64 (alignedload32 addrmode5:$addr)))]>;
    104 
    105 def VLDRS : ASI5<0b1101, 0b01, (outs SPR:$Sd), (ins addrmode5:$addr),
    106                  IIC_fpLoad32, "vldr", "\t$Sd, $addr",
    107                  [(set SPR:$Sd, (alignedload32 addrmode5:$addr))]> {
    108   // Some single precision VFP instructions may be executed on both NEON and VFP
    109   // pipelines.
    110   let D = VFPNeonDomain;
    111 }
    112 
    113 def VLDRH : AHI5<0b1101, 0b01, (outs SPR:$Sd), (ins addrmode5fp16:$addr),
    114                  IIC_fpLoad16, "vldr", ".16\t$Sd, $addr",
    115                  []>,
    116             Requires<[HasFullFP16]>;
    117 
    118 } // End of 'let canFoldAsLoad = 1, isReMaterializable = 1 in'
    119 
    120 def VSTRD : ADI5<0b1101, 0b00, (outs), (ins DPR:$Dd, addrmode5:$addr),
    121                  IIC_fpStore64, "vstr", "\t$Dd, $addr",
    122                  [(alignedstore32 (f64 DPR:$Dd), addrmode5:$addr)]>;
    123 
    124 def VSTRS : ASI5<0b1101, 0b00, (outs), (ins SPR:$Sd, addrmode5:$addr),
    125                  IIC_fpStore32, "vstr", "\t$Sd, $addr",
    126                  [(alignedstore32 SPR:$Sd, addrmode5:$addr)]> {
    127   // Some single precision VFP instructions may be executed on both NEON and VFP
    128   // pipelines.
    129   let D = VFPNeonDomain;
    130 }
    131 
    132 def VSTRH : AHI5<0b1101, 0b00, (outs), (ins SPR:$Sd, addrmode5fp16:$addr),
    133                  IIC_fpStore16, "vstr", ".16\t$Sd, $addr",
    134                  []>,
    135             Requires<[HasFullFP16]>;
    136 
    137 //===----------------------------------------------------------------------===//
    138 //  Load / store multiple Instructions.
    139 //
    140 
    141 multiclass vfp_ldst_mult<string asm, bit L_bit,
    142                          InstrItinClass itin, InstrItinClass itin_upd> {
    143   // Double Precision
    144   def DIA :
    145     AXDI4<(outs), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops),
    146           IndexModeNone, itin,
    147           !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
    148     let Inst{24-23} = 0b01;       // Increment After
    149     let Inst{21}    = 0;          // No writeback
    150     let Inst{20}    = L_bit;
    151   }
    152   def DIA_UPD :
    153     AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs,
    154                                variable_ops),
    155           IndexModeUpd, itin_upd,
    156           !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
    157     let Inst{24-23} = 0b01;       // Increment After
    158     let Inst{21}    = 1;          // Writeback
    159     let Inst{20}    = L_bit;
    160   }
    161   def DDB_UPD :
    162     AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs,
    163                                variable_ops),
    164           IndexModeUpd, itin_upd,
    165           !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
    166     let Inst{24-23} = 0b10;       // Decrement Before
    167     let Inst{21}    = 1;          // Writeback
    168     let Inst{20}    = L_bit;
    169   }
    170 
    171   // Single Precision
    172   def SIA :
    173     AXSI4<(outs), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops),
    174           IndexModeNone, itin,
    175           !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
    176     let Inst{24-23} = 0b01;       // Increment After
    177     let Inst{21}    = 0;          // No writeback
    178     let Inst{20}    = L_bit;
    179 
    180     // Some single precision VFP instructions may be executed on both NEON and
    181     // VFP pipelines.
    182     let D = VFPNeonDomain;
    183   }
    184   def SIA_UPD :
    185     AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs,
    186                                variable_ops),
    187           IndexModeUpd, itin_upd,
    188           !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
    189     let Inst{24-23} = 0b01;       // Increment After
    190     let Inst{21}    = 1;          // Writeback
    191     let Inst{20}    = L_bit;
    192 
    193     // Some single precision VFP instructions may be executed on both NEON and
    194     // VFP pipelines.
    195     let D = VFPNeonDomain;
    196   }
    197   def SDB_UPD :
    198     AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs,
    199                                variable_ops),
    200           IndexModeUpd, itin_upd,
    201           !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
    202     let Inst{24-23} = 0b10;       // Decrement Before
    203     let Inst{21}    = 1;          // Writeback
    204     let Inst{20}    = L_bit;
    205 
    206     // Some single precision VFP instructions may be executed on both NEON and
    207     // VFP pipelines.
    208     let D = VFPNeonDomain;
    209   }
    210 }
    211 
    212 let hasSideEffects = 0 in {
    213 
    214 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
    215 defm VLDM : vfp_ldst_mult<"vldm", 1, IIC_fpLoad_m, IIC_fpLoad_mu>;
    216 
    217 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
    218 defm VSTM : vfp_ldst_mult<"vstm", 0, IIC_fpStore_m, IIC_fpStore_mu>;
    219 
    220 } // hasSideEffects
    221 
    222 def : MnemonicAlias<"vldm", "vldmia">;
    223 def : MnemonicAlias<"vstm", "vstmia">;
    224 
    225 
    226 //===----------------------------------------------------------------------===//
    227 //  Lazy load / store multiple Instructions
    228 //
    229 let mayLoad = 1 in
    230 def VLLDM : AXSI4<(outs), (ins GPRnopc:$Rn, pred:$p), IndexModeNone,
    231                   IIC_fpLoad_m, "vlldm${p}\t$Rn", "", []>,
    232             Requires<[HasV8MMainline, Has8MSecExt]> {
    233     let Inst{24-23} = 0b00;
    234     let Inst{22}    = 0;
    235     let Inst{21}    = 1;
    236     let Inst{20}    = 1;
    237     let Inst{15-12} = 0;
    238     let Inst{7-0}   = 0;
    239     let mayLoad     = 1;
    240 }
    241 
    242 let mayStore = 1 in
    243 def VLSTM : AXSI4<(outs), (ins GPRnopc:$Rn, pred:$p), IndexModeNone,
    244                   IIC_fpStore_m, "vlstm${p}\t$Rn", "", []>,
    245             Requires<[HasV8MMainline, Has8MSecExt]> {
    246     let Inst{24-23} = 0b00;
    247     let Inst{22}    = 0;
    248     let Inst{21}    = 1;
    249     let Inst{20}    = 0;
    250     let Inst{15-12} = 0;
    251     let Inst{7-0}   = 0;
    252     let mayStore    = 1;
    253 }
    254 
    255 
    256 // FLDM/FSTM - Load / Store multiple single / double precision registers for
    257 // pre-ARMv6 cores.
    258 // These instructions are deprecated!
    259 def : VFP2MnemonicAlias<"fldmias", "vldmia">;
    260 def : VFP2MnemonicAlias<"fldmdbs", "vldmdb">;
    261 def : VFP2MnemonicAlias<"fldmeas", "vldmdb">;
    262 def : VFP2MnemonicAlias<"fldmfds", "vldmia">;
    263 def : VFP2MnemonicAlias<"fldmiad", "vldmia">;
    264 def : VFP2MnemonicAlias<"fldmdbd", "vldmdb">;
    265 def : VFP2MnemonicAlias<"fldmead", "vldmdb">;
    266 def : VFP2MnemonicAlias<"fldmfdd", "vldmia">;
    267 
    268 def : VFP2MnemonicAlias<"fstmias", "vstmia">;
    269 def : VFP2MnemonicAlias<"fstmdbs", "vstmdb">;
    270 def : VFP2MnemonicAlias<"fstmeas", "vstmia">;
    271 def : VFP2MnemonicAlias<"fstmfds", "vstmdb">;
    272 def : VFP2MnemonicAlias<"fstmiad", "vstmia">;
    273 def : VFP2MnemonicAlias<"fstmdbd", "vstmdb">;
    274 def : VFP2MnemonicAlias<"fstmead", "vstmia">;
    275 def : VFP2MnemonicAlias<"fstmfdd", "vstmdb">;
    276 
    277 def : InstAlias<"vpush${p} $r", (VSTMDDB_UPD SP, pred:$p, dpr_reglist:$r), 0>,
    278                 Requires<[HasVFP2]>;
    279 def : InstAlias<"vpush${p} $r", (VSTMSDB_UPD SP, pred:$p, spr_reglist:$r), 0>,
    280                 Requires<[HasVFP2]>;
    281 def : InstAlias<"vpop${p} $r",  (VLDMDIA_UPD SP, pred:$p, dpr_reglist:$r), 0>,
    282                 Requires<[HasVFP2]>;
    283 def : InstAlias<"vpop${p} $r",  (VLDMSIA_UPD SP, pred:$p, spr_reglist:$r), 0>,
    284                 Requires<[HasVFP2]>;
    285 defm : VFPDTAnyInstAlias<"vpush${p}", "$r",
    286                          (VSTMSDB_UPD SP, pred:$p, spr_reglist:$r)>;
    287 defm : VFPDTAnyInstAlias<"vpush${p}", "$r",
    288                          (VSTMDDB_UPD SP, pred:$p, dpr_reglist:$r)>;
    289 defm : VFPDTAnyInstAlias<"vpop${p}", "$r",
    290                          (VLDMSIA_UPD SP, pred:$p, spr_reglist:$r)>;
    291 defm : VFPDTAnyInstAlias<"vpop${p}", "$r",
    292                          (VLDMDIA_UPD SP, pred:$p, dpr_reglist:$r)>;
    293 
    294 // FLDMX, FSTMX - Load and store multiple unknown precision registers for
    295 // pre-armv6 cores.
    296 // These instruction are deprecated so we don't want them to get selected.
    297 multiclass vfp_ldstx_mult<string asm, bit L_bit> {
    298   // Unknown precision
    299   def XIA :
    300     AXXI4<(outs), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops),
    301           IndexModeNone, !strconcat(asm, "iax${p}\t$Rn, $regs"), "", []> {
    302     let Inst{24-23} = 0b01;       // Increment After
    303     let Inst{21}    = 0;          // No writeback
    304     let Inst{20}    = L_bit;
    305   }
    306   def XIA_UPD :
    307     AXXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops),
    308           IndexModeUpd, !strconcat(asm, "iax${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
    309     let Inst{24-23} = 0b01;         // Increment After
    310     let Inst{21}    = 1;            // Writeback
    311     let Inst{20}    = L_bit;
    312   }
    313   def XDB_UPD :
    314     AXXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops),
    315           IndexModeUpd, !strconcat(asm, "dbx${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
    316     let Inst{24-23} = 0b10;         // Decrement Before
    317     let Inst{21}    = 1;            // Writeback
    318     let Inst{20}    = L_bit;
    319   }
    320 }
    321 
    322 defm FLDM : vfp_ldstx_mult<"fldm", 1>;
    323 defm FSTM : vfp_ldstx_mult<"fstm", 0>;
    324 
    325 def : VFP2MnemonicAlias<"fldmeax", "fldmdbx">;
    326 def : VFP2MnemonicAlias<"fldmfdx", "fldmiax">;
    327 
    328 def : VFP2MnemonicAlias<"fstmeax", "fstmiax">;
    329 def : VFP2MnemonicAlias<"fstmfdx", "fstmdbx">;
    330 
    331 //===----------------------------------------------------------------------===//
    332 // FP Binary Operations.
    333 //
    334 
    335 let TwoOperandAliasConstraint = "$Dn = $Dd" in
    336 def VADDD  : ADbI<0b11100, 0b11, 0, 0,
    337                   (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
    338                   IIC_fpALU64, "vadd", ".f64\t$Dd, $Dn, $Dm",
    339                   [(set DPR:$Dd, (fadd DPR:$Dn, (f64 DPR:$Dm)))]>;
    340 
    341 let TwoOperandAliasConstraint = "$Sn = $Sd" in
    342 def VADDS  : ASbIn<0b11100, 0b11, 0, 0,
    343                    (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
    344                    IIC_fpALU32, "vadd", ".f32\t$Sd, $Sn, $Sm",
    345                    [(set SPR:$Sd, (fadd SPR:$Sn, SPR:$Sm))]> {
    346   // Some single precision VFP instructions may be executed on both NEON and
    347   // VFP pipelines on A8.
    348   let D = VFPNeonA8Domain;
    349 }
    350 
    351 let TwoOperandAliasConstraint = "$Sn = $Sd" in
    352 def VADDH  : AHbI<0b11100, 0b11, 0, 0,
    353                   (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
    354                   IIC_fpALU16, "vadd", ".f16\t$Sd, $Sn, $Sm",
    355                   []>;
    356 
    357 let TwoOperandAliasConstraint = "$Dn = $Dd" in
    358 def VSUBD  : ADbI<0b11100, 0b11, 1, 0,
    359                   (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
    360                   IIC_fpALU64, "vsub", ".f64\t$Dd, $Dn, $Dm",
    361                   [(set DPR:$Dd, (fsub DPR:$Dn, (f64 DPR:$Dm)))]>;
    362 
    363 let TwoOperandAliasConstraint = "$Sn = $Sd" in
    364 def VSUBS  : ASbIn<0b11100, 0b11, 1, 0,
    365                    (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
    366                    IIC_fpALU32, "vsub", ".f32\t$Sd, $Sn, $Sm",
    367                    [(set SPR:$Sd, (fsub SPR:$Sn, SPR:$Sm))]> {
    368   // Some single precision VFP instructions may be executed on both NEON and
    369   // VFP pipelines on A8.
    370   let D = VFPNeonA8Domain;
    371 }
    372 
    373 let TwoOperandAliasConstraint = "$Sn = $Sd" in
    374 def VSUBH  : AHbI<0b11100, 0b11, 1, 0,
    375                   (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
    376                   IIC_fpALU16, "vsub", ".f16\t$Sd, $Sn, $Sm",
    377                   []>;
    378 
    379 let TwoOperandAliasConstraint = "$Dn = $Dd" in
    380 def VDIVD  : ADbI<0b11101, 0b00, 0, 0,
    381                   (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
    382                   IIC_fpDIV64, "vdiv", ".f64\t$Dd, $Dn, $Dm",
    383                   [(set DPR:$Dd, (fdiv DPR:$Dn, (f64 DPR:$Dm)))]>;
    384 
    385 let TwoOperandAliasConstraint = "$Sn = $Sd" in
    386 def VDIVS  : ASbI<0b11101, 0b00, 0, 0,
    387                   (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
    388                   IIC_fpDIV32, "vdiv", ".f32\t$Sd, $Sn, $Sm",
    389                   [(set SPR:$Sd, (fdiv SPR:$Sn, SPR:$Sm))]>;
    390 
    391 let TwoOperandAliasConstraint = "$Sn = $Sd" in
    392 def VDIVH  : AHbI<0b11101, 0b00, 0, 0,
    393                   (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
    394                   IIC_fpDIV16, "vdiv", ".f16\t$Sd, $Sn, $Sm",
    395                   []>;
    396 
    397 let TwoOperandAliasConstraint = "$Dn = $Dd" in
    398 def VMULD  : ADbI<0b11100, 0b10, 0, 0,
    399                   (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
    400                   IIC_fpMUL64, "vmul", ".f64\t$Dd, $Dn, $Dm",
    401                   [(set DPR:$Dd, (fmul DPR:$Dn, (f64 DPR:$Dm)))]>;
    402 
    403 let TwoOperandAliasConstraint = "$Sn = $Sd" in
    404 def VMULS  : ASbIn<0b11100, 0b10, 0, 0,
    405                    (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
    406                    IIC_fpMUL32, "vmul", ".f32\t$Sd, $Sn, $Sm",
    407                    [(set SPR:$Sd, (fmul SPR:$Sn, SPR:$Sm))]> {
    408   // Some single precision VFP instructions may be executed on both NEON and
    409   // VFP pipelines on A8.
    410   let D = VFPNeonA8Domain;
    411 }
    412 
    413 let TwoOperandAliasConstraint = "$Sn = $Sd" in
    414 def VMULH  : AHbI<0b11100, 0b10, 0, 0,
    415                   (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
    416                   IIC_fpMUL16, "vmul", ".f16\t$Sd, $Sn, $Sm",
    417                   []>;
    418 
    419 def VNMULD : ADbI<0b11100, 0b10, 1, 0,
    420                   (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
    421                   IIC_fpMUL64, "vnmul", ".f64\t$Dd, $Dn, $Dm",
    422                   [(set DPR:$Dd, (fneg (fmul DPR:$Dn, (f64 DPR:$Dm))))]>;
    423 
    424 def VNMULS : ASbI<0b11100, 0b10, 1, 0,
    425                   (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
    426                   IIC_fpMUL32, "vnmul", ".f32\t$Sd, $Sn, $Sm",
    427                   [(set SPR:$Sd, (fneg (fmul SPR:$Sn, SPR:$Sm)))]> {
    428   // Some single precision VFP instructions may be executed on both NEON and
    429   // VFP pipelines on A8.
    430   let D = VFPNeonA8Domain;
    431 }
    432 
    433 def VNMULH : AHbI<0b11100, 0b10, 1, 0,
    434                   (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
    435                   IIC_fpMUL16, "vnmul", ".f16\t$Sd, $Sn, $Sm",
    436                   []>;
    437 
    438 multiclass vsel_inst<string op, bits<2> opc, int CC> {
    439   let DecoderNamespace = "VFPV8", PostEncoderMethod = "",
    440       Uses = [CPSR], AddedComplexity = 4 in {
    441     def H : AHbInp<0b11100, opc, 0,
    442                    (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
    443                    NoItinerary, !strconcat("vsel", op, ".f16\t$Sd, $Sn, $Sm"),
    444                    []>,
    445                    Requires<[HasFullFP16]>;
    446 
    447     def S : ASbInp<0b11100, opc, 0,
    448                    (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
    449                    NoItinerary, !strconcat("vsel", op, ".f32\t$Sd, $Sn, $Sm"),
    450                    [(set SPR:$Sd, (ARMcmov SPR:$Sm, SPR:$Sn, CC))]>,
    451                    Requires<[HasFPARMv8]>;
    452 
    453     def D : ADbInp<0b11100, opc, 0,
    454                    (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
    455                    NoItinerary, !strconcat("vsel", op, ".f64\t$Dd, $Dn, $Dm"),
    456                    [(set DPR:$Dd, (ARMcmov (f64 DPR:$Dm), (f64 DPR:$Dn), CC))]>,
    457                    Requires<[HasFPARMv8, HasDPVFP]>;
    458   }
    459 }
    460 
    461 // The CC constants here match ARMCC::CondCodes.
    462 defm VSELGT : vsel_inst<"gt", 0b11, 12>;
    463 defm VSELGE : vsel_inst<"ge", 0b10, 10>;
    464 defm VSELEQ : vsel_inst<"eq", 0b00, 0>;
    465 defm VSELVS : vsel_inst<"vs", 0b01, 6>;
    466 
    467 multiclass vmaxmin_inst<string op, bit opc, SDNode SD> {
    468   let DecoderNamespace = "VFPV8", PostEncoderMethod = "" in {
    469     def H : AHbInp<0b11101, 0b00, opc,
    470                    (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
    471                    NoItinerary, !strconcat(op, ".f16\t$Sd, $Sn, $Sm"),
    472                    []>,
    473                    Requires<[HasFullFP16]>;
    474 
    475     def S : ASbInp<0b11101, 0b00, opc,
    476                    (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
    477                    NoItinerary, !strconcat(op, ".f32\t$Sd, $Sn, $Sm"),
    478                    [(set SPR:$Sd, (SD SPR:$Sn, SPR:$Sm))]>,
    479                    Requires<[HasFPARMv8]>;
    480 
    481     def D : ADbInp<0b11101, 0b00, opc,
    482                    (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
    483                    NoItinerary, !strconcat(op, ".f64\t$Dd, $Dn, $Dm"),
    484                    [(set DPR:$Dd, (f64 (SD (f64 DPR:$Dn), (f64 DPR:$Dm))))]>,
    485                    Requires<[HasFPARMv8, HasDPVFP]>;
    486   }
    487 }
    488 
    489 defm VMAXNM : vmaxmin_inst<"vmaxnm", 0, fmaxnum>;
    490 defm VMINNM : vmaxmin_inst<"vminnm", 1, fminnum>;
    491 
    492 // Match reassociated forms only if not sign dependent rounding.
    493 def : Pat<(fmul (fneg DPR:$a), (f64 DPR:$b)),
    494           (VNMULD DPR:$a, DPR:$b)>,
    495           Requires<[NoHonorSignDependentRounding,HasDPVFP]>;
    496 def : Pat<(fmul (fneg SPR:$a), SPR:$b),
    497           (VNMULS SPR:$a, SPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
    498 
    499 // These are encoded as unary instructions.
    500 let Defs = [FPSCR_NZCV] in {
    501 def VCMPED : ADuI<0b11101, 0b11, 0b0100, 0b11, 0,
    502                   (outs), (ins DPR:$Dd, DPR:$Dm),
    503                   IIC_fpCMP64, "vcmpe", ".f64\t$Dd, $Dm",
    504                   [(arm_cmpfp DPR:$Dd, (f64 DPR:$Dm))]>;
    505 
    506 def VCMPES : ASuI<0b11101, 0b11, 0b0100, 0b11, 0,
    507                   (outs), (ins SPR:$Sd, SPR:$Sm),
    508                   IIC_fpCMP32, "vcmpe", ".f32\t$Sd, $Sm",
    509                   [(arm_cmpfp SPR:$Sd, SPR:$Sm)]> {
    510   // Some single precision VFP instructions may be executed on both NEON and
    511   // VFP pipelines on A8.
    512   let D = VFPNeonA8Domain;
    513 }
    514 
    515 def VCMPEH : AHuI<0b11101, 0b11, 0b0100, 0b11, 0,
    516                   (outs), (ins SPR:$Sd, SPR:$Sm),
    517                   IIC_fpCMP16, "vcmpe", ".f16\t$Sd, $Sm",
    518                   []>;
    519 
    520 
    521 // FIXME: Verify encoding after integrated assembler is working.
    522 def VCMPD  : ADuI<0b11101, 0b11, 0b0100, 0b01, 0,
    523                   (outs), (ins DPR:$Dd, DPR:$Dm),
    524                   IIC_fpCMP64, "vcmp", ".f64\t$Dd, $Dm",
    525                   [/* For disassembly only; pattern left blank */]>;
    526 
    527 def VCMPS  : ASuI<0b11101, 0b11, 0b0100, 0b01, 0,
    528                   (outs), (ins SPR:$Sd, SPR:$Sm),
    529                   IIC_fpCMP32, "vcmp", ".f32\t$Sd, $Sm",
    530                   [/* For disassembly only; pattern left blank */]> {
    531   // Some single precision VFP instructions may be executed on both NEON and
    532   // VFP pipelines on A8.
    533   let D = VFPNeonA8Domain;
    534 }
    535 
    536 def VCMPH  : AHuI<0b11101, 0b11, 0b0100, 0b01, 0,
    537                   (outs), (ins SPR:$Sd, SPR:$Sm),
    538                   IIC_fpCMP16, "vcmp", ".f16\t$Sd, $Sm",
    539                   []>;
    540 } // Defs = [FPSCR_NZCV]
    541 
    542 //===----------------------------------------------------------------------===//
    543 // FP Unary Operations.
    544 //
    545 
    546 def VABSD  : ADuI<0b11101, 0b11, 0b0000, 0b11, 0,
    547                   (outs DPR:$Dd), (ins DPR:$Dm),
    548                   IIC_fpUNA64, "vabs", ".f64\t$Dd, $Dm",
    549                   [(set DPR:$Dd, (fabs (f64 DPR:$Dm)))]>;
    550 
    551 def VABSS  : ASuIn<0b11101, 0b11, 0b0000, 0b11, 0,
    552                    (outs SPR:$Sd), (ins SPR:$Sm),
    553                    IIC_fpUNA32, "vabs", ".f32\t$Sd, $Sm",
    554                    [(set SPR:$Sd, (fabs SPR:$Sm))]> {
    555   // Some single precision VFP instructions may be executed on both NEON and
    556   // VFP pipelines on A8.
    557   let D = VFPNeonA8Domain;
    558 }
    559 
    560 def VABSH  : AHuI<0b11101, 0b11, 0b0000, 0b11, 0,
    561                    (outs SPR:$Sd), (ins SPR:$Sm),
    562                    IIC_fpUNA16, "vabs", ".f16\t$Sd, $Sm",
    563                    []>;
    564 
    565 let Defs = [FPSCR_NZCV] in {
    566 def VCMPEZD : ADuI<0b11101, 0b11, 0b0101, 0b11, 0,
    567                    (outs), (ins DPR:$Dd),
    568                    IIC_fpCMP64, "vcmpe", ".f64\t$Dd, #0",
    569                    [(arm_cmpfp0 (f64 DPR:$Dd))]> {
    570   let Inst{3-0} = 0b0000;
    571   let Inst{5}   = 0;
    572 }
    573 
    574 def VCMPEZS : ASuI<0b11101, 0b11, 0b0101, 0b11, 0,
    575                    (outs), (ins SPR:$Sd),
    576                    IIC_fpCMP32, "vcmpe", ".f32\t$Sd, #0",
    577                    [(arm_cmpfp0 SPR:$Sd)]> {
    578   let Inst{3-0} = 0b0000;
    579   let Inst{5}   = 0;
    580 
    581   // Some single precision VFP instructions may be executed on both NEON and
    582   // VFP pipelines on A8.
    583   let D = VFPNeonA8Domain;
    584 }
    585 
    586 def VCMPEZH : AHuI<0b11101, 0b11, 0b0101, 0b11, 0,
    587                    (outs), (ins SPR:$Sd),
    588                    IIC_fpCMP16, "vcmpe", ".f16\t$Sd, #0",
    589                    []> {
    590   let Inst{3-0} = 0b0000;
    591   let Inst{5}   = 0;
    592 }
    593 
    594 // FIXME: Verify encoding after integrated assembler is working.
    595 def VCMPZD  : ADuI<0b11101, 0b11, 0b0101, 0b01, 0,
    596                    (outs), (ins DPR:$Dd),
    597                    IIC_fpCMP64, "vcmp", ".f64\t$Dd, #0",
    598                    [/* For disassembly only; pattern left blank */]> {
    599   let Inst{3-0} = 0b0000;
    600   let Inst{5}   = 0;
    601 }
    602 
    603 def VCMPZS  : ASuI<0b11101, 0b11, 0b0101, 0b01, 0,
    604                    (outs), (ins SPR:$Sd),
    605                    IIC_fpCMP32, "vcmp", ".f32\t$Sd, #0",
    606                    [/* For disassembly only; pattern left blank */]> {
    607   let Inst{3-0} = 0b0000;
    608   let Inst{5}   = 0;
    609 
    610   // Some single precision VFP instructions may be executed on both NEON and
    611   // VFP pipelines on A8.
    612   let D = VFPNeonA8Domain;
    613 }
    614 
    615 def VCMPZH  : AHuI<0b11101, 0b11, 0b0101, 0b01, 0,
    616                    (outs), (ins SPR:$Sd),
    617                    IIC_fpCMP16, "vcmp", ".f16\t$Sd, #0",
    618                    []> {
    619   let Inst{3-0} = 0b0000;
    620   let Inst{5}   = 0;
    621 }
    622 } // Defs = [FPSCR_NZCV]
    623 
    624 def VCVTDS  : ASuI<0b11101, 0b11, 0b0111, 0b11, 0,
    625                    (outs DPR:$Dd), (ins SPR:$Sm),
    626                    IIC_fpCVTDS, "vcvt", ".f64.f32\t$Dd, $Sm",
    627                    [(set DPR:$Dd, (fextend SPR:$Sm))]> {
    628   // Instruction operands.
    629   bits<5> Dd;
    630   bits<5> Sm;
    631 
    632   // Encode instruction operands.
    633   let Inst{3-0}   = Sm{4-1};
    634   let Inst{5}     = Sm{0};
    635   let Inst{15-12} = Dd{3-0};
    636   let Inst{22}    = Dd{4};
    637 
    638   let Predicates = [HasVFP2, HasDPVFP];
    639 }
    640 
    641 // Special case encoding: bits 11-8 is 0b1011.
    642 def VCVTSD  : VFPAI<(outs SPR:$Sd), (ins DPR:$Dm), VFPUnaryFrm,
    643                     IIC_fpCVTSD, "vcvt", ".f32.f64\t$Sd, $Dm",
    644                     [(set SPR:$Sd, (fround DPR:$Dm))]> {
    645   // Instruction operands.
    646   bits<5> Sd;
    647   bits<5> Dm;
    648 
    649   // Encode instruction operands.
    650   let Inst{3-0}   = Dm{3-0};
    651   let Inst{5}     = Dm{4};
    652   let Inst{15-12} = Sd{4-1};
    653   let Inst{22}    = Sd{0};
    654 
    655   let Inst{27-23} = 0b11101;
    656   let Inst{21-16} = 0b110111;
    657   let Inst{11-8}  = 0b1011;
    658   let Inst{7-6}   = 0b11;
    659   let Inst{4}     = 0;
    660 
    661   let Predicates = [HasVFP2, HasDPVFP];
    662 }
    663 
    664 // Between half, single and double-precision.  For disassembly only.
    665 
    666 // FIXME: Verify encoding after integrated assembler is working.
    667 def VCVTBHS: ASuI<0b11101, 0b11, 0b0010, 0b01, 0, (outs SPR:$Sd), (ins SPR:$Sm),
    668                  /* FIXME */ IIC_fpCVTSH, "vcvtb", ".f32.f16\t$Sd, $Sm",
    669                  [/* For disassembly only; pattern left blank */]>,
    670                  Requires<[HasFP16]>;
    671 
    672 def VCVTBSH: ASuI<0b11101, 0b11, 0b0011, 0b01, 0, (outs SPR:$Sd), (ins SPR:$Sm),
    673                  /* FIXME */ IIC_fpCVTHS, "vcvtb", ".f16.f32\t$Sd, $Sm",
    674                  [/* For disassembly only; pattern left blank */]>,
    675                  Requires<[HasFP16]>;
    676 
    677 def VCVTTHS: ASuI<0b11101, 0b11, 0b0010, 0b11, 0, (outs SPR:$Sd), (ins SPR:$Sm),
    678                  /* FIXME */ IIC_fpCVTSH, "vcvtt", ".f32.f16\t$Sd, $Sm",
    679                  [/* For disassembly only; pattern left blank */]>,
    680                  Requires<[HasFP16]>;
    681 
    682 def VCVTTSH: ASuI<0b11101, 0b11, 0b0011, 0b11, 0, (outs SPR:$Sd), (ins SPR:$Sm),
    683                  /* FIXME */ IIC_fpCVTHS, "vcvtt", ".f16.f32\t$Sd, $Sm",
    684                  [/* For disassembly only; pattern left blank */]>,
    685                  Requires<[HasFP16]>;
    686 
    687 def VCVTBHD : ADuI<0b11101, 0b11, 0b0010, 0b01, 0,
    688                    (outs DPR:$Dd), (ins SPR:$Sm),
    689                    NoItinerary, "vcvtb", ".f64.f16\t$Dd, $Sm",
    690                    []>, Requires<[HasFPARMv8, HasDPVFP]> {
    691   // Instruction operands.
    692   bits<5> Sm;
    693 
    694   // Encode instruction operands.
    695   let Inst{3-0} = Sm{4-1};
    696   let Inst{5}   = Sm{0};
    697 }
    698 
    699 def VCVTBDH : ADuI<0b11101, 0b11, 0b0011, 0b01, 0,
    700                    (outs SPR:$Sd), (ins DPR:$Dm),
    701                    NoItinerary, "vcvtb", ".f16.f64\t$Sd, $Dm",
    702                    []>, Requires<[HasFPARMv8, HasDPVFP]> {
    703   // Instruction operands.
    704   bits<5> Sd;
    705   bits<5> Dm;
    706 
    707   // Encode instruction operands.
    708   let Inst{3-0}     = Dm{3-0};
    709   let Inst{5}       = Dm{4};
    710   let Inst{15-12}   = Sd{4-1};
    711   let Inst{22}      = Sd{0};
    712 }
    713 
    714 def VCVTTHD : ADuI<0b11101, 0b11, 0b0010, 0b11, 0,
    715                    (outs DPR:$Dd), (ins SPR:$Sm),
    716                    NoItinerary, "vcvtt", ".f64.f16\t$Dd, $Sm",
    717                    []>, Requires<[HasFPARMv8, HasDPVFP]> {
    718   // Instruction operands.
    719   bits<5> Sm;
    720 
    721   // Encode instruction operands.
    722   let Inst{3-0} = Sm{4-1};
    723   let Inst{5}   = Sm{0};
    724 }
    725 
    726 def VCVTTDH : ADuI<0b11101, 0b11, 0b0011, 0b11, 0,
    727                    (outs SPR:$Sd), (ins DPR:$Dm),
    728                    NoItinerary, "vcvtt", ".f16.f64\t$Sd, $Dm",
    729                    []>, Requires<[HasFPARMv8, HasDPVFP]> {
    730   // Instruction operands.
    731   bits<5> Sd;
    732   bits<5> Dm;
    733 
    734   // Encode instruction operands.
    735   let Inst{15-12} = Sd{4-1};
    736   let Inst{22}    = Sd{0};
    737   let Inst{3-0}   = Dm{3-0};
    738   let Inst{5}     = Dm{4};
    739 }
    740 
    741 def : Pat<(fp_to_f16 SPR:$a),
    742           (i32 (COPY_TO_REGCLASS (VCVTBSH SPR:$a), GPR))>;
    743 
    744 def : Pat<(fp_to_f16 (f64 DPR:$a)),
    745           (i32 (COPY_TO_REGCLASS (VCVTBDH DPR:$a), GPR))>;
    746 
    747 def : Pat<(f16_to_fp GPR:$a),
    748           (VCVTBHS (COPY_TO_REGCLASS GPR:$a, SPR))>;
    749 
    750 def : Pat<(f64 (f16_to_fp GPR:$a)),
    751           (VCVTBHD (COPY_TO_REGCLASS GPR:$a, SPR))>;
    752 
    753 multiclass vcvt_inst<string opc, bits<2> rm,
    754                      SDPatternOperator node = null_frag> {
    755   let PostEncoderMethod = "", DecoderNamespace = "VFPV8" in {
    756     def SH : AHuInp<0b11101, 0b11, 0b1100, 0b11, 0,
    757                     (outs SPR:$Sd), (ins SPR:$Sm),
    758                     NoItinerary, !strconcat("vcvt", opc, ".s32.f16\t$Sd, $Sm"),
    759                     []>,
    760                     Requires<[HasFullFP16]> {
    761       let Inst{17-16} = rm;
    762     }
    763 
    764     def UH : AHuInp<0b11101, 0b11, 0b1100, 0b01, 0,
    765                     (outs SPR:$Sd), (ins SPR:$Sm),
    766                     NoItinerary, !strconcat("vcvt", opc, ".u32.f16\t$Sd, $Sm"),
    767                     []>,
    768                     Requires<[HasFullFP16]> {
    769       let Inst{17-16} = rm;
    770     }
    771 
    772     def SS : ASuInp<0b11101, 0b11, 0b1100, 0b11, 0,
    773                     (outs SPR:$Sd), (ins SPR:$Sm),
    774                     NoItinerary, !strconcat("vcvt", opc, ".s32.f32\t$Sd, $Sm"),
    775                     []>,
    776                     Requires<[HasFPARMv8]> {
    777       let Inst{17-16} = rm;
    778     }
    779 
    780     def US : ASuInp<0b11101, 0b11, 0b1100, 0b01, 0,
    781                     (outs SPR:$Sd), (ins SPR:$Sm),
    782                     NoItinerary, !strconcat("vcvt", opc, ".u32.f32\t$Sd, $Sm"),
    783                     []>,
    784                     Requires<[HasFPARMv8]> {
    785       let Inst{17-16} = rm;
    786     }
    787 
    788     def SD : ASuInp<0b11101, 0b11, 0b1100, 0b11, 0,
    789                     (outs SPR:$Sd), (ins DPR:$Dm),
    790                     NoItinerary, !strconcat("vcvt", opc, ".s32.f64\t$Sd, $Dm"),
    791                     []>,
    792                     Requires<[HasFPARMv8, HasDPVFP]> {
    793       bits<5> Dm;
    794 
    795       let Inst{17-16} = rm;
    796 
    797       // Encode instruction operands
    798       let Inst{3-0} = Dm{3-0};
    799       let Inst{5}   = Dm{4};
    800       let Inst{8} = 1;
    801     }
    802 
    803     def UD : ASuInp<0b11101, 0b11, 0b1100, 0b01, 0,
    804                     (outs SPR:$Sd), (ins DPR:$Dm),
    805                     NoItinerary, !strconcat("vcvt", opc, ".u32.f64\t$Sd, $Dm"),
    806                     []>,
    807                     Requires<[HasFPARMv8, HasDPVFP]> {
    808       bits<5> Dm;
    809 
    810       let Inst{17-16} = rm;
    811 
    812       // Encode instruction operands
    813       let Inst{3-0}  = Dm{3-0};
    814       let Inst{5}    = Dm{4};
    815       let Inst{8} = 1;
    816     }
    817   }
    818 
    819   let Predicates = [HasFPARMv8] in {
    820     def : Pat<(i32 (fp_to_sint (node SPR:$a))),
    821               (COPY_TO_REGCLASS
    822                 (!cast<Instruction>(NAME#"SS") SPR:$a),
    823                 GPR)>;
    824     def : Pat<(i32 (fp_to_uint (node SPR:$a))),
    825               (COPY_TO_REGCLASS
    826                 (!cast<Instruction>(NAME#"US") SPR:$a),
    827                 GPR)>;
    828   }
    829   let Predicates = [HasFPARMv8, HasDPVFP] in {
    830     def : Pat<(i32 (fp_to_sint (node (f64 DPR:$a)))),
    831               (COPY_TO_REGCLASS
    832                 (!cast<Instruction>(NAME#"SD") DPR:$a),
    833                 GPR)>;
    834     def : Pat<(i32 (fp_to_uint (node (f64 DPR:$a)))),
    835               (COPY_TO_REGCLASS
    836                 (!cast<Instruction>(NAME#"UD") DPR:$a),
    837                 GPR)>;
    838   }
    839 }
    840 
    841 defm VCVTA : vcvt_inst<"a", 0b00, frnd>;
    842 defm VCVTN : vcvt_inst<"n", 0b01>;
    843 defm VCVTP : vcvt_inst<"p", 0b10, fceil>;
    844 defm VCVTM : vcvt_inst<"m", 0b11, ffloor>;
    845 
    846 def VNEGD  : ADuI<0b11101, 0b11, 0b0001, 0b01, 0,
    847                   (outs DPR:$Dd), (ins DPR:$Dm),
    848                   IIC_fpUNA64, "vneg", ".f64\t$Dd, $Dm",
    849                   [(set DPR:$Dd, (fneg (f64 DPR:$Dm)))]>;
    850 
    851 def VNEGS  : ASuIn<0b11101, 0b11, 0b0001, 0b01, 0,
    852                    (outs SPR:$Sd), (ins SPR:$Sm),
    853                    IIC_fpUNA32, "vneg", ".f32\t$Sd, $Sm",
    854                    [(set SPR:$Sd, (fneg SPR:$Sm))]> {
    855   // Some single precision VFP instructions may be executed on both NEON and
    856   // VFP pipelines on A8.
    857   let D = VFPNeonA8Domain;
    858 }
    859 
    860 def VNEGH  : AHuI<0b11101, 0b11, 0b0001, 0b01, 0,
    861                   (outs SPR:$Sd), (ins SPR:$Sm),
    862                   IIC_fpUNA16, "vneg", ".f16\t$Sd, $Sm",
    863                   []>;
    864 
    865 multiclass vrint_inst_zrx<string opc, bit op, bit op2, SDPatternOperator node> {
    866   def H : AHuI<0b11101, 0b11, 0b0110, 0b11, 0,
    867                (outs SPR:$Sd), (ins SPR:$Sm),
    868                NoItinerary, !strconcat("vrint", opc), ".f16\t$Sd, $Sm",
    869                []>,
    870                Requires<[HasFullFP16]> {
    871     let Inst{7} = op2;
    872     let Inst{16} = op;
    873   }
    874 
    875   def S : ASuI<0b11101, 0b11, 0b0110, 0b11, 0,
    876                (outs SPR:$Sd), (ins SPR:$Sm),
    877                NoItinerary, !strconcat("vrint", opc), ".f32\t$Sd, $Sm",
    878                [(set (f32 SPR:$Sd), (node (f32 SPR:$Sm)))]>,
    879                Requires<[HasFPARMv8]> {
    880     let Inst{7} = op2;
    881     let Inst{16} = op;
    882   }
    883   def D : ADuI<0b11101, 0b11, 0b0110, 0b11, 0,
    884                 (outs DPR:$Dd), (ins DPR:$Dm),
    885                 NoItinerary, !strconcat("vrint", opc), ".f64\t$Dd, $Dm",
    886                 [(set (f64 DPR:$Dd), (node (f64 DPR:$Dm)))]>,
    887                 Requires<[HasFPARMv8, HasDPVFP]> {
    888     let Inst{7} = op2;
    889     let Inst{16} = op;
    890   }
    891 
    892   def : InstAlias<!strconcat("vrint", opc, "$p.f16.f16\t$Sd, $Sm"),
    893                   (!cast<Instruction>(NAME#"H") SPR:$Sd, SPR:$Sm, pred:$p), 0>,
    894         Requires<[HasFullFP16]>;
    895   def : InstAlias<!strconcat("vrint", opc, "$p.f32.f32\t$Sd, $Sm"),
    896                   (!cast<Instruction>(NAME#"S") SPR:$Sd, SPR:$Sm, pred:$p), 0>,
    897         Requires<[HasFPARMv8]>;
    898   def : InstAlias<!strconcat("vrint", opc, "$p.f64.f64\t$Dd, $Dm"),
    899                   (!cast<Instruction>(NAME#"D") DPR:$Dd, DPR:$Dm, pred:$p), 0>,
    900         Requires<[HasFPARMv8,HasDPVFP]>;
    901 }
    902 
    903 defm VRINTZ : vrint_inst_zrx<"z", 0, 1, ftrunc>;
    904 defm VRINTR : vrint_inst_zrx<"r", 0, 0, fnearbyint>;
    905 defm VRINTX : vrint_inst_zrx<"x", 1, 0, frint>;
    906 
    907 multiclass vrint_inst_anpm<string opc, bits<2> rm,
    908                            SDPatternOperator node = null_frag> {
    909   let PostEncoderMethod = "", DecoderNamespace = "VFPV8" in {
    910     def H : AHuInp<0b11101, 0b11, 0b1000, 0b01, 0,
    911                    (outs SPR:$Sd), (ins SPR:$Sm),
    912                    NoItinerary, !strconcat("vrint", opc, ".f16\t$Sd, $Sm"),
    913                    []>,
    914                    Requires<[HasFullFP16]> {
    915       let Inst{17-16} = rm;
    916     }
    917     def S : ASuInp<0b11101, 0b11, 0b1000, 0b01, 0,
    918                    (outs SPR:$Sd), (ins SPR:$Sm),
    919                    NoItinerary, !strconcat("vrint", opc, ".f32\t$Sd, $Sm"),
    920                    [(set (f32 SPR:$Sd), (node (f32 SPR:$Sm)))]>,
    921                    Requires<[HasFPARMv8]> {
    922       let Inst{17-16} = rm;
    923     }
    924     def D : ADuInp<0b11101, 0b11, 0b1000, 0b01, 0,
    925                    (outs DPR:$Dd), (ins DPR:$Dm),
    926                    NoItinerary, !strconcat("vrint", opc, ".f64\t$Dd, $Dm"),
    927                    [(set (f64 DPR:$Dd), (node (f64 DPR:$Dm)))]>,
    928                    Requires<[HasFPARMv8, HasDPVFP]> {
    929       let Inst{17-16} = rm;
    930     }
    931   }
    932 
    933   def : InstAlias<!strconcat("vrint", opc, ".f32.f32\t$Sd, $Sm"),
    934                   (!cast<Instruction>(NAME#"S") SPR:$Sd, SPR:$Sm), 0>,
    935         Requires<[HasFPARMv8]>;
    936   def : InstAlias<!strconcat("vrint", opc, ".f64.f64\t$Dd, $Dm"),
    937                   (!cast<Instruction>(NAME#"D") DPR:$Dd, DPR:$Dm), 0>,
    938         Requires<[HasFPARMv8,HasDPVFP]>;
    939 }
    940 
    941 defm VRINTA : vrint_inst_anpm<"a", 0b00, frnd>;
    942 defm VRINTN : vrint_inst_anpm<"n", 0b01>;
    943 defm VRINTP : vrint_inst_anpm<"p", 0b10, fceil>;
    944 defm VRINTM : vrint_inst_anpm<"m", 0b11, ffloor>;
    945 
    946 def VSQRTD : ADuI<0b11101, 0b11, 0b0001, 0b11, 0,
    947                   (outs DPR:$Dd), (ins DPR:$Dm),
    948                   IIC_fpSQRT64, "vsqrt", ".f64\t$Dd, $Dm",
    949                   [(set DPR:$Dd, (fsqrt (f64 DPR:$Dm)))]>;
    950 
    951 def VSQRTS : ASuI<0b11101, 0b11, 0b0001, 0b11, 0,
    952                   (outs SPR:$Sd), (ins SPR:$Sm),
    953                   IIC_fpSQRT32, "vsqrt", ".f32\t$Sd, $Sm",
    954                   [(set SPR:$Sd, (fsqrt SPR:$Sm))]>;
    955 
    956 def VSQRTH : AHuI<0b11101, 0b11, 0b0001, 0b11, 0,
    957                   (outs SPR:$Sd), (ins SPR:$Sm),
    958                   IIC_fpSQRT16, "vsqrt", ".f16\t$Sd, $Sm",
    959                   []>;
    960 
    961 let hasSideEffects = 0 in {
    962 def VMOVD  : ADuI<0b11101, 0b11, 0b0000, 0b01, 0,
    963                   (outs DPR:$Dd), (ins DPR:$Dm),
    964                   IIC_fpUNA64, "vmov", ".f64\t$Dd, $Dm", []>;
    965 
    966 def VMOVS  : ASuI<0b11101, 0b11, 0b0000, 0b01, 0,
    967                   (outs SPR:$Sd), (ins SPR:$Sm),
    968                   IIC_fpUNA32, "vmov", ".f32\t$Sd, $Sm", []>;
    969 
    970 let PostEncoderMethod = "", DecoderNamespace = "VFPV8" in {
    971 def VMOVH  : ASuInp<0b11101, 0b11, 0b0000, 0b01, 0,
    972                   (outs SPR:$Sd), (ins SPR:$Sm),
    973                   IIC_fpUNA16, "vmovx.f16\t$Sd, $Sm", []>,
    974              Requires<[HasFullFP16]>;
    975 
    976 def VINSH  : ASuInp<0b11101, 0b11, 0b0000, 0b11, 0,
    977                   (outs SPR:$Sd), (ins SPR:$Sm),
    978                   IIC_fpUNA16, "vins.f16\t$Sd, $Sm", []>,
    979              Requires<[HasFullFP16]>;
    980 } // PostEncoderMethod
    981 } // hasSideEffects
    982 
    983 //===----------------------------------------------------------------------===//
    984 // FP <-> GPR Copies.  Int <-> FP Conversions.
    985 //
    986 
    987 def VMOVRS : AVConv2I<0b11100001, 0b1010,
    988                       (outs GPR:$Rt), (ins SPR:$Sn),
    989                       IIC_fpMOVSI, "vmov", "\t$Rt, $Sn",
    990                       [(set GPR:$Rt, (bitconvert SPR:$Sn))]> {
    991   // Instruction operands.
    992   bits<4> Rt;
    993   bits<5> Sn;
    994 
    995   // Encode instruction operands.
    996   let Inst{19-16} = Sn{4-1};
    997   let Inst{7}     = Sn{0};
    998   let Inst{15-12} = Rt;
    999 
   1000   let Inst{6-5}   = 0b00;
   1001   let Inst{3-0}   = 0b0000;
   1002 
   1003   // Some single precision VFP instructions may be executed on both NEON and VFP
   1004   // pipelines.
   1005   let D = VFPNeonDomain;
   1006 }
   1007 
   1008 // Bitcast i32 -> f32.  NEON prefers to use VMOVDRR.
   1009 def VMOVSR : AVConv4I<0b11100000, 0b1010,
   1010                       (outs SPR:$Sn), (ins GPR:$Rt),
   1011                       IIC_fpMOVIS, "vmov", "\t$Sn, $Rt",
   1012                       [(set SPR:$Sn, (bitconvert GPR:$Rt))]>,
   1013              Requires<[HasVFP2, UseVMOVSR]> {
   1014   // Instruction operands.
   1015   bits<5> Sn;
   1016   bits<4> Rt;
   1017 
   1018   // Encode instruction operands.
   1019   let Inst{19-16} = Sn{4-1};
   1020   let Inst{7}     = Sn{0};
   1021   let Inst{15-12} = Rt;
   1022 
   1023   let Inst{6-5}   = 0b00;
   1024   let Inst{3-0}   = 0b0000;
   1025 
   1026   // Some single precision VFP instructions may be executed on both NEON and VFP
   1027   // pipelines.
   1028   let D = VFPNeonDomain;
   1029 }
   1030 
   1031 let hasSideEffects = 0 in {
   1032 def VMOVRRD  : AVConv3I<0b11000101, 0b1011,
   1033                         (outs GPR:$Rt, GPR:$Rt2), (ins DPR:$Dm),
   1034                         IIC_fpMOVDI, "vmov", "\t$Rt, $Rt2, $Dm",
   1035                  [/* FIXME: Can't write pattern for multiple result instr*/]> {
   1036   // Instruction operands.
   1037   bits<5> Dm;
   1038   bits<4> Rt;
   1039   bits<4> Rt2;
   1040 
   1041   // Encode instruction operands.
   1042   let Inst{3-0}   = Dm{3-0};
   1043   let Inst{5}     = Dm{4};
   1044   let Inst{15-12} = Rt;
   1045   let Inst{19-16} = Rt2;
   1046 
   1047   let Inst{7-6} = 0b00;
   1048 
   1049   // Some single precision VFP instructions may be executed on both NEON and VFP
   1050   // pipelines.
   1051   let D = VFPNeonDomain;
   1052 
   1053   // This instruction is equivalent to
   1054   // $Rt = EXTRACT_SUBREG $Dm, ssub_0
   1055   // $Rt2 = EXTRACT_SUBREG $Dm, ssub_1
   1056   let isExtractSubreg = 1;
   1057 }
   1058 
   1059 def VMOVRRS  : AVConv3I<0b11000101, 0b1010,
   1060                       (outs GPR:$Rt, GPR:$Rt2), (ins SPR:$src1, SPR:$src2),
   1061                  IIC_fpMOVDI, "vmov", "\t$Rt, $Rt2, $src1, $src2",
   1062                  [/* For disassembly only; pattern left blank */]> {
   1063   bits<5> src1;
   1064   bits<4> Rt;
   1065   bits<4> Rt2;
   1066 
   1067   // Encode instruction operands.
   1068   let Inst{3-0}   = src1{4-1};
   1069   let Inst{5}     = src1{0};
   1070   let Inst{15-12} = Rt;
   1071   let Inst{19-16} = Rt2;
   1072 
   1073   let Inst{7-6} = 0b00;
   1074 
   1075   // Some single precision VFP instructions may be executed on both NEON and VFP
   1076   // pipelines.
   1077   let D = VFPNeonDomain;
   1078   let DecoderMethod = "DecodeVMOVRRS";
   1079 }
   1080 } // hasSideEffects
   1081 
   1082 // FMDHR: GPR -> SPR
   1083 // FMDLR: GPR -> SPR
   1084 
   1085 def VMOVDRR : AVConv5I<0b11000100, 0b1011,
   1086                       (outs DPR:$Dm), (ins GPR:$Rt, GPR:$Rt2),
   1087                       IIC_fpMOVID, "vmov", "\t$Dm, $Rt, $Rt2",
   1088                       [(set DPR:$Dm, (arm_fmdrr GPR:$Rt, GPR:$Rt2))]> {
   1089   // Instruction operands.
   1090   bits<5> Dm;
   1091   bits<4> Rt;
   1092   bits<4> Rt2;
   1093 
   1094   // Encode instruction operands.
   1095   let Inst{3-0}   = Dm{3-0};
   1096   let Inst{5}     = Dm{4};
   1097   let Inst{15-12} = Rt;
   1098   let Inst{19-16} = Rt2;
   1099 
   1100   let Inst{7-6}   = 0b00;
   1101 
   1102   // Some single precision VFP instructions may be executed on both NEON and VFP
   1103   // pipelines.
   1104   let D = VFPNeonDomain;
   1105 
   1106   // This instruction is equivalent to
   1107   // $Dm = REG_SEQUENCE $Rt, ssub_0, $Rt2, ssub_1
   1108   let isRegSequence = 1;
   1109 }
   1110 
   1111 // Hoist an fabs or a fneg of a value coming from integer registers
   1112 // and do the fabs/fneg on the integer value. This is never a lose
   1113 // and could enable the conversion to float to be removed completely.
   1114 def : Pat<(fabs (arm_fmdrr GPR:$Rl, GPR:$Rh)),
   1115           (VMOVDRR GPR:$Rl, (BFC GPR:$Rh, (i32 0x7FFFFFFF)))>,
   1116       Requires<[IsARM, HasV6T2]>;
   1117 def : Pat<(fabs (arm_fmdrr GPR:$Rl, GPR:$Rh)),
   1118           (VMOVDRR GPR:$Rl, (t2BFC GPR:$Rh, (i32 0x7FFFFFFF)))>,
   1119       Requires<[IsThumb2, HasV6T2]>;
   1120 def : Pat<(fneg (arm_fmdrr GPR:$Rl, GPR:$Rh)),
   1121           (VMOVDRR GPR:$Rl, (EORri GPR:$Rh, (i32 0x80000000)))>,
   1122       Requires<[IsARM]>;
   1123 def : Pat<(fneg (arm_fmdrr GPR:$Rl, GPR:$Rh)),
   1124           (VMOVDRR GPR:$Rl, (t2EORri GPR:$Rh, (i32 0x80000000)))>,
   1125       Requires<[IsThumb2]>;
   1126 
   1127 let hasSideEffects = 0 in
   1128 def VMOVSRR : AVConv5I<0b11000100, 0b1010,
   1129                      (outs SPR:$dst1, SPR:$dst2), (ins GPR:$src1, GPR:$src2),
   1130                 IIC_fpMOVID, "vmov", "\t$dst1, $dst2, $src1, $src2",
   1131                 [/* For disassembly only; pattern left blank */]> {
   1132   // Instruction operands.
   1133   bits<5> dst1;
   1134   bits<4> src1;
   1135   bits<4> src2;
   1136 
   1137   // Encode instruction operands.
   1138   let Inst{3-0}   = dst1{4-1};
   1139   let Inst{5}     = dst1{0};
   1140   let Inst{15-12} = src1;
   1141   let Inst{19-16} = src2;
   1142 
   1143   let Inst{7-6} = 0b00;
   1144 
   1145   // Some single precision VFP instructions may be executed on both NEON and VFP
   1146   // pipelines.
   1147   let D = VFPNeonDomain;
   1148 
   1149   let DecoderMethod = "DecodeVMOVSRR";
   1150 }
   1151 
   1152 // Move H->R, clearing top 16 bits
   1153 def VMOVRH : AVConv2I<0b11100001, 0b1001,
   1154                       (outs GPR:$Rt), (ins SPR:$Sn),
   1155                       IIC_fpMOVSI, "vmov", ".f16\t$Rt, $Sn",
   1156                       []>,
   1157              Requires<[HasFullFP16]> {
   1158   // Instruction operands.
   1159   bits<4> Rt;
   1160   bits<5> Sn;
   1161 
   1162   // Encode instruction operands.
   1163   let Inst{19-16} = Sn{4-1};
   1164   let Inst{7}     = Sn{0};
   1165   let Inst{15-12} = Rt;
   1166 
   1167   let Inst{6-5}   = 0b00;
   1168   let Inst{3-0}   = 0b0000;
   1169 }
   1170 
   1171 // Move R->H, clearing top 16 bits
   1172 def VMOVHR : AVConv4I<0b11100000, 0b1001,
   1173                       (outs SPR:$Sn), (ins GPR:$Rt),
   1174                       IIC_fpMOVIS, "vmov", ".f16\t$Sn, $Rt",
   1175                       []>,
   1176              Requires<[HasFullFP16]> {
   1177   // Instruction operands.
   1178   bits<5> Sn;
   1179   bits<4> Rt;
   1180 
   1181   // Encode instruction operands.
   1182   let Inst{19-16} = Sn{4-1};
   1183   let Inst{7}     = Sn{0};
   1184   let Inst{15-12} = Rt;
   1185 
   1186   let Inst{6-5}   = 0b00;
   1187   let Inst{3-0}   = 0b0000;
   1188 }
   1189 
   1190 // FMRDH: SPR -> GPR
   1191 // FMRDL: SPR -> GPR
   1192 // FMRRS: SPR -> GPR
   1193 // FMRX:  SPR system reg -> GPR
   1194 // FMSRR: GPR -> SPR
   1195 // FMXR:  GPR -> VFP system reg
   1196 
   1197 
   1198 // Int -> FP:
   1199 
   1200 class AVConv1IDs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
   1201                         bits<4> opcod4, dag oops, dag iops,
   1202                         InstrItinClass itin, string opc, string asm,
   1203                         list<dag> pattern>
   1204   : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
   1205              pattern> {
   1206   // Instruction operands.
   1207   bits<5> Dd;
   1208   bits<5> Sm;
   1209 
   1210   // Encode instruction operands.
   1211   let Inst{3-0}   = Sm{4-1};
   1212   let Inst{5}     = Sm{0};
   1213   let Inst{15-12} = Dd{3-0};
   1214   let Inst{22}    = Dd{4};
   1215 
   1216   let Predicates = [HasVFP2, HasDPVFP];
   1217 }
   1218 
   1219 class AVConv1InSs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
   1220                          bits<4> opcod4, dag oops, dag iops,InstrItinClass itin,
   1221                          string opc, string asm, list<dag> pattern>
   1222   : AVConv1In<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
   1223               pattern> {
   1224   // Instruction operands.
   1225   bits<5> Sd;
   1226   bits<5> Sm;
   1227 
   1228   // Encode instruction operands.
   1229   let Inst{3-0}   = Sm{4-1};
   1230   let Inst{5}     = Sm{0};
   1231   let Inst{15-12} = Sd{4-1};
   1232   let Inst{22}    = Sd{0};
   1233 }
   1234 
   1235 class AVConv1IHs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
   1236                         bits<4> opcod4, dag oops, dag iops,
   1237                         InstrItinClass itin, string opc, string asm,
   1238                         list<dag> pattern>
   1239   : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
   1240              pattern> {
   1241   // Instruction operands.
   1242   bits<5> Sd;
   1243   bits<5> Sm;
   1244 
   1245   // Encode instruction operands.
   1246   let Inst{3-0}   = Sm{4-1};
   1247   let Inst{5}     = Sm{0};
   1248   let Inst{15-12} = Sd{4-1};
   1249   let Inst{22}    = Sd{0};
   1250 
   1251   let Predicates = [HasFullFP16];
   1252 }
   1253 
   1254 def VSITOD : AVConv1IDs_Encode<0b11101, 0b11, 0b1000, 0b1011,
   1255                                (outs DPR:$Dd), (ins SPR:$Sm),
   1256                                IIC_fpCVTID, "vcvt", ".f64.s32\t$Dd, $Sm",
   1257                                []> {
   1258   let Inst{7} = 1; // s32
   1259 }
   1260 
   1261 let Predicates=[HasVFP2, HasDPVFP] in {
   1262   def : VFPPat<(f64 (sint_to_fp GPR:$a)),
   1263                (VSITOD (COPY_TO_REGCLASS GPR:$a, SPR))>;
   1264 
   1265   def : VFPPat<(f64 (sint_to_fp (i32 (alignedload32 addrmode5:$a)))),
   1266                (VSITOD (VLDRS addrmode5:$a))>;
   1267 }
   1268 
   1269 def VSITOS : AVConv1InSs_Encode<0b11101, 0b11, 0b1000, 0b1010,
   1270                                 (outs SPR:$Sd),(ins SPR:$Sm),
   1271                                 IIC_fpCVTIS, "vcvt", ".f32.s32\t$Sd, $Sm",
   1272                                 []> {
   1273   let Inst{7} = 1; // s32
   1274 
   1275   // Some single precision VFP instructions may be executed on both NEON and
   1276   // VFP pipelines on A8.
   1277   let D = VFPNeonA8Domain;
   1278 }
   1279 
   1280 def : VFPNoNEONPat<(f32 (sint_to_fp GPR:$a)),
   1281                    (VSITOS (COPY_TO_REGCLASS GPR:$a, SPR))>;
   1282 
   1283 def : VFPNoNEONPat<(f32 (sint_to_fp (i32 (alignedload32 addrmode5:$a)))),
   1284                    (VSITOS (VLDRS addrmode5:$a))>;
   1285 
   1286 def VSITOH : AVConv1IHs_Encode<0b11101, 0b11, 0b1000, 0b1001,
   1287                                (outs SPR:$Sd), (ins SPR:$Sm),
   1288                                IIC_fpCVTIH, "vcvt", ".f16.s32\t$Sd, $Sm",
   1289                                []> {
   1290   let Inst{7} = 1; // s32
   1291 }
   1292 
   1293 def VUITOD : AVConv1IDs_Encode<0b11101, 0b11, 0b1000, 0b1011,
   1294                                (outs DPR:$Dd), (ins SPR:$Sm),
   1295                                IIC_fpCVTID, "vcvt", ".f64.u32\t$Dd, $Sm",
   1296                                []> {
   1297   let Inst{7} = 0; // u32
   1298 }
   1299 
   1300 let Predicates=[HasVFP2, HasDPVFP] in {
   1301   def : VFPPat<(f64 (uint_to_fp GPR:$a)),
   1302                (VUITOD (COPY_TO_REGCLASS GPR:$a, SPR))>;
   1303 
   1304   def : VFPPat<(f64 (uint_to_fp (i32 (alignedload32 addrmode5:$a)))),
   1305                (VUITOD (VLDRS addrmode5:$a))>;
   1306 }
   1307 
   1308 def VUITOS : AVConv1InSs_Encode<0b11101, 0b11, 0b1000, 0b1010,
   1309                                 (outs SPR:$Sd), (ins SPR:$Sm),
   1310                                 IIC_fpCVTIS, "vcvt", ".f32.u32\t$Sd, $Sm",
   1311                                 []> {
   1312   let Inst{7} = 0; // u32
   1313 
   1314   // Some single precision VFP instructions may be executed on both NEON and
   1315   // VFP pipelines on A8.
   1316   let D = VFPNeonA8Domain;
   1317 }
   1318 
   1319 def : VFPNoNEONPat<(f32 (uint_to_fp GPR:$a)),
   1320                    (VUITOS (COPY_TO_REGCLASS GPR:$a, SPR))>;
   1321 
   1322 def : VFPNoNEONPat<(f32 (uint_to_fp (i32 (alignedload32 addrmode5:$a)))),
   1323                    (VUITOS (VLDRS addrmode5:$a))>;
   1324 
   1325 def VUITOH : AVConv1IHs_Encode<0b11101, 0b11, 0b1000, 0b1001,
   1326                                 (outs SPR:$Sd), (ins SPR:$Sm),
   1327                                 IIC_fpCVTIH, "vcvt", ".f16.u32\t$Sd, $Sm",
   1328                                 []> {
   1329   let Inst{7} = 0; // u32
   1330 }
   1331 
   1332 // FP -> Int:
   1333 
   1334 class AVConv1IsD_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
   1335                         bits<4> opcod4, dag oops, dag iops,
   1336                         InstrItinClass itin, string opc, string asm,
   1337                         list<dag> pattern>
   1338   : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
   1339              pattern> {
   1340   // Instruction operands.
   1341   bits<5> Sd;
   1342   bits<5> Dm;
   1343 
   1344   // Encode instruction operands.
   1345   let Inst{3-0}   = Dm{3-0};
   1346   let Inst{5}     = Dm{4};
   1347   let Inst{15-12} = Sd{4-1};
   1348   let Inst{22}    = Sd{0};
   1349 
   1350   let Predicates = [HasVFP2, HasDPVFP];
   1351 }
   1352 
   1353 class AVConv1InsS_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
   1354                          bits<4> opcod4, dag oops, dag iops,
   1355                          InstrItinClass itin, string opc, string asm,
   1356                          list<dag> pattern>
   1357   : AVConv1In<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
   1358               pattern> {
   1359   // Instruction operands.
   1360   bits<5> Sd;
   1361   bits<5> Sm;
   1362 
   1363   // Encode instruction operands.
   1364   let Inst{3-0}   = Sm{4-1};
   1365   let Inst{5}     = Sm{0};
   1366   let Inst{15-12} = Sd{4-1};
   1367   let Inst{22}    = Sd{0};
   1368 }
   1369 
   1370 class AVConv1IsH_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
   1371                          bits<4> opcod4, dag oops, dag iops,
   1372                          InstrItinClass itin, string opc, string asm,
   1373                          list<dag> pattern>
   1374   : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
   1375               pattern> {
   1376   // Instruction operands.
   1377   bits<5> Sd;
   1378   bits<5> Sm;
   1379 
   1380   // Encode instruction operands.
   1381   let Inst{3-0}   = Sm{4-1};
   1382   let Inst{5}     = Sm{0};
   1383   let Inst{15-12} = Sd{4-1};
   1384   let Inst{22}    = Sd{0};
   1385 
   1386   let Predicates = [HasFullFP16];
   1387 }
   1388 
   1389 // Always set Z bit in the instruction, i.e. "round towards zero" variants.
   1390 def VTOSIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011,
   1391                                 (outs SPR:$Sd), (ins DPR:$Dm),
   1392                                 IIC_fpCVTDI, "vcvt", ".s32.f64\t$Sd, $Dm",
   1393                                 []> {
   1394   let Inst{7} = 1; // Z bit
   1395 }
   1396 
   1397 let Predicates=[HasVFP2, HasDPVFP] in {
   1398   def : VFPPat<(i32 (fp_to_sint (f64 DPR:$a))),
   1399                (COPY_TO_REGCLASS (VTOSIZD DPR:$a), GPR)>;
   1400 
   1401   def : VFPPat<(alignedstore32 (i32 (fp_to_sint (f64 DPR:$a))), addrmode5:$ptr),
   1402                (VSTRS (VTOSIZD DPR:$a), addrmode5:$ptr)>;
   1403 }
   1404 
   1405 def VTOSIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010,
   1406                                  (outs SPR:$Sd), (ins SPR:$Sm),
   1407                                  IIC_fpCVTSI, "vcvt", ".s32.f32\t$Sd, $Sm",
   1408                                  []> {
   1409   let Inst{7} = 1; // Z bit
   1410 
   1411   // Some single precision VFP instructions may be executed on both NEON and
   1412   // VFP pipelines on A8.
   1413   let D = VFPNeonA8Domain;
   1414 }
   1415 
   1416 def : VFPNoNEONPat<(i32 (fp_to_sint SPR:$a)),
   1417                    (COPY_TO_REGCLASS (VTOSIZS SPR:$a), GPR)>;
   1418 
   1419 def : VFPNoNEONPat<(alignedstore32 (i32 (fp_to_sint (f32 SPR:$a))),
   1420                                    addrmode5:$ptr),
   1421                    (VSTRS (VTOSIZS SPR:$a), addrmode5:$ptr)>;
   1422 
   1423 def VTOSIZH : AVConv1IsH_Encode<0b11101, 0b11, 0b1101, 0b1001,
   1424                                  (outs SPR:$Sd), (ins SPR:$Sm),
   1425                                  IIC_fpCVTHI, "vcvt", ".s32.f16\t$Sd, $Sm",
   1426                                  []> {
   1427   let Inst{7} = 1; // Z bit
   1428 }
   1429 
   1430 def VTOUIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011,
   1431                                (outs SPR:$Sd), (ins DPR:$Dm),
   1432                                IIC_fpCVTDI, "vcvt", ".u32.f64\t$Sd, $Dm",
   1433                                []> {
   1434   let Inst{7} = 1; // Z bit
   1435 }
   1436 
   1437 let Predicates=[HasVFP2, HasDPVFP] in {
   1438   def : VFPPat<(i32 (fp_to_uint (f64 DPR:$a))),
   1439                (COPY_TO_REGCLASS (VTOUIZD DPR:$a), GPR)>;
   1440 
   1441   def : VFPPat<(alignedstore32 (i32 (fp_to_uint (f64 DPR:$a))), addrmode5:$ptr),
   1442                (VSTRS (VTOUIZD DPR:$a), addrmode5:$ptr)>;
   1443 }
   1444 
   1445 def VTOUIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010,
   1446                                  (outs SPR:$Sd), (ins SPR:$Sm),
   1447                                  IIC_fpCVTSI, "vcvt", ".u32.f32\t$Sd, $Sm",
   1448                                  []> {
   1449   let Inst{7} = 1; // Z bit
   1450 
   1451   // Some single precision VFP instructions may be executed on both NEON and
   1452   // VFP pipelines on A8.
   1453   let D = VFPNeonA8Domain;
   1454 }
   1455 
   1456 def : VFPNoNEONPat<(i32 (fp_to_uint SPR:$a)),
   1457                    (COPY_TO_REGCLASS (VTOUIZS SPR:$a), GPR)>;
   1458 
   1459 def : VFPNoNEONPat<(alignedstore32 (i32 (fp_to_uint (f32 SPR:$a))),
   1460                                    addrmode5:$ptr),
   1461                   (VSTRS (VTOUIZS SPR:$a), addrmode5:$ptr)>;
   1462 
   1463 def VTOUIZH : AVConv1IsH_Encode<0b11101, 0b11, 0b1100, 0b1001,
   1464                                  (outs SPR:$Sd), (ins SPR:$Sm),
   1465                                  IIC_fpCVTHI, "vcvt", ".u32.f16\t$Sd, $Sm",
   1466                                  []> {
   1467   let Inst{7} = 1; // Z bit
   1468 }
   1469 
   1470 // And the Z bit '0' variants, i.e. use the rounding mode specified by FPSCR.
   1471 let Uses = [FPSCR] in {
   1472 // FIXME: Verify encoding after integrated assembler is working.
   1473 def VTOSIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011,
   1474                                 (outs SPR:$Sd), (ins DPR:$Dm),
   1475                                 IIC_fpCVTDI, "vcvtr", ".s32.f64\t$Sd, $Dm",
   1476                                 [(set SPR:$Sd, (int_arm_vcvtr (f64 DPR:$Dm)))]>{
   1477   let Inst{7} = 0; // Z bit
   1478 }
   1479 
   1480 def VTOSIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010,
   1481                                  (outs SPR:$Sd), (ins SPR:$Sm),
   1482                                  IIC_fpCVTSI, "vcvtr", ".s32.f32\t$Sd, $Sm",
   1483                                  [(set SPR:$Sd, (int_arm_vcvtr SPR:$Sm))]> {
   1484   let Inst{7} = 0; // Z bit
   1485 }
   1486 
   1487 def VTOSIRH : AVConv1IsH_Encode<0b11101, 0b11, 0b1101, 0b1001,
   1488                                  (outs SPR:$Sd), (ins SPR:$Sm),
   1489                                  IIC_fpCVTHI, "vcvtr", ".s32.f16\t$Sd, $Sm",
   1490                                  []> {
   1491   let Inst{7} = 0; // Z bit
   1492 }
   1493 
   1494 def VTOUIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011,
   1495                                 (outs SPR:$Sd), (ins DPR:$Dm),
   1496                                 IIC_fpCVTDI, "vcvtr", ".u32.f64\t$Sd, $Dm",
   1497                                 [(set SPR:$Sd, (int_arm_vcvtru(f64 DPR:$Dm)))]>{
   1498   let Inst{7} = 0; // Z bit
   1499 }
   1500 
   1501 def VTOUIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010,
   1502                                  (outs SPR:$Sd), (ins SPR:$Sm),
   1503                                  IIC_fpCVTSI, "vcvtr", ".u32.f32\t$Sd, $Sm",
   1504                                  [(set SPR:$Sd, (int_arm_vcvtru SPR:$Sm))]> {
   1505   let Inst{7} = 0; // Z bit
   1506 }
   1507 
   1508 def VTOUIRH : AVConv1IsH_Encode<0b11101, 0b11, 0b1100, 0b1001,
   1509                                  (outs SPR:$Sd), (ins SPR:$Sm),
   1510                                  IIC_fpCVTHI, "vcvtr", ".u32.f16\t$Sd, $Sm",
   1511                                  []> {
   1512   let Inst{7} = 0; // Z bit
   1513 }
   1514 }
   1515 
   1516 // Convert between floating-point and fixed-point
   1517 // Data type for fixed-point naming convention:
   1518 //   S16 (U=0, sx=0) -> SH
   1519 //   U16 (U=1, sx=0) -> UH
   1520 //   S32 (U=0, sx=1) -> SL
   1521 //   U32 (U=1, sx=1) -> UL
   1522 
   1523 let Constraints = "$a = $dst" in {
   1524 
   1525 // FP to Fixed-Point:
   1526 
   1527 // Single Precision register
   1528 class AVConv1XInsS_Encode<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4,
   1529                           bit op5, dag oops, dag iops, InstrItinClass itin,
   1530                           string opc, string asm, list<dag> pattern>
   1531   : AVConv1XI<op1, op2, op3, op4, op5, oops, iops, itin, opc, asm, pattern>,
   1532   Sched<[WriteCvtFP]> {
   1533   bits<5> dst;
   1534   // if dp_operation then UInt(D:Vd) else UInt(Vd:D);
   1535   let Inst{22} = dst{0};
   1536   let Inst{15-12} = dst{4-1};
   1537 }
   1538 
   1539 // Double Precision register
   1540 class AVConv1XInsD_Encode<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4,
   1541                           bit op5, dag oops, dag iops, InstrItinClass itin,
   1542                           string opc, string asm, list<dag> pattern>
   1543   : AVConv1XI<op1, op2, op3, op4, op5, oops, iops, itin, opc, asm, pattern>,
   1544     Sched<[WriteCvtFP]> {
   1545   bits<5> dst;
   1546   // if dp_operation then UInt(D:Vd) else UInt(Vd:D);
   1547   let Inst{22} = dst{4};
   1548   let Inst{15-12} = dst{3-0};
   1549 
   1550   let Predicates = [HasVFP2, HasDPVFP];
   1551 }
   1552 
   1553 def VTOSHH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1001, 0,
   1554                        (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
   1555                  IIC_fpCVTHI, "vcvt", ".s16.f16\t$dst, $a, $fbits", []>,
   1556              Requires<[HasFullFP16]>;
   1557 
   1558 def VTOUHH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1001, 0,
   1559                        (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
   1560                  IIC_fpCVTHI, "vcvt", ".u16.f16\t$dst, $a, $fbits", []>,
   1561              Requires<[HasFullFP16]>;
   1562 
   1563 def VTOSLH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1001, 1,
   1564                        (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
   1565                  IIC_fpCVTHI, "vcvt", ".s32.f16\t$dst, $a, $fbits", []>,
   1566              Requires<[HasFullFP16]>;
   1567 
   1568 def VTOULH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1001, 1,
   1569                        (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
   1570                  IIC_fpCVTHI, "vcvt", ".u32.f16\t$dst, $a, $fbits", []>,
   1571              Requires<[HasFullFP16]>;
   1572 
   1573 def VTOSHS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1010, 0,
   1574                        (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
   1575                  IIC_fpCVTSI, "vcvt", ".s16.f32\t$dst, $a, $fbits", []> {
   1576   // Some single precision VFP instructions may be executed on both NEON and
   1577   // VFP pipelines on A8.
   1578   let D = VFPNeonA8Domain;
   1579 }
   1580 
   1581 def VTOUHS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1010, 0,
   1582                        (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
   1583                  IIC_fpCVTSI, "vcvt", ".u16.f32\t$dst, $a, $fbits", []> {
   1584   // Some single precision VFP instructions may be executed on both NEON and
   1585   // VFP pipelines on A8.
   1586   let D = VFPNeonA8Domain;
   1587 }
   1588 
   1589 def VTOSLS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1010, 1,
   1590                        (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
   1591                  IIC_fpCVTSI, "vcvt", ".s32.f32\t$dst, $a, $fbits", []> {
   1592   // Some single precision VFP instructions may be executed on both NEON and
   1593   // VFP pipelines on A8.
   1594   let D = VFPNeonA8Domain;
   1595 }
   1596 
   1597 def VTOULS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1010, 1,
   1598                        (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
   1599                  IIC_fpCVTSI, "vcvt", ".u32.f32\t$dst, $a, $fbits", []> {
   1600   // Some single precision VFP instructions may be executed on both NEON and
   1601   // VFP pipelines on A8.
   1602   let D = VFPNeonA8Domain;
   1603 }
   1604 
   1605 def VTOSHD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1110, 0b1011, 0,
   1606                        (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits),
   1607                  IIC_fpCVTDI, "vcvt", ".s16.f64\t$dst, $a, $fbits", []>;
   1608 
   1609 def VTOUHD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1111, 0b1011, 0,
   1610                        (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits),
   1611                  IIC_fpCVTDI, "vcvt", ".u16.f64\t$dst, $a, $fbits", []>;
   1612 
   1613 def VTOSLD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1110, 0b1011, 1,
   1614                        (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits),
   1615                  IIC_fpCVTDI, "vcvt", ".s32.f64\t$dst, $a, $fbits", []>;
   1616 
   1617 def VTOULD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1111, 0b1011, 1,
   1618                        (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits),
   1619                  IIC_fpCVTDI, "vcvt", ".u32.f64\t$dst, $a, $fbits", []>;
   1620 
   1621 // Fixed-Point to FP:
   1622 
   1623 def VSHTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1001, 0,
   1624                        (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
   1625                  IIC_fpCVTIH, "vcvt", ".f16.s16\t$dst, $a, $fbits", []>,
   1626              Requires<[HasFullFP16]>;
   1627 
   1628 def VUHTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1001, 0,
   1629                        (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
   1630                  IIC_fpCVTIH, "vcvt", ".f16.u16\t$dst, $a, $fbits", []>,
   1631              Requires<[HasFullFP16]>;
   1632 
   1633 def VSLTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1001, 1,
   1634                        (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
   1635                  IIC_fpCVTIH, "vcvt", ".f16.s32\t$dst, $a, $fbits", []>,
   1636              Requires<[HasFullFP16]>;
   1637 
   1638 def VULTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1001, 1,
   1639                        (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
   1640                  IIC_fpCVTIH, "vcvt", ".f16.u32\t$dst, $a, $fbits", []>,
   1641              Requires<[HasFullFP16]>;
   1642 
   1643 def VSHTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1010, 0,
   1644                        (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
   1645                  IIC_fpCVTIS, "vcvt", ".f32.s16\t$dst, $a, $fbits", []> {
   1646   // Some single precision VFP instructions may be executed on both NEON and
   1647   // VFP pipelines on A8.
   1648   let D = VFPNeonA8Domain;
   1649 }
   1650 
   1651 def VUHTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1010, 0,
   1652                        (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
   1653                  IIC_fpCVTIS, "vcvt", ".f32.u16\t$dst, $a, $fbits", []> {
   1654   // Some single precision VFP instructions may be executed on both NEON and
   1655   // VFP pipelines on A8.
   1656   let D = VFPNeonA8Domain;
   1657 }
   1658 
   1659 def VSLTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1010, 1,
   1660                        (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
   1661                  IIC_fpCVTIS, "vcvt", ".f32.s32\t$dst, $a, $fbits", []> {
   1662   // Some single precision VFP instructions may be executed on both NEON and
   1663   // VFP pipelines on A8.
   1664   let D = VFPNeonA8Domain;
   1665 }
   1666 
   1667 def VULTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1010, 1,
   1668                        (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
   1669                  IIC_fpCVTIS, "vcvt", ".f32.u32\t$dst, $a, $fbits", []> {
   1670   // Some single precision VFP instructions may be executed on both NEON and
   1671   // VFP pipelines on A8.
   1672   let D = VFPNeonA8Domain;
   1673 }
   1674 
   1675 def VSHTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1010, 0b1011, 0,
   1676                        (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits),
   1677                  IIC_fpCVTID, "vcvt", ".f64.s16\t$dst, $a, $fbits", []>;
   1678 
   1679 def VUHTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1011, 0b1011, 0,
   1680                        (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits),
   1681                  IIC_fpCVTID, "vcvt", ".f64.u16\t$dst, $a, $fbits", []>;
   1682 
   1683 def VSLTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1010, 0b1011, 1,
   1684                        (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits),
   1685                  IIC_fpCVTID, "vcvt", ".f64.s32\t$dst, $a, $fbits", []>;
   1686 
   1687 def VULTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1011, 0b1011, 1,
   1688                        (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits),
   1689                  IIC_fpCVTID, "vcvt", ".f64.u32\t$dst, $a, $fbits", []>;
   1690 
   1691 } // End of 'let Constraints = "$a = $dst" in'
   1692 
   1693 //===----------------------------------------------------------------------===//
   1694 // FP Multiply-Accumulate Operations.
   1695 //
   1696 
   1697 def VMLAD : ADbI<0b11100, 0b00, 0, 0,
   1698                  (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
   1699                  IIC_fpMAC64, "vmla", ".f64\t$Dd, $Dn, $Dm",
   1700                  [(set DPR:$Dd, (fadd_mlx (fmul_su DPR:$Dn, DPR:$Dm),
   1701                                           (f64 DPR:$Ddin)))]>,
   1702               RegConstraint<"$Ddin = $Dd">,
   1703               Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>;
   1704 
   1705 def VMLAS : ASbIn<0b11100, 0b00, 0, 0,
   1706                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1707                   IIC_fpMAC32, "vmla", ".f32\t$Sd, $Sn, $Sm",
   1708                   [(set SPR:$Sd, (fadd_mlx (fmul_su SPR:$Sn, SPR:$Sm),
   1709                                            SPR:$Sdin))]>,
   1710               RegConstraint<"$Sdin = $Sd">,
   1711               Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]> {
   1712   // Some single precision VFP instructions may be executed on both NEON and
   1713   // VFP pipelines on A8.
   1714   let D = VFPNeonA8Domain;
   1715 }
   1716 
   1717 def VMLAH : AHbI<0b11100, 0b00, 0, 0,
   1718                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1719                   IIC_fpMAC16, "vmla", ".f16\t$Sd, $Sn, $Sm",
   1720                   []>,
   1721               RegConstraint<"$Sdin = $Sd">,
   1722               Requires<[HasFullFP16,UseFPVMLx,DontUseFusedMAC]>;
   1723 
   1724 def : Pat<(fadd_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))),
   1725           (VMLAD DPR:$dstin, DPR:$a, DPR:$b)>,
   1726           Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>;
   1727 def : Pat<(fadd_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)),
   1728           (VMLAS SPR:$dstin, SPR:$a, SPR:$b)>,
   1729           Requires<[HasVFP2,DontUseNEONForFP, UseFPVMLx,DontUseFusedMAC]>;
   1730 
   1731 def VMLSD : ADbI<0b11100, 0b00, 1, 0,
   1732                  (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
   1733                  IIC_fpMAC64, "vmls", ".f64\t$Dd, $Dn, $Dm",
   1734                  [(set DPR:$Dd, (fadd_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)),
   1735                                           (f64 DPR:$Ddin)))]>,
   1736               RegConstraint<"$Ddin = $Dd">,
   1737               Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>;
   1738 
   1739 def VMLSS : ASbIn<0b11100, 0b00, 1, 0,
   1740                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1741                   IIC_fpMAC32, "vmls", ".f32\t$Sd, $Sn, $Sm",
   1742                   [(set SPR:$Sd, (fadd_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)),
   1743                                            SPR:$Sdin))]>,
   1744               RegConstraint<"$Sdin = $Sd">,
   1745               Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]> {
   1746   // Some single precision VFP instructions may be executed on both NEON and
   1747   // VFP pipelines on A8.
   1748   let D = VFPNeonA8Domain;
   1749 }
   1750 
   1751 def VMLSH : AHbI<0b11100, 0b00, 1, 0,
   1752                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1753                   IIC_fpMAC16, "vmls", ".f16\t$Sd, $Sn, $Sm",
   1754                   []>,
   1755               RegConstraint<"$Sdin = $Sd">,
   1756               Requires<[HasFullFP16,UseFPVMLx,DontUseFusedMAC]>;
   1757 
   1758 def : Pat<(fsub_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))),
   1759           (VMLSD DPR:$dstin, DPR:$a, DPR:$b)>,
   1760           Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>;
   1761 def : Pat<(fsub_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)),
   1762           (VMLSS SPR:$dstin, SPR:$a, SPR:$b)>,
   1763           Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]>;
   1764 
   1765 def VNMLAD : ADbI<0b11100, 0b01, 1, 0,
   1766                   (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
   1767                   IIC_fpMAC64, "vnmla", ".f64\t$Dd, $Dn, $Dm",
   1768                   [(set DPR:$Dd,(fsub_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)),
   1769                                           (f64 DPR:$Ddin)))]>,
   1770                 RegConstraint<"$Ddin = $Dd">,
   1771                 Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>;
   1772 
   1773 def VNMLAS : ASbI<0b11100, 0b01, 1, 0,
   1774                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1775                   IIC_fpMAC32, "vnmla", ".f32\t$Sd, $Sn, $Sm",
   1776                   [(set SPR:$Sd, (fsub_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)),
   1777                                            SPR:$Sdin))]>,
   1778                 RegConstraint<"$Sdin = $Sd">,
   1779                 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]> {
   1780   // Some single precision VFP instructions may be executed on both NEON and
   1781   // VFP pipelines on A8.
   1782   let D = VFPNeonA8Domain;
   1783 }
   1784 
   1785 def VNMLAH : AHbI<0b11100, 0b01, 1, 0,
   1786                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1787                   IIC_fpMAC16, "vnmla", ".f16\t$Sd, $Sn, $Sm",
   1788                   []>,
   1789                 RegConstraint<"$Sdin = $Sd">,
   1790                 Requires<[HasFullFP16,UseFPVMLx,DontUseFusedMAC]>;
   1791 
   1792 def : Pat<(fsub_mlx (fneg (fmul_su DPR:$a, (f64 DPR:$b))), DPR:$dstin),
   1793           (VNMLAD DPR:$dstin, DPR:$a, DPR:$b)>,
   1794           Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>;
   1795 def : Pat<(fsub_mlx (fneg (fmul_su SPR:$a, SPR:$b)), SPR:$dstin),
   1796           (VNMLAS SPR:$dstin, SPR:$a, SPR:$b)>,
   1797           Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]>;
   1798 
   1799 def VNMLSD : ADbI<0b11100, 0b01, 0, 0,
   1800                   (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
   1801                   IIC_fpMAC64, "vnmls", ".f64\t$Dd, $Dn, $Dm",
   1802                   [(set DPR:$Dd, (fsub_mlx (fmul_su DPR:$Dn, DPR:$Dm),
   1803                                            (f64 DPR:$Ddin)))]>,
   1804                RegConstraint<"$Ddin = $Dd">,
   1805                Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>;
   1806 
   1807 def VNMLSS : ASbI<0b11100, 0b01, 0, 0,
   1808                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1809                   IIC_fpMAC32, "vnmls", ".f32\t$Sd, $Sn, $Sm",
   1810              [(set SPR:$Sd, (fsub_mlx (fmul_su SPR:$Sn, SPR:$Sm), SPR:$Sdin))]>,
   1811                          RegConstraint<"$Sdin = $Sd">,
   1812                 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]> {
   1813   // Some single precision VFP instructions may be executed on both NEON and
   1814   // VFP pipelines on A8.
   1815   let D = VFPNeonA8Domain;
   1816 }
   1817 
   1818 def VNMLSH : AHbI<0b11100, 0b01, 0, 0,
   1819                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1820                   IIC_fpMAC16, "vnmls", ".f16\t$Sd, $Sn, $Sm",
   1821              []>,
   1822                          RegConstraint<"$Sdin = $Sd">,
   1823                 Requires<[HasFullFP16,UseFPVMLx,DontUseFusedMAC]>;
   1824 
   1825 def : Pat<(fsub_mlx (fmul_su DPR:$a, (f64 DPR:$b)), DPR:$dstin),
   1826           (VNMLSD DPR:$dstin, DPR:$a, DPR:$b)>,
   1827           Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>;
   1828 def : Pat<(fsub_mlx (fmul_su SPR:$a, SPR:$b), SPR:$dstin),
   1829           (VNMLSS SPR:$dstin, SPR:$a, SPR:$b)>,
   1830           Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]>;
   1831 
   1832 //===----------------------------------------------------------------------===//
   1833 // Fused FP Multiply-Accumulate Operations.
   1834 //
   1835 def VFMAD : ADbI<0b11101, 0b10, 0, 0,
   1836                  (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
   1837                  IIC_fpFMAC64, "vfma", ".f64\t$Dd, $Dn, $Dm",
   1838                  [(set DPR:$Dd, (fadd_mlx (fmul_su DPR:$Dn, DPR:$Dm),
   1839                                           (f64 DPR:$Ddin)))]>,
   1840               RegConstraint<"$Ddin = $Dd">,
   1841               Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>;
   1842 
   1843 def VFMAS : ASbIn<0b11101, 0b10, 0, 0,
   1844                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1845                   IIC_fpFMAC32, "vfma", ".f32\t$Sd, $Sn, $Sm",
   1846                   [(set SPR:$Sd, (fadd_mlx (fmul_su SPR:$Sn, SPR:$Sm),
   1847                                            SPR:$Sdin))]>,
   1848               RegConstraint<"$Sdin = $Sd">,
   1849               Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]> {
   1850   // Some single precision VFP instructions may be executed on both NEON and
   1851   // VFP pipelines.
   1852 }
   1853 
   1854 def VFMAH : AHbI<0b11101, 0b10, 0, 0,
   1855                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1856                   IIC_fpFMAC16, "vfma", ".f16\t$Sd, $Sn, $Sm",
   1857                   []>,
   1858               RegConstraint<"$Sdin = $Sd">,
   1859               Requires<[HasFullFP16,UseFusedMAC]>;
   1860 
   1861 def : Pat<(fadd_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))),
   1862           (VFMAD DPR:$dstin, DPR:$a, DPR:$b)>,
   1863           Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>;
   1864 def : Pat<(fadd_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)),
   1865           (VFMAS SPR:$dstin, SPR:$a, SPR:$b)>,
   1866           Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>;
   1867 
   1868 // Match @llvm.fma.* intrinsics
   1869 // (fma x, y, z) -> (vfms z, x, y)
   1870 def : Pat<(f64 (fma DPR:$Dn, DPR:$Dm, DPR:$Ddin)),
   1871           (VFMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>,
   1872       Requires<[HasVFP4,HasDPVFP]>;
   1873 def : Pat<(f32 (fma SPR:$Sn, SPR:$Sm, SPR:$Sdin)),
   1874           (VFMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>,
   1875       Requires<[HasVFP4]>;
   1876 
   1877 def VFMSD : ADbI<0b11101, 0b10, 1, 0,
   1878                  (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
   1879                  IIC_fpFMAC64, "vfms", ".f64\t$Dd, $Dn, $Dm",
   1880                  [(set DPR:$Dd, (fadd_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)),
   1881                                           (f64 DPR:$Ddin)))]>,
   1882               RegConstraint<"$Ddin = $Dd">,
   1883               Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>;
   1884 
   1885 def VFMSS : ASbIn<0b11101, 0b10, 1, 0,
   1886                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1887                   IIC_fpFMAC32, "vfms", ".f32\t$Sd, $Sn, $Sm",
   1888                   [(set SPR:$Sd, (fadd_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)),
   1889                                            SPR:$Sdin))]>,
   1890               RegConstraint<"$Sdin = $Sd">,
   1891               Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]> {
   1892   // Some single precision VFP instructions may be executed on both NEON and
   1893   // VFP pipelines.
   1894 }
   1895 
   1896 def VFMSH : AHbI<0b11101, 0b10, 1, 0,
   1897                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1898                   IIC_fpFMAC16, "vfms", ".f16\t$Sd, $Sn, $Sm",
   1899                   []>,
   1900               RegConstraint<"$Sdin = $Sd">,
   1901               Requires<[HasFullFP16,UseFusedMAC]>;
   1902 
   1903 def : Pat<(fsub_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))),
   1904           (VFMSD DPR:$dstin, DPR:$a, DPR:$b)>,
   1905           Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>;
   1906 def : Pat<(fsub_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)),
   1907           (VFMSS SPR:$dstin, SPR:$a, SPR:$b)>,
   1908           Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>;
   1909 
   1910 // Match @llvm.fma.* intrinsics
   1911 // (fma (fneg x), y, z) -> (vfms z, x, y)
   1912 def : Pat<(f64 (fma (fneg DPR:$Dn), DPR:$Dm, DPR:$Ddin)),
   1913           (VFMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>,
   1914       Requires<[HasVFP4,HasDPVFP]>;
   1915 def : Pat<(f32 (fma (fneg SPR:$Sn), SPR:$Sm, SPR:$Sdin)),
   1916           (VFMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>,
   1917       Requires<[HasVFP4]>;
   1918 // (fma x, (fneg y), z) -> (vfms z, x, y)
   1919 def : Pat<(f64 (fma DPR:$Dn, (fneg DPR:$Dm), DPR:$Ddin)),
   1920           (VFMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>,
   1921       Requires<[HasVFP4,HasDPVFP]>;
   1922 def : Pat<(f32 (fma SPR:$Sn, (fneg SPR:$Sm), SPR:$Sdin)),
   1923           (VFMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>,
   1924       Requires<[HasVFP4]>;
   1925 
   1926 def VFNMAD : ADbI<0b11101, 0b01, 1, 0,
   1927                   (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
   1928                   IIC_fpFMAC64, "vfnma", ".f64\t$Dd, $Dn, $Dm",
   1929                   [(set DPR:$Dd,(fsub_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)),
   1930                                           (f64 DPR:$Ddin)))]>,
   1931                 RegConstraint<"$Ddin = $Dd">,
   1932                 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>;
   1933 
   1934 def VFNMAS : ASbI<0b11101, 0b01, 1, 0,
   1935                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1936                   IIC_fpFMAC32, "vfnma", ".f32\t$Sd, $Sn, $Sm",
   1937                   [(set SPR:$Sd, (fsub_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)),
   1938                                            SPR:$Sdin))]>,
   1939                 RegConstraint<"$Sdin = $Sd">,
   1940                 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]> {
   1941   // Some single precision VFP instructions may be executed on both NEON and
   1942   // VFP pipelines.
   1943 }
   1944 
   1945 def VFNMAH : AHbI<0b11101, 0b01, 1, 0,
   1946                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1947                   IIC_fpFMAC16, "vfnma", ".f16\t$Sd, $Sn, $Sm",
   1948                   []>,
   1949                 RegConstraint<"$Sdin = $Sd">,
   1950                 Requires<[HasFullFP16,UseFusedMAC]>;
   1951 
   1952 def : Pat<(fsub_mlx (fneg (fmul_su DPR:$a, (f64 DPR:$b))), DPR:$dstin),
   1953           (VFNMAD DPR:$dstin, DPR:$a, DPR:$b)>,
   1954           Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>;
   1955 def : Pat<(fsub_mlx (fneg (fmul_su SPR:$a, SPR:$b)), SPR:$dstin),
   1956           (VFNMAS SPR:$dstin, SPR:$a, SPR:$b)>,
   1957           Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>;
   1958 
   1959 // Match @llvm.fma.* intrinsics
   1960 // (fneg (fma x, y, z)) -> (vfnma z, x, y)
   1961 def : Pat<(fneg (fma (f64 DPR:$Dn), (f64 DPR:$Dm), (f64 DPR:$Ddin))),
   1962           (VFNMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>,
   1963       Requires<[HasVFP4,HasDPVFP]>;
   1964 def : Pat<(fneg (fma (f32 SPR:$Sn), (f32 SPR:$Sm), (f32 SPR:$Sdin))),
   1965           (VFNMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>,
   1966       Requires<[HasVFP4]>;
   1967 // (fma (fneg x), y, (fneg z)) -> (vfnma z, x, y)
   1968 def : Pat<(f64 (fma (fneg DPR:$Dn), DPR:$Dm, (fneg DPR:$Ddin))),
   1969           (VFNMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>,
   1970       Requires<[HasVFP4,HasDPVFP]>;
   1971 def : Pat<(f32 (fma (fneg SPR:$Sn), SPR:$Sm, (fneg SPR:$Sdin))),
   1972           (VFNMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>,
   1973       Requires<[HasVFP4]>;
   1974 
   1975 def VFNMSD : ADbI<0b11101, 0b01, 0, 0,
   1976                   (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
   1977                   IIC_fpFMAC64, "vfnms", ".f64\t$Dd, $Dn, $Dm",
   1978                   [(set DPR:$Dd, (fsub_mlx (fmul_su DPR:$Dn, DPR:$Dm),
   1979                                            (f64 DPR:$Ddin)))]>,
   1980                RegConstraint<"$Ddin = $Dd">,
   1981                Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>;
   1982 
   1983 def VFNMSS : ASbI<0b11101, 0b01, 0, 0,
   1984                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1985                   IIC_fpFMAC32, "vfnms", ".f32\t$Sd, $Sn, $Sm",
   1986              [(set SPR:$Sd, (fsub_mlx (fmul_su SPR:$Sn, SPR:$Sm), SPR:$Sdin))]>,
   1987                          RegConstraint<"$Sdin = $Sd">,
   1988                   Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]> {
   1989   // Some single precision VFP instructions may be executed on both NEON and
   1990   // VFP pipelines.
   1991 }
   1992 
   1993 def VFNMSH : AHbI<0b11101, 0b01, 0, 0,
   1994                   (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
   1995                   IIC_fpFMAC16, "vfnms", ".f16\t$Sd, $Sn, $Sm",
   1996              []>,
   1997                          RegConstraint<"$Sdin = $Sd">,
   1998                   Requires<[HasFullFP16,UseFusedMAC]>;
   1999 
   2000 def : Pat<(fsub_mlx (fmul_su DPR:$a, (f64 DPR:$b)), DPR:$dstin),
   2001           (VFNMSD DPR:$dstin, DPR:$a, DPR:$b)>,
   2002           Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>;
   2003 def : Pat<(fsub_mlx (fmul_su SPR:$a, SPR:$b), SPR:$dstin),
   2004           (VFNMSS SPR:$dstin, SPR:$a, SPR:$b)>,
   2005           Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>;
   2006 
   2007 // Match @llvm.fma.* intrinsics
   2008 
   2009 // (fma x, y, (fneg z)) -> (vfnms z, x, y))
   2010 def : Pat<(f64 (fma DPR:$Dn, DPR:$Dm, (fneg DPR:$Ddin))),
   2011           (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>,
   2012       Requires<[HasVFP4,HasDPVFP]>;
   2013 def : Pat<(f32 (fma SPR:$Sn, SPR:$Sm, (fneg SPR:$Sdin))),
   2014           (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>,
   2015       Requires<[HasVFP4]>;
   2016 // (fneg (fma (fneg x), y, z)) -> (vfnms z, x, y)
   2017 def : Pat<(fneg (f64 (fma (fneg DPR:$Dn), DPR:$Dm, DPR:$Ddin))),
   2018           (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>,
   2019       Requires<[HasVFP4,HasDPVFP]>;
   2020 def : Pat<(fneg (f32 (fma (fneg SPR:$Sn), SPR:$Sm, SPR:$Sdin))),
   2021           (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>,
   2022       Requires<[HasVFP4]>;
   2023 // (fneg (fma x, (fneg y), z) -> (vfnms z, x, y)
   2024 def : Pat<(fneg (f64 (fma DPR:$Dn, (fneg DPR:$Dm), DPR:$Ddin))),
   2025           (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>,
   2026       Requires<[HasVFP4,HasDPVFP]>;
   2027 def : Pat<(fneg (f32 (fma SPR:$Sn, (fneg SPR:$Sm), SPR:$Sdin))),
   2028           (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>,
   2029       Requires<[HasVFP4]>;
   2030 
   2031 //===----------------------------------------------------------------------===//
   2032 // FP Conditional moves.
   2033 //
   2034 
   2035 let hasSideEffects = 0 in {
   2036 def VMOVDcc  : PseudoInst<(outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm, cmovpred:$p),
   2037                     IIC_fpUNA64,
   2038                     [(set (f64 DPR:$Dd),
   2039                           (ARMcmov DPR:$Dn, DPR:$Dm, cmovpred:$p))]>,
   2040                RegConstraint<"$Dn = $Dd">, Requires<[HasVFP2,HasDPVFP]>;
   2041 
   2042 def VMOVScc  : PseudoInst<(outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm, cmovpred:$p),
   2043                     IIC_fpUNA32,
   2044                     [(set (f32 SPR:$Sd),
   2045                           (ARMcmov SPR:$Sn, SPR:$Sm, cmovpred:$p))]>,
   2046                RegConstraint<"$Sn = $Sd">, Requires<[HasVFP2]>;
   2047 } // hasSideEffects
   2048 
   2049 //===----------------------------------------------------------------------===//
   2050 // Move from VFP System Register to ARM core register.
   2051 //
   2052 
   2053 class MovFromVFP<bits<4> opc19_16, dag oops, dag iops, string opc, string asm,
   2054                  list<dag> pattern>:
   2055   VFPAI<oops, iops, VFPMiscFrm, IIC_fpSTAT, opc, asm, pattern> {
   2056 
   2057   // Instruction operand.
   2058   bits<4> Rt;
   2059 
   2060   let Inst{27-20} = 0b11101111;
   2061   let Inst{19-16} = opc19_16;
   2062   let Inst{15-12} = Rt;
   2063   let Inst{11-8}  = 0b1010;
   2064   let Inst{7}     = 0;
   2065   let Inst{6-5}   = 0b00;
   2066   let Inst{4}     = 1;
   2067   let Inst{3-0}   = 0b0000;
   2068 }
   2069 
   2070 // APSR is the application level alias of CPSR. This FPSCR N, Z, C, V flags
   2071 // to APSR.
   2072 let Defs = [CPSR], Uses = [FPSCR_NZCV], Rt = 0b1111 /* apsr_nzcv */ in
   2073 def FMSTAT : MovFromVFP<0b0001 /* fpscr */, (outs), (ins),
   2074                         "vmrs", "\tAPSR_nzcv, fpscr", [(arm_fmstat)]>;
   2075 
   2076 // Application level FPSCR -> GPR
   2077 let hasSideEffects = 1, Uses = [FPSCR] in
   2078 def VMRS : MovFromVFP<0b0001 /* fpscr */, (outs GPR:$Rt), (ins),
   2079                       "vmrs", "\t$Rt, fpscr",
   2080                       [(set GPR:$Rt, (int_arm_get_fpscr))]>;
   2081 
   2082 // System level FPEXC, FPSID -> GPR
   2083 let Uses = [FPSCR] in {
   2084   def VMRS_FPEXC : MovFromVFP<0b1000 /* fpexc */, (outs GPR:$Rt), (ins),
   2085                               "vmrs", "\t$Rt, fpexc", []>;
   2086   def VMRS_FPSID : MovFromVFP<0b0000 /* fpsid */, (outs GPR:$Rt), (ins),
   2087                               "vmrs", "\t$Rt, fpsid", []>;
   2088   def VMRS_MVFR0 : MovFromVFP<0b0111 /* mvfr0 */, (outs GPR:$Rt), (ins),
   2089                               "vmrs", "\t$Rt, mvfr0", []>;
   2090   def VMRS_MVFR1 : MovFromVFP<0b0110 /* mvfr1 */, (outs GPR:$Rt), (ins),
   2091                               "vmrs", "\t$Rt, mvfr1", []>;
   2092   def VMRS_MVFR2 : MovFromVFP<0b0101 /* mvfr2 */, (outs GPR:$Rt), (ins),
   2093                               "vmrs", "\t$Rt, mvfr2", []>, Requires<[HasFPARMv8]>;
   2094   def VMRS_FPINST : MovFromVFP<0b1001 /* fpinst */, (outs GPR:$Rt), (ins),
   2095                               "vmrs", "\t$Rt, fpinst", []>;
   2096   def VMRS_FPINST2 : MovFromVFP<0b1010 /* fpinst2 */, (outs GPR:$Rt), (ins),
   2097                                 "vmrs", "\t$Rt, fpinst2", []>;
   2098 }
   2099 
   2100 //===----------------------------------------------------------------------===//
   2101 // Move from ARM core register to VFP System Register.
   2102 //
   2103 
   2104 class MovToVFP<bits<4> opc19_16, dag oops, dag iops, string opc, string asm,
   2105                list<dag> pattern>:
   2106   VFPAI<oops, iops, VFPMiscFrm, IIC_fpSTAT, opc, asm, pattern> {
   2107 
   2108   // Instruction operand.
   2109   bits<4> src;
   2110 
   2111   // Encode instruction operand.
   2112   let Inst{15-12} = src;
   2113 
   2114   let Inst{27-20} = 0b11101110;
   2115   let Inst{19-16} = opc19_16;
   2116   let Inst{11-8}  = 0b1010;
   2117   let Inst{7}     = 0;
   2118   let Inst{4}     = 1;
   2119 }
   2120 
   2121 let Defs = [FPSCR] in {
   2122   // Application level GPR -> FPSCR
   2123   def VMSR : MovToVFP<0b0001 /* fpscr */, (outs), (ins GPR:$src),
   2124                       "vmsr", "\tfpscr, $src", [(int_arm_set_fpscr GPR:$src)]>;
   2125   // System level GPR -> FPEXC
   2126   def VMSR_FPEXC : MovToVFP<0b1000 /* fpexc */, (outs), (ins GPR:$src),
   2127                       "vmsr", "\tfpexc, $src", []>;
   2128   // System level GPR -> FPSID
   2129   def VMSR_FPSID : MovToVFP<0b0000 /* fpsid */, (outs), (ins GPR:$src),
   2130                       "vmsr", "\tfpsid, $src", []>;
   2131 
   2132   def VMSR_FPINST : MovToVFP<0b1001 /* fpinst */, (outs), (ins GPR:$src),
   2133                               "vmsr", "\tfpinst, $src", []>;
   2134   def VMSR_FPINST2 : MovToVFP<0b1010 /* fpinst2 */, (outs), (ins GPR:$src),
   2135                                 "vmsr", "\tfpinst2, $src", []>;
   2136 }
   2137 
   2138 //===----------------------------------------------------------------------===//
   2139 // Misc.
   2140 //
   2141 
   2142 // Materialize FP immediates. VFP3 only.
   2143 let isReMaterializable = 1 in {
   2144 def FCONSTD : VFPAI<(outs DPR:$Dd), (ins vfp_f64imm:$imm),
   2145                     VFPMiscFrm, IIC_fpUNA64,
   2146                     "vmov", ".f64\t$Dd, $imm",
   2147                     [(set DPR:$Dd, vfp_f64imm:$imm)]>,
   2148               Requires<[HasVFP3,HasDPVFP]> {
   2149   bits<5> Dd;
   2150   bits<8> imm;
   2151 
   2152   let Inst{27-23} = 0b11101;
   2153   let Inst{22}    = Dd{4};
   2154   let Inst{21-20} = 0b11;
   2155   let Inst{19-16} = imm{7-4};
   2156   let Inst{15-12} = Dd{3-0};
   2157   let Inst{11-9}  = 0b101;
   2158   let Inst{8}     = 1;          // Double precision.
   2159   let Inst{7-4}   = 0b0000;
   2160   let Inst{3-0}   = imm{3-0};
   2161 }
   2162 
   2163 def FCONSTS : VFPAI<(outs SPR:$Sd), (ins vfp_f32imm:$imm),
   2164                      VFPMiscFrm, IIC_fpUNA32,
   2165                      "vmov", ".f32\t$Sd, $imm",
   2166                      [(set SPR:$Sd, vfp_f32imm:$imm)]>, Requires<[HasVFP3]> {
   2167   bits<5> Sd;
   2168   bits<8> imm;
   2169 
   2170   let Inst{27-23} = 0b11101;
   2171   let Inst{22}    = Sd{0};
   2172   let Inst{21-20} = 0b11;
   2173   let Inst{19-16} = imm{7-4};
   2174   let Inst{15-12} = Sd{4-1};
   2175   let Inst{11-9}  = 0b101;
   2176   let Inst{8}     = 0;          // Single precision.
   2177   let Inst{7-4}   = 0b0000;
   2178   let Inst{3-0}   = imm{3-0};
   2179 }
   2180 
   2181 def FCONSTH : VFPAI<(outs SPR:$Sd), (ins vfp_f16imm:$imm),
   2182                      VFPMiscFrm, IIC_fpUNA16,
   2183                      "vmov", ".f16\t$Sd, $imm",
   2184                      []>, Requires<[HasFullFP16]> {
   2185   bits<5> Sd;
   2186   bits<8> imm;
   2187 
   2188   let Inst{27-23} = 0b11101;
   2189   let Inst{22}    = Sd{0};
   2190   let Inst{21-20} = 0b11;
   2191   let Inst{19-16} = imm{7-4};
   2192   let Inst{15-12} = Sd{4-1};
   2193   let Inst{11-8}  = 0b1001;     // Half precision
   2194   let Inst{7-4}   = 0b0000;
   2195   let Inst{3-0}   = imm{3-0};
   2196 }
   2197 }
   2198 
   2199 //===----------------------------------------------------------------------===//
   2200 // Assembler aliases.
   2201 //
   2202 // A few mnemonic aliases for pre-unifixed syntax. We don't guarantee to
   2203 // support them all, but supporting at least some of the basics is
   2204 // good to be friendly.
   2205 def : VFP2MnemonicAlias<"flds", "vldr">;
   2206 def : VFP2MnemonicAlias<"fldd", "vldr">;
   2207 def : VFP2MnemonicAlias<"fmrs", "vmov">;
   2208 def : VFP2MnemonicAlias<"fmsr", "vmov">;
   2209 def : VFP2MnemonicAlias<"fsqrts", "vsqrt">;
   2210 def : VFP2MnemonicAlias<"fsqrtd", "vsqrt">;
   2211 def : VFP2MnemonicAlias<"fadds", "vadd.f32">;
   2212 def : VFP2MnemonicAlias<"faddd", "vadd.f64">;
   2213 def : VFP2MnemonicAlias<"fmrdd", "vmov">;
   2214 def : VFP2MnemonicAlias<"fmrds", "vmov">;
   2215 def : VFP2MnemonicAlias<"fmrrd", "vmov">;
   2216 def : VFP2MnemonicAlias<"fmdrr", "vmov">;
   2217 def : VFP2MnemonicAlias<"fmuls", "vmul.f32">;
   2218 def : VFP2MnemonicAlias<"fmuld", "vmul.f64">;
   2219 def : VFP2MnemonicAlias<"fnegs", "vneg.f32">;
   2220 def : VFP2MnemonicAlias<"fnegd", "vneg.f64">;
   2221 def : VFP2MnemonicAlias<"ftosizd", "vcvt.s32.f64">;
   2222 def : VFP2MnemonicAlias<"ftosid", "vcvtr.s32.f64">;
   2223 def : VFP2MnemonicAlias<"ftosizs", "vcvt.s32.f32">;
   2224 def : VFP2MnemonicAlias<"ftosis", "vcvtr.s32.f32">;
   2225 def : VFP2MnemonicAlias<"ftouizd", "vcvt.u32.f64">;
   2226 def : VFP2MnemonicAlias<"ftouid", "vcvtr.u32.f64">;
   2227 def : VFP2MnemonicAlias<"ftouizs", "vcvt.u32.f32">;
   2228 def : VFP2MnemonicAlias<"ftouis", "vcvtr.u32.f32">;
   2229 def : VFP2MnemonicAlias<"fsitod", "vcvt.f64.s32">;
   2230 def : VFP2MnemonicAlias<"fsitos", "vcvt.f32.s32">;
   2231 def : VFP2MnemonicAlias<"fuitod", "vcvt.f64.u32">;
   2232 def : VFP2MnemonicAlias<"fuitos", "vcvt.f32.u32">;
   2233 def : VFP2MnemonicAlias<"fsts", "vstr">;
   2234 def : VFP2MnemonicAlias<"fstd", "vstr">;
   2235 def : VFP2MnemonicAlias<"fmacd", "vmla.f64">;
   2236 def : VFP2MnemonicAlias<"fmacs", "vmla.f32">;
   2237 def : VFP2MnemonicAlias<"fcpys", "vmov.f32">;
   2238 def : VFP2MnemonicAlias<"fcpyd", "vmov.f64">;
   2239 def : VFP2MnemonicAlias<"fcmps", "vcmp.f32">;
   2240 def : VFP2MnemonicAlias<"fcmpd", "vcmp.f64">;
   2241 def : VFP2MnemonicAlias<"fdivs", "vdiv.f32">;
   2242 def : VFP2MnemonicAlias<"fdivd", "vdiv.f64">;
   2243 def : VFP2MnemonicAlias<"fmrx", "vmrs">;
   2244 def : VFP2MnemonicAlias<"fmxr", "vmsr">;
   2245 
   2246 // Be friendly and accept the old form of zero-compare
   2247 def : VFP2DPInstAlias<"fcmpzd${p} $val", (VCMPZD DPR:$val, pred:$p)>;
   2248 def : VFP2InstAlias<"fcmpzs${p} $val", (VCMPZS SPR:$val, pred:$p)>;
   2249 
   2250 
   2251 def : VFP2InstAlias<"fmstat${p}", (FMSTAT pred:$p)>;
   2252 def : VFP2InstAlias<"fadds${p} $Sd, $Sn, $Sm",
   2253                     (VADDS SPR:$Sd, SPR:$Sn, SPR:$Sm, pred:$p)>;
   2254 def : VFP2DPInstAlias<"faddd${p} $Dd, $Dn, $Dm",
   2255                       (VADDD DPR:$Dd, DPR:$Dn, DPR:$Dm, pred:$p)>;
   2256 def : VFP2InstAlias<"fsubs${p} $Sd, $Sn, $Sm",
   2257                     (VSUBS SPR:$Sd, SPR:$Sn, SPR:$Sm, pred:$p)>;
   2258 def : VFP2DPInstAlias<"fsubd${p} $Dd, $Dn, $Dm",
   2259                       (VSUBD DPR:$Dd, DPR:$Dn, DPR:$Dm, pred:$p)>;
   2260 
   2261 // No need for the size suffix on VSQRT. It's implied by the register classes.
   2262 def : VFP2InstAlias<"vsqrt${p} $Sd, $Sm", (VSQRTS SPR:$Sd, SPR:$Sm, pred:$p)>;
   2263 def : VFP2DPInstAlias<"vsqrt${p} $Dd, $Dm", (VSQRTD DPR:$Dd, DPR:$Dm, pred:$p)>;
   2264 
   2265 // VLDR/VSTR accept an optional type suffix.
   2266 def : VFP2InstAlias<"vldr${p}.32 $Sd, $addr",
   2267                     (VLDRS SPR:$Sd, addrmode5:$addr, pred:$p)>;
   2268 def : VFP2InstAlias<"vstr${p}.32 $Sd, $addr",
   2269                     (VSTRS SPR:$Sd, addrmode5:$addr, pred:$p)>;
   2270 def : VFP2InstAlias<"vldr${p}.64 $Dd, $addr",
   2271                     (VLDRD DPR:$Dd, addrmode5:$addr, pred:$p)>;
   2272 def : VFP2InstAlias<"vstr${p}.64 $Dd, $addr",
   2273                     (VSTRD DPR:$Dd, addrmode5:$addr, pred:$p)>;
   2274 
   2275 // VMOV can accept optional 32-bit or less data type suffix suffix.
   2276 def : VFP2InstAlias<"vmov${p}.8 $Rt, $Sn",
   2277                     (VMOVRS GPR:$Rt, SPR:$Sn, pred:$p)>;
   2278 def : VFP2InstAlias<"vmov${p}.16 $Rt, $Sn",
   2279                     (VMOVRS GPR:$Rt, SPR:$Sn, pred:$p)>;
   2280 def : VFP2InstAlias<"vmov${p}.32 $Rt, $Sn",
   2281                     (VMOVRS GPR:$Rt, SPR:$Sn, pred:$p)>;
   2282 def : VFP2InstAlias<"vmov${p}.8 $Sn, $Rt",
   2283                     (VMOVSR SPR:$Sn, GPR:$Rt, pred:$p)>;
   2284 def : VFP2InstAlias<"vmov${p}.16 $Sn, $Rt",
   2285                     (VMOVSR SPR:$Sn, GPR:$Rt, pred:$p)>;
   2286 def : VFP2InstAlias<"vmov${p}.32 $Sn, $Rt",
   2287                     (VMOVSR SPR:$Sn, GPR:$Rt, pred:$p)>;
   2288 
   2289 def : VFP2InstAlias<"vmov${p}.f64 $Rt, $Rt2, $Dn",
   2290                     (VMOVRRD GPR:$Rt, GPR:$Rt2, DPR:$Dn, pred:$p)>;
   2291 def : VFP2InstAlias<"vmov${p}.f64 $Dn, $Rt, $Rt2",
   2292                     (VMOVDRR DPR:$Dn, GPR:$Rt, GPR:$Rt2, pred:$p)>;
   2293 
   2294 // VMOVS doesn't need the .f32 to disambiguate from the NEON encoding the way
   2295 // VMOVD does.
   2296 def : VFP2InstAlias<"vmov${p} $Sd, $Sm",
   2297                     (VMOVS SPR:$Sd, SPR:$Sm, pred:$p)>;
   2298 
   2299 // FCONSTD/FCONSTS alias for vmov.f64/vmov.f32
   2300 // These aliases provide added functionality over vmov.f instructions by
   2301 // allowing users to write assembly containing encoded floating point constants
   2302 // (e.g. #0x70 vs #1.0).  Without these alises there is no way for the
   2303 // assembler to accept encoded fp constants (but the equivalent fp-literal is
   2304 // accepted directly by vmovf).
   2305 def : VFP3InstAlias<"fconstd${p} $Dd, $val",
   2306                     (FCONSTD DPR:$Dd, vfp_f64imm:$val, pred:$p)>;
   2307 def : VFP3InstAlias<"fconsts${p} $Sd, $val",
   2308                     (FCONSTS SPR:$Sd, vfp_f32imm:$val, pred:$p)>;
   2309