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