]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/arm/vfp.md
vfp.md (arm_movsi_vfp, [...]): Set attribute "insn".
[thirdparty/gcc.git] / gcc / config / arm / vfp.md
1 ;; ARM VFP instruction patterns
2 ;; Copyright (C) 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
3 ;; Written by CodeSourcery.
4 ;;
5 ;; This file is part of GCC.
6 ;;
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)
10 ;; any later version.
11 ;;
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.
16 ;;
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/>. */
20
21 ;; Additional register numbers
22 (define_constants
23 [(VFPCC_REGNUM 127)]
24 )
25
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
48
49 ;; SImode moves
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))"
58 "*
59 switch (which_alternative)
60 {
61 case 0: case 1:
62 return \"mov%?\\t%0, %1\";
63 case 2:
64 return \"mvn%?\\t%0, #%B1\";
65 case 3:
66 return \"movw%?\\t%0, %1\";
67 case 4:
68 return \"ldr%?\\t%0, %1\";
69 case 5:
70 return \"str%?\\t%1, %0\";
71 case 6:
72 return \"fmsr%?\\t%0, %1\\t%@ int\";
73 case 7:
74 return \"fmrs%?\\t%0, %1\\t%@ int\";
75 case 8:
76 return \"fcpys%?\\t%0, %1\\t%@ int\";
77 case 9: case 10:
78 return output_move_vfp (operands);
79 default:
80 gcc_unreachable ();
81 }
82 "
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 "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*")
86 (set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*")
87 (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")]
88 )
89
90 ;; See thumb2.md:thumb2_movsi_insn for an explanation of the split
91 ;; high/low register alternatives for loads and stores here.
92 (define_insn "*thumb2_movsi_vfp"
93 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r, l,*hk,m, *m,*t, r,*t,*t, *Uv")
94 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,*mi,l,*hk, r,*t,*t,*Uvi,*t"))]
95 "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT
96 && ( s_register_operand (operands[0], SImode)
97 || s_register_operand (operands[1], SImode))"
98 "*
99 switch (which_alternative)
100 {
101 case 0: case 1:
102 return \"mov%?\\t%0, %1\";
103 case 2:
104 return \"mvn%?\\t%0, #%B1\";
105 case 3:
106 return \"movw%?\\t%0, %1\";
107 case 4:
108 case 5:
109 return \"ldr%?\\t%0, %1\";
110 case 6:
111 case 7:
112 return \"str%?\\t%1, %0\";
113 case 8:
114 return \"fmsr%?\\t%0, %1\\t%@ int\";
115 case 9:
116 return \"fmrs%?\\t%0, %1\\t%@ int\";
117 case 10:
118 return \"fcpys%?\\t%0, %1\\t%@ int\";
119 case 11: case 12:
120 return output_move_vfp (operands);
121 default:
122 gcc_unreachable ();
123 }
124 "
125 [(set_attr "predicable" "yes")
126 (set_attr "type" "*,*,*,*,load1,load1,store1,store1,r_2_f,f_2_r,fcpys,f_load,f_store")
127 (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*,*,*")
128 (set_attr "pool_range" "*,*,*,*,1020,4096,*,*,*,*,*,1020,*")
129 (set_attr "neg_pool_range" "*,*,*,*, 0, 0,*,*,*,*,*,1008,*")]
130 )
131
132
133 ;; DImode moves
134
135 (define_insn "*arm_movdi_vfp"
136 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
137 (match_operand:DI 1 "di_operand" "rIK,mi,r,r,w,w,Uvi,w"))]
138 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
139 && ( register_operand (operands[0], DImode)
140 || register_operand (operands[1], DImode))"
141 "*
142 switch (which_alternative)
143 {
144 case 0:
145 return \"#\";
146 case 1:
147 case 2:
148 return output_move_double (operands);
149 case 3:
150 return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
151 case 4:
152 return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
153 case 5:
154 if (TARGET_VFP_SINGLE)
155 return \"fcpys%?\\t%0, %1\\t%@ int\;fcpys%?\\t%p0, %p1\\t%@ int\";
156 else
157 return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
158 case 6: case 7:
159 return output_move_vfp (operands);
160 default:
161 gcc_unreachable ();
162 }
163 "
164 [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
165 (set (attr "length") (cond [(eq_attr "alternative" "0,1,2") (const_int 8)
166 (eq_attr "alternative" "5")
167 (if_then_else
168 (eq (symbol_ref "TARGET_VFP_SINGLE")
169 (const_int 1))
170 (const_int 8)
171 (const_int 4))]
172 (const_int 4)))
173 (set_attr "predicable" "yes")
174 (set_attr "pool_range" "*,1020,*,*,*,*,1020,*")
175 (set_attr "neg_pool_range" "*,1008,*,*,*,*,1008,*")]
176 )
177
178 (define_insn "*thumb2_movdi_vfp"
179 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
180 (match_operand:DI 1 "di_operand" "rIK,mi,r,r,w,w,Uvi,w"))]
181 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
182 "*
183 switch (which_alternative)
184 {
185 case 0: case 1: case 2:
186 return (output_move_double (operands));
187 case 3:
188 return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
189 case 4:
190 return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
191 case 5:
192 if (TARGET_VFP_SINGLE)
193 return \"fcpys%?\\t%0, %1\\t%@ int\;fcpys%?\\t%p0, %p1\\t%@ int\";
194 else
195 return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
196 case 6: case 7:
197 return output_move_vfp (operands);
198 default:
199 abort ();
200 }
201 "
202 [(set_attr "type" "*,load2,store2,r_2_f,f_2_r,ffarithd,f_load,f_store")
203 (set (attr "length") (cond [(eq_attr "alternative" "0,1,2") (const_int 8)
204 (eq_attr "alternative" "5")
205 (if_then_else
206 (eq (symbol_ref "TARGET_VFP_SINGLE")
207 (const_int 1))
208 (const_int 8)
209 (const_int 4))]
210 (const_int 4)))
211 (set_attr "pool_range" "*,4096,*,*,*,*,1020,*")
212 (set_attr "neg_pool_range" "*, 0,*,*,*,*,1008,*")]
213 )
214
215 ;; HFmode moves
216 (define_insn "*movhf_vfp_neon"
217 [(set (match_operand:HF 0 "nonimmediate_operand" "= t,Um,r,m,t,r,t,r,r")
218 (match_operand:HF 1 "general_operand" " Um, t,m,r,t,r,r,t,F"))]
219 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_NEON_FP16
220 && ( s_register_operand (operands[0], HFmode)
221 || s_register_operand (operands[1], HFmode))"
222 "*
223 switch (which_alternative)
224 {
225 case 0: /* S register from memory */
226 return \"vld1.16\\t{%z0}, %A1\";
227 case 1: /* memory from S register */
228 return \"vst1.16\\t{%z1}, %A0\";
229 case 2: /* ARM register from memory */
230 return \"ldrh\\t%0, %1\\t%@ __fp16\";
231 case 3: /* memory from ARM register */
232 return \"strh\\t%1, %0\\t%@ __fp16\";
233 case 4: /* S register from S register */
234 return \"fcpys\\t%0, %1\";
235 case 5: /* ARM register from ARM register */
236 return \"mov\\t%0, %1\\t%@ __fp16\";
237 case 6: /* S register from ARM register */
238 return \"fmsr\\t%0, %1\";
239 case 7: /* ARM register from S register */
240 return \"fmrs\\t%0, %1\";
241 case 8: /* ARM register from constant */
242 {
243 REAL_VALUE_TYPE r;
244 long bits;
245 rtx ops[4];
246
247 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
248 bits = real_to_target (NULL, &r, HFmode);
249 ops[0] = operands[0];
250 ops[1] = GEN_INT (bits);
251 ops[2] = GEN_INT (bits & 0xff00);
252 ops[3] = GEN_INT (bits & 0x00ff);
253
254 if (arm_arch_thumb2)
255 output_asm_insn (\"movw\\t%0, %1\", ops);
256 else
257 output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops);
258 return \"\";
259 }
260 default:
261 gcc_unreachable ();
262 }
263 "
264 [(set_attr "conds" "unconditional")
265 (set_attr "type" "*,*,load1,store1,fcpys,*,r_2_f,f_2_r,*")
266 (set_attr "neon_type" "neon_vld1_1_2_regs,neon_vst1_1_2_regs_vst2_2_regs,*,*,*,*,*,*,*")
267 (set_attr "length" "4,4,4,4,4,4,4,4,8")]
268 )
269
270 ;; FP16 without element load/store instructions.
271 (define_insn "*movhf_vfp"
272 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,t,r,t,r,r")
273 (match_operand:HF 1 "general_operand" " m,r,t,r,r,t,F"))]
274 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16 && !TARGET_NEON_FP16
275 && ( s_register_operand (operands[0], HFmode)
276 || s_register_operand (operands[1], HFmode))"
277 "*
278 switch (which_alternative)
279 {
280 case 0: /* ARM register from memory */
281 return \"ldrh\\t%0, %1\\t%@ __fp16\";
282 case 1: /* memory from ARM register */
283 return \"strh\\t%1, %0\\t%@ __fp16\";
284 case 2: /* S register from S register */
285 return \"fcpys\\t%0, %1\";
286 case 3: /* ARM register from ARM register */
287 return \"mov\\t%0, %1\\t%@ __fp16\";
288 case 4: /* S register from ARM register */
289 return \"fmsr\\t%0, %1\";
290 case 5: /* ARM register from S register */
291 return \"fmrs\\t%0, %1\";
292 case 6: /* ARM register from constant */
293 {
294 REAL_VALUE_TYPE r;
295 long bits;
296 rtx ops[4];
297
298 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
299 bits = real_to_target (NULL, &r, HFmode);
300 ops[0] = operands[0];
301 ops[1] = GEN_INT (bits);
302 ops[2] = GEN_INT (bits & 0xff00);
303 ops[3] = GEN_INT (bits & 0x00ff);
304
305 if (arm_arch_thumb2)
306 output_asm_insn (\"movw\\t%0, %1\", ops);
307 else
308 output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops);
309 return \"\";
310 }
311 default:
312 gcc_unreachable ();
313 }
314 "
315 [(set_attr "conds" "unconditional")
316 (set_attr "type" "load1,store1,fcpys,*,r_2_f,f_2_r,*")
317 (set_attr "length" "4,4,4,4,4,4,8")]
318 )
319
320
321 ;; SFmode moves
322 ;; Disparage the w<->r cases because reloading an invalid address is
323 ;; preferable to loading the value via integer registers.
324
325 (define_insn "*movsf_vfp"
326 [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t ,t ,Uv,r ,m,t,r")
327 (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))]
328 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
329 && ( s_register_operand (operands[0], SFmode)
330 || s_register_operand (operands[1], SFmode))"
331 "*
332 switch (which_alternative)
333 {
334 case 0:
335 return \"fmsr%?\\t%0, %1\";
336 case 1:
337 return \"fmrs%?\\t%0, %1\";
338 case 2:
339 return \"fconsts%?\\t%0, #%G1\";
340 case 3: case 4:
341 return output_move_vfp (operands);
342 case 5:
343 return \"ldr%?\\t%0, %1\\t%@ float\";
344 case 6:
345 return \"str%?\\t%1, %0\\t%@ float\";
346 case 7:
347 return \"fcpys%?\\t%0, %1\";
348 case 8:
349 return \"mov%?\\t%0, %1\\t%@ float\";
350 default:
351 gcc_unreachable ();
352 }
353 "
354 [(set_attr "predicable" "yes")
355 (set_attr "type"
356 "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,*")
357 (set_attr "insn" "*,*,*,*,*,*,*,*,mov")
358 (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*")
359 (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")]
360 )
361
362 (define_insn "*thumb2_movsf_vfp"
363 [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t, t ,Uv,r ,m,t,r")
364 (match_operand:SF 1 "general_operand" " ?r,t,Dv,UvE,t, mE,r,t,r"))]
365 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP
366 && ( s_register_operand (operands[0], SFmode)
367 || s_register_operand (operands[1], SFmode))"
368 "*
369 switch (which_alternative)
370 {
371 case 0:
372 return \"fmsr%?\\t%0, %1\";
373 case 1:
374 return \"fmrs%?\\t%0, %1\";
375 case 2:
376 return \"fconsts%?\\t%0, #%G1\";
377 case 3: case 4:
378 return output_move_vfp (operands);
379 case 5:
380 return \"ldr%?\\t%0, %1\\t%@ float\";
381 case 6:
382 return \"str%?\\t%1, %0\\t%@ float\";
383 case 7:
384 return \"fcpys%?\\t%0, %1\";
385 case 8:
386 return \"mov%?\\t%0, %1\\t%@ float\";
387 default:
388 gcc_unreachable ();
389 }
390 "
391 [(set_attr "predicable" "yes")
392 (set_attr "type"
393 "r_2_f,f_2_r,fconsts,f_load,f_store,load1,store1,fcpys,*")
394 (set_attr "insn" "*,*,*,*,*,*,*,*,mov")
395 (set_attr "pool_range" "*,*,*,1020,*,4092,*,*,*")
396 (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")]
397 )
398
399
400 ;; DFmode moves
401
402 (define_insn "*movdf_vfp"
403 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w ,Uv,w,r")
404 (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,mF,r,UvF,w, w,r"))]
405 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
406 && ( register_operand (operands[0], DFmode)
407 || register_operand (operands[1], DFmode))"
408 "*
409 {
410 switch (which_alternative)
411 {
412 case 0:
413 return \"fmdrr%?\\t%P0, %Q1, %R1\";
414 case 1:
415 return \"fmrrd%?\\t%Q0, %R0, %P1\";
416 case 2:
417 gcc_assert (TARGET_VFP_DOUBLE);
418 return \"fconstd%?\\t%P0, #%G1\";
419 case 3: case 4:
420 return output_move_double (operands);
421 case 5: case 6:
422 return output_move_vfp (operands);
423 case 7:
424 if (TARGET_VFP_SINGLE)
425 return \"fcpys%?\\t%0, %1\;fcpys%?\\t%p0, %p1\";
426 else
427 return \"fcpyd%?\\t%P0, %P1\";
428 case 8:
429 return \"#\";
430 default:
431 gcc_unreachable ();
432 }
433 }
434 "
435 [(set_attr "type"
436 "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*")
437 (set (attr "length") (cond [(eq_attr "alternative" "3,4,8") (const_int 8)
438 (eq_attr "alternative" "7")
439 (if_then_else
440 (eq (symbol_ref "TARGET_VFP_SINGLE")
441 (const_int 1))
442 (const_int 8)
443 (const_int 4))]
444 (const_int 4)))
445 (set_attr "predicable" "yes")
446 (set_attr "pool_range" "*,*,*,1020,*,1020,*,*,*")
447 (set_attr "neg_pool_range" "*,*,*,1008,*,1008,*,*,*")]
448 )
449
450 (define_insn "*thumb2_movdf_vfp"
451 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,r, m,w ,Uv,w,r")
452 (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,mF,r,UvF,w, w,r"))]
453 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
454 "*
455 {
456 switch (which_alternative)
457 {
458 case 0:
459 return \"fmdrr%?\\t%P0, %Q1, %R1\";
460 case 1:
461 return \"fmrrd%?\\t%Q0, %R0, %P1\";
462 case 2:
463 gcc_assert (TARGET_VFP_DOUBLE);
464 return \"fconstd%?\\t%P0, #%G1\";
465 case 3: case 4: case 8:
466 return output_move_double (operands);
467 case 5: case 6:
468 return output_move_vfp (operands);
469 case 7:
470 if (TARGET_VFP_SINGLE)
471 return \"fcpys%?\\t%0, %1\;fcpys%?\\t%p0, %p1\";
472 else
473 return \"fcpyd%?\\t%P0, %P1\";
474 default:
475 abort ();
476 }
477 }
478 "
479 [(set_attr "type"
480 "r_2_f,f_2_r,fconstd,load2,store2,f_load,f_store,ffarithd,*")
481 (set (attr "length") (cond [(eq_attr "alternative" "3,4,8") (const_int 8)
482 (eq_attr "alternative" "7")
483 (if_then_else
484 (eq (symbol_ref "TARGET_VFP_SINGLE")
485 (const_int 1))
486 (const_int 8)
487 (const_int 4))]
488 (const_int 4)))
489 (set_attr "pool_range" "*,*,*,4096,*,1020,*,*,*")
490 (set_attr "neg_pool_range" "*,*,*,0,*,1008,*,*,*")]
491 )
492
493
494 ;; Conditional move patterns
495
496 (define_insn "*movsfcc_vfp"
497 [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
498 (if_then_else:SF
499 (match_operator 3 "arm_comparison_operator"
500 [(match_operand 4 "cc_register" "") (const_int 0)])
501 (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
502 (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
503 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
504 "@
505 fcpys%D3\\t%0, %2
506 fcpys%d3\\t%0, %1
507 fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
508 fmsr%D3\\t%0, %2
509 fmsr%d3\\t%0, %1
510 fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
511 fmrs%D3\\t%0, %2
512 fmrs%d3\\t%0, %1
513 fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
514 [(set_attr "conds" "use")
515 (set_attr "length" "4,4,8,4,4,8,4,4,8")
516 (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
517 )
518
519 (define_insn "*thumb2_movsfcc_vfp"
520 [(set (match_operand:SF 0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
521 (if_then_else:SF
522 (match_operator 3 "arm_comparison_operator"
523 [(match_operand 4 "cc_register" "") (const_int 0)])
524 (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
525 (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
526 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
527 "@
528 it\\t%D3\;fcpys%D3\\t%0, %2
529 it\\t%d3\;fcpys%d3\\t%0, %1
530 ite\\t%D3\;fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
531 it\\t%D3\;fmsr%D3\\t%0, %2
532 it\\t%d3\;fmsr%d3\\t%0, %1
533 ite\\t%D3\;fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
534 it\\t%D3\;fmrs%D3\\t%0, %2
535 it\\t%d3\;fmrs%d3\\t%0, %1
536 ite\\t%D3\;fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
537 [(set_attr "conds" "use")
538 (set_attr "length" "6,6,10,6,6,10,6,6,10")
539 (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
540 )
541
542 (define_insn "*movdfcc_vfp"
543 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
544 (if_then_else:DF
545 (match_operator 3 "arm_comparison_operator"
546 [(match_operand 4 "cc_register" "") (const_int 0)])
547 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
548 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
549 "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
550 "@
551 fcpyd%D3\\t%P0, %P2
552 fcpyd%d3\\t%P0, %P1
553 fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
554 fmdrr%D3\\t%P0, %Q2, %R2
555 fmdrr%d3\\t%P0, %Q1, %R1
556 fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
557 fmrrd%D3\\t%Q0, %R0, %P2
558 fmrrd%d3\\t%Q0, %R0, %P1
559 fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
560 [(set_attr "conds" "use")
561 (set_attr "length" "4,4,8,4,4,8,4,4,8")
562 (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
563 )
564
565 (define_insn "*thumb2_movdfcc_vfp"
566 [(set (match_operand:DF 0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
567 (if_then_else:DF
568 (match_operator 3 "arm_comparison_operator"
569 [(match_operand 4 "cc_register" "") (const_int 0)])
570 (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
571 (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
572 "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
573 "@
574 it\\t%D3\;fcpyd%D3\\t%P0, %P2
575 it\\t%d3\;fcpyd%d3\\t%P0, %P1
576 ite\\t%D3\;fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
577 it\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2
578 it\t%d3\;fmdrr%d3\\t%P0, %Q1, %R1
579 ite\\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
580 it\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2
581 it\t%d3\;fmrrd%d3\\t%Q0, %R0, %P1
582 ite\\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
583 [(set_attr "conds" "use")
584 (set_attr "length" "6,6,10,6,6,10,6,6,10")
585 (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")]
586 )
587
588
589 ;; Sign manipulation functions
590
591 (define_insn "*abssf2_vfp"
592 [(set (match_operand:SF 0 "s_register_operand" "=t")
593 (abs:SF (match_operand:SF 1 "s_register_operand" "t")))]
594 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
595 "fabss%?\\t%0, %1"
596 [(set_attr "predicable" "yes")
597 (set_attr "type" "ffariths")]
598 )
599
600 (define_insn "*absdf2_vfp"
601 [(set (match_operand:DF 0 "s_register_operand" "=w")
602 (abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
603 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
604 "fabsd%?\\t%P0, %P1"
605 [(set_attr "predicable" "yes")
606 (set_attr "type" "ffarithd")]
607 )
608
609 (define_insn "*negsf2_vfp"
610 [(set (match_operand:SF 0 "s_register_operand" "=t,?r")
611 (neg:SF (match_operand:SF 1 "s_register_operand" "t,r")))]
612 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
613 "@
614 fnegs%?\\t%0, %1
615 eor%?\\t%0, %1, #-2147483648"
616 [(set_attr "predicable" "yes")
617 (set_attr "type" "ffariths")]
618 )
619
620 (define_insn_and_split "*negdf2_vfp"
621 [(set (match_operand:DF 0 "s_register_operand" "=w,?r,?r")
622 (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))]
623 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
624 "@
625 fnegd%?\\t%P0, %P1
626 #
627 #"
628 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE && reload_completed
629 && arm_general_register_operand (operands[0], DFmode)"
630 [(set (match_dup 0) (match_dup 1))]
631 "
632 if (REGNO (operands[0]) == REGNO (operands[1]))
633 {
634 operands[0] = gen_highpart (SImode, operands[0]);
635 operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000));
636 }
637 else
638 {
639 rtx in_hi, in_lo, out_hi, out_lo;
640
641 in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]),
642 GEN_INT (0x80000000));
643 in_lo = gen_lowpart (SImode, operands[1]);
644 out_hi = gen_highpart (SImode, operands[0]);
645 out_lo = gen_lowpart (SImode, operands[0]);
646
647 if (REGNO (in_lo) == REGNO (out_hi))
648 {
649 emit_insn (gen_rtx_SET (SImode, out_lo, in_lo));
650 operands[0] = out_hi;
651 operands[1] = in_hi;
652 }
653 else
654 {
655 emit_insn (gen_rtx_SET (SImode, out_hi, in_hi));
656 operands[0] = out_lo;
657 operands[1] = in_lo;
658 }
659 }
660 "
661 [(set_attr "predicable" "yes")
662 (set_attr "length" "4,4,8")
663 (set_attr "type" "ffarithd")]
664 )
665
666
667 ;; Arithmetic insns
668
669 (define_insn "*addsf3_vfp"
670 [(set (match_operand:SF 0 "s_register_operand" "=t")
671 (plus:SF (match_operand:SF 1 "s_register_operand" "t")
672 (match_operand:SF 2 "s_register_operand" "t")))]
673 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
674 "fadds%?\\t%0, %1, %2"
675 [(set_attr "predicable" "yes")
676 (set_attr "type" "fadds")]
677 )
678
679 (define_insn "*adddf3_vfp"
680 [(set (match_operand:DF 0 "s_register_operand" "=w")
681 (plus:DF (match_operand:DF 1 "s_register_operand" "w")
682 (match_operand:DF 2 "s_register_operand" "w")))]
683 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
684 "faddd%?\\t%P0, %P1, %P2"
685 [(set_attr "predicable" "yes")
686 (set_attr "type" "faddd")]
687 )
688
689
690 (define_insn "*subsf3_vfp"
691 [(set (match_operand:SF 0 "s_register_operand" "=t")
692 (minus:SF (match_operand:SF 1 "s_register_operand" "t")
693 (match_operand:SF 2 "s_register_operand" "t")))]
694 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
695 "fsubs%?\\t%0, %1, %2"
696 [(set_attr "predicable" "yes")
697 (set_attr "type" "fadds")]
698 )
699
700 (define_insn "*subdf3_vfp"
701 [(set (match_operand:DF 0 "s_register_operand" "=w")
702 (minus:DF (match_operand:DF 1 "s_register_operand" "w")
703 (match_operand:DF 2 "s_register_operand" "w")))]
704 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
705 "fsubd%?\\t%P0, %P1, %P2"
706 [(set_attr "predicable" "yes")
707 (set_attr "type" "faddd")]
708 )
709
710
711 ;; Division insns
712
713 (define_insn "*divsf3_vfp"
714 [(set (match_operand:SF 0 "s_register_operand" "+t")
715 (div:SF (match_operand:SF 1 "s_register_operand" "t")
716 (match_operand:SF 2 "s_register_operand" "t")))]
717 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
718 "fdivs%?\\t%0, %1, %2"
719 [(set_attr "predicable" "yes")
720 (set_attr "type" "fdivs")]
721 )
722
723 (define_insn "*divdf3_vfp"
724 [(set (match_operand:DF 0 "s_register_operand" "+w")
725 (div:DF (match_operand:DF 1 "s_register_operand" "w")
726 (match_operand:DF 2 "s_register_operand" "w")))]
727 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
728 "fdivd%?\\t%P0, %P1, %P2"
729 [(set_attr "predicable" "yes")
730 (set_attr "type" "fdivd")]
731 )
732
733
734 ;; Multiplication insns
735
736 (define_insn "*mulsf3_vfp"
737 [(set (match_operand:SF 0 "s_register_operand" "+t")
738 (mult:SF (match_operand:SF 1 "s_register_operand" "t")
739 (match_operand:SF 2 "s_register_operand" "t")))]
740 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
741 "fmuls%?\\t%0, %1, %2"
742 [(set_attr "predicable" "yes")
743 (set_attr "type" "fmuls")]
744 )
745
746 (define_insn "*muldf3_vfp"
747 [(set (match_operand:DF 0 "s_register_operand" "+w")
748 (mult:DF (match_operand:DF 1 "s_register_operand" "w")
749 (match_operand:DF 2 "s_register_operand" "w")))]
750 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
751 "fmuld%?\\t%P0, %P1, %P2"
752 [(set_attr "predicable" "yes")
753 (set_attr "type" "fmuld")]
754 )
755
756
757 (define_insn "*mulsf3negsf_vfp"
758 [(set (match_operand:SF 0 "s_register_operand" "+t")
759 (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "t"))
760 (match_operand:SF 2 "s_register_operand" "t")))]
761 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
762 "fnmuls%?\\t%0, %1, %2"
763 [(set_attr "predicable" "yes")
764 (set_attr "type" "fmuls")]
765 )
766
767 (define_insn "*muldf3negdf_vfp"
768 [(set (match_operand:DF 0 "s_register_operand" "+w")
769 (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
770 (match_operand:DF 2 "s_register_operand" "w")))]
771 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
772 "fnmuld%?\\t%P0, %P1, %P2"
773 [(set_attr "predicable" "yes")
774 (set_attr "type" "fmuld")]
775 )
776
777
778 ;; Multiply-accumulate insns
779
780 ;; 0 = 1 * 2 + 0
781 (define_insn "*mulsf3addsf_vfp"
782 [(set (match_operand:SF 0 "s_register_operand" "=t")
783 (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
784 (match_operand:SF 3 "s_register_operand" "t"))
785 (match_operand:SF 1 "s_register_operand" "0")))]
786 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
787 "fmacs%?\\t%0, %2, %3"
788 [(set_attr "predicable" "yes")
789 (set_attr "type" "fmacs")]
790 )
791
792 (define_insn "*muldf3adddf_vfp"
793 [(set (match_operand:DF 0 "s_register_operand" "=w")
794 (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
795 (match_operand:DF 3 "s_register_operand" "w"))
796 (match_operand:DF 1 "s_register_operand" "0")))]
797 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
798 "fmacd%?\\t%P0, %P2, %P3"
799 [(set_attr "predicable" "yes")
800 (set_attr "type" "fmacd")]
801 )
802
803 ;; 0 = 1 * 2 - 0
804 (define_insn "*mulsf3subsf_vfp"
805 [(set (match_operand:SF 0 "s_register_operand" "=t")
806 (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
807 (match_operand:SF 3 "s_register_operand" "t"))
808 (match_operand:SF 1 "s_register_operand" "0")))]
809 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
810 "fmscs%?\\t%0, %2, %3"
811 [(set_attr "predicable" "yes")
812 (set_attr "type" "fmacs")]
813 )
814
815 (define_insn "*muldf3subdf_vfp"
816 [(set (match_operand:DF 0 "s_register_operand" "=w")
817 (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
818 (match_operand:DF 3 "s_register_operand" "w"))
819 (match_operand:DF 1 "s_register_operand" "0")))]
820 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
821 "fmscd%?\\t%P0, %P2, %P3"
822 [(set_attr "predicable" "yes")
823 (set_attr "type" "fmacd")]
824 )
825
826 ;; 0 = -(1 * 2) + 0
827 (define_insn "*mulsf3negsfaddsf_vfp"
828 [(set (match_operand:SF 0 "s_register_operand" "=t")
829 (minus:SF (match_operand:SF 1 "s_register_operand" "0")
830 (mult:SF (match_operand:SF 2 "s_register_operand" "t")
831 (match_operand:SF 3 "s_register_operand" "t"))))]
832 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
833 "fnmacs%?\\t%0, %2, %3"
834 [(set_attr "predicable" "yes")
835 (set_attr "type" "fmacs")]
836 )
837
838 (define_insn "*fmuldf3negdfadddf_vfp"
839 [(set (match_operand:DF 0 "s_register_operand" "=w")
840 (minus:DF (match_operand:DF 1 "s_register_operand" "0")
841 (mult:DF (match_operand:DF 2 "s_register_operand" "w")
842 (match_operand:DF 3 "s_register_operand" "w"))))]
843 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
844 "fnmacd%?\\t%P0, %P2, %P3"
845 [(set_attr "predicable" "yes")
846 (set_attr "type" "fmacd")]
847 )
848
849
850 ;; 0 = -(1 * 2) - 0
851 (define_insn "*mulsf3negsfsubsf_vfp"
852 [(set (match_operand:SF 0 "s_register_operand" "=t")
853 (minus:SF (mult:SF
854 (neg:SF (match_operand:SF 2 "s_register_operand" "t"))
855 (match_operand:SF 3 "s_register_operand" "t"))
856 (match_operand:SF 1 "s_register_operand" "0")))]
857 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
858 "fnmscs%?\\t%0, %2, %3"
859 [(set_attr "predicable" "yes")
860 (set_attr "type" "fmacs")]
861 )
862
863 (define_insn "*muldf3negdfsubdf_vfp"
864 [(set (match_operand:DF 0 "s_register_operand" "=w")
865 (minus:DF (mult:DF
866 (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
867 (match_operand:DF 3 "s_register_operand" "w"))
868 (match_operand:DF 1 "s_register_operand" "0")))]
869 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
870 "fnmscd%?\\t%P0, %P2, %P3"
871 [(set_attr "predicable" "yes")
872 (set_attr "type" "fmacd")]
873 )
874
875
876 ;; Conversion routines
877
878 (define_insn "*extendsfdf2_vfp"
879 [(set (match_operand:DF 0 "s_register_operand" "=w")
880 (float_extend:DF (match_operand:SF 1 "s_register_operand" "t")))]
881 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
882 "fcvtds%?\\t%P0, %1"
883 [(set_attr "predicable" "yes")
884 (set_attr "type" "f_cvt")]
885 )
886
887 (define_insn "*truncdfsf2_vfp"
888 [(set (match_operand:SF 0 "s_register_operand" "=t")
889 (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
890 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
891 "fcvtsd%?\\t%0, %P1"
892 [(set_attr "predicable" "yes")
893 (set_attr "type" "f_cvt")]
894 )
895
896 (define_insn "extendhfsf2"
897 [(set (match_operand:SF 0 "s_register_operand" "=t")
898 (float_extend:SF (match_operand:HF 1 "s_register_operand" "t")))]
899 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16"
900 "vcvtb%?.f32.f16\\t%0, %1"
901 [(set_attr "predicable" "yes")
902 (set_attr "type" "f_cvt")]
903 )
904
905 (define_insn "truncsfhf2"
906 [(set (match_operand:HF 0 "s_register_operand" "=t")
907 (float_truncate:HF (match_operand:SF 1 "s_register_operand" "t")))]
908 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16"
909 "vcvtb%?.f16.f32\\t%0, %1"
910 [(set_attr "predicable" "yes")
911 (set_attr "type" "f_cvt")]
912 )
913
914 (define_insn "*truncsisf2_vfp"
915 [(set (match_operand:SI 0 "s_register_operand" "=t")
916 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
917 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
918 "ftosizs%?\\t%0, %1"
919 [(set_attr "predicable" "yes")
920 (set_attr "type" "f_cvt")]
921 )
922
923 (define_insn "*truncsidf2_vfp"
924 [(set (match_operand:SI 0 "s_register_operand" "=t")
925 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
926 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
927 "ftosizd%?\\t%0, %P1"
928 [(set_attr "predicable" "yes")
929 (set_attr "type" "f_cvt")]
930 )
931
932
933 (define_insn "fixuns_truncsfsi2"
934 [(set (match_operand:SI 0 "s_register_operand" "=t")
935 (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
936 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
937 "ftouizs%?\\t%0, %1"
938 [(set_attr "predicable" "yes")
939 (set_attr "type" "f_cvt")]
940 )
941
942 (define_insn "fixuns_truncdfsi2"
943 [(set (match_operand:SI 0 "s_register_operand" "=t")
944 (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "t"))))]
945 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
946 "ftouizd%?\\t%0, %P1"
947 [(set_attr "predicable" "yes")
948 (set_attr "type" "f_cvt")]
949 )
950
951
952 (define_insn "*floatsisf2_vfp"
953 [(set (match_operand:SF 0 "s_register_operand" "=t")
954 (float:SF (match_operand:SI 1 "s_register_operand" "t")))]
955 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
956 "fsitos%?\\t%0, %1"
957 [(set_attr "predicable" "yes")
958 (set_attr "type" "f_cvt")]
959 )
960
961 (define_insn "*floatsidf2_vfp"
962 [(set (match_operand:DF 0 "s_register_operand" "=w")
963 (float:DF (match_operand:SI 1 "s_register_operand" "t")))]
964 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
965 "fsitod%?\\t%P0, %1"
966 [(set_attr "predicable" "yes")
967 (set_attr "type" "f_cvt")]
968 )
969
970
971 (define_insn "floatunssisf2"
972 [(set (match_operand:SF 0 "s_register_operand" "=t")
973 (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "t")))]
974 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
975 "fuitos%?\\t%0, %1"
976 [(set_attr "predicable" "yes")
977 (set_attr "type" "f_cvt")]
978 )
979
980 (define_insn "floatunssidf2"
981 [(set (match_operand:DF 0 "s_register_operand" "=w")
982 (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "t")))]
983 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
984 "fuitod%?\\t%P0, %1"
985 [(set_attr "predicable" "yes")
986 (set_attr "type" "f_cvt")]
987 )
988
989
990 ;; Sqrt insns.
991
992 (define_insn "*sqrtsf2_vfp"
993 [(set (match_operand:SF 0 "s_register_operand" "=t")
994 (sqrt:SF (match_operand:SF 1 "s_register_operand" "t")))]
995 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
996 "fsqrts%?\\t%0, %1"
997 [(set_attr "predicable" "yes")
998 (set_attr "type" "fdivs")]
999 )
1000
1001 (define_insn "*sqrtdf2_vfp"
1002 [(set (match_operand:DF 0 "s_register_operand" "=w")
1003 (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))]
1004 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1005 "fsqrtd%?\\t%P0, %P1"
1006 [(set_attr "predicable" "yes")
1007 (set_attr "type" "fdivd")]
1008 )
1009
1010
1011 ;; Patterns to split/copy vfp condition flags.
1012
1013 (define_insn "*movcc_vfp"
1014 [(set (reg CC_REGNUM)
1015 (reg VFPCC_REGNUM))]
1016 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1017 "fmstat%?"
1018 [(set_attr "conds" "set")
1019 (set_attr "type" "f_flag")]
1020 )
1021
1022 (define_insn_and_split "*cmpsf_split_vfp"
1023 [(set (reg:CCFP CC_REGNUM)
1024 (compare:CCFP (match_operand:SF 0 "s_register_operand" "t")
1025 (match_operand:SF 1 "vfp_compare_operand" "tG")))]
1026 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1027 "#"
1028 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1029 [(set (reg:CCFP VFPCC_REGNUM)
1030 (compare:CCFP (match_dup 0)
1031 (match_dup 1)))
1032 (set (reg:CCFP CC_REGNUM)
1033 (reg:CCFP VFPCC_REGNUM))]
1034 ""
1035 )
1036
1037 (define_insn_and_split "*cmpsf_trap_split_vfp"
1038 [(set (reg:CCFPE CC_REGNUM)
1039 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t")
1040 (match_operand:SF 1 "vfp_compare_operand" "tG")))]
1041 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1042 "#"
1043 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1044 [(set (reg:CCFPE VFPCC_REGNUM)
1045 (compare:CCFPE (match_dup 0)
1046 (match_dup 1)))
1047 (set (reg:CCFPE CC_REGNUM)
1048 (reg:CCFPE VFPCC_REGNUM))]
1049 ""
1050 )
1051
1052 (define_insn_and_split "*cmpdf_split_vfp"
1053 [(set (reg:CCFP CC_REGNUM)
1054 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w")
1055 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
1056 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1057 "#"
1058 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1059 [(set (reg:CCFP VFPCC_REGNUM)
1060 (compare:CCFP (match_dup 0)
1061 (match_dup 1)))
1062 (set (reg:CCFP CC_REGNUM)
1063 (reg:CCFP VFPCC_REGNUM))]
1064 ""
1065 )
1066
1067 (define_insn_and_split "*cmpdf_trap_split_vfp"
1068 [(set (reg:CCFPE CC_REGNUM)
1069 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w")
1070 (match_operand:DF 1 "vfp_compare_operand" "wG")))]
1071 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1072 "#"
1073 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1074 [(set (reg:CCFPE VFPCC_REGNUM)
1075 (compare:CCFPE (match_dup 0)
1076 (match_dup 1)))
1077 (set (reg:CCFPE CC_REGNUM)
1078 (reg:CCFPE VFPCC_REGNUM))]
1079 ""
1080 )
1081
1082
1083 ;; Comparison patterns
1084
1085 (define_insn "*cmpsf_vfp"
1086 [(set (reg:CCFP VFPCC_REGNUM)
1087 (compare:CCFP (match_operand:SF 0 "s_register_operand" "t,t")
1088 (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
1089 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1090 "@
1091 fcmps%?\\t%0, %1
1092 fcmpzs%?\\t%0"
1093 [(set_attr "predicable" "yes")
1094 (set_attr "type" "fcmps")]
1095 )
1096
1097 (define_insn "*cmpsf_trap_vfp"
1098 [(set (reg:CCFPE VFPCC_REGNUM)
1099 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "t,t")
1100 (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
1101 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1102 "@
1103 fcmpes%?\\t%0, %1
1104 fcmpezs%?\\t%0"
1105 [(set_attr "predicable" "yes")
1106 (set_attr "type" "fcmpd")]
1107 )
1108
1109 (define_insn "*cmpdf_vfp"
1110 [(set (reg:CCFP VFPCC_REGNUM)
1111 (compare:CCFP (match_operand:DF 0 "s_register_operand" "w,w")
1112 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1113 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1114 "@
1115 fcmpd%?\\t%P0, %P1
1116 fcmpzd%?\\t%P0"
1117 [(set_attr "predicable" "yes")
1118 (set_attr "type" "fcmpd")]
1119 )
1120
1121 (define_insn "*cmpdf_trap_vfp"
1122 [(set (reg:CCFPE VFPCC_REGNUM)
1123 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "w,w")
1124 (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1125 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1126 "@
1127 fcmped%?\\t%P0, %P1
1128 fcmpezd%?\\t%P0"
1129 [(set_attr "predicable" "yes")
1130 (set_attr "type" "fcmpd")]
1131 )
1132
1133
1134 ;; Store multiple insn used in function prologue.
1135
1136 (define_insn "*push_multi_vfp"
1137 [(match_parallel 2 "multi_register_push"
1138 [(set (match_operand:BLK 0 "memory_operand" "=m")
1139 (unspec:BLK [(match_operand:DF 1 "vfp_register_operand" "")]
1140 UNSPEC_PUSH_MULT))])]
1141 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1142 "* return vfp_output_fstmd (operands);"
1143 [(set_attr "type" "f_stored")]
1144 )
1145
1146
1147 ;; Unimplemented insns:
1148 ;; fldm*
1149 ;; fstm*
1150 ;; fmdhr et al (VFPv1)
1151 ;; Support for xD (single precision only) variants.
1152 ;; fmrrs, fmsrr