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