OSDN Git Service

PR target/21412
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 25 May 2005 07:04:04 +0000 (07:04 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 25 May 2005 07:04:04 +0000 (07:04 +0000)
* 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

gcc/ChangeLog
gcc/config/sparc/predicates.md
gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h

index 01d57e2..d6aa061 100644 (file)
@@ -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.
index 752286c..a0e9b04 100644 (file)
 ;; 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.
index a29bd69..9c1e372 100644 (file)
@@ -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);
index af920b3..1958f3f 100644 (file)
@@ -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);
index 0e0aea2..9fcee12 100644 (file)
@@ -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) == '&')