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