1/* Description of builtins used by the ARM backend.
2   Copyright (C) 2014-2020 Free Software Foundation, Inc.
3
4   This file is part of GCC.
5
6   GCC is free software; you can redistribute it and/or modify it
7   under the terms of the GNU General Public License as published
8   by the Free Software Foundation; either version 3, or (at your
9   option) any later version.
10
11   GCC is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14   License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with GCC; see the file COPYING3.  If not see
18   <http://www.gnu.org/licenses/>.  */
19
20#define IN_TARGET_CODE 1
21
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
25#include "target.h"
26#include "function.h"
27#include "rtl.h"
28#include "tree.h"
29#include "gimple-expr.h"
30#include "memmodel.h"
31#include "tm_p.h"
32#include "profile-count.h"
33#include "optabs.h"
34#include "emit-rtl.h"
35#include "recog.h"
36#include "diagnostic-core.h"
37#include "fold-const.h"
38#include "stor-layout.h"
39#include "explow.h"
40#include "expr.h"
41#include "langhooks.h"
42#include "case-cfn-macros.h"
43#include "sbitmap.h"
44#include "stringpool.h"
45#include "arm-builtins.h"
46#include "stringpool.h"
47#include "attribs.h"
48
49#define SIMD_MAX_BUILTIN_ARGS 7
50
51enum arm_type_qualifiers
52{
53  /* T foo.  */
54  qualifier_none = 0x0,
55  /* unsigned T foo.  */
56  qualifier_unsigned = 0x1, /* 1 << 0  */
57  /* const T foo.  */
58  qualifier_const = 0x2, /* 1 << 1  */
59  /* T *foo.  */
60  qualifier_pointer = 0x4, /* 1 << 2  */
61  /* const T * foo.  */
62  qualifier_const_pointer = 0x6,
63  /* Used when expanding arguments if an operand could
64     be an immediate.  */
65  qualifier_immediate = 0x8, /* 1 << 3  */
66  qualifier_unsigned_immediate = 0x9,
67  qualifier_maybe_immediate = 0x10, /* 1 << 4  */
68  /* void foo (...).  */
69  qualifier_void = 0x20, /* 1 << 5  */
70  /* Some patterns may have internal operands, this qualifier is an
71     instruction to the initialisation code to skip this operand.  */
72  qualifier_internal = 0x40, /* 1 << 6  */
73  /* Some builtins should use the T_*mode* encoded in a simd_builtin_datum
74     rather than using the type of the operand.  */
75  qualifier_map_mode = 0x80, /* 1 << 7  */
76  /* qualifier_pointer | qualifier_map_mode  */
77  qualifier_pointer_map_mode = 0x84,
78  /* qualifier_const_pointer | qualifier_map_mode  */
79  qualifier_const_pointer_map_mode = 0x86,
80  /* Polynomial types.  */
81  qualifier_poly = 0x100,
82  /* Lane indices - must be within range of previous argument = a vector.  */
83  qualifier_lane_index = 0x200,
84  /* Lane indices for single lane structure loads and stores.  */
85  qualifier_struct_load_store_lane_index = 0x400,
86  /* A void pointer.  */
87  qualifier_void_pointer = 0x800,
88  /* A const void pointer.  */
89  qualifier_const_void_pointer = 0x802,
90  /* Lane indices selected in pairs - must be within range of previous
91     argument = a vector.  */
92  qualifier_lane_pair_index = 0x1000,
93  /* Lane indices selected in quadtuplets - must be within range of previous
94     argument = a vector.  */
95  qualifier_lane_quadtup_index = 0x2000
96};
97
98/*  The qualifier_internal allows generation of a unary builtin from
99    a pattern with a third pseudo-operand such as a match_scratch.
100    T (T).  */
101static enum arm_type_qualifiers
102arm_unop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
103  = { qualifier_none, qualifier_none, qualifier_internal };
104#define UNOP_QUALIFIERS (arm_unop_qualifiers)
105
106/* unsigned T (unsigned T).  */
107static enum arm_type_qualifiers
108arm_bswap_qualifiers[SIMD_MAX_BUILTIN_ARGS]
109  = { qualifier_unsigned, qualifier_unsigned };
110#define BSWAP_QUALIFIERS (arm_bswap_qualifiers)
111
112/* T (T, T [maybe_immediate]).  */
113static enum arm_type_qualifiers
114arm_binop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
115  = { qualifier_none, qualifier_none, qualifier_maybe_immediate };
116#define BINOP_QUALIFIERS (arm_binop_qualifiers)
117
118/* T (T, T, T).  */
119static enum arm_type_qualifiers
120arm_ternop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
121  = { qualifier_none, qualifier_none, qualifier_none, qualifier_none };
122#define TERNOP_QUALIFIERS (arm_ternop_qualifiers)
123
124/* unsigned T (unsigned T, unsigned T, unsigned T).  */
125static enum arm_type_qualifiers
126arm_unsigned_uternop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
127  = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
128      qualifier_unsigned };
129#define UTERNOP_QUALIFIERS (arm_unsigned_uternop_qualifiers)
130
131/* T (T, unsigned T, T).  */
132static enum arm_type_qualifiers
133arm_usternop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
134  = { qualifier_none, qualifier_none, qualifier_unsigned,
135      qualifier_none };
136#define USTERNOP_QUALIFIERS (arm_usternop_qualifiers)
137
138/* T (T, immediate).  */
139static enum arm_type_qualifiers
140arm_binop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
141  = { qualifier_none, qualifier_none, qualifier_immediate };
142#define BINOP_IMM_QUALIFIERS (arm_binop_imm_qualifiers)
143
144/* T (T, unsigned immediate).  */
145static enum arm_type_qualifiers
146arm_sat_binop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
147  = { qualifier_unsigned, qualifier_none, qualifier_unsigned_immediate };
148#define SAT_BINOP_UNSIGNED_IMM_QUALIFIERS \
149  (arm_sat_binop_imm_qualifiers)
150
151/* unsigned T (T, unsigned immediate).  */
152static enum arm_type_qualifiers
153arm_unsigned_sat_binop_unsigned_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
154  = { qualifier_unsigned, qualifier_none, qualifier_unsigned_immediate };
155#define UNSIGNED_SAT_BINOP_UNSIGNED_IMM_QUALIFIERS \
156  (arm_unsigned_sat_binop_unsigned_imm_qualifiers)
157
158/* T (T, lane index).  */
159static enum arm_type_qualifiers
160arm_getlane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
161  = { qualifier_none, qualifier_none, qualifier_lane_index };
162#define GETLANE_QUALIFIERS (arm_getlane_qualifiers)
163
164/* T (T, T, T, immediate).  */
165static enum arm_type_qualifiers
166arm_mac_n_qualifiers[SIMD_MAX_BUILTIN_ARGS]
167  = { qualifier_none, qualifier_none, qualifier_none,
168      qualifier_none, qualifier_immediate };
169#define MAC_N_QUALIFIERS (arm_mac_n_qualifiers)
170
171/* T (T, T, T, lane index).  */
172static enum arm_type_qualifiers
173arm_mac_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
174  = { qualifier_none, qualifier_none, qualifier_none,
175      qualifier_none, qualifier_lane_index };
176#define MAC_LANE_QUALIFIERS (arm_mac_lane_qualifiers)
177
178/* T (T, T, T, lane pair index).  */
179static enum arm_type_qualifiers
180arm_mac_lane_pair_qualifiers[SIMD_MAX_BUILTIN_ARGS]
181  = { qualifier_none, qualifier_none, qualifier_none,
182      qualifier_none, qualifier_lane_pair_index };
183#define MAC_LANE_PAIR_QUALIFIERS (arm_mac_lane_pair_qualifiers)
184
185/* unsigned T (unsigned T, unsigned T, unsigend T, lane index).  */
186static enum arm_type_qualifiers
187arm_umac_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
188  = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
189      qualifier_unsigned, qualifier_lane_index };
190#define UMAC_LANE_QUALIFIERS (arm_umac_lane_qualifiers)
191
192/* T (T, unsigned T, T, lane index).  */
193static enum arm_type_qualifiers
194arm_usmac_lane_quadtup_qualifiers[SIMD_MAX_BUILTIN_ARGS]
195  = { qualifier_none, qualifier_none, qualifier_unsigned,
196      qualifier_none, qualifier_lane_quadtup_index };
197#define USMAC_LANE_QUADTUP_QUALIFIERS (arm_usmac_lane_quadtup_qualifiers)
198
199/* T (T, T, unsigend T, lane index).  */
200static enum arm_type_qualifiers
201arm_sumac_lane_quadtup_qualifiers[SIMD_MAX_BUILTIN_ARGS]
202  = { qualifier_none, qualifier_none, qualifier_none,
203      qualifier_unsigned, qualifier_lane_quadtup_index };
204#define SUMAC_LANE_QUADTUP_QUALIFIERS (arm_sumac_lane_quadtup_qualifiers)
205
206/* T (T, T, immediate).  */
207static enum arm_type_qualifiers
208arm_ternop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
209  = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate };
210#define TERNOP_IMM_QUALIFIERS (arm_ternop_imm_qualifiers)
211
212/* T (T, T, lane index).  */
213static enum arm_type_qualifiers
214arm_setlane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
215  = { qualifier_none, qualifier_none, qualifier_none, qualifier_lane_index };
216#define SETLANE_QUALIFIERS (arm_setlane_qualifiers)
217
218/* T (T, T).  */
219static enum arm_type_qualifiers
220arm_combine_qualifiers[SIMD_MAX_BUILTIN_ARGS]
221  = { qualifier_none, qualifier_none, qualifier_none };
222#define COMBINE_QUALIFIERS (arm_combine_qualifiers)
223
224/* T ([T element type] *).  */
225static enum arm_type_qualifiers
226arm_load1_qualifiers[SIMD_MAX_BUILTIN_ARGS]
227  = { qualifier_none, qualifier_const_pointer_map_mode };
228#define LOAD1_QUALIFIERS (arm_load1_qualifiers)
229
230/* T ([T element type] *, T, immediate).  */
231static enum arm_type_qualifiers
232arm_load1_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
233  = { qualifier_none, qualifier_const_pointer_map_mode,
234      qualifier_none, qualifier_struct_load_store_lane_index };
235#define LOAD1LANE_QUALIFIERS (arm_load1_lane_qualifiers)
236
237/* unsigned T (unsigned T, unsigned T, unsigned T).  */
238static enum arm_type_qualifiers
239arm_unsigned_binop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
240  = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
241      qualifier_unsigned };
242#define UBINOP_QUALIFIERS (arm_unsigned_binop_qualifiers)
243
244/* void (unsigned immediate, unsigned immediate, unsigned immediate,
245	 unsigned immediate, unsigned immediate, unsigned immediate).  */
246static enum arm_type_qualifiers
247arm_cdp_qualifiers[SIMD_MAX_BUILTIN_ARGS]
248  = { qualifier_void, qualifier_unsigned_immediate,
249      qualifier_unsigned_immediate,
250      qualifier_unsigned_immediate,
251      qualifier_unsigned_immediate,
252      qualifier_unsigned_immediate,
253      qualifier_unsigned_immediate };
254#define CDP_QUALIFIERS \
255  (arm_cdp_qualifiers)
256
257/* void (unsigned immediate, unsigned immediate,  const void *).  */
258static enum arm_type_qualifiers
259arm_ldc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
260  = { qualifier_void, qualifier_unsigned_immediate,
261      qualifier_unsigned_immediate, qualifier_const_void_pointer };
262#define LDC_QUALIFIERS \
263  (arm_ldc_qualifiers)
264
265/* void (unsigned immediate, unsigned immediate,  void *).  */
266static enum arm_type_qualifiers
267arm_stc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
268  = { qualifier_void, qualifier_unsigned_immediate,
269      qualifier_unsigned_immediate, qualifier_void_pointer };
270#define STC_QUALIFIERS \
271  (arm_stc_qualifiers)
272
273/* void (unsigned immediate, unsigned immediate,  T, unsigned immediate,
274	 unsigned immediate, unsigned immediate).  */
275static enum arm_type_qualifiers
276arm_mcr_qualifiers[SIMD_MAX_BUILTIN_ARGS]
277  = { qualifier_void, qualifier_unsigned_immediate,
278      qualifier_unsigned_immediate, qualifier_none,
279      qualifier_unsigned_immediate, qualifier_unsigned_immediate,
280      qualifier_unsigned_immediate };
281#define MCR_QUALIFIERS \
282  (arm_mcr_qualifiers)
283
284/* T (unsigned immediate, unsigned immediate, unsigned immediate,
285      unsigned immediate, unsigned immediate).  */
286static enum arm_type_qualifiers
287arm_mrc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
288  = { qualifier_none, qualifier_unsigned_immediate,
289      qualifier_unsigned_immediate, qualifier_unsigned_immediate,
290      qualifier_unsigned_immediate, qualifier_unsigned_immediate };
291#define MRC_QUALIFIERS \
292  (arm_mrc_qualifiers)
293
294/* void (unsigned immediate, unsigned immediate,  T, unsigned immediate).  */
295static enum arm_type_qualifiers
296arm_mcrr_qualifiers[SIMD_MAX_BUILTIN_ARGS]
297  = { qualifier_void, qualifier_unsigned_immediate,
298      qualifier_unsigned_immediate, qualifier_none,
299      qualifier_unsigned_immediate };
300#define MCRR_QUALIFIERS \
301  (arm_mcrr_qualifiers)
302
303/* T (unsigned immediate, unsigned immediate, unsigned immediate).  */
304static enum arm_type_qualifiers
305arm_mrrc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
306  = { qualifier_none, qualifier_unsigned_immediate,
307      qualifier_unsigned_immediate, qualifier_unsigned_immediate };
308#define MRRC_QUALIFIERS \
309  (arm_mrrc_qualifiers)
310
311/* T (immediate, unsigned immediate).  */
312static enum arm_type_qualifiers
313arm_cx_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
314  = { qualifier_none, qualifier_immediate, qualifier_unsigned_immediate };
315#define CX_IMM_QUALIFIERS (arm_cx_imm_qualifiers)
316
317/* T (immediate, T, unsigned immediate).  */
318static enum arm_type_qualifiers
319arm_cx_unary_qualifiers[SIMD_MAX_BUILTIN_ARGS]
320  = { qualifier_none, qualifier_immediate, qualifier_none,
321      qualifier_unsigned_immediate };
322#define CX_UNARY_QUALIFIERS (arm_cx_unary_qualifiers)
323
324/* T (immediate, T, T, unsigned immediate).  */
325static enum arm_type_qualifiers
326arm_cx_binary_qualifiers[SIMD_MAX_BUILTIN_ARGS]
327  = { qualifier_none, qualifier_immediate,
328      qualifier_none, qualifier_none,
329      qualifier_unsigned_immediate };
330#define CX_BINARY_QUALIFIERS (arm_cx_binary_qualifiers)
331
332/* T (immediate, T, T, T, unsigned immediate).  */
333static enum arm_type_qualifiers
334arm_cx_ternary_qualifiers[SIMD_MAX_BUILTIN_ARGS]
335  = { qualifier_none, qualifier_immediate,
336      qualifier_none, qualifier_none, qualifier_none,
337      qualifier_unsigned_immediate };
338#define CX_TERNARY_QUALIFIERS (arm_cx_ternary_qualifiers)
339
340/* T (immediate, T, unsigned immediate).  */
341static enum arm_type_qualifiers
342arm_cx_unary_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
343  = { qualifier_none, qualifier_immediate, qualifier_none,
344      qualifier_unsigned_immediate,
345      qualifier_unsigned };
346#define CX_UNARY_UNONE_QUALIFIERS (arm_cx_unary_unone_qualifiers)
347
348/* T (immediate, T, T, unsigned immediate).  */
349static enum arm_type_qualifiers
350arm_cx_binary_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
351  = { qualifier_none, qualifier_immediate,
352      qualifier_none, qualifier_none,
353      qualifier_unsigned_immediate,
354      qualifier_unsigned };
355#define CX_BINARY_UNONE_QUALIFIERS (arm_cx_binary_unone_qualifiers)
356
357/* T (immediate, T, T, T, unsigned immediate).  */
358static enum arm_type_qualifiers
359arm_cx_ternary_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
360  = { qualifier_none, qualifier_immediate,
361      qualifier_none, qualifier_none, qualifier_none,
362      qualifier_unsigned_immediate,
363      qualifier_unsigned };
364#define CX_TERNARY_UNONE_QUALIFIERS (arm_cx_ternary_unone_qualifiers)
365
366/* The first argument (return type) of a store should be void type,
367   which we represent with qualifier_void.  Their first operand will be
368   a DImode pointer to the location to store to, so we must use
369   qualifier_map_mode | qualifier_pointer to build a pointer to the
370   element type of the vector.
371
372   void ([T element type] *, T).  */
373static enum arm_type_qualifiers
374arm_store1_qualifiers[SIMD_MAX_BUILTIN_ARGS]
375  = { qualifier_void, qualifier_pointer_map_mode, qualifier_none };
376#define STORE1_QUALIFIERS (arm_store1_qualifiers)
377
378/* Qualifiers for MVE builtins.  */
379
380static enum arm_type_qualifiers
381arm_unop_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
382  = { qualifier_none, qualifier_none };
383#define UNOP_NONE_NONE_QUALIFIERS \
384  (arm_unop_none_none_qualifiers)
385
386static enum arm_type_qualifiers
387arm_unop_none_snone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
388  = { qualifier_none, qualifier_none };
389#define UNOP_NONE_SNONE_QUALIFIERS \
390  (arm_unop_none_snone_qualifiers)
391
392static enum arm_type_qualifiers
393arm_unop_none_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
394  = { qualifier_none, qualifier_unsigned };
395#define UNOP_NONE_UNONE_QUALIFIERS \
396  (arm_unop_none_unone_qualifiers)
397
398static enum arm_type_qualifiers
399arm_unop_snone_snone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
400  = { qualifier_none, qualifier_none };
401#define UNOP_SNONE_SNONE_QUALIFIERS \
402  (arm_unop_snone_snone_qualifiers)
403
404static enum arm_type_qualifiers
405arm_unop_snone_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
406  = { qualifier_none, qualifier_none };
407#define UNOP_SNONE_NONE_QUALIFIERS \
408  (arm_unop_snone_none_qualifiers)
409
410static enum arm_type_qualifiers
411arm_unop_snone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
412  = { qualifier_none, qualifier_immediate };
413#define UNOP_SNONE_IMM_QUALIFIERS \
414  (arm_unop_snone_imm_qualifiers)
415
416static enum arm_type_qualifiers
417arm_unop_unone_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
418  = { qualifier_unsigned, qualifier_none };
419#define UNOP_UNONE_NONE_QUALIFIERS \
420  (arm_unop_unone_none_qualifiers)
421
422static enum arm_type_qualifiers
423arm_unop_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
424  = { qualifier_unsigned, qualifier_unsigned };
425#define UNOP_UNONE_UNONE_QUALIFIERS \
426  (arm_unop_unone_unone_qualifiers)
427
428static enum arm_type_qualifiers
429arm_unop_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
430  = { qualifier_unsigned, qualifier_immediate };
431#define UNOP_UNONE_IMM_QUALIFIERS \
432  (arm_unop_unone_imm_qualifiers)
433
434static enum arm_type_qualifiers
435arm_binop_none_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
436  = { qualifier_none, qualifier_none, qualifier_none };
437#define BINOP_NONE_NONE_NONE_QUALIFIERS \
438  (arm_binop_none_none_none_qualifiers)
439
440static enum arm_type_qualifiers
441arm_binop_none_none_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
442  = { qualifier_none, qualifier_none, qualifier_immediate };
443#define BINOP_NONE_NONE_IMM_QUALIFIERS \
444  (arm_binop_none_none_imm_qualifiers)
445
446static enum arm_type_qualifiers
447arm_binop_none_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
448  = { qualifier_none, qualifier_unsigned, qualifier_immediate };
449#define BINOP_NONE_UNONE_IMM_QUALIFIERS \
450  (arm_binop_none_unone_imm_qualifiers)
451
452static enum arm_type_qualifiers
453arm_binop_none_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
454  = { qualifier_none, qualifier_unsigned, qualifier_unsigned };
455#define BINOP_NONE_UNONE_UNONE_QUALIFIERS \
456  (arm_binop_none_unone_unone_qualifiers)
457
458static enum arm_type_qualifiers
459arm_binop_unone_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
460  = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate };
461#define BINOP_UNONE_UNONE_IMM_QUALIFIERS \
462  (arm_binop_unone_unone_imm_qualifiers)
463
464static enum arm_type_qualifiers
465arm_binop_unone_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
466  = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned };
467#define BINOP_UNONE_UNONE_UNONE_QUALIFIERS \
468  (arm_binop_unone_unone_unone_qualifiers)
469
470static enum arm_type_qualifiers
471arm_binop_unone_none_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
472  = { qualifier_unsigned, qualifier_none, qualifier_immediate };
473#define BINOP_UNONE_NONE_IMM_QUALIFIERS \
474  (arm_binop_unone_none_imm_qualifiers)
475
476static enum arm_type_qualifiers
477arm_binop_none_none_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
478  = { qualifier_none, qualifier_none, qualifier_unsigned };
479#define BINOP_NONE_NONE_UNONE_QUALIFIERS \
480  (arm_binop_none_none_unone_qualifiers)
481
482static enum arm_type_qualifiers
483arm_binop_unone_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
484  = { qualifier_unsigned, qualifier_none, qualifier_none };
485#define BINOP_UNONE_NONE_NONE_QUALIFIERS \
486  (arm_binop_unone_none_none_qualifiers)
487
488static enum arm_type_qualifiers
489arm_binop_unone_unone_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
490  = { qualifier_unsigned, qualifier_unsigned, qualifier_none };
491#define BINOP_UNONE_UNONE_NONE_QUALIFIERS \
492  (arm_binop_unone_unone_none_qualifiers)
493
494static enum arm_type_qualifiers
495arm_ternop_unone_unone_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
496  = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
497    qualifier_immediate };
498#define TERNOP_UNONE_UNONE_UNONE_IMM_QUALIFIERS \
499  (arm_ternop_unone_unone_unone_imm_qualifiers)
500
501static enum arm_type_qualifiers
502arm_ternop_unone_unone_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
503  = { qualifier_unsigned, qualifier_unsigned, qualifier_none, qualifier_none };
504#define TERNOP_UNONE_UNONE_NONE_NONE_QUALIFIERS \
505  (arm_ternop_unone_unone_none_none_qualifiers)
506
507static enum arm_type_qualifiers
508arm_ternop_unone_none_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
509  = { qualifier_unsigned, qualifier_none, qualifier_unsigned,
510      qualifier_immediate };
511#define TERNOP_UNONE_NONE_UNONE_IMM_QUALIFIERS \
512  (arm_ternop_unone_none_unone_imm_qualifiers)
513
514static enum arm_type_qualifiers
515arm_ternop_none_none_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
516  = { qualifier_none, qualifier_none, qualifier_unsigned, qualifier_immediate };
517#define TERNOP_NONE_NONE_UNONE_IMM_QUALIFIERS \
518  (arm_ternop_none_none_unone_imm_qualifiers)
519
520static enum arm_type_qualifiers
521arm_ternop_unone_unone_none_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
522  = { qualifier_unsigned, qualifier_unsigned, qualifier_none,
523    qualifier_immediate };
524#define TERNOP_UNONE_UNONE_NONE_IMM_QUALIFIERS \
525  (arm_ternop_unone_unone_none_imm_qualifiers)
526
527static enum arm_type_qualifiers
528arm_ternop_unone_unone_none_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
529  = { qualifier_unsigned, qualifier_unsigned, qualifier_none,
530      qualifier_unsigned };
531#define TERNOP_UNONE_UNONE_NONE_UNONE_QUALIFIERS \
532  (arm_ternop_unone_unone_none_unone_qualifiers)
533
534static enum arm_type_qualifiers
535arm_ternop_unone_unone_imm_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
536  = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate,
537    qualifier_unsigned };
538#define TERNOP_UNONE_UNONE_IMM_UNONE_QUALIFIERS \
539  (arm_ternop_unone_unone_imm_unone_qualifiers)
540
541static enum arm_type_qualifiers
542arm_ternop_unone_none_none_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
543  = { qualifier_unsigned, qualifier_none, qualifier_none, qualifier_unsigned };
544#define TERNOP_UNONE_NONE_NONE_UNONE_QUALIFIERS \
545  (arm_ternop_unone_none_none_unone_qualifiers)
546
547static enum arm_type_qualifiers
548arm_ternop_none_none_none_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
549  = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate };
550#define TERNOP_NONE_NONE_NONE_IMM_QUALIFIERS \
551  (arm_ternop_none_none_none_imm_qualifiers)
552
553static enum arm_type_qualifiers
554arm_ternop_none_none_none_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
555  = { qualifier_none, qualifier_none, qualifier_none, qualifier_unsigned };
556#define TERNOP_NONE_NONE_NONE_UNONE_QUALIFIERS \
557  (arm_ternop_none_none_none_unone_qualifiers)
558
559static enum arm_type_qualifiers
560arm_ternop_none_none_imm_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
561  = { qualifier_none, qualifier_none, qualifier_immediate, qualifier_unsigned };
562#define TERNOP_NONE_NONE_IMM_UNONE_QUALIFIERS \
563  (arm_ternop_none_none_imm_unone_qualifiers)
564
565static enum arm_type_qualifiers
566arm_ternop_none_none_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
567  = { qualifier_none, qualifier_none, qualifier_unsigned, qualifier_unsigned };
568#define TERNOP_NONE_NONE_UNONE_UNONE_QUALIFIERS \
569  (arm_ternop_none_none_unone_unone_qualifiers)
570
571static enum arm_type_qualifiers
572arm_ternop_unone_unone_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
573  = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
574    qualifier_unsigned };
575#define TERNOP_UNONE_UNONE_UNONE_UNONE_QUALIFIERS \
576  (arm_ternop_unone_unone_unone_unone_qualifiers)
577
578static enum arm_type_qualifiers
579arm_ternop_none_none_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
580  = { qualifier_none, qualifier_none, qualifier_none, qualifier_none };
581#define TERNOP_NONE_NONE_NONE_NONE_QUALIFIERS \
582  (arm_ternop_none_none_none_none_qualifiers)
583
584static enum arm_type_qualifiers
585arm_quadop_unone_unone_none_none_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
586  = { qualifier_unsigned, qualifier_unsigned, qualifier_none, qualifier_none,
587    qualifier_unsigned };
588#define QUADOP_UNONE_UNONE_NONE_NONE_UNONE_QUALIFIERS \
589  (arm_quadop_unone_unone_none_none_unone_qualifiers)
590
591static enum arm_type_qualifiers
592arm_quadop_none_none_none_none_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
593  = { qualifier_none, qualifier_none, qualifier_none, qualifier_none,
594    qualifier_unsigned };
595#define QUADOP_NONE_NONE_NONE_NONE_UNONE_QUALIFIERS \
596  (arm_quadop_none_none_none_none_unone_qualifiers)
597
598static enum arm_type_qualifiers
599arm_quadop_none_none_none_imm_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
600  = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate,
601    qualifier_unsigned };
602#define QUADOP_NONE_NONE_NONE_IMM_UNONE_QUALIFIERS \
603  (arm_quadop_none_none_none_imm_unone_qualifiers)
604
605static enum arm_type_qualifiers
606arm_quadop_unone_unone_unone_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
607  = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
608    qualifier_unsigned, qualifier_unsigned };
609#define QUADOP_UNONE_UNONE_UNONE_UNONE_UNONE_QUALIFIERS \
610  (arm_quadop_unone_unone_unone_unone_unone_qualifiers)
611
612static enum arm_type_qualifiers
613arm_quadop_unone_unone_none_imm_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
614  = { qualifier_unsigned, qualifier_unsigned, qualifier_none,
615    qualifier_immediate, qualifier_unsigned };
616#define QUADOP_UNONE_UNONE_NONE_IMM_UNONE_QUALIFIERS \
617  (arm_quadop_unone_unone_none_imm_unone_qualifiers)
618
619static enum arm_type_qualifiers
620arm_quadop_none_none_unone_imm_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
621  = { qualifier_none, qualifier_none, qualifier_unsigned, qualifier_immediate,
622    qualifier_unsigned };
623#define QUADOP_NONE_NONE_UNONE_IMM_UNONE_QUALIFIERS \
624  (arm_quadop_none_none_unone_imm_unone_qualifiers)
625
626static enum arm_type_qualifiers
627arm_quadop_unone_unone_unone_imm_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
628  = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
629    qualifier_immediate, qualifier_unsigned };
630#define QUADOP_UNONE_UNONE_UNONE_IMM_UNONE_QUALIFIERS \
631  (arm_quadop_unone_unone_unone_imm_unone_qualifiers)
632
633static enum arm_type_qualifiers
634arm_quadop_unone_unone_unone_none_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
635  = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
636    qualifier_none, qualifier_unsigned };
637#define QUADOP_UNONE_UNONE_UNONE_NONE_UNONE_QUALIFIERS \
638  (arm_quadop_unone_unone_unone_none_unone_qualifiers)
639
640static enum arm_type_qualifiers
641arm_strs_qualifiers[SIMD_MAX_BUILTIN_ARGS]
642  = { qualifier_void, qualifier_pointer, qualifier_none };
643#define STRS_QUALIFIERS (arm_strs_qualifiers)
644
645static enum arm_type_qualifiers
646arm_stru_qualifiers[SIMD_MAX_BUILTIN_ARGS]
647  = { qualifier_void, qualifier_pointer, qualifier_unsigned };
648#define STRU_QUALIFIERS (arm_stru_qualifiers)
649
650static enum arm_type_qualifiers
651arm_strss_qualifiers[SIMD_MAX_BUILTIN_ARGS]
652  = { qualifier_void, qualifier_pointer, qualifier_unsigned,
653      qualifier_none};
654#define STRSS_QUALIFIERS (arm_strss_qualifiers)
655
656static enum arm_type_qualifiers
657arm_strsu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
658  = { qualifier_void, qualifier_pointer, qualifier_unsigned,
659      qualifier_unsigned};
660#define STRSU_QUALIFIERS (arm_strsu_qualifiers)
661
662static enum arm_type_qualifiers
663arm_strsbs_qualifiers[SIMD_MAX_BUILTIN_ARGS]
664  = { qualifier_void, qualifier_unsigned, qualifier_immediate, qualifier_none};
665#define STRSBS_QUALIFIERS (arm_strsbs_qualifiers)
666
667static enum arm_type_qualifiers
668arm_strsbu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
669  = { qualifier_void, qualifier_unsigned, qualifier_immediate,
670      qualifier_unsigned};
671#define STRSBU_QUALIFIERS (arm_strsbu_qualifiers)
672
673static enum arm_type_qualifiers
674arm_strs_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
675  = { qualifier_void, qualifier_pointer, qualifier_none, qualifier_unsigned};
676#define STRS_P_QUALIFIERS (arm_strs_p_qualifiers)
677
678static enum arm_type_qualifiers
679arm_stru_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
680  = { qualifier_void, qualifier_pointer, qualifier_unsigned,
681      qualifier_unsigned};
682#define STRU_P_QUALIFIERS (arm_stru_p_qualifiers)
683
684static enum arm_type_qualifiers
685arm_strsu_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
686  = { qualifier_void, qualifier_pointer, qualifier_unsigned,
687      qualifier_unsigned, qualifier_unsigned};
688#define STRSU_P_QUALIFIERS (arm_strsu_p_qualifiers)
689
690static enum arm_type_qualifiers
691arm_strss_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
692  = { qualifier_void, qualifier_pointer, qualifier_unsigned,
693      qualifier_none, qualifier_unsigned};
694#define STRSS_P_QUALIFIERS (arm_strss_p_qualifiers)
695
696static enum arm_type_qualifiers
697arm_strsbs_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
698  = { qualifier_void, qualifier_unsigned, qualifier_immediate,
699      qualifier_none, qualifier_unsigned};
700#define STRSBS_P_QUALIFIERS (arm_strsbs_p_qualifiers)
701
702static enum arm_type_qualifiers
703arm_strsbu_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
704  = { qualifier_void, qualifier_unsigned, qualifier_immediate,
705      qualifier_unsigned, qualifier_unsigned};
706#define STRSBU_P_QUALIFIERS (arm_strsbu_p_qualifiers)
707
708static enum arm_type_qualifiers
709arm_ldrgu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
710  = { qualifier_unsigned, qualifier_pointer, qualifier_unsigned};
711#define LDRGU_QUALIFIERS (arm_ldrgu_qualifiers)
712
713static enum arm_type_qualifiers
714arm_ldrgs_qualifiers[SIMD_MAX_BUILTIN_ARGS]
715  = { qualifier_none, qualifier_pointer, qualifier_unsigned};
716#define LDRGS_QUALIFIERS (arm_ldrgs_qualifiers)
717
718static enum arm_type_qualifiers
719arm_ldrs_qualifiers[SIMD_MAX_BUILTIN_ARGS]
720  = { qualifier_none, qualifier_pointer};
721#define LDRS_QUALIFIERS (arm_ldrs_qualifiers)
722
723static enum arm_type_qualifiers
724arm_ldru_qualifiers[SIMD_MAX_BUILTIN_ARGS]
725  = { qualifier_unsigned, qualifier_pointer};
726#define LDRU_QUALIFIERS (arm_ldru_qualifiers)
727
728static enum arm_type_qualifiers
729arm_ldrgbs_qualifiers[SIMD_MAX_BUILTIN_ARGS]
730  = { qualifier_none, qualifier_unsigned, qualifier_immediate};
731#define LDRGBS_QUALIFIERS (arm_ldrgbs_qualifiers)
732
733static enum arm_type_qualifiers
734arm_ldrgbu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
735  = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate};
736#define LDRGBU_QUALIFIERS (arm_ldrgbu_qualifiers)
737
738static enum arm_type_qualifiers
739arm_ldrgbs_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
740  = { qualifier_none, qualifier_unsigned, qualifier_immediate,
741      qualifier_unsigned};
742#define LDRGBS_Z_QUALIFIERS (arm_ldrgbs_z_qualifiers)
743
744static enum arm_type_qualifiers
745arm_ldrgbu_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
746  = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate,
747      qualifier_unsigned};
748#define LDRGBU_Z_QUALIFIERS (arm_ldrgbu_z_qualifiers)
749
750static enum arm_type_qualifiers
751arm_ldrgs_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
752  = { qualifier_none, qualifier_pointer, qualifier_unsigned,
753      qualifier_unsigned};
754#define LDRGS_Z_QUALIFIERS (arm_ldrgs_z_qualifiers)
755
756static enum arm_type_qualifiers
757arm_ldrgu_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
758  = { qualifier_unsigned, qualifier_pointer, qualifier_unsigned,
759      qualifier_unsigned};
760#define LDRGU_Z_QUALIFIERS (arm_ldrgu_z_qualifiers)
761
762static enum arm_type_qualifiers
763arm_ldrs_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
764  = { qualifier_none, qualifier_pointer, qualifier_unsigned};
765#define LDRS_Z_QUALIFIERS (arm_ldrs_z_qualifiers)
766
767static enum arm_type_qualifiers
768arm_ldru_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
769  = { qualifier_unsigned, qualifier_pointer, qualifier_unsigned};
770#define LDRU_Z_QUALIFIERS (arm_ldru_z_qualifiers)
771
772static enum arm_type_qualifiers
773arm_quinop_unone_unone_unone_unone_imm_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
774  = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
775      qualifier_unsigned, qualifier_immediate, qualifier_unsigned };
776#define QUINOP_UNONE_UNONE_UNONE_UNONE_IMM_UNONE_QUALIFIERS \
777  (arm_quinop_unone_unone_unone_unone_imm_unone_qualifiers)
778
779static enum arm_type_qualifiers
780arm_ldrgbwbxu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
781  = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate};
782#define LDRGBWBXU_QUALIFIERS (arm_ldrgbwbxu_qualifiers)
783
784static enum arm_type_qualifiers
785arm_ldrgbwbxu_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
786  = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate,
787      qualifier_unsigned};
788#define LDRGBWBXU_Z_QUALIFIERS (arm_ldrgbwbxu_z_qualifiers)
789
790static enum arm_type_qualifiers
791arm_ldrgbwbs_qualifiers[SIMD_MAX_BUILTIN_ARGS]
792  = { qualifier_none, qualifier_unsigned, qualifier_immediate};
793#define LDRGBWBS_QUALIFIERS (arm_ldrgbwbs_qualifiers)
794
795static enum arm_type_qualifiers
796arm_ldrgbwbu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
797  = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate};
798#define LDRGBWBU_QUALIFIERS (arm_ldrgbwbu_qualifiers)
799
800static enum arm_type_qualifiers
801arm_ldrgbwbs_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
802  = { qualifier_none, qualifier_unsigned, qualifier_immediate,
803      qualifier_unsigned};
804#define LDRGBWBS_Z_QUALIFIERS (arm_ldrgbwbs_z_qualifiers)
805
806static enum arm_type_qualifiers
807arm_ldrgbwbu_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
808  = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate,
809      qualifier_unsigned};
810#define LDRGBWBU_Z_QUALIFIERS (arm_ldrgbwbu_z_qualifiers)
811
812static enum arm_type_qualifiers
813arm_strsbwbs_qualifiers[SIMD_MAX_BUILTIN_ARGS]
814  = { qualifier_unsigned, qualifier_unsigned, qualifier_const, qualifier_none};
815#define STRSBWBS_QUALIFIERS (arm_strsbwbs_qualifiers)
816
817static enum arm_type_qualifiers
818arm_strsbwbu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
819  = { qualifier_unsigned, qualifier_unsigned, qualifier_const, qualifier_unsigned};
820#define STRSBWBU_QUALIFIERS (arm_strsbwbu_qualifiers)
821
822static enum arm_type_qualifiers
823arm_strsbwbs_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
824  = { qualifier_unsigned, qualifier_unsigned, qualifier_const,
825      qualifier_none, qualifier_unsigned};
826#define STRSBWBS_P_QUALIFIERS (arm_strsbwbs_p_qualifiers)
827
828static enum arm_type_qualifiers
829arm_strsbwbu_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
830  = { qualifier_unsigned, qualifier_unsigned, qualifier_const,
831      qualifier_unsigned, qualifier_unsigned};
832#define STRSBWBU_P_QUALIFIERS (arm_strsbwbu_p_qualifiers)
833
834static enum arm_type_qualifiers
835arm_lsll_qualifiers[SIMD_MAX_BUILTIN_ARGS]
836  = { qualifier_unsigned, qualifier_unsigned, qualifier_none};
837#define LSLL_QUALIFIERS (arm_lsll_qualifiers)
838
839static enum arm_type_qualifiers
840arm_uqshl_qualifiers[SIMD_MAX_BUILTIN_ARGS]
841  = { qualifier_unsigned, qualifier_unsigned, qualifier_const};
842#define UQSHL_QUALIFIERS (arm_uqshl_qualifiers)
843
844static enum arm_type_qualifiers
845arm_asrl_qualifiers[SIMD_MAX_BUILTIN_ARGS]
846  = { qualifier_none, qualifier_none, qualifier_none};
847#define ASRL_QUALIFIERS (arm_asrl_qualifiers)
848
849static enum arm_type_qualifiers
850arm_sqshl_qualifiers[SIMD_MAX_BUILTIN_ARGS]
851  = { qualifier_unsigned, qualifier_unsigned, qualifier_const};
852#define SQSHL_QUALIFIERS (arm_sqshl_qualifiers)
853
854/* End of Qualifier for MVE builtins.  */
855
856   /* void ([T element type] *, T, immediate).  */
857static enum arm_type_qualifiers
858arm_storestruct_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
859  = { qualifier_void, qualifier_pointer_map_mode,
860      qualifier_none, qualifier_struct_load_store_lane_index };
861#define STORE1LANE_QUALIFIERS (arm_storestruct_lane_qualifiers)
862
863   /* int (void).  */
864static enum arm_type_qualifiers
865arm_sat_occurred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
866  = { qualifier_none, qualifier_void };
867#define SAT_OCCURRED_QUALIFIERS (arm_sat_occurred_qualifiers)
868
869   /* void (int).  */
870static enum arm_type_qualifiers
871arm_set_sat_qualifiers[SIMD_MAX_BUILTIN_ARGS]
872  = { qualifier_void, qualifier_none };
873#define SET_SAT_QUALIFIERS (arm_set_sat_qualifiers)
874
875#define v8qi_UP  E_V8QImode
876#define v4hi_UP  E_V4HImode
877#define v4hf_UP  E_V4HFmode
878#define v4bf_UP  E_V4BFmode
879#define v2si_UP  E_V2SImode
880#define v2sf_UP  E_V2SFmode
881#define v2bf_UP  E_V2BFmode
882#define di_UP    E_DImode
883#define v16qi_UP E_V16QImode
884#define v8hi_UP  E_V8HImode
885#define v8hf_UP  E_V8HFmode
886#define v8bf_UP  E_V8BFmode
887#define v4si_UP  E_V4SImode
888#define v4sf_UP  E_V4SFmode
889#define v2di_UP  E_V2DImode
890#define ti_UP	 E_TImode
891#define ei_UP	 E_EImode
892#define oi_UP	 E_OImode
893#define hf_UP	 E_HFmode
894#define bf_UP    E_BFmode
895#define si_UP	 E_SImode
896#define hi_UP    E_HImode
897#define void_UP	 E_VOIDmode
898#define sf_UP	 E_SFmode
899#define UP(X) X##_UP
900
901typedef struct {
902  const char *name;
903  machine_mode mode;
904  const enum insn_code code;
905  unsigned int fcode;
906  enum arm_type_qualifiers *qualifiers;
907} arm_builtin_datum;
908
909#define CF(N,X) CODE_FOR_neon_##N##X
910
911#define VAR1(T, N, A) \
912  {#N #A, UP (A), CF (N, A), 0, T##_QUALIFIERS},
913#define VAR2(T, N, A, B) \
914  VAR1 (T, N, A) \
915  VAR1 (T, N, B)
916#define VAR3(T, N, A, B, C) \
917  VAR2 (T, N, A, B) \
918  VAR1 (T, N, C)
919#define VAR4(T, N, A, B, C, D) \
920  VAR3 (T, N, A, B, C) \
921  VAR1 (T, N, D)
922#define VAR5(T, N, A, B, C, D, E) \
923  VAR4 (T, N, A, B, C, D) \
924  VAR1 (T, N, E)
925#define VAR6(T, N, A, B, C, D, E, F) \
926  VAR5 (T, N, A, B, C, D, E) \
927  VAR1 (T, N, F)
928#define VAR7(T, N, A, B, C, D, E, F, G) \
929  VAR6 (T, N, A, B, C, D, E, F) \
930  VAR1 (T, N, G)
931#define VAR8(T, N, A, B, C, D, E, F, G, H) \
932  VAR7 (T, N, A, B, C, D, E, F, G) \
933  VAR1 (T, N, H)
934#define VAR9(T, N, A, B, C, D, E, F, G, H, I) \
935  VAR8 (T, N, A, B, C, D, E, F, G, H) \
936  VAR1 (T, N, I)
937#define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \
938  VAR9 (T, N, A, B, C, D, E, F, G, H, I) \
939  VAR1 (T, N, J)
940#define VAR11(T, N, A, B, C, D, E, F, G, H, I, J, K) \
941  VAR10 (T, N, A, B, C, D, E, F, G, H, I, J) \
942  VAR1 (T, N, K)
943#define VAR12(T, N, A, B, C, D, E, F, G, H, I, J, K, L) \
944  VAR11 (T, N, A, B, C, D, E, F, G, H, I, J, K) \
945  VAR1 (T, N, L)
946#define VAR13(T, N, A, B, C, D, E, F, G, H, I, J, K, L, M) \
947  VAR12 (T, N, A, B, C, D, E, F, G, H, I, J, K, L) \
948  VAR1 (T, N, M)
949#define VAR14(T, N, A, B, C, D, E, F, G, H, I, J, K, L, M, O) \
950  VAR13 (T, N, A, B, C, D, E, F, G, H, I, J, K, L, M) \
951  VAR1 (T, N, O)
952
953/* The builtin data can be found in arm_neon_builtins.def, arm_vfp_builtins.def
954   and arm_acle_builtins.def.  The entries in arm_neon_builtins.def require
955   TARGET_NEON to be true.  The feature tests are checked when the builtins are
956   expanded.
957
958   The mode entries in the following table correspond to the "key" type of the
959   instruction variant, i.e. equivalent to that which would be specified after
960   the assembler mnemonic for neon instructions, which usually refers to the
961   last vector operand.  The modes listed per instruction should be the same as
962   those defined for that instruction's pattern, for instance in neon.md.  */
963
964static arm_builtin_datum vfp_builtin_data[] =
965{
966#include "arm_vfp_builtins.def"
967};
968
969static arm_builtin_datum neon_builtin_data[] =
970{
971#include "arm_neon_builtins.def"
972};
973
974#undef CF
975#define CF(N,X) CODE_FOR_mve_##N##X
976static arm_builtin_datum mve_builtin_data[] =
977{
978#include "arm_mve_builtins.def"
979};
980
981#undef CF
982#undef VAR1
983#define VAR1(T, N, A) \
984  {#N, UP (A), CODE_FOR_arm_##N, 0, T##_QUALIFIERS},
985
986static arm_builtin_datum acle_builtin_data[] =
987{
988#include "arm_acle_builtins.def"
989};
990
991#undef VAR1
992/* IMM_MAX sets the maximum valid value of the CDE immediate operand.
993   ECF_FLAG sets the flag used for set_call_expr_flags.  */
994#define VAR1(T, N, A, IMM_MAX, ECF_FLAG) \
995  {{#N #A, UP (A), CODE_FOR_arm_##N##A, 0, T##_QUALIFIERS}, IMM_MAX, ECF_FLAG},
996
997typedef struct {
998  arm_builtin_datum base;
999  unsigned int imm_max;
1000  int ecf_flag;
1001} arm_builtin_cde_datum;
1002
1003static arm_builtin_cde_datum cde_builtin_data[] =
1004{
1005#include "arm_cde_builtins.def"
1006};
1007
1008#undef VAR1
1009#define VAR1(T, N, X) \
1010  ARM_BUILTIN_NEON_##N##X,
1011
1012enum arm_builtins
1013{
1014  ARM_BUILTIN_GETWCGR0,
1015  ARM_BUILTIN_GETWCGR1,
1016  ARM_BUILTIN_GETWCGR2,
1017  ARM_BUILTIN_GETWCGR3,
1018
1019  ARM_BUILTIN_SETWCGR0,
1020  ARM_BUILTIN_SETWCGR1,
1021  ARM_BUILTIN_SETWCGR2,
1022  ARM_BUILTIN_SETWCGR3,
1023
1024  ARM_BUILTIN_WZERO,
1025
1026  ARM_BUILTIN_WAVG2BR,
1027  ARM_BUILTIN_WAVG2HR,
1028  ARM_BUILTIN_WAVG2B,
1029  ARM_BUILTIN_WAVG2H,
1030
1031  ARM_BUILTIN_WACCB,
1032  ARM_BUILTIN_WACCH,
1033  ARM_BUILTIN_WACCW,
1034
1035  ARM_BUILTIN_WMACS,
1036  ARM_BUILTIN_WMACSZ,
1037  ARM_BUILTIN_WMACU,
1038  ARM_BUILTIN_WMACUZ,
1039
1040  ARM_BUILTIN_WSADB,
1041  ARM_BUILTIN_WSADBZ,
1042  ARM_BUILTIN_WSADH,
1043  ARM_BUILTIN_WSADHZ,
1044
1045  ARM_BUILTIN_WALIGNI,
1046  ARM_BUILTIN_WALIGNR0,
1047  ARM_BUILTIN_WALIGNR1,
1048  ARM_BUILTIN_WALIGNR2,
1049  ARM_BUILTIN_WALIGNR3,
1050
1051  ARM_BUILTIN_TMIA,
1052  ARM_BUILTIN_TMIAPH,
1053  ARM_BUILTIN_TMIABB,
1054  ARM_BUILTIN_TMIABT,
1055  ARM_BUILTIN_TMIATB,
1056  ARM_BUILTIN_TMIATT,
1057
1058  ARM_BUILTIN_TMOVMSKB,
1059  ARM_BUILTIN_TMOVMSKH,
1060  ARM_BUILTIN_TMOVMSKW,
1061
1062  ARM_BUILTIN_TBCSTB,
1063  ARM_BUILTIN_TBCSTH,
1064  ARM_BUILTIN_TBCSTW,
1065
1066  ARM_BUILTIN_WMADDS,
1067  ARM_BUILTIN_WMADDU,
1068
1069  ARM_BUILTIN_WPACKHSS,
1070  ARM_BUILTIN_WPACKWSS,
1071  ARM_BUILTIN_WPACKDSS,
1072  ARM_BUILTIN_WPACKHUS,
1073  ARM_BUILTIN_WPACKWUS,
1074  ARM_BUILTIN_WPACKDUS,
1075
1076  ARM_BUILTIN_WADDB,
1077  ARM_BUILTIN_WADDH,
1078  ARM_BUILTIN_WADDW,
1079  ARM_BUILTIN_WADDSSB,
1080  ARM_BUILTIN_WADDSSH,
1081  ARM_BUILTIN_WADDSSW,
1082  ARM_BUILTIN_WADDUSB,
1083  ARM_BUILTIN_WADDUSH,
1084  ARM_BUILTIN_WADDUSW,
1085  ARM_BUILTIN_WSUBB,
1086  ARM_BUILTIN_WSUBH,
1087  ARM_BUILTIN_WSUBW,
1088  ARM_BUILTIN_WSUBSSB,
1089  ARM_BUILTIN_WSUBSSH,
1090  ARM_BUILTIN_WSUBSSW,
1091  ARM_BUILTIN_WSUBUSB,
1092  ARM_BUILTIN_WSUBUSH,
1093  ARM_BUILTIN_WSUBUSW,
1094
1095  ARM_BUILTIN_WAND,
1096  ARM_BUILTIN_WANDN,
1097  ARM_BUILTIN_WOR,
1098  ARM_BUILTIN_WXOR,
1099
1100  ARM_BUILTIN_WCMPEQB,
1101  ARM_BUILTIN_WCMPEQH,
1102  ARM_BUILTIN_WCMPEQW,
1103  ARM_BUILTIN_WCMPGTUB,
1104  ARM_BUILTIN_WCMPGTUH,
1105  ARM_BUILTIN_WCMPGTUW,
1106  ARM_BUILTIN_WCMPGTSB,
1107  ARM_BUILTIN_WCMPGTSH,
1108  ARM_BUILTIN_WCMPGTSW,
1109
1110  ARM_BUILTIN_TEXTRMSB,
1111  ARM_BUILTIN_TEXTRMSH,
1112  ARM_BUILTIN_TEXTRMSW,
1113  ARM_BUILTIN_TEXTRMUB,
1114  ARM_BUILTIN_TEXTRMUH,
1115  ARM_BUILTIN_TEXTRMUW,
1116  ARM_BUILTIN_TINSRB,
1117  ARM_BUILTIN_TINSRH,
1118  ARM_BUILTIN_TINSRW,
1119
1120  ARM_BUILTIN_WMAXSW,
1121  ARM_BUILTIN_WMAXSH,
1122  ARM_BUILTIN_WMAXSB,
1123  ARM_BUILTIN_WMAXUW,
1124  ARM_BUILTIN_WMAXUH,
1125  ARM_BUILTIN_WMAXUB,
1126  ARM_BUILTIN_WMINSW,
1127  ARM_BUILTIN_WMINSH,
1128  ARM_BUILTIN_WMINSB,
1129  ARM_BUILTIN_WMINUW,
1130  ARM_BUILTIN_WMINUH,
1131  ARM_BUILTIN_WMINUB,
1132
1133  ARM_BUILTIN_WMULUM,
1134  ARM_BUILTIN_WMULSM,
1135  ARM_BUILTIN_WMULUL,
1136
1137  ARM_BUILTIN_PSADBH,
1138  ARM_BUILTIN_WSHUFH,
1139
1140  ARM_BUILTIN_WSLLH,
1141  ARM_BUILTIN_WSLLW,
1142  ARM_BUILTIN_WSLLD,
1143  ARM_BUILTIN_WSRAH,
1144  ARM_BUILTIN_WSRAW,
1145  ARM_BUILTIN_WSRAD,
1146  ARM_BUILTIN_WSRLH,
1147  ARM_BUILTIN_WSRLW,
1148  ARM_BUILTIN_WSRLD,
1149  ARM_BUILTIN_WRORH,
1150  ARM_BUILTIN_WRORW,
1151  ARM_BUILTIN_WRORD,
1152  ARM_BUILTIN_WSLLHI,
1153  ARM_BUILTIN_WSLLWI,
1154  ARM_BUILTIN_WSLLDI,
1155  ARM_BUILTIN_WSRAHI,
1156  ARM_BUILTIN_WSRAWI,
1157  ARM_BUILTIN_WSRADI,
1158  ARM_BUILTIN_WSRLHI,
1159  ARM_BUILTIN_WSRLWI,
1160  ARM_BUILTIN_WSRLDI,
1161  ARM_BUILTIN_WRORHI,
1162  ARM_BUILTIN_WRORWI,
1163  ARM_BUILTIN_WRORDI,
1164
1165  ARM_BUILTIN_WUNPCKIHB,
1166  ARM_BUILTIN_WUNPCKIHH,
1167  ARM_BUILTIN_WUNPCKIHW,
1168  ARM_BUILTIN_WUNPCKILB,
1169  ARM_BUILTIN_WUNPCKILH,
1170  ARM_BUILTIN_WUNPCKILW,
1171
1172  ARM_BUILTIN_WUNPCKEHSB,
1173  ARM_BUILTIN_WUNPCKEHSH,
1174  ARM_BUILTIN_WUNPCKEHSW,
1175  ARM_BUILTIN_WUNPCKEHUB,
1176  ARM_BUILTIN_WUNPCKEHUH,
1177  ARM_BUILTIN_WUNPCKEHUW,
1178  ARM_BUILTIN_WUNPCKELSB,
1179  ARM_BUILTIN_WUNPCKELSH,
1180  ARM_BUILTIN_WUNPCKELSW,
1181  ARM_BUILTIN_WUNPCKELUB,
1182  ARM_BUILTIN_WUNPCKELUH,
1183  ARM_BUILTIN_WUNPCKELUW,
1184
1185  ARM_BUILTIN_WABSB,
1186  ARM_BUILTIN_WABSH,
1187  ARM_BUILTIN_WABSW,
1188
1189  ARM_BUILTIN_WADDSUBHX,
1190  ARM_BUILTIN_WSUBADDHX,
1191
1192  ARM_BUILTIN_WABSDIFFB,
1193  ARM_BUILTIN_WABSDIFFH,
1194  ARM_BUILTIN_WABSDIFFW,
1195
1196  ARM_BUILTIN_WADDCH,
1197  ARM_BUILTIN_WADDCW,
1198
1199  ARM_BUILTIN_WAVG4,
1200  ARM_BUILTIN_WAVG4R,
1201
1202  ARM_BUILTIN_WMADDSX,
1203  ARM_BUILTIN_WMADDUX,
1204
1205  ARM_BUILTIN_WMADDSN,
1206  ARM_BUILTIN_WMADDUN,
1207
1208  ARM_BUILTIN_WMULWSM,
1209  ARM_BUILTIN_WMULWUM,
1210
1211  ARM_BUILTIN_WMULWSMR,
1212  ARM_BUILTIN_WMULWUMR,
1213
1214  ARM_BUILTIN_WMULWL,
1215
1216  ARM_BUILTIN_WMULSMR,
1217  ARM_BUILTIN_WMULUMR,
1218
1219  ARM_BUILTIN_WQMULM,
1220  ARM_BUILTIN_WQMULMR,
1221
1222  ARM_BUILTIN_WQMULWM,
1223  ARM_BUILTIN_WQMULWMR,
1224
1225  ARM_BUILTIN_WADDBHUSM,
1226  ARM_BUILTIN_WADDBHUSL,
1227
1228  ARM_BUILTIN_WQMIABB,
1229  ARM_BUILTIN_WQMIABT,
1230  ARM_BUILTIN_WQMIATB,
1231  ARM_BUILTIN_WQMIATT,
1232
1233  ARM_BUILTIN_WQMIABBN,
1234  ARM_BUILTIN_WQMIABTN,
1235  ARM_BUILTIN_WQMIATBN,
1236  ARM_BUILTIN_WQMIATTN,
1237
1238  ARM_BUILTIN_WMIABB,
1239  ARM_BUILTIN_WMIABT,
1240  ARM_BUILTIN_WMIATB,
1241  ARM_BUILTIN_WMIATT,
1242
1243  ARM_BUILTIN_WMIABBN,
1244  ARM_BUILTIN_WMIABTN,
1245  ARM_BUILTIN_WMIATBN,
1246  ARM_BUILTIN_WMIATTN,
1247
1248  ARM_BUILTIN_WMIAWBB,
1249  ARM_BUILTIN_WMIAWBT,
1250  ARM_BUILTIN_WMIAWTB,
1251  ARM_BUILTIN_WMIAWTT,
1252
1253  ARM_BUILTIN_WMIAWBBN,
1254  ARM_BUILTIN_WMIAWBTN,
1255  ARM_BUILTIN_WMIAWTBN,
1256  ARM_BUILTIN_WMIAWTTN,
1257
1258  ARM_BUILTIN_WMERGE,
1259
1260  ARM_BUILTIN_GET_FPSCR,
1261  ARM_BUILTIN_SET_FPSCR,
1262  ARM_BUILTIN_GET_FPSCR_NZCVQC,
1263  ARM_BUILTIN_SET_FPSCR_NZCVQC,
1264
1265  ARM_BUILTIN_CMSE_NONSECURE_CALLER,
1266  ARM_BUILTIN_SIMD_LANE_CHECK,
1267
1268#undef CRYPTO1
1269#undef CRYPTO2
1270#undef CRYPTO3
1271
1272#define CRYPTO1(L, U, M1, M2) \
1273  ARM_BUILTIN_CRYPTO_##U,
1274#define CRYPTO2(L, U, M1, M2, M3) \
1275  ARM_BUILTIN_CRYPTO_##U,
1276#define CRYPTO3(L, U, M1, M2, M3, M4) \
1277  ARM_BUILTIN_CRYPTO_##U,
1278
1279  ARM_BUILTIN_CRYPTO_BASE,
1280
1281#include "crypto.def"
1282
1283#undef CRYPTO1
1284#undef CRYPTO2
1285#undef CRYPTO3
1286
1287  ARM_BUILTIN_VFP_BASE,
1288
1289#include "arm_vfp_builtins.def"
1290
1291  ARM_BUILTIN_NEON_BASE,
1292
1293#include "arm_neon_builtins.def"
1294
1295#undef VAR1
1296#define VAR1(T, N, X) \
1297  ARM_BUILTIN_##N,
1298
1299  ARM_BUILTIN_ACLE_BASE,
1300  ARM_BUILTIN_SAT_IMM_CHECK = ARM_BUILTIN_ACLE_BASE,
1301
1302#include "arm_acle_builtins.def"
1303
1304#undef VAR1
1305#define VAR1(T, N, X, ... ) \
1306  ARM_BUILTIN_##N##X,
1307
1308  ARM_BUILTIN_CDE_BASE,
1309
1310#include "arm_cde_builtins.def"
1311
1312  ARM_BUILTIN_MVE_BASE,
1313
1314#undef VAR1
1315#define VAR1(T, N, X) \
1316  ARM_BUILTIN_MVE_##N##X,
1317#include "arm_mve_builtins.def"
1318
1319  ARM_BUILTIN_MAX
1320};
1321
1322#define ARM_BUILTIN_VFP_PATTERN_START \
1323  (ARM_BUILTIN_VFP_BASE + 1)
1324
1325#define ARM_BUILTIN_NEON_PATTERN_START \
1326  (ARM_BUILTIN_NEON_BASE + 1)
1327
1328#define ARM_BUILTIN_MVE_PATTERN_START \
1329  (ARM_BUILTIN_MVE_BASE + 1)
1330
1331#define ARM_BUILTIN_ACLE_PATTERN_START \
1332  (ARM_BUILTIN_ACLE_BASE + 1)
1333
1334#define ARM_BUILTIN_CDE_PATTERN_START \
1335  (ARM_BUILTIN_CDE_BASE + 1)
1336
1337#define ARM_BUILTIN_CDE_PATTERN_END \
1338  (ARM_BUILTIN_CDE_BASE + ARRAY_SIZE (cde_builtin_data))
1339
1340#undef CF
1341#undef VAR1
1342#undef VAR2
1343#undef VAR3
1344#undef VAR4
1345#undef VAR5
1346#undef VAR6
1347#undef VAR7
1348#undef VAR8
1349#undef VAR9
1350#undef VAR10
1351
1352static GTY(()) tree arm_builtin_decls[ARM_BUILTIN_MAX];
1353
1354#define NUM_DREG_TYPES 5
1355#define NUM_QREG_TYPES 6
1356
1357/* Internal scalar builtin types.  These types are used to support
1358   neon intrinsic builtins.  They are _not_ user-visible types.  Therefore
1359   the mangling for these types are implementation defined.  */
1360const char *arm_scalar_builtin_types[] = {
1361  "__builtin_neon_qi",
1362  "__builtin_neon_hi",
1363  "__builtin_neon_si",
1364  "__builtin_neon_sf",
1365  "__builtin_neon_di",
1366  "__builtin_neon_df",
1367  "__builtin_neon_ti",
1368  "__builtin_neon_uqi",
1369  "__builtin_neon_uhi",
1370  "__builtin_neon_usi",
1371  "__builtin_neon_udi",
1372  "__builtin_neon_ei",
1373  "__builtin_neon_oi",
1374  "__builtin_neon_ci",
1375  "__builtin_neon_xi",
1376  "__builtin_neon_bf",
1377  NULL
1378};
1379
1380#define ENTRY(E, M, Q, S, T, G) E,
1381enum arm_simd_type
1382{
1383#include "arm-simd-builtin-types.def"
1384  __TYPE_FINAL
1385};
1386#undef ENTRY
1387
1388struct arm_simd_type_info
1389{
1390  enum arm_simd_type type;
1391
1392  /* Internal type name.  */
1393  const char *name;
1394
1395  /* Internal type name(mangled).  The mangled names conform to the
1396     AAPCS (see "Procedure Call Standard for the ARM Architecture",
1397     Appendix A).  To qualify for emission with the mangled names defined in
1398     that document, a vector type must not only be of the correct mode but also
1399     be of the correct internal Neon vector type (e.g. __simd64_int8_t);
1400     these types are registered by arm_init_simd_builtin_types ().  In other
1401     words, vector types defined in other ways e.g. via vector_size attribute
1402     will get default mangled names.  */
1403  const char *mangle;
1404
1405  /* Internal type.  */
1406  tree itype;
1407
1408  /* Element type.  */
1409  tree eltype;
1410
1411  /* Machine mode the internal type maps to.  */
1412  machine_mode mode;
1413
1414  /* Qualifiers.  */
1415  enum arm_type_qualifiers q;
1416};
1417
1418#define ENTRY(E, M, Q, S, T, G)		\
1419  {E,					\
1420   "__simd" #S "_" #T "_t",		\
1421   #G "__simd" #S "_" #T "_t",		\
1422   NULL_TREE, NULL_TREE, M##mode, qualifier_##Q},
1423static struct arm_simd_type_info arm_simd_types [] = {
1424#include "arm-simd-builtin-types.def"
1425};
1426#undef ENTRY
1427
1428/* The user-visible __fp16 type.  */
1429tree arm_fp16_type_node = NULL_TREE;
1430
1431/* Back-end node type for brain float (bfloat) types.  */
1432tree arm_bf16_type_node = NULL_TREE;
1433tree arm_bf16_ptr_type_node = NULL_TREE;
1434
1435static tree arm_simd_intOI_type_node = NULL_TREE;
1436static tree arm_simd_intEI_type_node = NULL_TREE;
1437static tree arm_simd_intCI_type_node = NULL_TREE;
1438static tree arm_simd_intXI_type_node = NULL_TREE;
1439static tree arm_simd_polyQI_type_node = NULL_TREE;
1440static tree arm_simd_polyHI_type_node = NULL_TREE;
1441static tree arm_simd_polyDI_type_node = NULL_TREE;
1442static tree arm_simd_polyTI_type_node = NULL_TREE;
1443
1444static const char *
1445arm_mangle_builtin_scalar_type (const_tree type)
1446{
1447  int i = 0;
1448
1449  while (arm_scalar_builtin_types[i] != NULL)
1450    {
1451      const char *name = arm_scalar_builtin_types[i];
1452
1453      if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
1454	  && DECL_NAME (TYPE_NAME (type))
1455	  && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))), name))
1456	return arm_scalar_builtin_types[i];
1457      i++;
1458    }
1459  return NULL;
1460}
1461
1462static const char *
1463arm_mangle_builtin_vector_type (const_tree type)
1464{
1465  int i;
1466  int nelts = sizeof (arm_simd_types) / sizeof (arm_simd_types[0]);
1467
1468  for (i = 0; i < nelts; i++)
1469    if (arm_simd_types[i].mode ==  TYPE_MODE (type)
1470	&& TYPE_NAME (type)
1471	&& TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
1472	&& DECL_NAME (TYPE_NAME (type))
1473	&& !strcmp
1474	     (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
1475	      arm_simd_types[i].name))
1476      return arm_simd_types[i].mangle;
1477
1478  return NULL;
1479}
1480
1481const char *
1482arm_mangle_builtin_type (const_tree type)
1483{
1484  const char *mangle;
1485  /* Walk through all the Arm builtins types tables to filter out the
1486     incoming type.  */
1487  if ((mangle = arm_mangle_builtin_vector_type (type))
1488      || (mangle = arm_mangle_builtin_scalar_type (type)))
1489    return mangle;
1490
1491  return NULL;
1492}
1493
1494static tree
1495arm_simd_builtin_std_type (machine_mode mode,
1496			   enum arm_type_qualifiers q)
1497{
1498#define QUAL_TYPE(M)  \
1499  ((q == qualifier_none) ? int##M##_type_node : unsigned_int##M##_type_node);
1500  switch (mode)
1501    {
1502    case E_QImode:
1503      return QUAL_TYPE (QI);
1504    case E_HImode:
1505      return QUAL_TYPE (HI);
1506    case E_SImode:
1507      return QUAL_TYPE (SI);
1508    case E_DImode:
1509      return QUAL_TYPE (DI);
1510    case E_TImode:
1511      return QUAL_TYPE (TI);
1512    case E_OImode:
1513      return arm_simd_intOI_type_node;
1514    case E_EImode:
1515      return arm_simd_intEI_type_node;
1516    case E_CImode:
1517      return arm_simd_intCI_type_node;
1518    case E_XImode:
1519      return arm_simd_intXI_type_node;
1520    case E_HFmode:
1521      return arm_fp16_type_node;
1522    case E_SFmode:
1523      return float_type_node;
1524    case E_DFmode:
1525      return double_type_node;
1526    case E_BFmode:
1527      return arm_bf16_type_node;
1528    default:
1529      gcc_unreachable ();
1530    }
1531#undef QUAL_TYPE
1532}
1533
1534static tree
1535arm_lookup_simd_builtin_type (machine_mode mode,
1536			      enum arm_type_qualifiers q)
1537{
1538  int i;
1539  int nelts = sizeof (arm_simd_types) / sizeof (arm_simd_types[0]);
1540
1541  /* Non-poly scalar modes map to standard types not in the table.  */
1542  if (q != qualifier_poly && !VECTOR_MODE_P (mode))
1543    return arm_simd_builtin_std_type (mode, q);
1544
1545  for (i = 0; i < nelts; i++)
1546    if (arm_simd_types[i].mode == mode
1547	&& arm_simd_types[i].q == q)
1548      return arm_simd_types[i].itype;
1549
1550  /* Note that we won't have caught the underlying type for poly64x2_t
1551     in the above table.  This gets default mangling.  */
1552
1553  return NULL_TREE;
1554}
1555
1556static tree
1557arm_simd_builtin_type (machine_mode mode, bool unsigned_p, bool poly_p)
1558{
1559  if (poly_p)
1560    return arm_lookup_simd_builtin_type (mode, qualifier_poly);
1561  else if (unsigned_p)
1562    return arm_lookup_simd_builtin_type (mode, qualifier_unsigned);
1563  else
1564    return arm_lookup_simd_builtin_type (mode, qualifier_none);
1565}
1566
1567static void
1568arm_init_simd_builtin_types (void)
1569{
1570  int i;
1571  int nelts = sizeof (arm_simd_types) / sizeof (arm_simd_types[0]);
1572  tree tdecl;
1573
1574  /* Poly types are a world of their own.  In order to maintain legacy
1575     ABI, they get initialized using the old interface, and don't get
1576     an entry in our mangling table, consequently, they get default
1577     mangling.  As a further gotcha, poly8_t and poly16_t are signed
1578     types, poly64_t and poly128_t are unsigned types.  */
1579  if (!TARGET_HAVE_MVE)
1580    {
1581      arm_simd_polyQI_type_node
1582	= build_distinct_type_copy (intQI_type_node);
1583      (*lang_hooks.types.register_builtin_type) (arm_simd_polyQI_type_node,
1584						 "__builtin_neon_poly8");
1585      arm_simd_polyHI_type_node
1586	= build_distinct_type_copy (intHI_type_node);
1587      (*lang_hooks.types.register_builtin_type) (arm_simd_polyHI_type_node,
1588						 "__builtin_neon_poly16");
1589      arm_simd_polyDI_type_node
1590	= build_distinct_type_copy (unsigned_intDI_type_node);
1591      (*lang_hooks.types.register_builtin_type) (arm_simd_polyDI_type_node,
1592						 "__builtin_neon_poly64");
1593      arm_simd_polyTI_type_node
1594	= build_distinct_type_copy (unsigned_intTI_type_node);
1595      (*lang_hooks.types.register_builtin_type) (arm_simd_polyTI_type_node,
1596						 "__builtin_neon_poly128");
1597      /* Init poly vector element types with scalar poly types.  */
1598      arm_simd_types[Poly8x8_t].eltype = arm_simd_polyQI_type_node;
1599      arm_simd_types[Poly8x16_t].eltype = arm_simd_polyQI_type_node;
1600      arm_simd_types[Poly16x4_t].eltype = arm_simd_polyHI_type_node;
1601      arm_simd_types[Poly16x8_t].eltype = arm_simd_polyHI_type_node;
1602      /* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default
1603	 mangling.  */
1604
1605      /* Prevent front-ends from transforming poly vectors into string
1606	 literals.  */
1607      TYPE_STRING_FLAG (arm_simd_polyQI_type_node) = false;
1608      TYPE_STRING_FLAG (arm_simd_polyHI_type_node) = false;
1609    }
1610  /* Init all the element types built by the front-end.  */
1611  arm_simd_types[Int8x8_t].eltype = intQI_type_node;
1612  arm_simd_types[Int8x16_t].eltype = intQI_type_node;
1613  arm_simd_types[Int16x4_t].eltype = intHI_type_node;
1614  arm_simd_types[Int16x8_t].eltype = intHI_type_node;
1615  arm_simd_types[Int32x2_t].eltype = intSI_type_node;
1616  arm_simd_types[Int32x4_t].eltype = intSI_type_node;
1617  arm_simd_types[Int64x2_t].eltype = intDI_type_node;
1618  arm_simd_types[Uint8x8_t].eltype = unsigned_intQI_type_node;
1619  arm_simd_types[Uint8x16_t].eltype = unsigned_intQI_type_node;
1620  arm_simd_types[Uint16x4_t].eltype = unsigned_intHI_type_node;
1621  arm_simd_types[Uint16x8_t].eltype = unsigned_intHI_type_node;
1622  arm_simd_types[Uint32x2_t].eltype = unsigned_intSI_type_node;
1623  arm_simd_types[Uint32x4_t].eltype = unsigned_intSI_type_node;
1624  arm_simd_types[Uint64x2_t].eltype = unsigned_intDI_type_node;
1625
1626  /* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default
1627     mangling.  */
1628
1629  /* Continue with standard types.  */
1630  /* The __builtin_simd{64,128}_float16 types are kept private unless
1631     we have a scalar __fp16 type.  */
1632  arm_simd_types[Float16x4_t].eltype = arm_fp16_type_node;
1633  arm_simd_types[Float16x8_t].eltype = arm_fp16_type_node;
1634  arm_simd_types[Float32x2_t].eltype = float_type_node;
1635  arm_simd_types[Float32x4_t].eltype = float_type_node;
1636
1637  /* Init Bfloat vector types with underlying __bf16 scalar type.  */
1638  arm_simd_types[Bfloat16x2_t].eltype = arm_bf16_type_node;
1639  arm_simd_types[Bfloat16x4_t].eltype = arm_bf16_type_node;
1640  arm_simd_types[Bfloat16x8_t].eltype = arm_bf16_type_node;
1641
1642  for (i = 0; i < nelts; i++)
1643    {
1644      tree eltype = arm_simd_types[i].eltype;
1645      machine_mode mode = arm_simd_types[i].mode;
1646
1647      if (eltype == NULL)
1648	continue;
1649      if (arm_simd_types[i].itype == NULL)
1650	{
1651	  tree type = build_vector_type (eltype, GET_MODE_NUNITS (mode));
1652	  type = build_distinct_type_copy (type);
1653	  SET_TYPE_STRUCTURAL_EQUALITY (type);
1654
1655	  TYPE_ATTRIBUTES (type)
1656	    = tree_cons (get_identifier ("Advanced SIMD type"),
1657			 NULL_TREE, TYPE_ATTRIBUTES (type));
1658	  arm_simd_types[i].itype = type;
1659	}
1660
1661      tdecl = add_builtin_type (arm_simd_types[i].name,
1662				arm_simd_types[i].itype);
1663      TYPE_NAME (arm_simd_types[i].itype) = tdecl;
1664      SET_TYPE_STRUCTURAL_EQUALITY (arm_simd_types[i].itype);
1665    }
1666
1667#define AARCH_BUILD_SIGNED_TYPE(mode)  \
1668  make_signed_type (GET_MODE_PRECISION (mode));
1669  arm_simd_intOI_type_node = AARCH_BUILD_SIGNED_TYPE (OImode);
1670  arm_simd_intEI_type_node = AARCH_BUILD_SIGNED_TYPE (EImode);
1671  arm_simd_intCI_type_node = AARCH_BUILD_SIGNED_TYPE (CImode);
1672  arm_simd_intXI_type_node = AARCH_BUILD_SIGNED_TYPE (XImode);
1673#undef AARCH_BUILD_SIGNED_TYPE
1674
1675  tdecl = add_builtin_type
1676	    ("__builtin_neon_ei" , arm_simd_intEI_type_node);
1677  TYPE_NAME (arm_simd_intEI_type_node) = tdecl;
1678  tdecl = add_builtin_type
1679	    ("__builtin_neon_oi" , arm_simd_intOI_type_node);
1680  TYPE_NAME (arm_simd_intOI_type_node) = tdecl;
1681  tdecl = add_builtin_type
1682	    ("__builtin_neon_ci" , arm_simd_intCI_type_node);
1683  TYPE_NAME (arm_simd_intCI_type_node) = tdecl;
1684  tdecl = add_builtin_type
1685	    ("__builtin_neon_xi" , arm_simd_intXI_type_node);
1686  TYPE_NAME (arm_simd_intXI_type_node) = tdecl;
1687}
1688
1689static void
1690arm_init_simd_builtin_scalar_types (void)
1691{
1692  /* Define typedefs for all the standard scalar types.  */
1693  (*lang_hooks.types.register_builtin_type) (intQI_type_node,
1694					     "__builtin_neon_qi");
1695  (*lang_hooks.types.register_builtin_type) (intHI_type_node,
1696					     "__builtin_neon_hi");
1697  (*lang_hooks.types.register_builtin_type) (intSI_type_node,
1698					     "__builtin_neon_si");
1699  (*lang_hooks.types.register_builtin_type) (float_type_node,
1700					     "__builtin_neon_sf");
1701  (*lang_hooks.types.register_builtin_type) (intDI_type_node,
1702					     "__builtin_neon_di");
1703  (*lang_hooks.types.register_builtin_type) (double_type_node,
1704					     "__builtin_neon_df");
1705  (*lang_hooks.types.register_builtin_type) (intTI_type_node,
1706					     "__builtin_neon_ti");
1707  (*lang_hooks.types.register_builtin_type) (arm_bf16_type_node,
1708                                             "__builtin_neon_bf");
1709  /* Unsigned integer types for various mode sizes.  */
1710  (*lang_hooks.types.register_builtin_type) (unsigned_intQI_type_node,
1711					     "__builtin_neon_uqi");
1712  (*lang_hooks.types.register_builtin_type) (unsigned_intHI_type_node,
1713					     "__builtin_neon_uhi");
1714  (*lang_hooks.types.register_builtin_type) (unsigned_intSI_type_node,
1715					     "__builtin_neon_usi");
1716  (*lang_hooks.types.register_builtin_type) (unsigned_intDI_type_node,
1717					     "__builtin_neon_udi");
1718  (*lang_hooks.types.register_builtin_type) (unsigned_intTI_type_node,
1719					     "__builtin_neon_uti");
1720}
1721
1722/* Set up a builtin.  It will use information stored in the argument struct D to
1723   derive the builtin's type signature and name.  It will append the name in D
1724   to the PREFIX passed and use these to create a builtin declaration that is
1725   then stored in 'arm_builtin_decls' under index FCODE.  This FCODE is also
1726   written back to D for future use.  */
1727
1728static void
1729arm_init_builtin (unsigned int fcode, arm_builtin_datum *d,
1730		  const char * prefix)
1731{
1732  bool print_type_signature_p = false;
1733  char type_signature[SIMD_MAX_BUILTIN_ARGS] = { 0 };
1734  char namebuf[60];
1735  tree ftype = NULL;
1736  tree fndecl = NULL;
1737
1738  d->fcode = fcode;
1739
1740  /* We must track two variables here.  op_num is
1741     the operand number as in the RTL pattern.  This is
1742     required to access the mode (e.g. V4SF mode) of the
1743     argument, from which the base type can be derived.
1744     arg_num is an index in to the qualifiers data, which
1745     gives qualifiers to the type (e.g. const unsigned).
1746     The reason these two variables may differ by one is the
1747     void return type.  While all return types take the 0th entry
1748     in the qualifiers array, there is no operand for them in the
1749     RTL pattern.  */
1750  int op_num = insn_data[d->code].n_operands - 1;
1751  int arg_num = d->qualifiers[0] & qualifier_void
1752    ? op_num + 1
1753    : op_num;
1754  tree return_type = void_type_node, args = void_list_node;
1755  tree eltype;
1756
1757  /* Build a function type directly from the insn_data for this
1758     builtin.  The build_function_type () function takes care of
1759     removing duplicates for us.  */
1760  for (; op_num >= 0; arg_num--, op_num--)
1761    {
1762      machine_mode op_mode = insn_data[d->code].operand[op_num].mode;
1763      enum arm_type_qualifiers qualifiers = d->qualifiers[arg_num];
1764
1765      if (qualifiers & qualifier_unsigned)
1766	{
1767	  type_signature[arg_num] = 'u';
1768	  print_type_signature_p = true;
1769	}
1770      else if (qualifiers & qualifier_poly)
1771	{
1772	  type_signature[arg_num] = 'p';
1773	  print_type_signature_p = true;
1774	}
1775      else
1776	type_signature[arg_num] = 's';
1777
1778      /* Skip an internal operand for vget_{low, high}.  */
1779      if (qualifiers & qualifier_internal)
1780	continue;
1781
1782      /* Some builtins have different user-facing types
1783	 for certain arguments, encoded in d->mode.  */
1784      if (qualifiers & qualifier_map_mode)
1785	op_mode = d->mode;
1786
1787      /* For pointers, we want a pointer to the basic type
1788	 of the vector.  */
1789      if (qualifiers & qualifier_pointer && VECTOR_MODE_P (op_mode))
1790	op_mode = GET_MODE_INNER (op_mode);
1791
1792      /* For void pointers we already have nodes constructed by the midend.  */
1793      if (qualifiers & qualifier_void_pointer)
1794	eltype = qualifiers & qualifier_const
1795		 ? const_ptr_type_node : ptr_type_node;
1796      else
1797	{
1798	  eltype
1799	    = arm_simd_builtin_type (op_mode,
1800				     (qualifiers & qualifier_unsigned) != 0,
1801				     (qualifiers & qualifier_poly) != 0);
1802	  gcc_assert (eltype != NULL);
1803
1804	  /* Add qualifiers.  */
1805	  if (qualifiers & qualifier_const)
1806	    eltype = build_qualified_type (eltype, TYPE_QUAL_CONST);
1807
1808	  if (qualifiers & qualifier_pointer)
1809	    eltype = build_pointer_type (eltype);
1810	}
1811      /* If we have reached arg_num == 0, we are at a non-void
1812	 return type.  Otherwise, we are still processing
1813	 arguments.  */
1814      if (arg_num == 0)
1815	return_type = eltype;
1816      else
1817	args = tree_cons (NULL_TREE, eltype, args);
1818    }
1819
1820  ftype = build_function_type (return_type, args);
1821
1822  gcc_assert (ftype != NULL);
1823
1824  if (print_type_signature_p
1825      && IN_RANGE (fcode, ARM_BUILTIN_VFP_BASE, ARM_BUILTIN_ACLE_BASE - 1))
1826    snprintf (namebuf, sizeof (namebuf), "%s_%s_%s",
1827	      prefix, d->name, type_signature);
1828  else
1829    snprintf (namebuf, sizeof (namebuf), "%s_%s",
1830	      prefix, d->name);
1831
1832  fndecl = add_builtin_function (namebuf, ftype, fcode, BUILT_IN_MD,
1833				 NULL, NULL_TREE);
1834  arm_builtin_decls[fcode] = fndecl;
1835}
1836
1837/* Initialize the backend REAL_TYPE type supporting bfloat types.  */
1838static void
1839arm_init_bf16_types (void)
1840{
1841  arm_bf16_type_node = make_node (REAL_TYPE);
1842  TYPE_PRECISION (arm_bf16_type_node) = 16;
1843  SET_TYPE_MODE (arm_bf16_type_node, BFmode);
1844  layout_type (arm_bf16_type_node);
1845
1846  lang_hooks.types.register_builtin_type (arm_bf16_type_node, "__bf16");
1847  arm_bf16_ptr_type_node = build_pointer_type (arm_bf16_type_node);
1848}
1849
1850/* Set up ACLE builtins, even builtins for instructions that are not
1851   in the current target ISA to allow the user to compile particular modules
1852   with different target specific options that differ from the command line
1853   options.  Such builtins will be rejected in arm_expand_builtin.  */
1854
1855static void
1856arm_init_acle_builtins (void)
1857{
1858  unsigned int i, fcode = ARM_BUILTIN_ACLE_PATTERN_START;
1859
1860  tree sat_check_fpr = build_function_type_list (void_type_node,
1861						 intSI_type_node,
1862						 intSI_type_node,
1863						 intSI_type_node,
1864						 NULL);
1865  arm_builtin_decls[ARM_BUILTIN_SAT_IMM_CHECK]
1866    = add_builtin_function ("__builtin_sat_imm_check", sat_check_fpr,
1867			    ARM_BUILTIN_SAT_IMM_CHECK, BUILT_IN_MD,
1868			    NULL, NULL_TREE);
1869
1870  for (i = 0; i < ARRAY_SIZE (acle_builtin_data); i++, fcode++)
1871    {
1872      arm_builtin_datum *d = &acle_builtin_data[i];
1873      arm_init_builtin (fcode, d, "__builtin_arm");
1874    }
1875}
1876
1877static void
1878arm_init_cde_builtins (void)
1879{
1880  unsigned int i, fcode = ARM_BUILTIN_CDE_PATTERN_START;
1881  for (i = 0; i < ARRAY_SIZE (cde_builtin_data); i++, fcode++)
1882    {
1883      /* Only define CDE floating point builtins if the target has floating
1884	 point registers.  NOTE: without HARD_FLOAT we don't have MVE, so we
1885	 can break out of this loop directly here.  */
1886      if (!TARGET_MAYBE_HARD_FLOAT && fcode >= ARM_BUILTIN_vcx1si)
1887	break;
1888      /* Only define CDE/MVE builtins if MVE is available.  */
1889      if (!TARGET_HAVE_MVE && fcode >= ARM_BUILTIN_vcx1qv16qi)
1890	break;
1891      arm_builtin_cde_datum *cde = &cde_builtin_data[i];
1892      arm_builtin_datum *d = &cde->base;
1893      arm_init_builtin (fcode, d, "__builtin_arm");
1894      set_call_expr_flags (arm_builtin_decls[fcode], cde->ecf_flag);
1895    }
1896}
1897
1898/* Set up all the MVE builtins mentioned in arm_mve_builtins.def file.  */
1899static void
1900arm_init_mve_builtins (void)
1901{
1902  volatile unsigned int i, fcode = ARM_BUILTIN_MVE_PATTERN_START;
1903
1904  arm_init_simd_builtin_scalar_types ();
1905  arm_init_simd_builtin_types ();
1906
1907  /* Add support for __builtin_{get,set}_fpscr_nzcvqc, used by MVE intrinsics
1908     that read and/or write the carry bit.  */
1909  tree get_fpscr_nzcvqc = build_function_type_list (intSI_type_node,
1910						    NULL);
1911  tree set_fpscr_nzcvqc = build_function_type_list (void_type_node,
1912						    intSI_type_node,
1913						    NULL);
1914  arm_builtin_decls[ARM_BUILTIN_GET_FPSCR_NZCVQC]
1915    = add_builtin_function ("__builtin_arm_get_fpscr_nzcvqc", get_fpscr_nzcvqc,
1916			    ARM_BUILTIN_GET_FPSCR_NZCVQC, BUILT_IN_MD, NULL,
1917			    NULL_TREE);
1918  arm_builtin_decls[ARM_BUILTIN_SET_FPSCR_NZCVQC]
1919    = add_builtin_function ("__builtin_arm_set_fpscr_nzcvqc", set_fpscr_nzcvqc,
1920			    ARM_BUILTIN_SET_FPSCR_NZCVQC, BUILT_IN_MD, NULL,
1921			    NULL_TREE);
1922
1923  for (i = 0; i < ARRAY_SIZE (mve_builtin_data); i++, fcode++)
1924    {
1925      arm_builtin_datum *d = &mve_builtin_data[i];
1926      arm_init_builtin (fcode, d, "__builtin_mve");
1927    }
1928}
1929
1930/* Set up all the NEON builtins, even builtins for instructions that are not
1931   in the current target ISA to allow the user to compile particular modules
1932   with different target specific options that differ from the command line
1933   options. Such builtins will be rejected in arm_expand_builtin.  */
1934
1935static void
1936arm_init_neon_builtins (void)
1937{
1938  unsigned int i, fcode = ARM_BUILTIN_NEON_PATTERN_START;
1939
1940  arm_init_simd_builtin_types ();
1941
1942  /* Strong-typing hasn't been implemented for all AdvSIMD builtin intrinsics.
1943     Therefore we need to preserve the old __builtin scalar types.  It can be
1944     removed once all the intrinsics become strongly typed using the qualifier
1945     system.  */
1946  arm_init_simd_builtin_scalar_types ();
1947
1948  for (i = 0; i < ARRAY_SIZE (neon_builtin_data); i++, fcode++)
1949    {
1950      arm_builtin_datum *d = &neon_builtin_data[i];
1951      arm_init_builtin (fcode, d, "__builtin_neon");
1952    }
1953}
1954
1955/* Set up all the scalar floating point builtins.  */
1956
1957static void
1958arm_init_vfp_builtins (void)
1959{
1960  unsigned int i, fcode = ARM_BUILTIN_VFP_PATTERN_START;
1961
1962  for (i = 0; i < ARRAY_SIZE (vfp_builtin_data); i++, fcode++)
1963    {
1964      arm_builtin_datum *d = &vfp_builtin_data[i];
1965      arm_init_builtin (fcode, d, "__builtin_neon");
1966    }
1967}
1968
1969static void
1970arm_init_crypto_builtins (void)
1971{
1972  tree V16UQI_type_node
1973    = arm_simd_builtin_type (V16QImode, true, false);
1974
1975  tree V4USI_type_node
1976    = arm_simd_builtin_type (V4SImode, true, false);
1977
1978  tree v16uqi_ftype_v16uqi
1979    = build_function_type_list (V16UQI_type_node, V16UQI_type_node,
1980				NULL_TREE);
1981
1982  tree v16uqi_ftype_v16uqi_v16uqi
1983	= build_function_type_list (V16UQI_type_node, V16UQI_type_node,
1984				    V16UQI_type_node, NULL_TREE);
1985
1986  tree v4usi_ftype_v4usi
1987    = build_function_type_list (V4USI_type_node, V4USI_type_node,
1988				NULL_TREE);
1989
1990  tree v4usi_ftype_v4usi_v4usi
1991    = build_function_type_list (V4USI_type_node, V4USI_type_node,
1992				V4USI_type_node, NULL_TREE);
1993
1994  tree v4usi_ftype_v4usi_v4usi_v4usi
1995    = build_function_type_list (V4USI_type_node, V4USI_type_node,
1996				V4USI_type_node, V4USI_type_node,
1997				NULL_TREE);
1998
1999  tree uti_ftype_udi_udi
2000    = build_function_type_list (unsigned_intTI_type_node,
2001				unsigned_intDI_type_node,
2002				unsigned_intDI_type_node,
2003				NULL_TREE);
2004
2005  #undef CRYPTO1
2006  #undef CRYPTO2
2007  #undef CRYPTO3
2008  #undef C
2009  #undef N
2010  #undef CF
2011  #undef FT1
2012  #undef FT2
2013  #undef FT3
2014
2015  #define C(U) \
2016    ARM_BUILTIN_CRYPTO_##U
2017  #define N(L) \
2018    "__builtin_arm_crypto_"#L
2019  #define FT1(R, A) \
2020    R##_ftype_##A
2021  #define FT2(R, A1, A2) \
2022    R##_ftype_##A1##_##A2
2023  #define FT3(R, A1, A2, A3) \
2024    R##_ftype_##A1##_##A2##_##A3
2025  #define CRYPTO1(L, U, R, A) \
2026    arm_builtin_decls[C (U)] \
2027      = add_builtin_function (N (L), FT1 (R, A), \
2028		  C (U), BUILT_IN_MD, NULL, NULL_TREE);
2029  #define CRYPTO2(L, U, R, A1, A2)  \
2030    arm_builtin_decls[C (U)]	\
2031      = add_builtin_function (N (L), FT2 (R, A1, A2), \
2032		  C (U), BUILT_IN_MD, NULL, NULL_TREE);
2033
2034  #define CRYPTO3(L, U, R, A1, A2, A3) \
2035    arm_builtin_decls[C (U)]	   \
2036      = add_builtin_function (N (L), FT3 (R, A1, A2, A3), \
2037				  C (U), BUILT_IN_MD, NULL, NULL_TREE);
2038  #include "crypto.def"
2039
2040  #undef CRYPTO1
2041  #undef CRYPTO2
2042  #undef CRYPTO3
2043  #undef C
2044  #undef N
2045  #undef FT1
2046  #undef FT2
2047  #undef FT3
2048}
2049
2050#undef NUM_DREG_TYPES
2051#undef NUM_QREG_TYPES
2052
2053#define def_mbuiltin(FLAG, NAME, TYPE, CODE)				\
2054  do									\
2055    {									\
2056      if (FLAG == isa_nobit						\
2057	  || bitmap_bit_p (arm_active_target.isa, FLAG))		\
2058	{								\
2059	  tree bdecl;							\
2060	  bdecl = add_builtin_function ((NAME), (TYPE), (CODE),		\
2061					BUILT_IN_MD, NULL, NULL_TREE);	\
2062	  arm_builtin_decls[CODE] = bdecl;				\
2063	}								\
2064    }									\
2065  while (0)
2066
2067struct builtin_description
2068{
2069  const enum isa_feature   feature;
2070  const enum insn_code     icode;
2071  const char * const       name;
2072  const enum arm_builtins  code;
2073  const enum rtx_code      comparison;
2074  const unsigned int       flag;
2075};
2076
2077static const struct builtin_description bdesc_2arg[] =
2078{
2079#define IWMMXT_BUILTIN(code, string, builtin) \
2080  { isa_bit_iwmmxt, CODE_FOR_##code, \
2081    "__builtin_arm_" string,			     \
2082    ARM_BUILTIN_##builtin, UNKNOWN, 0 },
2083
2084#define IWMMXT2_BUILTIN(code, string, builtin) \
2085  { isa_bit_iwmmxt2, CODE_FOR_##code, \
2086    "__builtin_arm_" string,			      \
2087    ARM_BUILTIN_##builtin, UNKNOWN, 0 },
2088
2089  IWMMXT_BUILTIN (addv8qi3, "waddb", WADDB)
2090  IWMMXT_BUILTIN (addv4hi3, "waddh", WADDH)
2091  IWMMXT_BUILTIN (addv2si3, "waddw", WADDW)
2092  IWMMXT_BUILTIN (subv8qi3, "wsubb", WSUBB)
2093  IWMMXT_BUILTIN (subv4hi3, "wsubh", WSUBH)
2094  IWMMXT_BUILTIN (subv2si3, "wsubw", WSUBW)
2095  IWMMXT_BUILTIN (ssaddv8qi3, "waddbss", WADDSSB)
2096  IWMMXT_BUILTIN (ssaddv4hi3, "waddhss", WADDSSH)
2097  IWMMXT_BUILTIN (ssaddv2si3, "waddwss", WADDSSW)
2098  IWMMXT_BUILTIN (sssubv8qi3, "wsubbss", WSUBSSB)
2099  IWMMXT_BUILTIN (sssubv4hi3, "wsubhss", WSUBSSH)
2100  IWMMXT_BUILTIN (sssubv2si3, "wsubwss", WSUBSSW)
2101  IWMMXT_BUILTIN (usaddv8qi3, "waddbus", WADDUSB)
2102  IWMMXT_BUILTIN (usaddv4hi3, "waddhus", WADDUSH)
2103  IWMMXT_BUILTIN (usaddv2si3, "waddwus", WADDUSW)
2104  IWMMXT_BUILTIN (ussubv8qi3, "wsubbus", WSUBUSB)
2105  IWMMXT_BUILTIN (ussubv4hi3, "wsubhus", WSUBUSH)
2106  IWMMXT_BUILTIN (ussubv2si3, "wsubwus", WSUBUSW)
2107  IWMMXT_BUILTIN (mulv4hi3, "wmulul", WMULUL)
2108  IWMMXT_BUILTIN (smulv4hi3_highpart, "wmulsm", WMULSM)
2109  IWMMXT_BUILTIN (umulv4hi3_highpart, "wmulum", WMULUM)
2110  IWMMXT_BUILTIN (eqv8qi3, "wcmpeqb", WCMPEQB)
2111  IWMMXT_BUILTIN (eqv4hi3, "wcmpeqh", WCMPEQH)
2112  IWMMXT_BUILTIN (eqv2si3, "wcmpeqw", WCMPEQW)
2113  IWMMXT_BUILTIN (gtuv8qi3, "wcmpgtub", WCMPGTUB)
2114  IWMMXT_BUILTIN (gtuv4hi3, "wcmpgtuh", WCMPGTUH)
2115  IWMMXT_BUILTIN (gtuv2si3, "wcmpgtuw", WCMPGTUW)
2116  IWMMXT_BUILTIN (gtv8qi3, "wcmpgtsb", WCMPGTSB)
2117  IWMMXT_BUILTIN (gtv4hi3, "wcmpgtsh", WCMPGTSH)
2118  IWMMXT_BUILTIN (gtv2si3, "wcmpgtsw", WCMPGTSW)
2119  IWMMXT_BUILTIN (umaxv8qi3, "wmaxub", WMAXUB)
2120  IWMMXT_BUILTIN (smaxv8qi3, "wmaxsb", WMAXSB)
2121  IWMMXT_BUILTIN (umaxv4hi3, "wmaxuh", WMAXUH)
2122  IWMMXT_BUILTIN (smaxv4hi3, "wmaxsh", WMAXSH)
2123  IWMMXT_BUILTIN (umaxv2si3, "wmaxuw", WMAXUW)
2124  IWMMXT_BUILTIN (smaxv2si3, "wmaxsw", WMAXSW)
2125  IWMMXT_BUILTIN (uminv8qi3, "wminub", WMINUB)
2126  IWMMXT_BUILTIN (sminv8qi3, "wminsb", WMINSB)
2127  IWMMXT_BUILTIN (uminv4hi3, "wminuh", WMINUH)
2128  IWMMXT_BUILTIN (sminv4hi3, "wminsh", WMINSH)
2129  IWMMXT_BUILTIN (uminv2si3, "wminuw", WMINUW)
2130  IWMMXT_BUILTIN (sminv2si3, "wminsw", WMINSW)
2131  IWMMXT_BUILTIN (iwmmxt_anddi3, "wand", WAND)
2132  IWMMXT_BUILTIN (iwmmxt_nanddi3, "wandn", WANDN)
2133  IWMMXT_BUILTIN (iwmmxt_iordi3, "wor", WOR)
2134  IWMMXT_BUILTIN (iwmmxt_xordi3, "wxor", WXOR)
2135  IWMMXT_BUILTIN (iwmmxt_uavgv8qi3, "wavg2b", WAVG2B)
2136  IWMMXT_BUILTIN (iwmmxt_uavgv4hi3, "wavg2h", WAVG2H)
2137  IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3, "wavg2br", WAVG2BR)
2138  IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3, "wavg2hr", WAVG2HR)
2139  IWMMXT_BUILTIN (iwmmxt_wunpckilb, "wunpckilb", WUNPCKILB)
2140  IWMMXT_BUILTIN (iwmmxt_wunpckilh, "wunpckilh", WUNPCKILH)
2141  IWMMXT_BUILTIN (iwmmxt_wunpckilw, "wunpckilw", WUNPCKILW)
2142  IWMMXT_BUILTIN (iwmmxt_wunpckihb, "wunpckihb", WUNPCKIHB)
2143  IWMMXT_BUILTIN (iwmmxt_wunpckihh, "wunpckihh", WUNPCKIHH)
2144  IWMMXT_BUILTIN (iwmmxt_wunpckihw, "wunpckihw", WUNPCKIHW)
2145  IWMMXT2_BUILTIN (iwmmxt_waddsubhx, "waddsubhx", WADDSUBHX)
2146  IWMMXT2_BUILTIN (iwmmxt_wsubaddhx, "wsubaddhx", WSUBADDHX)
2147  IWMMXT2_BUILTIN (iwmmxt_wabsdiffb, "wabsdiffb", WABSDIFFB)
2148  IWMMXT2_BUILTIN (iwmmxt_wabsdiffh, "wabsdiffh", WABSDIFFH)
2149  IWMMXT2_BUILTIN (iwmmxt_wabsdiffw, "wabsdiffw", WABSDIFFW)
2150  IWMMXT2_BUILTIN (iwmmxt_avg4, "wavg4", WAVG4)
2151  IWMMXT2_BUILTIN (iwmmxt_avg4r, "wavg4r", WAVG4R)
2152  IWMMXT2_BUILTIN (iwmmxt_wmulwsm, "wmulwsm", WMULWSM)
2153  IWMMXT2_BUILTIN (iwmmxt_wmulwum, "wmulwum", WMULWUM)
2154  IWMMXT2_BUILTIN (iwmmxt_wmulwsmr, "wmulwsmr", WMULWSMR)
2155  IWMMXT2_BUILTIN (iwmmxt_wmulwumr, "wmulwumr", WMULWUMR)
2156  IWMMXT2_BUILTIN (iwmmxt_wmulwl, "wmulwl", WMULWL)
2157  IWMMXT2_BUILTIN (iwmmxt_wmulsmr, "wmulsmr", WMULSMR)
2158  IWMMXT2_BUILTIN (iwmmxt_wmulumr, "wmulumr", WMULUMR)
2159  IWMMXT2_BUILTIN (iwmmxt_wqmulm, "wqmulm", WQMULM)
2160  IWMMXT2_BUILTIN (iwmmxt_wqmulmr, "wqmulmr", WQMULMR)
2161  IWMMXT2_BUILTIN (iwmmxt_wqmulwm, "wqmulwm", WQMULWM)
2162  IWMMXT2_BUILTIN (iwmmxt_wqmulwmr, "wqmulwmr", WQMULWMR)
2163  IWMMXT_BUILTIN (iwmmxt_walignr0, "walignr0", WALIGNR0)
2164  IWMMXT_BUILTIN (iwmmxt_walignr1, "walignr1", WALIGNR1)
2165  IWMMXT_BUILTIN (iwmmxt_walignr2, "walignr2", WALIGNR2)
2166  IWMMXT_BUILTIN (iwmmxt_walignr3, "walignr3", WALIGNR3)
2167
2168#define IWMMXT_BUILTIN2(code, builtin) \
2169  { isa_bit_iwmmxt, CODE_FOR_##code, NULL, \
2170    ARM_BUILTIN_##builtin, UNKNOWN, 0 },
2171
2172#define IWMMXT2_BUILTIN2(code, builtin) \
2173  { isa_bit_iwmmxt2, CODE_FOR_##code, NULL, \
2174    ARM_BUILTIN_##builtin, UNKNOWN, 0 },
2175
2176  IWMMXT2_BUILTIN2 (iwmmxt_waddbhusm, WADDBHUSM)
2177  IWMMXT2_BUILTIN2 (iwmmxt_waddbhusl, WADDBHUSL)
2178  IWMMXT_BUILTIN2 (iwmmxt_wpackhss, WPACKHSS)
2179  IWMMXT_BUILTIN2 (iwmmxt_wpackwss, WPACKWSS)
2180  IWMMXT_BUILTIN2 (iwmmxt_wpackdss, WPACKDSS)
2181  IWMMXT_BUILTIN2 (iwmmxt_wpackhus, WPACKHUS)
2182  IWMMXT_BUILTIN2 (iwmmxt_wpackwus, WPACKWUS)
2183  IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS)
2184  IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ)
2185  IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ)
2186
2187
2188#define FP_BUILTIN(L, U) \
2189  {isa_nobit, CODE_FOR_##L, "__builtin_arm_"#L, ARM_BUILTIN_##U, \
2190   UNKNOWN, 0},
2191
2192  FP_BUILTIN (get_fpscr, GET_FPSCR)
2193  FP_BUILTIN (set_fpscr, SET_FPSCR)
2194#undef FP_BUILTIN
2195
2196#define CRYPTO_BUILTIN(L, U)					   \
2197  {isa_nobit, CODE_FOR_crypto_##L,	"__builtin_arm_crypto_"#L, \
2198   ARM_BUILTIN_CRYPTO_##U, UNKNOWN, 0},
2199#undef CRYPTO1
2200#undef CRYPTO2
2201#undef CRYPTO3
2202#define CRYPTO2(L, U, R, A1, A2) CRYPTO_BUILTIN (L, U)
2203#define CRYPTO1(L, U, R, A)
2204#define CRYPTO3(L, U, R, A1, A2, A3)
2205#include "crypto.def"
2206#undef CRYPTO1
2207#undef CRYPTO2
2208#undef CRYPTO3
2209
2210};
2211
2212static const struct builtin_description bdesc_1arg[] =
2213{
2214  IWMMXT_BUILTIN (iwmmxt_tmovmskb, "tmovmskb", TMOVMSKB)
2215  IWMMXT_BUILTIN (iwmmxt_tmovmskh, "tmovmskh", TMOVMSKH)
2216  IWMMXT_BUILTIN (iwmmxt_tmovmskw, "tmovmskw", TMOVMSKW)
2217  IWMMXT_BUILTIN (iwmmxt_waccb, "waccb", WACCB)
2218  IWMMXT_BUILTIN (iwmmxt_wacch, "wacch", WACCH)
2219  IWMMXT_BUILTIN (iwmmxt_waccw, "waccw", WACCW)
2220  IWMMXT_BUILTIN (iwmmxt_wunpckehub, "wunpckehub", WUNPCKEHUB)
2221  IWMMXT_BUILTIN (iwmmxt_wunpckehuh, "wunpckehuh", WUNPCKEHUH)
2222  IWMMXT_BUILTIN (iwmmxt_wunpckehuw, "wunpckehuw", WUNPCKEHUW)
2223  IWMMXT_BUILTIN (iwmmxt_wunpckehsb, "wunpckehsb", WUNPCKEHSB)
2224  IWMMXT_BUILTIN (iwmmxt_wunpckehsh, "wunpckehsh", WUNPCKEHSH)
2225  IWMMXT_BUILTIN (iwmmxt_wunpckehsw, "wunpckehsw", WUNPCKEHSW)
2226  IWMMXT_BUILTIN (iwmmxt_wunpckelub, "wunpckelub", WUNPCKELUB)
2227  IWMMXT_BUILTIN (iwmmxt_wunpckeluh, "wunpckeluh", WUNPCKELUH)
2228  IWMMXT_BUILTIN (iwmmxt_wunpckeluw, "wunpckeluw", WUNPCKELUW)
2229  IWMMXT_BUILTIN (iwmmxt_wunpckelsb, "wunpckelsb", WUNPCKELSB)
2230  IWMMXT_BUILTIN (iwmmxt_wunpckelsh, "wunpckelsh", WUNPCKELSH)
2231  IWMMXT_BUILTIN (iwmmxt_wunpckelsw, "wunpckelsw", WUNPCKELSW)
2232  IWMMXT2_BUILTIN (iwmmxt_wabsv8qi3, "wabsb", WABSB)
2233  IWMMXT2_BUILTIN (iwmmxt_wabsv4hi3, "wabsh", WABSH)
2234  IWMMXT2_BUILTIN (iwmmxt_wabsv2si3, "wabsw", WABSW)
2235  IWMMXT_BUILTIN (tbcstv8qi, "tbcstb", TBCSTB)
2236  IWMMXT_BUILTIN (tbcstv4hi, "tbcsth", TBCSTH)
2237  IWMMXT_BUILTIN (tbcstv2si, "tbcstw", TBCSTW)
2238
2239#define CRYPTO1(L, U, R, A) CRYPTO_BUILTIN (L, U)
2240#define CRYPTO2(L, U, R, A1, A2)
2241#define CRYPTO3(L, U, R, A1, A2, A3)
2242#include "crypto.def"
2243#undef CRYPTO1
2244#undef CRYPTO2
2245#undef CRYPTO3
2246};
2247
2248static const struct builtin_description bdesc_3arg[] =
2249{
2250#define CRYPTO3(L, U, R, A1, A2, A3) CRYPTO_BUILTIN (L, U)
2251#define CRYPTO1(L, U, R, A)
2252#define CRYPTO2(L, U, R, A1, A2)
2253#include "crypto.def"
2254#undef CRYPTO1
2255#undef CRYPTO2
2256#undef CRYPTO3
2257 };
2258#undef CRYPTO_BUILTIN
2259
2260/* Set up all the iWMMXt builtins.  This is not called if
2261   TARGET_IWMMXT is zero.  */
2262
2263static void
2264arm_init_iwmmxt_builtins (void)
2265{
2266  const struct builtin_description * d;
2267  size_t i;
2268
2269  tree V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
2270  tree V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
2271  tree V8QI_type_node = build_vector_type_for_mode (intQI_type_node, V8QImode);
2272
2273  tree v8qi_ftype_v8qi_v8qi_int
2274    = build_function_type_list (V8QI_type_node,
2275				V8QI_type_node, V8QI_type_node,
2276				integer_type_node, NULL_TREE);
2277  tree v4hi_ftype_v4hi_int
2278    = build_function_type_list (V4HI_type_node,
2279				V4HI_type_node, integer_type_node, NULL_TREE);
2280  tree v2si_ftype_v2si_int
2281    = build_function_type_list (V2SI_type_node,
2282				V2SI_type_node, integer_type_node, NULL_TREE);
2283  tree v2si_ftype_di_di
2284    = build_function_type_list (V2SI_type_node,
2285				long_long_integer_type_node,
2286				long_long_integer_type_node,
2287				NULL_TREE);
2288  tree di_ftype_di_int
2289    = build_function_type_list (long_long_integer_type_node,
2290				long_long_integer_type_node,
2291				integer_type_node, NULL_TREE);
2292  tree di_ftype_di_int_int
2293    = build_function_type_list (long_long_integer_type_node,
2294				long_long_integer_type_node,
2295				integer_type_node,
2296				integer_type_node, NULL_TREE);
2297  tree int_ftype_v8qi
2298    = build_function_type_list (integer_type_node,
2299				V8QI_type_node, NULL_TREE);
2300  tree int_ftype_v4hi
2301    = build_function_type_list (integer_type_node,
2302				V4HI_type_node, NULL_TREE);
2303  tree int_ftype_v2si
2304    = build_function_type_list (integer_type_node,
2305				V2SI_type_node, NULL_TREE);
2306  tree int_ftype_v8qi_int
2307    = build_function_type_list (integer_type_node,
2308				V8QI_type_node, integer_type_node, NULL_TREE);
2309  tree int_ftype_v4hi_int
2310    = build_function_type_list (integer_type_node,
2311				V4HI_type_node, integer_type_node, NULL_TREE);
2312  tree int_ftype_v2si_int
2313    = build_function_type_list (integer_type_node,
2314				V2SI_type_node, integer_type_node, NULL_TREE);
2315  tree v8qi_ftype_v8qi_int_int
2316    = build_function_type_list (V8QI_type_node,
2317				V8QI_type_node, integer_type_node,
2318				integer_type_node, NULL_TREE);
2319  tree v4hi_ftype_v4hi_int_int
2320    = build_function_type_list (V4HI_type_node,
2321				V4HI_type_node, integer_type_node,
2322				integer_type_node, NULL_TREE);
2323  tree v2si_ftype_v2si_int_int
2324    = build_function_type_list (V2SI_type_node,
2325				V2SI_type_node, integer_type_node,
2326				integer_type_node, NULL_TREE);
2327  /* Miscellaneous.  */
2328  tree v8qi_ftype_v4hi_v4hi
2329    = build_function_type_list (V8QI_type_node,
2330				V4HI_type_node, V4HI_type_node, NULL_TREE);
2331  tree v4hi_ftype_v2si_v2si
2332    = build_function_type_list (V4HI_type_node,
2333				V2SI_type_node, V2SI_type_node, NULL_TREE);
2334  tree v8qi_ftype_v4hi_v8qi
2335    = build_function_type_list (V8QI_type_node,
2336	                        V4HI_type_node, V8QI_type_node, NULL_TREE);
2337  tree v2si_ftype_v4hi_v4hi
2338    = build_function_type_list (V2SI_type_node,
2339				V4HI_type_node, V4HI_type_node, NULL_TREE);
2340  tree v2si_ftype_v8qi_v8qi
2341    = build_function_type_list (V2SI_type_node,
2342				V8QI_type_node, V8QI_type_node, NULL_TREE);
2343  tree v4hi_ftype_v4hi_di
2344    = build_function_type_list (V4HI_type_node,
2345				V4HI_type_node, long_long_integer_type_node,
2346				NULL_TREE);
2347  tree v2si_ftype_v2si_di
2348    = build_function_type_list (V2SI_type_node,
2349				V2SI_type_node, long_long_integer_type_node,
2350				NULL_TREE);
2351  tree di_ftype_void
2352    = build_function_type_list (long_long_unsigned_type_node, NULL_TREE);
2353  tree int_ftype_void
2354    = build_function_type_list (integer_type_node, NULL_TREE);
2355  tree di_ftype_v8qi
2356    = build_function_type_list (long_long_integer_type_node,
2357				V8QI_type_node, NULL_TREE);
2358  tree di_ftype_v4hi
2359    = build_function_type_list (long_long_integer_type_node,
2360				V4HI_type_node, NULL_TREE);
2361  tree di_ftype_v2si
2362    = build_function_type_list (long_long_integer_type_node,
2363				V2SI_type_node, NULL_TREE);
2364  tree v2si_ftype_v4hi
2365    = build_function_type_list (V2SI_type_node,
2366				V4HI_type_node, NULL_TREE);
2367  tree v4hi_ftype_v8qi
2368    = build_function_type_list (V4HI_type_node,
2369				V8QI_type_node, NULL_TREE);
2370  tree v8qi_ftype_v8qi
2371    = build_function_type_list (V8QI_type_node,
2372	                        V8QI_type_node, NULL_TREE);
2373  tree v4hi_ftype_v4hi
2374    = build_function_type_list (V4HI_type_node,
2375	                        V4HI_type_node, NULL_TREE);
2376  tree v2si_ftype_v2si
2377    = build_function_type_list (V2SI_type_node,
2378	                        V2SI_type_node, NULL_TREE);
2379
2380  tree di_ftype_di_v4hi_v4hi
2381    = build_function_type_list (long_long_unsigned_type_node,
2382				long_long_unsigned_type_node,
2383				V4HI_type_node, V4HI_type_node,
2384				NULL_TREE);
2385
2386  tree di_ftype_v4hi_v4hi
2387    = build_function_type_list (long_long_unsigned_type_node,
2388				V4HI_type_node,V4HI_type_node,
2389				NULL_TREE);
2390
2391  tree v2si_ftype_v2si_v4hi_v4hi
2392    = build_function_type_list (V2SI_type_node,
2393                                V2SI_type_node, V4HI_type_node,
2394                                V4HI_type_node, NULL_TREE);
2395
2396  tree v2si_ftype_v2si_v8qi_v8qi
2397    = build_function_type_list (V2SI_type_node,
2398                                V2SI_type_node, V8QI_type_node,
2399                                V8QI_type_node, NULL_TREE);
2400
2401  tree di_ftype_di_v2si_v2si
2402     = build_function_type_list (long_long_unsigned_type_node,
2403                                 long_long_unsigned_type_node,
2404                                 V2SI_type_node, V2SI_type_node,
2405                                 NULL_TREE);
2406
2407   tree di_ftype_di_di_int
2408     = build_function_type_list (long_long_unsigned_type_node,
2409                                 long_long_unsigned_type_node,
2410                                 long_long_unsigned_type_node,
2411                                 integer_type_node, NULL_TREE);
2412
2413   tree void_ftype_int
2414     = build_function_type_list (void_type_node,
2415                                 integer_type_node, NULL_TREE);
2416
2417   tree v8qi_ftype_char
2418     = build_function_type_list (V8QI_type_node,
2419                                 signed_char_type_node, NULL_TREE);
2420
2421   tree v4hi_ftype_short
2422     = build_function_type_list (V4HI_type_node,
2423                                 short_integer_type_node, NULL_TREE);
2424
2425   tree v2si_ftype_int
2426     = build_function_type_list (V2SI_type_node,
2427                                 integer_type_node, NULL_TREE);
2428
2429  /* Normal vector binops.  */
2430  tree v8qi_ftype_v8qi_v8qi
2431    = build_function_type_list (V8QI_type_node,
2432				V8QI_type_node, V8QI_type_node, NULL_TREE);
2433  tree v4hi_ftype_v4hi_v4hi
2434    = build_function_type_list (V4HI_type_node,
2435				V4HI_type_node,V4HI_type_node, NULL_TREE);
2436  tree v2si_ftype_v2si_v2si
2437    = build_function_type_list (V2SI_type_node,
2438				V2SI_type_node, V2SI_type_node, NULL_TREE);
2439  tree di_ftype_di_di
2440    = build_function_type_list (long_long_unsigned_type_node,
2441				long_long_unsigned_type_node,
2442				long_long_unsigned_type_node,
2443				NULL_TREE);
2444
2445  /* Add all builtins that are more or less simple operations on two
2446     operands.  */
2447  for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
2448    {
2449      /* Use one of the operands; the target can have a different mode for
2450	 mask-generating compares.  */
2451      machine_mode mode;
2452      tree type;
2453
2454      if (d->name == 0
2455	  || !(d->feature == isa_bit_iwmmxt
2456	       || d->feature == isa_bit_iwmmxt2))
2457	continue;
2458
2459      mode = insn_data[d->icode].operand[1].mode;
2460
2461      switch (mode)
2462	{
2463	case E_V8QImode:
2464	  type = v8qi_ftype_v8qi_v8qi;
2465	  break;
2466	case E_V4HImode:
2467	  type = v4hi_ftype_v4hi_v4hi;
2468	  break;
2469	case E_V2SImode:
2470	  type = v2si_ftype_v2si_v2si;
2471	  break;
2472	case E_DImode:
2473	  type = di_ftype_di_di;
2474	  break;
2475
2476	default:
2477	  gcc_unreachable ();
2478	}
2479
2480      def_mbuiltin (d->feature, d->name, type, d->code);
2481    }
2482
2483  /* Add the remaining MMX insns with somewhat more complicated types.  */
2484#define iwmmx_mbuiltin(NAME, TYPE, CODE)			\
2485  def_mbuiltin (isa_bit_iwmmxt, "__builtin_arm_" NAME, \
2486		(TYPE), ARM_BUILTIN_ ## CODE)
2487
2488#define iwmmx2_mbuiltin(NAME, TYPE, CODE)                      \
2489  def_mbuiltin (isa_bit_iwmmxt2, "__builtin_arm_" NAME, \
2490		(TYPE),	ARM_BUILTIN_ ## CODE)
2491
2492  iwmmx_mbuiltin ("wzero", di_ftype_void, WZERO);
2493  iwmmx_mbuiltin ("setwcgr0", void_ftype_int, SETWCGR0);
2494  iwmmx_mbuiltin ("setwcgr1", void_ftype_int, SETWCGR1);
2495  iwmmx_mbuiltin ("setwcgr2", void_ftype_int, SETWCGR2);
2496  iwmmx_mbuiltin ("setwcgr3", void_ftype_int, SETWCGR3);
2497  iwmmx_mbuiltin ("getwcgr0", int_ftype_void, GETWCGR0);
2498  iwmmx_mbuiltin ("getwcgr1", int_ftype_void, GETWCGR1);
2499  iwmmx_mbuiltin ("getwcgr2", int_ftype_void, GETWCGR2);
2500  iwmmx_mbuiltin ("getwcgr3", int_ftype_void, GETWCGR3);
2501
2502  iwmmx_mbuiltin ("wsllh", v4hi_ftype_v4hi_di, WSLLH);
2503  iwmmx_mbuiltin ("wsllw", v2si_ftype_v2si_di, WSLLW);
2504  iwmmx_mbuiltin ("wslld", di_ftype_di_di, WSLLD);
2505  iwmmx_mbuiltin ("wsllhi", v4hi_ftype_v4hi_int, WSLLHI);
2506  iwmmx_mbuiltin ("wsllwi", v2si_ftype_v2si_int, WSLLWI);
2507  iwmmx_mbuiltin ("wslldi", di_ftype_di_int, WSLLDI);
2508
2509  iwmmx_mbuiltin ("wsrlh", v4hi_ftype_v4hi_di, WSRLH);
2510  iwmmx_mbuiltin ("wsrlw", v2si_ftype_v2si_di, WSRLW);
2511  iwmmx_mbuiltin ("wsrld", di_ftype_di_di, WSRLD);
2512  iwmmx_mbuiltin ("wsrlhi", v4hi_ftype_v4hi_int, WSRLHI);
2513  iwmmx_mbuiltin ("wsrlwi", v2si_ftype_v2si_int, WSRLWI);
2514  iwmmx_mbuiltin ("wsrldi", di_ftype_di_int, WSRLDI);
2515
2516  iwmmx_mbuiltin ("wsrah", v4hi_ftype_v4hi_di, WSRAH);
2517  iwmmx_mbuiltin ("wsraw", v2si_ftype_v2si_di, WSRAW);
2518  iwmmx_mbuiltin ("wsrad", di_ftype_di_di, WSRAD);
2519  iwmmx_mbuiltin ("wsrahi", v4hi_ftype_v4hi_int, WSRAHI);
2520  iwmmx_mbuiltin ("wsrawi", v2si_ftype_v2si_int, WSRAWI);
2521  iwmmx_mbuiltin ("wsradi", di_ftype_di_int, WSRADI);
2522
2523  iwmmx_mbuiltin ("wrorh", v4hi_ftype_v4hi_di, WRORH);
2524  iwmmx_mbuiltin ("wrorw", v2si_ftype_v2si_di, WRORW);
2525  iwmmx_mbuiltin ("wrord", di_ftype_di_di, WRORD);
2526  iwmmx_mbuiltin ("wrorhi", v4hi_ftype_v4hi_int, WRORHI);
2527  iwmmx_mbuiltin ("wrorwi", v2si_ftype_v2si_int, WRORWI);
2528  iwmmx_mbuiltin ("wrordi", di_ftype_di_int, WRORDI);
2529
2530  iwmmx_mbuiltin ("wshufh", v4hi_ftype_v4hi_int, WSHUFH);
2531
2532  iwmmx_mbuiltin ("wsadb", v2si_ftype_v2si_v8qi_v8qi, WSADB);
2533  iwmmx_mbuiltin ("wsadh", v2si_ftype_v2si_v4hi_v4hi, WSADH);
2534  iwmmx_mbuiltin ("wmadds", v2si_ftype_v4hi_v4hi, WMADDS);
2535  iwmmx2_mbuiltin ("wmaddsx", v2si_ftype_v4hi_v4hi, WMADDSX);
2536  iwmmx2_mbuiltin ("wmaddsn", v2si_ftype_v4hi_v4hi, WMADDSN);
2537  iwmmx_mbuiltin ("wmaddu", v2si_ftype_v4hi_v4hi, WMADDU);
2538  iwmmx2_mbuiltin ("wmaddux", v2si_ftype_v4hi_v4hi, WMADDUX);
2539  iwmmx2_mbuiltin ("wmaddun", v2si_ftype_v4hi_v4hi, WMADDUN);
2540  iwmmx_mbuiltin ("wsadbz", v2si_ftype_v8qi_v8qi, WSADBZ);
2541  iwmmx_mbuiltin ("wsadhz", v2si_ftype_v4hi_v4hi, WSADHZ);
2542
2543  iwmmx_mbuiltin ("textrmsb", int_ftype_v8qi_int, TEXTRMSB);
2544  iwmmx_mbuiltin ("textrmsh", int_ftype_v4hi_int, TEXTRMSH);
2545  iwmmx_mbuiltin ("textrmsw", int_ftype_v2si_int, TEXTRMSW);
2546  iwmmx_mbuiltin ("textrmub", int_ftype_v8qi_int, TEXTRMUB);
2547  iwmmx_mbuiltin ("textrmuh", int_ftype_v4hi_int, TEXTRMUH);
2548  iwmmx_mbuiltin ("textrmuw", int_ftype_v2si_int, TEXTRMUW);
2549  iwmmx_mbuiltin ("tinsrb", v8qi_ftype_v8qi_int_int, TINSRB);
2550  iwmmx_mbuiltin ("tinsrh", v4hi_ftype_v4hi_int_int, TINSRH);
2551  iwmmx_mbuiltin ("tinsrw", v2si_ftype_v2si_int_int, TINSRW);
2552
2553  iwmmx_mbuiltin ("waccb", di_ftype_v8qi, WACCB);
2554  iwmmx_mbuiltin ("wacch", di_ftype_v4hi, WACCH);
2555  iwmmx_mbuiltin ("waccw", di_ftype_v2si, WACCW);
2556
2557  iwmmx_mbuiltin ("tmovmskb", int_ftype_v8qi, TMOVMSKB);
2558  iwmmx_mbuiltin ("tmovmskh", int_ftype_v4hi, TMOVMSKH);
2559  iwmmx_mbuiltin ("tmovmskw", int_ftype_v2si, TMOVMSKW);
2560
2561  iwmmx2_mbuiltin ("waddbhusm", v8qi_ftype_v4hi_v8qi, WADDBHUSM);
2562  iwmmx2_mbuiltin ("waddbhusl", v8qi_ftype_v4hi_v8qi, WADDBHUSL);
2563
2564  iwmmx_mbuiltin ("wpackhss", v8qi_ftype_v4hi_v4hi, WPACKHSS);
2565  iwmmx_mbuiltin ("wpackhus", v8qi_ftype_v4hi_v4hi, WPACKHUS);
2566  iwmmx_mbuiltin ("wpackwus", v4hi_ftype_v2si_v2si, WPACKWUS);
2567  iwmmx_mbuiltin ("wpackwss", v4hi_ftype_v2si_v2si, WPACKWSS);
2568  iwmmx_mbuiltin ("wpackdus", v2si_ftype_di_di, WPACKDUS);
2569  iwmmx_mbuiltin ("wpackdss", v2si_ftype_di_di, WPACKDSS);
2570
2571  iwmmx_mbuiltin ("wunpckehub", v4hi_ftype_v8qi, WUNPCKEHUB);
2572  iwmmx_mbuiltin ("wunpckehuh", v2si_ftype_v4hi, WUNPCKEHUH);
2573  iwmmx_mbuiltin ("wunpckehuw", di_ftype_v2si, WUNPCKEHUW);
2574  iwmmx_mbuiltin ("wunpckehsb", v4hi_ftype_v8qi, WUNPCKEHSB);
2575  iwmmx_mbuiltin ("wunpckehsh", v2si_ftype_v4hi, WUNPCKEHSH);
2576  iwmmx_mbuiltin ("wunpckehsw", di_ftype_v2si, WUNPCKEHSW);
2577  iwmmx_mbuiltin ("wunpckelub", v4hi_ftype_v8qi, WUNPCKELUB);
2578  iwmmx_mbuiltin ("wunpckeluh", v2si_ftype_v4hi, WUNPCKELUH);
2579  iwmmx_mbuiltin ("wunpckeluw", di_ftype_v2si, WUNPCKELUW);
2580  iwmmx_mbuiltin ("wunpckelsb", v4hi_ftype_v8qi, WUNPCKELSB);
2581  iwmmx_mbuiltin ("wunpckelsh", v2si_ftype_v4hi, WUNPCKELSH);
2582  iwmmx_mbuiltin ("wunpckelsw", di_ftype_v2si, WUNPCKELSW);
2583
2584  iwmmx_mbuiltin ("wmacs", di_ftype_di_v4hi_v4hi, WMACS);
2585  iwmmx_mbuiltin ("wmacsz", di_ftype_v4hi_v4hi, WMACSZ);
2586  iwmmx_mbuiltin ("wmacu", di_ftype_di_v4hi_v4hi, WMACU);
2587  iwmmx_mbuiltin ("wmacuz", di_ftype_v4hi_v4hi, WMACUZ);
2588
2589  iwmmx_mbuiltin ("walign", v8qi_ftype_v8qi_v8qi_int, WALIGNI);
2590  iwmmx_mbuiltin ("tmia", di_ftype_di_int_int, TMIA);
2591  iwmmx_mbuiltin ("tmiaph", di_ftype_di_int_int, TMIAPH);
2592  iwmmx_mbuiltin ("tmiabb", di_ftype_di_int_int, TMIABB);
2593  iwmmx_mbuiltin ("tmiabt", di_ftype_di_int_int, TMIABT);
2594  iwmmx_mbuiltin ("tmiatb", di_ftype_di_int_int, TMIATB);
2595  iwmmx_mbuiltin ("tmiatt", di_ftype_di_int_int, TMIATT);
2596
2597  iwmmx2_mbuiltin ("wabsb", v8qi_ftype_v8qi, WABSB);
2598  iwmmx2_mbuiltin ("wabsh", v4hi_ftype_v4hi, WABSH);
2599  iwmmx2_mbuiltin ("wabsw", v2si_ftype_v2si, WABSW);
2600
2601  iwmmx2_mbuiltin ("wqmiabb", v2si_ftype_v2si_v4hi_v4hi, WQMIABB);
2602  iwmmx2_mbuiltin ("wqmiabt", v2si_ftype_v2si_v4hi_v4hi, WQMIABT);
2603  iwmmx2_mbuiltin ("wqmiatb", v2si_ftype_v2si_v4hi_v4hi, WQMIATB);
2604  iwmmx2_mbuiltin ("wqmiatt", v2si_ftype_v2si_v4hi_v4hi, WQMIATT);
2605
2606  iwmmx2_mbuiltin ("wqmiabbn", v2si_ftype_v2si_v4hi_v4hi, WQMIABBN);
2607  iwmmx2_mbuiltin ("wqmiabtn", v2si_ftype_v2si_v4hi_v4hi, WQMIABTN);
2608  iwmmx2_mbuiltin ("wqmiatbn", v2si_ftype_v2si_v4hi_v4hi, WQMIATBN);
2609  iwmmx2_mbuiltin ("wqmiattn", v2si_ftype_v2si_v4hi_v4hi, WQMIATTN);
2610
2611  iwmmx2_mbuiltin ("wmiabb", di_ftype_di_v4hi_v4hi, WMIABB);
2612  iwmmx2_mbuiltin ("wmiabt", di_ftype_di_v4hi_v4hi, WMIABT);
2613  iwmmx2_mbuiltin ("wmiatb", di_ftype_di_v4hi_v4hi, WMIATB);
2614  iwmmx2_mbuiltin ("wmiatt", di_ftype_di_v4hi_v4hi, WMIATT);
2615
2616  iwmmx2_mbuiltin ("wmiabbn", di_ftype_di_v4hi_v4hi, WMIABBN);
2617  iwmmx2_mbuiltin ("wmiabtn", di_ftype_di_v4hi_v4hi, WMIABTN);
2618  iwmmx2_mbuiltin ("wmiatbn", di_ftype_di_v4hi_v4hi, WMIATBN);
2619  iwmmx2_mbuiltin ("wmiattn", di_ftype_di_v4hi_v4hi, WMIATTN);
2620
2621  iwmmx2_mbuiltin ("wmiawbb", di_ftype_di_v2si_v2si, WMIAWBB);
2622  iwmmx2_mbuiltin ("wmiawbt", di_ftype_di_v2si_v2si, WMIAWBT);
2623  iwmmx2_mbuiltin ("wmiawtb", di_ftype_di_v2si_v2si, WMIAWTB);
2624  iwmmx2_mbuiltin ("wmiawtt", di_ftype_di_v2si_v2si, WMIAWTT);
2625
2626  iwmmx2_mbuiltin ("wmiawbbn", di_ftype_di_v2si_v2si, WMIAWBBN);
2627  iwmmx2_mbuiltin ("wmiawbtn", di_ftype_di_v2si_v2si, WMIAWBTN);
2628  iwmmx2_mbuiltin ("wmiawtbn", di_ftype_di_v2si_v2si, WMIAWTBN);
2629  iwmmx2_mbuiltin ("wmiawttn", di_ftype_di_v2si_v2si, WMIAWTTN);
2630
2631  iwmmx2_mbuiltin ("wmerge", di_ftype_di_di_int, WMERGE);
2632
2633  iwmmx_mbuiltin ("tbcstb", v8qi_ftype_char, TBCSTB);
2634  iwmmx_mbuiltin ("tbcsth", v4hi_ftype_short, TBCSTH);
2635  iwmmx_mbuiltin ("tbcstw", v2si_ftype_int, TBCSTW);
2636
2637#undef iwmmx_mbuiltin
2638#undef iwmmx2_mbuiltin
2639}
2640
2641static void
2642arm_init_fp16_builtins (void)
2643{
2644  arm_fp16_type_node = make_node (REAL_TYPE);
2645  TYPE_PRECISION (arm_fp16_type_node) = GET_MODE_PRECISION (HFmode);
2646  layout_type (arm_fp16_type_node);
2647  if (arm_fp16_format)
2648    (*lang_hooks.types.register_builtin_type) (arm_fp16_type_node,
2649					       "__fp16");
2650}
2651
2652void
2653arm_init_builtins (void)
2654{
2655  if (TARGET_REALLY_IWMMXT)
2656    arm_init_iwmmxt_builtins ();
2657
2658  /* This creates the arm_simd_floatHF_type_node so must come before
2659     arm_init_neon_builtins which uses it.  */
2660  arm_init_fp16_builtins ();
2661
2662  arm_init_bf16_types ();
2663
2664  if (TARGET_MAYBE_HARD_FLOAT)
2665    {
2666      tree lane_check_fpr = build_function_type_list (void_type_node,
2667						      intSI_type_node,
2668						      intSI_type_node,
2669						      NULL);
2670      arm_builtin_decls[ARM_BUILTIN_SIMD_LANE_CHECK]
2671      = add_builtin_function ("__builtin_arm_lane_check", lane_check_fpr,
2672			      ARM_BUILTIN_SIMD_LANE_CHECK, BUILT_IN_MD,
2673			      NULL, NULL_TREE);
2674      if (TARGET_HAVE_MVE)
2675	arm_init_mve_builtins ();
2676      else
2677	arm_init_neon_builtins ();
2678      arm_init_vfp_builtins ();
2679      arm_init_crypto_builtins ();
2680    }
2681
2682  if (TARGET_CDE)
2683    arm_init_cde_builtins ();
2684
2685  arm_init_acle_builtins ();
2686
2687  if (TARGET_MAYBE_HARD_FLOAT)
2688    {
2689      tree ftype_set_fpscr
2690	= build_function_type_list (void_type_node, unsigned_type_node, NULL);
2691      tree ftype_get_fpscr
2692	= build_function_type_list (unsigned_type_node, NULL);
2693
2694      arm_builtin_decls[ARM_BUILTIN_GET_FPSCR]
2695	= add_builtin_function ("__builtin_arm_get_fpscr", ftype_get_fpscr,
2696				ARM_BUILTIN_GET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE);
2697      arm_builtin_decls[ARM_BUILTIN_SET_FPSCR]
2698	= add_builtin_function ("__builtin_arm_set_fpscr", ftype_set_fpscr,
2699				ARM_BUILTIN_SET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE);
2700    }
2701
2702  if (use_cmse)
2703    {
2704      tree ftype_cmse_nonsecure_caller
2705	= build_function_type_list (unsigned_type_node, NULL);
2706      arm_builtin_decls[ARM_BUILTIN_CMSE_NONSECURE_CALLER]
2707	= add_builtin_function ("__builtin_arm_cmse_nonsecure_caller",
2708				ftype_cmse_nonsecure_caller,
2709				ARM_BUILTIN_CMSE_NONSECURE_CALLER, BUILT_IN_MD,
2710				NULL, NULL_TREE);
2711    }
2712}
2713
2714/* Return the ARM builtin for CODE.  */
2715
2716tree
2717arm_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
2718{
2719  if (code >= ARM_BUILTIN_MAX)
2720    return error_mark_node;
2721
2722  return arm_builtin_decls[code];
2723}
2724
2725/* Errors in the source file can cause expand_expr to return const0_rtx
2726   where we expect a vector.  To avoid crashing, use one of the vector
2727   clear instructions.  */
2728
2729static rtx
2730safe_vector_operand (rtx x, machine_mode mode)
2731{
2732  if (x != const0_rtx)
2733    return x;
2734  x = gen_reg_rtx (mode);
2735
2736  emit_insn (gen_iwmmxt_clrdi (mode == DImode ? x
2737			       : gen_rtx_SUBREG (DImode, x, 0)));
2738  return x;
2739}
2740
2741/* Function to expand ternary builtins.  */
2742static rtx
2743arm_expand_ternop_builtin (enum insn_code icode,
2744                           tree exp, rtx target)
2745{
2746  rtx pat;
2747  tree arg0 = CALL_EXPR_ARG (exp, 0);
2748  tree arg1 = CALL_EXPR_ARG (exp, 1);
2749  tree arg2 = CALL_EXPR_ARG (exp, 2);
2750
2751  rtx op0 = expand_normal (arg0);
2752  rtx op1 = expand_normal (arg1);
2753  rtx op2 = expand_normal (arg2);
2754
2755  machine_mode tmode = insn_data[icode].operand[0].mode;
2756  machine_mode mode0 = insn_data[icode].operand[1].mode;
2757  machine_mode mode1 = insn_data[icode].operand[2].mode;
2758  machine_mode mode2 = insn_data[icode].operand[3].mode;
2759
2760  if (VECTOR_MODE_P (mode0))
2761    op0 = safe_vector_operand (op0, mode0);
2762  if (VECTOR_MODE_P (mode1))
2763    op1 = safe_vector_operand (op1, mode1);
2764  if (VECTOR_MODE_P (mode2))
2765    op2 = safe_vector_operand (op2, mode2);
2766
2767  if (! target
2768      || GET_MODE (target) != tmode
2769      || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2770    target = gen_reg_rtx (tmode);
2771
2772  gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode)
2773	      && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode)
2774	      && (GET_MODE (op2) == mode2 || GET_MODE (op2) == VOIDmode));
2775
2776  if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2777    op0 = copy_to_mode_reg (mode0, op0);
2778  if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
2779    op1 = copy_to_mode_reg (mode1, op1);
2780  if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
2781    op2 = copy_to_mode_reg (mode2, op2);
2782
2783  pat = GEN_FCN (icode) (target, op0, op1, op2);
2784  if (! pat)
2785    return 0;
2786  emit_insn (pat);
2787  return target;
2788}
2789
2790/* Subroutine of arm_expand_builtin to take care of binop insns.  */
2791
2792static rtx
2793arm_expand_binop_builtin (enum insn_code icode,
2794			  tree exp, rtx target)
2795{
2796  rtx pat;
2797  tree arg0 = CALL_EXPR_ARG (exp, 0);
2798  tree arg1 = CALL_EXPR_ARG (exp, 1);
2799  rtx op0 = expand_normal (arg0);
2800  rtx op1 = expand_normal (arg1);
2801  machine_mode tmode = insn_data[icode].operand[0].mode;
2802  machine_mode mode0 = insn_data[icode].operand[1].mode;
2803  machine_mode mode1 = insn_data[icode].operand[2].mode;
2804
2805  if (VECTOR_MODE_P (mode0))
2806    op0 = safe_vector_operand (op0, mode0);
2807  if (VECTOR_MODE_P (mode1))
2808    op1 = safe_vector_operand (op1, mode1);
2809
2810  if (! target
2811      || GET_MODE (target) != tmode
2812      || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2813    target = gen_reg_rtx (tmode);
2814
2815  gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode)
2816	      && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode));
2817
2818  if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2819    op0 = copy_to_mode_reg (mode0, op0);
2820  if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
2821    op1 = copy_to_mode_reg (mode1, op1);
2822
2823  pat = GEN_FCN (icode) (target, op0, op1);
2824  if (! pat)
2825    return 0;
2826  emit_insn (pat);
2827  return target;
2828}
2829
2830/* Subroutine of arm_expand_builtin to take care of unop insns.  */
2831
2832static rtx
2833arm_expand_unop_builtin (enum insn_code icode,
2834			 tree exp, rtx target, int do_load)
2835{
2836  rtx pat;
2837  tree arg0 = CALL_EXPR_ARG (exp, 0);
2838  rtx op0 = expand_normal (arg0);
2839  machine_mode tmode = insn_data[icode].operand[0].mode;
2840  machine_mode mode0 = insn_data[icode].operand[1].mode;
2841
2842  if (! target
2843      || GET_MODE (target) != tmode
2844      || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2845    target = gen_reg_rtx (tmode);
2846  if (do_load)
2847    op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
2848  else
2849    {
2850      if (VECTOR_MODE_P (mode0))
2851	op0 = safe_vector_operand (op0, mode0);
2852
2853      if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2854	op0 = copy_to_mode_reg (mode0, op0);
2855    }
2856
2857  pat = GEN_FCN (icode) (target, op0);
2858
2859  if (! pat)
2860    return 0;
2861  emit_insn (pat);
2862  return target;
2863}
2864
2865typedef enum {
2866  ARG_BUILTIN_COPY_TO_REG,
2867  ARG_BUILTIN_CONSTANT,
2868  ARG_BUILTIN_LANE_INDEX,
2869  ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX,
2870  ARG_BUILTIN_LANE_PAIR_INDEX,
2871  ARG_BUILTIN_LANE_QUADTUP_INDEX,
2872  ARG_BUILTIN_NEON_MEMORY,
2873  ARG_BUILTIN_MEMORY,
2874  ARG_BUILTIN_STOP
2875} builtin_arg;
2876
2877
2878/* EXP is a pointer argument to a Neon load or store intrinsic.  Derive
2879   and return an expression for the accessed memory.
2880
2881   The intrinsic function operates on a block of registers that has
2882   mode REG_MODE.  This block contains vectors of type TYPE_MODE.  The
2883   function references the memory at EXP of type TYPE and in mode
2884   MEM_MODE; this mode may be BLKmode if no more suitable mode is
2885   available.  */
2886
2887static tree
2888neon_dereference_pointer (tree exp, tree type, machine_mode mem_mode,
2889			  machine_mode reg_mode,
2890			  machine_mode vector_mode)
2891{
2892  HOST_WIDE_INT reg_size, vector_size, nvectors, nelems;
2893  tree elem_type, upper_bound, array_type;
2894
2895  /* Work out the size of the register block in bytes.  */
2896  reg_size = GET_MODE_SIZE (reg_mode);
2897
2898  /* Work out the size of each vector in bytes.  */
2899  vector_size = GET_MODE_SIZE (vector_mode);
2900
2901  /* Work out how many vectors there are.  */
2902  gcc_assert (reg_size % vector_size == 0);
2903  nvectors = reg_size / vector_size;
2904
2905  /* Work out the type of each element.  */
2906  gcc_assert (POINTER_TYPE_P (type));
2907  elem_type = TREE_TYPE (type);
2908
2909  /* Work out how many elements are being loaded or stored.
2910     MEM_MODE == REG_MODE implies a one-to-one mapping between register
2911     and memory elements; anything else implies a lane load or store.  */
2912  if (mem_mode == reg_mode)
2913    nelems = vector_size * nvectors / int_size_in_bytes (elem_type);
2914  else
2915    nelems = nvectors;
2916
2917  /* Create a type that describes the full access.  */
2918  upper_bound = build_int_cst (size_type_node, nelems - 1);
2919  array_type = build_array_type (elem_type, build_index_type (upper_bound));
2920
2921  /* Dereference EXP using that type.  */
2922  return fold_build2 (MEM_REF, array_type, exp,
2923		      build_int_cst (build_pointer_type (array_type), 0));
2924}
2925
2926/* EXP is a pointer argument to a vector scatter store intrinsics.
2927
2928   Consider the following example:
2929	VSTRW<v>.<dt> Qd, [Qm{, #+/-<imm>}]!
2930   When <Qm> used as the base register for the target address,
2931   this function is used to derive and return an expression for the
2932   accessed memory.
2933
2934   The intrinsic function operates on a block of registers that has mode
2935   REG_MODE.  This block contains vectors of type TYPE_MODE.  The function
2936   references the memory at EXP of type TYPE and in mode MEM_MODE.  This
2937   mode may be BLKmode if no more suitable mode is available.  */
2938
2939static tree
2940mve_dereference_pointer (tree exp, tree type, machine_mode reg_mode,
2941			 machine_mode vector_mode)
2942{
2943  HOST_WIDE_INT reg_size, vector_size, nelems;
2944  tree elem_type, upper_bound, array_type;
2945
2946  /* Work out the size of each vector in bytes.  */
2947  vector_size = GET_MODE_SIZE (vector_mode);
2948
2949  /* Work out the size of the register block in bytes.  */
2950  reg_size = GET_MODE_SIZE (reg_mode);
2951
2952  /* Work out the type of each element.  */
2953  gcc_assert (POINTER_TYPE_P (type));
2954  elem_type = TREE_TYPE (type);
2955
2956  nelems = reg_size / vector_size;
2957
2958  /* Create a type that describes the full access.  */
2959  upper_bound = build_int_cst (size_type_node, nelems - 1);
2960  array_type = build_array_type (elem_type, build_index_type (upper_bound));
2961
2962  /* Dereference EXP using that type.  */
2963  return fold_build2 (MEM_REF, array_type, exp,
2964		      build_int_cst (build_pointer_type (array_type), 0));
2965}
2966
2967/* Expand a builtin.  */
2968static rtx
2969arm_expand_builtin_args (rtx target, machine_mode map_mode, int fcode,
2970		      int icode, int have_retval, tree exp,
2971		      builtin_arg *args)
2972{
2973  rtx pat;
2974  tree arg[SIMD_MAX_BUILTIN_ARGS];
2975  rtx op[SIMD_MAX_BUILTIN_ARGS];
2976  machine_mode tmode = insn_data[icode].operand[0].mode;
2977  machine_mode mode[SIMD_MAX_BUILTIN_ARGS];
2978  tree formals;
2979  int argc = 0;
2980  rtx_insn * insn;
2981
2982  if (have_retval
2983      && (!target
2984	  || GET_MODE (target) != tmode
2985	  || !(*insn_data[icode].operand[0].predicate) (target, tmode)))
2986    target = gen_reg_rtx (tmode);
2987
2988  formals = TYPE_ARG_TYPES (TREE_TYPE (arm_builtin_decls[fcode]));
2989
2990  for (;;)
2991    {
2992      builtin_arg thisarg = args[argc];
2993
2994      if (thisarg == ARG_BUILTIN_STOP)
2995	break;
2996      else
2997	{
2998	  int opno = argc + have_retval;
2999	  arg[argc] = CALL_EXPR_ARG (exp, argc);
3000	  mode[argc] = insn_data[icode].operand[opno].mode;
3001	  if (thisarg == ARG_BUILTIN_NEON_MEMORY)
3002            {
3003              machine_mode other_mode
3004		= insn_data[icode].operand[1 - opno].mode;
3005	      if (TARGET_HAVE_MVE && mode[argc] != other_mode)
3006		{
3007		  arg[argc] = mve_dereference_pointer (arg[argc],
3008						    TREE_VALUE (formals),
3009						    other_mode, map_mode);
3010		}
3011	      else
3012		arg[argc] = neon_dereference_pointer (arg[argc],
3013						      TREE_VALUE (formals),
3014						      mode[argc], other_mode,
3015						      map_mode);
3016            }
3017
3018	  /* Use EXPAND_MEMORY for ARG_BUILTIN_MEMORY and
3019	     ARG_BUILTIN_NEON_MEMORY to ensure a MEM_P be returned.  */
3020	  op[argc] = expand_expr (arg[argc], NULL_RTX, VOIDmode,
3021				  ((thisarg == ARG_BUILTIN_MEMORY
3022				    || thisarg == ARG_BUILTIN_NEON_MEMORY)
3023				   ? EXPAND_MEMORY : EXPAND_NORMAL));
3024
3025	  switch (thisarg)
3026	    {
3027	    case ARG_BUILTIN_MEMORY:
3028	    case ARG_BUILTIN_COPY_TO_REG:
3029	      if (POINTER_TYPE_P (TREE_TYPE (arg[argc])))
3030		op[argc] = convert_memory_address (Pmode, op[argc]);
3031	      /*gcc_assert (GET_MODE (op[argc]) == mode[argc]); */
3032	      if (!(*insn_data[icode].operand[opno].predicate)
3033		  (op[argc], mode[argc]))
3034		op[argc] = copy_to_mode_reg (mode[argc], op[argc]);
3035	      break;
3036
3037	    case ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX:
3038	      gcc_assert (argc > 1);
3039	      if (CONST_INT_P (op[argc]))
3040		{
3041		  neon_lane_bounds (op[argc], 0,
3042				    GET_MODE_NUNITS (map_mode), exp);
3043		  /* Keep to GCC-vector-extension lane indices in the RTL.  */
3044		  op[argc] =
3045		    GEN_INT (NEON_ENDIAN_LANE_N (map_mode, INTVAL (op[argc])));
3046		}
3047	      goto constant_arg;
3048
3049	    case ARG_BUILTIN_LANE_INDEX:
3050	      /* Previous argument must be a vector, which this indexes.  */
3051	      gcc_assert (argc > 0);
3052	      if (CONST_INT_P (op[argc]))
3053		{
3054		  machine_mode vmode = mode[argc - 1];
3055		  neon_lane_bounds (op[argc], 0, GET_MODE_NUNITS (vmode), exp);
3056		}
3057	      /* If the lane index isn't a constant then error out.  */
3058	      goto constant_arg;
3059
3060	    case ARG_BUILTIN_LANE_PAIR_INDEX:
3061	      /* Previous argument must be a vector, which this indexes. The
3062		 indexing will always select i and i+1 out of the vector, which
3063		 puts a limit on i.  */
3064	      gcc_assert (argc > 0);
3065	      if (CONST_INT_P (op[argc]))
3066		{
3067		  machine_mode vmode = mode[argc - 1];
3068		  neon_lane_bounds (op[argc], 0,
3069				    GET_MODE_NUNITS (vmode) / 2, exp);
3070		}
3071	      /* If the lane index isn't a constant then error out.  */
3072	      goto constant_arg;
3073
3074	    case ARG_BUILTIN_LANE_QUADTUP_INDEX:
3075	      /* Previous argument must be a vector, which this indexes.  */
3076	      gcc_assert (argc > 0);
3077	      if (CONST_INT_P (op[argc]))
3078		{
3079		  machine_mode vmode = mode[argc - 1];
3080		  neon_lane_bounds (op[argc], 0,
3081				    GET_MODE_NUNITS (vmode) / 4, exp);
3082		}
3083	      /* If the lane index isn't a constant then error out.  */
3084	      goto constant_arg;
3085
3086	    case ARG_BUILTIN_CONSTANT:
3087constant_arg:
3088	      if (!(*insn_data[icode].operand[opno].predicate)
3089		  (op[argc], mode[argc]))
3090		{
3091		  if (IN_RANGE (fcode, ARM_BUILTIN_CDE_PATTERN_START,
3092				ARM_BUILTIN_CDE_PATTERN_END))
3093		    {
3094		      if (argc == 0)
3095			{
3096			  unsigned int cp_bit = (CONST_INT_P (op[argc])
3097						 ? UINTVAL (op[argc]) : -1);
3098			  if (IN_RANGE (cp_bit, 0, ARM_CDE_CONST_COPROC))
3099			    error ("%Kcoprocessor %d is not enabled "
3100				   "with +cdecp%d", exp, cp_bit, cp_bit);
3101			  else
3102			    error ("%Kcoproc must be a constant immediate in "
3103				   "range [0-%d] enabled with +cdecp<N>", exp,
3104				   ARM_CDE_CONST_COPROC);
3105			}
3106		      else
3107			/* Here we mention the builtin name to follow the same
3108			   format that the C/C++ frontends use for referencing
3109			   a given argument index.  */
3110			error ("%Kargument %d to %qE must be a constant immediate "
3111			       "in range [0-%d]", exp, argc + 1,
3112			       arm_builtin_decls[fcode],
3113			       cde_builtin_data[fcode -
3114			       ARM_BUILTIN_CDE_PATTERN_START].imm_max);
3115		    }
3116		  else
3117		    error ("%Kargument %d must be a constant immediate",
3118			   exp, argc + 1);
3119		  /* We have failed to expand the pattern, and are safely
3120		     in to invalid code.  But the mid-end will still try to
3121		     build an assignment for this node while it expands,
3122		     before stopping for the error, just pass it back
3123		     TARGET to ensure a valid assignment.  */
3124		  return target;
3125		}
3126	      break;
3127
3128	      case ARG_BUILTIN_NEON_MEMORY:
3129	      /* Check if expand failed.  */
3130	      if (op[argc] == const0_rtx)
3131		return 0;
3132	      gcc_assert (MEM_P (op[argc]));
3133	      PUT_MODE (op[argc], mode[argc]);
3134	      /* ??? arm_neon.h uses the same built-in functions for signed
3135		 and unsigned accesses, casting where necessary.  This isn't
3136		 alias safe.  */
3137	      set_mem_alias_set (op[argc], 0);
3138	      if (!(*insn_data[icode].operand[opno].predicate)
3139                   (op[argc], mode[argc]))
3140		op[argc] = (replace_equiv_address
3141			    (op[argc],
3142			     copy_to_mode_reg (Pmode, XEXP (op[argc], 0))));
3143              break;
3144
3145	    case ARG_BUILTIN_STOP:
3146	      gcc_unreachable ();
3147	    }
3148
3149	  argc++;
3150	}
3151    }
3152
3153  if (have_retval)
3154    switch (argc)
3155      {
3156      case 0:
3157	pat = GEN_FCN (icode) (target);
3158	break;
3159      case 1:
3160	pat = GEN_FCN (icode) (target, op[0]);
3161	break;
3162
3163      case 2:
3164	pat = GEN_FCN (icode) (target, op[0], op[1]);
3165	break;
3166
3167      case 3:
3168	pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
3169	break;
3170
3171      case 4:
3172	pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
3173	break;
3174
3175      case 5:
3176	pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4]);
3177	break;
3178
3179      case 6:
3180	pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4], op[5]);
3181	break;
3182
3183      default:
3184	gcc_unreachable ();
3185      }
3186  else
3187    switch (argc)
3188      {
3189      case 1:
3190	pat = GEN_FCN (icode) (op[0]);
3191	break;
3192
3193      case 2:
3194	pat = GEN_FCN (icode) (op[0], op[1]);
3195	break;
3196
3197      case 3:
3198	pat = GEN_FCN (icode) (op[0], op[1], op[2]);
3199	break;
3200
3201      case 4:
3202	pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
3203	break;
3204
3205      case 5:
3206	pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
3207	break;
3208
3209      case 6:
3210	pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]);
3211	break;
3212
3213      default:
3214	gcc_unreachable ();
3215      }
3216
3217  if (!pat)
3218    return 0;
3219
3220  /* Check whether our current target implements the pattern chosen for this
3221     builtin and error out if not.  */
3222  start_sequence ();
3223  emit_insn (pat);
3224  insn = get_insns ();
3225  end_sequence ();
3226
3227  if (recog_memoized (insn) < 0)
3228    error ("this builtin is not supported for this target");
3229  else
3230    emit_insn (insn);
3231
3232  return target;
3233}
3234
3235/* Expand a builtin.  These builtins are "special" because they don't have
3236   symbolic constants defined per-instruction or per instruction-variant.
3237   Instead, the required info is looked up in the ARM_BUILTIN_DATA record that
3238   is passed into the function.  */
3239
3240static rtx
3241arm_expand_builtin_1 (int fcode, tree exp, rtx target,
3242			   arm_builtin_datum *d)
3243{
3244  enum insn_code icode = d->code;
3245  builtin_arg args[SIMD_MAX_BUILTIN_ARGS + 1];
3246  int num_args = insn_data[d->code].n_operands;
3247  int is_void = 0;
3248  int k;
3249  bool neon = false;
3250  bool mve = false;
3251
3252  if (IN_RANGE (fcode, ARM_BUILTIN_VFP_BASE, ARM_BUILTIN_ACLE_BASE - 1))
3253    neon = true;
3254
3255  if (IN_RANGE (fcode, ARM_BUILTIN_MVE_BASE, ARM_BUILTIN_MAX - 1))
3256    mve = true;
3257
3258  is_void = !!(d->qualifiers[0] & qualifier_void);
3259
3260  num_args += is_void;
3261
3262  for (k = 1; k < num_args; k++)
3263    {
3264      /* We have four arrays of data, each indexed in a different fashion.
3265	 qualifiers - element 0 always describes the function return type.
3266	 operands - element 0 is either the operand for return value (if
3267	 the function has a non-void return type) or the operand for the
3268	 first argument.
3269	 expr_args - element 0 always holds the first argument.
3270	 args - element 0 is always used for the return type.  */
3271      int qualifiers_k = k;
3272      int operands_k = k - is_void;
3273      int expr_args_k = k - 1;
3274
3275      if (d->qualifiers[qualifiers_k] & qualifier_lane_index)
3276	args[k] = ARG_BUILTIN_LANE_INDEX;
3277      else if (d->qualifiers[qualifiers_k] & qualifier_lane_pair_index)
3278	args[k] = ARG_BUILTIN_LANE_PAIR_INDEX;
3279      else if (d->qualifiers[qualifiers_k] & qualifier_lane_quadtup_index)
3280	args[k] = ARG_BUILTIN_LANE_QUADTUP_INDEX;
3281      else if (d->qualifiers[qualifiers_k] & qualifier_struct_load_store_lane_index)
3282	args[k] = ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX;
3283      else if (d->qualifiers[qualifiers_k] & qualifier_immediate)
3284	args[k] = ARG_BUILTIN_CONSTANT;
3285      else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate)
3286	{
3287	  rtx arg
3288	    = expand_normal (CALL_EXPR_ARG (exp,
3289					    (expr_args_k)));
3290	  /* Handle constants only if the predicate allows it.  */
3291	  bool op_const_int_p =
3292	    (CONST_INT_P (arg)
3293	     && (*insn_data[icode].operand[operands_k].predicate)
3294	     (arg, insn_data[icode].operand[operands_k].mode));
3295	  args[k] = op_const_int_p ? ARG_BUILTIN_CONSTANT : ARG_BUILTIN_COPY_TO_REG;
3296	}
3297      else if (d->qualifiers[qualifiers_k] & qualifier_pointer)
3298	{
3299	  if (neon || mve)
3300	    args[k] = ARG_BUILTIN_NEON_MEMORY;
3301	  else
3302	    args[k] = ARG_BUILTIN_MEMORY;
3303	}
3304      else
3305	args[k] = ARG_BUILTIN_COPY_TO_REG;
3306    }
3307  args[k] = ARG_BUILTIN_STOP;
3308
3309  /* The interface to arm_expand_builtin_args expects a 0 if
3310     the function is void, and a 1 if it is not.  */
3311  return arm_expand_builtin_args
3312    (target, d->mode, fcode, icode, !is_void, exp,
3313     &args[1]);
3314}
3315
3316/* Expand an ACLE builtin, i.e. those registered only if their respective
3317   target constraints are met.  This check happens within
3318   arm_expand_builtin_args.  */
3319
3320static rtx
3321arm_expand_acle_builtin (int fcode, tree exp, rtx target)
3322{
3323  if (fcode == ARM_BUILTIN_SAT_IMM_CHECK)
3324    {
3325      /* Check the saturation immediate bounds.  */
3326
3327      rtx min_sat = expand_normal (CALL_EXPR_ARG (exp, 1));
3328      rtx max_sat = expand_normal (CALL_EXPR_ARG (exp, 2));
3329      gcc_assert (CONST_INT_P (min_sat));
3330      gcc_assert (CONST_INT_P (max_sat));
3331      rtx sat_imm = expand_normal (CALL_EXPR_ARG (exp, 0));
3332      if (CONST_INT_P (sat_imm))
3333	{
3334	  if (!IN_RANGE (sat_imm, min_sat, max_sat))
3335	    error ("%Ksaturation bit range must be in the range [%wd, %wd]",
3336		   exp, UINTVAL (min_sat), UINTVAL (max_sat));
3337	}
3338      else
3339	error ("%Ksaturation bit range must be a constant immediate", exp);
3340      /* Don't generate any RTL.  */
3341      return const0_rtx;
3342    }
3343
3344  gcc_assert (fcode != ARM_BUILTIN_CDE_BASE);
3345  arm_builtin_datum *d
3346    = (fcode < ARM_BUILTIN_CDE_BASE)
3347      ? &acle_builtin_data[fcode - ARM_BUILTIN_ACLE_PATTERN_START]
3348      : &cde_builtin_data[fcode - ARM_BUILTIN_CDE_PATTERN_START].base;
3349
3350  return arm_expand_builtin_1 (fcode, exp, target, d);
3351}
3352
3353/* Expand an MVE builtin, i.e. those registered only if their respective target
3354   constraints are met.  This check happens within arm_expand_builtin.  */
3355
3356static rtx
3357arm_expand_mve_builtin (int fcode, tree exp, rtx target)
3358{
3359  if (fcode >= ARM_BUILTIN_MVE_BASE && !TARGET_HAVE_MVE)
3360  {
3361    fatal_error (input_location,
3362		"You must enable MVE instructions"
3363		" to use these intrinsics");
3364    return const0_rtx;
3365  }
3366
3367  arm_builtin_datum *d
3368    = &mve_builtin_data[fcode - ARM_BUILTIN_MVE_PATTERN_START];
3369
3370  return arm_expand_builtin_1 (fcode, exp, target, d);
3371}
3372
3373/* Expand a Neon builtin, i.e. those registered only if TARGET_NEON holds.
3374   Most of these are "special" because they don't have symbolic
3375   constants defined per-instruction or per instruction-variant.  Instead, the
3376   required info is looked up in the table neon_builtin_data.  */
3377
3378static rtx
3379arm_expand_neon_builtin (int fcode, tree exp, rtx target)
3380{
3381  if (fcode >= ARM_BUILTIN_NEON_BASE && ! TARGET_NEON)
3382    {
3383      fatal_error (input_location,
3384		   "You must enable NEON instructions"
3385		   " (e.g. %<-mfloat-abi=softfp%> %<-mfpu=neon%>)"
3386		   " to use these intrinsics.");
3387      return const0_rtx;
3388    }
3389
3390  arm_builtin_datum *d
3391    = &neon_builtin_data[fcode - ARM_BUILTIN_NEON_PATTERN_START];
3392
3393  return arm_expand_builtin_1 (fcode, exp, target, d);
3394}
3395
3396/* Expand a VFP builtin.  These builtins are treated like
3397   neon builtins except that the data is looked up in table
3398   VFP_BUILTIN_DATA.  */
3399
3400static rtx
3401arm_expand_vfp_builtin (int fcode, tree exp, rtx target)
3402{
3403  if (fcode >= ARM_BUILTIN_VFP_BASE && ! TARGET_HARD_FLOAT)
3404    {
3405      fatal_error (input_location,
3406		   "You must enable VFP instructions"
3407		   " to use these intrinsics.");
3408      return const0_rtx;
3409    }
3410
3411  arm_builtin_datum *d
3412    = &vfp_builtin_data[fcode - ARM_BUILTIN_VFP_PATTERN_START];
3413
3414  return arm_expand_builtin_1 (fcode, exp, target, d);
3415}
3416
3417/* Expand an expression EXP that calls a built-in function,
3418   with result going to TARGET if that's convenient
3419   (and in mode MODE if that's convenient).
3420   SUBTARGET may be used as the target for computing one of EXP's operands.
3421   IGNORE is nonzero if the value is to be ignored.  */
3422
3423rtx
3424arm_expand_builtin (tree exp,
3425		    rtx target,
3426		    rtx subtarget ATTRIBUTE_UNUSED,
3427		    machine_mode mode ATTRIBUTE_UNUSED,
3428		    int ignore ATTRIBUTE_UNUSED)
3429{
3430  const struct builtin_description * d;
3431  enum insn_code    icode;
3432  tree              fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3433  tree              arg0;
3434  tree              arg1;
3435  tree              arg2;
3436  rtx               op0;
3437  rtx               op1;
3438  rtx               op2;
3439  rtx               pat;
3440  unsigned int      fcode = DECL_MD_FUNCTION_CODE (fndecl);
3441  size_t            i;
3442  machine_mode tmode;
3443  machine_mode mode0;
3444  machine_mode mode1;
3445  machine_mode mode2;
3446  int opint;
3447  int selector;
3448  int mask;
3449  int imm;
3450
3451  if (fcode == ARM_BUILTIN_SIMD_LANE_CHECK)
3452    {
3453      /* Builtin is only to check bounds of the lane passed to some intrinsics
3454	 that are implemented with gcc vector extensions in arm_neon.h.  */
3455
3456      tree nlanes = CALL_EXPR_ARG (exp, 0);
3457      gcc_assert (TREE_CODE (nlanes) == INTEGER_CST);
3458      rtx lane_idx = expand_normal (CALL_EXPR_ARG (exp, 1));
3459      if (CONST_INT_P (lane_idx))
3460	neon_lane_bounds (lane_idx, 0, TREE_INT_CST_LOW (nlanes), exp);
3461      else
3462	error ("%Klane index must be a constant immediate", exp);
3463      /* Don't generate any RTL.  */
3464      return const0_rtx;
3465    }
3466  if (fcode >= ARM_BUILTIN_MVE_BASE)
3467    return arm_expand_mve_builtin (fcode, exp, target);
3468
3469  if (fcode >= ARM_BUILTIN_ACLE_BASE)
3470    return arm_expand_acle_builtin (fcode, exp, target);
3471
3472  if (fcode >= ARM_BUILTIN_NEON_BASE)
3473    return arm_expand_neon_builtin (fcode, exp, target);
3474
3475  if (fcode >= ARM_BUILTIN_VFP_BASE)
3476    return arm_expand_vfp_builtin (fcode, exp, target);
3477
3478  /* Check in the context of the function making the call whether the
3479     builtin is supported.  */
3480  if (fcode >= ARM_BUILTIN_CRYPTO_BASE
3481      && (!TARGET_CRYPTO || !TARGET_HARD_FLOAT))
3482    {
3483      fatal_error (input_location,
3484		   "You must enable crypto instructions"
3485		   " (e.g. include %<-mfloat-abi=softfp%> "
3486		   "%<-mfpu=crypto-neon%>)"
3487		   " to use these intrinsics.");
3488      return const0_rtx;
3489    }
3490
3491  switch (fcode)
3492    {
3493    case ARM_BUILTIN_GET_FPSCR_NZCVQC:
3494    case ARM_BUILTIN_SET_FPSCR_NZCVQC:
3495      if (fcode == ARM_BUILTIN_GET_FPSCR_NZCVQC)
3496	{
3497	  icode = CODE_FOR_get_fpscr_nzcvqc;
3498	  target = gen_reg_rtx (SImode);
3499	  emit_insn (GEN_FCN (icode) (target));
3500	  return target;
3501	}
3502      else
3503	{
3504	  icode = CODE_FOR_set_fpscr_nzcvqc;
3505	  op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
3506	  emit_insn (GEN_FCN (icode) (force_reg (SImode, op0)));
3507	  return NULL_RTX;
3508	}
3509
3510    case ARM_BUILTIN_GET_FPSCR:
3511    case ARM_BUILTIN_SET_FPSCR:
3512      if (fcode == ARM_BUILTIN_GET_FPSCR)
3513	{
3514	  icode = CODE_FOR_get_fpscr;
3515	  target = gen_reg_rtx (SImode);
3516	  pat = GEN_FCN (icode) (target);
3517	}
3518      else
3519	{
3520	  target = NULL_RTX;
3521	  icode = CODE_FOR_set_fpscr;
3522	  arg0 = CALL_EXPR_ARG (exp, 0);
3523	  op0 = expand_normal (arg0);
3524	  pat = GEN_FCN (icode) (force_reg (SImode, op0));
3525	}
3526      emit_insn (pat);
3527      return target;
3528
3529    case ARM_BUILTIN_CMSE_NONSECURE_CALLER:
3530      target = gen_reg_rtx (SImode);
3531      op0 = arm_return_addr (0, NULL_RTX);
3532      emit_insn (gen_andsi3 (target, op0, const1_rtx));
3533      op1 = gen_rtx_EQ (SImode, target, const0_rtx);
3534      emit_insn (gen_cstoresi4 (target, op1, target, const0_rtx));
3535      return target;
3536
3537    case ARM_BUILTIN_TEXTRMSB:
3538    case ARM_BUILTIN_TEXTRMUB:
3539    case ARM_BUILTIN_TEXTRMSH:
3540    case ARM_BUILTIN_TEXTRMUH:
3541    case ARM_BUILTIN_TEXTRMSW:
3542    case ARM_BUILTIN_TEXTRMUW:
3543      icode = (fcode == ARM_BUILTIN_TEXTRMSB ? CODE_FOR_iwmmxt_textrmsb
3544	       : fcode == ARM_BUILTIN_TEXTRMUB ? CODE_FOR_iwmmxt_textrmub
3545	       : fcode == ARM_BUILTIN_TEXTRMSH ? CODE_FOR_iwmmxt_textrmsh
3546	       : fcode == ARM_BUILTIN_TEXTRMUH ? CODE_FOR_iwmmxt_textrmuh
3547	       : CODE_FOR_iwmmxt_textrmw);
3548
3549      arg0 = CALL_EXPR_ARG (exp, 0);
3550      arg1 = CALL_EXPR_ARG (exp, 1);
3551      op0 = expand_normal (arg0);
3552      op1 = expand_normal (arg1);
3553      tmode = insn_data[icode].operand[0].mode;
3554      mode0 = insn_data[icode].operand[1].mode;
3555      mode1 = insn_data[icode].operand[2].mode;
3556
3557      if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3558	op0 = copy_to_mode_reg (mode0, op0);
3559      if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
3560	{
3561	  /* @@@ better error message */
3562	  error ("selector must be an immediate");
3563	  return gen_reg_rtx (tmode);
3564	}
3565
3566      opint = INTVAL (op1);
3567      if (fcode == ARM_BUILTIN_TEXTRMSB || fcode == ARM_BUILTIN_TEXTRMUB)
3568	{
3569	  if (opint > 7 || opint < 0)
3570	    error ("the range of selector should be in 0 to 7");
3571	}
3572      else if (fcode == ARM_BUILTIN_TEXTRMSH || fcode == ARM_BUILTIN_TEXTRMUH)
3573	{
3574	  if (opint > 3 || opint < 0)
3575	    error ("the range of selector should be in 0 to 3");
3576	}
3577      else /* ARM_BUILTIN_TEXTRMSW || ARM_BUILTIN_TEXTRMUW.  */
3578	{
3579	  if (opint > 1 || opint < 0)
3580	    error ("the range of selector should be in 0 to 1");
3581	}
3582
3583      if (target == 0
3584	  || GET_MODE (target) != tmode
3585	  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3586	target = gen_reg_rtx (tmode);
3587      pat = GEN_FCN (icode) (target, op0, op1);
3588      if (! pat)
3589	return 0;
3590      emit_insn (pat);
3591      return target;
3592
3593    case ARM_BUILTIN_WALIGNI:
3594      /* If op2 is immediate, call walighi, else call walighr.  */
3595      arg0 = CALL_EXPR_ARG (exp, 0);
3596      arg1 = CALL_EXPR_ARG (exp, 1);
3597      arg2 = CALL_EXPR_ARG (exp, 2);
3598      op0 = expand_normal (arg0);
3599      op1 = expand_normal (arg1);
3600      op2 = expand_normal (arg2);
3601      if (CONST_INT_P (op2))
3602        {
3603	  icode = CODE_FOR_iwmmxt_waligni;
3604          tmode = insn_data[icode].operand[0].mode;
3605	  mode0 = insn_data[icode].operand[1].mode;
3606	  mode1 = insn_data[icode].operand[2].mode;
3607	  mode2 = insn_data[icode].operand[3].mode;
3608          if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
3609	    op0 = copy_to_mode_reg (mode0, op0);
3610          if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
3611	    op1 = copy_to_mode_reg (mode1, op1);
3612          gcc_assert ((*insn_data[icode].operand[3].predicate) (op2, mode2));
3613	  selector = INTVAL (op2);
3614	  if (selector > 7 || selector < 0)
3615	    error ("the range of selector should be in 0 to 7");
3616	}
3617      else
3618        {
3619	  icode = CODE_FOR_iwmmxt_walignr;
3620          tmode = insn_data[icode].operand[0].mode;
3621	  mode0 = insn_data[icode].operand[1].mode;
3622	  mode1 = insn_data[icode].operand[2].mode;
3623	  mode2 = insn_data[icode].operand[3].mode;
3624          if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
3625	    op0 = copy_to_mode_reg (mode0, op0);
3626          if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
3627	    op1 = copy_to_mode_reg (mode1, op1);
3628          if (!(*insn_data[icode].operand[3].predicate) (op2, mode2))
3629	    op2 = copy_to_mode_reg (mode2, op2);
3630	}
3631      if (target == 0
3632	  || GET_MODE (target) != tmode
3633	  || !(*insn_data[icode].operand[0].predicate) (target, tmode))
3634	target = gen_reg_rtx (tmode);
3635      pat = GEN_FCN (icode) (target, op0, op1, op2);
3636      if (!pat)
3637	return 0;
3638      emit_insn (pat);
3639      return target;
3640
3641    case ARM_BUILTIN_TINSRB:
3642    case ARM_BUILTIN_TINSRH:
3643    case ARM_BUILTIN_TINSRW:
3644    case ARM_BUILTIN_WMERGE:
3645      icode = (fcode == ARM_BUILTIN_TINSRB ? CODE_FOR_iwmmxt_tinsrb
3646	       : fcode == ARM_BUILTIN_TINSRH ? CODE_FOR_iwmmxt_tinsrh
3647	       : fcode == ARM_BUILTIN_WMERGE ? CODE_FOR_iwmmxt_wmerge
3648	       : CODE_FOR_iwmmxt_tinsrw);
3649      arg0 = CALL_EXPR_ARG (exp, 0);
3650      arg1 = CALL_EXPR_ARG (exp, 1);
3651      arg2 = CALL_EXPR_ARG (exp, 2);
3652      op0 = expand_normal (arg0);
3653      op1 = expand_normal (arg1);
3654      op2 = expand_normal (arg2);
3655      tmode = insn_data[icode].operand[0].mode;
3656      mode0 = insn_data[icode].operand[1].mode;
3657      mode1 = insn_data[icode].operand[2].mode;
3658      mode2 = insn_data[icode].operand[3].mode;
3659
3660      if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3661	op0 = copy_to_mode_reg (mode0, op0);
3662      if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
3663	op1 = copy_to_mode_reg (mode1, op1);
3664      if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
3665	{
3666	  error ("selector must be an immediate");
3667	  return const0_rtx;
3668	}
3669      if (icode == CODE_FOR_iwmmxt_wmerge)
3670	{
3671	  selector = INTVAL (op2);
3672	  if (selector > 7 || selector < 0)
3673	    error ("the range of selector should be in 0 to 7");
3674	}
3675      if ((icode == CODE_FOR_iwmmxt_tinsrb)
3676	  || (icode == CODE_FOR_iwmmxt_tinsrh)
3677	  || (icode == CODE_FOR_iwmmxt_tinsrw))
3678        {
3679	  mask = 0x01;
3680	  selector= INTVAL (op2);
3681	  if (icode == CODE_FOR_iwmmxt_tinsrb && (selector < 0 || selector > 7))
3682	    error ("the range of selector should be in 0 to 7");
3683	  else if (icode == CODE_FOR_iwmmxt_tinsrh && (selector < 0 ||selector > 3))
3684	    error ("the range of selector should be in 0 to 3");
3685	  else if (icode == CODE_FOR_iwmmxt_tinsrw && (selector < 0 ||selector > 1))
3686	    error ("the range of selector should be in 0 to 1");
3687	  mask <<= selector;
3688	  op2 = GEN_INT (mask);
3689	}
3690      if (target == 0
3691	  || GET_MODE (target) != tmode
3692	  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3693	target = gen_reg_rtx (tmode);
3694      pat = GEN_FCN (icode) (target, op0, op1, op2);
3695      if (! pat)
3696	return 0;
3697      emit_insn (pat);
3698      return target;
3699
3700    case ARM_BUILTIN_SETWCGR0:
3701    case ARM_BUILTIN_SETWCGR1:
3702    case ARM_BUILTIN_SETWCGR2:
3703    case ARM_BUILTIN_SETWCGR3:
3704      icode = (fcode == ARM_BUILTIN_SETWCGR0 ? CODE_FOR_iwmmxt_setwcgr0
3705	       : fcode == ARM_BUILTIN_SETWCGR1 ? CODE_FOR_iwmmxt_setwcgr1
3706	       : fcode == ARM_BUILTIN_SETWCGR2 ? CODE_FOR_iwmmxt_setwcgr2
3707	       : CODE_FOR_iwmmxt_setwcgr3);
3708      arg0 = CALL_EXPR_ARG (exp, 0);
3709      op0 = expand_normal (arg0);
3710      mode0 = insn_data[icode].operand[0].mode;
3711      if (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
3712        op0 = copy_to_mode_reg (mode0, op0);
3713      pat = GEN_FCN (icode) (op0);
3714      if (!pat)
3715	return 0;
3716      emit_insn (pat);
3717      return 0;
3718
3719    case ARM_BUILTIN_GETWCGR0:
3720    case ARM_BUILTIN_GETWCGR1:
3721    case ARM_BUILTIN_GETWCGR2:
3722    case ARM_BUILTIN_GETWCGR3:
3723      icode = (fcode == ARM_BUILTIN_GETWCGR0 ? CODE_FOR_iwmmxt_getwcgr0
3724	       : fcode == ARM_BUILTIN_GETWCGR1 ? CODE_FOR_iwmmxt_getwcgr1
3725	       : fcode == ARM_BUILTIN_GETWCGR2 ? CODE_FOR_iwmmxt_getwcgr2
3726	       : CODE_FOR_iwmmxt_getwcgr3);
3727      tmode = insn_data[icode].operand[0].mode;
3728      if (target == 0
3729	  || GET_MODE (target) != tmode
3730	  || !(*insn_data[icode].operand[0].predicate) (target, tmode))
3731        target = gen_reg_rtx (tmode);
3732      pat = GEN_FCN (icode) (target);
3733      if (!pat)
3734        return 0;
3735      emit_insn (pat);
3736      return target;
3737
3738    case ARM_BUILTIN_WSHUFH:
3739      icode = CODE_FOR_iwmmxt_wshufh;
3740      arg0 = CALL_EXPR_ARG (exp, 0);
3741      arg1 = CALL_EXPR_ARG (exp, 1);
3742      op0 = expand_normal (arg0);
3743      op1 = expand_normal (arg1);
3744      tmode = insn_data[icode].operand[0].mode;
3745      mode1 = insn_data[icode].operand[1].mode;
3746      mode2 = insn_data[icode].operand[2].mode;
3747
3748      if (! (*insn_data[icode].operand[1].predicate) (op0, mode1))
3749	op0 = copy_to_mode_reg (mode1, op0);
3750      if (! (*insn_data[icode].operand[2].predicate) (op1, mode2))
3751	{
3752	  error ("mask must be an immediate");
3753	  return const0_rtx;
3754	}
3755      selector = INTVAL (op1);
3756      if (selector < 0 || selector > 255)
3757	error ("the range of mask should be in 0 to 255");
3758      if (target == 0
3759	  || GET_MODE (target) != tmode
3760	  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3761	target = gen_reg_rtx (tmode);
3762      pat = GEN_FCN (icode) (target, op0, op1);
3763      if (! pat)
3764	return 0;
3765      emit_insn (pat);
3766      return target;
3767
3768    case ARM_BUILTIN_WMADDS:
3769      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmadds, exp, target);
3770    case ARM_BUILTIN_WMADDSX:
3771      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsx, exp, target);
3772    case ARM_BUILTIN_WMADDSN:
3773      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsn, exp, target);
3774    case ARM_BUILTIN_WMADDU:
3775      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddu, exp, target);
3776    case ARM_BUILTIN_WMADDUX:
3777      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddux, exp, target);
3778    case ARM_BUILTIN_WMADDUN:
3779      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddun, exp, target);
3780    case ARM_BUILTIN_WSADBZ:
3781      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz, exp, target);
3782    case ARM_BUILTIN_WSADHZ:
3783      return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz, exp, target);
3784
3785      /* Several three-argument builtins.  */
3786    case ARM_BUILTIN_WMACS:
3787    case ARM_BUILTIN_WMACU:
3788    case ARM_BUILTIN_TMIA:
3789    case ARM_BUILTIN_TMIAPH:
3790    case ARM_BUILTIN_TMIATT:
3791    case ARM_BUILTIN_TMIATB:
3792    case ARM_BUILTIN_TMIABT:
3793    case ARM_BUILTIN_TMIABB:
3794    case ARM_BUILTIN_WQMIABB:
3795    case ARM_BUILTIN_WQMIABT:
3796    case ARM_BUILTIN_WQMIATB:
3797    case ARM_BUILTIN_WQMIATT:
3798    case ARM_BUILTIN_WQMIABBN:
3799    case ARM_BUILTIN_WQMIABTN:
3800    case ARM_BUILTIN_WQMIATBN:
3801    case ARM_BUILTIN_WQMIATTN:
3802    case ARM_BUILTIN_WMIABB:
3803    case ARM_BUILTIN_WMIABT:
3804    case ARM_BUILTIN_WMIATB:
3805    case ARM_BUILTIN_WMIATT:
3806    case ARM_BUILTIN_WMIABBN:
3807    case ARM_BUILTIN_WMIABTN:
3808    case ARM_BUILTIN_WMIATBN:
3809    case ARM_BUILTIN_WMIATTN:
3810    case ARM_BUILTIN_WMIAWBB:
3811    case ARM_BUILTIN_WMIAWBT:
3812    case ARM_BUILTIN_WMIAWTB:
3813    case ARM_BUILTIN_WMIAWTT:
3814    case ARM_BUILTIN_WMIAWBBN:
3815    case ARM_BUILTIN_WMIAWBTN:
3816    case ARM_BUILTIN_WMIAWTBN:
3817    case ARM_BUILTIN_WMIAWTTN:
3818    case ARM_BUILTIN_WSADB:
3819    case ARM_BUILTIN_WSADH:
3820      icode = (fcode == ARM_BUILTIN_WMACS ? CODE_FOR_iwmmxt_wmacs
3821	       : fcode == ARM_BUILTIN_WMACU ? CODE_FOR_iwmmxt_wmacu
3822	       : fcode == ARM_BUILTIN_TMIA ? CODE_FOR_iwmmxt_tmia
3823	       : fcode == ARM_BUILTIN_TMIAPH ? CODE_FOR_iwmmxt_tmiaph
3824	       : fcode == ARM_BUILTIN_TMIABB ? CODE_FOR_iwmmxt_tmiabb
3825	       : fcode == ARM_BUILTIN_TMIABT ? CODE_FOR_iwmmxt_tmiabt
3826	       : fcode == ARM_BUILTIN_TMIATB ? CODE_FOR_iwmmxt_tmiatb
3827	       : fcode == ARM_BUILTIN_TMIATT ? CODE_FOR_iwmmxt_tmiatt
3828	       : fcode == ARM_BUILTIN_WQMIABB ? CODE_FOR_iwmmxt_wqmiabb
3829	       : fcode == ARM_BUILTIN_WQMIABT ? CODE_FOR_iwmmxt_wqmiabt
3830	       : fcode == ARM_BUILTIN_WQMIATB ? CODE_FOR_iwmmxt_wqmiatb
3831	       : fcode == ARM_BUILTIN_WQMIATT ? CODE_FOR_iwmmxt_wqmiatt
3832	       : fcode == ARM_BUILTIN_WQMIABBN ? CODE_FOR_iwmmxt_wqmiabbn
3833	       : fcode == ARM_BUILTIN_WQMIABTN ? CODE_FOR_iwmmxt_wqmiabtn
3834	       : fcode == ARM_BUILTIN_WQMIATBN ? CODE_FOR_iwmmxt_wqmiatbn
3835	       : fcode == ARM_BUILTIN_WQMIATTN ? CODE_FOR_iwmmxt_wqmiattn
3836	       : fcode == ARM_BUILTIN_WMIABB ? CODE_FOR_iwmmxt_wmiabb
3837	       : fcode == ARM_BUILTIN_WMIABT ? CODE_FOR_iwmmxt_wmiabt
3838	       : fcode == ARM_BUILTIN_WMIATB ? CODE_FOR_iwmmxt_wmiatb
3839	       : fcode == ARM_BUILTIN_WMIATT ? CODE_FOR_iwmmxt_wmiatt
3840	       : fcode == ARM_BUILTIN_WMIABBN ? CODE_FOR_iwmmxt_wmiabbn
3841	       : fcode == ARM_BUILTIN_WMIABTN ? CODE_FOR_iwmmxt_wmiabtn
3842	       : fcode == ARM_BUILTIN_WMIATBN ? CODE_FOR_iwmmxt_wmiatbn
3843	       : fcode == ARM_BUILTIN_WMIATTN ? CODE_FOR_iwmmxt_wmiattn
3844	       : fcode == ARM_BUILTIN_WMIAWBB ? CODE_FOR_iwmmxt_wmiawbb
3845	       : fcode == ARM_BUILTIN_WMIAWBT ? CODE_FOR_iwmmxt_wmiawbt
3846	       : fcode == ARM_BUILTIN_WMIAWTB ? CODE_FOR_iwmmxt_wmiawtb
3847	       : fcode == ARM_BUILTIN_WMIAWTT ? CODE_FOR_iwmmxt_wmiawtt
3848	       : fcode == ARM_BUILTIN_WMIAWBBN ? CODE_FOR_iwmmxt_wmiawbbn
3849	       : fcode == ARM_BUILTIN_WMIAWBTN ? CODE_FOR_iwmmxt_wmiawbtn
3850	       : fcode == ARM_BUILTIN_WMIAWTBN ? CODE_FOR_iwmmxt_wmiawtbn
3851	       : fcode == ARM_BUILTIN_WMIAWTTN ? CODE_FOR_iwmmxt_wmiawttn
3852	       : fcode == ARM_BUILTIN_WSADB ? CODE_FOR_iwmmxt_wsadb
3853	       : CODE_FOR_iwmmxt_wsadh);
3854      arg0 = CALL_EXPR_ARG (exp, 0);
3855      arg1 = CALL_EXPR_ARG (exp, 1);
3856      arg2 = CALL_EXPR_ARG (exp, 2);
3857      op0 = expand_normal (arg0);
3858      op1 = expand_normal (arg1);
3859      op2 = expand_normal (arg2);
3860      tmode = insn_data[icode].operand[0].mode;
3861      mode0 = insn_data[icode].operand[1].mode;
3862      mode1 = insn_data[icode].operand[2].mode;
3863      mode2 = insn_data[icode].operand[3].mode;
3864
3865      if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3866	op0 = copy_to_mode_reg (mode0, op0);
3867      if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
3868	op1 = copy_to_mode_reg (mode1, op1);
3869      if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
3870	op2 = copy_to_mode_reg (mode2, op2);
3871      if (target == 0
3872	  || GET_MODE (target) != tmode
3873	  || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3874	target = gen_reg_rtx (tmode);
3875      pat = GEN_FCN (icode) (target, op0, op1, op2);
3876      if (! pat)
3877	return 0;
3878      emit_insn (pat);
3879      return target;
3880
3881    case ARM_BUILTIN_WZERO:
3882      target = gen_reg_rtx (DImode);
3883      emit_insn (gen_iwmmxt_clrdi (target));
3884      return target;
3885
3886    case ARM_BUILTIN_WSRLHI:
3887    case ARM_BUILTIN_WSRLWI:
3888    case ARM_BUILTIN_WSRLDI:
3889    case ARM_BUILTIN_WSLLHI:
3890    case ARM_BUILTIN_WSLLWI:
3891    case ARM_BUILTIN_WSLLDI:
3892    case ARM_BUILTIN_WSRAHI:
3893    case ARM_BUILTIN_WSRAWI:
3894    case ARM_BUILTIN_WSRADI:
3895    case ARM_BUILTIN_WRORHI:
3896    case ARM_BUILTIN_WRORWI:
3897    case ARM_BUILTIN_WRORDI:
3898    case ARM_BUILTIN_WSRLH:
3899    case ARM_BUILTIN_WSRLW:
3900    case ARM_BUILTIN_WSRLD:
3901    case ARM_BUILTIN_WSLLH:
3902    case ARM_BUILTIN_WSLLW:
3903    case ARM_BUILTIN_WSLLD:
3904    case ARM_BUILTIN_WSRAH:
3905    case ARM_BUILTIN_WSRAW:
3906    case ARM_BUILTIN_WSRAD:
3907    case ARM_BUILTIN_WRORH:
3908    case ARM_BUILTIN_WRORW:
3909    case ARM_BUILTIN_WRORD:
3910      icode = (fcode == ARM_BUILTIN_WSRLHI ? CODE_FOR_lshrv4hi3_iwmmxt
3911	       : fcode == ARM_BUILTIN_WSRLWI ? CODE_FOR_lshrv2si3_iwmmxt
3912	       : fcode == ARM_BUILTIN_WSRLDI ? CODE_FOR_lshrdi3_iwmmxt
3913	       : fcode == ARM_BUILTIN_WSLLHI ? CODE_FOR_ashlv4hi3_iwmmxt
3914	       : fcode == ARM_BUILTIN_WSLLWI ? CODE_FOR_ashlv2si3_iwmmxt
3915	       : fcode == ARM_BUILTIN_WSLLDI ? CODE_FOR_ashldi3_iwmmxt
3916	       : fcode == ARM_BUILTIN_WSRAHI ? CODE_FOR_ashrv4hi3_iwmmxt
3917	       : fcode == ARM_BUILTIN_WSRAWI ? CODE_FOR_ashrv2si3_iwmmxt
3918	       : fcode == ARM_BUILTIN_WSRADI ? CODE_FOR_ashrdi3_iwmmxt
3919	       : fcode == ARM_BUILTIN_WRORHI ? CODE_FOR_rorv4hi3
3920	       : fcode == ARM_BUILTIN_WRORWI ? CODE_FOR_rorv2si3
3921	       : fcode == ARM_BUILTIN_WRORDI ? CODE_FOR_rordi3
3922	       : fcode == ARM_BUILTIN_WSRLH  ? CODE_FOR_lshrv4hi3_di
3923	       : fcode == ARM_BUILTIN_WSRLW  ? CODE_FOR_lshrv2si3_di
3924	       : fcode == ARM_BUILTIN_WSRLD  ? CODE_FOR_lshrdi3_di
3925	       : fcode == ARM_BUILTIN_WSLLH  ? CODE_FOR_ashlv4hi3_di
3926	       : fcode == ARM_BUILTIN_WSLLW  ? CODE_FOR_ashlv2si3_di
3927	       : fcode == ARM_BUILTIN_WSLLD  ? CODE_FOR_ashldi3_di
3928	       : fcode == ARM_BUILTIN_WSRAH  ? CODE_FOR_ashrv4hi3_di
3929	       : fcode == ARM_BUILTIN_WSRAW  ? CODE_FOR_ashrv2si3_di
3930	       : fcode == ARM_BUILTIN_WSRAD  ? CODE_FOR_ashrdi3_di
3931	       : fcode == ARM_BUILTIN_WRORH  ? CODE_FOR_rorv4hi3_di
3932	       : fcode == ARM_BUILTIN_WRORW  ? CODE_FOR_rorv2si3_di
3933	       : fcode == ARM_BUILTIN_WRORD  ? CODE_FOR_rordi3_di
3934	       : CODE_FOR_nothing);
3935      arg1 = CALL_EXPR_ARG (exp, 1);
3936      op1 = expand_normal (arg1);
3937      if (GET_MODE (op1) == VOIDmode)
3938	{
3939	  imm = INTVAL (op1);
3940	  if ((fcode == ARM_BUILTIN_WRORHI || fcode == ARM_BUILTIN_WRORWI
3941	       || fcode == ARM_BUILTIN_WRORH || fcode == ARM_BUILTIN_WRORW)
3942	      && (imm < 0 || imm > 32))
3943	    {
3944	      if (fcode == ARM_BUILTIN_WRORHI)
3945		error ("the range of count should be in 0 to 32.  please check the intrinsic _mm_rori_pi16 in code.");
3946	      else if (fcode == ARM_BUILTIN_WRORWI)
3947		error ("the range of count should be in 0 to 32.  please check the intrinsic _mm_rori_pi32 in code.");
3948	      else if (fcode == ARM_BUILTIN_WRORH)
3949		error ("the range of count should be in 0 to 32.  please check the intrinsic _mm_ror_pi16 in code.");
3950	      else
3951		error ("the range of count should be in 0 to 32.  please check the intrinsic _mm_ror_pi32 in code.");
3952	    }
3953	  else if ((fcode == ARM_BUILTIN_WRORDI || fcode == ARM_BUILTIN_WRORD)
3954		   && (imm < 0 || imm > 64))
3955	    {
3956	      if (fcode == ARM_BUILTIN_WRORDI)
3957		error ("the range of count should be in 0 to 64.  please check the intrinsic _mm_rori_si64 in code.");
3958	      else
3959		error ("the range of count should be in 0 to 64.  please check the intrinsic _mm_ror_si64 in code.");
3960	    }
3961	  else if (imm < 0)
3962	    {
3963	      if (fcode == ARM_BUILTIN_WSRLHI)
3964		error ("the count should be no less than 0.  please check the intrinsic _mm_srli_pi16 in code.");
3965	      else if (fcode == ARM_BUILTIN_WSRLWI)
3966		error ("the count should be no less than 0.  please check the intrinsic _mm_srli_pi32 in code.");
3967	      else if (fcode == ARM_BUILTIN_WSRLDI)
3968		error ("the count should be no less than 0.  please check the intrinsic _mm_srli_si64 in code.");
3969	      else if (fcode == ARM_BUILTIN_WSLLHI)
3970		error ("the count should be no less than 0.  please check the intrinsic _mm_slli_pi16 in code.");
3971	      else if (fcode == ARM_BUILTIN_WSLLWI)
3972		error ("the count should be no less than 0.  please check the intrinsic _mm_slli_pi32 in code.");
3973	      else if (fcode == ARM_BUILTIN_WSLLDI)
3974		error ("the count should be no less than 0.  please check the intrinsic _mm_slli_si64 in code.");
3975	      else if (fcode == ARM_BUILTIN_WSRAHI)
3976		error ("the count should be no less than 0.  please check the intrinsic _mm_srai_pi16 in code.");
3977	      else if (fcode == ARM_BUILTIN_WSRAWI)
3978		error ("the count should be no less than 0.  please check the intrinsic _mm_srai_pi32 in code.");
3979	      else if (fcode == ARM_BUILTIN_WSRADI)
3980		error ("the count should be no less than 0.  please check the intrinsic _mm_srai_si64 in code.");
3981	      else if (fcode == ARM_BUILTIN_WSRLH)
3982		error ("the count should be no less than 0.  please check the intrinsic _mm_srl_pi16 in code.");
3983	      else if (fcode == ARM_BUILTIN_WSRLW)
3984		error ("the count should be no less than 0.  please check the intrinsic _mm_srl_pi32 in code.");
3985	      else if (fcode == ARM_BUILTIN_WSRLD)
3986		error ("the count should be no less than 0.  please check the intrinsic _mm_srl_si64 in code.");
3987	      else if (fcode == ARM_BUILTIN_WSLLH)
3988		error ("the count should be no less than 0.  please check the intrinsic _mm_sll_pi16 in code.");
3989	      else if (fcode == ARM_BUILTIN_WSLLW)
3990		error ("the count should be no less than 0.  please check the intrinsic _mm_sll_pi32 in code.");
3991	      else if (fcode == ARM_BUILTIN_WSLLD)
3992		error ("the count should be no less than 0.  please check the intrinsic _mm_sll_si64 in code.");
3993	      else if (fcode == ARM_BUILTIN_WSRAH)
3994		error ("the count should be no less than 0.  please check the intrinsic _mm_sra_pi16 in code.");
3995	      else if (fcode == ARM_BUILTIN_WSRAW)
3996		error ("the count should be no less than 0.  please check the intrinsic _mm_sra_pi32 in code.");
3997	      else
3998		error ("the count should be no less than 0.  please check the intrinsic _mm_sra_si64 in code.");
3999	    }
4000	}
4001      return arm_expand_binop_builtin (icode, exp, target);
4002
4003    default:
4004      break;
4005    }
4006
4007  for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
4008    if (d->code == (enum arm_builtins) fcode)
4009      return arm_expand_binop_builtin (d->icode, exp, target);
4010
4011  for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
4012    if (d->code == (enum arm_builtins) fcode)
4013      return arm_expand_unop_builtin (d->icode, exp, target, 0);
4014
4015  for (i = 0, d = bdesc_3arg; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
4016    if (d->code == (enum arm_builtins) fcode)
4017      return arm_expand_ternop_builtin (d->icode, exp, target);
4018
4019  /* @@@ Should really do something sensible here.  */
4020  return NULL_RTX;
4021}
4022
4023tree
4024arm_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in)
4025{
4026  machine_mode in_mode, out_mode;
4027  int in_n, out_n;
4028  bool out_unsigned_p = TYPE_UNSIGNED (type_out);
4029
4030  /* Can't provide any vectorized builtins when we can't use NEON.  */
4031  if (!TARGET_NEON)
4032    return NULL_TREE;
4033
4034  if (TREE_CODE (type_out) != VECTOR_TYPE
4035      || TREE_CODE (type_in) != VECTOR_TYPE)
4036    return NULL_TREE;
4037
4038  out_mode = TYPE_MODE (TREE_TYPE (type_out));
4039  out_n = TYPE_VECTOR_SUBPARTS (type_out);
4040  in_mode = TYPE_MODE (TREE_TYPE (type_in));
4041  in_n = TYPE_VECTOR_SUBPARTS (type_in);
4042
4043/* ARM_CHECK_BUILTIN_MODE and ARM_FIND_VRINT_VARIANT are used to find the
4044   decl of the vectorized builtin for the appropriate vector mode.
4045   NULL_TREE is returned if no such builtin is available.  */
4046#undef ARM_CHECK_BUILTIN_MODE
4047#define ARM_CHECK_BUILTIN_MODE(C)    \
4048  (TARGET_VFP5   \
4049   && flag_unsafe_math_optimizations \
4050   && ARM_CHECK_BUILTIN_MODE_1 (C))
4051
4052#undef ARM_CHECK_BUILTIN_MODE_1
4053#define ARM_CHECK_BUILTIN_MODE_1(C) \
4054  (out_mode == SFmode && out_n == C \
4055   && in_mode == SFmode && in_n == C)
4056
4057#undef ARM_FIND_VRINT_VARIANT
4058#define ARM_FIND_VRINT_VARIANT(N) \
4059  (ARM_CHECK_BUILTIN_MODE (2) \
4060    ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sf, false) \
4061    : (ARM_CHECK_BUILTIN_MODE (4) \
4062      ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sf, false) \
4063      : NULL_TREE))
4064
4065  switch (fn)
4066    {
4067    CASE_CFN_FLOOR:
4068      return ARM_FIND_VRINT_VARIANT (vrintm);
4069    CASE_CFN_CEIL:
4070      return ARM_FIND_VRINT_VARIANT (vrintp);
4071    CASE_CFN_TRUNC:
4072      return ARM_FIND_VRINT_VARIANT (vrintz);
4073    CASE_CFN_ROUND:
4074      return ARM_FIND_VRINT_VARIANT (vrinta);
4075#undef ARM_CHECK_BUILTIN_MODE_1
4076#define ARM_CHECK_BUILTIN_MODE_1(C) \
4077  (out_mode == SImode && out_n == C \
4078   && in_mode == SFmode && in_n == C)
4079
4080#define ARM_FIND_VCVT_VARIANT(N) \
4081  (ARM_CHECK_BUILTIN_MODE (2) \
4082   ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sfv2si, false) \
4083   : (ARM_CHECK_BUILTIN_MODE (4) \
4084     ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sfv4si, false) \
4085     : NULL_TREE))
4086
4087#define ARM_FIND_VCVTU_VARIANT(N) \
4088  (ARM_CHECK_BUILTIN_MODE (2) \
4089   ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv2sfv2si, false) \
4090   : (ARM_CHECK_BUILTIN_MODE (4) \
4091     ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv4sfv4si, false) \
4092     : NULL_TREE))
4093    CASE_CFN_LROUND:
4094      return (out_unsigned_p
4095	      ? ARM_FIND_VCVTU_VARIANT (vcvta)
4096	      : ARM_FIND_VCVT_VARIANT (vcvta));
4097    CASE_CFN_LCEIL:
4098      return (out_unsigned_p
4099	      ? ARM_FIND_VCVTU_VARIANT (vcvtp)
4100	      : ARM_FIND_VCVT_VARIANT (vcvtp));
4101    CASE_CFN_LFLOOR:
4102      return (out_unsigned_p
4103	      ? ARM_FIND_VCVTU_VARIANT (vcvtm)
4104	      : ARM_FIND_VCVT_VARIANT (vcvtm));
4105#undef ARM_CHECK_BUILTIN_MODE
4106#define ARM_CHECK_BUILTIN_MODE(C, N) \
4107  (out_mode == N##mode && out_n == C \
4108   && in_mode == N##mode && in_n == C)
4109    case CFN_BUILT_IN_BSWAP16:
4110      if (ARM_CHECK_BUILTIN_MODE (4, HI))
4111	return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4hi, false);
4112      else if (ARM_CHECK_BUILTIN_MODE (8, HI))
4113	return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv8hi, false);
4114      else
4115	return NULL_TREE;
4116    case CFN_BUILT_IN_BSWAP32:
4117      if (ARM_CHECK_BUILTIN_MODE (2, SI))
4118	return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2si, false);
4119      else if (ARM_CHECK_BUILTIN_MODE (4, SI))
4120	return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4si, false);
4121      else
4122	return NULL_TREE;
4123    case CFN_BUILT_IN_BSWAP64:
4124      if (ARM_CHECK_BUILTIN_MODE (2, DI))
4125	return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2di, false);
4126      else
4127	return NULL_TREE;
4128    CASE_CFN_COPYSIGN:
4129      if (ARM_CHECK_BUILTIN_MODE (2, SF))
4130	return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv2sf, false);
4131      else if (ARM_CHECK_BUILTIN_MODE (4, SF))
4132	return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv4sf, false);
4133      else
4134	return NULL_TREE;
4135
4136    default:
4137      return NULL_TREE;
4138    }
4139  return NULL_TREE;
4140}
4141#undef ARM_FIND_VCVT_VARIANT
4142#undef ARM_FIND_VCVTU_VARIANT
4143#undef ARM_CHECK_BUILTIN_MODE
4144#undef ARM_FIND_VRINT_VARIANT
4145
4146void
4147arm_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
4148{
4149  const unsigned ARM_FE_INVALID = 1;
4150  const unsigned ARM_FE_DIVBYZERO = 2;
4151  const unsigned ARM_FE_OVERFLOW = 4;
4152  const unsigned ARM_FE_UNDERFLOW = 8;
4153  const unsigned ARM_FE_INEXACT = 16;
4154  const unsigned HOST_WIDE_INT ARM_FE_ALL_EXCEPT = (ARM_FE_INVALID
4155						    | ARM_FE_DIVBYZERO
4156						    | ARM_FE_OVERFLOW
4157						    | ARM_FE_UNDERFLOW
4158						    | ARM_FE_INEXACT);
4159  const unsigned HOST_WIDE_INT ARM_FE_EXCEPT_SHIFT = 8;
4160  tree fenv_var, get_fpscr, set_fpscr, mask, ld_fenv, masked_fenv;
4161  tree new_fenv_var, reload_fenv, restore_fnenv;
4162  tree update_call, atomic_feraiseexcept, hold_fnclex;
4163
4164  if (!TARGET_HARD_FLOAT)
4165    return;
4166
4167  /* Generate the equivalent of :
4168       unsigned int fenv_var;
4169       fenv_var = __builtin_arm_get_fpscr ();
4170
4171       unsigned int masked_fenv;
4172       masked_fenv = fenv_var & mask;
4173
4174       __builtin_arm_set_fpscr (masked_fenv);  */
4175
4176  fenv_var = create_tmp_var_raw (unsigned_type_node);
4177  get_fpscr = arm_builtin_decls[ARM_BUILTIN_GET_FPSCR];
4178  set_fpscr = arm_builtin_decls[ARM_BUILTIN_SET_FPSCR];
4179  mask = build_int_cst (unsigned_type_node,
4180			~((ARM_FE_ALL_EXCEPT << ARM_FE_EXCEPT_SHIFT)
4181			  | ARM_FE_ALL_EXCEPT));
4182  ld_fenv = build4 (TARGET_EXPR, unsigned_type_node,
4183		    fenv_var, build_call_expr (get_fpscr, 0),
4184		    NULL_TREE, NULL_TREE);
4185  masked_fenv = build2 (BIT_AND_EXPR, unsigned_type_node, fenv_var, mask);
4186  hold_fnclex = build_call_expr (set_fpscr, 1, masked_fenv);
4187  *hold = build2 (COMPOUND_EXPR, void_type_node,
4188		  build2 (COMPOUND_EXPR, void_type_node, masked_fenv, ld_fenv),
4189		  hold_fnclex);
4190
4191  /* Store the value of masked_fenv to clear the exceptions:
4192     __builtin_arm_set_fpscr (masked_fenv);  */
4193
4194  *clear = build_call_expr (set_fpscr, 1, masked_fenv);
4195
4196  /* Generate the equivalent of :
4197       unsigned int new_fenv_var;
4198       new_fenv_var = __builtin_arm_get_fpscr ();
4199
4200       __builtin_arm_set_fpscr (fenv_var);
4201
4202       __atomic_feraiseexcept (new_fenv_var);  */
4203
4204  new_fenv_var = create_tmp_var_raw (unsigned_type_node);
4205  reload_fenv = build4 (TARGET_EXPR, unsigned_type_node, new_fenv_var,
4206			build_call_expr (get_fpscr, 0), NULL_TREE, NULL_TREE);
4207  restore_fnenv = build_call_expr (set_fpscr, 1, fenv_var);
4208  atomic_feraiseexcept = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
4209  update_call = build_call_expr (atomic_feraiseexcept, 1,
4210				 fold_convert (integer_type_node, new_fenv_var));
4211  *update = build2 (COMPOUND_EXPR, void_type_node,
4212		    build2 (COMPOUND_EXPR, void_type_node,
4213			    reload_fenv, restore_fnenv), update_call);
4214}
4215
4216/* Implement TARGET_CHECK_BUILTIN_CALL.  Record a read of the Q bit through
4217   intrinsics in the machine function.  */
4218bool
4219arm_check_builtin_call (location_t , vec<location_t> , tree fndecl,
4220			tree, unsigned int, tree *)
4221{
4222  int fcode = DECL_MD_FUNCTION_CODE (fndecl);
4223  if (fcode == ARM_BUILTIN_saturation_occurred
4224      || fcode == ARM_BUILTIN_set_saturation)
4225    {
4226      if (cfun && cfun->decl)
4227	DECL_ATTRIBUTES (cfun->decl)
4228	  = tree_cons (get_identifier ("acle qbit"), NULL_TREE,
4229		       DECL_ATTRIBUTES (cfun->decl));
4230    }
4231  if (fcode == ARM_BUILTIN_sel)
4232    {
4233      if (cfun && cfun->decl)
4234	DECL_ATTRIBUTES (cfun->decl)
4235	  = tree_cons (get_identifier ("acle gebits"), NULL_TREE,
4236		       DECL_ATTRIBUTES (cfun->decl));
4237    }
4238  return true;
4239}
4240
4241enum resolver_ident
4242arm_describe_resolver (tree fndecl)
4243{
4244  if (DECL_MD_FUNCTION_CODE (fndecl) >= ARM_BUILTIN_vcx1qv16qi
4245    && DECL_MD_FUNCTION_CODE (fndecl) < ARM_BUILTIN_MVE_BASE)
4246    return arm_cde_resolver;
4247  return arm_no_resolver;
4248}
4249
4250unsigned
4251arm_cde_end_args (tree fndecl)
4252{
4253  return DECL_MD_FUNCTION_CODE (fndecl) >= ARM_BUILTIN_vcx1q_p_v16qi ? 2 : 1;
4254}
4255
4256#include "gt-arm-builtins.h"
4257