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