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