1 //===-- ARMInstrVFP.td - VFP support for ARM ---------------*- tablegen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file describes the ARM VFP instruction set.
12 //===----------------------------------------------------------------------===//
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>,
17 def SDT_VMOVRRD : SDTypeProfile<2, 1, [SDTCisVT<0, i32>, SDTCisSameAs<0, 1>,
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>;
26 //===----------------------------------------------------------------------===//
27 // Operand Definitions.
30 // 8-bit floating-point immediate encodings.
31 def FPImmOperand : AsmOperandClass {
33 let ParserMethod = "parseFPImm";
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);
44 let PrintMethod = "printFPImmOperand";
45 let ParserMatchClass = FPImmOperand;
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);
56 let PrintMethod = "printFPImmOperand";
57 let ParserMatchClass = FPImmOperand;
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);
68 let PrintMethod = "printFPImmOperand";
69 let ParserMatchClass = FPImmOperand;
72 def alignedload32 : PatFrag<(ops node:$ptr), (load node:$ptr), [{
73 return cast<LoadSDNode>(N)->getAlignment() >= 4;
76 def alignedstore32 : PatFrag<(ops node:$val, node:$ptr),
77 (store node:$val, node:$ptr), [{
78 return cast<StoreSDNode>(N)->getAlignment() >= 4;
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;
92 def fbits16_asm_operand : AsmOperandClass { let Name = "FBits16"; }
93 def fbits16 : Operand<i32> {
94 let PrintMethod = "printFBits16";
95 let ParserMatchClass = fbits16_asm_operand;
98 //===----------------------------------------------------------------------===//
99 // Load / store Instructions.
102 let canFoldAsLoad = 1, isReMaterializable = 1 in {
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)))]>;
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
113 let D = VFPNeonDomain;
116 def VLDRH : AHI5<0b1101, 0b01, (outs SPR:$Sd), (ins addrmode5fp16:$addr),
117 IIC_fpLoad16, "vldr", ".16\t$Sd, $addr",
119 Requires<[HasFullFP16]>;
121 } // End of 'let canFoldAsLoad = 1, isReMaterializable = 1 in'
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)]>;
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
132 let D = VFPNeonDomain;
135 def VSTRH : AHI5<0b1101, 0b00, (outs), (ins SPR:$Sd, addrmode5fp16:$addr),
136 IIC_fpStore16, "vstr", ".16\t$Sd, $addr",
138 Requires<[HasFullFP16]>;
140 //===----------------------------------------------------------------------===//
141 // Load / store multiple Instructions.
144 multiclass vfp_ldst_mult<string asm, bit L_bit,
145 InstrItinClass itin, InstrItinClass itin_upd> {
148 AXDI4<(outs), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops),
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;
156 AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs,
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;
165 AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs,
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;
176 AXSI4<(outs), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops),
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;
183 // Some single precision VFP instructions may be executed on both NEON and
185 let D = VFPNeonDomain;
188 AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs,
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;
196 // Some single precision VFP instructions may be executed on both NEON and
198 let D = VFPNeonDomain;
201 AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs,
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;
209 // Some single precision VFP instructions may be executed on both NEON and
211 let D = VFPNeonDomain;
215 let hasSideEffects = 0 in {
217 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
218 defm VLDM : vfp_ldst_mult<"vldm", 1, IIC_fpLoad_m, IIC_fpLoad_mu>;
220 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
221 defm VSTM : vfp_ldst_mult<"vstm", 0, IIC_fpStore_m, IIC_fpStore_mu>;
225 def : MnemonicAlias<"vldm", "vldmia">;
226 def : MnemonicAlias<"vstm", "vstmia">;
229 //===----------------------------------------------------------------------===//
230 // Lazy load / store multiple Instructions
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;
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;
258 def : InstAlias<"vpush${p} $r", (VSTMDDB_UPD SP, pred:$p, dpr_reglist:$r), 0>,
260 def : InstAlias<"vpush${p} $r", (VSTMSDB_UPD SP, pred:$p, spr_reglist:$r), 0>,
262 def : InstAlias<"vpop${p} $r", (VLDMDIA_UPD SP, pred:$p, dpr_reglist:$r), 0>,
264 def : InstAlias<"vpop${p} $r", (VLDMSIA_UPD SP, pred:$p, spr_reglist:$r), 0>,
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)>;
275 // FLDMX, FSTMX - Load and store multiple unknown precision registers for
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> {
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;
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;
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;
305 defm FLDM : vfp_ldstx_mult<"fldm", 1>;
306 defm FSTM : vfp_ldstx_mult<"fstm", 0>;
308 def : VFP2MnemonicAlias<"fldmeax", "fldmdbx">;
309 def : VFP2MnemonicAlias<"fldmfdx", "fldmiax">;
311 def : VFP2MnemonicAlias<"fstmeax", "fstmiax">;
312 def : VFP2MnemonicAlias<"fstmfdx", "fstmdbx">;
314 //===----------------------------------------------------------------------===//
315 // FP Binary Operations.
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]>;
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;
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",
341 Sched<[WriteFPALU32]>;
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]>;
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;
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",
366 Sched<[WriteFPALU32]>;
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]>;
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]>;
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",
387 Sched<[WriteFPDIV32]>;
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]>;
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;
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",
412 Sched<[WriteFPMUL32, ReadFPMUL, ReadFPMUL]>;
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]>;
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;
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",
434 Sched<[WriteFPMUL32, ReadFPMUL, ReadFPMUL]>;
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"),
443 Requires<[HasFullFP16]>;
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]>;
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]>;
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>;
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"),
471 Requires<[HasFullFP16]>;
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]>;
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]>;
487 defm VMAXNM : vmaxmin_inst<"vmaxnm", 0, fmaxnum>;
488 defm VMINNM : vmaxmin_inst<"vminnm", 1, fminnum>;
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]>;
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))]>;
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;
513 def VCMPEH : AHuI<0b11101, 0b11, 0b0100, 0b11, 0,
514 (outs), (ins SPR:$Sd, SPR:$Sm),
515 IIC_fpCMP16, "vcmpe", ".f16\t$Sd, $Sm",
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))]>;
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;
532 def VCMPH : AHuI<0b11101, 0b11, 0b0100, 0b01, 0,
533 (outs), (ins SPR:$Sd, SPR:$Sm),
534 IIC_fpCMP16, "vcmp", ".f16\t$Sd, $Sm",
536 } // Defs = [FPSCR_NZCV]
538 //===----------------------------------------------------------------------===//
539 // FP Unary Operations.
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)))]>;
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;
556 def VABSH : AHuI<0b11101, 0b11, 0b0000, 0b11, 0,
557 (outs SPR:$Sd), (ins SPR:$Sm),
558 IIC_fpUNA16, "vabs", ".f16\t$Sd, $Sm",
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;
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;
577 // Some single precision VFP instructions may be executed on both NEON and
578 // VFP pipelines on A8.
579 let D = VFPNeonA8Domain;
582 def VCMPEZH : AHuI<0b11101, 0b11, 0b0101, 0b11, 0,
583 (outs), (ins SPR:$Sd),
584 IIC_fpCMP16, "vcmpe", ".f16\t$Sd, #0",
586 let Inst{3-0} = 0b0000;
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;
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;
605 // Some single precision VFP instructions may be executed on both NEON and
606 // VFP pipelines on A8.
607 let D = VFPNeonA8Domain;
610 def VCMPZH : AHuI<0b11101, 0b11, 0b0101, 0b01, 0,
611 (outs), (ins SPR:$Sd),
612 IIC_fpCMP16, "vcmp", ".f16\t$Sd, #0",
614 let Inst{3-0} = 0b0000;
617 } // Defs = [FPSCR_NZCV]
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.
628 // Encode instruction operands.
629 let Inst{3-0} = Sm{4-1};
631 let Inst{15-12} = Dd{3-0};
632 let Inst{22} = Dd{4};
634 let Predicates = [HasVFP2, HasDPVFP];
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.
646 // Encode instruction operands.
647 let Inst{3-0} = Dm{3-0};
649 let Inst{15-12} = Sd{4-1};
650 let Inst{22} = Sd{0};
652 let Inst{27-23} = 0b11101;
653 let Inst{21-16} = 0b110111;
654 let Inst{11-8} = 0b1011;
655 let Inst{7-6} = 0b11;
658 let Predicates = [HasVFP2, HasDPVFP];
661 // Between half, single and double-precision. For disassembly only.
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 */]>,
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 */]>,
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 */]>,
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 */]>,
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.
695 // Encode instruction operands.
696 let Inst{3-0} = Sm{4-1};
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.
708 // Encode instruction operands.
709 let Inst{3-0} = Dm{3-0};
711 let Inst{15-12} = Sd{4-1};
712 let Inst{22} = Sd{0};
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.
722 // Encode instruction operands.
723 let Inst{3-0} = Sm{4-1};
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.
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};
742 def : Pat<(fp_to_f16 SPR:$a),
743 (i32 (COPY_TO_REGCLASS (VCVTBSH SPR:$a), GPR))>;
745 def : Pat<(fp_to_f16 (f64 DPR:$a)),
746 (i32 (COPY_TO_REGCLASS (VCVTBDH DPR:$a), GPR))>;
748 def : Pat<(f16_to_fp GPR:$a),
749 (VCVTBHS (COPY_TO_REGCLASS GPR:$a, SPR))>;
751 def : Pat<(f64 (f16_to_fp GPR:$a)),
752 (VCVTBHD (COPY_TO_REGCLASS GPR:$a, SPR))>;
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"),
761 Requires<[HasFullFP16]> {
762 let Inst{17-16} = rm;
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"),
769 Requires<[HasFullFP16]> {
770 let Inst{17-16} = rm;
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"),
777 Requires<[HasFPARMv8]> {
778 let Inst{17-16} = rm;
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"),
785 Requires<[HasFPARMv8]> {
786 let Inst{17-16} = rm;
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"),
793 Requires<[HasFPARMv8, HasDPVFP]> {
796 let Inst{17-16} = rm;
798 // Encode instruction operands
799 let Inst{3-0} = Dm{3-0};
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"),
808 Requires<[HasFPARMv8, HasDPVFP]> {
811 let Inst{17-16} = rm;
813 // Encode instruction operands
814 let Inst{3-0} = Dm{3-0};
820 let Predicates = [HasFPARMv8] in {
821 def : Pat<(i32 (fp_to_sint (node SPR:$a))),
823 (!cast<Instruction>(NAME#"SS") SPR:$a),
825 def : Pat<(i32 (fp_to_uint (node SPR:$a))),
827 (!cast<Instruction>(NAME#"US") SPR:$a),
830 let Predicates = [HasFPARMv8, HasDPVFP] in {
831 def : Pat<(i32 (fp_to_sint (node (f64 DPR:$a)))),
833 (!cast<Instruction>(NAME#"SD") DPR:$a),
835 def : Pat<(i32 (fp_to_uint (node (f64 DPR:$a)))),
837 (!cast<Instruction>(NAME#"UD") DPR:$a),
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>;
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)))]>;
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;
861 def VNEGH : AHuI<0b11101, 0b11, 0b0001, 0b01, 0,
862 (outs SPR:$Sd), (ins SPR:$Sm),
863 IIC_fpUNA16, "vneg", ".f16\t$Sd, $Sm",
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",
871 Requires<[HasFullFP16]> {
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]> {
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]> {
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]>;
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>;
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"),
915 Requires<[HasFullFP16]> {
916 let Inst{17-16} = rm;
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;
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;
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]>;
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>;
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]>;
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]>;
959 def VSQRTH : AHuI<0b11101, 0b11, 0b0001, 0b11, 0,
960 (outs SPR:$Sd), (ins SPR:$Sm),
961 IIC_fpSQRT16, "vsqrt", ".f16\t$Sd, $Sm",
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", []>;
969 def VMOVS : ASuI<0b11101, 0b11, 0b0000, 0b01, 0,
970 (outs SPR:$Sd), (ins SPR:$Sm),
971 IIC_fpUNA32, "vmov", ".f32\t$Sd, $Sm", []>;
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]>;
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
986 //===----------------------------------------------------------------------===//
987 // FP <-> GPR Copies. Int <-> FP Conversions.
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.
999 // Encode instruction operands.
1000 let Inst{19-16} = Sn{4-1};
1001 let Inst{7} = Sn{0};
1002 let Inst{15-12} = Rt;
1004 let Inst{6-5} = 0b00;
1005 let Inst{3-0} = 0b0000;
1007 // Some single precision VFP instructions may be executed on both NEON and VFP
1009 let D = VFPNeonDomain;
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.
1023 // Encode instruction operands.
1024 let Inst{19-16} = Sn{4-1};
1025 let Inst{7} = Sn{0};
1026 let Inst{15-12} = Rt;
1028 let Inst{6-5} = 0b00;
1029 let Inst{3-0} = 0b0000;
1031 // Some single precision VFP instructions may be executed on both NEON and VFP
1033 let D = VFPNeonDomain;
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.
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;
1053 let Inst{7-6} = 0b00;
1055 // Some single precision VFP instructions may be executed on both NEON and VFP
1057 let D = VFPNeonDomain;
1059 // This instruction is equivalent to
1060 // $Rt = EXTRACT_SUBREG $Dm, ssub_0
1061 // $Rt2 = EXTRACT_SUBREG $Dm, ssub_1
1062 let isExtractSubreg = 1;
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]> {
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;
1080 let Inst{7-6} = 0b00;
1082 // Some single precision VFP instructions may be executed on both NEON and VFP
1084 let D = VFPNeonDomain;
1085 let DecoderMethod = "DecodeVMOVRRS";
1089 // FMDHR: GPR -> SPR
1090 // FMDLR: GPR -> SPR
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.
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;
1108 let Inst{7-6} = 0b00;
1110 // Some single precision VFP instructions may be executed on both NEON and VFP
1112 let D = VFPNeonDomain;
1114 // This instruction is equivalent to
1115 // $Dm = REG_SEQUENCE $Rt, ssub_0, $Rt2, ssub_1
1116 let isRegSequence = 1;
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)))>,
1131 def : Pat<(fneg (arm_fmdrr GPR:$Rl, GPR:$Rh)),
1132 (VMOVDRR GPR:$Rl, (t2EORri GPR:$Rh, (i32 0x80000000)))>,
1133 Requires<[IsThumb2]>;
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.
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;
1152 let Inst{7-6} = 0b00;
1154 // Some single precision VFP instructions may be executed on both NEON and VFP
1156 let D = VFPNeonDomain;
1158 let DecoderMethod = "DecodeVMOVSRR";
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",
1166 Requires<[HasFullFP16]>,
1167 Sched<[WriteFPMOV]> {
1168 // Instruction operands.
1172 // Encode instruction operands.
1173 let Inst{19-16} = Sn{4-1};
1174 let Inst{7} = Sn{0};
1175 let Inst{15-12} = Rt;
1177 let Inst{6-5} = 0b00;
1178 let Inst{3-0} = 0b0000;
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",
1186 Requires<[HasFullFP16]>,
1187 Sched<[WriteFPMOV]> {
1188 // Instruction operands.
1192 // Encode instruction operands.
1193 let Inst{19-16} = Sn{4-1};
1194 let Inst{7} = Sn{0};
1195 let Inst{15-12} = Rt;
1197 let Inst{6-5} = 0b00;
1198 let Inst{3-0} = 0b0000;
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
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,
1215 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
1217 // Instruction operands.
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};
1227 let Predicates = [HasVFP2, HasDPVFP];
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,
1235 // Instruction operands.
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};
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,
1250 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
1252 // Instruction operands.
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};
1262 let Predicates = [HasFullFP16];
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",
1269 Sched<[WriteFPCVT]> {
1270 let Inst{7} = 1; // s32
1273 let Predicates=[HasVFP2, HasDPVFP] in {
1274 def : VFPPat<(f64 (sint_to_fp GPR:$a)),
1275 (VSITOD (COPY_TO_REGCLASS GPR:$a, SPR))>;
1277 def : VFPPat<(f64 (sint_to_fp (i32 (alignedload32 addrmode5:$a)))),
1278 (VSITOD (VLDRS addrmode5:$a))>;
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",
1285 Sched<[WriteFPCVT]> {
1286 let Inst{7} = 1; // s32
1288 // Some single precision VFP instructions may be executed on both NEON and
1289 // VFP pipelines on A8.
1290 let D = VFPNeonA8Domain;
1293 def : VFPNoNEONPat<(f32 (sint_to_fp GPR:$a)),
1294 (VSITOS (COPY_TO_REGCLASS GPR:$a, SPR))>;
1296 def : VFPNoNEONPat<(f32 (sint_to_fp (i32 (alignedload32 addrmode5:$a)))),
1297 (VSITOS (VLDRS addrmode5:$a))>;
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",
1303 Sched<[WriteFPCVT]> {
1304 let Inst{7} = 1; // s32
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",
1311 Sched<[WriteFPCVT]> {
1312 let Inst{7} = 0; // u32
1315 let Predicates=[HasVFP2, HasDPVFP] in {
1316 def : VFPPat<(f64 (uint_to_fp GPR:$a)),
1317 (VUITOD (COPY_TO_REGCLASS GPR:$a, SPR))>;
1319 def : VFPPat<(f64 (uint_to_fp (i32 (alignedload32 addrmode5:$a)))),
1320 (VUITOD (VLDRS addrmode5:$a))>;
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",
1327 Sched<[WriteFPCVT]> {
1328 let Inst{7} = 0; // u32
1330 // Some single precision VFP instructions may be executed on both NEON and
1331 // VFP pipelines on A8.
1332 let D = VFPNeonA8Domain;
1335 def : VFPNoNEONPat<(f32 (uint_to_fp GPR:$a)),
1336 (VUITOS (COPY_TO_REGCLASS GPR:$a, SPR))>;
1338 def : VFPNoNEONPat<(f32 (uint_to_fp (i32 (alignedload32 addrmode5:$a)))),
1339 (VUITOS (VLDRS addrmode5:$a))>;
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",
1345 Sched<[WriteFPCVT]> {
1346 let Inst{7} = 0; // u32
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,
1355 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
1357 // Instruction operands.
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};
1367 let Predicates = [HasVFP2, HasDPVFP];
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,
1374 : AVConv1In<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
1376 // Instruction operands.
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};
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,
1391 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
1393 // Instruction operands.
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};
1403 let Predicates = [HasFullFP16];
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",
1411 Sched<[WriteFPCVT]> {
1412 let Inst{7} = 1; // Z bit
1415 let Predicates=[HasVFP2, HasDPVFP] in {
1416 def : VFPPat<(i32 (fp_to_sint (f64 DPR:$a))),
1417 (COPY_TO_REGCLASS (VTOSIZD DPR:$a), GPR)>;
1419 def : VFPPat<(alignedstore32 (i32 (fp_to_sint (f64 DPR:$a))), addrmode5:$ptr),
1420 (VSTRS (VTOSIZD DPR:$a), addrmode5:$ptr)>;
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",
1427 Sched<[WriteFPCVT]> {
1428 let Inst{7} = 1; // Z bit
1430 // Some single precision VFP instructions may be executed on both NEON and
1431 // VFP pipelines on A8.
1432 let D = VFPNeonA8Domain;
1435 def : VFPNoNEONPat<(i32 (fp_to_sint SPR:$a)),
1436 (COPY_TO_REGCLASS (VTOSIZS SPR:$a), GPR)>;
1438 def : VFPNoNEONPat<(alignedstore32 (i32 (fp_to_sint (f32 SPR:$a))),
1440 (VSTRS (VTOSIZS SPR:$a), addrmode5:$ptr)>;
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",
1446 Sched<[WriteFPCVT]> {
1447 let Inst{7} = 1; // Z bit
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",
1454 Sched<[WriteFPCVT]> {
1455 let Inst{7} = 1; // Z bit
1458 let Predicates=[HasVFP2, HasDPVFP] in {
1459 def : VFPPat<(i32 (fp_to_uint (f64 DPR:$a))),
1460 (COPY_TO_REGCLASS (VTOUIZD DPR:$a), GPR)>;
1462 def : VFPPat<(alignedstore32 (i32 (fp_to_uint (f64 DPR:$a))), addrmode5:$ptr),
1463 (VSTRS (VTOUIZD DPR:$a), addrmode5:$ptr)>;
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",
1470 Sched<[WriteFPCVT]> {
1471 let Inst{7} = 1; // Z bit
1473 // Some single precision VFP instructions may be executed on both NEON and
1474 // VFP pipelines on A8.
1475 let D = VFPNeonA8Domain;
1478 def : VFPNoNEONPat<(i32 (fp_to_uint SPR:$a)),
1479 (COPY_TO_REGCLASS (VTOUIZS SPR:$a), GPR)>;
1481 def : VFPNoNEONPat<(alignedstore32 (i32 (fp_to_uint (f32 SPR:$a))),
1483 (VSTRS (VTOUIZS SPR:$a), addrmode5:$ptr)>;
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",
1489 Sched<[WriteFPCVT]> {
1490 let Inst{7} = 1; // Z bit
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
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
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",
1515 Sched<[WriteFPCVT]> {
1516 let Inst{7} = 0; // Z bit
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
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
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",
1539 Sched<[WriteFPCVT]> {
1540 let Inst{7} = 0; // Z bit
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",
1549 Requires<[HasFPARMv8, HasV8_3a]> {
1550 let Inst{7} = 1; // Z bit
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
1560 let Constraints = "$a = $dst" in {
1562 // FP to Fixed-Point:
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> {
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};
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> {
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};
1585 let Predicates = [HasVFP2, HasDPVFP];
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]>;
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]>;
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]>;
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]>;
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;
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;
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;
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;
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]>;
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]>;
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]>;
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]>;
1665 // Fixed-Point to FP:
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]>;
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]>;
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]>;
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]>;
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;
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;
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;
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;
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]>;
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]>;
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]>;
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]>;
1747 } // End of 'let Constraints = "$a = $dst" in'
1749 //===----------------------------------------------------------------------===//
1750 // FP Multiply-Accumulate Operations.
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]>;
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),
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;
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",
1779 RegConstraint<"$Sdin = $Sd">,
1780 Requires<[HasFullFP16,UseFPVMLx,DontUseFusedMAC]>;
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]>;
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]>;
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)),
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;
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",
1815 RegConstraint<"$Sdin = $Sd">,
1816 Requires<[HasFullFP16,UseFPVMLx,DontUseFusedMAC]>;
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]>;
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]>;
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)),
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;
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",
1851 RegConstraint<"$Sdin = $Sd">,
1852 Requires<[HasFullFP16,UseFPVMLx,DontUseFusedMAC]>;
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]>;
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]>;
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]>;
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;
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",
1895 RegConstraint<"$Sdin = $Sd">,
1896 Requires<[HasFullFP16,UseFPVMLx,DontUseFusedMAC]>;
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]>;
1905 //===----------------------------------------------------------------------===//
1906 // Fused FP Multiply-Accumulate Operations.
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]>;
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),
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
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",
1933 RegConstraint<"$Sdin = $Sd">,
1934 Requires<[HasFullFP16,UseFusedMAC]>,
1935 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
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]>;
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]>;
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]>;
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)),
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
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",
1978 RegConstraint<"$Sdin = $Sd">,
1979 Requires<[HasFullFP16,UseFusedMAC]>,
1980 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
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]>;
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]>;
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]>;
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)),
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
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",
2030 RegConstraint<"$Sdin = $Sd">,
2031 Requires<[HasFullFP16,UseFusedMAC]>,
2032 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
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]>;
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]>;
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]>;
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
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",
2081 RegConstraint<"$Sdin = $Sd">,
2082 Requires<[HasFullFP16,UseFusedMAC]>,
2083 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>;
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]>;
2092 // Match @llvm.fma.* intrinsics
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]>;
2116 //===----------------------------------------------------------------------===//
2117 // FP Conditional moves.
2120 let hasSideEffects = 0 in {
2121 def VMOVDcc : PseudoInst<(outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm, cmovpred:$p),
2123 [(set (f64 DPR:$Dd),
2124 (ARMcmov DPR:$Dn, DPR:$Dm, cmovpred:$p))]>,
2125 RegConstraint<"$Dn = $Dd">, Requires<[HasVFP2,HasDPVFP]>;
2127 def VMOVScc : PseudoInst<(outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm, cmovpred:$p),
2129 [(set (f32 SPR:$Sd),
2130 (ARMcmov SPR:$Sn, SPR:$Sm, cmovpred:$p))]>,
2131 RegConstraint<"$Sn = $Sd">, Requires<[HasVFP2]>;
2134 //===----------------------------------------------------------------------===//
2135 // Move from VFP System Register to ARM core register.
2138 class MovFromVFP<bits<4> opc19_16, dag oops, dag iops, string opc, string asm,
2140 VFPAI<oops, iops, VFPMiscFrm, IIC_fpSTAT, opc, asm, pattern> {
2142 // Instruction operand.
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;
2150 let Inst{6-5} = 0b00;
2152 let Inst{3-0} = 0b0000;
2155 // APSR is the application level alias of CPSR. This FPSCR N, Z, C, V flags
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)]>;
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))]>;
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", []>;
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", []>;
2189 //===----------------------------------------------------------------------===//
2190 // Move from ARM core register to VFP System Register.
2193 class MovToVFP<bits<4> opc19_16, dag oops, dag iops, string opc, string asm,
2195 VFPAI<oops, iops, VFPMiscFrm, IIC_fpSTAT, opc, asm, pattern> {
2197 // Instruction operand.
2200 // Encode instruction operand.
2201 let Inst{15-12} = src;
2203 let Inst{27-20} = 0b11101110;
2204 let Inst{19-16} = opc19_16;
2205 let Inst{11-8} = 0b1010;
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", []>;
2229 //===----------------------------------------------------------------------===//
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]> {
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};
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]> {
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};
2272 def FCONSTH : VFPAI<(outs SPR:$Sd), (ins vfp_f16imm:$imm),
2273 VFPMiscFrm, IIC_fpUNA16,
2274 "vmov", ".f16\t$Sd, $imm",
2275 []>, Requires<[HasFullFP16]> {
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};
2290 //===----------------------------------------------------------------------===//
2291 // Assembler aliases.
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">;
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)>;
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)>;
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)>;
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)>;
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)>;
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)>;
2385 // VMOVS doesn't need the .f32 to disambiguate from the NEON encoding the way
2387 def : VFP2InstAlias<"vmov${p} $Sd, $Sm",
2388 (VMOVS SPR:$Sd, SPR:$Sm, pred:$p)>;
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)>;