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