hard-reg-set.h (REG_CANNOT_CHANGE_MODE_P): New.
2002-11-04 Aldy Hernandez <aldyh@redhat.com> * hard-reg-set.h (REG_CANNOT_CHANGE_MODE_P): New. * config/rs6000/rs6000.h (CLASS_CANNOT_CHANGE_MODE_P): Remove. (CLASS_CANNOT_CHANGE_MODE): Remove. (CANNOT_CHANGE_MODE_CLASS): New. * config/alpha/alpha.h: Same. * config/ia64/ia64.h: Same. * config/mips/mips.h: Same. * config/s390/s390.h: Same. * config/sh/sh.h: Same. * config/pa/pa64-regs.h: Same. * config/sh/sh-protos.h (sh_cannot_change_mode_class): Add prototype. * config/sh/sh.c (sh_cannot_change_mode_class): New. * config/mips/mips-protos.h (mips_cannot_change_mode_class): Add prototype. * config/mips/mips.c (mips_cannot_change_mode_class): New. * doc/tm.texi (Register Classes): Remove CLASS_CANNOT_CHANGE_MODE and CLASS_CANNOT_CHANGE_MODE_P. Document CANNOT_CHANGE_MODE_CLASS. * reload.c (push_reload): Use CANNOT_CHANGE_MODE_CLASS. (push_reload): Same. * simplify-rtx.c (simplify_subreg): Same. * reload1.c (choose_reload_regs): Same. * recog.c (register_operand): Same. * regrename.c (mode_change_ok): Change to use new CANNOT_CHANGE_MODE_CLASS infrastructure. * regclass.c (cannot_change_mode_set_regs): New. Declare subregs_of_mode. (regclass): Use subregs_of_mode. Remove references to reg_changes_mode. (init_reg_sets_1): Remove class_can_change_mode and reg_changes_mode code. (invalid_mode_change_p): New. (dump_regclass): Use invalid_mode_change_p instead of class_can_change_mode. (regclass): Same. (record_operand_costs): Do not set reg_changes_mode. * local-alloc.c (struct qty): Remove changes_mode field. (alloc_qty): Remove changes_mode initialization. (update_qty_class): Remove set of changes_mode. (find_free_reg): Use subregs_of_mode. * global.c (find_reg): Use subregs_of_mode info. * rtl.h (cannot_change_mode_set_regs): New prototype. (invalid_mode_change_p): Same. (REG_CANNOT_CHANGE_MODE_P): New macro. * flow.c (mark_used_regs): Calculate subregs_of_mode. Remove REG_CHANGES_MODE. (life_analysis): Clear subregs_of_mode. * combine.c (subst): Pass class to CLASS_CANNOT_CHANGE_MODE_P. Remove use of CLASS_CANNOT_CHANGE_MODE. (simplify_set): Same. (gen_lowpart_for_combine): Calculate subregs_of_mode. Remove REG_CHANGES_MODE. * regs.h: Add extern for subregs_of_mode; Include hard-reg-set and basic-block. (REG_CHANGES_MODE): Delete. From-SVN: r58794
This commit is contained in:
parent
f1c129e309
commit
cff9f8d509
@ -1,3 +1,85 @@
|
||||
2002-11-04 Aldy Hernandez <aldyh@redhat.com>
|
||||
|
||||
* hard-reg-set.h (REG_CANNOT_CHANGE_MODE_P): New.
|
||||
|
||||
* config/rs6000/rs6000.h (CLASS_CANNOT_CHANGE_MODE_P): Remove.
|
||||
(CLASS_CANNOT_CHANGE_MODE): Remove.
|
||||
(CANNOT_CHANGE_MODE_CLASS): New.
|
||||
|
||||
* config/alpha/alpha.h: Same.
|
||||
|
||||
* config/ia64/ia64.h: Same.
|
||||
|
||||
* config/mips/mips.h: Same.
|
||||
|
||||
* config/s390/s390.h: Same.
|
||||
|
||||
* config/sh/sh.h: Same.
|
||||
|
||||
* config/pa/pa64-regs.h: Same.
|
||||
|
||||
* config/sh/sh-protos.h (sh_cannot_change_mode_class): Add prototype.
|
||||
|
||||
* config/sh/sh.c (sh_cannot_change_mode_class): New.
|
||||
|
||||
* config/mips/mips-protos.h (mips_cannot_change_mode_class): Add
|
||||
prototype.
|
||||
|
||||
* config/mips/mips.c (mips_cannot_change_mode_class): New.
|
||||
|
||||
* doc/tm.texi (Register Classes): Remove
|
||||
CLASS_CANNOT_CHANGE_MODE and CLASS_CANNOT_CHANGE_MODE_P.
|
||||
Document CANNOT_CHANGE_MODE_CLASS.
|
||||
|
||||
* reload.c (push_reload): Use CANNOT_CHANGE_MODE_CLASS.
|
||||
(push_reload): Same.
|
||||
|
||||
* simplify-rtx.c (simplify_subreg): Same.
|
||||
|
||||
* reload1.c (choose_reload_regs): Same.
|
||||
|
||||
* recog.c (register_operand): Same.
|
||||
|
||||
* regrename.c (mode_change_ok): Change to use new
|
||||
CANNOT_CHANGE_MODE_CLASS infrastructure.
|
||||
|
||||
* regclass.c (cannot_change_mode_set_regs): New.
|
||||
Declare subregs_of_mode.
|
||||
(regclass): Use subregs_of_mode.
|
||||
Remove references to reg_changes_mode.
|
||||
(init_reg_sets_1): Remove class_can_change_mode and
|
||||
reg_changes_mode code.
|
||||
(invalid_mode_change_p): New.
|
||||
(dump_regclass): Use invalid_mode_change_p instead of
|
||||
class_can_change_mode.
|
||||
(regclass): Same.
|
||||
(record_operand_costs): Do not set reg_changes_mode.
|
||||
|
||||
* local-alloc.c (struct qty): Remove changes_mode field.
|
||||
(alloc_qty): Remove changes_mode initialization.
|
||||
(update_qty_class): Remove set of changes_mode.
|
||||
(find_free_reg): Use subregs_of_mode.
|
||||
|
||||
* global.c (find_reg): Use subregs_of_mode info.
|
||||
|
||||
* rtl.h (cannot_change_mode_set_regs): New prototype.
|
||||
(invalid_mode_change_p): Same.
|
||||
(REG_CANNOT_CHANGE_MODE_P): New macro.
|
||||
|
||||
* flow.c (mark_used_regs): Calculate subregs_of_mode. Remove
|
||||
REG_CHANGES_MODE.
|
||||
(life_analysis): Clear subregs_of_mode.
|
||||
|
||||
* combine.c (subst): Pass class to CLASS_CANNOT_CHANGE_MODE_P.
|
||||
Remove use of CLASS_CANNOT_CHANGE_MODE.
|
||||
(simplify_set): Same.
|
||||
(gen_lowpart_for_combine): Calculate subregs_of_mode. Remove
|
||||
REG_CHANGES_MODE.
|
||||
|
||||
* regs.h: Add extern for subregs_of_mode;
|
||||
Include hard-reg-set and basic-block.
|
||||
(REG_CHANGES_MODE): Delete.
|
||||
|
||||
2002-11-03 John David Anglin <dave@hiauly1.hia.nrc.ca>
|
||||
|
||||
* jump.c (never_reached_warning): Don't set contains_insn until the
|
||||
|
@ -3519,15 +3519,13 @@ subst (x, from, to, in_dest, unique_copy)
|
||||
)
|
||||
return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
|
||||
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
if (code == SUBREG
|
||||
&& GET_CODE (to) == REG
|
||||
&& REGNO (to) < FIRST_PSEUDO_REGISTER
|
||||
&& (TEST_HARD_REG_BIT
|
||||
(reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
|
||||
REGNO (to)))
|
||||
&& CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (to),
|
||||
GET_MODE (x)))
|
||||
&& REG_CANNOT_CHANGE_MODE_P (REGNO (to),
|
||||
GET_MODE (to),
|
||||
GET_MODE (x)))
|
||||
return gen_rtx_CLOBBER (VOIDmode, const0_rtx);
|
||||
#endif
|
||||
|
||||
@ -5198,13 +5196,11 @@ simplify_set (x)
|
||||
&& (GET_MODE_SIZE (GET_MODE (src))
|
||||
< GET_MODE_SIZE (GET_MODE (SUBREG_REG (src))))
|
||||
#endif
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
&& ! (GET_CODE (dest) == REG && REGNO (dest) < FIRST_PSEUDO_REGISTER
|
||||
&& (TEST_HARD_REG_BIT
|
||||
(reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
|
||||
REGNO (dest)))
|
||||
&& CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (src),
|
||||
GET_MODE (SUBREG_REG (src))))
|
||||
&& REG_CANNOT_CHANGE_MODE_P (REGNO (dest),
|
||||
GET_MODE (src),
|
||||
GET_MODE (SUBREG_REG (src))))
|
||||
#endif
|
||||
&& (GET_CODE (dest) == REG
|
||||
|| (GET_CODE (dest) == SUBREG
|
||||
@ -9937,14 +9933,13 @@ gen_lowpart_for_combine (mode, x)
|
||||
}
|
||||
|
||||
result = gen_lowpart_common (mode, x);
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
if (result != 0
|
||||
&& GET_CODE (result) == SUBREG
|
||||
&& GET_CODE (SUBREG_REG (result)) == REG
|
||||
&& REGNO (SUBREG_REG (result)) >= FIRST_PSEUDO_REGISTER
|
||||
&& CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (result),
|
||||
GET_MODE (SUBREG_REG (result))))
|
||||
REG_CHANGES_MODE (REGNO (SUBREG_REG (result))) = 1;
|
||||
&& REGNO (SUBREG_REG (result)) >= FIRST_PSEUDO_REGISTER)
|
||||
SET_REGNO_REG_SET (&subregs_of_mode[GET_MODE (result)],
|
||||
REGNO (SUBREG_REG (result)));
|
||||
#endif
|
||||
|
||||
if (result)
|
||||
|
@ -857,15 +857,10 @@ enum reg_class {
|
||||
#define CLASS_MAX_NREGS(CLASS, MODE) \
|
||||
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
|
||||
|
||||
/* If defined, gives a class of registers that cannot be used as the
|
||||
operand of a SUBREG that changes the mode of the object illegally. */
|
||||
/* Return the class of registers that cannot change mode from FROM to TO. */
|
||||
|
||||
#define CLASS_CANNOT_CHANGE_MODE FLOAT_REGS
|
||||
|
||||
/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
|
||||
|
||||
#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
|
||||
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
|
||||
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
|
||||
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) ? FLOAT_REGS : NO_REGS)
|
||||
|
||||
/* Define the cost of moving between registers of various classes. Moving
|
||||
between FLOAT_REGS and anything else except float regs is expensive.
|
||||
|
@ -1008,17 +1008,11 @@ enum reg_class
|
||||
: ((CLASS) == FR_REGS && (MODE) == TFmode) ? 1 \
|
||||
: (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
|
||||
|
||||
/* If defined, gives a class of registers that cannot be used as the
|
||||
operand of a SUBREG that changes the mode of the object illegally. */
|
||||
|
||||
#define CLASS_CANNOT_CHANGE_MODE FR_REGS
|
||||
|
||||
/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE.
|
||||
In FP regs, we can't change FP values to integer values and vice
|
||||
/* In FP regs, we can't change FP values to integer values and vice
|
||||
versa, but we can change e.g. DImode to SImode. */
|
||||
|
||||
#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
|
||||
(GET_MODE_CLASS (FROM) != GET_MODE_CLASS (TO))
|
||||
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
|
||||
(GET_MODE_CLASS (FROM) != GET_MODE_CLASS (TO) ? FR_REGS : NO_REGS)
|
||||
|
||||
/* A C expression that defines the machine-dependent operand constraint
|
||||
letters (`I', `J', `K', .. 'P') that specify particular ranges of
|
||||
|
@ -122,6 +122,8 @@ extern int mips_adjust_insn_length PARAMS ((rtx, int));
|
||||
extern enum reg_class mips_secondary_reload_class PARAMS ((enum reg_class,
|
||||
enum machine_mode,
|
||||
rtx, int));
|
||||
extern enum reg_class mips_cannot_change_mode_class
|
||||
PARAMS ((enum machine_mode, enum machine_mode));
|
||||
extern int mips_class_max_nregs PARAMS ((enum reg_class,
|
||||
enum machine_mode));
|
||||
extern int mips_register_move_cost PARAMS ((enum machine_mode,
|
||||
|
@ -8399,6 +8399,23 @@ function_arg_pass_by_reference (cum, mode, type, named)
|
||||
return size == -1 || size > UNITS_PER_WORD;
|
||||
}
|
||||
|
||||
/* Return the class of registers for which a mode change from FROM to TO
|
||||
is invalid. */
|
||||
enum reg_class
|
||||
mips_cannot_change_mode_class (from, to)
|
||||
enum machine_mode from, to;
|
||||
{
|
||||
if (GET_MODE_SIZE (from) != GET_MODE_SIZE (to))
|
||||
{
|
||||
if (TARGET_BIG_ENDIAN)
|
||||
return FP_REGS;
|
||||
if (TARGET_FLOAT64)
|
||||
return HI_AND_FP_REGS;
|
||||
return HI_REG;
|
||||
}
|
||||
return NO_REGS;
|
||||
}
|
||||
|
||||
/* This function returns the register class required for a secondary
|
||||
register when copying between one of the registers in CLASS, and X,
|
||||
using MODE. If IN_P is nonzero, the copy is going from X to the
|
||||
|
@ -2343,14 +2343,8 @@ extern enum reg_class mips_char_to_class[256];
|
||||
We can't allow 64-bit float registers to change from a 32-bit
|
||||
mode to a 64-bit mode. */
|
||||
|
||||
#define CLASS_CANNOT_CHANGE_MODE \
|
||||
(TARGET_BIG_ENDIAN ? FP_REGS \
|
||||
: (TARGET_FLOAT64 ? HI_AND_FP_REGS : HI_REG))
|
||||
|
||||
/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
|
||||
|
||||
#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
|
||||
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
|
||||
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
|
||||
mips_cannot_change_mode_class (FROM, TO)
|
||||
|
||||
/* Stack layout; function entry, exit and calling. */
|
||||
|
||||
|
@ -232,12 +232,7 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
|
||||
{0x00000000, 0x10000000}, /* SHIFT_REGS */ \
|
||||
{0xfffffffe, 0x1fffffff}} /* ALL_REGS */
|
||||
|
||||
/* If defined, gives a class of registers that cannot be used as the
|
||||
operand of a SUBREG that changes the mode of the object illegally. */
|
||||
|
||||
#define CLASS_CANNOT_CHANGE_MODE (FP_REGS)
|
||||
|
||||
/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE.
|
||||
/* Defines invalid mode changes.
|
||||
|
||||
SImode loads to floating-point registers are not zero-extended.
|
||||
The definition for LOAD_EXTEND_OP specifies that integer loads
|
||||
@ -245,8 +240,9 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
|
||||
we inhibit changes from SImode unless they are to a mode that is
|
||||
identical in size. */
|
||||
|
||||
#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
|
||||
((FROM) == SImode && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
|
||||
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
|
||||
((FROM) == SImode && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
|
||||
? FP_REGS : NO_REGS)
|
||||
|
||||
/* Return the class number of the smallest class containing
|
||||
reg number REGNO. This could be a conditional expression
|
||||
|
@ -1314,16 +1314,14 @@ enum reg_class
|
||||
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
|
||||
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
|
||||
|
||||
/* If defined, gives a class of registers that cannot be used as the
|
||||
operand of a SUBREG that changes the mode of the object illegally. */
|
||||
|
||||
#define CLASS_CANNOT_CHANGE_MODE FLOAT_REGS
|
||||
/* Return a class of registers that cannot change FROM mode to TO mode. */
|
||||
|
||||
/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
|
||||
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
|
||||
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) ? FLOAT_REGS \
|
||||
: (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1 ? GENERAL_REGS \
|
||||
: NO_REGS)
|
||||
|
||||
#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
|
||||
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
|
||||
|
||||
/* Stack layout; function entry, exit and calling. */
|
||||
|
||||
/* Enumeration to give which calling sequence to use. */
|
||||
|
@ -330,10 +330,8 @@ do \
|
||||
/* If a 4-byte value is loaded into a FPR, it is placed into the
|
||||
*upper* half of the register, not the lower. Therefore, we
|
||||
cannot use SUBREGs to switch between modes in FP registers. */
|
||||
#define CLASS_CANNOT_CHANGE_MODE FP_REGS
|
||||
#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
|
||||
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
|
||||
|
||||
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
|
||||
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) ? FP_REGS : NO_REGS)
|
||||
|
||||
/* Register classes. */
|
||||
|
||||
|
@ -126,6 +126,8 @@ extern int sh_pr_n_sets PARAMS ((void));
|
||||
extern int sh_hard_regno_rename_ok PARAMS ((unsigned int, unsigned int));
|
||||
extern int sh_cfun_interrupt_handler_p PARAMS ((void));
|
||||
extern void sh_initialize_trampoline PARAMS ((rtx, rtx, rtx));
|
||||
extern enum reg_class sh_cannot_change_mode_class
|
||||
PARAMS ((enum machine_mode, enum machine_mode));
|
||||
|
||||
#ifdef HARD_CONST
|
||||
extern void fpscr_set_from_mem PARAMS ((int, HARD_REG_SET));
|
||||
|
@ -7733,4 +7733,26 @@ sh_expand_binop_v2sf (code, op0, op1, op2)
|
||||
emit_insn ((*fn) (op0, op1, op2, op, sel1, sel1, sel1));
|
||||
}
|
||||
|
||||
/* Return the class of registers for which a mode change from FROM to TO
|
||||
is invalid. */
|
||||
enum reg_class
|
||||
sh_cannot_change_mode_class (from, to)
|
||||
enum machine_mode from, to;
|
||||
{
|
||||
if (GET_MODE_SIZE (from) != GET_MODE_SIZE (to))
|
||||
{
|
||||
if (TARGET_LITTLE_ENDIAN)
|
||||
{
|
||||
if (GET_MODE_SIZE (to) < 8 || GET_MODE_SIZE (from) < 8)
|
||||
return DF_REGS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GET_MODE_SIZE (from) < 8)
|
||||
return DF_HI_REGS;
|
||||
}
|
||||
}
|
||||
return NO_REGS;
|
||||
}
|
||||
|
||||
#include "gt-sh.h"
|
||||
|
@ -1372,14 +1372,8 @@ extern const enum reg_class reg_class_from_letter[];
|
||||
/* ??? We need to renumber the internal numbers for the frnn registers
|
||||
when in little endian in order to allow mode size changes. */
|
||||
|
||||
#define CLASS_CANNOT_CHANGE_MODE (TARGET_LITTLE_ENDIAN ? DF_REGS : DF_HI_REGS)
|
||||
|
||||
/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE. */
|
||||
|
||||
#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
|
||||
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
|
||||
&& ((TARGET_LITTLE_ENDIAN && GET_MODE_SIZE (TO) < 8) \
|
||||
|| GET_MODE_SIZE (FROM) < 8))
|
||||
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
|
||||
sh_cannot_change_mode_class (FROM, TO)
|
||||
|
||||
/* Stack layout; function entry, exit and calling. */
|
||||
|
||||
|
@ -2561,25 +2561,22 @@ should be the maximum value of @code{HARD_REGNO_NREGS (@var{regno},
|
||||
This macro helps control the handling of multiple-word values
|
||||
in the reload pass.
|
||||
|
||||
@item CLASS_CANNOT_CHANGE_MODE
|
||||
If defined, a C expression for a class that contains registers for
|
||||
which the compiler may not change modes arbitrarily.
|
||||
|
||||
@item CLASS_CANNOT_CHANGE_MODE_P(@var{from}, @var{to})
|
||||
A C expression that is true if, for a register in
|
||||
@code{CLASS_CANNOT_CHANGE_MODE}, the requested mode punning is invalid.
|
||||
@item CANNOT_CHANGE_MODE_CLASS(@var{from}, @var{to})
|
||||
If defined, a C expression that returns a register class for which
|
||||
a change from mode @var{from} to mode @var{to} is invalid, otherwise the
|
||||
macro returns @code{NO_REGS}.
|
||||
|
||||
For the example, loading 32-bit integer or floating-point objects into
|
||||
floating-point registers on the Alpha extends them to 64 bits.
|
||||
Therefore loading a 64-bit object and then storing it as a 32-bit object
|
||||
does not store the low-order 32 bits, as would be the case for a normal
|
||||
register. Therefore, @file{alpha.h} defines @code{CLASS_CANNOT_CHANGE_MODE}
|
||||
as @code{FLOAT_REGS} and @code{CLASS_CANNOT_CHANGE_MODE_P} restricts
|
||||
mode changes to same-size modes.
|
||||
register. Therefore, @file{alpha.h} defines @code{CANNOT_CHANGE_MODE_CLASS}
|
||||
as below:
|
||||
|
||||
Compare this to IA-64, which extends floating-point values to 82-bits,
|
||||
and stores 64-bit integers in a different format than 64-bit doubles.
|
||||
Therefore @code{CLASS_CANNOT_CHANGE_MODE_P} is always true.
|
||||
@example
|
||||
#define CANNOT_CHANGE_MODE_CLASS \
|
||||
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) ? FLOAT_REGS : NO_REGS)
|
||||
@end example
|
||||
@end table
|
||||
|
||||
Three other special macros describe which operands fit which constraint
|
||||
|
27
gcc/flow.c
27
gcc/flow.c
@ -414,8 +414,8 @@ life_analysis (f, file, flags)
|
||||
FILE *file;
|
||||
int flags;
|
||||
{
|
||||
#ifdef ELIMINABLE_REGS
|
||||
int i;
|
||||
#ifdef ELIMINABLE_REGS
|
||||
static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
|
||||
#endif
|
||||
|
||||
@ -431,6 +431,13 @@ life_analysis (f, file, flags)
|
||||
SET_HARD_REG_BIT (elim_reg_set, FRAME_POINTER_REGNUM);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
if (flags & PROP_REG_INFO)
|
||||
for (i=0; i < NUM_MACHINE_MODES; ++i)
|
||||
INIT_REG_SET (&subregs_of_mode[i]);
|
||||
#endif
|
||||
|
||||
if (! optimize)
|
||||
flags &= ~(PROP_LOG_LINKS | PROP_AUTOINC | PROP_ALLOW_CFG_CHANGES);
|
||||
|
||||
@ -3813,12 +3820,11 @@ mark_used_regs (pbi, x, cond, insn)
|
||||
break;
|
||||
|
||||
case SUBREG:
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
if (GET_CODE (SUBREG_REG (x)) == REG
|
||||
&& REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER
|
||||
&& CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (x),
|
||||
GET_MODE (SUBREG_REG (x))))
|
||||
REG_CHANGES_MODE (REGNO (SUBREG_REG (x))) = 1;
|
||||
&& REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
|
||||
SET_REGNO_REG_SET (&subregs_of_mode[GET_MODE (x)],
|
||||
REGNO (SUBREG_REG (x)));
|
||||
#endif
|
||||
|
||||
/* While we're here, optimize this case. */
|
||||
@ -3862,13 +3868,12 @@ mark_used_regs (pbi, x, cond, insn)
|
||||
|| GET_CODE (testreg) == SIGN_EXTRACT
|
||||
|| GET_CODE (testreg) == SUBREG)
|
||||
{
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
if (GET_CODE (testreg) == SUBREG
|
||||
&& GET_CODE (SUBREG_REG (testreg)) == REG
|
||||
&& REGNO (SUBREG_REG (testreg)) >= FIRST_PSEUDO_REGISTER
|
||||
&& CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (testreg)),
|
||||
GET_MODE (testreg)))
|
||||
REG_CHANGES_MODE (REGNO (SUBREG_REG (testreg))) = 1;
|
||||
&& REGNO (SUBREG_REG (testreg)) >= FIRST_PSEUDO_REGISTER)
|
||||
SET_REGNO_REG_SET (&subregs_of_mode[GET_MODE (testreg)],
|
||||
REGNO (SUBREG_REG (testreg)));
|
||||
#endif
|
||||
|
||||
/* Modifying a single register in an alternate mode
|
||||
|
19
gcc/global.c
19
gcc/global.c
@ -974,10 +974,7 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying)
|
||||
int retrying;
|
||||
{
|
||||
int i, best_reg, pass;
|
||||
#ifdef HARD_REG_SET
|
||||
register /* Declare it register if it's a scalar. */
|
||||
#endif
|
||||
HARD_REG_SET used, used1, used2;
|
||||
HARD_REG_SET used, used1, used2;
|
||||
|
||||
enum reg_class class = (alt_regs_p
|
||||
? reg_alternate_class (allocno[num].reg)
|
||||
@ -1001,10 +998,8 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying)
|
||||
|
||||
IOR_HARD_REG_SET (used1, allocno[num].hard_reg_conflicts);
|
||||
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
if (REG_CHANGES_MODE (allocno[num].reg))
|
||||
IOR_HARD_REG_SET (used1,
|
||||
reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE]);
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
cannot_change_mode_set_regs (&used1, mode, allocno[num].reg);
|
||||
#endif
|
||||
|
||||
/* Try each hard reg to see if it fits. Do this in two passes.
|
||||
@ -1200,11 +1195,9 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying)
|
||||
&& (allocno[num].calls_crossed == 0
|
||||
|| accept_call_clobbered
|
||||
|| ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
&& ! (REG_CHANGES_MODE (allocno[num].reg)
|
||||
&& (TEST_HARD_REG_BIT
|
||||
(reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
|
||||
regno)))
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
&& ! invalid_mode_change_p (regno, REGNO_REG_CLASS (regno),
|
||||
mode)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
|
@ -488,4 +488,11 @@ extern int n_non_fixed_regs;
|
||||
|
||||
extern const char * reg_names[FIRST_PSEUDO_REGISTER];
|
||||
|
||||
/* Given a hard REGN a FROM mode and a TO mode, return non-zero if
|
||||
REGN cannot change modes between the specified modes. */
|
||||
#define REG_CANNOT_CHANGE_MODE_P(REGN, FROM, TO) \
|
||||
(TEST_HARD_REG_BIT \
|
||||
(reg_class_contents[(int) CANNOT_CHANGE_MODE_CLASS (FROM, TO)], \
|
||||
REGN))
|
||||
|
||||
#endif /* ! GCC_HARD_REG_SET_H */
|
||||
|
@ -61,10 +61,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "rtl.h"
|
||||
#include "tm_p.h"
|
||||
#include "flags.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "basic-block.h"
|
||||
#include "regs.h"
|
||||
#include "function.h"
|
||||
@ -144,12 +144,6 @@ struct qty
|
||||
or -1 if none was found. */
|
||||
|
||||
short phys_reg;
|
||||
|
||||
/* Nonzero if this quantity has been used in a SUBREG in some
|
||||
way that is illegal. */
|
||||
|
||||
char changes_mode;
|
||||
|
||||
};
|
||||
|
||||
static struct qty *qty;
|
||||
@ -328,7 +322,6 @@ alloc_qty (regno, mode, size, birth)
|
||||
qty[qtyno].alternate_class = reg_alternate_class (regno);
|
||||
qty[qtyno].n_refs = REG_N_REFS (regno);
|
||||
qty[qtyno].freq = REG_FREQ (regno);
|
||||
qty[qtyno].changes_mode = REG_CHANGES_MODE (regno);
|
||||
}
|
||||
|
||||
/* Main entry point of this file. */
|
||||
@ -2026,9 +2019,6 @@ update_qty_class (qtyno, reg)
|
||||
rclass = reg_alternate_class (reg);
|
||||
if (reg_class_subset_p (rclass, qty[qtyno].alternate_class))
|
||||
qty[qtyno].alternate_class = rclass;
|
||||
|
||||
if (REG_CHANGES_MODE (reg))
|
||||
qty[qtyno].changes_mode = 1;
|
||||
}
|
||||
|
||||
/* Handle something which alters the value of an rtx REG.
|
||||
@ -2182,11 +2172,7 @@ find_free_reg (class, mode, qtyno, accept_call_clobbered, just_try_suggested,
|
||||
int born_index, dead_index;
|
||||
{
|
||||
int i, ins;
|
||||
#ifdef HARD_REG_SET
|
||||
/* Declare it register if it's a scalar. */
|
||||
register
|
||||
#endif
|
||||
HARD_REG_SET used, first_used;
|
||||
HARD_REG_SET first_used, used;
|
||||
#ifdef ELIMINABLE_REGS
|
||||
static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
|
||||
#endif
|
||||
@ -2234,10 +2220,8 @@ find_free_reg (class, mode, qtyno, accept_call_clobbered, just_try_suggested,
|
||||
SET_HARD_REG_BIT (used, FRAME_POINTER_REGNUM);
|
||||
#endif
|
||||
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
if (qty[qtyno].changes_mode)
|
||||
IOR_HARD_REG_SET (used,
|
||||
reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE]);
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
cannot_change_mode_set_regs (&used, mode, qty[qtyno].first_reg);
|
||||
#endif
|
||||
|
||||
/* Normally, the registers that can be used for the first register in
|
||||
|
@ -1083,13 +1083,10 @@ register_operand (op, mode)
|
||||
if (! reload_completed && GET_CODE (sub) == MEM)
|
||||
return general_operand (op, mode);
|
||||
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
if (GET_CODE (sub) == REG
|
||||
&& REGNO (sub) < FIRST_PSEUDO_REGISTER
|
||||
&& (TEST_HARD_REG_BIT
|
||||
(reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
|
||||
REGNO (sub)))
|
||||
&& CLASS_CANNOT_CHANGE_MODE_P (mode, GET_MODE (sub))
|
||||
&& REG_CANNOT_CHANGE_MODE_P (REGNO (sub), mode, GET_MODE (sub))
|
||||
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_INT
|
||||
&& GET_MODE_CLASS (GET_MODE (sub)) != MODE_COMPLEX_FLOAT)
|
||||
return 0;
|
||||
|
114
gcc/regclass.c
114
gcc/regclass.c
@ -26,10 +26,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "rtl.h"
|
||||
#include "expr.h"
|
||||
#include "tm_p.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "flags.h"
|
||||
#include "basic-block.h"
|
||||
#include "regs.h"
|
||||
@ -227,20 +227,11 @@ static char *in_inc_dec;
|
||||
|
||||
#endif /* FORBIDDEN_INC_DEC_CLASSES */
|
||||
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
|
||||
/* These are the classes containing only registers that can be used in
|
||||
a SUBREG expression that changes the mode of the register in some
|
||||
way that is illegal. */
|
||||
|
||||
static int class_can_change_mode[N_REG_CLASSES];
|
||||
|
||||
/* Registers, including pseudos, which change modes in some way that
|
||||
is illegal. */
|
||||
|
||||
static regset reg_changes_mode;
|
||||
|
||||
#endif /* CLASS_CANNOT_CHANGE_MODE */
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
/* All registers that have been subreged. Indexed by mode, where each
|
||||
entry is a regset of registers. */
|
||||
regset_head subregs_of_mode [NUM_MACHINE_MODES];
|
||||
#endif
|
||||
|
||||
/* Sample MEM values for use by memory_move_secondary_cost. */
|
||||
|
||||
@ -549,22 +540,6 @@ init_reg_sets_1 ()
|
||||
may_move_out_cost[m][i][j] = 65536;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
{
|
||||
HARD_REG_SET c;
|
||||
COMPL_HARD_REG_SET (c, reg_class_contents[CLASS_CANNOT_CHANGE_MODE]);
|
||||
|
||||
for (i = 0; i < N_REG_CLASSES; i++)
|
||||
{
|
||||
GO_IF_HARD_REG_SUBSET (reg_class_contents[i], c, ok_class);
|
||||
class_can_change_mode [i] = 0;
|
||||
continue;
|
||||
ok_class:
|
||||
class_can_change_mode [i] = 1;
|
||||
}
|
||||
}
|
||||
#endif /* CLASS_CANNOT_CHANGE_MODE */
|
||||
}
|
||||
|
||||
/* Compute the table of register modes.
|
||||
@ -952,9 +927,9 @@ dump_regclass (dump)
|
||||
&& (!in_inc_dec[i]
|
||||
|| !forbidden_inc_dec_class[(enum reg_class) class])
|
||||
#endif
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
&& (!REGNO_REG_SET_P (reg_changes_mode, i)
|
||||
|| class_can_change_mode [(enum reg_class) class])
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
&& ! invalid_mode_change_p (i, (enum reg_class) class,
|
||||
PSEUDO_REGNO_MODE (i))
|
||||
#endif
|
||||
)
|
||||
fprintf (dump, " %s:%i", reg_class_names[class],
|
||||
@ -994,15 +969,7 @@ record_operand_costs (insn, op_costs, reg_pref)
|
||||
op_costs[i] = init_cost;
|
||||
|
||||
if (GET_CODE (recog_data.operand[i]) == SUBREG)
|
||||
{
|
||||
rtx inner = SUBREG_REG (recog_data.operand[i]);
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
if (GET_CODE (inner) == REG
|
||||
&& CLASS_CANNOT_CHANGE_MODE_P (modes[i], GET_MODE (inner)))
|
||||
SET_REGNO_REG_SET (reg_changes_mode, REGNO (inner));
|
||||
#endif
|
||||
recog_data.operand[i] = inner;
|
||||
}
|
||||
recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
|
||||
|
||||
if (GET_CODE (recog_data.operand[i]) == MEM)
|
||||
record_address_regs (XEXP (recog_data.operand[i], 0),
|
||||
@ -1193,10 +1160,6 @@ regclass (f, nregs, dump)
|
||||
|
||||
costs = (struct costs *) xmalloc (nregs * sizeof (struct costs));
|
||||
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
reg_changes_mode = BITMAP_XMALLOC ();
|
||||
#endif
|
||||
|
||||
#ifdef FORBIDDEN_INC_DEC_CLASSES
|
||||
|
||||
in_inc_dec = (char *) xmalloc (nregs);
|
||||
@ -1329,9 +1292,9 @@ regclass (f, nregs, dump)
|
||||
#ifdef FORBIDDEN_INC_DEC_CLASSES
|
||||
|| (in_inc_dec[i] && forbidden_inc_dec_class[class])
|
||||
#endif
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
|| (REGNO_REG_SET_P (reg_changes_mode, i)
|
||||
&& ! class_can_change_mode [class])
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
|| invalid_mode_change_p (i, (enum reg_class) class,
|
||||
PSEUDO_REGNO_MODE (i))
|
||||
#endif
|
||||
)
|
||||
;
|
||||
@ -1359,9 +1322,9 @@ regclass (f, nregs, dump)
|
||||
#ifdef FORBIDDEN_INC_DEC_CLASSES
|
||||
&& ! (in_inc_dec[i] && forbidden_inc_dec_class[class])
|
||||
#endif
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
&& ! (REGNO_REG_SET_P (reg_changes_mode, i)
|
||||
&& ! class_can_change_mode [class])
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
&& ! invalid_mode_change_p (i, (enum reg_class) class,
|
||||
PSEUDO_REGNO_MODE (i))
|
||||
#endif
|
||||
)
|
||||
alt = reg_class_subunion[(int) alt][class];
|
||||
@ -1394,9 +1357,6 @@ regclass (f, nregs, dump)
|
||||
|
||||
#ifdef FORBIDDEN_INC_DEC_CLASSES
|
||||
free (in_inc_dec);
|
||||
#endif
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
BITMAP_XFREE (reg_changes_mode);
|
||||
#endif
|
||||
free (costs);
|
||||
}
|
||||
@ -2643,4 +2603,46 @@ regset_release_memory ()
|
||||
bitmap_release_memory ();
|
||||
}
|
||||
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
/* Set bits in *USED which correspond to registers which can't change
|
||||
their mode from FROM to any mode in which REGNO was encountered. */
|
||||
|
||||
void
|
||||
cannot_change_mode_set_regs (used, from, regno)
|
||||
HARD_REG_SET *used;
|
||||
enum machine_mode from;
|
||||
unsigned int regno;
|
||||
{
|
||||
enum machine_mode to;
|
||||
enum reg_class class;
|
||||
|
||||
for (to = VOIDmode; to < MAX_MACHINE_MODE; ++to)
|
||||
if (REGNO_REG_SET_P (&subregs_of_mode[to], regno))
|
||||
{
|
||||
class = CANNOT_CHANGE_MODE_CLASS (from, to);
|
||||
if (class != NO_REGS)
|
||||
IOR_HARD_REG_SET (*used, reg_class_contents [(int) class]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return 1 if REGNO has had an invalid mode change in CLASS from FROM
|
||||
mode. */
|
||||
|
||||
bool
|
||||
invalid_mode_change_p (regno, class, from_mode)
|
||||
unsigned int regno;
|
||||
enum reg_class class;
|
||||
enum machine_mode from_mode;
|
||||
{
|
||||
enum machine_mode to_mode;
|
||||
|
||||
for (to_mode = 0; to_mode < NUM_MACHINE_MODES; ++to_mode)
|
||||
if (REGNO_REG_SET_P (&subregs_of_mode[(int) to_mode], regno)
|
||||
&& reg_classes_intersect_p
|
||||
(class, CANNOT_CHANGE_MODE_CLASS (from_mode, to_mode)))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
#endif /* CANNOT_CHANGE_MODE_CLASS */
|
||||
|
||||
#include "gt-regclass.h"
|
||||
|
@ -1313,10 +1313,8 @@ mode_change_ok (orig_mode, new_mode, regno)
|
||||
if (GET_MODE_SIZE (orig_mode) < GET_MODE_SIZE (new_mode))
|
||||
return false;
|
||||
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
if (TEST_HARD_REG_BIT (reg_class_contents[CLASS_CANNOT_CHANGE_MODE], regno)
|
||||
&& CLASS_CANNOT_CHANGE_MODE_P (orig_mode, new_mode))
|
||||
return false;
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
return !REG_CANNOT_CHANGE_MODE_P (regno, orig_mode, new_mode);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
11
gcc/regs.h
11
gcc/regs.h
@ -21,6 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
|
||||
|
||||
#include "varray.h"
|
||||
#include "hard-reg-set.h"
|
||||
#include "basic-block.h"
|
||||
|
||||
#define REG_BYTES(R) mode_size[(int) GET_MODE (R)]
|
||||
|
||||
@ -64,6 +66,8 @@ typedef struct reg_info_def
|
||||
|
||||
extern varray_type reg_n_info;
|
||||
|
||||
extern regset_head subregs_of_mode [NUM_MACHINE_MODES];
|
||||
|
||||
/* Indexed by n, gives number of times (REG n) is used or set. */
|
||||
|
||||
#define REG_N_REFS(N) (VARRAY_REG (reg_n_info, N)->refs)
|
||||
@ -104,13 +108,6 @@ extern varray_type reg_n_info;
|
||||
|
||||
#define REG_N_DEATHS(N) (VARRAY_REG (reg_n_info, N)->deaths)
|
||||
|
||||
/* Indexed by N; says whether a pseudo register N was ever used
|
||||
within a SUBREG that changes the mode of the reg in some way
|
||||
that is illegal for a given class (usually floating-point)
|
||||
of registers. */
|
||||
|
||||
#define REG_CHANGES_MODE(N) (VARRAY_REG (reg_n_info, N)->changes_mode)
|
||||
|
||||
/* Get the number of consecutive words required to hold pseudo-reg N. */
|
||||
|
||||
#define PSEUDO_REGNO_SIZE(N) \
|
||||
|
34
gcc/reload.c
34
gcc/reload.c
@ -967,9 +967,10 @@ push_reload (in, out, inloc, outloc, class,
|
||||
|
||||
if (in != 0 && GET_CODE (in) == SUBREG
|
||||
&& (subreg_lowpart_p (in) || strict_low)
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
&& (class != CLASS_CANNOT_CHANGE_MODE
|
||||
|| ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (in)), inmode))
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
&& !reg_classes_intersect_p
|
||||
(class, CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (in)),
|
||||
inmode))
|
||||
#endif
|
||||
&& (CONSTANT_P (SUBREG_REG (in))
|
||||
|| GET_CODE (SUBREG_REG (in)) == PLUS
|
||||
@ -1016,14 +1017,11 @@ push_reload (in, out, inloc, outloc, class,
|
||||
SUBREG_REG (in))
|
||||
== NO_REGS))
|
||||
#endif
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
|| (GET_CODE (SUBREG_REG (in)) == REG
|
||||
&& REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
|
||||
&& (TEST_HARD_REG_BIT
|
||||
(reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
|
||||
REGNO (SUBREG_REG (in))))
|
||||
&& CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (in)),
|
||||
inmode))
|
||||
&& REG_CANNOT_CHANGE_MODE_P
|
||||
(REGNO (SUBREG_REG (in)), GET_MODE (SUBREG_REG (in)), inmode))
|
||||
#endif
|
||||
))
|
||||
{
|
||||
@ -1081,10 +1079,10 @@ push_reload (in, out, inloc, outloc, class,
|
||||
and in that case the constraint should label it input-output.) */
|
||||
if (out != 0 && GET_CODE (out) == SUBREG
|
||||
&& (subreg_lowpart_p (out) || strict_low)
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
&& (class != CLASS_CANNOT_CHANGE_MODE
|
||||
|| ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (out)),
|
||||
outmode))
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
&& !reg_classes_intersect_p
|
||||
(class, CANNOT_CHANGE_MODE_CLASS (GET_MODE (SUBREG_REG (out)),
|
||||
outmode))
|
||||
#endif
|
||||
&& (CONSTANT_P (SUBREG_REG (out))
|
||||
|| strict_low
|
||||
@ -1118,14 +1116,12 @@ push_reload (in, out, inloc, outloc, class,
|
||||
SUBREG_REG (out))
|
||||
== NO_REGS))
|
||||
#endif
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
|| (GET_CODE (SUBREG_REG (out)) == REG
|
||||
&& REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
|
||||
&& (TEST_HARD_REG_BIT
|
||||
(reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
|
||||
REGNO (SUBREG_REG (out))))
|
||||
&& CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (out)),
|
||||
outmode))
|
||||
&& REG_CANNOT_CHANGE_MODE_P (REGNO (SUBREG_REG (out)),
|
||||
GET_MODE (SUBREG_REG (out)),
|
||||
outmode))
|
||||
#endif
|
||||
))
|
||||
{
|
||||
|
@ -5490,16 +5490,15 @@ choose_reload_regs (chain)
|
||||
GET_MODE_CLASS (mode));
|
||||
|
||||
if (
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
(TEST_HARD_REG_BIT
|
||||
(reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE], i)
|
||||
? ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (last_reg),
|
||||
need_mode)
|
||||
: (GET_MODE_SIZE (GET_MODE (last_reg))
|
||||
>= GET_MODE_SIZE (need_mode)))
|
||||
#else
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
(!REG_CANNOT_CHANGE_MODE_P (i, GET_MODE (last_reg),
|
||||
need_mode)
|
||||
||
|
||||
#endif
|
||||
(GET_MODE_SIZE (GET_MODE (last_reg))
|
||||
>= GET_MODE_SIZE (need_mode))
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
)
|
||||
#endif
|
||||
&& reg_reloaded_contents[i] == regno
|
||||
&& TEST_HARD_REG_BIT (reg_reloaded_valid, i)
|
||||
|
10
gcc/rtl.h
10
gcc/rtl.h
@ -2092,6 +2092,7 @@ extern int global_alloc PARAMS ((FILE *));
|
||||
extern void dump_global_regs PARAMS ((FILE *));
|
||||
#endif
|
||||
#ifdef HARD_CONST
|
||||
/* Yes, this ifdef is silly, but HARD_REG_SET is not always defined. */
|
||||
extern void retry_global_alloc PARAMS ((int, HARD_REG_SET));
|
||||
#endif
|
||||
extern void build_insn_chain PARAMS ((rtx));
|
||||
@ -2109,6 +2110,14 @@ extern void regclass PARAMS ((rtx, int, FILE *));
|
||||
extern void reg_scan PARAMS ((rtx, unsigned int, int));
|
||||
extern void reg_scan_update PARAMS ((rtx, rtx, unsigned int));
|
||||
extern void fix_register PARAMS ((const char *, int, int));
|
||||
#ifdef HARD_CONST
|
||||
extern void cannot_change_mode_set_regs PARAMS ((HARD_REG_SET *,
|
||||
enum machine_mode,
|
||||
unsigned int));
|
||||
#endif
|
||||
extern bool invalid_mode_change_p PARAMS ((unsigned int,
|
||||
enum reg_class,
|
||||
enum machine_mode));
|
||||
|
||||
extern int delete_null_pointer_checks PARAMS ((rtx));
|
||||
|
||||
@ -2269,4 +2278,5 @@ extern void invert_br_probabilities PARAMS ((rtx));
|
||||
extern bool expensive_function_p PARAMS ((int));
|
||||
/* In tracer.c */
|
||||
extern void tracer PARAMS ((void));
|
||||
|
||||
#endif /* ! GCC_RTL_H */
|
||||
|
@ -2586,15 +2586,12 @@ simplify_subreg (outermode, op, innermode, byte)
|
||||
if (REG_P (op)
|
||||
&& (! REG_FUNCTION_VALUE_P (op)
|
||||
|| ! rtx_equal_function_value_matters)
|
||||
#ifdef CLASS_CANNOT_CHANGE_MODE
|
||||
&& ! (CLASS_CANNOT_CHANGE_MODE_P (outermode, innermode)
|
||||
&& GET_MODE_CLASS (innermode) != MODE_COMPLEX_INT
|
||||
&& GET_MODE_CLASS (innermode) != MODE_COMPLEX_FLOAT
|
||||
&& (TEST_HARD_REG_BIT
|
||||
(reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
|
||||
REGNO (op))))
|
||||
#endif
|
||||
&& REGNO (op) < FIRST_PSEUDO_REGISTER
|
||||
#ifdef CANNOT_CHANGE_MODE_CLASS
|
||||
&& ! (REG_CANNOT_CHANGE_MODE_P (REGNO (op), outermode, innermode)
|
||||
&& GET_MODE_CLASS (innermode) != MODE_COMPLEX_INT
|
||||
&& GET_MODE_CLASS (innermode) != MODE_COMPLEX_FLOAT)
|
||||
#endif
|
||||
&& ((reload_completed && !frame_pointer_needed)
|
||||
|| (REGNO (op) != FRAME_POINTER_REGNUM
|
||||
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
|
||||
|
Loading…
Reference in New Issue
Block a user