aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlfie Richards <Alfie.Richards@arm.com>2024-09-11 14:55:24 +0200
committerChristophe Lyon <christophe.lyon@arm.com>2024-10-29 10:03:06 +0100
commit52e36cde0f6680ef56043cb220eb9cd0be927749 (patch)
tree940e5d47103a56874d95c709c62ae564d62fb669 /gcc
parentc31cdc3d85e365ce0d233fe40bee40a8bd672b11 (diff)
downloadgcc-52e36cde0f6680ef56043cb220eb9cd0be927749.zip
gcc-52e36cde0f6680ef56043cb220eb9cd0be927749.tar.gz
gcc-52e36cde0f6680ef56043cb220eb9cd0be927749.tar.bz2
arm: [MVE intrinsics] Add load_extending and store_truncating function bases
This patch adds the load_extending and store_truncating function bases for MVE intrinsics. The constructors have parameters describing the memory element type/width which is part of the function base name (e.g. "h" in vldrhq). 2024-09-11 Alfie Richards <Alfie.Richards@arm.com> gcc/ * config/arm/arm-mve-builtins-functions.h (load_extending): New class. (store_truncating): New class. * config/arm/arm-protos.h (arm_mve_data_mode): New helper function. * config/arm/arm.cc (arm_mve_data_mode): New helper function.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/arm/arm-mve-builtins-functions.h103
-rw-r--r--gcc/config/arm/arm-protos.h3
-rw-r--r--gcc/config/arm/arm.cc15
3 files changed, 121 insertions, 0 deletions
diff --git a/gcc/config/arm/arm-mve-builtins-functions.h b/gcc/config/arm/arm-mve-builtins-functions.h
index 57e59e3..48b9e79 100644
--- a/gcc/config/arm/arm-mve-builtins-functions.h
+++ b/gcc/config/arm/arm-mve-builtins-functions.h
@@ -20,6 +20,8 @@
#ifndef GCC_ARM_MVE_BUILTINS_FUNCTIONS_H
#define GCC_ARM_MVE_BUILTINS_FUNCTIONS_H
+#include "arm-protos.h"
+
namespace arm_mve {
/* Wrap T, which is derived from function_base, and indicate that the
@@ -977,6 +979,107 @@ public:
}
};
+/* A function_base that loads elements from memory and extends them
+ to a wider element. The memory element type is a fixed part of
+ the function base name. */
+class load_extending : public function_base
+{
+public:
+ CONSTEXPR load_extending (type_suffix_index signed_memory_type,
+ type_suffix_index unsigned_memory_type,
+ type_suffix_index float_memory_type)
+ : m_signed_memory_type (signed_memory_type),
+ m_unsigned_memory_type (unsigned_memory_type),
+ m_float_memory_type (float_memory_type)
+ {}
+ CONSTEXPR load_extending (type_suffix_index signed_memory_type,
+ type_suffix_index unsigned_memory_type)
+ : m_signed_memory_type (signed_memory_type),
+ m_unsigned_memory_type (unsigned_memory_type),
+ m_float_memory_type (NUM_TYPE_SUFFIXES)
+ {}
+
+ unsigned int call_properties (const function_instance &) const override
+ {
+ return CP_READ_MEMORY;
+ }
+
+ tree memory_scalar_type (const function_instance &fi) const override
+ {
+ type_suffix_index memory_type_suffix
+ = (fi.type_suffix (0).integer_p
+ ? (fi.type_suffix (0).unsigned_p
+ ? m_unsigned_memory_type
+ : m_signed_memory_type)
+ : m_float_memory_type);
+ return scalar_types[type_suffixes[memory_type_suffix].vector_type];
+ }
+
+ machine_mode memory_vector_mode (const function_instance &fi) const override
+ {
+ type_suffix_index memory_type_suffix
+ = (fi.type_suffix (0).integer_p
+ ? (fi.type_suffix (0).unsigned_p
+ ? m_unsigned_memory_type
+ : m_signed_memory_type)
+ : m_float_memory_type);
+ machine_mode mem_mode = type_suffixes[memory_type_suffix].vector_mode;
+ machine_mode reg_mode = fi.vector_mode (0);
+
+ return arm_mve_data_mode (GET_MODE_INNER (mem_mode),
+ GET_MODE_NUNITS (reg_mode)).require ();
+ }
+
+ /* The type of the memory elements. This is part of the function base
+ name rather than a true type suffix. */
+ type_suffix_index m_signed_memory_type;
+ type_suffix_index m_unsigned_memory_type;
+ type_suffix_index m_float_memory_type;
+};
+
+/* A function_base that truncates vector elements and stores them to memory.
+ The memory element width is a fixed part of the function base name. */
+class store_truncating : public function_base
+{
+public:
+ CONSTEXPR store_truncating (scalar_mode to_int_mode,
+ opt_scalar_mode to_float_mode)
+ : m_to_int_mode (to_int_mode), m_to_float_mode (to_float_mode)
+ {}
+
+ unsigned int call_properties (const function_instance &) const override
+ {
+ return CP_WRITE_MEMORY;
+ }
+
+ tree memory_scalar_type (const function_instance &fi) const override
+ {
+ /* In truncating stores, the signedness of the memory element is defined
+ to be the same as the signedness of the vector element. The signedness
+ doesn't make any difference to the behavior of the function. */
+ type_class_index tclass = fi.type_suffix (0).tclass;
+ unsigned int element_bits
+ = GET_MODE_BITSIZE (fi.type_suffix (0).integer_p
+ ? m_to_int_mode
+ : m_to_float_mode.require ());
+ type_suffix_index suffix = find_type_suffix (tclass, element_bits);
+ return scalar_types[type_suffixes[suffix].vector_type];
+ }
+
+ machine_mode memory_vector_mode (const function_instance &fi) const override
+ {
+ poly_uint64 nunits = GET_MODE_NUNITS (fi.vector_mode (0));
+ scalar_mode mode = (fi.type_suffix (0).integer_p
+ ? m_to_int_mode
+ : m_to_float_mode.require ());
+ return arm_mve_data_mode (mode, nunits).require ();
+ }
+
+ /* The mode of a single memory element. */
+ scalar_mode m_to_int_mode;
+ opt_scalar_mode m_to_float_mode;
+};
+
} /* end namespace arm_mve */
/* Declare the global function base NAME, creating it from an instance
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index b694589..7311ad4 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -616,4 +616,7 @@ void arm_initialize_isa (sbitmap, const enum isa_feature *);
const char * arm_gen_far_branch (rtx *, int, const char * , const char *);
bool arm_mve_immediate_check(rtx, machine_mode, bool);
+
+opt_machine_mode arm_mve_data_mode (scalar_mode, poly_uint64);
+
#endif /* ! GCC_ARM_PROTOS_H */
diff --git a/gcc/config/arm/arm.cc b/gcc/config/arm/arm.cc
index 8ccdf1a..6f11b6c 100644
--- a/gcc/config/arm/arm.cc
+++ b/gcc/config/arm/arm.cc
@@ -76,6 +76,7 @@
#include "opts.h"
#include "aarch-common.h"
#include "aarch-common-protos.h"
+#include "machmode.h"
/* This file should be included last. */
#include "target-def.h"
@@ -36212,4 +36213,18 @@ arm_output_load_tpidr (rtx dst, bool pred_p)
return "";
}
+/* Return the MVE vector mode that has NUNITS elements of mode INNER_MODE. */
+opt_machine_mode
+arm_mve_data_mode (scalar_mode inner_mode, poly_uint64 nunits)
+{
+ enum mode_class mclass
+ = (SCALAR_FLOAT_MODE_P (inner_mode) ? MODE_VECTOR_FLOAT : MODE_VECTOR_INT);
+ machine_mode mode;
+ FOR_EACH_MODE_IN_CLASS (mode, mclass)
+ if (inner_mode == GET_MODE_INNER (mode)
+ && known_eq (nunits, GET_MODE_NUNITS (mode)))
+ return mode;
+ return opt_machine_mode ();
+}
+
#include "gt-arm.h"