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