a404c97703080dcaccdd741d0b78c2b3f53aee20
[oota-llvm.git] / lib / Target / ARM / ARMInstrVFP.td
1 //===- ARMInstrVFP.td - VFP support for ARM ----------------*- tablegen -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file describes the ARM VFP instruction set.
11 //
12 //===----------------------------------------------------------------------===//
13
14 def SDT_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>,
18                                        SDTCisSameAs<1, 2>]>;
19
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>;
28
29
30 //===----------------------------------------------------------------------===//
31 // Operand Definitions.
32 //
33
34 def vfp_f32imm : Operand<f32>,
35                  PatLeaf<(f32 fpimm), [{
36       return ARM::getVFPf32Imm(N->getValueAPF()) != -1;
37     }]> {
38   let PrintMethod = "printVFPf32ImmOperand";
39 }
40
41 def vfp_f64imm : Operand<f64>,
42                  PatLeaf<(f64 fpimm), [{
43       return ARM::getVFPf64Imm(N->getValueAPF()) != -1;
44     }]> {
45   let PrintMethod = "printVFPf64ImmOperand";
46 }
47
48
49 //===----------------------------------------------------------------------===//
50 //  Load / store Instructions.
51 //
52
53 let canFoldAsLoad = 1, isReMaterializable = 1 in {
54 def VLDRD : ADI5<0b1101, 0b01, (outs DPR:$Dd), (ins addrmode5:$addr),
55                  IIC_fpLoad64, "vldr", ".64\t$Dd, $addr",
56                  [(set DPR:$Dd, (f64 (load addrmode5:$addr)))]>;
57
58 def VLDRS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr),
59                  IIC_fpLoad32, "vldr", ".32\t$dst, $addr",
60                  [(set SPR:$dst, (load addrmode5:$addr))]>;
61 } // canFoldAsLoad
62
63 def VSTRD  : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr),
64                  IIC_fpStore64, "vstr", ".64\t$src, $addr",
65                  [(store (f64 DPR:$src), addrmode5:$addr)]>;
66
67 def VSTRS  : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr),
68                  IIC_fpStore32, "vstr", ".32\t$src, $addr",
69                  [(store SPR:$src, addrmode5:$addr)]>;
70
71 //===----------------------------------------------------------------------===//
72 //  Load / store multiple Instructions.
73 //
74
75 let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
76 def VLDMD : AXDI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$dsts,
77                            variable_ops), IndexModeNone, IIC_fpLoad_m,
78                   "vldm${addr:submode}${p}\t$addr, $dsts", "", []> {
79   let Inst{20} = 1;
80 }
81
82 def VLDMS : AXSI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$dsts,
83                            variable_ops), IndexModeNone, IIC_fpLoad_m,
84                   "vldm${addr:submode}${p}\t$addr, $dsts", "", []> {
85   let Inst{20} = 1;
86 }
87
88 def VLDMD_UPD : AXDI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
89                                        reglist:$dsts, variable_ops),
90                       IndexModeUpd, IIC_fpLoad_mu,
91                       "vldm${addr:submode}${p}\t$addr!, $dsts",
92                       "$addr.addr = $wb", []> {
93   let Inst{20} = 1;
94 }
95
96 def VLDMS_UPD : AXSI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
97                                        reglist:$dsts, variable_ops),
98                       IndexModeUpd, IIC_fpLoad_mu, 
99                       "vldm${addr:submode}${p}\t$addr!, $dsts",
100                       "$addr.addr = $wb", []> {
101   let Inst{20} = 1;
102 }
103 } // mayLoad, neverHasSideEffects, hasExtraDefRegAllocReq
104
105 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
106 def VSTMD : AXDI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$srcs,
107                            variable_ops), IndexModeNone, IIC_fpStore_m,
108                   "vstm${addr:submode}${p}\t$addr, $srcs", "", []> {
109   let Inst{20} = 0;
110 }
111
112 def VSTMS : AXSI4<(outs), (ins addrmode4:$addr, pred:$p, reglist:$srcs,
113                            variable_ops), IndexModeNone, IIC_fpStore_m,
114                   "vstm${addr:submode}${p}\t$addr, $srcs", "", []> {
115   let Inst{20} = 0;
116 }
117
118 def VSTMD_UPD : AXDI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
119                                        reglist:$srcs, variable_ops),
120                       IndexModeUpd, IIC_fpStore_mu,
121                       "vstm${addr:submode}${p}\t$addr!, $srcs",
122                       "$addr.addr = $wb", []> {
123   let Inst{20} = 0;
124 }
125
126 def VSTMS_UPD : AXSI4<(outs GPR:$wb), (ins addrmode4:$addr, pred:$p,
127                                        reglist:$srcs, variable_ops),
128                       IndexModeUpd, IIC_fpStore_mu,
129                       "vstm${addr:submode}${p}\t$addr!, $srcs",
130                       "$addr.addr = $wb", []> {
131   let Inst{20} = 0;
132 }
133 } // mayStore, neverHasSideEffects, hasExtraSrcRegAllocReq
134
135 // FLDMX, FSTMX - mixing S/D registers for pre-armv6 cores
136
137
138 // FIXME: Can these be placed into the base class?
139 class ADbI_Encode<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
140                   dag iops, InstrItinClass itin, string opc, string asm,
141                   list<dag> pattern>
142   : ADbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
143   // Instruction operands.
144   bits<5> Dd;
145   bits<5> Dn;
146   bits<5> Dm;
147
148   // Encode instruction operands.
149   let Inst{3-0}   = Dm{3-0};
150   let Inst{5}     = Dm{4};
151   let Inst{19-16} = Dn{3-0};
152   let Inst{7}     = Dn{4};
153   let Inst{15-12} = Dd{3-0};
154   let Inst{22}    = Dd{4};
155 }
156
157 class ADuI_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
158                   bits<2> opcod4, bit opcod5, dag oops, dag iops,
159                   InstrItinClass itin, string opc, string asm,
160                   list<dag> pattern>
161   : ADuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc,
162          asm, pattern> {
163   // Instruction operands.
164   bits<5> Dd;
165   bits<5> Dm;
166
167   // Encode instruction operands.
168   let Inst{3-0}   = Dm{3-0};
169   let Inst{5}     = Dm{4};
170   let Inst{15-12} = Dd{3-0};
171   let Inst{22}    = Dd{4};
172 }
173
174 class ASbI_Encode<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
175                   dag iops, InstrItinClass itin, string opc, string asm,
176                   list<dag> pattern>
177   : ASbI<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
178   // Instruction operands.
179   bits<5> Sd;
180   bits<5> Sn;
181   bits<5> Sm;
182
183   // Encode instruction operands.
184   let Inst{3-0}   = Sm{4-1};
185   let Inst{5}     = Sm{0};
186   let Inst{19-16} = Sn{4-1};
187   let Inst{7}     = Sn{0};
188   let Inst{15-12} = Sd{4-1};
189   let Inst{22}    = Sd{0};
190 }
191
192 class ASbIn_Encode<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4, dag oops,
193                    dag iops, InstrItinClass itin, string opc, string asm,
194                    list<dag> pattern>
195   : ASbIn<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
196   // Instruction operands.
197   bits<5> Sd;
198   bits<5> Sn;
199   bits<5> Sm;
200
201   // Encode instruction operands.
202   let Inst{3-0}   = Sm{4-1};
203   let Inst{5}     = Sm{0};
204   let Inst{19-16} = Sn{4-1};
205   let Inst{7}     = Sn{0};
206   let Inst{15-12} = Sd{4-1};
207   let Inst{22}    = Sd{0};
208 }
209
210 class ASuI_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
211                   bits<2> opcod4, bit opcod5, dag oops, dag iops,
212                   InstrItinClass itin, string opc, string asm,
213                   list<dag> pattern>
214   : ASuI<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc,
215          asm, pattern> {
216   // Instruction operands.
217   bits<5> Sd;
218   bits<5> Sm;
219
220   // Encode instruction operands.
221   let Inst{3-0}   = Sm{4-1};
222   let Inst{5}     = Sm{0};
223   let Inst{15-12} = Sd{4-1};
224   let Inst{22}    = Sd{0};
225 }
226
227 class ASuIn_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
228                    bits<2> opcod4, bit opcod5, dag oops, dag iops,
229                    InstrItinClass itin, string opc, string asm,
230                    list<dag> pattern>
231   : ASuIn<opcod1, opcod2, opcod3, opcod4, opcod5, oops, iops, itin, opc,
232           asm, pattern> {
233   // Instruction operands.
234   bits<5> Sd;
235   bits<5> Sm;
236
237   // Encode instruction operands.
238   let Inst{3-0}   = Sm{4-1};
239   let Inst{5}     = Sm{0};
240   let Inst{15-12} = Sd{4-1};
241   let Inst{22}    = Sd{0};
242 }
243
244 //===----------------------------------------------------------------------===//
245 // FP Binary Operations.
246 //
247
248 def VADDD  : ADbI_Encode<0b11100, 0b11, 0, 0,
249                         (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
250                         IIC_fpALU64, "vadd", ".f64\t$Dd, $Dn, $Dm",
251                         [(set DPR:$Dd, (fadd DPR:$Dn, (f64 DPR:$Dm)))]>;
252
253 def VADDS  : ASbIn_Encode<0b11100, 0b11, 0, 0,
254                           (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
255                           IIC_fpALU32, "vadd", ".f32\t$Sd, $Sn, $Sm",
256                           [(set SPR:$Sd, (fadd SPR:$Sn, SPR:$Sm))]>;
257
258 def VSUBD  : ADbI_Encode<0b11100, 0b11, 1, 0,
259                          (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
260                          IIC_fpALU64, "vsub", ".f64\t$Dd, $Dn, $Dm",
261                          [(set DPR:$Dd, (fsub DPR:$Dn, (f64 DPR:$Dm)))]>;
262
263 def VSUBS  : ASbIn_Encode<0b11100, 0b11, 1, 0,
264                           (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
265                           IIC_fpALU32, "vsub", ".f32\t$Sd, $Sn, $Sm",
266                           [(set SPR:$Sd, (fsub SPR:$Sn, SPR:$Sm))]>;
267
268 def VDIVD  : ADbI_Encode<0b11101, 0b00, 0, 0,
269                          (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
270                          IIC_fpDIV64, "vdiv", ".f64\t$Dd, $Dn, $Dm",
271                          [(set DPR:$Dd, (fdiv DPR:$Dn, (f64 DPR:$Dm)))]>;
272
273 def VDIVS  : ASbI_Encode<0b11101, 0b00, 0, 0,
274                          (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
275                          IIC_fpDIV32, "vdiv", ".f32\t$Sd, $Sn, $Sm",
276                          [(set SPR:$Sd, (fdiv SPR:$Sn, SPR:$Sm))]>;
277
278 def VMULD  : ADbI_Encode<0b11100, 0b10, 0, 0,
279                          (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
280                          IIC_fpMUL64, "vmul", ".f64\t$Dd, $Dn, $Dm",
281                          [(set DPR:$Dd, (fmul DPR:$Dn, (f64 DPR:$Dm)))]>;
282
283 def VMULS  : ASbIn_Encode<0b11100, 0b10, 0, 0,
284                           (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
285                           IIC_fpMUL32, "vmul", ".f32\t$Sd, $Sn, $Sm",
286                           [(set SPR:$Sd, (fmul SPR:$Sn, SPR:$Sm))]>;
287
288 def VNMULD : ADbI_Encode<0b11100, 0b10, 1, 0,
289                          (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
290                          IIC_fpMUL64, "vnmul", ".f64\t$Dd, $Dn, $Dm",
291                          [(set DPR:$Dd, (fneg (fmul DPR:$Dn, (f64 DPR:$Dm))))]>;
292
293 def VNMULS : ASbI_Encode<0b11100, 0b10, 1, 0,
294                          (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
295                          IIC_fpMUL32, "vnmul", ".f32\t$Sd, $Sn, $Sm",
296                          [(set SPR:$Sd, (fneg (fmul SPR:$Sn, SPR:$Sm)))]>;
297
298 // Match reassociated forms only if not sign dependent rounding.
299 def : Pat<(fmul (fneg DPR:$a), (f64 DPR:$b)),
300           (VNMULD DPR:$a, DPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
301 def : Pat<(fmul (fneg SPR:$a), SPR:$b),
302           (VNMULS SPR:$a, SPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
303
304 // These are encoded as unary instructions.
305 let Defs = [FPSCR] in {
306 def VCMPED : ADuI_Encode<0b11101, 0b11, 0b0100, 0b11, 0,
307                          (outs), (ins DPR:$Dd, DPR:$Dm),
308                          IIC_fpCMP64, "vcmpe", ".f64\t$Dd, $Dm",
309                          [(arm_cmpfp DPR:$Dd, (f64 DPR:$Dm))]>;
310
311 def VCMPES : ASuI_Encode<0b11101, 0b11, 0b0100, 0b11, 0,
312                          (outs), (ins SPR:$Sd, SPR:$Sm),
313                          IIC_fpCMP32, "vcmpe", ".f32\t$Sd, $Sm",
314                          [(arm_cmpfp SPR:$Sd, SPR:$Sm)]>;
315
316 // FIXME: Verify encoding after integrated assembler is working.
317 def VCMPD  : ADuI_Encode<0b11101, 0b11, 0b0100, 0b01, 0,
318                          (outs), (ins DPR:$Dd, DPR:$Dm),
319                          IIC_fpCMP64, "vcmp", ".f64\t$Dd, $Dm",
320                          [/* For disassembly only; pattern left blank */]>;
321
322 def VCMPS  : ASuI_Encode<0b11101, 0b11, 0b0100, 0b01, 0,
323                          (outs), (ins SPR:$Sd, SPR:$Sm),
324                          IIC_fpCMP32, "vcmp", ".f32\t$Sd, $Sm",
325                          [/* For disassembly only; pattern left blank */]>;
326 }
327
328 //===----------------------------------------------------------------------===//
329 // FP Unary Operations.
330 //
331
332 def VABSD  : ADuI_Encode<0b11101, 0b11, 0b0000, 0b11, 0,
333                          (outs DPR:$Dd), (ins DPR:$Dm),
334                          IIC_fpUNA64, "vabs", ".f64\t$Dd, $Dm",
335                          [(set DPR:$Dd, (fabs (f64 DPR:$Dm)))]>;
336
337 def VABSS  : ASuIn_Encode<0b11101, 0b11, 0b0000, 0b11, 0,
338                           (outs SPR:$Sd), (ins SPR:$Sm),
339                           IIC_fpUNA32, "vabs", ".f32\t$Sd, $Sm",
340                           [(set SPR:$Sd, (fabs SPR:$Sm))]>;
341
342 let Defs = [FPSCR] in {
343 def VCMPEZD : ADuI_Encode<0b11101, 0b11, 0b0101, 0b11, 0,
344                           (outs), (ins DPR:$Dd),
345                           IIC_fpCMP64, "vcmpe", ".f64\t$Dd, #0",
346                           [(arm_cmpfp0 (f64 DPR:$Dd))]> {
347   let Inst{3-0}   = 0b0000;
348   let Inst{5}     = 0;
349 }
350
351 def VCMPEZS : ASuI_Encode<0b11101, 0b11, 0b0101, 0b11, 0,
352                          (outs), (ins SPR:$Sd),
353                          IIC_fpCMP32, "vcmpe", ".f32\t$Sd, #0",
354                          [(arm_cmpfp0 SPR:$Sd)]> {
355   let Inst{3-0}   = 0b0000;
356   let Inst{5}     = 0;
357 }
358
359 // FIXME: Verify encoding after integrated assembler is working.
360 def VCMPZD  : ADuI_Encode<0b11101, 0b11, 0b0101, 0b01, 0,
361                           (outs), (ins DPR:$Dd),
362                           IIC_fpCMP64, "vcmp", ".f64\t$Dd, #0",
363                           [/* For disassembly only; pattern left blank */]> {
364   let Inst{3-0}   = 0b0000;
365   let Inst{5}     = 0;
366 }
367
368 def VCMPZS  : ASuI_Encode<0b11101, 0b11, 0b0101, 0b01, 0,
369                           (outs), (ins SPR:$Sd),
370                           IIC_fpCMP32, "vcmp", ".f32\t$Sd, #0",
371                           [/* For disassembly only; pattern left blank */]> {
372   let Inst{3-0}   = 0b0000;
373   let Inst{5}     = 0;
374 }
375 }
376
377 def VCVTDS  : ASuI<0b11101, 0b11, 0b0111, 0b11, 0,
378                    (outs DPR:$Dd), (ins SPR:$Sm),
379                    IIC_fpCVTDS, "vcvt", ".f64.f32\t$Dd, $Sm",
380                    [(set DPR:$Dd, (fextend SPR:$Sm))]> {
381   // Instruction operands.
382   bits<5> Dd;
383   bits<5> Sm;
384
385   // Encode instruction operands.
386   let Inst{3-0}   = Sm{4-1};
387   let Inst{5}     = Sm{0};
388   let Inst{15-12} = Dd{3-0};
389   let Inst{22}    = Dd{4};
390 }
391
392 // Special case encoding: bits 11-8 is 0b1011.
393 def VCVTSD  : VFPAI<(outs SPR:$Sd), (ins DPR:$Dm), VFPUnaryFrm,
394                     IIC_fpCVTSD, "vcvt", ".f32.f64\t$Sd, $Dm",
395                     [(set SPR:$Sd, (fround DPR:$Dm))]> {
396   // Instruction operands.
397   bits<5> Sd;
398   bits<5> Dm;
399
400   // Encode instruction operands.
401   let Inst{3-0}   = Dm{3-0};
402   let Inst{5}     = Dm{4};
403   let Inst{15-12} = Sd{4-1};
404   let Inst{22}    = Sd{0};
405
406   let Inst{27-23} = 0b11101;
407   let Inst{21-16} = 0b110111;
408   let Inst{11-8}  = 0b1011;
409   let Inst{7-6}   = 0b11;
410   let Inst{4}     = 0;
411 }
412
413 // Between half-precision and single-precision.  For disassembly only.
414
415 // FIXME: Verify encoding after integrated assembler is working.
416 def VCVTBSH: ASuI<0b11101, 0b11, 0b0010, 0b01, 0, (outs SPR:$dst), (ins SPR:$a),
417                  /* FIXME */ IIC_fpCVTSH, "vcvtb", ".f32.f16\t$dst, $a",
418                  [/* For disassembly only; pattern left blank */]>;
419
420 def : ARMPat<(f32_to_f16 SPR:$a),
421              (i32 (COPY_TO_REGCLASS (VCVTBSH SPR:$a), GPR))>;
422
423 def VCVTBHS: ASuI<0b11101, 0b11, 0b0011, 0b01, 0, (outs SPR:$dst), (ins SPR:$a),
424                  /* FIXME */ IIC_fpCVTHS, "vcvtb", ".f16.f32\t$dst, $a",
425                  [/* For disassembly only; pattern left blank */]>;
426
427 def : ARMPat<(f16_to_f32 GPR:$a),
428              (VCVTBHS (COPY_TO_REGCLASS GPR:$a, SPR))>;
429
430 def VCVTTSH: ASuI<0b11101, 0b11, 0b0010, 0b11, 0, (outs SPR:$dst), (ins SPR:$a),
431                  /* FIXME */ IIC_fpCVTSH, "vcvtt", ".f32.f16\t$dst, $a",
432                  [/* For disassembly only; pattern left blank */]>;
433
434 def VCVTTHS: ASuI<0b11101, 0b11, 0b0011, 0b11, 0, (outs SPR:$dst), (ins SPR:$a),
435                  /* FIXME */ IIC_fpCVTHS, "vcvtt", ".f16.f32\t$dst, $a",
436                  [/* For disassembly only; pattern left blank */]>;
437
438 def VNEGD  : ADuI_Encode<0b11101, 0b11, 0b0001, 0b01, 0,
439                          (outs DPR:$Dd), (ins DPR:$Dm),
440                          IIC_fpUNA64, "vneg", ".f64\t$Dd, $Dm",
441                          [(set DPR:$Dd, (fneg (f64 DPR:$Dm)))]>;
442
443 def VNEGS  : ASuIn_Encode<0b11101, 0b11, 0b0001, 0b01, 0,
444                           (outs SPR:$Sd), (ins SPR:$Sm),
445                           IIC_fpUNA32, "vneg", ".f32\t$Sd, $Sm",
446                           [(set SPR:$Sd, (fneg SPR:$Sm))]>;
447
448 def VSQRTD : ADuI_Encode<0b11101, 0b11, 0b0001, 0b11, 0,
449                          (outs DPR:$Dd), (ins DPR:$Dm),
450                          IIC_fpSQRT64, "vsqrt", ".f64\t$Dd, $Dm",
451                          [(set DPR:$Dd, (fsqrt (f64 DPR:$Dm)))]>;
452
453 def VSQRTS : ASuI_Encode<0b11101, 0b11, 0b0001, 0b11, 0,
454                          (outs SPR:$Sd), (ins SPR:$Sm),
455                          IIC_fpSQRT32, "vsqrt", ".f32\t$Sd, $Sm",
456                          [(set SPR:$Sd, (fsqrt SPR:$Sm))]>;
457
458 let neverHasSideEffects = 1 in {
459 def VMOVD  : ADuI_Encode<0b11101, 0b11, 0b0000, 0b01, 0,
460                          (outs DPR:$Dd), (ins DPR:$Dm),
461                          IIC_fpUNA64, "vmov", ".f64\t$Dd, $Dm", []>;
462
463 def VMOVS  : ASuI_Encode<0b11101, 0b11, 0b0000, 0b01, 0,
464                          (outs SPR:$Sd), (ins SPR:$Sm),
465                          IIC_fpUNA32, "vmov", ".f32\t$Sd, $Sm", []>;
466 } // neverHasSideEffects
467
468 //===----------------------------------------------------------------------===//
469 // FP <-> GPR Copies.  Int <-> FP Conversions.
470 //
471
472 def VMOVRS : AVConv2I<0b11100001, 0b1010,
473                       (outs GPR:$Rt), (ins SPR:$Sn),
474                       IIC_fpMOVSI, "vmov", "\t$Rt, $Sn",
475                       [(set GPR:$Rt, (bitconvert SPR:$Sn))]> {
476   // Instruction operands.
477   bits<4> Rt;
478   bits<5> Sn;
479
480   // Encode instruction operands.
481   let Inst{19-16} = Sn{4-1};
482   let Inst{7}     = Sn{0};
483   let Inst{15-12} = Rt;
484
485   let Inst{6-5}   = 0b00;
486   let Inst{3-0}   = 0b0000;
487 }
488
489 def VMOVSR : AVConv4I<0b11100000, 0b1010,
490                       (outs SPR:$Sn), (ins GPR:$Rt),
491                       IIC_fpMOVIS, "vmov", "\t$Sn, $Rt",
492                       [(set SPR:$Sn, (bitconvert GPR:$Rt))]> {
493   // Instruction operands.
494   bits<5> Sn;
495   bits<4> Rt;
496
497   // Encode instruction operands.
498   let Inst{19-16} = Sn{4-1};
499   let Inst{7}     = Sn{0};
500   let Inst{15-12} = Rt;
501
502   let Inst{6-5}   = 0b00;
503   let Inst{3-0}   = 0b0000;
504 }
505
506 let neverHasSideEffects = 1 in {
507 def VMOVRRD  : AVConv3I<0b11000101, 0b1011,
508                         (outs GPR:$Rt, GPR:$Rt2), (ins DPR:$Dm),
509                         IIC_fpMOVDI, "vmov", "\t$Rt, $Rt2, $Dm",
510                  [/* FIXME: Can't write pattern for multiple result instr*/]> {
511   // Instruction operands.
512   bits<5> Dm;
513   bits<4> Rt;
514   bits<4> Rt2;
515
516   // Encode instruction operands.
517   let Inst{3-0}   = Dm{3-0};
518   let Inst{5}     = Dm{4};
519   let Inst{15-12} = Rt;
520   let Inst{19-16} = Rt2;
521
522   let Inst{7-6} = 0b00;
523 }
524
525 def VMOVRRS  : AVConv3I<0b11000101, 0b1010,
526                       (outs GPR:$wb, GPR:$dst2), (ins SPR:$src1, SPR:$src2),
527                  IIC_fpMOVDI, "vmov", "\t$wb, $dst2, $src1, $src2",
528                  [/* For disassembly only; pattern left blank */]> {
529   let Inst{7-6} = 0b00;
530 }
531 } // neverHasSideEffects
532
533 // FMDHR: GPR -> SPR
534 // FMDLR: GPR -> SPR
535
536 def VMOVDRR : AVConv5I<0b11000100, 0b1011,
537                       (outs DPR:$Dm), (ins GPR:$Rt, GPR:$Rt2),
538                       IIC_fpMOVID, "vmov", "\t$Dm, $Rt, $Rt2",
539                       [(set DPR:$Dm, (arm_fmdrr GPR:$Rt, GPR:$Rt2))]> {
540   // Instruction operands.
541   bits<5> Dm;
542   bits<4> Rt;
543   bits<4> Rt2;
544
545   // Encode instruction operands.
546   let Inst{3-0}   = Dm{3-0};
547   let Inst{5}     = Dm{4};
548   let Inst{15-12} = Rt;
549   let Inst{19-16} = Rt2;
550
551   let Inst{7-6}   = 0b00;
552 }
553
554 let neverHasSideEffects = 1 in
555 def VMOVSRR : AVConv5I<0b11000100, 0b1010,
556                      (outs SPR:$dst1, SPR:$dst2), (ins GPR:$src1, GPR:$src2),
557                 IIC_fpMOVID, "vmov", "\t$dst1, $dst2, $src1, $src2",
558                 [/* For disassembly only; pattern left blank */]> {
559   let Inst{7-6} = 0b00;
560 }
561
562 // FMRDH: SPR -> GPR
563 // FMRDL: SPR -> GPR
564 // FMRRS: SPR -> GPR
565 // FMRX:  SPR system reg -> GPR
566 // FMSRR: GPR -> SPR
567 // FMXR:  GPR -> VFP system reg
568
569
570 // Int -> FP:
571
572 class AVConv1IDs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
573                         bits<4> opcod4, dag oops, dag iops,
574                         InstrItinClass itin, string opc, string asm,
575                         list<dag> pattern>
576   : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
577              pattern> {
578   // Instruction operands.
579   bits<5> Dd;
580   bits<5> Sm;
581
582   // Encode instruction operands.
583   let Inst{3-0}   = Sm{4-1};
584   let Inst{5}     = Sm{0};
585   let Inst{15-12} = Dd{3-0};
586   let Inst{22}    = Dd{4};
587 }
588
589 class AVConv1InSs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
590                          bits<4> opcod4, dag oops, dag iops,InstrItinClass itin,
591                          string opc, string asm, list<dag> pattern>
592   : AVConv1In<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
593               pattern> {
594   // Instruction operands.
595   bits<5> Sd;
596   bits<5> Sm;
597
598   // Encode instruction operands.
599   let Inst{3-0}   = Sm{4-1};
600   let Inst{5}     = Sm{0};
601   let Inst{15-12} = Sd{4-1};
602   let Inst{22}    = Sd{0};
603 }
604
605 def VSITOD : AVConv1IDs_Encode<0b11101, 0b11, 0b1000, 0b1011,
606                                (outs DPR:$Dd), (ins SPR:$Sm),
607                                IIC_fpCVTID, "vcvt", ".f64.s32\t$Dd, $Sm",
608                                [(set DPR:$Dd, (f64 (arm_sitof SPR:$Sm)))]> {
609   let Inst{7} = 1; // s32
610 }
611
612 def VSITOS : AVConv1InSs_Encode<0b11101, 0b11, 0b1000, 0b1010,
613                                 (outs SPR:$Sd),(ins SPR:$Sm),
614                                 IIC_fpCVTIS, "vcvt", ".f32.s32\t$Sd, $Sm",
615                                 [(set SPR:$Sd, (arm_sitof SPR:$Sm))]> {
616   let Inst{7} = 1; // s32
617 }
618
619 def VUITOD : AVConv1IDs_Encode<0b11101, 0b11, 0b1000, 0b1011,
620                                (outs DPR:$Dd), (ins SPR:$Sm),
621                                IIC_fpCVTID, "vcvt", ".f64.u32\t$Dd, $Sm",
622                                [(set DPR:$Dd, (f64 (arm_uitof SPR:$Sm)))]> {
623   let Inst{7} = 0; // u32
624 }
625
626 def VUITOS : AVConv1InSs_Encode<0b11101, 0b11, 0b1000, 0b1010,
627                                 (outs SPR:$Sd), (ins SPR:$Sm),
628                                 IIC_fpCVTIS, "vcvt", ".f32.u32\t$Sd, $Sm",
629                                 [(set SPR:$Sd, (arm_uitof SPR:$Sm))]> {
630   let Inst{7} = 0; // u32
631 }
632
633 // FP -> Int:
634
635 class AVConv1IsD_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
636                         bits<4> opcod4, dag oops, dag iops,
637                         InstrItinClass itin, string opc, string asm,
638                         list<dag> pattern>
639   : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
640              pattern> {
641   // Instruction operands.
642   bits<5> Sd;
643   bits<5> Dm;
644
645   // Encode instruction operands.
646   let Inst{3-0}   = Dm{3-0};
647   let Inst{5}     = Dm{4};
648   let Inst{15-12} = Sd{4-1};
649   let Inst{22}    = Sd{0};
650 }
651
652 class AVConv1InsS_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
653                          bits<4> opcod4, dag oops, dag iops,
654                          InstrItinClass itin, string opc, string asm,
655                          list<dag> pattern>
656   : AVConv1In<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
657               pattern> {
658   // Instruction operands.
659   bits<5> Sd;
660   bits<5> Sm;
661
662   // Encode instruction operands.
663   let Inst{3-0}   = Sm{4-1};
664   let Inst{5}     = Sm{0};
665   let Inst{15-12} = Sd{4-1};
666   let Inst{22}    = Sd{0};
667 }
668
669 // Always set Z bit in the instruction, i.e. "round towards zero" variants.
670 def VTOSIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011,
671                                 (outs SPR:$Sd), (ins DPR:$Dm),
672                                 IIC_fpCVTDI, "vcvt", ".s32.f64\t$Sd, $Dm",
673                                 [(set SPR:$Sd, (arm_ftosi (f64 DPR:$Dm)))]> {
674   let Inst{7} = 1; // Z bit
675 }
676
677 def VTOSIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010,
678                                  (outs SPR:$Sd), (ins SPR:$Sm),
679                                  IIC_fpCVTSI, "vcvt", ".s32.f32\t$Sd, $Sm",
680                                  [(set SPR:$Sd, (arm_ftosi SPR:$Sm))]> {
681   let Inst{7} = 1; // Z bit
682 }
683
684 def VTOUIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011,
685                                (outs SPR:$Sd), (ins DPR:$Dm),
686                                IIC_fpCVTDI, "vcvt", ".u32.f64\t$Sd, $Dm",
687                                [(set SPR:$Sd, (arm_ftoui (f64 DPR:$Dm)))]> {
688   let Inst{7} = 1; // Z bit
689 }
690
691 def VTOUIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010,
692                                  (outs SPR:$Sd), (ins SPR:$Sm),
693                                  IIC_fpCVTSI, "vcvt", ".u32.f32\t$Sd, $Sm",
694                                  [(set SPR:$Sd, (arm_ftoui SPR:$Sm))]> {
695   let Inst{7} = 1; // Z bit
696 }
697
698 // And the Z bit '0' variants, i.e. use the rounding mode specified by FPSCR.
699 // For disassembly only.
700 let Uses = [FPSCR] in {
701 // FIXME: Verify encoding after integrated assembler is working.
702 def VTOSIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011,
703                                 (outs SPR:$Sd), (ins DPR:$Dm),
704                                 IIC_fpCVTDI, "vcvtr", ".s32.f64\t$Sd, $Dm",
705                                 [(set SPR:$Sd, (int_arm_vcvtr (f64 DPR:$Dm)))]>{
706   let Inst{7} = 0; // Z bit
707 }
708
709 def VTOSIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010,
710                                  (outs SPR:$Sd), (ins SPR:$Sm),
711                                  IIC_fpCVTSI, "vcvtr", ".s32.f32\t$Sd, $Sm",
712                                  [(set SPR:$Sd, (int_arm_vcvtr SPR:$Sm))]> {
713   let Inst{7} = 0; // Z bit
714 }
715
716 def VTOUIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011,
717                                 (outs SPR:$Sd), (ins DPR:$Dm),
718                                 IIC_fpCVTDI, "vcvtr", ".u32.f64\t$Sd, $Dm",
719                                 [(set SPR:$Sd, (int_arm_vcvtru(f64 DPR:$Dm)))]>{
720   let Inst{7} = 0; // Z bit
721 }
722
723 def VTOUIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010,
724                                  (outs SPR:$Sd), (ins SPR:$Sm),
725                                  IIC_fpCVTSI, "vcvtr", ".u32.f32\t$Sd, $Sm",
726                                  [(set SPR:$Sd, (int_arm_vcvtru SPR:$Sm))]> {
727   let Inst{7} = 0; // Z bit
728 }
729 }
730
731 // Convert between floating-point and fixed-point
732 // Data type for fixed-point naming convention:
733 //   S16 (U=0, sx=0) -> SH
734 //   U16 (U=1, sx=0) -> UH
735 //   S32 (U=0, sx=1) -> SL
736 //   U32 (U=1, sx=1) -> UL
737
738 let Constraints = "$a = $dst" in {
739
740 // FP to Fixed-Point:
741
742 let isCodeGenOnly = 1 in {
743 def VTOSHS : AVConv1XI<0b11101, 0b11, 0b1110, 0b1010, 0,
744                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
745                  IIC_fpCVTSI, "vcvt", ".s16.f32\t$dst, $a, $fbits",
746                  [/* For disassembly only; pattern left blank */]>;
747
748 def VTOUHS : AVConv1XI<0b11101, 0b11, 0b1111, 0b1010, 0,
749                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
750                  IIC_fpCVTSI, "vcvt", ".u16.f32\t$dst, $a, $fbits",
751                  [/* For disassembly only; pattern left blank */]>;
752
753 def VTOSLS : AVConv1XI<0b11101, 0b11, 0b1110, 0b1010, 1,
754                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
755                  IIC_fpCVTSI, "vcvt", ".s32.f32\t$dst, $a, $fbits",
756                  [/* For disassembly only; pattern left blank */]>;
757
758 def VTOULS : AVConv1XI<0b11101, 0b11, 0b1111, 0b1010, 1,
759                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
760                  IIC_fpCVTSI, "vcvt", ".u32.f32\t$dst, $a, $fbits",
761                  [/* For disassembly only; pattern left blank */]>;
762
763 def VTOSHD : AVConv1XI<0b11101, 0b11, 0b1110, 0b1011, 0,
764                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
765                  IIC_fpCVTDI, "vcvt", ".s16.f64\t$dst, $a, $fbits",
766                  [/* For disassembly only; pattern left blank */]>;
767
768 def VTOUHD : AVConv1XI<0b11101, 0b11, 0b1111, 0b1011, 0,
769                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
770                  IIC_fpCVTDI, "vcvt", ".u16.f64\t$dst, $a, $fbits",
771                  [/* For disassembly only; pattern left blank */]>;
772
773 def VTOSLD : AVConv1XI<0b11101, 0b11, 0b1110, 0b1011, 1,
774                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
775                  IIC_fpCVTDI, "vcvt", ".s32.f64\t$dst, $a, $fbits",
776                  [/* For disassembly only; pattern left blank */]>;
777
778 def VTOULD : AVConv1XI<0b11101, 0b11, 0b1111, 0b1011, 1,
779                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
780                  IIC_fpCVTDI, "vcvt", ".u32.f64\t$dst, $a, $fbits",
781                  [/* For disassembly only; pattern left blank */]>;
782 } // End of 'let isCodeGenOnly = 1 in'
783
784 // Fixed-Point to FP:
785
786 let isCodeGenOnly = 1 in {
787 def VSHTOS : AVConv1XI<0b11101, 0b11, 0b1010, 0b1010, 0,
788                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
789                  IIC_fpCVTIS, "vcvt", ".f32.s16\t$dst, $a, $fbits",
790                  [/* For disassembly only; pattern left blank */]>;
791
792 def VUHTOS : AVConv1XI<0b11101, 0b11, 0b1011, 0b1010, 0,
793                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
794                  IIC_fpCVTIS, "vcvt", ".f32.u16\t$dst, $a, $fbits",
795                  [/* For disassembly only; pattern left blank */]>;
796
797 def VSLTOS : AVConv1XI<0b11101, 0b11, 0b1010, 0b1010, 1,
798                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
799                  IIC_fpCVTIS, "vcvt", ".f32.s32\t$dst, $a, $fbits",
800                  [/* For disassembly only; pattern left blank */]>;
801
802 def VULTOS : AVConv1XI<0b11101, 0b11, 0b1011, 0b1010, 1,
803                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
804                  IIC_fpCVTIS, "vcvt", ".f32.u32\t$dst, $a, $fbits",
805                  [/* For disassembly only; pattern left blank */]>;
806
807 def VSHTOD : AVConv1XI<0b11101, 0b11, 0b1010, 0b1011, 0,
808                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
809                  IIC_fpCVTID, "vcvt", ".f64.s16\t$dst, $a, $fbits",
810                  [/* For disassembly only; pattern left blank */]>;
811
812 def VUHTOD : AVConv1XI<0b11101, 0b11, 0b1011, 0b1011, 0,
813                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
814                  IIC_fpCVTID, "vcvt", ".f64.u16\t$dst, $a, $fbits",
815                  [/* For disassembly only; pattern left blank */]>;
816
817 def VSLTOD : AVConv1XI<0b11101, 0b11, 0b1010, 0b1011, 1,
818                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
819                  IIC_fpCVTID, "vcvt", ".f64.s32\t$dst, $a, $fbits",
820                  [/* For disassembly only; pattern left blank */]>;
821
822 def VULTOD : AVConv1XI<0b11101, 0b11, 0b1011, 0b1011, 1,
823                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
824                  IIC_fpCVTID, "vcvt", ".f64.u32\t$dst, $a, $fbits",
825                  [/* For disassembly only; pattern left blank */]>;
826 } // End of 'let isCodeGenOnly = 1 in'
827
828 } // End of 'let Constraints = "$src = $dst" in'
829
830 //===----------------------------------------------------------------------===//
831 // FP FMA Operations.
832 //
833
834 class ADbI_vmlX_Encode<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4,
835                        dag oops, dag iops, InstrItinClass itin, string opc,
836                        string asm, list<dag> pattern>
837   : ADbI_vmlX<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
838   // Instruction operands.
839   bits<5> Dd;
840   bits<5> Dn;
841   bits<5> Dm;
842
843   // Encode instruction operands.
844   let Inst{19-16} = Dn{3-0};
845   let Inst{7}     = Dn{4};
846   let Inst{15-12} = Dd{3-0};
847   let Inst{22}    = Dd{4};
848   let Inst{3-0}   = Dm{3-0};
849   let Inst{5}     = Dm{4};
850 }
851
852 def VMLAD : ADbI_vmlX_Encode<0b11100, 0b00, 0, 0,
853                              (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
854                              IIC_fpMAC64, "vmla", ".f64\t$Dd, $Dn, $Dm",
855                              [(set DPR:$Dd, (fadd (fmul DPR:$Dn, DPR:$Dm),
856                                                   (f64 DPR:$Ddin)))]>,
857                              RegConstraint<"$Ddin = $Dd">;
858
859 def VMLAS : ASbIn_Encode<0b11100, 0b00, 0, 0,
860                          (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
861                          IIC_fpMAC32, "vmla", ".f32\t$Sd, $Sn, $Sm",
862                          [(set SPR:$Sd, (fadd (fmul SPR:$Sn, SPR:$Sm),
863                                               SPR:$Sdin))]>,
864                          RegConstraint<"$Sdin = $Sd">;
865
866 def : Pat<(fadd DPR:$dstin, (fmul DPR:$a, (f64 DPR:$b))),
867           (VMLAD DPR:$dstin, DPR:$a, DPR:$b)>, Requires<[DontUseNEONForFP]>;
868 def : Pat<(fadd SPR:$dstin, (fmul SPR:$a, SPR:$b)),
869           (VMLAS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[DontUseNEONForFP]>;
870
871 def VMLSD : ADbI_vmlX_Encode<0b11100, 0b00, 1, 0,
872                              (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
873                              IIC_fpMAC64, "vmls", ".f64\t$Dd, $Dn, $Dm",
874                              [(set DPR:$Dd, (fadd (fneg (fmul DPR:$Dn,DPR:$Dm)),
875                                                         (f64 DPR:$Ddin)))]>,
876                              RegConstraint<"$Ddin = $Dd">;
877
878 def VMLSS : ASbIn_Encode<0b11100, 0b00, 1, 0,
879                          (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
880                          IIC_fpMAC32, "vmls", ".f32\t$Sd, $Sn, $Sm",
881                          [(set SPR:$Sd, (fadd (fneg (fmul SPR:$Sn, SPR:$Sm)),
882                                                     SPR:$Sdin))]>,
883                          RegConstraint<"$Sdin = $Sd">;
884
885 def : Pat<(fsub DPR:$dstin, (fmul DPR:$a, (f64 DPR:$b))),
886           (VMLSD DPR:$dstin, DPR:$a, DPR:$b)>, Requires<[DontUseNEONForFP]>;
887 def : Pat<(fsub SPR:$dstin, (fmul SPR:$a, SPR:$b)),
888           (VMLSS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[DontUseNEONForFP]>;
889
890 def VNMLAD : ADbI_vmlX_Encode<0b11100, 0b01, 1, 0,
891                               (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
892                               IIC_fpMAC64, "vnmla", ".f64\t$Dd, $Dn, $Dm",
893                               [(set DPR:$Dd,(fsub (fneg (fmul DPR:$Dn,DPR:$Dm)),
894                                                   (f64 DPR:$Ddin)))]>,
895                 RegConstraint<"$Ddin = $Dd">;
896
897 def VNMLAS : ASbI_Encode<0b11100, 0b01, 1, 0,
898                          (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
899                          IIC_fpMAC32, "vnmla", ".f32\t$Sd, $Sn, $Sm",
900                          [(set SPR:$Sd, (fsub (fneg (fmul SPR:$Sn, SPR:$Sm)),
901                                               SPR:$Sdin))]>,
902                          RegConstraint<"$Sdin = $Sd">;
903
904 def : Pat<(fsub (fneg (fmul DPR:$a, (f64 DPR:$b))), DPR:$dstin),
905           (VNMLAD DPR:$dstin, DPR:$a, DPR:$b)>, Requires<[DontUseNEONForFP]>;
906 def : Pat<(fsub (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin),
907           (VNMLAS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[DontUseNEONForFP]>;
908
909 def VNMLSD : ADbI_vmlX_Encode<0b11100, 0b01, 0, 0,
910                               (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
911                               IIC_fpMAC64, "vnmls", ".f64\t$Dd, $Dn, $Dm",
912                               [(set DPR:$Dd, (fsub (fmul DPR:$Dn, DPR:$Dm),
913                                                    (f64 DPR:$Ddin)))]>,
914                               RegConstraint<"$Ddin = $Dd">;
915
916 def VNMLSS : ASbI_Encode<0b11100, 0b01, 0, 0,
917                          (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
918                          IIC_fpMAC32, "vnmls", ".f32\t$Sd, $Sn, $Sm",
919                          [(set SPR:$Sd, (fsub (fmul SPR:$Sn, SPR:$Sm),
920                                               SPR:$Sdin))]>,
921                          RegConstraint<"$Sdin = $Sd">;
922
923 def : Pat<(fsub (fmul DPR:$a, (f64 DPR:$b)), DPR:$dstin),
924           (VNMLSD DPR:$dstin, DPR:$a, DPR:$b)>, Requires<[DontUseNEONForFP]>;
925 def : Pat<(fsub (fmul SPR:$a, SPR:$b), SPR:$dstin),
926           (VNMLSS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[DontUseNEONForFP]>;
927
928
929 //===----------------------------------------------------------------------===//
930 // FP Conditional moves.
931 //
932
933 let neverHasSideEffects = 1 in {
934 def VMOVDcc  : ADuI_Encode<0b11101, 0b11, 0b0000, 0b01, 0,
935                            (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
936                            IIC_fpUNA64, "vmov", ".f64\t$Dd, $Dm",
937                       [/*(set DPR:$Dd, (ARMcmov DPR:$Dn, DPR:$Dm, imm:$cc))*/]>,
938                            RegConstraint<"$Dn = $Dd">;
939
940 def VMOVScc  : ASuI_Encode<0b11101, 0b11, 0b0000, 0b01, 0,
941                            (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
942                            IIC_fpUNA32, "vmov", ".f32\t$Sd, $Sm",
943                       [/*(set SPR:$Sd, (ARMcmov SPR:$Sn, SPR:$Sm, imm:$cc))*/]>,
944                            RegConstraint<"$Sn = $Sd">;
945
946 def VNEGDcc  : ADuI_Encode<0b11101, 0b11, 0b0001, 0b01, 0,
947                            (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
948                            IIC_fpUNA64, "vneg", ".f64\t$Dd, $Dm",
949                       [/*(set DPR:$Dd, (ARMcneg DPR:$Dn, DPR:$Dm, imm:$cc))*/]>,
950                            RegConstraint<"$Dn = $Dd">;
951
952 def VNEGScc  : ASuI_Encode<0b11101, 0b11, 0b0001, 0b01, 0,
953                            (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
954                            IIC_fpUNA32, "vneg", ".f32\t$Sd, $Sm",
955                       [/*(set SPR:$Sd, (ARMcneg SPR:$Sn, SPR:$Sm, imm:$cc))*/]>,
956                            RegConstraint<"$Sn = $Sd">;
957 } // neverHasSideEffects
958
959 //===----------------------------------------------------------------------===//
960 // Misc.
961 //
962
963 // APSR is the application level alias of CPSR. This FPSCR N, Z, C, V flags
964 // to APSR.
965 let Defs = [CPSR], Uses = [FPSCR] in
966 def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "vmrs",
967                    "\tapsr_nzcv, fpscr",
968                    [(arm_fmstat)]> {
969   let Inst{27-20} = 0b11101111;
970   let Inst{19-16} = 0b0001;
971   let Inst{15-12} = 0b1111;
972   let Inst{11-8}  = 0b1010;
973   let Inst{7}     = 0;
974   let Inst{6-5}   = 0b00;
975   let Inst{4}     = 1;
976   let Inst{3-0}   = 0b0000;
977 }
978
979 // FPSCR <-> GPR
980 let hasSideEffects = 1, Uses = [FPSCR] in
981 def VMRS : VFPAI<(outs GPR:$Rt), (ins), VFPMiscFrm, IIC_fpSTAT,
982                  "vmrs", "\t$Rt, fpscr",
983                  [(set GPR:$Rt, (int_arm_get_fpscr))]> {
984   // Instruction operand.
985   bits<4> Rt;
986
987   // Encode instruction operand.
988   let Inst{15-12} = Rt;
989
990   let Inst{27-20} = 0b11101111;
991   let Inst{19-16} = 0b0001;
992   let Inst{11-8}  = 0b1010;
993   let Inst{7}     = 0;
994   let Inst{6-5}   = 0b00;
995   let Inst{4}     = 1;
996   let Inst{3-0}   = 0b0000;
997 }
998
999 let Defs = [FPSCR] in 
1000 def VMSR : VFPAI<(outs), (ins GPR:$src), VFPMiscFrm, IIC_fpSTAT, 
1001                  "vmsr", "\tfpscr, $src",
1002                  [(int_arm_set_fpscr GPR:$src)]> {
1003   // Instruction operand.
1004   bits<4> src;
1005
1006   // Encode instruction operand.
1007   let Inst{15-12} = src;
1008
1009   let Inst{27-20} = 0b11101110;
1010   let Inst{19-16} = 0b0001;
1011   let Inst{11-8}  = 0b1010;
1012   let Inst{7}     = 0;
1013   let Inst{4}     = 1;
1014 }
1015
1016 // Materialize FP immediates. VFP3 only.
1017 let isReMaterializable = 1 in {
1018 def FCONSTD : VFPAI<(outs DPR:$Dd), (ins vfp_f64imm:$imm),
1019                     VFPMiscFrm, IIC_fpUNA64,
1020                     "vmov", ".f64\t$Dd, $imm",
1021                     [(set DPR:$Dd, vfp_f64imm:$imm)]>, Requires<[HasVFP3]> {
1022   // Instruction operands.
1023   bits<5>  Dd;
1024   bits<32> imm;
1025
1026   // Encode instruction operands.
1027   let Inst{15-12} = Dd{3-0};
1028   let Inst{22}    = Dd{4};
1029   let Inst{19}    = imm{31};
1030   let Inst{18-16} = imm{22-20};
1031   let Inst{3-0}   = imm{19-16};
1032
1033   // Encode remaining instruction bits.
1034   let Inst{27-23} = 0b11101;
1035   let Inst{21-20} = 0b11;
1036   let Inst{11-9}  = 0b101;
1037   let Inst{8}     = 1;          // Double precision.
1038   let Inst{7-4}   = 0b0000;
1039 }
1040
1041 def FCONSTS : VFPAI<(outs SPR:$Sd), (ins vfp_f32imm:$imm),
1042                      VFPMiscFrm, IIC_fpUNA32,
1043                      "vmov", ".f32\t$Sd, $imm",
1044                      [(set SPR:$Sd, vfp_f32imm:$imm)]>, Requires<[HasVFP3]> {
1045   // Instruction operands.
1046   bits<5>  Sd;
1047   bits<32> imm;
1048
1049   // Encode instruction operands.
1050   let Inst{15-12} = Sd{4-1};
1051   let Inst{22}    = Sd{0};
1052   let Inst{19}    = imm{31};    // The immediate is handled as a double.
1053   let Inst{18-16} = imm{22-20};
1054   let Inst{3-0}   = imm{19-16};
1055
1056   // Encode remaining instruction bits.
1057   let Inst{27-23} = 0b11101;
1058   let Inst{21-20} = 0b11;
1059   let Inst{11-9}  = 0b101;
1060   let Inst{8}     = 0;          // Single precision.
1061   let Inst{7-4}   = 0b0000;
1062 }
1063 }