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