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