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 3, 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 COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>. */
21 ;; Additional register numbers
26 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
27 ;; Pipeline description
28 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
30 (define_automaton "vfp11")
32 ;; There are 3 pipelines in the VFP11 unit.
34 ;; - A 8-stage FMAC pipeline (7 execute + writeback) with forward from
35 ;; fourth stage for simple operations.
37 ;; - A 5-stage DS pipeline (4 execute + writeback) for divide/sqrt insns.
38 ;; These insns also uses first execute stage of FMAC pipeline.
40 ;; - A 4-stage LS pipeline (execute + 2 memory + writeback) with forward from
41 ;; second memory stage for loads.
43 ;; We do not model Write-After-Read hazards.
44 ;; We do not do write scheduling with the arm core, so it is only necessary
45 ;; to model the first stage of each pipeline
46 ;; ??? Need to model LS pipeline properly for load/store multiple?
47 ;; We do not model fmstat properly. This could be done by modeling pipelines
48 ;; properly and defining an absence set between a dummy fmstat unit and all
51 (define_cpu_unit "fmac" "vfp11")
53 (define_cpu_unit "ds" "vfp11")
55 (define_cpu_unit "vfp_ls" "vfp11")
57 (define_cpu_unit "fmstat" "vfp11")
59 (exclusion_set "fmac,ds" "fmstat")
61 ;; The VFP "type" attributes differ from those used in the FPA model.
62 ;; ffarith Fast floating point insns, e.g. abs, neg, cpy, cmp.
63 ;; farith Most arithmetic insns.
64 ;; fmul Double precision multiply.
65 ;; fdivs Single precision sqrt or division.
66 ;; fdivd Double precision sqrt or division.
67 ;; f_flag fmstat operation
68 ;; f_load[sd] Floating point load from memory.
69 ;; f_store[sd] Floating point store to memory.
70 ;; f_2_r Transfer vfp to arm reg.
71 ;; r_2_f Transfer arm to vfp reg.
72 ;; f_cvt Convert floating<->integral
74 (define_insn_reservation "vfp_ffarith" 4
75 (and (eq_attr "generic_vfp" "yes")
76 (eq_attr "type" "ffarith"))
79 (define_insn_reservation "vfp_farith" 8
80 (and (eq_attr "generic_vfp" "yes")
81 (eq_attr "type" "farith,f_cvt"))
84 (define_insn_reservation "vfp_fmul" 9
85 (and (eq_attr "generic_vfp" "yes")
86 (eq_attr "type" "fmul"))
89 (define_insn_reservation "vfp_fdivs" 19
90 (and (eq_attr "generic_vfp" "yes")
91 (eq_attr "type" "fdivs"))
94 (define_insn_reservation "vfp_fdivd" 33
95 (and (eq_attr "generic_vfp" "yes")
96 (eq_attr "type" "fdivd"))
99 ;; Moves to/from arm regs also use the load/store pipeline.
100 (define_insn_reservation "vfp_fload" 4
101 (and (eq_attr "generic_vfp" "yes")
102 (eq_attr "type" "f_loads,f_loadd,r_2_f"))
105 (define_insn_reservation "vfp_fstore" 4
106 (and (eq_attr "generic_vfp" "yes")
107 (eq_attr "type" "f_stores,f_stored,f_2_r"))
110 (define_insn_reservation "vfp_to_cpsr" 4
111 (and (eq_attr "generic_vfp" "yes")
112 (eq_attr "type" "f_flag"))
115 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
117 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
120 ;; ??? For now do not allow loading constants into vfp regs. This causes
121 ;; problems because small constants get converted into adds.
122 (define_insn "*arm_movsi_vfp"
123 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m ,*t,r,*t,*t, *Uv")
124 (match_operand:SI 1 "general_operand" "rk, I,K,N,mi,rk,r,*t,*t,*Uvi,*t"))]
125 "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
126 && ( s_register_operand (operands[0], SImode)
127 || s_register_operand (operands[1], SImode))"
129 switch (which_alternative)
132 return \"mov%?\\t%0, %1\";
134 return \"mvn%?\\t%0, #%B1\";
136 return \"movw%?\\t%0, %1\";
138 return \"ldr%?\\t%0, %1\";
140 return \"str%?\\t%1, %0\";
142 return \"fmsr%?\\t%0, %1\\t%@ int\";
144 return \"fmrs%?\\t%0, %1\\t%@ int\";
146 return \"fcpys%?\\t%0, %1\\t%@ int\";
148 return output_move_vfp (operands);
153 [(set_attr "predicable" "yes")
154 (set_attr "type" "*,*,*,*,load1,store1,r_2_f,f_2_r,ffarith,f_loads,f_stores")
155 (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*")
156 (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")]
159 (define_insn "*thumb2_movsi_vfp"
160 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m,*t,r, *t,*t, *Uv")
161 (match_operand:SI 1 "general_operand" "rk, I,K,N,mi,rk,r,*t,*t,*Uvi,*t"))]
162 "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT
163 && ( s_register_operand (operands[0], SImode)
164 || s_register_operand (operands[1], SImode))"
166 switch (which_alternative)
169 return \"mov%?\\t%0, %1\";
171 return \"mvn%?\\t%0, #%B1\";
173 return \"movw%?\\t%0, %1\";
175 return \"ldr%?\\t%0, %1\";
177 return \"str%?\\t%1, %0\";
179 return \"fmsr%?\\t%0, %1\\t%@ int\";
181 return \"fmrs%?\\t%0, %1\\t%@ int\";
183 return \"fcpys%?\\t%0, %1\\t%@ int\";
185 return output_move_vfp (operands);
190 [(set_attr "predicable" "yes")
191 (set_attr "type" "*,*,*,*,load1,store1,r_2_f,f_2_r,ffarith,f_load,f_store")
192 (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*")
193 (set_attr "neg_pool_range" "*,*,*,*, 0,*,*,*,*,1008,*")]
199 (define_insn "*arm_movdi_vfp"
200 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
201 (match_operand:DI 1 "di_operand" "rIK,mi,r,r,w,w,Uvi,w"))]
202 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
203 && ( register_operand (operands[0], DImode)
204 || register_operand (operands[1], DImode))"
206 switch (which_alternative)
212 return output_move_double (operands);
214 return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
216 return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
218 return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
220 return output_move_vfp (operands);
225 [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_loadd,f_stored")
226 (set_attr "length" "8,8,8,4,4,4,4,4")
227 (set_attr "pool_range" "*,1020,*,*,*,*,1020,*")
228 (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
231 (define_insn "*thumb2_movdi_vfp"
232 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
233 (match_operand:DI 1 "di_operand" "rIK,mi,r,r,w,w,Uvi,w"))]
234 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
236 switch (which_alternative)
238 case 0: case 1: case 2:
239 return (output_move_double (operands));
241 return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
243 return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
245 return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
247 return output_move_vfp (operands);
252 [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarith,f_load,f_store")
253 (set_attr "length" "8,8,8,4,4,4,4,4")
254 (set_attr "pool_range" "*,4096,*,*,*,*,1020,*")
255 (set_attr "neg_pool_range" "*, 0,*,*,*,*,1008,*")]
260 ;; Disparage the w<->r cases because reloading an invalid address is
261 ;; preferable to loading the value via integer registers.
263 (define_insn "*movsf_vfp"
264 [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t ,t ,Uv,r ,m,t,r")
265 (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))]
266 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
267 && ( s_register_operand (operands[0], SFmode)
268 || s_register_operand (operands[1], SFmode))"
270 switch (which_alternative)
273 return \"fmsr%?\\t%0, %1\";
275 return \"fmrs%?\\t%0, %1\";
277 return \"fconsts%?\\t%0, #%G1\";
279 return output_move_vfp (operands);
281 return \"ldr%?\\t%0, %1\\t%@ float\";
283 return \"str%?\\t%1, %0\\t%@ float\";
285 return \"fcpys%?\\t%0, %1\";
287 return \"mov%?\\t%0, %1\\t%@ float\";
292 [(set_attr "predicable" "yes")
294 "r_2_f,f_2_r,farith,f_loads,f_stores,load1,store1,ffarith,*")
295 (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*")
296 (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")]
299 (define_insn "*thumb2_movsf_vfp"
300 [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t, t ,Uv,r ,m,t,r")
301 (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))]
302 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP
303 && ( s_register_operand (operands[0], SFmode)
304 || s_register_operand (operands[1], SFmode))"
306 switch (which_alternative)
309 return \"fmsr%?\\t%0, %1\";
311 return \"fmrs%?\\t%0, %1\";
313 return \"fconsts%?\\t%0, #%G1\";
315 return output_move_vfp (operands);
317 return \"ldr%?\\t%0, %1\\t%@ float\";
319 return \"str%?\\t%1, %0\\t%@ float\";
321 return \"fcpys%?\\t%0, %1\";
323 return \"mov%?\\t%0, %1\\t%@ float\";
328 [(set_attr "predicable" "yes")
330 "r_2_f,f_2_r,farith,f_load,f_store,load1,store1,ffarith,*")
331 (set_attr "pool_range" "*,*,*,1020,*,4092,*,*,*")
332 (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")]
338 (define_insn "*movdf_vfp"
339 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w ,Uv,w,r")
340 (match_operand:DF 1 "soft_df_operand" " ?r,w,Dv,mF,r,UvF,w, w,r"))]
341 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
342 && ( register_operand (operands[0], DFmode)
343 || register_operand (operands[1], DFmode))"
346 switch (which_alternative)
349 return \"fmdrr%?\\t%P0, %Q1, %R1\";
351 return \"fmrrd%?\\t%Q0, %R0, %P1\";
353 return \"fconstd%?\\t%P0, #%G1\";
355 return output_move_double (operands);
357 return output_move_vfp (operands);
359 return \"fcpyd%?\\t%P0, %P1\";
368 "r_2_f,f_2_r,farith,f_loadd,f_stored,load2,store2,ffarith,*")
369 (set_attr "length" "4,4,4,8,8,4,4,4,8")
370 (set_attr "pool_range" "*,*,*,1020,*,1020,*,*,*")
371 (set_attr "neg_pool_range" "*,*,*,1008,*,1008,*,*,*")]
374 (define_insn "*thumb2_movdf_vfp"
375 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w ,Uv,w,r")
376 (match_operand:DF 1 "soft_df_operand" " ?r,w,Dv,mF,r,UvF,w, w,r"))]
377 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
380 switch (which_alternative)
383 return \"fmdrr%?\\t%P0, %Q1, %R1\";
385 return \"fmrrd%?\\t%Q0, %R0, %P1\";
387 return \"fconstd%?\\t%P0, #%G1\";
388 case 3: case 4: case 8:
389 return output_move_double (operands);
391 return output_move_vfp (operands);
393 return \"fcpyd%?\\t%P0, %P1\";
400 "r_2_f,f_2_r,farith,load2,store2,f_load,f_store,ffarith,*")
401 (set_attr "length" "4,4,4,8,8,4,4,4,8")
402 (set_attr "pool_range" "*,*,*,4096,*,1020,*,*,*")
403 (set_attr "neg_pool_range" "*,*,*,0,*,1008,*,*,*")]
407 ;; Conditional move patterns
409 (define_insn "*movsfcc_vfp"
410 [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
412 (match_operator 3 "arm_comparison_operator"
413 [(match_operand 4 "cc_register" "") (const_int 0)])
414 (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
415 (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
416 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
420 fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
423 fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
426 fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
427 [(set_attr "conds" "use")
428 (set_attr "length" "4,4,8,4,4,8,4,4,8")
429 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
432 (define_insn "*thumb2_movsfcc_vfp"
433 [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
435 (match_operator 3 "arm_comparison_operator"
436 [(match_operand 4 "cc_register" "") (const_int 0)])
437 (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
438 (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
439 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
441 it\\t%D3\;fcpys%D3\\t%0, %2
442 it\\t%d3\;fcpys%d3\\t%0, %1
443 ite\\t%D3\;fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
444 it\\t%D3\;fmsr%D3\\t%0, %2
445 it\\t%d3\;fmsr%d3\\t%0, %1
446 ite\\t%D3\;fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
447 it\\t%D3\;fmrs%D3\\t%0, %2
448 it\\t%d3\;fmrs%d3\\t%0, %1
449 ite\\t%D3\;fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
450 [(set_attr "conds" "use")
451 (set_attr "length" "6,6,10,6,6,10,6,6,10")
452 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
455 (define_insn "*movdfcc_vfp"
456 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
458 (match_operator 3 "arm_comparison_operator"
459 [(match_operand 4 "cc_register" "") (const_int 0)])
460 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
461 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
462 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
466 fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
467 fmdrr%D3\\t%P0, %Q2, %R2
468 fmdrr%d3\\t%P0, %Q1, %R1
469 fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
470 fmrrd%D3\\t%Q0, %R0, %P2
471 fmrrd%d3\\t%Q0, %R0, %P1
472 fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
473 [(set_attr "conds" "use")
474 (set_attr "length" "4,4,8,4,4,8,4,4,8")
475 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
478 (define_insn "*thumb2_movdfcc_vfp"
479 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
481 (match_operator 3 "arm_comparison_operator"
482 [(match_operand 4 "cc_register" "") (const_int 0)])
483 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
484 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
485 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
487 it\\t%D3\;fcpyd%D3\\t%P0, %P2
488 it\\t%d3\;fcpyd%d3\\t%P0, %P1
489 ite\\t%D3\;fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
490 it\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2
491 it\t%d3\;fmdrr%d3\\t%P0, %Q1, %R1
492 ite\\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
493 it\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2
494 it\t%d3\;fmrrd%d3\\t%Q0, %R0, %P1
495 ite\\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
496 [(set_attr "conds" "use")
497 (set_attr "length" "6,6,10,6,6,10,6,6,10")
498 (set_attr "type" "ffarith,ffarith,ffarith,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
502 ;; Sign manipulation functions
504 (define_insn "*abssf2_vfp"
505 [(set (match_operand:SF 0 "s_register_operand" "=t")
506 (abs:SF (match_operand:SF 1 "s_register_operand" "t")))]
507 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
509 [(set_attr "predicable" "yes")
510 (set_attr "type" "ffarith")]
513 (define_insn "*absdf2_vfp"
514 [(set (match_operand:DF 0 "s_register_operand" "=w")
515 (abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
516 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
518 [(set_attr "predicable" "yes")
519 (set_attr "type" "ffarith")]
522 (define_insn "*negsf2_vfp"
523 [(set (match_operand:SF 0 "s_register_operand" "=t,?r")
524 (neg:SF (match_operand:SF 1 "s_register_operand" "t,r")))]
525 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
528 eor%?\\t%0, %1, #-2147483648"
529 [(set_attr "predicable" "yes")
530 (set_attr "type" "ffarith")]
533 (define_insn_and_split "*negdf2_vfp"
534 [(set (match_operand:DF 0 "s_register_operand" "=w,?r,?r")
535 (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))]
536 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
541 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && reload_completed
542 && arm_general_register_operand (operands[0], DFmode)"
543 [(set (match_dup 0) (match_dup 1))]
545 if (REGNO (operands[0]) == REGNO (operands[1]))
547 operands[0] = gen_highpart (SImode, operands[0]);
548 operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000));
552 rtx in_hi, in_lo, out_hi, out_lo;
554 in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]),
555 GEN_INT (0x80000000));
556 in_lo = gen_lowpart (SImode, operands[1]);
557 out_hi = gen_highpart (SImode, operands[0]);
558 out_lo = gen_lowpart (SImode, operands[0]);
560 if (REGNO (in_lo) == REGNO (out_hi))
562 emit_insn (gen_rtx_SET (SImode, out_lo, in_lo));
563 operands[0] = out_hi;
568 emit_insn (gen_rtx_SET (SImode, out_hi, in_hi));
569 operands[0] = out_lo;
574 [(set_attr "predicable" "yes")
575 (set_attr "length" "4,4,8")
576 (set_attr "type" "ffarith")]
582 (define_insn "*addsf3_vfp"
583 [(set (match_operand:SF 0 "s_register_operand" "=t")
584 (plus:SF (match_operand:SF 1 "s_register_operand" "t")
585 (match_operand:SF 2 "s_register_operand" "t")))]
586 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
587 "fadds%?\\t%0, %1, %2"
588 [(set_attr "predicable" "yes")
589 (set_attr "type" "farith")]
592 (define_insn "*adddf3_vfp"
593 [(set (match_operand:DF 0 "s_register_operand" "=w")
594 (plus:DF (match_operand:DF 1 "s_register_operand" "w")
595 (match_operand:DF 2 "s_register_operand" "w")))]
596 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
597 "faddd%?\\t%P0, %P1, %P2"
598 [(set_attr "predicable" "yes")
599 (set_attr "type" "farith")]
603 (define_insn "*subsf3_vfp"
604 [(set (match_operand:SF 0 "s_register_operand" "=t")
605 (minus:SF (match_operand:SF 1 "s_register_operand" "t")
606 (match_operand:SF 2 "s_register_operand" "t")))]
607 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
608 "fsubs%?\\t%0, %1, %2"
609 [(set_attr "predicable" "yes")
610 (set_attr "type" "farith")]
613 (define_insn "*subdf3_vfp"
614 [(set (match_operand:DF 0 "s_register_operand" "=w")
615 (minus:DF (match_operand:DF 1 "s_register_operand" "w")
616 (match_operand:DF 2 "s_register_operand" "w")))]
617 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
618 "fsubd%?\\t%P0, %P1, %P2"
619 [(set_attr "predicable" "yes")
620 (set_attr "type" "farith")]
626 (define_insn "*divsf3_vfp"
627 [(set (match_operand:SF 0 "s_register_operand" "+t")
628 (div:SF (match_operand:SF 1 "s_register_operand" "t")
629 (match_operand:SF 2 "s_register_operand" "t")))]
630 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
631 "fdivs%?\\t%0, %1, %2"
632 [(set_attr "predicable" "yes")
633 (set_attr "type" "fdivs")]
636 (define_insn "*divdf3_vfp"
637 [(set (match_operand:DF 0 "s_register_operand" "+w")
638 (div:DF (match_operand:DF 1 "s_register_operand" "w")
639 (match_operand:DF 2 "s_register_operand" "w")))]
640 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
641 "fdivd%?\\t%P0, %P1, %P2"
642 [(set_attr "predicable" "yes")
643 (set_attr "type" "fdivd")]
647 ;; Multiplication insns
649 (define_insn "*mulsf3_vfp"
650 [(set (match_operand:SF 0 "s_register_operand" "+t")
651 (mult:SF (match_operand:SF 1 "s_register_operand" "t")
652 (match_operand:SF 2 "s_register_operand" "t")))]
653 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
654 "fmuls%?\\t%0, %1, %2"
655 [(set_attr "predicable" "yes")
656 (set_attr "type" "farith")]
659 (define_insn "*muldf3_vfp"
660 [(set (match_operand:DF 0 "s_register_operand" "+w")
661 (mult:DF (match_operand:DF 1 "s_register_operand" "w")
662 (match_operand:DF 2 "s_register_operand" "w")))]
663 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
664 "fmuld%?\\t%P0, %P1, %P2"
665 [(set_attr "predicable" "yes")
666 (set_attr "type" "fmul")]
670 (define_insn "*mulsf3negsf_vfp"
671 [(set (match_operand:SF 0 "s_register_operand" "+t")
672 (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "t"))
673 (match_operand:SF 2 "s_register_operand" "t")))]
674 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
675 "fnmuls%?\\t%0, %1, %2"
676 [(set_attr "predicable" "yes")
677 (set_attr "type" "farith")]
680 (define_insn "*muldf3negdf_vfp"
681 [(set (match_operand:DF 0 "s_register_operand" "+w")
682 (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
683 (match_operand:DF 2 "s_register_operand" "w")))]
684 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
685 "fnmuld%?\\t%P0, %P1, %P2"
686 [(set_attr "predicable" "yes")
687 (set_attr "type" "fmul")]
691 ;; Multiply-accumulate insns
694 (define_insn "*mulsf3addsf_vfp"
695 [(set (match_operand:SF 0 "s_register_operand" "=t")
696 (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
697 (match_operand:SF 3 "s_register_operand" "t"))
698 (match_operand:SF 1 "s_register_operand" "0")))]
699 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
700 "fmacs%?\\t%0, %2, %3"
701 [(set_attr "predicable" "yes")
702 (set_attr "type" "farith")]
705 (define_insn "*muldf3adddf_vfp"
706 [(set (match_operand:DF 0 "s_register_operand" "=w")
707 (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
708 (match_operand:DF 3 "s_register_operand" "w"))
709 (match_operand:DF 1 "s_register_operand" "0")))]
710 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
711 "fmacd%?\\t%P0, %P2, %P3"
712 [(set_attr "predicable" "yes")
713 (set_attr "type" "fmul")]
717 (define_insn "*mulsf3subsf_vfp"
718 [(set (match_operand:SF 0 "s_register_operand" "=t")
719 (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
720 (match_operand:SF 3 "s_register_operand" "t"))
721 (match_operand:SF 1 "s_register_operand" "0")))]
722 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
723 "fmscs%?\\t%0, %2, %3"
724 [(set_attr "predicable" "yes")
725 (set_attr "type" "farith")]
728 (define_insn "*muldf3subdf_vfp"
729 [(set (match_operand:DF 0 "s_register_operand" "=w")
730 (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
731 (match_operand:DF 3 "s_register_operand" "w"))
732 (match_operand:DF 1 "s_register_operand" "0")))]
733 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
734 "fmscd%?\\t%P0, %P2, %P3"
735 [(set_attr "predicable" "yes")
736 (set_attr "type" "fmul")]
740 (define_insn "*mulsf3negsfaddsf_vfp"
741 [(set (match_operand:SF 0 "s_register_operand" "=t")
742 (minus:SF (match_operand:SF 1 "s_register_operand" "0")
743 (mult:SF (match_operand:SF 2 "s_register_operand" "t")
744 (match_operand:SF 3 "s_register_operand" "t"))))]
745 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
746 "fnmacs%?\\t%0, %2, %3"
747 [(set_attr "predicable" "yes")
748 (set_attr "type" "farith")]
751 (define_insn "*fmuldf3negdfadddf_vfp"
752 [(set (match_operand:DF 0 "s_register_operand" "=w")
753 (minus:DF (match_operand:DF 1 "s_register_operand" "0")
754 (mult:DF (match_operand:DF 2 "s_register_operand" "w")
755 (match_operand:DF 3 "s_register_operand" "w"))))]
756 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
757 "fnmacd%?\\t%P0, %P2, %P3"
758 [(set_attr "predicable" "yes")
759 (set_attr "type" "fmul")]
764 (define_insn "*mulsf3negsfsubsf_vfp"
765 [(set (match_operand:SF 0 "s_register_operand" "=t")
767 (neg:SF (match_operand:SF 2 "s_register_operand" "t"))
768 (match_operand:SF 3 "s_register_operand" "t"))
769 (match_operand:SF 1 "s_register_operand" "0")))]
770 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
771 "fnmscs%?\\t%0, %2, %3"
772 [(set_attr "predicable" "yes")
773 (set_attr "type" "farith")]
776 (define_insn "*muldf3negdfsubdf_vfp"
777 [(set (match_operand:DF 0 "s_register_operand" "=w")
779 (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
780 (match_operand:DF 3 "s_register_operand" "w"))
781 (match_operand:DF 1 "s_register_operand" "0")))]
782 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
783 "fnmscd%?\\t%P0, %P2, %P3"
784 [(set_attr "predicable" "yes")
785 (set_attr "type" "fmul")]
789 ;; Conversion routines
791 (define_insn "*extendsfdf2_vfp"
792 [(set (match_operand:DF 0 "s_register_operand" "=w")
793 (float_extend:DF (match_operand:SF 1 "s_register_operand" "t")))]
794 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
796 [(set_attr "predicable" "yes")
797 (set_attr "type" "f_cvt")]
800 (define_insn "*truncdfsf2_vfp"
801 [(set (match_operand:SF 0 "s_register_operand" "=t")
802 (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
803 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
805 [(set_attr "predicable" "yes")
806 (set_attr "type" "f_cvt")]
809 (define_insn "*truncsisf2_vfp"
810 [(set (match_operand:SI 0 "s_register_operand" "=t")
811 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
812 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
814 [(set_attr "predicable" "yes")
815 (set_attr "type" "f_cvt")]
818 (define_insn "*truncsidf2_vfp"
819 [(set (match_operand:SI 0 "s_register_operand" "=t")
820 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
821 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
822 "ftosizd%?\\t%0, %P1"
823 [(set_attr "predicable" "yes")
824 (set_attr "type" "f_cvt")]
828 (define_insn "fixuns_truncsfsi2"
829 [(set (match_operand:SI 0 "s_register_operand" "=t")
830 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
831 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
833 [(set_attr "predicable" "yes")
834 (set_attr "type" "f_cvt")]
837 (define_insn "fixuns_truncdfsi2"
838 [(set (match_operand:SI 0 "s_register_operand" "=t")
839 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "t"))))]
840 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
841 "ftouizd%?\\t%0, %P1"
842 [(set_attr "predicable" "yes")
843 (set_attr "type" "f_cvt")]
847 (define_insn "*floatsisf2_vfp"
848 [(set (match_operand:SF 0 "s_register_operand" "=t")
849 (float:SF (match_operand:SI 1 "s_register_operand" "t")))]
850 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
852 [(set_attr "predicable" "yes")
853 (set_attr "type" "f_cvt")]
856 (define_insn "*floatsidf2_vfp"
857 [(set (match_operand:DF 0 "s_register_operand" "=w")
858 (float:DF (match_operand:SI 1 "s_register_operand" "t")))]
859 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
861 [(set_attr "predicable" "yes")
862 (set_attr "type" "f_cvt")]
866 (define_insn "floatunssisf2"
867 [(set (match_operand:SF 0 "s_register_operand" "=t")
868 (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "t")))]
869 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
871 [(set_attr "predicable" "yes")
872 (set_attr "type" "f_cvt")]
875 (define_insn "floatunssidf2"
876 [(set (match_operand:DF 0 "s_register_operand" "=w")
877 (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "t")))]
878 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
880 [(set_attr "predicable" "yes")
881 (set_attr "type" "f_cvt")]
887 (define_insn "*sqrtsf2_vfp"
888 [(set (match_operand:SF 0 "s_register_operand" "=t")
889 (sqrt:SF (match_operand:SF 1 "s_register_operand" "t")))]
890 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
892 [(set_attr "predicable" "yes")
893 (set_attr "type" "fdivs")]
896 (define_insn "*sqrtdf2_vfp"
897 [(set (match_operand:DF 0 "s_register_operand" "=w")
898 (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))]
899 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
900 "fsqrtd%?\\t%P0, %P1"
901 [(set_attr "predicable" "yes")
902 (set_attr "type" "fdivd")]
906 ;; Patterns to split/copy vfp condition flags.
908 (define_insn "*movcc_vfp"
909 [(set (reg CC_REGNUM)
911 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
913 [(set_attr "conds" "set")
914 (set_attr "type" "f_flag")]
917 (define_insn_and_split "*cmpsf_split_vfp"
918 [(set (reg:CCFP CC_REGNUM)
919 (compare:CCFP (match_operand:SF 0 "s_register_operand" "t")
920 (match_operand:SF 1 "vfp_compare_operand" "tG")))]
921 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
923 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
924 [(set (reg:CCFP VFPCC_REGNUM)
925 (compare:CCFP (match_dup 0)
927 (set (reg:CCFP CC_REGNUM)
928 (reg:CCFP VFPCC_REGNUM))]
932 (define_insn_and_split "*cmpsf_trap_split_vfp"
933 [(set (reg:CCFPE CC_REGNUM)
934 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t")
935 (match_operand:SF 1 "vfp_compare_operand" "tG")))]
936 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
938 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
939 [(set (reg:CCFPE VFPCC_REGNUM)
940 (compare:CCFPE (match_dup 0)
942 (set (reg:CCFPE CC_REGNUM)
943 (reg:CCFPE VFPCC_REGNUM))]
947 (define_insn_and_split "*cmpdf_split_vfp"
948 [(set (reg:CCFP CC_REGNUM)
949 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w")
950 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
951 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
953 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
954 [(set (reg:CCFP VFPCC_REGNUM)
955 (compare:CCFP (match_dup 0)
957 (set (reg:CCFP CC_REGNUM)
958 (reg:CCFPE VFPCC_REGNUM))]
962 (define_insn_and_split "*cmpdf_trap_split_vfp"
963 [(set (reg:CCFPE CC_REGNUM)
964 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w")
965 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
966 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
968 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
969 [(set (reg:CCFPE VFPCC_REGNUM)
970 (compare:CCFPE (match_dup 0)
972 (set (reg:CCFPE CC_REGNUM)
973 (reg:CCFPE VFPCC_REGNUM))]
978 ;; Comparison patterns
980 (define_insn "*cmpsf_vfp"
981 [(set (reg:CCFP VFPCC_REGNUM)
982 (compare:CCFP (match_operand:SF 0 "s_register_operand" "t,t")
983 (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
984 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
988 [(set_attr "predicable" "yes")
989 (set_attr "type" "ffarith")]
992 (define_insn "*cmpsf_trap_vfp"
993 [(set (reg:CCFPE VFPCC_REGNUM)
994 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t,t")
995 (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
996 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1000 [(set_attr "predicable" "yes")
1001 (set_attr "type" "ffarith")]
1004 (define_insn "*cmpdf_vfp"
1005 [(set (reg:CCFP VFPCC_REGNUM)
1006 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w")
1007 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1008 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1012 [(set_attr "predicable" "yes")
1013 (set_attr "type" "ffarith")]
1016 (define_insn "*cmpdf_trap_vfp"
1017 [(set (reg:CCFPE VFPCC_REGNUM)
1018 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w")
1019 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1020 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1024 [(set_attr "predicable" "yes")
1025 (set_attr "type" "ffarith")]
1029 ;; Store multiple insn used in function prologue.
1031 (define_insn "*push_multi_vfp"
1032 [(match_parallel 2 "multi_register_push"
1033 [(set (match_operand:BLK 0 "memory_operand" "=m")
1034 (unspec:BLK [(match_operand:DF 1 "s_register_operand" "w")]
1035 UNSPEC_PUSH_MULT))])]
1036 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1037 "* return vfp_output_fstmd (operands);"
1038 [(set_attr "type" "f_stored")]
1042 ;; Unimplemented insns:
1045 ;; fmdhr et al (VFPv1)
1046 ;; Support for xD (single precision only) variants.