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