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