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