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
24 #include "coretypes.h"
29 #include "gimple-expr.h"
32 #include "profile-count.h"
36 #include "diagnostic-core.h"
37 #include "fold-const.h"
38 #include "stor-layout.h"
41 #include "langhooks.h"
42 #include "case-cfn-macros.h"
44 #include "stringpool.h"
45 #include "arm-builtins.h"
46 #include "stringpool.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.
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)
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
,
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
,
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)
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 \
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 \
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 \
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 \
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 \
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
,
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
,
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
,
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)
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)
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
906 const enum insn_code code
;
908 enum arm_type_qualifiers
*qualifiers
;
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) \
918 #define VAR3(T, N, A, B, C) \
921 #define VAR4(T, N, A, B, C, D) \
922 VAR3 (T, N, A, B, C) \
924 #define VAR5(T, N, A, B, C, D, E) \
925 VAR4 (T, N, A, B, C, D) \
927 #define VAR6(T, N, A, B, C, D, E, F) \
928 VAR5 (T, N, A, B, C, D, E) \
930 #define VAR7(T, N, A, B, C, D, E, F, G) \
931 VAR6 (T, N, A, B, C, D, E, F) \
933 #define VAR8(T, N, A, B, C, D, E, F, G, H) \
934 VAR7 (T, N, A, B, C, D, E, F, G) \
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) \
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) \
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) \
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) \
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) \
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) \
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
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"
977 #define CF(N,X) CODE_FOR_mve_##N##X
978 static arm_builtin_datum mve_builtin_data
[] =
980 #include "arm_mve_builtins.def"
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"
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},
1000 arm_builtin_datum base
;
1001 unsigned int imm_max
;
1003 } arm_builtin_cde_datum
;
1005 static arm_builtin_cde_datum cde_builtin_data
[] =
1007 #include "arm_cde_builtins.def"
1011 #define VAR1(T, N, X) \
1012 ARM_BUILTIN_NEON_##N##X,
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
,
1028 ARM_BUILTIN_WAVG2BR
,
1029 ARM_BUILTIN_WAVG2HR
,
1047 ARM_BUILTIN_WALIGNI
,
1048 ARM_BUILTIN_WALIGNR0
,
1049 ARM_BUILTIN_WALIGNR1
,
1050 ARM_BUILTIN_WALIGNR2
,
1051 ARM_BUILTIN_WALIGNR3
,
1060 ARM_BUILTIN_TMOVMSKB
,
1061 ARM_BUILTIN_TMOVMSKH
,
1062 ARM_BUILTIN_TMOVMSKW
,
1071 ARM_BUILTIN_WPACKHSS
,
1072 ARM_BUILTIN_WPACKWSS
,
1073 ARM_BUILTIN_WPACKDSS
,
1074 ARM_BUILTIN_WPACKHUS
,
1075 ARM_BUILTIN_WPACKWUS
,
1076 ARM_BUILTIN_WPACKDUS
,
1081 ARM_BUILTIN_WADDSSB
,
1082 ARM_BUILTIN_WADDSSH
,
1083 ARM_BUILTIN_WADDSSW
,
1084 ARM_BUILTIN_WADDUSB
,
1085 ARM_BUILTIN_WADDUSH
,
1086 ARM_BUILTIN_WADDUSW
,
1090 ARM_BUILTIN_WSUBSSB
,
1091 ARM_BUILTIN_WSUBSSH
,
1092 ARM_BUILTIN_WSUBSSW
,
1093 ARM_BUILTIN_WSUBUSB
,
1094 ARM_BUILTIN_WSUBUSH
,
1095 ARM_BUILTIN_WSUBUSW
,
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
,
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
,
1191 ARM_BUILTIN_WADDSUBHX
,
1192 ARM_BUILTIN_WSUBADDHX
,
1194 ARM_BUILTIN_WABSDIFFB
,
1195 ARM_BUILTIN_WABSDIFFH
,
1196 ARM_BUILTIN_WABSDIFFW
,
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
,
1218 ARM_BUILTIN_WMULSMR
,
1219 ARM_BUILTIN_WMULUMR
,
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
,
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
,
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
,
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"
1289 ARM_BUILTIN_VFP_BASE
,
1291 #include "arm_vfp_builtins.def"
1293 ARM_BUILTIN_NEON_BASE
,
1295 #include "arm_neon_builtins.def"
1298 #define VAR1(T, N, X) \
1301 ARM_BUILTIN_ACLE_BASE
,
1302 ARM_BUILTIN_SAT_IMM_CHECK
= ARM_BUILTIN_ACLE_BASE
,
1304 #include "arm_acle_builtins.def"
1307 #define VAR1(T, N, X, ... ) \
1310 ARM_BUILTIN_CDE_BASE
,
1312 #include "arm_cde_builtins.def"
1314 ARM_BUILTIN_MVE_BASE
,
1317 #define VAR1(T, N, X) \
1318 ARM_BUILTIN_MVE_##N##X,
1319 #include "arm_mve_builtins.def"
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))
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",
1382 #define ENTRY(E, M, Q, S, T, G) \
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"
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
;
1409 arm_mangle_builtin_scalar_type (const_tree type
)
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
];
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
);
1440 arm_mangle_builtin_type (const_tree type
)
1443 /* Walk through all the Arm builtins types tables to filter out the
1445 if ((mangle
= arm_mangle_builtin_vector_type (type
))
1446 || (mangle
= arm_mangle_builtin_scalar_type (type
)))
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);
1461 return QUAL_TYPE (QI
);
1463 return QUAL_TYPE (HI
);
1465 return QUAL_TYPE (SI
);
1467 return QUAL_TYPE (DI
);
1469 return QUAL_TYPE (TI
);
1471 return arm_simd_intOI_type_node
;
1473 return arm_simd_intEI_type_node
;
1475 return arm_simd_intCI_type_node
;
1477 return arm_simd_intXI_type_node
;
1479 return arm_fp16_type_node
;
1481 return float_type_node
;
1483 return double_type_node
;
1485 return arm_bf16_type_node
;
1493 arm_lookup_simd_builtin_type (machine_mode mode
,
1494 enum arm_type_qualifiers q
)
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. */
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
;
1524 return arm_lookup_simd_builtin_type (mode
, qualifier_none
);
1528 arm_init_simd_builtin_types (void)
1531 int nelts
= ARRAY_SIZE (arm_simd_types
);
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
1565 /* Prevent front-ends from transforming poly vectors into string
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
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
;
1608 /* VECTOR_BOOL is not supported unless MVE is activated,
1609 this would make build_truth_vector_type_for_mode
1611 && ((GET_MODE_CLASS (mode
) != MODE_VECTOR_BOOL
)
1612 || !TARGET_HAVE_MVE
))
1614 if (arm_simd_types
[i
].itype
== NULL
)
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
1622 type
= build_truth_vector_type_for_mode (GET_MODE_NUNITS (mode
),
1624 eltype
= TREE_TYPE (type
);
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
;
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. */
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 };
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
1729 int op_num
= insn_data
[d
->code
].n_operands
- 1;
1730 int arg_num
= d
->qualifiers
[0] & qualifier_void
1733 tree return_type
= void_type_node
, args
= void_list_node
;
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;
1755 type_signature
[arg_num
] = 's';
1757 /* Skip an internal operand for vget_{low, high}. */
1758 if (qualifiers
& qualifier_internal
)
1761 /* Some builtins have different user-facing types
1762 for certain arguments, encoded in d->mode. */
1763 if (qualifiers
& qualifier_map_mode
)
1766 /* MVE Predicates use HImode as mandated by the ABI: pred16_t is
1768 if (qualifiers
& qualifier_predicate
)
1771 /* For pointers, we want a pointer to the basic type
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
;
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
1797 return_type
= eltype
;
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
);
1811 snprintf (namebuf
, sizeof (namebuf
), "%s_%s",
1814 fndecl
= add_builtin_function (namebuf
, ftype
, fcode
, BUILT_IN_MD
,
1816 arm_builtin_decls
[fcode
] = fndecl
;
1819 /* Initialize the backend REAL_TYPE type supporting bfloat types. */
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. */
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
,
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
,
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");
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
)
1870 /* Only define CDE/MVE builtins if MVE is available. */
1871 if (!TARGET_HAVE_MVE
&& fcode
>= ARM_BUILTIN_vcx1qv16qi
)
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. */
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
,
1893 tree set_fpscr_nzcvqc
= build_function_type_list (void_type_node
,
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
,
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
,
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. */
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
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. */
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");
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
,
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
,
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
,
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
,
1998 ARM_BUILTIN_CRYPTO_##U
2000 "__builtin_arm_crypto_"#L
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"
2032 #undef NUM_DREG_TYPES
2033 #undef NUM_QREG_TYPES
2035 #define def_mbuiltin(FLAG, NAME, TYPE, CODE) \
2038 if (FLAG == isa_nobit \
2039 || bitmap_bit_p (arm_active_target.isa, FLAG)) \
2042 bdecl = add_builtin_function ((NAME), (TYPE), (CODE), \
2043 BUILT_IN_MD, NULL, NULL_TREE); \
2044 arm_builtin_decls[CODE] = bdecl; \
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, \
2174 FP_BUILTIN (get_fpscr
, GET_FPSCR
)
2175 FP_BUILTIN (set_fpscr
, SET_FPSCR
)
2178 #define CRYPTO_BUILTIN(L, U) \
2179 {isa_nobit, CODE_FOR_crypto_##L, "__builtin_arm_crypto_"#L, \
2180 ARM_BUILTIN_CRYPTO_##U, UNKNOWN, 0},
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"
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"
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"
2240 #undef CRYPTO_BUILTIN
2242 /* Set up all the iWMMXt builtins. This is not called if
2243 TARGET_IWMMXT is zero. */
2246 arm_init_iwmmxt_builtins (void)
2248 const struct builtin_description
* d
;
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
,
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
,
2278 integer_type_node
, NULL_TREE
);
2280 = build_function_type_list (integer_type_node
,
2281 V8QI_type_node
, NULL_TREE
);
2283 = build_function_type_list (integer_type_node
,
2284 V4HI_type_node
, NULL_TREE
);
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
,
2329 tree v2si_ftype_v2si_di
2330 = build_function_type_list (V2SI_type_node
,
2331 V2SI_type_node
, long_long_integer_type_node
,
2334 = build_function_type_list (long_long_unsigned_type_node
, NULL_TREE
);
2336 = build_function_type_list (integer_type_node
, NULL_TREE
);
2338 = build_function_type_list (long_long_integer_type_node
,
2339 V8QI_type_node
, NULL_TREE
);
2341 = build_function_type_list (long_long_integer_type_node
,
2342 V4HI_type_node
, NULL_TREE
);
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
,
2368 tree di_ftype_v4hi_v4hi
2369 = build_function_type_list (long_long_unsigned_type_node
,
2370 V4HI_type_node
,V4HI_type_node
,
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
,
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
);
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
);
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
);
2422 = build_function_type_list (long_long_unsigned_type_node
,
2423 long_long_unsigned_type_node
,
2424 long_long_unsigned_type_node
,
2427 /* Add all builtins that are more or less simple operations on two
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. */
2437 || !(d
->feature
== isa_bit_iwmmxt
2438 || d
->feature
== isa_bit_iwmmxt2
))
2441 mode
= insn_data
[d
->icode
].operand
[1].mode
;
2446 type
= v8qi_ftype_v8qi_v8qi
;
2449 type
= v4hi_ftype_v4hi_v4hi
;
2452 type
= v2si_ftype_v2si_v2si
;
2455 type
= di_ftype_di_di
;
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
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
,
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
,
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
,
2656 if (TARGET_HAVE_MVE
)
2657 arm_init_mve_builtins ();
2659 arm_init_neon_builtins ();
2660 arm_init_vfp_builtins ();
2661 arm_init_crypto_builtins ();
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
);
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
,
2696 /* Return the ARM builtin for CODE. */
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. */
2712 safe_vector_operand (rtx x
, machine_mode mode
)
2714 if (x
!= const0_rtx
)
2716 x
= gen_reg_rtx (mode
);
2718 emit_insn (gen_iwmmxt_clrdi (mode
== DImode
? x
2719 : gen_rtx_SUBREG (DImode
, x
, 0)));
2723 /* Function to expand ternary builtins. */
2725 arm_expand_ternop_builtin (enum insn_code icode
,
2726 tree exp
, rtx target
)
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
);
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
);
2772 /* Subroutine of arm_expand_builtin to take care of binop insns. */
2775 arm_expand_binop_builtin (enum insn_code icode
,
2776 tree exp
, rtx target
)
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
);
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
);
2812 /* Subroutine of arm_expand_builtin to take care of unop insns. */
2815 arm_expand_unop_builtin (enum insn_code icode
,
2816 tree exp
, rtx target
, int do_load
)
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
;
2825 || GET_MODE (target
) != tmode
2826 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2827 target
= gen_reg_rtx (tmode
);
2829 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
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
);
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
,
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
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
);
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
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. */
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. */
2951 arm_expand_builtin_args (rtx target
, machine_mode map_mode
, int fcode
,
2952 int icode
, int have_retval
, tree exp
,
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
];
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
]));
2974 builtin_arg thisarg
= args
[argc
];
2976 if (thisarg
== ARG_BUILTIN_STOP
)
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
);
2994 arg
[argc
] = neon_dereference_pointer (arg
[argc
],
2995 TREE_VALUE (formals
),
2996 mode
[argc
], other_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
));
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
]);
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. */
3036 GEN_INT (NEON_ENDIAN_LANE_N (map_mode
, INTVAL (op
[argc
])));
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. */
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. */
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. */
3077 case ARG_BUILTIN_CONSTANT
:
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
))
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
);
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
);
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
);
3111 error_at (EXPR_LOCATION (exp
),
3112 "argument %d must be a constant immediate",
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. */
3123 case ARG_BUILTIN_NEON_MEMORY
:
3124 /* Check if expand failed. */
3125 if (op
[argc
] == const0_rtx
)
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
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
3137 copy_to_mode_reg (Pmode
, XEXP (op
[argc
], 0))));
3140 case ARG_BUILTIN_STOP
:
3152 pat
= GEN_FCN (icode
) (target
);
3155 pat
= GEN_FCN (icode
) (target
, op
[0]);
3159 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
3163 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2]);
3167 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3]);
3171 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3], op
[4]);
3175 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3], op
[4], op
[5]);
3185 pat
= GEN_FCN (icode
) (op
[0]);
3189 pat
= GEN_FCN (icode
) (op
[0], op
[1]);
3193 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2]);
3197 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3]);
3201 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3], op
[4]);
3205 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3], op
[4], op
[5]);
3215 /* Check whether our current target implements the pattern chosen for this
3216 builtin and error out if not. */
3219 insn
= get_insns ();
3222 if (recog_memoized (insn
) < 0)
3223 error ("this builtin is not supported for this target");
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
));
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. */
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
;
3254 if (IN_RANGE (fcode
, ARM_BUILTIN_VFP_BASE
, ARM_BUILTIN_ACLE_BASE
- 1))
3257 if (IN_RANGE (fcode
, ARM_BUILTIN_MVE_BASE
, ARM_BUILTIN_MAX
- 1))
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
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
)
3290 = expand_normal (CALL_EXPR_ARG (exp
,
3292 /* Handle constants only if the predicate allows it. */
3293 bool op_const_int_p
=
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
)
3302 args
[k
] = ARG_BUILTIN_NEON_MEMORY
;
3304 args
[k
] = ARG_BUILTIN_MEMORY
;
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
,
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. */
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
));
3342 error_at (EXPR_LOCATION (exp
),
3343 "saturation bit range must be a constant immediate");
3344 /* Don't generate any RTL. */
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. */
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");
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. */
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.");
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. */
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.");
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
,
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);
3444 unsigned int fcode
= DECL_MD_FUNCTION_CODE (fndecl
);
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
);
3466 error_at (EXPR_LOCATION (exp
),
3467 "lane index must be a constant immediate");
3468 /* Don't generate any RTL. */
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.");
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
));
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
)));
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
);
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
));
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
));
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");
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
);
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");
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
);
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
);
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");
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
))
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");
3693 op2
= GEN_INT (mask
);
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
);
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
);
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
;
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
);
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");
3760 selector
= INTVAL (op1
);
3761 if (selector
< 0 || selector
> 255)
3762 error ("the range of mask should be in 0 to 255");
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
);
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
);
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
);
3886 case ARM_BUILTIN_WZERO
:
3887 target
= gen_reg_rtx (DImode
);
3888 emit_insn (gen_iwmmxt_clrdi (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
)
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
);
3971 const char *builtin
;
3974 case ARM_BUILTIN_WSRLHI
:
3975 builtin
= "_mm_srli_pi16";
3977 case ARM_BUILTIN_WSRLWI
:
3978 builtin
= "_mm_srli_pi32";
3980 case ARM_BUILTIN_WSRLDI
:
3981 builtin
= "_mm_srli_si64";
3983 case ARM_BUILTIN_WSLLHI
:
3984 builtin
= "_mm_slli_pi16";
3986 case ARM_BUILTIN_WSLLWI
:
3987 builtin
= "_mm_slli_pi32";
3989 case ARM_BUILTIN_WSLLDI
:
3990 builtin
= "_mm_slli_si64";
3992 case ARM_BUILTIN_WSRAHI
:
3993 builtin
= "_mm_srai_pi16";
3995 case ARM_BUILTIN_WSRAWI
:
3996 builtin
= "_mm_srai_pi32";
3998 case ARM_BUILTIN_WSRADI
:
3999 builtin
= "_mm_srai_si64";
4001 case ARM_BUILTIN_WSRLH
:
4002 builtin
= "_mm_srl_pi16";
4004 case ARM_BUILTIN_WSRLW
:
4005 builtin
= "_mm_srl_pi32";
4007 case ARM_BUILTIN_WSRLD
:
4008 builtin
= "_mm_srl_si64";
4010 case ARM_BUILTIN_WSLLH
:
4011 builtin
= "_mm_sll_pi16";
4013 case ARM_BUILTIN_WSLLW
:
4014 builtin
= "_mm_sll_pi32";
4016 case ARM_BUILTIN_WSLLD
:
4017 builtin
= "_mm_sll_si64";
4019 case ARM_BUILTIN_WSRAH
:
4020 builtin
= "_mm_sra_pi16";
4022 case ARM_BUILTIN_WSRAW
:
4023 builtin
= "_mm_sra_si64";
4026 builtin
= "_mm_sra_si64";
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
);
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. */
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
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
)
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
),
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. */
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
));
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
;
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"