aboutsummaryrefslogtreecommitdiff
path: root/gcc/genmodes.cc
diff options
context:
space:
mode:
authorChristophe Lyon <christophe.lyon@arm.com>2021-10-13 09:16:22 +0000
committerChristophe Lyon <christophe.lyon@foss.st.com>2022-02-22 15:55:07 +0000
commit884f77b4222289510e1df9db2889b60c5df6fcda (patch)
tree0eb87f48af7d3493bea416f34dbad130a491bf2b /gcc/genmodes.cc
parent0d0aaea105f6b5ddd9b4763e4cbd16ef65a74cb9 (diff)
downloadgcc-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.cc71
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 ();
}