OSDN Git Service

48b4e2a2c94c2d13b89f024ee8435a606162c7dd
[pf3gnuchains/gcc-fork.git] / gcc / config / arm / neon.md
1 ;; ARM NEON coprocessor Machine Description
2 ;; Copyright (C) 2006 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 2, 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 COPYING.  If not, write to the Free
19 ;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 ;; 02110-1301, USA.
21
22 ;; Constants for unspecs.
23 (define_constants
24   [(UNSPEC_ASHIFT_SIGNED        65)
25    (UNSPEC_ASHIFT_UNSIGNED      66)
26    (UNSPEC_VABA                 67)
27    (UNSPEC_VABAL                68)
28    (UNSPEC_VABD                 69)
29    (UNSPEC_VABDL                70)
30    (UNSPEC_VABS                 71)
31    (UNSPEC_VADD                 72)
32    (UNSPEC_VADDHN               73)
33    (UNSPEC_VADDL                74)
34    (UNSPEC_VADDW                75)
35    (UNSPEC_VAND                 76)
36    (UNSPEC_VBIC                 77)
37    (UNSPEC_VBSL                 78)
38    (UNSPEC_VCAGE                79)
39    (UNSPEC_VCAGT                80)
40    (UNSPEC_VCEQ                 81)
41    (UNSPEC_VCGE                 82)
42    (UNSPEC_VCGT                 83)
43    (UNSPEC_VCLS                 84)
44    (UNSPEC_VCLZ                 85)
45    (UNSPEC_VCNT                 86)
46    (UNSPEC_VCOMBINE             87)
47    (UNSPEC_VCVT                 88)
48    (UNSPEC_VCVT_N               89)
49    (UNSPEC_VDUP_LANE            90)
50    (UNSPEC_VDUP_N               91)
51    (UNSPEC_VEOR                 92)
52    (UNSPEC_VEXT                 93)
53    (UNSPEC_VGET_HIGH            94)
54    (UNSPEC_VGET_LANE            95)
55    (UNSPEC_VGET_LOW             96)
56    (UNSPEC_VHADD                97)
57    (UNSPEC_VHSUB                98)
58    (UNSPEC_VLD1                 99)
59    (UNSPEC_VLD1_DUP             100)
60    (UNSPEC_VLD1_LANE            101)
61    (UNSPEC_VLD2                 102)
62    (UNSPEC_VLD2_DUP             103)
63    (UNSPEC_VLD2_LANE            104)
64    (UNSPEC_VLD3                 105)
65    (UNSPEC_VLD3A                106)
66    (UNSPEC_VLD3B                107)
67    (UNSPEC_VLD3_DUP             108)
68    (UNSPEC_VLD3_LANE            109)
69    (UNSPEC_VLD4                 110)
70    (UNSPEC_VLD4A                111)
71    (UNSPEC_VLD4B                112)
72    (UNSPEC_VLD4_DUP             113)
73    (UNSPEC_VLD4_LANE            114)
74    (UNSPEC_VMAX                 115)
75    (UNSPEC_VMIN                 116)
76    (UNSPEC_VMLA                 117)
77    (UNSPEC_VMLAL                118)
78    (UNSPEC_VMLA_LANE            119)
79    (UNSPEC_VMLAL_LANE           120)
80    (UNSPEC_VMLS                 121)
81    (UNSPEC_VMLSL                122)
82    (UNSPEC_VMLS_LANE            123)
83    (UNSPEC_VMLSL_LANE           124)
84    (UNSPEC_VMOVL                125)
85    (UNSPEC_VMOVN                126)
86    (UNSPEC_VMUL                 127)
87    (UNSPEC_VMULL                128)
88    (UNSPEC_VMUL_LANE            129)
89    (UNSPEC_VMULL_LANE           130)
90    (UNSPEC_VMUL_N               131)
91    (UNSPEC_VMVN                 132)
92    (UNSPEC_VORN                 133)
93    (UNSPEC_VORR                 134)
94    (UNSPEC_VPADAL               135)
95    (UNSPEC_VPADD                136)
96    (UNSPEC_VPADDL               137)
97    (UNSPEC_VPMAX                138)
98    (UNSPEC_VPMIN                139)
99    (UNSPEC_VPSMAX               140)
100    (UNSPEC_VPSMIN               141)
101    (UNSPEC_VPUMAX               142)
102    (UNSPEC_VPUMIN               143)
103    (UNSPEC_VQABS                144)
104    (UNSPEC_VQADD                145)
105    (UNSPEC_VQDMLAL              146)
106    (UNSPEC_VQDMLAL_LANE         147)
107    (UNSPEC_VQDMLSL              148)
108    (UNSPEC_VQDMLSL_LANE         149)
109    (UNSPEC_VQDMULH              150)
110    (UNSPEC_VQDMULH_LANE         151)
111    (UNSPEC_VQDMULL              152)
112    (UNSPEC_VQDMULL_LANE         153)
113    (UNSPEC_VQMOVN               154)
114    (UNSPEC_VQMOVUN              155)
115    (UNSPEC_VQNEG                156)
116    (UNSPEC_VQSHL                157)
117    (UNSPEC_VQSHL_N              158)
118    (UNSPEC_VQSHLU_N             159)
119    (UNSPEC_VQSHRN_N             160)
120    (UNSPEC_VQSHRUN_N            161)
121    (UNSPEC_VQSUB                162)
122    (UNSPEC_VRECPE               163)
123    (UNSPEC_VRECPS               164)
124    (UNSPEC_VREV16               165)
125    (UNSPEC_VREV32               166)
126    (UNSPEC_VREV64               167)
127    (UNSPEC_VRSQRTE              168)
128    (UNSPEC_VRSQRTS              169)
129    (UNSPEC_VSET_LANE            170)
130    (UNSPEC_VSHL                 171)
131    (UNSPEC_VSHLL_N              172)
132    (UNSPEC_VSHL_N               173)
133    (UNSPEC_VSHR_N               174)
134    (UNSPEC_VSHRN_N              175)
135    (UNSPEC_VSLI                 176)
136    (UNSPEC_VSRA_N               177)
137    (UNSPEC_VSRI                 178)
138    (UNSPEC_VST1                 179)
139    (UNSPEC_VST1_LANE            180)
140    (UNSPEC_VST2                 181)
141    (UNSPEC_VST2_LANE            182)
142    (UNSPEC_VST3                 183)
143    (UNSPEC_VST3A                184)
144    (UNSPEC_VST3B                185)
145    (UNSPEC_VST3_LANE            186)
146    (UNSPEC_VST4                 187)
147    (UNSPEC_VST4A                188)
148    (UNSPEC_VST4B                189)
149    (UNSPEC_VST4_LANE            190)
150    (UNSPEC_VSTRUCTDUMMY         191)
151    (UNSPEC_VSUB                 192)
152    (UNSPEC_VSUBHN               193)
153    (UNSPEC_VSUBL                194)
154    (UNSPEC_VSUBW                195)
155    (UNSPEC_VTBL                 196)
156    (UNSPEC_VTBX                 197)
157    (UNSPEC_VTRN1                198)
158    (UNSPEC_VTRN2                199)
159    (UNSPEC_VTST                 200)
160    (UNSPEC_VUZP1                201)
161    (UNSPEC_VUZP2                202)
162    (UNSPEC_VZIP1                203)
163    (UNSPEC_VZIP2                204)])
164
165 ;; Double-width vector modes.
166 (define_mode_macro VD [V8QI V4HI V2SI V2SF])
167
168 ;; Double-width vector modes plus 64-bit elements.
169 (define_mode_macro VDX [V8QI V4HI V2SI V2SF DI])
170
171 ;; Same, without floating-point elements.
172 (define_mode_macro VDI [V8QI V4HI V2SI])
173
174 ;; Quad-width vector modes.
175 (define_mode_macro VQ [V16QI V8HI V4SI V4SF])
176
177 ;; Quad-width vector modes plus 64-bit elements.
178 (define_mode_macro VQX [V16QI V8HI V4SI V4SF V2DI])
179
180 ;; Same, without floating-point elements.
181 (define_mode_macro VQI [V16QI V8HI V4SI])
182
183 ;; Same, with TImode added, for moves.
184 (define_mode_macro VQXMOV [V16QI V8HI V4SI V4SF V2DI TI])
185
186 ;; Opaque structure types wider than TImode.
187 (define_mode_macro VSTRUCT [EI OI CI XI])
188
189 ;; Number of instructions needed to load/store struct elements. FIXME!
190 (define_mode_attr V_slen [(EI "2") (OI "2") (CI "3") (XI "4")])
191
192 ;; Opaque structure types used in table lookups (except vtbl1/vtbx1).
193 (define_mode_macro VTAB [TI EI OI])
194
195 ;; vtbl<n> suffix for above modes.
196 (define_mode_attr VTAB_n [(TI "2") (EI "3") (OI "4")])
197
198 ;; Widenable modes.
199 (define_mode_macro VW [V8QI V4HI V2SI])
200
201 ;; Narrowable modes.
202 (define_mode_macro VN [V8HI V4SI V2DI])
203
204 ;; All supported vector modes (except singleton DImode).
205 (define_mode_macro VDQ [V8QI V16QI V4HI V8HI V2SI V4SI V2SF V4SF V2DI])
206
207 ;; All supported vector modes (except those with 64-bit integer elements).
208 (define_mode_macro VDQW [V8QI V16QI V4HI V8HI V2SI V4SI V2SF V4SF])
209
210 ;; Supported integer vector modes (not 64 bit elements).
211 (define_mode_macro VDQIW [V8QI V16QI V4HI V8HI V2SI V4SI])
212
213 ;; Supported integer vector modes (not singleton DI)
214 (define_mode_macro VDQI [V8QI V16QI V4HI V8HI V2SI V4SI V2DI])
215
216 ;; Vector modes, including 64-bit integer elements.
217 (define_mode_macro VDQX [V8QI V16QI V4HI V8HI V2SI V4SI V2SF V4SF DI V2DI])
218
219 ;; Vector modes including 64-bit integer elements, but no floats.
220 (define_mode_macro VDQIX [V8QI V16QI V4HI V8HI V2SI V4SI DI V2DI])
221
222 ;; Vector modes for float->int conversions.
223 (define_mode_macro VCVTF [V2SF V4SF])
224
225 ;; Vector modes form int->float conversions.
226 (define_mode_macro VCVTI [V2SI V4SI])
227
228 ;; Vector modes for doubleword multiply-accumulate, etc. insns.
229 (define_mode_macro VMD [V4HI V2SI V2SF])
230
231 ;; Vector modes for quadword multiply-accumulate, etc. insns.
232 (define_mode_macro VMQ [V8HI V4SI V4SF])
233
234 ;; Above modes combined.
235 (define_mode_macro VMDQ [V4HI V2SI V2SF V8HI V4SI V4SF])
236
237 ;; As VMD, but integer modes only.
238 (define_mode_macro VMDI [V4HI V2SI])
239
240 ;; As VMQ, but integer modes only.
241 (define_mode_macro VMQI [V8HI V4SI])
242
243 ;; Above modes combined.
244 (define_mode_macro VMDQI [V4HI V2SI V8HI V4SI])
245
246 ;; Modes with 8-bit and 16-bit elements.
247 (define_mode_macro VX [V8QI V4HI V16QI V8HI])
248
249 ;; Modes with 8-bit elements.
250 (define_mode_macro VE [V8QI V16QI])
251
252 ;; Modes with 64-bit elements only.
253 (define_mode_macro V64 [DI V2DI])
254
255 ;; Modes with 32-bit elements only.
256 (define_mode_macro V32 [V2SI V2SF V4SI V4SF])
257
258 ;; (Opposite) mode to convert to/from for above conversions.
259 (define_mode_attr V_CVTTO [(V2SI "V2SF") (V2SF "V2SI")
260                            (V4SI "V4SF") (V4SF "V4SI")])
261
262 ;; Define element mode for each vector mode.
263 (define_mode_attr V_elem [(V8QI "QI") (V16QI "QI")
264                           (V4HI "HI") (V8HI "HI")
265                           (V2SI "SI") (V4SI "SI")
266                           (V2SF "SF") (V4SF "SF")
267                           (DI "DI")   (V2DI "DI")])
268
269 ;; Mode of pair of elements for each vector mode, to define transfer
270 ;; size for structure lane/dup loads and stores.
271 (define_mode_attr V_two_elem [(V8QI "HI") (V16QI "HI")
272                               (V4HI "SI") (V8HI "SI")
273                               (V2SI "V2SI") (V4SI "V2SI")
274                               (V2SF "V2SF") (V4SF "V2SF")
275                               (DI "V2DI")   (V2DI "V2DI")])
276
277 ;; Similar, for three elements.
278 ;; ??? Should we define extra modes so that sizes of all three-element
279 ;; accesses can be accurately represented?
280 (define_mode_attr V_three_elem [(V8QI "SI")   (V16QI "SI")
281                                 (V4HI "V4HI") (V8HI "V4HI")
282                                 (V2SI "V4SI") (V4SI "V4SI")
283                                 (V2SF "V4SF") (V4SF "V4SF")
284                                 (DI "EI")     (V2DI "EI")])
285
286 ;; Similar, for four elements.
287 (define_mode_attr V_four_elem [(V8QI "SI")   (V16QI "SI")
288                                (V4HI "V4HI") (V8HI "V4HI")
289                                (V2SI "V4SI") (V4SI "V4SI")
290                                (V2SF "V4SF") (V4SF "V4SF")
291                                (DI "OI")     (V2DI "OI")])
292
293 ;; Register width from element mode
294 (define_mode_attr V_reg [(V8QI "P") (V16QI "q")
295                          (V4HI "P") (V8HI  "q")
296                          (V2SI "P") (V4SI  "q")
297                          (V2SF "P") (V4SF  "q")
298                          (DI   "P") (V2DI  "q")])
299
300 ;; Wider modes with the same number of elements.
301 (define_mode_attr V_widen [(V8QI "V8HI") (V4HI "V4SI") (V2SI "V2DI")])
302
303 ;; Narrower modes with the same number of elements.
304 (define_mode_attr V_narrow [(V8HI "V8QI") (V4SI "V4HI") (V2DI "V2SI")])
305
306 ;; Modes with half the number of equal-sized elements.
307 (define_mode_attr V_HALF [(V16QI "V8QI") (V8HI "V4HI")
308                           (V4SI  "V2SI") (V4SF "V2SF")
309                           (V2DI "DI")])
310
311 ;; Same, but lower-case.
312 (define_mode_attr V_half [(V16QI "v8qi") (V8HI "v4hi")
313                           (V4SI  "v2si") (V4SF "v2sf")
314                           (V2DI "di")])
315
316 ;; Modes with twice the number of equal-sized elements.
317 (define_mode_attr V_DOUBLE [(V8QI "V16QI") (V4HI "V8HI")
318                             (V2SI "V4SI") (V2SF "V4SF")
319                             (DI "V2DI")])
320
321 ;; Same, but lower-case.
322 (define_mode_attr V_double [(V8QI "v16qi") (V4HI "v8hi")
323                             (V2SI "v4si") (V2SF "v4sf")
324                             (DI "v2di")])
325
326 ;; Modes with double-width elements.
327 (define_mode_attr V_double_width [(V8QI "V4HI") (V16QI "V8HI")
328                                   (V4HI "V2SI") (V8HI "V4SI")
329                                   (V2SI "DI")   (V4SI "V2DI")])
330
331 ;; Mode of result of comparison operations (and bit-select operand 1).
332 (define_mode_attr V_cmp_result [(V8QI "V8QI") (V16QI "V16QI")
333                                 (V4HI "V4HI") (V8HI  "V8HI")
334                                 (V2SI "V2SI") (V4SI  "V4SI")
335                                 (V2SF "V2SI") (V4SF  "V4SI")
336                                 (DI   "DI")   (V2DI  "V2DI")])
337
338 ;; Get element type from double-width mode, for operations where we don't care
339 ;; about signedness.
340 (define_mode_attr V_if_elem [(V8QI "i8")  (V16QI "i8")
341                              (V4HI "i16") (V8HI  "i16")
342                              (V2SI "i32") (V4SI  "i32")
343                              (DI   "i64") (V2DI  "i64")
344                              (V2SF "f32") (V4SF  "f32")])
345
346 ;; Same, but for operations which work on signed values.
347 (define_mode_attr V_s_elem [(V8QI "s8")  (V16QI "s8")
348                             (V4HI "s16") (V8HI  "s16")
349                             (V2SI "s32") (V4SI  "s32")
350                             (DI   "s64") (V2DI  "s64")
351                             (V2SF "f32") (V4SF  "f32")])
352
353 ;; Same, but for operations which work on unsigned values.
354 (define_mode_attr V_u_elem [(V8QI "u8")  (V16QI "u8")
355                             (V4HI "u16") (V8HI  "u16")
356                             (V2SI "u32") (V4SI  "u32")
357                             (DI   "u64") (V2DI  "u64")
358                             (V2SF "f32") (V4SF  "f32")])
359
360 ;; Element types for extraction of unsigned scalars.
361 (define_mode_attr V_uf_sclr [(V8QI "u8")  (V16QI "u8")
362                              (V4HI "u16") (V8HI "u16")
363                              (V2SI "32") (V4SI "32")
364                              (V2SF "32") (V4SF "32")])
365
366 (define_mode_attr V_sz_elem [(V8QI "8")  (V16QI "8")
367                              (V4HI "16") (V8HI  "16")
368                              (V2SI "32") (V4SI  "32")
369                              (DI   "64") (V2DI  "64")
370                              (V2SF "32") (V4SF  "32")])
371
372 ;; Element sizes for duplicating ARM registers to all elements of a vector.
373 (define_mode_attr VD_dup [(V8QI "8") (V4HI "16") (V2SI "32") (V2SF "32")])
374
375 ;; Opaque integer types for results of pair-forming intrinsics (vtrn, etc.)
376 (define_mode_attr V_PAIR [(V8QI "TI") (V16QI "OI")
377                           (V4HI "TI") (V8HI  "OI")
378                           (V2SI "TI") (V4SI  "OI")
379                           (V2SF "TI") (V4SF  "OI")
380                           (DI   "TI") (V2DI  "OI")])
381
382 ;; Same, but lower-case.
383 (define_mode_attr V_pair [(V8QI "ti") (V16QI "oi")
384                           (V4HI "ti") (V8HI  "oi")
385                           (V2SI "ti") (V4SI  "oi")
386                           (V2SF "ti") (V4SF  "oi")
387                           (DI   "ti") (V2DI  "oi")])
388
389 ;; Operations on two halves of a quadword vector.
390 (define_code_macro vqh_ops [plus smin smax umin umax])
391
392 ;; Same, without unsigned variants (for use with *SFmode pattern).
393 (define_code_macro vqhs_ops [plus smin smax])
394
395 ;; Assembler mnemonics for above codes.
396 (define_code_attr VQH_mnem [(plus "vadd") (smin "vmin") (smax "vmax")
397                             (umin "vmin") (umax "vmax")])
398
399 ;; Signs of above, where relevant.
400 (define_code_attr VQH_sign [(plus "i") (smin "s") (smax "s") (umin "u")
401                             (umax "u")])
402
403 ;; Extra suffix on some 64-bit insn names (to avoid collision with standard
404 ;; names which we don't want to define).
405 (define_mode_attr V_suf64 [(V8QI "") (V16QI "")
406                            (V4HI "") (V8HI "")
407                            (V2SI "") (V4SI "")
408                            (V2SF "") (V4SF "")
409                            (DI "_neon") (V2DI "")])
410
411 ;; Scalars to be presented to scalar multiplication instructions
412 ;; must satisfy the following constraints.
413 ;; 1. If the mode specifies 16-bit elements, the scalar must be in D0-D7.
414 ;; 2. If the mode specifies 32-bit elements, the scalar must be in D0-D15.
415 ;; This mode attribute is used to obtain the correct register constraints.
416 (define_mode_attr scalar_mul_constraint [(V4HI "x") (V2SI "t") (V2SF "t")
417                                          (V8HI "x") (V4SI "t") (V4SF "t")])
418
419 (define_insn "*neon_mov<mode>"
420   [(set (match_operand:VD 0 "nonimmediate_operand"
421           "=w,Uv,w, w,  ?r,?w,?r,?r, ?Us")
422         (match_operand:VD 1 "general_operand"
423           " w,w, Dn,Uvi, w, r, r, Usi,r"))]
424   "TARGET_NEON"
425 {
426   if (which_alternative == 2)
427     {
428       int width, is_valid;
429       static char templ[40];
430
431       is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
432         &operands[1], &width);
433
434       gcc_assert (is_valid != 0);
435
436       if (width == 0)
437         return "vmov.f32\t%P0, %1  @ <mode>";
438       else
439         sprintf (templ, "vmov.i%d\t%%P0, %%1  @ <mode>", width);
440
441       return templ;
442     }
443
444   /* FIXME: If the memory layout is changed in big-endian mode, output_move_vfp
445      below must be changed to output_move_neon (which will use the
446      element/structure loads/stores), and the constraint changed to 'Un' instead
447      of 'Uv'.  */
448
449   switch (which_alternative)
450     {
451     case 0: return "vmov\t%P0, %P1  @ <mode>";
452     case 1: case 3: return output_move_vfp (operands);
453     case 2: gcc_unreachable ();
454     case 4: return "vmov\t%Q0, %R0, %P1  @ <mode>";
455     case 5: return "vmov\t%P0, %Q1, %R1  @ <mode>";
456     default: return output_move_double (operands);
457     }
458 }
459   [(set_attr "type" "farith,f_stored,farith,f_loadd,f_2_r,r_2_f,*,load2,store2")
460    (set_attr "length" "4,4,4,4,4,4,8,8,8")
461    (set_attr "pool_range"     "*,*,*,1020,*,*,*,1020,*")
462    (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
463
464 (define_insn "*neon_mov<mode>"
465   [(set (match_operand:VQXMOV 0 "nonimmediate_operand"
466           "=w,Un,w, w,  ?r,?w,?r,?r,  ?Us")
467         (match_operand:VQXMOV 1 "general_operand"
468           " w,w, Dn,Uni, w, r, r, Usi, r"))]
469   "TARGET_NEON"
470 {
471   if (which_alternative == 2)
472     {
473       int width, is_valid;
474       static char templ[40];
475
476       is_valid = neon_immediate_valid_for_move (operands[1], <MODE>mode,
477         &operands[1], &width);
478
479       gcc_assert (is_valid != 0);
480
481       if (width == 0)
482         return "vmov.f32\t%q0, %1  @ <mode>";
483       else
484         sprintf (templ, "vmov.i%d\t%%q0, %%1  @ <mode>", width);
485
486       return templ;
487     }
488
489   switch (which_alternative)
490     {
491     case 0: return "vmov\t%q0, %q1  @ <mode>";
492     case 1: case 3: return output_move_neon (operands);
493     case 2: gcc_unreachable ();
494     case 4: return "vmov\t%Q0, %R0, %e1  @ <mode>\;vmov\t%J0, %K0, %f1";
495     case 5: return "vmov\t%e0, %Q1, %R1  @ <mode>\;vmov\t%f0, %J1, %K1";
496     default: return output_move_quad (operands);
497     }
498 }
499   [(set_attr "type" "farith,f_stored,farith,f_loadd,f_2_r,r_2_f,*,load2,store2")
500    (set_attr "length" "4,8,4,8,8,8,16,8,16")
501    (set_attr "pool_range" "*,*,*,1020,*,*,*,1020,*")
502    (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
503
504 (define_expand "movti"
505   [(set (match_operand:TI 0 "nonimmediate_operand" "")
506         (match_operand:TI 1 "general_operand" ""))]
507   "TARGET_NEON"
508 {
509 })
510
511 (define_expand "mov<mode>"
512   [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "")
513         (match_operand:VSTRUCT 1 "general_operand" ""))]
514   "TARGET_NEON"
515 {
516 })
517
518 (define_insn "*neon_mov<mode>"
519   [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "=w,Ut,w")
520         (match_operand:VSTRUCT 1 "general_operand"      " w,w, Ut"))]
521   "TARGET_NEON"
522 {
523   switch (which_alternative)
524     {
525     case 0: return "#";
526     case 1: case 2: return output_move_neon (operands);
527     default: gcc_unreachable ();
528     }
529 }
530   [(set_attr "length" "<V_slen>,<V_slen>,<V_slen>")])
531
532 (define_split
533   [(set (match_operand:EI 0 "s_register_operand" "")
534         (match_operand:EI 1 "s_register_operand" ""))]
535   "TARGET_NEON && reload_completed"
536   [(set (match_dup 0) (match_dup 1))
537    (set (match_dup 2) (match_dup 3))]
538 {
539   int rdest = REGNO (operands[0]);
540   int rsrc = REGNO (operands[1]);
541   rtx dest[2], src[2];
542
543   dest[0] = gen_rtx_REG (TImode, rdest);
544   src[0] = gen_rtx_REG (TImode, rsrc);
545   dest[1] = gen_rtx_REG (DImode, rdest + 4);
546   src[1] = gen_rtx_REG (DImode, rsrc + 4);
547
548   neon_disambiguate_copy (operands, dest, src, 2);
549 })
550
551 (define_split
552   [(set (match_operand:OI 0 "s_register_operand" "")
553         (match_operand:OI 1 "s_register_operand" ""))]
554   "TARGET_NEON && reload_completed"
555   [(set (match_dup 0) (match_dup 1))
556    (set (match_dup 2) (match_dup 3))]
557 {
558   int rdest = REGNO (operands[0]);
559   int rsrc = REGNO (operands[1]);
560   rtx dest[2], src[2];
561
562   dest[0] = gen_rtx_REG (TImode, rdest);
563   src[0] = gen_rtx_REG (TImode, rsrc);
564   dest[1] = gen_rtx_REG (TImode, rdest + 4);
565   src[1] = gen_rtx_REG (TImode, rsrc + 4);
566
567   neon_disambiguate_copy (operands, dest, src, 2);
568 })
569
570 (define_split
571   [(set (match_operand:CI 0 "s_register_operand" "")
572         (match_operand:CI 1 "s_register_operand" ""))]
573   "TARGET_NEON && reload_completed"
574   [(set (match_dup 0) (match_dup 1))
575    (set (match_dup 2) (match_dup 3))
576    (set (match_dup 4) (match_dup 5))]
577 {
578   int rdest = REGNO (operands[0]);
579   int rsrc = REGNO (operands[1]);
580   rtx dest[3], src[3];
581
582   dest[0] = gen_rtx_REG (TImode, rdest);
583   src[0] = gen_rtx_REG (TImode, rsrc);
584   dest[1] = gen_rtx_REG (TImode, rdest + 4);
585   src[1] = gen_rtx_REG (TImode, rsrc + 4);
586   dest[2] = gen_rtx_REG (TImode, rdest + 8);
587   src[2] = gen_rtx_REG (TImode, rsrc + 8);
588
589   neon_disambiguate_copy (operands, dest, src, 3);
590 })
591
592 (define_split
593   [(set (match_operand:XI 0 "s_register_operand" "")
594         (match_operand:XI 1 "s_register_operand" ""))]
595   "TARGET_NEON && reload_completed"
596   [(set (match_dup 0) (match_dup 1))
597    (set (match_dup 2) (match_dup 3))
598    (set (match_dup 4) (match_dup 5))
599    (set (match_dup 6) (match_dup 7))]
600 {
601   int rdest = REGNO (operands[0]);
602   int rsrc = REGNO (operands[1]);
603   rtx dest[4], src[4];
604
605   dest[0] = gen_rtx_REG (TImode, rdest);
606   src[0] = gen_rtx_REG (TImode, rsrc);
607   dest[1] = gen_rtx_REG (TImode, rdest + 4);
608   src[1] = gen_rtx_REG (TImode, rsrc + 4);
609   dest[2] = gen_rtx_REG (TImode, rdest + 8);
610   src[2] = gen_rtx_REG (TImode, rsrc + 8);
611   dest[3] = gen_rtx_REG (TImode, rdest + 12);
612   src[3] = gen_rtx_REG (TImode, rsrc + 12);
613
614   neon_disambiguate_copy (operands, dest, src, 4);
615 })
616
617 (define_insn "vec_set<mode>"
618   [(set (match_operand:VD 0 "s_register_operand" "+w")
619         (vec_merge:VD
620           (match_operand:VD 3 "s_register_operand" "0")
621           (vec_duplicate:VD
622             (match_operand:<V_elem> 1 "s_register_operand" "r"))
623           (ashift:SI (const_int 1)
624                      (match_operand:SI 2 "immediate_operand" "i"))))]
625   "TARGET_NEON"
626   "vmov%?.<V_uf_sclr>\t%P0[%c2], %1"
627   [(set_attr "predicable" "yes")])
628
629 (define_insn "vec_set<mode>"
630   [(set (match_operand:VQ 0 "s_register_operand" "+w")
631         (vec_merge:VQ
632           (match_operand:VQ 3 "s_register_operand" "0")
633           (vec_duplicate:VQ
634             (match_operand:<V_elem> 1 "s_register_operand" "r"))
635           (ashift:SI (const_int 1)
636                      (match_operand:SI 2 "immediate_operand" "i"))))]
637   "TARGET_NEON"
638 {
639   int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
640   int elt = INTVAL (operands[2]) % half_elts;
641   int hi = (INTVAL (operands[2]) / half_elts) * 2;
642   int regno = REGNO (operands[0]);
643
644   operands[0] = gen_rtx_REG (<V_HALF>mode, regno + hi);
645   operands[2] = GEN_INT (elt);
646
647   return "vmov%?.<V_uf_sclr>\t%P0[%c2], %1";
648 }
649   [(set_attr "predicable" "yes")])
650
651 (define_insn "vec_setv2di"
652   [(set (match_operand:V2DI 0 "s_register_operand" "+w")
653         (vec_merge:V2DI
654           (match_operand:V2DI 3 "s_register_operand" "0")
655           (vec_duplicate:V2DI
656             (match_operand:DI 1 "s_register_operand" "r"))
657           (ashift:SI (const_int 1)
658                      (match_operand:SI 2 "immediate_operand" "i"))))]
659   "TARGET_NEON"
660 {
661   int regno = REGNO (operands[0]) + INTVAL (operands[2]);
662
663   operands[0] = gen_rtx_REG (DImode, regno);
664
665   return "vmov%?.64\t%P0, %Q1, %R1";
666 }
667   [(set_attr "predicable" "yes")])
668
669 (define_insn "vec_extract<mode>"
670   [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
671         (vec_select:<V_elem>
672           (match_operand:VD 1 "s_register_operand" "w")
673           (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
674   "TARGET_NEON"
675   "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]"
676   [(set_attr "predicable" "yes")])
677
678 (define_insn "vec_extract<mode>"
679   [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
680         (vec_select:<V_elem>
681           (match_operand:VQ 1 "s_register_operand" "w")
682           (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
683   "TARGET_NEON"
684 {
685   int half_elts = GET_MODE_NUNITS (<MODE>mode) / 2;
686   int elt = INTVAL (operands[2]) % half_elts;
687   int hi = (INTVAL (operands[2]) / half_elts) * 2;
688   int regno = REGNO (operands[1]);
689
690   operands[1] = gen_rtx_REG (<V_HALF>mode, regno + hi);
691   operands[2] = GEN_INT (elt);
692
693   return "vmov%?.<V_uf_sclr>\t%0, %P1[%c2]";
694 }
695   [(set_attr "predicable" "yes")])
696
697 (define_insn "vec_extractv2di"
698   [(set (match_operand:DI 0 "s_register_operand" "=r")
699         (vec_select:DI
700           (match_operand:V2DI 1 "s_register_operand" "w")
701           (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
702   "TARGET_NEON"
703 {
704   int regno = REGNO (operands[1]) + INTVAL (operands[2]);
705
706   operands[1] = gen_rtx_REG (DImode, regno);
707
708   return "vmov%?.64\t%Q0, %R0, %P1";
709 }
710   [(set_attr "predicable" "yes")])
711
712 (define_expand "vec_init<mode>"
713   [(match_operand:VDQ 0 "s_register_operand" "")
714    (match_operand 1 "" "")]
715   "TARGET_NEON"
716 {
717   neon_expand_vector_init (operands[0], operands[1]);
718   DONE;
719 })
720
721 ;; Doubleword and quadword arithmetic.
722
723 ;; NOTE: vadd/vsub and some other instructions also support 64-bit integer
724 ;; element size, which we could potentially use for "long long" operations. We
725 ;; don't want to do this at present though, because moving values from the
726 ;; vector unit to the ARM core is currently slow and 64-bit addition (etc.) is
727 ;; easy to do with ARM instructions anyway.
728
729 (define_insn "*add<mode>3_neon"
730   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
731         (plus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
732                   (match_operand:VDQ 2 "s_register_operand" "w")))]
733   "TARGET_NEON"
734   "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
735
736 (define_insn "*sub<mode>3_neon"
737   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
738         (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
739                    (match_operand:VDQ 2 "s_register_operand" "w")))]
740   "TARGET_NEON"
741   "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
742
743 (define_insn "*mul<mode>3_neon"
744   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
745         (mult:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
746                   (match_operand:VDQ 2 "s_register_operand" "w")))]
747   "TARGET_NEON"
748   "vmul.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
749
750 (define_insn "ior<mode>3"
751   [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
752         (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
753                  (match_operand:VDQ 2 "neon_logic_op2" "w,Dl")))]
754   "TARGET_NEON"
755 {
756   switch (which_alternative)
757     {
758     case 0: return "vorr\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
759     case 1: return neon_output_logic_immediate ("vorr", &operands[2],
760                      <MODE>mode, 0, VALID_NEON_QREG_MODE (<MODE>mode));
761     default: gcc_unreachable ();
762     }
763 })
764
765 (define_insn "iordi3_neon"
766   [(set (match_operand:DI 0 "s_register_operand" "=w,w")
767         (unspec:DI [(match_operand:DI 1 "s_register_operand" "w,0")
768                     (match_operand:DI 2 "neon_logic_op2" "w,Dl")]
769                     UNSPEC_VORR))]
770   "TARGET_NEON"
771 {
772   switch (which_alternative)
773     {
774     case 0: return "vorr\t%P0, %P1, %P2";
775     case 1: return neon_output_logic_immediate ("vorr", &operands[2],
776                      DImode, 0, VALID_NEON_QREG_MODE (DImode));
777     default: gcc_unreachable ();
778     }
779 })
780
781 ;; The concrete forms of the Neon immediate-logic instructions are vbic and
782 ;; vorr. We support the pseudo-instruction vand instead, because that
783 ;; corresponds to the canonical form the middle-end expects to use for
784 ;; immediate bitwise-ANDs.
785
786 (define_insn "and<mode>3"
787   [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
788         (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
789                  (match_operand:VDQ 2 "neon_inv_logic_op2" "w,DL")))]
790   "TARGET_NEON"
791 {
792   switch (which_alternative)
793     {
794     case 0: return "vand\t%<V_reg>0, %<V_reg>1, %<V_reg>2";
795     case 1: return neon_output_logic_immediate ("vand", &operands[2],
796                      <MODE>mode, 1, VALID_NEON_QREG_MODE (<MODE>mode));
797     default: gcc_unreachable ();
798     }
799 })
800
801 (define_insn "anddi3_neon"
802   [(set (match_operand:DI 0 "s_register_operand" "=w,w")
803         (unspec:DI [(match_operand:DI 1 "s_register_operand" "w,0")
804                     (match_operand:DI 2 "neon_inv_logic_op2" "w,DL")]
805                     UNSPEC_VAND))]
806   "TARGET_NEON"
807 {
808   switch (which_alternative)
809     {
810     case 0: return "vand\t%P0, %P1, %P2";
811     case 1: return neon_output_logic_immediate ("vand", &operands[2],
812                      DImode, 1, VALID_NEON_QREG_MODE (DImode));
813     default: gcc_unreachable ();
814     }
815 })
816
817 (define_insn "orn<mode>3_neon"
818   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
819         (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
820                  (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
821   "TARGET_NEON"
822   "vorn\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
823
824 (define_insn "orndi3_neon"
825   [(set (match_operand:DI 0 "s_register_operand" "=w")
826         (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
827                     (match_operand:DI 2 "s_register_operand" "w")]
828                     UNSPEC_VORN))]
829   "TARGET_NEON"
830   "vorn\t%P0, %P1, %P2")
831
832 (define_insn "bic<mode>3_neon"
833   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
834         (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
835                   (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
836   "TARGET_NEON"
837   "vbic\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
838
839 (define_insn "bicdi3_neon"
840   [(set (match_operand:DI 0 "s_register_operand" "=w")
841         (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
842                      (match_operand:DI 2 "s_register_operand" "w")]
843                     UNSPEC_VBIC))]
844   "TARGET_NEON"
845   "vbic\t%P0, %P1, %P2")
846
847 (define_insn "xor<mode>3"
848   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
849         (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
850                  (match_operand:VDQ 2 "s_register_operand" "w")))]
851   "TARGET_NEON"
852   "veor\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
853
854 (define_insn "xordi3_neon"
855   [(set (match_operand:DI 0 "s_register_operand" "=w")
856         (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
857                      (match_operand:DI 2 "s_register_operand" "w")]
858                     UNSPEC_VEOR))]
859   "TARGET_NEON"
860   "veor\t%P0, %P1, %P2")
861
862 (define_insn "one_cmpl<mode>2"
863   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
864         (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))]
865   "TARGET_NEON"
866   "vmvn\t%<V_reg>0, %<V_reg>1")
867
868 (define_insn "abs<mode>2"
869   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
870         (abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
871   "TARGET_NEON"
872   "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1")
873
874 (define_insn "neg<mode>2"
875   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
876         (neg:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
877   "TARGET_NEON"
878   "vneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1")
879
880 (define_insn "*umin<mode>3_neon"
881   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
882         (umin:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
883                     (match_operand:VDQIW 2 "s_register_operand" "w")))]
884   "TARGET_NEON"
885   "vmin.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
886
887 (define_insn "*umax<mode>3_neon"
888   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
889         (umax:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
890                     (match_operand:VDQIW 2 "s_register_operand" "w")))]
891   "TARGET_NEON"
892   "vmax.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
893
894 (define_insn "*smin<mode>3_neon"
895   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
896         (smin:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
897                    (match_operand:VDQW 2 "s_register_operand" "w")))]
898   "TARGET_NEON"
899   "vmin.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
900
901 (define_insn "*smax<mode>3_neon"
902   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
903         (smax:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
904                    (match_operand:VDQW 2 "s_register_operand" "w")))]
905   "TARGET_NEON"
906   "vmax.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
907
908 ; TODO: V2DI shifts are current disabled because there are bugs in the
909 ; generic vectorizer code.  It ends up creating a V2DI constructor with
910 ; SImode elements.
911
912 (define_insn "ashl<mode>3"
913   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
914         (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
915                       (match_operand:VDQIW 2 "s_register_operand" "w")))]
916   "TARGET_NEON"
917   "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
918
919 ; Used for implementing logical shift-right, which is a left-shift by a negative
920 ; amount, with signed operands. This is essentially the same as ashl<mode>3
921 ; above, but using an unspec in case GCC tries anything tricky with negative
922 ; shift amounts.
923
924 (define_insn "ashl<mode>3_signed"
925   [(set (match_operand:VDQI 0 "s_register_operand" "=w")
926         (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
927                       (match_operand:VDQI 2 "s_register_operand" "w")]
928                      UNSPEC_ASHIFT_SIGNED))]
929   "TARGET_NEON"
930   "vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
931
932 ; Used for implementing logical shift-right, which is a left-shift by a negative
933 ; amount, with unsigned operands.
934
935 (define_insn "ashl<mode>3_unsigned"
936   [(set (match_operand:VDQI 0 "s_register_operand" "=w")
937         (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
938                       (match_operand:VDQI 2 "s_register_operand" "w")]
939                      UNSPEC_ASHIFT_UNSIGNED))]
940   "TARGET_NEON"
941   "vshl.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
942
943 (define_expand "ashr<mode>3"
944   [(set (match_operand:VDQIW 0 "s_register_operand" "")
945         (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
946                         (match_operand:VDQIW 2 "s_register_operand" "")))]
947   "TARGET_NEON"
948 {
949   rtx neg = gen_reg_rtx (<MODE>mode);
950
951   emit_insn (gen_neg<mode>2 (neg, operands[2]));
952   emit_insn (gen_ashl<mode>3_signed (operands[0], operands[1], neg));
953
954   DONE;
955 })
956
957 (define_expand "lshr<mode>3"
958   [(set (match_operand:VDQIW 0 "s_register_operand" "")
959         (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
960                         (match_operand:VDQIW 2 "s_register_operand" "")))]
961   "TARGET_NEON"
962 {
963   rtx neg = gen_reg_rtx (<MODE>mode);
964
965   emit_insn (gen_neg<mode>2 (neg, operands[2]));
966   emit_insn (gen_ashl<mode>3_unsigned (operands[0], operands[1], neg));
967
968   DONE;
969 })
970
971 ;; Widening operations
972
973 (define_insn "widen_ssum<mode>3"
974   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
975         (plus:<V_widen> (sign_extend:<V_widen>
976                           (match_operand:VW 1 "s_register_operand" "%w"))
977                         (match_operand:<V_widen> 2 "s_register_operand" "w")))]
978   "TARGET_NEON"
979   "vaddw.<V_s_elem>\t%q0, %q2, %P1")
980
981 (define_insn "widen_usum<mode>3"
982   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
983         (plus:<V_widen> (zero_extend:<V_widen>
984                           (match_operand:VW 1 "s_register_operand" "%w"))
985                         (match_operand:<V_widen> 2 "s_register_operand" "w")))]
986   "TARGET_NEON"
987   "vaddw.<V_u_elem>\t%q0, %q2, %P1")
988
989 ;; VEXT can be used to synthesize coarse whole-vector shifts with 8-bit
990 ;; shift-count granularity. That's good enough for the middle-end's current
991 ;; needs.
992
993 (define_expand "vec_shr_<mode>"
994   [(match_operand:VDQ 0 "s_register_operand" "")
995    (match_operand:VDQ 1 "s_register_operand" "")
996    (match_operand:SI 2 "const_multiple_of_8_operand" "")]
997   "TARGET_NEON"
998 {
999   rtx zero_reg;
1000   HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1001   const int width = GET_MODE_BITSIZE (<MODE>mode);
1002   const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1003   rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1004     (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1005
1006   if (num_bits == width)
1007     {
1008       emit_move_insn (operands[0], operands[1]);
1009       DONE;
1010     }
1011
1012   zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1013   operands[0] = gen_lowpart (bvecmode, operands[0]);
1014   operands[1] = gen_lowpart (bvecmode, operands[1]);
1015
1016   emit_insn (gen_ext (operands[0], operands[1], zero_reg,
1017                       GEN_INT (num_bits / BITS_PER_UNIT)));
1018   DONE;
1019 })
1020
1021 (define_expand "vec_shl_<mode>"
1022   [(match_operand:VDQ 0 "s_register_operand" "")
1023    (match_operand:VDQ 1 "s_register_operand" "")
1024    (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1025   "TARGET_NEON"
1026 {
1027   rtx zero_reg;
1028   HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1029   const int width = GET_MODE_BITSIZE (<MODE>mode);
1030   const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1031   rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1032     (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1033
1034   if (num_bits == 0)
1035     {
1036       emit_move_insn (operands[0], CONST0_RTX (<MODE>mode));
1037       DONE;
1038     }
1039
1040   num_bits = width - num_bits;
1041
1042   zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1043   operands[0] = gen_lowpart (bvecmode, operands[0]);
1044   operands[1] = gen_lowpart (bvecmode, operands[1]);
1045
1046   emit_insn (gen_ext (operands[0], zero_reg, operands[1],
1047                       GEN_INT (num_bits / BITS_PER_UNIT)));
1048   DONE;
1049 })
1050
1051 ;; Helpers for quad-word reduction operations
1052
1053 ; Add (or smin, smax...) the low N/2 elements of the N-element vector
1054 ; operand[1] to the high N/2 elements of same. Put the result in operand[0], an
1055 ; N/2-element vector.
1056
1057 (define_insn "quad_halves_<code>v4si"
1058   [(set (match_operand:V2SI 0 "s_register_operand" "=w")
1059         (vqh_ops:V2SI
1060           (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
1061                            (parallel [(const_int 0) (const_int 1)]))
1062           (vec_select:V2SI (match_dup 1)
1063                            (parallel [(const_int 2) (const_int 3)]))))]
1064   "TARGET_NEON"
1065   "<VQH_mnem>.<VQH_sign>32\t%P0, %e1, %f1")
1066
1067 (define_insn "quad_halves_<code>v4sf"
1068   [(set (match_operand:V2SF 0 "s_register_operand" "=w")
1069         (vqhs_ops:V2SF
1070           (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
1071                            (parallel [(const_int 0) (const_int 1)]))
1072           (vec_select:V2SF (match_dup 1)
1073                            (parallel [(const_int 2) (const_int 3)]))))]
1074   "TARGET_NEON"
1075   "<VQH_mnem>.f32\t%P0, %e1, %f1")
1076
1077 (define_insn "quad_halves_<code>v8hi"
1078   [(set (match_operand:V4HI 0 "s_register_operand" "+w")
1079         (vqh_ops:V4HI
1080           (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
1081                            (parallel [(const_int 0) (const_int 1)
1082                                       (const_int 2) (const_int 3)]))
1083           (vec_select:V4HI (match_dup 1)
1084                            (parallel [(const_int 4) (const_int 5)
1085                                       (const_int 6) (const_int 7)]))))]
1086   "TARGET_NEON"
1087   "<VQH_mnem>.<VQH_sign>16\t%P0, %e1, %f1")
1088
1089 (define_insn "quad_halves_<code>v16qi"
1090   [(set (match_operand:V8QI 0 "s_register_operand" "+w")
1091         (vqh_ops:V8QI
1092           (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
1093                            (parallel [(const_int 0) (const_int 1)
1094                                       (const_int 2) (const_int 3)
1095                                       (const_int 4) (const_int 5)
1096                                       (const_int 6) (const_int 7)]))
1097           (vec_select:V8QI (match_dup 1)
1098                            (parallel [(const_int 8) (const_int 9)
1099                                       (const_int 10) (const_int 11)
1100                                       (const_int 12) (const_int 13)
1101                                       (const_int 14) (const_int 15)]))))]
1102   "TARGET_NEON"
1103   "<VQH_mnem>.<VQH_sign>8\t%P0, %e1, %f1")
1104
1105 ; FIXME: We wouldn't need the following insns if we could write subregs of
1106 ; vector registers. Make an attempt at removing unnecessary moves, though
1107 ; we're really at the mercy of the register allocator.
1108
1109 (define_insn "move_lo_quad_v4si"
1110   [(set (match_operand:V4SI 0 "s_register_operand" "+w")
1111         (vec_concat:V4SI
1112           (match_operand:V2SI 1 "s_register_operand" "w")
1113           (vec_select:V2SI (match_dup 0)
1114                            (parallel [(const_int 2) (const_int 3)]))))]
1115   "TARGET_NEON"
1116 {
1117   int dest = REGNO (operands[0]);
1118   int src = REGNO (operands[1]);
1119
1120   if (dest != src)
1121     return "vmov\t%e0, %P1";
1122   else
1123     return "";
1124 })
1125
1126 (define_insn "move_lo_quad_v4sf"
1127   [(set (match_operand:V4SF 0 "s_register_operand" "+w")
1128         (vec_concat:V4SF
1129           (match_operand:V2SF 1 "s_register_operand" "w")
1130           (vec_select:V2SF (match_dup 0)
1131                            (parallel [(const_int 2) (const_int 3)]))))]
1132   "TARGET_NEON"
1133 {
1134   int dest = REGNO (operands[0]);
1135   int src = REGNO (operands[1]);
1136
1137   if (dest != src)
1138     return "vmov\t%e0, %P1";
1139   else
1140     return "";
1141 })
1142
1143 (define_insn "move_lo_quad_v8hi"
1144   [(set (match_operand:V8HI 0 "s_register_operand" "+w")
1145         (vec_concat:V8HI
1146           (match_operand:V4HI 1 "s_register_operand" "w")
1147           (vec_select:V4HI (match_dup 0)
1148                            (parallel [(const_int 4) (const_int 5)
1149                                       (const_int 6) (const_int 7)]))))]
1150   "TARGET_NEON"
1151 {
1152   int dest = REGNO (operands[0]);
1153   int src = REGNO (operands[1]);
1154
1155   if (dest != src)
1156     return "vmov\t%e0, %P1";
1157   else
1158     return "";
1159 })
1160
1161 (define_insn "move_lo_quad_v16qi"
1162   [(set (match_operand:V16QI 0 "s_register_operand" "+w")
1163         (vec_concat:V16QI
1164           (match_operand:V8QI 1 "s_register_operand" "w")
1165           (vec_select:V8QI (match_dup 0)
1166                            (parallel [(const_int 8)  (const_int 9)
1167                                       (const_int 10) (const_int 11)
1168                                       (const_int 12) (const_int 13)
1169                                       (const_int 14) (const_int 15)]))))]
1170   "TARGET_NEON"
1171 {
1172   int dest = REGNO (operands[0]);
1173   int src = REGNO (operands[1]);
1174
1175   if (dest != src)
1176     return "vmov\t%e0, %P1";
1177   else
1178     return "";
1179 })
1180
1181 ;; Reduction operations
1182
1183 (define_expand "reduc_splus_<mode>"
1184   [(match_operand:VD 0 "s_register_operand" "")
1185    (match_operand:VD 1 "s_register_operand" "")]
1186   "TARGET_NEON"
1187 {
1188   neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1189                         &gen_neon_vpadd_internal<mode>);
1190   DONE;
1191 })
1192
1193 (define_expand "reduc_splus_<mode>"
1194   [(match_operand:VQ 0 "s_register_operand" "")
1195    (match_operand:VQ 1 "s_register_operand" "")]
1196   "TARGET_NEON"
1197 {
1198   rtx step1 = gen_reg_rtx (<V_HALF>mode);
1199   rtx res_d = gen_reg_rtx (<V_HALF>mode);
1200
1201   emit_insn (gen_quad_halves_plus<mode> (step1, operands[1]));
1202   emit_insn (gen_reduc_splus_<V_half> (res_d, step1));
1203   emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1204
1205   DONE;
1206 })
1207
1208 (define_insn "reduc_splus_v2di"
1209   [(set (match_operand:V2DI 0 "s_register_operand" "=w")
1210         (unspec:V2DI [(match_operand:V2DI 1 "s_register_operand" "w")]
1211                      UNSPEC_VPADD))]
1212   "TARGET_NEON"
1213   "vadd.i64\t%e0, %e1, %f1")
1214
1215 ;; NEON does not distinguish between signed and unsigned addition except on
1216 ;; widening operations.
1217 (define_expand "reduc_uplus_<mode>"
1218   [(match_operand:VDQI 0 "s_register_operand" "")
1219    (match_operand:VDQI 1 "s_register_operand" "")]
1220   "TARGET_NEON"
1221 {
1222   emit_insn (gen_reduc_splus_<mode> (operands[0], operands[1]));
1223   DONE;
1224 })
1225
1226 (define_expand "reduc_smin_<mode>"
1227   [(match_operand:VD 0 "s_register_operand" "")
1228    (match_operand:VD 1 "s_register_operand" "")]
1229   "TARGET_NEON"
1230 {
1231   neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1232                         &gen_neon_vpsmin<mode>);
1233   DONE;
1234 })
1235
1236 (define_expand "reduc_smin_<mode>"
1237   [(match_operand:VQ 0 "s_register_operand" "")
1238    (match_operand:VQ 1 "s_register_operand" "")]
1239   "TARGET_NEON"
1240 {
1241   rtx step1 = gen_reg_rtx (<V_HALF>mode);
1242   rtx res_d = gen_reg_rtx (<V_HALF>mode);
1243
1244   emit_insn (gen_quad_halves_smin<mode> (step1, operands[1]));
1245   emit_insn (gen_reduc_smin_<V_half> (res_d, step1));
1246   emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1247
1248   DONE;
1249 })
1250
1251 (define_expand "reduc_smax_<mode>"
1252   [(match_operand:VD 0 "s_register_operand" "")
1253    (match_operand:VD 1 "s_register_operand" "")]
1254   "TARGET_NEON"
1255 {
1256   neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1257                         &gen_neon_vpsmax<mode>);
1258   DONE;
1259 })
1260
1261 (define_expand "reduc_smax_<mode>"
1262   [(match_operand:VQ 0 "s_register_operand" "")
1263    (match_operand:VQ 1 "s_register_operand" "")]
1264   "TARGET_NEON"
1265 {
1266   rtx step1 = gen_reg_rtx (<V_HALF>mode);
1267   rtx res_d = gen_reg_rtx (<V_HALF>mode);
1268
1269   emit_insn (gen_quad_halves_smax<mode> (step1, operands[1]));
1270   emit_insn (gen_reduc_smax_<V_half> (res_d, step1));
1271   emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1272
1273   DONE;
1274 })
1275
1276 (define_expand "reduc_umin_<mode>"
1277   [(match_operand:VDI 0 "s_register_operand" "")
1278    (match_operand:VDI 1 "s_register_operand" "")]
1279   "TARGET_NEON"
1280 {
1281   neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1282                         &gen_neon_vpumin<mode>);
1283   DONE;
1284 })
1285
1286 (define_expand "reduc_umin_<mode>"
1287   [(match_operand:VQI 0 "s_register_operand" "")
1288    (match_operand:VQI 1 "s_register_operand" "")]
1289   "TARGET_NEON"
1290 {
1291   rtx step1 = gen_reg_rtx (<V_HALF>mode);
1292   rtx res_d = gen_reg_rtx (<V_HALF>mode);
1293
1294   emit_insn (gen_quad_halves_umin<mode> (step1, operands[1]));
1295   emit_insn (gen_reduc_umin_<V_half> (res_d, step1));
1296   emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1297
1298   DONE;
1299 })
1300
1301 (define_expand "reduc_umax_<mode>"
1302   [(match_operand:VDI 0 "s_register_operand" "")
1303    (match_operand:VDI 1 "s_register_operand" "")]
1304   "TARGET_NEON"
1305 {
1306   neon_pairwise_reduce (operands[0], operands[1], <MODE>mode,
1307                         &gen_neon_vpumax<mode>);
1308   DONE;
1309 })
1310
1311 (define_expand "reduc_umax_<mode>"
1312   [(match_operand:VQI 0 "s_register_operand" "")
1313    (match_operand:VQI 1 "s_register_operand" "")]
1314   "TARGET_NEON"
1315 {
1316   rtx step1 = gen_reg_rtx (<V_HALF>mode);
1317   rtx res_d = gen_reg_rtx (<V_HALF>mode);
1318
1319   emit_insn (gen_quad_halves_umax<mode> (step1, operands[1]));
1320   emit_insn (gen_reduc_umax_<V_half> (res_d, step1));
1321   emit_insn (gen_move_lo_quad_<mode> (operands[0], res_d));
1322
1323   DONE;
1324 })
1325
1326 (define_insn "neon_vpadd_internal<mode>"
1327   [(set (match_operand:VD 0 "s_register_operand" "=w")
1328         (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1329                     (match_operand:VD 2 "s_register_operand" "w")]
1330                    UNSPEC_VPADD))]
1331   "TARGET_NEON"
1332   "vpadd.<V_if_elem>\t%P0, %P1, %P2")
1333
1334 (define_insn "neon_vpsmin<mode>"
1335   [(set (match_operand:VD 0 "s_register_operand" "=w")
1336         (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1337                     (match_operand:VD 2 "s_register_operand" "w")]
1338                    UNSPEC_VPSMIN))]
1339   "TARGET_NEON"
1340   "vpmin.<V_s_elem>\t%P0, %P1, %P2")
1341
1342 (define_insn "neon_vpsmax<mode>"
1343   [(set (match_operand:VD 0 "s_register_operand" "=w")
1344         (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1345                     (match_operand:VD 2 "s_register_operand" "w")]
1346                    UNSPEC_VPSMAX))]
1347   "TARGET_NEON"
1348   "vpmax.<V_s_elem>\t%P0, %P1, %P2")
1349
1350 (define_insn "neon_vpumin<mode>"
1351   [(set (match_operand:VDI 0 "s_register_operand" "=w")
1352         (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1353                      (match_operand:VDI 2 "s_register_operand" "w")]
1354                    UNSPEC_VPUMIN))]
1355   "TARGET_NEON"
1356   "vpmin.<V_u_elem>\t%P0, %P1, %P2")
1357
1358 (define_insn "neon_vpumax<mode>"
1359   [(set (match_operand:VDI 0 "s_register_operand" "=w")
1360         (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1361                      (match_operand:VDI 2 "s_register_operand" "w")]
1362                    UNSPEC_VPUMAX))]
1363   "TARGET_NEON"
1364   "vpmax.<V_u_elem>\t%P0, %P1, %P2")
1365
1366 ;; Saturating arithmetic
1367
1368 ; NOTE: Neon supports many more saturating variants of instructions than the
1369 ; following, but these are all GCC currently understands.
1370 ; FIXME: Actually, GCC doesn't know how to create saturating add/sub by itself
1371 ; yet either, although these patterns may be used by intrinsics when they're
1372 ; added.
1373
1374 (define_insn "*ss_add<mode>_neon"
1375   [(set (match_operand:VD 0 "s_register_operand" "=w")
1376        (ss_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1377                    (match_operand:VD 2 "s_register_operand" "w")))]
1378   "TARGET_NEON"
1379   "vqadd.<V_s_elem>\t%P0, %P1, %P2")
1380
1381 (define_insn "*us_add<mode>_neon"
1382   [(set (match_operand:VD 0 "s_register_operand" "=w")
1383        (us_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1384                    (match_operand:VD 2 "s_register_operand" "w")))]
1385   "TARGET_NEON"
1386   "vqadd.<V_u_elem>\t%P0, %P1, %P2")
1387
1388 (define_insn "*ss_sub<mode>_neon"
1389   [(set (match_operand:VD 0 "s_register_operand" "=w")
1390        (ss_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1391                     (match_operand:VD 2 "s_register_operand" "w")))]
1392   "TARGET_NEON"
1393   "vqsub.<V_s_elem>\t%P0, %P1, %P2")
1394
1395 (define_insn "*us_sub<mode>_neon"
1396   [(set (match_operand:VD 0 "s_register_operand" "=w")
1397        (us_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1398                     (match_operand:VD 2 "s_register_operand" "w")))]
1399   "TARGET_NEON"
1400   "vqsub.<V_u_elem>\t%P0, %P1, %P2")
1401
1402 ;; Patterns for builtins.
1403
1404 ; good for plain vadd, vaddq.
1405
1406 (define_insn "neon_vadd<mode>"
1407   [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1408         (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1409                       (match_operand:VDQX 2 "s_register_operand" "w")
1410                       (match_operand:SI 3 "immediate_operand" "i")]
1411                      UNSPEC_VADD))]
1412   "TARGET_NEON"
1413   "vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1414
1415 ; operand 3 represents in bits:
1416 ;  bit 0: signed (vs unsigned).
1417 ;  bit 1: rounding (vs none).
1418
1419 (define_insn "neon_vaddl<mode>"
1420   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1421         (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1422                            (match_operand:VDI 2 "s_register_operand" "w")
1423                            (match_operand:SI 3 "immediate_operand" "i")]
1424                           UNSPEC_VADDL))]
1425   "TARGET_NEON"
1426   "vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2")
1427
1428 (define_insn "neon_vaddw<mode>"
1429   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1430         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1431                            (match_operand:VDI 2 "s_register_operand" "w")
1432                            (match_operand:SI 3 "immediate_operand" "i")]
1433                           UNSPEC_VADDW))]
1434   "TARGET_NEON"
1435   "vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2")
1436
1437 ; vhadd and vrhadd.
1438
1439 (define_insn "neon_vhadd<mode>"
1440   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1441         (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1442                        (match_operand:VDQIW 2 "s_register_operand" "w")
1443                        (match_operand:SI 3 "immediate_operand" "i")]
1444                       UNSPEC_VHADD))]
1445   "TARGET_NEON"
1446   "v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1447
1448 (define_insn "neon_vqadd<mode>"
1449   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
1450         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
1451                        (match_operand:VDQIX 2 "s_register_operand" "w")
1452                        (match_operand:SI 3 "immediate_operand" "i")]
1453                      UNSPEC_VQADD))]
1454   "TARGET_NEON"
1455   "vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1456
1457 (define_insn "neon_vaddhn<mode>"
1458   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
1459         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
1460                             (match_operand:VN 2 "s_register_operand" "w")
1461                             (match_operand:SI 3 "immediate_operand" "i")]
1462                            UNSPEC_VADDHN))]
1463   "TARGET_NEON"
1464   "v%O3addhn.<V_if_elem>\t%P0, %q1, %q2")
1465
1466 (define_insn "neon_vmul<mode>"
1467   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1468         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1469                       (match_operand:VDQW 2 "s_register_operand" "w")
1470                       (match_operand:SI 3 "immediate_operand" "i")]
1471                      UNSPEC_VMUL))]
1472   "TARGET_NEON"
1473   "vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1474
1475 (define_insn "neon_vmla<mode>"
1476   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1477         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
1478                       (match_operand:VDQW 2 "s_register_operand" "w")
1479                       (match_operand:VDQW 3 "s_register_operand" "w")
1480                      (match_operand:SI 4 "immediate_operand" "i")]
1481                     UNSPEC_VMLA))]
1482   "TARGET_NEON"
1483   "vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3")
1484
1485 (define_insn "neon_vmlal<mode>"
1486   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1487         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1488                            (match_operand:VW 2 "s_register_operand" "w")
1489                            (match_operand:VW 3 "s_register_operand" "w")
1490                            (match_operand:SI 4 "immediate_operand" "i")]
1491                           UNSPEC_VMLAL))]
1492   "TARGET_NEON"
1493   "vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3")
1494
1495 (define_insn "neon_vmls<mode>"
1496   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1497         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
1498                       (match_operand:VDQW 2 "s_register_operand" "w")
1499                       (match_operand:VDQW 3 "s_register_operand" "w")
1500                      (match_operand:SI 4 "immediate_operand" "i")]
1501                     UNSPEC_VMLS))]
1502   "TARGET_NEON"
1503   "vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3")
1504
1505 (define_insn "neon_vmlsl<mode>"
1506   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1507         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1508                            (match_operand:VW 2 "s_register_operand" "w")
1509                            (match_operand:VW 3 "s_register_operand" "w")
1510                            (match_operand:SI 4 "immediate_operand" "i")]
1511                           UNSPEC_VMLSL))]
1512   "TARGET_NEON"
1513   "vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3")
1514
1515 (define_insn "neon_vqdmulh<mode>"
1516   [(set (match_operand:VMDQI 0 "s_register_operand" "=w")
1517         (unspec:VMDQI [(match_operand:VMDQI 1 "s_register_operand" "w")
1518                        (match_operand:VMDQI 2 "s_register_operand" "w")
1519                        (match_operand:SI 3 "immediate_operand" "i")]
1520                       UNSPEC_VQDMULH))]
1521   "TARGET_NEON"
1522   "vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1523
1524 (define_insn "neon_vqdmlal<mode>"
1525   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1526         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1527                            (match_operand:VMDI 2 "s_register_operand" "w")
1528                            (match_operand:VMDI 3 "s_register_operand" "w")
1529                            (match_operand:SI 4 "immediate_operand" "i")]
1530                           UNSPEC_VQDMLAL))]
1531   "TARGET_NEON"
1532   "vqdmlal.<V_s_elem>\t%q0, %P2, %P3")
1533
1534 (define_insn "neon_vqdmlsl<mode>"
1535   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1536         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1537                            (match_operand:VMDI 2 "s_register_operand" "w")
1538                            (match_operand:VMDI 3 "s_register_operand" "w")
1539                            (match_operand:SI 4 "immediate_operand" "i")]
1540                           UNSPEC_VQDMLSL))]
1541   "TARGET_NEON"
1542   "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3")
1543
1544 (define_insn "neon_vmull<mode>"
1545   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1546         (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
1547                            (match_operand:VW 2 "s_register_operand" "w")
1548                            (match_operand:SI 3 "immediate_operand" "i")]
1549                           UNSPEC_VMULL))]
1550   "TARGET_NEON"
1551   "vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2")
1552
1553 (define_insn "neon_vqdmull<mode>"
1554   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1555         (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
1556                            (match_operand:VMDI 2 "s_register_operand" "w")
1557                            (match_operand:SI 3 "immediate_operand" "i")]
1558                           UNSPEC_VQDMULL))]
1559   "TARGET_NEON"
1560   "vqdmull.<V_s_elem>\t%q0, %P1, %P2")
1561
1562 (define_insn "neon_vsub<mode>"
1563   [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1564         (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1565                       (match_operand:VDQX 2 "s_register_operand" "w")
1566                       (match_operand:SI 3 "immediate_operand" "i")]
1567                      UNSPEC_VSUB))]
1568   "TARGET_NEON"
1569   "vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1570
1571 (define_insn "neon_vsubl<mode>"
1572   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1573         (unspec:<V_widen> [(match_operand:VDI 1 "s_register_operand" "w")
1574                            (match_operand:VDI 2 "s_register_operand" "w")
1575                            (match_operand:SI 3 "immediate_operand" "i")]
1576                           UNSPEC_VSUBL))]
1577   "TARGET_NEON"
1578   "vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2")
1579
1580 (define_insn "neon_vsubw<mode>"
1581   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1582         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "w")
1583                            (match_operand:VDI 2 "s_register_operand" "w")
1584                            (match_operand:SI 3 "immediate_operand" "i")]
1585                           UNSPEC_VSUBW))]
1586   "TARGET_NEON"
1587   "vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2")
1588
1589 (define_insn "neon_vqsub<mode>"
1590   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
1591         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
1592                        (match_operand:VDQIX 2 "s_register_operand" "w")
1593                        (match_operand:SI 3 "immediate_operand" "i")]
1594                       UNSPEC_VQSUB))]
1595   "TARGET_NEON"
1596   "vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1597
1598 (define_insn "neon_vhsub<mode>"
1599   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1600         (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1601                        (match_operand:VDQIW 2 "s_register_operand" "w")
1602                        (match_operand:SI 3 "immediate_operand" "i")]
1603                       UNSPEC_VHSUB))]
1604   "TARGET_NEON"
1605   "vhsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1606
1607 (define_insn "neon_vsubhn<mode>"
1608   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
1609         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
1610                             (match_operand:VN 2 "s_register_operand" "w")
1611                             (match_operand:SI 3 "immediate_operand" "i")]
1612                            UNSPEC_VSUBHN))]
1613   "TARGET_NEON"
1614   "v%O3subhn.<V_if_elem>\t%P0, %q1, %q2")
1615
1616 (define_insn "neon_vceq<mode>"
1617   [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
1618         (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w")
1619                                 (match_operand:VDQW 2 "s_register_operand" "w")
1620                                 (match_operand:SI 3 "immediate_operand" "i")]
1621                                UNSPEC_VCEQ))]
1622   "TARGET_NEON"
1623   "vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1624
1625 (define_insn "neon_vcge<mode>"
1626   [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
1627         (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w")
1628                                 (match_operand:VDQW 2 "s_register_operand" "w")
1629                                 (match_operand:SI 3 "immediate_operand" "i")]
1630                                UNSPEC_VCGE))]
1631   "TARGET_NEON"
1632   "vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1633
1634 (define_insn "neon_vcgt<mode>"
1635   [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
1636         (unspec:<V_cmp_result> [(match_operand:VDQW 1 "s_register_operand" "w")
1637                                 (match_operand:VDQW 2 "s_register_operand" "w")
1638                                 (match_operand:SI 3 "immediate_operand" "i")]
1639                                UNSPEC_VCGT))]
1640   "TARGET_NEON"
1641   "vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1642
1643 (define_insn "neon_vcage<mode>"
1644   [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
1645         (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
1646                                 (match_operand:VCVTF 2 "s_register_operand" "w")
1647                                 (match_operand:SI 3 "immediate_operand" "i")]
1648                                UNSPEC_VCAGE))]
1649   "TARGET_NEON"
1650   "vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1651
1652 (define_insn "neon_vcagt<mode>"
1653   [(set (match_operand:<V_cmp_result> 0 "s_register_operand" "=w")
1654         (unspec:<V_cmp_result> [(match_operand:VCVTF 1 "s_register_operand" "w")
1655                                 (match_operand:VCVTF 2 "s_register_operand" "w")
1656                                 (match_operand:SI 3 "immediate_operand" "i")]
1657                                UNSPEC_VCAGT))]
1658   "TARGET_NEON"
1659   "vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1660
1661 (define_insn "neon_vtst<mode>"
1662   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1663         (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1664                        (match_operand:VDQIW 2 "s_register_operand" "w")
1665                        (match_operand:SI 3 "immediate_operand" "i")]
1666                       UNSPEC_VTST))]
1667   "TARGET_NEON"
1668   "vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1669
1670 (define_insn "neon_vabd<mode>"
1671   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1672         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1673                       (match_operand:VDQW 2 "s_register_operand" "w")
1674                       (match_operand:SI 3 "immediate_operand" "i")]
1675                      UNSPEC_VABD))]
1676   "TARGET_NEON"
1677   "vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1678
1679 (define_insn "neon_vabdl<mode>"
1680   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1681         (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
1682                            (match_operand:VW 2 "s_register_operand" "w")
1683                            (match_operand:SI 3 "immediate_operand" "i")]
1684                           UNSPEC_VABDL))]
1685   "TARGET_NEON"
1686   "vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2")
1687
1688 (define_insn "neon_vaba<mode>"
1689   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1690         (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "0")
1691                        (match_operand:VDQIW 2 "s_register_operand" "w")
1692                        (match_operand:VDQIW 3 "s_register_operand" "w")
1693                        (match_operand:SI 4 "immediate_operand" "i")]
1694                       UNSPEC_VABA))]
1695   "TARGET_NEON"
1696   "vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3")
1697
1698 (define_insn "neon_vabal<mode>"
1699   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
1700         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
1701                            (match_operand:VW 2 "s_register_operand" "w")
1702                            (match_operand:VW 3 "s_register_operand" "w")
1703                            (match_operand:SI 4 "immediate_operand" "i")]
1704                           UNSPEC_VABAL))]
1705   "TARGET_NEON"
1706   "vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3")
1707
1708 (define_insn "neon_vmax<mode>"
1709   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1710         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1711                       (match_operand:VDQW 2 "s_register_operand" "w")
1712                       (match_operand:SI 3 "immediate_operand" "i")]
1713                      UNSPEC_VMAX))]
1714   "TARGET_NEON"
1715   "vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1716
1717 (define_insn "neon_vmin<mode>"
1718   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1719         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1720                       (match_operand:VDQW 2 "s_register_operand" "w")
1721                       (match_operand:SI 3 "immediate_operand" "i")]
1722                      UNSPEC_VMIN))]
1723   "TARGET_NEON"
1724   "vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1725
1726 (define_expand "neon_vpadd<mode>"
1727   [(match_operand:VD 0 "s_register_operand" "=w")
1728    (match_operand:VD 1 "s_register_operand" "w")
1729    (match_operand:VD 2 "s_register_operand" "w")
1730    (match_operand:SI 3 "immediate_operand" "i")]
1731   "TARGET_NEON"
1732 {
1733   emit_insn (gen_neon_vpadd_internal<mode> (operands[0], operands[1],
1734                                             operands[2]));
1735   DONE;
1736 })
1737
1738 (define_insn "neon_vpaddl<mode>"
1739   [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
1740         (unspec:<V_double_width> [(match_operand:VDQIW 1 "s_register_operand" "w")
1741                                   (match_operand:SI 2 "immediate_operand" "i")]
1742                                  UNSPEC_VPADDL))]
1743   "TARGET_NEON"
1744   "vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1")
1745
1746 (define_insn "neon_vpadal<mode>"
1747   [(set (match_operand:<V_double_width> 0 "s_register_operand" "=w")
1748         (unspec:<V_double_width> [(match_operand:<V_double_width> 1 "s_register_operand" "0")
1749                                   (match_operand:VDQIW 2 "s_register_operand" "w")
1750                                   (match_operand:SI 3 "immediate_operand" "i")]
1751                                  UNSPEC_VPADAL))]
1752   "TARGET_NEON"
1753   "vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2")
1754
1755 (define_insn "neon_vpmax<mode>"
1756   [(set (match_operand:VD 0 "s_register_operand" "=w")
1757         (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1758                     (match_operand:VD 2 "s_register_operand" "w")
1759                     (match_operand:SI 3 "immediate_operand" "i")]
1760                    UNSPEC_VPMAX))]
1761   "TARGET_NEON"
1762   "vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1763
1764 (define_insn "neon_vpmin<mode>"
1765   [(set (match_operand:VD 0 "s_register_operand" "=w")
1766         (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1767                     (match_operand:VD 2 "s_register_operand" "w")
1768                     (match_operand:SI 3 "immediate_operand" "i")]
1769                    UNSPEC_VPMIN))]
1770   "TARGET_NEON"
1771   "vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1772
1773 (define_insn "neon_vrecps<mode>"
1774   [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
1775         (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
1776                        (match_operand:VCVTF 2 "s_register_operand" "w")
1777                        (match_operand:SI 3 "immediate_operand" "i")]
1778                       UNSPEC_VRECPS))]
1779   "TARGET_NEON"
1780   "vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1781
1782 (define_insn "neon_vrsqrts<mode>"
1783   [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
1784         (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
1785                        (match_operand:VCVTF 2 "s_register_operand" "w")
1786                        (match_operand:SI 3 "immediate_operand" "i")]
1787                       UNSPEC_VRSQRTS))]
1788   "TARGET_NEON"
1789   "vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
1790
1791 (define_insn "neon_vabs<mode>"
1792   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1793         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1794                       (match_operand:SI 2 "immediate_operand" "i")]
1795                      UNSPEC_VABS))]
1796   "TARGET_NEON"
1797   "vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1")
1798
1799 (define_insn "neon_vqabs<mode>"
1800   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1801         (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1802                        (match_operand:SI 2 "immediate_operand" "i")]
1803                       UNSPEC_VQABS))]
1804   "TARGET_NEON"
1805   "vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1")
1806
1807 (define_expand "neon_vneg<mode>"
1808   [(match_operand:VDQW 0 "s_register_operand" "")
1809    (match_operand:VDQW 1 "s_register_operand" "")
1810    (match_operand:SI 2 "immediate_operand" "")]
1811   "TARGET_NEON"
1812 {
1813   emit_insn (gen_neg<mode>2 (operands[0], operands[1]));
1814   DONE;
1815 })
1816
1817 (define_insn "neon_vqneg<mode>"
1818   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1819         (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1820                        (match_operand:SI 2 "immediate_operand" "i")]
1821                       UNSPEC_VQNEG))]
1822   "TARGET_NEON"
1823   "vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1")
1824
1825 (define_insn "neon_vcls<mode>"
1826   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1827         (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1828                        (match_operand:SI 2 "immediate_operand" "i")]
1829                       UNSPEC_VCLS))]
1830   "TARGET_NEON"
1831   "vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1")
1832
1833 (define_insn "neon_vclz<mode>"
1834   [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1835         (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1836                        (match_operand:SI 2 "immediate_operand" "i")]
1837                       UNSPEC_VCLZ))]
1838   "TARGET_NEON"
1839   "vclz.<V_if_elem>\t%<V_reg>0, %<V_reg>1")
1840
1841 (define_insn "neon_vcnt<mode>"
1842   [(set (match_operand:VE 0 "s_register_operand" "=w")
1843         (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
1844                     (match_operand:SI 2 "immediate_operand" "i")]
1845                    UNSPEC_VCNT))]
1846   "TARGET_NEON"
1847   "vcnt.<V_sz_elem>\t%<V_reg>0, %<V_reg>1")
1848
1849 (define_insn "neon_vrecpe<mode>"
1850   [(set (match_operand:V32 0 "s_register_operand" "=w")
1851         (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
1852                      (match_operand:SI 2 "immediate_operand" "i")]
1853                     UNSPEC_VRECPE))]
1854   "TARGET_NEON"
1855   "vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1")
1856
1857 (define_insn "neon_vrsqrte<mode>"
1858   [(set (match_operand:V32 0 "s_register_operand" "=w")
1859         (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
1860                      (match_operand:SI 2 "immediate_operand" "i")]
1861                     UNSPEC_VRSQRTE))]
1862   "TARGET_NEON"
1863   "vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1")
1864
1865 (define_expand "neon_vmvn<mode>"
1866   [(match_operand:VDQIW 0 "s_register_operand" "")
1867    (match_operand:VDQIW 1 "s_register_operand" "")
1868    (match_operand:SI 2 "immediate_operand" "")]
1869   "TARGET_NEON"
1870 {
1871   emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[1]));
1872   DONE;
1873 })
1874
1875 ;; FIXME: 32-bit element sizes are a bit funky (should be output as .32 not
1876 ;; .u32), but the assembler should cope with that.
1877
1878 (define_insn "neon_vget_lane<mode>"
1879   [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
1880         (unspec:<V_elem> [(match_operand:VD 1 "s_register_operand" "w")
1881                           (match_operand:SI 2 "immediate_operand" "i")
1882                           (match_operand:SI 3 "immediate_operand" "i")]
1883                          UNSPEC_VGET_LANE))]
1884   "TARGET_NEON"
1885   "vmov%?.%t3%#<V_sz_elem>\t%0, %P1[%c2]"
1886   [(set_attr "predicable" "yes")])
1887
1888 ; Operand 2 (lane number) is ignored because we can only extract the zeroth lane
1889 ; with this insn. Operand 3 (info word) is ignored because it does nothing
1890 ; useful with 64-bit elements.
1891
1892 (define_insn "neon_vget_lanedi"
1893   [(set (match_operand:DI 0 "s_register_operand" "=r")
1894        (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
1895                    (match_operand:SI 2 "immediate_operand" "i")
1896                    (match_operand:SI 3 "immediate_operand" "i")]
1897                   UNSPEC_VGET_LANE))]
1898   "TARGET_NEON"
1899   "vmov%?\t%Q0, %R0, %P1  @ di"
1900   [(set_attr "predicable" "yes")])
1901
1902 (define_insn "neon_vget_lane<mode>"
1903   [(set (match_operand:<V_elem> 0 "s_register_operand" "=r")
1904        (unspec:<V_elem> [(match_operand:VQ 1 "s_register_operand" "w")
1905                          (match_operand:SI 2 "immediate_operand" "i")
1906                          (match_operand:SI 3 "immediate_operand" "i")]
1907                         UNSPEC_VGET_LANE))]
1908   "TARGET_NEON"
1909 {
1910   rtx ops[4];
1911   int regno = REGNO (operands[1]);
1912   unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
1913   unsigned int elt = INTVAL (operands[2]);
1914
1915   ops[0] = operands[0];
1916   ops[1] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
1917   ops[2] = GEN_INT (elt % halfelts);
1918   ops[3] = operands[3];
1919   output_asm_insn ("vmov%?.%t3%#<V_sz_elem>\t%0, %P1[%c2]", ops);
1920
1921   return "";
1922 }
1923   [(set_attr "predicable" "yes")])
1924
1925 (define_insn "neon_vget_lanev2di"
1926   [(set (match_operand:DI 0 "s_register_operand" "=r")
1927        (unspec:DI [(match_operand:V2DI 1 "s_register_operand" "w")
1928                    (match_operand:SI 2 "immediate_operand" "i")
1929                    (match_operand:SI 3 "immediate_operand" "i")]
1930                   UNSPEC_VGET_LANE))]
1931   "TARGET_NEON"
1932 {
1933   rtx ops[2];
1934   unsigned int regno = REGNO (operands[1]);
1935   unsigned int elt = INTVAL (operands[2]);
1936
1937   ops[0] = operands[0];
1938   ops[1] = gen_rtx_REG (DImode, regno + 2 * elt);
1939   output_asm_insn ("vmov%?\t%Q0, %R0, %P1  @ v2di", ops);
1940
1941   return "";
1942 }
1943   [(set_attr "predicable" "yes")])
1944
1945
1946 (define_insn "neon_vset_lane<mode>"
1947   [(set (match_operand:VD 0 "s_register_operand" "=w")
1948         (unspec:VD [(match_operand:<V_elem> 1 "s_register_operand" "r")
1949                     (match_operand:VD 2 "s_register_operand" "0")
1950                     (match_operand:SI 3 "immediate_operand" "i")]
1951                    UNSPEC_VSET_LANE))]
1952   "TARGET_NEON"
1953   "vmov%?.<V_sz_elem>\t%P0[%c3], %1"
1954   [(set_attr "predicable" "yes")])
1955
1956 ; See neon_vget_lanedi comment for reasons operands 2 & 3 are ignored.
1957
1958 (define_insn "neon_vset_lanedi"
1959   [(set (match_operand:DI 0 "s_register_operand" "=w")
1960         (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")
1961                     (match_operand:DI 2 "s_register_operand" "0")
1962                     (match_operand:SI 3 "immediate_operand" "i")]
1963                    UNSPEC_VSET_LANE))]
1964   "TARGET_NEON"
1965   "vmov%?\t%P0, %Q1, %R1  @ di"
1966   [(set_attr "predicable" "yes")])
1967
1968 (define_insn "neon_vset_lane<mode>"
1969   [(set (match_operand:VQ 0 "s_register_operand" "=w")
1970         (unspec:VQ [(match_operand:<V_elem> 1 "s_register_operand" "r")
1971                     (match_operand:VQ 2 "s_register_operand" "0")
1972                     (match_operand:SI 3 "immediate_operand" "i")]
1973                    UNSPEC_VSET_LANE))]
1974   "TARGET_NEON"
1975 {
1976   rtx ops[4];
1977   unsigned int regno = REGNO (operands[0]);
1978   unsigned int halfelts = GET_MODE_NUNITS (<MODE>mode) / 2;
1979   unsigned int elt = INTVAL (operands[3]);
1980
1981   ops[0] = gen_rtx_REG (<V_HALF>mode, regno + 2 * (elt / halfelts));
1982   ops[1] = operands[1];
1983   ops[2] = GEN_INT (elt % halfelts);
1984   output_asm_insn ("vmov%?.<V_sz_elem>\t%P0[%c2], %1", ops);
1985
1986   return "";
1987 }
1988   [(set_attr "predicable" "yes")])
1989
1990 (define_insn "neon_vset_lanev2di"
1991   [(set (match_operand:V2DI 0 "s_register_operand" "=w")
1992         (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "r")
1993                       (match_operand:V2DI 2 "s_register_operand" "0")
1994                       (match_operand:SI 3 "immediate_operand" "i")]
1995                    UNSPEC_VSET_LANE))]
1996   "TARGET_NEON"
1997 {
1998   rtx ops[2];
1999   unsigned int regno = REGNO (operands[0]);
2000   unsigned int elt = INTVAL (operands[3]);
2001
2002   ops[0] = gen_rtx_REG (DImode, regno + 2 * elt);
2003   ops[1] = operands[1];
2004   output_asm_insn ("vmov%?\t%P0, %Q1, %R1  @ v2di", ops);
2005
2006   return "";
2007 }
2008   [(set_attr "predicable" "yes")])
2009
2010 (define_expand "neon_vcreate<mode>"
2011   [(match_operand:VDX 0 "s_register_operand" "")
2012    (match_operand:DI 1 "general_operand" "")]
2013   "TARGET_NEON"
2014 {
2015   rtx src = gen_lowpart (<MODE>mode, operands[1]);
2016   emit_move_insn (operands[0], src);
2017   DONE;
2018 })
2019
2020 (define_insn "neon_vdup_n<mode>"
2021   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2022         (unspec:VDQW [(match_operand:<V_elem> 1 "s_register_operand" "r")]
2023                     UNSPEC_VDUP_N))]
2024   "TARGET_NEON"
2025   "vdup%?.<V_sz_elem>\t%<V_reg>0, %1"
2026   [(set_attr "predicable" "yes")])
2027
2028 (define_insn "neon_vdup_ndi"
2029   [(set (match_operand:DI 0 "s_register_operand" "=w")
2030         (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")]
2031                    UNSPEC_VDUP_N))]
2032   "TARGET_NEON"
2033   "vmov%?\t%P0, %Q1, %R1"
2034   [(set_attr "predicable" "yes")])
2035
2036 (define_insn "neon_vdup_nv2di"
2037   [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2038         (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "r")]
2039                      UNSPEC_VDUP_N))]
2040   "TARGET_NEON"
2041   "vmov%?\t%e0, %Q1, %R1\;vmov%?\t%f0, %Q1, %R1"
2042   [(set_attr "predicable" "yes")
2043    (set_attr "length" "8")])
2044
2045 (define_insn "neon_vdup_lane<mode>"
2046   [(set (match_operand:VD 0 "s_register_operand" "=w")
2047         (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2048                     (match_operand:SI 2 "immediate_operand" "i")]
2049                    UNSPEC_VDUP_LANE))]
2050   "TARGET_NEON"
2051   "vdup.<V_sz_elem>\t%P0, %P1[%c2]")
2052
2053 (define_insn "neon_vdup_lane<mode>"
2054   [(set (match_operand:VQ 0 "s_register_operand" "=w")
2055         (unspec:VQ [(match_operand:<V_HALF> 1 "s_register_operand" "w")
2056                     (match_operand:SI 2 "immediate_operand" "i")]
2057                    UNSPEC_VDUP_LANE))]
2058   "TARGET_NEON"
2059   "vdup.<V_sz_elem>\t%q0, %P1[%c2]")
2060
2061 ; Scalar index is ignored, since only zero is valid here.
2062 (define_expand "neon_vdup_lanedi"
2063   [(set (match_operand:DI 0 "s_register_operand" "=w")
2064         (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
2065                     (match_operand:SI 2 "immediate_operand" "i")]
2066                    UNSPEC_VDUP_LANE))]
2067   "TARGET_NEON"
2068 {
2069   emit_move_insn (operands[0], operands[1]);
2070   DONE;
2071 })
2072
2073 ; Likewise.
2074 (define_insn "neon_vdup_lanev2di"
2075   [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2076         (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "w")
2077                       (match_operand:SI 2 "immediate_operand" "i")]
2078                      UNSPEC_VDUP_LANE))]
2079   "TARGET_NEON"
2080   "vmov\t%e0, %P1\;vmov\t%f0, %P1"
2081   [(set_attr "length" "8")])
2082
2083 ;; In this insn, operand 1 should be low, and operand 2 the high part of the
2084 ;; dest vector.
2085 ;; FIXME: A different implementation of this builtin could make it much
2086 ;; more likely that we wouldn't actually need to output anything (we could make
2087 ;; it so that the reg allocator puts things in the right places magically
2088 ;; instead). Lack of subregs for vectors makes that tricky though, I think.
2089
2090 (define_insn "neon_vcombine<mode>"
2091   [(set (match_operand:<V_DOUBLE> 0 "s_register_operand" "=w")
2092         (unspec:<V_DOUBLE> [(match_operand:VDX 1 "s_register_operand" "w")
2093                             (match_operand:VDX 2 "s_register_operand" "w")]
2094                            UNSPEC_VCOMBINE))]
2095   "TARGET_NEON"
2096 {
2097   int dest = REGNO (operands[0]);
2098   int src1 = REGNO (operands[1]);
2099   int src2 = REGNO (operands[2]);
2100   rtx destlo;
2101
2102   if (src1 == dest && src2 == dest + 2)
2103     return "";
2104   else if (src2 == dest && src1 == dest + 2)
2105     /* Special case of reversed high/low parts.  */
2106     return "vswp\t%P1, %P2";
2107
2108   destlo = gen_rtx_REG (<MODE>mode, dest);
2109
2110   if (!reg_overlap_mentioned_p (operands[2], destlo))
2111     {
2112       /* Try to avoid unnecessary moves if part of the result is in the right
2113          place already.  */
2114       if (src1 != dest)
2115         output_asm_insn ("vmov\t%e0, %P1", operands);
2116       if (src2 != dest + 2)
2117         output_asm_insn ("vmov\t%f0, %P2", operands);
2118     }
2119   else
2120     {
2121       if (src2 != dest + 2)
2122         output_asm_insn ("vmov\t%f0, %P2", operands);
2123       if (src1 != dest)
2124         output_asm_insn ("vmov\t%e0, %P1", operands);
2125     }
2126
2127   return "";
2128 }
2129   [(set_attr "length" "8")])
2130
2131 (define_insn "neon_vget_high<mode>"
2132   [(set (match_operand:<V_HALF> 0 "s_register_operand" "=w")
2133         (unspec:<V_HALF> [(match_operand:VQX 1 "s_register_operand" "w")]
2134                          UNSPEC_VGET_HIGH))]
2135   "TARGET_NEON"
2136 {
2137   int dest = REGNO (operands[0]);
2138   int src = REGNO (operands[1]);
2139
2140   if (dest != src + 2)
2141     return "vmov\t%P0, %f1";
2142   else
2143     return "";
2144 })
2145
2146 (define_insn "neon_vget_low<mode>"
2147   [(set (match_operand:<V_HALF> 0 "s_register_operand" "=w")
2148         (unspec:<V_HALF> [(match_operand:VQX 1 "s_register_operand" "w")]
2149                          UNSPEC_VGET_LOW))]
2150   "TARGET_NEON"
2151 {
2152   int dest = REGNO (operands[0]);
2153   int src = REGNO (operands[1]);
2154
2155   if (dest != src)
2156     return "vmov\t%P0, %e1";
2157   else
2158     return "";
2159 })
2160
2161 (define_insn "neon_vcvt<mode>"
2162   [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2163         (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
2164                            (match_operand:SI 2 "immediate_operand" "i")]
2165                           UNSPEC_VCVT))]
2166   "TARGET_NEON"
2167   "vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1")
2168
2169 (define_insn "neon_vcvt<mode>"
2170   [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2171         (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
2172                            (match_operand:SI 2 "immediate_operand" "i")]
2173                           UNSPEC_VCVT))]
2174   "TARGET_NEON"
2175   "vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1")
2176
2177 (define_insn "neon_vcvt_n<mode>"
2178   [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2179         (unspec:<V_CVTTO> [(match_operand:VCVTF 1 "s_register_operand" "w")
2180                            (match_operand:SI 2 "immediate_operand" "i")
2181                            (match_operand:SI 3 "immediate_operand" "i")]
2182                           UNSPEC_VCVT_N))]
2183   "TARGET_NEON"
2184   "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2")
2185
2186 (define_insn "neon_vcvt_n<mode>"
2187   [(set (match_operand:<V_CVTTO> 0 "s_register_operand" "=w")
2188         (unspec:<V_CVTTO> [(match_operand:VCVTI 1 "s_register_operand" "w")
2189                            (match_operand:SI 2 "immediate_operand" "i")
2190                            (match_operand:SI 3 "immediate_operand" "i")]
2191                           UNSPEC_VCVT_N))]
2192   "TARGET_NEON"
2193   "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2")
2194
2195 (define_insn "neon_vmovn<mode>"
2196   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2197         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2198                             (match_operand:SI 2 "immediate_operand" "i")]
2199                            UNSPEC_VMOVN))]
2200   "TARGET_NEON"
2201   "vmovn.<V_if_elem>\t%P0, %q1")
2202
2203 (define_insn "neon_vqmovn<mode>"
2204   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2205         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2206                             (match_operand:SI 2 "immediate_operand" "i")]
2207                            UNSPEC_VQMOVN))]
2208   "TARGET_NEON"
2209   "vqmovn.%T2%#<V_sz_elem>\t%P0, %q1")
2210
2211 (define_insn "neon_vqmovun<mode>"
2212   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2213         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2214                             (match_operand:SI 2 "immediate_operand" "i")]
2215                            UNSPEC_VQMOVUN))]
2216   "TARGET_NEON"
2217   "vqmovun.<V_s_elem>\t%P0, %q1")
2218
2219 (define_insn "neon_vmovl<mode>"
2220   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2221         (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2222                            (match_operand:SI 2 "immediate_operand" "i")]
2223                           UNSPEC_VMOVL))]
2224   "TARGET_NEON"
2225   "vmovl.%T2%#<V_sz_elem>\t%q0, %P1")
2226
2227 (define_insn "neon_vmul_lane<mode>"
2228   [(set (match_operand:VMD 0 "s_register_operand" "=w")
2229         (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "w")
2230                      (match_operand:VMD 2 "s_register_operand"
2231                                         "<scalar_mul_constraint>")
2232                      (match_operand:SI 3 "immediate_operand" "i")
2233                      (match_operand:SI 4 "immediate_operand" "i")]
2234                     UNSPEC_VMUL_LANE))]
2235   "TARGET_NEON"
2236   "vmul.<V_if_elem>\t%P0, %P1, %P2[%c3]")
2237
2238 (define_insn "neon_vmul_lane<mode>"
2239   [(set (match_operand:VMQ 0 "s_register_operand" "=w")
2240         (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "w")
2241                      (match_operand:<V_HALF> 2 "s_register_operand"
2242                                              "<scalar_mul_constraint>")
2243                      (match_operand:SI 3 "immediate_operand" "i")
2244                      (match_operand:SI 4 "immediate_operand" "i")]
2245                     UNSPEC_VMUL_LANE))]
2246   "TARGET_NEON"
2247   "vmul.<V_if_elem>\t%q0, %q1, %P2[%c3]")
2248
2249 (define_insn "neon_vmull_lane<mode>"
2250   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2251         (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
2252                            (match_operand:VMDI 2 "s_register_operand"
2253                                                "<scalar_mul_constraint>")
2254                            (match_operand:SI 3 "immediate_operand" "i")
2255                            (match_operand:SI 4 "immediate_operand" "i")]
2256                           UNSPEC_VMULL_LANE))]
2257   "TARGET_NEON"
2258   "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]")
2259
2260 (define_insn "neon_vqdmull_lane<mode>"
2261   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2262         (unspec:<V_widen> [(match_operand:VMDI 1 "s_register_operand" "w")
2263                            (match_operand:VMDI 2 "s_register_operand"
2264                                                "<scalar_mul_constraint>")
2265                            (match_operand:SI 3 "immediate_operand" "i")
2266                            (match_operand:SI 4 "immediate_operand" "i")]
2267                           UNSPEC_VQDMULL_LANE))]
2268   "TARGET_NEON"
2269   "vqdmull.<V_s_elem>\t%q0, %P1, %P2[%c3]")
2270
2271 (define_insn "neon_vqdmulh_lane<mode>"
2272   [(set (match_operand:VMQI 0 "s_register_operand" "=w")
2273         (unspec:VMQI [(match_operand:VMQI 1 "s_register_operand" "w")
2274                       (match_operand:<V_HALF> 2 "s_register_operand"
2275                                               "<scalar_mul_constraint>")
2276                       (match_operand:SI 3 "immediate_operand" "i")
2277                       (match_operand:SI 4 "immediate_operand" "i")]
2278                       UNSPEC_VQDMULH_LANE))]
2279   "TARGET_NEON"
2280   "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]")
2281
2282 (define_insn "neon_vqdmulh_lane<mode>"
2283   [(set (match_operand:VMDI 0 "s_register_operand" "=w")
2284         (unspec:VMDI [(match_operand:VMDI 1 "s_register_operand" "w")
2285                       (match_operand:VMDI 2 "s_register_operand"
2286                                           "<scalar_mul_constraint>")
2287                       (match_operand:SI 3 "immediate_operand" "i")
2288                       (match_operand:SI 4 "immediate_operand" "i")]
2289                       UNSPEC_VQDMULH_LANE))]
2290   "TARGET_NEON"
2291   "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]")
2292
2293 (define_insn "neon_vmla_lane<mode>"
2294   [(set (match_operand:VMD 0 "s_register_operand" "=w")
2295         (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
2296                      (match_operand:VMD 2 "s_register_operand" "w")
2297                      (match_operand:VMD 3 "s_register_operand"
2298                                         "<scalar_mul_constraint>")
2299                      (match_operand:SI 4 "immediate_operand" "i")
2300                      (match_operand:SI 5 "immediate_operand" "i")]
2301                      UNSPEC_VMLA_LANE))]
2302   "TARGET_NEON"
2303   "vmla.<V_if_elem>\t%P0, %P2, %P3[%c4]")
2304
2305 (define_insn "neon_vmla_lane<mode>"
2306   [(set (match_operand:VMQ 0 "s_register_operand" "=w")
2307         (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
2308                      (match_operand:VMQ 2 "s_register_operand" "w")
2309                      (match_operand:<V_HALF> 3 "s_register_operand"
2310                                              "<scalar_mul_constraint>")
2311                      (match_operand:SI 4 "immediate_operand" "i")
2312                      (match_operand:SI 5 "immediate_operand" "i")]
2313                      UNSPEC_VMLA_LANE))]
2314   "TARGET_NEON"
2315   "vmla.<V_if_elem>\t%q0, %q2, %P3[%c4]")
2316
2317 (define_insn "neon_vmlal_lane<mode>"
2318   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2319         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2320                            (match_operand:VMDI 2 "s_register_operand" "w")
2321                            (match_operand:VMDI 3 "s_register_operand"
2322                                                "<scalar_mul_constraint>")
2323                            (match_operand:SI 4 "immediate_operand" "i")
2324                            (match_operand:SI 5 "immediate_operand" "i")]
2325                           UNSPEC_VMLAL_LANE))]
2326   "TARGET_NEON"
2327   "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]")
2328
2329 (define_insn "neon_vqdmlal_lane<mode>"
2330   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2331         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2332                            (match_operand:VMDI 2 "s_register_operand" "w")
2333                            (match_operand:VMDI 3 "s_register_operand"
2334                                                "<scalar_mul_constraint>")
2335                            (match_operand:SI 4 "immediate_operand" "i")
2336                            (match_operand:SI 5 "immediate_operand" "i")]
2337                           UNSPEC_VQDMLAL_LANE))]
2338   "TARGET_NEON"
2339   "vqdmlal.<V_s_elem>\t%q0, %P2, %P3[%c4]")
2340
2341 (define_insn "neon_vmls_lane<mode>"
2342   [(set (match_operand:VMD 0 "s_register_operand" "=w")
2343         (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
2344                      (match_operand:VMD 2 "s_register_operand" "w")
2345                      (match_operand:VMD 3 "s_register_operand"
2346                                         "<scalar_mul_constraint>")
2347                      (match_operand:SI 4 "immediate_operand" "i")
2348                      (match_operand:SI 5 "immediate_operand" "i")]
2349                     UNSPEC_VMLS_LANE))]
2350   "TARGET_NEON"
2351   "vmls.<V_if_elem>\t%P0, %P2, %P3[%c4]")
2352
2353 (define_insn "neon_vmls_lane<mode>"
2354   [(set (match_operand:VMQ 0 "s_register_operand" "=w")
2355         (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
2356                      (match_operand:VMQ 2 "s_register_operand" "w")
2357                      (match_operand:<V_HALF> 3 "s_register_operand"
2358                                              "<scalar_mul_constraint>")
2359                      (match_operand:SI 4 "immediate_operand" "i")
2360                      (match_operand:SI 5 "immediate_operand" "i")]
2361                     UNSPEC_VMLS_LANE))]
2362   "TARGET_NEON"
2363   "vmls.<V_if_elem>\t%q0, %q2, %P3[%c4]")
2364
2365 (define_insn "neon_vmlsl_lane<mode>"
2366   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2367         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2368                            (match_operand:VMDI 2 "s_register_operand" "w")
2369                            (match_operand:VMDI 3 "s_register_operand"
2370                                                "<scalar_mul_constraint>")
2371                            (match_operand:SI 4 "immediate_operand" "i")
2372                            (match_operand:SI 5 "immediate_operand" "i")]
2373                           UNSPEC_VMLSL_LANE))]
2374   "TARGET_NEON"
2375   "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]")
2376
2377 (define_insn "neon_vqdmlsl_lane<mode>"
2378   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2379         (unspec:<V_widen> [(match_operand:<V_widen> 1 "s_register_operand" "0")
2380                            (match_operand:VMDI 2 "s_register_operand" "w")
2381                            (match_operand:VMDI 3 "s_register_operand"
2382                                                "<scalar_mul_constraint>")
2383                            (match_operand:SI 4 "immediate_operand" "i")
2384                            (match_operand:SI 5 "immediate_operand" "i")]
2385                           UNSPEC_VQDMLSL_LANE))]
2386   "TARGET_NEON"
2387   "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3[%c4]")
2388
2389 ; FIXME: For the "_n" multiply/multiply-accumulate insns, we copy a value in a
2390 ; core register into a temp register, then use a scalar taken from that. This
2391 ; isn't an optimal solution if e.g. the scalar has just been read from memory
2392 ; or extracted from another vector. The latter case it's currently better to
2393 ; use the "_lane" variant, and the former case can probably be implemented
2394 ; using vld1_lane, but that hasn't been done yet.
2395
2396 (define_expand "neon_vmul_n<mode>"
2397   [(match_operand:VMD 0 "s_register_operand" "")
2398    (match_operand:VMD 1 "s_register_operand" "")
2399    (match_operand:<V_elem> 2 "s_register_operand" "")
2400    (match_operand:SI 3 "immediate_operand" "")]
2401   "TARGET_NEON"
2402 {
2403   rtx tmp = gen_reg_rtx (<MODE>mode);
2404   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
2405   emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
2406                                        const0_rtx, const0_rtx));
2407   DONE;
2408 })
2409
2410 (define_expand "neon_vmul_n<mode>"
2411   [(match_operand:VMQ 0 "s_register_operand" "")
2412    (match_operand:VMQ 1 "s_register_operand" "")
2413    (match_operand:<V_elem> 2 "s_register_operand" "")
2414    (match_operand:SI 3 "immediate_operand" "")]
2415   "TARGET_NEON"
2416 {
2417   rtx tmp = gen_reg_rtx (<V_HALF>mode);
2418   emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
2419   emit_insn (gen_neon_vmul_lane<mode> (operands[0], operands[1], tmp,
2420                                        const0_rtx, const0_rtx));
2421   DONE;
2422 })
2423
2424 (define_expand "neon_vmull_n<mode>"
2425   [(match_operand:<V_widen> 0 "s_register_operand" "")
2426    (match_operand:VMDI 1 "s_register_operand" "")
2427    (match_operand:<V_elem> 2 "s_register_operand" "")
2428    (match_operand:SI 3 "immediate_operand" "")]
2429   "TARGET_NEON"
2430 {
2431   rtx tmp = gen_reg_rtx (<MODE>mode);
2432   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
2433   emit_insn (gen_neon_vmull_lane<mode> (operands[0], operands[1], tmp,
2434                                         const0_rtx, operands[3]));
2435   DONE;
2436 })
2437
2438 (define_expand "neon_vqdmull_n<mode>"
2439   [(match_operand:<V_widen> 0 "s_register_operand" "")
2440    (match_operand:VMDI 1 "s_register_operand" "")
2441    (match_operand:<V_elem> 2 "s_register_operand" "")
2442    (match_operand:SI 3 "immediate_operand" "")]
2443   "TARGET_NEON"
2444 {
2445   rtx tmp = gen_reg_rtx (<MODE>mode);
2446   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
2447   emit_insn (gen_neon_vqdmull_lane<mode> (operands[0], operands[1], tmp,
2448                                           const0_rtx, const0_rtx));
2449   DONE;
2450 })
2451
2452 (define_expand "neon_vqdmulh_n<mode>"
2453   [(match_operand:VMDI 0 "s_register_operand" "")
2454    (match_operand:VMDI 1 "s_register_operand" "")
2455    (match_operand:<V_elem> 2 "s_register_operand" "")
2456    (match_operand:SI 3 "immediate_operand" "")]
2457   "TARGET_NEON"
2458 {
2459   rtx tmp = gen_reg_rtx (<MODE>mode);
2460   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[2], tmp, const0_rtx));
2461   emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
2462                                           const0_rtx, operands[3]));
2463   DONE;
2464 })
2465
2466 (define_expand "neon_vqdmulh_n<mode>"
2467   [(match_operand:VMQI 0 "s_register_operand" "")
2468    (match_operand:VMQI 1 "s_register_operand" "")
2469    (match_operand:<V_elem> 2 "s_register_operand" "")
2470    (match_operand:SI 3 "immediate_operand" "")]
2471   "TARGET_NEON"
2472 {
2473   rtx tmp = gen_reg_rtx (<V_HALF>mode);
2474   emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[2], tmp, const0_rtx));
2475   emit_insn (gen_neon_vqdmulh_lane<mode> (operands[0], operands[1], tmp,
2476                                           const0_rtx, operands[3]));
2477   DONE;
2478 })
2479
2480 (define_expand "neon_vmla_n<mode>"
2481   [(match_operand:VMD 0 "s_register_operand" "")
2482    (match_operand:VMD 1 "s_register_operand" "")
2483    (match_operand:VMD 2 "s_register_operand" "")
2484    (match_operand:<V_elem> 3 "s_register_operand" "")
2485    (match_operand:SI 4 "immediate_operand" "")]
2486   "TARGET_NEON"
2487 {
2488   rtx tmp = gen_reg_rtx (<MODE>mode);
2489   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
2490   emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
2491                                        tmp, const0_rtx, operands[4]));
2492   DONE;
2493 })
2494
2495 (define_expand "neon_vmla_n<mode>"
2496   [(match_operand:VMQ 0 "s_register_operand" "")
2497    (match_operand:VMQ 1 "s_register_operand" "")
2498    (match_operand:VMQ 2 "s_register_operand" "")
2499    (match_operand:<V_elem> 3 "s_register_operand" "")
2500    (match_operand:SI 4 "immediate_operand" "")]
2501   "TARGET_NEON"
2502 {
2503   rtx tmp = gen_reg_rtx (<V_HALF>mode);
2504   emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
2505   emit_insn (gen_neon_vmla_lane<mode> (operands[0], operands[1], operands[2],
2506                                        tmp, const0_rtx, operands[4]));
2507   DONE;
2508 })
2509
2510 (define_expand "neon_vmlal_n<mode>"
2511   [(match_operand:<V_widen> 0 "s_register_operand" "")
2512    (match_operand:<V_widen> 1 "s_register_operand" "")
2513    (match_operand:VMDI 2 "s_register_operand" "")
2514    (match_operand:<V_elem> 3 "s_register_operand" "")
2515    (match_operand:SI 4 "immediate_operand" "")]
2516   "TARGET_NEON"
2517 {
2518   rtx tmp = gen_reg_rtx (<MODE>mode);
2519   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
2520   emit_insn (gen_neon_vmlal_lane<mode> (operands[0], operands[1], operands[2],
2521                                         tmp, const0_rtx, operands[4]));
2522   DONE;
2523 })
2524
2525 (define_expand "neon_vqdmlal_n<mode>"
2526   [(match_operand:<V_widen> 0 "s_register_operand" "")
2527    (match_operand:<V_widen> 1 "s_register_operand" "")
2528    (match_operand:VMDI 2 "s_register_operand" "")
2529    (match_operand:<V_elem> 3 "s_register_operand" "")
2530    (match_operand:SI 4 "immediate_operand" "")]
2531   "TARGET_NEON"
2532 {
2533   rtx tmp = gen_reg_rtx (<MODE>mode);
2534   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
2535   emit_insn (gen_neon_vqdmlal_lane<mode> (operands[0], operands[1], operands[2],
2536                                           tmp, const0_rtx, operands[4]));
2537   DONE;
2538 })
2539
2540 (define_expand "neon_vmls_n<mode>"
2541   [(match_operand:VMD 0 "s_register_operand" "")
2542    (match_operand:VMD 1 "s_register_operand" "")
2543    (match_operand:VMD 2 "s_register_operand" "")
2544    (match_operand:<V_elem> 3 "s_register_operand" "")
2545    (match_operand:SI 4 "immediate_operand" "")]
2546   "TARGET_NEON"
2547 {
2548   rtx tmp = gen_reg_rtx (<MODE>mode);
2549   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
2550   emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
2551                                        tmp, const0_rtx, operands[4]));
2552   DONE;
2553 })
2554
2555 (define_expand "neon_vmls_n<mode>"
2556   [(match_operand:VMQ 0 "s_register_operand" "")
2557    (match_operand:VMQ 1 "s_register_operand" "")
2558    (match_operand:VMQ 2 "s_register_operand" "")
2559    (match_operand:<V_elem> 3 "s_register_operand" "")
2560    (match_operand:SI 4 "immediate_operand" "")]
2561   "TARGET_NEON"
2562 {
2563   rtx tmp = gen_reg_rtx (<V_HALF>mode);
2564   emit_insn (gen_neon_vset_lane<V_half> (tmp, operands[3], tmp, const0_rtx));
2565   emit_insn (gen_neon_vmls_lane<mode> (operands[0], operands[1], operands[2],
2566                                        tmp, const0_rtx, operands[4]));
2567   DONE;
2568 })
2569
2570 (define_expand "neon_vmlsl_n<mode>"
2571   [(match_operand:<V_widen> 0 "s_register_operand" "")
2572    (match_operand:<V_widen> 1 "s_register_operand" "")
2573    (match_operand:VMDI 2 "s_register_operand" "")
2574    (match_operand:<V_elem> 3 "s_register_operand" "")
2575    (match_operand:SI 4 "immediate_operand" "")]
2576   "TARGET_NEON"
2577 {
2578   rtx tmp = gen_reg_rtx (<MODE>mode);
2579   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
2580   emit_insn (gen_neon_vmlsl_lane<mode> (operands[0], operands[1], operands[2],
2581                                         tmp, const0_rtx, operands[4]));
2582   DONE;
2583 })
2584
2585 (define_expand "neon_vqdmlsl_n<mode>"
2586   [(match_operand:<V_widen> 0 "s_register_operand" "")
2587    (match_operand:<V_widen> 1 "s_register_operand" "")
2588    (match_operand:VMDI 2 "s_register_operand" "")
2589    (match_operand:<V_elem> 3 "s_register_operand" "")
2590    (match_operand:SI 4 "immediate_operand" "")]
2591   "TARGET_NEON"
2592 {
2593   rtx tmp = gen_reg_rtx (<MODE>mode);
2594   emit_insn (gen_neon_vset_lane<mode> (tmp, operands[3], tmp, const0_rtx));
2595   emit_insn (gen_neon_vqdmlsl_lane<mode> (operands[0], operands[1], operands[2],
2596                                           tmp, const0_rtx, operands[4]));
2597   DONE;
2598 })
2599
2600 (define_insn "neon_vext<mode>"
2601   [(set (match_operand:VDQX 0 "s_register_operand" "=w")
2602         (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
2603                       (match_operand:VDQX 2 "s_register_operand" "w")
2604                       (match_operand:SI 3 "immediate_operand" "i")]
2605                      UNSPEC_VEXT))]
2606   "TARGET_NEON"
2607   "vext.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2, %3")
2608
2609 (define_insn "neon_vrev64<mode>"
2610   [(set (match_operand:VDQ 0 "s_register_operand" "=w")
2611         (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
2612                      (match_operand:SI 2 "immediate_operand" "i")]
2613                     UNSPEC_VREV64))]
2614   "TARGET_NEON"
2615   "vrev64.<V_sz_elem>\t%<V_reg>0, %<V_reg>1")
2616
2617 (define_insn "neon_vrev32<mode>"
2618   [(set (match_operand:VX 0 "s_register_operand" "=w")
2619         (unspec:VX [(match_operand:VX 1 "s_register_operand" "w")
2620                     (match_operand:SI 2 "immediate_operand" "i")]
2621                    UNSPEC_VREV32))]
2622   "TARGET_NEON"
2623   "vrev32.<V_sz_elem>\t%<V_reg>0, %<V_reg>1")
2624
2625 (define_insn "neon_vrev16<mode>"
2626   [(set (match_operand:VE 0 "s_register_operand" "=w")
2627         (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
2628                     (match_operand:SI 2 "immediate_operand" "i")]
2629                    UNSPEC_VREV16))]
2630   "TARGET_NEON"
2631   "vrev16.<V_sz_elem>\t%<V_reg>0, %<V_reg>1")
2632
2633 ; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
2634 ; allocation. For an intrinsic of form:
2635 ;   rD = vbsl_* (rS, rN, rM)
2636 ; We can use any of:
2637 ;   vbsl rS, rN, rM  (if D = S)
2638 ;   vbit rD, rN, rS  (if D = M, so 1-bits in rS choose bits from rN, else rM)
2639 ;   vbif rD, rM, rS  (if D = N, so 0-bits in rS choose bits from rM, else rN)
2640
2641 (define_insn "neon_vbsl<mode>_internal"
2642   [(set (match_operand:VDQX 0 "s_register_operand"               "=w,w,w")
2643         (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" " 0,w,w")
2644                       (match_operand:VDQX 2 "s_register_operand" " w,w,0")
2645                       (match_operand:VDQX 3 "s_register_operand" " w,0,w")]
2646                      UNSPEC_VBSL))]
2647   "TARGET_NEON"
2648   "@
2649   vbsl\t%<V_reg>0, %<V_reg>2, %<V_reg>3
2650   vbit\t%<V_reg>0, %<V_reg>2, %<V_reg>1
2651   vbif\t%<V_reg>0, %<V_reg>3, %<V_reg>1")
2652
2653 (define_expand "neon_vbsl<mode>"
2654   [(set (match_operand:VDQX 0 "s_register_operand" "")
2655         (unspec:VDQX [(match_operand:<V_cmp_result> 1 "s_register_operand" "")
2656                       (match_operand:VDQX 2 "s_register_operand" "")
2657                       (match_operand:VDQX 3 "s_register_operand" "")]
2658                      UNSPEC_VBSL))]
2659   "TARGET_NEON"
2660 {
2661   /* We can't alias operands together if they have different modes.  */
2662   operands[1] = gen_lowpart (<MODE>mode, operands[1]);
2663 })
2664
2665 (define_insn "neon_vshl<mode>"
2666   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2667         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2668                        (match_operand:VDQIX 2 "s_register_operand" "w")
2669                        (match_operand:SI 3 "immediate_operand" "i")]
2670                       UNSPEC_VSHL))]
2671   "TARGET_NEON"
2672   "v%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
2673
2674 (define_insn "neon_vqshl<mode>"
2675   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2676         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2677                        (match_operand:VDQIX 2 "s_register_operand" "w")
2678                        (match_operand:SI 3 "immediate_operand" "i")]
2679                       UNSPEC_VQSHL))]
2680   "TARGET_NEON"
2681   "vq%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2")
2682
2683 (define_insn "neon_vshr_n<mode>"
2684   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2685         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2686                        (match_operand:SI 2 "immediate_operand" "i")
2687                        (match_operand:SI 3 "immediate_operand" "i")]
2688                       UNSPEC_VSHR_N))]
2689   "TARGET_NEON"
2690   "v%O3shr.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2")
2691
2692 (define_insn "neon_vshrn_n<mode>"
2693   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2694         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2695                             (match_operand:SI 2 "immediate_operand" "i")
2696                             (match_operand:SI 3 "immediate_operand" "i")]
2697                            UNSPEC_VSHRN_N))]
2698   "TARGET_NEON"
2699   "v%O3shrn.<V_if_elem>\t%P0, %q1, %2")
2700
2701 (define_insn "neon_vqshrn_n<mode>"
2702   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2703         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2704                             (match_operand:SI 2 "immediate_operand" "i")
2705                             (match_operand:SI 3 "immediate_operand" "i")]
2706                            UNSPEC_VQSHRN_N))]
2707   "TARGET_NEON"
2708   "vq%O3shrn.%T3%#<V_sz_elem>\t%P0, %q1, %2")
2709
2710 (define_insn "neon_vqshrun_n<mode>"
2711   [(set (match_operand:<V_narrow> 0 "s_register_operand" "=w")
2712         (unspec:<V_narrow> [(match_operand:VN 1 "s_register_operand" "w")
2713                             (match_operand:SI 2 "immediate_operand" "i")
2714                             (match_operand:SI 3 "immediate_operand" "i")]
2715                            UNSPEC_VQSHRUN_N))]
2716   "TARGET_NEON"
2717   "vq%O3shrun.%T3%#<V_sz_elem>\t%P0, %q1, %2")
2718
2719 (define_insn "neon_vshl_n<mode>"
2720   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2721         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2722                        (match_operand:SI 2 "immediate_operand" "i")
2723                        (match_operand:SI 3 "immediate_operand" "i")]
2724                       UNSPEC_VSHL_N))]
2725   "TARGET_NEON"
2726   "vshl.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %2")
2727
2728 (define_insn "neon_vqshl_n<mode>"
2729   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2730         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2731                        (match_operand:SI 2 "immediate_operand" "i")
2732                        (match_operand:SI 3 "immediate_operand" "i")]
2733                       UNSPEC_VQSHL_N))]
2734   "TARGET_NEON"
2735   "vqshl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2")
2736
2737 (define_insn "neon_vqshlu_n<mode>"
2738   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2739         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2740                        (match_operand:SI 2 "immediate_operand" "i")
2741                        (match_operand:SI 3 "immediate_operand" "i")]
2742                       UNSPEC_VQSHLU_N))]
2743   "TARGET_NEON"
2744   "vqshlu.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2")
2745
2746 (define_insn "neon_vshll_n<mode>"
2747   [(set (match_operand:<V_widen> 0 "s_register_operand" "=w")
2748         (unspec:<V_widen> [(match_operand:VW 1 "s_register_operand" "w")
2749                            (match_operand:SI 2 "immediate_operand" "i")
2750                            (match_operand:SI 3 "immediate_operand" "i")]
2751                           UNSPEC_VSHLL_N))]
2752   "TARGET_NEON"
2753   "vshll.%T3%#<V_sz_elem>\t%q0, %P1, %2")
2754
2755 (define_insn "neon_vsra_n<mode>"
2756   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2757         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
2758                        (match_operand:VDQIX 2 "s_register_operand" "w")
2759                        (match_operand:SI 3 "immediate_operand" "i")
2760                        (match_operand:SI 4 "immediate_operand" "i")]
2761                       UNSPEC_VSRA_N))]
2762   "TARGET_NEON"
2763   "v%O4sra.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3")
2764
2765 (define_insn "neon_vsri_n<mode>"
2766   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2767         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
2768                        (match_operand:VDQIX 2 "s_register_operand" "w")
2769                        (match_operand:SI 3 "immediate_operand" "i")]
2770                       UNSPEC_VSRI))]
2771   "TARGET_NEON"
2772   "vsri.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3")
2773
2774 (define_insn "neon_vsli_n<mode>"
2775   [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2776         (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
2777                        (match_operand:VDQIX 2 "s_register_operand" "w")
2778                        (match_operand:SI 3 "immediate_operand" "i")]
2779                       UNSPEC_VSLI))]
2780   "TARGET_NEON"
2781   "vsli.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3")
2782
2783 (define_insn "neon_vtbl1v8qi"
2784   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2785         (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "w")
2786                       (match_operand:V8QI 2 "s_register_operand" "w")]
2787                      UNSPEC_VTBL))]
2788   "TARGET_NEON"
2789   "vtbl.8\t%P0, {%P1}, %P2")
2790
2791 (define_insn "neon_vtbl2v8qi"
2792   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2793         (unspec:V8QI [(match_operand:TI 1 "s_register_operand" "w")
2794                       (match_operand:V8QI 2 "s_register_operand" "w")]
2795                      UNSPEC_VTBL))]
2796   "TARGET_NEON"
2797 {
2798   rtx ops[4];
2799   int tabbase = REGNO (operands[1]);
2800
2801   ops[0] = operands[0];
2802   ops[1] = gen_rtx_REG (V8QImode, tabbase);
2803   ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
2804   ops[3] = operands[2];
2805   output_asm_insn ("vtbl.8\t%P0, {%P1, %P2}, %P3", ops);
2806
2807   return "";
2808 })
2809
2810 (define_insn "neon_vtbl3v8qi"
2811   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2812         (unspec:V8QI [(match_operand:EI 1 "s_register_operand" "w")
2813                       (match_operand:V8QI 2 "s_register_operand" "w")]
2814                      UNSPEC_VTBL))]
2815   "TARGET_NEON"
2816 {
2817   rtx ops[5];
2818   int tabbase = REGNO (operands[1]);
2819
2820   ops[0] = operands[0];
2821   ops[1] = gen_rtx_REG (V8QImode, tabbase);
2822   ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
2823   ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
2824   ops[4] = operands[2];
2825   output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
2826
2827   return "";
2828 })
2829
2830 (define_insn "neon_vtbl4v8qi"
2831   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2832         (unspec:V8QI [(match_operand:OI 1 "s_register_operand" "w")
2833                       (match_operand:V8QI 2 "s_register_operand" "w")]
2834                      UNSPEC_VTBL))]
2835   "TARGET_NEON"
2836 {
2837   rtx ops[6];
2838   int tabbase = REGNO (operands[1]);
2839
2840   ops[0] = operands[0];
2841   ops[1] = gen_rtx_REG (V8QImode, tabbase);
2842   ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
2843   ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
2844   ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
2845   ops[5] = operands[2];
2846   output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
2847
2848   return "";
2849 })
2850
2851 (define_insn "neon_vtbx1v8qi"
2852   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2853         (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
2854                       (match_operand:V8QI 2 "s_register_operand" "w")
2855                       (match_operand:V8QI 3 "s_register_operand" "w")]
2856                      UNSPEC_VTBX))]
2857   "TARGET_NEON"
2858   "vtbx.8\t%P0, {%P2}, %P3")
2859
2860 (define_insn "neon_vtbx2v8qi"
2861   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2862         (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
2863                       (match_operand:TI 2 "s_register_operand" "w")
2864                       (match_operand:V8QI 3 "s_register_operand" "w")]
2865                      UNSPEC_VTBX))]
2866   "TARGET_NEON"
2867 {
2868   rtx ops[4];
2869   int tabbase = REGNO (operands[2]);
2870
2871   ops[0] = operands[0];
2872   ops[1] = gen_rtx_REG (V8QImode, tabbase);
2873   ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
2874   ops[3] = operands[3];
2875   output_asm_insn ("vtbx.8\t%P0, {%P1, %P2}, %P3", ops);
2876
2877   return "";
2878 })
2879
2880 (define_insn "neon_vtbx3v8qi"
2881   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2882         (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
2883                       (match_operand:EI 2 "s_register_operand" "w")
2884                       (match_operand:V8QI 3 "s_register_operand" "w")]
2885                      UNSPEC_VTBX))]
2886   "TARGET_NEON"
2887 {
2888   rtx ops[5];
2889   int tabbase = REGNO (operands[2]);
2890
2891   ops[0] = operands[0];
2892   ops[1] = gen_rtx_REG (V8QImode, tabbase);
2893   ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
2894   ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
2895   ops[4] = operands[3];
2896   output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
2897
2898   return "";
2899 })
2900
2901 (define_insn "neon_vtbx4v8qi"
2902   [(set (match_operand:V8QI 0 "s_register_operand" "=w")
2903         (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
2904                       (match_operand:OI 2 "s_register_operand" "w")
2905                       (match_operand:V8QI 3 "s_register_operand" "w")]
2906                      UNSPEC_VTBX))]
2907   "TARGET_NEON"
2908 {
2909   rtx ops[6];
2910   int tabbase = REGNO (operands[2]);
2911
2912   ops[0] = operands[0];
2913   ops[1] = gen_rtx_REG (V8QImode, tabbase);
2914   ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
2915   ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
2916   ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
2917   ops[5] = operands[3];
2918   output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
2919
2920   return "";
2921 })
2922
2923 (define_insn "neon_vtrn<mode>_internal"
2924   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2925         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
2926                      UNSPEC_VTRN1))
2927    (set (match_operand:VDQW 2 "s_register_operand" "=w")
2928         (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
2929                      UNSPEC_VTRN2))]
2930   "TARGET_NEON"
2931   "vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>2")
2932
2933 (define_expand "neon_vtrn<mode>"
2934   [(match_operand:SI 0 "s_register_operand" "r")
2935    (match_operand:VDQW 1 "s_register_operand" "w")
2936    (match_operand:VDQW 2 "s_register_operand" "w")]
2937   "TARGET_NEON"
2938 {
2939   neon_emit_pair_result_insn (<MODE>mode, gen_neon_vtrn<mode>_internal,
2940                               operands[0], operands[1], operands[2]);
2941   DONE;
2942 })
2943
2944 (define_insn "neon_vzip<mode>_internal"
2945   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2946         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
2947                      UNSPEC_VZIP1))
2948    (set (match_operand:VDQW 2 "s_register_operand" "=w")
2949         (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
2950                      UNSPEC_VZIP2))]
2951   "TARGET_NEON"
2952   "vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>2")
2953
2954 (define_expand "neon_vzip<mode>"
2955   [(match_operand:SI 0 "s_register_operand" "r")
2956    (match_operand:VDQW 1 "s_register_operand" "w")
2957    (match_operand:VDQW 2 "s_register_operand" "w")]
2958   "TARGET_NEON"
2959 {
2960   neon_emit_pair_result_insn (<MODE>mode, gen_neon_vzip<mode>_internal,
2961                               operands[0], operands[1], operands[2]);
2962   DONE;
2963 })
2964
2965 (define_insn "neon_vuzp<mode>_internal"
2966   [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2967         (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
2968                      UNSPEC_VUZP1))
2969    (set (match_operand:VDQW 2 "s_register_operand" "=w")
2970         (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
2971                      UNSPEC_VUZP2))]
2972   "TARGET_NEON"
2973   "vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>2")
2974
2975 (define_expand "neon_vuzp<mode>"
2976   [(match_operand:SI 0 "s_register_operand" "r")
2977    (match_operand:VDQW 1 "s_register_operand" "w")
2978    (match_operand:VDQW 2 "s_register_operand" "w")]
2979   "TARGET_NEON"
2980 {
2981   neon_emit_pair_result_insn (<MODE>mode, gen_neon_vuzp<mode>_internal,
2982                               operands[0], operands[1], operands[2]);
2983   DONE;
2984 })
2985
2986 (define_expand "neon_vreinterpretv8qi<mode>"
2987   [(match_operand:V8QI 0 "s_register_operand" "")
2988    (match_operand:VDX 1 "s_register_operand" "")]
2989   "TARGET_NEON"
2990 {
2991   neon_reinterpret (operands[0], operands[1]);
2992   DONE;
2993 })
2994
2995 (define_expand "neon_vreinterpretv4hi<mode>"
2996   [(match_operand:V4HI 0 "s_register_operand" "")
2997    (match_operand:VDX 1 "s_register_operand" "")]
2998   "TARGET_NEON"
2999 {
3000   neon_reinterpret (operands[0], operands[1]);
3001   DONE;
3002 })
3003
3004 (define_expand "neon_vreinterpretv2si<mode>"
3005   [(match_operand:V2SI 0 "s_register_operand" "")
3006    (match_operand:VDX 1 "s_register_operand" "")]
3007   "TARGET_NEON"
3008 {
3009   neon_reinterpret (operands[0], operands[1]);
3010   DONE;
3011 })
3012
3013 (define_expand "neon_vreinterpretv2sf<mode>"
3014   [(match_operand:V2SF 0 "s_register_operand" "")
3015    (match_operand:VDX 1 "s_register_operand" "")]
3016   "TARGET_NEON"
3017 {
3018   neon_reinterpret (operands[0], operands[1]);
3019   DONE;
3020 })
3021
3022 (define_expand "neon_vreinterpretdi<mode>"
3023   [(match_operand:DI 0 "s_register_operand" "")
3024    (match_operand:VDX 1 "s_register_operand" "")]
3025   "TARGET_NEON"
3026 {
3027   neon_reinterpret (operands[0], operands[1]);
3028   DONE;
3029 })
3030
3031 (define_expand "neon_vreinterpretv16qi<mode>"
3032   [(match_operand:V16QI 0 "s_register_operand" "")
3033    (match_operand:VQX 1 "s_register_operand" "")]
3034   "TARGET_NEON"
3035 {
3036   neon_reinterpret (operands[0], operands[1]);
3037   DONE;
3038 })
3039
3040 (define_expand "neon_vreinterpretv8hi<mode>"
3041   [(match_operand:V8HI 0 "s_register_operand" "")
3042    (match_operand:VQX 1 "s_register_operand" "")]
3043   "TARGET_NEON"
3044 {
3045   neon_reinterpret (operands[0], operands[1]);
3046   DONE;
3047 })
3048
3049 (define_expand "neon_vreinterpretv4si<mode>"
3050   [(match_operand:V4SI 0 "s_register_operand" "")
3051    (match_operand:VQX 1 "s_register_operand" "")]
3052   "TARGET_NEON"
3053 {
3054   neon_reinterpret (operands[0], operands[1]);
3055   DONE;
3056 })
3057
3058 (define_expand "neon_vreinterpretv4sf<mode>"
3059   [(match_operand:V4SF 0 "s_register_operand" "")
3060    (match_operand:VQX 1 "s_register_operand" "")]
3061   "TARGET_NEON"
3062 {
3063   neon_reinterpret (operands[0], operands[1]);
3064   DONE;
3065 })
3066
3067 (define_expand "neon_vreinterpretv2di<mode>"
3068   [(match_operand:V2DI 0 "s_register_operand" "")
3069    (match_operand:VQX 1 "s_register_operand" "")]
3070   "TARGET_NEON"
3071 {
3072   neon_reinterpret (operands[0], operands[1]);
3073   DONE;
3074 })
3075
3076 (define_insn "neon_vld1<mode>"
3077   [(set (match_operand:VDQX 0 "s_register_operand" "=w")
3078         (unspec:VDQX [(mem:VDQX (match_operand:SI 1 "s_register_operand" "r"))]
3079                     UNSPEC_VLD1))]
3080   "TARGET_NEON"
3081   "vld1.<V_sz_elem>\t%h0, [%1]")
3082
3083 (define_insn "neon_vld1_lane<mode>"
3084   [(set (match_operand:VDX 0 "s_register_operand" "=w")
3085         (unspec:VDX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))
3086                      (match_operand:VDX 2 "s_register_operand" "0")
3087                      (match_operand:SI 3 "immediate_operand" "i")]
3088                     UNSPEC_VLD1_LANE))]
3089   "TARGET_NEON"
3090 {
3091   HOST_WIDE_INT lane = INTVAL (operands[3]);
3092   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3093   if (lane < 0 || lane >= max)
3094     error ("lane out of range");
3095   if (max == 1)
3096     return "vld1.<V_sz_elem>\t%P0, [%1]";
3097   else
3098     return "vld1.<V_sz_elem>\t{%P0[%c3]}, [%1]";
3099 })
3100
3101 (define_insn "neon_vld1_lane<mode>"
3102   [(set (match_operand:VQX 0 "s_register_operand" "=w")
3103         (unspec:VQX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))
3104                      (match_operand:VQX 2 "s_register_operand" "0")
3105                      (match_operand:SI 3 "immediate_operand" "i")]
3106                     UNSPEC_VLD1_LANE))]
3107   "TARGET_NEON"
3108 {
3109   HOST_WIDE_INT lane = INTVAL (operands[3]);
3110   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3111   int regno = REGNO (operands[0]);
3112   if (lane < 0 || lane >= max)
3113     error ("lane out of range");
3114   else if (lane >= max / 2)
3115     {
3116       lane -= max / 2;
3117       regno += 2;
3118       operands[3] = GEN_INT (lane);
3119     }
3120   operands[0] = gen_rtx_REG (<V_HALF>mode, regno);
3121   if (max == 2)
3122     return "vld1.<V_sz_elem>\t%P0, [%1]";
3123   else
3124     return "vld1.<V_sz_elem>\t{%P0[%c3]}, [%1]";
3125 })
3126
3127 (define_insn "neon_vld1_dup<mode>"
3128   [(set (match_operand:VDX 0 "s_register_operand" "=w")
3129         (unspec:VDX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))]
3130                     UNSPEC_VLD1_DUP))]
3131   "TARGET_NEON"
3132 {
3133   if (GET_MODE_NUNITS (<MODE>mode) > 1)
3134     return "vld1.<V_sz_elem>\t{%P0[]}, [%1]";
3135   else
3136     return "vld1.<V_sz_elem>\t%h0, [%1]";
3137 })
3138
3139 (define_insn "neon_vld1_dup<mode>"
3140   [(set (match_operand:VQX 0 "s_register_operand" "=w")
3141         (unspec:VQX [(mem:<V_elem> (match_operand:SI 1 "s_register_operand" "r"))]
3142                     UNSPEC_VLD1_DUP))]
3143   "TARGET_NEON"
3144 {
3145   if (GET_MODE_NUNITS (<MODE>mode) > 2)
3146     return "vld1.<V_sz_elem>\t{%e0[], %f0[]}, [%1]";
3147   else
3148     return "vld1.<V_sz_elem>\t%h0, [%1]";
3149 })
3150
3151 (define_insn "neon_vst1<mode>"
3152   [(set (mem:VDQX (match_operand:SI 0 "s_register_operand" "r"))
3153         (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")]
3154                      UNSPEC_VST1))]
3155   "TARGET_NEON"
3156   "vst1.<V_sz_elem>\t%h1, [%0]")
3157
3158 (define_insn "neon_vst1_lane<mode>"
3159   [(set (mem:<V_elem> (match_operand:SI 0 "s_register_operand" "r"))
3160         (vec_select:<V_elem>
3161           (match_operand:VDX 1 "s_register_operand" "w")
3162           (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
3163   "TARGET_NEON"
3164 {
3165   HOST_WIDE_INT lane = INTVAL (operands[2]);
3166   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3167   if (lane < 0 || lane >= max)
3168     error ("lane out of range");
3169   if (max == 1)
3170     return "vst1.<V_sz_elem>\t{%P1}, [%0]";
3171   else
3172     return "vst1.<V_sz_elem>\t{%P1[%c2]}, [%0]";
3173 })
3174
3175 (define_insn "neon_vst1_lane<mode>"
3176   [(set (mem:<V_elem> (match_operand:SI 0 "s_register_operand" "r"))
3177         (vec_select:<V_elem>
3178            (match_operand:VQX 1 "s_register_operand" "w")
3179            (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
3180   "TARGET_NEON"
3181 {
3182   HOST_WIDE_INT lane = INTVAL (operands[2]);
3183   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3184   int regno = REGNO (operands[1]);
3185   if (lane < 0 || lane >= max)
3186     error ("lane out of range");
3187   else if (lane >= max / 2)
3188     {
3189       lane -= max / 2;
3190       regno += 2;
3191       operands[2] = GEN_INT (lane);
3192     }
3193   operands[1] = gen_rtx_REG (<V_HALF>mode, regno);
3194   if (max == 2)
3195     return "vst1.<V_sz_elem>\t{%P1}, [%0]";
3196   else
3197     return "vst1.<V_sz_elem>\t{%P1[%c2]}, [%0]";
3198 })
3199
3200 (define_insn "neon_vld2<mode>"
3201   [(set (match_operand:TI 0 "s_register_operand" "=w")
3202         (unspec:TI [(mem:TI (match_operand:SI 1 "s_register_operand" "r"))
3203                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3204                    UNSPEC_VLD2))]
3205   "TARGET_NEON"
3206 {
3207   if (<V_sz_elem> == 64)
3208     return "vld1.64\t%h0, [%1]";
3209   else
3210     return "vld2.<V_sz_elem>\t%h0, [%1]";
3211 })
3212
3213 (define_insn "neon_vld2<mode>"
3214   [(set (match_operand:OI 0 "s_register_operand" "=w")
3215         (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
3216                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3217                    UNSPEC_VLD2))]
3218   "TARGET_NEON"
3219   "vld2.<V_sz_elem>\t%h0, [%1]")
3220
3221 (define_insn "neon_vld2_lane<mode>"
3222   [(set (match_operand:TI 0 "s_register_operand" "=w")
3223         (unspec:TI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
3224                     (match_operand:TI 2 "s_register_operand" "0")
3225                     (match_operand:SI 3 "immediate_operand" "i")
3226                     (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3227                    UNSPEC_VLD2_LANE))]
3228   "TARGET_NEON"
3229 {
3230   HOST_WIDE_INT lane = INTVAL (operands[3]);
3231   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3232   int regno = REGNO (operands[0]);
3233   rtx ops[4];
3234   if (lane < 0 || lane >= max)
3235     error ("lane out of range");
3236   ops[0] = gen_rtx_REG (DImode, regno);
3237   ops[1] = gen_rtx_REG (DImode, regno + 2);
3238   ops[2] = operands[1];
3239   ops[3] = operands[3];
3240   output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
3241   return "";
3242 })
3243
3244 (define_insn "neon_vld2_lane<mode>"
3245   [(set (match_operand:OI 0 "s_register_operand" "=w")
3246         (unspec:OI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
3247                     (match_operand:OI 2 "s_register_operand" "0")
3248                     (match_operand:SI 3 "immediate_operand" "i")
3249                     (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3250                    UNSPEC_VLD2_LANE))]
3251   "TARGET_NEON"
3252 {
3253   HOST_WIDE_INT lane = INTVAL (operands[3]);
3254   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3255   int regno = REGNO (operands[0]);
3256   rtx ops[4];
3257   if (lane < 0 || lane >= max)
3258     error ("lane out of range");
3259   else if (lane >= max / 2)
3260     {
3261       lane -= max / 2;
3262       regno += 2;
3263     }
3264   ops[0] = gen_rtx_REG (DImode, regno);
3265   ops[1] = gen_rtx_REG (DImode, regno + 4);
3266   ops[2] = operands[1];
3267   ops[3] = GEN_INT (lane);
3268   output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
3269   return "";
3270 })
3271
3272 (define_insn "neon_vld2_dup<mode>"
3273   [(set (match_operand:TI 0 "s_register_operand" "=w")
3274         (unspec:TI [(mem:<V_two_elem> (match_operand:SI 1 "s_register_operand" "r"))
3275                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3276                    UNSPEC_VLD2_DUP))]
3277   "TARGET_NEON"
3278 {
3279   if (GET_MODE_NUNITS (<MODE>mode) > 1)
3280     return "vld2.<V_sz_elem>\t{%e0[], %f0[]}, [%1]";
3281   else
3282     return "vld1.<V_sz_elem>\t%h0, [%1]";
3283 })
3284
3285 (define_insn "neon_vst2<mode>"
3286   [(set (mem:TI (match_operand:SI 0 "s_register_operand" "r"))
3287         (unspec:TI [(match_operand:TI 1 "s_register_operand" "w")
3288                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3289                    UNSPEC_VST2))]
3290   "TARGET_NEON"
3291 {
3292   if (<V_sz_elem> == 64)
3293     return "vst1.64\t%h1, [%0]";
3294   else
3295     return "vst2.<V_sz_elem>\t%h1, [%0]";
3296 })
3297
3298 (define_insn "neon_vst2<mode>"
3299   [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
3300         (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
3301                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3302                    UNSPEC_VST2))]
3303   "TARGET_NEON"
3304   "vst2.<V_sz_elem>\t%h1, [%0]")
3305
3306 (define_insn "neon_vst2_lane<mode>"
3307   [(set (mem:<V_two_elem> (match_operand:SI 0 "s_register_operand" "r"))
3308         (unspec:<V_two_elem>
3309           [(match_operand:TI 1 "s_register_operand" "w")
3310            (match_operand:SI 2 "immediate_operand" "i")
3311            (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3312           UNSPEC_VST2_LANE))]
3313   "TARGET_NEON"
3314 {
3315   HOST_WIDE_INT lane = INTVAL (operands[2]);
3316   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3317   int regno = REGNO (operands[1]);
3318   rtx ops[4];
3319   if (lane < 0 || lane >= max)
3320     error ("lane out of range");
3321   ops[0] = operands[0];
3322   ops[1] = gen_rtx_REG (DImode, regno);
3323   ops[2] = gen_rtx_REG (DImode, regno + 2);
3324   ops[3] = operands[2];
3325   output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
3326   return "";
3327 })
3328
3329 (define_insn "neon_vst2_lane<mode>"
3330   [(set (mem:<V_two_elem> (match_operand:SI 0 "s_register_operand" "r"))
3331         (unspec:<V_two_elem>
3332            [(match_operand:OI 1 "s_register_operand" "w")
3333             (match_operand:SI 2 "immediate_operand" "i")
3334             (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3335            UNSPEC_VST2_LANE))]
3336   "TARGET_NEON"
3337 {
3338   HOST_WIDE_INT lane = INTVAL (operands[2]);
3339   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3340   int regno = REGNO (operands[1]);
3341   rtx ops[4];
3342   if (lane < 0 || lane >= max)
3343     error ("lane out of range");
3344   else if (lane >= max / 2)
3345     {
3346       lane -= max / 2;
3347       regno += 2;
3348     }
3349   ops[0] = operands[0];
3350   ops[1] = gen_rtx_REG (DImode, regno);
3351   ops[2] = gen_rtx_REG (DImode, regno + 4);
3352   ops[3] = GEN_INT (lane);
3353   output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
3354   return "";
3355 })
3356
3357 (define_insn "neon_vld3<mode>"
3358   [(set (match_operand:EI 0 "s_register_operand" "=w")
3359         (unspec:EI [(mem:EI (match_operand:SI 1 "s_register_operand" "r"))
3360                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3361                    UNSPEC_VLD3))]
3362   "TARGET_NEON"
3363 {
3364   if (<V_sz_elem> == 64)
3365     return "vld1.64\t%h0, [%1]";
3366   else
3367     return "vld3.<V_sz_elem>\t%h0, [%1]";
3368 })
3369
3370 (define_expand "neon_vld3<mode>"
3371   [(match_operand:CI 0 "s_register_operand" "=w")
3372    (match_operand:SI 1 "s_register_operand" "+r")
3373    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3374   "TARGET_NEON"
3375 {
3376   emit_insn (gen_neon_vld3qa<mode> (operands[0], operands[0],
3377                                     operands[1], operands[1]));
3378   emit_insn (gen_neon_vld3qb<mode> (operands[0], operands[0],
3379                                     operands[1], operands[1]));
3380   DONE;
3381 })
3382
3383 (define_insn "neon_vld3qa<mode>"
3384   [(set (match_operand:CI 0 "s_register_operand" "=w")
3385         (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
3386                     (match_operand:CI 1 "s_register_operand" "0")
3387                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3388                    UNSPEC_VLD3A))
3389    (set (match_operand:SI 2 "s_register_operand" "=r")
3390         (plus:SI (match_dup 3)
3391                  (const_int 24)))]
3392   "TARGET_NEON"
3393 {
3394   int regno = REGNO (operands[0]);
3395   rtx ops[4];
3396   ops[0] = gen_rtx_REG (DImode, regno);
3397   ops[1] = gen_rtx_REG (DImode, regno + 4);
3398   ops[2] = gen_rtx_REG (DImode, regno + 8);
3399   ops[3] = operands[2];
3400   output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, [%3]!", ops);
3401   return "";
3402 })
3403
3404 (define_insn "neon_vld3qb<mode>"
3405   [(set (match_operand:CI 0 "s_register_operand" "=w")
3406         (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
3407                     (match_operand:CI 1 "s_register_operand" "0")
3408                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3409                    UNSPEC_VLD3B))
3410    (set (match_operand:SI 2 "s_register_operand" "=r")
3411         (plus:SI (match_dup 3)
3412                  (const_int 24)))]
3413   "TARGET_NEON"
3414 {
3415   int regno = REGNO (operands[0]);
3416   rtx ops[4];
3417   ops[0] = gen_rtx_REG (DImode, regno + 2);
3418   ops[1] = gen_rtx_REG (DImode, regno + 6);
3419   ops[2] = gen_rtx_REG (DImode, regno + 10);
3420   ops[3] = operands[2];
3421   output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, [%3]!", ops);
3422   return "";
3423 })
3424
3425 (define_insn "neon_vld3_lane<mode>"
3426   [(set (match_operand:EI 0 "s_register_operand" "=w")
3427         (unspec:EI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
3428                     (match_operand:EI 2 "s_register_operand" "0")
3429                     (match_operand:SI 3 "immediate_operand" "i")
3430                     (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3431                    UNSPEC_VLD3_LANE))]
3432   "TARGET_NEON"
3433 {
3434   HOST_WIDE_INT lane = INTVAL (operands[3]);
3435   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3436   int regno = REGNO (operands[0]);
3437   rtx ops[5];
3438   if (lane < 0 || lane >= max)
3439     error ("lane out of range");
3440   ops[0] = gen_rtx_REG (DImode, regno);
3441   ops[1] = gen_rtx_REG (DImode, regno + 2);
3442   ops[2] = gen_rtx_REG (DImode, regno + 4);
3443   ops[3] = operands[1];
3444   ops[4] = operands[3];
3445   output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
3446                    ops);
3447   return "";
3448 })
3449
3450 (define_insn "neon_vld3_lane<mode>"
3451   [(set (match_operand:CI 0 "s_register_operand" "=w")
3452         (unspec:CI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
3453                     (match_operand:CI 2 "s_register_operand" "0")
3454                     (match_operand:SI 3 "immediate_operand" "i")
3455                     (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3456                    UNSPEC_VLD3_LANE))]
3457   "TARGET_NEON"
3458 {
3459   HOST_WIDE_INT lane = INTVAL (operands[3]);
3460   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3461   int regno = REGNO (operands[0]);
3462   rtx ops[5];
3463   if (lane < 0 || lane >= max)
3464     error ("lane out of range");
3465   else if (lane >= max / 2)
3466     {
3467       lane -= max / 2;
3468       regno += 2;
3469     }
3470   ops[0] = gen_rtx_REG (DImode, regno);
3471   ops[1] = gen_rtx_REG (DImode, regno + 4);
3472   ops[2] = gen_rtx_REG (DImode, regno + 8);
3473   ops[3] = operands[1];
3474   ops[4] = GEN_INT (lane);
3475   output_asm_insn ("vld3.<V_sz_elem>\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
3476                    ops);
3477   return "";
3478 })
3479
3480 (define_insn "neon_vld3_dup<mode>"
3481   [(set (match_operand:EI 0 "s_register_operand" "=w")
3482         (unspec:EI [(mem:<V_three_elem> (match_operand:SI 1 "s_register_operand" "r"))
3483                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3484                    UNSPEC_VLD3_DUP))]
3485   "TARGET_NEON"
3486 {
3487   if (GET_MODE_NUNITS (<MODE>mode) > 1)
3488     {
3489       int regno = REGNO (operands[0]);
3490       rtx ops[4];
3491       ops[0] = gen_rtx_REG (DImode, regno);
3492       ops[1] = gen_rtx_REG (DImode, regno + 2);
3493       ops[2] = gen_rtx_REG (DImode, regno + 4);
3494       ops[3] = operands[1];
3495       output_asm_insn ("vld3.<V_sz_elem>\t{%P0[], %P1[], %P2[]}, [%3]", ops);
3496       return "";
3497     }
3498   else
3499     return "vld1.<V_sz_elem>\t%h0, [%1]";
3500 })
3501
3502 (define_insn "neon_vst3<mode>"
3503   [(set (mem:EI (match_operand:SI 0 "s_register_operand" "r"))
3504         (unspec:EI [(match_operand:EI 1 "s_register_operand" "w")
3505                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3506                    UNSPEC_VST3))]
3507   "TARGET_NEON"
3508 {
3509   if (<V_sz_elem> == 64)
3510     return "vst1.64\t%h1, [%0]";
3511   else
3512     return "vst3.<V_sz_elem>\t%h1, [%0]";
3513 })
3514
3515 (define_expand "neon_vst3<mode>"
3516   [(match_operand:SI 0 "s_register_operand" "+r")
3517    (match_operand:CI 1 "s_register_operand" "w")
3518    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3519   "TARGET_NEON"
3520 {
3521   emit_insn (gen_neon_vst3qa<mode> (operands[0], operands[0], operands[1]));
3522   emit_insn (gen_neon_vst3qb<mode> (operands[0], operands[0], operands[1]));
3523   DONE;
3524 })
3525
3526 (define_insn "neon_vst3qa<mode>"
3527   [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
3528         (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
3529                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3530                    UNSPEC_VST3A))
3531    (set (match_operand:SI 0 "s_register_operand" "=r")
3532         (plus:SI (match_dup 1)
3533                  (const_int 24)))]
3534   "TARGET_NEON"
3535 {
3536   int regno = REGNO (operands[2]);
3537   rtx ops[4];
3538   ops[0] = operands[0];
3539   ops[1] = gen_rtx_REG (DImode, regno);
3540   ops[2] = gen_rtx_REG (DImode, regno + 4);
3541   ops[3] = gen_rtx_REG (DImode, regno + 8);
3542   output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, [%0]!", ops);
3543   return "";
3544 })
3545
3546 (define_insn "neon_vst3qb<mode>"
3547   [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
3548         (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
3549                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3550                    UNSPEC_VST3B))
3551    (set (match_operand:SI 0 "s_register_operand" "=r")
3552         (plus:SI (match_dup 1)
3553                  (const_int 24)))]
3554   "TARGET_NEON"
3555 {
3556   int regno = REGNO (operands[2]);
3557   rtx ops[4];
3558   ops[0] = operands[0];
3559   ops[1] = gen_rtx_REG (DImode, regno + 2);
3560   ops[2] = gen_rtx_REG (DImode, regno + 6);
3561   ops[3] = gen_rtx_REG (DImode, regno + 10);
3562   output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, [%0]!", ops);
3563   return "";
3564 })
3565
3566 (define_insn "neon_vst3_lane<mode>"
3567   [(set (mem:<V_three_elem> (match_operand:SI 0 "s_register_operand" "r"))
3568         (unspec:<V_three_elem>
3569            [(match_operand:EI 1 "s_register_operand" "w")
3570             (match_operand:SI 2 "immediate_operand" "i")
3571             (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3572            UNSPEC_VST3_LANE))]
3573   "TARGET_NEON"
3574 {
3575   HOST_WIDE_INT lane = INTVAL (operands[2]);
3576   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3577   int regno = REGNO (operands[1]);
3578   rtx ops[5];
3579   if (lane < 0 || lane >= max)
3580     error ("lane out of range");
3581   ops[0] = operands[0];
3582   ops[1] = gen_rtx_REG (DImode, regno);
3583   ops[2] = gen_rtx_REG (DImode, regno + 2);
3584   ops[3] = gen_rtx_REG (DImode, regno + 4);
3585   ops[4] = operands[2];
3586   output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
3587                    ops);
3588   return "";
3589 })
3590
3591 (define_insn "neon_vst3_lane<mode>"
3592   [(set (mem:<V_three_elem> (match_operand:SI 0 "s_register_operand" "r"))
3593         (unspec:<V_three_elem>
3594            [(match_operand:CI 1 "s_register_operand" "w")
3595             (match_operand:SI 2 "immediate_operand" "i")
3596             (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3597            UNSPEC_VST3_LANE))]
3598   "TARGET_NEON"
3599 {
3600   HOST_WIDE_INT lane = INTVAL (operands[2]);
3601   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3602   int regno = REGNO (operands[1]);
3603   rtx ops[5];
3604   if (lane < 0 || lane >= max)
3605     error ("lane out of range");
3606   else if (lane >= max / 2)
3607     {
3608       lane -= max / 2;
3609       regno += 2;
3610     }
3611   ops[0] = operands[0];
3612   ops[1] = gen_rtx_REG (DImode, regno);
3613   ops[2] = gen_rtx_REG (DImode, regno + 4);
3614   ops[3] = gen_rtx_REG (DImode, regno + 8);
3615   ops[4] = GEN_INT (lane);
3616   output_asm_insn ("vst3.<V_sz_elem>\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
3617                    ops);
3618   return "";
3619 })
3620
3621 (define_insn "neon_vld4<mode>"
3622   [(set (match_operand:OI 0 "s_register_operand" "=w")
3623         (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
3624                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3625                    UNSPEC_VLD4))]
3626   "TARGET_NEON"
3627 {
3628   if (<V_sz_elem> == 64)
3629     return "vld1.64\t%h0, [%1]";
3630   else
3631     return "vld4.<V_sz_elem>\t%h0, [%1]";
3632 })
3633
3634 (define_expand "neon_vld4<mode>"
3635   [(match_operand:XI 0 "s_register_operand" "=w")
3636    (match_operand:SI 1 "s_register_operand" "+r")
3637    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3638   "TARGET_NEON"
3639 {
3640   emit_insn (gen_neon_vld4qa<mode> (operands[0], operands[0],
3641                                     operands[1], operands[1]));
3642   emit_insn (gen_neon_vld4qb<mode> (operands[0], operands[0],
3643                                     operands[1], operands[1]));
3644   DONE;
3645 })
3646
3647 (define_insn "neon_vld4qa<mode>"
3648   [(set (match_operand:XI 0 "s_register_operand" "=w")
3649         (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
3650                     (match_operand:XI 1 "s_register_operand" "0")
3651                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3652                    UNSPEC_VLD4A))
3653    (set (match_operand:SI 2 "s_register_operand" "=r")
3654         (plus:SI (match_dup 3)
3655                  (const_int 32)))]
3656   "TARGET_NEON"
3657 {
3658   int regno = REGNO (operands[0]);
3659   rtx ops[5];
3660   ops[0] = gen_rtx_REG (DImode, regno);
3661   ops[1] = gen_rtx_REG (DImode, regno + 4);
3662   ops[2] = gen_rtx_REG (DImode, regno + 8);
3663   ops[3] = gen_rtx_REG (DImode, regno + 12);
3664   ops[4] = operands[2];
3665   output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
3666   return "";
3667 })
3668
3669 (define_insn "neon_vld4qb<mode>"
3670   [(set (match_operand:XI 0 "s_register_operand" "=w")
3671         (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
3672                     (match_operand:XI 1 "s_register_operand" "0")
3673                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3674                    UNSPEC_VLD4B))
3675    (set (match_operand:SI 2 "s_register_operand" "=r")
3676         (plus:SI (match_dup 3)
3677                  (const_int 32)))]
3678   "TARGET_NEON"
3679 {
3680   int regno = REGNO (operands[0]);
3681   rtx ops[5];
3682   ops[0] = gen_rtx_REG (DImode, regno + 2);
3683   ops[1] = gen_rtx_REG (DImode, regno + 6);
3684   ops[2] = gen_rtx_REG (DImode, regno + 10);
3685   ops[3] = gen_rtx_REG (DImode, regno + 14);
3686   ops[4] = operands[2];
3687   output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
3688   return "";
3689 })
3690
3691 (define_insn "neon_vld4_lane<mode>"
3692   [(set (match_operand:OI 0 "s_register_operand" "=w")
3693         (unspec:OI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
3694                     (match_operand:OI 2 "s_register_operand" "0")
3695                     (match_operand:SI 3 "immediate_operand" "i")
3696                     (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3697                    UNSPEC_VLD4_LANE))]
3698   "TARGET_NEON"
3699 {
3700   HOST_WIDE_INT lane = INTVAL (operands[3]);
3701   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3702   int regno = REGNO (operands[0]);
3703   rtx ops[6];
3704   if (lane < 0 || lane >= max)
3705     error ("lane out of range");
3706   ops[0] = gen_rtx_REG (DImode, regno);
3707   ops[1] = gen_rtx_REG (DImode, regno + 2);
3708   ops[2] = gen_rtx_REG (DImode, regno + 4);
3709   ops[3] = gen_rtx_REG (DImode, regno + 6);
3710   ops[4] = operands[1];
3711   ops[5] = operands[3];
3712   output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
3713                    ops);
3714   return "";
3715 })
3716
3717 (define_insn "neon_vld4_lane<mode>"
3718   [(set (match_operand:XI 0 "s_register_operand" "=w")
3719         (unspec:XI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
3720                     (match_operand:XI 2 "s_register_operand" "0")
3721                     (match_operand:SI 3 "immediate_operand" "i")
3722                     (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3723                    UNSPEC_VLD4_LANE))]
3724   "TARGET_NEON"
3725 {
3726   HOST_WIDE_INT lane = INTVAL (operands[3]);
3727   HOST_WIDE_INT max = GET_MODE_NUNITS (<MODE>mode);
3728   int regno = REGNO (operands[0]);
3729   rtx ops[6];
3730   if (lane < 0 || lane >= max)
3731     error ("lane out of range");
3732   else if (lane >= max / 2)
3733     {
3734       lane -= max / 2;
3735       regno += 2;
3736     }
3737   ops[0] = gen_rtx_REG (DImode, regno);
3738   ops[1] = gen_rtx_REG (DImode, regno + 4);
3739   ops[2] = gen_rtx_REG (DImode, regno + 8);
3740   ops[3] = gen_rtx_REG (DImode, regno + 12);
3741   ops[4] = operands[1];
3742   ops[5] = GEN_INT (lane);
3743   output_asm_insn ("vld4.<V_sz_elem>\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
3744                    ops);
3745   return "";
3746 })
3747
3748 (define_insn "neon_vld4_dup<mode>"
3749   [(set (match_operand:OI 0 "s_register_operand" "=w")
3750         (unspec:OI [(mem:<V_four_elem> (match_operand:SI 1 "s_register_operand" "r"))
3751                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3752                    UNSPEC_VLD4_DUP))]
3753   "TARGET_NEON"
3754 {
3755   if (GET_MODE_NUNITS (<MODE>mode) > 1)
3756     {
3757       int regno = REGNO (operands[0]);
3758       rtx ops[5];
3759       ops[0] = gen_rtx_REG (DImode, regno);
3760       ops[1] = gen_rtx_REG (DImode, regno + 2);
3761       ops[2] = gen_rtx_REG (DImode, regno + 4);
3762       ops[3] = gen_rtx_REG (DImode, regno + 6);
3763       ops[4] = operands[1];
3764       output_asm_insn ("vld4.<V_sz_elem>\t{%P0[], %P1[], %P2[], %P3[]}, [%4]",
3765                        ops);
3766       return "";
3767     }
3768   else
3769     return "vld1.<V_sz_elem>\t%h0, [%1]";
3770 })
3771
3772 (define_insn "neon_vst4<mode>"
3773   [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
3774         (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
3775                     (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3776                    UNSPEC_VST4))]
3777   "TARGET_NEON"
3778 {
3779   if (<V_sz_elem> == 64)
3780     return "vst1.64\t%h1, [%0]";
3781   else
3782     return "vst4.<V_sz_elem>\t%h1, [%0]";
3783 })
3784
3785 (define_expand "neon_vst4<mode>"
3786   [(match_operand:SI 0 "s_register_operand" "+r")
3787    (match_operand:XI 1 "s_register_operand" "w")
3788    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3789   "TARGET_NEON"
3790 {
3791   emit_insn (gen_neon_vst4qa<mode> (operands[0], operands[0], operands[1]));
3792   emit_insn (gen_neon_vst4qb<mode> (operands[0], operands[0], operands[1]));
3793   DONE;
3794 })
3795
3796 (define_insn "neon_vst4qa<mode>"
3797   [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
3798         (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
3799                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3800                    UNSPEC_VST4A))
3801    (set (match_operand:SI 0 "s_register_operand" "=r")
3802         (plus:SI (match_dup 1)
3803                  (const_int 32)))]
3804   "TARGET_NEON"
3805 {
3806   int regno = REGNO (operands[2]);
3807   rtx ops[5];
3808   ops[0] = operands[0];
3809   ops[1] = gen_rtx_REG (DImode, regno);
3810   ops[2] = gen_rtx_REG (DImode, regno + 4);
3811   ops[3] = gen_rtx_REG (DImode, regno + 8);
3812   ops[4] = gen_rtx_REG (DImode, regno + 12);
3813   output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
3814   return "";
3815 })
3816
3817 (define_insn "neon_vst4qb<mode>"
3818   [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
3819         (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
3820                     (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3821                    UNSPEC_VST4B))
3822    (set (match_operand:SI 0 "s_register_operand" "=r")
3823         (plus:SI (match_dup 1)
3824                  (const_int 32)))]
3825   "TARGET_NEON"
3826 {
3827   int regno = REGNO (operands[2]);
3828   rtx ops[5];
3829   ops[0] = operands[0];
3830   ops[1] = gen_rtx_REG (DImode, regno + 2);
3831   ops[2] = gen_rtx_REG (DImode, regno + 6);
3832   ops[3] = gen_rtx_REG (DImode, regno + 10);
3833   ops[4] = gen_rtx_REG (DImode, regno + 14);
3834   output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
3835   return "";
3836 })
3837
3838 (define_insn "neon_vst4_lane<mode>"
3839   [(set (mem:<V_four_elem> (match_operand:SI 0 "s_register_operand" "r"))
3840         (unspec:<V_four_elem>
3841            [(match_operand:OI 1 "s_register_operand" "w")
3842             (match_operand:SI 2 "immediate_operand" "i")
3843             (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
3844            UNSPEC_VST4_LANE))]
3845   "TARGET_NEON"
3846 {