OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [config/] [arm/] [neon.md] - Blame information for rev 282

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 282 jeremybenn
;; ARM NEON coprocessor Machine Description
2
;; Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
3
;; Written by CodeSourcery.
4
;;
5
;; This file is part of GCC.
6
;;
7
;; GCC is free software; you can redistribute it and/or modify it
8
;; under the terms of the GNU General Public License as published by
9
;; the Free Software Foundation; either version 3, or (at your option)
10
;; any later version.
11
;;
12
;; GCC is distributed in the hope that it will be useful, but
13
;; WITHOUT ANY WARRANTY; without even the implied warranty of
14
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
;; General Public License for more details.
16
;;
17
;; You should have received a copy of the GNU General Public License
18
;; along with GCC; see the file COPYING3.  If not see
19
;; .
20
 
21
;; Constants for unspecs.
22
(define_constants
23
  [(UNSPEC_ASHIFT_SIGNED        65)
24
   (UNSPEC_ASHIFT_UNSIGNED      66)
25
   (UNSPEC_VABA                 67)
26
   (UNSPEC_VABAL                68)
27
   (UNSPEC_VABD                 69)
28
   (UNSPEC_VABDL                70)
29
   (UNSPEC_VABS                 71)
30
   (UNSPEC_VADD                 72)
31
   (UNSPEC_VADDHN               73)
32
   (UNSPEC_VADDL                74)
33
   (UNSPEC_VADDW                75)
34
   (UNSPEC_VAND                 76)
35
   (UNSPEC_VBIC                 77)
36
   (UNSPEC_VBSL                 78)
37
   (UNSPEC_VCAGE                79)
38
   (UNSPEC_VCAGT                80)
39
   (UNSPEC_VCEQ                 81)
40
   (UNSPEC_VCGE                 82)
41
   (UNSPEC_VCGT                 83)
42
   (UNSPEC_VCLS                 84)
43
   (UNSPEC_VCLZ                 85)
44
   (UNSPEC_VCNT                 86)
45
   (UNSPEC_VCOMBINE             87)
46
   (UNSPEC_VCVT                 88)
47
   (UNSPEC_VCVT_N               89)
48
   (UNSPEC_VDUP_LANE            90)
49
   (UNSPEC_VDUP_N               91)
50
   (UNSPEC_VEOR                 92)
51
   (UNSPEC_VEXT                 93)
52
   (UNSPEC_VGET_HIGH            94)
53
   (UNSPEC_VGET_LANE            95)
54
   (UNSPEC_VGET_LOW             96)
55
   (UNSPEC_VHADD                97)
56
   (UNSPEC_VHSUB                98)
57
   (UNSPEC_VLD1                 99)
58
   (UNSPEC_VLD1_DUP             100)
59
   (UNSPEC_VLD1_LANE            101)
60
   (UNSPEC_VLD2                 102)
61
   (UNSPEC_VLD2_DUP             103)
62
   (UNSPEC_VLD2_LANE            104)
63
   (UNSPEC_VLD3                 105)
64
   (UNSPEC_VLD3A                106)
65
   (UNSPEC_VLD3B                107)
66
   (UNSPEC_VLD3_DUP             108)
67
   (UNSPEC_VLD3_LANE            109)
68
   (UNSPEC_VLD4                 110)
69
   (UNSPEC_VLD4A                111)
70
   (UNSPEC_VLD4B                112)
71
   (UNSPEC_VLD4_DUP             113)
72
   (UNSPEC_VLD4_LANE            114)
73
   (UNSPEC_VMAX                 115)
74
   (UNSPEC_VMIN                 116)
75
   (UNSPEC_VMLA                 117)
76
   (UNSPEC_VMLAL                118)
77
   (UNSPEC_VMLA_LANE            119)
78
   (UNSPEC_VMLAL_LANE           120)
79
   (UNSPEC_VMLS                 121)
80
   (UNSPEC_VMLSL                122)
81
   (UNSPEC_VMLS_LANE            123)
82
   (UNSPEC_VMLSL_LANE           124)
83
   (UNSPEC_VMOVL                125)
84
   (UNSPEC_VMOVN                126)
85
   (UNSPEC_VMUL                 127)
86
   (UNSPEC_VMULL                128)
87
   (UNSPEC_VMUL_LANE            129)
88
   (UNSPEC_VMULL_LANE           130)
89
   (UNSPEC_VMUL_N               131)
90
   (UNSPEC_VMVN                 132)
91
   (UNSPEC_VORN                 133)
92
   (UNSPEC_VORR                 134)
93
   (UNSPEC_VPADAL               135)
94
   (UNSPEC_VPADD                136)
95
   (UNSPEC_VPADDL               137)
96
   (UNSPEC_VPMAX                138)
97
   (UNSPEC_VPMIN                139)
98
   (UNSPEC_VPSMAX               140)
99
   (UNSPEC_VPSMIN               141)
100
   (UNSPEC_VPUMAX               142)
101
   (UNSPEC_VPUMIN               143)
102
   (UNSPEC_VQABS                144)
103
   (UNSPEC_VQADD                145)
104
   (UNSPEC_VQDMLAL              146)
105
   (UNSPEC_VQDMLAL_LANE         147)
106
   (UNSPEC_VQDMLSL              148)
107
   (UNSPEC_VQDMLSL_LANE         149)
108
   (UNSPEC_VQDMULH              150)
109
   (UNSPEC_VQDMULH_LANE         151)
110
   (UNSPEC_VQDMULL              152)
111
   (UNSPEC_VQDMULL_LANE         153)
112
   (UNSPEC_VQMOVN               154)
113
   (UNSPEC_VQMOVUN              155)
114
   (UNSPEC_VQNEG                156)
115
   (UNSPEC_VQSHL                157)
116
   (UNSPEC_VQSHL_N              158)
117
   (UNSPEC_VQSHLU_N             159)
118
   (UNSPEC_VQSHRN_N             160)
119
   (UNSPEC_VQSHRUN_N            161)
120
   (UNSPEC_VQSUB                162)
121
   (UNSPEC_VRECPE               163)
122
   (UNSPEC_VRECPS               164)
123
   (UNSPEC_VREV16               165)
124
   (UNSPEC_VREV32               166)
125
   (UNSPEC_VREV64               167)
126
   (UNSPEC_VRSQRTE              168)
127
   (UNSPEC_VRSQRTS              169)
128
   (UNSPEC_VSET_LANE            170)
129
   (UNSPEC_VSHL                 171)
130
   (UNSPEC_VSHLL_N              172)
131
   (UNSPEC_VSHL_N               173)
132
   (UNSPEC_VSHR_N               174)
133
   (UNSPEC_VSHRN_N              175)
134
   (UNSPEC_VSLI                 176)
135
   (UNSPEC_VSRA_N               177)
136
   (UNSPEC_VSRI                 178)
137
   (UNSPEC_VST1                 179)
138
   (UNSPEC_VST1_LANE            180)
139
   (UNSPEC_VST2                 181)
140
   (UNSPEC_VST2_LANE            182)
141
   (UNSPEC_VST3                 183)
142
   (UNSPEC_VST3A                184)
143
   (UNSPEC_VST3B                185)
144
   (UNSPEC_VST3_LANE            186)
145
   (UNSPEC_VST4                 187)
146
   (UNSPEC_VST4A                188)
147
   (UNSPEC_VST4B                189)
148
   (UNSPEC_VST4_LANE            190)
149
   (UNSPEC_VSTRUCTDUMMY         191)
150
   (UNSPEC_VSUB                 192)
151
   (UNSPEC_VSUBHN               193)
152
   (UNSPEC_VSUBL                194)
153
   (UNSPEC_VSUBW                195)
154
   (UNSPEC_VTBL                 196)
155
   (UNSPEC_VTBX                 197)
156
   (UNSPEC_VTRN1                198)
157
   (UNSPEC_VTRN2                199)
158
   (UNSPEC_VTST                 200)
159
   (UNSPEC_VUZP1                201)
160
   (UNSPEC_VUZP2                202)
161
   (UNSPEC_VZIP1                203)
162
   (UNSPEC_VZIP2                204)])
163
 
164
;; Double-width vector modes.
165
(define_mode_iterator VD [V8QI V4HI V2SI V2SF])
166
 
167
;; Double-width vector modes plus 64-bit elements.
168
(define_mode_iterator VDX [V8QI V4HI V2SI V2SF DI])
169
 
170
;; Same, without floating-point elements.
171
(define_mode_iterator VDI [V8QI V4HI V2SI])
172
 
173
;; Quad-width vector modes.
174
(define_mode_iterator VQ [V16QI V8HI V4SI V4SF])
175
 
176
;; Quad-width vector modes plus 64-bit elements.
177
(define_mode_iterator VQX [V16QI V8HI V4SI V4SF V2DI])
178
 
179
;; Same, without floating-point elements.
180
(define_mode_iterator VQI [V16QI V8HI V4SI])
181
 
182
;; Same, with TImode added, for moves.
183
(define_mode_iterator VQXMOV [V16QI V8HI V4SI V4SF V2DI TI])
184
 
185
;; Opaque structure types wider than TImode.
186
(define_mode_iterator VSTRUCT [EI OI CI XI])
187
 
188
;; Opaque structure types used in table lookups (except vtbl1/vtbx1).
189
(define_mode_iterator VTAB [TI EI OI])
190
 
191
;; vtbl suffix for above modes.
192
(define_mode_attr VTAB_n [(TI "2") (EI "3") (OI "4")])
193
 
194
;; Widenable modes.
195
(define_mode_iterator VW [V8QI V4HI V2SI])
196
 
197
;; Narrowable modes.
198
(define_mode_iterator VN [V8HI V4SI V2DI])
199
 
200
;; All supported vector modes (except singleton DImode).
201
(define_mode_iterator VDQ [V8QI V16QI V4HI V8HI V2SI V4SI V2SF V4SF V2DI])
202
 
203
;; All supported vector modes (except those with 64-bit integer elements).
204
(define_mode_iterator VDQW [V8QI V16QI V4HI V8HI V2SI V4SI V2SF V4SF])
205
 
206
;; Supported integer vector modes (not 64 bit elements).
207
(define_mode_iterator VDQIW [V8QI V16QI V4HI V8HI V2SI V4SI])
208
 
209
;; Supported integer vector modes (not singleton DI)
210
(define_mode_iterator VDQI [V8QI V16QI V4HI V8HI V2SI V4SI V2DI])
211
 
212
;; Vector modes, including 64-bit integer elements.
213
(define_mode_iterator VDQX [V8QI V16QI V4HI V8HI V2SI V4SI V2SF V4SF DI V2DI])
214
 
215
;; Vector modes including 64-bit integer elements, but no floats.
216
(define_mode_iterator VDQIX [V8QI V16QI V4HI V8HI V2SI V4SI DI V2DI])
217
 
218
;; Vector modes for float->int conversions.
219
(define_mode_iterator VCVTF [V2SF V4SF])
220
 
221
;; Vector modes form int->float conversions.
222
(define_mode_iterator VCVTI [V2SI V4SI])
223
 
224
;; Vector modes for doubleword multiply-accumulate, etc. insns.
225
(define_mode_iterator VMD [V4HI V2SI V2SF])
226
 
227
;; Vector modes for quadword multiply-accumulate, etc. insns.
228
(define_mode_iterator VMQ [V8HI V4SI V4SF])
229
 
230
;; Above modes combined.
231
(define_mode_iterator VMDQ [V4HI V2SI V2SF V8HI V4SI V4SF])
232
 
233
;; As VMD, but integer modes only.
234
(define_mode_iterator VMDI [V4HI V2SI])
235
 
236
;; As VMQ, but integer modes only.
237
(define_mode_iterator VMQI [V8HI V4SI])
238
 
239
;; Above modes combined.
240
(define_mode_iterator VMDQI [V4HI V2SI V8HI V4SI])
241
 
242
;; Modes with 8-bit and 16-bit elements.
243
(define_mode_iterator VX [V8QI V4HI V16QI V8HI])
244
 
245
;; Modes with 8-bit elements.
246
(define_mode_iterator VE [V8QI V16QI])
247
 
248
;; Modes with 64-bit elements only.
249
(define_mode_iterator V64 [DI V2DI])
250
 
251
;; Modes with 32-bit elements only.
252
(define_mode_iterator V32 [V2SI V2SF V4SI V4SF])
253
 
254
;; (Opposite) mode to convert to/from for above conversions.
255
(define_mode_attr V_CVTTO [(V2SI "V2SF") (V2SF "V2SI")
256
                           (V4SI "V4SF") (V4SF "V4SI")])
257
 
258
;; Define element mode for each vector mode.
259
(define_mode_attr V_elem [(V8QI "QI") (V16QI "QI")
260
                          (V4HI "HI") (V8HI "HI")
261
                          (V2SI "SI") (V4SI "SI")
262
                          (V2SF "SF") (V4SF "SF")
263
                          (DI "DI")   (V2DI "DI")])
264
 
265
;; Element modes for vector extraction, padded up to register size.
266
 
267
(define_mode_attr V_ext [(V8QI "SI") (V16QI "SI")
268
                         (V4HI "SI") (V8HI "SI")
269
                         (V2SI "SI") (V4SI "SI")
270
                         (V2SF "SF") (V4SF "SF")
271
                         (DI "DI") (V2DI "DI")])
272
 
273
;; Mode of pair of elements for each vector mode, to define transfer
274
;; size for structure lane/dup loads and stores.
275
(define_mode_attr V_two_elem [(V8QI "HI") (V16QI "HI")
276
                              (V4HI "SI") (V8HI "SI")
277
                              (V2SI "V2SI") (V4SI "V2SI")
278
                              (V2SF "V2SF") (V4SF "V2SF")
279
                              (DI "V2DI")   (V2DI "V2DI")])
280
 
281
;; Similar, for three elements.
282
;; ??? Should we define extra modes so that sizes of all three-element
283
;; accesses can be accurately represented?
284
(define_mode_attr V_three_elem [(V8QI "SI")   (V16QI "SI")
285
                                (V4HI "V4HI") (V8HI "V4HI")
286
                                (V2SI "V4SI") (V4SI "V4SI")
287
                                (V2SF "V4SF") (V4SF "V4SF")
288
                                (DI "EI")     (V2DI "EI")])
289
 
290
;; Similar, for four elements.
291
(define_mode_attr V_four_elem [(V8QI "SI")   (V16QI "SI")
292
                               (V4HI "V4HI") (V8HI "V4HI")
293
                               (V2SI "V4SI") (V4SI "V4SI")
294
                               (V2SF "V4SF") (V4SF "V4SF")
295
                               (DI "OI")     (V2DI "OI")])
296
 
297
;; Register width from element mode
298
(define_mode_attr V_reg [(V8QI "P") (V16QI "q")
299
                         (V4HI "P") (V8HI  "q")
300
                         (V2SI "P") (V4SI  "q")
301
                         (V2SF "P") (V4SF  "q")
302
                         (DI   "P") (V2DI  "q")])
303
 
304
;; Wider modes with the same number of elements.
305
(define_mode_attr V_widen [(V8QI "V8HI") (V4HI "V4SI") (V2SI "V2DI")])
306
 
307
;; Narrower modes with the same number of elements.
308
(define_mode_attr V_narrow [(V8HI "V8QI") (V4SI "V4HI") (V2DI "V2SI")])
309
 
310
;; Modes with half the number of equal-sized elements.
311
(define_mode_attr V_HALF [(V16QI "V8QI") (V8HI "V4HI")
312
                          (V4SI  "V2SI") (V4SF "V2SF")
313
                          (V2DI "DI")])
314
 
315
;; Same, but lower-case.
316
(define_mode_attr V_half [(V16QI "v8qi") (V8HI "v4hi")
317
                          (V4SI  "v2si") (V4SF "v2sf")
318
                          (V2DI "di")])
319
 
320
;; Modes with twice the number of equal-sized elements.
321
(define_mode_attr V_DOUBLE [(V8QI "V16QI") (V4HI "V8HI")
322
                            (V2SI "V4SI") (V2SF "V4SF")
323
                            (DI "V2DI")])
324
 
325
;; Same, but lower-case.
326
(define_mode_attr V_double [(V8QI "v16qi") (V4HI "v8hi")
327
                            (V2SI "v4si") (V2SF "v4sf")
328
                            (DI "v2di")])
329
 
330
;; Modes with double-width elements.
331
(define_mode_attr V_double_width [(V8QI "V4HI") (V16QI "V8HI")
332
                                  (V4HI "V2SI") (V8HI "V4SI")
333
                                  (V2SI "DI")   (V4SI "V2DI")])
334
 
335
;; Mode of result of comparison operations (and bit-select operand 1).
336
(define_mode_attr V_cmp_result [(V8QI "V8QI") (V16QI "V16QI")
337
                                (V4HI "V4HI") (V8HI  "V8HI")
338
                                (V2SI "V2SI") (V4SI  "V4SI")
339
                                (V2SF "V2SI") (V4SF  "V4SI")
340
                                (DI   "DI")   (V2DI  "V2DI")])
341
 
342
;; Get element type from double-width mode, for operations where we don't care
343
;; about signedness.
344
(define_mode_attr V_if_elem [(V8QI "i8")  (V16QI "i8")
345
                             (V4HI "i16") (V8HI  "i16")
346
                             (V2SI "i32") (V4SI  "i32")
347
                             (DI   "i64") (V2DI  "i64")
348
                             (V2SF "f32") (V4SF  "f32")])
349
 
350
;; Same, but for operations which work on signed values.
351
(define_mode_attr V_s_elem [(V8QI "s8")  (V16QI "s8")
352
                            (V4HI "s16") (V8HI  "s16")
353
                            (V2SI "s32") (V4SI  "s32")
354
                            (DI   "s64") (V2DI  "s64")
355
                            (V2SF "f32") (V4SF  "f32")])
356
 
357
;; Same, but for operations which work on unsigned values.
358
(define_mode_attr V_u_elem [(V8QI "u8")  (V16QI "u8")
359
                            (V4HI "u16") (V8HI  "u16")
360
                            (V2SI "u32") (V4SI  "u32")
361
                            (DI   "u64") (V2DI  "u64")
362
                            (V2SF "f32") (V4SF  "f32")])
363
 
364
;; Element types for extraction of unsigned scalars.
365
(define_mode_attr V_uf_sclr [(V8QI "u8")  (V16QI "u8")
366
                             (V4HI "u16") (V8HI "u16")
367
                             (V2SI "32") (V4SI "32")
368
                             (V2SF "32") (V4SF "32")])
369
 
370
(define_mode_attr V_sz_elem [(V8QI "8")  (V16QI "8")
371
                             (V4HI "16") (V8HI  "16")
372
                             (V2SI "32") (V4SI  "32")
373
                             (DI   "64") (V2DI  "64")
374
                             (V2SF "32") (V4SF  "32")])
375
 
376
;; Element sizes for duplicating ARM registers to all elements of a vector.
377
(define_mode_attr VD_dup [(V8QI "8") (V4HI "16") (V2SI "32") (V2SF "32")])
378
 
379
;; Opaque integer types for results of pair-forming intrinsics (vtrn, etc.)
380
(define_mode_attr V_PAIR [(V8QI "TI") (V16QI "OI")
381
                          (V4HI "TI") (V8HI  "OI")
382
                          (V2SI "TI") (V4SI  "OI")
383
                          (V2SF "TI") (V4SF  "OI")
384
                          (DI   "TI") (V2DI  "OI")])
385
 
386
;; Same, but lower-case.
387
(define_mode_attr V_pair [(V8QI "ti") (V16QI "oi")
388
                          (V4HI "ti") (V8HI  "oi")
389
                          (V2SI "ti") (V4SI  "oi")
390
                          (V2SF "ti") (V4SF  "oi")
391
                          (DI   "ti") (V2DI  "oi")])
392
 
393
;; Operations on two halves of a quadword vector.
394
(define_code_iterator vqh_ops [plus smin smax umin umax])
395
 
396
;; Same, without unsigned variants (for use with *SFmode pattern).
397
(define_code_iterator vqhs_ops [plus smin smax])
398
 
399
;; Assembler mnemonics for above codes.
400
(define_code_attr VQH_mnem [(plus "vadd") (smin "vmin") (smax "vmax")
401
                            (umin "vmin") (umax "vmax")])
402
 
403
;; Signs of above, where relevant.
404
(define_code_attr VQH_sign [(plus "i") (smin "s") (smax "s") (umin "u")
405
                            (umax "u")])
406
 
407
;; Extra suffix on some 64-bit insn names (to avoid collision with standard
408
;; names which we don't want to define).
409
(define_mode_attr V_suf64 [(V8QI "") (V16QI "")
410
                           (V4HI "") (V8HI "")
411
                           (V2SI "") (V4SI "")
412
                           (V2SF "") (V4SF "")
413
                           (DI "_neon") (V2DI "")])
414
 
415
;; Scalars to be presented to scalar multiplication instructions
416
;; must satisfy the following constraints.
417
;; 1. If the mode specifies 16-bit elements, the scalar must be in D0-D7.
418
;; 2. If the mode specifies 32-bit elements, the scalar must be in D0-D15.
419
;; This mode attribute is used to obtain the correct register constraints.
420
(define_mode_attr scalar_mul_constraint [(V4HI "x") (V2SI "t") (V2SF "t")
421
                                         (V8HI "x") (V4SI "t") (V4SF "t")])
422
 
423
;; Attribute used to permit string comparisons against  in
424
;; neon_type attribute definitions.
425
(define_attr "vqh_mnem" "vadd,vmin,vmax" (const_string "vadd"))
426
 
427
;; Predicates used for setting neon_type
428
 
429
(define_mode_attr Is_float_mode [(V8QI "false") (V16QI "false")
430
                                 (V4HI "false") (V8HI "false")
431
                                 (V2SI "false") (V4SI "false")
432
                                 (V2SF "true") (V4SF "true")
433
                                 (DI "false") (V2DI "false")])
434
 
435
(define_mode_attr Scalar_mul_8_16 [(V8QI "true") (V16QI "true")
436
                                   (V4HI "true") (V8HI "true")
437
                                   (V2SI "false") (V4SI "false")
438
                                   (V2SF "false") (V4SF "false")
439
                                   (DI "false") (V2DI "false")])
440
 
441
 
442
(define_mode_attr Is_d_reg [(V8QI "true") (V16QI "false")
443
                            (V4HI "true") (V8HI  "false")
444
                            (V2SI "true") (V4SI  "false")
445
                            (V2SF "true") (V4SF  "false")
446
                            (DI   "true") (V2DI  "false")])
447
 
448
(define_mode_attr V_mode_nunits [(V8QI "8") (V16QI "16")
449
                                 (V4HI "4") (V8HI "8")
450
                                 (V2SI "2") (V4SI "4")
451
                                 (V2SF "2") (V4SF "4")
452
                                 (DI "1")   (V2DI "2")])
453
 
454
(define_insn "*neon_mov"
455
  [(set (match_operand:VD 0 "nonimmediate_operand"
456
          "=w,Uv,w, w,  ?r,?w,?r,?r, ?Us")
457
        (match_operand:VD 1 "general_operand"
458
          " w,w, Dn,Uvi, w, r, r, Usi,r"))]
459
  "TARGET_NEON
460
   && (register_operand (operands[0], mode)
461
       || register_operand (operands[1], mode))"
462
{
463
  if (which_alternative == 2)
464
    {
465
      int width, is_valid;
466
      static char templ[40];
467
 
468
      is_valid = neon_immediate_valid_for_move (operands[1], mode,
469
        &operands[1], &width);
470
 
471
      gcc_assert (is_valid != 0);
472
 
473
      if (width == 0)
474
        return "vmov.f32\t%P0, %1  @ ";
475
      else
476
        sprintf (templ, "vmov.i%d\t%%P0, %%1  @ ", width);
477
 
478
      return templ;
479
    }
480
 
481
  /* FIXME: If the memory layout is changed in big-endian mode, output_move_vfp
482
     below must be changed to output_move_neon (which will use the
483
     element/structure loads/stores), and the constraint changed to 'Um' instead
484
     of 'Uv'.  */
485
 
486
  switch (which_alternative)
487
    {
488
    case 0: return "vmov\t%P0, %P1  @ ";
489
    case 1: case 3: return output_move_vfp (operands);
490
    case 2: gcc_unreachable ();
491
    case 4: return "vmov\t%Q0, %R0, %P1  @ ";
492
    case 5: return "vmov\t%P0, %Q1, %R1  @ ";
493
    default: return output_move_double (operands);
494
    }
495
}
496
 [(set_attr "neon_type" "neon_int_1,*,neon_vmov,*,neon_mrrc,neon_mcr_2_mcrr,*,*,*")
497
  (set_attr "type" "*,f_stored,*,f_loadd,*,*,alu,load2,store2")
498
  (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
499
  (set_attr "length" "4,4,4,4,4,4,8,8,8")
500
  (set_attr "pool_range"     "*,*,*,1020,*,*,*,1020,*")
501
  (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
502
 
503
(define_insn "*neon_mov"
504
  [(set (match_operand:VQXMOV 0 "nonimmediate_operand"
505
          "=w,Un,w, w,  ?r,?w,?r,?r,  ?Us")
506
        (match_operand:VQXMOV 1 "general_operand"
507
          " w,w, Dn,Uni, w, r, r, Usi, r"))]
508
  "TARGET_NEON
509
   && (register_operand (operands[0], mode)
510
       || register_operand (operands[1], mode))"
511
{
512
  if (which_alternative == 2)
513
    {
514
      int width, is_valid;
515
      static char templ[40];
516
 
517
      is_valid = neon_immediate_valid_for_move (operands[1], mode,
518
        &operands[1], &width);
519
 
520
      gcc_assert (is_valid != 0);
521
 
522
      if (width == 0)
523
        return "vmov.f32\t%q0, %1  @ ";
524
      else
525
        sprintf (templ, "vmov.i%d\t%%q0, %%1  @ ", width);
526
 
527
      return templ;
528
    }
529
 
530
  switch (which_alternative)
531
    {
532
    case 0: return "vmov\t%q0, %q1  @ ";
533
    case 1: case 3: return output_move_neon (operands);
534
    case 2: gcc_unreachable ();
535
    case 4: return "vmov\t%Q0, %R0, %e1  @ \;vmov\t%J0, %K0, %f1";
536
    case 5: return "vmov\t%e0, %Q1, %R1  @ \;vmov\t%f0, %J1, %K1";
537
    default: return output_move_quad (operands);
538
    }
539
}
540
  [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_vmov,neon_ldm_2,\
541
                          neon_mrrc,neon_mcr_2_mcrr,*,*,*")
542
   (set_attr "type" "*,*,*,*,*,*,alu,load4,store4")
543
   (set_attr "insn" "*,*,*,*,*,*,mov,*,*")
544
   (set_attr "length" "4,8,4,8,8,8,16,8,16")
545
   (set_attr "pool_range" "*,*,*,1020,*,*,*,1020,*")
546
   (set_attr "neg_pool_range" "*,*,*,1008,*,*,*,1008,*")])
547
 
548
(define_expand "movti"
549
  [(set (match_operand:TI 0 "nonimmediate_operand" "")
550
        (match_operand:TI 1 "general_operand" ""))]
551
  "TARGET_NEON"
552
{
553
  if (can_create_pseudo_p ())
554
    {
555
      if (GET_CODE (operands[0]) != REG)
556
        operands[1] = force_reg (TImode, operands[1]);
557
    }
558
})
559
 
560
(define_expand "mov"
561
  [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "")
562
        (match_operand:VSTRUCT 1 "general_operand" ""))]
563
  "TARGET_NEON"
564
{
565
  if (can_create_pseudo_p ())
566
    {
567
      if (GET_CODE (operands[0]) != REG)
568
        operands[1] = force_reg (mode, operands[1]);
569
    }
570
})
571
 
572
(define_insn "*neon_mov"
573
  [(set (match_operand:VSTRUCT 0 "nonimmediate_operand" "=w,Ut,w")
574
        (match_operand:VSTRUCT 1 "general_operand"      " w,w, Ut"))]
575
  "TARGET_NEON
576
   && (register_operand (operands[0], mode)
577
       || register_operand (operands[1], mode))"
578
{
579
  switch (which_alternative)
580
    {
581
    case 0: return "#";
582
    case 1: case 2: return output_move_neon (operands);
583
    default: gcc_unreachable ();
584
    }
585
}
586
  [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_ldm_2")
587
   (set (attr "length") (symbol_ref "arm_attr_length_move_neon (insn)"))])
588
 
589
(define_split
590
  [(set (match_operand:EI 0 "s_register_operand" "")
591
        (match_operand:EI 1 "s_register_operand" ""))]
592
  "TARGET_NEON && reload_completed"
593
  [(set (match_dup 0) (match_dup 1))
594
   (set (match_dup 2) (match_dup 3))]
595
{
596
  int rdest = REGNO (operands[0]);
597
  int rsrc = REGNO (operands[1]);
598
  rtx dest[2], src[2];
599
 
600
  dest[0] = gen_rtx_REG (TImode, rdest);
601
  src[0] = gen_rtx_REG (TImode, rsrc);
602
  dest[1] = gen_rtx_REG (DImode, rdest + 4);
603
  src[1] = gen_rtx_REG (DImode, rsrc + 4);
604
 
605
  neon_disambiguate_copy (operands, dest, src, 2);
606
})
607
 
608
(define_split
609
  [(set (match_operand:OI 0 "s_register_operand" "")
610
        (match_operand:OI 1 "s_register_operand" ""))]
611
  "TARGET_NEON && reload_completed"
612
  [(set (match_dup 0) (match_dup 1))
613
   (set (match_dup 2) (match_dup 3))]
614
{
615
  int rdest = REGNO (operands[0]);
616
  int rsrc = REGNO (operands[1]);
617
  rtx dest[2], src[2];
618
 
619
  dest[0] = gen_rtx_REG (TImode, rdest);
620
  src[0] = gen_rtx_REG (TImode, rsrc);
621
  dest[1] = gen_rtx_REG (TImode, rdest + 4);
622
  src[1] = gen_rtx_REG (TImode, rsrc + 4);
623
 
624
  neon_disambiguate_copy (operands, dest, src, 2);
625
})
626
 
627
(define_split
628
  [(set (match_operand:CI 0 "s_register_operand" "")
629
        (match_operand:CI 1 "s_register_operand" ""))]
630
  "TARGET_NEON && reload_completed"
631
  [(set (match_dup 0) (match_dup 1))
632
   (set (match_dup 2) (match_dup 3))
633
   (set (match_dup 4) (match_dup 5))]
634
{
635
  int rdest = REGNO (operands[0]);
636
  int rsrc = REGNO (operands[1]);
637
  rtx dest[3], src[3];
638
 
639
  dest[0] = gen_rtx_REG (TImode, rdest);
640
  src[0] = gen_rtx_REG (TImode, rsrc);
641
  dest[1] = gen_rtx_REG (TImode, rdest + 4);
642
  src[1] = gen_rtx_REG (TImode, rsrc + 4);
643
  dest[2] = gen_rtx_REG (TImode, rdest + 8);
644
  src[2] = gen_rtx_REG (TImode, rsrc + 8);
645
 
646
  neon_disambiguate_copy (operands, dest, src, 3);
647
})
648
 
649
(define_split
650
  [(set (match_operand:XI 0 "s_register_operand" "")
651
        (match_operand:XI 1 "s_register_operand" ""))]
652
  "TARGET_NEON && reload_completed"
653
  [(set (match_dup 0) (match_dup 1))
654
   (set (match_dup 2) (match_dup 3))
655
   (set (match_dup 4) (match_dup 5))
656
   (set (match_dup 6) (match_dup 7))]
657
{
658
  int rdest = REGNO (operands[0]);
659
  int rsrc = REGNO (operands[1]);
660
  rtx dest[4], src[4];
661
 
662
  dest[0] = gen_rtx_REG (TImode, rdest);
663
  src[0] = gen_rtx_REG (TImode, rsrc);
664
  dest[1] = gen_rtx_REG (TImode, rdest + 4);
665
  src[1] = gen_rtx_REG (TImode, rsrc + 4);
666
  dest[2] = gen_rtx_REG (TImode, rdest + 8);
667
  src[2] = gen_rtx_REG (TImode, rsrc + 8);
668
  dest[3] = gen_rtx_REG (TImode, rdest + 12);
669
  src[3] = gen_rtx_REG (TImode, rsrc + 12);
670
 
671
  neon_disambiguate_copy (operands, dest, src, 4);
672
})
673
 
674
(define_insn "vec_set_internal"
675
  [(set (match_operand:VD 0 "s_register_operand" "=w")
676
        (vec_merge:VD
677
          (vec_duplicate:VD
678
            (match_operand: 1 "s_register_operand" "r"))
679
          (match_operand:VD 3 "s_register_operand" "0")
680
          (match_operand:SI 2 "immediate_operand" "i")))]
681
  "TARGET_NEON"
682
{
683
  int elt = ffs ((int) INTVAL (operands[2]) - 1);
684
  if (BYTES_BIG_ENDIAN)
685
    elt = GET_MODE_NUNITS (mode) - 1 - elt;
686
  operands[2] = GEN_INT (elt);
687
 
688
  return "vmov%?.\t%P0[%c2], %1";
689
}
690
  [(set_attr "predicable" "yes")
691
   (set_attr "neon_type" "neon_mcr")])
692
 
693
(define_insn "vec_set_internal"
694
  [(set (match_operand:VQ 0 "s_register_operand" "=w")
695
        (vec_merge:VQ
696
          (vec_duplicate:VQ
697
            (match_operand: 1 "s_register_operand" "r"))
698
          (match_operand:VQ 3 "s_register_operand" "0")
699
          (match_operand:SI 2 "immediate_operand" "i")))]
700
  "TARGET_NEON"
701
{
702
  HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
703
  int half_elts = GET_MODE_NUNITS (mode) / 2;
704
  int elt = elem % half_elts;
705
  int hi = (elem / half_elts) * 2;
706
  int regno = REGNO (operands[0]);
707
 
708
  if (BYTES_BIG_ENDIAN)
709
    elt = half_elts - 1 - elt;
710
 
711
  operands[0] = gen_rtx_REG (mode, regno + hi);
712
  operands[2] = GEN_INT (elt);
713
 
714
  return "vmov%?.\t%P0[%c2], %1";
715
}
716
  [(set_attr "predicable" "yes")
717
   (set_attr "neon_type" "neon_mcr")]
718
)
719
 
720
(define_insn "vec_setv2di_internal"
721
  [(set (match_operand:V2DI 0 "s_register_operand" "=w")
722
        (vec_merge:V2DI
723
          (vec_duplicate:V2DI
724
            (match_operand:DI 1 "s_register_operand" "r"))
725
          (match_operand:V2DI 3 "s_register_operand" "0")
726
          (match_operand:SI 2 "immediate_operand" "i")))]
727
  "TARGET_NEON"
728
{
729
  HOST_WIDE_INT elem = ffs ((int) INTVAL (operands[2])) - 1;
730
  int regno = REGNO (operands[0]) + 2 * elem;
731
 
732
  operands[0] = gen_rtx_REG (DImode, regno);
733
 
734
  return "vmov%?.64\t%P0, %Q1, %R1";
735
}
736
  [(set_attr "predicable" "yes")
737
   (set_attr "neon_type" "neon_mcr_2_mcrr")]
738
)
739
 
740
(define_expand "vec_set"
741
  [(match_operand:VDQ 0 "s_register_operand" "")
742
   (match_operand: 1 "s_register_operand" "")
743
   (match_operand:SI 2 "immediate_operand" "")]
744
  "TARGET_NEON"
745
{
746
  HOST_WIDE_INT elem = (HOST_WIDE_INT) 1 << INTVAL (operands[2]);
747
  emit_insn (gen_vec_set_internal (operands[0], operands[1],
748
                                         GEN_INT (elem), operands[0]));
749
  DONE;
750
})
751
 
752
(define_insn "vec_extract"
753
  [(set (match_operand: 0 "s_register_operand" "=r")
754
        (vec_select:
755
          (match_operand:VD 1 "s_register_operand" "w")
756
          (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
757
  "TARGET_NEON"
758
{
759
  if (BYTES_BIG_ENDIAN)
760
    {
761
      int elt = INTVAL (operands[2]);
762
      elt = GET_MODE_NUNITS (mode) - 1 - elt;
763
      operands[2] = GEN_INT (elt);
764
    }
765
  return "vmov%?.\t%0, %P1[%c2]";
766
}
767
  [(set_attr "predicable" "yes")
768
   (set_attr "neon_type" "neon_bp_simple")]
769
)
770
 
771
(define_insn "vec_extract"
772
  [(set (match_operand: 0 "s_register_operand" "=r")
773
        (vec_select:
774
          (match_operand:VQ 1 "s_register_operand" "w")
775
          (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
776
  "TARGET_NEON"
777
{
778
  int half_elts = GET_MODE_NUNITS (mode) / 2;
779
  int elt = INTVAL (operands[2]) % half_elts;
780
  int hi = (INTVAL (operands[2]) / half_elts) * 2;
781
  int regno = REGNO (operands[1]);
782
 
783
  if (BYTES_BIG_ENDIAN)
784
    elt = half_elts - 1 - elt;
785
 
786
  operands[1] = gen_rtx_REG (mode, regno + hi);
787
  operands[2] = GEN_INT (elt);
788
 
789
  return "vmov%?.\t%0, %P1[%c2]";
790
}
791
  [(set_attr "predicable" "yes")
792
   (set_attr "neon_type" "neon_bp_simple")]
793
)
794
 
795
(define_insn "vec_extractv2di"
796
  [(set (match_operand:DI 0 "s_register_operand" "=r")
797
        (vec_select:DI
798
          (match_operand:V2DI 1 "s_register_operand" "w")
799
          (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
800
  "TARGET_NEON"
801
{
802
  int regno = REGNO (operands[1]) + INTVAL (operands[2]);
803
 
804
  operands[1] = gen_rtx_REG (DImode, regno);
805
 
806
  return "vmov%?.64\t%Q0, %R0, %P1";
807
}
808
  [(set_attr "predicable" "yes")
809
   (set_attr "neon_type" "neon_int_1")]
810
)
811
 
812
(define_expand "vec_init"
813
  [(match_operand:VDQ 0 "s_register_operand" "")
814
   (match_operand 1 "" "")]
815
  "TARGET_NEON"
816
{
817
  neon_expand_vector_init (operands[0], operands[1]);
818
  DONE;
819
})
820
 
821
;; Doubleword and quadword arithmetic.
822
 
823
;; NOTE: vadd/vsub and some other instructions also support 64-bit integer
824
;; element size, which we could potentially use for "long long" operations. We
825
;; don't want to do this at present though, because moving values from the
826
;; vector unit to the ARM core is currently slow and 64-bit addition (etc.) is
827
;; easy to do with ARM instructions anyway.
828
 
829
(define_insn "*add3_neon"
830
  [(set (match_operand:VDQ 0 "s_register_operand" "=w")
831
        (plus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
832
                  (match_operand:VDQ 2 "s_register_operand" "w")))]
833
  "TARGET_NEON"
834
  "vadd.\t%0, %1, %2"
835
  [(set (attr "neon_type")
836
      (if_then_else (ne (symbol_ref "") (const_int 0))
837
                    (if_then_else (ne (symbol_ref "") (const_int 0))
838
                                  (const_string "neon_fp_vadd_ddd_vabs_dd")
839
                                  (const_string "neon_fp_vadd_qqq_vabs_qq"))
840
                    (const_string "neon_int_1")))]
841
)
842
 
843
(define_insn "*sub3_neon"
844
  [(set (match_operand:VDQ 0 "s_register_operand" "=w")
845
        (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
846
                   (match_operand:VDQ 2 "s_register_operand" "w")))]
847
  "TARGET_NEON"
848
  "vsub.\t%0, %1, %2"
849
  [(set (attr "neon_type")
850
      (if_then_else (ne (symbol_ref "") (const_int 0))
851
                    (if_then_else (ne (symbol_ref "") (const_int 0))
852
                                  (const_string "neon_fp_vadd_ddd_vabs_dd")
853
                                  (const_string "neon_fp_vadd_qqq_vabs_qq"))
854
                    (const_string "neon_int_2")))]
855
)
856
 
857
(define_insn "*mul3_neon"
858
  [(set (match_operand:VDQ 0 "s_register_operand" "=w")
859
        (mult:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
860
                  (match_operand:VDQ 2 "s_register_operand" "w")))]
861
  "TARGET_NEON"
862
  "vmul.\t%0, %1, %2"
863
  [(set (attr "neon_type")
864
      (if_then_else (ne (symbol_ref "") (const_int 0))
865
                    (if_then_else (ne (symbol_ref "") (const_int 0))
866
                                  (const_string "neon_fp_vadd_ddd_vabs_dd")
867
                                  (const_string "neon_fp_vadd_qqq_vabs_qq"))
868
                    (if_then_else (ne (symbol_ref "") (const_int 0))
869
                                  (if_then_else
870
                                    (ne (symbol_ref "") (const_int 0))
871
                                    (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
872
                                    (const_string "neon_mul_qqq_8_16_32_ddd_32"))
873
                                  (if_then_else (ne (symbol_ref "") (const_int 0))
874
                                    (const_string "neon_mul_qqq_8_16_32_ddd_32")
875
                                    (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
876
)
877
 
878
(define_insn "*mul3add_neon"
879
  [(set (match_operand:VDQ 0 "s_register_operand" "=w")
880
        (plus:VDQ (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
881
                            (match_operand:VDQ 3 "s_register_operand" "w"))
882
                  (match_operand:VDQ 1 "s_register_operand" "0")))]
883
  "TARGET_NEON"
884
  "vmla.\t%0, %2, %3"
885
  [(set (attr "neon_type")
886
      (if_then_else (ne (symbol_ref "") (const_int 0))
887
                    (if_then_else (ne (symbol_ref "") (const_int 0))
888
                                  (const_string "neon_fp_vmla_ddd")
889
                                  (const_string "neon_fp_vmla_qqq"))
890
                    (if_then_else (ne (symbol_ref "") (const_int 0))
891
                                  (if_then_else
892
                                    (ne (symbol_ref "") (const_int 0))
893
                                    (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
894
                                    (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
895
                                  (if_then_else (ne (symbol_ref "") (const_int 0))
896
                                    (const_string "neon_mla_qqq_8_16")
897
                                    (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
898
)
899
 
900
(define_insn "*mul3negadd_neon"
901
  [(set (match_operand:VDQ 0 "s_register_operand" "=w")
902
        (minus:VDQ (match_operand:VDQ 1 "s_register_operand" "0")
903
                   (mult:VDQ (match_operand:VDQ 2 "s_register_operand" "w")
904
                             (match_operand:VDQ 3 "s_register_operand" "w"))))]
905
  "TARGET_NEON"
906
  "vmls.\t%0, %2, %3"
907
  [(set (attr "neon_type")
908
      (if_then_else (ne (symbol_ref "") (const_int 0))
909
                    (if_then_else (ne (symbol_ref "") (const_int 0))
910
                                  (const_string "neon_fp_vmla_ddd")
911
                                  (const_string "neon_fp_vmla_qqq"))
912
                    (if_then_else (ne (symbol_ref "") (const_int 0))
913
                                  (if_then_else
914
                                    (ne (symbol_ref "") (const_int 0))
915
                                    (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
916
                                    (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
917
                                  (if_then_else (ne (symbol_ref "") (const_int 0))
918
                                    (const_string "neon_mla_qqq_8_16")
919
                                    (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
920
)
921
 
922
(define_insn "ior3"
923
  [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
924
        (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
925
                 (match_operand:VDQ 2 "neon_logic_op2" "w,Dl")))]
926
  "TARGET_NEON"
927
{
928
  switch (which_alternative)
929
    {
930
    case 0: return "vorr\t%0, %1, %2";
931
    case 1: return neon_output_logic_immediate ("vorr", &operands[2],
932
                     mode, 0, VALID_NEON_QREG_MODE (mode));
933
    default: gcc_unreachable ();
934
    }
935
}
936
  [(set_attr "neon_type" "neon_int_1")]
937
)
938
 
939
(define_insn "iordi3_neon"
940
  [(set (match_operand:DI 0 "s_register_operand" "=w,w")
941
        (unspec:DI [(match_operand:DI 1 "s_register_operand" "w,0")
942
                    (match_operand:DI 2 "neon_logic_op2" "w,Dl")]
943
                    UNSPEC_VORR))]
944
  "TARGET_NEON"
945
{
946
  switch (which_alternative)
947
    {
948
    case 0: return "vorr\t%P0, %P1, %P2";
949
    case 1: return neon_output_logic_immediate ("vorr", &operands[2],
950
                     DImode, 0, VALID_NEON_QREG_MODE (DImode));
951
    default: gcc_unreachable ();
952
    }
953
}
954
  [(set_attr "neon_type" "neon_int_1")]
955
)
956
 
957
;; The concrete forms of the Neon immediate-logic instructions are vbic and
958
;; vorr. We support the pseudo-instruction vand instead, because that
959
;; corresponds to the canonical form the middle-end expects to use for
960
;; immediate bitwise-ANDs.
961
 
962
(define_insn "and3"
963
  [(set (match_operand:VDQ 0 "s_register_operand" "=w,w")
964
        (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w,0")
965
                 (match_operand:VDQ 2 "neon_inv_logic_op2" "w,DL")))]
966
  "TARGET_NEON"
967
{
968
  switch (which_alternative)
969
    {
970
    case 0: return "vand\t%0, %1, %2";
971
    case 1: return neon_output_logic_immediate ("vand", &operands[2],
972
                     mode, 1, VALID_NEON_QREG_MODE (mode));
973
    default: gcc_unreachable ();
974
    }
975
}
976
  [(set_attr "neon_type" "neon_int_1")]
977
)
978
 
979
(define_insn "anddi3_neon"
980
  [(set (match_operand:DI 0 "s_register_operand" "=w,w")
981
        (unspec:DI [(match_operand:DI 1 "s_register_operand" "w,0")
982
                    (match_operand:DI 2 "neon_inv_logic_op2" "w,DL")]
983
                    UNSPEC_VAND))]
984
  "TARGET_NEON"
985
{
986
  switch (which_alternative)
987
    {
988
    case 0: return "vand\t%P0, %P1, %P2";
989
    case 1: return neon_output_logic_immediate ("vand", &operands[2],
990
                     DImode, 1, VALID_NEON_QREG_MODE (DImode));
991
    default: gcc_unreachable ();
992
    }
993
}
994
  [(set_attr "neon_type" "neon_int_1")]
995
)
996
 
997
(define_insn "orn3_neon"
998
  [(set (match_operand:VDQ 0 "s_register_operand" "=w")
999
        (ior:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
1000
                 (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
1001
  "TARGET_NEON"
1002
  "vorn\t%0, %1, %2"
1003
  [(set_attr "neon_type" "neon_int_1")]
1004
)
1005
 
1006
(define_insn "orndi3_neon"
1007
  [(set (match_operand:DI 0 "s_register_operand" "=w")
1008
        (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
1009
                    (match_operand:DI 2 "s_register_operand" "w")]
1010
                    UNSPEC_VORN))]
1011
  "TARGET_NEON"
1012
  "vorn\t%P0, %P1, %P2"
1013
  [(set_attr "neon_type" "neon_int_1")]
1014
)
1015
 
1016
(define_insn "bic3_neon"
1017
  [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1018
        (and:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
1019
                  (not:VDQ (match_operand:VDQ 2 "s_register_operand" "w"))))]
1020
  "TARGET_NEON"
1021
  "vbic\t%0, %1, %2"
1022
  [(set_attr "neon_type" "neon_int_1")]
1023
)
1024
 
1025
(define_insn "bicdi3_neon"
1026
  [(set (match_operand:DI 0 "s_register_operand" "=w")
1027
        (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
1028
                     (match_operand:DI 2 "s_register_operand" "w")]
1029
                    UNSPEC_VBIC))]
1030
  "TARGET_NEON"
1031
  "vbic\t%P0, %P1, %P2"
1032
  [(set_attr "neon_type" "neon_int_1")]
1033
)
1034
 
1035
(define_insn "xor3"
1036
  [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1037
        (xor:VDQ (match_operand:VDQ 1 "s_register_operand" "w")
1038
                 (match_operand:VDQ 2 "s_register_operand" "w")))]
1039
  "TARGET_NEON"
1040
  "veor\t%0, %1, %2"
1041
  [(set_attr "neon_type" "neon_int_1")]
1042
)
1043
 
1044
(define_insn "xordi3_neon"
1045
  [(set (match_operand:DI 0 "s_register_operand" "=w")
1046
        (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
1047
                     (match_operand:DI 2 "s_register_operand" "w")]
1048
                    UNSPEC_VEOR))]
1049
  "TARGET_NEON"
1050
  "veor\t%P0, %P1, %P2"
1051
  [(set_attr "neon_type" "neon_int_1")]
1052
)
1053
 
1054
(define_insn "one_cmpl2"
1055
  [(set (match_operand:VDQ 0 "s_register_operand" "=w")
1056
        (not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))]
1057
  "TARGET_NEON"
1058
  "vmvn\t%0, %1"
1059
  [(set_attr "neon_type" "neon_int_1")]
1060
)
1061
 
1062
(define_insn "abs2"
1063
  [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1064
        (abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
1065
  "TARGET_NEON"
1066
  "vabs.\t%0, %1"
1067
  [(set (attr "neon_type")
1068
      (if_then_else (ne (symbol_ref "") (const_int 0))
1069
                    (if_then_else (ne (symbol_ref "") (const_int 0))
1070
                                  (const_string "neon_fp_vadd_ddd_vabs_dd")
1071
                                  (const_string "neon_fp_vadd_qqq_vabs_qq"))
1072
                    (const_string "neon_int_3")))]
1073
)
1074
 
1075
(define_insn "neg2"
1076
  [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1077
        (neg:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
1078
  "TARGET_NEON"
1079
  "vneg.\t%0, %1"
1080
  [(set (attr "neon_type")
1081
      (if_then_else (ne (symbol_ref "") (const_int 0))
1082
                    (if_then_else (ne (symbol_ref "") (const_int 0))
1083
                                  (const_string "neon_fp_vadd_ddd_vabs_dd")
1084
                                  (const_string "neon_fp_vadd_qqq_vabs_qq"))
1085
                    (const_string "neon_int_3")))]
1086
)
1087
 
1088
(define_insn "*umin3_neon"
1089
  [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1090
        (umin:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
1091
                    (match_operand:VDQIW 2 "s_register_operand" "w")))]
1092
  "TARGET_NEON"
1093
  "vmin.\t%0, %1, %2"
1094
  [(set_attr "neon_type" "neon_int_5")]
1095
)
1096
 
1097
(define_insn "*umax3_neon"
1098
  [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1099
        (umax:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
1100
                    (match_operand:VDQIW 2 "s_register_operand" "w")))]
1101
  "TARGET_NEON"
1102
  "vmax.\t%0, %1, %2"
1103
  [(set_attr "neon_type" "neon_int_5")]
1104
)
1105
 
1106
(define_insn "*smin3_neon"
1107
  [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1108
        (smin:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
1109
                   (match_operand:VDQW 2 "s_register_operand" "w")))]
1110
  "TARGET_NEON"
1111
  "vmin.\t%0, %1, %2"
1112
  [(set (attr "neon_type")
1113
      (if_then_else (ne (symbol_ref "") (const_int 0))
1114
                    (const_string "neon_fp_vadd_ddd_vabs_dd")
1115
                    (const_string "neon_int_5")))]
1116
)
1117
 
1118
(define_insn "*smax3_neon"
1119
  [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1120
        (smax:VDQW (match_operand:VDQW 1 "s_register_operand" "w")
1121
                   (match_operand:VDQW 2 "s_register_operand" "w")))]
1122
  "TARGET_NEON"
1123
  "vmax.\t%0, %1, %2"
1124
  [(set (attr "neon_type")
1125
      (if_then_else (ne (symbol_ref "") (const_int 0))
1126
                    (const_string "neon_fp_vadd_ddd_vabs_dd")
1127
                    (const_string "neon_int_5")))]
1128
)
1129
 
1130
; TODO: V2DI shifts are current disabled because there are bugs in the
1131
; generic vectorizer code.  It ends up creating a V2DI constructor with
1132
; SImode elements.
1133
 
1134
(define_insn "vashl3"
1135
  [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1136
        (ashift:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")
1137
                      (match_operand:VDQIW 2 "s_register_operand" "w")))]
1138
  "TARGET_NEON"
1139
  "vshl.\t%0, %1, %2"
1140
  [(set (attr "neon_type")
1141
      (if_then_else (ne (symbol_ref "") (const_int 0))
1142
                    (const_string "neon_vshl_ddd")
1143
                    (const_string "neon_shift_3")))]
1144
)
1145
 
1146
; Used for implementing logical shift-right, which is a left-shift by a negative
1147
; amount, with signed operands. This is essentially the same as ashl3
1148
; above, but using an unspec in case GCC tries anything tricky with negative
1149
; shift amounts.
1150
 
1151
(define_insn "ashl3_signed"
1152
  [(set (match_operand:VDQI 0 "s_register_operand" "=w")
1153
        (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
1154
                      (match_operand:VDQI 2 "s_register_operand" "w")]
1155
                     UNSPEC_ASHIFT_SIGNED))]
1156
  "TARGET_NEON"
1157
  "vshl.\t%0, %1, %2"
1158
  [(set (attr "neon_type")
1159
      (if_then_else (ne (symbol_ref "") (const_int 0))
1160
                    (const_string "neon_vshl_ddd")
1161
                    (const_string "neon_shift_3")))]
1162
)
1163
 
1164
; Used for implementing logical shift-right, which is a left-shift by a negative
1165
; amount, with unsigned operands.
1166
 
1167
(define_insn "ashl3_unsigned"
1168
  [(set (match_operand:VDQI 0 "s_register_operand" "=w")
1169
        (unspec:VDQI [(match_operand:VDQI 1 "s_register_operand" "w")
1170
                      (match_operand:VDQI 2 "s_register_operand" "w")]
1171
                     UNSPEC_ASHIFT_UNSIGNED))]
1172
  "TARGET_NEON"
1173
  "vshl.\t%0, %1, %2"
1174
  [(set (attr "neon_type")
1175
      (if_then_else (ne (symbol_ref "") (const_int 0))
1176
                    (const_string "neon_vshl_ddd")
1177
                    (const_string "neon_shift_3")))]
1178
)
1179
 
1180
(define_expand "vashr3"
1181
  [(set (match_operand:VDQIW 0 "s_register_operand" "")
1182
        (ashiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
1183
                        (match_operand:VDQIW 2 "s_register_operand" "")))]
1184
  "TARGET_NEON"
1185
{
1186
  rtx neg = gen_reg_rtx (mode);
1187
 
1188
  emit_insn (gen_neg2 (neg, operands[2]));
1189
  emit_insn (gen_ashl3_signed (operands[0], operands[1], neg));
1190
 
1191
  DONE;
1192
})
1193
 
1194
(define_expand "vlshr3"
1195
  [(set (match_operand:VDQIW 0 "s_register_operand" "")
1196
        (lshiftrt:VDQIW (match_operand:VDQIW 1 "s_register_operand" "")
1197
                        (match_operand:VDQIW 2 "s_register_operand" "")))]
1198
  "TARGET_NEON"
1199
{
1200
  rtx neg = gen_reg_rtx (mode);
1201
 
1202
  emit_insn (gen_neg2 (neg, operands[2]));
1203
  emit_insn (gen_ashl3_unsigned (operands[0], operands[1], neg));
1204
 
1205
  DONE;
1206
})
1207
 
1208
;; Widening operations
1209
 
1210
(define_insn "widen_ssum3"
1211
  [(set (match_operand: 0 "s_register_operand" "=w")
1212
        (plus: (sign_extend:
1213
                          (match_operand:VW 1 "s_register_operand" "%w"))
1214
                        (match_operand: 2 "s_register_operand" "w")))]
1215
  "TARGET_NEON"
1216
  "vaddw.\t%q0, %q2, %P1"
1217
  [(set_attr "neon_type" "neon_int_3")]
1218
)
1219
 
1220
(define_insn "widen_usum3"
1221
  [(set (match_operand: 0 "s_register_operand" "=w")
1222
        (plus: (zero_extend:
1223
                          (match_operand:VW 1 "s_register_operand" "%w"))
1224
                        (match_operand: 2 "s_register_operand" "w")))]
1225
  "TARGET_NEON"
1226
  "vaddw.\t%q0, %q2, %P1"
1227
  [(set_attr "neon_type" "neon_int_3")]
1228
)
1229
 
1230
;; VEXT can be used to synthesize coarse whole-vector shifts with 8-bit
1231
;; shift-count granularity. That's good enough for the middle-end's current
1232
;; needs.
1233
 
1234
(define_expand "vec_shr_"
1235
  [(match_operand:VDQ 0 "s_register_operand" "")
1236
   (match_operand:VDQ 1 "s_register_operand" "")
1237
   (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1238
  "TARGET_NEON"
1239
{
1240
  rtx zero_reg;
1241
  HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1242
  const int width = GET_MODE_BITSIZE (mode);
1243
  const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1244
  rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1245
    (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1246
 
1247
  if (num_bits == width)
1248
    {
1249
      emit_move_insn (operands[0], operands[1]);
1250
      DONE;
1251
    }
1252
 
1253
  zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1254
  operands[0] = gen_lowpart (bvecmode, operands[0]);
1255
  operands[1] = gen_lowpart (bvecmode, operands[1]);
1256
 
1257
  emit_insn (gen_ext (operands[0], operands[1], zero_reg,
1258
                      GEN_INT (num_bits / BITS_PER_UNIT)));
1259
  DONE;
1260
})
1261
 
1262
(define_expand "vec_shl_"
1263
  [(match_operand:VDQ 0 "s_register_operand" "")
1264
   (match_operand:VDQ 1 "s_register_operand" "")
1265
   (match_operand:SI 2 "const_multiple_of_8_operand" "")]
1266
  "TARGET_NEON"
1267
{
1268
  rtx zero_reg;
1269
  HOST_WIDE_INT num_bits = INTVAL (operands[2]);
1270
  const int width = GET_MODE_BITSIZE (mode);
1271
  const enum machine_mode bvecmode = (width == 128) ? V16QImode : V8QImode;
1272
  rtx (*gen_ext) (rtx, rtx, rtx, rtx) =
1273
    (width == 128) ? gen_neon_vextv16qi : gen_neon_vextv8qi;
1274
 
1275
  if (num_bits == 0)
1276
    {
1277
      emit_move_insn (operands[0], CONST0_RTX (mode));
1278
      DONE;
1279
    }
1280
 
1281
  num_bits = width - num_bits;
1282
 
1283
  zero_reg = force_reg (bvecmode, CONST0_RTX (bvecmode));
1284
  operands[0] = gen_lowpart (bvecmode, operands[0]);
1285
  operands[1] = gen_lowpart (bvecmode, operands[1]);
1286
 
1287
  emit_insn (gen_ext (operands[0], zero_reg, operands[1],
1288
                      GEN_INT (num_bits / BITS_PER_UNIT)));
1289
  DONE;
1290
})
1291
 
1292
;; Helpers for quad-word reduction operations
1293
 
1294
; Add (or smin, smax...) the low N/2 elements of the N-element vector
1295
; operand[1] to the high N/2 elements of same. Put the result in operand[0], an
1296
; N/2-element vector.
1297
 
1298
(define_insn "quad_halves_v4si"
1299
  [(set (match_operand:V2SI 0 "s_register_operand" "=w")
1300
        (vqh_ops:V2SI
1301
          (vec_select:V2SI (match_operand:V4SI 1 "s_register_operand" "w")
1302
                           (parallel [(const_int 0) (const_int 1)]))
1303
          (vec_select:V2SI (match_dup 1)
1304
                           (parallel [(const_int 2) (const_int 3)]))))]
1305
  "TARGET_NEON"
1306
  ".32\t%P0, %e1, %f1"
1307
  [(set_attr "vqh_mnem" "")
1308
   (set (attr "neon_type")
1309
      (if_then_else (eq_attr "vqh_mnem" "vadd")
1310
                    (const_string "neon_int_1") (const_string "neon_int_5")))]
1311
)
1312
 
1313
(define_insn "quad_halves_v4sf"
1314
  [(set (match_operand:V2SF 0 "s_register_operand" "=w")
1315
        (vqhs_ops:V2SF
1316
          (vec_select:V2SF (match_operand:V4SF 1 "s_register_operand" "w")
1317
                           (parallel [(const_int 0) (const_int 1)]))
1318
          (vec_select:V2SF (match_dup 1)
1319
                           (parallel [(const_int 2) (const_int 3)]))))]
1320
  "TARGET_NEON"
1321
  ".f32\t%P0, %e1, %f1"
1322
  [(set_attr "vqh_mnem" "")
1323
   (set (attr "neon_type")
1324
      (if_then_else (eq_attr "vqh_mnem" "vadd")
1325
                    (const_string "neon_int_1") (const_string "neon_int_5")))]
1326
)
1327
 
1328
(define_insn "quad_halves_v8hi"
1329
  [(set (match_operand:V4HI 0 "s_register_operand" "+w")
1330
        (vqh_ops:V4HI
1331
          (vec_select:V4HI (match_operand:V8HI 1 "s_register_operand" "w")
1332
                           (parallel [(const_int 0) (const_int 1)
1333
                                      (const_int 2) (const_int 3)]))
1334
          (vec_select:V4HI (match_dup 1)
1335
                           (parallel [(const_int 4) (const_int 5)
1336
                                      (const_int 6) (const_int 7)]))))]
1337
  "TARGET_NEON"
1338
  ".16\t%P0, %e1, %f1"
1339
  [(set_attr "vqh_mnem" "")
1340
   (set (attr "neon_type")
1341
      (if_then_else (eq_attr "vqh_mnem" "vadd")
1342
                    (const_string "neon_int_1") (const_string "neon_int_5")))]
1343
)
1344
 
1345
(define_insn "quad_halves_v16qi"
1346
  [(set (match_operand:V8QI 0 "s_register_operand" "+w")
1347
        (vqh_ops:V8QI
1348
          (vec_select:V8QI (match_operand:V16QI 1 "s_register_operand" "w")
1349
                           (parallel [(const_int 0) (const_int 1)
1350
                                      (const_int 2) (const_int 3)
1351
                                      (const_int 4) (const_int 5)
1352
                                      (const_int 6) (const_int 7)]))
1353
          (vec_select:V8QI (match_dup 1)
1354
                           (parallel [(const_int 8) (const_int 9)
1355
                                      (const_int 10) (const_int 11)
1356
                                      (const_int 12) (const_int 13)
1357
                                      (const_int 14) (const_int 15)]))))]
1358
  "TARGET_NEON"
1359
  ".8\t%P0, %e1, %f1"
1360
  [(set_attr "vqh_mnem" "")
1361
   (set (attr "neon_type")
1362
      (if_then_else (eq_attr "vqh_mnem" "vadd")
1363
                    (const_string "neon_int_1") (const_string "neon_int_5")))]
1364
)
1365
 
1366
; FIXME: We wouldn't need the following insns if we could write subregs of
1367
; vector registers. Make an attempt at removing unnecessary moves, though
1368
; we're really at the mercy of the register allocator.
1369
 
1370
(define_insn "move_lo_quad_v4si"
1371
  [(set (match_operand:V4SI 0 "s_register_operand" "+w")
1372
        (vec_concat:V4SI
1373
          (match_operand:V2SI 1 "s_register_operand" "w")
1374
          (vec_select:V2SI (match_dup 0)
1375
                           (parallel [(const_int 2) (const_int 3)]))))]
1376
  "TARGET_NEON"
1377
{
1378
  int dest = REGNO (operands[0]);
1379
  int src = REGNO (operands[1]);
1380
 
1381
  if (dest != src)
1382
    return "vmov\t%e0, %P1";
1383
  else
1384
    return "";
1385
}
1386
  [(set_attr "neon_type" "neon_bp_simple")]
1387
)
1388
 
1389
(define_insn "move_lo_quad_v4sf"
1390
  [(set (match_operand:V4SF 0 "s_register_operand" "+w")
1391
        (vec_concat:V4SF
1392
          (match_operand:V2SF 1 "s_register_operand" "w")
1393
          (vec_select:V2SF (match_dup 0)
1394
                           (parallel [(const_int 2) (const_int 3)]))))]
1395
  "TARGET_NEON"
1396
{
1397
  int dest = REGNO (operands[0]);
1398
  int src = REGNO (operands[1]);
1399
 
1400
  if (dest != src)
1401
    return "vmov\t%e0, %P1";
1402
  else
1403
    return "";
1404
}
1405
  [(set_attr "neon_type" "neon_bp_simple")]
1406
)
1407
 
1408
(define_insn "move_lo_quad_v8hi"
1409
  [(set (match_operand:V8HI 0 "s_register_operand" "+w")
1410
        (vec_concat:V8HI
1411
          (match_operand:V4HI 1 "s_register_operand" "w")
1412
          (vec_select:V4HI (match_dup 0)
1413
                           (parallel [(const_int 4) (const_int 5)
1414
                                      (const_int 6) (const_int 7)]))))]
1415
  "TARGET_NEON"
1416
{
1417
  int dest = REGNO (operands[0]);
1418
  int src = REGNO (operands[1]);
1419
 
1420
  if (dest != src)
1421
    return "vmov\t%e0, %P1";
1422
  else
1423
    return "";
1424
}
1425
  [(set_attr "neon_type" "neon_bp_simple")]
1426
)
1427
 
1428
(define_insn "move_lo_quad_v16qi"
1429
  [(set (match_operand:V16QI 0 "s_register_operand" "+w")
1430
        (vec_concat:V16QI
1431
          (match_operand:V8QI 1 "s_register_operand" "w")
1432
          (vec_select:V8QI (match_dup 0)
1433
                           (parallel [(const_int 8)  (const_int 9)
1434
                                      (const_int 10) (const_int 11)
1435
                                      (const_int 12) (const_int 13)
1436
                                      (const_int 14) (const_int 15)]))))]
1437
  "TARGET_NEON"
1438
{
1439
  int dest = REGNO (operands[0]);
1440
  int src = REGNO (operands[1]);
1441
 
1442
  if (dest != src)
1443
    return "vmov\t%e0, %P1";
1444
  else
1445
    return "";
1446
}
1447
  [(set_attr "neon_type" "neon_bp_simple")]
1448
)
1449
 
1450
;; Reduction operations
1451
 
1452
(define_expand "reduc_splus_"
1453
  [(match_operand:VD 0 "s_register_operand" "")
1454
   (match_operand:VD 1 "s_register_operand" "")]
1455
  "TARGET_NEON"
1456
{
1457
  neon_pairwise_reduce (operands[0], operands[1], mode,
1458
                        &gen_neon_vpadd_internal);
1459
  DONE;
1460
})
1461
 
1462
(define_expand "reduc_splus_"
1463
  [(match_operand:VQ 0 "s_register_operand" "")
1464
   (match_operand:VQ 1 "s_register_operand" "")]
1465
  "TARGET_NEON"
1466
{
1467
  rtx step1 = gen_reg_rtx (mode);
1468
  rtx res_d = gen_reg_rtx (mode);
1469
 
1470
  emit_insn (gen_quad_halves_plus (step1, operands[1]));
1471
  emit_insn (gen_reduc_splus_ (res_d, step1));
1472
  emit_insn (gen_move_lo_quad_ (operands[0], res_d));
1473
 
1474
  DONE;
1475
})
1476
 
1477
(define_insn "reduc_splus_v2di"
1478
  [(set (match_operand:V2DI 0 "s_register_operand" "=w")
1479
        (unspec:V2DI [(match_operand:V2DI 1 "s_register_operand" "w")]
1480
                     UNSPEC_VPADD))]
1481
  "TARGET_NEON"
1482
  "vadd.i64\t%e0, %e1, %f1"
1483
  [(set_attr "neon_type" "neon_int_1")]
1484
)
1485
 
1486
;; NEON does not distinguish between signed and unsigned addition except on
1487
;; widening operations.
1488
(define_expand "reduc_uplus_"
1489
  [(match_operand:VDQI 0 "s_register_operand" "")
1490
   (match_operand:VDQI 1 "s_register_operand" "")]
1491
  "TARGET_NEON"
1492
{
1493
  emit_insn (gen_reduc_splus_ (operands[0], operands[1]));
1494
  DONE;
1495
})
1496
 
1497
(define_expand "reduc_smin_"
1498
  [(match_operand:VD 0 "s_register_operand" "")
1499
   (match_operand:VD 1 "s_register_operand" "")]
1500
  "TARGET_NEON"
1501
{
1502
  neon_pairwise_reduce (operands[0], operands[1], mode,
1503
                        &gen_neon_vpsmin);
1504
  DONE;
1505
})
1506
 
1507
(define_expand "reduc_smin_"
1508
  [(match_operand:VQ 0 "s_register_operand" "")
1509
   (match_operand:VQ 1 "s_register_operand" "")]
1510
  "TARGET_NEON"
1511
{
1512
  rtx step1 = gen_reg_rtx (mode);
1513
  rtx res_d = gen_reg_rtx (mode);
1514
 
1515
  emit_insn (gen_quad_halves_smin (step1, operands[1]));
1516
  emit_insn (gen_reduc_smin_ (res_d, step1));
1517
  emit_insn (gen_move_lo_quad_ (operands[0], res_d));
1518
 
1519
  DONE;
1520
})
1521
 
1522
(define_expand "reduc_smax_"
1523
  [(match_operand:VD 0 "s_register_operand" "")
1524
   (match_operand:VD 1 "s_register_operand" "")]
1525
  "TARGET_NEON"
1526
{
1527
  neon_pairwise_reduce (operands[0], operands[1], mode,
1528
                        &gen_neon_vpsmax);
1529
  DONE;
1530
})
1531
 
1532
(define_expand "reduc_smax_"
1533
  [(match_operand:VQ 0 "s_register_operand" "")
1534
   (match_operand:VQ 1 "s_register_operand" "")]
1535
  "TARGET_NEON"
1536
{
1537
  rtx step1 = gen_reg_rtx (mode);
1538
  rtx res_d = gen_reg_rtx (mode);
1539
 
1540
  emit_insn (gen_quad_halves_smax (step1, operands[1]));
1541
  emit_insn (gen_reduc_smax_ (res_d, step1));
1542
  emit_insn (gen_move_lo_quad_ (operands[0], res_d));
1543
 
1544
  DONE;
1545
})
1546
 
1547
(define_expand "reduc_umin_"
1548
  [(match_operand:VDI 0 "s_register_operand" "")
1549
   (match_operand:VDI 1 "s_register_operand" "")]
1550
  "TARGET_NEON"
1551
{
1552
  neon_pairwise_reduce (operands[0], operands[1], mode,
1553
                        &gen_neon_vpumin);
1554
  DONE;
1555
})
1556
 
1557
(define_expand "reduc_umin_"
1558
  [(match_operand:VQI 0 "s_register_operand" "")
1559
   (match_operand:VQI 1 "s_register_operand" "")]
1560
  "TARGET_NEON"
1561
{
1562
  rtx step1 = gen_reg_rtx (mode);
1563
  rtx res_d = gen_reg_rtx (mode);
1564
 
1565
  emit_insn (gen_quad_halves_umin (step1, operands[1]));
1566
  emit_insn (gen_reduc_umin_ (res_d, step1));
1567
  emit_insn (gen_move_lo_quad_ (operands[0], res_d));
1568
 
1569
  DONE;
1570
})
1571
 
1572
(define_expand "reduc_umax_"
1573
  [(match_operand:VDI 0 "s_register_operand" "")
1574
   (match_operand:VDI 1 "s_register_operand" "")]
1575
  "TARGET_NEON"
1576
{
1577
  neon_pairwise_reduce (operands[0], operands[1], mode,
1578
                        &gen_neon_vpumax);
1579
  DONE;
1580
})
1581
 
1582
(define_expand "reduc_umax_"
1583
  [(match_operand:VQI 0 "s_register_operand" "")
1584
   (match_operand:VQI 1 "s_register_operand" "")]
1585
  "TARGET_NEON"
1586
{
1587
  rtx step1 = gen_reg_rtx (mode);
1588
  rtx res_d = gen_reg_rtx (mode);
1589
 
1590
  emit_insn (gen_quad_halves_umax (step1, operands[1]));
1591
  emit_insn (gen_reduc_umax_ (res_d, step1));
1592
  emit_insn (gen_move_lo_quad_ (operands[0], res_d));
1593
 
1594
  DONE;
1595
})
1596
 
1597
(define_insn "neon_vpadd_internal"
1598
  [(set (match_operand:VD 0 "s_register_operand" "=w")
1599
        (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1600
                    (match_operand:VD 2 "s_register_operand" "w")]
1601
                   UNSPEC_VPADD))]
1602
  "TARGET_NEON"
1603
  "vpadd.\t%P0, %P1, %P2"
1604
  ;; Assume this schedules like vadd.
1605
  [(set (attr "neon_type")
1606
      (if_then_else (ne (symbol_ref "") (const_int 0))
1607
                    (if_then_else (ne (symbol_ref "") (const_int 0))
1608
                                  (const_string "neon_fp_vadd_ddd_vabs_dd")
1609
                                  (const_string "neon_fp_vadd_qqq_vabs_qq"))
1610
                    (const_string "neon_int_1")))]
1611
)
1612
 
1613
(define_insn "neon_vpsmin"
1614
  [(set (match_operand:VD 0 "s_register_operand" "=w")
1615
        (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1616
                    (match_operand:VD 2 "s_register_operand" "w")]
1617
                   UNSPEC_VPSMIN))]
1618
  "TARGET_NEON"
1619
  "vpmin.\t%P0, %P1, %P2"
1620
  ;; Assume this schedules like vmin.
1621
  [(set (attr "neon_type")
1622
      (if_then_else (ne (symbol_ref "") (const_int 0))
1623
                    (const_string "neon_fp_vadd_ddd_vabs_dd")
1624
                    (const_string "neon_int_5")))]
1625
)
1626
 
1627
(define_insn "neon_vpsmax"
1628
  [(set (match_operand:VD 0 "s_register_operand" "=w")
1629
        (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
1630
                    (match_operand:VD 2 "s_register_operand" "w")]
1631
                   UNSPEC_VPSMAX))]
1632
  "TARGET_NEON"
1633
  "vpmax.\t%P0, %P1, %P2"
1634
  ;; Assume this schedules like vmax.
1635
  [(set (attr "neon_type")
1636
      (if_then_else (ne (symbol_ref "") (const_int 0))
1637
                    (const_string "neon_fp_vadd_ddd_vabs_dd")
1638
                    (const_string "neon_int_5")))]
1639
)
1640
 
1641
(define_insn "neon_vpumin"
1642
  [(set (match_operand:VDI 0 "s_register_operand" "=w")
1643
        (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1644
                     (match_operand:VDI 2 "s_register_operand" "w")]
1645
                   UNSPEC_VPUMIN))]
1646
  "TARGET_NEON"
1647
  "vpmin.\t%P0, %P1, %P2"
1648
  ;; Assume this schedules like umin.
1649
  [(set_attr "neon_type" "neon_int_5")]
1650
)
1651
 
1652
(define_insn "neon_vpumax"
1653
  [(set (match_operand:VDI 0 "s_register_operand" "=w")
1654
        (unspec:VDI [(match_operand:VDI 1 "s_register_operand" "w")
1655
                     (match_operand:VDI 2 "s_register_operand" "w")]
1656
                   UNSPEC_VPUMAX))]
1657
  "TARGET_NEON"
1658
  "vpmax.\t%P0, %P1, %P2"
1659
  ;; Assume this schedules like umax.
1660
  [(set_attr "neon_type" "neon_int_5")]
1661
)
1662
 
1663
;; Saturating arithmetic
1664
 
1665
; NOTE: Neon supports many more saturating variants of instructions than the
1666
; following, but these are all GCC currently understands.
1667
; FIXME: Actually, GCC doesn't know how to create saturating add/sub by itself
1668
; yet either, although these patterns may be used by intrinsics when they're
1669
; added.
1670
 
1671
(define_insn "*ss_add_neon"
1672
  [(set (match_operand:VD 0 "s_register_operand" "=w")
1673
       (ss_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1674
                   (match_operand:VD 2 "s_register_operand" "w")))]
1675
  "TARGET_NEON"
1676
  "vqadd.\t%P0, %P1, %P2"
1677
  [(set_attr "neon_type" "neon_int_4")]
1678
)
1679
 
1680
(define_insn "*us_add_neon"
1681
  [(set (match_operand:VD 0 "s_register_operand" "=w")
1682
       (us_plus:VD (match_operand:VD 1 "s_register_operand" "w")
1683
                   (match_operand:VD 2 "s_register_operand" "w")))]
1684
  "TARGET_NEON"
1685
  "vqadd.\t%P0, %P1, %P2"
1686
  [(set_attr "neon_type" "neon_int_4")]
1687
)
1688
 
1689
(define_insn "*ss_sub_neon"
1690
  [(set (match_operand:VD 0 "s_register_operand" "=w")
1691
       (ss_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1692
                    (match_operand:VD 2 "s_register_operand" "w")))]
1693
  "TARGET_NEON"
1694
  "vqsub.\t%P0, %P1, %P2"
1695
  [(set_attr "neon_type" "neon_int_5")]
1696
)
1697
 
1698
(define_insn "*us_sub_neon"
1699
  [(set (match_operand:VD 0 "s_register_operand" "=w")
1700
       (us_minus:VD (match_operand:VD 1 "s_register_operand" "w")
1701
                    (match_operand:VD 2 "s_register_operand" "w")))]
1702
  "TARGET_NEON"
1703
  "vqsub.\t%P0, %P1, %P2"
1704
  [(set_attr "neon_type" "neon_int_5")]
1705
)
1706
 
1707
;; Patterns for builtins.
1708
 
1709
; good for plain vadd, vaddq.
1710
 
1711
(define_insn "neon_vadd"
1712
  [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1713
        (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1714
                      (match_operand:VDQX 2 "s_register_operand" "w")
1715
                      (match_operand:SI 3 "immediate_operand" "i")]
1716
                     UNSPEC_VADD))]
1717
  "TARGET_NEON"
1718
  "vadd.\t%0, %1, %2"
1719
  [(set (attr "neon_type")
1720
      (if_then_else (ne (symbol_ref "") (const_int 0))
1721
                    (if_then_else (ne (symbol_ref "") (const_int 0))
1722
                                  (const_string "neon_fp_vadd_ddd_vabs_dd")
1723
                                  (const_string "neon_fp_vadd_qqq_vabs_qq"))
1724
                    (const_string "neon_int_1")))]
1725
)
1726
 
1727
; operand 3 represents in bits:
1728
;  bit 0: signed (vs unsigned).
1729
;  bit 1: rounding (vs none).
1730
 
1731
(define_insn "neon_vaddl"
1732
  [(set (match_operand: 0 "s_register_operand" "=w")
1733
        (unspec: [(match_operand:VDI 1 "s_register_operand" "w")
1734
                           (match_operand:VDI 2 "s_register_operand" "w")
1735
                           (match_operand:SI 3 "immediate_operand" "i")]
1736
                          UNSPEC_VADDL))]
1737
  "TARGET_NEON"
1738
  "vaddl.%T3%#\t%q0, %P1, %P2"
1739
  [(set_attr "neon_type" "neon_int_3")]
1740
)
1741
 
1742
(define_insn "neon_vaddw"
1743
  [(set (match_operand: 0 "s_register_operand" "=w")
1744
        (unspec: [(match_operand: 1 "s_register_operand" "w")
1745
                           (match_operand:VDI 2 "s_register_operand" "w")
1746
                           (match_operand:SI 3 "immediate_operand" "i")]
1747
                          UNSPEC_VADDW))]
1748
  "TARGET_NEON"
1749
  "vaddw.%T3%#\t%q0, %q1, %P2"
1750
  [(set_attr "neon_type" "neon_int_2")]
1751
)
1752
 
1753
; vhadd and vrhadd.
1754
 
1755
(define_insn "neon_vhadd"
1756
  [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
1757
        (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
1758
                       (match_operand:VDQIW 2 "s_register_operand" "w")
1759
                       (match_operand:SI 3 "immediate_operand" "i")]
1760
                      UNSPEC_VHADD))]
1761
  "TARGET_NEON"
1762
  "v%O3hadd.%T3%#\t%0, %1, %2"
1763
  [(set_attr "neon_type" "neon_int_4")]
1764
)
1765
 
1766
(define_insn "neon_vqadd"
1767
  [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
1768
        (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
1769
                       (match_operand:VDQIX 2 "s_register_operand" "w")
1770
                       (match_operand:SI 3 "immediate_operand" "i")]
1771
                     UNSPEC_VQADD))]
1772
  "TARGET_NEON"
1773
  "vqadd.%T3%#\t%0, %1, %2"
1774
  [(set_attr "neon_type" "neon_int_4")]
1775
)
1776
 
1777
(define_insn "neon_vaddhn"
1778
  [(set (match_operand: 0 "s_register_operand" "=w")
1779
        (unspec: [(match_operand:VN 1 "s_register_operand" "w")
1780
                            (match_operand:VN 2 "s_register_operand" "w")
1781
                            (match_operand:SI 3 "immediate_operand" "i")]
1782
                           UNSPEC_VADDHN))]
1783
  "TARGET_NEON"
1784
  "v%O3addhn.\t%P0, %q1, %q2"
1785
  [(set_attr "neon_type" "neon_int_4")]
1786
)
1787
 
1788
(define_insn "neon_vmul"
1789
  [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1790
        (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
1791
                      (match_operand:VDQW 2 "s_register_operand" "w")
1792
                      (match_operand:SI 3 "immediate_operand" "i")]
1793
                     UNSPEC_VMUL))]
1794
  "TARGET_NEON"
1795
  "vmul.%F3%#\t%0, %1, %2"
1796
  [(set (attr "neon_type")
1797
      (if_then_else (ne (symbol_ref "") (const_int 0))
1798
                    (if_then_else (ne (symbol_ref "") (const_int 0))
1799
                                  (const_string "neon_fp_vadd_ddd_vabs_dd")
1800
                                  (const_string "neon_fp_vadd_qqq_vabs_qq"))
1801
                    (if_then_else (ne (symbol_ref "") (const_int 0))
1802
                                  (if_then_else
1803
                                    (ne (symbol_ref "") (const_int 0))
1804
                                    (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1805
                                    (const_string "neon_mul_qqq_8_16_32_ddd_32"))
1806
                                  (if_then_else (ne (symbol_ref "") (const_int 0))
1807
                                    (const_string "neon_mul_qqq_8_16_32_ddd_32")
1808
                                    (const_string "neon_mul_qqq_8_16_32_ddd_32")))))]
1809
)
1810
 
1811
(define_insn "neon_vmla"
1812
  [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1813
        (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
1814
                      (match_operand:VDQW 2 "s_register_operand" "w")
1815
                      (match_operand:VDQW 3 "s_register_operand" "w")
1816
                     (match_operand:SI 4 "immediate_operand" "i")]
1817
                    UNSPEC_VMLA))]
1818
  "TARGET_NEON"
1819
  "vmla.\t%0, %2, %3"
1820
  [(set (attr "neon_type")
1821
      (if_then_else (ne (symbol_ref "") (const_int 0))
1822
                    (if_then_else (ne (symbol_ref "") (const_int 0))
1823
                                  (const_string "neon_fp_vmla_ddd")
1824
                                  (const_string "neon_fp_vmla_qqq"))
1825
                    (if_then_else (ne (symbol_ref "") (const_int 0))
1826
                                  (if_then_else
1827
                                    (ne (symbol_ref "") (const_int 0))
1828
                                    (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1829
                                    (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
1830
                                  (if_then_else (ne (symbol_ref "") (const_int 0))
1831
                                    (const_string "neon_mla_qqq_8_16")
1832
                                    (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
1833
)
1834
 
1835
(define_insn "neon_vmlal"
1836
  [(set (match_operand: 0 "s_register_operand" "=w")
1837
        (unspec: [(match_operand: 1 "s_register_operand" "0")
1838
                           (match_operand:VW 2 "s_register_operand" "w")
1839
                           (match_operand:VW 3 "s_register_operand" "w")
1840
                           (match_operand:SI 4 "immediate_operand" "i")]
1841
                          UNSPEC_VMLAL))]
1842
  "TARGET_NEON"
1843
  "vmlal.%T4%#\t%q0, %P2, %P3"
1844
  [(set (attr "neon_type")
1845
     (if_then_else (ne (symbol_ref "") (const_int 0))
1846
                   (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1847
                   (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1848
)
1849
 
1850
(define_insn "neon_vmls"
1851
  [(set (match_operand:VDQW 0 "s_register_operand" "=w")
1852
        (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")
1853
                      (match_operand:VDQW 2 "s_register_operand" "w")
1854
                      (match_operand:VDQW 3 "s_register_operand" "w")
1855
                     (match_operand:SI 4 "immediate_operand" "i")]
1856
                    UNSPEC_VMLS))]
1857
  "TARGET_NEON"
1858
  "vmls.\t%0, %2, %3"
1859
  [(set (attr "neon_type")
1860
      (if_then_else (ne (symbol_ref "") (const_int 0))
1861
                    (if_then_else (ne (symbol_ref "") (const_int 0))
1862
                                  (const_string "neon_fp_vmla_ddd")
1863
                                  (const_string "neon_fp_vmla_qqq"))
1864
                    (if_then_else (ne (symbol_ref "") (const_int 0))
1865
                                  (if_then_else
1866
                                    (ne (symbol_ref "") (const_int 0))
1867
                                    (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1868
                                    (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
1869
                                  (if_then_else
1870
                                    (ne (symbol_ref "") (const_int 0))
1871
                                    (const_string "neon_mla_qqq_8_16")
1872
                                    (const_string "neon_mla_qqq_32_qqd_32_scalar")))))]
1873
)
1874
 
1875
(define_insn "neon_vmlsl"
1876
  [(set (match_operand: 0 "s_register_operand" "=w")
1877
        (unspec: [(match_operand: 1 "s_register_operand" "0")
1878
                           (match_operand:VW 2 "s_register_operand" "w")
1879
                           (match_operand:VW 3 "s_register_operand" "w")
1880
                           (match_operand:SI 4 "immediate_operand" "i")]
1881
                          UNSPEC_VMLSL))]
1882
  "TARGET_NEON"
1883
  "vmlsl.%T4%#\t%q0, %P2, %P3"
1884
  [(set (attr "neon_type")
1885
     (if_then_else (ne (symbol_ref "") (const_int 0))
1886
                   (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1887
                   (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1888
)
1889
 
1890
(define_insn "neon_vqdmulh"
1891
  [(set (match_operand:VMDQI 0 "s_register_operand" "=w")
1892
        (unspec:VMDQI [(match_operand:VMDQI 1 "s_register_operand" "w")
1893
                       (match_operand:VMDQI 2 "s_register_operand" "w")
1894
                       (match_operand:SI 3 "immediate_operand" "i")]
1895
                      UNSPEC_VQDMULH))]
1896
  "TARGET_NEON"
1897
  "vq%O3dmulh.\t%0, %1, %2"
1898
  [(set (attr "neon_type")
1899
     (if_then_else (ne (symbol_ref "") (const_int 0))
1900
        (if_then_else (ne (symbol_ref "") (const_int 0))
1901
                      (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1902
                      (const_string "neon_mul_qqq_8_16_32_ddd_32"))
1903
        (if_then_else (ne (symbol_ref "") (const_int 0))
1904
                      (const_string "neon_mul_qqq_8_16_32_ddd_32")
1905
                      (const_string "neon_mul_qqq_8_16_32_ddd_32"))))]
1906
)
1907
 
1908
(define_insn "neon_vqdmlal"
1909
  [(set (match_operand: 0 "s_register_operand" "=w")
1910
        (unspec: [(match_operand: 1 "s_register_operand" "0")
1911
                           (match_operand:VMDI 2 "s_register_operand" "w")
1912
                           (match_operand:VMDI 3 "s_register_operand" "w")
1913
                           (match_operand:SI 4 "immediate_operand" "i")]
1914
                          UNSPEC_VQDMLAL))]
1915
  "TARGET_NEON"
1916
  "vqdmlal.\t%q0, %P2, %P3"
1917
  [(set (attr "neon_type")
1918
     (if_then_else (ne (symbol_ref "") (const_int 0))
1919
                   (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1920
                   (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1921
)
1922
 
1923
(define_insn "neon_vqdmlsl"
1924
  [(set (match_operand: 0 "s_register_operand" "=w")
1925
        (unspec: [(match_operand: 1 "s_register_operand" "0")
1926
                           (match_operand:VMDI 2 "s_register_operand" "w")
1927
                           (match_operand:VMDI 3 "s_register_operand" "w")
1928
                           (match_operand:SI 4 "immediate_operand" "i")]
1929
                          UNSPEC_VQDMLSL))]
1930
  "TARGET_NEON"
1931
  "vqdmlsl.\t%q0, %P2, %P3"
1932
  [(set (attr "neon_type")
1933
     (if_then_else (ne (symbol_ref "") (const_int 0))
1934
                   (const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
1935
                   (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
1936
)
1937
 
1938
(define_insn "neon_vmull"
1939
  [(set (match_operand: 0 "s_register_operand" "=w")
1940
        (unspec: [(match_operand:VW 1 "s_register_operand" "w")
1941
                           (match_operand:VW 2 "s_register_operand" "w")
1942
                           (match_operand:SI 3 "immediate_operand" "i")]
1943
                          UNSPEC_VMULL))]
1944
  "TARGET_NEON"
1945
  "vmull.%T3%#\t%q0, %P1, %P2"
1946
  [(set (attr "neon_type")
1947
     (if_then_else (ne (symbol_ref "") (const_int 0))
1948
                   (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1949
                   (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
1950
)
1951
 
1952
(define_insn "neon_vqdmull"
1953
  [(set (match_operand: 0 "s_register_operand" "=w")
1954
        (unspec: [(match_operand:VMDI 1 "s_register_operand" "w")
1955
                           (match_operand:VMDI 2 "s_register_operand" "w")
1956
                           (match_operand:SI 3 "immediate_operand" "i")]
1957
                          UNSPEC_VQDMULL))]
1958
  "TARGET_NEON"
1959
  "vqdmull.\t%q0, %P1, %P2"
1960
  [(set (attr "neon_type")
1961
     (if_then_else (ne (symbol_ref "") (const_int 0))
1962
                   (const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
1963
                   (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
1964
)
1965
 
1966
(define_insn "neon_vsub"
1967
  [(set (match_operand:VDQX 0 "s_register_operand" "=w")
1968
        (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
1969
                      (match_operand:VDQX 2 "s_register_operand" "w")
1970
                      (match_operand:SI 3 "immediate_operand" "i")]
1971
                     UNSPEC_VSUB))]
1972
  "TARGET_NEON"
1973
  "vsub.\t%0, %1, %2"
1974
  [(set (attr "neon_type")
1975
      (if_then_else (ne (symbol_ref "") (const_int 0))
1976
                    (if_then_else (ne (symbol_ref "") (const_int 0))
1977
                                  (const_string "neon_fp_vadd_ddd_vabs_dd")
1978
                                  (const_string "neon_fp_vadd_qqq_vabs_qq"))
1979
                    (const_string "neon_int_2")))]
1980
)
1981
 
1982
(define_insn "neon_vsubl"
1983
  [(set (match_operand: 0 "s_register_operand" "=w")
1984
        (unspec: [(match_operand:VDI 1 "s_register_operand" "w")
1985
                           (match_operand:VDI 2 "s_register_operand" "w")
1986
                           (match_operand:SI 3 "immediate_operand" "i")]
1987
                          UNSPEC_VSUBL))]
1988
  "TARGET_NEON"
1989
  "vsubl.%T3%#\t%q0, %P1, %P2"
1990
  [(set_attr "neon_type" "neon_int_2")]
1991
)
1992
 
1993
(define_insn "neon_vsubw"
1994
  [(set (match_operand: 0 "s_register_operand" "=w")
1995
        (unspec: [(match_operand: 1 "s_register_operand" "w")
1996
                           (match_operand:VDI 2 "s_register_operand" "w")
1997
                           (match_operand:SI 3 "immediate_operand" "i")]
1998
                          UNSPEC_VSUBW))]
1999
  "TARGET_NEON"
2000
  "vsubw.%T3%#\t%q0, %q1, %P2"
2001
  [(set_attr "neon_type" "neon_int_2")]
2002
)
2003
 
2004
(define_insn "neon_vqsub"
2005
  [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
2006
        (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
2007
                       (match_operand:VDQIX 2 "s_register_operand" "w")
2008
                       (match_operand:SI 3 "immediate_operand" "i")]
2009
                      UNSPEC_VQSUB))]
2010
  "TARGET_NEON"
2011
  "vqsub.%T3%#\t%0, %1, %2"
2012
  [(set_attr "neon_type" "neon_int_5")]
2013
)
2014
 
2015
(define_insn "neon_vhsub"
2016
  [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2017
        (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2018
                       (match_operand:VDQIW 2 "s_register_operand" "w")
2019
                       (match_operand:SI 3 "immediate_operand" "i")]
2020
                      UNSPEC_VHSUB))]
2021
  "TARGET_NEON"
2022
  "vhsub.%T3%#\t%0, %1, %2"
2023
  [(set_attr "neon_type" "neon_int_5")]
2024
)
2025
 
2026
(define_insn "neon_vsubhn"
2027
  [(set (match_operand: 0 "s_register_operand" "=w")
2028
        (unspec: [(match_operand:VN 1 "s_register_operand" "w")
2029
                            (match_operand:VN 2 "s_register_operand" "w")
2030
                            (match_operand:SI 3 "immediate_operand" "i")]
2031
                           UNSPEC_VSUBHN))]
2032
  "TARGET_NEON"
2033
  "v%O3subhn.\t%P0, %q1, %q2"
2034
  [(set_attr "neon_type" "neon_int_4")]
2035
)
2036
 
2037
(define_insn "neon_vceq"
2038
  [(set (match_operand: 0 "s_register_operand" "=w")
2039
        (unspec: [(match_operand:VDQW 1 "s_register_operand" "w")
2040
                                (match_operand:VDQW 2 "s_register_operand" "w")
2041
                                (match_operand:SI 3 "immediate_operand" "i")]
2042
                               UNSPEC_VCEQ))]
2043
  "TARGET_NEON"
2044
  "vceq.\t%0, %1, %2"
2045
  [(set (attr "neon_type")
2046
      (if_then_else (ne (symbol_ref "") (const_int 0))
2047
                    (if_then_else (ne (symbol_ref "") (const_int 0))
2048
                                  (const_string "neon_fp_vadd_ddd_vabs_dd")
2049
                                  (const_string "neon_fp_vadd_qqq_vabs_qq"))
2050
                    (const_string "neon_int_5")))]
2051
)
2052
 
2053
(define_insn "neon_vcge"
2054
  [(set (match_operand: 0 "s_register_operand" "=w")
2055
        (unspec: [(match_operand:VDQW 1 "s_register_operand" "w")
2056
                                (match_operand:VDQW 2 "s_register_operand" "w")
2057
                                (match_operand:SI 3 "immediate_operand" "i")]
2058
                               UNSPEC_VCGE))]
2059
  "TARGET_NEON"
2060
  "vcge.%T3%#\t%0, %1, %2"
2061
  [(set (attr "neon_type")
2062
     (if_then_else (ne (symbol_ref "") (const_int 0))
2063
                   (if_then_else (ne (symbol_ref "") (const_int 0))
2064
                                 (const_string "neon_fp_vadd_ddd_vabs_dd")
2065
                                 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2066
                   (const_string "neon_int_5")))]
2067
)
2068
 
2069
(define_insn "neon_vcgt"
2070
  [(set (match_operand: 0 "s_register_operand" "=w")
2071
        (unspec: [(match_operand:VDQW 1 "s_register_operand" "w")
2072
                                (match_operand:VDQW 2 "s_register_operand" "w")
2073
                                (match_operand:SI 3 "immediate_operand" "i")]
2074
                               UNSPEC_VCGT))]
2075
  "TARGET_NEON"
2076
  "vcgt.%T3%#\t%0, %1, %2"
2077
  [(set (attr "neon_type")
2078
     (if_then_else (ne (symbol_ref "") (const_int 0))
2079
                   (if_then_else (ne (symbol_ref "") (const_int 0))
2080
                                 (const_string "neon_fp_vadd_ddd_vabs_dd")
2081
                                 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2082
                   (const_string "neon_int_5")))]
2083
)
2084
 
2085
(define_insn "neon_vcage"
2086
  [(set (match_operand: 0 "s_register_operand" "=w")
2087
        (unspec: [(match_operand:VCVTF 1 "s_register_operand" "w")
2088
                                (match_operand:VCVTF 2 "s_register_operand" "w")
2089
                                (match_operand:SI 3 "immediate_operand" "i")]
2090
                               UNSPEC_VCAGE))]
2091
  "TARGET_NEON"
2092
  "vacge.\t%0, %1, %2"
2093
  [(set (attr "neon_type")
2094
     (if_then_else (ne (symbol_ref "") (const_int 0))
2095
                   (const_string "neon_fp_vadd_ddd_vabs_dd")
2096
                   (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2097
)
2098
 
2099
(define_insn "neon_vcagt"
2100
  [(set (match_operand: 0 "s_register_operand" "=w")
2101
        (unspec: [(match_operand:VCVTF 1 "s_register_operand" "w")
2102
                                (match_operand:VCVTF 2 "s_register_operand" "w")
2103
                                (match_operand:SI 3 "immediate_operand" "i")]
2104
                               UNSPEC_VCAGT))]
2105
  "TARGET_NEON"
2106
  "vacgt.\t%0, %1, %2"
2107
  [(set (attr "neon_type")
2108
     (if_then_else (ne (symbol_ref "") (const_int 0))
2109
                   (const_string "neon_fp_vadd_ddd_vabs_dd")
2110
                   (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2111
)
2112
 
2113
(define_insn "neon_vtst"
2114
  [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2115
        (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2116
                       (match_operand:VDQIW 2 "s_register_operand" "w")
2117
                       (match_operand:SI 3 "immediate_operand" "i")]
2118
                      UNSPEC_VTST))]
2119
  "TARGET_NEON"
2120
  "vtst.\t%0, %1, %2"
2121
  [(set_attr "neon_type" "neon_int_4")]
2122
)
2123
 
2124
(define_insn "neon_vabd"
2125
  [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2126
        (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2127
                      (match_operand:VDQW 2 "s_register_operand" "w")
2128
                      (match_operand:SI 3 "immediate_operand" "i")]
2129
                     UNSPEC_VABD))]
2130
  "TARGET_NEON"
2131
  "vabd.%T3%#\t%0, %1, %2"
2132
  [(set (attr "neon_type")
2133
     (if_then_else (ne (symbol_ref "") (const_int 0))
2134
                   (if_then_else (ne (symbol_ref "") (const_int 0))
2135
                                 (const_string "neon_fp_vadd_ddd_vabs_dd")
2136
                                 (const_string "neon_fp_vadd_qqq_vabs_qq"))
2137
                   (const_string "neon_int_5")))]
2138
)
2139
 
2140
(define_insn "neon_vabdl"
2141
  [(set (match_operand: 0 "s_register_operand" "=w")
2142
        (unspec: [(match_operand:VW 1 "s_register_operand" "w")
2143
                           (match_operand:VW 2 "s_register_operand" "w")
2144
                           (match_operand:SI 3 "immediate_operand" "i")]
2145
                          UNSPEC_VABDL))]
2146
  "TARGET_NEON"
2147
  "vabdl.%T3%#\t%q0, %P1, %P2"
2148
  [(set_attr "neon_type" "neon_int_5")]
2149
)
2150
 
2151
(define_insn "neon_vaba"
2152
  [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2153
        (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "0")
2154
                       (match_operand:VDQIW 2 "s_register_operand" "w")
2155
                       (match_operand:VDQIW 3 "s_register_operand" "w")
2156
                       (match_operand:SI 4 "immediate_operand" "i")]
2157
                      UNSPEC_VABA))]
2158
  "TARGET_NEON"
2159
  "vaba.%T4%#\t%0, %2, %3"
2160
  [(set (attr "neon_type")
2161
     (if_then_else (ne (symbol_ref "") (const_int 0))
2162
                   (const_string "neon_vaba") (const_string "neon_vaba_qqq")))]
2163
)
2164
 
2165
(define_insn "neon_vabal"
2166
  [(set (match_operand: 0 "s_register_operand" "=w")
2167
        (unspec: [(match_operand: 1 "s_register_operand" "0")
2168
                           (match_operand:VW 2 "s_register_operand" "w")
2169
                           (match_operand:VW 3 "s_register_operand" "w")
2170
                           (match_operand:SI 4 "immediate_operand" "i")]
2171
                          UNSPEC_VABAL))]
2172
  "TARGET_NEON"
2173
  "vabal.%T4%#\t%q0, %P2, %P3"
2174
  [(set_attr "neon_type" "neon_vaba")]
2175
)
2176
 
2177
(define_insn "neon_vmax"
2178
  [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2179
        (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2180
                      (match_operand:VDQW 2 "s_register_operand" "w")
2181
                      (match_operand:SI 3 "immediate_operand" "i")]
2182
                     UNSPEC_VMAX))]
2183
  "TARGET_NEON"
2184
  "vmax.%T3%#\t%0, %1, %2"
2185
  [(set (attr "neon_type")
2186
    (if_then_else (ne (symbol_ref "") (const_int 0))
2187
                  (if_then_else (ne (symbol_ref "") (const_int 0))
2188
                                (const_string "neon_fp_vadd_ddd_vabs_dd")
2189
                                (const_string "neon_fp_vadd_qqq_vabs_qq"))
2190
                  (const_string "neon_int_5")))]
2191
)
2192
 
2193
(define_insn "neon_vmin"
2194
  [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2195
        (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2196
                      (match_operand:VDQW 2 "s_register_operand" "w")
2197
                      (match_operand:SI 3 "immediate_operand" "i")]
2198
                     UNSPEC_VMIN))]
2199
  "TARGET_NEON"
2200
  "vmin.%T3%#\t%0, %1, %2"
2201
  [(set (attr "neon_type")
2202
    (if_then_else (ne (symbol_ref "") (const_int 0))
2203
                  (if_then_else (ne (symbol_ref "") (const_int 0))
2204
                                (const_string "neon_fp_vadd_ddd_vabs_dd")
2205
                                (const_string "neon_fp_vadd_qqq_vabs_qq"))
2206
                  (const_string "neon_int_5")))]
2207
)
2208
 
2209
(define_expand "neon_vpadd"
2210
  [(match_operand:VD 0 "s_register_operand" "=w")
2211
   (match_operand:VD 1 "s_register_operand" "w")
2212
   (match_operand:VD 2 "s_register_operand" "w")
2213
   (match_operand:SI 3 "immediate_operand" "i")]
2214
  "TARGET_NEON"
2215
{
2216
  emit_insn (gen_neon_vpadd_internal (operands[0], operands[1],
2217
                                            operands[2]));
2218
  DONE;
2219
})
2220
 
2221
(define_insn "neon_vpaddl"
2222
  [(set (match_operand: 0 "s_register_operand" "=w")
2223
        (unspec: [(match_operand:VDQIW 1 "s_register_operand" "w")
2224
                                  (match_operand:SI 2 "immediate_operand" "i")]
2225
                                 UNSPEC_VPADDL))]
2226
  "TARGET_NEON"
2227
  "vpaddl.%T2%#\t%0, %1"
2228
  ;; Assume this schedules like vaddl.
2229
  [(set_attr "neon_type" "neon_int_3")]
2230
)
2231
 
2232
(define_insn "neon_vpadal"
2233
  [(set (match_operand: 0 "s_register_operand" "=w")
2234
        (unspec: [(match_operand: 1 "s_register_operand" "0")
2235
                                  (match_operand:VDQIW 2 "s_register_operand" "w")
2236
                                  (match_operand:SI 3 "immediate_operand" "i")]
2237
                                 UNSPEC_VPADAL))]
2238
  "TARGET_NEON"
2239
  "vpadal.%T3%#\t%0, %2"
2240
  ;; Assume this schedules like vpadd.
2241
  [(set_attr "neon_type" "neon_int_1")]
2242
)
2243
 
2244
(define_insn "neon_vpmax"
2245
  [(set (match_operand:VD 0 "s_register_operand" "=w")
2246
        (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2247
                    (match_operand:VD 2 "s_register_operand" "w")
2248
                    (match_operand:SI 3 "immediate_operand" "i")]
2249
                   UNSPEC_VPMAX))]
2250
  "TARGET_NEON"
2251
  "vpmax.%T3%#\t%0, %1, %2"
2252
  ;; Assume this schedules like vmax.
2253
  [(set (attr "neon_type")
2254
    (if_then_else (ne (symbol_ref "") (const_int 0))
2255
                  (const_string "neon_fp_vadd_ddd_vabs_dd")
2256
                  (const_string "neon_int_5")))]
2257
)
2258
 
2259
(define_insn "neon_vpmin"
2260
  [(set (match_operand:VD 0 "s_register_operand" "=w")
2261
        (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2262
                    (match_operand:VD 2 "s_register_operand" "w")
2263
                    (match_operand:SI 3 "immediate_operand" "i")]
2264
                   UNSPEC_VPMIN))]
2265
  "TARGET_NEON"
2266
  "vpmin.%T3%#\t%0, %1, %2"
2267
  ;; Assume this schedules like vmin.
2268
  [(set (attr "neon_type")
2269
    (if_then_else (ne (symbol_ref "") (const_int 0))
2270
                  (const_string "neon_fp_vadd_ddd_vabs_dd")
2271
                  (const_string "neon_int_5")))]
2272
)
2273
 
2274
(define_insn "neon_vrecps"
2275
  [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2276
        (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2277
                       (match_operand:VCVTF 2 "s_register_operand" "w")
2278
                       (match_operand:SI 3 "immediate_operand" "i")]
2279
                      UNSPEC_VRECPS))]
2280
  "TARGET_NEON"
2281
  "vrecps.\t%0, %1, %2"
2282
  [(set (attr "neon_type")
2283
      (if_then_else (ne (symbol_ref "") (const_int 0))
2284
                    (const_string "neon_fp_vrecps_vrsqrts_ddd")
2285
                    (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2286
)
2287
 
2288
(define_insn "neon_vrsqrts"
2289
  [(set (match_operand:VCVTF 0 "s_register_operand" "=w")
2290
        (unspec:VCVTF [(match_operand:VCVTF 1 "s_register_operand" "w")
2291
                       (match_operand:VCVTF 2 "s_register_operand" "w")
2292
                       (match_operand:SI 3 "immediate_operand" "i")]
2293
                      UNSPEC_VRSQRTS))]
2294
  "TARGET_NEON"
2295
  "vrsqrts.\t%0, %1, %2"
2296
  [(set (attr "neon_type")
2297
      (if_then_else (ne (symbol_ref "") (const_int 0))
2298
                    (const_string "neon_fp_vrecps_vrsqrts_ddd")
2299
                    (const_string "neon_fp_vrecps_vrsqrts_qqq")))]
2300
)
2301
 
2302
(define_insn "neon_vabs"
2303
  [(set (match_operand:VDQW 0 "s_register_operand" "=w")
2304
        (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "w")
2305
                      (match_operand:SI 2 "immediate_operand" "i")]
2306
                     UNSPEC_VABS))]
2307
  "TARGET_NEON"
2308
  "vabs.\t%0, %1"
2309
  [(set (attr "neon_type")
2310
     (if_then_else (ior (ne (symbol_ref "") (const_int 0))
2311
                        (ne (symbol_ref "") (const_int 0)))
2312
                   (if_then_else
2313
                      (ne (symbol_ref "") (const_int 0))
2314
                      (const_string "neon_fp_vadd_ddd_vabs_dd")
2315
                      (const_string "neon_fp_vadd_qqq_vabs_qq"))
2316
                   (const_string "neon_vqneg_vqabs")))]
2317
)
2318
 
2319
(define_insn "neon_vqabs"
2320
  [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2321
        (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2322
                       (match_operand:SI 2 "immediate_operand" "i")]
2323
                      UNSPEC_VQABS))]
2324
  "TARGET_NEON"
2325
  "vqabs.\t%0, %1"
2326
  [(set_attr "neon_type" "neon_vqneg_vqabs")]
2327
)
2328
 
2329
(define_expand "neon_vneg"
2330
  [(match_operand:VDQW 0 "s_register_operand" "")
2331
   (match_operand:VDQW 1 "s_register_operand" "")
2332
   (match_operand:SI 2 "immediate_operand" "")]
2333
  "TARGET_NEON"
2334
{
2335
  emit_insn (gen_neg2 (operands[0], operands[1]));
2336
  DONE;
2337
})
2338
 
2339
(define_insn "neon_vqneg"
2340
  [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2341
        (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2342
                       (match_operand:SI 2 "immediate_operand" "i")]
2343
                      UNSPEC_VQNEG))]
2344
  "TARGET_NEON"
2345
  "vqneg.\t%0, %1"
2346
  [(set_attr "neon_type" "neon_vqneg_vqabs")]
2347
)
2348
 
2349
(define_insn "neon_vcls"
2350
  [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2351
        (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2352
                       (match_operand:SI 2 "immediate_operand" "i")]
2353
                      UNSPEC_VCLS))]
2354
  "TARGET_NEON"
2355
  "vcls.\t%0, %1"
2356
  [(set_attr "neon_type" "neon_int_1")]
2357
)
2358
 
2359
(define_insn "neon_vclz"
2360
  [(set (match_operand:VDQIW 0 "s_register_operand" "=w")
2361
        (unspec:VDQIW [(match_operand:VDQIW 1 "s_register_operand" "w")
2362
                       (match_operand:SI 2 "immediate_operand" "i")]
2363
                      UNSPEC_VCLZ))]
2364
  "TARGET_NEON"
2365
  "vclz.\t%0, %1"
2366
  [(set_attr "neon_type" "neon_int_1")]
2367
)
2368
 
2369
(define_insn "neon_vcnt"
2370
  [(set (match_operand:VE 0 "s_register_operand" "=w")
2371
        (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
2372
                    (match_operand:SI 2 "immediate_operand" "i")]
2373
                   UNSPEC_VCNT))]
2374
  "TARGET_NEON"
2375
  "vcnt.\t%0, %1"
2376
  [(set_attr "neon_type" "neon_int_1")]
2377
)
2378
 
2379
(define_insn "neon_vrecpe"
2380
  [(set (match_operand:V32 0 "s_register_operand" "=w")
2381
        (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2382
                     (match_operand:SI 2 "immediate_operand" "i")]
2383
                    UNSPEC_VRECPE))]
2384
  "TARGET_NEON"
2385
  "vrecpe.\t%0, %1"
2386
  [(set (attr "neon_type")
2387
      (if_then_else (ne (symbol_ref "") (const_int 0))
2388
                    (const_string "neon_fp_vadd_ddd_vabs_dd")
2389
                    (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2390
)
2391
 
2392
(define_insn "neon_vrsqrte"
2393
  [(set (match_operand:V32 0 "s_register_operand" "=w")
2394
        (unspec:V32 [(match_operand:V32 1 "s_register_operand" "w")
2395
                     (match_operand:SI 2 "immediate_operand" "i")]
2396
                    UNSPEC_VRSQRTE))]
2397
  "TARGET_NEON"
2398
  "vrsqrte.\t%0, %1"
2399
  [(set (attr "neon_type")
2400
      (if_then_else (ne (symbol_ref "") (const_int 0))
2401
                    (const_string "neon_fp_vadd_ddd_vabs_dd")
2402
                    (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2403
)
2404
 
2405
(define_expand "neon_vmvn"
2406
  [(match_operand:VDQIW 0 "s_register_operand" "")
2407
   (match_operand:VDQIW 1 "s_register_operand" "")
2408
   (match_operand:SI 2 "immediate_operand" "")]
2409
  "TARGET_NEON"
2410
{
2411
  emit_insn (gen_one_cmpl2 (operands[0], operands[1]));
2412
  DONE;
2413
})
2414
 
2415
(define_insn "neon_vget_lane_sext_internal"
2416
  [(set (match_operand:SI 0 "s_register_operand" "=r")
2417
        (sign_extend:SI
2418
          (vec_select:
2419
            (match_operand:VD 1 "s_register_operand" "w")
2420
            (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2421
  "TARGET_NEON"
2422
{
2423
  if (BYTES_BIG_ENDIAN)
2424
    {
2425
      int elt = INTVAL (operands[2]);
2426
      elt = GET_MODE_NUNITS (mode) - 1 - elt;
2427
      operands[2] = GEN_INT (elt);
2428
    }
2429
  return "vmov%?.s\t%0, %P1[%c2]";
2430
}
2431
  [(set_attr "predicable" "yes")
2432
   (set_attr "neon_type" "neon_bp_simple")]
2433
)
2434
 
2435
(define_insn "neon_vget_lane_zext_internal"
2436
  [(set (match_operand:SI 0 "s_register_operand" "=r")
2437
        (zero_extend:SI
2438
          (vec_select:
2439
            (match_operand:VD 1 "s_register_operand" "w")
2440
            (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2441
  "TARGET_NEON"
2442
{
2443
  if (BYTES_BIG_ENDIAN)
2444
    {
2445
      int elt = INTVAL (operands[2]);
2446
      elt = GET_MODE_NUNITS (mode) - 1 - elt;
2447
      operands[2] = GEN_INT (elt);
2448
    }
2449
  return "vmov%?.u\t%0, %P1[%c2]";
2450
}
2451
  [(set_attr "predicable" "yes")
2452
   (set_attr "neon_type" "neon_bp_simple")]
2453
)
2454
 
2455
(define_insn "neon_vget_lane_sext_internal"
2456
  [(set (match_operand:SI 0 "s_register_operand" "=r")
2457
        (sign_extend:SI
2458
          (vec_select:
2459
            (match_operand:VQ 1 "s_register_operand" "w")
2460
            (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2461
  "TARGET_NEON"
2462
{
2463
  rtx ops[3];
2464
  int regno = REGNO (operands[1]);
2465
  unsigned int halfelts = GET_MODE_NUNITS (mode) / 2;
2466
  unsigned int elt = INTVAL (operands[2]);
2467
  unsigned int elt_adj = elt % halfelts;
2468
 
2469
  if (BYTES_BIG_ENDIAN)
2470
    elt_adj = halfelts - 1 - elt_adj;
2471
 
2472
  ops[0] = operands[0];
2473
  ops[1] = gen_rtx_REG (mode, regno + 2 * (elt / halfelts));
2474
  ops[2] = GEN_INT (elt_adj);
2475
  output_asm_insn ("vmov%?.s\t%0, %P1[%c2]", ops);
2476
 
2477
  return "";
2478
}
2479
  [(set_attr "predicable" "yes")
2480
   (set_attr "neon_type" "neon_bp_simple")]
2481
)
2482
 
2483
(define_insn "neon_vget_lane_zext_internal"
2484
  [(set (match_operand:SI 0 "s_register_operand" "=r")
2485
        (zero_extend:SI
2486
          (vec_select:
2487
            (match_operand:VQ 1 "s_register_operand" "w")
2488
            (parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
2489
  "TARGET_NEON"
2490
{
2491
  rtx ops[3];
2492
  int regno = REGNO (operands[1]);
2493
  unsigned int halfelts = GET_MODE_NUNITS (mode) / 2;
2494
  unsigned int elt = INTVAL (operands[2]);
2495
  unsigned int elt_adj = elt % halfelts;
2496
 
2497
  if (BYTES_BIG_ENDIAN)
2498
    elt_adj = halfelts - 1 - elt_adj;
2499
 
2500
  ops[0] = operands[0];
2501
  ops[1] = gen_rtx_REG (mode, regno + 2 * (elt / halfelts));
2502
  ops[2] = GEN_INT (elt_adj);
2503
  output_asm_insn ("vmov%?.u\t%0, %P1[%c2]", ops);
2504
 
2505
  return "";
2506
}
2507
  [(set_attr "predicable" "yes")
2508
   (set_attr "neon_type" "neon_bp_simple")]
2509
)
2510
 
2511
(define_expand "neon_vget_lane"
2512
  [(match_operand: 0 "s_register_operand" "")
2513
   (match_operand:VDQW 1 "s_register_operand" "")
2514
   (match_operand:SI 2 "immediate_operand" "")
2515
   (match_operand:SI 3 "immediate_operand" "")]
2516
  "TARGET_NEON"
2517
{
2518
  HOST_WIDE_INT magic = INTVAL (operands[3]);
2519
  rtx insn;
2520
 
2521
  neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (mode));
2522
 
2523
  if (BYTES_BIG_ENDIAN)
2524
    {
2525
      /* The intrinsics are defined in terms of a model where the
2526
         element ordering in memory is vldm order, whereas the generic
2527
         RTL is defined in terms of a model where the element ordering
2528
         in memory is array order.  Convert the lane number to conform
2529
         to this model.  */
2530
      unsigned int elt = INTVAL (operands[2]);
2531
      unsigned int reg_nelts
2532
        = 64 / GET_MODE_BITSIZE (GET_MODE_INNER (mode));
2533
      elt ^= reg_nelts - 1;
2534
      operands[2] = GEN_INT (elt);
2535
    }
2536
 
2537
  if ((magic & 3) == 3 || GET_MODE_BITSIZE (GET_MODE_INNER (mode)) == 32)
2538
    insn = gen_vec_extract (operands[0], operands[1], operands[2]);
2539
  else
2540
    {
2541
      if ((magic & 1) != 0)
2542
        insn = gen_neon_vget_lane_sext_internal (operands[0], operands[1],
2543
                                                       operands[2]);
2544
      else
2545
        insn = gen_neon_vget_lane_zext_internal (operands[0], operands[1],
2546
                                                       operands[2]);
2547
    }
2548
  emit_insn (insn);
2549
  DONE;
2550
})
2551
 
2552
; Operand 3 (info word) is ignored because it does nothing useful with 64-bit
2553
; elements.
2554
 
2555
(define_insn "neon_vget_lanedi"
2556
  [(set (match_operand:DI 0 "s_register_operand" "=r")
2557
       (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
2558
                   (match_operand:SI 2 "immediate_operand" "i")
2559
                   (match_operand:SI 3 "immediate_operand" "i")]
2560
                  UNSPEC_VGET_LANE))]
2561
  "TARGET_NEON"
2562
{
2563
  neon_lane_bounds (operands[2], 0, 1);
2564
  return "vmov%?\t%Q0, %R0, %P1  @ di";
2565
}
2566
  [(set_attr "predicable" "yes")
2567
   (set_attr "neon_type" "neon_bp_simple")]
2568
)
2569
 
2570
(define_insn "neon_vget_lanev2di"
2571
  [(set (match_operand:DI 0 "s_register_operand" "=r")
2572
       (unspec:DI [(match_operand:V2DI 1 "s_register_operand" "w")
2573
                   (match_operand:SI 2 "immediate_operand" "i")
2574
                   (match_operand:SI 3 "immediate_operand" "i")]
2575
                  UNSPEC_VGET_LANE))]
2576
  "TARGET_NEON"
2577
{
2578
  rtx ops[2];
2579
  unsigned int regno = REGNO (operands[1]);
2580
  unsigned int elt = INTVAL (operands[2]);
2581
 
2582
  neon_lane_bounds (operands[2], 0, 2);
2583
 
2584
  ops[0] = operands[0];
2585
  ops[1] = gen_rtx_REG (DImode, regno + 2 * elt);
2586
  output_asm_insn ("vmov%?\t%Q0, %R0, %P1  @ v2di", ops);
2587
 
2588
  return "";
2589
}
2590
  [(set_attr "predicable" "yes")
2591
   (set_attr "neon_type" "neon_bp_simple")]
2592
)
2593
 
2594
(define_insn "neon_vset_lane"
2595
  [(set (match_operand:VD 0 "s_register_operand" "=w")
2596
        (unspec:VD [(match_operand: 1 "s_register_operand" "r")
2597
                    (match_operand:VD 2 "s_register_operand" "0")
2598
                    (match_operand:SI 3 "immediate_operand" "i")]
2599
                   UNSPEC_VSET_LANE))]
2600
  "TARGET_NEON"
2601
{
2602
  neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (mode));
2603
  return "vmov%?.\t%P0[%c3], %1";
2604
}
2605
  [(set_attr "predicable" "yes")
2606
   (set_attr "neon_type" "neon_bp_simple")]
2607
)
2608
 
2609
; See neon_vget_lanedi comment for reasons operands 2 & 3 are ignored.
2610
 
2611
(define_insn "neon_vset_lanedi"
2612
  [(set (match_operand:DI 0 "s_register_operand" "=w")
2613
        (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")
2614
                    (match_operand:DI 2 "s_register_operand" "0")
2615
                    (match_operand:SI 3 "immediate_operand" "i")]
2616
                   UNSPEC_VSET_LANE))]
2617
  "TARGET_NEON"
2618
{
2619
  neon_lane_bounds (operands[3], 0, 1);
2620
  return "vmov%?\t%P0, %Q1, %R1  @ di";
2621
}
2622
  [(set_attr "predicable" "yes")
2623
   (set_attr "neon_type" "neon_bp_simple")]
2624
)
2625
 
2626
(define_insn "neon_vset_lane"
2627
  [(set (match_operand:VQ 0 "s_register_operand" "=w")
2628
        (unspec:VQ [(match_operand: 1 "s_register_operand" "r")
2629
                    (match_operand:VQ 2 "s_register_operand" "0")
2630
                    (match_operand:SI 3 "immediate_operand" "i")]
2631
                   UNSPEC_VSET_LANE))]
2632
  "TARGET_NEON"
2633
{
2634
  rtx ops[4];
2635
  unsigned int regno = REGNO (operands[0]);
2636
  unsigned int halfelts = GET_MODE_NUNITS (mode) / 2;
2637
  unsigned int elt = INTVAL (operands[3]);
2638
 
2639
  neon_lane_bounds (operands[3], 0, halfelts * 2);
2640
 
2641
  ops[0] = gen_rtx_REG (mode, regno + 2 * (elt / halfelts));
2642
  ops[1] = operands[1];
2643
  ops[2] = GEN_INT (elt % halfelts);
2644
  output_asm_insn ("vmov%?.\t%P0[%c2], %1", ops);
2645
 
2646
  return "";
2647
}
2648
  [(set_attr "predicable" "yes")
2649
   (set_attr "neon_type" "neon_bp_simple")]
2650
)
2651
 
2652
(define_insn "neon_vset_lanev2di"
2653
  [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2654
        (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "r")
2655
                      (match_operand:V2DI 2 "s_register_operand" "0")
2656
                      (match_operand:SI 3 "immediate_operand" "i")]
2657
                   UNSPEC_VSET_LANE))]
2658
  "TARGET_NEON"
2659
{
2660
  rtx ops[2];
2661
  unsigned int regno = REGNO (operands[0]);
2662
  unsigned int elt = INTVAL (operands[3]);
2663
 
2664
  neon_lane_bounds (operands[3], 0, 2);
2665
 
2666
  ops[0] = gen_rtx_REG (DImode, regno + 2 * elt);
2667
  ops[1] = operands[1];
2668
  output_asm_insn ("vmov%?\t%P0, %Q1, %R1  @ v2di", ops);
2669
 
2670
  return "";
2671
}
2672
  [(set_attr "predicable" "yes")
2673
   (set_attr "neon_type" "neon_bp_simple")]
2674
)
2675
 
2676
(define_expand "neon_vcreate"
2677
  [(match_operand:VDX 0 "s_register_operand" "")
2678
   (match_operand:DI 1 "general_operand" "")]
2679
  "TARGET_NEON"
2680
{
2681
  rtx src = gen_lowpart (mode, operands[1]);
2682
  emit_move_insn (operands[0], src);
2683
  DONE;
2684
})
2685
 
2686
(define_insn "neon_vdup_n"
2687
  [(set (match_operand:VX 0 "s_register_operand" "=w")
2688
        (unspec:VX [(match_operand: 1 "s_register_operand" "r")]
2689
                   UNSPEC_VDUP_N))]
2690
  "TARGET_NEON"
2691
  "vdup%?.\t%0, %1"
2692
  ;; Assume this schedules like vmov.
2693
  [(set_attr "predicable" "yes")
2694
   (set_attr "neon_type" "neon_bp_simple")]
2695
)
2696
 
2697
(define_insn "neon_vdup_n"
2698
  [(set (match_operand:V32 0 "s_register_operand" "=w,w")
2699
        (unspec:V32 [(match_operand: 1 "s_register_operand" "r,t")]
2700
                    UNSPEC_VDUP_N))]
2701
  "TARGET_NEON"
2702
  "@
2703
  vdup%?.\t%0, %1
2704
  vdup%?.\t%0, %y1"
2705
  ;; Assume this schedules like vmov.
2706
  [(set_attr "predicable" "yes")
2707
   (set_attr "neon_type" "neon_bp_simple")]
2708
)
2709
 
2710
(define_insn "neon_vdup_ndi"
2711
  [(set (match_operand:DI 0 "s_register_operand" "=w")
2712
        (unspec:DI [(match_operand:DI 1 "s_register_operand" "r")]
2713
                   UNSPEC_VDUP_N))]
2714
  "TARGET_NEON"
2715
  "vmov%?\t%P0, %Q1, %R1"
2716
  [(set_attr "predicable" "yes")
2717
   (set_attr "neon_type" "neon_bp_simple")]
2718
)
2719
 
2720
(define_insn "neon_vdup_nv2di"
2721
  [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2722
        (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "r")]
2723
                     UNSPEC_VDUP_N))]
2724
  "TARGET_NEON"
2725
  "vmov%?\t%e0, %Q1, %R1\;vmov%?\t%f0, %Q1, %R1"
2726
  [(set_attr "predicable" "yes")
2727
   (set_attr "length" "8")
2728
   (set_attr "neon_type" "neon_bp_simple")]
2729
)
2730
 
2731
(define_insn "neon_vdup_lane"
2732
  [(set (match_operand:VD 0 "s_register_operand" "=w")
2733
        (unspec:VD [(match_operand:VD 1 "s_register_operand" "w")
2734
                    (match_operand:SI 2 "immediate_operand" "i")]
2735
                   UNSPEC_VDUP_LANE))]
2736
  "TARGET_NEON"
2737
{
2738
  neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (mode));
2739
  return "vdup.\t%P0, %P1[%c2]";
2740
}
2741
  ;; Assume this schedules like vmov.
2742
  [(set_attr "neon_type" "neon_bp_simple")]
2743
)
2744
 
2745
(define_insn "neon_vdup_lane"
2746
  [(set (match_operand:VQ 0 "s_register_operand" "=w")
2747
        (unspec:VQ [(match_operand: 1 "s_register_operand" "w")
2748
                    (match_operand:SI 2 "immediate_operand" "i")]
2749
                   UNSPEC_VDUP_LANE))]
2750
  "TARGET_NEON"
2751
{
2752
  neon_lane_bounds (operands[2], 0, GET_MODE_NUNITS (mode));
2753
  return "vdup.\t%q0, %P1[%c2]";
2754
}
2755
  ;; Assume this schedules like vmov.
2756
  [(set_attr "neon_type" "neon_bp_simple")]
2757
)
2758
 
2759
; Scalar index is ignored, since only zero is valid here.
2760
(define_expand "neon_vdup_lanedi"
2761
  [(set (match_operand:DI 0 "s_register_operand" "=w")
2762
        (unspec:DI [(match_operand:DI 1 "s_register_operand" "w")
2763
                    (match_operand:SI 2 "immediate_operand" "i")]
2764
                   UNSPEC_VDUP_LANE))]
2765
  "TARGET_NEON"
2766
{
2767
  neon_lane_bounds (operands[2], 0, 1);
2768
  emit_move_insn (operands[0], operands[1]);
2769
  DONE;
2770
})
2771
 
2772
; Likewise.
2773
(define_insn "neon_vdup_lanev2di"
2774
  [(set (match_operand:V2DI 0 "s_register_operand" "=w")
2775
        (unspec:V2DI [(match_operand:DI 1 "s_register_operand" "w")
2776
                      (match_operand:SI 2 "immediate_operand" "i")]
2777
                     UNSPEC_VDUP_LANE))]
2778
  "TARGET_NEON"
2779
{
2780
  neon_lane_bounds (operands[2], 0, 1);
2781
  return "vmov\t%e0, %P1\;vmov\t%f0, %P1";
2782
}
2783
  [(set_attr "length" "8")
2784
   (set_attr "neon_type" "neon_bp_simple")]
2785
)
2786
 
2787
;; In this insn, operand 1 should be low, and operand 2 the high part of the
2788
;; dest vector.
2789
;; FIXME: A different implementation of this builtin could make it much
2790
;; more likely that we wouldn't actually need to output anything (we could make
2791
;; it so that the reg allocator puts things in the right places magically
2792
;; instead). Lack of subregs for vectors makes that tricky though, I think.
2793
 
2794
(define_insn "neon_vcombine"
2795
  [(set (match_operand: 0 "s_register_operand" "=w")
2796
        (unspec: [(match_operand:VDX 1 "s_register_operand" "w")
2797
                            (match_operand:VDX 2 "s_register_operand" "w")]
2798
                           UNSPEC_VCOMBINE))]
2799
  "TARGET_NEON"
2800
{
2801
  int dest = REGNO (operands[0]);
2802
  int src1 = REGNO (operands[1]);
2803
  int src2 = REGNO (operands[2]);
2804
  rtx destlo;
2805
 
2806
  if (src1 == dest && src2 == dest + 2)
2807
    return "";
2808
  else if (src2 == dest && src1 == dest + 2)
2809
    /* Special case of reversed high/low parts.  */
2810
    return "vswp\t%P1, %P2";
2811
 
2812
  destlo = gen_rtx_REG (mode, dest);
2813
 
2814
  if (!reg_overlap_mentioned_p (operands[2], destlo))
2815
    {
2816
      /* Try to avoid unnecessary moves if part of the result is in the right
2817
         place already.  */
2818
      if (src1 != dest)
2819
        output_asm_insn ("vmov\t%e0, %P1", operands);
2820
      if (src2 != dest + 2)
2821
        output_asm_insn ("vmov\t%f0, %P2", operands);
2822
    }
2823
  else
2824
    {
2825
      if (src2 != dest + 2)
2826
        output_asm_insn ("vmov\t%f0, %P2", operands);
2827
      if (src1 != dest)
2828
        output_asm_insn ("vmov\t%e0, %P1", operands);
2829
    }
2830
 
2831
  return "";
2832
}
2833
  ;; We set the neon_type attribute based on the vmov instructions above.
2834
  [(set_attr "length" "8")
2835
   (set_attr "neon_type" "neon_bp_simple")]
2836
)
2837
 
2838
(define_insn "neon_vget_high"
2839
  [(set (match_operand: 0 "s_register_operand" "=w")
2840
        (unspec: [(match_operand:VQX 1 "s_register_operand" "w")]
2841
                         UNSPEC_VGET_HIGH))]
2842
  "TARGET_NEON"
2843
{
2844
  int dest = REGNO (operands[0]);
2845
  int src = REGNO (operands[1]);
2846
 
2847
  if (dest != src + 2)
2848
    return "vmov\t%P0, %f1";
2849
  else
2850
    return "";
2851
}
2852
  [(set_attr "neon_type" "neon_bp_simple")]
2853
)
2854
 
2855
(define_insn "neon_vget_low"
2856
  [(set (match_operand: 0 "s_register_operand" "=w")
2857
        (unspec: [(match_operand:VQX 1 "s_register_operand" "w")]
2858
                         UNSPEC_VGET_LOW))]
2859
  "TARGET_NEON"
2860
{
2861
  int dest = REGNO (operands[0]);
2862
  int src = REGNO (operands[1]);
2863
 
2864
  if (dest != src)
2865
    return "vmov\t%P0, %e1";
2866
  else
2867
    return "";
2868
}
2869
  [(set_attr "neon_type" "neon_bp_simple")]
2870
)
2871
 
2872
(define_insn "neon_vcvt"
2873
  [(set (match_operand: 0 "s_register_operand" "=w")
2874
        (unspec: [(match_operand:VCVTF 1 "s_register_operand" "w")
2875
                           (match_operand:SI 2 "immediate_operand" "i")]
2876
                          UNSPEC_VCVT))]
2877
  "TARGET_NEON"
2878
  "vcvt.%T2%#32.f32\t%0, %1"
2879
  [(set (attr "neon_type")
2880
     (if_then_else (ne (symbol_ref "") (const_int 0))
2881
                   (const_string "neon_fp_vadd_ddd_vabs_dd")
2882
                   (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2883
)
2884
 
2885
(define_insn "neon_vcvt"
2886
  [(set (match_operand: 0 "s_register_operand" "=w")
2887
        (unspec: [(match_operand:VCVTI 1 "s_register_operand" "w")
2888
                           (match_operand:SI 2 "immediate_operand" "i")]
2889
                          UNSPEC_VCVT))]
2890
  "TARGET_NEON"
2891
  "vcvt.f32.%T2%#32\t%0, %1"
2892
  [(set (attr "neon_type")
2893
     (if_then_else (ne (symbol_ref "") (const_int 0))
2894
                   (const_string "neon_fp_vadd_ddd_vabs_dd")
2895
                   (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2896
)
2897
 
2898
(define_insn "neon_vcvt_n"
2899
  [(set (match_operand: 0 "s_register_operand" "=w")
2900
        (unspec: [(match_operand:VCVTF 1 "s_register_operand" "w")
2901
                           (match_operand:SI 2 "immediate_operand" "i")
2902
                           (match_operand:SI 3 "immediate_operand" "i")]
2903
                          UNSPEC_VCVT_N))]
2904
  "TARGET_NEON"
2905
{
2906
  neon_const_bounds (operands[2], 1, 33);
2907
  return "vcvt.%T3%#32.f32\t%0, %1, %2";
2908
}
2909
  [(set (attr "neon_type")
2910
     (if_then_else (ne (symbol_ref "") (const_int 0))
2911
                   (const_string "neon_fp_vadd_ddd_vabs_dd")
2912
                   (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2913
)
2914
 
2915
(define_insn "neon_vcvt_n"
2916
  [(set (match_operand: 0 "s_register_operand" "=w")
2917
        (unspec: [(match_operand:VCVTI 1 "s_register_operand" "w")
2918
                           (match_operand:SI 2 "immediate_operand" "i")
2919
                           (match_operand:SI 3 "immediate_operand" "i")]
2920
                          UNSPEC_VCVT_N))]
2921
  "TARGET_NEON"
2922
{
2923
  neon_const_bounds (operands[2], 1, 33);
2924
  return "vcvt.f32.%T3%#32\t%0, %1, %2";
2925
}
2926
  [(set (attr "neon_type")
2927
     (if_then_else (ne (symbol_ref "") (const_int 0))
2928
                   (const_string "neon_fp_vadd_ddd_vabs_dd")
2929
                   (const_string "neon_fp_vadd_qqq_vabs_qq")))]
2930
)
2931
 
2932
(define_insn "neon_vmovn"
2933
  [(set (match_operand: 0 "s_register_operand" "=w")
2934
        (unspec: [(match_operand:VN 1 "s_register_operand" "w")
2935
                            (match_operand:SI 2 "immediate_operand" "i")]
2936
                           UNSPEC_VMOVN))]
2937
  "TARGET_NEON"
2938
  "vmovn.\t%P0, %q1"
2939
  [(set_attr "neon_type" "neon_bp_simple")]
2940
)
2941
 
2942
(define_insn "neon_vqmovn"
2943
  [(set (match_operand: 0 "s_register_operand" "=w")
2944
        (unspec: [(match_operand:VN 1 "s_register_operand" "w")
2945
                            (match_operand:SI 2 "immediate_operand" "i")]
2946
                           UNSPEC_VQMOVN))]
2947
  "TARGET_NEON"
2948
  "vqmovn.%T2%#\t%P0, %q1"
2949
  [(set_attr "neon_type" "neon_shift_2")]
2950
)
2951
 
2952
(define_insn "neon_vqmovun"
2953
  [(set (match_operand: 0 "s_register_operand" "=w")
2954
        (unspec: [(match_operand:VN 1 "s_register_operand" "w")
2955
                            (match_operand:SI 2 "immediate_operand" "i")]
2956
                           UNSPEC_VQMOVUN))]
2957
  "TARGET_NEON"
2958
  "vqmovun.\t%P0, %q1"
2959
  [(set_attr "neon_type" "neon_shift_2")]
2960
)
2961
 
2962
(define_insn "neon_vmovl"
2963
  [(set (match_operand: 0 "s_register_operand" "=w")
2964
        (unspec: [(match_operand:VW 1 "s_register_operand" "w")
2965
                           (match_operand:SI 2 "immediate_operand" "i")]
2966
                          UNSPEC_VMOVL))]
2967
  "TARGET_NEON"
2968
  "vmovl.%T2%#\t%q0, %P1"
2969
  [(set_attr "neon_type" "neon_shift_1")]
2970
)
2971
 
2972
(define_insn "neon_vmul_lane"
2973
  [(set (match_operand:VMD 0 "s_register_operand" "=w")
2974
        (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "w")
2975
                     (match_operand:VMD 2 "s_register_operand"
2976
                                        "")
2977
                     (match_operand:SI 3 "immediate_operand" "i")
2978
                     (match_operand:SI 4 "immediate_operand" "i")]
2979
                    UNSPEC_VMUL_LANE))]
2980
  "TARGET_NEON"
2981
{
2982
  neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (mode));
2983
  return "vmul.\t%P0, %P1, %P2[%c3]";
2984
}
2985
  [(set (attr "neon_type")
2986
     (if_then_else (ne (symbol_ref "") (const_int 0))
2987
                   (const_string "neon_fp_vmul_ddd")
2988
                   (if_then_else (ne (symbol_ref "") (const_int 0))
2989
                                 (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
2990
                                 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))))]
2991
)
2992
 
2993
(define_insn "neon_vmul_lane"
2994
  [(set (match_operand:VMQ 0 "s_register_operand" "=w")
2995
        (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "w")
2996
                     (match_operand: 2 "s_register_operand"
2997
                                             "")
2998
                     (match_operand:SI 3 "immediate_operand" "i")
2999
                     (match_operand:SI 4 "immediate_operand" "i")]
3000
                    UNSPEC_VMUL_LANE))]
3001
  "TARGET_NEON"
3002
{
3003
  neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (mode));
3004
  return "vmul.\t%q0, %q1, %P2[%c3]";
3005
}
3006
  [(set (attr "neon_type")
3007
     (if_then_else (ne (symbol_ref "") (const_int 0))
3008
                   (const_string "neon_fp_vmul_qqd")
3009
                   (if_then_else (ne (symbol_ref "") (const_int 0))
3010
                                 (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3011
                                 (const_string "neon_mul_qqd_32_scalar"))))]
3012
)
3013
 
3014
(define_insn "neon_vmull_lane"
3015
  [(set (match_operand: 0 "s_register_operand" "=w")
3016
        (unspec: [(match_operand:VMDI 1 "s_register_operand" "w")
3017
                           (match_operand:VMDI 2 "s_register_operand"
3018
                                               "")
3019
                           (match_operand:SI 3 "immediate_operand" "i")
3020
                           (match_operand:SI 4 "immediate_operand" "i")]
3021
                          UNSPEC_VMULL_LANE))]
3022
  "TARGET_NEON"
3023
{
3024
  neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (mode));
3025
  return "vmull.%T4%#\t%q0, %P1, %P2[%c3]";
3026
}
3027
  [(set (attr "neon_type")
3028
     (if_then_else (ne (symbol_ref "") (const_int 0))
3029
                   (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3030
                   (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3031
)
3032
 
3033
(define_insn "neon_vqdmull_lane"
3034
  [(set (match_operand: 0 "s_register_operand" "=w")
3035
        (unspec: [(match_operand:VMDI 1 "s_register_operand" "w")
3036
                           (match_operand:VMDI 2 "s_register_operand"
3037
                                               "")
3038
                           (match_operand:SI 3 "immediate_operand" "i")
3039
                           (match_operand:SI 4 "immediate_operand" "i")]
3040
                          UNSPEC_VQDMULL_LANE))]
3041
  "TARGET_NEON"
3042
{
3043
  neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (mode));
3044
  return "vqdmull.\t%q0, %P1, %P2[%c3]";
3045
}
3046
  [(set (attr "neon_type")
3047
     (if_then_else (ne (symbol_ref "") (const_int 0))
3048
                   (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3049
                   (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3050
)
3051
 
3052
(define_insn "neon_vqdmulh_lane"
3053
  [(set (match_operand:VMQI 0 "s_register_operand" "=w")
3054
        (unspec:VMQI [(match_operand:VMQI 1 "s_register_operand" "w")
3055
                      (match_operand: 2 "s_register_operand"
3056
                                              "")
3057
                      (match_operand:SI 3 "immediate_operand" "i")
3058
                      (match_operand:SI 4 "immediate_operand" "i")]
3059
                      UNSPEC_VQDMULH_LANE))]
3060
  "TARGET_NEON"
3061
{
3062
  neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (mode));
3063
  return "vq%O4dmulh.%T4%#\t%q0, %q1, %P2[%c3]";
3064
}
3065
  [(set (attr "neon_type")
3066
     (if_then_else (ne (symbol_ref "") (const_int 0))
3067
                   (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
3068
                   (const_string "neon_mul_qqd_32_scalar")))]
3069
)
3070
 
3071
(define_insn "neon_vqdmulh_lane"
3072
  [(set (match_operand:VMDI 0 "s_register_operand" "=w")
3073
        (unspec:VMDI [(match_operand:VMDI 1 "s_register_operand" "w")
3074
                      (match_operand:VMDI 2 "s_register_operand"
3075
                                          "")
3076
                      (match_operand:SI 3 "immediate_operand" "i")
3077
                      (match_operand:SI 4 "immediate_operand" "i")]
3078
                      UNSPEC_VQDMULH_LANE))]
3079
  "TARGET_NEON"
3080
{
3081
  neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (mode));
3082
  return "vq%O4dmulh.%T4%#\t%P0, %P1, %P2[%c3]";
3083
}
3084
  [(set (attr "neon_type")
3085
     (if_then_else (ne (symbol_ref "") (const_int 0))
3086
                   (const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
3087
                   (const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
3088
)
3089
 
3090
(define_insn "neon_vmla_lane"
3091
  [(set (match_operand:VMD 0 "s_register_operand" "=w")
3092
        (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3093
                     (match_operand:VMD 2 "s_register_operand" "w")
3094
                     (match_operand:VMD 3 "s_register_operand"
3095
                                        "")
3096
                     (match_operand:SI 4 "immediate_operand" "i")
3097
                     (match_operand:SI 5 "immediate_operand" "i")]
3098
                     UNSPEC_VMLA_LANE))]
3099
  "TARGET_NEON"
3100
{
3101
  neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (mode));
3102
  return "vmla.\t%P0, %P2, %P3[%c4]";
3103
}
3104
  [(set (attr "neon_type")
3105
     (if_then_else (ne (symbol_ref "") (const_int 0))
3106
                   (const_string "neon_fp_vmla_ddd_scalar")
3107
                   (if_then_else (ne (symbol_ref "") (const_int 0))
3108
                                 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3109
                                 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3110
)
3111
 
3112
(define_insn "neon_vmla_lane"
3113
  [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3114
        (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3115
                     (match_operand:VMQ 2 "s_register_operand" "w")
3116
                     (match_operand: 3 "s_register_operand"
3117
                                             "")
3118
                     (match_operand:SI 4 "immediate_operand" "i")
3119
                     (match_operand:SI 5 "immediate_operand" "i")]
3120
                     UNSPEC_VMLA_LANE))]
3121
  "TARGET_NEON"
3122
{
3123
  neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (mode));
3124
  return "vmla.\t%q0, %q2, %P3[%c4]";
3125
}
3126
  [(set (attr "neon_type")
3127
     (if_then_else (ne (symbol_ref "") (const_int 0))
3128
                   (const_string "neon_fp_vmla_qqq_scalar")
3129
                   (if_then_else (ne (symbol_ref "") (const_int 0))
3130
                                 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3131
                                 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3132
)
3133
 
3134
(define_insn "neon_vmlal_lane"
3135
  [(set (match_operand: 0 "s_register_operand" "=w")
3136
        (unspec: [(match_operand: 1 "s_register_operand" "0")
3137
                           (match_operand:VMDI 2 "s_register_operand" "w")
3138
                           (match_operand:VMDI 3 "s_register_operand"
3139
                                               "")
3140
                           (match_operand:SI 4 "immediate_operand" "i")
3141
                           (match_operand:SI 5 "immediate_operand" "i")]
3142
                          UNSPEC_VMLAL_LANE))]
3143
  "TARGET_NEON"
3144
{
3145
  neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (mode));
3146
  return "vmlal.%T5%#\t%q0, %P2, %P3[%c4]";
3147
}
3148
  [(set (attr "neon_type")
3149
     (if_then_else (ne (symbol_ref "") (const_int 0))
3150
                   (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3151
                   (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3152
)
3153
 
3154
(define_insn "neon_vqdmlal_lane"
3155
  [(set (match_operand: 0 "s_register_operand" "=w")
3156
        (unspec: [(match_operand: 1 "s_register_operand" "0")
3157
                           (match_operand:VMDI 2 "s_register_operand" "w")
3158
                           (match_operand:VMDI 3 "s_register_operand"
3159
                                               "")
3160
                           (match_operand:SI 4 "immediate_operand" "i")
3161
                           (match_operand:SI 5 "immediate_operand" "i")]
3162
                          UNSPEC_VQDMLAL_LANE))]
3163
  "TARGET_NEON"
3164
{
3165
  neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (mode));
3166
  return "vqdmlal.\t%q0, %P2, %P3[%c4]";
3167
}
3168
  [(set (attr "neon_type")
3169
     (if_then_else (ne (symbol_ref "") (const_int 0))
3170
                   (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3171
                   (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3172
)
3173
 
3174
(define_insn "neon_vmls_lane"
3175
  [(set (match_operand:VMD 0 "s_register_operand" "=w")
3176
        (unspec:VMD [(match_operand:VMD 1 "s_register_operand" "0")
3177
                     (match_operand:VMD 2 "s_register_operand" "w")
3178
                     (match_operand:VMD 3 "s_register_operand"
3179
                                        "")
3180
                     (match_operand:SI 4 "immediate_operand" "i")
3181
                     (match_operand:SI 5 "immediate_operand" "i")]
3182
                    UNSPEC_VMLS_LANE))]
3183
  "TARGET_NEON"
3184
{
3185
  neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (mode));
3186
  return "vmls.\t%P0, %P2, %P3[%c4]";
3187
}
3188
  [(set (attr "neon_type")
3189
     (if_then_else (ne (symbol_ref "") (const_int 0))
3190
                   (const_string "neon_fp_vmla_ddd_scalar")
3191
                   (if_then_else (ne (symbol_ref "") (const_int 0))
3192
                                 (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3193
                                 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))))]
3194
)
3195
 
3196
(define_insn "neon_vmls_lane"
3197
  [(set (match_operand:VMQ 0 "s_register_operand" "=w")
3198
        (unspec:VMQ [(match_operand:VMQ 1 "s_register_operand" "0")
3199
                     (match_operand:VMQ 2 "s_register_operand" "w")
3200
                     (match_operand: 3 "s_register_operand"
3201
                                             "")
3202
                     (match_operand:SI 4 "immediate_operand" "i")
3203
                     (match_operand:SI 5 "immediate_operand" "i")]
3204
                    UNSPEC_VMLS_LANE))]
3205
  "TARGET_NEON"
3206
{
3207
  neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (mode));
3208
  return "vmls.\t%q0, %q2, %P3[%c4]";
3209
}
3210
  [(set (attr "neon_type")
3211
     (if_then_else (ne (symbol_ref "") (const_int 0))
3212
                   (const_string "neon_fp_vmla_qqq_scalar")
3213
                   (if_then_else (ne (symbol_ref "") (const_int 0))
3214
                                 (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")
3215
                                 (const_string "neon_mla_qqq_32_qqd_32_scalar"))))]
3216
)
3217
 
3218
(define_insn "neon_vmlsl_lane"
3219
  [(set (match_operand: 0 "s_register_operand" "=w")
3220
        (unspec: [(match_operand: 1 "s_register_operand" "0")
3221
                           (match_operand:VMDI 2 "s_register_operand" "w")
3222
                           (match_operand:VMDI 3 "s_register_operand"
3223
                                               "")
3224
                           (match_operand:SI 4 "immediate_operand" "i")
3225
                           (match_operand:SI 5 "immediate_operand" "i")]
3226
                          UNSPEC_VMLSL_LANE))]
3227
  "TARGET_NEON"
3228
{
3229
  neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (mode));
3230
  return "vmlsl.%T5%#\t%q0, %P2, %P3[%c4]";
3231
}
3232
  [(set (attr "neon_type")
3233
     (if_then_else (ne (symbol_ref "") (const_int 0))
3234
                   (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3235
                   (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3236
)
3237
 
3238
(define_insn "neon_vqdmlsl_lane"
3239
  [(set (match_operand: 0 "s_register_operand" "=w")
3240
        (unspec: [(match_operand: 1 "s_register_operand" "0")
3241
                           (match_operand:VMDI 2 "s_register_operand" "w")
3242
                           (match_operand:VMDI 3 "s_register_operand"
3243
                                               "")
3244
                           (match_operand:SI 4 "immediate_operand" "i")
3245
                           (match_operand:SI 5 "immediate_operand" "i")]
3246
                          UNSPEC_VQDMLSL_LANE))]
3247
  "TARGET_NEON"
3248
{
3249
  neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (mode));
3250
  return "vqdmlsl.\t%q0, %P2, %P3[%c4]";
3251
}
3252
  [(set (attr "neon_type")
3253
     (if_then_else (ne (symbol_ref "") (const_int 0))
3254
                   (const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
3255
                   (const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
3256
)
3257
 
3258
; FIXME: For the "_n" multiply/multiply-accumulate insns, we copy a value in a
3259
; core register into a temp register, then use a scalar taken from that. This
3260
; isn't an optimal solution if e.g. the scalar has just been read from memory
3261
; or extracted from another vector. The latter case it's currently better to
3262
; use the "_lane" variant, and the former case can probably be implemented
3263
; using vld1_lane, but that hasn't been done yet.
3264
 
3265
(define_expand "neon_vmul_n"
3266
  [(match_operand:VMD 0 "s_register_operand" "")
3267
   (match_operand:VMD 1 "s_register_operand" "")
3268
   (match_operand: 2 "s_register_operand" "")
3269
   (match_operand:SI 3 "immediate_operand" "")]
3270
  "TARGET_NEON"
3271
{
3272
  rtx tmp = gen_reg_rtx (mode);
3273
  emit_insn (gen_neon_vset_lane (tmp, operands[2], tmp, const0_rtx));
3274
  emit_insn (gen_neon_vmul_lane (operands[0], operands[1], tmp,
3275
                                       const0_rtx, const0_rtx));
3276
  DONE;
3277
})
3278
 
3279
(define_expand "neon_vmul_n"
3280
  [(match_operand:VMQ 0 "s_register_operand" "")
3281
   (match_operand:VMQ 1 "s_register_operand" "")
3282
   (match_operand: 2 "s_register_operand" "")
3283
   (match_operand:SI 3 "immediate_operand" "")]
3284
  "TARGET_NEON"
3285
{
3286
  rtx tmp = gen_reg_rtx (mode);
3287
  emit_insn (gen_neon_vset_lane (tmp, operands[2], tmp, const0_rtx));
3288
  emit_insn (gen_neon_vmul_lane (operands[0], operands[1], tmp,
3289
                                       const0_rtx, const0_rtx));
3290
  DONE;
3291
})
3292
 
3293
(define_expand "neon_vmull_n"
3294
  [(match_operand: 0 "s_register_operand" "")
3295
   (match_operand:VMDI 1 "s_register_operand" "")
3296
   (match_operand: 2 "s_register_operand" "")
3297
   (match_operand:SI 3 "immediate_operand" "")]
3298
  "TARGET_NEON"
3299
{
3300
  rtx tmp = gen_reg_rtx (mode);
3301
  emit_insn (gen_neon_vset_lane (tmp, operands[2], tmp, const0_rtx));
3302
  emit_insn (gen_neon_vmull_lane (operands[0], operands[1], tmp,
3303
                                        const0_rtx, operands[3]));
3304
  DONE;
3305
})
3306
 
3307
(define_expand "neon_vqdmull_n"
3308
  [(match_operand: 0 "s_register_operand" "")
3309
   (match_operand:VMDI 1 "s_register_operand" "")
3310
   (match_operand: 2 "s_register_operand" "")
3311
   (match_operand:SI 3 "immediate_operand" "")]
3312
  "TARGET_NEON"
3313
{
3314
  rtx tmp = gen_reg_rtx (mode);
3315
  emit_insn (gen_neon_vset_lane (tmp, operands[2], tmp, const0_rtx));
3316
  emit_insn (gen_neon_vqdmull_lane (operands[0], operands[1], tmp,
3317
                                          const0_rtx, const0_rtx));
3318
  DONE;
3319
})
3320
 
3321
(define_expand "neon_vqdmulh_n"
3322
  [(match_operand:VMDI 0 "s_register_operand" "")
3323
   (match_operand:VMDI 1 "s_register_operand" "")
3324
   (match_operand: 2 "s_register_operand" "")
3325
   (match_operand:SI 3 "immediate_operand" "")]
3326
  "TARGET_NEON"
3327
{
3328
  rtx tmp = gen_reg_rtx (mode);
3329
  emit_insn (gen_neon_vset_lane (tmp, operands[2], tmp, const0_rtx));
3330
  emit_insn (gen_neon_vqdmulh_lane (operands[0], operands[1], tmp,
3331
                                          const0_rtx, operands[3]));
3332
  DONE;
3333
})
3334
 
3335
(define_expand "neon_vqdmulh_n"
3336
  [(match_operand:VMQI 0 "s_register_operand" "")
3337
   (match_operand:VMQI 1 "s_register_operand" "")
3338
   (match_operand: 2 "s_register_operand" "")
3339
   (match_operand:SI 3 "immediate_operand" "")]
3340
  "TARGET_NEON"
3341
{
3342
  rtx tmp = gen_reg_rtx (mode);
3343
  emit_insn (gen_neon_vset_lane (tmp, operands[2], tmp, const0_rtx));
3344
  emit_insn (gen_neon_vqdmulh_lane (operands[0], operands[1], tmp,
3345
                                          const0_rtx, operands[3]));
3346
  DONE;
3347
})
3348
 
3349
(define_expand "neon_vmla_n"
3350
  [(match_operand:VMD 0 "s_register_operand" "")
3351
   (match_operand:VMD 1 "s_register_operand" "")
3352
   (match_operand:VMD 2 "s_register_operand" "")
3353
   (match_operand: 3 "s_register_operand" "")
3354
   (match_operand:SI 4 "immediate_operand" "")]
3355
  "TARGET_NEON"
3356
{
3357
  rtx tmp = gen_reg_rtx (mode);
3358
  emit_insn (gen_neon_vset_lane (tmp, operands[3], tmp, const0_rtx));
3359
  emit_insn (gen_neon_vmla_lane (operands[0], operands[1], operands[2],
3360
                                       tmp, const0_rtx, operands[4]));
3361
  DONE;
3362
})
3363
 
3364
(define_expand "neon_vmla_n"
3365
  [(match_operand:VMQ 0 "s_register_operand" "")
3366
   (match_operand:VMQ 1 "s_register_operand" "")
3367
   (match_operand:VMQ 2 "s_register_operand" "")
3368
   (match_operand: 3 "s_register_operand" "")
3369
   (match_operand:SI 4 "immediate_operand" "")]
3370
  "TARGET_NEON"
3371
{
3372
  rtx tmp = gen_reg_rtx (mode);
3373
  emit_insn (gen_neon_vset_lane (tmp, operands[3], tmp, const0_rtx));
3374
  emit_insn (gen_neon_vmla_lane (operands[0], operands[1], operands[2],
3375
                                       tmp, const0_rtx, operands[4]));
3376
  DONE;
3377
})
3378
 
3379
(define_expand "neon_vmlal_n"
3380
  [(match_operand: 0 "s_register_operand" "")
3381
   (match_operand: 1 "s_register_operand" "")
3382
   (match_operand:VMDI 2 "s_register_operand" "")
3383
   (match_operand: 3 "s_register_operand" "")
3384
   (match_operand:SI 4 "immediate_operand" "")]
3385
  "TARGET_NEON"
3386
{
3387
  rtx tmp = gen_reg_rtx (mode);
3388
  emit_insn (gen_neon_vset_lane (tmp, operands[3], tmp, const0_rtx));
3389
  emit_insn (gen_neon_vmlal_lane (operands[0], operands[1], operands[2],
3390
                                        tmp, const0_rtx, operands[4]));
3391
  DONE;
3392
})
3393
 
3394
(define_expand "neon_vqdmlal_n"
3395
  [(match_operand: 0 "s_register_operand" "")
3396
   (match_operand: 1 "s_register_operand" "")
3397
   (match_operand:VMDI 2 "s_register_operand" "")
3398
   (match_operand: 3 "s_register_operand" "")
3399
   (match_operand:SI 4 "immediate_operand" "")]
3400
  "TARGET_NEON"
3401
{
3402
  rtx tmp = gen_reg_rtx (mode);
3403
  emit_insn (gen_neon_vset_lane (tmp, operands[3], tmp, const0_rtx));
3404
  emit_insn (gen_neon_vqdmlal_lane (operands[0], operands[1], operands[2],
3405
                                          tmp, const0_rtx, operands[4]));
3406
  DONE;
3407
})
3408
 
3409
(define_expand "neon_vmls_n"
3410
  [(match_operand:VMD 0 "s_register_operand" "")
3411
   (match_operand:VMD 1 "s_register_operand" "")
3412
   (match_operand:VMD 2 "s_register_operand" "")
3413
   (match_operand: 3 "s_register_operand" "")
3414
   (match_operand:SI 4 "immediate_operand" "")]
3415
  "TARGET_NEON"
3416
{
3417
  rtx tmp = gen_reg_rtx (mode);
3418
  emit_insn (gen_neon_vset_lane (tmp, operands[3], tmp, const0_rtx));
3419
  emit_insn (gen_neon_vmls_lane (operands[0], operands[1], operands[2],
3420
                                       tmp, const0_rtx, operands[4]));
3421
  DONE;
3422
})
3423
 
3424
(define_expand "neon_vmls_n"
3425
  [(match_operand:VMQ 0 "s_register_operand" "")
3426
   (match_operand:VMQ 1 "s_register_operand" "")
3427
   (match_operand:VMQ 2 "s_register_operand" "")
3428
   (match_operand: 3 "s_register_operand" "")
3429
   (match_operand:SI 4 "immediate_operand" "")]
3430
  "TARGET_NEON"
3431
{
3432
  rtx tmp = gen_reg_rtx (mode);
3433
  emit_insn (gen_neon_vset_lane (tmp, operands[3], tmp, const0_rtx));
3434
  emit_insn (gen_neon_vmls_lane (operands[0], operands[1], operands[2],
3435
                                       tmp, const0_rtx, operands[4]));
3436
  DONE;
3437
})
3438
 
3439
(define_expand "neon_vmlsl_n"
3440
  [(match_operand: 0 "s_register_operand" "")
3441
   (match_operand: 1 "s_register_operand" "")
3442
   (match_operand:VMDI 2 "s_register_operand" "")
3443
   (match_operand: 3 "s_register_operand" "")
3444
   (match_operand:SI 4 "immediate_operand" "")]
3445
  "TARGET_NEON"
3446
{
3447
  rtx tmp = gen_reg_rtx (mode);
3448
  emit_insn (gen_neon_vset_lane (tmp, operands[3], tmp, const0_rtx));
3449
  emit_insn (gen_neon_vmlsl_lane (operands[0], operands[1], operands[2],
3450
                                        tmp, const0_rtx, operands[4]));
3451
  DONE;
3452
})
3453
 
3454
(define_expand "neon_vqdmlsl_n"
3455
  [(match_operand: 0 "s_register_operand" "")
3456
   (match_operand: 1 "s_register_operand" "")
3457
   (match_operand:VMDI 2 "s_register_operand" "")
3458
   (match_operand: 3 "s_register_operand" "")
3459
   (match_operand:SI 4 "immediate_operand" "")]
3460
  "TARGET_NEON"
3461
{
3462
  rtx tmp = gen_reg_rtx (mode);
3463
  emit_insn (gen_neon_vset_lane (tmp, operands[3], tmp, const0_rtx));
3464
  emit_insn (gen_neon_vqdmlsl_lane (operands[0], operands[1], operands[2],
3465
                                          tmp, const0_rtx, operands[4]));
3466
  DONE;
3467
})
3468
 
3469
(define_insn "neon_vext"
3470
  [(set (match_operand:VDQX 0 "s_register_operand" "=w")
3471
        (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")
3472
                      (match_operand:VDQX 2 "s_register_operand" "w")
3473
                      (match_operand:SI 3 "immediate_operand" "i")]
3474
                     UNSPEC_VEXT))]
3475
  "TARGET_NEON"
3476
{
3477
  neon_const_bounds (operands[3], 0, GET_MODE_NUNITS (mode));
3478
  return "vext.\t%0, %1, %2, %3";
3479
}
3480
  [(set (attr "neon_type")
3481
      (if_then_else (ne (symbol_ref "") (const_int 0))
3482
                    (const_string "neon_bp_simple")
3483
                    (const_string "neon_bp_2cycle")))]
3484
)
3485
 
3486
(define_insn "neon_vrev64"
3487
  [(set (match_operand:VDQ 0 "s_register_operand" "=w")
3488
        (unspec:VDQ [(match_operand:VDQ 1 "s_register_operand" "w")
3489
                     (match_operand:SI 2 "immediate_operand" "i")]
3490
                    UNSPEC_VREV64))]
3491
  "TARGET_NEON"
3492
  "vrev64.\t%0, %1"
3493
  [(set_attr "neon_type" "neon_bp_simple")]
3494
)
3495
 
3496
(define_insn "neon_vrev32"
3497
  [(set (match_operand:VX 0 "s_register_operand" "=w")
3498
        (unspec:VX [(match_operand:VX 1 "s_register_operand" "w")
3499
                    (match_operand:SI 2 "immediate_operand" "i")]
3500
                   UNSPEC_VREV32))]
3501
  "TARGET_NEON"
3502
  "vrev32.\t%0, %1"
3503
  [(set_attr "neon_type" "neon_bp_simple")]
3504
)
3505
 
3506
(define_insn "neon_vrev16"
3507
  [(set (match_operand:VE 0 "s_register_operand" "=w")
3508
        (unspec:VE [(match_operand:VE 1 "s_register_operand" "w")
3509
                    (match_operand:SI 2 "immediate_operand" "i")]
3510
                   UNSPEC_VREV16))]
3511
  "TARGET_NEON"
3512
  "vrev16.\t%0, %1"
3513
  [(set_attr "neon_type" "neon_bp_simple")]
3514
)
3515
 
3516
; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
3517
; allocation. For an intrinsic of form:
3518
;   rD = vbsl_* (rS, rN, rM)
3519
; We can use any of:
3520
;   vbsl rS, rN, rM  (if D = S)
3521
;   vbit rD, rN, rS  (if D = M, so 1-bits in rS choose bits from rN, else rM)
3522
;   vbif rD, rM, rS  (if D = N, so 0-bits in rS choose bits from rM, else rN)
3523
 
3524
(define_insn "neon_vbsl_internal"
3525
  [(set (match_operand:VDQX 0 "s_register_operand"               "=w,w,w")
3526
        (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" " 0,w,w")
3527
                      (match_operand:VDQX 2 "s_register_operand" " w,w,0")
3528
                      (match_operand:VDQX 3 "s_register_operand" " w,0,w")]
3529
                     UNSPEC_VBSL))]
3530
  "TARGET_NEON"
3531
  "@
3532
  vbsl\t%0, %2, %3
3533
  vbit\t%0, %2, %1
3534
  vbif\t%0, %3, %1"
3535
  [(set_attr "neon_type" "neon_int_1")]
3536
)
3537
 
3538
(define_expand "neon_vbsl"
3539
  [(set (match_operand:VDQX 0 "s_register_operand" "")
3540
        (unspec:VDQX [(match_operand: 1 "s_register_operand" "")
3541
                      (match_operand:VDQX 2 "s_register_operand" "")
3542
                      (match_operand:VDQX 3 "s_register_operand" "")]
3543
                     UNSPEC_VBSL))]
3544
  "TARGET_NEON"
3545
{
3546
  /* We can't alias operands together if they have different modes.  */
3547
  operands[1] = gen_lowpart (mode, operands[1]);
3548
})
3549
 
3550
(define_insn "neon_vshl"
3551
  [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3552
        (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3553
                       (match_operand:VDQIX 2 "s_register_operand" "w")
3554
                       (match_operand:SI 3 "immediate_operand" "i")]
3555
                      UNSPEC_VSHL))]
3556
  "TARGET_NEON"
3557
  "v%O3shl.%T3%#\t%0, %1, %2"
3558
  [(set (attr "neon_type")
3559
      (if_then_else (ne (symbol_ref "") (const_int 0))
3560
                    (const_string "neon_vshl_ddd")
3561
                    (const_string "neon_shift_3")))]
3562
)
3563
 
3564
(define_insn "neon_vqshl"
3565
  [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3566
        (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3567
                       (match_operand:VDQIX 2 "s_register_operand" "w")
3568
                       (match_operand:SI 3 "immediate_operand" "i")]
3569
                      UNSPEC_VQSHL))]
3570
  "TARGET_NEON"
3571
  "vq%O3shl.%T3%#\t%0, %1, %2"
3572
  [(set (attr "neon_type")
3573
      (if_then_else (ne (symbol_ref "") (const_int 0))
3574
                    (const_string "neon_shift_2")
3575
                    (const_string "neon_vqshl_vrshl_vqrshl_qqq")))]
3576
)
3577
 
3578
(define_insn "neon_vshr_n"
3579
  [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3580
        (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3581
                       (match_operand:SI 2 "immediate_operand" "i")
3582
                       (match_operand:SI 3 "immediate_operand" "i")]
3583
                      UNSPEC_VSHR_N))]
3584
  "TARGET_NEON"
3585
{
3586
  neon_const_bounds (operands[2], 1, neon_element_bits (mode) + 1);
3587
  return "v%O3shr.%T3%#\t%0, %1, %2";
3588
}
3589
  [(set_attr "neon_type" "neon_shift_1")]
3590
)
3591
 
3592
(define_insn "neon_vshrn_n"
3593
  [(set (match_operand: 0 "s_register_operand" "=w")
3594
        (unspec: [(match_operand:VN 1 "s_register_operand" "w")
3595
                            (match_operand:SI 2 "immediate_operand" "i")
3596
                            (match_operand:SI 3 "immediate_operand" "i")]
3597
                           UNSPEC_VSHRN_N))]
3598
  "TARGET_NEON"
3599
{
3600
  neon_const_bounds (operands[2], 1, neon_element_bits (mode) / 2 + 1);
3601
  return "v%O3shrn.\t%P0, %q1, %2";
3602
}
3603
  [(set_attr "neon_type" "neon_shift_1")]
3604
)
3605
 
3606
(define_insn "neon_vqshrn_n"
3607
  [(set (match_operand: 0 "s_register_operand" "=w")
3608
        (unspec: [(match_operand:VN 1 "s_register_operand" "w")
3609
                            (match_operand:SI 2 "immediate_operand" "i")
3610
                            (match_operand:SI 3 "immediate_operand" "i")]
3611
                           UNSPEC_VQSHRN_N))]
3612
  "TARGET_NEON"
3613
{
3614
  neon_const_bounds (operands[2], 1, neon_element_bits (mode) / 2 + 1);
3615
  return "vq%O3shrn.%T3%#\t%P0, %q1, %2";
3616
}
3617
  [(set_attr "neon_type" "neon_shift_2")]
3618
)
3619
 
3620
(define_insn "neon_vqshrun_n"
3621
  [(set (match_operand: 0 "s_register_operand" "=w")
3622
        (unspec: [(match_operand:VN 1 "s_register_operand" "w")
3623
                            (match_operand:SI 2 "immediate_operand" "i")
3624
                            (match_operand:SI 3 "immediate_operand" "i")]
3625
                           UNSPEC_VQSHRUN_N))]
3626
  "TARGET_NEON"
3627
{
3628
  neon_const_bounds (operands[2], 1, neon_element_bits (mode) / 2 + 1);
3629
  return "vq%O3shrun.%T3%#\t%P0, %q1, %2";
3630
}
3631
  [(set_attr "neon_type" "neon_shift_2")]
3632
)
3633
 
3634
(define_insn "neon_vshl_n"
3635
  [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3636
        (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3637
                       (match_operand:SI 2 "immediate_operand" "i")
3638
                       (match_operand:SI 3 "immediate_operand" "i")]
3639
                      UNSPEC_VSHL_N))]
3640
  "TARGET_NEON"
3641
{
3642
  neon_const_bounds (operands[2], 0, neon_element_bits (mode));
3643
  return "vshl.\t%0, %1, %2";
3644
}
3645
  [(set_attr "neon_type" "neon_shift_1")]
3646
)
3647
 
3648
(define_insn "neon_vqshl_n"
3649
  [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3650
        (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3651
                       (match_operand:SI 2 "immediate_operand" "i")
3652
                       (match_operand:SI 3 "immediate_operand" "i")]
3653
                      UNSPEC_VQSHL_N))]
3654
  "TARGET_NEON"
3655
{
3656
  neon_const_bounds (operands[2], 0, neon_element_bits (mode));
3657
  return "vqshl.%T3%#\t%0, %1, %2";
3658
}
3659
  [(set_attr "neon_type" "neon_shift_2")]
3660
)
3661
 
3662
(define_insn "neon_vqshlu_n"
3663
  [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3664
        (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "w")
3665
                       (match_operand:SI 2 "immediate_operand" "i")
3666
                       (match_operand:SI 3 "immediate_operand" "i")]
3667
                      UNSPEC_VQSHLU_N))]
3668
  "TARGET_NEON"
3669
{
3670
  neon_const_bounds (operands[2], 0, neon_element_bits (mode));
3671
  return "vqshlu.%T3%#\t%0, %1, %2";
3672
}
3673
  [(set_attr "neon_type" "neon_shift_2")]
3674
)
3675
 
3676
(define_insn "neon_vshll_n"
3677
  [(set (match_operand: 0 "s_register_operand" "=w")
3678
        (unspec: [(match_operand:VW 1 "s_register_operand" "w")
3679
                           (match_operand:SI 2 "immediate_operand" "i")
3680
                           (match_operand:SI 3 "immediate_operand" "i")]
3681
                          UNSPEC_VSHLL_N))]
3682
  "TARGET_NEON"
3683
{
3684
  /* The boundaries are: 0 < imm <= size.  */
3685
  neon_const_bounds (operands[2], 0, neon_element_bits (mode) + 1);
3686
  return "vshll.%T3%#\t%q0, %P1, %2";
3687
}
3688
  [(set_attr "neon_type" "neon_shift_1")]
3689
)
3690
 
3691
(define_insn "neon_vsra_n"
3692
  [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3693
        (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3694
                       (match_operand:VDQIX 2 "s_register_operand" "w")
3695
                       (match_operand:SI 3 "immediate_operand" "i")
3696
                       (match_operand:SI 4 "immediate_operand" "i")]
3697
                      UNSPEC_VSRA_N))]
3698
  "TARGET_NEON"
3699
{
3700
  neon_const_bounds (operands[3], 1, neon_element_bits (mode) + 1);
3701
  return "v%O4sra.%T4%#\t%0, %2, %3";
3702
}
3703
  [(set_attr "neon_type" "neon_vsra_vrsra")]
3704
)
3705
 
3706
(define_insn "neon_vsri_n"
3707
  [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3708
        (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3709
                       (match_operand:VDQIX 2 "s_register_operand" "w")
3710
                       (match_operand:SI 3 "immediate_operand" "i")]
3711
                      UNSPEC_VSRI))]
3712
  "TARGET_NEON"
3713
{
3714
  neon_const_bounds (operands[3], 1, neon_element_bits (mode) + 1);
3715
  return "vsri.\t%0, %2, %3";
3716
}
3717
  [(set (attr "neon_type")
3718
      (if_then_else (ne (symbol_ref "") (const_int 0))
3719
                    (const_string "neon_shift_1")
3720
                    (const_string "neon_shift_3")))]
3721
)
3722
 
3723
(define_insn "neon_vsli_n"
3724
  [(set (match_operand:VDQIX 0 "s_register_operand" "=w")
3725
        (unspec:VDQIX [(match_operand:VDQIX 1 "s_register_operand" "0")
3726
                       (match_operand:VDQIX 2 "s_register_operand" "w")
3727
                       (match_operand:SI 3 "immediate_operand" "i")]
3728
                      UNSPEC_VSLI))]
3729
  "TARGET_NEON"
3730
{
3731
  neon_const_bounds (operands[3], 0, neon_element_bits (mode));
3732
  return "vsli.\t%0, %2, %3";
3733
}
3734
  [(set (attr "neon_type")
3735
      (if_then_else (ne (symbol_ref "") (const_int 0))
3736
                    (const_string "neon_shift_1")
3737
                    (const_string "neon_shift_3")))]
3738
)
3739
 
3740
(define_insn "neon_vtbl1v8qi"
3741
  [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3742
        (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "w")
3743
                      (match_operand:V8QI 2 "s_register_operand" "w")]
3744
                     UNSPEC_VTBL))]
3745
  "TARGET_NEON"
3746
  "vtbl.8\t%P0, {%P1}, %P2"
3747
  [(set_attr "neon_type" "neon_bp_2cycle")]
3748
)
3749
 
3750
(define_insn "neon_vtbl2v8qi"
3751
  [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3752
        (unspec:V8QI [(match_operand:TI 1 "s_register_operand" "w")
3753
                      (match_operand:V8QI 2 "s_register_operand" "w")]
3754
                     UNSPEC_VTBL))]
3755
  "TARGET_NEON"
3756
{
3757
  rtx ops[4];
3758
  int tabbase = REGNO (operands[1]);
3759
 
3760
  ops[0] = operands[0];
3761
  ops[1] = gen_rtx_REG (V8QImode, tabbase);
3762
  ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3763
  ops[3] = operands[2];
3764
  output_asm_insn ("vtbl.8\t%P0, {%P1, %P2}, %P3", ops);
3765
 
3766
  return "";
3767
}
3768
  [(set_attr "neon_type" "neon_bp_2cycle")]
3769
)
3770
 
3771
(define_insn "neon_vtbl3v8qi"
3772
  [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3773
        (unspec:V8QI [(match_operand:EI 1 "s_register_operand" "w")
3774
                      (match_operand:V8QI 2 "s_register_operand" "w")]
3775
                     UNSPEC_VTBL))]
3776
  "TARGET_NEON"
3777
{
3778
  rtx ops[5];
3779
  int tabbase = REGNO (operands[1]);
3780
 
3781
  ops[0] = operands[0];
3782
  ops[1] = gen_rtx_REG (V8QImode, tabbase);
3783
  ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3784
  ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3785
  ops[4] = operands[2];
3786
  output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
3787
 
3788
  return "";
3789
}
3790
  [(set_attr "neon_type" "neon_bp_3cycle")]
3791
)
3792
 
3793
(define_insn "neon_vtbl4v8qi"
3794
  [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3795
        (unspec:V8QI [(match_operand:OI 1 "s_register_operand" "w")
3796
                      (match_operand:V8QI 2 "s_register_operand" "w")]
3797
                     UNSPEC_VTBL))]
3798
  "TARGET_NEON"
3799
{
3800
  rtx ops[6];
3801
  int tabbase = REGNO (operands[1]);
3802
 
3803
  ops[0] = operands[0];
3804
  ops[1] = gen_rtx_REG (V8QImode, tabbase);
3805
  ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3806
  ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3807
  ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
3808
  ops[5] = operands[2];
3809
  output_asm_insn ("vtbl.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
3810
 
3811
  return "";
3812
}
3813
  [(set_attr "neon_type" "neon_bp_3cycle")]
3814
)
3815
 
3816
(define_insn "neon_vtbx1v8qi"
3817
  [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3818
        (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
3819
                      (match_operand:V8QI 2 "s_register_operand" "w")
3820
                      (match_operand:V8QI 3 "s_register_operand" "w")]
3821
                     UNSPEC_VTBX))]
3822
  "TARGET_NEON"
3823
  "vtbx.8\t%P0, {%P2}, %P3"
3824
  [(set_attr "neon_type" "neon_bp_2cycle")]
3825
)
3826
 
3827
(define_insn "neon_vtbx2v8qi"
3828
  [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3829
        (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
3830
                      (match_operand:TI 2 "s_register_operand" "w")
3831
                      (match_operand:V8QI 3 "s_register_operand" "w")]
3832
                     UNSPEC_VTBX))]
3833
  "TARGET_NEON"
3834
{
3835
  rtx ops[4];
3836
  int tabbase = REGNO (operands[2]);
3837
 
3838
  ops[0] = operands[0];
3839
  ops[1] = gen_rtx_REG (V8QImode, tabbase);
3840
  ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3841
  ops[3] = operands[3];
3842
  output_asm_insn ("vtbx.8\t%P0, {%P1, %P2}, %P3", ops);
3843
 
3844
  return "";
3845
}
3846
  [(set_attr "neon_type" "neon_bp_2cycle")]
3847
)
3848
 
3849
(define_insn "neon_vtbx3v8qi"
3850
  [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3851
        (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
3852
                      (match_operand:EI 2 "s_register_operand" "w")
3853
                      (match_operand:V8QI 3 "s_register_operand" "w")]
3854
                     UNSPEC_VTBX))]
3855
  "TARGET_NEON"
3856
{
3857
  rtx ops[5];
3858
  int tabbase = REGNO (operands[2]);
3859
 
3860
  ops[0] = operands[0];
3861
  ops[1] = gen_rtx_REG (V8QImode, tabbase);
3862
  ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3863
  ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3864
  ops[4] = operands[3];
3865
  output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3}, %P4", ops);
3866
 
3867
  return "";
3868
}
3869
  [(set_attr "neon_type" "neon_bp_3cycle")]
3870
)
3871
 
3872
(define_insn "neon_vtbx4v8qi"
3873
  [(set (match_operand:V8QI 0 "s_register_operand" "=w")
3874
        (unspec:V8QI [(match_operand:V8QI 1 "s_register_operand" "0")
3875
                      (match_operand:OI 2 "s_register_operand" "w")
3876
                      (match_operand:V8QI 3 "s_register_operand" "w")]
3877
                     UNSPEC_VTBX))]
3878
  "TARGET_NEON"
3879
{
3880
  rtx ops[6];
3881
  int tabbase = REGNO (operands[2]);
3882
 
3883
  ops[0] = operands[0];
3884
  ops[1] = gen_rtx_REG (V8QImode, tabbase);
3885
  ops[2] = gen_rtx_REG (V8QImode, tabbase + 2);
3886
  ops[3] = gen_rtx_REG (V8QImode, tabbase + 4);
3887
  ops[4] = gen_rtx_REG (V8QImode, tabbase + 6);
3888
  ops[5] = operands[3];
3889
  output_asm_insn ("vtbx.8\t%P0, {%P1, %P2, %P3, %P4}, %P5", ops);
3890
 
3891
  return "";
3892
}
3893
  [(set_attr "neon_type" "neon_bp_3cycle")]
3894
)
3895
 
3896
(define_insn "neon_vtrn_internal"
3897
  [(set (match_operand:VDQW 0 "s_register_operand" "=w")
3898
        (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
3899
                     UNSPEC_VTRN1))
3900
   (set (match_operand:VDQW 2 "s_register_operand" "=w")
3901
        (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
3902
                     UNSPEC_VTRN2))]
3903
  "TARGET_NEON"
3904
  "vtrn.\t%0, %2"
3905
  [(set (attr "neon_type")
3906
      (if_then_else (ne (symbol_ref "") (const_int 0))
3907
                    (const_string "neon_bp_simple")
3908
                    (const_string "neon_bp_3cycle")))]
3909
)
3910
 
3911
(define_expand "neon_vtrn"
3912
  [(match_operand:SI 0 "s_register_operand" "r")
3913
   (match_operand:VDQW 1 "s_register_operand" "w")
3914
   (match_operand:VDQW 2 "s_register_operand" "w")]
3915
  "TARGET_NEON"
3916
{
3917
  neon_emit_pair_result_insn (mode, gen_neon_vtrn_internal,
3918
                              operands[0], operands[1], operands[2]);
3919
  DONE;
3920
})
3921
 
3922
(define_insn "neon_vzip_internal"
3923
  [(set (match_operand:VDQW 0 "s_register_operand" "=w")
3924
        (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
3925
                     UNSPEC_VZIP1))
3926
   (set (match_operand:VDQW 2 "s_register_operand" "=w")
3927
        (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
3928
                     UNSPEC_VZIP2))]
3929
  "TARGET_NEON"
3930
  "vzip.\t%0, %2"
3931
  [(set (attr "neon_type")
3932
      (if_then_else (ne (symbol_ref "") (const_int 0))
3933
                    (const_string "neon_bp_simple")
3934
                    (const_string "neon_bp_3cycle")))]
3935
)
3936
 
3937
(define_expand "neon_vzip"
3938
  [(match_operand:SI 0 "s_register_operand" "r")
3939
   (match_operand:VDQW 1 "s_register_operand" "w")
3940
   (match_operand:VDQW 2 "s_register_operand" "w")]
3941
  "TARGET_NEON"
3942
{
3943
  neon_emit_pair_result_insn (mode, gen_neon_vzip_internal,
3944
                              operands[0], operands[1], operands[2]);
3945
  DONE;
3946
})
3947
 
3948
(define_insn "neon_vuzp_internal"
3949
  [(set (match_operand:VDQW 0 "s_register_operand" "=w")
3950
        (unspec:VDQW [(match_operand:VDQW 1 "s_register_operand" "0")]
3951
                     UNSPEC_VUZP1))
3952
   (set (match_operand:VDQW 2 "s_register_operand" "=w")
3953
        (unspec:VDQW [(match_operand:VDQW 3 "s_register_operand" "2")]
3954
                     UNSPEC_VUZP2))]
3955
  "TARGET_NEON"
3956
  "vuzp.\t%0, %2"
3957
  [(set (attr "neon_type")
3958
      (if_then_else (ne (symbol_ref "") (const_int 0))
3959
                    (const_string "neon_bp_simple")
3960
                    (const_string "neon_bp_3cycle")))]
3961
)
3962
 
3963
(define_expand "neon_vuzp"
3964
  [(match_operand:SI 0 "s_register_operand" "r")
3965
   (match_operand:VDQW 1 "s_register_operand" "w")
3966
   (match_operand:VDQW 2 "s_register_operand" "w")]
3967
  "TARGET_NEON"
3968
{
3969
  neon_emit_pair_result_insn (mode, gen_neon_vuzp_internal,
3970
                              operands[0], operands[1], operands[2]);
3971
  DONE;
3972
})
3973
 
3974
(define_expand "neon_vreinterpretv8qi"
3975
  [(match_operand:V8QI 0 "s_register_operand" "")
3976
   (match_operand:VDX 1 "s_register_operand" "")]
3977
  "TARGET_NEON"
3978
{
3979
  neon_reinterpret (operands[0], operands[1]);
3980
  DONE;
3981
})
3982
 
3983
(define_expand "neon_vreinterpretv4hi"
3984
  [(match_operand:V4HI 0 "s_register_operand" "")
3985
   (match_operand:VDX 1 "s_register_operand" "")]
3986
  "TARGET_NEON"
3987
{
3988
  neon_reinterpret (operands[0], operands[1]);
3989
  DONE;
3990
})
3991
 
3992
(define_expand "neon_vreinterpretv2si"
3993
  [(match_operand:V2SI 0 "s_register_operand" "")
3994
   (match_operand:VDX 1 "s_register_operand" "")]
3995
  "TARGET_NEON"
3996
{
3997
  neon_reinterpret (operands[0], operands[1]);
3998
  DONE;
3999
})
4000
 
4001
(define_expand "neon_vreinterpretv2sf"
4002
  [(match_operand:V2SF 0 "s_register_operand" "")
4003
   (match_operand:VDX 1 "s_register_operand" "")]
4004
  "TARGET_NEON"
4005
{
4006
  neon_reinterpret (operands[0], operands[1]);
4007
  DONE;
4008
})
4009
 
4010
(define_expand "neon_vreinterpretdi"
4011
  [(match_operand:DI 0 "s_register_operand" "")
4012
   (match_operand:VDX 1 "s_register_operand" "")]
4013
  "TARGET_NEON"
4014
{
4015
  neon_reinterpret (operands[0], operands[1]);
4016
  DONE;
4017
})
4018
 
4019
(define_expand "neon_vreinterpretv16qi"
4020
  [(match_operand:V16QI 0 "s_register_operand" "")
4021
   (match_operand:VQX 1 "s_register_operand" "")]
4022
  "TARGET_NEON"
4023
{
4024
  neon_reinterpret (operands[0], operands[1]);
4025
  DONE;
4026
})
4027
 
4028
(define_expand "neon_vreinterpretv8hi"
4029
  [(match_operand:V8HI 0 "s_register_operand" "")
4030
   (match_operand:VQX 1 "s_register_operand" "")]
4031
  "TARGET_NEON"
4032
{
4033
  neon_reinterpret (operands[0], operands[1]);
4034
  DONE;
4035
})
4036
 
4037
(define_expand "neon_vreinterpretv4si"
4038
  [(match_operand:V4SI 0 "s_register_operand" "")
4039
   (match_operand:VQX 1 "s_register_operand" "")]
4040
  "TARGET_NEON"
4041
{
4042
  neon_reinterpret (operands[0], operands[1]);
4043
  DONE;
4044
})
4045
 
4046
(define_expand "neon_vreinterpretv4sf"
4047
  [(match_operand:V4SF 0 "s_register_operand" "")
4048
   (match_operand:VQX 1 "s_register_operand" "")]
4049
  "TARGET_NEON"
4050
{
4051
  neon_reinterpret (operands[0], operands[1]);
4052
  DONE;
4053
})
4054
 
4055
(define_expand "neon_vreinterpretv2di"
4056
  [(match_operand:V2DI 0 "s_register_operand" "")
4057
   (match_operand:VQX 1 "s_register_operand" "")]
4058
  "TARGET_NEON"
4059
{
4060
  neon_reinterpret (operands[0], operands[1]);
4061
  DONE;
4062
})
4063
 
4064
(define_insn "neon_vld1"
4065
  [(set (match_operand:VDQX 0 "s_register_operand" "=w")
4066
        (unspec:VDQX [(mem:VDQX (match_operand:SI 1 "s_register_operand" "r"))]
4067
                    UNSPEC_VLD1))]
4068
  "TARGET_NEON"
4069
  "vld1.\t%h0, [%1]"
4070
  [(set_attr "neon_type" "neon_vld1_1_2_regs")]
4071
)
4072
 
4073
(define_insn "neon_vld1_lane"
4074
  [(set (match_operand:VDX 0 "s_register_operand" "=w")
4075
        (unspec:VDX [(mem: (match_operand:SI 1 "s_register_operand" "r"))
4076
                     (match_operand:VDX 2 "s_register_operand" "0")
4077
                     (match_operand:SI 3 "immediate_operand" "i")]
4078
                    UNSPEC_VLD1_LANE))]
4079
  "TARGET_NEON"
4080
{
4081
  HOST_WIDE_INT lane = INTVAL (operands[3]);
4082
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4083
  if (lane < 0 || lane >= max)
4084
    error ("lane out of range");
4085
  if (max == 1)
4086
    return "vld1.\t%P0, [%1]";
4087
  else
4088
    return "vld1.\t{%P0[%c3]}, [%1]";
4089
}
4090
  [(set (attr "neon_type")
4091
      (if_then_else (eq (const_string "") (const_int 2))
4092
                    (const_string "neon_vld1_1_2_regs")
4093
                    (const_string "neon_vld1_vld2_lane")))]
4094
)
4095
 
4096
(define_insn "neon_vld1_lane"
4097
  [(set (match_operand:VQX 0 "s_register_operand" "=w")
4098
        (unspec:VQX [(mem: (match_operand:SI 1 "s_register_operand" "r"))
4099
                     (match_operand:VQX 2 "s_register_operand" "0")
4100
                     (match_operand:SI 3 "immediate_operand" "i")]
4101
                    UNSPEC_VLD1_LANE))]
4102
  "TARGET_NEON"
4103
{
4104
  HOST_WIDE_INT lane = INTVAL (operands[3]);
4105
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4106
  int regno = REGNO (operands[0]);
4107
  if (lane < 0 || lane >= max)
4108
    error ("lane out of range");
4109
  else if (lane >= max / 2)
4110
    {
4111
      lane -= max / 2;
4112
      regno += 2;
4113
      operands[3] = GEN_INT (lane);
4114
    }
4115
  operands[0] = gen_rtx_REG (mode, regno);
4116
  if (max == 2)
4117
    return "vld1.\t%P0, [%1]";
4118
  else
4119
    return "vld1.\t{%P0[%c3]}, [%1]";
4120
}
4121
  [(set (attr "neon_type")
4122
      (if_then_else (eq (const_string "") (const_int 2))
4123
                    (const_string "neon_vld1_1_2_regs")
4124
                    (const_string "neon_vld1_vld2_lane")))]
4125
)
4126
 
4127
(define_insn "neon_vld1_dup"
4128
  [(set (match_operand:VDX 0 "s_register_operand" "=w")
4129
        (unspec:VDX [(mem: (match_operand:SI 1 "s_register_operand" "r"))]
4130
                    UNSPEC_VLD1_DUP))]
4131
  "TARGET_NEON"
4132
{
4133
  if (GET_MODE_NUNITS (mode) > 1)
4134
    return "vld1.\t{%P0[]}, [%1]";
4135
  else
4136
    return "vld1.\t%h0, [%1]";
4137
}
4138
  [(set (attr "neon_type")
4139
      (if_then_else (gt (const_string "") (const_string "1"))
4140
                    (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4141
                    (const_string "neon_vld1_1_2_regs")))]
4142
)
4143
 
4144
(define_insn "neon_vld1_dup"
4145
  [(set (match_operand:VQX 0 "s_register_operand" "=w")
4146
        (unspec:VQX [(mem: (match_operand:SI 1 "s_register_operand" "r"))]
4147
                    UNSPEC_VLD1_DUP))]
4148
  "TARGET_NEON"
4149
{
4150
  if (GET_MODE_NUNITS (mode) > 2)
4151
    return "vld1.\t{%e0[], %f0[]}, [%1]";
4152
  else
4153
    return "vld1.\t%h0, [%1]";
4154
}
4155
  [(set (attr "neon_type")
4156
      (if_then_else (gt (const_string "") (const_string "1"))
4157
                    (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4158
                    (const_string "neon_vld1_1_2_regs")))]
4159
)
4160
 
4161
(define_insn "neon_vst1"
4162
  [(set (mem:VDQX (match_operand:SI 0 "s_register_operand" "r"))
4163
        (unspec:VDQX [(match_operand:VDQX 1 "s_register_operand" "w")]
4164
                     UNSPEC_VST1))]
4165
  "TARGET_NEON"
4166
  "vst1.\t%h1, [%0]"
4167
  [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
4168
 
4169
(define_insn "neon_vst1_lane"
4170
  [(set (mem: (match_operand:SI 0 "s_register_operand" "r"))
4171
        (vec_select:
4172
          (match_operand:VDX 1 "s_register_operand" "w")
4173
          (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
4174
  "TARGET_NEON"
4175
{
4176
  HOST_WIDE_INT lane = INTVAL (operands[2]);
4177
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4178
  if (lane < 0 || lane >= max)
4179
    error ("lane out of range");
4180
  if (max == 1)
4181
    return "vst1.\t{%P1}, [%0]";
4182
  else
4183
    return "vst1.\t{%P1[%c2]}, [%0]";
4184
}
4185
  [(set (attr "neon_type")
4186
      (if_then_else (eq (const_string "") (const_int 1))
4187
                    (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4188
                    (const_string "neon_vst1_vst2_lane")))])
4189
 
4190
(define_insn "neon_vst1_lane"
4191
  [(set (mem: (match_operand:SI 0 "s_register_operand" "r"))
4192
        (vec_select:
4193
           (match_operand:VQX 1 "s_register_operand" "w")
4194
           (parallel [(match_operand:SI 2 "neon_lane_number" "i")])))]
4195
  "TARGET_NEON"
4196
{
4197
  HOST_WIDE_INT lane = INTVAL (operands[2]);
4198
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4199
  int regno = REGNO (operands[1]);
4200
  if (lane < 0 || lane >= max)
4201
    error ("lane out of range");
4202
  else if (lane >= max / 2)
4203
    {
4204
      lane -= max / 2;
4205
      regno += 2;
4206
      operands[2] = GEN_INT (lane);
4207
    }
4208
  operands[1] = gen_rtx_REG (mode, regno);
4209
  if (max == 2)
4210
    return "vst1.\t{%P1}, [%0]";
4211
  else
4212
    return "vst1.\t{%P1[%c2]}, [%0]";
4213
}
4214
  [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4215
)
4216
 
4217
(define_insn "neon_vld2"
4218
  [(set (match_operand:TI 0 "s_register_operand" "=w")
4219
        (unspec:TI [(mem:TI (match_operand:SI 1 "s_register_operand" "r"))
4220
                    (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4221
                   UNSPEC_VLD2))]
4222
  "TARGET_NEON"
4223
{
4224
  if ( == 64)
4225
    return "vld1.64\t%h0, [%1]";
4226
  else
4227
    return "vld2.\t%h0, [%1]";
4228
}
4229
  [(set (attr "neon_type")
4230
      (if_then_else (eq (const_string "") (const_string "64"))
4231
                    (const_string "neon_vld1_1_2_regs")
4232
                    (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")))]
4233
)
4234
 
4235
(define_insn "neon_vld2"
4236
  [(set (match_operand:OI 0 "s_register_operand" "=w")
4237
        (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
4238
                    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4239
                   UNSPEC_VLD2))]
4240
  "TARGET_NEON"
4241
  "vld2.\t%h0, [%1]"
4242
  [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")])
4243
 
4244
(define_insn "neon_vld2_lane"
4245
  [(set (match_operand:TI 0 "s_register_operand" "=w")
4246
        (unspec:TI [(mem: (match_operand:SI 1 "s_register_operand" "r"))
4247
                    (match_operand:TI 2 "s_register_operand" "0")
4248
                    (match_operand:SI 3 "immediate_operand" "i")
4249
                    (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4250
                   UNSPEC_VLD2_LANE))]
4251
  "TARGET_NEON"
4252
{
4253
  HOST_WIDE_INT lane = INTVAL (operands[3]);
4254
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4255
  int regno = REGNO (operands[0]);
4256
  rtx ops[4];
4257
  if (lane < 0 || lane >= max)
4258
    error ("lane out of range");
4259
  ops[0] = gen_rtx_REG (DImode, regno);
4260
  ops[1] = gen_rtx_REG (DImode, regno + 2);
4261
  ops[2] = operands[1];
4262
  ops[3] = operands[3];
4263
  output_asm_insn ("vld2.\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
4264
  return "";
4265
}
4266
  [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4267
)
4268
 
4269
(define_insn "neon_vld2_lane"
4270
  [(set (match_operand:OI 0 "s_register_operand" "=w")
4271
        (unspec:OI [(mem: (match_operand:SI 1 "s_register_operand" "r"))
4272
                    (match_operand:OI 2 "s_register_operand" "0")
4273
                    (match_operand:SI 3 "immediate_operand" "i")
4274
                    (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4275
                   UNSPEC_VLD2_LANE))]
4276
  "TARGET_NEON"
4277
{
4278
  HOST_WIDE_INT lane = INTVAL (operands[3]);
4279
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4280
  int regno = REGNO (operands[0]);
4281
  rtx ops[4];
4282
  if (lane < 0 || lane >= max)
4283
    error ("lane out of range");
4284
  else if (lane >= max / 2)
4285
    {
4286
      lane -= max / 2;
4287
      regno += 2;
4288
    }
4289
  ops[0] = gen_rtx_REG (DImode, regno);
4290
  ops[1] = gen_rtx_REG (DImode, regno + 4);
4291
  ops[2] = operands[1];
4292
  ops[3] = GEN_INT (lane);
4293
  output_asm_insn ("vld2.\t{%P0[%c3], %P1[%c3]}, [%2]", ops);
4294
  return "";
4295
}
4296
  [(set_attr "neon_type" "neon_vld1_vld2_lane")]
4297
)
4298
 
4299
(define_insn "neon_vld2_dup"
4300
  [(set (match_operand:TI 0 "s_register_operand" "=w")
4301
        (unspec:TI [(mem: (match_operand:SI 1 "s_register_operand" "r"))
4302
                    (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4303
                   UNSPEC_VLD2_DUP))]
4304
  "TARGET_NEON"
4305
{
4306
  if (GET_MODE_NUNITS (mode) > 1)
4307
    return "vld2.\t{%e0[], %f0[]}, [%1]";
4308
  else
4309
    return "vld1.\t%h0, [%1]";
4310
}
4311
  [(set (attr "neon_type")
4312
      (if_then_else (gt (const_string "") (const_string "1"))
4313
                    (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
4314
                    (const_string "neon_vld1_1_2_regs")))]
4315
)
4316
 
4317
(define_insn "neon_vst2"
4318
  [(set (mem:TI (match_operand:SI 0 "s_register_operand" "r"))
4319
        (unspec:TI [(match_operand:TI 1 "s_register_operand" "w")
4320
                    (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4321
                   UNSPEC_VST2))]
4322
  "TARGET_NEON"
4323
{
4324
  if ( == 64)
4325
    return "vst1.64\t%h1, [%0]";
4326
  else
4327
    return "vst2.\t%h1, [%0]";
4328
}
4329
  [(set (attr "neon_type")
4330
      (if_then_else (eq (const_string "") (const_string "64"))
4331
                    (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4332
                    (const_string "neon_vst1_1_2_regs_vst2_2_regs")))]
4333
)
4334
 
4335
(define_insn "neon_vst2"
4336
  [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
4337
        (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
4338
                    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4339
                   UNSPEC_VST2))]
4340
  "TARGET_NEON"
4341
  "vst2.\t%h1, [%0]"
4342
  [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]
4343
)
4344
 
4345
(define_insn "neon_vst2_lane"
4346
  [(set (mem: (match_operand:SI 0 "s_register_operand" "r"))
4347
        (unspec:
4348
          [(match_operand:TI 1 "s_register_operand" "w")
4349
           (match_operand:SI 2 "immediate_operand" "i")
4350
           (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4351
          UNSPEC_VST2_LANE))]
4352
  "TARGET_NEON"
4353
{
4354
  HOST_WIDE_INT lane = INTVAL (operands[2]);
4355
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4356
  int regno = REGNO (operands[1]);
4357
  rtx ops[4];
4358
  if (lane < 0 || lane >= max)
4359
    error ("lane out of range");
4360
  ops[0] = operands[0];
4361
  ops[1] = gen_rtx_REG (DImode, regno);
4362
  ops[2] = gen_rtx_REG (DImode, regno + 2);
4363
  ops[3] = operands[2];
4364
  output_asm_insn ("vst2.\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
4365
  return "";
4366
}
4367
  [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4368
)
4369
 
4370
(define_insn "neon_vst2_lane"
4371
  [(set (mem: (match_operand:SI 0 "s_register_operand" "r"))
4372
        (unspec:
4373
           [(match_operand:OI 1 "s_register_operand" "w")
4374
            (match_operand:SI 2 "immediate_operand" "i")
4375
            (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4376
           UNSPEC_VST2_LANE))]
4377
  "TARGET_NEON"
4378
{
4379
  HOST_WIDE_INT lane = INTVAL (operands[2]);
4380
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4381
  int regno = REGNO (operands[1]);
4382
  rtx ops[4];
4383
  if (lane < 0 || lane >= max)
4384
    error ("lane out of range");
4385
  else if (lane >= max / 2)
4386
    {
4387
      lane -= max / 2;
4388
      regno += 2;
4389
    }
4390
  ops[0] = operands[0];
4391
  ops[1] = gen_rtx_REG (DImode, regno);
4392
  ops[2] = gen_rtx_REG (DImode, regno + 4);
4393
  ops[3] = GEN_INT (lane);
4394
  output_asm_insn ("vst2.\t{%P1[%c3], %P2[%c3]}, [%0]", ops);
4395
  return "";
4396
}
4397
  [(set_attr "neon_type" "neon_vst1_vst2_lane")]
4398
)
4399
 
4400
(define_insn "neon_vld3"
4401
  [(set (match_operand:EI 0 "s_register_operand" "=w")
4402
        (unspec:EI [(mem:EI (match_operand:SI 1 "s_register_operand" "r"))
4403
                    (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4404
                   UNSPEC_VLD3))]
4405
  "TARGET_NEON"
4406
{
4407
  if ( == 64)
4408
    return "vld1.64\t%h0, [%1]";
4409
  else
4410
    return "vld3.\t%h0, [%1]";
4411
}
4412
  [(set (attr "neon_type")
4413
      (if_then_else (eq (const_string "") (const_string "64"))
4414
                    (const_string "neon_vld1_1_2_regs")
4415
                    (const_string "neon_vld3_vld4")))]
4416
)
4417
 
4418
(define_expand "neon_vld3"
4419
  [(match_operand:CI 0 "s_register_operand" "=w")
4420
   (match_operand:SI 1 "s_register_operand" "+r")
4421
   (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4422
  "TARGET_NEON"
4423
{
4424
  emit_insn (gen_neon_vld3qa (operands[0], operands[0],
4425
                                    operands[1], operands[1]));
4426
  emit_insn (gen_neon_vld3qb (operands[0], operands[0],
4427
                                    operands[1], operands[1]));
4428
  DONE;
4429
})
4430
 
4431
(define_insn "neon_vld3qa"
4432
  [(set (match_operand:CI 0 "s_register_operand" "=w")
4433
        (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
4434
                    (match_operand:CI 1 "s_register_operand" "0")
4435
                    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4436
                   UNSPEC_VLD3A))
4437
   (set (match_operand:SI 2 "s_register_operand" "=r")
4438
        (plus:SI (match_dup 3)
4439
                 (const_int 24)))]
4440
  "TARGET_NEON"
4441
{
4442
  int regno = REGNO (operands[0]);
4443
  rtx ops[4];
4444
  ops[0] = gen_rtx_REG (DImode, regno);
4445
  ops[1] = gen_rtx_REG (DImode, regno + 4);
4446
  ops[2] = gen_rtx_REG (DImode, regno + 8);
4447
  ops[3] = operands[2];
4448
  output_asm_insn ("vld3.\t{%P0, %P1, %P2}, [%3]!", ops);
4449
  return "";
4450
}
4451
  [(set_attr "neon_type" "neon_vld3_vld4")]
4452
)
4453
 
4454
(define_insn "neon_vld3qb"
4455
  [(set (match_operand:CI 0 "s_register_operand" "=w")
4456
        (unspec:CI [(mem:CI (match_operand:SI 3 "s_register_operand" "2"))
4457
                    (match_operand:CI 1 "s_register_operand" "0")
4458
                    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4459
                   UNSPEC_VLD3B))
4460
   (set (match_operand:SI 2 "s_register_operand" "=r")
4461
        (plus:SI (match_dup 3)
4462
                 (const_int 24)))]
4463
  "TARGET_NEON"
4464
{
4465
  int regno = REGNO (operands[0]);
4466
  rtx ops[4];
4467
  ops[0] = gen_rtx_REG (DImode, regno + 2);
4468
  ops[1] = gen_rtx_REG (DImode, regno + 6);
4469
  ops[2] = gen_rtx_REG (DImode, regno + 10);
4470
  ops[3] = operands[2];
4471
  output_asm_insn ("vld3.\t{%P0, %P1, %P2}, [%3]!", ops);
4472
  return "";
4473
}
4474
  [(set_attr "neon_type" "neon_vld3_vld4")]
4475
)
4476
 
4477
(define_insn "neon_vld3_lane"
4478
  [(set (match_operand:EI 0 "s_register_operand" "=w")
4479
        (unspec:EI [(mem: (match_operand:SI 1 "s_register_operand" "r"))
4480
                    (match_operand:EI 2 "s_register_operand" "0")
4481
                    (match_operand:SI 3 "immediate_operand" "i")
4482
                    (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4483
                   UNSPEC_VLD3_LANE))]
4484
  "TARGET_NEON"
4485
{
4486
  HOST_WIDE_INT lane = INTVAL (operands[3]);
4487
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4488
  int regno = REGNO (operands[0]);
4489
  rtx ops[5];
4490
  if (lane < 0 || lane >= max)
4491
    error ("lane out of range");
4492
  ops[0] = gen_rtx_REG (DImode, regno);
4493
  ops[1] = gen_rtx_REG (DImode, regno + 2);
4494
  ops[2] = gen_rtx_REG (DImode, regno + 4);
4495
  ops[3] = operands[1];
4496
  ops[4] = operands[3];
4497
  output_asm_insn ("vld3.\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
4498
                   ops);
4499
  return "";
4500
}
4501
  [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4502
)
4503
 
4504
(define_insn "neon_vld3_lane"
4505
  [(set (match_operand:CI 0 "s_register_operand" "=w")
4506
        (unspec:CI [(mem: (match_operand:SI 1 "s_register_operand" "r"))
4507
                    (match_operand:CI 2 "s_register_operand" "0")
4508
                    (match_operand:SI 3 "immediate_operand" "i")
4509
                    (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4510
                   UNSPEC_VLD3_LANE))]
4511
  "TARGET_NEON"
4512
{
4513
  HOST_WIDE_INT lane = INTVAL (operands[3]);
4514
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4515
  int regno = REGNO (operands[0]);
4516
  rtx ops[5];
4517
  if (lane < 0 || lane >= max)
4518
    error ("lane out of range");
4519
  else if (lane >= max / 2)
4520
    {
4521
      lane -= max / 2;
4522
      regno += 2;
4523
    }
4524
  ops[0] = gen_rtx_REG (DImode, regno);
4525
  ops[1] = gen_rtx_REG (DImode, regno + 4);
4526
  ops[2] = gen_rtx_REG (DImode, regno + 8);
4527
  ops[3] = operands[1];
4528
  ops[4] = GEN_INT (lane);
4529
  output_asm_insn ("vld3.\t{%P0[%c4], %P1[%c4], %P2[%c4]}, [%3]",
4530
                   ops);
4531
  return "";
4532
}
4533
  [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4534
)
4535
 
4536
(define_insn "neon_vld3_dup"
4537
  [(set (match_operand:EI 0 "s_register_operand" "=w")
4538
        (unspec:EI [(mem: (match_operand:SI 1 "s_register_operand" "r"))
4539
                    (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4540
                   UNSPEC_VLD3_DUP))]
4541
  "TARGET_NEON"
4542
{
4543
  if (GET_MODE_NUNITS (mode) > 1)
4544
    {
4545
      int regno = REGNO (operands[0]);
4546
      rtx ops[4];
4547
      ops[0] = gen_rtx_REG (DImode, regno);
4548
      ops[1] = gen_rtx_REG (DImode, regno + 2);
4549
      ops[2] = gen_rtx_REG (DImode, regno + 4);
4550
      ops[3] = operands[1];
4551
      output_asm_insn ("vld3.\t{%P0[], %P1[], %P2[]}, [%3]", ops);
4552
      return "";
4553
    }
4554
  else
4555
    return "vld1.\t%h0, [%1]";
4556
}
4557
  [(set (attr "neon_type")
4558
      (if_then_else (gt (const_string "") (const_string "1"))
4559
                    (const_string "neon_vld3_vld4_all_lanes")
4560
                    (const_string "neon_vld1_1_2_regs")))])
4561
 
4562
(define_insn "neon_vst3"
4563
  [(set (mem:EI (match_operand:SI 0 "s_register_operand" "r"))
4564
        (unspec:EI [(match_operand:EI 1 "s_register_operand" "w")
4565
                    (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4566
                   UNSPEC_VST3))]
4567
  "TARGET_NEON"
4568
{
4569
  if ( == 64)
4570
    return "vst1.64\t%h1, [%0]";
4571
  else
4572
    return "vst3.\t%h1, [%0]";
4573
}
4574
  [(set (attr "neon_type")
4575
      (if_then_else (eq (const_string "") (const_string "64"))
4576
                    (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4577
                    (const_string "neon_vst2_4_regs_vst3_vst4")))])
4578
 
4579
(define_expand "neon_vst3"
4580
  [(match_operand:SI 0 "s_register_operand" "+r")
4581
   (match_operand:CI 1 "s_register_operand" "w")
4582
   (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4583
  "TARGET_NEON"
4584
{
4585
  emit_insn (gen_neon_vst3qa (operands[0], operands[0], operands[1]));
4586
  emit_insn (gen_neon_vst3qb (operands[0], operands[0], operands[1]));
4587
  DONE;
4588
})
4589
 
4590
(define_insn "neon_vst3qa"
4591
  [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
4592
        (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
4593
                    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4594
                   UNSPEC_VST3A))
4595
   (set (match_operand:SI 0 "s_register_operand" "=r")
4596
        (plus:SI (match_dup 1)
4597
                 (const_int 24)))]
4598
  "TARGET_NEON"
4599
{
4600
  int regno = REGNO (operands[2]);
4601
  rtx ops[4];
4602
  ops[0] = operands[0];
4603
  ops[1] = gen_rtx_REG (DImode, regno);
4604
  ops[2] = gen_rtx_REG (DImode, regno + 4);
4605
  ops[3] = gen_rtx_REG (DImode, regno + 8);
4606
  output_asm_insn ("vst3.\t{%P1, %P2, %P3}, [%0]!", ops);
4607
  return "";
4608
}
4609
  [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4610
)
4611
 
4612
(define_insn "neon_vst3qb"
4613
  [(set (mem:EI (match_operand:SI 1 "s_register_operand" "0"))
4614
        (unspec:EI [(match_operand:CI 2 "s_register_operand" "w")
4615
                    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4616
                   UNSPEC_VST3B))
4617
   (set (match_operand:SI 0 "s_register_operand" "=r")
4618
        (plus:SI (match_dup 1)
4619
                 (const_int 24)))]
4620
  "TARGET_NEON"
4621
{
4622
  int regno = REGNO (operands[2]);
4623
  rtx ops[4];
4624
  ops[0] = operands[0];
4625
  ops[1] = gen_rtx_REG (DImode, regno + 2);
4626
  ops[2] = gen_rtx_REG (DImode, regno + 6);
4627
  ops[3] = gen_rtx_REG (DImode, regno + 10);
4628
  output_asm_insn ("vst3.\t{%P1, %P2, %P3}, [%0]!", ops);
4629
  return "";
4630
}
4631
  [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4632
)
4633
 
4634
(define_insn "neon_vst3_lane"
4635
  [(set (mem: (match_operand:SI 0 "s_register_operand" "r"))
4636
        (unspec:
4637
           [(match_operand:EI 1 "s_register_operand" "w")
4638
            (match_operand:SI 2 "immediate_operand" "i")
4639
            (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4640
           UNSPEC_VST3_LANE))]
4641
  "TARGET_NEON"
4642
{
4643
  HOST_WIDE_INT lane = INTVAL (operands[2]);
4644
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4645
  int regno = REGNO (operands[1]);
4646
  rtx ops[5];
4647
  if (lane < 0 || lane >= max)
4648
    error ("lane out of range");
4649
  ops[0] = operands[0];
4650
  ops[1] = gen_rtx_REG (DImode, regno);
4651
  ops[2] = gen_rtx_REG (DImode, regno + 2);
4652
  ops[3] = gen_rtx_REG (DImode, regno + 4);
4653
  ops[4] = operands[2];
4654
  output_asm_insn ("vst3.\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
4655
                   ops);
4656
  return "";
4657
}
4658
  [(set_attr "neon_type" "neon_vst3_vst4_lane")]
4659
)
4660
 
4661
(define_insn "neon_vst3_lane"
4662
  [(set (mem: (match_operand:SI 0 "s_register_operand" "r"))
4663
        (unspec:
4664
           [(match_operand:CI 1 "s_register_operand" "w")
4665
            (match_operand:SI 2 "immediate_operand" "i")
4666
            (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4667
           UNSPEC_VST3_LANE))]
4668
  "TARGET_NEON"
4669
{
4670
  HOST_WIDE_INT lane = INTVAL (operands[2]);
4671
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4672
  int regno = REGNO (operands[1]);
4673
  rtx ops[5];
4674
  if (lane < 0 || lane >= max)
4675
    error ("lane out of range");
4676
  else if (lane >= max / 2)
4677
    {
4678
      lane -= max / 2;
4679
      regno += 2;
4680
    }
4681
  ops[0] = operands[0];
4682
  ops[1] = gen_rtx_REG (DImode, regno);
4683
  ops[2] = gen_rtx_REG (DImode, regno + 4);
4684
  ops[3] = gen_rtx_REG (DImode, regno + 8);
4685
  ops[4] = GEN_INT (lane);
4686
  output_asm_insn ("vst3.\t{%P1[%c4], %P2[%c4], %P3[%c4]}, [%0]",
4687
                   ops);
4688
  return "";
4689
}
4690
[(set_attr "neon_type" "neon_vst3_vst4_lane")])
4691
 
4692
(define_insn "neon_vld4"
4693
  [(set (match_operand:OI 0 "s_register_operand" "=w")
4694
        (unspec:OI [(mem:OI (match_operand:SI 1 "s_register_operand" "r"))
4695
                    (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4696
                   UNSPEC_VLD4))]
4697
  "TARGET_NEON"
4698
{
4699
  if ( == 64)
4700
    return "vld1.64\t%h0, [%1]";
4701
  else
4702
    return "vld4.\t%h0, [%1]";
4703
}
4704
  [(set (attr "neon_type")
4705
      (if_then_else (eq (const_string "") (const_string "64"))
4706
                    (const_string "neon_vld1_1_2_regs")
4707
                    (const_string "neon_vld3_vld4")))]
4708
)
4709
 
4710
(define_expand "neon_vld4"
4711
  [(match_operand:XI 0 "s_register_operand" "=w")
4712
   (match_operand:SI 1 "s_register_operand" "+r")
4713
   (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4714
  "TARGET_NEON"
4715
{
4716
  emit_insn (gen_neon_vld4qa (operands[0], operands[0],
4717
                                    operands[1], operands[1]));
4718
  emit_insn (gen_neon_vld4qb (operands[0], operands[0],
4719
                                    operands[1], operands[1]));
4720
  DONE;
4721
})
4722
 
4723
(define_insn "neon_vld4qa"
4724
  [(set (match_operand:XI 0 "s_register_operand" "=w")
4725
        (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
4726
                    (match_operand:XI 1 "s_register_operand" "0")
4727
                    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4728
                   UNSPEC_VLD4A))
4729
   (set (match_operand:SI 2 "s_register_operand" "=r")
4730
        (plus:SI (match_dup 3)
4731
                 (const_int 32)))]
4732
  "TARGET_NEON"
4733
{
4734
  int regno = REGNO (operands[0]);
4735
  rtx ops[5];
4736
  ops[0] = gen_rtx_REG (DImode, regno);
4737
  ops[1] = gen_rtx_REG (DImode, regno + 4);
4738
  ops[2] = gen_rtx_REG (DImode, regno + 8);
4739
  ops[3] = gen_rtx_REG (DImode, regno + 12);
4740
  ops[4] = operands[2];
4741
  output_asm_insn ("vld4.\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
4742
  return "";
4743
}
4744
  [(set_attr "neon_type" "neon_vld3_vld4")]
4745
)
4746
 
4747
(define_insn "neon_vld4qb"
4748
  [(set (match_operand:XI 0 "s_register_operand" "=w")
4749
        (unspec:XI [(mem:XI (match_operand:SI 3 "s_register_operand" "2"))
4750
                    (match_operand:XI 1 "s_register_operand" "0")
4751
                    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4752
                   UNSPEC_VLD4B))
4753
   (set (match_operand:SI 2 "s_register_operand" "=r")
4754
        (plus:SI (match_dup 3)
4755
                 (const_int 32)))]
4756
  "TARGET_NEON"
4757
{
4758
  int regno = REGNO (operands[0]);
4759
  rtx ops[5];
4760
  ops[0] = gen_rtx_REG (DImode, regno + 2);
4761
  ops[1] = gen_rtx_REG (DImode, regno + 6);
4762
  ops[2] = gen_rtx_REG (DImode, regno + 10);
4763
  ops[3] = gen_rtx_REG (DImode, regno + 14);
4764
  ops[4] = operands[2];
4765
  output_asm_insn ("vld4.\t{%P0, %P1, %P2, %P3}, [%4]!", ops);
4766
  return "";
4767
}
4768
  [(set_attr "neon_type" "neon_vld3_vld4")]
4769
)
4770
 
4771
(define_insn "neon_vld4_lane"
4772
  [(set (match_operand:OI 0 "s_register_operand" "=w")
4773
        (unspec:OI [(mem: (match_operand:SI 1 "s_register_operand" "r"))
4774
                    (match_operand:OI 2 "s_register_operand" "0")
4775
                    (match_operand:SI 3 "immediate_operand" "i")
4776
                    (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4777
                   UNSPEC_VLD4_LANE))]
4778
  "TARGET_NEON"
4779
{
4780
  HOST_WIDE_INT lane = INTVAL (operands[3]);
4781
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4782
  int regno = REGNO (operands[0]);
4783
  rtx ops[6];
4784
  if (lane < 0 || lane >= max)
4785
    error ("lane out of range");
4786
  ops[0] = gen_rtx_REG (DImode, regno);
4787
  ops[1] = gen_rtx_REG (DImode, regno + 2);
4788
  ops[2] = gen_rtx_REG (DImode, regno + 4);
4789
  ops[3] = gen_rtx_REG (DImode, regno + 6);
4790
  ops[4] = operands[1];
4791
  ops[5] = operands[3];
4792
  output_asm_insn ("vld4.\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
4793
                   ops);
4794
  return "";
4795
}
4796
  [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4797
)
4798
 
4799
(define_insn "neon_vld4_lane"
4800
  [(set (match_operand:XI 0 "s_register_operand" "=w")
4801
        (unspec:XI [(mem: (match_operand:SI 1 "s_register_operand" "r"))
4802
                    (match_operand:XI 2 "s_register_operand" "0")
4803
                    (match_operand:SI 3 "immediate_operand" "i")
4804
                    (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4805
                   UNSPEC_VLD4_LANE))]
4806
  "TARGET_NEON"
4807
{
4808
  HOST_WIDE_INT lane = INTVAL (operands[3]);
4809
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4810
  int regno = REGNO (operands[0]);
4811
  rtx ops[6];
4812
  if (lane < 0 || lane >= max)
4813
    error ("lane out of range");
4814
  else if (lane >= max / 2)
4815
    {
4816
      lane -= max / 2;
4817
      regno += 2;
4818
    }
4819
  ops[0] = gen_rtx_REG (DImode, regno);
4820
  ops[1] = gen_rtx_REG (DImode, regno + 4);
4821
  ops[2] = gen_rtx_REG (DImode, regno + 8);
4822
  ops[3] = gen_rtx_REG (DImode, regno + 12);
4823
  ops[4] = operands[1];
4824
  ops[5] = GEN_INT (lane);
4825
  output_asm_insn ("vld4.\t{%P0[%c5], %P1[%c5], %P2[%c5], %P3[%c5]}, [%4]",
4826
                   ops);
4827
  return "";
4828
}
4829
  [(set_attr "neon_type" "neon_vld3_vld4_lane")]
4830
)
4831
 
4832
(define_insn "neon_vld4_dup"
4833
  [(set (match_operand:OI 0 "s_register_operand" "=w")
4834
        (unspec:OI [(mem: (match_operand:SI 1 "s_register_operand" "r"))
4835
                    (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4836
                   UNSPEC_VLD4_DUP))]
4837
  "TARGET_NEON"
4838
{
4839
  if (GET_MODE_NUNITS (mode) > 1)
4840
    {
4841
      int regno = REGNO (operands[0]);
4842
      rtx ops[5];
4843
      ops[0] = gen_rtx_REG (DImode, regno);
4844
      ops[1] = gen_rtx_REG (DImode, regno + 2);
4845
      ops[2] = gen_rtx_REG (DImode, regno + 4);
4846
      ops[3] = gen_rtx_REG (DImode, regno + 6);
4847
      ops[4] = operands[1];
4848
      output_asm_insn ("vld4.\t{%P0[], %P1[], %P2[], %P3[]}, [%4]",
4849
                       ops);
4850
      return "";
4851
    }
4852
  else
4853
    return "vld1.\t%h0, [%1]";
4854
}
4855
  [(set (attr "neon_type")
4856
      (if_then_else (gt (const_string "") (const_string "1"))
4857
                    (const_string "neon_vld3_vld4_all_lanes")
4858
                    (const_string "neon_vld1_1_2_regs")))]
4859
)
4860
 
4861
(define_insn "neon_vst4"
4862
  [(set (mem:OI (match_operand:SI 0 "s_register_operand" "r"))
4863
        (unspec:OI [(match_operand:OI 1 "s_register_operand" "w")
4864
                    (unspec:VDX [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4865
                   UNSPEC_VST4))]
4866
  "TARGET_NEON"
4867
{
4868
  if ( == 64)
4869
    return "vst1.64\t%h1, [%0]";
4870
  else
4871
    return "vst4.\t%h1, [%0]";
4872
}
4873
  [(set (attr "neon_type")
4874
      (if_then_else (eq (const_string "") (const_string "64"))
4875
                    (const_string "neon_vst1_1_2_regs_vst2_2_regs")
4876
                    (const_string "neon_vst2_4_regs_vst3_vst4")))]
4877
)
4878
 
4879
(define_expand "neon_vst4"
4880
  [(match_operand:SI 0 "s_register_operand" "+r")
4881
   (match_operand:XI 1 "s_register_operand" "w")
4882
   (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4883
  "TARGET_NEON"
4884
{
4885
  emit_insn (gen_neon_vst4qa (operands[0], operands[0], operands[1]));
4886
  emit_insn (gen_neon_vst4qb (operands[0], operands[0], operands[1]));
4887
  DONE;
4888
})
4889
 
4890
(define_insn "neon_vst4qa"
4891
  [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
4892
        (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
4893
                    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4894
                   UNSPEC_VST4A))
4895
   (set (match_operand:SI 0 "s_register_operand" "=r")
4896
        (plus:SI (match_dup 1)
4897
                 (const_int 32)))]
4898
  "TARGET_NEON"
4899
{
4900
  int regno = REGNO (operands[2]);
4901
  rtx ops[5];
4902
  ops[0] = operands[0];
4903
  ops[1] = gen_rtx_REG (DImode, regno);
4904
  ops[2] = gen_rtx_REG (DImode, regno + 4);
4905
  ops[3] = gen_rtx_REG (DImode, regno + 8);
4906
  ops[4] = gen_rtx_REG (DImode, regno + 12);
4907
  output_asm_insn ("vst4.\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
4908
  return "";
4909
}
4910
  [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4911
)
4912
 
4913
(define_insn "neon_vst4qb"
4914
  [(set (mem:OI (match_operand:SI 1 "s_register_operand" "0"))
4915
        (unspec:OI [(match_operand:XI 2 "s_register_operand" "w")
4916
                    (unspec:VQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4917
                   UNSPEC_VST4B))
4918
   (set (match_operand:SI 0 "s_register_operand" "=r")
4919
        (plus:SI (match_dup 1)
4920
                 (const_int 32)))]
4921
  "TARGET_NEON"
4922
{
4923
  int regno = REGNO (operands[2]);
4924
  rtx ops[5];
4925
  ops[0] = operands[0];
4926
  ops[1] = gen_rtx_REG (DImode, regno + 2);
4927
  ops[2] = gen_rtx_REG (DImode, regno + 6);
4928
  ops[3] = gen_rtx_REG (DImode, regno + 10);
4929
  ops[4] = gen_rtx_REG (DImode, regno + 14);
4930
  output_asm_insn ("vst4.\t{%P1, %P2, %P3, %P4}, [%0]!", ops);
4931
  return "";
4932
}
4933
  [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
4934
)
4935
 
4936
(define_insn "neon_vst4_lane"
4937
  [(set (mem: (match_operand:SI 0 "s_register_operand" "r"))
4938
        (unspec:
4939
           [(match_operand:OI 1 "s_register_operand" "w")
4940
            (match_operand:SI 2 "immediate_operand" "i")
4941
            (unspec:VD [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4942
           UNSPEC_VST4_LANE))]
4943
  "TARGET_NEON"
4944
{
4945
  HOST_WIDE_INT lane = INTVAL (operands[2]);
4946
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4947
  int regno = REGNO (operands[1]);
4948
  rtx ops[6];
4949
  if (lane < 0 || lane >= max)
4950
    error ("lane out of range");
4951
  ops[0] = operands[0];
4952
  ops[1] = gen_rtx_REG (DImode, regno);
4953
  ops[2] = gen_rtx_REG (DImode, regno + 2);
4954
  ops[3] = gen_rtx_REG (DImode, regno + 4);
4955
  ops[4] = gen_rtx_REG (DImode, regno + 6);
4956
  ops[5] = operands[2];
4957
  output_asm_insn ("vst4.\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, [%0]",
4958
                   ops);
4959
  return "";
4960
}
4961
  [(set_attr "neon_type" "neon_vst3_vst4_lane")]
4962
)
4963
 
4964
(define_insn "neon_vst4_lane"
4965
  [(set (mem: (match_operand:SI 0 "s_register_operand" "r"))
4966
        (unspec:
4967
           [(match_operand:XI 1 "s_register_operand" "w")
4968
            (match_operand:SI 2 "immediate_operand" "i")
4969
            (unspec:VMQ [(const_int 0)] UNSPEC_VSTRUCTDUMMY)]
4970
           UNSPEC_VST4_LANE))]
4971
  "TARGET_NEON"
4972
{
4973
  HOST_WIDE_INT lane = INTVAL (operands[2]);
4974
  HOST_WIDE_INT max = GET_MODE_NUNITS (mode);
4975
  int regno = REGNO (operands[1]);
4976
  rtx ops[6];
4977
  if (lane < 0 || lane >= max)
4978
    error ("lane out of range");
4979
  else if (lane >= max / 2)
4980
    {
4981
      lane -= max / 2;
4982
      regno += 2;
4983
    }
4984
  ops[0] = operands[0];
4985
  ops[1] = gen_rtx_REG (DImode, regno);
4986
  ops[2] = gen_rtx_REG (DImode, regno + 4);
4987
  ops[3] = gen_rtx_REG (DImode, regno + 8);
4988
  ops[4] = gen_rtx_REG (DImode, regno + 12);
4989
  ops[5] = GEN_INT (lane);
4990
  output_asm_insn ("vst4.\t{%P1[%c5], %P2[%c5], %P3[%c5], %P4[%c5]}, [%0]",
4991
                   ops);
4992
  return "";
4993
}
4994
  [(set_attr "neon_type" "neon_vst3_vst4_lane")]
4995
)
4996
 
4997
(define_expand "neon_vand"
4998
  [(match_operand:VDQX 0 "s_register_operand" "")
4999
   (match_operand:VDQX 1 "s_register_operand" "")
5000
   (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5001
   (match_operand:SI 3 "immediate_operand" "")]
5002
  "TARGET_NEON"
5003
{
5004
  emit_insn (gen_and3 (operands[0], operands[1], operands[2]));
5005
  DONE;
5006
})
5007
 
5008
(define_expand "neon_vorr"
5009
  [(match_operand:VDQX 0 "s_register_operand" "")
5010
   (match_operand:VDQX 1 "s_register_operand" "")
5011
   (match_operand:VDQX 2 "neon_logic_op2" "")
5012
   (match_operand:SI 3 "immediate_operand" "")]
5013
  "TARGET_NEON"
5014
{
5015
  emit_insn (gen_ior3 (operands[0], operands[1], operands[2]));
5016
  DONE;
5017
})
5018
 
5019
(define_expand "neon_veor"
5020
  [(match_operand:VDQX 0 "s_register_operand" "")
5021
   (match_operand:VDQX 1 "s_register_operand" "")
5022
   (match_operand:VDQX 2 "s_register_operand" "")
5023
   (match_operand:SI 3 "immediate_operand" "")]
5024
  "TARGET_NEON"
5025
{
5026
  emit_insn (gen_xor3 (operands[0], operands[1], operands[2]));
5027
  DONE;
5028
})
5029
 
5030
(define_expand "neon_vbic"
5031
  [(match_operand:VDQX 0 "s_register_operand" "")
5032
   (match_operand:VDQX 1 "s_register_operand" "")
5033
   (match_operand:VDQX 2 "neon_logic_op2" "")
5034
   (match_operand:SI 3 "immediate_operand" "")]
5035
  "TARGET_NEON"
5036
{
5037
  emit_insn (gen_bic3_neon (operands[0], operands[1], operands[2]));
5038
  DONE;
5039
})
5040
 
5041
(define_expand "neon_vorn"
5042
  [(match_operand:VDQX 0 "s_register_operand" "")
5043
   (match_operand:VDQX 1 "s_register_operand" "")
5044
   (match_operand:VDQX 2 "neon_inv_logic_op2" "")
5045
   (match_operand:SI 3 "immediate_operand" "")]
5046
  "TARGET_NEON"
5047
{
5048
  emit_insn (gen_orn3_neon (operands[0], operands[1], operands[2]));
5049
  DONE;
5050
})

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.