From 58e6223e9283df9deb166d5dbc1fcc4d21c17ce0 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sun, 25 Jul 2010 21:46:32 +0000 Subject: [PATCH] re PR target/44707 (operand requires impossible reload) PR target/44707 * config/sparc/sparc-protos.h (sparc_legitimize_reload_address): New. * config/sparc/sparc.c: Include reload.h. (legitimize_tls_address): Rename into... (sparc_legitimize_tls_address): ...this. (legitimize_pic_address): Rename into... (sparc_legitimize_pic_address): ...this. (sparc_expand_move): Adjust to above renaming. (sparc_tls_referenced_p): Likewise. (sparc_legitimize_tls_address): Likewise. (sparc_legitimize_pic_address): Likewise. (sparc_legitimize_address): Likewise. (sparc_output_mi_thunk): Likewise. (sparc_legitimize_reload_address): New global function. Recognize (lo_sum (high ...) ...) patterns generated by earlier passes. * config/sparc/sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Use above function. From-SVN: r162521 --- gcc/ChangeLog | 19 +++++++ gcc/config/sparc/sparc-protos.h | 2 + gcc/config/sparc/sparc.c | 91 ++++++++++++++++++++++++++------- gcc/config/sparc/sparc.h | 38 +++----------- 4 files changed, 101 insertions(+), 49 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd557151d60..8fc9c977e73 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2010-07-25 Eric Botcazou + + PR target/44707 + * config/sparc/sparc-protos.h (sparc_legitimize_reload_address): New. + * config/sparc/sparc.c: Include reload.h. + (legitimize_tls_address): Rename into... + (sparc_legitimize_tls_address): ...this. + (legitimize_pic_address): Rename into... + (sparc_legitimize_pic_address): ...this. + (sparc_expand_move): Adjust to above renaming. + (sparc_tls_referenced_p): Likewise. + (sparc_legitimize_tls_address): Likewise. + (sparc_legitimize_pic_address): Likewise. + (sparc_legitimize_address): Likewise. + (sparc_output_mi_thunk): Likewise. + (sparc_legitimize_reload_address): New global function. Recognize + (lo_sum (high ...) ...) patterns generated by earlier passes. + * config/sparc/sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Use above function. + 2010-07-25 Eric Botcazou PR target/44484 diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index 35c99b967ba..f5efcb988f2 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -63,6 +63,8 @@ extern void emit_tfmode_cvt (enum rtx_code, rtx *); extern bool legitimate_constant_p (rtx); extern bool constant_address_p (rtx); extern bool legitimate_pic_operand_p (rtx); +extern rtx sparc_legitimize_reload_address (rtx, enum machine_mode, int, int, + int, int *win); extern void sparc_emit_call_insn (rtx, rtx); extern void sparc_defer_case_vector (rtx, rtx, int); extern bool sparc_expand_move (enum machine_mode, rtx *); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index d4769554033..48cf00e902a 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see #include "cfglayout.h" #include "gimple.h" #include "langhooks.h" +#include "reload.h" #include "params.h" #include "df.h" #include "dwarf2out.h" @@ -416,8 +417,8 @@ static void sparc_va_start (tree, rtx); static tree sparc_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *); static bool sparc_vector_mode_supported_p (enum machine_mode); static bool sparc_tls_referenced_p (rtx); -static rtx legitimize_tls_address (rtx); -static rtx legitimize_pic_address (rtx, rtx); +static rtx sparc_legitimize_tls_address (rtx); +static rtx sparc_legitimize_pic_address (rtx, rtx); static rtx sparc_legitimize_address (rtx, rtx, enum machine_mode); static bool sparc_mode_dependent_address_p (const_rtx); static bool sparc_pass_by_reference (CUMULATIVE_ARGS *, @@ -1006,7 +1007,7 @@ sparc_expand_move (enum machine_mode mode, rtx *operands) && CONSTANT_P (operands[1]) && sparc_tls_referenced_p (operands [1])) { - operands[1] = legitimize_tls_address (operands[1]); + operands[1] = sparc_legitimize_tls_address (operands[1]); return false; } @@ -1014,7 +1015,7 @@ sparc_expand_move (enum machine_mode mode, rtx *operands) if (flag_pic && CONSTANT_P (operands[1])) { if (pic_address_needs_scratch (operands[1])) - operands[1] = legitimize_pic_address (operands[1], NULL_RTX); + operands[1] = sparc_legitimize_pic_address (operands[1], NULL_RTX); /* VxWorks does not impose a fixed gap between segments; the run-time gap can be different from the object-file gap. We therefore can't @@ -1041,9 +1042,10 @@ sparc_expand_move (enum machine_mode mode, rtx *operands) if (symbolic_operand (operands[1], mode)) { - operands[1] = legitimize_pic_address (operands[1], - reload_in_progress - ? operands[0] : NULL_RTX); + operands[1] + = sparc_legitimize_pic_address (operands[1], + reload_in_progress + ? operands[0] : NULL_RTX); return false; } } @@ -3217,7 +3219,7 @@ sparc_tls_referenced_p (rtx x) if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x)) return true; - /* That's all we handle in legitimize_tls_address for now. */ + /* That's all we handle in sparc_legitimize_tls_address for now. */ return false; } @@ -3225,7 +3227,7 @@ sparc_tls_referenced_p (rtx x) this (thread-local) address. */ static rtx -legitimize_tls_address (rtx addr) +sparc_legitimize_tls_address (rtx addr) { rtx temp1, temp2, temp3, ret, o0, got, insn; @@ -3354,7 +3356,7 @@ legitimize_tls_address (rtx addr) gcc_assert (GET_CODE (XEXP (addr, 0)) == PLUS); - base = legitimize_tls_address (XEXP (XEXP (addr, 0), 0)); + base = sparc_legitimize_tls_address (XEXP (XEXP (addr, 0), 0)); offset = XEXP (XEXP (addr, 0), 1); base = force_operand (base, NULL_RTX); @@ -3375,7 +3377,7 @@ legitimize_tls_address (rtx addr) necessary. */ static rtx -legitimize_pic_address (rtx orig, rtx reg) +sparc_legitimize_pic_address (rtx orig, rtx reg) { bool gotdata_op = false; @@ -3424,10 +3426,12 @@ legitimize_pic_address (rtx orig, rtx reg) if (gotdata_op) { if (TARGET_ARCH64) - insn = emit_insn (gen_movdi_pic_gotdata_op (reg, pic_offset_table_rtx, + insn = emit_insn (gen_movdi_pic_gotdata_op (reg, + pic_offset_table_rtx, address, orig)); else - insn = emit_insn (gen_movsi_pic_gotdata_op (reg, pic_offset_table_rtx, + insn = emit_insn (gen_movsi_pic_gotdata_op (reg, + pic_offset_table_rtx, address, orig)); } else @@ -3457,9 +3461,9 @@ legitimize_pic_address (rtx orig, rtx reg) } gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS); - base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), reg); - offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), - base == reg ? NULL_RTX : reg); + base = sparc_legitimize_pic_address (XEXP (XEXP (orig, 0), 0), reg); + offset = sparc_legitimize_pic_address (XEXP (XEXP (orig, 0), 1), + base == reg ? NULL_RTX : reg); if (GET_CODE (offset) == CONST_INT) { @@ -3515,9 +3519,9 @@ sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, return x; if (sparc_tls_referenced_p (x)) - x = legitimize_tls_address (x); + x = sparc_legitimize_tls_address (x); else if (flag_pic) - x = legitimize_pic_address (x, NULL_RTX); + x = sparc_legitimize_pic_address (x, NULL_RTX); else if (GET_CODE (x) == PLUS && CONSTANT_ADDRESS_P (XEXP (x, 1))) x = gen_rtx_PLUS (Pmode, XEXP (x, 0), copy_to_mode_reg (Pmode, XEXP (x, 1))); @@ -3532,6 +3536,55 @@ sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, return x; } +/* SPARC implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to + replace the input X, or the original X if no replacement is called for. + The output parameter *WIN is 1 if the calling macro should goto WIN, + 0 if it should not. + + For SPARC, we wish to handle addresses by splitting them into + HIGH+LO_SUM pairs, retaining the LO_SUM in the memory reference. + This cuts the number of extra insns by one. + + Do nothing when generating PIC code and the address is a symbolic + operand or requires a scratch register. */ + +rtx +sparc_legitimize_reload_address (rtx x, enum machine_mode mode, + int opnum, int type, + int ind_levels ATTRIBUTE_UNUSED, int *win) +{ + /* Decompose SImode constants into HIGH+LO_SUM. */ + if (CONSTANT_P (x) + && (mode != TFmode || TARGET_ARCH64) + && GET_MODE (x) == SImode + && GET_CODE (x) != LO_SUM + && GET_CODE (x) != HIGH + && sparc_cmodel <= CM_MEDLOW + && !(flag_pic + && (symbolic_operand (x, Pmode) || pic_address_needs_scratch (x)))) + { + x = gen_rtx_LO_SUM (GET_MODE (x), gen_rtx_HIGH (GET_MODE (x), x), x); + push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, + BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0, + opnum, (enum reload_type)type); + *win = 1; + return x; + } + + /* We have to recognize what we have already generated above. */ + if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == HIGH) + { + push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL, + BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0, + opnum, (enum reload_type)type); + *win = 1; + return x; + } + + *win = 0; + return x; +} + /* Return true if ADDR (a legitimate address expression) has an effect that depends on the machine mode it is used for. @@ -9111,7 +9164,7 @@ sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, /* Delay emitting the PIC helper function because it needs to change the section and we are emitting assembly code. */ load_pic_register (); /* clobbers %o7 */ - scratch = legitimize_pic_address (funexp, scratch); + scratch = sparc_legitimize_pic_address (funexp, scratch); seq = get_insns (); end_sequence (); emit_and_preserve (seq, spill_reg, spill_reg2); diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 6f6aec7d3f9..eae39597023 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -1801,36 +1801,14 @@ do { \ /* Try a machine-dependent way of reloading an illegitimate address operand. If we find one, push the reload and jump to WIN. This - macro is used in only one place: `find_reloads_address' in reload.c. - - For SPARC 32, we wish to handle addresses by splitting them into - HIGH+LO_SUM pairs, retaining the LO_SUM in the memory reference. - This cuts the number of extra insns by one. - - Do nothing when generating PIC code and the address is a - symbolic operand or requires a scratch register. */ - -#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \ -do { \ - /* Decompose SImode constants into hi+lo_sum. We do have to \ - rerecognize what we produce, so be careful. */ \ - if (CONSTANT_P (X) \ - && (MODE != TFmode || TARGET_ARCH64) \ - && GET_MODE (X) == SImode \ - && GET_CODE (X) != LO_SUM && GET_CODE (X) != HIGH \ - && ! (flag_pic \ - && (symbolic_operand (X, Pmode) \ - || pic_address_needs_scratch (X))) \ - && sparc_cmodel <= CM_MEDLOW) \ - { \ - X = gen_rtx_LO_SUM (GET_MODE (X), \ - gen_rtx_HIGH (GET_MODE (X), X), X); \ - push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL, \ - BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \ - OPNUM, TYPE); \ - goto WIN; \ - } \ - /* ??? 64-bit reloads. */ \ + macro is used in only one place: `find_reloads_address' in reload.c. */ +#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \ +do { \ + int win; \ + (X) = sparc_legitimize_reload_address ((X), (MODE), (OPNUM), \ + (int)(TYPE), (IND_LEVELS), &win); \ + if (win) \ + goto WIN; \ } while (0) /* Specify the machine mode that this machine uses