diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 24 | ||||
-rw-r--r-- | gcc/caller-save.c | 2 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.h | 2 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 2 | ||||
-rw-r--r-- | gcc/config/s390/s390.h | 6 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.h | 14 | ||||
-rw-r--r-- | gcc/expmed.c | 11 | ||||
-rw-r--r-- | gcc/lower-subreg.c | 14 | ||||
-rw-r--r-- | gcc/machmode.h | 31 | ||||
-rw-r--r-- | gcc/reload.c | 3 | ||||
-rw-r--r-- | gcc/stor-layout.c | 52 | ||||
-rw-r--r-- | gcc/varasm.c | 4 |
12 files changed, 97 insertions, 68 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7fbade7..4a7f676 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,29 @@ 2017-09-05 Richard Sandiford <richard.sandiford@linaro.org> + * machmode.h (opt_machine_mode): New type. + (opt_mode<T>): Allow construction from anything that can be + converted to a T. + (is_a, as_a, dyn_cast): Add overloads for opt_mode. + (mode_for_size): Return an opt_machine_mode. + * stor-layout.c (mode_for_size): Likewise. + (mode_for_size_tree): Update call accordingly. + (bitwise_mode_for_mode): Likewise. + (make_fract_type): Likewise. + (make_accum_type): Likewise. + * caller-save.c (replace_reg_with_saved_mem): Update call + accordingly. + * config/alpha/alpha.h (SECONDARY_MEMORY_NEEDED_MODE): Likewise. + * config/i386/i386.h (SECONDARY_MEMORY_NEEDED_MODE): Likewise. + * config/s390/s390.h (SECONDARY_MEMORY_NEEDED_MODE): Likewise. + * config/sparc/sparc.h (SECONDARY_MEMORY_NEEDED_MODE): Likewise. + * expmed.c (extract_bit_field_1): Likewise. + * reload.c (get_secondary_mem): Likewise. + * varasm.c (assemble_integer): Likewise. + * lower-subreg.c (simplify_subreg_concatn): Likewise. Move + early-out. + +2017-09-05 Richard Sandiford <richard.sandiford@linaro.org> + * machmode.h (decimal_float_mode_for_size): New function. * real.h (REAL_VALUE_TO_TARGET_LONG_DOUBLE): Use float_mode_for_size. (REAL_VALUE_TO_TARGET_DOUBLE): Likewise. diff --git a/gcc/caller-save.c b/gcc/caller-save.c index 5e6b92b..619dac9 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -1161,7 +1161,7 @@ replace_reg_with_saved_mem (rtx *loc, gcc_assert (smode != VOIDmode); if (hard_regno_nregs [regno][smode] > 1) smode = mode_for_size (GET_MODE_SIZE (mode) / nregs, - GET_MODE_CLASS (mode), 0); + GET_MODE_CLASS (mode), 0).require (); XVECEXP (mem, 0, i) = gen_rtx_REG (smode, regno + i); } } diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index b9fee20..8bca5b3 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -508,7 +508,7 @@ enum reg_class { #define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ (GET_MODE_CLASS (MODE) == MODE_FLOAT ? (MODE) \ : GET_MODE_SIZE (MODE) >= 4 ? (MODE) \ - : mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0)) + : mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0).require ()) /* Return the class of registers that cannot change mode from FROM to TO. */ diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 8f9a2ad..873122c 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1548,7 +1548,7 @@ enum reg_class for integral modes that can be moved using 32 bit move. */ #define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ (GET_MODE_BITSIZE (MODE) < 32 && INTEGRAL_MODE_P (MODE) \ - ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ + ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require () \ : MODE) /* Return a class of registers that cannot change FROM mode to TO mode. */ diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 34fffb4..a52f866 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -624,9 +624,9 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER]; /* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on 64bit because the movsi and movsf patterns don't handle r/f moves. */ -#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ - (GET_MODE_BITSIZE (MODE) < 32 \ - ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ +#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ + (GET_MODE_BITSIZE (MODE) < 32 \ + ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require () \ : (MODE)) diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 36f7667..3c71a3f 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1077,13 +1077,13 @@ extern char leaf_reg_remap[]; /* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on v9 because the movsi and movsf patterns don't handle r/f moves. For v8 we copy the default definition. */ -#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ - (TARGET_ARCH64 \ - ? (GET_MODE_BITSIZE (MODE) < 32 \ - ? mode_for_size (32, GET_MODE_CLASS (MODE), 0) \ - : MODE) \ - : (GET_MODE_BITSIZE (MODE) < BITS_PER_WORD \ - ? mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0) \ +#define SECONDARY_MEMORY_NEEDED_MODE(MODE) \ + (TARGET_ARCH64 \ + ? (GET_MODE_BITSIZE (MODE) < 32 \ + ? mode_for_size (32, GET_MODE_CLASS (MODE), 0).require () \ + : MODE) \ + : (GET_MODE_BITSIZE (MODE) < BITS_PER_WORD \ + ? mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (MODE), 0).require () \ : MODE)) /* Return the maximum number of consecutive registers diff --git a/gcc/expmed.c b/gcc/expmed.c index fa223165..894e369 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -1711,14 +1711,9 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, /* Get the mode of the field to use for atomic access or subreg conversion. */ - mode1 = mode; - if (SCALAR_INT_MODE_P (tmode)) - { - machine_mode try_mode = mode_for_size (bitsize, - GET_MODE_CLASS (tmode), 0); - if (try_mode != BLKmode) - mode1 = try_mode; - } + if (!SCALAR_INT_MODE_P (tmode) + || !mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0).exists (&mode1)) + mode1 = mode; gcc_assert (mode1 != BLKmode); /* Extraction of a full MODE1 value can be done with a subreg as long diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c index 43b6cd0..e34746b 100644 --- a/gcc/lower-subreg.c +++ b/gcc/lower-subreg.c @@ -616,20 +616,18 @@ simplify_subreg_concatn (machine_mode outermode, rtx op, part = XVECEXP (op, 0, byte / inner_size); partmode = GET_MODE (part); + final_offset = byte % inner_size; + if (final_offset + GET_MODE_SIZE (outermode) > inner_size) + return NULL_RTX; + /* VECTOR_CSTs in debug expressions are expanded into CONCATN instead of regular CONST_VECTORs. They have vector or integer modes, depending on the capabilities of the target. Cope with them. */ if (partmode == VOIDmode && VECTOR_MODE_P (innermode)) partmode = GET_MODE_INNER (innermode); else if (partmode == VOIDmode) - { - enum mode_class mclass = GET_MODE_CLASS (innermode); - partmode = mode_for_size (inner_size * BITS_PER_UNIT, mclass, 0); - } - - final_offset = byte % inner_size; - if (final_offset + GET_MODE_SIZE (outermode) > inner_size) - return NULL_RTX; + partmode = mode_for_size (inner_size * BITS_PER_UNIT, + GET_MODE_CLASS (innermode), 0).require (); return simplify_gen_subreg (outermode, part, partmode, final_offset); } diff --git a/gcc/machmode.h b/gcc/machmode.h index d8344a9..956e2c0 100644 --- a/gcc/machmode.h +++ b/gcc/machmode.h @@ -20,6 +20,8 @@ along with GCC; see the file COPYING3. If not see #ifndef HAVE_MACHINE_MODES #define HAVE_MACHINE_MODES +typedef opt_mode<machine_mode> opt_machine_mode; + extern CONST_MODE_SIZE unsigned short mode_size[NUM_MACHINE_MODES]; extern const unsigned short mode_precision[NUM_MACHINE_MODES]; extern const unsigned char mode_inner[NUM_MACHINE_MODES]; @@ -237,6 +239,8 @@ public: ALWAYS_INLINE opt_mode () : m_mode (E_VOIDmode) {} ALWAYS_INLINE opt_mode (const T &m) : m_mode (m) {} + template<typename U> + ALWAYS_INLINE opt_mode (const U &m) : m_mode (T (m)) {} ALWAYS_INLINE opt_mode (from_int m) : m_mode (machine_mode (m)) {} machine_mode else_void () const; @@ -325,6 +329,13 @@ is_a (machine_mode m) return T::includes_p (m); } +template<typename T, typename U> +inline bool +is_a (const opt_mode<U> &m) +{ + return T::includes_p (m.else_void ()); +} + /* Assert that mode M has type T, and return it in that form. */ template<typename T> @@ -335,6 +346,13 @@ as_a (machine_mode m) return typename mode_traits<T>::from_int (m); } +template<typename T, typename U> +inline T +as_a (const opt_mode<U> &m) +{ + return as_a <T> (m.else_void ()); +} + /* Convert M to an opt_mode<T>. */ template<typename T> @@ -346,6 +364,13 @@ dyn_cast (machine_mode m) return opt_mode<T> (); } +template<typename T, typename U> +inline opt_mode<T> +dyn_cast (const opt_mode<U> &m) +{ + return dyn_cast <T> (m.else_void ()); +} + /* Return true if mode M has type T, storing it as a T in *RESULT if so. */ @@ -627,11 +652,7 @@ GET_MODE_2XWIDER_MODE (const T &m) extern const unsigned char mode_complex[NUM_MACHINE_MODES]; #define GET_MODE_COMPLEX_MODE(MODE) ((machine_mode) mode_complex[MODE]) -/* Return the mode for data of a given size SIZE and mode class CLASS. - If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE. - The value is BLKmode if no other mode is found. */ - -extern machine_mode mode_for_size (unsigned int, enum mode_class, int); +extern opt_machine_mode mode_for_size (unsigned int, enum mode_class, int); /* Return the machine mode to use for a MODE_INT of SIZE bits, if one exists. If LIMIT is nonzero, modes wider than MAX_FIXED_MODE_SIZE diff --git a/gcc/reload.c b/gcc/reload.c index f10a88b..9d96700 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -578,7 +578,8 @@ get_secondary_mem (rtx x ATTRIBUTE_UNUSED, machine_mode mode, mode = SECONDARY_MEMORY_NEEDED_MODE (mode); #else if (GET_MODE_BITSIZE (mode) < BITS_PER_WORD && INTEGRAL_MODE_P (mode)) - mode = mode_for_size (BITS_PER_WORD, GET_MODE_CLASS (mode), 0); + mode = mode_for_size (BITS_PER_WORD, + GET_MODE_CLASS (mode), 0).require (); #endif /* If we already have made a MEM for this operand in MODE, return it. */ diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 27a1eba..f9a28e7 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -291,19 +291,19 @@ finalize_size_functions (void) vec_free (size_functions); } -/* Return the machine mode to use for a nonscalar of SIZE bits. The - mode must be in class MCLASS, and have exactly that many value bits; - it may have padding as well. If LIMIT is nonzero, modes of wider - than MAX_FIXED_MODE_SIZE will not be used. */ +/* Return a machine mode of class MCLASS with SIZE bits of precision, + if one exists. The mode may have padding bits as well the SIZE + value bits. If LIMIT is nonzero, disregard modes wider than + MAX_FIXED_MODE_SIZE. */ -machine_mode +opt_machine_mode mode_for_size (unsigned int size, enum mode_class mclass, int limit) { machine_mode mode; int i; if (limit && size > MAX_FIXED_MODE_SIZE) - return BLKmode; + return opt_machine_mode (); /* Get the first mode which has this size, in the specified class. */ FOR_EACH_MODE_IN_CLASS (mode, mclass) @@ -316,7 +316,7 @@ mode_for_size (unsigned int size, enum mode_class mclass, int limit) && int_n_enabled_p[i]) return int_n_data[i].m; - return BLKmode; + return opt_machine_mode (); } /* Similar, except passed a tree node. */ @@ -333,11 +333,11 @@ mode_for_size_tree (const_tree size, enum mode_class mclass, int limit) ui = uhwi; if (uhwi != ui) return BLKmode; - return mode_for_size (ui, mclass, limit); + return mode_for_size (ui, mclass, limit).else_blk (); } -/* Similar, but never return BLKmode; return the narrowest mode that - contains at least the requested number of value bits. */ +/* Return the narrowest mode of class MCLASS that contains at least + SIZE bits. Abort if no such mode exists. */ machine_mode smallest_mode_for_size (unsigned int size, enum mode_class mclass) @@ -426,9 +426,8 @@ bitwise_mode_for_mode (machine_mode mode) if (COMPLEX_MODE_P (mode)) { machine_mode trial = mode; - if (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT) - trial = mode_for_size (bitsize, MODE_COMPLEX_INT, false); - if (trial != BLKmode + if ((GET_MODE_CLASS (trial) == MODE_COMPLEX_INT + || mode_for_size (bitsize, MODE_COMPLEX_INT, false).exists (&trial)) && have_regs_of_mode[GET_MODE_INNER (trial)]) return trial; } @@ -438,16 +437,15 @@ bitwise_mode_for_mode (machine_mode mode) if (VECTOR_MODE_P (mode) || bitsize > MAX_FIXED_MODE_SIZE) { machine_mode trial = mode; - if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT) - trial = mode_for_size (bitsize, MODE_VECTOR_INT, 0); - if (trial != BLKmode + if ((GET_MODE_CLASS (trial) == MODE_VECTOR_INT + || mode_for_size (bitsize, MODE_VECTOR_INT, 0).exists (&trial)) && have_regs_of_mode[trial] && targetm.vector_mode_supported_p (trial)) return trial; } /* Otherwise fall back on integers while honoring MAX_FIXED_MODE_SIZE. */ - return mode_for_size (bitsize, MODE_INT, true); + return mode_for_size (bitsize, MODE_INT, true).else_blk (); } /* Find a type that can be used for efficient bitwise operations on MODE. @@ -2543,13 +2541,9 @@ make_fract_type (int precision, int unsignedp, int satp) TYPE_SATURATING (type) = 1; /* Lay out the type: set its alignment, size, etc. */ - if (unsignedp) - { - TYPE_UNSIGNED (type) = 1; - SET_TYPE_MODE (type, mode_for_size (precision, MODE_UFRACT, 0)); - } - else - SET_TYPE_MODE (type, mode_for_size (precision, MODE_FRACT, 0)); + TYPE_UNSIGNED (type) = unsignedp; + enum mode_class mclass = unsignedp ? MODE_UFRACT : MODE_FRACT; + SET_TYPE_MODE (type, mode_for_size (precision, mclass, 0).require ()); layout_type (type); return type; @@ -2569,13 +2563,9 @@ make_accum_type (int precision, int unsignedp, int satp) TYPE_SATURATING (type) = 1; /* Lay out the type: set its alignment, size, etc. */ - if (unsignedp) - { - TYPE_UNSIGNED (type) = 1; - SET_TYPE_MODE (type, mode_for_size (precision, MODE_UACCUM, 0)); - } - else - SET_TYPE_MODE (type, mode_for_size (precision, MODE_ACCUM, 0)); + TYPE_UNSIGNED (type) = unsignedp; + enum mode_class mclass = unsignedp ? MODE_UACCUM : MODE_ACCUM; + SET_TYPE_MODE (type, mode_for_size (precision, mclass, 0).require ()); layout_type (type); return type; diff --git a/gcc/varasm.c b/gcc/varasm.c index 476efcf..f2a12f0 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -2780,8 +2780,8 @@ assemble_integer (rtx x, unsigned int size, unsigned int align, int force) else mclass = MODE_INT; - omode = mode_for_size (subsize * BITS_PER_UNIT, mclass, 0); - imode = mode_for_size (size * BITS_PER_UNIT, mclass, 0); + omode = mode_for_size (subsize * BITS_PER_UNIT, mclass, 0).require (); + imode = mode_for_size (size * BITS_PER_UNIT, mclass, 0).require (); for (i = 0; i < size; i += subsize) { |