===================================================================
@@ -4823,7 +4823,7 @@ cse_insn (rtx insn)
rtx new_and = gen_rtx_AND (VOIDmode, NULL_RTX, XEXP (src, 1));
for (tmode = GET_MODE_WIDER_MODE (mode);
- GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
+ GET_MODE_SIZE (tmode) <= UNITS_PER_WORD && tmode != VOIDmode;
tmode = GET_MODE_WIDER_MODE (tmode))
{
rtx inner = gen_lowpart (tmode, XEXP (src, 0));
@@ -4875,7 +4875,7 @@ cse_insn (rtx insn)
XEXP (memory_extend_rtx, 0) = src;
for (tmode = GET_MODE_WIDER_MODE (mode);
- GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
+ GET_MODE_SIZE (tmode) <= UNITS_PER_WORD && tmode != VOIDmode;
tmode = GET_MODE_WIDER_MODE (tmode))
{
struct table_elt *larger_elt;
===================================================================
@@ -1738,7 +1738,7 @@ find_shift_sequence (int access_size,
for (new_mode = smallest_mode_for_size (access_size * BITS_PER_UNIT,
MODE_INT);
- GET_MODE_BITSIZE (new_mode) <= BITS_PER_WORD;
+ GET_MODE_BITSIZE (new_mode) <= BITS_PER_WORD && new_mode != VOIDmode;
new_mode = GET_MODE_WIDER_MODE (new_mode))
{
rtx target, new_reg, shift_seq, insn, new_lhs;
===================================================================
@@ -11118,7 +11118,8 @@ simplify_comparison (enum rtx_code code,
else if (c0 == c1)
for (tmode = GET_CLASS_NARROWEST_MODE
(GET_MODE_CLASS (GET_MODE (op0)));
- tmode != GET_MODE (op0); tmode = GET_MODE_WIDER_MODE (tmode))
+ tmode != GET_MODE (op0) && tmode != VOIDmode;
+ tmode = GET_MODE_WIDER_MODE (tmode))
if ((unsigned HOST_WIDE_INT) c0 == GET_MODE_MASK (tmode))
{
op0 = gen_lowpart (tmode, inner_op0);
===================================================================
@@ -249,6 +249,12 @@ extern const unsigned char mode_nunits[N
extern const unsigned char mode_wider[NUM_MACHINE_MODES];
#define GET_MODE_WIDER_MODE(MODE) ((enum machine_mode) mode_wider[MODE])
+/* Special modes are not listed in the normal widening tables, but they are
+ listed in the widening tables used for initialization, etc. */
+extern const unsigned char mode_wider_special[NUM_MACHINE_MODES];
+#define GET_MODE_WIDER_MODE_SPECIAL(MODE) \
+ ((enum machine_mode) mode_wider_special[MODE])
+
/* For scalars, this is a mode with twice the precision. For vectors,
this is a mode with the same inner mode but with twice the elements. */
extern const unsigned char mode_2xwider[NUM_MACHINE_MODES];
===================================================================
@@ -5278,7 +5278,8 @@ init_num_sign_bit_copies_in_rep (void)
for (in_mode = GET_CLASS_NARROWEST_MODE (MODE_INT); in_mode != VOIDmode;
in_mode = GET_MODE_WIDER_MODE (mode))
- for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != in_mode;
+ for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
+ mode != in_mode && mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
{
enum machine_mode i;
===================================================================
@@ -90,6 +90,15 @@ along with GCC; see the file COPYING3.
storage, but with only PRECISION significant bits, using
floating point format FORMAT.
+ SPECIAL_FLOAT_MODE (MODE, BYTESIZE, FORMAT);
+ declares MODE to be of class FLOAT and BYTESIZE bytes wide, using
+ floating point format FORMAT. MODE is arranged so that other scalar
+ floating point mode's of the same size are preferred when the compiler
+ is trying to widen the floating point. The intention is to support the
+ PowerPC which has 2 128-bit floating point types (IEEE 128-bit and the
+ IBM extended double format), and have DFmode widen to TFmode (IBM
+ format) instead of KFmode (IEEE 128-bit).
+
DECIMAL_FLOAT_MODE (MODE, BYTESIZE, FORMAT);
declares MODE to be of class DECIMAL_FLOAT and BYTESIZE bytes
wide. All of the bits of its representation are significant.
===================================================================
@@ -264,11 +264,11 @@ init_expr_target (void)
mem = gen_rtx_MEM (VOIDmode, gen_rtx_raw_REG (Pmode, 10000));
for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
{
enum machine_mode srcmode;
for (srcmode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); srcmode != mode;
- srcmode = GET_MODE_WIDER_MODE (srcmode))
+ srcmode = GET_MODE_WIDER_MODE_SPECIAL (srcmode))
{
enum insn_code ic;
@@ -3645,7 +3645,7 @@ compress_float_constant (rtx x, rtx y)
oldcost = set_src_cost (force_const_mem (dstmode, y), speed);
for (srcmode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (orig_srcmode));
- srcmode != orig_srcmode;
+ srcmode != orig_srcmode && srcmode != VOIDmode;
srcmode = GET_MODE_WIDER_MODE (srcmode))
{
enum insn_code ic;
===================================================================
@@ -74,6 +74,8 @@ struct mode_data
unsigned int fbit; /* the number of fractional bits */
bool need_bytesize_adj; /* true if this mode need dynamic size
adjustment */
+ bool special; /* true if this mode is special and should be
+ skipped with the normal widening rules. */
};
static struct mode_data *modes[MAX_MODE_CLASS];
@@ -84,7 +86,7 @@ static const struct mode_data blank_mode
0, "<unknown>", MAX_MODE_CLASS,
-1U, -1U, -1U, -1U,
0, 0, 0, 0, 0,
- "<unknown>", 0, 0, 0, 0, false
+ "<unknown>", 0, 0, 0, 0, false, false
};
static htab_t modes_by_name;
@@ -368,6 +370,7 @@ complete_mode (struct mode_data *m)
/* Complex modes should have a component indicated, but no more. */
validate_mode (m, UNSET, UNSET, SET, UNSET, UNSET);
m->ncomponents = 2;
+ m->special = m->component->special;
if (m->component->precision != (unsigned int)-1)
m->precision = 2 * m->component->precision;
m->bytesize = 2 * m->component->bytesize;
@@ -384,6 +387,7 @@ complete_mode (struct mode_data *m)
if (m->component->precision != (unsigned int)-1)
m->precision = m->ncomponents * m->component->precision;
m->bytesize = m->ncomponents * m->component->bytesize;
+ m->special = m->component->special;
break;
default:
@@ -579,20 +583,29 @@ make_fixed_point_mode (enum mode_class c
m->fbit = fbit;
}
-#define FLOAT_MODE(N, Y, F) FRACTIONAL_FLOAT_MODE (N, -1U, Y, F)
-#define FRACTIONAL_FLOAT_MODE(N, B, Y, F) \
- make_float_mode (#N, B, Y, #F, __FILE__, __LINE__)
+#define FLOAT_MODE(N, Y, F) \
+ FLOAT_MODE_INTERNAL (N, -1U, Y, F, false)
+
+#define FRACTIONAL_FLOAT_MODE(N, B, Y, F) \
+ FLOAT_MODE_INTERNAL (N, B, Y, F, false)
+
+#define SPECIAL_FLOAT_MODE(N, B, Y, F) \
+ FLOAT_MODE_INTERNAL (N, B, Y, F, true)
+
+#define FLOAT_MODE_INTERNAL(N, B, Y, F, SPECIAL) \
+ make_float_mode (#N, B, Y, #F, SPECIAL, __FILE__, __LINE__)
static void
make_float_mode (const char *name,
unsigned int precision, unsigned int bytesize,
- const char *format,
+ const char *format, bool special,
const char *file, unsigned int line)
{
struct mode_data *m = new_mode (MODE_FLOAT, name, file, line);
m->bytesize = bytesize;
m->precision = precision;
m->format = format;
+ m->special = special;
}
#define DECIMAL_FLOAT_MODE(N, Y, F) \
@@ -1194,7 +1207,9 @@ emit_mode_wider (void)
int c;
struct mode_data *m;
- print_decl ("unsigned char", "mode_wider", "NUM_MACHINE_MODES");
+ /* Special modes are not listed in the normal widening tables, but they are
+ listed in the widening tables used for initialization, etc. */
+ print_decl ("unsigned char", "mode_wider_special", "NUM_MACHINE_MODES");
for_all_modes (c, m)
tagged_printf ("%smode",
@@ -1202,6 +1217,37 @@ emit_mode_wider (void)
m->name);
print_closer ();
+ print_decl ("unsigned char", "mode_wider", "NUM_MACHINE_MODES");
+
+ for_all_modes (c, m)
+ {
+ const char *name;
+
+ if (!m->wider)
+ name = void_mode->name;
+ else if (!m->wider->special || m->special)
+ name = m->wider->name;
+ else
+ {
+ struct mode_data * m2;
+
+ name = void_mode->name;
+ for (m2 = m->wider->wider;
+ m2 && m2 != void_mode;
+ m2 = m2->wider)
+ {
+ if (!m2->special)
+ {
+ name = m2->name;
+ break;
+ }
+ }
+ }
+
+ tagged_printf ("%smode", name, m->name);
+ }
+
+ print_closer ();
print_decl ("unsigned char", "mode_2xwider", "NUM_MACHINE_MODES");
for_all_modes (c, m)
@@ -1212,6 +1258,8 @@ emit_mode_wider (void)
m2 && m2 != void_mode;
m2 = m2->wider)
{
+ if (m2->special && !m->special)
+ continue;
if (m2->bytesize < 2 * m->bytesize)
continue;
if (m->precision != (unsigned int) -1)
@@ -1242,8 +1290,10 @@ emit_mode_wider (void)
break;
}
+
if (m2 == void_mode)
m2 = 0;
+
tagged_printf ("%smode",
m2 ? m2->name : void_mode->name,
m->name);
===================================================================
@@ -5786,7 +5786,7 @@ init_derived_machine_modes (void)
for (enum machine_mode mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
{
if (GET_MODE_BITSIZE (mode) == BITS_PER_UNIT
&& byte_mode == VOIDmode)
@@ -5868,13 +5868,13 @@ init_emit_once (void)
for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
const_tiny_rtx[i][(int) mode] =
CONST_DOUBLE_FROM_REAL_VALUE (*r, mode);
for (mode = GET_CLASS_NARROWEST_MODE (MODE_DECIMAL_FLOAT);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
const_tiny_rtx[i][(int) mode] =
CONST_DOUBLE_FROM_REAL_VALUE (*r, mode);
@@ -5882,7 +5882,7 @@ init_emit_once (void)
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
const_tiny_rtx[i][(int) mode] = GEN_INT (i);
for (mode = MIN_MODE_PARTIAL_INT;
@@ -5895,7 +5895,7 @@ init_emit_once (void)
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
const_tiny_rtx[3][(int) mode] = constm1_rtx;
for (mode = MIN_MODE_PARTIAL_INT;
@@ -5905,7 +5905,7 @@ init_emit_once (void)
for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_INT);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
{
rtx inner = const_tiny_rtx[0][(int)GET_MODE_INNER (mode)];
const_tiny_rtx[0][(int) mode] = gen_rtx_CONCAT (mode, inner, inner);
@@ -5913,7 +5913,7 @@ init_emit_once (void)
for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
{
rtx inner = const_tiny_rtx[0][(int)GET_MODE_INNER (mode)];
const_tiny_rtx[0][(int) mode] = gen_rtx_CONCAT (mode, inner, inner);
@@ -5921,7 +5921,7 @@ init_emit_once (void)
for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
{
const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
@@ -5930,7 +5930,7 @@ init_emit_once (void)
for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
{
const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
@@ -5938,7 +5938,7 @@ init_emit_once (void)
for (mode = GET_CLASS_NARROWEST_MODE (MODE_FRACT);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
{
FCONST0 (mode).data.high = 0;
FCONST0 (mode).data.low = 0;
@@ -5949,7 +5949,7 @@ init_emit_once (void)
for (mode = GET_CLASS_NARROWEST_MODE (MODE_UFRACT);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
{
FCONST0 (mode).data.high = 0;
FCONST0 (mode).data.low = 0;
@@ -5960,7 +5960,7 @@ init_emit_once (void)
for (mode = GET_CLASS_NARROWEST_MODE (MODE_ACCUM);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
{
FCONST0 (mode).data.high = 0;
FCONST0 (mode).data.low = 0;
@@ -5982,7 +5982,7 @@ init_emit_once (void)
for (mode = GET_CLASS_NARROWEST_MODE (MODE_UACCUM);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
{
FCONST0 (mode).data.high = 0;
FCONST0 (mode).data.low = 0;
@@ -6004,21 +6004,21 @@ init_emit_once (void)
for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FRACT);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
{
const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
}
for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_UFRACT);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
{
const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
}
for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_ACCUM);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
{
const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
@@ -6026,7 +6026,7 @@ init_emit_once (void)
for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_UACCUM);
mode != VOIDmode;
- mode = GET_MODE_WIDER_MODE (mode))
+ mode = GET_MODE_WIDER_MODE_SPECIAL (mode))
{
const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);