parent
ab40ad2b6a
commit
5352b11a95
|
@ -2921,7 +2921,7 @@ simplify_unary_operation (code, mode, op, op_mode)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLOAT_TRUNCATE:
|
case FLOAT_TRUNCATE:
|
||||||
d = (double) REAL_VALUE_TRUNCATE (mode, d);
|
d = (double) real_value_truncate (mode, d);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLOAT_EXTEND:
|
case FLOAT_EXTEND:
|
||||||
|
@ -3061,8 +3061,8 @@ simplify_binary_operation (code, mode, op0, op1)
|
||||||
|
|
||||||
REAL_VALUE_FROM_CONST_DOUBLE (f0, op0);
|
REAL_VALUE_FROM_CONST_DOUBLE (f0, op0);
|
||||||
REAL_VALUE_FROM_CONST_DOUBLE (f1, op1);
|
REAL_VALUE_FROM_CONST_DOUBLE (f1, op1);
|
||||||
f0 = REAL_VALUE_TRUNCATE (mode, f0);
|
f0 = real_value_truncate (mode, f0);
|
||||||
f1 = REAL_VALUE_TRUNCATE (mode, f1);
|
f1 = real_value_truncate (mode, f1);
|
||||||
|
|
||||||
#ifdef REAL_ARITHMETIC
|
#ifdef REAL_ARITHMETIC
|
||||||
REAL_ARITHMETIC (value, code, f0, f1);
|
REAL_ARITHMETIC (value, code, f0, f1);
|
||||||
|
@ -3097,7 +3097,7 @@ simplify_binary_operation (code, mode, op0, op1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
set_float_handler (0);
|
set_float_handler (0);
|
||||||
value = REAL_VALUE_TRUNCATE (mode, value);
|
value = real_value_truncate (mode, value);
|
||||||
return immed_real_const_1 (value, mode);
|
return immed_real_const_1 (value, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -699,6 +699,35 @@ div_and_round_double (code, uns,
|
||||||
add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
|
add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Effectively truncate a real value to represent
|
||||||
|
the nearest possible value in a narrower mode.
|
||||||
|
The result is actually represented in the same data type as the argument,
|
||||||
|
but its value is usually different. */
|
||||||
|
|
||||||
|
REAL_VALUE_TYPE
|
||||||
|
real_value_truncate (mode, arg)
|
||||||
|
enum machine_mode mode;
|
||||||
|
REAL_VALUE_TYPE arg;
|
||||||
|
{
|
||||||
|
#ifdef __STDC__
|
||||||
|
/* Make sure the value is actually stored in memory before we turn off
|
||||||
|
the handler. */
|
||||||
|
volatile
|
||||||
|
#endif
|
||||||
|
REAL_VALUE_TYPE value;
|
||||||
|
jmp_buf handler;
|
||||||
|
|
||||||
|
if (setjmp (handler))
|
||||||
|
{
|
||||||
|
error ("floating overflow");
|
||||||
|
return dconst0;
|
||||||
|
}
|
||||||
|
set_float_handler (handler);
|
||||||
|
value = REAL_VALUE_TRUNCATE (mode, arg);
|
||||||
|
set_float_handler (0);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
#if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
|
#if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
|
||||||
|
|
||||||
/* Check for infinity in an IEEE double precision number. */
|
/* Check for infinity in an IEEE double precision number. */
|
||||||
|
@ -1215,7 +1244,7 @@ const_binop (code, arg1, arg2)
|
||||||
}
|
}
|
||||||
#endif /* no REAL_ARITHMETIC */
|
#endif /* no REAL_ARITHMETIC */
|
||||||
t = build_real (TREE_TYPE (arg1),
|
t = build_real (TREE_TYPE (arg1),
|
||||||
REAL_VALUE_TRUNCATE (TYPE_MODE (TREE_TYPE (arg1)), value));
|
real_value_truncate (TYPE_MODE (TREE_TYPE (arg1)), value));
|
||||||
set_float_handler (0);
|
set_float_handler (0);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -1423,7 +1452,7 @@ fold_convert (t, arg1)
|
||||||
}
|
}
|
||||||
set_float_handler (float_error);
|
set_float_handler (float_error);
|
||||||
|
|
||||||
t = build_real (type, REAL_VALUE_TRUNCATE (TYPE_MODE (type),
|
t = build_real (type, real_value_truncate (TYPE_MODE (type),
|
||||||
TREE_REAL_CST (arg1)));
|
TREE_REAL_CST (arg1)));
|
||||||
set_float_handler (0);
|
set_float_handler (0);
|
||||||
return t;
|
return t;
|
||||||
|
|
|
@ -154,6 +154,9 @@ extern double (atof) ();
|
||||||
for the most common case where the host and target have objects of the same
|
for the most common case where the host and target have objects of the same
|
||||||
size and where `float' is SFmode. */
|
size and where `float' is SFmode. */
|
||||||
|
|
||||||
|
/* Don't use REAL_VALUE_TRUNCATE directly--always call real_value_truncate. */
|
||||||
|
extern REAL_VALUE_TYPE real_value_truncate ();
|
||||||
|
|
||||||
#ifndef REAL_VALUE_TRUNCATE
|
#ifndef REAL_VALUE_TRUNCATE
|
||||||
#define REAL_VALUE_TRUNCATE(mode, x) \
|
#define REAL_VALUE_TRUNCATE(mode, x) \
|
||||||
(GET_MODE_BITSIZE (mode) == sizeof (float) * HOST_BITS_PER_CHAR \
|
(GET_MODE_BITSIZE (mode) == sizeof (float) * HOST_BITS_PER_CHAR \
|
||||||
|
|
|
@ -319,6 +319,7 @@ static void reload_as_needed ();
|
||||||
static int modes_equiv_for_class_p ();
|
static int modes_equiv_for_class_p ();
|
||||||
static void alter_reg ();
|
static void alter_reg ();
|
||||||
static void delete_dead_insn ();
|
static void delete_dead_insn ();
|
||||||
|
static void spill_failure ();
|
||||||
static int new_spill_reg();
|
static int new_spill_reg();
|
||||||
static void set_label_offsets ();
|
static void set_label_offsets ();
|
||||||
static int eliminate_regs_in_insn ();
|
static int eliminate_regs_in_insn ();
|
||||||
|
@ -477,9 +478,12 @@ init_reload ()
|
||||||
DUMPFILE is the global-reg debugging dump file stream, or 0.
|
DUMPFILE is the global-reg debugging dump file stream, or 0.
|
||||||
If it is nonzero, messages are written to it to describe
|
If it is nonzero, messages are written to it to describe
|
||||||
which registers are seized as reload regs, which pseudo regs
|
which registers are seized as reload regs, which pseudo regs
|
||||||
are spilled from them, and where the pseudo regs are reallocated to. */
|
are spilled from them, and where the pseudo regs are reallocated to.
|
||||||
|
|
||||||
void
|
Return value is nonzero if reload failed
|
||||||
|
and we must not do any more for this function. */
|
||||||
|
|
||||||
|
int
|
||||||
reload (first, global, dumpfile)
|
reload (first, global, dumpfile)
|
||||||
rtx first;
|
rtx first;
|
||||||
int global;
|
int global;
|
||||||
|
@ -497,6 +501,9 @@ reload (first, global, dumpfile)
|
||||||
enum reg_class caller_save_spill_class = NO_REGS;
|
enum reg_class caller_save_spill_class = NO_REGS;
|
||||||
int caller_save_group_size = 1;
|
int caller_save_group_size = 1;
|
||||||
|
|
||||||
|
/* Nonzero means we couldn't get enough spill regs. */
|
||||||
|
int failure = 0;
|
||||||
|
|
||||||
/* The basic block number currently being processed for INSN. */
|
/* The basic block number currently being processed for INSN. */
|
||||||
int this_block;
|
int this_block;
|
||||||
|
|
||||||
|
@ -777,12 +784,19 @@ reload (first, global, dumpfile)
|
||||||
they must be the same size and equally restrictive for that class,
|
they must be the same size and equally restrictive for that class,
|
||||||
otherwise we can't handle the complexity. */
|
otherwise we can't handle the complexity. */
|
||||||
enum machine_mode group_mode[N_REG_CLASSES];
|
enum machine_mode group_mode[N_REG_CLASSES];
|
||||||
|
/* Record the insn where each maximum need is first found. */
|
||||||
|
rtx max_needs_insn[N_REG_CLASSES];
|
||||||
|
rtx max_groups_insn[N_REG_CLASSES];
|
||||||
|
rtx max_nongroups_insn[N_REG_CLASSES];
|
||||||
rtx x;
|
rtx x;
|
||||||
|
|
||||||
something_changed = 0;
|
something_changed = 0;
|
||||||
bzero (max_needs, sizeof max_needs);
|
bzero (max_needs, sizeof max_needs);
|
||||||
bzero (max_groups, sizeof max_groups);
|
bzero (max_groups, sizeof max_groups);
|
||||||
bzero (max_nongroups, sizeof max_nongroups);
|
bzero (max_nongroups, sizeof max_nongroups);
|
||||||
|
bzero (max_needs_insn, sizeof max_needs_insn);
|
||||||
|
bzero (max_groups_insn, sizeof max_groups_insn);
|
||||||
|
bzero (max_nongroups_insn, sizeof max_nongroups_insn);
|
||||||
bzero (group_size, sizeof group_size);
|
bzero (group_size, sizeof group_size);
|
||||||
for (i = 0; i < N_REG_CLASSES; i++)
|
for (i = 0; i < N_REG_CLASSES; i++)
|
||||||
group_mode[i] = VOIDmode;
|
group_mode[i] = VOIDmode;
|
||||||
|
@ -1271,12 +1285,21 @@ reload (first, global, dumpfile)
|
||||||
for (i = 0; i < N_REG_CLASSES; i++)
|
for (i = 0; i < N_REG_CLASSES; i++)
|
||||||
{
|
{
|
||||||
if (max_needs[i] < insn_needs[i])
|
if (max_needs[i] < insn_needs[i])
|
||||||
max_needs[i] = insn_needs[i];
|
{
|
||||||
|
max_needs[i] = insn_needs[i];
|
||||||
|
max_needs_insn[i] = insn;
|
||||||
|
}
|
||||||
if (max_groups[i] < insn_groups[i])
|
if (max_groups[i] < insn_groups[i])
|
||||||
max_groups[i] = insn_groups[i];
|
{
|
||||||
|
max_groups[i] = insn_groups[i];
|
||||||
|
max_groups_insn[i] = insn;
|
||||||
|
}
|
||||||
if (insn_total_groups > 0)
|
if (insn_total_groups > 0)
|
||||||
if (max_nongroups[i] < insn_needs[i])
|
if (max_nongroups[i] < insn_needs[i])
|
||||||
max_nongroups[i] = insn_needs[i];
|
{
|
||||||
|
max_nongroups[i] = insn_needs[i];
|
||||||
|
max_nongroups_insn[i] = insn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Note that there is a continue statement above. */
|
/* Note that there is a continue statement above. */
|
||||||
|
@ -1567,9 +1590,17 @@ reload (first, global, dumpfile)
|
||||||
/* I should be the index in potential_reload_regs
|
/* I should be the index in potential_reload_regs
|
||||||
of the new reload reg we have found. */
|
of the new reload reg we have found. */
|
||||||
|
|
||||||
something_changed
|
if (i >= FIRST_PSEUDO_REGISTER)
|
||||||
|= new_spill_reg (i, class, max_needs, 0,
|
{
|
||||||
global, dumpfile);
|
/* There are no groups left to spill. */
|
||||||
|
spill_failure (max_groups_insn[class]);
|
||||||
|
failure = 1;
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
something_changed
|
||||||
|
|= new_spill_reg (i, class, max_needs, 0,
|
||||||
|
global, dumpfile);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1600,9 +1631,17 @@ reload (first, global, dumpfile)
|
||||||
for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
|
for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
|
||||||
if (potential_reload_regs[idx] == j + k)
|
if (potential_reload_regs[idx] == j + k)
|
||||||
break;
|
break;
|
||||||
something_changed
|
if (i >= FIRST_PSEUDO_REGISTER)
|
||||||
|= new_spill_reg (idx, class, max_needs, 0,
|
{
|
||||||
global, dumpfile);
|
/* There are no groups left. */
|
||||||
|
spill_failure (max_groups_insn[class]);
|
||||||
|
failure = 1;
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
something_changed
|
||||||
|
|= new_spill_reg (idx, class, max_needs, 0,
|
||||||
|
global, dumpfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We have found one that will complete a group,
|
/* We have found one that will complete a group,
|
||||||
|
@ -1648,9 +1687,18 @@ reload (first, global, dumpfile)
|
||||||
/* I should be the index in potential_reload_regs
|
/* I should be the index in potential_reload_regs
|
||||||
of the new reload reg we have found. */
|
of the new reload reg we have found. */
|
||||||
|
|
||||||
something_changed
|
if (i >= FIRST_PSEUDO_REGISTER)
|
||||||
|= new_spill_reg (i, class, max_needs, max_nongroups,
|
{
|
||||||
global, dumpfile);
|
/* There are no possible registers left to spill. */
|
||||||
|
spill_failure (max_needs[class] > 0 ? max_needs_insn[class]
|
||||||
|
: max_nongroups_insn[class]);
|
||||||
|
failure = 1;
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
something_changed
|
||||||
|
|= new_spill_reg (i, class, max_needs, max_nongroups,
|
||||||
|
global, dumpfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1706,6 +1754,10 @@ reload (first, global, dumpfile)
|
||||||
|
|
||||||
reload_in_progress = 0;
|
reload_in_progress = 0;
|
||||||
|
|
||||||
|
/* Come here (with failure set nonzero) if we can't get enough spill regs
|
||||||
|
and we decide not to abort about it. */
|
||||||
|
failed:
|
||||||
|
|
||||||
/* Now eliminate all pseudo regs by modifying them into
|
/* Now eliminate all pseudo regs by modifying them into
|
||||||
their equivalent memory references.
|
their equivalent memory references.
|
||||||
The REG-rtx's for the pseudos are modified in place,
|
The REG-rtx's for the pseudos are modified in place,
|
||||||
|
@ -1766,6 +1818,8 @@ reload (first, global, dumpfile)
|
||||||
/* Indicate that we no longer have known memory locations or constants. */
|
/* Indicate that we no longer have known memory locations or constants. */
|
||||||
reg_equiv_constant = 0;
|
reg_equiv_constant = 0;
|
||||||
reg_equiv_memory_loc = 0;
|
reg_equiv_memory_loc = 0;
|
||||||
|
|
||||||
|
return failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nonzero if, after spilling reg REGNO for non-groups,
|
/* Nonzero if, after spilling reg REGNO for non-groups,
|
||||||
|
@ -1917,6 +1971,19 @@ modes_equiv_for_class_p (allocate_mode, other_mode, class)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle the failure to find a register to spill.
|
||||||
|
INSN should be one of the insns which needed this particular spill reg. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
spill_failure (insn)
|
||||||
|
rtx insn;
|
||||||
|
{
|
||||||
|
if (asm_noperands (PATTERN (insn)) >= 0)
|
||||||
|
error_for_asm (insn, "`asm' needs too many reloads");
|
||||||
|
else
|
||||||
|
abort ();
|
||||||
|
}
|
||||||
|
|
||||||
/* Add a new register to the tables of available spill-registers
|
/* Add a new register to the tables of available spill-registers
|
||||||
(as well as spilling all pseudos allocated to the register).
|
(as well as spilling all pseudos allocated to the register).
|
||||||
I is the index of this register in potential_reload_regs.
|
I is the index of this register in potential_reload_regs.
|
||||||
|
|
Loading…
Reference in New Issue