aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/arm/arm-c.c21
-rw-r--r--gcc/config/arm/arm-mve-builtins.cc196
-rw-r--r--gcc/config/arm/arm-mve-builtins.def39
-rw-r--r--gcc/config/arm/arm-mve-builtins.h41
-rw-r--r--gcc/config/arm/arm-protos.h5
-rw-r--r--gcc/config/arm/arm_mve_types.h30
-rw-r--r--gcc/config/arm/t-arm10
7 files changed, 313 insertions, 29 deletions
diff --git a/gcc/config/arm/arm-c.c b/gcc/config/arm/arm-c.c
index cc7901b..d1414f6 100644
--- a/gcc/config/arm/arm-c.c
+++ b/gcc/config/arm/arm-c.c
@@ -28,6 +28,7 @@
#include "c-family/c-pragma.h"
#include "stringpool.h"
#include "arm-builtins.h"
+#include "arm-protos.h"
tree
arm_resolve_cde_builtin (location_t loc, tree fndecl, void *arglist)
@@ -129,6 +130,24 @@ arm_resolve_cde_builtin (location_t loc, tree fndecl, void *arglist)
return call_expr;
}
+/* Implement "#pragma GCC arm". */
+static void
+arm_pragma_arm (cpp_reader *)
+{
+ tree x;
+ if (pragma_lex (&x) != CPP_STRING)
+ {
+ error ("%<#pragma GCC arm%> requires a string parameter");
+ return;
+ }
+
+ const char *name = TREE_STRING_POINTER (x);
+ if (strcmp (name, "arm_mve_types.h") == 0)
+ arm_mve::handle_arm_mve_types_h ();
+ else
+ error ("unknown %<#pragma GCC arm%> option %qs", name);
+}
+
/* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN. This is currently only
used for the MVE related builtins for the CDE extension.
Here we ensure the type of arguments is such that the size is correct, and
@@ -476,6 +495,8 @@ arm_register_target_pragmas (void)
targetm.target_option.pragma_parse = arm_pragma_target_parse;
targetm.resolve_overloaded_builtin = arm_resolve_overloaded_builtin;
+ c_register_pragma ("GCC", "arm", arm_pragma_arm);
+
#ifdef REGISTER_SUBTARGET_PRAGMAS
REGISTER_SUBTARGET_PRAGMAS ();
#endif
diff --git a/gcc/config/arm/arm-mve-builtins.cc b/gcc/config/arm/arm-mve-builtins.cc
new file mode 100644
index 0000000..71838a8
--- /dev/null
+++ b/gcc/config/arm/arm-mve-builtins.cc
@@ -0,0 +1,196 @@
+/* ACLE support for Arm MVE
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#define IN_TARGET_CODE 1
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "fold-const.h"
+#include "langhooks.h"
+#include "stringpool.h"
+#include "attribs.h"
+#include "diagnostic.h"
+#include "arm-protos.h"
+#include "arm-builtins.h"
+#include "arm-mve-builtins.h"
+
+namespace arm_mve {
+
+/* Static information about each single-predicate or single-vector
+ ACLE type. */
+struct vector_type_info
+{
+ /* The name of the type as declared by arm_mve.h. */
+ const char *acle_name;
+
+ /* Whether the type requires a floating point abi. */
+ const bool requires_float;
+};
+
+/* Flag indicating whether the arm MVE types have been handled. */
+static bool handle_arm_mve_types_p;
+
+/* Information about each single-predicate or single-vector type. */
+static CONSTEXPR const vector_type_info vector_types[] = {
+#define DEF_MVE_TYPE(ACLE_NAME, SCALAR_TYPE) \
+ { #ACLE_NAME, REQUIRES_FLOAT },
+#include "arm-mve-builtins.def"
+#undef DEF_MVE_TYPE
+};
+
+/* The scalar type associated with each vector type. */
+GTY(()) tree scalar_types[NUM_VECTOR_TYPES];
+
+/* The single-predicate and single-vector types, with their built-in
+ "__simd128_..._t" name. Allow an index of NUM_VECTOR_TYPES, which always
+ yields a null tree. */
+static GTY(()) tree abi_vector_types[NUM_VECTOR_TYPES + 1];
+
+/* Same, but with the arm_mve.h names. */
+GTY(()) tree acle_vector_types[3][NUM_VECTOR_TYPES + 1];
+
+/* Return the MVE abi type with element of type TYPE. */
+static tree
+arm_mve_type_for_scalar_type (tree eltype)
+{
+ for (unsigned int i = 0; i < __TYPE_FINAL; ++i)
+ if (arm_simd_types[i].eltype == eltype
+ && GET_MODE_SIZE (arm_simd_types[i].mode) == 16)
+ return arm_simd_types[i].itype;
+
+ gcc_unreachable ();
+}
+
+/* Register the built-in MVE ABI vector types, such as uint32x4_t. */
+static void
+register_builtin_types ()
+{
+#define DEF_MVE_TYPE(ACLE_NAME, SCALAR_TYPE) \
+ scalar_types[VECTOR_TYPE_ ## ACLE_NAME] = SCALAR_TYPE;
+#include "arm-mve-builtins.def"
+#undef DEF_MVE_TYPE
+ for (unsigned int i = 0; i < NUM_VECTOR_TYPES; ++i)
+ {
+ if (vector_types[i].requires_float && !TARGET_HAVE_MVE_FLOAT)
+ continue;
+ tree eltype = scalar_types[i];
+ tree vectype;
+ if (eltype == boolean_type_node)
+ {
+ vectype = get_typenode_from_name (UINT16_TYPE);
+ gcc_assert (GET_MODE_SIZE (TYPE_MODE (vectype)) == 2);
+ }
+ else
+ {
+ vectype = arm_mve_type_for_scalar_type (eltype);
+ gcc_assert (VECTOR_MODE_P (TYPE_MODE (vectype))
+ && GET_MODE_SIZE (TYPE_MODE (vectype)) == 16);
+ }
+ abi_vector_types[i] = vectype;
+ }
+}
+
+/* Register vector type TYPE under its arm_mve.h name. */
+static void
+register_vector_type (vector_type_index type)
+{
+ if (vector_types[type].requires_float && !TARGET_HAVE_MVE_FLOAT)
+ return;
+ tree vectype = abi_vector_types[type];
+ tree id = get_identifier (vector_types[type].acle_name);
+ tree decl = build_decl (input_location, TYPE_DECL, id, vectype);
+ decl = lang_hooks.decls.pushdecl (decl);
+
+ /* Record the new ACLE type if pushdecl succeeded without error. Use
+ the ABI type otherwise, so that the type we record at least has the
+ right form, even if it doesn't have the right name. This should give
+ better error recovery behavior than installing error_mark_node or
+ installing an incorrect type. */
+ if (decl
+ && TREE_CODE (decl) == TYPE_DECL
+ && TREE_TYPE (decl) != error_mark_node
+ && TYPE_MAIN_VARIANT (TREE_TYPE (decl)) == vectype)
+ vectype = TREE_TYPE (decl);
+ acle_vector_types[0][type] = vectype;
+}
+
+/* Register tuple type TYPE with NUM_VECTORS arity under its
+ arm_mve_types.h name. */
+static void
+register_builtin_tuple_types (vector_type_index type)
+{
+ const vector_type_info* info = &vector_types[type];
+ if (scalar_types[type] == boolean_type_node
+ || (info->requires_float && !TARGET_HAVE_MVE_FLOAT))
+ return;
+ const char *vector_type_name = info->acle_name;
+ char buffer[sizeof ("float32x4x2_t")];
+ for (unsigned int num_vectors = 2; num_vectors <= 4; num_vectors += 2)
+ {
+ snprintf (buffer, sizeof (buffer), "%.*sx%d_t",
+ (int) strlen (vector_type_name) - 2, vector_type_name,
+ num_vectors);
+
+ tree vectype = acle_vector_types[0][type];
+ tree arrtype = build_array_type_nelts (vectype, num_vectors);
+ gcc_assert (TYPE_MODE_RAW (arrtype) == TYPE_MODE (arrtype));
+ tree field = build_decl (input_location, FIELD_DECL,
+ get_identifier ("val"), arrtype);
+
+ tree t = lang_hooks.types.simulate_record_decl (input_location, buffer,
+ make_array_slice (&field,
+ 1));
+ gcc_assert (TYPE_MODE_RAW (t) == TYPE_MODE (t));
+ acle_vector_types[num_vectors >> 1][type] = TREE_TYPE (t);
+ }
+}
+
+/* Implement #pragma GCC arm "arm_mve_types.h". */
+void
+handle_arm_mve_types_h ()
+{
+ if (handle_arm_mve_types_p)
+ {
+ error ("duplicate definition of %qs", "arm_mve_types.h");
+ return;
+ }
+ handle_arm_mve_types_p = true;
+ if (!TARGET_HAVE_MVE)
+ {
+ error ("this definition requires the MVE ISA extension");
+ return;
+ }
+ register_builtin_types ();
+ for (unsigned int type_i = 0; type_i < NUM_VECTOR_TYPES; ++type_i)
+ {
+ vector_type_index type = vector_type_index (type_i);
+ register_vector_type (type);
+ if (type_i != VECTOR_TYPE_mve_pred16_t)
+ register_builtin_tuple_types (type);
+ }
+}
+
+} /* end namespace arm_mve */
+
+using namespace arm_mve;
+
+#include "gt-arm-mve-builtins.h"
diff --git a/gcc/config/arm/arm-mve-builtins.def b/gcc/config/arm/arm-mve-builtins.def
new file mode 100644
index 0000000..31bfa60
--- /dev/null
+++ b/gcc/config/arm/arm-mve-builtins.def
@@ -0,0 +1,39 @@
+/* Builtin lists for Arm MVE
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef DEF_MVE_TYPE
+#error "arm-mve-builtins.def included without defining DEF_MVE_TYPE"
+#endif
+
+#define REQUIRES_FLOAT false
+DEF_MVE_TYPE (mve_pred16_t, boolean_type_node)
+DEF_MVE_TYPE (uint8x16_t, unsigned_intQI_type_node)
+DEF_MVE_TYPE (uint16x8_t, unsigned_intHI_type_node)
+DEF_MVE_TYPE (uint32x4_t, unsigned_intSI_type_node)
+DEF_MVE_TYPE (uint64x2_t, unsigned_intDI_type_node)
+DEF_MVE_TYPE (int8x16_t, intQI_type_node)
+DEF_MVE_TYPE (int16x8_t, intHI_type_node)
+DEF_MVE_TYPE (int32x4_t, intSI_type_node)
+DEF_MVE_TYPE (int64x2_t, intDI_type_node)
+#undef REQUIRES_FLOAT
+
+#define REQUIRES_FLOAT true
+DEF_MVE_TYPE (float16x8_t, arm_fp16_type_node)
+DEF_MVE_TYPE (float32x4_t, float_type_node)
+#undef REQUIRES_FLOAT
diff --git a/gcc/config/arm/arm-mve-builtins.h b/gcc/config/arm/arm-mve-builtins.h
new file mode 100644
index 0000000..aa5c2cc
--- /dev/null
+++ b/gcc/config/arm/arm-mve-builtins.h
@@ -0,0 +1,41 @@
+/* ACLE support for Arm MVE
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_ARM_MVE_BUILTINS_H
+#define GCC_ARM_MVE_BUILTINS_H
+
+namespace arm_mve {
+
+/* Enumerates the MVE predicate and (data) vector types, together called
+ "vector types" for brevity. */
+enum vector_type_index
+{
+#define DEF_MVE_TYPE(ACLE_NAME, SCALAR_TYPE) \
+ VECTOR_TYPE_ ## ACLE_NAME,
+#include "arm-mve-builtins.def"
+ NUM_VECTOR_TYPES
+#undef DEF_MVE_TYPE
+};
+
+extern tree scalar_types[NUM_VECTOR_TYPES];
+extern tree acle_vector_types[3][NUM_VECTOR_TYPES + 1];
+
+} /* end namespace arm_mve */
+
+#endif /* GCC_ARM_MVE_BUILTINS_H */
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 9b1f613..c91cb5a 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -204,6 +204,11 @@ extern int arm_apply_result_size (void);
#endif /* RTX_CODE */
+/* MVE functions. */
+namespace arm_mve {
+ void handle_arm_mve_types_h ();
+}
+
/* Thumb functions. */
extern void arm_init_expanders (void);
extern const char *thumb1_unexpanded_epilogue (void);
diff --git a/gcc/config/arm/arm_mve_types.h b/gcc/config/arm/arm_mve_types.h
index 8958f4e..7fbc89b 100644
--- a/gcc/config/arm/arm_mve_types.h
+++ b/gcc/config/arm/arm_mve_types.h
@@ -25,37 +25,9 @@
#if (__ARM_FEATURE_MVE & 2) /* MVE Floating point. */
typedef __fp16 float16_t;
typedef float float32_t;
-typedef __simd128_float16_t float16x8_t;
-typedef __simd128_float32_t float32x4_t;
-
-typedef struct { float16x8_t val[2]; } float16x8x2_t;
-typedef struct { float16x8_t val[4]; } float16x8x4_t;
-typedef struct { float32x4_t val[2]; } float32x4x2_t;
-typedef struct { float32x4_t val[4]; } float32x4x4_t;
#endif
-typedef uint16_t mve_pred16_t;
-typedef __simd128_uint8_t uint8x16_t;
-typedef __simd128_uint16_t uint16x8_t;
-typedef __simd128_uint32_t uint32x4_t;
-typedef __simd128_uint64_t uint64x2_t;
-typedef __simd128_int8_t int8x16_t;
-typedef __simd128_int16_t int16x8_t;
-typedef __simd128_int32_t int32x4_t;
-typedef __simd128_int64_t int64x2_t;
-
-typedef struct { int16x8_t val[2]; } int16x8x2_t;
-typedef struct { int16x8_t val[4]; } int16x8x4_t;
-typedef struct { int32x4_t val[2]; } int32x4x2_t;
-typedef struct { int32x4_t val[4]; } int32x4x4_t;
-typedef struct { int8x16_t val[2]; } int8x16x2_t;
-typedef struct { int8x16_t val[4]; } int8x16x4_t;
-typedef struct { uint16x8_t val[2]; } uint16x8x2_t;
-typedef struct { uint16x8_t val[4]; } uint16x8x4_t;
-typedef struct { uint32x4_t val[2]; } uint32x4x2_t;
-typedef struct { uint32x4_t val[4]; } uint32x4x4_t;
-typedef struct { uint8x16_t val[2]; } uint8x16x2_t;
-typedef struct { uint8x16_t val[4]; } uint8x16x4_t;
+#pragma GCC arm "arm_mve_types.h"
__extension__ extern __inline int16x8_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm
index 5f69ee6..f655f36 100644
--- a/gcc/config/arm/t-arm
+++ b/gcc/config/arm/t-arm
@@ -153,6 +153,16 @@ arm-builtins.o: $(srcdir)/config/arm/arm-builtins.c $(CONFIG_H) \
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/arm/arm-builtins.c
+arm-mve-builtins.o: $(srcdir)/config/arm/arm-mve-builtins.cc $(CONFIG_H) \
+ $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
+ fold-const.h langhooks.h stringpool.h attribs.h diagnostic.h \
+ $(srcdir)/config/arm/arm-protos.h \
+ $(srcdir)/config/arm/arm-builtins.h \
+ $(srcdir)/config/arm/arm-mve-builtins.h \
+ $(srcdir)/config/arm/arm-mve-builtins.def
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/arm/arm-mve-builtins.cc
+
arm-c.o: $(srcdir)/config/arm/arm-c.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) output.h $(C_COMMON_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \