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