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_FTOI : SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>;
15 def SDT_ITOF : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>;
16 def SDT_CMPFP0 : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
17 def SDT_VMOVDRR : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>,
20 def arm_ftoui : SDNode<"ARMISD::FTOUI", SDT_FTOI>;
21 def arm_ftosi : SDNode<"ARMISD::FTOSI", SDT_FTOI>;
22 def arm_sitof : SDNode<"ARMISD::SITOF", SDT_ITOF>;
23 def arm_uitof : SDNode<"ARMISD::UITOF", SDT_ITOF>;
24 def arm_fmstat : SDNode<"ARMISD::FMSTAT", SDTNone, [SDNPInFlag, SDNPOutFlag]>;
25 def arm_cmpfp : SDNode<"ARMISD::CMPFP", SDT_ARMCmp, [SDNPOutFlag]>;
26 def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0", SDT_CMPFP0, [SDNPOutFlag]>;
27 def arm_fmdrr : SDNode<"ARMISD::VMOVDRR", SDT_VMOVDRR>;
30 //===----------------------------------------------------------------------===//
31 // Operand Definitions.
34 def vfp_f32imm : Operand<f32>,
35 PatLeaf<(f32 fpimm), [{
36 return ARM::getVFPf32Imm(N->getValueAPF()) != -1;
38 let PrintMethod = "printVFPf32ImmOperand";
41 def vfp_f64imm : Operand<f64>,
42 PatLeaf<(f64 fpimm), [{
43 return ARM::getVFPf64Imm(N->getValueAPF()) != -1;
45 let PrintMethod = "printVFPf64ImmOperand";
49 //===----------------------------------------------------------------------===//
50 // Load / store Instructions.
53 let canFoldAsLoad = 1, isReMaterializable = 1 in {
55 def VLDRD : ADI5<0b1101, 0b01, (outs DPR:$Dd), (ins addrmode5:$addr),
56 IIC_fpLoad64, "vldr", ".64\t$Dd, $addr",
57 [(set DPR:$Dd, (f64 (load addrmode5:$addr)))]>;
59 def VLDRS : ASI5<0b1101, 0b01, (outs SPR:$Sd), (ins addrmode5:$addr),
60 IIC_fpLoad32, "vldr", ".32\t$Sd, $addr",
61 [(set SPR:$Sd, (load addrmode5:$addr))]>;
63 } // End of 'let canFoldAsLoad = 1, isReMaterializable = 1 in'
65 def VSTRD : ADI5<0b1101, 0b00, (outs), (ins DPR:$Dd, addrmode5:$addr),
66 IIC_fpStore64, "vstr", ".64\t$Dd, $addr",
67 [(store (f64 DPR:$Dd), addrmode5:$addr)]>;
69 def VSTRS : ASI5<0b1101, 0b00, (outs), (ins SPR:$Sd, addrmode5:$addr),
70 IIC_fpStore32, "vstr", ".32\t$Sd, $addr",
71 [(store SPR:$Sd, addrmode5:$addr)]>;
73 //===----------------------------------------------------------------------===//
74 // Load / store multiple Instructions.
77 multiclass vfp_ldst_mult<string asm, bit L_bit,
78 InstrItinClass itin, InstrItinClass itin_upd> {
81 AXDI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
83 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
84 let Inst{24-23} = 0b01; // Increment After
85 let Inst{21} = 0; // No writeback
89 AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
90 IndexModeUpd, itin_upd,
91 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
92 let Inst{24-23} = 0b01; // Increment After
93 let Inst{21} = 1; // Writeback
97 AXDI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
99 !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
100 let Inst{24-23} = 0b10; // Decrement Before
101 let Inst{21} = 0; // No writeback
102 let Inst{20} = L_bit;
105 AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
106 IndexModeUpd, itin_upd,
107 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
108 let Inst{24-23} = 0b10; // Decrement Before
109 let Inst{21} = 1; // Writeback
110 let Inst{20} = L_bit;
115 AXSI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
117 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> {
118 let Inst{24-23} = 0b01; // Increment After
119 let Inst{21} = 0; // No writeback
120 let Inst{20} = L_bit;
123 AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
124 IndexModeUpd, itin_upd,
125 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
126 let Inst{24-23} = 0b01; // Increment After
127 let Inst{21} = 1; // Writeback
128 let Inst{20} = L_bit;
131 AXSI4<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
133 !strconcat(asm, "db${p}\t$Rn, $regs"), "", []> {
134 let Inst{24-23} = 0b10; // Decrement Before
135 let Inst{21} = 0; // No writeback
136 let Inst{20} = L_bit;
139 AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
140 IndexModeUpd, itin_upd,
141 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> {
142 let Inst{24-23} = 0b10; // Decrement Before
143 let Inst{21} = 1; // Writeback
144 let Inst{20} = L_bit;
148 let neverHasSideEffects = 1 in {
150 let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
151 defm VLDM : vfp_ldst_mult<"vldm", 1, IIC_fpLoad_m, IIC_fpLoad_mu>;
153 let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
154 defm VSTM : vfp_ldst_mult<"vstm", 0, IIC_fpLoad_m, IIC_fpLoad_mu>;
156 } // neverHasSideEffects
158 // FLDMX, FSTMX - mixing S/D registers for pre-armv6 cores
160 //===----------------------------------------------------------------------===//
161 // FP Binary Operations.
164 def VADDD : ADbI<0b11100, 0b11, 0, 0,
165 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
166 IIC_fpALU64, "vadd", ".f64\t$Dd, $Dn, $Dm",
167 [(set DPR:$Dd, (fadd DPR:$Dn, (f64 DPR:$Dm)))]>;
169 def VADDS : ASbIn<0b11100, 0b11, 0, 0,
170 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
171 IIC_fpALU32, "vadd", ".f32\t$Sd, $Sn, $Sm",
172 [(set SPR:$Sd, (fadd SPR:$Sn, SPR:$Sm))]>;
174 def VSUBD : ADbI<0b11100, 0b11, 1, 0,
175 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
176 IIC_fpALU64, "vsub", ".f64\t$Dd, $Dn, $Dm",
177 [(set DPR:$Dd, (fsub DPR:$Dn, (f64 DPR:$Dm)))]>;
179 def VSUBS : ASbIn<0b11100, 0b11, 1, 0,
180 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
181 IIC_fpALU32, "vsub", ".f32\t$Sd, $Sn, $Sm",
182 [(set SPR:$Sd, (fsub SPR:$Sn, SPR:$Sm))]>;
184 def VDIVD : ADbI<0b11101, 0b00, 0, 0,
185 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
186 IIC_fpDIV64, "vdiv", ".f64\t$Dd, $Dn, $Dm",
187 [(set DPR:$Dd, (fdiv DPR:$Dn, (f64 DPR:$Dm)))]>;
189 def VDIVS : ASbI<0b11101, 0b00, 0, 0,
190 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
191 IIC_fpDIV32, "vdiv", ".f32\t$Sd, $Sn, $Sm",
192 [(set SPR:$Sd, (fdiv SPR:$Sn, SPR:$Sm))]>;
194 def VMULD : ADbI<0b11100, 0b10, 0, 0,
195 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
196 IIC_fpMUL64, "vmul", ".f64\t$Dd, $Dn, $Dm",
197 [(set DPR:$Dd, (fmul DPR:$Dn, (f64 DPR:$Dm)))]>;
199 def VMULS : ASbIn<0b11100, 0b10, 0, 0,
200 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
201 IIC_fpMUL32, "vmul", ".f32\t$Sd, $Sn, $Sm",
202 [(set SPR:$Sd, (fmul SPR:$Sn, SPR:$Sm))]>;
204 def VNMULD : ADbI<0b11100, 0b10, 1, 0,
205 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
206 IIC_fpMUL64, "vnmul", ".f64\t$Dd, $Dn, $Dm",
207 [(set DPR:$Dd, (fneg (fmul DPR:$Dn, (f64 DPR:$Dm))))]>;
209 def VNMULS : ASbI<0b11100, 0b10, 1, 0,
210 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
211 IIC_fpMUL32, "vnmul", ".f32\t$Sd, $Sn, $Sm",
212 [(set SPR:$Sd, (fneg (fmul SPR:$Sn, SPR:$Sm)))]>;
214 // Match reassociated forms only if not sign dependent rounding.
215 def : Pat<(fmul (fneg DPR:$a), (f64 DPR:$b)),
216 (VNMULD DPR:$a, DPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
217 def : Pat<(fmul (fneg SPR:$a), SPR:$b),
218 (VNMULS SPR:$a, SPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
220 // These are encoded as unary instructions.
221 let Defs = [FPSCR] in {
222 def VCMPED : ADuI<0b11101, 0b11, 0b0100, 0b11, 0,
223 (outs), (ins DPR:$Dd, DPR:$Dm),
224 IIC_fpCMP64, "vcmpe", ".f64\t$Dd, $Dm",
225 [(arm_cmpfp DPR:$Dd, (f64 DPR:$Dm))]>;
227 def VCMPES : ASuI<0b11101, 0b11, 0b0100, 0b11, 0,
228 (outs), (ins SPR:$Sd, SPR:$Sm),
229 IIC_fpCMP32, "vcmpe", ".f32\t$Sd, $Sm",
230 [(arm_cmpfp SPR:$Sd, SPR:$Sm)]>;
232 // FIXME: Verify encoding after integrated assembler is working.
233 def VCMPD : ADuI<0b11101, 0b11, 0b0100, 0b01, 0,
234 (outs), (ins DPR:$Dd, DPR:$Dm),
235 IIC_fpCMP64, "vcmp", ".f64\t$Dd, $Dm",
236 [/* For disassembly only; pattern left blank */]>;
238 def VCMPS : ASuI<0b11101, 0b11, 0b0100, 0b01, 0,
239 (outs), (ins SPR:$Sd, SPR:$Sm),
240 IIC_fpCMP32, "vcmp", ".f32\t$Sd, $Sm",
241 [/* For disassembly only; pattern left blank */]>;
244 //===----------------------------------------------------------------------===//
245 // FP Unary Operations.
248 def VABSD : ADuI<0b11101, 0b11, 0b0000, 0b11, 0,
249 (outs DPR:$Dd), (ins DPR:$Dm),
250 IIC_fpUNA64, "vabs", ".f64\t$Dd, $Dm",
251 [(set DPR:$Dd, (fabs (f64 DPR:$Dm)))]>;
253 def VABSS : ASuIn<0b11101, 0b11, 0b0000, 0b11, 0,
254 (outs SPR:$Sd), (ins SPR:$Sm),
255 IIC_fpUNA32, "vabs", ".f32\t$Sd, $Sm",
256 [(set SPR:$Sd, (fabs SPR:$Sm))]>;
258 let Defs = [FPSCR] in {
259 def VCMPEZD : ADuI<0b11101, 0b11, 0b0101, 0b11, 0,
260 (outs), (ins DPR:$Dd),
261 IIC_fpCMP64, "vcmpe", ".f64\t$Dd, #0",
262 [(arm_cmpfp0 (f64 DPR:$Dd))]> {
263 let Inst{3-0} = 0b0000;
267 def VCMPEZS : ASuI<0b11101, 0b11, 0b0101, 0b11, 0,
268 (outs), (ins SPR:$Sd),
269 IIC_fpCMP32, "vcmpe", ".f32\t$Sd, #0",
270 [(arm_cmpfp0 SPR:$Sd)]> {
271 let Inst{3-0} = 0b0000;
275 // FIXME: Verify encoding after integrated assembler is working.
276 def VCMPZD : ADuI<0b11101, 0b11, 0b0101, 0b01, 0,
277 (outs), (ins DPR:$Dd),
278 IIC_fpCMP64, "vcmp", ".f64\t$Dd, #0",
279 [/* For disassembly only; pattern left blank */]> {
280 let Inst{3-0} = 0b0000;
284 def VCMPZS : ASuI<0b11101, 0b11, 0b0101, 0b01, 0,
285 (outs), (ins SPR:$Sd),
286 IIC_fpCMP32, "vcmp", ".f32\t$Sd, #0",
287 [/* For disassembly only; pattern left blank */]> {
288 let Inst{3-0} = 0b0000;
293 def VCVTDS : ASuI<0b11101, 0b11, 0b0111, 0b11, 0,
294 (outs DPR:$Dd), (ins SPR:$Sm),
295 IIC_fpCVTDS, "vcvt", ".f64.f32\t$Dd, $Sm",
296 [(set DPR:$Dd, (fextend SPR:$Sm))]> {
297 // Instruction operands.
301 // Encode instruction operands.
302 let Inst{3-0} = Sm{4-1};
304 let Inst{15-12} = Dd{3-0};
305 let Inst{22} = Dd{4};
308 // Special case encoding: bits 11-8 is 0b1011.
309 def VCVTSD : VFPAI<(outs SPR:$Sd), (ins DPR:$Dm), VFPUnaryFrm,
310 IIC_fpCVTSD, "vcvt", ".f32.f64\t$Sd, $Dm",
311 [(set SPR:$Sd, (fround DPR:$Dm))]> {
312 // Instruction operands.
316 // Encode instruction operands.
317 let Inst{3-0} = Dm{3-0};
319 let Inst{15-12} = Sd{4-1};
320 let Inst{22} = Sd{0};
322 let Inst{27-23} = 0b11101;
323 let Inst{21-16} = 0b110111;
324 let Inst{11-8} = 0b1011;
325 let Inst{7-6} = 0b11;
329 // Between half-precision and single-precision. For disassembly only.
331 // FIXME: Verify encoding after integrated assembler is working.
332 def VCVTBSH: ASuI<0b11101, 0b11, 0b0010, 0b01, 0, (outs SPR:$dst), (ins SPR:$a),
333 /* FIXME */ IIC_fpCVTSH, "vcvtb", ".f32.f16\t$dst, $a",
334 [/* For disassembly only; pattern left blank */]>;
336 def : ARMPat<(f32_to_f16 SPR:$a),
337 (i32 (COPY_TO_REGCLASS (VCVTBSH SPR:$a), GPR))>;
339 def VCVTBHS: ASuI<0b11101, 0b11, 0b0011, 0b01, 0, (outs SPR:$dst), (ins SPR:$a),
340 /* FIXME */ IIC_fpCVTHS, "vcvtb", ".f16.f32\t$dst, $a",
341 [/* For disassembly only; pattern left blank */]>;
343 def : ARMPat<(f16_to_f32 GPR:$a),
344 (VCVTBHS (COPY_TO_REGCLASS GPR:$a, SPR))>;
346 def VCVTTSH: ASuI<0b11101, 0b11, 0b0010, 0b11, 0, (outs SPR:$dst), (ins SPR:$a),
347 /* FIXME */ IIC_fpCVTSH, "vcvtt", ".f32.f16\t$dst, $a",
348 [/* For disassembly only; pattern left blank */]>;
350 def VCVTTHS: ASuI<0b11101, 0b11, 0b0011, 0b11, 0, (outs SPR:$dst), (ins SPR:$a),
351 /* FIXME */ IIC_fpCVTHS, "vcvtt", ".f16.f32\t$dst, $a",
352 [/* For disassembly only; pattern left blank */]>;
354 def VNEGD : ADuI<0b11101, 0b11, 0b0001, 0b01, 0,
355 (outs DPR:$Dd), (ins DPR:$Dm),
356 IIC_fpUNA64, "vneg", ".f64\t$Dd, $Dm",
357 [(set DPR:$Dd, (fneg (f64 DPR:$Dm)))]>;
359 def VNEGS : ASuIn<0b11101, 0b11, 0b0001, 0b01, 0,
360 (outs SPR:$Sd), (ins SPR:$Sm),
361 IIC_fpUNA32, "vneg", ".f32\t$Sd, $Sm",
362 [(set SPR:$Sd, (fneg SPR:$Sm))]>;
364 def VSQRTD : ADuI<0b11101, 0b11, 0b0001, 0b11, 0,
365 (outs DPR:$Dd), (ins DPR:$Dm),
366 IIC_fpSQRT64, "vsqrt", ".f64\t$Dd, $Dm",
367 [(set DPR:$Dd, (fsqrt (f64 DPR:$Dm)))]>;
369 def VSQRTS : ASuI<0b11101, 0b11, 0b0001, 0b11, 0,
370 (outs SPR:$Sd), (ins SPR:$Sm),
371 IIC_fpSQRT32, "vsqrt", ".f32\t$Sd, $Sm",
372 [(set SPR:$Sd, (fsqrt SPR:$Sm))]>;
374 let neverHasSideEffects = 1 in {
375 def VMOVD : ADuI<0b11101, 0b11, 0b0000, 0b01, 0,
376 (outs DPR:$Dd), (ins DPR:$Dm),
377 IIC_fpUNA64, "vmov", ".f64\t$Dd, $Dm", []>;
379 def VMOVS : ASuI<0b11101, 0b11, 0b0000, 0b01, 0,
380 (outs SPR:$Sd), (ins SPR:$Sm),
381 IIC_fpUNA32, "vmov", ".f32\t$Sd, $Sm", []>;
382 } // neverHasSideEffects
384 //===----------------------------------------------------------------------===//
385 // FP <-> GPR Copies. Int <-> FP Conversions.
388 def VMOVRS : AVConv2I<0b11100001, 0b1010,
389 (outs GPR:$Rt), (ins SPR:$Sn),
390 IIC_fpMOVSI, "vmov", "\t$Rt, $Sn",
391 [(set GPR:$Rt, (bitconvert SPR:$Sn))]> {
392 // Instruction operands.
396 // Encode instruction operands.
397 let Inst{19-16} = Sn{4-1};
399 let Inst{15-12} = Rt;
401 let Inst{6-5} = 0b00;
402 let Inst{3-0} = 0b0000;
405 def VMOVSR : AVConv4I<0b11100000, 0b1010,
406 (outs SPR:$Sn), (ins GPR:$Rt),
407 IIC_fpMOVIS, "vmov", "\t$Sn, $Rt",
408 [(set SPR:$Sn, (bitconvert GPR:$Rt))]> {
409 // Instruction operands.
413 // Encode instruction operands.
414 let Inst{19-16} = Sn{4-1};
416 let Inst{15-12} = Rt;
418 let Inst{6-5} = 0b00;
419 let Inst{3-0} = 0b0000;
422 let neverHasSideEffects = 1 in {
423 def VMOVRRD : AVConv3I<0b11000101, 0b1011,
424 (outs GPR:$Rt, GPR:$Rt2), (ins DPR:$Dm),
425 IIC_fpMOVDI, "vmov", "\t$Rt, $Rt2, $Dm",
426 [/* FIXME: Can't write pattern for multiple result instr*/]> {
427 // Instruction operands.
432 // Encode instruction operands.
433 let Inst{3-0} = Dm{3-0};
435 let Inst{15-12} = Rt;
436 let Inst{19-16} = Rt2;
438 let Inst{7-6} = 0b00;
441 def VMOVRRS : AVConv3I<0b11000101, 0b1010,
442 (outs GPR:$wb, GPR:$dst2), (ins SPR:$src1, SPR:$src2),
443 IIC_fpMOVDI, "vmov", "\t$wb, $dst2, $src1, $src2",
444 [/* For disassembly only; pattern left blank */]> {
445 let Inst{7-6} = 0b00;
447 } // neverHasSideEffects
452 def VMOVDRR : AVConv5I<0b11000100, 0b1011,
453 (outs DPR:$Dm), (ins GPR:$Rt, GPR:$Rt2),
454 IIC_fpMOVID, "vmov", "\t$Dm, $Rt, $Rt2",
455 [(set DPR:$Dm, (arm_fmdrr GPR:$Rt, GPR:$Rt2))]> {
456 // Instruction operands.
461 // Encode instruction operands.
462 let Inst{3-0} = Dm{3-0};
464 let Inst{15-12} = Rt;
465 let Inst{19-16} = Rt2;
467 let Inst{7-6} = 0b00;
470 let neverHasSideEffects = 1 in
471 def VMOVSRR : AVConv5I<0b11000100, 0b1010,
472 (outs SPR:$dst1, SPR:$dst2), (ins GPR:$src1, GPR:$src2),
473 IIC_fpMOVID, "vmov", "\t$dst1, $dst2, $src1, $src2",
474 [/* For disassembly only; pattern left blank */]> {
475 let Inst{7-6} = 0b00;
481 // FMRX: SPR system reg -> GPR
483 // FMXR: GPR -> VFP system reg
488 class AVConv1IDs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
489 bits<4> opcod4, dag oops, dag iops,
490 InstrItinClass itin, string opc, string asm,
492 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
494 // Instruction operands.
498 // Encode instruction operands.
499 let Inst{3-0} = Sm{4-1};
501 let Inst{15-12} = Dd{3-0};
502 let Inst{22} = Dd{4};
505 class AVConv1InSs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
506 bits<4> opcod4, dag oops, dag iops,InstrItinClass itin,
507 string opc, string asm, list<dag> pattern>
508 : AVConv1In<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
510 // Instruction operands.
514 // Encode instruction operands.
515 let Inst{3-0} = Sm{4-1};
517 let Inst{15-12} = Sd{4-1};
518 let Inst{22} = Sd{0};
521 def VSITOD : AVConv1IDs_Encode<0b11101, 0b11, 0b1000, 0b1011,
522 (outs DPR:$Dd), (ins SPR:$Sm),
523 IIC_fpCVTID, "vcvt", ".f64.s32\t$Dd, $Sm",
524 [(set DPR:$Dd, (f64 (arm_sitof SPR:$Sm)))]> {
525 let Inst{7} = 1; // s32
528 def VSITOS : AVConv1InSs_Encode<0b11101, 0b11, 0b1000, 0b1010,
529 (outs SPR:$Sd),(ins SPR:$Sm),
530 IIC_fpCVTIS, "vcvt", ".f32.s32\t$Sd, $Sm",
531 [(set SPR:$Sd, (arm_sitof SPR:$Sm))]> {
532 let Inst{7} = 1; // s32
535 def VUITOD : AVConv1IDs_Encode<0b11101, 0b11, 0b1000, 0b1011,
536 (outs DPR:$Dd), (ins SPR:$Sm),
537 IIC_fpCVTID, "vcvt", ".f64.u32\t$Dd, $Sm",
538 [(set DPR:$Dd, (f64 (arm_uitof SPR:$Sm)))]> {
539 let Inst{7} = 0; // u32
542 def VUITOS : AVConv1InSs_Encode<0b11101, 0b11, 0b1000, 0b1010,
543 (outs SPR:$Sd), (ins SPR:$Sm),
544 IIC_fpCVTIS, "vcvt", ".f32.u32\t$Sd, $Sm",
545 [(set SPR:$Sd, (arm_uitof SPR:$Sm))]> {
546 let Inst{7} = 0; // u32
551 class AVConv1IsD_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
552 bits<4> opcod4, dag oops, dag iops,
553 InstrItinClass itin, string opc, string asm,
555 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
557 // Instruction operands.
561 // Encode instruction operands.
562 let Inst{3-0} = Dm{3-0};
564 let Inst{15-12} = Sd{4-1};
565 let Inst{22} = Sd{0};
568 class AVConv1InsS_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
569 bits<4> opcod4, dag oops, dag iops,
570 InstrItinClass itin, string opc, string asm,
572 : AVConv1In<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
574 // Instruction operands.
578 // Encode instruction operands.
579 let Inst{3-0} = Sm{4-1};
581 let Inst{15-12} = Sd{4-1};
582 let Inst{22} = Sd{0};
585 // Always set Z bit in the instruction, i.e. "round towards zero" variants.
586 def VTOSIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011,
587 (outs SPR:$Sd), (ins DPR:$Dm),
588 IIC_fpCVTDI, "vcvt", ".s32.f64\t$Sd, $Dm",
589 [(set SPR:$Sd, (arm_ftosi (f64 DPR:$Dm)))]> {
590 let Inst{7} = 1; // Z bit
593 def VTOSIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010,
594 (outs SPR:$Sd), (ins SPR:$Sm),
595 IIC_fpCVTSI, "vcvt", ".s32.f32\t$Sd, $Sm",
596 [(set SPR:$Sd, (arm_ftosi SPR:$Sm))]> {
597 let Inst{7} = 1; // Z bit
600 def VTOUIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011,
601 (outs SPR:$Sd), (ins DPR:$Dm),
602 IIC_fpCVTDI, "vcvt", ".u32.f64\t$Sd, $Dm",
603 [(set SPR:$Sd, (arm_ftoui (f64 DPR:$Dm)))]> {
604 let Inst{7} = 1; // Z bit
607 def VTOUIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010,
608 (outs SPR:$Sd), (ins SPR:$Sm),
609 IIC_fpCVTSI, "vcvt", ".u32.f32\t$Sd, $Sm",
610 [(set SPR:$Sd, (arm_ftoui SPR:$Sm))]> {
611 let Inst{7} = 1; // Z bit
614 // And the Z bit '0' variants, i.e. use the rounding mode specified by FPSCR.
615 // For disassembly only.
616 let Uses = [FPSCR] in {
617 // FIXME: Verify encoding after integrated assembler is working.
618 def VTOSIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011,
619 (outs SPR:$Sd), (ins DPR:$Dm),
620 IIC_fpCVTDI, "vcvtr", ".s32.f64\t$Sd, $Dm",
621 [(set SPR:$Sd, (int_arm_vcvtr (f64 DPR:$Dm)))]>{
622 let Inst{7} = 0; // Z bit
625 def VTOSIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010,
626 (outs SPR:$Sd), (ins SPR:$Sm),
627 IIC_fpCVTSI, "vcvtr", ".s32.f32\t$Sd, $Sm",
628 [(set SPR:$Sd, (int_arm_vcvtr SPR:$Sm))]> {
629 let Inst{7} = 0; // Z bit
632 def VTOUIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011,
633 (outs SPR:$Sd), (ins DPR:$Dm),
634 IIC_fpCVTDI, "vcvtr", ".u32.f64\t$Sd, $Dm",
635 [(set SPR:$Sd, (int_arm_vcvtru(f64 DPR:$Dm)))]>{
636 let Inst{7} = 0; // Z bit
639 def VTOUIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010,
640 (outs SPR:$Sd), (ins SPR:$Sm),
641 IIC_fpCVTSI, "vcvtr", ".u32.f32\t$Sd, $Sm",
642 [(set SPR:$Sd, (int_arm_vcvtru SPR:$Sm))]> {
643 let Inst{7} = 0; // Z bit
647 // Convert between floating-point and fixed-point
648 // Data type for fixed-point naming convention:
649 // S16 (U=0, sx=0) -> SH
650 // U16 (U=1, sx=0) -> UH
651 // S32 (U=0, sx=1) -> SL
652 // U32 (U=1, sx=1) -> UL
654 // FIXME: Marking these as codegen only seems wrong. They are real
656 let Constraints = "$a = $dst", isCodeGenOnly = 1 in {
658 // FP to Fixed-Point:
660 def VTOSHS : AVConv1XI<0b11101, 0b11, 0b1110, 0b1010, 0,
661 (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
662 IIC_fpCVTSI, "vcvt", ".s16.f32\t$dst, $a, $fbits",
663 [/* For disassembly only; pattern left blank */]>;
665 def VTOUHS : AVConv1XI<0b11101, 0b11, 0b1111, 0b1010, 0,
666 (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
667 IIC_fpCVTSI, "vcvt", ".u16.f32\t$dst, $a, $fbits",
668 [/* For disassembly only; pattern left blank */]>;
670 def VTOSLS : AVConv1XI<0b11101, 0b11, 0b1110, 0b1010, 1,
671 (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
672 IIC_fpCVTSI, "vcvt", ".s32.f32\t$dst, $a, $fbits",
673 [/* For disassembly only; pattern left blank */]>;
675 def VTOULS : AVConv1XI<0b11101, 0b11, 0b1111, 0b1010, 1,
676 (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
677 IIC_fpCVTSI, "vcvt", ".u32.f32\t$dst, $a, $fbits",
678 [/* For disassembly only; pattern left blank */]>;
680 def VTOSHD : AVConv1XI<0b11101, 0b11, 0b1110, 0b1011, 0,
681 (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
682 IIC_fpCVTDI, "vcvt", ".s16.f64\t$dst, $a, $fbits",
683 [/* For disassembly only; pattern left blank */]>;
685 def VTOUHD : AVConv1XI<0b11101, 0b11, 0b1111, 0b1011, 0,
686 (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
687 IIC_fpCVTDI, "vcvt", ".u16.f64\t$dst, $a, $fbits",
688 [/* For disassembly only; pattern left blank */]>;
690 def VTOSLD : AVConv1XI<0b11101, 0b11, 0b1110, 0b1011, 1,
691 (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
692 IIC_fpCVTDI, "vcvt", ".s32.f64\t$dst, $a, $fbits",
693 [/* For disassembly only; pattern left blank */]>;
695 def VTOULD : AVConv1XI<0b11101, 0b11, 0b1111, 0b1011, 1,
696 (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
697 IIC_fpCVTDI, "vcvt", ".u32.f64\t$dst, $a, $fbits",
698 [/* For disassembly only; pattern left blank */]>;
700 // Fixed-Point to FP:
702 def VSHTOS : AVConv1XI<0b11101, 0b11, 0b1010, 0b1010, 0,
703 (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
704 IIC_fpCVTIS, "vcvt", ".f32.s16\t$dst, $a, $fbits",
705 [/* For disassembly only; pattern left blank */]>;
707 def VUHTOS : AVConv1XI<0b11101, 0b11, 0b1011, 0b1010, 0,
708 (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
709 IIC_fpCVTIS, "vcvt", ".f32.u16\t$dst, $a, $fbits",
710 [/* For disassembly only; pattern left blank */]>;
712 def VSLTOS : AVConv1XI<0b11101, 0b11, 0b1010, 0b1010, 1,
713 (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
714 IIC_fpCVTIS, "vcvt", ".f32.s32\t$dst, $a, $fbits",
715 [/* For disassembly only; pattern left blank */]>;
717 def VULTOS : AVConv1XI<0b11101, 0b11, 0b1011, 0b1010, 1,
718 (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
719 IIC_fpCVTIS, "vcvt", ".f32.u32\t$dst, $a, $fbits",
720 [/* For disassembly only; pattern left blank */]>;
722 def VSHTOD : AVConv1XI<0b11101, 0b11, 0b1010, 0b1011, 0,
723 (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
724 IIC_fpCVTID, "vcvt", ".f64.s16\t$dst, $a, $fbits",
725 [/* For disassembly only; pattern left blank */]>;
727 def VUHTOD : AVConv1XI<0b11101, 0b11, 0b1011, 0b1011, 0,
728 (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
729 IIC_fpCVTID, "vcvt", ".f64.u16\t$dst, $a, $fbits",
730 [/* For disassembly only; pattern left blank */]>;
732 def VSLTOD : AVConv1XI<0b11101, 0b11, 0b1010, 0b1011, 1,
733 (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
734 IIC_fpCVTID, "vcvt", ".f64.s32\t$dst, $a, $fbits",
735 [/* For disassembly only; pattern left blank */]>;
737 def VULTOD : AVConv1XI<0b11101, 0b11, 0b1011, 0b1011, 1,
738 (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
739 IIC_fpCVTID, "vcvt", ".f64.u32\t$dst, $a, $fbits",
740 [/* For disassembly only; pattern left blank */]>;
742 } // End of 'let Constraints = "$a = $dst", isCodeGenOnly = 1 in'
744 //===----------------------------------------------------------------------===//
745 // FP FMA Operations.
748 def VMLAD : ADbI<0b11100, 0b00, 0, 0,
749 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
750 IIC_fpMAC64, "vmla", ".f64\t$Dd, $Dn, $Dm",
751 [(set DPR:$Dd, (fadd (fmul DPR:$Dn, DPR:$Dm),
753 RegConstraint<"$Ddin = $Dd">,
754 Requires<[HasVFP2,UseVMLx]>;
756 def VMLAS : ASbIn<0b11100, 0b00, 0, 0,
757 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
758 IIC_fpMAC32, "vmla", ".f32\t$Sd, $Sn, $Sm",
759 [(set SPR:$Sd, (fadd (fmul SPR:$Sn, SPR:$Sm),
761 RegConstraint<"$Sdin = $Sd">,
762 Requires<[HasVFP2,DontUseNEONForFP,UseVMLx]>;
764 def : Pat<(fadd DPR:$dstin, (fmul DPR:$a, (f64 DPR:$b))),
765 (VMLAD DPR:$dstin, DPR:$a, DPR:$b)>,
766 Requires<[HasVFP2,UseVMLx]>;
767 def : Pat<(fadd SPR:$dstin, (fmul SPR:$a, SPR:$b)),
768 (VMLAS SPR:$dstin, SPR:$a, SPR:$b)>,
769 Requires<[HasVFP2,DontUseNEONForFP, UseVMLx]>;
771 def VMLSD : ADbI<0b11100, 0b00, 1, 0,
772 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
773 IIC_fpMAC64, "vmls", ".f64\t$Dd, $Dn, $Dm",
774 [(set DPR:$Dd, (fadd (fneg (fmul DPR:$Dn,DPR:$Dm)),
776 RegConstraint<"$Ddin = $Dd">,
777 Requires<[HasVFP2,UseVMLx]>;
779 def VMLSS : ASbIn<0b11100, 0b00, 1, 0,
780 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
781 IIC_fpMAC32, "vmls", ".f32\t$Sd, $Sn, $Sm",
782 [(set SPR:$Sd, (fadd (fneg (fmul SPR:$Sn, SPR:$Sm)),
784 RegConstraint<"$Sdin = $Sd">,
785 Requires<[HasVFP2,DontUseNEONForFP,UseVMLx]>;
787 def : Pat<(fsub DPR:$dstin, (fmul DPR:$a, (f64 DPR:$b))),
788 (VMLSD DPR:$dstin, DPR:$a, DPR:$b)>,
789 Requires<[HasVFP2,UseVMLx]>;
790 def : Pat<(fsub SPR:$dstin, (fmul SPR:$a, SPR:$b)),
791 (VMLSS SPR:$dstin, SPR:$a, SPR:$b)>,
792 Requires<[HasVFP2,DontUseNEONForFP,UseVMLx]>;
794 def VNMLAD : ADbI<0b11100, 0b01, 1, 0,
795 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
796 IIC_fpMAC64, "vnmla", ".f64\t$Dd, $Dn, $Dm",
797 [(set DPR:$Dd,(fsub (fneg (fmul DPR:$Dn,DPR:$Dm)),
799 RegConstraint<"$Ddin = $Dd">,
800 Requires<[HasVFP2,UseVMLx]>;
802 def VNMLAS : ASbI<0b11100, 0b01, 1, 0,
803 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
804 IIC_fpMAC32, "vnmla", ".f32\t$Sd, $Sn, $Sm",
805 [(set SPR:$Sd, (fsub (fneg (fmul SPR:$Sn, SPR:$Sm)),
807 RegConstraint<"$Sdin = $Sd">,
808 Requires<[HasVFP2,DontUseNEONForFP,UseVMLx]>;
810 def : Pat<(fsub (fneg (fmul DPR:$a, (f64 DPR:$b))), DPR:$dstin),
811 (VNMLAD DPR:$dstin, DPR:$a, DPR:$b)>,
812 Requires<[HasVFP2,UseVMLx]>;
813 def : Pat<(fsub (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin),
814 (VNMLAS SPR:$dstin, SPR:$a, SPR:$b)>,
815 Requires<[HasVFP2,DontUseNEONForFP,UseVMLx]>;
817 def VNMLSD : ADbI<0b11100, 0b01, 0, 0,
818 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
819 IIC_fpMAC64, "vnmls", ".f64\t$Dd, $Dn, $Dm",
820 [(set DPR:$Dd, (fsub (fmul DPR:$Dn, DPR:$Dm),
822 RegConstraint<"$Ddin = $Dd">,
823 Requires<[HasVFP2,UseVMLx]>;
825 def VNMLSS : ASbI<0b11100, 0b01, 0, 0,
826 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
827 IIC_fpMAC32, "vnmls", ".f32\t$Sd, $Sn, $Sm",
828 [(set SPR:$Sd, (fsub (fmul SPR:$Sn, SPR:$Sm), SPR:$Sdin))]>,
829 RegConstraint<"$Sdin = $Sd">,
830 Requires<[HasVFP2,DontUseNEONForFP,UseVMLx]>;
832 def : Pat<(fsub (fmul DPR:$a, (f64 DPR:$b)), DPR:$dstin),
833 (VNMLSD DPR:$dstin, DPR:$a, DPR:$b)>,
834 Requires<[HasVFP2,UseVMLx]>;
835 def : Pat<(fsub (fmul SPR:$a, SPR:$b), SPR:$dstin),
836 (VNMLSS SPR:$dstin, SPR:$a, SPR:$b)>,
837 Requires<[HasVFP2,DontUseNEONForFP,UseVMLx]>;
840 //===----------------------------------------------------------------------===//
841 // FP Conditional moves.
844 let neverHasSideEffects = 1 in {
845 def VMOVDcc : ADuI<0b11101, 0b11, 0b0000, 0b01, 0,
846 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
847 IIC_fpUNA64, "vmov", ".f64\t$Dd, $Dm",
848 [/*(set DPR:$Dd, (ARMcmov DPR:$Dn, DPR:$Dm, imm:$cc))*/]>,
849 RegConstraint<"$Dn = $Dd">;
851 def VMOVScc : ASuI<0b11101, 0b11, 0b0000, 0b01, 0,
852 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
853 IIC_fpUNA32, "vmov", ".f32\t$Sd, $Sm",
854 [/*(set SPR:$Sd, (ARMcmov SPR:$Sn, SPR:$Sm, imm:$cc))*/]>,
855 RegConstraint<"$Sn = $Sd">;
857 def VNEGDcc : ADuI<0b11101, 0b11, 0b0001, 0b01, 0,
858 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
859 IIC_fpUNA64, "vneg", ".f64\t$Dd, $Dm",
860 [/*(set DPR:$Dd, (ARMcneg DPR:$Dn, DPR:$Dm, imm:$cc))*/]>,
861 RegConstraint<"$Dn = $Dd">;
863 def VNEGScc : ASuI<0b11101, 0b11, 0b0001, 0b01, 0,
864 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
865 IIC_fpUNA32, "vneg", ".f32\t$Sd, $Sm",
866 [/*(set SPR:$Sd, (ARMcneg SPR:$Sn, SPR:$Sm, imm:$cc))*/]>,
867 RegConstraint<"$Sn = $Sd">;
868 } // neverHasSideEffects
870 //===----------------------------------------------------------------------===//
874 // APSR is the application level alias of CPSR. This FPSCR N, Z, C, V flags
876 let Defs = [CPSR], Uses = [FPSCR] in
877 def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT,
878 "vmrs", "\tapsr_nzcv, fpscr",
880 let Inst{27-20} = 0b11101111;
881 let Inst{19-16} = 0b0001;
882 let Inst{15-12} = 0b1111;
883 let Inst{11-8} = 0b1010;
885 let Inst{6-5} = 0b00;
887 let Inst{3-0} = 0b0000;
891 let hasSideEffects = 1, Uses = [FPSCR] in
892 def VMRS : VFPAI<(outs GPR:$Rt), (ins), VFPMiscFrm, IIC_fpSTAT,
893 "vmrs", "\t$Rt, fpscr",
894 [(set GPR:$Rt, (int_arm_get_fpscr))]> {
895 // Instruction operand.
898 // Encode instruction operand.
899 let Inst{15-12} = Rt;
901 let Inst{27-20} = 0b11101111;
902 let Inst{19-16} = 0b0001;
903 let Inst{11-8} = 0b1010;
905 let Inst{6-5} = 0b00;
907 let Inst{3-0} = 0b0000;
910 let Defs = [FPSCR] in
911 def VMSR : VFPAI<(outs), (ins GPR:$src), VFPMiscFrm, IIC_fpSTAT,
912 "vmsr", "\tfpscr, $src",
913 [(int_arm_set_fpscr GPR:$src)]> {
914 // Instruction operand.
917 // Encode instruction operand.
918 let Inst{15-12} = src;
920 let Inst{27-20} = 0b11101110;
921 let Inst{19-16} = 0b0001;
922 let Inst{11-8} = 0b1010;
927 // Materialize FP immediates. VFP3 only.
928 let isReMaterializable = 1 in {
929 def FCONSTD : VFPAI<(outs DPR:$Dd), (ins vfp_f64imm:$imm),
930 VFPMiscFrm, IIC_fpUNA64,
931 "vmov", ".f64\t$Dd, $imm",
932 [(set DPR:$Dd, vfp_f64imm:$imm)]>, Requires<[HasVFP3]> {
933 // Instruction operands.
937 // Encode instruction operands.
938 let Inst{15-12} = Dd{3-0};
939 let Inst{22} = Dd{4};
940 let Inst{19} = imm{31};
941 let Inst{18-16} = imm{22-20};
942 let Inst{3-0} = imm{19-16};
944 // Encode remaining instruction bits.
945 let Inst{27-23} = 0b11101;
946 let Inst{21-20} = 0b11;
947 let Inst{11-9} = 0b101;
948 let Inst{8} = 1; // Double precision.
949 let Inst{7-4} = 0b0000;
952 def FCONSTS : VFPAI<(outs SPR:$Sd), (ins vfp_f32imm:$imm),
953 VFPMiscFrm, IIC_fpUNA32,
954 "vmov", ".f32\t$Sd, $imm",
955 [(set SPR:$Sd, vfp_f32imm:$imm)]>, Requires<[HasVFP3]> {
956 // Instruction operands.
960 // Encode instruction operands.
961 let Inst{15-12} = Sd{4-1};
962 let Inst{22} = Sd{0};
963 let Inst{19} = imm{31}; // The immediate is handled as a double.
964 let Inst{18-16} = imm{22-20};
965 let Inst{3-0} = imm{19-16};
967 // Encode remaining instruction bits.
968 let Inst{27-23} = 0b11101;
969 let Inst{21-20} = 0b11;
970 let Inst{11-9} = 0b101;
971 let Inst{8} = 0; // Single precision.
972 let Inst{7-4} = 0b0000;