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
This commit is contained in:
parent
bfb7cccf06
commit
58e6223e92
|
@ -1,3 +1,22 @@
|
|||
2010-07-25 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
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 <ebotcazou@adacore.com>
|
||||
|
||||
PR target/44484
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue