Commit 58e6223e by Eric Botcazou Committed by Eric Botcazou

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
parent bfb7cccf
2010-07-25 Eric Botcazou <ebotcazou@adacore.com> 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 PR target/44484
* config/sparc/predicates.md (memory_reg_operand): Delete. * config/sparc/predicates.md (memory_reg_operand): Delete.
* config/sparc/sync.md (sync_compare_and_swap): Minor tweaks. * config/sparc/sync.md (sync_compare_and_swap): Minor tweaks.
......
...@@ -63,6 +63,8 @@ extern void emit_tfmode_cvt (enum rtx_code, rtx *); ...@@ -63,6 +63,8 @@ extern void emit_tfmode_cvt (enum rtx_code, rtx *);
extern bool legitimate_constant_p (rtx); extern bool legitimate_constant_p (rtx);
extern bool constant_address_p (rtx); extern bool constant_address_p (rtx);
extern bool legitimate_pic_operand_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_emit_call_insn (rtx, rtx);
extern void sparc_defer_case_vector (rtx, rtx, int); extern void sparc_defer_case_vector (rtx, rtx, int);
extern bool sparc_expand_move (enum machine_mode, rtx *); extern bool sparc_expand_move (enum machine_mode, rtx *);
......
...@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfglayout.h" #include "cfglayout.h"
#include "gimple.h" #include "gimple.h"
#include "langhooks.h" #include "langhooks.h"
#include "reload.h"
#include "params.h" #include "params.h"
#include "df.h" #include "df.h"
#include "dwarf2out.h" #include "dwarf2out.h"
...@@ -416,8 +417,8 @@ static void sparc_va_start (tree, rtx); ...@@ -416,8 +417,8 @@ static void sparc_va_start (tree, rtx);
static tree sparc_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *); 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_vector_mode_supported_p (enum machine_mode);
static bool sparc_tls_referenced_p (rtx); static bool sparc_tls_referenced_p (rtx);
static rtx legitimize_tls_address (rtx); static rtx sparc_legitimize_tls_address (rtx);
static rtx legitimize_pic_address (rtx, rtx); static rtx sparc_legitimize_pic_address (rtx, rtx);
static rtx sparc_legitimize_address (rtx, rtx, enum machine_mode); static rtx sparc_legitimize_address (rtx, rtx, enum machine_mode);
static bool sparc_mode_dependent_address_p (const_rtx); static bool sparc_mode_dependent_address_p (const_rtx);
static bool sparc_pass_by_reference (CUMULATIVE_ARGS *, static bool sparc_pass_by_reference (CUMULATIVE_ARGS *,
...@@ -1006,7 +1007,7 @@ sparc_expand_move (enum machine_mode mode, rtx *operands) ...@@ -1006,7 +1007,7 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
&& CONSTANT_P (operands[1]) && CONSTANT_P (operands[1])
&& sparc_tls_referenced_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; return false;
} }
...@@ -1014,7 +1015,7 @@ sparc_expand_move (enum machine_mode mode, rtx *operands) ...@@ -1014,7 +1015,7 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
if (flag_pic && CONSTANT_P (operands[1])) if (flag_pic && CONSTANT_P (operands[1]))
{ {
if (pic_address_needs_scratch (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 /* 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 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) ...@@ -1041,9 +1042,10 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
if (symbolic_operand (operands[1], mode)) if (symbolic_operand (operands[1], mode))
{ {
operands[1] = legitimize_pic_address (operands[1], operands[1]
reload_in_progress = sparc_legitimize_pic_address (operands[1],
? operands[0] : NULL_RTX); reload_in_progress
? operands[0] : NULL_RTX);
return false; return false;
} }
} }
...@@ -3217,7 +3219,7 @@ sparc_tls_referenced_p (rtx x) ...@@ -3217,7 +3219,7 @@ sparc_tls_referenced_p (rtx x)
if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x)) if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x))
return true; 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; return false;
} }
...@@ -3225,7 +3227,7 @@ sparc_tls_referenced_p (rtx x) ...@@ -3225,7 +3227,7 @@ sparc_tls_referenced_p (rtx x)
this (thread-local) address. */ this (thread-local) address. */
static rtx static rtx
legitimize_tls_address (rtx addr) sparc_legitimize_tls_address (rtx addr)
{ {
rtx temp1, temp2, temp3, ret, o0, got, insn; rtx temp1, temp2, temp3, ret, o0, got, insn;
...@@ -3354,7 +3356,7 @@ legitimize_tls_address (rtx addr) ...@@ -3354,7 +3356,7 @@ legitimize_tls_address (rtx addr)
gcc_assert (GET_CODE (XEXP (addr, 0)) == PLUS); 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); offset = XEXP (XEXP (addr, 0), 1);
base = force_operand (base, NULL_RTX); base = force_operand (base, NULL_RTX);
...@@ -3375,7 +3377,7 @@ legitimize_tls_address (rtx addr) ...@@ -3375,7 +3377,7 @@ legitimize_tls_address (rtx addr)
necessary. */ necessary. */
static rtx static rtx
legitimize_pic_address (rtx orig, rtx reg) sparc_legitimize_pic_address (rtx orig, rtx reg)
{ {
bool gotdata_op = false; bool gotdata_op = false;
...@@ -3424,10 +3426,12 @@ legitimize_pic_address (rtx orig, rtx reg) ...@@ -3424,10 +3426,12 @@ legitimize_pic_address (rtx orig, rtx reg)
if (gotdata_op) if (gotdata_op)
{ {
if (TARGET_ARCH64) 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)); address, orig));
else 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)); address, orig));
} }
else else
...@@ -3457,9 +3461,9 @@ legitimize_pic_address (rtx orig, rtx reg) ...@@ -3457,9 +3461,9 @@ legitimize_pic_address (rtx orig, rtx reg)
} }
gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS); gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), reg); base = sparc_legitimize_pic_address (XEXP (XEXP (orig, 0), 0), reg);
offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), offset = sparc_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
base == reg ? NULL_RTX : reg); base == reg ? NULL_RTX : reg);
if (GET_CODE (offset) == CONST_INT) if (GET_CODE (offset) == CONST_INT)
{ {
...@@ -3515,9 +3519,9 @@ sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, ...@@ -3515,9 +3519,9 @@ sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
return x; return x;
if (sparc_tls_referenced_p (x)) if (sparc_tls_referenced_p (x))
x = legitimize_tls_address (x); x = sparc_legitimize_tls_address (x);
else if (flag_pic) 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))) else if (GET_CODE (x) == PLUS && CONSTANT_ADDRESS_P (XEXP (x, 1)))
x = gen_rtx_PLUS (Pmode, XEXP (x, 0), x = gen_rtx_PLUS (Pmode, XEXP (x, 0),
copy_to_mode_reg (Pmode, XEXP (x, 1))); copy_to_mode_reg (Pmode, XEXP (x, 1)));
...@@ -3532,6 +3536,55 @@ sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, ...@@ -3532,6 +3536,55 @@ sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
return x; 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) /* Return true if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for. 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, ...@@ -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 /* Delay emitting the PIC helper function because it needs to
change the section and we are emitting assembly code. */ change the section and we are emitting assembly code. */
load_pic_register (); /* clobbers %o7 */ load_pic_register (); /* clobbers %o7 */
scratch = legitimize_pic_address (funexp, scratch); scratch = sparc_legitimize_pic_address (funexp, scratch);
seq = get_insns (); seq = get_insns ();
end_sequence (); end_sequence ();
emit_and_preserve (seq, spill_reg, spill_reg2); emit_and_preserve (seq, spill_reg, spill_reg2);
......
...@@ -1801,36 +1801,14 @@ do { \ ...@@ -1801,36 +1801,14 @@ do { \
/* Try a machine-dependent way of reloading an illegitimate address /* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This 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. macro is used in only one place: `find_reloads_address' in reload.c. */
#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
For SPARC 32, we wish to handle addresses by splitting them into do { \
HIGH+LO_SUM pairs, retaining the LO_SUM in the memory reference. int win; \
This cuts the number of extra insns by one. (X) = sparc_legitimize_reload_address ((X), (MODE), (OPNUM), \
(int)(TYPE), (IND_LEVELS), &win); \
Do nothing when generating PIC code and the address is a if (win) \
symbolic operand or requires a scratch register. */ goto WIN; \
#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. */ \
} while (0) } while (0)
/* Specify the machine mode that this machine uses /* Specify the machine mode that this machine uses
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment