]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/vfp.md
pex-djgpp.c: Include string.h, fcntl.h, unistd.h, and sys/stat.h.
[thirdparty/gcc.git] / gcc / config / arm / vfp.md
CommitLineData
9b66ebb1 1;; ARM VFP coprocessor Machine Description
5b86a469 2;; Copyright (C) 2003, 2005 Free Software Foundation, Inc.
9b66ebb1
PB
3;; Written by CodeSourcery, LLC.
4;;
5;; This file is part of GCC.
6;;
7;; GCC is free software; you can redistribute it and/or modify it
8;; under the terms of the GNU General Public License as published by
9;; the Free Software Foundation; either version 2, or (at your option)
10;; any later version.
11;;
12;; GCC is distributed in the hope that it will be useful, but
13;; WITHOUT ANY WARRANTY; without even the implied warranty of
14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15;; General Public License for more details.
16;;
17;; You should have received a copy of the GNU General Public License
18;; along with GCC; see the file COPYING. If not, write to the Free
19;; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20;; 02111-1307, USA. */
21
22;; Additional register numbers
23(define_constants
24 [(VFPCC_REGNUM 95)]
25)
26
27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28;; Pipeline description
29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
30
31(define_automaton "vfp11")
32
33;; There are 3 pipelines in the VFP11 unit.
34;;
35;; - A 8-stage FMAC pipeline (7 execute + writeback) with forward from
36;; fourth stage for simple operations.
37;;
38;; - A 5-stage DS pipeline (4 execute + writeback) for divide/sqrt insns.
39;; These insns also uses first execute stage of FMAC pipeline.
40;;
41;; - A 4-stage LS pipeline (execute + 2 memory + writeback) with forward from
42;; second memory stage for loads.
43
44;; We do not model Write-After-Read hazards.
59b9a953
KH
45;; We do not do write scheduling with the arm core, so it is only necessary
46;; to model the first stage of each pipeline
9b66ebb1 47;; ??? Need to model LS pipeline properly for load/store multiple?
59b9a953 48;; We do not model fmstat properly. This could be done by modeling pipelines
9b66ebb1
PB
49;; properly and defining an absence set between a dummy fmstat unit and all
50;; other vfp units.
51
52(define_cpu_unit "fmac" "vfp11")
53
54(define_cpu_unit "ds" "vfp11")
55
56(define_cpu_unit "vfp_ls" "vfp11")
57
58;; The VFP "type" attributes differ from those used in the FPA model.
112cdef5 59;; ffarith Fast floating point insns, e.g. abs, neg, cpy, cmp.
9b66ebb1 60;; farith Most arithmetic insns.
59b9a953 61;; fmul Double precision multiply.
9b66ebb1
PB
62;; fdivs Single precision sqrt or division.
63;; fdivd Double precision sqrt or division.
64;; f_load Floating point load from memory.
65;; f_store Floating point store to memory.
66;; f_2_r Transfer vfp to arm reg.
67;; r_2_f Transfer arm to vfp reg.
68
69(define_insn_reservation "vfp_ffarith" 4
70 (and (eq_attr "fpu" "vfp")
71 (eq_attr "type" "ffarith"))
72 "fmac")
73
74(define_insn_reservation "vfp_farith" 8
75 (and (eq_attr "fpu" "vfp")
76 (eq_attr "type" "farith"))
77 "fmac")
78
79(define_insn_reservation "vfp_fmul" 9
80 (and (eq_attr "fpu" "vfp")
81 (eq_attr "type" "fmul"))
82 "fmac*2")
83
84(define_insn_reservation "vfp_fdivs" 19
85 (and (eq_attr "fpu" "vfp")
86 (eq_attr "type" "fdivs"))
87 "ds*15")
88
89(define_insn_reservation "vfp_fdivd" 33
90 (and (eq_attr "fpu" "vfp")
91 (eq_attr "type" "fdivd"))
92 "fmac+ds*29")
93
94;; Moves to/from arm regs also use the load/store pipeline.
95(define_insn_reservation "vfp_fload" 4
96 (and (eq_attr "fpu" "vfp")
97 (eq_attr "type" "f_load,r_2_f"))
98 "vfp_ls")
99
100(define_insn_reservation "vfp_fstore" 4
101 (and (eq_attr "fpu" "vfp")
102 (eq_attr "type" "f_load,f_2_r"))
103 "vfp_ls")
104
105
106;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
59b9a953 107;; Insn pattern
9b66ebb1
PB
108;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
109
110;; SImode moves
111;; ??? For now do not allow loading constants into vfp regs. This causes
59b9a953 112;; problems because small constants get converted into adds.
9b66ebb1 113(define_insn "*arm_movsi_vfp"
082cca25
RE
114 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,m,*w,r,*w,*w, *Uv")
115 (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,*w,*w,*Uvi,*w"))]
9b66ebb1
PB
116 "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
117 && ( s_register_operand (operands[0], SImode)
118 || s_register_operand (operands[1], SImode))"
119 "@
120 mov%?\\t%0, %1
121 mvn%?\\t%0, #%B1
122 ldr%?\\t%0, %1
123 str%?\\t%1, %0
124 fmsr%?\\t%0, %1\\t%@ int
125 fmrs%?\\t%0, %1\\t%@ int
126 fcpys%?\\t%0, %1\\t%@ int
127 flds%?\\t%0, %1\\t%@ int
128 fsts%?\\t%1, %0\\t%@ int"
129 [(set_attr "predicable" "yes")
130 (set_attr "type" "*,*,load1,store1,r_2_f,f_2_r,ffarith,f_load,f_store")
131 (set_attr "pool_range" "*,*,4096,*,*,*,*,1020,*")
132 (set_attr "neg_pool_range" "*,*,4084,*,*,*,*,1008,*")]
133)
134
135
136;; DImode moves
137
138(define_insn "*arm_movdi_vfp"
fdd695fd
PB
139 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
140 (match_operand:DI 1 "di_operand" "rIK,mi,r,r,w,w,Uvi,w"))]
9b66ebb1
PB
141 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
142 "*
143 switch (which_alternative)
144 {
9b901d50
RE
145 case 0:
146 return \"#\";
147 case 1:
148 case 2:
149 return output_move_double (operands);
9b66ebb1
PB
150 case 3:
151 return \"fmdrr%?\\t%P0, %1\\t%@ int\";
152 case 4:
153 return \"fmrrd%?\\t%0, %1\\t%@ int\";
154 case 5:
155 return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
156 case 6:
157 return \"fldd%?\\t%P0, %1\\t%@ int\";
158 case 7:
159 return \"fstd%?\\t%P1, %0\\t%@ int\";
160 default:
e6d29d15 161 gcc_unreachable ();
9b66ebb1
PB
162 }
163 "
164 [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_load,f_store")
165 (set_attr "length" "8,8,8,4,4,4,4,4")
166 (set_attr "pool_range" "*,1020,*,*,*,*,1020,*")
167 (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
168)
169
170
171;; SFmode moves
172
173(define_insn "*movsf_vfp"
1e1ab407
RE
174 [(set (match_operand:SF 0 "nonimmediate_operand" "=w,r,w ,Uv,r ,m,w,r")
175 (match_operand:SF 1 "general_operand" " r,w,UvE,w, mE,r,w,r"))]
9b66ebb1
PB
176 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
177 && ( s_register_operand (operands[0], SFmode)
178 || s_register_operand (operands[1], SFmode))"
179 "@
180 fmsr%?\\t%0, %1
181 fmrs%?\\t%0, %1
182 flds%?\\t%0, %1
183 fsts%?\\t%1, %0
184 ldr%?\\t%0, %1\\t%@ float
185 str%?\\t%1, %0\\t%@ float
186 fcpys%?\\t%0, %1
187 mov%?\\t%0, %1\\t%@ float"
188 [(set_attr "predicable" "yes")
189 (set_attr "type" "r_2_f,f_2_r,ffarith,*,f_load,f_store,load1,store1")
190 (set_attr "pool_range" "*,*,1020,*,4096,*,*,*")
191 (set_attr "neg_pool_range" "*,*,1008,*,4080,*,*,*")]
192)
193
194
195;; DFmode moves
196
197(define_insn "*movdf_vfp"
1e1ab407
RE
198 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,r,r, m,w ,Uv,w,r")
199 (match_operand:DF 1 "soft_df_operand" " r,w,mF,r,UvF,w, w,r"))]
9b66ebb1
PB
200 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
201 "*
202 {
203 switch (which_alternative)
204 {
205 case 0:
206 return \"fmdrr%?\\t%P0, %Q1, %R1\";
207 case 1:
208 return \"fmrrd%?\\t%Q0, %R0, %P1\";
9b901d50 209 case 2: case 3:
9b66ebb1
PB
210 return output_move_double (operands);
211 case 4:
212 return \"fldd%?\\t%P0, %1\";
213 case 5:
214 return \"fstd%?\\t%P1, %0\";
215 case 6:
216 return \"fcpyd%?\\t%P0, %P1\";
9b901d50
RE
217 case 7:
218 return \"#\";
9b66ebb1 219 default:
e6d29d15 220 gcc_unreachable ();
9b66ebb1
PB
221 }
222 }
223 "
224 [(set_attr "type" "r_2_f,f_2_r,ffarith,*,load2,store2,f_load,f_store")
225 (set_attr "length" "4,4,8,8,4,4,4,8")
226 (set_attr "pool_range" "*,*,1020,*,1020,*,*,*")
227 (set_attr "neg_pool_range" "*,*,1008,*,1008,*,*,*")]
228)
229
230
231;; Conditional move patterns
232
233(define_insn "*movsfcc_vfp"
234 [(set (match_operand:SF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
235 (if_then_else:SF
236 (match_operator 3 "arm_comparison_operator"
237 [(match_operand 4 "cc_register" "") (const_int 0)])
238 (match_operand:SF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
239 (match_operand:SF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
240 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
241 "@
242 fcpys%D3\\t%0, %2
243 fcpys%d3\\t%0, %1
244 fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
245 fmsr%D3\\t%0, %2
246 fmsr%d3\\t%0, %1
247 fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
248 fmrs%D3\\t%0, %2
249 fmrs%d3\\t%0, %1
250 fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
251 [(set_attr "conds" "use")
252 (set_attr "length" "4,4,8,4,4,8,4,4,8")
253 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
254)
255
256(define_insn "*movdfcc_vfp"
257 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
258 (if_then_else:DF
259 (match_operator 3 "arm_comparison_operator"
260 [(match_operand 4 "cc_register" "") (const_int 0)])
261 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
262 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
263 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
264 "@
265 fcpyd%D3\\t%P0, %P2
266 fcpyd%d3\\t%P0, %P1
267 fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
268 fmdrr%D3\\t%P0, %Q2, %R2
269 fmdrr%d3\\t%P0, %Q1, %R1
270 fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
271 fmrrd%D3\\t%Q0, %R0, %P2
272 fmrrd%d3\\t%Q0, %R0, %P1
273 fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
274 [(set_attr "conds" "use")
275 (set_attr "length" "4,4,8,4,4,8,4,4,8")
276 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
277)
278
279
280;; Sign manipulation functions
281
282(define_insn "*abssf2_vfp"
283 [(set (match_operand:SF 0 "s_register_operand" "=w")
284 (abs:SF (match_operand:SF 1 "s_register_operand" "w")))]
285 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
286 "fabss%?\\t%0, %1"
287 [(set_attr "predicable" "yes")
288 (set_attr "type" "ffarith")]
289)
290
291(define_insn "*absdf2_vfp"
292 [(set (match_operand:DF 0 "s_register_operand" "=w")
293 (abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
294 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
295 "fabsd%?\\t%P0, %P1"
296 [(set_attr "predicable" "yes")
297 (set_attr "type" "ffarith")]
298)
299
300(define_insn "*negsf2_vfp"
301 [(set (match_operand:SF 0 "s_register_operand" "+w")
302 (neg:SF (match_operand:SF 1 "s_register_operand" "w")))]
303 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
304 "fnegs%?\\t%0, %1"
305 [(set_attr "predicable" "yes")
306 (set_attr "type" "ffarith")]
307)
308
309(define_insn "*negdf2_vfp"
310 [(set (match_operand:DF 0 "s_register_operand" "+w")
311 (neg:DF (match_operand:DF 1 "s_register_operand" "w")))]
312 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
313 "fnegd%?\\t%P0, %P1"
314 [(set_attr "predicable" "yes")
315 (set_attr "type" "ffarith")]
316)
317
318
319;; Arithmetic insns
320
321(define_insn "*addsf3_vfp"
322 [(set (match_operand:SF 0 "s_register_operand" "=w")
323 (plus:SF (match_operand:SF 1 "s_register_operand" "w")
324 (match_operand:SF 2 "s_register_operand" "w")))]
325 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
326 "fadds%?\\t%0, %1, %2"
327 [(set_attr "predicable" "yes")
328 (set_attr "type" "farith")]
329)
330
331(define_insn "*adddf3_vfp"
332 [(set (match_operand:DF 0 "s_register_operand" "=w")
333 (plus:DF (match_operand:DF 1 "s_register_operand" "w")
334 (match_operand:DF 2 "s_register_operand" "w")))]
335 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
336 "faddd%?\\t%P0, %P1, %P2"
337 [(set_attr "predicable" "yes")
338 (set_attr "type" "farith")]
339)
340
341
342(define_insn "*subsf3_vfp"
343 [(set (match_operand:SF 0 "s_register_operand" "=w")
344 (minus:SF (match_operand:SF 1 "s_register_operand" "w")
345 (match_operand:SF 2 "s_register_operand" "w")))]
346 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
347 "fsubs%?\\t%0, %1, %2"
348 [(set_attr "predicable" "yes")
349 (set_attr "type" "farith")]
350)
351
352(define_insn "*subdf3_vfp"
353 [(set (match_operand:DF 0 "s_register_operand" "=w")
354 (minus:DF (match_operand:DF 1 "s_register_operand" "w")
355 (match_operand:DF 2 "s_register_operand" "w")))]
356 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
357 "fsubd%?\\t%P0, %P1, %P2"
358 [(set_attr "predicable" "yes")
359 (set_attr "type" "farith")]
360)
361
362
363;; Division insns
364
365(define_insn "*divsf3_vfp"
366 [(set (match_operand:SF 0 "s_register_operand" "+w")
367 (div:SF (match_operand:SF 1 "s_register_operand" "w")
368 (match_operand:SF 2 "s_register_operand" "w")))]
369 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
370 "fdivs%?\\t%0, %1, %2"
371 [(set_attr "predicable" "yes")
372 (set_attr "type" "fdivs")]
373)
374
375(define_insn "*divdf3_vfp"
376 [(set (match_operand:DF 0 "s_register_operand" "+w")
377 (div:DF (match_operand:DF 1 "s_register_operand" "w")
378 (match_operand:DF 2 "s_register_operand" "w")))]
379 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
380 "fdivd%?\\t%P0, %P1, %P2"
381 [(set_attr "predicable" "yes")
382 (set_attr "type" "fdivd")]
383)
384
385
386;; Multiplication insns
387
388(define_insn "*mulsf3_vfp"
389 [(set (match_operand:SF 0 "s_register_operand" "+w")
390 (mult:SF (match_operand:SF 1 "s_register_operand" "w")
391 (match_operand:SF 2 "s_register_operand" "w")))]
392 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
393 "fmuls%?\\t%0, %1, %2"
394 [(set_attr "predicable" "yes")
395 (set_attr "type" "farith")]
396)
397
398(define_insn "*muldf3_vfp"
399 [(set (match_operand:DF 0 "s_register_operand" "+w")
400 (mult:DF (match_operand:DF 1 "s_register_operand" "w")
401 (match_operand:DF 2 "s_register_operand" "w")))]
402 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
403 "fmuld%?\\t%P0, %P1, %P2"
404 [(set_attr "predicable" "yes")
405 (set_attr "type" "fmul")]
406)
407
408
409(define_insn "*mulsf3negsf_vfp"
410 [(set (match_operand:SF 0 "s_register_operand" "+w")
411 (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "w"))
412 (match_operand:SF 2 "s_register_operand" "w")))]
413 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
414 "fnmuls%?\\t%0, %1, %2"
415 [(set_attr "predicable" "yes")
416 (set_attr "type" "farith")]
417)
418
419(define_insn "*muldf3negdf_vfp"
420 [(set (match_operand:DF 0 "s_register_operand" "+w")
421 (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
422 (match_operand:DF 2 "s_register_operand" "w")))]
423 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
424 "fnmuld%?\\t%P0, %P1, %P2"
425 [(set_attr "predicable" "yes")
426 (set_attr "type" "fmul")]
427)
428
429
430;; Multiply-accumulate insns
431
432;; 0 = 1 * 2 + 0
433(define_insn "*mulsf3addsf_vfp"
434 [(set (match_operand:SF 0 "s_register_operand" "=w")
435 (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "w")
436 (match_operand:SF 3 "s_register_operand" "w"))
437 (match_operand:SF 1 "s_register_operand" "0")))]
438 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
439 "fmacs%?\\t%0, %2, %3"
440 [(set_attr "predicable" "yes")
441 (set_attr "type" "farith")]
442)
443
444(define_insn "*muldf3adddf_vfp"
445 [(set (match_operand:DF 0 "s_register_operand" "=w")
446 (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
447 (match_operand:DF 3 "s_register_operand" "w"))
448 (match_operand:DF 1 "s_register_operand" "0")))]
449 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
450 "fmacd%?\\t%P0, %P2, %P3"
451 [(set_attr "predicable" "yes")
452 (set_attr "type" "fmul")]
453)
454
455;; 0 = 1 * 2 - 0
456(define_insn "*mulsf3subsf_vfp"
457 [(set (match_operand:SF 0 "s_register_operand" "=w")
458 (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "w")
459 (match_operand:SF 3 "s_register_operand" "w"))
460 (match_operand:SF 1 "s_register_operand" "0")))]
461 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
462 "fmscs%?\\t%0, %2, %3"
463 [(set_attr "predicable" "yes")
464 (set_attr "type" "farith")]
465)
466
467(define_insn "*muldf3subdf_vfp"
468 [(set (match_operand:DF 0 "s_register_operand" "=w")
469 (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
470 (match_operand:DF 3 "s_register_operand" "w"))
471 (match_operand:DF 1 "s_register_operand" "0")))]
472 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
473 "fmscd%?\\t%P0, %P2, %P3"
474 [(set_attr "predicable" "yes")
475 (set_attr "type" "fmul")]
476)
477
478;; 0 = -(1 * 2) + 0
479(define_insn "*mulsf3negsfaddsf_vfp"
480 [(set (match_operand:SF 0 "s_register_operand" "=w")
481 (minus:SF (match_operand:SF 1 "s_register_operand" "0")
482 (mult:SF (match_operand:SF 2 "s_register_operand" "w")
483 (match_operand:SF 3 "s_register_operand" "w"))))]
484 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
485 "fnmacs%?\\t%0, %2, %3"
486 [(set_attr "predicable" "yes")
487 (set_attr "type" "farith")]
488)
489
490(define_insn "*fmuldf3negdfadddf_vfp"
491 [(set (match_operand:DF 0 "s_register_operand" "=w")
492 (minus:DF (match_operand:DF 1 "s_register_operand" "0")
493 (mult:DF (match_operand:DF 2 "s_register_operand" "w")
494 (match_operand:DF 3 "s_register_operand" "w"))))]
495 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
496 "fnmacd%?\\t%P0, %P2, %P3"
497 [(set_attr "predicable" "yes")
498 (set_attr "type" "fmul")]
499)
500
501
502;; 0 = -(1 * 2) - 0
503(define_insn "*mulsf3negsfsubsf_vfp"
504 [(set (match_operand:SF 0 "s_register_operand" "=w")
505 (minus:SF (mult:SF
506 (neg:SF (match_operand:SF 2 "s_register_operand" "w"))
507 (match_operand:SF 3 "s_register_operand" "w"))
508 (match_operand:SF 1 "s_register_operand" "0")))]
509 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
510 "fnmscs%?\\t%0, %2, %3"
511 [(set_attr "predicable" "yes")
512 (set_attr "type" "farith")]
513)
514
515(define_insn "*muldf3negdfsubdf_vfp"
516 [(set (match_operand:DF 0 "s_register_operand" "=w")
517 (minus:DF (mult:DF
518 (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
519 (match_operand:DF 3 "s_register_operand" "w"))
520 (match_operand:DF 1 "s_register_operand" "0")))]
521 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
522 "fnmscd%?\\t%P0, %P2, %P3"
523 [(set_attr "predicable" "yes")
524 (set_attr "type" "fmul")]
525)
526
527
528;; Conversion routines
529
530(define_insn "*extendsfdf2_vfp"
531 [(set (match_operand:DF 0 "s_register_operand" "=w")
532 (float_extend:DF (match_operand:SF 1 "s_register_operand" "w")))]
533 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
534 "fcvtds%?\\t%P0, %1"
535 [(set_attr "predicable" "yes")
536 (set_attr "type" "farith")]
537)
538
539(define_insn "*truncdfsf2_vfp"
540 [(set (match_operand:SF 0 "s_register_operand" "=w")
541 (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
542 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
543 "fcvtsd%?\\t%0, %P1"
544 [(set_attr "predicable" "yes")
545 (set_attr "type" "farith")]
546)
547
548(define_insn "*truncsisf2_vfp"
549 [(set (match_operand:SI 0 "s_register_operand" "=w")
550 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "w"))))]
551 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
552 "ftosizs%?\\t%0, %1"
553 [(set_attr "predicable" "yes")
554 (set_attr "type" "farith")]
555)
556
557(define_insn "*truncsidf2_vfp"
558 [(set (match_operand:SI 0 "s_register_operand" "=w")
559 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
560 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
561 "ftosizd%?\\t%0, %P1"
562 [(set_attr "predicable" "yes")
563 (set_attr "type" "farith")]
564)
565
6f6c1f6d
PB
566
567(define_insn "fixuns_truncsfsi2"
568 [(set (match_operand:SI 0 "s_register_operand" "=w")
569 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "w"))))]
570 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
571 "ftouizs%?\\t%0, %1"
572 [(set_attr "predicable" "yes")
573 (set_attr "type" "farith")]
574)
575
576(define_insn "fixuns_truncdfsi2"
577 [(set (match_operand:SI 0 "s_register_operand" "=w")
578 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
579 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
580 "ftouizd%?\\t%0, %P1"
581 [(set_attr "predicable" "yes")
582 (set_attr "type" "farith")]
583)
584
585
9b66ebb1
PB
586(define_insn "*floatsisf2_vfp"
587 [(set (match_operand:SF 0 "s_register_operand" "=w")
588 (float:SF (match_operand:SI 1 "s_register_operand" "w")))]
589 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
590 "fsitos%?\\t%0, %1"
591 [(set_attr "predicable" "yes")
592 (set_attr "type" "farith")]
593)
594
595(define_insn "*floatsidf2_vfp"
596 [(set (match_operand:DF 0 "s_register_operand" "=w")
597 (float:DF (match_operand:SI 1 "s_register_operand" "w")))]
598 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
599 "fsitod%?\\t%P0, %1"
600 [(set_attr "predicable" "yes")
601 (set_attr "type" "farith")]
602)
603
604
6f6c1f6d
PB
605(define_insn "floatunssisf2"
606 [(set (match_operand:SF 0 "s_register_operand" "=w")
607 (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "w")))]
608 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
609 "fuitos%?\\t%0, %1"
610 [(set_attr "predicable" "yes")
611 (set_attr "type" "farith")]
612)
613
614(define_insn "floatunssidf2"
615 [(set (match_operand:DF 0 "s_register_operand" "=w")
616 (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "w")))]
617 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
618 "fuitod%?\\t%P0, %1"
619 [(set_attr "predicable" "yes")
620 (set_attr "type" "farith")]
621)
622
623
9b66ebb1
PB
624;; Sqrt insns.
625
626(define_insn "*sqrtsf2_vfp"
627 [(set (match_operand:SF 0 "s_register_operand" "=w")
628 (sqrt:SF (match_operand:SF 1 "s_register_operand" "w")))]
629 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
630 "fsqrts%?\\t%0, %1"
631 [(set_attr "predicable" "yes")
632 (set_attr "type" "fdivs")]
633)
634
635(define_insn "*sqrtdf2_vfp"
636 [(set (match_operand:DF 0 "s_register_operand" "=w")
637 (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))]
638 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
639 "fsqrtd%?\\t%P0, %P1"
640 [(set_attr "predicable" "yes")
641 (set_attr "type" "fdivd")]
642)
643
644
645;; Patterns to split/copy vfp condition flags.
646
647(define_insn "*movcc_vfp"
648 [(set (reg CC_REGNUM)
649 (reg VFPCC_REGNUM))]
650 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
651 "fmstat%?"
652 [(set_attr "conds" "set")
653 (set_attr "type" "ffarith")]
654)
655
656(define_insn_and_split "*cmpsf_split_vfp"
657 [(set (reg:CCFP CC_REGNUM)
658 (compare:CCFP (match_operand:SF 0 "s_register_operand" "w")
659 (match_operand:SF 1 "vfp_compare_operand" "wG")))]
660 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
661 "#"
662 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
663 [(set (reg:CCFP VFPCC_REGNUM)
664 (compare:CCFP (match_dup 0)
665 (match_dup 1)))
666 (set (reg:CCFP CC_REGNUM)
667 (reg:CCFP VFPCC_REGNUM))]
668 ""
669)
670
671(define_insn_and_split "*cmpsf_trap_split_vfp"
672 [(set (reg:CCFPE CC_REGNUM)
673 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "w")
674 (match_operand:SF 1 "vfp_compare_operand" "wG")))]
675 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
676 "#"
677 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
678 [(set (reg:CCFPE VFPCC_REGNUM)
679 (compare:CCFPE (match_dup 0)
680 (match_dup 1)))
681 (set (reg:CCFPE CC_REGNUM)
682 (reg:CCFPE VFPCC_REGNUM))]
683 ""
684)
685
686(define_insn_and_split "*cmpdf_split_vfp"
687 [(set (reg:CCFP CC_REGNUM)
688 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w")
689 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
690 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
691 "#"
692 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
693 [(set (reg:CCFP VFPCC_REGNUM)
694 (compare:CCFP (match_dup 0)
695 (match_dup 1)))
696 (set (reg:CCFP CC_REGNUM)
697 (reg:CCFPE VFPCC_REGNUM))]
698 ""
699)
700
701(define_insn_and_split "*cmpdf_trap_split_vfp"
702 [(set (reg:CCFPE CC_REGNUM)
703 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w")
704 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
705 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
706 "#"
707 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
708 [(set (reg:CCFPE VFPCC_REGNUM)
709 (compare:CCFPE (match_dup 0)
710 (match_dup 1)))
711 (set (reg:CCFPE CC_REGNUM)
712 (reg:CCFPE VFPCC_REGNUM))]
713 ""
714)
715
716
717;; Comparison patterns
718
719(define_insn "*cmpsf_vfp"
720 [(set (reg:CCFP VFPCC_REGNUM)
721 (compare:CCFP (match_operand:SF 0 "s_register_operand" "w,w")
722 (match_operand:SF 1 "vfp_compare_operand" "w,G")))]
723 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
724 "@
725 fcmps%?\\t%0, %1
726 fcmpzs%?\\t%0"
727 [(set_attr "predicable" "yes")
728 (set_attr "type" "ffarith")]
729)
730
731(define_insn "*cmpsf_trap_vfp"
732 [(set (reg:CCFPE VFPCC_REGNUM)
733 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "w,w")
734 (match_operand:SF 1 "vfp_compare_operand" "w,G")))]
735 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
736 "@
737 fcmpes%?\\t%0, %1
738 fcmpezs%?\\t%0"
739 [(set_attr "predicable" "yes")
740 (set_attr "type" "ffarith")]
741)
742
743(define_insn "*cmpdf_vfp"
744 [(set (reg:CCFP VFPCC_REGNUM)
745 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w")
746 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
747 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
748 "@
749 fcmpd%?\\t%P0, %P1
750 fcmpzd%?\\t%P0"
751 [(set_attr "predicable" "yes")
752 (set_attr "type" "ffarith")]
753)
754
755(define_insn "*cmpdf_trap_vfp"
756 [(set (reg:CCFPE VFPCC_REGNUM)
757 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w")
758 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
759 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
760 "@
761 fcmped%?\\t%P0, %P1
762 fcmpezd%?\\t%P0"
763 [(set_attr "predicable" "yes")
764 (set_attr "type" "ffarith")]
765)
766
767
768;; Store multiple insn used in function prologue.
769
770(define_insn "*push_multi_vfp"
771 [(match_parallel 2 "multi_register_push"
772 [(set (match_operand:BLK 0 "memory_operand" "=m")
773 (unspec:BLK [(match_operand:DF 1 "s_register_operand" "w")]
774 UNSPEC_PUSH_MULT))])]
775 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
776 "* return vfp_output_fstmx (operands);"
777 [(set_attr "type" "f_store")]
778)
779
780
781;; Unimplemented insns:
782;; fldm*
783;; fstm*
784;; fmdhr et al (VFPv1)
59b9a953 785;; Support for xD (single precision only) variants.
9b66ebb1 786;; fmrrs, fmsrr