]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm-builtins.c
[1/77] Add an E_ prefix to mode names
[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"
9ea846c4 30#include "profile-count.h"
c1eb80de 31#include "optabs.h"
32#include "emit-rtl.h"
33#include "recog.h"
34#include "diagnostic-core.h"
b20a8bb4 35#include "fold-const.h"
d6504d76 36#include "stor-layout.h"
d53441c8 37#include "explow.h"
d6504d76 38#include "expr.h"
d6504d76 39#include "langhooks.h"
b6c464fe 40#include "case-cfn-macros.h"
b1af3254 41#include "sbitmap.h"
d6504d76 42
1be6395a 43#define SIMD_MAX_BUILTIN_ARGS 7
c5f2b407 44
45enum arm_type_qualifiers
46{
47 /* T foo. */
48 qualifier_none = 0x0,
49 /* unsigned T foo. */
50 qualifier_unsigned = 0x1, /* 1 << 0 */
51 /* const T foo. */
52 qualifier_const = 0x2, /* 1 << 1 */
53 /* T *foo. */
54 qualifier_pointer = 0x4, /* 1 << 2 */
638b44bd 55 /* const T * foo. */
56 qualifier_const_pointer = 0x6,
c5f2b407 57 /* Used when expanding arguments if an operand could
58 be an immediate. */
59 qualifier_immediate = 0x8, /* 1 << 3 */
1be6395a 60 qualifier_unsigned_immediate = 0x9,
c5f2b407 61 qualifier_maybe_immediate = 0x10, /* 1 << 4 */
62 /* void foo (...). */
63 qualifier_void = 0x20, /* 1 << 5 */
64 /* Some patterns may have internal operands, this qualifier is an
65 instruction to the initialisation code to skip this operand. */
66 qualifier_internal = 0x40, /* 1 << 6 */
67 /* Some builtins should use the T_*mode* encoded in a simd_builtin_datum
68 rather than using the type of the operand. */
69 qualifier_map_mode = 0x80, /* 1 << 7 */
70 /* qualifier_pointer | qualifier_map_mode */
71 qualifier_pointer_map_mode = 0x84,
72 /* qualifier_const_pointer | qualifier_map_mode */
73 qualifier_const_pointer_map_mode = 0x86,
74 /* Polynomial types. */
505e1f91 75 qualifier_poly = 0x100,
76 /* Lane indices - must be within range of previous argument = a vector. */
d4023b2c 77 qualifier_lane_index = 0x200,
78 /* Lane indices for single lane structure loads and stores. */
79 qualifier_struct_load_store_lane_index = 0x400
c5f2b407 80};
81
82/* The qualifier_internal allows generation of a unary builtin from
83 a pattern with a third pseudo-operand such as a match_scratch.
84 T (T). */
85static enum arm_type_qualifiers
86arm_unop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
87 = { qualifier_none, qualifier_none, qualifier_internal };
c5f2b407 88#define UNOP_QUALIFIERS (arm_unop_qualifiers)
89
90/* unsigned T (unsigned T). */
91static enum arm_type_qualifiers
92arm_bswap_qualifiers[SIMD_MAX_BUILTIN_ARGS]
93 = { qualifier_unsigned, qualifier_unsigned };
94#define BSWAP_QUALIFIERS (arm_bswap_qualifiers)
95
96/* T (T, T [maybe_immediate]). */
97static enum arm_type_qualifiers
98arm_binop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
99 = { qualifier_none, qualifier_none, qualifier_maybe_immediate };
100#define BINOP_QUALIFIERS (arm_binop_qualifiers)
c5f2b407 101
102/* T (T, T, T). */
103static enum arm_type_qualifiers
104arm_ternop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
105 = { qualifier_none, qualifier_none, qualifier_none, qualifier_none };
106#define TERNOP_QUALIFIERS (arm_ternop_qualifiers)
c5f2b407 107
108/* T (T, immediate). */
109static enum arm_type_qualifiers
505e1f91 110arm_binop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
c5f2b407 111 = { qualifier_none, qualifier_none, qualifier_immediate };
505e1f91 112#define BINOP_IMM_QUALIFIERS (arm_binop_imm_qualifiers)
113
114/* T (T, lane index). */
115static enum arm_type_qualifiers
116arm_getlane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
117 = { qualifier_none, qualifier_none, qualifier_lane_index };
c5f2b407 118#define GETLANE_QUALIFIERS (arm_getlane_qualifiers)
c5f2b407 119
120/* T (T, T, T, immediate). */
121static enum arm_type_qualifiers
505e1f91 122arm_mac_n_qualifiers[SIMD_MAX_BUILTIN_ARGS]
c5f2b407 123 = { qualifier_none, qualifier_none, qualifier_none,
124 qualifier_none, qualifier_immediate };
505e1f91 125#define MAC_N_QUALIFIERS (arm_mac_n_qualifiers)
126
127/* T (T, T, T, lane index). */
128static enum arm_type_qualifiers
129arm_mac_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
130 = { qualifier_none, qualifier_none, qualifier_none,
131 qualifier_none, qualifier_lane_index };
132#define MAC_LANE_QUALIFIERS (arm_mac_lane_qualifiers)
c5f2b407 133
134/* T (T, T, immediate). */
135static enum arm_type_qualifiers
505e1f91 136arm_ternop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
c5f2b407 137 = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate };
505e1f91 138#define TERNOP_IMM_QUALIFIERS (arm_ternop_imm_qualifiers)
139
140/* T (T, T, lane index). */
141static enum arm_type_qualifiers
142arm_setlane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
143 = { qualifier_none, qualifier_none, qualifier_none, qualifier_lane_index };
c5f2b407 144#define SETLANE_QUALIFIERS (arm_setlane_qualifiers)
c5f2b407 145
146/* T (T, T). */
147static enum arm_type_qualifiers
148arm_combine_qualifiers[SIMD_MAX_BUILTIN_ARGS]
149 = { qualifier_none, qualifier_none, qualifier_none };
150#define COMBINE_QUALIFIERS (arm_combine_qualifiers)
c5f2b407 151
152/* T ([T element type] *). */
153static enum arm_type_qualifiers
154arm_load1_qualifiers[SIMD_MAX_BUILTIN_ARGS]
155 = { qualifier_none, qualifier_const_pointer_map_mode };
156#define LOAD1_QUALIFIERS (arm_load1_qualifiers)
c5f2b407 157
158/* T ([T element type] *, T, immediate). */
159static enum arm_type_qualifiers
160arm_load1_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
161 = { qualifier_none, qualifier_const_pointer_map_mode,
fe8542d5 162 qualifier_none, qualifier_struct_load_store_lane_index };
c5f2b407 163#define LOAD1LANE_QUALIFIERS (arm_load1_lane_qualifiers)
c5f2b407 164
f6bc04f8 165/* unsigned T (unsigned T, unsigned T, unsigned T). */
166static enum arm_type_qualifiers
167arm_unsigned_binop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
168 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
169 qualifier_unsigned };
170#define UBINOP_QUALIFIERS (arm_unsigned_binop_qualifiers)
171
1be6395a 172/* void (unsigned immediate, unsigned immediate, unsigned immediate,
173 unsigned immediate, unsigned immediate, unsigned immediate). */
174static enum arm_type_qualifiers
175arm_cdp_qualifiers[SIMD_MAX_BUILTIN_ARGS]
176 = { qualifier_void, qualifier_unsigned_immediate,
177 qualifier_unsigned_immediate,
178 qualifier_unsigned_immediate,
179 qualifier_unsigned_immediate,
180 qualifier_unsigned_immediate,
181 qualifier_unsigned_immediate };
182#define CDP_QUALIFIERS \
183 (arm_cdp_qualifiers)
638b44bd 184
185/* void (unsigned immediate, unsigned immediate, const void *). */
186static enum arm_type_qualifiers
187arm_ldc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
188 = { qualifier_void, qualifier_unsigned_immediate,
189 qualifier_unsigned_immediate, qualifier_const_pointer };
190#define LDC_QUALIFIERS \
191 (arm_ldc_qualifiers)
192
193/* void (unsigned immediate, unsigned immediate, void *). */
194static enum arm_type_qualifiers
195arm_stc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
196 = { qualifier_void, qualifier_unsigned_immediate,
197 qualifier_unsigned_immediate, qualifier_pointer };
198#define STC_QUALIFIERS \
199 (arm_stc_qualifiers)
200
415e9b1f 201/* void (unsigned immediate, unsigned immediate, T, unsigned immediate,
202 unsigned immediate, unsigned immediate). */
203static enum arm_type_qualifiers
204arm_mcr_qualifiers[SIMD_MAX_BUILTIN_ARGS]
205 = { qualifier_void, qualifier_unsigned_immediate,
206 qualifier_unsigned_immediate, qualifier_none,
207 qualifier_unsigned_immediate, qualifier_unsigned_immediate,
208 qualifier_unsigned_immediate };
209#define MCR_QUALIFIERS \
210 (arm_mcr_qualifiers)
211
212/* T (unsigned immediate, unsigned immediate, unsigned immediate,
213 unsigned immediate, unsigned immediate). */
214static enum arm_type_qualifiers
215arm_mrc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
216 = { qualifier_none, qualifier_unsigned_immediate,
217 qualifier_unsigned_immediate, qualifier_unsigned_immediate,
218 qualifier_unsigned_immediate, qualifier_unsigned_immediate };
219#define MRC_QUALIFIERS \
220 (arm_mrc_qualifiers)
cabfd710 221
222/* void (unsigned immediate, unsigned immediate, T, unsigned immediate). */
223static enum arm_type_qualifiers
224arm_mcrr_qualifiers[SIMD_MAX_BUILTIN_ARGS]
225 = { qualifier_void, qualifier_unsigned_immediate,
226 qualifier_unsigned_immediate, qualifier_none,
227 qualifier_unsigned_immediate };
228#define MCRR_QUALIFIERS \
229 (arm_mcrr_qualifiers)
230
231/* T (unsigned immediate, unsigned immediate, unsigned immediate). */
232static enum arm_type_qualifiers
233arm_mrrc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
234 = { qualifier_none, qualifier_unsigned_immediate,
235 qualifier_unsigned_immediate, qualifier_unsigned_immediate };
236#define MRRC_QUALIFIERS \
237 (arm_mrrc_qualifiers)
238
c5f2b407 239/* The first argument (return type) of a store should be void type,
240 which we represent with qualifier_void. Their first operand will be
241 a DImode pointer to the location to store to, so we must use
242 qualifier_map_mode | qualifier_pointer to build a pointer to the
243 element type of the vector.
244
245 void ([T element type] *, T). */
246static enum arm_type_qualifiers
247arm_store1_qualifiers[SIMD_MAX_BUILTIN_ARGS]
248 = { qualifier_void, qualifier_pointer_map_mode, qualifier_none };
249#define STORE1_QUALIFIERS (arm_store1_qualifiers)
c5f2b407 250
251 /* void ([T element type] *, T, immediate). */
252static enum arm_type_qualifiers
253arm_storestruct_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
254 = { qualifier_void, qualifier_pointer_map_mode,
fe8542d5 255 qualifier_none, qualifier_struct_load_store_lane_index };
c5f2b407 256#define STORE1LANE_QUALIFIERS (arm_storestruct_lane_qualifiers)
c5f2b407 257
1e0295b9 258#define v8qi_UP E_V8QImode
259#define v4hi_UP E_V4HImode
260#define v4hf_UP E_V4HFmode
261#define v2si_UP E_V2SImode
262#define v2sf_UP E_V2SFmode
263#define di_UP E_DImode
264#define v16qi_UP E_V16QImode
265#define v8hi_UP E_V8HImode
266#define v8hf_UP E_V8HFmode
267#define v4si_UP E_V4SImode
268#define v4sf_UP E_V4SFmode
269#define v2di_UP E_V2DImode
270#define ti_UP E_TImode
271#define ei_UP E_EImode
272#define oi_UP E_OImode
273#define hf_UP E_HFmode
274#define si_UP E_SImode
275#define void_UP E_VOIDmode
d6504d76 276
277#define UP(X) X##_UP
278
d6504d76 279typedef struct {
280 const char *name;
c7796b7e 281 machine_mode mode;
d6504d76 282 const enum insn_code code;
283 unsigned int fcode;
c5f2b407 284 enum arm_type_qualifiers *qualifiers;
286c4ff9 285} arm_builtin_datum;
d6504d76 286
287#define CF(N,X) CODE_FOR_neon_##N##X
288
289#define VAR1(T, N, A) \
c7796b7e 290 {#N #A, UP (A), CF (N, A), 0, T##_QUALIFIERS},
d6504d76 291#define VAR2(T, N, A, B) \
e0b44776 292 VAR1 (T, N, A) \
293 VAR1 (T, N, B)
d6504d76 294#define VAR3(T, N, A, B, C) \
e0b44776 295 VAR2 (T, N, A, B) \
296 VAR1 (T, N, C)
d6504d76 297#define VAR4(T, N, A, B, C, D) \
e0b44776 298 VAR3 (T, N, A, B, C) \
299 VAR1 (T, N, D)
d6504d76 300#define VAR5(T, N, A, B, C, D, E) \
e0b44776 301 VAR4 (T, N, A, B, C, D) \
302 VAR1 (T, N, E)
d6504d76 303#define VAR6(T, N, A, B, C, D, E, F) \
e0b44776 304 VAR5 (T, N, A, B, C, D, E) \
305 VAR1 (T, N, F)
d6504d76 306#define VAR7(T, N, A, B, C, D, E, F, G) \
e0b44776 307 VAR6 (T, N, A, B, C, D, E, F) \
308 VAR1 (T, N, G)
d6504d76 309#define VAR8(T, N, A, B, C, D, E, F, G, H) \
e0b44776 310 VAR7 (T, N, A, B, C, D, E, F, G) \
311 VAR1 (T, N, H)
d6504d76 312#define VAR9(T, N, A, B, C, D, E, F, G, H, I) \
e0b44776 313 VAR8 (T, N, A, B, C, D, E, F, G, H) \
314 VAR1 (T, N, I)
d6504d76 315#define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \
e0b44776 316 VAR9 (T, N, A, B, C, D, E, F, G, H, I) \
317 VAR1 (T, N, J)
fb5f110d 318#define VAR11(T, N, A, B, C, D, E, F, G, H, I, J, K) \
319 VAR10 (T, N, A, B, C, D, E, F, G, H, I, J) \
320 VAR1 (T, N, K)
321#define VAR12(T, N, A, B, C, D, E, F, G, H, I, J, K, L) \
322 VAR11 (T, N, A, B, C, D, E, F, G, H, I, J, K) \
323 VAR1 (T, N, L)
d6504d76 324
f6bc04f8 325/* The builtin data can be found in arm_neon_builtins.def, arm_vfp_builtins.def
326 and arm_acle_builtins.def. The entries in arm_neon_builtins.def require
327 TARGET_NEON to be true. The feature tests are checked when the builtins are
328 expanded.
03d12d86 329
f6bc04f8 330 The mode entries in the following table correspond to the "key" type of the
331 instruction variant, i.e. equivalent to that which would be specified after
332 the assembler mnemonic for neon instructions, which usually refers to the
333 last vector operand. The modes listed per instruction should be the same as
334 those defined for that instruction's pattern, for instance in neon.md. */
03d12d86 335
286c4ff9 336static arm_builtin_datum vfp_builtin_data[] =
03d12d86 337{
338#include "arm_vfp_builtins.def"
339};
d6504d76 340
286c4ff9 341static arm_builtin_datum neon_builtin_data[] =
d6504d76 342{
343#include "arm_neon_builtins.def"
344};
345
346#undef CF
f6bc04f8 347#undef VAR1
348#define VAR1(T, N, A) \
349 {#N, UP (A), CODE_FOR_##N, 0, T##_QUALIFIERS},
350
351static arm_builtin_datum acle_builtin_data[] =
352{
353#include "arm_acle_builtins.def"
354};
355
d6504d76 356#undef VAR1
d6504d76 357
e0b44776 358#define VAR1(T, N, X) \
359 ARM_BUILTIN_NEON_##N##X,
360
d6504d76 361enum arm_builtins
362{
363 ARM_BUILTIN_GETWCGR0,
364 ARM_BUILTIN_GETWCGR1,
365 ARM_BUILTIN_GETWCGR2,
366 ARM_BUILTIN_GETWCGR3,
367
368 ARM_BUILTIN_SETWCGR0,
369 ARM_BUILTIN_SETWCGR1,
370 ARM_BUILTIN_SETWCGR2,
371 ARM_BUILTIN_SETWCGR3,
372
373 ARM_BUILTIN_WZERO,
374
375 ARM_BUILTIN_WAVG2BR,
376 ARM_BUILTIN_WAVG2HR,
377 ARM_BUILTIN_WAVG2B,
378 ARM_BUILTIN_WAVG2H,
379
380 ARM_BUILTIN_WACCB,
381 ARM_BUILTIN_WACCH,
382 ARM_BUILTIN_WACCW,
383
384 ARM_BUILTIN_WMACS,
385 ARM_BUILTIN_WMACSZ,
386 ARM_BUILTIN_WMACU,
387 ARM_BUILTIN_WMACUZ,
388
389 ARM_BUILTIN_WSADB,
390 ARM_BUILTIN_WSADBZ,
391 ARM_BUILTIN_WSADH,
392 ARM_BUILTIN_WSADHZ,
393
394 ARM_BUILTIN_WALIGNI,
395 ARM_BUILTIN_WALIGNR0,
396 ARM_BUILTIN_WALIGNR1,
397 ARM_BUILTIN_WALIGNR2,
398 ARM_BUILTIN_WALIGNR3,
399
400 ARM_BUILTIN_TMIA,
401 ARM_BUILTIN_TMIAPH,
402 ARM_BUILTIN_TMIABB,
403 ARM_BUILTIN_TMIABT,
404 ARM_BUILTIN_TMIATB,
405 ARM_BUILTIN_TMIATT,
406
407 ARM_BUILTIN_TMOVMSKB,
408 ARM_BUILTIN_TMOVMSKH,
409 ARM_BUILTIN_TMOVMSKW,
410
411 ARM_BUILTIN_TBCSTB,
412 ARM_BUILTIN_TBCSTH,
413 ARM_BUILTIN_TBCSTW,
414
415 ARM_BUILTIN_WMADDS,
416 ARM_BUILTIN_WMADDU,
417
418 ARM_BUILTIN_WPACKHSS,
419 ARM_BUILTIN_WPACKWSS,
420 ARM_BUILTIN_WPACKDSS,
421 ARM_BUILTIN_WPACKHUS,
422 ARM_BUILTIN_WPACKWUS,
423 ARM_BUILTIN_WPACKDUS,
424
425 ARM_BUILTIN_WADDB,
426 ARM_BUILTIN_WADDH,
427 ARM_BUILTIN_WADDW,
428 ARM_BUILTIN_WADDSSB,
429 ARM_BUILTIN_WADDSSH,
430 ARM_BUILTIN_WADDSSW,
431 ARM_BUILTIN_WADDUSB,
432 ARM_BUILTIN_WADDUSH,
433 ARM_BUILTIN_WADDUSW,
434 ARM_BUILTIN_WSUBB,
435 ARM_BUILTIN_WSUBH,
436 ARM_BUILTIN_WSUBW,
437 ARM_BUILTIN_WSUBSSB,
438 ARM_BUILTIN_WSUBSSH,
439 ARM_BUILTIN_WSUBSSW,
440 ARM_BUILTIN_WSUBUSB,
441 ARM_BUILTIN_WSUBUSH,
442 ARM_BUILTIN_WSUBUSW,
443
444 ARM_BUILTIN_WAND,
445 ARM_BUILTIN_WANDN,
446 ARM_BUILTIN_WOR,
447 ARM_BUILTIN_WXOR,
448
449 ARM_BUILTIN_WCMPEQB,
450 ARM_BUILTIN_WCMPEQH,
451 ARM_BUILTIN_WCMPEQW,
452 ARM_BUILTIN_WCMPGTUB,
453 ARM_BUILTIN_WCMPGTUH,
454 ARM_BUILTIN_WCMPGTUW,
455 ARM_BUILTIN_WCMPGTSB,
456 ARM_BUILTIN_WCMPGTSH,
457 ARM_BUILTIN_WCMPGTSW,
458
459 ARM_BUILTIN_TEXTRMSB,
460 ARM_BUILTIN_TEXTRMSH,
461 ARM_BUILTIN_TEXTRMSW,
462 ARM_BUILTIN_TEXTRMUB,
463 ARM_BUILTIN_TEXTRMUH,
464 ARM_BUILTIN_TEXTRMUW,
465 ARM_BUILTIN_TINSRB,
466 ARM_BUILTIN_TINSRH,
467 ARM_BUILTIN_TINSRW,
468
469 ARM_BUILTIN_WMAXSW,
470 ARM_BUILTIN_WMAXSH,
471 ARM_BUILTIN_WMAXSB,
472 ARM_BUILTIN_WMAXUW,
473 ARM_BUILTIN_WMAXUH,
474 ARM_BUILTIN_WMAXUB,
475 ARM_BUILTIN_WMINSW,
476 ARM_BUILTIN_WMINSH,
477 ARM_BUILTIN_WMINSB,
478 ARM_BUILTIN_WMINUW,
479 ARM_BUILTIN_WMINUH,
480 ARM_BUILTIN_WMINUB,
481
482 ARM_BUILTIN_WMULUM,
483 ARM_BUILTIN_WMULSM,
484 ARM_BUILTIN_WMULUL,
485
486 ARM_BUILTIN_PSADBH,
487 ARM_BUILTIN_WSHUFH,
488
489 ARM_BUILTIN_WSLLH,
490 ARM_BUILTIN_WSLLW,
491 ARM_BUILTIN_WSLLD,
492 ARM_BUILTIN_WSRAH,
493 ARM_BUILTIN_WSRAW,
494 ARM_BUILTIN_WSRAD,
495 ARM_BUILTIN_WSRLH,
496 ARM_BUILTIN_WSRLW,
497 ARM_BUILTIN_WSRLD,
498 ARM_BUILTIN_WRORH,
499 ARM_BUILTIN_WRORW,
500 ARM_BUILTIN_WRORD,
501 ARM_BUILTIN_WSLLHI,
502 ARM_BUILTIN_WSLLWI,
503 ARM_BUILTIN_WSLLDI,
504 ARM_BUILTIN_WSRAHI,
505 ARM_BUILTIN_WSRAWI,
506 ARM_BUILTIN_WSRADI,
507 ARM_BUILTIN_WSRLHI,
508 ARM_BUILTIN_WSRLWI,
509 ARM_BUILTIN_WSRLDI,
510 ARM_BUILTIN_WRORHI,
511 ARM_BUILTIN_WRORWI,
512 ARM_BUILTIN_WRORDI,
513
514 ARM_BUILTIN_WUNPCKIHB,
515 ARM_BUILTIN_WUNPCKIHH,
516 ARM_BUILTIN_WUNPCKIHW,
517 ARM_BUILTIN_WUNPCKILB,
518 ARM_BUILTIN_WUNPCKILH,
519 ARM_BUILTIN_WUNPCKILW,
520
521 ARM_BUILTIN_WUNPCKEHSB,
522 ARM_BUILTIN_WUNPCKEHSH,
523 ARM_BUILTIN_WUNPCKEHSW,
524 ARM_BUILTIN_WUNPCKEHUB,
525 ARM_BUILTIN_WUNPCKEHUH,
526 ARM_BUILTIN_WUNPCKEHUW,
527 ARM_BUILTIN_WUNPCKELSB,
528 ARM_BUILTIN_WUNPCKELSH,
529 ARM_BUILTIN_WUNPCKELSW,
530 ARM_BUILTIN_WUNPCKELUB,
531 ARM_BUILTIN_WUNPCKELUH,
532 ARM_BUILTIN_WUNPCKELUW,
533
534 ARM_BUILTIN_WABSB,
535 ARM_BUILTIN_WABSH,
536 ARM_BUILTIN_WABSW,
537
538 ARM_BUILTIN_WADDSUBHX,
539 ARM_BUILTIN_WSUBADDHX,
540
541 ARM_BUILTIN_WABSDIFFB,
542 ARM_BUILTIN_WABSDIFFH,
543 ARM_BUILTIN_WABSDIFFW,
544
545 ARM_BUILTIN_WADDCH,
546 ARM_BUILTIN_WADDCW,
547
548 ARM_BUILTIN_WAVG4,
549 ARM_BUILTIN_WAVG4R,
550
551 ARM_BUILTIN_WMADDSX,
552 ARM_BUILTIN_WMADDUX,
553
554 ARM_BUILTIN_WMADDSN,
555 ARM_BUILTIN_WMADDUN,
556
557 ARM_BUILTIN_WMULWSM,
558 ARM_BUILTIN_WMULWUM,
559
560 ARM_BUILTIN_WMULWSMR,
561 ARM_BUILTIN_WMULWUMR,
562
563 ARM_BUILTIN_WMULWL,
564
565 ARM_BUILTIN_WMULSMR,
566 ARM_BUILTIN_WMULUMR,
567
568 ARM_BUILTIN_WQMULM,
569 ARM_BUILTIN_WQMULMR,
570
571 ARM_BUILTIN_WQMULWM,
572 ARM_BUILTIN_WQMULWMR,
573
574 ARM_BUILTIN_WADDBHUSM,
575 ARM_BUILTIN_WADDBHUSL,
576
577 ARM_BUILTIN_WQMIABB,
578 ARM_BUILTIN_WQMIABT,
579 ARM_BUILTIN_WQMIATB,
580 ARM_BUILTIN_WQMIATT,
581
582 ARM_BUILTIN_WQMIABBN,
583 ARM_BUILTIN_WQMIABTN,
584 ARM_BUILTIN_WQMIATBN,
585 ARM_BUILTIN_WQMIATTN,
586
587 ARM_BUILTIN_WMIABB,
588 ARM_BUILTIN_WMIABT,
589 ARM_BUILTIN_WMIATB,
590 ARM_BUILTIN_WMIATT,
591
592 ARM_BUILTIN_WMIABBN,
593 ARM_BUILTIN_WMIABTN,
594 ARM_BUILTIN_WMIATBN,
595 ARM_BUILTIN_WMIATTN,
596
597 ARM_BUILTIN_WMIAWBB,
598 ARM_BUILTIN_WMIAWBT,
599 ARM_BUILTIN_WMIAWTB,
600 ARM_BUILTIN_WMIAWTT,
601
602 ARM_BUILTIN_WMIAWBBN,
603 ARM_BUILTIN_WMIAWBTN,
604 ARM_BUILTIN_WMIAWTBN,
605 ARM_BUILTIN_WMIAWTTN,
606
607 ARM_BUILTIN_WMERGE,
608
d6504d76 609 ARM_BUILTIN_GET_FPSCR,
610 ARM_BUILTIN_SET_FPSCR,
611
cd5e2b04 612 ARM_BUILTIN_CMSE_NONSECURE_CALLER,
613
d6504d76 614#undef CRYPTO1
615#undef CRYPTO2
616#undef CRYPTO3
617
618#define CRYPTO1(L, U, M1, M2) \
619 ARM_BUILTIN_CRYPTO_##U,
620#define CRYPTO2(L, U, M1, M2, M3) \
621 ARM_BUILTIN_CRYPTO_##U,
622#define CRYPTO3(L, U, M1, M2, M3, M4) \
623 ARM_BUILTIN_CRYPTO_##U,
624
86eff91f 625 ARM_BUILTIN_CRYPTO_BASE,
626
d6504d76 627#include "crypto.def"
628
629#undef CRYPTO1
630#undef CRYPTO2
631#undef CRYPTO3
632
03d12d86 633 ARM_BUILTIN_VFP_BASE,
634
635#include "arm_vfp_builtins.def"
636
732205bc 637 ARM_BUILTIN_NEON_BASE,
638 ARM_BUILTIN_NEON_LANE_CHECK = ARM_BUILTIN_NEON_BASE,
639
d6504d76 640#include "arm_neon_builtins.def"
641
f6bc04f8 642#undef VAR1
643#define VAR1(T, N, X) \
644 ARM_BUILTIN_##N,
645
646 ARM_BUILTIN_ACLE_BASE,
647
648#include "arm_acle_builtins.def"
649
e0b44776 650 ARM_BUILTIN_MAX
d6504d76 651};
652
03d12d86 653#define ARM_BUILTIN_VFP_PATTERN_START \
654 (ARM_BUILTIN_VFP_BASE + 1)
655
732205bc 656#define ARM_BUILTIN_NEON_PATTERN_START \
3d586c7e 657 (ARM_BUILTIN_NEON_BASE + 1)
d6504d76 658
f6bc04f8 659#define ARM_BUILTIN_ACLE_PATTERN_START \
660 (ARM_BUILTIN_ACLE_BASE + 1)
661
d6504d76 662#undef CF
663#undef VAR1
664#undef VAR2
665#undef VAR3
666#undef VAR4
667#undef VAR5
668#undef VAR6
669#undef VAR7
670#undef VAR8
671#undef VAR9
672#undef VAR10
673
674static GTY(()) tree arm_builtin_decls[ARM_BUILTIN_MAX];
675
676#define NUM_DREG_TYPES 5
677#define NUM_QREG_TYPES 6
678
6612f298 679/* Internal scalar builtin types. These types are used to support
680 neon intrinsic builtins. They are _not_ user-visible types. Therefore
681 the mangling for these types are implementation defined. */
682const char *arm_scalar_builtin_types[] = {
683 "__builtin_neon_qi",
684 "__builtin_neon_hi",
685 "__builtin_neon_si",
686 "__builtin_neon_sf",
687 "__builtin_neon_di",
688 "__builtin_neon_df",
689 "__builtin_neon_ti",
690 "__builtin_neon_uqi",
691 "__builtin_neon_uhi",
692 "__builtin_neon_usi",
693 "__builtin_neon_udi",
694 "__builtin_neon_ei",
695 "__builtin_neon_oi",
696 "__builtin_neon_ci",
697 "__builtin_neon_xi",
698 NULL
699};
700
701#define ENTRY(E, M, Q, S, T, G) E,
702enum arm_simd_type
703{
704#include "arm-simd-builtin-types.def"
705 __TYPE_FINAL
706};
707#undef ENTRY
708
709struct arm_simd_type_info
710{
711 enum arm_simd_type type;
712
713 /* Internal type name. */
714 const char *name;
715
716 /* Internal type name(mangled). The mangled names conform to the
717 AAPCS (see "Procedure Call Standard for the ARM Architecture",
718 Appendix A). To qualify for emission with the mangled names defined in
719 that document, a vector type must not only be of the correct mode but also
720 be of the correct internal Neon vector type (e.g. __simd64_int8_t);
721 these types are registered by arm_init_simd_builtin_types (). In other
722 words, vector types defined in other ways e.g. via vector_size attribute
723 will get default mangled names. */
724 const char *mangle;
725
726 /* Internal type. */
727 tree itype;
728
729 /* Element type. */
730 tree eltype;
731
732 /* Machine mode the internal type maps to. */
733 machine_mode mode;
734
735 /* Qualifiers. */
736 enum arm_type_qualifiers q;
737};
738
739#define ENTRY(E, M, Q, S, T, G) \
740 {E, \
741 "__simd" #S "_" #T "_t", \
742 #G "__simd" #S "_" #T "_t", \
743 NULL_TREE, NULL_TREE, M##mode, qualifier_##Q},
744static struct arm_simd_type_info arm_simd_types [] = {
745#include "arm-simd-builtin-types.def"
746};
747#undef ENTRY
748
ee1f2deb 749/* The user-visible __fp16 type. */
750tree arm_fp16_type_node = NULL_TREE;
6612f298 751static tree arm_simd_intOI_type_node = NULL_TREE;
752static tree arm_simd_intEI_type_node = NULL_TREE;
753static tree arm_simd_intCI_type_node = NULL_TREE;
754static tree arm_simd_intXI_type_node = NULL_TREE;
755static tree arm_simd_polyQI_type_node = NULL_TREE;
756static tree arm_simd_polyHI_type_node = NULL_TREE;
757static tree arm_simd_polyDI_type_node = NULL_TREE;
758static tree arm_simd_polyTI_type_node = NULL_TREE;
759
760static const char *
761arm_mangle_builtin_scalar_type (const_tree type)
762{
763 int i = 0;
764
765 while (arm_scalar_builtin_types[i] != NULL)
766 {
767 const char *name = arm_scalar_builtin_types[i];
768
769 if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
770 && DECL_NAME (TYPE_NAME (type))
771 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))), name))
772 return arm_scalar_builtin_types[i];
773 i++;
774 }
775 return NULL;
776}
777
778static const char *
779arm_mangle_builtin_vector_type (const_tree type)
780{
781 int i;
782 int nelts = sizeof (arm_simd_types) / sizeof (arm_simd_types[0]);
783
784 for (i = 0; i < nelts; i++)
785 if (arm_simd_types[i].mode == TYPE_MODE (type)
786 && TYPE_NAME (type)
787 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
788 && DECL_NAME (TYPE_NAME (type))
789 && !strcmp
790 (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
791 arm_simd_types[i].name))
792 return arm_simd_types[i].mangle;
793
794 return NULL;
795}
796
797const char *
798arm_mangle_builtin_type (const_tree type)
799{
800 const char *mangle;
801 /* Walk through all the AArch64 builtins types tables to filter out the
802 incoming type. */
803 if ((mangle = arm_mangle_builtin_vector_type (type))
804 || (mangle = arm_mangle_builtin_scalar_type (type)))
805 return mangle;
806
807 return NULL;
808}
809
810static tree
582adad1 811arm_simd_builtin_std_type (machine_mode mode,
6612f298 812 enum arm_type_qualifiers q)
813{
814#define QUAL_TYPE(M) \
815 ((q == qualifier_none) ? int##M##_type_node : unsigned_int##M##_type_node);
816 switch (mode)
817 {
818 case QImode:
819 return QUAL_TYPE (QI);
820 case HImode:
821 return QUAL_TYPE (HI);
822 case SImode:
823 return QUAL_TYPE (SI);
824 case DImode:
825 return QUAL_TYPE (DI);
826 case TImode:
827 return QUAL_TYPE (TI);
828 case OImode:
829 return arm_simd_intOI_type_node;
830 case EImode:
831 return arm_simd_intEI_type_node;
832 case CImode:
833 return arm_simd_intCI_type_node;
834 case XImode:
835 return arm_simd_intXI_type_node;
836 case HFmode:
ee1f2deb 837 return arm_fp16_type_node;
6612f298 838 case SFmode:
839 return float_type_node;
840 case DFmode:
841 return double_type_node;
842 default:
843 gcc_unreachable ();
844 }
845#undef QUAL_TYPE
846}
847
848static tree
582adad1 849arm_lookup_simd_builtin_type (machine_mode mode,
6612f298 850 enum arm_type_qualifiers q)
851{
852 int i;
853 int nelts = sizeof (arm_simd_types) / sizeof (arm_simd_types[0]);
854
855 /* Non-poly scalar modes map to standard types not in the table. */
856 if (q != qualifier_poly && !VECTOR_MODE_P (mode))
857 return arm_simd_builtin_std_type (mode, q);
858
859 for (i = 0; i < nelts; i++)
860 if (arm_simd_types[i].mode == mode
861 && arm_simd_types[i].q == q)
862 return arm_simd_types[i].itype;
863
864 /* Note that we won't have caught the underlying type for poly64x2_t
865 in the above table. This gets default mangling. */
866
867 return NULL_TREE;
868}
869
870static tree
582adad1 871arm_simd_builtin_type (machine_mode mode, bool unsigned_p, bool poly_p)
6612f298 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;
582adad1 945 machine_mode mode = arm_simd_types[i].mode;
6612f298 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
c1c9b4d4 1879 if (TARGET_MAYBE_HARD_FLOAT)
86eff91f 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
c1c9b4d4 1888 if (TARGET_MAYBE_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 {
582adad1 2235 machine_mode vmode = mode[argc - 1];
505e1f91 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);
586c8c8e 2248 /* We have failed to expand the pattern, and are safely
2249 in to invalid code. But the mid-end will still try to
2250 build an assignment for this node while it expands,
2251 before stopping for the error, just pass it back
2252 TARGET to ensure a valid assignment. */
2253 return target;
d4023b2c 2254 }
c7796b7e 2255 break;
d4023b2c 2256
286c4ff9 2257 case ARG_BUILTIN_NEON_MEMORY:
d6504d76 2258 /* Check if expand failed. */
2259 if (op[argc] == const0_rtx)
2260 return 0;
2261 gcc_assert (MEM_P (op[argc]));
2262 PUT_MODE (op[argc], mode[argc]);
2263 /* ??? arm_neon.h uses the same built-in functions for signed
2264 and unsigned accesses, casting where necessary. This isn't
2265 alias safe. */
2266 set_mem_alias_set (op[argc], 0);
2267 if (!(*insn_data[icode].operand[opno].predicate)
c7796b7e 2268 (op[argc], mode[argc]))
d6504d76 2269 op[argc] = (replace_equiv_address
0eb4264c 2270 (op[argc],
2271 copy_to_mode_reg (Pmode, XEXP (op[argc], 0))));
d6504d76 2272 break;
2273
286c4ff9 2274 case ARG_BUILTIN_STOP:
c7796b7e 2275 gcc_unreachable ();
2276 }
d6504d76 2277
c7796b7e 2278 argc++;
2279 }
d6504d76 2280 }
2281
d6504d76 2282 if (have_retval)
2283 switch (argc)
2284 {
2285 case 1:
2286 pat = GEN_FCN (icode) (target, op[0]);
2287 break;
2288
2289 case 2:
2290 pat = GEN_FCN (icode) (target, op[0], op[1]);
2291 break;
2292
2293 case 3:
2294 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
2295 break;
2296
2297 case 4:
2298 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
2299 break;
2300
2301 case 5:
2302 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4]);
2303 break;
2304
1be6395a 2305 case 6:
2306 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4], op[5]);
2307 break;
2308
d6504d76 2309 default:
2310 gcc_unreachable ();
2311 }
2312 else
2313 switch (argc)
2314 {
2315 case 1:
2316 pat = GEN_FCN (icode) (op[0]);
2317 break;
2318
2319 case 2:
2320 pat = GEN_FCN (icode) (op[0], op[1]);
2321 break;
2322
2323 case 3:
2324 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
2325 break;
2326
2327 case 4:
2328 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
2329 break;
2330
2331 case 5:
2332 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
c7796b7e 2333 break;
d6504d76 2334
1be6395a 2335 case 6:
2336 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]);
2337 break;
2338
d6504d76 2339 default:
2340 gcc_unreachable ();
2341 }
2342
2343 if (!pat)
2344 return 0;
2345
f6bc04f8 2346 /* Check whether our current target implements the pattern chosen for this
2347 builtin and error out if not. */
2348 start_sequence ();
d6504d76 2349 emit_insn (pat);
f6bc04f8 2350 insn = get_insns ();
2351 end_sequence ();
2352
2353 if (recog_memoized (insn) < 0)
2354 error ("this builtin is not supported for this target");
2355 else
2356 emit_insn (insn);
d6504d76 2357
2358 return target;
2359}
2360
286c4ff9 2361/* Expand a builtin. These builtins are "special" because they don't have
2362 symbolic constants defined per-instruction or per instruction-variant.
2363 Instead, the required info is looked up in the ARM_BUILTIN_DATA record that
2364 is passed into the function. */
3d586c7e 2365
d6504d76 2366static rtx
286c4ff9 2367arm_expand_builtin_1 (int fcode, tree exp, rtx target,
2368 arm_builtin_datum *d)
d6504d76 2369{
d6504d76 2370 enum insn_code icode = d->code;
47c0bea3 2371 builtin_arg args[SIMD_MAX_BUILTIN_ARGS + 1];
c7796b7e 2372 int num_args = insn_data[d->code].n_operands;
2373 int is_void = 0;
2374 int k;
286c4ff9 2375 bool neon = false;
2376
f6bc04f8 2377 if (IN_RANGE (fcode, ARM_BUILTIN_VFP_BASE, ARM_BUILTIN_ACLE_BASE - 1))
286c4ff9 2378 neon = true;
c7796b7e 2379
2380 is_void = !!(d->qualifiers[0] & qualifier_void);
d6504d76 2381
c7796b7e 2382 num_args += is_void;
2383
2384 for (k = 1; k < num_args; k++)
d6504d76 2385 {
c7796b7e 2386 /* We have four arrays of data, each indexed in a different fashion.
2387 qualifiers - element 0 always describes the function return type.
2388 operands - element 0 is either the operand for return value (if
3d586c7e 2389 the function has a non-void return type) or the operand for the
2390 first argument.
c7796b7e 2391 expr_args - element 0 always holds the first argument.
2392 args - element 0 is always used for the return type. */
2393 int qualifiers_k = k;
2394 int operands_k = k - is_void;
2395 int expr_args_k = k - 1;
2396
505e1f91 2397 if (d->qualifiers[qualifiers_k] & qualifier_lane_index)
286c4ff9 2398 args[k] = ARG_BUILTIN_LANE_INDEX;
d4023b2c 2399 else if (d->qualifiers[qualifiers_k] & qualifier_struct_load_store_lane_index)
286c4ff9 2400 args[k] = ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX;
505e1f91 2401 else if (d->qualifiers[qualifiers_k] & qualifier_immediate)
286c4ff9 2402 args[k] = ARG_BUILTIN_CONSTANT;
c7796b7e 2403 else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate)
2404 {
2405 rtx arg
2406 = expand_normal (CALL_EXPR_ARG (exp,
2407 (expr_args_k)));
2408 /* Handle constants only if the predicate allows it. */
2409 bool op_const_int_p =
2410 (CONST_INT_P (arg)
2411 && (*insn_data[icode].operand[operands_k].predicate)
3d586c7e 2412 (arg, insn_data[icode].operand[operands_k].mode));
286c4ff9 2413 args[k] = op_const_int_p ? ARG_BUILTIN_CONSTANT : ARG_BUILTIN_COPY_TO_REG;
c7796b7e 2414 }
2415 else if (d->qualifiers[qualifiers_k] & qualifier_pointer)
286c4ff9 2416 {
2417 if (neon)
2418 args[k] = ARG_BUILTIN_NEON_MEMORY;
2419 else
2420 args[k] = ARG_BUILTIN_MEMORY;
2421 }
c7796b7e 2422 else
286c4ff9 2423 args[k] = ARG_BUILTIN_COPY_TO_REG;
d6504d76 2424 }
286c4ff9 2425 args[k] = ARG_BUILTIN_STOP;
c7796b7e 2426
286c4ff9 2427 /* The interface to arm_expand_builtin_args expects a 0 if
c7796b7e 2428 the function is void, and a 1 if it is not. */
286c4ff9 2429 return arm_expand_builtin_args
3d586c7e 2430 (target, d->mode, fcode, icode, !is_void, exp,
2431 &args[1]);
2432}
2433
f6bc04f8 2434/* Expand an ACLE builtin, i.e. those registered only if their respective
2435 target constraints are met. This check happens within
2436 arm_expand_builtin_args. */
2437
2438static rtx
2439arm_expand_acle_builtin (int fcode, tree exp, rtx target)
2440{
2441
2442 arm_builtin_datum *d
2443 = &acle_builtin_data[fcode - ARM_BUILTIN_ACLE_PATTERN_START];
2444
2445 return arm_expand_builtin_1 (fcode, exp, target, d);
2446}
2447
3d586c7e 2448/* Expand a Neon builtin, i.e. those registered only if TARGET_NEON holds.
2449 Most of these are "special" because they don't have symbolic
2450 constants defined per-instruction or per instruction-variant. Instead, the
2451 required info is looked up in the table neon_builtin_data. */
2452
2453static rtx
2454arm_expand_neon_builtin (int fcode, tree exp, rtx target)
2455{
2456 if (fcode >= ARM_BUILTIN_NEON_BASE && ! TARGET_NEON)
2457 {
2458 fatal_error (input_location,
2459 "You must enable NEON instructions"
2460 " (e.g. -mfloat-abi=softfp -mfpu=neon)"
2461 " to use these intrinsics.");
2462 return const0_rtx;
2463 }
2464
2465 if (fcode == ARM_BUILTIN_NEON_LANE_CHECK)
2466 {
2467 /* Builtin is only to check bounds of the lane passed to some intrinsics
2468 that are implemented with gcc vector extensions in arm_neon.h. */
2469
2470 tree nlanes = CALL_EXPR_ARG (exp, 0);
2471 gcc_assert (TREE_CODE (nlanes) == INTEGER_CST);
2472 rtx lane_idx = expand_normal (CALL_EXPR_ARG (exp, 1));
2473 if (CONST_INT_P (lane_idx))
2474 neon_lane_bounds (lane_idx, 0, TREE_INT_CST_LOW (nlanes), exp);
2475 else
2476 error ("%Klane index must be a constant immediate", exp);
2477 /* Don't generate any RTL. */
2478 return const0_rtx;
2479 }
2480
286c4ff9 2481 arm_builtin_datum *d
3d586c7e 2482 = &neon_builtin_data[fcode - ARM_BUILTIN_NEON_PATTERN_START];
2483
286c4ff9 2484 return arm_expand_builtin_1 (fcode, exp, target, d);
d6504d76 2485}
2486
d7216193 2487/* Expand a VFP builtin. These builtins are treated like
03d12d86 2488 neon builtins except that the data is looked up in table
2489 VFP_BUILTIN_DATA. */
2490
2491static rtx
2492arm_expand_vfp_builtin (int fcode, tree exp, rtx target)
2493{
d7216193 2494 if (fcode >= ARM_BUILTIN_VFP_BASE && ! TARGET_HARD_FLOAT)
03d12d86 2495 {
2496 fatal_error (input_location,
2497 "You must enable VFP instructions"
2498 " to use these intrinsics.");
2499 return const0_rtx;
2500 }
2501
286c4ff9 2502 arm_builtin_datum *d
03d12d86 2503 = &vfp_builtin_data[fcode - ARM_BUILTIN_VFP_PATTERN_START];
2504
286c4ff9 2505 return arm_expand_builtin_1 (fcode, exp, target, d);
03d12d86 2506}
2507
d6504d76 2508/* Expand an expression EXP that calls a built-in function,
2509 with result going to TARGET if that's convenient
2510 (and in mode MODE if that's convenient).
2511 SUBTARGET may be used as the target for computing one of EXP's operands.
2512 IGNORE is nonzero if the value is to be ignored. */
2513
2514rtx
2515arm_expand_builtin (tree exp,
2516 rtx target,
2517 rtx subtarget ATTRIBUTE_UNUSED,
2518 machine_mode mode ATTRIBUTE_UNUSED,
2519 int ignore ATTRIBUTE_UNUSED)
2520{
2521 const struct builtin_description * d;
2522 enum insn_code icode;
2523 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2524 tree arg0;
2525 tree arg1;
2526 tree arg2;
2527 rtx op0;
2528 rtx op1;
2529 rtx op2;
2530 rtx pat;
2531 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
2532 size_t i;
2533 machine_mode tmode;
2534 machine_mode mode0;
2535 machine_mode mode1;
2536 machine_mode mode2;
2537 int opint;
2538 int selector;
2539 int mask;
2540 int imm;
2541
f6bc04f8 2542 if (fcode >= ARM_BUILTIN_ACLE_BASE)
2543 return arm_expand_acle_builtin (fcode, exp, target);
2544
d6504d76 2545 if (fcode >= ARM_BUILTIN_NEON_BASE)
2546 return arm_expand_neon_builtin (fcode, exp, target);
2547
03d12d86 2548 if (fcode >= ARM_BUILTIN_VFP_BASE)
2549 return arm_expand_vfp_builtin (fcode, exp, target);
2550
86eff91f 2551 /* Check in the context of the function making the call whether the
2552 builtin is supported. */
2553 if (fcode >= ARM_BUILTIN_CRYPTO_BASE
2554 && (!TARGET_CRYPTO || !TARGET_HARD_FLOAT))
2555 {
2556 fatal_error (input_location,
03d12d86 2557 "You must enable crypto instructions"
2558 " (e.g. include -mfloat-abi=softfp -mfpu=crypto-neon...)"
2559 " to use these intrinsics.");
86eff91f 2560 return const0_rtx;
2561 }
2562
d6504d76 2563 switch (fcode)
2564 {
2565 case ARM_BUILTIN_GET_FPSCR:
2566 case ARM_BUILTIN_SET_FPSCR:
2567 if (fcode == ARM_BUILTIN_GET_FPSCR)
2568 {
2569 icode = CODE_FOR_get_fpscr;
2570 target = gen_reg_rtx (SImode);
2571 pat = GEN_FCN (icode) (target);
2572 }
2573 else
2574 {
2575 target = NULL_RTX;
2576 icode = CODE_FOR_set_fpscr;
2577 arg0 = CALL_EXPR_ARG (exp, 0);
2578 op0 = expand_normal (arg0);
2579 pat = GEN_FCN (icode) (op0);
2580 }
2581 emit_insn (pat);
2582 return target;
2583
cd5e2b04 2584 case ARM_BUILTIN_CMSE_NONSECURE_CALLER:
2585 target = gen_reg_rtx (SImode);
2586 op0 = arm_return_addr (0, NULL_RTX);
2587 emit_insn (gen_addsi3 (target, op0, const1_rtx));
2588 return target;
2589
d6504d76 2590 case ARM_BUILTIN_TEXTRMSB:
2591 case ARM_BUILTIN_TEXTRMUB:
2592 case ARM_BUILTIN_TEXTRMSH:
2593 case ARM_BUILTIN_TEXTRMUH:
2594 case ARM_BUILTIN_TEXTRMSW:
2595 case ARM_BUILTIN_TEXTRMUW:
2596 icode = (fcode == ARM_BUILTIN_TEXTRMSB ? CODE_FOR_iwmmxt_textrmsb
2597 : fcode == ARM_BUILTIN_TEXTRMUB ? CODE_FOR_iwmmxt_textrmub
2598 : fcode == ARM_BUILTIN_TEXTRMSH ? CODE_FOR_iwmmxt_textrmsh
2599 : fcode == ARM_BUILTIN_TEXTRMUH ? CODE_FOR_iwmmxt_textrmuh
2600 : CODE_FOR_iwmmxt_textrmw);
2601
2602 arg0 = CALL_EXPR_ARG (exp, 0);
2603 arg1 = CALL_EXPR_ARG (exp, 1);
2604 op0 = expand_normal (arg0);
2605 op1 = expand_normal (arg1);
2606 tmode = insn_data[icode].operand[0].mode;
2607 mode0 = insn_data[icode].operand[1].mode;
2608 mode1 = insn_data[icode].operand[2].mode;
2609
2610 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2611 op0 = copy_to_mode_reg (mode0, op0);
2612 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
2613 {
2614 /* @@@ better error message */
2615 error ("selector must be an immediate");
2616 return gen_reg_rtx (tmode);
2617 }
2618
2619 opint = INTVAL (op1);
2620 if (fcode == ARM_BUILTIN_TEXTRMSB || fcode == ARM_BUILTIN_TEXTRMUB)
2621 {
2622 if (opint > 7 || opint < 0)
2623 error ("the range of selector should be in 0 to 7");
2624 }
2625 else if (fcode == ARM_BUILTIN_TEXTRMSH || fcode == ARM_BUILTIN_TEXTRMUH)
2626 {
2627 if (opint > 3 || opint < 0)
2628 error ("the range of selector should be in 0 to 3");
2629 }
2630 else /* ARM_BUILTIN_TEXTRMSW || ARM_BUILTIN_TEXTRMUW. */
2631 {
2632 if (opint > 1 || opint < 0)
2633 error ("the range of selector should be in 0 to 1");
2634 }
2635
2636 if (target == 0
2637 || GET_MODE (target) != tmode
2638 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2639 target = gen_reg_rtx (tmode);
2640 pat = GEN_FCN (icode) (target, op0, op1);
2641 if (! pat)
2642 return 0;
2643 emit_insn (pat);
2644 return target;
2645
2646 case ARM_BUILTIN_WALIGNI:
2647 /* If op2 is immediate, call walighi, else call walighr. */
2648 arg0 = CALL_EXPR_ARG (exp, 0);
2649 arg1 = CALL_EXPR_ARG (exp, 1);
2650 arg2 = CALL_EXPR_ARG (exp, 2);
2651 op0 = expand_normal (arg0);
2652 op1 = expand_normal (arg1);
2653 op2 = expand_normal (arg2);
2654 if (CONST_INT_P (op2))
2655 {
2656 icode = CODE_FOR_iwmmxt_waligni;
2657 tmode = insn_data[icode].operand[0].mode;
2658 mode0 = insn_data[icode].operand[1].mode;
2659 mode1 = insn_data[icode].operand[2].mode;
2660 mode2 = insn_data[icode].operand[3].mode;
2661 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
2662 op0 = copy_to_mode_reg (mode0, op0);
2663 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
2664 op1 = copy_to_mode_reg (mode1, op1);
2665 gcc_assert ((*insn_data[icode].operand[3].predicate) (op2, mode2));
2666 selector = INTVAL (op2);
2667 if (selector > 7 || selector < 0)
2668 error ("the range of selector should be in 0 to 7");
2669 }
2670 else
2671 {
2672 icode = CODE_FOR_iwmmxt_walignr;
2673 tmode = insn_data[icode].operand[0].mode;
2674 mode0 = insn_data[icode].operand[1].mode;
2675 mode1 = insn_data[icode].operand[2].mode;
2676 mode2 = insn_data[icode].operand[3].mode;
2677 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
2678 op0 = copy_to_mode_reg (mode0, op0);
2679 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
2680 op1 = copy_to_mode_reg (mode1, op1);
2681 if (!(*insn_data[icode].operand[3].predicate) (op2, mode2))
2682 op2 = copy_to_mode_reg (mode2, op2);
2683 }
2684 if (target == 0
2685 || GET_MODE (target) != tmode
2686 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
2687 target = gen_reg_rtx (tmode);
2688 pat = GEN_FCN (icode) (target, op0, op1, op2);
2689 if (!pat)
2690 return 0;
2691 emit_insn (pat);
2692 return target;
2693
2694 case ARM_BUILTIN_TINSRB:
2695 case ARM_BUILTIN_TINSRH:
2696 case ARM_BUILTIN_TINSRW:
2697 case ARM_BUILTIN_WMERGE:
2698 icode = (fcode == ARM_BUILTIN_TINSRB ? CODE_FOR_iwmmxt_tinsrb
2699 : fcode == ARM_BUILTIN_TINSRH ? CODE_FOR_iwmmxt_tinsrh
2700 : fcode == ARM_BUILTIN_WMERGE ? CODE_FOR_iwmmxt_wmerge
2701 : CODE_FOR_iwmmxt_tinsrw);
2702 arg0 = CALL_EXPR_ARG (exp, 0);
2703 arg1 = CALL_EXPR_ARG (exp, 1);
2704 arg2 = CALL_EXPR_ARG (exp, 2);
2705 op0 = expand_normal (arg0);
2706 op1 = expand_normal (arg1);
2707 op2 = expand_normal (arg2);
2708 tmode = insn_data[icode].operand[0].mode;
2709 mode0 = insn_data[icode].operand[1].mode;
2710 mode1 = insn_data[icode].operand[2].mode;
2711 mode2 = insn_data[icode].operand[3].mode;
2712
2713 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2714 op0 = copy_to_mode_reg (mode0, op0);
2715 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
2716 op1 = copy_to_mode_reg (mode1, op1);
2717 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
2718 {
2719 error ("selector must be an immediate");
2720 return const0_rtx;
2721 }
2722 if (icode == CODE_FOR_iwmmxt_wmerge)
2723 {
2724 selector = INTVAL (op2);
2725 if (selector > 7 || selector < 0)
2726 error ("the range of selector should be in 0 to 7");
2727 }
2728 if ((icode == CODE_FOR_iwmmxt_tinsrb)
2729 || (icode == CODE_FOR_iwmmxt_tinsrh)
2730 || (icode == CODE_FOR_iwmmxt_tinsrw))
2731 {
2732 mask = 0x01;
2733 selector= INTVAL (op2);
2734 if (icode == CODE_FOR_iwmmxt_tinsrb && (selector < 0 || selector > 7))
2735 error ("the range of selector should be in 0 to 7");
2736 else if (icode == CODE_FOR_iwmmxt_tinsrh && (selector < 0 ||selector > 3))
2737 error ("the range of selector should be in 0 to 3");
2738 else if (icode == CODE_FOR_iwmmxt_tinsrw && (selector < 0 ||selector > 1))
2739 error ("the range of selector should be in 0 to 1");
2740 mask <<= selector;
2741 op2 = GEN_INT (mask);
2742 }
2743 if (target == 0
2744 || GET_MODE (target) != tmode
2745 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2746 target = gen_reg_rtx (tmode);
2747 pat = GEN_FCN (icode) (target, op0, op1, op2);
2748 if (! pat)
2749 return 0;
2750 emit_insn (pat);
2751 return target;
2752
2753 case ARM_BUILTIN_SETWCGR0:
2754 case ARM_BUILTIN_SETWCGR1:
2755 case ARM_BUILTIN_SETWCGR2:
2756 case ARM_BUILTIN_SETWCGR3:
2757 icode = (fcode == ARM_BUILTIN_SETWCGR0 ? CODE_FOR_iwmmxt_setwcgr0
2758 : fcode == ARM_BUILTIN_SETWCGR1 ? CODE_FOR_iwmmxt_setwcgr1
2759 : fcode == ARM_BUILTIN_SETWCGR2 ? CODE_FOR_iwmmxt_setwcgr2
2760 : CODE_FOR_iwmmxt_setwcgr3);
2761 arg0 = CALL_EXPR_ARG (exp, 0);
2762 op0 = expand_normal (arg0);
2763 mode0 = insn_data[icode].operand[0].mode;
2764 if (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
2765 op0 = copy_to_mode_reg (mode0, op0);
2766 pat = GEN_FCN (icode) (op0);
2767 if (!pat)
2768 return 0;
2769 emit_insn (pat);
2770 return 0;
2771
2772 case ARM_BUILTIN_GETWCGR0:
2773 case ARM_BUILTIN_GETWCGR1:
2774 case ARM_BUILTIN_GETWCGR2:
2775 case ARM_BUILTIN_GETWCGR3:
2776 icode = (fcode == ARM_BUILTIN_GETWCGR0 ? CODE_FOR_iwmmxt_getwcgr0
2777 : fcode == ARM_BUILTIN_GETWCGR1 ? CODE_FOR_iwmmxt_getwcgr1
2778 : fcode == ARM_BUILTIN_GETWCGR2 ? CODE_FOR_iwmmxt_getwcgr2
2779 : CODE_FOR_iwmmxt_getwcgr3);
2780 tmode = insn_data[icode].operand[0].mode;
2781 if (target == 0
2782 || GET_MODE (target) != tmode
2783 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
2784 target = gen_reg_rtx (tmode);
2785 pat = GEN_FCN (icode) (target);
2786 if (!pat)
2787 return 0;
2788 emit_insn (pat);
2789 return target;
2790
2791 case ARM_BUILTIN_WSHUFH:
2792 icode = CODE_FOR_iwmmxt_wshufh;
2793 arg0 = CALL_EXPR_ARG (exp, 0);
2794 arg1 = CALL_EXPR_ARG (exp, 1);
2795 op0 = expand_normal (arg0);
2796 op1 = expand_normal (arg1);
2797 tmode = insn_data[icode].operand[0].mode;
2798 mode1 = insn_data[icode].operand[1].mode;
2799 mode2 = insn_data[icode].operand[2].mode;
2800
2801 if (! (*insn_data[icode].operand[1].predicate) (op0, mode1))
2802 op0 = copy_to_mode_reg (mode1, op0);
2803 if (! (*insn_data[icode].operand[2].predicate) (op1, mode2))
2804 {
2805 error ("mask must be an immediate");
2806 return const0_rtx;
2807 }
2808 selector = INTVAL (op1);
2809 if (selector < 0 || selector > 255)
2810 error ("the range of mask should be in 0 to 255");
2811 if (target == 0
2812 || GET_MODE (target) != tmode
2813 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2814 target = gen_reg_rtx (tmode);
2815 pat = GEN_FCN (icode) (target, op0, op1);
2816 if (! pat)
2817 return 0;
2818 emit_insn (pat);
2819 return target;
2820
2821 case ARM_BUILTIN_WMADDS:
2822 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmadds, exp, target);
2823 case ARM_BUILTIN_WMADDSX:
2824 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsx, exp, target);
2825 case ARM_BUILTIN_WMADDSN:
2826 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsn, exp, target);
2827 case ARM_BUILTIN_WMADDU:
2828 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddu, exp, target);
2829 case ARM_BUILTIN_WMADDUX:
2830 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddux, exp, target);
2831 case ARM_BUILTIN_WMADDUN:
2832 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddun, exp, target);
2833 case ARM_BUILTIN_WSADBZ:
2834 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz, exp, target);
2835 case ARM_BUILTIN_WSADHZ:
2836 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz, exp, target);
2837
2838 /* Several three-argument builtins. */
2839 case ARM_BUILTIN_WMACS:
2840 case ARM_BUILTIN_WMACU:
2841 case ARM_BUILTIN_TMIA:
2842 case ARM_BUILTIN_TMIAPH:
2843 case ARM_BUILTIN_TMIATT:
2844 case ARM_BUILTIN_TMIATB:
2845 case ARM_BUILTIN_TMIABT:
2846 case ARM_BUILTIN_TMIABB:
2847 case ARM_BUILTIN_WQMIABB:
2848 case ARM_BUILTIN_WQMIABT:
2849 case ARM_BUILTIN_WQMIATB:
2850 case ARM_BUILTIN_WQMIATT:
2851 case ARM_BUILTIN_WQMIABBN:
2852 case ARM_BUILTIN_WQMIABTN:
2853 case ARM_BUILTIN_WQMIATBN:
2854 case ARM_BUILTIN_WQMIATTN:
2855 case ARM_BUILTIN_WMIABB:
2856 case ARM_BUILTIN_WMIABT:
2857 case ARM_BUILTIN_WMIATB:
2858 case ARM_BUILTIN_WMIATT:
2859 case ARM_BUILTIN_WMIABBN:
2860 case ARM_BUILTIN_WMIABTN:
2861 case ARM_BUILTIN_WMIATBN:
2862 case ARM_BUILTIN_WMIATTN:
2863 case ARM_BUILTIN_WMIAWBB:
2864 case ARM_BUILTIN_WMIAWBT:
2865 case ARM_BUILTIN_WMIAWTB:
2866 case ARM_BUILTIN_WMIAWTT:
2867 case ARM_BUILTIN_WMIAWBBN:
2868 case ARM_BUILTIN_WMIAWBTN:
2869 case ARM_BUILTIN_WMIAWTBN:
2870 case ARM_BUILTIN_WMIAWTTN:
2871 case ARM_BUILTIN_WSADB:
2872 case ARM_BUILTIN_WSADH:
2873 icode = (fcode == ARM_BUILTIN_WMACS ? CODE_FOR_iwmmxt_wmacs
2874 : fcode == ARM_BUILTIN_WMACU ? CODE_FOR_iwmmxt_wmacu
2875 : fcode == ARM_BUILTIN_TMIA ? CODE_FOR_iwmmxt_tmia
2876 : fcode == ARM_BUILTIN_TMIAPH ? CODE_FOR_iwmmxt_tmiaph
2877 : fcode == ARM_BUILTIN_TMIABB ? CODE_FOR_iwmmxt_tmiabb
2878 : fcode == ARM_BUILTIN_TMIABT ? CODE_FOR_iwmmxt_tmiabt
2879 : fcode == ARM_BUILTIN_TMIATB ? CODE_FOR_iwmmxt_tmiatb
2880 : fcode == ARM_BUILTIN_TMIATT ? CODE_FOR_iwmmxt_tmiatt
2881 : fcode == ARM_BUILTIN_WQMIABB ? CODE_FOR_iwmmxt_wqmiabb
2882 : fcode == ARM_BUILTIN_WQMIABT ? CODE_FOR_iwmmxt_wqmiabt
2883 : fcode == ARM_BUILTIN_WQMIATB ? CODE_FOR_iwmmxt_wqmiatb
2884 : fcode == ARM_BUILTIN_WQMIATT ? CODE_FOR_iwmmxt_wqmiatt
2885 : fcode == ARM_BUILTIN_WQMIABBN ? CODE_FOR_iwmmxt_wqmiabbn
2886 : fcode == ARM_BUILTIN_WQMIABTN ? CODE_FOR_iwmmxt_wqmiabtn
2887 : fcode == ARM_BUILTIN_WQMIATBN ? CODE_FOR_iwmmxt_wqmiatbn
2888 : fcode == ARM_BUILTIN_WQMIATTN ? CODE_FOR_iwmmxt_wqmiattn
2889 : fcode == ARM_BUILTIN_WMIABB ? CODE_FOR_iwmmxt_wmiabb
2890 : fcode == ARM_BUILTIN_WMIABT ? CODE_FOR_iwmmxt_wmiabt
2891 : fcode == ARM_BUILTIN_WMIATB ? CODE_FOR_iwmmxt_wmiatb
2892 : fcode == ARM_BUILTIN_WMIATT ? CODE_FOR_iwmmxt_wmiatt
2893 : fcode == ARM_BUILTIN_WMIABBN ? CODE_FOR_iwmmxt_wmiabbn
2894 : fcode == ARM_BUILTIN_WMIABTN ? CODE_FOR_iwmmxt_wmiabtn
2895 : fcode == ARM_BUILTIN_WMIATBN ? CODE_FOR_iwmmxt_wmiatbn
2896 : fcode == ARM_BUILTIN_WMIATTN ? CODE_FOR_iwmmxt_wmiattn
2897 : fcode == ARM_BUILTIN_WMIAWBB ? CODE_FOR_iwmmxt_wmiawbb
2898 : fcode == ARM_BUILTIN_WMIAWBT ? CODE_FOR_iwmmxt_wmiawbt
2899 : fcode == ARM_BUILTIN_WMIAWTB ? CODE_FOR_iwmmxt_wmiawtb
2900 : fcode == ARM_BUILTIN_WMIAWTT ? CODE_FOR_iwmmxt_wmiawtt
2901 : fcode == ARM_BUILTIN_WMIAWBBN ? CODE_FOR_iwmmxt_wmiawbbn
2902 : fcode == ARM_BUILTIN_WMIAWBTN ? CODE_FOR_iwmmxt_wmiawbtn
2903 : fcode == ARM_BUILTIN_WMIAWTBN ? CODE_FOR_iwmmxt_wmiawtbn
2904 : fcode == ARM_BUILTIN_WMIAWTTN ? CODE_FOR_iwmmxt_wmiawttn
2905 : fcode == ARM_BUILTIN_WSADB ? CODE_FOR_iwmmxt_wsadb
2906 : CODE_FOR_iwmmxt_wsadh);
2907 arg0 = CALL_EXPR_ARG (exp, 0);
2908 arg1 = CALL_EXPR_ARG (exp, 1);
2909 arg2 = CALL_EXPR_ARG (exp, 2);
2910 op0 = expand_normal (arg0);
2911 op1 = expand_normal (arg1);
2912 op2 = expand_normal (arg2);
2913 tmode = insn_data[icode].operand[0].mode;
2914 mode0 = insn_data[icode].operand[1].mode;
2915 mode1 = insn_data[icode].operand[2].mode;
2916 mode2 = insn_data[icode].operand[3].mode;
2917
2918 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2919 op0 = copy_to_mode_reg (mode0, op0);
2920 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
2921 op1 = copy_to_mode_reg (mode1, op1);
2922 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
2923 op2 = copy_to_mode_reg (mode2, op2);
2924 if (target == 0
2925 || GET_MODE (target) != tmode
2926 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2927 target = gen_reg_rtx (tmode);
2928 pat = GEN_FCN (icode) (target, op0, op1, op2);
2929 if (! pat)
2930 return 0;
2931 emit_insn (pat);
2932 return target;
2933
2934 case ARM_BUILTIN_WZERO:
2935 target = gen_reg_rtx (DImode);
2936 emit_insn (gen_iwmmxt_clrdi (target));
2937 return target;
2938
2939 case ARM_BUILTIN_WSRLHI:
2940 case ARM_BUILTIN_WSRLWI:
2941 case ARM_BUILTIN_WSRLDI:
2942 case ARM_BUILTIN_WSLLHI:
2943 case ARM_BUILTIN_WSLLWI:
2944 case ARM_BUILTIN_WSLLDI:
2945 case ARM_BUILTIN_WSRAHI:
2946 case ARM_BUILTIN_WSRAWI:
2947 case ARM_BUILTIN_WSRADI:
2948 case ARM_BUILTIN_WRORHI:
2949 case ARM_BUILTIN_WRORWI:
2950 case ARM_BUILTIN_WRORDI:
2951 case ARM_BUILTIN_WSRLH:
2952 case ARM_BUILTIN_WSRLW:
2953 case ARM_BUILTIN_WSRLD:
2954 case ARM_BUILTIN_WSLLH:
2955 case ARM_BUILTIN_WSLLW:
2956 case ARM_BUILTIN_WSLLD:
2957 case ARM_BUILTIN_WSRAH:
2958 case ARM_BUILTIN_WSRAW:
2959 case ARM_BUILTIN_WSRAD:
2960 case ARM_BUILTIN_WRORH:
2961 case ARM_BUILTIN_WRORW:
2962 case ARM_BUILTIN_WRORD:
2963 icode = (fcode == ARM_BUILTIN_WSRLHI ? CODE_FOR_lshrv4hi3_iwmmxt
2964 : fcode == ARM_BUILTIN_WSRLWI ? CODE_FOR_lshrv2si3_iwmmxt
2965 : fcode == ARM_BUILTIN_WSRLDI ? CODE_FOR_lshrdi3_iwmmxt
2966 : fcode == ARM_BUILTIN_WSLLHI ? CODE_FOR_ashlv4hi3_iwmmxt
2967 : fcode == ARM_BUILTIN_WSLLWI ? CODE_FOR_ashlv2si3_iwmmxt
2968 : fcode == ARM_BUILTIN_WSLLDI ? CODE_FOR_ashldi3_iwmmxt
2969 : fcode == ARM_BUILTIN_WSRAHI ? CODE_FOR_ashrv4hi3_iwmmxt
2970 : fcode == ARM_BUILTIN_WSRAWI ? CODE_FOR_ashrv2si3_iwmmxt
2971 : fcode == ARM_BUILTIN_WSRADI ? CODE_FOR_ashrdi3_iwmmxt
2972 : fcode == ARM_BUILTIN_WRORHI ? CODE_FOR_rorv4hi3
2973 : fcode == ARM_BUILTIN_WRORWI ? CODE_FOR_rorv2si3
2974 : fcode == ARM_BUILTIN_WRORDI ? CODE_FOR_rordi3
2975 : fcode == ARM_BUILTIN_WSRLH ? CODE_FOR_lshrv4hi3_di
2976 : fcode == ARM_BUILTIN_WSRLW ? CODE_FOR_lshrv2si3_di
2977 : fcode == ARM_BUILTIN_WSRLD ? CODE_FOR_lshrdi3_di
2978 : fcode == ARM_BUILTIN_WSLLH ? CODE_FOR_ashlv4hi3_di
2979 : fcode == ARM_BUILTIN_WSLLW ? CODE_FOR_ashlv2si3_di
2980 : fcode == ARM_BUILTIN_WSLLD ? CODE_FOR_ashldi3_di
2981 : fcode == ARM_BUILTIN_WSRAH ? CODE_FOR_ashrv4hi3_di
2982 : fcode == ARM_BUILTIN_WSRAW ? CODE_FOR_ashrv2si3_di
2983 : fcode == ARM_BUILTIN_WSRAD ? CODE_FOR_ashrdi3_di
2984 : fcode == ARM_BUILTIN_WRORH ? CODE_FOR_rorv4hi3_di
2985 : fcode == ARM_BUILTIN_WRORW ? CODE_FOR_rorv2si3_di
2986 : fcode == ARM_BUILTIN_WRORD ? CODE_FOR_rordi3_di
2987 : CODE_FOR_nothing);
2988 arg1 = CALL_EXPR_ARG (exp, 1);
2989 op1 = expand_normal (arg1);
2990 if (GET_MODE (op1) == VOIDmode)
2991 {
2992 imm = INTVAL (op1);
2993 if ((fcode == ARM_BUILTIN_WRORHI || fcode == ARM_BUILTIN_WRORWI
2994 || fcode == ARM_BUILTIN_WRORH || fcode == ARM_BUILTIN_WRORW)
2995 && (imm < 0 || imm > 32))
2996 {
2997 if (fcode == ARM_BUILTIN_WRORHI)
2998 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi16 in code.");
2999 else if (fcode == ARM_BUILTIN_WRORWI)
3000 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi32 in code.");
3001 else if (fcode == ARM_BUILTIN_WRORH)
3002 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi16 in code.");
3003 else
3004 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi32 in code.");
3005 }
3006 else if ((fcode == ARM_BUILTIN_WRORDI || fcode == ARM_BUILTIN_WRORD)
3007 && (imm < 0 || imm > 64))
3008 {
3009 if (fcode == ARM_BUILTIN_WRORDI)
3010 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_rori_si64 in code.");
3011 else
3012 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_ror_si64 in code.");
3013 }
3014 else if (imm < 0)
3015 {
3016 if (fcode == ARM_BUILTIN_WSRLHI)
3017 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi16 in code.");
3018 else if (fcode == ARM_BUILTIN_WSRLWI)
3019 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi32 in code.");
3020 else if (fcode == ARM_BUILTIN_WSRLDI)
3021 error ("the count should be no less than 0. please check the intrinsic _mm_srli_si64 in code.");
3022 else if (fcode == ARM_BUILTIN_WSLLHI)
3023 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi16 in code.");
3024 else if (fcode == ARM_BUILTIN_WSLLWI)
3025 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi32 in code.");
3026 else if (fcode == ARM_BUILTIN_WSLLDI)
3027 error ("the count should be no less than 0. please check the intrinsic _mm_slli_si64 in code.");
3028 else if (fcode == ARM_BUILTIN_WSRAHI)
3029 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi16 in code.");
3030 else if (fcode == ARM_BUILTIN_WSRAWI)
3031 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi32 in code.");
3032 else if (fcode == ARM_BUILTIN_WSRADI)
3033 error ("the count should be no less than 0. please check the intrinsic _mm_srai_si64 in code.");
3034 else if (fcode == ARM_BUILTIN_WSRLH)
3035 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi16 in code.");
3036 else if (fcode == ARM_BUILTIN_WSRLW)
3037 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi32 in code.");
3038 else if (fcode == ARM_BUILTIN_WSRLD)
3039 error ("the count should be no less than 0. please check the intrinsic _mm_srl_si64 in code.");
3040 else if (fcode == ARM_BUILTIN_WSLLH)
3041 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi16 in code.");
3042 else if (fcode == ARM_BUILTIN_WSLLW)
3043 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi32 in code.");
3044 else if (fcode == ARM_BUILTIN_WSLLD)
3045 error ("the count should be no less than 0. please check the intrinsic _mm_sll_si64 in code.");
3046 else if (fcode == ARM_BUILTIN_WSRAH)
3047 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi16 in code.");
3048 else if (fcode == ARM_BUILTIN_WSRAW)
3049 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi32 in code.");
3050 else
3051 error ("the count should be no less than 0. please check the intrinsic _mm_sra_si64 in code.");
3052 }
3053 }
3054 return arm_expand_binop_builtin (icode, exp, target);
3055
3056 default:
3057 break;
3058 }
3059
3060 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
8972d3d0 3061 if (d->code == (enum arm_builtins) fcode)
d6504d76 3062 return arm_expand_binop_builtin (d->icode, exp, target);
3063
3064 for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
8972d3d0 3065 if (d->code == (enum arm_builtins) fcode)
d6504d76 3066 return arm_expand_unop_builtin (d->icode, exp, target, 0);
3067
3068 for (i = 0, d = bdesc_3arg; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
8972d3d0 3069 if (d->code == (enum arm_builtins) fcode)
d6504d76 3070 return arm_expand_ternop_builtin (d->icode, exp, target);
3071
3072 /* @@@ Should really do something sensible here. */
3073 return NULL_RTX;
3074}
3075
3076tree
b6c464fe 3077arm_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in)
d6504d76 3078{
3079 machine_mode in_mode, out_mode;
3080 int in_n, out_n;
3081 bool out_unsigned_p = TYPE_UNSIGNED (type_out);
3082
3f5ea43a 3083 /* Can't provide any vectorized builtins when we can't use NEON. */
3084 if (!TARGET_NEON)
3085 return NULL_TREE;
3086
d6504d76 3087 if (TREE_CODE (type_out) != VECTOR_TYPE
3088 || TREE_CODE (type_in) != VECTOR_TYPE)
3089 return NULL_TREE;
3090
3091 out_mode = TYPE_MODE (TREE_TYPE (type_out));
3092 out_n = TYPE_VECTOR_SUBPARTS (type_out);
3093 in_mode = TYPE_MODE (TREE_TYPE (type_in));
3094 in_n = TYPE_VECTOR_SUBPARTS (type_in);
3095
3096/* ARM_CHECK_BUILTIN_MODE and ARM_FIND_VRINT_VARIANT are used to find the
3097 decl of the vectorized builtin for the appropriate vector mode.
3098 NULL_TREE is returned if no such builtin is available. */
3099#undef ARM_CHECK_BUILTIN_MODE
3100#define ARM_CHECK_BUILTIN_MODE(C) \
c79c1b1b 3101 (TARGET_VFP5 \
d6504d76 3102 && flag_unsafe_math_optimizations \
3103 && ARM_CHECK_BUILTIN_MODE_1 (C))
3104
3105#undef ARM_CHECK_BUILTIN_MODE_1
3106#define ARM_CHECK_BUILTIN_MODE_1(C) \
3107 (out_mode == SFmode && out_n == C \
3108 && in_mode == SFmode && in_n == C)
3109
3110#undef ARM_FIND_VRINT_VARIANT
3111#define ARM_FIND_VRINT_VARIANT(N) \
3112 (ARM_CHECK_BUILTIN_MODE (2) \
3113 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sf, false) \
3114 : (ARM_CHECK_BUILTIN_MODE (4) \
3115 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sf, false) \
3116 : NULL_TREE))
3117
b6c464fe 3118 switch (fn)
d6504d76 3119 {
b6c464fe 3120 CASE_CFN_FLOOR:
3121 return ARM_FIND_VRINT_VARIANT (vrintm);
3122 CASE_CFN_CEIL:
3123 return ARM_FIND_VRINT_VARIANT (vrintp);
3124 CASE_CFN_TRUNC:
3125 return ARM_FIND_VRINT_VARIANT (vrintz);
3126 CASE_CFN_ROUND:
3127 return ARM_FIND_VRINT_VARIANT (vrinta);
d6504d76 3128#undef ARM_CHECK_BUILTIN_MODE_1
3129#define ARM_CHECK_BUILTIN_MODE_1(C) \
3130 (out_mode == SImode && out_n == C \
3131 && in_mode == SFmode && in_n == C)
3132
3133#define ARM_FIND_VCVT_VARIANT(N) \
3134 (ARM_CHECK_BUILTIN_MODE (2) \
3135 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sfv2si, false) \
3136 : (ARM_CHECK_BUILTIN_MODE (4) \
3137 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sfv4si, false) \
3138 : NULL_TREE))
3139
3140#define ARM_FIND_VCVTU_VARIANT(N) \
3141 (ARM_CHECK_BUILTIN_MODE (2) \
3142 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv2sfv2si, false) \
3143 : (ARM_CHECK_BUILTIN_MODE (4) \
3144 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv4sfv4si, false) \
3145 : NULL_TREE))
b6c464fe 3146 CASE_CFN_LROUND:
3147 return (out_unsigned_p
3148 ? ARM_FIND_VCVTU_VARIANT (vcvta)
3149 : ARM_FIND_VCVT_VARIANT (vcvta));
3150 CASE_CFN_LCEIL:
3151 return (out_unsigned_p
3152 ? ARM_FIND_VCVTU_VARIANT (vcvtp)
3153 : ARM_FIND_VCVT_VARIANT (vcvtp));
3154 CASE_CFN_LFLOOR:
3155 return (out_unsigned_p
3156 ? ARM_FIND_VCVTU_VARIANT (vcvtm)
3157 : ARM_FIND_VCVT_VARIANT (vcvtm));
d6504d76 3158#undef ARM_CHECK_BUILTIN_MODE
3159#define ARM_CHECK_BUILTIN_MODE(C, N) \
3160 (out_mode == N##mode && out_n == C \
3161 && in_mode == N##mode && in_n == C)
b6c464fe 3162 case CFN_BUILT_IN_BSWAP16:
3163 if (ARM_CHECK_BUILTIN_MODE (4, HI))
3164 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4hi, false);
3165 else if (ARM_CHECK_BUILTIN_MODE (8, HI))
3166 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv8hi, false);
3167 else
3168 return NULL_TREE;
3169 case CFN_BUILT_IN_BSWAP32:
3170 if (ARM_CHECK_BUILTIN_MODE (2, SI))
3171 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2si, false);
3172 else if (ARM_CHECK_BUILTIN_MODE (4, SI))
3173 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4si, false);
3174 else
3175 return NULL_TREE;
3176 case CFN_BUILT_IN_BSWAP64:
3177 if (ARM_CHECK_BUILTIN_MODE (2, DI))
3178 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2di, false);
3179 else
3180 return NULL_TREE;
3181 CASE_CFN_COPYSIGN:
3182 if (ARM_CHECK_BUILTIN_MODE (2, SF))
3183 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv2sf, false);
3184 else if (ARM_CHECK_BUILTIN_MODE (4, SF))
3185 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv4sf, false);
3186 else
3187 return NULL_TREE;
3188
3189 default:
3190 return NULL_TREE;
d6504d76 3191 }
3192 return NULL_TREE;
3193}
3194#undef ARM_FIND_VCVT_VARIANT
3195#undef ARM_FIND_VCVTU_VARIANT
3196#undef ARM_CHECK_BUILTIN_MODE
3197#undef ARM_FIND_VRINT_VARIANT
3198
3199void
3200arm_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
3201{
3202 const unsigned ARM_FE_INVALID = 1;
3203 const unsigned ARM_FE_DIVBYZERO = 2;
3204 const unsigned ARM_FE_OVERFLOW = 4;
3205 const unsigned ARM_FE_UNDERFLOW = 8;
3206 const unsigned ARM_FE_INEXACT = 16;
3207 const unsigned HOST_WIDE_INT ARM_FE_ALL_EXCEPT = (ARM_FE_INVALID
3208 | ARM_FE_DIVBYZERO
3209 | ARM_FE_OVERFLOW
3210 | ARM_FE_UNDERFLOW
3211 | ARM_FE_INEXACT);
3212 const unsigned HOST_WIDE_INT ARM_FE_EXCEPT_SHIFT = 8;
3213 tree fenv_var, get_fpscr, set_fpscr, mask, ld_fenv, masked_fenv;
3214 tree new_fenv_var, reload_fenv, restore_fnenv;
3215 tree update_call, atomic_feraiseexcept, hold_fnclex;
3216
d7216193 3217 if (!TARGET_HARD_FLOAT)
d6504d76 3218 return;
3219
3220 /* Generate the equivalent of :
3221 unsigned int fenv_var;
3222 fenv_var = __builtin_arm_get_fpscr ();
3223
3224 unsigned int masked_fenv;
3225 masked_fenv = fenv_var & mask;
3226
3227 __builtin_arm_set_fpscr (masked_fenv); */
3228
7aa5890a 3229 fenv_var = create_tmp_var_raw (unsigned_type_node);
d6504d76 3230 get_fpscr = arm_builtin_decls[ARM_BUILTIN_GET_FPSCR];
3231 set_fpscr = arm_builtin_decls[ARM_BUILTIN_SET_FPSCR];
3232 mask = build_int_cst (unsigned_type_node,
3233 ~((ARM_FE_ALL_EXCEPT << ARM_FE_EXCEPT_SHIFT)
3234 | ARM_FE_ALL_EXCEPT));
3235 ld_fenv = build2 (MODIFY_EXPR, unsigned_type_node,
3236 fenv_var, build_call_expr (get_fpscr, 0));
3237 masked_fenv = build2 (BIT_AND_EXPR, unsigned_type_node, fenv_var, mask);
3238 hold_fnclex = build_call_expr (set_fpscr, 1, masked_fenv);
3239 *hold = build2 (COMPOUND_EXPR, void_type_node,
3240 build2 (COMPOUND_EXPR, void_type_node, masked_fenv, ld_fenv),
3241 hold_fnclex);
3242
3243 /* Store the value of masked_fenv to clear the exceptions:
3244 __builtin_arm_set_fpscr (masked_fenv); */
3245
3246 *clear = build_call_expr (set_fpscr, 1, masked_fenv);
3247
3248 /* Generate the equivalent of :
3249 unsigned int new_fenv_var;
3250 new_fenv_var = __builtin_arm_get_fpscr ();
3251
3252 __builtin_arm_set_fpscr (fenv_var);
3253
3254 __atomic_feraiseexcept (new_fenv_var); */
3255
7aa5890a 3256 new_fenv_var = create_tmp_var_raw (unsigned_type_node);
d6504d76 3257 reload_fenv = build2 (MODIFY_EXPR, unsigned_type_node, new_fenv_var,
3258 build_call_expr (get_fpscr, 0));
3259 restore_fnenv = build_call_expr (set_fpscr, 1, fenv_var);
3260 atomic_feraiseexcept = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
3261 update_call = build_call_expr (atomic_feraiseexcept, 1,
3262 fold_convert (integer_type_node, new_fenv_var));
3263 *update = build2 (COMPOUND_EXPR, void_type_node,
3264 build2 (COMPOUND_EXPR, void_type_node,
3265 reload_fenv, restore_fnenv), update_call);
3266}
3267
3268#include "gt-arm-builtins.h"