diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-08-30 11:09:10 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-08-30 11:09:10 +0000 |
commit | e386a52f70c47499fff14a338fe17df691e886e2 (patch) | |
tree | bf21dc05503e220cd0d838c391f028ef314c252b /gcc/machmode.h | |
parent | 490d0f6c91c0c4fef57a5ffe438629b0687113de (diff) | |
download | gcc-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.h | 97 |
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. */ |