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