diff options
author | Richard Sandiford <richard@codesourcery.com> | 2007-03-06 09:01:07 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2007-03-06 09:01:07 +0000 |
commit | ffa2596e3aae16e6bc2254c954b52ea504a612b6 (patch) | |
tree | e7694879133c0b1bb72192801c9bf1826003b890 /gcc/config/m68k | |
parent | 4f44ecc07f40ad8210c703300224b7e6bed86a86 (diff) | |
download | gcc-ffa2596e3aae16e6bc2254c954b52ea504a612b6.zip gcc-ffa2596e3aae16e6bc2254c954b52ea504a612b6.tar.gz gcc-ffa2596e3aae16e6bc2254c954b52ea504a612b6.tar.bz2 |
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
Diffstat (limited to 'gcc/config/m68k')
-rw-r--r-- | gcc/config/m68k/m68k-protos.h | 3 | ||||
-rw-r--r-- | gcc/config/m68k/m68k.c | 71 | ||||
-rw-r--r-- | gcc/config/m68k/m68k.h | 37 |
3 files changed, 72 insertions, 39 deletions
diff --git a/gcc/config/m68k/m68k-protos.h b/gcc/config/m68k/m68k-protos.h index 185e7bc..b3b78a1 100644 --- a/gcc/config/m68k/m68k-protos.h +++ b/gcc/config/m68k/m68k-protos.h @@ -69,6 +69,9 @@ extern const char *m68k_output_movem (rtx *, rtx, HOST_WIDE_INT, bool); #endif /* RTX_CODE */ 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 void m68k_expand_prologue (void); extern bool m68k_use_return_insn (void); diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index e491beb..b702f85 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -4153,9 +4153,10 @@ m68k_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED, return 1; } -/* 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, but the 68881 registers can hold only SFmode or DFmode. */ +/* Value is true if hard register REGNO can hold a value of machine-mode + MODE. On the 68000, we let the cpu registers can hold any mode, but + restrict the 68881 registers to floating-point modes. */ + bool 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)) { - /* 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) return true; } @@ -4186,6 +4183,66 @@ m68k_regno_mode_ok (int regno, enum machine_mode mode) 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 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. diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h index c4b1e14..9d7843d 100644 --- a/gcc/config/m68k/m68k.h +++ b/gcc/config/m68k/m68k.h @@ -401,13 +401,12 @@ Boston, MA 02110-1301, USA. */ #define 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) \ 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) \ (! TARGET_HARD_FLOAT \ || ((GET_MODE_CLASS (MODE1) == MODE_FLOAT \ @@ -544,34 +543,8 @@ extern enum reg_class regno_reg_class[]; ? const_call_operand (OP, VOIDmode) \ : 0) -/* On the m68k, use a data reg if possible when the - value is a constant in the range where moveq could be used - 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)) +#define PREFERRED_RELOAD_CLASS(X,CLASS) \ + m68k_preferred_reload_class (X, CLASS) /* On the m68k, this is the size of MODE in words, except in the FP regs, where a single reg is always enough. */ |