ARMInstrVFP.td revision 80a119842da2ce2786ea476037001ab5b6c67046
1//===- ARMInstrVFP.td - VFP support for ARM -------------------------------===//
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 :
15SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>;
16def SDT_ITOF :
17SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>;
18def SDT_CMPFP0 :
19SDTypeProfile<0, 1, [SDTCisFP<0>]>;
20def SDT_FMDRR :
21SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>,
22                     SDTCisSameAs<1, 2>]>;
23
24def arm_ftoui  : SDNode<"ARMISD::FTOUI",  SDT_FTOI>;
25def arm_ftosi  : SDNode<"ARMISD::FTOSI",  SDT_FTOI>;
26def arm_sitof  : SDNode<"ARMISD::SITOF",  SDT_ITOF>;
27def arm_uitof  : SDNode<"ARMISD::UITOF",  SDT_ITOF>;
28def arm_fmstat : SDNode<"ARMISD::FMSTAT", SDTNone, [SDNPInFlag,SDNPOutFlag]>;
29def arm_cmpfp  : SDNode<"ARMISD::CMPFP",  SDT_ARMCmp, [SDNPOutFlag]>;
30def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0",SDT_CMPFP0, [SDNPOutFlag]>;
31def arm_fmdrr  : SDNode<"ARMISD::FMDRR",  SDT_FMDRR>;
32
33//===----------------------------------------------------------------------===//
34//  Load / store Instructions.
35//
36
37let isSimpleLoad = 1 in {
38def FLDD  : ADI5<0b1101, 0b01, (outs DPR:$dst), (ins addrmode5:$addr),
39                 "fldd", " $dst, $addr",
40                 [(set DPR:$dst, (load addrmode5:$addr))]>;
41
42def FLDS  : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr),
43                 "flds", " $dst, $addr",
44                 [(set SPR:$dst, (load addrmode5:$addr))]>;
45} // isSimpleLoad
46
47def FSTD  : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr),
48                 "fstd", " $src, $addr",
49                 [(store DPR:$src, addrmode5:$addr)]>;
50
51def FSTS  : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr),
52                 "fsts", " $src, $addr",
53                 [(store SPR:$src, addrmode5:$addr)]>;
54
55//===----------------------------------------------------------------------===//
56//  Load / store multiple Instructions.
57//
58
59let mayLoad = 1 in {
60def FLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1,
61                           variable_ops),
62                  "fldm${addr:submode}d${p} ${addr:base}, $dst1",
63                  []> {
64  let Inst{20} = 1;
65}
66
67def FLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1,
68                           variable_ops),
69                  "fldm${addr:submode}s${p} ${addr:base}, $dst1",
70                  []> {
71  let Inst{20} = 1;
72}
73}
74
75let mayStore = 1 in {
76def FSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1,
77                           variable_ops),
78                 "fstm${addr:submode}d${p} ${addr:base}, $src1",
79                 []> {
80  let Inst{20} = 0;
81}
82
83def FSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1,
84                           variable_ops),
85                 "fstm${addr:submode}s${p} ${addr:base}, $src1",
86                 []> {
87  let Inst{20} = 0;
88}
89} // mayStore
90
91// FLDMX, FSTMX - mixing S/D registers for pre-armv6 cores
92
93//===----------------------------------------------------------------------===//
94// FP Binary Operations.
95//
96
97def FADDD  : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
98                 "faddd", " $dst, $a, $b",
99                 [(set DPR:$dst, (fadd DPR:$a, DPR:$b))]>;
100
101def FADDS  : ASbI<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
102                 "fadds", " $dst, $a, $b",
103                 [(set SPR:$dst, (fadd SPR:$a, SPR:$b))]>;
104
105def FCMPED : ADbI<0b11101011, (outs), (ins DPR:$a, DPR:$b),
106                 "fcmped", " $a, $b",
107                 [(arm_cmpfp DPR:$a, DPR:$b)]> {
108  let Inst{19-16} = 0b0100;
109  let Inst{7-6}   = 0b11;
110}
111
112def FCMPES : ASbI<0b11101011, (outs), (ins SPR:$a, SPR:$b),
113                 "fcmpes", " $a, $b",
114                 [(arm_cmpfp SPR:$a, SPR:$b)]> {
115  let Inst{19-16} = 0b0100;
116  let Inst{7-6}   = 0b11;
117}
118
119def FDIVD  : ADbI<0b11101000, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
120                 "fdivd", " $dst, $a, $b",
121                 [(set DPR:$dst, (fdiv DPR:$a, DPR:$b))]>;
122
123def FDIVS  : ASbI<0b11101000, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
124                 "fdivs", " $dst, $a, $b",
125                 [(set SPR:$dst, (fdiv SPR:$a, SPR:$b))]>;
126
127def FMULD  : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
128                 "fmuld", " $dst, $a, $b",
129                 [(set DPR:$dst, (fmul DPR:$a, DPR:$b))]>;
130
131def FMULS  : ASbI<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
132                 "fmuls", " $dst, $a, $b",
133                 [(set SPR:$dst, (fmul SPR:$a, SPR:$b))]>;
134                 
135def FNMULD  : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
136                  "fnmuld", " $dst, $a, $b",
137                  [(set DPR:$dst, (fneg (fmul DPR:$a, DPR:$b)))]> {
138  let Inst{6} = 1;
139}
140
141def FNMULS  : ASbI<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
142                  "fnmuls", " $dst, $a, $b",
143                  [(set SPR:$dst, (fneg (fmul SPR:$a, SPR:$b)))]> {
144  let Inst{6} = 1;
145}
146
147// Match reassociated forms only if not sign dependent rounding.
148def : Pat<(fmul (fneg DPR:$a), DPR:$b),
149          (FNMULD DPR:$a, DPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
150def : Pat<(fmul (fneg SPR:$a), SPR:$b),
151          (FNMULS SPR:$a, SPR:$b)>, Requires<[NoHonorSignDependentRounding]>;
152
153
154def FSUBD  : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
155                 "fsubd", " $dst, $a, $b",
156                 [(set DPR:$dst, (fsub DPR:$a, DPR:$b))]>;
157
158def FSUBS  : ASbI<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
159                 "fsubs", " $dst, $a, $b",
160                 [(set SPR:$dst, (fsub SPR:$a, SPR:$b))]>;
161
162//===----------------------------------------------------------------------===//
163// FP Unary Operations.
164//
165
166def FABSD  : ADuI<0b11101011, 0b0000, 0b1100, (outs DPR:$dst), (ins DPR:$a),
167                 "fabsd", " $dst, $a",
168                 [(set DPR:$dst, (fabs DPR:$a))]>;
169
170def FABSS  : ASuI<0b11101011, 0b0000, 0b1100, (outs SPR:$dst), (ins SPR:$a),
171                 "fabss", " $dst, $a",
172                 [(set SPR:$dst, (fabs SPR:$a))]>;
173
174def FCMPEZD : ADuI<0b11101011, 0b0101, 0b1100, (outs), (ins DPR:$a),
175                  "fcmpezd", " $a",
176                  [(arm_cmpfp0 DPR:$a)]>;
177
178def FCMPEZS : ASuI<0b11101011, 0b0101, 0b1100, (outs), (ins SPR:$a),
179                  "fcmpezs", " $a",
180                  [(arm_cmpfp0 SPR:$a)]>;
181
182def FCVTDS : ASuI<0b11101011, 0b0111, 0b1100, (outs DPR:$dst), (ins SPR:$a),
183                 "fcvtds", " $dst, $a",
184                 [(set DPR:$dst, (fextend SPR:$a))]>;
185
186// Special case encoding: bits 11-8 is 0b1011.
187def FCVTSD : AI<(outs SPR:$dst), (ins DPR:$a), VFPUnaryFrm,
188                 "fcvtsd", " $dst, $a",
189                 [(set SPR:$dst, (fround DPR:$a))]> {
190  let Inst{27-23} = 0b11101;
191  let Inst{21-16} = 0b110111;
192  let Inst{11-8}  = 0b1011;
193  let Inst{7-4}   = 0b1100;
194}
195
196def FCPYD  : ADuI<0b11101011, 0b0000, 0b0100, (outs DPR:$dst), (ins DPR:$a),
197                 "fcpyd", " $dst, $a", []>;
198
199def FCPYS  : ASuI<0b11101011, 0b0000, 0b0100, (outs SPR:$dst), (ins SPR:$a),
200                 "fcpys", " $dst, $a", []>;
201
202def FNEGD  : ADuI<0b11101011, 0b0001, 0b0100, (outs DPR:$dst), (ins DPR:$a),
203                 "fnegd", " $dst, $a",
204                 [(set DPR:$dst, (fneg DPR:$a))]>;
205
206def FNEGS  : ASuI<0b11101011, 0b0001, 0b0100, (outs SPR:$dst), (ins SPR:$a),
207                 "fnegs", " $dst, $a",
208                 [(set SPR:$dst, (fneg SPR:$a))]>;
209
210def FSQRTD  : ADuI<0b11101011, 0b0001, 0b1100, (outs DPR:$dst), (ins DPR:$a),
211                 "fsqrtd", " $dst, $a",
212                 [(set DPR:$dst, (fsqrt DPR:$a))]>;
213
214def FSQRTS  : ASuI<0b11101011, 0b0001, 0b1100, (outs SPR:$dst), (ins SPR:$a),
215                 "fsqrts", " $dst, $a",
216                 [(set SPR:$dst, (fsqrt SPR:$a))]>;
217
218//===----------------------------------------------------------------------===//
219// FP <-> GPR Copies.  Int <-> FP Conversions.
220//
221
222def FMRS   : AVConv2I<0b11100001, 0b1010, (outs GPR:$dst), (ins SPR:$src),
223                 "fmrs", " $dst, $src",
224                 [(set GPR:$dst, (bitconvert SPR:$src))]>;
225
226def FMSR   : AVConv4I<0b11100000, 0b1010, (outs SPR:$dst), (ins GPR:$src),
227                 "fmsr", " $dst, $src",
228                 [(set SPR:$dst, (bitconvert GPR:$src))]>;
229
230def FMRRD  : AVConv3I<0b11000101, 0b1011,
231                      (outs GPR:$dst1, GPR:$dst2), (ins DPR:$src),
232                 "fmrrd", " $dst1, $dst2, $src",
233                 [/* FIXME: Can't write pattern for multiple result instr*/]>;
234
235// FMDHR: GPR -> SPR
236// FMDLR: GPR -> SPR
237
238def FMDRR : AVConv5I<0b11000100, 0b1011, (outs DPR:$dst), (ins GPR:$src1, GPR:$src2),
239                "fmdrr", " $dst, $src1, $src2",
240                [(set DPR:$dst, (arm_fmdrr GPR:$src1, GPR:$src2))]>;
241
242// FMRDH: SPR -> GPR
243// FMRDL: SPR -> GPR
244// FMRRS: SPR -> GPR
245// FMRX : SPR system reg -> GPR
246
247// FMSRR: GPR -> SPR
248
249// FMXR: GPR -> VFP Sstem reg
250
251
252// Int to FP:
253
254def FSITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
255                 "fsitod", " $dst, $a",
256                 [(set DPR:$dst, (arm_sitof SPR:$a))]> {
257  let Inst{7} = 1; // Z bit
258}
259
260def FSITOS : AVConv1I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a),
261                 "fsitos", " $dst, $a",
262                 [(set SPR:$dst, (arm_sitof SPR:$a))]> {
263  let Inst{7} = 1; // Z bit
264}
265
266def FUITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
267                 "fuitod", " $dst, $a",
268                 [(set DPR:$dst, (arm_uitof SPR:$a))]> {
269  let Inst{7} = 0; // Z bit
270}
271
272def FUITOS : AVConv1I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a),
273                 "fuitos", " $dst, $a",
274                 [(set SPR:$dst, (arm_uitof SPR:$a))]> {
275  let Inst{7} = 1; // Z bit
276}
277
278// FP to Int:
279// Always set Z bit in the instruction, i.e. "round towards zero" variants.
280
281def FTOSIZD : AVConv1I<0b11101011, 0b1101, 0b1011,
282                       (outs SPR:$dst), (ins DPR:$a),
283                 "ftosizd", " $dst, $a",
284                 [(set SPR:$dst, (arm_ftosi DPR:$a))]> {
285  let Inst{7} = 1; // Z bit
286}
287
288def FTOSIZS : AVConv1I<0b11101011, 0b1101, 0b1010,
289                       (outs SPR:$dst), (ins SPR:$a),
290                 "ftosizs", " $dst, $a",
291                 [(set SPR:$dst, (arm_ftosi SPR:$a))]> {
292  let Inst{7} = 1; // Z bit
293}
294
295def FTOUIZD : AVConv1I<0b11101011, 0b1100, 0b1011,
296                       (outs SPR:$dst), (ins DPR:$a),
297                 "ftouizd", " $dst, $a",
298                 [(set SPR:$dst, (arm_ftoui DPR:$a))]> {
299  let Inst{7} = 1; // Z bit
300}
301
302def FTOUIZS : AVConv1I<0b11101011, 0b1100, 0b1010,
303                       (outs SPR:$dst), (ins SPR:$a),
304                 "ftouizs", " $dst, $a",
305                 [(set SPR:$dst, (arm_ftoui SPR:$a))]> {
306  let Inst{7} = 1; // Z bit
307}
308
309//===----------------------------------------------------------------------===//
310// FP FMA Operations.
311//
312
313def FMACD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
314                "fmacd", " $dst, $a, $b",
315                [(set DPR:$dst, (fadd (fmul DPR:$a, DPR:$b), DPR:$dstin))]>,
316                RegConstraint<"$dstin = $dst">;
317
318def FMACS : ASbI<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
319                "fmacs", " $dst, $a, $b",
320                [(set SPR:$dst, (fadd (fmul SPR:$a, SPR:$b), SPR:$dstin))]>,
321                RegConstraint<"$dstin = $dst">;
322
323def FMSCD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
324                "fmscd", " $dst, $a, $b",
325                [(set DPR:$dst, (fsub (fmul DPR:$a, DPR:$b), DPR:$dstin))]>,
326                RegConstraint<"$dstin = $dst">;
327
328def FMSCS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
329                "fmscs", " $dst, $a, $b",
330                [(set SPR:$dst, (fsub (fmul SPR:$a, SPR:$b), SPR:$dstin))]>,
331                RegConstraint<"$dstin = $dst">;
332
333def FNMACD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
334                 "fnmacd", " $dst, $a, $b",
335             [(set DPR:$dst, (fadd (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>,
336                RegConstraint<"$dstin = $dst"> {
337  let Inst{6} = 1;
338}
339
340def FNMACS : ASbI<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
341                "fnmacs", " $dst, $a, $b",
342             [(set SPR:$dst, (fadd (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>,
343                RegConstraint<"$dstin = $dst"> {
344  let Inst{6} = 1;
345}
346
347def FNMSCD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
348                 "fnmscd", " $dst, $a, $b",
349             [(set DPR:$dst, (fsub (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>,
350                RegConstraint<"$dstin = $dst"> {
351  let Inst{6} = 1;
352}
353
354def FNMSCS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
355                "fnmscs", " $dst, $a, $b",
356             [(set SPR:$dst, (fsub (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>,
357                RegConstraint<"$dstin = $dst"> {
358  let Inst{6} = 1;
359}
360
361//===----------------------------------------------------------------------===//
362// FP Conditional moves.
363//
364
365def FCPYDcc  : ADuI<0b11101011, 0b0000, 0b0100,
366                    (outs DPR:$dst), (ins DPR:$false, DPR:$true),
367                    "fcpyd", " $dst, $true",
368                [/*(set DPR:$dst, (ARMcmov DPR:$false, DPR:$true, imm:$cc))*/]>,
369                    RegConstraint<"$false = $dst">;
370
371def FCPYScc  : ASuI<0b11101011, 0b0000, 0b0100,
372                    (outs SPR:$dst), (ins SPR:$false, SPR:$true),
373                    "fcpys", " $dst, $true",
374                [/*(set SPR:$dst, (ARMcmov SPR:$false, SPR:$true, imm:$cc))*/]>,
375                    RegConstraint<"$false = $dst">;
376
377def FNEGDcc  : ADuI<0b11101011, 0b0001, 0b0100,
378                    (outs DPR:$dst), (ins DPR:$false, DPR:$true),
379                    "fnegd", " $dst, $true",
380                [/*(set DPR:$dst, (ARMcneg DPR:$false, DPR:$true, imm:$cc))*/]>,
381                    RegConstraint<"$false = $dst">;
382
383def FNEGScc  : ASuI<0b11101011, 0b0001, 0b0100,
384                    (outs SPR:$dst), (ins SPR:$false, SPR:$true),
385                    "fnegs", " $dst, $true",
386                [/*(set SPR:$dst, (ARMcneg SPR:$false, SPR:$true, imm:$cc))*/]>,
387                    RegConstraint<"$false = $dst">;
388
389
390//===----------------------------------------------------------------------===//
391// Misc.
392//
393
394let Defs = [CPSR] in
395def FMSTAT : AI<(outs), (ins), VFPMiscFrm, "fmstat", "", [(arm_fmstat)]> {
396  let Inst{27-20} = 0b11101111;
397  let Inst{19-16} = 0b0001;
398  let Inst{15-12} = 0b1111;
399  let Inst{11-8}  = 0b1010;
400  let Inst{7}     = 0;
401  let Inst{4}     = 1;
402}
403