*** empty log message ***

From-SVN: r1232
This commit is contained in:
Richard Stallman 1992-06-22 03:40:10 +00:00
parent ab40ad2b6a
commit 5352b11a95
4 changed files with 119 additions and 20 deletions

View File

@ -2921,7 +2921,7 @@ simplify_unary_operation (code, mode, op, op_mode)
break;
case FLOAT_TRUNCATE:
d = (double) REAL_VALUE_TRUNCATE (mode, d);
d = (double) real_value_truncate (mode, d);
break;
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 (f1, op1);
f0 = REAL_VALUE_TRUNCATE (mode, f0);
f1 = REAL_VALUE_TRUNCATE (mode, f1);
f0 = real_value_truncate (mode, f0);
f1 = real_value_truncate (mode, f1);
#ifdef REAL_ARITHMETIC
REAL_ARITHMETIC (value, code, f0, f1);
@ -3097,7 +3097,7 @@ simplify_binary_operation (code, mode, op0, op1)
#endif
set_float_handler (0);
value = REAL_VALUE_TRUNCATE (mode, value);
value = real_value_truncate (mode, value);
return immed_real_const_1 (value, mode);
}

View File

@ -699,6 +699,35 @@ div_and_round_double (code, uns,
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
/* Check for infinity in an IEEE double precision number. */
@ -1215,7 +1244,7 @@ const_binop (code, arg1, arg2)
}
#endif /* no REAL_ARITHMETIC */
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);
return t;
}
@ -1423,7 +1452,7 @@ fold_convert (t, arg1)
}
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)));
set_float_handler (0);
return t;

View File

@ -154,6 +154,9 @@ extern double (atof) ();
for the most common case where the host and target have objects of the same
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
#define REAL_VALUE_TRUNCATE(mode, x) \
(GET_MODE_BITSIZE (mode) == sizeof (float) * HOST_BITS_PER_CHAR \

View File

@ -319,6 +319,7 @@ static void reload_as_needed ();
static int modes_equiv_for_class_p ();
static void alter_reg ();
static void delete_dead_insn ();
static void spill_failure ();
static int new_spill_reg();
static void set_label_offsets ();
static int eliminate_regs_in_insn ();
@ -477,9 +478,12 @@ init_reload ()
DUMPFILE is the global-reg debugging dump file stream, or 0.
If it is nonzero, messages are written to it to describe
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)
rtx first;
int global;
@ -497,6 +501,9 @@ reload (first, global, dumpfile)
enum reg_class caller_save_spill_class = NO_REGS;
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. */
int this_block;
@ -777,12 +784,19 @@ reload (first, global, dumpfile)
they must be the same size and equally restrictive for that class,
otherwise we can't handle the complexity. */
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;
something_changed = 0;
bzero (max_needs, sizeof max_needs);
bzero (max_groups, sizeof max_groups);
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);
for (i = 0; i < N_REG_CLASSES; i++)
group_mode[i] = VOIDmode;
@ -1271,12 +1285,21 @@ reload (first, global, dumpfile)
for (i = 0; i < N_REG_CLASSES; 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])
max_groups[i] = insn_groups[i];
{
max_groups[i] = insn_groups[i];
max_groups_insn[i] = insn;
}
if (insn_total_groups > 0)
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. */
@ -1567,9 +1590,17 @@ reload (first, global, dumpfile)
/* I should be the index in potential_reload_regs
of the new reload reg we have found. */
something_changed
|= new_spill_reg (i, class, max_needs, 0,
global, dumpfile);
if (i >= FIRST_PSEUDO_REGISTER)
{
/* 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
{
@ -1600,9 +1631,17 @@ reload (first, global, dumpfile)
for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++)
if (potential_reload_regs[idx] == j + k)
break;
something_changed
|= new_spill_reg (idx, class, max_needs, 0,
global, dumpfile);
if (i >= FIRST_PSEUDO_REGISTER)
{
/* 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,
@ -1648,9 +1687,18 @@ reload (first, global, dumpfile)
/* I should be the index in potential_reload_regs
of the new reload reg we have found. */
something_changed
|= new_spill_reg (i, class, max_needs, max_nongroups,
global, dumpfile);
if (i >= FIRST_PSEUDO_REGISTER)
{
/* 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;
/* 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
their equivalent memory references.
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. */
reg_equiv_constant = 0;
reg_equiv_memory_loc = 0;
return failure;
}
/* 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;
}
/* 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
(as well as spilling all pseudos allocated to the register).
I is the index of this register in potential_reload_regs.