1;; ARM VFP instruction patterns
2;; Copyright (C) 2003-2018 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;; 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))"
33{
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    }
54}
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 "store_4")
64    (const_string "load_4")
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")]
72)
73
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))"
84{
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    }
105}
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, store_4, load_4,\
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")]
116)
117
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))"
129{
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    }
150}
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 "store_4")
160    (const_string "load_4")
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")]
168)
169
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))"
179{
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    }
200}
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, store_4, load_4,\
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")]
212)
213
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,load_4,store_4,
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,*")]
253)
254
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,load_4,load_4,store_4,store_4,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,*")]
301)
302
303
304;; DImode moves
305
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
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,load_8,load_8,store_8,f_mcrr,f_mrrc,ffarithd,f_loadd,f_stored")
342   (set (attr "length") (cond [(eq_attr "alternative" "1") (const_int 8)
343                              (eq_attr "alternative" "2") (const_int 12)
344                              (eq_attr "alternative" "3") (const_int 16)
345			      (eq_attr "alternative" "4,5,6")
346			       (symbol_ref "arm_count_output_move_double_insns (operands) * 4")
347                              (eq_attr "alternative" "9")
348                               (if_then_else
349                                 (match_test "TARGET_VFP_SINGLE")
350                                 (const_int 8)
351                                 (const_int 4))]
352                              (const_int 4)))
353   (set_attr "predicable"    "yes")
354   (set_attr "arm_pool_range"     "*,*,*,*,1020,4096,*,*,*,*,1020,*")
355   (set_attr "thumb2_pool_range"     "*,*,*,*,1018,4094,*,*,*,*,1018,*")
356   (set_attr "neg_pool_range" "*,*,*,*,1004,0,*,*,*,*,1004,*")
357   (set (attr "ce_count") (symbol_ref "get_attr_length (insn) / 4"))
358   (set_attr "arch"           "t2,any,any,any,a,t2,any,any,any,any,any,any")]
359)
360
361;; HFmode moves
362
363(define_insn "*movhf_vfp_fp16"
364  [(set (match_operand:HF 0 "nonimmediate_operand"
365			  "= r,m,t,r,t,r,t,t,Um,r")
366	(match_operand:HF 1 "general_operand"
367			  "  m,r,t,r,r,t,Dv,Um,t,F"))]
368  "TARGET_32BIT
369   && TARGET_VFP_FP16INST
370   && (s_register_operand (operands[0], HFmode)
371       || s_register_operand (operands[1], HFmode))"
372 {
373  switch (which_alternative)
374    {
375    case 0: /* ARM register from memory.  */
376      return \"ldrh%?\\t%0, %1\\t%@ __fp16\";
377    case 1: /* Memory from ARM register.  */
378      return \"strh%?\\t%1, %0\\t%@ __fp16\";
379    case 2: /* S register from S register.  */
380      return \"vmov\\t%0, %1\t%@ __fp16\";
381    case 3: /* ARM register from ARM register.  */
382      return \"mov%?\\t%0, %1\\t%@ __fp16\";
383    case 4: /* S register from ARM register.  */
384    case 5: /* ARM register from S register.  */
385    case 6: /* S register from immediate.  */
386      return \"vmov.f16\\t%0, %1\t%@ __fp16\";
387    case 7: /* S register from memory.  */
388      return \"vld1.16\\t{%z0}, %A1\";
389    case 8: /* Memory from S register.  */
390      return \"vst1.16\\t{%z1}, %A0\";
391    case 9: /* ARM register from constant.  */
392      {
393	long bits;
394	rtx ops[4];
395
396	bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
397			       HFmode);
398	ops[0] = operands[0];
399	ops[1] = GEN_INT (bits);
400	ops[2] = GEN_INT (bits & 0xff00);
401	ops[3] = GEN_INT (bits & 0x00ff);
402
403	if (arm_arch_thumb2)
404	  output_asm_insn (\"movw\\t%0, %1\", ops);
405	else
406	  output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops);
407	return \"\";
408       }
409    default:
410      gcc_unreachable ();
411    }
412 }
413  [(set_attr "conds" "*, *, unconditional, *, unconditional, unconditional,\
414		      unconditional, unconditional, unconditional,\
415		      unconditional")
416   (set_attr "predicable" "yes, yes, no, yes, no, no, no, no, no, no")
417   (set_attr "predicable_short_it" "no, no, no, yes,\
418				    no, no, no, no,\
419				    no, no")
420   (set_attr_alternative "type"
421    [(const_string "load_4") (const_string "store_4")
422     (const_string "fmov") (const_string "mov_reg")
423     (const_string "f_mcr") (const_string "f_mrc")
424     (const_string "fconsts") (const_string "neon_load1_1reg")
425     (const_string "neon_store1_1reg")
426     (if_then_else (match_test "arm_arch_thumb2")
427      (const_string "mov_imm")
428      (const_string "multiple"))])
429   (set_attr_alternative "length"
430    [(const_int 4) (const_int 4)
431     (const_int 4) (const_int 4)
432     (const_int 4) (const_int 4)
433     (const_int 4) (const_int 4)
434     (const_int 4)
435     (if_then_else (match_test "arm_arch_thumb2")
436      (const_int 4)
437      (const_int 8))])]
438)
439
440(define_insn "*movhf_vfp_neon"
441  [(set (match_operand:HF 0 "nonimmediate_operand" "= t,Um,r,m,t,r,t,r,r")
442	(match_operand:HF 1 "general_operand"	   " Um, t,m,r,t,r,r,t,F"))]
443  "TARGET_32BIT
444   && TARGET_HARD_FLOAT && TARGET_NEON_FP16
445   && !TARGET_VFP_FP16INST
446   && (   s_register_operand (operands[0], HFmode)
447       || s_register_operand (operands[1], HFmode))"
448  "*
449  switch (which_alternative)
450    {
451    case 0:     /* S register from memory */
452      return \"vld1.16\\t{%z0}, %A1\";
453    case 1:     /* memory from S register */
454      return \"vst1.16\\t{%z1}, %A0\";
455    case 2:     /* ARM register from memory */
456      return \"ldrh\\t%0, %1\\t%@ __fp16\";
457    case 3:     /* memory from ARM register */
458      return \"strh\\t%1, %0\\t%@ __fp16\";
459    case 4:	/* S register from S register */
460      return \"vmov.f32\\t%0, %1\";
461    case 5:	/* ARM register from ARM register */
462      return \"mov\\t%0, %1\\t%@ __fp16\";
463    case 6:	/* S register from ARM register */
464      return \"vmov\\t%0, %1\";
465    case 7:	/* ARM register from S register */
466      return \"vmov\\t%0, %1\";
467    case 8:	/* ARM register from constant */
468      {
469	long bits;
470	rtx ops[4];
471
472	bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
473			       HFmode);
474	ops[0] = operands[0];
475	ops[1] = GEN_INT (bits);
476	ops[2] = GEN_INT (bits & 0xff00);
477	ops[3] = GEN_INT (bits & 0x00ff);
478
479	if (arm_arch_thumb2)
480	  output_asm_insn (\"movw\\t%0, %1\", ops);
481	else
482	  output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops);
483	return \"\";
484       }
485    default:
486      gcc_unreachable ();
487    }
488  "
489  [(set_attr "conds" "unconditional")
490   (set_attr "type" "neon_load1_1reg,neon_store1_1reg,\
491                     load_4,store_4,fmov,mov_reg,f_mcr,f_mrc,multiple")
492   (set_attr "length" "4,4,4,4,4,4,4,4,8")]
493)
494
495;; FP16 without element load/store instructions.
496(define_insn "*movhf_vfp"
497  [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,t,r,t,r,r")
498	(match_operand:HF 1 "general_operand"	   " m,r,t,r,r,t,F"))]
499  "TARGET_32BIT
500   && TARGET_HARD_FLOAT
501   && !TARGET_NEON_FP16
502   && !TARGET_VFP_FP16INST
503   && (   s_register_operand (operands[0], HFmode)
504       || s_register_operand (operands[1], HFmode))"
505  "*
506  switch (which_alternative)
507    {
508    case 0:     /* ARM register from memory */
509      return \"ldrh\\t%0, %1\\t%@ __fp16\";
510    case 1:     /* memory from ARM register */
511      return \"strh\\t%1, %0\\t%@ __fp16\";
512    case 2:	/* S register from S register */
513      return \"vmov.f32\\t%0, %1\";
514    case 3:	/* ARM register from ARM register */
515      return \"mov\\t%0, %1\\t%@ __fp16\";
516    case 4:	/* S register from ARM register */
517      return \"vmov\\t%0, %1\";
518    case 5:	/* ARM register from S register */
519      return \"vmov\\t%0, %1\";
520    case 6:	/* ARM register from constant */
521      {
522	long bits;
523	rtx ops[4];
524
525	bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]),
526			       HFmode);
527	ops[0] = operands[0];
528	ops[1] = GEN_INT (bits);
529	ops[2] = GEN_INT (bits & 0xff00);
530	ops[3] = GEN_INT (bits & 0x00ff);
531
532	if (arm_arch_thumb2)
533	  output_asm_insn (\"movw\\t%0, %1\", ops);
534	else
535	  output_asm_insn (\"mov\\t%0, %2\;orr\\t%0, %0, %3\", ops);
536	return \"\";
537       }
538    default:
539      gcc_unreachable ();
540    }
541  "
542  [(set_attr "conds" "unconditional")
543   (set_attr "type" "load_4,store_4,fmov,mov_reg,f_mcr,f_mrc,multiple")
544   (set_attr "length" "4,4,4,4,4,4,8")]
545)
546
547
548;; SFmode moves
549;; Disparage the w<->r cases because reloading an invalid address is
550;; preferable to loading the value via integer registers.
551
552(define_insn "*movsf_vfp"
553  [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t ,t  ,Uv,r ,m,t,r")
554        (match_operand:SF 1 "general_operand"	   " ?r,t,Dv,UvE,t, mE,r,t,r"))]
555  "TARGET_ARM && TARGET_HARD_FLOAT
556   && (   s_register_operand (operands[0], SFmode)
557       || s_register_operand (operands[1], SFmode))"
558  "*
559  switch (which_alternative)
560    {
561    case 0:
562      return \"vmov%?\\t%0, %1\";
563    case 1:
564      return \"vmov%?\\t%0, %1\";
565    case 2:
566      return \"vmov%?.f32\\t%0, %1\";
567    case 3: case 4:
568      return output_move_vfp (operands);
569    case 5:
570      return \"ldr%?\\t%0, %1\\t%@ float\";
571    case 6:
572      return \"str%?\\t%1, %0\\t%@ float\";
573    case 7:
574      return \"vmov%?.f32\\t%0, %1\";
575    case 8:
576      return \"mov%?\\t%0, %1\\t%@ float\";
577    default:
578      gcc_unreachable ();
579    }
580  "
581  [(set_attr "predicable" "yes")
582   (set_attr "type"
583     "f_mcr,f_mrc,fconsts,f_loads,f_stores,load_4,store_4,fmov,mov_reg")
584   (set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*")
585   (set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")]
586)
587
588(define_insn "*thumb2_movsf_vfp"
589  [(set (match_operand:SF 0 "nonimmediate_operand" "=t,?r,t, t  ,Uv,r ,m,t,r")
590	(match_operand:SF 1 "general_operand"	   " ?r,t,Dv,UvE,t, mE,r,t,r"))]
591  "TARGET_THUMB2 && TARGET_HARD_FLOAT
592   && (   s_register_operand (operands[0], SFmode)
593       || s_register_operand (operands[1], SFmode))"
594  "*
595  switch (which_alternative)
596    {
597    case 0:
598      return \"vmov%?\\t%0, %1\";
599    case 1:
600      return \"vmov%?\\t%0, %1\";
601    case 2:
602      return \"vmov%?.f32\\t%0, %1\";
603    case 3: case 4:
604      return output_move_vfp (operands);
605    case 5:
606      return \"ldr%?\\t%0, %1\\t%@ float\";
607    case 6:
608      return \"str%?\\t%1, %0\\t%@ float\";
609    case 7:
610      return \"vmov%?.f32\\t%0, %1\";
611    case 8:
612      return \"mov%?\\t%0, %1\\t%@ float\";
613    default:
614      gcc_unreachable ();
615    }
616  "
617  [(set_attr "predicable" "yes")
618   (set_attr "type"
619     "f_mcr,f_mrc,fconsts,f_loads,f_stores,load_4,store_4,fmov,mov_reg")
620   (set_attr "pool_range" "*,*,*,1018,*,4090,*,*,*")
621   (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")]
622)
623
624;; DFmode moves
625
626(define_insn "*movdf_vfp"
627  [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w,w  ,Uv,r, m,w,r")
628	(match_operand:DF 1 "soft_df_operand"		   " ?r,w,Dy,G,UvF,w ,mF,r,w,r"))]
629  "TARGET_ARM && TARGET_HARD_FLOAT
630   && (   register_operand (operands[0], DFmode)
631       || register_operand (operands[1], DFmode))"
632  "*
633  {
634    switch (which_alternative)
635      {
636      case 0:
637	return \"vmov%?\\t%P0, %Q1, %R1\";
638      case 1:
639	return \"vmov%?\\t%Q0, %R0, %P1\";
640      case 2:
641	gcc_assert (TARGET_VFP_DOUBLE);
642        return \"vmov%?.f64\\t%P0, %1\";
643      case 3:
644	gcc_assert (TARGET_VFP_DOUBLE);
645	return \"vmov.i64\\t%P0, #0\\t%@ float\";
646      case 4: case 5:
647	return output_move_vfp (operands);
648      case 6: case 7:
649	return output_move_double (operands, true, NULL);
650      case 8:
651	if (TARGET_VFP_SINGLE)
652	  return \"vmov%?.f32\\t%0, %1\;vmov%?.f32\\t%p0, %p1\";
653	else
654	  return \"vmov%?.f64\\t%P0, %P1\";
655      case 9:
656        return \"#\";
657      default:
658	gcc_unreachable ();
659      }
660    }
661  "
662  [(set_attr "type" "f_mcrr,f_mrrc,fconstd,neon_move,f_loadd,f_stored,\
663                     load_8,store_8,ffarithd,multiple")
664   (set (attr "length") (cond [(eq_attr "alternative" "6,7,9") (const_int 8)
665			       (eq_attr "alternative" "8")
666				(if_then_else
667				 (match_test "TARGET_VFP_SINGLE")
668				 (const_int 8)
669				 (const_int 4))]
670			      (const_int 4)))
671   (set_attr "predicable" "yes,yes,yes,no,yes,yes,yes,yes,yes,yes")
672   (set_attr "pool_range" "*,*,*,*,1020,*,1020,*,*,*")
673   (set_attr "neg_pool_range" "*,*,*,*,1004,*,1004,*,*,*")
674   (set_attr "arch" "any,any,any,neon,any,any,any,any,any,any")]
675)
676
677(define_insn "*thumb2_movdf_vfp"
678  [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w,w  ,Uv,r ,m,w,r")
679	(match_operand:DF 1 "soft_df_operand"		   " ?r,w,Dy,G,UvF,w, mF,r, w,r"))]
680  "TARGET_THUMB2 && TARGET_HARD_FLOAT
681   && (   register_operand (operands[0], DFmode)
682       || register_operand (operands[1], DFmode))"
683  "*
684  {
685    switch (which_alternative)
686      {
687      case 0:
688	return \"vmov%?\\t%P0, %Q1, %R1\";
689      case 1:
690	return \"vmov%?\\t%Q0, %R0, %P1\";
691      case 2:
692	gcc_assert (TARGET_VFP_DOUBLE);
693	return \"vmov%?.f64\\t%P0, %1\";
694      case 3:
695	gcc_assert (TARGET_VFP_DOUBLE);
696	return \"vmov.i64\\t%P0, #0\\t%@ float\";
697      case 4: case 5:
698	return output_move_vfp (operands);
699      case 6: case 7: case 9:
700	return output_move_double (operands, true, NULL);
701      case 8:
702	if (TARGET_VFP_SINGLE)
703	  return \"vmov%?.f32\\t%0, %1\;vmov%?.f32\\t%p0, %p1\";
704	else
705	  return \"vmov%?.f64\\t%P0, %P1\";
706      default:
707	abort ();
708      }
709    }
710  "
711  [(set_attr "type" "f_mcrr,f_mrrc,fconstd,neon_move,f_loadd,\
712                     f_stored,load_8,store_8,ffarithd,multiple")
713   (set (attr "length") (cond [(eq_attr "alternative" "6,7,9") (const_int 8)
714			       (eq_attr "alternative" "8")
715				(if_then_else
716				 (match_test "TARGET_VFP_SINGLE")
717				 (const_int 8)
718				 (const_int 4))]
719			      (const_int 4)))
720   (set_attr "pool_range" "*,*,*,*,1018,*,4094,*,*,*")
721   (set_attr "neg_pool_range" "*,*,*,*,1008,*,0,*,*,*")
722   (set_attr "arch" "any,any,any,neon,any,any,any,any,any,any")]
723)
724
725
726;; Conditional move patterns
727
728(define_insn "*movsfcc_vfp"
729  [(set (match_operand:SF   0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
730	(if_then_else:SF
731	  (match_operator   3 "arm_comparison_operator"
732	    [(match_operand 4 "cc_register" "") (const_int 0)])
733	  (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
734	  (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
735  "TARGET_ARM && TARGET_HARD_FLOAT"
736  "@
737   vmov%D3.f32\\t%0, %2
738   vmov%d3.f32\\t%0, %1
739   vmov%D3.f32\\t%0, %2\;vmov%d3.f32\\t%0, %1
740   vmov%D3\\t%0, %2
741   vmov%d3\\t%0, %1
742   vmov%D3\\t%0, %2\;vmov%d3\\t%0, %1
743   vmov%D3\\t%0, %2
744   vmov%d3\\t%0, %1
745   vmov%D3\\t%0, %2\;vmov%d3\\t%0, %1"
746   [(set_attr "conds" "use")
747    (set_attr "length" "4,4,8,4,4,8,4,4,8")
748    (set_attr "type" "fmov,fmov,fmov,f_mcr,f_mcr,f_mcr,f_mrc,f_mrc,f_mrc")]
749)
750
751(define_insn "*thumb2_movsfcc_vfp"
752  [(set (match_operand:SF   0 "s_register_operand" "=t,t,t,t,t,t,?r,?r,?r")
753	(if_then_else:SF
754	  (match_operator   3 "arm_comparison_operator"
755	    [(match_operand 4 "cc_register" "") (const_int 0)])
756	  (match_operand:SF 1 "s_register_operand" "0,t,t,0,?r,?r,0,t,t")
757	  (match_operand:SF 2 "s_register_operand" "t,0,t,?r,0,?r,t,0,t")))]
758  "TARGET_THUMB2 && TARGET_HARD_FLOAT && !arm_restrict_it"
759  "@
760   it\\t%D3\;vmov%D3.f32\\t%0, %2
761   it\\t%d3\;vmov%d3.f32\\t%0, %1
762   ite\\t%D3\;vmov%D3.f32\\t%0, %2\;vmov%d3.f32\\t%0, %1
763   it\\t%D3\;vmov%D3\\t%0, %2
764   it\\t%d3\;vmov%d3\\t%0, %1
765   ite\\t%D3\;vmov%D3\\t%0, %2\;vmov%d3\\t%0, %1
766   it\\t%D3\;vmov%D3\\t%0, %2
767   it\\t%d3\;vmov%d3\\t%0, %1
768   ite\\t%D3\;vmov%D3\\t%0, %2\;vmov%d3\\t%0, %1"
769   [(set_attr "conds" "use")
770    (set_attr "length" "6,6,10,6,6,10,6,6,10")
771    (set_attr "type" "fmov,fmov,fmov,f_mcr,f_mcr,f_mcr,f_mrc,f_mrc,f_mrc")]
772)
773
774(define_insn "*movdfcc_vfp"
775  [(set (match_operand:DF   0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
776	(if_then_else:DF
777	  (match_operator   3 "arm_comparison_operator"
778	    [(match_operand 4 "cc_register" "") (const_int 0)])
779	  (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
780	  (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
781  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
782  "@
783   vmov%D3.f64\\t%P0, %P2
784   vmov%d3.f64\\t%P0, %P1
785   vmov%D3.f64\\t%P0, %P2\;vmov%d3.f64\\t%P0, %P1
786   vmov%D3\\t%P0, %Q2, %R2
787   vmov%d3\\t%P0, %Q1, %R1
788   vmov%D3\\t%P0, %Q2, %R2\;vmov%d3\\t%P0, %Q1, %R1
789   vmov%D3\\t%Q0, %R0, %P2
790   vmov%d3\\t%Q0, %R0, %P1
791   vmov%D3\\t%Q0, %R0, %P2\;vmov%d3\\t%Q0, %R0, %P1"
792   [(set_attr "conds" "use")
793    (set_attr "length" "4,4,8,4,4,8,4,4,8")
794    (set_attr "type" "ffarithd,ffarithd,ffarithd,f_mcr,f_mcr,f_mcr,f_mrrc,f_mrrc,f_mrrc")]
795)
796
797(define_insn "*thumb2_movdfcc_vfp"
798  [(set (match_operand:DF   0 "s_register_operand" "=w,w,w,w,w,w,?r,?r,?r")
799	(if_then_else:DF
800	  (match_operator   3 "arm_comparison_operator"
801	    [(match_operand 4 "cc_register" "") (const_int 0)])
802	  (match_operand:DF 1 "s_register_operand" "0,w,w,0,?r,?r,0,w,w")
803	  (match_operand:DF 2 "s_register_operand" "w,0,w,?r,0,?r,w,0,w")))]
804  "TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE && !arm_restrict_it"
805  "@
806   it\\t%D3\;vmov%D3.f64\\t%P0, %P2
807   it\\t%d3\;vmov%d3.f64\\t%P0, %P1
808   ite\\t%D3\;vmov%D3.f64\\t%P0, %P2\;vmov%d3.f64\\t%P0, %P1
809   it\t%D3\;vmov%D3\\t%P0, %Q2, %R2
810   it\t%d3\;vmov%d3\\t%P0, %Q1, %R1
811   ite\\t%D3\;vmov%D3\\t%P0, %Q2, %R2\;vmov%d3\\t%P0, %Q1, %R1
812   it\t%D3\;vmov%D3\\t%Q0, %R0, %P2
813   it\t%d3\;vmov%d3\\t%Q0, %R0, %P1
814   ite\\t%D3\;vmov%D3\\t%Q0, %R0, %P2\;vmov%d3\\t%Q0, %R0, %P1"
815   [(set_attr "conds" "use")
816    (set_attr "length" "6,6,10,6,6,10,6,6,10")
817    (set_attr "type" "ffarithd,ffarithd,ffarithd,f_mcr,f_mcr,f_mcrr,f_mrrc,f_mrrc,f_mrrc")]
818)
819
820
821;; Sign manipulation functions
822
823(define_insn "*abssf2_vfp"
824  [(set (match_operand:SF	  0 "s_register_operand" "=t")
825	(abs:SF (match_operand:SF 1 "s_register_operand" "t")))]
826  "TARGET_32BIT && TARGET_HARD_FLOAT"
827  "vabs%?.f32\\t%0, %1"
828  [(set_attr "predicable" "yes")
829   (set_attr "type" "ffariths")]
830)
831
832(define_insn "*absdf2_vfp"
833  [(set (match_operand:DF	  0 "s_register_operand" "=w")
834	(abs:DF (match_operand:DF 1 "s_register_operand" "w")))]
835  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
836  "vabs%?.f64\\t%P0, %P1"
837  [(set_attr "predicable" "yes")
838   (set_attr "type" "ffarithd")]
839)
840
841(define_insn "*negsf2_vfp"
842  [(set (match_operand:SF	  0 "s_register_operand" "=t,?r")
843	(neg:SF (match_operand:SF 1 "s_register_operand" "t,r")))]
844  "TARGET_32BIT && TARGET_HARD_FLOAT"
845  "@
846   vneg%?.f32\\t%0, %1
847   eor%?\\t%0, %1, #-2147483648"
848  [(set_attr "predicable" "yes")
849   (set_attr "type" "ffariths")]
850)
851
852(define_insn_and_split "*negdf2_vfp"
853  [(set (match_operand:DF	  0 "s_register_operand" "=w,?r,?r")
854	(neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))]
855  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
856  "@
857   vneg%?.f64\\t%P0, %P1
858   #
859   #"
860  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE && reload_completed
861   && arm_general_register_operand (operands[0], DFmode)"
862  [(set (match_dup 0) (match_dup 1))]
863  "
864  if (REGNO (operands[0]) == REGNO (operands[1]))
865    {
866      operands[0] = gen_highpart (SImode, operands[0]);
867      operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000));
868    }
869  else
870    {
871      rtx in_hi, in_lo, out_hi, out_lo;
872
873      in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]),
874			   GEN_INT (0x80000000));
875      in_lo = gen_lowpart (SImode, operands[1]);
876      out_hi = gen_highpart (SImode, operands[0]);
877      out_lo = gen_lowpart (SImode, operands[0]);
878
879      if (REGNO (in_lo) == REGNO (out_hi))
880        {
881          emit_insn (gen_rtx_SET (out_lo, in_lo));
882	  operands[0] = out_hi;
883          operands[1] = in_hi;
884        }
885      else
886        {
887          emit_insn (gen_rtx_SET (out_hi, in_hi));
888	  operands[0] = out_lo;
889          operands[1] = in_lo;
890        }
891    }
892  "
893  [(set_attr "predicable" "yes")
894   (set_attr "length" "4,4,8")
895   (set_attr "type" "ffarithd")]
896)
897
898;; ABS and NEG for FP16.
899(define_insn "<absneg_str>hf2"
900  [(set (match_operand:HF 0 "s_register_operand" "=w")
901    (ABSNEG:HF (match_operand:HF 1 "s_register_operand" "w")))]
902 "TARGET_VFP_FP16INST"
903 "v<absneg_str>.f16\t%0, %1"
904  [(set_attr "conds" "unconditional")
905   (set_attr "type" "ffariths")]
906)
907
908(define_expand "neon_vabshf"
909 [(set
910   (match_operand:HF 0 "s_register_operand")
911   (abs:HF (match_operand:HF 1 "s_register_operand")))]
912 "TARGET_VFP_FP16INST"
913{
914  emit_insn (gen_abshf2 (operands[0], operands[1]));
915  DONE;
916})
917
918;; VRND for FP16.
919(define_insn "neon_v<fp16_rnd_str>hf"
920  [(set (match_operand:HF 0 "s_register_operand" "=w")
921    (unspec:HF
922     [(match_operand:HF 1 "s_register_operand" "w")]
923     FP16_RND))]
924 "TARGET_VFP_FP16INST"
925 "<fp16_rnd_insn>.f16\t%0, %1"
926 [(set_attr "conds" "unconditional")
927  (set_attr "type" "neon_fp_round_s")]
928)
929
930(define_insn "neon_vrndihf"
931  [(set (match_operand:HF 0 "s_register_operand" "=w")
932    (unspec:HF
933     [(match_operand:HF 1 "s_register_operand" "w")]
934     UNSPEC_VRNDI))]
935  "TARGET_VFP_FP16INST"
936  "vrintr.f16\t%0, %1"
937 [(set_attr "conds" "unconditional")
938  (set_attr "type" "neon_fp_round_s")]
939)
940
941;; Arithmetic insns
942
943(define_insn "addhf3"
944  [(set
945    (match_operand:HF 0 "s_register_operand" "=w")
946    (plus:HF
947     (match_operand:HF 1 "s_register_operand" "w")
948     (match_operand:HF 2 "s_register_operand" "w")))]
949 "TARGET_VFP_FP16INST"
950 "vadd.f16\t%0, %1, %2"
951  [(set_attr "conds" "unconditional")
952   (set_attr "type" "fadds")]
953)
954
955(define_insn "*addsf3_vfp"
956  [(set (match_operand:SF	   0 "s_register_operand" "=t")
957	(plus:SF (match_operand:SF 1 "s_register_operand" "t")
958		 (match_operand:SF 2 "s_register_operand" "t")))]
959  "TARGET_32BIT && TARGET_HARD_FLOAT"
960  "vadd%?.f32\\t%0, %1, %2"
961  [(set_attr "predicable" "yes")
962   (set_attr "type" "fadds")]
963)
964
965(define_insn "*adddf3_vfp"
966  [(set (match_operand:DF	   0 "s_register_operand" "=w")
967	(plus:DF (match_operand:DF 1 "s_register_operand" "w")
968		 (match_operand:DF 2 "s_register_operand" "w")))]
969  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
970  "vadd%?.f64\\t%P0, %P1, %P2"
971  [(set_attr "predicable" "yes")
972   (set_attr "type" "faddd")]
973)
974
975(define_insn "subhf3"
976 [(set
977   (match_operand:HF 0 "s_register_operand" "=w")
978   (minus:HF
979    (match_operand:HF 1 "s_register_operand" "w")
980    (match_operand:HF 2 "s_register_operand" "w")))]
981 "TARGET_VFP_FP16INST"
982 "vsub.f16\t%0, %1, %2"
983  [(set_attr "conds" "unconditional")
984   (set_attr "type" "fadds")]
985)
986
987(define_insn "*subsf3_vfp"
988  [(set (match_operand:SF	    0 "s_register_operand" "=t")
989	(minus:SF (match_operand:SF 1 "s_register_operand" "t")
990		  (match_operand:SF 2 "s_register_operand" "t")))]
991  "TARGET_32BIT && TARGET_HARD_FLOAT"
992  "vsub%?.f32\\t%0, %1, %2"
993  [(set_attr "predicable" "yes")
994   (set_attr "type" "fadds")]
995)
996
997(define_insn "*subdf3_vfp"
998  [(set (match_operand:DF	    0 "s_register_operand" "=w")
999	(minus:DF (match_operand:DF 1 "s_register_operand" "w")
1000		  (match_operand:DF 2 "s_register_operand" "w")))]
1001  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1002  "vsub%?.f64\\t%P0, %P1, %P2"
1003  [(set_attr "predicable" "yes")
1004   (set_attr "type" "faddd")]
1005)
1006
1007
1008;; Division insns
1009
1010;; FP16 Division.
1011(define_insn "divhf3"
1012  [(set
1013    (match_operand:HF	   0 "s_register_operand" "=w")
1014    (div:HF
1015     (match_operand:HF 1 "s_register_operand" "w")
1016     (match_operand:HF 2 "s_register_operand" "w")))]
1017  "TARGET_VFP_FP16INST"
1018  "vdiv.f16\t%0, %1, %2"
1019  [(set_attr "conds" "unconditional")
1020   (set_attr "type" "fdivs")]
1021)
1022
1023; VFP9 Erratum 760019: It's potentially unsafe to overwrite the input
1024; operands, so mark the output as early clobber for VFPv2 on ARMv5 or
1025; earlier.
1026(define_insn "*divsf3_vfp"
1027  [(set (match_operand:SF	  0 "s_register_operand" "=&t,t")
1028	(div:SF (match_operand:SF 1 "s_register_operand" "t,t")
1029		(match_operand:SF 2 "s_register_operand" "t,t")))]
1030  "TARGET_32BIT && TARGET_HARD_FLOAT"
1031  "vdiv%?.f32\\t%0, %1, %2"
1032  [(set_attr "predicable" "yes")
1033   (set_attr "arch" "*,armv6_or_vfpv3")
1034   (set_attr "type" "fdivs")]
1035)
1036
1037(define_insn "*divdf3_vfp"
1038  [(set (match_operand:DF	  0 "s_register_operand" "=&w,w")
1039	(div:DF (match_operand:DF 1 "s_register_operand" "w,w")
1040		(match_operand:DF 2 "s_register_operand" "w,w")))]
1041  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1042  "vdiv%?.f64\\t%P0, %P1, %P2"
1043  [(set_attr "predicable" "yes")
1044   (set_attr "arch" "*,armv6_or_vfpv3")
1045   (set_attr "type" "fdivd")]
1046)
1047
1048
1049;; Multiplication insns
1050
1051(define_insn "mulhf3"
1052 [(set
1053   (match_operand:HF 0 "s_register_operand" "=w")
1054   (mult:HF (match_operand:HF 1 "s_register_operand" "w")
1055	    (match_operand:HF 2 "s_register_operand" "w")))]
1056  "TARGET_VFP_FP16INST"
1057  "vmul.f16\t%0, %1, %2"
1058  [(set_attr "conds" "unconditional")
1059   (set_attr "type" "fmuls")]
1060)
1061
1062(define_insn "*mulsf3_vfp"
1063  [(set (match_operand:SF	   0 "s_register_operand" "=t")
1064	(mult:SF (match_operand:SF 1 "s_register_operand" "t")
1065		 (match_operand:SF 2 "s_register_operand" "t")))]
1066  "TARGET_32BIT && TARGET_HARD_FLOAT"
1067  "vmul%?.f32\\t%0, %1, %2"
1068  [(set_attr "predicable" "yes")
1069   (set_attr "type" "fmuls")]
1070)
1071
1072(define_insn "*muldf3_vfp"
1073  [(set (match_operand:DF	   0 "s_register_operand" "=w")
1074	(mult:DF (match_operand:DF 1 "s_register_operand" "w")
1075		 (match_operand:DF 2 "s_register_operand" "w")))]
1076  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1077  "vmul%?.f64\\t%P0, %P1, %P2"
1078  [(set_attr "predicable" "yes")
1079   (set_attr "type" "fmuld")]
1080)
1081
1082(define_insn "*mulsf3neghf_vfp"
1083  [(set (match_operand:HF		   0 "s_register_operand" "=t")
1084	(mult:HF (neg:HF (match_operand:HF 1 "s_register_operand" "t"))
1085		 (match_operand:HF	   2 "s_register_operand" "t")))]
1086  "TARGET_VFP_FP16INST && !flag_rounding_math"
1087  "vnmul.f16\\t%0, %1, %2"
1088  [(set_attr "conds" "unconditional")
1089   (set_attr "type" "fmuls")]
1090)
1091
1092(define_insn "*negmulhf3_vfp"
1093  [(set (match_operand:HF		   0 "s_register_operand" "=t")
1094	(neg:HF (mult:HF (match_operand:HF 1 "s_register_operand" "t")
1095		 (match_operand:HF	   2 "s_register_operand" "t"))))]
1096  "TARGET_VFP_FP16INST"
1097  "vnmul.f16\\t%0, %1, %2"
1098  [(set_attr "conds" "unconditional")
1099   (set_attr "type" "fmuls")]
1100)
1101
1102(define_insn "*mulsf3negsf_vfp"
1103  [(set (match_operand:SF		   0 "s_register_operand" "=t")
1104	(mult:SF (neg:SF (match_operand:SF 1 "s_register_operand" "t"))
1105		 (match_operand:SF	   2 "s_register_operand" "t")))]
1106  "TARGET_32BIT && TARGET_HARD_FLOAT && !flag_rounding_math"
1107  "vnmul%?.f32\\t%0, %1, %2"
1108  [(set_attr "predicable" "yes")
1109   (set_attr "type" "fmuls")]
1110)
1111
1112(define_insn "*negmulsf3_vfp"
1113  [(set (match_operand:SF		   0 "s_register_operand" "=t")
1114	(neg:SF (mult:SF (match_operand:SF 1 "s_register_operand" "t")
1115		 (match_operand:SF	   2 "s_register_operand" "t"))))]
1116  "TARGET_32BIT && TARGET_HARD_FLOAT"
1117  "vnmul%?.f32\\t%0, %1, %2"
1118  [(set_attr "predicable" "yes")
1119   (set_attr "type" "fmuls")]
1120)
1121
1122(define_insn "*muldf3negdf_vfp"
1123  [(set (match_operand:DF		   0 "s_register_operand" "=w")
1124	(mult:DF (neg:DF (match_operand:DF 1 "s_register_operand" "w"))
1125		 (match_operand:DF	   2 "s_register_operand" "w")))]
1126  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE
1127  && !flag_rounding_math"
1128  "vnmul%?.f64\\t%P0, %P1, %P2"
1129  [(set_attr "predicable" "yes")
1130   (set_attr "type" "fmuld")]
1131)
1132
1133(define_insn "*negmuldf3_vfp"
1134  [(set (match_operand:DF		   0 "s_register_operand" "=w")
1135	(neg:DF (mult:DF (match_operand:DF 1 "s_register_operand" "w")
1136		 (match_operand:DF	   2 "s_register_operand" "w"))))]
1137  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1138  "vnmul%?.f64\\t%P0, %P1, %P2"
1139  [(set_attr "predicable" "yes")
1140   (set_attr "type" "fmuld")]
1141)
1142
1143
1144;; Multiply-accumulate insns
1145
1146;; 0 = 1 * 2 + 0
1147(define_insn "*mulsf3addhf_vfp"
1148 [(set (match_operand:HF 0 "s_register_operand" "=t")
1149       (plus:HF
1150	(mult:HF (match_operand:HF 2 "s_register_operand" "t")
1151		 (match_operand:HF 3 "s_register_operand" "t"))
1152	(match_operand:HF 1 "s_register_operand" "0")))]
1153  "TARGET_VFP_FP16INST"
1154  "vmla.f16\\t%0, %2, %3"
1155  [(set_attr "conds" "unconditional")
1156   (set_attr "type" "fmacs")]
1157)
1158
1159(define_insn "*mulsf3addsf_vfp"
1160  [(set (match_operand:SF		    0 "s_register_operand" "=t")
1161	(plus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
1162			  (match_operand:SF 3 "s_register_operand" "t"))
1163		 (match_operand:SF	    1 "s_register_operand" "0")))]
1164  "TARGET_32BIT && TARGET_HARD_FLOAT"
1165  "vmla%?.f32\\t%0, %2, %3"
1166  [(set_attr "predicable" "yes")
1167   (set_attr "type" "fmacs")]
1168)
1169
1170(define_insn "*muldf3adddf_vfp"
1171  [(set (match_operand:DF		    0 "s_register_operand" "=w")
1172	(plus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
1173			  (match_operand:DF 3 "s_register_operand" "w"))
1174		 (match_operand:DF	    1 "s_register_operand" "0")))]
1175  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1176  "vmla%?.f64\\t%P0, %P2, %P3"
1177  [(set_attr "predicable" "yes")
1178   (set_attr "type" "fmacd")]
1179)
1180
1181;; 0 = 1 * 2 - 0
1182(define_insn "*mulhf3subhf_vfp"
1183  [(set (match_operand:HF 0 "s_register_operand" "=t")
1184	(minus:HF (mult:HF (match_operand:HF 2 "s_register_operand" "t")
1185			   (match_operand:HF 3 "s_register_operand" "t"))
1186		  (match_operand:HF 1 "s_register_operand" "0")))]
1187  "TARGET_VFP_FP16INST"
1188  "vnmls.f16\\t%0, %2, %3"
1189  [(set_attr "conds" "unconditional")
1190   (set_attr "type" "fmacs")]
1191)
1192
1193(define_insn "*mulsf3subsf_vfp"
1194  [(set (match_operand:SF		     0 "s_register_operand" "=t")
1195	(minus:SF (mult:SF (match_operand:SF 2 "s_register_operand" "t")
1196			   (match_operand:SF 3 "s_register_operand" "t"))
1197		  (match_operand:SF	     1 "s_register_operand" "0")))]
1198  "TARGET_32BIT && TARGET_HARD_FLOAT"
1199  "vnmls%?.f32\\t%0, %2, %3"
1200  [(set_attr "predicable" "yes")
1201   (set_attr "type" "fmacs")]
1202)
1203
1204(define_insn "*muldf3subdf_vfp"
1205  [(set (match_operand:DF		     0 "s_register_operand" "=w")
1206	(minus:DF (mult:DF (match_operand:DF 2 "s_register_operand" "w")
1207			   (match_operand:DF 3 "s_register_operand" "w"))
1208		  (match_operand:DF	     1 "s_register_operand" "0")))]
1209  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1210  "vnmls%?.f64\\t%P0, %P2, %P3"
1211  [(set_attr "predicable" "yes")
1212   (set_attr "type" "fmacd")]
1213)
1214
1215;; 0 = -(1 * 2) + 0
1216(define_insn "*mulhf3neghfaddhf_vfp"
1217  [(set (match_operand:HF 0 "s_register_operand" "=t")
1218	(minus:HF (match_operand:HF 1 "s_register_operand" "0")
1219		  (mult:HF (match_operand:HF 2 "s_register_operand" "t")
1220			   (match_operand:HF 3 "s_register_operand" "t"))))]
1221  "TARGET_VFP_FP16INST"
1222  "vmls.f16\\t%0, %2, %3"
1223  [(set_attr "conds" "unconditional")
1224   (set_attr "type" "fmacs")]
1225)
1226
1227(define_insn "*mulsf3negsfaddsf_vfp"
1228  [(set (match_operand:SF		     0 "s_register_operand" "=t")
1229	(minus:SF (match_operand:SF	     1 "s_register_operand" "0")
1230		  (mult:SF (match_operand:SF 2 "s_register_operand" "t")
1231			   (match_operand:SF 3 "s_register_operand" "t"))))]
1232  "TARGET_32BIT && TARGET_HARD_FLOAT"
1233  "vmls%?.f32\\t%0, %2, %3"
1234  [(set_attr "predicable" "yes")
1235   (set_attr "type" "fmacs")]
1236)
1237
1238(define_insn "*fmuldf3negdfadddf_vfp"
1239  [(set (match_operand:DF		     0 "s_register_operand" "=w")
1240	(minus:DF (match_operand:DF	     1 "s_register_operand" "0")
1241		  (mult:DF (match_operand:DF 2 "s_register_operand" "w")
1242			   (match_operand:DF 3 "s_register_operand" "w"))))]
1243  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1244  "vmls%?.f64\\t%P0, %P2, %P3"
1245  [(set_attr "predicable" "yes")
1246   (set_attr "type" "fmacd")]
1247)
1248
1249
1250;; 0 = -(1 * 2) - 0
1251(define_insn "*mulhf3neghfsubhf_vfp"
1252  [(set (match_operand:HF 0 "s_register_operand" "=t")
1253	(minus:HF (mult:HF
1254		   (neg:HF (match_operand:HF 2 "s_register_operand" "t"))
1255		   (match_operand:HF 3 "s_register_operand" "t"))
1256		  (match_operand:HF 1 "s_register_operand" "0")))]
1257  "TARGET_VFP_FP16INST"
1258  "vnmla.f16\\t%0, %2, %3"
1259  [(set_attr "conds" "unconditional")
1260   (set_attr "type" "fmacs")]
1261)
1262
1263(define_insn "*mulsf3negsfsubsf_vfp"
1264  [(set (match_operand:SF		      0 "s_register_operand" "=t")
1265	(minus:SF (mult:SF
1266		    (neg:SF (match_operand:SF 2 "s_register_operand" "t"))
1267		    (match_operand:SF	      3 "s_register_operand" "t"))
1268		  (match_operand:SF	      1 "s_register_operand" "0")))]
1269  "TARGET_32BIT && TARGET_HARD_FLOAT"
1270  "vnmla%?.f32\\t%0, %2, %3"
1271  [(set_attr "predicable" "yes")
1272   (set_attr "type" "fmacs")]
1273)
1274
1275(define_insn "*muldf3negdfsubdf_vfp"
1276  [(set (match_operand:DF		      0 "s_register_operand" "=w")
1277	(minus:DF (mult:DF
1278		    (neg:DF (match_operand:DF 2 "s_register_operand" "w"))
1279		    (match_operand:DF	      3 "s_register_operand" "w"))
1280		  (match_operand:DF	      1 "s_register_operand" "0")))]
1281  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1282  "vnmla%?.f64\\t%P0, %P2, %P3"
1283  [(set_attr "predicable" "yes")
1284   (set_attr "type" "fmacd")]
1285)
1286
1287;; Fused-multiply-accumulate
1288
1289(define_insn "fmahf4"
1290  [(set (match_operand:HF 0 "register_operand" "=w")
1291    (fma:HF
1292     (match_operand:HF 1 "register_operand" "w")
1293     (match_operand:HF 2 "register_operand" "w")
1294     (match_operand:HF 3 "register_operand" "0")))]
1295 "TARGET_VFP_FP16INST"
1296 "vfma.f16\\t%0, %1, %2"
1297 [(set_attr "conds" "unconditional")
1298  (set_attr "type" "ffmas")]
1299)
1300
1301(define_expand "neon_vfmahf"
1302  [(match_operand:HF 0 "s_register_operand")
1303   (match_operand:HF 1 "s_register_operand")
1304   (match_operand:HF 2 "s_register_operand")
1305   (match_operand:HF 3 "s_register_operand")]
1306  "TARGET_VFP_FP16INST"
1307{
1308  emit_insn (gen_fmahf4 (operands[0], operands[2], operands[3],
1309			 operands[1]));
1310  DONE;
1311})
1312
1313(define_insn "fma<SDF:mode>4"
1314  [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
1315        (fma:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>")
1316		 (match_operand:SDF 2 "register_operand" "<F_constraint>")
1317		 (match_operand:SDF 3 "register_operand" "0")))]
1318  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
1319  "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1320  [(set_attr "predicable" "yes")
1321   (set_attr "type" "ffma<vfp_type>")]
1322)
1323
1324(define_insn "fmsubhf4_fp16"
1325 [(set (match_operand:HF 0 "register_operand" "=w")
1326   (fma:HF
1327    (neg:HF (match_operand:HF 1 "register_operand" "w"))
1328    (match_operand:HF 2 "register_operand" "w")
1329    (match_operand:HF 3 "register_operand" "0")))]
1330 "TARGET_VFP_FP16INST"
1331 "vfms.f16\\t%0, %1, %2"
1332 [(set_attr "conds" "unconditional")
1333  (set_attr "type" "ffmas")]
1334)
1335
1336(define_expand "neon_vfmshf"
1337  [(match_operand:HF 0 "s_register_operand")
1338   (match_operand:HF 1 "s_register_operand")
1339   (match_operand:HF 2 "s_register_operand")
1340   (match_operand:HF 3 "s_register_operand")]
1341  "TARGET_VFP_FP16INST"
1342{
1343  emit_insn (gen_fmsubhf4_fp16 (operands[0], operands[2], operands[3],
1344				operands[1]));
1345  DONE;
1346})
1347
1348(define_insn "*fmsub<SDF:mode>4"
1349  [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
1350	(fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand"
1351					     "<F_constraint>"))
1352		 (match_operand:SDF 2 "register_operand" "<F_constraint>")
1353		 (match_operand:SDF 3 "register_operand" "0")))]
1354  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
1355  "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1356  [(set_attr "predicable" "yes")
1357   (set_attr "type" "ffma<vfp_type>")]
1358)
1359
1360(define_insn "*fnmsubhf4"
1361  [(set (match_operand:HF 0 "register_operand" "=w")
1362	(fma:HF (match_operand:HF 1 "register_operand" "w")
1363		 (match_operand:HF 2 "register_operand" "w")
1364		 (neg:HF (match_operand:HF 3 "register_operand" "0"))))]
1365  "TARGET_VFP_FP16INST"
1366  "vfnms.f16\\t%0, %1, %2"
1367  [(set_attr "conds" "unconditional")
1368   (set_attr "type" "ffmas")]
1369)
1370
1371(define_insn "*fnmsub<SDF:mode>4"
1372  [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
1373	(fma:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>")
1374		 (match_operand:SDF 2 "register_operand" "<F_constraint>")
1375		 (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))]
1376  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
1377  "vfnms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1378  [(set_attr "predicable" "yes")
1379   (set_attr "type" "ffma<vfp_type>")]
1380)
1381
1382(define_insn "*fnmaddhf4"
1383  [(set (match_operand:HF 0 "register_operand" "=w")
1384	(fma:HF (neg:HF (match_operand:HF 1 "register_operand" "w"))
1385		 (match_operand:HF 2 "register_operand" "w")
1386		 (neg:HF (match_operand:HF 3 "register_operand" "0"))))]
1387  "TARGET_VFP_FP16INST"
1388  "vfnma.f16\\t%0, %1, %2"
1389  [(set_attr "conds" "unconditional")
1390   (set_attr "type" "ffmas")]
1391)
1392
1393(define_insn "*fnmadd<SDF:mode>4"
1394  [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
1395	(fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand"
1396					       "<F_constraint>"))
1397		 (match_operand:SDF 2 "register_operand" "<F_constraint>")
1398		 (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))]
1399  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
1400  "vfnma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1401  [(set_attr "predicable" "yes")
1402   (set_attr "type" "ffma<vfp_type>")]
1403)
1404
1405
1406;; Conversion routines
1407
1408(define_insn "*extendsfdf2_vfp"
1409  [(set (match_operand:DF		   0 "s_register_operand" "=w")
1410	(float_extend:DF (match_operand:SF 1 "s_register_operand" "t")))]
1411  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1412  "vcvt%?.f64.f32\\t%P0, %1"
1413  [(set_attr "predicable" "yes")
1414   (set_attr "type" "f_cvt")]
1415)
1416
1417(define_insn "*truncdfsf2_vfp"
1418  [(set (match_operand:SF		   0 "s_register_operand" "=t")
1419	(float_truncate:SF (match_operand:DF 1 "s_register_operand" "w")))]
1420  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1421  "vcvt%?.f32.f64\\t%0, %P1"
1422  [(set_attr "predicable" "yes")
1423   (set_attr "type" "f_cvt")]
1424)
1425
1426(define_insn "extendhfsf2"
1427  [(set (match_operand:SF		   0 "s_register_operand" "=t")
1428	(float_extend:SF (match_operand:HF 1 "s_register_operand" "t")))]
1429  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FP16 || TARGET_VFP_FP16INST)"
1430  "vcvtb%?.f32.f16\\t%0, %1"
1431  [(set_attr "predicable" "yes")
1432   (set_attr "type" "f_cvt")]
1433)
1434
1435(define_insn "*truncdfhf2"
1436  [(set (match_operand:HF		   0 "s_register_operand" "=t")
1437	(float_truncate:HF (match_operand:DF 1 "s_register_operand" "w")))]
1438  "TARGET_32BIT && TARGET_FP16_TO_DOUBLE"
1439  "vcvtb%?.f16.f64\\t%0, %P1"
1440  [(set_attr "predicable" "yes")
1441   (set_attr "type" "f_cvt")]
1442)
1443
1444(define_insn "*extendhfdf2"
1445  [(set (match_operand:DF		   0 "s_register_operand" "=w")
1446	(float_extend:DF (match_operand:HF 1 "s_register_operand" "t")))]
1447  "TARGET_32BIT && TARGET_FP16_TO_DOUBLE"
1448  "vcvtb%?.f64.f16\\t%P0, %1"
1449  [(set_attr "predicable" "yes")
1450   (set_attr "type" "f_cvt")]
1451)
1452
1453(define_insn "truncsfhf2"
1454  [(set (match_operand:HF		   0 "s_register_operand" "=t")
1455	(float_truncate:HF (match_operand:SF 1 "s_register_operand" "t")))]
1456  "TARGET_32BIT && TARGET_HARD_FLOAT && (TARGET_FP16 || TARGET_VFP_FP16INST)"
1457  "vcvtb%?.f16.f32\\t%0, %1"
1458  [(set_attr "predicable" "yes")
1459   (set_attr "type" "f_cvt")]
1460)
1461
1462(define_insn "*truncsisf2_vfp"
1463  [(set (match_operand:SI		  0 "s_register_operand" "=t")
1464	(fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
1465  "TARGET_32BIT && TARGET_HARD_FLOAT"
1466  "vcvt%?.s32.f32\\t%0, %1"
1467  [(set_attr "predicable" "yes")
1468   (set_attr "type" "f_cvtf2i")]
1469)
1470
1471(define_insn "*truncsidf2_vfp"
1472  [(set (match_operand:SI		  0 "s_register_operand" "=t")
1473	(fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "w"))))]
1474  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1475  "vcvt%?.s32.f64\\t%0, %P1"
1476  [(set_attr "predicable" "yes")
1477   (set_attr "type" "f_cvtf2i")]
1478)
1479
1480
1481(define_insn "fixuns_truncsfsi2"
1482  [(set (match_operand:SI		  0 "s_register_operand" "=t")
1483	(unsigned_fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" "t"))))]
1484  "TARGET_32BIT && TARGET_HARD_FLOAT"
1485  "vcvt%?.u32.f32\\t%0, %1"
1486  [(set_attr "predicable" "yes")
1487   (set_attr "type" "f_cvtf2i")]
1488)
1489
1490(define_insn "fixuns_truncdfsi2"
1491  [(set (match_operand:SI		  0 "s_register_operand" "=t")
1492	(unsigned_fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" "t"))))]
1493  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1494  "vcvt%?.u32.f64\\t%0, %P1"
1495  [(set_attr "predicable" "yes")
1496   (set_attr "type" "f_cvtf2i")]
1497)
1498
1499
1500(define_insn "*floatsisf2_vfp"
1501  [(set (match_operand:SF	    0 "s_register_operand" "=t")
1502	(float:SF (match_operand:SI 1 "s_register_operand" "t")))]
1503  "TARGET_32BIT && TARGET_HARD_FLOAT"
1504  "vcvt%?.f32.s32\\t%0, %1"
1505  [(set_attr "predicable" "yes")
1506   (set_attr "type" "f_cvti2f")]
1507)
1508
1509(define_insn "*floatsidf2_vfp"
1510  [(set (match_operand:DF	    0 "s_register_operand" "=w")
1511	(float:DF (match_operand:SI 1 "s_register_operand" "t")))]
1512  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1513  "vcvt%?.f64.s32\\t%P0, %1"
1514  [(set_attr "predicable" "yes")
1515   (set_attr "type" "f_cvti2f")]
1516)
1517
1518
1519(define_insn "floatunssisf2"
1520  [(set (match_operand:SF	    0 "s_register_operand" "=t")
1521	(unsigned_float:SF (match_operand:SI 1 "s_register_operand" "t")))]
1522  "TARGET_32BIT && TARGET_HARD_FLOAT"
1523  "vcvt%?.f32.u32\\t%0, %1"
1524  [(set_attr "predicable" "yes")
1525   (set_attr "type" "f_cvti2f")]
1526)
1527
1528(define_insn "floatunssidf2"
1529  [(set (match_operand:DF	    0 "s_register_operand" "=w")
1530	(unsigned_float:DF (match_operand:SI 1 "s_register_operand" "t")))]
1531  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1532  "vcvt%?.f64.u32\\t%P0, %1"
1533  [(set_attr "predicable" "yes")
1534   (set_attr "type" "f_cvti2f")]
1535)
1536
1537
1538;; Sqrt insns.
1539
1540(define_insn "neon_vsqrthf"
1541  [(set (match_operand:HF 0 "s_register_operand" "=w")
1542	(sqrt:HF (match_operand:HF 1 "s_register_operand" "w")))]
1543  "TARGET_VFP_FP16INST"
1544  "vsqrt.f16\t%0, %1"
1545  [(set_attr "conds" "unconditional")
1546   (set_attr "type" "fsqrts")]
1547)
1548
1549(define_insn "neon_vrsqrtshf"
1550  [(set
1551    (match_operand:HF 0 "s_register_operand" "=w")
1552    (unspec:HF [(match_operand:HF 1 "s_register_operand" "w")
1553		(match_operand:HF 2 "s_register_operand" "w")]
1554     UNSPEC_VRSQRTS))]
1555 "TARGET_VFP_FP16INST"
1556 "vrsqrts.f16\t%0, %1, %2"
1557 [(set_attr "conds" "unconditional")
1558  (set_attr "type" "fsqrts")]
1559)
1560
1561; VFP9 Erratum 760019: It's potentially unsafe to overwrite the input
1562; operands, so mark the output as early clobber for VFPv2 on ARMv5 or
1563; earlier.
1564(define_insn "*sqrtsf2_vfp"
1565  [(set (match_operand:SF	   0 "s_register_operand" "=&t,t")
1566	(sqrt:SF (match_operand:SF 1 "s_register_operand" "t,t")))]
1567  "TARGET_32BIT && TARGET_HARD_FLOAT"
1568  "vsqrt%?.f32\\t%0, %1"
1569  [(set_attr "predicable" "yes")
1570   (set_attr "arch" "*,armv6_or_vfpv3")
1571   (set_attr "type" "fsqrts")]
1572)
1573
1574(define_insn "*sqrtdf2_vfp"
1575  [(set (match_operand:DF	   0 "s_register_operand" "=&w,w")
1576	(sqrt:DF (match_operand:DF 1 "s_register_operand" "w,w")))]
1577  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1578  "vsqrt%?.f64\\t%P0, %P1"
1579  [(set_attr "predicable" "yes")
1580   (set_attr "arch" "*,armv6_or_vfpv3")
1581   (set_attr "type" "fsqrtd")]
1582)
1583
1584
1585;; Patterns to split/copy vfp condition flags.
1586
1587(define_insn "*movcc_vfp"
1588  [(set (reg CC_REGNUM)
1589	(reg VFPCC_REGNUM))]
1590  "TARGET_32BIT && TARGET_HARD_FLOAT"
1591  "vmrs%?\\tAPSR_nzcv, FPSCR"
1592  [(set_attr "conds" "set")
1593   (set_attr "type" "f_flag")]
1594)
1595
1596(define_insn_and_split "*cmpsf_split_vfp"
1597  [(set (reg:CCFP CC_REGNUM)
1598	(compare:CCFP (match_operand:SF 0 "s_register_operand"  "t")
1599		      (match_operand:SF 1 "vfp_compare_operand" "tG")))]
1600  "TARGET_32BIT && TARGET_HARD_FLOAT"
1601  "#"
1602  "TARGET_32BIT && TARGET_HARD_FLOAT"
1603  [(set (reg:CCFP VFPCC_REGNUM)
1604	(compare:CCFP (match_dup 0)
1605		      (match_dup 1)))
1606   (set (reg:CCFP CC_REGNUM)
1607	(reg:CCFP VFPCC_REGNUM))]
1608  ""
1609)
1610
1611(define_insn_and_split "*cmpsf_trap_split_vfp"
1612  [(set (reg:CCFPE CC_REGNUM)
1613	(compare:CCFPE (match_operand:SF 0 "s_register_operand"  "t")
1614		       (match_operand:SF 1 "vfp_compare_operand" "tG")))]
1615  "TARGET_32BIT && TARGET_HARD_FLOAT"
1616  "#"
1617  "TARGET_32BIT && TARGET_HARD_FLOAT"
1618  [(set (reg:CCFPE VFPCC_REGNUM)
1619	(compare:CCFPE (match_dup 0)
1620		       (match_dup 1)))
1621   (set (reg:CCFPE CC_REGNUM)
1622	(reg:CCFPE VFPCC_REGNUM))]
1623  ""
1624)
1625
1626(define_insn_and_split "*cmpdf_split_vfp"
1627  [(set (reg:CCFP CC_REGNUM)
1628	(compare:CCFP (match_operand:DF 0 "s_register_operand"  "w")
1629		      (match_operand:DF 1 "vfp_compare_operand" "wG")))]
1630  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1631  "#"
1632  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1633  [(set (reg:CCFP VFPCC_REGNUM)
1634	(compare:CCFP (match_dup 0)
1635		       (match_dup 1)))
1636   (set (reg:CCFP CC_REGNUM)
1637	(reg:CCFP VFPCC_REGNUM))]
1638  ""
1639)
1640
1641(define_insn_and_split "*cmpdf_trap_split_vfp"
1642  [(set (reg:CCFPE CC_REGNUM)
1643	(compare:CCFPE (match_operand:DF 0 "s_register_operand"  "w")
1644		       (match_operand:DF 1 "vfp_compare_operand" "wG")))]
1645  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1646  "#"
1647  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1648  [(set (reg:CCFPE VFPCC_REGNUM)
1649	(compare:CCFPE (match_dup 0)
1650		       (match_dup 1)))
1651   (set (reg:CCFPE CC_REGNUM)
1652	(reg:CCFPE VFPCC_REGNUM))]
1653  ""
1654)
1655
1656
1657;; Comparison patterns
1658
1659;; In the compare with FP zero case the ARM Architecture Reference Manual
1660;; specifies the immediate to be #0.0.  However, some buggy assemblers only
1661;; accept #0.  We don't want to autodetect broken assemblers, so output #0.
1662(define_insn "*cmpsf_vfp"
1663  [(set (reg:CCFP VFPCC_REGNUM)
1664	(compare:CCFP (match_operand:SF 0 "s_register_operand"  "t,t")
1665		      (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
1666  "TARGET_32BIT && TARGET_HARD_FLOAT"
1667  "@
1668   vcmp%?.f32\\t%0, %1
1669   vcmp%?.f32\\t%0, #0"
1670  [(set_attr "predicable" "yes")
1671   (set_attr "type" "fcmps")]
1672)
1673
1674(define_insn "*cmpsf_trap_vfp"
1675  [(set (reg:CCFPE VFPCC_REGNUM)
1676	(compare:CCFPE (match_operand:SF 0 "s_register_operand"  "t,t")
1677		       (match_operand:SF 1 "vfp_compare_operand" "t,G")))]
1678  "TARGET_32BIT && TARGET_HARD_FLOAT"
1679  "@
1680   vcmpe%?.f32\\t%0, %1
1681   vcmpe%?.f32\\t%0, #0"
1682  [(set_attr "predicable" "yes")
1683   (set_attr "type" "fcmps")]
1684)
1685
1686(define_insn "*cmpdf_vfp"
1687  [(set (reg:CCFP VFPCC_REGNUM)
1688	(compare:CCFP (match_operand:DF 0 "s_register_operand"  "w,w")
1689		      (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1690  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1691  "@
1692   vcmp%?.f64\\t%P0, %P1
1693   vcmp%?.f64\\t%P0, #0"
1694  [(set_attr "predicable" "yes")
1695   (set_attr "type" "fcmpd")]
1696)
1697
1698(define_insn "*cmpdf_trap_vfp"
1699  [(set (reg:CCFPE VFPCC_REGNUM)
1700	(compare:CCFPE (match_operand:DF 0 "s_register_operand"  "w,w")
1701		       (match_operand:DF 1 "vfp_compare_operand" "w,G")))]
1702  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE"
1703  "@
1704   vcmpe%?.f64\\t%P0, %P1
1705   vcmpe%?.f64\\t%P0, #0"
1706  [(set_attr "predicable" "yes")
1707   (set_attr "type" "fcmpd")]
1708)
1709
1710;; Fixed point to floating point conversions.
1711(define_insn "*combine_vcvt_f32_<FCVTI32typename>"
1712  [(set (match_operand:SF 0 "s_register_operand" "=t")
1713	(mult:SF (FCVT:SF (match_operand:SI 1 "s_register_operand" "0"))
1714		 (match_operand 2
1715			"const_double_vcvt_power_of_two_reciprocal" "Dt")))]
1716  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math"
1717  "vcvt%?.f32.<FCVTI32typename>\\t%0, %1, %v2"
1718  [(set_attr "predicable" "yes")
1719   (set_attr "type" "f_cvti2f")]
1720)
1721
1722;; Not the ideal way of implementing this. Ideally we would be able to split
1723;; this into a move to a DP register and then a vcvt.f64.i32
1724(define_insn "*combine_vcvt_f64_<FCVTI32typename>"
1725  [(set (match_operand:DF 0 "s_register_operand" "=x,x,w")
1726	(mult:DF (FCVT:DF (match_operand:SI 1 "s_register_operand" "r,t,r"))
1727		 (match_operand 2
1728		     "const_double_vcvt_power_of_two_reciprocal" "Dt,Dt,Dt")))]
1729  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math
1730  && !TARGET_VFP_SINGLE"
1731  "@
1732  vmov%?.f32\\t%0, %1\;vcvt%?.f64.<FCVTI32typename>\\t%P0, %P0, %v2
1733  vmov%?.f32\\t%0, %1\;vcvt%?.f64.<FCVTI32typename>\\t%P0, %P0, %v2
1734  vmov%?.f64\\t%P0, %1, %1\;vcvt%?.f64.<FCVTI32typename>\\t%P0, %P0, %v2"
1735  [(set_attr "predicable" "yes")
1736   (set_attr "ce_count" "2")
1737   (set_attr "type" "f_cvti2f")
1738   (set_attr "length" "8")]
1739)
1740
1741(define_insn "*combine_vcvtf2i"
1742  [(set (match_operand:SI 0 "s_register_operand" "=t")
1743	(fix:SI (fix:SF (mult:SF (match_operand:SF 1 "s_register_operand" "0")
1744				 (match_operand 2
1745				 "const_double_vcvt_power_of_two" "Dp")))))]
1746  "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math"
1747  "vcvt%?.s32.f32\\t%0, %1, %v2"
1748  [(set_attr "predicable" "yes")
1749   (set_attr "type" "f_cvtf2i")]
1750 )
1751
1752;; FP16 conversions.
1753(define_insn "neon_vcvth<sup>hf"
1754 [(set (match_operand:HF 0 "s_register_operand" "=w")
1755   (unspec:HF
1756    [(match_operand:SI 1 "s_register_operand" "w")]
1757    VCVTH_US))]
1758 "TARGET_VFP_FP16INST"
1759 "vcvt.f16.<sup>%#32\t%0, %1"
1760 [(set_attr "conds" "unconditional")
1761  (set_attr "type" "f_cvti2f")]
1762)
1763
1764(define_insn "neon_vcvth<sup>si"
1765 [(set (match_operand:SI 0 "s_register_operand" "=w")
1766   (unspec:SI
1767    [(match_operand:HF 1 "s_register_operand" "w")]
1768    VCVTH_US))]
1769 "TARGET_VFP_FP16INST"
1770 "vcvt.<sup>%#32.f16\t%0, %1"
1771 [(set_attr "conds" "unconditional")
1772  (set_attr "type" "f_cvtf2i")]
1773)
1774
1775;; The neon_vcvth<sup>_nhf patterns are used to generate the instruction for the
1776;; vcvth_n_f16_<sup>32 arm_fp16 intrinsics.  They are complicated by the
1777;; hardware requirement that the source and destination registers are the same
1778;; despite having different machine modes.  The approach is to use a temporary
1779;; register for the conversion and move that to the correct destination.
1780
1781;; Generate an unspec pattern for the intrinsic.
1782(define_insn "neon_vcvth<sup>_nhf_unspec"
1783 [(set
1784   (match_operand:SI 0 "s_register_operand" "=w")
1785   (unspec:SI
1786    [(match_operand:SI 1 "s_register_operand" "0")
1787     (match_operand:SI 2 "immediate_operand" "i")]
1788    VCVT_HF_US_N))
1789 (set
1790  (match_operand:HF 3 "s_register_operand" "=w")
1791  (float_truncate:HF (float:SF (match_dup 0))))]
1792 "TARGET_VFP_FP16INST"
1793{
1794  arm_const_bounds (operands[2], 1, 33);
1795  return "vcvt.f16.<sup>32\t%0, %0, %2\;vmov.f32\t%3, %0";
1796}
1797  [(set_attr "conds" "unconditional")
1798   (set_attr "type" "f_cvti2f")]
1799)
1800
1801;; Generate the instruction patterns needed for vcvth_n_f16_s32 neon intrinsics.
1802(define_expand "neon_vcvth<sup>_nhf"
1803 [(match_operand:HF 0 "s_register_operand")
1804  (unspec:HF [(match_operand:SI 1 "s_register_operand")
1805	      (match_operand:SI 2 "immediate_operand")]
1806   VCVT_HF_US_N)]
1807"TARGET_VFP_FP16INST"
1808{
1809  rtx op1 = gen_reg_rtx (SImode);
1810
1811  arm_const_bounds (operands[2], 1, 33);
1812
1813  emit_move_insn (op1, operands[1]);
1814  emit_insn (gen_neon_vcvth<sup>_nhf_unspec (op1, op1, operands[2],
1815					     operands[0]));
1816  DONE;
1817})
1818
1819;; The neon_vcvth<sup>_nsi patterns are used to generate the instruction for the
1820;; vcvth_n_<sup>32_f16 arm_fp16 intrinsics.  They have the same restrictions and
1821;; are implemented in the same way as the neon_vcvth<sup>_nhf patterns.
1822
1823;; Generate an unspec pattern, constraining the registers.
1824(define_insn "neon_vcvth<sup>_nsi_unspec"
1825 [(set (match_operand:SI 0 "s_register_operand" "=w")
1826   (unspec:SI
1827    [(fix:SI
1828      (fix:SF
1829       (float_extend:SF
1830	(match_operand:HF 1 "s_register_operand" "w"))))
1831     (match_operand:SI 2 "immediate_operand" "i")]
1832    VCVT_SI_US_N))]
1833 "TARGET_VFP_FP16INST"
1834{
1835  arm_const_bounds (operands[2], 1, 33);
1836  return "vmov.f32\t%0, %1\;vcvt.<sup>%#32.f16\t%0, %0, %2";
1837}
1838  [(set_attr "conds" "unconditional")
1839   (set_attr "type" "f_cvtf2i")]
1840)
1841
1842;; Generate the instruction patterns needed for vcvth_n_f16_s32 neon intrinsics.
1843(define_expand "neon_vcvth<sup>_nsi"
1844 [(match_operand:SI 0 "s_register_operand")
1845  (unspec:SI
1846   [(match_operand:HF 1 "s_register_operand")
1847    (match_operand:SI 2 "immediate_operand")]
1848   VCVT_SI_US_N)]
1849 "TARGET_VFP_FP16INST"
1850{
1851  rtx op1 = gen_reg_rtx (SImode);
1852
1853  arm_const_bounds (operands[2], 1, 33);
1854  emit_insn (gen_neon_vcvth<sup>_nsi_unspec (op1, operands[1], operands[2]));
1855  emit_move_insn (operands[0], op1);
1856  DONE;
1857})
1858
1859(define_insn "neon_vcvt<vcvth_op>h<sup>si"
1860 [(set
1861   (match_operand:SI 0 "s_register_operand" "=w")
1862   (unspec:SI
1863    [(match_operand:HF 1 "s_register_operand" "w")]
1864    VCVT_HF_US))]
1865 "TARGET_VFP_FP16INST"
1866 "vcvt<vcvth_op>.<sup>%#32.f16\t%0, %1"
1867  [(set_attr "conds" "unconditional")
1868   (set_attr "type" "f_cvtf2i")]
1869)
1870
1871;; Store multiple insn used in function prologue.
1872(define_insn "*push_multi_vfp"
1873  [(match_parallel 2 "multi_register_push"
1874    [(set (match_operand:BLK 0 "memory_operand" "=m")
1875	  (unspec:BLK [(match_operand:DF 1 "vfp_register_operand" "")]
1876		      UNSPEC_PUSH_MULT))])]
1877  "TARGET_32BIT && TARGET_HARD_FLOAT"
1878  "* return vfp_output_vstmd (operands);"
1879  [(set_attr "type" "f_stored")]
1880)
1881
1882;; VRINT round to integral instructions.
1883;; Invoked for the patterns: btruncsf2, btruncdf2, ceilsf2, ceildf2,
1884;; roundsf2, rounddf2, floorsf2, floordf2, nearbyintsf2, nearbyintdf2,
1885;; rintsf2, rintdf2.
1886(define_insn "<vrint_pattern><SDF:mode>2"
1887  [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
1888        (unspec:SDF [(match_operand:SDF 1
1889		         "register_operand" "<F_constraint>")]
1890         VRINT))]
1891  "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
1892  "vrint<vrint_variant>%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1"
1893  [(set_attr "predicable" "<vrint_predicable>")
1894   (set_attr "type" "f_rint<vfp_type>")
1895   (set_attr "conds" "<vrint_conds>")]
1896)
1897
1898;; Implements the lround, lfloor and lceil optabs.
1899(define_insn "l<vrint_pattern><su_optab><mode>si2"
1900  [(set (match_operand:SI 0 "register_operand" "=t")
1901        (FIXUORS:SI (unspec:SDF
1902                        [(match_operand:SDF 1
1903                           "register_operand" "<F_constraint>")] VCVT)))]
1904  "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
1905  "vcvt<vrint_variant>.<su>32.<V_if_elem>\\t%0, %<V_reg>1"
1906  [(set_attr "conds" "unconditional")
1907   (set_attr "type" "f_cvtf2i")]
1908)
1909
1910;; MIN_EXPR and MAX_EXPR eventually map to 'smin' and 'smax' in RTL.
1911;; The 'smax' and 'smin' RTL standard pattern names do not specify which
1912;; operand will be returned when both operands are zero (i.e. they may not
1913;; honour signed zeroes), or when either operand is NaN.  Therefore GCC
1914;; only introduces MIN_EXPR/MAX_EXPR in fast math mode or when not honouring
1915;; NaNs.
1916
1917(define_insn "smax<mode>3"
1918  [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
1919        (smax:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>")
1920		  (match_operand:SDF 2 "register_operand" "<F_constraint>")))]
1921  "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
1922  "vmaxnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1923  [(set_attr "type" "f_minmax<vfp_type>")
1924   (set_attr "conds" "unconditional")]
1925)
1926
1927(define_insn "smin<mode>3"
1928  [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
1929        (smin:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>")
1930		  (match_operand:SDF 2 "register_operand" "<F_constraint>")))]
1931  "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
1932  "vminnm.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1933  [(set_attr "type" "f_minmax<vfp_type>")
1934   (set_attr "conds" "unconditional")]
1935)
1936
1937;; Scalar forms for the IEEE-754 fmax()/fmin() functions
1938
1939(define_insn "neon_<fmaxmin_op>hf"
1940 [(set
1941   (match_operand:HF 0 "s_register_operand" "=w")
1942   (unspec:HF
1943    [(match_operand:HF 1 "s_register_operand" "w")
1944     (match_operand:HF 2 "s_register_operand" "w")]
1945    VMAXMINFNM))]
1946 "TARGET_VFP_FP16INST"
1947 "<fmaxmin_op>.f16\t%0, %1, %2"
1948 [(set_attr "conds" "unconditional")
1949  (set_attr "type" "f_minmaxs")]
1950)
1951
1952(define_insn "<fmaxmin><mode>3"
1953  [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>")
1954	(unspec:SDF [(match_operand:SDF 1 "s_register_operand" "<F_constraint>")
1955		     (match_operand:SDF 2 "s_register_operand" "<F_constraint>")]
1956		     VMAXMINFNM))]
1957  "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>"
1958  "<fmaxmin_op>.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1959  [(set_attr "type" "f_minmax<vfp_type>")
1960   (set_attr "conds" "unconditional")]
1961)
1962
1963;; Write Floating-point Status and Control Register.
1964(define_insn "set_fpscr"
1965  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_SET_FPSCR)]
1966  "TARGET_HARD_FLOAT"
1967  "mcr\\tp10, 7, %0, cr1, cr0, 0\\t @SET_FPSCR"
1968  [(set_attr "type" "mrs")])
1969
1970;; Read Floating-point Status and Control Register.
1971(define_insn "get_fpscr"
1972  [(set (match_operand:SI 0 "register_operand" "=r")
1973        (unspec_volatile:SI [(const_int 0)] VUNSPEC_GET_FPSCR))]
1974  "TARGET_HARD_FLOAT"
1975  "mrc\\tp10, 7, %0, cr1, cr0, 0\\t @GET_FPSCR"
1976  [(set_attr "type" "mrs")])
1977
1978
1979;; Unimplemented insns:
1980;; fldm*
1981;; fstm*
1982;; fmdhr et al (VFPv1)
1983;; Support for xD (single precision only) variants.
1984;; fmrrs, fmsrr
1985
1986;; Split an immediate DF move to two immediate SI moves.
1987(define_insn_and_split "no_literal_pool_df_immediate"
1988  [(set (match_operand:DF 0 "s_register_operand" "")
1989	(match_operand:DF 1 "const_double_operand" ""))]
1990  "TARGET_THUMB2 && arm_disable_literal_pool
1991  && !(TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE
1992       && vfp3_const_double_rtx (operands[1]))"
1993  "#"
1994  "&& !reload_completed"
1995  [(set (subreg:SI (match_dup 1) 0) (match_dup 2))
1996   (set (subreg:SI (match_dup 1) 4) (match_dup 3))
1997   (set (match_dup 0) (match_dup 1))]
1998  "
1999  long buf[2];
2000  real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode);
2001  operands[2] = GEN_INT ((int) buf[0]);
2002  operands[3] = GEN_INT ((int) buf[1]);
2003  operands[1] = gen_reg_rtx (DFmode);
2004  ")
2005
2006;; Split an immediate SF move to one immediate SI move.
2007(define_insn_and_split "no_literal_pool_sf_immediate"
2008  [(set (match_operand:SF 0 "s_register_operand" "")
2009	(match_operand:SF 1 "const_double_operand" ""))]
2010  "TARGET_THUMB2 && arm_disable_literal_pool
2011  && !(TARGET_HARD_FLOAT && vfp3_const_double_rtx (operands[1]))"
2012  "#"
2013  "&& !reload_completed"
2014  [(set (subreg:SI (match_dup 1) 0) (match_dup 2))
2015   (set (match_dup 0) (match_dup 1))]
2016  "
2017  long buf;
2018  real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
2019  operands[2] = GEN_INT ((int) buf);
2020  operands[1] = gen_reg_rtx (SFmode);
2021  ")
2022