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