This provides a type-safe way to ask for a float mode and get it as a scalar_float_mode.
gcc/ 2016-11-24 Richard Sandiford <richard.sandif...@arm.com> Alan Hayward <alan.hayw...@arm.com> David Sherwood <david.sherw...@arm.com> * coretypes.h (opt_scalar_float_mode): New typedef. * machmode.h (float_mode_for_size): New function. * emit-rtl.c (double_mode): Delete. (init_emit_once): Use float_mode_for_size. * stor-layout.c (layout_type): Likewise. diff --git a/gcc/coretypes.h b/gcc/coretypes.h index f4c1859..8341cab 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -58,6 +58,7 @@ typedef const struct rtx_def *const_rtx; class machine_mode; class scalar_float_mode; template<typename> class opt_mode; +typedef opt_mode<scalar_float_mode> opt_scalar_float_mode; /* Subclasses of rtx_def, using indentation to show the class hierarchy, along with the relevant invariant. diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 3bcafbb..efddad4 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -71,7 +71,6 @@ struct target_rtl *this_target_rtl = &default_target_rtl; machine_mode byte_mode; /* Mode whose width is BITS_PER_UNIT. */ machine_mode word_mode; /* Mode whose width is BITS_PER_WORD. */ -machine_mode double_mode; /* Mode whose width is DOUBLE_TYPE_SIZE. */ machine_mode ptr_mode; /* Mode whose width is POINTER_SIZE. */ /* Datastructures maintained for currently processed function in RTL form. */ @@ -5864,7 +5863,7 @@ init_emit_once (void) { int i; machine_mode mode; - machine_mode double_mode; + scalar_float_mode double_mode; /* Initialize the CONST_INT, CONST_WIDE_INT, CONST_DOUBLE, CONST_FIXED, and memory attribute hash tables. */ @@ -5908,7 +5907,7 @@ init_emit_once (void) else const_true_rtx = gen_rtx_CONST_INT (VOIDmode, STORE_FLAG_VALUE); - double_mode = mode_for_size (DOUBLE_TYPE_SIZE, MODE_FLOAT, 0); + double_mode = *float_mode_for_size (DOUBLE_TYPE_SIZE); real_from_integer (&dconst0, double_mode, 0, SIGNED); real_from_integer (&dconst1, double_mode, 1, SIGNED); diff --git a/gcc/machmode.h b/gcc/machmode.h index 996f991..41a3a00 100644 --- a/gcc/machmode.h +++ b/gcc/machmode.h @@ -513,7 +513,16 @@ extern const unsigned char mode_complex[NUM_MACHINE_MODES]; extern machine_mode mode_for_size (unsigned int, enum mode_class, int); -/* Similar, but find the smallest mode for a given width. */ +/* Return the machine mode to use for a MODE_FLOAT of SIZE bits, if one + exists. */ + +inline opt_scalar_float_mode +float_mode_for_size (unsigned int size) +{ + return dyn_cast <scalar_float_mode> (mode_for_size (size, MODE_FLOAT, 0)); +} + +/* Similar to mode_for_size, but find the smallest mode for a given width. */ extern machine_mode smallest_mode_for_size (unsigned int, enum mode_class); diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 834cf8b..2cde94e 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -2132,14 +2132,16 @@ layout_type (tree type) break; case REAL_TYPE: - /* Allow the caller to choose the type mode, which is how decimal - floats are distinguished from binary ones. */ - if (TYPE_MODE (type) == VOIDmode) - SET_TYPE_MODE (type, - mode_for_size (TYPE_PRECISION (type), MODE_FLOAT, 0)); - TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type))); - TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type))); - break; + { + /* Allow the caller to choose the type mode, which is how decimal + floats are distinguished from binary ones. */ + if (TYPE_MODE (type) == VOIDmode) + SET_TYPE_MODE (type, *float_mode_for_size (TYPE_PRECISION (type))); + scalar_float_mode mode = as_a <scalar_float_mode> (TYPE_MODE (type)); + TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (mode)); + TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode)); + break; + } case FIXED_POINT_TYPE: /* TYPE_MODE (type) has been set already. */