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