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