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