Commit 38fc66ba by Eric Botcazou Committed by Eric Botcazou

re PR target/21412 (ICE loading TLS address)

	PR target/21412
	* config/sparc/sparc.h (SPARC_SYMBOL_REF_TLS_P): New macro
	* config/sparc/sparc-protos.h (tls_symbolic_operand): Delete.
	(sparc_tls_referenced_p): New prototype.
	* config/sparc/sparc.c (tls_symbolic_operand): Delete.
	(sparc_expand_move): Look for TLS addresses with constant offsets.
	(legitimate_constant_p): Use SPARC_SYMBOL_REF_TLS_P instead of
	tls_symbolic_operand.
	(legitimate_pic_operand_p): Likewise.
	(legitimate_address_p): Likewise.
	(legitimize_address): Likewise.
	(sparc_tls_symbol_ref_1): New function.
	(sparc_tls_referenced_p): New function.
	* config/sparc/predicates.md (tgd_symbolic_operand): Use
	SYMBOL_REF_TLS_MODEL instead of tls_symbolic_operand.
	(tld_symbolic_operand): Likewise.
	(tie_symbolic_operand): Likewise.
	(tle_symbolic_operand): Likewise.

From-SVN: r100137
parent 5c498b10
2005-05-25 Eric Botcazou <ebotcazou@libertysurf.fr>
PR target/21412
* config/sparc/sparc.h (SPARC_SYMBOL_REF_TLS_P): New macro
* config/sparc/sparc-protos.h (tls_symbolic_operand): Delete.
(sparc_tls_referenced_p): New prototype.
* config/sparc/sparc.c (tls_symbolic_operand): Delete.
(sparc_expand_move): Look for TLS addresses with constant offsets.
(legitimate_constant_p): Use SPARC_SYMBOL_REF_TLS_P instead of
tls_symbolic_operand.
(legitimate_pic_operand_p): Likewise.
(legitimate_address_p): Likewise.
(legitimize_address): Likewise.
(sparc_tls_symbol_ref_1): New function.
(sparc_tls_referenced_p): New function.
* config/sparc/predicates.md (tgd_symbolic_operand): Use
SYMBOL_REF_TLS_MODEL instead of tls_symbolic_operand.
(tld_symbolic_operand): Likewise.
(tie_symbolic_operand): Likewise.
(tle_symbolic_operand): Likewise.
2005-05-24 DJ Delorie <dj@redhat.com>
* common.opt (-Wattributes): New. Default true.
......
......@@ -120,22 +120,22 @@
;; Return true if OP is a symbolic operand for the TLS Global Dynamic model.
(define_predicate "tgd_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "tls_symbolic_operand (op) == TLS_MODEL_GLOBAL_DYNAMIC")))
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_GLOBAL_DYNAMIC")))
;; Return true if OP is a symbolic operand for the TLS Local Dynamic model.
(define_predicate "tld_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "tls_symbolic_operand (op) == TLS_MODEL_LOCAL_DYNAMIC")))
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_DYNAMIC")))
;; Return true if OP is a symbolic operand for the TLS Initial Exec model.
(define_predicate "tie_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "tls_symbolic_operand (op) == TLS_MODEL_INITIAL_EXEC")))
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_INITIAL_EXEC")))
;; Return true if OP is a symbolic operand for the TLS Local Exec model.
(define_predicate "tle_symbolic_operand"
(and (match_code "symbol_ref")
(match_test "tls_symbolic_operand (op) == TLS_MODEL_LOCAL_EXEC")))
(match_test "SYMBOL_REF_TLS_MODEL (op) == TLS_MODEL_LOCAL_EXEC")))
;; Return true if the operand is an argument used in generating PIC references
;; in either the medium/low or embedded medium/anywhere code models on V9.
......
......@@ -94,7 +94,6 @@ extern int arith_4096_operand (rtx, enum machine_mode);
extern int zero_operand (rtx, enum machine_mode);
extern int fp_zero_operand (rtx, enum machine_mode);
extern int reg_or_0_operand (rtx, enum machine_mode);
extern int tls_symbolic_operand (rtx);
extern int empty_delay_slot (rtx);
extern int eligible_for_return_delay (rtx);
extern int eligible_for_sibcall_delay (rtx);
......@@ -103,6 +102,7 @@ extern int emit_move_sequence (rtx, enum machine_mode);
extern int fp_sethi_p (rtx);
extern int fp_mov_p (rtx);
extern int fp_high_losum_p (rtx);
extern bool sparc_tls_referenced_p (rtx);
extern int mem_min_alignment (rtx, int);
extern int pic_address_needs_scratch (rtx);
extern int reg_unused_after (rtx, rtx);
......
......@@ -864,17 +864,6 @@ fp_high_losum_p (rtx op)
return 0;
}
/* If OP is a SYMBOL_REF of a thread-local symbol, return its TLS mode,
otherwise return 0. */
int
tls_symbolic_operand (rtx op)
{
if (GET_CODE (op) != SYMBOL_REF)
return 0;
return SYMBOL_REF_TLS_MODEL (op);
}
/* Expand a move instruction. Return true if all work is done. */
bool
......@@ -895,9 +884,31 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
}
/* Fixup TLS cases. */
if (tls_symbolic_operand (operands [1]))
operands[1] = legitimize_tls_address (operands[1]);
if (TARGET_HAVE_TLS
&& CONSTANT_P (operands[1])
&& GET_CODE (operands[1]) != HIGH
&& sparc_tls_referenced_p (operands [1]))
{
rtx sym = operands[1];
rtx addend = NULL;
if (GET_CODE (sym) == CONST && GET_CODE (XEXP (sym, 0)) == PLUS)
{
addend = XEXP (XEXP (sym, 0), 1);
sym = XEXP (XEXP (sym, 0), 0);
}
gcc_assert (SPARC_SYMBOL_REF_TLS_P (sym));
sym = legitimize_tls_address (sym);
if (addend)
{
sym = gen_rtx_PLUS (mode, sym, addend);
sym = force_operand (sym, operands[0]);
}
operands[1] = sym;
}
/* Fixup PIC cases. */
if (flag_pic && CONSTANT_P (operands[1]))
{
......@@ -2725,7 +2736,7 @@ legitimate_constant_p (rtx x)
/* Offsets of TLS symbols are never valid.
Discourage CSE from creating them. */
if (GET_CODE (inner) == PLUS
&& tls_symbolic_operand (XEXP (inner, 0)))
&& SPARC_SYMBOL_REF_TLS_P (XEXP (inner, 0)))
return false;
break;
......@@ -2792,10 +2803,10 @@ legitimate_pic_operand_p (rtx x)
{
if (pic_address_needs_scratch (x))
return false;
if (tls_symbolic_operand (x)
if (SPARC_SYMBOL_REF_TLS_P (x)
|| (GET_CODE (x) == CONST
&& GET_CODE (XEXP (x, 0)) == PLUS
&& tls_symbolic_operand (XEXP (XEXP (x, 0), 0))))
&& SPARC_SYMBOL_REF_TLS_P (XEXP (XEXP (x, 0), 0))))
return false;
return true;
}
......@@ -2833,7 +2844,7 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
&& GET_CODE (rs2) != SUBREG
&& GET_CODE (rs2) != LO_SUM
&& GET_CODE (rs2) != MEM
&& !tls_symbolic_operand (rs2)
&& ! SPARC_SYMBOL_REF_TLS_P (rs2)
&& (! symbolic_operand (rs2, VOIDmode) || mode == Pmode)
&& (GET_CODE (rs2) != CONST_INT || SMALL_INT (rs2)))
|| ((REG_P (rs1)
......@@ -2873,7 +2884,7 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
rs2 = NULL;
imm1 = XEXP (rs1, 1);
rs1 = XEXP (rs1, 0);
if (! CONSTANT_P (imm1) || tls_symbolic_operand (rs1))
if (! CONSTANT_P (imm1) || SPARC_SYMBOL_REF_TLS_P (rs1))
return 0;
}
}
......@@ -2882,7 +2893,7 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
rs1 = XEXP (addr, 0);
imm1 = XEXP (addr, 1);
if (! CONSTANT_P (imm1) || tls_symbolic_operand (rs1))
if (! CONSTANT_P (imm1) || SPARC_SYMBOL_REF_TLS_P (rs1))
return 0;
/* We can't allow TFmode in 32-bit mode, because an offset greater
......@@ -2931,6 +2942,7 @@ legitimate_address_p (enum machine_mode mode, rtx addr, int strict)
/* Construct the SYMBOL_REF for the tls_get_offset function. */
static GTY(()) rtx sparc_tls_symbol;
static rtx
sparc_tls_get_addr (void)
{
......@@ -2957,6 +2969,24 @@ sparc_tls_got (void)
return temp;
}
/* Return 1 if *X is a thread-local symbol. */
static int
sparc_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
{
return SPARC_SYMBOL_REF_TLS_P (*x);
}
/* Return 1 if X contains a thread-local symbol. */
bool
sparc_tls_referenced_p (rtx x)
{
if (!TARGET_HAVE_TLS)
return false;
return for_each_rtx (&x, &sparc_tls_symbol_ref_1, 0);
}
/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
this (thread-local) address. */
......@@ -3219,7 +3249,7 @@ legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, enum machine_mode mode)
if (x != orig_x && legitimate_address_p (mode, x, FALSE))
return x;
if (tls_symbolic_operand (x))
if (SPARC_SYMBOL_REF_TLS_P (x))
x = legitimize_tls_address (x);
else if (flag_pic)
x = legitimize_pic_address (x, mode, 0);
......
......@@ -2358,6 +2358,9 @@ extern int sparc_indent_opcode;
sparc_output_dwarf_dtprel (FILE, SIZE, X)
#endif
#define SPARC_SYMBOL_REF_TLS_P(RTX) \
(GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0)
#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
((CHAR) == '#' || (CHAR) == '*' || (CHAR) == '(' \
|| (CHAR) == ')' || (CHAR) == '_' || (CHAR) == '&')
......
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