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