1 ;; ARM VFP coprocessor Machine Description
2 ;; Copyright (C) 2003, 2005, 2006, 2007 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,r ,m,*w,r,*w,*w, *Uv")
125 (match_operand:SI 1 "general_operand" "rI,K,N,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))"
130 switch (which_alternative)
133 return \"mov%?\\t%0, %1\";
135 return \"mvn%?\\t%0, #%B1\";
137 return \"movw%?\\t%0, %1\";
139 return \"ldr%?\\t%0, %1\";
141 return \"str%?\\t%1, %0\";
143 return \"fmsr%?\\t%0, %1\\t%@ int\";
145 return \"fmrs%?\\t%0, %1\\t%@ int\";
147 return \"fcpys%?\\t%0, %1\\t%@ int\";
149 return output_move_vfp (operands);
154 [(set_attr "predicable" "yes")
155 (set_attr "type" "*,*,*,load1,store1,r_2_f,f_2_r,ffarith,f_loads,f_stores")
156 (set_attr "pool_range" "*,*,*,4096,*,*,*,*,1020,*")
157 (set_attr "neg_pool_range" "*,*,*,4084,*,*,*,*,1008,*")]
160 (define_insn "*thumb2_movsi_vfp"
161 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*w,r,*w,*w, *Uv")
162 (match_operand:SI 1 "general_operand" "rI,K,N,mi,r,r,*w,*w,*Uvi,*w"))]
163 "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT
164 && ( s_register_operand (operands[0], SImode)
165 || s_register_operand (operands[1], SImode))"
167 switch (which_alternative)
170 return \"mov%?\\t%0, %1\";
172 return \"mvn%?\\t%0, #%B1\";
174 return \"movw%?\\t%0, %1\";
176 return \"ldr%?\\t%0, %1\";
178 return \"str%?\\t%1, %0\";
180 return \"fmsr%?\\t%0, %1\\t%@ int\";
182 return \"fmrs%?\\t%0, %1\\t%@ int\";
184 return \"fcpys%?\\t%0, %1\\t%@ int\";
186 return output_move_vfp (operands);
191 [(set_attr "predicable" "yes")
192 (set_attr "type" "*,*,*,load1,store1,r_2_f,f_2_r,ffarith,f_load,f_store")
193 (set_attr "pool_range" "*,*,*,4096,*,*,*,*,1020,*")
194 (set_attr "neg_pool_range" "*,*,*, 0,*,*,*,*,1008,*")]
200 (define_insn "*arm_movdi_vfp"
201 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
202 (match_operand:DI 1 "di_operand" "rIK,mi,r,r,w,w,Uvi,w"))]
203 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
204 && ( register_operand (operands[0], DImode)
205 || register_operand (operands[1], DImode))"
207 switch (which_alternative)
213 return output_move_double (operands);
215 return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
217 return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
219 return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
221 return output_move_vfp (operands);
226 [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_loadd,f_stored")
227 (set_attr "length" "8,8,8,4,4,4,4,4")
228 (set_attr "pool_range" "*,1020,*,*,*,*,1020,*")
229 (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
232 (define_insn "*thumb2_movdi_vfp"
233 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
234 (match_operand:DI 1 "di_operand" "rIK,mi,r,r,w,w,Uvi,w"))]
235 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
237 switch (which_alternative)
239 case 0: case 1: case 2:
240 return (output_move_double (operands));
242 return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
244 return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
246 return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
248 return output_move_vfp (operands);
253 [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_load,f_store")
254 (set_attr "length" "8,8,8,4,4,4,4,4")
255 (set_attr "pool_range" "*,4096,*,*,*,*,1020,*")
256 (set_attr "neg_pool_range" "*, 0,*,*,*,*,1008,*")]
261 ;; Disparage the w<->r cases because reloading an invalid address is
262 ;; preferable to loading the value via integer registers.
264 (define_insn "*movsf_vfp"
265 [(set (match_operand:SF 0 "nonimmediate_operand" "=w,?r,w ,Uv,r ,m,w,r")
266 (match_operand:SF 1 "general_operand" " ?r,w,UvE,w, mE,r,w,r"))]
267 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
268 && ( s_register_operand (operands[0], SFmode)
269 || s_register_operand (operands[1], SFmode))"
271 switch (which_alternative)
274 return \"fmsr%?\\t%0, %1\";
276 return \"fmrs%?\\t%0, %1\";
278 return output_move_vfp (operands);
280 return \"ldr%?\\t%0, %1\\t%@ float\";
282 return \"str%?\\t%1, %0\\t%@ float\";
284 return \"fcpys%?\\t%0, %1\";
286 return \"mov%?\\t%0, %1\\t%@ float\";
291 [(set_attr "predicable" "yes")
292 (set_attr "type" "r_2_f,f_2_r,ffarith,*,f_loads,f_stores,load1,store1")
293 (set_attr "pool_range" "*,*,1020,*,4096,*,*,*")
294 (set_attr "neg_pool_range" "*,*,1008,*,4080,*,*,*")]
297 (define_insn "*thumb2_movsf_vfp"
298 [(set (match_operand:SF 0 "nonimmediate_operand" "=w,?r,w ,Uv,r ,m,w,r")
299 (match_operand:SF 1 "general_operand" " ?r,w,UvE,w, mE,r,w,r"))]
300 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP
301 && ( s_register_operand (operands[0], SFmode)
302 || s_register_operand (operands[1], SFmode))"
304 switch (which_alternative)
307 return \"fmsr%?\\t%0, %1\";
309 return \"fmrs%?\\t%0, %1\";
311 return output_move_vfp (operands);
313 return \"ldr%?\\t%0, %1\\t%@ float\";
315 return \"str%?\\t%1, %0\\t%@ float\";
317 return \"fcpys%?\\t%0, %1\";
319 return \"mov%?\\t%0, %1\\t%@ float\";
324 [(set_attr "predicable" "yes")
325 (set_attr "type" "r_2_f,f_2_r,ffarith,*,f_load,f_store,load1,store1")
326 (set_attr "pool_range" "*,*,1020,*,4092,*,*,*")
327 (set_attr "neg_pool_range" "*,*,1008,*,0,*,*,*")]
333 (define_insn "*movdf_vfp"
334 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,r, m,w ,Uv,w,r")
335 (match_operand:DF 1 "soft_df_operand" " ?r,w,mF,r,UvF,w, w,r"))]
336 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
337 && ( register_operand (operands[0], DFmode)
338 || register_operand (operands[1], DFmode))"
341 switch (which_alternative)
344 return \"fmdrr%?\\t%P0, %Q1, %R1\";
346 return \"fmrrd%?\\t%Q0, %R0, %P1\";
348 return output_move_double (operands);
350 return output_move_vfp (operands);
352 return \"fcpyd%?\\t%P0, %P1\";
360 [(set_attr "type" "r_2_f,f_2_r,ffarith,*,load2,store2,f_loadd,f_stored")
361 (set_attr "length" "4,4,8,8,4,4,4,8")
362 (set_attr "pool_range" "*,*,1020,*,1020,*,*,*")
363 (set_attr "neg_pool_range" "*,*,1008,*,1008,*,*,*")]
366 (define_insn "*thumb2_movdf_vfp"
367 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,r, m,w ,Uv,w,r")
368 (match_operand:DF 1 "soft_df_operand" " ?r,w,mF,r,UvF,w, w,r"))]
369 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
372 switch (which_alternative)
375 return \"fmdrr%?\\t%P0, %Q1, %R1\";
377 return \"fmrrd%?\\t%Q0, %R0, %P1\";
378 case 2: case 3: case 7:
379 return output_move_double (operands);
381 return output_move_vfp (operands);
383 return \"fcpyd%?\\t%P0, %P1\";
389 [(set_attr "type" "r_2_f,f_2_r,ffarith,*,load2,store2,f_load,f_store")
390 (set_attr "length" "4,4,8,8,4,4,4,8")
391 (set_attr "pool_range" "*,*,4096,*,1020,*,*,*")
392 (set_attr "neg_pool_range" "*,*,0,*,1008,*,*,*")]
396 ;; Conditional move patterns
398 (define_insn "*movsfcc_vfp"
399 [(set (match_operand:SF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
401 (match_operator 3 "arm_comparison_operator"
402 [(match_operand 4 "cc_register" "") (const_int 0)])
403 (match_operand:SF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
404 (match_operand:SF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
405 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
409 fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
412 fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
415 fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
416 [(set_attr "conds" "use")
417 (set_attr "length" "4,4,8,4,4,8,4,4,8")
418 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
421 (define_insn "*thumb2_movsfcc_vfp"
422 [(set (match_operand:SF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
424 (match_operator 3 "arm_comparison_operator"
425 [(match_operand 4 "cc_register" "") (const_int 0)])
426 (match_operand:SF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
427 (match_operand:SF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
428 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
430 it\\t%D3\;fcpys%D3\\t%0, %2
431 it\\t%d3\;fcpys%d3\\t%0, %1
432 ite\\t%D3\;fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
433 it\\t%D3\;fmsr%D3\\t%0, %2
434 it\\t%d3\;fmsr%d3\\t%0, %1
435 ite\\t%D3\;fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
436 it\\t%D3\;fmrs%D3\\t%0, %2
437 it\\t%d3\;fmrs%d3\\t%0, %1
438 ite\\t%D3\;fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
439 [(set_attr "conds" "use")
440 (set_attr "length" "6,6,10,6,6,10,6,6,10")
441 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
444 (define_insn "*movdfcc_vfp"
445 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
447 (match_operator 3 "arm_comparison_operator"
448 [(match_operand 4 "cc_register" "") (const_int 0)])
449 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
450 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
451 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
455 fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
456 fmdrr%D3\\t%P0, %Q2, %R2
457 fmdrr%d3\\t%P0, %Q1, %R1
458 fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
459 fmrrd%D3\\t%Q0, %R0, %P2
460 fmrrd%d3\\t%Q0, %R0, %P1
461 fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
462 [(set_attr "conds" "use")
463 (set_attr "length" "4,4,8,4,4,8,4,4,8")
464 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
467 (define_insn "*thumb2_movdfcc_vfp"
468 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
470 (match_operator 3 "arm_comparison_operator"
471 [(match_operand 4 "cc_register" "") (const_int 0)])
472 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
473 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
474 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
476 it\\t%D3\;fcpyd%D3\\t%P0, %P2
477 it\\t%d3\;fcpyd%d3\\t%P0, %P1
478 ite\\t%D3\;fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
479 it\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2
480 it\t%d3\;fmdrr%d3\\t%P0, %Q1, %R1
481 ite\\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
482 it\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2
483 it\t%d3\;fmrrd%d3\\t%Q0, %R0, %P1
484 ite\\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
485 [(set_attr "conds" "use")
486 (set_attr "length" "6,6,10,6,6,10,6,6,10")
487 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
491 ;; Sign manipulation functions
493 (define_insn "*abssf2_vfp"
494 [(set (match_operand:SF 0 "s_register_operand" "=w")
495 (abs:SF (match_operand:SF 1 "s_register_operand" "w")))]
496 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
498 [(set_attr "predicable" "yes")
499 (set_attr "type" "ffarith")]
502 (define_insn "*absdf2_vfp"
503 [(set (match_operand:DF 0 "s_register_operand" "=w")
504 (abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
505 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
507 [(set_attr "predicable" "yes")
508 (set_attr "type" "ffarith")]
511 (define_insn "*negsf2_vfp"
512 [(set (match_operand:SF 0 "s_register_operand" "=w,?r")
513 (neg:SF (match_operand:SF 1 "s_register_operand" "w,r")))]
514 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
517 eor%?\\t%0, %1, #-2147483648"
518 [(set_attr "predicable" "yes")
519 (set_attr "type" "ffarith")]
522 (define_insn_and_split "*negdf2_vfp"
523 [(set (match_operand:DF 0 "s_register_operand" "=w,?r,?r")
524 (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))]
525 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
530 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && reload_completed
531 && arm_general_register_operand (operands[0], DFmode)"
532 [(set (match_dup 0) (match_dup 1))]
534 if (REGNO (operands[0]) == REGNO (operands[1]))
536 operands[0] = gen_highpart (SImode, operands[0]);
537 operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000));
541 rtx in_hi, in_lo, out_hi, out_lo;
543 in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]),
544 GEN_INT (0x80000000));
545 in_lo = gen_lowpart (SImode, operands[1]);
546 out_hi = gen_highpart (SImode, operands[0]);
547 out_lo = gen_lowpart (SImode, operands[0]);
549 if (REGNO (in_lo) == REGNO (out_hi))
551 emit_insn (gen_rtx_SET (SImode, out_lo, in_lo));
552 operands[0] = out_hi;
557 emit_insn (gen_rtx_SET (SImode, out_hi, in_hi));
558 operands[0] = out_lo;
563 [(set_attr "predicable" "yes")
564 (set_attr "length" "4,4,8")
565 (set_attr "type" "ffarith")]
571 (define_insn "*addsf3_vfp"
572 [(set (match_operand:SF 0 "s_register_operand" "=w")
573 (plus:SF (match_operand:SF 1 "s_register_operand" "w")
574 (match_operand:SF 2 "s_register_operand" "w")))]
575 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
576 "fadds%?\\t%0, %1, %2"
577 [(set_attr "predicable" "yes")
578 (set_attr "type" "farith")]
581 (define_insn "*adddf3_vfp"
582 [(set (match_operand:DF 0 "s_register_operand" "=w")
583 (plus:DF (match_operand:DF 1 "s_register_operand" "w")
584 (match_operand:DF 2 "s_register_operand" "w")))]
585 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
586 "faddd%?\\t%P0, %P1, %P2"
587 [(set_attr "predicable" "yes")
588 (set_attr "type" "farith")]
592 (define_insn "*subsf3_vfp"
593 [(set (match_operand:SF 0 "s_register_operand" "=w")
594 (minus:SF (match_operand:SF 1 "s_register_operand" "w")
595 (match_operand:SF 2 "s_register_operand" "w")))]
596 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
597 "fsubs%?\\t%0, %1, %2"
598 [(set_attr "predicable" "yes")
599 (set_attr "type" "farith")]
602 (define_insn "*subdf3_vfp"
603 [(set (match_operand:DF 0 "s_register_operand" "=w")
604 (minus:DF (match_operand:DF 1 "s_register_operand" "w")
605 (match_operand:DF 2 "s_register_operand" "w")))]
606 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
607 "fsubd%?\\t%P0, %P1, %P2"
608 [(set_attr "predicable" "yes")
609 (set_attr "type" "farith")]
615 (define_insn "*divsf3_vfp"
616 [(set (match_operand:SF 0 "s_register_operand" "+w")
617 (div:SF (match_operand:SF 1 "s_register_operand" "w")
618 (match_operand:SF 2 "s_register_operand" "w")))]
619 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
620 "fdivs%?\\t%0, %1, %2"
621 [(set_attr "predicable" "yes")
622 (set_attr "type" "fdivs")]
625 (define_insn "*divdf3_vfp"
626 [(set (match_operand:DF 0 "s_register_operand" "+w")
627 (div:DF (match_operand:DF 1 "s_register_operand" "w")
628 (match_operand:DF 2 "s_register_operand" "w")))]
629 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
630 "fdivd%?\\t%P0, %P1, %P2"
631 [(set_attr "predicable" "yes")
632 (set_attr "type" "fdivd")]
636 ;; Multiplication insns
638 (define_insn "*mulsf3_vfp"
639 [(set (match_operand:SF 0 "s_register_operand" "+w")
640 (mult:SF (match_operand:SF 1 "s_register_operand" "w")
641 (match_operand:SF 2 "s_register_operand" "w")))]
642 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
643 "fmuls%?\\t%0, %1, %2"
644 [(set_attr "predicable" "yes")
645 (set_attr "type" "farith")]
648 (define_insn "*muldf3_vfp"
649 [(set (match_operand:DF 0 "s_register_operand" "+w")
650 (mult:DF (match_operand:DF 1 "s_register_operand" "w")
651 (match_operand:DF 2 "s_register_operand" "w")))]
652 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
653 "fmuld%?\\t%P0, %P1, %P2"
654 [(set_attr "predicable" "yes")
655 (set_attr "type" "fmul")]
659 (define_insn "*mulsf3negsf_vfp"
660 [(set (match_operand:SF 0 "s_register_operand" "+w")
661 (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "w"))
662 (match_operand:SF 2 "s_register_operand" "w")))]
663 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
664 "fnmuls%?\\t%0, %1, %2"
665 [(set_attr "predicable" "yes")
666 (set_attr "type" "farith")]
669 (define_insn "*muldf3negdf_vfp"
670 [(set (match_operand:DF 0 "s_register_operand" "+w")
671 (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
672 (match_operand:DF 2 "s_register_operand" "w")))]
673 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
674 "fnmuld%?\\t%P0, %P1, %P2"
675 [(set_attr "predicable" "yes")
676 (set_attr "type" "fmul")]
680 ;; Multiply-accumulate insns
683 (define_insn "*mulsf3addsf_vfp"
684 [(set (match_operand:SF 0 "s_register_operand" "=w")
685 (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "w")
686 (match_operand:SF 3 "s_register_operand" "w"))
687 (match_operand:SF 1 "s_register_operand" "0")))]
688 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
689 "fmacs%?\\t%0, %2, %3"
690 [(set_attr "predicable" "yes")
691 (set_attr "type" "farith")]
694 (define_insn "*muldf3adddf_vfp"
695 [(set (match_operand:DF 0 "s_register_operand" "=w")
696 (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
697 (match_operand:DF 3 "s_register_operand" "w"))
698 (match_operand:DF 1 "s_register_operand" "0")))]
699 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
700 "fmacd%?\\t%P0, %P2, %P3"
701 [(set_attr "predicable" "yes")
702 (set_attr "type" "fmul")]
706 (define_insn "*mulsf3subsf_vfp"
707 [(set (match_operand:SF 0 "s_register_operand" "=w")
708 (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "w")
709 (match_operand:SF 3 "s_register_operand" "w"))
710 (match_operand:SF 1 "s_register_operand" "0")))]
711 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
712 "fmscs%?\\t%0, %2, %3"
713 [(set_attr "predicable" "yes")
714 (set_attr "type" "farith")]
717 (define_insn "*muldf3subdf_vfp"
718 [(set (match_operand:DF 0 "s_register_operand" "=w")
719 (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
720 (match_operand:DF 3 "s_register_operand" "w"))
721 (match_operand:DF 1 "s_register_operand" "0")))]
722 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
723 "fmscd%?\\t%P0, %P2, %P3"
724 [(set_attr "predicable" "yes")
725 (set_attr "type" "fmul")]
729 (define_insn "*mulsf3negsfaddsf_vfp"
730 [(set (match_operand:SF 0 "s_register_operand" "=w")
731 (minus:SF (match_operand:SF 1 "s_register_operand" "0")
732 (mult:SF (match_operand:SF 2 "s_register_operand" "w")
733 (match_operand:SF 3 "s_register_operand" "w"))))]
734 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
735 "fnmacs%?\\t%0, %2, %3"
736 [(set_attr "predicable" "yes")
737 (set_attr "type" "farith")]
740 (define_insn "*fmuldf3negdfadddf_vfp"
741 [(set (match_operand:DF 0 "s_register_operand" "=w")
742 (minus:DF (match_operand:DF 1 "s_register_operand" "0")
743 (mult:DF (match_operand:DF 2 "s_register_operand" "w")
744 (match_operand:DF 3 "s_register_operand" "w"))))]
745 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
746 "fnmacd%?\\t%P0, %P2, %P3"
747 [(set_attr "predicable" "yes")
748 (set_attr "type" "fmul")]
753 (define_insn "*mulsf3negsfsubsf_vfp"
754 [(set (match_operand:SF 0 "s_register_operand" "=w")
756 (neg:SF (match_operand:SF 2 "s_register_operand" "w"))
757 (match_operand:SF 3 "s_register_operand" "w"))
758 (match_operand:SF 1 "s_register_operand" "0")))]
759 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
760 "fnmscs%?\\t%0, %2, %3"
761 [(set_attr "predicable" "yes")
762 (set_attr "type" "farith")]
765 (define_insn "*muldf3negdfsubdf_vfp"
766 [(set (match_operand:DF 0 "s_register_operand" "=w")
768 (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
769 (match_operand:DF 3 "s_register_operand" "w"))
770 (match_operand:DF 1 "s_register_operand" "0")))]
771 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
772 "fnmscd%?\\t%P0, %P2, %P3"
773 [(set_attr "predicable" "yes")
774 (set_attr "type" "fmul")]
778 ;; Conversion routines
780 (define_insn "*extendsfdf2_vfp"
781 [(set (match_operand:DF 0 "s_register_operand" "=w")
782 (float_extend:DF (match_operand:SF 1 "s_register_operand" "w")))]
783 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
785 [(set_attr "predicable" "yes")
786 (set_attr "type" "f_cvt")]
789 (define_insn "*truncdfsf2_vfp"
790 [(set (match_operand:SF 0 "s_register_operand" "=w")
791 (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
792 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
794 [(set_attr "predicable" "yes")
795 (set_attr "type" "f_cvt")]
798 (define_insn "*truncsisf2_vfp"
799 [(set (match_operand:SI 0 "s_register_operand" "=w")
800 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "w"))))]
801 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
803 [(set_attr "predicable" "yes")
804 (set_attr "type" "f_cvt")]
807 (define_insn "*truncsidf2_vfp"
808 [(set (match_operand:SI 0 "s_register_operand" "=w")
809 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
810 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
811 "ftosizd%?\\t%0, %P1"
812 [(set_attr "predicable" "yes")
813 (set_attr "type" "f_cvt")]
817 (define_insn "fixuns_truncsfsi2"
818 [(set (match_operand:SI 0 "s_register_operand" "=w")
819 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "w"))))]
820 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
822 [(set_attr "predicable" "yes")
823 (set_attr "type" "f_cvt")]
826 (define_insn "fixuns_truncdfsi2"
827 [(set (match_operand:SI 0 "s_register_operand" "=w")
828 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
829 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
830 "ftouizd%?\\t%0, %P1"
831 [(set_attr "predicable" "yes")
832 (set_attr "type" "f_cvt")]
836 (define_insn "*floatsisf2_vfp"
837 [(set (match_operand:SF 0 "s_register_operand" "=w")
838 (float:SF (match_operand:SI 1 "s_register_operand" "w")))]
839 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
841 [(set_attr "predicable" "yes")
842 (set_attr "type" "f_cvt")]
845 (define_insn "*floatsidf2_vfp"
846 [(set (match_operand:DF 0 "s_register_operand" "=w")
847 (float:DF (match_operand:SI 1 "s_register_operand" "w")))]
848 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
850 [(set_attr "predicable" "yes")
851 (set_attr "type" "f_cvt")]
855 (define_insn "floatunssisf2"
856 [(set (match_operand:SF 0 "s_register_operand" "=w")
857 (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "w")))]
858 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
860 [(set_attr "predicable" "yes")
861 (set_attr "type" "f_cvt")]
864 (define_insn "floatunssidf2"
865 [(set (match_operand:DF 0 "s_register_operand" "=w")
866 (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "w")))]
867 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
869 [(set_attr "predicable" "yes")
870 (set_attr "type" "f_cvt")]
876 (define_insn "*sqrtsf2_vfp"
877 [(set (match_operand:SF 0 "s_register_operand" "=w")
878 (sqrt:SF (match_operand:SF 1 "s_register_operand" "w")))]
879 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
881 [(set_attr "predicable" "yes")
882 (set_attr "type" "fdivs")]
885 (define_insn "*sqrtdf2_vfp"
886 [(set (match_operand:DF 0 "s_register_operand" "=w")
887 (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))]
888 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
889 "fsqrtd%?\\t%P0, %P1"
890 [(set_attr "predicable" "yes")
891 (set_attr "type" "fdivd")]
895 ;; Patterns to split/copy vfp condition flags.
897 (define_insn "*movcc_vfp"
898 [(set (reg CC_REGNUM)
900 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
902 [(set_attr "conds" "set")
903 (set_attr "type" "f_flag")]
906 (define_insn_and_split "*cmpsf_split_vfp"
907 [(set (reg:CCFP CC_REGNUM)
908 (compare:CCFP (match_operand:SF 0 "s_register_operand" "w")
909 (match_operand:SF 1 "vfp_compare_operand" "wG")))]
910 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
912 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
913 [(set (reg:CCFP VFPCC_REGNUM)
914 (compare:CCFP (match_dup 0)
916 (set (reg:CCFP CC_REGNUM)
917 (reg:CCFP VFPCC_REGNUM))]
921 (define_insn_and_split "*cmpsf_trap_split_vfp"
922 [(set (reg:CCFPE CC_REGNUM)
923 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "w")
924 (match_operand:SF 1 "vfp_compare_operand" "wG")))]
925 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
927 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
928 [(set (reg:CCFPE VFPCC_REGNUM)
929 (compare:CCFPE (match_dup 0)
931 (set (reg:CCFPE CC_REGNUM)
932 (reg:CCFPE VFPCC_REGNUM))]
936 (define_insn_and_split "*cmpdf_split_vfp"
937 [(set (reg:CCFP CC_REGNUM)
938 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w")
939 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
940 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
942 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
943 [(set (reg:CCFP VFPCC_REGNUM)
944 (compare:CCFP (match_dup 0)
946 (set (reg:CCFP CC_REGNUM)
947 (reg:CCFPE VFPCC_REGNUM))]
951 (define_insn_and_split "*cmpdf_trap_split_vfp"
952 [(set (reg:CCFPE CC_REGNUM)
953 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w")
954 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
955 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
957 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
958 [(set (reg:CCFPE VFPCC_REGNUM)
959 (compare:CCFPE (match_dup 0)
961 (set (reg:CCFPE CC_REGNUM)
962 (reg:CCFPE VFPCC_REGNUM))]
967 ;; Comparison patterns
969 (define_insn "*cmpsf_vfp"
970 [(set (reg:CCFP VFPCC_REGNUM)
971 (compare:CCFP (match_operand:SF 0 "s_register_operand" "w,w")
972 (match_operand:SF 1 "vfp_compare_operand" "w,G")))]
973 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
977 [(set_attr "predicable" "yes")
978 (set_attr "type" "ffarith")]
981 (define_insn "*cmpsf_trap_vfp"
982 [(set (reg:CCFPE VFPCC_REGNUM)
983 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "w,w")
984 (match_operand:SF 1 "vfp_compare_operand" "w,G")))]
985 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
989 [(set_attr "predicable" "yes")
990 (set_attr "type" "ffarith")]
993 (define_insn "*cmpdf_vfp"
994 [(set (reg:CCFP VFPCC_REGNUM)
995 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w")
996 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
997 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1001 [(set_attr "predicable" "yes")
1002 (set_attr "type" "ffarith")]
1005 (define_insn "*cmpdf_trap_vfp"
1006 [(set (reg:CCFPE VFPCC_REGNUM)
1007 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w")
1008 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1009 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1013 [(set_attr "predicable" "yes")
1014 (set_attr "type" "ffarith")]
1018 ;; Store multiple insn used in function prologue.
1020 (define_insn "*push_multi_vfp"
1021 [(match_parallel 2 "multi_register_push"
1022 [(set (match_operand:BLK 0 "memory_operand" "=m")
1023 (unspec:BLK [(match_operand:DF 1 "s_register_operand" "w")]
1024 UNSPEC_PUSH_MULT))])]
1025 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1026 "* return vfp_output_fstmd (operands);"
1027 [(set_attr "type" "f_stored")]
1031 ;; Unimplemented insns:
1034 ;; fmdhr et al (VFPv1)
1035 ;; Support for xD (single precision only) variants.