aboutsummaryrefslogtreecommitdiff
path: root/gcc/machmode.h
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-08-30 11:09:10 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-08-30 11:09:10 +0000
commite386a52f70c47499fff14a338fe17df691e886e2 (patch)
treebf21dc05503e220cd0d838c391f028ef314c252b /gcc/machmode.h
parent490d0f6c91c0c4fef57a5ffe438629b0687113de (diff)
downloadgcc-e386a52f70c47499fff14a338fe17df691e886e2.zip
gcc-e386a52f70c47499fff14a338fe17df691e886e2.tar.gz
gcc-e386a52f70c47499fff14a338fe17df691e886e2.tar.bz2
[7/77] Add scalar_float_mode
This patch adds a scalar_float_mode class, which wraps a mode enum that is known to satisfy SCALAR_FLOAT_MODE_P. Things like "SFmode" now give a scalar_float_mode object instead of a machine_mode. This in turn needs a change to the real.h format_helper, so that it can accept both machine_modes and scalar_float_modes. 2017-08-30 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * coretypes.h (scalar_float_mode): New type. * machmode.h (mode_traits::from_int): Use machine_mode if USE_ENUM_MODES is defined. (is_a): New function. (as_a): Likewise. (dyn_cast): Likewise. (scalar_float_mode): New class. (scalar_float_mode::includes_p): New function. (is_float_mode): Likewise. * gdbhooks.py (MachineModePrinter): New class. (build_pretty_printer): Use it for scalar_float_mode. * real.h (FLOAT_MODE_FORMAT): Use as_a <scalar_float_mode>. (format_helper::format_helper): Turn into a template. * genmodes.c (get_mode_class): New function. (emit_insn_modes_h): Give modes the class returned by get_mode_class, or machine_mode if none. * config/aarch64/aarch64.c (aarch64_simd_valid_immediate): Use as_a <scalar_float_mode>. * dwarf2out.c (mem_loc_descriptor): Likewise. (insert_float): Likewise. (add_const_value_attribute): Likewise. * simplify-rtx.c (simplify_immed_subreg): Likewise. * optabs.c (expand_absneg_bit): Take a scalar_float_mode. (expand_unop): Update accordingly. (expand_abs_nojump): Likewise. (expand_copysign_absneg): Take a scalar_float_mode. (expand_copysign_bit): Likewise. (expand_copysign): Update accordingly. gcc/ada/ * gcc-interface/utils.c (gnat_type_for_mode): Use is_a <scalar_float_mode> instead of SCALAR_FLOAT_MODE_P. gcc/go/ * go-lang.c (go_langhook_type_for_mode): Use is_float_mode. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r251458
Diffstat (limited to 'gcc/machmode.h')
-rw-r--r--gcc/machmode.h97
1 files changed, 94 insertions, 3 deletions
diff --git a/gcc/machmode.h b/gcc/machmode.h
index 3b06f6d..3b71b9d 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -46,9 +46,15 @@ struct mode_traits
res = T (typename mode_traits<T>::from_int (mode));
when assigning to a value RES that must be assignment-compatible
- with (but possibly not the same as) T.
-
- Here we use an enum type distinct from machine_mode but with the
+ with (but possibly not the same as) T. */
+#ifdef USE_ENUM_MODES
+ /* Allow direct conversion of enums to specific mode classes only
+ when USE_ENUM_MODES is defined. This is only intended for use
+ by gencondmd, so that it can tell more easily when .md conditions
+ are always false. */
+ typedef machine_mode from_int;
+#else
+ /* Here we use an enum type distinct from machine_mode but with the
same range as machine_mode. T should have a constructor that
accepts this enum type; it should not have a constructor that
accepts machine_mode.
@@ -58,6 +64,7 @@ struct mode_traits
unoptimized code, the return statement above would construct the
returned T directly from the numerical value of MODE. */
enum from_int { dummy = MAX_MACHINE_MODE };
+#endif
};
template<>
@@ -286,6 +293,75 @@ opt_mode<T>::exists (U *mode) const
return false;
}
+/* Return true if mode M has type T. */
+
+template<typename T>
+inline bool
+is_a (machine_mode m)
+{
+ return T::includes_p (m);
+}
+
+/* Assert that mode M has type T, and return it in that form. */
+
+template<typename T>
+inline T
+as_a (machine_mode m)
+{
+ gcc_checking_assert (T::includes_p (m));
+ return typename mode_traits<T>::from_int (m);
+}
+
+/* Convert M to an opt_mode<T>. */
+
+template<typename T>
+inline opt_mode<T>
+dyn_cast (machine_mode m)
+{
+ if (T::includes_p (m))
+ return T (typename mode_traits<T>::from_int (m));
+ return opt_mode<T> ();
+}
+
+/* Return true if mode M has type T, storing it as a T in *RESULT
+ if so. */
+
+template<typename T, typename U>
+inline bool
+is_a (machine_mode m, U *result)
+{
+ if (T::includes_p (m))
+ {
+ *result = T (typename mode_traits<T>::from_int (m));
+ return true;
+ }
+ return false;
+}
+
+/* Represents a machine mode that is known to be a SCALAR_FLOAT_MODE_P. */
+class scalar_float_mode
+{
+public:
+ typedef mode_traits<scalar_float_mode>::from_int from_int;
+
+ ALWAYS_INLINE scalar_float_mode () {}
+ ALWAYS_INLINE scalar_float_mode (from_int m) : m_mode (machine_mode (m)) {}
+ ALWAYS_INLINE operator machine_mode () const { return m_mode; }
+
+ static bool includes_p (machine_mode);
+
+protected:
+ machine_mode m_mode;
+};
+
+/* Return true if M is a scalar_float_mode. */
+
+inline bool
+scalar_float_mode::includes_p (machine_mode m)
+{
+ return SCALAR_FLOAT_MODE_P (m);
+}
+
/* Return the base GET_MODE_SIZE value for MODE. */
ALWAYS_INLINE unsigned short
@@ -547,6 +623,21 @@ struct int_n_data_t {
extern bool int_n_enabled_p[NUM_INT_N_ENTS];
extern const int_n_data_t int_n_data[NUM_INT_N_ENTS];
+/* Return true if MODE has class MODE_FLOAT, storing it as a
+ scalar_float_mode in *FLOAT_MODE if so. */
+
+template<typename T>
+inline bool
+is_float_mode (machine_mode mode, T *float_mode)
+{
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ *float_mode = scalar_float_mode (scalar_float_mode::from_int (mode));
+ return true;
+ }
+ return false;
+}
+
namespace mode_iterator
{
/* Start mode iterator *ITER at the first mode in class MCLASS, if any. */