aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog24
-rw-r--r--gcc/caller-save.c2
-rw-r--r--gcc/config/alpha/alpha.h2
-rw-r--r--gcc/config/i386/i386.h2
-rw-r--r--gcc/config/s390/s390.h6
-rw-r--r--gcc/config/sparc/sparc.h14
-rw-r--r--gcc/expmed.c11
-rw-r--r--gcc/lower-subreg.c14
-rw-r--r--gcc/machmode.h31
-rw-r--r--gcc/reload.c3
-rw-r--r--gcc/stor-layout.c52
-rw-r--r--gcc/varasm.c4
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)
{