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