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