1 /* Description of builtins used by the ARM backend.
2 Copyright (C) 2014-2021 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 enum arm_type_qualifiers
56 qualifier_unsigned
= 0x1, /* 1 << 0 */
58 qualifier_const
= 0x2, /* 1 << 1 */
60 qualifier_pointer
= 0x4, /* 1 << 2 */
62 qualifier_const_pointer
= 0x6,
63 /* Used when expanding arguments if an operand could
65 qualifier_immediate
= 0x8, /* 1 << 3 */
66 qualifier_unsigned_immediate
= 0x9,
67 qualifier_maybe_immediate
= 0x10, /* 1 << 4 */
69 qualifier_void
= 0x20, /* 1 << 5 */
70 /* Some patterns may have internal operands, this qualifier is an
71 instruction to the initialisation code to skip this operand. */
72 qualifier_internal
= 0x40, /* 1 << 6 */
73 /* Some builtins should use the T_*mode* encoded in a simd_builtin_datum
74 rather than using the type of the operand. */
75 qualifier_map_mode
= 0x80, /* 1 << 7 */
76 /* qualifier_pointer | qualifier_map_mode */
77 qualifier_pointer_map_mode
= 0x84,
78 /* qualifier_const_pointer | qualifier_map_mode */
79 qualifier_const_pointer_map_mode
= 0x86,
80 /* Polynomial types. */
81 qualifier_poly
= 0x100,
82 /* Lane indices - must be within range of previous argument = a vector. */
83 qualifier_lane_index
= 0x200,
84 /* Lane indices for single lane structure loads and stores. */
85 qualifier_struct_load_store_lane_index
= 0x400,
87 qualifier_void_pointer
= 0x800,
88 /* A const void pointer. */
89 qualifier_const_void_pointer
= 0x802,
90 /* Lane indices selected in pairs - must be within range of previous
91 argument = a vector. */
92 qualifier_lane_pair_index
= 0x1000,
93 /* Lane indices selected in quadtuplets - must be within range of previous
94 argument = a vector. */
95 qualifier_lane_quadtup_index
= 0x2000
98 /* The qualifier_internal allows generation of a unary builtin from
99 a pattern with a third pseudo-operand such as a match_scratch.
101 static enum arm_type_qualifiers
102 arm_unop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
103 = { qualifier_none
, qualifier_none
, qualifier_internal
};
104 #define UNOP_QUALIFIERS (arm_unop_qualifiers)
106 /* unsigned T (unsigned T). */
107 static enum arm_type_qualifiers
108 arm_bswap_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
109 = { qualifier_unsigned
, qualifier_unsigned
};
110 #define BSWAP_QUALIFIERS (arm_bswap_qualifiers)
112 /* T (T, T [maybe_immediate]). */
113 static enum arm_type_qualifiers
114 arm_binop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
115 = { qualifier_none
, qualifier_none
, qualifier_maybe_immediate
};
116 #define BINOP_QUALIFIERS (arm_binop_qualifiers)
119 static enum arm_type_qualifiers
120 arm_ternop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
121 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_none
};
122 #define TERNOP_QUALIFIERS (arm_ternop_qualifiers)
124 /* unsigned T (unsigned T, unsigned T, unsigned T). */
125 static enum arm_type_qualifiers
126 arm_unsigned_uternop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
127 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
,
128 qualifier_unsigned
};
129 #define UTERNOP_QUALIFIERS (arm_unsigned_uternop_qualifiers)
131 /* T (T, unsigned T, T). */
132 static enum arm_type_qualifiers
133 arm_usternop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
134 = { qualifier_none
, qualifier_none
, qualifier_unsigned
,
136 #define USTERNOP_QUALIFIERS (arm_usternop_qualifiers)
138 /* T (T, immediate). */
139 static enum arm_type_qualifiers
140 arm_binop_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
141 = { qualifier_none
, qualifier_none
, qualifier_immediate
};
142 #define BINOP_IMM_QUALIFIERS (arm_binop_imm_qualifiers)
144 /* T (T, unsigned immediate). */
145 static enum arm_type_qualifiers
146 arm_sat_binop_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
147 = { qualifier_unsigned
, qualifier_none
, qualifier_unsigned_immediate
};
148 #define SAT_BINOP_UNSIGNED_IMM_QUALIFIERS \
149 (arm_sat_binop_imm_qualifiers)
151 /* unsigned T (T, unsigned immediate). */
152 static enum arm_type_qualifiers
153 arm_unsigned_sat_binop_unsigned_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
154 = { qualifier_unsigned
, qualifier_none
, qualifier_unsigned_immediate
};
155 #define UNSIGNED_SAT_BINOP_UNSIGNED_IMM_QUALIFIERS \
156 (arm_unsigned_sat_binop_unsigned_imm_qualifiers)
158 /* T (T, lane index). */
159 static enum arm_type_qualifiers
160 arm_getlane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
161 = { qualifier_none
, qualifier_none
, qualifier_lane_index
};
162 #define GETLANE_QUALIFIERS (arm_getlane_qualifiers)
164 /* T (T, T, T, immediate). */
165 static enum arm_type_qualifiers
166 arm_mac_n_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
167 = { qualifier_none
, qualifier_none
, qualifier_none
,
168 qualifier_none
, qualifier_immediate
};
169 #define MAC_N_QUALIFIERS (arm_mac_n_qualifiers)
171 /* T (T, T, T, lane index). */
172 static enum arm_type_qualifiers
173 arm_mac_lane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
174 = { qualifier_none
, qualifier_none
, qualifier_none
,
175 qualifier_none
, qualifier_lane_index
};
176 #define MAC_LANE_QUALIFIERS (arm_mac_lane_qualifiers)
178 /* T (T, T, T, lane pair index). */
179 static enum arm_type_qualifiers
180 arm_mac_lane_pair_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
181 = { qualifier_none
, qualifier_none
, qualifier_none
,
182 qualifier_none
, qualifier_lane_pair_index
};
183 #define MAC_LANE_PAIR_QUALIFIERS (arm_mac_lane_pair_qualifiers)
185 /* unsigned T (unsigned T, unsigned T, unsigend T, lane index). */
186 static enum arm_type_qualifiers
187 arm_umac_lane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
188 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
,
189 qualifier_unsigned
, qualifier_lane_index
};
190 #define UMAC_LANE_QUALIFIERS (arm_umac_lane_qualifiers)
192 /* T (T, unsigned T, T, lane index). */
193 static enum arm_type_qualifiers
194 arm_usmac_lane_quadtup_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
195 = { qualifier_none
, qualifier_none
, qualifier_unsigned
,
196 qualifier_none
, qualifier_lane_quadtup_index
};
197 #define USMAC_LANE_QUADTUP_QUALIFIERS (arm_usmac_lane_quadtup_qualifiers)
199 /* T (T, T, unsigend T, lane index). */
200 static enum arm_type_qualifiers
201 arm_sumac_lane_quadtup_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
202 = { qualifier_none
, qualifier_none
, qualifier_none
,
203 qualifier_unsigned
, qualifier_lane_quadtup_index
};
204 #define SUMAC_LANE_QUADTUP_QUALIFIERS (arm_sumac_lane_quadtup_qualifiers)
206 /* T (T, T, immediate). */
207 static enum arm_type_qualifiers
208 arm_ternop_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
209 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_immediate
};
210 #define TERNOP_IMM_QUALIFIERS (arm_ternop_imm_qualifiers)
212 /* T (T, T, lane index). */
213 static enum arm_type_qualifiers
214 arm_setlane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
215 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_lane_index
};
216 #define SETLANE_QUALIFIERS (arm_setlane_qualifiers)
219 static enum arm_type_qualifiers
220 arm_combine_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
221 = { qualifier_none
, qualifier_none
, qualifier_none
};
222 #define COMBINE_QUALIFIERS (arm_combine_qualifiers)
224 /* T ([T element type] *). */
225 static enum arm_type_qualifiers
226 arm_load1_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
227 = { qualifier_none
, qualifier_const_pointer_map_mode
};
228 #define LOAD1_QUALIFIERS (arm_load1_qualifiers)
230 /* T ([T element type] *, T, immediate). */
231 static enum arm_type_qualifiers
232 arm_load1_lane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
233 = { qualifier_none
, qualifier_const_pointer_map_mode
,
234 qualifier_none
, qualifier_struct_load_store_lane_index
};
235 #define LOAD1LANE_QUALIFIERS (arm_load1_lane_qualifiers)
237 /* unsigned T (unsigned T, unsigned T, unsigned T). */
238 static enum arm_type_qualifiers
239 arm_unsigned_binop_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
240 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
,
241 qualifier_unsigned
};
242 #define UBINOP_QUALIFIERS (arm_unsigned_binop_qualifiers)
244 /* void (unsigned immediate, unsigned immediate, unsigned immediate,
245 unsigned immediate, unsigned immediate, unsigned immediate). */
246 static enum arm_type_qualifiers
247 arm_cdp_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
248 = { qualifier_void
, qualifier_unsigned_immediate
,
249 qualifier_unsigned_immediate
,
250 qualifier_unsigned_immediate
,
251 qualifier_unsigned_immediate
,
252 qualifier_unsigned_immediate
,
253 qualifier_unsigned_immediate
};
254 #define CDP_QUALIFIERS \
257 /* void (unsigned immediate, unsigned immediate, const void *). */
258 static enum arm_type_qualifiers
259 arm_ldc_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
260 = { qualifier_void
, qualifier_unsigned_immediate
,
261 qualifier_unsigned_immediate
, qualifier_const_void_pointer
};
262 #define LDC_QUALIFIERS \
265 /* void (unsigned immediate, unsigned immediate, void *). */
266 static enum arm_type_qualifiers
267 arm_stc_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
268 = { qualifier_void
, qualifier_unsigned_immediate
,
269 qualifier_unsigned_immediate
, qualifier_void_pointer
};
270 #define STC_QUALIFIERS \
273 /* void (unsigned immediate, unsigned immediate, T, unsigned immediate,
274 unsigned immediate, unsigned immediate). */
275 static enum arm_type_qualifiers
276 arm_mcr_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
277 = { qualifier_void
, qualifier_unsigned_immediate
,
278 qualifier_unsigned_immediate
, qualifier_none
,
279 qualifier_unsigned_immediate
, qualifier_unsigned_immediate
,
280 qualifier_unsigned_immediate
};
281 #define MCR_QUALIFIERS \
284 /* T (unsigned immediate, unsigned immediate, unsigned immediate,
285 unsigned immediate, unsigned immediate). */
286 static enum arm_type_qualifiers
287 arm_mrc_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
288 = { qualifier_none
, qualifier_unsigned_immediate
,
289 qualifier_unsigned_immediate
, qualifier_unsigned_immediate
,
290 qualifier_unsigned_immediate
, qualifier_unsigned_immediate
};
291 #define MRC_QUALIFIERS \
294 /* void (unsigned immediate, unsigned immediate, T, unsigned immediate). */
295 static enum arm_type_qualifiers
296 arm_mcrr_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
297 = { qualifier_void
, qualifier_unsigned_immediate
,
298 qualifier_unsigned_immediate
, qualifier_none
,
299 qualifier_unsigned_immediate
};
300 #define MCRR_QUALIFIERS \
301 (arm_mcrr_qualifiers)
303 /* T (unsigned immediate, unsigned immediate, unsigned immediate). */
304 static enum arm_type_qualifiers
305 arm_mrrc_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
306 = { qualifier_none
, qualifier_unsigned_immediate
,
307 qualifier_unsigned_immediate
, qualifier_unsigned_immediate
};
308 #define MRRC_QUALIFIERS \
309 (arm_mrrc_qualifiers)
311 /* T (immediate, unsigned immediate). */
312 static enum arm_type_qualifiers
313 arm_cx_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
314 = { qualifier_none
, qualifier_immediate
, qualifier_unsigned_immediate
};
315 #define CX_IMM_QUALIFIERS (arm_cx_imm_qualifiers)
317 /* T (immediate, T, unsigned immediate). */
318 static enum arm_type_qualifiers
319 arm_cx_unary_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
320 = { qualifier_none
, qualifier_immediate
, qualifier_none
,
321 qualifier_unsigned_immediate
};
322 #define CX_UNARY_QUALIFIERS (arm_cx_unary_qualifiers)
324 /* T (immediate, T, T, unsigned immediate). */
325 static enum arm_type_qualifiers
326 arm_cx_binary_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
327 = { qualifier_none
, qualifier_immediate
,
328 qualifier_none
, qualifier_none
,
329 qualifier_unsigned_immediate
};
330 #define CX_BINARY_QUALIFIERS (arm_cx_binary_qualifiers)
332 /* T (immediate, T, T, T, unsigned immediate). */
333 static enum arm_type_qualifiers
334 arm_cx_ternary_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
335 = { qualifier_none
, qualifier_immediate
,
336 qualifier_none
, qualifier_none
, qualifier_none
,
337 qualifier_unsigned_immediate
};
338 #define CX_TERNARY_QUALIFIERS (arm_cx_ternary_qualifiers)
340 /* T (immediate, T, unsigned immediate). */
341 static enum arm_type_qualifiers
342 arm_cx_unary_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
343 = { qualifier_none
, qualifier_immediate
, qualifier_none
,
344 qualifier_unsigned_immediate
,
345 qualifier_unsigned
};
346 #define CX_UNARY_UNONE_QUALIFIERS (arm_cx_unary_unone_qualifiers)
348 /* T (immediate, T, T, unsigned immediate). */
349 static enum arm_type_qualifiers
350 arm_cx_binary_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
351 = { qualifier_none
, qualifier_immediate
,
352 qualifier_none
, qualifier_none
,
353 qualifier_unsigned_immediate
,
354 qualifier_unsigned
};
355 #define CX_BINARY_UNONE_QUALIFIERS (arm_cx_binary_unone_qualifiers)
357 /* T (immediate, T, T, T, unsigned immediate). */
358 static enum arm_type_qualifiers
359 arm_cx_ternary_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
360 = { qualifier_none
, qualifier_immediate
,
361 qualifier_none
, qualifier_none
, qualifier_none
,
362 qualifier_unsigned_immediate
,
363 qualifier_unsigned
};
364 #define CX_TERNARY_UNONE_QUALIFIERS (arm_cx_ternary_unone_qualifiers)
366 /* The first argument (return type) of a store should be void type,
367 which we represent with qualifier_void. Their first operand will be
368 a DImode pointer to the location to store to, so we must use
369 qualifier_map_mode | qualifier_pointer to build a pointer to the
370 element type of the vector.
372 void ([T element type] *, T). */
373 static enum arm_type_qualifiers
374 arm_store1_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
375 = { qualifier_void
, qualifier_pointer_map_mode
, qualifier_none
};
376 #define STORE1_QUALIFIERS (arm_store1_qualifiers)
378 /* Qualifiers for MVE builtins. */
380 static enum arm_type_qualifiers
381 arm_unop_none_none_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
382 = { qualifier_none
, qualifier_none
};
383 #define UNOP_NONE_NONE_QUALIFIERS \
384 (arm_unop_none_none_qualifiers)
386 static enum arm_type_qualifiers
387 arm_unop_none_snone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
388 = { qualifier_none
, qualifier_none
};
389 #define UNOP_NONE_SNONE_QUALIFIERS \
390 (arm_unop_none_snone_qualifiers)
392 static enum arm_type_qualifiers
393 arm_unop_none_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
394 = { qualifier_none
, qualifier_unsigned
};
395 #define UNOP_NONE_UNONE_QUALIFIERS \
396 (arm_unop_none_unone_qualifiers)
398 static enum arm_type_qualifiers
399 arm_unop_snone_snone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
400 = { qualifier_none
, qualifier_none
};
401 #define UNOP_SNONE_SNONE_QUALIFIERS \
402 (arm_unop_snone_snone_qualifiers)
404 static enum arm_type_qualifiers
405 arm_unop_snone_none_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
406 = { qualifier_none
, qualifier_none
};
407 #define UNOP_SNONE_NONE_QUALIFIERS \
408 (arm_unop_snone_none_qualifiers)
410 static enum arm_type_qualifiers
411 arm_unop_snone_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
412 = { qualifier_none
, qualifier_immediate
};
413 #define UNOP_SNONE_IMM_QUALIFIERS \
414 (arm_unop_snone_imm_qualifiers)
416 static enum arm_type_qualifiers
417 arm_unop_unone_none_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
418 = { qualifier_unsigned
, qualifier_none
};
419 #define UNOP_UNONE_NONE_QUALIFIERS \
420 (arm_unop_unone_none_qualifiers)
422 static enum arm_type_qualifiers
423 arm_unop_unone_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
424 = { qualifier_unsigned
, qualifier_unsigned
};
425 #define UNOP_UNONE_UNONE_QUALIFIERS \
426 (arm_unop_unone_unone_qualifiers)
428 static enum arm_type_qualifiers
429 arm_unop_unone_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
430 = { qualifier_unsigned
, qualifier_immediate
};
431 #define UNOP_UNONE_IMM_QUALIFIERS \
432 (arm_unop_unone_imm_qualifiers)
434 static enum arm_type_qualifiers
435 arm_binop_none_none_none_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
436 = { qualifier_none
, qualifier_none
, qualifier_none
};
437 #define BINOP_NONE_NONE_NONE_QUALIFIERS \
438 (arm_binop_none_none_none_qualifiers)
440 static enum arm_type_qualifiers
441 arm_binop_none_none_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
442 = { qualifier_none
, qualifier_none
, qualifier_immediate
};
443 #define BINOP_NONE_NONE_IMM_QUALIFIERS \
444 (arm_binop_none_none_imm_qualifiers)
446 static enum arm_type_qualifiers
447 arm_binop_none_unone_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
448 = { qualifier_none
, qualifier_unsigned
, qualifier_immediate
};
449 #define BINOP_NONE_UNONE_IMM_QUALIFIERS \
450 (arm_binop_none_unone_imm_qualifiers)
452 static enum arm_type_qualifiers
453 arm_binop_none_unone_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
454 = { qualifier_none
, qualifier_unsigned
, qualifier_unsigned
};
455 #define BINOP_NONE_UNONE_UNONE_QUALIFIERS \
456 (arm_binop_none_unone_unone_qualifiers)
458 static enum arm_type_qualifiers
459 arm_binop_unone_unone_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
460 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_immediate
};
461 #define BINOP_UNONE_UNONE_IMM_QUALIFIERS \
462 (arm_binop_unone_unone_imm_qualifiers)
464 static enum arm_type_qualifiers
465 arm_binop_unone_unone_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
466 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
};
467 #define BINOP_UNONE_UNONE_UNONE_QUALIFIERS \
468 (arm_binop_unone_unone_unone_qualifiers)
470 static enum arm_type_qualifiers
471 arm_binop_unone_none_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
472 = { qualifier_unsigned
, qualifier_none
, qualifier_immediate
};
473 #define BINOP_UNONE_NONE_IMM_QUALIFIERS \
474 (arm_binop_unone_none_imm_qualifiers)
476 static enum arm_type_qualifiers
477 arm_binop_none_none_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
478 = { qualifier_none
, qualifier_none
, qualifier_unsigned
};
479 #define BINOP_NONE_NONE_UNONE_QUALIFIERS \
480 (arm_binop_none_none_unone_qualifiers)
482 static enum arm_type_qualifiers
483 arm_binop_unone_none_none_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
484 = { qualifier_unsigned
, qualifier_none
, qualifier_none
};
485 #define BINOP_UNONE_NONE_NONE_QUALIFIERS \
486 (arm_binop_unone_none_none_qualifiers)
488 static enum arm_type_qualifiers
489 arm_binop_unone_unone_none_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
490 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_none
};
491 #define BINOP_UNONE_UNONE_NONE_QUALIFIERS \
492 (arm_binop_unone_unone_none_qualifiers)
494 static enum arm_type_qualifiers
495 arm_ternop_unone_unone_unone_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
496 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
,
497 qualifier_immediate
};
498 #define TERNOP_UNONE_UNONE_UNONE_IMM_QUALIFIERS \
499 (arm_ternop_unone_unone_unone_imm_qualifiers)
501 static enum arm_type_qualifiers
502 arm_ternop_unone_unone_none_none_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
503 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_none
, qualifier_none
};
504 #define TERNOP_UNONE_UNONE_NONE_NONE_QUALIFIERS \
505 (arm_ternop_unone_unone_none_none_qualifiers)
507 static enum arm_type_qualifiers
508 arm_ternop_unone_none_unone_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
509 = { qualifier_unsigned
, qualifier_none
, qualifier_unsigned
,
510 qualifier_immediate
};
511 #define TERNOP_UNONE_NONE_UNONE_IMM_QUALIFIERS \
512 (arm_ternop_unone_none_unone_imm_qualifiers)
514 static enum arm_type_qualifiers
515 arm_ternop_none_none_unone_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
516 = { qualifier_none
, qualifier_none
, qualifier_unsigned
, qualifier_immediate
};
517 #define TERNOP_NONE_NONE_UNONE_IMM_QUALIFIERS \
518 (arm_ternop_none_none_unone_imm_qualifiers)
520 static enum arm_type_qualifiers
521 arm_ternop_unone_unone_none_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
522 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_none
,
523 qualifier_immediate
};
524 #define TERNOP_UNONE_UNONE_NONE_IMM_QUALIFIERS \
525 (arm_ternop_unone_unone_none_imm_qualifiers)
527 static enum arm_type_qualifiers
528 arm_ternop_unone_unone_none_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
529 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_none
,
530 qualifier_unsigned
};
531 #define TERNOP_UNONE_UNONE_NONE_UNONE_QUALIFIERS \
532 (arm_ternop_unone_unone_none_unone_qualifiers)
534 static enum arm_type_qualifiers
535 arm_ternop_unone_unone_imm_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
536 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_immediate
,
537 qualifier_unsigned
};
538 #define TERNOP_UNONE_UNONE_IMM_UNONE_QUALIFIERS \
539 (arm_ternop_unone_unone_imm_unone_qualifiers)
541 static enum arm_type_qualifiers
542 arm_ternop_unone_none_none_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
543 = { qualifier_unsigned
, qualifier_none
, qualifier_none
, qualifier_unsigned
};
544 #define TERNOP_UNONE_NONE_NONE_UNONE_QUALIFIERS \
545 (arm_ternop_unone_none_none_unone_qualifiers)
547 static enum arm_type_qualifiers
548 arm_ternop_none_none_none_imm_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
549 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_immediate
};
550 #define TERNOP_NONE_NONE_NONE_IMM_QUALIFIERS \
551 (arm_ternop_none_none_none_imm_qualifiers)
553 static enum arm_type_qualifiers
554 arm_ternop_none_none_none_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
555 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_unsigned
};
556 #define TERNOP_NONE_NONE_NONE_UNONE_QUALIFIERS \
557 (arm_ternop_none_none_none_unone_qualifiers)
559 static enum arm_type_qualifiers
560 arm_ternop_none_none_imm_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
561 = { qualifier_none
, qualifier_none
, qualifier_immediate
, qualifier_unsigned
};
562 #define TERNOP_NONE_NONE_IMM_UNONE_QUALIFIERS \
563 (arm_ternop_none_none_imm_unone_qualifiers)
565 static enum arm_type_qualifiers
566 arm_ternop_none_none_unone_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
567 = { qualifier_none
, qualifier_none
, qualifier_unsigned
, qualifier_unsigned
};
568 #define TERNOP_NONE_NONE_UNONE_UNONE_QUALIFIERS \
569 (arm_ternop_none_none_unone_unone_qualifiers)
571 static enum arm_type_qualifiers
572 arm_ternop_unone_unone_unone_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
573 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
,
574 qualifier_unsigned
};
575 #define TERNOP_UNONE_UNONE_UNONE_UNONE_QUALIFIERS \
576 (arm_ternop_unone_unone_unone_unone_qualifiers)
578 static enum arm_type_qualifiers
579 arm_ternop_none_none_none_none_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
580 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_none
};
581 #define TERNOP_NONE_NONE_NONE_NONE_QUALIFIERS \
582 (arm_ternop_none_none_none_none_qualifiers)
584 static enum arm_type_qualifiers
585 arm_quadop_unone_unone_none_none_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
586 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_none
, qualifier_none
,
587 qualifier_unsigned
};
588 #define QUADOP_UNONE_UNONE_NONE_NONE_UNONE_QUALIFIERS \
589 (arm_quadop_unone_unone_none_none_unone_qualifiers)
591 static enum arm_type_qualifiers
592 arm_quadop_none_none_none_none_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
593 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_none
,
594 qualifier_unsigned
};
595 #define QUADOP_NONE_NONE_NONE_NONE_UNONE_QUALIFIERS \
596 (arm_quadop_none_none_none_none_unone_qualifiers)
598 static enum arm_type_qualifiers
599 arm_quadop_none_none_none_imm_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
600 = { qualifier_none
, qualifier_none
, qualifier_none
, qualifier_immediate
,
601 qualifier_unsigned
};
602 #define QUADOP_NONE_NONE_NONE_IMM_UNONE_QUALIFIERS \
603 (arm_quadop_none_none_none_imm_unone_qualifiers)
605 static enum arm_type_qualifiers
606 arm_quadop_unone_unone_unone_unone_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
607 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
,
608 qualifier_unsigned
, qualifier_unsigned
};
609 #define QUADOP_UNONE_UNONE_UNONE_UNONE_UNONE_QUALIFIERS \
610 (arm_quadop_unone_unone_unone_unone_unone_qualifiers)
612 static enum arm_type_qualifiers
613 arm_quadop_unone_unone_none_imm_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
614 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_none
,
615 qualifier_immediate
, qualifier_unsigned
};
616 #define QUADOP_UNONE_UNONE_NONE_IMM_UNONE_QUALIFIERS \
617 (arm_quadop_unone_unone_none_imm_unone_qualifiers)
619 static enum arm_type_qualifiers
620 arm_quadop_none_none_unone_imm_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
621 = { qualifier_none
, qualifier_none
, qualifier_unsigned
, qualifier_immediate
,
622 qualifier_unsigned
};
623 #define QUADOP_NONE_NONE_UNONE_IMM_UNONE_QUALIFIERS \
624 (arm_quadop_none_none_unone_imm_unone_qualifiers)
626 static enum arm_type_qualifiers
627 arm_quadop_unone_unone_unone_imm_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
628 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
,
629 qualifier_immediate
, qualifier_unsigned
};
630 #define QUADOP_UNONE_UNONE_UNONE_IMM_UNONE_QUALIFIERS \
631 (arm_quadop_unone_unone_unone_imm_unone_qualifiers)
633 static enum arm_type_qualifiers
634 arm_quadop_unone_unone_unone_none_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
635 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
,
636 qualifier_none
, qualifier_unsigned
};
637 #define QUADOP_UNONE_UNONE_UNONE_NONE_UNONE_QUALIFIERS \
638 (arm_quadop_unone_unone_unone_none_unone_qualifiers)
640 static enum arm_type_qualifiers
641 arm_strs_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
642 = { qualifier_void
, qualifier_pointer
, qualifier_none
};
643 #define STRS_QUALIFIERS (arm_strs_qualifiers)
645 static enum arm_type_qualifiers
646 arm_stru_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
647 = { qualifier_void
, qualifier_pointer
, qualifier_unsigned
};
648 #define STRU_QUALIFIERS (arm_stru_qualifiers)
650 static enum arm_type_qualifiers
651 arm_strss_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
652 = { qualifier_void
, qualifier_pointer
, qualifier_unsigned
,
654 #define STRSS_QUALIFIERS (arm_strss_qualifiers)
656 static enum arm_type_qualifiers
657 arm_strsu_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
658 = { qualifier_void
, qualifier_pointer
, qualifier_unsigned
,
660 #define STRSU_QUALIFIERS (arm_strsu_qualifiers)
662 static enum arm_type_qualifiers
663 arm_strsbs_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
664 = { qualifier_void
, qualifier_unsigned
, qualifier_immediate
, qualifier_none
};
665 #define STRSBS_QUALIFIERS (arm_strsbs_qualifiers)
667 static enum arm_type_qualifiers
668 arm_strsbu_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
669 = { qualifier_void
, qualifier_unsigned
, qualifier_immediate
,
671 #define STRSBU_QUALIFIERS (arm_strsbu_qualifiers)
673 static enum arm_type_qualifiers
674 arm_strs_p_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
675 = { qualifier_void
, qualifier_pointer
, qualifier_none
, qualifier_unsigned
};
676 #define STRS_P_QUALIFIERS (arm_strs_p_qualifiers)
678 static enum arm_type_qualifiers
679 arm_stru_p_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
680 = { qualifier_void
, qualifier_pointer
, qualifier_unsigned
,
682 #define STRU_P_QUALIFIERS (arm_stru_p_qualifiers)
684 static enum arm_type_qualifiers
685 arm_strsu_p_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
686 = { qualifier_void
, qualifier_pointer
, qualifier_unsigned
,
687 qualifier_unsigned
, qualifier_unsigned
};
688 #define STRSU_P_QUALIFIERS (arm_strsu_p_qualifiers)
690 static enum arm_type_qualifiers
691 arm_strss_p_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
692 = { qualifier_void
, qualifier_pointer
, qualifier_unsigned
,
693 qualifier_none
, qualifier_unsigned
};
694 #define STRSS_P_QUALIFIERS (arm_strss_p_qualifiers)
696 static enum arm_type_qualifiers
697 arm_strsbs_p_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
698 = { qualifier_void
, qualifier_unsigned
, qualifier_immediate
,
699 qualifier_none
, qualifier_unsigned
};
700 #define STRSBS_P_QUALIFIERS (arm_strsbs_p_qualifiers)
702 static enum arm_type_qualifiers
703 arm_strsbu_p_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
704 = { qualifier_void
, qualifier_unsigned
, qualifier_immediate
,
705 qualifier_unsigned
, qualifier_unsigned
};
706 #define STRSBU_P_QUALIFIERS (arm_strsbu_p_qualifiers)
708 static enum arm_type_qualifiers
709 arm_ldrgu_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
710 = { qualifier_unsigned
, qualifier_pointer
, qualifier_unsigned
};
711 #define LDRGU_QUALIFIERS (arm_ldrgu_qualifiers)
713 static enum arm_type_qualifiers
714 arm_ldrgs_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
715 = { qualifier_none
, qualifier_pointer
, qualifier_unsigned
};
716 #define LDRGS_QUALIFIERS (arm_ldrgs_qualifiers)
718 static enum arm_type_qualifiers
719 arm_ldrs_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
720 = { qualifier_none
, qualifier_pointer
};
721 #define LDRS_QUALIFIERS (arm_ldrs_qualifiers)
723 static enum arm_type_qualifiers
724 arm_ldru_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
725 = { qualifier_unsigned
, qualifier_pointer
};
726 #define LDRU_QUALIFIERS (arm_ldru_qualifiers)
728 static enum arm_type_qualifiers
729 arm_ldrgbs_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
730 = { qualifier_none
, qualifier_unsigned
, qualifier_immediate
};
731 #define LDRGBS_QUALIFIERS (arm_ldrgbs_qualifiers)
733 static enum arm_type_qualifiers
734 arm_ldrgbu_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
735 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_immediate
};
736 #define LDRGBU_QUALIFIERS (arm_ldrgbu_qualifiers)
738 static enum arm_type_qualifiers
739 arm_ldrgbs_z_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
740 = { qualifier_none
, qualifier_unsigned
, qualifier_immediate
,
742 #define LDRGBS_Z_QUALIFIERS (arm_ldrgbs_z_qualifiers)
744 static enum arm_type_qualifiers
745 arm_ldrgbu_z_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
746 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_immediate
,
748 #define LDRGBU_Z_QUALIFIERS (arm_ldrgbu_z_qualifiers)
750 static enum arm_type_qualifiers
751 arm_ldrgs_z_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
752 = { qualifier_none
, qualifier_pointer
, qualifier_unsigned
,
754 #define LDRGS_Z_QUALIFIERS (arm_ldrgs_z_qualifiers)
756 static enum arm_type_qualifiers
757 arm_ldrgu_z_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
758 = { qualifier_unsigned
, qualifier_pointer
, qualifier_unsigned
,
760 #define LDRGU_Z_QUALIFIERS (arm_ldrgu_z_qualifiers)
762 static enum arm_type_qualifiers
763 arm_ldrs_z_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
764 = { qualifier_none
, qualifier_pointer
, qualifier_unsigned
};
765 #define LDRS_Z_QUALIFIERS (arm_ldrs_z_qualifiers)
767 static enum arm_type_qualifiers
768 arm_ldru_z_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
769 = { qualifier_unsigned
, qualifier_pointer
, qualifier_unsigned
};
770 #define LDRU_Z_QUALIFIERS (arm_ldru_z_qualifiers)
772 static enum arm_type_qualifiers
773 arm_quinop_unone_unone_unone_unone_imm_unone_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
774 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_unsigned
,
775 qualifier_unsigned
, qualifier_immediate
, qualifier_unsigned
};
776 #define QUINOP_UNONE_UNONE_UNONE_UNONE_IMM_UNONE_QUALIFIERS \
777 (arm_quinop_unone_unone_unone_unone_imm_unone_qualifiers)
779 static enum arm_type_qualifiers
780 arm_ldrgbwbxu_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
781 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_immediate
};
782 #define LDRGBWBXU_QUALIFIERS (arm_ldrgbwbxu_qualifiers)
784 static enum arm_type_qualifiers
785 arm_ldrgbwbxu_z_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
786 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_immediate
,
788 #define LDRGBWBXU_Z_QUALIFIERS (arm_ldrgbwbxu_z_qualifiers)
790 static enum arm_type_qualifiers
791 arm_ldrgbwbs_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
792 = { qualifier_none
, qualifier_unsigned
, qualifier_immediate
};
793 #define LDRGBWBS_QUALIFIERS (arm_ldrgbwbs_qualifiers)
795 static enum arm_type_qualifiers
796 arm_ldrgbwbu_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
797 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_immediate
};
798 #define LDRGBWBU_QUALIFIERS (arm_ldrgbwbu_qualifiers)
800 static enum arm_type_qualifiers
801 arm_ldrgbwbs_z_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
802 = { qualifier_none
, qualifier_unsigned
, qualifier_immediate
,
804 #define LDRGBWBS_Z_QUALIFIERS (arm_ldrgbwbs_z_qualifiers)
806 static enum arm_type_qualifiers
807 arm_ldrgbwbu_z_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
808 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_immediate
,
810 #define LDRGBWBU_Z_QUALIFIERS (arm_ldrgbwbu_z_qualifiers)
812 static enum arm_type_qualifiers
813 arm_strsbwbs_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
814 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_const
, qualifier_none
};
815 #define STRSBWBS_QUALIFIERS (arm_strsbwbs_qualifiers)
817 static enum arm_type_qualifiers
818 arm_strsbwbu_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
819 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_const
, qualifier_unsigned
};
820 #define STRSBWBU_QUALIFIERS (arm_strsbwbu_qualifiers)
822 static enum arm_type_qualifiers
823 arm_strsbwbs_p_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
824 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_const
,
825 qualifier_none
, qualifier_unsigned
};
826 #define STRSBWBS_P_QUALIFIERS (arm_strsbwbs_p_qualifiers)
828 static enum arm_type_qualifiers
829 arm_strsbwbu_p_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
830 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_const
,
831 qualifier_unsigned
, qualifier_unsigned
};
832 #define STRSBWBU_P_QUALIFIERS (arm_strsbwbu_p_qualifiers)
834 static enum arm_type_qualifiers
835 arm_lsll_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
836 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_none
};
837 #define LSLL_QUALIFIERS (arm_lsll_qualifiers)
839 static enum arm_type_qualifiers
840 arm_uqshl_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
841 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_const
};
842 #define UQSHL_QUALIFIERS (arm_uqshl_qualifiers)
844 static enum arm_type_qualifiers
845 arm_asrl_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
846 = { qualifier_none
, qualifier_none
, qualifier_none
};
847 #define ASRL_QUALIFIERS (arm_asrl_qualifiers)
849 static enum arm_type_qualifiers
850 arm_sqshl_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
851 = { qualifier_unsigned
, qualifier_unsigned
, qualifier_const
};
852 #define SQSHL_QUALIFIERS (arm_sqshl_qualifiers)
854 /* End of Qualifier for MVE builtins. */
856 /* void ([T element type] *, T, immediate). */
857 static enum arm_type_qualifiers
858 arm_storestruct_lane_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
859 = { qualifier_void
, qualifier_pointer_map_mode
,
860 qualifier_none
, qualifier_struct_load_store_lane_index
};
861 #define STORE1LANE_QUALIFIERS (arm_storestruct_lane_qualifiers)
864 static enum arm_type_qualifiers
865 arm_sat_occurred_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
866 = { qualifier_none
, qualifier_void
};
867 #define SAT_OCCURRED_QUALIFIERS (arm_sat_occurred_qualifiers)
870 static enum arm_type_qualifiers
871 arm_set_sat_qualifiers
[SIMD_MAX_BUILTIN_ARGS
]
872 = { qualifier_void
, qualifier_none
};
873 #define SET_SAT_QUALIFIERS (arm_set_sat_qualifiers)
875 #define v8qi_UP E_V8QImode
876 #define v4hi_UP E_V4HImode
877 #define v4hf_UP E_V4HFmode
878 #define v4bf_UP E_V4BFmode
879 #define v2si_UP E_V2SImode
880 #define v2sf_UP E_V2SFmode
881 #define v2bf_UP E_V2BFmode
882 #define di_UP E_DImode
883 #define v16qi_UP E_V16QImode
884 #define v8hi_UP E_V8HImode
885 #define v8hf_UP E_V8HFmode
886 #define v8bf_UP E_V8BFmode
887 #define v4si_UP E_V4SImode
888 #define v4sf_UP E_V4SFmode
889 #define v2di_UP E_V2DImode
890 #define ti_UP E_TImode
891 #define ei_UP E_EImode
892 #define oi_UP E_OImode
893 #define hf_UP E_HFmode
894 #define bf_UP E_BFmode
895 #define si_UP E_SImode
896 #define hi_UP E_HImode
897 #define void_UP E_VOIDmode
898 #define sf_UP E_SFmode
904 const enum insn_code code
;
906 enum arm_type_qualifiers
*qualifiers
;
909 #define CF(N,X) CODE_FOR_neon_##N##X
911 #define VAR1(T, N, A) \
912 {#N #A, UP (A), CF (N, A), 0, T##_QUALIFIERS},
913 #define VAR2(T, N, A, B) \
916 #define VAR3(T, N, A, B, C) \
919 #define VAR4(T, N, A, B, C, D) \
920 VAR3 (T, N, A, B, C) \
922 #define VAR5(T, N, A, B, C, D, E) \
923 VAR4 (T, N, A, B, C, D) \
925 #define VAR6(T, N, A, B, C, D, E, F) \
926 VAR5 (T, N, A, B, C, D, E) \
928 #define VAR7(T, N, A, B, C, D, E, F, G) \
929 VAR6 (T, N, A, B, C, D, E, F) \
931 #define VAR8(T, N, A, B, C, D, E, F, G, H) \
932 VAR7 (T, N, A, B, C, D, E, F, G) \
934 #define VAR9(T, N, A, B, C, D, E, F, G, H, I) \
935 VAR8 (T, N, A, B, C, D, E, F, G, H) \
937 #define VAR10(T, N, A, B, C, D, E, F, G, H, I, J) \
938 VAR9 (T, N, A, B, C, D, E, F, G, H, I) \
940 #define VAR11(T, N, A, B, C, D, E, F, G, H, I, J, K) \
941 VAR10 (T, N, A, B, C, D, E, F, G, H, I, J) \
943 #define VAR12(T, N, A, B, C, D, E, F, G, H, I, J, K, L) \
944 VAR11 (T, N, A, B, C, D, E, F, G, H, I, J, K) \
946 #define VAR13(T, N, A, B, C, D, E, F, G, H, I, J, K, L, M) \
947 VAR12 (T, N, A, B, C, D, E, F, G, H, I, J, K, L) \
949 #define VAR14(T, N, A, B, C, D, E, F, G, H, I, J, K, L, M, O) \
950 VAR13 (T, N, A, B, C, D, E, F, G, H, I, J, K, L, M) \
953 /* The builtin data can be found in arm_neon_builtins.def, arm_vfp_builtins.def
954 and arm_acle_builtins.def. The entries in arm_neon_builtins.def require
955 TARGET_NEON to be true. The feature tests are checked when the builtins are
958 The mode entries in the following table correspond to the "key" type of the
959 instruction variant, i.e. equivalent to that which would be specified after
960 the assembler mnemonic for neon instructions, which usually refers to the
961 last vector operand. The modes listed per instruction should be the same as
962 those defined for that instruction's pattern, for instance in neon.md. */
964 static arm_builtin_datum vfp_builtin_data
[] =
966 #include "arm_vfp_builtins.def"
969 static arm_builtin_datum neon_builtin_data
[] =
971 #include "arm_neon_builtins.def"
975 #define CF(N,X) CODE_FOR_mve_##N##X
976 static arm_builtin_datum mve_builtin_data
[] =
978 #include "arm_mve_builtins.def"
983 #define VAR1(T, N, A) \
984 {#N, UP (A), CODE_FOR_arm_##N, 0, T##_QUALIFIERS},
986 static arm_builtin_datum acle_builtin_data
[] =
988 #include "arm_acle_builtins.def"
992 /* IMM_MAX sets the maximum valid value of the CDE immediate operand.
993 ECF_FLAG sets the flag used for set_call_expr_flags. */
994 #define VAR1(T, N, A, IMM_MAX, ECF_FLAG) \
995 {{#N #A, UP (A), CODE_FOR_arm_##N##A, 0, T##_QUALIFIERS}, IMM_MAX, ECF_FLAG},
998 arm_builtin_datum base
;
999 unsigned int imm_max
;
1001 } arm_builtin_cde_datum
;
1003 static arm_builtin_cde_datum cde_builtin_data
[] =
1005 #include "arm_cde_builtins.def"
1009 #define VAR1(T, N, X) \
1010 ARM_BUILTIN_NEON_##N##X,
1014 ARM_BUILTIN_GETWCGR0
,
1015 ARM_BUILTIN_GETWCGR1
,
1016 ARM_BUILTIN_GETWCGR2
,
1017 ARM_BUILTIN_GETWCGR3
,
1019 ARM_BUILTIN_SETWCGR0
,
1020 ARM_BUILTIN_SETWCGR1
,
1021 ARM_BUILTIN_SETWCGR2
,
1022 ARM_BUILTIN_SETWCGR3
,
1026 ARM_BUILTIN_WAVG2BR
,
1027 ARM_BUILTIN_WAVG2HR
,
1045 ARM_BUILTIN_WALIGNI
,
1046 ARM_BUILTIN_WALIGNR0
,
1047 ARM_BUILTIN_WALIGNR1
,
1048 ARM_BUILTIN_WALIGNR2
,
1049 ARM_BUILTIN_WALIGNR3
,
1058 ARM_BUILTIN_TMOVMSKB
,
1059 ARM_BUILTIN_TMOVMSKH
,
1060 ARM_BUILTIN_TMOVMSKW
,
1069 ARM_BUILTIN_WPACKHSS
,
1070 ARM_BUILTIN_WPACKWSS
,
1071 ARM_BUILTIN_WPACKDSS
,
1072 ARM_BUILTIN_WPACKHUS
,
1073 ARM_BUILTIN_WPACKWUS
,
1074 ARM_BUILTIN_WPACKDUS
,
1079 ARM_BUILTIN_WADDSSB
,
1080 ARM_BUILTIN_WADDSSH
,
1081 ARM_BUILTIN_WADDSSW
,
1082 ARM_BUILTIN_WADDUSB
,
1083 ARM_BUILTIN_WADDUSH
,
1084 ARM_BUILTIN_WADDUSW
,
1088 ARM_BUILTIN_WSUBSSB
,
1089 ARM_BUILTIN_WSUBSSH
,
1090 ARM_BUILTIN_WSUBSSW
,
1091 ARM_BUILTIN_WSUBUSB
,
1092 ARM_BUILTIN_WSUBUSH
,
1093 ARM_BUILTIN_WSUBUSW
,
1100 ARM_BUILTIN_WCMPEQB
,
1101 ARM_BUILTIN_WCMPEQH
,
1102 ARM_BUILTIN_WCMPEQW
,
1103 ARM_BUILTIN_WCMPGTUB
,
1104 ARM_BUILTIN_WCMPGTUH
,
1105 ARM_BUILTIN_WCMPGTUW
,
1106 ARM_BUILTIN_WCMPGTSB
,
1107 ARM_BUILTIN_WCMPGTSH
,
1108 ARM_BUILTIN_WCMPGTSW
,
1110 ARM_BUILTIN_TEXTRMSB
,
1111 ARM_BUILTIN_TEXTRMSH
,
1112 ARM_BUILTIN_TEXTRMSW
,
1113 ARM_BUILTIN_TEXTRMUB
,
1114 ARM_BUILTIN_TEXTRMUH
,
1115 ARM_BUILTIN_TEXTRMUW
,
1165 ARM_BUILTIN_WUNPCKIHB
,
1166 ARM_BUILTIN_WUNPCKIHH
,
1167 ARM_BUILTIN_WUNPCKIHW
,
1168 ARM_BUILTIN_WUNPCKILB
,
1169 ARM_BUILTIN_WUNPCKILH
,
1170 ARM_BUILTIN_WUNPCKILW
,
1172 ARM_BUILTIN_WUNPCKEHSB
,
1173 ARM_BUILTIN_WUNPCKEHSH
,
1174 ARM_BUILTIN_WUNPCKEHSW
,
1175 ARM_BUILTIN_WUNPCKEHUB
,
1176 ARM_BUILTIN_WUNPCKEHUH
,
1177 ARM_BUILTIN_WUNPCKEHUW
,
1178 ARM_BUILTIN_WUNPCKELSB
,
1179 ARM_BUILTIN_WUNPCKELSH
,
1180 ARM_BUILTIN_WUNPCKELSW
,
1181 ARM_BUILTIN_WUNPCKELUB
,
1182 ARM_BUILTIN_WUNPCKELUH
,
1183 ARM_BUILTIN_WUNPCKELUW
,
1189 ARM_BUILTIN_WADDSUBHX
,
1190 ARM_BUILTIN_WSUBADDHX
,
1192 ARM_BUILTIN_WABSDIFFB
,
1193 ARM_BUILTIN_WABSDIFFH
,
1194 ARM_BUILTIN_WABSDIFFW
,
1202 ARM_BUILTIN_WMADDSX
,
1203 ARM_BUILTIN_WMADDUX
,
1205 ARM_BUILTIN_WMADDSN
,
1206 ARM_BUILTIN_WMADDUN
,
1208 ARM_BUILTIN_WMULWSM
,
1209 ARM_BUILTIN_WMULWUM
,
1211 ARM_BUILTIN_WMULWSMR
,
1212 ARM_BUILTIN_WMULWUMR
,
1216 ARM_BUILTIN_WMULSMR
,
1217 ARM_BUILTIN_WMULUMR
,
1220 ARM_BUILTIN_WQMULMR
,
1222 ARM_BUILTIN_WQMULWM
,
1223 ARM_BUILTIN_WQMULWMR
,
1225 ARM_BUILTIN_WADDBHUSM
,
1226 ARM_BUILTIN_WADDBHUSL
,
1228 ARM_BUILTIN_WQMIABB
,
1229 ARM_BUILTIN_WQMIABT
,
1230 ARM_BUILTIN_WQMIATB
,
1231 ARM_BUILTIN_WQMIATT
,
1233 ARM_BUILTIN_WQMIABBN
,
1234 ARM_BUILTIN_WQMIABTN
,
1235 ARM_BUILTIN_WQMIATBN
,
1236 ARM_BUILTIN_WQMIATTN
,
1243 ARM_BUILTIN_WMIABBN
,
1244 ARM_BUILTIN_WMIABTN
,
1245 ARM_BUILTIN_WMIATBN
,
1246 ARM_BUILTIN_WMIATTN
,
1248 ARM_BUILTIN_WMIAWBB
,
1249 ARM_BUILTIN_WMIAWBT
,
1250 ARM_BUILTIN_WMIAWTB
,
1251 ARM_BUILTIN_WMIAWTT
,
1253 ARM_BUILTIN_WMIAWBBN
,
1254 ARM_BUILTIN_WMIAWBTN
,
1255 ARM_BUILTIN_WMIAWTBN
,
1256 ARM_BUILTIN_WMIAWTTN
,
1260 ARM_BUILTIN_GET_FPSCR
,
1261 ARM_BUILTIN_SET_FPSCR
,
1262 ARM_BUILTIN_GET_FPSCR_NZCVQC
,
1263 ARM_BUILTIN_SET_FPSCR_NZCVQC
,
1265 ARM_BUILTIN_CMSE_NONSECURE_CALLER
,
1266 ARM_BUILTIN_SIMD_LANE_CHECK
,
1272 #define CRYPTO1(L, U, M1, M2) \
1273 ARM_BUILTIN_CRYPTO_##U,
1274 #define CRYPTO2(L, U, M1, M2, M3) \
1275 ARM_BUILTIN_CRYPTO_##U,
1276 #define CRYPTO3(L, U, M1, M2, M3, M4) \
1277 ARM_BUILTIN_CRYPTO_##U,
1279 ARM_BUILTIN_CRYPTO_BASE
,
1281 #include "crypto.def"
1287 ARM_BUILTIN_VFP_BASE
,
1289 #include "arm_vfp_builtins.def"
1291 ARM_BUILTIN_NEON_BASE
,
1293 #include "arm_neon_builtins.def"
1296 #define VAR1(T, N, X) \
1299 ARM_BUILTIN_ACLE_BASE
,
1300 ARM_BUILTIN_SAT_IMM_CHECK
= ARM_BUILTIN_ACLE_BASE
,
1302 #include "arm_acle_builtins.def"
1305 #define VAR1(T, N, X, ... ) \
1308 ARM_BUILTIN_CDE_BASE
,
1310 #include "arm_cde_builtins.def"
1312 ARM_BUILTIN_MVE_BASE
,
1315 #define VAR1(T, N, X) \
1316 ARM_BUILTIN_MVE_##N##X,
1317 #include "arm_mve_builtins.def"
1322 #define ARM_BUILTIN_VFP_PATTERN_START \
1323 (ARM_BUILTIN_VFP_BASE + 1)
1325 #define ARM_BUILTIN_NEON_PATTERN_START \
1326 (ARM_BUILTIN_NEON_BASE + 1)
1328 #define ARM_BUILTIN_MVE_PATTERN_START \
1329 (ARM_BUILTIN_MVE_BASE + 1)
1331 #define ARM_BUILTIN_ACLE_PATTERN_START \
1332 (ARM_BUILTIN_ACLE_BASE + 1)
1334 #define ARM_BUILTIN_CDE_PATTERN_START \
1335 (ARM_BUILTIN_CDE_BASE + 1)
1337 #define ARM_BUILTIN_CDE_PATTERN_END \
1338 (ARM_BUILTIN_CDE_BASE + ARRAY_SIZE (cde_builtin_data))
1352 static GTY(()) tree arm_builtin_decls
[ARM_BUILTIN_MAX
];
1354 #define NUM_DREG_TYPES 5
1355 #define NUM_QREG_TYPES 6
1357 /* Internal scalar builtin types. These types are used to support
1358 neon intrinsic builtins. They are _not_ user-visible types. Therefore
1359 the mangling for these types are implementation defined. */
1360 const char *arm_scalar_builtin_types
[] = {
1361 "__builtin_neon_qi",
1362 "__builtin_neon_hi",
1363 "__builtin_neon_si",
1364 "__builtin_neon_sf",
1365 "__builtin_neon_di",
1366 "__builtin_neon_df",
1367 "__builtin_neon_ti",
1368 "__builtin_neon_uqi",
1369 "__builtin_neon_uhi",
1370 "__builtin_neon_usi",
1371 "__builtin_neon_udi",
1372 "__builtin_neon_ei",
1373 "__builtin_neon_oi",
1374 "__builtin_neon_ci",
1375 "__builtin_neon_xi",
1376 "__builtin_neon_bf",
1380 #define ENTRY(E, M, Q, S, T, G) E,
1383 #include "arm-simd-builtin-types.def"
1388 struct arm_simd_type_info
1390 enum arm_simd_type type
;
1392 /* Internal type name. */
1395 /* Internal type name(mangled). The mangled names conform to the
1396 AAPCS (see "Procedure Call Standard for the ARM Architecture",
1397 Appendix A). To qualify for emission with the mangled names defined in
1398 that document, a vector type must not only be of the correct mode but also
1399 be of the correct internal Neon vector type (e.g. __simd64_int8_t);
1400 these types are registered by arm_init_simd_builtin_types (). In other
1401 words, vector types defined in other ways e.g. via vector_size attribute
1402 will get default mangled names. */
1405 /* Internal type. */
1411 /* Machine mode the internal type maps to. */
1415 enum arm_type_qualifiers q
;
1418 #define ENTRY(E, M, Q, S, T, G) \
1420 "__simd" #S "_" #T "_t", \
1421 #G "__simd" #S "_" #T "_t", \
1422 NULL_TREE, NULL_TREE, M##mode, qualifier_##Q},
1423 static struct arm_simd_type_info arm_simd_types
[] = {
1424 #include "arm-simd-builtin-types.def"
1428 /* The user-visible __fp16 type. */
1429 tree arm_fp16_type_node
= NULL_TREE
;
1431 /* Back-end node type for brain float (bfloat) types. */
1432 tree arm_bf16_type_node
= NULL_TREE
;
1433 tree arm_bf16_ptr_type_node
= NULL_TREE
;
1435 static tree arm_simd_intOI_type_node
= NULL_TREE
;
1436 static tree arm_simd_intEI_type_node
= NULL_TREE
;
1437 static tree arm_simd_intCI_type_node
= NULL_TREE
;
1438 static tree arm_simd_intXI_type_node
= NULL_TREE
;
1439 static tree arm_simd_polyQI_type_node
= NULL_TREE
;
1440 static tree arm_simd_polyHI_type_node
= NULL_TREE
;
1441 static tree arm_simd_polyDI_type_node
= NULL_TREE
;
1442 static tree arm_simd_polyTI_type_node
= NULL_TREE
;
1445 arm_mangle_builtin_scalar_type (const_tree type
)
1449 while (arm_scalar_builtin_types
[i
] != NULL
)
1451 const char *name
= arm_scalar_builtin_types
[i
];
1453 if (TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
1454 && DECL_NAME (TYPE_NAME (type
))
1455 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type
))), name
))
1456 return arm_scalar_builtin_types
[i
];
1463 arm_mangle_builtin_vector_type (const_tree type
)
1465 tree attrs
= TYPE_ATTRIBUTES (type
);
1466 if (tree attr
= lookup_attribute ("Advanced SIMD type", attrs
))
1468 tree mangled_name
= TREE_VALUE (TREE_VALUE (attr
));
1469 return IDENTIFIER_POINTER (mangled_name
);
1476 arm_mangle_builtin_type (const_tree type
)
1479 /* Walk through all the Arm builtins types tables to filter out the
1481 if ((mangle
= arm_mangle_builtin_vector_type (type
))
1482 || (mangle
= arm_mangle_builtin_scalar_type (type
)))
1489 arm_simd_builtin_std_type (machine_mode mode
,
1490 enum arm_type_qualifiers q
)
1492 #define QUAL_TYPE(M) \
1493 ((q == qualifier_none) ? int##M##_type_node : unsigned_int##M##_type_node);
1497 return QUAL_TYPE (QI
);
1499 return QUAL_TYPE (HI
);
1501 return QUAL_TYPE (SI
);
1503 return QUAL_TYPE (DI
);
1505 return QUAL_TYPE (TI
);
1507 return arm_simd_intOI_type_node
;
1509 return arm_simd_intEI_type_node
;
1511 return arm_simd_intCI_type_node
;
1513 return arm_simd_intXI_type_node
;
1515 return arm_fp16_type_node
;
1517 return float_type_node
;
1519 return double_type_node
;
1521 return arm_bf16_type_node
;
1529 arm_lookup_simd_builtin_type (machine_mode mode
,
1530 enum arm_type_qualifiers q
)
1533 int nelts
= sizeof (arm_simd_types
) / sizeof (arm_simd_types
[0]);
1535 /* Non-poly scalar modes map to standard types not in the table. */
1536 if (q
!= qualifier_poly
&& !VECTOR_MODE_P (mode
))
1537 return arm_simd_builtin_std_type (mode
, q
);
1539 for (i
= 0; i
< nelts
; i
++)
1540 if (arm_simd_types
[i
].mode
== mode
1541 && arm_simd_types
[i
].q
== q
)
1542 return arm_simd_types
[i
].itype
;
1544 /* Note that we won't have caught the underlying type for poly64x2_t
1545 in the above table. This gets default mangling. */
1551 arm_simd_builtin_type (machine_mode mode
, bool unsigned_p
, bool poly_p
)
1554 return arm_lookup_simd_builtin_type (mode
, qualifier_poly
);
1555 else if (unsigned_p
)
1556 return arm_lookup_simd_builtin_type (mode
, qualifier_unsigned
);
1558 return arm_lookup_simd_builtin_type (mode
, qualifier_none
);
1562 arm_init_simd_builtin_types (void)
1565 int nelts
= sizeof (arm_simd_types
) / sizeof (arm_simd_types
[0]);
1568 /* Poly types are a world of their own. In order to maintain legacy
1569 ABI, they get initialized using the old interface, and don't get
1570 an entry in our mangling table, consequently, they get default
1571 mangling. As a further gotcha, poly8_t and poly16_t are signed
1572 types, poly64_t and poly128_t are unsigned types. */
1573 if (!TARGET_HAVE_MVE
)
1575 arm_simd_polyQI_type_node
1576 = build_distinct_type_copy (intQI_type_node
);
1577 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyQI_type_node
,
1578 "__builtin_neon_poly8");
1579 arm_simd_polyHI_type_node
1580 = build_distinct_type_copy (intHI_type_node
);
1581 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyHI_type_node
,
1582 "__builtin_neon_poly16");
1583 arm_simd_polyDI_type_node
1584 = build_distinct_type_copy (unsigned_intDI_type_node
);
1585 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyDI_type_node
,
1586 "__builtin_neon_poly64");
1587 arm_simd_polyTI_type_node
1588 = build_distinct_type_copy (unsigned_intTI_type_node
);
1589 (*lang_hooks
.types
.register_builtin_type
) (arm_simd_polyTI_type_node
,
1590 "__builtin_neon_poly128");
1591 /* Init poly vector element types with scalar poly types. */
1592 arm_simd_types
[Poly8x8_t
].eltype
= arm_simd_polyQI_type_node
;
1593 arm_simd_types
[Poly8x16_t
].eltype
= arm_simd_polyQI_type_node
;
1594 arm_simd_types
[Poly16x4_t
].eltype
= arm_simd_polyHI_type_node
;
1595 arm_simd_types
[Poly16x8_t
].eltype
= arm_simd_polyHI_type_node
;
1596 /* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default
1599 /* Prevent front-ends from transforming poly vectors into string
1601 TYPE_STRING_FLAG (arm_simd_polyQI_type_node
) = false;
1602 TYPE_STRING_FLAG (arm_simd_polyHI_type_node
) = false;
1604 /* Init all the element types built by the front-end. */
1605 arm_simd_types
[Int8x8_t
].eltype
= intQI_type_node
;
1606 arm_simd_types
[Int8x16_t
].eltype
= intQI_type_node
;
1607 arm_simd_types
[Int16x4_t
].eltype
= intHI_type_node
;
1608 arm_simd_types
[Int16x8_t
].eltype
= intHI_type_node
;
1609 arm_simd_types
[Int32x2_t
].eltype
= intSI_type_node
;
1610 arm_simd_types
[Int32x4_t
].eltype
= intSI_type_node
;
1611 arm_simd_types
[Int64x2_t
].eltype
= intDI_type_node
;
1612 arm_simd_types
[Uint8x8_t
].eltype
= unsigned_intQI_type_node
;
1613 arm_simd_types
[Uint8x16_t
].eltype
= unsigned_intQI_type_node
;
1614 arm_simd_types
[Uint16x4_t
].eltype
= unsigned_intHI_type_node
;
1615 arm_simd_types
[Uint16x8_t
].eltype
= unsigned_intHI_type_node
;
1616 arm_simd_types
[Uint32x2_t
].eltype
= unsigned_intSI_type_node
;
1617 arm_simd_types
[Uint32x4_t
].eltype
= unsigned_intSI_type_node
;
1618 arm_simd_types
[Uint64x2_t
].eltype
= unsigned_intDI_type_node
;
1620 /* Note: poly64x2_t is defined in arm_neon.h, to ensure it gets default
1623 /* Continue with standard types. */
1624 /* The __builtin_simd{64,128}_float16 types are kept private unless
1625 we have a scalar __fp16 type. */
1626 arm_simd_types
[Float16x4_t
].eltype
= arm_fp16_type_node
;
1627 arm_simd_types
[Float16x8_t
].eltype
= arm_fp16_type_node
;
1628 arm_simd_types
[Float32x2_t
].eltype
= float_type_node
;
1629 arm_simd_types
[Float32x4_t
].eltype
= float_type_node
;
1631 /* Init Bfloat vector types with underlying __bf16 scalar type. */
1632 arm_simd_types
[Bfloat16x2_t
].eltype
= arm_bf16_type_node
;
1633 arm_simd_types
[Bfloat16x4_t
].eltype
= arm_bf16_type_node
;
1634 arm_simd_types
[Bfloat16x8_t
].eltype
= arm_bf16_type_node
;
1636 for (i
= 0; i
< nelts
; i
++)
1638 tree eltype
= arm_simd_types
[i
].eltype
;
1639 machine_mode mode
= arm_simd_types
[i
].mode
;
1643 if (arm_simd_types
[i
].itype
== NULL
)
1645 tree type
= build_vector_type (eltype
, GET_MODE_NUNITS (mode
));
1646 type
= build_distinct_type_copy (type
);
1647 SET_TYPE_STRUCTURAL_EQUALITY (type
);
1649 tree mangled_name
= get_identifier (arm_simd_types
[i
].mangle
);
1650 tree value
= tree_cons (NULL_TREE
, mangled_name
, NULL_TREE
);
1651 TYPE_ATTRIBUTES (type
)
1652 = tree_cons (get_identifier ("Advanced SIMD type"), value
,
1653 TYPE_ATTRIBUTES (type
));
1654 arm_simd_types
[i
].itype
= type
;
1657 tdecl
= add_builtin_type (arm_simd_types
[i
].name
,
1658 arm_simd_types
[i
].itype
);
1659 TYPE_NAME (arm_simd_types
[i
].itype
) = tdecl
;
1660 SET_TYPE_STRUCTURAL_EQUALITY (arm_simd_types
[i
].itype
);
1663 #define AARCH_BUILD_SIGNED_TYPE(mode) \
1664 make_signed_type (GET_MODE_PRECISION (mode));
1665 arm_simd_intOI_type_node
= AARCH_BUILD_SIGNED_TYPE (OImode
);
1666 arm_simd_intEI_type_node
= AARCH_BUILD_SIGNED_TYPE (EImode
);
1667 arm_simd_intCI_type_node
= AARCH_BUILD_SIGNED_TYPE (CImode
);
1668 arm_simd_intXI_type_node
= AARCH_BUILD_SIGNED_TYPE (XImode
);
1669 #undef AARCH_BUILD_SIGNED_TYPE
1671 tdecl
= add_builtin_type
1672 ("__builtin_neon_ei" , arm_simd_intEI_type_node
);
1673 TYPE_NAME (arm_simd_intEI_type_node
) = tdecl
;
1674 tdecl
= add_builtin_type
1675 ("__builtin_neon_oi" , arm_simd_intOI_type_node
);
1676 TYPE_NAME (arm_simd_intOI_type_node
) = tdecl
;
1677 tdecl
= add_builtin_type
1678 ("__builtin_neon_ci" , arm_simd_intCI_type_node
);
1679 TYPE_NAME (arm_simd_intCI_type_node
) = tdecl
;
1680 tdecl
= add_builtin_type
1681 ("__builtin_neon_xi" , arm_simd_intXI_type_node
);
1682 TYPE_NAME (arm_simd_intXI_type_node
) = tdecl
;
1686 arm_init_simd_builtin_scalar_types (void)
1688 /* Define typedefs for all the standard scalar types. */
1689 (*lang_hooks
.types
.register_builtin_type
) (intQI_type_node
,
1690 "__builtin_neon_qi");
1691 (*lang_hooks
.types
.register_builtin_type
) (intHI_type_node
,
1692 "__builtin_neon_hi");
1693 (*lang_hooks
.types
.register_builtin_type
) (intSI_type_node
,
1694 "__builtin_neon_si");
1695 (*lang_hooks
.types
.register_builtin_type
) (float_type_node
,
1696 "__builtin_neon_sf");
1697 (*lang_hooks
.types
.register_builtin_type
) (intDI_type_node
,
1698 "__builtin_neon_di");
1699 (*lang_hooks
.types
.register_builtin_type
) (double_type_node
,
1700 "__builtin_neon_df");
1701 (*lang_hooks
.types
.register_builtin_type
) (intTI_type_node
,
1702 "__builtin_neon_ti");
1703 (*lang_hooks
.types
.register_builtin_type
) (arm_bf16_type_node
,
1704 "__builtin_neon_bf");
1705 /* Unsigned integer types for various mode sizes. */
1706 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intQI_type_node
,
1707 "__builtin_neon_uqi");
1708 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intHI_type_node
,
1709 "__builtin_neon_uhi");
1710 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intSI_type_node
,
1711 "__builtin_neon_usi");
1712 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intDI_type_node
,
1713 "__builtin_neon_udi");
1714 (*lang_hooks
.types
.register_builtin_type
) (unsigned_intTI_type_node
,
1715 "__builtin_neon_uti");
1718 /* Set up a builtin. It will use information stored in the argument struct D to
1719 derive the builtin's type signature and name. It will append the name in D
1720 to the PREFIX passed and use these to create a builtin declaration that is
1721 then stored in 'arm_builtin_decls' under index FCODE. This FCODE is also
1722 written back to D for future use. */
1725 arm_init_builtin (unsigned int fcode
, arm_builtin_datum
*d
,
1726 const char * prefix
)
1728 bool print_type_signature_p
= false;
1729 char type_signature
[SIMD_MAX_BUILTIN_ARGS
] = { 0 };
1736 /* We must track two variables here. op_num is
1737 the operand number as in the RTL pattern. This is
1738 required to access the mode (e.g. V4SF mode) of the
1739 argument, from which the base type can be derived.
1740 arg_num is an index in to the qualifiers data, which
1741 gives qualifiers to the type (e.g. const unsigned).
1742 The reason these two variables may differ by one is the
1743 void return type. While all return types take the 0th entry
1744 in the qualifiers array, there is no operand for them in the
1746 int op_num
= insn_data
[d
->code
].n_operands
- 1;
1747 int arg_num
= d
->qualifiers
[0] & qualifier_void
1750 tree return_type
= void_type_node
, args
= void_list_node
;
1753 /* Build a function type directly from the insn_data for this
1754 builtin. The build_function_type () function takes care of
1755 removing duplicates for us. */
1756 for (; op_num
>= 0; arg_num
--, op_num
--)
1758 machine_mode op_mode
= insn_data
[d
->code
].operand
[op_num
].mode
;
1759 enum arm_type_qualifiers qualifiers
= d
->qualifiers
[arg_num
];
1761 if (qualifiers
& qualifier_unsigned
)
1763 type_signature
[arg_num
] = 'u';
1764 print_type_signature_p
= true;
1766 else if (qualifiers
& qualifier_poly
)
1768 type_signature
[arg_num
] = 'p';
1769 print_type_signature_p
= true;
1772 type_signature
[arg_num
] = 's';
1774 /* Skip an internal operand for vget_{low, high}. */
1775 if (qualifiers
& qualifier_internal
)
1778 /* Some builtins have different user-facing types
1779 for certain arguments, encoded in d->mode. */
1780 if (qualifiers
& qualifier_map_mode
)
1783 /* For pointers, we want a pointer to the basic type
1785 if (qualifiers
& qualifier_pointer
&& VECTOR_MODE_P (op_mode
))
1786 op_mode
= GET_MODE_INNER (op_mode
);
1788 /* For void pointers we already have nodes constructed by the midend. */
1789 if (qualifiers
& qualifier_void_pointer
)
1790 eltype
= qualifiers
& qualifier_const
1791 ? const_ptr_type_node
: ptr_type_node
;
1795 = arm_simd_builtin_type (op_mode
,
1796 (qualifiers
& qualifier_unsigned
) != 0,
1797 (qualifiers
& qualifier_poly
) != 0);
1798 gcc_assert (eltype
!= NULL
);
1800 /* Add qualifiers. */
1801 if (qualifiers
& qualifier_const
)
1802 eltype
= build_qualified_type (eltype
, TYPE_QUAL_CONST
);
1804 if (qualifiers
& qualifier_pointer
)
1805 eltype
= build_pointer_type (eltype
);
1807 /* If we have reached arg_num == 0, we are at a non-void
1808 return type. Otherwise, we are still processing
1811 return_type
= eltype
;
1813 args
= tree_cons (NULL_TREE
, eltype
, args
);
1816 ftype
= build_function_type (return_type
, args
);
1818 gcc_assert (ftype
!= NULL
);
1820 if (print_type_signature_p
1821 && IN_RANGE (fcode
, ARM_BUILTIN_VFP_BASE
, ARM_BUILTIN_ACLE_BASE
- 1))
1822 snprintf (namebuf
, sizeof (namebuf
), "%s_%s_%s",
1823 prefix
, d
->name
, type_signature
);
1825 snprintf (namebuf
, sizeof (namebuf
), "%s_%s",
1828 fndecl
= add_builtin_function (namebuf
, ftype
, fcode
, BUILT_IN_MD
,
1830 arm_builtin_decls
[fcode
] = fndecl
;
1833 /* Initialize the backend REAL_TYPE type supporting bfloat types. */
1835 arm_init_bf16_types (void)
1837 arm_bf16_type_node
= make_node (REAL_TYPE
);
1838 TYPE_PRECISION (arm_bf16_type_node
) = 16;
1839 SET_TYPE_MODE (arm_bf16_type_node
, BFmode
);
1840 layout_type (arm_bf16_type_node
);
1842 lang_hooks
.types
.register_builtin_type (arm_bf16_type_node
, "__bf16");
1843 arm_bf16_ptr_type_node
= build_pointer_type (arm_bf16_type_node
);
1846 /* Set up ACLE builtins, even builtins for instructions that are not
1847 in the current target ISA to allow the user to compile particular modules
1848 with different target specific options that differ from the command line
1849 options. Such builtins will be rejected in arm_expand_builtin. */
1852 arm_init_acle_builtins (void)
1854 unsigned int i
, fcode
= ARM_BUILTIN_ACLE_PATTERN_START
;
1856 tree sat_check_fpr
= build_function_type_list (void_type_node
,
1861 arm_builtin_decls
[ARM_BUILTIN_SAT_IMM_CHECK
]
1862 = add_builtin_function ("__builtin_sat_imm_check", sat_check_fpr
,
1863 ARM_BUILTIN_SAT_IMM_CHECK
, BUILT_IN_MD
,
1866 for (i
= 0; i
< ARRAY_SIZE (acle_builtin_data
); i
++, fcode
++)
1868 arm_builtin_datum
*d
= &acle_builtin_data
[i
];
1869 arm_init_builtin (fcode
, d
, "__builtin_arm");
1874 arm_init_cde_builtins (void)
1876 unsigned int i
, fcode
= ARM_BUILTIN_CDE_PATTERN_START
;
1877 for (i
= 0; i
< ARRAY_SIZE (cde_builtin_data
); i
++, fcode
++)
1879 /* Only define CDE floating point builtins if the target has floating
1880 point registers. NOTE: without HARD_FLOAT we don't have MVE, so we
1881 can break out of this loop directly here. */
1882 if (!TARGET_MAYBE_HARD_FLOAT
&& fcode
>= ARM_BUILTIN_vcx1si
)
1884 /* Only define CDE/MVE builtins if MVE is available. */
1885 if (!TARGET_HAVE_MVE
&& fcode
>= ARM_BUILTIN_vcx1qv16qi
)
1887 arm_builtin_cde_datum
*cde
= &cde_builtin_data
[i
];
1888 arm_builtin_datum
*d
= &cde
->base
;
1889 arm_init_builtin (fcode
, d
, "__builtin_arm");
1890 set_call_expr_flags (arm_builtin_decls
[fcode
], cde
->ecf_flag
);
1894 /* Set up all the MVE builtins mentioned in arm_mve_builtins.def file. */
1896 arm_init_mve_builtins (void)
1898 volatile unsigned int i
, fcode
= ARM_BUILTIN_MVE_PATTERN_START
;
1900 arm_init_simd_builtin_scalar_types ();
1901 arm_init_simd_builtin_types ();
1903 /* Add support for __builtin_{get,set}_fpscr_nzcvqc, used by MVE intrinsics
1904 that read and/or write the carry bit. */
1905 tree get_fpscr_nzcvqc
= build_function_type_list (intSI_type_node
,
1907 tree set_fpscr_nzcvqc
= build_function_type_list (void_type_node
,
1910 arm_builtin_decls
[ARM_BUILTIN_GET_FPSCR_NZCVQC
]
1911 = add_builtin_function ("__builtin_arm_get_fpscr_nzcvqc", get_fpscr_nzcvqc
,
1912 ARM_BUILTIN_GET_FPSCR_NZCVQC
, BUILT_IN_MD
, NULL
,
1914 arm_builtin_decls
[ARM_BUILTIN_SET_FPSCR_NZCVQC
]
1915 = add_builtin_function ("__builtin_arm_set_fpscr_nzcvqc", set_fpscr_nzcvqc
,
1916 ARM_BUILTIN_SET_FPSCR_NZCVQC
, BUILT_IN_MD
, NULL
,
1919 for (i
= 0; i
< ARRAY_SIZE (mve_builtin_data
); i
++, fcode
++)
1921 arm_builtin_datum
*d
= &mve_builtin_data
[i
];
1922 arm_init_builtin (fcode
, d
, "__builtin_mve");
1926 /* Set up all the NEON builtins, even builtins for instructions that are not
1927 in the current target ISA to allow the user to compile particular modules
1928 with different target specific options that differ from the command line
1929 options. Such builtins will be rejected in arm_expand_builtin. */
1932 arm_init_neon_builtins (void)
1934 unsigned int i
, fcode
= ARM_BUILTIN_NEON_PATTERN_START
;
1936 arm_init_simd_builtin_types ();
1938 /* Strong-typing hasn't been implemented for all AdvSIMD builtin intrinsics.
1939 Therefore we need to preserve the old __builtin scalar types. It can be
1940 removed once all the intrinsics become strongly typed using the qualifier
1942 arm_init_simd_builtin_scalar_types ();
1944 for (i
= 0; i
< ARRAY_SIZE (neon_builtin_data
); i
++, fcode
++)
1946 arm_builtin_datum
*d
= &neon_builtin_data
[i
];
1947 arm_init_builtin (fcode
, d
, "__builtin_neon");
1951 /* Set up all the scalar floating point builtins. */
1954 arm_init_vfp_builtins (void)
1956 unsigned int i
, fcode
= ARM_BUILTIN_VFP_PATTERN_START
;
1958 for (i
= 0; i
< ARRAY_SIZE (vfp_builtin_data
); i
++, fcode
++)
1960 arm_builtin_datum
*d
= &vfp_builtin_data
[i
];
1961 arm_init_builtin (fcode
, d
, "__builtin_neon");
1966 arm_init_crypto_builtins (void)
1968 tree V16UQI_type_node
1969 = arm_simd_builtin_type (V16QImode
, true, false);
1971 tree V4USI_type_node
1972 = arm_simd_builtin_type (V4SImode
, true, false);
1974 tree v16uqi_ftype_v16uqi
1975 = build_function_type_list (V16UQI_type_node
, V16UQI_type_node
,
1978 tree v16uqi_ftype_v16uqi_v16uqi
1979 = build_function_type_list (V16UQI_type_node
, V16UQI_type_node
,
1980 V16UQI_type_node
, NULL_TREE
);
1982 tree v4usi_ftype_v4usi
1983 = build_function_type_list (V4USI_type_node
, V4USI_type_node
,
1986 tree v4usi_ftype_v4usi_v4usi
1987 = build_function_type_list (V4USI_type_node
, V4USI_type_node
,
1988 V4USI_type_node
, NULL_TREE
);
1990 tree v4usi_ftype_v4usi_v4usi_v4usi
1991 = build_function_type_list (V4USI_type_node
, V4USI_type_node
,
1992 V4USI_type_node
, V4USI_type_node
,
1995 tree uti_ftype_udi_udi
1996 = build_function_type_list (unsigned_intTI_type_node
,
1997 unsigned_intDI_type_node
,
1998 unsigned_intDI_type_node
,
2012 ARM_BUILTIN_CRYPTO_##U
2014 "__builtin_arm_crypto_"#L
2017 #define FT2(R, A1, A2) \
2018 R##_ftype_##A1##_##A2
2019 #define FT3(R, A1, A2, A3) \
2020 R##_ftype_##A1##_##A2##_##A3
2021 #define CRYPTO1(L, U, R, A) \
2022 arm_builtin_decls[C (U)] \
2023 = add_builtin_function (N (L), FT1 (R, A), \
2024 C (U), BUILT_IN_MD, NULL, NULL_TREE);
2025 #define CRYPTO2(L, U, R, A1, A2) \
2026 arm_builtin_decls[C (U)] \
2027 = add_builtin_function (N (L), FT2 (R, A1, A2), \
2028 C (U), BUILT_IN_MD, NULL, NULL_TREE);
2030 #define CRYPTO3(L, U, R, A1, A2, A3) \
2031 arm_builtin_decls[C (U)] \
2032 = add_builtin_function (N (L), FT3 (R, A1, A2, A3), \
2033 C (U), BUILT_IN_MD, NULL, NULL_TREE);
2034 #include "crypto.def"
2046 #undef NUM_DREG_TYPES
2047 #undef NUM_QREG_TYPES
2049 #define def_mbuiltin(FLAG, NAME, TYPE, CODE) \
2052 if (FLAG == isa_nobit \
2053 || bitmap_bit_p (arm_active_target.isa, FLAG)) \
2056 bdecl = add_builtin_function ((NAME), (TYPE), (CODE), \
2057 BUILT_IN_MD, NULL, NULL_TREE); \
2058 arm_builtin_decls[CODE] = bdecl; \
2063 struct builtin_description
2065 const enum isa_feature feature
;
2066 const enum insn_code icode
;
2067 const char * const name
;
2068 const enum arm_builtins code
;
2069 const enum rtx_code comparison
;
2070 const unsigned int flag
;
2073 static const struct builtin_description bdesc_2arg
[] =
2075 #define IWMMXT_BUILTIN(code, string, builtin) \
2076 { isa_bit_iwmmxt, CODE_FOR_##code, \
2077 "__builtin_arm_" string, \
2078 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
2080 #define IWMMXT2_BUILTIN(code, string, builtin) \
2081 { isa_bit_iwmmxt2, CODE_FOR_##code, \
2082 "__builtin_arm_" string, \
2083 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
2085 IWMMXT_BUILTIN (addv8qi3
, "waddb", WADDB
)
2086 IWMMXT_BUILTIN (addv4hi3
, "waddh", WADDH
)
2087 IWMMXT_BUILTIN (addv2si3
, "waddw", WADDW
)
2088 IWMMXT_BUILTIN (subv8qi3
, "wsubb", WSUBB
)
2089 IWMMXT_BUILTIN (subv4hi3
, "wsubh", WSUBH
)
2090 IWMMXT_BUILTIN (subv2si3
, "wsubw", WSUBW
)
2091 IWMMXT_BUILTIN (ssaddv8qi3
, "waddbss", WADDSSB
)
2092 IWMMXT_BUILTIN (ssaddv4hi3
, "waddhss", WADDSSH
)
2093 IWMMXT_BUILTIN (ssaddv2si3
, "waddwss", WADDSSW
)
2094 IWMMXT_BUILTIN (sssubv8qi3
, "wsubbss", WSUBSSB
)
2095 IWMMXT_BUILTIN (sssubv4hi3
, "wsubhss", WSUBSSH
)
2096 IWMMXT_BUILTIN (sssubv2si3
, "wsubwss", WSUBSSW
)
2097 IWMMXT_BUILTIN (usaddv8qi3
, "waddbus", WADDUSB
)
2098 IWMMXT_BUILTIN (usaddv4hi3
, "waddhus", WADDUSH
)
2099 IWMMXT_BUILTIN (usaddv2si3
, "waddwus", WADDUSW
)
2100 IWMMXT_BUILTIN (ussubv8qi3
, "wsubbus", WSUBUSB
)
2101 IWMMXT_BUILTIN (ussubv4hi3
, "wsubhus", WSUBUSH
)
2102 IWMMXT_BUILTIN (ussubv2si3
, "wsubwus", WSUBUSW
)
2103 IWMMXT_BUILTIN (mulv4hi3
, "wmulul", WMULUL
)
2104 IWMMXT_BUILTIN (smulv4hi3_highpart
, "wmulsm", WMULSM
)
2105 IWMMXT_BUILTIN (umulv4hi3_highpart
, "wmulum", WMULUM
)
2106 IWMMXT_BUILTIN (eqv8qi3
, "wcmpeqb", WCMPEQB
)
2107 IWMMXT_BUILTIN (eqv4hi3
, "wcmpeqh", WCMPEQH
)
2108 IWMMXT_BUILTIN (eqv2si3
, "wcmpeqw", WCMPEQW
)
2109 IWMMXT_BUILTIN (gtuv8qi3
, "wcmpgtub", WCMPGTUB
)
2110 IWMMXT_BUILTIN (gtuv4hi3
, "wcmpgtuh", WCMPGTUH
)
2111 IWMMXT_BUILTIN (gtuv2si3
, "wcmpgtuw", WCMPGTUW
)
2112 IWMMXT_BUILTIN (gtv8qi3
, "wcmpgtsb", WCMPGTSB
)
2113 IWMMXT_BUILTIN (gtv4hi3
, "wcmpgtsh", WCMPGTSH
)
2114 IWMMXT_BUILTIN (gtv2si3
, "wcmpgtsw", WCMPGTSW
)
2115 IWMMXT_BUILTIN (umaxv8qi3
, "wmaxub", WMAXUB
)
2116 IWMMXT_BUILTIN (smaxv8qi3
, "wmaxsb", WMAXSB
)
2117 IWMMXT_BUILTIN (umaxv4hi3
, "wmaxuh", WMAXUH
)
2118 IWMMXT_BUILTIN (smaxv4hi3
, "wmaxsh", WMAXSH
)
2119 IWMMXT_BUILTIN (umaxv2si3
, "wmaxuw", WMAXUW
)
2120 IWMMXT_BUILTIN (smaxv2si3
, "wmaxsw", WMAXSW
)
2121 IWMMXT_BUILTIN (uminv8qi3
, "wminub", WMINUB
)
2122 IWMMXT_BUILTIN (sminv8qi3
, "wminsb", WMINSB
)
2123 IWMMXT_BUILTIN (uminv4hi3
, "wminuh", WMINUH
)
2124 IWMMXT_BUILTIN (sminv4hi3
, "wminsh", WMINSH
)
2125 IWMMXT_BUILTIN (uminv2si3
, "wminuw", WMINUW
)
2126 IWMMXT_BUILTIN (sminv2si3
, "wminsw", WMINSW
)
2127 IWMMXT_BUILTIN (iwmmxt_anddi3
, "wand", WAND
)
2128 IWMMXT_BUILTIN (iwmmxt_nanddi3
, "wandn", WANDN
)
2129 IWMMXT_BUILTIN (iwmmxt_iordi3
, "wor", WOR
)
2130 IWMMXT_BUILTIN (iwmmxt_xordi3
, "wxor", WXOR
)
2131 IWMMXT_BUILTIN (iwmmxt_uavgv8qi3
, "wavg2b", WAVG2B
)
2132 IWMMXT_BUILTIN (iwmmxt_uavgv4hi3
, "wavg2h", WAVG2H
)
2133 IWMMXT_BUILTIN (iwmmxt_uavgrndv8qi3
, "wavg2br", WAVG2BR
)
2134 IWMMXT_BUILTIN (iwmmxt_uavgrndv4hi3
, "wavg2hr", WAVG2HR
)
2135 IWMMXT_BUILTIN (iwmmxt_wunpckilb
, "wunpckilb", WUNPCKILB
)
2136 IWMMXT_BUILTIN (iwmmxt_wunpckilh
, "wunpckilh", WUNPCKILH
)
2137 IWMMXT_BUILTIN (iwmmxt_wunpckilw
, "wunpckilw", WUNPCKILW
)
2138 IWMMXT_BUILTIN (iwmmxt_wunpckihb
, "wunpckihb", WUNPCKIHB
)
2139 IWMMXT_BUILTIN (iwmmxt_wunpckihh
, "wunpckihh", WUNPCKIHH
)
2140 IWMMXT_BUILTIN (iwmmxt_wunpckihw
, "wunpckihw", WUNPCKIHW
)
2141 IWMMXT2_BUILTIN (iwmmxt_waddsubhx
, "waddsubhx", WADDSUBHX
)
2142 IWMMXT2_BUILTIN (iwmmxt_wsubaddhx
, "wsubaddhx", WSUBADDHX
)
2143 IWMMXT2_BUILTIN (iwmmxt_wabsdiffb
, "wabsdiffb", WABSDIFFB
)
2144 IWMMXT2_BUILTIN (iwmmxt_wabsdiffh
, "wabsdiffh", WABSDIFFH
)
2145 IWMMXT2_BUILTIN (iwmmxt_wabsdiffw
, "wabsdiffw", WABSDIFFW
)
2146 IWMMXT2_BUILTIN (iwmmxt_avg4
, "wavg4", WAVG4
)
2147 IWMMXT2_BUILTIN (iwmmxt_avg4r
, "wavg4r", WAVG4R
)
2148 IWMMXT2_BUILTIN (iwmmxt_wmulwsm
, "wmulwsm", WMULWSM
)
2149 IWMMXT2_BUILTIN (iwmmxt_wmulwum
, "wmulwum", WMULWUM
)
2150 IWMMXT2_BUILTIN (iwmmxt_wmulwsmr
, "wmulwsmr", WMULWSMR
)
2151 IWMMXT2_BUILTIN (iwmmxt_wmulwumr
, "wmulwumr", WMULWUMR
)
2152 IWMMXT2_BUILTIN (iwmmxt_wmulwl
, "wmulwl", WMULWL
)
2153 IWMMXT2_BUILTIN (iwmmxt_wmulsmr
, "wmulsmr", WMULSMR
)
2154 IWMMXT2_BUILTIN (iwmmxt_wmulumr
, "wmulumr", WMULUMR
)
2155 IWMMXT2_BUILTIN (iwmmxt_wqmulm
, "wqmulm", WQMULM
)
2156 IWMMXT2_BUILTIN (iwmmxt_wqmulmr
, "wqmulmr", WQMULMR
)
2157 IWMMXT2_BUILTIN (iwmmxt_wqmulwm
, "wqmulwm", WQMULWM
)
2158 IWMMXT2_BUILTIN (iwmmxt_wqmulwmr
, "wqmulwmr", WQMULWMR
)
2159 IWMMXT_BUILTIN (iwmmxt_walignr0
, "walignr0", WALIGNR0
)
2160 IWMMXT_BUILTIN (iwmmxt_walignr1
, "walignr1", WALIGNR1
)
2161 IWMMXT_BUILTIN (iwmmxt_walignr2
, "walignr2", WALIGNR2
)
2162 IWMMXT_BUILTIN (iwmmxt_walignr3
, "walignr3", WALIGNR3
)
2164 #define IWMMXT_BUILTIN2(code, builtin) \
2165 { isa_bit_iwmmxt, CODE_FOR_##code, NULL, \
2166 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
2168 #define IWMMXT2_BUILTIN2(code, builtin) \
2169 { isa_bit_iwmmxt2, CODE_FOR_##code, NULL, \
2170 ARM_BUILTIN_##builtin, UNKNOWN, 0 },
2172 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusm
, WADDBHUSM
)
2173 IWMMXT2_BUILTIN2 (iwmmxt_waddbhusl
, WADDBHUSL
)
2174 IWMMXT_BUILTIN2 (iwmmxt_wpackhss
, WPACKHSS
)
2175 IWMMXT_BUILTIN2 (iwmmxt_wpackwss
, WPACKWSS
)
2176 IWMMXT_BUILTIN2 (iwmmxt_wpackdss
, WPACKDSS
)
2177 IWMMXT_BUILTIN2 (iwmmxt_wpackhus
, WPACKHUS
)
2178 IWMMXT_BUILTIN2 (iwmmxt_wpackwus
, WPACKWUS
)
2179 IWMMXT_BUILTIN2 (iwmmxt_wpackdus
, WPACKDUS
)
2180 IWMMXT_BUILTIN2 (iwmmxt_wmacuz
, WMACUZ
)
2181 IWMMXT_BUILTIN2 (iwmmxt_wmacsz
, WMACSZ
)
2184 #define FP_BUILTIN(L, U) \
2185 {isa_nobit, CODE_FOR_##L, "__builtin_arm_"#L, ARM_BUILTIN_##U, \
2188 FP_BUILTIN (get_fpscr
, GET_FPSCR
)
2189 FP_BUILTIN (set_fpscr
, SET_FPSCR
)
2192 #define CRYPTO_BUILTIN(L, U) \
2193 {isa_nobit, CODE_FOR_crypto_##L, "__builtin_arm_crypto_"#L, \
2194 ARM_BUILTIN_CRYPTO_##U, UNKNOWN, 0},
2198 #define CRYPTO2(L, U, R, A1, A2) CRYPTO_BUILTIN (L, U)
2199 #define CRYPTO1(L, U, R, A)
2200 #define CRYPTO3(L, U, R, A1, A2, A3)
2201 #include "crypto.def"
2208 static const struct builtin_description bdesc_1arg
[] =
2210 IWMMXT_BUILTIN (iwmmxt_tmovmskb
, "tmovmskb", TMOVMSKB
)
2211 IWMMXT_BUILTIN (iwmmxt_tmovmskh
, "tmovmskh", TMOVMSKH
)
2212 IWMMXT_BUILTIN (iwmmxt_tmovmskw
, "tmovmskw", TMOVMSKW
)
2213 IWMMXT_BUILTIN (iwmmxt_waccb
, "waccb", WACCB
)
2214 IWMMXT_BUILTIN (iwmmxt_wacch
, "wacch", WACCH
)
2215 IWMMXT_BUILTIN (iwmmxt_waccw
, "waccw", WACCW
)
2216 IWMMXT_BUILTIN (iwmmxt_wunpckehub
, "wunpckehub", WUNPCKEHUB
)
2217 IWMMXT_BUILTIN (iwmmxt_wunpckehuh
, "wunpckehuh", WUNPCKEHUH
)
2218 IWMMXT_BUILTIN (iwmmxt_wunpckehuw
, "wunpckehuw", WUNPCKEHUW
)
2219 IWMMXT_BUILTIN (iwmmxt_wunpckehsb
, "wunpckehsb", WUNPCKEHSB
)
2220 IWMMXT_BUILTIN (iwmmxt_wunpckehsh
, "wunpckehsh", WUNPCKEHSH
)
2221 IWMMXT_BUILTIN (iwmmxt_wunpckehsw
, "wunpckehsw", WUNPCKEHSW
)
2222 IWMMXT_BUILTIN (iwmmxt_wunpckelub
, "wunpckelub", WUNPCKELUB
)
2223 IWMMXT_BUILTIN (iwmmxt_wunpckeluh
, "wunpckeluh", WUNPCKELUH
)
2224 IWMMXT_BUILTIN (iwmmxt_wunpckeluw
, "wunpckeluw", WUNPCKELUW
)
2225 IWMMXT_BUILTIN (iwmmxt_wunpckelsb
, "wunpckelsb", WUNPCKELSB
)
2226 IWMMXT_BUILTIN (iwmmxt_wunpckelsh
, "wunpckelsh", WUNPCKELSH
)
2227 IWMMXT_BUILTIN (iwmmxt_wunpckelsw
, "wunpckelsw", WUNPCKELSW
)
2228 IWMMXT2_BUILTIN (iwmmxt_wabsv8qi3
, "wabsb", WABSB
)
2229 IWMMXT2_BUILTIN (iwmmxt_wabsv4hi3
, "wabsh", WABSH
)
2230 IWMMXT2_BUILTIN (iwmmxt_wabsv2si3
, "wabsw", WABSW
)
2231 IWMMXT_BUILTIN (tbcstv8qi
, "tbcstb", TBCSTB
)
2232 IWMMXT_BUILTIN (tbcstv4hi
, "tbcsth", TBCSTH
)
2233 IWMMXT_BUILTIN (tbcstv2si
, "tbcstw", TBCSTW
)
2235 #define CRYPTO1(L, U, R, A) CRYPTO_BUILTIN (L, U)
2236 #define CRYPTO2(L, U, R, A1, A2)
2237 #define CRYPTO3(L, U, R, A1, A2, A3)
2238 #include "crypto.def"
2244 static const struct builtin_description bdesc_3arg
[] =
2246 #define CRYPTO3(L, U, R, A1, A2, A3) CRYPTO_BUILTIN (L, U)
2247 #define CRYPTO1(L, U, R, A)
2248 #define CRYPTO2(L, U, R, A1, A2)
2249 #include "crypto.def"
2254 #undef CRYPTO_BUILTIN
2256 /* Set up all the iWMMXt builtins. This is not called if
2257 TARGET_IWMMXT is zero. */
2260 arm_init_iwmmxt_builtins (void)
2262 const struct builtin_description
* d
;
2265 tree V2SI_type_node
= build_vector_type_for_mode (intSI_type_node
, V2SImode
);
2266 tree V4HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V4HImode
);
2267 tree V8QI_type_node
= build_vector_type_for_mode (intQI_type_node
, V8QImode
);
2269 tree v8qi_ftype_v8qi_v8qi_int
2270 = build_function_type_list (V8QI_type_node
,
2271 V8QI_type_node
, V8QI_type_node
,
2272 integer_type_node
, NULL_TREE
);
2273 tree v4hi_ftype_v4hi_int
2274 = build_function_type_list (V4HI_type_node
,
2275 V4HI_type_node
, integer_type_node
, NULL_TREE
);
2276 tree v2si_ftype_v2si_int
2277 = build_function_type_list (V2SI_type_node
,
2278 V2SI_type_node
, integer_type_node
, NULL_TREE
);
2279 tree v2si_ftype_di_di
2280 = build_function_type_list (V2SI_type_node
,
2281 long_long_integer_type_node
,
2282 long_long_integer_type_node
,
2284 tree di_ftype_di_int
2285 = build_function_type_list (long_long_integer_type_node
,
2286 long_long_integer_type_node
,
2287 integer_type_node
, NULL_TREE
);
2288 tree di_ftype_di_int_int
2289 = build_function_type_list (long_long_integer_type_node
,
2290 long_long_integer_type_node
,
2292 integer_type_node
, NULL_TREE
);
2294 = build_function_type_list (integer_type_node
,
2295 V8QI_type_node
, NULL_TREE
);
2297 = build_function_type_list (integer_type_node
,
2298 V4HI_type_node
, NULL_TREE
);
2300 = build_function_type_list (integer_type_node
,
2301 V2SI_type_node
, NULL_TREE
);
2302 tree int_ftype_v8qi_int
2303 = build_function_type_list (integer_type_node
,
2304 V8QI_type_node
, integer_type_node
, NULL_TREE
);
2305 tree int_ftype_v4hi_int
2306 = build_function_type_list (integer_type_node
,
2307 V4HI_type_node
, integer_type_node
, NULL_TREE
);
2308 tree int_ftype_v2si_int
2309 = build_function_type_list (integer_type_node
,
2310 V2SI_type_node
, integer_type_node
, NULL_TREE
);
2311 tree v8qi_ftype_v8qi_int_int
2312 = build_function_type_list (V8QI_type_node
,
2313 V8QI_type_node
, integer_type_node
,
2314 integer_type_node
, NULL_TREE
);
2315 tree v4hi_ftype_v4hi_int_int
2316 = build_function_type_list (V4HI_type_node
,
2317 V4HI_type_node
, integer_type_node
,
2318 integer_type_node
, NULL_TREE
);
2319 tree v2si_ftype_v2si_int_int
2320 = build_function_type_list (V2SI_type_node
,
2321 V2SI_type_node
, integer_type_node
,
2322 integer_type_node
, NULL_TREE
);
2323 /* Miscellaneous. */
2324 tree v8qi_ftype_v4hi_v4hi
2325 = build_function_type_list (V8QI_type_node
,
2326 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
2327 tree v4hi_ftype_v2si_v2si
2328 = build_function_type_list (V4HI_type_node
,
2329 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
2330 tree v8qi_ftype_v4hi_v8qi
2331 = build_function_type_list (V8QI_type_node
,
2332 V4HI_type_node
, V8QI_type_node
, NULL_TREE
);
2333 tree v2si_ftype_v4hi_v4hi
2334 = build_function_type_list (V2SI_type_node
,
2335 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
2336 tree v2si_ftype_v8qi_v8qi
2337 = build_function_type_list (V2SI_type_node
,
2338 V8QI_type_node
, V8QI_type_node
, NULL_TREE
);
2339 tree v4hi_ftype_v4hi_di
2340 = build_function_type_list (V4HI_type_node
,
2341 V4HI_type_node
, long_long_integer_type_node
,
2343 tree v2si_ftype_v2si_di
2344 = build_function_type_list (V2SI_type_node
,
2345 V2SI_type_node
, long_long_integer_type_node
,
2348 = build_function_type_list (long_long_unsigned_type_node
, NULL_TREE
);
2350 = build_function_type_list (integer_type_node
, NULL_TREE
);
2352 = build_function_type_list (long_long_integer_type_node
,
2353 V8QI_type_node
, NULL_TREE
);
2355 = build_function_type_list (long_long_integer_type_node
,
2356 V4HI_type_node
, NULL_TREE
);
2358 = build_function_type_list (long_long_integer_type_node
,
2359 V2SI_type_node
, NULL_TREE
);
2360 tree v2si_ftype_v4hi
2361 = build_function_type_list (V2SI_type_node
,
2362 V4HI_type_node
, NULL_TREE
);
2363 tree v4hi_ftype_v8qi
2364 = build_function_type_list (V4HI_type_node
,
2365 V8QI_type_node
, NULL_TREE
);
2366 tree v8qi_ftype_v8qi
2367 = build_function_type_list (V8QI_type_node
,
2368 V8QI_type_node
, NULL_TREE
);
2369 tree v4hi_ftype_v4hi
2370 = build_function_type_list (V4HI_type_node
,
2371 V4HI_type_node
, NULL_TREE
);
2372 tree v2si_ftype_v2si
2373 = build_function_type_list (V2SI_type_node
,
2374 V2SI_type_node
, NULL_TREE
);
2376 tree di_ftype_di_v4hi_v4hi
2377 = build_function_type_list (long_long_unsigned_type_node
,
2378 long_long_unsigned_type_node
,
2379 V4HI_type_node
, V4HI_type_node
,
2382 tree di_ftype_v4hi_v4hi
2383 = build_function_type_list (long_long_unsigned_type_node
,
2384 V4HI_type_node
,V4HI_type_node
,
2387 tree v2si_ftype_v2si_v4hi_v4hi
2388 = build_function_type_list (V2SI_type_node
,
2389 V2SI_type_node
, V4HI_type_node
,
2390 V4HI_type_node
, NULL_TREE
);
2392 tree v2si_ftype_v2si_v8qi_v8qi
2393 = build_function_type_list (V2SI_type_node
,
2394 V2SI_type_node
, V8QI_type_node
,
2395 V8QI_type_node
, NULL_TREE
);
2397 tree di_ftype_di_v2si_v2si
2398 = build_function_type_list (long_long_unsigned_type_node
,
2399 long_long_unsigned_type_node
,
2400 V2SI_type_node
, V2SI_type_node
,
2403 tree di_ftype_di_di_int
2404 = build_function_type_list (long_long_unsigned_type_node
,
2405 long_long_unsigned_type_node
,
2406 long_long_unsigned_type_node
,
2407 integer_type_node
, NULL_TREE
);
2410 = build_function_type_list (void_type_node
,
2411 integer_type_node
, NULL_TREE
);
2413 tree v8qi_ftype_char
2414 = build_function_type_list (V8QI_type_node
,
2415 signed_char_type_node
, NULL_TREE
);
2417 tree v4hi_ftype_short
2418 = build_function_type_list (V4HI_type_node
,
2419 short_integer_type_node
, NULL_TREE
);
2422 = build_function_type_list (V2SI_type_node
,
2423 integer_type_node
, NULL_TREE
);
2425 /* Normal vector binops. */
2426 tree v8qi_ftype_v8qi_v8qi
2427 = build_function_type_list (V8QI_type_node
,
2428 V8QI_type_node
, V8QI_type_node
, NULL_TREE
);
2429 tree v4hi_ftype_v4hi_v4hi
2430 = build_function_type_list (V4HI_type_node
,
2431 V4HI_type_node
,V4HI_type_node
, NULL_TREE
);
2432 tree v2si_ftype_v2si_v2si
2433 = build_function_type_list (V2SI_type_node
,
2434 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
2436 = build_function_type_list (long_long_unsigned_type_node
,
2437 long_long_unsigned_type_node
,
2438 long_long_unsigned_type_node
,
2441 /* Add all builtins that are more or less simple operations on two
2443 for (i
= 0, d
= bdesc_2arg
; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
2445 /* Use one of the operands; the target can have a different mode for
2446 mask-generating compares. */
2451 || !(d
->feature
== isa_bit_iwmmxt
2452 || d
->feature
== isa_bit_iwmmxt2
))
2455 mode
= insn_data
[d
->icode
].operand
[1].mode
;
2460 type
= v8qi_ftype_v8qi_v8qi
;
2463 type
= v4hi_ftype_v4hi_v4hi
;
2466 type
= v2si_ftype_v2si_v2si
;
2469 type
= di_ftype_di_di
;
2476 def_mbuiltin (d
->feature
, d
->name
, type
, d
->code
);
2479 /* Add the remaining MMX insns with somewhat more complicated types. */
2480 #define iwmmx_mbuiltin(NAME, TYPE, CODE) \
2481 def_mbuiltin (isa_bit_iwmmxt, "__builtin_arm_" NAME, \
2482 (TYPE), ARM_BUILTIN_ ## CODE)
2484 #define iwmmx2_mbuiltin(NAME, TYPE, CODE) \
2485 def_mbuiltin (isa_bit_iwmmxt2, "__builtin_arm_" NAME, \
2486 (TYPE), ARM_BUILTIN_ ## CODE)
2488 iwmmx_mbuiltin ("wzero", di_ftype_void
, WZERO
);
2489 iwmmx_mbuiltin ("setwcgr0", void_ftype_int
, SETWCGR0
);
2490 iwmmx_mbuiltin ("setwcgr1", void_ftype_int
, SETWCGR1
);
2491 iwmmx_mbuiltin ("setwcgr2", void_ftype_int
, SETWCGR2
);
2492 iwmmx_mbuiltin ("setwcgr3", void_ftype_int
, SETWCGR3
);
2493 iwmmx_mbuiltin ("getwcgr0", int_ftype_void
, GETWCGR0
);
2494 iwmmx_mbuiltin ("getwcgr1", int_ftype_void
, GETWCGR1
);
2495 iwmmx_mbuiltin ("getwcgr2", int_ftype_void
, GETWCGR2
);
2496 iwmmx_mbuiltin ("getwcgr3", int_ftype_void
, GETWCGR3
);
2498 iwmmx_mbuiltin ("wsllh", v4hi_ftype_v4hi_di
, WSLLH
);
2499 iwmmx_mbuiltin ("wsllw", v2si_ftype_v2si_di
, WSLLW
);
2500 iwmmx_mbuiltin ("wslld", di_ftype_di_di
, WSLLD
);
2501 iwmmx_mbuiltin ("wsllhi", v4hi_ftype_v4hi_int
, WSLLHI
);
2502 iwmmx_mbuiltin ("wsllwi", v2si_ftype_v2si_int
, WSLLWI
);
2503 iwmmx_mbuiltin ("wslldi", di_ftype_di_int
, WSLLDI
);
2505 iwmmx_mbuiltin ("wsrlh", v4hi_ftype_v4hi_di
, WSRLH
);
2506 iwmmx_mbuiltin ("wsrlw", v2si_ftype_v2si_di
, WSRLW
);
2507 iwmmx_mbuiltin ("wsrld", di_ftype_di_di
, WSRLD
);
2508 iwmmx_mbuiltin ("wsrlhi", v4hi_ftype_v4hi_int
, WSRLHI
);
2509 iwmmx_mbuiltin ("wsrlwi", v2si_ftype_v2si_int
, WSRLWI
);
2510 iwmmx_mbuiltin ("wsrldi", di_ftype_di_int
, WSRLDI
);
2512 iwmmx_mbuiltin ("wsrah", v4hi_ftype_v4hi_di
, WSRAH
);
2513 iwmmx_mbuiltin ("wsraw", v2si_ftype_v2si_di
, WSRAW
);
2514 iwmmx_mbuiltin ("wsrad", di_ftype_di_di
, WSRAD
);
2515 iwmmx_mbuiltin ("wsrahi", v4hi_ftype_v4hi_int
, WSRAHI
);
2516 iwmmx_mbuiltin ("wsrawi", v2si_ftype_v2si_int
, WSRAWI
);
2517 iwmmx_mbuiltin ("wsradi", di_ftype_di_int
, WSRADI
);
2519 iwmmx_mbuiltin ("wrorh", v4hi_ftype_v4hi_di
, WRORH
);
2520 iwmmx_mbuiltin ("wrorw", v2si_ftype_v2si_di
, WRORW
);
2521 iwmmx_mbuiltin ("wrord", di_ftype_di_di
, WRORD
);
2522 iwmmx_mbuiltin ("wrorhi", v4hi_ftype_v4hi_int
, WRORHI
);
2523 iwmmx_mbuiltin ("wrorwi", v2si_ftype_v2si_int
, WRORWI
);
2524 iwmmx_mbuiltin ("wrordi", di_ftype_di_int
, WRORDI
);
2526 iwmmx_mbuiltin ("wshufh", v4hi_ftype_v4hi_int
, WSHUFH
);
2528 iwmmx_mbuiltin ("wsadb", v2si_ftype_v2si_v8qi_v8qi
, WSADB
);
2529 iwmmx_mbuiltin ("wsadh", v2si_ftype_v2si_v4hi_v4hi
, WSADH
);
2530 iwmmx_mbuiltin ("wmadds", v2si_ftype_v4hi_v4hi
, WMADDS
);
2531 iwmmx2_mbuiltin ("wmaddsx", v2si_ftype_v4hi_v4hi
, WMADDSX
);
2532 iwmmx2_mbuiltin ("wmaddsn", v2si_ftype_v4hi_v4hi
, WMADDSN
);
2533 iwmmx_mbuiltin ("wmaddu", v2si_ftype_v4hi_v4hi
, WMADDU
);
2534 iwmmx2_mbuiltin ("wmaddux", v2si_ftype_v4hi_v4hi
, WMADDUX
);
2535 iwmmx2_mbuiltin ("wmaddun", v2si_ftype_v4hi_v4hi
, WMADDUN
);
2536 iwmmx_mbuiltin ("wsadbz", v2si_ftype_v8qi_v8qi
, WSADBZ
);
2537 iwmmx_mbuiltin ("wsadhz", v2si_ftype_v4hi_v4hi
, WSADHZ
);
2539 iwmmx_mbuiltin ("textrmsb", int_ftype_v8qi_int
, TEXTRMSB
);
2540 iwmmx_mbuiltin ("textrmsh", int_ftype_v4hi_int
, TEXTRMSH
);
2541 iwmmx_mbuiltin ("textrmsw", int_ftype_v2si_int
, TEXTRMSW
);
2542 iwmmx_mbuiltin ("textrmub", int_ftype_v8qi_int
, TEXTRMUB
);
2543 iwmmx_mbuiltin ("textrmuh", int_ftype_v4hi_int
, TEXTRMUH
);
2544 iwmmx_mbuiltin ("textrmuw", int_ftype_v2si_int
, TEXTRMUW
);
2545 iwmmx_mbuiltin ("tinsrb", v8qi_ftype_v8qi_int_int
, TINSRB
);
2546 iwmmx_mbuiltin ("tinsrh", v4hi_ftype_v4hi_int_int
, TINSRH
);
2547 iwmmx_mbuiltin ("tinsrw", v2si_ftype_v2si_int_int
, TINSRW
);
2549 iwmmx_mbuiltin ("waccb", di_ftype_v8qi
, WACCB
);
2550 iwmmx_mbuiltin ("wacch", di_ftype_v4hi
, WACCH
);
2551 iwmmx_mbuiltin ("waccw", di_ftype_v2si
, WACCW
);
2553 iwmmx_mbuiltin ("tmovmskb", int_ftype_v8qi
, TMOVMSKB
);
2554 iwmmx_mbuiltin ("tmovmskh", int_ftype_v4hi
, TMOVMSKH
);
2555 iwmmx_mbuiltin ("tmovmskw", int_ftype_v2si
, TMOVMSKW
);
2557 iwmmx2_mbuiltin ("waddbhusm", v8qi_ftype_v4hi_v8qi
, WADDBHUSM
);
2558 iwmmx2_mbuiltin ("waddbhusl", v8qi_ftype_v4hi_v8qi
, WADDBHUSL
);
2560 iwmmx_mbuiltin ("wpackhss", v8qi_ftype_v4hi_v4hi
, WPACKHSS
);
2561 iwmmx_mbuiltin ("wpackhus", v8qi_ftype_v4hi_v4hi
, WPACKHUS
);
2562 iwmmx_mbuiltin ("wpackwus", v4hi_ftype_v2si_v2si
, WPACKWUS
);
2563 iwmmx_mbuiltin ("wpackwss", v4hi_ftype_v2si_v2si
, WPACKWSS
);
2564 iwmmx_mbuiltin ("wpackdus", v2si_ftype_di_di
, WPACKDUS
);
2565 iwmmx_mbuiltin ("wpackdss", v2si_ftype_di_di
, WPACKDSS
);
2567 iwmmx_mbuiltin ("wunpckehub", v4hi_ftype_v8qi
, WUNPCKEHUB
);
2568 iwmmx_mbuiltin ("wunpckehuh", v2si_ftype_v4hi
, WUNPCKEHUH
);
2569 iwmmx_mbuiltin ("wunpckehuw", di_ftype_v2si
, WUNPCKEHUW
);
2570 iwmmx_mbuiltin ("wunpckehsb", v4hi_ftype_v8qi
, WUNPCKEHSB
);
2571 iwmmx_mbuiltin ("wunpckehsh", v2si_ftype_v4hi
, WUNPCKEHSH
);
2572 iwmmx_mbuiltin ("wunpckehsw", di_ftype_v2si
, WUNPCKEHSW
);
2573 iwmmx_mbuiltin ("wunpckelub", v4hi_ftype_v8qi
, WUNPCKELUB
);
2574 iwmmx_mbuiltin ("wunpckeluh", v2si_ftype_v4hi
, WUNPCKELUH
);
2575 iwmmx_mbuiltin ("wunpckeluw", di_ftype_v2si
, WUNPCKELUW
);
2576 iwmmx_mbuiltin ("wunpckelsb", v4hi_ftype_v8qi
, WUNPCKELSB
);
2577 iwmmx_mbuiltin ("wunpckelsh", v2si_ftype_v4hi
, WUNPCKELSH
);
2578 iwmmx_mbuiltin ("wunpckelsw", di_ftype_v2si
, WUNPCKELSW
);
2580 iwmmx_mbuiltin ("wmacs", di_ftype_di_v4hi_v4hi
, WMACS
);
2581 iwmmx_mbuiltin ("wmacsz", di_ftype_v4hi_v4hi
, WMACSZ
);
2582 iwmmx_mbuiltin ("wmacu", di_ftype_di_v4hi_v4hi
, WMACU
);
2583 iwmmx_mbuiltin ("wmacuz", di_ftype_v4hi_v4hi
, WMACUZ
);
2585 iwmmx_mbuiltin ("walign", v8qi_ftype_v8qi_v8qi_int
, WALIGNI
);
2586 iwmmx_mbuiltin ("tmia", di_ftype_di_int_int
, TMIA
);
2587 iwmmx_mbuiltin ("tmiaph", di_ftype_di_int_int
, TMIAPH
);
2588 iwmmx_mbuiltin ("tmiabb", di_ftype_di_int_int
, TMIABB
);
2589 iwmmx_mbuiltin ("tmiabt", di_ftype_di_int_int
, TMIABT
);
2590 iwmmx_mbuiltin ("tmiatb", di_ftype_di_int_int
, TMIATB
);
2591 iwmmx_mbuiltin ("tmiatt", di_ftype_di_int_int
, TMIATT
);
2593 iwmmx2_mbuiltin ("wabsb", v8qi_ftype_v8qi
, WABSB
);
2594 iwmmx2_mbuiltin ("wabsh", v4hi_ftype_v4hi
, WABSH
);
2595 iwmmx2_mbuiltin ("wabsw", v2si_ftype_v2si
, WABSW
);
2597 iwmmx2_mbuiltin ("wqmiabb", v2si_ftype_v2si_v4hi_v4hi
, WQMIABB
);
2598 iwmmx2_mbuiltin ("wqmiabt", v2si_ftype_v2si_v4hi_v4hi
, WQMIABT
);
2599 iwmmx2_mbuiltin ("wqmiatb", v2si_ftype_v2si_v4hi_v4hi
, WQMIATB
);
2600 iwmmx2_mbuiltin ("wqmiatt", v2si_ftype_v2si_v4hi_v4hi
, WQMIATT
);
2602 iwmmx2_mbuiltin ("wqmiabbn", v2si_ftype_v2si_v4hi_v4hi
, WQMIABBN
);
2603 iwmmx2_mbuiltin ("wqmiabtn", v2si_ftype_v2si_v4hi_v4hi
, WQMIABTN
);
2604 iwmmx2_mbuiltin ("wqmiatbn", v2si_ftype_v2si_v4hi_v4hi
, WQMIATBN
);
2605 iwmmx2_mbuiltin ("wqmiattn", v2si_ftype_v2si_v4hi_v4hi
, WQMIATTN
);
2607 iwmmx2_mbuiltin ("wmiabb", di_ftype_di_v4hi_v4hi
, WMIABB
);
2608 iwmmx2_mbuiltin ("wmiabt", di_ftype_di_v4hi_v4hi
, WMIABT
);
2609 iwmmx2_mbuiltin ("wmiatb", di_ftype_di_v4hi_v4hi
, WMIATB
);
2610 iwmmx2_mbuiltin ("wmiatt", di_ftype_di_v4hi_v4hi
, WMIATT
);
2612 iwmmx2_mbuiltin ("wmiabbn", di_ftype_di_v4hi_v4hi
, WMIABBN
);
2613 iwmmx2_mbuiltin ("wmiabtn", di_ftype_di_v4hi_v4hi
, WMIABTN
);
2614 iwmmx2_mbuiltin ("wmiatbn", di_ftype_di_v4hi_v4hi
, WMIATBN
);
2615 iwmmx2_mbuiltin ("wmiattn", di_ftype_di_v4hi_v4hi
, WMIATTN
);
2617 iwmmx2_mbuiltin ("wmiawbb", di_ftype_di_v2si_v2si
, WMIAWBB
);
2618 iwmmx2_mbuiltin ("wmiawbt", di_ftype_di_v2si_v2si
, WMIAWBT
);
2619 iwmmx2_mbuiltin ("wmiawtb", di_ftype_di_v2si_v2si
, WMIAWTB
);
2620 iwmmx2_mbuiltin ("wmiawtt", di_ftype_di_v2si_v2si
, WMIAWTT
);
2622 iwmmx2_mbuiltin ("wmiawbbn", di_ftype_di_v2si_v2si
, WMIAWBBN
);
2623 iwmmx2_mbuiltin ("wmiawbtn", di_ftype_di_v2si_v2si
, WMIAWBTN
);
2624 iwmmx2_mbuiltin ("wmiawtbn", di_ftype_di_v2si_v2si
, WMIAWTBN
);
2625 iwmmx2_mbuiltin ("wmiawttn", di_ftype_di_v2si_v2si
, WMIAWTTN
);
2627 iwmmx2_mbuiltin ("wmerge", di_ftype_di_di_int
, WMERGE
);
2629 iwmmx_mbuiltin ("tbcstb", v8qi_ftype_char
, TBCSTB
);
2630 iwmmx_mbuiltin ("tbcsth", v4hi_ftype_short
, TBCSTH
);
2631 iwmmx_mbuiltin ("tbcstw", v2si_ftype_int
, TBCSTW
);
2633 #undef iwmmx_mbuiltin
2634 #undef iwmmx2_mbuiltin
2638 arm_init_fp16_builtins (void)
2640 arm_fp16_type_node
= make_node (REAL_TYPE
);
2641 TYPE_PRECISION (arm_fp16_type_node
) = GET_MODE_PRECISION (HFmode
);
2642 layout_type (arm_fp16_type_node
);
2643 if (arm_fp16_format
)
2644 (*lang_hooks
.types
.register_builtin_type
) (arm_fp16_type_node
,
2649 arm_init_builtins (void)
2651 if (TARGET_REALLY_IWMMXT
)
2652 arm_init_iwmmxt_builtins ();
2654 /* This creates the arm_simd_floatHF_type_node so must come before
2655 arm_init_neon_builtins which uses it. */
2656 arm_init_fp16_builtins ();
2658 arm_init_bf16_types ();
2660 if (TARGET_MAYBE_HARD_FLOAT
)
2662 tree lane_check_fpr
= build_function_type_list (void_type_node
,
2666 arm_builtin_decls
[ARM_BUILTIN_SIMD_LANE_CHECK
]
2667 = add_builtin_function ("__builtin_arm_lane_check", lane_check_fpr
,
2668 ARM_BUILTIN_SIMD_LANE_CHECK
, BUILT_IN_MD
,
2670 if (TARGET_HAVE_MVE
)
2671 arm_init_mve_builtins ();
2673 arm_init_neon_builtins ();
2674 arm_init_vfp_builtins ();
2675 arm_init_crypto_builtins ();
2679 arm_init_cde_builtins ();
2681 arm_init_acle_builtins ();
2683 if (TARGET_MAYBE_HARD_FLOAT
)
2685 tree ftype_set_fpscr
2686 = build_function_type_list (void_type_node
, unsigned_type_node
, NULL
);
2687 tree ftype_get_fpscr
2688 = build_function_type_list (unsigned_type_node
, NULL
);
2690 arm_builtin_decls
[ARM_BUILTIN_GET_FPSCR
]
2691 = add_builtin_function ("__builtin_arm_get_fpscr", ftype_get_fpscr
,
2692 ARM_BUILTIN_GET_FPSCR
, BUILT_IN_MD
, NULL
, NULL_TREE
);
2693 arm_builtin_decls
[ARM_BUILTIN_SET_FPSCR
]
2694 = add_builtin_function ("__builtin_arm_set_fpscr", ftype_set_fpscr
,
2695 ARM_BUILTIN_SET_FPSCR
, BUILT_IN_MD
, NULL
, NULL_TREE
);
2700 tree ftype_cmse_nonsecure_caller
2701 = build_function_type_list (unsigned_type_node
, NULL
);
2702 arm_builtin_decls
[ARM_BUILTIN_CMSE_NONSECURE_CALLER
]
2703 = add_builtin_function ("__builtin_arm_cmse_nonsecure_caller",
2704 ftype_cmse_nonsecure_caller
,
2705 ARM_BUILTIN_CMSE_NONSECURE_CALLER
, BUILT_IN_MD
,
2710 /* Return the ARM builtin for CODE. */
2713 arm_builtin_decl (unsigned code
, bool initialize_p ATTRIBUTE_UNUSED
)
2715 if (code
>= ARM_BUILTIN_MAX
)
2716 return error_mark_node
;
2718 return arm_builtin_decls
[code
];
2721 /* Errors in the source file can cause expand_expr to return const0_rtx
2722 where we expect a vector. To avoid crashing, use one of the vector
2723 clear instructions. */
2726 safe_vector_operand (rtx x
, machine_mode mode
)
2728 if (x
!= const0_rtx
)
2730 x
= gen_reg_rtx (mode
);
2732 emit_insn (gen_iwmmxt_clrdi (mode
== DImode
? x
2733 : gen_rtx_SUBREG (DImode
, x
, 0)));
2737 /* Function to expand ternary builtins. */
2739 arm_expand_ternop_builtin (enum insn_code icode
,
2740 tree exp
, rtx target
)
2743 tree arg0
= CALL_EXPR_ARG (exp
, 0);
2744 tree arg1
= CALL_EXPR_ARG (exp
, 1);
2745 tree arg2
= CALL_EXPR_ARG (exp
, 2);
2747 rtx op0
= expand_normal (arg0
);
2748 rtx op1
= expand_normal (arg1
);
2749 rtx op2
= expand_normal (arg2
);
2751 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
2752 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2753 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
2754 machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
2756 if (VECTOR_MODE_P (mode0
))
2757 op0
= safe_vector_operand (op0
, mode0
);
2758 if (VECTOR_MODE_P (mode1
))
2759 op1
= safe_vector_operand (op1
, mode1
);
2760 if (VECTOR_MODE_P (mode2
))
2761 op2
= safe_vector_operand (op2
, mode2
);
2764 || GET_MODE (target
) != tmode
2765 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2766 target
= gen_reg_rtx (tmode
);
2768 gcc_assert ((GET_MODE (op0
) == mode0
|| GET_MODE (op0
) == VOIDmode
)
2769 && (GET_MODE (op1
) == mode1
|| GET_MODE (op1
) == VOIDmode
)
2770 && (GET_MODE (op2
) == mode2
|| GET_MODE (op2
) == VOIDmode
));
2772 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2773 op0
= copy_to_mode_reg (mode0
, op0
);
2774 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2775 op1
= copy_to_mode_reg (mode1
, op1
);
2776 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
2777 op2
= copy_to_mode_reg (mode2
, op2
);
2779 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
2786 /* Subroutine of arm_expand_builtin to take care of binop insns. */
2789 arm_expand_binop_builtin (enum insn_code icode
,
2790 tree exp
, rtx target
)
2793 tree arg0
= CALL_EXPR_ARG (exp
, 0);
2794 tree arg1
= CALL_EXPR_ARG (exp
, 1);
2795 rtx op0
= expand_normal (arg0
);
2796 rtx op1
= expand_normal (arg1
);
2797 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
2798 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2799 machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
2801 if (VECTOR_MODE_P (mode0
))
2802 op0
= safe_vector_operand (op0
, mode0
);
2803 if (VECTOR_MODE_P (mode1
))
2804 op1
= safe_vector_operand (op1
, mode1
);
2807 || GET_MODE (target
) != tmode
2808 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2809 target
= gen_reg_rtx (tmode
);
2811 gcc_assert ((GET_MODE (op0
) == mode0
|| GET_MODE (op0
) == VOIDmode
)
2812 && (GET_MODE (op1
) == mode1
|| GET_MODE (op1
) == VOIDmode
));
2814 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2815 op0
= copy_to_mode_reg (mode0
, op0
);
2816 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
2817 op1
= copy_to_mode_reg (mode1
, op1
);
2819 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
2826 /* Subroutine of arm_expand_builtin to take care of unop insns. */
2829 arm_expand_unop_builtin (enum insn_code icode
,
2830 tree exp
, rtx target
, int do_load
)
2833 tree arg0
= CALL_EXPR_ARG (exp
, 0);
2834 rtx op0
= expand_normal (arg0
);
2835 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
2836 machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2839 || GET_MODE (target
) != tmode
2840 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
2841 target
= gen_reg_rtx (tmode
);
2843 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
2846 if (VECTOR_MODE_P (mode0
))
2847 op0
= safe_vector_operand (op0
, mode0
);
2849 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2850 op0
= copy_to_mode_reg (mode0
, op0
);
2853 pat
= GEN_FCN (icode
) (target
, op0
);
2862 ARG_BUILTIN_COPY_TO_REG
,
2863 ARG_BUILTIN_CONSTANT
,
2864 ARG_BUILTIN_LANE_INDEX
,
2865 ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX
,
2866 ARG_BUILTIN_LANE_PAIR_INDEX
,
2867 ARG_BUILTIN_LANE_QUADTUP_INDEX
,
2868 ARG_BUILTIN_NEON_MEMORY
,
2874 /* EXP is a pointer argument to a Neon load or store intrinsic. Derive
2875 and return an expression for the accessed memory.
2877 The intrinsic function operates on a block of registers that has
2878 mode REG_MODE. This block contains vectors of type TYPE_MODE. The
2879 function references the memory at EXP of type TYPE and in mode
2880 MEM_MODE; this mode may be BLKmode if no more suitable mode is
2884 neon_dereference_pointer (tree exp
, tree type
, machine_mode mem_mode
,
2885 machine_mode reg_mode
,
2886 machine_mode vector_mode
)
2888 HOST_WIDE_INT reg_size
, vector_size
, nvectors
, nelems
;
2889 tree elem_type
, upper_bound
, array_type
;
2891 /* Work out the size of the register block in bytes. */
2892 reg_size
= GET_MODE_SIZE (reg_mode
);
2894 /* Work out the size of each vector in bytes. */
2895 vector_size
= GET_MODE_SIZE (vector_mode
);
2897 /* Work out how many vectors there are. */
2898 gcc_assert (reg_size
% vector_size
== 0);
2899 nvectors
= reg_size
/ vector_size
;
2901 /* Work out the type of each element. */
2902 gcc_assert (POINTER_TYPE_P (type
));
2903 elem_type
= TREE_TYPE (type
);
2905 /* Work out how many elements are being loaded or stored.
2906 MEM_MODE == REG_MODE implies a one-to-one mapping between register
2907 and memory elements; anything else implies a lane load or store. */
2908 if (mem_mode
== reg_mode
)
2909 nelems
= vector_size
* nvectors
/ int_size_in_bytes (elem_type
);
2913 /* Create a type that describes the full access. */
2914 upper_bound
= build_int_cst (size_type_node
, nelems
- 1);
2915 array_type
= build_array_type (elem_type
, build_index_type (upper_bound
));
2917 /* Dereference EXP using that type. */
2918 return fold_build2 (MEM_REF
, array_type
, exp
,
2919 build_int_cst (build_pointer_type (array_type
), 0));
2922 /* EXP is a pointer argument to a vector scatter store intrinsics.
2924 Consider the following example:
2925 VSTRW<v>.<dt> Qd, [Qm{, #+/-<imm>}]!
2926 When <Qm> used as the base register for the target address,
2927 this function is used to derive and return an expression for the
2930 The intrinsic function operates on a block of registers that has mode
2931 REG_MODE. This block contains vectors of type TYPE_MODE. The function
2932 references the memory at EXP of type TYPE and in mode MEM_MODE. This
2933 mode may be BLKmode if no more suitable mode is available. */
2936 mve_dereference_pointer (tree exp
, tree type
, machine_mode reg_mode
,
2937 machine_mode vector_mode
)
2939 HOST_WIDE_INT reg_size
, vector_size
, nelems
;
2940 tree elem_type
, upper_bound
, array_type
;
2942 /* Work out the size of each vector in bytes. */
2943 vector_size
= GET_MODE_SIZE (vector_mode
);
2945 /* Work out the size of the register block in bytes. */
2946 reg_size
= GET_MODE_SIZE (reg_mode
);
2948 /* Work out the type of each element. */
2949 gcc_assert (POINTER_TYPE_P (type
));
2950 elem_type
= TREE_TYPE (type
);
2952 nelems
= reg_size
/ vector_size
;
2954 /* Create a type that describes the full access. */
2955 upper_bound
= build_int_cst (size_type_node
, nelems
- 1);
2956 array_type
= build_array_type (elem_type
, build_index_type (upper_bound
));
2958 /* Dereference EXP using that type. */
2959 return fold_build2 (MEM_REF
, array_type
, exp
,
2960 build_int_cst (build_pointer_type (array_type
), 0));
2963 /* Expand a builtin. */
2965 arm_expand_builtin_args (rtx target
, machine_mode map_mode
, int fcode
,
2966 int icode
, int have_retval
, tree exp
,
2970 tree arg
[SIMD_MAX_BUILTIN_ARGS
];
2971 rtx op
[SIMD_MAX_BUILTIN_ARGS
];
2972 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
2973 machine_mode mode
[SIMD_MAX_BUILTIN_ARGS
];
2980 || GET_MODE (target
) != tmode
2981 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
)))
2982 target
= gen_reg_rtx (tmode
);
2984 formals
= TYPE_ARG_TYPES (TREE_TYPE (arm_builtin_decls
[fcode
]));
2988 builtin_arg thisarg
= args
[argc
];
2990 if (thisarg
== ARG_BUILTIN_STOP
)
2994 int opno
= argc
+ have_retval
;
2995 arg
[argc
] = CALL_EXPR_ARG (exp
, argc
);
2996 mode
[argc
] = insn_data
[icode
].operand
[opno
].mode
;
2997 if (thisarg
== ARG_BUILTIN_NEON_MEMORY
)
2999 machine_mode other_mode
3000 = insn_data
[icode
].operand
[1 - opno
].mode
;
3001 if (TARGET_HAVE_MVE
&& mode
[argc
] != other_mode
)
3003 arg
[argc
] = mve_dereference_pointer (arg
[argc
],
3004 TREE_VALUE (formals
),
3005 other_mode
, map_mode
);
3008 arg
[argc
] = neon_dereference_pointer (arg
[argc
],
3009 TREE_VALUE (formals
),
3010 mode
[argc
], other_mode
,
3014 /* Use EXPAND_MEMORY for ARG_BUILTIN_MEMORY and
3015 ARG_BUILTIN_NEON_MEMORY to ensure a MEM_P be returned. */
3016 op
[argc
] = expand_expr (arg
[argc
], NULL_RTX
, VOIDmode
,
3017 ((thisarg
== ARG_BUILTIN_MEMORY
3018 || thisarg
== ARG_BUILTIN_NEON_MEMORY
)
3019 ? EXPAND_MEMORY
: EXPAND_NORMAL
));
3023 case ARG_BUILTIN_MEMORY
:
3024 case ARG_BUILTIN_COPY_TO_REG
:
3025 if (POINTER_TYPE_P (TREE_TYPE (arg
[argc
])))
3026 op
[argc
] = convert_memory_address (Pmode
, op
[argc
]);
3027 /*gcc_assert (GET_MODE (op[argc]) == mode[argc]); */
3028 if (!(*insn_data
[icode
].operand
[opno
].predicate
)
3029 (op
[argc
], mode
[argc
]))
3030 op
[argc
] = copy_to_mode_reg (mode
[argc
], op
[argc
]);
3033 case ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX
:
3034 gcc_assert (argc
> 1);
3035 if (CONST_INT_P (op
[argc
]))
3037 neon_lane_bounds (op
[argc
], 0,
3038 GET_MODE_NUNITS (map_mode
), exp
);
3039 /* Keep to GCC-vector-extension lane indices in the RTL. */
3041 GEN_INT (NEON_ENDIAN_LANE_N (map_mode
, INTVAL (op
[argc
])));
3045 case ARG_BUILTIN_LANE_INDEX
:
3046 /* Previous argument must be a vector, which this indexes. */
3047 gcc_assert (argc
> 0);
3048 if (CONST_INT_P (op
[argc
]))
3050 machine_mode vmode
= mode
[argc
- 1];
3051 neon_lane_bounds (op
[argc
], 0, GET_MODE_NUNITS (vmode
), exp
);
3053 /* If the lane index isn't a constant then error out. */
3056 case ARG_BUILTIN_LANE_PAIR_INDEX
:
3057 /* Previous argument must be a vector, which this indexes. The
3058 indexing will always select i and i+1 out of the vector, which
3059 puts a limit on i. */
3060 gcc_assert (argc
> 0);
3061 if (CONST_INT_P (op
[argc
]))
3063 machine_mode vmode
= mode
[argc
- 1];
3064 neon_lane_bounds (op
[argc
], 0,
3065 GET_MODE_NUNITS (vmode
) / 2, exp
);
3067 /* If the lane index isn't a constant then error out. */
3070 case ARG_BUILTIN_LANE_QUADTUP_INDEX
:
3071 /* Previous argument must be a vector, which this indexes. */
3072 gcc_assert (argc
> 0);
3073 if (CONST_INT_P (op
[argc
]))
3075 machine_mode vmode
= mode
[argc
- 1];
3076 neon_lane_bounds (op
[argc
], 0,
3077 GET_MODE_NUNITS (vmode
) / 4, exp
);
3079 /* If the lane index isn't a constant then error out. */
3082 case ARG_BUILTIN_CONSTANT
:
3084 if (!(*insn_data
[icode
].operand
[opno
].predicate
)
3085 (op
[argc
], mode
[argc
]))
3087 if (IN_RANGE (fcode
, ARM_BUILTIN_CDE_PATTERN_START
,
3088 ARM_BUILTIN_CDE_PATTERN_END
))
3092 unsigned int cp_bit
= (CONST_INT_P (op
[argc
])
3093 ? UINTVAL (op
[argc
]) : -1);
3094 if (IN_RANGE (cp_bit
, 0, ARM_CDE_CONST_COPROC
))
3095 error ("%Kcoprocessor %d is not enabled "
3096 "with +cdecp%d", exp
, cp_bit
, cp_bit
);
3098 error ("%Kcoproc must be a constant immediate in "
3099 "range [0-%d] enabled with +cdecp<N>", exp
,
3100 ARM_CDE_CONST_COPROC
);
3103 /* Here we mention the builtin name to follow the same
3104 format that the C/C++ frontends use for referencing
3105 a given argument index. */
3106 error ("%Kargument %d to %qE must be a constant immediate "
3107 "in range [0-%d]", exp
, argc
+ 1,
3108 arm_builtin_decls
[fcode
],
3109 cde_builtin_data
[fcode
-
3110 ARM_BUILTIN_CDE_PATTERN_START
].imm_max
);
3113 error ("%Kargument %d must be a constant immediate",
3115 /* We have failed to expand the pattern, and are safely
3116 in to invalid code. But the mid-end will still try to
3117 build an assignment for this node while it expands,
3118 before stopping for the error, just pass it back
3119 TARGET to ensure a valid assignment. */
3124 case ARG_BUILTIN_NEON_MEMORY
:
3125 /* Check if expand failed. */
3126 if (op
[argc
] == const0_rtx
)
3128 gcc_assert (MEM_P (op
[argc
]));
3129 PUT_MODE (op
[argc
], mode
[argc
]);
3130 /* ??? arm_neon.h uses the same built-in functions for signed
3131 and unsigned accesses, casting where necessary. This isn't
3133 set_mem_alias_set (op
[argc
], 0);
3134 if (!(*insn_data
[icode
].operand
[opno
].predicate
)
3135 (op
[argc
], mode
[argc
]))
3136 op
[argc
] = (replace_equiv_address
3138 copy_to_mode_reg (Pmode
, XEXP (op
[argc
], 0))));
3141 case ARG_BUILTIN_STOP
:
3153 pat
= GEN_FCN (icode
) (target
);
3156 pat
= GEN_FCN (icode
) (target
, op
[0]);
3160 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1]);
3164 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2]);
3168 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3]);
3172 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3], op
[4]);
3176 pat
= GEN_FCN (icode
) (target
, op
[0], op
[1], op
[2], op
[3], op
[4], op
[5]);
3186 pat
= GEN_FCN (icode
) (op
[0]);
3190 pat
= GEN_FCN (icode
) (op
[0], op
[1]);
3194 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2]);
3198 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3]);
3202 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3], op
[4]);
3206 pat
= GEN_FCN (icode
) (op
[0], op
[1], op
[2], op
[3], op
[4], op
[5]);
3216 /* Check whether our current target implements the pattern chosen for this
3217 builtin and error out if not. */
3220 insn
= get_insns ();
3223 if (recog_memoized (insn
) < 0)
3224 error ("this builtin is not supported for this target");
3231 /* Expand a builtin. These builtins are "special" because they don't have
3232 symbolic constants defined per-instruction or per instruction-variant.
3233 Instead, the required info is looked up in the ARM_BUILTIN_DATA record that
3234 is passed into the function. */
3237 arm_expand_builtin_1 (int fcode
, tree exp
, rtx target
,
3238 arm_builtin_datum
*d
)
3240 enum insn_code icode
= d
->code
;
3241 builtin_arg args
[SIMD_MAX_BUILTIN_ARGS
+ 1];
3242 int num_args
= insn_data
[d
->code
].n_operands
;
3248 if (IN_RANGE (fcode
, ARM_BUILTIN_VFP_BASE
, ARM_BUILTIN_ACLE_BASE
- 1))
3251 if (IN_RANGE (fcode
, ARM_BUILTIN_MVE_BASE
, ARM_BUILTIN_MAX
- 1))
3254 is_void
= !!(d
->qualifiers
[0] & qualifier_void
);
3256 num_args
+= is_void
;
3258 for (k
= 1; k
< num_args
; k
++)
3260 /* We have four arrays of data, each indexed in a different fashion.
3261 qualifiers - element 0 always describes the function return type.
3262 operands - element 0 is either the operand for return value (if
3263 the function has a non-void return type) or the operand for the
3265 expr_args - element 0 always holds the first argument.
3266 args - element 0 is always used for the return type. */
3267 int qualifiers_k
= k
;
3268 int operands_k
= k
- is_void
;
3269 int expr_args_k
= k
- 1;
3271 if (d
->qualifiers
[qualifiers_k
] & qualifier_lane_index
)
3272 args
[k
] = ARG_BUILTIN_LANE_INDEX
;
3273 else if (d
->qualifiers
[qualifiers_k
] & qualifier_lane_pair_index
)
3274 args
[k
] = ARG_BUILTIN_LANE_PAIR_INDEX
;
3275 else if (d
->qualifiers
[qualifiers_k
] & qualifier_lane_quadtup_index
)
3276 args
[k
] = ARG_BUILTIN_LANE_QUADTUP_INDEX
;
3277 else if (d
->qualifiers
[qualifiers_k
] & qualifier_struct_load_store_lane_index
)
3278 args
[k
] = ARG_BUILTIN_STRUCT_LOAD_STORE_LANE_INDEX
;
3279 else if (d
->qualifiers
[qualifiers_k
] & qualifier_immediate
)
3280 args
[k
] = ARG_BUILTIN_CONSTANT
;
3281 else if (d
->qualifiers
[qualifiers_k
] & qualifier_maybe_immediate
)
3284 = expand_normal (CALL_EXPR_ARG (exp
,
3286 /* Handle constants only if the predicate allows it. */
3287 bool op_const_int_p
=
3289 && (*insn_data
[icode
].operand
[operands_k
].predicate
)
3290 (arg
, insn_data
[icode
].operand
[operands_k
].mode
));
3291 args
[k
] = op_const_int_p
? ARG_BUILTIN_CONSTANT
: ARG_BUILTIN_COPY_TO_REG
;
3293 else if (d
->qualifiers
[qualifiers_k
] & qualifier_pointer
)
3296 args
[k
] = ARG_BUILTIN_NEON_MEMORY
;
3298 args
[k
] = ARG_BUILTIN_MEMORY
;
3301 args
[k
] = ARG_BUILTIN_COPY_TO_REG
;
3303 args
[k
] = ARG_BUILTIN_STOP
;
3305 /* The interface to arm_expand_builtin_args expects a 0 if
3306 the function is void, and a 1 if it is not. */
3307 return arm_expand_builtin_args
3308 (target
, d
->mode
, fcode
, icode
, !is_void
, exp
,
3312 /* Expand an ACLE builtin, i.e. those registered only if their respective
3313 target constraints are met. This check happens within
3314 arm_expand_builtin_args. */
3317 arm_expand_acle_builtin (int fcode
, tree exp
, rtx target
)
3319 if (fcode
== ARM_BUILTIN_SAT_IMM_CHECK
)
3321 /* Check the saturation immediate bounds. */
3323 rtx min_sat
= expand_normal (CALL_EXPR_ARG (exp
, 1));
3324 rtx max_sat
= expand_normal (CALL_EXPR_ARG (exp
, 2));
3325 gcc_assert (CONST_INT_P (min_sat
));
3326 gcc_assert (CONST_INT_P (max_sat
));
3327 rtx sat_imm
= expand_normal (CALL_EXPR_ARG (exp
, 0));
3328 if (CONST_INT_P (sat_imm
))
3330 if (!IN_RANGE (sat_imm
, min_sat
, max_sat
))
3331 error ("%Ksaturation bit range must be in the range [%wd, %wd]",
3332 exp
, UINTVAL (min_sat
), UINTVAL (max_sat
));
3335 error ("%Ksaturation bit range must be a constant immediate", exp
);
3336 /* Don't generate any RTL. */
3340 gcc_assert (fcode
!= ARM_BUILTIN_CDE_BASE
);
3341 arm_builtin_datum
*d
3342 = (fcode
< ARM_BUILTIN_CDE_BASE
)
3343 ? &acle_builtin_data
[fcode
- ARM_BUILTIN_ACLE_PATTERN_START
]
3344 : &cde_builtin_data
[fcode
- ARM_BUILTIN_CDE_PATTERN_START
].base
;
3346 return arm_expand_builtin_1 (fcode
, exp
, target
, d
);
3349 /* Expand an MVE builtin, i.e. those registered only if their respective target
3350 constraints are met. This check happens within arm_expand_builtin. */
3353 arm_expand_mve_builtin (int fcode
, tree exp
, rtx target
)
3355 if (fcode
>= ARM_BUILTIN_MVE_BASE
&& !TARGET_HAVE_MVE
)
3357 fatal_error (input_location
,
3358 "You must enable MVE instructions"
3359 " to use these intrinsics");
3363 arm_builtin_datum
*d
3364 = &mve_builtin_data
[fcode
- ARM_BUILTIN_MVE_PATTERN_START
];
3366 return arm_expand_builtin_1 (fcode
, exp
, target
, d
);
3369 /* Expand a Neon builtin, i.e. those registered only if TARGET_NEON holds.
3370 Most of these are "special" because they don't have symbolic
3371 constants defined per-instruction or per instruction-variant. Instead, the
3372 required info is looked up in the table neon_builtin_data. */
3375 arm_expand_neon_builtin (int fcode
, tree exp
, rtx target
)
3377 if (fcode
>= ARM_BUILTIN_NEON_BASE
&& ! TARGET_NEON
)
3379 fatal_error (input_location
,
3380 "You must enable NEON instructions"
3381 " (e.g. %<-mfloat-abi=softfp%> %<-mfpu=neon%>)"
3382 " to use these intrinsics.");
3386 arm_builtin_datum
*d
3387 = &neon_builtin_data
[fcode
- ARM_BUILTIN_NEON_PATTERN_START
];
3389 return arm_expand_builtin_1 (fcode
, exp
, target
, d
);
3392 /* Expand a VFP builtin. These builtins are treated like
3393 neon builtins except that the data is looked up in table
3394 VFP_BUILTIN_DATA. */
3397 arm_expand_vfp_builtin (int fcode
, tree exp
, rtx target
)
3399 if (fcode
>= ARM_BUILTIN_VFP_BASE
&& ! TARGET_HARD_FLOAT
)
3401 fatal_error (input_location
,
3402 "You must enable VFP instructions"
3403 " to use these intrinsics.");
3407 arm_builtin_datum
*d
3408 = &vfp_builtin_data
[fcode
- ARM_BUILTIN_VFP_PATTERN_START
];
3410 return arm_expand_builtin_1 (fcode
, exp
, target
, d
);
3413 /* Expand an expression EXP that calls a built-in function,
3414 with result going to TARGET if that's convenient
3415 (and in mode MODE if that's convenient).
3416 SUBTARGET may be used as the target for computing one of EXP's operands.
3417 IGNORE is nonzero if the value is to be ignored. */
3420 arm_expand_builtin (tree exp
,
3422 rtx subtarget ATTRIBUTE_UNUSED
,
3423 machine_mode mode ATTRIBUTE_UNUSED
,
3424 int ignore ATTRIBUTE_UNUSED
)
3426 const struct builtin_description
* d
;
3427 enum insn_code icode
;
3428 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
3436 unsigned int fcode
= DECL_MD_FUNCTION_CODE (fndecl
);
3447 if (fcode
== ARM_BUILTIN_SIMD_LANE_CHECK
)
3449 /* Builtin is only to check bounds of the lane passed to some intrinsics
3450 that are implemented with gcc vector extensions in arm_neon.h. */
3452 tree nlanes
= CALL_EXPR_ARG (exp
, 0);
3453 gcc_assert (TREE_CODE (nlanes
) == INTEGER_CST
);
3454 rtx lane_idx
= expand_normal (CALL_EXPR_ARG (exp
, 1));
3455 if (CONST_INT_P (lane_idx
))
3456 neon_lane_bounds (lane_idx
, 0, TREE_INT_CST_LOW (nlanes
), exp
);
3458 error ("%Klane index must be a constant immediate", exp
);
3459 /* Don't generate any RTL. */
3462 if (fcode
>= ARM_BUILTIN_MVE_BASE
)
3463 return arm_expand_mve_builtin (fcode
, exp
, target
);
3465 if (fcode
>= ARM_BUILTIN_ACLE_BASE
)
3466 return arm_expand_acle_builtin (fcode
, exp
, target
);
3468 if (fcode
>= ARM_BUILTIN_NEON_BASE
)
3469 return arm_expand_neon_builtin (fcode
, exp
, target
);
3471 if (fcode
>= ARM_BUILTIN_VFP_BASE
)
3472 return arm_expand_vfp_builtin (fcode
, exp
, target
);
3474 /* Check in the context of the function making the call whether the
3475 builtin is supported. */
3476 if (fcode
>= ARM_BUILTIN_CRYPTO_BASE
3477 && (!TARGET_CRYPTO
|| !TARGET_HARD_FLOAT
))
3479 fatal_error (input_location
,
3480 "You must enable crypto instructions"
3481 " (e.g. include %<-mfloat-abi=softfp%> "
3482 "%<-mfpu=crypto-neon%>)"
3483 " to use these intrinsics.");
3489 case ARM_BUILTIN_GET_FPSCR_NZCVQC
:
3490 case ARM_BUILTIN_SET_FPSCR_NZCVQC
:
3491 if (fcode
== ARM_BUILTIN_GET_FPSCR_NZCVQC
)
3493 icode
= CODE_FOR_get_fpscr_nzcvqc
;
3494 target
= gen_reg_rtx (SImode
);
3495 emit_insn (GEN_FCN (icode
) (target
));
3500 icode
= CODE_FOR_set_fpscr_nzcvqc
;
3501 op0
= expand_normal (CALL_EXPR_ARG (exp
, 0));
3502 emit_insn (GEN_FCN (icode
) (force_reg (SImode
, op0
)));
3506 case ARM_BUILTIN_GET_FPSCR
:
3507 case ARM_BUILTIN_SET_FPSCR
:
3508 if (fcode
== ARM_BUILTIN_GET_FPSCR
)
3510 icode
= CODE_FOR_get_fpscr
;
3511 target
= gen_reg_rtx (SImode
);
3512 pat
= GEN_FCN (icode
) (target
);
3517 icode
= CODE_FOR_set_fpscr
;
3518 arg0
= CALL_EXPR_ARG (exp
, 0);
3519 op0
= expand_normal (arg0
);
3520 pat
= GEN_FCN (icode
) (force_reg (SImode
, op0
));
3525 case ARM_BUILTIN_CMSE_NONSECURE_CALLER
:
3526 target
= gen_reg_rtx (SImode
);
3527 op0
= arm_return_addr (0, NULL_RTX
);
3528 emit_insn (gen_andsi3 (target
, op0
, const1_rtx
));
3529 op1
= gen_rtx_EQ (SImode
, target
, const0_rtx
);
3530 emit_insn (gen_cstoresi4 (target
, op1
, target
, const0_rtx
));
3533 case ARM_BUILTIN_TEXTRMSB
:
3534 case ARM_BUILTIN_TEXTRMUB
:
3535 case ARM_BUILTIN_TEXTRMSH
:
3536 case ARM_BUILTIN_TEXTRMUH
:
3537 case ARM_BUILTIN_TEXTRMSW
:
3538 case ARM_BUILTIN_TEXTRMUW
:
3539 icode
= (fcode
== ARM_BUILTIN_TEXTRMSB
? CODE_FOR_iwmmxt_textrmsb
3540 : fcode
== ARM_BUILTIN_TEXTRMUB
? CODE_FOR_iwmmxt_textrmub
3541 : fcode
== ARM_BUILTIN_TEXTRMSH
? CODE_FOR_iwmmxt_textrmsh
3542 : fcode
== ARM_BUILTIN_TEXTRMUH
? CODE_FOR_iwmmxt_textrmuh
3543 : CODE_FOR_iwmmxt_textrmw
);
3545 arg0
= CALL_EXPR_ARG (exp
, 0);
3546 arg1
= CALL_EXPR_ARG (exp
, 1);
3547 op0
= expand_normal (arg0
);
3548 op1
= expand_normal (arg1
);
3549 tmode
= insn_data
[icode
].operand
[0].mode
;
3550 mode0
= insn_data
[icode
].operand
[1].mode
;
3551 mode1
= insn_data
[icode
].operand
[2].mode
;
3553 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
3554 op0
= copy_to_mode_reg (mode0
, op0
);
3555 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
3557 /* @@@ better error message */
3558 error ("selector must be an immediate");
3559 return gen_reg_rtx (tmode
);
3562 opint
= INTVAL (op1
);
3563 if (fcode
== ARM_BUILTIN_TEXTRMSB
|| fcode
== ARM_BUILTIN_TEXTRMUB
)
3565 if (opint
> 7 || opint
< 0)
3566 error ("the range of selector should be in 0 to 7");
3568 else if (fcode
== ARM_BUILTIN_TEXTRMSH
|| fcode
== ARM_BUILTIN_TEXTRMUH
)
3570 if (opint
> 3 || opint
< 0)
3571 error ("the range of selector should be in 0 to 3");
3573 else /* ARM_BUILTIN_TEXTRMSW || ARM_BUILTIN_TEXTRMUW. */
3575 if (opint
> 1 || opint
< 0)
3576 error ("the range of selector should be in 0 to 1");
3580 || GET_MODE (target
) != tmode
3581 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
3582 target
= gen_reg_rtx (tmode
);
3583 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
3589 case ARM_BUILTIN_WALIGNI
:
3590 /* If op2 is immediate, call walighi, else call walighr. */
3591 arg0
= CALL_EXPR_ARG (exp
, 0);
3592 arg1
= CALL_EXPR_ARG (exp
, 1);
3593 arg2
= CALL_EXPR_ARG (exp
, 2);
3594 op0
= expand_normal (arg0
);
3595 op1
= expand_normal (arg1
);
3596 op2
= expand_normal (arg2
);
3597 if (CONST_INT_P (op2
))
3599 icode
= CODE_FOR_iwmmxt_waligni
;
3600 tmode
= insn_data
[icode
].operand
[0].mode
;
3601 mode0
= insn_data
[icode
].operand
[1].mode
;
3602 mode1
= insn_data
[icode
].operand
[2].mode
;
3603 mode2
= insn_data
[icode
].operand
[3].mode
;
3604 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
3605 op0
= copy_to_mode_reg (mode0
, op0
);
3606 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
3607 op1
= copy_to_mode_reg (mode1
, op1
);
3608 gcc_assert ((*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
));
3609 selector
= INTVAL (op2
);
3610 if (selector
> 7 || selector
< 0)
3611 error ("the range of selector should be in 0 to 7");
3615 icode
= CODE_FOR_iwmmxt_walignr
;
3616 tmode
= insn_data
[icode
].operand
[0].mode
;
3617 mode0
= insn_data
[icode
].operand
[1].mode
;
3618 mode1
= insn_data
[icode
].operand
[2].mode
;
3619 mode2
= insn_data
[icode
].operand
[3].mode
;
3620 if (!(*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
3621 op0
= copy_to_mode_reg (mode0
, op0
);
3622 if (!(*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
3623 op1
= copy_to_mode_reg (mode1
, op1
);
3624 if (!(*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
3625 op2
= copy_to_mode_reg (mode2
, op2
);
3628 || GET_MODE (target
) != tmode
3629 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
3630 target
= gen_reg_rtx (tmode
);
3631 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
3637 case ARM_BUILTIN_TINSRB
:
3638 case ARM_BUILTIN_TINSRH
:
3639 case ARM_BUILTIN_TINSRW
:
3640 case ARM_BUILTIN_WMERGE
:
3641 icode
= (fcode
== ARM_BUILTIN_TINSRB
? CODE_FOR_iwmmxt_tinsrb
3642 : fcode
== ARM_BUILTIN_TINSRH
? CODE_FOR_iwmmxt_tinsrh
3643 : fcode
== ARM_BUILTIN_WMERGE
? CODE_FOR_iwmmxt_wmerge
3644 : CODE_FOR_iwmmxt_tinsrw
);
3645 arg0
= CALL_EXPR_ARG (exp
, 0);
3646 arg1
= CALL_EXPR_ARG (exp
, 1);
3647 arg2
= CALL_EXPR_ARG (exp
, 2);
3648 op0
= expand_normal (arg0
);
3649 op1
= expand_normal (arg1
);
3650 op2
= expand_normal (arg2
);
3651 tmode
= insn_data
[icode
].operand
[0].mode
;
3652 mode0
= insn_data
[icode
].operand
[1].mode
;
3653 mode1
= insn_data
[icode
].operand
[2].mode
;
3654 mode2
= insn_data
[icode
].operand
[3].mode
;
3656 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
3657 op0
= copy_to_mode_reg (mode0
, op0
);
3658 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
3659 op1
= copy_to_mode_reg (mode1
, op1
);
3660 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
3662 error ("selector must be an immediate");
3665 if (icode
== CODE_FOR_iwmmxt_wmerge
)
3667 selector
= INTVAL (op2
);
3668 if (selector
> 7 || selector
< 0)
3669 error ("the range of selector should be in 0 to 7");
3671 if ((icode
== CODE_FOR_iwmmxt_tinsrb
)
3672 || (icode
== CODE_FOR_iwmmxt_tinsrh
)
3673 || (icode
== CODE_FOR_iwmmxt_tinsrw
))
3676 selector
= INTVAL (op2
);
3677 if (icode
== CODE_FOR_iwmmxt_tinsrb
&& (selector
< 0 || selector
> 7))
3678 error ("the range of selector should be in 0 to 7");
3679 else if (icode
== CODE_FOR_iwmmxt_tinsrh
&& (selector
< 0 ||selector
> 3))
3680 error ("the range of selector should be in 0 to 3");
3681 else if (icode
== CODE_FOR_iwmmxt_tinsrw
&& (selector
< 0 ||selector
> 1))
3682 error ("the range of selector should be in 0 to 1");
3684 op2
= GEN_INT (mask
);
3687 || GET_MODE (target
) != tmode
3688 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
3689 target
= gen_reg_rtx (tmode
);
3690 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
3696 case ARM_BUILTIN_SETWCGR0
:
3697 case ARM_BUILTIN_SETWCGR1
:
3698 case ARM_BUILTIN_SETWCGR2
:
3699 case ARM_BUILTIN_SETWCGR3
:
3700 icode
= (fcode
== ARM_BUILTIN_SETWCGR0
? CODE_FOR_iwmmxt_setwcgr0
3701 : fcode
== ARM_BUILTIN_SETWCGR1
? CODE_FOR_iwmmxt_setwcgr1
3702 : fcode
== ARM_BUILTIN_SETWCGR2
? CODE_FOR_iwmmxt_setwcgr2
3703 : CODE_FOR_iwmmxt_setwcgr3
);
3704 arg0
= CALL_EXPR_ARG (exp
, 0);
3705 op0
= expand_normal (arg0
);
3706 mode0
= insn_data
[icode
].operand
[0].mode
;
3707 if (!(*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
3708 op0
= copy_to_mode_reg (mode0
, op0
);
3709 pat
= GEN_FCN (icode
) (op0
);
3715 case ARM_BUILTIN_GETWCGR0
:
3716 case ARM_BUILTIN_GETWCGR1
:
3717 case ARM_BUILTIN_GETWCGR2
:
3718 case ARM_BUILTIN_GETWCGR3
:
3719 icode
= (fcode
== ARM_BUILTIN_GETWCGR0
? CODE_FOR_iwmmxt_getwcgr0
3720 : fcode
== ARM_BUILTIN_GETWCGR1
? CODE_FOR_iwmmxt_getwcgr1
3721 : fcode
== ARM_BUILTIN_GETWCGR2
? CODE_FOR_iwmmxt_getwcgr2
3722 : CODE_FOR_iwmmxt_getwcgr3
);
3723 tmode
= insn_data
[icode
].operand
[0].mode
;
3725 || GET_MODE (target
) != tmode
3726 || !(*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
3727 target
= gen_reg_rtx (tmode
);
3728 pat
= GEN_FCN (icode
) (target
);
3734 case ARM_BUILTIN_WSHUFH
:
3735 icode
= CODE_FOR_iwmmxt_wshufh
;
3736 arg0
= CALL_EXPR_ARG (exp
, 0);
3737 arg1
= CALL_EXPR_ARG (exp
, 1);
3738 op0
= expand_normal (arg0
);
3739 op1
= expand_normal (arg1
);
3740 tmode
= insn_data
[icode
].operand
[0].mode
;
3741 mode1
= insn_data
[icode
].operand
[1].mode
;
3742 mode2
= insn_data
[icode
].operand
[2].mode
;
3744 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode1
))
3745 op0
= copy_to_mode_reg (mode1
, op0
);
3746 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode2
))
3748 error ("mask must be an immediate");
3751 selector
= INTVAL (op1
);
3752 if (selector
< 0 || selector
> 255)
3753 error ("the range of mask should be in 0 to 255");
3755 || GET_MODE (target
) != tmode
3756 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
3757 target
= gen_reg_rtx (tmode
);
3758 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
3764 case ARM_BUILTIN_WMADDS
:
3765 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmadds
, exp
, target
);
3766 case ARM_BUILTIN_WMADDSX
:
3767 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsx
, exp
, target
);
3768 case ARM_BUILTIN_WMADDSN
:
3769 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddsn
, exp
, target
);
3770 case ARM_BUILTIN_WMADDU
:
3771 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddu
, exp
, target
);
3772 case ARM_BUILTIN_WMADDUX
:
3773 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddux
, exp
, target
);
3774 case ARM_BUILTIN_WMADDUN
:
3775 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wmaddun
, exp
, target
);
3776 case ARM_BUILTIN_WSADBZ
:
3777 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadbz
, exp
, target
);
3778 case ARM_BUILTIN_WSADHZ
:
3779 return arm_expand_binop_builtin (CODE_FOR_iwmmxt_wsadhz
, exp
, target
);
3781 /* Several three-argument builtins. */
3782 case ARM_BUILTIN_WMACS
:
3783 case ARM_BUILTIN_WMACU
:
3784 case ARM_BUILTIN_TMIA
:
3785 case ARM_BUILTIN_TMIAPH
:
3786 case ARM_BUILTIN_TMIATT
:
3787 case ARM_BUILTIN_TMIATB
:
3788 case ARM_BUILTIN_TMIABT
:
3789 case ARM_BUILTIN_TMIABB
:
3790 case ARM_BUILTIN_WQMIABB
:
3791 case ARM_BUILTIN_WQMIABT
:
3792 case ARM_BUILTIN_WQMIATB
:
3793 case ARM_BUILTIN_WQMIATT
:
3794 case ARM_BUILTIN_WQMIABBN
:
3795 case ARM_BUILTIN_WQMIABTN
:
3796 case ARM_BUILTIN_WQMIATBN
:
3797 case ARM_BUILTIN_WQMIATTN
:
3798 case ARM_BUILTIN_WMIABB
:
3799 case ARM_BUILTIN_WMIABT
:
3800 case ARM_BUILTIN_WMIATB
:
3801 case ARM_BUILTIN_WMIATT
:
3802 case ARM_BUILTIN_WMIABBN
:
3803 case ARM_BUILTIN_WMIABTN
:
3804 case ARM_BUILTIN_WMIATBN
:
3805 case ARM_BUILTIN_WMIATTN
:
3806 case ARM_BUILTIN_WMIAWBB
:
3807 case ARM_BUILTIN_WMIAWBT
:
3808 case ARM_BUILTIN_WMIAWTB
:
3809 case ARM_BUILTIN_WMIAWTT
:
3810 case ARM_BUILTIN_WMIAWBBN
:
3811 case ARM_BUILTIN_WMIAWBTN
:
3812 case ARM_BUILTIN_WMIAWTBN
:
3813 case ARM_BUILTIN_WMIAWTTN
:
3814 case ARM_BUILTIN_WSADB
:
3815 case ARM_BUILTIN_WSADH
:
3816 icode
= (fcode
== ARM_BUILTIN_WMACS
? CODE_FOR_iwmmxt_wmacs
3817 : fcode
== ARM_BUILTIN_WMACU
? CODE_FOR_iwmmxt_wmacu
3818 : fcode
== ARM_BUILTIN_TMIA
? CODE_FOR_iwmmxt_tmia
3819 : fcode
== ARM_BUILTIN_TMIAPH
? CODE_FOR_iwmmxt_tmiaph
3820 : fcode
== ARM_BUILTIN_TMIABB
? CODE_FOR_iwmmxt_tmiabb
3821 : fcode
== ARM_BUILTIN_TMIABT
? CODE_FOR_iwmmxt_tmiabt
3822 : fcode
== ARM_BUILTIN_TMIATB
? CODE_FOR_iwmmxt_tmiatb
3823 : fcode
== ARM_BUILTIN_TMIATT
? CODE_FOR_iwmmxt_tmiatt
3824 : fcode
== ARM_BUILTIN_WQMIABB
? CODE_FOR_iwmmxt_wqmiabb
3825 : fcode
== ARM_BUILTIN_WQMIABT
? CODE_FOR_iwmmxt_wqmiabt
3826 : fcode
== ARM_BUILTIN_WQMIATB
? CODE_FOR_iwmmxt_wqmiatb
3827 : fcode
== ARM_BUILTIN_WQMIATT
? CODE_FOR_iwmmxt_wqmiatt
3828 : fcode
== ARM_BUILTIN_WQMIABBN
? CODE_FOR_iwmmxt_wqmiabbn
3829 : fcode
== ARM_BUILTIN_WQMIABTN
? CODE_FOR_iwmmxt_wqmiabtn
3830 : fcode
== ARM_BUILTIN_WQMIATBN
? CODE_FOR_iwmmxt_wqmiatbn
3831 : fcode
== ARM_BUILTIN_WQMIATTN
? CODE_FOR_iwmmxt_wqmiattn
3832 : fcode
== ARM_BUILTIN_WMIABB
? CODE_FOR_iwmmxt_wmiabb
3833 : fcode
== ARM_BUILTIN_WMIABT
? CODE_FOR_iwmmxt_wmiabt
3834 : fcode
== ARM_BUILTIN_WMIATB
? CODE_FOR_iwmmxt_wmiatb
3835 : fcode
== ARM_BUILTIN_WMIATT
? CODE_FOR_iwmmxt_wmiatt
3836 : fcode
== ARM_BUILTIN_WMIABBN
? CODE_FOR_iwmmxt_wmiabbn
3837 : fcode
== ARM_BUILTIN_WMIABTN
? CODE_FOR_iwmmxt_wmiabtn
3838 : fcode
== ARM_BUILTIN_WMIATBN
? CODE_FOR_iwmmxt_wmiatbn
3839 : fcode
== ARM_BUILTIN_WMIATTN
? CODE_FOR_iwmmxt_wmiattn
3840 : fcode
== ARM_BUILTIN_WMIAWBB
? CODE_FOR_iwmmxt_wmiawbb
3841 : fcode
== ARM_BUILTIN_WMIAWBT
? CODE_FOR_iwmmxt_wmiawbt
3842 : fcode
== ARM_BUILTIN_WMIAWTB
? CODE_FOR_iwmmxt_wmiawtb
3843 : fcode
== ARM_BUILTIN_WMIAWTT
? CODE_FOR_iwmmxt_wmiawtt
3844 : fcode
== ARM_BUILTIN_WMIAWBBN
? CODE_FOR_iwmmxt_wmiawbbn
3845 : fcode
== ARM_BUILTIN_WMIAWBTN
? CODE_FOR_iwmmxt_wmiawbtn
3846 : fcode
== ARM_BUILTIN_WMIAWTBN
? CODE_FOR_iwmmxt_wmiawtbn
3847 : fcode
== ARM_BUILTIN_WMIAWTTN
? CODE_FOR_iwmmxt_wmiawttn
3848 : fcode
== ARM_BUILTIN_WSADB
? CODE_FOR_iwmmxt_wsadb
3849 : CODE_FOR_iwmmxt_wsadh
);
3850 arg0
= CALL_EXPR_ARG (exp
, 0);
3851 arg1
= CALL_EXPR_ARG (exp
, 1);
3852 arg2
= CALL_EXPR_ARG (exp
, 2);
3853 op0
= expand_normal (arg0
);
3854 op1
= expand_normal (arg1
);
3855 op2
= expand_normal (arg2
);
3856 tmode
= insn_data
[icode
].operand
[0].mode
;
3857 mode0
= insn_data
[icode
].operand
[1].mode
;
3858 mode1
= insn_data
[icode
].operand
[2].mode
;
3859 mode2
= insn_data
[icode
].operand
[3].mode
;
3861 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
3862 op0
= copy_to_mode_reg (mode0
, op0
);
3863 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
3864 op1
= copy_to_mode_reg (mode1
, op1
);
3865 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
3866 op2
= copy_to_mode_reg (mode2
, op2
);
3868 || GET_MODE (target
) != tmode
3869 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
3870 target
= gen_reg_rtx (tmode
);
3871 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
3877 case ARM_BUILTIN_WZERO
:
3878 target
= gen_reg_rtx (DImode
);
3879 emit_insn (gen_iwmmxt_clrdi (target
));
3882 case ARM_BUILTIN_WSRLHI
:
3883 case ARM_BUILTIN_WSRLWI
:
3884 case ARM_BUILTIN_WSRLDI
:
3885 case ARM_BUILTIN_WSLLHI
:
3886 case ARM_BUILTIN_WSLLWI
:
3887 case ARM_BUILTIN_WSLLDI
:
3888 case ARM_BUILTIN_WSRAHI
:
3889 case ARM_BUILTIN_WSRAWI
:
3890 case ARM_BUILTIN_WSRADI
:
3891 case ARM_BUILTIN_WRORHI
:
3892 case ARM_BUILTIN_WRORWI
:
3893 case ARM_BUILTIN_WRORDI
:
3894 case ARM_BUILTIN_WSRLH
:
3895 case ARM_BUILTIN_WSRLW
:
3896 case ARM_BUILTIN_WSRLD
:
3897 case ARM_BUILTIN_WSLLH
:
3898 case ARM_BUILTIN_WSLLW
:
3899 case ARM_BUILTIN_WSLLD
:
3900 case ARM_BUILTIN_WSRAH
:
3901 case ARM_BUILTIN_WSRAW
:
3902 case ARM_BUILTIN_WSRAD
:
3903 case ARM_BUILTIN_WRORH
:
3904 case ARM_BUILTIN_WRORW
:
3905 case ARM_BUILTIN_WRORD
:
3906 icode
= (fcode
== ARM_BUILTIN_WSRLHI
? CODE_FOR_lshrv4hi3_iwmmxt
3907 : fcode
== ARM_BUILTIN_WSRLWI
? CODE_FOR_lshrv2si3_iwmmxt
3908 : fcode
== ARM_BUILTIN_WSRLDI
? CODE_FOR_lshrdi3_iwmmxt
3909 : fcode
== ARM_BUILTIN_WSLLHI
? CODE_FOR_ashlv4hi3_iwmmxt
3910 : fcode
== ARM_BUILTIN_WSLLWI
? CODE_FOR_ashlv2si3_iwmmxt
3911 : fcode
== ARM_BUILTIN_WSLLDI
? CODE_FOR_ashldi3_iwmmxt
3912 : fcode
== ARM_BUILTIN_WSRAHI
? CODE_FOR_ashrv4hi3_iwmmxt
3913 : fcode
== ARM_BUILTIN_WSRAWI
? CODE_FOR_ashrv2si3_iwmmxt
3914 : fcode
== ARM_BUILTIN_WSRADI
? CODE_FOR_ashrdi3_iwmmxt
3915 : fcode
== ARM_BUILTIN_WRORHI
? CODE_FOR_rorv4hi3
3916 : fcode
== ARM_BUILTIN_WRORWI
? CODE_FOR_rorv2si3
3917 : fcode
== ARM_BUILTIN_WRORDI
? CODE_FOR_rordi3
3918 : fcode
== ARM_BUILTIN_WSRLH
? CODE_FOR_lshrv4hi3_di
3919 : fcode
== ARM_BUILTIN_WSRLW
? CODE_FOR_lshrv2si3_di
3920 : fcode
== ARM_BUILTIN_WSRLD
? CODE_FOR_lshrdi3_di
3921 : fcode
== ARM_BUILTIN_WSLLH
? CODE_FOR_ashlv4hi3_di
3922 : fcode
== ARM_BUILTIN_WSLLW
? CODE_FOR_ashlv2si3_di
3923 : fcode
== ARM_BUILTIN_WSLLD
? CODE_FOR_ashldi3_di
3924 : fcode
== ARM_BUILTIN_WSRAH
? CODE_FOR_ashrv4hi3_di
3925 : fcode
== ARM_BUILTIN_WSRAW
? CODE_FOR_ashrv2si3_di
3926 : fcode
== ARM_BUILTIN_WSRAD
? CODE_FOR_ashrdi3_di
3927 : fcode
== ARM_BUILTIN_WRORH
? CODE_FOR_rorv4hi3_di
3928 : fcode
== ARM_BUILTIN_WRORW
? CODE_FOR_rorv2si3_di
3929 : fcode
== ARM_BUILTIN_WRORD
? CODE_FOR_rordi3_di
3930 : CODE_FOR_nothing
);
3931 arg1
= CALL_EXPR_ARG (exp
, 1);
3932 op1
= expand_normal (arg1
);
3933 if (GET_MODE (op1
) == VOIDmode
)
3936 if ((fcode
== ARM_BUILTIN_WRORHI
|| fcode
== ARM_BUILTIN_WRORWI
3937 || fcode
== ARM_BUILTIN_WRORH
|| fcode
== ARM_BUILTIN_WRORW
)
3938 && (imm
< 0 || imm
> 32))
3940 if (fcode
== ARM_BUILTIN_WRORHI
)
3941 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi16 in code.");
3942 else if (fcode
== ARM_BUILTIN_WRORWI
)
3943 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_rori_pi32 in code.");
3944 else if (fcode
== ARM_BUILTIN_WRORH
)
3945 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi16 in code.");
3947 error ("the range of count should be in 0 to 32. please check the intrinsic _mm_ror_pi32 in code.");
3949 else if ((fcode
== ARM_BUILTIN_WRORDI
|| fcode
== ARM_BUILTIN_WRORD
)
3950 && (imm
< 0 || imm
> 64))
3952 if (fcode
== ARM_BUILTIN_WRORDI
)
3953 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_rori_si64 in code.");
3955 error ("the range of count should be in 0 to 64. please check the intrinsic _mm_ror_si64 in code.");
3959 if (fcode
== ARM_BUILTIN_WSRLHI
)
3960 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi16 in code.");
3961 else if (fcode
== ARM_BUILTIN_WSRLWI
)
3962 error ("the count should be no less than 0. please check the intrinsic _mm_srli_pi32 in code.");
3963 else if (fcode
== ARM_BUILTIN_WSRLDI
)
3964 error ("the count should be no less than 0. please check the intrinsic _mm_srli_si64 in code.");
3965 else if (fcode
== ARM_BUILTIN_WSLLHI
)
3966 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi16 in code.");
3967 else if (fcode
== ARM_BUILTIN_WSLLWI
)
3968 error ("the count should be no less than 0. please check the intrinsic _mm_slli_pi32 in code.");
3969 else if (fcode
== ARM_BUILTIN_WSLLDI
)
3970 error ("the count should be no less than 0. please check the intrinsic _mm_slli_si64 in code.");
3971 else if (fcode
== ARM_BUILTIN_WSRAHI
)
3972 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi16 in code.");
3973 else if (fcode
== ARM_BUILTIN_WSRAWI
)
3974 error ("the count should be no less than 0. please check the intrinsic _mm_srai_pi32 in code.");
3975 else if (fcode
== ARM_BUILTIN_WSRADI
)
3976 error ("the count should be no less than 0. please check the intrinsic _mm_srai_si64 in code.");
3977 else if (fcode
== ARM_BUILTIN_WSRLH
)
3978 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi16 in code.");
3979 else if (fcode
== ARM_BUILTIN_WSRLW
)
3980 error ("the count should be no less than 0. please check the intrinsic _mm_srl_pi32 in code.");
3981 else if (fcode
== ARM_BUILTIN_WSRLD
)
3982 error ("the count should be no less than 0. please check the intrinsic _mm_srl_si64 in code.");
3983 else if (fcode
== ARM_BUILTIN_WSLLH
)
3984 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi16 in code.");
3985 else if (fcode
== ARM_BUILTIN_WSLLW
)
3986 error ("the count should be no less than 0. please check the intrinsic _mm_sll_pi32 in code.");
3987 else if (fcode
== ARM_BUILTIN_WSLLD
)
3988 error ("the count should be no less than 0. please check the intrinsic _mm_sll_si64 in code.");
3989 else if (fcode
== ARM_BUILTIN_WSRAH
)
3990 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi16 in code.");
3991 else if (fcode
== ARM_BUILTIN_WSRAW
)
3992 error ("the count should be no less than 0. please check the intrinsic _mm_sra_pi32 in code.");
3994 error ("the count should be no less than 0. please check the intrinsic _mm_sra_si64 in code.");
3997 return arm_expand_binop_builtin (icode
, exp
, target
);
4003 for (i
= 0, d
= bdesc_2arg
; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
4004 if (d
->code
== (enum arm_builtins
) fcode
)
4005 return arm_expand_binop_builtin (d
->icode
, exp
, target
);
4007 for (i
= 0, d
= bdesc_1arg
; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
4008 if (d
->code
== (enum arm_builtins
) fcode
)
4009 return arm_expand_unop_builtin (d
->icode
, exp
, target
, 0);
4011 for (i
= 0, d
= bdesc_3arg
; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
4012 if (d
->code
== (enum arm_builtins
) fcode
)
4013 return arm_expand_ternop_builtin (d
->icode
, exp
, target
);
4015 /* @@@ Should really do something sensible here. */
4020 arm_builtin_vectorized_function (unsigned int fn
, tree type_out
, tree type_in
)
4022 machine_mode in_mode
, out_mode
;
4024 bool out_unsigned_p
= TYPE_UNSIGNED (type_out
);
4026 /* Can't provide any vectorized builtins when we can't use NEON. */
4030 if (TREE_CODE (type_out
) != VECTOR_TYPE
4031 || TREE_CODE (type_in
) != VECTOR_TYPE
)
4034 out_mode
= TYPE_MODE (TREE_TYPE (type_out
));
4035 out_n
= TYPE_VECTOR_SUBPARTS (type_out
);
4036 in_mode
= TYPE_MODE (TREE_TYPE (type_in
));
4037 in_n
= TYPE_VECTOR_SUBPARTS (type_in
);
4039 /* ARM_CHECK_BUILTIN_MODE and ARM_FIND_VRINT_VARIANT are used to find the
4040 decl of the vectorized builtin for the appropriate vector mode.
4041 NULL_TREE is returned if no such builtin is available. */
4042 #undef ARM_CHECK_BUILTIN_MODE
4043 #define ARM_CHECK_BUILTIN_MODE(C) \
4045 && flag_unsafe_math_optimizations \
4046 && ARM_CHECK_BUILTIN_MODE_1 (C))
4048 #undef ARM_CHECK_BUILTIN_MODE_1
4049 #define ARM_CHECK_BUILTIN_MODE_1(C) \
4050 (out_mode == SFmode && out_n == C \
4051 && in_mode == SFmode && in_n == C)
4053 #undef ARM_FIND_VRINT_VARIANT
4054 #define ARM_FIND_VRINT_VARIANT(N) \
4055 (ARM_CHECK_BUILTIN_MODE (2) \
4056 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sf, false) \
4057 : (ARM_CHECK_BUILTIN_MODE (4) \
4058 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sf, false) \
4064 return ARM_FIND_VRINT_VARIANT (vrintm
);
4066 return ARM_FIND_VRINT_VARIANT (vrintp
);
4068 return ARM_FIND_VRINT_VARIANT (vrintz
);
4070 return ARM_FIND_VRINT_VARIANT (vrinta
);
4071 #undef ARM_CHECK_BUILTIN_MODE_1
4072 #define ARM_CHECK_BUILTIN_MODE_1(C) \
4073 (out_mode == SImode && out_n == C \
4074 && in_mode == SFmode && in_n == C)
4076 #define ARM_FIND_VCVT_VARIANT(N) \
4077 (ARM_CHECK_BUILTIN_MODE (2) \
4078 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v2sfv2si, false) \
4079 : (ARM_CHECK_BUILTIN_MODE (4) \
4080 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##v4sfv4si, false) \
4083 #define ARM_FIND_VCVTU_VARIANT(N) \
4084 (ARM_CHECK_BUILTIN_MODE (2) \
4085 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv2sfv2si, false) \
4086 : (ARM_CHECK_BUILTIN_MODE (4) \
4087 ? arm_builtin_decl(ARM_BUILTIN_NEON_##N##uv4sfv4si, false) \
4090 return (out_unsigned_p
4091 ? ARM_FIND_VCVTU_VARIANT (vcvta
)
4092 : ARM_FIND_VCVT_VARIANT (vcvta
));
4094 return (out_unsigned_p
4095 ? ARM_FIND_VCVTU_VARIANT (vcvtp
)
4096 : ARM_FIND_VCVT_VARIANT (vcvtp
));
4098 return (out_unsigned_p
4099 ? ARM_FIND_VCVTU_VARIANT (vcvtm
)
4100 : ARM_FIND_VCVT_VARIANT (vcvtm
));
4101 #undef ARM_CHECK_BUILTIN_MODE
4102 #define ARM_CHECK_BUILTIN_MODE(C, N) \
4103 (out_mode == N##mode && out_n == C \
4104 && in_mode == N##mode && in_n == C)
4105 case CFN_BUILT_IN_BSWAP16
:
4106 if (ARM_CHECK_BUILTIN_MODE (4, HI
))
4107 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4hi
, false);
4108 else if (ARM_CHECK_BUILTIN_MODE (8, HI
))
4109 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv8hi
, false);
4112 case CFN_BUILT_IN_BSWAP32
:
4113 if (ARM_CHECK_BUILTIN_MODE (2, SI
))
4114 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2si
, false);
4115 else if (ARM_CHECK_BUILTIN_MODE (4, SI
))
4116 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv4si
, false);
4119 case CFN_BUILT_IN_BSWAP64
:
4120 if (ARM_CHECK_BUILTIN_MODE (2, DI
))
4121 return arm_builtin_decl (ARM_BUILTIN_NEON_bswapv2di
, false);
4125 if (ARM_CHECK_BUILTIN_MODE (2, SF
))
4126 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv2sf
, false);
4127 else if (ARM_CHECK_BUILTIN_MODE (4, SF
))
4128 return arm_builtin_decl (ARM_BUILTIN_NEON_copysignfv4sf
, false);
4137 #undef ARM_FIND_VCVT_VARIANT
4138 #undef ARM_FIND_VCVTU_VARIANT
4139 #undef ARM_CHECK_BUILTIN_MODE
4140 #undef ARM_FIND_VRINT_VARIANT
4143 arm_atomic_assign_expand_fenv (tree
*hold
, tree
*clear
, tree
*update
)
4145 const unsigned ARM_FE_INVALID
= 1;
4146 const unsigned ARM_FE_DIVBYZERO
= 2;
4147 const unsigned ARM_FE_OVERFLOW
= 4;
4148 const unsigned ARM_FE_UNDERFLOW
= 8;
4149 const unsigned ARM_FE_INEXACT
= 16;
4150 const unsigned HOST_WIDE_INT ARM_FE_ALL_EXCEPT
= (ARM_FE_INVALID
4155 const unsigned HOST_WIDE_INT ARM_FE_EXCEPT_SHIFT
= 8;
4156 tree fenv_var
, get_fpscr
, set_fpscr
, mask
, ld_fenv
, masked_fenv
;
4157 tree new_fenv_var
, reload_fenv
, restore_fnenv
;
4158 tree update_call
, atomic_feraiseexcept
, hold_fnclex
;
4160 if (!TARGET_HARD_FLOAT
)
4163 /* Generate the equivalent of :
4164 unsigned int fenv_var;
4165 fenv_var = __builtin_arm_get_fpscr ();
4167 unsigned int masked_fenv;
4168 masked_fenv = fenv_var & mask;
4170 __builtin_arm_set_fpscr (masked_fenv); */
4172 fenv_var
= create_tmp_var_raw (unsigned_type_node
);
4173 get_fpscr
= arm_builtin_decls
[ARM_BUILTIN_GET_FPSCR
];
4174 set_fpscr
= arm_builtin_decls
[ARM_BUILTIN_SET_FPSCR
];
4175 mask
= build_int_cst (unsigned_type_node
,
4176 ~((ARM_FE_ALL_EXCEPT
<< ARM_FE_EXCEPT_SHIFT
)
4177 | ARM_FE_ALL_EXCEPT
));
4178 ld_fenv
= build4 (TARGET_EXPR
, unsigned_type_node
,
4179 fenv_var
, build_call_expr (get_fpscr
, 0),
4180 NULL_TREE
, NULL_TREE
);
4181 masked_fenv
= build2 (BIT_AND_EXPR
, unsigned_type_node
, fenv_var
, mask
);
4182 hold_fnclex
= build_call_expr (set_fpscr
, 1, masked_fenv
);
4183 *hold
= build2 (COMPOUND_EXPR
, void_type_node
,
4184 build2 (COMPOUND_EXPR
, void_type_node
, masked_fenv
, ld_fenv
),
4187 /* Store the value of masked_fenv to clear the exceptions:
4188 __builtin_arm_set_fpscr (masked_fenv); */
4190 *clear
= build_call_expr (set_fpscr
, 1, masked_fenv
);
4192 /* Generate the equivalent of :
4193 unsigned int new_fenv_var;
4194 new_fenv_var = __builtin_arm_get_fpscr ();
4196 __builtin_arm_set_fpscr (fenv_var);
4198 __atomic_feraiseexcept (new_fenv_var); */
4200 new_fenv_var
= create_tmp_var_raw (unsigned_type_node
);
4201 reload_fenv
= build4 (TARGET_EXPR
, unsigned_type_node
, new_fenv_var
,
4202 build_call_expr (get_fpscr
, 0), NULL_TREE
, NULL_TREE
);
4203 restore_fnenv
= build_call_expr (set_fpscr
, 1, fenv_var
);
4204 atomic_feraiseexcept
= builtin_decl_implicit (BUILT_IN_ATOMIC_FERAISEEXCEPT
);
4205 update_call
= build_call_expr (atomic_feraiseexcept
, 1,
4206 fold_convert (integer_type_node
, new_fenv_var
));
4207 *update
= build2 (COMPOUND_EXPR
, void_type_node
,
4208 build2 (COMPOUND_EXPR
, void_type_node
,
4209 reload_fenv
, restore_fnenv
), update_call
);
4212 /* Implement TARGET_CHECK_BUILTIN_CALL. Record a read of the Q bit through
4213 intrinsics in the machine function. */
4215 arm_check_builtin_call (location_t
, vec
<location_t
> , tree fndecl
,
4216 tree
, unsigned int, tree
*)
4218 int fcode
= DECL_MD_FUNCTION_CODE (fndecl
);
4219 if (fcode
== ARM_BUILTIN_saturation_occurred
4220 || fcode
== ARM_BUILTIN_set_saturation
)
4222 if (cfun
&& cfun
->decl
)
4223 DECL_ATTRIBUTES (cfun
->decl
)
4224 = tree_cons (get_identifier ("acle qbit"), NULL_TREE
,
4225 DECL_ATTRIBUTES (cfun
->decl
));
4227 if (fcode
== ARM_BUILTIN_sel
)
4229 if (cfun
&& cfun
->decl
)
4230 DECL_ATTRIBUTES (cfun
->decl
)
4231 = tree_cons (get_identifier ("acle gebits"), NULL_TREE
,
4232 DECL_ATTRIBUTES (cfun
->decl
));
4238 arm_describe_resolver (tree fndecl
)
4240 if (DECL_MD_FUNCTION_CODE (fndecl
) >= ARM_BUILTIN_vcx1qv16qi
4241 && DECL_MD_FUNCTION_CODE (fndecl
) < ARM_BUILTIN_MVE_BASE
)
4242 return arm_cde_resolver
;
4243 return arm_no_resolver
;
4247 arm_cde_end_args (tree fndecl
)
4249 return DECL_MD_FUNCTION_CODE (fndecl
) >= ARM_BUILTIN_vcx1q_p_v16qi
? 2 : 1;
4252 #include "gt-arm-builtins.h"