1 ;; ARM VFP instruction patterns
2 ;; Copyright (C) 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
3 ;; Written by CodeSourcery.
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 ;; The VFP "type" attributes differ from those used in the FPA model.
27 ;; fcpys Single precision cpy.
28 ;; ffariths Single precision abs, neg.
29 ;; ffarithd Double precision abs, neg, cpy.
30 ;; fadds Single precision add/sub.
31 ;; faddd Double precision add/sub.
32 ;; fconsts Single precision load immediate.
33 ;; fconstd Double precision load immediate.
34 ;; fcmps Single precision comparison.
35 ;; fcmpd Double precision comparison.
36 ;; fmuls Single precision multiply.
37 ;; fmuld Double precision multiply.
38 ;; fmacs Single precision multiply-accumulate.
39 ;; fmacd Double precision multiply-accumulate.
40 ;; fdivs Single precision sqrt or division.
41 ;; fdivd Double precision sqrt or division.
42 ;; f_flag fmstat operation
43 ;; f_load[sd] Floating point load from memory.
44 ;; f_store[sd] Floating point store to memory.
45 ;; f_2_r Transfer vfp to arm reg.
46 ;; r_2_f Transfer arm to vfp reg.
47 ;; f_cvt Convert floating<->integral
50 ;; ??? For now do not allow loading constants into vfp regs. This causes
51 ;; problems because small constants get converted into adds.
52 (define_insn "*arm_movsi_vfp"
53 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m ,*t,r,*t,*t, *Uv")
54 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk,r,*t,*t,*Uvi,*t"))]
55 "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
56 && ( s_register_operand (operands[0], SImode)
57 || s_register_operand (operands[1], SImode))"
59 switch (which_alternative)
62 return \"mov%?\\t%0, %1\";
64 return \"mvn%?\\t%0, #%B1\";
66 return \"movw%?\\t%0, %1\";
68 return \"ldr%?\\t%0, %1\";
70 return \"str%?\\t%1, %0\";
72 return \"fmsr%?\\t%0, %1\\t%@ int\";
74 return \"fmrs%?\\t%0, %1\\t%@ int\";
76 return \"fcpys%?\\t%0, %1\\t%@ int\";
78 return output_move_vfp (operands);
83 [(set_attr "predicable" "yes")
84 (set_attr "type" "*,*,*,*,load1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores")
85 (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*")
86 (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")]
89 (define_insn "*thumb2_movsi_vfp"
90 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m,*t,r, *t,*t, *Uv")
91 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk,r,*t,*t,*Uvi,*t"))]
92 "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT
93 && ( s_register_operand (operands[0], SImode)
94 || s_register_operand (operands[1], SImode))"
96 switch (which_alternative)
99 return \"mov%?\\t%0, %1\";
101 return \"mvn%?\\t%0, #%B1\";
103 return \"movw%?\\t%0, %1\";
105 return \"ldr%?\\t%0, %1\";
107 return \"str%?\\t%1, %0\";
109 return \"fmsr%?\\t%0, %1\\t%@ int\";
111 return \"fmrs%?\\t%0, %1\\t%@ int\";
113 return \"fcpys%?\\t%0, %1\\t%@ int\";
115 return output_move_vfp (operands);
120 [(set_attr "predicable" "yes")
121 (set_attr "type" "*,*,*,*,load1,store1,r_2_f,f_2_r,fcpys,f_load,f_store")
122 (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*")
123 (set_attr "neg_pool_range" "*,*,*,*, 0,*,*,*,*,1008,*")]
129 (define_insn "*arm_movdi_vfp"
130 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
131 (match_operand:DI 1 "di_operand" "rIK,mi,r,r,w,w,Uvi,w"))]
132 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
133 && ( register_operand (operands[0], DImode)
134 || register_operand (operands[1], DImode))"
136 switch (which_alternative)
142 return output_move_double (operands);
144 return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
146 return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
148 return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
150 return output_move_vfp (operands);
155 [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
156 (set_attr "length" "8,8,8,4,4,4,4,4")
157 (set_attr "predicable" "yes")
158 (set_attr "pool_range" "*,1020,*,*,*,*,1020,*")
159 (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
162 (define_insn "*thumb2_movdi_vfp"
163 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
164 (match_operand:DI 1 "di_operand" "rIK,mi,r,r,w,w,Uvi,w"))]
165 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
167 switch (which_alternative)
169 case 0: case 1: case 2:
170 return (output_move_double (operands));
172 return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
174 return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
176 return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
178 return output_move_vfp (operands);
183 [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarithd,f_load,f_store")
184 (set_attr "length" "8,8,8,4,4,4,4,4")
185 (set_attr "pool_range" "*,4096,*,*,*,*,1020,*")
186 (set_attr "neg_pool_range" "*, 0,*,*,*,*,1008,*")]
190 (define_insn "*movhf_vfp"
191 [(set (match_operand:HF 0 "nonimmediate_operand" "= t,Um,r,m,t,r,t,r,r")
192 (match_operand:HF 1 "general_operand" " Um, t,m,r,t,r,r,t,F"))]
193 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_NEON_FP16
194 && ( s_register_operand (operands[0], HFmode)
195 || s_register_operand (operands[1], HFmode))"
197 switch (which_alternative)
199 case 0: /* S register from memory */
200 return \"vld1.16\\t{%z0}, %A1\";
201 case 1: /* memory from S register */
202 return \"vst1.16\\t{%z1}, %A0\";
203 case 2: /* ARM register from memory */
204 return \"ldrh\\t%0, %1\\t%@ __fp16\";
205 case 3: /* memory from ARM register */
206 return \"strh\\t%1, %0\\t%@ __fp16\";
207 case 4: /* S register from S register */
208 return \"fcpys\\t%0, %1\";
209 case 5: /* ARM register from ARM register */
210 return \"mov\\t%0, %1\\t%@ __fp16\";
211 case 6: /* S register from ARM register */
212 return \"fmsr\\t%0, %1\";
213 case 7: /* ARM register from S register */
214 return \"fmrs\\t%0, %1\";
215 case 8: /* ARM register from constant */
221 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
222 bits = real_to_target (NULL, &r, HFmode);
223 ops[0] = operands[0];
224 ops[1] = GEN_INT (bits);
225 ops[2] = GEN_INT (bits & 0xff00);
226 ops[3] = GEN_INT (bits & 0x00ff);
229 output_asm_insn (\"movw\\t%0, %1\", ops);
231 output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops);
238 [(set_attr "conds" "unconditional")
239 (set_attr "type" "*,*,load1,store1,fcpys,*,r_2_f,f_2_r,*")
240 (set_attr "neon_type" "neon_vld1_1_2_regs,neon_vst1_1_2_regs_vst2_2_regs,*,*,*,*,*,*,*")
241 (set_attr "length" "4,4,4,4,4,4,4,4,8")]
246 ;; Disparage the w<->r cases because reloading an invalid address is
247 ;; preferable to loading the value via integer registers.
249 (define_insn "*movsf_vfp"
250 [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t ,t ,Uv,r ,m,t,r")
251 (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))]
252 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
253 && ( s_register_operand (operands[0], SFmode)
254 || s_register_operand (operands[1], SFmode))"
256 switch (which_alternative)
259 return \"fmsr%?\\t%0, %1\";
261 return \"fmrs%?\\t%0, %1\";
263 return \"fconsts%?\\t%0, #%G1\";
265 return output_move_vfp (operands);
267 return \"ldr%?\\t%0, %1\\t%@ float\";
269 return \"str%?\\t%1, %0\\t%@ float\";
271 return \"fcpys%?\\t%0, %1\";
273 return \"mov%?\\t%0, %1\\t%@ float\";
278 [(set_attr "predicable" "yes")
280 "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,*")
281 (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*")
282 (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")]
285 (define_insn "*thumb2_movsf_vfp"
286 [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t, t ,Uv,r ,m,t,r")
287 (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))]
288 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP
289 && ( s_register_operand (operands[0], SFmode)
290 || s_register_operand (operands[1], SFmode))"
292 switch (which_alternative)
295 return \"fmsr%?\\t%0, %1\";
297 return \"fmrs%?\\t%0, %1\";
299 return \"fconsts%?\\t%0, #%G1\";
301 return output_move_vfp (operands);
303 return \"ldr%?\\t%0, %1\\t%@ float\";
305 return \"str%?\\t%1, %0\\t%@ float\";
307 return \"fcpys%?\\t%0, %1\";
309 return \"mov%?\\t%0, %1\\t%@ float\";
314 [(set_attr "predicable" "yes")
316 "r_2_f,f_2_r,fconsts,f_load,f_store,load1,store1,fcpys,*")
317 (set_attr "pool_range" "*,*,*,1020,*,4092,*,*,*")
318 (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")]
324 (define_insn "*movdf_vfp"
325 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w ,Uv,w,r")
326 (match_operand:DF 1 "soft_df_operand" " ?r,w,Dv,mF,r,UvF,w, w,r"))]
327 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
328 && ( register_operand (operands[0], DFmode)
329 || register_operand (operands[1], DFmode))"
332 switch (which_alternative)
335 return \"fmdrr%?\\t%P0, %Q1, %R1\";
337 return \"fmrrd%?\\t%Q0, %R0, %P1\";
339 return \"fconstd%?\\t%P0, #%G1\";
341 return output_move_double (operands);
343 return output_move_vfp (operands);
345 return \"fcpyd%?\\t%P0, %P1\";
354 "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*")
355 (set_attr "length" "4,4,4,8,8,4,4,4,8")
356 (set_attr "predicable" "yes")
357 (set_attr "pool_range" "*,*,*,1020,*,1020,*,*,*")
358 (set_attr "neg_pool_range" "*,*,*,1008,*,1008,*,*,*")]
361 (define_insn "*thumb2_movdf_vfp"
362 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w ,Uv,w,r")
363 (match_operand:DF 1 "soft_df_operand" " ?r,w,Dv,mF,r,UvF,w, w,r"))]
364 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
367 switch (which_alternative)
370 return \"fmdrr%?\\t%P0, %Q1, %R1\";
372 return \"fmrrd%?\\t%Q0, %R0, %P1\";
374 return \"fconstd%?\\t%P0, #%G1\";
375 case 3: case 4: case 8:
376 return output_move_double (operands);
378 return output_move_vfp (operands);
380 return \"fcpyd%?\\t%P0, %P1\";
387 "r_2_f,f_2_r,fconstd,load2,store2,f_load,f_store,ffarithd,*")
388 (set_attr "length" "4,4,4,8,8,4,4,4,8")
389 (set_attr "pool_range" "*,*,*,4096,*,1020,*,*,*")
390 (set_attr "neg_pool_range" "*,*,*,0,*,1008,*,*,*")]
394 ;; Conditional move patterns
396 (define_insn "*movsfcc_vfp"
397 [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
399 (match_operator 3 "arm_comparison_operator"
400 [(match_operand 4 "cc_register" "") (const_int 0)])
401 (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
402 (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
403 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
407 fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
410 fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
413 fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
414 [(set_attr "conds" "use")
415 (set_attr "length" "4,4,8,4,4,8,4,4,8")
416 (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
419 (define_insn "*thumb2_movsfcc_vfp"
420 [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
422 (match_operator 3 "arm_comparison_operator"
423 [(match_operand 4 "cc_register" "") (const_int 0)])
424 (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
425 (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
426 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
428 it\\t%D3\;fcpys%D3\\t%0, %2
429 it\\t%d3\;fcpys%d3\\t%0, %1
430 ite\\t%D3\;fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
431 it\\t%D3\;fmsr%D3\\t%0, %2
432 it\\t%d3\;fmsr%d3\\t%0, %1
433 ite\\t%D3\;fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
434 it\\t%D3\;fmrs%D3\\t%0, %2
435 it\\t%d3\;fmrs%d3\\t%0, %1
436 ite\\t%D3\;fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
437 [(set_attr "conds" "use")
438 (set_attr "length" "6,6,10,6,6,10,6,6,10")
439 (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
442 (define_insn "*movdfcc_vfp"
443 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
445 (match_operator 3 "arm_comparison_operator"
446 [(match_operand 4 "cc_register" "") (const_int 0)])
447 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
448 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
449 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
453 fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
454 fmdrr%D3\\t%P0, %Q2, %R2
455 fmdrr%d3\\t%P0, %Q1, %R1
456 fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
457 fmrrd%D3\\t%Q0, %R0, %P2
458 fmrrd%d3\\t%Q0, %R0, %P1
459 fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
460 [(set_attr "conds" "use")
461 (set_attr "length" "4,4,8,4,4,8,4,4,8")
462 (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
465 (define_insn "*thumb2_movdfcc_vfp"
466 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
468 (match_operator 3 "arm_comparison_operator"
469 [(match_operand 4 "cc_register" "") (const_int 0)])
470 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
471 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
472 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
474 it\\t%D3\;fcpyd%D3\\t%P0, %P2
475 it\\t%d3\;fcpyd%d3\\t%P0, %P1
476 ite\\t%D3\;fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
477 it\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2
478 it\t%d3\;fmdrr%d3\\t%P0, %Q1, %R1
479 ite\\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
480 it\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2
481 it\t%d3\;fmrrd%d3\\t%Q0, %R0, %P1
482 ite\\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
483 [(set_attr "conds" "use")
484 (set_attr "length" "6,6,10,6,6,10,6,6,10")
485 (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
489 ;; Sign manipulation functions
491 (define_insn "*abssf2_vfp"
492 [(set (match_operand:SF 0 "s_register_operand" "=t")
493 (abs:SF (match_operand:SF 1 "s_register_operand" "t")))]
494 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
496 [(set_attr "predicable" "yes")
497 (set_attr "type" "ffariths")]
500 (define_insn "*absdf2_vfp"
501 [(set (match_operand:DF 0 "s_register_operand" "=w")
502 (abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
503 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
505 [(set_attr "predicable" "yes")
506 (set_attr "type" "ffarithd")]
509 (define_insn "*negsf2_vfp"
510 [(set (match_operand:SF 0 "s_register_operand" "=t,?r")
511 (neg:SF (match_operand:SF 1 "s_register_operand" "t,r")))]
512 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
515 eor%?\\t%0, %1, #-2147483648"
516 [(set_attr "predicable" "yes")
517 (set_attr "type" "ffariths")]
520 (define_insn_and_split "*negdf2_vfp"
521 [(set (match_operand:DF 0 "s_register_operand" "=w,?r,?r")
522 (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))]
523 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
528 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && reload_completed
529 && arm_general_register_operand (operands[0], DFmode)"
530 [(set (match_dup 0) (match_dup 1))]
532 if (REGNO (operands[0]) == REGNO (operands[1]))
534 operands[0] = gen_highpart (SImode, operands[0]);
535 operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000));
539 rtx in_hi, in_lo, out_hi, out_lo;
541 in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]),
542 GEN_INT (0x80000000));
543 in_lo = gen_lowpart (SImode, operands[1]);
544 out_hi = gen_highpart (SImode, operands[0]);
545 out_lo = gen_lowpart (SImode, operands[0]);
547 if (REGNO (in_lo) == REGNO (out_hi))
549 emit_insn (gen_rtx_SET (SImode, out_lo, in_lo));
550 operands[0] = out_hi;
555 emit_insn (gen_rtx_SET (SImode, out_hi, in_hi));
556 operands[0] = out_lo;
561 [(set_attr "predicable" "yes")
562 (set_attr "length" "4,4,8")
563 (set_attr "type" "ffarithd")]
569 (define_insn "*addsf3_vfp"
570 [(set (match_operand:SF 0 "s_register_operand" "=t")
571 (plus:SF (match_operand:SF 1 "s_register_operand" "t")
572 (match_operand:SF 2 "s_register_operand" "t")))]
573 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
574 "fadds%?\\t%0, %1, %2"
575 [(set_attr "predicable" "yes")
576 (set_attr "type" "fadds")]
579 (define_insn "*adddf3_vfp"
580 [(set (match_operand:DF 0 "s_register_operand" "=w")
581 (plus:DF (match_operand:DF 1 "s_register_operand" "w")
582 (match_operand:DF 2 "s_register_operand" "w")))]
583 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
584 "faddd%?\\t%P0, %P1, %P2"
585 [(set_attr "predicable" "yes")
586 (set_attr "type" "faddd")]
590 (define_insn "*subsf3_vfp"
591 [(set (match_operand:SF 0 "s_register_operand" "=t")
592 (minus:SF (match_operand:SF 1 "s_register_operand" "t")
593 (match_operand:SF 2 "s_register_operand" "t")))]
594 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
595 "fsubs%?\\t%0, %1, %2"
596 [(set_attr "predicable" "yes")
597 (set_attr "type" "fadds")]
600 (define_insn "*subdf3_vfp"
601 [(set (match_operand:DF 0 "s_register_operand" "=w")
602 (minus:DF (match_operand:DF 1 "s_register_operand" "w")
603 (match_operand:DF 2 "s_register_operand" "w")))]
604 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
605 "fsubd%?\\t%P0, %P1, %P2"
606 [(set_attr "predicable" "yes")
607 (set_attr "type" "faddd")]
613 (define_insn "*divsf3_vfp"
614 [(set (match_operand:SF 0 "s_register_operand" "+t")
615 (div:SF (match_operand:SF 1 "s_register_operand" "t")
616 (match_operand:SF 2 "s_register_operand" "t")))]
617 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
618 "fdivs%?\\t%0, %1, %2"
619 [(set_attr "predicable" "yes")
620 (set_attr "type" "fdivs")]
623 (define_insn "*divdf3_vfp"
624 [(set (match_operand:DF 0 "s_register_operand" "+w")
625 (div:DF (match_operand:DF 1 "s_register_operand" "w")
626 (match_operand:DF 2 "s_register_operand" "w")))]
627 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
628 "fdivd%?\\t%P0, %P1, %P2"
629 [(set_attr "predicable" "yes")
630 (set_attr "type" "fdivd")]
634 ;; Multiplication insns
636 (define_insn "*mulsf3_vfp"
637 [(set (match_operand:SF 0 "s_register_operand" "+t")
638 (mult:SF (match_operand:SF 1 "s_register_operand" "t")
639 (match_operand:SF 2 "s_register_operand" "t")))]
640 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
641 "fmuls%?\\t%0, %1, %2"
642 [(set_attr "predicable" "yes")
643 (set_attr "type" "fmuls")]
646 (define_insn "*muldf3_vfp"
647 [(set (match_operand:DF 0 "s_register_operand" "+w")
648 (mult:DF (match_operand:DF 1 "s_register_operand" "w")
649 (match_operand:DF 2 "s_register_operand" "w")))]
650 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
651 "fmuld%?\\t%P0, %P1, %P2"
652 [(set_attr "predicable" "yes")
653 (set_attr "type" "fmuld")]
657 (define_insn "*mulsf3negsf_vfp"
658 [(set (match_operand:SF 0 "s_register_operand" "+t")
659 (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "t"))
660 (match_operand:SF 2 "s_register_operand" "t")))]
661 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
662 "fnmuls%?\\t%0, %1, %2"
663 [(set_attr "predicable" "yes")
664 (set_attr "type" "fmuls")]
667 (define_insn "*muldf3negdf_vfp"
668 [(set (match_operand:DF 0 "s_register_operand" "+w")
669 (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
670 (match_operand:DF 2 "s_register_operand" "w")))]
671 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
672 "fnmuld%?\\t%P0, %P1, %P2"
673 [(set_attr "predicable" "yes")
674 (set_attr "type" "fmuld")]
678 ;; Multiply-accumulate insns
681 (define_insn "*mulsf3addsf_vfp"
682 [(set (match_operand:SF 0 "s_register_operand" "=t")
683 (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
684 (match_operand:SF 3 "s_register_operand" "t"))
685 (match_operand:SF 1 "s_register_operand" "0")))]
686 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
687 "fmacs%?\\t%0, %2, %3"
688 [(set_attr "predicable" "yes")
689 (set_attr "type" "fmacs")]
692 (define_insn "*muldf3adddf_vfp"
693 [(set (match_operand:DF 0 "s_register_operand" "=w")
694 (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
695 (match_operand:DF 3 "s_register_operand" "w"))
696 (match_operand:DF 1 "s_register_operand" "0")))]
697 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
698 "fmacd%?\\t%P0, %P2, %P3"
699 [(set_attr "predicable" "yes")
700 (set_attr "type" "fmacd")]
704 (define_insn "*mulsf3subsf_vfp"
705 [(set (match_operand:SF 0 "s_register_operand" "=t")
706 (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
707 (match_operand:SF 3 "s_register_operand" "t"))
708 (match_operand:SF 1 "s_register_operand" "0")))]
709 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
710 "fmscs%?\\t%0, %2, %3"
711 [(set_attr "predicable" "yes")
712 (set_attr "type" "fmacs")]
715 (define_insn "*muldf3subdf_vfp"
716 [(set (match_operand:DF 0 "s_register_operand" "=w")
717 (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
718 (match_operand:DF 3 "s_register_operand" "w"))
719 (match_operand:DF 1 "s_register_operand" "0")))]
720 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
721 "fmscd%?\\t%P0, %P2, %P3"
722 [(set_attr "predicable" "yes")
723 (set_attr "type" "fmacd")]
727 (define_insn "*mulsf3negsfaddsf_vfp"
728 [(set (match_operand:SF 0 "s_register_operand" "=t")
729 (minus:SF (match_operand:SF 1 "s_register_operand" "0")
730 (mult:SF (match_operand:SF 2 "s_register_operand" "t")
731 (match_operand:SF 3 "s_register_operand" "t"))))]
732 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
733 "fnmacs%?\\t%0, %2, %3"
734 [(set_attr "predicable" "yes")
735 (set_attr "type" "fmacs")]
738 (define_insn "*fmuldf3negdfadddf_vfp"
739 [(set (match_operand:DF 0 "s_register_operand" "=w")
740 (minus:DF (match_operand:DF 1 "s_register_operand" "0")
741 (mult:DF (match_operand:DF 2 "s_register_operand" "w")
742 (match_operand:DF 3 "s_register_operand" "w"))))]
743 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
744 "fnmacd%?\\t%P0, %P2, %P3"
745 [(set_attr "predicable" "yes")
746 (set_attr "type" "fmacd")]
751 (define_insn "*mulsf3negsfsubsf_vfp"
752 [(set (match_operand:SF 0 "s_register_operand" "=t")
754 (neg:SF (match_operand:SF 2 "s_register_operand" "t"))
755 (match_operand:SF 3 "s_register_operand" "t"))
756 (match_operand:SF 1 "s_register_operand" "0")))]
757 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
758 "fnmscs%?\\t%0, %2, %3"
759 [(set_attr "predicable" "yes")
760 (set_attr "type" "fmacs")]
763 (define_insn "*muldf3negdfsubdf_vfp"
764 [(set (match_operand:DF 0 "s_register_operand" "=w")
766 (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
767 (match_operand:DF 3 "s_register_operand" "w"))
768 (match_operand:DF 1 "s_register_operand" "0")))]
769 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
770 "fnmscd%?\\t%P0, %P2, %P3"
771 [(set_attr "predicable" "yes")
772 (set_attr "type" "fmacd")]
776 ;; Conversion routines
778 (define_insn "*extendsfdf2_vfp"
779 [(set (match_operand:DF 0 "s_register_operand" "=w")
780 (float_extend:DF (match_operand:SF 1 "s_register_operand" "t")))]
781 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
783 [(set_attr "predicable" "yes")
784 (set_attr "type" "f_cvt")]
787 (define_insn "*truncdfsf2_vfp"
788 [(set (match_operand:SF 0 "s_register_operand" "=t")
789 (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
790 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
792 [(set_attr "predicable" "yes")
793 (set_attr "type" "f_cvt")]
796 (define_insn "extendhfsf2"
797 [(set (match_operand:SF 0 "s_register_operand" "=t")
798 (float_extend:SF (match_operand:HF 1 "s_register_operand" "t")))]
799 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_NEON_FP16"
800 "vcvtb%?.f32.f16\\t%0, %1"
801 [(set_attr "predicable" "yes")
802 (set_attr "type" "f_cvt")]
805 (define_insn "truncsfhf2"
806 [(set (match_operand:HF 0 "s_register_operand" "=t")
807 (float_truncate:HF (match_operand:SF 1 "s_register_operand" "t")))]
808 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_NEON_FP16"
809 "vcvtb%?.f16.f32\\t%0, %1"
810 [(set_attr "predicable" "yes")
811 (set_attr "type" "f_cvt")]
814 (define_insn "*truncsisf2_vfp"
815 [(set (match_operand:SI 0 "s_register_operand" "=t")
816 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
817 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
819 [(set_attr "predicable" "yes")
820 (set_attr "type" "f_cvt")]
823 (define_insn "*truncsidf2_vfp"
824 [(set (match_operand:SI 0 "s_register_operand" "=t")
825 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
826 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
827 "ftosizd%?\\t%0, %P1"
828 [(set_attr "predicable" "yes")
829 (set_attr "type" "f_cvt")]
833 (define_insn "fixuns_truncsfsi2"
834 [(set (match_operand:SI 0 "s_register_operand" "=t")
835 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
836 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
838 [(set_attr "predicable" "yes")
839 (set_attr "type" "f_cvt")]
842 (define_insn "fixuns_truncdfsi2"
843 [(set (match_operand:SI 0 "s_register_operand" "=t")
844 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "t"))))]
845 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
846 "ftouizd%?\\t%0, %P1"
847 [(set_attr "predicable" "yes")
848 (set_attr "type" "f_cvt")]
852 (define_insn "*floatsisf2_vfp"
853 [(set (match_operand:SF 0 "s_register_operand" "=t")
854 (float:SF (match_operand:SI 1 "s_register_operand" "t")))]
855 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
857 [(set_attr "predicable" "yes")
858 (set_attr "type" "f_cvt")]
861 (define_insn "*floatsidf2_vfp"
862 [(set (match_operand:DF 0 "s_register_operand" "=w")
863 (float:DF (match_operand:SI 1 "s_register_operand" "t")))]
864 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
866 [(set_attr "predicable" "yes")
867 (set_attr "type" "f_cvt")]
871 (define_insn "floatunssisf2"
872 [(set (match_operand:SF 0 "s_register_operand" "=t")
873 (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "t")))]
874 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
876 [(set_attr "predicable" "yes")
877 (set_attr "type" "f_cvt")]
880 (define_insn "floatunssidf2"
881 [(set (match_operand:DF 0 "s_register_operand" "=w")
882 (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "t")))]
883 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
885 [(set_attr "predicable" "yes")
886 (set_attr "type" "f_cvt")]
892 (define_insn "*sqrtsf2_vfp"
893 [(set (match_operand:SF 0 "s_register_operand" "=t")
894 (sqrt:SF (match_operand:SF 1 "s_register_operand" "t")))]
895 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
897 [(set_attr "predicable" "yes")
898 (set_attr "type" "fdivs")]
901 (define_insn "*sqrtdf2_vfp"
902 [(set (match_operand:DF 0 "s_register_operand" "=w")
903 (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))]
904 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
905 "fsqrtd%?\\t%P0, %P1"
906 [(set_attr "predicable" "yes")
907 (set_attr "type" "fdivd")]
911 ;; Patterns to split/copy vfp condition flags.
913 (define_insn "*movcc_vfp"
914 [(set (reg CC_REGNUM)
916 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
918 [(set_attr "conds" "set")
919 (set_attr "type" "f_flag")]
922 (define_insn_and_split "*cmpsf_split_vfp"
923 [(set (reg:CCFP CC_REGNUM)
924 (compare:CCFP (match_operand:SF 0 "s_register_operand" "t")
925 (match_operand:SF 1 "vfp_compare_operand" "tG")))]
926 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
928 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
929 [(set (reg:CCFP VFPCC_REGNUM)
930 (compare:CCFP (match_dup 0)
932 (set (reg:CCFP CC_REGNUM)
933 (reg:CCFP VFPCC_REGNUM))]
937 (define_insn_and_split "*cmpsf_trap_split_vfp"
938 [(set (reg:CCFPE CC_REGNUM)
939 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t")
940 (match_operand:SF 1 "vfp_compare_operand" "tG")))]
941 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
943 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
944 [(set (reg:CCFPE VFPCC_REGNUM)
945 (compare:CCFPE (match_dup 0)
947 (set (reg:CCFPE CC_REGNUM)
948 (reg:CCFPE VFPCC_REGNUM))]
952 (define_insn_and_split "*cmpdf_split_vfp"
953 [(set (reg:CCFP CC_REGNUM)
954 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w")
955 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
956 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
958 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
959 [(set (reg:CCFP VFPCC_REGNUM)
960 (compare:CCFP (match_dup 0)
962 (set (reg:CCFP CC_REGNUM)
963 (reg:CCFPE VFPCC_REGNUM))]
967 (define_insn_and_split "*cmpdf_trap_split_vfp"
968 [(set (reg:CCFPE CC_REGNUM)
969 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w")
970 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
971 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
973 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
974 [(set (reg:CCFPE VFPCC_REGNUM)
975 (compare:CCFPE (match_dup 0)
977 (set (reg:CCFPE CC_REGNUM)
978 (reg:CCFPE VFPCC_REGNUM))]
983 ;; Comparison patterns
985 (define_insn "*cmpsf_vfp"
986 [(set (reg:CCFP VFPCC_REGNUM)
987 (compare:CCFP (match_operand:SF 0 "s_register_operand" "t,t")
988 (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
989 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
993 [(set_attr "predicable" "yes")
994 (set_attr "type" "fcmps")]
997 (define_insn "*cmpsf_trap_vfp"
998 [(set (reg:CCFPE VFPCC_REGNUM)
999 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t,t")
1000 (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
1001 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1005 [(set_attr "predicable" "yes")
1006 (set_attr "type" "fcmpd")]
1009 (define_insn "*cmpdf_vfp"
1010 [(set (reg:CCFP VFPCC_REGNUM)
1011 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w")
1012 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1013 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1017 [(set_attr "predicable" "yes")
1018 (set_attr "type" "fcmpd")]
1021 (define_insn "*cmpdf_trap_vfp"
1022 [(set (reg:CCFPE VFPCC_REGNUM)
1023 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w")
1024 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1025 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1029 [(set_attr "predicable" "yes")
1030 (set_attr "type" "fcmpd")]
1034 ;; Store multiple insn used in function prologue.
1036 (define_insn "*push_multi_vfp"
1037 [(match_parallel 2 "multi_register_push"
1038 [(set (match_operand:BLK 0 "memory_operand" "=m")
1039 (unspec:BLK [(match_operand:DF 1 "s_register_operand" "w")]
1040 UNSPEC_PUSH_MULT))])]
1041 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1042 "* return vfp_output_fstmd (operands);"
1043 [(set_attr "type" "f_stored")]
1047 ;; Unimplemented insns:
1050 ;; fmdhr et al (VFPv1)
1051 ;; Support for xD (single precision only) variants.