1 /* ACLE support for AArch64 SVE
2 Copyright (C) 2018-2024 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 by
8 the Free Software Foundation; either version 3, or (at your option)
11 GCC is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public 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"
30 #include "insn-codes.h"
33 #include "diagnostic.h"
35 #include "basic-block.h"
37 #include "fold-const.h"
39 #include "gimple-iterator.h"
43 #include "tree-vector-builder.h"
44 #include "stor-layout.h"
47 #include "gimple-fold.h"
48 #include "langhooks.h"
49 #include "stringpool.h"
51 #include "aarch64-sve-builtins.h"
52 #include "aarch64-sve-builtins-base.h"
53 #include "aarch64-sve-builtins-sve2.h"
54 #include "aarch64-sve-builtins-sme.h"
55 #include "aarch64-sve-builtins-shapes.h"
56 #include "aarch64-builtins.h"
58 namespace aarch64_sve
{
60 /* Static information about each single-predicate or single-vector
62 struct vector_type_info
64 /* The name of the type as declared by arm_sve.h. */
65 const char *acle_name
;
67 /* The name of the type specified in AAPCS64. The type is always
68 available under this name, even when arm_sve.h isn't included. */
71 /* The C++ mangling of ABI_NAME. */
72 const char *mangled_name
;
75 /* Describes a function decl. */
76 class GTY(()) registered_function
79 /* The ACLE function that the decl represents. */
80 function_instance instance
GTY ((skip
));
82 /* The decl itself. */
85 /* The architecture extensions that the function requires, as a set of
86 AARCH64_FL_* flags. */
87 aarch64_feature_flags required_extensions
;
89 /* True if the decl represents an overloaded function that needs to be
90 resolved by function_resolver. */
94 /* Hash traits for registered_function. */
95 struct registered_function_hasher
: nofree_ptr_hash
<registered_function
>
97 typedef function_instance compare_type
;
99 static hashval_t
hash (value_type
);
100 static bool equal (value_type
, const compare_type
&);
103 /* Information about each single-predicate or single-vector type. */
104 static CONSTEXPR
const vector_type_info vector_types
[] = {
105 #define DEF_SVE_TYPE(ACLE_NAME, NCHARS, ABI_NAME, SCALAR_TYPE) \
106 { #ACLE_NAME, #ABI_NAME, "u" #NCHARS #ABI_NAME },
107 #include "aarch64-sve-builtins.def"
110 /* The function name suffix associated with each predication type. */
111 static const char *const pred_suffixes
[NUM_PREDS
+ 1] = {
121 /* Static information about each mode_suffix_index. */
122 CONSTEXPR
const mode_suffix_info mode_suffixes
[] = {
123 #define VECTOR_TYPE_none NUM_VECTOR_TYPES
124 #define DEF_SVE_MODE(NAME, BASE, DISPLACEMENT, UNITS) \
125 { "_" #NAME, VECTOR_TYPE_##BASE, VECTOR_TYPE_##DISPLACEMENT, UNITS_##UNITS },
126 #include "aarch64-sve-builtins.def"
127 #undef VECTOR_TYPE_none
128 { "", NUM_VECTOR_TYPES
, NUM_VECTOR_TYPES
, UNITS_none
}
131 /* Static information about each type_suffix_index. */
132 CONSTEXPR
const type_suffix_info type_suffixes
[NUM_TYPE_SUFFIXES
+ 1] = {
133 #define DEF_SVE_NEON_TYPE_SUFFIX(NAME, ACLE_TYPE, CLASS, BITS, MODE, \
136 VECTOR_TYPE_##ACLE_TYPE, \
139 BITS / BITS_PER_UNIT, \
140 TYPE_##CLASS == TYPE_signed || TYPE_##CLASS == TYPE_unsigned, \
141 TYPE_##CLASS == TYPE_unsigned, \
142 TYPE_##CLASS == TYPE_float, \
143 TYPE_##CLASS != TYPE_bool, \
144 TYPE_##CLASS == TYPE_bool, \
150 #define DEF_SVE_TYPE_SUFFIX(NAME, ACLE_TYPE, CLASS, BITS, MODE) \
151 DEF_SVE_NEON_TYPE_SUFFIX (NAME, ACLE_TYPE, CLASS, BITS, MODE, \
152 ARM_NEON_H_TYPES_LAST, ARM_NEON_H_TYPES_LAST)
153 #define DEF_SME_ZA_SUFFIX(NAME, BITS, MODE) \
158 BITS / BITS_PER_UNIT, \
167 ARM_NEON_H_TYPES_LAST, \
168 ARM_NEON_H_TYPES_LAST },
169 #include "aarch64-sve-builtins.def"
170 { "", NUM_VECTOR_TYPES
, TYPE_bool
, 0, 0, false, false, false, false,
171 false, false, 0, VOIDmode
, ARM_NEON_H_TYPES_LAST
, ARM_NEON_H_TYPES_LAST
}
174 CONSTEXPR
const group_suffix_info group_suffixes
[] = {
175 #define DEF_SVE_GROUP_SUFFIX(NAME, VG, VECTORS_PER_TUPLE) \
176 { "_" #NAME, VG, VECTORS_PER_TUPLE },
177 #include "aarch64-sve-builtins.def"
181 /* Define a TYPES_<combination> macro for each combination of type
182 suffixes that an ACLE function can have, where <combination> is the
183 name used in DEF_SVE_FUNCTION entries.
185 Use S (T) for single type suffix T and D (T1, T2) for a pair of type
186 suffixes T1 and T2. Use commas to separate the suffixes.
188 Although the order shouldn't matter, the convention is to sort the
189 suffixes lexicographically after dividing suffixes into a type
190 class ("b", "f", etc.) and a numerical bit count. */
192 /* _b8 _b16 _b32 _b64. */
193 #define TYPES_all_pred(S, D) \
194 S (b8), S (b16), S (b32), S (b64)
196 /* _c8 _c16 _c32 _c64. */
197 #define TYPES_all_count(S, D) \
198 S (c8), S (c16), S (c32), S (c64)
200 /* _b8 _b16 _b32 _b64
201 _c8 _c16 _c32 _c64. */
202 #define TYPES_all_pred_count(S, D) \
203 TYPES_all_pred (S, D), \
204 TYPES_all_count (S, D)
206 /* _f16 _f32 _f64. */
207 #define TYPES_all_float(S, D) \
208 S (f16), S (f32), S (f64)
210 /* _s8 _s16 _s32 _s64. */
211 #define TYPES_all_signed(S, D) \
212 S (s8), S (s16), S (s32), S (s64)
215 _s8 _s16 _s32 _s64. */
216 #define TYPES_all_float_and_signed(S, D) \
217 TYPES_all_float (S, D), TYPES_all_signed (S, D)
219 /* _u8 _u16 _u32 _u64. */
220 #define TYPES_all_unsigned(S, D) \
221 S (u8), S (u16), S (u32), S (u64)
223 /* _s8 _s16 _s32 _s64
224 _u8 _u16 _u32 _u64. */
225 #define TYPES_all_integer(S, D) \
226 TYPES_all_signed (S, D), TYPES_all_unsigned (S, D)
230 _u8 _u16 _u32 _u64. */
231 #define TYPES_all_arith(S, D) \
232 TYPES_all_float (S, D), TYPES_all_integer (S, D)
237 _u8 _u16 _u32 _u64. */
238 #define TYPES_all_data(S, D) \
239 S (bf16), TYPES_all_arith (S, D)
242 #define TYPES_b(S, D) \
246 #define TYPES_c(S, D) \
250 #define TYPES_b_unsigned(S, D) \
255 #define TYPES_b_integer(S, D) \
256 S (s8), TYPES_b_unsigned (S, D)
260 #define TYPES_bh_integer(S, D) \
261 S (s8), S (s16), S (u8), S (u16)
264 #define TYPES_bs_unsigned(S, D) \
268 #define TYPES_bhs_signed(S, D) \
269 S (s8), S (s16), S (s32)
272 #define TYPES_bhs_unsigned(S, D) \
273 S (u8), S (u16), S (u32)
277 #define TYPES_bhs_integer(S, D) \
278 TYPES_bhs_signed (S, D), TYPES_bhs_unsigned (S, D)
284 #define TYPES_bhs_data(S, D) \
285 S (bf16), S (f16), S (f32), TYPES_bhs_integer (S, D)
287 /* _s16_s8 _s32_s16 _s64_s32
288 _u16_u8 _u32_u16 _u64_u32. */
289 #define TYPES_bhs_widen(S, D) \
290 D (s16, s8), D (s32, s16), D (s64, s32), \
291 D (u16, u8), D (u32, u16), D (u64, u32)
295 #define TYPES_h_integer(S, D) \
299 #define TYPES_hs_signed(S, D) \
304 #define TYPES_hs_integer(S, D) \
305 TYPES_hs_signed (S, D), S (u16), S (u32)
308 #define TYPES_hs_float(S, D) \
315 #define TYPES_hs_data(S, D) \
316 S (bf16), S (f16), S (f32), TYPES_hs_integer (S, D)
319 #define TYPES_hd_unsigned(S, D) \
322 /* _s16 _s32 _s64. */
323 #define TYPES_hsd_signed(S, D) \
324 S (s16), S (s32), S (s64)
328 #define TYPES_hsd_integer(S, D) \
329 TYPES_hsd_signed (S, D), S (u16), S (u32), S (u64)
332 #define TYPES_s_float(S, D) \
338 #define TYPES_s_float_hsd_integer(S, D) \
339 TYPES_s_float (S, D), TYPES_hsd_integer (S, D)
344 #define TYPES_s_float_sd_integer(S, D) \
345 TYPES_s_float (S, D), TYPES_sd_integer (S, D)
348 #define TYPES_s_signed(S, D) \
352 #define TYPES_s_unsigned(S, D) \
356 #define TYPES_s_integer(S, D) \
357 TYPES_s_signed (S, D), TYPES_s_unsigned (S, D)
360 #define TYPES_sd_signed(S, D) \
364 #define TYPES_sd_unsigned(S, D) \
369 #define TYPES_sd_integer(S, D) \
370 TYPES_sd_signed (S, D), TYPES_sd_unsigned (S, D)
375 #define TYPES_sd_data(S, D) \
376 S (f32), S (f64), TYPES_sd_integer (S, D)
381 #define TYPES_all_float_and_sd_integer(S, D) \
382 TYPES_all_float (S, D), TYPES_sd_integer (S, D)
385 #define TYPES_d_float(S, D) \
389 #define TYPES_d_unsigned(S, D) \
394 #define TYPES_d_integer(S, D) \
395 S (s64), TYPES_d_unsigned (S, D)
400 #define TYPES_d_data(S, D) \
401 TYPES_d_float (S, D), TYPES_d_integer (S, D)
403 /* All the type combinations allowed by svcvt. */
404 #define TYPES_cvt(S, D) \
405 D (f16, f32), D (f16, f64), \
406 D (f16, s16), D (f16, s32), D (f16, s64), \
407 D (f16, u16), D (f16, u32), D (f16, u64), \
409 D (f32, f16), D (f32, f64), \
410 D (f32, s32), D (f32, s64), \
411 D (f32, u32), D (f32, u64), \
413 D (f64, f16), D (f64, f32), \
414 D (f64, s32), D (f64, s64), \
415 D (f64, u32), D (f64, u64), \
418 D (s32, f16), D (s32, f32), D (s32, f64), \
419 D (s64, f16), D (s64, f32), D (s64, f64), \
422 D (u32, f16), D (u32, f32), D (u32, f64), \
423 D (u64, f16), D (u64, f32), D (u64, f64)
426 #define TYPES_cvt_bfloat(S, D) \
429 /* { _bf16 _f16 } x _f32. */
430 #define TYPES_cvt_h_s_float(S, D) \
431 D (bf16, f32), D (f16, f32)
435 #define TYPES_cvt_long(S, D) \
436 D (f32, f16), D (f64, f32)
439 #define TYPES_cvt_narrow_s(S, D) \
444 #define TYPES_cvt_narrow(S, D) \
445 D (f16, f32), TYPES_cvt_narrow_s (S, D)
447 /* { _s32 _u32 } x _f32
449 _f32 x { _s32 _u32 }. */
450 #define TYPES_cvt_s_s(S, D) \
456 /* { _s32 _s64 } x { _b8 _b16 _b32 _b64 }
458 #define TYPES_inc_dec_n1(D, A) \
459 D (A, b8), D (A, b16), D (A, b32), D (A, b64)
460 #define TYPES_inc_dec_n(S, D) \
461 TYPES_inc_dec_n1 (D, s32), \
462 TYPES_inc_dec_n1 (D, s64), \
463 TYPES_inc_dec_n1 (D, u32), \
464 TYPES_inc_dec_n1 (D, u64)
466 /* { _s16 _u16 } x _s32
469 #define TYPES_qcvt_x2(S, D) \
474 /* { _s8 _u8 } x _s32
481 #define TYPES_qcvt_x4(S, D) \
491 #define TYPES_qrshr_x2(S, D) \
496 #define TYPES_qrshru_x2(S, D) \
503 #define TYPES_qrshr_x4(S, D) \
511 #define TYPES_qrshru_x4(S, D) \
515 /* { _bf16 } { _bf16 }
516 { _f16 _f32 _f64 } { _f16 _f32 _f64 }
517 { _s8 _s16 _s32 _s64 } x { _s8 _s16 _s32 _s64 }
518 { _u8 _u16 _u32 _u64 } { _u8 _u16 _u32 _u64 }. */
519 #define TYPES_reinterpret1(D, A) \
521 D (A, f16), D (A, f32), D (A, f64), \
522 D (A, s8), D (A, s16), D (A, s32), D (A, s64), \
523 D (A, u8), D (A, u16), D (A, u32), D (A, u64)
524 #define TYPES_reinterpret(S, D) \
525 TYPES_reinterpret1 (D, bf16), \
526 TYPES_reinterpret1 (D, f16), \
527 TYPES_reinterpret1 (D, f32), \
528 TYPES_reinterpret1 (D, f64), \
529 TYPES_reinterpret1 (D, s8), \
530 TYPES_reinterpret1 (D, s16), \
531 TYPES_reinterpret1 (D, s32), \
532 TYPES_reinterpret1 (D, s64), \
533 TYPES_reinterpret1 (D, u8), \
534 TYPES_reinterpret1 (D, u16), \
535 TYPES_reinterpret1 (D, u32), \
536 TYPES_reinterpret1 (D, u64)
540 #define TYPES_reinterpret_b(S, D) \
544 /* { _b8 _b16 _b32 _b64 } x { _s32 _s64 }
546 #define TYPES_while1(D, bn) \
547 D (bn, s32), D (bn, s64), D (bn, u32), D (bn, u64)
548 #define TYPES_while(S, D) \
549 TYPES_while1 (D, b8), \
550 TYPES_while1 (D, b16), \
551 TYPES_while1 (D, b32), \
552 TYPES_while1 (D, b64)
554 /* { _b8 _b16 _b32 _b64 } x { _s64 }
556 #define TYPES_while_x(S, D) \
557 D (b8, s64), D (b8, u64), \
558 D (b16, s64), D (b16, u64), \
559 D (b32, s64), D (b32, u64), \
560 D (b64, s64), D (b64, u64)
562 /* { _c8 _c16 _c32 _c64 } x { _s64 }
564 #define TYPES_while_x_c(S, D) \
565 D (c8, s64), D (c8, u64), \
566 D (c16, s64), D (c16, u64), \
567 D (c32, s64), D (c32, u64), \
568 D (c64, s64), D (c64, u64)
573 #define TYPES_s_narrow_fsu(S, D) \
574 D (f32, f16), D (s32, s16), D (u32, u16)
576 /* _za8 _za16 _za32 _za64 _za128. */
577 #define TYPES_all_za(S, D) \
578 S (za8), S (za16), S (za32), S (za64), S (za128)
581 #define TYPES_d_za(S, D) \
584 /* { _za8 } x { _s8 _u8 }
586 { _za16 } x { _bf16 _f16 _s16 _u16 }
588 { _za32 } x { _f32 _s32 _u32 }
590 { _za64 } x { _f64 _s64 _u64 }. */
591 #define TYPES_za_bhsd_data(S, D) \
592 D (za8, s8), D (za8, u8), \
593 D (za16, bf16), D (za16, f16), D (za16, s16), D (za16, u16), \
594 D (za32, f32), D (za32, s32), D (za32, u32), \
595 D (za64, f64), D (za64, s64), D (za64, u64)
599 { _za128 } x { _bf16 }
601 { _s8 _s16 _s32 _s64 }
602 { _u8 _u16 _u32 _u64 }. */
604 #define TYPES_za_all_data(S, D) \
605 TYPES_za_bhsd_data (S, D), \
606 TYPES_reinterpret1 (D, za128)
609 #define TYPES_za_s_b_signed(S, D) \
613 #define TYPES_za_s_b_unsigned(S, D) \
616 /* _za32 x { _s8 _u8 }. */
617 #define TYPES_za_s_b_integer(S, D) \
618 D (za32, s8), D (za32, u8)
620 /* _za32 x { _s16 _u16 }. */
621 #define TYPES_za_s_h_integer(S, D) \
622 D (za32, s16), D (za32, u16)
624 /* _za32 x { _bf16 _f16 _s16 _u16 }. */
625 #define TYPES_za_s_h_data(S, D) \
626 D (za32, bf16), D (za32, f16), D (za32, s16), D (za32, u16)
629 #define TYPES_za_s_unsigned(S, D) \
632 /* _za32 x { _s32 _u32 }. */
633 #define TYPES_za_s_integer(S, D) \
634 D (za32, s32), D (za32, u32)
637 #define TYPES_za_s_float(S, D) \
640 /* _za32 x { _f32 _s32 _u32 }. */
641 #define TYPES_za_s_data(S, D) \
642 D (za32, f32), D (za32, s32), D (za32, u32)
644 /* _za64 x { _s16 _u16 }. */
645 #define TYPES_za_d_h_integer(S, D) \
646 D (za64, s16), D (za64, u16)
649 #define TYPES_za_d_float(S, D) \
652 /* _za64 x { _s64 _u64 }. */
653 #define TYPES_za_d_integer(S, D) \
654 D (za64, s64), D (za64, u64)
656 /* _za32 x { _s8 _u8 _bf16 _f16 _f32 }. */
657 #define TYPES_mop_base(S, D) \
658 D (za32, s8), D (za32, u8), D (za32, bf16), D (za32, f16), D (za32, f32)
661 #define TYPES_mop_base_signed(S, D) \
665 #define TYPES_mop_base_unsigned(S, D) \
668 /* _za64 x { _s16 _u16 }. */
669 #define TYPES_mop_i16i64(S, D) \
670 D (za64, s16), D (za64, u16)
673 #define TYPES_mop_i16i64_signed(S, D) \
677 #define TYPES_mop_i16i64_unsigned(S, D) \
681 #define TYPES_za(S, D) \
684 /* Describe a pair of type suffixes in which only the first is used. */
685 #define DEF_VECTOR_TYPE(X) { TYPE_SUFFIX_ ## X, NUM_TYPE_SUFFIXES }
687 /* Describe a pair of type suffixes in which both are used. */
688 #define DEF_DOUBLE_TYPE(X, Y) { TYPE_SUFFIX_ ## X, TYPE_SUFFIX_ ## Y }
690 /* Create an array that can be used in aarch64-sve-builtins.def to
691 select the type suffixes in TYPES_<NAME>. */
692 #define DEF_SVE_TYPES_ARRAY(NAME) \
693 static const type_suffix_pair types_##NAME[] = { \
694 TYPES_##NAME (DEF_VECTOR_TYPE, DEF_DOUBLE_TYPE), \
695 { NUM_TYPE_SUFFIXES, NUM_TYPE_SUFFIXES } \
698 /* For functions that don't take any type suffixes. */
699 static const type_suffix_pair types_none
[] = {
700 { NUM_TYPE_SUFFIXES
, NUM_TYPE_SUFFIXES
},
701 { NUM_TYPE_SUFFIXES
, NUM_TYPE_SUFFIXES
}
704 /* Create an array for each TYPES_<combination> macro above. */
705 DEF_SVE_TYPES_ARRAY (all_pred
);
706 DEF_SVE_TYPES_ARRAY (all_count
);
707 DEF_SVE_TYPES_ARRAY (all_pred_count
);
708 DEF_SVE_TYPES_ARRAY (all_float
);
709 DEF_SVE_TYPES_ARRAY (all_signed
);
710 DEF_SVE_TYPES_ARRAY (all_float_and_signed
);
711 DEF_SVE_TYPES_ARRAY (all_unsigned
);
712 DEF_SVE_TYPES_ARRAY (all_integer
);
713 DEF_SVE_TYPES_ARRAY (all_arith
);
714 DEF_SVE_TYPES_ARRAY (all_data
);
715 DEF_SVE_TYPES_ARRAY (b
);
716 DEF_SVE_TYPES_ARRAY (b_unsigned
);
717 DEF_SVE_TYPES_ARRAY (b_integer
);
718 DEF_SVE_TYPES_ARRAY (bh_integer
);
719 DEF_SVE_TYPES_ARRAY (bs_unsigned
);
720 DEF_SVE_TYPES_ARRAY (bhs_signed
);
721 DEF_SVE_TYPES_ARRAY (bhs_unsigned
);
722 DEF_SVE_TYPES_ARRAY (bhs_integer
);
723 DEF_SVE_TYPES_ARRAY (bhs_data
);
724 DEF_SVE_TYPES_ARRAY (bhs_widen
);
725 DEF_SVE_TYPES_ARRAY (c
);
726 DEF_SVE_TYPES_ARRAY (h_integer
);
727 DEF_SVE_TYPES_ARRAY (hs_signed
);
728 DEF_SVE_TYPES_ARRAY (hs_integer
);
729 DEF_SVE_TYPES_ARRAY (hs_float
);
730 DEF_SVE_TYPES_ARRAY (hs_data
);
731 DEF_SVE_TYPES_ARRAY (hd_unsigned
);
732 DEF_SVE_TYPES_ARRAY (hsd_signed
);
733 DEF_SVE_TYPES_ARRAY (hsd_integer
);
734 DEF_SVE_TYPES_ARRAY (s_float
);
735 DEF_SVE_TYPES_ARRAY (s_float_hsd_integer
);
736 DEF_SVE_TYPES_ARRAY (s_float_sd_integer
);
737 DEF_SVE_TYPES_ARRAY (s_signed
);
738 DEF_SVE_TYPES_ARRAY (s_unsigned
);
739 DEF_SVE_TYPES_ARRAY (s_integer
);
740 DEF_SVE_TYPES_ARRAY (sd_signed
);
741 DEF_SVE_TYPES_ARRAY (sd_unsigned
);
742 DEF_SVE_TYPES_ARRAY (sd_integer
);
743 DEF_SVE_TYPES_ARRAY (sd_data
);
744 DEF_SVE_TYPES_ARRAY (all_float_and_sd_integer
);
745 DEF_SVE_TYPES_ARRAY (d_float
);
746 DEF_SVE_TYPES_ARRAY (d_unsigned
);
747 DEF_SVE_TYPES_ARRAY (d_integer
);
748 DEF_SVE_TYPES_ARRAY (d_data
);
749 DEF_SVE_TYPES_ARRAY (cvt
);
750 DEF_SVE_TYPES_ARRAY (cvt_bfloat
);
751 DEF_SVE_TYPES_ARRAY (cvt_h_s_float
);
752 DEF_SVE_TYPES_ARRAY (cvt_long
);
753 DEF_SVE_TYPES_ARRAY (cvt_narrow_s
);
754 DEF_SVE_TYPES_ARRAY (cvt_narrow
);
755 DEF_SVE_TYPES_ARRAY (cvt_s_s
);
756 DEF_SVE_TYPES_ARRAY (inc_dec_n
);
757 DEF_SVE_TYPES_ARRAY (qcvt_x2
);
758 DEF_SVE_TYPES_ARRAY (qcvt_x4
);
759 DEF_SVE_TYPES_ARRAY (qrshr_x2
);
760 DEF_SVE_TYPES_ARRAY (qrshr_x4
);
761 DEF_SVE_TYPES_ARRAY (qrshru_x2
);
762 DEF_SVE_TYPES_ARRAY (qrshru_x4
);
763 DEF_SVE_TYPES_ARRAY (reinterpret
);
764 DEF_SVE_TYPES_ARRAY (reinterpret_b
);
765 DEF_SVE_TYPES_ARRAY (while);
766 DEF_SVE_TYPES_ARRAY (while_x
);
767 DEF_SVE_TYPES_ARRAY (while_x_c
);
768 DEF_SVE_TYPES_ARRAY (s_narrow_fsu
);
769 DEF_SVE_TYPES_ARRAY (all_za
);
770 DEF_SVE_TYPES_ARRAY (d_za
);
771 DEF_SVE_TYPES_ARRAY (za_bhsd_data
);
772 DEF_SVE_TYPES_ARRAY (za_all_data
);
773 DEF_SVE_TYPES_ARRAY (za_s_b_signed
);
774 DEF_SVE_TYPES_ARRAY (za_s_b_unsigned
);
775 DEF_SVE_TYPES_ARRAY (za_s_b_integer
);
776 DEF_SVE_TYPES_ARRAY (za_s_h_integer
);
777 DEF_SVE_TYPES_ARRAY (za_s_h_data
);
778 DEF_SVE_TYPES_ARRAY (za_s_unsigned
);
779 DEF_SVE_TYPES_ARRAY (za_s_integer
);
780 DEF_SVE_TYPES_ARRAY (za_s_float
);
781 DEF_SVE_TYPES_ARRAY (za_s_data
);
782 DEF_SVE_TYPES_ARRAY (za_d_h_integer
);
783 DEF_SVE_TYPES_ARRAY (za_d_float
);
784 DEF_SVE_TYPES_ARRAY (za_d_integer
);
785 DEF_SVE_TYPES_ARRAY (mop_base
);
786 DEF_SVE_TYPES_ARRAY (mop_base_signed
);
787 DEF_SVE_TYPES_ARRAY (mop_base_unsigned
);
788 DEF_SVE_TYPES_ARRAY (mop_i16i64
);
789 DEF_SVE_TYPES_ARRAY (mop_i16i64_signed
);
790 DEF_SVE_TYPES_ARRAY (mop_i16i64_unsigned
);
791 DEF_SVE_TYPES_ARRAY (za
);
793 static const group_suffix_index groups_none
[] = {
794 GROUP_none
, NUM_GROUP_SUFFIXES
797 static const group_suffix_index groups_x2
[] = { GROUP_x2
, NUM_GROUP_SUFFIXES
};
799 static const group_suffix_index groups_x12
[] = {
800 GROUP_none
, GROUP_x2
, NUM_GROUP_SUFFIXES
803 static const group_suffix_index groups_x4
[] = { GROUP_x4
, NUM_GROUP_SUFFIXES
};
805 static const group_suffix_index groups_x24
[] = {
806 GROUP_x2
, GROUP_x4
, NUM_GROUP_SUFFIXES
809 static const group_suffix_index groups_x124
[] = {
810 GROUP_none
, GROUP_x2
, GROUP_x4
, NUM_GROUP_SUFFIXES
813 static const group_suffix_index groups_x1234
[] = {
814 GROUP_none
, GROUP_x2
, GROUP_x3
, GROUP_x4
, NUM_GROUP_SUFFIXES
817 static const group_suffix_index groups_vg1x2
[] = {
818 GROUP_vg1x2
, NUM_GROUP_SUFFIXES
821 static const group_suffix_index groups_vg1x4
[] = {
822 GROUP_vg1x4
, NUM_GROUP_SUFFIXES
825 static const group_suffix_index groups_vg1x24
[] = {
826 GROUP_vg1x2
, GROUP_vg1x4
, NUM_GROUP_SUFFIXES
829 static const group_suffix_index groups_vg2
[] = {
830 GROUP_vg2x1
, GROUP_vg2x2
, GROUP_vg2x4
, NUM_GROUP_SUFFIXES
833 static const group_suffix_index groups_vg4
[] = {
834 GROUP_vg4x1
, GROUP_vg4x2
, GROUP_vg4x4
, NUM_GROUP_SUFFIXES
837 static const group_suffix_index groups_vg24
[] = {
838 GROUP_vg2
, GROUP_vg4
, NUM_GROUP_SUFFIXES
841 /* Used by functions that have no governing predicate. */
842 static const predication_index preds_none
[] = { PRED_none
, NUM_PREDS
};
844 /* Used by functions that have a governing predicate but do not have an
846 static const predication_index preds_implicit
[] = { PRED_implicit
, NUM_PREDS
};
848 /* Used by functions that only support "_m" predication. */
849 static const predication_index preds_m
[] = { PRED_m
, NUM_PREDS
};
851 /* Used by functions that allow merging and "don't care" predication,
852 but are not suitable for predicated MOVPRFX. */
853 static const predication_index preds_mx
[] = {
854 PRED_m
, PRED_x
, NUM_PREDS
857 /* Used by functions that allow merging, zeroing and "don't care"
859 static const predication_index preds_mxz
[] = {
860 PRED_m
, PRED_x
, PRED_z
, NUM_PREDS
863 /* Used by functions that have the mxz predicated forms above, and in addition
864 have an unpredicated form. */
865 static const predication_index preds_mxz_or_none
[] = {
866 PRED_m
, PRED_x
, PRED_z
, PRED_none
, NUM_PREDS
869 /* Used by functions that allow merging and zeroing predication but have
871 static const predication_index preds_mz
[] = { PRED_m
, PRED_z
, NUM_PREDS
};
873 /* Used by functions that have an unpredicated form and a _z predicated
875 static const predication_index preds_z_or_none
[] = {
876 PRED_z
, PRED_none
, NUM_PREDS
879 /* Used by (mostly predicate) functions that only support "_z" predication. */
880 static const predication_index preds_z
[] = { PRED_z
, NUM_PREDS
};
882 /* Used by SME instructions that always merge into ZA. */
883 static const predication_index preds_za_m
[] = { PRED_za_m
, NUM_PREDS
};
885 /* A list of all arm_sve.h functions. */
886 static CONSTEXPR
const function_group_info function_groups
[] = {
887 #define DEF_SVE_FUNCTION_GS(NAME, SHAPE, TYPES, GROUPS, PREDS) \
888 { #NAME, &functions::NAME, &shapes::SHAPE, types_##TYPES, groups_##GROUPS, \
889 preds_##PREDS, REQUIRED_EXTENSIONS },
890 #include "aarch64-sve-builtins.def"
893 /* A list of all arm_neon_sve_bridge.h ACLE functions. */
894 static CONSTEXPR
const function_group_info neon_sve_function_groups
[] = {
895 #define DEF_NEON_SVE_FUNCTION(NAME, SHAPE, TYPES, GROUPS, PREDS) \
896 { #NAME, &neon_sve_bridge_functions::NAME, &shapes::SHAPE, types_##TYPES, \
897 groups_##GROUPS, preds_##PREDS, 0 },
898 #include "aarch64-neon-sve-bridge-builtins.def"
901 /* A list of all arm_sme.h functions. */
902 static CONSTEXPR
const function_group_info sme_function_groups
[] = {
903 #define DEF_SME_FUNCTION_GS(NAME, SHAPE, TYPES, GROUPS, PREDS) \
904 { #NAME, &functions::NAME, &shapes::SHAPE, types_##TYPES, groups_##GROUPS, \
905 preds_##PREDS, REQUIRED_EXTENSIONS },
906 #define DEF_SME_ZA_FUNCTION_GS(NAME, SHAPE, TYPES, GROUPS, PREDS) \
907 { #NAME, &functions::NAME##_za, &shapes::SHAPE, types_##TYPES, \
908 groups_##GROUPS, preds_##PREDS, (REQUIRED_EXTENSIONS | AARCH64_FL_ZA_ON) },
909 #include "aarch64-sve-builtins-sme.def"
912 /* The scalar type associated with each vector type. */
913 extern GTY(()) tree scalar_types
[NUM_VECTOR_TYPES
+ 1];
914 tree scalar_types
[NUM_VECTOR_TYPES
+ 1];
916 /* The single-predicate and single-vector types, with their built-in
917 "__SV..._t" name. Allow an index of NUM_VECTOR_TYPES, which always
918 yields a null tree. */
919 static GTY(()) tree abi_vector_types
[NUM_VECTOR_TYPES
+ 1];
921 /* Same, but with the arm_sve.h "sv..._t" name. */
922 extern GTY(()) tree acle_vector_types
[MAX_TUPLE_SIZE
][NUM_VECTOR_TYPES
+ 1];
923 tree acle_vector_types
[MAX_TUPLE_SIZE
][NUM_VECTOR_TYPES
+ 1];
925 /* The svpattern enum type. */
926 extern GTY(()) tree acle_svpattern
;
929 /* The svprfop enum type. */
930 extern GTY(()) tree acle_svprfop
;
933 /* The list of all registered function decls, indexed by code. */
934 static GTY(()) vec
<registered_function
*, va_gc
> *registered_functions
;
936 /* Stores the starting function index for each pragma handler. */
937 static unsigned int initial_indexes
[NUM_PRAGMA_HANDLERS
];
939 /* All registered function decls, hashed on the function_instance
940 that they implement. This is used for looking up implementations of
941 overloaded functions. */
942 static hash_table
<registered_function_hasher
> *function_table
;
944 /* Index 0 maps all overloaded function names that we've registered so far to
945 their associated function_instances. Index 1 does the same for functions
946 that we've skipped over without registering. In both cases, the map keys
947 are IDENTIFIER_NODEs. */
948 static GTY(()) hash_map
<tree
, registered_function
*> *overload_names
[2];
950 /* Record that TYPE is an ABI-defined SVE type that contains NUM_ZR SVE vectors
951 and NUM_PR SVE predicates. MANGLED_NAME, if nonnull, is the ABI-defined
952 mangling of the type. ACLE_NAME is the <arm_sve.h> name of the type. */
954 add_sve_type_attribute (tree type
, unsigned int num_zr
, unsigned int num_pr
,
955 const char *mangled_name
, const char *acle_name
)
957 tree mangled_name_tree
958 = (mangled_name
? get_identifier (mangled_name
) : NULL_TREE
);
960 tree value
= tree_cons (NULL_TREE
, get_identifier (acle_name
), NULL_TREE
);
961 value
= tree_cons (NULL_TREE
, mangled_name_tree
, value
);
962 value
= tree_cons (NULL_TREE
, size_int (num_pr
), value
);
963 value
= tree_cons (NULL_TREE
, size_int (num_zr
), value
);
964 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("SVE type"), value
,
965 TYPE_ATTRIBUTES (type
));
968 /* If TYPE is an ABI-defined SVE type, return its attribute descriptor,
969 otherwise return null. */
971 lookup_sve_type_attribute (const_tree type
)
973 if (type
== error_mark_node
)
975 return lookup_attribute ("SVE type", TYPE_ATTRIBUTES (type
));
978 /* Force TYPE to be a sizeless type. */
980 make_type_sizeless (tree type
)
982 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("SVE sizeless type"),
983 NULL_TREE
, TYPE_ATTRIBUTES (type
));
986 /* Return true if TYPE is a sizeless type. */
988 sizeless_type_p (const_tree type
)
990 if (type
== error_mark_node
)
992 return lookup_attribute ("SVE sizeless type", TYPE_ATTRIBUTES (type
));
995 /* Return true if CANDIDATE is equivalent to MODEL_TYPE for overloading
998 matches_type_p (const_tree model_type
, const_tree candidate
)
1000 if (VECTOR_TYPE_P (model_type
))
1002 if (!VECTOR_TYPE_P (candidate
)
1003 || maybe_ne (TYPE_VECTOR_SUBPARTS (model_type
),
1004 TYPE_VECTOR_SUBPARTS (candidate
))
1005 || TYPE_MODE (model_type
) != TYPE_MODE (candidate
))
1008 model_type
= TREE_TYPE (model_type
);
1009 candidate
= TREE_TYPE (candidate
);
1011 return (candidate
!= error_mark_node
1012 && TYPE_MAIN_VARIANT (model_type
) == TYPE_MAIN_VARIANT (candidate
));
1015 /* If TYPE is a valid SVE element type, return the corresponding type
1016 suffix, otherwise return NUM_TYPE_SUFFIXES. */
1017 static type_suffix_index
1018 find_type_suffix_for_scalar_type (const_tree type
)
1020 /* A linear search should be OK here, since the code isn't hot and
1021 the number of types is only small. */
1022 for (unsigned int suffix_i
= 0; suffix_i
< NUM_TYPE_SUFFIXES
; ++suffix_i
)
1023 if (type_suffixes
[suffix_i
].vector_p
)
1025 vector_type_index vector_i
= type_suffixes
[suffix_i
].vector_type
;
1026 if (matches_type_p (scalar_types
[vector_i
], type
))
1027 return type_suffix_index (suffix_i
);
1029 return NUM_TYPE_SUFFIXES
;
1032 /* Return the implicit group suffix for intrinsics that operate on NVECTORS
1034 static group_suffix_index
1035 num_vectors_to_group (unsigned int nvectors
)
1039 case 1: return GROUP_none
;
1040 case 2: return GROUP_x2
;
1041 case 3: return GROUP_x3
;
1042 case 4: return GROUP_x4
;
1047 /* Return the vector type associated with TYPE. */
1049 get_vector_type (sve_type type
)
1051 auto vector_type
= type_suffixes
[type
.type
].vector_type
;
1052 return acle_vector_types
[type
.num_vectors
- 1][vector_type
];
1055 /* If FNDECL is an SVE builtin, return its function instance, otherwise
1057 const function_instance
*
1058 lookup_fndecl (tree fndecl
)
1060 if (!fndecl_built_in_p (fndecl
, BUILT_IN_MD
))
1063 unsigned int code
= DECL_MD_FUNCTION_CODE (fndecl
);
1064 if ((code
& AARCH64_BUILTIN_CLASS
) != AARCH64_BUILTIN_SVE
)
1067 unsigned int subcode
= code
>> AARCH64_BUILTIN_SHIFT
;
1068 return &(*registered_functions
)[subcode
]->instance
;
1072 /* Report that LOCATION has a call to FNDECL in which argument ARGNO
1073 was not an integer constant expression. ARGNO counts from zero. */
1075 report_non_ice (location_t location
, tree fndecl
, unsigned int argno
)
1077 error_at (location
, "argument %d of %qE must be an integer constant"
1078 " expression", argno
+ 1, fndecl
);
1081 /* Report that LOCATION has a call to FNDECL in which argument ARGNO has
1082 the value ACTUAL, whereas the function requires a value in the range
1083 [MIN, MAX]. ARGNO counts from zero. */
1085 report_out_of_range (location_t location
, tree fndecl
, unsigned int argno
,
1086 HOST_WIDE_INT actual
, HOST_WIDE_INT min
,
1090 error_at (location
, "passing %wd to argument %d of %qE, which expects"
1091 " the value %wd", actual
, argno
+ 1, fndecl
, min
);
1093 error_at (location
, "passing %wd to argument %d of %qE, which expects"
1094 " a value in the range [%wd, %wd]", actual
, argno
+ 1, fndecl
,
1098 /* Report that LOCATION has a call to FNDECL in which argument ARGNO has
1099 the value ACTUAL, whereas the function requires either VALUE0 or
1100 VALUE1. ARGNO counts from zero. */
1102 report_neither_nor (location_t location
, tree fndecl
, unsigned int argno
,
1103 HOST_WIDE_INT actual
, HOST_WIDE_INT value0
,
1104 HOST_WIDE_INT value1
)
1106 error_at (location
, "passing %wd to argument %d of %qE, which expects"
1107 " either %wd or %wd", actual
, argno
+ 1, fndecl
, value0
, value1
);
1110 /* Report that LOCATION has a call to FNDECL in which argument ARGNO has
1111 the value ACTUAL, whereas the function requires one of VALUE0..3.
1112 ARGNO counts from zero. */
1114 report_not_one_of (location_t location
, tree fndecl
, unsigned int argno
,
1115 HOST_WIDE_INT actual
, HOST_WIDE_INT value0
,
1116 HOST_WIDE_INT value1
, HOST_WIDE_INT value2
,
1117 HOST_WIDE_INT value3
)
1119 error_at (location
, "passing %wd to argument %d of %qE, which expects"
1120 " %wd, %wd, %wd or %wd", actual
, argno
+ 1, fndecl
, value0
, value1
,
1124 /* Report that LOCATION has a call to FNDECL in which argument ARGNO has
1125 the value ACTUAL, whereas the function requires a valid value of
1126 enum type ENUMTYPE. ARGNO counts from zero. */
1128 report_not_enum (location_t location
, tree fndecl
, unsigned int argno
,
1129 HOST_WIDE_INT actual
, tree enumtype
)
1131 error_at (location
, "passing %wd to argument %d of %qE, which expects"
1132 " a valid %qT value", actual
, argno
+ 1, fndecl
, enumtype
);
1135 /* Try to fold constant arguments ARG1 and ARG2 using the given tree_code.
1136 Operations are not treated as overflowing. */
1138 aarch64_const_binop (enum tree_code code
, tree arg1
, tree arg2
)
1140 if (poly_int_tree_p (arg1
) && poly_int_tree_p (arg2
))
1142 poly_wide_int poly_res
;
1143 tree type
= TREE_TYPE (arg1
);
1144 signop sign
= TYPE_SIGN (type
);
1145 wi::overflow_type overflow
= wi::OVF_NONE
;
1147 /* Return 0 for division by 0, like SDIV and UDIV do. */
1148 if (code
== TRUNC_DIV_EXPR
&& integer_zerop (arg2
))
1151 if (!poly_int_binop (poly_res
, code
, arg1
, arg2
, sign
, &overflow
))
1153 return force_fit_type (type
, poly_res
, false,
1154 TREE_OVERFLOW (arg1
) | TREE_OVERFLOW (arg2
));
1159 /* Return a hash code for a function_instance. */
1161 function_instance::hash () const
1164 /* BASE uniquely determines BASE_NAME, so we don't need to hash both. */
1167 h
.add_int (mode_suffix_id
);
1168 h
.add_int (type_suffix_ids
[0]);
1169 h
.add_int (type_suffix_ids
[1]);
1170 h
.add_int (group_suffix_id
);
1175 /* Return a set of CP_* flags that describe what the function could do,
1176 taking the command-line flags into account. */
1178 function_instance::call_properties () const
1180 unsigned int flags
= base
->call_properties (*this);
1182 /* -fno-trapping-math means that we can assume any FP exceptions
1183 are not user-visible. */
1184 if (!flag_trapping_math
)
1185 flags
&= ~CP_RAISE_FP_EXCEPTIONS
;
1190 /* Return true if calls to the function could read some form of
1193 function_instance::reads_global_state_p () const
1195 unsigned int flags
= call_properties ();
1197 /* Preserve any dependence on rounding mode, flush to zero mode, etc.
1198 There is currently no way of turning this off; in particular,
1199 -fno-rounding-math (which is the default) means that we should make
1200 the usual assumptions about rounding mode, which for intrinsics means
1201 acting as the instructions do. */
1202 if (flags
& CP_READ_FPCR
)
1205 /* Handle direct reads of global state. */
1206 return flags
& (CP_READ_MEMORY
| CP_READ_FFR
| CP_READ_ZA
| CP_READ_ZT0
);
1209 /* Return true if calls to the function could modify some form of
1212 function_instance::modifies_global_state_p () const
1214 unsigned int flags
= call_properties ();
1216 /* Preserve any exception state written back to the FPCR,
1217 unless -fno-trapping-math says this is unnecessary. */
1218 if (flags
& CP_RAISE_FP_EXCEPTIONS
)
1221 /* Treat prefetches as modifying global state, since that's the
1222 only means we have of keeping them in their correct position. */
1223 if (flags
& CP_PREFETCH_MEMORY
)
1226 /* Handle direct modifications of global state. */
1227 return flags
& (CP_WRITE_MEMORY
| CP_WRITE_FFR
| CP_WRITE_ZA
| CP_WRITE_ZT0
);
1230 /* Return true if calls to the function could raise a signal. */
1232 function_instance::could_trap_p () const
1234 unsigned int flags
= call_properties ();
1236 /* Handle functions that could raise SIGFPE. */
1237 if (flags
& CP_RAISE_FP_EXCEPTIONS
)
1240 /* Handle functions that could raise SIGBUS or SIGSEGV. */
1241 if (flags
& (CP_READ_MEMORY
| CP_WRITE_MEMORY
))
1248 registered_function_hasher::hash (value_type value
)
1250 return value
->instance
.hash ();
1254 registered_function_hasher::equal (value_type value
, const compare_type
&key
)
1256 return value
->instance
== key
;
1259 sve_switcher::sve_switcher (aarch64_feature_flags flags
)
1260 : aarch64_simd_switcher (AARCH64_FL_F16
| AARCH64_FL_SVE
| flags
)
1262 /* Changing the ISA flags and have_regs_of_mode should be enough here.
1263 We shouldn't need to pay the compile-time cost of a full target
1265 m_old_maximum_field_alignment
= maximum_field_alignment
;
1266 maximum_field_alignment
= 0;
1268 memcpy (m_old_have_regs_of_mode
, have_regs_of_mode
,
1269 sizeof (have_regs_of_mode
));
1270 for (int i
= 0; i
< NUM_MACHINE_MODES
; ++i
)
1271 if (aarch64_sve_mode_p ((machine_mode
) i
))
1272 have_regs_of_mode
[i
] = true;
1275 sve_switcher::~sve_switcher ()
1277 memcpy (have_regs_of_mode
, m_old_have_regs_of_mode
,
1278 sizeof (have_regs_of_mode
));
1279 maximum_field_alignment
= m_old_maximum_field_alignment
;
1282 function_builder::function_builder (handle_pragma_index pragma_index
,
1283 bool function_nulls
)
1285 m_overload_type
= build_function_type (void_type_node
, void_list_node
);
1286 m_direct_overloads
= lang_GNU_CXX () || in_lto_p
;
1288 if (initial_indexes
[pragma_index
] == 0)
1290 unsigned int index
= vec_safe_length (registered_functions
);
1291 initial_indexes
[pragma_index
] = index
;
1294 m_function_index
= initial_indexes
[pragma_index
];
1295 m_function_nulls
= function_nulls
;
1297 gcc_obstack_init (&m_string_obstack
);
1300 function_builder::~function_builder ()
1302 obstack_free (&m_string_obstack
, NULL
);
1305 /* Add NAME to the end of the function name being built. */
1307 function_builder::append_name (const char *name
)
1309 obstack_grow (&m_string_obstack
, name
, strlen (name
));
1312 /* Zero-terminate and complete the function name being built. */
1314 function_builder::finish_name ()
1316 obstack_1grow (&m_string_obstack
, 0);
1317 return (char *) obstack_finish (&m_string_obstack
);
1320 /* Return the overloaded or full function name for INSTANCE; OVERLOADED_P
1321 selects which. Allocate the string on m_string_obstack; the caller
1322 must use obstack_free to free it after use. */
1324 function_builder::get_name (const function_instance
&instance
,
1327 /* __arm_* functions are listed as arm_*, so that the associated GCC
1328 code is not in the implementation namespace. */
1329 if (strncmp (instance
.base_name
, "arm_", 4) == 0)
1331 append_name (instance
.base_name
);
1333 switch (instance
.displacement_units ())
1339 append_name ("_offset");
1342 case UNITS_elements
:
1343 append_name ("_index");
1347 append_name ("_vnum");
1351 append_name (instance
.mode_suffix ().string
);
1352 for (unsigned int i
= 0; i
< 2; ++i
)
1353 if (!overloaded_p
|| instance
.shape
->explicit_type_suffix_p (i
))
1354 append_name (instance
.type_suffix (i
).string
);
1355 if (!overloaded_p
|| instance
.shape
->explicit_group_suffix_p ())
1356 append_name (instance
.group_suffix ().string
);
1357 append_name (pred_suffixes
[instance
.pred
]);
1358 return finish_name ();
1361 /* Add attribute NAME to ATTRS. */
1363 add_attribute (const char *name
, tree attrs
)
1365 return tree_cons (get_identifier (name
), NULL_TREE
, attrs
);
1368 /* Add attribute NS::NAME to ATTRS. */
1370 add_attribute (const char *ns
, const char *name
, tree value
, tree attrs
)
1372 return tree_cons (build_tree_list (get_identifier (ns
),
1373 get_identifier (name
)),
1377 /* Attribute arm::NAME describes shared state that is an input if IS_IN
1378 and an output if IS_OUT. Check whether a call with call properties
1379 CALL_FLAGS needs such an attribute. Add it to in-progress attribute
1380 list ATTRS if so. Return the new attribute list. */
1382 add_shared_state_attribute (const char *name
, bool is_in
, bool is_out
,
1383 unsigned int call_flags
, tree attrs
)
1385 struct state_flag_info
1388 unsigned int read_flag
;
1389 unsigned int write_flag
;
1391 static state_flag_info state_flags
[] =
1393 { "za", CP_READ_ZA
, CP_WRITE_ZA
},
1394 { "zt0", CP_READ_ZT0
, CP_WRITE_ZT0
}
1397 tree args
= NULL_TREE
;
1398 for (const auto &state_flag
: state_flags
)
1400 auto all_flags
= state_flag
.read_flag
| state_flag
.write_flag
;
1401 auto these_flags
= ((is_in
? state_flag
.read_flag
: 0)
1402 | (is_out
? state_flag
.write_flag
: 0));
1403 if ((call_flags
& all_flags
) == these_flags
)
1405 tree value
= build_string (strlen (state_flag
.name
) + 1,
1407 args
= tree_cons (NULL_TREE
, value
, args
);
1411 attrs
= add_attribute ("arm", name
, args
, attrs
);
1415 /* Return the appropriate function attributes for INSTANCE, which requires
1416 the feature flags in REQUIRED_EXTENSIONS. */
1418 function_builder::get_attributes (const function_instance
&instance
,
1419 aarch64_feature_flags required_extensions
)
1421 tree attrs
= NULL_TREE
;
1423 if (required_extensions
& AARCH64_FL_SM_ON
)
1424 attrs
= add_attribute ("arm", "streaming", NULL_TREE
, attrs
);
1425 else if (!(required_extensions
& AARCH64_FL_SM_OFF
))
1426 attrs
= add_attribute ("arm", "streaming_compatible", NULL_TREE
, attrs
);
1428 attrs
= add_shared_state_attribute ("in", true, false,
1429 instance
.call_properties (), attrs
);
1430 attrs
= add_shared_state_attribute ("out", false, true,
1431 instance
.call_properties (), attrs
);
1432 attrs
= add_shared_state_attribute ("inout", true, true,
1433 instance
.call_properties (), attrs
);
1435 if (!instance
.modifies_global_state_p ())
1437 if (instance
.reads_global_state_p ())
1438 attrs
= add_attribute ("pure", attrs
);
1440 attrs
= add_attribute ("const", attrs
);
1443 if (!flag_non_call_exceptions
|| !instance
.could_trap_p ())
1444 attrs
= add_attribute ("nothrow", attrs
);
1446 return add_attribute ("leaf", attrs
);
1449 /* Add a function called NAME with type FNTYPE and attributes ATTRS.
1450 INSTANCE describes what the function does and OVERLOADED_P indicates
1451 whether it is overloaded. REQUIRED_EXTENSIONS are the set of
1452 architecture extensions that the function requires. */
1453 registered_function
&
1454 function_builder::add_function (const function_instance
&instance
,
1455 const char *name
, tree fntype
, tree attrs
,
1456 aarch64_feature_flags required_extensions
,
1460 unsigned int length
= vec_safe_length (registered_functions
);
1461 unsigned int code
= (m_function_index
<< AARCH64_BUILTIN_SHIFT
) | AARCH64_BUILTIN_SVE
;
1462 /* We need to be able to generate placeholders to enusre that we have a
1463 consistent numbering scheme for function codes between the C and C++
1464 frontends, so that everything ties up in LTO.
1466 Currently, tree-streamer-in.cc:unpack_ts_function_decl_value_fields
1467 validates that tree nodes returned by TARGET_BUILTIN_DECL are non-NULL and
1468 some node other than error_mark_node. This is a holdover from when builtin
1469 decls were streamed by code rather than by value.
1471 Ultimately, we should be able to remove this validation of BUILT_IN_MD
1472 nodes and remove the target hook. For now, however, we need to appease the
1473 validation and return a non-NULL, non-error_mark_node node, so we
1474 arbitrarily choose integer_zero_node. */
1475 tree decl
= placeholder_p
|| m_function_nulls
1477 : simulate_builtin_function_decl (input_location
, name
, fntype
,
1480 registered_function
&rfn
= *ggc_alloc
<registered_function
> ();
1481 rfn
.instance
= instance
;
1483 rfn
.required_extensions
= required_extensions
;
1484 rfn
.overloaded_p
= overloaded_p
;
1485 if (m_function_index
>= length
)
1486 vec_safe_push (registered_functions
, &rfn
);
1488 (*registered_functions
)[m_function_index
] = &rfn
;
1494 /* Add a built-in function for INSTANCE, with the argument types given
1495 by ARGUMENT_TYPES and the return type given by RETURN_TYPE.
1496 REQUIRED_EXTENSIONS are the set of architecture extensions that the
1497 function requires. FORCE_DIRECT_OVERLOADS is true if there is a
1498 one-to-one mapping between "short" and "full" names, and if standard
1499 overload resolution therefore isn't necessary. */
1502 add_unique_function (const function_instance
&instance
,
1504 vec
<tree
> &argument_types
,
1505 aarch64_feature_flags required_extensions
,
1506 bool force_direct_overloads
)
1508 /* Add the function under its full (unique) name. */
1509 char *name
= get_name (instance
, false);
1510 tree fntype
= build_function_type_array (return_type
,
1511 argument_types
.length (),
1512 argument_types
.address ());
1513 tree attrs
= get_attributes (instance
, required_extensions
);
1514 registered_function
&rfn
= add_function (instance
, name
, fntype
, attrs
,
1515 required_extensions
, false, false);
1517 /* Enter the function into the hash table. */
1518 if (!m_function_nulls
)
1520 hashval_t hash
= instance
.hash ();
1521 registered_function
**rfn_slot
1522 = function_table
->find_slot_with_hash (instance
, hash
, INSERT
);
1523 gcc_assert (!*rfn_slot
);
1527 /* Also add the function under its overloaded alias, if we want
1528 a separate decl for each instance of an overloaded function. */
1529 char *overload_name
= get_name (instance
, true);
1530 if (strcmp (name
, overload_name
) != 0)
1532 /* Attribute lists shouldn't be shared. */
1533 tree attrs
= get_attributes (instance
, required_extensions
);
1534 bool placeholder_p
= !(m_direct_overloads
|| force_direct_overloads
);
1535 add_function (instance
, overload_name
, fntype
, attrs
,
1536 required_extensions
, false, placeholder_p
);
1539 obstack_free (&m_string_obstack
, name
);
1542 /* Add one function decl for INSTANCE, to be used with manual overload
1543 resolution. REQUIRED_EXTENSIONS are the set of architecture extensions
1544 that the function requires.
1546 For simplicity, deal with duplicate attempts to add the same function,
1547 including cases in which the new function requires more features than
1548 the original one did. In that case we'll check whether the required
1549 features are available as part of resolving the function to the
1550 relevant unique function. */
1553 add_overloaded_function (const function_instance
&instance
,
1554 aarch64_feature_flags required_extensions
)
1556 auto &name_map
= overload_names
[m_function_nulls
];
1558 name_map
= hash_map
<tree
, registered_function
*>::create_ggc ();
1560 char *name
= get_name (instance
, true);
1561 tree id
= get_identifier (name
);
1562 if (registered_function
**map_value
= name_map
->get (id
))
1563 gcc_assert ((*map_value
)->instance
== instance
1564 && ((*map_value
)->required_extensions
1565 & ~required_extensions
) == 0);
1568 registered_function
&rfn
1569 = add_function (instance
, name
, m_overload_type
, NULL_TREE
,
1570 required_extensions
, true, m_direct_overloads
);
1571 name_map
->put (id
, &rfn
);
1573 obstack_free (&m_string_obstack
, name
);
1576 /* If we are using manual overload resolution, add one function decl
1577 for each overloaded function in GROUP. Take the function base name
1578 from GROUP and the mode from MODE. */
1580 function_builder::add_overloaded_functions (const function_group_info
&group
,
1581 mode_suffix_index mode
)
1583 bool explicit_type0
= (*group
.shape
)->explicit_type_suffix_p (0);
1584 bool explicit_type1
= (*group
.shape
)->explicit_type_suffix_p (1);
1585 bool explicit_group
= (*group
.shape
)->explicit_group_suffix_p ();
1586 auto add_function
= [&](const type_suffix_pair
&types
,
1587 group_suffix_index group_suffix_id
,
1590 function_instance
instance (group
.base_name
, *group
.base
,
1591 *group
.shape
, mode
, types
,
1592 group_suffix_id
, group
.preds
[pi
]);
1593 add_overloaded_function (instance
, group
.required_extensions
);
1596 auto add_group_suffix
= [&](group_suffix_index group_suffix_id
,
1599 if (mode
== MODE_single
1600 && group_suffixes
[group_suffix_id
].vectors_per_tuple
== 1)
1603 if (!explicit_type0
&& !explicit_type1
)
1604 /* Deal with the common case in which there is one overloaded
1605 function for all type combinations. */
1606 add_function (types_none
[0], group_suffix_id
, pi
);
1608 for (unsigned int ti
= 0; group
.types
[ti
][0] != NUM_TYPE_SUFFIXES
;
1611 /* Stub out the types that are determined by overload
1613 type_suffix_pair types
= {
1614 explicit_type0
? group
.types
[ti
][0] : NUM_TYPE_SUFFIXES
,
1615 explicit_type1
? group
.types
[ti
][1] : NUM_TYPE_SUFFIXES
1617 add_function (types
, group_suffix_id
, pi
);
1621 for (unsigned int pi
= 0; group
.preds
[pi
] != NUM_PREDS
; ++pi
)
1623 for (unsigned int gi
= 0; group
.groups
[gi
] != NUM_GROUP_SUFFIXES
; ++gi
)
1624 add_group_suffix (group
.groups
[gi
], pi
);
1626 add_group_suffix (GROUP_none
, pi
);
1629 /* Register all the functions in GROUP. */
1631 function_builder::register_function_group (const function_group_info
&group
)
1633 (*group
.shape
)->build (*this, group
);
1636 function_call_info::function_call_info (location_t location_in
,
1637 const function_instance
&instance_in
,
1639 : function_instance (instance_in
), location (location_in
), fndecl (fndecl_in
)
1643 function_resolver::function_resolver (location_t location
,
1644 const function_instance
&instance
,
1645 tree fndecl
, vec
<tree
, va_gc
> &arglist
)
1646 : function_call_info (location
, instance
, fndecl
), m_arglist (arglist
)
1650 /* Return the <stdint.h> name associated with TYPE. Using the <stdint.h>
1651 name should be more user-friendly than the underlying canonical type,
1652 since it makes the signedness and bitwidth explicit. */
1654 function_resolver::get_scalar_type_name (type_suffix_index type
)
1656 return vector_types
[type_suffixes
[type
].vector_type
].acle_name
+ 2;
1659 /* Return the type of argument I, or error_mark_node if it isn't
1662 function_resolver::get_argument_type (unsigned int i
)
1664 tree arg
= m_arglist
[i
];
1665 return arg
== error_mark_node
? arg
: TREE_TYPE (arg
);
1668 /* Return true if argument I is some form of scalar value. */
1670 function_resolver::scalar_argument_p (unsigned int i
)
1672 tree type
= get_argument_type (i
);
1673 return (INTEGRAL_TYPE_P (type
)
1674 /* Allow pointer types, leaving the frontend to warn where
1676 || POINTER_TYPE_P (type
)
1677 || SCALAR_FLOAT_TYPE_P (type
));
1680 /* Report that argument ARGNO was expected to have NUM_VECTORS vectors.
1681 TYPE is the type that ARGNO actually has. */
1683 function_resolver::report_incorrect_num_vectors (unsigned int argno
,
1685 unsigned int num_vectors
)
1687 if (num_vectors
== 1)
1688 error_at (location
, "passing %qT to argument %d of %qE, which"
1689 " expects a single SVE vector rather than a tuple",
1690 get_vector_type (type
), argno
+ 1, fndecl
);
1691 else if (type
.num_vectors
== 1
1692 && type
.type
!= TYPE_SUFFIX_b
)
1693 /* num_vectors is always != 1, so the singular isn't needed. */
1694 error_n (location
, num_vectors
, "%qT%d%qE%d",
1695 "passing single vector %qT to argument %d"
1696 " of %qE, which expects a tuple of %d vectors",
1697 get_vector_type (type
), argno
+ 1, fndecl
, num_vectors
);
1699 /* num_vectors is always != 1, so the singular isn't needed. */
1700 error_n (location
, num_vectors
, "%qT%d%qE%d",
1701 "passing %qT to argument %d of %qE, which"
1702 " expects a tuple of %d vectors", get_vector_type (type
),
1703 argno
+ 1, fndecl
, num_vectors
);
1706 /* Report that arguments FIRST_ARGNO and ARGNO have different numbers
1707 of vectors, but are required to have the same number of vectors.
1708 FIRST_TYPE and TYPE are the types that arguments FIRST_ARGNO and
1709 ARGNO actually have. */
1711 function_resolver::report_mismatched_num_vectors (unsigned int first_argno
,
1712 sve_type first_type
,
1716 /* If the tuple size is implied by the group suffix, and if the first
1717 type had the right number of vectors, treat argument ARGNO as being
1718 individually wrong, rather than wrong in relation to FIRST_ARGNO. */
1719 if (group_suffix_id
!= GROUP_none
1720 && first_type
.num_vectors
== vectors_per_tuple ())
1722 report_incorrect_num_vectors (argno
, type
, first_type
.num_vectors
);
1726 /* Make sure that FIRST_TYPE itself is sensible before using it
1727 as a basis for an error message. */
1728 if (resolve_to (mode_suffix_id
, first_type
) == error_mark_node
)
1731 if (type
.num_vectors
!= 1 && first_type
.num_vectors
== 1)
1732 error_at (location
, "passing tuple %qT to argument %d of %qE after"
1733 " passing single vector %qT to argument %d",
1734 get_vector_type (type
), argno
+ 1, fndecl
,
1735 get_vector_type (first_type
), first_argno
+ 1);
1736 else if (type
.num_vectors
== 1 && first_type
.num_vectors
!= 1)
1737 error_at (location
, "passing single vector %qT to argument %d"
1738 " of %qE after passing tuple %qT to argument %d",
1739 get_vector_type (type
), argno
+ 1, fndecl
,
1740 get_vector_type (first_type
), first_argno
+ 1);
1742 error_at (location
, "passing mismatched tuple types %qT and %qT"
1743 " to arguments %d and %d of %qE",
1744 get_vector_type (first_type
), get_vector_type (type
),
1745 first_argno
+ 1, argno
+ 1, fndecl
);
1748 /* Report that the function has no form that takes type TYPE.
1749 Return error_mark_node. */
1751 function_resolver::report_no_such_form (sve_type type
)
1753 error_at (location
, "%qE has no form that takes %qT arguments",
1754 fndecl
, get_vector_type (type
));
1755 return error_mark_node
;
1758 /* Silently check whether there is an instance of the function with the
1759 mode suffix given by MODE, the type suffixes given by TYPE0 and TYPE1,
1760 and the group suffix given by GROUP. Return its function decl if so,
1761 otherwise return null. */
1763 function_resolver::lookup_form (mode_suffix_index mode
,
1764 type_suffix_index type0
,
1765 type_suffix_index type1
,
1766 group_suffix_index group
)
1768 type_suffix_pair types
= { type0
, type1
};
1769 function_instance
instance (base_name
, base
, shape
, mode
, types
,
1771 registered_function
*rfn
1772 = function_table
->find_with_hash (instance
, instance
.hash ());
1773 return rfn
? rfn
->decl
: NULL_TREE
;
1776 /* Silently check whether there is an instance of the function that has the
1777 mode suffix given by MODE and the type and group suffixes implied by TYPE.
1778 If the overloaded function has an explicit first type suffix (like
1779 conversions do), TYPE describes the implicit second type suffix.
1780 Otherwise, TYPE describes the only type suffix.
1782 Return the decl of the function if it exists, otherwise return null. */
1784 function_resolver::lookup_form (mode_suffix_index mode
, sve_type type
)
1786 type_suffix_index type0
= type_suffix_ids
[0];
1787 type_suffix_index type1
= type_suffix_ids
[1];
1788 (type0
== NUM_TYPE_SUFFIXES
? type0
: type1
) = type
.type
;
1790 group_suffix_index group
= group_suffix_id
;
1791 if (group
== GROUP_none
&& type
.num_vectors
!= vectors_per_tuple ())
1792 group
= num_vectors_to_group (type
.num_vectors
);
1794 return lookup_form (mode
, type0
, type1
, group
);
1797 /* Resolve the function to one with the mode suffix given by MODE, the
1798 type suffixes given by TYPE0 and TYPE1, and group suffix given by
1799 GROUP. Return its function decl on success, otherwise report an
1800 error and return error_mark_node. */
1802 function_resolver::resolve_to (mode_suffix_index mode
,
1803 type_suffix_index type0
,
1804 type_suffix_index type1
,
1805 group_suffix_index group
)
1807 tree res
= lookup_form (mode
, type0
, type1
, group
);
1810 if (type1
== NUM_TYPE_SUFFIXES
)
1811 return report_no_such_form (type0
);
1812 if (type0
== type_suffix_ids
[0])
1813 return report_no_such_form (type1
);
1814 error_at (location
, "%qE has no form that takes %qT and %qT arguments",
1815 fndecl
, get_vector_type (type0
), get_vector_type (type1
));
1816 return error_mark_node
;
1821 /* Resolve the function to one that has the suffixes associated with MODE
1822 and TYPE; see lookup_form for how TYPE is interpreted. Return the
1823 function decl on success, otherwise report an error and return
1826 function_resolver::resolve_to (mode_suffix_index mode
, sve_type type
)
1828 if (tree res
= lookup_form (mode
, type
))
1831 return report_no_such_form (type
);
1834 /* Like resolve_to, but used for a conversion function with the following
1837 - The function has an explicit first type suffix.
1838 - The elements of the argument (which has type TYPE) might be narrower
1839 or wider than the elements of the return type.
1840 - The return type has enough vectors to represent the converted value
1842 - The group suffix describes the wider of the argument type and the
1845 function_resolver::resolve_conversion (mode_suffix_index mode
, sve_type type
)
1847 auto ret_type
= type_suffix_ids
[0];
1848 unsigned int num_ret_vectors
= (type
.num_vectors
1849 * type_suffixes
[ret_type
].element_bits
1850 / type_suffixes
[type
.type
].element_bits
);
1851 if (num_ret_vectors
== 1
1852 || num_ret_vectors
== 2
1853 || num_ret_vectors
== 4)
1855 unsigned int num_vectors
= MAX (num_ret_vectors
, type
.num_vectors
);
1856 if (tree res
= lookup_form (mode
, { type
.type
, num_vectors
}))
1859 return report_no_such_form (type
);
1862 /* Require argument ARGNO to be an svbool_t or svcount_t predicate.
1863 Return its type on success, otherwise report an error and return
1864 NUM_VECTOR_TYPES. */
1866 function_resolver::infer_predicate_type (unsigned int argno
)
1868 tree actual
= get_argument_type (argno
);
1869 if (actual
== error_mark_node
)
1870 return NUM_VECTOR_TYPES
;
1872 for (auto index
: { VECTOR_TYPE_svbool_t
, VECTOR_TYPE_svcount_t
})
1873 if (matches_type_p (acle_vector_types
[0][index
], actual
))
1876 error_at (location
, "passing %qT to argument %d of %qE, which expects"
1877 " an %qs or %qs", actual
, argno
+ 1, fndecl
, "svbool_t",
1879 return NUM_VECTOR_TYPES
;
1882 /* Require argument ARGNO to be a 32-bit or 64-bit scalar integer type.
1883 Return the associated type suffix on success, otherwise report an
1884 error and return NUM_TYPE_SUFFIXES. */
1886 function_resolver::infer_integer_scalar_type (unsigned int argno
)
1888 tree actual
= get_argument_type (argno
);
1889 if (actual
== error_mark_node
)
1890 return NUM_TYPE_SUFFIXES
;
1892 /* Allow enums and booleans to decay to integers, for compatibility
1893 with C++ overloading rules. */
1894 if (INTEGRAL_TYPE_P (actual
))
1896 bool uns_p
= TYPE_UNSIGNED (actual
);
1897 /* Honor the usual integer promotions, so that resolution works
1898 in the same way as for C++. */
1899 if (TYPE_PRECISION (actual
) < 32)
1900 return TYPE_SUFFIX_s32
;
1901 if (TYPE_PRECISION (actual
) == 32)
1902 return uns_p
? TYPE_SUFFIX_u32
: TYPE_SUFFIX_s32
;
1903 if (TYPE_PRECISION (actual
) == 64)
1904 return uns_p
? TYPE_SUFFIX_u64
: TYPE_SUFFIX_s64
;
1907 error_at (location
, "passing %qT to argument %d of %qE, which expects"
1908 " a 32-bit or 64-bit integer type", actual
, argno
+ 1, fndecl
);
1909 return NUM_TYPE_SUFFIXES
;
1912 /* Return arguments ARGNO and ARGNO + 1 to be 64-bit scalar integers
1913 of the same signedness, or be a combination that converts unambiguously
1914 to such a pair. Return the associated type suffix if they are,
1915 otherwise report an error and return NUM_TYPE_SUFFIXES. */
1917 function_resolver::infer_64bit_scalar_integer_pair (unsigned int argno
)
1919 /* Require two scalar integers, with one having 64 bits and the other
1920 one being no bigger. */
1921 tree types
[] = { get_argument_type (argno
), get_argument_type (argno
+ 1) };
1922 if (!INTEGRAL_TYPE_P (types
[0])
1923 || !INTEGRAL_TYPE_P (types
[1])
1924 || MAX (TYPE_PRECISION (types
[0]), TYPE_PRECISION (types
[1])) != 64)
1926 error_at (location
, "passing %qT and %qT to arguments %d and %d of %qE,"
1927 " which expects a pair of 64-bit integers", types
[0], types
[1],
1928 argno
+ 1, argno
+ 2, fndecl
);
1929 return NUM_TYPE_SUFFIXES
;
1932 /* Allow signed integers smaller than int64_t to be paired with an int64_t.
1933 Allow unsigned integers smaller than uint64_t to be paired with any
1935 for (int i
= 0; i
< 2; ++i
)
1937 if (TYPE_PRECISION (types
[i
]) != 64)
1940 if (TYPE_UNSIGNED (types
[1 - i
]) != TYPE_UNSIGNED (types
[i
]))
1942 if (TYPE_PRECISION (types
[1 - i
]) == 64)
1944 if (!TYPE_UNSIGNED (types
[1 - i
]))
1947 return TYPE_UNSIGNED (types
[i
]) ? TYPE_SUFFIX_u64
: TYPE_SUFFIX_s64
;
1950 error_at (location
, "passing mismatched integer types %qT and %qT"
1951 " to arguments %d and %d of %qE", types
[0], types
[1],
1952 argno
+ 1, argno
+ 2, fndecl
);
1953 return NUM_TYPE_SUFFIXES
;
1956 /* Require argument ARGNO to be a pointer to a scalar type that has a
1957 corresponding type suffix. Return that type suffix on success,
1958 otherwise report an error and return NUM_TYPE_SUFFIXES.
1959 GATHER_SCATTER_P is true if the function is a gather/scatter
1960 operation, and so requires a pointer to 32-bit or 64-bit data. */
1962 function_resolver::infer_pointer_type (unsigned int argno
,
1963 bool gather_scatter_p
)
1965 tree actual
= get_argument_type (argno
);
1966 if (actual
== error_mark_node
)
1967 return NUM_TYPE_SUFFIXES
;
1969 if (TREE_CODE (actual
) != POINTER_TYPE
)
1971 error_at (location
, "passing %qT to argument %d of %qE, which"
1972 " expects a pointer type", actual
, argno
+ 1, fndecl
);
1973 if (VECTOR_TYPE_P (actual
) && gather_scatter_p
)
1974 inform (location
, "an explicit type suffix is needed"
1975 " when using a vector of base addresses");
1976 return NUM_TYPE_SUFFIXES
;
1979 tree target
= TREE_TYPE (actual
);
1980 type_suffix_index type
= find_type_suffix_for_scalar_type (target
);
1981 if (type
== NUM_TYPE_SUFFIXES
)
1983 error_at (location
, "passing %qT to argument %d of %qE, but %qT is not"
1984 " a valid SVE element type", actual
, argno
+ 1, fndecl
,
1985 build_qualified_type (target
, 0));
1986 return NUM_TYPE_SUFFIXES
;
1988 unsigned int bits
= type_suffixes
[type
].element_bits
;
1989 if (gather_scatter_p
&& bits
!= 32 && bits
!= 64)
1991 error_at (location
, "passing %qT to argument %d of %qE, which"
1992 " expects a pointer to 32-bit or 64-bit elements",
1993 actual
, argno
+ 1, fndecl
);
1994 return NUM_TYPE_SUFFIXES
;
2000 /* If TYPE is an SVE predicate or vector type, or a tuple of such a type,
2001 return the associated sve_type, otherwise return an invalid sve_type. */
2003 find_sve_type (const_tree type
)
2005 /* A linear search should be OK here, since the code isn't hot and
2006 the number of types is only small. */
2007 for (unsigned int size_i
= 0; size_i
< MAX_TUPLE_SIZE
; ++size_i
)
2008 for (unsigned int suffix_i
= 0; suffix_i
< NUM_TYPE_SUFFIXES
; ++suffix_i
)
2010 vector_type_index type_i
= type_suffixes
[suffix_i
].vector_type
;
2011 tree this_type
= acle_vector_types
[size_i
][type_i
];
2012 if (this_type
&& matches_type_p (this_type
, type
))
2013 return { type_suffix_index (suffix_i
), size_i
+ 1 };
2019 /* Require argument ARGNO to be an SVE type (i.e. something that can be
2020 represented by sve_type). Return the (valid) type if it is, otherwise
2021 report an error and return an invalid type. */
2023 function_resolver::infer_sve_type (unsigned int argno
)
2025 tree actual
= get_argument_type (argno
);
2026 if (actual
== error_mark_node
)
2029 if (sve_type type
= find_sve_type (actual
))
2032 if (scalar_argument_p (argno
))
2033 error_at (location
, "passing %qT to argument %d of %qE, which"
2034 " expects an SVE type rather than a scalar type",
2035 actual
, argno
+ 1, fndecl
);
2037 error_at (location
, "passing %qT to argument %d of %qE, which"
2038 " expects an SVE type",
2039 actual
, argno
+ 1, fndecl
);
2043 /* Require argument ARGNO to be a single vector or a tuple of NUM_VECTORS
2044 vectors; NUM_VECTORS is 1 for the former. Return the associated type
2045 on success. Report an error on failure. */
2047 function_resolver::infer_vector_or_tuple_type (unsigned int argno
,
2048 unsigned int num_vectors
)
2050 auto type
= infer_sve_type (argno
);
2054 if (type
.num_vectors
== num_vectors
)
2057 report_incorrect_num_vectors (argno
, type
, num_vectors
);
2061 /* Require argument ARGNO to have some form of vector type. Return the
2062 associated type suffix on success, using TYPE_SUFFIX_b for predicates.
2063 Report an error and return NUM_TYPE_SUFFIXES on failure. */
2065 function_resolver::infer_vector_type (unsigned int argno
)
2067 if (auto type
= infer_vector_or_tuple_type (argno
, 1))
2069 return NUM_TYPE_SUFFIXES
;
2072 /* Like infer_vector_type, but also require the type to be integral. */
2074 function_resolver::infer_integer_vector_type (unsigned int argno
)
2076 type_suffix_index type
= infer_vector_type (argno
);
2077 if (type
== NUM_TYPE_SUFFIXES
)
2080 if (!type_suffixes
[type
].integer_p
)
2082 error_at (location
, "passing %qT to argument %d of %qE, which"
2083 " expects a vector of integers", get_argument_type (argno
),
2085 return NUM_TYPE_SUFFIXES
;
2091 /* Require argument ARGNO to have some form of NEON128 vector type. Return the
2092 associated type suffix on success.
2093 Report an error and return NUM_TYPE_SUFFIXES on failure. */
2095 function_resolver::infer_neon128_vector_type (unsigned int argno
)
2097 tree actual
= get_argument_type (argno
);
2098 if (actual
== error_mark_node
)
2099 return NUM_TYPE_SUFFIXES
;
2101 for (unsigned int suffix_i
= 0; suffix_i
< NUM_TYPE_SUFFIXES
; ++suffix_i
)
2103 int neon_index
= type_suffixes
[suffix_i
].neon128_type
;
2104 if (neon_index
!= ARM_NEON_H_TYPES_LAST
)
2106 tree type
= aarch64_simd_types
[neon_index
].itype
;
2107 if (type
&& matches_type_p (type
, actual
))
2108 return type_suffix_index (suffix_i
);
2112 error_at (location
, "passing %qT to argument %d of %qE, which"
2113 " expects a 128 bit NEON vector type", actual
, argno
+ 1, fndecl
);
2114 return NUM_TYPE_SUFFIXES
;
2118 /* Like infer_vector_type, but also require the type to be an unsigned
2121 function_resolver::infer_unsigned_vector_type (unsigned int argno
)
2123 type_suffix_index type
= infer_vector_type (argno
);
2124 if (type
== NUM_TYPE_SUFFIXES
)
2127 if (!type_suffixes
[type
].unsigned_p
)
2129 error_at (location
, "passing %qT to argument %d of %qE, which"
2130 " expects a vector of unsigned integers",
2131 get_argument_type (argno
), argno
+ 1, fndecl
);
2132 return NUM_TYPE_SUFFIXES
;
2138 /* Like infer_vector_type, but also require the element size to be
2141 function_resolver::infer_sd_vector_type (unsigned int argno
)
2143 type_suffix_index type
= infer_vector_type (argno
);
2144 if (type
== NUM_TYPE_SUFFIXES
)
2147 unsigned int bits
= type_suffixes
[type
].element_bits
;
2148 if (bits
!= 32 && bits
!= 64)
2150 error_at (location
, "passing %qT to argument %d of %qE, which"
2151 " expects a vector of 32-bit or 64-bit elements",
2152 get_argument_type (argno
), argno
+ 1, fndecl
);
2153 return NUM_TYPE_SUFFIXES
;
2159 /* If the function operates on tuples of vectors, require argument ARGNO to be
2160 a tuple with the appropriate number of vectors, otherwise require it to be
2161 a single vector. Return the associated type on success. Report an error
2164 function_resolver::infer_tuple_type (unsigned int argno
)
2166 return infer_vector_or_tuple_type (argno
, vectors_per_tuple ());
2169 /* PRED_TYPE is the type of a governing predicate argument and DATA_TYPE
2170 is the type of an argument that it predicates. Require the two types
2171 to "agree": svcount_t must be used for multiple vectors and svbool_t
2174 Return true if they do agree, otherwise report an error and
2176 bool function_resolver::
2177 require_matching_predicate_type (vector_type_index pred_type
,
2180 if (pred_type
== VECTOR_TYPE_svbool_t
&& data_type
.num_vectors
== 1)
2183 if (pred_type
== VECTOR_TYPE_svcount_t
&& data_type
.num_vectors
!= 1)
2186 /* Make sure that FIRST_TYPE itself is sensible before using it
2187 as a basis for an error message. */
2188 if (resolve_to (mode_suffix_id
, data_type
) == error_mark_node
)
2191 if (data_type
.num_vectors
> 1)
2192 error_at (location
, "operations on multiple vectors must be predicated"
2193 " by %qs rather than %qs", "svcount_t", "svbool_t");
2195 error_at (location
, "operations on single vectors must be predicated"
2196 " by %qs rather than %qs", "svbool_t", "svcount_t");
2200 /* Require argument ARGNO to be a vector or scalar argument. Return true
2201 if it is, otherwise report an appropriate error. */
2203 function_resolver::require_vector_or_scalar_type (unsigned int argno
)
2205 tree actual
= get_argument_type (argno
);
2206 if (actual
== error_mark_node
)
2209 if (!scalar_argument_p (argno
) && !VECTOR_TYPE_P (actual
))
2211 error_at (location
, "passing %qT to argument %d of %qE, which"
2212 " expects a vector or scalar type", actual
, argno
+ 1, fndecl
);
2219 /* Require argument ARGNO to have vector type TYPE, in cases where this
2220 requirement holds for all uses of the function. Return true if the
2221 argument has the right form, otherwise report an appropriate error. */
2223 function_resolver::require_vector_type (unsigned int argno
,
2224 vector_type_index type
)
2226 tree expected
= acle_vector_types
[0][type
];
2227 tree actual
= get_argument_type (argno
);
2228 if (actual
== error_mark_node
)
2231 if (!matches_type_p (expected
, actual
))
2233 error_at (location
, "passing %qT to argument %d of %qE, which"
2234 " expects %qT", actual
, argno
+ 1, fndecl
, expected
);
2240 /* Like require_vector_type, but TYPE is inferred from argument FIRST_ARGNO
2241 rather than being a fixed part of the function signature. This changes
2242 the nature of the error messages. */
2244 function_resolver::require_matching_vector_type (unsigned int argno
,
2245 unsigned int first_argno
,
2248 sve_type new_type
= infer_sve_type (argno
);
2252 if (type
.num_vectors
!= new_type
.num_vectors
)
2254 report_mismatched_num_vectors (first_argno
, type
, argno
, new_type
);
2258 if (type
!= new_type
)
2260 error_at (location
, "passing %qT to argument %d of %qE, but"
2261 " argument %d had type %qT",
2262 get_vector_type (new_type
), argno
+ 1, fndecl
,
2263 first_argno
+ 1, get_vector_type (type
));
2269 /* Require argument ARGNO to be a vector or tuple type with the following
2272 - the type class must be the same as FIRST_TYPE's if EXPECTED_TCLASS
2273 is SAME_TYPE_CLASS, otherwise it must be EXPECTED_TCLASS itself.
2275 - the element size must be:
2277 - the same as FIRST_TYPE's if EXPECTED_BITS == SAME_SIZE
2278 - half of FIRST_TYPE's if EXPECTED_BITS == HALF_SIZE
2279 - a quarter of FIRST_TYPE's if EXPECTED_BITS == QUARTER_SIZE
2280 - EXPECTED_BITS itself otherwise
2282 - the number of vectors must be the same as FIRST_TYPE's if
2283 EXPECTED_NUM_VECTORS is zero, otherwise it must be EXPECTED_NUM_VECTORS.
2285 Return true if the argument has the required type, otherwise report
2286 an appropriate error.
2288 FIRST_ARGNO is the first argument that is known to have type FIRST_TYPE.
2289 Usually it comes before ARGNO, but sometimes it is more natural to resolve
2290 arguments out of order.
2292 If the required properties depend on FIRST_TYPE then both FIRST_ARGNO and
2293 ARGNO contribute to the resolution process. If the required properties
2294 are fixed, only FIRST_ARGNO contributes to the resolution process.
2296 This function is a bit of a Swiss army knife. The complication comes
2297 from trying to give good error messages when FIRST_ARGNO and ARGNO are
2298 inconsistent, since either of them might be wrong. */
2299 bool function_resolver::
2300 require_derived_vector_type (unsigned int argno
,
2301 unsigned int first_argno
,
2302 sve_type first_type
,
2303 type_class_index expected_tclass
,
2304 unsigned int expected_bits
,
2305 unsigned int expected_num_vectors
)
2307 /* If the type needs to match FIRST_ARGNO exactly, use the preferred
2308 error message for that case. */
2309 if (expected_tclass
== SAME_TYPE_CLASS
2310 && expected_bits
== SAME_SIZE
2311 && expected_num_vectors
== 0)
2313 /* There's no need to resolve this case out of order. */
2314 gcc_assert (argno
> first_argno
);
2315 return require_matching_vector_type (argno
, first_argno
, first_type
);
2318 /* Use FIRST_TYPE to get the expected type class and element size. */
2319 auto &first_type_suffix
= type_suffixes
[first_type
.type
];
2320 type_class_index orig_expected_tclass
= expected_tclass
;
2321 if (expected_tclass
== NUM_TYPE_CLASSES
)
2322 expected_tclass
= first_type_suffix
.tclass
;
2324 unsigned int orig_expected_bits
= expected_bits
;
2325 if (expected_bits
== SAME_SIZE
)
2326 expected_bits
= first_type_suffix
.element_bits
;
2327 else if (expected_bits
== HALF_SIZE
)
2328 expected_bits
= first_type_suffix
.element_bits
/ 2;
2329 else if (expected_bits
== QUARTER_SIZE
)
2330 expected_bits
= first_type_suffix
.element_bits
/ 4;
2332 unsigned int orig_expected_num_vectors
= expected_num_vectors
;
2333 if (expected_num_vectors
== 0)
2334 expected_num_vectors
= first_type
.num_vectors
;
2336 /* If the expected type doesn't depend on FIRST_TYPE at all,
2337 just check for the fixed choice of vector type. */
2338 if (expected_tclass
== orig_expected_tclass
2339 && expected_bits
== orig_expected_bits
2340 && orig_expected_num_vectors
== 1)
2342 const type_suffix_info
&expected_suffix
2343 = type_suffixes
[find_type_suffix (expected_tclass
, expected_bits
)];
2344 return require_vector_type (argno
, expected_suffix
.vector_type
);
2347 /* Require the argument to be some form of SVE vector type,
2348 without being specific about the type of vector we want. */
2349 sve_type actual_type
= infer_sve_type (argno
);
2353 if (actual_type
.num_vectors
!= expected_num_vectors
)
2355 if (orig_expected_num_vectors
== 0)
2356 report_mismatched_num_vectors (first_argno
, first_type
,
2357 argno
, actual_type
);
2359 report_incorrect_num_vectors (argno
, actual_type
,
2360 expected_num_vectors
);
2364 if (orig_expected_tclass
== SAME_TYPE_CLASS
2365 && orig_expected_bits
== SAME_SIZE
)
2367 if (actual_type
.type
== first_type
.type
)
2370 if (first_type
.num_vectors
> 1)
2371 error_at (location
, "passing %qT to argument %d of %qE, but"
2372 " argument %d was a tuple of %qT",
2373 get_vector_type (actual_type
), argno
+ 1, fndecl
,
2374 first_argno
+ 1, get_vector_type (first_type
.type
));
2376 error_at (location
, "passing %qT to argument %d of %qE, but"
2377 " argument %d had type %qT",
2378 get_vector_type (actual_type
), argno
+ 1, fndecl
,
2379 first_argno
+ 1, get_vector_type (first_type
));
2383 /* Exit now if we got the right type. */
2384 auto &actual_type_suffix
= type_suffixes
[actual_type
.type
];
2385 bool tclass_ok_p
= (actual_type_suffix
.tclass
== expected_tclass
);
2386 bool size_ok_p
= (actual_type_suffix
.element_bits
== expected_bits
);
2387 if (tclass_ok_p
&& size_ok_p
)
2390 /* First look for cases in which the actual type contravenes a fixed
2391 size requirement, without having to refer to FIRST_TYPE. */
2392 if (!size_ok_p
&& expected_bits
== orig_expected_bits
)
2394 if (expected_num_vectors
== 1)
2395 error_at (location
, "passing %qT to argument %d of %qE, which"
2396 " expects a vector of %d-bit elements",
2397 get_vector_type (actual_type
), argno
+ 1, fndecl
,
2400 error_at (location
, "passing %qT to argument %d of %qE, which"
2401 " expects vectors of %d-bit elements",
2402 get_vector_type (actual_type
), argno
+ 1, fndecl
,
2407 /* Likewise for a fixed type class requirement. This is only ever
2408 needed for signed and unsigned types, so don't create unnecessary
2409 translation work for other type classes. */
2410 if (!tclass_ok_p
&& orig_expected_tclass
== TYPE_signed
)
2412 if (expected_num_vectors
== 1)
2413 error_at (location
, "passing %qT to argument %d of %qE, which"
2414 " expects a vector of signed integers",
2415 get_vector_type (actual_type
), argno
+ 1, fndecl
);
2417 /* Translation note: could also be written "expects a tuple of
2418 signed integer vectors". */
2419 error_at (location
, "passing %qT to argument %d of %qE, which"
2420 " expects vectors of signed integers",
2421 get_vector_type (actual_type
), argno
+ 1, fndecl
);
2424 if (!tclass_ok_p
&& orig_expected_tclass
== TYPE_unsigned
)
2426 if (expected_num_vectors
== 1)
2427 error_at (location
, "passing %qT to argument %d of %qE, which"
2428 " expects a vector of unsigned integers",
2429 get_vector_type (actual_type
), argno
+ 1, fndecl
);
2431 /* Translation note: could also be written "expects a tuple of
2432 unsigned integer vectors". */
2433 error_at (location
, "passing %qT to argument %d of %qE, which"
2434 " expects vectors of unsigned integers",
2435 get_vector_type (actual_type
), argno
+ 1, fndecl
);
2439 /* Make sure that FIRST_TYPE itself is sensible before using it
2440 as a basis for an error message. */
2441 if (resolve_to (mode_suffix_id
, first_type
) == error_mark_node
)
2444 /* If the arguments have consistent type classes, but a link between
2445 the sizes has been broken, try to describe the error in those terms. */
2446 if (tclass_ok_p
&& orig_expected_bits
== SAME_SIZE
)
2448 if (argno
< first_argno
)
2450 std::swap (argno
, first_argno
);
2451 std::swap (actual_type
, first_type
);
2453 error_at (location
, "arguments %d and %d of %qE must have the"
2454 " same element size, but the values passed here have type"
2455 " %qT and %qT respectively", first_argno
+ 1, argno
+ 1,
2456 fndecl
, get_vector_type (first_type
),
2457 get_vector_type (actual_type
));
2461 /* Likewise in reverse: look for cases in which the sizes are consistent
2462 but a link between the type classes has been broken. */
2464 && orig_expected_tclass
== SAME_TYPE_CLASS
2465 && first_type_suffix
.integer_p
2466 && actual_type_suffix
.integer_p
)
2468 if (argno
< first_argno
)
2470 std::swap (argno
, first_argno
);
2471 std::swap (actual_type
, first_type
);
2473 error_at (location
, "arguments %d and %d of %qE must have the"
2474 " same signedness, but the values passed here have type"
2475 " %qT and %qT respectively", first_argno
+ 1, argno
+ 1,
2476 fndecl
, get_vector_type (first_type
),
2477 get_vector_type (actual_type
));
2481 /* The two arguments are wildly inconsistent. */
2482 type_suffix_index expected_type
2483 = find_type_suffix (expected_tclass
, expected_bits
);
2484 error_at (location
, "passing %qT instead of the expected %qT to argument"
2485 " %d of %qE, after passing %qT to argument %d",
2486 get_vector_type (actual_type
), get_vector_type (expected_type
),
2487 argno
+ 1, fndecl
, get_argument_type (first_argno
),
2492 /* Require argument ARGNO to match argument FIRST_ARGNO, which was inferred
2493 to be a pointer to a scalar element of type TYPE. */
2495 function_resolver::require_matching_pointer_type (unsigned int argno
,
2496 unsigned int first_argno
,
2497 type_suffix_index type
)
2499 type_suffix_index new_type
= infer_pointer_type (argno
);
2500 if (new_type
== NUM_TYPE_SUFFIXES
)
2503 if (type
!= new_type
)
2505 error_at (location
, "passing %qT to argument %d of %qE, but"
2506 " argument %d had type %qT", get_argument_type (argno
),
2507 argno
+ 1, fndecl
, first_argno
+ 1,
2508 get_argument_type (first_argno
));
2514 /* Require argument ARGNO to be a (possibly variable) scalar, using EXPECTED
2515 as the name of its expected type. Return true if the argument has the
2516 right form, otherwise report an appropriate error. */
2518 function_resolver::require_scalar_type (unsigned int argno
,
2519 const char *expected
)
2521 if (!scalar_argument_p (argno
))
2524 error_at (location
, "passing %qT to argument %d of %qE, which"
2525 " expects %qs", get_argument_type (argno
), argno
+ 1,
2532 /* Require argument ARGNO to be a nonscalar type, given that it has already
2533 passed require_vector_or_scalar_type. Return true if it is, otherwise
2534 report an error. This is used when two sets of instructions share the
2535 same overloaded function and one accepts scalars while the other
2538 function_resolver::require_nonscalar_type (unsigned int argno
)
2540 if (scalar_argument_p (argno
))
2542 error_at (location
, "passing %qT to argument %d of %qE, which"
2543 " does not accept scalars for this combination of arguments",
2544 get_argument_type (argno
), argno
+ 1, fndecl
);
2550 /* Require argument ARGNO to be some form of pointer, without being specific
2551 about its target type. Return true if the argument has the right form,
2552 otherwise report an appropriate error. */
2554 function_resolver::require_pointer_type (unsigned int argno
)
2556 if (!scalar_argument_p (argno
))
2558 error_at (location
, "passing %qT to argument %d of %qE, which"
2559 " expects a scalar pointer", get_argument_type (argno
),
2566 /* Argument FIRST_ARGNO is a scalar with type EXPECTED_TYPE, and argument
2567 ARGNO should be consistent with it. Return true if it is, otherwise
2568 report an appropriate error. */
2569 bool function_resolver::
2570 require_matching_integer_scalar_type (unsigned int argno
,
2571 unsigned int first_argno
,
2572 type_suffix_index expected_type
)
2574 type_suffix_index actual_type
= infer_integer_scalar_type (argno
);
2575 if (actual_type
== NUM_TYPE_SUFFIXES
)
2578 if (actual_type
== expected_type
)
2581 error_at (location
, "call to %qE is ambiguous; argument %d has type"
2582 " %qs but argument %d has type %qs", fndecl
,
2583 first_argno
+ 1, get_scalar_type_name (expected_type
),
2584 argno
+ 1, get_scalar_type_name (actual_type
));
2588 /* Require argument ARGNO to be a (possibly variable) scalar, expecting it
2589 to have the following properties:
2591 - the type class must be the same as for type suffix 0 if EXPECTED_TCLASS
2592 is SAME_TYPE_CLASS, otherwise it must be EXPECTED_TCLASS itself.
2594 - the element size must be the same as for type suffix 0 if EXPECTED_BITS
2595 is SAME_TYPE_SIZE, otherwise it must be EXPECTED_BITS itself.
2597 Return true if the argument is valid, otherwise report an appropriate error.
2599 Note that we don't check whether the scalar type actually has the required
2600 properties, since that's subject to implicit promotions and conversions.
2601 Instead we just use the expected properties to tune the error message. */
2602 bool function_resolver::
2603 require_derived_scalar_type (unsigned int argno
,
2604 type_class_index expected_tclass
,
2605 unsigned int expected_bits
)
2607 gcc_assert (expected_tclass
== SAME_TYPE_CLASS
2608 || expected_tclass
== TYPE_signed
2609 || expected_tclass
== TYPE_unsigned
);
2611 /* If the expected type doesn't depend on the type suffix at all,
2612 just check for the fixed choice of scalar type. */
2613 if (expected_tclass
!= SAME_TYPE_CLASS
&& expected_bits
!= SAME_SIZE
)
2615 type_suffix_index expected_type
2616 = find_type_suffix (expected_tclass
, expected_bits
);
2617 return require_scalar_type (argno
, get_scalar_type_name (expected_type
));
2620 if (scalar_argument_p (argno
))
2623 if (expected_tclass
== SAME_TYPE_CLASS
)
2624 /* It doesn't really matter whether the element is expected to be
2625 the same size as type suffix 0. */
2626 error_at (location
, "passing %qT to argument %d of %qE, which"
2627 " expects a scalar element", get_argument_type (argno
),
2630 /* It doesn't seem useful to distinguish between signed and unsigned
2632 error_at (location
, "passing %qT to argument %d of %qE, which"
2633 " expects a scalar integer", get_argument_type (argno
),
2638 /* Require argument ARGNO to be suitable for an integer constant expression.
2639 Return true if it is, otherwise report an appropriate error.
2641 function_checker checks whether the argument is actually constant and
2642 has a suitable range. The reason for distinguishing immediate arguments
2643 here is because it provides more consistent error messages than
2644 require_scalar_type would. */
2646 function_resolver::require_integer_immediate (unsigned int argno
)
2648 if (!scalar_argument_p (argno
))
2650 report_non_ice (location
, fndecl
, argno
);
2656 /* Require argument ARGNO to be a vector base in a gather-style address.
2657 Return its type on success, otherwise return NUM_VECTOR_TYPES. */
2659 function_resolver::infer_vector_base_type (unsigned int argno
)
2661 type_suffix_index type
= infer_vector_type (argno
);
2662 if (type
== NUM_TYPE_SUFFIXES
)
2663 return NUM_VECTOR_TYPES
;
2665 if (type
== TYPE_SUFFIX_u32
|| type
== TYPE_SUFFIX_u64
)
2666 return type_suffixes
[type
].vector_type
;
2668 error_at (location
, "passing %qT to argument %d of %qE, which"
2669 " expects %qs or %qs", get_argument_type (argno
),
2670 argno
+ 1, fndecl
, "svuint32_t", "svuint64_t");
2671 return NUM_VECTOR_TYPES
;
2674 /* Require argument ARGNO to be a vector displacement in a gather-style
2675 address. Return its type on success, otherwise return NUM_VECTOR_TYPES. */
2677 function_resolver::infer_vector_displacement_type (unsigned int argno
)
2679 type_suffix_index type
= infer_integer_vector_type (argno
);
2680 if (type
== NUM_TYPE_SUFFIXES
)
2681 return NUM_VECTOR_TYPES
;
2683 if (type_suffixes
[type
].integer_p
2684 && (type_suffixes
[type
].element_bits
== 32
2685 || type_suffixes
[type
].element_bits
== 64))
2686 return type_suffixes
[type
].vector_type
;
2688 error_at (location
, "passing %qT to argument %d of %qE, which"
2689 " expects a vector of 32-bit or 64-bit integers",
2690 get_argument_type (argno
), argno
+ 1, fndecl
);
2691 return NUM_VECTOR_TYPES
;
2694 /* Require argument ARGNO to be a vector displacement in a gather-style
2695 address. There are three possible uses:
2697 - for loading into elements of type TYPE (when LOAD_P is true)
2698 - for storing from elements of type TYPE (when LOAD_P is false)
2699 - for prefetching data (when TYPE is NUM_TYPE_SUFFIXES)
2701 The overloaded function's mode suffix determines the units of the
2702 displacement (bytes for "_offset", elements for "_index").
2704 Return the associated mode on success, otherwise report an error
2705 and return MODE_none. */
2707 function_resolver::resolve_sv_displacement (unsigned int argno
,
2708 type_suffix_index type
,
2711 if (type
== NUM_TYPE_SUFFIXES
)
2713 /* For prefetches, the base is a void pointer and the displacement
2714 can be any valid offset or index type. */
2715 vector_type_index displacement_vector_type
2716 = infer_vector_displacement_type (argno
);
2717 if (displacement_vector_type
== NUM_VECTOR_TYPES
)
2720 mode_suffix_index mode
= find_mode_suffix (NUM_VECTOR_TYPES
,
2721 displacement_vector_type
,
2722 displacement_units ());
2723 gcc_assert (mode
!= MODE_none
);
2727 unsigned int required_bits
= type_suffixes
[type
].element_bits
;
2728 if (required_bits
== 32
2729 && displacement_units () == UNITS_elements
2730 && !lookup_form (MODE_s32index
, type
)
2731 && !lookup_form (MODE_u32index
, type
))
2733 if (lookup_form (MODE_u32base_index
, type
))
2735 if (type_suffix_ids
[0] == NUM_TYPE_SUFFIXES
)
2737 gcc_assert (!load_p
);
2738 error_at (location
, "when storing %qT, %qE requires a vector"
2739 " base and a scalar index", get_vector_type (type
),
2743 error_at (location
, "%qE requires a vector base and a scalar"
2747 error_at (location
, "%qE does not support 32-bit vector type %qT",
2748 fndecl
, get_vector_type (type
));
2752 /* Check for some form of vector type, without naming any in particular
2753 as being expected. */
2754 type_suffix_index displacement_type
= infer_vector_type (argno
);
2755 if (displacement_type
== NUM_TYPE_SUFFIXES
)
2758 /* If the displacement type is consistent with the data vector type,
2759 try to find the associated mode suffix. This will fall through
2760 for non-integral displacement types. */
2761 if (type_suffixes
[displacement_type
].element_bits
== required_bits
)
2763 vector_type_index displacement_vector_type
2764 = type_suffixes
[displacement_type
].vector_type
;
2765 mode_suffix_index mode
= find_mode_suffix (NUM_VECTOR_TYPES
,
2766 displacement_vector_type
,
2767 displacement_units ());
2768 if (mode
!= MODE_none
)
2770 if (mode
== MODE_s32offset
2771 && !lookup_form (mode
, type
)
2772 && lookup_form (MODE_u32offset
, type
))
2774 if (type_suffix_ids
[0] == NUM_TYPE_SUFFIXES
)
2775 error_at (location
, "%qE does not support 32-bit sign-extended"
2776 " offsets", fndecl
);
2778 error_at (location
, "%qE does not support sign-extended"
2779 " offsets", fndecl
);
2786 if (type_suffix_ids
[0] == NUM_TYPE_SUFFIXES
)
2788 /* TYPE has been inferred rather than specified by the user,
2789 so mention it in the error messages. */
2791 error_at (location
, "passing %qT to argument %d of %qE, which when"
2792 " loading %qT expects a vector of %d-bit integers",
2793 get_argument_type (argno
), argno
+ 1, fndecl
,
2794 get_vector_type (type
), required_bits
);
2796 error_at (location
, "passing %qT to argument %d of %qE, which when"
2797 " storing %qT expects a vector of %d-bit integers",
2798 get_argument_type (argno
), argno
+ 1, fndecl
,
2799 get_vector_type (type
), required_bits
);
2802 /* TYPE is part of the function name. */
2803 error_at (location
, "passing %qT to argument %d of %qE, which"
2804 " expects a vector of %d-bit integers",
2805 get_argument_type (argno
), argno
+ 1, fndecl
, required_bits
);
2809 /* Require the arguments starting at ARGNO to form a gather-style address.
2810 There are three possible uses:
2812 - for loading into elements of type TYPE (when LOAD_P is true)
2813 - for storing from elements of type TYPE (when LOAD_P is false)
2814 - for prefetching data (when TYPE is NUM_TYPE_SUFFIXES)
2816 The three possible addresses are:
2818 - a vector base with no displacement
2819 - a vector base and a scalar displacement
2820 - a scalar (pointer) base and a vector displacement
2822 The overloaded function's mode suffix determines whether there is
2823 a displacement, and if so, what units it uses:
2825 - MODE_none: no displacement
2826 - MODE_offset: the displacement is measured in bytes
2827 - MODE_index: the displacement is measured in elements
2829 Return the mode of the non-overloaded function on success, otherwise
2830 report an error and return MODE_none. */
2832 function_resolver::resolve_gather_address (unsigned int argno
,
2833 type_suffix_index type
,
2836 tree actual
= get_argument_type (argno
);
2837 if (actual
== error_mark_node
)
2840 if (displacement_units () != UNITS_none
)
2842 /* Some form of displacement is needed. First handle a scalar
2843 pointer base and a vector displacement. */
2844 if (scalar_argument_p (argno
))
2845 /* Don't check the pointer type here, since there's only one valid
2846 choice. Leave that to the frontend. */
2847 return resolve_sv_displacement (argno
+ 1, type
, load_p
);
2849 if (!VECTOR_TYPE_P (actual
))
2851 error_at (location
, "passing %qT to argument %d of %qE,"
2852 " which expects a vector or pointer base address",
2853 actual
, argno
+ 1, fndecl
);
2858 /* Check for the correct choice of vector base type. */
2859 vector_type_index base_vector_type
;
2860 if (type
== NUM_TYPE_SUFFIXES
)
2862 /* Since prefetches have no type suffix, there is a free choice
2863 between 32-bit and 64-bit base addresses. */
2864 base_vector_type
= infer_vector_base_type (argno
);
2865 if (base_vector_type
== NUM_VECTOR_TYPES
)
2870 /* Check for some form of vector type, without saying which type
2872 type_suffix_index base_type
= infer_vector_type (argno
);
2873 if (base_type
== NUM_TYPE_SUFFIXES
)
2876 /* Check whether the type is the right one. */
2877 unsigned int required_bits
= type_suffixes
[type
].element_bits
;
2878 gcc_assert (required_bits
== 32 || required_bits
== 64);
2879 type_suffix_index required_type
= (required_bits
== 32
2882 if (required_type
!= base_type
)
2884 error_at (location
, "passing %qT to argument %d of %qE,"
2885 " which expects %qT", actual
, argno
+ 1, fndecl
,
2886 get_vector_type (required_type
));
2889 base_vector_type
= type_suffixes
[base_type
].vector_type
;
2892 /* Check the scalar displacement, if any. */
2893 if (displacement_units () != UNITS_none
2894 && !require_scalar_type (argno
+ 1, "int64_t"))
2897 /* Find the appropriate mode suffix. The checks above should have
2898 weeded out all erroneous cases. */
2899 for (unsigned int mode_i
= 0; mode_i
< ARRAY_SIZE (mode_suffixes
); ++mode_i
)
2901 const mode_suffix_info
&mode
= mode_suffixes
[mode_i
];
2902 if (mode
.base_vector_type
== base_vector_type
2903 && mode
.displacement_vector_type
== NUM_VECTOR_TYPES
2904 && mode
.displacement_units
== displacement_units ())
2905 return mode_suffix_index (mode_i
);
2911 /* Require arguments ARGNO and ARGNO + 1 to form an ADR-style address,
2912 i.e. one with a vector of base addresses and a vector of displacements.
2913 The overloaded function's mode suffix determines the units of the
2914 displacement (bytes for "_offset", elements for "_index").
2916 Return the associated mode suffix on success, otherwise report
2917 an error and return MODE_none. */
2919 function_resolver::resolve_adr_address (unsigned int argno
)
2921 vector_type_index base_type
= infer_vector_base_type (argno
);
2922 if (base_type
== NUM_VECTOR_TYPES
)
2925 vector_type_index displacement_type
2926 = infer_vector_displacement_type (argno
+ 1);
2927 if (displacement_type
== NUM_VECTOR_TYPES
)
2930 mode_suffix_index mode
= find_mode_suffix (base_type
, displacement_type
,
2931 displacement_units ());
2932 if (mode
== MODE_none
)
2934 if (mode_suffix_id
== MODE_offset
)
2935 error_at (location
, "cannot combine a base of type %qT with"
2936 " an offset of type %qT",
2937 get_argument_type (argno
), get_argument_type (argno
+ 1));
2939 error_at (location
, "cannot combine a base of type %qT with"
2940 " an index of type %qT",
2941 get_argument_type (argno
), get_argument_type (argno
+ 1));
2946 /* Require the function to have exactly EXPECTED arguments. Return true
2947 if it does, otherwise report an appropriate error. */
2949 function_resolver::check_num_arguments (unsigned int expected
)
2951 if (m_arglist
.length () < expected
)
2952 error_at (location
, "too few arguments to function %qE", fndecl
);
2953 else if (m_arglist
.length () > expected
)
2954 error_at (location
, "too many arguments to function %qE", fndecl
);
2955 return m_arglist
.length () == expected
;
2958 /* If the function is predicated, check that the first argument is a
2959 suitable governing predicate. Also check that there are NOPS further
2960 arguments after any governing predicate, but don't check what they are.
2962 Return true on success, otherwise report a suitable error.
2963 When returning true:
2965 - set I to the number of the first unchecked argument.
2966 - set NARGS to the total number of arguments. */
2968 function_resolver::check_gp_argument (unsigned int nops
,
2969 unsigned int &i
, unsigned int &nargs
)
2971 gcc_assert (pred
!= PRED_za_m
);
2973 if (pred
!= PRED_none
)
2975 /* Unary merge operations should use resolve_unary instead. */
2976 gcc_assert (!shape
->has_merge_argument_p (*this, nops
));
2978 if (!check_num_arguments (nargs
)
2979 || !require_vector_type (i
, gp_type_index ()))
2986 if (!check_num_arguments (nargs
))
2993 /* Finish resolving a function whose final argument can be a vector
2994 or a scalar, with the function having an implicit "_n" suffix
2995 in the latter case. This "_n" form might only exist for certain
2998 ARGNO is the index of the final argument. The inferred type suffix
2999 was obtained from argument FIRST_ARGNO, which has type FIRST_TYPE.
3000 EXPECTED_TCLASS and EXPECTED_BITS describe the expected properties
3001 of the final vector or scalar argument, in the same way as for
3002 require_derived_vector_type. INFERRED_TYPE is the inferred type
3003 suffix itself, or NUM_TYPE_SUFFIXES if it's the same as FIRST_TYPE.
3005 Return the function decl of the resolved function on success,
3006 otherwise report a suitable error and return error_mark_node. */
3007 tree
function_resolver::
3008 finish_opt_n_resolution (unsigned int argno
, unsigned int first_argno
,
3009 type_suffix_index first_type
,
3010 type_class_index expected_tclass
,
3011 unsigned int expected_bits
,
3012 type_suffix_index inferred_type
)
3014 if (inferred_type
== NUM_TYPE_SUFFIXES
)
3015 inferred_type
= first_type
;
3016 tree scalar_form
= lookup_form (MODE_n
, inferred_type
);
3018 /* Allow the final argument to be scalar, if an _n form exists. */
3019 if (scalar_argument_p (argno
))
3024 /* Check the vector form normally. If that succeeds, raise an
3025 error about having no corresponding _n form. */
3026 tree res
= resolve_to (mode_suffix_id
, inferred_type
);
3027 if (res
!= error_mark_node
)
3028 error_at (location
, "passing %qT to argument %d of %qE, but its"
3029 " %qT form does not accept scalars",
3030 get_argument_type (argno
), argno
+ 1, fndecl
,
3031 get_vector_type (first_type
));
3032 return error_mark_node
;
3035 /* If an _n form does exist, provide a more accurate message than
3036 require_derived_vector_type would for arguments that are neither
3037 vectors nor scalars. */
3038 if (scalar_form
&& !require_vector_or_scalar_type (argno
))
3039 return error_mark_node
;
3041 /* Check for the correct vector type. */
3042 if (!require_derived_vector_type (argno
, first_argno
, first_type
,
3043 expected_tclass
, expected_bits
))
3044 return error_mark_node
;
3046 return resolve_to (mode_suffix_id
, inferred_type
);
3049 /* Finish resolving a function whose final argument can be a tuple
3050 or a vector, with the function having an implicit "_single" suffix
3051 in the latter case. This "_single" form might only exist for certain
3054 ARGNO is the index of the final argument. The inferred type suffix
3055 was obtained from argument FIRST_ARGNO, which has type FIRST_TYPE.
3056 EXPECTED_TCLASS gives the expected type class for the final tuple
3059 Return the function decl of the resolved function on success,
3060 otherwise report a suitable error and return error_mark_node. */
3061 tree
function_resolver::
3062 finish_opt_single_resolution (unsigned int argno
, unsigned int first_argno
,
3063 sve_type first_type
,
3064 type_class_index expected_tclass
)
3066 sve_type new_type
= infer_sve_type (argno
);
3068 return error_mark_node
;
3070 /* If the type is a tuple, require it to match the group suffix. */
3071 unsigned int num_vectors
= vectors_per_tuple ();
3072 if (num_vectors
!= 1
3073 && new_type
.num_vectors
!= 1
3074 && new_type
.num_vectors
!= num_vectors
)
3076 report_incorrect_num_vectors (argno
, new_type
, num_vectors
);
3077 return error_mark_node
;
3080 auto expected_num_vectors
= (new_type
.num_vectors
== 1 ? 1 : 0);
3081 if (!require_derived_vector_type (argno
, first_argno
, first_type
,
3082 expected_tclass
, SAME_SIZE
,
3083 expected_num_vectors
))
3084 return error_mark_node
;
3086 if (new_type
.num_vectors
== 1 && first_type
.num_vectors
> 1)
3088 if (tree single_form
= lookup_form (MODE_single
, first_type
))
3091 if (resolve_to (mode_suffix_id
, first_type
) != error_mark_node
)
3092 error_at (location
, "passing %qT to argument %d of %qE, but its"
3093 " %qT form does not accept single vectors",
3094 get_vector_type (new_type
), argno
+ 1, fndecl
,
3095 get_vector_type (first_type
));
3096 return error_mark_node
;
3098 return resolve_to (mode_suffix_id
, first_type
);
3101 /* Resolve a (possibly predicated) unary function. If the function uses
3102 merge predication or if TREAT_AS_MERGE_P is true, there is an extra
3103 vector argument before the governing predicate that specifies the
3104 values of inactive elements. This argument has the following
3107 - the type class must be the same as for active elements if MERGE_TCLASS
3108 is SAME_TYPE_CLASS, otherwise it must be MERGE_TCLASS itself.
3110 - the element size must be the same as for active elements if MERGE_BITS
3111 is SAME_TYPE_SIZE, otherwise it must be MERGE_BITS itself.
3113 Return the function decl of the resolved function on success,
3114 otherwise report a suitable error and return error_mark_node. */
3116 function_resolver::resolve_unary (type_class_index merge_tclass
,
3117 unsigned int merge_bits
,
3118 bool treat_as_merge_p
)
3120 type_suffix_index type
;
3121 if (pred
== PRED_m
|| treat_as_merge_p
)
3123 if (!check_num_arguments (3))
3124 return error_mark_node
;
3125 if (merge_tclass
== SAME_TYPE_CLASS
&& merge_bits
== SAME_SIZE
)
3127 /* The inactive elements are the same as the active elements,
3128 so we can use normal left-to-right resolution. */
3129 if ((type
= infer_vector_type (0)) == NUM_TYPE_SUFFIXES
3130 || !require_vector_type (1, VECTOR_TYPE_svbool_t
)
3131 || !require_matching_vector_type (2, 0, type
))
3132 return error_mark_node
;
3136 /* The inactive element type is a function of the active one,
3137 so resolve the active one first. */
3138 if (!require_vector_type (1, VECTOR_TYPE_svbool_t
)
3139 || (type
= infer_vector_type (2)) == NUM_TYPE_SUFFIXES
3140 || !require_derived_vector_type (0, 2, type
, merge_tclass
,
3142 return error_mark_node
;
3147 /* We just need to check the predicate (if any) and the single
3149 unsigned int i
, nargs
;
3150 if (!check_gp_argument (1, i
, nargs
)
3151 || (type
= infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
3152 return error_mark_node
;
3155 /* Handle convert-like functions in which the first type suffix is
3157 if (type_suffix_ids
[0] != NUM_TYPE_SUFFIXES
)
3158 return resolve_to (mode_suffix_id
, type_suffix_ids
[0], type
);
3160 return resolve_to (mode_suffix_id
, type
);
3163 /* Resolve a (possibly predicated) function that takes NOPS like-typed
3164 vector arguments followed by NIMM integer immediates. Return the
3165 function decl of the resolved function on success, otherwise report
3166 a suitable error and return error_mark_node. */
3168 function_resolver::resolve_uniform (unsigned int nops
, unsigned int nimm
)
3170 unsigned int i
, nargs
;
3171 type_suffix_index type
;
3172 if (!check_gp_argument (nops
+ nimm
, i
, nargs
)
3173 || (type
= infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
3174 return error_mark_node
;
3176 unsigned int first_arg
= i
++;
3177 for (; i
< nargs
- nimm
; ++i
)
3178 if (!require_matching_vector_type (i
, first_arg
, type
))
3179 return error_mark_node
;
3181 for (; i
< nargs
; ++i
)
3182 if (!require_integer_immediate (i
))
3183 return error_mark_node
;
3185 return resolve_to (mode_suffix_id
, type
);
3188 /* Resolve a (possibly predicated) function that offers a choice between
3191 - NOPS like-typed vector arguments or
3192 - NOPS - 1 like-typed vector arguments followed by a scalar argument
3194 Return the function decl of the resolved function on success,
3195 otherwise report a suitable error and return error_mark_node. */
3197 function_resolver::resolve_uniform_opt_n (unsigned int nops
)
3199 unsigned int i
, nargs
;
3200 type_suffix_index type
;
3201 if (!check_gp_argument (nops
, i
, nargs
)
3202 || (type
= infer_vector_type (i
)) == NUM_TYPE_SUFFIXES
)
3203 return error_mark_node
;
3205 unsigned int first_arg
= i
++;
3206 for (; i
< nargs
- 1; ++i
)
3207 if (!require_matching_vector_type (i
, first_arg
, type
))
3208 return error_mark_node
;
3210 return finish_opt_n_resolution (i
, first_arg
, type
);
3213 /* If the call is erroneous, report an appropriate error and return
3214 error_mark_node. Otherwise, if the function is overloaded, return
3215 the decl of the non-overloaded function. Return NULL_TREE otherwise,
3216 indicating that the call should be processed in the normal way. */
3218 function_resolver::resolve ()
3220 return shape
->resolve (*this);
3223 function_checker::function_checker (location_t location
,
3224 const function_instance
&instance
,
3225 tree fndecl
, tree fntype
,
3226 unsigned int nargs
, tree
*args
)
3227 : function_call_info (location
, instance
, fndecl
),
3228 m_fntype (fntype
), m_nargs (nargs
), m_args (args
),
3229 m_base_arg (pred
!= PRED_none
&& pred
!= PRED_za_m
? 1 : 0)
3233 /* Return true if argument ARGNO exists. which it might not for
3234 erroneous calls. It is safe to wave through checks if this
3235 function returns false. */
3237 function_checker::argument_exists_p (unsigned int argno
)
3239 gcc_assert (argno
< (unsigned int) type_num_arguments (m_fntype
));
3240 return argno
< m_nargs
;
3243 /* Check that argument ARGNO is an integer constant expression and
3244 store its value in VALUE_OUT if so. The caller should first
3245 check that argument ARGNO exists. */
3247 function_checker::require_immediate (unsigned int argno
,
3248 HOST_WIDE_INT
&value_out
)
3250 gcc_assert (argno
< m_nargs
);
3251 tree arg
= m_args
[argno
];
3253 /* The type and range are unsigned, so read the argument as an
3254 unsigned rather than signed HWI. */
3255 if (!tree_fits_uhwi_p (arg
))
3257 report_non_ice (location
, fndecl
, argno
);
3261 /* ...but treat VALUE_OUT as signed for error reporting, since printing
3262 -1 is more user-friendly than the maximum uint64_t value. */
3263 value_out
= tree_to_uhwi (arg
);
3267 /* Check that argument REL_ARGNO is an integer constant expression that
3268 has the value VALUE0 or VALUE1. REL_ARGNO counts from the end of the
3269 predication arguments. */
3271 function_checker::require_immediate_either_or (unsigned int rel_argno
,
3272 HOST_WIDE_INT value0
,
3273 HOST_WIDE_INT value1
)
3275 unsigned int argno
= m_base_arg
+ rel_argno
;
3276 if (!argument_exists_p (argno
))
3279 HOST_WIDE_INT actual
;
3280 if (!require_immediate (argno
, actual
))
3283 if (actual
!= value0
&& actual
!= value1
)
3285 report_neither_nor (location
, fndecl
, argno
, actual
, value0
, value1
);
3292 /* Check that argument REL_ARGNO is an integer constant expression that has
3293 a valid value for enumeration type TYPE. REL_ARGNO counts from the end
3294 of the predication arguments. */
3296 function_checker::require_immediate_enum (unsigned int rel_argno
, tree type
)
3298 unsigned int argno
= m_base_arg
+ rel_argno
;
3299 if (!argument_exists_p (argno
))
3302 HOST_WIDE_INT actual
;
3303 if (!require_immediate (argno
, actual
))
3306 for (tree entry
= TYPE_VALUES (type
); entry
; entry
= TREE_CHAIN (entry
))
3308 /* The value is an INTEGER_CST for C and a CONST_DECL wrapper
3309 around an INTEGER_CST for C++. */
3310 tree value
= TREE_VALUE (entry
);
3311 if (TREE_CODE (value
) == CONST_DECL
)
3312 value
= DECL_INITIAL (value
);
3313 if (wi::to_widest (value
) == actual
)
3317 report_not_enum (location
, fndecl
, argno
, actual
, type
);
3321 /* The intrinsic conceptually divides vector argument REL_VEC_ARGNO into
3322 groups of GROUP_SIZE elements. Return true if argument REL_ARGNO is
3323 a suitable constant index for selecting one of these groups. The
3324 selection happens within a 128-bit quadword, rather than the whole vector.
3326 REL_ARGNO and REL_VEC_ARGNO count from the end of the predication
3329 function_checker::require_immediate_lane_index (unsigned int rel_argno
,
3330 unsigned int rel_vec_argno
,
3331 unsigned int group_size
)
3333 unsigned int argno
= m_base_arg
+ rel_argno
;
3334 if (!argument_exists_p (argno
))
3337 /* Get the type of the vector argument. tree_argument_type wants a
3338 1-based number, whereas VEC_ARGNO is 0-based. */
3339 unsigned int vec_argno
= m_base_arg
+ rel_vec_argno
;
3340 machine_mode mode
= TYPE_MODE (type_argument_type (m_fntype
, vec_argno
+ 1));
3341 gcc_assert (VECTOR_MODE_P (mode
));
3342 unsigned int nlanes
= 128 / (group_size
* GET_MODE_UNIT_BITSIZE (mode
));
3343 return require_immediate_range (rel_argno
, 0, nlanes
- 1);
3346 /* Check that argument REL_ARGNO is an integer constant expression that
3347 has one of the given values. */
3349 function_checker::require_immediate_one_of (unsigned int rel_argno
,
3350 HOST_WIDE_INT value0
,
3351 HOST_WIDE_INT value1
,
3352 HOST_WIDE_INT value2
,
3353 HOST_WIDE_INT value3
)
3355 unsigned int argno
= m_base_arg
+ rel_argno
;
3356 if (!argument_exists_p (argno
))
3359 HOST_WIDE_INT actual
;
3360 if (!require_immediate (argno
, actual
))
3363 if (actual
!= value0
3366 && actual
!= value3
)
3368 report_not_one_of (location
, fndecl
, argno
, actual
,
3369 value0
, value1
, value2
, value3
);
3376 /* Check that argument REL_ARGNO is an integer constant expression in the
3377 range [MIN, MAX]. REL_ARGNO counts from the end of the predication
3380 function_checker::require_immediate_range (unsigned int rel_argno
,
3384 unsigned int argno
= m_base_arg
+ rel_argno
;
3385 if (!argument_exists_p (argno
))
3388 /* Required because of the tree_to_uhwi -> HOST_WIDE_INT conversion
3389 in require_immediate. */
3390 gcc_assert (min
>= 0 && min
<= max
);
3391 HOST_WIDE_INT actual
;
3392 if (!require_immediate (argno
, actual
))
3395 if (!IN_RANGE (actual
, min
, max
))
3397 report_out_of_range (location
, fndecl
, argno
, actual
, min
, max
);
3404 /* Perform semantic checks on the call. Return true if the call is valid,
3405 otherwise report a suitable error. */
3407 function_checker::check ()
3409 function_args_iterator iter
;
3412 FOREACH_FUNCTION_ARGS (m_fntype
, type
, iter
)
3414 if (type
== void_type_node
|| i
>= m_nargs
)
3418 && TREE_CODE (type
) == ENUMERAL_TYPE
3419 && !require_immediate_enum (i
- m_base_arg
, type
))
3425 return shape
->check (*this);
3428 /* Return true if V is a vector constant and if, for every in-range integer I,
3429 element STEP*I is equal to element 0. */
3431 vector_cst_all_same (tree v
, unsigned int step
)
3433 if (TREE_CODE (v
) != VECTOR_CST
)
3436 /* VECTOR_CST_NELTS_PER_PATTERN applies to any multiple of
3437 VECTOR_CST_NPATTERNS. */
3438 unsigned int lcm
= least_common_multiple (step
, VECTOR_CST_NPATTERNS (v
));
3439 unsigned int nelts
= lcm
* VECTOR_CST_NELTS_PER_PATTERN (v
);
3440 tree first_el
= VECTOR_CST_ENCODED_ELT (v
, 0);
3441 for (unsigned int i
= 0; i
< nelts
; i
+= step
)
3442 if (!operand_equal_p (VECTOR_CST_ELT (v
, i
), first_el
, 0))
3448 /* Return true if V is a constant predicate that acts as a ptrue when
3449 predicating STEP-byte elements. */
3451 is_ptrue (tree v
, unsigned int step
)
3453 return (TREE_CODE (v
) == VECTOR_CST
3454 && TYPE_MODE (TREE_TYPE (v
)) == VNx16BImode
3455 && integer_nonzerop (VECTOR_CST_ENCODED_ELT (v
, 0))
3456 && vector_cst_all_same (v
, step
));
3459 gimple_folder::gimple_folder (const function_instance
&instance
, tree fndecl
,
3460 gimple_stmt_iterator
*gsi_in
, gcall
*call_in
)
3461 : function_call_info (gimple_location (call_in
), instance
, fndecl
),
3462 gsi (gsi_in
), call (call_in
), lhs (gimple_call_lhs (call_in
))
3466 /* VALUE might be a vector of type VECTYPE or a single scalar element.
3467 Duplicate it into a vector of type VECTYPE in the latter case, adding any
3468 new statements to STMTS. */
3470 gimple_folder::force_vector (gimple_seq
&stmts
, tree vectype
, tree value
)
3472 if (!VECTOR_TYPE_P (TREE_TYPE (value
)))
3473 value
= gimple_build_vector_from_val (&stmts
, vectype
, value
);
3477 /* Convert predicate argument ARGNO so that it has the type appropriate for
3478 an operation on VECTYPE. Add any new statements to STMTS. */
3480 gimple_folder::convert_pred (gimple_seq
&stmts
, tree vectype
,
3483 tree pred
= gimple_call_arg (call
, argno
);
3484 if (known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (pred
)),
3485 TYPE_VECTOR_SUBPARTS (vectype
)))
3488 return gimple_build (&stmts
, VIEW_CONVERT_EXPR
,
3489 truth_type_for (vectype
), pred
);
3492 /* Return a pointer to the address in a contiguous load or store,
3493 given that each memory vector has type VECTYPE. Add any new
3494 statements to STMTS. */
3496 gimple_folder::fold_contiguous_base (gimple_seq
&stmts
, tree vectype
)
3498 tree base
= gimple_call_arg (call
, 1);
3499 if (mode_suffix_id
== MODE_vnum
)
3501 tree offset
= gimple_call_arg (call
, 2);
3502 offset
= gimple_convert (&stmts
, sizetype
, offset
);
3503 offset
= gimple_build (&stmts
, MULT_EXPR
, sizetype
, offset
,
3504 TYPE_SIZE_UNIT (vectype
));
3505 base
= gimple_build (&stmts
, POINTER_PLUS_EXPR
, TREE_TYPE (base
),
3511 /* Return the alignment and TBAA argument to an internal load or store
3512 function like IFN_MASK_LOAD or IFN_MASK_STORE, given that it accesses
3513 memory elements of type TYPE. */
3515 gimple_folder::load_store_cookie (tree type
)
3517 return build_int_cst (build_pointer_type (type
), TYPE_ALIGN (type
));
3520 /* Fold the call to a call to INSTANCE, with the same arguments. */
3522 gimple_folder::redirect_call (const function_instance
&instance
)
3524 registered_function
*rfn
3525 = function_table
->find_with_hash (instance
, instance
.hash ());
3529 gimple_call_set_fndecl (call
, rfn
->decl
);
3533 /* Redirect _z and _m calls to _x functions if the predicate is all-true.
3534 This allows us to use unpredicated instructions, where available. */
3536 gimple_folder::redirect_pred_x ()
3538 if (pred
!= PRED_z
&& pred
!= PRED_m
)
3541 if (gimple_call_num_args (call
) < 2)
3544 tree lhs_type
= TREE_TYPE (TREE_TYPE (fndecl
));
3545 tree arg0_type
= type_argument_type (TREE_TYPE (fndecl
), 1);
3546 tree arg1_type
= type_argument_type (TREE_TYPE (fndecl
), 2);
3547 if (!VECTOR_TYPE_P (lhs_type
)
3548 || !VECTOR_TYPE_P (arg0_type
)
3549 || !VECTOR_TYPE_P (arg1_type
))
3552 auto lhs_step
= element_precision (lhs_type
);
3553 auto rhs_step
= element_precision (arg1_type
);
3554 auto step
= MAX (lhs_step
, rhs_step
);
3555 if (!multiple_p (step
, BITS_PER_UNIT
)
3556 || !is_ptrue (gimple_call_arg (call
, 0), step
/ BITS_PER_UNIT
))
3559 function_instance
instance (*this);
3560 instance
.pred
= PRED_x
;
3561 return redirect_call (instance
);
3564 /* Fold the call to constant VAL. */
3566 gimple_folder::fold_to_cstu (poly_uint64 val
)
3568 return gimple_build_assign (lhs
, build_int_cstu (TREE_TYPE (lhs
), val
));
3571 /* Fold the call to a PTRUE, taking the element size from type suffix 0. */
3573 gimple_folder::fold_to_ptrue ()
3575 tree svbool_type
= TREE_TYPE (lhs
);
3576 tree bool_type
= TREE_TYPE (svbool_type
);
3577 unsigned int element_bytes
= type_suffix (0).element_bytes
;
3579 /* The return type is svbool_t for all type suffixes, thus for b8 we
3580 want { 1, 1, 1, 1, ... }, for b16 we want { 1, 0, 1, 0, ... }, etc. */
3581 tree_vector_builder
builder (svbool_type
, element_bytes
, 1);
3582 builder
.quick_push (build_all_ones_cst (bool_type
));
3583 for (unsigned int i
= 1; i
< element_bytes
; ++i
)
3584 builder
.quick_push (build_zero_cst (bool_type
));
3585 return gimple_build_assign (lhs
, builder
.build ());
3588 /* Fold the call to a PFALSE. */
3590 gimple_folder::fold_to_pfalse ()
3592 return gimple_build_assign (lhs
, build_zero_cst (TREE_TYPE (lhs
)));
3595 /* Fold an operation to a constant predicate in which the first VL
3596 elements are set and the rest are clear. Take the element size
3597 from type suffix 0. */
3599 gimple_folder::fold_to_vl_pred (unsigned int vl
)
3601 tree vectype
= TREE_TYPE (lhs
);
3602 tree element_type
= TREE_TYPE (vectype
);
3603 tree minus_one
= build_all_ones_cst (element_type
);
3604 tree zero
= build_zero_cst (element_type
);
3605 unsigned int element_bytes
= type_suffix (0).element_bytes
;
3607 /* Construct COUNT elements that contain the ptrue followed by
3608 a repeating sequence of COUNT elements. */
3609 unsigned int count
= constant_lower_bound (TYPE_VECTOR_SUBPARTS (vectype
));
3610 gcc_assert (vl
* element_bytes
<= count
);
3611 tree_vector_builder
builder (vectype
, count
, 2);
3612 for (unsigned int i
= 0; i
< count
* 2; ++i
)
3614 bool bit
= (i
& (element_bytes
- 1)) == 0 && i
< vl
* element_bytes
;
3615 builder
.quick_push (bit
? minus_one
: zero
);
3617 return gimple_build_assign (lhs
, builder
.build ());
3620 /* Try to fold the call to a constant, given that, for integers, the call
3621 is roughly equivalent to binary operation CODE. aarch64_const_binop
3622 handles any differences between CODE and the intrinsic. */
3624 gimple_folder::fold_const_binary (enum tree_code code
)
3626 gcc_assert (gimple_call_num_args (call
) == 3);
3627 tree pg
= gimple_call_arg (call
, 0);
3628 tree op1
= gimple_call_arg (call
, 1);
3629 tree op2
= gimple_call_arg (call
, 2);
3631 if (type_suffix (0).integer_p
3632 && (pred
== PRED_x
|| is_ptrue (pg
, type_suffix (0).element_bytes
)))
3633 if (tree res
= vector_const_binop (code
, op1
, op2
, aarch64_const_binop
))
3634 return gimple_build_assign (lhs
, res
);
3639 /* Try to fold the call. Return the new statement on success and null
3642 gimple_folder::fold ()
3644 /* Don't fold anything when SVE is disabled; emit an error during
3645 expansion instead. */
3649 /* Punt if the function has a return type and no result location is
3650 provided. The attributes should allow target-independent code to
3651 remove the calls if appropriate. */
3652 if (!lhs
&& TREE_TYPE (gimple_call_fntype (call
)) != void_type_node
)
3655 /* First try some simplifications that are common to many functions. */
3656 if (auto *call
= redirect_pred_x ())
3659 return base
->fold (*this);
3662 function_expander::function_expander (const function_instance
&instance
,
3663 tree fndecl
, tree call_expr_in
,
3664 rtx possible_target_in
)
3665 : function_call_info (EXPR_LOCATION (call_expr_in
), instance
, fndecl
),
3666 call_expr (call_expr_in
), possible_target (possible_target_in
)
3670 /* Return the handler of direct optab OP for type suffix SUFFIX_I. */
3672 function_expander::direct_optab_handler (optab op
, unsigned int suffix_i
)
3674 return ::direct_optab_handler (op
, tuple_mode (suffix_i
));
3677 /* Choose between signed and unsigned direct optabs SIGNED_OP and
3678 UNSIGNED_OP based on the signedness of type suffix SUFFIX_I, then
3679 pick the appropriate optab handler for the mode. Use MODE as the
3680 mode if given, otherwise use the mode of type suffix SUFFIX_I. */
3682 function_expander::direct_optab_handler_for_sign (optab signed_op
,
3684 unsigned int suffix_i
,
3687 if (mode
== VOIDmode
)
3688 mode
= vector_mode (suffix_i
);
3689 optab op
= type_suffix (suffix_i
).unsigned_p
? unsigned_op
: signed_op
;
3690 return ::direct_optab_handler (op
, mode
);
3693 /* Choose between signed and unsigned convert optabs SIGNED_OP and
3694 UNSIGNED_OP based on the signedness of type suffix SUFFIX_I, then
3695 pick the appropriate optab handler for "converting" from FROM_MODE
3698 function_expander::convert_optab_handler_for_sign (optab signed_op
,
3700 unsigned int suffix_i
,
3701 machine_mode to_mode
,
3702 machine_mode from_mode
)
3704 optab op
= type_suffix (suffix_i
).unsigned_p
? unsigned_op
: signed_op
;
3705 return ::convert_optab_handler (op
, to_mode
, from_mode
);
3708 /* Return true if X overlaps any input. */
3710 function_expander::overlaps_input_p (rtx x
)
3712 for (unsigned int i
= 0; i
< args
.length (); ++i
)
3713 if (reg_overlap_mentioned_p (x
, args
[i
]))
3718 /* Convert ptr_mode value X to Pmode. */
3720 function_expander::convert_to_pmode (rtx x
)
3722 if (ptr_mode
== SImode
)
3723 x
= simplify_gen_unary (ZERO_EXTEND
, DImode
, x
, SImode
);
3727 /* Return the base address for a contiguous load or store function.
3728 MEM_MODE is the mode of the addressed memory, BASE_ARGNO is
3729 the index of the base argument, and VNUM_ARGNO is the index of
3730 the vnum offset argument (if any). VL_ISA_MODE is AARCH64_FL_SM_ON
3731 if the vnum argument is a factor of the SME vector length, 0 if it
3732 is a factor of the current prevailing vector length. */
3734 function_expander::get_contiguous_base (machine_mode mem_mode
,
3735 unsigned int base_argno
,
3736 unsigned int vnum_argno
,
3737 aarch64_feature_flags vl_isa_mode
)
3739 rtx base
= convert_to_pmode (args
[base_argno
]);
3740 if (mode_suffix_id
== MODE_vnum
)
3742 rtx vnum
= args
[vnum_argno
];
3743 if (vnum
!= const0_rtx
)
3745 /* Use the size of the memory mode for extending loads and truncating
3746 stores. Use the size of a full vector for non-extending loads
3747 and non-truncating stores (including svld[234] and svst[234]). */
3748 poly_int64 size
= ordered_min (GET_MODE_SIZE (mem_mode
),
3749 BYTES_PER_SVE_VECTOR
);
3751 if ((vl_isa_mode
& AARCH64_FL_SM_ON
)
3752 && !TARGET_STREAMING
3753 && !size
.is_constant ())
3755 gcc_assert (known_eq (size
, BYTES_PER_SVE_VECTOR
));
3756 if (CONST_INT_P (vnum
) && IN_RANGE (INTVAL (vnum
), -32, 31))
3757 offset
= aarch64_sme_vq_immediate (Pmode
, INTVAL (vnum
) * 16,
3761 offset
= aarch64_sme_vq_immediate (Pmode
, 16,
3763 offset
= simplify_gen_binary (MULT
, Pmode
, vnum
, offset
);
3768 offset
= gen_int_mode (size
, Pmode
);
3769 offset
= simplify_gen_binary (MULT
, Pmode
, vnum
, offset
);
3771 base
= simplify_gen_binary (PLUS
, Pmode
, base
, offset
);
3777 /* For a function that does the equivalent of:
3779 OUTPUT = COND ? FN (INPUTS) : FALLBACK;
3781 return the value of FALLBACK.
3783 MODE is the mode of OUTPUT. NOPS is the number of operands in INPUTS.
3784 MERGE_ARGNO is the argument that provides FALLBACK for _m functions,
3785 or DEFAULT_MERGE_ARGNO if we should apply the usual rules.
3787 ARGNO is the caller's index into args. If the returned value is
3788 argument 0 (as for unary _m operations), increment ARGNO past the
3789 returned argument. */
3791 function_expander::get_fallback_value (machine_mode mode
, unsigned int nops
,
3792 unsigned int merge_argno
,
3793 unsigned int &argno
)
3796 return CONST0_RTX (mode
);
3798 gcc_assert (pred
== PRED_m
|| pred
== PRED_x
);
3799 if (merge_argno
== DEFAULT_MERGE_ARGNO
)
3800 merge_argno
= shape
->has_merge_argument_p (*this, nops
) ? 0 : 1;
3802 if (merge_argno
== 0)
3803 return args
[argno
++];
3805 return args
[merge_argno
];
3808 /* Return a REG rtx that can be used for the result of the function,
3809 using the preferred target if suitable. */
3811 function_expander::get_reg_target ()
3813 machine_mode target_mode
= result_mode ();
3814 if (!possible_target
|| GET_MODE (possible_target
) != target_mode
)
3815 possible_target
= gen_reg_rtx (target_mode
);
3816 return possible_target
;
3819 /* As for get_reg_target, but make sure that the returned REG does not
3820 overlap any inputs. */
3822 function_expander::get_nonoverlapping_reg_target ()
3824 if (possible_target
&& overlaps_input_p (possible_target
))
3825 possible_target
= NULL_RTX
;
3826 return get_reg_target ();
3829 /* Add an output operand to the instruction we're building, which has
3830 code ICODE. Bind the output to the preferred target rtx if possible. */
3832 function_expander::add_output_operand (insn_code icode
)
3834 unsigned int opno
= m_ops
.length ();
3835 machine_mode mode
= insn_data
[icode
].operand
[opno
].mode
;
3836 m_ops
.safe_grow (opno
+ 1, true);
3837 create_output_operand (&m_ops
.last (), possible_target
, mode
);
3840 /* Add an input operand to the instruction we're building, which has
3841 code ICODE. Calculate the value of the operand as follows:
3843 - If the operand is a vector and X is not, broadcast X to fill a
3844 vector of the appropriate mode.
3846 - Otherwise, if the operand is a predicate, coerce X to have the
3847 mode that the instruction expects. In this case X is known to be
3848 VNx16BImode (the mode of svbool_t).
3850 - Otherwise use X directly. The expand machinery checks that X has
3851 the right mode for the instruction. */
3853 function_expander::add_input_operand (insn_code icode
, rtx x
)
3855 unsigned int opno
= m_ops
.length ();
3856 const insn_operand_data
&operand
= insn_data
[icode
].operand
[opno
];
3857 machine_mode mode
= operand
.mode
;
3858 if (mode
== VOIDmode
)
3860 /* The only allowable uses of VOIDmode are:
3862 - the wildcard aarch64_any_register_operand, which is used
3863 to avoid combinatorial explosion in the reinterpret patterns
3865 - pmode_register_operand, which always has mode Pmode. */
3866 if (operand
.predicate
== aarch64_any_register_operand
)
3867 mode
= GET_MODE (x
);
3868 else if (operand
.predicate
== pmode_register_operand
)
3873 else if (!VECTOR_MODE_P (GET_MODE (x
)) && VECTOR_MODE_P (mode
))
3874 x
= expand_vector_broadcast (mode
, x
);
3875 else if (GET_MODE_CLASS (mode
) == MODE_VECTOR_BOOL
)
3877 gcc_assert (GET_MODE (x
) == VNx16BImode
);
3878 x
= gen_lowpart (mode
, x
);
3880 m_ops
.safe_grow (m_ops
.length () + 1, true);
3881 create_input_operand (&m_ops
.last (), x
, mode
);
3884 /* Add an integer operand with value X to the instruction. */
3886 function_expander::add_integer_operand (poly_int64 x
)
3888 m_ops
.safe_grow (m_ops
.length () + 1, true);
3889 create_integer_operand (&m_ops
.last (), x
);
3892 /* Add a memory operand with mode MODE and address ADDR. */
3894 function_expander::add_mem_operand (machine_mode mode
, rtx addr
)
3896 /* Exception for OImode for the ld1ro intrinsics.
3897 They act on 256 bit octaword data, and it's just easier to use a scalar
3898 mode to represent that than add a new vector mode solely for the purpose
3899 of this intrinsic. */
3900 gcc_assert (VECTOR_MODE_P (mode
) || mode
== OImode
);
3901 rtx mem
= gen_rtx_MEM (mode
, memory_address (mode
, addr
));
3902 /* The memory is only guaranteed to be element-aligned. */
3903 set_mem_align (mem
, GET_MODE_ALIGNMENT (GET_MODE_INNER (mode
)));
3904 add_fixed_operand (mem
);
3907 /* Add an address operand with value X. The static operand data says
3908 what mode and form the address must have. */
3910 function_expander::add_address_operand (rtx x
)
3912 m_ops
.safe_grow (m_ops
.length () + 1, true);
3913 create_address_operand (&m_ops
.last (), x
);
3916 /* Add an operand that must be X. The only way of legitimizing an
3917 invalid X is to reload the address of a MEM. */
3919 function_expander::add_fixed_operand (rtx x
)
3921 m_ops
.safe_grow (m_ops
.length () + 1, true);
3922 create_fixed_operand (&m_ops
.last (), x
);
3925 /* Generate instruction ICODE, given that its operands have already
3926 been added to M_OPS. Return the value of the first operand. */
3928 function_expander::generate_insn (insn_code icode
)
3930 expand_insn (icode
, m_ops
.length (), m_ops
.address ());
3931 return function_returns_void_p () ? const0_rtx
: m_ops
[0].value
;
3934 /* Convert the arguments to a gather/scatter function into the
3935 associated md operands. Argument ARGNO is the scalar or vector base and
3936 argument ARGNO + 1 is the scalar or vector displacement (if applicable).
3937 The md pattern expects:
3940 - a vector displacement
3942 If SCALED_P is true, it also expects:
3944 - a const_int that is 1 if the displacement is zero-extended from 32 bits
3945 - a scaling multiplier (1 for bytes, 2 for .h indices, etc.).
3947 If SCALED_P is false, the displacement is implicitly zero-extended
3948 and the scaling multiplier is implicitly 1. */
3950 function_expander::prepare_gather_address_operands (unsigned int argno
,
3953 machine_mode mem_mode
= memory_vector_mode ();
3954 tree vector_type
= base_vector_type ();
3955 units_index units
= displacement_units ();
3957 if (units
== UNITS_none
)
3959 /* Vector base, no displacement. Convert to an integer zero base
3960 and a vector byte offset. */
3961 args
.quick_insert (argno
, const0_rtx
);
3962 units
= UNITS_bytes
;
3964 else if (vector_type
)
3966 /* Vector base, scalar displacement. Convert to a scalar base and
3967 a vector byte offset. */
3968 std::swap (args
[argno
], args
[argno
+ 1]);
3969 if (units
== UNITS_elements
)
3974 /* Scalar base, vector displacement. This is the order that the md
3976 args
[argno
] = convert_to_pmode (args
[argno
]);
3977 vector_type
= displacement_vector_type ();
3978 if (units
== UNITS_elements
&& !scaled_p
)
3979 shift_idx
= argno
+ 1;
3981 tree scalar_displacement_type
= TREE_TYPE (vector_type
);
3985 machine_mode arg_mode
= GET_MODE (args
[shift_idx
]);
3986 if (arg_mode
== VOIDmode
)
3988 unsigned int elt_bytes
= GET_MODE_UNIT_SIZE (mem_mode
);
3989 rtx shift
= gen_int_mode (exact_log2 (elt_bytes
), DImode
);
3990 args
[shift_idx
] = simplify_gen_binary (ASHIFT
, arg_mode
,
3991 args
[shift_idx
], shift
);
3992 units
= UNITS_bytes
;
3995 bool uxtw_p
= (TYPE_PRECISION (scalar_displacement_type
) == 64
3996 || TYPE_UNSIGNED (scalar_displacement_type
));
3997 unsigned int scale
= (units
== UNITS_bytes
3998 ? 1 : GET_MODE_UNIT_SIZE (mem_mode
));
4002 args
.quick_insert (argno
+ 2, GEN_INT (uxtw_p
));
4003 args
.quick_insert (argno
+ 3, GEN_INT (scale
));
4006 gcc_assert (uxtw_p
&& scale
== 1);
4009 /* The final argument is an immediate svprfop value. Add two fake arguments
4010 to represent the rw and locality operands of a PREFETCH rtx. */
4012 function_expander::prepare_prefetch_operands ()
4014 unsigned int prfop
= INTVAL (args
.last ());
4015 /* Bit 3 of the prfop selects stores over loads. */
4016 args
.quick_push (GEN_INT ((prfop
& 8) != 0));
4017 /* Bits 1 and 2 specify the locality; 0-based for svprfop but
4018 1-based for PREFETCH. */
4019 args
.quick_push (GEN_INT (((prfop
>> 1) & 3) + 1));
4022 /* Add a dummy argument to indicate whether predicate argument ARGNO
4023 is all-true when interpreted in mode PRED_MODE. The hint goes
4024 immediately after ARGNO. */
4026 function_expander::add_ptrue_hint (unsigned int argno
, machine_mode pred_mode
)
4028 rtx pred
= gen_lowpart (pred_mode
, args
[argno
]);
4029 int hint
= (pred
== CONSTM1_RTX (pred_mode
)
4030 ? SVE_KNOWN_PTRUE
: SVE_MAYBE_NOT_PTRUE
);
4031 args
.quick_insert (argno
+ 1, gen_int_mode (hint
, SImode
));
4034 /* Rotate inputs args[START:END] one position to the left, so that
4035 args[START] becomes args[END - 1]. */
4037 function_expander::rotate_inputs_left (unsigned int start
, unsigned int end
)
4039 rtx new_last
= args
[start
];
4040 for (unsigned int i
= start
; i
< end
- 1; ++i
)
4041 args
[i
] = args
[i
+ 1];
4042 args
[end
- 1] = new_last
;
4045 /* Return true if the negation of argument ARGNO can be folded away,
4046 replacing it with the negated value if so. MODE is the associated
4047 vector mode, but the argument could be a single element. The main
4048 case this handles is constant arguments. */
4050 function_expander::try_negating_argument (unsigned int argno
,
4053 rtx x
= args
[argno
];
4054 if (!VECTOR_MODE_P (GET_MODE (x
)))
4055 mode
= GET_MODE_INNER (mode
);
4057 x
= simplify_unary_operation (NEG
, mode
, x
, mode
);
4065 /* Implement the call using instruction ICODE, with a 1:1 mapping between
4066 arguments and input operands. */
4068 function_expander::use_exact_insn (insn_code icode
)
4070 unsigned int nops
= insn_data
[icode
].n_operands
;
4071 if (!function_returns_void_p ())
4073 add_output_operand (icode
);
4076 for (unsigned int i
= 0; i
< nops
; ++i
)
4077 add_input_operand (icode
, args
[i
]);
4078 return generate_insn (icode
);
4081 /* Implement the call using instruction ICODE, which does not use a
4082 governing predicate. We must therefore drop the GP from an _x call. */
4084 function_expander::use_unpred_insn (insn_code icode
)
4086 /* We can't drop the predicate for _z and _m. */
4087 gcc_assert (pred
== PRED_x
|| pred
== PRED_none
);
4088 /* Discount the output operand. */
4089 unsigned int nops
= insn_data
[icode
].n_operands
- 1;
4090 /* Drop the predicate argument in the case of _x predication. */
4091 unsigned int bias
= (pred
== PRED_x
? 1 : 0);
4094 add_output_operand (icode
);
4095 for (; i
< nops
; ++i
)
4096 add_input_operand (icode
, args
[i
+ bias
]);
4098 return generate_insn (icode
);
4101 /* Implement the call using instruction ICODE, which is a predicated
4102 operation that returns arbitrary values for inactive lanes. */
4104 function_expander::use_pred_x_insn (insn_code icode
)
4106 /* At present we never need to handle PRED_none, which would involve
4107 creating a new predicate rather than using one supplied by the user. */
4108 gcc_assert (pred
== PRED_x
);
4109 /* Discount the output operand. */
4110 unsigned int nops
= args
.length () - 1;
4112 bool has_float_operand_p
= FLOAT_MODE_P (insn_data
[icode
].operand
[0].mode
);
4114 /* Add the normal operands. */
4115 add_output_operand (icode
);
4116 add_input_operand (icode
, args
[0]);
4117 for (unsigned int i
= 0; i
< nops
; ++i
)
4119 add_input_operand (icode
, args
[i
+ 1]);
4120 if (FLOAT_MODE_P (GET_MODE (args
[i
+ 1])))
4121 has_float_operand_p
= true;
4124 if (has_float_operand_p
4125 && insn_data
[icode
].n_operands
> (int) nops
+ 2)
4127 /* Add a flag that indicates whether unpredicated instructions
4129 rtx pred
= m_ops
[1].value
;
4130 if (flag_trapping_math
&& pred
!= CONST1_RTX (GET_MODE (pred
)))
4131 add_integer_operand (SVE_STRICT_GP
);
4133 add_integer_operand (SVE_RELAXED_GP
);
4136 return generate_insn (icode
);
4139 /* Implement the call using instruction ICODE, which does the equivalent of:
4141 OUTPUT = COND ? FN (INPUTS) : FALLBACK;
4143 The instruction operands are in the order above: OUTPUT, COND, INPUTS
4144 and FALLBACK. MERGE_ARGNO is the argument that provides FALLBACK for _m
4145 functions, or DEFAULT_MERGE_ARGNO if we should apply the usual rules. */
4147 function_expander::use_cond_insn (insn_code icode
, unsigned int merge_argno
)
4149 /* At present we never need to handle PRED_none, which would involve
4150 creating a new predicate rather than using one supplied by the user. */
4151 gcc_assert (pred
!= PRED_none
);
4152 /* Discount the output, predicate and fallback value. */
4153 unsigned int nops
= insn_data
[icode
].n_operands
- 3;
4154 machine_mode mode
= insn_data
[icode
].operand
[0].mode
;
4156 unsigned int opno
= 0;
4157 rtx fallback_arg
= get_fallback_value (mode
, nops
, merge_argno
, opno
);
4158 rtx pred
= args
[opno
++];
4160 add_output_operand (icode
);
4161 add_input_operand (icode
, pred
);
4162 for (unsigned int i
= 0; i
< nops
; ++i
)
4163 add_input_operand (icode
, args
[opno
+ i
]);
4164 add_input_operand (icode
, fallback_arg
);
4165 return generate_insn (icode
);
4168 /* Implement the call using instruction ICODE, which is a select-like
4169 operation with the following operands:
4176 MERGE_ARGNO is the argument that provides the "false" value for _m
4177 functions, or DEFAULT_MERGE_ARGNO if we should apply the usual rules. */
4179 function_expander::use_vcond_mask_insn (insn_code icode
,
4180 unsigned int merge_argno
)
4182 machine_mode mode
= vector_mode (0);
4184 unsigned int opno
= 0;
4185 rtx false_arg
= get_fallback_value (mode
, 1, merge_argno
, opno
);
4186 rtx pred_arg
= args
[opno
++];
4187 rtx true_arg
= args
[opno
++];
4189 add_output_operand (icode
);
4190 add_input_operand (icode
, true_arg
);
4191 add_input_operand (icode
, false_arg
);
4192 add_input_operand (icode
, pred_arg
);
4193 return generate_insn (icode
);
4196 /* Implement the call using instruction ICODE, which loads memory operand 1
4197 into register operand 0 under the control of predicate operand 2.
4198 Extending loads have a further predicate (operand 3) that nominally
4199 controls the extension. */
4201 function_expander::use_contiguous_load_insn (insn_code icode
)
4203 machine_mode mem_mode
= memory_vector_mode ();
4205 add_output_operand (icode
);
4206 add_mem_operand (mem_mode
, get_contiguous_base (mem_mode
));
4207 add_input_operand (icode
, args
[0]);
4208 if (GET_MODE_UNIT_BITSIZE (mem_mode
) < type_suffix (0).element_bits
)
4209 add_input_operand (icode
, CONSTM1_RTX (VNx16BImode
));
4210 return generate_insn (icode
);
4213 /* Implement the call using instruction ICODE, which prefetches from
4214 address operand 1 under the control of predicate operand 0.
4215 Operands 2, 3 and 4 respectively specify the svprfop value,
4216 the PREFETCH rw flag and the PREFETCH locality. */
4218 function_expander::use_contiguous_prefetch_insn (insn_code icode
)
4220 add_input_operand (icode
, args
[0]);
4221 add_address_operand (get_contiguous_base (VNx16QImode
));
4222 for (unsigned int i
= args
.length () - 3; i
< args
.length (); ++i
)
4223 add_input_operand (icode
, args
[i
]);
4224 return generate_insn (icode
);
4227 /* Implement the call using instruction ICODE, which stores register operand 1
4228 into memory operand 0 under the control of predicate operand 2. */
4230 function_expander::use_contiguous_store_insn (insn_code icode
)
4232 machine_mode mem_mode
= memory_vector_mode ();
4234 add_mem_operand (mem_mode
, get_contiguous_base (mem_mode
));
4235 add_input_operand (icode
, args
.last ());
4236 add_input_operand (icode
, args
[0]);
4237 return generate_insn (icode
);
4240 /* Implement the call using one of the following strategies, chosen in order:
4242 (1) "aarch64_pred_<optab><mode>_z" for PRED_z predicate functions
4244 (2) "aarch64_pred_<optab><mode>" for PRED_x functions
4246 (3) a normal unpredicated optab for PRED_none and PRED_x functions,
4247 dropping the predicate in the latter case
4249 (4) an unpredicated "aarch64_sve_<code_optab><mode>" for PRED_none and
4250 PRED_x functions, again dropping the predicate for PRED_x
4252 (5) "cond_<optab><mode>" otherwise
4254 where <optab> corresponds to:
4256 - CODE_FOR_SINT for signed integers
4257 - CODE_FOR_UINT for unsigned integers
4258 - UNSPEC_FOR_COND_FP for predicated floating-point
4259 - UNSPEC_FOR_UNCOND_FP for unpredicated floating-point
4261 and where <code_optab> is like <optab>, but uses CODE_FOR_SINT instead
4262 of UNSPEC_FOR_FP for floating-point values.
4264 MERGE_ARGNO is the argument that provides the values of inactive lanes for
4265 _m functions, or DEFAULT_MERGE_ARGNO if we should apply the usual rules. */
4267 function_expander::map_to_rtx_codes (rtx_code code_for_sint
,
4268 rtx_code code_for_uint
,
4269 int unspec_for_cond_fp
,
4270 int unspec_for_uncond_fp
,
4271 unsigned int merge_argno
)
4273 machine_mode mode
= tuple_mode (0);
4274 rtx_code code
= (type_suffix (0).unsigned_p
? code_for_uint
: code_for_sint
);
4277 if (mode_suffix_id
== MODE_single
)
4279 gcc_assert (pred
== PRED_none
);
4280 if (type_suffix (0).integer_p
)
4281 icode
= code_for_aarch64_sve_single (code
, mode
);
4283 icode
= code_for_aarch64_sve_single (unspec_for_uncond_fp
, mode
);
4284 return use_exact_insn (icode
);
4287 /* Handle predicate logic operations, which always use _z predication. */
4288 if (type_suffix (0).tclass
== TYPE_bool
)
4290 gcc_assert (pred
== PRED_z
&& code_for_uint
== code_for_sint
);
4291 return use_exact_insn (code_for_aarch64_pred_z (code
, mode
));
4294 /* First try using UNSPEC_PRED_X patterns for _x predication,
4298 if (type_suffix (0).integer_p
)
4299 icode
= maybe_code_for_aarch64_pred (code
, mode
);
4301 icode
= maybe_code_for_aarch64_pred (unspec_for_cond_fp
, mode
);
4302 if (icode
!= CODE_FOR_nothing
)
4303 return use_pred_x_insn (icode
);
4306 /* Otherwise expand PRED_none and PRED_x operations without a predicate.
4307 Floating-point operations conventionally use the signed rtx code. */
4308 if (pred
== PRED_none
|| pred
== PRED_x
)
4310 if (type_suffix (0).float_p
&& unspec_for_uncond_fp
>= 0)
4311 icode
= maybe_code_for_aarch64_sve (unspec_for_uncond_fp
, mode
);
4313 icode
= direct_optab_handler (code_to_optab (code
), 0);
4314 if (icode
== CODE_FOR_nothing
)
4315 icode
= code_for_aarch64_sve (code
, mode
);
4316 return use_unpred_insn (icode
);
4319 /* Don't use cond_*_optabs here, since not all codes have one yet. */
4320 if (type_suffix (0).integer_p
)
4321 icode
= code_for_cond (code
, mode
);
4323 icode
= code_for_cond (unspec_for_cond_fp
, mode
);
4324 return use_cond_insn (icode
, merge_argno
);
4327 /* Implement the call using one of the following strategies, chosen in order:
4329 (1) "aarch64_pred_<optab><mode>" for PRED_x functions; this is a
4332 (2) "aarch64_sve_<optab><mode>" for PRED_none and PRED_x functions;
4333 this is an unpredicated pattern
4335 (3) "cond_<optab><mode>" otherwise
4337 where <optab> corresponds to:
4339 - UNSPEC_FOR_SINT for signed integers
4340 - UNSPEC_FOR_UINT for unsigned integers
4341 - UNSPEC_FOR_FP for floating-point values
4343 MERGE_ARGNO is the argument that provides the values of inactive lanes for
4344 _m functions, or DEFAULT_MERGE_ARGNO if we should apply the usual rules. */
4346 function_expander::map_to_unspecs (int unspec_for_sint
, int unspec_for_uint
,
4347 int unspec_for_fp
, unsigned int merge_argno
)
4349 machine_mode mode
= tuple_mode (0);
4350 int unspec
= (!type_suffix (0).integer_p
? unspec_for_fp
4351 : type_suffix (0).unsigned_p
? unspec_for_uint
4354 if (mode_suffix_id
== MODE_single
)
4356 gcc_assert (pred
== PRED_none
);
4357 return use_exact_insn (code_for_aarch64_sve_single (unspec
, mode
));
4362 insn_code icode
= maybe_code_for_aarch64_pred (unspec
, mode
);
4363 if (icode
!= CODE_FOR_nothing
)
4364 return use_pred_x_insn (icode
);
4367 if (pred
== PRED_none
|| pred
== PRED_x
)
4369 insn_code icode
= maybe_code_for_aarch64_sve (unspec
, mode
);
4370 if (icode
!= CODE_FOR_nothing
)
4371 return use_unpred_insn (icode
);
4374 insn_code icode
= code_for_cond (unspec
, vector_mode (0));
4375 return use_cond_insn (icode
, merge_argno
);
4378 /* Expand the call and return its lhs. */
4380 function_expander::expand ()
4382 unsigned int nargs
= call_expr_nargs (call_expr
);
4383 args
.reserve (nargs
);
4384 for (unsigned int i
= 0; i
< nargs
; ++i
)
4385 args
.quick_push (expand_normal (CALL_EXPR_ARG (call_expr
, i
)));
4387 return base
->expand (*this);
4390 /* Return a structure type that contains a single field of type FIELD_TYPE.
4391 The field is called __val, but that's an internal detail rather than
4392 an exposed part of the API. */
4394 wrap_type_in_struct (tree field_type
)
4396 tree field
= build_decl (input_location
, FIELD_DECL
,
4397 get_identifier ("__val"), field_type
);
4398 tree struct_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
4399 DECL_FIELD_CONTEXT (field
) = struct_type
;
4400 TYPE_FIELDS (struct_type
) = field
;
4401 make_type_sizeless (struct_type
);
4402 layout_type (struct_type
);
4406 /* Register a built-in TYPE_DECL called NAME for TYPE. This is used/needed
4407 when TYPE is a structure type. */
4409 register_type_decl (tree type
, const char *name
)
4411 tree decl
= build_decl (input_location
, TYPE_DECL
,
4412 get_identifier (name
), type
);
4413 TYPE_NAME (type
) = decl
;
4414 TYPE_STUB_DECL (type
) = decl
;
4415 lang_hooks
.decls
.pushdecl (decl
);
4416 /* ??? Undo the effect of set_underlying_type for C. The C frontend
4417 doesn't recognize DECL as a built-in because (as intended) the decl has
4418 a real location instead of BUILTINS_LOCATION. The frontend therefore
4419 treats the decl like a normal C "typedef struct foo foo;", expecting
4420 the type for tag "struct foo" to have a dummy unnamed TYPE_DECL instead
4421 of the named one we attached above. It then sets DECL_ORIGINAL_TYPE
4422 on the supposedly unnamed decl, creating a circularity that upsets
4425 We don't want to follow the normal C model and create "struct foo"
4426 tags for tuple types since (a) the types are supposed to be opaque
4427 and (b) they couldn't be defined as a real struct anyway. Treating
4428 the TYPE_DECLs as "typedef struct foo foo;" without creating
4429 "struct foo" would lead to confusing error messages. */
4430 DECL_ORIGINAL_TYPE (decl
) = NULL_TREE
;
4433 /* Register the built-in SVE ABI types, such as __SVBool_t. */
4435 register_builtin_types ()
4437 #define DEF_SVE_TYPE(ACLE_NAME, NCHARS, ABI_NAME, SCALAR_TYPE) \
4438 scalar_types[VECTOR_TYPE_ ## ACLE_NAME] = SCALAR_TYPE;
4439 #include "aarch64-sve-builtins.def"
4441 for (unsigned int i
= 0; i
< NUM_VECTOR_TYPES
; ++i
)
4444 unsigned int num_zr
= 0, num_pr
= 0;
4445 if (vector_type_index (i
) == VECTOR_TYPE_svcount_t
)
4447 vectype
= abi_vector_types
[VECTOR_TYPE_svbool_t
];
4448 vectype
= wrap_type_in_struct (vectype
);
4453 tree eltype
= scalar_types
[i
];
4454 if (eltype
== boolean_type_node
)
4456 vectype
= build_truth_vector_type_for_mode (BYTES_PER_SVE_VECTOR
,
4462 scalar_mode elmode
= SCALAR_TYPE_MODE (eltype
);
4463 unsigned int elbytes
= GET_MODE_SIZE (elmode
);
4464 poly_uint64 nunits
= exact_div (BYTES_PER_SVE_VECTOR
, elbytes
);
4466 = aarch64_sve_data_mode (elmode
, nunits
).require ();
4467 vectype
= build_vector_type_for_mode (eltype
, mode
);
4468 auto size
= wi::to_poly_offset (TYPE_SIZE (vectype
));
4469 gcc_assert (VECTOR_MODE_P (TYPE_MODE (vectype
))
4470 && TYPE_MODE (vectype
) == mode
4471 && TYPE_MODE_RAW (vectype
) == mode
4472 && TYPE_ALIGN (vectype
) == 128
4473 && known_eq (size
, BITS_PER_SVE_VECTOR
));
4476 vectype
= build_distinct_type_copy (vectype
);
4477 gcc_assert (vectype
== TYPE_MAIN_VARIANT (vectype
));
4478 SET_TYPE_STRUCTURAL_EQUALITY (vectype
);
4479 TYPE_ARTIFICIAL (vectype
) = 1;
4480 TYPE_INDIVISIBLE_P (vectype
) = 1;
4481 make_type_sizeless (vectype
);
4485 auto size
= wi::to_poly_offset (TYPE_SIZE (vectype
));
4486 gcc_assert (TYPE_MODE (vectype
) == VNx16BImode
4487 && TYPE_MODE (vectype
) == TYPE_MODE_RAW (vectype
)
4488 && TYPE_ALIGN (vectype
) == 16
4489 && known_eq (size
, BYTES_PER_SVE_VECTOR
));
4491 add_sve_type_attribute (vectype
, num_zr
, num_pr
,
4492 vector_types
[i
].mangled_name
,
4493 vector_types
[i
].acle_name
);
4494 abi_vector_types
[i
] = vectype
;
4495 if (TREE_CODE (vectype
) == RECORD_TYPE
)
4496 register_type_decl (vectype
, vector_types
[i
].abi_name
);
4498 lang_hooks
.types
.register_builtin_type (vectype
,
4499 vector_types
[i
].abi_name
);
4503 /* Initialize all compiler built-ins related to SVE that should be
4504 defined at start-up. */
4509 register_builtin_types ();
4512 handle_arm_sve_h (false);
4513 handle_arm_sme_h (false);
4514 handle_arm_neon_sve_bridge_h (false);
4518 /* Register vector type TYPE under its arm_sve.h name. */
4520 register_vector_type (vector_type_index type
)
4522 tree vectype
= abi_vector_types
[type
];
4523 tree id
= get_identifier (vector_types
[type
].acle_name
);
4524 tree decl
= build_decl (input_location
, TYPE_DECL
, id
, vectype
);
4525 decl
= lang_hooks
.decls
.pushdecl (decl
);
4527 /* Record the new ACLE type if pushdecl succeeded without error. Use
4528 the ABI type otherwise, so that the type we record at least has the
4529 right form, even if it doesn't have the right name. This should give
4530 better error recovery behavior than installing error_mark_node or
4531 installing an incorrect type. */
4533 && TREE_CODE (decl
) == TYPE_DECL
4534 && TREE_TYPE (decl
) != error_mark_node
4535 && TYPE_MAIN_VARIANT (TREE_TYPE (decl
)) == vectype
)
4536 vectype
= TREE_TYPE (decl
);
4537 acle_vector_types
[0][type
] = vectype
;
4540 /* Register the tuple type that contains NUM_VECTORS vectors of type TYPE. */
4542 register_tuple_type (unsigned int num_vectors
, vector_type_index type
)
4544 tree vector_type
= acle_vector_types
[0][type
];
4545 bool is_pred
= GET_MODE_CLASS (TYPE_MODE (vector_type
)) == MODE_VECTOR_BOOL
;
4547 /* Work out the structure name. */
4548 char buffer
[sizeof ("svbfloat16x4_t")];
4549 const char *vector_type_name
= vector_types
[type
].acle_name
;
4550 snprintf (buffer
, sizeof (buffer
), "%.*sx%d_t",
4551 (int) strlen (vector_type_name
) - 2, vector_type_name
,
4554 /* The contents of the type are opaque, so we can define them in any
4555 way that maps to the correct ABI type.
4557 Here we choose to use the same layout as for arm_neon.h, but with
4558 "__val" instead of "val":
4560 struct svfooxN_t { svfoo_t __val[N]; };
4562 (It wouldn't be possible to write that directly in C or C++ for
4563 sizeless types, but that's not a problem for this function.)
4565 Using arrays simplifies the handling of svget and svset for variable
4567 tree array_type
= build_array_type_nelts (vector_type
, num_vectors
);
4568 gcc_assert (VECTOR_MODE_P (TYPE_MODE (array_type
))
4569 && TYPE_MODE_RAW (array_type
) == TYPE_MODE (array_type
)
4570 && TYPE_ALIGN (array_type
) == (is_pred
? 16 : 128));
4572 tree tuple_type
= wrap_type_in_struct (array_type
);
4574 add_sve_type_attribute (tuple_type
, 0, num_vectors
, NULL
, buffer
);
4576 add_sve_type_attribute (tuple_type
, num_vectors
, 0, NULL
, buffer
);
4577 gcc_assert (VECTOR_MODE_P (TYPE_MODE (tuple_type
))
4578 && TYPE_MODE_RAW (tuple_type
) == TYPE_MODE (tuple_type
)
4579 && TYPE_ALIGN (tuple_type
) == TYPE_ALIGN (array_type
));
4581 register_type_decl (tuple_type
, buffer
);
4583 acle_vector_types
[num_vectors
- 1][type
] = tuple_type
;
4586 /* Register the svpattern enum. */
4588 register_svpattern ()
4590 auto_vec
<string_int_pair
, 32> values
;
4591 #define PUSH(UPPER, LOWER, VALUE) \
4592 values.quick_push (string_int_pair ("SV_" #UPPER, VALUE));
4593 AARCH64_FOR_SVPATTERN (PUSH
)
4596 acle_svpattern
= lang_hooks
.types
.simulate_enum_decl (input_location
,
4597 "svpattern", &values
);
4600 /* Register the svprfop enum. */
4604 auto_vec
<string_int_pair
, 16> values
;
4605 #define PUSH(UPPER, LOWER, VALUE) \
4606 values.quick_push (string_int_pair ("SV_" #UPPER, VALUE));
4607 AARCH64_FOR_SVPRFOP (PUSH
)
4610 acle_svprfop
= lang_hooks
.types
.simulate_enum_decl (input_location
,
4611 "svprfop", &values
);
4614 /* Implement #pragma GCC aarch64 "arm_sve.h". */
4616 handle_arm_sve_h (bool function_nulls_p
)
4620 error ("duplicate definition of %qs", "arm_sve.h");
4626 /* Define the vector and tuple types. */
4627 for (unsigned int type_i
= 0; type_i
< NUM_VECTOR_TYPES
; ++type_i
)
4629 vector_type_index type
= vector_type_index (type_i
);
4630 register_vector_type (type
);
4631 if (type
!= VECTOR_TYPE_svcount_t
)
4632 for (unsigned int count
= 2; count
<= MAX_TUPLE_SIZE
; ++count
)
4633 if (type
!= VECTOR_TYPE_svbool_t
|| count
== 2)
4634 register_tuple_type (count
, type
);
4637 /* Define the enums. */
4638 register_svpattern ();
4639 register_svprfop ();
4641 /* Define the functions. */
4642 function_table
= new hash_table
<registered_function_hasher
> (1023);
4643 function_builder
builder (arm_sve_handle
, function_nulls_p
);
4644 for (unsigned int i
= 0; i
< ARRAY_SIZE (function_groups
); ++i
)
4645 builder
.register_function_group (function_groups
[i
]);
4648 /* Implement #pragma GCC aarch64 "arm_neon_sve_bridge.h". */
4650 handle_arm_neon_sve_bridge_h (bool function_nulls_p
)
4652 if (initial_indexes
[arm_sme_handle
] == 0)
4653 handle_arm_sme_h (true);
4655 /* Define the functions. */
4656 function_builder
builder (arm_neon_sve_handle
, function_nulls_p
);
4657 for (unsigned int i
= 0; i
< ARRAY_SIZE (neon_sve_function_groups
); ++i
)
4658 builder
.register_function_group (neon_sve_function_groups
[i
]);
4661 /* Return the function decl with SVE function subcode CODE, or error_mark_node
4662 if no such function exists. */
4664 builtin_decl (unsigned int code
, bool)
4666 if (code
>= vec_safe_length (registered_functions
))
4667 return error_mark_node
;
4668 return (*registered_functions
)[code
]->decl
;
4671 /* Implement #pragma GCC aarch64 "arm_sme.h". */
4673 handle_arm_sme_h (bool function_nulls_p
)
4675 if (!function_table
)
4677 error ("%qs defined without first defining %qs",
4678 "arm_sme.h", "arm_sve.h");
4684 function_builder
builder (arm_sme_handle
, function_nulls_p
);
4685 for (unsigned int i
= 0; i
< ARRAY_SIZE (sme_function_groups
); ++i
)
4686 builder
.register_function_group (sme_function_groups
[i
]);
4689 /* If we're implementing manual overloading, check whether the SVE
4690 function with subcode CODE is overloaded, and if so attempt to
4691 determine the corresponding non-overloaded function. The call
4692 occurs at location LOCATION and has the arguments given by ARGLIST.
4694 If the call is erroneous, report an appropriate error and return
4695 error_mark_node. Otherwise, if the function is overloaded, return
4696 the decl of the non-overloaded function. Return NULL_TREE otherwise,
4697 indicating that the call should be processed in the normal way. */
4699 resolve_overloaded_builtin (location_t location
, unsigned int code
,
4700 vec
<tree
, va_gc
> *arglist
)
4702 if (code
>= vec_safe_length (registered_functions
))
4705 registered_function
&rfn
= *(*registered_functions
)[code
];
4706 if (rfn
.overloaded_p
)
4707 return function_resolver (location
, rfn
.instance
, rfn
.decl
,
4708 *arglist
).resolve ();
4712 /* Perform any semantic checks needed for a call to the SVE function
4713 with subcode CODE, such as testing for integer constant expressions.
4714 The call occurs at location LOCATION and has NARGS arguments,
4715 given by ARGS. FNDECL is the original function decl, before
4716 overload resolution.
4718 Return true if the call is valid, otherwise report a suitable error. */
4720 check_builtin_call (location_t location
, vec
<location_t
>, unsigned int code
,
4721 tree fndecl
, unsigned int nargs
, tree
*args
)
4723 const registered_function
&rfn
= *(*registered_functions
)[code
];
4724 if (!aarch64_check_required_extensions (location
, rfn
.decl
,
4725 rfn
.required_extensions
))
4727 return function_checker (location
, rfn
.instance
, fndecl
,
4728 TREE_TYPE (rfn
.decl
), nargs
, args
).check ();
4731 /* Attempt to fold STMT, given that it's a call to the SVE function
4732 with subcode CODE. Return the new statement on success and null
4733 on failure. Insert any other new statements at GSI. */
4735 gimple_fold_builtin (unsigned int code
, gimple_stmt_iterator
*gsi
, gcall
*stmt
)
4737 registered_function
&rfn
= *(*registered_functions
)[code
];
4738 return gimple_folder (rfn
.instance
, rfn
.decl
, gsi
, stmt
).fold ();
4741 /* Expand a call to the SVE function with subcode CODE. EXP is the call
4742 expression and TARGET is the preferred location for the result.
4743 Return the value of the lhs. */
4745 expand_builtin (unsigned int code
, tree exp
, rtx target
)
4747 registered_function
&rfn
= *(*registered_functions
)[code
];
4748 if (!aarch64_check_required_extensions (EXPR_LOCATION (exp
), rfn
.decl
,
4749 rfn
.required_extensions
))
4751 return function_expander (rfn
.instance
, rfn
.decl
, exp
, target
).expand ();
4754 /* If TYPE is a built-in type defined by the SVE ABI, return the mangled name,
4755 otherwise return NULL. */
4757 mangle_builtin_type (const_tree type
)
4759 /* ??? The C++ frontend normally strips qualifiers and attributes before
4760 calling this hook, adding separate mangling for attributes that affect
4761 type identity. Fortunately the type copy will have the same TYPE_NAME
4762 as the original, so we can get the attributes from there. */
4763 if (TYPE_NAME (type
) && TREE_CODE (TYPE_NAME (type
)) == TYPE_DECL
)
4764 type
= TREE_TYPE (TYPE_NAME (type
));
4765 if (tree attr
= lookup_sve_type_attribute (type
))
4766 if (tree id
= TREE_VALUE (chain_index (2, TREE_VALUE (attr
))))
4767 return IDENTIFIER_POINTER (id
);
4771 /* Return true if TYPE is a built-in SVE type defined by the ABI or ACLE. */
4773 builtin_type_p (const_tree type
)
4775 return lookup_sve_type_attribute (type
);
4778 /* Return true if TYPE is a built-in SVE type defined by the ABI or ACLE.
4779 If so, store the number of constituent SVE vectors in *NUM_ZR and the
4780 number of constituent SVE predicates in *NUM_PR. */
4782 builtin_type_p (const_tree type
, unsigned int *num_zr
, unsigned int *num_pr
)
4784 if (tree attr
= lookup_sve_type_attribute (type
))
4786 tree num_zr_node
= TREE_VALUE (attr
);
4787 tree num_pr_node
= TREE_CHAIN (num_zr_node
);
4788 *num_zr
= tree_to_uhwi (TREE_VALUE (num_zr_node
));
4789 *num_pr
= tree_to_uhwi (TREE_VALUE (num_pr_node
));
4795 /* ATTRS is the attribute list for a sizeless SVE type. Return the
4796 attributes of the associated fixed-length SVE type, taking the
4797 "SVE type" attributes from NEW_SVE_TYPE_ARGS. */
4799 get_arm_sve_vector_bits_attributes (tree old_attrs
, tree new_sve_type_args
)
4801 tree new_attrs
= NULL_TREE
;
4802 tree
*ptr
= &new_attrs
;
4803 for (tree attr
= old_attrs
; attr
; attr
= TREE_CHAIN (attr
))
4805 tree name
= get_attribute_name (attr
);
4806 if (is_attribute_p ("SVE sizeless type", name
))
4809 tree args
= TREE_VALUE (attr
);
4810 if (is_attribute_p ("SVE type", name
))
4811 args
= new_sve_type_args
;
4812 *ptr
= tree_cons (TREE_PURPOSE (attr
), args
, NULL_TREE
);
4813 ptr
= &TREE_CHAIN (*ptr
);
4818 /* An attribute callback for the "arm_sve_vector_bits" attribute. */
4820 handle_arm_sve_vector_bits_attribute (tree
*node
, tree
, tree args
, int,
4823 *no_add_attrs
= true;
4826 tree attr
= lookup_sve_type_attribute (type
);
4829 error ("%qs applied to non-SVE type %qT", "arm_sve_vector_bits", type
);
4833 if (!VECTOR_TYPE_P (type
))
4835 error ("%qs applied to non-vector type %qT",
4836 "arm_sve_vector_bits", type
);
4840 if (!sizeless_type_p (type
))
4842 error ("%qs applied to type %qT, which already has a size",
4843 "arm_sve_vector_bits", type
);
4847 tree size
= TREE_VALUE (args
);
4848 if (TREE_CODE (size
) != INTEGER_CST
)
4850 error ("%qs requires an integer constant expression",
4851 "arm_sve_vector_bits");
4855 unsigned HOST_WIDE_INT value
= tree_to_uhwi (size
);
4856 if (maybe_ne (value
, BITS_PER_SVE_VECTOR
))
4858 warning (OPT_Wattributes
, "unsupported SVE vector size");
4862 /* Construct a new list of "SVE type" attribute arguments. */
4863 tree new_sve_type_args
= copy_list (TREE_VALUE (attr
));
4865 /* Mangle the type as an instance of the imaginary template:
4867 __SVE_VLS<typename, unsigned>
4869 where the first parameter is the SVE type and where the second
4870 parameter is the SVE vector length in bits. */
4871 tree mangled_name_node
= chain_index (2, new_sve_type_args
);
4872 const char *old_mangled_name
4873 = IDENTIFIER_POINTER (TREE_VALUE (mangled_name_node
));
4874 char *new_mangled_name
4875 = xasprintf ("9__SVE_VLSI%sLj%dEE", old_mangled_name
, (int) value
);
4876 TREE_VALUE (mangled_name_node
) = get_identifier (new_mangled_name
);
4877 free (new_mangled_name
);
4879 /* FIXME: The type ought to be a distinct copy in all cases, but
4880 currently that makes the C frontend reject conversions between
4881 svbool_t and its fixed-length variants. Using a type variant
4882 avoids that but means that we treat some ambiguous combinations
4885 tree base_type
= TYPE_MAIN_VARIANT (type
);
4886 if (lang_GNU_C () && VECTOR_BOOLEAN_TYPE_P (type
))
4887 new_type
= build_variant_type_copy (base_type
);
4889 new_type
= build_distinct_type_copy (base_type
);
4891 /* Construct a TYPE_DECL for the new type. This serves two purposes:
4893 - It ensures we don't print the original TYPE_DECL in error messages.
4894 Printing the original name would be confusing because there are
4895 situations in which the distinction between the original type and
4896 the new type matters. For example:
4898 __SVInt8_t __attribute__((arm_sve_vector_bits(512))) *a;
4903 is invalid in C++, but without this, we'd print both types in
4906 - Having a separate TYPE_DECL is necessary to ensure that C++
4907 mangling works correctly. See mangle_builtin_type for details.
4909 The name of the decl is something like:
4911 svint8_t __attribute__((arm_sve_vector_bits(512)))
4913 This is a compromise. It would be more accurate to use something like:
4915 __SVInt8_t __attribute__((arm_sve_vector_bits(512)))
4917 but the <arm_sve.h> name is likely to be more meaningful. */
4918 tree acle_name_node
= TREE_CHAIN (mangled_name_node
);
4919 const char *old_type_name
= IDENTIFIER_POINTER (TREE_VALUE (acle_name_node
));
4921 = xasprintf ("%s __attribute__((arm_sve_vector_bits(%d)))",
4922 old_type_name
, (int) value
);
4923 tree decl
= build_decl (BUILTINS_LOCATION
, TYPE_DECL
,
4924 get_identifier (new_type_name
), new_type
);
4925 DECL_ARTIFICIAL (decl
) = 1;
4926 TYPE_NAME (new_type
) = decl
;
4927 free (new_type_name
);
4929 /* Allow the GNU vector extensions to be applied to vectors.
4930 The extensions aren't yet defined for packed predicates,
4931 so continue to treat them as abstract entities for now. */
4932 if (!VECTOR_BOOLEAN_TYPE_P (new_type
))
4933 TYPE_INDIVISIBLE_P (new_type
) = 0;
4935 /* The new type is a normal sized type; it doesn't have the same
4936 restrictions as sizeless types. */
4937 TYPE_ATTRIBUTES (new_type
)
4938 = get_arm_sve_vector_bits_attributes (TYPE_ATTRIBUTES (new_type
),
4941 /* Apply the relevant attributes, qualifiers and alignment of TYPE,
4942 if they differ from the original (sizeless) BASE_TYPE. */
4943 if (TYPE_ATTRIBUTES (base_type
) != TYPE_ATTRIBUTES (type
)
4944 || TYPE_QUALS (base_type
) != TYPE_QUALS (type
))
4947 = get_arm_sve_vector_bits_attributes (TYPE_ATTRIBUTES (type
),
4949 new_type
= build_type_attribute_qual_variant (new_type
, attrs
,
4952 if (TYPE_ALIGN (base_type
) != TYPE_ALIGN (type
))
4953 new_type
= build_aligned_type (new_type
, TYPE_ALIGN (type
));
4959 /* Implement TARGET_VERIFY_TYPE_CONTEXT for SVE types. */
4961 verify_type_context (location_t loc
, type_context_kind context
,
4962 const_tree type
, bool silent_p
)
4964 if (!sizeless_type_p (type
))
4970 case TCTX_STATIC_STORAGE
:
4972 error_at (loc
, "SVE type %qT does not have a fixed size", type
);
4977 error_at (loc
, "SVE type %qT does not have a defined alignment", type
);
4980 case TCTX_THREAD_STORAGE
:
4982 error_at (loc
, "variables of type %qT cannot have thread-local"
4983 " storage duration", type
);
4986 case TCTX_POINTER_ARITH
:
4988 error_at (loc
, "arithmetic on pointer to SVE type %qT", type
);
4994 else if (lang_GNU_CXX ())
4995 error_at (loc
, "member variables cannot have SVE type %qT", type
);
4997 error_at (loc
, "fields cannot have SVE type %qT", type
);
5000 case TCTX_ARRAY_ELEMENT
:
5002 error_at (loc
, "array elements cannot have SVE type %qT", type
);
5005 case TCTX_ALLOCATION
:
5007 error_at (loc
, "cannot allocate objects with SVE type %qT", type
);
5010 case TCTX_DEALLOCATION
:
5012 error_at (loc
, "cannot delete objects with SVE type %qT", type
);
5015 case TCTX_EXCEPTIONS
:
5017 error_at (loc
, "cannot throw or catch SVE type %qT", type
);
5020 case TCTX_CAPTURE_BY_COPY
:
5022 error_at (loc
, "capture by copy of SVE type %qT", type
);
5030 using namespace aarch64_sve
;
5033 gt_ggc_mx (function_instance
*)
5038 gt_pch_nx (function_instance
*)
5043 gt_pch_nx (function_instance
*, gt_pointer_operator
, void *)
5047 #include "gt-aarch64-sve-builtins.h"