From: Ulrich Weigand Date: Tue, 16 Aug 2011 18:33:15 +0000 (+0000) Subject: spu.h (LEGITIMIZE_RELOAD_ADDRESS): New macro. X-Git-Tag: releases/gcc-4.7.0~4431 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2ea0be597eaacb6ca34f0fc8a9249949bcf97d64;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 59176fccb34c..67ae4ed82637 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2011-08-16 Ulrich Weigand + + * 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 * config/m32c/m32c.h (PREFERRED_RELOAD_CLASS, diff --git a/gcc/config/spu/spu-protos.h b/gcc/config/spu/spu-protos.h index cb5cc2415397..9485f384f1f5 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 c6db6c3b3b00..7868c7f98107 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 c69cf7efc4e3..d89bf49f2d2f 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 */