Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / gcc / config / arm / neon.md
1 ;; ARM NEON coprocessor Machine Description
2 ;; Copyright (C) 2006-2013 Free Software Foundation, Inc.
3 ;; Written by CodeSourcery.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
11 ;;
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;; General Public License for more details.
16 ;;
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3.  If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21
22 ;; Attribute used to permit string comparisons against <VQH_mnem> in
23 ;; neon_type attribute definitions.
24 (define_attr "vqh_mnem" "vadd,vmin,vmax" (const_string "vadd"))
25
26 (define_insn "*neon_mov<mode>"
27   [(set (match_operand:VDX 0 "nonimmediate_operand"
28           "=w,Un,w, w,  ?r,?w,?r,?r, ?Us")
29         (match_operand:VDX 1 "general_operand"
30           " w,w, Dn,Uni, w, r, r, Usi,r"))]
31   "TARGET_NEON
32    && (register_operand (operands[0], <MODE>mode)
33        || register_operand (operands[1], <MODE>mode))"
34 {
35   if (which_alternative == 2)
36     {
37       int width, is_valid;
38       static char templ[40];
39
40       is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
41         &operands[1], &width);
42
43       gcc_assert (is_valid != 0);
44
45       if (width == 0)
46         return "vmov.f32\t%P0, %1  @ <mode>";
47       else
48         sprintf (templ, "vmov.i%d\t%%P0, %%x1  @ <mode>", width);
49
50       return templ;
51     }
52
53   switch (which_alternative)
54     {
55     case 0: return "vmov\t%P0, %P1  @ <mode>";
56     case 1: case 3: return output_move_neon (operands);
57     case 2: gcc_unreachable ();
58     case 4: return "vmov\t%Q0, %R0, %P1  @ <mode>";
59     case 5: return "vmov\t%P0, %Q1, %R1  @ <mode>";
60     default: return output_move_double (operands, true, NULL);
61     }
62 }
63  [(set_attr "neon_type" "neon_int_1,*,neon_vmov,*,neon_mrrc,neon_mcr_2_mcrr,*,*,*")
64   (set_attr "type" "*,f_stored,*,f_loadd,*,*,alu_reg,load2,store2")
65   (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
66   (set_attr "length" "4,4,4,4,4,4,8,8,8")
67   (set_attr "arm_pool_range"     "*,*,*,1020,*,*,*,1020,*")
68   (set_attr "thumb2_pool_range"     "*,*,*,1018,*,*,*,1018,*")
69   (set_attr "neg_pool_range" "*,*,*,1004,*,*,*,1004,*")])
70
71 (define_insn "*neon_mov<mode>"
72   [(set (match_operand:VQXMOV 0 "nonimmediate_operand"
73           "=w,Un,w, w,  ?r,?w,?r,?r,  ?Us")
74         (match_operand:VQXMOV 1 "general_operand"
75           " w,w, Dn,Uni, w, r, r, Usi, r"))]
76   "TARGET_NEON
77    && (register_operand (operands[0], <MODE>mode)
78        || register_operand (operands[1], <MODE>mode))"
79 {
80   if (which_alternative == 2)
81     {
82       int width, is_valid;
83       static char templ[40];
84
85       is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
86         &operands[1], &width);
87
88       gcc_assert (is_valid != 0);
89
90       if (width == 0)
91         return "vmov.f32\t%q0, %1  @ <mode>";
92       else
93         sprintf (templ, "vmov.i%d\t%%q0, %%1  @ <mode>", width);
94
95       return templ;
96     }
97
98   switch (which_alternative)
99     {
100     case 0: return "vmov\t%q0, %q1  @ <mode>";
101     case 1: case 3: return output_move_neon (operands);
102     case 2: gcc_unreachable ();
103     case 4: return "vmov\t%Q0, %R0, %e1  @ <mode>\;vmov\t%J0, %K0, %f1";
104     case 5: return "vmov\t%e0, %Q1, %R1  @ <mode>\;vmov\t%f0, %J1, %K1";
105     default: return output_move_quad (operands);
106     }
107 }
108   [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_vmov,neon_ldm_2,\
109                           neon_mrrc,neon_mcr_2_mcrr,*,*,*")
110    (set_attr "type" "*,*,*,*,*,*,alu_reg,load4,store4")
111    (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
112    (set_attr "length" "4,8,4,8,8,8,16,8,16")
113    (set_attr "arm_pool_range" "*,*,*,1020,*,*,*,1020,*")
114    (set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*")
115    (set_attr "neg_pool_range" "*,*,*,996,*,*,*,996,*")])
116
117 (define_expand "movti"
118   [(set (match_operand:TI 0 "nonimmediate_operand" "")
119         (match_operand:TI 1 "general_operand" ""))]
120   "TARGET_NEON"
121 {
122   if (can_create_pseudo_p ())
123     {
124       if (!REG_P (operands[0]))
125         operands[1] = force_reg (TImode, operands[1]);
126     }
127 })
128
129 (define_expand "mov<mode>"
130   [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "")
131         (match_operand:VSTRUCT 1 "general_operand" ""))]
132   "TARGET_NEON"
133 {
134   if (can_create_pseudo_p ())
135     {
136       if (!REG_P (operands[0]))
137         operands[1] = force_reg (<MODE>mode, operands[1]);
138     }
139 })
140
141 (define_insn "*neon_mov<mode>"
142   [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "=w,Ut,w")
143         (match_operand:VSTRUCT 1 "general_operand"      " w,w, Ut"))]
144   "TARGET_NEON
145    && (register_operand (operands[0], <MODE>mode)
146        || register_operand (operands[1], <MODE>mode))"
147 {
148   switch (which_alternative)
149     {
150     case 0: return "#";
151     case 1: case 2: return output_move_neon (operands);
152     default: gcc_unreachable ();
153     }
154 }
155   [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_ldm_2")
156    (set (attr "length") (symbol_ref "arm_attr_length_move_neon (insn)"))])
157
158 (define_split
159   [(set (match_operand:EI 0 "s_register_operand" "")
160         (match_operand:EI 1 "s_register_operand" ""))]
161   "TARGET_NEON && reload_completed"
162   [(set (match_dup 0) (match_dup 1))
163    (set (match_dup 2) (match_dup 3))]
164 {
165   int rdest = REGNO (operands[0]);
166   int rsrc = REGNO (operands[1]);
167   rtx dest[2], src[2];
168
169   dest[0] = gen_rtx_REG (TImode, rdest);
170   src[0] = gen_rtx_REG (TImode, rsrc);
171   dest[1] = gen_rtx_REG (DImode, rdest + 4);
172   src[1] = gen_rtx_REG (DImode, rsrc + 4);
173
174   neon_disambiguate_copy (operands, dest, src, 2);
175 })
176
177 (define_split
178   [(set (match_operand:OI 0 "s_register_operand" "")
179         (match_operand:OI 1 "s_register_operand" ""))]
180   "TARGET_NEON && reload_completed"
181   [(set (match_dup 0) (match_dup 1))
182    (set (match_dup 2) (match_dup 3))]
183 {
184   int rdest = REGNO (operands[0]);
185   int rsrc = REGNO (operands[1]);
186   rtx dest[2], src[2];
187
188   dest[0] = gen_rtx_REG (TImode, rdest);
189   src[0] = gen_rtx_REG (TImode, rsrc);
190   dest[1] = gen_rtx_REG (TImode, rdest + 4);
191   src[1] = gen_rtx_REG (TImode, rsrc + 4);
192
193   neon_disambiguate_copy (operands, dest, src, 2);
194 })
195
196 (define_split
197   [(set (match_operand:CI 0 "s_register_operand" "")
198         (match_operand:CI 1 "s_register_operand" ""))]
199   "TARGET_NEON && reload_completed"
200   [(set (match_dup 0) (match_dup 1))
201    (set (match_dup 2) (match_dup 3))
202    (set (match_dup 4) (match_dup 5))]
203 {
204   int rdest = REGNO (operands[0]);
205   int rsrc = REGNO (operands[1]);
206   rtx dest[3], src[3];
207
208   dest[0] = gen_rtx_REG (TImode, rdest);
209   src[0] = gen_rtx_REG (TImode, rsrc);
210   dest[1] = gen_rtx_REG (TImode, rdest + 4);
211   src[1] = gen_rtx_REG (TImode, rsrc + 4);
212   dest[2] = gen_rtx_REG (TImode, rdest + 8);
213   src[2] = gen_rtx_REG (TImode, rsrc + 8);
214
215   neon_disambiguate_copy (operands, dest, src, 3);
216 })
217
218 (define_split
219   [(set (match_operand:XI 0 "s_register_operand" "")
220         (match_operand:XI 1 "s_register_operand" ""))]
221   "TARGET_NEON && reload_completed"
222   [(set (match_dup 0) (match_dup 1))
223    (set (match_dup 2) (match_dup 3))
224    (set (match_dup 4) (match_dup 5))
225    (set (match_dup 6) (match_dup 7))]
226 {
227   int rdest = REGNO (operands[0]);
228   int rsrc = REGNO (operands[1]);
229   rtx dest[4], src[4];
230
231   dest[0] = gen_rtx_REG (TImode, rdest);
232   src[0] = gen_rtx_REG (TImode, rsrc);
233   dest[1] = gen_rtx_REG (TImode, rdest + 4);
234   src[1] = gen_rtx_REG (TImode, rsrc + 4);
235   dest[2] = gen_rtx_REG (TImode, rdest + 8);
236   src[2] = gen_rtx_REG (TImode, rsrc + 8);
237   dest[3] = gen_rtx_REG (TImode, rdest + 12);
238   src[3] = gen_rtx_REG (TImode, rsrc + 12);
239
240   neon_disambiguate_copy (operands, dest, src, 4);
241 })
242
243 (define_expand "movmisalign<mode>"
244   [(set (match_operand:VDQX 0 "neon_struct_or_register_operand")
245         (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_or_register_operand")]
246                      UNSPEC_MISALIGNED_ACCESS))]
247   "TARGET_NEON && !BYTES_BIG_ENDIAN"
248 {
249   /* This pattern is not permitted to fail during expansion: if both arguments
250      are non-registers (e.g. memory := constant, which can be created by the
251      auto-vectorizer), force operand 1 into a register.  */
252   if (!s_register_operand (operands[0], <MODE>mode)
253       && !s_register_operand (operands[1], <MODE>mode))
254     operands[1] = force_reg (<MODE>mode, operands[1]);
255 })
256
257 (define_insn "*movmisalign<mode>_neon_store"
258   [(set (match_operand:VDX 0 "neon_struct_operand"             "=Um")
259         (unspec:VDX [(match_operand:VDX 1 "s_register_operand" " w")]
260                     UNSPEC_MISALIGNED_ACCESS))]
261   "TARGET_NEON && !BYTES_BIG_ENDIAN"
262   "vst1.<V_sz_elem>\t{%P1}, %A0"
263   [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
264
265 (define_insn "*movmisalign<mode>_neon_load"
266   [(set (match_operand:VDX 0 "s_register_operand"               "=w")
267         (unspec:VDX [(match_operand:VDX 1 "neon_struct_operand" " Um")]
268                     UNSPEC_MISALIGNED_ACCESS))]
269   "TARGET_NEON && !BYTES_BIG_ENDIAN"
270   "vld1.<V_sz_elem>\t{%P0}, %A1"
271   [(set_attr "neon_type" "neon_vld1_1_2_regs")])
272
273 (define_insn "*movmisalign<mode>_neon_store"
274   [(set (match_operand:VQX 0 "neon_struct_operand"             "=Um")
275         (unspec:VQX [(match_operand:VQX 1 "s_register_operand" " w")]
276                     UNSPEC_MISALIGNED_ACCESS))]
277   "TARGET_NEON && !BYTES_BIG_ENDIAN"
278   "vst1.<V_sz_elem>\t{%q1}, %A0"
279   [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
280
281 (define_insn "*movmisalign<mode>_neon_load"
282   [(set (match_operand:VQX 0 "s_register_operand"                "=w")
283         (unspec:VQX [(match_operand:VQX 1 "neon_struct_operand" " Um")]
284                     UNSPEC_MISALIGNED_ACCESS))]
285   "TARGET_NEON && !BYTES_BIG_ENDIAN"
286   "vld1.<V_sz_elem>\t{%q0}, %A1"
287   [(set_attr "neon_type" "neon_vld1_1_2_regs")])
288
289 (define_insn "vec_set<mode>_internal"
290   [(set (match_operand:VD 0 "s_register_operand" "=w,w")
291         (vec_merge:VD
292           (vec_duplicate:VD
293             (match_operand:<V_elem> 1 "nonimmediate_operand" "Um,r"))
294           (match_operand:VD 3 "s_register_operand" "0,0")
295           (match_operand:SI 2 "immediate_operand" "i,i")))]
296   "TARGET_NEON"
297 {
298   int elt = ffs ((int) INTVAL (operands[2])) - 1;
299   if (BYTES_BIG_ENDIAN)
300     elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
301   operands[2] = GEN_INT (elt);
302
303   if (which_alternative == 0)
304     return "vld1.<V_sz_elem>\t{%P0[%c2]}, %A1";
305   else
306     return "vmov.<V_sz_elem>\t%P0[%c2], %1";
307 }
308   [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")])
309
310 (define_insn "vec_set<mode>_internal"
311   [(set (match_operand:VQ 0 "s_register_operand" "=w,w")
312         (vec_merge:VQ
313           (vec_duplicate:VQ
314             (match_operand:<V_elem> 1 "nonimmediate_operand" "Um,r"))
315           (match_operand:VQ 3 "s_register_operand" "0,0")
316           (match_operand:SI 2 "immediate_operand" "i,i")))]
317   "TARGET_NEON"
318 {
319   HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
320   int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
321   int elt = elem % half_elts;
322   int hi = (elem / half_elts) * 2;
323   int regno = REGNO (operands[0]);
324
325   if (BYTES_BIG_ENDIAN)
326     elt = half_elts - 1 - elt;
327
328   operands[0] = gen_rtx_REG (<V_HALF>mode, regno + hi);
329   operands[2] = GEN_INT (elt);
330
331   if (which_alternative == 0)
332     return "vld1.<V_sz_elem>\t{%P0[%c2]}, %A1";
333   else
334     return "vmov.<V_sz_elem>\t%P0[%c2], %1";
335 }
336   [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")]
337 )
338
339 (define_insn "vec_setv2di_internal"
340   [(set (match_operand:V2DI 0 "s_register_operand" "=w,w")
341         (vec_merge:V2DI
342           (vec_duplicate:V2DI
343             (match_operand:DI 1 "nonimmediate_operand" "Um,r"))
344           (match_operand:V2DI 3 "s_register_operand" "0,0")
345           (match_operand:SI 2 "immediate_operand" "i,i")))]
346   "TARGET_NEON"
347 {
348   HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
349   int regno = REGNO (operands[0]) + 2 * elem;
350
351   operands[0] = gen_rtx_REG (DImode, regno);
352
353   if (which_alternative == 0)
354     return "vld1.64\t%P0, %A1";
355   else
356     return "vmov\t%P0, %Q1, %R1";
357 }
358   [(set_attr "neon_type" "neon_vld1_1_2_regs,neon_mcr_2_mcrr")]
359 )
360
361 (define_expand "vec_set<mode>"
362   [(match_operand:VDQ 0 "s_register_operand" "")
363    (match_operand:<V_elem> 1 "s_register_operand" "")
364    (match_operand:SI 2 "immediate_operand" "")]
365   "TARGET_NEON"
366 {
367   HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
368   emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
369                                          GEN_INT (elem), operands[0]));
370   DONE;
371 })
372
373 (define_insn "vec_extract<mode>"
374   [(set (match_operand:<V_elem> 0 "nonimmediate_operand" "=Um,r")
375         (vec_select:<V_elem>
376           (match_operand:VD 1 "s_register_operand" "w,w")
377           (parallel [(match_operand:SI 2 "immediate_operand" "i,i")])))]
378   "TARGET_NEON"
379 {
380   if (BYTES_BIG_ENDIAN)
381     {
382       int elt = INTVAL (operands[2]);
383       elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
384       operands[2] = GEN_INT (elt);
385     }
386
387   if (which_alternative == 0)
388     return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
389   else
390     return "vmov.<V_uf_sclr>\t%0, %P1[%c2]";
391 }
392   [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_bp_simple")]
393 )
394
395 (define_insn "vec_extract<mode>"
396   [(set (match_operand:<V_elem> 0 "nonimmediate_operand" "=Um,r")
397         (vec_select:<V_elem>
398           (match_operand:VQ 1 "s_register_operand" "w,w")
399           (parallel [(match_operand:SI 2 "immediate_operand" "i,i")])))]
400   "TARGET_NEON"
401 {
402   int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
403   int elt = INTVAL (operands[2]) % half_elts;
404   int hi = (INTVAL (operands[2]) / half_elts) * 2;
405   int regno = REGNO (operands[1]);
406
407   if (BYTES_BIG_ENDIAN)
408     elt = half_elts - 1 - elt;
409
410   operands[1] = gen_rtx_REG (<V_HALF>mode, regno + hi);
411   operands[2] = GEN_INT (elt);
412
413   if (which_alternative == 0)
414     return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
415   else
416     return "vmov.<V_uf_sclr>\t%0, %P1[%c2]";
417 }
418   [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_bp_simple")]
419 )
420
421 (define_insn "vec_extractv2di"
422   [(set (match_operand:DI 0 "nonimmediate_operand" "=Um,r")
423         (vec_select:DI
424           (match_operand:V2DI 1 "s_register_operand" "w,w")
425           (parallel [(match_operand:SI 2 "immediate_operand" "i,i")])))]
426   "TARGET_NEON"
427 {
428   int regno = REGNO (operands[1]) + 2 * INTVAL (operands[2]);
429
430   operands[1] = gen_rtx_REG (DImode, regno);
431
432   if (which_alternative == 0)
433     return "vst1.64\t{%P1}, %A0  @ v2di";
434   else
435     return "vmov\t%Q0, %R0, %P1  @ v2di";
436 }
437   [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_int_1")]
438 )
439
440 (define_expand "vec_init<mode>"
441   [(match_operand:VDQ 0 "s_register_operand" "")
442    (match_operand 1 "" "")]
443   "TARGET_NEON"
444 {
445   neon_expand_vector_init (operands[0], operands[1]);
446   DONE;
447 })
448
449 ;; Doubleword and quadword arithmetic.
450
451 ;; NOTE: some other instructions also support 64-bit integer
452 ;; element size, which we could potentially use for "long long" operations.
453
454 (define_insn "*add<mode>3_neon"
455   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
456         (plus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
457                   (match_operand:VDQ 2 "s_register_operand" "w")))]
458   "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
459   "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
460   [(set (attr "neon_type")
461       (if_then_else (match_test "<Is_float_mode>")
462                     (if_then_else (match_test "<Is_d_reg>")
463                                   (const_string "neon_fp_vadd_ddd_vabs_dd")
464                                   (const_string "neon_fp_vadd_qqq_vabs_qq"))
465                     (const_string "neon_int_1")))]
466 )
467
468 (define_insn "adddi3_neon"
469   [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w,?&r,?&r,?&r")
470         (plus:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,w,r,0,r")
471                  (match_operand:DI 2 "arm_adddi_operand"     "w,r,0,w,r,Dd,Dd")))
472    (clobber (reg:CC CC_REGNUM))]
473   "TARGET_NEON"
474 {
475   switch (which_alternative)
476     {
477     case 0: /* fall through */
478     case 3: return "vadd.i64\t%P0, %P1, %P2";
479     case 1: return "#";
480     case 2: return "#";
481     case 4: return "#";
482     case 5: return "#";
483     case 6: return "#";
484     default: gcc_unreachable ();
485     }
486 }
487   [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1,*,*,*")
488    (set_attr "conds" "*,clob,clob,*,clob,clob,clob")
489    (set_attr "length" "*,8,8,*,8,8,8")
490    (set_attr "arch" "nota8,*,*,onlya8,*,*,*")]
491 )
492
493 (define_insn "*sub<mode>3_neon"
494   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
495         (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
496                    (match_operand:VDQ 2 "s_register_operand" "w")))]
497   "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
498   "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
499   [(set (attr "neon_type")
500       (if_then_else (match_test "<Is_float_mode>")
501                     (if_then_else (match_test "<Is_d_reg>")
502                                   (const_string "neon_fp_vadd_ddd_vabs_dd")
503                                   (const_string "neon_fp_vadd_qqq_vabs_qq"))
504                     (const_string "neon_int_2")))]
505 )
506
507 (define_insn "subdi3_neon"
508   [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r,?w")
509         (minus:DI (match_operand:DI 1 "s_register_operand" "w,0,r,0,w")
510                   (match_operand:DI 2 "s_register_operand" "w,r,0,0,w")))
511    (clobber (reg:CC CC_REGNUM))]
512   "TARGET_NEON"
513 {
514   switch (which_alternative)
515     {
516     case 0: /* fall through */
517     case 4: return "vsub.i64\t%P0, %P1, %P2";
518     case 1: /* fall through */ 
519     case 2: /* fall through */
520     case 3: return  "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2";
521     default: gcc_unreachable ();
522     }
523 }
524   [(set_attr "neon_type" "neon_int_2,*,*,*,neon_int_2")
525    (set_attr "conds" "*,clob,clob,clob,*")
526    (set_attr "length" "*,8,8,8,*")
527    (set_attr "arch" "nota8,*,*,*,onlya8")]
528 )
529
530 (define_insn "*mul<mode>3_neon"
531   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
532         (mult:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
533                   (match_operand:VDQ 2 "s_register_operand" "w")))]
534   "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
535   "vmul.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
536   [(set (attr "neon_type")
537       (if_then_else (match_test "<Is_float_mode>")
538                     (if_then_else (match_test "<Is_d_reg>")
539                                   (const_string "neon_fp_vadd_ddd_vabs_dd")
540                                   (const_string "neon_fp_vadd_qqq_vabs_qq"))
541                     (if_then_else (match_test "<Is_d_reg>")
542                                   (if_then_else
543                                     (match_test "<Scalar_mul_8_16>")
544                                     (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
545                                     (const_string "neon_mul_qqq_8_16_32_ddd_32"))
546                                   (if_then_else (match_test "<Scalar_mul_8_16>")
547                                     (const_string "neon_mul_qqq_8_16_32_ddd_32")
548                                     (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
549 )
550
551 (define_insn "mul<mode>3add<mode>_neon"
552   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
553         (plus:VDQ (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
554                             (match_operand:VDQ 3 "s_register_operand" "w"))
555                   (match_operand:VDQ 1 "s_register_operand" "0")))]
556   "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
557   "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
558   [(set (attr "neon_type")
559       (if_then_else (match_test "<Is_float_mode>")
560                     (if_then_else (match_test "<Is_d_reg>")
561                                   (const_string "neon_fp_vmla_ddd")
562                                   (const_string "neon_fp_vmla_qqq"))
563                     (if_then_else (match_test "<Is_d_reg>")
564                                   (if_then_else
565                                     (match_test "<Scalar_mul_8_16>")
566                                     (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
567                                     (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
568                                   (if_then_else (match_test "<Scalar_mul_8_16>")
569                                     (const_string "neon_mla_qqq_8_16")
570                                     (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
571 )
572
573 (define_insn "mul<mode>3neg<mode>add<mode>_neon"
574   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
575         (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "0")
576                    (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
577                              (match_operand:VDQ 3 "s_register_operand" "w"))))]
578   "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
579   "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
580   [(set (attr "neon_type")
581       (if_then_else (match_test "<Is_float_mode>")
582                     (if_then_else (match_test "<Is_d_reg>")
583                                   (const_string "neon_fp_vmla_ddd")
584                                   (const_string "neon_fp_vmla_qqq"))
585                     (if_then_else (match_test "<Is_d_reg>")
586                                   (if_then_else
587                                     (match_test "<Scalar_mul_8_16>")
588                                     (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
589                                     (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
590                                   (if_then_else (match_test "<Scalar_mul_8_16>")
591                                     (const_string "neon_mla_qqq_8_16")
592                                     (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
593 )
594
595 ;; Fused multiply-accumulate
596 ;; We define each insn twice here:
597 ;;    1: with flag_unsafe_math_optimizations for the widening multiply phase
598 ;;       to be able to use when converting to FMA.
599 ;;    2: without flag_unsafe_math_optimizations for the intrinsics to use.
600 (define_insn "fma<VCVTF:mode>4"
601   [(set (match_operand:VCVTF 0 "register_operand" "=w")
602         (fma:VCVTF (match_operand:VCVTF 1 "register_operand" "w")
603                  (match_operand:VCVTF 2 "register_operand" "w")
604                  (match_operand:VCVTF 3 "register_operand" "0")))]
605   "TARGET_NEON && TARGET_FMA && flag_unsafe_math_optimizations"
606   "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
607   [(set (attr "neon_type")
608         (if_then_else (match_test "<Is_d_reg>")
609                       (const_string "neon_fp_vmla_ddd")
610                       (const_string "neon_fp_vmla_qqq")))]
611 )
612
613 (define_insn "fma<VCVTF:mode>4_intrinsic"
614   [(set (match_operand:VCVTF 0 "register_operand" "=w")
615         (fma:VCVTF (match_operand:VCVTF 1 "register_operand" "w")
616                  (match_operand:VCVTF 2 "register_operand" "w")
617                  (match_operand:VCVTF 3 "register_operand" "0")))]
618   "TARGET_NEON && TARGET_FMA"
619   "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
620   [(set (attr "neon_type")
621         (if_then_else (match_test "<Is_d_reg>")
622                       (const_string "neon_fp_vmla_ddd")
623                       (const_string "neon_fp_vmla_qqq")))]
624 )
625
626 (define_insn "*fmsub<VCVTF:mode>4"
627   [(set (match_operand:VCVTF 0 "register_operand" "=w")
628         (fma:VCVTF (neg:VCVTF (match_operand:VCVTF 1 "register_operand" "w"))
629                    (match_operand:VCVTF 2 "register_operand" "w")
630                    (match_operand:VCVTF 3 "register_operand" "0")))]
631   "TARGET_NEON && TARGET_FMA && flag_unsafe_math_optimizations"
632   "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
633   [(set (attr "neon_type")
634         (if_then_else (match_test "<Is_d_reg>")
635                       (const_string "neon_fp_vmla_ddd")
636                       (const_string "neon_fp_vmla_qqq")))]
637 )
638
639 (define_insn "fmsub<VCVTF:mode>4_intrinsic"
640   [(set (match_operand:VCVTF 0 "register_operand" "=w")
641         (fma:VCVTF (neg:VCVTF (match_operand:VCVTF 1 "register_operand" "w"))
642                    (match_operand:VCVTF 2 "register_operand" "w")
643                    (match_operand:VCVTF 3 "register_operand" "0")))]
644   "TARGET_NEON && TARGET_FMA"
645   "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
646   [(set (attr "neon_type")
647         (if_then_else (match_test "<Is_d_reg>")
648                       (const_string "neon_fp_vmla_ddd")
649                       (const_string "neon_fp_vmla_qqq")))]
650 )
651
652 (define_insn "neon_vrint<NEON_VRINT:nvrint_variant><VCVTF:mode>"
653   [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
654         (unspec:VCVTF [(match_operand:VCVTF 1
655                          "s_register_operand" "w")]
656                 NEON_VRINT))]
657   "TARGET_NEON && TARGET_FPU_ARMV8"
658   "vrint<nvrint_variant>%?.f32\\t%<V_reg>0, %<V_reg>1"
659   [(set (attr "neon_type")
660         (if_then_else (match_test "<Is_d_reg>")
661                 (const_string "neon_fp_vadd_ddd_vabs_dd")
662                 (const_string "neon_fp_vadd_qqq_vabs_qq")))]
663 )
664
665 (define_insn "ior<mode>3"
666   [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
667         (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
668                  (match_operand:VDQ 2 "neon_logic_op2" "w,Dl")))]
669   "TARGET_NEON"
670 {
671   switch (which_alternative)
672     {
673     case 0: return "vorr\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
674     case 1: return neon_output_logic_immediate ("vorr", &operands[2],
675                      <MODE>mode, 0, VALID_NEON_QREG_MODE (<MODE>mode));
676     default: gcc_unreachable ();
677     }
678 }
679   [(set_attr "neon_type" "neon_int_1")]
680 )
681
682 (define_insn "iordi3_neon"
683   [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r,?w,?w")
684         (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r,w,0")
685                 (match_operand:DI 2 "neon_logic_op2" "w,Dl,r,r,w,Dl")))]
686   "TARGET_NEON"
687 {
688   switch (which_alternative)
689     {
690     case 0: /* fall through */
691     case 4: return "vorr\t%P0, %P1, %P2";
692     case 1: /* fall through */
693     case 5: return neon_output_logic_immediate ("vorr", &operands[2],
694                      DImode, 0, VALID_NEON_QREG_MODE (DImode));
695     case 2: return "#";
696     case 3: return "#";
697     default: gcc_unreachable ();
698     }
699 }
700   [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,neon_int_1,neon_int_1")
701    (set_attr "length" "*,*,8,8,*,*")
702    (set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8")]
703 )
704
705 ;; The concrete forms of the Neon immediate-logic instructions are vbic and
706 ;; vorr. We support the pseudo-instruction vand instead, because that
707 ;; corresponds to the canonical form the middle-end expects to use for
708 ;; immediate bitwise-ANDs.
709
710 (define_insn "and<mode>3"
711   [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
712         (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
713                  (match_operand:VDQ 2 "neon_inv_logic_op2" "w,DL")))]
714   "TARGET_NEON"
715 {
716   switch (which_alternative)
717     {
718     case 0: return "vand\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
719     case 1: return neon_output_logic_immediate ("vand", &operands[2],
720                      <MODE>mode, 1, VALID_NEON_QREG_MODE (<MODE>mode));
721     default: gcc_unreachable ();
722     }
723 }
724   [(set_attr "neon_type" "neon_int_1")]
725 )
726
727 (define_insn "anddi3_neon"
728   [(set (match_operand:DI 0 "s_register_operand" "=w,w,?&r,?&r,?w,?w")
729         (and:DI (match_operand:DI 1 "s_register_operand" "%w,0,0,r,w,0")
730                 (match_operand:DI 2 "neon_inv_logic_op2" "w,DL,r,r,w,DL")))]
731   "TARGET_NEON"
732 {
733   switch (which_alternative)
734     {
735     case 0: /* fall through */
736     case 4: return "vand\t%P0, %P1, %P2";
737     case 1: /* fall through */
738     case 5: return neon_output_logic_immediate ("vand", &operands[2],
739                      DImode, 1, VALID_NEON_QREG_MODE (DImode));
740     case 2: return "#";
741     case 3: return "#";
742     default: gcc_unreachable ();
743     }
744 }
745   [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,neon_int_1,neon_int_1")
746    (set_attr "length" "*,*,8,8,*,*")
747    (set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8")]
748 )
749
750 (define_insn "orn<mode>3_neon"
751   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
752         (ior:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))
753                  (match_operand:VDQ 1 "s_register_operand" "w")))]
754   "TARGET_NEON"
755   "vorn\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
756   [(set_attr "neon_type" "neon_int_1")]
757 )
758
759 ;; TODO: investigate whether we should disable 
760 ;; this and bicdi3_neon for the A8 in line with the other
761 ;; changes above. 
762 (define_insn_and_split "orndi3_neon"
763   [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?&r")
764         (ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,0,0,r"))
765                 (match_operand:DI 1 "s_register_operand" "w,r,r,0")))]
766   "TARGET_NEON"
767   "@
768    vorn\t%P0, %P1, %P2
769    #
770    #
771    #"
772   "reload_completed && 
773    (TARGET_NEON && !(IS_VFP_REGNUM (REGNO (operands[0]))))"
774   [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
775    (set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))]
776   "
777   {
778     if (TARGET_THUMB2)
779       {
780         operands[3] = gen_highpart (SImode, operands[0]);
781         operands[0] = gen_lowpart (SImode, operands[0]);
782         operands[4] = gen_highpart (SImode, operands[2]);
783         operands[2] = gen_lowpart (SImode, operands[2]);
784         operands[5] = gen_highpart (SImode, operands[1]);
785         operands[1] = gen_lowpart (SImode, operands[1]);
786       }
787     else
788       {
789         emit_insn (gen_one_cmpldi2 (operands[0], operands[2]));
790         emit_insn (gen_iordi3 (operands[0], operands[1], operands[0]));
791         DONE;
792       }
793   }"
794   [(set_attr "neon_type" "neon_int_1,*,*,*")
795    (set_attr "length" "*,16,8,8")
796    (set_attr "arch" "any,a,t2,t2")]
797 )
798
799 (define_insn "bic<mode>3_neon"
800   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
801         (and:VDQ (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))
802                  (match_operand:VDQ 1 "s_register_operand" "w")))]
803   "TARGET_NEON"
804   "vbic\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
805   [(set_attr "neon_type" "neon_int_1")]
806 )
807
808 ;; Compare to *anddi_notdi_di.
809 (define_insn "bicdi3_neon"
810   [(set (match_operand:DI 0 "s_register_operand" "=w,?=&r,?&r")
811         (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "w,r,0"))
812                 (match_operand:DI 1 "s_register_operand" "w,0,r")))]
813   "TARGET_NEON"
814   "@
815    vbic\t%P0, %P1, %P2
816    #
817    #"
818   [(set_attr "neon_type" "neon_int_1,*,*")
819    (set_attr "length" "*,8,8")]
820 )
821
822 (define_insn "xor<mode>3"
823   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
824         (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
825                  (match_operand:VDQ 2 "s_register_operand" "w")))]
826   "TARGET_NEON"
827   "veor\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
828   [(set_attr "neon_type" "neon_int_1")]
829 )
830
831 (define_insn "xordi3_neon"
832   [(set (match_operand:DI 0 "s_register_operand" "=w,?&r,?&r,?w")
833         (xor:DI (match_operand:DI 1 "s_register_operand" "%w,0,r,w")
834                 (match_operand:DI 2 "s_register_operand" "w,r,r,w")))]
835   "TARGET_NEON"
836   "@
837    veor\t%P0, %P1, %P2
838    #
839    #
840    veor\t%P0, %P1, %P2"
841   [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1")
842    (set_attr "length" "*,8,8,*")
843    (set_attr "arch" "nota8,*,*,onlya8")]
844 )
845
846 (define_insn "one_cmpl<mode>2"
847   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
848         (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))]
849   "TARGET_NEON"
850   "vmvn\t%<V_reg>0, %<V_reg>1"
851   [(set_attr "neon_type" "neon_int_1")]
852 )
853
854 (define_insn "abs<mode>2"
855   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
856         (abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
857   "TARGET_NEON"
858   "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
859   [(set (attr "neon_type")
860       (if_then_else (match_test "<Is_float_mode>")
861                     (if_then_else (match_test "<Is_d_reg>")
862                                   (const_string "neon_fp_vadd_ddd_vabs_dd")
863                                   (const_string "neon_fp_vadd_qqq_vabs_qq"))
864                     (const_string "neon_int_3")))]
865 )
866
867 (define_insn "neg<mode>2"
868   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
869         (neg:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
870   "TARGET_NEON"
871   "vneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
872   [(set (attr "neon_type")
873       (if_then_else (match_test "<Is_float_mode>")
874                     (if_then_else (match_test "<Is_d_reg>")
875                                   (const_string "neon_fp_vadd_ddd_vabs_dd")
876                                   (const_string "neon_fp_vadd_qqq_vabs_qq"))
877                     (const_string "neon_int_3")))]
878 )
879
880 (define_insn "negdi2_neon"
881   [(set (match_operand:DI 0 "s_register_operand"         "=&w, w,r,&r")
882         (neg:DI (match_operand:DI 1 "s_register_operand" "  w, w,0, r")))
883    (clobber (match_scratch:DI 2                          "= X,&w,X, X"))
884    (clobber (reg:CC CC_REGNUM))]
885   "TARGET_NEON"
886   "#"
887   [(set_attr "length" "8")]
888 )
889
890 ; Split negdi2_neon for vfp registers
891 (define_split
892   [(set (match_operand:DI 0 "s_register_operand" "")
893         (neg:DI (match_operand:DI 1 "s_register_operand" "")))
894    (clobber (match_scratch:DI 2 ""))
895    (clobber (reg:CC CC_REGNUM))]
896   "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
897   [(set (match_dup 2) (const_int 0))
898    (parallel [(set (match_dup 0) (minus:DI (match_dup 2) (match_dup 1)))
899               (clobber (reg:CC CC_REGNUM))])]
900   {
901     if (!REG_P (operands[2]))
902       operands[2] = operands[0];
903   }
904 )
905
906 ; Split negdi2_neon for core registers
907 (define_split
908   [(set (match_operand:DI 0 "s_register_operand" "")
909         (neg:DI (match_operand:DI 1 "s_register_operand" "")))
910    (clobber (match_scratch:DI 2 ""))
911    (clobber (reg:CC CC_REGNUM))]
912   "TARGET_32BIT && reload_completed
913    && arm_general_register_operand (operands[0], DImode)"
914   [(parallel [(set (match_dup 0) (neg:DI (match_dup 1)))
915               (clobber (reg:CC CC_REGNUM))])]
916   ""
917 )
918
919 (define_insn "*umin<mode>3_neon"
920   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
921         (umin:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
922                     (match_operand:VDQIW 2 "s_register_operand" "w")))]
923   "TARGET_NEON"
924   "vmin.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
925   [(set_attr "neon_type" "neon_int_5")]
926 )
927
928 (define_insn "*umax<mode>3_neon"
929   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
930         (umax:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
931                     (match_operand:VDQIW 2 "s_register_operand" "w")))]
932   "TARGET_NEON"
933   "vmax.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
934   [(set_attr "neon_type" "neon_int_5")]
935 )
936
937 (define_insn "*smin<mode>3_neon"
938   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
939         (smin:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
940                    (match_operand:VDQW 2 "s_register_operand" "w")))]
941   "TARGET_NEON"
942   "vmin.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
943   [(set (attr "neon_type")
944       (if_then_else (match_test "<Is_float_mode>")
945                     (const_string "neon_fp_vadd_ddd_vabs_dd")
946                     (const_string "neon_int_5")))]
947 )
948
949 (define_insn "*smax<mode>3_neon"
950   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
951         (smax:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
952                    (match_operand:VDQW 2 "s_register_operand" "w")))]
953   "TARGET_NEON"
954   "vmax.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
955   [(set (attr "neon_type")
956       (if_then_else (match_test "<Is_float_mode>")
957                     (const_string "neon_fp_vadd_ddd_vabs_dd")
958                     (const_string "neon_int_5")))]
959 )
960
961 ; TODO: V2DI shifts are current disabled because there are bugs in the
962 ; generic vectorizer code.  It ends up creating a V2DI constructor with
963 ; SImode elements.
964
965 (define_insn "vashl<mode>3"
966   [(set (match_operand:VDQIW 0 "s_register_operand" "=w,w")
967         (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w,w")
968                       (match_operand:VDQIW 2 "imm_lshift_or_reg_neon" "w,Dn")))]
969   "TARGET_NEON"
970   {
971     switch (which_alternative)
972       {
973         case 0: return "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
974         case 1: return neon_output_shift_immediate ("vshl", 'i', &operands[2],
975                                                     <MODE>mode,
976                                                     VALID_NEON_QREG_MODE (<MODE>mode),
977                                                     true);
978         default: gcc_unreachable ();
979       }
980   }
981   [(set (attr "neon_type")
982       (if_then_else (match_test "<Is_d_reg>")
983                     (const_string "neon_vshl_ddd")
984                     (const_string "neon_shift_3")))]
985 )
986
987 (define_insn "vashr<mode>3_imm"
988   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
989         (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
990                         (match_operand:VDQIW 2 "imm_for_neon_rshift_operand" "Dn")))]
991   "TARGET_NEON"
992   {
993     return neon_output_shift_immediate ("vshr", 's', &operands[2],
994                                         <MODE>mode, VALID_NEON_QREG_MODE (<MODE>mode),
995                                         false);
996   }
997   [(set (attr "neon_type")
998       (if_then_else (match_test "<Is_d_reg>")
999                     (const_string "neon_vshl_ddd")
1000                     (const_string "neon_shift_3")))]
1001 )
1002
1003 (define_insn "vlshr<mode>3_imm"
1004   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1005         (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
1006                         (match_operand:VDQIW 2 "imm_for_neon_rshift_operand" "Dn")))]
1007   "TARGET_NEON"
1008   {
1009     return neon_output_shift_immediate ("vshr", 'u', &operands[2],
1010                                         <MODE>mode, VALID_NEON_QREG_MODE (<MODE>mode),
1011                                         false);
1012   }              
1013   [(set (attr "neon_type")
1014         (if_then_else (match_test "<Is_d_reg>")
1015                       (const_string "neon_vshl_ddd")
1016                       (const_string "neon_shift_3")))]
1017 )
1018
1019 ; Used for implementing logical shift-right, which is a left-shift by a negative
1020 ; amount, with signed operands. This is essentially the same as ashl<mode>3
1021 ; above, but using an unspec in case GCC tries anything tricky with negative
1022 ; shift amounts.
1023
1024 (define_insn "ashl<mode>3_signed"
1025   [(set (match_operand:VDQI 0 "s_register_operand" "=w")
1026         (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
1027                       (match_operand:VDQI 2 "s_register_operand" "w")]
1028                      UNSPEC_ASHIFT_SIGNED))]
1029   "TARGET_NEON"
1030   "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1031   [(set (attr "neon_type")
1032       (if_then_else (match_test "<Is_d_reg>")
1033                     (const_string "neon_vshl_ddd")
1034                     (const_string "neon_shift_3")))]
1035 )
1036
1037 ; Used for implementing logical shift-right, which is a left-shift by a negative
1038 ; amount, with unsigned operands.
1039
1040 (define_insn "ashl<mode>3_unsigned"
1041   [(set (match_operand:VDQI 0 "s_register_operand" "=w")
1042         (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
1043                       (match_operand:VDQI 2 "s_register_operand" "w")]
1044                      UNSPEC_ASHIFT_UNSIGNED))]
1045   "TARGET_NEON"
1046   "vshl.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1047   [(set (attr "neon_type")
1048       (if_then_else (match_test "<Is_d_reg>")
1049                     (const_string "neon_vshl_ddd")
1050                     (const_string "neon_shift_3")))]
1051 )
1052
1053 (define_expand "vashr<mode>3"
1054   [(set (match_operand:VDQIW 0 "s_register_operand" "")
1055         (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
1056                         (match_operand:VDQIW 2 "imm_rshift_or_reg_neon" "")))]
1057   "TARGET_NEON"
1058 {
1059   if (s_register_operand (operands[2], <MODE>mode))
1060     {
1061       rtx neg = gen_reg_rtx (<MODE>mode);
1062       emit_insn (gen_neg<mode>2 (neg, operands[2]));
1063       emit_insn (gen_ashl<mode>3_signed (operands[0], operands[1], neg));
1064     }
1065   else
1066     emit_insn (gen_vashr<mode>3_imm (operands[0], operands[1], operands[2]));
1067   DONE;
1068 })
1069
1070 (define_expand "vlshr<mode>3"
1071   [(set (match_operand:VDQIW 0 "s_register_operand" "")
1072         (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
1073                         (match_operand:VDQIW 2 "imm_rshift_or_reg_neon" "")))]
1074   "TARGET_NEON"
1075 {
1076   if (s_register_operand (operands[2], <MODE>mode))
1077     {
1078       rtx neg = gen_reg_rtx (<MODE>mode);
1079       emit_insn (gen_neg<mode>2 (neg, operands[2]));
1080       emit_insn (gen_ashl<mode>3_unsigned (operands[0], operands[1], neg));
1081     }
1082   else
1083     emit_insn (gen_vlshr<mode>3_imm (operands[0], operands[1], operands[2]));
1084   DONE;
1085 })
1086
1087 ;; 64-bit shifts
1088
1089 ;; This pattern loads a 32-bit shift count into a 64-bit NEON register,
1090 ;; leaving the upper half uninitalized.  This is OK since the shift
1091 ;; instruction only looks at the low 8 bits anyway.  To avoid confusing
1092 ;; data flow analysis however, we pretend the full register is set
1093 ;; using an unspec.
1094 (define_insn "neon_load_count"
1095   [(set (match_operand:DI 0 "s_register_operand" "=w,w")
1096         (unspec:DI [(match_operand:SI 1 "nonimmediate_operand" "Um,r")]
1097                    UNSPEC_LOAD_COUNT))]
1098   "TARGET_NEON"
1099   "@
1100    vld1.32\t{%P0[0]}, %A1
1101    vmov.32\t%P0[0], %1"
1102   [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")]
1103 )
1104
1105 (define_insn "ashldi3_neon_noclobber"
1106   [(set (match_operand:DI 0 "s_register_operand"            "=w,w")
1107         (ashift:DI (match_operand:DI 1 "s_register_operand" " w,w")
1108                    (match_operand:DI 2 "reg_or_int_operand" " i,w")))]
1109   "TARGET_NEON && reload_completed
1110    && (!CONST_INT_P (operands[2])
1111        || (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 64))"
1112   "@
1113    vshl.u64\t%P0, %P1, %2
1114    vshl.u64\t%P0, %P1, %P2"
1115   [(set_attr "neon_type" "neon_vshl_ddd,neon_vshl_ddd")]
1116 )
1117
1118 (define_insn_and_split "ashldi3_neon"
1119   [(set (match_operand:DI 0 "s_register_operand"            "= w, w,?&r,?r, ?w,w")
1120         (ashift:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, r, 0w,w")
1121                    (match_operand:SI 2 "general_operand"    "rUm, i,  r, i,rUm,i")))
1122    (clobber (match_scratch:SI 3                             "= X, X,?&r, X,  X,X"))
1123    (clobber (match_scratch:SI 4                             "= X, X,?&r, X,  X,X"))
1124    (clobber (match_scratch:DI 5                             "=&w, X,  X, X, &w,X"))
1125    (clobber (reg:CC_C CC_REGNUM))]
1126   "TARGET_NEON"
1127   "#"
1128   "TARGET_NEON && reload_completed"
1129   [(const_int 0)]
1130   "
1131   {
1132     if (IS_VFP_REGNUM (REGNO (operands[0])))
1133       {
1134         if (CONST_INT_P (operands[2]))
1135           {
1136             if (INTVAL (operands[2]) < 1)
1137               {
1138                 emit_insn (gen_movdi (operands[0], operands[1]));
1139                 DONE;
1140               }
1141             else if (INTVAL (operands[2]) > 63)
1142               operands[2] = gen_rtx_CONST_INT (VOIDmode, 63);
1143           }
1144         else
1145           {
1146             emit_insn (gen_neon_load_count (operands[5], operands[2]));
1147             operands[2] = operands[5];
1148           }
1149
1150         /* Ditch the unnecessary clobbers.  */
1151         emit_insn (gen_ashldi3_neon_noclobber (operands[0], operands[1],
1152                                                operands[2]));
1153       }
1154     else
1155       {
1156         if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
1157           /* This clobbers CC.  */
1158           emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1]));
1159         else
1160           arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1],
1161                                          operands[2], operands[3], operands[4]);
1162       }
1163     DONE;
1164   }"
1165   [(set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8")
1166    (set_attr "opt" "*,*,speed,speed,*,*")]
1167 )
1168
1169 ; The shift amount needs to be negated for right-shifts
1170 (define_insn "signed_shift_di3_neon"
1171   [(set (match_operand:DI 0 "s_register_operand"             "=w")
1172         (unspec:DI [(match_operand:DI 1 "s_register_operand" " w")
1173                     (match_operand:DI 2 "s_register_operand" " w")]
1174                    UNSPEC_ASHIFT_SIGNED))]
1175   "TARGET_NEON && reload_completed"
1176   "vshl.s64\t%P0, %P1, %P2"
1177   [(set_attr "neon_type" "neon_vshl_ddd")]
1178 )
1179
1180 ; The shift amount needs to be negated for right-shifts
1181 (define_insn "unsigned_shift_di3_neon"
1182   [(set (match_operand:DI 0 "s_register_operand"             "=w")
1183         (unspec:DI [(match_operand:DI 1 "s_register_operand" " w")
1184                     (match_operand:DI 2 "s_register_operand" " w")]
1185                    UNSPEC_ASHIFT_UNSIGNED))]
1186   "TARGET_NEON && reload_completed"
1187   "vshl.u64\t%P0, %P1, %P2"
1188   [(set_attr "neon_type" "neon_vshl_ddd")]
1189 )
1190
1191 (define_insn "ashrdi3_neon_imm_noclobber"
1192   [(set (match_operand:DI 0 "s_register_operand"              "=w")
1193         (ashiftrt:DI (match_operand:DI 1 "s_register_operand" " w")
1194                      (match_operand:DI 2 "const_int_operand"  " i")))]
1195   "TARGET_NEON && reload_completed
1196    && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 64"
1197   "vshr.s64\t%P0, %P1, %2"
1198   [(set_attr "neon_type" "neon_vshl_ddd")]
1199 )
1200
1201 (define_insn "lshrdi3_neon_imm_noclobber"
1202   [(set (match_operand:DI 0 "s_register_operand"              "=w")
1203         (lshiftrt:DI (match_operand:DI 1 "s_register_operand" " w")
1204                      (match_operand:DI 2 "const_int_operand"  " i")))]
1205   "TARGET_NEON && reload_completed
1206    && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 64"
1207   "vshr.u64\t%P0, %P1, %2"
1208   [(set_attr "neon_type" "neon_vshl_ddd")]
1209 )
1210
1211 ;; ashrdi3_neon
1212 ;; lshrdi3_neon
1213 (define_insn_and_split "<shift>di3_neon"
1214   [(set (match_operand:DI 0 "s_register_operand"             "= w, w,?&r,?r,?w,?w")
1215         (rshifts:DI (match_operand:DI 1 "s_register_operand" " 0w, w, 0r, r,0w, w")
1216                     (match_operand:SI 2 "reg_or_int_operand" "  r, i,  r, i, r, i")))
1217    (clobber (match_scratch:SI 3                              "=2r, X, &r, X,2r, X"))
1218    (clobber (match_scratch:SI 4                              "= X, X, &r, X, X, X"))
1219    (clobber (match_scratch:DI 5                              "=&w, X,  X, X,&w, X"))
1220    (clobber (reg:CC CC_REGNUM))]
1221   "TARGET_NEON"
1222   "#"
1223   "TARGET_NEON && reload_completed"
1224   [(const_int 0)]
1225   "
1226   {
1227     if (IS_VFP_REGNUM (REGNO (operands[0])))
1228       {
1229         if (CONST_INT_P (operands[2]))
1230           {
1231             if (INTVAL (operands[2]) < 1)
1232               {
1233                 emit_insn (gen_movdi (operands[0], operands[1]));
1234                 DONE;
1235               }
1236             else if (INTVAL (operands[2]) > 64)
1237               operands[2] = gen_rtx_CONST_INT (VOIDmode, 64);
1238
1239             /* Ditch the unnecessary clobbers.  */
1240             emit_insn (gen_<shift>di3_neon_imm_noclobber (operands[0],
1241                                                           operands[1],
1242                                                           operands[2]));
1243           }
1244         else 
1245           {
1246             /* We must use a negative left-shift.  */
1247             emit_insn (gen_negsi2 (operands[3], operands[2]));
1248             emit_insn (gen_neon_load_count (operands[5], operands[3]));
1249             emit_insn (gen_<shifttype>_shift_di3_neon (operands[0], operands[1],
1250                                                        operands[5]));
1251           }
1252       }
1253     else
1254       {
1255         if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 1)
1256           /* This clobbers CC.  */
1257           emit_insn (gen_arm_<shift>di3_1bit (operands[0], operands[1]));
1258         else
1259           /* This clobbers CC (ASHIFTRT by register only).  */
1260           arm_emit_coreregs_64bit_shift (<CODE>, operands[0], operands[1],
1261                                          operands[2], operands[3], operands[4]);
1262       }
1263
1264     DONE;
1265   }"
1266   [(set_attr "arch" "nota8,nota8,*,*,onlya8,onlya8")
1267    (set_attr "opt" "*,*,speed,speed,*,*")]
1268 )
1269
1270 ;; Widening operations
1271
1272 (define_insn "widen_ssum<mode>3"
1273   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1274         (plus:<V_widen> (sign_extend:<V_widen>
1275                           (match_operand:VW 1 "s_register_operand" "%w"))
1276                         (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1277   "TARGET_NEON"
1278   "vaddw.<V_s_elem>\t%q0, %q2, %P1"
1279   [(set_attr "neon_type" "neon_int_3")]
1280 )
1281
1282 (define_insn "widen_usum<mode>3"
1283   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1284         (plus:<V_widen> (zero_extend:<V_widen>
1285                           (match_operand:VW 1 "s_register_operand" "%w"))
1286                         (match_operand:<V_widen> 2 "s_register_operand" "w")))]
1287   "TARGET_NEON"
1288   "vaddw.<V_u_elem>\t%q0, %q2, %P1"
1289   [(set_attr "neon_type" "neon_int_3")]
1290 )
1291
1292 ;; VEXT can be used to synthesize coarse whole-vector shifts with 8-bit
1293 ;; shift-count granularity. That's good enough for the middle-end's current
1294 ;; needs.
1295
1296 ;; Note that it's not safe to perform such an operation in big-endian mode,
1297 ;; due to element-ordering issues.
1298
1299 (define_expand "vec_shr_<mode>"
1300   [(match_operand:VDQ 0 "s_register_operand" "")
1301    (match_operand:VDQ 1 "s_register_operand" "")
1302    (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1303   "TARGET_NEON && !BYTES_BIG_ENDIAN"
1304 {
1305   rtx zero_reg;
1306   HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1307   const int width = GET_MODE_BITSIZE (<MODE>mode);
1308   const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1309   rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1310     (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1311
1312   if (num_bits == width)
1313     {
1314       emit_move_insn (operands[0], operands[1]);
1315       DONE;
1316     }
1317
1318   zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1319   operands[0] = gen_lowpart (bvecmode, operands[0]);
1320   operands[1] = gen_lowpart (bvecmode, operands[1]);
1321
1322   emit_insn (gen_ext (operands[0], operands[1], zero_reg,
1323                       GEN_INT (num_bits / BITS_PER_UNIT)));
1324   DONE;
1325 })
1326
1327 (define_expand "vec_shl_<mode>"
1328   [(match_operand:VDQ 0 "s_register_operand" "")
1329    (match_operand:VDQ 1 "s_register_operand" "")
1330    (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1331   "TARGET_NEON && !BYTES_BIG_ENDIAN"
1332 {
1333   rtx zero_reg;
1334   HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1335   const int width = GET_MODE_BITSIZE (<MODE>mode);
1336   const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1337   rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1338     (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1339
1340   if (num_bits == 0)
1341     {
1342       emit_move_insn (operands[0], CONST0_RTX (<MODE>mode));
1343       DONE;
1344     }
1345
1346   num_bits = width - num_bits;
1347
1348   zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1349   operands[0] = gen_lowpart (bvecmode, operands[0]);
1350   operands[1] = gen_lowpart (bvecmode, operands[1]);
1351
1352   emit_insn (gen_ext (operands[0], zero_reg, operands[1],
1353                       GEN_INT (num_bits / BITS_PER_UNIT)));
1354   DONE;
1355 })
1356
1357 ;; Helpers for quad-word reduction operations
1358
1359 ; Add (or smin, smax...) the low N/2 elements of the N-element vector
1360 ; operand[1] to the high N/2 elements of same. Put the result in operand[0], an
1361 ; N/2-element vector.
1362
1363 (define_insn "quad_halves_<code>v4si"
1364   [(set (match_operand:V2SI 0 "s_register_operand" "=w")
1365         (vqh_ops:V2SI
1366           (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
1367                            (parallel [(const_int 0) (const_int 1)]))
1368           (vec_select:V2SI (match_dup 1)
1369                            (parallel [(const_int 2) (const_int 3)]))))]
1370   "TARGET_NEON"
1371   "<VQH_mnem>.<VQH_sign>32\t%P0, %e1, %f1"
1372   [(set_attr "vqh_mnem" "<VQH_mnem>")
1373    (set (attr "neon_type")
1374       (if_then_else (eq_attr "vqh_mnem" "vadd")
1375                     (const_string "neon_int_1") (const_string "neon_int_5")))]
1376 )
1377
1378 (define_insn "quad_halves_<code>v4sf"
1379   [(set (match_operand:V2SF 0 "s_register_operand" "=w")
1380         (vqhs_ops:V2SF
1381           (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
1382                            (parallel [(const_int 0) (const_int 1)]))
1383           (vec_select:V2SF (match_dup 1)
1384                            (parallel [(const_int 2) (const_int 3)]))))]
1385   "TARGET_NEON && flag_unsafe_math_optimizations"
1386   "<VQH_mnem>.f32\t%P0, %e1, %f1"
1387   [(set_attr "vqh_mnem" "<VQH_mnem>")
1388    (set (attr "neon_type")
1389       (if_then_else (eq_attr "vqh_mnem" "vadd")
1390                     (const_string "neon_int_1") (const_string "neon_int_5")))]
1391 )
1392
1393 (define_insn "quad_halves_<code>v8hi"
1394   [(set (match_operand:V4HI 0 "s_register_operand" "+w")
1395         (vqh_ops:V4HI
1396           (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
1397                            (parallel [(const_int 0) (const_int 1)
1398                                       (const_int 2) (const_int 3)]))
1399           (vec_select:V4HI (match_dup 1)
1400                            (parallel [(const_int 4) (const_int 5)
1401                                       (const_int 6) (const_int 7)]))))]
1402   "TARGET_NEON"
1403   "<VQH_mnem>.<VQH_sign>16\t%P0, %e1, %f1"
1404   [(set_attr "vqh_mnem" "<VQH_mnem>")
1405    (set (attr "neon_type")
1406       (if_then_else (eq_attr "vqh_mnem" "vadd")
1407                     (const_string "neon_int_1") (const_string "neon_int_5")))]
1408 )
1409
1410 (define_insn "quad_halves_<code>v16qi"
1411   [(set (match_operand:V8QI 0 "s_register_operand" "+w")
1412         (vqh_ops:V8QI
1413           (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
1414                            (parallel [(const_int 0) (const_int 1)
1415                                       (const_int 2) (const_int 3)
1416                                       (const_int 4) (const_int 5)
1417                                       (const_int 6) (const_int 7)]))
1418           (vec_select:V8QI (match_dup 1)
1419                            (parallel [(const_int 8) (const_int 9)
1420                                       (const_int 10) (const_int 11)
1421                                       (const_int 12) (const_int 13)
1422                                       (const_int 14) (const_int 15)]))))]
1423   "TARGET_NEON"
1424   "<VQH_mnem>.<VQH_sign>8\t%P0, %e1, %f1"
1425   [(set_attr "vqh_mnem" "<VQH_mnem>")
1426    (set (attr "neon_type")
1427       (if_then_else (eq_attr "vqh_mnem" "vadd")
1428                     (const_string "neon_int_1") (const_string "neon_int_5")))]
1429 )
1430
1431 (define_expand "move_hi_quad_<mode>"
1432  [(match_operand:ANY128 0 "s_register_operand" "")
1433   (match_operand:<V_HALF> 1 "s_register_operand" "")]
1434  "TARGET_NEON"
1435 {
1436   emit_move_insn (simplify_gen_subreg (<V_HALF>mode, operands[0], <MODE>mode,
1437                                        GET_MODE_SIZE (<V_HALF>mode)),
1438                   operands[1]);
1439   DONE;
1440 })
1441
1442 (define_expand "move_lo_quad_<mode>"
1443  [(match_operand:ANY128 0 "s_register_operand" "")
1444   (match_operand:<V_HALF> 1 "s_register_operand" "")]
1445  "TARGET_NEON"
1446 {
1447   emit_move_insn (simplify_gen_subreg (<V_HALF>mode, operands[0],
1448                                        <MODE>mode, 0),
1449                   operands[1]);
1450   DONE;
1451 })
1452
1453 ;; Reduction operations
1454
1455 (define_expand "reduc_splus_<mode>"
1456   [(match_operand:VD 0 "s_register_operand" "")
1457    (match_operand:VD 1 "s_register_operand" "")]
1458   "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1459 {
1460   neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1461                         &gen_neon_vpadd_internal<mode>);
1462   DONE;
1463 })
1464
1465 (define_expand "reduc_splus_<mode>"
1466   [(match_operand:VQ 0 "s_register_operand" "")
1467    (match_operand:VQ 1 "s_register_operand" "")]
1468   "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)
1469    && !BYTES_BIG_ENDIAN"
1470 {
1471   rtx step1 = gen_reg_rtx (<V_HALF>mode);
1472   rtx res_d = gen_reg_rtx (<V_HALF>mode);
1473
1474   emit_insn (gen_quad_halves_plus<mode> (step1, operands[1]));
1475   emit_insn (gen_reduc_splus_<V_half> (res_d, step1));
1476   emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1477
1478   DONE;
1479 })
1480
1481 (define_insn "reduc_splus_v2di"
1482   [(set (match_operand:V2DI 0 "s_register_operand" "=w")
1483         (unspec:V2DI [(match_operand:V2DI 1 "s_register_operand" "w")]
1484                      UNSPEC_VPADD))]
1485   "TARGET_NEON && !BYTES_BIG_ENDIAN"
1486   "vadd.i64\t%e0, %e1, %f1"
1487   [(set_attr "neon_type" "neon_int_1")]
1488 )
1489
1490 ;; NEON does not distinguish between signed and unsigned addition except on
1491 ;; widening operations.
1492 (define_expand "reduc_uplus_<mode>"
1493   [(match_operand:VDQI 0 "s_register_operand" "")
1494    (match_operand:VDQI 1 "s_register_operand" "")]
1495   "TARGET_NEON && (<Is_d_reg> || !BYTES_BIG_ENDIAN)"
1496 {
1497   emit_insn (gen_reduc_splus_<mode> (operands[0], operands[1]));
1498   DONE;
1499 })
1500
1501 (define_expand "reduc_smin_<mode>"
1502   [(match_operand:VD 0 "s_register_operand" "")
1503    (match_operand:VD 1 "s_register_operand" "")]
1504   "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1505 {
1506   neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1507                         &gen_neon_vpsmin<mode>);
1508   DONE;
1509 })
1510
1511 (define_expand "reduc_smin_<mode>"
1512   [(match_operand:VQ 0 "s_register_operand" "")
1513    (match_operand:VQ 1 "s_register_operand" "")]
1514   "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)
1515    && !BYTES_BIG_ENDIAN"
1516 {
1517   rtx step1 = gen_reg_rtx (<V_HALF>mode);
1518   rtx res_d = gen_reg_rtx (<V_HALF>mode);
1519
1520   emit_insn (gen_quad_halves_smin<mode> (step1, operands[1]));
1521   emit_insn (gen_reduc_smin_<V_half> (res_d, step1));
1522   emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1523
1524   DONE;
1525 })
1526
1527 (define_expand "reduc_smax_<mode>"
1528   [(match_operand:VD 0 "s_register_operand" "")
1529    (match_operand:VD 1 "s_register_operand" "")]
1530   "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1531 {
1532   neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1533                         &gen_neon_vpsmax<mode>);
1534   DONE;
1535 })
1536
1537 (define_expand "reduc_smax_<mode>"
1538   [(match_operand:VQ 0 "s_register_operand" "")
1539    (match_operand:VQ 1 "s_register_operand" "")]
1540   "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)
1541    && !BYTES_BIG_ENDIAN"
1542 {
1543   rtx step1 = gen_reg_rtx (<V_HALF>mode);
1544   rtx res_d = gen_reg_rtx (<V_HALF>mode);
1545
1546   emit_insn (gen_quad_halves_smax<mode> (step1, operands[1]));
1547   emit_insn (gen_reduc_smax_<V_half> (res_d, step1));
1548   emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1549
1550   DONE;
1551 })
1552
1553 (define_expand "reduc_umin_<mode>"
1554   [(match_operand:VDI 0 "s_register_operand" "")
1555    (match_operand:VDI 1 "s_register_operand" "")]
1556   "TARGET_NEON"
1557 {
1558   neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1559                         &gen_neon_vpumin<mode>);
1560   DONE;
1561 })
1562
1563 (define_expand "reduc_umin_<mode>"
1564   [(match_operand:VQI 0 "s_register_operand" "")
1565    (match_operand:VQI 1 "s_register_operand" "")]
1566   "TARGET_NEON && !BYTES_BIG_ENDIAN"
1567 {
1568   rtx step1 = gen_reg_rtx (<V_HALF>mode);
1569   rtx res_d = gen_reg_rtx (<V_HALF>mode);
1570
1571   emit_insn (gen_quad_halves_umin<mode> (step1, operands[1]));
1572   emit_insn (gen_reduc_umin_<V_half> (res_d, step1));
1573   emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1574
1575   DONE;
1576 })
1577
1578 (define_expand "reduc_umax_<mode>"
1579   [(match_operand:VDI 0 "s_register_operand" "")
1580    (match_operand:VDI 1 "s_register_operand" "")]
1581   "TARGET_NEON"
1582 {
1583   neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1584                         &gen_neon_vpumax<mode>);
1585   DONE;
1586 })
1587
1588 (define_expand "reduc_umax_<mode>"
1589   [(match_operand:VQI 0 "s_register_operand" "")
1590    (match_operand:VQI 1 "s_register_operand" "")]
1591   "TARGET_NEON && !BYTES_BIG_ENDIAN"
1592 {
1593   rtx step1 = gen_reg_rtx (<V_HALF>mode);
1594   rtx res_d = gen_reg_rtx (<V_HALF>mode);
1595
1596   emit_insn (gen_quad_halves_umax<mode> (step1, operands[1]));
1597   emit_insn (gen_reduc_umax_<V_half> (res_d, step1));
1598   emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1599
1600   DONE;
1601 })
1602
1603 (define_insn "neon_vpadd_internal<mode>"
1604   [(set (match_operand:VD 0 "s_register_operand" "=w")
1605         (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1606                     (match_operand:VD 2 "s_register_operand" "w")]
1607                    UNSPEC_VPADD))]
1608   "TARGET_NEON"
1609   "vpadd.<V_if_elem>\t%P0, %P1, %P2"
1610   ;; Assume this schedules like vadd.
1611   [(set (attr "neon_type")
1612       (if_then_else (match_test "<Is_float_mode>")
1613                     (if_then_else (match_test "<Is_d_reg>")
1614                                   (const_string "neon_fp_vadd_ddd_vabs_dd")
1615                                   (const_string "neon_fp_vadd_qqq_vabs_qq"))
1616                     (const_string "neon_int_1")))]
1617 )
1618
1619 (define_insn "neon_vpsmin<mode>"
1620   [(set (match_operand:VD 0 "s_register_operand" "=w")
1621         (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1622                     (match_operand:VD 2 "s_register_operand" "w")]
1623                    UNSPEC_VPSMIN))]
1624   "TARGET_NEON"
1625   "vpmin.<V_s_elem>\t%P0, %P1, %P2"
1626   ;; Assume this schedules like vmin.
1627   [(set (attr "neon_type")
1628       (if_then_else (match_test "<Is_float_mode>")
1629                     (const_string "neon_fp_vadd_ddd_vabs_dd")
1630                     (const_string "neon_int_5")))]
1631 )
1632
1633 (define_insn "neon_vpsmax<mode>"
1634   [(set (match_operand:VD 0 "s_register_operand" "=w")
1635         (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1636                     (match_operand:VD 2 "s_register_operand" "w")]
1637                    UNSPEC_VPSMAX))]
1638   "TARGET_NEON"
1639   "vpmax.<V_s_elem>\t%P0, %P1, %P2"
1640   ;; Assume this schedules like vmax.
1641   [(set (attr "neon_type")
1642       (if_then_else (match_test "<Is_float_mode>")
1643                     (const_string "neon_fp_vadd_ddd_vabs_dd")
1644                     (const_string "neon_int_5")))]
1645 )
1646
1647 (define_insn "neon_vpumin<mode>"
1648   [(set (match_operand:VDI 0 "s_register_operand" "=w")
1649         (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1650                      (match_operand:VDI 2 "s_register_operand" "w")]
1651                    UNSPEC_VPUMIN))]
1652   "TARGET_NEON"
1653   "vpmin.<V_u_elem>\t%P0, %P1, %P2"
1654   ;; Assume this schedules like umin.
1655   [(set_attr "neon_type" "neon_int_5")]
1656 )
1657
1658 (define_insn "neon_vpumax<mode>"
1659   [(set (match_operand:VDI 0 "s_register_operand" "=w")
1660         (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1661                      (match_operand:VDI 2 "s_register_operand" "w")]
1662                    UNSPEC_VPUMAX))]
1663   "TARGET_NEON"
1664   "vpmax.<V_u_elem>\t%P0, %P1, %P2"
1665   ;; Assume this schedules like umax.
1666   [(set_attr "neon_type" "neon_int_5")]
1667 )
1668
1669 ;; Saturating arithmetic
1670
1671 ; NOTE: Neon supports many more saturating variants of instructions than the
1672 ; following, but these are all GCC currently understands.
1673 ; FIXME: Actually, GCC doesn't know how to create saturating add/sub by itself
1674 ; yet either, although these patterns may be used by intrinsics when they're
1675 ; added.
1676
1677 (define_insn "*ss_add<mode>_neon"
1678   [(set (match_operand:VD 0 "s_register_operand" "=w")
1679        (ss_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1680                    (match_operand:VD 2 "s_register_operand" "w")))]
1681   "TARGET_NEON"
1682   "vqadd.<V_s_elem>\t%P0, %P1, %P2"
1683   [(set_attr "neon_type" "neon_int_4")]
1684 )
1685
1686 (define_insn "*us_add<mode>_neon"
1687   [(set (match_operand:VD 0 "s_register_operand" "=w")
1688        (us_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1689                    (match_operand:VD 2 "s_register_operand" "w")))]
1690   "TARGET_NEON"
1691   "vqadd.<V_u_elem>\t%P0, %P1, %P2"
1692   [(set_attr "neon_type" "neon_int_4")]
1693 )
1694
1695 (define_insn "*ss_sub<mode>_neon"
1696   [(set (match_operand:VD 0 "s_register_operand" "=w")
1697        (ss_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1698                     (match_operand:VD 2 "s_register_operand" "w")))]
1699   "TARGET_NEON"
1700   "vqsub.<V_s_elem>\t%P0, %P1, %P2"
1701   [(set_attr "neon_type" "neon_int_5")]
1702 )
1703
1704 (define_insn "*us_sub<mode>_neon"
1705   [(set (match_operand:VD 0 "s_register_operand" "=w")
1706        (us_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1707                     (match_operand:VD 2 "s_register_operand" "w")))]
1708   "TARGET_NEON"
1709   "vqsub.<V_u_elem>\t%P0, %P1, %P2"
1710   [(set_attr "neon_type" "neon_int_5")]
1711 )
1712
1713 ;; Conditional instructions.  These are comparisons with conditional moves for
1714 ;; vectors.  They perform the assignment:
1715 ;;   
1716 ;;     Vop0 = (Vop4 <op3> Vop5) ? Vop1 : Vop2;
1717 ;;
1718 ;; where op3 is <, <=, ==, !=, >= or >.  Operations are performed
1719 ;; element-wise.
1720
1721 (define_expand "vcond<mode><mode>"
1722   [(set (match_operand:VDQW 0 "s_register_operand" "")
1723         (if_then_else:VDQW
1724           (match_operator 3 "comparison_operator"
1725             [(match_operand:VDQW 4 "s_register_operand" "")
1726              (match_operand:VDQW 5 "nonmemory_operand" "")])
1727           (match_operand:VDQW 1 "s_register_operand" "")
1728           (match_operand:VDQW 2 "s_register_operand" "")))]
1729   "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
1730 {
1731   HOST_WIDE_INT magic_word = (<MODE>mode == V2SFmode || <MODE>mode == V4SFmode)
1732                              ? 3 : 1;
1733   rtx magic_rtx = GEN_INT (magic_word);
1734   int inverse = 0;
1735   int swap_bsl_operands = 0;
1736   rtx mask = gen_reg_rtx (<V_cmp_result>mode);
1737   rtx tmp = gen_reg_rtx (<V_cmp_result>mode);
1738
1739   rtx (*base_comparison) (rtx, rtx, rtx, rtx);
1740   rtx (*complimentary_comparison) (rtx, rtx, rtx, rtx);
1741
1742   switch (GET_CODE (operands[3]))
1743     {
1744     case GE:
1745     case LE:
1746     case EQ:
1747       if (!REG_P (operands[5])
1748           && (operands[5] != CONST0_RTX (<MODE>mode)))
1749         operands[5] = force_reg (<MODE>mode, operands[5]);
1750       break;
1751     default:
1752       if (!REG_P (operands[5]))
1753         operands[5] = force_reg (<MODE>mode, operands[5]);
1754     }
1755
1756   switch (GET_CODE (operands[3]))
1757     {
1758     case LT:
1759     case UNLT:
1760       inverse = 1;
1761       /* Fall through.  */
1762     case GE:
1763     case UNGE:
1764     case ORDERED:
1765     case UNORDERED:
1766       base_comparison = gen_neon_vcge<mode>;
1767       complimentary_comparison = gen_neon_vcgt<mode>;
1768       break;
1769     case LE:
1770     case UNLE:
1771       inverse = 1;
1772       /* Fall through.  */
1773     case GT:
1774     case UNGT:
1775       base_comparison = gen_neon_vcgt<mode>;
1776       complimentary_comparison = gen_neon_vcge<mode>;
1777       break;
1778     case EQ:
1779     case NE:
1780     case UNEQ:
1781       base_comparison = gen_neon_vceq<mode>;
1782       complimentary_comparison = gen_neon_vceq<mode>;
1783       break;
1784     default:
1785       gcc_unreachable ();
1786     }
1787
1788   switch (GET_CODE (operands[3]))
1789     {
1790     case LT:
1791     case LE:
1792     case GT:
1793     case GE:
1794     case EQ:
1795       /* The easy case.  Here we emit one of vcge, vcgt or vceq.
1796          As a LT b <=> b GE a && a LE b <=> b GT a.  Our transformations are:
1797          a GE b -> a GE b
1798          a GT b -> a GT b
1799          a LE b -> b GE a
1800          a LT b -> b GT a
1801          a EQ b -> a EQ b  */
1802
1803       if (!inverse)
1804         emit_insn (base_comparison (mask, operands[4], operands[5], magic_rtx));
1805       else
1806         emit_insn (complimentary_comparison (mask, operands[5], operands[4], magic_rtx));
1807       break;
1808     case UNLT:
1809     case UNLE:
1810     case UNGT:
1811     case UNGE:
1812     case NE:
1813       /* Vector compare returns false for lanes which are unordered, so if we use
1814          the inverse of the comparison we actually want to emit, then
1815          swap the operands to BSL, we will end up with the correct result.
1816          Note that a NE NaN and NaN NE b are true for all a, b.
1817
1818          Our transformations are:
1819          a GE b -> !(b GT a)
1820          a GT b -> !(b GE a)
1821          a LE b -> !(a GT b)
1822          a LT b -> !(a GE b)
1823          a NE b -> !(a EQ b)  */
1824
1825       if (inverse)
1826         emit_insn (base_comparison (mask, operands[4], operands[5], magic_rtx));
1827       else
1828         emit_insn (complimentary_comparison (mask, operands[5], operands[4], magic_rtx));
1829
1830       swap_bsl_operands = 1;
1831       break;
1832     case UNEQ:
1833       /* We check (a > b ||  b > a).  combining these comparisons give us
1834          true iff !(a != b && a ORDERED b), swapping the operands to BSL
1835          will then give us (a == b ||  a UNORDERED b) as intended.  */
1836
1837       emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5], magic_rtx));
1838       emit_insn (gen_neon_vcgt<mode> (tmp, operands[5], operands[4], magic_rtx));
1839       emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
1840       swap_bsl_operands = 1;
1841       break;
1842     case UNORDERED:
1843        /* Operands are ORDERED iff (a > b || b >= a).
1844          Swapping the operands to BSL will give the UNORDERED case.  */
1845      swap_bsl_operands = 1;
1846      /* Fall through.  */
1847     case ORDERED:
1848       emit_insn (gen_neon_vcgt<mode> (tmp, operands[4], operands[5], magic_rtx));
1849       emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4], magic_rtx));
1850       emit_insn (gen_ior<v_cmp_result>3 (mask, mask, tmp));
1851       break;
1852     default:
1853       gcc_unreachable ();
1854     }
1855
1856   if (swap_bsl_operands)
1857     emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1858                                     operands[1]));
1859   else
1860     emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1861                                     operands[2]));
1862   DONE;
1863 })
1864
1865 (define_expand "vcondu<mode><mode>"
1866   [(set (match_operand:VDQIW 0 "s_register_operand" "")
1867         (if_then_else:VDQIW
1868           (match_operator 3 "arm_comparison_operator"
1869             [(match_operand:VDQIW 4 "s_register_operand" "")
1870              (match_operand:VDQIW 5 "s_register_operand" "")])
1871           (match_operand:VDQIW 1 "s_register_operand" "")
1872           (match_operand:VDQIW 2 "s_register_operand" "")))]
1873   "TARGET_NEON"
1874 {
1875   rtx mask;
1876   int inverse = 0, immediate_zero = 0;
1877   
1878   mask = gen_reg_rtx (<V_cmp_result>mode);
1879   
1880   if (operands[5] == CONST0_RTX (<MODE>mode))
1881     immediate_zero = 1;
1882   else if (!REG_P (operands[5]))
1883     operands[5] = force_reg (<MODE>mode, operands[5]);
1884   
1885   switch (GET_CODE (operands[3]))
1886     {
1887     case GEU:
1888       emit_insn (gen_neon_vcge<mode> (mask, operands[4], operands[5],
1889                                       const0_rtx));
1890       break;
1891     
1892     case GTU:
1893       emit_insn (gen_neon_vcgt<mode> (mask, operands[4], operands[5],
1894                                       const0_rtx));
1895       break;
1896     
1897     case EQ:
1898       emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1899                                       const0_rtx));
1900       break;
1901     
1902     case LEU:
1903       if (immediate_zero)
1904         emit_insn (gen_neon_vcle<mode> (mask, operands[4], operands[5],
1905                                         const0_rtx));
1906       else
1907         emit_insn (gen_neon_vcge<mode> (mask, operands[5], operands[4],
1908                                         const0_rtx));
1909       break;
1910     
1911     case LTU:
1912       if (immediate_zero)
1913         emit_insn (gen_neon_vclt<mode> (mask, operands[4], operands[5],
1914                                         const0_rtx));
1915       else
1916         emit_insn (gen_neon_vcgt<mode> (mask, operands[5], operands[4],
1917                                         const0_rtx));
1918       break;
1919     
1920     case NE:
1921       emit_insn (gen_neon_vceq<mode> (mask, operands[4], operands[5],
1922                                       const0_rtx));
1923       inverse = 1;
1924       break;
1925     
1926     default:
1927       gcc_unreachable ();
1928     }
1929   
1930   if (inverse)
1931     emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[2],
1932                                     operands[1]));
1933   else
1934     emit_insn (gen_neon_vbsl<mode> (operands[0], mask, operands[1],
1935                                     operands[2]));
1936
1937   DONE;
1938 })
1939
1940 ;; Patterns for builtins.
1941
1942 ; good for plain vadd, vaddq.
1943
1944 (define_expand "neon_vadd<mode>"
1945   [(match_operand:VDQX 0 "s_register_operand" "=w")
1946    (match_operand:VDQX 1 "s_register_operand" "w")
1947    (match_operand:VDQX 2 "s_register_operand" "w")
1948    (match_operand:SI 3 "immediate_operand" "i")]
1949   "TARGET_NEON"
1950 {
1951   if (!<Is_float_mode> || flag_unsafe_math_optimizations)
1952     emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[2]));
1953   else
1954     emit_insn (gen_neon_vadd<mode>_unspec (operands[0], operands[1],
1955                                            operands[2]));
1956   DONE;
1957 })
1958
1959 ; Note that NEON operations don't support the full IEEE 754 standard: in
1960 ; particular, denormal values are flushed to zero.  This means that GCC cannot
1961 ; use those instructions for autovectorization, etc. unless
1962 ; -funsafe-math-optimizations is in effect (in which case flush-to-zero
1963 ; behaviour is permissible).  Intrinsic operations (provided by the arm_neon.h
1964 ; header) must work in either case: if -funsafe-math-optimizations is given,
1965 ; intrinsics expand to "canonical" RTL where possible, otherwise intrinsics
1966 ; expand to unspecs (which may potentially limit the extent to which they might
1967 ; be optimized by generic code).
1968
1969 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
1970
1971 (define_insn "neon_vadd<mode>_unspec"
1972   [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1973         (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1974                       (match_operand:VDQX 2 "s_register_operand" "w")]
1975                      UNSPEC_VADD))]
1976   "TARGET_NEON"
1977   "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
1978   [(set (attr "neon_type")
1979       (if_then_else (match_test "<Is_float_mode>")
1980                     (if_then_else (match_test "<Is_d_reg>")
1981                                   (const_string "neon_fp_vadd_ddd_vabs_dd")
1982                                   (const_string "neon_fp_vadd_qqq_vabs_qq"))
1983                     (const_string "neon_int_1")))]
1984 )
1985
1986 ; operand 3 represents in bits:
1987 ;  bit 0: signed (vs unsigned).
1988 ;  bit 1: rounding (vs none).
1989
1990 (define_insn "neon_vaddl<mode>"
1991   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1992         (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1993                            (match_operand:VDI 2 "s_register_operand" "w")
1994                            (match_operand:SI 3 "immediate_operand" "i")]
1995                           UNSPEC_VADDL))]
1996   "TARGET_NEON"
1997   "vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
1998   [(set_attr "neon_type" "neon_int_3")]
1999 )
2000
2001 (define_insn "neon_vaddw<mode>"
2002   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2003         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
2004                            (match_operand:VDI 2 "s_register_operand" "w")
2005                            (match_operand:SI 3 "immediate_operand" "i")]
2006                           UNSPEC_VADDW))]
2007   "TARGET_NEON"
2008   "vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
2009   [(set_attr "neon_type" "neon_int_2")]
2010 )
2011
2012 ; vhadd and vrhadd.
2013
2014 (define_insn "neon_vhadd<mode>"
2015   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2016         (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2017                        (match_operand:VDQIW 2 "s_register_operand" "w")
2018                        (match_operand:SI 3 "immediate_operand" "i")]
2019                       UNSPEC_VHADD))]
2020   "TARGET_NEON"
2021   "v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2022   [(set_attr "neon_type" "neon_int_4")]
2023 )
2024
2025 (define_insn "neon_vqadd<mode>"
2026   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2027         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2028                        (match_operand:VDQIX 2 "s_register_operand" "w")
2029                        (match_operand:SI 3 "immediate_operand" "i")]
2030                      UNSPEC_VQADD))]
2031   "TARGET_NEON"
2032   "vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2033   [(set_attr "neon_type" "neon_int_4")]
2034 )
2035
2036 (define_insn "neon_vaddhn<mode>"
2037   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2038         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2039                             (match_operand:VN 2 "s_register_operand" "w")
2040                             (match_operand:SI 3 "immediate_operand" "i")]
2041                            UNSPEC_VADDHN))]
2042   "TARGET_NEON"
2043   "v%O3addhn.<V_if_elem>\t%P0, %q1, %q2"
2044   [(set_attr "neon_type" "neon_int_4")]
2045 )
2046
2047 ;; We cannot replace this unspec with mul<mode>3 because of the odd 
2048 ;; polynomial multiplication case that can specified by operand 3.
2049 (define_insn "neon_vmul<mode>"
2050   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2051         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2052                       (match_operand:VDQW 2 "s_register_operand" "w")
2053                       (match_operand:SI 3 "immediate_operand" "i")]
2054                      UNSPEC_VMUL))]
2055   "TARGET_NEON"
2056   "vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2057   [(set (attr "neon_type")
2058       (if_then_else (match_test "<Is_float_mode>")
2059                     (if_then_else (match_test "<Is_d_reg>")
2060                                   (const_string "neon_fp_vadd_ddd_vabs_dd")
2061                                   (const_string "neon_fp_vadd_qqq_vabs_qq"))
2062                     (if_then_else (match_test "<Is_d_reg>")
2063                                   (if_then_else
2064                                     (match_test "<Scalar_mul_8_16>")
2065                                     (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2066                                     (const_string "neon_mul_qqq_8_16_32_ddd_32"))
2067                                   (if_then_else (match_test "<Scalar_mul_8_16>")
2068                                     (const_string "neon_mul_qqq_8_16_32_ddd_32")
2069                                     (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
2070 )
2071
2072 (define_expand "neon_vmla<mode>"
2073   [(match_operand:VDQW 0 "s_register_operand" "=w")
2074    (match_operand:VDQW 1 "s_register_operand" "0")
2075    (match_operand:VDQW 2 "s_register_operand" "w")
2076    (match_operand:VDQW 3 "s_register_operand" "w")
2077    (match_operand:SI 4 "immediate_operand" "i")]
2078   "TARGET_NEON"
2079 {
2080   if (!<Is_float_mode> || flag_unsafe_math_optimizations)
2081     emit_insn (gen_mul<mode>3add<mode>_neon (operands[0], operands[1],
2082                                              operands[2], operands[3]));
2083   else
2084     emit_insn (gen_neon_vmla<mode>_unspec (operands[0], operands[1],
2085                                            operands[2], operands[3]));
2086   DONE;
2087 })
2088
2089 (define_expand "neon_vfma<VCVTF:mode>"
2090   [(match_operand:VCVTF 0 "s_register_operand")
2091    (match_operand:VCVTF 1 "s_register_operand")
2092    (match_operand:VCVTF 2 "s_register_operand")
2093    (match_operand:VCVTF 3 "s_register_operand")
2094    (match_operand:SI 4 "immediate_operand")]
2095   "TARGET_NEON && TARGET_FMA"
2096 {
2097   emit_insn (gen_fma<mode>4_intrinsic (operands[0], operands[2], operands[3],
2098                                        operands[1]));
2099   DONE;
2100 })
2101
2102 (define_expand "neon_vfms<VCVTF:mode>"
2103   [(match_operand:VCVTF 0 "s_register_operand")
2104    (match_operand:VCVTF 1 "s_register_operand")
2105    (match_operand:VCVTF 2 "s_register_operand")
2106    (match_operand:VCVTF 3 "s_register_operand")
2107    (match_operand:SI 4 "immediate_operand")]
2108   "TARGET_NEON && TARGET_FMA"
2109 {
2110   emit_insn (gen_fmsub<mode>4_intrinsic (operands[0], operands[2], operands[3],
2111                                          operands[1]));
2112   DONE;
2113 })
2114
2115 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2116
2117 (define_insn "neon_vmla<mode>_unspec"
2118   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
2119         (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
2120                      (match_operand:VDQ 2 "s_register_operand" "w")
2121                      (match_operand:VDQ 3 "s_register_operand" "w")]
2122                     UNSPEC_VMLA))]
2123   "TARGET_NEON"
2124   "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2125   [(set (attr "neon_type")
2126       (if_then_else (match_test "<Is_float_mode>")
2127                     (if_then_else (match_test "<Is_d_reg>")
2128                                   (const_string "neon_fp_vmla_ddd")
2129                                   (const_string "neon_fp_vmla_qqq"))
2130                     (if_then_else (match_test "<Is_d_reg>")
2131                                   (if_then_else
2132                                     (match_test "<Scalar_mul_8_16>")
2133                                     (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2134                                     (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
2135                                   (if_then_else (match_test "<Scalar_mul_8_16>")
2136                                     (const_string "neon_mla_qqq_8_16")
2137                                     (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
2138 )
2139
2140 (define_insn "neon_vmlal<mode>"
2141   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2142         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2143                            (match_operand:VW 2 "s_register_operand" "w")
2144                            (match_operand:VW 3 "s_register_operand" "w")
2145                            (match_operand:SI 4 "immediate_operand" "i")]
2146                           UNSPEC_VMLAL))]
2147   "TARGET_NEON"
2148   "vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2149   [(set (attr "neon_type")
2150      (if_then_else (match_test "<Scalar_mul_8_16>")
2151                    (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2152                    (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2153 )
2154
2155 (define_expand "neon_vmls<mode>"
2156   [(match_operand:VDQW 0 "s_register_operand" "=w")
2157    (match_operand:VDQW 1 "s_register_operand" "0")
2158    (match_operand:VDQW 2 "s_register_operand" "w")
2159    (match_operand:VDQW 3 "s_register_operand" "w")
2160    (match_operand:SI 4 "immediate_operand" "i")]
2161   "TARGET_NEON"
2162 {
2163   if (!<Is_float_mode> || flag_unsafe_math_optimizations)
2164     emit_insn (gen_mul<mode>3neg<mode>add<mode>_neon (operands[0],
2165                  operands[1], operands[2], operands[3]));
2166   else
2167     emit_insn (gen_neon_vmls<mode>_unspec (operands[0], operands[1],
2168                                            operands[2], operands[3]));
2169   DONE;
2170 })
2171
2172 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2173
2174 (define_insn "neon_vmls<mode>_unspec"
2175   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
2176         (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "0")
2177                      (match_operand:VDQ 2 "s_register_operand" "w")
2178                      (match_operand:VDQ 3 "s_register_operand" "w")]
2179                     UNSPEC_VMLS))]
2180   "TARGET_NEON"
2181   "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2182   [(set (attr "neon_type")
2183       (if_then_else (match_test "<Is_float_mode>")
2184                     (if_then_else (match_test "<Is_d_reg>")
2185                                   (const_string "neon_fp_vmla_ddd")
2186                                   (const_string "neon_fp_vmla_qqq"))
2187                     (if_then_else (match_test "<Is_d_reg>")
2188                                   (if_then_else
2189                                     (match_test "<Scalar_mul_8_16>")
2190                                     (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2191                                     (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
2192                                   (if_then_else
2193                                     (match_test "<Scalar_mul_8_16>")
2194                                     (const_string "neon_mla_qqq_8_16")
2195                                     (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
2196 )
2197
2198 (define_insn "neon_vmlsl<mode>"
2199   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2200         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2201                            (match_operand:VW 2 "s_register_operand" "w")
2202                            (match_operand:VW 3 "s_register_operand" "w")
2203                            (match_operand:SI 4 "immediate_operand" "i")]
2204                           UNSPEC_VMLSL))]
2205   "TARGET_NEON"
2206   "vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2207   [(set (attr "neon_type")
2208      (if_then_else (match_test "<Scalar_mul_8_16>")
2209                    (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2210                    (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2211 )
2212
2213 (define_insn "neon_vqdmulh<mode>"
2214   [(set (match_operand:VMDQI 0 "s_register_operand" "=w")
2215         (unspec:VMDQI [(match_operand:VMDQI 1 "s_register_operand" "w")
2216                        (match_operand:VMDQI 2 "s_register_operand" "w")
2217                        (match_operand:SI 3 "immediate_operand" "i")]
2218                       UNSPEC_VQDMULH))]
2219   "TARGET_NEON"
2220   "vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2221   [(set (attr "neon_type")
2222      (if_then_else (match_test "<Is_d_reg>")
2223         (if_then_else (match_test "<Scalar_mul_8_16>")
2224                       (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2225                       (const_string "neon_mul_qqq_8_16_32_ddd_32"))
2226         (if_then_else (match_test "<Scalar_mul_8_16>")
2227                       (const_string "neon_mul_qqq_8_16_32_ddd_32")
2228                       (const_string "neon_mul_qqq_8_16_32_ddd_32"))))]
2229 )
2230
2231 (define_insn "neon_vqdmlal<mode>"
2232   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2233         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2234                            (match_operand:VMDI 2 "s_register_operand" "w")
2235                            (match_operand:VMDI 3 "s_register_operand" "w")
2236                            (match_operand:SI 4 "immediate_operand" "i")]
2237                           UNSPEC_VQDMLAL))]
2238   "TARGET_NEON"
2239   "vqdmlal.<V_s_elem>\t%q0, %P2, %P3"
2240   [(set (attr "neon_type")
2241      (if_then_else (match_test "<Scalar_mul_8_16>")
2242                    (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2243                    (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2244 )
2245
2246 (define_insn "neon_vqdmlsl<mode>"
2247   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2248         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2249                            (match_operand:VMDI 2 "s_register_operand" "w")
2250                            (match_operand:VMDI 3 "s_register_operand" "w")
2251                            (match_operand:SI 4 "immediate_operand" "i")]
2252                           UNSPEC_VQDMLSL))]
2253   "TARGET_NEON"
2254   "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3"
2255   [(set (attr "neon_type")
2256      (if_then_else (match_test "<Scalar_mul_8_16>")
2257                    (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
2258                    (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
2259 )
2260
2261 (define_insn "neon_vmull<mode>"
2262   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2263         (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2264                            (match_operand:VW 2 "s_register_operand" "w")
2265                            (match_operand:SI 3 "immediate_operand" "i")]
2266                           UNSPEC_VMULL))]
2267   "TARGET_NEON"
2268   "vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2269   [(set (attr "neon_type")
2270      (if_then_else (match_test "<Scalar_mul_8_16>")
2271                    (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2272                    (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
2273 )
2274
2275 (define_insn "neon_vqdmull<mode>"
2276   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2277         (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
2278                            (match_operand:VMDI 2 "s_register_operand" "w")
2279                            (match_operand:SI 3 "immediate_operand" "i")]
2280                           UNSPEC_VQDMULL))]
2281   "TARGET_NEON"
2282   "vqdmull.<V_s_elem>\t%q0, %P1, %P2"
2283   [(set (attr "neon_type")
2284      (if_then_else (match_test "<Scalar_mul_8_16>")
2285                    (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
2286                    (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
2287 )
2288
2289 (define_expand "neon_vsub<mode>"
2290   [(match_operand:VDQX 0 "s_register_operand" "=w")
2291    (match_operand:VDQX 1 "s_register_operand" "w")
2292    (match_operand:VDQX 2 "s_register_operand" "w")
2293    (match_operand:SI 3 "immediate_operand" "i")]
2294   "TARGET_NEON"
2295 {
2296   if (!<Is_float_mode> || flag_unsafe_math_optimizations)
2297     emit_insn (gen_sub<mode>3 (operands[0], operands[1], operands[2]));
2298   else
2299     emit_insn (gen_neon_vsub<mode>_unspec (operands[0], operands[1],
2300                                            operands[2]));
2301   DONE;
2302 })
2303
2304 ; Used for intrinsics when flag_unsafe_math_optimizations is false.
2305
2306 (define_insn "neon_vsub<mode>_unspec"
2307   [(set (match_operand:VDQX 0 "s_register_operand" "=w")
2308         (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
2309                       (match_operand:VDQX 2 "s_register_operand" "w")]
2310                      UNSPEC_VSUB))]
2311   "TARGET_NEON"
2312   "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2313   [(set (attr "neon_type")
2314       (if_then_else (match_test "<Is_float_mode>")
2315                     (if_then_else (match_test "<Is_d_reg>")
2316                                   (const_string "neon_fp_vadd_ddd_vabs_dd")
2317                                   (const_string "neon_fp_vadd_qqq_vabs_qq"))
2318                     (const_string "neon_int_2")))]
2319 )
2320
2321 (define_insn "neon_vsubl<mode>"
2322   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2323         (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
2324                            (match_operand:VDI 2 "s_register_operand" "w")
2325                            (match_operand:SI 3 "immediate_operand" "i")]
2326                           UNSPEC_VSUBL))]
2327   "TARGET_NEON"
2328   "vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2329   [(set_attr "neon_type" "neon_int_2")]
2330 )
2331
2332 (define_insn "neon_vsubw<mode>"
2333   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2334         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
2335                            (match_operand:VDI 2 "s_register_operand" "w")
2336                            (match_operand:SI 3 "immediate_operand" "i")]
2337                           UNSPEC_VSUBW))]
2338   "TARGET_NEON"
2339   "vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
2340   [(set_attr "neon_type" "neon_int_2")]
2341 )
2342
2343 (define_insn "neon_vqsub<mode>"
2344   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2345         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2346                        (match_operand:VDQIX 2 "s_register_operand" "w")
2347                        (match_operand:SI 3 "immediate_operand" "i")]
2348                       UNSPEC_VQSUB))]
2349   "TARGET_NEON"
2350   "vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2351   [(set_attr "neon_type" "neon_int_5")]
2352 )
2353
2354 (define_insn "neon_vhsub<mode>"
2355   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2356         (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2357                        (match_operand:VDQIW 2 "s_register_operand" "w")
2358                        (match_operand:SI 3 "immediate_operand" "i")]
2359                       UNSPEC_VHSUB))]
2360   "TARGET_NEON"
2361   "vhsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2362   [(set_attr "neon_type" "neon_int_5")]
2363 )
2364
2365 (define_insn "neon_vsubhn<mode>"
2366   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2367         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2368                             (match_operand:VN 2 "s_register_operand" "w")
2369                             (match_operand:SI 3 "immediate_operand" "i")]
2370                            UNSPEC_VSUBHN))]
2371   "TARGET_NEON"
2372   "v%O3subhn.<V_if_elem>\t%P0, %q1, %q2"
2373   [(set_attr "neon_type" "neon_int_4")]
2374 )
2375
2376 (define_insn "neon_vceq<mode>"
2377   [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2378         (unspec:<V_cmp_result>
2379           [(match_operand:VDQW 1 "s_register_operand" "w,w")
2380            (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")
2381            (match_operand:SI 3 "immediate_operand" "i,i")]
2382           UNSPEC_VCEQ))]
2383   "TARGET_NEON"
2384   "@
2385   vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2386   vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, #0"
2387   [(set (attr "neon_type")
2388       (if_then_else (match_test "<Is_float_mode>")
2389                     (if_then_else (match_test "<Is_d_reg>")
2390                                   (const_string "neon_fp_vadd_ddd_vabs_dd")
2391                                   (const_string "neon_fp_vadd_qqq_vabs_qq"))
2392                     (const_string "neon_int_5")))]
2393 )
2394
2395 (define_insn "neon_vcge<mode>"
2396   [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2397         (unspec:<V_cmp_result>
2398           [(match_operand:VDQW 1 "s_register_operand" "w,w")
2399            (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")
2400            (match_operand:SI 3 "immediate_operand" "i,i")]
2401           UNSPEC_VCGE))]
2402   "TARGET_NEON"
2403   "@
2404   vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2405   vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2406   [(set (attr "neon_type")
2407      (if_then_else (match_test "<Is_float_mode>")
2408                    (if_then_else (match_test "<Is_d_reg>")
2409                                  (const_string "neon_fp_vadd_ddd_vabs_dd")
2410                                  (const_string "neon_fp_vadd_qqq_vabs_qq"))
2411                    (const_string "neon_int_5")))]
2412 )
2413
2414 (define_insn "neon_vcgeu<mode>"
2415   [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2416         (unspec:<V_cmp_result>
2417           [(match_operand:VDQIW 1 "s_register_operand" "w")
2418            (match_operand:VDQIW 2 "s_register_operand" "w")
2419            (match_operand:SI 3 "immediate_operand" "i")]
2420           UNSPEC_VCGEU))]
2421   "TARGET_NEON"
2422   "vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2423   [(set_attr "neon_type" "neon_int_5")]
2424 )
2425
2426 (define_insn "neon_vcgt<mode>"
2427   [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w,w")
2428         (unspec:<V_cmp_result>
2429           [(match_operand:VDQW 1 "s_register_operand" "w,w")
2430            (match_operand:VDQW 2 "reg_or_zero_operand" "w,Dz")
2431            (match_operand:SI 3 "immediate_operand" "i,i")]
2432           UNSPEC_VCGT))]
2433   "TARGET_NEON"
2434   "@
2435   vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
2436   vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2437   [(set (attr "neon_type")
2438      (if_then_else (match_test "<Is_float_mode>")
2439                    (if_then_else (match_test "<Is_d_reg>")
2440                                  (const_string "neon_fp_vadd_ddd_vabs_dd")
2441                                  (const_string "neon_fp_vadd_qqq_vabs_qq"))
2442                    (const_string "neon_int_5")))]
2443 )
2444
2445 (define_insn "neon_vcgtu<mode>"
2446   [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2447         (unspec:<V_cmp_result>
2448           [(match_operand:VDQIW 1 "s_register_operand" "w")
2449            (match_operand:VDQIW 2 "s_register_operand" "w")
2450            (match_operand:SI 3 "immediate_operand" "i")]
2451           UNSPEC_VCGTU))]
2452   "TARGET_NEON"
2453   "vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2454   [(set_attr "neon_type" "neon_int_5")]
2455 )
2456
2457 ;; VCLE and VCLT only support comparisons with immediate zero (register
2458 ;; variants are VCGE and VCGT with operands reversed).
2459
2460 (define_insn "neon_vcle<mode>"
2461   [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2462         (unspec:<V_cmp_result>
2463           [(match_operand:VDQW 1 "s_register_operand" "w")
2464            (match_operand:VDQW 2 "zero_operand" "Dz")
2465            (match_operand:SI 3 "immediate_operand" "i")]
2466           UNSPEC_VCLE))]
2467   "TARGET_NEON"
2468   "vcle.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2469   [(set (attr "neon_type")
2470       (if_then_else (match_test "<Is_float_mode>")
2471                     (if_then_else (match_test "<Is_d_reg>")
2472                                   (const_string "neon_fp_vadd_ddd_vabs_dd")
2473                                   (const_string "neon_fp_vadd_qqq_vabs_qq"))
2474                     (const_string "neon_int_5")))]
2475 )
2476
2477 (define_insn "neon_vclt<mode>"
2478   [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2479         (unspec:<V_cmp_result>
2480           [(match_operand:VDQW 1 "s_register_operand" "w")
2481            (match_operand:VDQW 2 "zero_operand" "Dz")
2482            (match_operand:SI 3 "immediate_operand" "i")]
2483           UNSPEC_VCLT))]
2484   "TARGET_NEON"
2485   "vclt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
2486   [(set (attr "neon_type")
2487       (if_then_else (match_test "<Is_float_mode>")
2488                     (if_then_else (match_test "<Is_d_reg>")
2489                                   (const_string "neon_fp_vadd_ddd_vabs_dd")
2490                                   (const_string "neon_fp_vadd_qqq_vabs_qq"))
2491                     (const_string "neon_int_5")))]
2492 )
2493
2494 (define_insn "neon_vcage<mode>"
2495   [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2496         (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2497                                 (match_operand:VCVTF 2 "s_register_operand" "w")
2498                                 (match_operand:SI 3 "immediate_operand" "i")]
2499                                UNSPEC_VCAGE))]
2500   "TARGET_NEON"
2501   "vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2502   [(set (attr "neon_type")
2503      (if_then_else (match_test "<Is_d_reg>")
2504                    (const_string "neon_fp_vadd_ddd_vabs_dd")
2505                    (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2506 )
2507
2508 (define_insn "neon_vcagt<mode>"
2509   [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
2510         (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
2511                                 (match_operand:VCVTF 2 "s_register_operand" "w")
2512                                 (match_operand:SI 3 "immediate_operand" "i")]
2513                                UNSPEC_VCAGT))]
2514   "TARGET_NEON"
2515   "vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2516   [(set (attr "neon_type")
2517      (if_then_else (match_test "<Is_d_reg>")
2518                    (const_string "neon_fp_vadd_ddd_vabs_dd")
2519                    (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2520 )
2521
2522 (define_insn "neon_vtst<mode>"
2523   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2524         (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2525                        (match_operand:VDQIW 2 "s_register_operand" "w")
2526                        (match_operand:SI 3 "immediate_operand" "i")]
2527                       UNSPEC_VTST))]
2528   "TARGET_NEON"
2529   "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2530   [(set_attr "neon_type" "neon_int_4")]
2531 )
2532
2533 (define_insn "neon_vabd<mode>"
2534   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2535         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2536                       (match_operand:VDQW 2 "s_register_operand" "w")
2537                       (match_operand:SI 3 "immediate_operand" "i")]
2538                      UNSPEC_VABD))]
2539   "TARGET_NEON"
2540   "vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2541   [(set (attr "neon_type")
2542      (if_then_else (match_test "<Is_float_mode>")
2543                    (if_then_else (match_test "<Is_d_reg>")
2544                                  (const_string "neon_fp_vadd_ddd_vabs_dd")
2545                                  (const_string "neon_fp_vadd_qqq_vabs_qq"))
2546                    (const_string "neon_int_5")))]
2547 )
2548
2549 (define_insn "neon_vabdl<mode>"
2550   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2551         (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2552                            (match_operand:VW 2 "s_register_operand" "w")
2553                            (match_operand:SI 3 "immediate_operand" "i")]
2554                           UNSPEC_VABDL))]
2555   "TARGET_NEON"
2556   "vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
2557   [(set_attr "neon_type" "neon_int_5")]
2558 )
2559
2560 (define_insn "neon_vaba<mode>"
2561   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2562         (plus:VDQIW (unspec:VDQIW [(match_operand:VDQIW 2 "s_register_operand" "w")
2563                                    (match_operand:VDQIW 3 "s_register_operand" "w")
2564                                    (match_operand:SI 4 "immediate_operand" "i")]
2565                                   UNSPEC_VABD)
2566                     (match_operand:VDQIW 1 "s_register_operand" "0")))]
2567   "TARGET_NEON"
2568   "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
2569   [(set (attr "neon_type")
2570      (if_then_else (match_test "<Is_d_reg>")
2571                    (const_string "neon_vaba") (const_string "neon_vaba_qqq")))]
2572 )
2573
2574 (define_insn "neon_vabal<mode>"
2575   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2576         (plus:<V_widen> (unspec:<V_widen> [(match_operand:VW 2 "s_register_operand" "w")
2577                                            (match_operand:VW 3 "s_register_operand" "w")
2578                                            (match_operand:SI 4 "immediate_operand" "i")]
2579                                            UNSPEC_VABDL)
2580                          (match_operand:<V_widen> 1 "s_register_operand" "0")))]
2581   "TARGET_NEON"
2582   "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
2583   [(set_attr "neon_type" "neon_vaba")]
2584 )
2585
2586 (define_insn "neon_vmax<mode>"
2587   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2588         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2589                       (match_operand:VDQW 2 "s_register_operand" "w")
2590                       (match_operand:SI 3 "immediate_operand" "i")]
2591                      UNSPEC_VMAX))]
2592   "TARGET_NEON"
2593   "vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2594   [(set (attr "neon_type")
2595     (if_then_else (match_test "<Is_float_mode>")
2596                   (if_then_else (match_test "<Is_d_reg>")
2597                                 (const_string "neon_fp_vadd_ddd_vabs_dd")
2598                                 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2599                   (const_string "neon_int_5")))]
2600 )
2601
2602 (define_insn "neon_vmin<mode>"
2603   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2604         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2605                       (match_operand:VDQW 2 "s_register_operand" "w")
2606                       (match_operand:SI 3 "immediate_operand" "i")]
2607                      UNSPEC_VMIN))]
2608   "TARGET_NEON"
2609   "vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2610   [(set (attr "neon_type")
2611     (if_then_else (match_test "<Is_float_mode>")
2612                   (if_then_else (match_test "<Is_d_reg>")
2613                                 (const_string "neon_fp_vadd_ddd_vabs_dd")
2614                                 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2615                   (const_string "neon_int_5")))]
2616 )
2617
2618 (define_expand "neon_vpadd<mode>"
2619   [(match_operand:VD 0 "s_register_operand" "=w")
2620    (match_operand:VD 1 "s_register_operand" "w")
2621    (match_operand:VD 2 "s_register_operand" "w")
2622    (match_operand:SI 3 "immediate_operand" "i")]
2623   "TARGET_NEON"
2624 {
2625   emit_insn (gen_neon_vpadd_internal<mode> (operands[0], operands[1],
2626                                             operands[2]));
2627   DONE;
2628 })
2629
2630 (define_insn "neon_vpaddl<mode>"
2631   [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2632         (unspec:<V_double_width> [(match_operand:VDQIW 1 "s_register_operand" "w")
2633                                   (match_operand:SI 2 "immediate_operand" "i")]
2634                                  UNSPEC_VPADDL))]
2635   "TARGET_NEON"
2636   "vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2637   ;; Assume this schedules like vaddl.
2638   [(set_attr "neon_type" "neon_int_3")]
2639 )
2640
2641 (define_insn "neon_vpadal<mode>"
2642   [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
2643         (unspec:<V_double_width> [(match_operand:<V_double_width> 1 "s_register_operand" "0")
2644                                   (match_operand:VDQIW 2 "s_register_operand" "w")
2645                                   (match_operand:SI 3 "immediate_operand" "i")]
2646                                  UNSPEC_VPADAL))]
2647   "TARGET_NEON"
2648   "vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
2649   ;; Assume this schedules like vpadd.
2650   [(set_attr "neon_type" "neon_int_1")]
2651 )
2652
2653 (define_insn "neon_vpmax<mode>"
2654   [(set (match_operand:VD 0 "s_register_operand" "=w")
2655         (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2656                     (match_operand:VD 2 "s_register_operand" "w")
2657                     (match_operand:SI 3 "immediate_operand" "i")]
2658                    UNSPEC_VPMAX))]
2659   "TARGET_NEON"
2660   "vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2661   ;; Assume this schedules like vmax.
2662   [(set (attr "neon_type")
2663     (if_then_else (match_test "<Is_float_mode>")
2664                   (const_string "neon_fp_vadd_ddd_vabs_dd")
2665                   (const_string "neon_int_5")))]
2666 )
2667
2668 (define_insn "neon_vpmin<mode>"
2669   [(set (match_operand:VD 0 "s_register_operand" "=w")
2670         (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2671                     (match_operand:VD 2 "s_register_operand" "w")
2672                     (match_operand:SI 3 "immediate_operand" "i")]
2673                    UNSPEC_VPMIN))]
2674   "TARGET_NEON"
2675   "vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2676   ;; Assume this schedules like vmin.
2677   [(set (attr "neon_type")
2678     (if_then_else (match_test "<Is_float_mode>")
2679                   (const_string "neon_fp_vadd_ddd_vabs_dd")
2680                   (const_string "neon_int_5")))]
2681 )
2682
2683 (define_insn "neon_vrecps<mode>"
2684   [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2685         (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2686                        (match_operand:VCVTF 2 "s_register_operand" "w")
2687                        (match_operand:SI 3 "immediate_operand" "i")]
2688                       UNSPEC_VRECPS))]
2689   "TARGET_NEON"
2690   "vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2691   [(set (attr "neon_type")
2692       (if_then_else (match_test "<Is_d_reg>")
2693                     (const_string "neon_fp_vrecps_vrsqrts_ddd")
2694                     (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2695 )
2696
2697 (define_insn "neon_vrsqrts<mode>"
2698   [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2699         (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2700                        (match_operand:VCVTF 2 "s_register_operand" "w")
2701                        (match_operand:SI 3 "immediate_operand" "i")]
2702                       UNSPEC_VRSQRTS))]
2703   "TARGET_NEON"
2704   "vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
2705   [(set (attr "neon_type")
2706       (if_then_else (match_test "<Is_d_reg>")
2707                     (const_string "neon_fp_vrecps_vrsqrts_ddd")
2708                     (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2709 )
2710
2711 (define_expand "neon_vabs<mode>"
2712   [(match_operand:VDQW 0 "s_register_operand" "")
2713    (match_operand:VDQW 1 "s_register_operand" "")
2714    (match_operand:SI 2 "immediate_operand" "")]
2715   "TARGET_NEON"
2716 {
2717   emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
2718   DONE;
2719 })
2720
2721 (define_insn "neon_vqabs<mode>"
2722   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2723         (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2724                        (match_operand:SI 2 "immediate_operand" "i")]
2725                       UNSPEC_VQABS))]
2726   "TARGET_NEON"
2727   "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2728   [(set_attr "neon_type" "neon_vqneg_vqabs")]
2729 )
2730
2731 (define_expand "neon_vneg<mode>"
2732   [(match_operand:VDQW 0 "s_register_operand" "")
2733    (match_operand:VDQW 1 "s_register_operand" "")
2734    (match_operand:SI 2 "immediate_operand" "")]
2735   "TARGET_NEON"
2736 {
2737   emit_insn (gen_neg<mode>2 (operands[0], operands[1]));
2738   DONE;
2739 })
2740
2741 (define_insn "neon_vqneg<mode>"
2742   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2743         (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2744                        (match_operand:SI 2 "immediate_operand" "i")]
2745                       UNSPEC_VQNEG))]
2746   "TARGET_NEON"
2747   "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2748   [(set_attr "neon_type" "neon_vqneg_vqabs")]
2749 )
2750
2751 (define_insn "neon_vcls<mode>"
2752   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2753         (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2754                        (match_operand:SI 2 "immediate_operand" "i")]
2755                       UNSPEC_VCLS))]
2756   "TARGET_NEON"
2757   "vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
2758   [(set_attr "neon_type" "neon_int_1")]
2759 )
2760
2761 (define_insn "clz<mode>2"
2762   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2763         (clz:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")))]
2764   "TARGET_NEON"
2765   "vclz.<V_if_elem>\t%<V_reg>0, %<V_reg>1"
2766   [(set_attr "neon_type" "neon_int_1")]
2767 )
2768
2769 (define_expand "neon_vclz<mode>"
2770   [(match_operand:VDQIW 0 "s_register_operand" "")
2771    (match_operand:VDQIW 1 "s_register_operand" "")
2772    (match_operand:SI 2 "immediate_operand" "")]
2773   "TARGET_NEON"
2774 {
2775   emit_insn (gen_clz<mode>2 (operands[0], operands[1]));
2776   DONE;
2777 })
2778
2779 (define_insn "popcount<mode>2"
2780   [(set (match_operand:VE 0 "s_register_operand" "=w")
2781         (popcount:VE (match_operand:VE 1 "s_register_operand" "w")))]
2782   "TARGET_NEON"
2783   "vcnt.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
2784   [(set_attr "neon_type" "neon_int_1")]
2785 )
2786
2787 (define_expand "neon_vcnt<mode>"
2788   [(match_operand:VE 0 "s_register_operand" "=w")
2789    (match_operand:VE 1 "s_register_operand" "w")
2790    (match_operand:SI 2 "immediate_operand" "i")]
2791   "TARGET_NEON"
2792 {
2793   emit_insn (gen_popcount<mode>2 (operands[0], operands[1]));
2794   DONE;
2795 })
2796
2797 (define_insn "neon_vrecpe<mode>"
2798   [(set (match_operand:V32 0 "s_register_operand" "=w")
2799         (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2800                      (match_operand:SI 2 "immediate_operand" "i")]
2801                     UNSPEC_VRECPE))]
2802   "TARGET_NEON"
2803   "vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2804   [(set (attr "neon_type")
2805       (if_then_else (match_test "<Is_d_reg>")
2806                     (const_string "neon_fp_vadd_ddd_vabs_dd")
2807                     (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2808 )
2809
2810 (define_insn "neon_vrsqrte<mode>"
2811   [(set (match_operand:V32 0 "s_register_operand" "=w")
2812         (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2813                      (match_operand:SI 2 "immediate_operand" "i")]
2814                     UNSPEC_VRSQRTE))]
2815   "TARGET_NEON"
2816   "vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
2817   [(set (attr "neon_type")
2818       (if_then_else (match_test "<Is_d_reg>")
2819                     (const_string "neon_fp_vadd_ddd_vabs_dd")
2820                     (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2821 )
2822
2823 (define_expand "neon_vmvn<mode>"
2824   [(match_operand:VDQIW 0 "s_register_operand" "")
2825    (match_operand:VDQIW 1 "s_register_operand" "")
2826    (match_operand:SI 2 "immediate_operand" "")]
2827   "TARGET_NEON"
2828 {
2829   emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[1]));
2830   DONE;
2831 })
2832
2833 (define_insn "neon_vget_lane<mode>_sext_internal"
2834   [(set (match_operand:SI 0 "s_register_operand" "=r")
2835         (sign_extend:SI
2836           (vec_select:<V_elem>
2837             (match_operand:VD 1 "s_register_operand" "w")
2838             (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2839   "TARGET_NEON"
2840 {
2841   if (BYTES_BIG_ENDIAN)
2842     {
2843       int elt = INTVAL (operands[2]);
2844       elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2845       operands[2] = GEN_INT (elt);
2846     }
2847   return "vmov.s<V_sz_elem>\t%0, %P1[%c2]";
2848 }
2849   [(set_attr "neon_type" "neon_bp_simple")]
2850 )
2851
2852 (define_insn "neon_vget_lane<mode>_zext_internal"
2853   [(set (match_operand:SI 0 "s_register_operand" "=r")
2854         (zero_extend:SI
2855           (vec_select:<V_elem>
2856             (match_operand:VD 1 "s_register_operand" "w")
2857             (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2858   "TARGET_NEON"
2859 {
2860   if (BYTES_BIG_ENDIAN)
2861     {
2862       int elt = INTVAL (operands[2]);
2863       elt = GET_MODE_NUNITS (<MODE>mode) - 1 - elt;
2864       operands[2] = GEN_INT (elt);
2865     }
2866   return "vmov.u<V_sz_elem>\t%0, %P1[%c2]";
2867 }
2868   [(set_attr "neon_type" "neon_bp_simple")]
2869 )
2870
2871 (define_insn "neon_vget_lane<mode>_sext_internal"
2872   [(set (match_operand:SI 0 "s_register_operand" "=r")
2873         (sign_extend:SI
2874           (vec_select:<V_elem>
2875             (match_operand:VQ 1 "s_register_operand" "w")
2876             (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2877   "TARGET_NEON"
2878 {
2879   rtx ops[3];
2880   int regno = REGNO (operands[1]);
2881   unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2882   unsigned int elt = INTVAL (operands[2]);
2883   unsigned int elt_adj = elt % halfelts;
2884
2885   if (BYTES_BIG_ENDIAN)
2886     elt_adj = halfelts - 1 - elt_adj;
2887
2888   ops[0] = operands[0];
2889   ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2890   ops[2] = GEN_INT (elt_adj);
2891   output_asm_insn ("vmov.s<V_sz_elem>\t%0, %P1[%c2]", ops);
2892
2893   return "";
2894 }
2895   [(set_attr "neon_type" "neon_bp_simple")]
2896 )
2897
2898 (define_insn "neon_vget_lane<mode>_zext_internal"
2899   [(set (match_operand:SI 0 "s_register_operand" "=r")
2900         (zero_extend:SI
2901           (vec_select:<V_elem>
2902             (match_operand:VQ 1 "s_register_operand" "w")
2903             (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2904   "TARGET_NEON"
2905 {
2906   rtx ops[3];
2907   int regno = REGNO (operands[1]);
2908   unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
2909   unsigned int elt = INTVAL (operands[2]);
2910   unsigned int elt_adj = elt % halfelts;
2911
2912   if (BYTES_BIG_ENDIAN)
2913     elt_adj = halfelts - 1 - elt_adj;
2914
2915   ops[0] = operands[0];
2916   ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
2917   ops[2] = GEN_INT (elt_adj);
2918   output_asm_insn ("vmov.u<V_sz_elem>\t%0, %P1[%c2]", ops);
2919
2920   return "";
2921 }
2922   [(set_attr "neon_type" "neon_bp_simple")]
2923 )
2924
2925 (define_expand "neon_vget_lane<mode>"
2926   [(match_operand:<V_ext> 0 "s_register_operand" "")
2927    (match_operand:VDQW 1 "s_register_operand" "")
2928    (match_operand:SI 2 "immediate_operand" "")
2929    (match_operand:SI 3 "immediate_operand" "")]
2930   "TARGET_NEON"
2931 {
2932   HOST_WIDE_INT magic = INTVAL (operands[3]);
2933   rtx insn;
2934
2935   neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<MODE>mode));
2936
2937   if (BYTES_BIG_ENDIAN)
2938     {
2939       /* The intrinsics are defined in terms of a model where the
2940          element ordering in memory is vldm order, whereas the generic
2941          RTL is defined in terms of a model where the element ordering
2942          in memory is array order.  Convert the lane number to conform
2943          to this model.  */
2944       unsigned int elt = INTVAL (operands[2]);
2945       unsigned int reg_nelts
2946         = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
2947       elt ^= reg_nelts - 1;
2948       operands[2] = GEN_INT (elt);
2949     }
2950
2951   if ((magic & 3) == 3 || GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode)) == 32)
2952     insn = gen_vec_extract<mode> (operands[0], operands[1], operands[2]);
2953   else
2954     {
2955       if ((magic & 1) != 0)
2956         insn = gen_neon_vget_lane<mode>_sext_internal (operands[0], operands[1],
2957                                                        operands[2]);
2958       else
2959         insn = gen_neon_vget_lane<mode>_zext_internal (operands[0], operands[1],
2960                                                        operands[2]);
2961     }
2962   emit_insn (insn);
2963   DONE;
2964 })
2965
2966 ; Operand 3 (info word) is ignored because it does nothing useful with 64-bit
2967 ; elements.
2968
2969 (define_expand "neon_vget_lanedi"
2970   [(match_operand:DI 0 "s_register_operand" "=r")
2971    (match_operand:DI 1 "s_register_operand" "w")
2972    (match_operand:SI 2 "immediate_operand" "i")
2973    (match_operand:SI 3 "immediate_operand" "i")]
2974   "TARGET_NEON"
2975 {
2976   neon_lane_bounds (operands[2], 0, 1);
2977   emit_move_insn (operands[0], operands[1]);
2978   DONE;
2979 })
2980
2981 (define_expand "neon_vget_lanev2di"
2982   [(match_operand:DI 0 "s_register_operand" "")
2983    (match_operand:V2DI 1 "s_register_operand" "")
2984    (match_operand:SI 2 "immediate_operand" "")
2985    (match_operand:SI 3 "immediate_operand" "")]
2986   "TARGET_NEON"
2987 {
2988   switch (INTVAL (operands[2]))
2989     {
2990     case 0:
2991       emit_move_insn (operands[0], gen_lowpart (DImode, operands[1]));
2992       break;
2993     case 1:
2994       emit_move_insn (operands[0], gen_highpart (DImode, operands[1]));
2995       break;
2996     default:
2997       neon_lane_bounds (operands[2], 0, 1);
2998       FAIL;
2999     }
3000   DONE;
3001 })
3002
3003 (define_expand "neon_vset_lane<mode>"
3004   [(match_operand:VDQ 0 "s_register_operand" "=w")
3005    (match_operand:<V_elem> 1 "s_register_operand" "r")
3006    (match_operand:VDQ 2 "s_register_operand" "0")
3007    (match_operand:SI 3 "immediate_operand" "i")]
3008   "TARGET_NEON"
3009 {
3010   unsigned int elt = INTVAL (operands[3]);
3011   neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3012
3013   if (BYTES_BIG_ENDIAN)
3014     {
3015       unsigned int reg_nelts
3016         = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<MODE>mode));
3017       elt ^= reg_nelts - 1;
3018     }
3019
3020   emit_insn (gen_vec_set<mode>_internal (operands[0], operands[1],
3021                                          GEN_INT (1 << elt), operands[2]));
3022   DONE;
3023 })
3024
3025 ; See neon_vget_lanedi comment for reasons operands 2 & 3 are ignored.
3026
3027 (define_expand "neon_vset_lanedi"
3028   [(match_operand:DI 0 "s_register_operand" "=w")
3029    (match_operand:DI 1 "s_register_operand" "r")
3030    (match_operand:DI 2 "s_register_operand" "0")
3031    (match_operand:SI 3 "immediate_operand" "i")]
3032   "TARGET_NEON"
3033 {
3034   neon_lane_bounds (operands[3], 0, 1);
3035   emit_move_insn (operands[0], operands[1]);
3036   DONE;
3037 })
3038
3039 (define_expand "neon_vcreate<mode>"
3040   [(match_operand:VDX 0 "s_register_operand" "")
3041    (match_operand:DI 1 "general_operand" "")]
3042   "TARGET_NEON"
3043 {
3044   rtx src = gen_lowpart (<MODE>mode, operands[1]);
3045   emit_move_insn (operands[0], src);
3046   DONE;
3047 })
3048
3049 (define_insn "neon_vdup_n<mode>"
3050   [(set (match_operand:VX 0 "s_register_operand" "=w")
3051         (vec_duplicate:VX (match_operand:<V_elem> 1 "s_register_operand" "r")))]
3052   "TARGET_NEON"
3053   "vdup.<V_sz_elem>\t%<V_reg>0, %1"
3054   ;; Assume this schedules like vmov.
3055   [(set_attr "neon_type" "neon_bp_simple")]
3056 )
3057
3058 (define_insn "neon_vdup_n<mode>"
3059   [(set (match_operand:V32 0 "s_register_operand" "=w,w")
3060         (vec_duplicate:V32 (match_operand:<V_elem> 1 "s_register_operand" "r,t")))]
3061   "TARGET_NEON"
3062   "@
3063   vdup.<V_sz_elem>\t%<V_reg>0, %1
3064   vdup.<V_sz_elem>\t%<V_reg>0, %y1"
3065   ;; Assume this schedules like vmov.
3066   [(set_attr "neon_type" "neon_bp_simple")]
3067 )
3068
3069 (define_expand "neon_vdup_ndi"
3070   [(match_operand:DI 0 "s_register_operand" "=w")
3071    (match_operand:DI 1 "s_register_operand" "r")]
3072   "TARGET_NEON"
3073 {
3074   emit_move_insn (operands[0], operands[1]);
3075   DONE;
3076 }
3077 )
3078
3079 (define_insn "neon_vdup_nv2di"
3080   [(set (match_operand:V2DI 0 "s_register_operand" "=w,w")
3081         (vec_duplicate:V2DI (match_operand:DI 1 "s_register_operand" "r,w")))]
3082   "TARGET_NEON"
3083   "@
3084   vmov\t%e0, %Q1, %R1\;vmov\t%f0, %Q1, %R1
3085   vmov\t%e0, %P1\;vmov\t%f0, %P1"
3086   [(set_attr "length" "8")
3087    (set_attr "neon_type" "neon_bp_simple")]
3088 )
3089
3090 (define_insn "neon_vdup_lane<mode>_internal"
3091   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
3092         (vec_duplicate:VDQW 
3093           (vec_select:<V_elem>
3094             (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
3095             (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
3096   "TARGET_NEON"
3097 {
3098   if (BYTES_BIG_ENDIAN)
3099     {
3100       int elt = INTVAL (operands[2]);
3101       elt = GET_MODE_NUNITS (<V_double_vector_mode>mode) - 1 - elt;
3102       operands[2] = GEN_INT (elt);
3103     }
3104   if (<Is_d_reg>)
3105     return "vdup.<V_sz_elem>\t%P0, %P1[%c2]";
3106   else
3107     return "vdup.<V_sz_elem>\t%q0, %P1[%c2]";
3108 }
3109   ;; Assume this schedules like vmov.
3110   [(set_attr "neon_type" "neon_bp_simple")]
3111 )
3112
3113 (define_expand "neon_vdup_lane<mode>"
3114   [(match_operand:VDQW 0 "s_register_operand" "=w")
3115    (match_operand:<V_double_vector_mode> 1 "s_register_operand" "w")
3116    (match_operand:SI 2 "immediate_operand" "i")]
3117   "TARGET_NEON"
3118 {
3119   neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (<V_double_vector_mode>mode));
3120   if (BYTES_BIG_ENDIAN)
3121     {
3122       unsigned int elt = INTVAL (operands[2]);
3123       unsigned int reg_nelts
3124         = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (<V_double_vector_mode>mode));
3125       elt ^= reg_nelts - 1;
3126       operands[2] = GEN_INT (elt);
3127     }
3128     emit_insn (gen_neon_vdup_lane<mode>_internal (operands[0], operands[1],
3129                                                   operands[2]));
3130     DONE;
3131 })
3132
3133 ; Scalar index is ignored, since only zero is valid here.
3134 (define_expand "neon_vdup_lanedi"
3135   [(match_operand:DI 0 "s_register_operand" "=w")
3136    (match_operand:DI 1 "s_register_operand" "w")
3137    (match_operand:SI 2 "immediate_operand" "i")]
3138   "TARGET_NEON"
3139 {
3140   neon_lane_bounds (operands[2], 0, 1);
3141   emit_move_insn (operands[0], operands[1]);
3142   DONE;
3143 })
3144
3145 ; Likewise for v2di, as the DImode second operand has only a single element.
3146 (define_expand "neon_vdup_lanev2di"
3147   [(match_operand:V2DI 0 "s_register_operand" "=w")
3148    (match_operand:DI 1 "s_register_operand" "w")
3149    (match_operand:SI 2 "immediate_operand" "i")]
3150   "TARGET_NEON"
3151 {
3152   neon_lane_bounds (operands[2], 0, 1);
3153   emit_insn (gen_neon_vdup_nv2di (operands[0], operands[1]));
3154   DONE;
3155 })
3156
3157 ; Disabled before reload because we don't want combine doing something silly,
3158 ; but used by the post-reload expansion of neon_vcombine.
3159 (define_insn "*neon_vswp<mode>"
3160   [(set (match_operand:VDQX 0 "s_register_operand" "+w")
3161         (match_operand:VDQX 1 "s_register_operand" "+w"))
3162    (set (match_dup 1) (match_dup 0))]
3163   "TARGET_NEON && reload_completed"
3164   "vswp\t%<V_reg>0, %<V_reg>1"
3165   [(set (attr "neon_type")
3166         (if_then_else (match_test "<Is_d_reg>")
3167                       (const_string "neon_bp_simple")
3168                       (const_string "neon_bp_2cycle")))]
3169 )
3170
3171 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
3172 ;; dest vector.
3173 ;; FIXME: A different implementation of this builtin could make it much
3174 ;; more likely that we wouldn't actually need to output anything (we could make
3175 ;; it so that the reg allocator puts things in the right places magically
3176 ;; instead). Lack of subregs for vectors makes that tricky though, I think.
3177
3178 (define_insn_and_split "neon_vcombine<mode>"
3179   [(set (match_operand:<V_DOUBLE> 0 "s_register_operand" "=w")
3180         (vec_concat:<V_DOUBLE>
3181           (match_operand:VDX 1 "s_register_operand" "w")
3182           (match_operand:VDX 2 "s_register_operand" "w")))]
3183   "TARGET_NEON"
3184   "#"
3185   "&& reload_completed"
3186   [(const_int 0)]
3187 {
3188   neon_split_vcombine (operands);
3189   DONE;
3190 })
3191
3192 (define_expand "neon_vget_high<mode>"
3193   [(match_operand:<V_HALF> 0 "s_register_operand")
3194    (match_operand:VQX 1 "s_register_operand")]
3195   "TARGET_NEON"
3196 {
3197   emit_move_insn (operands[0],
3198                   simplify_gen_subreg (<V_HALF>mode, operands[1], <MODE>mode,
3199                                        GET_MODE_SIZE (<V_HALF>mode)));
3200   DONE;
3201 })
3202
3203 (define_expand "neon_vget_low<mode>"
3204   [(match_operand:<V_HALF> 0 "s_register_operand")
3205    (match_operand:VQX 1 "s_register_operand")]
3206   "TARGET_NEON"
3207 {
3208   emit_move_insn (operands[0],
3209                   simplify_gen_subreg (<V_HALF>mode, operands[1],
3210                                        <MODE>mode, 0));
3211   DONE;
3212 })
3213
3214 (define_insn "float<mode><V_cvtto>2"
3215   [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3216         (float:<V_CVTTO> (match_operand:VCVTI 1 "s_register_operand" "w")))]
3217   "TARGET_NEON && !flag_rounding_math"
3218   "vcvt.f32.s32\t%<V_reg>0, %<V_reg>1"
3219   [(set (attr "neon_type")
3220      (if_then_else (match_test "<Is_d_reg>")
3221                    (const_string "neon_fp_vadd_ddd_vabs_dd")
3222                    (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3223 )
3224
3225 (define_insn "floatuns<mode><V_cvtto>2"
3226   [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3227         (unsigned_float:<V_CVTTO> (match_operand:VCVTI 1 "s_register_operand" "w")))] 
3228   "TARGET_NEON && !flag_rounding_math"
3229   "vcvt.f32.u32\t%<V_reg>0, %<V_reg>1"
3230   [(set (attr "neon_type")
3231      (if_then_else (match_test "<Is_d_reg>")
3232                    (const_string "neon_fp_vadd_ddd_vabs_dd")
3233                    (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3234 )
3235
3236 (define_insn "fix_trunc<mode><V_cvtto>2"
3237   [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3238         (fix:<V_CVTTO> (match_operand:VCVTF 1 "s_register_operand" "w")))]
3239   "TARGET_NEON"
3240   "vcvt.s32.f32\t%<V_reg>0, %<V_reg>1"
3241   [(set (attr "neon_type")
3242      (if_then_else (match_test "<Is_d_reg>")
3243                    (const_string "neon_fp_vadd_ddd_vabs_dd")
3244                    (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3245 )
3246
3247 (define_insn "fixuns_trunc<mode><V_cvtto>2"
3248   [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3249         (unsigned_fix:<V_CVTTO> (match_operand:VCVTF 1 "s_register_operand" "w")))]
3250   "TARGET_NEON"
3251   "vcvt.u32.f32\t%<V_reg>0, %<V_reg>1"
3252   [(set (attr "neon_type")
3253      (if_then_else (match_test "<Is_d_reg>")
3254                    (const_string "neon_fp_vadd_ddd_vabs_dd")
3255                    (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3256 )
3257
3258 (define_insn "neon_vcvt<mode>"
3259   [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3260         (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3261                            (match_operand:SI 2 "immediate_operand" "i")]
3262                           UNSPEC_VCVT))]
3263   "TARGET_NEON"
3264   "vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1"
3265   [(set (attr "neon_type")
3266      (if_then_else (match_test "<Is_d_reg>")
3267                    (const_string "neon_fp_vadd_ddd_vabs_dd")
3268                    (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3269 )
3270
3271 (define_insn "neon_vcvt<mode>"
3272   [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3273         (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3274                            (match_operand:SI 2 "immediate_operand" "i")]
3275                           UNSPEC_VCVT))]
3276   "TARGET_NEON"
3277   "vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1"
3278   [(set (attr "neon_type")
3279      (if_then_else (match_test "<Is_d_reg>")
3280                    (const_string "neon_fp_vadd_ddd_vabs_dd")
3281                    (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3282 )
3283
3284 (define_insn "neon_vcvt_n<mode>"
3285   [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3286         (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
3287                            (match_operand:SI 2 "immediate_operand" "i")
3288                            (match_operand:SI 3 "immediate_operand" "i")]
3289                           UNSPEC_VCVT_N))]
3290   "TARGET_NEON"
3291 {
3292   neon_const_bounds (operands[2], 1, 33);
3293   return "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2";
3294 }
3295   [(set (attr "neon_type")
3296      (if_then_else (match_test "<Is_d_reg>")
3297                    (const_string "neon_fp_vadd_ddd_vabs_dd")
3298                    (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3299 )
3300
3301 (define_insn "neon_vcvt_n<mode>"
3302   [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
3303         (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
3304                            (match_operand:SI 2 "immediate_operand" "i")
3305                            (match_operand:SI 3 "immediate_operand" "i")]
3306                           UNSPEC_VCVT_N))]
3307   "TARGET_NEON"
3308 {
3309   neon_const_bounds (operands[2], 1, 33);
3310   return "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2";
3311 }
3312   [(set (attr "neon_type")
3313      (if_then_else (match_test "<Is_d_reg>")
3314                    (const_string "neon_fp_vadd_ddd_vabs_dd")
3315                    (const_string "neon_fp_vadd_qqq_vabs_qq")))]
3316 )
3317
3318 (define_insn "neon_vmovn<mode>"
3319   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3320         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3321                             (match_operand:SI 2 "immediate_operand" "i")]
3322                            UNSPEC_VMOVN))]
3323   "TARGET_NEON"
3324   "vmovn.<V_if_elem>\t%P0, %q1"
3325   [(set_attr "neon_type" "neon_bp_simple")]
3326 )
3327
3328 (define_insn "neon_vqmovn<mode>"
3329   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3330         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3331                             (match_operand:SI 2 "immediate_operand" "i")]
3332                            UNSPEC_VQMOVN))]
3333   "TARGET_NEON"
3334   "vqmovn.%T2%#<V_sz_elem>\t%P0, %q1"
3335   [(set_attr "neon_type" "neon_shift_2")]
3336 )
3337
3338 (define_insn "neon_vqmovun<mode>"
3339   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3340         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3341                             (match_operand:SI 2 "immediate_operand" "i")]
3342                            UNSPEC_VQMOVUN))]
3343   "TARGET_NEON"
3344   "vqmovun.<V_s_elem>\t%P0, %q1"
3345   [(set_attr "neon_type" "neon_shift_2")]
3346 )
3347
3348 (define_insn "neon_vmovl<mode>"
3349   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3350         (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
3351                            (match_operand:SI 2 "immediate_operand" "i")]
3352                           UNSPEC_VMOVL))]
3353   "TARGET_NEON"
3354   "vmovl.%T2%#<V_sz_elem>\t%q0, %P1"
3355   [(set_attr "neon_type" "neon_shift_1")]
3356 )
3357
3358 (define_insn "neon_vmul_lane<mode>"
3359   [(set (match_operand:VMD 0 "s_register_operand" "=w")
3360         (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "w")
3361                      (match_operand:VMD 2 "s_register_operand"
3362                                         "<scalar_mul_constraint>")
3363                      (match_operand:SI 3 "immediate_operand" "i")
3364                      (match_operand:SI 4 "immediate_operand" "i")]
3365                     UNSPEC_VMUL_LANE))]
3366   "TARGET_NEON"
3367 {
3368   neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3369   return "vmul.<V_if_elem>\t%P0, %P1, %P2[%c3]";
3370 }
3371   [(set (attr "neon_type")
3372      (if_then_else (match_test "<Is_float_mode>")
3373                    (const_string "neon_fp_vmul_ddd")
3374                    (if_then_else (match_test "<Scalar_mul_8_16>")
3375                                  (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3376                                  (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))))]
3377 )
3378
3379 (define_insn "neon_vmul_lane<mode>"
3380   [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3381         (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "w")
3382                      (match_operand:<V_HALF> 2 "s_register_operand"
3383                                              "<scalar_mul_constraint>")
3384                      (match_operand:SI 3 "immediate_operand" "i")
3385                      (match_operand:SI 4 "immediate_operand" "i")]
3386                     UNSPEC_VMUL_LANE))]
3387   "TARGET_NEON"
3388 {
3389   neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<V_HALF>mode));
3390   return "vmul.<V_if_elem>\t%q0, %q1, %P2[%c3]";
3391 }
3392   [(set (attr "neon_type")
3393      (if_then_else (match_test "<Is_float_mode>")
3394                    (const_string "neon_fp_vmul_qqd")
3395                    (if_then_else (match_test "<Scalar_mul_8_16>")
3396                                  (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3397                                  (const_string "neon_mul_qqd_32_scalar"))))]
3398 )
3399
3400 (define_insn "neon_vmull_lane<mode>"
3401   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3402         (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3403                            (match_operand:VMDI 2 "s_register_operand"
3404                                                "<scalar_mul_constraint>")
3405                            (match_operand:SI 3 "immediate_operand" "i")
3406                            (match_operand:SI 4 "immediate_operand" "i")]
3407                           UNSPEC_VMULL_LANE))]
3408   "TARGET_NEON"
3409 {
3410   neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3411   return "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]";
3412 }
3413   [(set (attr "neon_type")
3414      (if_then_else (match_test "<Scalar_mul_8_16>")
3415                    (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3416                    (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3417 )
3418
3419 (define_insn "neon_vqdmull_lane<mode>"
3420   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3421         (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
3422                            (match_operand:VMDI 2 "s_register_operand"
3423                                                "<scalar_mul_constraint>")
3424                            (match_operand:SI 3 "immediate_operand" "i")
3425                            (match_operand:SI 4 "immediate_operand" "i")]
3426                           UNSPEC_VQDMULL_LANE))]
3427   "TARGET_NEON"
3428 {
3429   neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3430   return "vqdmull.<V_s_elem>\t%q0, %P1, %P2[%c3]";
3431 }
3432   [(set (attr "neon_type")
3433      (if_then_else (match_test "<Scalar_mul_8_16>")
3434                    (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3435                    (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3436 )
3437
3438 (define_insn "neon_vqdmulh_lane<mode>"
3439   [(set (match_operand:VMQI 0 "s_register_operand" "=w")
3440         (unspec:VMQI [(match_operand:VMQI 1 "s_register_operand" "w")
3441                       (match_operand:<V_HALF> 2 "s_register_operand"
3442                                               "<scalar_mul_constraint>")
3443                       (match_operand:SI 3 "immediate_operand" "i")
3444                       (match_operand:SI 4 "immediate_operand" "i")]
3445                       UNSPEC_VQDMULH_LANE))]
3446   "TARGET_NEON"
3447 {
3448   neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3449   return "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]";
3450 }
3451   [(set (attr "neon_type")
3452      (if_then_else (match_test "<Scalar_mul_8_16>")
3453                    (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3454                    (const_string "neon_mul_qqd_32_scalar")))]
3455 )
3456
3457 (define_insn "neon_vqdmulh_lane<mode>"
3458   [(set (match_operand:VMDI 0 "s_register_operand" "=w")
3459         (unspec:VMDI [(match_operand:VMDI 1 "s_register_operand" "w")
3460                       (match_operand:VMDI 2 "s_register_operand"
3461                                           "<scalar_mul_constraint>")
3462                       (match_operand:SI 3 "immediate_operand" "i")
3463                       (match_operand:SI 4 "immediate_operand" "i")]
3464                       UNSPEC_VQDMULH_LANE))]
3465   "TARGET_NEON"
3466 {
3467   neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3468   return "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]";
3469 }
3470   [(set (attr "neon_type")
3471      (if_then_else (match_test "<Scalar_mul_8_16>")
3472                    (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3473                    (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3474 )
3475
3476 (define_insn "neon_vmla_lane<mode>"
3477   [(set (match_operand:VMD 0 "s_register_operand" "=w")
3478         (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3479                      (match_operand:VMD 2 "s_register_operand" "w")
3480                      (match_operand:VMD 3 "s_register_operand"
3481                                         "<scalar_mul_constraint>")
3482                      (match_operand:SI 4 "immediate_operand" "i")
3483                      (match_operand:SI 5 "immediate_operand" "i")]
3484                      UNSPEC_VMLA_LANE))]
3485   "TARGET_NEON"
3486 {
3487   neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3488   return "vmla.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3489 }
3490   [(set (attr "neon_type")
3491      (if_then_else (match_test "<Is_float_mode>")
3492                    (const_string "neon_fp_vmla_ddd_scalar")
3493                    (if_then_else (match_test "<Scalar_mul_8_16>")
3494                                  (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3495                                  (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3496 )
3497
3498 (define_insn "neon_vmla_lane<mode>"
3499   [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3500         (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3501                      (match_operand:VMQ 2 "s_register_operand" "w")
3502                      (match_operand:<V_HALF> 3 "s_register_operand"
3503                                              "<scalar_mul_constraint>")
3504                      (match_operand:SI 4 "immediate_operand" "i")
3505                      (match_operand:SI 5 "immediate_operand" "i")]
3506                      UNSPEC_VMLA_LANE))]
3507   "TARGET_NEON"
3508 {
3509   neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3510   return "vmla.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3511 }
3512   [(set (attr "neon_type")
3513      (if_then_else (match_test "<Is_float_mode>")
3514                    (const_string "neon_fp_vmla_qqq_scalar")
3515                    (if_then_else (match_test "<Scalar_mul_8_16>")
3516                                  (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3517                                  (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3518 )
3519
3520 (define_insn "neon_vmlal_lane<mode>"
3521   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3522         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3523                            (match_operand:VMDI 2 "s_register_operand" "w")
3524                            (match_operand:VMDI 3 "s_register_operand"
3525                                                "<scalar_mul_constraint>")
3526                            (match_operand:SI 4 "immediate_operand" "i")
3527                            (match_operand:SI 5 "immediate_operand" "i")]
3528                           UNSPEC_VMLAL_LANE))]
3529   "TARGET_NEON"
3530 {
3531   neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3532   return "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3533 }
3534   [(set (attr "neon_type")
3535      (if_then_else (match_test "<Scalar_mul_8_16>")
3536                    (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3537                    (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3538 )
3539
3540 (define_insn "neon_vqdmlal_lane<mode>"
3541   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3542         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3543                            (match_operand:VMDI 2 "s_register_operand" "w")
3544                            (match_operand:VMDI 3 "s_register_operand"
3545                                                "<scalar_mul_constraint>")
3546                            (match_operand:SI 4 "immediate_operand" "i")
3547                            (match_operand:SI 5 "immediate_operand" "i")]
3548                           UNSPEC_VQDMLAL_LANE))]
3549   "TARGET_NEON"
3550 {
3551   neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3552   return "vqdmlal.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3553 }
3554   [(set (attr "neon_type")
3555      (if_then_else (match_test "<Scalar_mul_8_16>")
3556                    (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3557                    (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3558 )
3559
3560 (define_insn "neon_vmls_lane<mode>"
3561   [(set (match_operand:VMD 0 "s_register_operand" "=w")
3562         (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3563                      (match_operand:VMD 2 "s_register_operand" "w")
3564                      (match_operand:VMD 3 "s_register_operand"
3565                                         "<scalar_mul_constraint>")
3566                      (match_operand:SI 4 "immediate_operand" "i")
3567                      (match_operand:SI 5 "immediate_operand" "i")]
3568                     UNSPEC_VMLS_LANE))]
3569   "TARGET_NEON"
3570 {
3571   neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3572   return "vmls.<V_if_elem>\t%P0, %P2, %P3[%c4]";
3573 }
3574   [(set (attr "neon_type")
3575      (if_then_else (match_test "<Is_float_mode>")
3576                    (const_string "neon_fp_vmla_ddd_scalar")
3577                    (if_then_else (match_test "<Scalar_mul_8_16>")
3578                                  (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3579                                  (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3580 )
3581
3582 (define_insn "neon_vmls_lane<mode>"
3583   [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3584         (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3585                      (match_operand:VMQ 2 "s_register_operand" "w")
3586                      (match_operand:<V_HALF> 3 "s_register_operand"
3587                                              "<scalar_mul_constraint>")
3588                      (match_operand:SI 4 "immediate_operand" "i")
3589                      (match_operand:SI 5 "immediate_operand" "i")]
3590                     UNSPEC_VMLS_LANE))]
3591   "TARGET_NEON"
3592 {
3593   neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3594   return "vmls.<V_if_elem>\t%q0, %q2, %P3[%c4]";
3595 }
3596   [(set (attr "neon_type")
3597      (if_then_else (match_test "<Is_float_mode>")
3598                    (const_string "neon_fp_vmla_qqq_scalar")
3599                    (if_then_else (match_test "<Scalar_mul_8_16>")
3600                                  (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3601                                  (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3602 )
3603
3604 (define_insn "neon_vmlsl_lane<mode>"
3605   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3606         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3607                            (match_operand:VMDI 2 "s_register_operand" "w")
3608                            (match_operand:VMDI 3 "s_register_operand"
3609                                                "<scalar_mul_constraint>")
3610                            (match_operand:SI 4 "immediate_operand" "i")
3611                            (match_operand:SI 5 "immediate_operand" "i")]
3612                           UNSPEC_VMLSL_LANE))]
3613   "TARGET_NEON"
3614 {
3615   neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3616   return "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
3617 }
3618   [(set (attr "neon_type")
3619      (if_then_else (match_test "<Scalar_mul_8_16>")
3620                    (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3621                    (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3622 )
3623
3624 (define_insn "neon_vqdmlsl_lane<mode>"
3625   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
3626         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
3627                            (match_operand:VMDI 2 "s_register_operand" "w")
3628                            (match_operand:VMDI 3 "s_register_operand"
3629                                                "<scalar_mul_constraint>")
3630                            (match_operand:SI 4 "immediate_operand" "i")
3631                            (match_operand:SI 5 "immediate_operand" "i")]
3632                           UNSPEC_VQDMLSL_LANE))]
3633   "TARGET_NEON"
3634 {
3635   neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
3636   return "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3[%c4]";
3637 }
3638   [(set (attr "neon_type")
3639      (if_then_else (match_test "<Scalar_mul_8_16>")
3640                    (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3641                    (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3642 )
3643
3644 ; FIXME: For the "_n" multiply/multiply-accumulate insns, we copy a value in a
3645 ; core register into a temp register, then use a scalar taken from that. This
3646 ; isn't an optimal solution if e.g. the scalar has just been read from memory
3647 ; or extracted from another vector. The latter case it's currently better to
3648 ; use the "_lane" variant, and the former case can probably be implemented
3649 ; using vld1_lane, but that hasn't been done yet.
3650
3651 (define_expand "neon_vmul_n<mode>"
3652   [(match_operand:VMD 0 "s_register_operand" "")
3653    (match_operand:VMD 1 "s_register_operand" "")
3654    (match_operand:<V_elem> 2 "s_register_operand" "")
3655    (match_operand:SI 3 "immediate_operand" "")]
3656   "TARGET_NEON"
3657 {
3658   rtx tmp = gen_reg_rtx (<MODE>mode);
3659   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3660   emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3661                                        const0_rtx, const0_rtx));
3662   DONE;
3663 })
3664
3665 (define_expand "neon_vmul_n<mode>"
3666   [(match_operand:VMQ 0 "s_register_operand" "")
3667    (match_operand:VMQ 1 "s_register_operand" "")
3668    (match_operand:<V_elem> 2 "s_register_operand" "")
3669    (match_operand:SI 3 "immediate_operand" "")]
3670   "TARGET_NEON"
3671 {
3672   rtx tmp = gen_reg_rtx (<V_HALF>mode);
3673   emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3674   emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
3675                                        const0_rtx, const0_rtx));
3676   DONE;
3677 })
3678
3679 (define_expand "neon_vmull_n<mode>"
3680   [(match_operand:<V_widen> 0 "s_register_operand" "")
3681    (match_operand:VMDI 1 "s_register_operand" "")
3682    (match_operand:<V_elem> 2 "s_register_operand" "")
3683    (match_operand:SI 3 "immediate_operand" "")]
3684   "TARGET_NEON"
3685 {
3686   rtx tmp = gen_reg_rtx (<MODE>mode);
3687   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3688   emit_insn (gen_neon_vmull_lane<mode> (operands[0], operands[1], tmp,
3689                                         const0_rtx, operands[3]));
3690   DONE;
3691 })
3692
3693 (define_expand "neon_vqdmull_n<mode>"
3694   [(match_operand:<V_widen> 0 "s_register_operand" "")
3695    (match_operand:VMDI 1 "s_register_operand" "")
3696    (match_operand:<V_elem> 2 "s_register_operand" "")
3697    (match_operand:SI 3 "immediate_operand" "")]
3698   "TARGET_NEON"
3699 {
3700   rtx tmp = gen_reg_rtx (<MODE>mode);
3701   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3702   emit_insn (gen_neon_vqdmull_lane<mode> (operands[0], operands[1], tmp,
3703                                           const0_rtx, const0_rtx));
3704   DONE;
3705 })
3706
3707 (define_expand "neon_vqdmulh_n<mode>"
3708   [(match_operand:VMDI 0 "s_register_operand" "")
3709    (match_operand:VMDI 1 "s_register_operand" "")
3710    (match_operand:<V_elem> 2 "s_register_operand" "")
3711    (match_operand:SI 3 "immediate_operand" "")]
3712   "TARGET_NEON"
3713 {
3714   rtx tmp = gen_reg_rtx (<MODE>mode);
3715   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
3716   emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3717                                           const0_rtx, operands[3]));
3718   DONE;
3719 })
3720
3721 (define_expand "neon_vqdmulh_n<mode>"
3722   [(match_operand:VMQI 0 "s_register_operand" "")
3723    (match_operand:VMQI 1 "s_register_operand" "")
3724    (match_operand:<V_elem> 2 "s_register_operand" "")
3725    (match_operand:SI 3 "immediate_operand" "")]
3726   "TARGET_NEON"
3727 {
3728   rtx tmp = gen_reg_rtx (<V_HALF>mode);
3729   emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
3730   emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
3731                                           const0_rtx, operands[3]));
3732   DONE;
3733 })
3734
3735 (define_expand "neon_vmla_n<mode>"
3736   [(match_operand:VMD 0 "s_register_operand" "")
3737    (match_operand:VMD 1 "s_register_operand" "")
3738    (match_operand:VMD 2 "s_register_operand" "")
3739    (match_operand:<V_elem> 3 "s_register_operand" "")
3740    (match_operand:SI 4 "immediate_operand" "")]
3741   "TARGET_NEON"
3742 {
3743   rtx tmp = gen_reg_rtx (<MODE>mode);
3744   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3745   emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3746                                        tmp, const0_rtx, operands[4]));
3747   DONE;
3748 })
3749
3750 (define_expand "neon_vmla_n<mode>"
3751   [(match_operand:VMQ 0 "s_register_operand" "")
3752    (match_operand:VMQ 1 "s_register_operand" "")
3753    (match_operand:VMQ 2 "s_register_operand" "")
3754    (match_operand:<V_elem> 3 "s_register_operand" "")
3755    (match_operand:SI 4 "immediate_operand" "")]
3756   "TARGET_NEON"
3757 {
3758   rtx tmp = gen_reg_rtx (<V_HALF>mode);
3759   emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3760   emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
3761                                        tmp, const0_rtx, operands[4]));
3762   DONE;
3763 })
3764
3765 (define_expand "neon_vmlal_n<mode>"
3766   [(match_operand:<V_widen> 0 "s_register_operand" "")
3767    (match_operand:<V_widen> 1 "s_register_operand" "")
3768    (match_operand:VMDI 2 "s_register_operand" "")
3769    (match_operand:<V_elem> 3 "s_register_operand" "")
3770    (match_operand:SI 4 "immediate_operand" "")]
3771   "TARGET_NEON"
3772 {
3773   rtx tmp = gen_reg_rtx (<MODE>mode);
3774   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3775   emit_insn (gen_neon_vmlal_lane<mode> (operands[0], operands[1], operands[2],
3776                                         tmp, const0_rtx, operands[4]));
3777   DONE;
3778 })
3779
3780 (define_expand "neon_vqdmlal_n<mode>"
3781   [(match_operand:<V_widen> 0 "s_register_operand" "")
3782    (match_operand:<V_widen> 1 "s_register_operand" "")
3783    (match_operand:VMDI 2 "s_register_operand" "")
3784    (match_operand:<V_elem> 3 "s_register_operand" "")
3785    (match_operand:SI 4 "immediate_operand" "")]
3786   "TARGET_NEON"
3787 {
3788   rtx tmp = gen_reg_rtx (<MODE>mode);
3789   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3790   emit_insn (gen_neon_vqdmlal_lane<mode> (operands[0], operands[1], operands[2],
3791                                           tmp, const0_rtx, operands[4]));
3792   DONE;
3793 })
3794
3795 (define_expand "neon_vmls_n<mode>"
3796   [(match_operand:VMD 0 "s_register_operand" "")
3797    (match_operand:VMD 1 "s_register_operand" "")
3798    (match_operand:VMD 2 "s_register_operand" "")
3799    (match_operand:<V_elem> 3 "s_register_operand" "")
3800    (match_operand:SI 4 "immediate_operand" "")]
3801   "TARGET_NEON"
3802 {
3803   rtx tmp = gen_reg_rtx (<MODE>mode);
3804   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3805   emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3806                                        tmp, const0_rtx, operands[4]));
3807   DONE;
3808 })
3809
3810 (define_expand "neon_vmls_n<mode>"
3811   [(match_operand:VMQ 0 "s_register_operand" "")
3812    (match_operand:VMQ 1 "s_register_operand" "")
3813    (match_operand:VMQ 2 "s_register_operand" "")
3814    (match_operand:<V_elem> 3 "s_register_operand" "")
3815    (match_operand:SI 4 "immediate_operand" "")]
3816   "TARGET_NEON"
3817 {
3818   rtx tmp = gen_reg_rtx (<V_HALF>mode);
3819   emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
3820   emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
3821                                        tmp, const0_rtx, operands[4]));
3822   DONE;
3823 })
3824
3825 (define_expand "neon_vmlsl_n<mode>"
3826   [(match_operand:<V_widen> 0 "s_register_operand" "")
3827    (match_operand:<V_widen> 1 "s_register_operand" "")
3828    (match_operand:VMDI 2 "s_register_operand" "")
3829    (match_operand:<V_elem> 3 "s_register_operand" "")
3830    (match_operand:SI 4 "immediate_operand" "")]
3831   "TARGET_NEON"
3832 {
3833   rtx tmp = gen_reg_rtx (<MODE>mode);
3834   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3835   emit_insn (gen_neon_vmlsl_lane<mode> (operands[0], operands[1], operands[2],
3836                                         tmp, const0_rtx, operands[4]));
3837   DONE;
3838 })
3839
3840 (define_expand "neon_vqdmlsl_n<mode>"
3841   [(match_operand:<V_widen> 0 "s_register_operand" "")
3842    (match_operand:<V_widen> 1 "s_register_operand" "")
3843    (match_operand:VMDI 2 "s_register_operand" "")
3844    (match_operand:<V_elem> 3 "s_register_operand" "")
3845    (match_operand:SI 4 "immediate_operand" "")]
3846   "TARGET_NEON"
3847 {
3848   rtx tmp = gen_reg_rtx (<MODE>mode);
3849   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
3850   emit_insn (gen_neon_vqdmlsl_lane<mode> (operands[0], operands[1], operands[2],
3851                                           tmp, const0_rtx, operands[4]));
3852   DONE;
3853 })
3854
3855 (define_insn "neon_vext<mode>"
3856   [(set (match_operand:VDQX 0 "s_register_operand" "=w")
3857         (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
3858                       (match_operand:VDQX 2 "s_register_operand" "w")
3859                       (match_operand:SI 3 "immediate_operand" "i")]
3860                      UNSPEC_VEXT))]
3861   "TARGET_NEON"
3862 {
3863   neon_const_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
3864   return "vext.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2, %3";
3865 }
3866   [(set (attr "neon_type")
3867       (if_then_else (match_test "<Is_d_reg>")
3868                     (const_string "neon_bp_simple")
3869                     (const_string "neon_bp_2cycle")))]
3870 )
3871
3872 (define_insn "neon_vrev64<mode>"
3873   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
3874         (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
3875                      (match_operand:SI 2 "immediate_operand" "i")]
3876                     UNSPEC_VREV64))]
3877   "TARGET_NEON"
3878   "vrev64.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3879   [(set_attr "neon_type" "neon_bp_simple")]
3880 )
3881
3882 (define_insn "neon_vrev32<mode>"
3883   [(set (match_operand:VX 0 "s_register_operand" "=w")
3884         (unspec:VX [(match_operand:VX 1 "s_register_operand" "w")
3885                     (match_operand:SI 2 "immediate_operand" "i")]
3886                    UNSPEC_VREV32))]
3887   "TARGET_NEON"
3888   "vrev32.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3889   [(set_attr "neon_type" "neon_bp_simple")]
3890 )
3891
3892 (define_insn "neon_vrev16<mode>"
3893   [(set (match_operand:VE 0 "s_register_operand" "=w")
3894         (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
3895                     (match_operand:SI 2 "immediate_operand" "i")]
3896                    UNSPEC_VREV16))]
3897   "TARGET_NEON"
3898   "vrev16.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
3899   [(set_attr "neon_type" "neon_bp_simple")]
3900 )
3901
3902 ; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
3903 ; allocation. For an intrinsic of form:
3904 ;   rD = vbsl_* (rS, rN, rM)
3905 ; We can use any of:
3906 ;   vbsl rS, rN, rM  (if D = S)
3907 ;   vbit rD, rN, rS  (if D = M, so 1-bits in rS choose bits from rN, else rM)
3908 ;   vbif rD, rM, rS  (if D = N, so 0-bits in rS choose bits from rM, else rN)
3909
3910 (define_insn "neon_vbsl<mode>_internal"
3911   [(set (match_operand:VDQX 0 "s_register_operand"               "=w,w,w")
3912         (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" " 0,w,w")
3913                       (match_operand:VDQX 2 "s_register_operand" " w,w,0")
3914                       (match_operand:VDQX 3 "s_register_operand" " w,0,w")]
3915                      UNSPEC_VBSL))]
3916   "TARGET_NEON"
3917   "@
3918   vbsl\t%<V_reg>0, %<V_reg>2, %<V_reg>3
3919   vbit\t%<V_reg>0, %<V_reg>2, %<V_reg>1
3920   vbif\t%<V_reg>0, %<V_reg>3, %<V_reg>1"
3921   [(set_attr "neon_type" "neon_int_1")]
3922 )
3923
3924 (define_expand "neon_vbsl<mode>"
3925   [(set (match_operand:VDQX 0 "s_register_operand" "")
3926         (unspec:VDQX [(match_operand:<V_cmp_result> 1 "s_register_operand" "")
3927                       (match_operand:VDQX 2 "s_register_operand" "")
3928                       (match_operand:VDQX 3 "s_register_operand" "")]
3929                      UNSPEC_VBSL))]
3930   "TARGET_NEON"
3931 {
3932   /* We can't alias operands together if they have different modes.  */
3933   operands[1] = gen_lowpart (<MODE>mode, operands[1]);
3934 })
3935
3936 (define_insn "neon_vshl<mode>"
3937   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3938         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3939                        (match_operand:VDQIX 2 "s_register_operand" "w")
3940                        (match_operand:SI 3 "immediate_operand" "i")]
3941                       UNSPEC_VSHL))]
3942   "TARGET_NEON"
3943   "v%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3944   [(set (attr "neon_type")
3945       (if_then_else (match_test "<Is_d_reg>")
3946                     (const_string "neon_vshl_ddd")
3947                     (const_string "neon_shift_3")))]
3948 )
3949
3950 (define_insn "neon_vqshl<mode>"
3951   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3952         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3953                        (match_operand:VDQIX 2 "s_register_operand" "w")
3954                        (match_operand:SI 3 "immediate_operand" "i")]
3955                       UNSPEC_VQSHL))]
3956   "TARGET_NEON"
3957   "vq%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
3958   [(set (attr "neon_type")
3959       (if_then_else (match_test "<Is_d_reg>")
3960                     (const_string "neon_shift_2")
3961                     (const_string "neon_vqshl_vrshl_vqrshl_qqq")))]
3962 )
3963
3964 (define_insn "neon_vshr_n<mode>"
3965   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3966         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3967                        (match_operand:SI 2 "immediate_operand" "i")
3968                        (match_operand:SI 3 "immediate_operand" "i")]
3969                       UNSPEC_VSHR_N))]
3970   "TARGET_NEON"
3971 {
3972   neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) + 1);
3973   return "v%O3shr.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
3974 }
3975   [(set_attr "neon_type" "neon_shift_1")]
3976 )
3977
3978 (define_insn "neon_vshrn_n<mode>"
3979   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3980         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3981                             (match_operand:SI 2 "immediate_operand" "i")
3982                             (match_operand:SI 3 "immediate_operand" "i")]
3983                            UNSPEC_VSHRN_N))]
3984   "TARGET_NEON"
3985 {
3986   neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
3987   return "v%O3shrn.<V_if_elem>\t%P0, %q1, %2";
3988 }
3989   [(set_attr "neon_type" "neon_shift_1")]
3990 )
3991
3992 (define_insn "neon_vqshrn_n<mode>"
3993   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
3994         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
3995                             (match_operand:SI 2 "immediate_operand" "i")
3996                             (match_operand:SI 3 "immediate_operand" "i")]
3997                            UNSPEC_VQSHRN_N))]
3998   "TARGET_NEON"
3999 {
4000   neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
4001   return "vq%O3shrn.%T3%#<V_sz_elem>\t%P0, %q1, %2";
4002 }
4003   [(set_attr "neon_type" "neon_shift_2")]
4004 )
4005
4006 (define_insn "neon_vqshrun_n<mode>"
4007   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
4008         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
4009                             (match_operand:SI 2 "immediate_operand" "i")
4010                             (match_operand:SI 3 "immediate_operand" "i")]
4011                            UNSPEC_VQSHRUN_N))]
4012   "TARGET_NEON"
4013 {
4014   neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
4015   return "vq%O3shrun.%T3%#<V_sz_elem>\t%P0, %q1, %2";
4016 }
4017   [(set_attr "neon_type" "neon_shift_2")]
4018 )
4019
4020 (define_insn "neon_vshl_n<mode>"
4021   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4022         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
4023                        (match_operand:SI 2 "immediate_operand" "i")
4024                        (match_operand:SI 3 "immediate_operand" "i")]
4025                       UNSPEC_VSHL_N))]
4026   "TARGET_NEON"
4027 {
4028   neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
4029   return "vshl.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %2";
4030 }
4031   [(set_attr "neon_type" "neon_shift_1")]
4032 )
4033
4034 (define_insn "neon_vqshl_n<mode>"
4035   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4036         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
4037                        (match_operand:SI 2 "immediate_operand" "i")
4038                        (match_operand:SI 3 "immediate_operand" "i")]
4039                       UNSPEC_VQSHL_N))]
4040   "TARGET_NEON"
4041 {
4042   neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
4043   return "vqshl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
4044 }
4045   [(set_attr "neon_type" "neon_shift_2")]
4046 )
4047
4048 (define_insn "neon_vqshlu_n<mode>"
4049   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4050         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
4051                        (match_operand:SI 2 "immediate_operand" "i")
4052                        (match_operand:SI 3 "immediate_operand" "i")]
4053                       UNSPEC_VQSHLU_N))]
4054   "TARGET_NEON"
4055 {
4056   neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
4057   return "vqshlu.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
4058 }
4059   [(set_attr "neon_type" "neon_shift_2")]
4060 )
4061
4062 (define_insn "neon_vshll_n<mode>"
4063   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
4064         (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
4065                            (match_operand:SI 2 "immediate_operand" "i")
4066                            (match_operand:SI 3 "immediate_operand" "i")]
4067                           UNSPEC_VSHLL_N))]
4068   "TARGET_NEON"
4069 {
4070   /* The boundaries are: 0 < imm <= size.  */
4071   neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode) + 1);
4072   return "vshll.%T3%#<V_sz_elem>\t%q0, %P1, %2";
4073 }
4074   [(set_attr "neon_type" "neon_shift_1")]
4075 )
4076
4077 (define_insn "neon_vsra_n<mode>"
4078   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4079         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
4080                        (match_operand:VDQIX 2 "s_register_operand" "w")
4081                        (match_operand:SI 3 "immediate_operand" "i")
4082                        (match_operand:SI 4 "immediate_operand" "i")]
4083                       UNSPEC_VSRA_N))]
4084   "TARGET_NEON"
4085 {
4086   neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
4087   return "v%O4sra.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
4088 }
4089   [(set_attr "neon_type" "neon_vsra_vrsra")]
4090 )
4091
4092 (define_insn "neon_vsri_n<mode>"
4093   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4094         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
4095                        (match_operand:VDQIX 2 "s_register_operand" "w")
4096                        (match_operand:SI 3 "immediate_operand" "i")]
4097                       UNSPEC_VSRI))]
4098   "TARGET_NEON"
4099 {
4100   neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
4101   return "vsri.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
4102 }
4103   [(set (attr "neon_type")
4104       (if_then_else (match_test "<Is_d_reg>")
4105                     (const_string "neon_shift_1")
4106                     (const_string "neon_shift_3")))]
4107 )
4108
4109 (define_insn "neon_vsli_n<mode>"
4110   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
4111         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
4112                        (match_operand:VDQIX 2 "s_register_operand" "w")
4113                        (match_operand:SI 3 "immediate_operand" "i")]
4114                       UNSPEC_VSLI))]
4115   "TARGET_NEON"
4116 {
4117   neon_const_bounds (operands[3], 0, neon_element_bits (<MODE>mode));
4118   return "vsli.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
4119 }
4120   [(set (attr "neon_type")
4121       (if_then_else (match_test "<Is_d_reg>")
4122                     (const_string "neon_shift_1")
4123                     (const_string "neon_shift_3")))]
4124 )
4125
4126 (define_insn "neon_vtbl1v8qi"
4127   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4128         (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "w")
4129                       (match_operand:V8QI 2 "s_register_operand" "w")]
4130                      UNSPEC_VTBL))]
4131   "TARGET_NEON"
4132   "vtbl.8\t%P0, {%P1}, %P2"
4133   [(set_attr "neon_type" "neon_bp_2cycle")]
4134 )
4135
4136 (define_insn "neon_vtbl2v8qi"
4137   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4138         (unspec:V8QI [(match_operand:TI 1 "s_register_operand" "w")
4139                       (match_operand:V8QI 2 "s_register_operand" "w")]
4140                      UNSPEC_VTBL))]
4141   "TARGET_NEON"
4142 {
4143   rtx ops[4];
4144   int tabbase = REGNO (operands[1]);
4145
4146   ops[0] = operands[0];
4147   ops[1] = gen_rtx_REG (V8QImode, tabbase);
4148   ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4149   ops[3] = operands[2];
4150   output_asm_insn ("vtbl.8\t%P0, {%P1, %P2}, %P3", ops);
4151
4152   return "";
4153 }
4154   [(set_attr "neon_type" "neon_bp_2cycle")]
4155 )
4156
4157 (define_insn "neon_vtbl3v8qi"
4158   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4159         (unspec:V8QI [(match_operand:EI 1 "s_register_operand" "w")
4160                       (match_operand:V8QI 2 "s_register_operand" "w")]
4161                      UNSPEC_VTBL))]
4162   "TARGET_NEON"
4163 {
4164   rtx ops[5];
4165   int tabbase = REGNO (operands[1]);
4166
4167   ops[0] = operands[0];
4168   ops[1] = gen_rtx_REG (V8QImode, tabbase);
4169   ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4170   ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4171   ops[4] = operands[2];
4172   output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
4173
4174   return "";
4175 }
4176   [(set_attr "neon_type" "neon_bp_3cycle")]
4177 )
4178
4179 (define_insn "neon_vtbl4v8qi"
4180   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4181         (unspec:V8QI [(match_operand:OI 1 "s_register_operand" "w")
4182                       (match_operand:V8QI 2 "s_register_operand" "w")]
4183                      UNSPEC_VTBL))]
4184   "TARGET_NEON"
4185 {
4186   rtx ops[6];
4187   int tabbase = REGNO (operands[1]);
4188
4189   ops[0] = operands[0];
4190   ops[1] = gen_rtx_REG (V8QImode, tabbase);
4191   ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4192   ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4193   ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
4194   ops[5] = operands[2];
4195   output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
4196
4197   return "";
4198 }
4199   [(set_attr "neon_type" "neon_bp_3cycle")]
4200 )
4201
4202 ;; These three are used by the vec_perm infrastructure for V16QImode.
4203 (define_insn_and_split "neon_vtbl1v16qi"
4204   [(set (match_operand:V16QI 0 "s_register_operand" "=&w")
4205         (unspec:V16QI [(match_operand:V16QI 1 "s_register_operand" "w")
4206                        (match_operand:V16QI 2 "s_register_operand" "w")]
4207                       UNSPEC_VTBL))]
4208   "TARGET_NEON"
4209   "#"
4210   "&& reload_completed"
4211   [(const_int 0)]
4212 {
4213   rtx op0, op1, op2, part0, part2;
4214   unsigned ofs;
4215
4216   op0 = operands[0];
4217   op1 = gen_lowpart (TImode, operands[1]);
4218   op2 = operands[2];
4219
4220   ofs = subreg_lowpart_offset (V8QImode, V16QImode);
4221   part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4222   part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4223   emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4224
4225   ofs = subreg_highpart_offset (V8QImode, V16QImode);
4226   part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4227   part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4228   emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4229   DONE;
4230 })
4231
4232 (define_insn_and_split "neon_vtbl2v16qi"
4233   [(set (match_operand:V16QI 0 "s_register_operand" "=&w")
4234         (unspec:V16QI [(match_operand:OI 1 "s_register_operand" "w")
4235                        (match_operand:V16QI 2 "s_register_operand" "w")]
4236                       UNSPEC_VTBL))]
4237   "TARGET_NEON"
4238   "#"
4239   "&& reload_completed"
4240   [(const_int 0)]
4241 {
4242   rtx op0, op1, op2, part0, part2;
4243   unsigned ofs;
4244
4245   op0 = operands[0];
4246   op1 = operands[1];
4247   op2 = operands[2];
4248
4249   ofs = subreg_lowpart_offset (V8QImode, V16QImode);
4250   part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4251   part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4252   emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4253
4254   ofs = subreg_highpart_offset (V8QImode, V16QImode);
4255   part0 = simplify_subreg (V8QImode, op0, V16QImode, ofs);
4256   part2 = simplify_subreg (V8QImode, op2, V16QImode, ofs);
4257   emit_insn (gen_neon_vtbl2v8qi (part0, op1, part2));
4258   DONE;
4259 })
4260
4261 ;; ??? Logically we should extend the regular neon_vcombine pattern to
4262 ;; handle quad-word input modes, producing octa-word output modes.  But
4263 ;; that requires us to add support for octa-word vector modes in moves.
4264 ;; That seems overkill for this one use in vec_perm.
4265 (define_insn_and_split "neon_vcombinev16qi"
4266   [(set (match_operand:OI 0 "s_register_operand" "=w")
4267         (unspec:OI [(match_operand:V16QI 1 "s_register_operand" "w")
4268                     (match_operand:V16QI 2 "s_register_operand" "w")]
4269                    UNSPEC_VCONCAT))]
4270   "TARGET_NEON"
4271   "#"
4272   "&& reload_completed"
4273   [(const_int 0)]
4274 {
4275   neon_split_vcombine (operands);
4276   DONE;
4277 })
4278
4279 (define_insn "neon_vtbx1v8qi"
4280   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4281         (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4282                       (match_operand:V8QI 2 "s_register_operand" "w")
4283                       (match_operand:V8QI 3 "s_register_operand" "w")]
4284                      UNSPEC_VTBX))]
4285   "TARGET_NEON"
4286   "vtbx.8\t%P0, {%P2}, %P3"
4287   [(set_attr "neon_type" "neon_bp_2cycle")]
4288 )
4289
4290 (define_insn "neon_vtbx2v8qi"
4291   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4292         (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4293                       (match_operand:TI 2 "s_register_operand" "w")
4294                       (match_operand:V8QI 3 "s_register_operand" "w")]
4295                      UNSPEC_VTBX))]
4296   "TARGET_NEON"
4297 {
4298   rtx ops[4];
4299   int tabbase = REGNO (operands[2]);
4300
4301   ops[0] = operands[0];
4302   ops[1] = gen_rtx_REG (V8QImode, tabbase);
4303   ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4304   ops[3] = operands[3];
4305   output_asm_insn ("vtbx.8\t%P0, {%P1, %P2}, %P3", ops);
4306
4307   return "";
4308 }
4309   [(set_attr "neon_type" "neon_bp_2cycle")]
4310 )
4311
4312 (define_insn "neon_vtbx3v8qi"
4313   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4314         (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4315                       (match_operand:EI 2 "s_register_operand" "w")
4316                       (match_operand:V8QI 3 "s_register_operand" "w")]
4317                      UNSPEC_VTBX))]
4318   "TARGET_NEON"
4319 {
4320   rtx ops[5];
4321   int tabbase = REGNO (operands[2]);
4322
4323   ops[0] = operands[0];
4324   ops[1] = gen_rtx_REG (V8QImode, tabbase);
4325   ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4326   ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4327   ops[4] = operands[3];
4328   output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
4329
4330   return "";
4331 }
4332   [(set_attr "neon_type" "neon_bp_3cycle")]
4333 )
4334
4335 (define_insn "neon_vtbx4v8qi"
4336   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
4337         (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
4338                       (match_operand:OI 2 "s_register_operand" "w")
4339                       (match_operand:V8QI 3 "s_register_operand" "w")]
4340                      UNSPEC_VTBX))]
4341   "TARGET_NEON"
4342 {
4343   rtx ops[6];
4344   int tabbase = REGNO (operands[2]);
4345
4346   ops[0] = operands[0];
4347   ops[1] = gen_rtx_REG (V8QImode, tabbase);
4348   ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
4349   ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
4350   ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
4351   ops[5] = operands[3];
4352   output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
4353
4354   return "";
4355 }
4356   [(set_attr "neon_type" "neon_bp_3cycle")]
4357 )
4358
4359 (define_expand "neon_vtrn<mode>_internal"
4360   [(parallel
4361     [(set (match_operand:VDQW 0 "s_register_operand" "")
4362           (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "")
4363                         (match_operand:VDQW 2 "s_register_operand" "")]
4364            UNSPEC_VTRN1))
4365      (set (match_operand:VDQW 3 "s_register_operand" "")
4366           (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VTRN2))])]
4367   "TARGET_NEON"
4368   ""
4369 )
4370
4371 ;; Note: Different operand numbering to handle tied registers correctly.
4372 (define_insn "*neon_vtrn<mode>_insn"
4373   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4374         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
4375                       (match_operand:VDQW 3 "s_register_operand" "2")]
4376                      UNSPEC_VTRN1))
4377    (set (match_operand:VDQW 2 "s_register_operand" "=w")
4378          (unspec:VDQW [(match_dup 1) (match_dup 3)]
4379                      UNSPEC_VTRN2))]
4380   "TARGET_NEON"
4381   "vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4382   [(set (attr "neon_type")
4383       (if_then_else (match_test "<Is_d_reg>")
4384                     (const_string "neon_bp_simple")
4385                     (const_string "neon_bp_3cycle")))]
4386 )
4387
4388 (define_expand "neon_vtrn<mode>"
4389   [(match_operand:SI 0 "s_register_operand" "r")
4390    (match_operand:VDQW 1 "s_register_operand" "w")
4391    (match_operand:VDQW 2 "s_register_operand" "w")]
4392   "TARGET_NEON"
4393 {
4394   neon_emit_pair_result_insn (<MODE>mode, gen_neon_vtrn<mode>_internal,
4395                               operands[0], operands[1], operands[2]);
4396   DONE;
4397 })
4398
4399 (define_expand "neon_vzip<mode>_internal"
4400   [(parallel
4401     [(set (match_operand:VDQW 0 "s_register_operand" "")
4402           (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "")
4403                         (match_operand:VDQW 2 "s_register_operand" "")]
4404                        UNSPEC_VZIP1))
4405     (set (match_operand:VDQW 3 "s_register_operand" "")
4406          (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VZIP2))])]
4407   "TARGET_NEON"
4408   ""
4409 )
4410
4411 ;; Note: Different operand numbering to handle tied registers correctly.
4412 (define_insn "*neon_vzip<mode>_insn"
4413   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4414         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
4415                       (match_operand:VDQW 3 "s_register_operand" "2")]
4416                      UNSPEC_VZIP1))
4417    (set (match_operand:VDQW 2 "s_register_operand" "=w")
4418         (unspec:VDQW [(match_dup 1) (match_dup 3)]
4419                      UNSPEC_VZIP2))]
4420   "TARGET_NEON"
4421   "vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4422   [(set (attr "neon_type")
4423       (if_then_else (match_test "<Is_d_reg>")
4424                     (const_string "neon_bp_simple")
4425                     (const_string "neon_bp_3cycle")))]
4426 )
4427
4428 (define_expand "neon_vzip<mode>"
4429   [(match_operand:SI 0 "s_register_operand" "r")
4430    (match_operand:VDQW 1 "s_register_operand" "w")
4431    (match_operand:VDQW 2 "s_register_operand" "w")]
4432   "TARGET_NEON"
4433 {
4434   neon_emit_pair_result_insn (<MODE>mode, gen_neon_vzip<mode>_internal,
4435                               operands[0], operands[1], operands[2]);
4436   DONE;
4437 })
4438
4439 (define_expand "neon_vuzp<mode>_internal"
4440   [(parallel
4441     [(set (match_operand:VDQW 0 "s_register_operand" "")
4442           (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "")
4443                         (match_operand:VDQW 2 "s_register_operand" "")]
4444            UNSPEC_VUZP1))
4445      (set (match_operand:VDQW 3 "s_register_operand" "")
4446           (unspec:VDQW [(match_dup 1) (match_dup 2)] UNSPEC_VUZP2))])]
4447   "TARGET_NEON"
4448   ""
4449 )
4450
4451 ;; Note: Different operand numbering to handle tied registers correctly.
4452 (define_insn "*neon_vuzp<mode>_insn"
4453   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
4454         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
4455                       (match_operand:VDQW 3 "s_register_operand" "2")]
4456                      UNSPEC_VUZP1))
4457    (set (match_operand:VDQW 2 "s_register_operand" "=w")
4458         (unspec:VDQW [(match_dup 1) (match_dup 3)]
4459                      UNSPEC_VUZP2))]
4460   "TARGET_NEON"
4461   "vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
4462   [(set (attr "neon_type")
4463       (if_then_else (match_test "<Is_d_reg>")
4464                     (const_string "neon_bp_simple")
4465                     (const_string "neon_bp_3cycle")))]
4466 )
4467
4468 (define_expand "neon_vuzp<mode>"
4469   [(match_operand:SI 0 "s_register_operand" "r")
4470    (match_operand:VDQW 1 "s_register_operand" "w")
4471    (match_operand:VDQW 2 "s_register_operand" "w")]
4472   "TARGET_NEON"
4473 {
4474   neon_emit_pair_result_insn (<MODE>mode, gen_neon_vuzp<mode>_internal,
4475                               operands[0], operands[1], operands[2]);
4476   DONE;
4477 })
4478
4479 (define_expand "neon_vreinterpretv8qi<mode>"
4480   [(match_operand:V8QI 0 "s_register_operand" "")
4481    (match_operand:VDX 1 "s_register_operand" "")]
4482   "TARGET_NEON"
4483 {
4484   neon_reinterpret (operands[0], operands[1]);
4485   DONE;
4486 })
4487
4488 (define_expand "neon_vreinterpretv4hi<mode>"
4489   [(match_operand:V4HI 0 "s_register_operand" "")
4490    (match_operand:VDX 1 "s_register_operand" "")]
4491   "TARGET_NEON"
4492 {
4493   neon_reinterpret (operands[0], operands[1]);
4494   DONE;
4495 })
4496
4497 (define_expand "neon_vreinterpretv2si<mode>"
4498   [(match_operand:V2SI 0 "s_register_operand" "")
4499    (match_operand:VDX 1 "s_register_operand" "")]
4500   "TARGET_NEON"
4501 {
4502   neon_reinterpret (operands[0], operands[1]);
4503   DONE;
4504 })
4505
4506 (define_expand "neon_vreinterpretv2sf<mode>"
4507   [(match_operand:V2SF 0 "s_register_operand" "")
4508    (match_operand:VDX 1 "s_register_operand" "")]
4509   "TARGET_NEON"
4510 {
4511   neon_reinterpret (operands[0], operands[1]);
4512   DONE;
4513 })
4514
4515 (define_expand "neon_vreinterpretdi<mode>"
4516   [(match_operand:DI 0 "s_register_operand" "")
4517    (match_operand:VDX 1 "s_register_operand" "")]
4518   "TARGET_NEON"
4519 {
4520   neon_reinterpret (operands[0], operands[1]);
4521   DONE;
4522 })
4523
4524 (define_expand "neon_vreinterpretv16qi<mode>"
4525   [(match_operand:V16QI 0 "s_register_operand" "")
4526    (match_operand:VQX 1 "s_register_operand" "")]
4527   "TARGET_NEON"
4528 {
4529   neon_reinterpret (operands[0], operands[1]);
4530   DONE;
4531 })
4532
4533 (define_expand "neon_vreinterpretv8hi<mode>"
4534   [(match_operand:V8HI 0 "s_register_operand" "")
4535    (match_operand:VQX 1 "s_register_operand" "")]
4536   "TARGET_NEON"
4537 {
4538   neon_reinterpret (operands[0], operands[1]);
4539   DONE;
4540 })
4541
4542 (define_expand "neon_vreinterpretv4si<mode>"
4543   [(match_operand:V4SI 0 "s_register_operand" "")
4544    (match_operand:VQX 1 "s_register_operand" "")]
4545   "TARGET_NEON"
4546 {
4547   neon_reinterpret (operands[0], operands[1]);
4548   DONE;
4549 })
4550
4551 (define_expand "neon_vreinterpretv4sf<mode>"
4552   [(match_operand:V4SF 0 "s_register_operand" "")
4553    (match_operand:VQX 1 "s_register_operand" "")]
4554   "TARGET_NEON"
4555 {
4556   neon_reinterpret (operands[0], operands[1]);
4557   DONE;
4558 })
4559
4560 (define_expand "neon_vreinterpretv2di<mode>"
4561   [(match_operand:V2DI 0 "s_register_operand" "")
4562    (match_operand:VQX 1 "s_register_operand" "")]
4563   "TARGET_NEON"
4564 {
4565   neon_reinterpret (operands[0], operands[1]);
4566   DONE;
4567 })
4568
4569 (define_expand "vec_load_lanes<mode><mode>"
4570   [(set (match_operand:VDQX 0 "s_register_operand")
4571         (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_operand")]
4572                      UNSPEC_VLD1))]
4573   "TARGET_NEON")
4574
4575 (define_insn "neon_vld1<mode>"
4576   [(set (match_operand:VDQX 0 "s_register_operand" "=w")
4577         (unspec:VDQX [(match_operand:VDQX 1 "neon_struct_operand" "Um")]
4578                     UNSPEC_VLD1))]
4579   "TARGET_NEON"
4580   "vld1.<V_sz_elem>\t%h0, %A1"
4581   [(set_attr "neon_type" "neon_vld1_1_2_regs")]
4582 )
4583
4584 (define_insn "neon_vld1_lane<mode>"
4585   [(set (match_operand:VDX 0 "s_register_operand" "=w")
4586         (unspec:VDX [(match_operand:<V_elem> 1 "neon_struct_operand" "Um")
4587                      (match_operand:VDX 2 "s_register_operand" "0")
4588                      (match_operand:SI 3 "immediate_operand" "i")]
4589                     UNSPEC_VLD1_LANE))]
4590   "TARGET_NEON"
4591 {
4592   HOST_WIDE_INT lane = INTVAL (operands[3]);
4593   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4594   if (lane < 0 || lane >= max)
4595     error ("lane out of range");
4596   if (max == 1)
4597     return "vld1.<V_sz_elem>\t%P0, %A1";
4598   else
4599     return "vld1.<V_sz_elem>\t{%P0[%c3]}, %A1";
4600 }
4601   [(set (attr "neon_type")
4602       (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4603                     (const_string "neon_vld1_1_2_regs")
4604                     (const_string "neon_vld1_vld2_lane")))]
4605 )
4606
4607 (define_insn "neon_vld1_lane<mode>"
4608   [(set (match_operand:VQX 0 "s_register_operand" "=w")
4609         (unspec:VQX [(match_operand:<V_elem> 1 "neon_struct_operand" "Um")
4610                      (match_operand:VQX 2 "s_register_operand" "0")
4611                      (match_operand:SI 3 "immediate_operand" "i")]
4612                     UNSPEC_VLD1_LANE))]
4613   "TARGET_NEON"
4614 {
4615   HOST_WIDE_INT lane = INTVAL (operands[3]);
4616   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4617   int regno = REGNO (operands[0]);
4618   if (lane < 0 || lane >= max)
4619     error ("lane out of range");
4620   else if (lane >= max / 2)
4621     {
4622       lane -= max / 2;
4623       regno += 2;
4624       operands[3] = GEN_INT (lane);
4625     }
4626   operands[0] = gen_rtx_REG (<V_HALF>mode, regno);
4627   if (max == 2)
4628     return "vld1.<V_sz_elem>\t%P0, %A1";
4629   else
4630     return "vld1.<V_sz_elem>\t{%P0[%c3]}, %A1";
4631 }
4632   [(set (attr "neon_type")
4633       (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
4634                     (const_string "neon_vld1_1_2_regs")
4635                     (const_string "neon_vld1_vld2_lane")))]
4636 )
4637
4638 (define_insn "neon_vld1_dup<mode>"
4639   [(set (match_operand:VDX 0 "s_register_operand" "=w")
4640         (vec_duplicate:VDX (match_operand:<V_elem> 1 "neon_struct_operand" "Um")))]
4641   "TARGET_NEON"
4642 {
4643   if (GET_MODE_NUNITS (<MODE>mode) > 1)
4644     return "vld1.<V_sz_elem>\t{%P0[]}, %A1";
4645   else
4646     return "vld1.<V_sz_elem>\t%h0, %A1";
4647 }
4648   [(set (attr "neon_type")
4649       (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4650                     (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4651                     (const_string "neon_vld1_1_2_regs")))]
4652 )
4653
4654 (define_insn "neon_vld1_dup<mode>"
4655   [(set (match_operand:VQ 0 "s_register_operand" "=w")
4656         (vec_duplicate:VQ (match_operand:<V_elem> 1 "neon_struct_operand" "Um")))]
4657   "TARGET_NEON"
4658 {
4659   return "vld1.<V_sz_elem>\t{%e0[], %f0[]}, %A1";
4660 }
4661   [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
4662 )
4663
4664 (define_insn_and_split "neon_vld1_dupv2di"
4665    [(set (match_operand:V2DI 0 "s_register_operand" "=w")
4666     (vec_duplicate:V2DI (match_operand:DI 1 "neon_struct_operand" "Um")))]
4667    "TARGET_NEON"
4668    "#"
4669    "&& reload_completed"
4670    [(const_int 0)]
4671    {
4672     rtx tmprtx = gen_lowpart (DImode, operands[0]);
4673     emit_insn (gen_neon_vld1_dupdi (tmprtx, operands[1]));
4674     emit_move_insn (gen_highpart (DImode, operands[0]), tmprtx );
4675     DONE;
4676     }
4677   [(set_attr "length" "8")
4678    (set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
4679 )
4680
4681 (define_expand "vec_store_lanes<mode><mode>"
4682   [(set (match_operand:VDQX 0 "neon_struct_operand")
4683         (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand")]
4684                      UNSPEC_VST1))]
4685   "TARGET_NEON")
4686
4687 (define_insn "neon_vst1<mode>"
4688   [(set (match_operand:VDQX 0 "neon_struct_operand" "=Um")
4689         (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")]
4690                      UNSPEC_VST1))]
4691   "TARGET_NEON"
4692   "vst1.<V_sz_elem>\t%h1, %A0"
4693   [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
4694
4695 (define_insn "neon_vst1_lane<mode>"
4696   [(set (match_operand:<V_elem> 0 "neon_struct_operand" "=Um")
4697         (unspec:<V_elem>
4698           [(match_operand:VDX 1 "s_register_operand" "w")
4699            (match_operand:SI 2 "immediate_operand" "i")]
4700           UNSPEC_VST1_LANE))]
4701   "TARGET_NEON"
4702 {
4703   HOST_WIDE_INT lane = INTVAL (operands[2]);
4704   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4705   if (lane < 0 || lane >= max)
4706     error ("lane out of range");
4707   if (max == 1)
4708     return "vst1.<V_sz_elem>\t{%P1}, %A0";
4709   else
4710     return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
4711 }
4712   [(set (attr "neon_type")
4713       (if_then_else (eq (const_string "<V_mode_nunits>") (const_int 1))
4714                     (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4715                     (const_string "neon_vst1_vst2_lane")))])
4716
4717 (define_insn "neon_vst1_lane<mode>"
4718   [(set (match_operand:<V_elem> 0 "neon_struct_operand" "=Um")
4719         (unspec:<V_elem>
4720           [(match_operand:VQX 1 "s_register_operand" "w")
4721            (match_operand:SI 2 "immediate_operand" "i")]
4722           UNSPEC_VST1_LANE))]
4723   "TARGET_NEON"
4724 {
4725   HOST_WIDE_INT lane = INTVAL (operands[2]);
4726   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4727   int regno = REGNO (operands[1]);
4728   if (lane < 0 || lane >= max)
4729     error ("lane out of range");
4730   else if (lane >= max / 2)
4731     {
4732       lane -= max / 2;
4733       regno += 2;
4734       operands[2] = GEN_INT (lane);
4735     }
4736   operands[1] = gen_rtx_REG (<V_HALF>mode, regno);
4737   if (max == 2)
4738     return "vst1.<V_sz_elem>\t{%P1}, %A0";
4739   else
4740     return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
4741 }
4742   [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4743 )
4744
4745 (define_expand "vec_load_lanesti<mode>"
4746   [(set (match_operand:TI 0 "s_register_operand")
4747         (unspec:TI [(match_operand:TI 1 "neon_struct_operand")
4748                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4749                    UNSPEC_VLD2))]
4750   "TARGET_NEON")
4751
4752 (define_insn "neon_vld2<mode>"
4753   [(set (match_operand:TI 0 "s_register_operand" "=w")
4754         (unspec:TI [(match_operand:TI 1 "neon_struct_operand" "Um")
4755                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4756                    UNSPEC_VLD2))]
4757   "TARGET_NEON"
4758 {
4759   if (<V_sz_elem> == 64)
4760     return "vld1.64\t%h0, %A1";
4761   else
4762     return "vld2.<V_sz_elem>\t%h0, %A1";
4763 }
4764   [(set (attr "neon_type")
4765       (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4766                     (const_string "neon_vld1_1_2_regs")
4767                     (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")))]
4768 )
4769
4770 (define_expand "vec_load_lanesoi<mode>"
4771   [(set (match_operand:OI 0 "s_register_operand")
4772         (unspec:OI [(match_operand:OI 1 "neon_struct_operand")
4773                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4774                    UNSPEC_VLD2))]
4775   "TARGET_NEON")
4776
4777 (define_insn "neon_vld2<mode>"
4778   [(set (match_operand:OI 0 "s_register_operand" "=w")
4779         (unspec:OI [(match_operand:OI 1 "neon_struct_operand" "Um")
4780                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4781                    UNSPEC_VLD2))]
4782   "TARGET_NEON"
4783   "vld2.<V_sz_elem>\t%h0, %A1"
4784   [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")])
4785
4786 (define_insn "neon_vld2_lane<mode>"
4787   [(set (match_operand:TI 0 "s_register_operand" "=w")
4788         (unspec:TI [(match_operand:<V_two_elem> 1 "neon_struct_operand" "Um")
4789                     (match_operand:TI 2 "s_register_operand" "0")
4790                     (match_operand:SI 3 "immediate_operand" "i")
4791                     (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4792                    UNSPEC_VLD2_LANE))]
4793   "TARGET_NEON"
4794 {
4795   HOST_WIDE_INT lane = INTVAL (operands[3]);
4796   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4797   int regno = REGNO (operands[0]);
4798   rtx ops[4];
4799   if (lane < 0 || lane >= max)
4800     error ("lane out of range");
4801   ops[0] = gen_rtx_REG (DImode, regno);
4802   ops[1] = gen_rtx_REG (DImode, regno + 2);
4803   ops[2] = operands[1];
4804   ops[3] = operands[3];
4805   output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, %A2", ops);
4806   return "";
4807 }
4808   [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4809 )
4810
4811 (define_insn "neon_vld2_lane<mode>"
4812   [(set (match_operand:OI 0 "s_register_operand" "=w")
4813         (unspec:OI [(match_operand:<V_two_elem> 1 "neon_struct_operand" "Um")
4814                     (match_operand:OI 2 "s_register_operand" "0")
4815                     (match_operand:SI 3 "immediate_operand" "i")
4816                     (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4817                    UNSPEC_VLD2_LANE))]
4818   "TARGET_NEON"
4819 {
4820   HOST_WIDE_INT lane = INTVAL (operands[3]);
4821   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4822   int regno = REGNO (operands[0]);
4823   rtx ops[4];
4824   if (lane < 0 || lane >= max)
4825     error ("lane out of range");
4826   else if (lane >= max / 2)
4827     {
4828       lane -= max / 2;
4829       regno += 2;
4830     }
4831   ops[0] = gen_rtx_REG (DImode, regno);
4832   ops[1] = gen_rtx_REG (DImode, regno + 4);
4833   ops[2] = operands[1];
4834   ops[3] = GEN_INT (lane);
4835   output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, %A2", ops);
4836   return "";
4837 }
4838   [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4839 )
4840
4841 (define_insn "neon_vld2_dup<mode>"
4842   [(set (match_operand:TI 0 "s_register_operand" "=w")
4843         (unspec:TI [(match_operand:<V_two_elem> 1 "neon_struct_operand" "Um")
4844                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4845                    UNSPEC_VLD2_DUP))]
4846   "TARGET_NEON"
4847 {
4848   if (GET_MODE_NUNITS (<MODE>mode) > 1)
4849     return "vld2.<V_sz_elem>\t{%e0[], %f0[]}, %A1";
4850   else
4851     return "vld1.<V_sz_elem>\t%h0, %A1";
4852 }
4853   [(set (attr "neon_type")
4854       (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
4855                     (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4856                     (const_string "neon_vld1_1_2_regs")))]
4857 )
4858
4859 (define_expand "vec_store_lanesti<mode>"
4860   [(set (match_operand:TI 0 "neon_struct_operand")
4861         (unspec:TI [(match_operand:TI 1 "s_register_operand")
4862                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4863                    UNSPEC_VST2))]
4864   "TARGET_NEON")
4865
4866 (define_insn "neon_vst2<mode>"
4867   [(set (match_operand:TI 0 "neon_struct_operand" "=Um")
4868         (unspec:TI [(match_operand:TI 1 "s_register_operand" "w")
4869                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4870                    UNSPEC_VST2))]
4871   "TARGET_NEON"
4872 {
4873   if (<V_sz_elem> == 64)
4874     return "vst1.64\t%h1, %A0";
4875   else
4876     return "vst2.<V_sz_elem>\t%h1, %A0";
4877 }
4878   [(set (attr "neon_type")
4879       (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4880                     (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4881                     (const_string "neon_vst1_1_2_regs_vst2_2_regs")))]
4882 )
4883
4884 (define_expand "vec_store_lanesoi<mode>"
4885   [(set (match_operand:OI 0 "neon_struct_operand")
4886         (unspec:OI [(match_operand:OI 1 "s_register_operand")
4887                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4888                    UNSPEC_VST2))]
4889   "TARGET_NEON")
4890
4891 (define_insn "neon_vst2<mode>"
4892   [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
4893         (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
4894                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4895                    UNSPEC_VST2))]
4896   "TARGET_NEON"
4897   "vst2.<V_sz_elem>\t%h1, %A0"
4898   [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]
4899 )
4900
4901 (define_insn "neon_vst2_lane<mode>"
4902   [(set (match_operand:<V_two_elem> 0 "neon_struct_operand" "=Um")
4903         (unspec:<V_two_elem>
4904           [(match_operand:TI 1 "s_register_operand" "w")
4905            (match_operand:SI 2 "immediate_operand" "i")
4906            (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4907           UNSPEC_VST2_LANE))]
4908   "TARGET_NEON"
4909 {
4910   HOST_WIDE_INT lane = INTVAL (operands[2]);
4911   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4912   int regno = REGNO (operands[1]);
4913   rtx ops[4];
4914   if (lane < 0 || lane >= max)
4915     error ("lane out of range");
4916   ops[0] = operands[0];
4917   ops[1] = gen_rtx_REG (DImode, regno);
4918   ops[2] = gen_rtx_REG (DImode, regno + 2);
4919   ops[3] = operands[2];
4920   output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, %A0", ops);
4921   return "";
4922 }
4923   [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4924 )
4925
4926 (define_insn "neon_vst2_lane<mode>"
4927   [(set (match_operand:<V_two_elem> 0 "neon_struct_operand" "=Um")
4928         (unspec:<V_two_elem>
4929            [(match_operand:OI 1 "s_register_operand" "w")
4930             (match_operand:SI 2 "immediate_operand" "i")
4931             (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4932            UNSPEC_VST2_LANE))]
4933   "TARGET_NEON"
4934 {
4935   HOST_WIDE_INT lane = INTVAL (operands[2]);
4936   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
4937   int regno = REGNO (operands[1]);
4938   rtx ops[4];
4939   if (lane < 0 || lane >= max)
4940     error ("lane out of range");
4941   else if (lane >= max / 2)
4942     {
4943       lane -= max / 2;
4944       regno += 2;
4945     }
4946   ops[0] = operands[0];
4947   ops[1] = gen_rtx_REG (DImode, regno);
4948   ops[2] = gen_rtx_REG (DImode, regno + 4);
4949   ops[3] = GEN_INT (lane);
4950   output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, %A0", ops);
4951   return "";
4952 }
4953   [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4954 )
4955
4956 (define_expand "vec_load_lanesei<mode>"
4957   [(set (match_operand:EI 0 "s_register_operand")
4958         (unspec:EI [(match_operand:EI 1 "neon_struct_operand")
4959                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4960                    UNSPEC_VLD3))]
4961   "TARGET_NEON")
4962
4963 (define_insn "neon_vld3<mode>"
4964   [(set (match_operand:EI 0 "s_register_operand" "=w")
4965         (unspec:EI [(match_operand:EI 1 "neon_struct_operand" "Um")
4966                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4967                    UNSPEC_VLD3))]
4968   "TARGET_NEON"
4969 {
4970   if (<V_sz_elem> == 64)
4971     return "vld1.64\t%h0, %A1";
4972   else
4973     return "vld3.<V_sz_elem>\t%h0, %A1";
4974 }
4975   [(set (attr "neon_type")
4976       (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
4977                     (const_string "neon_vld1_1_2_regs")
4978                     (const_string "neon_vld3_vld4")))]
4979 )
4980
4981 (define_expand "vec_load_lanesci<mode>"
4982   [(match_operand:CI 0 "s_register_operand")
4983    (match_operand:CI 1 "neon_struct_operand")
4984    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4985   "TARGET_NEON"
4986 {
4987   emit_insn (gen_neon_vld3<mode> (operands[0], operands[1]));
4988   DONE;
4989 })
4990
4991 (define_expand "neon_vld3<mode>"
4992   [(match_operand:CI 0 "s_register_operand")
4993    (match_operand:CI 1 "neon_struct_operand")
4994    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4995   "TARGET_NEON"
4996 {
4997   rtx mem;
4998
4999   mem = adjust_address (operands[1], EImode, 0);
5000   emit_insn (gen_neon_vld3qa<mode> (operands[0], mem));
5001   mem = adjust_address (mem, EImode, GET_MODE_SIZE (EImode));
5002   emit_insn (gen_neon_vld3qb<mode> (operands[0], mem, operands[0]));
5003   DONE;
5004 })
5005
5006 (define_insn "neon_vld3qa<mode>"
5007   [(set (match_operand:CI 0 "s_register_operand" "=w")
5008         (unspec:CI [(match_operand:EI 1 "neon_struct_operand" "Um")
5009                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5010                    UNSPEC_VLD3A))]
5011   "TARGET_NEON"
5012 {
5013   int regno = REGNO (operands[0]);
5014   rtx ops[4];
5015   ops[0] = gen_rtx_REG (DImode, regno);
5016   ops[1] = gen_rtx_REG (DImode, regno + 4);
5017   ops[2] = gen_rtx_REG (DImode, regno + 8);
5018   ops[3] = operands[1];
5019   output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, %A3", ops);
5020   return "";
5021 }
5022   [(set_attr "neon_type" "neon_vld3_vld4")]
5023 )
5024
5025 (define_insn "neon_vld3qb<mode>"
5026   [(set (match_operand:CI 0 "s_register_operand" "=w")
5027         (unspec:CI [(match_operand:EI 1 "neon_struct_operand" "Um")
5028                     (match_operand:CI 2 "s_register_operand" "0")
5029                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5030                    UNSPEC_VLD3B))]
5031   "TARGET_NEON"
5032 {
5033   int regno = REGNO (operands[0]);
5034   rtx ops[4];
5035   ops[0] = gen_rtx_REG (DImode, regno + 2);
5036   ops[1] = gen_rtx_REG (DImode, regno + 6);
5037   ops[2] = gen_rtx_REG (DImode, regno + 10);
5038   ops[3] = operands[1];
5039   output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, %A3", ops);
5040   return "";
5041 }
5042   [(set_attr "neon_type" "neon_vld3_vld4")]
5043 )
5044
5045 (define_insn "neon_vld3_lane<mode>"
5046   [(set (match_operand:EI 0 "s_register_operand" "=w")
5047         (unspec:EI [(match_operand:<V_three_elem> 1 "neon_struct_operand" "Um")
5048                     (match_operand:EI 2 "s_register_operand" "0")
5049                     (match_operand:SI 3 "immediate_operand" "i")
5050                     (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5051                    UNSPEC_VLD3_LANE))]
5052   "TARGET_NEON"
5053 {
5054   HOST_WIDE_INT lane = INTVAL (operands[3]);
5055   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5056   int regno = REGNO (operands[0]);
5057   rtx ops[5];
5058   if (lane < 0 || lane >= max)
5059     error ("lane out of range");
5060   ops[0] = gen_rtx_REG (DImode, regno);
5061   ops[1] = gen_rtx_REG (DImode, regno + 2);
5062   ops[2] = gen_rtx_REG (DImode, regno + 4);
5063   ops[3] = operands[1];
5064   ops[4] = operands[3];
5065   output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, %3",
5066                    ops);
5067   return "";
5068 }
5069   [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5070 )
5071
5072 (define_insn "neon_vld3_lane<mode>"
5073   [(set (match_operand:CI 0 "s_register_operand" "=w")
5074         (unspec:CI [(match_operand:<V_three_elem> 1 "neon_struct_operand" "Um")
5075                     (match_operand:CI 2 "s_register_operand" "0")
5076                     (match_operand:SI 3 "immediate_operand" "i")
5077                     (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5078                    UNSPEC_VLD3_LANE))]
5079   "TARGET_NEON"
5080 {
5081   HOST_WIDE_INT lane = INTVAL (operands[3]);
5082   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5083   int regno = REGNO (operands[0]);
5084   rtx ops[5];
5085   if (lane < 0 || lane >= max)
5086     error ("lane out of range");
5087   else if (lane >= max / 2)
5088     {
5089       lane -= max / 2;
5090       regno += 2;
5091     }
5092   ops[0] = gen_rtx_REG (DImode, regno);
5093   ops[1] = gen_rtx_REG (DImode, regno + 4);
5094   ops[2] = gen_rtx_REG (DImode, regno + 8);
5095   ops[3] = operands[1];
5096   ops[4] = GEN_INT (lane);
5097   output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, %3",
5098                    ops);
5099   return "";
5100 }
5101   [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5102 )
5103
5104 (define_insn "neon_vld3_dup<mode>"
5105   [(set (match_operand:EI 0 "s_register_operand" "=w")
5106         (unspec:EI [(match_operand:<V_three_elem> 1 "neon_struct_operand" "Um")
5107                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5108                    UNSPEC_VLD3_DUP))]
5109   "TARGET_NEON"
5110 {
5111   if (GET_MODE_NUNITS (<MODE>mode) > 1)
5112     {
5113       int regno = REGNO (operands[0]);
5114       rtx ops[4];
5115       ops[0] = gen_rtx_REG (DImode, regno);
5116       ops[1] = gen_rtx_REG (DImode, regno + 2);
5117       ops[2] = gen_rtx_REG (DImode, regno + 4);
5118       ops[3] = operands[1];
5119       output_asm_insn ("vld3.<V_sz_elem>\t{%P0[], %P1[], %P2[]}, %3", ops);
5120       return "";
5121     }
5122   else
5123     return "vld1.<V_sz_elem>\t%h0, %A1";
5124 }
5125   [(set (attr "neon_type")
5126       (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
5127                     (const_string "neon_vld3_vld4_all_lanes")
5128                     (const_string "neon_vld1_1_2_regs")))])
5129
5130 (define_expand "vec_store_lanesei<mode>"
5131   [(set (match_operand:EI 0 "neon_struct_operand")
5132         (unspec:EI [(match_operand:EI 1 "s_register_operand")
5133                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5134                    UNSPEC_VST3))]
5135   "TARGET_NEON")
5136
5137 (define_insn "neon_vst3<mode>"
5138   [(set (match_operand:EI 0 "neon_struct_operand" "=Um")
5139         (unspec:EI [(match_operand:EI 1 "s_register_operand" "w")
5140                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5141                    UNSPEC_VST3))]
5142   "TARGET_NEON"
5143 {
5144   if (<V_sz_elem> == 64)
5145     return "vst1.64\t%h1, %A0";
5146   else
5147     return "vst3.<V_sz_elem>\t%h1, %A0";
5148 }
5149   [(set (attr "neon_type")
5150       (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5151                     (const_string "neon_vst1_1_2_regs_vst2_2_regs")
5152                     (const_string "neon_vst2_4_regs_vst3_vst4")))])
5153
5154 (define_expand "vec_store_lanesci<mode>"
5155   [(match_operand:CI 0 "neon_struct_operand")
5156    (match_operand:CI 1 "s_register_operand")
5157    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5158   "TARGET_NEON"
5159 {
5160   emit_insn (gen_neon_vst3<mode> (operands[0], operands[1]));
5161   DONE;
5162 })
5163
5164 (define_expand "neon_vst3<mode>"
5165   [(match_operand:CI 0 "neon_struct_operand")
5166    (match_operand:CI 1 "s_register_operand")
5167    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5168   "TARGET_NEON"
5169 {
5170   rtx mem;
5171
5172   mem = adjust_address (operands[0], EImode, 0);
5173   emit_insn (gen_neon_vst3qa<mode> (mem, operands[1]));
5174   mem = adjust_address (mem, EImode, GET_MODE_SIZE (EImode));
5175   emit_insn (gen_neon_vst3qb<mode> (mem, operands[1]));
5176   DONE;
5177 })
5178
5179 (define_insn "neon_vst3qa<mode>"
5180   [(set (match_operand:EI 0 "neon_struct_operand" "=Um")
5181         (unspec:EI [(match_operand:CI 1 "s_register_operand" "w")
5182                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5183                    UNSPEC_VST3A))]
5184   "TARGET_NEON"
5185 {
5186   int regno = REGNO (operands[1]);
5187   rtx ops[4];
5188   ops[0] = operands[0];
5189   ops[1] = gen_rtx_REG (DImode, regno);
5190   ops[2] = gen_rtx_REG (DImode, regno + 4);
5191   ops[3] = gen_rtx_REG (DImode, regno + 8);
5192   output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, %A0", ops);
5193   return "";
5194 }
5195   [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5196 )
5197
5198 (define_insn "neon_vst3qb<mode>"
5199   [(set (match_operand:EI 0 "neon_struct_operand" "=Um")
5200         (unspec:EI [(match_operand:CI 1 "s_register_operand" "w")
5201                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5202                    UNSPEC_VST3B))]
5203   "TARGET_NEON"
5204 {
5205   int regno = REGNO (operands[1]);
5206   rtx ops[4];
5207   ops[0] = operands[0];
5208   ops[1] = gen_rtx_REG (DImode, regno + 2);
5209   ops[2] = gen_rtx_REG (DImode, regno + 6);
5210   ops[3] = gen_rtx_REG (DImode, regno + 10);
5211   output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, %A0", ops);
5212   return "";
5213 }
5214   [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5215 )
5216
5217 (define_insn "neon_vst3_lane<mode>"
5218   [(set (match_operand:<V_three_elem> 0 "neon_struct_operand" "=Um")
5219         (unspec:<V_three_elem>
5220            [(match_operand:EI 1 "s_register_operand" "w")
5221             (match_operand:SI 2 "immediate_operand" "i")
5222             (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5223            UNSPEC_VST3_LANE))]
5224   "TARGET_NEON"
5225 {
5226   HOST_WIDE_INT lane = INTVAL (operands[2]);
5227   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5228   int regno = REGNO (operands[1]);
5229   rtx ops[5];
5230   if (lane < 0 || lane >= max)
5231     error ("lane out of range");
5232   ops[0] = operands[0];
5233   ops[1] = gen_rtx_REG (DImode, regno);
5234   ops[2] = gen_rtx_REG (DImode, regno + 2);
5235   ops[3] = gen_rtx_REG (DImode, regno + 4);
5236   ops[4] = operands[2];
5237   output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, %0",
5238                    ops);
5239   return "";
5240 }
5241   [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5242 )
5243
5244 (define_insn "neon_vst3_lane<mode>"
5245   [(set (match_operand:<V_three_elem> 0 "neon_struct_operand" "=Um")
5246         (unspec:<V_three_elem>
5247            [(match_operand:CI 1 "s_register_operand" "w")
5248             (match_operand:SI 2 "immediate_operand" "i")
5249             (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5250            UNSPEC_VST3_LANE))]
5251   "TARGET_NEON"
5252 {
5253   HOST_WIDE_INT lane = INTVAL (operands[2]);
5254   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5255   int regno = REGNO (operands[1]);
5256   rtx ops[5];
5257   if (lane < 0 || lane >= max)
5258     error ("lane out of range");
5259   else if (lane >= max / 2)
5260     {
5261       lane -= max / 2;
5262       regno += 2;
5263     }
5264   ops[0] = operands[0];
5265   ops[1] = gen_rtx_REG (DImode, regno);
5266   ops[2] = gen_rtx_REG (DImode, regno + 4);
5267   ops[3] = gen_rtx_REG (DImode, regno + 8);
5268   ops[4] = GEN_INT (lane);
5269   output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, %0",
5270                    ops);
5271   return "";
5272 }
5273 [(set_attr "neon_type" "neon_vst3_vst4_lane")])
5274
5275 (define_expand "vec_load_lanesoi<mode>"
5276   [(set (match_operand:OI 0 "s_register_operand")
5277         (unspec:OI [(match_operand:OI 1 "neon_struct_operand")
5278                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5279                    UNSPEC_VLD4))]
5280   "TARGET_NEON")
5281
5282 (define_insn "neon_vld4<mode>"
5283   [(set (match_operand:OI 0 "s_register_operand" "=w")
5284         (unspec:OI [(match_operand:OI 1 "neon_struct_operand" "Um")
5285                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5286                    UNSPEC_VLD4))]
5287   "TARGET_NEON"
5288 {
5289   if (<V_sz_elem> == 64)
5290     return "vld1.64\t%h0, %A1";
5291   else
5292     return "vld4.<V_sz_elem>\t%h0, %A1";
5293 }
5294   [(set (attr "neon_type")
5295       (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5296                     (const_string "neon_vld1_1_2_regs")
5297                     (const_string "neon_vld3_vld4")))]
5298 )
5299
5300 (define_expand "vec_load_lanesxi<mode>"
5301   [(match_operand:XI 0 "s_register_operand")
5302    (match_operand:XI 1 "neon_struct_operand")
5303    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5304   "TARGET_NEON"
5305 {
5306   emit_insn (gen_neon_vld4<mode> (operands[0], operands[1]));
5307   DONE;
5308 })
5309
5310 (define_expand "neon_vld4<mode>"
5311   [(match_operand:XI 0 "s_register_operand")
5312    (match_operand:XI 1 "neon_struct_operand")
5313    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5314   "TARGET_NEON"
5315 {
5316   rtx mem;
5317
5318   mem = adjust_address (operands[1], OImode, 0);
5319   emit_insn (gen_neon_vld4qa<mode> (operands[0], mem));
5320   mem = adjust_address (mem, OImode, GET_MODE_SIZE (OImode));
5321   emit_insn (gen_neon_vld4qb<mode> (operands[0], mem, operands[0]));
5322   DONE;
5323 })
5324
5325 (define_insn "neon_vld4qa<mode>"
5326   [(set (match_operand:XI 0 "s_register_operand" "=w")
5327         (unspec:XI [(match_operand:OI 1 "neon_struct_operand" "Um")
5328                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5329                    UNSPEC_VLD4A))]
5330   "TARGET_NEON"
5331 {
5332   int regno = REGNO (operands[0]);
5333   rtx ops[5];
5334   ops[0] = gen_rtx_REG (DImode, regno);
5335   ops[1] = gen_rtx_REG (DImode, regno + 4);
5336   ops[2] = gen_rtx_REG (DImode, regno + 8);
5337   ops[3] = gen_rtx_REG (DImode, regno + 12);
5338   ops[4] = operands[1];
5339   output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, %A4", ops);
5340   return "";
5341 }
5342   [(set_attr "neon_type" "neon_vld3_vld4")]
5343 )
5344
5345 (define_insn "neon_vld4qb<mode>"
5346   [(set (match_operand:XI 0 "s_register_operand" "=w")
5347         (unspec:XI [(match_operand:OI 1 "neon_struct_operand" "Um")
5348                     (match_operand:XI 2 "s_register_operand" "0")
5349                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5350                    UNSPEC_VLD4B))]
5351   "TARGET_NEON"
5352 {
5353   int regno = REGNO (operands[0]);
5354   rtx ops[5];
5355   ops[0] = gen_rtx_REG (DImode, regno + 2);
5356   ops[1] = gen_rtx_REG (DImode, regno + 6);
5357   ops[2] = gen_rtx_REG (DImode, regno + 10);
5358   ops[3] = gen_rtx_REG (DImode, regno + 14);
5359   ops[4] = operands[1];
5360   output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, %A4", ops);
5361   return "";
5362 }
5363   [(set_attr "neon_type" "neon_vld3_vld4")]
5364 )
5365
5366 (define_insn "neon_vld4_lane<mode>"
5367   [(set (match_operand:OI 0 "s_register_operand" "=w")
5368         (unspec:OI [(match_operand:<V_four_elem> 1 "neon_struct_operand" "Um")
5369                     (match_operand:OI 2 "s_register_operand" "0")
5370                     (match_operand:SI 3 "immediate_operand" "i")
5371                     (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5372                    UNSPEC_VLD4_LANE))]
5373   "TARGET_NEON"
5374 {
5375   HOST_WIDE_INT lane = INTVAL (operands[3]);
5376   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5377   int regno = REGNO (operands[0]);
5378   rtx ops[6];
5379   if (lane < 0 || lane >= max)
5380     error ("lane out of range");
5381   ops[0] = gen_rtx_REG (DImode, regno);
5382   ops[1] = gen_rtx_REG (DImode, regno + 2);
5383   ops[2] = gen_rtx_REG (DImode, regno + 4);
5384   ops[3] = gen_rtx_REG (DImode, regno + 6);
5385   ops[4] = operands[1];
5386   ops[5] = operands[3];
5387   output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, %A4",
5388                    ops);
5389   return "";
5390 }
5391   [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5392 )
5393
5394 (define_insn "neon_vld4_lane<mode>"
5395   [(set (match_operand:XI 0 "s_register_operand" "=w")
5396         (unspec:XI [(match_operand:<V_four_elem> 1 "neon_struct_operand" "Um")
5397                     (match_operand:XI 2 "s_register_operand" "0")
5398                     (match_operand:SI 3 "immediate_operand" "i")
5399                     (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5400                    UNSPEC_VLD4_LANE))]
5401   "TARGET_NEON"
5402 {
5403   HOST_WIDE_INT lane = INTVAL (operands[3]);
5404   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5405   int regno = REGNO (operands[0]);
5406   rtx ops[6];
5407   if (lane < 0 || lane >= max)
5408     error ("lane out of range");
5409   else if (lane >= max / 2)
5410     {
5411       lane -= max / 2;
5412       regno += 2;
5413     }
5414   ops[0] = gen_rtx_REG (DImode, regno);
5415   ops[1] = gen_rtx_REG (DImode, regno + 4);
5416   ops[2] = gen_rtx_REG (DImode, regno + 8);
5417   ops[3] = gen_rtx_REG (DImode, regno + 12);
5418   ops[4] = operands[1];
5419   ops[5] = GEN_INT (lane);
5420   output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, %A4",
5421                    ops);
5422   return "";
5423 }
5424   [(set_attr "neon_type" "neon_vld3_vld4_lane")]
5425 )
5426
5427 (define_insn "neon_vld4_dup<mode>"
5428   [(set (match_operand:OI 0 "s_register_operand" "=w")
5429         (unspec:OI [(match_operand:<V_four_elem> 1 "neon_struct_operand" "Um")
5430                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5431                    UNSPEC_VLD4_DUP))]
5432   "TARGET_NEON"
5433 {
5434   if (GET_MODE_NUNITS (<MODE>mode) > 1)
5435     {
5436       int regno = REGNO (operands[0]);
5437       rtx ops[5];
5438       ops[0] = gen_rtx_REG (DImode, regno);
5439       ops[1] = gen_rtx_REG (DImode, regno + 2);
5440       ops[2] = gen_rtx_REG (DImode, regno + 4);
5441       ops[3] = gen_rtx_REG (DImode, regno + 6);
5442       ops[4] = operands[1];
5443       output_asm_insn ("vld4.<V_sz_elem>\t{%P0[], %P1[], %P2[], %P3[]}, %A4",
5444                        ops);
5445       return "";
5446     }
5447   else
5448     return "vld1.<V_sz_elem>\t%h0, %A1";
5449 }
5450   [(set (attr "neon_type")
5451       (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
5452                     (const_string "neon_vld3_vld4_all_lanes")
5453                     (const_string "neon_vld1_1_2_regs")))]
5454 )
5455
5456 (define_expand "vec_store_lanesoi<mode>"
5457   [(set (match_operand:OI 0 "neon_struct_operand")
5458         (unspec:OI [(match_operand:OI 1 "s_register_operand")
5459                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5460                    UNSPEC_VST4))]
5461   "TARGET_NEON")
5462
5463 (define_insn "neon_vst4<mode>"
5464   [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
5465         (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
5466                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5467                    UNSPEC_VST4))]
5468   "TARGET_NEON"
5469 {
5470   if (<V_sz_elem> == 64)
5471     return "vst1.64\t%h1, %A0";
5472   else
5473     return "vst4.<V_sz_elem>\t%h1, %A0";
5474 }
5475   [(set (attr "neon_type")
5476       (if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
5477                     (const_string "neon_vst1_1_2_regs_vst2_2_regs")
5478                     (const_string "neon_vst2_4_regs_vst3_vst4")))]
5479 )
5480
5481 (define_expand "vec_store_lanesxi<mode>"
5482   [(match_operand:XI 0 "neon_struct_operand")
5483    (match_operand:XI 1 "s_register_operand")
5484    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5485   "TARGET_NEON"
5486 {
5487   emit_insn (gen_neon_vst4<mode> (operands[0], operands[1]));
5488   DONE;
5489 })
5490
5491 (define_expand "neon_vst4<mode>"
5492   [(match_operand:XI 0 "neon_struct_operand")
5493    (match_operand:XI 1 "s_register_operand")
5494    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5495   "TARGET_NEON"
5496 {
5497   rtx mem;
5498
5499   mem = adjust_address (operands[0], OImode, 0);
5500   emit_insn (gen_neon_vst4qa<mode> (mem, operands[1]));
5501   mem = adjust_address (mem, OImode, GET_MODE_SIZE (OImode));
5502   emit_insn (gen_neon_vst4qb<mode> (mem, operands[1]));
5503   DONE;
5504 })
5505
5506 (define_insn "neon_vst4qa<mode>"
5507   [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
5508         (unspec:OI [(match_operand:XI 1 "s_register_operand" "w")
5509                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5510                    UNSPEC_VST4A))]
5511   "TARGET_NEON"
5512 {
5513   int regno = REGNO (operands[1]);
5514   rtx ops[5];
5515   ops[0] = operands[0];
5516   ops[1] = gen_rtx_REG (DImode, regno);
5517   ops[2] = gen_rtx_REG (DImode, regno + 4);
5518   ops[3] = gen_rtx_REG (DImode, regno + 8);
5519   ops[4] = gen_rtx_REG (DImode, regno + 12);
5520   output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, %A0", ops);
5521   return "";
5522 }
5523   [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5524 )
5525
5526 (define_insn "neon_vst4qb<mode>"
5527   [(set (match_operand:OI 0 "neon_struct_operand" "=Um")
5528         (unspec:OI [(match_operand:XI 1 "s_register_operand" "w")
5529                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5530                    UNSPEC_VST4B))]
5531   "TARGET_NEON"
5532 {
5533   int regno = REGNO (operands[1]);
5534   rtx ops[5];
5535   ops[0] = operands[0];
5536   ops[1] = gen_rtx_REG (DImode, regno + 2);
5537   ops[2] = gen_rtx_REG (DImode, regno + 6);
5538   ops[3] = gen_rtx_REG (DImode, regno + 10);
5539   ops[4] = gen_rtx_REG (DImode, regno + 14);
5540   output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, %A0", ops);
5541   return "";
5542 }
5543   [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
5544 )
5545
5546 (define_insn "neon_vst4_lane<mode>"
5547   [(set (match_operand:<V_four_elem> 0 "neon_struct_operand" "=Um")
5548         (unspec:<V_four_elem>
5549            [(match_operand:OI 1 "s_register_operand" "w")
5550             (match_operand:SI 2 "immediate_operand" "i")
5551             (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5552            UNSPEC_VST4_LANE))]
5553   "TARGET_NEON"
5554 {
5555   HOST_WIDE_INT lane = INTVAL (operands[2]);
5556   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5557   int regno = REGNO (operands[1]);
5558   rtx ops[6];
5559   if (lane < 0 || lane >= max)
5560     error ("lane out of range");
5561   ops[0] = operands[0];
5562   ops[1] = gen_rtx_REG (DImode, regno);
5563   ops[2] = gen_rtx_REG (DImode, regno + 2);
5564   ops[3] = gen_rtx_REG (DImode, regno + 4);
5565   ops[4] = gen_rtx_REG (DImode, regno + 6);
5566   ops[5] = operands[2];
5567   output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, %A0",
5568                    ops);
5569   return "";
5570 }
5571   [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5572 )
5573
5574 (define_insn "neon_vst4_lane<mode>"
5575   [(set (match_operand:<V_four_elem> 0 "neon_struct_operand" "=Um")
5576         (unspec:<V_four_elem>
5577            [(match_operand:XI 1 "s_register_operand" "w")
5578             (match_operand:SI 2 "immediate_operand" "i")
5579             (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
5580            UNSPEC_VST4_LANE))]
5581   "TARGET_NEON"
5582 {
5583   HOST_WIDE_INT lane = INTVAL (operands[2]);
5584   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
5585   int regno = REGNO (operands[1]);
5586   rtx ops[6];
5587   if (lane < 0 || lane >= max)
5588     error ("lane out of range");
5589   else if (lane >= max / 2)
5590     {
5591       lane -= max / 2;
5592       regno += 2;
5593     }
5594   ops[0] = operands[0];
5595   ops[1] = gen_rtx_REG (DImode, regno);
5596   ops[2] = gen_rtx_REG (DImode, regno + 4);
5597   ops[3] = gen_rtx_REG (DImode, regno + 8);
5598   ops[4] = gen_rtx_REG (DImode, regno + 12);
5599   ops[5] = GEN_INT (lane);
5600   output_asm_insn ("vst4.<V_sz_elem>\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, %A0",
5601                    ops);
5602   return "";
5603 }
5604   [(set_attr "neon_type" "neon_vst3_vst4_lane")]
5605 )
5606
5607 (define_expand "neon_vand<mode>"
5608   [(match_operand:VDQX 0 "s_register_operand" "")
5609    (match_operand:VDQX 1 "s_register_operand" "")
5610    (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5611    (match_operand:SI 3 "immediate_operand" "")]
5612   "TARGET_NEON"
5613 {
5614   emit_insn (gen_and<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5615   DONE;
5616 })
5617
5618 (define_expand "neon_vorr<mode>"
5619   [(match_operand:VDQX 0 "s_register_operand" "")
5620    (match_operand:VDQX 1 "s_register_operand" "")
5621    (match_operand:VDQX 2 "neon_logic_op2" "")
5622    (match_operand:SI 3 "immediate_operand" "")]
5623   "TARGET_NEON"
5624 {
5625   emit_insn (gen_ior<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5626   DONE;
5627 })
5628
5629 (define_expand "neon_veor<mode>"
5630   [(match_operand:VDQX 0 "s_register_operand" "")
5631    (match_operand:VDQX 1 "s_register_operand" "")
5632    (match_operand:VDQX 2 "s_register_operand" "")
5633    (match_operand:SI 3 "immediate_operand" "")]
5634   "TARGET_NEON"
5635 {
5636   emit_insn (gen_xor<mode>3<V_suf64> (operands[0], operands[1], operands[2]));
5637   DONE;
5638 })
5639
5640 (define_expand "neon_vbic<mode>"
5641   [(match_operand:VDQX 0 "s_register_operand" "")
5642    (match_operand:VDQX 1 "s_register_operand" "")
5643    (match_operand:VDQX 2 "neon_logic_op2" "")
5644    (match_operand:SI 3 "immediate_operand" "")]
5645   "TARGET_NEON"
5646 {
5647   emit_insn (gen_bic<mode>3_neon (operands[0], operands[1], operands[2]));
5648   DONE;
5649 })
5650
5651 (define_expand "neon_vorn<mode>"
5652   [(match_operand:VDQX 0 "s_register_operand" "")
5653    (match_operand:VDQX 1 "s_register_operand" "")
5654    (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5655    (match_operand:SI 3 "immediate_operand" "")]
5656   "TARGET_NEON"
5657 {
5658   emit_insn (gen_orn<mode>3_neon (operands[0], operands[1], operands[2]));
5659   DONE;
5660 })
5661
5662 (define_insn "neon_vec_unpack<US>_lo_<mode>"
5663   [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5664         (SE:<V_unpack> (vec_select:<V_HALF>
5665                           (match_operand:VU 1 "register_operand" "w")
5666                           (match_operand:VU 2 "vect_par_constant_low" ""))))]
5667   "TARGET_NEON && !BYTES_BIG_ENDIAN"
5668   "vmovl.<US><V_sz_elem> %q0, %e1"
5669   [(set_attr "neon_type" "neon_shift_1")]
5670 )
5671
5672 (define_insn "neon_vec_unpack<US>_hi_<mode>"
5673   [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5674         (SE:<V_unpack> (vec_select:<V_HALF>
5675                           (match_operand:VU 1 "register_operand" "w")
5676                           (match_operand:VU 2 "vect_par_constant_high" ""))))]
5677   "TARGET_NEON && !BYTES_BIG_ENDIAN"
5678   "vmovl.<US><V_sz_elem> %q0, %f1"
5679   [(set_attr "neon_type" "neon_shift_1")]
5680 )
5681
5682 (define_expand "vec_unpack<US>_hi_<mode>"
5683   [(match_operand:<V_unpack> 0 "register_operand" "")
5684    (SE:<V_unpack> (match_operand:VU 1 "register_operand"))]
5685  "TARGET_NEON && !BYTES_BIG_ENDIAN"
5686   {
5687    rtvec v = rtvec_alloc (<V_mode_nunits>/2)  ;
5688    rtx t1;
5689    int i;
5690    for (i = 0; i < (<V_mode_nunits>/2); i++)
5691      RTVEC_ELT (v, i) = GEN_INT ((<V_mode_nunits>/2) + i);
5692   
5693    t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5694    emit_insn (gen_neon_vec_unpack<US>_hi_<mode> (operands[0], 
5695                                                  operands[1], 
5696                                                  t1));
5697    DONE;
5698   }
5699 )
5700
5701 (define_expand "vec_unpack<US>_lo_<mode>"
5702   [(match_operand:<V_unpack> 0 "register_operand" "")
5703    (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))]
5704  "TARGET_NEON && !BYTES_BIG_ENDIAN"
5705   {
5706    rtvec v = rtvec_alloc (<V_mode_nunits>/2)  ;
5707    rtx t1;
5708    int i;
5709    for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5710      RTVEC_ELT (v, i) = GEN_INT (i);
5711    t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5712    emit_insn (gen_neon_vec_unpack<US>_lo_<mode> (operands[0], 
5713                                                  operands[1], 
5714                                                  t1));
5715    DONE;
5716   }
5717 )
5718
5719 (define_insn "neon_vec_<US>mult_lo_<mode>"
5720  [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5721        (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5722                            (match_operand:VU 1 "register_operand" "w") 
5723                            (match_operand:VU 2 "vect_par_constant_low" "")))
5724                         (SE:<V_unpack> (vec_select:<V_HALF>
5725                            (match_operand:VU 3 "register_operand" "w") 
5726                            (match_dup 2)))))]
5727   "TARGET_NEON && !BYTES_BIG_ENDIAN"
5728   "vmull.<US><V_sz_elem> %q0, %e1, %e3"
5729   [(set_attr "neon_type" "neon_shift_1")]
5730 )
5731
5732 (define_expand "vec_widen_<US>mult_lo_<mode>"
5733   [(match_operand:<V_unpack> 0 "register_operand" "")
5734    (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5735    (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5736  "TARGET_NEON && !BYTES_BIG_ENDIAN"
5737  {
5738    rtvec v = rtvec_alloc (<V_mode_nunits>/2)  ;
5739    rtx t1;
5740    int i;
5741    for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5742      RTVEC_ELT (v, i) = GEN_INT (i);
5743    t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5744
5745    emit_insn (gen_neon_vec_<US>mult_lo_<mode> (operands[0],
5746                                                operands[1],
5747                                                t1,
5748                                                operands[2]));
5749    DONE;
5750  }
5751 )
5752
5753 (define_insn "neon_vec_<US>mult_hi_<mode>"
5754  [(set (match_operand:<V_unpack> 0 "register_operand" "=w")
5755       (mult:<V_unpack> (SE:<V_unpack> (vec_select:<V_HALF>
5756                             (match_operand:VU 1 "register_operand" "w") 
5757                             (match_operand:VU 2 "vect_par_constant_high" "")))
5758                        (SE:<V_unpack> (vec_select:<V_HALF>
5759                             (match_operand:VU 3 "register_operand" "w") 
5760                             (match_dup 2)))))]
5761   "TARGET_NEON && !BYTES_BIG_ENDIAN"
5762   "vmull.<US><V_sz_elem> %q0, %f1, %f3"
5763   [(set_attr "neon_type" "neon_shift_1")]
5764 )
5765
5766 (define_expand "vec_widen_<US>mult_hi_<mode>"
5767   [(match_operand:<V_unpack> 0 "register_operand" "")
5768    (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5769    (SE:<V_unpack> (match_operand:VU 2 "register_operand" ""))]
5770  "TARGET_NEON && !BYTES_BIG_ENDIAN"
5771  {
5772    rtvec v = rtvec_alloc (<V_mode_nunits>/2)  ;
5773    rtx t1;
5774    int i;
5775    for (i = 0; i < (<V_mode_nunits>/2) ; i++)
5776      RTVEC_ELT (v, i) = GEN_INT (<V_mode_nunits>/2 + i);
5777    t1 = gen_rtx_PARALLEL (<MODE>mode, v);
5778
5779    emit_insn (gen_neon_vec_<US>mult_hi_<mode> (operands[0],
5780                                                operands[1],
5781                                                t1,
5782                                                operands[2]));
5783    DONE;
5784
5785  }
5786 )
5787
5788 (define_insn "neon_vec_<US>shiftl_<mode>"
5789  [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5790        (SE:<V_widen> (ashift:VW (match_operand:VW 1 "register_operand" "w")
5791        (match_operand:<V_innermode> 2 "const_neon_scalar_shift_amount_operand" ""))))]
5792   "TARGET_NEON"
5793 {
5794   return "vshll.<US><V_sz_elem> %q0, %P1, %2";
5795 }
5796   [(set_attr "neon_type" "neon_shift_1")]
5797 )
5798
5799 (define_expand "vec_widen_<US>shiftl_lo_<mode>"
5800   [(match_operand:<V_unpack> 0 "register_operand" "")
5801    (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5802    (match_operand:SI 2 "immediate_operand" "i")]
5803  "TARGET_NEON && !BYTES_BIG_ENDIAN"
5804  {
5805   emit_insn (gen_neon_vec_<US>shiftl_<V_half> (operands[0],
5806                 simplify_gen_subreg (<V_HALF>mode, operands[1], <MODE>mode, 0),
5807                 operands[2]));
5808    DONE;
5809  }
5810 )
5811
5812 (define_expand "vec_widen_<US>shiftl_hi_<mode>"
5813   [(match_operand:<V_unpack> 0 "register_operand" "")
5814    (SE:<V_unpack> (match_operand:VU 1 "register_operand" ""))
5815    (match_operand:SI 2 "immediate_operand" "i")]
5816  "TARGET_NEON && !BYTES_BIG_ENDIAN"
5817  {
5818   emit_insn (gen_neon_vec_<US>shiftl_<V_half> (operands[0],
5819                 simplify_gen_subreg (<V_HALF>mode, operands[1], <MODE>mode,
5820                                      GET_MODE_SIZE (<V_HALF>mode)),
5821                 operands[2]));
5822    DONE;
5823  }
5824 )
5825
5826 ;; Vectorize for non-neon-quad case
5827 (define_insn "neon_unpack<US>_<mode>"
5828  [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5829        (SE:<V_widen> (match_operand:VDI 1 "register_operand" "w")))]
5830  "TARGET_NEON"
5831  "vmovl.<US><V_sz_elem> %q0, %P1"
5832   [(set_attr "neon_type" "neon_shift_1")]
5833 )
5834
5835 (define_expand "vec_unpack<US>_lo_<mode>"
5836  [(match_operand:<V_double_width> 0 "register_operand" "")
5837   (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5838  "TARGET_NEON"
5839 {
5840   rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5841   emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5842   emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5843
5844   DONE;
5845 }
5846 )
5847
5848 (define_expand "vec_unpack<US>_hi_<mode>"
5849  [(match_operand:<V_double_width> 0 "register_operand" "")
5850   (SE:<V_double_width>(match_operand:VDI 1 "register_operand"))]
5851  "TARGET_NEON"
5852 {
5853   rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5854   emit_insn (gen_neon_unpack<US>_<mode> (tmpreg, operands[1]));
5855   emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5856
5857   DONE;
5858 }
5859 )
5860
5861 (define_insn "neon_vec_<US>mult_<mode>"
5862  [(set (match_operand:<V_widen> 0 "register_operand" "=w")
5863        (mult:<V_widen> (SE:<V_widen> 
5864                            (match_operand:VDI 1 "register_operand" "w"))
5865                        (SE:<V_widen> 
5866                            (match_operand:VDI 2 "register_operand" "w"))))]
5867   "TARGET_NEON"
5868   "vmull.<US><V_sz_elem> %q0, %P1, %P2"
5869   [(set_attr "neon_type" "neon_shift_1")]
5870 )
5871
5872 (define_expand "vec_widen_<US>mult_hi_<mode>"
5873   [(match_operand:<V_double_width> 0 "register_operand" "")
5874    (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5875    (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5876  "TARGET_NEON"
5877  {
5878    rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5879    emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5880    emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5881                                             
5882    DONE;
5883
5884  }
5885 )
5886
5887 (define_expand "vec_widen_<US>mult_lo_<mode>"
5888   [(match_operand:<V_double_width> 0 "register_operand" "")
5889    (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5890    (SE:<V_double_width> (match_operand:VDI 2 "register_operand" ""))]
5891  "TARGET_NEON"
5892  {
5893    rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5894    emit_insn (gen_neon_vec_<US>mult_<mode> (tmpreg, operands[1], operands[2]));
5895    emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5896                                             
5897    DONE;
5898
5899  }
5900 )
5901
5902 (define_expand "vec_widen_<US>shiftl_hi_<mode>"
5903  [(match_operand:<V_double_width> 0 "register_operand" "")
5904    (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5905    (match_operand:SI 2 "immediate_operand" "i")]
5906  "TARGET_NEON"
5907  {
5908    rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5909    emit_insn (gen_neon_vec_<US>shiftl_<mode> (tmpreg, operands[1], operands[2]));
5910    emit_insn (gen_neon_vget_high<V_widen_l> (operands[0], tmpreg));
5911
5912    DONE;
5913  }
5914 )
5915
5916 (define_expand "vec_widen_<US>shiftl_lo_<mode>"
5917   [(match_operand:<V_double_width> 0 "register_operand" "")
5918    (SE:<V_double_width> (match_operand:VDI 1 "register_operand" ""))
5919    (match_operand:SI 2 "immediate_operand" "i")]
5920  "TARGET_NEON"
5921  {
5922    rtx tmpreg = gen_reg_rtx (<V_widen>mode);
5923    emit_insn (gen_neon_vec_<US>shiftl_<mode> (tmpreg, operands[1], operands[2]));
5924    emit_insn (gen_neon_vget_low<V_widen_l> (operands[0], tmpreg));
5925
5926    DONE;
5927  }
5928 )
5929
5930 ; FIXME: These instruction patterns can't be used safely in big-endian mode
5931 ; because the ordering of vector elements in Q registers is different from what
5932 ; the semantics of the instructions require.
5933
5934 (define_insn "vec_pack_trunc_<mode>"
5935  [(set (match_operand:<V_narrow_pack> 0 "register_operand" "=&w")
5936        (vec_concat:<V_narrow_pack> 
5937                 (truncate:<V_narrow> 
5938                         (match_operand:VN 1 "register_operand" "w"))
5939                 (truncate:<V_narrow>
5940                         (match_operand:VN 2 "register_operand" "w"))))]
5941  "TARGET_NEON && !BYTES_BIG_ENDIAN"
5942  "vmovn.i<V_sz_elem>\t%e0, %q1\;vmovn.i<V_sz_elem>\t%f0, %q2"
5943  [(set_attr "neon_type" "neon_shift_1")
5944   (set_attr "length" "8")]
5945 )
5946
5947 ;; For the non-quad case.
5948 (define_insn "neon_vec_pack_trunc_<mode>"
5949  [(set (match_operand:<V_narrow> 0 "register_operand" "=w")
5950        (truncate:<V_narrow> (match_operand:VN 1 "register_operand" "w")))]
5951  "TARGET_NEON && !BYTES_BIG_ENDIAN"
5952  "vmovn.i<V_sz_elem>\t%P0, %q1"
5953  [(set_attr "neon_type" "neon_shift_1")]
5954 )
5955
5956 (define_expand "vec_pack_trunc_<mode>"
5957  [(match_operand:<V_narrow_pack> 0 "register_operand" "")
5958   (match_operand:VSHFT 1 "register_operand" "")
5959   (match_operand:VSHFT 2 "register_operand")]
5960  "TARGET_NEON && !BYTES_BIG_ENDIAN"
5961 {
5962   rtx tempreg = gen_reg_rtx (<V_DOUBLE>mode);
5963   
5964   emit_insn (gen_move_lo_quad_<V_double> (tempreg, operands[1])); 
5965   emit_insn (gen_move_hi_quad_<V_double> (tempreg, operands[2])); 
5966   emit_insn (gen_neon_vec_pack_trunc_<V_double> (operands[0], tempreg));
5967   DONE;
5968 })
5969
5970 (define_insn "neon_vabd<mode>_2"
5971  [(set (match_operand:VDQ 0 "s_register_operand" "=w")
5972        (abs:VDQ (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
5973                            (match_operand:VDQ 2 "s_register_operand" "w"))))]
5974  "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
5975  "vabd.<V_s_elem> %<V_reg>0, %<V_reg>1, %<V_reg>2"
5976  [(set (attr "neon_type")
5977        (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
5978                      (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
5979                                    (const_string "neon_fp_vadd_ddd_vabs_dd")
5980                                    (const_string "neon_fp_vadd_qqq_vabs_qq"))
5981                      (const_string "neon_int_5")))]
5982 )
5983
5984 (define_insn "neon_vabd<mode>_3"
5985  [(set (match_operand:VDQ 0 "s_register_operand" "=w")
5986        (abs:VDQ (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
5987                              (match_operand:VDQ 2 "s_register_operand" "w")]
5988                  UNSPEC_VSUB)))]
5989  "TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
5990  "vabd.<V_if_elem> %<V_reg>0, %<V_reg>1, %<V_reg>2"
5991  [(set (attr "neon_type")
5992        (if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
5993                      (if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
5994                                    (const_string "neon_fp_vadd_ddd_vabs_dd")
5995                                    (const_string "neon_fp_vadd_qqq_vabs_qq"))
5996                      (const_string "neon_int_5")))]
5997 )
5998
5999 ;; Copy from core-to-neon regs, then extend, not vice-versa
6000
6001 (define_split
6002   [(set (match_operand:DI 0 "s_register_operand" "")
6003         (sign_extend:DI (match_operand:SI 1 "s_register_operand" "")))]
6004   "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6005   [(set (match_dup 2) (vec_duplicate:V2SI (match_dup 1)))
6006    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 32)))]
6007   {
6008     operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0]));
6009   })
6010
6011 (define_split
6012   [(set (match_operand:DI 0 "s_register_operand" "")
6013         (sign_extend:DI (match_operand:HI 1 "s_register_operand" "")))]
6014   "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6015   [(set (match_dup 2) (vec_duplicate:V4HI (match_dup 1)))
6016    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 48)))]
6017   {
6018     operands[2] = gen_rtx_REG (V4HImode, REGNO (operands[0]));
6019   })
6020
6021 (define_split
6022   [(set (match_operand:DI 0 "s_register_operand" "")
6023         (sign_extend:DI (match_operand:QI 1 "s_register_operand" "")))]
6024   "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6025   [(set (match_dup 2) (vec_duplicate:V8QI (match_dup 1)))
6026    (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))]
6027   {
6028     operands[2] = gen_rtx_REG (V8QImode, REGNO (operands[0]));
6029   })
6030
6031 (define_split
6032   [(set (match_operand:DI 0 "s_register_operand" "")
6033         (zero_extend:DI (match_operand:SI 1 "s_register_operand" "")))]
6034   "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6035   [(set (match_dup 2) (vec_duplicate:V2SI (match_dup 1)))
6036    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 32)))]
6037   {
6038     operands[2] = gen_rtx_REG (V2SImode, REGNO (operands[0]));
6039   })
6040
6041 (define_split
6042   [(set (match_operand:DI 0 "s_register_operand" "")
6043         (zero_extend:DI (match_operand:HI 1 "s_register_operand" "")))]
6044   "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6045   [(set (match_dup 2) (vec_duplicate:V4HI (match_dup 1)))
6046    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 48)))]
6047   {
6048     operands[2] = gen_rtx_REG (V4HImode, REGNO (operands[0]));
6049   })
6050
6051 (define_split
6052   [(set (match_operand:DI 0 "s_register_operand" "")
6053         (zero_extend:DI (match_operand:QI 1 "s_register_operand" "")))]
6054   "TARGET_NEON && reload_completed && IS_VFP_REGNUM (REGNO (operands[0]))"
6055   [(set (match_dup 2) (vec_duplicate:V8QI (match_dup 1)))
6056    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
6057   {
6058     operands[2] = gen_rtx_REG (V8QImode, REGNO (operands[0]));
6059   })