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,*t,r,*t,*t, *Uv")
125 (match_operand:SI 1 "general_operand" "rI,K,N,mi,r,r,*t,*t,*Uvi,*t"))]
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,*t,r,*t,*t, *Uv")
162 (match_operand:SI 1 "general_operand" "rI,K,N,mi,r,r,*t,*t,*Uvi,*t"))]
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" "=t,?r,t ,t ,Uv,r ,m,t,r")
266 (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,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 \"fconsts%?\\t%0, #%G1\";
280 return output_move_vfp (operands);
282 return \"ldr%?\\t%0, %1\\t%@ float\";
284 return \"str%?\\t%1, %0\\t%@ float\";
286 return \"fcpys%?\\t%0, %1\";
288 return \"mov%?\\t%0, %1\\t%@ float\";
293 [(set_attr "predicable" "yes")
295 "r_2_f,f_2_r,farith,f_loads,f_stores,load1,store1,ffarith,*")
296 (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*")
297 (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")]
300 (define_insn "*thumb2_movsf_vfp"
301 [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t, t ,Uv,r ,m,t,r")
302 (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))]
303 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP
304 && ( s_register_operand (operands[0], SFmode)
305 || s_register_operand (operands[1], SFmode))"
307 switch (which_alternative)
310 return \"fmsr%?\\t%0, %1\";
312 return \"fmrs%?\\t%0, %1\";
314 return \"fconsts%?\\t%0, #%G1\";
316 return output_move_vfp (operands);
318 return \"ldr%?\\t%0, %1\\t%@ float\";
320 return \"str%?\\t%1, %0\\t%@ float\";
322 return \"fcpys%?\\t%0, %1\";
324 return \"mov%?\\t%0, %1\\t%@ float\";
329 [(set_attr "predicable" "yes")
331 "r_2_f,f_2_r,farith,f_load,f_store,load1,store1,ffarith,*")
332 (set_attr "pool_range" "*,*,*,1020,*,4092,*,*,*")
333 (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")]
339 (define_insn "*movdf_vfp"
340 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w ,Uv,w,r")
341 (match_operand:DF 1 "soft_df_operand" " ?r,w,Dv,mF,r,UvF,w, w,r"))]
342 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
343 && ( register_operand (operands[0], DFmode)
344 || register_operand (operands[1], DFmode))"
347 switch (which_alternative)
350 return \"fmdrr%?\\t%P0, %Q1, %R1\";
352 return \"fmrrd%?\\t%Q0, %R0, %P1\";
354 return \"fconstd%?\\t%P0, #%G1\";
356 return output_move_double (operands);
358 return output_move_vfp (operands);
360 return \"fcpyd%?\\t%P0, %P1\";
369 "r_2_f,f_2_r,farith,f_loadd,f_stored,load2,store2,ffarith,*")
370 (set_attr "length" "4,4,4,8,8,4,4,4,8")
371 (set_attr "pool_range" "*,*,*,1020,*,1020,*,*,*")
372 (set_attr "neg_pool_range" "*,*,*,1008,*,1008,*,*,*")]
375 (define_insn "*thumb2_movdf_vfp"
376 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w ,Uv,w,r")
377 (match_operand:DF 1 "soft_df_operand" " ?r,w,Dv,mF,r,UvF,w, w,r"))]
378 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
381 switch (which_alternative)
384 return \"fmdrr%?\\t%P0, %Q1, %R1\";
386 return \"fmrrd%?\\t%Q0, %R0, %P1\";
388 return \"fconstd%?\\t%P0, #%G1\";
389 case 3: case 4: case 8:
390 return output_move_double (operands);
392 return output_move_vfp (operands);
394 return \"fcpyd%?\\t%P0, %P1\";
401 "r_2_f,f_2_r,farith,load2,store2,f_load,f_store,ffarith,*")
402 (set_attr "length" "4,4,4,8,8,4,4,4,8")
403 (set_attr "pool_range" "*,*,*,4096,*,1020,*,*,*")
404 (set_attr "neg_pool_range" "*,*,*,0,*,1008,*,*,*")]
408 ;; Conditional move patterns
410 (define_insn "*movsfcc_vfp"
411 [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
413 (match_operator 3 "arm_comparison_operator"
414 [(match_operand 4 "cc_register" "") (const_int 0)])
415 (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
416 (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
417 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
421 fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
424 fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
427 fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
428 [(set_attr "conds" "use")
429 (set_attr "length" "4,4,8,4,4,8,4,4,8")
430 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
433 (define_insn "*thumb2_movsfcc_vfp"
434 [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
436 (match_operator 3 "arm_comparison_operator"
437 [(match_operand 4 "cc_register" "") (const_int 0)])
438 (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
439 (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
440 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
442 it\\t%D3\;fcpys%D3\\t%0, %2
443 it\\t%d3\;fcpys%d3\\t%0, %1
444 ite\\t%D3\;fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
445 it\\t%D3\;fmsr%D3\\t%0, %2
446 it\\t%d3\;fmsr%d3\\t%0, %1
447 ite\\t%D3\;fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
448 it\\t%D3\;fmrs%D3\\t%0, %2
449 it\\t%d3\;fmrs%d3\\t%0, %1
450 ite\\t%D3\;fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
451 [(set_attr "conds" "use")
452 (set_attr "length" "6,6,10,6,6,10,6,6,10")
453 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
456 (define_insn "*movdfcc_vfp"
457 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
459 (match_operator 3 "arm_comparison_operator"
460 [(match_operand 4 "cc_register" "") (const_int 0)])
461 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
462 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
463 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
467 fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
468 fmdrr%D3\\t%P0, %Q2, %R2
469 fmdrr%d3\\t%P0, %Q1, %R1
470 fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
471 fmrrd%D3\\t%Q0, %R0, %P2
472 fmrrd%d3\\t%Q0, %R0, %P1
473 fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
474 [(set_attr "conds" "use")
475 (set_attr "length" "4,4,8,4,4,8,4,4,8")
476 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
479 (define_insn "*thumb2_movdfcc_vfp"
480 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
482 (match_operator 3 "arm_comparison_operator"
483 [(match_operand 4 "cc_register" "") (const_int 0)])
484 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
485 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
486 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
488 it\\t%D3\;fcpyd%D3\\t%P0, %P2
489 it\\t%d3\;fcpyd%d3\\t%P0, %P1
490 ite\\t%D3\;fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
491 it\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2
492 it\t%d3\;fmdrr%d3\\t%P0, %Q1, %R1
493 ite\\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
494 it\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2
495 it\t%d3\;fmrrd%d3\\t%Q0, %R0, %P1
496 ite\\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
497 [(set_attr "conds" "use")
498 (set_attr "length" "6,6,10,6,6,10,6,6,10")
499 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
503 ;; Sign manipulation functions
505 (define_insn "*abssf2_vfp"
506 [(set (match_operand:SF 0 "s_register_operand" "=t")
507 (abs:SF (match_operand:SF 1 "s_register_operand" "t")))]
508 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
510 [(set_attr "predicable" "yes")
511 (set_attr "type" "ffarith")]
514 (define_insn "*absdf2_vfp"
515 [(set (match_operand:DF 0 "s_register_operand" "=w")
516 (abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
517 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
519 [(set_attr "predicable" "yes")
520 (set_attr "type" "ffarith")]
523 (define_insn "*negsf2_vfp"
524 [(set (match_operand:SF 0 "s_register_operand" "=t,?r")
525 (neg:SF (match_operand:SF 1 "s_register_operand" "t,r")))]
526 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
529 eor%?\\t%0, %1, #-2147483648"
530 [(set_attr "predicable" "yes")
531 (set_attr "type" "ffarith")]
534 (define_insn_and_split "*negdf2_vfp"
535 [(set (match_operand:DF 0 "s_register_operand" "=w,?r,?r")
536 (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))]
537 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
542 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && reload_completed
543 && arm_general_register_operand (operands[0], DFmode)"
544 [(set (match_dup 0) (match_dup 1))]
546 if (REGNO (operands[0]) == REGNO (operands[1]))
548 operands[0] = gen_highpart (SImode, operands[0]);
549 operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000));
553 rtx in_hi, in_lo, out_hi, out_lo;
555 in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]),
556 GEN_INT (0x80000000));
557 in_lo = gen_lowpart (SImode, operands[1]);
558 out_hi = gen_highpart (SImode, operands[0]);
559 out_lo = gen_lowpart (SImode, operands[0]);
561 if (REGNO (in_lo) == REGNO (out_hi))
563 emit_insn (gen_rtx_SET (SImode, out_lo, in_lo));
564 operands[0] = out_hi;
569 emit_insn (gen_rtx_SET (SImode, out_hi, in_hi));
570 operands[0] = out_lo;
575 [(set_attr "predicable" "yes")
576 (set_attr "length" "4,4,8")
577 (set_attr "type" "ffarith")]
583 (define_insn "*addsf3_vfp"
584 [(set (match_operand:SF 0 "s_register_operand" "=t")
585 (plus:SF (match_operand:SF 1 "s_register_operand" "t")
586 (match_operand:SF 2 "s_register_operand" "t")))]
587 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
588 "fadds%?\\t%0, %1, %2"
589 [(set_attr "predicable" "yes")
590 (set_attr "type" "farith")]
593 (define_insn "*adddf3_vfp"
594 [(set (match_operand:DF 0 "s_register_operand" "=w")
595 (plus:DF (match_operand:DF 1 "s_register_operand" "w")
596 (match_operand:DF 2 "s_register_operand" "w")))]
597 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
598 "faddd%?\\t%P0, %P1, %P2"
599 [(set_attr "predicable" "yes")
600 (set_attr "type" "farith")]
604 (define_insn "*subsf3_vfp"
605 [(set (match_operand:SF 0 "s_register_operand" "=t")
606 (minus:SF (match_operand:SF 1 "s_register_operand" "t")
607 (match_operand:SF 2 "s_register_operand" "t")))]
608 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
609 "fsubs%?\\t%0, %1, %2"
610 [(set_attr "predicable" "yes")
611 (set_attr "type" "farith")]
614 (define_insn "*subdf3_vfp"
615 [(set (match_operand:DF 0 "s_register_operand" "=w")
616 (minus:DF (match_operand:DF 1 "s_register_operand" "w")
617 (match_operand:DF 2 "s_register_operand" "w")))]
618 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
619 "fsubd%?\\t%P0, %P1, %P2"
620 [(set_attr "predicable" "yes")
621 (set_attr "type" "farith")]
627 (define_insn "*divsf3_vfp"
628 [(set (match_operand:SF 0 "s_register_operand" "+t")
629 (div:SF (match_operand:SF 1 "s_register_operand" "t")
630 (match_operand:SF 2 "s_register_operand" "t")))]
631 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
632 "fdivs%?\\t%0, %1, %2"
633 [(set_attr "predicable" "yes")
634 (set_attr "type" "fdivs")]
637 (define_insn "*divdf3_vfp"
638 [(set (match_operand:DF 0 "s_register_operand" "+w")
639 (div:DF (match_operand:DF 1 "s_register_operand" "w")
640 (match_operand:DF 2 "s_register_operand" "w")))]
641 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
642 "fdivd%?\\t%P0, %P1, %P2"
643 [(set_attr "predicable" "yes")
644 (set_attr "type" "fdivd")]
648 ;; Multiplication insns
650 (define_insn "*mulsf3_vfp"
651 [(set (match_operand:SF 0 "s_register_operand" "+t")
652 (mult:SF (match_operand:SF 1 "s_register_operand" "t")
653 (match_operand:SF 2 "s_register_operand" "t")))]
654 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
655 "fmuls%?\\t%0, %1, %2"
656 [(set_attr "predicable" "yes")
657 (set_attr "type" "farith")]
660 (define_insn "*muldf3_vfp"
661 [(set (match_operand:DF 0 "s_register_operand" "+w")
662 (mult:DF (match_operand:DF 1 "s_register_operand" "w")
663 (match_operand:DF 2 "s_register_operand" "w")))]
664 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
665 "fmuld%?\\t%P0, %P1, %P2"
666 [(set_attr "predicable" "yes")
667 (set_attr "type" "fmul")]
671 (define_insn "*mulsf3negsf_vfp"
672 [(set (match_operand:SF 0 "s_register_operand" "+t")
673 (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "t"))
674 (match_operand:SF 2 "s_register_operand" "t")))]
675 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
676 "fnmuls%?\\t%0, %1, %2"
677 [(set_attr "predicable" "yes")
678 (set_attr "type" "farith")]
681 (define_insn "*muldf3negdf_vfp"
682 [(set (match_operand:DF 0 "s_register_operand" "+w")
683 (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
684 (match_operand:DF 2 "s_register_operand" "w")))]
685 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
686 "fnmuld%?\\t%P0, %P1, %P2"
687 [(set_attr "predicable" "yes")
688 (set_attr "type" "fmul")]
692 ;; Multiply-accumulate insns
695 (define_insn "*mulsf3addsf_vfp"
696 [(set (match_operand:SF 0 "s_register_operand" "=t")
697 (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
698 (match_operand:SF 3 "s_register_operand" "t"))
699 (match_operand:SF 1 "s_register_operand" "0")))]
700 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
701 "fmacs%?\\t%0, %2, %3"
702 [(set_attr "predicable" "yes")
703 (set_attr "type" "farith")]
706 (define_insn "*muldf3adddf_vfp"
707 [(set (match_operand:DF 0 "s_register_operand" "=w")
708 (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
709 (match_operand:DF 3 "s_register_operand" "w"))
710 (match_operand:DF 1 "s_register_operand" "0")))]
711 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
712 "fmacd%?\\t%P0, %P2, %P3"
713 [(set_attr "predicable" "yes")
714 (set_attr "type" "fmul")]
718 (define_insn "*mulsf3subsf_vfp"
719 [(set (match_operand:SF 0 "s_register_operand" "=t")
720 (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
721 (match_operand:SF 3 "s_register_operand" "t"))
722 (match_operand:SF 1 "s_register_operand" "0")))]
723 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
724 "fmscs%?\\t%0, %2, %3"
725 [(set_attr "predicable" "yes")
726 (set_attr "type" "farith")]
729 (define_insn "*muldf3subdf_vfp"
730 [(set (match_operand:DF 0 "s_register_operand" "=w")
731 (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
732 (match_operand:DF 3 "s_register_operand" "w"))
733 (match_operand:DF 1 "s_register_operand" "0")))]
734 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
735 "fmscd%?\\t%P0, %P2, %P3"
736 [(set_attr "predicable" "yes")
737 (set_attr "type" "fmul")]
741 (define_insn "*mulsf3negsfaddsf_vfp"
742 [(set (match_operand:SF 0 "s_register_operand" "=t")
743 (minus:SF (match_operand:SF 1 "s_register_operand" "0")
744 (mult:SF (match_operand:SF 2 "s_register_operand" "t")
745 (match_operand:SF 3 "s_register_operand" "t"))))]
746 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
747 "fnmacs%?\\t%0, %2, %3"
748 [(set_attr "predicable" "yes")
749 (set_attr "type" "farith")]
752 (define_insn "*fmuldf3negdfadddf_vfp"
753 [(set (match_operand:DF 0 "s_register_operand" "=w")
754 (minus:DF (match_operand:DF 1 "s_register_operand" "0")
755 (mult:DF (match_operand:DF 2 "s_register_operand" "w")
756 (match_operand:DF 3 "s_register_operand" "w"))))]
757 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
758 "fnmacd%?\\t%P0, %P2, %P3"
759 [(set_attr "predicable" "yes")
760 (set_attr "type" "fmul")]
765 (define_insn "*mulsf3negsfsubsf_vfp"
766 [(set (match_operand:SF 0 "s_register_operand" "=t")
768 (neg:SF (match_operand:SF 2 "s_register_operand" "t"))
769 (match_operand:SF 3 "s_register_operand" "t"))
770 (match_operand:SF 1 "s_register_operand" "0")))]
771 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
772 "fnmscs%?\\t%0, %2, %3"
773 [(set_attr "predicable" "yes")
774 (set_attr "type" "farith")]
777 (define_insn "*muldf3negdfsubdf_vfp"
778 [(set (match_operand:DF 0 "s_register_operand" "=w")
780 (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
781 (match_operand:DF 3 "s_register_operand" "w"))
782 (match_operand:DF 1 "s_register_operand" "0")))]
783 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
784 "fnmscd%?\\t%P0, %P2, %P3"
785 [(set_attr "predicable" "yes")
786 (set_attr "type" "fmul")]
790 ;; Conversion routines
792 (define_insn "*extendsfdf2_vfp"
793 [(set (match_operand:DF 0 "s_register_operand" "=w")
794 (float_extend:DF (match_operand:SF 1 "s_register_operand" "t")))]
795 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
797 [(set_attr "predicable" "yes")
798 (set_attr "type" "f_cvt")]
801 (define_insn "*truncdfsf2_vfp"
802 [(set (match_operand:SF 0 "s_register_operand" "=t")
803 (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
804 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
806 [(set_attr "predicable" "yes")
807 (set_attr "type" "f_cvt")]
810 (define_insn "*truncsisf2_vfp"
811 [(set (match_operand:SI 0 "s_register_operand" "=t")
812 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
813 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
815 [(set_attr "predicable" "yes")
816 (set_attr "type" "f_cvt")]
819 (define_insn "*truncsidf2_vfp"
820 [(set (match_operand:SI 0 "s_register_operand" "=t")
821 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
822 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
823 "ftosizd%?\\t%0, %P1"
824 [(set_attr "predicable" "yes")
825 (set_attr "type" "f_cvt")]
829 (define_insn "fixuns_truncsfsi2"
830 [(set (match_operand:SI 0 "s_register_operand" "=t")
831 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
832 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
834 [(set_attr "predicable" "yes")
835 (set_attr "type" "f_cvt")]
838 (define_insn "fixuns_truncdfsi2"
839 [(set (match_operand:SI 0 "s_register_operand" "=t")
840 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "t"))))]
841 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
842 "ftouizd%?\\t%0, %P1"
843 [(set_attr "predicable" "yes")
844 (set_attr "type" "f_cvt")]
848 (define_insn "*floatsisf2_vfp"
849 [(set (match_operand:SF 0 "s_register_operand" "=t")
850 (float:SF (match_operand:SI 1 "s_register_operand" "t")))]
851 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
853 [(set_attr "predicable" "yes")
854 (set_attr "type" "f_cvt")]
857 (define_insn "*floatsidf2_vfp"
858 [(set (match_operand:DF 0 "s_register_operand" "=w")
859 (float:DF (match_operand:SI 1 "s_register_operand" "t")))]
860 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
862 [(set_attr "predicable" "yes")
863 (set_attr "type" "f_cvt")]
867 (define_insn "floatunssisf2"
868 [(set (match_operand:SF 0 "s_register_operand" "=t")
869 (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "t")))]
870 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
872 [(set_attr "predicable" "yes")
873 (set_attr "type" "f_cvt")]
876 (define_insn "floatunssidf2"
877 [(set (match_operand:DF 0 "s_register_operand" "=w")
878 (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "t")))]
879 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
881 [(set_attr "predicable" "yes")
882 (set_attr "type" "f_cvt")]
888 (define_insn "*sqrtsf2_vfp"
889 [(set (match_operand:SF 0 "s_register_operand" "=t")
890 (sqrt:SF (match_operand:SF 1 "s_register_operand" "t")))]
891 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
893 [(set_attr "predicable" "yes")
894 (set_attr "type" "fdivs")]
897 (define_insn "*sqrtdf2_vfp"
898 [(set (match_operand:DF 0 "s_register_operand" "=w")
899 (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))]
900 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
901 "fsqrtd%?\\t%P0, %P1"
902 [(set_attr "predicable" "yes")
903 (set_attr "type" "fdivd")]
907 ;; Patterns to split/copy vfp condition flags.
909 (define_insn "*movcc_vfp"
910 [(set (reg CC_REGNUM)
912 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
914 [(set_attr "conds" "set")
915 (set_attr "type" "f_flag")]
918 (define_insn_and_split "*cmpsf_split_vfp"
919 [(set (reg:CCFP CC_REGNUM)
920 (compare:CCFP (match_operand:SF 0 "s_register_operand" "t")
921 (match_operand:SF 1 "vfp_compare_operand" "tG")))]
922 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
924 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
925 [(set (reg:CCFP VFPCC_REGNUM)
926 (compare:CCFP (match_dup 0)
928 (set (reg:CCFP CC_REGNUM)
929 (reg:CCFP VFPCC_REGNUM))]
933 (define_insn_and_split "*cmpsf_trap_split_vfp"
934 [(set (reg:CCFPE CC_REGNUM)
935 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t")
936 (match_operand:SF 1 "vfp_compare_operand" "tG")))]
937 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
939 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
940 [(set (reg:CCFPE VFPCC_REGNUM)
941 (compare:CCFPE (match_dup 0)
943 (set (reg:CCFPE CC_REGNUM)
944 (reg:CCFPE VFPCC_REGNUM))]
948 (define_insn_and_split "*cmpdf_split_vfp"
949 [(set (reg:CCFP CC_REGNUM)
950 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w")
951 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
952 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
954 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
955 [(set (reg:CCFP VFPCC_REGNUM)
956 (compare:CCFP (match_dup 0)
958 (set (reg:CCFP CC_REGNUM)
959 (reg:CCFPE VFPCC_REGNUM))]
963 (define_insn_and_split "*cmpdf_trap_split_vfp"
964 [(set (reg:CCFPE CC_REGNUM)
965 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w")
966 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
967 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
969 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
970 [(set (reg:CCFPE VFPCC_REGNUM)
971 (compare:CCFPE (match_dup 0)
973 (set (reg:CCFPE CC_REGNUM)
974 (reg:CCFPE VFPCC_REGNUM))]
979 ;; Comparison patterns
981 (define_insn "*cmpsf_vfp"
982 [(set (reg:CCFP VFPCC_REGNUM)
983 (compare:CCFP (match_operand:SF 0 "s_register_operand" "t,t")
984 (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
985 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
989 [(set_attr "predicable" "yes")
990 (set_attr "type" "ffarith")]
993 (define_insn "*cmpsf_trap_vfp"
994 [(set (reg:CCFPE VFPCC_REGNUM)
995 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t,t")
996 (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
997 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1001 [(set_attr "predicable" "yes")
1002 (set_attr "type" "ffarith")]
1005 (define_insn "*cmpdf_vfp"
1006 [(set (reg:CCFP VFPCC_REGNUM)
1007 (compare:CCFP (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")]
1017 (define_insn "*cmpdf_trap_vfp"
1018 [(set (reg:CCFPE VFPCC_REGNUM)
1019 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w")
1020 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1021 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1025 [(set_attr "predicable" "yes")
1026 (set_attr "type" "ffarith")]
1030 ;; Store multiple insn used in function prologue.
1032 (define_insn "*push_multi_vfp"
1033 [(match_parallel 2 "multi_register_push"
1034 [(set (match_operand:BLK 0 "memory_operand" "=m")
1035 (unspec:BLK [(match_operand:DF 1 "s_register_operand" "w")]
1036 UNSPEC_PUSH_MULT))])]
1037 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1038 "* return vfp_output_fstmd (operands);"
1039 [(set_attr "type" "f_stored")]
1043 ;; Unimplemented insns:
1046 ;; fmdhr et al (VFPv1)
1047 ;; Support for xD (single precision only) variants.