OSDN Git Service

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