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