1 ;; ARM VFP coprocessor Machine Description
2 ;; Copyright (C) 2003, 2005 Free Software Foundation, Inc.
3 ;; Written by CodeSourcery, LLC.
5 ;; This file is part of GCC.
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)
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.
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, 51 Franklin Street, Fifth Floor, Boston, MA
20 ;; 02110-1301, USA. */
22 ;; Additional register numbers
27 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28 ;; Pipeline description
29 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
31 (define_automaton "vfp11")
33 ;; There are 3 pipelines in the VFP11 unit.
35 ;; - A 8-stage FMAC pipeline (7 execute + writeback) with forward from
36 ;; fourth stage for simple operations.
38 ;; - A 5-stage DS pipeline (4 execute + writeback) for divide/sqrt insns.
39 ;; These insns also uses first execute stage of FMAC pipeline.
41 ;; - A 4-stage LS pipeline (execute + 2 memory + writeback) with forward from
42 ;; second memory stage for loads.
44 ;; We do not model Write-After-Read hazards.
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
47 ;; ??? Need to model LS pipeline properly for load/store multiple?
48 ;; We do not model fmstat properly. This could be done by modeling pipelines
49 ;; properly and defining an absence set between a dummy fmstat unit and all
52 (define_cpu_unit "fmac" "vfp11")
54 (define_cpu_unit "ds" "vfp11")
56 (define_cpu_unit "vfp_ls" "vfp11")
58 (define_cpu_unit "fmstat" "vfp11")
60 (exclusion_set "fmac,ds" "fmstat")
62 ;; The VFP "type" attributes differ from those used in the FPA model.
63 ;; ffarith Fast floating point insns, e.g. abs, neg, cpy, cmp.
64 ;; farith Most arithmetic insns.
65 ;; fmul Double precision multiply.
66 ;; fdivs Single precision sqrt or division.
67 ;; fdivd Double precision sqrt or division.
68 ;; f_flag fmstat operation
69 ;; f_load[sd] Floating point load from memory.
70 ;; f_store[sd] Floating point store to memory.
71 ;; f_2_r Transfer vfp to arm reg.
72 ;; r_2_f Transfer arm to vfp reg.
73 ;; f_cvt Convert floating<->integral
75 (define_insn_reservation "vfp_ffarith" 4
76 (and (eq_attr "generic_vfp" "yes")
77 (eq_attr "type" "ffarith"))
80 (define_insn_reservation "vfp_farith" 8
81 (and (eq_attr "generic_vfp" "yes")
82 (eq_attr "type" "farith,f_cvt"))
85 (define_insn_reservation "vfp_fmul" 9
86 (and (eq_attr "generic_vfp" "yes")
87 (eq_attr "type" "fmul"))
90 (define_insn_reservation "vfp_fdivs" 19
91 (and (eq_attr "generic_vfp" "yes")
92 (eq_attr "type" "fdivs"))
95 (define_insn_reservation "vfp_fdivd" 33
96 (and (eq_attr "generic_vfp" "yes")
97 (eq_attr "type" "fdivd"))
100 ;; Moves to/from arm regs also use the load/store pipeline.
101 (define_insn_reservation "vfp_fload" 4
102 (and (eq_attr "generic_vfp" "yes")
103 (eq_attr "type" "f_loads,f_loadd,r_2_f"))
106 (define_insn_reservation "vfp_fstore" 4
107 (and (eq_attr "generic_vfp" "yes")
108 (eq_attr "type" "f_stores,f_stored,f_2_r"))
111 (define_insn_reservation "vfp_to_cpsr" 4
112 (and (eq_attr "generic_vfp" "yes")
113 (eq_attr "type" "f_flag"))
116 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
118 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
121 ;; ??? For now do not allow loading constants into vfp regs. This causes
122 ;; problems because small constants get converted into adds.
123 (define_insn "*arm_movsi_vfp"
124 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r ,m,*w,r,*w,*w, *Uv")
125 (match_operand:SI 1 "general_operand" "rI,K,mi,r,r,*w,*w,*Uvi,*w"))]
126 "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
127 && ( s_register_operand (operands[0], SImode)
128 || s_register_operand (operands[1], SImode))"
134 fmsr%?\\t%0, %1\\t%@ int
135 fmrs%?\\t%0, %1\\t%@ int
136 fcpys%?\\t%0, %1\\t%@ int
137 flds%?\\t%0, %1\\t%@ int
138 fsts%?\\t%1, %0\\t%@ int"
139 [(set_attr "predicable" "yes")
140 (set_attr "type" "*,*,load1,store1,r_2_f,f_2_r,ffarith,f_loads,f_stores")
141 (set_attr "pool_range" "*,*,4096,*,*,*,*,1020,*")
142 (set_attr "neg_pool_range" "*,*,4084,*,*,*,*,1008,*")]
148 (define_insn "*arm_movdi_vfp"
149 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
150 (match_operand:DI 1 "di_operand" "rIK,mi,r,r,w,w,Uvi,w"))]
151 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
153 switch (which_alternative)
159 return output_move_double (operands);
161 return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
163 return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
165 return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
167 return \"fldd%?\\t%P0, %1\\t%@ int\";
169 return \"fstd%?\\t%P1, %0\\t%@ int\";
174 [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_loadd,f_stored")
175 (set_attr "length" "8,8,8,4,4,4,4,4")
176 (set_attr "pool_range" "*,1020,*,*,*,*,1020,*")
177 (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
183 (define_insn "*movsf_vfp"
184 [(set (match_operand:SF 0 "nonimmediate_operand" "=w,r,w ,Uv,r ,m,w,r")
185 (match_operand:SF 1 "general_operand" " r,w,UvE,w, mE,r,w,r"))]
186 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
187 && ( s_register_operand (operands[0], SFmode)
188 || s_register_operand (operands[1], SFmode))"
194 ldr%?\\t%0, %1\\t%@ float
195 str%?\\t%1, %0\\t%@ float
197 mov%?\\t%0, %1\\t%@ float"
198 [(set_attr "predicable" "yes")
199 (set_attr "type" "r_2_f,f_2_r,ffarith,*,f_loads,f_stores,load1,store1")
200 (set_attr "pool_range" "*,*,1020,*,4096,*,*,*")
201 (set_attr "neg_pool_range" "*,*,1008,*,4080,*,*,*")]
207 (define_insn "*movdf_vfp"
208 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,r,r, m,w ,Uv,w,r")
209 (match_operand:DF 1 "soft_df_operand" " r,w,mF,r,UvF,w, w,r"))]
210 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
213 switch (which_alternative)
216 return \"fmdrr%?\\t%P0, %Q1, %R1\";
218 return \"fmrrd%?\\t%Q0, %R0, %P1\";
220 return output_move_double (operands);
222 return \"fldd%?\\t%P0, %1\";
224 return \"fstd%?\\t%P1, %0\";
226 return \"fcpyd%?\\t%P0, %P1\";
234 [(set_attr "type" "r_2_f,f_2_r,ffarith,*,load2,store2,f_loadd,f_stored")
235 (set_attr "length" "4,4,8,8,4,4,4,8")
236 (set_attr "pool_range" "*,*,1020,*,1020,*,*,*")
237 (set_attr "neg_pool_range" "*,*,1008,*,1008,*,*,*")]
241 ;; Conditional move patterns
243 (define_insn "*movsfcc_vfp"
244 [(set (match_operand:SF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
246 (match_operator 3 "arm_comparison_operator"
247 [(match_operand 4 "cc_register" "") (const_int 0)])
248 (match_operand:SF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
249 (match_operand:SF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
250 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
254 fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
257 fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
260 fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
261 [(set_attr "conds" "use")
262 (set_attr "length" "4,4,8,4,4,8,4,4,8")
263 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
266 (define_insn "*movdfcc_vfp"
267 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
269 (match_operator 3 "arm_comparison_operator"
270 [(match_operand 4 "cc_register" "") (const_int 0)])
271 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
272 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
273 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
277 fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
278 fmdrr%D3\\t%P0, %Q2, %R2
279 fmdrr%d3\\t%P0, %Q1, %R1
280 fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
281 fmrrd%D3\\t%Q0, %R0, %P2
282 fmrrd%d3\\t%Q0, %R0, %P1
283 fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
284 [(set_attr "conds" "use")
285 (set_attr "length" "4,4,8,4,4,8,4,4,8")
286 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
290 ;; Sign manipulation functions
292 (define_insn "*abssf2_vfp"
293 [(set (match_operand:SF 0 "s_register_operand" "=w")
294 (abs:SF (match_operand:SF 1 "s_register_operand" "w")))]
295 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
297 [(set_attr "predicable" "yes")
298 (set_attr "type" "ffarith")]
301 (define_insn "*absdf2_vfp"
302 [(set (match_operand:DF 0 "s_register_operand" "=w")
303 (abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
304 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
306 [(set_attr "predicable" "yes")
307 (set_attr "type" "ffarith")]
310 (define_insn "*negsf2_vfp"
311 [(set (match_operand:SF 0 "s_register_operand" "=w,?r")
312 (neg:SF (match_operand:SF 1 "s_register_operand" "w,r")))]
313 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
316 eor%?\\t%0, %1, #-2147483648"
317 [(set_attr "predicable" "yes")
318 (set_attr "type" "ffarith")]
321 (define_insn_and_split "*negdf2_vfp"
322 [(set (match_operand:DF 0 "s_register_operand" "=w,?r,?r")
323 (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))]
324 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
329 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP && reload_completed
330 && arm_general_register_operand (operands[0], DFmode)"
331 [(set (match_dup 0) (match_dup 1))]
333 if (REGNO (operands[0]) == REGNO (operands[1]))
335 operands[0] = gen_highpart (SImode, operands[0]);
336 operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000));
340 rtx in_hi, in_lo, out_hi, out_lo;
342 in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]),
343 GEN_INT (0x80000000));
344 in_lo = gen_lowpart (SImode, operands[1]);
345 out_hi = gen_highpart (SImode, operands[0]);
346 out_lo = gen_lowpart (SImode, operands[0]);
348 if (REGNO (in_lo) == REGNO (out_hi))
350 emit_insn (gen_rtx_SET (SImode, out_lo, in_lo));
351 operands[0] = out_hi;
356 emit_insn (gen_rtx_SET (SImode, out_hi, in_hi));
357 operands[0] = out_lo;
362 [(set_attr "predicable" "yes")
363 (set_attr "length" "4,4,8")
364 (set_attr "type" "ffarith")]
370 (define_insn "*addsf3_vfp"
371 [(set (match_operand:SF 0 "s_register_operand" "=w")
372 (plus:SF (match_operand:SF 1 "s_register_operand" "w")
373 (match_operand:SF 2 "s_register_operand" "w")))]
374 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
375 "fadds%?\\t%0, %1, %2"
376 [(set_attr "predicable" "yes")
377 (set_attr "type" "farith")]
380 (define_insn "*adddf3_vfp"
381 [(set (match_operand:DF 0 "s_register_operand" "=w")
382 (plus:DF (match_operand:DF 1 "s_register_operand" "w")
383 (match_operand:DF 2 "s_register_operand" "w")))]
384 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
385 "faddd%?\\t%P0, %P1, %P2"
386 [(set_attr "predicable" "yes")
387 (set_attr "type" "farith")]
391 (define_insn "*subsf3_vfp"
392 [(set (match_operand:SF 0 "s_register_operand" "=w")
393 (minus:SF (match_operand:SF 1 "s_register_operand" "w")
394 (match_operand:SF 2 "s_register_operand" "w")))]
395 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
396 "fsubs%?\\t%0, %1, %2"
397 [(set_attr "predicable" "yes")
398 (set_attr "type" "farith")]
401 (define_insn "*subdf3_vfp"
402 [(set (match_operand:DF 0 "s_register_operand" "=w")
403 (minus:DF (match_operand:DF 1 "s_register_operand" "w")
404 (match_operand:DF 2 "s_register_operand" "w")))]
405 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
406 "fsubd%?\\t%P0, %P1, %P2"
407 [(set_attr "predicable" "yes")
408 (set_attr "type" "farith")]
414 (define_insn "*divsf3_vfp"
415 [(set (match_operand:SF 0 "s_register_operand" "+w")
416 (div:SF (match_operand:SF 1 "s_register_operand" "w")
417 (match_operand:SF 2 "s_register_operand" "w")))]
418 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
419 "fdivs%?\\t%0, %1, %2"
420 [(set_attr "predicable" "yes")
421 (set_attr "type" "fdivs")]
424 (define_insn "*divdf3_vfp"
425 [(set (match_operand:DF 0 "s_register_operand" "+w")
426 (div:DF (match_operand:DF 1 "s_register_operand" "w")
427 (match_operand:DF 2 "s_register_operand" "w")))]
428 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
429 "fdivd%?\\t%P0, %P1, %P2"
430 [(set_attr "predicable" "yes")
431 (set_attr "type" "fdivd")]
435 ;; Multiplication insns
437 (define_insn "*mulsf3_vfp"
438 [(set (match_operand:SF 0 "s_register_operand" "+w")
439 (mult:SF (match_operand:SF 1 "s_register_operand" "w")
440 (match_operand:SF 2 "s_register_operand" "w")))]
441 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
442 "fmuls%?\\t%0, %1, %2"
443 [(set_attr "predicable" "yes")
444 (set_attr "type" "farith")]
447 (define_insn "*muldf3_vfp"
448 [(set (match_operand:DF 0 "s_register_operand" "+w")
449 (mult:DF (match_operand:DF 1 "s_register_operand" "w")
450 (match_operand:DF 2 "s_register_operand" "w")))]
451 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
452 "fmuld%?\\t%P0, %P1, %P2"
453 [(set_attr "predicable" "yes")
454 (set_attr "type" "fmul")]
458 (define_insn "*mulsf3negsf_vfp"
459 [(set (match_operand:SF 0 "s_register_operand" "+w")
460 (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "w"))
461 (match_operand:SF 2 "s_register_operand" "w")))]
462 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
463 "fnmuls%?\\t%0, %1, %2"
464 [(set_attr "predicable" "yes")
465 (set_attr "type" "farith")]
468 (define_insn "*muldf3negdf_vfp"
469 [(set (match_operand:DF 0 "s_register_operand" "+w")
470 (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
471 (match_operand:DF 2 "s_register_operand" "w")))]
472 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
473 "fnmuld%?\\t%P0, %P1, %P2"
474 [(set_attr "predicable" "yes")
475 (set_attr "type" "fmul")]
479 ;; Multiply-accumulate insns
482 (define_insn "*mulsf3addsf_vfp"
483 [(set (match_operand:SF 0 "s_register_operand" "=w")
484 (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "w")
485 (match_operand:SF 3 "s_register_operand" "w"))
486 (match_operand:SF 1 "s_register_operand" "0")))]
487 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
488 "fmacs%?\\t%0, %2, %3"
489 [(set_attr "predicable" "yes")
490 (set_attr "type" "farith")]
493 (define_insn "*muldf3adddf_vfp"
494 [(set (match_operand:DF 0 "s_register_operand" "=w")
495 (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
496 (match_operand:DF 3 "s_register_operand" "w"))
497 (match_operand:DF 1 "s_register_operand" "0")))]
498 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
499 "fmacd%?\\t%P0, %P2, %P3"
500 [(set_attr "predicable" "yes")
501 (set_attr "type" "fmul")]
505 (define_insn "*mulsf3subsf_vfp"
506 [(set (match_operand:SF 0 "s_register_operand" "=w")
507 (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "w")
508 (match_operand:SF 3 "s_register_operand" "w"))
509 (match_operand:SF 1 "s_register_operand" "0")))]
510 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
511 "fmscs%?\\t%0, %2, %3"
512 [(set_attr "predicable" "yes")
513 (set_attr "type" "farith")]
516 (define_insn "*muldf3subdf_vfp"
517 [(set (match_operand:DF 0 "s_register_operand" "=w")
518 (minus:DF (mult: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 "fmscd%?\\t%P0, %P2, %P3"
523 [(set_attr "predicable" "yes")
524 (set_attr "type" "fmul")]
528 (define_insn "*mulsf3negsfaddsf_vfp"
529 [(set (match_operand:SF 0 "s_register_operand" "=w")
530 (minus:SF (match_operand:SF 1 "s_register_operand" "0")
531 (mult:SF (match_operand:SF 2 "s_register_operand" "w")
532 (match_operand:SF 3 "s_register_operand" "w"))))]
533 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
534 "fnmacs%?\\t%0, %2, %3"
535 [(set_attr "predicable" "yes")
536 (set_attr "type" "farith")]
539 (define_insn "*fmuldf3negdfadddf_vfp"
540 [(set (match_operand:DF 0 "s_register_operand" "=w")
541 (minus:DF (match_operand:DF 1 "s_register_operand" "0")
542 (mult:DF (match_operand:DF 2 "s_register_operand" "w")
543 (match_operand:DF 3 "s_register_operand" "w"))))]
544 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
545 "fnmacd%?\\t%P0, %P2, %P3"
546 [(set_attr "predicable" "yes")
547 (set_attr "type" "fmul")]
552 (define_insn "*mulsf3negsfsubsf_vfp"
553 [(set (match_operand:SF 0 "s_register_operand" "=w")
555 (neg:SF (match_operand:SF 2 "s_register_operand" "w"))
556 (match_operand:SF 3 "s_register_operand" "w"))
557 (match_operand:SF 1 "s_register_operand" "0")))]
558 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
559 "fnmscs%?\\t%0, %2, %3"
560 [(set_attr "predicable" "yes")
561 (set_attr "type" "farith")]
564 (define_insn "*muldf3negdfsubdf_vfp"
565 [(set (match_operand:DF 0 "s_register_operand" "=w")
567 (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
568 (match_operand:DF 3 "s_register_operand" "w"))
569 (match_operand:DF 1 "s_register_operand" "0")))]
570 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
571 "fnmscd%?\\t%P0, %P2, %P3"
572 [(set_attr "predicable" "yes")
573 (set_attr "type" "fmul")]
577 ;; Conversion routines
579 (define_insn "*extendsfdf2_vfp"
580 [(set (match_operand:DF 0 "s_register_operand" "=w")
581 (float_extend:DF (match_operand:SF 1 "s_register_operand" "w")))]
582 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
584 [(set_attr "predicable" "yes")
585 (set_attr "type" "f_cvt")]
588 (define_insn "*truncdfsf2_vfp"
589 [(set (match_operand:SF 0 "s_register_operand" "=w")
590 (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
591 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
593 [(set_attr "predicable" "yes")
594 (set_attr "type" "f_cvt")]
597 (define_insn "*truncsisf2_vfp"
598 [(set (match_operand:SI 0 "s_register_operand" "=w")
599 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "w"))))]
600 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
602 [(set_attr "predicable" "yes")
603 (set_attr "type" "f_cvt")]
606 (define_insn "*truncsidf2_vfp"
607 [(set (match_operand:SI 0 "s_register_operand" "=w")
608 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
609 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
610 "ftosizd%?\\t%0, %P1"
611 [(set_attr "predicable" "yes")
612 (set_attr "type" "f_cvt")]
616 (define_insn "fixuns_truncsfsi2"
617 [(set (match_operand:SI 0 "s_register_operand" "=w")
618 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "w"))))]
619 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
621 [(set_attr "predicable" "yes")
622 (set_attr "type" "f_cvt")]
625 (define_insn "fixuns_truncdfsi2"
626 [(set (match_operand:SI 0 "s_register_operand" "=w")
627 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
628 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
629 "ftouizd%?\\t%0, %P1"
630 [(set_attr "predicable" "yes")
631 (set_attr "type" "f_cvt")]
635 (define_insn "*floatsisf2_vfp"
636 [(set (match_operand:SF 0 "s_register_operand" "=w")
637 (float:SF (match_operand:SI 1 "s_register_operand" "w")))]
638 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
640 [(set_attr "predicable" "yes")
641 (set_attr "type" "f_cvt")]
644 (define_insn "*floatsidf2_vfp"
645 [(set (match_operand:DF 0 "s_register_operand" "=w")
646 (float:DF (match_operand:SI 1 "s_register_operand" "w")))]
647 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
649 [(set_attr "predicable" "yes")
650 (set_attr "type" "f_cvt")]
654 (define_insn "floatunssisf2"
655 [(set (match_operand:SF 0 "s_register_operand" "=w")
656 (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "w")))]
657 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
659 [(set_attr "predicable" "yes")
660 (set_attr "type" "f_cvt")]
663 (define_insn "floatunssidf2"
664 [(set (match_operand:DF 0 "s_register_operand" "=w")
665 (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "w")))]
666 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
668 [(set_attr "predicable" "yes")
669 (set_attr "type" "f_cvt")]
675 (define_insn "*sqrtsf2_vfp"
676 [(set (match_operand:SF 0 "s_register_operand" "=w")
677 (sqrt:SF (match_operand:SF 1 "s_register_operand" "w")))]
678 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
680 [(set_attr "predicable" "yes")
681 (set_attr "type" "fdivs")]
684 (define_insn "*sqrtdf2_vfp"
685 [(set (match_operand:DF 0 "s_register_operand" "=w")
686 (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))]
687 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
688 "fsqrtd%?\\t%P0, %P1"
689 [(set_attr "predicable" "yes")
690 (set_attr "type" "fdivd")]
694 ;; Patterns to split/copy vfp condition flags.
696 (define_insn "*movcc_vfp"
697 [(set (reg CC_REGNUM)
699 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
701 [(set_attr "conds" "set")
702 (set_attr "type" "f_flag")]
705 (define_insn_and_split "*cmpsf_split_vfp"
706 [(set (reg:CCFP CC_REGNUM)
707 (compare:CCFP (match_operand:SF 0 "s_register_operand" "w")
708 (match_operand:SF 1 "vfp_compare_operand" "wG")))]
709 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
711 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
712 [(set (reg:CCFP VFPCC_REGNUM)
713 (compare:CCFP (match_dup 0)
715 (set (reg:CCFP CC_REGNUM)
716 (reg:CCFP VFPCC_REGNUM))]
720 (define_insn_and_split "*cmpsf_trap_split_vfp"
721 [(set (reg:CCFPE CC_REGNUM)
722 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "w")
723 (match_operand:SF 1 "vfp_compare_operand" "wG")))]
724 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
726 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
727 [(set (reg:CCFPE VFPCC_REGNUM)
728 (compare:CCFPE (match_dup 0)
730 (set (reg:CCFPE CC_REGNUM)
731 (reg:CCFPE VFPCC_REGNUM))]
735 (define_insn_and_split "*cmpdf_split_vfp"
736 [(set (reg:CCFP CC_REGNUM)
737 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w")
738 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
739 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
741 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
742 [(set (reg:CCFP VFPCC_REGNUM)
743 (compare:CCFP (match_dup 0)
745 (set (reg:CCFP CC_REGNUM)
746 (reg:CCFPE VFPCC_REGNUM))]
750 (define_insn_and_split "*cmpdf_trap_split_vfp"
751 [(set (reg:CCFPE CC_REGNUM)
752 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w")
753 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
754 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
756 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
757 [(set (reg:CCFPE VFPCC_REGNUM)
758 (compare:CCFPE (match_dup 0)
760 (set (reg:CCFPE CC_REGNUM)
761 (reg:CCFPE VFPCC_REGNUM))]
766 ;; Comparison patterns
768 (define_insn "*cmpsf_vfp"
769 [(set (reg:CCFP VFPCC_REGNUM)
770 (compare:CCFP (match_operand:SF 0 "s_register_operand" "w,w")
771 (match_operand:SF 1 "vfp_compare_operand" "w,G")))]
772 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
776 [(set_attr "predicable" "yes")
777 (set_attr "type" "ffarith")]
780 (define_insn "*cmpsf_trap_vfp"
781 [(set (reg:CCFPE VFPCC_REGNUM)
782 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "w,w")
783 (match_operand:SF 1 "vfp_compare_operand" "w,G")))]
784 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
788 [(set_attr "predicable" "yes")
789 (set_attr "type" "ffarith")]
792 (define_insn "*cmpdf_vfp"
793 [(set (reg:CCFP VFPCC_REGNUM)
794 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w")
795 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
796 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
800 [(set_attr "predicable" "yes")
801 (set_attr "type" "ffarith")]
804 (define_insn "*cmpdf_trap_vfp"
805 [(set (reg:CCFPE VFPCC_REGNUM)
806 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w")
807 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
808 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
812 [(set_attr "predicable" "yes")
813 (set_attr "type" "ffarith")]
817 ;; Store multiple insn used in function prologue.
819 (define_insn "*push_multi_vfp"
820 [(match_parallel 2 "multi_register_push"
821 [(set (match_operand:BLK 0 "memory_operand" "=m")
822 (unspec:BLK [(match_operand:DF 1 "s_register_operand" "w")]
823 UNSPEC_PUSH_MULT))])]
824 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
825 "* return vfp_output_fstmx (operands);"
826 [(set_attr "type" "f_stored")]
830 ;; Unimplemented insns:
833 ;; fmdhr et al (VFPv1)
834 ;; Support for xD (single precision only) variants.