diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-08-20 23:34:10 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-08-20 23:34:10 +0000 |
commit | f25bee5a48a12a3a55c9b911c549e8d0b64d6a7d (patch) | |
tree | 9fbd6951ec335b2e9c4bc5c74e765668d5ee5d8d /gcc/reload.c | |
parent | ba453b31f7e8c5b8ea6628512d7d8a5f6464fad8 (diff) | |
download | gcc-f25bee5a48a12a3a55c9b911c549e8d0b64d6a7d.tar.gz |
* reload.c (find_reloads_address): Reload the sum of a LO_SUM and
a CONST_INT.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@86342 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reload.c')
-rw-r--r-- | gcc/reload.c | 102 |
1 files changed, 53 insertions, 49 deletions
diff --git a/gcc/reload.c b/gcc/reload.c index b114dc2b148..715e58fa127 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -4647,6 +4647,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad, { int regno; int removed_and = 0; + int op_index; rtx tem; /* If the address is a register, see if it is a legitimate address and @@ -4892,7 +4893,9 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad, Handle all base registers here, not just fp/ap/sp, because on some targets (namely SPARC) we can also get invalid addresses from preventive - subreg big-endian corrections made by find_reloads_toplev. + subreg big-endian corrections made by find_reloads_toplev. We + can also get expressions involving LO_SUM (rather than PLUS) from + find_reloads_subreg_address. If we decide to do something, it must be that `double_reg_address_ok' is true. We generate a reload of the base register + constant and @@ -4900,62 +4903,63 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad, This is safe because we know the address isn't shared. We check for the base register as both the first and second operand of - the innermost PLUS. */ - - else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT - && GET_CODE (XEXP (ad, 0)) == PLUS - && REG_P (XEXP (XEXP (ad, 0), 0)) - && REGNO (XEXP (XEXP (ad, 0), 0)) < FIRST_PSEUDO_REGISTER - && (REG_MODE_OK_FOR_BASE_P (XEXP (XEXP (ad, 0), 0), mode) - || XEXP (XEXP (ad, 0), 0) == frame_pointer_rtx -#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM - || XEXP (XEXP (ad, 0), 0) == hard_frame_pointer_rtx -#endif -#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM - || XEXP (XEXP (ad, 0), 0) == arg_pointer_rtx -#endif - || XEXP (XEXP (ad, 0), 0) == stack_pointer_rtx) - && ! maybe_memory_address_p (mode, ad, &XEXP (XEXP (ad, 0), 1))) + the innermost PLUS and/or LO_SUM. */ + + for (op_index = 0; op_index < 2; ++op_index) { - *loc = ad = gen_rtx_PLUS (GET_MODE (ad), - plus_constant (XEXP (XEXP (ad, 0), 0), - INTVAL (XEXP (ad, 1))), - XEXP (XEXP (ad, 0), 1)); - find_reloads_address_part (XEXP (ad, 0), &XEXP (ad, 0), - MODE_BASE_REG_CLASS (mode), - GET_MODE (ad), opnum, type, ind_levels); - find_reloads_address_1 (mode, XEXP (ad, 1), 1, &XEXP (ad, 1), opnum, - type, 0, insn); + rtx operand; - return 0; - } + if (!(GET_CODE (ad) == PLUS + && GET_CODE (XEXP (ad, 1)) == CONST_INT + && (GET_CODE (XEXP (ad, 0)) == PLUS + || GET_CODE (XEXP (ad, 0)) == LO_SUM))) + continue; - else if (GET_CODE (ad) == PLUS && GET_CODE (XEXP (ad, 1)) == CONST_INT - && GET_CODE (XEXP (ad, 0)) == PLUS - && REG_P (XEXP (XEXP (ad, 0), 1)) - && REGNO (XEXP (XEXP (ad, 0), 1)) < FIRST_PSEUDO_REGISTER - && (REG_MODE_OK_FOR_BASE_P (XEXP (XEXP (ad, 0), 1), mode) - || XEXP (XEXP (ad, 0), 1) == frame_pointer_rtx + operand = XEXP (XEXP (ad, 0), op_index); + if (!(REG_P (operand) + || REGNO (operand) < FIRST_PSEUDO_REGISTER)) + continue; + + if ((REG_MODE_OK_FOR_BASE_P (operand, mode) + || operand == frame_pointer_rtx #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM - || XEXP (XEXP (ad, 0), 1) == hard_frame_pointer_rtx + || operand == hard_frame_pointer_rtx #endif #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM - || XEXP (XEXP (ad, 0), 1) == arg_pointer_rtx + || operand == arg_pointer_rtx #endif - || XEXP (XEXP (ad, 0), 1) == stack_pointer_rtx) - && ! maybe_memory_address_p (mode, ad, &XEXP (XEXP (ad, 0), 0))) - { - *loc = ad = gen_rtx_PLUS (GET_MODE (ad), - XEXP (XEXP (ad, 0), 0), - plus_constant (XEXP (XEXP (ad, 0), 1), - INTVAL (XEXP (ad, 1)))); - find_reloads_address_part (XEXP (ad, 1), &XEXP (ad, 1), - MODE_BASE_REG_CLASS (mode), - GET_MODE (ad), opnum, type, ind_levels); - find_reloads_address_1 (mode, XEXP (ad, 0), 1, &XEXP (ad, 0), opnum, - type, 0, insn); + || operand == stack_pointer_rtx) + && ! maybe_memory_address_p (mode, ad, + &XEXP (XEXP (ad, 0), op_index))) + { + rtx offset_reg; + rtx addend; + + offset_reg = plus_constant (operand, INTVAL (XEXP (ad, 1))); + addend = XEXP (XEXP (ad, 0), 1 - op_index); + + /* Form the adjusted address. */ + if (GET_CODE (XEXP (ad, 0)) == PLUS) + ad = gen_rtx_PLUS (GET_MODE (ad), + op_index == 0 ? offset_reg : addend, + op_index == 0 ? addend : offset_reg); + else + ad = gen_rtx_LO_SUM (GET_MODE (ad), + op_index == 0 ? offset_reg : addend, + op_index == 0 ? addend : offset_reg); + *loc = ad; + + find_reloads_address_part (XEXP (ad, op_index), + &XEXP (ad, op_index), + MODE_BASE_REG_CLASS (mode), + GET_MODE (ad), opnum, type, ind_levels); + find_reloads_address_1 (mode, + XEXP (ad, 1 - op_index), 1, + &XEXP (ad, 1 - op_index), opnum, + type, 0, insn); - return 0; + return 0; + } } /* See if address becomes valid when an eliminable register |