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