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