]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm-builtins.c
Update copyright years.
[thirdparty/gcc.git] / gcc / config / arm / arm-builtins.c
CommitLineData
33857df2 1/* Description of builtins used by the ARM backend.
99dee823 2 Copyright (C) 2014-2021 Free Software Foundation, Inc.
33857df2
JG
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
8fcc61f8
RS
20#define IN_TARGET_CODE 1
21
33857df2
JG
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
e11c4407
AM
25#include "target.h"
26#include "function.h"
33857df2
JG
27#include "rtl.h"
28#include "tree.h"
e11c4407 29#include "gimple-expr.h"
4d0cdd0c 30#include "memmodel.h"
e11c4407 31#include "tm_p.h"
84a1b7fe 32#include "profile-count.h"
e11c4407
AM
33#include "optabs.h"
34#include "emit-rtl.h"
35#include "recog.h"
36#include "diagnostic-core.h"
40e23961 37#include "fold-const.h"
33857df2 38#include "stor-layout.h"
36566b39 39#include "explow.h"
33857df2 40#include "expr.h"
33857df2 41#include "langhooks.h"
10766209 42#include "case-cfn-macros.h"
7d0ce941 43#include "sbitmap.h"
cf16f980 44#include "stringpool.h"
ef684c78 45#include "arm-builtins.h"
efe99cca
RS
46#include "stringpool.h"
47#include "attribs.h"
33857df2 48
d57daa0c 49#define SIMD_MAX_BUILTIN_ARGS 7
638ba4aa
JG
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 */
3811581f
AV
61 /* const T * foo. */
62 qualifier_const_pointer = 0x6,
638ba4aa
JG
63 /* Used when expanding arguments if an operand could
64 be an immediate. */
65 qualifier_immediate = 0x8, /* 1 << 3 */
d57daa0c 66 qualifier_unsigned_immediate = 0x9,
638ba4aa
JG
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. */
eaa80f64
AL
81 qualifier_poly = 0x100,
82 /* Lane indices - must be within range of previous argument = a vector. */
2f7d18dd
CB
83 qualifier_lane_index = 0x200,
84 /* Lane indices for single lane structure loads and stores. */
12b2b910
KT
85 qualifier_struct_load_store_lane_index = 0x400,
86 /* A void pointer. */
87 qualifier_void_pointer = 0x800,
88 /* A const void pointer. */
c2b7062d
TC
89 qualifier_const_void_pointer = 0x802,
90 /* Lane indices selected in pairs - must be within range of previous
91 argument = a vector. */
f348846e
SMW
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
638ba4aa
JG
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 };
638ba4aa
JG
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)
638ba4aa
JG
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)
638ba4aa 123
f8e109ba
TC
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
f348846e
SMW
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
638ba4aa
JG
138/* T (T, immediate). */
139static enum arm_type_qualifiers
eaa80f64 140arm_binop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
638ba4aa 141 = { qualifier_none, qualifier_none, qualifier_immediate };
eaa80f64
AL
142#define BINOP_IMM_QUALIFIERS (arm_binop_imm_qualifiers)
143
cf16f980
KT
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
eaa80f64
AL
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 };
638ba4aa 162#define GETLANE_QUALIFIERS (arm_getlane_qualifiers)
638ba4aa
JG
163
164/* T (T, T, T, immediate). */
165static enum arm_type_qualifiers
eaa80f64 166arm_mac_n_qualifiers[SIMD_MAX_BUILTIN_ARGS]
638ba4aa
JG
167 = { qualifier_none, qualifier_none, qualifier_none,
168 qualifier_none, qualifier_immediate };
eaa80f64
AL
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)
638ba4aa 177
c2b7062d
TC
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
f8e109ba
TC
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
f348846e
SMW
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
638ba4aa
JG
206/* T (T, T, immediate). */
207static enum arm_type_qualifiers
eaa80f64 208arm_ternop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
638ba4aa 209 = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate };
eaa80f64
AL
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 };
638ba4aa 216#define SETLANE_QUALIFIERS (arm_setlane_qualifiers)
638ba4aa
JG
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)
638ba4aa
JG
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)
638ba4aa
JG
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,
22f9db64 234 qualifier_none, qualifier_struct_load_store_lane_index };
638ba4aa 235#define LOAD1LANE_QUALIFIERS (arm_load1_lane_qualifiers)
638ba4aa 236
7a2c8e28
AV
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
d57daa0c
AV
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)
3811581f
AV
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,
12b2b910 261 qualifier_unsigned_immediate, qualifier_const_void_pointer };
3811581f
AV
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,
12b2b910 269 qualifier_unsigned_immediate, qualifier_void_pointer };
3811581f
AV
270#define STC_QUALIFIERS \
271 (arm_stc_qualifiers)
272
ecc9a25b
AV
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)
f3caa118
AV
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
07b9bfd0
DZ
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
ef684c78
MM
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
638ba4aa
JG
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)
638ba4aa 377
a50f6abf
SP
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
5db0eb95
SP
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
4be8cf77
SP
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
f166a8cd
SP
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
d71dba7b
SP
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
0dad5b33
SP
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
db5db9d2
SP
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
4ff68575
SP
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
405e918c
SP
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
535a8645
SP
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
429d607b
SP
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
92f80065
SP
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
ff825b81
SP
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
41e1a7ff
SP
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]
37753588 814 = { qualifier_unsigned, qualifier_unsigned, qualifier_const, qualifier_none};
41e1a7ff
SP
815#define STRSBWBS_QUALIFIERS (arm_strsbwbs_qualifiers)
816
817static enum arm_type_qualifiers
818arm_strsbwbu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
37753588 819 = { qualifier_unsigned, qualifier_unsigned, qualifier_const, qualifier_unsigned};
41e1a7ff
SP
820#define STRSBWBU_QUALIFIERS (arm_strsbwbu_qualifiers)
821
822static enum arm_type_qualifiers
823arm_strsbwbs_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
37753588 824 = { qualifier_unsigned, qualifier_unsigned, qualifier_const,
41e1a7ff
SP
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]
37753588 830 = { qualifier_unsigned, qualifier_unsigned, qualifier_const,
41e1a7ff
SP
831 qualifier_unsigned, qualifier_unsigned};
832#define STRSBWBU_P_QUALIFIERS (arm_strsbwbu_p_qualifiers)
833
85244449
SP
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
a50f6abf
SP
854/* End of Qualifier for MVE builtins. */
855
638ba4aa
JG
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,
22f9db64 860 qualifier_none, qualifier_struct_load_store_lane_index };
638ba4aa 861#define STORE1LANE_QUALIFIERS (arm_storestruct_lane_qualifiers)
638ba4aa 862
cf16f980
KT
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
0d4a1197
RS
875#define v8qi_UP E_V8QImode
876#define v4hi_UP E_V4HImode
877#define v4hf_UP E_V4HFmode
2e87b2f4 878#define v4bf_UP E_V4BFmode
0d4a1197
RS
879#define v2si_UP E_V2SImode
880#define v2sf_UP E_V2SFmode
ff229375 881#define v2bf_UP E_V2BFmode
0d4a1197
RS
882#define di_UP E_DImode
883#define v16qi_UP E_V16QImode
884#define v8hi_UP E_V8HImode
885#define v8hf_UP E_V8HFmode
2e87b2f4 886#define v8bf_UP E_V8BFmode
0d4a1197
RS
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
2e87b2f4 894#define bf_UP E_BFmode
0d4a1197 895#define si_UP E_SImode
a475f153 896#define hi_UP E_HImode
0d4a1197 897#define void_UP E_VOIDmode
2e87b2f4 898#define sf_UP E_SFmode
33857df2
JG
899#define UP(X) X##_UP
900
33857df2
JG
901typedef struct {
902 const char *name;
bd79363c 903 machine_mode mode;
33857df2
JG
904 const enum insn_code code;
905 unsigned int fcode;
638ba4aa 906 enum arm_type_qualifiers *qualifiers;
131e1faa 907} arm_builtin_datum;
33857df2
JG
908
909#define CF(N,X) CODE_FOR_neon_##N##X
910
911#define VAR1(T, N, A) \
bd79363c 912 {#N #A, UP (A), CF (N, A), 0, T##_QUALIFIERS},
33857df2 913#define VAR2(T, N, A, B) \
1add35db
JG
914 VAR1 (T, N, A) \
915 VAR1 (T, N, B)
33857df2 916#define VAR3(T, N, A, B, C) \
1add35db
JG
917 VAR2 (T, N, A, B) \
918 VAR1 (T, N, C)
33857df2 919#define VAR4(T, N, A, B, C, D) \
1add35db
JG
920 VAR3 (T, N, A, B, C) \
921 VAR1 (T, N, D)
33857df2 922#define VAR5(T, N, A, B, C, D, E) \
1add35db
JG
923 VAR4 (T, N, A, B, C, D) \
924 VAR1 (T, N, E)
33857df2 925#define VAR6(T, N, A, B, C, D, E, F) \
1add35db
JG
926 VAR5 (T, N, A, B, C, D, E) \
927 VAR1 (T, N, F)
33857df2 928#define VAR7(T, N, A, B, C, D, E, F, G) \
1add35db
JG
929 VAR6 (T, N, A, B, C, D, E, F) \
930 VAR1 (T, N, G)
33857df2 931#define VAR8(T, N, A, B, C, D, E, F, G, H) \
1add35db
JG
932 VAR7 (T, N, A, B, C, D, E, F, G) \
933 VAR1 (T, N, H)
33857df2 934#define VAR9(T, N, A, B, C, D, E, F, G, H, I) \
1add35db
JG
935 VAR8 (T, N, A, B, C, D, E, F, G, H) \
936 VAR1 (T, N, I)
33857df2 937#define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \
1add35db
JG
938 VAR9 (T, N, A, B, C, D, E, F, G, H, I) \
939 VAR1 (T, N, J)
4b644867
AL
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)
ff229375
DB
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)
89007667
AC
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)
33857df2 952
7a2c8e28
AV
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.
66e31c3d 957
7a2c8e28
AV
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. */
66e31c3d 963
131e1faa 964static arm_builtin_datum vfp_builtin_data[] =
66e31c3d
MW
965{
966#include "arm_vfp_builtins.def"
967};
33857df2 968
131e1faa 969static arm_builtin_datum neon_builtin_data[] =
33857df2
JG
970{
971#include "arm_neon_builtins.def"
972};
973
14782c81
SP
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
33857df2 981#undef CF
7a2c8e28
AV
982#undef VAR1
983#define VAR1(T, N, A) \
93733789 984 {#N, UP (A), CODE_FOR_arm_##N, 0, T##_QUALIFIERS},
7a2c8e28
AV
985
986static arm_builtin_datum acle_builtin_data[] =
987{
988#include "arm_acle_builtins.def"
989};
990
33857df2 991#undef VAR1
07b9bfd0
DZ
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};
33857df2 1007
07b9bfd0 1008#undef VAR1
1add35db
JG
1009#define VAR1(T, N, X) \
1010 ARM_BUILTIN_NEON_##N##X,
1011
33857df2
JG
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
33857df2
JG
1260 ARM_BUILTIN_GET_FPSCR,
1261 ARM_BUILTIN_SET_FPSCR,
c3562f81
SP
1262 ARM_BUILTIN_GET_FPSCR_NZCVQC,
1263 ARM_BUILTIN_SET_FPSCR_NZCVQC,
33857df2 1264
8261e476 1265 ARM_BUILTIN_CMSE_NONSECURE_CALLER,
63c8f7d6 1266 ARM_BUILTIN_SIMD_LANE_CHECK,
8261e476 1267
33857df2
JG
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
edef1fa8
CB
1279 ARM_BUILTIN_CRYPTO_BASE,
1280
33857df2
JG
1281#include "crypto.def"
1282
1283#undef CRYPTO1
1284#undef CRYPTO2
1285#undef CRYPTO3
1286
66e31c3d
MW
1287 ARM_BUILTIN_VFP_BASE,
1288
1289#include "arm_vfp_builtins.def"
1290
6d60b856 1291 ARM_BUILTIN_NEON_BASE,
6d60b856 1292
33857df2
JG
1293#include "arm_neon_builtins.def"
1294
7a2c8e28
AV
1295#undef VAR1
1296#define VAR1(T, N, X) \
1297 ARM_BUILTIN_##N,
1298
1299 ARM_BUILTIN_ACLE_BASE,
cf16f980 1300 ARM_BUILTIN_SAT_IMM_CHECK = ARM_BUILTIN_ACLE_BASE,
7a2c8e28
AV
1301
1302#include "arm_acle_builtins.def"
1303
07b9bfd0
DZ
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
14782c81
SP
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
1add35db 1319 ARM_BUILTIN_MAX
33857df2
JG
1320};
1321
66e31c3d
MW
1322#define ARM_BUILTIN_VFP_PATTERN_START \
1323 (ARM_BUILTIN_VFP_BASE + 1)
1324
6d60b856 1325#define ARM_BUILTIN_NEON_PATTERN_START \
bce2b8f9 1326 (ARM_BUILTIN_NEON_BASE + 1)
33857df2 1327
14782c81
SP
1328#define ARM_BUILTIN_MVE_PATTERN_START \
1329 (ARM_BUILTIN_MVE_BASE + 1)
1330
7a2c8e28
AV
1331#define ARM_BUILTIN_ACLE_PATTERN_START \
1332 (ARM_BUILTIN_ACLE_BASE + 1)
1333
07b9bfd0
DZ
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
33857df2
JG
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
6276b630
JG
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",
1c43ee69 1376 "__builtin_neon_bf",
6276b630
JG
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
5774b1fa
JG
1428/* The user-visible __fp16 type. */
1429tree arm_fp16_type_node = NULL_TREE;
2e87b2f4
SMW
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
6276b630
JG
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{
efe99cca
RS
1465 tree attrs = TYPE_ATTRIBUTES (type);
1466 if (tree attr = lookup_attribute ("Advanced SIMD type", attrs))
1467 {
1468 tree mangled_name = TREE_VALUE (TREE_VALUE (attr));
1469 return IDENTIFIER_POINTER (mangled_name);
1470 }
6276b630
JG
1471
1472 return NULL;
1473}
1474
1475const char *
1476arm_mangle_builtin_type (const_tree type)
1477{
1478 const char *mangle;
2e87b2f4 1479 /* Walk through all the Arm builtins types tables to filter out the
6276b630
JG
1480 incoming type. */
1481 if ((mangle = arm_mangle_builtin_vector_type (type))
1482 || (mangle = arm_mangle_builtin_scalar_type (type)))
1483 return mangle;
1484
1485 return NULL;
1486}
1487
1488static tree
b8506a8a 1489arm_simd_builtin_std_type (machine_mode mode,
6276b630
JG
1490 enum arm_type_qualifiers q)
1491{
1492#define QUAL_TYPE(M) \
1493 ((q == qualifier_none) ? int##M##_type_node : unsigned_int##M##_type_node);
1494 switch (mode)
1495 {
4e10a5a7 1496 case E_QImode:
6276b630 1497 return QUAL_TYPE (QI);
4e10a5a7 1498 case E_HImode:
6276b630 1499 return QUAL_TYPE (HI);
4e10a5a7 1500 case E_SImode:
6276b630 1501 return QUAL_TYPE (SI);
4e10a5a7 1502 case E_DImode:
6276b630 1503 return QUAL_TYPE (DI);
4e10a5a7 1504 case E_TImode:
6276b630 1505 return QUAL_TYPE (TI);
4e10a5a7 1506 case E_OImode:
6276b630 1507 return arm_simd_intOI_type_node;
4e10a5a7 1508 case E_EImode:
6276b630 1509 return arm_simd_intEI_type_node;
4e10a5a7 1510 case E_CImode:
6276b630 1511 return arm_simd_intCI_type_node;
4e10a5a7 1512 case E_XImode:
6276b630 1513 return arm_simd_intXI_type_node;
4e10a5a7 1514 case E_HFmode:
5774b1fa 1515 return arm_fp16_type_node;
4e10a5a7 1516 case E_SFmode:
6276b630 1517 return float_type_node;
4e10a5a7 1518 case E_DFmode:
6276b630 1519 return double_type_node;
2e87b2f4
SMW
1520 case E_BFmode:
1521 return arm_bf16_type_node;
6276b630
JG
1522 default:
1523 gcc_unreachable ();
1524 }
1525#undef QUAL_TYPE
1526}
1527
1528static tree
b8506a8a 1529arm_lookup_simd_builtin_type (machine_mode mode,
6276b630
JG
1530 enum arm_type_qualifiers q)
1531{
1532 int i;
1533 int nelts = sizeof (arm_simd_types) / sizeof (arm_simd_types[0]);
1534
1535 /* Non-poly scalar modes map to standard types not in the table. */
1536 if (q != qualifier_poly && !VECTOR_MODE_P (mode))
1537 return arm_simd_builtin_std_type (mode, q);
1538
1539 for (i = 0; i < nelts; i++)
1540 if (arm_simd_types[i].mode == mode
1541 && arm_simd_types[i].q == q)
1542 return arm_simd_types[i].itype;
1543
1544 /* Note that we won't have caught the underlying type for poly64x2_t
1545 in the above table. This gets default mangling. */
1546
1547 return NULL_TREE;
1548}
1549
1550static tree
b8506a8a 1551arm_simd_builtin_type (machine_mode mode, bool unsigned_p, bool poly_p)
6276b630
JG
1552{
1553 if (poly_p)
1554 return arm_lookup_simd_builtin_type (mode, qualifier_poly);
1555 else if (unsigned_p)
1556 return arm_lookup_simd_builtin_type (mode, qualifier_unsigned);
1557 else
1558 return arm_lookup_simd_builtin_type (mode, qualifier_none);
1559}
1560
33857df2 1561static void
6276b630
JG
1562arm_init_simd_builtin_types (void)
1563{
1564 int i;
1565 int nelts = sizeof (arm_simd_types) / sizeof (arm_simd_types[0]);
1566 tree tdecl;
1567
6276b630
JG
1568 /* Poly types are a world of their own. In order to maintain legacy
1569 ABI, they get initialized using the old interface, and don't get
1570 an entry in our mangling table, consequently, they get default
1571 mangling. As a further gotcha, poly8_t and poly16_t are signed
1572 types, poly64_t and poly128_t are unsigned types. */
63c8f7d6
SP
1573 if (!TARGET_HAVE_MVE)
1574 {
1575 arm_simd_polyQI_type_node
1576 = build_distinct_type_copy (intQI_type_node);
1577 (*lang_hooks.types.register_builtin_type) (arm_simd_polyQI_type_node,
1578 "__builtin_neon_poly8");
1579 arm_simd_polyHI_type_node
1580 = build_distinct_type_copy (intHI_type_node);
1581 (*lang_hooks.types.register_builtin_type) (arm_simd_polyHI_type_node,
1582 "__builtin_neon_poly16");
1583 arm_simd_polyDI_type_node
1584 = build_distinct_type_copy (unsigned_intDI_type_node);
1585 (*lang_hooks.types.register_builtin_type) (arm_simd_polyDI_type_node,
1586 "__builtin_neon_poly64");
1587 arm_simd_polyTI_type_node
1588 = build_distinct_type_copy (unsigned_intTI_type_node);
1589 (*lang_hooks.types.register_builtin_type) (arm_simd_polyTI_type_node,
1590 "__builtin_neon_poly128");
1591 /* Init poly vector element types with scalar poly types. */
1592 arm_simd_types[Poly8x8_t].eltype = arm_simd_polyQI_type_node;
1593 arm_simd_types[Poly8x16_t].eltype = arm_simd_polyQI_type_node;
1594 arm_simd_types[Poly16x4_t].eltype = arm_simd_polyHI_type_node;
1595 arm_simd_types[Poly16x8_t].eltype = arm_simd_polyHI_type_node;
1596 /* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default
1597 mangling. */
1598
1599 /* Prevent front-ends from transforming poly vectors into string
1600 literals. */
1601 TYPE_STRING_FLAG (arm_simd_polyQI_type_node) = false;
1602 TYPE_STRING_FLAG (arm_simd_polyHI_type_node) = false;
1603 }
6276b630
JG
1604 /* Init all the element types built by the front-end. */
1605 arm_simd_types[Int8x8_t].eltype = intQI_type_node;
1606 arm_simd_types[Int8x16_t].eltype = intQI_type_node;
1607 arm_simd_types[Int16x4_t].eltype = intHI_type_node;
1608 arm_simd_types[Int16x8_t].eltype = intHI_type_node;
1609 arm_simd_types[Int32x2_t].eltype = intSI_type_node;
1610 arm_simd_types[Int32x4_t].eltype = intSI_type_node;
1611 arm_simd_types[Int64x2_t].eltype = intDI_type_node;
1612 arm_simd_types[Uint8x8_t].eltype = unsigned_intQI_type_node;
1613 arm_simd_types[Uint8x16_t].eltype = unsigned_intQI_type_node;
1614 arm_simd_types[Uint16x4_t].eltype = unsigned_intHI_type_node;
1615 arm_simd_types[Uint16x8_t].eltype = unsigned_intHI_type_node;
1616 arm_simd_types[Uint32x2_t].eltype = unsigned_intSI_type_node;
1617 arm_simd_types[Uint32x4_t].eltype = unsigned_intSI_type_node;
1618 arm_simd_types[Uint64x2_t].eltype = unsigned_intDI_type_node;
1619
6276b630
JG
1620 /* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default
1621 mangling. */
1622
1623 /* Continue with standard types. */
50399bb1
AL
1624 /* The __builtin_simd{64,128}_float16 types are kept private unless
1625 we have a scalar __fp16 type. */
5774b1fa
JG
1626 arm_simd_types[Float16x4_t].eltype = arm_fp16_type_node;
1627 arm_simd_types[Float16x8_t].eltype = arm_fp16_type_node;
6276b630
JG
1628 arm_simd_types[Float32x2_t].eltype = float_type_node;
1629 arm_simd_types[Float32x4_t].eltype = float_type_node;
1630
2e87b2f4 1631 /* Init Bfloat vector types with underlying __bf16 scalar type. */
ff229375 1632 arm_simd_types[Bfloat16x2_t].eltype = arm_bf16_type_node;
2e87b2f4
SMW
1633 arm_simd_types[Bfloat16x4_t].eltype = arm_bf16_type_node;
1634 arm_simd_types[Bfloat16x8_t].eltype = arm_bf16_type_node;
1635
6276b630
JG
1636 for (i = 0; i < nelts; i++)
1637 {
1638 tree eltype = arm_simd_types[i].eltype;
b8506a8a 1639 machine_mode mode = arm_simd_types[i].mode;
6276b630 1640
63c8f7d6
SP
1641 if (eltype == NULL)
1642 continue;
6276b630 1643 if (arm_simd_types[i].itype == NULL)
efe99cca
RS
1644 {
1645 tree type = build_vector_type (eltype, GET_MODE_NUNITS (mode));
1646 type = build_distinct_type_copy (type);
1647 SET_TYPE_STRUCTURAL_EQUALITY (type);
1648
1649 tree mangled_name = get_identifier (arm_simd_types[i].mangle);
1650 tree value = tree_cons (NULL_TREE, mangled_name, NULL_TREE);
1651 TYPE_ATTRIBUTES (type)
1652 = tree_cons (get_identifier ("Advanced SIMD type"), value,
1653 TYPE_ATTRIBUTES (type));
1654 arm_simd_types[i].itype = type;
1655 }
6276b630
JG
1656
1657 tdecl = add_builtin_type (arm_simd_types[i].name,
1658 arm_simd_types[i].itype);
1659 TYPE_NAME (arm_simd_types[i].itype) = tdecl;
1660 SET_TYPE_STRUCTURAL_EQUALITY (arm_simd_types[i].itype);
1661 }
1662
1663#define AARCH_BUILD_SIGNED_TYPE(mode) \
1664 make_signed_type (GET_MODE_PRECISION (mode));
1665 arm_simd_intOI_type_node = AARCH_BUILD_SIGNED_TYPE (OImode);
1666 arm_simd_intEI_type_node = AARCH_BUILD_SIGNED_TYPE (EImode);
1667 arm_simd_intCI_type_node = AARCH_BUILD_SIGNED_TYPE (CImode);
1668 arm_simd_intXI_type_node = AARCH_BUILD_SIGNED_TYPE (XImode);
1669#undef AARCH_BUILD_SIGNED_TYPE
1670
1671 tdecl = add_builtin_type
1672 ("__builtin_neon_ei" , arm_simd_intEI_type_node);
1673 TYPE_NAME (arm_simd_intEI_type_node) = tdecl;
1674 tdecl = add_builtin_type
1675 ("__builtin_neon_oi" , arm_simd_intOI_type_node);
1676 TYPE_NAME (arm_simd_intOI_type_node) = tdecl;
1677 tdecl = add_builtin_type
1678 ("__builtin_neon_ci" , arm_simd_intCI_type_node);
1679 TYPE_NAME (arm_simd_intCI_type_node) = tdecl;
1680 tdecl = add_builtin_type
1681 ("__builtin_neon_xi" , arm_simd_intXI_type_node);
1682 TYPE_NAME (arm_simd_intXI_type_node) = tdecl;
1683}
1684
1685static void
1686arm_init_simd_builtin_scalar_types (void)
33857df2 1687{
6276b630
JG
1688 /* Define typedefs for all the standard scalar types. */
1689 (*lang_hooks.types.register_builtin_type) (intQI_type_node,
33857df2 1690 "__builtin_neon_qi");
6276b630 1691 (*lang_hooks.types.register_builtin_type) (intHI_type_node,
33857df2 1692 "__builtin_neon_hi");
6276b630 1693 (*lang_hooks.types.register_builtin_type) (intSI_type_node,
33857df2 1694 "__builtin_neon_si");
6276b630 1695 (*lang_hooks.types.register_builtin_type) (float_type_node,
33857df2 1696 "__builtin_neon_sf");
6276b630 1697 (*lang_hooks.types.register_builtin_type) (intDI_type_node,
33857df2 1698 "__builtin_neon_di");
6276b630
JG
1699 (*lang_hooks.types.register_builtin_type) (double_type_node,
1700 "__builtin_neon_df");
1701 (*lang_hooks.types.register_builtin_type) (intTI_type_node,
1702 "__builtin_neon_ti");
1c43ee69
DB
1703 (*lang_hooks.types.register_builtin_type) (arm_bf16_type_node,
1704 "__builtin_neon_bf");
33857df2 1705 /* Unsigned integer types for various mode sizes. */
6276b630 1706 (*lang_hooks.types.register_builtin_type) (unsigned_intQI_type_node,
33857df2 1707 "__builtin_neon_uqi");
6276b630 1708 (*lang_hooks.types.register_builtin_type) (unsigned_intHI_type_node,
33857df2 1709 "__builtin_neon_uhi");
6276b630 1710 (*lang_hooks.types.register_builtin_type) (unsigned_intSI_type_node,
33857df2 1711 "__builtin_neon_usi");
6276b630 1712 (*lang_hooks.types.register_builtin_type) (unsigned_intDI_type_node,
33857df2 1713 "__builtin_neon_udi");
6276b630
JG
1714 (*lang_hooks.types.register_builtin_type) (unsigned_intTI_type_node,
1715 "__builtin_neon_uti");
1716}
33857df2 1717
131e1faa
AV
1718/* Set up a builtin. It will use information stored in the argument struct D to
1719 derive the builtin's type signature and name. It will append the name in D
1720 to the PREFIX passed and use these to create a builtin declaration that is
1721 then stored in 'arm_builtin_decls' under index FCODE. This FCODE is also
1722 written back to D for future use. */
bce2b8f9
MW
1723
1724static void
131e1faa
AV
1725arm_init_builtin (unsigned int fcode, arm_builtin_datum *d,
1726 const char * prefix)
bce2b8f9
MW
1727{
1728 bool print_type_signature_p = false;
1729 char type_signature[SIMD_MAX_BUILTIN_ARGS] = { 0 };
1730 char namebuf[60];
1731 tree ftype = NULL;
1732 tree fndecl = NULL;
1733
1734 d->fcode = fcode;
1735
1736 /* We must track two variables here. op_num is
1737 the operand number as in the RTL pattern. This is
1738 required to access the mode (e.g. V4SF mode) of the
1739 argument, from which the base type can be derived.
1740 arg_num is an index in to the qualifiers data, which
1741 gives qualifiers to the type (e.g. const unsigned).
1742 The reason these two variables may differ by one is the
1743 void return type. While all return types take the 0th entry
1744 in the qualifiers array, there is no operand for them in the
1745 RTL pattern. */
1746 int op_num = insn_data[d->code].n_operands - 1;
1747 int arg_num = d->qualifiers[0] & qualifier_void
1748 ? op_num + 1
1749 : op_num;
1750 tree return_type = void_type_node, args = void_list_node;
1751 tree eltype;
1752
1753 /* Build a function type directly from the insn_data for this
1754 builtin. The build_function_type () function takes care of
1755 removing duplicates for us. */
1756 for (; op_num >= 0; arg_num--, op_num--)
1757 {
1758 machine_mode op_mode = insn_data[d->code].operand[op_num].mode;
1759 enum arm_type_qualifiers qualifiers = d->qualifiers[arg_num];
1760
1761 if (qualifiers & qualifier_unsigned)
1762 {
1763 type_signature[arg_num] = 'u';
1764 print_type_signature_p = true;
1765 }
1766 else if (qualifiers & qualifier_poly)
1767 {
1768 type_signature[arg_num] = 'p';
1769 print_type_signature_p = true;
1770 }
1771 else
1772 type_signature[arg_num] = 's';
1773
1774 /* Skip an internal operand for vget_{low, high}. */
1775 if (qualifiers & qualifier_internal)
1776 continue;
1777
1778 /* Some builtins have different user-facing types
1779 for certain arguments, encoded in d->mode. */
1780 if (qualifiers & qualifier_map_mode)
1781 op_mode = d->mode;
1782
1783 /* For pointers, we want a pointer to the basic type
1784 of the vector. */
1785 if (qualifiers & qualifier_pointer && VECTOR_MODE_P (op_mode))
1786 op_mode = GET_MODE_INNER (op_mode);
1787
12b2b910
KT
1788 /* For void pointers we already have nodes constructed by the midend. */
1789 if (qualifiers & qualifier_void_pointer)
1790 eltype = qualifiers & qualifier_const
1791 ? const_ptr_type_node : ptr_type_node;
1792 else
1793 {
1794 eltype
1795 = arm_simd_builtin_type (op_mode,
1796 (qualifiers & qualifier_unsigned) != 0,
1797 (qualifiers & qualifier_poly) != 0);
1798 gcc_assert (eltype != NULL);
1799
1800 /* Add qualifiers. */
1801 if (qualifiers & qualifier_const)
1802 eltype = build_qualified_type (eltype, TYPE_QUAL_CONST);
1803
1804 if (qualifiers & qualifier_pointer)
1805 eltype = build_pointer_type (eltype);
1806 }
bce2b8f9
MW
1807 /* If we have reached arg_num == 0, we are at a non-void
1808 return type. Otherwise, we are still processing
1809 arguments. */
1810 if (arg_num == 0)
1811 return_type = eltype;
1812 else
1813 args = tree_cons (NULL_TREE, eltype, args);
1814 }
1815
1816 ftype = build_function_type (return_type, args);
1817
1818 gcc_assert (ftype != NULL);
1819
131e1faa 1820 if (print_type_signature_p
7a2c8e28 1821 && IN_RANGE (fcode, ARM_BUILTIN_VFP_BASE, ARM_BUILTIN_ACLE_BASE - 1))
131e1faa
AV
1822 snprintf (namebuf, sizeof (namebuf), "%s_%s_%s",
1823 prefix, d->name, type_signature);
bce2b8f9 1824 else
131e1faa
AV
1825 snprintf (namebuf, sizeof (namebuf), "%s_%s",
1826 prefix, d->name);
bce2b8f9
MW
1827
1828 fndecl = add_builtin_function (namebuf, ftype, fcode, BUILT_IN_MD,
1829 NULL, NULL_TREE);
1830 arm_builtin_decls[fcode] = fndecl;
1831}
1832
2e87b2f4
SMW
1833/* Initialize the backend REAL_TYPE type supporting bfloat types. */
1834static void
1835arm_init_bf16_types (void)
1836{
1837 arm_bf16_type_node = make_node (REAL_TYPE);
1838 TYPE_PRECISION (arm_bf16_type_node) = 16;
1839 SET_TYPE_MODE (arm_bf16_type_node, BFmode);
1840 layout_type (arm_bf16_type_node);
1841
1842 lang_hooks.types.register_builtin_type (arm_bf16_type_node, "__bf16");
1843 arm_bf16_ptr_type_node = build_pointer_type (arm_bf16_type_node);
1844}
1845
7a2c8e28
AV
1846/* Set up ACLE builtins, even builtins for instructions that are not
1847 in the current target ISA to allow the user to compile particular modules
1848 with different target specific options that differ from the command line
1849 options. Such builtins will be rejected in arm_expand_builtin. */
1850
1851static void
1852arm_init_acle_builtins (void)
1853{
1854 unsigned int i, fcode = ARM_BUILTIN_ACLE_PATTERN_START;
1855
cf16f980
KT
1856 tree sat_check_fpr = build_function_type_list (void_type_node,
1857 intSI_type_node,
1858 intSI_type_node,
1859 intSI_type_node,
1860 NULL);
1861 arm_builtin_decls[ARM_BUILTIN_SAT_IMM_CHECK]
1862 = add_builtin_function ("__builtin_sat_imm_check", sat_check_fpr,
1863 ARM_BUILTIN_SAT_IMM_CHECK, BUILT_IN_MD,
1864 NULL, NULL_TREE);
1865
7a2c8e28
AV
1866 for (i = 0; i < ARRAY_SIZE (acle_builtin_data); i++, fcode++)
1867 {
1868 arm_builtin_datum *d = &acle_builtin_data[i];
1869 arm_init_builtin (fcode, d, "__builtin_arm");
1870 }
78bf9163 1871}
07b9bfd0 1872
78bf9163
MM
1873static void
1874arm_init_cde_builtins (void)
1875{
1876 unsigned int i, fcode = ARM_BUILTIN_CDE_PATTERN_START;
07b9bfd0
DZ
1877 for (i = 0; i < ARRAY_SIZE (cde_builtin_data); i++, fcode++)
1878 {
78bf9163
MM
1879 /* Only define CDE floating point builtins if the target has floating
1880 point registers. NOTE: without HARD_FLOAT we don't have MVE, so we
1881 can break out of this loop directly here. */
1882 if (!TARGET_MAYBE_HARD_FLOAT && fcode >= ARM_BUILTIN_vcx1si)
1883 break;
1884 /* Only define CDE/MVE builtins if MVE is available. */
1885 if (!TARGET_HAVE_MVE && fcode >= ARM_BUILTIN_vcx1qv16qi)
1886 break;
07b9bfd0
DZ
1887 arm_builtin_cde_datum *cde = &cde_builtin_data[i];
1888 arm_builtin_datum *d = &cde->base;
1889 arm_init_builtin (fcode, d, "__builtin_arm");
1890 set_call_expr_flags (arm_builtin_decls[fcode], cde->ecf_flag);
1891 }
7a2c8e28
AV
1892}
1893
14782c81
SP
1894/* Set up all the MVE builtins mentioned in arm_mve_builtins.def file. */
1895static void
1896arm_init_mve_builtins (void)
1897{
1898 volatile unsigned int i, fcode = ARM_BUILTIN_MVE_PATTERN_START;
1899
1900 arm_init_simd_builtin_scalar_types ();
1901 arm_init_simd_builtin_types ();
1902
c3562f81
SP
1903 /* Add support for __builtin_{get,set}_fpscr_nzcvqc, used by MVE intrinsics
1904 that read and/or write the carry bit. */
1905 tree get_fpscr_nzcvqc = build_function_type_list (intSI_type_node,
1906 NULL);
1907 tree set_fpscr_nzcvqc = build_function_type_list (void_type_node,
1908 intSI_type_node,
1909 NULL);
1910 arm_builtin_decls[ARM_BUILTIN_GET_FPSCR_NZCVQC]
1911 = add_builtin_function ("__builtin_arm_get_fpscr_nzcvqc", get_fpscr_nzcvqc,
1912 ARM_BUILTIN_GET_FPSCR_NZCVQC, BUILT_IN_MD, NULL,
1913 NULL_TREE);
1914 arm_builtin_decls[ARM_BUILTIN_SET_FPSCR_NZCVQC]
1915 = add_builtin_function ("__builtin_arm_set_fpscr_nzcvqc", set_fpscr_nzcvqc,
1916 ARM_BUILTIN_SET_FPSCR_NZCVQC, BUILT_IN_MD, NULL,
1917 NULL_TREE);
1918
14782c81
SP
1919 for (i = 0; i < ARRAY_SIZE (mve_builtin_data); i++, fcode++)
1920 {
1921 arm_builtin_datum *d = &mve_builtin_data[i];
1922 arm_init_builtin (fcode, d, "__builtin_mve");
1923 }
1924}
1925
edef1fa8
CB
1926/* Set up all the NEON builtins, even builtins for instructions that are not
1927 in the current target ISA to allow the user to compile particular modules
1928 with different target specific options that differ from the command line
1929 options. Such builtins will be rejected in arm_expand_builtin. */
1930
6276b630 1931static void
edef1fa8 1932arm_init_neon_builtins (void)
6276b630 1933{
6d60b856 1934 unsigned int i, fcode = ARM_BUILTIN_NEON_PATTERN_START;
33857df2 1935
6276b630 1936 arm_init_simd_builtin_types ();
33857df2 1937
6276b630
JG
1938 /* Strong-typing hasn't been implemented for all AdvSIMD builtin intrinsics.
1939 Therefore we need to preserve the old __builtin scalar types. It can be
1940 removed once all the intrinsics become strongly typed using the qualifier
1941 system. */
1942 arm_init_simd_builtin_scalar_types ();
33857df2 1943
6276b630 1944 for (i = 0; i < ARRAY_SIZE (neon_builtin_data); i++, fcode++)
33857df2 1945 {
131e1faa
AV
1946 arm_builtin_datum *d = &neon_builtin_data[i];
1947 arm_init_builtin (fcode, d, "__builtin_neon");
6276b630 1948 }
00c02a70 1949}
33857df2 1950
66e31c3d
MW
1951/* Set up all the scalar floating point builtins. */
1952
1953static void
1954arm_init_vfp_builtins (void)
1955{
1956 unsigned int i, fcode = ARM_BUILTIN_VFP_PATTERN_START;
1957
1958 for (i = 0; i < ARRAY_SIZE (vfp_builtin_data); i++, fcode++)
1959 {
131e1faa
AV
1960 arm_builtin_datum *d = &vfp_builtin_data[i];
1961 arm_init_builtin (fcode, d, "__builtin_neon");
66e31c3d
MW
1962 }
1963}
1964
00c02a70 1965static void
edef1fa8 1966arm_init_crypto_builtins (void)
00c02a70
CB
1967{
1968 tree V16UQI_type_node
1969 = arm_simd_builtin_type (V16QImode, true, false);
6276b630 1970
00c02a70
CB
1971 tree V4USI_type_node
1972 = arm_simd_builtin_type (V4SImode, true, false);
6276b630 1973
00c02a70
CB
1974 tree v16uqi_ftype_v16uqi
1975 = build_function_type_list (V16UQI_type_node, V16UQI_type_node,
1976 NULL_TREE);
6276b630 1977
00c02a70 1978 tree v16uqi_ftype_v16uqi_v16uqi
6276b630
JG
1979 = build_function_type_list (V16UQI_type_node, V16UQI_type_node,
1980 V16UQI_type_node, NULL_TREE);
1981
00c02a70
CB
1982 tree v4usi_ftype_v4usi
1983 = build_function_type_list (V4USI_type_node, V4USI_type_node,
1984 NULL_TREE);
1985
1986 tree v4usi_ftype_v4usi_v4usi
1987 = build_function_type_list (V4USI_type_node, V4USI_type_node,
1988 V4USI_type_node, NULL_TREE);
1989
1990 tree v4usi_ftype_v4usi_v4usi_v4usi
1991 = build_function_type_list (V4USI_type_node, V4USI_type_node,
1992 V4USI_type_node, V4USI_type_node,
1993 NULL_TREE);
1994
1995 tree uti_ftype_udi_udi
1996 = build_function_type_list (unsigned_intTI_type_node,
1997 unsigned_intDI_type_node,
1998 unsigned_intDI_type_node,
1999 NULL_TREE);
2000
2001 #undef CRYPTO1
2002 #undef CRYPTO2
2003 #undef CRYPTO3
2004 #undef C
2005 #undef N
2006 #undef CF
2007 #undef FT1
2008 #undef FT2
2009 #undef FT3
2010
2011 #define C(U) \
2012 ARM_BUILTIN_CRYPTO_##U
2013 #define N(L) \
2014 "__builtin_arm_crypto_"#L
2015 #define FT1(R, A) \
2016 R##_ftype_##A
2017 #define FT2(R, A1, A2) \
2018 R##_ftype_##A1##_##A2
2019 #define FT3(R, A1, A2, A3) \
2020 R##_ftype_##A1##_##A2##_##A3
2021 #define CRYPTO1(L, U, R, A) \
2022 arm_builtin_decls[C (U)] \
2023 = add_builtin_function (N (L), FT1 (R, A), \
2024 C (U), BUILT_IN_MD, NULL, NULL_TREE);
2025 #define CRYPTO2(L, U, R, A1, A2) \
2026 arm_builtin_decls[C (U)] \
2027 = add_builtin_function (N (L), FT2 (R, A1, A2), \
2028 C (U), BUILT_IN_MD, NULL, NULL_TREE);
2029
2030 #define CRYPTO3(L, U, R, A1, A2, A3) \
2031 arm_builtin_decls[C (U)] \
2032 = add_builtin_function (N (L), FT3 (R, A1, A2, A3), \
6276b630 2033 C (U), BUILT_IN_MD, NULL, NULL_TREE);
00c02a70
CB
2034 #include "crypto.def"
2035
2036 #undef CRYPTO1
2037 #undef CRYPTO2
2038 #undef CRYPTO3
2039 #undef C
2040 #undef N
2041 #undef FT1
2042 #undef FT2
2043 #undef FT3
2044}
6276b630 2045
33857df2
JG
2046#undef NUM_DREG_TYPES
2047#undef NUM_QREG_TYPES
2048
7d0ce941 2049#define def_mbuiltin(FLAG, NAME, TYPE, CODE) \
33857df2
JG
2050 do \
2051 { \
7d0ce941
RE
2052 if (FLAG == isa_nobit \
2053 || bitmap_bit_p (arm_active_target.isa, FLAG)) \
33857df2
JG
2054 { \
2055 tree bdecl; \
2056 bdecl = add_builtin_function ((NAME), (TYPE), (CODE), \
2057 BUILT_IN_MD, NULL, NULL_TREE); \
2058 arm_builtin_decls[CODE] = bdecl; \
2059 } \
2060 } \
2061 while (0)
2062
2063struct builtin_description
2064{
7d0ce941 2065 const enum isa_feature feature;
33857df2
JG
2066 const enum insn_code icode;
2067 const char * const name;
2068 const enum arm_builtins code;
2069 const enum rtx_code comparison;
2070 const unsigned int flag;
2071};
2072
2073static const struct builtin_description bdesc_2arg[] =
2074{
2075#define IWMMXT_BUILTIN(code, string, builtin) \
7d0ce941 2076 { isa_bit_iwmmxt, CODE_FOR_##code, \
23b9ccbe 2077 "__builtin_arm_" string, \
33857df2
JG
2078 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
2079
2080#define IWMMXT2_BUILTIN(code, string, builtin) \
7d0ce941 2081 { isa_bit_iwmmxt2, CODE_FOR_##code, \
23b9ccbe 2082 "__builtin_arm_" string, \
33857df2
JG
2083 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
2084
2085 IWMMXT_BUILTIN (addv8qi3, "waddb", WADDB)
2086 IWMMXT_BUILTIN (addv4hi3, "waddh", WADDH)
2087 IWMMXT_BUILTIN (addv2si3, "waddw", WADDW)
2088 IWMMXT_BUILTIN (subv8qi3, "wsubb", WSUBB)
2089 IWMMXT_BUILTIN (subv4hi3, "wsubh", WSUBH)
2090 IWMMXT_BUILTIN (subv2si3, "wsubw", WSUBW)
2091 IWMMXT_BUILTIN (ssaddv8qi3, "waddbss", WADDSSB)
2092 IWMMXT_BUILTIN (ssaddv4hi3, "waddhss", WADDSSH)
2093 IWMMXT_BUILTIN (ssaddv2si3, "waddwss", WADDSSW)
2094 IWMMXT_BUILTIN (sssubv8qi3, "wsubbss", WSUBSSB)
2095 IWMMXT_BUILTIN (sssubv4hi3, "wsubhss", WSUBSSH)
2096 IWMMXT_BUILTIN (sssubv2si3, "wsubwss", WSUBSSW)
2097 IWMMXT_BUILTIN (usaddv8qi3, "waddbus", WADDUSB)
2098 IWMMXT_BUILTIN (usaddv4hi3, "waddhus", WADDUSH)
2099 IWMMXT_BUILTIN (usaddv2si3, "waddwus", WADDUSW)
2100 IWMMXT_BUILTIN (ussubv8qi3, "wsubbus", WSUBUSB)
2101 IWMMXT_BUILTIN (ussubv4hi3, "wsubhus", WSUBUSH)
2102 IWMMXT_BUILTIN (ussubv2si3, "wsubwus", WSUBUSW)
2103 IWMMXT_BUILTIN (mulv4hi3, "wmulul", WMULUL)
2104 IWMMXT_BUILTIN (smulv4hi3_highpart, "wmulsm", WMULSM)
2105 IWMMXT_BUILTIN (umulv4hi3_highpart, "wmulum", WMULUM)
2106 IWMMXT_BUILTIN (eqv8qi3, "wcmpeqb", WCMPEQB)
2107 IWMMXT_BUILTIN (eqv4hi3, "wcmpeqh", WCMPEQH)
2108 IWMMXT_BUILTIN (eqv2si3, "wcmpeqw", WCMPEQW)
2109 IWMMXT_BUILTIN (gtuv8qi3, "wcmpgtub", WCMPGTUB)
2110 IWMMXT_BUILTIN (gtuv4hi3, "wcmpgtuh", WCMPGTUH)
2111 IWMMXT_BUILTIN (gtuv2si3, "wcmpgtuw", WCMPGTUW)
2112 IWMMXT_BUILTIN (gtv8qi3, "wcmpgtsb", WCMPGTSB)
2113 IWMMXT_BUILTIN (gtv4hi3, "wcmpgtsh", WCMPGTSH)
2114 IWMMXT_BUILTIN (gtv2si3, "wcmpgtsw", WCMPGTSW)
2115 IWMMXT_BUILTIN (umaxv8qi3, "wmaxub", WMAXUB)
2116 IWMMXT_BUILTIN (smaxv8qi3, "wmaxsb", WMAXSB)
2117 IWMMXT_BUILTIN (umaxv4hi3, "wmaxuh", WMAXUH)
2118 IWMMXT_BUILTIN (smaxv4hi3, "wmaxsh", WMAXSH)
2119 IWMMXT_BUILTIN (umaxv2si3, "wmaxuw", WMAXUW)
2120 IWMMXT_BUILTIN (smaxv2si3, "wmaxsw", WMAXSW)
2121 IWMMXT_BUILTIN (uminv8qi3, "wminub", WMINUB)
2122 IWMMXT_BUILTIN (sminv8qi3, "wminsb", WMINSB)
2123 IWMMXT_BUILTIN (uminv4hi3, "wminuh", WMINUH)
2124 IWMMXT_BUILTIN (sminv4hi3, "wminsh", WMINSH)
2125 IWMMXT_BUILTIN (uminv2si3, "wminuw", WMINUW)
2126 IWMMXT_BUILTIN (sminv2si3, "wminsw", WMINSW)
2127 IWMMXT_BUILTIN (iwmmxt_anddi3, "wand", WAND)
2128 IWMMXT_BUILTIN (iwmmxt_nanddi3, "wandn", WANDN)
2129 IWMMXT_BUILTIN (iwmmxt_iordi3, "wor", WOR)
2130 IWMMXT_BUILTIN (iwmmxt_xordi3, "wxor", WXOR)
2131 IWMMXT_BUILTIN (iwmmxt_uavgv8qi3, "wavg2b", WAVG2B)
2132 IWMMXT_BUILTIN (iwmmxt_uavgv4hi3, "wavg2h", WAVG2H)
2133 IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3, "wavg2br", WAVG2BR)
2134 IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3, "wavg2hr", WAVG2HR)
2135 IWMMXT_BUILTIN (iwmmxt_wunpckilb, "wunpckilb", WUNPCKILB)
2136 IWMMXT_BUILTIN (iwmmxt_wunpckilh, "wunpckilh", WUNPCKILH)
2137 IWMMXT_BUILTIN (iwmmxt_wunpckilw, "wunpckilw", WUNPCKILW)
2138 IWMMXT_BUILTIN (iwmmxt_wunpckihb, "wunpckihb", WUNPCKIHB)
2139 IWMMXT_BUILTIN (iwmmxt_wunpckihh, "wunpckihh", WUNPCKIHH)
2140 IWMMXT_BUILTIN (iwmmxt_wunpckihw, "wunpckihw", WUNPCKIHW)
2141 IWMMXT2_BUILTIN (iwmmxt_waddsubhx, "waddsubhx", WADDSUBHX)
2142 IWMMXT2_BUILTIN (iwmmxt_wsubaddhx, "wsubaddhx", WSUBADDHX)
2143 IWMMXT2_BUILTIN (iwmmxt_wabsdiffb, "wabsdiffb", WABSDIFFB)
2144 IWMMXT2_BUILTIN (iwmmxt_wabsdiffh, "wabsdiffh", WABSDIFFH)
2145 IWMMXT2_BUILTIN (iwmmxt_wabsdiffw, "wabsdiffw", WABSDIFFW)
2146 IWMMXT2_BUILTIN (iwmmxt_avg4, "wavg4", WAVG4)
2147 IWMMXT2_BUILTIN (iwmmxt_avg4r, "wavg4r", WAVG4R)
2148 IWMMXT2_BUILTIN (iwmmxt_wmulwsm, "wmulwsm", WMULWSM)
2149 IWMMXT2_BUILTIN (iwmmxt_wmulwum, "wmulwum", WMULWUM)
2150 IWMMXT2_BUILTIN (iwmmxt_wmulwsmr, "wmulwsmr", WMULWSMR)
2151 IWMMXT2_BUILTIN (iwmmxt_wmulwumr, "wmulwumr", WMULWUMR)
2152 IWMMXT2_BUILTIN (iwmmxt_wmulwl, "wmulwl", WMULWL)
2153 IWMMXT2_BUILTIN (iwmmxt_wmulsmr, "wmulsmr", WMULSMR)
2154 IWMMXT2_BUILTIN (iwmmxt_wmulumr, "wmulumr", WMULUMR)
2155 IWMMXT2_BUILTIN (iwmmxt_wqmulm, "wqmulm", WQMULM)
2156 IWMMXT2_BUILTIN (iwmmxt_wqmulmr, "wqmulmr", WQMULMR)
2157 IWMMXT2_BUILTIN (iwmmxt_wqmulwm, "wqmulwm", WQMULWM)
2158 IWMMXT2_BUILTIN (iwmmxt_wqmulwmr, "wqmulwmr", WQMULWMR)
2159 IWMMXT_BUILTIN (iwmmxt_walignr0, "walignr0", WALIGNR0)
2160 IWMMXT_BUILTIN (iwmmxt_walignr1, "walignr1", WALIGNR1)
2161 IWMMXT_BUILTIN (iwmmxt_walignr2, "walignr2", WALIGNR2)
2162 IWMMXT_BUILTIN (iwmmxt_walignr3, "walignr3", WALIGNR3)
2163
2164#define IWMMXT_BUILTIN2(code, builtin) \
7d0ce941 2165 { isa_bit_iwmmxt, CODE_FOR_##code, NULL, \
23b9ccbe 2166 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
33857df2
JG
2167
2168#define IWMMXT2_BUILTIN2(code, builtin) \
7d0ce941 2169 { isa_bit_iwmmxt2, CODE_FOR_##code, NULL, \
23b9ccbe 2170 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
33857df2
JG
2171
2172 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusm, WADDBHUSM)
2173 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusl, WADDBHUSL)
2174 IWMMXT_BUILTIN2 (iwmmxt_wpackhss, WPACKHSS)
2175 IWMMXT_BUILTIN2 (iwmmxt_wpackwss, WPACKWSS)
2176 IWMMXT_BUILTIN2 (iwmmxt_wpackdss, WPACKDSS)
2177 IWMMXT_BUILTIN2 (iwmmxt_wpackhus, WPACKHUS)
2178 IWMMXT_BUILTIN2 (iwmmxt_wpackwus, WPACKWUS)
2179 IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS)
2180 IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ)
2181 IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ)
2182
2183
2184#define FP_BUILTIN(L, U) \
7d0ce941 2185 {isa_nobit, CODE_FOR_##L, "__builtin_arm_"#L, ARM_BUILTIN_##U, \
33857df2
JG
2186 UNKNOWN, 0},
2187
2188 FP_BUILTIN (get_fpscr, GET_FPSCR)
2189 FP_BUILTIN (set_fpscr, SET_FPSCR)
2190#undef FP_BUILTIN
2191
23b9ccbe 2192#define CRYPTO_BUILTIN(L, U) \
7d0ce941 2193 {isa_nobit, CODE_FOR_crypto_##L, "__builtin_arm_crypto_"#L, \
23b9ccbe 2194 ARM_BUILTIN_CRYPTO_##U, UNKNOWN, 0},
33857df2
JG
2195#undef CRYPTO1
2196#undef CRYPTO2
2197#undef CRYPTO3
2198#define CRYPTO2(L, U, R, A1, A2) CRYPTO_BUILTIN (L, U)
2199#define CRYPTO1(L, U, R, A)
2200#define CRYPTO3(L, U, R, A1, A2, A3)
2201#include "crypto.def"
2202#undef CRYPTO1
2203#undef CRYPTO2
2204#undef CRYPTO3
2205
2206};
2207
2208static const struct builtin_description bdesc_1arg[] =
2209{
2210 IWMMXT_BUILTIN (iwmmxt_tmovmskb, "tmovmskb", TMOVMSKB)
2211 IWMMXT_BUILTIN (iwmmxt_tmovmskh, "tmovmskh", TMOVMSKH)
2212 IWMMXT_BUILTIN (iwmmxt_tmovmskw, "tmovmskw", TMOVMSKW)
2213 IWMMXT_BUILTIN (iwmmxt_waccb, "waccb", WACCB)
2214 IWMMXT_BUILTIN (iwmmxt_wacch, "wacch", WACCH)
2215 IWMMXT_BUILTIN (iwmmxt_waccw, "waccw", WACCW)
2216 IWMMXT_BUILTIN (iwmmxt_wunpckehub, "wunpckehub", WUNPCKEHUB)
2217 IWMMXT_BUILTIN (iwmmxt_wunpckehuh, "wunpckehuh", WUNPCKEHUH)
2218 IWMMXT_BUILTIN (iwmmxt_wunpckehuw, "wunpckehuw", WUNPCKEHUW)
2219 IWMMXT_BUILTIN (iwmmxt_wunpckehsb, "wunpckehsb", WUNPCKEHSB)
2220 IWMMXT_BUILTIN (iwmmxt_wunpckehsh, "wunpckehsh", WUNPCKEHSH)
2221 IWMMXT_BUILTIN (iwmmxt_wunpckehsw, "wunpckehsw", WUNPCKEHSW)
2222 IWMMXT_BUILTIN (iwmmxt_wunpckelub, "wunpckelub", WUNPCKELUB)
2223 IWMMXT_BUILTIN (iwmmxt_wunpckeluh, "wunpckeluh", WUNPCKELUH)
2224 IWMMXT_BUILTIN (iwmmxt_wunpckeluw, "wunpckeluw", WUNPCKELUW)
2225 IWMMXT_BUILTIN (iwmmxt_wunpckelsb, "wunpckelsb", WUNPCKELSB)
2226 IWMMXT_BUILTIN (iwmmxt_wunpckelsh, "wunpckelsh", WUNPCKELSH)
2227 IWMMXT_BUILTIN (iwmmxt_wunpckelsw, "wunpckelsw", WUNPCKELSW)
2228 IWMMXT2_BUILTIN (iwmmxt_wabsv8qi3, "wabsb", WABSB)
2229 IWMMXT2_BUILTIN (iwmmxt_wabsv4hi3, "wabsh", WABSH)
2230 IWMMXT2_BUILTIN (iwmmxt_wabsv2si3, "wabsw", WABSW)
2231 IWMMXT_BUILTIN (tbcstv8qi, "tbcstb", TBCSTB)
2232 IWMMXT_BUILTIN (tbcstv4hi, "tbcsth", TBCSTH)
2233 IWMMXT_BUILTIN (tbcstv2si, "tbcstw", TBCSTW)
2234
2235#define CRYPTO1(L, U, R, A) CRYPTO_BUILTIN (L, U)
2236#define CRYPTO2(L, U, R, A1, A2)
2237#define CRYPTO3(L, U, R, A1, A2, A3)
2238#include "crypto.def"
2239#undef CRYPTO1
2240#undef CRYPTO2
2241#undef CRYPTO3
2242};
2243
2244static const struct builtin_description bdesc_3arg[] =
2245{
2246#define CRYPTO3(L, U, R, A1, A2, A3) CRYPTO_BUILTIN (L, U)
2247#define CRYPTO1(L, U, R, A)
2248#define CRYPTO2(L, U, R, A1, A2)
2249#include "crypto.def"
2250#undef CRYPTO1
2251#undef CRYPTO2
2252#undef CRYPTO3
2253 };
2254#undef CRYPTO_BUILTIN
2255
2256/* Set up all the iWMMXt builtins. This is not called if
2257 TARGET_IWMMXT is zero. */
2258
2259static void
2260arm_init_iwmmxt_builtins (void)
2261{
2262 const struct builtin_description * d;
2263 size_t i;
2264
2265 tree V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
2266 tree V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
2267 tree V8QI_type_node = build_vector_type_for_mode (intQI_type_node, V8QImode);
2268
2269 tree v8qi_ftype_v8qi_v8qi_int
2270 = build_function_type_list (V8QI_type_node,
2271 V8QI_type_node, V8QI_type_node,
2272 integer_type_node, NULL_TREE);
2273 tree v4hi_ftype_v4hi_int
2274 = build_function_type_list (V4HI_type_node,
2275 V4HI_type_node, integer_type_node, NULL_TREE);
2276 tree v2si_ftype_v2si_int
2277 = build_function_type_list (V2SI_type_node,
2278 V2SI_type_node, integer_type_node, NULL_TREE);
2279 tree v2si_ftype_di_di
2280 = build_function_type_list (V2SI_type_node,
2281 long_long_integer_type_node,
2282 long_long_integer_type_node,
2283 NULL_TREE);
2284 tree di_ftype_di_int
2285 = build_function_type_list (long_long_integer_type_node,
2286 long_long_integer_type_node,
2287 integer_type_node, NULL_TREE);
2288 tree di_ftype_di_int_int
2289 = build_function_type_list (long_long_integer_type_node,
2290 long_long_integer_type_node,
2291 integer_type_node,
2292 integer_type_node, NULL_TREE);
2293 tree int_ftype_v8qi
2294 = build_function_type_list (integer_type_node,
2295 V8QI_type_node, NULL_TREE);
2296 tree int_ftype_v4hi
2297 = build_function_type_list (integer_type_node,
2298 V4HI_type_node, NULL_TREE);
2299 tree int_ftype_v2si
2300 = build_function_type_list (integer_type_node,
2301 V2SI_type_node, NULL_TREE);
2302 tree int_ftype_v8qi_int
2303 = build_function_type_list (integer_type_node,
2304 V8QI_type_node, integer_type_node, NULL_TREE);
2305 tree int_ftype_v4hi_int
2306 = build_function_type_list (integer_type_node,
2307 V4HI_type_node, integer_type_node, NULL_TREE);
2308 tree int_ftype_v2si_int
2309 = build_function_type_list (integer_type_node,
2310 V2SI_type_node, integer_type_node, NULL_TREE);
2311 tree v8qi_ftype_v8qi_int_int
2312 = build_function_type_list (V8QI_type_node,
2313 V8QI_type_node, integer_type_node,
2314 integer_type_node, NULL_TREE);
2315 tree v4hi_ftype_v4hi_int_int
2316 = build_function_type_list (V4HI_type_node,
2317 V4HI_type_node, integer_type_node,
2318 integer_type_node, NULL_TREE);
2319 tree v2si_ftype_v2si_int_int
2320 = build_function_type_list (V2SI_type_node,
2321 V2SI_type_node, integer_type_node,
2322 integer_type_node, NULL_TREE);
2323 /* Miscellaneous. */
2324 tree v8qi_ftype_v4hi_v4hi
2325 = build_function_type_list (V8QI_type_node,
2326 V4HI_type_node, V4HI_type_node, NULL_TREE);
2327 tree v4hi_ftype_v2si_v2si
2328 = build_function_type_list (V4HI_type_node,
2329 V2SI_type_node, V2SI_type_node, NULL_TREE);
2330 tree v8qi_ftype_v4hi_v8qi
2331 = build_function_type_list (V8QI_type_node,
2332 V4HI_type_node, V8QI_type_node, NULL_TREE);
2333 tree v2si_ftype_v4hi_v4hi
2334 = build_function_type_list (V2SI_type_node,
2335 V4HI_type_node, V4HI_type_node, NULL_TREE);
2336 tree v2si_ftype_v8qi_v8qi
2337 = build_function_type_list (V2SI_type_node,
2338 V8QI_type_node, V8QI_type_node, NULL_TREE);
2339 tree v4hi_ftype_v4hi_di
2340 = build_function_type_list (V4HI_type_node,
2341 V4HI_type_node, long_long_integer_type_node,
2342 NULL_TREE);
2343 tree v2si_ftype_v2si_di
2344 = build_function_type_list (V2SI_type_node,
2345 V2SI_type_node, long_long_integer_type_node,
2346 NULL_TREE);
2347 tree di_ftype_void
2348 = build_function_type_list (long_long_unsigned_type_node, NULL_TREE);
2349 tree int_ftype_void
2350 = build_function_type_list (integer_type_node, NULL_TREE);
2351 tree di_ftype_v8qi
2352 = build_function_type_list (long_long_integer_type_node,
2353 V8QI_type_node, NULL_TREE);
2354 tree di_ftype_v4hi
2355 = build_function_type_list (long_long_integer_type_node,
2356 V4HI_type_node, NULL_TREE);
2357 tree di_ftype_v2si
2358 = build_function_type_list (long_long_integer_type_node,
2359 V2SI_type_node, NULL_TREE);
2360 tree v2si_ftype_v4hi
2361 = build_function_type_list (V2SI_type_node,
2362 V4HI_type_node, NULL_TREE);
2363 tree v4hi_ftype_v8qi
2364 = build_function_type_list (V4HI_type_node,
2365 V8QI_type_node, NULL_TREE);
2366 tree v8qi_ftype_v8qi
2367 = build_function_type_list (V8QI_type_node,
2368 V8QI_type_node, NULL_TREE);
2369 tree v4hi_ftype_v4hi
2370 = build_function_type_list (V4HI_type_node,
2371 V4HI_type_node, NULL_TREE);
2372 tree v2si_ftype_v2si
2373 = build_function_type_list (V2SI_type_node,
2374 V2SI_type_node, NULL_TREE);
2375
2376 tree di_ftype_di_v4hi_v4hi
2377 = build_function_type_list (long_long_unsigned_type_node,
2378 long_long_unsigned_type_node,
2379 V4HI_type_node, V4HI_type_node,
2380 NULL_TREE);
2381
2382 tree di_ftype_v4hi_v4hi
2383 = build_function_type_list (long_long_unsigned_type_node,
2384 V4HI_type_node,V4HI_type_node,
2385 NULL_TREE);
2386
2387 tree v2si_ftype_v2si_v4hi_v4hi
2388 = build_function_type_list (V2SI_type_node,
2389 V2SI_type_node, V4HI_type_node,
2390 V4HI_type_node, NULL_TREE);
2391
2392 tree v2si_ftype_v2si_v8qi_v8qi
2393 = build_function_type_list (V2SI_type_node,
2394 V2SI_type_node, V8QI_type_node,
2395 V8QI_type_node, NULL_TREE);
2396
2397 tree di_ftype_di_v2si_v2si
2398 = build_function_type_list (long_long_unsigned_type_node,
2399 long_long_unsigned_type_node,
2400 V2SI_type_node, V2SI_type_node,
2401 NULL_TREE);
2402
2403 tree di_ftype_di_di_int
2404 = build_function_type_list (long_long_unsigned_type_node,
2405 long_long_unsigned_type_node,
2406 long_long_unsigned_type_node,
2407 integer_type_node, NULL_TREE);
2408
2409 tree void_ftype_int
2410 = build_function_type_list (void_type_node,
2411 integer_type_node, NULL_TREE);
2412
2413 tree v8qi_ftype_char
2414 = build_function_type_list (V8QI_type_node,
2415 signed_char_type_node, NULL_TREE);
2416
2417 tree v4hi_ftype_short
2418 = build_function_type_list (V4HI_type_node,
2419 short_integer_type_node, NULL_TREE);
2420
2421 tree v2si_ftype_int
2422 = build_function_type_list (V2SI_type_node,
2423 integer_type_node, NULL_TREE);
2424
2425 /* Normal vector binops. */
2426 tree v8qi_ftype_v8qi_v8qi
2427 = build_function_type_list (V8QI_type_node,
2428 V8QI_type_node, V8QI_type_node, NULL_TREE);
2429 tree v4hi_ftype_v4hi_v4hi
2430 = build_function_type_list (V4HI_type_node,
2431 V4HI_type_node,V4HI_type_node, NULL_TREE);
2432 tree v2si_ftype_v2si_v2si
2433 = build_function_type_list (V2SI_type_node,
2434 V2SI_type_node, V2SI_type_node, NULL_TREE);
2435 tree di_ftype_di_di
2436 = build_function_type_list (long_long_unsigned_type_node,
2437 long_long_unsigned_type_node,
2438 long_long_unsigned_type_node,
2439 NULL_TREE);
2440
2441 /* Add all builtins that are more or less simple operations on two
2442 operands. */
2443 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
2444 {
2445 /* Use one of the operands; the target can have a different mode for
2446 mask-generating compares. */
2447 machine_mode mode;
2448 tree type;
2449
7d0ce941
RE
2450 if (d->name == 0
2451 || !(d->feature == isa_bit_iwmmxt
2452 || d->feature == isa_bit_iwmmxt2))
33857df2
JG
2453 continue;
2454
2455 mode = insn_data[d->icode].operand[1].mode;
2456
2457 switch (mode)
2458 {
4e10a5a7 2459 case E_V8QImode:
33857df2
JG
2460 type = v8qi_ftype_v8qi_v8qi;
2461 break;
4e10a5a7 2462 case E_V4HImode:
33857df2
JG
2463 type = v4hi_ftype_v4hi_v4hi;
2464 break;
4e10a5a7 2465 case E_V2SImode:
33857df2
JG
2466 type = v2si_ftype_v2si_v2si;
2467 break;
4e10a5a7 2468 case E_DImode:
33857df2
JG
2469 type = di_ftype_di_di;
2470 break;
2471
2472 default:
2473 gcc_unreachable ();
2474 }
2475
7d0ce941 2476 def_mbuiltin (d->feature, d->name, type, d->code);
33857df2
JG
2477 }
2478
2479 /* Add the remaining MMX insns with somewhat more complicated types. */
2480#define iwmmx_mbuiltin(NAME, TYPE, CODE) \
7d0ce941 2481 def_mbuiltin (isa_bit_iwmmxt, "__builtin_arm_" NAME, \
23b9ccbe 2482 (TYPE), ARM_BUILTIN_ ## CODE)
33857df2
JG
2483
2484#define iwmmx2_mbuiltin(NAME, TYPE, CODE) \
7d0ce941 2485 def_mbuiltin (isa_bit_iwmmxt2, "__builtin_arm_" NAME, \
23b9ccbe 2486 (TYPE), ARM_BUILTIN_ ## CODE)
33857df2
JG
2487
2488 iwmmx_mbuiltin ("wzero", di_ftype_void, WZERO);
2489 iwmmx_mbuiltin ("setwcgr0", void_ftype_int, SETWCGR0);
2490 iwmmx_mbuiltin ("setwcgr1", void_ftype_int, SETWCGR1);
2491 iwmmx_mbuiltin ("setwcgr2", void_ftype_int, SETWCGR2);
2492 iwmmx_mbuiltin ("setwcgr3", void_ftype_int, SETWCGR3);
2493 iwmmx_mbuiltin ("getwcgr0", int_ftype_void, GETWCGR0);
2494 iwmmx_mbuiltin ("getwcgr1", int_ftype_void, GETWCGR1);
2495 iwmmx_mbuiltin ("getwcgr2", int_ftype_void, GETWCGR2);
2496 iwmmx_mbuiltin ("getwcgr3", int_ftype_void, GETWCGR3);
2497
2498 iwmmx_mbuiltin ("wsllh", v4hi_ftype_v4hi_di, WSLLH);
2499 iwmmx_mbuiltin ("wsllw", v2si_ftype_v2si_di, WSLLW);
2500 iwmmx_mbuiltin ("wslld", di_ftype_di_di, WSLLD);
2501 iwmmx_mbuiltin ("wsllhi", v4hi_ftype_v4hi_int, WSLLHI);
2502 iwmmx_mbuiltin ("wsllwi", v2si_ftype_v2si_int, WSLLWI);
2503 iwmmx_mbuiltin ("wslldi", di_ftype_di_int, WSLLDI);
2504
2505 iwmmx_mbuiltin ("wsrlh", v4hi_ftype_v4hi_di, WSRLH);
2506 iwmmx_mbuiltin ("wsrlw", v2si_ftype_v2si_di, WSRLW);
2507 iwmmx_mbuiltin ("wsrld", di_ftype_di_di, WSRLD);
2508 iwmmx_mbuiltin ("wsrlhi", v4hi_ftype_v4hi_int, WSRLHI);
2509 iwmmx_mbuiltin ("wsrlwi", v2si_ftype_v2si_int, WSRLWI);
2510 iwmmx_mbuiltin ("wsrldi", di_ftype_di_int, WSRLDI);
2511
2512 iwmmx_mbuiltin ("wsrah", v4hi_ftype_v4hi_di, WSRAH);
2513 iwmmx_mbuiltin ("wsraw", v2si_ftype_v2si_di, WSRAW);
2514 iwmmx_mbuiltin ("wsrad", di_ftype_di_di, WSRAD);
2515 iwmmx_mbuiltin ("wsrahi", v4hi_ftype_v4hi_int, WSRAHI);
2516 iwmmx_mbuiltin ("wsrawi", v2si_ftype_v2si_int, WSRAWI);
2517 iwmmx_mbuiltin ("wsradi", di_ftype_di_int, WSRADI);
2518
2519 iwmmx_mbuiltin ("wrorh", v4hi_ftype_v4hi_di, WRORH);
2520 iwmmx_mbuiltin ("wrorw", v2si_ftype_v2si_di, WRORW);
2521 iwmmx_mbuiltin ("wrord", di_ftype_di_di, WRORD);
2522 iwmmx_mbuiltin ("wrorhi", v4hi_ftype_v4hi_int, WRORHI);
2523 iwmmx_mbuiltin ("wrorwi", v2si_ftype_v2si_int, WRORWI);
2524 iwmmx_mbuiltin ("wrordi", di_ftype_di_int, WRORDI);
2525
2526 iwmmx_mbuiltin ("wshufh", v4hi_ftype_v4hi_int, WSHUFH);
2527
2528 iwmmx_mbuiltin ("wsadb", v2si_ftype_v2si_v8qi_v8qi, WSADB);
2529 iwmmx_mbuiltin ("wsadh", v2si_ftype_v2si_v4hi_v4hi, WSADH);
2530 iwmmx_mbuiltin ("wmadds", v2si_ftype_v4hi_v4hi, WMADDS);
2531 iwmmx2_mbuiltin ("wmaddsx", v2si_ftype_v4hi_v4hi, WMADDSX);
2532 iwmmx2_mbuiltin ("wmaddsn", v2si_ftype_v4hi_v4hi, WMADDSN);
2533 iwmmx_mbuiltin ("wmaddu", v2si_ftype_v4hi_v4hi, WMADDU);
2534 iwmmx2_mbuiltin ("wmaddux", v2si_ftype_v4hi_v4hi, WMADDUX);
2535 iwmmx2_mbuiltin ("wmaddun", v2si_ftype_v4hi_v4hi, WMADDUN);
2536 iwmmx_mbuiltin ("wsadbz", v2si_ftype_v8qi_v8qi, WSADBZ);
2537 iwmmx_mbuiltin ("wsadhz", v2si_ftype_v4hi_v4hi, WSADHZ);
2538
2539 iwmmx_mbuiltin ("textrmsb", int_ftype_v8qi_int, TEXTRMSB);
2540 iwmmx_mbuiltin ("textrmsh", int_ftype_v4hi_int, TEXTRMSH);
2541 iwmmx_mbuiltin ("textrmsw", int_ftype_v2si_int, TEXTRMSW);
2542 iwmmx_mbuiltin ("textrmub", int_ftype_v8qi_int, TEXTRMUB);
2543 iwmmx_mbuiltin ("textrmuh", int_ftype_v4hi_int, TEXTRMUH);
2544 iwmmx_mbuiltin ("textrmuw", int_ftype_v2si_int, TEXTRMUW);
2545 iwmmx_mbuiltin ("tinsrb", v8qi_ftype_v8qi_int_int, TINSRB);
2546 iwmmx_mbuiltin ("tinsrh", v4hi_ftype_v4hi_int_int, TINSRH);
2547 iwmmx_mbuiltin ("tinsrw", v2si_ftype_v2si_int_int, TINSRW);
2548
2549 iwmmx_mbuiltin ("waccb", di_ftype_v8qi, WACCB);
2550 iwmmx_mbuiltin ("wacch", di_ftype_v4hi, WACCH);
2551 iwmmx_mbuiltin ("waccw", di_ftype_v2si, WACCW);
2552
2553 iwmmx_mbuiltin ("tmovmskb", int_ftype_v8qi, TMOVMSKB);
2554 iwmmx_mbuiltin ("tmovmskh", int_ftype_v4hi, TMOVMSKH);
2555 iwmmx_mbuiltin ("tmovmskw", int_ftype_v2si, TMOVMSKW);
2556
2557 iwmmx2_mbuiltin ("waddbhusm", v8qi_ftype_v4hi_v8qi, WADDBHUSM);
2558 iwmmx2_mbuiltin ("waddbhusl", v8qi_ftype_v4hi_v8qi, WADDBHUSL);
2559
2560 iwmmx_mbuiltin ("wpackhss", v8qi_ftype_v4hi_v4hi, WPACKHSS);
2561 iwmmx_mbuiltin ("wpackhus", v8qi_ftype_v4hi_v4hi, WPACKHUS);
2562 iwmmx_mbuiltin ("wpackwus", v4hi_ftype_v2si_v2si, WPACKWUS);
2563 iwmmx_mbuiltin ("wpackwss", v4hi_ftype_v2si_v2si, WPACKWSS);
2564 iwmmx_mbuiltin ("wpackdus", v2si_ftype_di_di, WPACKDUS);
2565 iwmmx_mbuiltin ("wpackdss", v2si_ftype_di_di, WPACKDSS);
2566
2567 iwmmx_mbuiltin ("wunpckehub", v4hi_ftype_v8qi, WUNPCKEHUB);
2568 iwmmx_mbuiltin ("wunpckehuh", v2si_ftype_v4hi, WUNPCKEHUH);
2569 iwmmx_mbuiltin ("wunpckehuw", di_ftype_v2si, WUNPCKEHUW);
2570 iwmmx_mbuiltin ("wunpckehsb", v4hi_ftype_v8qi, WUNPCKEHSB);
2571 iwmmx_mbuiltin ("wunpckehsh", v2si_ftype_v4hi, WUNPCKEHSH);
2572 iwmmx_mbuiltin ("wunpckehsw", di_ftype_v2si, WUNPCKEHSW);
2573 iwmmx_mbuiltin ("wunpckelub", v4hi_ftype_v8qi, WUNPCKELUB);
2574 iwmmx_mbuiltin ("wunpckeluh", v2si_ftype_v4hi, WUNPCKELUH);
2575 iwmmx_mbuiltin ("wunpckeluw", di_ftype_v2si, WUNPCKELUW);
2576 iwmmx_mbuiltin ("wunpckelsb", v4hi_ftype_v8qi, WUNPCKELSB);
2577 iwmmx_mbuiltin ("wunpckelsh", v2si_ftype_v4hi, WUNPCKELSH);
2578 iwmmx_mbuiltin ("wunpckelsw", di_ftype_v2si, WUNPCKELSW);
2579
2580 iwmmx_mbuiltin ("wmacs", di_ftype_di_v4hi_v4hi, WMACS);
2581 iwmmx_mbuiltin ("wmacsz", di_ftype_v4hi_v4hi, WMACSZ);
2582 iwmmx_mbuiltin ("wmacu", di_ftype_di_v4hi_v4hi, WMACU);
2583 iwmmx_mbuiltin ("wmacuz", di_ftype_v4hi_v4hi, WMACUZ);
2584
2585 iwmmx_mbuiltin ("walign", v8qi_ftype_v8qi_v8qi_int, WALIGNI);
2586 iwmmx_mbuiltin ("tmia", di_ftype_di_int_int, TMIA);
2587 iwmmx_mbuiltin ("tmiaph", di_ftype_di_int_int, TMIAPH);
2588 iwmmx_mbuiltin ("tmiabb", di_ftype_di_int_int, TMIABB);
2589 iwmmx_mbuiltin ("tmiabt", di_ftype_di_int_int, TMIABT);
2590 iwmmx_mbuiltin ("tmiatb", di_ftype_di_int_int, TMIATB);
2591 iwmmx_mbuiltin ("tmiatt", di_ftype_di_int_int, TMIATT);
2592
2593 iwmmx2_mbuiltin ("wabsb", v8qi_ftype_v8qi, WABSB);
2594 iwmmx2_mbuiltin ("wabsh", v4hi_ftype_v4hi, WABSH);
2595 iwmmx2_mbuiltin ("wabsw", v2si_ftype_v2si, WABSW);
2596
2597 iwmmx2_mbuiltin ("wqmiabb", v2si_ftype_v2si_v4hi_v4hi, WQMIABB);
2598 iwmmx2_mbuiltin ("wqmiabt", v2si_ftype_v2si_v4hi_v4hi, WQMIABT);
2599 iwmmx2_mbuiltin ("wqmiatb", v2si_ftype_v2si_v4hi_v4hi, WQMIATB);
2600 iwmmx2_mbuiltin ("wqmiatt", v2si_ftype_v2si_v4hi_v4hi, WQMIATT);
2601
2602 iwmmx2_mbuiltin ("wqmiabbn", v2si_ftype_v2si_v4hi_v4hi, WQMIABBN);
2603 iwmmx2_mbuiltin ("wqmiabtn", v2si_ftype_v2si_v4hi_v4hi, WQMIABTN);
2604 iwmmx2_mbuiltin ("wqmiatbn", v2si_ftype_v2si_v4hi_v4hi, WQMIATBN);
2605 iwmmx2_mbuiltin ("wqmiattn", v2si_ftype_v2si_v4hi_v4hi, WQMIATTN);
2606
2607 iwmmx2_mbuiltin ("wmiabb", di_ftype_di_v4hi_v4hi, WMIABB);
2608 iwmmx2_mbuiltin ("wmiabt", di_ftype_di_v4hi_v4hi, WMIABT);
2609 iwmmx2_mbuiltin ("wmiatb", di_ftype_di_v4hi_v4hi, WMIATB);
2610 iwmmx2_mbuiltin ("wmiatt", di_ftype_di_v4hi_v4hi, WMIATT);
2611
2612 iwmmx2_mbuiltin ("wmiabbn", di_ftype_di_v4hi_v4hi, WMIABBN);
2613 iwmmx2_mbuiltin ("wmiabtn", di_ftype_di_v4hi_v4hi, WMIABTN);
2614 iwmmx2_mbuiltin ("wmiatbn", di_ftype_di_v4hi_v4hi, WMIATBN);
2615 iwmmx2_mbuiltin ("wmiattn", di_ftype_di_v4hi_v4hi, WMIATTN);
2616
2617 iwmmx2_mbuiltin ("wmiawbb", di_ftype_di_v2si_v2si, WMIAWBB);
2618 iwmmx2_mbuiltin ("wmiawbt", di_ftype_di_v2si_v2si, WMIAWBT);
2619 iwmmx2_mbuiltin ("wmiawtb", di_ftype_di_v2si_v2si, WMIAWTB);
2620 iwmmx2_mbuiltin ("wmiawtt", di_ftype_di_v2si_v2si, WMIAWTT);
2621
2622 iwmmx2_mbuiltin ("wmiawbbn", di_ftype_di_v2si_v2si, WMIAWBBN);
2623 iwmmx2_mbuiltin ("wmiawbtn", di_ftype_di_v2si_v2si, WMIAWBTN);
2624 iwmmx2_mbuiltin ("wmiawtbn", di_ftype_di_v2si_v2si, WMIAWTBN);
2625 iwmmx2_mbuiltin ("wmiawttn", di_ftype_di_v2si_v2si, WMIAWTTN);
2626
2627 iwmmx2_mbuiltin ("wmerge", di_ftype_di_di_int, WMERGE);
2628
2629 iwmmx_mbuiltin ("tbcstb", v8qi_ftype_char, TBCSTB);
2630 iwmmx_mbuiltin ("tbcsth", v4hi_ftype_short, TBCSTH);
2631 iwmmx_mbuiltin ("tbcstw", v2si_ftype_int, TBCSTW);
2632
2633#undef iwmmx_mbuiltin
2634#undef iwmmx2_mbuiltin
2635}
2636
2637static void
2638arm_init_fp16_builtins (void)
2639{
5774b1fa
JG
2640 arm_fp16_type_node = make_node (REAL_TYPE);
2641 TYPE_PRECISION (arm_fp16_type_node) = GET_MODE_PRECISION (HFmode);
2642 layout_type (arm_fp16_type_node);
50399bb1 2643 if (arm_fp16_format)
5774b1fa 2644 (*lang_hooks.types.register_builtin_type) (arm_fp16_type_node,
50399bb1 2645 "__fp16");
33857df2
JG
2646}
2647
33857df2
JG
2648void
2649arm_init_builtins (void)
2650{
2651 if (TARGET_REALLY_IWMMXT)
2652 arm_init_iwmmxt_builtins ();
2653
50399bb1
AL
2654 /* This creates the arm_simd_floatHF_type_node so must come before
2655 arm_init_neon_builtins which uses it. */
2656 arm_init_fp16_builtins ();
2657
2e87b2f4
SMW
2658 arm_init_bf16_types ();
2659
2e17e319 2660 if (TARGET_MAYBE_HARD_FLOAT)
edef1fa8 2661 {
63c8f7d6
SP
2662 tree lane_check_fpr = build_function_type_list (void_type_node,
2663 intSI_type_node,
2664 intSI_type_node,
2665 NULL);
2666 arm_builtin_decls[ARM_BUILTIN_SIMD_LANE_CHECK]
2667 = add_builtin_function ("__builtin_arm_lane_check", lane_check_fpr,
2668 ARM_BUILTIN_SIMD_LANE_CHECK, BUILT_IN_MD,
2669 NULL, NULL_TREE);
14782c81
SP
2670 if (TARGET_HAVE_MVE)
2671 arm_init_mve_builtins ();
2672 else
2673 arm_init_neon_builtins ();
66e31c3d 2674 arm_init_vfp_builtins ();
edef1fa8
CB
2675 arm_init_crypto_builtins ();
2676 }
33857df2 2677
78bf9163
MM
2678 if (TARGET_CDE)
2679 arm_init_cde_builtins ();
2680
7a2c8e28 2681 arm_init_acle_builtins ();
33857df2 2682
2e17e319 2683 if (TARGET_MAYBE_HARD_FLOAT)
33857df2
JG
2684 {
2685 tree ftype_set_fpscr
2686 = build_function_type_list (void_type_node, unsigned_type_node, NULL);
2687 tree ftype_get_fpscr
2688 = build_function_type_list (unsigned_type_node, NULL);
2689
2690 arm_builtin_decls[ARM_BUILTIN_GET_FPSCR]
556cf088 2691 = add_builtin_function ("__builtin_arm_get_fpscr", ftype_get_fpscr,
33857df2
JG
2692 ARM_BUILTIN_GET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE);
2693 arm_builtin_decls[ARM_BUILTIN_SET_FPSCR]
556cf088 2694 = add_builtin_function ("__builtin_arm_set_fpscr", ftype_set_fpscr,
33857df2
JG
2695 ARM_BUILTIN_SET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE);
2696 }
8261e476
AV
2697
2698 if (use_cmse)
2699 {
2700 tree ftype_cmse_nonsecure_caller
2701 = build_function_type_list (unsigned_type_node, NULL);
2702 arm_builtin_decls[ARM_BUILTIN_CMSE_NONSECURE_CALLER]
2703 = add_builtin_function ("__builtin_arm_cmse_nonsecure_caller",
2704 ftype_cmse_nonsecure_caller,
2705 ARM_BUILTIN_CMSE_NONSECURE_CALLER, BUILT_IN_MD,
2706 NULL, NULL_TREE);
2707 }
33857df2
JG
2708}
2709
2710/* Return the ARM builtin for CODE. */
2711
2712tree
2713arm_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
2714{
2715 if (code >= ARM_BUILTIN_MAX)
2716 return error_mark_node;
2717
2718 return arm_builtin_decls[code];
2719}
2720
2721/* Errors in the source file can cause expand_expr to return const0_rtx
2722 where we expect a vector. To avoid crashing, use one of the vector
2723 clear instructions. */
2724
2725static rtx
2726safe_vector_operand (rtx x, machine_mode mode)
2727{
2728 if (x != const0_rtx)
2729 return x;
2730 x = gen_reg_rtx (mode);
2731
2732 emit_insn (gen_iwmmxt_clrdi (mode == DImode ? x
2733 : gen_rtx_SUBREG (DImode, x, 0)));
2734 return x;
2735}
2736
2737/* Function to expand ternary builtins. */
2738static rtx
2739arm_expand_ternop_builtin (enum insn_code icode,
2740 tree exp, rtx target)
2741{
2742 rtx pat;
2743 tree arg0 = CALL_EXPR_ARG (exp, 0);
2744 tree arg1 = CALL_EXPR_ARG (exp, 1);
2745 tree arg2 = CALL_EXPR_ARG (exp, 2);
2746
2747 rtx op0 = expand_normal (arg0);
2748 rtx op1 = expand_normal (arg1);
2749 rtx op2 = expand_normal (arg2);
33857df2 2750
33857df2
JG
2751 machine_mode tmode = insn_data[icode].operand[0].mode;
2752 machine_mode mode0 = insn_data[icode].operand[1].mode;
2753 machine_mode mode1 = insn_data[icode].operand[2].mode;
2754 machine_mode mode2 = insn_data[icode].operand[3].mode;
2755
33857df2
JG
2756 if (VECTOR_MODE_P (mode0))
2757 op0 = safe_vector_operand (op0, mode0);
2758 if (VECTOR_MODE_P (mode1))
2759 op1 = safe_vector_operand (op1, mode1);
2760 if (VECTOR_MODE_P (mode2))
2761 op2 = safe_vector_operand (op2, mode2);
2762
2763 if (! target
2764 || GET_MODE (target) != tmode
2765 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2766 target = gen_reg_rtx (tmode);
2767
2768 gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode)
2769 && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode)
2770 && (GET_MODE (op2) == mode2 || GET_MODE (op2) == VOIDmode));
2771
2772 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2773 op0 = copy_to_mode_reg (mode0, op0);
2774 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
2775 op1 = copy_to_mode_reg (mode1, op1);
2776 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
2777 op2 = copy_to_mode_reg (mode2, op2);
33857df2 2778
b9a01009 2779 pat = GEN_FCN (icode) (target, op0, op1, op2);
33857df2
JG
2780 if (! pat)
2781 return 0;
2782 emit_insn (pat);
2783 return target;
2784}
2785
2786/* Subroutine of arm_expand_builtin to take care of binop insns. */
2787
2788static rtx
2789arm_expand_binop_builtin (enum insn_code icode,
2790 tree exp, rtx target)
2791{
2792 rtx pat;
2793 tree arg0 = CALL_EXPR_ARG (exp, 0);
2794 tree arg1 = CALL_EXPR_ARG (exp, 1);
2795 rtx op0 = expand_normal (arg0);
2796 rtx op1 = expand_normal (arg1);
2797 machine_mode tmode = insn_data[icode].operand[0].mode;
2798 machine_mode mode0 = insn_data[icode].operand[1].mode;
2799 machine_mode mode1 = insn_data[icode].operand[2].mode;
2800
2801 if (VECTOR_MODE_P (mode0))
2802 op0 = safe_vector_operand (op0, mode0);
2803 if (VECTOR_MODE_P (mode1))
2804 op1 = safe_vector_operand (op1, mode1);
2805
2806 if (! target
2807 || GET_MODE (target) != tmode
2808 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2809 target = gen_reg_rtx (tmode);
2810
2811 gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode)
2812 && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode));
2813
2814 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2815 op0 = copy_to_mode_reg (mode0, op0);
2816 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
2817 op1 = copy_to_mode_reg (mode1, op1);
2818
2819 pat = GEN_FCN (icode) (target, op0, op1);
2820 if (! pat)
2821 return 0;
2822 emit_insn (pat);
2823 return target;
2824}
2825
2826/* Subroutine of arm_expand_builtin to take care of unop insns. */
2827
2828static rtx
2829arm_expand_unop_builtin (enum insn_code icode,
2830 tree exp, rtx target, int do_load)
2831{
2832 rtx pat;
2833 tree arg0 = CALL_EXPR_ARG (exp, 0);
2834 rtx op0 = expand_normal (arg0);
33857df2
JG
2835 machine_mode tmode = insn_data[icode].operand[0].mode;
2836 machine_mode mode0 = insn_data[icode].operand[1].mode;
33857df2
JG
2837
2838 if (! target
2839 || GET_MODE (target) != tmode
2840 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2841 target = gen_reg_rtx (tmode);
2842 if (do_load)
2843 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
2844 else
2845 {
2846 if (VECTOR_MODE_P (mode0))
2847 op0 = safe_vector_operand (op0, mode0);
2848
2849 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2850 op0 = copy_to_mode_reg (mode0, op0);
2851 }
33857df2 2852
b9a01009
ST
2853 pat = GEN_FCN (icode) (target, op0);
2854
33857df2
JG
2855 if (! pat)
2856 return 0;
2857 emit_insn (pat);
2858 return target;
2859}
2860
2861typedef enum {
131e1faa
AV
2862 ARG_BUILTIN_COPY_TO_REG,
2863 ARG_BUILTIN_CONSTANT,
2864 ARG_BUILTIN_LANE_INDEX,
2865 ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX,
c2b7062d 2866 ARG_BUILTIN_LANE_PAIR_INDEX,
f348846e 2867 ARG_BUILTIN_LANE_QUADTUP_INDEX,
131e1faa
AV
2868 ARG_BUILTIN_NEON_MEMORY,
2869 ARG_BUILTIN_MEMORY,
2870 ARG_BUILTIN_STOP
33857df2
JG
2871} builtin_arg;
2872
33857df2
JG
2873
2874/* EXP is a pointer argument to a Neon load or store intrinsic. Derive
2875 and return an expression for the accessed memory.
2876
2877 The intrinsic function operates on a block of registers that has
2878 mode REG_MODE. This block contains vectors of type TYPE_MODE. The
2879 function references the memory at EXP of type TYPE and in mode
2880 MEM_MODE; this mode may be BLKmode if no more suitable mode is
2881 available. */
2882
2883static tree
2884neon_dereference_pointer (tree exp, tree type, machine_mode mem_mode,
2885 machine_mode reg_mode,
bd79363c 2886 machine_mode vector_mode)
33857df2
JG
2887{
2888 HOST_WIDE_INT reg_size, vector_size, nvectors, nelems;
2889 tree elem_type, upper_bound, array_type;
2890
2891 /* Work out the size of the register block in bytes. */
2892 reg_size = GET_MODE_SIZE (reg_mode);
2893
2894 /* Work out the size of each vector in bytes. */
bd79363c 2895 vector_size = GET_MODE_SIZE (vector_mode);
33857df2
JG
2896
2897 /* Work out how many vectors there are. */
2898 gcc_assert (reg_size % vector_size == 0);
2899 nvectors = reg_size / vector_size;
2900
2901 /* Work out the type of each element. */
2902 gcc_assert (POINTER_TYPE_P (type));
2903 elem_type = TREE_TYPE (type);
2904
2905 /* Work out how many elements are being loaded or stored.
2906 MEM_MODE == REG_MODE implies a one-to-one mapping between register
2907 and memory elements; anything else implies a lane load or store. */
2908 if (mem_mode == reg_mode)
2909 nelems = vector_size * nvectors / int_size_in_bytes (elem_type);
2910 else
2911 nelems = nvectors;
2912
2913 /* Create a type that describes the full access. */
2914 upper_bound = build_int_cst (size_type_node, nelems - 1);
2915 array_type = build_array_type (elem_type, build_index_type (upper_bound));
2916
2917 /* Dereference EXP using that type. */
2918 return fold_build2 (MEM_REF, array_type, exp,
2919 build_int_cst (build_pointer_type (array_type), 0));
2920}
2921
63c8f7d6
SP
2922/* EXP is a pointer argument to a vector scatter store intrinsics.
2923
2924 Consider the following example:
2925 VSTRW<v>.<dt> Qd, [Qm{, #+/-<imm>}]!
2926 When <Qm> used as the base register for the target address,
2927 this function is used to derive and return an expression for the
2928 accessed memory.
2929
2930 The intrinsic function operates on a block of registers that has mode
2931 REG_MODE. This block contains vectors of type TYPE_MODE. The function
2932 references the memory at EXP of type TYPE and in mode MEM_MODE. This
2933 mode may be BLKmode if no more suitable mode is available. */
2934
2935static tree
2936mve_dereference_pointer (tree exp, tree type, machine_mode reg_mode,
2937 machine_mode vector_mode)
2938{
2939 HOST_WIDE_INT reg_size, vector_size, nelems;
2940 tree elem_type, upper_bound, array_type;
2941
2942 /* Work out the size of each vector in bytes. */
2943 vector_size = GET_MODE_SIZE (vector_mode);
2944
2945 /* Work out the size of the register block in bytes. */
2946 reg_size = GET_MODE_SIZE (reg_mode);
2947
2948 /* Work out the type of each element. */
2949 gcc_assert (POINTER_TYPE_P (type));
2950 elem_type = TREE_TYPE (type);
2951
2952 nelems = reg_size / vector_size;
2953
2954 /* Create a type that describes the full access. */
2955 upper_bound = build_int_cst (size_type_node, nelems - 1);
2956 array_type = build_array_type (elem_type, build_index_type (upper_bound));
2957
2958 /* Dereference EXP using that type. */
2959 return fold_build2 (MEM_REF, array_type, exp,
2960 build_int_cst (build_pointer_type (array_type), 0));
2961}
2962
131e1faa 2963/* Expand a builtin. */
33857df2 2964static rtx
131e1faa 2965arm_expand_builtin_args (rtx target, machine_mode map_mode, int fcode,
2f7d18dd
CB
2966 int icode, int have_retval, tree exp,
2967 builtin_arg *args)
33857df2 2968{
33857df2 2969 rtx pat;
bd79363c
JG
2970 tree arg[SIMD_MAX_BUILTIN_ARGS];
2971 rtx op[SIMD_MAX_BUILTIN_ARGS];
33857df2 2972 machine_mode tmode = insn_data[icode].operand[0].mode;
bd79363c
JG
2973 machine_mode mode[SIMD_MAX_BUILTIN_ARGS];
2974 tree formals;
33857df2 2975 int argc = 0;
7a2c8e28 2976 rtx_insn * insn;
33857df2
JG
2977
2978 if (have_retval
2979 && (!target
2980 || GET_MODE (target) != tmode
2981 || !(*insn_data[icode].operand[0].predicate) (target, tmode)))
2982 target = gen_reg_rtx (tmode);
2983
33857df2
JG
2984 formals = TYPE_ARG_TYPES (TREE_TYPE (arm_builtin_decls[fcode]));
2985
2986 for (;;)
2987 {
2f7d18dd 2988 builtin_arg thisarg = args[argc];
33857df2 2989
131e1faa 2990 if (thisarg == ARG_BUILTIN_STOP)
bd79363c 2991 break;
33857df2 2992 else
bd79363c
JG
2993 {
2994 int opno = argc + have_retval;
2995 arg[argc] = CALL_EXPR_ARG (exp, argc);
2996 mode[argc] = insn_data[icode].operand[opno].mode;
131e1faa 2997 if (thisarg == ARG_BUILTIN_NEON_MEMORY)
33857df2 2998 {
bd79363c
JG
2999 machine_mode other_mode
3000 = insn_data[icode].operand[1 - opno].mode;
63c8f7d6
SP
3001 if (TARGET_HAVE_MVE && mode[argc] != other_mode)
3002 {
3003 arg[argc] = mve_dereference_pointer (arg[argc],
bd79363c 3004 TREE_VALUE (formals),
63c8f7d6
SP
3005 other_mode, map_mode);
3006 }
3007 else
3008 arg[argc] = neon_dereference_pointer (arg[argc],
3009 TREE_VALUE (formals),
3010 mode[argc], other_mode,
3011 map_mode);
33857df2
JG
3012 }
3013
131e1faa
AV
3014 /* Use EXPAND_MEMORY for ARG_BUILTIN_MEMORY and
3015 ARG_BUILTIN_NEON_MEMORY to ensure a MEM_P be returned. */
33857df2 3016 op[argc] = expand_expr (arg[argc], NULL_RTX, VOIDmode,
131e1faa
AV
3017 ((thisarg == ARG_BUILTIN_MEMORY
3018 || thisarg == ARG_BUILTIN_NEON_MEMORY)
33857df2
JG
3019 ? EXPAND_MEMORY : EXPAND_NORMAL));
3020
bd79363c
JG
3021 switch (thisarg)
3022 {
131e1faa
AV
3023 case ARG_BUILTIN_MEMORY:
3024 case ARG_BUILTIN_COPY_TO_REG:
bd79363c
JG
3025 if (POINTER_TYPE_P (TREE_TYPE (arg[argc])))
3026 op[argc] = convert_memory_address (Pmode, op[argc]);
3027 /*gcc_assert (GET_MODE (op[argc]) == mode[argc]); */
3028 if (!(*insn_data[icode].operand[opno].predicate)
3029 (op[argc], mode[argc]))
3030 op[argc] = copy_to_mode_reg (mode[argc], op[argc]);
3031 break;
33857df2 3032
131e1faa 3033 case ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX:
2f7d18dd
CB
3034 gcc_assert (argc > 1);
3035 if (CONST_INT_P (op[argc]))
3036 {
3037 neon_lane_bounds (op[argc], 0,
3038 GET_MODE_NUNITS (map_mode), exp);
3039 /* Keep to GCC-vector-extension lane indices in the RTL. */
3040 op[argc] =
3041 GEN_INT (NEON_ENDIAN_LANE_N (map_mode, INTVAL (op[argc])));
3042 }
3043 goto constant_arg;
3044
131e1faa 3045 case ARG_BUILTIN_LANE_INDEX:
eaa80f64
AL
3046 /* Previous argument must be a vector, which this indexes. */
3047 gcc_assert (argc > 0);
3048 if (CONST_INT_P (op[argc]))
3049 {
b8506a8a 3050 machine_mode vmode = mode[argc - 1];
eaa80f64
AL
3051 neon_lane_bounds (op[argc], 0, GET_MODE_NUNITS (vmode), exp);
3052 }
c2b7062d
TC
3053 /* If the lane index isn't a constant then error out. */
3054 goto constant_arg;
3055
3056 case ARG_BUILTIN_LANE_PAIR_INDEX:
3057 /* Previous argument must be a vector, which this indexes. The
3058 indexing will always select i and i+1 out of the vector, which
3059 puts a limit on i. */
3060 gcc_assert (argc > 0);
3061 if (CONST_INT_P (op[argc]))
3062 {
3063 machine_mode vmode = mode[argc - 1];
f348846e
SMW
3064 neon_lane_bounds (op[argc], 0,
3065 GET_MODE_NUNITS (vmode) / 2, exp);
3066 }
3067 /* If the lane index isn't a constant then error out. */
3068 goto constant_arg;
3069
3070 case ARG_BUILTIN_LANE_QUADTUP_INDEX:
3071 /* Previous argument must be a vector, which this indexes. */
3072 gcc_assert (argc > 0);
3073 if (CONST_INT_P (op[argc]))
3074 {
3075 machine_mode vmode = mode[argc - 1];
3076 neon_lane_bounds (op[argc], 0,
3077 GET_MODE_NUNITS (vmode) / 4, exp);
c2b7062d 3078 }
f348846e
SMW
3079 /* If the lane index isn't a constant then error out. */
3080 goto constant_arg;
3081
131e1faa 3082 case ARG_BUILTIN_CONSTANT:
2f7d18dd 3083constant_arg:
bd79363c
JG
3084 if (!(*insn_data[icode].operand[opno].predicate)
3085 (op[argc], mode[argc]))
2f7d18dd 3086 {
07b9bfd0
DZ
3087 if (IN_RANGE (fcode, ARM_BUILTIN_CDE_PATTERN_START,
3088 ARM_BUILTIN_CDE_PATTERN_END))
3089 {
3090 if (argc == 0)
3091 {
53e65d80
RS
3092 unsigned int cp_bit = (CONST_INT_P (op[argc])
3093 ? UINTVAL (op[argc]) : -1);
07b9bfd0
DZ
3094 if (IN_RANGE (cp_bit, 0, ARM_CDE_CONST_COPROC))
3095 error ("%Kcoprocessor %d is not enabled "
3096 "with +cdecp%d", exp, cp_bit, cp_bit);
3097 else
3098 error ("%Kcoproc must be a constant immediate in "
3099 "range [0-%d] enabled with +cdecp<N>", exp,
3100 ARM_CDE_CONST_COPROC);
3101 }
3102 else
ef684c78
MM
3103 /* Here we mention the builtin name to follow the same
3104 format that the C/C++ frontends use for referencing
3105 a given argument index. */
3106 error ("%Kargument %d to %qE must be a constant immediate "
07b9bfd0 3107 "in range [0-%d]", exp, argc + 1,
ef684c78 3108 arm_builtin_decls[fcode],
07b9bfd0
DZ
3109 cde_builtin_data[fcode -
3110 ARM_BUILTIN_CDE_PATTERN_START].imm_max);
3111 }
3112 else
3113 error ("%Kargument %d must be a constant immediate",
3114 exp, argc + 1);
56960fd6
JG
3115 /* We have failed to expand the pattern, and are safely
3116 in to invalid code. But the mid-end will still try to
3117 build an assignment for this node while it expands,
3118 before stopping for the error, just pass it back
3119 TARGET to ensure a valid assignment. */
3120 return target;
2f7d18dd 3121 }
bd79363c 3122 break;
2f7d18dd 3123
131e1faa 3124 case ARG_BUILTIN_NEON_MEMORY:
33857df2
JG
3125 /* Check if expand failed. */
3126 if (op[argc] == const0_rtx)
3127 return 0;
3128 gcc_assert (MEM_P (op[argc]));
3129 PUT_MODE (op[argc], mode[argc]);
3130 /* ??? arm_neon.h uses the same built-in functions for signed
3131 and unsigned accesses, casting where necessary. This isn't
3132 alias safe. */
3133 set_mem_alias_set (op[argc], 0);
3134 if (!(*insn_data[icode].operand[opno].predicate)
bd79363c 3135 (op[argc], mode[argc]))
33857df2 3136 op[argc] = (replace_equiv_address
27b1820a
KV
3137 (op[argc],
3138 copy_to_mode_reg (Pmode, XEXP (op[argc], 0))));
33857df2
JG
3139 break;
3140
131e1faa 3141 case ARG_BUILTIN_STOP:
bd79363c
JG
3142 gcc_unreachable ();
3143 }
33857df2 3144
bd79363c
JG
3145 argc++;
3146 }
33857df2
JG
3147 }
3148
33857df2
JG
3149 if (have_retval)
3150 switch (argc)
3151 {
cf16f980
KT
3152 case 0:
3153 pat = GEN_FCN (icode) (target);
3154 break;
33857df2
JG
3155 case 1:
3156 pat = GEN_FCN (icode) (target, op[0]);
3157 break;
3158
3159 case 2:
3160 pat = GEN_FCN (icode) (target, op[0], op[1]);
3161 break;
3162
3163 case 3:
3164 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
3165 break;
3166
3167 case 4:
3168 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
3169 break;
3170
3171 case 5:
3172 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4]);
3173 break;
3174
d57daa0c
AV
3175 case 6:
3176 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4], op[5]);
3177 break;
3178
33857df2
JG
3179 default:
3180 gcc_unreachable ();
3181 }
3182 else
3183 switch (argc)
3184 {
3185 case 1:
3186 pat = GEN_FCN (icode) (op[0]);
3187 break;
3188
3189 case 2:
3190 pat = GEN_FCN (icode) (op[0], op[1]);
3191 break;
3192
3193 case 3:
3194 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
3195 break;
3196
3197 case 4:
3198 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
3199 break;
3200
3201 case 5:
3202 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
bd79363c 3203 break;
33857df2 3204
d57daa0c
AV
3205 case 6:
3206 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]);
3207 break;
3208
33857df2
JG
3209 default:
3210 gcc_unreachable ();
3211 }
3212
3213 if (!pat)
3214 return 0;
3215
7a2c8e28
AV
3216 /* Check whether our current target implements the pattern chosen for this
3217 builtin and error out if not. */
3218 start_sequence ();
33857df2 3219 emit_insn (pat);
7a2c8e28
AV
3220 insn = get_insns ();
3221 end_sequence ();
3222
3223 if (recog_memoized (insn) < 0)
3224 error ("this builtin is not supported for this target");
3225 else
3226 emit_insn (insn);
33857df2
JG
3227
3228 return target;
3229}
3230
131e1faa
AV
3231/* Expand a builtin. These builtins are "special" because they don't have
3232 symbolic constants defined per-instruction or per instruction-variant.
3233 Instead, the required info is looked up in the ARM_BUILTIN_DATA record that
3234 is passed into the function. */
bce2b8f9 3235
33857df2 3236static rtx
131e1faa
AV
3237arm_expand_builtin_1 (int fcode, tree exp, rtx target,
3238 arm_builtin_datum *d)
33857df2 3239{
33857df2 3240 enum insn_code icode = d->code;
6d31cc75 3241 builtin_arg args[SIMD_MAX_BUILTIN_ARGS + 1];
bd79363c
JG
3242 int num_args = insn_data[d->code].n_operands;
3243 int is_void = 0;
3244 int k;
131e1faa 3245 bool neon = false;
14782c81 3246 bool mve = false;
131e1faa 3247
7a2c8e28 3248 if (IN_RANGE (fcode, ARM_BUILTIN_VFP_BASE, ARM_BUILTIN_ACLE_BASE - 1))
131e1faa 3249 neon = true;
bd79363c 3250
14782c81
SP
3251 if (IN_RANGE (fcode, ARM_BUILTIN_MVE_BASE, ARM_BUILTIN_MAX - 1))
3252 mve = true;
3253
bd79363c 3254 is_void = !!(d->qualifiers[0] & qualifier_void);
33857df2 3255
bd79363c
JG
3256 num_args += is_void;
3257
3258 for (k = 1; k < num_args; k++)
33857df2 3259 {
bd79363c
JG
3260 /* We have four arrays of data, each indexed in a different fashion.
3261 qualifiers - element 0 always describes the function return type.
3262 operands - element 0 is either the operand for return value (if
bce2b8f9
MW
3263 the function has a non-void return type) or the operand for the
3264 first argument.
bd79363c
JG
3265 expr_args - element 0 always holds the first argument.
3266 args - element 0 is always used for the return type. */
3267 int qualifiers_k = k;
3268 int operands_k = k - is_void;
3269 int expr_args_k = k - 1;
3270
eaa80f64 3271 if (d->qualifiers[qualifiers_k] & qualifier_lane_index)
131e1faa 3272 args[k] = ARG_BUILTIN_LANE_INDEX;
c2b7062d
TC
3273 else if (d->qualifiers[qualifiers_k] & qualifier_lane_pair_index)
3274 args[k] = ARG_BUILTIN_LANE_PAIR_INDEX;
f348846e
SMW
3275 else if (d->qualifiers[qualifiers_k] & qualifier_lane_quadtup_index)
3276 args[k] = ARG_BUILTIN_LANE_QUADTUP_INDEX;
2f7d18dd 3277 else if (d->qualifiers[qualifiers_k] & qualifier_struct_load_store_lane_index)
131e1faa 3278 args[k] = ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX;
eaa80f64 3279 else if (d->qualifiers[qualifiers_k] & qualifier_immediate)
131e1faa 3280 args[k] = ARG_BUILTIN_CONSTANT;
bd79363c
JG
3281 else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate)
3282 {
3283 rtx arg
3284 = expand_normal (CALL_EXPR_ARG (exp,
3285 (expr_args_k)));
3286 /* Handle constants only if the predicate allows it. */
3287 bool op_const_int_p =
3288 (CONST_INT_P (arg)
3289 && (*insn_data[icode].operand[operands_k].predicate)
bce2b8f9 3290 (arg, insn_data[icode].operand[operands_k].mode));
131e1faa 3291 args[k] = op_const_int_p ? ARG_BUILTIN_CONSTANT : ARG_BUILTIN_COPY_TO_REG;
bd79363c
JG
3292 }
3293 else if (d->qualifiers[qualifiers_k] & qualifier_pointer)
131e1faa 3294 {
14782c81 3295 if (neon || mve)
131e1faa
AV
3296 args[k] = ARG_BUILTIN_NEON_MEMORY;
3297 else
3298 args[k] = ARG_BUILTIN_MEMORY;
3299 }
bd79363c 3300 else
131e1faa 3301 args[k] = ARG_BUILTIN_COPY_TO_REG;
33857df2 3302 }
131e1faa 3303 args[k] = ARG_BUILTIN_STOP;
bd79363c 3304
131e1faa 3305 /* The interface to arm_expand_builtin_args expects a 0 if
bd79363c 3306 the function is void, and a 1 if it is not. */
131e1faa 3307 return arm_expand_builtin_args
bce2b8f9
MW
3308 (target, d->mode, fcode, icode, !is_void, exp,
3309 &args[1]);
3310}
3311
7a2c8e28
AV
3312/* Expand an ACLE builtin, i.e. those registered only if their respective
3313 target constraints are met. This check happens within
3314 arm_expand_builtin_args. */
3315
3316static rtx
3317arm_expand_acle_builtin (int fcode, tree exp, rtx target)
3318{
cf16f980
KT
3319 if (fcode == ARM_BUILTIN_SAT_IMM_CHECK)
3320 {
3321 /* Check the saturation immediate bounds. */
3322
3323 rtx min_sat = expand_normal (CALL_EXPR_ARG (exp, 1));
3324 rtx max_sat = expand_normal (CALL_EXPR_ARG (exp, 2));
3325 gcc_assert (CONST_INT_P (min_sat));
3326 gcc_assert (CONST_INT_P (max_sat));
3327 rtx sat_imm = expand_normal (CALL_EXPR_ARG (exp, 0));
3328 if (CONST_INT_P (sat_imm))
3329 {
3330 if (!IN_RANGE (sat_imm, min_sat, max_sat))
3331 error ("%Ksaturation bit range must be in the range [%wd, %wd]",
3332 exp, UINTVAL (min_sat), UINTVAL (max_sat));
3333 }
3334 else
3335 error ("%Ksaturation bit range must be a constant immediate", exp);
3336 /* Don't generate any RTL. */
3337 return const0_rtx;
3338 }
07b9bfd0
DZ
3339
3340 gcc_assert (fcode != ARM_BUILTIN_CDE_BASE);
7a2c8e28 3341 arm_builtin_datum *d
07b9bfd0
DZ
3342 = (fcode < ARM_BUILTIN_CDE_BASE)
3343 ? &acle_builtin_data[fcode - ARM_BUILTIN_ACLE_PATTERN_START]
3344 : &cde_builtin_data[fcode - ARM_BUILTIN_CDE_PATTERN_START].base;
7a2c8e28
AV
3345
3346 return arm_expand_builtin_1 (fcode, exp, target, d);
3347}
3348
14782c81
SP
3349/* Expand an MVE builtin, i.e. those registered only if their respective target
3350 constraints are met. This check happens within arm_expand_builtin. */
3351
3352static rtx
3353arm_expand_mve_builtin (int fcode, tree exp, rtx target)
3354{
3355 if (fcode >= ARM_BUILTIN_MVE_BASE && !TARGET_HAVE_MVE)
3356 {
3357 fatal_error (input_location,
3358 "You must enable MVE instructions"
3359 " to use these intrinsics");
3360 return const0_rtx;
3361 }
3362
3363 arm_builtin_datum *d
3364 = &mve_builtin_data[fcode - ARM_BUILTIN_MVE_PATTERN_START];
3365
3366 return arm_expand_builtin_1 (fcode, exp, target, d);
3367}
3368
bce2b8f9
MW
3369/* Expand a Neon builtin, i.e. those registered only if TARGET_NEON holds.
3370 Most of these are "special" because they don't have symbolic
3371 constants defined per-instruction or per instruction-variant. Instead, the
3372 required info is looked up in the table neon_builtin_data. */
3373
3374static rtx
3375arm_expand_neon_builtin (int fcode, tree exp, rtx target)
3376{
3377 if (fcode >= ARM_BUILTIN_NEON_BASE && ! TARGET_NEON)
3378 {
3379 fatal_error (input_location,
3380 "You must enable NEON instructions"
a3f9f006 3381 " (e.g. %<-mfloat-abi=softfp%> %<-mfpu=neon%>)"
bce2b8f9
MW
3382 " to use these intrinsics.");
3383 return const0_rtx;
3384 }
3385
131e1faa 3386 arm_builtin_datum *d
bce2b8f9
MW
3387 = &neon_builtin_data[fcode - ARM_BUILTIN_NEON_PATTERN_START];
3388
131e1faa 3389 return arm_expand_builtin_1 (fcode, exp, target, d);
33857df2
JG
3390}
3391
00ea1506 3392/* Expand a VFP builtin. These builtins are treated like
66e31c3d
MW
3393 neon builtins except that the data is looked up in table
3394 VFP_BUILTIN_DATA. */
3395
3396static rtx
3397arm_expand_vfp_builtin (int fcode, tree exp, rtx target)
3398{
00ea1506 3399 if (fcode >= ARM_BUILTIN_VFP_BASE && ! TARGET_HARD_FLOAT)
66e31c3d
MW
3400 {
3401 fatal_error (input_location,
3402 "You must enable VFP instructions"
3403 " to use these intrinsics.");
3404 return const0_rtx;
3405 }
3406
131e1faa 3407 arm_builtin_datum *d
66e31c3d
MW
3408 = &vfp_builtin_data[fcode - ARM_BUILTIN_VFP_PATTERN_START];
3409
131e1faa 3410 return arm_expand_builtin_1 (fcode, exp, target, d);
66e31c3d
MW
3411}
3412
33857df2
JG
3413/* Expand an expression EXP that calls a built-in function,
3414 with result going to TARGET if that's convenient
3415 (and in mode MODE if that's convenient).
3416 SUBTARGET may be used as the target for computing one of EXP's operands.
3417 IGNORE is nonzero if the value is to be ignored. */
3418
3419rtx
3420arm_expand_builtin (tree exp,
3421 rtx target,
3422 rtx subtarget ATTRIBUTE_UNUSED,
3423 machine_mode mode ATTRIBUTE_UNUSED,
3424 int ignore ATTRIBUTE_UNUSED)
3425{
3426 const struct builtin_description * d;
3427 enum insn_code icode;
3428 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3429 tree arg0;
3430 tree arg1;
3431 tree arg2;
3432 rtx op0;
3433 rtx op1;
3434 rtx op2;
3435 rtx pat;
4d732405 3436 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
33857df2
JG
3437 size_t i;
3438 machine_mode tmode;
3439 machine_mode mode0;
3440 machine_mode mode1;
3441 machine_mode mode2;
3442 int opint;
3443 int selector;
3444 int mask;
3445 int imm;
3446
63c8f7d6
SP
3447 if (fcode == ARM_BUILTIN_SIMD_LANE_CHECK)
3448 {
3449 /* Builtin is only to check bounds of the lane passed to some intrinsics
3450 that are implemented with gcc vector extensions in arm_neon.h. */
3451
3452 tree nlanes = CALL_EXPR_ARG (exp, 0);
3453 gcc_assert (TREE_CODE (nlanes) == INTEGER_CST);
3454 rtx lane_idx = expand_normal (CALL_EXPR_ARG (exp, 1));
3455 if (CONST_INT_P (lane_idx))
3456 neon_lane_bounds (lane_idx, 0, TREE_INT_CST_LOW (nlanes), exp);
3457 else
3458 error ("%Klane index must be a constant immediate", exp);
3459 /* Don't generate any RTL. */
3460 return const0_rtx;
3461 }
14782c81
SP
3462 if (fcode >= ARM_BUILTIN_MVE_BASE)
3463 return arm_expand_mve_builtin (fcode, exp, target);
63c8f7d6 3464
7a2c8e28
AV
3465 if (fcode >= ARM_BUILTIN_ACLE_BASE)
3466 return arm_expand_acle_builtin (fcode, exp, target);
3467
33857df2
JG
3468 if (fcode >= ARM_BUILTIN_NEON_BASE)
3469 return arm_expand_neon_builtin (fcode, exp, target);
3470
66e31c3d
MW
3471 if (fcode >= ARM_BUILTIN_VFP_BASE)
3472 return arm_expand_vfp_builtin (fcode, exp, target);
3473
edef1fa8
CB
3474 /* Check in the context of the function making the call whether the
3475 builtin is supported. */
3476 if (fcode >= ARM_BUILTIN_CRYPTO_BASE
3477 && (!TARGET_CRYPTO || !TARGET_HARD_FLOAT))
3478 {
3479 fatal_error (input_location,
66e31c3d 3480 "You must enable crypto instructions"
a3f9f006
ML
3481 " (e.g. include %<-mfloat-abi=softfp%> "
3482 "%<-mfpu=crypto-neon%>)"
66e31c3d 3483 " to use these intrinsics.");
edef1fa8
CB
3484 return const0_rtx;
3485 }
3486
33857df2
JG
3487 switch (fcode)
3488 {
c3562f81
SP
3489 case ARM_BUILTIN_GET_FPSCR_NZCVQC:
3490 case ARM_BUILTIN_SET_FPSCR_NZCVQC:
3491 if (fcode == ARM_BUILTIN_GET_FPSCR_NZCVQC)
3492 {
3493 icode = CODE_FOR_get_fpscr_nzcvqc;
3494 target = gen_reg_rtx (SImode);
3495 emit_insn (GEN_FCN (icode) (target));
3496 return target;
3497 }
3498 else
3499 {
3500 icode = CODE_FOR_set_fpscr_nzcvqc;
3501 op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
3502 emit_insn (GEN_FCN (icode) (force_reg (SImode, op0)));
3503 return NULL_RTX;
3504 }
3505
33857df2
JG
3506 case ARM_BUILTIN_GET_FPSCR:
3507 case ARM_BUILTIN_SET_FPSCR:
3508 if (fcode == ARM_BUILTIN_GET_FPSCR)
3509 {
3510 icode = CODE_FOR_get_fpscr;
3511 target = gen_reg_rtx (SImode);
3512 pat = GEN_FCN (icode) (target);
3513 }
3514 else
3515 {
3516 target = NULL_RTX;
3517 icode = CODE_FOR_set_fpscr;
3518 arg0 = CALL_EXPR_ARG (exp, 0);
3519 op0 = expand_normal (arg0);
60d1915f 3520 pat = GEN_FCN (icode) (force_reg (SImode, op0));
33857df2
JG
3521 }
3522 emit_insn (pat);
3523 return target;
3524
8261e476
AV
3525 case ARM_BUILTIN_CMSE_NONSECURE_CALLER:
3526 target = gen_reg_rtx (SImode);
3527 op0 = arm_return_addr (0, NULL_RTX);
f4d43ef0
TP
3528 emit_insn (gen_andsi3 (target, op0, const1_rtx));
3529 op1 = gen_rtx_EQ (SImode, target, const0_rtx);
3530 emit_insn (gen_cstoresi4 (target, op1, target, const0_rtx));
8261e476
AV
3531 return target;
3532
33857df2
JG
3533 case ARM_BUILTIN_TEXTRMSB:
3534 case ARM_BUILTIN_TEXTRMUB:
3535 case ARM_BUILTIN_TEXTRMSH:
3536 case ARM_BUILTIN_TEXTRMUH:
3537 case ARM_BUILTIN_TEXTRMSW:
3538 case ARM_BUILTIN_TEXTRMUW:
3539 icode = (fcode == ARM_BUILTIN_TEXTRMSB ? CODE_FOR_iwmmxt_textrmsb
3540 : fcode == ARM_BUILTIN_TEXTRMUB ? CODE_FOR_iwmmxt_textrmub
3541 : fcode == ARM_BUILTIN_TEXTRMSH ? CODE_FOR_iwmmxt_textrmsh
3542 : fcode == ARM_BUILTIN_TEXTRMUH ? CODE_FOR_iwmmxt_textrmuh
3543 : CODE_FOR_iwmmxt_textrmw);
3544
3545 arg0 = CALL_EXPR_ARG (exp, 0);
3546 arg1 = CALL_EXPR_ARG (exp, 1);
3547 op0 = expand_normal (arg0);
3548 op1 = expand_normal (arg1);
3549 tmode = insn_data[icode].operand[0].mode;
3550 mode0 = insn_data[icode].operand[1].mode;
3551 mode1 = insn_data[icode].operand[2].mode;
3552
3553 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3554 op0 = copy_to_mode_reg (mode0, op0);
3555 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
3556 {
3557 /* @@@ better error message */
3558 error ("selector must be an immediate");
3559 return gen_reg_rtx (tmode);
3560 }
3561
3562 opint = INTVAL (op1);
3563 if (fcode == ARM_BUILTIN_TEXTRMSB || fcode == ARM_BUILTIN_TEXTRMUB)
3564 {
3565 if (opint > 7 || opint < 0)
3566 error ("the range of selector should be in 0 to 7");
3567 }
3568 else if (fcode == ARM_BUILTIN_TEXTRMSH || fcode == ARM_BUILTIN_TEXTRMUH)
3569 {
3570 if (opint > 3 || opint < 0)
3571 error ("the range of selector should be in 0 to 3");
3572 }
3573 else /* ARM_BUILTIN_TEXTRMSW || ARM_BUILTIN_TEXTRMUW. */
3574 {
3575 if (opint > 1 || opint < 0)
3576 error ("the range of selector should be in 0 to 1");
3577 }
3578
3579 if (target == 0
3580 || GET_MODE (target) != tmode
3581 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3582 target = gen_reg_rtx (tmode);
3583 pat = GEN_FCN (icode) (target, op0, op1);
3584 if (! pat)
3585 return 0;
3586 emit_insn (pat);
3587 return target;
3588
3589 case ARM_BUILTIN_WALIGNI:
3590 /* If op2 is immediate, call walighi, else call walighr. */
3591 arg0 = CALL_EXPR_ARG (exp, 0);
3592 arg1 = CALL_EXPR_ARG (exp, 1);
3593 arg2 = CALL_EXPR_ARG (exp, 2);
3594 op0 = expand_normal (arg0);
3595 op1 = expand_normal (arg1);
3596 op2 = expand_normal (arg2);
3597 if (CONST_INT_P (op2))
3598 {
3599 icode = CODE_FOR_iwmmxt_waligni;
3600 tmode = insn_data[icode].operand[0].mode;
3601 mode0 = insn_data[icode].operand[1].mode;
3602 mode1 = insn_data[icode].operand[2].mode;
3603 mode2 = insn_data[icode].operand[3].mode;
3604 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
3605 op0 = copy_to_mode_reg (mode0, op0);
3606 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
3607 op1 = copy_to_mode_reg (mode1, op1);
3608 gcc_assert ((*insn_data[icode].operand[3].predicate) (op2, mode2));
3609 selector = INTVAL (op2);
3610 if (selector > 7 || selector < 0)
3611 error ("the range of selector should be in 0 to 7");
3612 }
3613 else
3614 {
3615 icode = CODE_FOR_iwmmxt_walignr;
3616 tmode = insn_data[icode].operand[0].mode;
3617 mode0 = insn_data[icode].operand[1].mode;
3618 mode1 = insn_data[icode].operand[2].mode;
3619 mode2 = insn_data[icode].operand[3].mode;
3620 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
3621 op0 = copy_to_mode_reg (mode0, op0);
3622 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
3623 op1 = copy_to_mode_reg (mode1, op1);
3624 if (!(*insn_data[icode].operand[3].predicate) (op2, mode2))
3625 op2 = copy_to_mode_reg (mode2, op2);
3626 }
3627 if (target == 0
3628 || GET_MODE (target) != tmode
3629 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
3630 target = gen_reg_rtx (tmode);
3631 pat = GEN_FCN (icode) (target, op0, op1, op2);
3632 if (!pat)
3633 return 0;
3634 emit_insn (pat);
3635 return target;
3636
3637 case ARM_BUILTIN_TINSRB:
3638 case ARM_BUILTIN_TINSRH:
3639 case ARM_BUILTIN_TINSRW:
3640 case ARM_BUILTIN_WMERGE:
3641 icode = (fcode == ARM_BUILTIN_TINSRB ? CODE_FOR_iwmmxt_tinsrb
3642 : fcode == ARM_BUILTIN_TINSRH ? CODE_FOR_iwmmxt_tinsrh
3643 : fcode == ARM_BUILTIN_WMERGE ? CODE_FOR_iwmmxt_wmerge
3644 : CODE_FOR_iwmmxt_tinsrw);
3645 arg0 = CALL_EXPR_ARG (exp, 0);
3646 arg1 = CALL_EXPR_ARG (exp, 1);
3647 arg2 = CALL_EXPR_ARG (exp, 2);
3648 op0 = expand_normal (arg0);
3649 op1 = expand_normal (arg1);
3650 op2 = expand_normal (arg2);
3651 tmode = insn_data[icode].operand[0].mode;
3652 mode0 = insn_data[icode].operand[1].mode;
3653 mode1 = insn_data[icode].operand[2].mode;
3654 mode2 = insn_data[icode].operand[3].mode;
3655
3656 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3657 op0 = copy_to_mode_reg (mode0, op0);
3658 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
3659 op1 = copy_to_mode_reg (mode1, op1);
3660 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
3661 {
3662 error ("selector must be an immediate");
3663 return const0_rtx;
3664 }
3665 if (icode == CODE_FOR_iwmmxt_wmerge)
3666 {
3667 selector = INTVAL (op2);
3668 if (selector > 7 || selector < 0)
3669 error ("the range of selector should be in 0 to 7");
3670 }
3671 if ((icode == CODE_FOR_iwmmxt_tinsrb)
3672 || (icode == CODE_FOR_iwmmxt_tinsrh)
3673 || (icode == CODE_FOR_iwmmxt_tinsrw))
3674 {
3675 mask = 0x01;
3676 selector= INTVAL (op2);
3677 if (icode == CODE_FOR_iwmmxt_tinsrb && (selector < 0 || selector > 7))
3678 error ("the range of selector should be in 0 to 7");
3679 else if (icode == CODE_FOR_iwmmxt_tinsrh && (selector < 0 ||selector > 3))
3680 error ("the range of selector should be in 0 to 3");
3681 else if (icode == CODE_FOR_iwmmxt_tinsrw && (selector < 0 ||selector > 1))
3682 error ("the range of selector should be in 0 to 1");
3683 mask <<= selector;
3684 op2 = GEN_INT (mask);
3685 }
3686 if (target == 0
3687 || GET_MODE (target) != tmode
3688 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3689 target = gen_reg_rtx (tmode);
3690 pat = GEN_FCN (icode) (target, op0, op1, op2);
3691 if (! pat)
3692 return 0;
3693 emit_insn (pat);
3694 return target;
3695
3696 case ARM_BUILTIN_SETWCGR0:
3697 case ARM_BUILTIN_SETWCGR1:
3698 case ARM_BUILTIN_SETWCGR2:
3699 case ARM_BUILTIN_SETWCGR3:
3700 icode = (fcode == ARM_BUILTIN_SETWCGR0 ? CODE_FOR_iwmmxt_setwcgr0
3701 : fcode == ARM_BUILTIN_SETWCGR1 ? CODE_FOR_iwmmxt_setwcgr1
3702 : fcode == ARM_BUILTIN_SETWCGR2 ? CODE_FOR_iwmmxt_setwcgr2
3703 : CODE_FOR_iwmmxt_setwcgr3);
3704 arg0 = CALL_EXPR_ARG (exp, 0);
3705 op0 = expand_normal (arg0);
3706 mode0 = insn_data[icode].operand[0].mode;
3707 if (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
3708 op0 = copy_to_mode_reg (mode0, op0);
3709 pat = GEN_FCN (icode) (op0);
3710 if (!pat)
3711 return 0;
3712 emit_insn (pat);
3713 return 0;
3714
3715 case ARM_BUILTIN_GETWCGR0:
3716 case ARM_BUILTIN_GETWCGR1:
3717 case ARM_BUILTIN_GETWCGR2:
3718 case ARM_BUILTIN_GETWCGR3:
3719 icode = (fcode == ARM_BUILTIN_GETWCGR0 ? CODE_FOR_iwmmxt_getwcgr0
3720 : fcode == ARM_BUILTIN_GETWCGR1 ? CODE_FOR_iwmmxt_getwcgr1
3721 : fcode == ARM_BUILTIN_GETWCGR2 ? CODE_FOR_iwmmxt_getwcgr2
3722 : CODE_FOR_iwmmxt_getwcgr3);
3723 tmode = insn_data[icode].operand[0].mode;
3724 if (target == 0
3725 || GET_MODE (target) != tmode
3726 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
3727 target = gen_reg_rtx (tmode);
3728 pat = GEN_FCN (icode) (target);
3729 if (!pat)
3730 return 0;
3731 emit_insn (pat);
3732 return target;
3733
3734 case ARM_BUILTIN_WSHUFH:
3735 icode = CODE_FOR_iwmmxt_wshufh;
3736 arg0 = CALL_EXPR_ARG (exp, 0);
3737 arg1 = CALL_EXPR_ARG (exp, 1);
3738 op0 = expand_normal (arg0);
3739 op1 = expand_normal (arg1);
3740 tmode = insn_data[icode].operand[0].mode;
3741 mode1 = insn_data[icode].operand[1].mode;
3742 mode2 = insn_data[icode].operand[2].mode;
3743
3744 if (! (*insn_data[icode].operand[1].predicate) (op0, mode1))
3745 op0 = copy_to_mode_reg (mode1, op0);
3746 if (! (*insn_data[icode].operand[2].predicate) (op1, mode2))
3747 {
3748 error ("mask must be an immediate");
3749 return const0_rtx;
3750 }
3751 selector = INTVAL (op1);
3752 if (selector < 0 || selector > 255)
3753 error ("the range of mask should be in 0 to 255");
3754 if (target == 0
3755 || GET_MODE (target) != tmode
3756 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3757 target = gen_reg_rtx (tmode);
3758 pat = GEN_FCN (icode) (target, op0, op1);
3759 if (! pat)
3760 return 0;
3761 emit_insn (pat);
3762 return target;
3763
3764 case ARM_BUILTIN_WMADDS:
3765 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmadds, exp, target);
3766 case ARM_BUILTIN_WMADDSX:
3767 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsx, exp, target);
3768 case ARM_BUILTIN_WMADDSN:
3769 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsn, exp, target);
3770 case ARM_BUILTIN_WMADDU:
3771 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddu, exp, target);
3772 case ARM_BUILTIN_WMADDUX:
3773 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddux, exp, target);
3774 case ARM_BUILTIN_WMADDUN:
3775 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddun, exp, target);
3776 case ARM_BUILTIN_WSADBZ:
3777 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz, exp, target);
3778 case ARM_BUILTIN_WSADHZ:
3779 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz, exp, target);
3780
3781 /* Several three-argument builtins. */
3782 case ARM_BUILTIN_WMACS:
3783 case ARM_BUILTIN_WMACU:
3784 case ARM_BUILTIN_TMIA:
3785 case ARM_BUILTIN_TMIAPH:
3786 case ARM_BUILTIN_TMIATT:
3787 case ARM_BUILTIN_TMIATB:
3788 case ARM_BUILTIN_TMIABT:
3789 case ARM_BUILTIN_TMIABB:
3790 case ARM_BUILTIN_WQMIABB:
3791 case ARM_BUILTIN_WQMIABT:
3792 case ARM_BUILTIN_WQMIATB:
3793 case ARM_BUILTIN_WQMIATT:
3794 case ARM_BUILTIN_WQMIABBN:
3795 case ARM_BUILTIN_WQMIABTN:
3796 case ARM_BUILTIN_WQMIATBN:
3797 case ARM_BUILTIN_WQMIATTN:
3798 case ARM_BUILTIN_WMIABB:
3799 case ARM_BUILTIN_WMIABT:
3800 case ARM_BUILTIN_WMIATB:
3801 case ARM_BUILTIN_WMIATT:
3802 case ARM_BUILTIN_WMIABBN:
3803 case ARM_BUILTIN_WMIABTN:
3804 case ARM_BUILTIN_WMIATBN:
3805 case ARM_BUILTIN_WMIATTN:
3806 case ARM_BUILTIN_WMIAWBB:
3807 case ARM_BUILTIN_WMIAWBT:
3808 case ARM_BUILTIN_WMIAWTB:
3809 case ARM_BUILTIN_WMIAWTT:
3810 case ARM_BUILTIN_WMIAWBBN:
3811 case ARM_BUILTIN_WMIAWBTN:
3812 case ARM_BUILTIN_WMIAWTBN:
3813 case ARM_BUILTIN_WMIAWTTN:
3814 case ARM_BUILTIN_WSADB:
3815 case ARM_BUILTIN_WSADH:
3816 icode = (fcode == ARM_BUILTIN_WMACS ? CODE_FOR_iwmmxt_wmacs
3817 : fcode == ARM_BUILTIN_WMACU ? CODE_FOR_iwmmxt_wmacu
3818 : fcode == ARM_BUILTIN_TMIA ? CODE_FOR_iwmmxt_tmia
3819 : fcode == ARM_BUILTIN_TMIAPH ? CODE_FOR_iwmmxt_tmiaph
3820 : fcode == ARM_BUILTIN_TMIABB ? CODE_FOR_iwmmxt_tmiabb
3821 : fcode == ARM_BUILTIN_TMIABT ? CODE_FOR_iwmmxt_tmiabt
3822 : fcode == ARM_BUILTIN_TMIATB ? CODE_FOR_iwmmxt_tmiatb
3823 : fcode == ARM_BUILTIN_TMIATT ? CODE_FOR_iwmmxt_tmiatt
3824 : fcode == ARM_BUILTIN_WQMIABB ? CODE_FOR_iwmmxt_wqmiabb
3825 : fcode == ARM_BUILTIN_WQMIABT ? CODE_FOR_iwmmxt_wqmiabt
3826 : fcode == ARM_BUILTIN_WQMIATB ? CODE_FOR_iwmmxt_wqmiatb
3827 : fcode == ARM_BUILTIN_WQMIATT ? CODE_FOR_iwmmxt_wqmiatt
3828 : fcode == ARM_BUILTIN_WQMIABBN ? CODE_FOR_iwmmxt_wqmiabbn
3829 : fcode == ARM_BUILTIN_WQMIABTN ? CODE_FOR_iwmmxt_wqmiabtn
3830 : fcode == ARM_BUILTIN_WQMIATBN ? CODE_FOR_iwmmxt_wqmiatbn
3831 : fcode == ARM_BUILTIN_WQMIATTN ? CODE_FOR_iwmmxt_wqmiattn
3832 : fcode == ARM_BUILTIN_WMIABB ? CODE_FOR_iwmmxt_wmiabb
3833 : fcode == ARM_BUILTIN_WMIABT ? CODE_FOR_iwmmxt_wmiabt
3834 : fcode == ARM_BUILTIN_WMIATB ? CODE_FOR_iwmmxt_wmiatb
3835 : fcode == ARM_BUILTIN_WMIATT ? CODE_FOR_iwmmxt_wmiatt
3836 : fcode == ARM_BUILTIN_WMIABBN ? CODE_FOR_iwmmxt_wmiabbn
3837 : fcode == ARM_BUILTIN_WMIABTN ? CODE_FOR_iwmmxt_wmiabtn
3838 : fcode == ARM_BUILTIN_WMIATBN ? CODE_FOR_iwmmxt_wmiatbn
3839 : fcode == ARM_BUILTIN_WMIATTN ? CODE_FOR_iwmmxt_wmiattn
3840 : fcode == ARM_BUILTIN_WMIAWBB ? CODE_FOR_iwmmxt_wmiawbb
3841 : fcode == ARM_BUILTIN_WMIAWBT ? CODE_FOR_iwmmxt_wmiawbt
3842 : fcode == ARM_BUILTIN_WMIAWTB ? CODE_FOR_iwmmxt_wmiawtb
3843 : fcode == ARM_BUILTIN_WMIAWTT ? CODE_FOR_iwmmxt_wmiawtt
3844 : fcode == ARM_BUILTIN_WMIAWBBN ? CODE_FOR_iwmmxt_wmiawbbn
3845 : fcode == ARM_BUILTIN_WMIAWBTN ? CODE_FOR_iwmmxt_wmiawbtn
3846 : fcode == ARM_BUILTIN_WMIAWTBN ? CODE_FOR_iwmmxt_wmiawtbn
3847 : fcode == ARM_BUILTIN_WMIAWTTN ? CODE_FOR_iwmmxt_wmiawttn
3848 : fcode == ARM_BUILTIN_WSADB ? CODE_FOR_iwmmxt_wsadb
3849 : CODE_FOR_iwmmxt_wsadh);
3850 arg0 = CALL_EXPR_ARG (exp, 0);
3851 arg1 = CALL_EXPR_ARG (exp, 1);
3852 arg2 = CALL_EXPR_ARG (exp, 2);
3853 op0 = expand_normal (arg0);
3854 op1 = expand_normal (arg1);
3855 op2 = expand_normal (arg2);
3856 tmode = insn_data[icode].operand[0].mode;
3857 mode0 = insn_data[icode].operand[1].mode;
3858 mode1 = insn_data[icode].operand[2].mode;
3859 mode2 = insn_data[icode].operand[3].mode;
3860
3861 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3862 op0 = copy_to_mode_reg (mode0, op0);
3863 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
3864 op1 = copy_to_mode_reg (mode1, op1);
3865 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
3866 op2 = copy_to_mode_reg (mode2, op2);
3867 if (target == 0
3868 || GET_MODE (target) != tmode
3869 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3870 target = gen_reg_rtx (tmode);
3871 pat = GEN_FCN (icode) (target, op0, op1, op2);
3872 if (! pat)
3873 return 0;
3874 emit_insn (pat);
3875 return target;
3876
3877 case ARM_BUILTIN_WZERO:
3878 target = gen_reg_rtx (DImode);
3879 emit_insn (gen_iwmmxt_clrdi (target));
3880 return target;
3881
3882 case ARM_BUILTIN_WSRLHI:
3883 case ARM_BUILTIN_WSRLWI:
3884 case ARM_BUILTIN_WSRLDI:
3885 case ARM_BUILTIN_WSLLHI:
3886 case ARM_BUILTIN_WSLLWI:
3887 case ARM_BUILTIN_WSLLDI:
3888 case ARM_BUILTIN_WSRAHI:
3889 case ARM_BUILTIN_WSRAWI:
3890 case ARM_BUILTIN_WSRADI:
3891 case ARM_BUILTIN_WRORHI:
3892 case ARM_BUILTIN_WRORWI:
3893 case ARM_BUILTIN_WRORDI:
3894 case ARM_BUILTIN_WSRLH:
3895 case ARM_BUILTIN_WSRLW:
3896 case ARM_BUILTIN_WSRLD:
3897 case ARM_BUILTIN_WSLLH:
3898 case ARM_BUILTIN_WSLLW:
3899 case ARM_BUILTIN_WSLLD:
3900 case ARM_BUILTIN_WSRAH:
3901 case ARM_BUILTIN_WSRAW:
3902 case ARM_BUILTIN_WSRAD:
3903 case ARM_BUILTIN_WRORH:
3904 case ARM_BUILTIN_WRORW:
3905 case ARM_BUILTIN_WRORD:
3906 icode = (fcode == ARM_BUILTIN_WSRLHI ? CODE_FOR_lshrv4hi3_iwmmxt
3907 : fcode == ARM_BUILTIN_WSRLWI ? CODE_FOR_lshrv2si3_iwmmxt
3908 : fcode == ARM_BUILTIN_WSRLDI ? CODE_FOR_lshrdi3_iwmmxt
3909 : fcode == ARM_BUILTIN_WSLLHI ? CODE_FOR_ashlv4hi3_iwmmxt
3910 : fcode == ARM_BUILTIN_WSLLWI ? CODE_FOR_ashlv2si3_iwmmxt
3911 : fcode == ARM_BUILTIN_WSLLDI ? CODE_FOR_ashldi3_iwmmxt
3912 : fcode == ARM_BUILTIN_WSRAHI ? CODE_FOR_ashrv4hi3_iwmmxt
3913 : fcode == ARM_BUILTIN_WSRAWI ? CODE_FOR_ashrv2si3_iwmmxt
3914 : fcode == ARM_BUILTIN_WSRADI ? CODE_FOR_ashrdi3_iwmmxt
3915 : fcode == ARM_BUILTIN_WRORHI ? CODE_FOR_rorv4hi3
3916 : fcode == ARM_BUILTIN_WRORWI ? CODE_FOR_rorv2si3
3917 : fcode == ARM_BUILTIN_WRORDI ? CODE_FOR_rordi3
3918 : fcode == ARM_BUILTIN_WSRLH ? CODE_FOR_lshrv4hi3_di
3919 : fcode == ARM_BUILTIN_WSRLW ? CODE_FOR_lshrv2si3_di
3920 : fcode == ARM_BUILTIN_WSRLD ? CODE_FOR_lshrdi3_di
3921 : fcode == ARM_BUILTIN_WSLLH ? CODE_FOR_ashlv4hi3_di
3922 : fcode == ARM_BUILTIN_WSLLW ? CODE_FOR_ashlv2si3_di
3923 : fcode == ARM_BUILTIN_WSLLD ? CODE_FOR_ashldi3_di
3924 : fcode == ARM_BUILTIN_WSRAH ? CODE_FOR_ashrv4hi3_di
3925 : fcode == ARM_BUILTIN_WSRAW ? CODE_FOR_ashrv2si3_di
3926 : fcode == ARM_BUILTIN_WSRAD ? CODE_FOR_ashrdi3_di
3927 : fcode == ARM_BUILTIN_WRORH ? CODE_FOR_rorv4hi3_di
3928 : fcode == ARM_BUILTIN_WRORW ? CODE_FOR_rorv2si3_di
3929 : fcode == ARM_BUILTIN_WRORD ? CODE_FOR_rordi3_di
3930 : CODE_FOR_nothing);
3931 arg1 = CALL_EXPR_ARG (exp, 1);
3932 op1 = expand_normal (arg1);
3933 if (GET_MODE (op1) == VOIDmode)
3934 {
3935 imm = INTVAL (op1);
3936 if ((fcode == ARM_BUILTIN_WRORHI || fcode == ARM_BUILTIN_WRORWI
3937 || fcode == ARM_BUILTIN_WRORH || fcode == ARM_BUILTIN_WRORW)
3938 && (imm < 0 || imm > 32))
3939 {
3940 if (fcode == ARM_BUILTIN_WRORHI)
3941 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi16 in code.");
3942 else if (fcode == ARM_BUILTIN_WRORWI)
3943 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi32 in code.");
3944 else if (fcode == ARM_BUILTIN_WRORH)
3945 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi16 in code.");
3946 else
3947 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi32 in code.");
3948 }
3949 else if ((fcode == ARM_BUILTIN_WRORDI || fcode == ARM_BUILTIN_WRORD)
3950 && (imm < 0 || imm > 64))
3951 {
3952 if (fcode == ARM_BUILTIN_WRORDI)
3953 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_rori_si64 in code.");
3954 else
3955 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_ror_si64 in code.");
3956 }
3957 else if (imm < 0)
3958 {
3959 if (fcode == ARM_BUILTIN_WSRLHI)
3960 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi16 in code.");
3961 else if (fcode == ARM_BUILTIN_WSRLWI)
3962 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi32 in code.");
3963 else if (fcode == ARM_BUILTIN_WSRLDI)
3964 error ("the count should be no less than 0. please check the intrinsic _mm_srli_si64 in code.");
3965 else if (fcode == ARM_BUILTIN_WSLLHI)
3966 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi16 in code.");
3967 else if (fcode == ARM_BUILTIN_WSLLWI)
3968 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi32 in code.");
3969 else if (fcode == ARM_BUILTIN_WSLLDI)
3970 error ("the count should be no less than 0. please check the intrinsic _mm_slli_si64 in code.");
3971 else if (fcode == ARM_BUILTIN_WSRAHI)
3972 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi16 in code.");
3973 else if (fcode == ARM_BUILTIN_WSRAWI)
3974 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi32 in code.");
3975 else if (fcode == ARM_BUILTIN_WSRADI)
3976 error ("the count should be no less than 0. please check the intrinsic _mm_srai_si64 in code.");
3977 else if (fcode == ARM_BUILTIN_WSRLH)
3978 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi16 in code.");
3979 else if (fcode == ARM_BUILTIN_WSRLW)
3980 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi32 in code.");
3981 else if (fcode == ARM_BUILTIN_WSRLD)
3982 error ("the count should be no less than 0. please check the intrinsic _mm_srl_si64 in code.");
3983 else if (fcode == ARM_BUILTIN_WSLLH)
3984 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi16 in code.");
3985 else if (fcode == ARM_BUILTIN_WSLLW)
3986 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi32 in code.");
3987 else if (fcode == ARM_BUILTIN_WSLLD)
3988 error ("the count should be no less than 0. please check the intrinsic _mm_sll_si64 in code.");
3989 else if (fcode == ARM_BUILTIN_WSRAH)
3990 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi16 in code.");
3991 else if (fcode == ARM_BUILTIN_WSRAW)
3992 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi32 in code.");
3993 else
3994 error ("the count should be no less than 0. please check the intrinsic _mm_sra_si64 in code.");
3995 }
3996 }
3997 return arm_expand_binop_builtin (icode, exp, target);
3998
3999 default:
4000 break;
4001 }
4002
4003 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
064263c1 4004 if (d->code == (enum arm_builtins) fcode)
33857df2
JG
4005 return arm_expand_binop_builtin (d->icode, exp, target);
4006
4007 for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
064263c1 4008 if (d->code == (enum arm_builtins) fcode)
33857df2
JG
4009 return arm_expand_unop_builtin (d->icode, exp, target, 0);
4010
4011 for (i = 0, d = bdesc_3arg; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
064263c1 4012 if (d->code == (enum arm_builtins) fcode)
33857df2
JG
4013 return arm_expand_ternop_builtin (d->icode, exp, target);
4014
4015 /* @@@ Should really do something sensible here. */
4016 return NULL_RTX;
4017}
4018
4019tree
10766209 4020arm_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in)
33857df2
JG
4021{
4022 machine_mode in_mode, out_mode;
4023 int in_n, out_n;
4024 bool out_unsigned_p = TYPE_UNSIGNED (type_out);
4025
4f83064e
KT
4026 /* Can't provide any vectorized builtins when we can't use NEON. */
4027 if (!TARGET_NEON)
4028 return NULL_TREE;
4029
33857df2
JG
4030 if (TREE_CODE (type_out) != VECTOR_TYPE
4031 || TREE_CODE (type_in) != VECTOR_TYPE)
4032 return NULL_TREE;
4033
4034 out_mode = TYPE_MODE (TREE_TYPE (type_out));
4035 out_n = TYPE_VECTOR_SUBPARTS (type_out);
4036 in_mode = TYPE_MODE (TREE_TYPE (type_in));
4037 in_n = TYPE_VECTOR_SUBPARTS (type_in);
4038
4039/* ARM_CHECK_BUILTIN_MODE and ARM_FIND_VRINT_VARIANT are used to find the
4040 decl of the vectorized builtin for the appropriate vector mode.
4041 NULL_TREE is returned if no such builtin is available. */
4042#undef ARM_CHECK_BUILTIN_MODE
4043#define ARM_CHECK_BUILTIN_MODE(C) \
c8d61ab8 4044 (TARGET_VFP5 \
33857df2
JG
4045 && flag_unsafe_math_optimizations \
4046 && ARM_CHECK_BUILTIN_MODE_1 (C))
4047
4048#undef ARM_CHECK_BUILTIN_MODE_1
4049#define ARM_CHECK_BUILTIN_MODE_1(C) \
4050 (out_mode == SFmode && out_n == C \
4051 && in_mode == SFmode && in_n == C)
4052
4053#undef ARM_FIND_VRINT_VARIANT
4054#define ARM_FIND_VRINT_VARIANT(N) \
4055 (ARM_CHECK_BUILTIN_MODE (2) \
4056 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sf, false) \
4057 : (ARM_CHECK_BUILTIN_MODE (4) \
4058 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sf, false) \
4059 : NULL_TREE))
4060
10766209 4061 switch (fn)
33857df2 4062 {
10766209
RS
4063 CASE_CFN_FLOOR:
4064 return ARM_FIND_VRINT_VARIANT (vrintm);
4065 CASE_CFN_CEIL:
4066 return ARM_FIND_VRINT_VARIANT (vrintp);
4067 CASE_CFN_TRUNC:
4068 return ARM_FIND_VRINT_VARIANT (vrintz);
4069 CASE_CFN_ROUND:
4070 return ARM_FIND_VRINT_VARIANT (vrinta);
33857df2
JG
4071#undef ARM_CHECK_BUILTIN_MODE_1
4072#define ARM_CHECK_BUILTIN_MODE_1(C) \
4073 (out_mode == SImode && out_n == C \
4074 && in_mode == SFmode && in_n == C)
4075
4076#define ARM_FIND_VCVT_VARIANT(N) \
4077 (ARM_CHECK_BUILTIN_MODE (2) \
4078 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sfv2si, false) \
4079 : (ARM_CHECK_BUILTIN_MODE (4) \
4080 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sfv4si, false) \
4081 : NULL_TREE))
4082
4083#define ARM_FIND_VCVTU_VARIANT(N) \
4084 (ARM_CHECK_BUILTIN_MODE (2) \
4085 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv2sfv2si, false) \
4086 : (ARM_CHECK_BUILTIN_MODE (4) \
4087 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv4sfv4si, false) \
4088 : NULL_TREE))
10766209
RS
4089 CASE_CFN_LROUND:
4090 return (out_unsigned_p
4091 ? ARM_FIND_VCVTU_VARIANT (vcvta)
4092 : ARM_FIND_VCVT_VARIANT (vcvta));
4093 CASE_CFN_LCEIL:
4094 return (out_unsigned_p
4095 ? ARM_FIND_VCVTU_VARIANT (vcvtp)
4096 : ARM_FIND_VCVT_VARIANT (vcvtp));
4097 CASE_CFN_LFLOOR:
4098 return (out_unsigned_p
4099 ? ARM_FIND_VCVTU_VARIANT (vcvtm)
4100 : ARM_FIND_VCVT_VARIANT (vcvtm));
33857df2
JG
4101#undef ARM_CHECK_BUILTIN_MODE
4102#define ARM_CHECK_BUILTIN_MODE(C, N) \
4103 (out_mode == N##mode && out_n == C \
4104 && in_mode == N##mode && in_n == C)
10766209
RS
4105 case CFN_BUILT_IN_BSWAP16:
4106 if (ARM_CHECK_BUILTIN_MODE (4, HI))
4107 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4hi, false);
4108 else if (ARM_CHECK_BUILTIN_MODE (8, HI))
4109 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv8hi, false);
4110 else
4111 return NULL_TREE;
4112 case CFN_BUILT_IN_BSWAP32:
4113 if (ARM_CHECK_BUILTIN_MODE (2, SI))
4114 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2si, false);
4115 else if (ARM_CHECK_BUILTIN_MODE (4, SI))
4116 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4si, false);
4117 else
4118 return NULL_TREE;
4119 case CFN_BUILT_IN_BSWAP64:
4120 if (ARM_CHECK_BUILTIN_MODE (2, DI))
4121 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2di, false);
4122 else
4123 return NULL_TREE;
4124 CASE_CFN_COPYSIGN:
4125 if (ARM_CHECK_BUILTIN_MODE (2, SF))
4126 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv2sf, false);
4127 else if (ARM_CHECK_BUILTIN_MODE (4, SF))
4128 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv4sf, false);
4129 else
4130 return NULL_TREE;
4131
4132 default:
4133 return NULL_TREE;
33857df2
JG
4134 }
4135 return NULL_TREE;
4136}
4137#undef ARM_FIND_VCVT_VARIANT
4138#undef ARM_FIND_VCVTU_VARIANT
4139#undef ARM_CHECK_BUILTIN_MODE
4140#undef ARM_FIND_VRINT_VARIANT
4141
4142void
4143arm_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
4144{
4145 const unsigned ARM_FE_INVALID = 1;
4146 const unsigned ARM_FE_DIVBYZERO = 2;
4147 const unsigned ARM_FE_OVERFLOW = 4;
4148 const unsigned ARM_FE_UNDERFLOW = 8;
4149 const unsigned ARM_FE_INEXACT = 16;
4150 const unsigned HOST_WIDE_INT ARM_FE_ALL_EXCEPT = (ARM_FE_INVALID
4151 | ARM_FE_DIVBYZERO
4152 | ARM_FE_OVERFLOW
4153 | ARM_FE_UNDERFLOW
4154 | ARM_FE_INEXACT);
4155 const unsigned HOST_WIDE_INT ARM_FE_EXCEPT_SHIFT = 8;
4156 tree fenv_var, get_fpscr, set_fpscr, mask, ld_fenv, masked_fenv;
4157 tree new_fenv_var, reload_fenv, restore_fnenv;
4158 tree update_call, atomic_feraiseexcept, hold_fnclex;
4159
00ea1506 4160 if (!TARGET_HARD_FLOAT)
33857df2
JG
4161 return;
4162
4163 /* Generate the equivalent of :
4164 unsigned int fenv_var;
4165 fenv_var = __builtin_arm_get_fpscr ();
4166
4167 unsigned int masked_fenv;
4168 masked_fenv = fenv_var & mask;
4169
4170 __builtin_arm_set_fpscr (masked_fenv); */
4171
baba8d7d 4172 fenv_var = create_tmp_var_raw (unsigned_type_node);
33857df2
JG
4173 get_fpscr = arm_builtin_decls[ARM_BUILTIN_GET_FPSCR];
4174 set_fpscr = arm_builtin_decls[ARM_BUILTIN_SET_FPSCR];
4175 mask = build_int_cst (unsigned_type_node,
4176 ~((ARM_FE_ALL_EXCEPT << ARM_FE_EXCEPT_SHIFT)
4177 | ARM_FE_ALL_EXCEPT));
1d7ead9c
RS
4178 ld_fenv = build4 (TARGET_EXPR, unsigned_type_node,
4179 fenv_var, build_call_expr (get_fpscr, 0),
4180 NULL_TREE, NULL_TREE);
33857df2
JG
4181 masked_fenv = build2 (BIT_AND_EXPR, unsigned_type_node, fenv_var, mask);
4182 hold_fnclex = build_call_expr (set_fpscr, 1, masked_fenv);
4183 *hold = build2 (COMPOUND_EXPR, void_type_node,
4184 build2 (COMPOUND_EXPR, void_type_node, masked_fenv, ld_fenv),
4185 hold_fnclex);
4186
4187 /* Store the value of masked_fenv to clear the exceptions:
4188 __builtin_arm_set_fpscr (masked_fenv); */
4189
4190 *clear = build_call_expr (set_fpscr, 1, masked_fenv);
4191
4192 /* Generate the equivalent of :
4193 unsigned int new_fenv_var;
4194 new_fenv_var = __builtin_arm_get_fpscr ();
4195
4196 __builtin_arm_set_fpscr (fenv_var);
4197
4198 __atomic_feraiseexcept (new_fenv_var); */
4199
baba8d7d 4200 new_fenv_var = create_tmp_var_raw (unsigned_type_node);
1d7ead9c
RS
4201 reload_fenv = build4 (TARGET_EXPR, unsigned_type_node, new_fenv_var,
4202 build_call_expr (get_fpscr, 0), NULL_TREE, NULL_TREE);
33857df2
JG
4203 restore_fnenv = build_call_expr (set_fpscr, 1, fenv_var);
4204 atomic_feraiseexcept = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
4205 update_call = build_call_expr (atomic_feraiseexcept, 1,
4206 fold_convert (integer_type_node, new_fenv_var));
4207 *update = build2 (COMPOUND_EXPR, void_type_node,
4208 build2 (COMPOUND_EXPR, void_type_node,
4209 reload_fenv, restore_fnenv), update_call);
4210}
4211
cf16f980
KT
4212/* Implement TARGET_CHECK_BUILTIN_CALL. Record a read of the Q bit through
4213 intrinsics in the machine function. */
4214bool
4215arm_check_builtin_call (location_t , vec<location_t> , tree fndecl,
4216 tree, unsigned int, tree *)
4217{
4218 int fcode = DECL_MD_FUNCTION_CODE (fndecl);
4219 if (fcode == ARM_BUILTIN_saturation_occurred
4220 || fcode == ARM_BUILTIN_set_saturation)
4221 {
4222 if (cfun && cfun->decl)
4223 DECL_ATTRIBUTES (cfun->decl)
4224 = tree_cons (get_identifier ("acle qbit"), NULL_TREE,
4225 DECL_ATTRIBUTES (cfun->decl));
4226 }
16155ccf
KT
4227 if (fcode == ARM_BUILTIN_sel)
4228 {
4229 if (cfun && cfun->decl)
4230 DECL_ATTRIBUTES (cfun->decl)
4231 = tree_cons (get_identifier ("acle gebits"), NULL_TREE,
4232 DECL_ATTRIBUTES (cfun->decl));
4233 }
cf16f980
KT
4234 return true;
4235}
4236
ef684c78
MM
4237enum resolver_ident
4238arm_describe_resolver (tree fndecl)
78bf9163 4239{
ef684c78
MM
4240 if (DECL_MD_FUNCTION_CODE (fndecl) >= ARM_BUILTIN_vcx1qv16qi
4241 && DECL_MD_FUNCTION_CODE (fndecl) < ARM_BUILTIN_MVE_BASE)
4242 return arm_cde_resolver;
4243 return arm_no_resolver;
4244}
78bf9163 4245
ef684c78
MM
4246unsigned
4247arm_cde_end_args (tree fndecl)
4248{
4249 return DECL_MD_FUNCTION_CODE (fndecl) >= ARM_BUILTIN_vcx1q_p_v16qi ? 2 : 1;
78bf9163
MM
4250}
4251
33857df2 4252#include "gt-arm-builtins.h"