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