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