summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2005-05-25 07:04:04 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2005-05-25 07:04:04 +0000
commit76d4bacb4f5fd50773dce38c67fd4b889bb3f71c (patch)
tree484e1f45bb64046a2af02ae5b5edc1eb51ecbfca /gcc
parent9b2d6d13808845e60fdd0047dcf2b626c641f75d (diff)
downloadgcc-76d4bacb4f5fd50773dce38c67fd4b889bb3f71c.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@100137 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/config/sparc/predicates.md8
-rw-r--r--gcc/config/sparc/sparc-protos.h2
-rw-r--r--gcc/config/sparc/sparc.c70
-rw-r--r--gcc/config/sparc/sparc.h3
5 files changed, 79 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 01d57e2da3d..d6aa061f637 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+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.
diff --git a/gcc/config/sparc/predicates.md b/gcc/config/sparc/predicates.md
index 752286cb184..a0e9b04fad3 100644
--- a/gcc/config/sparc/predicates.md
+++ b/gcc/config/sparc/predicates.md
@@ -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.
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
index a29bd691509..9c1e3721b72 100644
--- a/gcc/config/sparc/sparc-protos.h
+++ b/gcc/config/sparc/sparc-protos.h
@@ -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);
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index af920b30734..1958f3f3982 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -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);
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 0e0aea211ff..9fcee127385 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -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) == '&')