Commit ffa2596e by Richard Sandiford Committed by Richard Sandiford

re PR target/28181 (ICE in reload_cse_simplify_operands, at postreload.c:393 on m68k)

gcc/
	PR target/28181
	* config/m68k/m68k-protos.h (m68k_secondary_reload_class): Declare.
	(m68k_preferred_reload_class): Likewise.
	* config/m68k/m68k.h (HARD_REGNO_MODE_OK): Remove duplicated comment.
	(SECONDARY_RELOAD_CLASS): Define.
	(PREFERRED_RELOAD_CLASS): Use m68k_preferred_reload_class.
	(LIMIT_RELOAD_CLASS): Delete.
	* config/m68k/m68k.c (m68k_regno_mode_ok): Don't prevent address
	registers from storing bytes.
	(m68k_secondary_reload_class): New function.
	(m68k_preferred_reload_class): Likewise.

gcc/testsuite/
	* gcc.c-torture/compile/m68k-byte-addr.c: New test.

From-SVN: r122609
parent 4f44ecc0
2007-03-06 Richard Sandiford <richard@codesourcery.com> 2007-03-06 Richard Sandiford <richard@codesourcery.com>
PR target/28181
* config/m68k/m68k-protos.h (m68k_secondary_reload_class): Declare.
(m68k_preferred_reload_class): Likewise.
* config/m68k/m68k.h (HARD_REGNO_MODE_OK): Remove duplicated comment.
(SECONDARY_RELOAD_CLASS): Define.
(PREFERRED_RELOAD_CLASS): Use m68k_preferred_reload_class.
(LIMIT_RELOAD_CLASS): Delete.
* config/m68k/m68k.c (m68k_regno_mode_ok): Don't prevent address
registers from storing bytes.
(m68k_secondary_reload_class): New function.
(m68k_preferred_reload_class): Likewise.
2007-03-06 Richard Sandiford <richard@codesourcery.com>
* config/m68k/m68k.c (m68k_save_reg): Remove special case for * config/m68k/m68k.c (m68k_save_reg): Remove special case for
leaf functions. leaf functions.
(m68k_expand_prologue): Likewise. (m68k_expand_prologue): Likewise.
......
...@@ -69,6 +69,9 @@ extern const char *m68k_output_movem (rtx *, rtx, HOST_WIDE_INT, bool); ...@@ -69,6 +69,9 @@ extern const char *m68k_output_movem (rtx *, rtx, HOST_WIDE_INT, bool);
#endif /* RTX_CODE */ #endif /* RTX_CODE */
extern bool m68k_regno_mode_ok (int, enum machine_mode); extern bool m68k_regno_mode_ok (int, enum machine_mode);
extern enum reg_class m68k_secondary_reload_class (enum reg_class,
enum machine_mode, rtx);
extern enum reg_class m68k_preferred_reload_class (rtx, enum reg_class);
extern int flags_in_68881 (void); extern int flags_in_68881 (void);
extern void m68k_expand_prologue (void); extern void m68k_expand_prologue (void);
extern bool m68k_use_return_insn (void); extern bool m68k_use_return_insn (void);
......
...@@ -4153,9 +4153,10 @@ m68k_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED, ...@@ -4153,9 +4153,10 @@ m68k_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
return 1; return 1;
} }
/* Value is true if hard register REGNO can hold a value of machine-mode MODE. /* Value is true if hard register REGNO can hold a value of machine-mode
On the 68000, the cpu registers can hold any mode except bytes in address MODE. On the 68000, we let the cpu registers can hold any mode, but
registers, but the 68881 registers can hold only SFmode or DFmode. */ restrict the 68881 registers to floating-point modes. */
bool bool
m68k_regno_mode_ok (int regno, enum machine_mode mode) m68k_regno_mode_ok (int regno, enum machine_mode mode)
{ {
...@@ -4167,10 +4168,6 @@ m68k_regno_mode_ok (int regno, enum machine_mode mode) ...@@ -4167,10 +4168,6 @@ m68k_regno_mode_ok (int regno, enum machine_mode mode)
} }
else if (ADDRESS_REGNO_P (regno)) else if (ADDRESS_REGNO_P (regno))
{ {
/* Address Registers, can't hold bytes, can hold aggregate if
fits in. */
if (GET_MODE_SIZE (mode) == 1)
return false;
if (regno + GET_MODE_SIZE (mode) / 4 <= 16) if (regno + GET_MODE_SIZE (mode) / 4 <= 16)
return true; return true;
} }
...@@ -4186,6 +4183,66 @@ m68k_regno_mode_ok (int regno, enum machine_mode mode) ...@@ -4186,6 +4183,66 @@ m68k_regno_mode_ok (int regno, enum machine_mode mode)
return false; return false;
} }
/* Implement SECONDARY_RELOAD_CLASS. */
enum reg_class
m68k_secondary_reload_class (enum reg_class rclass,
enum machine_mode mode, rtx x)
{
int regno;
regno = true_regnum (x);
/* If one operand of a movqi is an address register, the other
operand must be a general register or constant. Other types
of operand must be reloaded through a data register. */
if (GET_MODE_SIZE (mode) == 1
&& reg_classes_intersect_p (rclass, ADDR_REGS)
&& !(INT_REGNO_P (regno) || CONSTANT_P (x)))
return DATA_REGS;
/* PC-relative addresses must be loaded into an address register first. */
if (TARGET_PCREL
&& !reg_class_subset_p (rclass, ADDR_REGS)
&& symbolic_operand (x, VOIDmode))
return ADDR_REGS;
return NO_REGS;
}
/* Implement PREFERRED_RELOAD_CLASS. */
enum reg_class
m68k_preferred_reload_class (rtx x, enum reg_class rclass)
{
enum reg_class secondary_class;
/* If RCLASS might need a secondary reload, try restricting it to
a class that doesn't. */
secondary_class = m68k_secondary_reload_class (rclass, GET_MODE (x), x);
if (secondary_class != NO_REGS
&& reg_class_subset_p (secondary_class, rclass))
return secondary_class;
/* Prefer to use moveq for in-range constants. */
if (GET_CODE (x) == CONST_INT
&& reg_class_subset_p (DATA_REGS, rclass)
&& IN_RANGE (INTVAL (x), -0x80, 0x7f))
return DATA_REGS;
/* ??? Do we really need this now? */
if (GET_CODE (x) == CONST_DOUBLE
&& GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
{
if (TARGET_HARD_FLOAT && reg_class_subset_p (FP_REGS, rclass))
return FP_REGS;
return NO_REGS;
}
return rclass;
}
/* Return floating point values in a 68881 register. This makes 68881 code /* Return floating point values in a 68881 register. This makes 68881 code
a little bit faster. It also makes -msoft-float code incompatible with a little bit faster. It also makes -msoft-float code incompatible with
hard-float code, so people have to be careful not to mix the two. hard-float code, so people have to be careful not to mix the two.
......
...@@ -401,13 +401,12 @@ Boston, MA 02110-1301, USA. */ ...@@ -401,13 +401,12 @@ Boston, MA 02110-1301, USA. */
#define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \ #define HARD_REGNO_RENAME_OK(OLD_REG, NEW_REG) \
m68k_hard_regno_rename_ok (OLD_REG, NEW_REG) m68k_hard_regno_rename_ok (OLD_REG, NEW_REG)
/* Value is true if hard register REGNO can hold a value of machine-mode MODE.
On the 68000, the cpu registers can hold any mode except bytes in
address registers, the 68881 registers can hold only SFmode or DFmode. */
#define HARD_REGNO_MODE_OK(REGNO, MODE) \ #define HARD_REGNO_MODE_OK(REGNO, MODE) \
m68k_regno_mode_ok ((REGNO), (MODE)) m68k_regno_mode_ok ((REGNO), (MODE))
#define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) \
m68k_secondary_reload_class (CLASS, MODE, X)
#define MODES_TIEABLE_P(MODE1, MODE2) \ #define MODES_TIEABLE_P(MODE1, MODE2) \
(! TARGET_HARD_FLOAT \ (! TARGET_HARD_FLOAT \
|| ((GET_MODE_CLASS (MODE1) == MODE_FLOAT \ || ((GET_MODE_CLASS (MODE1) == MODE_FLOAT \
...@@ -544,34 +543,8 @@ extern enum reg_class regno_reg_class[]; ...@@ -544,34 +543,8 @@ extern enum reg_class regno_reg_class[];
? const_call_operand (OP, VOIDmode) \ ? const_call_operand (OP, VOIDmode) \
: 0) : 0)
/* On the m68k, use a data reg if possible when the #define PREFERRED_RELOAD_CLASS(X,CLASS) \
value is a constant in the range where moveq could be used m68k_preferred_reload_class (X, CLASS)
and we ensure that QImodes are reloaded into data regs. */
#define PREFERRED_RELOAD_CLASS(X,CLASS) \
((GET_CODE (X) == CONST_INT \
&& (unsigned) (INTVAL (X) + 0x80) < 0x100 \
&& (CLASS) != ADDR_REGS) \
? DATA_REGS \
: (GET_MODE (X) == QImode && (CLASS) != ADDR_REGS) \
? DATA_REGS \
: (GET_CODE (X) == CONST_DOUBLE \
&& GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
? (TARGET_HARD_FLOAT && (CLASS == FP_REGS || CLASS == DATA_OR_FP_REGS) \
? FP_REGS : NO_REGS) \
: (TARGET_PCREL \
&& (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST \
|| GET_CODE (X) == LABEL_REF)) \
? ADDR_REGS \
: (CLASS))
/* Force QImode output reloads from subregs to be allocated to data regs,
since QImode stores from address regs are not supported. We make the
assumption that if the class is not ADDR_REGS, then it must be a superset
of DATA_REGS. */
#define LIMIT_RELOAD_CLASS(MODE, CLASS) \
(((MODE) == QImode && (CLASS) != ADDR_REGS) \
? DATA_REGS \
: (CLASS))
/* On the m68k, this is the size of MODE in words, /* On the m68k, this is the size of MODE in words,
except in the FP regs, where a single reg is always enough. */ except in the FP regs, where a single reg is always enough. */
......
2007-03-06 Richard Sandiford <richard@codesourcery.com>
* gcc.c-torture/compile/m68k-byte-addr.c: New test.
2007-03-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> 2007-03-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gcc.dg/torture/builtin-convert-4.c: New test. * gcc.dg/torture/builtin-convert-4.c: New test.
/* This testcase triggered an attempt to reload a byte value into an
address register. */
extern volatile unsigned char x[];
#define DECLARE(I) orig##I, inc##I
#define READ(I) orig##I = x[I]
#define INC(I) inc##I = orig##I + 1
#define WRITE1(I) x[I] = orig##I
#define WRITE2(I) x[I] = inc##I
#define REPEAT(X) X(0), X(1), X(2), X(3), X(4), X(5), X(6), X(7), X(8)
void foo (void)
{
unsigned char REPEAT (DECLARE);
REPEAT (READ);
REPEAT (INC);
REPEAT (WRITE1);
REPEAT (WRITE2);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment