xref: /freebsd/contrib/llvm-project/llvm/lib/Target/ARM/ARMInstrVFP.td (revision 3ceba58a7509418b47b8fca2d2b6bbf088714e26)
1//===-- ARMInstrVFP.td - VFP support for ARM ---------------*- tablegen -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file describes the ARM VFP instruction set.
10//
11//===----------------------------------------------------------------------===//
12
13def SDT_CMPFP0  : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
14def SDT_VMOVDRR : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>,
15                                       SDTCisSameAs<1, 2>]>;
16def SDT_VMOVRRD : SDTypeProfile<2, 1, [SDTCisVT<0, i32>, SDTCisSameAs<0, 1>,
17                                       SDTCisVT<2, f64>]>;
18
19def SDT_VMOVSR : SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisVT<1, i32>]>;
20
21def arm_fmstat : SDNode<"ARMISD::FMSTAT",  SDTNone, [SDNPInGlue, SDNPOutGlue]>;
22def arm_cmpfp  : SDNode<"ARMISD::CMPFP",   SDT_ARMCmp, [SDNPOutGlue]>;
23def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0", SDT_CMPFP0, [SDNPOutGlue]>;
24def arm_cmpfpe : SDNode<"ARMISD::CMPFPE",  SDT_ARMCmp, [SDNPOutGlue]>;
25def arm_cmpfpe0: SDNode<"ARMISD::CMPFPEw0",SDT_CMPFP0, [SDNPOutGlue]>;
26def arm_fmdrr  : SDNode<"ARMISD::VMOVDRR", SDT_VMOVDRR>;
27def arm_fmrrd  : SDNode<"ARMISD::VMOVRRD", SDT_VMOVRRD>;
28def arm_vmovsr  : SDNode<"ARMISD::VMOVSR", SDT_VMOVSR>;
29
30def SDT_VMOVhr : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, i32>] >;
31def SDT_VMOVrh : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisFP<1>] >;
32def arm_vmovhr : SDNode<"ARMISD::VMOVhr", SDT_VMOVhr>;
33def arm_vmovrh : SDNode<"ARMISD::VMOVrh", SDT_VMOVrh>;
34
35//===----------------------------------------------------------------------===//
36// Operand Definitions.
37//
38
39// 8-bit floating-point immediate encodings.
40def FPImmOperand : AsmOperandClass {
41  let Name = "FPImm";
42  let ParserMethod = "parseFPImm";
43}
44
45def vfp_f16imm : Operand<f16>,
46                 PatLeaf<(f16 fpimm), [{
47      return ARM_AM::getFP16Imm(N->getValueAPF()) != -1;
48    }], SDNodeXForm<fpimm, [{
49      APFloat InVal = N->getValueAPF();
50      uint32_t enc = ARM_AM::getFP16Imm(InVal);
51      return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
52    }]>> {
53  let PrintMethod = "printFPImmOperand";
54  let ParserMatchClass = FPImmOperand;
55}
56
57def vfp_f32f16imm_xform : SDNodeXForm<fpimm, [{
58      APFloat InVal = N->getValueAPF();
59      uint32_t enc = ARM_AM::getFP32FP16Imm(InVal);
60      return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
61    }]>;
62
63def vfp_f32f16imm : PatLeaf<(f32 fpimm), [{
64      return ARM_AM::getFP32FP16Imm(N->getValueAPF()) != -1;
65    }], vfp_f32f16imm_xform>;
66
67def vfp_f32imm_xform : SDNodeXForm<fpimm, [{
68      APFloat InVal = N->getValueAPF();
69      uint32_t enc = ARM_AM::getFP32Imm(InVal);
70      return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
71    }]>;
72
73def gi_vfp_f32imm : GICustomOperandRenderer<"renderVFPF32Imm">,
74                    GISDNodeXFormEquiv<vfp_f32imm_xform>;
75
76def vfp_f32imm : Operand<f32>,
77                 PatLeaf<(f32 fpimm), [{
78      return ARM_AM::getFP32Imm(N->getValueAPF()) != -1;
79    }], vfp_f32imm_xform> {
80  let PrintMethod = "printFPImmOperand";
81  let ParserMatchClass = FPImmOperand;
82  let GISelPredicateCode = [{
83      const auto &MO = MI.getOperand(1);
84      if (!MO.isFPImm())
85        return false;
86      return ARM_AM::getFP32Imm(MO.getFPImm()->getValueAPF()) != -1;
87    }];
88}
89
90def vfp_f64imm_xform : SDNodeXForm<fpimm, [{
91      APFloat InVal = N->getValueAPF();
92      uint32_t enc = ARM_AM::getFP64Imm(InVal);
93      return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
94    }]>;
95
96def gi_vfp_f64imm : GICustomOperandRenderer<"renderVFPF64Imm">,
97                    GISDNodeXFormEquiv<vfp_f64imm_xform>;
98
99def vfp_f64imm : Operand<f64>,
100                 PatLeaf<(f64 fpimm), [{
101      return ARM_AM::getFP64Imm(N->getValueAPF()) != -1;
102    }], vfp_f64imm_xform> {
103  let PrintMethod = "printFPImmOperand";
104  let ParserMatchClass = FPImmOperand;
105  let GISelPredicateCode = [{
106      const auto &MO = MI.getOperand(1);
107      if (!MO.isFPImm())
108        return false;
109      return ARM_AM::getFP64Imm(MO.getFPImm()->getValueAPF()) != -1;
110    }];
111}
112
113def alignedload16 : PatFrag<(ops node:$ptr), (load node:$ptr), [{
114  return cast<LoadSDNode>(N)->getAlign() >= 2;
115}]>;
116
117def alignedload32 : PatFrag<(ops node:$ptr), (load node:$ptr), [{
118  return cast<LoadSDNode>(N)->getAlign() >= 4;
119}]>;
120
121def alignedstore16 : PatFrag<(ops node:$val, node:$ptr),
122                             (store node:$val, node:$ptr), [{
123  return cast<StoreSDNode>(N)->getAlign() >= 2;
124}]>;
125
126def alignedstore32 : PatFrag<(ops node:$val, node:$ptr),
127                             (store node:$val, node:$ptr), [{
128  return cast<StoreSDNode>(N)->getAlign() >= 4;
129}]>;
130
131// The VCVT to/from fixed-point instructions encode the 'fbits' operand
132// (the number of fixed bits) differently than it appears in the assembly
133// source. It's encoded as "Size - fbits" where Size is the size of the
134// fixed-point representation (32 or 16) and fbits is the value appearing
135// in the assembly source, an integer in [0,16] or (0,32], depending on size.
136def fbits32_asm_operand : AsmOperandClass { let Name = "FBits32"; }
137def fbits32 : Operand<i32> {
138  let PrintMethod = "printFBits32";
139  let ParserMatchClass = fbits32_asm_operand;
140}
141
142def fbits16_asm_operand : AsmOperandClass { let Name = "FBits16"; }
143def fbits16 : Operand<i32> {
144  let PrintMethod = "printFBits16";
145  let ParserMatchClass = fbits16_asm_operand;
146}
147
148//===----------------------------------------------------------------------===//
149//  Load / store Instructions.
150//
151
152let canFoldAsLoad = 1, isReMaterializable = 1 in {
153
154def VLDRD : ADI5<0b1101, 0b01, (outs DPR:$Dd), (ins addrmode5:$addr),
155                 IIC_fpLoad64, "vldr", "\t$Dd, $addr",
156                 [(set DPR:$Dd, (f64 (alignedload32 addrmode5:$addr)))]>,
157            Requires<[HasFPRegs]>;
158
159def VLDRS : ASI5<0b1101, 0b01, (outs SPR:$Sd), (ins addrmode5:$addr),
160                 IIC_fpLoad32, "vldr", "\t$Sd, $addr",
161                 [(set SPR:$Sd, (alignedload32 addrmode5:$addr))]>,
162            Requires<[HasFPRegs]> {
163  // Some single precision VFP instructions may be executed on both NEON and VFP
164  // pipelines.
165  let D = VFPNeonDomain;
166}
167
168let isUnpredicable = 1 in
169def VLDRH : AHI5<0b1101, 0b01, (outs HPR:$Sd), (ins addrmode5fp16:$addr),
170                 IIC_fpLoad16, "vldr", ".16\t$Sd, $addr",
171                 [(set HPR:$Sd, (f16 (alignedload16 addrmode5fp16:$addr)))]>,
172            Requires<[HasFPRegs16]>;
173
174} // End of 'let canFoldAsLoad = 1, isReMaterializable = 1 in'
175
176def : Pat<(bf16 (alignedload16 addrmode5fp16:$addr)),
177          (VLDRH addrmode5fp16:$addr)> {
178  let Predicates = [HasFPRegs16];
179}
180def : Pat<(bf16 (alignedload16 addrmode3:$addr)),
181          (COPY_TO_REGCLASS (LDRH addrmode3:$addr), HPR)> {
182  let Predicates = [HasNoFPRegs16, IsARM];
183}
184def : Pat<(bf16 (alignedload16 t2addrmode_imm12:$addr)),
185          (COPY_TO_REGCLASS (t2LDRHi12 t2addrmode_imm12:$addr), HPR)> {
186  let Predicates = [HasNoFPRegs16, IsThumb];
187}
188
189def VSTRD : ADI5<0b1101, 0b00, (outs), (ins DPR:$Dd, addrmode5:$addr),
190                 IIC_fpStore64, "vstr", "\t$Dd, $addr",
191                 [(alignedstore32 (f64 DPR:$Dd), addrmode5:$addr)]>,
192            Requires<[HasFPRegs]>;
193
194def VSTRS : ASI5<0b1101, 0b00, (outs), (ins SPR:$Sd, addrmode5:$addr),
195                 IIC_fpStore32, "vstr", "\t$Sd, $addr",
196                 [(alignedstore32 SPR:$Sd, addrmode5:$addr)]>,
197            Requires<[HasFPRegs]> {
198  // Some single precision VFP instructions may be executed on both NEON and VFP
199  // pipelines.
200  let D = VFPNeonDomain;
201}
202
203let isUnpredicable = 1 in
204def VSTRH : AHI5<0b1101, 0b00, (outs), (ins HPR:$Sd, addrmode5fp16:$addr),
205                 IIC_fpStore16, "vstr", ".16\t$Sd, $addr",
206                 [(alignedstore16 (f16 HPR:$Sd), addrmode5fp16:$addr)]>,
207            Requires<[HasFPRegs16]>;
208
209def : Pat<(alignedstore16 (bf16 HPR:$Sd), addrmode5fp16:$addr),
210          (VSTRH (bf16 HPR:$Sd), addrmode5fp16:$addr)> {
211  let Predicates = [HasFPRegs16];
212}
213def : Pat<(alignedstore16 (bf16 HPR:$Sd), addrmode3:$addr),
214          (STRH (COPY_TO_REGCLASS $Sd, GPR), addrmode3:$addr)> {
215  let Predicates = [HasNoFPRegs16, IsARM];
216}
217def : Pat<(alignedstore16 (bf16 HPR:$Sd), t2addrmode_imm12:$addr),
218          (t2STRHi12 (COPY_TO_REGCLASS $Sd, GPR), t2addrmode_imm12:$addr)> {
219  let Predicates = [HasNoFPRegs16, IsThumb];
220}
221
222//===----------------------------------------------------------------------===//
223//  Load / store multiple Instructions.
224//
225
226multiclass vfp_ldst_mult<string asm, bit L_bit,
227                         InstrItinClass itin, InstrItinClass itin_upd> {
228  let Predicates = [HasFPRegs] in {
229  // Double Precision
230  def DIA :
231    AXDI4<(outs), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops),
232          IndexModeNone, itin,
233          !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
234    let Inst{24-23} = 0b01;       // Increment After
235    let Inst{21}    = 0;          // No writeback
236    let Inst{20}    = L_bit;
237  }
238  def DIA_UPD :
239    AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs,
240                               variable_ops),
241          IndexModeUpd, itin_upd,
242          !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
243    let Inst{24-23} = 0b01;       // Increment After
244    let Inst{21}    = 1;          // Writeback
245    let Inst{20}    = L_bit;
246  }
247  def DDB_UPD :
248    AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs,
249                               variable_ops),
250          IndexModeUpd, itin_upd,
251          !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
252    let Inst{24-23} = 0b10;       // Decrement Before
253    let Inst{21}    = 1;          // Writeback
254    let Inst{20}    = L_bit;
255  }
256
257  // Single Precision
258  def SIA :
259    AXSI4<(outs), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops),
260          IndexModeNone, itin,
261          !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
262    let Inst{24-23} = 0b01;       // Increment After
263    let Inst{21}    = 0;          // No writeback
264    let Inst{20}    = L_bit;
265
266    // Some single precision VFP instructions may be executed on both NEON and
267    // VFP pipelines.
268    let D = VFPNeonDomain;
269  }
270  def SIA_UPD :
271    AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs,
272                               variable_ops),
273          IndexModeUpd, itin_upd,
274          !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
275    let Inst{24-23} = 0b01;       // Increment After
276    let Inst{21}    = 1;          // Writeback
277    let Inst{20}    = L_bit;
278
279    // Some single precision VFP instructions may be executed on both NEON and
280    // VFP pipelines.
281    let D = VFPNeonDomain;
282  }
283  def SDB_UPD :
284    AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs,
285                               variable_ops),
286          IndexModeUpd, itin_upd,
287          !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
288    let Inst{24-23} = 0b10;       // Decrement Before
289    let Inst{21}    = 1;          // Writeback
290    let Inst{20}    = L_bit;
291
292    // Some single precision VFP instructions may be executed on both NEON and
293    // VFP pipelines.
294    let D = VFPNeonDomain;
295  }
296  }
297}
298
299let hasSideEffects = 0 in {
300
301let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
302defm VLDM : vfp_ldst_mult<"vldm", 1, IIC_fpLoad_m, IIC_fpLoad_mu>;
303
304let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
305defm VSTM : vfp_ldst_mult<"vstm", 0, IIC_fpStore_m, IIC_fpStore_mu>;
306
307} // hasSideEffects
308
309def : MnemonicAlias<"vldm", "vldmia">;
310def : MnemonicAlias<"vstm", "vstmia">;
311
312
313//===----------------------------------------------------------------------===//
314//  Lazy load / store multiple Instructions
315//
316// VLLDM and VLSTM:
317// 2 encoding options:
318// T1 (bit 7 is 0):
319// T1 takes an optional dpr_reglist, must be '{d0-d15}' (exactly)
320// T1 require v8-M.Main, secure state, target with 16 D registers (or with no D registers - NOP)
321// T2 (bit 7 is 1):
322// T2 takes a mandatory dpr_reglist, must be '{d0-d31}' (exactly)
323// T2 require v8.1-M.Main, secure state, target with 16/32 D registers (or with no D registers - NOP)
324// (source: Arm v8-M ARM, DDI0553B.v ID16122022)
325
326def VLLDM : AXSI4FR<"vlldm${p}\t$Rn, $regs", 0, 1>,
327            Requires<[HasV8MMainline, Has8MSecExt]> {
328    let Defs = [VPR, FPSCR, FPSCR_NZCV, D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15];
329    let DecoderMethod = "DecodeLazyLoadStoreMul";
330}
331// T1: assembly does not contains the register list.
332def : InstAlias<"vlldm${p}\t$Rn", (VLLDM GPRnopc:$Rn, pred:$p, 0)>,
333                Requires<[HasV8MMainline, Has8MSecExt]>;
334// T2: assembly must contains the register list.
335// The register list has no effect on the encoding, it is for assembly/disassembly purposes only.
336def VLLDM_T2 : AXSI4FR<"vlldm${p}\t$Rn, $regs", 1, 1>,
337            Requires<[HasV8_1MMainline, Has8MSecExt]> {
338    let Defs = [VPR, FPSCR, FPSCR_NZCV, D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,  D8,  D9,  D10, D11, D12, D13, D14, D15,
339                                        D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31];
340    let DecoderMethod = "DecodeLazyLoadStoreMul";
341}
342// T1: assembly contains the register list.
343// The register list has no effect on the encoding, it is for assembly/disassembly purposes only.
344def VLSTM : AXSI4FR<"vlstm${p}\t$Rn, $regs", 0, 0>,
345            Requires<[HasV8MMainline, Has8MSecExt]> {
346    let Defs = [VPR, FPSCR, FPSCR_NZCV];
347    let Uses = [VPR, FPSCR, FPSCR_NZCV, D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15];
348    let DecoderMethod = "DecodeLazyLoadStoreMul";
349}
350// T1: assembly does not contain the register list.
351def : InstAlias<"vlstm${p}\t$Rn", (VLSTM GPRnopc:$Rn, pred:$p, 0)>,
352                Requires<[HasV8MMainline, Has8MSecExt]>;
353// T2: assembly must contain the register list.
354// The register list has no effect on the encoding, it is for assembly/disassembly purposes only.
355def VLSTM_T2 : AXSI4FR<"vlstm${p}\t$Rn, $regs", 1, 0>,
356            Requires<[HasV8_1MMainline, Has8MSecExt]> {
357    let Defs = [VPR, FPSCR, FPSCR_NZCV];
358    let Uses = [VPR, FPSCR, FPSCR_NZCV, D0,  D1,  D2,  D3,  D4,  D5,  D6,  D7,  D8,  D9,  D10, D11, D12, D13, D14, D15,
359                                        D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30, D31];
360    let DecoderMethod = "DecodeLazyLoadStoreMul";
361}
362
363def : InstAlias<"vpush${p} $r", (VSTMDDB_UPD SP, pred:$p, dpr_reglist:$r), 0>,
364                Requires<[HasFPRegs]>;
365def : InstAlias<"vpush${p} $r", (VSTMSDB_UPD SP, pred:$p, spr_reglist:$r), 0>,
366                Requires<[HasFPRegs]>;
367def : InstAlias<"vpop${p} $r",  (VLDMDIA_UPD SP, pred:$p, dpr_reglist:$r), 0>,
368                Requires<[HasFPRegs]>;
369def : InstAlias<"vpop${p} $r",  (VLDMSIA_UPD SP, pred:$p, spr_reglist:$r), 0>,
370                Requires<[HasFPRegs]>;
371defm : VFPDTAnyInstAlias<"vpush${p}", "$r",
372                         (VSTMSDB_UPD SP, pred:$p, spr_reglist:$r)>;
373defm : VFPDTAnyInstAlias<"vpush${p}", "$r",
374                         (VSTMDDB_UPD SP, pred:$p, dpr_reglist:$r)>;
375defm : VFPDTAnyInstAlias<"vpop${p}", "$r",
376                         (VLDMSIA_UPD SP, pred:$p, spr_reglist:$r)>;
377defm : VFPDTAnyInstAlias<"vpop${p}", "$r",
378                         (VLDMDIA_UPD SP, pred:$p, dpr_reglist:$r)>;
379
380// FLDMX, FSTMX - Load and store multiple unknown precision registers for
381// pre-armv6 cores.
382// These instruction are deprecated so we don't want them to get selected.
383// However, there is no UAL syntax for them, so we keep them around for
384// (dis)assembly only.
385multiclass vfp_ldstx_mult<string asm, bit L_bit> {
386  let Predicates = [HasFPRegs], hasNoSchedulingInfo = 1 in {
387  // Unknown precision
388  def XIA :
389    AXXI4<(outs), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops),
390          IndexModeNone, !strconcat(asm, "iax${p}\t$Rn, $regs"), "", []> {
391    let Inst{24-23} = 0b01;       // Increment After
392    let Inst{21}    = 0;          // No writeback
393    let Inst{20}    = L_bit;
394  }
395  def XIA_UPD :
396    AXXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops),
397          IndexModeUpd, !strconcat(asm, "iax${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
398    let Inst{24-23} = 0b01;         // Increment After
399    let Inst{21}    = 1;            // Writeback
400    let Inst{20}    = L_bit;
401  }
402  def XDB_UPD :
403    AXXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops),
404          IndexModeUpd, !strconcat(asm, "dbx${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
405    let Inst{24-23} = 0b10;         // Decrement Before
406    let Inst{21}    = 1;            // Writeback
407    let Inst{20}    = L_bit;
408  }
409  }
410}
411
412defm FLDM : vfp_ldstx_mult<"fldm", 1>;
413defm FSTM : vfp_ldstx_mult<"fstm", 0>;
414
415def : VFP2MnemonicAlias<"fldmeax", "fldmdbx">;
416def : VFP2MnemonicAlias<"fldmfdx", "fldmiax">;
417
418def : VFP2MnemonicAlias<"fstmeax", "fstmiax">;
419def : VFP2MnemonicAlias<"fstmfdx", "fstmdbx">;
420
421//===----------------------------------------------------------------------===//
422// FP Binary Operations.
423//
424
425let TwoOperandAliasConstraint = "$Dn = $Dd" in
426def VADDD  : ADbI<0b11100, 0b11, 0, 0,
427                  (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
428                  IIC_fpALU64, "vadd", ".f64\t$Dd, $Dn, $Dm",
429                  [(set DPR:$Dd, (fadd DPR:$Dn, (f64 DPR:$Dm)))]>,
430             Sched<[WriteFPALU64]>;
431
432let TwoOperandAliasConstraint = "$Sn = $Sd" in
433def VADDS  : ASbIn<0b11100, 0b11, 0, 0,
434                   (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
435                   IIC_fpALU32, "vadd", ".f32\t$Sd, $Sn, $Sm",
436                   [(set SPR:$Sd, (fadd SPR:$Sn, SPR:$Sm))]>,
437             Sched<[WriteFPALU32]> {
438  // Some single precision VFP instructions may be executed on both NEON and
439  // VFP pipelines on A8.
440  let D = VFPNeonA8Domain;
441}
442
443let TwoOperandAliasConstraint = "$Sn = $Sd" in
444def VADDH  : AHbI<0b11100, 0b11, 0, 0,
445                  (outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm),
446                  IIC_fpALU16, "vadd", ".f16\t$Sd, $Sn, $Sm",
447                  [(set (f16 HPR:$Sd), (fadd (f16 HPR:$Sn), (f16 HPR:$Sm)))]>,
448             Sched<[WriteFPALU32]>;
449
450let TwoOperandAliasConstraint = "$Dn = $Dd" in
451def VSUBD  : ADbI<0b11100, 0b11, 1, 0,
452                  (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
453                  IIC_fpALU64, "vsub", ".f64\t$Dd, $Dn, $Dm",
454                  [(set DPR:$Dd, (fsub DPR:$Dn, (f64 DPR:$Dm)))]>,
455             Sched<[WriteFPALU64]>;
456
457let TwoOperandAliasConstraint = "$Sn = $Sd" in
458def VSUBS  : ASbIn<0b11100, 0b11, 1, 0,
459                   (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
460                   IIC_fpALU32, "vsub", ".f32\t$Sd, $Sn, $Sm",
461                   [(set SPR:$Sd, (fsub SPR:$Sn, SPR:$Sm))]>,
462             Sched<[WriteFPALU32]>{
463  // Some single precision VFP instructions may be executed on both NEON and
464  // VFP pipelines on A8.
465  let D = VFPNeonA8Domain;
466}
467
468let TwoOperandAliasConstraint = "$Sn = $Sd" in
469def VSUBH  : AHbI<0b11100, 0b11, 1, 0,
470                  (outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm),
471                  IIC_fpALU16, "vsub", ".f16\t$Sd, $Sn, $Sm",
472                  [(set (f16 HPR:$Sd), (fsub (f16 HPR:$Sn), (f16 HPR:$Sm)))]>,
473            Sched<[WriteFPALU32]>;
474
475let TwoOperandAliasConstraint = "$Dn = $Dd" in
476def VDIVD  : ADbI<0b11101, 0b00, 0, 0,
477                  (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
478                  IIC_fpDIV64, "vdiv", ".f64\t$Dd, $Dn, $Dm",
479                  [(set DPR:$Dd, (fdiv DPR:$Dn, (f64 DPR:$Dm)))]>,
480             Sched<[WriteFPDIV64]>;
481
482let TwoOperandAliasConstraint = "$Sn = $Sd" in
483def VDIVS  : ASbI<0b11101, 0b00, 0, 0,
484                  (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
485                  IIC_fpDIV32, "vdiv", ".f32\t$Sd, $Sn, $Sm",
486                  [(set SPR:$Sd, (fdiv SPR:$Sn, SPR:$Sm))]>,
487             Sched<[WriteFPDIV32]>;
488
489let TwoOperandAliasConstraint = "$Sn = $Sd" in
490def VDIVH  : AHbI<0b11101, 0b00, 0, 0,
491                  (outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm),
492                  IIC_fpDIV16, "vdiv", ".f16\t$Sd, $Sn, $Sm",
493                  [(set (f16 HPR:$Sd), (fdiv (f16 HPR:$Sn), (f16 HPR:$Sm)))]>,
494             Sched<[WriteFPDIV32]>;
495
496let TwoOperandAliasConstraint = "$Dn = $Dd" in
497def VMULD  : ADbI<0b11100, 0b10, 0, 0,
498                  (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
499                  IIC_fpMUL64, "vmul", ".f64\t$Dd, $Dn, $Dm",
500                  [(set DPR:$Dd, (fmul DPR:$Dn, (f64 DPR:$Dm)))]>,
501             Sched<[WriteFPMUL64, ReadFPMUL, ReadFPMUL]>;
502
503let TwoOperandAliasConstraint = "$Sn = $Sd" in
504def VMULS  : ASbIn<0b11100, 0b10, 0, 0,
505                   (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
506                   IIC_fpMUL32, "vmul", ".f32\t$Sd, $Sn, $Sm",
507                   [(set SPR:$Sd, (fmul SPR:$Sn, SPR:$Sm))]>,
508            Sched<[WriteFPMUL32, ReadFPMUL, ReadFPMUL]> {
509  // Some single precision VFP instructions may be executed on both NEON and
510  // VFP pipelines on A8.
511  let D = VFPNeonA8Domain;
512}
513
514let TwoOperandAliasConstraint = "$Sn = $Sd" in
515def VMULH  : AHbI<0b11100, 0b10, 0, 0,
516                  (outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm),
517                  IIC_fpMUL16, "vmul", ".f16\t$Sd, $Sn, $Sm",
518                  [(set (f16 HPR:$Sd), (fmul (f16 HPR:$Sn), (f16 HPR:$Sm)))]>,
519             Sched<[WriteFPMUL32, ReadFPMUL, ReadFPMUL]>;
520
521let TwoOperandAliasConstraint = "$Dn = $Dd" in
522def VNMULD : ADbI<0b11100, 0b10, 1, 0,
523                  (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
524                  IIC_fpMUL64, "vnmul", ".f64\t$Dd, $Dn, $Dm",
525                  [(set DPR:$Dd, (fneg (fmul DPR:$Dn, (f64 DPR:$Dm))))]>,
526             Sched<[WriteFPMUL64, ReadFPMUL, ReadFPMUL]>;
527
528let TwoOperandAliasConstraint = "$Sn = $Sd" in
529def VNMULS : ASbI<0b11100, 0b10, 1, 0,
530                  (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
531                  IIC_fpMUL32, "vnmul", ".f32\t$Sd, $Sn, $Sm",
532                  [(set SPR:$Sd, (fneg (fmul SPR:$Sn, SPR:$Sm)))]>,
533            Sched<[WriteFPMUL32, ReadFPMUL, ReadFPMUL]> {
534  // Some single precision VFP instructions may be executed on both NEON and
535  // VFP pipelines on A8.
536  let D = VFPNeonA8Domain;
537}
538
539let TwoOperandAliasConstraint = "$Sn = $Sd" in
540def VNMULH : AHbI<0b11100, 0b10, 1, 0,
541                  (outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm),
542                  IIC_fpMUL16, "vnmul", ".f16\t$Sd, $Sn, $Sm",
543                  [(set (f16 HPR:$Sd), (fneg (fmul (f16 HPR:$Sn), (f16 HPR:$Sm))))]>,
544             Sched<[WriteFPMUL32, ReadFPMUL, ReadFPMUL]>;
545
546multiclass vsel_inst<string op, bits<2> opc, int CC> {
547  let DecoderNamespace = "VFPV8", PostEncoderMethod = "",
548      Uses = [CPSR], AddedComplexity = 4, isUnpredicable = 1 in {
549    def H : AHbInp<0b11100, opc, 0,
550                   (outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm),
551                   NoItinerary, !strconcat("vsel", op, ".f16\t$Sd, $Sn, $Sm"),
552                   [(set (f16 HPR:$Sd), (ARMcmov (f16 HPR:$Sm), (f16 HPR:$Sn), CC))]>,
553                   Requires<[HasFullFP16]>;
554
555    def S : ASbInp<0b11100, opc, 0,
556                   (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
557                   NoItinerary, !strconcat("vsel", op, ".f32\t$Sd, $Sn, $Sm"),
558                   [(set SPR:$Sd, (ARMcmov SPR:$Sm, SPR:$Sn, CC))]>,
559                   Requires<[HasFPARMv8]>;
560
561    def D : ADbInp<0b11100, opc, 0,
562                   (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
563                   NoItinerary, !strconcat("vsel", op, ".f64\t$Dd, $Dn, $Dm"),
564                   [(set DPR:$Dd, (ARMcmov (f64 DPR:$Dm), (f64 DPR:$Dn), CC))]>,
565                   Requires<[HasFPARMv8, HasDPVFP]>;
566  }
567}
568
569// The CC constants here match ARMCC::CondCodes.
570defm VSELGT : vsel_inst<"gt", 0b11, 12>;
571defm VSELGE : vsel_inst<"ge", 0b10, 10>;
572defm VSELEQ : vsel_inst<"eq", 0b00, 0>;
573defm VSELVS : vsel_inst<"vs", 0b01, 6>;
574
575multiclass vmaxmin_inst<string op, bit opc, SDNode SD> {
576  let DecoderNamespace = "VFPV8", PostEncoderMethod = "",
577      isUnpredicable = 1 in {
578    def H : AHbInp<0b11101, 0b00, opc,
579                   (outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm),
580                   NoItinerary, !strconcat(op, ".f16\t$Sd, $Sn, $Sm"),
581                   [(set (f16 HPR:$Sd), (SD (f16 HPR:$Sn), (f16 HPR:$Sm)))]>,
582                   Requires<[HasFullFP16]>;
583
584    def S : ASbInp<0b11101, 0b00, opc,
585                   (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
586                   NoItinerary, !strconcat(op, ".f32\t$Sd, $Sn, $Sm"),
587                   [(set SPR:$Sd, (SD SPR:$Sn, SPR:$Sm))]>,
588                   Requires<[HasFPARMv8]>;
589
590    def D : ADbInp<0b11101, 0b00, opc,
591                   (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
592                   NoItinerary, !strconcat(op, ".f64\t$Dd, $Dn, $Dm"),
593                   [(set DPR:$Dd, (f64 (SD (f64 DPR:$Dn), (f64 DPR:$Dm))))]>,
594                   Requires<[HasFPARMv8, HasDPVFP]>;
595  }
596}
597
598defm VFP_VMAXNM : vmaxmin_inst<"vmaxnm", 0, fmaxnum>;
599defm VFP_VMINNM : vmaxmin_inst<"vminnm", 1, fminnum>;
600
601// Match reassociated forms only if not sign dependent rounding.
602def : Pat<(fmul (fneg DPR:$a), (f64 DPR:$b)),
603          (VNMULD DPR:$a, DPR:$b)>,
604          Requires<[NoHonorSignDependentRounding,HasDPVFP]>;
605def : Pat<(fmul (fneg SPR:$a), SPR:$b),
606          (VNMULS SPR:$a, SPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
607
608// These are encoded as unary instructions.
609let Defs = [FPSCR_NZCV] in {
610def VCMPED : ADuI<0b11101, 0b11, 0b0100, 0b11, 0,
611                  (outs), (ins DPR:$Dd, DPR:$Dm),
612                  IIC_fpCMP64, "vcmpe", ".f64\t$Dd, $Dm", "",
613                  [(arm_cmpfpe DPR:$Dd, (f64 DPR:$Dm))]>;
614
615def VCMPES : ASuI<0b11101, 0b11, 0b0100, 0b11, 0,
616                  (outs), (ins SPR:$Sd, SPR:$Sm),
617                  IIC_fpCMP32, "vcmpe", ".f32\t$Sd, $Sm", "",
618                  [(arm_cmpfpe SPR:$Sd, SPR:$Sm)]> {
619  // Some single precision VFP instructions may be executed on both NEON and
620  // VFP pipelines on A8.
621  let D = VFPNeonA8Domain;
622}
623
624def VCMPEH : AHuI<0b11101, 0b11, 0b0100, 0b11, 0,
625                  (outs), (ins HPR:$Sd, HPR:$Sm),
626                  IIC_fpCMP16, "vcmpe", ".f16\t$Sd, $Sm",
627                  [(arm_cmpfpe (f16 HPR:$Sd), (f16 HPR:$Sm))]>;
628
629def VCMPD  : ADuI<0b11101, 0b11, 0b0100, 0b01, 0,
630                  (outs), (ins DPR:$Dd, DPR:$Dm),
631                  IIC_fpCMP64, "vcmp", ".f64\t$Dd, $Dm", "",
632                  [(arm_cmpfp DPR:$Dd, (f64 DPR:$Dm))]>;
633
634def VCMPS  : ASuI<0b11101, 0b11, 0b0100, 0b01, 0,
635                  (outs), (ins SPR:$Sd, SPR:$Sm),
636                  IIC_fpCMP32, "vcmp", ".f32\t$Sd, $Sm", "",
637                  [(arm_cmpfp SPR:$Sd, SPR:$Sm)]> {
638  // Some single precision VFP instructions may be executed on both NEON and
639  // VFP pipelines on A8.
640  let D = VFPNeonA8Domain;
641}
642
643def VCMPH  : AHuI<0b11101, 0b11, 0b0100, 0b01, 0,
644                  (outs), (ins HPR:$Sd, HPR:$Sm),
645                  IIC_fpCMP16, "vcmp", ".f16\t$Sd, $Sm",
646                  [(arm_cmpfp (f16 HPR:$Sd), (f16 HPR:$Sm))]>;
647} // Defs = [FPSCR_NZCV]
648
649//===----------------------------------------------------------------------===//
650// FP Unary Operations.
651//
652
653def VABSD  : ADuI<0b11101, 0b11, 0b0000, 0b11, 0,
654                  (outs DPR:$Dd), (ins DPR:$Dm),
655                  IIC_fpUNA64, "vabs", ".f64\t$Dd, $Dm", "",
656                  [(set DPR:$Dd, (fabs (f64 DPR:$Dm)))]>;
657
658def VABSS  : ASuIn<0b11101, 0b11, 0b0000, 0b11, 0,
659                   (outs SPR:$Sd), (ins SPR:$Sm),
660                   IIC_fpUNA32, "vabs", ".f32\t$Sd, $Sm",
661                   [(set SPR:$Sd, (fabs SPR:$Sm))]> {
662  // Some single precision VFP instructions may be executed on both NEON and
663  // VFP pipelines on A8.
664  let D = VFPNeonA8Domain;
665}
666
667def VABSH  : AHuI<0b11101, 0b11, 0b0000, 0b11, 0,
668                   (outs HPR:$Sd), (ins HPR:$Sm),
669                   IIC_fpUNA16, "vabs", ".f16\t$Sd, $Sm",
670                   [(set (f16 HPR:$Sd), (fabs (f16 HPR:$Sm)))]>;
671
672let Defs = [FPSCR_NZCV] in {
673def VCMPEZD : ADuI<0b11101, 0b11, 0b0101, 0b11, 0,
674                   (outs), (ins DPR:$Dd),
675                   IIC_fpCMP64, "vcmpe", ".f64\t$Dd, #0", "",
676                   [(arm_cmpfpe0 (f64 DPR:$Dd))]> {
677  let Inst{3-0} = 0b0000;
678  let Inst{5}   = 0;
679}
680
681def VCMPEZS : ASuI<0b11101, 0b11, 0b0101, 0b11, 0,
682                   (outs), (ins SPR:$Sd),
683                   IIC_fpCMP32, "vcmpe", ".f32\t$Sd, #0", "",
684                   [(arm_cmpfpe0 SPR:$Sd)]> {
685  let Inst{3-0} = 0b0000;
686  let Inst{5}   = 0;
687
688  // Some single precision VFP instructions may be executed on both NEON and
689  // VFP pipelines on A8.
690  let D = VFPNeonA8Domain;
691}
692
693def VCMPEZH : AHuI<0b11101, 0b11, 0b0101, 0b11, 0,
694                   (outs), (ins HPR:$Sd),
695                   IIC_fpCMP16, "vcmpe", ".f16\t$Sd, #0",
696                   [(arm_cmpfpe0 (f16 HPR:$Sd))]> {
697  let Inst{3-0} = 0b0000;
698  let Inst{5}   = 0;
699}
700
701def VCMPZD  : ADuI<0b11101, 0b11, 0b0101, 0b01, 0,
702                   (outs), (ins DPR:$Dd),
703                   IIC_fpCMP64, "vcmp", ".f64\t$Dd, #0", "",
704                   [(arm_cmpfp0 (f64 DPR:$Dd))]> {
705  let Inst{3-0} = 0b0000;
706  let Inst{5}   = 0;
707}
708
709def VCMPZS  : ASuI<0b11101, 0b11, 0b0101, 0b01, 0,
710                   (outs), (ins SPR:$Sd),
711                   IIC_fpCMP32, "vcmp", ".f32\t$Sd, #0", "",
712                   [(arm_cmpfp0 SPR:$Sd)]> {
713  let Inst{3-0} = 0b0000;
714  let Inst{5}   = 0;
715
716  // Some single precision VFP instructions may be executed on both NEON and
717  // VFP pipelines on A8.
718  let D = VFPNeonA8Domain;
719}
720
721def VCMPZH  : AHuI<0b11101, 0b11, 0b0101, 0b01, 0,
722                   (outs), (ins HPR:$Sd),
723                   IIC_fpCMP16, "vcmp", ".f16\t$Sd, #0",
724                   [(arm_cmpfp0 (f16 HPR:$Sd))]> {
725  let Inst{3-0} = 0b0000;
726  let Inst{5}   = 0;
727}
728} // Defs = [FPSCR_NZCV]
729
730def VCVTDS  : ASuI<0b11101, 0b11, 0b0111, 0b11, 0,
731                   (outs DPR:$Dd), (ins SPR:$Sm),
732                   IIC_fpCVTDS, "vcvt", ".f64.f32\t$Dd, $Sm", "",
733                   [(set DPR:$Dd, (fpextend SPR:$Sm))]>,
734             Sched<[WriteFPCVT]> {
735  // Instruction operands.
736  bits<5> Dd;
737  bits<5> Sm;
738
739  // Encode instruction operands.
740  let Inst{3-0}   = Sm{4-1};
741  let Inst{5}     = Sm{0};
742  let Inst{15-12} = Dd{3-0};
743  let Inst{22}    = Dd{4};
744
745  let Predicates = [HasVFP2, HasDPVFP];
746  let hasSideEffects = 0;
747}
748
749// Special case encoding: bits 11-8 is 0b1011.
750def VCVTSD  : VFPAI<(outs SPR:$Sd), (ins DPR:$Dm), VFPUnaryFrm,
751                    IIC_fpCVTSD, "vcvt", ".f32.f64\t$Sd, $Dm", "",
752                    [(set SPR:$Sd, (fpround DPR:$Dm))]>,
753              Sched<[WriteFPCVT]> {
754  // Instruction operands.
755  bits<5> Sd;
756  bits<5> Dm;
757
758  // Encode instruction operands.
759  let Inst{3-0}   = Dm{3-0};
760  let Inst{5}     = Dm{4};
761  let Inst{15-12} = Sd{4-1};
762  let Inst{22}    = Sd{0};
763
764  let Inst{27-23} = 0b11101;
765  let Inst{21-16} = 0b110111;
766  let Inst{11-8}  = 0b1011;
767  let Inst{7-6}   = 0b11;
768  let Inst{4}     = 0;
769
770  let Predicates = [HasVFP2, HasDPVFP];
771  let hasSideEffects = 0;
772}
773
774// Between half, single and double-precision.
775let hasSideEffects = 0 in
776def VCVTBHS: ASuI<0b11101, 0b11, 0b0010, 0b01, 0, (outs SPR:$Sd), (ins SPR:$Sm),
777                 /* FIXME */ IIC_fpCVTSH, "vcvtb", ".f32.f16\t$Sd, $Sm", "",
778                 [/* Intentionally left blank, see patterns below */]>,
779                 Requires<[HasFP16]>,
780             Sched<[WriteFPCVT]>;
781
782def : FP16Pat<(f32 (fpextend (f16 HPR:$Sm))),
783              (VCVTBHS (COPY_TO_REGCLASS (f16 HPR:$Sm), SPR))>;
784def : FP16Pat<(f16_to_fp GPR:$a),
785              (VCVTBHS (COPY_TO_REGCLASS GPR:$a, SPR))>;
786
787let hasSideEffects = 0 in
788def VCVTBSH: ASuI<0b11101, 0b11, 0b0011, 0b01, 0, (outs SPR:$Sd), (ins SPR:$Sda, SPR:$Sm),
789                 /* FIXME */ IIC_fpCVTHS, "vcvtb", ".f16.f32\t$Sd, $Sm", "$Sd = $Sda",
790                 [/* Intentionally left blank, see patterns below */]>,
791                 Requires<[HasFP16]>,
792             Sched<[WriteFPCVT]>;
793
794def : FP16Pat<(f16 (fpround SPR:$Sm)),
795              (COPY_TO_REGCLASS (VCVTBSH (IMPLICIT_DEF), SPR:$Sm), HPR)>;
796def : FP16Pat<(fp_to_f16 SPR:$a),
797              (i32 (COPY_TO_REGCLASS (VCVTBSH (IMPLICIT_DEF), SPR:$a), GPR))>;
798def : FP16Pat<(insertelt (v8f16 MQPR:$src1), (f16 (fpround (f32 SPR:$src2))), imm_even:$lane),
799              (v8f16 (INSERT_SUBREG (v8f16 MQPR:$src1),
800                                    (VCVTBSH (EXTRACT_SUBREG (v8f16 MQPR:$src1), (SSubReg_f16_reg imm:$lane)),
801                                             SPR:$src2),
802                                    (SSubReg_f16_reg imm:$lane)))>;
803def : FP16Pat<(insertelt (v4f16 DPR:$src1), (f16 (fpround (f32 SPR:$src2))), imm_even:$lane),
804              (v4f16 (INSERT_SUBREG (v4f16 DPR:$src1),
805                                    (VCVTBSH (EXTRACT_SUBREG (v4f16 DPR:$src1), (SSubReg_f16_reg imm:$lane)),
806                                             SPR:$src2),
807                                    (SSubReg_f16_reg imm:$lane)))>;
808
809let hasSideEffects = 0 in
810def VCVTTHS: ASuI<0b11101, 0b11, 0b0010, 0b11, 0, (outs SPR:$Sd), (ins SPR:$Sm),
811                 /* FIXME */ IIC_fpCVTSH, "vcvtt", ".f32.f16\t$Sd, $Sm", "",
812                 [/* Intentionally left blank, see patterns below */]>,
813                 Requires<[HasFP16]>,
814             Sched<[WriteFPCVT]>;
815
816def : FP16Pat<(f32 (fpextend (extractelt (v8f16 MQPR:$src), imm_odd:$lane))),
817              (VCVTTHS (EXTRACT_SUBREG MQPR:$src, (SSubReg_f16_reg imm_odd:$lane)))>;
818def : FP16Pat<(f32 (fpextend (extractelt (v4f16 DPR:$src), imm_odd:$lane))),
819              (VCVTTHS (EXTRACT_SUBREG
820                (v2f32 (COPY_TO_REGCLASS (v4f16 DPR:$src), DPR_VFP2)),
821                (SSubReg_f16_reg imm_odd:$lane)))>;
822
823let hasSideEffects = 0 in
824def VCVTTSH: ASuI<0b11101, 0b11, 0b0011, 0b11, 0, (outs SPR:$Sd), (ins SPR:$Sda, SPR:$Sm),
825                 /* FIXME */ IIC_fpCVTHS, "vcvtt", ".f16.f32\t$Sd, $Sm", "$Sd = $Sda",
826                 [/* Intentionally left blank, see patterns below */]>,
827                 Requires<[HasFP16]>,
828            Sched<[WriteFPCVT]>;
829
830def : FP16Pat<(insertelt (v8f16 MQPR:$src1), (f16 (fpround (f32 SPR:$src2))), imm_odd:$lane),
831              (v8f16 (INSERT_SUBREG (v8f16 MQPR:$src1),
832                                    (VCVTTSH (EXTRACT_SUBREG (v8f16 MQPR:$src1), (SSubReg_f16_reg imm:$lane)),
833                                             SPR:$src2),
834                                    (SSubReg_f16_reg imm:$lane)))>;
835def : FP16Pat<(insertelt (v4f16 DPR:$src1), (f16 (fpround (f32 SPR:$src2))), imm_odd:$lane),
836              (v4f16 (INSERT_SUBREG (v4f16 DPR:$src1),
837                                    (VCVTTSH (EXTRACT_SUBREG (v4f16 DPR:$src1), (SSubReg_f16_reg imm:$lane)),
838                                             SPR:$src2),
839                                    (SSubReg_f16_reg imm:$lane)))>;
840
841def VCVTBHD : ADuI<0b11101, 0b11, 0b0010, 0b01, 0,
842                   (outs DPR:$Dd), (ins SPR:$Sm),
843                   NoItinerary, "vcvtb", ".f64.f16\t$Dd, $Sm", "",
844                   [/* Intentionally left blank, see patterns below */]>,
845                   Requires<[HasFPARMv8, HasDPVFP]>,
846              Sched<[WriteFPCVT]> {
847  // Instruction operands.
848  bits<5> Sm;
849
850  // Encode instruction operands.
851  let Inst{3-0} = Sm{4-1};
852  let Inst{5}   = Sm{0};
853
854  let hasSideEffects = 0;
855}
856
857def : FullFP16Pat<(f64 (fpextend (f16 HPR:$Sm))),
858                  (VCVTBHD (COPY_TO_REGCLASS (f16 HPR:$Sm), SPR))>,
859                  Requires<[HasFPARMv8, HasDPVFP]>;
860def : FP16Pat<(f64 (f16_to_fp GPR:$a)),
861              (VCVTBHD (COPY_TO_REGCLASS GPR:$a, SPR))>,
862              Requires<[HasFPARMv8, HasDPVFP]>;
863
864def VCVTBDH : ADuI<0b11101, 0b11, 0b0011, 0b01, 0,
865                   (outs SPR:$Sd), (ins SPR:$Sda, DPR:$Dm),
866                   NoItinerary, "vcvtb", ".f16.f64\t$Sd, $Dm", "$Sd = $Sda",
867                   [/* Intentionally left blank, see patterns below */]>,
868                   Requires<[HasFPARMv8, HasDPVFP]> {
869  // Instruction operands.
870  bits<5> Sd;
871  bits<5> Dm;
872
873  // Encode instruction operands.
874  let Inst{3-0}     = Dm{3-0};
875  let Inst{5}       = Dm{4};
876  let Inst{15-12}   = Sd{4-1};
877  let Inst{22}      = Sd{0};
878
879  let hasSideEffects = 0;
880}
881
882def : FullFP16Pat<(f16 (fpround DPR:$Dm)),
883                  (COPY_TO_REGCLASS (VCVTBDH (IMPLICIT_DEF), DPR:$Dm), HPR)>,
884                  Requires<[HasFPARMv8, HasDPVFP]>;
885def : FP16Pat<(fp_to_f16 (f64 DPR:$a)),
886              (i32 (COPY_TO_REGCLASS (VCVTBDH (IMPLICIT_DEF), DPR:$a), GPR))>,
887                   Requires<[HasFPARMv8, HasDPVFP]>;
888
889def VCVTTHD : ADuI<0b11101, 0b11, 0b0010, 0b11, 0,
890                   (outs DPR:$Dd), (ins SPR:$Sm),
891                   NoItinerary, "vcvtt", ".f64.f16\t$Dd, $Sm", "",
892                   []>, Requires<[HasFPARMv8, HasDPVFP]> {
893  // Instruction operands.
894  bits<5> Sm;
895
896  // Encode instruction operands.
897  let Inst{3-0} = Sm{4-1};
898  let Inst{5}   = Sm{0};
899
900  let hasSideEffects = 0;
901}
902
903def VCVTTDH : ADuI<0b11101, 0b11, 0b0011, 0b11, 0,
904                   (outs SPR:$Sd), (ins SPR:$Sda, DPR:$Dm),
905                   NoItinerary, "vcvtt", ".f16.f64\t$Sd, $Dm", "$Sd = $Sda",
906                   []>, Requires<[HasFPARMv8, HasDPVFP]> {
907  // Instruction operands.
908  bits<5> Sd;
909  bits<5> Dm;
910
911  // Encode instruction operands.
912  let Inst{15-12} = Sd{4-1};
913  let Inst{22}    = Sd{0};
914  let Inst{3-0}   = Dm{3-0};
915  let Inst{5}     = Dm{4};
916
917  let hasSideEffects = 0;
918}
919
920multiclass vcvt_inst<string opc, bits<2> rm,
921                     SDPatternOperator node = null_frag> {
922  let PostEncoderMethod = "", DecoderNamespace = "VFPV8", hasSideEffects = 0 in {
923    def SH : AHuInp<0b11101, 0b11, 0b1100, 0b11, 0,
924                    (outs SPR:$Sd), (ins HPR:$Sm),
925                    NoItinerary, !strconcat("vcvt", opc, ".s32.f16\t$Sd, $Sm"),
926                    []>,
927                    Requires<[HasFullFP16]> {
928      let Inst{17-16} = rm;
929    }
930
931    def UH : AHuInp<0b11101, 0b11, 0b1100, 0b01, 0,
932                    (outs SPR:$Sd), (ins HPR:$Sm),
933                    NoItinerary, !strconcat("vcvt", opc, ".u32.f16\t$Sd, $Sm"),
934                    []>,
935                    Requires<[HasFullFP16]> {
936      let Inst{17-16} = rm;
937    }
938
939    def SS : ASuInp<0b11101, 0b11, 0b1100, 0b11, 0,
940                    (outs SPR:$Sd), (ins SPR:$Sm),
941                    NoItinerary, !strconcat("vcvt", opc, ".s32.f32\t$Sd, $Sm"),
942                    []>,
943                    Requires<[HasFPARMv8]> {
944      let Inst{17-16} = rm;
945    }
946
947    def US : ASuInp<0b11101, 0b11, 0b1100, 0b01, 0,
948                    (outs SPR:$Sd), (ins SPR:$Sm),
949                    NoItinerary, !strconcat("vcvt", opc, ".u32.f32\t$Sd, $Sm"),
950                    []>,
951                    Requires<[HasFPARMv8]> {
952      let Inst{17-16} = rm;
953    }
954
955    def SD : ASuInp<0b11101, 0b11, 0b1100, 0b11, 0,
956                    (outs SPR:$Sd), (ins DPR:$Dm),
957                    NoItinerary, !strconcat("vcvt", opc, ".s32.f64\t$Sd, $Dm"),
958                    []>,
959                    Requires<[HasFPARMv8, HasDPVFP]> {
960      bits<5> Dm;
961
962      let Inst{17-16} = rm;
963
964      // Encode instruction operands.
965      let Inst{3-0} = Dm{3-0};
966      let Inst{5}   = Dm{4};
967      let Inst{8} = 1;
968    }
969
970    def UD : ASuInp<0b11101, 0b11, 0b1100, 0b01, 0,
971                    (outs SPR:$Sd), (ins DPR:$Dm),
972                    NoItinerary, !strconcat("vcvt", opc, ".u32.f64\t$Sd, $Dm"),
973                    []>,
974                    Requires<[HasFPARMv8, HasDPVFP]> {
975      bits<5> Dm;
976
977      let Inst{17-16} = rm;
978
979      // Encode instruction operands
980      let Inst{3-0}  = Dm{3-0};
981      let Inst{5}    = Dm{4};
982      let Inst{8} = 1;
983    }
984  }
985
986  let Predicates = [HasFPARMv8] in {
987    let Predicates = [HasFullFP16] in {
988    def : Pat<(i32 (fp_to_sint (node (f16 HPR:$a)))),
989              (COPY_TO_REGCLASS
990                (!cast<Instruction>(NAME#"SH") (f16 HPR:$a)),
991                GPR)>;
992
993    def : Pat<(i32 (fp_to_uint (node (f16 HPR:$a)))),
994              (COPY_TO_REGCLASS
995                (!cast<Instruction>(NAME#"UH") (f16 HPR:$a)),
996                GPR)>;
997    }
998    def : Pat<(i32 (fp_to_sint (node SPR:$a))),
999              (COPY_TO_REGCLASS
1000                (!cast<Instruction>(NAME#"SS") SPR:$a),
1001                GPR)>;
1002    def : Pat<(i32 (fp_to_uint (node SPR:$a))),
1003              (COPY_TO_REGCLASS
1004                (!cast<Instruction>(NAME#"US") SPR:$a),
1005                GPR)>;
1006  }
1007  let Predicates = [HasFPARMv8, HasDPVFP] in {
1008    def : Pat<(i32 (fp_to_sint (node (f64 DPR:$a)))),
1009              (COPY_TO_REGCLASS
1010                (!cast<Instruction>(NAME#"SD") DPR:$a),
1011                GPR)>;
1012    def : Pat<(i32 (fp_to_uint (node (f64 DPR:$a)))),
1013              (COPY_TO_REGCLASS
1014                (!cast<Instruction>(NAME#"UD") DPR:$a),
1015                GPR)>;
1016  }
1017}
1018
1019defm VCVTA : vcvt_inst<"a", 0b00, fround>;
1020defm VCVTN : vcvt_inst<"n", 0b01>;
1021defm VCVTP : vcvt_inst<"p", 0b10, fceil>;
1022defm VCVTM : vcvt_inst<"m", 0b11, ffloor>;
1023
1024def VNEGD  : ADuI<0b11101, 0b11, 0b0001, 0b01, 0,
1025                  (outs DPR:$Dd), (ins DPR:$Dm),
1026                  IIC_fpUNA64, "vneg", ".f64\t$Dd, $Dm", "",
1027                  [(set DPR:$Dd, (fneg (f64 DPR:$Dm)))]>;
1028
1029def VNEGS  : ASuIn<0b11101, 0b11, 0b0001, 0b01, 0,
1030                   (outs SPR:$Sd), (ins SPR:$Sm),
1031                   IIC_fpUNA32, "vneg", ".f32\t$Sd, $Sm",
1032                   [(set SPR:$Sd, (fneg SPR:$Sm))]> {
1033  // Some single precision VFP instructions may be executed on both NEON and
1034  // VFP pipelines on A8.
1035  let D = VFPNeonA8Domain;
1036}
1037
1038def VNEGH  : AHuI<0b11101, 0b11, 0b0001, 0b01, 0,
1039                  (outs HPR:$Sd), (ins HPR:$Sm),
1040                  IIC_fpUNA16, "vneg", ".f16\t$Sd, $Sm",
1041                  [(set (f16 HPR:$Sd), (fneg (f16 HPR:$Sm)))]>;
1042
1043multiclass vrint_inst_zrx<string opc, bit op, bit op2, SDPatternOperator node> {
1044  def H : AHuI<0b11101, 0b11, 0b0110, 0b11, 0,
1045               (outs HPR:$Sd), (ins HPR:$Sm),
1046               NoItinerary, !strconcat("vrint", opc), ".f16\t$Sd, $Sm",
1047               [(set (f16 HPR:$Sd), (node (f16 HPR:$Sm)))]>,
1048               Requires<[HasFullFP16]> {
1049    let Inst{7} = op2;
1050    let Inst{16} = op;
1051  }
1052
1053  def S : ASuI<0b11101, 0b11, 0b0110, 0b11, 0,
1054               (outs SPR:$Sd), (ins SPR:$Sm),
1055               NoItinerary, !strconcat("vrint", opc), ".f32\t$Sd, $Sm", "",
1056               [(set (f32 SPR:$Sd), (node (f32 SPR:$Sm)))]>,
1057               Requires<[HasFPARMv8]> {
1058    let Inst{7} = op2;
1059    let Inst{16} = op;
1060  }
1061  def D : ADuI<0b11101, 0b11, 0b0110, 0b11, 0,
1062                (outs DPR:$Dd), (ins DPR:$Dm),
1063                NoItinerary, !strconcat("vrint", opc), ".f64\t$Dd, $Dm", "",
1064                [(set (f64 DPR:$Dd), (node (f64 DPR:$Dm)))]>,
1065                Requires<[HasFPARMv8, HasDPVFP]> {
1066    let Inst{7} = op2;
1067    let Inst{16} = op;
1068  }
1069
1070  def : InstAlias<!strconcat("vrint", opc, "$p.f16.f16\t$Sd, $Sm"),
1071                  (!cast<Instruction>(NAME#"H") SPR:$Sd, SPR:$Sm, pred:$p), 0>,
1072        Requires<[HasFullFP16]>;
1073  def : InstAlias<!strconcat("vrint", opc, "$p.f32.f32\t$Sd, $Sm"),
1074                  (!cast<Instruction>(NAME#"S") SPR:$Sd, SPR:$Sm, pred:$p), 0>,
1075        Requires<[HasFPARMv8]>;
1076  def : InstAlias<!strconcat("vrint", opc, "$p.f64.f64\t$Dd, $Dm"),
1077                  (!cast<Instruction>(NAME#"D") DPR:$Dd, DPR:$Dm, pred:$p), 0>,
1078        Requires<[HasFPARMv8,HasDPVFP]>;
1079}
1080
1081defm VRINTZ : vrint_inst_zrx<"z", 0, 1, ftrunc>;
1082defm VRINTR : vrint_inst_zrx<"r", 0, 0, fnearbyint>;
1083defm VRINTX : vrint_inst_zrx<"x", 1, 0, frint>;
1084
1085multiclass vrint_inst_anpm<string opc, bits<2> rm,
1086                           SDPatternOperator node = null_frag> {
1087  let PostEncoderMethod = "", DecoderNamespace = "VFPV8",
1088      isUnpredicable = 1 in {
1089    def H : AHuInp<0b11101, 0b11, 0b1000, 0b01, 0,
1090                   (outs HPR:$Sd), (ins HPR:$Sm),
1091                   NoItinerary, !strconcat("vrint", opc, ".f16\t$Sd, $Sm"),
1092                   [(set (f16 HPR:$Sd), (node (f16 HPR:$Sm)))]>,
1093                   Requires<[HasFullFP16]> {
1094      let Inst{17-16} = rm;
1095    }
1096    def S : ASuInp<0b11101, 0b11, 0b1000, 0b01, 0,
1097                   (outs SPR:$Sd), (ins SPR:$Sm),
1098                   NoItinerary, !strconcat("vrint", opc, ".f32\t$Sd, $Sm"),
1099                   [(set (f32 SPR:$Sd), (node (f32 SPR:$Sm)))]>,
1100                   Requires<[HasFPARMv8]> {
1101      let Inst{17-16} = rm;
1102    }
1103    def D : ADuInp<0b11101, 0b11, 0b1000, 0b01, 0,
1104                   (outs DPR:$Dd), (ins DPR:$Dm),
1105                   NoItinerary, !strconcat("vrint", opc, ".f64\t$Dd, $Dm"),
1106                   [(set (f64 DPR:$Dd), (node (f64 DPR:$Dm)))]>,
1107                   Requires<[HasFPARMv8, HasDPVFP]> {
1108      let Inst{17-16} = rm;
1109    }
1110  }
1111
1112  def : InstAlias<!strconcat("vrint", opc, ".f16.f16\t$Sd, $Sm"),
1113                  (!cast<Instruction>(NAME#"H") HPR:$Sd, HPR:$Sm), 0>,
1114        Requires<[HasFullFP16]>;
1115  def : InstAlias<!strconcat("vrint", opc, ".f32.f32\t$Sd, $Sm"),
1116                  (!cast<Instruction>(NAME#"S") SPR:$Sd, SPR:$Sm), 0>,
1117        Requires<[HasFPARMv8]>;
1118  def : InstAlias<!strconcat("vrint", opc, ".f64.f64\t$Dd, $Dm"),
1119                  (!cast<Instruction>(NAME#"D") DPR:$Dd, DPR:$Dm), 0>,
1120        Requires<[HasFPARMv8,HasDPVFP]>;
1121}
1122
1123defm VRINTA : vrint_inst_anpm<"a", 0b00, fround>;
1124defm VRINTN : vrint_inst_anpm<"n", 0b01, int_arm_neon_vrintn>;
1125defm VRINTP : vrint_inst_anpm<"p", 0b10, fceil>;
1126defm VRINTM : vrint_inst_anpm<"m", 0b11, ffloor>;
1127
1128def VSQRTD : ADuI<0b11101, 0b11, 0b0001, 0b11, 0,
1129                  (outs DPR:$Dd), (ins DPR:$Dm),
1130                  IIC_fpSQRT64, "vsqrt", ".f64\t$Dd, $Dm", "",
1131                  [(set DPR:$Dd, (fsqrt (f64 DPR:$Dm)))]>,
1132             Sched<[WriteFPSQRT64]>;
1133
1134def VSQRTS : ASuI<0b11101, 0b11, 0b0001, 0b11, 0,
1135                  (outs SPR:$Sd), (ins SPR:$Sm),
1136                  IIC_fpSQRT32, "vsqrt", ".f32\t$Sd, $Sm", "",
1137                  [(set SPR:$Sd, (fsqrt SPR:$Sm))]>,
1138             Sched<[WriteFPSQRT32]>;
1139
1140def VSQRTH : AHuI<0b11101, 0b11, 0b0001, 0b11, 0,
1141                  (outs HPR:$Sd), (ins HPR:$Sm),
1142                  IIC_fpSQRT16, "vsqrt", ".f16\t$Sd, $Sm",
1143                  [(set (f16 HPR:$Sd), (fsqrt (f16 HPR:$Sm)))]>;
1144
1145let hasSideEffects = 0 in {
1146let isMoveReg = 1 in {
1147def VMOVD  : ADuI<0b11101, 0b11, 0b0000, 0b01, 0,
1148                  (outs DPR:$Dd), (ins DPR:$Dm),
1149                  IIC_fpUNA64, "vmov", ".f64\t$Dd, $Dm", "", []>,
1150             Requires<[HasFPRegs64]>;
1151
1152def VMOVS  : ASuI<0b11101, 0b11, 0b0000, 0b01, 0,
1153                  (outs SPR:$Sd), (ins SPR:$Sm),
1154                  IIC_fpUNA32, "vmov", ".f32\t$Sd, $Sm", "", []>,
1155             Requires<[HasFPRegs]>;
1156} // isMoveReg
1157
1158let PostEncoderMethod = "", DecoderNamespace = "VFPV8", isUnpredicable = 1 in {
1159def VMOVH  : ASuInp<0b11101, 0b11, 0b0000, 0b01, 0,
1160                  (outs SPR:$Sd), (ins SPR:$Sm),
1161                  IIC_fpUNA16, "vmovx.f16\t$Sd, $Sm", []>,
1162             Requires<[HasFullFP16]>;
1163
1164def VINSH  : ASuInp<0b11101, 0b11, 0b0000, 0b11, 0,
1165                  (outs SPR:$Sd), (ins SPR:$Sda, SPR:$Sm),
1166                  IIC_fpUNA16, "vins.f16\t$Sd, $Sm", []>,
1167             Requires<[HasFullFP16]> {
1168  let Constraints = "$Sd = $Sda";
1169}
1170
1171} // PostEncoderMethod
1172} // hasSideEffects
1173
1174//===----------------------------------------------------------------------===//
1175// FP <-> GPR Copies.  Int <-> FP Conversions.
1176//
1177
1178let isMoveReg = 1 in {
1179def VMOVRS : AVConv2I<0b11100001, 0b1010,
1180                      (outs GPR:$Rt), (ins SPR:$Sn),
1181                      IIC_fpMOVSI, "vmov", "\t$Rt, $Sn",
1182                      [(set GPR:$Rt, (bitconvert SPR:$Sn))]>,
1183             Requires<[HasFPRegs]>,
1184             Sched<[WriteFPMOV]> {
1185  // Instruction operands.
1186  bits<4> Rt;
1187  bits<5> Sn;
1188
1189  // Encode instruction operands.
1190  let Inst{19-16} = Sn{4-1};
1191  let Inst{7}     = Sn{0};
1192  let Inst{15-12} = Rt;
1193
1194  let Inst{6-5}   = 0b00;
1195  let Inst{3-0}   = 0b0000;
1196
1197  // Some single precision VFP instructions may be executed on both NEON and VFP
1198  // pipelines.
1199  let D = VFPNeonDomain;
1200}
1201
1202// Bitcast i32 -> f32.  NEON prefers to use VMOVDRR.
1203def VMOVSR : AVConv4I<0b11100000, 0b1010,
1204                      (outs SPR:$Sn), (ins GPR:$Rt),
1205                      IIC_fpMOVIS, "vmov", "\t$Sn, $Rt",
1206                      [(set SPR:$Sn, (bitconvert GPR:$Rt))]>,
1207             Requires<[HasFPRegs, UseVMOVSR]>,
1208             Sched<[WriteFPMOV]> {
1209  // Instruction operands.
1210  bits<5> Sn;
1211  bits<4> Rt;
1212
1213  // Encode instruction operands.
1214  let Inst{19-16} = Sn{4-1};
1215  let Inst{7}     = Sn{0};
1216  let Inst{15-12} = Rt;
1217
1218  let Inst{6-5}   = 0b00;
1219  let Inst{3-0}   = 0b0000;
1220
1221  // Some single precision VFP instructions may be executed on both NEON and VFP
1222  // pipelines.
1223  let D = VFPNeonDomain;
1224}
1225} // isMoveReg
1226def : Pat<(arm_vmovsr GPR:$Rt), (VMOVSR GPR:$Rt)>, Requires<[HasFPRegs, UseVMOVSR]>;
1227
1228let hasSideEffects = 0 in {
1229def VMOVRRD  : AVConv3I<0b11000101, 0b1011,
1230                        (outs GPR:$Rt, GPR:$Rt2), (ins DPR:$Dm),
1231                        IIC_fpMOVDI, "vmov", "\t$Rt, $Rt2, $Dm",
1232                 [(set GPR:$Rt, GPR:$Rt2, (arm_fmrrd DPR:$Dm))]>,
1233               Requires<[HasFPRegs]>,
1234               Sched<[WriteFPMOV]> {
1235  // Instruction operands.
1236  bits<5> Dm;
1237  bits<4> Rt;
1238  bits<4> Rt2;
1239
1240  // Encode instruction operands.
1241  let Inst{3-0}   = Dm{3-0};
1242  let Inst{5}     = Dm{4};
1243  let Inst{15-12} = Rt;
1244  let Inst{19-16} = Rt2;
1245
1246  let Inst{7-6} = 0b00;
1247
1248  // Some single precision VFP instructions may be executed on both NEON and VFP
1249  // pipelines.
1250  let D = VFPNeonDomain;
1251
1252  // This instruction is equivalent to
1253  // $Rt = EXTRACT_SUBREG $Dm, ssub_0
1254  // $Rt2 = EXTRACT_SUBREG $Dm, ssub_1
1255  let isExtractSubreg = 1;
1256}
1257
1258def VMOVRRS  : AVConv3I<0b11000101, 0b1010,
1259                      (outs GPR:$Rt, GPR:$Rt2), (ins SPR:$src1, SPR:$src2),
1260                 IIC_fpMOVDI, "vmov", "\t$Rt, $Rt2, $src1, $src2",
1261                 [/* For disassembly only; pattern left blank */]>,
1262               Requires<[HasFPRegs]>,
1263               Sched<[WriteFPMOV]> {
1264  bits<5> src1;
1265  bits<4> Rt;
1266  bits<4> Rt2;
1267
1268  // Encode instruction operands.
1269  let Inst{3-0}   = src1{4-1};
1270  let Inst{5}     = src1{0};
1271  let Inst{15-12} = Rt;
1272  let Inst{19-16} = Rt2;
1273
1274  let Inst{7-6} = 0b00;
1275
1276  // Some single precision VFP instructions may be executed on both NEON and VFP
1277  // pipelines.
1278  let D = VFPNeonDomain;
1279  let DecoderMethod = "DecodeVMOVRRS";
1280}
1281} // hasSideEffects
1282
1283// FMDHR: GPR -> SPR
1284// FMDLR: GPR -> SPR
1285
1286def VMOVDRR : AVConv5I<0b11000100, 0b1011,
1287                      (outs DPR:$Dm), (ins GPR:$Rt, GPR:$Rt2),
1288                      IIC_fpMOVID, "vmov", "\t$Dm, $Rt, $Rt2",
1289                      [(set DPR:$Dm, (arm_fmdrr GPR:$Rt, GPR:$Rt2))]>,
1290              Requires<[HasFPRegs]>,
1291              Sched<[WriteFPMOV]> {
1292  // Instruction operands.
1293  bits<5> Dm;
1294  bits<4> Rt;
1295  bits<4> Rt2;
1296
1297  // Encode instruction operands.
1298  let Inst{3-0}   = Dm{3-0};
1299  let Inst{5}     = Dm{4};
1300  let Inst{15-12} = Rt;
1301  let Inst{19-16} = Rt2;
1302
1303  let Inst{7-6}   = 0b00;
1304
1305  // Some single precision VFP instructions may be executed on both NEON and VFP
1306  // pipelines.
1307  let D = VFPNeonDomain;
1308
1309  // This instruction is equivalent to
1310  // $Dm = REG_SEQUENCE $Rt, ssub_0, $Rt2, ssub_1
1311  let isRegSequence = 1;
1312}
1313
1314// Hoist an fabs or a fneg of a value coming from integer registers
1315// and do the fabs/fneg on the integer value. This is never a lose
1316// and could enable the conversion to float to be removed completely.
1317def : Pat<(fabs (arm_fmdrr GPR:$Rl, GPR:$Rh)),
1318          (VMOVDRR GPR:$Rl, (BFC GPR:$Rh, (i32 0x7FFFFFFF)))>,
1319      Requires<[IsARM, HasV6T2]>;
1320def : Pat<(fabs (arm_fmdrr GPR:$Rl, GPR:$Rh)),
1321          (VMOVDRR GPR:$Rl, (t2BFC GPR:$Rh, (i32 0x7FFFFFFF)))>,
1322      Requires<[IsThumb2, HasV6T2]>;
1323def : Pat<(fneg (arm_fmdrr GPR:$Rl, GPR:$Rh)),
1324          (VMOVDRR GPR:$Rl, (EORri GPR:$Rh, (i32 0x80000000)))>,
1325      Requires<[IsARM]>;
1326def : Pat<(fneg (arm_fmdrr GPR:$Rl, GPR:$Rh)),
1327          (VMOVDRR GPR:$Rl, (t2EORri GPR:$Rh, (i32 0x80000000)))>,
1328      Requires<[IsThumb2]>;
1329
1330let hasSideEffects = 0 in
1331def VMOVSRR : AVConv5I<0b11000100, 0b1010,
1332                     (outs SPR:$dst1, SPR:$dst2), (ins GPR:$src1, GPR:$src2),
1333                IIC_fpMOVID, "vmov", "\t$dst1, $dst2, $src1, $src2",
1334                [/* For disassembly only; pattern left blank */]>,
1335              Requires<[HasFPRegs]>,
1336              Sched<[WriteFPMOV]> {
1337  // Instruction operands.
1338  bits<5> dst1;
1339  bits<4> src1;
1340  bits<4> src2;
1341
1342  // Encode instruction operands.
1343  let Inst{3-0}   = dst1{4-1};
1344  let Inst{5}     = dst1{0};
1345  let Inst{15-12} = src1;
1346  let Inst{19-16} = src2;
1347
1348  let Inst{7-6} = 0b00;
1349
1350  // Some single precision VFP instructions may be executed on both NEON and VFP
1351  // pipelines.
1352  let D = VFPNeonDomain;
1353
1354  let DecoderMethod = "DecodeVMOVSRR";
1355}
1356
1357// Move H->R, clearing top 16 bits
1358def VMOVRH : AVConv2I<0b11100001, 0b1001,
1359                      (outs rGPR:$Rt), (ins HPR:$Sn),
1360                      IIC_fpMOVSI, "vmov", ".f16\t$Rt, $Sn",
1361                      []>,
1362             Requires<[HasFPRegs16]>,
1363             Sched<[WriteFPMOV]> {
1364  // Instruction operands.
1365  bits<4> Rt;
1366  bits<5> Sn;
1367
1368  // Encode instruction operands.
1369  let Inst{19-16} = Sn{4-1};
1370  let Inst{7}     = Sn{0};
1371  let Inst{15-12} = Rt;
1372
1373  let Inst{6-5}   = 0b00;
1374  let Inst{3-0}   = 0b0000;
1375
1376  let isUnpredicable = 1;
1377}
1378
1379// Move R->H, clearing top 16 bits
1380def VMOVHR : AVConv4I<0b11100000, 0b1001,
1381                      (outs HPR:$Sn), (ins rGPR:$Rt),
1382                      IIC_fpMOVIS, "vmov", ".f16\t$Sn, $Rt",
1383                      []>,
1384             Requires<[HasFPRegs16]>,
1385             Sched<[WriteFPMOV]> {
1386  // Instruction operands.
1387  bits<5> Sn;
1388  bits<4> Rt;
1389
1390  // Encode instruction operands.
1391  let Inst{19-16} = Sn{4-1};
1392  let Inst{7}     = Sn{0};
1393  let Inst{15-12} = Rt;
1394
1395  let Inst{6-5}   = 0b00;
1396  let Inst{3-0}   = 0b0000;
1397
1398  let isUnpredicable = 1;
1399}
1400
1401def : FPRegs16Pat<(arm_vmovrh (f16 HPR:$Sn)), (VMOVRH (f16 HPR:$Sn))>;
1402def : FPRegs16Pat<(arm_vmovrh (bf16 HPR:$Sn)), (VMOVRH (bf16 HPR:$Sn))>;
1403def : FPRegs16Pat<(f16 (arm_vmovhr rGPR:$Rt)), (VMOVHR rGPR:$Rt)>;
1404def : FPRegs16Pat<(bf16 (arm_vmovhr rGPR:$Rt)), (VMOVHR rGPR:$Rt)>;
1405
1406// FMRDH: SPR -> GPR
1407// FMRDL: SPR -> GPR
1408// FMRRS: SPR -> GPR
1409// FMRX:  SPR system reg -> GPR
1410// FMSRR: GPR -> SPR
1411// FMXR:  GPR -> VFP system reg
1412
1413
1414// Int -> FP:
1415
1416class AVConv1IDs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
1417                        bits<4> opcod4, dag oops, dag iops,
1418                        InstrItinClass itin, string opc, string asm,
1419                        list<dag> pattern>
1420  : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
1421             pattern> {
1422  // Instruction operands.
1423  bits<5> Dd;
1424  bits<5> Sm;
1425
1426  // Encode instruction operands.
1427  let Inst{3-0}   = Sm{4-1};
1428  let Inst{5}     = Sm{0};
1429  let Inst{15-12} = Dd{3-0};
1430  let Inst{22}    = Dd{4};
1431
1432  let Predicates = [HasVFP2, HasDPVFP];
1433  let hasSideEffects = 0;
1434}
1435
1436class AVConv1InSs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
1437                         bits<4> opcod4, dag oops, dag iops,InstrItinClass itin,
1438                         string opc, string asm, list<dag> pattern>
1439  : AVConv1In<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
1440              pattern> {
1441  // Instruction operands.
1442  bits<5> Sd;
1443  bits<5> Sm;
1444
1445  // Encode instruction operands.
1446  let Inst{3-0}   = Sm{4-1};
1447  let Inst{5}     = Sm{0};
1448  let Inst{15-12} = Sd{4-1};
1449  let Inst{22}    = Sd{0};
1450
1451  let hasSideEffects = 0;
1452}
1453
1454class AVConv1IHs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
1455                        bits<4> opcod4, dag oops, dag iops,
1456                        InstrItinClass itin, string opc, string asm,
1457                        list<dag> pattern>
1458  : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
1459             pattern> {
1460  // Instruction operands.
1461  bits<5> Sd;
1462  bits<5> Sm;
1463
1464  // Encode instruction operands.
1465  let Inst{3-0}   = Sm{4-1};
1466  let Inst{5}     = Sm{0};
1467  let Inst{15-12} = Sd{4-1};
1468  let Inst{22}    = Sd{0};
1469
1470  let Predicates = [HasFullFP16];
1471  let hasSideEffects = 0;
1472}
1473
1474def VSITOD : AVConv1IDs_Encode<0b11101, 0b11, 0b1000, 0b1011,
1475                               (outs DPR:$Dd), (ins SPR:$Sm),
1476                               IIC_fpCVTID, "vcvt", ".f64.s32\t$Dd, $Sm",
1477                               []>,
1478             Sched<[WriteFPCVT]> {
1479  let Inst{7} = 1; // s32
1480}
1481
1482let Predicates=[HasVFP2, HasDPVFP] in {
1483  def : VFPPat<(f64 (sint_to_fp GPR:$a)),
1484               (VSITOD (COPY_TO_REGCLASS GPR:$a, SPR))>;
1485
1486  def : VFPPat<(f64 (sint_to_fp (i32 (alignedload32 addrmode5:$a)))),
1487               (VSITOD (VLDRS addrmode5:$a))>;
1488}
1489
1490def VSITOS : AVConv1InSs_Encode<0b11101, 0b11, 0b1000, 0b1010,
1491                                (outs SPR:$Sd),(ins SPR:$Sm),
1492                                IIC_fpCVTIS, "vcvt", ".f32.s32\t$Sd, $Sm",
1493                                []>,
1494             Sched<[WriteFPCVT]> {
1495  let Inst{7} = 1; // s32
1496
1497  // Some single precision VFP instructions may be executed on both NEON and
1498  // VFP pipelines on A8.
1499  let D = VFPNeonA8Domain;
1500}
1501
1502def : VFPNoNEONPat<(f32 (sint_to_fp GPR:$a)),
1503                   (VSITOS (COPY_TO_REGCLASS GPR:$a, SPR))>;
1504
1505def : VFPNoNEONPat<(f32 (sint_to_fp (i32 (alignedload32 addrmode5:$a)))),
1506                   (VSITOS (VLDRS addrmode5:$a))>;
1507
1508def VSITOH : AVConv1IHs_Encode<0b11101, 0b11, 0b1000, 0b1001,
1509                               (outs HPR:$Sd), (ins SPR:$Sm),
1510                               IIC_fpCVTIH, "vcvt", ".f16.s32\t$Sd, $Sm",
1511                               []>,
1512             Sched<[WriteFPCVT]> {
1513  let Inst{7} = 1; // s32
1514  let isUnpredicable = 1;
1515}
1516
1517def : VFPNoNEONPat<(f16 (sint_to_fp GPR:$a)),
1518                   (VSITOH (COPY_TO_REGCLASS GPR:$a, SPR))>;
1519
1520def VUITOD : AVConv1IDs_Encode<0b11101, 0b11, 0b1000, 0b1011,
1521                               (outs DPR:$Dd), (ins SPR:$Sm),
1522                               IIC_fpCVTID, "vcvt", ".f64.u32\t$Dd, $Sm",
1523                               []>,
1524             Sched<[WriteFPCVT]> {
1525  let Inst{7} = 0; // u32
1526}
1527
1528let Predicates=[HasVFP2, HasDPVFP] in {
1529  def : VFPPat<(f64 (uint_to_fp GPR:$a)),
1530               (VUITOD (COPY_TO_REGCLASS GPR:$a, SPR))>;
1531
1532  def : VFPPat<(f64 (uint_to_fp (i32 (alignedload32 addrmode5:$a)))),
1533               (VUITOD (VLDRS addrmode5:$a))>;
1534}
1535
1536def VUITOS : AVConv1InSs_Encode<0b11101, 0b11, 0b1000, 0b1010,
1537                                (outs SPR:$Sd), (ins SPR:$Sm),
1538                                IIC_fpCVTIS, "vcvt", ".f32.u32\t$Sd, $Sm",
1539                                []>,
1540             Sched<[WriteFPCVT]> {
1541  let Inst{7} = 0; // u32
1542
1543  // Some single precision VFP instructions may be executed on both NEON and
1544  // VFP pipelines on A8.
1545  let D = VFPNeonA8Domain;
1546}
1547
1548def : VFPNoNEONPat<(f32 (uint_to_fp GPR:$a)),
1549                   (VUITOS (COPY_TO_REGCLASS GPR:$a, SPR))>;
1550
1551def : VFPNoNEONPat<(f32 (uint_to_fp (i32 (alignedload32 addrmode5:$a)))),
1552                   (VUITOS (VLDRS addrmode5:$a))>;
1553
1554def VUITOH : AVConv1IHs_Encode<0b11101, 0b11, 0b1000, 0b1001,
1555                                (outs HPR:$Sd), (ins SPR:$Sm),
1556                                IIC_fpCVTIH, "vcvt", ".f16.u32\t$Sd, $Sm",
1557                                []>,
1558             Sched<[WriteFPCVT]> {
1559  let Inst{7} = 0; // u32
1560  let isUnpredicable = 1;
1561}
1562
1563def : VFPNoNEONPat<(f16 (uint_to_fp GPR:$a)),
1564                   (VUITOH (COPY_TO_REGCLASS GPR:$a, SPR))>;
1565
1566// FP -> Int:
1567
1568class AVConv1IsD_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
1569                        bits<4> opcod4, dag oops, dag iops,
1570                        InstrItinClass itin, string opc, string asm,
1571                        list<dag> pattern>
1572  : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
1573             pattern> {
1574  // Instruction operands.
1575  bits<5> Sd;
1576  bits<5> Dm;
1577
1578  // Encode instruction operands.
1579  let Inst{3-0}   = Dm{3-0};
1580  let Inst{5}     = Dm{4};
1581  let Inst{15-12} = Sd{4-1};
1582  let Inst{22}    = Sd{0};
1583
1584  let Predicates = [HasVFP2, HasDPVFP];
1585  let hasSideEffects = 0;
1586}
1587
1588class AVConv1InsS_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
1589                         bits<4> opcod4, dag oops, dag iops,
1590                         InstrItinClass itin, string opc, string asm,
1591                         list<dag> pattern>
1592  : AVConv1In<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
1593              pattern> {
1594  // Instruction operands.
1595  bits<5> Sd;
1596  bits<5> Sm;
1597
1598  // Encode instruction operands.
1599  let Inst{3-0}   = Sm{4-1};
1600  let Inst{5}     = Sm{0};
1601  let Inst{15-12} = Sd{4-1};
1602  let Inst{22}    = Sd{0};
1603
1604  let hasSideEffects = 0;
1605}
1606
1607class AVConv1IsH_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
1608                         bits<4> opcod4, dag oops, dag iops,
1609                         InstrItinClass itin, string opc, string asm,
1610                         list<dag> pattern>
1611  : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
1612              pattern> {
1613  // Instruction operands.
1614  bits<5> Sd;
1615  bits<5> Sm;
1616
1617  // Encode instruction operands.
1618  let Inst{3-0}   = Sm{4-1};
1619  let Inst{5}     = Sm{0};
1620  let Inst{15-12} = Sd{4-1};
1621  let Inst{22}    = Sd{0};
1622
1623  let Predicates = [HasFullFP16];
1624  let hasSideEffects = 0;
1625}
1626
1627// Always set Z bit in the instruction, i.e. "round towards zero" variants.
1628def VTOSIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011,
1629                                (outs SPR:$Sd), (ins DPR:$Dm),
1630                                IIC_fpCVTDI, "vcvt", ".s32.f64\t$Sd, $Dm",
1631                                []>,
1632              Sched<[WriteFPCVT]> {
1633  let Inst{7} = 1; // Z bit
1634}
1635
1636let Predicates=[HasVFP2, HasDPVFP] in {
1637  def : VFPPat<(i32 (fp_to_sint (f64 DPR:$a))),
1638               (COPY_TO_REGCLASS (VTOSIZD DPR:$a), GPR)>;
1639  def : VFPPat<(i32 (fp_to_sint_sat (f64 DPR:$a), i32)),
1640               (COPY_TO_REGCLASS (VTOSIZD DPR:$a), GPR)>;
1641
1642  def : VFPPat<(alignedstore32 (i32 (fp_to_sint (f64 DPR:$a))), addrmode5:$ptr),
1643               (VSTRS (VTOSIZD DPR:$a), addrmode5:$ptr)>;
1644  def : VFPPat<(alignedstore32 (i32 (fp_to_sint_sat (f64 DPR:$a), i32)), addrmode5:$ptr),
1645               (VSTRS (VTOSIZD DPR:$a), addrmode5:$ptr)>;
1646}
1647
1648def VTOSIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010,
1649                                 (outs SPR:$Sd), (ins SPR:$Sm),
1650                                 IIC_fpCVTSI, "vcvt", ".s32.f32\t$Sd, $Sm",
1651                                 []>,
1652              Sched<[WriteFPCVT]> {
1653  let Inst{7} = 1; // Z bit
1654
1655  // Some single precision VFP instructions may be executed on both NEON and
1656  // VFP pipelines on A8.
1657  let D = VFPNeonA8Domain;
1658}
1659
1660def : VFPNoNEONPat<(i32 (fp_to_sint SPR:$a)),
1661                   (COPY_TO_REGCLASS (VTOSIZS SPR:$a), GPR)>;
1662def : VFPPat<(i32 (fp_to_sint_sat SPR:$a, i32)),
1663             (COPY_TO_REGCLASS (VTOSIZS SPR:$a), GPR)>;
1664
1665def : VFPNoNEONPat<(alignedstore32 (i32 (fp_to_sint (f32 SPR:$a))),
1666                                   addrmode5:$ptr),
1667                   (VSTRS (VTOSIZS SPR:$a), addrmode5:$ptr)>;
1668def : VFPPat<(alignedstore32 (i32 (fp_to_sint_sat (f32 SPR:$a), i32)),
1669                                   addrmode5:$ptr),
1670             (VSTRS (VTOSIZS SPR:$a), addrmode5:$ptr)>;
1671
1672def VTOSIZH : AVConv1IsH_Encode<0b11101, 0b11, 0b1101, 0b1001,
1673                                 (outs SPR:$Sd), (ins HPR:$Sm),
1674                                 IIC_fpCVTHI, "vcvt", ".s32.f16\t$Sd, $Sm",
1675                                 []>,
1676              Sched<[WriteFPCVT]> {
1677  let Inst{7} = 1; // Z bit
1678  let isUnpredicable = 1;
1679}
1680
1681def : VFPNoNEONPat<(i32 (fp_to_sint (f16 HPR:$a))),
1682                   (COPY_TO_REGCLASS (VTOSIZH (f16 HPR:$a)), GPR)>;
1683def : VFPPat<(i32 (fp_to_sint_sat (f16 HPR:$a), i32)),
1684             (COPY_TO_REGCLASS (VTOSIZH (f16 HPR:$a)), GPR)>;
1685
1686def VTOUIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011,
1687                               (outs SPR:$Sd), (ins DPR:$Dm),
1688                               IIC_fpCVTDI, "vcvt", ".u32.f64\t$Sd, $Dm",
1689                               []>,
1690              Sched<[WriteFPCVT]> {
1691  let Inst{7} = 1; // Z bit
1692}
1693
1694let Predicates=[HasVFP2, HasDPVFP] in {
1695  def : VFPPat<(i32 (fp_to_uint (f64 DPR:$a))),
1696               (COPY_TO_REGCLASS (VTOUIZD DPR:$a), GPR)>;
1697  def : VFPPat<(i32 (fp_to_uint_sat (f64 DPR:$a), i32)),
1698               (COPY_TO_REGCLASS (VTOUIZD DPR:$a), GPR)>;
1699
1700  def : VFPPat<(alignedstore32 (i32 (fp_to_uint (f64 DPR:$a))), addrmode5:$ptr),
1701               (VSTRS (VTOUIZD DPR:$a), addrmode5:$ptr)>;
1702  def : VFPPat<(alignedstore32 (i32 (fp_to_uint_sat (f64 DPR:$a), i32)), addrmode5:$ptr),
1703               (VSTRS (VTOUIZD DPR:$a), addrmode5:$ptr)>;
1704}
1705
1706def VTOUIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010,
1707                                 (outs SPR:$Sd), (ins SPR:$Sm),
1708                                 IIC_fpCVTSI, "vcvt", ".u32.f32\t$Sd, $Sm",
1709                                 []>,
1710              Sched<[WriteFPCVT]> {
1711  let Inst{7} = 1; // Z bit
1712
1713  // Some single precision VFP instructions may be executed on both NEON and
1714  // VFP pipelines on A8.
1715  let D = VFPNeonA8Domain;
1716}
1717
1718def : VFPNoNEONPat<(i32 (fp_to_uint SPR:$a)),
1719                   (COPY_TO_REGCLASS (VTOUIZS SPR:$a), GPR)>;
1720def : VFPPat<(i32 (fp_to_uint_sat SPR:$a, i32)),
1721             (COPY_TO_REGCLASS (VTOUIZS SPR:$a), GPR)>;
1722
1723def : VFPNoNEONPat<(alignedstore32 (i32 (fp_to_uint (f32 SPR:$a))),
1724                                   addrmode5:$ptr),
1725                  (VSTRS (VTOUIZS SPR:$a), addrmode5:$ptr)>;
1726def : VFPPat<(alignedstore32 (i32 (fp_to_uint_sat (f32 SPR:$a), i32)),
1727                                   addrmode5:$ptr),
1728             (VSTRS (VTOUIZS SPR:$a), addrmode5:$ptr)>;
1729
1730def VTOUIZH : AVConv1IsH_Encode<0b11101, 0b11, 0b1100, 0b1001,
1731                                 (outs SPR:$Sd), (ins HPR:$Sm),
1732                                 IIC_fpCVTHI, "vcvt", ".u32.f16\t$Sd, $Sm",
1733                                 []>,
1734              Sched<[WriteFPCVT]> {
1735  let Inst{7} = 1; // Z bit
1736  let isUnpredicable = 1;
1737}
1738
1739def : VFPNoNEONPat<(i32 (fp_to_uint (f16 HPR:$a))),
1740                   (COPY_TO_REGCLASS (VTOUIZH (f16 HPR:$a)), GPR)>;
1741def : VFPPat<(i32 (fp_to_uint_sat (f16 HPR:$a), i32)),
1742             (COPY_TO_REGCLASS (VTOUIZH (f16 HPR:$a)), GPR)>;
1743
1744// And the Z bit '0' variants, i.e. use the rounding mode specified by FPSCR.
1745let Uses = [FPSCR] in {
1746def VTOSIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011,
1747                                (outs SPR:$Sd), (ins DPR:$Dm),
1748                                IIC_fpCVTDI, "vcvtr", ".s32.f64\t$Sd, $Dm",
1749                                [(set SPR:$Sd, (int_arm_vcvtr (f64 DPR:$Dm)))]>,
1750              Sched<[WriteFPCVT]> {
1751  let Inst{7} = 0; // Z bit
1752}
1753
1754def VTOSIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010,
1755                                 (outs SPR:$Sd), (ins SPR:$Sm),
1756                                 IIC_fpCVTSI, "vcvtr", ".s32.f32\t$Sd, $Sm",
1757                                 [(set SPR:$Sd, (int_arm_vcvtr SPR:$Sm))]>,
1758              Sched<[WriteFPCVT]> {
1759  let Inst{7} = 0; // Z bit
1760}
1761
1762def VTOSIRH : AVConv1IsH_Encode<0b11101, 0b11, 0b1101, 0b1001,
1763                                 (outs SPR:$Sd), (ins SPR:$Sm),
1764                                 IIC_fpCVTHI, "vcvtr", ".s32.f16\t$Sd, $Sm",
1765                                 []>,
1766              Sched<[WriteFPCVT]> {
1767  let Inst{7} = 0; // Z bit
1768  let isUnpredicable = 1;
1769}
1770
1771def VTOUIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011,
1772                                (outs SPR:$Sd), (ins DPR:$Dm),
1773                                IIC_fpCVTDI, "vcvtr", ".u32.f64\t$Sd, $Dm",
1774                                [(set SPR:$Sd, (int_arm_vcvtru(f64 DPR:$Dm)))]>,
1775              Sched<[WriteFPCVT]> {
1776  let Inst{7} = 0; // Z bit
1777}
1778
1779def VTOUIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010,
1780                                 (outs SPR:$Sd), (ins SPR:$Sm),
1781                                 IIC_fpCVTSI, "vcvtr", ".u32.f32\t$Sd, $Sm",
1782                                 [(set SPR:$Sd, (int_arm_vcvtru SPR:$Sm))]>,
1783              Sched<[WriteFPCVT]> {
1784  let Inst{7} = 0; // Z bit
1785}
1786
1787def VTOUIRH : AVConv1IsH_Encode<0b11101, 0b11, 0b1100, 0b1001,
1788                                 (outs SPR:$Sd), (ins SPR:$Sm),
1789                                 IIC_fpCVTHI, "vcvtr", ".u32.f16\t$Sd, $Sm",
1790                                 []>,
1791              Sched<[WriteFPCVT]> {
1792  let Inst{7} = 0; // Z bit
1793  let isUnpredicable = 1;
1794}
1795}
1796
1797// v8.3-a Javascript Convert to Signed fixed-point
1798def VJCVT : AVConv1IsD_Encode<0b11101, 0b11, 0b1001, 0b1011,
1799                                (outs SPR:$Sd), (ins DPR:$Dm),
1800                                IIC_fpCVTDI, "vjcvt", ".s32.f64\t$Sd, $Dm",
1801                                []>,
1802            Requires<[HasFPARMv8, HasV8_3a]> {
1803  let Inst{7} = 1; // Z bit
1804}
1805
1806// Convert between floating-point and fixed-point
1807// Data type for fixed-point naming convention:
1808//   S16 (U=0, sx=0) -> SH
1809//   U16 (U=1, sx=0) -> UH
1810//   S32 (U=0, sx=1) -> SL
1811//   U32 (U=1, sx=1) -> UL
1812
1813let Constraints = "$a = $dst" in {
1814
1815// FP to Fixed-Point:
1816
1817// Single Precision register
1818class AVConv1XInsS_Encode<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4,
1819                          bit op5, dag oops, dag iops, InstrItinClass itin,
1820                          string opc, string asm, list<dag> pattern>
1821  : AVConv1XI<op1, op2, op3, op4, op5, oops, iops, itin, opc, asm, pattern> {
1822  bits<5> dst;
1823  // if dp_operation then UInt(D:Vd) else UInt(Vd:D);
1824  let Inst{22} = dst{0};
1825  let Inst{15-12} = dst{4-1};
1826
1827  let hasSideEffects = 0;
1828}
1829
1830// Double Precision register
1831class AVConv1XInsD_Encode<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4,
1832                          bit op5, dag oops, dag iops, InstrItinClass itin,
1833                          string opc, string asm, list<dag> pattern>
1834  : AVConv1XI<op1, op2, op3, op4, op5, oops, iops, itin, opc, asm, pattern> {
1835  bits<5> dst;
1836  // if dp_operation then UInt(D:Vd) else UInt(Vd:D);
1837  let Inst{22} = dst{4};
1838  let Inst{15-12} = dst{3-0};
1839
1840  let hasSideEffects = 0;
1841  let Predicates = [HasVFP2, HasDPVFP];
1842}
1843
1844let isUnpredicable = 1 in {
1845
1846def VTOSHH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1001, 0,
1847                       (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
1848                 IIC_fpCVTHI, "vcvt", ".s16.f16\t$dst, $a, $fbits", []>,
1849             Requires<[HasFullFP16]>,
1850             Sched<[WriteFPCVT]>;
1851
1852def VTOUHH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1001, 0,
1853                       (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
1854                 IIC_fpCVTHI, "vcvt", ".u16.f16\t$dst, $a, $fbits", []>,
1855             Requires<[HasFullFP16]>,
1856             Sched<[WriteFPCVT]>;
1857
1858def VTOSLH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1001, 1,
1859                       (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
1860                 IIC_fpCVTHI, "vcvt", ".s32.f16\t$dst, $a, $fbits", []>,
1861             Requires<[HasFullFP16]>,
1862             Sched<[WriteFPCVT]>;
1863
1864def VTOULH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1001, 1,
1865                       (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
1866                 IIC_fpCVTHI, "vcvt", ".u32.f16\t$dst, $a, $fbits", []>,
1867             Requires<[HasFullFP16]>,
1868             Sched<[WriteFPCVT]>;
1869
1870} // End of 'let isUnpredicable = 1 in'
1871
1872def VTOSHS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1010, 0,
1873                       (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
1874                 IIC_fpCVTSI, "vcvt", ".s16.f32\t$dst, $a, $fbits", []>,
1875             Sched<[WriteFPCVT]> {
1876  // Some single precision VFP instructions may be executed on both NEON and
1877  // VFP pipelines on A8.
1878  let D = VFPNeonA8Domain;
1879}
1880
1881def VTOUHS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1010, 0,
1882                       (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
1883                 IIC_fpCVTSI, "vcvt", ".u16.f32\t$dst, $a, $fbits", []>,
1884             Sched<[WriteFPCVT]> {
1885  // Some single precision VFP instructions may be executed on both NEON and
1886  // VFP pipelines on A8.
1887  let D = VFPNeonA8Domain;
1888}
1889
1890def VTOSLS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1010, 1,
1891                       (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
1892                 IIC_fpCVTSI, "vcvt", ".s32.f32\t$dst, $a, $fbits", []>,
1893             Sched<[WriteFPCVT]> {
1894  // Some single precision VFP instructions may be executed on both NEON and
1895  // VFP pipelines on A8.
1896  let D = VFPNeonA8Domain;
1897}
1898
1899def VTOULS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1010, 1,
1900                       (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
1901                 IIC_fpCVTSI, "vcvt", ".u32.f32\t$dst, $a, $fbits", []>,
1902             Sched<[WriteFPCVT]> {
1903  // Some single precision VFP instructions may be executed on both NEON and
1904  // VFP pipelines on A8.
1905  let D = VFPNeonA8Domain;
1906}
1907
1908def VTOSHD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1110, 0b1011, 0,
1909                       (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits),
1910                 IIC_fpCVTDI, "vcvt", ".s16.f64\t$dst, $a, $fbits", []>,
1911             Sched<[WriteFPCVT]>;
1912
1913def VTOUHD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1111, 0b1011, 0,
1914                       (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits),
1915                 IIC_fpCVTDI, "vcvt", ".u16.f64\t$dst, $a, $fbits", []>,
1916             Sched<[WriteFPCVT]>;
1917
1918def VTOSLD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1110, 0b1011, 1,
1919                       (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits),
1920                 IIC_fpCVTDI, "vcvt", ".s32.f64\t$dst, $a, $fbits", []>,
1921             Sched<[WriteFPCVT]>;
1922
1923def VTOULD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1111, 0b1011, 1,
1924                       (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits),
1925                 IIC_fpCVTDI, "vcvt", ".u32.f64\t$dst, $a, $fbits", []>,
1926             Sched<[WriteFPCVT]>;
1927
1928// Fixed-Point to FP:
1929
1930let isUnpredicable = 1 in {
1931
1932def VSHTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1001, 0,
1933                       (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
1934                 IIC_fpCVTIH, "vcvt", ".f16.s16\t$dst, $a, $fbits", []>,
1935             Requires<[HasFullFP16]>,
1936             Sched<[WriteFPCVT]>;
1937
1938def VUHTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1001, 0,
1939                       (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
1940                 IIC_fpCVTIH, "vcvt", ".f16.u16\t$dst, $a, $fbits", []>,
1941             Requires<[HasFullFP16]>,
1942             Sched<[WriteFPCVT]>;
1943
1944def VSLTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1001, 1,
1945                       (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
1946                 IIC_fpCVTIH, "vcvt", ".f16.s32\t$dst, $a, $fbits", []>,
1947             Requires<[HasFullFP16]>,
1948             Sched<[WriteFPCVT]>;
1949
1950def VULTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1001, 1,
1951                       (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
1952                 IIC_fpCVTIH, "vcvt", ".f16.u32\t$dst, $a, $fbits", []>,
1953             Requires<[HasFullFP16]>,
1954             Sched<[WriteFPCVT]>;
1955
1956} // End of 'let isUnpredicable = 1 in'
1957
1958def VSHTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1010, 0,
1959                       (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
1960                 IIC_fpCVTIS, "vcvt", ".f32.s16\t$dst, $a, $fbits", []>,
1961             Sched<[WriteFPCVT]> {
1962  // Some single precision VFP instructions may be executed on both NEON and
1963  // VFP pipelines on A8.
1964  let D = VFPNeonA8Domain;
1965}
1966
1967def VUHTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1010, 0,
1968                       (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits),
1969                 IIC_fpCVTIS, "vcvt", ".f32.u16\t$dst, $a, $fbits", []>,
1970             Sched<[WriteFPCVT]> {
1971  // Some single precision VFP instructions may be executed on both NEON and
1972  // VFP pipelines on A8.
1973  let D = VFPNeonA8Domain;
1974}
1975
1976def VSLTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1010, 1,
1977                       (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
1978                 IIC_fpCVTIS, "vcvt", ".f32.s32\t$dst, $a, $fbits", []>,
1979             Sched<[WriteFPCVT]> {
1980  // Some single precision VFP instructions may be executed on both NEON and
1981  // VFP pipelines on A8.
1982  let D = VFPNeonA8Domain;
1983}
1984
1985def VULTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1010, 1,
1986                       (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits),
1987                 IIC_fpCVTIS, "vcvt", ".f32.u32\t$dst, $a, $fbits", []>,
1988             Sched<[WriteFPCVT]> {
1989  // Some single precision VFP instructions may be executed on both NEON and
1990  // VFP pipelines on A8.
1991  let D = VFPNeonA8Domain;
1992}
1993
1994def VSHTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1010, 0b1011, 0,
1995                       (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits),
1996                 IIC_fpCVTID, "vcvt", ".f64.s16\t$dst, $a, $fbits", []>,
1997             Sched<[WriteFPCVT]>;
1998
1999def VUHTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1011, 0b1011, 0,
2000                       (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits),
2001                 IIC_fpCVTID, "vcvt", ".f64.u16\t$dst, $a, $fbits", []>,
2002             Sched<[WriteFPCVT]>;
2003
2004def VSLTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1010, 0b1011, 1,
2005                       (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits),
2006                 IIC_fpCVTID, "vcvt", ".f64.s32\t$dst, $a, $fbits", []>,
2007             Sched<[WriteFPCVT]>;
2008
2009def VULTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1011, 0b1011, 1,
2010                       (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits),
2011                 IIC_fpCVTID, "vcvt", ".f64.u32\t$dst, $a, $fbits", []>,
2012             Sched<[WriteFPCVT]>;
2013
2014} // End of 'let Constraints = "$a = $dst" in'
2015
2016// BFloat16  - Single precision, unary, predicated
2017class BF16_VCVT<string opc, bits<2> op7_6>
2018   : VFPAI<(outs SPR:$Sd), (ins SPR:$dst, SPR:$Sm),
2019           VFPUnaryFrm, NoItinerary,
2020           opc, ".bf16.f32\t$Sd, $Sm", "", []>,
2021      RegConstraint<"$dst = $Sd">,
2022      Requires<[HasBF16]>,
2023     Sched<[]> {
2024  bits<5> Sd;
2025  bits<5> Sm;
2026
2027  // Encode instruction operands.
2028  let Inst{3-0}   = Sm{4-1};
2029  let Inst{5}     = Sm{0};
2030  let Inst{15-12} = Sd{4-1};
2031  let Inst{22}    = Sd{0};
2032
2033  let Inst{27-23} = 0b11101; // opcode1
2034  let Inst{21-20} = 0b11;    // opcode2
2035  let Inst{19-16} = 0b0011;  // opcode3
2036  let Inst{11-8}  = 0b1001;
2037  let Inst{7-6}   = op7_6;
2038  let Inst{4}     = 0;
2039
2040  let DecoderNamespace = "VFPV8";
2041  let hasSideEffects = 0;
2042}
2043
2044def BF16_VCVTB : BF16_VCVT<"vcvtb", 0b01>;
2045def BF16_VCVTT : BF16_VCVT<"vcvtt", 0b11>;
2046
2047//===----------------------------------------------------------------------===//
2048// FP Multiply-Accumulate Operations.
2049//
2050
2051def VMLAD : ADbI<0b11100, 0b00, 0, 0,
2052                 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
2053                 IIC_fpMAC64, "vmla", ".f64\t$Dd, $Dn, $Dm",
2054                 [(set DPR:$Dd, (fadd_mlx (fmul_su DPR:$Dn, DPR:$Dm),
2055                                          (f64 DPR:$Ddin)))]>,
2056              RegConstraint<"$Ddin = $Dd">,
2057              Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>,
2058              Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
2059
2060def VMLAS : ASbIn<0b11100, 0b00, 0, 0,
2061                  (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
2062                  IIC_fpMAC32, "vmla", ".f32\t$Sd, $Sn, $Sm",
2063                  [(set SPR:$Sd, (fadd_mlx (fmul_su SPR:$Sn, SPR:$Sm),
2064                                           SPR:$Sdin))]>,
2065              RegConstraint<"$Sdin = $Sd">,
2066              Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>,
2067              Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> {
2068  // Some single precision VFP instructions may be executed on both NEON and
2069  // VFP pipelines on A8.
2070  let D = VFPNeonA8Domain;
2071}
2072
2073def VMLAH : AHbI<0b11100, 0b00, 0, 0,
2074                  (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm),
2075                  IIC_fpMAC16, "vmla", ".f16\t$Sd, $Sn, $Sm",
2076                  [(set (f16 HPR:$Sd), (fadd_mlx (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm)),
2077                                           (f16 HPR:$Sdin)))]>,
2078              RegConstraint<"$Sdin = $Sd">,
2079              Requires<[HasFullFP16,UseFPVMLx]>;
2080
2081def : Pat<(fadd_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))),
2082          (VMLAD DPR:$dstin, DPR:$a, DPR:$b)>,
2083          Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>;
2084def : Pat<(fadd_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)),
2085          (VMLAS SPR:$dstin, SPR:$a, SPR:$b)>,
2086          Requires<[HasVFP2,DontUseNEONForFP, UseFPVMLx]>;
2087def : Pat<(fadd_mlx HPR:$dstin, (fmul_su (f16 HPR:$a), HPR:$b)),
2088          (VMLAH HPR:$dstin, (f16 HPR:$a), HPR:$b)>,
2089          Requires<[HasFullFP16,DontUseNEONForFP, UseFPVMLx]>;
2090
2091
2092def VMLSD : ADbI<0b11100, 0b00, 1, 0,
2093                 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
2094                 IIC_fpMAC64, "vmls", ".f64\t$Dd, $Dn, $Dm",
2095                 [(set DPR:$Dd, (fadd_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)),
2096                                          (f64 DPR:$Ddin)))]>,
2097              RegConstraint<"$Ddin = $Dd">,
2098              Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>,
2099              Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
2100
2101def VMLSS : ASbIn<0b11100, 0b00, 1, 0,
2102                  (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
2103                  IIC_fpMAC32, "vmls", ".f32\t$Sd, $Sn, $Sm",
2104                  [(set SPR:$Sd, (fadd_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)),
2105                                           SPR:$Sdin))]>,
2106              RegConstraint<"$Sdin = $Sd">,
2107              Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>,
2108              Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> {
2109  // Some single precision VFP instructions may be executed on both NEON and
2110  // VFP pipelines on A8.
2111  let D = VFPNeonA8Domain;
2112}
2113
2114def VMLSH : AHbI<0b11100, 0b00, 1, 0,
2115                  (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm),
2116                  IIC_fpMAC16, "vmls", ".f16\t$Sd, $Sn, $Sm",
2117                  [(set (f16 HPR:$Sd), (fadd_mlx (fneg (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm))),
2118                                           (f16 HPR:$Sdin)))]>,
2119              RegConstraint<"$Sdin = $Sd">,
2120              Requires<[HasFullFP16,UseFPVMLx]>;
2121
2122def : Pat<(fsub_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))),
2123          (VMLSD DPR:$dstin, DPR:$a, DPR:$b)>,
2124          Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>;
2125def : Pat<(fsub_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)),
2126          (VMLSS SPR:$dstin, SPR:$a, SPR:$b)>,
2127          Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>;
2128def : Pat<(fsub_mlx HPR:$dstin, (fmul_su (f16 HPR:$a), HPR:$b)),
2129          (VMLSH HPR:$dstin, (f16 HPR:$a), HPR:$b)>,
2130          Requires<[HasFullFP16,DontUseNEONForFP,UseFPVMLx]>;
2131
2132def VNMLAD : ADbI<0b11100, 0b01, 1, 0,
2133                  (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
2134                  IIC_fpMAC64, "vnmla", ".f64\t$Dd, $Dn, $Dm",
2135                  [(set DPR:$Dd,(fsub_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)),
2136                                          (f64 DPR:$Ddin)))]>,
2137                RegConstraint<"$Ddin = $Dd">,
2138                Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>,
2139                Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
2140
2141def VNMLAS : ASbI<0b11100, 0b01, 1, 0,
2142                  (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
2143                  IIC_fpMAC32, "vnmla", ".f32\t$Sd, $Sn, $Sm",
2144                  [(set SPR:$Sd, (fsub_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)),
2145                                           SPR:$Sdin))]>,
2146                RegConstraint<"$Sdin = $Sd">,
2147                Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>,
2148                Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> {
2149  // Some single precision VFP instructions may be executed on both NEON and
2150  // VFP pipelines on A8.
2151  let D = VFPNeonA8Domain;
2152}
2153
2154def VNMLAH : AHbI<0b11100, 0b01, 1, 0,
2155                  (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm),
2156                  IIC_fpMAC16, "vnmla", ".f16\t$Sd, $Sn, $Sm",
2157                  [(set (f16 HPR:$Sd), (fsub_mlx (fneg (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm))),
2158                                           (f16 HPR:$Sdin)))]>,
2159                RegConstraint<"$Sdin = $Sd">,
2160                Requires<[HasFullFP16,UseFPVMLx]>;
2161
2162// (-(a * b) - dst) -> -(dst + (a * b))
2163def : Pat<(fsub_mlx (fneg (fmul_su DPR:$a, (f64 DPR:$b))), DPR:$dstin),
2164          (VNMLAD DPR:$dstin, DPR:$a, DPR:$b)>,
2165          Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>;
2166def : Pat<(fsub_mlx (fneg (fmul_su SPR:$a, SPR:$b)), SPR:$dstin),
2167          (VNMLAS SPR:$dstin, SPR:$a, SPR:$b)>,
2168          Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>;
2169def : Pat<(fsub_mlx (fneg (fmul_su (f16 HPR:$a), HPR:$b)), HPR:$dstin),
2170          (VNMLAH HPR:$dstin, (f16 HPR:$a), HPR:$b)>,
2171          Requires<[HasFullFP16,DontUseNEONForFP,UseFPVMLx]>;
2172
2173// (-dst - (a * b)) -> -(dst + (a * b))
2174def : Pat<(fsub_mlx (fneg DPR:$dstin), (fmul_su DPR:$a, (f64 DPR:$b))),
2175          (VNMLAD DPR:$dstin, DPR:$a, DPR:$b)>,
2176          Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>;
2177def : Pat<(fsub_mlx (fneg SPR:$dstin), (fmul_su SPR:$a, SPR:$b)),
2178          (VNMLAS SPR:$dstin, SPR:$a, SPR:$b)>,
2179          Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>;
2180def : Pat<(fsub_mlx (fneg HPR:$dstin), (fmul_su (f16 HPR:$a), HPR:$b)),
2181          (VNMLAH HPR:$dstin, (f16 HPR:$a), HPR:$b)>,
2182          Requires<[HasFullFP16,DontUseNEONForFP,UseFPVMLx]>;
2183
2184def VNMLSD : ADbI<0b11100, 0b01, 0, 0,
2185                  (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
2186                  IIC_fpMAC64, "vnmls", ".f64\t$Dd, $Dn, $Dm",
2187                  [(set DPR:$Dd, (fsub_mlx (fmul_su DPR:$Dn, DPR:$Dm),
2188                                           (f64 DPR:$Ddin)))]>,
2189               RegConstraint<"$Ddin = $Dd">,
2190               Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>,
2191               Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
2192
2193def VNMLSS : ASbI<0b11100, 0b01, 0, 0,
2194                  (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
2195                  IIC_fpMAC32, "vnmls", ".f32\t$Sd, $Sn, $Sm",
2196             [(set SPR:$Sd, (fsub_mlx (fmul_su SPR:$Sn, SPR:$Sm), SPR:$Sdin))]>,
2197                         RegConstraint<"$Sdin = $Sd">,
2198                Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>,
2199             Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> {
2200  // Some single precision VFP instructions may be executed on both NEON and
2201  // VFP pipelines on A8.
2202  let D = VFPNeonA8Domain;
2203}
2204
2205def VNMLSH : AHbI<0b11100, 0b01, 0, 0,
2206                  (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm),
2207                  IIC_fpMAC16, "vnmls", ".f16\t$Sd, $Sn, $Sm",
2208             [(set (f16 HPR:$Sd), (fsub_mlx (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm)), (f16 HPR:$Sdin)))]>,
2209                         RegConstraint<"$Sdin = $Sd">,
2210                Requires<[HasFullFP16,UseFPVMLx]>;
2211
2212def : Pat<(fsub_mlx (fmul_su DPR:$a, (f64 DPR:$b)), DPR:$dstin),
2213          (VNMLSD DPR:$dstin, DPR:$a, DPR:$b)>,
2214          Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>;
2215def : Pat<(fsub_mlx (fmul_su SPR:$a, SPR:$b), SPR:$dstin),
2216          (VNMLSS SPR:$dstin, SPR:$a, SPR:$b)>,
2217          Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>;
2218def : Pat<(fsub_mlx (fmul_su (f16 HPR:$a), HPR:$b), HPR:$dstin),
2219          (VNMLSH HPR:$dstin, (f16 HPR:$a), HPR:$b)>,
2220          Requires<[HasFullFP16,DontUseNEONForFP,UseFPVMLx]>;
2221
2222//===----------------------------------------------------------------------===//
2223// Fused FP Multiply-Accumulate Operations.
2224//
2225def VFMAD : ADbI<0b11101, 0b10, 0, 0,
2226                 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
2227                 IIC_fpFMAC64, "vfma", ".f64\t$Dd, $Dn, $Dm",
2228                 [(set DPR:$Dd, (fadd_mlx (fmul_su DPR:$Dn, DPR:$Dm),
2229                                          (f64 DPR:$Ddin)))]>,
2230              RegConstraint<"$Ddin = $Dd">,
2231              Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>,
2232            Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
2233
2234def VFMAS : ASbIn<0b11101, 0b10, 0, 0,
2235                  (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
2236                  IIC_fpFMAC32, "vfma", ".f32\t$Sd, $Sn, $Sm",
2237                  [(set SPR:$Sd, (fadd_mlx (fmul_su SPR:$Sn, SPR:$Sm),
2238                                           SPR:$Sdin))]>,
2239              RegConstraint<"$Sdin = $Sd">,
2240              Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>,
2241            Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> {
2242  // Some single precision VFP instructions may be executed on both NEON and
2243  // VFP pipelines.
2244}
2245
2246def VFMAH : AHbI<0b11101, 0b10, 0, 0,
2247                  (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm),
2248                  IIC_fpFMAC16, "vfma", ".f16\t$Sd, $Sn, $Sm",
2249                  [(set (f16 HPR:$Sd), (fadd_mlx (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm)),
2250                                           (f16 HPR:$Sdin)))]>,
2251              RegConstraint<"$Sdin = $Sd">,
2252              Requires<[HasFullFP16,UseFusedMAC]>,
2253            Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
2254
2255def : Pat<(fadd_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))),
2256          (VFMAD DPR:$dstin, DPR:$a, DPR:$b)>,
2257          Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>;
2258def : Pat<(fadd_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)),
2259          (VFMAS SPR:$dstin, SPR:$a, SPR:$b)>,
2260          Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>;
2261def : Pat<(fadd_mlx HPR:$dstin, (fmul_su (f16 HPR:$a), HPR:$b)),
2262          (VFMAH HPR:$dstin, (f16 HPR:$a), HPR:$b)>,
2263          Requires<[HasFullFP16,DontUseNEONForFP,UseFusedMAC]>;
2264
2265// Match @llvm.fma.* intrinsics
2266// (fma x, y, z) -> (vfms z, x, y)
2267def : Pat<(f64 (fma DPR:$Dn, DPR:$Dm, DPR:$Ddin)),
2268          (VFMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>,
2269      Requires<[HasVFP4,HasDPVFP]>;
2270def : Pat<(f32 (fma SPR:$Sn, SPR:$Sm, SPR:$Sdin)),
2271          (VFMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>,
2272      Requires<[HasVFP4]>;
2273def : Pat<(f16 (fma HPR:$Sn, HPR:$Sm, (f16 HPR:$Sdin))),
2274          (VFMAH (f16 HPR:$Sdin), (f16 HPR:$Sn), (f16 HPR:$Sm))>,
2275      Requires<[HasFullFP16]>;
2276
2277def VFMSD : ADbI<0b11101, 0b10, 1, 0,
2278                 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
2279                 IIC_fpFMAC64, "vfms", ".f64\t$Dd, $Dn, $Dm",
2280                 [(set DPR:$Dd, (fadd_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)),
2281                                          (f64 DPR:$Ddin)))]>,
2282              RegConstraint<"$Ddin = $Dd">,
2283              Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>,
2284              Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
2285
2286def VFMSS : ASbIn<0b11101, 0b10, 1, 0,
2287                  (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
2288                  IIC_fpFMAC32, "vfms", ".f32\t$Sd, $Sn, $Sm",
2289                  [(set SPR:$Sd, (fadd_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)),
2290                                           SPR:$Sdin))]>,
2291              RegConstraint<"$Sdin = $Sd">,
2292              Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>,
2293              Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> {
2294  // Some single precision VFP instructions may be executed on both NEON and
2295  // VFP pipelines.
2296}
2297
2298def VFMSH : AHbI<0b11101, 0b10, 1, 0,
2299                  (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm),
2300                  IIC_fpFMAC16, "vfms", ".f16\t$Sd, $Sn, $Sm",
2301                  [(set (f16 HPR:$Sd), (fadd_mlx (fneg (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm))),
2302                                           (f16 HPR:$Sdin)))]>,
2303              RegConstraint<"$Sdin = $Sd">,
2304              Requires<[HasFullFP16,UseFusedMAC]>,
2305              Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
2306
2307def : Pat<(fsub_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))),
2308          (VFMSD DPR:$dstin, DPR:$a, DPR:$b)>,
2309          Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>;
2310def : Pat<(fsub_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)),
2311          (VFMSS SPR:$dstin, SPR:$a, SPR:$b)>,
2312          Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>;
2313def : Pat<(fsub_mlx HPR:$dstin, (fmul_su (f16 HPR:$a), HPR:$b)),
2314          (VFMSH HPR:$dstin, (f16 HPR:$a), HPR:$b)>,
2315          Requires<[HasFullFP16,DontUseNEONForFP,UseFusedMAC]>;
2316
2317// Match @llvm.fma.* intrinsics
2318// (fma (fneg x), y, z) -> (vfms z, x, y)
2319def : Pat<(f64 (fma (fneg DPR:$Dn), DPR:$Dm, DPR:$Ddin)),
2320          (VFMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>,
2321      Requires<[HasVFP4,HasDPVFP]>;
2322def : Pat<(f32 (fma (fneg SPR:$Sn), SPR:$Sm, SPR:$Sdin)),
2323          (VFMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>,
2324      Requires<[HasVFP4]>;
2325def : Pat<(f16 (fma (fneg (f16 HPR:$Sn)), (f16 HPR:$Sm), (f16 HPR:$Sdin))),
2326          (VFMSH (f16 HPR:$Sdin), (f16 HPR:$Sn), (f16 HPR:$Sm))>,
2327      Requires<[HasFullFP16]>;
2328
2329def VFNMAD : ADbI<0b11101, 0b01, 1, 0,
2330                  (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
2331                  IIC_fpFMAC64, "vfnma", ".f64\t$Dd, $Dn, $Dm",
2332                  [(set DPR:$Dd,(fsub_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)),
2333                                          (f64 DPR:$Ddin)))]>,
2334                RegConstraint<"$Ddin = $Dd">,
2335                Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>,
2336                Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
2337
2338def VFNMAS : ASbI<0b11101, 0b01, 1, 0,
2339                  (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
2340                  IIC_fpFMAC32, "vfnma", ".f32\t$Sd, $Sn, $Sm",
2341                  [(set SPR:$Sd, (fsub_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)),
2342                                           SPR:$Sdin))]>,
2343                RegConstraint<"$Sdin = $Sd">,
2344                Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>,
2345                Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> {
2346  // Some single precision VFP instructions may be executed on both NEON and
2347  // VFP pipelines.
2348}
2349
2350def VFNMAH : AHbI<0b11101, 0b01, 1, 0,
2351                  (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm),
2352                  IIC_fpFMAC16, "vfnma", ".f16\t$Sd, $Sn, $Sm",
2353                  [(set (f16 HPR:$Sd), (fsub_mlx (fneg (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm))),
2354                                           (f16 HPR:$Sdin)))]>,
2355                RegConstraint<"$Sdin = $Sd">,
2356                Requires<[HasFullFP16,UseFusedMAC]>,
2357                Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
2358
2359def : Pat<(fsub_mlx (fneg (fmul_su DPR:$a, (f64 DPR:$b))), DPR:$dstin),
2360          (VFNMAD DPR:$dstin, DPR:$a, DPR:$b)>,
2361          Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>;
2362def : Pat<(fsub_mlx (fneg (fmul_su SPR:$a, SPR:$b)), SPR:$dstin),
2363          (VFNMAS SPR:$dstin, SPR:$a, SPR:$b)>,
2364          Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>;
2365
2366// Match @llvm.fma.* intrinsics
2367// (fneg (fma x, y, z)) -> (vfnma z, x, y)
2368def : Pat<(fneg (fma (f64 DPR:$Dn), (f64 DPR:$Dm), (f64 DPR:$Ddin))),
2369          (VFNMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>,
2370      Requires<[HasVFP4,HasDPVFP]>;
2371def : Pat<(fneg (fma (f32 SPR:$Sn), (f32 SPR:$Sm), (f32 SPR:$Sdin))),
2372          (VFNMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>,
2373      Requires<[HasVFP4]>;
2374def : Pat<(fneg (fma (f16 HPR:$Sn), (f16 HPR:$Sm), (f16 (f16 HPR:$Sdin)))),
2375          (VFNMAH (f16 HPR:$Sdin), (f16 HPR:$Sn), (f16 HPR:$Sm))>,
2376      Requires<[HasFullFP16]>;
2377// (fma (fneg x), y, (fneg z)) -> (vfnma z, x, y)
2378def : Pat<(f64 (fma (fneg DPR:$Dn), DPR:$Dm, (fneg DPR:$Ddin))),
2379          (VFNMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>,
2380      Requires<[HasVFP4,HasDPVFP]>;
2381def : Pat<(f32 (fma (fneg SPR:$Sn), SPR:$Sm, (fneg SPR:$Sdin))),
2382          (VFNMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>,
2383      Requires<[HasVFP4]>;
2384def : Pat<(f16 (fma (fneg (f16 HPR:$Sn)), (f16 HPR:$Sm), (fneg (f16 HPR:$Sdin)))),
2385          (VFNMAH (f16 HPR:$Sdin), (f16 HPR:$Sn), (f16 HPR:$Sm))>,
2386      Requires<[HasFullFP16]>;
2387
2388def VFNMSD : ADbI<0b11101, 0b01, 0, 0,
2389                  (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
2390                  IIC_fpFMAC64, "vfnms", ".f64\t$Dd, $Dn, $Dm",
2391                  [(set DPR:$Dd, (fsub_mlx (fmul_su DPR:$Dn, DPR:$Dm),
2392                                           (f64 DPR:$Ddin)))]>,
2393               RegConstraint<"$Ddin = $Dd">,
2394               Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>,
2395               Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
2396
2397def VFNMSS : ASbI<0b11101, 0b01, 0, 0,
2398                  (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
2399                  IIC_fpFMAC32, "vfnms", ".f32\t$Sd, $Sn, $Sm",
2400             [(set SPR:$Sd, (fsub_mlx (fmul_su SPR:$Sn, SPR:$Sm), SPR:$Sdin))]>,
2401                         RegConstraint<"$Sdin = $Sd">,
2402                  Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>,
2403                  Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> {
2404  // Some single precision VFP instructions may be executed on both NEON and
2405  // VFP pipelines.
2406}
2407
2408def VFNMSH : AHbI<0b11101, 0b01, 0, 0,
2409                  (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm),
2410                  IIC_fpFMAC16, "vfnms", ".f16\t$Sd, $Sn, $Sm",
2411             [(set (f16 HPR:$Sd), (fsub_mlx (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm)), (f16 HPR:$Sdin)))]>,
2412                         RegConstraint<"$Sdin = $Sd">,
2413                  Requires<[HasFullFP16,UseFusedMAC]>,
2414                  Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
2415
2416def : Pat<(fsub_mlx (fmul_su DPR:$a, (f64 DPR:$b)), DPR:$dstin),
2417          (VFNMSD DPR:$dstin, DPR:$a, DPR:$b)>,
2418          Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>;
2419def : Pat<(fsub_mlx (fmul_su SPR:$a, SPR:$b), SPR:$dstin),
2420          (VFNMSS SPR:$dstin, SPR:$a, SPR:$b)>,
2421          Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>;
2422
2423// Match @llvm.fma.* intrinsics
2424
2425// (fma x, y, (fneg z)) -> (vfnms z, x, y))
2426def : Pat<(f64 (fma DPR:$Dn, DPR:$Dm, (fneg DPR:$Ddin))),
2427          (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>,
2428      Requires<[HasVFP4,HasDPVFP]>;
2429def : Pat<(f32 (fma SPR:$Sn, SPR:$Sm, (fneg SPR:$Sdin))),
2430          (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>,
2431      Requires<[HasVFP4]>;
2432def : Pat<(f16 (fma (f16 HPR:$Sn), (f16 HPR:$Sm), (fneg (f16 HPR:$Sdin)))),
2433          (VFNMSH (f16 HPR:$Sdin), (f16 HPR:$Sn), (f16 HPR:$Sm))>,
2434      Requires<[HasFullFP16]>;
2435// (fneg (fma (fneg x), y, z)) -> (vfnms z, x, y)
2436def : Pat<(fneg (f64 (fma (fneg DPR:$Dn), DPR:$Dm, DPR:$Ddin))),
2437          (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>,
2438      Requires<[HasVFP4,HasDPVFP]>;
2439def : Pat<(fneg (f32 (fma (fneg SPR:$Sn), SPR:$Sm, SPR:$Sdin))),
2440          (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>,
2441      Requires<[HasVFP4]>;
2442def : Pat<(fneg (f16 (fma (fneg (f16 HPR:$Sn)), (f16 HPR:$Sm), (f16 HPR:$Sdin)))),
2443          (VFNMSH (f16 HPR:$Sdin), (f16 HPR:$Sn), (f16 HPR:$Sm))>,
2444      Requires<[HasFullFP16]>;
2445
2446//===----------------------------------------------------------------------===//
2447// FP Conditional moves.
2448//
2449
2450let hasSideEffects = 0 in {
2451def VMOVDcc  : PseudoInst<(outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm, cmovpred:$p),
2452                    IIC_fpUNA64,
2453                    [(set (f64 DPR:$Dd),
2454                          (ARMcmov DPR:$Dn, DPR:$Dm, cmovpred:$p))]>,
2455               RegConstraint<"$Dn = $Dd">, Requires<[HasFPRegs64]>;
2456
2457def VMOVScc  : PseudoInst<(outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm, cmovpred:$p),
2458                    IIC_fpUNA32,
2459                    [(set (f32 SPR:$Sd),
2460                          (ARMcmov SPR:$Sn, SPR:$Sm, cmovpred:$p))]>,
2461               RegConstraint<"$Sn = $Sd">, Requires<[HasFPRegs]>;
2462
2463def VMOVHcc  : PseudoInst<(outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm, cmovpred:$p),
2464                    IIC_fpUNA16,
2465                    [(set (f16 HPR:$Sd),
2466                          (ARMcmov (f16 HPR:$Sn), (f16 HPR:$Sm), cmovpred:$p))]>,
2467               RegConstraint<"$Sd = $Sn">, Requires<[HasFPRegs]>;
2468} // hasSideEffects
2469
2470//===----------------------------------------------------------------------===//
2471// Move from VFP System Register to ARM core register.
2472//
2473
2474class MovFromVFP<bits<4> opc19_16, dag oops, dag iops, string opc, string asm,
2475                 list<dag> pattern>:
2476  VFPAI<oops, iops, VFPMiscFrm, IIC_fpSTAT, opc, asm, "", pattern> {
2477
2478  // Instruction operand.
2479  bits<4> Rt;
2480
2481  let Inst{27-20} = 0b11101111;
2482  let Inst{19-16} = opc19_16;
2483  let Inst{15-12} = Rt;
2484  let Inst{11-8}  = 0b1010;
2485  let Inst{7}     = 0;
2486  let Inst{6-5}   = 0b00;
2487  let Inst{4}     = 1;
2488  let Inst{3-0}   = 0b0000;
2489  let Unpredictable{7-5} = 0b111;
2490  let Unpredictable{3-0} = 0b1111;
2491}
2492
2493let DecoderMethod = "DecodeForVMRSandVMSR" in {
2494 // APSR is the application level alias of CPSR. This FPSCR N, Z, C, V flags
2495 // to APSR.
2496 let Defs = [CPSR], Uses = [FPSCR_NZCV], Predicates = [HasFPRegs],
2497     Rt = 0b1111 /* apsr_nzcv */ in
2498 def FMSTAT : MovFromVFP<0b0001 /* fpscr */, (outs), (ins),
2499                         "vmrs", "\tAPSR_nzcv, fpscr", [(arm_fmstat)]>;
2500
2501 // Application level FPSCR -> GPR
2502 let hasSideEffects = 1, Uses = [FPSCR], Predicates = [HasFPRegs] in
2503 def VMRS :  MovFromVFP<0b0001 /* fpscr */, (outs GPRnopc:$Rt), (ins),
2504                        "vmrs", "\t$Rt, fpscr",
2505                        [(set GPRnopc:$Rt, (int_arm_get_fpscr))]>;
2506
2507 // System level FPEXC, FPSID -> GPR
2508 let Uses = [FPSCR] in {
2509   def VMRS_FPEXC : MovFromVFP<0b1000 /* fpexc */, (outs GPRnopc:$Rt), (ins),
2510                               "vmrs", "\t$Rt, fpexc", []>;
2511   def VMRS_FPSID : MovFromVFP<0b0000 /* fpsid */, (outs GPRnopc:$Rt), (ins),
2512                               "vmrs", "\t$Rt, fpsid", []>;
2513   def VMRS_MVFR0 : MovFromVFP<0b0111 /* mvfr0 */, (outs GPRnopc:$Rt), (ins),
2514                              "vmrs", "\t$Rt, mvfr0", []>;
2515   def VMRS_MVFR1 : MovFromVFP<0b0110 /* mvfr1 */, (outs GPRnopc:$Rt), (ins),
2516                               "vmrs", "\t$Rt, mvfr1", []>;
2517   let Predicates = [HasFPARMv8] in {
2518     def VMRS_MVFR2 : MovFromVFP<0b0101 /* mvfr2 */, (outs GPRnopc:$Rt), (ins),
2519                                 "vmrs", "\t$Rt, mvfr2", []>;
2520   }
2521   def VMRS_FPINST : MovFromVFP<0b1001 /* fpinst */, (outs GPRnopc:$Rt), (ins),
2522                                "vmrs", "\t$Rt, fpinst", []>;
2523   def VMRS_FPINST2 : MovFromVFP<0b1010 /* fpinst2 */, (outs GPRnopc:$Rt),
2524                                 (ins), "vmrs", "\t$Rt, fpinst2", []>;
2525   let Predicates = [HasV8_1MMainline, HasFPRegs] in {
2526     // System level FPSCR_NZCVQC -> GPR
2527     def VMRS_FPSCR_NZCVQC
2528       : MovFromVFP<0b0010 /* fpscr_nzcvqc */,
2529                    (outs GPR:$Rt), (ins cl_FPSCR_NZCV:$fpscr_in),
2530                    "vmrs", "\t$Rt, fpscr_nzcvqc", []>;
2531   }
2532 }
2533 let Predicates = [HasV8_1MMainline, Has8MSecExt] in {
2534   // System level FPSCR -> GPR, with context saving for security extensions
2535   def VMRS_FPCXTNS : MovFromVFP<0b1110 /* fpcxtns */, (outs GPR:$Rt), (ins),
2536                                 "vmrs", "\t$Rt, fpcxtns", []>;
2537 }
2538 let Predicates = [HasV8_1MMainline, Has8MSecExt] in {
2539   // System level FPSCR -> GPR, with context saving for security extensions
2540   def VMRS_FPCXTS : MovFromVFP<0b1111 /* fpcxts */, (outs GPR:$Rt), (ins),
2541                                "vmrs", "\t$Rt, fpcxts", []>;
2542 }
2543
2544 let Predicates = [HasV8_1MMainline, HasMVEInt] in {
2545   // System level VPR/P0 -> GPR
2546   let Uses = [VPR] in
2547   def VMRS_VPR : MovFromVFP<0b1100 /* vpr */, (outs GPR:$Rt), (ins),
2548                             "vmrs", "\t$Rt, vpr", []>;
2549
2550   def VMRS_P0  : MovFromVFP<0b1101 /* p0 */, (outs GPR:$Rt), (ins VCCR:$cond),
2551                             "vmrs", "\t$Rt, p0", []>;
2552 }
2553}
2554
2555//===----------------------------------------------------------------------===//
2556// Move from ARM core register to VFP System Register.
2557//
2558
2559class MovToVFP<bits<4> opc19_16, dag oops, dag iops, string opc, string asm,
2560               list<dag> pattern>:
2561  VFPAI<oops, iops, VFPMiscFrm, IIC_fpSTAT, opc, asm, "", pattern> {
2562
2563  // Instruction operand.
2564  bits<4> Rt;
2565
2566  let Inst{27-20} = 0b11101110;
2567  let Inst{19-16} = opc19_16;
2568  let Inst{15-12} = Rt;
2569  let Inst{11-8}  = 0b1010;
2570  let Inst{7}     = 0;
2571  let Inst{6-5}   = 0b00;
2572  let Inst{4}     = 1;
2573  let Inst{3-0}   = 0b0000;
2574  let Predicates = [HasVFP2];
2575  let Unpredictable{7-5} = 0b111;
2576  let Unpredictable{3-0} = 0b1111;
2577}
2578
2579let DecoderMethod = "DecodeForVMRSandVMSR" in {
2580 let Defs = [FPSCR] in {
2581   let Predicates = [HasFPRegs] in
2582   // Application level GPR -> FPSCR
2583   def VMSR : MovToVFP<0b0001 /* fpscr */, (outs), (ins GPRnopc:$Rt),
2584                       "vmsr", "\tfpscr, $Rt",
2585                       [(int_arm_set_fpscr GPRnopc:$Rt)]>;
2586   // System level GPR -> FPEXC
2587   def VMSR_FPEXC : MovToVFP<0b1000 /* fpexc */, (outs), (ins GPRnopc:$Rt),
2588                               "vmsr", "\tfpexc, $Rt", []>;
2589   // System level GPR -> FPSID
2590   def VMSR_FPSID : MovToVFP<0b0000 /* fpsid */, (outs), (ins GPRnopc:$Rt),
2591                             "vmsr", "\tfpsid, $Rt", []>;
2592   def VMSR_FPINST : MovToVFP<0b1001 /* fpinst */, (outs), (ins GPRnopc:$Rt),
2593                              "vmsr", "\tfpinst, $Rt", []>;
2594   def VMSR_FPINST2 : MovToVFP<0b1010 /* fpinst2 */, (outs), (ins GPRnopc:$Rt),
2595                               "vmsr", "\tfpinst2, $Rt", []>;
2596 }
2597 let Predicates = [HasV8_1MMainline, Has8MSecExt] in {
2598   // System level GPR -> FPSCR with context saving for security extensions
2599   def VMSR_FPCXTNS : MovToVFP<0b1110 /* fpcxtns */, (outs), (ins GPR:$Rt),
2600                               "vmsr", "\tfpcxtns, $Rt", []>;
2601 }
2602 let Predicates = [HasV8_1MMainline, Has8MSecExt] in {
2603   // System level GPR -> FPSCR with context saving for security extensions
2604   def VMSR_FPCXTS : MovToVFP<0b1111 /* fpcxts */, (outs), (ins GPR:$Rt),
2605                              "vmsr", "\tfpcxts, $Rt", []>;
2606 }
2607 let Predicates = [HasV8_1MMainline, HasFPRegs] in {
2608   // System level GPR -> FPSCR_NZCVQC
2609   def VMSR_FPSCR_NZCVQC
2610     : MovToVFP<0b0010 /* fpscr_nzcvqc */,
2611                (outs cl_FPSCR_NZCV:$fpscr_out), (ins GPR:$Rt),
2612                "vmsr", "\tfpscr_nzcvqc, $Rt", []>;
2613 }
2614
2615 let Predicates = [HasV8_1MMainline, HasMVEInt] in {
2616   // System level GPR -> VPR/P0
2617   let Defs = [VPR] in
2618   def VMSR_VPR : MovToVFP<0b1100 /* vpr */, (outs), (ins GPR:$Rt),
2619                           "vmsr", "\tvpr, $Rt", []>;
2620
2621   def VMSR_P0  : MovToVFP<0b1101 /* p0 */, (outs VCCR:$cond), (ins GPR:$Rt),
2622                           "vmsr", "\tp0, $Rt", []>;
2623 }
2624}
2625
2626//===----------------------------------------------------------------------===//
2627// Misc.
2628//
2629
2630// Materialize FP immediates. VFP3 only.
2631let isReMaterializable = 1 in {
2632def FCONSTD : VFPAI<(outs DPR:$Dd), (ins vfp_f64imm:$imm),
2633                    VFPMiscFrm, IIC_fpUNA64,
2634                    "vmov", ".f64\t$Dd, $imm", "",
2635                    [(set DPR:$Dd, vfp_f64imm:$imm)]>,
2636              Requires<[HasVFP3,HasDPVFP]> {
2637  bits<5> Dd;
2638  bits<8> imm;
2639
2640  let Inst{27-23} = 0b11101;
2641  let Inst{22}    = Dd{4};
2642  let Inst{21-20} = 0b11;
2643  let Inst{19-16} = imm{7-4};
2644  let Inst{15-12} = Dd{3-0};
2645  let Inst{11-9}  = 0b101;
2646  let Inst{8}     = 1;          // Double precision.
2647  let Inst{7-4}   = 0b0000;
2648  let Inst{3-0}   = imm{3-0};
2649}
2650
2651def FCONSTS : VFPAI<(outs SPR:$Sd), (ins vfp_f32imm:$imm),
2652                     VFPMiscFrm, IIC_fpUNA32,
2653                     "vmov", ".f32\t$Sd, $imm", "",
2654                     [(set SPR:$Sd, vfp_f32imm:$imm)]>, Requires<[HasVFP3]> {
2655  bits<5> Sd;
2656  bits<8> imm;
2657
2658  let Inst{27-23} = 0b11101;
2659  let Inst{22}    = Sd{0};
2660  let Inst{21-20} = 0b11;
2661  let Inst{19-16} = imm{7-4};
2662  let Inst{15-12} = Sd{4-1};
2663  let Inst{11-9}  = 0b101;
2664  let Inst{8}     = 0;          // Single precision.
2665  let Inst{7-4}   = 0b0000;
2666  let Inst{3-0}   = imm{3-0};
2667}
2668
2669def FCONSTH : VFPAI<(outs HPR:$Sd), (ins vfp_f16imm:$imm),
2670                     VFPMiscFrm, IIC_fpUNA16,
2671                     "vmov", ".f16\t$Sd, $imm", "",
2672                     [(set (f16 HPR:$Sd), vfp_f16imm:$imm)]>,
2673              Requires<[HasFullFP16]> {
2674  bits<5> Sd;
2675  bits<8> imm;
2676
2677  let Inst{27-23} = 0b11101;
2678  let Inst{22}    = Sd{0};
2679  let Inst{21-20} = 0b11;
2680  let Inst{19-16} = imm{7-4};
2681  let Inst{15-12} = Sd{4-1};
2682  let Inst{11-8}  = 0b1001;     // Half precision
2683  let Inst{7-4}   = 0b0000;
2684  let Inst{3-0}   = imm{3-0};
2685
2686  let isUnpredicable = 1;
2687}
2688}
2689
2690def : Pat<(f32 (vfp_f32f16imm:$imm)),
2691          (f32 (COPY_TO_REGCLASS (f16 (FCONSTH (vfp_f32f16imm_xform (f32 $imm)))), SPR))> {
2692  let Predicates = [HasFullFP16];
2693}
2694
2695// Floating-point environment management.
2696def : Pat<(get_fpenv), (VMRS)>;
2697def : Pat<(set_fpenv GPRnopc:$Rt), (VMSR GPRnopc:$Rt)>;
2698def : Pat<(reset_fpenv), (VMSR (MOVi 0))>, Requires<[IsARM]>;
2699def : Pat<(reset_fpenv), (VMSR (tMOVi8 0))>, Requires<[IsThumb]>;
2700def : Pat<(get_fpmode), (VMRS)>;
2701
2702//===----------------------------------------------------------------------===//
2703// Assembler aliases.
2704//
2705// A few mnemonic aliases for pre-unifixed syntax. We don't guarantee to
2706// support them all, but supporting at least some of the basics is
2707// good to be friendly.
2708def : VFP2MnemonicAlias<"flds", "vldr">;
2709def : VFP2MnemonicAlias<"fldd", "vldr">;
2710def : VFP2MnemonicAlias<"fmrs", "vmov">;
2711def : VFP2MnemonicAlias<"fmsr", "vmov">;
2712def : VFP2MnemonicAlias<"fsqrts", "vsqrt">;
2713def : VFP2MnemonicAlias<"fsqrtd", "vsqrt">;
2714def : VFP2MnemonicAlias<"fadds", "vadd.f32">;
2715def : VFP2MnemonicAlias<"faddd", "vadd.f64">;
2716def : VFP2MnemonicAlias<"fmrdd", "vmov">;
2717def : VFP2MnemonicAlias<"fmrds", "vmov">;
2718def : VFP2MnemonicAlias<"fmrrd", "vmov">;
2719def : VFP2MnemonicAlias<"fmdrr", "vmov">;
2720def : VFP2MnemonicAlias<"fmuls", "vmul.f32">;
2721def : VFP2MnemonicAlias<"fmuld", "vmul.f64">;
2722def : VFP2MnemonicAlias<"fnegs", "vneg.f32">;
2723def : VFP2MnemonicAlias<"fnegd", "vneg.f64">;
2724def : VFP2MnemonicAlias<"ftosizd", "vcvt.s32.f64">;
2725def : VFP2MnemonicAlias<"ftosid", "vcvtr.s32.f64">;
2726def : VFP2MnemonicAlias<"ftosizs", "vcvt.s32.f32">;
2727def : VFP2MnemonicAlias<"ftosis", "vcvtr.s32.f32">;
2728def : VFP2MnemonicAlias<"ftouizd", "vcvt.u32.f64">;
2729def : VFP2MnemonicAlias<"ftouid", "vcvtr.u32.f64">;
2730def : VFP2MnemonicAlias<"ftouizs", "vcvt.u32.f32">;
2731def : VFP2MnemonicAlias<"ftouis", "vcvtr.u32.f32">;
2732def : VFP2MnemonicAlias<"fsitod", "vcvt.f64.s32">;
2733def : VFP2MnemonicAlias<"fsitos", "vcvt.f32.s32">;
2734def : VFP2MnemonicAlias<"fuitod", "vcvt.f64.u32">;
2735def : VFP2MnemonicAlias<"fuitos", "vcvt.f32.u32">;
2736def : VFP2MnemonicAlias<"fsts", "vstr">;
2737def : VFP2MnemonicAlias<"fstd", "vstr">;
2738def : VFP2MnemonicAlias<"fmacd", "vmla.f64">;
2739def : VFP2MnemonicAlias<"fmacs", "vmla.f32">;
2740def : VFP2MnemonicAlias<"fcpys", "vmov.f32">;
2741def : VFP2MnemonicAlias<"fcpyd", "vmov.f64">;
2742def : VFP2MnemonicAlias<"fcmps", "vcmp.f32">;
2743def : VFP2MnemonicAlias<"fcmpd", "vcmp.f64">;
2744def : VFP2MnemonicAlias<"fdivs", "vdiv.f32">;
2745def : VFP2MnemonicAlias<"fdivd", "vdiv.f64">;
2746def : VFP2MnemonicAlias<"fmrx", "vmrs">;
2747def : VFP2MnemonicAlias<"fmxr", "vmsr">;
2748
2749// Be friendly and accept the old form of zero-compare
2750def : VFP2DPInstAlias<"fcmpzd${p} $val", (VCMPZD DPR:$val, pred:$p)>;
2751def : VFP2InstAlias<"fcmpzs${p} $val", (VCMPZS SPR:$val, pred:$p)>;
2752
2753
2754def : InstAlias<"fmstat${p}", (FMSTAT pred:$p), 0>, Requires<[HasFPRegs]>;
2755def : VFP2InstAlias<"fadds${p} $Sd, $Sn, $Sm",
2756                    (VADDS SPR:$Sd, SPR:$Sn, SPR:$Sm, pred:$p)>;
2757def : VFP2DPInstAlias<"faddd${p} $Dd, $Dn, $Dm",
2758                      (VADDD DPR:$Dd, DPR:$Dn, DPR:$Dm, pred:$p)>;
2759def : VFP2InstAlias<"fsubs${p} $Sd, $Sn, $Sm",
2760                    (VSUBS SPR:$Sd, SPR:$Sn, SPR:$Sm, pred:$p)>;
2761def : VFP2DPInstAlias<"fsubd${p} $Dd, $Dn, $Dm",
2762                      (VSUBD DPR:$Dd, DPR:$Dn, DPR:$Dm, pred:$p)>;
2763
2764// No need for the size suffix on VSQRT. It's implied by the register classes.
2765def : VFP2InstAlias<"vsqrt${p} $Sd, $Sm", (VSQRTS SPR:$Sd, SPR:$Sm, pred:$p)>;
2766def : VFP2DPInstAlias<"vsqrt${p} $Dd, $Dm", (VSQRTD DPR:$Dd, DPR:$Dm, pred:$p)>;
2767
2768// VLDR/VSTR accept an optional type suffix.
2769def : VFP2InstAlias<"vldr${p}.32 $Sd, $addr",
2770                    (VLDRS SPR:$Sd, addrmode5:$addr, pred:$p)>;
2771def : VFP2InstAlias<"vstr${p}.32 $Sd, $addr",
2772                    (VSTRS SPR:$Sd, addrmode5:$addr, pred:$p)>;
2773def : VFP2InstAlias<"vldr${p}.64 $Dd, $addr",
2774                    (VLDRD DPR:$Dd, addrmode5:$addr, pred:$p)>;
2775def : VFP2InstAlias<"vstr${p}.64 $Dd, $addr",
2776                    (VSTRD DPR:$Dd, addrmode5:$addr, pred:$p)>;
2777
2778// VMOV can accept optional 32-bit or less data type suffix suffix.
2779def : VFP2InstAlias<"vmov${p}.8 $Rt, $Sn",
2780                    (VMOVRS GPR:$Rt, SPR:$Sn, pred:$p)>;
2781def : VFP2InstAlias<"vmov${p}.16 $Rt, $Sn",
2782                    (VMOVRS GPR:$Rt, SPR:$Sn, pred:$p)>;
2783def : VFP2InstAlias<"vmov${p}.32 $Rt, $Sn",
2784                    (VMOVRS GPR:$Rt, SPR:$Sn, pred:$p)>;
2785def : VFP2InstAlias<"vmov${p}.8 $Sn, $Rt",
2786                    (VMOVSR SPR:$Sn, GPR:$Rt, pred:$p)>;
2787def : VFP2InstAlias<"vmov${p}.16 $Sn, $Rt",
2788                    (VMOVSR SPR:$Sn, GPR:$Rt, pred:$p)>;
2789def : VFP2InstAlias<"vmov${p}.32 $Sn, $Rt",
2790                    (VMOVSR SPR:$Sn, GPR:$Rt, pred:$p)>;
2791
2792def : VFP2InstAlias<"vmov${p}.f64 $Rt, $Rt2, $Dn",
2793                    (VMOVRRD GPR:$Rt, GPR:$Rt2, DPR:$Dn, pred:$p)>;
2794def : VFP2InstAlias<"vmov${p}.f64 $Dn, $Rt, $Rt2",
2795                    (VMOVDRR DPR:$Dn, GPR:$Rt, GPR:$Rt2, pred:$p)>;
2796
2797// VMOVS doesn't need the .f32 to disambiguate from the NEON encoding the way
2798// VMOVD does.
2799def : VFP2InstAlias<"vmov${p} $Sd, $Sm",
2800                    (VMOVS SPR:$Sd, SPR:$Sm, pred:$p)>;
2801
2802// FCONSTD/FCONSTS alias for vmov.f64/vmov.f32
2803// These aliases provide added functionality over vmov.f instructions by
2804// allowing users to write assembly containing encoded floating point constants
2805// (e.g. #0x70 vs #1.0).  Without these alises there is no way for the
2806// assembler to accept encoded fp constants (but the equivalent fp-literal is
2807// accepted directly by vmovf).
2808def : VFP3InstAlias<"fconstd${p} $Dd, $val",
2809                    (FCONSTD DPR:$Dd, vfp_f64imm:$val, pred:$p)>;
2810def : VFP3InstAlias<"fconsts${p} $Sd, $val",
2811                    (FCONSTS SPR:$Sd, vfp_f32imm:$val, pred:$p)>;
2812
2813def VSCCLRMD : VFPXI<(outs), (ins pred:$p, fp_dreglist_with_vpr:$regs, variable_ops),
2814                      AddrModeNone, 4, IndexModeNone, VFPMiscFrm, NoItinerary,
2815                      "vscclrm{$p}\t$regs", "", []>, Sched<[]> {
2816  bits<13> regs;
2817  let Inst{31-23} = 0b111011001;
2818  let Inst{22} = regs{12};
2819  let Inst{21-16} = 0b011111;
2820  let Inst{15-12} = regs{11-8};
2821  let Inst{11-8} = 0b1011;
2822  let Inst{7-1} = regs{7-1};
2823  let Inst{0} = 0;
2824
2825  let DecoderMethod = "DecodeVSCCLRM";
2826
2827  list<Predicate> Predicates = [HasV8_1MMainline, Has8MSecExt];
2828}
2829
2830def VSCCLRMS : VFPXI<(outs), (ins pred:$p, fp_sreglist_with_vpr:$regs, variable_ops),
2831                      AddrModeNone, 4, IndexModeNone, VFPMiscFrm, NoItinerary,
2832                      "vscclrm{$p}\t$regs", "", []>, Sched<[]> {
2833  bits<13> regs;
2834  let Inst{31-23} = 0b111011001;
2835  let Inst{22} = regs{8};
2836  let Inst{21-16} = 0b011111;
2837  let Inst{15-12} = regs{12-9};
2838  let Inst{11-8} = 0b1010;
2839  let Inst{7-0} = regs{7-0};
2840
2841  let DecoderMethod = "DecodeVSCCLRM";
2842
2843  list<Predicate> Predicates = [HasV8_1MMainline, Has8MSecExt];
2844}
2845
2846//===----------------------------------------------------------------------===//
2847// Store VFP System Register to memory.
2848//
2849
2850class vfp_vstrldr<bit opc, bit P, bit W, bits<4> SysReg, string sysreg,
2851                  dag oops, dag iops, IndexMode im, string Dest, string cstr>
2852    : VFPI<oops, iops, AddrModeT2_i7s4, 4, im, VFPLdStFrm, IIC_fpSTAT,
2853           !if(opc,"vldr","vstr"), !strconcat("\t", sysreg, ", ", Dest), cstr, []>,
2854      Sched<[]> {
2855  bits<12> addr;
2856  let Inst{27-25} = 0b110;
2857  let Inst{24} = P;
2858  let Inst{23} = addr{7};
2859  let Inst{22} = SysReg{3};
2860  let Inst{21} = W;
2861  let Inst{20} = opc;
2862  let Inst{19-16} = addr{11-8};
2863  let Inst{15-13} = SysReg{2-0};
2864  let Inst{12-7} = 0b011111;
2865  let Inst{6-0} = addr{6-0};
2866  list<Predicate> Predicates = [HasFPRegs, HasV8_1MMainline];
2867  let mayLoad = opc;
2868  let mayStore = !if(opc, 0b0, 0b1);
2869  let hasSideEffects = 1;
2870}
2871
2872multiclass vfp_vstrldr_sysreg<bit opc, bits<4> SysReg, string sysreg,
2873                              dag oops=(outs), dag iops=(ins)> {
2874  def _off :
2875    vfp_vstrldr<opc, 1, 0, SysReg, sysreg,
2876                oops, !con(iops, (ins t2addrmode_imm7s4:$addr)),
2877                IndexModePost, "$addr", "" > {
2878    let DecoderMethod = "DecodeVSTRVLDR_SYSREG<false>";
2879  }
2880
2881  def _pre :
2882    vfp_vstrldr<opc, 1, 1, SysReg, sysreg,
2883                !con(oops, (outs GPRnopc:$wb)),
2884                !con(iops, (ins t2addrmode_imm7s4_pre:$addr)),
2885                IndexModePre, "$addr!", "$addr.base = $wb"> {
2886    let DecoderMethod = "DecodeVSTRVLDR_SYSREG<true>";
2887  }
2888
2889  def _post :
2890    vfp_vstrldr<opc, 0, 1, SysReg, sysreg,
2891                !con(oops, (outs GPRnopc:$wb)),
2892                !con(iops, (ins t2_addr_offset_none:$Rn,
2893                                t2am_imm7s4_offset:$addr)),
2894                IndexModePost, "$Rn$addr", "$Rn.base = $wb"> {
2895   bits<4> Rn;
2896   let Inst{19-16} = Rn{3-0};
2897   let DecoderMethod = "DecodeVSTRVLDR_SYSREG<true>";
2898 }
2899}
2900
2901let Defs = [FPSCR] in {
2902  defm VSTR_FPSCR          : vfp_vstrldr_sysreg<0b0,0b0001, "fpscr">;
2903  defm VSTR_FPSCR_NZCVQC   : vfp_vstrldr_sysreg<0b0,0b0010, "fpscr_nzcvqc">;
2904
2905  let Predicates = [HasV8_1MMainline, Has8MSecExt] in {
2906    defm VSTR_FPCXTNS      : vfp_vstrldr_sysreg<0b0,0b1110, "fpcxtns">;
2907    defm VSTR_FPCXTS       : vfp_vstrldr_sysreg<0b0,0b1111, "fpcxts">;
2908  }
2909}
2910
2911let Predicates = [HasV8_1MMainline, HasMVEInt] in {
2912  let Uses = [VPR] in {
2913    defm VSTR_VPR          : vfp_vstrldr_sysreg<0b0,0b1100, "vpr">;
2914  }
2915  defm VSTR_P0             : vfp_vstrldr_sysreg<0b0,0b1101, "p0",
2916                                                (outs), (ins VCCR:$P0)>;
2917
2918  let Defs = [VPR] in {
2919    defm VLDR_VPR          : vfp_vstrldr_sysreg<0b1,0b1100, "vpr">;
2920  }
2921  defm VLDR_P0             : vfp_vstrldr_sysreg<0b1,0b1101, "p0",
2922                                                (outs VCCR:$P0), (ins)>;
2923}
2924
2925let Uses = [FPSCR] in {
2926  defm VLDR_FPSCR          : vfp_vstrldr_sysreg<0b1,0b0001, "fpscr">;
2927  defm VLDR_FPSCR_NZCVQC   : vfp_vstrldr_sysreg<0b1,0b0010, "fpscr_nzcvqc">;
2928
2929  let Predicates = [HasV8_1MMainline, Has8MSecExt] in {
2930    defm VLDR_FPCXTNS      : vfp_vstrldr_sysreg<0b1,0b1110, "fpcxtns">;
2931    defm VLDR_FPCXTS       : vfp_vstrldr_sysreg<0b1,0b1111, "fpcxts">;
2932  }
2933}
2934