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
152 && ( register_operand (operands[0], DImode)
153 || register_operand (operands[1], DImode))"
155 switch (which_alternative)
161 return output_move_double (operands);
163 return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
165 return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
167 return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
169 return \"fldd%?\\t%P0, %1\\t%@ int\";
171 return \"fstd%?\\t%P1, %0\\t%@ int\";
176 [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_loadd,f_stored")
177 (set_attr "length" "8,8,8,4,4,4,4,4")
178 (set_attr "pool_range" "*,1020,*,*,*,*,1020,*")
179 (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
184 ;; Disparage the w<->r cases because reloading an invalid address is
185 ;; preferable to loading the value via integer registers.
187 (define_insn "*movsf_vfp"
188 [(set (match_operand:SF 0 "nonimmediate_operand" "=w,?r,w ,Uv,r ,m,w,r")
189 (match_operand:SF 1 "general_operand" " ?r,w,UvE,w, mE,r,w,r"))]
190 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
191 && ( s_register_operand (operands[0], SFmode)
192 || s_register_operand (operands[1], SFmode))"
198 ldr%?\\t%0, %1\\t%@ float
199 str%?\\t%1, %0\\t%@ float
201 mov%?\\t%0, %1\\t%@ float"
202 [(set_attr "predicable" "yes")
203 (set_attr "type" "r_2_f,f_2_r,ffarith,*,f_loads,f_stores,load1,store1")
204 (set_attr "pool_range" "*,*,1020,*,4096,*,*,*")
205 (set_attr "neg_pool_range" "*,*,1008,*,4080,*,*,*")]
211 (define_insn "*movdf_vfp"
212 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,r, m,w ,Uv,w,r")
213 (match_operand:DF 1 "soft_df_operand" " ?r,w,mF,r,UvF,w, w,r"))]
214 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
215 && ( register_operand (operands[0], DFmode)
216 || register_operand (operands[1], DFmode))"
219 switch (which_alternative)
222 return \"fmdrr%?\\t%P0, %Q1, %R1\";
224 return \"fmrrd%?\\t%Q0, %R0, %P1\";
226 return output_move_double (operands);
228 return \"fldd%?\\t%P0, %1\";
230 return \"fstd%?\\t%P1, %0\";
232 return \"fcpyd%?\\t%P0, %P1\";
240 [(set_attr "type" "r_2_f,f_2_r,ffarith,*,load2,store2,f_loadd,f_stored")
241 (set_attr "length" "4,4,8,8,4,4,4,8")
242 (set_attr "pool_range" "*,*,1020,*,1020,*,*,*")
243 (set_attr "neg_pool_range" "*,*,1008,*,1008,*,*,*")]
247 ;; Conditional move patterns
249 (define_insn "*movsfcc_vfp"
250 [(set (match_operand:SF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
252 (match_operator 3 "arm_comparison_operator"
253 [(match_operand 4 "cc_register" "") (const_int 0)])
254 (match_operand:SF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
255 (match_operand:SF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
256 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
260 fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
263 fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
266 fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
267 [(set_attr "conds" "use")
268 (set_attr "length" "4,4,8,4,4,8,4,4,8")
269 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
272 (define_insn "*movdfcc_vfp"
273 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
275 (match_operator 3 "arm_comparison_operator"
276 [(match_operand 4 "cc_register" "") (const_int 0)])
277 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
278 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
279 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
283 fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
284 fmdrr%D3\\t%P0, %Q2, %R2
285 fmdrr%d3\\t%P0, %Q1, %R1
286 fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
287 fmrrd%D3\\t%Q0, %R0, %P2
288 fmrrd%d3\\t%Q0, %R0, %P1
289 fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
290 [(set_attr "conds" "use")
291 (set_attr "length" "4,4,8,4,4,8,4,4,8")
292 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
296 ;; Sign manipulation functions
298 (define_insn "*abssf2_vfp"
299 [(set (match_operand:SF 0 "s_register_operand" "=w")
300 (abs:SF (match_operand:SF 1 "s_register_operand" "w")))]
301 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
303 [(set_attr "predicable" "yes")
304 (set_attr "type" "ffarith")]
307 (define_insn "*absdf2_vfp"
308 [(set (match_operand:DF 0 "s_register_operand" "=w")
309 (abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
310 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
312 [(set_attr "predicable" "yes")
313 (set_attr "type" "ffarith")]
316 (define_insn "*negsf2_vfp"
317 [(set (match_operand:SF 0 "s_register_operand" "=w,?r")
318 (neg:SF (match_operand:SF 1 "s_register_operand" "w,r")))]
319 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
322 eor%?\\t%0, %1, #-2147483648"
323 [(set_attr "predicable" "yes")
324 (set_attr "type" "ffarith")]
327 (define_insn_and_split "*negdf2_vfp"
328 [(set (match_operand:DF 0 "s_register_operand" "=w,?r,?r")
329 (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))]
330 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
335 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP && reload_completed
336 && arm_general_register_operand (operands[0], DFmode)"
337 [(set (match_dup 0) (match_dup 1))]
339 if (REGNO (operands[0]) == REGNO (operands[1]))
341 operands[0] = gen_highpart (SImode, operands[0]);
342 operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000));
346 rtx in_hi, in_lo, out_hi, out_lo;
348 in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]),
349 GEN_INT (0x80000000));
350 in_lo = gen_lowpart (SImode, operands[1]);
351 out_hi = gen_highpart (SImode, operands[0]);
352 out_lo = gen_lowpart (SImode, operands[0]);
354 if (REGNO (in_lo) == REGNO (out_hi))
356 emit_insn (gen_rtx_SET (SImode, out_lo, in_lo));
357 operands[0] = out_hi;
362 emit_insn (gen_rtx_SET (SImode, out_hi, in_hi));
363 operands[0] = out_lo;
368 [(set_attr "predicable" "yes")
369 (set_attr "length" "4,4,8")
370 (set_attr "type" "ffarith")]
376 (define_insn "*addsf3_vfp"
377 [(set (match_operand:SF 0 "s_register_operand" "=w")
378 (plus:SF (match_operand:SF 1 "s_register_operand" "w")
379 (match_operand:SF 2 "s_register_operand" "w")))]
380 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
381 "fadds%?\\t%0, %1, %2"
382 [(set_attr "predicable" "yes")
383 (set_attr "type" "farith")]
386 (define_insn "*adddf3_vfp"
387 [(set (match_operand:DF 0 "s_register_operand" "=w")
388 (plus:DF (match_operand:DF 1 "s_register_operand" "w")
389 (match_operand:DF 2 "s_register_operand" "w")))]
390 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
391 "faddd%?\\t%P0, %P1, %P2"
392 [(set_attr "predicable" "yes")
393 (set_attr "type" "farith")]
397 (define_insn "*subsf3_vfp"
398 [(set (match_operand:SF 0 "s_register_operand" "=w")
399 (minus:SF (match_operand:SF 1 "s_register_operand" "w")
400 (match_operand:SF 2 "s_register_operand" "w")))]
401 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
402 "fsubs%?\\t%0, %1, %2"
403 [(set_attr "predicable" "yes")
404 (set_attr "type" "farith")]
407 (define_insn "*subdf3_vfp"
408 [(set (match_operand:DF 0 "s_register_operand" "=w")
409 (minus:DF (match_operand:DF 1 "s_register_operand" "w")
410 (match_operand:DF 2 "s_register_operand" "w")))]
411 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
412 "fsubd%?\\t%P0, %P1, %P2"
413 [(set_attr "predicable" "yes")
414 (set_attr "type" "farith")]
420 (define_insn "*divsf3_vfp"
421 [(set (match_operand:SF 0 "s_register_operand" "+w")
422 (div:SF (match_operand:SF 1 "s_register_operand" "w")
423 (match_operand:SF 2 "s_register_operand" "w")))]
424 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
425 "fdivs%?\\t%0, %1, %2"
426 [(set_attr "predicable" "yes")
427 (set_attr "type" "fdivs")]
430 (define_insn "*divdf3_vfp"
431 [(set (match_operand:DF 0 "s_register_operand" "+w")
432 (div:DF (match_operand:DF 1 "s_register_operand" "w")
433 (match_operand:DF 2 "s_register_operand" "w")))]
434 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
435 "fdivd%?\\t%P0, %P1, %P2"
436 [(set_attr "predicable" "yes")
437 (set_attr "type" "fdivd")]
441 ;; Multiplication insns
443 (define_insn "*mulsf3_vfp"
444 [(set (match_operand:SF 0 "s_register_operand" "+w")
445 (mult:SF (match_operand:SF 1 "s_register_operand" "w")
446 (match_operand:SF 2 "s_register_operand" "w")))]
447 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
448 "fmuls%?\\t%0, %1, %2"
449 [(set_attr "predicable" "yes")
450 (set_attr "type" "farith")]
453 (define_insn "*muldf3_vfp"
454 [(set (match_operand:DF 0 "s_register_operand" "+w")
455 (mult:DF (match_operand:DF 1 "s_register_operand" "w")
456 (match_operand:DF 2 "s_register_operand" "w")))]
457 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
458 "fmuld%?\\t%P0, %P1, %P2"
459 [(set_attr "predicable" "yes")
460 (set_attr "type" "fmul")]
464 (define_insn "*mulsf3negsf_vfp"
465 [(set (match_operand:SF 0 "s_register_operand" "+w")
466 (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "w"))
467 (match_operand:SF 2 "s_register_operand" "w")))]
468 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
469 "fnmuls%?\\t%0, %1, %2"
470 [(set_attr "predicable" "yes")
471 (set_attr "type" "farith")]
474 (define_insn "*muldf3negdf_vfp"
475 [(set (match_operand:DF 0 "s_register_operand" "+w")
476 (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
477 (match_operand:DF 2 "s_register_operand" "w")))]
478 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
479 "fnmuld%?\\t%P0, %P1, %P2"
480 [(set_attr "predicable" "yes")
481 (set_attr "type" "fmul")]
485 ;; Multiply-accumulate insns
488 (define_insn "*mulsf3addsf_vfp"
489 [(set (match_operand:SF 0 "s_register_operand" "=w")
490 (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "w")
491 (match_operand:SF 3 "s_register_operand" "w"))
492 (match_operand:SF 1 "s_register_operand" "0")))]
493 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
494 "fmacs%?\\t%0, %2, %3"
495 [(set_attr "predicable" "yes")
496 (set_attr "type" "farith")]
499 (define_insn "*muldf3adddf_vfp"
500 [(set (match_operand:DF 0 "s_register_operand" "=w")
501 (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
502 (match_operand:DF 3 "s_register_operand" "w"))
503 (match_operand:DF 1 "s_register_operand" "0")))]
504 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
505 "fmacd%?\\t%P0, %P2, %P3"
506 [(set_attr "predicable" "yes")
507 (set_attr "type" "fmul")]
511 (define_insn "*mulsf3subsf_vfp"
512 [(set (match_operand:SF 0 "s_register_operand" "=w")
513 (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "w")
514 (match_operand:SF 3 "s_register_operand" "w"))
515 (match_operand:SF 1 "s_register_operand" "0")))]
516 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
517 "fmscs%?\\t%0, %2, %3"
518 [(set_attr "predicable" "yes")
519 (set_attr "type" "farith")]
522 (define_insn "*muldf3subdf_vfp"
523 [(set (match_operand:DF 0 "s_register_operand" "=w")
524 (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
525 (match_operand:DF 3 "s_register_operand" "w"))
526 (match_operand:DF 1 "s_register_operand" "0")))]
527 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
528 "fmscd%?\\t%P0, %P2, %P3"
529 [(set_attr "predicable" "yes")
530 (set_attr "type" "fmul")]
534 (define_insn "*mulsf3negsfaddsf_vfp"
535 [(set (match_operand:SF 0 "s_register_operand" "=w")
536 (minus:SF (match_operand:SF 1 "s_register_operand" "0")
537 (mult:SF (match_operand:SF 2 "s_register_operand" "w")
538 (match_operand:SF 3 "s_register_operand" "w"))))]
539 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
540 "fnmacs%?\\t%0, %2, %3"
541 [(set_attr "predicable" "yes")
542 (set_attr "type" "farith")]
545 (define_insn "*fmuldf3negdfadddf_vfp"
546 [(set (match_operand:DF 0 "s_register_operand" "=w")
547 (minus:DF (match_operand:DF 1 "s_register_operand" "0")
548 (mult:DF (match_operand:DF 2 "s_register_operand" "w")
549 (match_operand:DF 3 "s_register_operand" "w"))))]
550 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
551 "fnmacd%?\\t%P0, %P2, %P3"
552 [(set_attr "predicable" "yes")
553 (set_attr "type" "fmul")]
558 (define_insn "*mulsf3negsfsubsf_vfp"
559 [(set (match_operand:SF 0 "s_register_operand" "=w")
561 (neg:SF (match_operand:SF 2 "s_register_operand" "w"))
562 (match_operand:SF 3 "s_register_operand" "w"))
563 (match_operand:SF 1 "s_register_operand" "0")))]
564 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
565 "fnmscs%?\\t%0, %2, %3"
566 [(set_attr "predicable" "yes")
567 (set_attr "type" "farith")]
570 (define_insn "*muldf3negdfsubdf_vfp"
571 [(set (match_operand:DF 0 "s_register_operand" "=w")
573 (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
574 (match_operand:DF 3 "s_register_operand" "w"))
575 (match_operand:DF 1 "s_register_operand" "0")))]
576 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
577 "fnmscd%?\\t%P0, %P2, %P3"
578 [(set_attr "predicable" "yes")
579 (set_attr "type" "fmul")]
583 ;; Conversion routines
585 (define_insn "*extendsfdf2_vfp"
586 [(set (match_operand:DF 0 "s_register_operand" "=w")
587 (float_extend:DF (match_operand:SF 1 "s_register_operand" "w")))]
588 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
590 [(set_attr "predicable" "yes")
591 (set_attr "type" "f_cvt")]
594 (define_insn "*truncdfsf2_vfp"
595 [(set (match_operand:SF 0 "s_register_operand" "=w")
596 (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
597 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
599 [(set_attr "predicable" "yes")
600 (set_attr "type" "f_cvt")]
603 (define_insn "*truncsisf2_vfp"
604 [(set (match_operand:SI 0 "s_register_operand" "=w")
605 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "w"))))]
606 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
608 [(set_attr "predicable" "yes")
609 (set_attr "type" "f_cvt")]
612 (define_insn "*truncsidf2_vfp"
613 [(set (match_operand:SI 0 "s_register_operand" "=w")
614 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
615 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
616 "ftosizd%?\\t%0, %P1"
617 [(set_attr "predicable" "yes")
618 (set_attr "type" "f_cvt")]
622 (define_insn "fixuns_truncsfsi2"
623 [(set (match_operand:SI 0 "s_register_operand" "=w")
624 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "w"))))]
625 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
627 [(set_attr "predicable" "yes")
628 (set_attr "type" "f_cvt")]
631 (define_insn "fixuns_truncdfsi2"
632 [(set (match_operand:SI 0 "s_register_operand" "=w")
633 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
634 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
635 "ftouizd%?\\t%0, %P1"
636 [(set_attr "predicable" "yes")
637 (set_attr "type" "f_cvt")]
641 (define_insn "*floatsisf2_vfp"
642 [(set (match_operand:SF 0 "s_register_operand" "=w")
643 (float:SF (match_operand:SI 1 "s_register_operand" "w")))]
644 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
646 [(set_attr "predicable" "yes")
647 (set_attr "type" "f_cvt")]
650 (define_insn "*floatsidf2_vfp"
651 [(set (match_operand:DF 0 "s_register_operand" "=w")
652 (float:DF (match_operand:SI 1 "s_register_operand" "w")))]
653 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
655 [(set_attr "predicable" "yes")
656 (set_attr "type" "f_cvt")]
660 (define_insn "floatunssisf2"
661 [(set (match_operand:SF 0 "s_register_operand" "=w")
662 (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "w")))]
663 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
665 [(set_attr "predicable" "yes")
666 (set_attr "type" "f_cvt")]
669 (define_insn "floatunssidf2"
670 [(set (match_operand:DF 0 "s_register_operand" "=w")
671 (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "w")))]
672 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
674 [(set_attr "predicable" "yes")
675 (set_attr "type" "f_cvt")]
681 (define_insn "*sqrtsf2_vfp"
682 [(set (match_operand:SF 0 "s_register_operand" "=w")
683 (sqrt:SF (match_operand:SF 1 "s_register_operand" "w")))]
684 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
686 [(set_attr "predicable" "yes")
687 (set_attr "type" "fdivs")]
690 (define_insn "*sqrtdf2_vfp"
691 [(set (match_operand:DF 0 "s_register_operand" "=w")
692 (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))]
693 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
694 "fsqrtd%?\\t%P0, %P1"
695 [(set_attr "predicable" "yes")
696 (set_attr "type" "fdivd")]
700 ;; Patterns to split/copy vfp condition flags.
702 (define_insn "*movcc_vfp"
703 [(set (reg CC_REGNUM)
705 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
707 [(set_attr "conds" "set")
708 (set_attr "type" "f_flag")]
711 (define_insn_and_split "*cmpsf_split_vfp"
712 [(set (reg:CCFP CC_REGNUM)
713 (compare:CCFP (match_operand:SF 0 "s_register_operand" "w")
714 (match_operand:SF 1 "vfp_compare_operand" "wG")))]
715 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
717 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
718 [(set (reg:CCFP VFPCC_REGNUM)
719 (compare:CCFP (match_dup 0)
721 (set (reg:CCFP CC_REGNUM)
722 (reg:CCFP VFPCC_REGNUM))]
726 (define_insn_and_split "*cmpsf_trap_split_vfp"
727 [(set (reg:CCFPE CC_REGNUM)
728 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "w")
729 (match_operand:SF 1 "vfp_compare_operand" "wG")))]
730 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
732 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
733 [(set (reg:CCFPE VFPCC_REGNUM)
734 (compare:CCFPE (match_dup 0)
736 (set (reg:CCFPE CC_REGNUM)
737 (reg:CCFPE VFPCC_REGNUM))]
741 (define_insn_and_split "*cmpdf_split_vfp"
742 [(set (reg:CCFP CC_REGNUM)
743 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w")
744 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
745 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
747 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
748 [(set (reg:CCFP VFPCC_REGNUM)
749 (compare:CCFP (match_dup 0)
751 (set (reg:CCFP CC_REGNUM)
752 (reg:CCFPE VFPCC_REGNUM))]
756 (define_insn_and_split "*cmpdf_trap_split_vfp"
757 [(set (reg:CCFPE CC_REGNUM)
758 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w")
759 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
760 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
762 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
763 [(set (reg:CCFPE VFPCC_REGNUM)
764 (compare:CCFPE (match_dup 0)
766 (set (reg:CCFPE CC_REGNUM)
767 (reg:CCFPE VFPCC_REGNUM))]
772 ;; Comparison patterns
774 (define_insn "*cmpsf_vfp"
775 [(set (reg:CCFP VFPCC_REGNUM)
776 (compare:CCFP (match_operand:SF 0 "s_register_operand" "w,w")
777 (match_operand:SF 1 "vfp_compare_operand" "w,G")))]
778 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
782 [(set_attr "predicable" "yes")
783 (set_attr "type" "ffarith")]
786 (define_insn "*cmpsf_trap_vfp"
787 [(set (reg:CCFPE VFPCC_REGNUM)
788 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "w,w")
789 (match_operand:SF 1 "vfp_compare_operand" "w,G")))]
790 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
794 [(set_attr "predicable" "yes")
795 (set_attr "type" "ffarith")]
798 (define_insn "*cmpdf_vfp"
799 [(set (reg:CCFP VFPCC_REGNUM)
800 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w")
801 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
802 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
806 [(set_attr "predicable" "yes")
807 (set_attr "type" "ffarith")]
810 (define_insn "*cmpdf_trap_vfp"
811 [(set (reg:CCFPE VFPCC_REGNUM)
812 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w")
813 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
814 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
818 [(set_attr "predicable" "yes")
819 (set_attr "type" "ffarith")]
823 ;; Store multiple insn used in function prologue.
825 (define_insn "*push_multi_vfp"
826 [(match_parallel 2 "multi_register_push"
827 [(set (match_operand:BLK 0 "memory_operand" "=m")
828 (unspec:BLK [(match_operand:DF 1 "s_register_operand" "w")]
829 UNSPEC_PUSH_MULT))])]
830 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
831 "* return vfp_output_fstmx (operands);"
832 [(set_attr "type" "f_stored")]
836 ;; Unimplemented insns:
839 ;; fmdhr et al (VFPv1)
840 ;; Support for xD (single precision only) variants.