diff options
author | Christophe Lyon <christophe.lyon@arm.com> | 2021-10-13 09:16:22 +0000 |
---|---|---|
committer | Christophe Lyon <christophe.lyon@foss.st.com> | 2022-02-22 15:55:07 +0000 |
commit | 884f77b4222289510e1df9db2889b60c5df6fcda (patch) | |
tree | 0eb87f48af7d3493bea416f34dbad130a491bf2b /gcc/genmodes.cc | |
parent | 0d0aaea105f6b5ddd9b4763e4cbd16ef65a74cb9 (diff) | |
download | gcc-884f77b4222289510e1df9db2889b60c5df6fcda.zip gcc-884f77b4222289510e1df9db2889b60c5df6fcda.tar.gz gcc-884f77b4222289510e1df9db2889b60c5df6fcda.tar.bz2 |
arm: Implement MVE predicates as vectors of booleans
This patch implements support for vectors of booleans to support MVE
predicates, instead of HImode. Since the ABI mandates pred16_t (aka
uint16_t) to represent predicates in intrinsics prototypes, we
introduce a new "predicate" type qualifier so that we can map relevant
builtins HImode arguments and return value to the appropriate vector
of booleans (VxBI).
We have to update test_vector_ops_duplicate, because it iterates using
an offset in bytes, where we would need to iterate in bits: we stop
iterating when we reach the end of the vector of booleans.
In addition, we have to fix the underlying definition of vectors of
booleans because ARM/MVE needs a different representation than
AArch64/SVE. With ARM/MVE the 'true' bit is duplicated over the
element size, so that a true element of V4BI is represented by
'0b1111'. This patch updates the aarch64 definition of VNx*BI as
needed.
Most of the work of this patch series was carried out while I was
working at STMicroelectronics as a Linaro assignee.
2022-02-22 Christophe Lyon <christophe.lyon@arm.com>
Richard Sandiford <richard.sandiford@arm.com>
gcc/
PR target/100757
PR target/101325
* config/aarch64/aarch64-modes.def (VNx16BI, VNx8BI, VNx4BI,
VNx2BI): Update definition.
* config/arm/arm-builtins.cc (arm_init_simd_builtin_types): Add new
simd types.
(arm_init_builtin): Map predicate vectors arguments to HImode.
(arm_expand_builtin_args): Move HImode predicate arguments to VxBI
rtx. Move return value to HImode rtx.
* config/arm/arm-builtins.h (arm_type_qualifiers): Add qualifier_predicate.
* config/arm/arm-modes.def (B2I, B4I, V16BI, V8BI, V4BI): New modes.
* config/arm/arm-simd-builtin-types.def (Pred1x16_t,
Pred2x8_t,Pred4x4_t): New.
* emit-rtl.cc (init_emit_once): Handle all boolean modes.
* genmodes.cc (mode_data): Add boolean field.
(blank_mode): Initialize it.
(make_complex_modes): Fix handling of boolean modes.
(make_vector_modes): Likewise.
(VECTOR_BOOL_MODE): Use new COMPONENT parameter.
(make_vector_bool_mode): Likewise.
(BOOL_MODE): New.
(make_bool_mode): New.
(emit_insn_modes_h): Fix generation of boolean modes.
(emit_class_narrowest_mode): Likewise.
* machmode.def: (VECTOR_BOOL_MODE): Document new COMPONENT
parameter. Use new BOOL_MODE instead of FRACTIONAL_INT_MODE to
define BImode.
* rtx-vector-builder.cc (rtx_vector_builder::find_cached_value):
Fix handling of constm1_rtx for VECTOR_BOOL.
* simplify-rtx.cc (native_encode_rtx): Fix support for VECTOR_BOOL.
(native_decode_vector_rtx): Likewise.
(test_vector_ops_duplicate): Skip vec_merge test
with vectors of booleans.
* varasm.cc (output_constant_pool_2): Likewise.
Diffstat (limited to 'gcc/genmodes.cc')
-rw-r--r-- | gcc/genmodes.cc | 71 |
1 files changed, 50 insertions, 21 deletions
diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc index 0185716..59850bb 100644 --- a/gcc/genmodes.cc +++ b/gcc/genmodes.cc @@ -78,6 +78,7 @@ struct mode_data bool need_bytesize_adj; /* true if this mode needs dynamic size adjustment */ unsigned int int_n; /* If nonzero, then __int<INT_N> will be defined */ + bool boolean; }; static struct mode_data *modes[MAX_MODE_CLASS]; @@ -88,7 +89,8 @@ static const struct mode_data blank_mode = { 0, "<unknown>", MAX_MODE_CLASS, 0, -1U, -1U, -1U, -1U, 0, 0, 0, 0, 0, 0, - "<unknown>", 0, 0, 0, 0, false, false, 0 + "<unknown>", 0, 0, 0, 0, false, false, 0, + false }; static htab_t modes_by_name; @@ -456,7 +458,7 @@ make_complex_modes (enum mode_class cl, size_t m_len; /* Skip BImode. FIXME: BImode probably shouldn't be MODE_INT. */ - if (m->precision == 1) + if (m->boolean) continue; m_len = strlen (m->name); @@ -528,7 +530,7 @@ make_vector_modes (enum mode_class cl, const char *prefix, unsigned int width, not be necessary. */ if (cl == MODE_FLOAT && m->bytesize == 1) continue; - if (cl == MODE_INT && m->precision == 1) + if (m->boolean) continue; if ((size_t) snprintf (buf, sizeof buf, "%s%u%s", prefix, @@ -548,17 +550,18 @@ make_vector_modes (enum mode_class cl, const char *prefix, unsigned int width, /* Create a vector of booleans called NAME with COUNT elements and BYTESIZE bytes in total. */ -#define VECTOR_BOOL_MODE(NAME, COUNT, BYTESIZE) \ - make_vector_bool_mode (#NAME, COUNT, BYTESIZE, __FILE__, __LINE__) +#define VECTOR_BOOL_MODE(NAME, COUNT, COMPONENT, BYTESIZE) \ + make_vector_bool_mode (#NAME, COUNT, #COMPONENT, BYTESIZE, \ + __FILE__, __LINE__) static void ATTRIBUTE_UNUSED make_vector_bool_mode (const char *name, unsigned int count, - unsigned int bytesize, const char *file, - unsigned int line) + const char *component, unsigned int bytesize, + const char *file, unsigned int line) { - struct mode_data *m = find_mode ("BI"); + struct mode_data *m = find_mode (component); if (!m) { - error ("%s:%d: no mode \"BI\"", file, line); + error ("%s:%d: no mode \"%s\"", file, line, component); return; } @@ -596,6 +599,20 @@ make_int_mode (const char *name, m->precision = precision; } +#define BOOL_MODE(N, B, Y) \ + make_bool_mode (#N, B, Y, __FILE__, __LINE__) + +static void +make_bool_mode (const char *name, + unsigned int precision, unsigned int bytesize, + const char *file, unsigned int line) +{ + struct mode_data *m = new_mode (MODE_INT, name, file, line); + m->bytesize = bytesize; + m->precision = precision; + m->boolean = true; +} + #define OPAQUE_MODE(N, B) \ make_opaque_mode (#N, -1U, B, __FILE__, __LINE__) @@ -1298,9 +1315,21 @@ enum machine_mode\n{"); /* Don't use BImode for MIN_MODE_INT, since otherwise the middle end will try to use it for bitfields in structures and the like, which we do not want. Only the target md file should - generate BImode widgets. */ - if (first && first->precision == 1 && c == MODE_INT) - first = first->next; + generate BImode widgets. Since some targets such as ARM/MVE + define boolean modes with multiple bits, handle those too. */ + if (first && first->boolean) + { + struct mode_data *last_bool = first; + printf (" MIN_MODE_BOOL = E_%smode,\n", first->name); + + while (first && first->boolean) + { + last_bool = first; + first = first->next; + } + + printf (" MAX_MODE_BOOL = E_%smode,\n\n", last_bool->name); + } if (first && last) printf (" MIN_%s = E_%smode,\n MAX_%s = E_%smode,\n\n", @@ -1679,15 +1708,15 @@ emit_class_narrowest_mode (void) print_decl ("unsigned char", "class_narrowest_mode", "MAX_MODE_CLASS"); for (c = 0; c < MAX_MODE_CLASS; c++) - /* Bleah, all this to get the comment right for MIN_MODE_INT. */ - tagged_printf ("MIN_%s", mode_class_names[c], - modes[c] - ? ((c != MODE_INT || modes[c]->precision != 1) - ? modes[c]->name - : (modes[c]->next - ? modes[c]->next->name - : void_mode->name)) - : void_mode->name); + { + /* Bleah, all this to get the comment right for MIN_MODE_INT. */ + struct mode_data *m = modes[c]; + while (m && m->boolean) + m = m->next; + const char *comment_name = (m ? m : void_mode)->name; + + tagged_printf ("MIN_%s", mode_class_names[c], comment_name); + } print_closer (); } |