remove unused files
[platform/upstream/gcc48.git] / gcc / config / arm / vfp.md
1 ;; ARM VFP instruction patterns
2 ;; Copyright (C) 2003-2013 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 ;; The VFP "type" attributes differ from those used in the FPA model.
22 ;; fcpys        Single precision cpy.
23 ;; ffariths     Single precision abs, neg.
24 ;; ffarithd     Double precision abs, neg, cpy.
25 ;; fadds        Single precision add/sub.
26 ;; faddd        Double precision add/sub.
27 ;; fconsts      Single precision load immediate.
28 ;; fconstd      Double precision load immediate.
29 ;; fcmps        Single precision comparison.
30 ;; fcmpd        Double precision comparison.
31 ;; fmuls        Single precision multiply.
32 ;; fmuld        Double precision multiply.
33 ;; fmacs        Single precision multiply-accumulate.
34 ;; fmacd        Double precision multiply-accumulate.
35 ;; ffmas        Single precision fused multiply-accumulate.
36 ;; ffmad        Double precision fused multiply-accumulate.
37 ;; fdivs        Single precision sqrt or division.
38 ;; fdivd        Double precision sqrt or division.
39 ;; f_flag       fmstat operation
40 ;; f_load[sd]   Floating point load from memory.
41 ;; f_store[sd]  Floating point store to memory.
42 ;; f_2_r        Transfer vfp to arm reg.
43 ;; r_2_f        Transfer arm to vfp reg.
44 ;; f_cvt        Convert floating<->integral
45
46 ;; SImode moves
47 ;; ??? For now do not allow loading constants into vfp regs.  This causes
48 ;; problems because small constants get converted into adds.
49 (define_insn "*arm_movsi_vfp"
50   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m ,*t,r,*t,*t, *Uv")
51       (match_operand:SI 1 "general_operand"        "rk, I,K,j,mi,rk,r,*t,*t,*Uvi,*t"))]
52   "TARGET_ARM && TARGET_VFP && TARGET_HARD_FLOAT
53    && (   s_register_operand (operands[0], SImode)
54        || s_register_operand (operands[1], SImode))"
55   "*
56   switch (which_alternative)
57     {
58     case 0: case 1:
59       return \"mov%?\\t%0, %1\";
60     case 2:
61       return \"mvn%?\\t%0, #%B1\";
62     case 3:
63       return \"movw%?\\t%0, %1\";
64     case 4:
65       return \"ldr%?\\t%0, %1\";
66     case 5:
67       return \"str%?\\t%1, %0\";
68     case 6:
69       return \"fmsr%?\\t%0, %1\\t%@ int\";
70     case 7:
71       return \"fmrs%?\\t%0, %1\\t%@ int\";
72     case 8:
73       return \"fcpys%?\\t%0, %1\\t%@ int\";
74     case 9: case 10:
75       return output_move_vfp (operands);
76     default:
77       gcc_unreachable ();
78     }
79   "
80   [(set_attr "predicable" "yes")
81    (set_attr "type" "*,*,simple_alu_imm,simple_alu_imm,load1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores")
82    (set_attr "neon_type" "*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*")
83    (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*")
84    (set_attr "pool_range"     "*,*,*,*,4096,*,*,*,*,1020,*")
85    (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")]
86 )
87
88 ;; See thumb2.md:thumb2_movsi_insn for an explanation of the split
89 ;; high/low register alternatives for loads and stores here.
90 (define_insn "*thumb2_movsi_vfp"
91   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r, l,*hk,m, *m,*t, r,*t,*t,  *Uv")
92         (match_operand:SI 1 "general_operand"      "rk, I,K,j,mi,*mi,l,*hk, r,*t,*t,*Uvi,*t"))]
93   "TARGET_THUMB2 && TARGET_VFP && TARGET_HARD_FLOAT
94    && (   s_register_operand (operands[0], SImode)
95        || s_register_operand (operands[1], SImode))"
96   "*
97   switch (which_alternative)
98     {
99     case 0: case 1:
100       return \"mov%?\\t%0, %1\";
101     case 2:
102       return \"mvn%?\\t%0, #%B1\";
103     case 3:
104       return \"movw%?\\t%0, %1\";
105     case 4:
106     case 5:
107       return \"ldr%?\\t%0, %1\";
108     case 6:
109     case 7:
110       return \"str%?\\t%1, %0\";
111     case 8:
112       return \"fmsr%?\\t%0, %1\\t%@ int\";
113     case 9:
114       return \"fmrs%?\\t%0, %1\\t%@ int\";
115     case 10:
116       return \"fcpys%?\\t%0, %1\\t%@ int\";
117     case 11: case 12:
118       return output_move_vfp (operands);
119     default:
120       gcc_unreachable ();
121     }
122   "
123   [(set_attr "predicable" "yes")
124    (set_attr "type" "*,*,*,*,load1,load1,store1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores")
125    (set_attr "neon_type" "*,*,*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*")
126    (set_attr "insn" "mov,mov,mvn,mov,*,*,*,*,*,*,*,*,*")
127    (set_attr "pool_range"     "*,*,*,*,1018,4094,*,*,*,*,*,1018,*")
128    (set_attr "neg_pool_range" "*,*,*,*,   0,   0,*,*,*,*,*,1008,*")]
129 )
130
131
132 ;; DImode moves
133
134 (define_insn "*movdi_vfp"
135   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,r,r,m,w,r,w,w, Uv")
136        (match_operand:DI 1 "di_operand"              "r,rDa,Db,Dc,mi,mi,r,r,w,w,Uvi,w"))]
137   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && arm_tune != cortexa8
138    && (   register_operand (operands[0], DImode)
139        || register_operand (operands[1], DImode))
140    && !(TARGET_NEON && CONST_INT_P (operands[1])
141         && neon_immediate_valid_for_move (operands[1], DImode, NULL, NULL))"
142   "*
143   switch (which_alternative)
144     {
145     case 0: 
146     case 1:
147     case 2:
148     case 3:
149       return \"#\";
150     case 4:
151     case 5:
152     case 6:
153       return output_move_double (operands, true, NULL);
154     case 7:
155       return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
156     case 8:
157       return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
158     case 9:
159       if (TARGET_VFP_SINGLE)
160         return \"fcpys%?\\t%0, %1\\t%@ int\;fcpys%?\\t%p0, %p1\\t%@ int\";
161       else
162         return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
163     case 10: case 11:
164       return output_move_vfp (operands);
165     default:
166       gcc_unreachable ();
167     }
168   "
169   [(set_attr "type" "*,*,*,*,load2,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
170    (set_attr "neon_type" "*,*,*,*,*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*")
171    (set (attr "length") (cond [(eq_attr "alternative" "1,4,5,6") (const_int 8)
172                               (eq_attr "alternative" "2") (const_int 12)
173                               (eq_attr "alternative" "3") (const_int 16)
174                               (eq_attr "alternative" "9")
175                                (if_then_else
176                                  (match_test "TARGET_VFP_SINGLE")
177                                  (const_int 8)
178                                  (const_int 4))]
179                               (const_int 4)))
180    (set_attr "arm_pool_range"     "*,*,*,*,1020,4096,*,*,*,*,1020,*")
181    (set_attr "thumb2_pool_range"     "*,*,*,*,1018,4094,*,*,*,*,1018,*")
182    (set_attr "neg_pool_range" "*,*,*,*,1004,0,*,*,*,*,1004,*")
183    (set_attr "arch"           "t2,any,any,any,a,t2,any,any,any,any,any,any")]
184 )
185
186 (define_insn "*movdi_vfp_cortexa8"
187   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,r,r,m,w,!r,w,w, Uv")
188        (match_operand:DI 1 "di_operand"              "r,rDa,Db,Dc,mi,mi,r,r,w,w,Uvi,w"))]
189   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP && arm_tune == cortexa8
190     && (   register_operand (operands[0], DImode)
191         || register_operand (operands[1], DImode))
192     && !(TARGET_NEON && CONST_INT_P (operands[1])
193          && neon_immediate_valid_for_move (operands[1], DImode, NULL, NULL))"
194   "*
195   switch (which_alternative)
196     {
197     case 0: 
198     case 1:
199     case 2:
200     case 3:
201       return \"#\";
202     case 4:
203     case 5:
204     case 6:
205       return output_move_double (operands, true, NULL);
206     case 7:
207       return \"fmdrr%?\\t%P0, %Q1, %R1\\t%@ int\";
208     case 8:
209       return \"fmrrd%?\\t%Q0, %R0, %P1\\t%@ int\";
210     case 9:
211       return \"fcpyd%?\\t%P0, %P1\\t%@ int\";
212     case 10: case 11:
213       return output_move_vfp (operands);
214     default:
215       gcc_unreachable ();
216     }
217   "
218   [(set_attr "type" "*,*,*,*,load2,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
219    (set_attr "neon_type" "*,*,*,*,*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*")
220    (set (attr "length") (cond [(eq_attr "alternative" "1") (const_int 8)
221                                (eq_attr "alternative" "2") (const_int 12)
222                                (eq_attr "alternative" "3") (const_int 16)
223                                (eq_attr "alternative" "4,5,6") 
224                                (symbol_ref 
225                                 "arm_count_output_move_double_insns (operands) \
226                                  * 4")]
227                               (const_int 4)))
228    (set_attr "predicable"    "yes")
229    (set_attr "arm_pool_range"     "*,*,*,*,1018,4094,*,*,*,*,1018,*")
230    (set_attr "thumb2_pool_range"     "*,*,*,*,1018,4094,*,*,*,*,1018,*")
231    (set_attr "neg_pool_range" "*,*,*,*,1004,0,*,*,*,*,1004,*")
232    (set (attr "ce_count") 
233         (symbol_ref "get_attr_length (insn) / 4"))
234    (set_attr "arch"           "t2,any,any,any,a,t2,any,any,any,any,any,any")]
235  )
236
237 ;; HFmode moves
238 (define_insn "*movhf_vfp_neon"
239   [(set (match_operand:HF 0 "nonimmediate_operand" "= t,Um,r,m,t,r,t,r,r")
240         (match_operand:HF 1 "general_operand"      " Um, t,m,r,t,r,r,t,F"))]
241   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_NEON_FP16
242    && (   s_register_operand (operands[0], HFmode)
243        || s_register_operand (operands[1], HFmode))"
244   "*
245   switch (which_alternative)
246     {
247     case 0:     /* S register from memory */
248       return \"vld1.16\\t{%z0}, %A1\";
249     case 1:     /* memory from S register */
250       return \"vst1.16\\t{%z1}, %A0\";
251     case 2:     /* ARM register from memory */
252       return \"ldrh\\t%0, %1\\t%@ __fp16\";
253     case 3:     /* memory from ARM register */
254       return \"strh\\t%1, %0\\t%@ __fp16\";
255     case 4:     /* S register from S register */
256       return \"fcpys\\t%0, %1\";
257     case 5:     /* ARM register from ARM register */
258       return \"mov\\t%0, %1\\t%@ __fp16\";
259     case 6:     /* S register from ARM register */
260       return \"fmsr\\t%0, %1\";
261     case 7:     /* ARM register from S register */
262       return \"fmrs\\t%0, %1\";
263     case 8:     /* ARM register from constant */
264       {
265         REAL_VALUE_TYPE r;
266         long bits;
267         rtx ops[4];
268
269         REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
270         bits = real_to_target (NULL, &r, HFmode);
271         ops[0] = operands[0];
272         ops[1] = GEN_INT (bits);
273         ops[2] = GEN_INT (bits & 0xff00);
274         ops[3] = GEN_INT (bits & 0x00ff);
275
276         if (arm_arch_thumb2)
277           output_asm_insn (\"movw\\t%0, %1\", ops);
278         else
279           output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops);
280         return \"\";
281        }
282     default:
283       gcc_unreachable ();
284     }
285   "
286   [(set_attr "conds" "unconditional")
287    (set_attr "type" "*,*,load1,store1,fcpys,*,r_2_f,f_2_r,*")
288    (set_attr "neon_type" "neon_vld1_1_2_regs,neon_vst1_1_2_regs_vst2_2_regs,*,*,*,*,*,*,*")
289    (set_attr "length" "4,4,4,4,4,4,4,4,8")]
290 )
291
292 ;; FP16 without element load/store instructions.
293 (define_insn "*movhf_vfp"
294   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,t,r,t,r,r")
295         (match_operand:HF 1 "general_operand"      " m,r,t,r,r,t,F"))]
296   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16 && !TARGET_NEON_FP16
297    && (   s_register_operand (operands[0], HFmode)
298        || s_register_operand (operands[1], HFmode))"
299   "*
300   switch (which_alternative)
301     {
302     case 0:     /* ARM register from memory */
303       return \"ldrh\\t%0, %1\\t%@ __fp16\";
304     case 1:     /* memory from ARM register */
305       return \"strh\\t%1, %0\\t%@ __fp16\";
306     case 2:     /* S register from S register */
307       return \"fcpys\\t%0, %1\";
308     case 3:     /* ARM register from ARM register */
309       return \"mov\\t%0, %1\\t%@ __fp16\";
310     case 4:     /* S register from ARM register */
311       return \"fmsr\\t%0, %1\";
312     case 5:     /* ARM register from S register */
313       return \"fmrs\\t%0, %1\";
314     case 6:     /* ARM register from constant */
315       {
316         REAL_VALUE_TYPE r;
317         long bits;
318         rtx ops[4];
319
320         REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
321         bits = real_to_target (NULL, &r, HFmode);
322         ops[0] = operands[0];
323         ops[1] = GEN_INT (bits);
324         ops[2] = GEN_INT (bits & 0xff00);
325         ops[3] = GEN_INT (bits & 0x00ff);
326
327         if (arm_arch_thumb2)
328           output_asm_insn (\"movw\\t%0, %1\", ops);
329         else
330           output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops);
331         return \"\";
332        }
333     default:
334       gcc_unreachable ();
335     }
336   "
337   [(set_attr "conds" "unconditional")
338    (set_attr "type" "load1,store1,fcpys,*,r_2_f,f_2_r,*")
339    (set_attr "length" "4,4,4,4,4,4,8")]
340 )
341
342
343 ;; SFmode moves
344 ;; Disparage the w<->r cases because reloading an invalid address is
345 ;; preferable to loading the value via integer registers.
346
347 (define_insn "*movsf_vfp"
348   [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t ,t  ,Uv,r ,m,t,r")
349         (match_operand:SF 1 "general_operand"      " ?r,t,Dv,UvE,t, mE,r,t,r"))]
350   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
351    && (   s_register_operand (operands[0], SFmode)
352        || s_register_operand (operands[1], SFmode))"
353   "*
354   switch (which_alternative)
355     {
356     case 0:
357       return \"fmsr%?\\t%0, %1\";
358     case 1:
359       return \"fmrs%?\\t%0, %1\";
360     case 2:
361       return \"fconsts%?\\t%0, #%G1\";
362     case 3: case 4:
363       return output_move_vfp (operands);
364     case 5:
365       return \"ldr%?\\t%0, %1\\t%@ float\";
366     case 6:
367       return \"str%?\\t%1, %0\\t%@ float\";
368     case 7:
369       return \"fcpys%?\\t%0, %1\";
370     case 8:
371       return \"mov%?\\t%0, %1\\t%@ float\";
372     default:
373       gcc_unreachable ();
374     }
375   "
376   [(set_attr "predicable" "yes")
377    (set_attr "type"
378      "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,*")
379    (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*")
380    (set_attr "insn" "*,*,*,*,*,*,*,*,mov")
381    (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*")
382    (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")]
383 )
384
385 (define_insn "*thumb2_movsf_vfp"
386   [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t, t  ,Uv,r ,m,t,r")
387         (match_operand:SF 1 "general_operand"      " ?r,t,Dv,UvE,t, mE,r,t,r"))]
388   "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP
389    && (   s_register_operand (operands[0], SFmode)
390        || s_register_operand (operands[1], SFmode))"
391   "*
392   switch (which_alternative)
393     {
394     case 0:
395       return \"fmsr%?\\t%0, %1\";
396     case 1:
397       return \"fmrs%?\\t%0, %1\";
398     case 2:
399       return \"fconsts%?\\t%0, #%G1\";
400     case 3: case 4:
401       return output_move_vfp (operands);
402     case 5:
403       return \"ldr%?\\t%0, %1\\t%@ float\";
404     case 6:
405       return \"str%?\\t%1, %0\\t%@ float\";
406     case 7:
407       return \"fcpys%?\\t%0, %1\";
408     case 8:
409       return \"mov%?\\t%0, %1\\t%@ float\";
410     default:
411       gcc_unreachable ();
412     }
413   "
414   [(set_attr "predicable" "yes")
415    (set_attr "type"
416      "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,*")
417    (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*")
418    (set_attr "insn" "*,*,*,*,*,*,*,*,mov")
419    (set_attr "pool_range" "*,*,*,1018,*,4090,*,*,*")
420    (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")]
421 )
422
423
424 ;; DFmode moves
425
426 (define_insn "*movdf_vfp"
427   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w  ,Uv,r, m,w,r")
428         (match_operand:DF 1 "soft_df_operand"              " ?r,w,Dy,UvF,w ,mF,r,w,r"))]
429   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
430    && (   register_operand (operands[0], DFmode)
431        || register_operand (operands[1], DFmode))"
432   "*
433   {
434     switch (which_alternative)
435       {
436       case 0:
437         return \"fmdrr%?\\t%P0, %Q1, %R1\";
438       case 1:
439         return \"fmrrd%?\\t%Q0, %R0, %P1\";
440       case 2:
441         gcc_assert (TARGET_VFP_DOUBLE);
442         return \"fconstd%?\\t%P0, #%G1\";
443       case 3: case 4:
444         return output_move_vfp (operands);
445       case 5: case 6:
446         return output_move_double (operands, true, NULL);
447       case 7:
448         if (TARGET_VFP_SINGLE)
449           return \"fcpys%?\\t%0, %1\;fcpys%?\\t%p0, %p1\";
450         else
451           return \"fcpyd%?\\t%P0, %P1\";
452       case 8:
453         return \"#\";
454       default:
455         gcc_unreachable ();
456       }
457     }
458   "
459   [(set_attr "type"
460      "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*")
461    (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*")
462    (set (attr "length") (cond [(eq_attr "alternative" "5,6,8") (const_int 8)
463                                (eq_attr "alternative" "7")
464                                 (if_then_else
465                                  (match_test "TARGET_VFP_SINGLE")
466                                  (const_int 8)
467                                  (const_int 4))]
468                               (const_int 4)))
469    (set_attr "predicable" "yes")
470    (set_attr "pool_range" "*,*,*,1020,*,1020,*,*,*")
471    (set_attr "neg_pool_range" "*,*,*,1004,*,1004,*,*,*")]
472 )
473
474 (define_insn "*thumb2_movdf_vfp"
475   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w  ,Uv,r ,m,w,r")
476         (match_operand:DF 1 "soft_df_operand"              " ?r,w,Dy,UvF,w, mF,r, w,r"))]
477   "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP
478    && (   register_operand (operands[0], DFmode)
479        || register_operand (operands[1], DFmode))"
480   "*
481   {
482     switch (which_alternative)
483       {
484       case 0:
485         return \"fmdrr%?\\t%P0, %Q1, %R1\";
486       case 1:
487         return \"fmrrd%?\\t%Q0, %R0, %P1\";
488       case 2:
489         gcc_assert (TARGET_VFP_DOUBLE);
490         return \"fconstd%?\\t%P0, #%G1\";
491       case 3: case 4:
492         return output_move_vfp (operands);
493       case 5: case 6: case 8:
494         return output_move_double (operands, true, NULL);
495       case 7:
496         if (TARGET_VFP_SINGLE)
497           return \"fcpys%?\\t%0, %1\;fcpys%?\\t%p0, %p1\";
498         else
499           return \"fcpyd%?\\t%P0, %P1\";
500       default:
501         abort ();
502       }
503     }
504   "
505   [(set_attr "type"
506      "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*")
507    (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*")
508    (set (attr "length") (cond [(eq_attr "alternative" "5,6,8") (const_int 8)
509                                (eq_attr "alternative" "7")
510                                 (if_then_else
511                                  (match_test "TARGET_VFP_SINGLE")
512                                  (const_int 8)
513                                  (const_int 4))]
514                               (const_int 4)))
515    (set_attr "pool_range" "*,*,*,1018,*,4094,*,*,*")
516    (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")]
517 )
518
519
520 ;; Conditional move patterns
521
522 (define_insn "*movsfcc_vfp"
523   [(set (match_operand:SF   0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
524         (if_then_else:SF
525           (match_operator   3 "arm_comparison_operator"
526             [(match_operand 4 "cc_register" "") (const_int 0)])
527           (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
528           (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
529   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
530   "@
531    fcpys%D3\\t%0, %2
532    fcpys%d3\\t%0, %1
533    fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
534    fmsr%D3\\t%0, %2
535    fmsr%d3\\t%0, %1
536    fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
537    fmrs%D3\\t%0, %2
538    fmrs%d3\\t%0, %1
539    fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
540    [(set_attr "conds" "use")
541     (set_attr "length" "4,4,8,4,4,8,4,4,8")
542     (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
543     (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr,neon_mcr,neon_mcr,neon_mrc,neon_mrc,neon_mrc")]
544 )
545
546 (define_insn "*thumb2_movsfcc_vfp"
547   [(set (match_operand:SF   0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
548         (if_then_else:SF
549           (match_operator   3 "arm_comparison_operator"
550             [(match_operand 4 "cc_register" "") (const_int 0)])
551           (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
552           (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
553   "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP"
554   "@
555    it\\t%D3\;fcpys%D3\\t%0, %2
556    it\\t%d3\;fcpys%d3\\t%0, %1
557    ite\\t%D3\;fcpys%D3\\t%0, %2\;fcpys%d3\\t%0, %1
558    it\\t%D3\;fmsr%D3\\t%0, %2
559    it\\t%d3\;fmsr%d3\\t%0, %1
560    ite\\t%D3\;fmsr%D3\\t%0, %2\;fmsr%d3\\t%0, %1
561    it\\t%D3\;fmrs%D3\\t%0, %2
562    it\\t%d3\;fmrs%d3\\t%0, %1
563    ite\\t%D3\;fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
564    [(set_attr "conds" "use")
565     (set_attr "length" "6,6,10,6,6,10,6,6,10")
566     (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
567     (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr,neon_mcr,neon_mcr,neon_mrc,neon_mrc,neon_mrc")]
568 )
569
570 (define_insn "*movdfcc_vfp"
571   [(set (match_operand:DF   0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
572         (if_then_else:DF
573           (match_operator   3 "arm_comparison_operator"
574             [(match_operand 4 "cc_register" "") (const_int 0)])
575           (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
576           (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
577   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
578   "@
579    fcpyd%D3\\t%P0, %P2
580    fcpyd%d3\\t%P0, %P1
581    fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
582    fmdrr%D3\\t%P0, %Q2, %R2
583    fmdrr%d3\\t%P0, %Q1, %R1
584    fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
585    fmrrd%D3\\t%Q0, %R0, %P2
586    fmrrd%d3\\t%Q0, %R0, %P1
587    fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
588    [(set_attr "conds" "use")
589     (set_attr "length" "4,4,8,4,4,8,4,4,8")
590     (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
591     (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mrrc,neon_mrrc,neon_mrrc")]
592 )
593
594 (define_insn "*thumb2_movdfcc_vfp"
595   [(set (match_operand:DF   0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
596         (if_then_else:DF
597           (match_operator   3 "arm_comparison_operator"
598             [(match_operand 4 "cc_register" "") (const_int 0)])
599           (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
600           (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
601   "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
602   "@
603    it\\t%D3\;fcpyd%D3\\t%P0, %P2
604    it\\t%d3\;fcpyd%d3\\t%P0, %P1
605    ite\\t%D3\;fcpyd%D3\\t%P0, %P2\;fcpyd%d3\\t%P0, %P1
606    it\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2
607    it\t%d3\;fmdrr%d3\\t%P0, %Q1, %R1
608    ite\\t%D3\;fmdrr%D3\\t%P0, %Q2, %R2\;fmdrr%d3\\t%P0, %Q1, %R1
609    it\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2
610    it\t%d3\;fmrrd%d3\\t%Q0, %R0, %P1
611    ite\\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
612    [(set_attr "conds" "use")
613     (set_attr "length" "6,6,10,6,6,10,6,6,10")
614     (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
615     (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mrrc,neon_mrrc,neon_mrrc")]
616 )
617
618
619 ;; Sign manipulation functions
620
621 (define_insn "*abssf2_vfp"
622   [(set (match_operand:SF         0 "s_register_operand" "=t")
623         (abs:SF (match_operand:SF 1 "s_register_operand" "t")))]
624   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
625   "fabss%?\\t%0, %1"
626   [(set_attr "predicable" "yes")
627    (set_attr "type" "ffariths")]
628 )
629
630 (define_insn "*absdf2_vfp"
631   [(set (match_operand:DF         0 "s_register_operand" "=w")
632         (abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
633   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
634   "fabsd%?\\t%P0, %P1"
635   [(set_attr "predicable" "yes")
636    (set_attr "type" "ffarithd")]
637 )
638
639 (define_insn "*negsf2_vfp"
640   [(set (match_operand:SF         0 "s_register_operand" "=t,?r")
641         (neg:SF (match_operand:SF 1 "s_register_operand" "t,r")))]
642   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
643   "@
644    fnegs%?\\t%0, %1
645    eor%?\\t%0, %1, #-2147483648"
646   [(set_attr "predicable" "yes")
647    (set_attr "type" "ffariths")]
648 )
649
650 (define_insn_and_split "*negdf2_vfp"
651   [(set (match_operand:DF         0 "s_register_operand" "=w,?r,?r")
652         (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))]
653   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
654   "@
655    fnegd%?\\t%P0, %P1
656    #
657    #"
658   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE && reload_completed
659    && arm_general_register_operand (operands[0], DFmode)"
660   [(set (match_dup 0) (match_dup 1))]
661   "
662   if (REGNO (operands[0]) == REGNO (operands[1]))
663     {
664       operands[0] = gen_highpart (SImode, operands[0]);
665       operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000));
666     }
667   else
668     {
669       rtx in_hi, in_lo, out_hi, out_lo;
670
671       in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]),
672                            GEN_INT (0x80000000));
673       in_lo = gen_lowpart (SImode, operands[1]);
674       out_hi = gen_highpart (SImode, operands[0]);
675       out_lo = gen_lowpart (SImode, operands[0]);
676
677       if (REGNO (in_lo) == REGNO (out_hi))
678         {
679           emit_insn (gen_rtx_SET (SImode, out_lo, in_lo));
680           operands[0] = out_hi;
681           operands[1] = in_hi;
682         }
683       else
684         {
685           emit_insn (gen_rtx_SET (SImode, out_hi, in_hi));
686           operands[0] = out_lo;
687           operands[1] = in_lo;
688         }
689     }
690   "
691   [(set_attr "predicable" "yes")
692    (set_attr "length" "4,4,8")
693    (set_attr "type" "ffarithd")]
694 )
695
696
697 ;; Arithmetic insns
698
699 (define_insn "*addsf3_vfp"
700   [(set (match_operand:SF          0 "s_register_operand" "=t")
701         (plus:SF (match_operand:SF 1 "s_register_operand" "t")
702                  (match_operand:SF 2 "s_register_operand" "t")))]
703   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
704   "fadds%?\\t%0, %1, %2"
705   [(set_attr "predicable" "yes")
706    (set_attr "type" "fadds")]
707 )
708
709 (define_insn "*adddf3_vfp"
710   [(set (match_operand:DF          0 "s_register_operand" "=w")
711         (plus:DF (match_operand:DF 1 "s_register_operand" "w")
712                  (match_operand:DF 2 "s_register_operand" "w")))]
713   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
714   "faddd%?\\t%P0, %P1, %P2"
715   [(set_attr "predicable" "yes")
716    (set_attr "type" "faddd")]
717 )
718
719
720 (define_insn "*subsf3_vfp"
721   [(set (match_operand:SF           0 "s_register_operand" "=t")
722         (minus:SF (match_operand:SF 1 "s_register_operand" "t")
723                   (match_operand:SF 2 "s_register_operand" "t")))]
724   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
725   "fsubs%?\\t%0, %1, %2"
726   [(set_attr "predicable" "yes")
727    (set_attr "type" "fadds")]
728 )
729
730 (define_insn "*subdf3_vfp"
731   [(set (match_operand:DF           0 "s_register_operand" "=w")
732         (minus:DF (match_operand:DF 1 "s_register_operand" "w")
733                   (match_operand:DF 2 "s_register_operand" "w")))]
734   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
735   "fsubd%?\\t%P0, %P1, %P2"
736   [(set_attr "predicable" "yes")
737    (set_attr "type" "faddd")]
738 )
739
740
741 ;; Division insns
742
743 (define_insn "*divsf3_vfp"
744   [(set (match_operand:SF         0 "s_register_operand" "=t")
745         (div:SF (match_operand:SF 1 "s_register_operand" "t")
746                 (match_operand:SF 2 "s_register_operand" "t")))]
747   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
748   "fdivs%?\\t%0, %1, %2"
749   [(set_attr "predicable" "yes")
750    (set_attr "type" "fdivs")]
751 )
752
753 (define_insn "*divdf3_vfp"
754   [(set (match_operand:DF         0 "s_register_operand" "=w")
755         (div:DF (match_operand:DF 1 "s_register_operand" "w")
756                 (match_operand:DF 2 "s_register_operand" "w")))]
757   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
758   "fdivd%?\\t%P0, %P1, %P2"
759   [(set_attr "predicable" "yes")
760    (set_attr "type" "fdivd")]
761 )
762
763
764 ;; Multiplication insns
765
766 (define_insn "*mulsf3_vfp"
767   [(set (match_operand:SF          0 "s_register_operand" "=t")
768         (mult:SF (match_operand:SF 1 "s_register_operand" "t")
769                  (match_operand:SF 2 "s_register_operand" "t")))]
770   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
771   "fmuls%?\\t%0, %1, %2"
772   [(set_attr "predicable" "yes")
773    (set_attr "type" "fmuls")]
774 )
775
776 (define_insn "*muldf3_vfp"
777   [(set (match_operand:DF          0 "s_register_operand" "=w")
778         (mult:DF (match_operand:DF 1 "s_register_operand" "w")
779                  (match_operand:DF 2 "s_register_operand" "w")))]
780   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
781   "fmuld%?\\t%P0, %P1, %P2"
782   [(set_attr "predicable" "yes")
783    (set_attr "type" "fmuld")]
784 )
785
786 (define_insn "*mulsf3negsf_vfp"
787   [(set (match_operand:SF                  0 "s_register_operand" "=t")
788         (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "t"))
789                  (match_operand:SF         2 "s_register_operand" "t")))]
790   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
791   "fnmuls%?\\t%0, %1, %2"
792   [(set_attr "predicable" "yes")
793    (set_attr "type" "fmuls")]
794 )
795
796 (define_insn "*muldf3negdf_vfp"
797   [(set (match_operand:DF                  0 "s_register_operand" "=w")
798         (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
799                  (match_operand:DF         2 "s_register_operand" "w")))]
800   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
801   "fnmuld%?\\t%P0, %P1, %P2"
802   [(set_attr "predicable" "yes")
803    (set_attr "type" "fmuld")]
804 )
805
806
807 ;; Multiply-accumulate insns
808
809 ;; 0 = 1 * 2 + 0
810 (define_insn "*mulsf3addsf_vfp"
811   [(set (match_operand:SF                   0 "s_register_operand" "=t")
812         (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
813                           (match_operand:SF 3 "s_register_operand" "t"))
814                  (match_operand:SF          1 "s_register_operand" "0")))]
815   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
816   "fmacs%?\\t%0, %2, %3"
817   [(set_attr "predicable" "yes")
818    (set_attr "type" "fmacs")]
819 )
820
821 (define_insn "*muldf3adddf_vfp"
822   [(set (match_operand:DF                   0 "s_register_operand" "=w")
823         (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
824                           (match_operand:DF 3 "s_register_operand" "w"))
825                  (match_operand:DF          1 "s_register_operand" "0")))]
826   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
827   "fmacd%?\\t%P0, %P2, %P3"
828   [(set_attr "predicable" "yes")
829    (set_attr "type" "fmacd")]
830 )
831
832 ;; 0 = 1 * 2 - 0
833 (define_insn "*mulsf3subsf_vfp"
834   [(set (match_operand:SF                    0 "s_register_operand" "=t")
835         (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
836                            (match_operand:SF 3 "s_register_operand" "t"))
837                   (match_operand:SF          1 "s_register_operand" "0")))]
838   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
839   "fmscs%?\\t%0, %2, %3"
840   [(set_attr "predicable" "yes")
841    (set_attr "type" "fmacs")]
842 )
843
844 (define_insn "*muldf3subdf_vfp"
845   [(set (match_operand:DF                    0 "s_register_operand" "=w")
846         (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
847                            (match_operand:DF 3 "s_register_operand" "w"))
848                   (match_operand:DF          1 "s_register_operand" "0")))]
849   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
850   "fmscd%?\\t%P0, %P2, %P3"
851   [(set_attr "predicable" "yes")
852    (set_attr "type" "fmacd")]
853 )
854
855 ;; 0 = -(1 * 2) + 0
856 (define_insn "*mulsf3negsfaddsf_vfp"
857   [(set (match_operand:SF                    0 "s_register_operand" "=t")
858         (minus:SF (match_operand:SF          1 "s_register_operand" "0")
859                   (mult:SF (match_operand:SF 2 "s_register_operand" "t")
860                            (match_operand:SF 3 "s_register_operand" "t"))))]
861   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
862   "fnmacs%?\\t%0, %2, %3"
863   [(set_attr "predicable" "yes")
864    (set_attr "type" "fmacs")]
865 )
866
867 (define_insn "*fmuldf3negdfadddf_vfp"
868   [(set (match_operand:DF                    0 "s_register_operand" "=w")
869         (minus:DF (match_operand:DF          1 "s_register_operand" "0")
870                   (mult:DF (match_operand:DF 2 "s_register_operand" "w")
871                            (match_operand:DF 3 "s_register_operand" "w"))))]
872   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
873   "fnmacd%?\\t%P0, %P2, %P3"
874   [(set_attr "predicable" "yes")
875    (set_attr "type" "fmacd")]
876 )
877
878
879 ;; 0 = -(1 * 2) - 0
880 (define_insn "*mulsf3negsfsubsf_vfp"
881   [(set (match_operand:SF                     0 "s_register_operand" "=t")
882         (minus:SF (mult:SF
883                     (neg:SF (match_operand:SF 2 "s_register_operand" "t"))
884                     (match_operand:SF         3 "s_register_operand" "t"))
885                   (match_operand:SF           1 "s_register_operand" "0")))]
886   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
887   "fnmscs%?\\t%0, %2, %3"
888   [(set_attr "predicable" "yes")
889    (set_attr "type" "fmacs")]
890 )
891
892 (define_insn "*muldf3negdfsubdf_vfp"
893   [(set (match_operand:DF                     0 "s_register_operand" "=w")
894         (minus:DF (mult:DF
895                     (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
896                     (match_operand:DF         3 "s_register_operand" "w"))
897                   (match_operand:DF           1 "s_register_operand" "0")))]
898   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
899   "fnmscd%?\\t%P0, %P2, %P3"
900   [(set_attr "predicable" "yes")
901    (set_attr "type" "fmacd")]
902 )
903
904 ;; Fused-multiply-accumulate
905
906 (define_insn "fma<SDF:mode>4"
907   [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
908         (fma:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>")
909                  (match_operand:SDF 2 "register_operand" "<F_constraint>")
910                  (match_operand:SDF 3 "register_operand" "0")))]
911   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
912   "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
913   [(set_attr "predicable" "yes")
914    (set_attr "type" "ffma<vfp_type>")]
915 )
916
917 (define_insn "*fmsub<SDF:mode>4"
918   [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
919         (fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand"
920                                              "<F_constraint>"))
921                  (match_operand:SDF 2 "register_operand" "<F_constraint>")
922                  (match_operand:SDF 3 "register_operand" "0")))]
923   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
924   "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
925   [(set_attr "predicable" "yes")
926    (set_attr "type" "ffma<vfp_type>")]
927 )
928
929 (define_insn "*fnmsub<SDF:mode>4"
930   [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
931         (fma:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>")
932                  (match_operand:SDF 2 "register_operand" "<F_constraint>")
933                  (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))]
934   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
935   "vfnms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
936   [(set_attr "predicable" "yes")
937    (set_attr "type" "ffma<vfp_type>")]
938 )
939
940 (define_insn "*fnmadd<SDF:mode>4"
941   [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
942         (fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand"
943                                                "<F_constraint>"))
944                  (match_operand:SDF 2 "register_operand" "<F_constraint>")
945                  (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))]
946   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
947   "vfnma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
948   [(set_attr "predicable" "yes")
949    (set_attr "type" "ffma<vfp_type>")]
950 )
951
952
953 ;; Conversion routines
954
955 (define_insn "*extendsfdf2_vfp"
956   [(set (match_operand:DF                  0 "s_register_operand" "=w")
957         (float_extend:DF (match_operand:SF 1 "s_register_operand" "t")))]
958   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
959   "fcvtds%?\\t%P0, %1"
960   [(set_attr "predicable" "yes")
961    (set_attr "type" "f_cvt")]
962 )
963
964 (define_insn "*truncdfsf2_vfp"
965   [(set (match_operand:SF                  0 "s_register_operand" "=t")
966         (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
967   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
968   "fcvtsd%?\\t%0, %P1"
969   [(set_attr "predicable" "yes")
970    (set_attr "type" "f_cvt")]
971 )
972
973 (define_insn "extendhfsf2"
974   [(set (match_operand:SF                  0 "s_register_operand" "=t")
975         (float_extend:SF (match_operand:HF 1 "s_register_operand" "t")))]
976   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16"
977   "vcvtb%?.f32.f16\\t%0, %1"
978   [(set_attr "predicable" "yes")
979    (set_attr "type" "f_cvt")]
980 )
981
982 (define_insn "truncsfhf2"
983   [(set (match_operand:HF                  0 "s_register_operand" "=t")
984         (float_truncate:HF (match_operand:SF 1 "s_register_operand" "t")))]
985   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16"
986   "vcvtb%?.f16.f32\\t%0, %1"
987   [(set_attr "predicable" "yes")
988    (set_attr "type" "f_cvt")]
989 )
990
991 (define_insn "*truncsisf2_vfp"
992   [(set (match_operand:SI                 0 "s_register_operand" "=t")
993         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
994   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
995   "ftosizs%?\\t%0, %1"
996   [(set_attr "predicable" "yes")
997    (set_attr "type" "f_cvt")]
998 )
999
1000 (define_insn "*truncsidf2_vfp"
1001   [(set (match_operand:SI                 0 "s_register_operand" "=t")
1002         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
1003   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1004   "ftosizd%?\\t%0, %P1"
1005   [(set_attr "predicable" "yes")
1006    (set_attr "type" "f_cvt")]
1007 )
1008
1009
1010 (define_insn "fixuns_truncsfsi2"
1011   [(set (match_operand:SI                 0 "s_register_operand" "=t")
1012         (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
1013   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1014   "ftouizs%?\\t%0, %1"
1015   [(set_attr "predicable" "yes")
1016    (set_attr "type" "f_cvt")]
1017 )
1018
1019 (define_insn "fixuns_truncdfsi2"
1020   [(set (match_operand:SI                 0 "s_register_operand" "=t")
1021         (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "t"))))]
1022   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1023   "ftouizd%?\\t%0, %P1"
1024   [(set_attr "predicable" "yes")
1025    (set_attr "type" "f_cvt")]
1026 )
1027
1028
1029 (define_insn "*floatsisf2_vfp"
1030   [(set (match_operand:SF           0 "s_register_operand" "=t")
1031         (float:SF (match_operand:SI 1 "s_register_operand" "t")))]
1032   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1033   "fsitos%?\\t%0, %1"
1034   [(set_attr "predicable" "yes")
1035    (set_attr "type" "f_cvt")]
1036 )
1037
1038 (define_insn "*floatsidf2_vfp"
1039   [(set (match_operand:DF           0 "s_register_operand" "=w")
1040         (float:DF (match_operand:SI 1 "s_register_operand" "t")))]
1041   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1042   "fsitod%?\\t%P0, %1"
1043   [(set_attr "predicable" "yes")
1044    (set_attr "type" "f_cvt")]
1045 )
1046
1047
1048 (define_insn "floatunssisf2"
1049   [(set (match_operand:SF           0 "s_register_operand" "=t")
1050         (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "t")))]
1051   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1052   "fuitos%?\\t%0, %1"
1053   [(set_attr "predicable" "yes")
1054    (set_attr "type" "f_cvt")]
1055 )
1056
1057 (define_insn "floatunssidf2"
1058   [(set (match_operand:DF           0 "s_register_operand" "=w")
1059         (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "t")))]
1060   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1061   "fuitod%?\\t%P0, %1"
1062   [(set_attr "predicable" "yes")
1063    (set_attr "type" "f_cvt")]
1064 )
1065
1066
1067 ;; Sqrt insns.
1068
1069 (define_insn "*sqrtsf2_vfp"
1070   [(set (match_operand:SF          0 "s_register_operand" "=t")
1071         (sqrt:SF (match_operand:SF 1 "s_register_operand" "t")))]
1072   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1073   "fsqrts%?\\t%0, %1"
1074   [(set_attr "predicable" "yes")
1075    (set_attr "type" "fdivs")]
1076 )
1077
1078 (define_insn "*sqrtdf2_vfp"
1079   [(set (match_operand:DF          0 "s_register_operand" "=w")
1080         (sqrt:DF (match_operand:DF 1 "s_register_operand" "w")))]
1081   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1082   "fsqrtd%?\\t%P0, %P1"
1083   [(set_attr "predicable" "yes")
1084    (set_attr "type" "fdivd")]
1085 )
1086
1087
1088 ;; Patterns to split/copy vfp condition flags.
1089
1090 (define_insn "*movcc_vfp"
1091   [(set (reg CC_REGNUM)
1092         (reg VFPCC_REGNUM))]
1093   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1094   "fmstat%?"
1095   [(set_attr "conds" "set")
1096    (set_attr "type" "f_flag")]
1097 )
1098
1099 (define_insn_and_split "*cmpsf_split_vfp"
1100   [(set (reg:CCFP CC_REGNUM)
1101         (compare:CCFP (match_operand:SF 0 "s_register_operand"  "t")
1102                       (match_operand:SF 1 "vfp_compare_operand" "tG")))]
1103   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1104   "#"
1105   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1106   [(set (reg:CCFP VFPCC_REGNUM)
1107         (compare:CCFP (match_dup 0)
1108                       (match_dup 1)))
1109    (set (reg:CCFP CC_REGNUM)
1110         (reg:CCFP VFPCC_REGNUM))]
1111   ""
1112 )
1113
1114 (define_insn_and_split "*cmpsf_trap_split_vfp"
1115   [(set (reg:CCFPE CC_REGNUM)
1116         (compare:CCFPE (match_operand:SF 0 "s_register_operand"  "t")
1117                        (match_operand:SF 1 "vfp_compare_operand" "tG")))]
1118   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1119   "#"
1120   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1121   [(set (reg:CCFPE VFPCC_REGNUM)
1122         (compare:CCFPE (match_dup 0)
1123                        (match_dup 1)))
1124    (set (reg:CCFPE CC_REGNUM)
1125         (reg:CCFPE VFPCC_REGNUM))]
1126   ""
1127 )
1128
1129 (define_insn_and_split "*cmpdf_split_vfp"
1130   [(set (reg:CCFP CC_REGNUM)
1131         (compare:CCFP (match_operand:DF 0 "s_register_operand"  "w")
1132                       (match_operand:DF 1 "vfp_compare_operand" "wG")))]
1133   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1134   "#"
1135   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1136   [(set (reg:CCFP VFPCC_REGNUM)
1137         (compare:CCFP (match_dup 0)
1138                        (match_dup 1)))
1139    (set (reg:CCFP CC_REGNUM)
1140         (reg:CCFP VFPCC_REGNUM))]
1141   ""
1142 )
1143
1144 (define_insn_and_split "*cmpdf_trap_split_vfp"
1145   [(set (reg:CCFPE CC_REGNUM)
1146         (compare:CCFPE (match_operand:DF 0 "s_register_operand"  "w")
1147                        (match_operand:DF 1 "vfp_compare_operand" "wG")))]
1148   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1149   "#"
1150   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1151   [(set (reg:CCFPE VFPCC_REGNUM)
1152         (compare:CCFPE (match_dup 0)
1153                        (match_dup 1)))
1154    (set (reg:CCFPE CC_REGNUM)
1155         (reg:CCFPE VFPCC_REGNUM))]
1156   ""
1157 )
1158
1159
1160 ;; Comparison patterns
1161
1162 (define_insn "*cmpsf_vfp"
1163   [(set (reg:CCFP VFPCC_REGNUM)
1164         (compare:CCFP (match_operand:SF 0 "s_register_operand"  "t,t")
1165                       (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
1166   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1167   "@
1168    fcmps%?\\t%0, %1
1169    fcmpzs%?\\t%0"
1170   [(set_attr "predicable" "yes")
1171    (set_attr "type" "fcmps")]
1172 )
1173
1174 (define_insn "*cmpsf_trap_vfp"
1175   [(set (reg:CCFPE VFPCC_REGNUM)
1176         (compare:CCFPE (match_operand:SF 0 "s_register_operand"  "t,t")
1177                        (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
1178   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1179   "@
1180    fcmpes%?\\t%0, %1
1181    fcmpezs%?\\t%0"
1182   [(set_attr "predicable" "yes")
1183    (set_attr "type" "fcmps")]
1184 )
1185
1186 (define_insn "*cmpdf_vfp"
1187   [(set (reg:CCFP VFPCC_REGNUM)
1188         (compare:CCFP (match_operand:DF 0 "s_register_operand"  "w,w")
1189                       (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1190   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1191   "@
1192    fcmpd%?\\t%P0, %P1
1193    fcmpzd%?\\t%P0"
1194   [(set_attr "predicable" "yes")
1195    (set_attr "type" "fcmpd")]
1196 )
1197
1198 (define_insn "*cmpdf_trap_vfp"
1199   [(set (reg:CCFPE VFPCC_REGNUM)
1200         (compare:CCFPE (match_operand:DF 0 "s_register_operand"  "w,w")
1201                        (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1202   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1203   "@
1204    fcmped%?\\t%P0, %P1
1205    fcmpezd%?\\t%P0"
1206   [(set_attr "predicable" "yes")
1207    (set_attr "type" "fcmpd")]
1208 )
1209
1210 ;; Fixed point to floating point conversions.
1211 (define_code_iterator FCVT [unsigned_float float])
1212 (define_code_attr FCVTI32typename [(unsigned_float "u32") (float "s32")])
1213
1214 (define_insn "*combine_vcvt_f32_<FCVTI32typename>"
1215   [(set (match_operand:SF 0 "s_register_operand" "=t")
1216         (mult:SF (FCVT:SF (match_operand:SI 1 "s_register_operand" "0"))
1217                  (match_operand 2
1218                         "const_double_vcvt_power_of_two_reciprocal" "Dt")))]
1219   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math"
1220   "vcvt%?.f32.<FCVTI32typename>\\t%0, %1, %v2"
1221  [(set_attr "predicable" "yes")
1222   (set_attr "type" "f_cvt")]
1223 )
1224
1225 ;; Not the ideal way of implementing this. Ideally we would be able to split
1226 ;; this into a move to a DP register and then a vcvt.f64.i32
1227 (define_insn "*combine_vcvt_f64_<FCVTI32typename>"
1228   [(set (match_operand:DF 0 "s_register_operand" "=x,x,w")
1229         (mult:DF (FCVT:DF (match_operand:SI 1 "s_register_operand" "r,t,r"))
1230                  (match_operand 2
1231                      "const_double_vcvt_power_of_two_reciprocal" "Dt,Dt,Dt")))]
1232   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math
1233   && !TARGET_VFP_SINGLE"
1234   "@
1235   vmov%?.f32\\t%0, %1\;vcvt%?.f64.<FCVTI32typename>\\t%P0, %P0, %v2
1236   vmov%?.f32\\t%0, %1\;vcvt%?.f64.<FCVTI32typename>\\t%P0, %P0, %v2
1237   vmov%?.f64\\t%P0, %1, %1\;vcvt%?.f64.<FCVTI32typename>\\t%P0, %P0, %v2"
1238  [(set_attr "predicable" "yes")
1239   (set_attr "ce_count" "2")
1240   (set_attr "type" "f_cvt")
1241   (set_attr "length" "8")]
1242 )
1243
1244 ;; Store multiple insn used in function prologue.
1245 (define_insn "*push_multi_vfp"
1246   [(match_parallel 2 "multi_register_push"
1247     [(set (match_operand:BLK 0 "memory_operand" "=m")
1248           (unspec:BLK [(match_operand:DF 1 "vfp_register_operand" "")]
1249                       UNSPEC_PUSH_MULT))])]
1250   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP"
1251   "* return vfp_output_fstmd (operands);"
1252   [(set_attr "type" "f_stored")]
1253 )
1254
1255 ;; VRINT round to integral instructions.
1256 ;; Invoked for the patterns: btruncsf2, btruncdf2, ceilsf2, ceildf2,
1257 ;; roundsf2, rounddf2, floorsf2, floordf2, nearbyintsf2, nearbyintdf2,
1258 ;; rintsf2, rintdf2.
1259 (define_insn "<vrint_pattern><SDF:mode>2"
1260   [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
1261         (unspec:SDF [(match_operand:SDF 1
1262                          "register_operand" "<F_constraint>")]
1263          VRINT))]
1264   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
1265   "vrint<vrint_variant>%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1"
1266   [(set_attr "predicable" "<vrint_predicable>")
1267    (set_attr "type" "f_rint<vfp_type>")]
1268 )
1269
1270 ;; MIN_EXPR and MAX_EXPR eventually map to 'smin' and 'smax' in RTL.
1271 ;; The 'smax' and 'smin' RTL standard pattern names do not specify which
1272 ;; operand will be returned when both operands are zero (i.e. they may not
1273 ;; honour signed zeroes), or when either operand is NaN.  Therefore GCC
1274 ;; only introduces MIN_EXPR/MAX_EXPR in fast math mode or when not honouring
1275 ;; NaNs.
1276
1277 (define_insn "smax<mode>3"
1278   [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
1279         (smax:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>")
1280                   (match_operand:SDF 2 "register_operand" "<F_constraint>")))]
1281   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
1282   "vmaxnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1283   [(set_attr "type" "f_minmax<vfp_type>")]
1284 )
1285
1286 (define_insn "smin<mode>3"
1287   [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
1288         (smin:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>")
1289                   (match_operand:SDF 2 "register_operand" "<F_constraint>")))]
1290   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
1291   "vminnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1292   [(set_attr "type" "f_minmax<vfp_type>")]
1293 )
1294
1295 ;; Unimplemented insns:
1296 ;; fldm*
1297 ;; fstm*
1298 ;; fmdhr et al (VFPv1)
1299 ;; Support for xD (single precision only) variants.
1300 ;; fmrrs, fmsrr