[ARM] PR71607: Fix ICE when loading constant
[official-gcc.git] / gcc / config / arm / vfp.md
blobd8f77e2ffe4fdb7c952d6a5ac947d91f89ce259d
1 ;; ARM VFP instruction patterns
2 ;; Copyright (C) 2003-2017 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.
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.  */
21 ;; Patterns for HI moves which provide more data transfer instructions when VFP
22 ;; support is enabled.
23 (define_insn "*arm_movhi_vfp"
24  [(set
25    (match_operand:HI 0 "nonimmediate_operand"
26     "=rk,  r, r, m, r, *t,  r, *t")
27    (match_operand:HI 1 "general_operand"
28     "rIk, K, n, r, mi, r, *t, *t"))]
29  "TARGET_ARM && TARGET_HARD_FLOAT
30   && !TARGET_VFP_FP16INST
31   && (register_operand (operands[0], HImode)
32        || register_operand (operands[1], HImode))"
34   switch (which_alternative)
35     {
36     case 0:
37       return "mov%?\t%0, %1\t%@ movhi";
38     case 1:
39       return "mvn%?\t%0, #%B1\t%@ movhi";
40     case 2:
41       return "movw%?\t%0, %L1\t%@ movhi";
42     case 3:
43       return "strh%?\t%1, %0\t%@ movhi";
44     case 4:
45       return "ldrh%?\t%0, %1\t%@ movhi";
46     case 5:
47     case 6:
48       return "vmov%?\t%0, %1\t%@ int";
49     case 7:
50       return "vmov%?.f32\t%0, %1\t%@ int";
51     default:
52       gcc_unreachable ();
53     }
55  [(set_attr "predicable" "yes")
56   (set_attr_alternative "type"
57    [(if_then_else
58      (match_operand 1 "const_int_operand" "")
59      (const_string "mov_imm")
60      (const_string "mov_reg"))
61     (const_string "mvn_imm")
62     (const_string "mov_imm")
63     (const_string "store1")
64     (const_string "load1")
65     (const_string "f_mcr")
66     (const_string "f_mrc")
67     (const_string "fmov")])
68   (set_attr "arch" "*, *, v6t2, *, *, *, *, *")
69   (set_attr "pool_range" "*, *, *, *, 256, *, *, *")
70   (set_attr "neg_pool_range" "*, *, *, *, 244, *, *, *")
71   (set_attr "length" "4")]
74 (define_insn "*thumb2_movhi_vfp"
75  [(set
76    (match_operand:HI 0 "nonimmediate_operand"
77     "=rk, r, l, r, m, r, *t, r, *t")
78    (match_operand:HI 1 "general_operand"
79     "rk, I, Py, n, r, m, r, *t, *t"))]
80  "TARGET_THUMB2 && TARGET_HARD_FLOAT
81   && !TARGET_VFP_FP16INST
82   && (register_operand (operands[0], HImode)
83        || register_operand (operands[1], HImode))"
85   switch (which_alternative)
86     {
87     case 0:
88     case 1:
89     case 2:
90       return "mov%?\t%0, %1\t%@ movhi";
91     case 3:
92       return "movw%?\t%0, %L1\t%@ movhi";
93     case 4:
94       return "strh%?\t%1, %0\t%@ movhi";
95     case 5:
96       return "ldrh%?\t%0, %1\t%@ movhi";
97     case 6:
98     case 7:
99       return "vmov%?\t%0, %1\t%@ int";
100     case 8:
101       return "vmov%?.f32\t%0, %1\t%@ int";
102     default:
103       gcc_unreachable ();
104     }
106  [(set_attr "predicable" "yes")
107   (set_attr "predicable_short_it"
108    "yes, no, yes, no, no, no, no, no, no")
109   (set_attr "type"
110    "mov_reg, mov_imm, mov_imm, mov_imm, store1, load1,\
111     f_mcr, f_mrc, fmov")
112   (set_attr "arch" "*, *, *, v6t2, *, *, *, *, *")
113   (set_attr "pool_range" "*, *, *, *, *, 4094, *, *, *")
114   (set_attr "neg_pool_range" "*, *, *, *, *, 250, *, *, *")
115   (set_attr "length" "2, 4, 2, 4, 4, 4, 4, 4, 4")]
118 ;; Patterns for HI moves which provide more data transfer instructions when FP16
119 ;; instructions are available.
120 (define_insn "*arm_movhi_fp16"
121  [(set
122    (match_operand:HI 0 "nonimmediate_operand"
123     "=r,  r, r, m, r, *t,  r, *t")
124    (match_operand:HI 1 "general_operand"
125     "rIk, K, n, r, mi, r, *t, *t"))]
126  "TARGET_ARM && TARGET_VFP_FP16INST
127   && (register_operand (operands[0], HImode)
128        || register_operand (operands[1], HImode))"
130   switch (which_alternative)
131     {
132     case 0:
133       return "mov%?\t%0, %1\t%@ movhi";
134     case 1:
135       return "mvn%?\t%0, #%B1\t%@ movhi";
136     case 2:
137       return "movw%?\t%0, %L1\t%@ movhi";
138     case 3:
139       return "strh%?\t%1, %0\t%@ movhi";
140     case 4:
141       return "ldrh%?\t%0, %1\t%@ movhi";
142     case 5:
143     case 6:
144       return "vmov.f16\t%0, %1\t%@ int";
145     case 7:
146       return "vmov%?.f32\t%0, %1\t%@ int";
147     default:
148       gcc_unreachable ();
149     }
151  [(set_attr "predicable" "yes, yes, yes, yes, yes, no, no, yes")
152   (set_attr_alternative "type"
153    [(if_then_else
154      (match_operand 1 "const_int_operand" "")
155      (const_string "mov_imm")
156      (const_string "mov_reg"))
157     (const_string "mvn_imm")
158     (const_string "mov_imm")
159     (const_string "store1")
160     (const_string "load1")
161     (const_string "f_mcr")
162     (const_string "f_mrc")
163     (const_string "fmov")])
164   (set_attr "arch" "*, *, v6t2, *, *, *, *, *")
165   (set_attr "pool_range" "*, *, *, *, 256, *, *, *")
166   (set_attr "neg_pool_range" "*, *, *, *, 244, *, *, *")
167   (set_attr "length" "4")]
170 (define_insn "*thumb2_movhi_fp16"
171  [(set
172    (match_operand:HI 0 "nonimmediate_operand"
173     "=rk, r, l, r, m, r, *t, r, *t")
174    (match_operand:HI 1 "general_operand"
175     "rk, I, Py, n, r, m, r, *t, *t"))]
176  "TARGET_THUMB2 && TARGET_VFP_FP16INST
177   && (register_operand (operands[0], HImode)
178        || register_operand (operands[1], HImode))"
180   switch (which_alternative)
181     {
182     case 0:
183     case 1:
184     case 2:
185       return "mov%?\t%0, %1\t%@ movhi";
186     case 3:
187       return "movw%?\t%0, %L1\t%@ movhi";
188     case 4:
189       return "strh%?\t%1, %0\t%@ movhi";
190     case 5:
191       return "ldrh%?\t%0, %1\t%@ movhi";
192     case 6:
193     case 7:
194       return "vmov.f16\t%0, %1\t%@ int";
195     case 8:
196       return "vmov%?.f32\t%0, %1\t%@ int";
197     default:
198       gcc_unreachable ();
199     }
201  [(set_attr "predicable"
202    "yes, yes, yes, yes, yes, yes, no, no, yes")
203   (set_attr "predicable_short_it"
204    "yes, no, yes, no, no, no, no, no, no")
205   (set_attr "type"
206    "mov_reg, mov_imm, mov_imm, mov_imm, store1, load1,\
207     f_mcr, f_mrc, fmov")
208   (set_attr "arch" "*, *, *, v6t2, *, *, *, *, *")
209   (set_attr "pool_range" "*, *, *, *, *, 4094, *, *, *")
210   (set_attr "neg_pool_range" "*, *, *, *, *, 250, *, *, *")
211   (set_attr "length" "2, 4, 2, 4, 4, 4, 4, 4, 4")]
214 ;; SImode moves
215 ;; ??? For now do not allow loading constants into vfp regs.  This causes
216 ;; problems because small constants get converted into adds.
217 (define_insn "*arm_movsi_vfp"
218   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m ,*t,r,*t,*t, *Uv")
219       (match_operand:SI 1 "general_operand"        "rk, I,K,j,mi,rk,r,*t,*t,*Uvi,*t"))]
220   "TARGET_ARM && TARGET_HARD_FLOAT
221    && (   s_register_operand (operands[0], SImode)
222        || s_register_operand (operands[1], SImode))"
223   "*
224   switch (which_alternative)
225     {
226     case 0: case 1:
227       return \"mov%?\\t%0, %1\";
228     case 2:
229       return \"mvn%?\\t%0, #%B1\";
230     case 3:
231       return \"movw%?\\t%0, %1\";
232     case 4:
233       return \"ldr%?\\t%0, %1\";
234     case 5:
235       return \"str%?\\t%1, %0\";
236     case 6:
237       return \"vmov%?\\t%0, %1\\t%@ int\";
238     case 7:
239       return \"vmov%?\\t%0, %1\\t%@ int\";
240     case 8:
241       return \"vmov%?.f32\\t%0, %1\\t%@ int\";
242     case 9: case 10:
243       return output_move_vfp (operands);
244     default:
245       gcc_unreachable ();
246     }
247   "
248   [(set_attr "predicable" "yes")
249    (set_attr "type" "mov_reg,mov_reg,mvn_imm,mov_imm,load1,store1,
250                      f_mcr,f_mrc,fmov,f_loads,f_stores")
251    (set_attr "pool_range"     "*,*,*,*,4096,*,*,*,*,1020,*")
252    (set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")]
255 ;; See thumb2.md:thumb2_movsi_insn for an explanation of the split
256 ;; high/low register alternatives for loads and stores here.
257 ;; The l/Py alternative should come after r/I to ensure that the short variant
258 ;; is chosen with length 2 when the instruction is predicated for
259 ;; arm_restrict_it.
260 (define_insn "*thumb2_movsi_vfp"
261   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r, l,*hk,m, *m,*t, r,*t,*t,  *Uv")
262         (match_operand:SI 1 "general_operand"      "rk,I,Py,K,j,mi,*mi,l,*hk, r,*t,*t,*Uvi,*t"))]
263   "TARGET_THUMB2 && TARGET_HARD_FLOAT
264    && (   s_register_operand (operands[0], SImode)
265        || s_register_operand (operands[1], SImode))"
266   "*
267   switch (which_alternative)
268     {
269     case 0:
270     case 1:
271     case 2:
272       return \"mov%?\\t%0, %1\";
273     case 3:
274       return \"mvn%?\\t%0, #%B1\";
275     case 4:
276       return \"movw%?\\t%0, %1\";
277     case 5:
278     case 6:
279       return \"ldr%?\\t%0, %1\";
280     case 7:
281     case 8:
282       return \"str%?\\t%1, %0\";
283     case 9:
284       return \"vmov%?\\t%0, %1\\t%@ int\";
285     case 10:
286       return \"vmov%?\\t%0, %1\\t%@ int\";
287     case 11:
288       return \"vmov%?.f32\\t%0, %1\\t%@ int\";
289     case 12: case 13:
290       return output_move_vfp (operands);
291     default:
292       gcc_unreachable ();
293     }
294   "
295   [(set_attr "predicable" "yes")
296    (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no,no,no,no,no,no")
297    (set_attr "type" "mov_reg,mov_reg,mov_reg,mvn_reg,mov_imm,load1,load1,store1,store1,f_mcr,f_mrc,fmov,f_loads,f_stores")
298    (set_attr "length" "2,4,2,4,4,4,4,4,4,4,4,4,4,4")
299    (set_attr "pool_range"     "*,*,*,*,*,1018,4094,*,*,*,*,*,1018,*")
300    (set_attr "neg_pool_range" "*,*,*,*,*,   0,   0,*,*,*,*,*,1008,*")]
304 ;; DImode moves
306 (define_insn "*movdi_vfp"
307   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,q,q,m,w,r,w,w, Uv")
308        (match_operand:DI 1 "di_operand"              "r,rDa,Db,Dc,mi,mi,q,r,w,w,Uvi,w"))]
309   "TARGET_32BIT && TARGET_HARD_FLOAT && arm_tune != TARGET_CPU_cortexa8
310    && (   register_operand (operands[0], DImode)
311        || register_operand (operands[1], DImode))
312    && !(TARGET_NEON && CONST_INT_P (operands[1])
313         && neon_immediate_valid_for_move (operands[1], DImode, NULL, NULL))"
314   "*
315   switch (which_alternative)
316     {
317     case 0: 
318     case 1:
319     case 2:
320     case 3:
321       return \"#\";
322     case 4:
323     case 5:
324     case 6:
325       return output_move_double (operands, true, NULL);
326     case 7:
327       return \"vmov%?\\t%P0, %Q1, %R1\\t%@ int\";
328     case 8:
329       return \"vmov%?\\t%Q0, %R0, %P1\\t%@ int\";
330     case 9:
331       if (TARGET_VFP_SINGLE)
332         return \"vmov%?.f32\\t%0, %1\\t%@ int\;vmov%?.f32\\t%p0, %p1\\t%@ int\";
333       else
334         return \"vmov%?.f64\\t%P0, %P1\\t%@ int\";
335     case 10: case 11:
336       return output_move_vfp (operands);
337     default:
338       gcc_unreachable ();
339     }
340   "
341   [(set_attr "type" "multiple,multiple,multiple,multiple,load2,load2,store2,f_mcrr,f_mrrc,ffarithd,f_loadd,f_stored")
342    (set (attr "length") (cond [(eq_attr "alternative" "1,4,5,6") (const_int 8)
343                               (eq_attr "alternative" "2") (const_int 12)
344                               (eq_attr "alternative" "3") (const_int 16)
345                               (eq_attr "alternative" "9")
346                                (if_then_else
347                                  (match_test "TARGET_VFP_SINGLE")
348                                  (const_int 8)
349                                  (const_int 4))]
350                               (const_int 4)))
351    (set_attr "arm_pool_range"     "*,*,*,*,1020,4096,*,*,*,*,1020,*")
352    (set_attr "thumb2_pool_range"     "*,*,*,*,1018,4094,*,*,*,*,1018,*")
353    (set_attr "neg_pool_range" "*,*,*,*,1004,0,*,*,*,*,1004,*")
354    (set_attr "arch"           "t2,any,any,any,a,t2,any,any,any,any,any,any")]
357 (define_insn "*movdi_vfp_cortexa8"
358   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r,r,r,r,q,q,m,w,!r,w,w, Uv")
359         (match_operand:DI 1 "di_operand"                "r,rDa,Db,Dc,mi,mi,q,r,w,w,Uvi,w"))]
360   "TARGET_32BIT && TARGET_HARD_FLOAT && arm_tune == TARGET_CPU_cortexa8
361     && (   register_operand (operands[0], DImode)
362         || register_operand (operands[1], DImode))
363     && !(TARGET_NEON && CONST_INT_P (operands[1])
364          && neon_immediate_valid_for_move (operands[1], DImode, NULL, NULL))"
365   "*
366   switch (which_alternative)
367     {
368     case 0: 
369     case 1:
370     case 2:
371     case 3:
372       return \"#\";
373     case 4:
374     case 5:
375     case 6:
376       return output_move_double (operands, true, NULL);
377     case 7:
378       return \"vmov%?\\t%P0, %Q1, %R1\\t%@ int\";
379     case 8:
380       return \"vmov%?\\t%Q0, %R0, %P1\\t%@ int\";
381     case 9:
382       return \"vmov%?.f64\\t%P0, %P1\\t%@ int\";
383     case 10: case 11:
384       return output_move_vfp (operands);
385     default:
386       gcc_unreachable ();
387     }
388   "
389   [(set_attr "type" "multiple,multiple,multiple,multiple,load2,load2,store2,f_mcrr,f_mrrc,ffarithd,f_loadd,f_stored")
390    (set (attr "length") (cond [(eq_attr "alternative" "1") (const_int 8)
391                                (eq_attr "alternative" "2") (const_int 12)
392                                (eq_attr "alternative" "3") (const_int 16)
393                                (eq_attr "alternative" "4,5,6") 
394                                (symbol_ref 
395                                 "arm_count_output_move_double_insns (operands) \
396                                  * 4")]
397                               (const_int 4)))
398    (set_attr "predicable"    "yes")
399    (set_attr "arm_pool_range"     "*,*,*,*,1018,4094,*,*,*,*,1018,*")
400    (set_attr "thumb2_pool_range"     "*,*,*,*,1018,4094,*,*,*,*,1018,*")
401    (set_attr "neg_pool_range" "*,*,*,*,1004,0,*,*,*,*,1004,*")
402    (set (attr "ce_count") 
403         (symbol_ref "get_attr_length (insn) / 4"))
404    (set_attr "arch"           "t2,any,any,any,a,t2,any,any,any,any,any,any")]
407 ;; HFmode moves
409 (define_insn "*movhf_vfp_fp16"
410   [(set (match_operand:HF 0 "nonimmediate_operand"
411                           "= r,m,t,r,t,r,t,t,Um,r")
412         (match_operand:HF 1 "general_operand"
413                           "  m,r,t,r,r,t,Dv,Um,t,F"))]
414   "TARGET_32BIT
415    && TARGET_VFP_FP16INST
416    && (s_register_operand (operands[0], HFmode)
417        || s_register_operand (operands[1], HFmode))"
419   switch (which_alternative)
420     {
421     case 0: /* ARM register from memory.  */
422       return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
423     case 1: /* Memory from ARM register.  */
424       return \"strh%?\\t%1, %0\\t%@ __fp16\";
425     case 2: /* S register from S register.  */
426       return \"vmov\\t%0, %1\t%@ __fp16\";
427     case 3: /* ARM register from ARM register.  */
428       return \"mov%?\\t%0, %1\\t%@ __fp16\";
429     case 4: /* S register from ARM register.  */
430     case 5: /* ARM register from S register.  */
431     case 6: /* S register from immediate.  */
432       return \"vmov.f16\\t%0, %1\t%@ __fp16\";
433     case 7: /* S register from memory.  */
434       return \"vld1.16\\t{%z0}, %A1\";
435     case 8: /* Memory from S register.  */
436       return \"vst1.16\\t{%z1}, %A0\";
437     case 9: /* ARM register from constant.  */
438       {
439         long bits;
440         rtx ops[4];
442         bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
443                                HFmode);
444         ops[0] = operands[0];
445         ops[1] = GEN_INT (bits);
446         ops[2] = GEN_INT (bits & 0xff00);
447         ops[3] = GEN_INT (bits & 0x00ff);
449         if (arm_arch_thumb2)
450           output_asm_insn (\"movw\\t%0, %1\", ops);
451         else
452           output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops);
453         return \"\";
454        }
455     default:
456       gcc_unreachable ();
457     }
459   [(set_attr "predicable" "yes, yes, no, yes, no, no, no, no, no, no")
460    (set_attr "predicable_short_it" "no, no, no, yes,\
461                                     no, no, no, no,\
462                                     no, no")
463    (set_attr_alternative "type"
464     [(const_string "load1") (const_string "store1")
465      (const_string "fmov") (const_string "mov_reg")
466      (const_string "f_mcr") (const_string "f_mrc")
467      (const_string "fconsts") (const_string "neon_load1_1reg")
468      (const_string "neon_store1_1reg")
469      (if_then_else (match_test "arm_arch_thumb2")
470       (const_string "mov_imm")
471       (const_string "multiple"))])
472    (set_attr_alternative "length"
473     [(const_int 4) (const_int 4)
474      (const_int 4) (const_int 4)
475      (const_int 4) (const_int 4)
476      (const_int 4) (const_int 4)
477      (const_int 4)
478      (if_then_else (match_test "arm_arch_thumb2")
479       (const_int 4)
480       (const_int 8))])]
483 (define_insn "*movhf_vfp_neon"
484   [(set (match_operand:HF 0 "nonimmediate_operand" "= t,Um,r,m,t,r,t,r,r")
485         (match_operand:HF 1 "general_operand"      " Um, t,m,r,t,r,r,t,F"))]
486   "TARGET_32BIT
487    && TARGET_HARD_FLOAT && TARGET_NEON_FP16
488    && !TARGET_VFP_FP16INST
489    && (   s_register_operand (operands[0], HFmode)
490        || s_register_operand (operands[1], HFmode))"
491   "*
492   switch (which_alternative)
493     {
494     case 0:     /* S register from memory */
495       return \"vld1.16\\t{%z0}, %A1\";
496     case 1:     /* memory from S register */
497       return \"vst1.16\\t{%z1}, %A0\";
498     case 2:     /* ARM register from memory */
499       return \"ldrh\\t%0, %1\\t%@ __fp16\";
500     case 3:     /* memory from ARM register */
501       return \"strh\\t%1, %0\\t%@ __fp16\";
502     case 4:     /* S register from S register */
503       return \"vmov.f32\\t%0, %1\";
504     case 5:     /* ARM register from ARM register */
505       return \"mov\\t%0, %1\\t%@ __fp16\";
506     case 6:     /* S register from ARM register */
507       return \"vmov\\t%0, %1\";
508     case 7:     /* ARM register from S register */
509       return \"vmov\\t%0, %1\";
510     case 8:     /* ARM register from constant */
511       {
512         long bits;
513         rtx ops[4];
515         bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
516                                HFmode);
517         ops[0] = operands[0];
518         ops[1] = GEN_INT (bits);
519         ops[2] = GEN_INT (bits & 0xff00);
520         ops[3] = GEN_INT (bits & 0x00ff);
522         if (arm_arch_thumb2)
523           output_asm_insn (\"movw\\t%0, %1\", ops);
524         else
525           output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops);
526         return \"\";
527        }
528     default:
529       gcc_unreachable ();
530     }
531   "
532   [(set_attr "conds" "unconditional")
533    (set_attr "type" "neon_load1_1reg,neon_store1_1reg,\
534                      load1,store1,fmov,mov_reg,f_mcr,f_mrc,multiple")
535    (set_attr "length" "4,4,4,4,4,4,4,4,8")]
538 ;; FP16 without element load/store instructions.
539 (define_insn "*movhf_vfp"
540   [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,t,r,t,r,r")
541         (match_operand:HF 1 "general_operand"      " m,r,t,r,r,t,F"))]
542   "TARGET_32BIT
543    && TARGET_HARD_FLOAT
544    && !TARGET_NEON_FP16
545    && !TARGET_VFP_FP16INST
546    && (   s_register_operand (operands[0], HFmode)
547        || s_register_operand (operands[1], HFmode))"
548   "*
549   switch (which_alternative)
550     {
551     case 0:     /* ARM register from memory */
552       return \"ldrh\\t%0, %1\\t%@ __fp16\";
553     case 1:     /* memory from ARM register */
554       return \"strh\\t%1, %0\\t%@ __fp16\";
555     case 2:     /* S register from S register */
556       return \"vmov.f32\\t%0, %1\";
557     case 3:     /* ARM register from ARM register */
558       return \"mov\\t%0, %1\\t%@ __fp16\";
559     case 4:     /* S register from ARM register */
560       return \"vmov\\t%0, %1\";
561     case 5:     /* ARM register from S register */
562       return \"vmov\\t%0, %1\";
563     case 6:     /* ARM register from constant */
564       {
565         long bits;
566         rtx ops[4];
568         bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
569                                HFmode);
570         ops[0] = operands[0];
571         ops[1] = GEN_INT (bits);
572         ops[2] = GEN_INT (bits & 0xff00);
573         ops[3] = GEN_INT (bits & 0x00ff);
575         if (arm_arch_thumb2)
576           output_asm_insn (\"movw\\t%0, %1\", ops);
577         else
578           output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops);
579         return \"\";
580        }
581     default:
582       gcc_unreachable ();
583     }
584   "
585   [(set_attr "conds" "unconditional")
586    (set_attr "type" "load1,store1,fmov,mov_reg,f_mcr,f_mrc,multiple")
587    (set_attr "length" "4,4,4,4,4,4,8")]
591 ;; SFmode moves
592 ;; Disparage the w<->r cases because reloading an invalid address is
593 ;; preferable to loading the value via integer registers.
595 (define_insn "*movsf_vfp"
596   [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t ,t  ,Uv,r ,m,t,r")
597         (match_operand:SF 1 "general_operand"      " ?r,t,Dv,UvE,t, mE,r,t,r"))]
598   "TARGET_ARM && TARGET_HARD_FLOAT
599    && (   s_register_operand (operands[0], SFmode)
600        || s_register_operand (operands[1], SFmode))"
601   "*
602   switch (which_alternative)
603     {
604     case 0:
605       return \"vmov%?\\t%0, %1\";
606     case 1:
607       return \"vmov%?\\t%0, %1\";
608     case 2:
609       return \"vmov%?.f32\\t%0, %1\";
610     case 3: case 4:
611       return output_move_vfp (operands);
612     case 5:
613       return \"ldr%?\\t%0, %1\\t%@ float\";
614     case 6:
615       return \"str%?\\t%1, %0\\t%@ float\";
616     case 7:
617       return \"vmov%?.f32\\t%0, %1\";
618     case 8:
619       return \"mov%?\\t%0, %1\\t%@ float\";
620     default:
621       gcc_unreachable ();
622     }
623   "
624   [(set_attr "predicable" "yes")
625    (set_attr "type"
626      "f_mcr,f_mrc,fconsts,f_loads,f_stores,load1,store1,fmov,mov_reg")
627    (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*")
628    (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")]
631 (define_insn "*thumb2_movsf_vfp"
632   [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t, t  ,Uv,r ,m,t,r")
633         (match_operand:SF 1 "general_operand"      " ?r,t,Dv,UvE,t, mE,r,t,r"))]
634   "TARGET_THUMB2 && TARGET_HARD_FLOAT
635    && (   s_register_operand (operands[0], SFmode)
636        || s_register_operand (operands[1], SFmode))"
637   "*
638   switch (which_alternative)
639     {
640     case 0:
641       return \"vmov%?\\t%0, %1\";
642     case 1:
643       return \"vmov%?\\t%0, %1\";
644     case 2:
645       return \"vmov%?.f32\\t%0, %1\";
646     case 3: case 4:
647       return output_move_vfp (operands);
648     case 5:
649       return \"ldr%?\\t%0, %1\\t%@ float\";
650     case 6:
651       return \"str%?\\t%1, %0\\t%@ float\";
652     case 7:
653       return \"vmov%?.f32\\t%0, %1\";
654     case 8:
655       return \"mov%?\\t%0, %1\\t%@ float\";
656     default:
657       gcc_unreachable ();
658     }
659   "
660   [(set_attr "predicable" "yes")
661    (set_attr "predicable_short_it" "no")
662    (set_attr "type"
663      "f_mcr,f_mrc,fconsts,f_loads,f_stores,load1,store1,fmov,mov_reg")
664    (set_attr "pool_range" "*,*,*,1018,*,4090,*,*,*")
665    (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")]
668 ;; DFmode moves
670 (define_insn "*movdf_vfp"
671   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w,w  ,Uv,r, m,w,r")
672         (match_operand:DF 1 "soft_df_operand"              " ?r,w,Dy,G,UvF,w ,mF,r,w,r"))]
673   "TARGET_ARM && TARGET_HARD_FLOAT
674    && (   register_operand (operands[0], DFmode)
675        || register_operand (operands[1], DFmode))"
676   "*
677   {
678     switch (which_alternative)
679       {
680       case 0:
681         return \"vmov%?\\t%P0, %Q1, %R1\";
682       case 1:
683         return \"vmov%?\\t%Q0, %R0, %P1\";
684       case 2:
685         gcc_assert (TARGET_VFP_DOUBLE);
686         return \"vmov%?.f64\\t%P0, %1\";
687       case 3:
688         gcc_assert (TARGET_VFP_DOUBLE);
689         return \"vmov.i64\\t%P0, #0\\t%@ float\";
690       case 4: case 5:
691         return output_move_vfp (operands);
692       case 6: case 7:
693         return output_move_double (operands, true, NULL);
694       case 8:
695         if (TARGET_VFP_SINGLE)
696           return \"vmov%?.f32\\t%0, %1\;vmov%?.f32\\t%p0, %p1\";
697         else
698           return \"vmov%?.f64\\t%P0, %P1\";
699       case 9:
700         return \"#\";
701       default:
702         gcc_unreachable ();
703       }
704     }
705   "
706   [(set_attr "type" "f_mcrr,f_mrrc,fconstd,neon_move,f_loadd,f_stored,\
707                      load2,store2,ffarithd,multiple")
708    (set (attr "length") (cond [(eq_attr "alternative" "6,7,9") (const_int 8)
709                                (eq_attr "alternative" "8")
710                                 (if_then_else
711                                  (match_test "TARGET_VFP_SINGLE")
712                                  (const_int 8)
713                                  (const_int 4))]
714                               (const_int 4)))
715    (set_attr "predicable" "yes,yes,yes,no,yes,yes,yes,yes,yes,yes")
716    (set_attr "pool_range" "*,*,*,*,1020,*,1020,*,*,*")
717    (set_attr "neg_pool_range" "*,*,*,*,1004,*,1004,*,*,*")
718    (set_attr "arch" "any,any,any,neon,any,any,any,any,any,any")]
721 (define_insn "*thumb2_movdf_vfp"
722   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w,w  ,Uv,r ,m,w,r")
723         (match_operand:DF 1 "soft_df_operand"              " ?r,w,Dy,G,UvF,w, mF,r, w,r"))]
724   "TARGET_THUMB2 && TARGET_HARD_FLOAT
725    && (   register_operand (operands[0], DFmode)
726        || register_operand (operands[1], DFmode))"
727   "*
728   {
729     switch (which_alternative)
730       {
731       case 0:
732         return \"vmov%?\\t%P0, %Q1, %R1\";
733       case 1:
734         return \"vmov%?\\t%Q0, %R0, %P1\";
735       case 2:
736         gcc_assert (TARGET_VFP_DOUBLE);
737         return \"vmov%?.f64\\t%P0, %1\";
738       case 3:
739         gcc_assert (TARGET_VFP_DOUBLE);
740         return \"vmov.i64\\t%P0, #0\\t%@ float\";
741       case 4: case 5:
742         return output_move_vfp (operands);
743       case 6: case 7: case 9:
744         return output_move_double (operands, true, NULL);
745       case 8:
746         if (TARGET_VFP_SINGLE)
747           return \"vmov%?.f32\\t%0, %1\;vmov%?.f32\\t%p0, %p1\";
748         else
749           return \"vmov%?.f64\\t%P0, %P1\";
750       default:
751         abort ();
752       }
753     }
754   "
755   [(set_attr "type" "f_mcrr,f_mrrc,fconstd,neon_move,f_loadd,\
756                      f_stored,load2,store2,ffarithd,multiple")
757    (set (attr "length") (cond [(eq_attr "alternative" "6,7,9") (const_int 8)
758                                (eq_attr "alternative" "8")
759                                 (if_then_else
760                                  (match_test "TARGET_VFP_SINGLE")
761                                  (const_int 8)
762                                  (const_int 4))]
763                               (const_int 4)))
764    (set_attr "pool_range" "*,*,*,*,1018,*,4094,*,*,*")
765    (set_attr "neg_pool_range" "*,*,*,*,1008,*,0,*,*,*")
766    (set_attr "arch" "any,any,any,neon,any,any,any,any,any,any")]
770 ;; Conditional move patterns
772 (define_insn "*movsfcc_vfp"
773   [(set (match_operand:SF   0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
774         (if_then_else:SF
775           (match_operator   3 "arm_comparison_operator"
776             [(match_operand 4 "cc_register" "") (const_int 0)])
777           (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
778           (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
779   "TARGET_ARM && TARGET_HARD_FLOAT"
780   "@
781    vmov%D3.f32\\t%0, %2
782    vmov%d3.f32\\t%0, %1
783    vmov%D3.f32\\t%0, %2\;vmov%d3.f32\\t%0, %1
784    vmov%D3\\t%0, %2
785    vmov%d3\\t%0, %1
786    vmov%D3\\t%0, %2\;vmov%d3\\t%0, %1
787    vmov%D3\\t%0, %2
788    vmov%d3\\t%0, %1
789    vmov%D3\\t%0, %2\;vmov%d3\\t%0, %1"
790    [(set_attr "conds" "use")
791     (set_attr "length" "4,4,8,4,4,8,4,4,8")
792     (set_attr "type" "fmov,fmov,fmov,f_mcr,f_mcr,f_mcr,f_mrc,f_mrc,f_mrc")]
795 (define_insn "*thumb2_movsfcc_vfp"
796   [(set (match_operand:SF   0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
797         (if_then_else:SF
798           (match_operator   3 "arm_comparison_operator"
799             [(match_operand 4 "cc_register" "") (const_int 0)])
800           (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
801           (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
802   "TARGET_THUMB2 && TARGET_HARD_FLOAT && !arm_restrict_it"
803   "@
804    it\\t%D3\;vmov%D3.f32\\t%0, %2
805    it\\t%d3\;vmov%d3.f32\\t%0, %1
806    ite\\t%D3\;vmov%D3.f32\\t%0, %2\;vmov%d3.f32\\t%0, %1
807    it\\t%D3\;vmov%D3\\t%0, %2
808    it\\t%d3\;vmov%d3\\t%0, %1
809    ite\\t%D3\;vmov%D3\\t%0, %2\;vmov%d3\\t%0, %1
810    it\\t%D3\;vmov%D3\\t%0, %2
811    it\\t%d3\;vmov%d3\\t%0, %1
812    ite\\t%D3\;vmov%D3\\t%0, %2\;vmov%d3\\t%0, %1"
813    [(set_attr "conds" "use")
814     (set_attr "length" "6,6,10,6,6,10,6,6,10")
815     (set_attr "type" "fmov,fmov,fmov,f_mcr,f_mcr,f_mcr,f_mrc,f_mrc,f_mrc")]
818 (define_insn "*movdfcc_vfp"
819   [(set (match_operand:DF   0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
820         (if_then_else:DF
821           (match_operator   3 "arm_comparison_operator"
822             [(match_operand 4 "cc_register" "") (const_int 0)])
823           (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
824           (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
825   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
826   "@
827    vmov%D3.f64\\t%P0, %P2
828    vmov%d3.f64\\t%P0, %P1
829    vmov%D3.f64\\t%P0, %P2\;vmov%d3.f64\\t%P0, %P1
830    vmov%D3\\t%P0, %Q2, %R2
831    vmov%d3\\t%P0, %Q1, %R1
832    vmov%D3\\t%P0, %Q2, %R2\;vmov%d3\\t%P0, %Q1, %R1
833    vmov%D3\\t%Q0, %R0, %P2
834    vmov%d3\\t%Q0, %R0, %P1
835    vmov%D3\\t%Q0, %R0, %P2\;vmov%d3\\t%Q0, %R0, %P1"
836    [(set_attr "conds" "use")
837     (set_attr "length" "4,4,8,4,4,8,4,4,8")
838     (set_attr "type" "ffarithd,ffarithd,ffarithd,f_mcr,f_mcr,f_mcr,f_mrrc,f_mrrc,f_mrrc")]
841 (define_insn "*thumb2_movdfcc_vfp"
842   [(set (match_operand:DF   0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
843         (if_then_else:DF
844           (match_operator   3 "arm_comparison_operator"
845             [(match_operand 4 "cc_register" "") (const_int 0)])
846           (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
847           (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
848   "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE && !arm_restrict_it"
849   "@
850    it\\t%D3\;vmov%D3.f64\\t%P0, %P2
851    it\\t%d3\;vmov%d3.f64\\t%P0, %P1
852    ite\\t%D3\;vmov%D3.f64\\t%P0, %P2\;vmov%d3.f64\\t%P0, %P1
853    it\t%D3\;vmov%D3\\t%P0, %Q2, %R2
854    it\t%d3\;vmov%d3\\t%P0, %Q1, %R1
855    ite\\t%D3\;vmov%D3\\t%P0, %Q2, %R2\;vmov%d3\\t%P0, %Q1, %R1
856    it\t%D3\;vmov%D3\\t%Q0, %R0, %P2
857    it\t%d3\;vmov%d3\\t%Q0, %R0, %P1
858    ite\\t%D3\;vmov%D3\\t%Q0, %R0, %P2\;vmov%d3\\t%Q0, %R0, %P1"
859    [(set_attr "conds" "use")
860     (set_attr "length" "6,6,10,6,6,10,6,6,10")
861     (set_attr "type" "ffarithd,ffarithd,ffarithd,f_mcr,f_mcr,f_mcrr,f_mrrc,f_mrrc,f_mrrc")]
865 ;; Sign manipulation functions
867 (define_insn "*abssf2_vfp"
868   [(set (match_operand:SF         0 "s_register_operand" "=t")
869         (abs:SF (match_operand:SF 1 "s_register_operand" "t")))]
870   "TARGET_32BIT && TARGET_HARD_FLOAT"
871   "vabs%?.f32\\t%0, %1"
872   [(set_attr "predicable" "yes")
873    (set_attr "predicable_short_it" "no")
874    (set_attr "type" "ffariths")]
877 (define_insn "*absdf2_vfp"
878   [(set (match_operand:DF         0 "s_register_operand" "=w")
879         (abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
880   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
881   "vabs%?.f64\\t%P0, %P1"
882   [(set_attr "predicable" "yes")
883    (set_attr "predicable_short_it" "no")
884    (set_attr "type" "ffarithd")]
887 (define_insn "*negsf2_vfp"
888   [(set (match_operand:SF         0 "s_register_operand" "=t,?r")
889         (neg:SF (match_operand:SF 1 "s_register_operand" "t,r")))]
890   "TARGET_32BIT && TARGET_HARD_FLOAT"
891   "@
892    vneg%?.f32\\t%0, %1
893    eor%?\\t%0, %1, #-2147483648"
894   [(set_attr "predicable" "yes")
895    (set_attr "predicable_short_it" "no")
896    (set_attr "type" "ffariths")]
899 (define_insn_and_split "*negdf2_vfp"
900   [(set (match_operand:DF         0 "s_register_operand" "=w,?r,?r")
901         (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))]
902   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
903   "@
904    vneg%?.f64\\t%P0, %P1
905    #
906    #"
907   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE && reload_completed
908    && arm_general_register_operand (operands[0], DFmode)"
909   [(set (match_dup 0) (match_dup 1))]
910   "
911   if (REGNO (operands[0]) == REGNO (operands[1]))
912     {
913       operands[0] = gen_highpart (SImode, operands[0]);
914       operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000));
915     }
916   else
917     {
918       rtx in_hi, in_lo, out_hi, out_lo;
920       in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]),
921                            GEN_INT (0x80000000));
922       in_lo = gen_lowpart (SImode, operands[1]);
923       out_hi = gen_highpart (SImode, operands[0]);
924       out_lo = gen_lowpart (SImode, operands[0]);
926       if (REGNO (in_lo) == REGNO (out_hi))
927         {
928           emit_insn (gen_rtx_SET (out_lo, in_lo));
929           operands[0] = out_hi;
930           operands[1] = in_hi;
931         }
932       else
933         {
934           emit_insn (gen_rtx_SET (out_hi, in_hi));
935           operands[0] = out_lo;
936           operands[1] = in_lo;
937         }
938     }
939   "
940   [(set_attr "predicable" "yes")
941    (set_attr "predicable_short_it" "no")
942    (set_attr "length" "4,4,8")
943    (set_attr "type" "ffarithd")]
946 ;; ABS and NEG for FP16.
947 (define_insn "<absneg_str>hf2"
948   [(set (match_operand:HF 0 "s_register_operand" "=w")
949     (ABSNEG:HF (match_operand:HF 1 "s_register_operand" "w")))]
950  "TARGET_VFP_FP16INST"
951  "v<absneg_str>.f16\t%0, %1"
952   [(set_attr "conds" "unconditional")
953    (set_attr "type" "ffariths")]
956 (define_expand "neon_vabshf"
957  [(set
958    (match_operand:HF 0 "s_register_operand")
959    (abs:HF (match_operand:HF 1 "s_register_operand")))]
960  "TARGET_VFP_FP16INST"
962   emit_insn (gen_abshf2 (operands[0], operands[1]));
963   DONE;
966 ;; VRND for FP16.
967 (define_insn "neon_v<fp16_rnd_str>hf"
968   [(set (match_operand:HF 0 "s_register_operand" "=w")
969     (unspec:HF
970      [(match_operand:HF 1 "s_register_operand" "w")]
971      FP16_RND))]
972  "TARGET_VFP_FP16INST"
973  "<fp16_rnd_insn>.f16\t%0, %1"
974  [(set_attr "conds" "unconditional")
975   (set_attr "type" "neon_fp_round_s")]
978 (define_insn "neon_vrndihf"
979   [(set (match_operand:HF 0 "s_register_operand" "=w")
980     (unspec:HF
981      [(match_operand:HF 1 "s_register_operand" "w")]
982      UNSPEC_VRNDI))]
983   "TARGET_VFP_FP16INST"
984   "vrintr.f16\t%0, %1"
985  [(set_attr "conds" "unconditional")
986   (set_attr "type" "neon_fp_round_s")]
989 ;; Arithmetic insns
991 (define_insn "addhf3"
992   [(set
993     (match_operand:HF 0 "s_register_operand" "=w")
994     (plus:HF
995      (match_operand:HF 1 "s_register_operand" "w")
996      (match_operand:HF 2 "s_register_operand" "w")))]
997  "TARGET_VFP_FP16INST"
998  "vadd.f16\t%0, %1, %2"
999   [(set_attr "conds" "unconditional")
1000    (set_attr "type" "fadds")]
1003 (define_insn "*addsf3_vfp"
1004   [(set (match_operand:SF          0 "s_register_operand" "=t")
1005         (plus:SF (match_operand:SF 1 "s_register_operand" "t")
1006                  (match_operand:SF 2 "s_register_operand" "t")))]
1007   "TARGET_32BIT && TARGET_HARD_FLOAT"
1008   "vadd%?.f32\\t%0, %1, %2"
1009   [(set_attr "predicable" "yes")
1010    (set_attr "predicable_short_it" "no")
1011    (set_attr "type" "fadds")]
1014 (define_insn "*adddf3_vfp"
1015   [(set (match_operand:DF          0 "s_register_operand" "=w")
1016         (plus:DF (match_operand:DF 1 "s_register_operand" "w")
1017                  (match_operand:DF 2 "s_register_operand" "w")))]
1018   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1019   "vadd%?.f64\\t%P0, %P1, %P2"
1020   [(set_attr "predicable" "yes")
1021    (set_attr "predicable_short_it" "no")
1022    (set_attr "type" "faddd")]
1025 (define_insn "subhf3"
1026  [(set
1027    (match_operand:HF 0 "s_register_operand" "=w")
1028    (minus:HF
1029     (match_operand:HF 1 "s_register_operand" "w")
1030     (match_operand:HF 2 "s_register_operand" "w")))]
1031  "TARGET_VFP_FP16INST"
1032  "vsub.f16\t%0, %1, %2"
1033   [(set_attr "conds" "unconditional")
1034    (set_attr "type" "fadds")]
1037 (define_insn "*subsf3_vfp"
1038   [(set (match_operand:SF           0 "s_register_operand" "=t")
1039         (minus:SF (match_operand:SF 1 "s_register_operand" "t")
1040                   (match_operand:SF 2 "s_register_operand" "t")))]
1041   "TARGET_32BIT && TARGET_HARD_FLOAT"
1042   "vsub%?.f32\\t%0, %1, %2"
1043   [(set_attr "predicable" "yes")
1044    (set_attr "predicable_short_it" "no")
1045    (set_attr "type" "fadds")]
1048 (define_insn "*subdf3_vfp"
1049   [(set (match_operand:DF           0 "s_register_operand" "=w")
1050         (minus:DF (match_operand:DF 1 "s_register_operand" "w")
1051                   (match_operand:DF 2 "s_register_operand" "w")))]
1052   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1053   "vsub%?.f64\\t%P0, %P1, %P2"
1054   [(set_attr "predicable" "yes")
1055    (set_attr "predicable_short_it" "no")
1056    (set_attr "type" "faddd")]
1060 ;; Division insns
1062 ;; FP16 Division.
1063 (define_insn "divhf3"
1064   [(set
1065     (match_operand:HF      0 "s_register_operand" "=w")
1066     (div:HF
1067      (match_operand:HF 1 "s_register_operand" "w")
1068      (match_operand:HF 2 "s_register_operand" "w")))]
1069   "TARGET_VFP_FP16INST"
1070   "vdiv.f16\t%0, %1, %2"
1071   [(set_attr "conds" "unconditional")
1072    (set_attr "type" "fdivs")]
1075 ; VFP9 Erratum 760019: It's potentially unsafe to overwrite the input
1076 ; operands, so mark the output as early clobber for VFPv2 on ARMv5 or
1077 ; earlier.
1078 (define_insn "*divsf3_vfp"
1079   [(set (match_operand:SF         0 "s_register_operand" "=&t,t")
1080         (div:SF (match_operand:SF 1 "s_register_operand" "t,t")
1081                 (match_operand:SF 2 "s_register_operand" "t,t")))]
1082   "TARGET_32BIT && TARGET_HARD_FLOAT"
1083   "vdiv%?.f32\\t%0, %1, %2"
1084   [(set_attr "predicable" "yes")
1085    (set_attr "predicable_short_it" "no")
1086    (set_attr "arch" "*,armv6_or_vfpv3")
1087    (set_attr "type" "fdivs")]
1090 (define_insn "*divdf3_vfp"
1091   [(set (match_operand:DF         0 "s_register_operand" "=&w,w")
1092         (div:DF (match_operand:DF 1 "s_register_operand" "w,w")
1093                 (match_operand:DF 2 "s_register_operand" "w,w")))]
1094   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1095   "vdiv%?.f64\\t%P0, %P1, %P2"
1096   [(set_attr "predicable" "yes")
1097    (set_attr "predicable_short_it" "no")
1098    (set_attr "arch" "*,armv6_or_vfpv3")
1099    (set_attr "type" "fdivd")]
1103 ;; Multiplication insns
1105 (define_insn "mulhf3"
1106  [(set
1107    (match_operand:HF 0 "s_register_operand" "=w")
1108    (mult:HF (match_operand:HF 1 "s_register_operand" "w")
1109             (match_operand:HF 2 "s_register_operand" "w")))]
1110   "TARGET_VFP_FP16INST"
1111   "vmul.f16\t%0, %1, %2"
1112   [(set_attr "conds" "unconditional")
1113    (set_attr "type" "fmuls")]
1116 (define_insn "*mulsf3_vfp"
1117   [(set (match_operand:SF          0 "s_register_operand" "=t")
1118         (mult:SF (match_operand:SF 1 "s_register_operand" "t")
1119                  (match_operand:SF 2 "s_register_operand" "t")))]
1120   "TARGET_32BIT && TARGET_HARD_FLOAT"
1121   "vmul%?.f32\\t%0, %1, %2"
1122   [(set_attr "predicable" "yes")
1123    (set_attr "predicable_short_it" "no")
1124    (set_attr "type" "fmuls")]
1127 (define_insn "*muldf3_vfp"
1128   [(set (match_operand:DF          0 "s_register_operand" "=w")
1129         (mult:DF (match_operand:DF 1 "s_register_operand" "w")
1130                  (match_operand:DF 2 "s_register_operand" "w")))]
1131   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1132   "vmul%?.f64\\t%P0, %P1, %P2"
1133   [(set_attr "predicable" "yes")
1134    (set_attr "predicable_short_it" "no")
1135    (set_attr "type" "fmuld")]
1138 (define_insn "*mulsf3neghf_vfp"
1139   [(set (match_operand:HF                  0 "s_register_operand" "=t")
1140         (mult:HF (neg:HF (match_operand:HF 1 "s_register_operand" "t"))
1141                  (match_operand:HF         2 "s_register_operand" "t")))]
1142   "TARGET_VFP_FP16INST && !flag_rounding_math"
1143   "vnmul.f16\\t%0, %1, %2"
1144   [(set_attr "conds" "unconditional")
1145    (set_attr "type" "fmuls")]
1148 (define_insn "*negmulhf3_vfp"
1149   [(set (match_operand:HF                  0 "s_register_operand" "=t")
1150         (neg:HF (mult:HF (match_operand:HF 1 "s_register_operand" "t")
1151                  (match_operand:HF         2 "s_register_operand" "t"))))]
1152   "TARGET_VFP_FP16INST"
1153   "vnmul.f16\\t%0, %1, %2"
1154   [(set_attr "conds" "unconditional")
1155    (set_attr "type" "fmuls")]
1158 (define_insn "*mulsf3negsf_vfp"
1159   [(set (match_operand:SF                  0 "s_register_operand" "=t")
1160         (mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "t"))
1161                  (match_operand:SF         2 "s_register_operand" "t")))]
1162   "TARGET_32BIT && TARGET_HARD_FLOAT && !flag_rounding_math"
1163   "vnmul%?.f32\\t%0, %1, %2"
1164   [(set_attr "predicable" "yes")
1165    (set_attr "predicable_short_it" "no")
1166    (set_attr "type" "fmuls")]
1169 (define_insn "*negmulsf3_vfp"
1170   [(set (match_operand:SF                  0 "s_register_operand" "=t")
1171         (neg:SF (mult:SF (match_operand:SF 1 "s_register_operand" "t")
1172                  (match_operand:SF         2 "s_register_operand" "t"))))]
1173   "TARGET_32BIT && TARGET_HARD_FLOAT"
1174   "vnmul%?.f32\\t%0, %1, %2"
1175   [(set_attr "predicable" "yes")
1176    (set_attr "predicable_short_it" "no")
1177    (set_attr "type" "fmuls")]
1180 (define_insn "*muldf3negdf_vfp"
1181   [(set (match_operand:DF                  0 "s_register_operand" "=w")
1182         (mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
1183                  (match_operand:DF         2 "s_register_operand" "w")))]
1184   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE
1185   && !flag_rounding_math"
1186   "vnmul%?.f64\\t%P0, %P1, %P2"
1187   [(set_attr "predicable" "yes")
1188    (set_attr "predicable_short_it" "no")
1189    (set_attr "type" "fmuld")]
1192 (define_insn "*negmuldf3_vfp"
1193   [(set (match_operand:DF                  0 "s_register_operand" "=w")
1194         (neg:DF (mult:DF (match_operand:DF 1 "s_register_operand" "w")
1195                  (match_operand:DF         2 "s_register_operand" "w"))))]
1196   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1197   "vnmul%?.f64\\t%P0, %P1, %P2"
1198   [(set_attr "predicable" "yes")
1199    (set_attr "predicable_short_it" "no")
1200    (set_attr "type" "fmuld")]
1204 ;; Multiply-accumulate insns
1206 ;; 0 = 1 * 2 + 0
1207 (define_insn "*mulsf3addhf_vfp"
1208  [(set (match_operand:HF 0 "s_register_operand" "=t")
1209        (plus:HF
1210         (mult:HF (match_operand:HF 2 "s_register_operand" "t")
1211                  (match_operand:HF 3 "s_register_operand" "t"))
1212         (match_operand:HF 1 "s_register_operand" "0")))]
1213   "TARGET_VFP_FP16INST"
1214   "vmla.f16\\t%0, %2, %3"
1215   [(set_attr "conds" "unconditional")
1216    (set_attr "type" "fmacs")]
1219 (define_insn "*mulsf3addsf_vfp"
1220   [(set (match_operand:SF                   0 "s_register_operand" "=t")
1221         (plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
1222                           (match_operand:SF 3 "s_register_operand" "t"))
1223                  (match_operand:SF          1 "s_register_operand" "0")))]
1224   "TARGET_32BIT && TARGET_HARD_FLOAT"
1225   "vmla%?.f32\\t%0, %2, %3"
1226   [(set_attr "predicable" "yes")
1227    (set_attr "predicable_short_it" "no")
1228    (set_attr "type" "fmacs")]
1231 (define_insn "*muldf3adddf_vfp"
1232   [(set (match_operand:DF                   0 "s_register_operand" "=w")
1233         (plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
1234                           (match_operand:DF 3 "s_register_operand" "w"))
1235                  (match_operand:DF          1 "s_register_operand" "0")))]
1236   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1237   "vmla%?.f64\\t%P0, %P2, %P3"
1238   [(set_attr "predicable" "yes")
1239    (set_attr "predicable_short_it" "no")
1240    (set_attr "type" "fmacd")]
1243 ;; 0 = 1 * 2 - 0
1244 (define_insn "*mulhf3subhf_vfp"
1245   [(set (match_operand:HF 0 "s_register_operand" "=t")
1246         (minus:HF (mult:HF (match_operand:HF 2 "s_register_operand" "t")
1247                            (match_operand:HF 3 "s_register_operand" "t"))
1248                   (match_operand:HF 1 "s_register_operand" "0")))]
1249   "TARGET_VFP_FP16INST"
1250   "vnmls.f16\\t%0, %2, %3"
1251   [(set_attr "conds" "unconditional")
1252    (set_attr "type" "fmacs")]
1255 (define_insn "*mulsf3subsf_vfp"
1256   [(set (match_operand:SF                    0 "s_register_operand" "=t")
1257         (minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
1258                            (match_operand:SF 3 "s_register_operand" "t"))
1259                   (match_operand:SF          1 "s_register_operand" "0")))]
1260   "TARGET_32BIT && TARGET_HARD_FLOAT"
1261   "vnmls%?.f32\\t%0, %2, %3"
1262   [(set_attr "predicable" "yes")
1263    (set_attr "predicable_short_it" "no")
1264    (set_attr "type" "fmacs")]
1267 (define_insn "*muldf3subdf_vfp"
1268   [(set (match_operand:DF                    0 "s_register_operand" "=w")
1269         (minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
1270                            (match_operand:DF 3 "s_register_operand" "w"))
1271                   (match_operand:DF          1 "s_register_operand" "0")))]
1272   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1273   "vnmls%?.f64\\t%P0, %P2, %P3"
1274   [(set_attr "predicable" "yes")
1275    (set_attr "predicable_short_it" "no")
1276    (set_attr "type" "fmacd")]
1279 ;; 0 = -(1 * 2) + 0
1280 (define_insn "*mulhf3neghfaddhf_vfp"
1281   [(set (match_operand:HF 0 "s_register_operand" "=t")
1282         (minus:HF (match_operand:HF 1 "s_register_operand" "0")
1283                   (mult:HF (match_operand:HF 2 "s_register_operand" "t")
1284                            (match_operand:HF 3 "s_register_operand" "t"))))]
1285   "TARGET_VFP_FP16INST"
1286   "vmls.f16\\t%0, %2, %3"
1287   [(set_attr "conds" "unconditional")
1288    (set_attr "type" "fmacs")]
1291 (define_insn "*mulsf3negsfaddsf_vfp"
1292   [(set (match_operand:SF                    0 "s_register_operand" "=t")
1293         (minus:SF (match_operand:SF          1 "s_register_operand" "0")
1294                   (mult:SF (match_operand:SF 2 "s_register_operand" "t")
1295                            (match_operand:SF 3 "s_register_operand" "t"))))]
1296   "TARGET_32BIT && TARGET_HARD_FLOAT"
1297   "vmls%?.f32\\t%0, %2, %3"
1298   [(set_attr "predicable" "yes")
1299    (set_attr "predicable_short_it" "no")
1300    (set_attr "type" "fmacs")]
1303 (define_insn "*fmuldf3negdfadddf_vfp"
1304   [(set (match_operand:DF                    0 "s_register_operand" "=w")
1305         (minus:DF (match_operand:DF          1 "s_register_operand" "0")
1306                   (mult:DF (match_operand:DF 2 "s_register_operand" "w")
1307                            (match_operand:DF 3 "s_register_operand" "w"))))]
1308   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1309   "vmls%?.f64\\t%P0, %P2, %P3"
1310   [(set_attr "predicable" "yes")
1311    (set_attr "predicable_short_it" "no")
1312    (set_attr "type" "fmacd")]
1316 ;; 0 = -(1 * 2) - 0
1317 (define_insn "*mulhf3neghfsubhf_vfp"
1318   [(set (match_operand:HF 0 "s_register_operand" "=t")
1319         (minus:HF (mult:HF
1320                    (neg:HF (match_operand:HF 2 "s_register_operand" "t"))
1321                    (match_operand:HF 3 "s_register_operand" "t"))
1322                   (match_operand:HF 1 "s_register_operand" "0")))]
1323   "TARGET_VFP_FP16INST"
1324   "vnmla.f16\\t%0, %2, %3"
1325   [(set_attr "conds" "unconditional")
1326    (set_attr "type" "fmacs")]
1329 (define_insn "*mulsf3negsfsubsf_vfp"
1330   [(set (match_operand:SF                     0 "s_register_operand" "=t")
1331         (minus:SF (mult:SF
1332                     (neg:SF (match_operand:SF 2 "s_register_operand" "t"))
1333                     (match_operand:SF         3 "s_register_operand" "t"))
1334                   (match_operand:SF           1 "s_register_operand" "0")))]
1335   "TARGET_32BIT && TARGET_HARD_FLOAT"
1336   "vnmla%?.f32\\t%0, %2, %3"
1337   [(set_attr "predicable" "yes")
1338    (set_attr "predicable_short_it" "no")
1339    (set_attr "type" "fmacs")]
1342 (define_insn "*muldf3negdfsubdf_vfp"
1343   [(set (match_operand:DF                     0 "s_register_operand" "=w")
1344         (minus:DF (mult:DF
1345                     (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
1346                     (match_operand:DF         3 "s_register_operand" "w"))
1347                   (match_operand:DF           1 "s_register_operand" "0")))]
1348   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1349   "vnmla%?.f64\\t%P0, %P2, %P3"
1350   [(set_attr "predicable" "yes")
1351    (set_attr "predicable_short_it" "no")
1352    (set_attr "type" "fmacd")]
1355 ;; Fused-multiply-accumulate
1357 (define_insn "fmahf4"
1358   [(set (match_operand:HF 0 "register_operand" "=w")
1359     (fma:HF
1360      (match_operand:HF 1 "register_operand" "w")
1361      (match_operand:HF 2 "register_operand" "w")
1362      (match_operand:HF 3 "register_operand" "0")))]
1363  "TARGET_VFP_FP16INST"
1364  "vfma.f16\\t%0, %1, %2"
1365  [(set_attr "conds" "unconditional")
1366   (set_attr "type" "ffmas")]
1369 (define_expand "neon_vfmahf"
1370   [(match_operand:HF 0 "s_register_operand")
1371    (match_operand:HF 1 "s_register_operand")
1372    (match_operand:HF 2 "s_register_operand")
1373    (match_operand:HF 3 "s_register_operand")]
1374   "TARGET_VFP_FP16INST"
1376   emit_insn (gen_fmahf4 (operands[0], operands[2], operands[3],
1377                          operands[1]));
1378   DONE;
1381 (define_insn "fma<SDF:mode>4"
1382   [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
1383         (fma:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>")
1384                  (match_operand:SDF 2 "register_operand" "<F_constraint>")
1385                  (match_operand:SDF 3 "register_operand" "0")))]
1386   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
1387   "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1388   [(set_attr "predicable" "yes")
1389    (set_attr "predicable_short_it" "no")
1390    (set_attr "type" "ffma<vfp_type>")]
1393 (define_insn "fmsubhf4_fp16"
1394  [(set (match_operand:HF 0 "register_operand" "=w")
1395    (fma:HF
1396     (neg:HF (match_operand:HF 1 "register_operand" "w"))
1397     (match_operand:HF 2 "register_operand" "w")
1398     (match_operand:HF 3 "register_operand" "0")))]
1399  "TARGET_VFP_FP16INST"
1400  "vfms.f16\\t%0, %1, %2"
1401  [(set_attr "conds" "unconditional")
1402   (set_attr "type" "ffmas")]
1405 (define_expand "neon_vfmshf"
1406   [(match_operand:HF 0 "s_register_operand")
1407    (match_operand:HF 1 "s_register_operand")
1408    (match_operand:HF 2 "s_register_operand")
1409    (match_operand:HF 3 "s_register_operand")]
1410   "TARGET_VFP_FP16INST"
1412   emit_insn (gen_fmsubhf4_fp16 (operands[0], operands[2], operands[3],
1413                                 operands[1]));
1414   DONE;
1417 (define_insn "*fmsub<SDF:mode>4"
1418   [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
1419         (fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand"
1420                                              "<F_constraint>"))
1421                  (match_operand:SDF 2 "register_operand" "<F_constraint>")
1422                  (match_operand:SDF 3 "register_operand" "0")))]
1423   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
1424   "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1425   [(set_attr "predicable" "yes")
1426    (set_attr "predicable_short_it" "no")
1427    (set_attr "type" "ffma<vfp_type>")]
1430 (define_insn "*fnmsubhf4"
1431   [(set (match_operand:HF 0 "register_operand" "=w")
1432         (fma:HF (match_operand:HF 1 "register_operand" "w")
1433                  (match_operand:HF 2 "register_operand" "w")
1434                  (neg:HF (match_operand:HF 3 "register_operand" "0"))))]
1435   "TARGET_VFP_FP16INST"
1436   "vfnms.f16\\t%0, %1, %2"
1437   [(set_attr "conds" "unconditional")
1438    (set_attr "type" "ffmas")]
1441 (define_insn "*fnmsub<SDF:mode>4"
1442   [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
1443         (fma:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>")
1444                  (match_operand:SDF 2 "register_operand" "<F_constraint>")
1445                  (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))]
1446   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
1447   "vfnms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1448   [(set_attr "predicable" "yes")
1449    (set_attr "predicable_short_it" "no")
1450    (set_attr "type" "ffma<vfp_type>")]
1453 (define_insn "*fnmaddhf4"
1454   [(set (match_operand:HF 0 "register_operand" "=w")
1455         (fma:HF (neg:HF (match_operand:HF 1 "register_operand" "w"))
1456                  (match_operand:HF 2 "register_operand" "w")
1457                  (neg:HF (match_operand:HF 3 "register_operand" "0"))))]
1458   "TARGET_VFP_FP16INST"
1459   "vfnma.f16\\t%0, %1, %2"
1460   [(set_attr "conds" "unconditional")
1461    (set_attr "type" "ffmas")]
1464 (define_insn "*fnmadd<SDF:mode>4"
1465   [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
1466         (fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand"
1467                                                "<F_constraint>"))
1468                  (match_operand:SDF 2 "register_operand" "<F_constraint>")
1469                  (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))]
1470   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
1471   "vfnma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1472   [(set_attr "predicable" "yes")
1473    (set_attr "predicable_short_it" "no")
1474    (set_attr "type" "ffma<vfp_type>")]
1478 ;; Conversion routines
1480 (define_insn "*extendsfdf2_vfp"
1481   [(set (match_operand:DF                  0 "s_register_operand" "=w")
1482         (float_extend:DF (match_operand:SF 1 "s_register_operand" "t")))]
1483   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1484   "vcvt%?.f64.f32\\t%P0, %1"
1485   [(set_attr "predicable" "yes")
1486    (set_attr "predicable_short_it" "no")
1487    (set_attr "type" "f_cvt")]
1490 (define_insn "*truncdfsf2_vfp"
1491   [(set (match_operand:SF                  0 "s_register_operand" "=t")
1492         (float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
1493   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1494   "vcvt%?.f32.f64\\t%0, %P1"
1495   [(set_attr "predicable" "yes")
1496    (set_attr "predicable_short_it" "no")
1497    (set_attr "type" "f_cvt")]
1500 (define_insn "extendhfsf2"
1501   [(set (match_operand:SF                  0 "s_register_operand" "=t")
1502         (float_extend:SF (match_operand:HF 1 "s_register_operand" "t")))]
1503   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FP16 || TARGET_VFP_FP16INST)"
1504   "vcvtb%?.f32.f16\\t%0, %1"
1505   [(set_attr "predicable" "yes")
1506    (set_attr "predicable_short_it" "no")
1507    (set_attr "type" "f_cvt")]
1510 (define_insn "*truncdfhf2"
1511   [(set (match_operand:HF                  0 "s_register_operand" "=t")
1512         (float_truncate:HF (match_operand:DF 1 "s_register_operand" "w")))]
1513   "TARGET_32BIT && TARGET_FP16_TO_DOUBLE"
1514   "vcvtb%?.f16.f64\\t%0, %P1"
1515   [(set_attr "predicable" "yes")
1516    (set_attr "predicable_short_it" "no")
1517    (set_attr "type" "f_cvt")]
1520 (define_insn "*extendhfdf2"
1521   [(set (match_operand:DF                  0 "s_register_operand" "=w")
1522         (float_extend:DF (match_operand:HF 1 "s_register_operand" "t")))]
1523   "TARGET_32BIT && TARGET_FP16_TO_DOUBLE"
1524   "vcvtb%?.f64.f16\\t%P0, %1"
1525   [(set_attr "predicable" "yes")
1526    (set_attr "predicable_short_it" "no")
1527    (set_attr "type" "f_cvt")]
1530 (define_insn "truncsfhf2"
1531   [(set (match_operand:HF                  0 "s_register_operand" "=t")
1532         (float_truncate:HF (match_operand:SF 1 "s_register_operand" "t")))]
1533   "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FP16 || TARGET_VFP_FP16INST)"
1534   "vcvtb%?.f16.f32\\t%0, %1"
1535   [(set_attr "predicable" "yes")
1536    (set_attr "predicable_short_it" "no")
1537    (set_attr "type" "f_cvt")]
1540 (define_insn "*truncsisf2_vfp"
1541   [(set (match_operand:SI                 0 "s_register_operand" "=t")
1542         (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
1543   "TARGET_32BIT && TARGET_HARD_FLOAT"
1544   "vcvt%?.s32.f32\\t%0, %1"
1545   [(set_attr "predicable" "yes")
1546    (set_attr "predicable_short_it" "no")
1547    (set_attr "type" "f_cvtf2i")]
1550 (define_insn "*truncsidf2_vfp"
1551   [(set (match_operand:SI                 0 "s_register_operand" "=t")
1552         (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
1553   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1554   "vcvt%?.s32.f64\\t%0, %P1"
1555   [(set_attr "predicable" "yes")
1556    (set_attr "predicable_short_it" "no")
1557    (set_attr "type" "f_cvtf2i")]
1561 (define_insn "fixuns_truncsfsi2"
1562   [(set (match_operand:SI                 0 "s_register_operand" "=t")
1563         (unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
1564   "TARGET_32BIT && TARGET_HARD_FLOAT"
1565   "vcvt%?.u32.f32\\t%0, %1"
1566   [(set_attr "predicable" "yes")
1567    (set_attr "predicable_short_it" "no")
1568    (set_attr "type" "f_cvtf2i")]
1571 (define_insn "fixuns_truncdfsi2"
1572   [(set (match_operand:SI                 0 "s_register_operand" "=t")
1573         (unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "t"))))]
1574   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1575   "vcvt%?.u32.f64\\t%0, %P1"
1576   [(set_attr "predicable" "yes")
1577    (set_attr "predicable_short_it" "no")
1578    (set_attr "type" "f_cvtf2i")]
1582 (define_insn "*floatsisf2_vfp"
1583   [(set (match_operand:SF           0 "s_register_operand" "=t")
1584         (float:SF (match_operand:SI 1 "s_register_operand" "t")))]
1585   "TARGET_32BIT && TARGET_HARD_FLOAT"
1586   "vcvt%?.f32.s32\\t%0, %1"
1587   [(set_attr "predicable" "yes")
1588    (set_attr "predicable_short_it" "no")
1589    (set_attr "type" "f_cvti2f")]
1592 (define_insn "*floatsidf2_vfp"
1593   [(set (match_operand:DF           0 "s_register_operand" "=w")
1594         (float:DF (match_operand:SI 1 "s_register_operand" "t")))]
1595   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1596   "vcvt%?.f64.s32\\t%P0, %1"
1597   [(set_attr "predicable" "yes")
1598    (set_attr "predicable_short_it" "no")
1599    (set_attr "type" "f_cvti2f")]
1603 (define_insn "floatunssisf2"
1604   [(set (match_operand:SF           0 "s_register_operand" "=t")
1605         (unsigned_float:SF (match_operand:SI 1 "s_register_operand" "t")))]
1606   "TARGET_32BIT && TARGET_HARD_FLOAT"
1607   "vcvt%?.f32.u32\\t%0, %1"
1608   [(set_attr "predicable" "yes")
1609    (set_attr "predicable_short_it" "no")
1610    (set_attr "type" "f_cvti2f")]
1613 (define_insn "floatunssidf2"
1614   [(set (match_operand:DF           0 "s_register_operand" "=w")
1615         (unsigned_float:DF (match_operand:SI 1 "s_register_operand" "t")))]
1616   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1617   "vcvt%?.f64.u32\\t%P0, %1"
1618   [(set_attr "predicable" "yes")
1619    (set_attr "predicable_short_it" "no")
1620    (set_attr "type" "f_cvti2f")]
1624 ;; Sqrt insns.
1626 (define_insn "neon_vsqrthf"
1627   [(set (match_operand:HF 0 "s_register_operand" "=w")
1628         (sqrt:HF (match_operand:HF 1 "s_register_operand" "w")))]
1629   "TARGET_VFP_FP16INST"
1630   "vsqrt.f16\t%0, %1"
1631   [(set_attr "conds" "unconditional")
1632    (set_attr "type" "fsqrts")]
1635 (define_insn "neon_vrsqrtshf"
1636   [(set
1637     (match_operand:HF 0 "s_register_operand" "=w")
1638     (unspec:HF [(match_operand:HF 1 "s_register_operand" "w")
1639                 (match_operand:HF 2 "s_register_operand" "w")]
1640      UNSPEC_VRSQRTS))]
1641  "TARGET_VFP_FP16INST"
1642  "vrsqrts.f16\t%0, %1, %2"
1643  [(set_attr "conds" "unconditional")
1644   (set_attr "type" "fsqrts")]
1647 ; VFP9 Erratum 760019: It's potentially unsafe to overwrite the input
1648 ; operands, so mark the output as early clobber for VFPv2 on ARMv5 or
1649 ; earlier.
1650 (define_insn "*sqrtsf2_vfp"
1651   [(set (match_operand:SF          0 "s_register_operand" "=&t,t")
1652         (sqrt:SF (match_operand:SF 1 "s_register_operand" "t,t")))]
1653   "TARGET_32BIT && TARGET_HARD_FLOAT"
1654   "vsqrt%?.f32\\t%0, %1"
1655   [(set_attr "predicable" "yes")
1656    (set_attr "predicable_short_it" "no")
1657    (set_attr "arch" "*,armv6_or_vfpv3")
1658    (set_attr "type" "fsqrts")]
1661 (define_insn "*sqrtdf2_vfp"
1662   [(set (match_operand:DF          0 "s_register_operand" "=&w,w")
1663         (sqrt:DF (match_operand:DF 1 "s_register_operand" "w,w")))]
1664   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1665   "vsqrt%?.f64\\t%P0, %P1"
1666   [(set_attr "predicable" "yes")
1667    (set_attr "predicable_short_it" "no")
1668    (set_attr "arch" "*,armv6_or_vfpv3")
1669    (set_attr "type" "fsqrtd")]
1673 ;; Patterns to split/copy vfp condition flags.
1675 (define_insn "*movcc_vfp"
1676   [(set (reg CC_REGNUM)
1677         (reg VFPCC_REGNUM))]
1678   "TARGET_32BIT && TARGET_HARD_FLOAT"
1679   "vmrs%?\\tAPSR_nzcv, FPSCR"
1680   [(set_attr "conds" "set")
1681    (set_attr "type" "f_flag")]
1684 (define_insn_and_split "*cmpsf_split_vfp"
1685   [(set (reg:CCFP CC_REGNUM)
1686         (compare:CCFP (match_operand:SF 0 "s_register_operand"  "t")
1687                       (match_operand:SF 1 "vfp_compare_operand" "tG")))]
1688   "TARGET_32BIT && TARGET_HARD_FLOAT"
1689   "#"
1690   "TARGET_32BIT && TARGET_HARD_FLOAT"
1691   [(set (reg:CCFP VFPCC_REGNUM)
1692         (compare:CCFP (match_dup 0)
1693                       (match_dup 1)))
1694    (set (reg:CCFP CC_REGNUM)
1695         (reg:CCFP VFPCC_REGNUM))]
1696   ""
1699 (define_insn_and_split "*cmpsf_trap_split_vfp"
1700   [(set (reg:CCFPE CC_REGNUM)
1701         (compare:CCFPE (match_operand:SF 0 "s_register_operand"  "t")
1702                        (match_operand:SF 1 "vfp_compare_operand" "tG")))]
1703   "TARGET_32BIT && TARGET_HARD_FLOAT"
1704   "#"
1705   "TARGET_32BIT && TARGET_HARD_FLOAT"
1706   [(set (reg:CCFPE VFPCC_REGNUM)
1707         (compare:CCFPE (match_dup 0)
1708                        (match_dup 1)))
1709    (set (reg:CCFPE CC_REGNUM)
1710         (reg:CCFPE VFPCC_REGNUM))]
1711   ""
1714 (define_insn_and_split "*cmpdf_split_vfp"
1715   [(set (reg:CCFP CC_REGNUM)
1716         (compare:CCFP (match_operand:DF 0 "s_register_operand"  "w")
1717                       (match_operand:DF 1 "vfp_compare_operand" "wG")))]
1718   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1719   "#"
1720   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1721   [(set (reg:CCFP VFPCC_REGNUM)
1722         (compare:CCFP (match_dup 0)
1723                        (match_dup 1)))
1724    (set (reg:CCFP CC_REGNUM)
1725         (reg:CCFP VFPCC_REGNUM))]
1726   ""
1729 (define_insn_and_split "*cmpdf_trap_split_vfp"
1730   [(set (reg:CCFPE CC_REGNUM)
1731         (compare:CCFPE (match_operand:DF 0 "s_register_operand"  "w")
1732                        (match_operand:DF 1 "vfp_compare_operand" "wG")))]
1733   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1734   "#"
1735   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1736   [(set (reg:CCFPE VFPCC_REGNUM)
1737         (compare:CCFPE (match_dup 0)
1738                        (match_dup 1)))
1739    (set (reg:CCFPE CC_REGNUM)
1740         (reg:CCFPE VFPCC_REGNUM))]
1741   ""
1745 ;; Comparison patterns
1747 ;; In the compare with FP zero case the ARM Architecture Reference Manual
1748 ;; specifies the immediate to be #0.0.  However, some buggy assemblers only
1749 ;; accept #0.  We don't want to autodetect broken assemblers, so output #0.
1750 (define_insn "*cmpsf_vfp"
1751   [(set (reg:CCFP VFPCC_REGNUM)
1752         (compare:CCFP (match_operand:SF 0 "s_register_operand"  "t,t")
1753                       (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
1754   "TARGET_32BIT && TARGET_HARD_FLOAT"
1755   "@
1756    vcmp%?.f32\\t%0, %1
1757    vcmp%?.f32\\t%0, #0"
1758   [(set_attr "predicable" "yes")
1759    (set_attr "predicable_short_it" "no")
1760    (set_attr "type" "fcmps")]
1763 (define_insn "*cmpsf_trap_vfp"
1764   [(set (reg:CCFPE VFPCC_REGNUM)
1765         (compare:CCFPE (match_operand:SF 0 "s_register_operand"  "t,t")
1766                        (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
1767   "TARGET_32BIT && TARGET_HARD_FLOAT"
1768   "@
1769    vcmpe%?.f32\\t%0, %1
1770    vcmpe%?.f32\\t%0, #0"
1771   [(set_attr "predicable" "yes")
1772    (set_attr "predicable_short_it" "no")
1773    (set_attr "type" "fcmps")]
1776 (define_insn "*cmpdf_vfp"
1777   [(set (reg:CCFP VFPCC_REGNUM)
1778         (compare:CCFP (match_operand:DF 0 "s_register_operand"  "w,w")
1779                       (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1780   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1781   "@
1782    vcmp%?.f64\\t%P0, %P1
1783    vcmp%?.f64\\t%P0, #0"
1784   [(set_attr "predicable" "yes")
1785    (set_attr "predicable_short_it" "no")
1786    (set_attr "type" "fcmpd")]
1789 (define_insn "*cmpdf_trap_vfp"
1790   [(set (reg:CCFPE VFPCC_REGNUM)
1791         (compare:CCFPE (match_operand:DF 0 "s_register_operand"  "w,w")
1792                        (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1793   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1794   "@
1795    vcmpe%?.f64\\t%P0, %P1
1796    vcmpe%?.f64\\t%P0, #0"
1797   [(set_attr "predicable" "yes")
1798    (set_attr "predicable_short_it" "no")
1799    (set_attr "type" "fcmpd")]
1802 ;; Fixed point to floating point conversions.
1803 (define_insn "*combine_vcvt_f32_<FCVTI32typename>"
1804   [(set (match_operand:SF 0 "s_register_operand" "=t")
1805         (mult:SF (FCVT:SF (match_operand:SI 1 "s_register_operand" "0"))
1806                  (match_operand 2
1807                         "const_double_vcvt_power_of_two_reciprocal" "Dt")))]
1808   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math"
1809   "vcvt%?.f32.<FCVTI32typename>\\t%0, %1, %v2"
1810   [(set_attr "predicable" "yes")
1811    (set_attr "predicable_short_it" "no")
1812    (set_attr "type" "f_cvti2f")]
1815 ;; Not the ideal way of implementing this. Ideally we would be able to split
1816 ;; this into a move to a DP register and then a vcvt.f64.i32
1817 (define_insn "*combine_vcvt_f64_<FCVTI32typename>"
1818   [(set (match_operand:DF 0 "s_register_operand" "=x,x,w")
1819         (mult:DF (FCVT:DF (match_operand:SI 1 "s_register_operand" "r,t,r"))
1820                  (match_operand 2
1821                      "const_double_vcvt_power_of_two_reciprocal" "Dt,Dt,Dt")))]
1822   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math
1823   && !TARGET_VFP_SINGLE"
1824   "@
1825   vmov%?.f32\\t%0, %1\;vcvt%?.f64.<FCVTI32typename>\\t%P0, %P0, %v2
1826   vmov%?.f32\\t%0, %1\;vcvt%?.f64.<FCVTI32typename>\\t%P0, %P0, %v2
1827   vmov%?.f64\\t%P0, %1, %1\;vcvt%?.f64.<FCVTI32typename>\\t%P0, %P0, %v2"
1828   [(set_attr "predicable" "yes")
1829    (set_attr "ce_count" "2")
1830    (set_attr "predicable_short_it" "no")
1831    (set_attr "type" "f_cvti2f")
1832    (set_attr "length" "8")]
1835 (define_insn "*combine_vcvtf2i"
1836   [(set (match_operand:SI 0 "s_register_operand" "=t")
1837         (fix:SI (fix:SF (mult:SF (match_operand:SF 1 "s_register_operand" "0")
1838                                  (match_operand 2
1839                                  "const_double_vcvt_power_of_two" "Dp")))))]
1840   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math"
1841   "vcvt%?.s32.f32\\t%0, %1, %v2"
1842   [(set_attr "predicable" "yes")
1843    (set_attr "predicable_short_it" "no")
1844    (set_attr "type" "f_cvtf2i")]
1847 ;; FP16 conversions.
1848 (define_insn "neon_vcvth<sup>hf"
1849  [(set (match_operand:HF 0 "s_register_operand" "=w")
1850    (unspec:HF
1851     [(match_operand:SI 1 "s_register_operand" "w")]
1852     VCVTH_US))]
1853  "TARGET_VFP_FP16INST"
1854  "vcvt.f16.<sup>%#32\t%0, %1"
1855  [(set_attr "conds" "unconditional")
1856   (set_attr "type" "f_cvti2f")]
1859 (define_insn "neon_vcvth<sup>si"
1860  [(set (match_operand:SI 0 "s_register_operand" "=w")
1861    (unspec:SI
1862     [(match_operand:HF 1 "s_register_operand" "w")]
1863     VCVTH_US))]
1864  "TARGET_VFP_FP16INST"
1865  "vcvt.<sup>%#32.f16\t%0, %1"
1866  [(set_attr "conds" "unconditional")
1867   (set_attr "type" "f_cvtf2i")]
1870 ;; The neon_vcvth<sup>_nhf patterns are used to generate the instruction for the
1871 ;; vcvth_n_f16_<sup>32 arm_fp16 intrinsics.  They are complicated by the
1872 ;; hardware requirement that the source and destination registers are the same
1873 ;; despite having different machine modes.  The approach is to use a temporary
1874 ;; register for the conversion and move that to the correct destination.
1876 ;; Generate an unspec pattern for the intrinsic.
1877 (define_insn "neon_vcvth<sup>_nhf_unspec"
1878  [(set
1879    (match_operand:SI 0 "s_register_operand" "=w")
1880    (unspec:SI
1881     [(match_operand:SI 1 "s_register_operand" "0")
1882      (match_operand:SI 2 "immediate_operand" "i")]
1883     VCVT_HF_US_N))
1884  (set
1885   (match_operand:HF 3 "s_register_operand" "=w")
1886   (float_truncate:HF (float:SF (match_dup 0))))]
1887  "TARGET_VFP_FP16INST"
1889   arm_const_bounds (operands[2], 1, 33);
1890   return "vcvt.f16.<sup>32\t%0, %0, %2\;vmov.f32\t%3, %0";
1892   [(set_attr "conds" "unconditional")
1893    (set_attr "type" "f_cvti2f")]
1896 ;; Generate the instruction patterns needed for vcvth_n_f16_s32 neon intrinsics.
1897 (define_expand "neon_vcvth<sup>_nhf"
1898  [(match_operand:HF 0 "s_register_operand")
1899   (unspec:HF [(match_operand:SI 1 "s_register_operand")
1900               (match_operand:SI 2 "immediate_operand")]
1901    VCVT_HF_US_N)]
1902 "TARGET_VFP_FP16INST"
1904   rtx op1 = gen_reg_rtx (SImode);
1906   arm_const_bounds (operands[2], 1, 33);
1908   emit_move_insn (op1, operands[1]);
1909   emit_insn (gen_neon_vcvth<sup>_nhf_unspec (op1, op1, operands[2],
1910                                              operands[0]));
1911   DONE;
1914 ;; The neon_vcvth<sup>_nsi patterns are used to generate the instruction for the
1915 ;; vcvth_n_<sup>32_f16 arm_fp16 intrinsics.  They have the same restrictions and
1916 ;; are implemented in the same way as the neon_vcvth<sup>_nhf patterns.
1918 ;; Generate an unspec pattern, constraining the registers.
1919 (define_insn "neon_vcvth<sup>_nsi_unspec"
1920  [(set (match_operand:SI 0 "s_register_operand" "=w")
1921    (unspec:SI
1922     [(fix:SI
1923       (fix:SF
1924        (float_extend:SF
1925         (match_operand:HF 1 "s_register_operand" "w"))))
1926      (match_operand:SI 2 "immediate_operand" "i")]
1927     VCVT_SI_US_N))]
1928  "TARGET_VFP_FP16INST"
1930   arm_const_bounds (operands[2], 1, 33);
1931   return "vmov.f32\t%0, %1\;vcvt.<sup>%#32.f16\t%0, %0, %2";
1933   [(set_attr "conds" "unconditional")
1934    (set_attr "type" "f_cvtf2i")]
1937 ;; Generate the instruction patterns needed for vcvth_n_f16_s32 neon intrinsics.
1938 (define_expand "neon_vcvth<sup>_nsi"
1939  [(match_operand:SI 0 "s_register_operand")
1940   (unspec:SI
1941    [(match_operand:HF 1 "s_register_operand")
1942     (match_operand:SI 2 "immediate_operand")]
1943    VCVT_SI_US_N)]
1944  "TARGET_VFP_FP16INST"
1946   rtx op1 = gen_reg_rtx (SImode);
1948   arm_const_bounds (operands[2], 1, 33);
1949   emit_insn (gen_neon_vcvth<sup>_nsi_unspec (op1, operands[1], operands[2]));
1950   emit_move_insn (operands[0], op1);
1951   DONE;
1954 (define_insn "neon_vcvt<vcvth_op>h<sup>si"
1955  [(set
1956    (match_operand:SI 0 "s_register_operand" "=w")
1957    (unspec:SI
1958     [(match_operand:HF 1 "s_register_operand" "w")]
1959     VCVT_HF_US))]
1960  "TARGET_VFP_FP16INST"
1961  "vcvt<vcvth_op>.<sup>%#32.f16\t%0, %1"
1962   [(set_attr "conds" "unconditional")
1963    (set_attr "type" "f_cvtf2i")]
1966 ;; Store multiple insn used in function prologue.
1967 (define_insn "*push_multi_vfp"
1968   [(match_parallel 2 "multi_register_push"
1969     [(set (match_operand:BLK 0 "memory_operand" "=m")
1970           (unspec:BLK [(match_operand:DF 1 "vfp_register_operand" "")]
1971                       UNSPEC_PUSH_MULT))])]
1972   "TARGET_32BIT && TARGET_HARD_FLOAT"
1973   "* return vfp_output_vstmd (operands);"
1974   [(set_attr "type" "f_stored")]
1977 ;; VRINT round to integral instructions.
1978 ;; Invoked for the patterns: btruncsf2, btruncdf2, ceilsf2, ceildf2,
1979 ;; roundsf2, rounddf2, floorsf2, floordf2, nearbyintsf2, nearbyintdf2,
1980 ;; rintsf2, rintdf2.
1981 (define_insn "<vrint_pattern><SDF:mode>2"
1982   [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
1983         (unspec:SDF [(match_operand:SDF 1
1984                          "register_operand" "<F_constraint>")]
1985          VRINT))]
1986   "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
1987   "vrint<vrint_variant>%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1"
1988   [(set_attr "predicable" "<vrint_predicable>")
1989    (set_attr "predicable_short_it" "no")
1990    (set_attr "type" "f_rint<vfp_type>")
1991    (set_attr "conds" "<vrint_conds>")]
1994 ;; Implements the lround, lfloor and lceil optabs.
1995 (define_insn "l<vrint_pattern><su_optab><mode>si2"
1996   [(set (match_operand:SI 0 "register_operand" "=t")
1997         (FIXUORS:SI (unspec:SDF
1998                         [(match_operand:SDF 1
1999                            "register_operand" "<F_constraint>")] VCVT)))]
2000   "TARGET_HARD_FLOAT && TARGET_FPU_ARMV8 <vfp_double_cond>"
2001   "vcvt<vrint_variant>.<su>32.<V_if_elem>\\t%0, %<V_reg>1"
2002   [(set_attr "predicable" "no")
2003    (set_attr "conds" "unconditional")
2004    (set_attr "type" "f_cvtf2i")]
2007 ;; MIN_EXPR and MAX_EXPR eventually map to 'smin' and 'smax' in RTL.
2008 ;; The 'smax' and 'smin' RTL standard pattern names do not specify which
2009 ;; operand will be returned when both operands are zero (i.e. they may not
2010 ;; honour signed zeroes), or when either operand is NaN.  Therefore GCC
2011 ;; only introduces MIN_EXPR/MAX_EXPR in fast math mode or when not honouring
2012 ;; NaNs.
2014 (define_insn "smax<mode>3"
2015   [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
2016         (smax:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>")
2017                   (match_operand:SDF 2 "register_operand" "<F_constraint>")))]
2018   "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
2019   "vmaxnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2020   [(set_attr "type" "f_minmax<vfp_type>")
2021    (set_attr "conds" "unconditional")]
2024 (define_insn "smin<mode>3"
2025   [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
2026         (smin:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>")
2027                   (match_operand:SDF 2 "register_operand" "<F_constraint>")))]
2028   "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
2029   "vminnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2030   [(set_attr "type" "f_minmax<vfp_type>")
2031    (set_attr "conds" "unconditional")]
2034 ;; Scalar forms for the IEEE-754 fmax()/fmin() functions
2036 (define_insn "neon_<fmaxmin_op>hf"
2037  [(set
2038    (match_operand:HF 0 "s_register_operand" "=w")
2039    (unspec:HF
2040     [(match_operand:HF 1 "s_register_operand" "w")
2041      (match_operand:HF 2 "s_register_operand" "w")]
2042     VMAXMINFNM))]
2043  "TARGET_VFP_FP16INST"
2044  "<fmaxmin_op>.f16\t%0, %1, %2"
2045  [(set_attr "conds" "unconditional")
2046   (set_attr "type" "f_minmaxs")]
2049 (define_insn "<fmaxmin><mode>3"
2050   [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
2051         (unspec:SDF [(match_operand:SDF 1 "s_register_operand" "<F_constraint>")
2052                      (match_operand:SDF 2 "s_register_operand" "<F_constraint>")]
2053                      VMAXMINFNM))]
2054   "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
2055   "<fmaxmin_op>.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2056   [(set_attr "type" "f_minmax<vfp_type>")
2057    (set_attr "conds" "unconditional")]
2060 ;; Write Floating-point Status and Control Register.
2061 (define_insn "set_fpscr"
2062   [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_SET_FPSCR)]
2063   "TARGET_HARD_FLOAT"
2064   "mcr\\tp10, 7, %0, cr1, cr0, 0\\t @SET_FPSCR"
2065   [(set_attr "type" "mrs")])
2067 ;; Read Floating-point Status and Control Register.
2068 (define_insn "get_fpscr"
2069   [(set (match_operand:SI 0 "register_operand" "=r")
2070         (unspec_volatile:SI [(const_int 0)] VUNSPEC_GET_FPSCR))]
2071   "TARGET_HARD_FLOAT"
2072   "mrc\\tp10, 7, %0, cr1, cr0, 0\\t @GET_FPSCR"
2073   [(set_attr "type" "mrs")])
2076 ;; Unimplemented insns:
2077 ;; fldm*
2078 ;; fstm*
2079 ;; fmdhr et al (VFPv1)
2080 ;; Support for xD (single precision only) variants.
2081 ;; fmrrs, fmsrr
2083 ;; Split an immediate DF move to two immediate SI moves.
2084 (define_insn_and_split "no_literal_pool_df_immediate"
2085   [(set (match_operand:DF 0 "s_register_operand" "")
2086         (match_operand:DF 1 "const_double_operand" ""))]
2087   "TARGET_THUMB2 && arm_disable_literal_pool
2088   && !(TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE
2089        && vfp3_const_double_rtx (operands[1]))"
2090   "#"
2091   "&& !reload_completed"
2092   [(set (subreg:SI (match_dup 1) 0) (match_dup 2))
2093    (set (subreg:SI (match_dup 1) 4) (match_dup 3))
2094    (set (match_dup 0) (match_dup 1))]
2095   "
2096   long buf[2];
2097   real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
2098   operands[2] = GEN_INT ((int) buf[0]);
2099   operands[3] = GEN_INT ((int) buf[1]);
2100   operands[1] = gen_reg_rtx (DFmode);
2101   ")
2103 ;; Split an immediate SF move to one immediate SI move.
2104 (define_insn_and_split "no_literal_pool_sf_immediate"
2105   [(set (match_operand:SF 0 "s_register_operand" "")
2106         (match_operand:SF 1 "const_double_operand" ""))]
2107   "TARGET_THUMB2 && arm_disable_literal_pool
2108   && !(TARGET_HARD_FLOAT && vfp3_const_double_rtx (operands[1]))"
2109   "#"
2110   "&& !reload_completed"
2111   [(set (subreg:SI (match_dup 1) 0) (match_dup 2))
2112    (set (match_dup 0) (match_dup 1))]
2113   "
2114   long buf;
2115   real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
2116   operands[2] = GEN_INT ((int) buf);
2117   operands[1] = gen_reg_rtx (SFmode);
2118   ")