Add assember CFI directives to millicode division and remainder routines.
[official-gcc.git] / gcc / config / arm / arm-builtins.cc
blob9f5c568cbc3389daebcfad8ac79babdb02025039
1 /* Description of builtins used by the ARM backend.
2 Copyright (C) 2014-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
20 #define IN_TARGET_CODE 1
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 #include "stringpool.h"
45 #include "arm-builtins.h"
46 #include "stringpool.h"
47 #include "attribs.h"
49 #define SIMD_MAX_BUILTIN_ARGS 7
51 /* The qualifier_internal allows generation of a unary builtin from
52 a pattern with a third pseudo-operand such as a match_scratch.
53 T (T). */
54 static enum arm_type_qualifiers
55 arm_unop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
56 = { qualifier_none, qualifier_none, qualifier_internal };
57 #define UNOP_QUALIFIERS (arm_unop_qualifiers)
59 /* unsigned T (unsigned T). */
60 static enum arm_type_qualifiers
61 arm_bswap_qualifiers[SIMD_MAX_BUILTIN_ARGS]
62 = { qualifier_unsigned, qualifier_unsigned };
63 #define BSWAP_QUALIFIERS (arm_bswap_qualifiers)
65 /* T (T, T [maybe_immediate]). */
66 static enum arm_type_qualifiers
67 arm_binop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
68 = { qualifier_none, qualifier_none, qualifier_maybe_immediate };
69 #define BINOP_QUALIFIERS (arm_binop_qualifiers)
71 /* T (T, T, T). */
72 static enum arm_type_qualifiers
73 arm_ternop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
74 = { qualifier_none, qualifier_none, qualifier_none, qualifier_none };
75 #define TERNOP_QUALIFIERS (arm_ternop_qualifiers)
77 /* unsigned T (unsigned T, unsigned T, unsigned T). */
78 static enum arm_type_qualifiers
79 arm_unsigned_uternop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
80 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
81 qualifier_unsigned };
82 #define UTERNOP_QUALIFIERS (arm_unsigned_uternop_qualifiers)
84 /* T (T, unsigned T, T). */
85 static enum arm_type_qualifiers
86 arm_usternop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
87 = { qualifier_none, qualifier_none, qualifier_unsigned,
88 qualifier_none };
89 #define USTERNOP_QUALIFIERS (arm_usternop_qualifiers)
91 /* T (T, immediate). */
92 static enum arm_type_qualifiers
93 arm_binop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
94 = { qualifier_none, qualifier_none, qualifier_immediate };
95 #define BINOP_IMM_QUALIFIERS (arm_binop_imm_qualifiers)
97 /* T (T, unsigned immediate). */
98 static enum arm_type_qualifiers
99 arm_sat_binop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
100 = { qualifier_unsigned, qualifier_none, qualifier_unsigned_immediate };
101 #define SAT_BINOP_UNSIGNED_IMM_QUALIFIERS \
102 (arm_sat_binop_imm_qualifiers)
104 /* unsigned T (T, unsigned immediate). */
105 static enum arm_type_qualifiers
106 arm_unsigned_sat_binop_unsigned_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
107 = { qualifier_unsigned, qualifier_none, qualifier_unsigned_immediate };
108 #define UNSIGNED_SAT_BINOP_UNSIGNED_IMM_QUALIFIERS \
109 (arm_unsigned_sat_binop_unsigned_imm_qualifiers)
111 /* T (T, lane index). */
112 static enum arm_type_qualifiers
113 arm_getlane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
114 = { qualifier_none, qualifier_none, qualifier_lane_index };
115 #define GETLANE_QUALIFIERS (arm_getlane_qualifiers)
117 /* T (T, T, T, immediate). */
118 static enum arm_type_qualifiers
119 arm_mac_n_qualifiers[SIMD_MAX_BUILTIN_ARGS]
120 = { qualifier_none, qualifier_none, qualifier_none,
121 qualifier_none, qualifier_immediate };
122 #define MAC_N_QUALIFIERS (arm_mac_n_qualifiers)
124 /* T (T, T, T, lane index). */
125 static enum arm_type_qualifiers
126 arm_mac_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
127 = { qualifier_none, qualifier_none, qualifier_none,
128 qualifier_none, qualifier_lane_index };
129 #define MAC_LANE_QUALIFIERS (arm_mac_lane_qualifiers)
131 /* T (T, T, T, lane pair index). */
132 static enum arm_type_qualifiers
133 arm_mac_lane_pair_qualifiers[SIMD_MAX_BUILTIN_ARGS]
134 = { qualifier_none, qualifier_none, qualifier_none,
135 qualifier_none, qualifier_lane_pair_index };
136 #define MAC_LANE_PAIR_QUALIFIERS (arm_mac_lane_pair_qualifiers)
138 /* unsigned T (unsigned T, unsigned T, unsigend T, lane index). */
139 static enum arm_type_qualifiers
140 arm_umac_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
141 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
142 qualifier_unsigned, qualifier_lane_index };
143 #define UMAC_LANE_QUALIFIERS (arm_umac_lane_qualifiers)
145 /* T (T, unsigned T, T, lane index). */
146 static enum arm_type_qualifiers
147 arm_usmac_lane_quadtup_qualifiers[SIMD_MAX_BUILTIN_ARGS]
148 = { qualifier_none, qualifier_none, qualifier_unsigned,
149 qualifier_none, qualifier_lane_quadtup_index };
150 #define USMAC_LANE_QUADTUP_QUALIFIERS (arm_usmac_lane_quadtup_qualifiers)
152 /* T (T, T, unsigend T, lane index). */
153 static enum arm_type_qualifiers
154 arm_sumac_lane_quadtup_qualifiers[SIMD_MAX_BUILTIN_ARGS]
155 = { qualifier_none, qualifier_none, qualifier_none,
156 qualifier_unsigned, qualifier_lane_quadtup_index };
157 #define SUMAC_LANE_QUADTUP_QUALIFIERS (arm_sumac_lane_quadtup_qualifiers)
159 /* T (T, T, immediate). */
160 static enum arm_type_qualifiers
161 arm_ternop_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
162 = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate };
163 #define TERNOP_IMM_QUALIFIERS (arm_ternop_imm_qualifiers)
165 /* T (T, T, lane index). */
166 static enum arm_type_qualifiers
167 arm_setlane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
168 = { qualifier_none, qualifier_none, qualifier_none, qualifier_lane_index };
169 #define SETLANE_QUALIFIERS (arm_setlane_qualifiers)
171 /* T (T, T). */
172 static enum arm_type_qualifiers
173 arm_combine_qualifiers[SIMD_MAX_BUILTIN_ARGS]
174 = { qualifier_none, qualifier_none, qualifier_none };
175 #define COMBINE_QUALIFIERS (arm_combine_qualifiers)
177 /* T ([T element type] *). */
178 static enum arm_type_qualifiers
179 arm_load1_qualifiers[SIMD_MAX_BUILTIN_ARGS]
180 = { qualifier_none, qualifier_const_pointer_map_mode };
181 #define LOAD1_QUALIFIERS (arm_load1_qualifiers)
183 /* T ([T element type] *, T, immediate). */
184 static enum arm_type_qualifiers
185 arm_load1_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
186 = { qualifier_none, qualifier_const_pointer_map_mode,
187 qualifier_none, qualifier_struct_load_store_lane_index };
188 #define LOAD1LANE_QUALIFIERS (arm_load1_lane_qualifiers)
190 /* unsigned T (unsigned T, unsigned T, unsigned T). */
191 static enum arm_type_qualifiers
192 arm_unsigned_binop_qualifiers[SIMD_MAX_BUILTIN_ARGS]
193 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
194 qualifier_unsigned };
195 #define UBINOP_QUALIFIERS (arm_unsigned_binop_qualifiers)
197 /* void (unsigned immediate, unsigned immediate, unsigned immediate,
198 unsigned immediate, unsigned immediate, unsigned immediate). */
199 static enum arm_type_qualifiers
200 arm_cdp_qualifiers[SIMD_MAX_BUILTIN_ARGS]
201 = { qualifier_void, qualifier_unsigned_immediate,
202 qualifier_unsigned_immediate,
203 qualifier_unsigned_immediate,
204 qualifier_unsigned_immediate,
205 qualifier_unsigned_immediate,
206 qualifier_unsigned_immediate };
207 #define CDP_QUALIFIERS \
208 (arm_cdp_qualifiers)
210 /* void (unsigned immediate, unsigned immediate, const void *). */
211 static enum arm_type_qualifiers
212 arm_ldc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
213 = { qualifier_void, qualifier_unsigned_immediate,
214 qualifier_unsigned_immediate, qualifier_const_void_pointer };
215 #define LDC_QUALIFIERS \
216 (arm_ldc_qualifiers)
218 /* void (unsigned immediate, unsigned immediate, void *). */
219 static enum arm_type_qualifiers
220 arm_stc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
221 = { qualifier_void, qualifier_unsigned_immediate,
222 qualifier_unsigned_immediate, qualifier_void_pointer };
223 #define STC_QUALIFIERS \
224 (arm_stc_qualifiers)
226 /* void (unsigned immediate, unsigned immediate, T, unsigned immediate,
227 unsigned immediate, unsigned immediate). */
228 static enum arm_type_qualifiers
229 arm_mcr_qualifiers[SIMD_MAX_BUILTIN_ARGS]
230 = { qualifier_void, qualifier_unsigned_immediate,
231 qualifier_unsigned_immediate, qualifier_none,
232 qualifier_unsigned_immediate, qualifier_unsigned_immediate,
233 qualifier_unsigned_immediate };
234 #define MCR_QUALIFIERS \
235 (arm_mcr_qualifiers)
237 /* T (unsigned immediate, unsigned immediate, unsigned immediate,
238 unsigned immediate, unsigned immediate). */
239 static enum arm_type_qualifiers
240 arm_mrc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
241 = { qualifier_none, qualifier_unsigned_immediate,
242 qualifier_unsigned_immediate, qualifier_unsigned_immediate,
243 qualifier_unsigned_immediate, qualifier_unsigned_immediate };
244 #define MRC_QUALIFIERS \
245 (arm_mrc_qualifiers)
247 /* void (unsigned immediate, unsigned immediate, T, unsigned immediate). */
248 static enum arm_type_qualifiers
249 arm_mcrr_qualifiers[SIMD_MAX_BUILTIN_ARGS]
250 = { qualifier_void, qualifier_unsigned_immediate,
251 qualifier_unsigned_immediate, qualifier_none,
252 qualifier_unsigned_immediate };
253 #define MCRR_QUALIFIERS \
254 (arm_mcrr_qualifiers)
256 /* T (unsigned immediate, unsigned immediate, unsigned immediate). */
257 static enum arm_type_qualifiers
258 arm_mrrc_qualifiers[SIMD_MAX_BUILTIN_ARGS]
259 = { qualifier_none, qualifier_unsigned_immediate,
260 qualifier_unsigned_immediate, qualifier_unsigned_immediate };
261 #define MRRC_QUALIFIERS \
262 (arm_mrrc_qualifiers)
264 /* T (immediate, unsigned immediate). */
265 static enum arm_type_qualifiers
266 arm_cx_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
267 = { qualifier_none, qualifier_immediate, qualifier_unsigned_immediate };
268 #define CX_IMM_QUALIFIERS (arm_cx_imm_qualifiers)
270 /* T (immediate, T, unsigned immediate). */
271 static enum arm_type_qualifiers
272 arm_cx_unary_qualifiers[SIMD_MAX_BUILTIN_ARGS]
273 = { qualifier_none, qualifier_immediate, qualifier_none,
274 qualifier_unsigned_immediate };
275 #define CX_UNARY_QUALIFIERS (arm_cx_unary_qualifiers)
277 /* T (immediate, T, T, unsigned immediate). */
278 static enum arm_type_qualifiers
279 arm_cx_binary_qualifiers[SIMD_MAX_BUILTIN_ARGS]
280 = { qualifier_none, qualifier_immediate,
281 qualifier_none, qualifier_none,
282 qualifier_unsigned_immediate };
283 #define CX_BINARY_QUALIFIERS (arm_cx_binary_qualifiers)
285 /* T (immediate, T, T, T, unsigned immediate). */
286 static enum arm_type_qualifiers
287 arm_cx_ternary_qualifiers[SIMD_MAX_BUILTIN_ARGS]
288 = { qualifier_none, qualifier_immediate,
289 qualifier_none, qualifier_none, qualifier_none,
290 qualifier_unsigned_immediate };
291 #define CX_TERNARY_QUALIFIERS (arm_cx_ternary_qualifiers)
293 /* T (immediate, T, unsigned immediate). */
294 static enum arm_type_qualifiers
295 arm_cx_unary_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
296 = { qualifier_none, qualifier_immediate, qualifier_none,
297 qualifier_unsigned_immediate,
298 qualifier_predicate };
299 #define CX_UNARY_UNONE_QUALIFIERS (arm_cx_unary_unone_qualifiers)
301 /* T (immediate, T, T, unsigned immediate). */
302 static enum arm_type_qualifiers
303 arm_cx_binary_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
304 = { qualifier_none, qualifier_immediate,
305 qualifier_none, qualifier_none,
306 qualifier_unsigned_immediate,
307 qualifier_predicate };
308 #define CX_BINARY_UNONE_QUALIFIERS (arm_cx_binary_unone_qualifiers)
310 /* T (immediate, T, T, T, unsigned immediate). */
311 static enum arm_type_qualifiers
312 arm_cx_ternary_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
313 = { qualifier_none, qualifier_immediate,
314 qualifier_none, qualifier_none, qualifier_none,
315 qualifier_unsigned_immediate,
316 qualifier_predicate };
317 #define CX_TERNARY_UNONE_QUALIFIERS (arm_cx_ternary_unone_qualifiers)
319 /* The first argument (return type) of a store should be void type,
320 which we represent with qualifier_void. Their first operand will be
321 a DImode pointer to the location to store to, so we must use
322 qualifier_map_mode | qualifier_pointer to build a pointer to the
323 element type of the vector.
325 void ([T element type] *, T). */
326 static enum arm_type_qualifiers
327 arm_store1_qualifiers[SIMD_MAX_BUILTIN_ARGS]
328 = { qualifier_void, qualifier_pointer_map_mode, qualifier_none };
329 #define STORE1_QUALIFIERS (arm_store1_qualifiers)
331 /* Qualifiers for MVE builtins. */
333 static enum arm_type_qualifiers
334 arm_unop_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
335 = { qualifier_none, qualifier_none };
336 #define UNOP_NONE_NONE_QUALIFIERS \
337 (arm_unop_none_none_qualifiers)
339 static enum arm_type_qualifiers
340 arm_unop_none_snone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
341 = { qualifier_none, qualifier_none };
342 #define UNOP_NONE_SNONE_QUALIFIERS \
343 (arm_unop_none_snone_qualifiers)
345 static enum arm_type_qualifiers
346 arm_unop_none_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
347 = { qualifier_none, qualifier_unsigned };
348 #define UNOP_NONE_UNONE_QUALIFIERS \
349 (arm_unop_none_unone_qualifiers)
351 static enum arm_type_qualifiers
352 arm_unop_snone_snone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
353 = { qualifier_none, qualifier_none };
354 #define UNOP_SNONE_SNONE_QUALIFIERS \
355 (arm_unop_snone_snone_qualifiers)
357 static enum arm_type_qualifiers
358 arm_unop_snone_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
359 = { qualifier_none, qualifier_none };
360 #define UNOP_SNONE_NONE_QUALIFIERS \
361 (arm_unop_snone_none_qualifiers)
363 static enum arm_type_qualifiers
364 arm_unop_snone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
365 = { qualifier_none, qualifier_immediate };
366 #define UNOP_SNONE_IMM_QUALIFIERS \
367 (arm_unop_snone_imm_qualifiers)
369 static enum arm_type_qualifiers
370 arm_unop_unone_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
371 = { qualifier_unsigned, qualifier_none };
372 #define UNOP_UNONE_NONE_QUALIFIERS \
373 (arm_unop_unone_none_qualifiers)
375 static enum arm_type_qualifiers
376 arm_unop_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
377 = { qualifier_unsigned, qualifier_unsigned };
378 #define UNOP_UNONE_UNONE_QUALIFIERS \
379 (arm_unop_unone_unone_qualifiers)
381 static enum arm_type_qualifiers
382 arm_unop_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
383 = { qualifier_unsigned, qualifier_immediate };
384 #define UNOP_UNONE_IMM_QUALIFIERS \
385 (arm_unop_unone_imm_qualifiers)
387 static enum arm_type_qualifiers
388 arm_unop_pred_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
389 = { qualifier_predicate, qualifier_unsigned };
390 #define UNOP_PRED_UNONE_QUALIFIERS \
391 (arm_unop_pred_unone_qualifiers)
393 static enum arm_type_qualifiers
394 arm_unop_pred_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
395 = { qualifier_predicate, qualifier_predicate };
396 #define UNOP_PRED_PRED_QUALIFIERS \
397 (arm_unop_pred_pred_qualifiers)
400 static enum arm_type_qualifiers
401 arm_binop_none_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
402 = { qualifier_none, qualifier_none, qualifier_none };
403 #define BINOP_NONE_NONE_NONE_QUALIFIERS \
404 (arm_binop_none_none_none_qualifiers)
406 static enum arm_type_qualifiers
407 arm_binop_none_none_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
408 = { qualifier_none, qualifier_none, qualifier_immediate };
409 #define BINOP_NONE_NONE_IMM_QUALIFIERS \
410 (arm_binop_none_none_imm_qualifiers)
412 static enum arm_type_qualifiers
413 arm_binop_none_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
414 = { qualifier_none, qualifier_unsigned, qualifier_immediate };
415 #define BINOP_NONE_UNONE_IMM_QUALIFIERS \
416 (arm_binop_none_unone_imm_qualifiers)
418 static enum arm_type_qualifiers
419 arm_binop_none_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
420 = { qualifier_none, qualifier_unsigned, qualifier_unsigned };
421 #define BINOP_NONE_UNONE_UNONE_QUALIFIERS \
422 (arm_binop_none_unone_unone_qualifiers)
424 static enum arm_type_qualifiers
425 arm_binop_unone_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
426 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate };
427 #define BINOP_UNONE_UNONE_IMM_QUALIFIERS \
428 (arm_binop_unone_unone_imm_qualifiers)
430 static enum arm_type_qualifiers
431 arm_binop_unone_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
432 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned };
433 #define BINOP_UNONE_UNONE_UNONE_QUALIFIERS \
434 (arm_binop_unone_unone_unone_qualifiers)
436 static enum arm_type_qualifiers
437 arm_binop_pred_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
438 = { qualifier_predicate, qualifier_unsigned, qualifier_unsigned };
439 #define BINOP_PRED_UNONE_UNONE_QUALIFIERS \
440 (arm_binop_pred_unone_unone_qualifiers)
442 static enum arm_type_qualifiers
443 arm_binop_pred_unone_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
444 = { qualifier_predicate, qualifier_unsigned, qualifier_predicate };
445 #define BINOP_PRED_UNONE_PRED_QUALIFIERS \
446 (arm_binop_pred_unone_pred_qualifiers)
448 static enum arm_type_qualifiers
449 arm_binop_unone_none_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
450 = { qualifier_unsigned, qualifier_none, qualifier_immediate };
451 #define BINOP_UNONE_NONE_IMM_QUALIFIERS \
452 (arm_binop_unone_none_imm_qualifiers)
454 static enum arm_type_qualifiers
455 arm_binop_pred_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
456 = { qualifier_predicate, qualifier_none, qualifier_none };
457 #define BINOP_PRED_NONE_NONE_QUALIFIERS \
458 (arm_binop_pred_none_none_qualifiers)
460 static enum arm_type_qualifiers
461 arm_binop_unone_unone_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
462 = { qualifier_unsigned, qualifier_unsigned, qualifier_none };
463 #define BINOP_UNONE_UNONE_NONE_QUALIFIERS \
464 (arm_binop_unone_unone_none_qualifiers)
466 static enum arm_type_qualifiers
467 arm_ternop_unone_unone_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
468 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
469 qualifier_immediate };
470 #define TERNOP_UNONE_UNONE_UNONE_IMM_QUALIFIERS \
471 (arm_ternop_unone_unone_unone_imm_qualifiers)
473 static enum arm_type_qualifiers
474 arm_ternop_unone_unone_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
475 = { qualifier_unsigned, qualifier_unsigned, qualifier_none, qualifier_none };
476 #define TERNOP_UNONE_UNONE_NONE_NONE_QUALIFIERS \
477 (arm_ternop_unone_unone_none_none_qualifiers)
479 static enum arm_type_qualifiers
480 arm_ternop_unone_none_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
481 = { qualifier_unsigned, qualifier_none, qualifier_unsigned,
482 qualifier_immediate };
483 #define TERNOP_UNONE_NONE_UNONE_IMM_QUALIFIERS \
484 (arm_ternop_unone_none_unone_imm_qualifiers)
486 static enum arm_type_qualifiers
487 arm_ternop_none_none_unone_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
488 = { qualifier_none, qualifier_none, qualifier_unsigned, qualifier_immediate };
489 #define TERNOP_NONE_NONE_UNONE_IMM_QUALIFIERS \
490 (arm_ternop_none_none_unone_imm_qualifiers)
492 static enum arm_type_qualifiers
493 arm_ternop_unone_unone_none_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
494 = { qualifier_unsigned, qualifier_unsigned, qualifier_none,
495 qualifier_immediate };
496 #define TERNOP_UNONE_UNONE_NONE_IMM_QUALIFIERS \
497 (arm_ternop_unone_unone_none_imm_qualifiers)
499 static enum arm_type_qualifiers
500 arm_ternop_unone_unone_none_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
501 = { qualifier_unsigned, qualifier_unsigned, qualifier_none,
502 qualifier_predicate };
503 #define TERNOP_UNONE_UNONE_NONE_PRED_QUALIFIERS \
504 (arm_ternop_unone_unone_none_pred_qualifiers)
506 static enum arm_type_qualifiers
507 arm_ternop_unone_unone_imm_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
508 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate,
509 qualifier_predicate };
510 #define TERNOP_UNONE_UNONE_IMM_PRED_QUALIFIERS \
511 (arm_ternop_unone_unone_imm_pred_qualifiers)
513 static enum arm_type_qualifiers
514 arm_ternop_pred_none_none_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
515 = { qualifier_predicate, qualifier_none, qualifier_none, qualifier_predicate };
516 #define TERNOP_PRED_NONE_NONE_PRED_QUALIFIERS \
517 (arm_ternop_pred_none_none_pred_qualifiers)
519 static enum arm_type_qualifiers
520 arm_ternop_none_none_none_imm_qualifiers[SIMD_MAX_BUILTIN_ARGS]
521 = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate };
522 #define TERNOP_NONE_NONE_NONE_IMM_QUALIFIERS \
523 (arm_ternop_none_none_none_imm_qualifiers)
525 static enum arm_type_qualifiers
526 arm_ternop_none_none_none_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
527 = { qualifier_none, qualifier_none, qualifier_none, qualifier_predicate };
528 #define TERNOP_NONE_NONE_NONE_PRED_QUALIFIERS \
529 (arm_ternop_none_none_none_pred_qualifiers)
531 static enum arm_type_qualifiers
532 arm_ternop_none_none_imm_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
533 = { qualifier_none, qualifier_none, qualifier_immediate, qualifier_predicate };
534 #define TERNOP_NONE_NONE_IMM_PRED_QUALIFIERS \
535 (arm_ternop_none_none_imm_pred_qualifiers)
537 static enum arm_type_qualifiers
538 arm_ternop_none_none_unone_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
539 = { qualifier_none, qualifier_none, qualifier_unsigned, qualifier_predicate };
540 #define TERNOP_NONE_NONE_UNONE_PRED_QUALIFIERS \
541 (arm_ternop_none_none_unone_pred_qualifiers)
543 static enum arm_type_qualifiers
544 arm_ternop_unone_unone_unone_unone_qualifiers[SIMD_MAX_BUILTIN_ARGS]
545 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
546 qualifier_unsigned };
547 #define TERNOP_UNONE_UNONE_UNONE_UNONE_QUALIFIERS \
548 (arm_ternop_unone_unone_unone_unone_qualifiers)
550 static enum arm_type_qualifiers
551 arm_ternop_unone_unone_unone_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
552 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
553 qualifier_predicate };
554 #define TERNOP_UNONE_UNONE_UNONE_PRED_QUALIFIERS \
555 (arm_ternop_unone_unone_unone_pred_qualifiers)
557 static enum arm_type_qualifiers
558 arm_ternop_pred_unone_unone_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
559 = { qualifier_predicate, qualifier_unsigned, qualifier_unsigned,
560 qualifier_predicate };
561 #define TERNOP_PRED_UNONE_UNONE_PRED_QUALIFIERS \
562 (arm_ternop_pred_unone_unone_pred_qualifiers)
564 static enum arm_type_qualifiers
565 arm_ternop_none_none_none_none_qualifiers[SIMD_MAX_BUILTIN_ARGS]
566 = { qualifier_none, qualifier_none, qualifier_none, qualifier_none };
567 #define TERNOP_NONE_NONE_NONE_NONE_QUALIFIERS \
568 (arm_ternop_none_none_none_none_qualifiers)
570 static enum arm_type_qualifiers
571 arm_quadop_unone_unone_none_none_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
572 = { qualifier_unsigned, qualifier_unsigned, qualifier_none, qualifier_none,
573 qualifier_predicate };
574 #define QUADOP_UNONE_UNONE_NONE_NONE_PRED_QUALIFIERS \
575 (arm_quadop_unone_unone_none_none_pred_qualifiers)
577 static enum arm_type_qualifiers
578 arm_quadop_none_none_none_none_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
579 = { qualifier_none, qualifier_none, qualifier_none, qualifier_none,
580 qualifier_predicate };
581 #define QUADOP_NONE_NONE_NONE_NONE_PRED_QUALIFIERS \
582 (arm_quadop_none_none_none_none_pred_qualifiers)
584 static enum arm_type_qualifiers
585 arm_quadop_none_none_none_imm_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
586 = { qualifier_none, qualifier_none, qualifier_none, qualifier_immediate,
587 qualifier_predicate };
588 #define QUADOP_NONE_NONE_NONE_IMM_PRED_QUALIFIERS \
589 (arm_quadop_none_none_none_imm_pred_qualifiers)
591 static enum arm_type_qualifiers
592 arm_quadop_unone_unone_unone_unone_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
593 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
594 qualifier_unsigned, qualifier_predicate };
595 #define QUADOP_UNONE_UNONE_UNONE_UNONE_PRED_QUALIFIERS \
596 (arm_quadop_unone_unone_unone_unone_pred_qualifiers)
598 static enum arm_type_qualifiers
599 arm_quadop_unone_unone_none_imm_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
600 = { qualifier_unsigned, qualifier_unsigned, qualifier_none,
601 qualifier_immediate, qualifier_predicate };
602 #define QUADOP_UNONE_UNONE_NONE_IMM_PRED_QUALIFIERS \
603 (arm_quadop_unone_unone_none_imm_pred_qualifiers)
605 static enum arm_type_qualifiers
606 arm_quadop_none_none_unone_imm_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
607 = { qualifier_none, qualifier_none, qualifier_unsigned, qualifier_immediate,
608 qualifier_predicate };
609 #define QUADOP_NONE_NONE_UNONE_IMM_PRED_QUALIFIERS \
610 (arm_quadop_none_none_unone_imm_pred_qualifiers)
612 static enum arm_type_qualifiers
613 arm_quadop_unone_unone_unone_imm_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
614 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
615 qualifier_immediate, qualifier_predicate };
616 #define QUADOP_UNONE_UNONE_UNONE_IMM_PRED_QUALIFIERS \
617 (arm_quadop_unone_unone_unone_imm_pred_qualifiers)
619 static enum arm_type_qualifiers
620 arm_quadop_unone_unone_unone_none_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
621 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
622 qualifier_none, qualifier_predicate };
623 #define QUADOP_UNONE_UNONE_UNONE_NONE_PRED_QUALIFIERS \
624 (arm_quadop_unone_unone_unone_none_pred_qualifiers)
626 static enum arm_type_qualifiers
627 arm_strs_qualifiers[SIMD_MAX_BUILTIN_ARGS]
628 = { qualifier_void, qualifier_pointer, qualifier_none };
629 #define STRS_QUALIFIERS (arm_strs_qualifiers)
631 static enum arm_type_qualifiers
632 arm_stru_qualifiers[SIMD_MAX_BUILTIN_ARGS]
633 = { qualifier_void, qualifier_pointer, qualifier_unsigned };
634 #define STRU_QUALIFIERS (arm_stru_qualifiers)
636 static enum arm_type_qualifiers
637 arm_strss_qualifiers[SIMD_MAX_BUILTIN_ARGS]
638 = { qualifier_void, qualifier_pointer, qualifier_unsigned,
639 qualifier_none};
640 #define STRSS_QUALIFIERS (arm_strss_qualifiers)
642 static enum arm_type_qualifiers
643 arm_strsu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
644 = { qualifier_void, qualifier_pointer, qualifier_unsigned,
645 qualifier_unsigned};
646 #define STRSU_QUALIFIERS (arm_strsu_qualifiers)
648 static enum arm_type_qualifiers
649 arm_strsbs_qualifiers[SIMD_MAX_BUILTIN_ARGS]
650 = { qualifier_void, qualifier_unsigned, qualifier_immediate, qualifier_none};
651 #define STRSBS_QUALIFIERS (arm_strsbs_qualifiers)
653 static enum arm_type_qualifiers
654 arm_strsbu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
655 = { qualifier_void, qualifier_unsigned, qualifier_immediate,
656 qualifier_unsigned};
657 #define STRSBU_QUALIFIERS (arm_strsbu_qualifiers)
659 static enum arm_type_qualifiers
660 arm_strs_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
661 = { qualifier_void, qualifier_pointer, qualifier_none, qualifier_predicate};
662 #define STRS_P_QUALIFIERS (arm_strs_p_qualifiers)
664 static enum arm_type_qualifiers
665 arm_stru_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
666 = { qualifier_void, qualifier_pointer, qualifier_unsigned,
667 qualifier_predicate};
668 #define STRU_P_QUALIFIERS (arm_stru_p_qualifiers)
670 static enum arm_type_qualifiers
671 arm_strsu_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
672 = { qualifier_void, qualifier_pointer, qualifier_unsigned,
673 qualifier_unsigned, qualifier_predicate};
674 #define STRSU_P_QUALIFIERS (arm_strsu_p_qualifiers)
676 static enum arm_type_qualifiers
677 arm_strss_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
678 = { qualifier_void, qualifier_pointer, qualifier_unsigned,
679 qualifier_none, qualifier_predicate};
680 #define STRSS_P_QUALIFIERS (arm_strss_p_qualifiers)
682 static enum arm_type_qualifiers
683 arm_strsbs_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
684 = { qualifier_void, qualifier_unsigned, qualifier_immediate,
685 qualifier_none, qualifier_predicate};
686 #define STRSBS_P_QUALIFIERS (arm_strsbs_p_qualifiers)
688 static enum arm_type_qualifiers
689 arm_strsbu_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
690 = { qualifier_void, qualifier_unsigned, qualifier_immediate,
691 qualifier_unsigned, qualifier_predicate};
692 #define STRSBU_P_QUALIFIERS (arm_strsbu_p_qualifiers)
694 static enum arm_type_qualifiers
695 arm_ldrgu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
696 = { qualifier_unsigned, qualifier_pointer, qualifier_unsigned};
697 #define LDRGU_QUALIFIERS (arm_ldrgu_qualifiers)
699 static enum arm_type_qualifiers
700 arm_ldrgs_qualifiers[SIMD_MAX_BUILTIN_ARGS]
701 = { qualifier_none, qualifier_pointer, qualifier_unsigned};
702 #define LDRGS_QUALIFIERS (arm_ldrgs_qualifiers)
704 static enum arm_type_qualifiers
705 arm_ldrs_qualifiers[SIMD_MAX_BUILTIN_ARGS]
706 = { qualifier_none, qualifier_pointer};
707 #define LDRS_QUALIFIERS (arm_ldrs_qualifiers)
709 static enum arm_type_qualifiers
710 arm_ldru_qualifiers[SIMD_MAX_BUILTIN_ARGS]
711 = { qualifier_unsigned, qualifier_pointer};
712 #define LDRU_QUALIFIERS (arm_ldru_qualifiers)
714 static enum arm_type_qualifiers
715 arm_ldrgbs_qualifiers[SIMD_MAX_BUILTIN_ARGS]
716 = { qualifier_none, qualifier_unsigned, qualifier_immediate};
717 #define LDRGBS_QUALIFIERS (arm_ldrgbs_qualifiers)
719 static enum arm_type_qualifiers
720 arm_ldrgbu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
721 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate};
722 #define LDRGBU_QUALIFIERS (arm_ldrgbu_qualifiers)
724 static enum arm_type_qualifiers
725 arm_ldrgbs_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
726 = { qualifier_none, qualifier_unsigned, qualifier_immediate,
727 qualifier_predicate};
728 #define LDRGBS_Z_QUALIFIERS (arm_ldrgbs_z_qualifiers)
730 static enum arm_type_qualifiers
731 arm_ldrgbu_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
732 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate,
733 qualifier_predicate};
734 #define LDRGBU_Z_QUALIFIERS (arm_ldrgbu_z_qualifiers)
736 static enum arm_type_qualifiers
737 arm_ldrgs_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
738 = { qualifier_none, qualifier_pointer, qualifier_unsigned,
739 qualifier_predicate};
740 #define LDRGS_Z_QUALIFIERS (arm_ldrgs_z_qualifiers)
742 static enum arm_type_qualifiers
743 arm_ldrgu_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
744 = { qualifier_unsigned, qualifier_pointer, qualifier_unsigned,
745 qualifier_predicate};
746 #define LDRGU_Z_QUALIFIERS (arm_ldrgu_z_qualifiers)
748 static enum arm_type_qualifiers
749 arm_ldrs_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
750 = { qualifier_none, qualifier_pointer, qualifier_predicate};
751 #define LDRS_Z_QUALIFIERS (arm_ldrs_z_qualifiers)
753 static enum arm_type_qualifiers
754 arm_ldru_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
755 = { qualifier_unsigned, qualifier_pointer, qualifier_predicate};
756 #define LDRU_Z_QUALIFIERS (arm_ldru_z_qualifiers)
758 static enum arm_type_qualifiers
759 arm_quinop_unone_unone_unone_unone_imm_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
760 = { qualifier_unsigned, qualifier_unsigned, qualifier_unsigned,
761 qualifier_unsigned, qualifier_immediate, qualifier_predicate };
762 #define QUINOP_UNONE_UNONE_UNONE_UNONE_IMM_PRED_QUALIFIERS \
763 (arm_quinop_unone_unone_unone_unone_imm_pred_qualifiers)
765 static enum arm_type_qualifiers
766 arm_ldrgbwbxu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
767 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate};
768 #define LDRGBWBXU_QUALIFIERS (arm_ldrgbwbxu_qualifiers)
770 static enum arm_type_qualifiers
771 arm_ldrgbwbxu_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
772 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate,
773 qualifier_predicate};
774 #define LDRGBWBXU_Z_QUALIFIERS (arm_ldrgbwbxu_z_qualifiers)
776 static enum arm_type_qualifiers
777 arm_ldrgbwbs_qualifiers[SIMD_MAX_BUILTIN_ARGS]
778 = { qualifier_none, qualifier_unsigned, qualifier_immediate};
779 #define LDRGBWBS_QUALIFIERS (arm_ldrgbwbs_qualifiers)
781 static enum arm_type_qualifiers
782 arm_ldrgbwbu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
783 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate};
784 #define LDRGBWBU_QUALIFIERS (arm_ldrgbwbu_qualifiers)
786 static enum arm_type_qualifiers
787 arm_ldrgbwbs_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
788 = { qualifier_none, qualifier_unsigned, qualifier_immediate,
789 qualifier_predicate};
790 #define LDRGBWBS_Z_QUALIFIERS (arm_ldrgbwbs_z_qualifiers)
792 static enum arm_type_qualifiers
793 arm_ldrgbwbu_z_qualifiers[SIMD_MAX_BUILTIN_ARGS]
794 = { qualifier_unsigned, qualifier_unsigned, qualifier_immediate,
795 qualifier_predicate};
796 #define LDRGBWBU_Z_QUALIFIERS (arm_ldrgbwbu_z_qualifiers)
798 static enum arm_type_qualifiers
799 arm_strsbwbs_qualifiers[SIMD_MAX_BUILTIN_ARGS]
800 = { qualifier_unsigned, qualifier_unsigned, qualifier_const, qualifier_none};
801 #define STRSBWBS_QUALIFIERS (arm_strsbwbs_qualifiers)
803 static enum arm_type_qualifiers
804 arm_strsbwbu_qualifiers[SIMD_MAX_BUILTIN_ARGS]
805 = { qualifier_unsigned, qualifier_unsigned, qualifier_const, qualifier_unsigned};
806 #define STRSBWBU_QUALIFIERS (arm_strsbwbu_qualifiers)
808 static enum arm_type_qualifiers
809 arm_strsbwbs_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
810 = { qualifier_unsigned, qualifier_unsigned, qualifier_const,
811 qualifier_none, qualifier_predicate};
812 #define STRSBWBS_P_QUALIFIERS (arm_strsbwbs_p_qualifiers)
814 static enum arm_type_qualifiers
815 arm_strsbwbu_p_qualifiers[SIMD_MAX_BUILTIN_ARGS]
816 = { qualifier_unsigned, qualifier_unsigned, qualifier_const,
817 qualifier_unsigned, qualifier_predicate};
818 #define STRSBWBU_P_QUALIFIERS (arm_strsbwbu_p_qualifiers)
820 static enum arm_type_qualifiers
821 arm_lsll_qualifiers[SIMD_MAX_BUILTIN_ARGS]
822 = { qualifier_unsigned, qualifier_unsigned, qualifier_none};
823 #define LSLL_QUALIFIERS (arm_lsll_qualifiers)
825 static enum arm_type_qualifiers
826 arm_uqshl_qualifiers[SIMD_MAX_BUILTIN_ARGS]
827 = { qualifier_unsigned, qualifier_unsigned, qualifier_const};
828 #define UQSHL_QUALIFIERS (arm_uqshl_qualifiers)
830 static enum arm_type_qualifiers
831 arm_asrl_qualifiers[SIMD_MAX_BUILTIN_ARGS]
832 = { qualifier_none, qualifier_none, qualifier_none};
833 #define ASRL_QUALIFIERS (arm_asrl_qualifiers)
835 static enum arm_type_qualifiers
836 arm_sqshl_qualifiers[SIMD_MAX_BUILTIN_ARGS]
837 = { qualifier_unsigned, qualifier_unsigned, qualifier_const};
838 #define SQSHL_QUALIFIERS (arm_sqshl_qualifiers)
840 static enum arm_type_qualifiers
841 arm_binop_none_none_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
842 = { qualifier_none, qualifier_none, qualifier_predicate };
843 #define BINOP_NONE_NONE_PRED_QUALIFIERS \
844 (arm_binop_none_none_pred_qualifiers)
846 static enum arm_type_qualifiers
847 arm_binop_unone_unone_pred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
848 = { qualifier_unsigned, qualifier_unsigned, qualifier_predicate };
849 #define BINOP_UNONE_UNONE_PRED_QUALIFIERS \
850 (arm_binop_unone_unone_pred_qualifiers)
852 /* End of Qualifier for MVE builtins. */
854 /* void ([T element type] *, T, immediate). */
855 static enum arm_type_qualifiers
856 arm_storestruct_lane_qualifiers[SIMD_MAX_BUILTIN_ARGS]
857 = { qualifier_void, qualifier_pointer_map_mode,
858 qualifier_none, qualifier_struct_load_store_lane_index };
859 #define STORE1LANE_QUALIFIERS (arm_storestruct_lane_qualifiers)
861 /* int (void). */
862 static enum arm_type_qualifiers
863 arm_sat_occurred_qualifiers[SIMD_MAX_BUILTIN_ARGS]
864 = { qualifier_none, qualifier_void };
865 #define SAT_OCCURRED_QUALIFIERS (arm_sat_occurred_qualifiers)
867 /* void (int). */
868 static enum arm_type_qualifiers
869 arm_set_sat_qualifiers[SIMD_MAX_BUILTIN_ARGS]
870 = { qualifier_void, qualifier_none };
871 #define SET_SAT_QUALIFIERS (arm_set_sat_qualifiers)
873 #define v2qi_UP E_V2QImode
874 #define v4bi_UP E_V4BImode
875 #define v8bi_UP E_V8BImode
876 #define v16bi_UP E_V16BImode
877 #define v8qi_UP E_V8QImode
878 #define v4hi_UP E_V4HImode
879 #define v4hf_UP E_V4HFmode
880 #define v4bf_UP E_V4BFmode
881 #define v2si_UP E_V2SImode
882 #define v2sf_UP E_V2SFmode
883 #define v2bf_UP E_V2BFmode
884 #define di_UP E_DImode
885 #define v16qi_UP E_V16QImode
886 #define v8hi_UP E_V8HImode
887 #define v8hf_UP E_V8HFmode
888 #define v8bf_UP E_V8BFmode
889 #define v4si_UP E_V4SImode
890 #define v4sf_UP E_V4SFmode
891 #define v2di_UP E_V2DImode
892 #define ti_UP E_TImode
893 #define ei_UP E_EImode
894 #define oi_UP E_OImode
895 #define hf_UP E_HFmode
896 #define bf_UP E_BFmode
897 #define si_UP E_SImode
898 #define hi_UP E_HImode
899 #define void_UP E_VOIDmode
900 #define sf_UP E_SFmode
901 #define UP(X) X##_UP
903 typedef struct {
904 const char *name;
905 machine_mode mode;
906 const enum insn_code code;
907 unsigned int fcode;
908 enum arm_type_qualifiers *qualifiers;
909 } arm_builtin_datum;
911 #define CF(N,X) CODE_FOR_neon_##N##X
913 #define VAR1(T, N, A) \
914 {#N #A, UP (A), CF (N, A), 0, T##_QUALIFIERS},
915 #define VAR2(T, N, A, B) \
916 VAR1 (T, N, A) \
917 VAR1 (T, N, B)
918 #define VAR3(T, N, A, B, C) \
919 VAR2 (T, N, A, B) \
920 VAR1 (T, N, C)
921 #define VAR4(T, N, A, B, C, D) \
922 VAR3 (T, N, A, B, C) \
923 VAR1 (T, N, D)
924 #define VAR5(T, N, A, B, C, D, E) \
925 VAR4 (T, N, A, B, C, D) \
926 VAR1 (T, N, E)
927 #define VAR6(T, N, A, B, C, D, E, F) \
928 VAR5 (T, N, A, B, C, D, E) \
929 VAR1 (T, N, F)
930 #define VAR7(T, N, A, B, C, D, E, F, G) \
931 VAR6 (T, N, A, B, C, D, E, F) \
932 VAR1 (T, N, G)
933 #define VAR8(T, N, A, B, C, D, E, F, G, H) \
934 VAR7 (T, N, A, B, C, D, E, F, G) \
935 VAR1 (T, N, H)
936 #define VAR9(T, N, A, B, C, D, E, F, G, H, I) \
937 VAR8 (T, N, A, B, C, D, E, F, G, H) \
938 VAR1 (T, N, I)
939 #define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \
940 VAR9 (T, N, A, B, C, D, E, F, G, H, I) \
941 VAR1 (T, N, J)
942 #define VAR11(T, N, A, B, C, D, E, F, G, H, I, J, K) \
943 VAR10 (T, N, A, B, C, D, E, F, G, H, I, J) \
944 VAR1 (T, N, K)
945 #define VAR12(T, N, A, B, C, D, E, F, G, H, I, J, K, L) \
946 VAR11 (T, N, A, B, C, D, E, F, G, H, I, J, K) \
947 VAR1 (T, N, L)
948 #define VAR13(T, N, A, B, C, D, E, F, G, H, I, J, K, L, M) \
949 VAR12 (T, N, A, B, C, D, E, F, G, H, I, J, K, L) \
950 VAR1 (T, N, M)
951 #define VAR14(T, N, A, B, C, D, E, F, G, H, I, J, K, L, M, O) \
952 VAR13 (T, N, A, B, C, D, E, F, G, H, I, J, K, L, M) \
953 VAR1 (T, N, O)
955 /* The builtin data can be found in arm_neon_builtins.def, arm_vfp_builtins.def
956 and arm_acle_builtins.def. The entries in arm_neon_builtins.def require
957 TARGET_NEON to be true. The feature tests are checked when the builtins are
958 expanded.
960 The mode entries in the following table correspond to the "key" type of the
961 instruction variant, i.e. equivalent to that which would be specified after
962 the assembler mnemonic for neon instructions, which usually refers to the
963 last vector operand. The modes listed per instruction should be the same as
964 those defined for that instruction's pattern, for instance in neon.md. */
966 static arm_builtin_datum vfp_builtin_data[] =
968 #include "arm_vfp_builtins.def"
971 static arm_builtin_datum neon_builtin_data[] =
973 #include "arm_neon_builtins.def"
976 #undef CF
977 #define CF(N,X) CODE_FOR_mve_##N##X
978 static arm_builtin_datum mve_builtin_data[] =
980 #include "arm_mve_builtins.def"
983 #undef CF
984 #undef VAR1
985 #define VAR1(T, N, A) \
986 {#N, UP (A), CODE_FOR_arm_##N, 0, T##_QUALIFIERS},
988 static arm_builtin_datum acle_builtin_data[] =
990 #include "arm_acle_builtins.def"
993 #undef VAR1
994 /* IMM_MAX sets the maximum valid value of the CDE immediate operand.
995 ECF_FLAG sets the flag used for set_call_expr_flags. */
996 #define VAR1(T, N, A, IMM_MAX, ECF_FLAG) \
997 {{#N #A, UP (A), CODE_FOR_arm_##N##A, 0, T##_QUALIFIERS}, IMM_MAX, ECF_FLAG},
999 typedef struct {
1000 arm_builtin_datum base;
1001 unsigned int imm_max;
1002 int ecf_flag;
1003 } arm_builtin_cde_datum;
1005 static arm_builtin_cde_datum cde_builtin_data[] =
1007 #include "arm_cde_builtins.def"
1010 #undef VAR1
1011 #define VAR1(T, N, X) \
1012 ARM_BUILTIN_NEON_##N##X,
1014 enum arm_builtins
1016 ARM_BUILTIN_GETWCGR0,
1017 ARM_BUILTIN_GETWCGR1,
1018 ARM_BUILTIN_GETWCGR2,
1019 ARM_BUILTIN_GETWCGR3,
1021 ARM_BUILTIN_SETWCGR0,
1022 ARM_BUILTIN_SETWCGR1,
1023 ARM_BUILTIN_SETWCGR2,
1024 ARM_BUILTIN_SETWCGR3,
1026 ARM_BUILTIN_WZERO,
1028 ARM_BUILTIN_WAVG2BR,
1029 ARM_BUILTIN_WAVG2HR,
1030 ARM_BUILTIN_WAVG2B,
1031 ARM_BUILTIN_WAVG2H,
1033 ARM_BUILTIN_WACCB,
1034 ARM_BUILTIN_WACCH,
1035 ARM_BUILTIN_WACCW,
1037 ARM_BUILTIN_WMACS,
1038 ARM_BUILTIN_WMACSZ,
1039 ARM_BUILTIN_WMACU,
1040 ARM_BUILTIN_WMACUZ,
1042 ARM_BUILTIN_WSADB,
1043 ARM_BUILTIN_WSADBZ,
1044 ARM_BUILTIN_WSADH,
1045 ARM_BUILTIN_WSADHZ,
1047 ARM_BUILTIN_WALIGNI,
1048 ARM_BUILTIN_WALIGNR0,
1049 ARM_BUILTIN_WALIGNR1,
1050 ARM_BUILTIN_WALIGNR2,
1051 ARM_BUILTIN_WALIGNR3,
1053 ARM_BUILTIN_TMIA,
1054 ARM_BUILTIN_TMIAPH,
1055 ARM_BUILTIN_TMIABB,
1056 ARM_BUILTIN_TMIABT,
1057 ARM_BUILTIN_TMIATB,
1058 ARM_BUILTIN_TMIATT,
1060 ARM_BUILTIN_TMOVMSKB,
1061 ARM_BUILTIN_TMOVMSKH,
1062 ARM_BUILTIN_TMOVMSKW,
1064 ARM_BUILTIN_TBCSTB,
1065 ARM_BUILTIN_TBCSTH,
1066 ARM_BUILTIN_TBCSTW,
1068 ARM_BUILTIN_WMADDS,
1069 ARM_BUILTIN_WMADDU,
1071 ARM_BUILTIN_WPACKHSS,
1072 ARM_BUILTIN_WPACKWSS,
1073 ARM_BUILTIN_WPACKDSS,
1074 ARM_BUILTIN_WPACKHUS,
1075 ARM_BUILTIN_WPACKWUS,
1076 ARM_BUILTIN_WPACKDUS,
1078 ARM_BUILTIN_WADDB,
1079 ARM_BUILTIN_WADDH,
1080 ARM_BUILTIN_WADDW,
1081 ARM_BUILTIN_WADDSSB,
1082 ARM_BUILTIN_WADDSSH,
1083 ARM_BUILTIN_WADDSSW,
1084 ARM_BUILTIN_WADDUSB,
1085 ARM_BUILTIN_WADDUSH,
1086 ARM_BUILTIN_WADDUSW,
1087 ARM_BUILTIN_WSUBB,
1088 ARM_BUILTIN_WSUBH,
1089 ARM_BUILTIN_WSUBW,
1090 ARM_BUILTIN_WSUBSSB,
1091 ARM_BUILTIN_WSUBSSH,
1092 ARM_BUILTIN_WSUBSSW,
1093 ARM_BUILTIN_WSUBUSB,
1094 ARM_BUILTIN_WSUBUSH,
1095 ARM_BUILTIN_WSUBUSW,
1097 ARM_BUILTIN_WAND,
1098 ARM_BUILTIN_WANDN,
1099 ARM_BUILTIN_WOR,
1100 ARM_BUILTIN_WXOR,
1102 ARM_BUILTIN_WCMPEQB,
1103 ARM_BUILTIN_WCMPEQH,
1104 ARM_BUILTIN_WCMPEQW,
1105 ARM_BUILTIN_WCMPGTUB,
1106 ARM_BUILTIN_WCMPGTUH,
1107 ARM_BUILTIN_WCMPGTUW,
1108 ARM_BUILTIN_WCMPGTSB,
1109 ARM_BUILTIN_WCMPGTSH,
1110 ARM_BUILTIN_WCMPGTSW,
1112 ARM_BUILTIN_TEXTRMSB,
1113 ARM_BUILTIN_TEXTRMSH,
1114 ARM_BUILTIN_TEXTRMSW,
1115 ARM_BUILTIN_TEXTRMUB,
1116 ARM_BUILTIN_TEXTRMUH,
1117 ARM_BUILTIN_TEXTRMUW,
1118 ARM_BUILTIN_TINSRB,
1119 ARM_BUILTIN_TINSRH,
1120 ARM_BUILTIN_TINSRW,
1122 ARM_BUILTIN_WMAXSW,
1123 ARM_BUILTIN_WMAXSH,
1124 ARM_BUILTIN_WMAXSB,
1125 ARM_BUILTIN_WMAXUW,
1126 ARM_BUILTIN_WMAXUH,
1127 ARM_BUILTIN_WMAXUB,
1128 ARM_BUILTIN_WMINSW,
1129 ARM_BUILTIN_WMINSH,
1130 ARM_BUILTIN_WMINSB,
1131 ARM_BUILTIN_WMINUW,
1132 ARM_BUILTIN_WMINUH,
1133 ARM_BUILTIN_WMINUB,
1135 ARM_BUILTIN_WMULUM,
1136 ARM_BUILTIN_WMULSM,
1137 ARM_BUILTIN_WMULUL,
1139 ARM_BUILTIN_PSADBH,
1140 ARM_BUILTIN_WSHUFH,
1142 ARM_BUILTIN_WSLLH,
1143 ARM_BUILTIN_WSLLW,
1144 ARM_BUILTIN_WSLLD,
1145 ARM_BUILTIN_WSRAH,
1146 ARM_BUILTIN_WSRAW,
1147 ARM_BUILTIN_WSRAD,
1148 ARM_BUILTIN_WSRLH,
1149 ARM_BUILTIN_WSRLW,
1150 ARM_BUILTIN_WSRLD,
1151 ARM_BUILTIN_WRORH,
1152 ARM_BUILTIN_WRORW,
1153 ARM_BUILTIN_WRORD,
1154 ARM_BUILTIN_WSLLHI,
1155 ARM_BUILTIN_WSLLWI,
1156 ARM_BUILTIN_WSLLDI,
1157 ARM_BUILTIN_WSRAHI,
1158 ARM_BUILTIN_WSRAWI,
1159 ARM_BUILTIN_WSRADI,
1160 ARM_BUILTIN_WSRLHI,
1161 ARM_BUILTIN_WSRLWI,
1162 ARM_BUILTIN_WSRLDI,
1163 ARM_BUILTIN_WRORHI,
1164 ARM_BUILTIN_WRORWI,
1165 ARM_BUILTIN_WRORDI,
1167 ARM_BUILTIN_WUNPCKIHB,
1168 ARM_BUILTIN_WUNPCKIHH,
1169 ARM_BUILTIN_WUNPCKIHW,
1170 ARM_BUILTIN_WUNPCKILB,
1171 ARM_BUILTIN_WUNPCKILH,
1172 ARM_BUILTIN_WUNPCKILW,
1174 ARM_BUILTIN_WUNPCKEHSB,
1175 ARM_BUILTIN_WUNPCKEHSH,
1176 ARM_BUILTIN_WUNPCKEHSW,
1177 ARM_BUILTIN_WUNPCKEHUB,
1178 ARM_BUILTIN_WUNPCKEHUH,
1179 ARM_BUILTIN_WUNPCKEHUW,
1180 ARM_BUILTIN_WUNPCKELSB,
1181 ARM_BUILTIN_WUNPCKELSH,
1182 ARM_BUILTIN_WUNPCKELSW,
1183 ARM_BUILTIN_WUNPCKELUB,
1184 ARM_BUILTIN_WUNPCKELUH,
1185 ARM_BUILTIN_WUNPCKELUW,
1187 ARM_BUILTIN_WABSB,
1188 ARM_BUILTIN_WABSH,
1189 ARM_BUILTIN_WABSW,
1191 ARM_BUILTIN_WADDSUBHX,
1192 ARM_BUILTIN_WSUBADDHX,
1194 ARM_BUILTIN_WABSDIFFB,
1195 ARM_BUILTIN_WABSDIFFH,
1196 ARM_BUILTIN_WABSDIFFW,
1198 ARM_BUILTIN_WADDCH,
1199 ARM_BUILTIN_WADDCW,
1201 ARM_BUILTIN_WAVG4,
1202 ARM_BUILTIN_WAVG4R,
1204 ARM_BUILTIN_WMADDSX,
1205 ARM_BUILTIN_WMADDUX,
1207 ARM_BUILTIN_WMADDSN,
1208 ARM_BUILTIN_WMADDUN,
1210 ARM_BUILTIN_WMULWSM,
1211 ARM_BUILTIN_WMULWUM,
1213 ARM_BUILTIN_WMULWSMR,
1214 ARM_BUILTIN_WMULWUMR,
1216 ARM_BUILTIN_WMULWL,
1218 ARM_BUILTIN_WMULSMR,
1219 ARM_BUILTIN_WMULUMR,
1221 ARM_BUILTIN_WQMULM,
1222 ARM_BUILTIN_WQMULMR,
1224 ARM_BUILTIN_WQMULWM,
1225 ARM_BUILTIN_WQMULWMR,
1227 ARM_BUILTIN_WADDBHUSM,
1228 ARM_BUILTIN_WADDBHUSL,
1230 ARM_BUILTIN_WQMIABB,
1231 ARM_BUILTIN_WQMIABT,
1232 ARM_BUILTIN_WQMIATB,
1233 ARM_BUILTIN_WQMIATT,
1235 ARM_BUILTIN_WQMIABBN,
1236 ARM_BUILTIN_WQMIABTN,
1237 ARM_BUILTIN_WQMIATBN,
1238 ARM_BUILTIN_WQMIATTN,
1240 ARM_BUILTIN_WMIABB,
1241 ARM_BUILTIN_WMIABT,
1242 ARM_BUILTIN_WMIATB,
1243 ARM_BUILTIN_WMIATT,
1245 ARM_BUILTIN_WMIABBN,
1246 ARM_BUILTIN_WMIABTN,
1247 ARM_BUILTIN_WMIATBN,
1248 ARM_BUILTIN_WMIATTN,
1250 ARM_BUILTIN_WMIAWBB,
1251 ARM_BUILTIN_WMIAWBT,
1252 ARM_BUILTIN_WMIAWTB,
1253 ARM_BUILTIN_WMIAWTT,
1255 ARM_BUILTIN_WMIAWBBN,
1256 ARM_BUILTIN_WMIAWBTN,
1257 ARM_BUILTIN_WMIAWTBN,
1258 ARM_BUILTIN_WMIAWTTN,
1260 ARM_BUILTIN_WMERGE,
1262 ARM_BUILTIN_GET_FPSCR,
1263 ARM_BUILTIN_SET_FPSCR,
1264 ARM_BUILTIN_GET_FPSCR_NZCVQC,
1265 ARM_BUILTIN_SET_FPSCR_NZCVQC,
1267 ARM_BUILTIN_CMSE_NONSECURE_CALLER,
1268 ARM_BUILTIN_SIMD_LANE_CHECK,
1270 #undef CRYPTO1
1271 #undef CRYPTO2
1272 #undef CRYPTO3
1274 #define CRYPTO1(L, U, M1, M2) \
1275 ARM_BUILTIN_CRYPTO_##U,
1276 #define CRYPTO2(L, U, M1, M2, M3) \
1277 ARM_BUILTIN_CRYPTO_##U,
1278 #define CRYPTO3(L, U, M1, M2, M3, M4) \
1279 ARM_BUILTIN_CRYPTO_##U,
1281 ARM_BUILTIN_CRYPTO_BASE,
1283 #include "crypto.def"
1285 #undef CRYPTO1
1286 #undef CRYPTO2
1287 #undef CRYPTO3
1289 ARM_BUILTIN_VFP_BASE,
1291 #include "arm_vfp_builtins.def"
1293 ARM_BUILTIN_NEON_BASE,
1295 #include "arm_neon_builtins.def"
1297 #undef VAR1
1298 #define VAR1(T, N, X) \
1299 ARM_BUILTIN_##N,
1301 ARM_BUILTIN_ACLE_BASE,
1302 ARM_BUILTIN_SAT_IMM_CHECK = ARM_BUILTIN_ACLE_BASE,
1304 #include "arm_acle_builtins.def"
1306 #undef VAR1
1307 #define VAR1(T, N, X, ... ) \
1308 ARM_BUILTIN_##N##X,
1310 ARM_BUILTIN_CDE_BASE,
1312 #include "arm_cde_builtins.def"
1314 ARM_BUILTIN_MVE_BASE,
1316 #undef VAR1
1317 #define VAR1(T, N, X) \
1318 ARM_BUILTIN_MVE_##N##X,
1319 #include "arm_mve_builtins.def"
1321 ARM_BUILTIN_MAX
1324 #define ARM_BUILTIN_VFP_PATTERN_START \
1325 (ARM_BUILTIN_VFP_BASE + 1)
1327 #define ARM_BUILTIN_NEON_PATTERN_START \
1328 (ARM_BUILTIN_NEON_BASE + 1)
1330 #define ARM_BUILTIN_MVE_PATTERN_START \
1331 (ARM_BUILTIN_MVE_BASE + 1)
1333 #define ARM_BUILTIN_ACLE_PATTERN_START \
1334 (ARM_BUILTIN_ACLE_BASE + 1)
1336 #define ARM_BUILTIN_CDE_PATTERN_START \
1337 (ARM_BUILTIN_CDE_BASE + 1)
1339 #define ARM_BUILTIN_CDE_PATTERN_END \
1340 (ARM_BUILTIN_CDE_BASE + ARRAY_SIZE (cde_builtin_data))
1342 #undef CF
1343 #undef VAR1
1344 #undef VAR2
1345 #undef VAR3
1346 #undef VAR4
1347 #undef VAR5
1348 #undef VAR6
1349 #undef VAR7
1350 #undef VAR8
1351 #undef VAR9
1352 #undef VAR10
1354 static GTY(()) tree arm_builtin_decls[ARM_BUILTIN_MAX];
1356 #define NUM_DREG_TYPES 5
1357 #define NUM_QREG_TYPES 6
1359 /* Internal scalar builtin types. These types are used to support
1360 neon intrinsic builtins. They are _not_ user-visible types. Therefore
1361 the mangling for these types are implementation defined. */
1362 const char *arm_scalar_builtin_types[] = {
1363 "__builtin_neon_qi",
1364 "__builtin_neon_hi",
1365 "__builtin_neon_si",
1366 "__builtin_neon_sf",
1367 "__builtin_neon_di",
1368 "__builtin_neon_df",
1369 "__builtin_neon_ti",
1370 "__builtin_neon_uqi",
1371 "__builtin_neon_uhi",
1372 "__builtin_neon_usi",
1373 "__builtin_neon_udi",
1374 "__builtin_neon_ei",
1375 "__builtin_neon_oi",
1376 "__builtin_neon_ci",
1377 "__builtin_neon_xi",
1378 "__builtin_neon_bf",
1379 NULL
1382 #define ENTRY(E, M, Q, S, T, G) \
1383 {E, \
1384 "__simd" #S "_" #T "_t", \
1385 #G "__simd" #S "_" #T "_t", \
1386 NULL_TREE, NULL_TREE, M##mode, qualifier_##Q},
1387 struct arm_simd_type_info arm_simd_types [] = {
1388 #include "arm-simd-builtin-types.def"
1390 #undef ENTRY
1392 /* The user-visible __fp16 type. */
1393 tree arm_fp16_type_node = NULL_TREE;
1395 /* Back-end node type for brain float (bfloat) types. */
1396 tree arm_bf16_type_node = NULL_TREE;
1397 tree arm_bf16_ptr_type_node = NULL_TREE;
1399 static tree arm_simd_intOI_type_node = NULL_TREE;
1400 static tree arm_simd_intEI_type_node = NULL_TREE;
1401 static tree arm_simd_intCI_type_node = NULL_TREE;
1402 static tree arm_simd_intXI_type_node = NULL_TREE;
1403 static tree arm_simd_polyQI_type_node = NULL_TREE;
1404 static tree arm_simd_polyHI_type_node = NULL_TREE;
1405 static tree arm_simd_polyDI_type_node = NULL_TREE;
1406 static tree arm_simd_polyTI_type_node = NULL_TREE;
1408 static const char *
1409 arm_mangle_builtin_scalar_type (const_tree type)
1411 int i = 0;
1413 while (arm_scalar_builtin_types[i] != NULL)
1415 const char *name = arm_scalar_builtin_types[i];
1417 if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
1418 && DECL_NAME (TYPE_NAME (type))
1419 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))), name))
1420 return arm_scalar_builtin_types[i];
1421 i++;
1423 return NULL;
1426 static const char *
1427 arm_mangle_builtin_vector_type (const_tree type)
1429 tree attrs = TYPE_ATTRIBUTES (type);
1430 if (tree attr = lookup_attribute ("Advanced SIMD type", attrs))
1432 tree mangled_name = TREE_VALUE (TREE_VALUE (attr));
1433 return IDENTIFIER_POINTER (mangled_name);
1436 return NULL;
1439 const char *
1440 arm_mangle_builtin_type (const_tree type)
1442 const char *mangle;
1443 /* Walk through all the Arm builtins types tables to filter out the
1444 incoming type. */
1445 if ((mangle = arm_mangle_builtin_vector_type (type))
1446 || (mangle = arm_mangle_builtin_scalar_type (type)))
1447 return mangle;
1449 return NULL;
1452 static tree
1453 arm_simd_builtin_std_type (machine_mode mode,
1454 enum arm_type_qualifiers q)
1456 #define QUAL_TYPE(M) \
1457 ((q == qualifier_none) ? int##M##_type_node : unsigned_int##M##_type_node);
1458 switch (mode)
1460 case E_QImode:
1461 return QUAL_TYPE (QI);
1462 case E_HImode:
1463 return QUAL_TYPE (HI);
1464 case E_SImode:
1465 return QUAL_TYPE (SI);
1466 case E_DImode:
1467 return QUAL_TYPE (DI);
1468 case E_TImode:
1469 return QUAL_TYPE (TI);
1470 case E_OImode:
1471 return arm_simd_intOI_type_node;
1472 case E_EImode:
1473 return arm_simd_intEI_type_node;
1474 case E_CImode:
1475 return arm_simd_intCI_type_node;
1476 case E_XImode:
1477 return arm_simd_intXI_type_node;
1478 case E_HFmode:
1479 return arm_fp16_type_node;
1480 case E_SFmode:
1481 return float_type_node;
1482 case E_DFmode:
1483 return double_type_node;
1484 case E_BFmode:
1485 return arm_bf16_type_node;
1486 default:
1487 gcc_unreachable ();
1489 #undef QUAL_TYPE
1492 static tree
1493 arm_lookup_simd_builtin_type (machine_mode mode,
1494 enum arm_type_qualifiers q)
1496 int i;
1497 int nelts = ARRAY_SIZE (arm_simd_types);
1499 /* Non-poly scalar modes map to standard types not in the table. */
1500 if (q != qualifier_poly && !VECTOR_MODE_P (mode))
1501 return arm_simd_builtin_std_type (mode, q);
1503 for (i = 0; i < nelts; i++)
1504 if (arm_simd_types[i].mode == mode
1505 && arm_simd_types[i].q == q)
1506 return arm_simd_types[i].itype;
1508 /* Note that we won't have caught the underlying type for poly64x2_t
1509 in the above table. This gets default mangling. */
1511 return NULL_TREE;
1514 static tree
1515 arm_simd_builtin_type (machine_mode mode, arm_type_qualifiers qualifiers)
1517 if ((qualifiers & qualifier_poly) != 0)
1518 return arm_lookup_simd_builtin_type (mode, qualifier_poly);
1519 else if ((qualifiers & qualifier_unsigned) != 0)
1520 return arm_lookup_simd_builtin_type (mode, qualifier_unsigned);
1521 else if ((qualifiers & qualifier_predicate) != 0)
1522 return unsigned_intHI_type_node;
1523 else
1524 return arm_lookup_simd_builtin_type (mode, qualifier_none);
1527 static void
1528 arm_init_simd_builtin_types (void)
1530 int i;
1531 int nelts = ARRAY_SIZE (arm_simd_types);
1532 tree tdecl;
1534 /* Poly types are a world of their own. In order to maintain legacy
1535 ABI, they get initialized using the old interface, and don't get
1536 an entry in our mangling table, consequently, they get default
1537 mangling. As a further gotcha, poly8_t and poly16_t are signed
1538 types, poly64_t and poly128_t are unsigned types. */
1539 if (!TARGET_HAVE_MVE)
1541 arm_simd_polyQI_type_node
1542 = build_distinct_type_copy (intQI_type_node);
1543 (*lang_hooks.types.register_builtin_type) (arm_simd_polyQI_type_node,
1544 "__builtin_neon_poly8");
1545 arm_simd_polyHI_type_node
1546 = build_distinct_type_copy (intHI_type_node);
1547 (*lang_hooks.types.register_builtin_type) (arm_simd_polyHI_type_node,
1548 "__builtin_neon_poly16");
1549 arm_simd_polyDI_type_node
1550 = build_distinct_type_copy (unsigned_intDI_type_node);
1551 (*lang_hooks.types.register_builtin_type) (arm_simd_polyDI_type_node,
1552 "__builtin_neon_poly64");
1553 arm_simd_polyTI_type_node
1554 = build_distinct_type_copy (unsigned_intTI_type_node);
1555 (*lang_hooks.types.register_builtin_type) (arm_simd_polyTI_type_node,
1556 "__builtin_neon_poly128");
1557 /* Init poly vector element types with scalar poly types. */
1558 arm_simd_types[Poly8x8_t].eltype = arm_simd_polyQI_type_node;
1559 arm_simd_types[Poly8x16_t].eltype = arm_simd_polyQI_type_node;
1560 arm_simd_types[Poly16x4_t].eltype = arm_simd_polyHI_type_node;
1561 arm_simd_types[Poly16x8_t].eltype = arm_simd_polyHI_type_node;
1562 /* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default
1563 mangling. */
1565 /* Prevent front-ends from transforming poly vectors into string
1566 literals. */
1567 TYPE_STRING_FLAG (arm_simd_polyQI_type_node) = false;
1568 TYPE_STRING_FLAG (arm_simd_polyHI_type_node) = false;
1570 /* Init all the element types built by the front-end. */
1571 arm_simd_types[Int8x8_t].eltype = intQI_type_node;
1572 arm_simd_types[Int8x16_t].eltype = intQI_type_node;
1573 arm_simd_types[Int16x4_t].eltype = intHI_type_node;
1574 arm_simd_types[Int16x8_t].eltype = intHI_type_node;
1575 arm_simd_types[Int32x2_t].eltype = intSI_type_node;
1576 arm_simd_types[Int32x4_t].eltype = intSI_type_node;
1577 arm_simd_types[Int64x2_t].eltype = intDI_type_node;
1578 arm_simd_types[Uint8x8_t].eltype = unsigned_intQI_type_node;
1579 arm_simd_types[Uint8x16_t].eltype = unsigned_intQI_type_node;
1580 arm_simd_types[Uint16x4_t].eltype = unsigned_intHI_type_node;
1581 arm_simd_types[Uint16x8_t].eltype = unsigned_intHI_type_node;
1582 arm_simd_types[Uint32x2_t].eltype = unsigned_intSI_type_node;
1583 arm_simd_types[Uint32x4_t].eltype = unsigned_intSI_type_node;
1584 arm_simd_types[Uint64x2_t].eltype = unsigned_intDI_type_node;
1586 /* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default
1587 mangling. */
1589 /* Continue with standard types. */
1590 /* The __builtin_simd{64,128}_float16 types are kept private unless
1591 we have a scalar __fp16 type. */
1592 arm_simd_types[Float16x4_t].eltype = arm_fp16_type_node;
1593 arm_simd_types[Float16x8_t].eltype = arm_fp16_type_node;
1594 arm_simd_types[Float32x2_t].eltype = float_type_node;
1595 arm_simd_types[Float32x4_t].eltype = float_type_node;
1597 /* Init Bfloat vector types with underlying __bf16 scalar type. */
1598 arm_simd_types[Bfloat16x2_t].eltype = arm_bf16_type_node;
1599 arm_simd_types[Bfloat16x4_t].eltype = arm_bf16_type_node;
1600 arm_simd_types[Bfloat16x8_t].eltype = arm_bf16_type_node;
1602 for (i = 0; i < nelts; i++)
1604 tree eltype = arm_simd_types[i].eltype;
1605 machine_mode mode = arm_simd_types[i].mode;
1607 if (eltype == NULL
1608 /* VECTOR_BOOL is not supported unless MVE is activated,
1609 this would make build_truth_vector_type_for_mode
1610 crash. */
1611 && ((GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
1612 || !TARGET_HAVE_MVE))
1613 continue;
1614 if (arm_simd_types[i].itype == NULL)
1616 tree type;
1617 if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
1619 /* Handle MVE predicates: they are internally stored as
1620 16 bits, but are used as vectors of 1, 2 or 4-bit
1621 elements. */
1622 type = build_truth_vector_type_for_mode (GET_MODE_NUNITS (mode),
1623 mode);
1624 eltype = TREE_TYPE (type);
1626 else
1627 type = build_vector_type (eltype, GET_MODE_NUNITS (mode));
1629 type = build_distinct_type_copy (type);
1630 SET_TYPE_STRUCTURAL_EQUALITY (type);
1632 tree mangled_name = get_identifier (arm_simd_types[i].mangle);
1633 tree value = tree_cons (NULL_TREE, mangled_name, NULL_TREE);
1634 TYPE_ATTRIBUTES (type)
1635 = tree_cons (get_identifier ("Advanced SIMD type"), value,
1636 TYPE_ATTRIBUTES (type));
1637 arm_simd_types[i].itype = type;
1640 tdecl = add_builtin_type (arm_simd_types[i].name,
1641 arm_simd_types[i].itype);
1642 TYPE_NAME (arm_simd_types[i].itype) = tdecl;
1643 SET_TYPE_STRUCTURAL_EQUALITY (arm_simd_types[i].itype);
1646 #define AARCH_BUILD_SIGNED_TYPE(mode) \
1647 make_signed_type (GET_MODE_PRECISION (mode));
1648 arm_simd_intOI_type_node = AARCH_BUILD_SIGNED_TYPE (OImode);
1649 arm_simd_intEI_type_node = AARCH_BUILD_SIGNED_TYPE (EImode);
1650 arm_simd_intCI_type_node = AARCH_BUILD_SIGNED_TYPE (CImode);
1651 arm_simd_intXI_type_node = AARCH_BUILD_SIGNED_TYPE (XImode);
1652 #undef AARCH_BUILD_SIGNED_TYPE
1654 tdecl = add_builtin_type
1655 ("__builtin_neon_ei" , arm_simd_intEI_type_node);
1656 TYPE_NAME (arm_simd_intEI_type_node) = tdecl;
1657 tdecl = add_builtin_type
1658 ("__builtin_neon_oi" , arm_simd_intOI_type_node);
1659 TYPE_NAME (arm_simd_intOI_type_node) = tdecl;
1660 tdecl = add_builtin_type
1661 ("__builtin_neon_ci" , arm_simd_intCI_type_node);
1662 TYPE_NAME (arm_simd_intCI_type_node) = tdecl;
1663 tdecl = add_builtin_type
1664 ("__builtin_neon_xi" , arm_simd_intXI_type_node);
1665 TYPE_NAME (arm_simd_intXI_type_node) = tdecl;
1668 static void
1669 arm_init_simd_builtin_scalar_types (void)
1671 /* Define typedefs for all the standard scalar types. */
1672 (*lang_hooks.types.register_builtin_type) (intQI_type_node,
1673 "__builtin_neon_qi");
1674 (*lang_hooks.types.register_builtin_type) (intHI_type_node,
1675 "__builtin_neon_hi");
1676 (*lang_hooks.types.register_builtin_type) (intSI_type_node,
1677 "__builtin_neon_si");
1678 (*lang_hooks.types.register_builtin_type) (float_type_node,
1679 "__builtin_neon_sf");
1680 (*lang_hooks.types.register_builtin_type) (intDI_type_node,
1681 "__builtin_neon_di");
1682 (*lang_hooks.types.register_builtin_type) (double_type_node,
1683 "__builtin_neon_df");
1684 (*lang_hooks.types.register_builtin_type) (intTI_type_node,
1685 "__builtin_neon_ti");
1686 (*lang_hooks.types.register_builtin_type) (arm_bf16_type_node,
1687 "__builtin_neon_bf");
1688 /* Unsigned integer types for various mode sizes. */
1689 (*lang_hooks.types.register_builtin_type) (unsigned_intQI_type_node,
1690 "__builtin_neon_uqi");
1691 (*lang_hooks.types.register_builtin_type) (unsigned_intHI_type_node,
1692 "__builtin_neon_uhi");
1693 (*lang_hooks.types.register_builtin_type) (unsigned_intSI_type_node,
1694 "__builtin_neon_usi");
1695 (*lang_hooks.types.register_builtin_type) (unsigned_intDI_type_node,
1696 "__builtin_neon_udi");
1697 (*lang_hooks.types.register_builtin_type) (unsigned_intTI_type_node,
1698 "__builtin_neon_uti");
1701 /* Set up a builtin. It will use information stored in the argument struct D to
1702 derive the builtin's type signature and name. It will append the name in D
1703 to the PREFIX passed and use these to create a builtin declaration that is
1704 then stored in 'arm_builtin_decls' under index FCODE. This FCODE is also
1705 written back to D for future use. */
1707 static void
1708 arm_init_builtin (unsigned int fcode, arm_builtin_datum *d,
1709 const char * prefix)
1711 bool print_type_signature_p = false;
1712 char type_signature[SIMD_MAX_BUILTIN_ARGS] = { 0 };
1713 char namebuf[60];
1714 tree ftype = NULL;
1715 tree fndecl = NULL;
1717 d->fcode = fcode;
1719 /* We must track two variables here. op_num is
1720 the operand number as in the RTL pattern. This is
1721 required to access the mode (e.g. V4SF mode) of the
1722 argument, from which the base type can be derived.
1723 arg_num is an index in to the qualifiers data, which
1724 gives qualifiers to the type (e.g. const unsigned).
1725 The reason these two variables may differ by one is the
1726 void return type. While all return types take the 0th entry
1727 in the qualifiers array, there is no operand for them in the
1728 RTL pattern. */
1729 int op_num = insn_data[d->code].n_operands - 1;
1730 int arg_num = d->qualifiers[0] & qualifier_void
1731 ? op_num + 1
1732 : op_num;
1733 tree return_type = void_type_node, args = void_list_node;
1734 tree eltype;
1736 /* Build a function type directly from the insn_data for this
1737 builtin. The build_function_type () function takes care of
1738 removing duplicates for us. */
1739 for (; op_num >= 0; arg_num--, op_num--)
1741 machine_mode op_mode = insn_data[d->code].operand[op_num].mode;
1742 enum arm_type_qualifiers qualifiers = d->qualifiers[arg_num];
1744 if (qualifiers & qualifier_unsigned)
1746 type_signature[arg_num] = 'u';
1747 print_type_signature_p = true;
1749 else if (qualifiers & qualifier_poly)
1751 type_signature[arg_num] = 'p';
1752 print_type_signature_p = true;
1754 else
1755 type_signature[arg_num] = 's';
1757 /* Skip an internal operand for vget_{low, high}. */
1758 if (qualifiers & qualifier_internal)
1759 continue;
1761 /* Some builtins have different user-facing types
1762 for certain arguments, encoded in d->mode. */
1763 if (qualifiers & qualifier_map_mode)
1764 op_mode = d->mode;
1766 /* MVE Predicates use HImode as mandated by the ABI: pred16_t is
1767 unsigned short. */
1768 if (qualifiers & qualifier_predicate)
1769 op_mode = HImode;
1771 /* For pointers, we want a pointer to the basic type
1772 of the vector. */
1773 if (qualifiers & qualifier_pointer && VECTOR_MODE_P (op_mode))
1774 op_mode = GET_MODE_INNER (op_mode);
1776 /* For void pointers we already have nodes constructed by the midend. */
1777 if (qualifiers & qualifier_void_pointer)
1778 eltype = qualifiers & qualifier_const
1779 ? const_ptr_type_node : ptr_type_node;
1780 else
1782 eltype
1783 = arm_simd_builtin_type (op_mode, qualifiers);
1784 gcc_assert (eltype != NULL);
1786 /* Add qualifiers. */
1787 if (qualifiers & qualifier_const)
1788 eltype = build_qualified_type (eltype, TYPE_QUAL_CONST);
1790 if (qualifiers & qualifier_pointer)
1791 eltype = build_pointer_type (eltype);
1793 /* If we have reached arg_num == 0, we are at a non-void
1794 return type. Otherwise, we are still processing
1795 arguments. */
1796 if (arg_num == 0)
1797 return_type = eltype;
1798 else
1799 args = tree_cons (NULL_TREE, eltype, args);
1802 ftype = build_function_type (return_type, args);
1804 gcc_assert (ftype != NULL);
1806 if (print_type_signature_p
1807 && IN_RANGE (fcode, ARM_BUILTIN_VFP_BASE, ARM_BUILTIN_ACLE_BASE - 1))
1808 snprintf (namebuf, sizeof (namebuf), "%s_%s_%s",
1809 prefix, d->name, type_signature);
1810 else
1811 snprintf (namebuf, sizeof (namebuf), "%s_%s",
1812 prefix, d->name);
1814 fndecl = add_builtin_function (namebuf, ftype, fcode, BUILT_IN_MD,
1815 NULL, NULL_TREE);
1816 arm_builtin_decls[fcode] = fndecl;
1819 /* Initialize the backend REAL_TYPE type supporting bfloat types. */
1820 static void
1821 arm_init_bf16_types (void)
1823 arm_bf16_type_node = make_node (REAL_TYPE);
1824 TYPE_PRECISION (arm_bf16_type_node) = 16;
1825 SET_TYPE_MODE (arm_bf16_type_node, BFmode);
1826 layout_type (arm_bf16_type_node);
1828 lang_hooks.types.register_builtin_type (arm_bf16_type_node, "__bf16");
1829 arm_bf16_ptr_type_node = build_pointer_type (arm_bf16_type_node);
1832 /* Set up ACLE builtins, even builtins for instructions that are not
1833 in the current target ISA to allow the user to compile particular modules
1834 with different target specific options that differ from the command line
1835 options. Such builtins will be rejected in arm_expand_builtin. */
1837 static void
1838 arm_init_acle_builtins (void)
1840 unsigned int i, fcode = ARM_BUILTIN_ACLE_PATTERN_START;
1842 tree sat_check_fpr = build_function_type_list (void_type_node,
1843 intSI_type_node,
1844 intSI_type_node,
1845 intSI_type_node,
1846 NULL);
1847 arm_builtin_decls[ARM_BUILTIN_SAT_IMM_CHECK]
1848 = add_builtin_function ("__builtin_sat_imm_check", sat_check_fpr,
1849 ARM_BUILTIN_SAT_IMM_CHECK, BUILT_IN_MD,
1850 NULL, NULL_TREE);
1852 for (i = 0; i < ARRAY_SIZE (acle_builtin_data); i++, fcode++)
1854 arm_builtin_datum *d = &acle_builtin_data[i];
1855 arm_init_builtin (fcode, d, "__builtin_arm");
1859 static void
1860 arm_init_cde_builtins (void)
1862 unsigned int i, fcode = ARM_BUILTIN_CDE_PATTERN_START;
1863 for (i = 0; i < ARRAY_SIZE (cde_builtin_data); i++, fcode++)
1865 /* Only define CDE floating point builtins if the target has floating
1866 point registers. NOTE: without HARD_FLOAT we don't have MVE, so we
1867 can break out of this loop directly here. */
1868 if (!TARGET_MAYBE_HARD_FLOAT && fcode >= ARM_BUILTIN_vcx1si)
1869 break;
1870 /* Only define CDE/MVE builtins if MVE is available. */
1871 if (!TARGET_HAVE_MVE && fcode >= ARM_BUILTIN_vcx1qv16qi)
1872 break;
1873 arm_builtin_cde_datum *cde = &cde_builtin_data[i];
1874 arm_builtin_datum *d = &cde->base;
1875 arm_init_builtin (fcode, d, "__builtin_arm");
1876 set_call_expr_flags (arm_builtin_decls[fcode], cde->ecf_flag);
1880 /* Set up all the MVE builtins mentioned in arm_mve_builtins.def file. */
1881 static void
1882 arm_init_mve_builtins (void)
1884 volatile unsigned int i, fcode = ARM_BUILTIN_MVE_PATTERN_START;
1886 arm_init_simd_builtin_scalar_types ();
1887 arm_init_simd_builtin_types ();
1889 /* Add support for __builtin_{get,set}_fpscr_nzcvqc, used by MVE intrinsics
1890 that read and/or write the carry bit. */
1891 tree get_fpscr_nzcvqc = build_function_type_list (intSI_type_node,
1892 NULL);
1893 tree set_fpscr_nzcvqc = build_function_type_list (void_type_node,
1894 intSI_type_node,
1895 NULL);
1896 arm_builtin_decls[ARM_BUILTIN_GET_FPSCR_NZCVQC]
1897 = add_builtin_function ("__builtin_arm_get_fpscr_nzcvqc", get_fpscr_nzcvqc,
1898 ARM_BUILTIN_GET_FPSCR_NZCVQC, BUILT_IN_MD, NULL,
1899 NULL_TREE);
1900 arm_builtin_decls[ARM_BUILTIN_SET_FPSCR_NZCVQC]
1901 = add_builtin_function ("__builtin_arm_set_fpscr_nzcvqc", set_fpscr_nzcvqc,
1902 ARM_BUILTIN_SET_FPSCR_NZCVQC, BUILT_IN_MD, NULL,
1903 NULL_TREE);
1905 for (i = 0; i < ARRAY_SIZE (mve_builtin_data); i++, fcode++)
1907 arm_builtin_datum *d = &mve_builtin_data[i];
1908 arm_init_builtin (fcode, d, "__builtin_mve");
1912 /* Set up all the NEON builtins, even builtins for instructions that are not
1913 in the current target ISA to allow the user to compile particular modules
1914 with different target specific options that differ from the command line
1915 options. Such builtins will be rejected in arm_expand_builtin. */
1917 static void
1918 arm_init_neon_builtins (void)
1920 unsigned int i, fcode = ARM_BUILTIN_NEON_PATTERN_START;
1922 arm_init_simd_builtin_types ();
1924 /* Strong-typing hasn't been implemented for all AdvSIMD builtin intrinsics.
1925 Therefore we need to preserve the old __builtin scalar types. It can be
1926 removed once all the intrinsics become strongly typed using the qualifier
1927 system. */
1928 arm_init_simd_builtin_scalar_types ();
1930 for (i = 0; i < ARRAY_SIZE (neon_builtin_data); i++, fcode++)
1932 arm_builtin_datum *d = &neon_builtin_data[i];
1933 arm_init_builtin (fcode, d, "__builtin_neon");
1937 /* Set up all the scalar floating point builtins. */
1939 static void
1940 arm_init_vfp_builtins (void)
1942 unsigned int i, fcode = ARM_BUILTIN_VFP_PATTERN_START;
1944 for (i = 0; i < ARRAY_SIZE (vfp_builtin_data); i++, fcode++)
1946 arm_builtin_datum *d = &vfp_builtin_data[i];
1947 arm_init_builtin (fcode, d, "__builtin_neon");
1951 static void
1952 arm_init_crypto_builtins (void)
1954 tree V16UQI_type_node
1955 = arm_simd_builtin_type (V16QImode, qualifier_unsigned);
1957 tree V4USI_type_node
1958 = arm_simd_builtin_type (V4SImode, qualifier_unsigned);
1960 tree v16uqi_ftype_v16uqi
1961 = build_function_type_list (V16UQI_type_node, V16UQI_type_node,
1962 NULL_TREE);
1964 tree v16uqi_ftype_v16uqi_v16uqi
1965 = build_function_type_list (V16UQI_type_node, V16UQI_type_node,
1966 V16UQI_type_node, NULL_TREE);
1968 tree v4usi_ftype_v4usi
1969 = build_function_type_list (V4USI_type_node, V4USI_type_node,
1970 NULL_TREE);
1972 tree v4usi_ftype_v4usi_v4usi
1973 = build_function_type_list (V4USI_type_node, V4USI_type_node,
1974 V4USI_type_node, NULL_TREE);
1976 tree v4usi_ftype_v4usi_v4usi_v4usi
1977 = build_function_type_list (V4USI_type_node, V4USI_type_node,
1978 V4USI_type_node, V4USI_type_node,
1979 NULL_TREE);
1981 tree uti_ftype_udi_udi
1982 = build_function_type_list (unsigned_intTI_type_node,
1983 unsigned_intDI_type_node,
1984 unsigned_intDI_type_node,
1985 NULL_TREE);
1987 #undef CRYPTO1
1988 #undef CRYPTO2
1989 #undef CRYPTO3
1990 #undef C
1991 #undef N
1992 #undef CF
1993 #undef FT1
1994 #undef FT2
1995 #undef FT3
1997 #define C(U) \
1998 ARM_BUILTIN_CRYPTO_##U
1999 #define N(L) \
2000 "__builtin_arm_crypto_"#L
2001 #define FT1(R, A) \
2002 R##_ftype_##A
2003 #define FT2(R, A1, A2) \
2004 R##_ftype_##A1##_##A2
2005 #define FT3(R, A1, A2, A3) \
2006 R##_ftype_##A1##_##A2##_##A3
2007 #define CRYPTO1(L, U, R, A) \
2008 arm_builtin_decls[C (U)] \
2009 = add_builtin_function (N (L), FT1 (R, A), \
2010 C (U), BUILT_IN_MD, NULL, NULL_TREE);
2011 #define CRYPTO2(L, U, R, A1, A2) \
2012 arm_builtin_decls[C (U)] \
2013 = add_builtin_function (N (L), FT2 (R, A1, A2), \
2014 C (U), BUILT_IN_MD, NULL, NULL_TREE);
2016 #define CRYPTO3(L, U, R, A1, A2, A3) \
2017 arm_builtin_decls[C (U)] \
2018 = add_builtin_function (N (L), FT3 (R, A1, A2, A3), \
2019 C (U), BUILT_IN_MD, NULL, NULL_TREE);
2020 #include "crypto.def"
2022 #undef CRYPTO1
2023 #undef CRYPTO2
2024 #undef CRYPTO3
2025 #undef C
2026 #undef N
2027 #undef FT1
2028 #undef FT2
2029 #undef FT3
2032 #undef NUM_DREG_TYPES
2033 #undef NUM_QREG_TYPES
2035 #define def_mbuiltin(FLAG, NAME, TYPE, CODE) \
2036 do \
2038 if (FLAG == isa_nobit \
2039 || bitmap_bit_p (arm_active_target.isa, FLAG)) \
2041 tree bdecl; \
2042 bdecl = add_builtin_function ((NAME), (TYPE), (CODE), \
2043 BUILT_IN_MD, NULL, NULL_TREE); \
2044 arm_builtin_decls[CODE] = bdecl; \
2047 while (0)
2049 struct builtin_description
2051 const enum isa_feature feature;
2052 const enum insn_code icode;
2053 const char * const name;
2054 const enum arm_builtins code;
2055 const enum rtx_code comparison;
2056 const unsigned int flag;
2059 static const struct builtin_description bdesc_2arg[] =
2061 #define IWMMXT_BUILTIN(code, string, builtin) \
2062 { isa_bit_iwmmxt, CODE_FOR_##code, \
2063 "__builtin_arm_" string, \
2064 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
2066 #define IWMMXT2_BUILTIN(code, string, builtin) \
2067 { isa_bit_iwmmxt2, CODE_FOR_##code, \
2068 "__builtin_arm_" string, \
2069 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
2071 IWMMXT_BUILTIN (addv8qi3, "waddb", WADDB)
2072 IWMMXT_BUILTIN (addv4hi3, "waddh", WADDH)
2073 IWMMXT_BUILTIN (addv2si3, "waddw", WADDW)
2074 IWMMXT_BUILTIN (subv8qi3, "wsubb", WSUBB)
2075 IWMMXT_BUILTIN (subv4hi3, "wsubh", WSUBH)
2076 IWMMXT_BUILTIN (subv2si3, "wsubw", WSUBW)
2077 IWMMXT_BUILTIN (ssaddv8qi3, "waddbss", WADDSSB)
2078 IWMMXT_BUILTIN (ssaddv4hi3, "waddhss", WADDSSH)
2079 IWMMXT_BUILTIN (ssaddv2si3, "waddwss", WADDSSW)
2080 IWMMXT_BUILTIN (sssubv8qi3, "wsubbss", WSUBSSB)
2081 IWMMXT_BUILTIN (sssubv4hi3, "wsubhss", WSUBSSH)
2082 IWMMXT_BUILTIN (sssubv2si3, "wsubwss", WSUBSSW)
2083 IWMMXT_BUILTIN (usaddv8qi3, "waddbus", WADDUSB)
2084 IWMMXT_BUILTIN (usaddv4hi3, "waddhus", WADDUSH)
2085 IWMMXT_BUILTIN (usaddv2si3, "waddwus", WADDUSW)
2086 IWMMXT_BUILTIN (ussubv8qi3, "wsubbus", WSUBUSB)
2087 IWMMXT_BUILTIN (ussubv4hi3, "wsubhus", WSUBUSH)
2088 IWMMXT_BUILTIN (ussubv2si3, "wsubwus", WSUBUSW)
2089 IWMMXT_BUILTIN (mulv4hi3, "wmulul", WMULUL)
2090 IWMMXT_BUILTIN (smulv4hi3_highpart, "wmulsm", WMULSM)
2091 IWMMXT_BUILTIN (umulv4hi3_highpart, "wmulum", WMULUM)
2092 IWMMXT_BUILTIN (eqv8qi3, "wcmpeqb", WCMPEQB)
2093 IWMMXT_BUILTIN (eqv4hi3, "wcmpeqh", WCMPEQH)
2094 IWMMXT_BUILTIN (eqv2si3, "wcmpeqw", WCMPEQW)
2095 IWMMXT_BUILTIN (gtuv8qi3, "wcmpgtub", WCMPGTUB)
2096 IWMMXT_BUILTIN (gtuv4hi3, "wcmpgtuh", WCMPGTUH)
2097 IWMMXT_BUILTIN (gtuv2si3, "wcmpgtuw", WCMPGTUW)
2098 IWMMXT_BUILTIN (gtv8qi3, "wcmpgtsb", WCMPGTSB)
2099 IWMMXT_BUILTIN (gtv4hi3, "wcmpgtsh", WCMPGTSH)
2100 IWMMXT_BUILTIN (gtv2si3, "wcmpgtsw", WCMPGTSW)
2101 IWMMXT_BUILTIN (umaxv8qi3, "wmaxub", WMAXUB)
2102 IWMMXT_BUILTIN (smaxv8qi3, "wmaxsb", WMAXSB)
2103 IWMMXT_BUILTIN (umaxv4hi3, "wmaxuh", WMAXUH)
2104 IWMMXT_BUILTIN (smaxv4hi3, "wmaxsh", WMAXSH)
2105 IWMMXT_BUILTIN (umaxv2si3, "wmaxuw", WMAXUW)
2106 IWMMXT_BUILTIN (smaxv2si3, "wmaxsw", WMAXSW)
2107 IWMMXT_BUILTIN (uminv8qi3, "wminub", WMINUB)
2108 IWMMXT_BUILTIN (sminv8qi3, "wminsb", WMINSB)
2109 IWMMXT_BUILTIN (uminv4hi3, "wminuh", WMINUH)
2110 IWMMXT_BUILTIN (sminv4hi3, "wminsh", WMINSH)
2111 IWMMXT_BUILTIN (uminv2si3, "wminuw", WMINUW)
2112 IWMMXT_BUILTIN (sminv2si3, "wminsw", WMINSW)
2113 IWMMXT_BUILTIN (iwmmxt_anddi3, "wand", WAND)
2114 IWMMXT_BUILTIN (iwmmxt_nanddi3, "wandn", WANDN)
2115 IWMMXT_BUILTIN (iwmmxt_iordi3, "wor", WOR)
2116 IWMMXT_BUILTIN (iwmmxt_xordi3, "wxor", WXOR)
2117 IWMMXT_BUILTIN (iwmmxt_uavgv8qi3, "wavg2b", WAVG2B)
2118 IWMMXT_BUILTIN (iwmmxt_uavgv4hi3, "wavg2h", WAVG2H)
2119 IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3, "wavg2br", WAVG2BR)
2120 IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3, "wavg2hr", WAVG2HR)
2121 IWMMXT_BUILTIN (iwmmxt_wunpckilb, "wunpckilb", WUNPCKILB)
2122 IWMMXT_BUILTIN (iwmmxt_wunpckilh, "wunpckilh", WUNPCKILH)
2123 IWMMXT_BUILTIN (iwmmxt_wunpckilw, "wunpckilw", WUNPCKILW)
2124 IWMMXT_BUILTIN (iwmmxt_wunpckihb, "wunpckihb", WUNPCKIHB)
2125 IWMMXT_BUILTIN (iwmmxt_wunpckihh, "wunpckihh", WUNPCKIHH)
2126 IWMMXT_BUILTIN (iwmmxt_wunpckihw, "wunpckihw", WUNPCKIHW)
2127 IWMMXT2_BUILTIN (iwmmxt_waddsubhx, "waddsubhx", WADDSUBHX)
2128 IWMMXT2_BUILTIN (iwmmxt_wsubaddhx, "wsubaddhx", WSUBADDHX)
2129 IWMMXT2_BUILTIN (iwmmxt_wabsdiffb, "wabsdiffb", WABSDIFFB)
2130 IWMMXT2_BUILTIN (iwmmxt_wabsdiffh, "wabsdiffh", WABSDIFFH)
2131 IWMMXT2_BUILTIN (iwmmxt_wabsdiffw, "wabsdiffw", WABSDIFFW)
2132 IWMMXT2_BUILTIN (iwmmxt_avg4, "wavg4", WAVG4)
2133 IWMMXT2_BUILTIN (iwmmxt_avg4r, "wavg4r", WAVG4R)
2134 IWMMXT2_BUILTIN (iwmmxt_wmulwsm, "wmulwsm", WMULWSM)
2135 IWMMXT2_BUILTIN (iwmmxt_wmulwum, "wmulwum", WMULWUM)
2136 IWMMXT2_BUILTIN (iwmmxt_wmulwsmr, "wmulwsmr", WMULWSMR)
2137 IWMMXT2_BUILTIN (iwmmxt_wmulwumr, "wmulwumr", WMULWUMR)
2138 IWMMXT2_BUILTIN (iwmmxt_wmulwl, "wmulwl", WMULWL)
2139 IWMMXT2_BUILTIN (iwmmxt_wmulsmr, "wmulsmr", WMULSMR)
2140 IWMMXT2_BUILTIN (iwmmxt_wmulumr, "wmulumr", WMULUMR)
2141 IWMMXT2_BUILTIN (iwmmxt_wqmulm, "wqmulm", WQMULM)
2142 IWMMXT2_BUILTIN (iwmmxt_wqmulmr, "wqmulmr", WQMULMR)
2143 IWMMXT2_BUILTIN (iwmmxt_wqmulwm, "wqmulwm", WQMULWM)
2144 IWMMXT2_BUILTIN (iwmmxt_wqmulwmr, "wqmulwmr", WQMULWMR)
2145 IWMMXT_BUILTIN (iwmmxt_walignr0, "walignr0", WALIGNR0)
2146 IWMMXT_BUILTIN (iwmmxt_walignr1, "walignr1", WALIGNR1)
2147 IWMMXT_BUILTIN (iwmmxt_walignr2, "walignr2", WALIGNR2)
2148 IWMMXT_BUILTIN (iwmmxt_walignr3, "walignr3", WALIGNR3)
2150 #define IWMMXT_BUILTIN2(code, builtin) \
2151 { isa_bit_iwmmxt, CODE_FOR_##code, NULL, \
2152 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
2154 #define IWMMXT2_BUILTIN2(code, builtin) \
2155 { isa_bit_iwmmxt2, CODE_FOR_##code, NULL, \
2156 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
2158 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusm, WADDBHUSM)
2159 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusl, WADDBHUSL)
2160 IWMMXT_BUILTIN2 (iwmmxt_wpackhss, WPACKHSS)
2161 IWMMXT_BUILTIN2 (iwmmxt_wpackwss, WPACKWSS)
2162 IWMMXT_BUILTIN2 (iwmmxt_wpackdss, WPACKDSS)
2163 IWMMXT_BUILTIN2 (iwmmxt_wpackhus, WPACKHUS)
2164 IWMMXT_BUILTIN2 (iwmmxt_wpackwus, WPACKWUS)
2165 IWMMXT_BUILTIN2 (iwmmxt_wpackdus, WPACKDUS)
2166 IWMMXT_BUILTIN2 (iwmmxt_wmacuz, WMACUZ)
2167 IWMMXT_BUILTIN2 (iwmmxt_wmacsz, WMACSZ)
2170 #define FP_BUILTIN(L, U) \
2171 {isa_nobit, CODE_FOR_##L, "__builtin_arm_"#L, ARM_BUILTIN_##U, \
2172 UNKNOWN, 0},
2174 FP_BUILTIN (get_fpscr, GET_FPSCR)
2175 FP_BUILTIN (set_fpscr, SET_FPSCR)
2176 #undef FP_BUILTIN
2178 #define CRYPTO_BUILTIN(L, U) \
2179 {isa_nobit, CODE_FOR_crypto_##L, "__builtin_arm_crypto_"#L, \
2180 ARM_BUILTIN_CRYPTO_##U, UNKNOWN, 0},
2181 #undef CRYPTO1
2182 #undef CRYPTO2
2183 #undef CRYPTO3
2184 #define CRYPTO2(L, U, R, A1, A2) CRYPTO_BUILTIN (L, U)
2185 #define CRYPTO1(L, U, R, A)
2186 #define CRYPTO3(L, U, R, A1, A2, A3)
2187 #include "crypto.def"
2188 #undef CRYPTO1
2189 #undef CRYPTO2
2190 #undef CRYPTO3
2194 static const struct builtin_description bdesc_1arg[] =
2196 IWMMXT_BUILTIN (iwmmxt_tmovmskb, "tmovmskb", TMOVMSKB)
2197 IWMMXT_BUILTIN (iwmmxt_tmovmskh, "tmovmskh", TMOVMSKH)
2198 IWMMXT_BUILTIN (iwmmxt_tmovmskw, "tmovmskw", TMOVMSKW)
2199 IWMMXT_BUILTIN (iwmmxt_waccb, "waccb", WACCB)
2200 IWMMXT_BUILTIN (iwmmxt_wacch, "wacch", WACCH)
2201 IWMMXT_BUILTIN (iwmmxt_waccw, "waccw", WACCW)
2202 IWMMXT_BUILTIN (iwmmxt_wunpckehub, "wunpckehub", WUNPCKEHUB)
2203 IWMMXT_BUILTIN (iwmmxt_wunpckehuh, "wunpckehuh", WUNPCKEHUH)
2204 IWMMXT_BUILTIN (iwmmxt_wunpckehuw, "wunpckehuw", WUNPCKEHUW)
2205 IWMMXT_BUILTIN (iwmmxt_wunpckehsb, "wunpckehsb", WUNPCKEHSB)
2206 IWMMXT_BUILTIN (iwmmxt_wunpckehsh, "wunpckehsh", WUNPCKEHSH)
2207 IWMMXT_BUILTIN (iwmmxt_wunpckehsw, "wunpckehsw", WUNPCKEHSW)
2208 IWMMXT_BUILTIN (iwmmxt_wunpckelub, "wunpckelub", WUNPCKELUB)
2209 IWMMXT_BUILTIN (iwmmxt_wunpckeluh, "wunpckeluh", WUNPCKELUH)
2210 IWMMXT_BUILTIN (iwmmxt_wunpckeluw, "wunpckeluw", WUNPCKELUW)
2211 IWMMXT_BUILTIN (iwmmxt_wunpckelsb, "wunpckelsb", WUNPCKELSB)
2212 IWMMXT_BUILTIN (iwmmxt_wunpckelsh, "wunpckelsh", WUNPCKELSH)
2213 IWMMXT_BUILTIN (iwmmxt_wunpckelsw, "wunpckelsw", WUNPCKELSW)
2214 IWMMXT2_BUILTIN (iwmmxt_wabsv8qi3, "wabsb", WABSB)
2215 IWMMXT2_BUILTIN (iwmmxt_wabsv4hi3, "wabsh", WABSH)
2216 IWMMXT2_BUILTIN (iwmmxt_wabsv2si3, "wabsw", WABSW)
2217 IWMMXT_BUILTIN (tbcstv8qi, "tbcstb", TBCSTB)
2218 IWMMXT_BUILTIN (tbcstv4hi, "tbcsth", TBCSTH)
2219 IWMMXT_BUILTIN (tbcstv2si, "tbcstw", TBCSTW)
2221 #define CRYPTO1(L, U, R, A) CRYPTO_BUILTIN (L, U)
2222 #define CRYPTO2(L, U, R, A1, A2)
2223 #define CRYPTO3(L, U, R, A1, A2, A3)
2224 #include "crypto.def"
2225 #undef CRYPTO1
2226 #undef CRYPTO2
2227 #undef CRYPTO3
2230 static const struct builtin_description bdesc_3arg[] =
2232 #define CRYPTO3(L, U, R, A1, A2, A3) CRYPTO_BUILTIN (L, U)
2233 #define CRYPTO1(L, U, R, A)
2234 #define CRYPTO2(L, U, R, A1, A2)
2235 #include "crypto.def"
2236 #undef CRYPTO1
2237 #undef CRYPTO2
2238 #undef CRYPTO3
2240 #undef CRYPTO_BUILTIN
2242 /* Set up all the iWMMXt builtins. This is not called if
2243 TARGET_IWMMXT is zero. */
2245 static void
2246 arm_init_iwmmxt_builtins (void)
2248 const struct builtin_description * d;
2249 size_t i;
2251 tree V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
2252 tree V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
2253 tree V8QI_type_node = build_vector_type_for_mode (intQI_type_node, V8QImode);
2255 tree v8qi_ftype_v8qi_v8qi_int
2256 = build_function_type_list (V8QI_type_node,
2257 V8QI_type_node, V8QI_type_node,
2258 integer_type_node, NULL_TREE);
2259 tree v4hi_ftype_v4hi_int
2260 = build_function_type_list (V4HI_type_node,
2261 V4HI_type_node, integer_type_node, NULL_TREE);
2262 tree v2si_ftype_v2si_int
2263 = build_function_type_list (V2SI_type_node,
2264 V2SI_type_node, integer_type_node, NULL_TREE);
2265 tree v2si_ftype_di_di
2266 = build_function_type_list (V2SI_type_node,
2267 long_long_integer_type_node,
2268 long_long_integer_type_node,
2269 NULL_TREE);
2270 tree di_ftype_di_int
2271 = build_function_type_list (long_long_integer_type_node,
2272 long_long_integer_type_node,
2273 integer_type_node, NULL_TREE);
2274 tree di_ftype_di_int_int
2275 = build_function_type_list (long_long_integer_type_node,
2276 long_long_integer_type_node,
2277 integer_type_node,
2278 integer_type_node, NULL_TREE);
2279 tree int_ftype_v8qi
2280 = build_function_type_list (integer_type_node,
2281 V8QI_type_node, NULL_TREE);
2282 tree int_ftype_v4hi
2283 = build_function_type_list (integer_type_node,
2284 V4HI_type_node, NULL_TREE);
2285 tree int_ftype_v2si
2286 = build_function_type_list (integer_type_node,
2287 V2SI_type_node, NULL_TREE);
2288 tree int_ftype_v8qi_int
2289 = build_function_type_list (integer_type_node,
2290 V8QI_type_node, integer_type_node, NULL_TREE);
2291 tree int_ftype_v4hi_int
2292 = build_function_type_list (integer_type_node,
2293 V4HI_type_node, integer_type_node, NULL_TREE);
2294 tree int_ftype_v2si_int
2295 = build_function_type_list (integer_type_node,
2296 V2SI_type_node, integer_type_node, NULL_TREE);
2297 tree v8qi_ftype_v8qi_int_int
2298 = build_function_type_list (V8QI_type_node,
2299 V8QI_type_node, integer_type_node,
2300 integer_type_node, NULL_TREE);
2301 tree v4hi_ftype_v4hi_int_int
2302 = build_function_type_list (V4HI_type_node,
2303 V4HI_type_node, integer_type_node,
2304 integer_type_node, NULL_TREE);
2305 tree v2si_ftype_v2si_int_int
2306 = build_function_type_list (V2SI_type_node,
2307 V2SI_type_node, integer_type_node,
2308 integer_type_node, NULL_TREE);
2309 /* Miscellaneous. */
2310 tree v8qi_ftype_v4hi_v4hi
2311 = build_function_type_list (V8QI_type_node,
2312 V4HI_type_node, V4HI_type_node, NULL_TREE);
2313 tree v4hi_ftype_v2si_v2si
2314 = build_function_type_list (V4HI_type_node,
2315 V2SI_type_node, V2SI_type_node, NULL_TREE);
2316 tree v8qi_ftype_v4hi_v8qi
2317 = build_function_type_list (V8QI_type_node,
2318 V4HI_type_node, V8QI_type_node, NULL_TREE);
2319 tree v2si_ftype_v4hi_v4hi
2320 = build_function_type_list (V2SI_type_node,
2321 V4HI_type_node, V4HI_type_node, NULL_TREE);
2322 tree v2si_ftype_v8qi_v8qi
2323 = build_function_type_list (V2SI_type_node,
2324 V8QI_type_node, V8QI_type_node, NULL_TREE);
2325 tree v4hi_ftype_v4hi_di
2326 = build_function_type_list (V4HI_type_node,
2327 V4HI_type_node, long_long_integer_type_node,
2328 NULL_TREE);
2329 tree v2si_ftype_v2si_di
2330 = build_function_type_list (V2SI_type_node,
2331 V2SI_type_node, long_long_integer_type_node,
2332 NULL_TREE);
2333 tree di_ftype_void
2334 = build_function_type_list (long_long_unsigned_type_node, NULL_TREE);
2335 tree int_ftype_void
2336 = build_function_type_list (integer_type_node, NULL_TREE);
2337 tree di_ftype_v8qi
2338 = build_function_type_list (long_long_integer_type_node,
2339 V8QI_type_node, NULL_TREE);
2340 tree di_ftype_v4hi
2341 = build_function_type_list (long_long_integer_type_node,
2342 V4HI_type_node, NULL_TREE);
2343 tree di_ftype_v2si
2344 = build_function_type_list (long_long_integer_type_node,
2345 V2SI_type_node, NULL_TREE);
2346 tree v2si_ftype_v4hi
2347 = build_function_type_list (V2SI_type_node,
2348 V4HI_type_node, NULL_TREE);
2349 tree v4hi_ftype_v8qi
2350 = build_function_type_list (V4HI_type_node,
2351 V8QI_type_node, NULL_TREE);
2352 tree v8qi_ftype_v8qi
2353 = build_function_type_list (V8QI_type_node,
2354 V8QI_type_node, NULL_TREE);
2355 tree v4hi_ftype_v4hi
2356 = build_function_type_list (V4HI_type_node,
2357 V4HI_type_node, NULL_TREE);
2358 tree v2si_ftype_v2si
2359 = build_function_type_list (V2SI_type_node,
2360 V2SI_type_node, NULL_TREE);
2362 tree di_ftype_di_v4hi_v4hi
2363 = build_function_type_list (long_long_unsigned_type_node,
2364 long_long_unsigned_type_node,
2365 V4HI_type_node, V4HI_type_node,
2366 NULL_TREE);
2368 tree di_ftype_v4hi_v4hi
2369 = build_function_type_list (long_long_unsigned_type_node,
2370 V4HI_type_node,V4HI_type_node,
2371 NULL_TREE);
2373 tree v2si_ftype_v2si_v4hi_v4hi
2374 = build_function_type_list (V2SI_type_node,
2375 V2SI_type_node, V4HI_type_node,
2376 V4HI_type_node, NULL_TREE);
2378 tree v2si_ftype_v2si_v8qi_v8qi
2379 = build_function_type_list (V2SI_type_node,
2380 V2SI_type_node, V8QI_type_node,
2381 V8QI_type_node, NULL_TREE);
2383 tree di_ftype_di_v2si_v2si
2384 = build_function_type_list (long_long_unsigned_type_node,
2385 long_long_unsigned_type_node,
2386 V2SI_type_node, V2SI_type_node,
2387 NULL_TREE);
2389 tree di_ftype_di_di_int
2390 = build_function_type_list (long_long_unsigned_type_node,
2391 long_long_unsigned_type_node,
2392 long_long_unsigned_type_node,
2393 integer_type_node, NULL_TREE);
2395 tree void_ftype_int
2396 = build_function_type_list (void_type_node,
2397 integer_type_node, NULL_TREE);
2399 tree v8qi_ftype_char
2400 = build_function_type_list (V8QI_type_node,
2401 signed_char_type_node, NULL_TREE);
2403 tree v4hi_ftype_short
2404 = build_function_type_list (V4HI_type_node,
2405 short_integer_type_node, NULL_TREE);
2407 tree v2si_ftype_int
2408 = build_function_type_list (V2SI_type_node,
2409 integer_type_node, NULL_TREE);
2411 /* Normal vector binops. */
2412 tree v8qi_ftype_v8qi_v8qi
2413 = build_function_type_list (V8QI_type_node,
2414 V8QI_type_node, V8QI_type_node, NULL_TREE);
2415 tree v4hi_ftype_v4hi_v4hi
2416 = build_function_type_list (V4HI_type_node,
2417 V4HI_type_node,V4HI_type_node, NULL_TREE);
2418 tree v2si_ftype_v2si_v2si
2419 = build_function_type_list (V2SI_type_node,
2420 V2SI_type_node, V2SI_type_node, NULL_TREE);
2421 tree di_ftype_di_di
2422 = build_function_type_list (long_long_unsigned_type_node,
2423 long_long_unsigned_type_node,
2424 long_long_unsigned_type_node,
2425 NULL_TREE);
2427 /* Add all builtins that are more or less simple operations on two
2428 operands. */
2429 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
2431 /* Use one of the operands; the target can have a different mode for
2432 mask-generating compares. */
2433 machine_mode mode;
2434 tree type;
2436 if (d->name == 0
2437 || !(d->feature == isa_bit_iwmmxt
2438 || d->feature == isa_bit_iwmmxt2))
2439 continue;
2441 mode = insn_data[d->icode].operand[1].mode;
2443 switch (mode)
2445 case E_V8QImode:
2446 type = v8qi_ftype_v8qi_v8qi;
2447 break;
2448 case E_V4HImode:
2449 type = v4hi_ftype_v4hi_v4hi;
2450 break;
2451 case E_V2SImode:
2452 type = v2si_ftype_v2si_v2si;
2453 break;
2454 case E_DImode:
2455 type = di_ftype_di_di;
2456 break;
2458 default:
2459 gcc_unreachable ();
2462 def_mbuiltin (d->feature, d->name, type, d->code);
2465 /* Add the remaining MMX insns with somewhat more complicated types. */
2466 #define iwmmx_mbuiltin(NAME, TYPE, CODE) \
2467 def_mbuiltin (isa_bit_iwmmxt, "__builtin_arm_" NAME, \
2468 (TYPE), ARM_BUILTIN_ ## CODE)
2470 #define iwmmx2_mbuiltin(NAME, TYPE, CODE) \
2471 def_mbuiltin (isa_bit_iwmmxt2, "__builtin_arm_" NAME, \
2472 (TYPE), ARM_BUILTIN_ ## CODE)
2474 iwmmx_mbuiltin ("wzero", di_ftype_void, WZERO);
2475 iwmmx_mbuiltin ("setwcgr0", void_ftype_int, SETWCGR0);
2476 iwmmx_mbuiltin ("setwcgr1", void_ftype_int, SETWCGR1);
2477 iwmmx_mbuiltin ("setwcgr2", void_ftype_int, SETWCGR2);
2478 iwmmx_mbuiltin ("setwcgr3", void_ftype_int, SETWCGR3);
2479 iwmmx_mbuiltin ("getwcgr0", int_ftype_void, GETWCGR0);
2480 iwmmx_mbuiltin ("getwcgr1", int_ftype_void, GETWCGR1);
2481 iwmmx_mbuiltin ("getwcgr2", int_ftype_void, GETWCGR2);
2482 iwmmx_mbuiltin ("getwcgr3", int_ftype_void, GETWCGR3);
2484 iwmmx_mbuiltin ("wsllh", v4hi_ftype_v4hi_di, WSLLH);
2485 iwmmx_mbuiltin ("wsllw", v2si_ftype_v2si_di, WSLLW);
2486 iwmmx_mbuiltin ("wslld", di_ftype_di_di, WSLLD);
2487 iwmmx_mbuiltin ("wsllhi", v4hi_ftype_v4hi_int, WSLLHI);
2488 iwmmx_mbuiltin ("wsllwi", v2si_ftype_v2si_int, WSLLWI);
2489 iwmmx_mbuiltin ("wslldi", di_ftype_di_int, WSLLDI);
2491 iwmmx_mbuiltin ("wsrlh", v4hi_ftype_v4hi_di, WSRLH);
2492 iwmmx_mbuiltin ("wsrlw", v2si_ftype_v2si_di, WSRLW);
2493 iwmmx_mbuiltin ("wsrld", di_ftype_di_di, WSRLD);
2494 iwmmx_mbuiltin ("wsrlhi", v4hi_ftype_v4hi_int, WSRLHI);
2495 iwmmx_mbuiltin ("wsrlwi", v2si_ftype_v2si_int, WSRLWI);
2496 iwmmx_mbuiltin ("wsrldi", di_ftype_di_int, WSRLDI);
2498 iwmmx_mbuiltin ("wsrah", v4hi_ftype_v4hi_di, WSRAH);
2499 iwmmx_mbuiltin ("wsraw", v2si_ftype_v2si_di, WSRAW);
2500 iwmmx_mbuiltin ("wsrad", di_ftype_di_di, WSRAD);
2501 iwmmx_mbuiltin ("wsrahi", v4hi_ftype_v4hi_int, WSRAHI);
2502 iwmmx_mbuiltin ("wsrawi", v2si_ftype_v2si_int, WSRAWI);
2503 iwmmx_mbuiltin ("wsradi", di_ftype_di_int, WSRADI);
2505 iwmmx_mbuiltin ("wrorh", v4hi_ftype_v4hi_di, WRORH);
2506 iwmmx_mbuiltin ("wrorw", v2si_ftype_v2si_di, WRORW);
2507 iwmmx_mbuiltin ("wrord", di_ftype_di_di, WRORD);
2508 iwmmx_mbuiltin ("wrorhi", v4hi_ftype_v4hi_int, WRORHI);
2509 iwmmx_mbuiltin ("wrorwi", v2si_ftype_v2si_int, WRORWI);
2510 iwmmx_mbuiltin ("wrordi", di_ftype_di_int, WRORDI);
2512 iwmmx_mbuiltin ("wshufh", v4hi_ftype_v4hi_int, WSHUFH);
2514 iwmmx_mbuiltin ("wsadb", v2si_ftype_v2si_v8qi_v8qi, WSADB);
2515 iwmmx_mbuiltin ("wsadh", v2si_ftype_v2si_v4hi_v4hi, WSADH);
2516 iwmmx_mbuiltin ("wmadds", v2si_ftype_v4hi_v4hi, WMADDS);
2517 iwmmx2_mbuiltin ("wmaddsx", v2si_ftype_v4hi_v4hi, WMADDSX);
2518 iwmmx2_mbuiltin ("wmaddsn", v2si_ftype_v4hi_v4hi, WMADDSN);
2519 iwmmx_mbuiltin ("wmaddu", v2si_ftype_v4hi_v4hi, WMADDU);
2520 iwmmx2_mbuiltin ("wmaddux", v2si_ftype_v4hi_v4hi, WMADDUX);
2521 iwmmx2_mbuiltin ("wmaddun", v2si_ftype_v4hi_v4hi, WMADDUN);
2522 iwmmx_mbuiltin ("wsadbz", v2si_ftype_v8qi_v8qi, WSADBZ);
2523 iwmmx_mbuiltin ("wsadhz", v2si_ftype_v4hi_v4hi, WSADHZ);
2525 iwmmx_mbuiltin ("textrmsb", int_ftype_v8qi_int, TEXTRMSB);
2526 iwmmx_mbuiltin ("textrmsh", int_ftype_v4hi_int, TEXTRMSH);
2527 iwmmx_mbuiltin ("textrmsw", int_ftype_v2si_int, TEXTRMSW);
2528 iwmmx_mbuiltin ("textrmub", int_ftype_v8qi_int, TEXTRMUB);
2529 iwmmx_mbuiltin ("textrmuh", int_ftype_v4hi_int, TEXTRMUH);
2530 iwmmx_mbuiltin ("textrmuw", int_ftype_v2si_int, TEXTRMUW);
2531 iwmmx_mbuiltin ("tinsrb", v8qi_ftype_v8qi_int_int, TINSRB);
2532 iwmmx_mbuiltin ("tinsrh", v4hi_ftype_v4hi_int_int, TINSRH);
2533 iwmmx_mbuiltin ("tinsrw", v2si_ftype_v2si_int_int, TINSRW);
2535 iwmmx_mbuiltin ("waccb", di_ftype_v8qi, WACCB);
2536 iwmmx_mbuiltin ("wacch", di_ftype_v4hi, WACCH);
2537 iwmmx_mbuiltin ("waccw", di_ftype_v2si, WACCW);
2539 iwmmx_mbuiltin ("tmovmskb", int_ftype_v8qi, TMOVMSKB);
2540 iwmmx_mbuiltin ("tmovmskh", int_ftype_v4hi, TMOVMSKH);
2541 iwmmx_mbuiltin ("tmovmskw", int_ftype_v2si, TMOVMSKW);
2543 iwmmx2_mbuiltin ("waddbhusm", v8qi_ftype_v4hi_v8qi, WADDBHUSM);
2544 iwmmx2_mbuiltin ("waddbhusl", v8qi_ftype_v4hi_v8qi, WADDBHUSL);
2546 iwmmx_mbuiltin ("wpackhss", v8qi_ftype_v4hi_v4hi, WPACKHSS);
2547 iwmmx_mbuiltin ("wpackhus", v8qi_ftype_v4hi_v4hi, WPACKHUS);
2548 iwmmx_mbuiltin ("wpackwus", v4hi_ftype_v2si_v2si, WPACKWUS);
2549 iwmmx_mbuiltin ("wpackwss", v4hi_ftype_v2si_v2si, WPACKWSS);
2550 iwmmx_mbuiltin ("wpackdus", v2si_ftype_di_di, WPACKDUS);
2551 iwmmx_mbuiltin ("wpackdss", v2si_ftype_di_di, WPACKDSS);
2553 iwmmx_mbuiltin ("wunpckehub", v4hi_ftype_v8qi, WUNPCKEHUB);
2554 iwmmx_mbuiltin ("wunpckehuh", v2si_ftype_v4hi, WUNPCKEHUH);
2555 iwmmx_mbuiltin ("wunpckehuw", di_ftype_v2si, WUNPCKEHUW);
2556 iwmmx_mbuiltin ("wunpckehsb", v4hi_ftype_v8qi, WUNPCKEHSB);
2557 iwmmx_mbuiltin ("wunpckehsh", v2si_ftype_v4hi, WUNPCKEHSH);
2558 iwmmx_mbuiltin ("wunpckehsw", di_ftype_v2si, WUNPCKEHSW);
2559 iwmmx_mbuiltin ("wunpckelub", v4hi_ftype_v8qi, WUNPCKELUB);
2560 iwmmx_mbuiltin ("wunpckeluh", v2si_ftype_v4hi, WUNPCKELUH);
2561 iwmmx_mbuiltin ("wunpckeluw", di_ftype_v2si, WUNPCKELUW);
2562 iwmmx_mbuiltin ("wunpckelsb", v4hi_ftype_v8qi, WUNPCKELSB);
2563 iwmmx_mbuiltin ("wunpckelsh", v2si_ftype_v4hi, WUNPCKELSH);
2564 iwmmx_mbuiltin ("wunpckelsw", di_ftype_v2si, WUNPCKELSW);
2566 iwmmx_mbuiltin ("wmacs", di_ftype_di_v4hi_v4hi, WMACS);
2567 iwmmx_mbuiltin ("wmacsz", di_ftype_v4hi_v4hi, WMACSZ);
2568 iwmmx_mbuiltin ("wmacu", di_ftype_di_v4hi_v4hi, WMACU);
2569 iwmmx_mbuiltin ("wmacuz", di_ftype_v4hi_v4hi, WMACUZ);
2571 iwmmx_mbuiltin ("walign", v8qi_ftype_v8qi_v8qi_int, WALIGNI);
2572 iwmmx_mbuiltin ("tmia", di_ftype_di_int_int, TMIA);
2573 iwmmx_mbuiltin ("tmiaph", di_ftype_di_int_int, TMIAPH);
2574 iwmmx_mbuiltin ("tmiabb", di_ftype_di_int_int, TMIABB);
2575 iwmmx_mbuiltin ("tmiabt", di_ftype_di_int_int, TMIABT);
2576 iwmmx_mbuiltin ("tmiatb", di_ftype_di_int_int, TMIATB);
2577 iwmmx_mbuiltin ("tmiatt", di_ftype_di_int_int, TMIATT);
2579 iwmmx2_mbuiltin ("wabsb", v8qi_ftype_v8qi, WABSB);
2580 iwmmx2_mbuiltin ("wabsh", v4hi_ftype_v4hi, WABSH);
2581 iwmmx2_mbuiltin ("wabsw", v2si_ftype_v2si, WABSW);
2583 iwmmx2_mbuiltin ("wqmiabb", v2si_ftype_v2si_v4hi_v4hi, WQMIABB);
2584 iwmmx2_mbuiltin ("wqmiabt", v2si_ftype_v2si_v4hi_v4hi, WQMIABT);
2585 iwmmx2_mbuiltin ("wqmiatb", v2si_ftype_v2si_v4hi_v4hi, WQMIATB);
2586 iwmmx2_mbuiltin ("wqmiatt", v2si_ftype_v2si_v4hi_v4hi, WQMIATT);
2588 iwmmx2_mbuiltin ("wqmiabbn", v2si_ftype_v2si_v4hi_v4hi, WQMIABBN);
2589 iwmmx2_mbuiltin ("wqmiabtn", v2si_ftype_v2si_v4hi_v4hi, WQMIABTN);
2590 iwmmx2_mbuiltin ("wqmiatbn", v2si_ftype_v2si_v4hi_v4hi, WQMIATBN);
2591 iwmmx2_mbuiltin ("wqmiattn", v2si_ftype_v2si_v4hi_v4hi, WQMIATTN);
2593 iwmmx2_mbuiltin ("wmiabb", di_ftype_di_v4hi_v4hi, WMIABB);
2594 iwmmx2_mbuiltin ("wmiabt", di_ftype_di_v4hi_v4hi, WMIABT);
2595 iwmmx2_mbuiltin ("wmiatb", di_ftype_di_v4hi_v4hi, WMIATB);
2596 iwmmx2_mbuiltin ("wmiatt", di_ftype_di_v4hi_v4hi, WMIATT);
2598 iwmmx2_mbuiltin ("wmiabbn", di_ftype_di_v4hi_v4hi, WMIABBN);
2599 iwmmx2_mbuiltin ("wmiabtn", di_ftype_di_v4hi_v4hi, WMIABTN);
2600 iwmmx2_mbuiltin ("wmiatbn", di_ftype_di_v4hi_v4hi, WMIATBN);
2601 iwmmx2_mbuiltin ("wmiattn", di_ftype_di_v4hi_v4hi, WMIATTN);
2603 iwmmx2_mbuiltin ("wmiawbb", di_ftype_di_v2si_v2si, WMIAWBB);
2604 iwmmx2_mbuiltin ("wmiawbt", di_ftype_di_v2si_v2si, WMIAWBT);
2605 iwmmx2_mbuiltin ("wmiawtb", di_ftype_di_v2si_v2si, WMIAWTB);
2606 iwmmx2_mbuiltin ("wmiawtt", di_ftype_di_v2si_v2si, WMIAWTT);
2608 iwmmx2_mbuiltin ("wmiawbbn", di_ftype_di_v2si_v2si, WMIAWBBN);
2609 iwmmx2_mbuiltin ("wmiawbtn", di_ftype_di_v2si_v2si, WMIAWBTN);
2610 iwmmx2_mbuiltin ("wmiawtbn", di_ftype_di_v2si_v2si, WMIAWTBN);
2611 iwmmx2_mbuiltin ("wmiawttn", di_ftype_di_v2si_v2si, WMIAWTTN);
2613 iwmmx2_mbuiltin ("wmerge", di_ftype_di_di_int, WMERGE);
2615 iwmmx_mbuiltin ("tbcstb", v8qi_ftype_char, TBCSTB);
2616 iwmmx_mbuiltin ("tbcsth", v4hi_ftype_short, TBCSTH);
2617 iwmmx_mbuiltin ("tbcstw", v2si_ftype_int, TBCSTW);
2619 #undef iwmmx_mbuiltin
2620 #undef iwmmx2_mbuiltin
2623 static void
2624 arm_init_fp16_builtins (void)
2626 arm_fp16_type_node = make_node (REAL_TYPE);
2627 TYPE_PRECISION (arm_fp16_type_node) = GET_MODE_PRECISION (HFmode);
2628 layout_type (arm_fp16_type_node);
2629 if (arm_fp16_format)
2630 (*lang_hooks.types.register_builtin_type) (arm_fp16_type_node,
2631 "__fp16");
2634 void
2635 arm_init_builtins (void)
2637 if (TARGET_REALLY_IWMMXT)
2638 arm_init_iwmmxt_builtins ();
2640 /* This creates the arm_simd_floatHF_type_node so must come before
2641 arm_init_neon_builtins which uses it. */
2642 arm_init_fp16_builtins ();
2644 arm_init_bf16_types ();
2646 if (TARGET_MAYBE_HARD_FLOAT)
2648 tree lane_check_fpr = build_function_type_list (void_type_node,
2649 intSI_type_node,
2650 intSI_type_node,
2651 NULL);
2652 arm_builtin_decls[ARM_BUILTIN_SIMD_LANE_CHECK]
2653 = add_builtin_function ("__builtin_arm_lane_check", lane_check_fpr,
2654 ARM_BUILTIN_SIMD_LANE_CHECK, BUILT_IN_MD,
2655 NULL, NULL_TREE);
2656 if (TARGET_HAVE_MVE)
2657 arm_init_mve_builtins ();
2658 else
2659 arm_init_neon_builtins ();
2660 arm_init_vfp_builtins ();
2661 arm_init_crypto_builtins ();
2664 if (TARGET_CDE)
2665 arm_init_cde_builtins ();
2667 arm_init_acle_builtins ();
2669 if (TARGET_MAYBE_HARD_FLOAT)
2671 tree ftype_set_fpscr
2672 = build_function_type_list (void_type_node, unsigned_type_node, NULL);
2673 tree ftype_get_fpscr
2674 = build_function_type_list (unsigned_type_node, NULL);
2676 arm_builtin_decls[ARM_BUILTIN_GET_FPSCR]
2677 = add_builtin_function ("__builtin_arm_get_fpscr", ftype_get_fpscr,
2678 ARM_BUILTIN_GET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE);
2679 arm_builtin_decls[ARM_BUILTIN_SET_FPSCR]
2680 = add_builtin_function ("__builtin_arm_set_fpscr", ftype_set_fpscr,
2681 ARM_BUILTIN_SET_FPSCR, BUILT_IN_MD, NULL, NULL_TREE);
2684 if (use_cmse)
2686 tree ftype_cmse_nonsecure_caller
2687 = build_function_type_list (unsigned_type_node, NULL);
2688 arm_builtin_decls[ARM_BUILTIN_CMSE_NONSECURE_CALLER]
2689 = add_builtin_function ("__builtin_arm_cmse_nonsecure_caller",
2690 ftype_cmse_nonsecure_caller,
2691 ARM_BUILTIN_CMSE_NONSECURE_CALLER, BUILT_IN_MD,
2692 NULL, NULL_TREE);
2696 /* Return the ARM builtin for CODE. */
2698 tree
2699 arm_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
2701 if (code >= ARM_BUILTIN_MAX)
2702 return error_mark_node;
2704 return arm_builtin_decls[code];
2707 /* Errors in the source file can cause expand_expr to return const0_rtx
2708 where we expect a vector. To avoid crashing, use one of the vector
2709 clear instructions. */
2711 static rtx
2712 safe_vector_operand (rtx x, machine_mode mode)
2714 if (x != const0_rtx)
2715 return x;
2716 x = gen_reg_rtx (mode);
2718 emit_insn (gen_iwmmxt_clrdi (mode == DImode ? x
2719 : gen_rtx_SUBREG (DImode, x, 0)));
2720 return x;
2723 /* Function to expand ternary builtins. */
2724 static rtx
2725 arm_expand_ternop_builtin (enum insn_code icode,
2726 tree exp, rtx target)
2728 rtx pat;
2729 tree arg0 = CALL_EXPR_ARG (exp, 0);
2730 tree arg1 = CALL_EXPR_ARG (exp, 1);
2731 tree arg2 = CALL_EXPR_ARG (exp, 2);
2733 rtx op0 = expand_normal (arg0);
2734 rtx op1 = expand_normal (arg1);
2735 rtx op2 = expand_normal (arg2);
2737 machine_mode tmode = insn_data[icode].operand[0].mode;
2738 machine_mode mode0 = insn_data[icode].operand[1].mode;
2739 machine_mode mode1 = insn_data[icode].operand[2].mode;
2740 machine_mode mode2 = insn_data[icode].operand[3].mode;
2742 if (VECTOR_MODE_P (mode0))
2743 op0 = safe_vector_operand (op0, mode0);
2744 if (VECTOR_MODE_P (mode1))
2745 op1 = safe_vector_operand (op1, mode1);
2746 if (VECTOR_MODE_P (mode2))
2747 op2 = safe_vector_operand (op2, mode2);
2749 if (! target
2750 || GET_MODE (target) != tmode
2751 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2752 target = gen_reg_rtx (tmode);
2754 gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode)
2755 && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode)
2756 && (GET_MODE (op2) == mode2 || GET_MODE (op2) == VOIDmode));
2758 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2759 op0 = copy_to_mode_reg (mode0, op0);
2760 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
2761 op1 = copy_to_mode_reg (mode1, op1);
2762 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
2763 op2 = copy_to_mode_reg (mode2, op2);
2765 pat = GEN_FCN (icode) (target, op0, op1, op2);
2766 if (! pat)
2767 return 0;
2768 emit_insn (pat);
2769 return target;
2772 /* Subroutine of arm_expand_builtin to take care of binop insns. */
2774 static rtx
2775 arm_expand_binop_builtin (enum insn_code icode,
2776 tree exp, rtx target)
2778 rtx pat;
2779 tree arg0 = CALL_EXPR_ARG (exp, 0);
2780 tree arg1 = CALL_EXPR_ARG (exp, 1);
2781 rtx op0 = expand_normal (arg0);
2782 rtx op1 = expand_normal (arg1);
2783 machine_mode tmode = insn_data[icode].operand[0].mode;
2784 machine_mode mode0 = insn_data[icode].operand[1].mode;
2785 machine_mode mode1 = insn_data[icode].operand[2].mode;
2787 if (VECTOR_MODE_P (mode0))
2788 op0 = safe_vector_operand (op0, mode0);
2789 if (VECTOR_MODE_P (mode1))
2790 op1 = safe_vector_operand (op1, mode1);
2792 if (! target
2793 || GET_MODE (target) != tmode
2794 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2795 target = gen_reg_rtx (tmode);
2797 gcc_assert ((GET_MODE (op0) == mode0 || GET_MODE (op0) == VOIDmode)
2798 && (GET_MODE (op1) == mode1 || GET_MODE (op1) == VOIDmode));
2800 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2801 op0 = copy_to_mode_reg (mode0, op0);
2802 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
2803 op1 = copy_to_mode_reg (mode1, op1);
2805 pat = GEN_FCN (icode) (target, op0, op1);
2806 if (! pat)
2807 return 0;
2808 emit_insn (pat);
2809 return target;
2812 /* Subroutine of arm_expand_builtin to take care of unop insns. */
2814 static rtx
2815 arm_expand_unop_builtin (enum insn_code icode,
2816 tree exp, rtx target, int do_load)
2818 rtx pat;
2819 tree arg0 = CALL_EXPR_ARG (exp, 0);
2820 rtx op0 = expand_normal (arg0);
2821 machine_mode tmode = insn_data[icode].operand[0].mode;
2822 machine_mode mode0 = insn_data[icode].operand[1].mode;
2824 if (! target
2825 || GET_MODE (target) != tmode
2826 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
2827 target = gen_reg_rtx (tmode);
2828 if (do_load)
2829 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
2830 else
2832 if (VECTOR_MODE_P (mode0))
2833 op0 = safe_vector_operand (op0, mode0);
2835 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2836 op0 = copy_to_mode_reg (mode0, op0);
2839 pat = GEN_FCN (icode) (target, op0);
2841 if (! pat)
2842 return 0;
2843 emit_insn (pat);
2844 return target;
2847 typedef enum {
2848 ARG_BUILTIN_COPY_TO_REG,
2849 ARG_BUILTIN_CONSTANT,
2850 ARG_BUILTIN_LANE_INDEX,
2851 ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX,
2852 ARG_BUILTIN_LANE_PAIR_INDEX,
2853 ARG_BUILTIN_LANE_QUADTUP_INDEX,
2854 ARG_BUILTIN_NEON_MEMORY,
2855 ARG_BUILTIN_MEMORY,
2856 ARG_BUILTIN_STOP
2857 } builtin_arg;
2860 /* EXP is a pointer argument to a Neon load or store intrinsic. Derive
2861 and return an expression for the accessed memory.
2863 The intrinsic function operates on a block of registers that has
2864 mode REG_MODE. This block contains vectors of type TYPE_MODE. The
2865 function references the memory at EXP of type TYPE and in mode
2866 MEM_MODE; this mode may be BLKmode if no more suitable mode is
2867 available. */
2869 static tree
2870 neon_dereference_pointer (tree exp, tree type, machine_mode mem_mode,
2871 machine_mode reg_mode,
2872 machine_mode vector_mode)
2874 HOST_WIDE_INT reg_size, vector_size, nvectors, nelems;
2875 tree elem_type, upper_bound, array_type;
2877 /* Work out the size of the register block in bytes. */
2878 reg_size = GET_MODE_SIZE (reg_mode);
2880 /* Work out the size of each vector in bytes. */
2881 vector_size = GET_MODE_SIZE (vector_mode);
2883 /* Work out how many vectors there are. */
2884 gcc_assert (reg_size % vector_size == 0);
2885 nvectors = reg_size / vector_size;
2887 /* Work out the type of each element. */
2888 gcc_assert (POINTER_TYPE_P (type));
2889 elem_type = TREE_TYPE (type);
2891 /* Work out how many elements are being loaded or stored.
2892 MEM_MODE == REG_MODE implies a one-to-one mapping between register
2893 and memory elements; anything else implies a lane load or store. */
2894 if (mem_mode == reg_mode)
2895 nelems = vector_size * nvectors / int_size_in_bytes (elem_type);
2896 else
2897 nelems = nvectors;
2899 /* Create a type that describes the full access. */
2900 upper_bound = build_int_cst (size_type_node, nelems - 1);
2901 array_type = build_array_type (elem_type, build_index_type (upper_bound));
2903 /* Dereference EXP using that type. */
2904 return fold_build2 (MEM_REF, array_type, exp,
2905 build_int_cst (build_pointer_type (array_type), 0));
2908 /* EXP is a pointer argument to a vector scatter store intrinsics.
2910 Consider the following example:
2911 VSTRW<v>.<dt> Qd, [Qm{, #+/-<imm>}]!
2912 When <Qm> used as the base register for the target address,
2913 this function is used to derive and return an expression for the
2914 accessed memory.
2916 The intrinsic function operates on a block of registers that has mode
2917 REG_MODE. This block contains vectors of type TYPE_MODE. The function
2918 references the memory at EXP of type TYPE and in mode MEM_MODE. This
2919 mode may be BLKmode if no more suitable mode is available. */
2921 static tree
2922 mve_dereference_pointer (tree exp, tree type, machine_mode reg_mode,
2923 machine_mode vector_mode)
2925 HOST_WIDE_INT reg_size, vector_size, nelems;
2926 tree elem_type, upper_bound, array_type;
2928 /* Work out the size of each vector in bytes. */
2929 vector_size = GET_MODE_SIZE (vector_mode);
2931 /* Work out the size of the register block in bytes. */
2932 reg_size = GET_MODE_SIZE (reg_mode);
2934 /* Work out the type of each element. */
2935 gcc_assert (POINTER_TYPE_P (type));
2936 elem_type = TREE_TYPE (type);
2938 nelems = reg_size / vector_size;
2940 /* Create a type that describes the full access. */
2941 upper_bound = build_int_cst (size_type_node, nelems - 1);
2942 array_type = build_array_type (elem_type, build_index_type (upper_bound));
2944 /* Dereference EXP using that type. */
2945 return fold_build2 (MEM_REF, array_type, exp,
2946 build_int_cst (build_pointer_type (array_type), 0));
2949 /* Expand a builtin. */
2950 static rtx
2951 arm_expand_builtin_args (rtx target, machine_mode map_mode, int fcode,
2952 int icode, int have_retval, tree exp,
2953 builtin_arg *args)
2955 rtx pat;
2956 tree arg[SIMD_MAX_BUILTIN_ARGS];
2957 rtx op[SIMD_MAX_BUILTIN_ARGS];
2958 machine_mode tmode = insn_data[icode].operand[0].mode;
2959 machine_mode mode[SIMD_MAX_BUILTIN_ARGS];
2960 tree formals;
2961 int argc = 0;
2962 rtx_insn * insn;
2964 if (have_retval
2965 && (!target
2966 || GET_MODE (target) != tmode
2967 || !(*insn_data[icode].operand[0].predicate) (target, tmode)))
2968 target = gen_reg_rtx (tmode);
2970 formals = TYPE_ARG_TYPES (TREE_TYPE (arm_builtin_decls[fcode]));
2972 for (;;)
2974 builtin_arg thisarg = args[argc];
2976 if (thisarg == ARG_BUILTIN_STOP)
2977 break;
2978 else
2980 int opno = argc + have_retval;
2981 arg[argc] = CALL_EXPR_ARG (exp, argc);
2982 mode[argc] = insn_data[icode].operand[opno].mode;
2983 if (thisarg == ARG_BUILTIN_NEON_MEMORY)
2985 machine_mode other_mode
2986 = insn_data[icode].operand[1 - opno].mode;
2987 if (TARGET_HAVE_MVE && mode[argc] != other_mode)
2989 arg[argc] = mve_dereference_pointer (arg[argc],
2990 TREE_VALUE (formals),
2991 other_mode, map_mode);
2993 else
2994 arg[argc] = neon_dereference_pointer (arg[argc],
2995 TREE_VALUE (formals),
2996 mode[argc], other_mode,
2997 map_mode);
3000 /* Use EXPAND_MEMORY for ARG_BUILTIN_MEMORY and
3001 ARG_BUILTIN_NEON_MEMORY to ensure a MEM_P be returned. */
3002 op[argc] = expand_expr (arg[argc], NULL_RTX, VOIDmode,
3003 ((thisarg == ARG_BUILTIN_MEMORY
3004 || thisarg == ARG_BUILTIN_NEON_MEMORY)
3005 ? EXPAND_MEMORY : EXPAND_NORMAL));
3007 switch (thisarg)
3009 case ARG_BUILTIN_MEMORY:
3010 case ARG_BUILTIN_COPY_TO_REG:
3011 if (POINTER_TYPE_P (TREE_TYPE (arg[argc])))
3012 op[argc] = convert_memory_address (Pmode, op[argc]);
3014 /* MVE uses mve_pred16_t (aka HImode) for vectors of
3015 predicates, but internally we use V16BI/V8BI/V4BI/V2QI for
3016 MVE predicate modes. */
3017 if (TARGET_HAVE_MVE && VALID_MVE_PRED_MODE (mode[argc]))
3018 op[argc] = gen_lowpart (mode[argc], op[argc]);
3020 gcc_assert (GET_MODE (op[argc]) == mode[argc]
3021 || (GET_MODE(op[argc]) == E_VOIDmode
3022 && CONSTANT_P (op[argc])));
3023 if (!(*insn_data[icode].operand[opno].predicate)
3024 (op[argc], mode[argc]))
3025 op[argc] = copy_to_mode_reg (mode[argc], op[argc]);
3026 break;
3028 case ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX:
3029 gcc_assert (argc > 1);
3030 if (CONST_INT_P (op[argc]))
3032 neon_lane_bounds (op[argc], 0,
3033 GET_MODE_NUNITS (map_mode), exp);
3034 /* Keep to GCC-vector-extension lane indices in the RTL. */
3035 op[argc] =
3036 GEN_INT (NEON_ENDIAN_LANE_N (map_mode, INTVAL (op[argc])));
3038 goto constant_arg;
3040 case ARG_BUILTIN_LANE_INDEX:
3041 /* Previous argument must be a vector, which this indexes. */
3042 gcc_assert (argc > 0);
3043 if (CONST_INT_P (op[argc]))
3045 machine_mode vmode = mode[argc - 1];
3046 neon_lane_bounds (op[argc], 0, GET_MODE_NUNITS (vmode), exp);
3048 /* If the lane index isn't a constant then error out. */
3049 goto constant_arg;
3051 case ARG_BUILTIN_LANE_PAIR_INDEX:
3052 /* Previous argument must be a vector, which this indexes. The
3053 indexing will always select i and i+1 out of the vector, which
3054 puts a limit on i. */
3055 gcc_assert (argc > 0);
3056 if (CONST_INT_P (op[argc]))
3058 machine_mode vmode = mode[argc - 1];
3059 neon_lane_bounds (op[argc], 0,
3060 GET_MODE_NUNITS (vmode) / 2, exp);
3062 /* If the lane index isn't a constant then error out. */
3063 goto constant_arg;
3065 case ARG_BUILTIN_LANE_QUADTUP_INDEX:
3066 /* Previous argument must be a vector, which this indexes. */
3067 gcc_assert (argc > 0);
3068 if (CONST_INT_P (op[argc]))
3070 machine_mode vmode = mode[argc - 1];
3071 neon_lane_bounds (op[argc], 0,
3072 GET_MODE_NUNITS (vmode) / 4, exp);
3074 /* If the lane index isn't a constant then error out. */
3075 goto constant_arg;
3077 case ARG_BUILTIN_CONSTANT:
3078 constant_arg:
3079 if (!(*insn_data[icode].operand[opno].predicate)
3080 (op[argc], mode[argc]))
3082 if (IN_RANGE (fcode, ARM_BUILTIN_CDE_PATTERN_START,
3083 ARM_BUILTIN_CDE_PATTERN_END))
3085 if (argc == 0)
3087 unsigned int cp_bit = (CONST_INT_P (op[argc])
3088 ? UINTVAL (op[argc]) : -1);
3089 if (IN_RANGE (cp_bit, 0, ARM_CDE_CONST_COPROC))
3090 error_at (EXPR_LOCATION (exp),
3091 "coprocessor %d is not enabled "
3092 "with +cdecp%d", cp_bit, cp_bit);
3093 else
3094 error_at (EXPR_LOCATION (exp),
3095 "coproc must be a constant immediate in "
3096 "range [0-%d] enabled with %<+cdecp<N>%>",
3097 ARM_CDE_CONST_COPROC);
3099 else
3100 /* Here we mention the builtin name to follow the same
3101 format that the C/C++ frontends use for referencing
3102 a given argument index. */
3103 error_at (EXPR_LOCATION (exp),
3104 "argument %d to %qE must be a constant "
3105 "immediate in range [0-%d]", argc + 1,
3106 arm_builtin_decls[fcode],
3107 cde_builtin_data[fcode -
3108 ARM_BUILTIN_CDE_PATTERN_START].imm_max);
3110 else
3111 error_at (EXPR_LOCATION (exp),
3112 "argument %d must be a constant immediate",
3113 argc + 1);
3114 /* We have failed to expand the pattern, and are safely
3115 in to invalid code. But the mid-end will still try to
3116 build an assignment for this node while it expands,
3117 before stopping for the error, just pass it back
3118 TARGET to ensure a valid assignment. */
3119 return target;
3121 break;
3123 case ARG_BUILTIN_NEON_MEMORY:
3124 /* Check if expand failed. */
3125 if (op[argc] == const0_rtx)
3126 return 0;
3127 gcc_assert (MEM_P (op[argc]));
3128 PUT_MODE (op[argc], mode[argc]);
3129 /* ??? arm_neon.h uses the same built-in functions for signed
3130 and unsigned accesses, casting where necessary. This isn't
3131 alias safe. */
3132 set_mem_alias_set (op[argc], 0);
3133 if (!(*insn_data[icode].operand[opno].predicate)
3134 (op[argc], mode[argc]))
3135 op[argc] = (replace_equiv_address
3136 (op[argc],
3137 copy_to_mode_reg (Pmode, XEXP (op[argc], 0))));
3138 break;
3140 case ARG_BUILTIN_STOP:
3141 gcc_unreachable ();
3144 argc++;
3148 if (have_retval)
3149 switch (argc)
3151 case 0:
3152 pat = GEN_FCN (icode) (target);
3153 break;
3154 case 1:
3155 pat = GEN_FCN (icode) (target, op[0]);
3156 break;
3158 case 2:
3159 pat = GEN_FCN (icode) (target, op[0], op[1]);
3160 break;
3162 case 3:
3163 pat = GEN_FCN (icode) (target, op[0], op[1], op[2]);
3164 break;
3166 case 4:
3167 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3]);
3168 break;
3170 case 5:
3171 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4]);
3172 break;
3174 case 6:
3175 pat = GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4], op[5]);
3176 break;
3178 default:
3179 gcc_unreachable ();
3181 else
3182 switch (argc)
3184 case 1:
3185 pat = GEN_FCN (icode) (op[0]);
3186 break;
3188 case 2:
3189 pat = GEN_FCN (icode) (op[0], op[1]);
3190 break;
3192 case 3:
3193 pat = GEN_FCN (icode) (op[0], op[1], op[2]);
3194 break;
3196 case 4:
3197 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
3198 break;
3200 case 5:
3201 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]);
3202 break;
3204 case 6:
3205 pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]);
3206 break;
3208 default:
3209 gcc_unreachable ();
3212 if (!pat)
3213 return 0;
3215 /* Check whether our current target implements the pattern chosen for this
3216 builtin and error out if not. */
3217 start_sequence ();
3218 emit_insn (pat);
3219 insn = get_insns ();
3220 end_sequence ();
3222 if (recog_memoized (insn) < 0)
3223 error ("this builtin is not supported for this target");
3224 else
3225 emit_insn (insn);
3227 if (TARGET_HAVE_MVE && VALID_MVE_PRED_MODE (tmode))
3229 rtx HItarget = gen_reg_rtx (HImode);
3230 emit_move_insn (HItarget, gen_lowpart (HImode, target));
3231 return HItarget;
3234 return target;
3237 /* Expand a builtin. These builtins are "special" because they don't have
3238 symbolic constants defined per-instruction or per instruction-variant.
3239 Instead, the required info is looked up in the ARM_BUILTIN_DATA record that
3240 is passed into the function. */
3242 static rtx
3243 arm_expand_builtin_1 (int fcode, tree exp, rtx target,
3244 arm_builtin_datum *d)
3246 enum insn_code icode = d->code;
3247 builtin_arg args[SIMD_MAX_BUILTIN_ARGS + 1];
3248 int num_args = insn_data[d->code].n_operands;
3249 int is_void = 0;
3250 int k;
3251 bool neon = false;
3252 bool mve = false;
3254 if (IN_RANGE (fcode, ARM_BUILTIN_VFP_BASE, ARM_BUILTIN_ACLE_BASE - 1))
3255 neon = true;
3257 if (IN_RANGE (fcode, ARM_BUILTIN_MVE_BASE, ARM_BUILTIN_MAX - 1))
3258 mve = true;
3260 is_void = !!(d->qualifiers[0] & qualifier_void);
3262 num_args += is_void;
3264 for (k = 1; k < num_args; k++)
3266 /* We have four arrays of data, each indexed in a different fashion.
3267 qualifiers - element 0 always describes the function return type.
3268 operands - element 0 is either the operand for return value (if
3269 the function has a non-void return type) or the operand for the
3270 first argument.
3271 expr_args - element 0 always holds the first argument.
3272 args - element 0 is always used for the return type. */
3273 int qualifiers_k = k;
3274 int operands_k = k - is_void;
3275 int expr_args_k = k - 1;
3277 if (d->qualifiers[qualifiers_k] & qualifier_lane_index)
3278 args[k] = ARG_BUILTIN_LANE_INDEX;
3279 else if (d->qualifiers[qualifiers_k] & qualifier_lane_pair_index)
3280 args[k] = ARG_BUILTIN_LANE_PAIR_INDEX;
3281 else if (d->qualifiers[qualifiers_k] & qualifier_lane_quadtup_index)
3282 args[k] = ARG_BUILTIN_LANE_QUADTUP_INDEX;
3283 else if (d->qualifiers[qualifiers_k] & qualifier_struct_load_store_lane_index)
3284 args[k] = ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX;
3285 else if (d->qualifiers[qualifiers_k] & qualifier_immediate)
3286 args[k] = ARG_BUILTIN_CONSTANT;
3287 else if (d->qualifiers[qualifiers_k] & qualifier_maybe_immediate)
3289 rtx arg
3290 = expand_normal (CALL_EXPR_ARG (exp,
3291 (expr_args_k)));
3292 /* Handle constants only if the predicate allows it. */
3293 bool op_const_int_p =
3294 (CONST_INT_P (arg)
3295 && (*insn_data[icode].operand[operands_k].predicate)
3296 (arg, insn_data[icode].operand[operands_k].mode));
3297 args[k] = op_const_int_p ? ARG_BUILTIN_CONSTANT : ARG_BUILTIN_COPY_TO_REG;
3299 else if (d->qualifiers[qualifiers_k] & qualifier_pointer)
3301 if (neon || mve)
3302 args[k] = ARG_BUILTIN_NEON_MEMORY;
3303 else
3304 args[k] = ARG_BUILTIN_MEMORY;
3306 else
3307 args[k] = ARG_BUILTIN_COPY_TO_REG;
3309 args[k] = ARG_BUILTIN_STOP;
3311 /* The interface to arm_expand_builtin_args expects a 0 if
3312 the function is void, and a 1 if it is not. */
3313 return arm_expand_builtin_args
3314 (target, d->mode, fcode, icode, !is_void, exp,
3315 &args[1]);
3318 /* Expand an ACLE builtin, i.e. those registered only if their respective
3319 target constraints are met. This check happens within
3320 arm_expand_builtin_args. */
3322 static rtx
3323 arm_expand_acle_builtin (int fcode, tree exp, rtx target)
3325 if (fcode == ARM_BUILTIN_SAT_IMM_CHECK)
3327 /* Check the saturation immediate bounds. */
3329 rtx min_sat = expand_normal (CALL_EXPR_ARG (exp, 1));
3330 rtx max_sat = expand_normal (CALL_EXPR_ARG (exp, 2));
3331 gcc_assert (CONST_INT_P (min_sat));
3332 gcc_assert (CONST_INT_P (max_sat));
3333 rtx sat_imm = expand_normal (CALL_EXPR_ARG (exp, 0));
3334 if (CONST_INT_P (sat_imm))
3336 if (!IN_RANGE (sat_imm, min_sat, max_sat))
3337 error_at (EXPR_LOCATION (exp),
3338 "saturation bit range must be in the range [%wd, %wd]",
3339 UINTVAL (min_sat), UINTVAL (max_sat));
3341 else
3342 error_at (EXPR_LOCATION (exp),
3343 "saturation bit range must be a constant immediate");
3344 /* Don't generate any RTL. */
3345 return const0_rtx;
3348 gcc_assert (fcode != ARM_BUILTIN_CDE_BASE);
3349 arm_builtin_datum *d
3350 = (fcode < ARM_BUILTIN_CDE_BASE)
3351 ? &acle_builtin_data[fcode - ARM_BUILTIN_ACLE_PATTERN_START]
3352 : &cde_builtin_data[fcode - ARM_BUILTIN_CDE_PATTERN_START].base;
3354 return arm_expand_builtin_1 (fcode, exp, target, d);
3357 /* Expand an MVE builtin, i.e. those registered only if their respective target
3358 constraints are met. This check happens within arm_expand_builtin. */
3360 static rtx
3361 arm_expand_mve_builtin (int fcode, tree exp, rtx target)
3363 if (fcode >= ARM_BUILTIN_MVE_BASE && !TARGET_HAVE_MVE)
3365 fatal_error (input_location,
3366 "You must enable MVE instructions"
3367 " to use these intrinsics");
3368 return const0_rtx;
3371 arm_builtin_datum *d
3372 = &mve_builtin_data[fcode - ARM_BUILTIN_MVE_PATTERN_START];
3374 return arm_expand_builtin_1 (fcode, exp, target, d);
3377 /* Expand a Neon builtin, i.e. those registered only if TARGET_NEON holds.
3378 Most of these are "special" because they don't have symbolic
3379 constants defined per-instruction or per instruction-variant. Instead, the
3380 required info is looked up in the table neon_builtin_data. */
3382 static rtx
3383 arm_expand_neon_builtin (int fcode, tree exp, rtx target)
3385 if (fcode >= ARM_BUILTIN_NEON_BASE && ! TARGET_NEON)
3387 fatal_error (input_location,
3388 "You must enable NEON instructions"
3389 " (e.g. %<-mfloat-abi=softfp%> %<-mfpu=neon%>)"
3390 " to use these intrinsics.");
3391 return const0_rtx;
3394 arm_builtin_datum *d
3395 = &neon_builtin_data[fcode - ARM_BUILTIN_NEON_PATTERN_START];
3397 return arm_expand_builtin_1 (fcode, exp, target, d);
3400 /* Expand a VFP builtin. These builtins are treated like
3401 neon builtins except that the data is looked up in table
3402 VFP_BUILTIN_DATA. */
3404 static rtx
3405 arm_expand_vfp_builtin (int fcode, tree exp, rtx target)
3407 if (fcode >= ARM_BUILTIN_VFP_BASE && ! TARGET_HARD_FLOAT)
3409 fatal_error (input_location,
3410 "You must enable VFP instructions"
3411 " to use these intrinsics.");
3412 return const0_rtx;
3415 arm_builtin_datum *d
3416 = &vfp_builtin_data[fcode - ARM_BUILTIN_VFP_PATTERN_START];
3418 return arm_expand_builtin_1 (fcode, exp, target, d);
3421 /* Expand an expression EXP that calls a built-in function,
3422 with result going to TARGET if that's convenient
3423 (and in mode MODE if that's convenient).
3424 SUBTARGET may be used as the target for computing one of EXP's operands.
3425 IGNORE is nonzero if the value is to be ignored. */
3428 arm_expand_builtin (tree exp,
3429 rtx target,
3430 rtx subtarget ATTRIBUTE_UNUSED,
3431 machine_mode mode ATTRIBUTE_UNUSED,
3432 int ignore ATTRIBUTE_UNUSED)
3434 const struct builtin_description * d;
3435 enum insn_code icode;
3436 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3437 tree arg0;
3438 tree arg1;
3439 tree arg2;
3440 rtx op0;
3441 rtx op1;
3442 rtx op2;
3443 rtx pat;
3444 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
3445 size_t i;
3446 machine_mode tmode;
3447 machine_mode mode0;
3448 machine_mode mode1;
3449 machine_mode mode2;
3450 int opint;
3451 int selector;
3452 int mask;
3453 int imm;
3455 if (fcode == ARM_BUILTIN_SIMD_LANE_CHECK)
3457 /* Builtin is only to check bounds of the lane passed to some intrinsics
3458 that are implemented with gcc vector extensions in arm_neon.h. */
3460 tree nlanes = CALL_EXPR_ARG (exp, 0);
3461 gcc_assert (TREE_CODE (nlanes) == INTEGER_CST);
3462 rtx lane_idx = expand_normal (CALL_EXPR_ARG (exp, 1));
3463 if (CONST_INT_P (lane_idx))
3464 neon_lane_bounds (lane_idx, 0, TREE_INT_CST_LOW (nlanes), exp);
3465 else
3466 error_at (EXPR_LOCATION (exp),
3467 "lane index must be a constant immediate");
3468 /* Don't generate any RTL. */
3469 return const0_rtx;
3471 if (fcode >= ARM_BUILTIN_MVE_BASE)
3472 return arm_expand_mve_builtin (fcode, exp, target);
3474 if (fcode >= ARM_BUILTIN_ACLE_BASE)
3475 return arm_expand_acle_builtin (fcode, exp, target);
3477 if (fcode >= ARM_BUILTIN_NEON_BASE)
3478 return arm_expand_neon_builtin (fcode, exp, target);
3480 if (fcode >= ARM_BUILTIN_VFP_BASE)
3481 return arm_expand_vfp_builtin (fcode, exp, target);
3483 /* Check in the context of the function making the call whether the
3484 builtin is supported. */
3485 if (fcode >= ARM_BUILTIN_CRYPTO_BASE
3486 && (!TARGET_CRYPTO || !TARGET_HARD_FLOAT))
3488 fatal_error (input_location,
3489 "You must enable crypto instructions"
3490 " (e.g. include %<-mfloat-abi=softfp%> "
3491 "%<-mfpu=crypto-neon%>)"
3492 " to use these intrinsics.");
3493 return const0_rtx;
3496 switch (fcode)
3498 case ARM_BUILTIN_GET_FPSCR_NZCVQC:
3499 case ARM_BUILTIN_SET_FPSCR_NZCVQC:
3500 if (fcode == ARM_BUILTIN_GET_FPSCR_NZCVQC)
3502 icode = CODE_FOR_get_fpscr_nzcvqc;
3503 target = gen_reg_rtx (SImode);
3504 emit_insn (GEN_FCN (icode) (target));
3505 return target;
3507 else
3509 icode = CODE_FOR_set_fpscr_nzcvqc;
3510 op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
3511 emit_insn (GEN_FCN (icode) (force_reg (SImode, op0)));
3512 return NULL_RTX;
3515 case ARM_BUILTIN_GET_FPSCR:
3516 case ARM_BUILTIN_SET_FPSCR:
3517 if (fcode == ARM_BUILTIN_GET_FPSCR)
3519 icode = CODE_FOR_get_fpscr;
3520 target = gen_reg_rtx (SImode);
3521 pat = GEN_FCN (icode) (target);
3523 else
3525 target = NULL_RTX;
3526 icode = CODE_FOR_set_fpscr;
3527 arg0 = CALL_EXPR_ARG (exp, 0);
3528 op0 = expand_normal (arg0);
3529 pat = GEN_FCN (icode) (force_reg (SImode, op0));
3531 emit_insn (pat);
3532 return target;
3534 case ARM_BUILTIN_CMSE_NONSECURE_CALLER:
3535 target = gen_reg_rtx (SImode);
3536 op0 = arm_return_addr (0, NULL_RTX);
3537 emit_insn (gen_andsi3 (target, op0, const1_rtx));
3538 op1 = gen_rtx_EQ (SImode, target, const0_rtx);
3539 emit_insn (gen_cstoresi4 (target, op1, target, const0_rtx));
3540 return target;
3542 case ARM_BUILTIN_TEXTRMSB:
3543 case ARM_BUILTIN_TEXTRMUB:
3544 case ARM_BUILTIN_TEXTRMSH:
3545 case ARM_BUILTIN_TEXTRMUH:
3546 case ARM_BUILTIN_TEXTRMSW:
3547 case ARM_BUILTIN_TEXTRMUW:
3548 icode = (fcode == ARM_BUILTIN_TEXTRMSB ? CODE_FOR_iwmmxt_textrmsb
3549 : fcode == ARM_BUILTIN_TEXTRMUB ? CODE_FOR_iwmmxt_textrmub
3550 : fcode == ARM_BUILTIN_TEXTRMSH ? CODE_FOR_iwmmxt_textrmsh
3551 : fcode == ARM_BUILTIN_TEXTRMUH ? CODE_FOR_iwmmxt_textrmuh
3552 : CODE_FOR_iwmmxt_textrmw);
3554 arg0 = CALL_EXPR_ARG (exp, 0);
3555 arg1 = CALL_EXPR_ARG (exp, 1);
3556 op0 = expand_normal (arg0);
3557 op1 = expand_normal (arg1);
3558 tmode = insn_data[icode].operand[0].mode;
3559 mode0 = insn_data[icode].operand[1].mode;
3560 mode1 = insn_data[icode].operand[2].mode;
3562 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3563 op0 = copy_to_mode_reg (mode0, op0);
3564 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
3566 /* @@@ better error message */
3567 error ("selector must be an immediate");
3568 return gen_reg_rtx (tmode);
3571 opint = INTVAL (op1);
3572 if (fcode == ARM_BUILTIN_TEXTRMSB || fcode == ARM_BUILTIN_TEXTRMUB)
3574 if (opint > 7 || opint < 0)
3575 error ("the range of selector should be in 0 to 7");
3577 else if (fcode == ARM_BUILTIN_TEXTRMSH || fcode == ARM_BUILTIN_TEXTRMUH)
3579 if (opint > 3 || opint < 0)
3580 error ("the range of selector should be in 0 to 3");
3582 else /* ARM_BUILTIN_TEXTRMSW || ARM_BUILTIN_TEXTRMUW. */
3584 if (opint > 1 || opint < 0)
3585 error ("the range of selector should be in 0 to 1");
3588 if (target == 0
3589 || GET_MODE (target) != tmode
3590 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3591 target = gen_reg_rtx (tmode);
3592 pat = GEN_FCN (icode) (target, op0, op1);
3593 if (! pat)
3594 return 0;
3595 emit_insn (pat);
3596 return target;
3598 case ARM_BUILTIN_WALIGNI:
3599 /* If op2 is immediate, call walighi, else call walighr. */
3600 arg0 = CALL_EXPR_ARG (exp, 0);
3601 arg1 = CALL_EXPR_ARG (exp, 1);
3602 arg2 = CALL_EXPR_ARG (exp, 2);
3603 op0 = expand_normal (arg0);
3604 op1 = expand_normal (arg1);
3605 op2 = expand_normal (arg2);
3606 if (CONST_INT_P (op2))
3608 icode = CODE_FOR_iwmmxt_waligni;
3609 tmode = insn_data[icode].operand[0].mode;
3610 mode0 = insn_data[icode].operand[1].mode;
3611 mode1 = insn_data[icode].operand[2].mode;
3612 mode2 = insn_data[icode].operand[3].mode;
3613 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
3614 op0 = copy_to_mode_reg (mode0, op0);
3615 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
3616 op1 = copy_to_mode_reg (mode1, op1);
3617 gcc_assert ((*insn_data[icode].operand[3].predicate) (op2, mode2));
3618 selector = INTVAL (op2);
3619 if (selector > 7 || selector < 0)
3620 error ("the range of selector should be in 0 to 7");
3622 else
3624 icode = CODE_FOR_iwmmxt_walignr;
3625 tmode = insn_data[icode].operand[0].mode;
3626 mode0 = insn_data[icode].operand[1].mode;
3627 mode1 = insn_data[icode].operand[2].mode;
3628 mode2 = insn_data[icode].operand[3].mode;
3629 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
3630 op0 = copy_to_mode_reg (mode0, op0);
3631 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
3632 op1 = copy_to_mode_reg (mode1, op1);
3633 if (!(*insn_data[icode].operand[3].predicate) (op2, mode2))
3634 op2 = copy_to_mode_reg (mode2, op2);
3636 if (target == 0
3637 || GET_MODE (target) != tmode
3638 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
3639 target = gen_reg_rtx (tmode);
3640 pat = GEN_FCN (icode) (target, op0, op1, op2);
3641 if (!pat)
3642 return 0;
3643 emit_insn (pat);
3644 return target;
3646 case ARM_BUILTIN_TINSRB:
3647 case ARM_BUILTIN_TINSRH:
3648 case ARM_BUILTIN_TINSRW:
3649 case ARM_BUILTIN_WMERGE:
3650 icode = (fcode == ARM_BUILTIN_TINSRB ? CODE_FOR_iwmmxt_tinsrb
3651 : fcode == ARM_BUILTIN_TINSRH ? CODE_FOR_iwmmxt_tinsrh
3652 : fcode == ARM_BUILTIN_WMERGE ? CODE_FOR_iwmmxt_wmerge
3653 : CODE_FOR_iwmmxt_tinsrw);
3654 arg0 = CALL_EXPR_ARG (exp, 0);
3655 arg1 = CALL_EXPR_ARG (exp, 1);
3656 arg2 = CALL_EXPR_ARG (exp, 2);
3657 op0 = expand_normal (arg0);
3658 op1 = expand_normal (arg1);
3659 op2 = expand_normal (arg2);
3660 tmode = insn_data[icode].operand[0].mode;
3661 mode0 = insn_data[icode].operand[1].mode;
3662 mode1 = insn_data[icode].operand[2].mode;
3663 mode2 = insn_data[icode].operand[3].mode;
3665 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3666 op0 = copy_to_mode_reg (mode0, op0);
3667 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
3668 op1 = copy_to_mode_reg (mode1, op1);
3669 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
3671 error ("selector must be an immediate");
3672 return const0_rtx;
3674 if (icode == CODE_FOR_iwmmxt_wmerge)
3676 selector = INTVAL (op2);
3677 if (selector > 7 || selector < 0)
3678 error ("the range of selector should be in 0 to 7");
3680 if ((icode == CODE_FOR_iwmmxt_tinsrb)
3681 || (icode == CODE_FOR_iwmmxt_tinsrh)
3682 || (icode == CODE_FOR_iwmmxt_tinsrw))
3684 mask = 0x01;
3685 selector= INTVAL (op2);
3686 if (icode == CODE_FOR_iwmmxt_tinsrb && (selector < 0 || selector > 7))
3687 error ("the range of selector should be in 0 to 7");
3688 else if (icode == CODE_FOR_iwmmxt_tinsrh && (selector < 0 ||selector > 3))
3689 error ("the range of selector should be in 0 to 3");
3690 else if (icode == CODE_FOR_iwmmxt_tinsrw && (selector < 0 ||selector > 1))
3691 error ("the range of selector should be in 0 to 1");
3692 mask <<= selector;
3693 op2 = GEN_INT (mask);
3695 if (target == 0
3696 || GET_MODE (target) != tmode
3697 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3698 target = gen_reg_rtx (tmode);
3699 pat = GEN_FCN (icode) (target, op0, op1, op2);
3700 if (! pat)
3701 return 0;
3702 emit_insn (pat);
3703 return target;
3705 case ARM_BUILTIN_SETWCGR0:
3706 case ARM_BUILTIN_SETWCGR1:
3707 case ARM_BUILTIN_SETWCGR2:
3708 case ARM_BUILTIN_SETWCGR3:
3709 icode = (fcode == ARM_BUILTIN_SETWCGR0 ? CODE_FOR_iwmmxt_setwcgr0
3710 : fcode == ARM_BUILTIN_SETWCGR1 ? CODE_FOR_iwmmxt_setwcgr1
3711 : fcode == ARM_BUILTIN_SETWCGR2 ? CODE_FOR_iwmmxt_setwcgr2
3712 : CODE_FOR_iwmmxt_setwcgr3);
3713 arg0 = CALL_EXPR_ARG (exp, 0);
3714 op0 = expand_normal (arg0);
3715 mode0 = insn_data[icode].operand[0].mode;
3716 if (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
3717 op0 = copy_to_mode_reg (mode0, op0);
3718 pat = GEN_FCN (icode) (op0);
3719 if (!pat)
3720 return 0;
3721 emit_insn (pat);
3722 return 0;
3724 case ARM_BUILTIN_GETWCGR0:
3725 case ARM_BUILTIN_GETWCGR1:
3726 case ARM_BUILTIN_GETWCGR2:
3727 case ARM_BUILTIN_GETWCGR3:
3728 icode = (fcode == ARM_BUILTIN_GETWCGR0 ? CODE_FOR_iwmmxt_getwcgr0
3729 : fcode == ARM_BUILTIN_GETWCGR1 ? CODE_FOR_iwmmxt_getwcgr1
3730 : fcode == ARM_BUILTIN_GETWCGR2 ? CODE_FOR_iwmmxt_getwcgr2
3731 : CODE_FOR_iwmmxt_getwcgr3);
3732 tmode = insn_data[icode].operand[0].mode;
3733 if (target == 0
3734 || GET_MODE (target) != tmode
3735 || !(*insn_data[icode].operand[0].predicate) (target, tmode))
3736 target = gen_reg_rtx (tmode);
3737 pat = GEN_FCN (icode) (target);
3738 if (!pat)
3739 return 0;
3740 emit_insn (pat);
3741 return target;
3743 case ARM_BUILTIN_WSHUFH:
3744 icode = CODE_FOR_iwmmxt_wshufh;
3745 arg0 = CALL_EXPR_ARG (exp, 0);
3746 arg1 = CALL_EXPR_ARG (exp, 1);
3747 op0 = expand_normal (arg0);
3748 op1 = expand_normal (arg1);
3749 tmode = insn_data[icode].operand[0].mode;
3750 mode1 = insn_data[icode].operand[1].mode;
3751 mode2 = insn_data[icode].operand[2].mode;
3753 if (! (*insn_data[icode].operand[1].predicate) (op0, mode1))
3754 op0 = copy_to_mode_reg (mode1, op0);
3755 if (! (*insn_data[icode].operand[2].predicate) (op1, mode2))
3757 error ("mask must be an immediate");
3758 return const0_rtx;
3760 selector = INTVAL (op1);
3761 if (selector < 0 || selector > 255)
3762 error ("the range of mask should be in 0 to 255");
3763 if (target == 0
3764 || GET_MODE (target) != tmode
3765 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3766 target = gen_reg_rtx (tmode);
3767 pat = GEN_FCN (icode) (target, op0, op1);
3768 if (! pat)
3769 return 0;
3770 emit_insn (pat);
3771 return target;
3773 case ARM_BUILTIN_WMADDS:
3774 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmadds, exp, target);
3775 case ARM_BUILTIN_WMADDSX:
3776 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsx, exp, target);
3777 case ARM_BUILTIN_WMADDSN:
3778 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsn, exp, target);
3779 case ARM_BUILTIN_WMADDU:
3780 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddu, exp, target);
3781 case ARM_BUILTIN_WMADDUX:
3782 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddux, exp, target);
3783 case ARM_BUILTIN_WMADDUN:
3784 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddun, exp, target);
3785 case ARM_BUILTIN_WSADBZ:
3786 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz, exp, target);
3787 case ARM_BUILTIN_WSADHZ:
3788 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz, exp, target);
3790 /* Several three-argument builtins. */
3791 case ARM_BUILTIN_WMACS:
3792 case ARM_BUILTIN_WMACU:
3793 case ARM_BUILTIN_TMIA:
3794 case ARM_BUILTIN_TMIAPH:
3795 case ARM_BUILTIN_TMIATT:
3796 case ARM_BUILTIN_TMIATB:
3797 case ARM_BUILTIN_TMIABT:
3798 case ARM_BUILTIN_TMIABB:
3799 case ARM_BUILTIN_WQMIABB:
3800 case ARM_BUILTIN_WQMIABT:
3801 case ARM_BUILTIN_WQMIATB:
3802 case ARM_BUILTIN_WQMIATT:
3803 case ARM_BUILTIN_WQMIABBN:
3804 case ARM_BUILTIN_WQMIABTN:
3805 case ARM_BUILTIN_WQMIATBN:
3806 case ARM_BUILTIN_WQMIATTN:
3807 case ARM_BUILTIN_WMIABB:
3808 case ARM_BUILTIN_WMIABT:
3809 case ARM_BUILTIN_WMIATB:
3810 case ARM_BUILTIN_WMIATT:
3811 case ARM_BUILTIN_WMIABBN:
3812 case ARM_BUILTIN_WMIABTN:
3813 case ARM_BUILTIN_WMIATBN:
3814 case ARM_BUILTIN_WMIATTN:
3815 case ARM_BUILTIN_WMIAWBB:
3816 case ARM_BUILTIN_WMIAWBT:
3817 case ARM_BUILTIN_WMIAWTB:
3818 case ARM_BUILTIN_WMIAWTT:
3819 case ARM_BUILTIN_WMIAWBBN:
3820 case ARM_BUILTIN_WMIAWBTN:
3821 case ARM_BUILTIN_WMIAWTBN:
3822 case ARM_BUILTIN_WMIAWTTN:
3823 case ARM_BUILTIN_WSADB:
3824 case ARM_BUILTIN_WSADH:
3825 icode = (fcode == ARM_BUILTIN_WMACS ? CODE_FOR_iwmmxt_wmacs
3826 : fcode == ARM_BUILTIN_WMACU ? CODE_FOR_iwmmxt_wmacu
3827 : fcode == ARM_BUILTIN_TMIA ? CODE_FOR_iwmmxt_tmia
3828 : fcode == ARM_BUILTIN_TMIAPH ? CODE_FOR_iwmmxt_tmiaph
3829 : fcode == ARM_BUILTIN_TMIABB ? CODE_FOR_iwmmxt_tmiabb
3830 : fcode == ARM_BUILTIN_TMIABT ? CODE_FOR_iwmmxt_tmiabt
3831 : fcode == ARM_BUILTIN_TMIATB ? CODE_FOR_iwmmxt_tmiatb
3832 : fcode == ARM_BUILTIN_TMIATT ? CODE_FOR_iwmmxt_tmiatt
3833 : fcode == ARM_BUILTIN_WQMIABB ? CODE_FOR_iwmmxt_wqmiabb
3834 : fcode == ARM_BUILTIN_WQMIABT ? CODE_FOR_iwmmxt_wqmiabt
3835 : fcode == ARM_BUILTIN_WQMIATB ? CODE_FOR_iwmmxt_wqmiatb
3836 : fcode == ARM_BUILTIN_WQMIATT ? CODE_FOR_iwmmxt_wqmiatt
3837 : fcode == ARM_BUILTIN_WQMIABBN ? CODE_FOR_iwmmxt_wqmiabbn
3838 : fcode == ARM_BUILTIN_WQMIABTN ? CODE_FOR_iwmmxt_wqmiabtn
3839 : fcode == ARM_BUILTIN_WQMIATBN ? CODE_FOR_iwmmxt_wqmiatbn
3840 : fcode == ARM_BUILTIN_WQMIATTN ? CODE_FOR_iwmmxt_wqmiattn
3841 : fcode == ARM_BUILTIN_WMIABB ? CODE_FOR_iwmmxt_wmiabb
3842 : fcode == ARM_BUILTIN_WMIABT ? CODE_FOR_iwmmxt_wmiabt
3843 : fcode == ARM_BUILTIN_WMIATB ? CODE_FOR_iwmmxt_wmiatb
3844 : fcode == ARM_BUILTIN_WMIATT ? CODE_FOR_iwmmxt_wmiatt
3845 : fcode == ARM_BUILTIN_WMIABBN ? CODE_FOR_iwmmxt_wmiabbn
3846 : fcode == ARM_BUILTIN_WMIABTN ? CODE_FOR_iwmmxt_wmiabtn
3847 : fcode == ARM_BUILTIN_WMIATBN ? CODE_FOR_iwmmxt_wmiatbn
3848 : fcode == ARM_BUILTIN_WMIATTN ? CODE_FOR_iwmmxt_wmiattn
3849 : fcode == ARM_BUILTIN_WMIAWBB ? CODE_FOR_iwmmxt_wmiawbb
3850 : fcode == ARM_BUILTIN_WMIAWBT ? CODE_FOR_iwmmxt_wmiawbt
3851 : fcode == ARM_BUILTIN_WMIAWTB ? CODE_FOR_iwmmxt_wmiawtb
3852 : fcode == ARM_BUILTIN_WMIAWTT ? CODE_FOR_iwmmxt_wmiawtt
3853 : fcode == ARM_BUILTIN_WMIAWBBN ? CODE_FOR_iwmmxt_wmiawbbn
3854 : fcode == ARM_BUILTIN_WMIAWBTN ? CODE_FOR_iwmmxt_wmiawbtn
3855 : fcode == ARM_BUILTIN_WMIAWTBN ? CODE_FOR_iwmmxt_wmiawtbn
3856 : fcode == ARM_BUILTIN_WMIAWTTN ? CODE_FOR_iwmmxt_wmiawttn
3857 : fcode == ARM_BUILTIN_WSADB ? CODE_FOR_iwmmxt_wsadb
3858 : CODE_FOR_iwmmxt_wsadh);
3859 arg0 = CALL_EXPR_ARG (exp, 0);
3860 arg1 = CALL_EXPR_ARG (exp, 1);
3861 arg2 = CALL_EXPR_ARG (exp, 2);
3862 op0 = expand_normal (arg0);
3863 op1 = expand_normal (arg1);
3864 op2 = expand_normal (arg2);
3865 tmode = insn_data[icode].operand[0].mode;
3866 mode0 = insn_data[icode].operand[1].mode;
3867 mode1 = insn_data[icode].operand[2].mode;
3868 mode2 = insn_data[icode].operand[3].mode;
3870 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
3871 op0 = copy_to_mode_reg (mode0, op0);
3872 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
3873 op1 = copy_to_mode_reg (mode1, op1);
3874 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
3875 op2 = copy_to_mode_reg (mode2, op2);
3876 if (target == 0
3877 || GET_MODE (target) != tmode
3878 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
3879 target = gen_reg_rtx (tmode);
3880 pat = GEN_FCN (icode) (target, op0, op1, op2);
3881 if (! pat)
3882 return 0;
3883 emit_insn (pat);
3884 return target;
3886 case ARM_BUILTIN_WZERO:
3887 target = gen_reg_rtx (DImode);
3888 emit_insn (gen_iwmmxt_clrdi (target));
3889 return target;
3891 case ARM_BUILTIN_WSRLHI:
3892 case ARM_BUILTIN_WSRLWI:
3893 case ARM_BUILTIN_WSRLDI:
3894 case ARM_BUILTIN_WSLLHI:
3895 case ARM_BUILTIN_WSLLWI:
3896 case ARM_BUILTIN_WSLLDI:
3897 case ARM_BUILTIN_WSRAHI:
3898 case ARM_BUILTIN_WSRAWI:
3899 case ARM_BUILTIN_WSRADI:
3900 case ARM_BUILTIN_WRORHI:
3901 case ARM_BUILTIN_WRORWI:
3902 case ARM_BUILTIN_WRORDI:
3903 case ARM_BUILTIN_WSRLH:
3904 case ARM_BUILTIN_WSRLW:
3905 case ARM_BUILTIN_WSRLD:
3906 case ARM_BUILTIN_WSLLH:
3907 case ARM_BUILTIN_WSLLW:
3908 case ARM_BUILTIN_WSLLD:
3909 case ARM_BUILTIN_WSRAH:
3910 case ARM_BUILTIN_WSRAW:
3911 case ARM_BUILTIN_WSRAD:
3912 case ARM_BUILTIN_WRORH:
3913 case ARM_BUILTIN_WRORW:
3914 case ARM_BUILTIN_WRORD:
3915 icode = (fcode == ARM_BUILTIN_WSRLHI ? CODE_FOR_lshrv4hi3_iwmmxt
3916 : fcode == ARM_BUILTIN_WSRLWI ? CODE_FOR_lshrv2si3_iwmmxt
3917 : fcode == ARM_BUILTIN_WSRLDI ? CODE_FOR_lshrdi3_iwmmxt
3918 : fcode == ARM_BUILTIN_WSLLHI ? CODE_FOR_ashlv4hi3_iwmmxt
3919 : fcode == ARM_BUILTIN_WSLLWI ? CODE_FOR_ashlv2si3_iwmmxt
3920 : fcode == ARM_BUILTIN_WSLLDI ? CODE_FOR_ashldi3_iwmmxt
3921 : fcode == ARM_BUILTIN_WSRAHI ? CODE_FOR_ashrv4hi3_iwmmxt
3922 : fcode == ARM_BUILTIN_WSRAWI ? CODE_FOR_ashrv2si3_iwmmxt
3923 : fcode == ARM_BUILTIN_WSRADI ? CODE_FOR_ashrdi3_iwmmxt
3924 : fcode == ARM_BUILTIN_WRORHI ? CODE_FOR_rorv4hi3
3925 : fcode == ARM_BUILTIN_WRORWI ? CODE_FOR_rorv2si3
3926 : fcode == ARM_BUILTIN_WRORDI ? CODE_FOR_rordi3
3927 : fcode == ARM_BUILTIN_WSRLH ? CODE_FOR_lshrv4hi3_di
3928 : fcode == ARM_BUILTIN_WSRLW ? CODE_FOR_lshrv2si3_di
3929 : fcode == ARM_BUILTIN_WSRLD ? CODE_FOR_lshrdi3_di
3930 : fcode == ARM_BUILTIN_WSLLH ? CODE_FOR_ashlv4hi3_di
3931 : fcode == ARM_BUILTIN_WSLLW ? CODE_FOR_ashlv2si3_di
3932 : fcode == ARM_BUILTIN_WSLLD ? CODE_FOR_ashldi3_di
3933 : fcode == ARM_BUILTIN_WSRAH ? CODE_FOR_ashrv4hi3_di
3934 : fcode == ARM_BUILTIN_WSRAW ? CODE_FOR_ashrv2si3_di
3935 : fcode == ARM_BUILTIN_WSRAD ? CODE_FOR_ashrdi3_di
3936 : fcode == ARM_BUILTIN_WRORH ? CODE_FOR_rorv4hi3_di
3937 : fcode == ARM_BUILTIN_WRORW ? CODE_FOR_rorv2si3_di
3938 : fcode == ARM_BUILTIN_WRORD ? CODE_FOR_rordi3_di
3939 : CODE_FOR_nothing);
3940 arg1 = CALL_EXPR_ARG (exp, 1);
3941 op1 = expand_normal (arg1);
3942 if (GET_MODE (op1) == VOIDmode)
3944 imm = INTVAL (op1);
3945 if ((fcode == ARM_BUILTIN_WRORWI || fcode == ARM_BUILTIN_WRORW)
3946 && (imm < 0 || imm > 32))
3948 const char *builtin = (fcode == ARM_BUILTIN_WRORWI
3949 ? "_mm_rori_pi32" : "_mm_ror_pi32");
3950 error ("the range of count should be in 0 to 32; "
3951 "please check the intrinsic %qs in code", builtin);
3953 else if ((fcode == ARM_BUILTIN_WRORHI || fcode == ARM_BUILTIN_WRORH)
3954 && (imm < 0 || imm > 16))
3956 const char *builtin = (fcode == ARM_BUILTIN_WRORHI
3957 ? "_mm_rori_pi16" : "_mm_ror_pi16");
3958 error ("the range of count should be in 0 to 16; "
3959 "please check the intrinsic %qs in code", builtin);
3961 else if ((fcode == ARM_BUILTIN_WRORDI || fcode == ARM_BUILTIN_WRORD)
3962 && (imm < 0 || imm > 64))
3964 const char *builtin = (fcode == ARM_BUILTIN_WRORDI
3965 ? "_mm_rori_si64" : "_mm_ror_si64");
3966 error ("the range of count should be in 0 to 64; "
3967 "please check the intrinsic %qs in code", builtin);
3969 else if (imm < 0)
3971 const char *builtin;
3972 switch (fcode)
3974 case ARM_BUILTIN_WSRLHI:
3975 builtin = "_mm_srli_pi16";
3976 break;
3977 case ARM_BUILTIN_WSRLWI:
3978 builtin = "_mm_srli_pi32";
3979 break;
3980 case ARM_BUILTIN_WSRLDI:
3981 builtin = "_mm_srli_si64";
3982 break;
3983 case ARM_BUILTIN_WSLLHI:
3984 builtin = "_mm_slli_pi16";
3985 break;
3986 case ARM_BUILTIN_WSLLWI:
3987 builtin = "_mm_slli_pi32";
3988 break;
3989 case ARM_BUILTIN_WSLLDI:
3990 builtin = "_mm_slli_si64";
3991 break;
3992 case ARM_BUILTIN_WSRAHI:
3993 builtin = "_mm_srai_pi16";
3994 break;
3995 case ARM_BUILTIN_WSRAWI:
3996 builtin = "_mm_srai_pi32";
3997 break;
3998 case ARM_BUILTIN_WSRADI:
3999 builtin = "_mm_srai_si64";
4000 break;
4001 case ARM_BUILTIN_WSRLH:
4002 builtin = "_mm_srl_pi16";
4003 break;
4004 case ARM_BUILTIN_WSRLW:
4005 builtin = "_mm_srl_pi32";
4006 break;
4007 case ARM_BUILTIN_WSRLD:
4008 builtin = "_mm_srl_si64";
4009 break;
4010 case ARM_BUILTIN_WSLLH:
4011 builtin = "_mm_sll_pi16";
4012 break;
4013 case ARM_BUILTIN_WSLLW:
4014 builtin = "_mm_sll_pi32";
4015 break;
4016 case ARM_BUILTIN_WSLLD:
4017 builtin = "_mm_sll_si64";
4018 break;
4019 case ARM_BUILTIN_WSRAH:
4020 builtin = "_mm_sra_pi16";
4021 break;
4022 case ARM_BUILTIN_WSRAW:
4023 builtin = "_mm_sra_si64";
4024 break;
4025 default:
4026 builtin = "_mm_sra_si64";
4027 break;
4029 error ("the count should be no less than 0; "
4030 "please check the intrinsic %qs in code", builtin);
4033 return arm_expand_binop_builtin (icode, exp, target);
4035 default:
4036 break;
4039 for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
4040 if (d->code == (enum arm_builtins) fcode)
4041 return arm_expand_binop_builtin (d->icode, exp, target);
4043 for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
4044 if (d->code == (enum arm_builtins) fcode)
4045 return arm_expand_unop_builtin (d->icode, exp, target, 0);
4047 for (i = 0, d = bdesc_3arg; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
4048 if (d->code == (enum arm_builtins) fcode)
4049 return arm_expand_ternop_builtin (d->icode, exp, target);
4051 /* @@@ Should really do something sensible here. */
4052 return NULL_RTX;
4055 void
4056 arm_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
4058 const unsigned ARM_FE_INVALID = 1;
4059 const unsigned ARM_FE_DIVBYZERO = 2;
4060 const unsigned ARM_FE_OVERFLOW = 4;
4061 const unsigned ARM_FE_UNDERFLOW = 8;
4062 const unsigned ARM_FE_INEXACT = 16;
4063 const unsigned HOST_WIDE_INT ARM_FE_ALL_EXCEPT = (ARM_FE_INVALID
4064 | ARM_FE_DIVBYZERO
4065 | ARM_FE_OVERFLOW
4066 | ARM_FE_UNDERFLOW
4067 | ARM_FE_INEXACT);
4068 const unsigned HOST_WIDE_INT ARM_FE_EXCEPT_SHIFT = 8;
4069 tree fenv_var, get_fpscr, set_fpscr, mask, ld_fenv, masked_fenv;
4070 tree new_fenv_var, reload_fenv, restore_fnenv;
4071 tree update_call, atomic_feraiseexcept, hold_fnclex;
4073 if (!TARGET_HARD_FLOAT)
4074 return;
4076 /* Generate the equivalent of :
4077 unsigned int fenv_var;
4078 fenv_var = __builtin_arm_get_fpscr ();
4080 unsigned int masked_fenv;
4081 masked_fenv = fenv_var & mask;
4083 __builtin_arm_set_fpscr (masked_fenv); */
4085 fenv_var = create_tmp_var_raw (unsigned_type_node);
4086 get_fpscr = arm_builtin_decls[ARM_BUILTIN_GET_FPSCR];
4087 set_fpscr = arm_builtin_decls[ARM_BUILTIN_SET_FPSCR];
4088 mask = build_int_cst (unsigned_type_node,
4089 ~((ARM_FE_ALL_EXCEPT << ARM_FE_EXCEPT_SHIFT)
4090 | ARM_FE_ALL_EXCEPT));
4091 ld_fenv = build4 (TARGET_EXPR, unsigned_type_node,
4092 fenv_var, build_call_expr (get_fpscr, 0),
4093 NULL_TREE, NULL_TREE);
4094 masked_fenv = build2 (BIT_AND_EXPR, unsigned_type_node, fenv_var, mask);
4095 hold_fnclex = build_call_expr (set_fpscr, 1, masked_fenv);
4096 *hold = build2 (COMPOUND_EXPR, void_type_node,
4097 build2 (COMPOUND_EXPR, void_type_node, masked_fenv, ld_fenv),
4098 hold_fnclex);
4100 /* Store the value of masked_fenv to clear the exceptions:
4101 __builtin_arm_set_fpscr (masked_fenv); */
4103 *clear = build_call_expr (set_fpscr, 1, masked_fenv);
4105 /* Generate the equivalent of :
4106 unsigned int new_fenv_var;
4107 new_fenv_var = __builtin_arm_get_fpscr ();
4109 __builtin_arm_set_fpscr (fenv_var);
4111 __atomic_feraiseexcept (new_fenv_var); */
4113 new_fenv_var = create_tmp_var_raw (unsigned_type_node);
4114 reload_fenv = build4 (TARGET_EXPR, unsigned_type_node, new_fenv_var,
4115 build_call_expr (get_fpscr, 0), NULL_TREE, NULL_TREE);
4116 restore_fnenv = build_call_expr (set_fpscr, 1, fenv_var);
4117 atomic_feraiseexcept = builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT);
4118 update_call = build_call_expr (atomic_feraiseexcept, 1,
4119 fold_convert (integer_type_node, new_fenv_var));
4120 *update = build2 (COMPOUND_EXPR, void_type_node,
4121 build2 (COMPOUND_EXPR, void_type_node,
4122 reload_fenv, restore_fnenv), update_call);
4125 /* Implement TARGET_CHECK_BUILTIN_CALL. Record a read of the Q bit through
4126 intrinsics in the machine function. */
4127 bool
4128 arm_check_builtin_call (location_t , vec<location_t> , tree fndecl,
4129 tree, unsigned int, tree *)
4131 int fcode = DECL_MD_FUNCTION_CODE (fndecl);
4132 if (fcode == ARM_BUILTIN_saturation_occurred
4133 || fcode == ARM_BUILTIN_set_saturation)
4135 if (cfun && cfun->decl)
4136 DECL_ATTRIBUTES (cfun->decl)
4137 = tree_cons (get_identifier ("acle qbit"), NULL_TREE,
4138 DECL_ATTRIBUTES (cfun->decl));
4140 if (fcode == ARM_BUILTIN_sel)
4142 if (cfun && cfun->decl)
4143 DECL_ATTRIBUTES (cfun->decl)
4144 = tree_cons (get_identifier ("acle gebits"), NULL_TREE,
4145 DECL_ATTRIBUTES (cfun->decl));
4147 return true;
4150 enum resolver_ident
4151 arm_describe_resolver (tree fndecl)
4153 if (DECL_MD_FUNCTION_CODE (fndecl) >= ARM_BUILTIN_vcx1qv16qi
4154 && DECL_MD_FUNCTION_CODE (fndecl) < ARM_BUILTIN_MVE_BASE)
4155 return arm_cde_resolver;
4156 return arm_no_resolver;
4159 unsigned
4160 arm_cde_end_args (tree fndecl)
4162 return DECL_MD_FUNCTION_CODE (fndecl) >= ARM_BUILTIN_vcx1q_p_v16qi ? 2 : 1;
4165 #include "gt-arm-builtins.h"