]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/arm-builtins.c
bb-slp-32.c: Adjust testcase.
[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
JG
895static void
896arm_init_neon_builtins (void)
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 }
33857df2 1017
6276b630
JG
1018 if (TARGET_CRYPTO && TARGET_HARD_FLOAT)
1019 {
1020 tree V16UQI_type_node = arm_simd_builtin_type (V16QImode,
1021 true,
1022 false);
1023
1024 tree V4USI_type_node = arm_simd_builtin_type (V4SImode,
1025 true,
1026 false);
1027
1028 tree v16uqi_ftype_v16uqi
1029 = build_function_type_list (V16UQI_type_node, V16UQI_type_node,
1030 NULL_TREE);
1031
1032 tree v16uqi_ftype_v16uqi_v16uqi
1033 = build_function_type_list (V16UQI_type_node, V16UQI_type_node,
1034 V16UQI_type_node, NULL_TREE);
1035
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), \
1087 C (U), BUILT_IN_MD, NULL, NULL_TREE);
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
33857df2
JG
1098 }
1099}
1100
1101#undef NUM_DREG_TYPES
1102#undef NUM_QREG_TYPES
1103
23b9ccbe 1104#define def_mbuiltin(FLAGS, NAME, TYPE, CODE) \
33857df2
JG
1105 do \
1106 { \
23b9ccbe
MW
1107 const arm_feature_set flags = FLAGS; \
1108 if (ARM_FSET_CPU_SUBSET (flags, insn_flags)) \
33857df2
JG
1109 { \
1110 tree bdecl; \
1111 bdecl = add_builtin_function ((NAME), (TYPE), (CODE), \
1112 BUILT_IN_MD, NULL, NULL_TREE); \
1113 arm_builtin_decls[CODE] = bdecl; \
1114 } \
1115 } \
1116 while (0)
1117
1118struct builtin_description
1119{
23b9ccbe 1120 const arm_feature_set features;
33857df2
JG
1121 const enum insn_code icode;
1122 const char * const name;
1123 const enum arm_builtins code;
1124 const enum rtx_code comparison;
1125 const unsigned int flag;
1126};
1127
1128static const struct builtin_description bdesc_2arg[] =
1129{
1130#define IWMMXT_BUILTIN(code, string, builtin) \
23b9ccbe
MW
1131 { ARM_FSET_MAKE_CPU1 (FL_IWMMXT), CODE_FOR_##code, \
1132 "__builtin_arm_" string, \
33857df2
JG
1133 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1134
1135#define IWMMXT2_BUILTIN(code, string, builtin) \
23b9ccbe
MW
1136 { ARM_FSET_MAKE_CPU1 (FL_IWMMXT2), CODE_FOR_##code, \
1137 "__builtin_arm_" string, \
33857df2
JG
1138 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
1139
1140 IWMMXT_BUILTIN (addv8qi3, "waddb", WADDB)
1141 IWMMXT_BUILTIN (addv4hi3, "waddh", WADDH)
1142 IWMMXT_BUILTIN (addv2si3, "waddw", WADDW)
1143 IWMMXT_BUILTIN (subv8qi3, "wsubb", WSUBB)
1144 IWMMXT_BUILTIN (subv4hi3, "wsubh", WSUBH)
1145 IWMMXT_BUILTIN (subv2si3, "wsubw", WSUBW)
1146 IWMMXT_BUILTIN (ssaddv8qi3, "waddbss", WADDSSB)
1147 IWMMXT_BUILTIN (ssaddv4hi3, "waddhss", WADDSSH)
1148 IWMMXT_BUILTIN (ssaddv2si3, "waddwss", WADDSSW)
1149 IWMMXT_BUILTIN (sssubv8qi3, "wsubbss", WSUBSSB)
1150 IWMMXT_BUILTIN (sssubv4hi3, "wsubhss", WSUBSSH)
1151 IWMMXT_BUILTIN (sssubv2si3, "wsubwss", WSUBSSW)
1152 IWMMXT_BUILTIN (usaddv8qi3, "waddbus", WADDUSB)
1153 IWMMXT_BUILTIN (usaddv4hi3, "waddhus", WADDUSH)
1154 IWMMXT_BUILTIN (usaddv2si3, "waddwus", WADDUSW)
1155 IWMMXT_BUILTIN (ussubv8qi3, "wsubbus", WSUBUSB)
1156 IWMMXT_BUILTIN (ussubv4hi3, "wsubhus", WSUBUSH)
1157 IWMMXT_BUILTIN (ussubv2si3, "wsubwus", WSUBUSW)
1158 IWMMXT_BUILTIN (mulv4hi3, "wmulul", WMULUL)
1159 IWMMXT_BUILTIN (smulv4hi3_highpart, "wmulsm", WMULSM)
1160 IWMMXT_BUILTIN (umulv4hi3_highpart, "wmulum", WMULUM)
1161 IWMMXT_BUILTIN (eqv8qi3, "wcmpeqb", WCMPEQB)
1162 IWMMXT_BUILTIN (eqv4hi3, "wcmpeqh", WCMPEQH)
1163 IWMMXT_BUILTIN (eqv2si3, "wcmpeqw", WCMPEQW)
1164 IWMMXT_BUILTIN (gtuv8qi3, "wcmpgtub", WCMPGTUB)
1165 IWMMXT_BUILTIN (gtuv4hi3, "wcmpgtuh", WCMPGTUH)
1166 IWMMXT_BUILTIN (gtuv2si3, "wcmpgtuw", WCMPGTUW)
1167 IWMMXT_BUILTIN (gtv8qi3, "wcmpgtsb", WCMPGTSB)
1168 IWMMXT_BUILTIN (gtv4hi3, "wcmpgtsh", WCMPGTSH)
1169 IWMMXT_BUILTIN (gtv2si3, "wcmpgtsw", WCMPGTSW)
1170 IWMMXT_BUILTIN (umaxv8qi3, "wmaxub", WMAXUB)
1171 IWMMXT_BUILTIN (smaxv8qi3, "wmaxsb", WMAXSB)
1172 IWMMXT_BUILTIN (umaxv4hi3, "wmaxuh", WMAXUH)
1173 IWMMXT_BUILTIN (smaxv4hi3, "wmaxsh", WMAXSH)
1174 IWMMXT_BUILTIN (umaxv2si3, "wmaxuw", WMAXUW)
1175 IWMMXT_BUILTIN (smaxv2si3, "wmaxsw", WMAXSW)
1176 IWMMXT_BUILTIN (uminv8qi3, "wminub", WMINUB)
1177 IWMMXT_BUILTIN (sminv8qi3, "wminsb", WMINSB)
1178 IWMMXT_BUILTIN (uminv4hi3, "wminuh", WMINUH)
1179 IWMMXT_BUILTIN (sminv4hi3, "wminsh", WMINSH)
1180 IWMMXT_BUILTIN (uminv2si3, "wminuw", WMINUW)
1181 IWMMXT_BUILTIN (sminv2si3, "wminsw", WMINSW)
1182 IWMMXT_BUILTIN (iwmmxt_anddi3, "wand", WAND)
1183 IWMMXT_BUILTIN (iwmmxt_nanddi3, "wandn", WANDN)
1184 IWMMXT_BUILTIN (iwmmxt_iordi3, "wor", WOR)
1185 IWMMXT_BUILTIN (iwmmxt_xordi3, "wxor", WXOR)
1186 IWMMXT_BUILTIN (iwmmxt_uavgv8qi3, "wavg2b", WAVG2B)
1187 IWMMXT_BUILTIN (iwmmxt_uavgv4hi3, "wavg2h", WAVG2H)
1188 IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3, "wavg2br", WAVG2BR)
1189 IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3, "wavg2hr", WAVG2HR)
1190 IWMMXT_BUILTIN (iwmmxt_wunpckilb, "wunpckilb", WUNPCKILB)
1191 IWMMXT_BUILTIN (iwmmxt_wunpckilh, "wunpckilh", WUNPCKILH)
1192 IWMMXT_BUILTIN (iwmmxt_wunpckilw, "wunpckilw", WUNPCKILW)
1193 IWMMXT_BUILTIN (iwmmxt_wunpckihb, "wunpckihb", WUNPCKIHB)
1194 IWMMXT_BUILTIN (iwmmxt_wunpckihh, "wunpckihh", WUNPCKIHH)
1195 IWMMXT_BUILTIN (iwmmxt_wunpckihw, "wunpckihw", WUNPCKIHW)
1196 IWMMXT2_BUILTIN (iwmmxt_waddsubhx, "waddsubhx", WADDSUBHX)
1197 IWMMXT2_BUILTIN (iwmmxt_wsubaddhx, "wsubaddhx", WSUBADDHX)
1198 IWMMXT2_BUILTIN (iwmmxt_wabsdiffb, "wabsdiffb", WABSDIFFB)
1199 IWMMXT2_BUILTIN (iwmmxt_wabsdiffh, "wabsdiffh", WABSDIFFH)
1200 IWMMXT2_BUILTIN (iwmmxt_wabsdiffw, "wabsdiffw", WABSDIFFW)
1201 IWMMXT2_BUILTIN (iwmmxt_avg4, "wavg4", WAVG4)
1202 IWMMXT2_BUILTIN (iwmmxt_avg4r, "wavg4r", WAVG4R)
1203 IWMMXT2_BUILTIN (iwmmxt_wmulwsm, "wmulwsm", WMULWSM)
1204 IWMMXT2_BUILTIN (iwmmxt_wmulwum, "wmulwum", WMULWUM)
1205 IWMMXT2_BUILTIN (iwmmxt_wmulwsmr, "wmulwsmr", WMULWSMR)
1206 IWMMXT2_BUILTIN (iwmmxt_wmulwumr, "wmulwumr", WMULWUMR)
1207 IWMMXT2_BUILTIN (iwmmxt_wmulwl, "wmulwl", WMULWL)
1208 IWMMXT2_BUILTIN (iwmmxt_wmulsmr, "wmulsmr", WMULSMR)
1209 IWMMXT2_BUILTIN (iwmmxt_wmulumr, "wmulumr", WMULUMR)
1210 IWMMXT2_BUILTIN (iwmmxt_wqmulm, "wqmulm", WQMULM)
1211 IWMMXT2_BUILTIN (iwmmxt_wqmulmr, "wqmulmr", WQMULMR)
1212 IWMMXT2_BUILTIN (iwmmxt_wqmulwm, "wqmulwm", WQMULWM)
1213 IWMMXT2_BUILTIN (iwmmxt_wqmulwmr, "wqmulwmr", WQMULWMR)
1214 IWMMXT_BUILTIN (iwmmxt_walignr0, "walignr0", WALIGNR0)
1215 IWMMXT_BUILTIN (iwmmxt_walignr1, "walignr1", WALIGNR1)
1216 IWMMXT_BUILTIN (iwmmxt_walignr2, "walignr2", WALIGNR2)
1217 IWMMXT_BUILTIN (iwmmxt_walignr3, "walignr3", WALIGNR3)
1218
1219#define IWMMXT_BUILTIN2(code, builtin) \
23b9ccbe
MW
1220 { ARM_FSET_MAKE_CPU1 (FL_IWMMXT), CODE_FOR_##code, NULL, \
1221 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
33857df2
JG
1222
1223#define IWMMXT2_BUILTIN2(code, builtin) \
23b9ccbe
MW
1224 { ARM_FSET_MAKE_CPU2 (FL_IWMMXT2), CODE_FOR_##code, NULL, \
1225 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
33857df2
JG
1226
1227 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusm, WADDBHUSM)
1228 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusl, WADDBHUSL)
1229 IWMMXT_BUILTIN2 (iwmmxt_wpackhss, WPACKHSS)
1230 IWMMXT_BUILTIN2 (iwmmxt_wpackwss, WPACKWSS)
1231 IWMMXT_BUILTIN2 (iwmmxt_wpackdss, WPACKDSS)
1232 IWMMXT_BUILTIN2 (iwmmxt_wpackhus, WPACKHUS)
1233 IWMMXT_BUILTIN2 (iwmmxt_wpackwus, WPACKWUS)
1234 IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS)
1235 IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ)
1236 IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ)
1237
1238
1239#define FP_BUILTIN(L, U) \
23b9ccbe 1240 {ARM_FSET_EMPTY, CODE_FOR_##L, "__builtin_arm_"#L, ARM_BUILTIN_##U, \
33857df2
JG
1241 UNKNOWN, 0},
1242
1243 FP_BUILTIN (get_fpscr, GET_FPSCR)
1244 FP_BUILTIN (set_fpscr, SET_FPSCR)
1245#undef FP_BUILTIN
1246
1247#define CRC32_BUILTIN(L, U) \
23b9ccbe
MW
1248 {ARM_FSET_EMPTY, CODE_FOR_##L, "__builtin_arm_"#L, \
1249 ARM_BUILTIN_##U, UNKNOWN, 0},
33857df2
JG
1250 CRC32_BUILTIN (crc32b, CRC32B)
1251 CRC32_BUILTIN (crc32h, CRC32H)
1252 CRC32_BUILTIN (crc32w, CRC32W)
1253 CRC32_BUILTIN (crc32cb, CRC32CB)
1254 CRC32_BUILTIN (crc32ch, CRC32CH)
1255 CRC32_BUILTIN (crc32cw, CRC32CW)
1256#undef CRC32_BUILTIN
1257
1258
23b9ccbe
MW
1259#define CRYPTO_BUILTIN(L, U) \
1260 {ARM_FSET_EMPTY, CODE_FOR_crypto_##L, "__builtin_arm_crypto_"#L, \
1261 ARM_BUILTIN_CRYPTO_##U, UNKNOWN, 0},
33857df2
JG
1262#undef CRYPTO1
1263#undef CRYPTO2
1264#undef CRYPTO3
1265#define CRYPTO2(L, U, R, A1, A2) CRYPTO_BUILTIN (L, U)
1266#define CRYPTO1(L, U, R, A)
1267#define CRYPTO3(L, U, R, A1, A2, A3)
1268#include "crypto.def"
1269#undef CRYPTO1
1270#undef CRYPTO2
1271#undef CRYPTO3
1272
1273};
1274
1275static const struct builtin_description bdesc_1arg[] =
1276{
1277 IWMMXT_BUILTIN (iwmmxt_tmovmskb, "tmovmskb", TMOVMSKB)
1278 IWMMXT_BUILTIN (iwmmxt_tmovmskh, "tmovmskh", TMOVMSKH)
1279 IWMMXT_BUILTIN (iwmmxt_tmovmskw, "tmovmskw", TMOVMSKW)
1280 IWMMXT_BUILTIN (iwmmxt_waccb, "waccb", WACCB)
1281 IWMMXT_BUILTIN (iwmmxt_wacch, "wacch", WACCH)
1282 IWMMXT_BUILTIN (iwmmxt_waccw, "waccw", WACCW)
1283 IWMMXT_BUILTIN (iwmmxt_wunpckehub, "wunpckehub", WUNPCKEHUB)
1284 IWMMXT_BUILTIN (iwmmxt_wunpckehuh, "wunpckehuh", WUNPCKEHUH)
1285 IWMMXT_BUILTIN (iwmmxt_wunpckehuw, "wunpckehuw", WUNPCKEHUW)
1286 IWMMXT_BUILTIN (iwmmxt_wunpckehsb, "wunpckehsb", WUNPCKEHSB)
1287 IWMMXT_BUILTIN (iwmmxt_wunpckehsh, "wunpckehsh", WUNPCKEHSH)
1288 IWMMXT_BUILTIN (iwmmxt_wunpckehsw, "wunpckehsw", WUNPCKEHSW)
1289 IWMMXT_BUILTIN (iwmmxt_wunpckelub, "wunpckelub", WUNPCKELUB)
1290 IWMMXT_BUILTIN (iwmmxt_wunpckeluh, "wunpckeluh", WUNPCKELUH)
1291 IWMMXT_BUILTIN (iwmmxt_wunpckeluw, "wunpckeluw", WUNPCKELUW)
1292 IWMMXT_BUILTIN (iwmmxt_wunpckelsb, "wunpckelsb", WUNPCKELSB)
1293 IWMMXT_BUILTIN (iwmmxt_wunpckelsh, "wunpckelsh", WUNPCKELSH)
1294 IWMMXT_BUILTIN (iwmmxt_wunpckelsw, "wunpckelsw", WUNPCKELSW)
1295 IWMMXT2_BUILTIN (iwmmxt_wabsv8qi3, "wabsb", WABSB)
1296 IWMMXT2_BUILTIN (iwmmxt_wabsv4hi3, "wabsh", WABSH)
1297 IWMMXT2_BUILTIN (iwmmxt_wabsv2si3, "wabsw", WABSW)
1298 IWMMXT_BUILTIN (tbcstv8qi, "tbcstb", TBCSTB)
1299 IWMMXT_BUILTIN (tbcstv4hi, "tbcsth", TBCSTH)
1300 IWMMXT_BUILTIN (tbcstv2si, "tbcstw", TBCSTW)
1301
1302#define CRYPTO1(L, U, R, A) CRYPTO_BUILTIN (L, U)
1303#define CRYPTO2(L, U, R, A1, A2)
1304#define CRYPTO3(L, U, R, A1, A2, A3)
1305#include "crypto.def"
1306#undef CRYPTO1
1307#undef CRYPTO2
1308#undef CRYPTO3
1309};
1310
1311static const struct builtin_description bdesc_3arg[] =
1312{
1313#define CRYPTO3(L, U, R, A1, A2, A3) CRYPTO_BUILTIN (L, U)
1314#define CRYPTO1(L, U, R, A)
1315#define CRYPTO2(L, U, R, A1, A2)
1316#include "crypto.def"
1317#undef CRYPTO1
1318#undef CRYPTO2
1319#undef CRYPTO3
1320 };
1321#undef CRYPTO_BUILTIN
1322
1323/* Set up all the iWMMXt builtins. This is not called if
1324 TARGET_IWMMXT is zero. */
1325
1326static void
1327arm_init_iwmmxt_builtins (void)
1328{
1329 const struct builtin_description * d;
1330 size_t i;
1331
1332 tree V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
1333 tree V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
1334 tree V8QI_type_node = build_vector_type_for_mode (intQI_type_node, V8QImode);
1335
1336 tree v8qi_ftype_v8qi_v8qi_int
1337 = build_function_type_list (V8QI_type_node,
1338 V8QI_type_node, V8QI_type_node,
1339 integer_type_node, NULL_TREE);
1340 tree v4hi_ftype_v4hi_int
1341 = build_function_type_list (V4HI_type_node,
1342 V4HI_type_node, integer_type_node, NULL_TREE);
1343 tree v2si_ftype_v2si_int
1344 = build_function_type_list (V2SI_type_node,
1345 V2SI_type_node, integer_type_node, NULL_TREE);
1346 tree v2si_ftype_di_di
1347 = build_function_type_list (V2SI_type_node,
1348 long_long_integer_type_node,
1349 long_long_integer_type_node,
1350 NULL_TREE);
1351 tree di_ftype_di_int
1352 = build_function_type_list (long_long_integer_type_node,
1353 long_long_integer_type_node,
1354 integer_type_node, NULL_TREE);
1355 tree di_ftype_di_int_int
1356 = build_function_type_list (long_long_integer_type_node,
1357 long_long_integer_type_node,
1358 integer_type_node,
1359 integer_type_node, NULL_TREE);
1360 tree int_ftype_v8qi
1361 = build_function_type_list (integer_type_node,
1362 V8QI_type_node, NULL_TREE);
1363 tree int_ftype_v4hi
1364 = build_function_type_list (integer_type_node,
1365 V4HI_type_node, NULL_TREE);
1366 tree int_ftype_v2si
1367 = build_function_type_list (integer_type_node,
1368 V2SI_type_node, NULL_TREE);
1369 tree int_ftype_v8qi_int
1370 = build_function_type_list (integer_type_node,
1371 V8QI_type_node, integer_type_node, NULL_TREE);
1372 tree int_ftype_v4hi_int
1373 = build_function_type_list (integer_type_node,
1374 V4HI_type_node, integer_type_node, NULL_TREE);
1375 tree int_ftype_v2si_int
1376 = build_function_type_list (integer_type_node,
1377 V2SI_type_node, integer_type_node, NULL_TREE);
1378 tree v8qi_ftype_v8qi_int_int
1379 = build_function_type_list (V8QI_type_node,
1380 V8QI_type_node, integer_type_node,
1381 integer_type_node, NULL_TREE);
1382 tree v4hi_ftype_v4hi_int_int
1383 = build_function_type_list (V4HI_type_node,
1384 V4HI_type_node, integer_type_node,
1385 integer_type_node, NULL_TREE);
1386 tree v2si_ftype_v2si_int_int
1387 = build_function_type_list (V2SI_type_node,
1388 V2SI_type_node, integer_type_node,
1389 integer_type_node, NULL_TREE);
1390 /* Miscellaneous. */
1391 tree v8qi_ftype_v4hi_v4hi
1392 = build_function_type_list (V8QI_type_node,
1393 V4HI_type_node, V4HI_type_node, NULL_TREE);
1394 tree v4hi_ftype_v2si_v2si
1395 = build_function_type_list (V4HI_type_node,
1396 V2SI_type_node, V2SI_type_node, NULL_TREE);
1397 tree v8qi_ftype_v4hi_v8qi
1398 = build_function_type_list (V8QI_type_node,
1399 V4HI_type_node, V8QI_type_node, NULL_TREE);
1400 tree v2si_ftype_v4hi_v4hi
1401 = build_function_type_list (V2SI_type_node,
1402 V4HI_type_node, V4HI_type_node, NULL_TREE);
1403 tree v2si_ftype_v8qi_v8qi
1404 = build_function_type_list (V2SI_type_node,
1405 V8QI_type_node, V8QI_type_node, NULL_TREE);
1406 tree v4hi_ftype_v4hi_di
1407 = build_function_type_list (V4HI_type_node,
1408 V4HI_type_node, long_long_integer_type_node,
1409 NULL_TREE);
1410 tree v2si_ftype_v2si_di
1411 = build_function_type_list (V2SI_type_node,
1412 V2SI_type_node, long_long_integer_type_node,
1413 NULL_TREE);
1414 tree di_ftype_void
1415 = build_function_type_list (long_long_unsigned_type_node, NULL_TREE);
1416 tree int_ftype_void
1417 = build_function_type_list (integer_type_node, NULL_TREE);
1418 tree di_ftype_v8qi
1419 = build_function_type_list (long_long_integer_type_node,
1420 V8QI_type_node, NULL_TREE);
1421 tree di_ftype_v4hi
1422 = build_function_type_list (long_long_integer_type_node,
1423 V4HI_type_node, NULL_TREE);
1424 tree di_ftype_v2si
1425 = build_function_type_list (long_long_integer_type_node,
1426 V2SI_type_node, NULL_TREE);
1427 tree v2si_ftype_v4hi
1428 = build_function_type_list (V2SI_type_node,
1429 V4HI_type_node, NULL_TREE);
1430 tree v4hi_ftype_v8qi
1431 = build_function_type_list (V4HI_type_node,
1432 V8QI_type_node, NULL_TREE);
1433 tree v8qi_ftype_v8qi
1434 = build_function_type_list (V8QI_type_node,
1435 V8QI_type_node, NULL_TREE);
1436 tree v4hi_ftype_v4hi
1437 = build_function_type_list (V4HI_type_node,
1438 V4HI_type_node, NULL_TREE);
1439 tree v2si_ftype_v2si
1440 = build_function_type_list (V2SI_type_node,
1441 V2SI_type_node, NULL_TREE);
1442
1443 tree di_ftype_di_v4hi_v4hi
1444 = build_function_type_list (long_long_unsigned_type_node,
1445 long_long_unsigned_type_node,
1446 V4HI_type_node, V4HI_type_node,
1447 NULL_TREE);
1448
1449 tree di_ftype_v4hi_v4hi
1450 = build_function_type_list (long_long_unsigned_type_node,
1451 V4HI_type_node,V4HI_type_node,
1452 NULL_TREE);
1453
1454 tree v2si_ftype_v2si_v4hi_v4hi
1455 = build_function_type_list (V2SI_type_node,
1456 V2SI_type_node, V4HI_type_node,
1457 V4HI_type_node, NULL_TREE);
1458
1459 tree v2si_ftype_v2si_v8qi_v8qi
1460 = build_function_type_list (V2SI_type_node,
1461 V2SI_type_node, V8QI_type_node,
1462 V8QI_type_node, NULL_TREE);
1463
1464 tree di_ftype_di_v2si_v2si
1465 = build_function_type_list (long_long_unsigned_type_node,
1466 long_long_unsigned_type_node,
1467 V2SI_type_node, V2SI_type_node,
1468 NULL_TREE);
1469
1470 tree di_ftype_di_di_int
1471 = build_function_type_list (long_long_unsigned_type_node,
1472 long_long_unsigned_type_node,
1473 long_long_unsigned_type_node,
1474 integer_type_node, NULL_TREE);
1475
1476 tree void_ftype_int
1477 = build_function_type_list (void_type_node,
1478 integer_type_node, NULL_TREE);
1479
1480 tree v8qi_ftype_char
1481 = build_function_type_list (V8QI_type_node,
1482 signed_char_type_node, NULL_TREE);
1483
1484 tree v4hi_ftype_short
1485 = build_function_type_list (V4HI_type_node,
1486 short_integer_type_node, NULL_TREE);
1487
1488 tree v2si_ftype_int
1489 = build_function_type_list (V2SI_type_node,
1490 integer_type_node, NULL_TREE);
1491
1492 /* Normal vector binops. */
1493 tree v8qi_ftype_v8qi_v8qi
1494 = build_function_type_list (V8QI_type_node,
1495 V8QI_type_node, V8QI_type_node, NULL_TREE);
1496 tree v4hi_ftype_v4hi_v4hi
1497 = build_function_type_list (V4HI_type_node,
1498 V4HI_type_node,V4HI_type_node, NULL_TREE);
1499 tree v2si_ftype_v2si_v2si
1500 = build_function_type_list (V2SI_type_node,
1501 V2SI_type_node, V2SI_type_node, NULL_TREE);
1502 tree di_ftype_di_di
1503 = build_function_type_list (long_long_unsigned_type_node,
1504 long_long_unsigned_type_node,
1505 long_long_unsigned_type_node,
1506 NULL_TREE);
1507
1508 /* Add all builtins that are more or less simple operations on two
1509 operands. */
1510 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
1511 {
1512 /* Use one of the operands; the target can have a different mode for
1513 mask-generating compares. */
1514 machine_mode mode;
1515 tree type;
1516
23b9ccbe
MW
1517 if (d->name == 0 ||
1518 !(ARM_FSET_HAS_CPU1 (d->features, FL_IWMMXT) ||
1519 ARM_FSET_HAS_CPU1 (d->features, FL_IWMMXT2)))
33857df2
JG
1520 continue;
1521
1522 mode = insn_data[d->icode].operand[1].mode;
1523
1524 switch (mode)
1525 {
1526 case V8QImode:
1527 type = v8qi_ftype_v8qi_v8qi;
1528 break;
1529 case V4HImode:
1530 type = v4hi_ftype_v4hi_v4hi;
1531 break;
1532 case V2SImode:
1533 type = v2si_ftype_v2si_v2si;
1534 break;
1535 case DImode:
1536 type = di_ftype_di_di;
1537 break;
1538
1539 default:
1540 gcc_unreachable ();
1541 }
1542
23b9ccbe 1543 def_mbuiltin (d->features, d->name, type, d->code);
33857df2
JG
1544 }
1545
1546 /* Add the remaining MMX insns with somewhat more complicated types. */
1547#define iwmmx_mbuiltin(NAME, TYPE, CODE) \
23b9ccbe
MW
1548 def_mbuiltin (ARM_FSET_MAKE_CPU1 (FL_IWMMXT), "__builtin_arm_" NAME, \
1549 (TYPE), ARM_BUILTIN_ ## CODE)
33857df2
JG
1550
1551#define iwmmx2_mbuiltin(NAME, TYPE, CODE) \
23b9ccbe
MW
1552 def_mbuiltin (ARM_FSET_MAKE_CPU1 (FL_IWMMXT2), "__builtin_arm_" NAME, \
1553 (TYPE), ARM_BUILTIN_ ## CODE)
33857df2
JG
1554
1555 iwmmx_mbuiltin ("wzero", di_ftype_void, WZERO);
1556 iwmmx_mbuiltin ("setwcgr0", void_ftype_int, SETWCGR0);
1557 iwmmx_mbuiltin ("setwcgr1", void_ftype_int, SETWCGR1);
1558 iwmmx_mbuiltin ("setwcgr2", void_ftype_int, SETWCGR2);
1559 iwmmx_mbuiltin ("setwcgr3", void_ftype_int, SETWCGR3);
1560 iwmmx_mbuiltin ("getwcgr0", int_ftype_void, GETWCGR0);
1561 iwmmx_mbuiltin ("getwcgr1", int_ftype_void, GETWCGR1);
1562 iwmmx_mbuiltin ("getwcgr2", int_ftype_void, GETWCGR2);
1563 iwmmx_mbuiltin ("getwcgr3", int_ftype_void, GETWCGR3);
1564
1565 iwmmx_mbuiltin ("wsllh", v4hi_ftype_v4hi_di, WSLLH);
1566 iwmmx_mbuiltin ("wsllw", v2si_ftype_v2si_di, WSLLW);
1567 iwmmx_mbuiltin ("wslld", di_ftype_di_di, WSLLD);
1568 iwmmx_mbuiltin ("wsllhi", v4hi_ftype_v4hi_int, WSLLHI);
1569 iwmmx_mbuiltin ("wsllwi", v2si_ftype_v2si_int, WSLLWI);
1570 iwmmx_mbuiltin ("wslldi", di_ftype_di_int, WSLLDI);
1571
1572 iwmmx_mbuiltin ("wsrlh", v4hi_ftype_v4hi_di, WSRLH);
1573 iwmmx_mbuiltin ("wsrlw", v2si_ftype_v2si_di, WSRLW);
1574 iwmmx_mbuiltin ("wsrld", di_ftype_di_di, WSRLD);
1575 iwmmx_mbuiltin ("wsrlhi", v4hi_ftype_v4hi_int, WSRLHI);
1576 iwmmx_mbuiltin ("wsrlwi", v2si_ftype_v2si_int, WSRLWI);
1577 iwmmx_mbuiltin ("wsrldi", di_ftype_di_int, WSRLDI);
1578
1579 iwmmx_mbuiltin ("wsrah", v4hi_ftype_v4hi_di, WSRAH);
1580 iwmmx_mbuiltin ("wsraw", v2si_ftype_v2si_di, WSRAW);
1581 iwmmx_mbuiltin ("wsrad", di_ftype_di_di, WSRAD);
1582 iwmmx_mbuiltin ("wsrahi", v4hi_ftype_v4hi_int, WSRAHI);
1583 iwmmx_mbuiltin ("wsrawi", v2si_ftype_v2si_int, WSRAWI);
1584 iwmmx_mbuiltin ("wsradi", di_ftype_di_int, WSRADI);
1585
1586 iwmmx_mbuiltin ("wrorh", v4hi_ftype_v4hi_di, WRORH);
1587 iwmmx_mbuiltin ("wrorw", v2si_ftype_v2si_di, WRORW);
1588 iwmmx_mbuiltin ("wrord", di_ftype_di_di, WRORD);
1589 iwmmx_mbuiltin ("wrorhi", v4hi_ftype_v4hi_int, WRORHI);
1590 iwmmx_mbuiltin ("wrorwi", v2si_ftype_v2si_int, WRORWI);
1591 iwmmx_mbuiltin ("wrordi", di_ftype_di_int, WRORDI);
1592
1593 iwmmx_mbuiltin ("wshufh", v4hi_ftype_v4hi_int, WSHUFH);
1594
1595 iwmmx_mbuiltin ("wsadb", v2si_ftype_v2si_v8qi_v8qi, WSADB);
1596 iwmmx_mbuiltin ("wsadh", v2si_ftype_v2si_v4hi_v4hi, WSADH);
1597 iwmmx_mbuiltin ("wmadds", v2si_ftype_v4hi_v4hi, WMADDS);
1598 iwmmx2_mbuiltin ("wmaddsx", v2si_ftype_v4hi_v4hi, WMADDSX);
1599 iwmmx2_mbuiltin ("wmaddsn", v2si_ftype_v4hi_v4hi, WMADDSN);
1600 iwmmx_mbuiltin ("wmaddu", v2si_ftype_v4hi_v4hi, WMADDU);
1601 iwmmx2_mbuiltin ("wmaddux", v2si_ftype_v4hi_v4hi, WMADDUX);
1602 iwmmx2_mbuiltin ("wmaddun", v2si_ftype_v4hi_v4hi, WMADDUN);
1603 iwmmx_mbuiltin ("wsadbz", v2si_ftype_v8qi_v8qi, WSADBZ);
1604 iwmmx_mbuiltin ("wsadhz", v2si_ftype_v4hi_v4hi, WSADHZ);
1605
1606 iwmmx_mbuiltin ("textrmsb", int_ftype_v8qi_int, TEXTRMSB);
1607 iwmmx_mbuiltin ("textrmsh", int_ftype_v4hi_int, TEXTRMSH);
1608 iwmmx_mbuiltin ("textrmsw", int_ftype_v2si_int, TEXTRMSW);
1609 iwmmx_mbuiltin ("textrmub", int_ftype_v8qi_int, TEXTRMUB);
1610 iwmmx_mbuiltin ("textrmuh", int_ftype_v4hi_int, TEXTRMUH);
1611 iwmmx_mbuiltin ("textrmuw", int_ftype_v2si_int, TEXTRMUW);
1612 iwmmx_mbuiltin ("tinsrb", v8qi_ftype_v8qi_int_int, TINSRB);
1613 iwmmx_mbuiltin ("tinsrh", v4hi_ftype_v4hi_int_int, TINSRH);
1614 iwmmx_mbuiltin ("tinsrw", v2si_ftype_v2si_int_int, TINSRW);
1615
1616 iwmmx_mbuiltin ("waccb", di_ftype_v8qi, WACCB);
1617 iwmmx_mbuiltin ("wacch", di_ftype_v4hi, WACCH);
1618 iwmmx_mbuiltin ("waccw", di_ftype_v2si, WACCW);
1619
1620 iwmmx_mbuiltin ("tmovmskb", int_ftype_v8qi, TMOVMSKB);
1621 iwmmx_mbuiltin ("tmovmskh", int_ftype_v4hi, TMOVMSKH);
1622 iwmmx_mbuiltin ("tmovmskw", int_ftype_v2si, TMOVMSKW);
1623
1624 iwmmx2_mbuiltin ("waddbhusm", v8qi_ftype_v4hi_v8qi, WADDBHUSM);
1625 iwmmx2_mbuiltin ("waddbhusl", v8qi_ftype_v4hi_v8qi, WADDBHUSL);
1626
1627 iwmmx_mbuiltin ("wpackhss", v8qi_ftype_v4hi_v4hi, WPACKHSS);
1628 iwmmx_mbuiltin ("wpackhus", v8qi_ftype_v4hi_v4hi, WPACKHUS);
1629 iwmmx_mbuiltin ("wpackwus", v4hi_ftype_v2si_v2si, WPACKWUS);
1630 iwmmx_mbuiltin ("wpackwss", v4hi_ftype_v2si_v2si, WPACKWSS);
1631 iwmmx_mbuiltin ("wpackdus", v2si_ftype_di_di, WPACKDUS);
1632 iwmmx_mbuiltin ("wpackdss", v2si_ftype_di_di, WPACKDSS);
1633
1634 iwmmx_mbuiltin ("wunpckehub", v4hi_ftype_v8qi, WUNPCKEHUB);
1635 iwmmx_mbuiltin ("wunpckehuh", v2si_ftype_v4hi, WUNPCKEHUH);
1636 iwmmx_mbuiltin ("wunpckehuw", di_ftype_v2si, WUNPCKEHUW);
1637 iwmmx_mbuiltin ("wunpckehsb", v4hi_ftype_v8qi, WUNPCKEHSB);
1638 iwmmx_mbuiltin ("wunpckehsh", v2si_ftype_v4hi, WUNPCKEHSH);
1639 iwmmx_mbuiltin ("wunpckehsw", di_ftype_v2si, WUNPCKEHSW);
1640 iwmmx_mbuiltin ("wunpckelub", v4hi_ftype_v8qi, WUNPCKELUB);
1641 iwmmx_mbuiltin ("wunpckeluh", v2si_ftype_v4hi, WUNPCKELUH);
1642 iwmmx_mbuiltin ("wunpckeluw", di_ftype_v2si, WUNPCKELUW);
1643 iwmmx_mbuiltin ("wunpckelsb", v4hi_ftype_v8qi, WUNPCKELSB);
1644 iwmmx_mbuiltin ("wunpckelsh", v2si_ftype_v4hi, WUNPCKELSH);
1645 iwmmx_mbuiltin ("wunpckelsw", di_ftype_v2si, WUNPCKELSW);
1646
1647 iwmmx_mbuiltin ("wmacs", di_ftype_di_v4hi_v4hi, WMACS);
1648 iwmmx_mbuiltin ("wmacsz", di_ftype_v4hi_v4hi, WMACSZ);
1649 iwmmx_mbuiltin ("wmacu", di_ftype_di_v4hi_v4hi, WMACU);
1650 iwmmx_mbuiltin ("wmacuz", di_ftype_v4hi_v4hi, WMACUZ);
1651
1652 iwmmx_mbuiltin ("walign", v8qi_ftype_v8qi_v8qi_int, WALIGNI);
1653 iwmmx_mbuiltin ("tmia", di_ftype_di_int_int, TMIA);
1654 iwmmx_mbuiltin ("tmiaph", di_ftype_di_int_int, TMIAPH);
1655 iwmmx_mbuiltin ("tmiabb", di_ftype_di_int_int, TMIABB);
1656 iwmmx_mbuiltin ("tmiabt", di_ftype_di_int_int, TMIABT);
1657 iwmmx_mbuiltin ("tmiatb", di_ftype_di_int_int, TMIATB);
1658 iwmmx_mbuiltin ("tmiatt", di_ftype_di_int_int, TMIATT);
1659
1660 iwmmx2_mbuiltin ("wabsb", v8qi_ftype_v8qi, WABSB);
1661 iwmmx2_mbuiltin ("wabsh", v4hi_ftype_v4hi, WABSH);
1662 iwmmx2_mbuiltin ("wabsw", v2si_ftype_v2si, WABSW);
1663
1664 iwmmx2_mbuiltin ("wqmiabb", v2si_ftype_v2si_v4hi_v4hi, WQMIABB);
1665 iwmmx2_mbuiltin ("wqmiabt", v2si_ftype_v2si_v4hi_v4hi, WQMIABT);
1666 iwmmx2_mbuiltin ("wqmiatb", v2si_ftype_v2si_v4hi_v4hi, WQMIATB);
1667 iwmmx2_mbuiltin ("wqmiatt", v2si_ftype_v2si_v4hi_v4hi, WQMIATT);
1668
1669 iwmmx2_mbuiltin ("wqmiabbn", v2si_ftype_v2si_v4hi_v4hi, WQMIABBN);
1670 iwmmx2_mbuiltin ("wqmiabtn", v2si_ftype_v2si_v4hi_v4hi, WQMIABTN);
1671 iwmmx2_mbuiltin ("wqmiatbn", v2si_ftype_v2si_v4hi_v4hi, WQMIATBN);
1672 iwmmx2_mbuiltin ("wqmiattn", v2si_ftype_v2si_v4hi_v4hi, WQMIATTN);
1673
1674 iwmmx2_mbuiltin ("wmiabb", di_ftype_di_v4hi_v4hi, WMIABB);
1675 iwmmx2_mbuiltin ("wmiabt", di_ftype_di_v4hi_v4hi, WMIABT);
1676 iwmmx2_mbuiltin ("wmiatb", di_ftype_di_v4hi_v4hi, WMIATB);
1677 iwmmx2_mbuiltin ("wmiatt", di_ftype_di_v4hi_v4hi, WMIATT);
1678
1679 iwmmx2_mbuiltin ("wmiabbn", di_ftype_di_v4hi_v4hi, WMIABBN);
1680 iwmmx2_mbuiltin ("wmiabtn", di_ftype_di_v4hi_v4hi, WMIABTN);
1681 iwmmx2_mbuiltin ("wmiatbn", di_ftype_di_v4hi_v4hi, WMIATBN);
1682 iwmmx2_mbuiltin ("wmiattn", di_ftype_di_v4hi_v4hi, WMIATTN);
1683
1684 iwmmx2_mbuiltin ("wmiawbb", di_ftype_di_v2si_v2si, WMIAWBB);
1685 iwmmx2_mbuiltin ("wmiawbt", di_ftype_di_v2si_v2si, WMIAWBT);
1686 iwmmx2_mbuiltin ("wmiawtb", di_ftype_di_v2si_v2si, WMIAWTB);
1687 iwmmx2_mbuiltin ("wmiawtt", di_ftype_di_v2si_v2si, WMIAWTT);
1688
1689 iwmmx2_mbuiltin ("wmiawbbn", di_ftype_di_v2si_v2si, WMIAWBBN);
1690 iwmmx2_mbuiltin ("wmiawbtn", di_ftype_di_v2si_v2si, WMIAWBTN);
1691 iwmmx2_mbuiltin ("wmiawtbn", di_ftype_di_v2si_v2si, WMIAWTBN);
1692 iwmmx2_mbuiltin ("wmiawttn", di_ftype_di_v2si_v2si, WMIAWTTN);
1693
1694 iwmmx2_mbuiltin ("wmerge", di_ftype_di_di_int, WMERGE);
1695
1696 iwmmx_mbuiltin ("tbcstb", v8qi_ftype_char, TBCSTB);
1697 iwmmx_mbuiltin ("tbcsth", v4hi_ftype_short, TBCSTH);
1698 iwmmx_mbuiltin ("tbcstw", v2si_ftype_int, TBCSTW);
1699
1700#undef iwmmx_mbuiltin
1701#undef iwmmx2_mbuiltin
1702}
1703
1704static void
1705arm_init_fp16_builtins (void)
1706{
50399bb1
AL
1707 arm_simd_floatHF_type_node = make_node (REAL_TYPE);
1708 TYPE_PRECISION (arm_simd_floatHF_type_node) = GET_MODE_PRECISION (HFmode);
1709 layout_type (arm_simd_floatHF_type_node);
1710 if (arm_fp16_format)
1711 (*lang_hooks.types.register_builtin_type) (arm_simd_floatHF_type_node,
1712 "__fp16");
33857df2
JG
1713}
1714
1715static void
1716arm_init_crc32_builtins ()
1717{
1718 tree si_ftype_si_qi
1719 = build_function_type_list (unsigned_intSI_type_node,
1720 unsigned_intSI_type_node,
1721 unsigned_intQI_type_node, NULL_TREE);
1722 tree si_ftype_si_hi
1723 = build_function_type_list (unsigned_intSI_type_node,
1724 unsigned_intSI_type_node,
1725 unsigned_intHI_type_node, NULL_TREE);
1726 tree si_ftype_si_si
1727 = build_function_type_list (unsigned_intSI_type_node,
1728 unsigned_intSI_type_node,
1729 unsigned_intSI_type_node, NULL_TREE);
1730
1731 arm_builtin_decls[ARM_BUILTIN_CRC32B]
1732 = add_builtin_function ("__builtin_arm_crc32b", si_ftype_si_qi,
1733 ARM_BUILTIN_CRC32B, BUILT_IN_MD, NULL, NULL_TREE);
1734 arm_builtin_decls[ARM_BUILTIN_CRC32H]
1735 = add_builtin_function ("__builtin_arm_crc32h", si_ftype_si_hi,
1736 ARM_BUILTIN_CRC32H, BUILT_IN_MD, NULL, NULL_TREE);
1737 arm_builtin_decls[ARM_BUILTIN_CRC32W]
1738 = add_builtin_function ("__builtin_arm_crc32w", si_ftype_si_si,
1739 ARM_BUILTIN_CRC32W, BUILT_IN_MD, NULL, NULL_TREE);
1740 arm_builtin_decls[ARM_BUILTIN_CRC32CB]
1741 = add_builtin_function ("__builtin_arm_crc32cb", si_ftype_si_qi,
1742 ARM_BUILTIN_CRC32CB, BUILT_IN_MD, NULL, NULL_TREE);
1743 arm_builtin_decls[ARM_BUILTIN_CRC32CH]
1744 = add_builtin_function ("__builtin_arm_crc32ch", si_ftype_si_hi,
1745 ARM_BUILTIN_CRC32CH, BUILT_IN_MD, NULL, NULL_TREE);
1746 arm_builtin_decls[ARM_BUILTIN_CRC32CW]
1747 = add_builtin_function ("__builtin_arm_crc32cw", si_ftype_si_si,
1748 ARM_BUILTIN_CRC32CW, BUILT_IN_MD, NULL, NULL_TREE);
1749}
1750
1751void
1752arm_init_builtins (void)
1753{
1754 if (TARGET_REALLY_IWMMXT)
1755 arm_init_iwmmxt_builtins ();
1756
50399bb1
AL
1757 /* This creates the arm_simd_floatHF_type_node so must come before
1758 arm_init_neon_builtins which uses it. */
1759 arm_init_fp16_builtins ();
1760
33857df2
JG
1761 if (TARGET_NEON)
1762 arm_init_neon_builtins ();
1763
33857df2
JG
1764 if (TARGET_CRC32)
1765 arm_init_crc32_builtins ();
1766
1767 if (TARGET_VFP && TARGET_HARD_FLOAT)
1768 {
1769 tree ftype_set_fpscr
1770 = build_function_type_list (void_type_node, unsigned_type_node, NULL);
1771 tree ftype_get_fpscr
1772 = build_function_type_list (unsigned_type_node, NULL);
1773
1774 arm_builtin_decls[ARM_BUILTIN_GET_FPSCR]
1775 = add_builtin_function ("__builtin_arm_ldfscr", ftype_get_fpscr,
1776 ARM_BUILTIN_GET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE);
1777 arm_builtin_decls[ARM_BUILTIN_SET_FPSCR]
1778 = add_builtin_function ("__builtin_arm_stfscr", ftype_set_fpscr,
1779 ARM_BUILTIN_SET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE);
1780 }
1781}
1782
1783/* Return the ARM builtin for CODE. */
1784
1785tree
1786arm_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
1787{
1788 if (code >= ARM_BUILTIN_MAX)
1789 return error_mark_node;
1790
1791 return arm_builtin_decls[code];
1792}
1793
1794/* Errors in the source file can cause expand_expr to return const0_rtx
1795 where we expect a vector. To avoid crashing, use one of the vector
1796 clear instructions. */
1797
1798static rtx
1799safe_vector_operand (rtx x, machine_mode mode)
1800{
1801 if (x != const0_rtx)
1802 return x;
1803 x = gen_reg_rtx (mode);
1804
1805 emit_insn (gen_iwmmxt_clrdi (mode == DImode ? x
1806 : gen_rtx_SUBREG (DImode, x, 0)));
1807 return x;
1808}
1809
1810/* Function to expand ternary builtins. */
1811static rtx
1812arm_expand_ternop_builtin (enum insn_code icode,
1813 tree exp, rtx target)
1814{
1815 rtx pat;
1816 tree arg0 = CALL_EXPR_ARG (exp, 0);
1817 tree arg1 = CALL_EXPR_ARG (exp, 1);
1818 tree arg2 = CALL_EXPR_ARG (exp, 2);
1819
1820 rtx op0 = expand_normal (arg0);
1821 rtx op1 = expand_normal (arg1);
1822 rtx op2 = expand_normal (arg2);
1823 rtx op3 = NULL_RTX;
1824
1825 /* The sha1c, sha1p, sha1m crypto builtins require a different vec_select
1826 lane operand depending on endianness. */
1827 bool builtin_sha1cpm_p = false;
1828
1829 if (insn_data[icode].n_operands == 5)
1830 {
1831 gcc_assert (icode == CODE_FOR_crypto_sha1c
1832 || icode == CODE_FOR_crypto_sha1p
1833 || icode == CODE_FOR_crypto_sha1m);
1834 builtin_sha1cpm_p = true;
1835 }
1836 machine_mode tmode = insn_data[icode].operand[0].mode;
1837 machine_mode mode0 = insn_data[icode].operand[1].mode;
1838 machine_mode mode1 = insn_data[icode].operand[2].mode;
1839 machine_mode mode2 = insn_data[icode].operand[3].mode;
1840
1841
1842 if (VECTOR_MODE_P (mode0))
1843 op0 = safe_vector_operand (op0, mode0);
1844 if (VECTOR_MODE_P (mode1))
1845 op1 = safe_vector_operand (op1, mode1);
1846 if (VECTOR_MODE_P (mode2))
1847 op2 = safe_vector_operand (op2, mode2);
1848
1849 if (! target
1850 || GET_MODE (target) != tmode
1851 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
1852 target = gen_reg_rtx (tmode);
1853
1854 gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode)
1855 && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode)
1856 && (GET_MODE (op2) == mode2 || GET_MODE (op2) == VOIDmode));
1857
1858 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
1859 op0 = copy_to_mode_reg (mode0, op0);
1860 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
1861 op1 = copy_to_mode_reg (mode1, op1);
1862 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
1863 op2 = copy_to_mode_reg (mode2, op2);
1864 if (builtin_sha1cpm_p)
1865 op3 = GEN_INT (TARGET_BIG_END ? 1 : 0);
1866
1867 if (builtin_sha1cpm_p)
1868 pat = GEN_FCN (icode) (target, op0, op1, op2, op3);
1869 else
1870 pat = GEN_FCN (icode) (target, op0, op1, op2);
1871 if (! pat)
1872 return 0;
1873 emit_insn (pat);
1874 return target;
1875}
1876
1877/* Subroutine of arm_expand_builtin to take care of binop insns. */
1878
1879static rtx
1880arm_expand_binop_builtin (enum insn_code icode,
1881 tree exp, rtx target)
1882{
1883 rtx pat;
1884 tree arg0 = CALL_EXPR_ARG (exp, 0);
1885 tree arg1 = CALL_EXPR_ARG (exp, 1);
1886 rtx op0 = expand_normal (arg0);
1887 rtx op1 = expand_normal (arg1);
1888 machine_mode tmode = insn_data[icode].operand[0].mode;
1889 machine_mode mode0 = insn_data[icode].operand[1].mode;
1890 machine_mode mode1 = insn_data[icode].operand[2].mode;
1891
1892 if (VECTOR_MODE_P (mode0))
1893 op0 = safe_vector_operand (op0, mode0);
1894 if (VECTOR_MODE_P (mode1))
1895 op1 = safe_vector_operand (op1, mode1);
1896
1897 if (! target
1898 || GET_MODE (target) != tmode
1899 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
1900 target = gen_reg_rtx (tmode);
1901
1902 gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode)
1903 && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode));
1904
1905 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
1906 op0 = copy_to_mode_reg (mode0, op0);
1907 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
1908 op1 = copy_to_mode_reg (mode1, op1);
1909
1910 pat = GEN_FCN (icode) (target, op0, op1);
1911 if (! pat)
1912 return 0;
1913 emit_insn (pat);
1914 return target;
1915}
1916
1917/* Subroutine of arm_expand_builtin to take care of unop insns. */
1918
1919static rtx
1920arm_expand_unop_builtin (enum insn_code icode,
1921 tree exp, rtx target, int do_load)
1922{
1923 rtx pat;
1924 tree arg0 = CALL_EXPR_ARG (exp, 0);
1925 rtx op0 = expand_normal (arg0);
1926 rtx op1 = NULL_RTX;
1927 machine_mode tmode = insn_data[icode].operand[0].mode;
1928 machine_mode mode0 = insn_data[icode].operand[1].mode;
1929 bool builtin_sha1h_p = false;
1930
1931 if (insn_data[icode].n_operands == 3)
1932 {
1933 gcc_assert (icode == CODE_FOR_crypto_sha1h);
1934 builtin_sha1h_p = true;
1935 }
1936
1937 if (! target
1938 || GET_MODE (target) != tmode
1939 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
1940 target = gen_reg_rtx (tmode);
1941 if (do_load)
1942 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
1943 else
1944 {
1945 if (VECTOR_MODE_P (mode0))
1946 op0 = safe_vector_operand (op0, mode0);
1947
1948 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
1949 op0 = copy_to_mode_reg (mode0, op0);
1950 }
1951 if (builtin_sha1h_p)
1952 op1 = GEN_INT (TARGET_BIG_END ? 1 : 0);
1953
1954 if (builtin_sha1h_p)
1955 pat = GEN_FCN (icode) (target, op0, op1);
1956 else
1957 pat = GEN_FCN (icode) (target, op0);
1958 if (! pat)
1959 return 0;
1960 emit_insn (pat);
1961 return target;
1962}
1963
1964typedef enum {
1965 NEON_ARG_COPY_TO_REG,
1966 NEON_ARG_CONSTANT,
eaa80f64 1967 NEON_ARG_LANE_INDEX,
2f7d18dd 1968 NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX,
33857df2
JG
1969 NEON_ARG_MEMORY,
1970 NEON_ARG_STOP
1971} builtin_arg;
1972
1973#define NEON_MAX_BUILTIN_ARGS 5
1974
1975/* EXP is a pointer argument to a Neon load or store intrinsic. Derive
1976 and return an expression for the accessed memory.
1977
1978 The intrinsic function operates on a block of registers that has
1979 mode REG_MODE. This block contains vectors of type TYPE_MODE. The
1980 function references the memory at EXP of type TYPE and in mode
1981 MEM_MODE; this mode may be BLKmode if no more suitable mode is
1982 available. */
1983
1984static tree
1985neon_dereference_pointer (tree exp, tree type, machine_mode mem_mode,
1986 machine_mode reg_mode,
bd79363c 1987 machine_mode vector_mode)
33857df2
JG
1988{
1989 HOST_WIDE_INT reg_size, vector_size, nvectors, nelems;
1990 tree elem_type, upper_bound, array_type;
1991
1992 /* Work out the size of the register block in bytes. */
1993 reg_size = GET_MODE_SIZE (reg_mode);
1994
1995 /* Work out the size of each vector in bytes. */
bd79363c 1996 vector_size = GET_MODE_SIZE (vector_mode);
33857df2
JG
1997
1998 /* Work out how many vectors there are. */
1999 gcc_assert (reg_size % vector_size == 0);
2000 nvectors = reg_size / vector_size;
2001
2002 /* Work out the type of each element. */
2003 gcc_assert (POINTER_TYPE_P (type));
2004 elem_type = TREE_TYPE (type);
2005
2006 /* Work out how many elements are being loaded or stored.
2007 MEM_MODE == REG_MODE implies a one-to-one mapping between register
2008 and memory elements; anything else implies a lane load or store. */
2009 if (mem_mode == reg_mode)
2010 nelems = vector_size * nvectors / int_size_in_bytes (elem_type);
2011 else
2012 nelems = nvectors;
2013
2014 /* Create a type that describes the full access. */
2015 upper_bound = build_int_cst (size_type_node, nelems - 1);
2016 array_type = build_array_type (elem_type, build_index_type (upper_bound));
2017
2018 /* Dereference EXP using that type. */
2019 return fold_build2 (MEM_REF, array_type, exp,
2020 build_int_cst (build_pointer_type (array_type), 0));
2021}
2022
2023/* Expand a Neon builtin. */
2024static rtx
bd79363c 2025arm_expand_neon_args (rtx target, machine_mode map_mode, int fcode,
2f7d18dd
CB
2026 int icode, int have_retval, tree exp,
2027 builtin_arg *args)
33857df2 2028{
33857df2 2029 rtx pat;
bd79363c
JG
2030 tree arg[SIMD_MAX_BUILTIN_ARGS];
2031 rtx op[SIMD_MAX_BUILTIN_ARGS];
33857df2 2032 machine_mode tmode = insn_data[icode].operand[0].mode;
bd79363c
JG
2033 machine_mode mode[SIMD_MAX_BUILTIN_ARGS];
2034 tree formals;
33857df2 2035 int argc = 0;
33857df2
JG
2036
2037 if (have_retval
2038 && (!target
2039 || GET_MODE (target) != tmode
2040 || !(*insn_data[icode].operand[0].predicate) (target, tmode)))
2041 target = gen_reg_rtx (tmode);
2042
33857df2
JG
2043 formals = TYPE_ARG_TYPES (TREE_TYPE (arm_builtin_decls[fcode]));
2044
2045 for (;;)
2046 {
2f7d18dd 2047 builtin_arg thisarg = args[argc];
33857df2
JG
2048
2049 if (thisarg == NEON_ARG_STOP)
bd79363c 2050 break;
33857df2 2051 else
bd79363c
JG
2052 {
2053 int opno = argc + have_retval;
2054 arg[argc] = CALL_EXPR_ARG (exp, argc);
2055 mode[argc] = insn_data[icode].operand[opno].mode;
33857df2
JG
2056 if (thisarg == NEON_ARG_MEMORY)
2057 {
bd79363c
JG
2058 machine_mode other_mode
2059 = insn_data[icode].operand[1 - opno].mode;
2060 arg[argc] = neon_dereference_pointer (arg[argc],
2061 TREE_VALUE (formals),
33857df2 2062 mode[argc], other_mode,
bd79363c 2063 map_mode);
33857df2
JG
2064 }
2065
2066 /* Use EXPAND_MEMORY for NEON_ARG_MEMORY to ensure a MEM_P
2067 be returned. */
2068 op[argc] = expand_expr (arg[argc], NULL_RTX, VOIDmode,
2069 (thisarg == NEON_ARG_MEMORY
2070 ? EXPAND_MEMORY : EXPAND_NORMAL));
2071
bd79363c
JG
2072 switch (thisarg)
2073 {
2074 case NEON_ARG_COPY_TO_REG:
2075 if (POINTER_TYPE_P (TREE_TYPE (arg[argc])))
2076 op[argc] = convert_memory_address (Pmode, op[argc]);
2077 /*gcc_assert (GET_MODE (op[argc]) == mode[argc]); */
2078 if (!(*insn_data[icode].operand[opno].predicate)
2079 (op[argc], mode[argc]))
2080 op[argc] = copy_to_mode_reg (mode[argc], op[argc]);
2081 break;
33857df2 2082
2f7d18dd
CB
2083 case NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX:
2084 gcc_assert (argc > 1);
2085 if (CONST_INT_P (op[argc]))
2086 {
2087 neon_lane_bounds (op[argc], 0,
2088 GET_MODE_NUNITS (map_mode), exp);
2089 /* Keep to GCC-vector-extension lane indices in the RTL. */
2090 op[argc] =
2091 GEN_INT (NEON_ENDIAN_LANE_N (map_mode, INTVAL (op[argc])));
2092 }
2093 goto constant_arg;
2094
eaa80f64
AL
2095 case NEON_ARG_LANE_INDEX:
2096 /* Previous argument must be a vector, which this indexes. */
2097 gcc_assert (argc > 0);
2098 if (CONST_INT_P (op[argc]))
2099 {
2100 enum machine_mode vmode = mode[argc - 1];
2101 neon_lane_bounds (op[argc], 0, GET_MODE_NUNITS (vmode), exp);
2102 }
2103 /* Fall through - if the lane index isn't a constant then
2104 the next case will error. */
2f7d18dd 2105
bd79363c 2106 case NEON_ARG_CONSTANT:
2f7d18dd 2107constant_arg:
bd79363c
JG
2108 if (!(*insn_data[icode].operand[opno].predicate)
2109 (op[argc], mode[argc]))
2f7d18dd
CB
2110 {
2111 error ("%Kargument %d must be a constant immediate",
2112 exp, argc + 1);
2113 return const0_rtx;
2114 }
bd79363c 2115 break;
2f7d18dd 2116
33857df2
JG
2117 case NEON_ARG_MEMORY:
2118 /* Check if expand failed. */
2119 if (op[argc] == const0_rtx)
2120 return 0;
2121 gcc_assert (MEM_P (op[argc]));
2122 PUT_MODE (op[argc], mode[argc]);
2123 /* ??? arm_neon.h uses the same built-in functions for signed
2124 and unsigned accesses, casting where necessary. This isn't
2125 alias safe. */
2126 set_mem_alias_set (op[argc], 0);
2127 if (!(*insn_data[icode].operand[opno].predicate)
bd79363c 2128 (op[argc], mode[argc]))
33857df2
JG
2129 op[argc] = (replace_equiv_address
2130 (op[argc], force_reg (Pmode, XEXP (op[argc], 0))));
2131 break;
2132
bd79363c
JG
2133 case NEON_ARG_STOP:
2134 gcc_unreachable ();
2135 }
33857df2 2136
bd79363c
JG
2137 argc++;
2138 }
33857df2
JG
2139 }
2140
33857df2
JG
2141 if (have_retval)
2142 switch (argc)
2143 {
2144 case 1:
2145 pat = GEN_FCN (icode) (target, op[0]);
2146 break;
2147
2148 case 2:
2149 pat = GEN_FCN (icode) (target, op[0], op[1]);
2150 break;
2151
2152 case 3:
2153 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
2154 break;
2155
2156 case 4:
2157 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
2158 break;
2159
2160 case 5:
2161 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4]);
2162 break;
2163
2164 default:
2165 gcc_unreachable ();
2166 }
2167 else
2168 switch (argc)
2169 {
2170 case 1:
2171 pat = GEN_FCN (icode) (op[0]);
2172 break;
2173
2174 case 2:
2175 pat = GEN_FCN (icode) (op[0], op[1]);
2176 break;
2177
2178 case 3:
2179 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
2180 break;
2181
2182 case 4:
2183 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
2184 break;
2185
2186 case 5:
2187 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
bd79363c 2188 break;
33857df2
JG
2189
2190 default:
2191 gcc_unreachable ();
2192 }
2193
2194 if (!pat)
2195 return 0;
2196
2197 emit_insn (pat);
2198
2199 return target;
2200}
2201
6d60b856
AL
2202/* Expand a Neon builtin, i.e. those registered only if TARGET_NEON holds.
2203 Most of these are "special" because they don't have symbolic
33857df2
JG
2204 constants defined per-instruction or per instruction-variant. Instead, the
2205 required info is looked up in the table neon_builtin_data. */
2206static rtx
2207arm_expand_neon_builtin (int fcode, tree exp, rtx target)
2208{
6d60b856
AL
2209 if (fcode == ARM_BUILTIN_NEON_LANE_CHECK)
2210 {
2211 /* Builtin is only to check bounds of the lane passed to some intrinsics
2212 that are implemented with gcc vector extensions in arm_neon.h. */
2213
2214 tree nlanes = CALL_EXPR_ARG (exp, 0);
2215 gcc_assert (TREE_CODE (nlanes) == INTEGER_CST);
2216 rtx lane_idx = expand_normal (CALL_EXPR_ARG (exp, 1));
2217 if (CONST_INT_P (lane_idx))
2218 neon_lane_bounds (lane_idx, 0, TREE_INT_CST_LOW (nlanes), exp);
2219 else
2220 error ("%Klane index must be a constant immediate", exp);
2221 /* Don't generate any RTL. */
2222 return const0_rtx;
2223 }
2224
bd79363c 2225 neon_builtin_datum *d =
6d60b856 2226 &neon_builtin_data[fcode - ARM_BUILTIN_NEON_PATTERN_START];
33857df2 2227 enum insn_code icode = d->code;
bd79363c
JG
2228 builtin_arg args[SIMD_MAX_BUILTIN_ARGS];
2229 int num_args = insn_data[d->code].n_operands;
2230 int is_void = 0;
2231 int k;
2232
2233 is_void = !!(d->qualifiers[0] & qualifier_void);
33857df2 2234
bd79363c
JG
2235 num_args += is_void;
2236
2237 for (k = 1; k < num_args; k++)
33857df2 2238 {
bd79363c
JG
2239 /* We have four arrays of data, each indexed in a different fashion.
2240 qualifiers - element 0 always describes the function return type.
2241 operands - element 0 is either the operand for return value (if
2242 the function has a non-void return type) or the operand for the
2243 first argument.
2244 expr_args - element 0 always holds the first argument.
2245 args - element 0 is always used for the return type. */
2246 int qualifiers_k = k;
2247 int operands_k = k - is_void;
2248 int expr_args_k = k - 1;
2249
eaa80f64
AL
2250 if (d->qualifiers[qualifiers_k] & qualifier_lane_index)
2251 args[k] = NEON_ARG_LANE_INDEX;
2f7d18dd
CB
2252 else if (d->qualifiers[qualifiers_k] & qualifier_struct_load_store_lane_index)
2253 args[k] = NEON_ARG_STRUCT_LOAD_STORE_LANE_INDEX;
eaa80f64 2254 else if (d->qualifiers[qualifiers_k] & qualifier_immediate)
bd79363c
JG
2255 args[k] = NEON_ARG_CONSTANT;
2256 else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate)
2257 {
2258 rtx arg
2259 = expand_normal (CALL_EXPR_ARG (exp,
2260 (expr_args_k)));
2261 /* Handle constants only if the predicate allows it. */
2262 bool op_const_int_p =
2263 (CONST_INT_P (arg)
2264 && (*insn_data[icode].operand[operands_k].predicate)
2265 (arg, insn_data[icode].operand[operands_k].mode));
2266 args[k] = op_const_int_p ? NEON_ARG_CONSTANT : NEON_ARG_COPY_TO_REG;
2267 }
2268 else if (d->qualifiers[qualifiers_k] & qualifier_pointer)
2269 args[k] = NEON_ARG_MEMORY;
2270 else
2271 args[k] = NEON_ARG_COPY_TO_REG;
33857df2 2272 }
bd79363c
JG
2273 args[k] = NEON_ARG_STOP;
2274
2275 /* The interface to arm_expand_neon_args expects a 0 if
2276 the function is void, and a 1 if it is not. */
2277 return arm_expand_neon_args
2278 (target, d->mode, fcode, icode, !is_void, exp,
2f7d18dd 2279 &args[1]);
33857df2
JG
2280}
2281
2282/* Expand an expression EXP that calls a built-in function,
2283 with result going to TARGET if that's convenient
2284 (and in mode MODE if that's convenient).
2285 SUBTARGET may be used as the target for computing one of EXP's operands.
2286 IGNORE is nonzero if the value is to be ignored. */
2287
2288rtx
2289arm_expand_builtin (tree exp,
2290 rtx target,
2291 rtx subtarget ATTRIBUTE_UNUSED,
2292 machine_mode mode ATTRIBUTE_UNUSED,
2293 int ignore ATTRIBUTE_UNUSED)
2294{
2295 const struct builtin_description * d;
2296 enum insn_code icode;
2297 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2298 tree arg0;
2299 tree arg1;
2300 tree arg2;
2301 rtx op0;
2302 rtx op1;
2303 rtx op2;
2304 rtx pat;
2305 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
2306 size_t i;
2307 machine_mode tmode;
2308 machine_mode mode0;
2309 machine_mode mode1;
2310 machine_mode mode2;
2311 int opint;
2312 int selector;
2313 int mask;
2314 int imm;
2315
2316 if (fcode >= ARM_BUILTIN_NEON_BASE)
2317 return arm_expand_neon_builtin (fcode, exp, target);
2318
2319 switch (fcode)
2320 {
2321 case ARM_BUILTIN_GET_FPSCR:
2322 case ARM_BUILTIN_SET_FPSCR:
2323 if (fcode == ARM_BUILTIN_GET_FPSCR)
2324 {
2325 icode = CODE_FOR_get_fpscr;
2326 target = gen_reg_rtx (SImode);
2327 pat = GEN_FCN (icode) (target);
2328 }
2329 else
2330 {
2331 target = NULL_RTX;
2332 icode = CODE_FOR_set_fpscr;
2333 arg0 = CALL_EXPR_ARG (exp, 0);
2334 op0 = expand_normal (arg0);
2335 pat = GEN_FCN (icode) (op0);
2336 }
2337 emit_insn (pat);
2338 return target;
2339
2340 case ARM_BUILTIN_TEXTRMSB:
2341 case ARM_BUILTIN_TEXTRMUB:
2342 case ARM_BUILTIN_TEXTRMSH:
2343 case ARM_BUILTIN_TEXTRMUH:
2344 case ARM_BUILTIN_TEXTRMSW:
2345 case ARM_BUILTIN_TEXTRMUW:
2346 icode = (fcode == ARM_BUILTIN_TEXTRMSB ? CODE_FOR_iwmmxt_textrmsb
2347 : fcode == ARM_BUILTIN_TEXTRMUB ? CODE_FOR_iwmmxt_textrmub
2348 : fcode == ARM_BUILTIN_TEXTRMSH ? CODE_FOR_iwmmxt_textrmsh
2349 : fcode == ARM_BUILTIN_TEXTRMUH ? CODE_FOR_iwmmxt_textrmuh
2350 : CODE_FOR_iwmmxt_textrmw);
2351
2352 arg0 = CALL_EXPR_ARG (exp, 0);
2353 arg1 = CALL_EXPR_ARG (exp, 1);
2354 op0 = expand_normal (arg0);
2355 op1 = expand_normal (arg1);
2356 tmode = insn_data[icode].operand[0].mode;
2357 mode0 = insn_data[icode].operand[1].mode;
2358 mode1 = insn_data[icode].operand[2].mode;
2359
2360 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2361 op0 = copy_to_mode_reg (mode0, op0);
2362 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
2363 {
2364 /* @@@ better error message */
2365 error ("selector must be an immediate");
2366 return gen_reg_rtx (tmode);
2367 }
2368
2369 opint = INTVAL (op1);
2370 if (fcode == ARM_BUILTIN_TEXTRMSB || fcode == ARM_BUILTIN_TEXTRMUB)
2371 {
2372 if (opint > 7 || opint < 0)
2373 error ("the range of selector should be in 0 to 7");
2374 }
2375 else if (fcode == ARM_BUILTIN_TEXTRMSH || fcode == ARM_BUILTIN_TEXTRMUH)
2376 {
2377 if (opint > 3 || opint < 0)
2378 error ("the range of selector should be in 0 to 3");
2379 }
2380 else /* ARM_BUILTIN_TEXTRMSW || ARM_BUILTIN_TEXTRMUW. */
2381 {
2382 if (opint > 1 || opint < 0)
2383 error ("the range of selector should be in 0 to 1");
2384 }
2385
2386 if (target == 0
2387 || GET_MODE (target) != tmode
2388 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2389 target = gen_reg_rtx (tmode);
2390 pat = GEN_FCN (icode) (target, op0, op1);
2391 if (! pat)
2392 return 0;
2393 emit_insn (pat);
2394 return target;
2395
2396 case ARM_BUILTIN_WALIGNI:
2397 /* If op2 is immediate, call walighi, else call walighr. */
2398 arg0 = CALL_EXPR_ARG (exp, 0);
2399 arg1 = CALL_EXPR_ARG (exp, 1);
2400 arg2 = CALL_EXPR_ARG (exp, 2);
2401 op0 = expand_normal (arg0);
2402 op1 = expand_normal (arg1);
2403 op2 = expand_normal (arg2);
2404 if (CONST_INT_P (op2))
2405 {
2406 icode = CODE_FOR_iwmmxt_waligni;
2407 tmode = insn_data[icode].operand[0].mode;
2408 mode0 = insn_data[icode].operand[1].mode;
2409 mode1 = insn_data[icode].operand[2].mode;
2410 mode2 = insn_data[icode].operand[3].mode;
2411 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
2412 op0 = copy_to_mode_reg (mode0, op0);
2413 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
2414 op1 = copy_to_mode_reg (mode1, op1);
2415 gcc_assert ((*insn_data[icode].operand[3].predicate) (op2, mode2));
2416 selector = INTVAL (op2);
2417 if (selector > 7 || selector < 0)
2418 error ("the range of selector should be in 0 to 7");
2419 }
2420 else
2421 {
2422 icode = CODE_FOR_iwmmxt_walignr;
2423 tmode = insn_data[icode].operand[0].mode;
2424 mode0 = insn_data[icode].operand[1].mode;
2425 mode1 = insn_data[icode].operand[2].mode;
2426 mode2 = insn_data[icode].operand[3].mode;
2427 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
2428 op0 = copy_to_mode_reg (mode0, op0);
2429 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
2430 op1 = copy_to_mode_reg (mode1, op1);
2431 if (!(*insn_data[icode].operand[3].predicate) (op2, mode2))
2432 op2 = copy_to_mode_reg (mode2, op2);
2433 }
2434 if (target == 0
2435 || GET_MODE (target) != tmode
2436 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
2437 target = gen_reg_rtx (tmode);
2438 pat = GEN_FCN (icode) (target, op0, op1, op2);
2439 if (!pat)
2440 return 0;
2441 emit_insn (pat);
2442 return target;
2443
2444 case ARM_BUILTIN_TINSRB:
2445 case ARM_BUILTIN_TINSRH:
2446 case ARM_BUILTIN_TINSRW:
2447 case ARM_BUILTIN_WMERGE:
2448 icode = (fcode == ARM_BUILTIN_TINSRB ? CODE_FOR_iwmmxt_tinsrb
2449 : fcode == ARM_BUILTIN_TINSRH ? CODE_FOR_iwmmxt_tinsrh
2450 : fcode == ARM_BUILTIN_WMERGE ? CODE_FOR_iwmmxt_wmerge
2451 : CODE_FOR_iwmmxt_tinsrw);
2452 arg0 = CALL_EXPR_ARG (exp, 0);
2453 arg1 = CALL_EXPR_ARG (exp, 1);
2454 arg2 = CALL_EXPR_ARG (exp, 2);
2455 op0 = expand_normal (arg0);
2456 op1 = expand_normal (arg1);
2457 op2 = expand_normal (arg2);
2458 tmode = insn_data[icode].operand[0].mode;
2459 mode0 = insn_data[icode].operand[1].mode;
2460 mode1 = insn_data[icode].operand[2].mode;
2461 mode2 = insn_data[icode].operand[3].mode;
2462
2463 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2464 op0 = copy_to_mode_reg (mode0, op0);
2465 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
2466 op1 = copy_to_mode_reg (mode1, op1);
2467 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
2468 {
2469 error ("selector must be an immediate");
2470 return const0_rtx;
2471 }
2472 if (icode == CODE_FOR_iwmmxt_wmerge)
2473 {
2474 selector = INTVAL (op2);
2475 if (selector > 7 || selector < 0)
2476 error ("the range of selector should be in 0 to 7");
2477 }
2478 if ((icode == CODE_FOR_iwmmxt_tinsrb)
2479 || (icode == CODE_FOR_iwmmxt_tinsrh)
2480 || (icode == CODE_FOR_iwmmxt_tinsrw))
2481 {
2482 mask = 0x01;
2483 selector= INTVAL (op2);
2484 if (icode == CODE_FOR_iwmmxt_tinsrb && (selector < 0 || selector > 7))
2485 error ("the range of selector should be in 0 to 7");
2486 else if (icode == CODE_FOR_iwmmxt_tinsrh && (selector < 0 ||selector > 3))
2487 error ("the range of selector should be in 0 to 3");
2488 else if (icode == CODE_FOR_iwmmxt_tinsrw && (selector < 0 ||selector > 1))
2489 error ("the range of selector should be in 0 to 1");
2490 mask <<= selector;
2491 op2 = GEN_INT (mask);
2492 }
2493 if (target == 0
2494 || GET_MODE (target) != tmode
2495 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2496 target = gen_reg_rtx (tmode);
2497 pat = GEN_FCN (icode) (target, op0, op1, op2);
2498 if (! pat)
2499 return 0;
2500 emit_insn (pat);
2501 return target;
2502
2503 case ARM_BUILTIN_SETWCGR0:
2504 case ARM_BUILTIN_SETWCGR1:
2505 case ARM_BUILTIN_SETWCGR2:
2506 case ARM_BUILTIN_SETWCGR3:
2507 icode = (fcode == ARM_BUILTIN_SETWCGR0 ? CODE_FOR_iwmmxt_setwcgr0
2508 : fcode == ARM_BUILTIN_SETWCGR1 ? CODE_FOR_iwmmxt_setwcgr1
2509 : fcode == ARM_BUILTIN_SETWCGR2 ? CODE_FOR_iwmmxt_setwcgr2
2510 : CODE_FOR_iwmmxt_setwcgr3);
2511 arg0 = CALL_EXPR_ARG (exp, 0);
2512 op0 = expand_normal (arg0);
2513 mode0 = insn_data[icode].operand[0].mode;
2514 if (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
2515 op0 = copy_to_mode_reg (mode0, op0);
2516 pat = GEN_FCN (icode) (op0);
2517 if (!pat)
2518 return 0;
2519 emit_insn (pat);
2520 return 0;
2521
2522 case ARM_BUILTIN_GETWCGR0:
2523 case ARM_BUILTIN_GETWCGR1:
2524 case ARM_BUILTIN_GETWCGR2:
2525 case ARM_BUILTIN_GETWCGR3:
2526 icode = (fcode == ARM_BUILTIN_GETWCGR0 ? CODE_FOR_iwmmxt_getwcgr0
2527 : fcode == ARM_BUILTIN_GETWCGR1 ? CODE_FOR_iwmmxt_getwcgr1
2528 : fcode == ARM_BUILTIN_GETWCGR2 ? CODE_FOR_iwmmxt_getwcgr2
2529 : CODE_FOR_iwmmxt_getwcgr3);
2530 tmode = insn_data[icode].operand[0].mode;
2531 if (target == 0
2532 || GET_MODE (target) != tmode
2533 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
2534 target = gen_reg_rtx (tmode);
2535 pat = GEN_FCN (icode) (target);
2536 if (!pat)
2537 return 0;
2538 emit_insn (pat);
2539 return target;
2540
2541 case ARM_BUILTIN_WSHUFH:
2542 icode = CODE_FOR_iwmmxt_wshufh;
2543 arg0 = CALL_EXPR_ARG (exp, 0);
2544 arg1 = CALL_EXPR_ARG (exp, 1);
2545 op0 = expand_normal (arg0);
2546 op1 = expand_normal (arg1);
2547 tmode = insn_data[icode].operand[0].mode;
2548 mode1 = insn_data[icode].operand[1].mode;
2549 mode2 = insn_data[icode].operand[2].mode;
2550
2551 if (! (*insn_data[icode].operand[1].predicate) (op0, mode1))
2552 op0 = copy_to_mode_reg (mode1, op0);
2553 if (! (*insn_data[icode].operand[2].predicate) (op1, mode2))
2554 {
2555 error ("mask must be an immediate");
2556 return const0_rtx;
2557 }
2558 selector = INTVAL (op1);
2559 if (selector < 0 || selector > 255)
2560 error ("the range of mask should be in 0 to 255");
2561 if (target == 0
2562 || GET_MODE (target) != tmode
2563 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2564 target = gen_reg_rtx (tmode);
2565 pat = GEN_FCN (icode) (target, op0, op1);
2566 if (! pat)
2567 return 0;
2568 emit_insn (pat);
2569 return target;
2570
2571 case ARM_BUILTIN_WMADDS:
2572 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmadds, exp, target);
2573 case ARM_BUILTIN_WMADDSX:
2574 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsx, exp, target);
2575 case ARM_BUILTIN_WMADDSN:
2576 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsn, exp, target);
2577 case ARM_BUILTIN_WMADDU:
2578 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddu, exp, target);
2579 case ARM_BUILTIN_WMADDUX:
2580 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddux, exp, target);
2581 case ARM_BUILTIN_WMADDUN:
2582 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddun, exp, target);
2583 case ARM_BUILTIN_WSADBZ:
2584 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz, exp, target);
2585 case ARM_BUILTIN_WSADHZ:
2586 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz, exp, target);
2587
2588 /* Several three-argument builtins. */
2589 case ARM_BUILTIN_WMACS:
2590 case ARM_BUILTIN_WMACU:
2591 case ARM_BUILTIN_TMIA:
2592 case ARM_BUILTIN_TMIAPH:
2593 case ARM_BUILTIN_TMIATT:
2594 case ARM_BUILTIN_TMIATB:
2595 case ARM_BUILTIN_TMIABT:
2596 case ARM_BUILTIN_TMIABB:
2597 case ARM_BUILTIN_WQMIABB:
2598 case ARM_BUILTIN_WQMIABT:
2599 case ARM_BUILTIN_WQMIATB:
2600 case ARM_BUILTIN_WQMIATT:
2601 case ARM_BUILTIN_WQMIABBN:
2602 case ARM_BUILTIN_WQMIABTN:
2603 case ARM_BUILTIN_WQMIATBN:
2604 case ARM_BUILTIN_WQMIATTN:
2605 case ARM_BUILTIN_WMIABB:
2606 case ARM_BUILTIN_WMIABT:
2607 case ARM_BUILTIN_WMIATB:
2608 case ARM_BUILTIN_WMIATT:
2609 case ARM_BUILTIN_WMIABBN:
2610 case ARM_BUILTIN_WMIABTN:
2611 case ARM_BUILTIN_WMIATBN:
2612 case ARM_BUILTIN_WMIATTN:
2613 case ARM_BUILTIN_WMIAWBB:
2614 case ARM_BUILTIN_WMIAWBT:
2615 case ARM_BUILTIN_WMIAWTB:
2616 case ARM_BUILTIN_WMIAWTT:
2617 case ARM_BUILTIN_WMIAWBBN:
2618 case ARM_BUILTIN_WMIAWBTN:
2619 case ARM_BUILTIN_WMIAWTBN:
2620 case ARM_BUILTIN_WMIAWTTN:
2621 case ARM_BUILTIN_WSADB:
2622 case ARM_BUILTIN_WSADH:
2623 icode = (fcode == ARM_BUILTIN_WMACS ? CODE_FOR_iwmmxt_wmacs
2624 : fcode == ARM_BUILTIN_WMACU ? CODE_FOR_iwmmxt_wmacu
2625 : fcode == ARM_BUILTIN_TMIA ? CODE_FOR_iwmmxt_tmia
2626 : fcode == ARM_BUILTIN_TMIAPH ? CODE_FOR_iwmmxt_tmiaph
2627 : fcode == ARM_BUILTIN_TMIABB ? CODE_FOR_iwmmxt_tmiabb
2628 : fcode == ARM_BUILTIN_TMIABT ? CODE_FOR_iwmmxt_tmiabt
2629 : fcode == ARM_BUILTIN_TMIATB ? CODE_FOR_iwmmxt_tmiatb
2630 : fcode == ARM_BUILTIN_TMIATT ? CODE_FOR_iwmmxt_tmiatt
2631 : fcode == ARM_BUILTIN_WQMIABB ? CODE_FOR_iwmmxt_wqmiabb
2632 : fcode == ARM_BUILTIN_WQMIABT ? CODE_FOR_iwmmxt_wqmiabt
2633 : fcode == ARM_BUILTIN_WQMIATB ? CODE_FOR_iwmmxt_wqmiatb
2634 : fcode == ARM_BUILTIN_WQMIATT ? CODE_FOR_iwmmxt_wqmiatt
2635 : fcode == ARM_BUILTIN_WQMIABBN ? CODE_FOR_iwmmxt_wqmiabbn
2636 : fcode == ARM_BUILTIN_WQMIABTN ? CODE_FOR_iwmmxt_wqmiabtn
2637 : fcode == ARM_BUILTIN_WQMIATBN ? CODE_FOR_iwmmxt_wqmiatbn
2638 : fcode == ARM_BUILTIN_WQMIATTN ? CODE_FOR_iwmmxt_wqmiattn
2639 : fcode == ARM_BUILTIN_WMIABB ? CODE_FOR_iwmmxt_wmiabb
2640 : fcode == ARM_BUILTIN_WMIABT ? CODE_FOR_iwmmxt_wmiabt
2641 : fcode == ARM_BUILTIN_WMIATB ? CODE_FOR_iwmmxt_wmiatb
2642 : fcode == ARM_BUILTIN_WMIATT ? CODE_FOR_iwmmxt_wmiatt
2643 : fcode == ARM_BUILTIN_WMIABBN ? CODE_FOR_iwmmxt_wmiabbn
2644 : fcode == ARM_BUILTIN_WMIABTN ? CODE_FOR_iwmmxt_wmiabtn
2645 : fcode == ARM_BUILTIN_WMIATBN ? CODE_FOR_iwmmxt_wmiatbn
2646 : fcode == ARM_BUILTIN_WMIATTN ? CODE_FOR_iwmmxt_wmiattn
2647 : fcode == ARM_BUILTIN_WMIAWBB ? CODE_FOR_iwmmxt_wmiawbb
2648 : fcode == ARM_BUILTIN_WMIAWBT ? CODE_FOR_iwmmxt_wmiawbt
2649 : fcode == ARM_BUILTIN_WMIAWTB ? CODE_FOR_iwmmxt_wmiawtb
2650 : fcode == ARM_BUILTIN_WMIAWTT ? CODE_FOR_iwmmxt_wmiawtt
2651 : fcode == ARM_BUILTIN_WMIAWBBN ? CODE_FOR_iwmmxt_wmiawbbn
2652 : fcode == ARM_BUILTIN_WMIAWBTN ? CODE_FOR_iwmmxt_wmiawbtn
2653 : fcode == ARM_BUILTIN_WMIAWTBN ? CODE_FOR_iwmmxt_wmiawtbn
2654 : fcode == ARM_BUILTIN_WMIAWTTN ? CODE_FOR_iwmmxt_wmiawttn
2655 : fcode == ARM_BUILTIN_WSADB ? CODE_FOR_iwmmxt_wsadb
2656 : CODE_FOR_iwmmxt_wsadh);
2657 arg0 = CALL_EXPR_ARG (exp, 0);
2658 arg1 = CALL_EXPR_ARG (exp, 1);
2659 arg2 = CALL_EXPR_ARG (exp, 2);
2660 op0 = expand_normal (arg0);
2661 op1 = expand_normal (arg1);
2662 op2 = expand_normal (arg2);
2663 tmode = insn_data[icode].operand[0].mode;
2664 mode0 = insn_data[icode].operand[1].mode;
2665 mode1 = insn_data[icode].operand[2].mode;
2666 mode2 = insn_data[icode].operand[3].mode;
2667
2668 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2669 op0 = copy_to_mode_reg (mode0, op0);
2670 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
2671 op1 = copy_to_mode_reg (mode1, op1);
2672 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
2673 op2 = copy_to_mode_reg (mode2, op2);
2674 if (target == 0
2675 || GET_MODE (target) != tmode
2676 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2677 target = gen_reg_rtx (tmode);
2678 pat = GEN_FCN (icode) (target, op0, op1, op2);
2679 if (! pat)
2680 return 0;
2681 emit_insn (pat);
2682 return target;
2683
2684 case ARM_BUILTIN_WZERO:
2685 target = gen_reg_rtx (DImode);
2686 emit_insn (gen_iwmmxt_clrdi (target));
2687 return target;
2688
2689 case ARM_BUILTIN_WSRLHI:
2690 case ARM_BUILTIN_WSRLWI:
2691 case ARM_BUILTIN_WSRLDI:
2692 case ARM_BUILTIN_WSLLHI:
2693 case ARM_BUILTIN_WSLLWI:
2694 case ARM_BUILTIN_WSLLDI:
2695 case ARM_BUILTIN_WSRAHI:
2696 case ARM_BUILTIN_WSRAWI:
2697 case ARM_BUILTIN_WSRADI:
2698 case ARM_BUILTIN_WRORHI:
2699 case ARM_BUILTIN_WRORWI:
2700 case ARM_BUILTIN_WRORDI:
2701 case ARM_BUILTIN_WSRLH:
2702 case ARM_BUILTIN_WSRLW:
2703 case ARM_BUILTIN_WSRLD:
2704 case ARM_BUILTIN_WSLLH:
2705 case ARM_BUILTIN_WSLLW:
2706 case ARM_BUILTIN_WSLLD:
2707 case ARM_BUILTIN_WSRAH:
2708 case ARM_BUILTIN_WSRAW:
2709 case ARM_BUILTIN_WSRAD:
2710 case ARM_BUILTIN_WRORH:
2711 case ARM_BUILTIN_WRORW:
2712 case ARM_BUILTIN_WRORD:
2713 icode = (fcode == ARM_BUILTIN_WSRLHI ? CODE_FOR_lshrv4hi3_iwmmxt
2714 : fcode == ARM_BUILTIN_WSRLWI ? CODE_FOR_lshrv2si3_iwmmxt
2715 : fcode == ARM_BUILTIN_WSRLDI ? CODE_FOR_lshrdi3_iwmmxt
2716 : fcode == ARM_BUILTIN_WSLLHI ? CODE_FOR_ashlv4hi3_iwmmxt
2717 : fcode == ARM_BUILTIN_WSLLWI ? CODE_FOR_ashlv2si3_iwmmxt
2718 : fcode == ARM_BUILTIN_WSLLDI ? CODE_FOR_ashldi3_iwmmxt
2719 : fcode == ARM_BUILTIN_WSRAHI ? CODE_FOR_ashrv4hi3_iwmmxt
2720 : fcode == ARM_BUILTIN_WSRAWI ? CODE_FOR_ashrv2si3_iwmmxt
2721 : fcode == ARM_BUILTIN_WSRADI ? CODE_FOR_ashrdi3_iwmmxt
2722 : fcode == ARM_BUILTIN_WRORHI ? CODE_FOR_rorv4hi3
2723 : fcode == ARM_BUILTIN_WRORWI ? CODE_FOR_rorv2si3
2724 : fcode == ARM_BUILTIN_WRORDI ? CODE_FOR_rordi3
2725 : fcode == ARM_BUILTIN_WSRLH ? CODE_FOR_lshrv4hi3_di
2726 : fcode == ARM_BUILTIN_WSRLW ? CODE_FOR_lshrv2si3_di
2727 : fcode == ARM_BUILTIN_WSRLD ? CODE_FOR_lshrdi3_di
2728 : fcode == ARM_BUILTIN_WSLLH ? CODE_FOR_ashlv4hi3_di
2729 : fcode == ARM_BUILTIN_WSLLW ? CODE_FOR_ashlv2si3_di
2730 : fcode == ARM_BUILTIN_WSLLD ? CODE_FOR_ashldi3_di
2731 : fcode == ARM_BUILTIN_WSRAH ? CODE_FOR_ashrv4hi3_di
2732 : fcode == ARM_BUILTIN_WSRAW ? CODE_FOR_ashrv2si3_di
2733 : fcode == ARM_BUILTIN_WSRAD ? CODE_FOR_ashrdi3_di
2734 : fcode == ARM_BUILTIN_WRORH ? CODE_FOR_rorv4hi3_di
2735 : fcode == ARM_BUILTIN_WRORW ? CODE_FOR_rorv2si3_di
2736 : fcode == ARM_BUILTIN_WRORD ? CODE_FOR_rordi3_di
2737 : CODE_FOR_nothing);
2738 arg1 = CALL_EXPR_ARG (exp, 1);
2739 op1 = expand_normal (arg1);
2740 if (GET_MODE (op1) == VOIDmode)
2741 {
2742 imm = INTVAL (op1);
2743 if ((fcode == ARM_BUILTIN_WRORHI || fcode == ARM_BUILTIN_WRORWI
2744 || fcode == ARM_BUILTIN_WRORH || fcode == ARM_BUILTIN_WRORW)
2745 && (imm < 0 || imm > 32))
2746 {
2747 if (fcode == ARM_BUILTIN_WRORHI)
2748 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi16 in code.");
2749 else if (fcode == ARM_BUILTIN_WRORWI)
2750 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi32 in code.");
2751 else if (fcode == ARM_BUILTIN_WRORH)
2752 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi16 in code.");
2753 else
2754 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi32 in code.");
2755 }
2756 else if ((fcode == ARM_BUILTIN_WRORDI || fcode == ARM_BUILTIN_WRORD)
2757 && (imm < 0 || imm > 64))
2758 {
2759 if (fcode == ARM_BUILTIN_WRORDI)
2760 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_rori_si64 in code.");
2761 else
2762 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_ror_si64 in code.");
2763 }
2764 else if (imm < 0)
2765 {
2766 if (fcode == ARM_BUILTIN_WSRLHI)
2767 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi16 in code.");
2768 else if (fcode == ARM_BUILTIN_WSRLWI)
2769 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi32 in code.");
2770 else if (fcode == ARM_BUILTIN_WSRLDI)
2771 error ("the count should be no less than 0. please check the intrinsic _mm_srli_si64 in code.");
2772 else if (fcode == ARM_BUILTIN_WSLLHI)
2773 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi16 in code.");
2774 else if (fcode == ARM_BUILTIN_WSLLWI)
2775 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi32 in code.");
2776 else if (fcode == ARM_BUILTIN_WSLLDI)
2777 error ("the count should be no less than 0. please check the intrinsic _mm_slli_si64 in code.");
2778 else if (fcode == ARM_BUILTIN_WSRAHI)
2779 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi16 in code.");
2780 else if (fcode == ARM_BUILTIN_WSRAWI)
2781 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi32 in code.");
2782 else if (fcode == ARM_BUILTIN_WSRADI)
2783 error ("the count should be no less than 0. please check the intrinsic _mm_srai_si64 in code.");
2784 else if (fcode == ARM_BUILTIN_WSRLH)
2785 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi16 in code.");
2786 else if (fcode == ARM_BUILTIN_WSRLW)
2787 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi32 in code.");
2788 else if (fcode == ARM_BUILTIN_WSRLD)
2789 error ("the count should be no less than 0. please check the intrinsic _mm_srl_si64 in code.");
2790 else if (fcode == ARM_BUILTIN_WSLLH)
2791 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi16 in code.");
2792 else if (fcode == ARM_BUILTIN_WSLLW)
2793 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi32 in code.");
2794 else if (fcode == ARM_BUILTIN_WSLLD)
2795 error ("the count should be no less than 0. please check the intrinsic _mm_sll_si64 in code.");
2796 else if (fcode == ARM_BUILTIN_WSRAH)
2797 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi16 in code.");
2798 else if (fcode == ARM_BUILTIN_WSRAW)
2799 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi32 in code.");
2800 else
2801 error ("the count should be no less than 0. please check the intrinsic _mm_sra_si64 in code.");
2802 }
2803 }
2804 return arm_expand_binop_builtin (icode, exp, target);
2805
2806 default:
2807 break;
2808 }
2809
2810 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
2811 if (d->code == (const enum arm_builtins) fcode)
2812 return arm_expand_binop_builtin (d->icode, exp, target);
2813
2814 for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
2815 if (d->code == (const enum arm_builtins) fcode)
2816 return arm_expand_unop_builtin (d->icode, exp, target, 0);
2817
2818 for (i = 0, d = bdesc_3arg; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
2819 if (d->code == (const enum arm_builtins) fcode)
2820 return arm_expand_ternop_builtin (d->icode, exp, target);
2821
2822 /* @@@ Should really do something sensible here. */
2823 return NULL_RTX;
2824}
2825
2826tree
2827arm_builtin_vectorized_function (tree fndecl, tree type_out, tree type_in)
2828{
2829 machine_mode in_mode, out_mode;
2830 int in_n, out_n;
2831 bool out_unsigned_p = TYPE_UNSIGNED (type_out);
2832
2833 if (TREE_CODE (type_out) != VECTOR_TYPE
2834 || TREE_CODE (type_in) != VECTOR_TYPE)
2835 return NULL_TREE;
2836
2837 out_mode = TYPE_MODE (TREE_TYPE (type_out));
2838 out_n = TYPE_VECTOR_SUBPARTS (type_out);
2839 in_mode = TYPE_MODE (TREE_TYPE (type_in));
2840 in_n = TYPE_VECTOR_SUBPARTS (type_in);
2841
2842/* ARM_CHECK_BUILTIN_MODE and ARM_FIND_VRINT_VARIANT are used to find the
2843 decl of the vectorized builtin for the appropriate vector mode.
2844 NULL_TREE is returned if no such builtin is available. */
2845#undef ARM_CHECK_BUILTIN_MODE
2846#define ARM_CHECK_BUILTIN_MODE(C) \
2847 (TARGET_NEON && TARGET_FPU_ARMV8 \
2848 && flag_unsafe_math_optimizations \
2849 && ARM_CHECK_BUILTIN_MODE_1 (C))
2850
2851#undef ARM_CHECK_BUILTIN_MODE_1
2852#define ARM_CHECK_BUILTIN_MODE_1(C) \
2853 (out_mode == SFmode && out_n == C \
2854 && in_mode == SFmode && in_n == C)
2855
2856#undef ARM_FIND_VRINT_VARIANT
2857#define ARM_FIND_VRINT_VARIANT(N) \
2858 (ARM_CHECK_BUILTIN_MODE (2) \
2859 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sf, false) \
2860 : (ARM_CHECK_BUILTIN_MODE (4) \
2861 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sf, false) \
2862 : NULL_TREE))
2863
2864 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
2865 {
2866 enum built_in_function fn = DECL_FUNCTION_CODE (fndecl);
2867 switch (fn)
2868 {
2869 case BUILT_IN_FLOORF:
2870 return ARM_FIND_VRINT_VARIANT (vrintm);
2871 case BUILT_IN_CEILF:
2872 return ARM_FIND_VRINT_VARIANT (vrintp);
2873 case BUILT_IN_TRUNCF:
2874 return ARM_FIND_VRINT_VARIANT (vrintz);
2875 case BUILT_IN_ROUNDF:
2876 return ARM_FIND_VRINT_VARIANT (vrinta);
2877#undef ARM_CHECK_BUILTIN_MODE_1
2878#define ARM_CHECK_BUILTIN_MODE_1(C) \
2879 (out_mode == SImode && out_n == C \
2880 && in_mode == SFmode && in_n == C)
2881
2882#define ARM_FIND_VCVT_VARIANT(N) \
2883 (ARM_CHECK_BUILTIN_MODE (2) \
2884 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sfv2si, false) \
2885 : (ARM_CHECK_BUILTIN_MODE (4) \
2886 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sfv4si, false) \
2887 : NULL_TREE))
2888
2889#define ARM_FIND_VCVTU_VARIANT(N) \
2890 (ARM_CHECK_BUILTIN_MODE (2) \
2891 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv2sfv2si, false) \
2892 : (ARM_CHECK_BUILTIN_MODE (4) \
2893 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv4sfv4si, false) \
2894 : NULL_TREE))
2895 case BUILT_IN_LROUNDF:
2896 return out_unsigned_p
2897 ? ARM_FIND_VCVTU_VARIANT (vcvta)
2898 : ARM_FIND_VCVT_VARIANT (vcvta);
2899 case BUILT_IN_LCEILF:
2900 return out_unsigned_p
2901 ? ARM_FIND_VCVTU_VARIANT (vcvtp)
2902 : ARM_FIND_VCVT_VARIANT (vcvtp);
2903 case BUILT_IN_LFLOORF:
2904 return out_unsigned_p
2905 ? ARM_FIND_VCVTU_VARIANT (vcvtm)
2906 : ARM_FIND_VCVT_VARIANT (vcvtm);
2907#undef ARM_CHECK_BUILTIN_MODE
2908#define ARM_CHECK_BUILTIN_MODE(C, N) \
2909 (out_mode == N##mode && out_n == C \
2910 && in_mode == N##mode && in_n == C)
2911 case BUILT_IN_BSWAP16:
2912 if (ARM_CHECK_BUILTIN_MODE (4, HI))
2913 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4hi, false);
2914 else if (ARM_CHECK_BUILTIN_MODE (8, HI))
2915 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv8hi, false);
2916 else
2917 return NULL_TREE;
2918 case BUILT_IN_BSWAP32:
2919 if (ARM_CHECK_BUILTIN_MODE (2, SI))
2920 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2si, false);
2921 else if (ARM_CHECK_BUILTIN_MODE (4, SI))
2922 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4si, false);
2923 else
2924 return NULL_TREE;
2925 case BUILT_IN_BSWAP64:
2926 if (ARM_CHECK_BUILTIN_MODE (2, DI))
2927 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2di, false);
2928 else
2929 return NULL_TREE;
2930 case BUILT_IN_COPYSIGNF:
2931 if (ARM_CHECK_BUILTIN_MODE (2, SF))
2932 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv2sf, false);
2933 else if (ARM_CHECK_BUILTIN_MODE (4, SF))
2934 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv4sf, false);
2935 else
2936 return NULL_TREE;
2937
2938 default:
2939 return NULL_TREE;
2940 }
2941 }
2942 return NULL_TREE;
2943}
2944#undef ARM_FIND_VCVT_VARIANT
2945#undef ARM_FIND_VCVTU_VARIANT
2946#undef ARM_CHECK_BUILTIN_MODE
2947#undef ARM_FIND_VRINT_VARIANT
2948
2949void
2950arm_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
2951{
2952 const unsigned ARM_FE_INVALID = 1;
2953 const unsigned ARM_FE_DIVBYZERO = 2;
2954 const unsigned ARM_FE_OVERFLOW = 4;
2955 const unsigned ARM_FE_UNDERFLOW = 8;
2956 const unsigned ARM_FE_INEXACT = 16;
2957 const unsigned HOST_WIDE_INT ARM_FE_ALL_EXCEPT = (ARM_FE_INVALID
2958 | ARM_FE_DIVBYZERO
2959 | ARM_FE_OVERFLOW
2960 | ARM_FE_UNDERFLOW
2961 | ARM_FE_INEXACT);
2962 const unsigned HOST_WIDE_INT ARM_FE_EXCEPT_SHIFT = 8;
2963 tree fenv_var, get_fpscr, set_fpscr, mask, ld_fenv, masked_fenv;
2964 tree new_fenv_var, reload_fenv, restore_fnenv;
2965 tree update_call, atomic_feraiseexcept, hold_fnclex;
2966
2967 if (!TARGET_VFP || !TARGET_HARD_FLOAT)
2968 return;
2969
2970 /* Generate the equivalent of :
2971 unsigned int fenv_var;
2972 fenv_var = __builtin_arm_get_fpscr ();
2973
2974 unsigned int masked_fenv;
2975 masked_fenv = fenv_var & mask;
2976
2977 __builtin_arm_set_fpscr (masked_fenv); */
2978
baba8d7d 2979 fenv_var = create_tmp_var_raw (unsigned_type_node);
33857df2
JG
2980 get_fpscr = arm_builtin_decls[ARM_BUILTIN_GET_FPSCR];
2981 set_fpscr = arm_builtin_decls[ARM_BUILTIN_SET_FPSCR];
2982 mask = build_int_cst (unsigned_type_node,
2983 ~((ARM_FE_ALL_EXCEPT << ARM_FE_EXCEPT_SHIFT)
2984 | ARM_FE_ALL_EXCEPT));
2985 ld_fenv = build2 (MODIFY_EXPR, unsigned_type_node,
2986 fenv_var, build_call_expr (get_fpscr, 0));
2987 masked_fenv = build2 (BIT_AND_EXPR, unsigned_type_node, fenv_var, mask);
2988 hold_fnclex = build_call_expr (set_fpscr, 1, masked_fenv);
2989 *hold = build2 (COMPOUND_EXPR, void_type_node,
2990 build2 (COMPOUND_EXPR, void_type_node, masked_fenv, ld_fenv),
2991 hold_fnclex);
2992
2993 /* Store the value of masked_fenv to clear the exceptions:
2994 __builtin_arm_set_fpscr (masked_fenv); */
2995
2996 *clear = build_call_expr (set_fpscr, 1, masked_fenv);
2997
2998 /* Generate the equivalent of :
2999 unsigned int new_fenv_var;
3000 new_fenv_var = __builtin_arm_get_fpscr ();
3001
3002 __builtin_arm_set_fpscr (fenv_var);
3003
3004 __atomic_feraiseexcept (new_fenv_var); */
3005
baba8d7d 3006 new_fenv_var = create_tmp_var_raw (unsigned_type_node);
33857df2
JG
3007 reload_fenv = build2 (MODIFY_EXPR, unsigned_type_node, new_fenv_var,
3008 build_call_expr (get_fpscr, 0));
3009 restore_fnenv = build_call_expr (set_fpscr, 1, fenv_var);
3010 atomic_feraiseexcept = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
3011 update_call = build_call_expr (atomic_feraiseexcept, 1,
3012 fold_convert (integer_type_node, new_fenv_var));
3013 *update = build2 (COMPOUND_EXPR, void_type_node,
3014 build2 (COMPOUND_EXPR, void_type_node,
3015 reload_fenv, restore_fnenv), update_call);
3016}
3017
3018#include "gt-arm-builtins.h"