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