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