Add encodings for movement between ARM core registers and single-precision
[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:$wb, GPR:$dst2), (ins DPR:$src),
509                  IIC_fpMOVDI, "vmov", "\t$wb, $dst2, $src",
510                  [/* FIXME: Can't write pattern for multiple result instr*/]> {
511   let Inst{7-6} = 0b00;
512 }
513
514 def VMOVRRS  : AVConv3I<0b11000101, 0b1010,
515                       (outs GPR:$wb, GPR:$dst2), (ins SPR:$src1, SPR:$src2),
516                  IIC_fpMOVDI, "vmov", "\t$wb, $dst2, $src1, $src2",
517                  [/* For disassembly only; pattern left blank */]> {
518   let Inst{7-6} = 0b00;
519 }
520 } // neverHasSideEffects
521
522 // FMDHR: GPR -> SPR
523 // FMDLR: GPR -> SPR
524
525 def VMOVDRR : AVConv5I<0b11000100, 0b1011,
526                      (outs DPR:$dst), (ins GPR:$src1, GPR:$src2),
527                 IIC_fpMOVID, "vmov", "\t$dst, $src1, $src2",
528                 [(set DPR:$dst, (arm_fmdrr GPR:$src1, GPR:$src2))]> {
529   let Inst{7-6} = 0b00;
530 }
531
532 let neverHasSideEffects = 1 in
533 def VMOVSRR : AVConv5I<0b11000100, 0b1010,
534                      (outs SPR:$dst1, SPR:$dst2), (ins GPR:$src1, GPR:$src2),
535                 IIC_fpMOVID, "vmov", "\t$dst1, $dst2, $src1, $src2",
536                 [/* For disassembly only; pattern left blank */]> {
537   let Inst{7-6} = 0b00;
538 }
539
540 // FMRDH: SPR -> GPR
541 // FMRDL: SPR -> GPR
542 // FMRRS: SPR -> GPR
543 // FMRX:  SPR system reg -> GPR
544 // FMSRR: GPR -> SPR
545 // FMXR:  GPR -> VFP system reg
546
547
548 // Int -> FP:
549
550 class AVConv1IDs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
551                         bits<4> opcod4, dag oops, dag iops,
552                         InstrItinClass itin, string opc, string asm,
553                         list<dag> pattern>
554   : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
555              pattern> {
556   // Instruction operands.
557   bits<5> Dd;
558   bits<5> Sm;
559
560   // Encode instruction operands.
561   let Inst{3-0}   = Sm{4-1};
562   let Inst{5}     = Sm{0};
563   let Inst{15-12} = Dd{3-0};
564   let Inst{22}    = Dd{4};
565 }
566
567 class AVConv1InSs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
568                          bits<4> opcod4, dag oops, dag iops,InstrItinClass itin,
569                          string opc, string asm, list<dag> pattern>
570   : AVConv1In<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
571               pattern> {
572   // Instruction operands.
573   bits<5> Sd;
574   bits<5> Sm;
575
576   // Encode instruction operands.
577   let Inst{3-0}   = Sm{4-1};
578   let Inst{5}     = Sm{0};
579   let Inst{15-12} = Sd{4-1};
580   let Inst{22}    = Sd{0};
581 }
582
583 def VSITOD : AVConv1IDs_Encode<0b11101, 0b11, 0b1000, 0b1011,
584                                (outs DPR:$Dd), (ins SPR:$Sm),
585                                IIC_fpCVTID, "vcvt", ".f64.s32\t$Dd, $Sm",
586                                [(set DPR:$Dd, (f64 (arm_sitof SPR:$Sm)))]> {
587   let Inst{7} = 1; // s32
588 }
589
590 def VSITOS : AVConv1InSs_Encode<0b11101, 0b11, 0b1000, 0b1010,
591                                 (outs SPR:$Sd),(ins SPR:$Sm),
592                                 IIC_fpCVTIS, "vcvt", ".f32.s32\t$Sd, $Sm",
593                                 [(set SPR:$Sd, (arm_sitof SPR:$Sm))]> {
594   let Inst{7} = 1; // s32
595 }
596
597 def VUITOD : AVConv1IDs_Encode<0b11101, 0b11, 0b1000, 0b1011,
598                                (outs DPR:$Dd), (ins SPR:$Sm),
599                                IIC_fpCVTID, "vcvt", ".f64.u32\t$Dd, $Sm",
600                                [(set DPR:$Dd, (f64 (arm_uitof SPR:$Sm)))]> {
601   let Inst{7} = 0; // u32
602 }
603
604 def VUITOS : AVConv1InSs_Encode<0b11101, 0b11, 0b1000, 0b1010,
605                                 (outs SPR:$Sd), (ins SPR:$Sm),
606                                 IIC_fpCVTIS, "vcvt", ".f32.u32\t$Sd, $Sm",
607                                 [(set SPR:$Sd, (arm_uitof SPR:$Sm))]> {
608   let Inst{7} = 0; // u32
609 }
610
611 // FP -> Int:
612
613 class AVConv1IsD_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
614                         bits<4> opcod4, dag oops, dag iops,
615                         InstrItinClass itin, string opc, string asm,
616                         list<dag> pattern>
617   : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
618              pattern> {
619   // Instruction operands.
620   bits<5> Sd;
621   bits<5> Dm;
622
623   // Encode instruction operands.
624   let Inst{3-0}   = Dm{3-0};
625   let Inst{5}     = Dm{4};
626   let Inst{15-12} = Sd{4-1};
627   let Inst{22}    = Sd{0};
628 }
629
630 class AVConv1InsS_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3,
631                          bits<4> opcod4, dag oops, dag iops,
632                          InstrItinClass itin, string opc, string asm,
633                          list<dag> pattern>
634   : AVConv1In<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm,
635               pattern> {
636   // Instruction operands.
637   bits<5> Sd;
638   bits<5> Sm;
639
640   // Encode instruction operands.
641   let Inst{3-0}   = Sm{4-1};
642   let Inst{5}     = Sm{0};
643   let Inst{15-12} = Sd{4-1};
644   let Inst{22}    = Sd{0};
645 }
646
647 // Always set Z bit in the instruction, i.e. "round towards zero" variants.
648 def VTOSIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011,
649                                 (outs SPR:$Sd), (ins DPR:$Dm),
650                                 IIC_fpCVTDI, "vcvt", ".s32.f64\t$Sd, $Dm",
651                                 [(set SPR:$Sd, (arm_ftosi (f64 DPR:$Dm)))]> {
652   let Inst{7} = 1; // Z bit
653 }
654
655 def VTOSIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010,
656                                  (outs SPR:$Sd), (ins SPR:$Sm),
657                                  IIC_fpCVTSI, "vcvt", ".s32.f32\t$Sd, $Sm",
658                                  [(set SPR:$Sd, (arm_ftosi SPR:$Sm))]> {
659   let Inst{7} = 1; // Z bit
660 }
661
662 def VTOUIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011,
663                                (outs SPR:$Sd), (ins DPR:$Dm),
664                                IIC_fpCVTDI, "vcvt", ".u32.f64\t$Sd, $Dm",
665                                [(set SPR:$Sd, (arm_ftoui (f64 DPR:$Dm)))]> {
666   let Inst{7} = 1; // Z bit
667 }
668
669 def VTOUIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010,
670                                  (outs SPR:$Sd), (ins SPR:$Sm),
671                                  IIC_fpCVTSI, "vcvt", ".u32.f32\t$Sd, $Sm",
672                                  [(set SPR:$Sd, (arm_ftoui SPR:$Sm))]> {
673   let Inst{7} = 1; // Z bit
674 }
675
676 // And the Z bit '0' variants, i.e. use the rounding mode specified by FPSCR.
677 // For disassembly only.
678 let Uses = [FPSCR] in {
679 // FIXME: Verify encoding after integrated assembler is working.
680 def VTOSIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011,
681                                 (outs SPR:$Sd), (ins DPR:$Dm),
682                                 IIC_fpCVTDI, "vcvtr", ".s32.f64\t$Sd, $Dm",
683                                 [(set SPR:$Sd, (int_arm_vcvtr (f64 DPR:$Dm)))]>{
684   let Inst{7} = 0; // Z bit
685 }
686
687 def VTOSIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010,
688                                  (outs SPR:$Sd), (ins SPR:$Sm),
689                                  IIC_fpCVTSI, "vcvtr", ".s32.f32\t$Sd, $Sm",
690                                  [(set SPR:$Sd, (int_arm_vcvtr SPR:$Sm))]> {
691   let Inst{7} = 0; // Z bit
692 }
693
694 def VTOUIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011,
695                                 (outs SPR:$Sd), (ins DPR:$Dm),
696                                 IIC_fpCVTDI, "vcvtr", ".u32.f64\t$Sd, $Dm",
697                                 [(set SPR:$Sd, (int_arm_vcvtru(f64 DPR:$Dm)))]>{
698   let Inst{7} = 0; // Z bit
699 }
700
701 def VTOUIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010,
702                                  (outs SPR:$Sd), (ins SPR:$Sm),
703                                  IIC_fpCVTSI, "vcvtr", ".u32.f32\t$Sd, $Sm",
704                                  [(set SPR:$Sd, (int_arm_vcvtru SPR:$Sm))]> {
705   let Inst{7} = 0; // Z bit
706 }
707 }
708
709 // Convert between floating-point and fixed-point
710 // Data type for fixed-point naming convention:
711 //   S16 (U=0, sx=0) -> SH
712 //   U16 (U=1, sx=0) -> UH
713 //   S32 (U=0, sx=1) -> SL
714 //   U32 (U=1, sx=1) -> UL
715
716 let Constraints = "$a = $dst" in {
717
718 // FP to Fixed-Point:
719
720 let isCodeGenOnly = 1 in {
721 def VTOSHS : AVConv1XI<0b11101, 0b11, 0b1110, 0b1010, 0,
722                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
723                  IIC_fpCVTSI, "vcvt", ".s16.f32\t$dst, $a, $fbits",
724                  [/* For disassembly only; pattern left blank */]>;
725
726 def VTOUHS : AVConv1XI<0b11101, 0b11, 0b1111, 0b1010, 0,
727                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
728                  IIC_fpCVTSI, "vcvt", ".u16.f32\t$dst, $a, $fbits",
729                  [/* For disassembly only; pattern left blank */]>;
730
731 def VTOSLS : AVConv1XI<0b11101, 0b11, 0b1110, 0b1010, 1,
732                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
733                  IIC_fpCVTSI, "vcvt", ".s32.f32\t$dst, $a, $fbits",
734                  [/* For disassembly only; pattern left blank */]>;
735
736 def VTOULS : AVConv1XI<0b11101, 0b11, 0b1111, 0b1010, 1,
737                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
738                  IIC_fpCVTSI, "vcvt", ".u32.f32\t$dst, $a, $fbits",
739                  [/* For disassembly only; pattern left blank */]>;
740
741 def VTOSHD : AVConv1XI<0b11101, 0b11, 0b1110, 0b1011, 0,
742                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
743                  IIC_fpCVTDI, "vcvt", ".s16.f64\t$dst, $a, $fbits",
744                  [/* For disassembly only; pattern left blank */]>;
745
746 def VTOUHD : AVConv1XI<0b11101, 0b11, 0b1111, 0b1011, 0,
747                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
748                  IIC_fpCVTDI, "vcvt", ".u16.f64\t$dst, $a, $fbits",
749                  [/* For disassembly only; pattern left blank */]>;
750
751 def VTOSLD : AVConv1XI<0b11101, 0b11, 0b1110, 0b1011, 1,
752                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
753                  IIC_fpCVTDI, "vcvt", ".s32.f64\t$dst, $a, $fbits",
754                  [/* For disassembly only; pattern left blank */]>;
755
756 def VTOULD : AVConv1XI<0b11101, 0b11, 0b1111, 0b1011, 1,
757                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
758                  IIC_fpCVTDI, "vcvt", ".u32.f64\t$dst, $a, $fbits",
759                  [/* For disassembly only; pattern left blank */]>;
760 } // End of 'let isCodeGenOnly = 1 in'
761
762 // Fixed-Point to FP:
763
764 let isCodeGenOnly = 1 in {
765 def VSHTOS : AVConv1XI<0b11101, 0b11, 0b1010, 0b1010, 0,
766                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
767                  IIC_fpCVTIS, "vcvt", ".f32.s16\t$dst, $a, $fbits",
768                  [/* For disassembly only; pattern left blank */]>;
769
770 def VUHTOS : AVConv1XI<0b11101, 0b11, 0b1011, 0b1010, 0,
771                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
772                  IIC_fpCVTIS, "vcvt", ".f32.u16\t$dst, $a, $fbits",
773                  [/* For disassembly only; pattern left blank */]>;
774
775 def VSLTOS : AVConv1XI<0b11101, 0b11, 0b1010, 0b1010, 1,
776                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
777                  IIC_fpCVTIS, "vcvt", ".f32.s32\t$dst, $a, $fbits",
778                  [/* For disassembly only; pattern left blank */]>;
779
780 def VULTOS : AVConv1XI<0b11101, 0b11, 0b1011, 0b1010, 1,
781                        (outs SPR:$dst), (ins SPR:$a, i32imm:$fbits),
782                  IIC_fpCVTIS, "vcvt", ".f32.u32\t$dst, $a, $fbits",
783                  [/* For disassembly only; pattern left blank */]>;
784
785 def VSHTOD : AVConv1XI<0b11101, 0b11, 0b1010, 0b1011, 0,
786                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
787                  IIC_fpCVTID, "vcvt", ".f64.s16\t$dst, $a, $fbits",
788                  [/* For disassembly only; pattern left blank */]>;
789
790 def VUHTOD : AVConv1XI<0b11101, 0b11, 0b1011, 0b1011, 0,
791                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
792                  IIC_fpCVTID, "vcvt", ".f64.u16\t$dst, $a, $fbits",
793                  [/* For disassembly only; pattern left blank */]>;
794
795 def VSLTOD : AVConv1XI<0b11101, 0b11, 0b1010, 0b1011, 1,
796                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
797                  IIC_fpCVTID, "vcvt", ".f64.s32\t$dst, $a, $fbits",
798                  [/* For disassembly only; pattern left blank */]>;
799
800 def VULTOD : AVConv1XI<0b11101, 0b11, 0b1011, 0b1011, 1,
801                        (outs DPR:$dst), (ins DPR:$a, i32imm:$fbits),
802                  IIC_fpCVTID, "vcvt", ".f64.u32\t$dst, $a, $fbits",
803                  [/* For disassembly only; pattern left blank */]>;
804 } // End of 'let isCodeGenOnly = 1 in'
805
806 } // End of 'let Constraints = "$src = $dst" in'
807
808 //===----------------------------------------------------------------------===//
809 // FP FMA Operations.
810 //
811
812 class ADbI_vmlX_Encode<bits<5> opcod1, bits<2> opcod2, bit op6, bit op4,
813                        dag oops, dag iops, InstrItinClass itin, string opc,
814                        string asm, list<dag> pattern>
815   : ADbI_vmlX<opcod1, opcod2, op6, op4, oops, iops, itin, opc, asm, pattern> {
816   // Instruction operands.
817   bits<5> Dd;
818   bits<5> Dn;
819   bits<5> Dm;
820
821   // Encode instruction operands.
822   let Inst{19-16} = Dn{3-0};
823   let Inst{7}     = Dn{4};
824   let Inst{15-12} = Dd{3-0};
825   let Inst{22}    = Dd{4};
826   let Inst{3-0}   = Dm{3-0};
827   let Inst{5}     = Dm{4};
828 }
829
830 def VMLAD : ADbI_vmlX_Encode<0b11100, 0b00, 0, 0,
831                              (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
832                              IIC_fpMAC64, "vmla", ".f64\t$Dd, $Dn, $Dm",
833                              [(set DPR:$Dd, (fadd (fmul DPR:$Dn, DPR:$Dm),
834                                                   (f64 DPR:$Ddin)))]>,
835                              RegConstraint<"$Ddin = $Dd">;
836
837 def VMLAS : ASbIn_Encode<0b11100, 0b00, 0, 0,
838                          (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
839                          IIC_fpMAC32, "vmla", ".f32\t$Sd, $Sn, $Sm",
840                          [(set SPR:$Sd, (fadd (fmul SPR:$Sn, SPR:$Sm),
841                                               SPR:$Sdin))]>,
842                          RegConstraint<"$Sdin = $Sd">;
843
844 def : Pat<(fadd DPR:$dstin, (fmul DPR:$a, (f64 DPR:$b))),
845           (VMLAD DPR:$dstin, DPR:$a, DPR:$b)>, Requires<[DontUseNEONForFP]>;
846 def : Pat<(fadd SPR:$dstin, (fmul SPR:$a, SPR:$b)),
847           (VMLAS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[DontUseNEONForFP]>;
848
849 def VMLSD : ADbI_vmlX_Encode<0b11100, 0b00, 1, 0,
850                              (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
851                              IIC_fpMAC64, "vmls", ".f64\t$Dd, $Dn, $Dm",
852                              [(set DPR:$Dd, (fadd (fneg (fmul DPR:$Dn,DPR:$Dm)),
853                                                         (f64 DPR:$Ddin)))]>,
854                              RegConstraint<"$Ddin = $Dd">;
855
856 def VMLSS : ASbIn_Encode<0b11100, 0b00, 1, 0,
857                          (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
858                          IIC_fpMAC32, "vmls", ".f32\t$Sd, $Sn, $Sm",
859                          [(set SPR:$Sd, (fadd (fneg (fmul SPR:$Sn, SPR:$Sm)),
860                                                     SPR:$Sdin))]>,
861                          RegConstraint<"$Sdin = $Sd">;
862
863 def : Pat<(fsub DPR:$dstin, (fmul DPR:$a, (f64 DPR:$b))),
864           (VMLSD DPR:$dstin, DPR:$a, DPR:$b)>, Requires<[DontUseNEONForFP]>;
865 def : Pat<(fsub SPR:$dstin, (fmul SPR:$a, SPR:$b)),
866           (VMLSS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[DontUseNEONForFP]>;
867
868 def VNMLAD : ADbI_vmlX_Encode<0b11100, 0b01, 1, 0,
869                               (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
870                               IIC_fpMAC64, "vnmla", ".f64\t$Dd, $Dn, $Dm",
871                               [(set DPR:$Dd,(fsub (fneg (fmul DPR:$Dn,DPR:$Dm)),
872                                                   (f64 DPR:$Ddin)))]>,
873                 RegConstraint<"$Ddin = $Dd">;
874
875 def VNMLAS : ASbI_Encode<0b11100, 0b01, 1, 0,
876                          (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
877                          IIC_fpMAC32, "vnmla", ".f32\t$Sd, $Sn, $Sm",
878                          [(set SPR:$Sd, (fsub (fneg (fmul SPR:$Sn, SPR:$Sm)),
879                                               SPR:$Sdin))]>,
880                          RegConstraint<"$Sdin = $Sd">;
881
882 def : Pat<(fsub (fneg (fmul DPR:$a, (f64 DPR:$b))), DPR:$dstin),
883           (VNMLAD DPR:$dstin, DPR:$a, DPR:$b)>, Requires<[DontUseNEONForFP]>;
884 def : Pat<(fsub (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin),
885           (VNMLAS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[DontUseNEONForFP]>;
886
887 def VNMLSD : ADbI_vmlX_Encode<0b11100, 0b01, 0, 0,
888                               (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm),
889                               IIC_fpMAC64, "vnmls", ".f64\t$Dd, $Dn, $Dm",
890                               [(set DPR:$Dd, (fsub (fmul DPR:$Dn, DPR:$Dm),
891                                                    (f64 DPR:$Ddin)))]>,
892                               RegConstraint<"$Ddin = $Dd">;
893
894 def VNMLSS : ASbI_Encode<0b11100, 0b01, 0, 0,
895                          (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm),
896                          IIC_fpMAC32, "vnmls", ".f32\t$Sd, $Sn, $Sm",
897                          [(set SPR:$Sd, (fsub (fmul SPR:$Sn, SPR:$Sm),
898                                               SPR:$Sdin))]>,
899                          RegConstraint<"$Sdin = $Sd">;
900
901 def : Pat<(fsub (fmul DPR:$a, (f64 DPR:$b)), DPR:$dstin),
902           (VNMLSD DPR:$dstin, DPR:$a, DPR:$b)>, Requires<[DontUseNEONForFP]>;
903 def : Pat<(fsub (fmul SPR:$a, SPR:$b), SPR:$dstin),
904           (VNMLSS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[DontUseNEONForFP]>;
905
906
907 //===----------------------------------------------------------------------===//
908 // FP Conditional moves.
909 //
910
911 let neverHasSideEffects = 1 in {
912 def VMOVDcc  : ADuI_Encode<0b11101, 0b11, 0b0000, 0b01, 0,
913                            (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
914                            IIC_fpUNA64, "vmov", ".f64\t$Dd, $Dm",
915                       [/*(set DPR:$Dd, (ARMcmov DPR:$Dn, DPR:$Dm, imm:$cc))*/]>,
916                            RegConstraint<"$Dn = $Dd">;
917
918 def VMOVScc  : ASuI_Encode<0b11101, 0b11, 0b0000, 0b01, 0,
919                            (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
920                            IIC_fpUNA32, "vmov", ".f32\t$Sd, $Sm",
921                       [/*(set SPR:$Sd, (ARMcmov SPR:$Sn, SPR:$Sm, imm:$cc))*/]>,
922                            RegConstraint<"$Sn = $Sd">;
923
924 def VNEGDcc  : ADuI_Encode<0b11101, 0b11, 0b0001, 0b01, 0,
925                            (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm),
926                            IIC_fpUNA64, "vneg", ".f64\t$Dd, $Dm",
927                       [/*(set DPR:$Dd, (ARMcneg DPR:$Dn, DPR:$Dm, imm:$cc))*/]>,
928                            RegConstraint<"$Dn = $Dd">;
929
930 def VNEGScc  : ASuI_Encode<0b11101, 0b11, 0b0001, 0b01, 0,
931                            (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm),
932                            IIC_fpUNA32, "vneg", ".f32\t$Sd, $Sm",
933                       [/*(set SPR:$Sd, (ARMcneg SPR:$Sn, SPR:$Sm, imm:$cc))*/]>,
934                            RegConstraint<"$Sn = $Sd">;
935 } // neverHasSideEffects
936
937 //===----------------------------------------------------------------------===//
938 // Misc.
939 //
940
941 // APSR is the application level alias of CPSR. This FPSCR N, Z, C, V flags
942 // to APSR.
943 let Defs = [CPSR], Uses = [FPSCR] in
944 def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpSTAT, "vmrs",
945                    "\tapsr_nzcv, fpscr",
946                    [(arm_fmstat)]> {
947   let Inst{27-20} = 0b11101111;
948   let Inst{19-16} = 0b0001;
949   let Inst{15-12} = 0b1111;
950   let Inst{11-8}  = 0b1010;
951   let Inst{7}     = 0;
952   let Inst{6-5}   = 0b00;
953   let Inst{4}     = 1;
954   let Inst{3-0}   = 0b0000;
955 }
956
957 // FPSCR <-> GPR
958 let hasSideEffects = 1, Uses = [FPSCR] in
959 def VMRS : VFPAI<(outs GPR:$Rt), (ins), VFPMiscFrm, IIC_fpSTAT,
960                  "vmrs", "\t$Rt, fpscr",
961                  [(set GPR:$Rt, (int_arm_get_fpscr))]> {
962   // Instruction operand.
963   bits<4> Rt;
964
965   // Encode instruction operand.
966   let Inst{15-12} = Rt;
967
968   let Inst{27-20} = 0b11101111;
969   let Inst{19-16} = 0b0001;
970   let Inst{11-8}  = 0b1010;
971   let Inst{7}     = 0;
972   let Inst{6-5}   = 0b00;
973   let Inst{4}     = 1;
974   let Inst{3-0}   = 0b0000;
975 }
976
977 let Defs = [FPSCR] in 
978 def VMSR : VFPAI<(outs), (ins GPR:$src), VFPMiscFrm, IIC_fpSTAT, 
979                  "vmsr", "\tfpscr, $src",
980                  [(int_arm_set_fpscr GPR:$src)]> {
981   // Instruction operand.
982   bits<4> src;
983
984   // Encode instruction operand.
985   let Inst{15-12} = src;
986
987   let Inst{27-20} = 0b11101110;
988   let Inst{19-16} = 0b0001;
989   let Inst{11-8}  = 0b1010;
990   let Inst{7}     = 0;
991   let Inst{4}     = 1;
992 }
993
994 // Materialize FP immediates. VFP3 only.
995 let isReMaterializable = 1 in {
996 def FCONSTD : VFPAI<(outs DPR:$Dd), (ins vfp_f64imm:$imm),
997                     VFPMiscFrm, IIC_fpUNA64,
998                     "vmov", ".f64\t$Dd, $imm",
999                     [(set DPR:$Dd, vfp_f64imm:$imm)]>, Requires<[HasVFP3]> {
1000   // Instruction operands.
1001   bits<5>  Dd;
1002   bits<32> imm;
1003
1004   // Encode instruction operands.
1005   let Inst{15-12} = Dd{3-0};
1006   let Inst{22}    = Dd{4};
1007   let Inst{19}    = imm{31};
1008   let Inst{18-16} = imm{22-20};
1009   let Inst{3-0}   = imm{19-16};
1010
1011   // Encode remaining instruction bits.
1012   let Inst{27-23} = 0b11101;
1013   let Inst{21-20} = 0b11;
1014   let Inst{11-9}  = 0b101;
1015   let Inst{8}     = 1;          // Double precision.
1016   let Inst{7-4}   = 0b0000;
1017 }
1018
1019 def FCONSTS : VFPAI<(outs SPR:$Sd), (ins vfp_f32imm:$imm),
1020                      VFPMiscFrm, IIC_fpUNA32,
1021                      "vmov", ".f32\t$Sd, $imm",
1022                      [(set SPR:$Sd, vfp_f32imm:$imm)]>, Requires<[HasVFP3]> {
1023   // Instruction operands.
1024   bits<5>  Sd;
1025   bits<32> imm;
1026
1027   // Encode instruction operands.
1028   let Inst{15-12} = Sd{4-1};
1029   let Inst{22}    = Sd{0};
1030   let Inst{19}    = imm{31};    // The immediate is handled as a double.
1031   let Inst{18-16} = imm{22-20};
1032   let Inst{3-0}   = imm{19-16};
1033
1034   // Encode remaining instruction bits.
1035   let Inst{27-23} = 0b11101;
1036   let Inst{21-20} = 0b11;
1037   let Inst{11-9}  = 0b101;
1038   let Inst{8}     = 0;          // Single precision.
1039   let Inst{7-4}   = 0b0000;
1040 }
1041 }