diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2011-08-16 18:33:15 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2011-08-16 18:33:15 +0000 |
commit | 2ea0be597eaacb6ca34f0fc8a9249949bcf97d64 (patch) | |
tree | 6e28f379a4706d4b9a7e2349ef3514928ddd453d | |
parent | b05933f5277f7a0f09670f205af31b082e0e4976 (diff) | |
download | gcc-2ea0be597eaacb6ca34f0fc8a9249949bcf97d64.zip gcc-2ea0be597eaacb6ca34f0fc8a9249949bcf97d64.tar.gz gcc-2ea0be597eaacb6ca34f0fc8a9249949bcf97d64.tar.bz2 |
spu.h (LEGITIMIZE_RELOAD_ADDRESS): New macro.
* config/spu/spu.h (LEGITIMIZE_RELOAD_ADDRESS): New macro.
* config/spu/spu-protos.h (spu_legitimize_reload_address): Add
prototype.
* config/spu/spu.c (spu_legitimize_reload_address): New function.
(spu_legitimate_address_p): Do not check displacement if the base
is an eliminable stack register.
From-SVN: r177794
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/spu/spu-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/spu/spu.c | 49 | ||||
-rw-r--r-- | gcc/config/spu/spu.h | 11 |
4 files changed, 68 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 59176fc..67ae4ed8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2011-08-16 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * config/spu/spu.h (LEGITIMIZE_RELOAD_ADDRESS): New macro. + * config/spu/spu-protos.h (spu_legitimize_reload_address): Add + prototype. + * config/spu/spu.c (spu_legitimize_reload_address): New function. + (spu_legitimate_address_p): Do not check displacement if the base + is an eliminable stack register. + 2011-08-16 Anatoly Sokolov <aesok@post.ru> * config/m32c/m32c.h (PREFERRED_RELOAD_CLASS, diff --git a/gcc/config/spu/spu-protos.h b/gcc/config/spu/spu-protos.h index cb5cc24..9485f38 100644 --- a/gcc/config/spu/spu-protos.h +++ b/gcc/config/spu/spu-protos.h @@ -76,6 +76,7 @@ extern void spu_builtin_insert (rtx ops[]); extern void spu_builtin_promote (rtx ops[]); extern void spu_expand_sign_extend (rtx ops[]); extern void spu_expand_vector_init (rtx target, rtx vals); +extern rtx spu_legitimize_reload_address (rtx, enum machine_mode, int, int); #endif /* RTX_CODE */ extern void spu_init_expanders (void); diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c index c6db6c3..7868c7f 100644 --- a/gcc/config/spu/spu.c +++ b/gcc/config/spu/spu.c @@ -3803,8 +3803,14 @@ spu_legitimate_address_p (enum machine_mode mode, if (GET_CODE (op0) == REG && INT_REG_OK_FOR_BASE_P (op0, reg_ok_strict) && GET_CODE (op1) == CONST_INT - && INTVAL (op1) >= -0x2000 - && INTVAL (op1) <= 0x1fff + && ((INTVAL (op1) >= -0x2000 && INTVAL (op1) <= 0x1fff) + /* If virtual registers are involved, the displacement will + change later on anyway, so checking would be premature. + Reload will make sure the final displacement after + register elimination is OK. */ + || op0 == arg_pointer_rtx + || op0 == frame_pointer_rtx + || op0 == virtual_stack_vars_rtx) && (!aligned || (INTVAL (op1) & 15) == 0)) return TRUE; if (GET_CODE (op0) == REG @@ -3877,6 +3883,45 @@ spu_addr_space_legitimize_address (rtx x, rtx oldx, enum machine_mode mode, return spu_legitimize_address (x, oldx, mode); } +/* Reload reg + const_int for out-of-range displacements. */ +rtx +spu_legitimize_reload_address (rtx ad, enum machine_mode mode ATTRIBUTE_UNUSED, + int opnum, int type) +{ + bool removed_and = false; + + if (GET_CODE (ad) == AND + && CONST_INT_P (XEXP (ad, 1)) + && INTVAL (XEXP (ad, 1)) == (HOST_WIDE_INT) - 16) + { + ad = XEXP (ad, 0); + removed_and = true; + } + + if (GET_CODE (ad) == PLUS + && REG_P (XEXP (ad, 0)) + && CONST_INT_P (XEXP (ad, 1)) + && !(INTVAL (XEXP (ad, 1)) >= -0x2000 + && INTVAL (XEXP (ad, 1)) <= 0x1fff)) + { + /* Unshare the sum. */ + ad = copy_rtx (ad); + + /* Reload the displacement. */ + push_reload (XEXP (ad, 1), NULL_RTX, &XEXP (ad, 1), NULL, + BASE_REG_CLASS, GET_MODE (ad), VOIDmode, 0, 0, + opnum, (enum reload_type) type); + + /* Add back AND for alignment if we stripped it. */ + if (removed_and) + ad = gen_rtx_AND (GET_MODE (ad), ad, GEN_INT (-16)); + + return ad; + } + + return NULL_RTX; +} + /* Handle an attribute requiring a FUNCTION_DECL; arguments as in struct attribute_spec.handler. */ static tree diff --git a/gcc/config/spu/spu.h b/gcc/config/spu/spu.h index c69cf7e..d89bf49 100644 --- a/gcc/config/spu/spu.h +++ b/gcc/config/spu/spu.h @@ -390,6 +390,17 @@ targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \ #define MAX_REGS_PER_ADDRESS 2 +#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \ +do { \ + rtx new_rtx = spu_legitimize_reload_address (AD, MODE, OPNUM, \ + (int)(TYPE)); \ + if (new_rtx) \ + { \ + (AD) = new_rtx; \ + goto WIN; \ + } \ +} while (0) + /* Costs */ |