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