diff gcc/config/sparc/sparc.c @ 47:3bfb6c00c1e0

update it from 4.4.2 to 4.4.3.
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Sun, 07 Feb 2010 17:44:34 +0900
parents a06113de4d67
children 77e2b8dfacca
line wrap: on
line diff
--- a/gcc/config/sparc/sparc.c	Sun Feb 07 17:43:48 2010 +0900
+++ b/gcc/config/sparc/sparc.c	Sun Feb 07 17:44:34 2010 +0900
@@ -412,6 +412,9 @@
 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 bool sparc_pass_by_reference (CUMULATIVE_ARGS *,
 				     enum machine_mode, const_tree, bool);
 static int sparc_arg_partial_bytes (CUMULATIVE_ARGS *,
@@ -986,34 +989,17 @@
   /* Fixup TLS cases.  */
   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;
-    }
- 
+      operands[1] = legitimize_tls_address (operands[1]);
+      return false;
+    }
+
   /* Fixup PIC cases.  */
   if (flag_pic && CONSTANT_P (operands[1]))
     {
       if (pic_address_needs_scratch (operands[1]))
-	operands[1] = legitimize_pic_address (operands[1], mode, 0);
+	operands[1] = 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,10 +1027,8 @@
       if (symbolic_operand (operands[1], mode))
 	{
 	  operands[1] = legitimize_pic_address (operands[1],
-						mode,
-						(reload_in_progress ?
-						 operands[0] :
-						 NULL_RTX));
+						reload_in_progress
+						? operands[0] : NULL_RTX);
 	  return false;
 	}
     }
@@ -2865,23 +2849,11 @@
 bool
 legitimate_constant_p (rtx x)
 {
-  rtx inner;
-
   switch (GET_CODE (x))
     {
+    case CONST:
     case SYMBOL_REF:
-      /* TLS symbols are not constant.  */
-      if (SYMBOL_REF_TLS_MODEL (x))
-	return false;
-      break;
-
-    case CONST:
-      inner = XEXP (x, 0);
-
-      /* Offsets of TLS symbols are never valid.
-	 Discourage CSE from creating them.  */
-      if (GET_CODE (inner) == PLUS
-	  && SPARC_SYMBOL_REF_TLS_P (XEXP (inner, 0)))
+      if (sparc_tls_referenced_p (x))
 	return false;
       break;
 
@@ -2948,10 +2920,7 @@
 {
   if (pic_address_needs_scratch (x))
     return false;
-  if (SPARC_SYMBOL_REF_TLS_P (x)
-      || (GET_CODE (x) == CONST
-	  && GET_CODE (XEXP (x, 0)) == PLUS
-	  && SPARC_SYMBOL_REF_TLS_P (XEXP (XEXP (x, 0), 0))))
+  if (sparc_tls_referenced_p (x))
     return false;
   return true;
 }
@@ -2989,7 +2958,7 @@
 	   && GET_CODE (rs2) != SUBREG
 	   && GET_CODE (rs2) != LO_SUM
 	   && GET_CODE (rs2) != MEM
-	   && ! SPARC_SYMBOL_REF_TLS_P (rs2)
+	   && !(GET_CODE (rs2) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (rs2))
 	   && (! symbolic_operand (rs2, VOIDmode) || mode == Pmode)
 	   && (GET_CODE (rs2) != CONST_INT || SMALL_INT (rs2)))
 	  || ((REG_P (rs1)
@@ -3029,7 +2998,8 @@
 	  rs2 = NULL;
 	  imm1 = XEXP (rs1, 1);
 	  rs1 = XEXP (rs1, 0);
-	  if (! CONSTANT_P (imm1) || SPARC_SYMBOL_REF_TLS_P (rs1))
+	  if (!CONSTANT_P (imm1)
+	      || (GET_CODE (rs1) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (rs1)))
 	    return 0;
 	}
     }
@@ -3038,7 +3008,8 @@
       rs1 = XEXP (addr, 0);
       imm1 = XEXP (addr, 1);
 
-      if (! CONSTANT_P (imm1) || SPARC_SYMBOL_REF_TLS_P (rs1))
+      if (!CONSTANT_P (imm1)
+	  || (GET_CODE (rs1) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (rs1)))
 	return 0;
 
       /* We can't allow TFmode in 32-bit mode, because an offset greater
@@ -3114,29 +3085,28 @@
   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
+/* Return true if X contains a thread-local symbol.  */
+
+static bool
 sparc_tls_referenced_p (rtx x)
 {
   if (!TARGET_HAVE_TLS)
     return false;
 
-  return for_each_rtx (&x, &sparc_tls_symbol_ref_1, 0);
+  if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS)
+    x = XEXP (XEXP (x, 0), 0);
+
+  if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x))
+    return true;
+
+  /* That's all we handle in legitimize_tls_address for now.  */
+  return false;
 }
 
 /* ADDR contains a thread-local SYMBOL_REF.  Generate code to compute
    this (thread-local) address.  */
 
-rtx
+static rtx
 legitimize_tls_address (rtx addr)
 {
   rtx temp1, temp2, temp3, ret, o0, got, insn;
@@ -3260,21 +3230,34 @@
 	gcc_unreachable ();
       }
 
+  else if (GET_CODE (addr) == CONST)
+    {
+      rtx base, offset;
+
+      gcc_assert (GET_CODE (XEXP (addr, 0)) == PLUS);
+
+      base = legitimize_tls_address (XEXP (XEXP (addr, 0), 0));
+      offset = XEXP (XEXP (addr, 0), 1);
+
+      base = force_operand (base, NULL_RTX);
+      if (!(GET_CODE (offset) == CONST_INT && SMALL_INT (offset)))
+	offset = force_reg (Pmode, offset);
+      ret = gen_rtx_PLUS (Pmode, base, offset);
+    }
+
   else
     gcc_unreachable ();  /* for now ... */
 
   return ret;
 }
 
-
 /* Legitimize PIC addresses.  If the address is already position-independent,
    we return ORIG.  Newly generated position-independent addresses go into a
    reg.  This is REG if nonzero, otherwise we allocate register(s) as
    necessary.  */
 
-rtx
-legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
-			rtx reg)
+static rtx
+legitimize_pic_address (rtx orig, rtx reg)
 {
   if (GET_CODE (orig) == SYMBOL_REF
       /* See the comment in sparc_expand_move.  */
@@ -3341,9 +3324,9 @@
 	}
 
       gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
-      base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
-      offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
-			 	       base == reg ? 0 : reg);
+      base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), reg);
+      offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
+			 	       base == reg ? NULL_RTX : reg);
 
       if (GET_CODE (offset) == CONST_INT)
 	{
@@ -3395,10 +3378,10 @@
   if (x != orig_x && legitimate_address_p (mode, x, FALSE))
     return x;
 
-  if (SPARC_SYMBOL_REF_TLS_P (x))
+  if (sparc_tls_referenced_p (x))
     x = legitimize_tls_address (x);
   else if (flag_pic)
-    x = legitimize_pic_address (x, mode, 0);
+    x = 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)));
@@ -3407,8 +3390,9 @@
 		      copy_to_mode_reg (Pmode, XEXP (x, 0)));
   else if (GET_CODE (x) == SYMBOL_REF
 	   || GET_CODE (x) == CONST
-           || GET_CODE (x) == LABEL_REF)
+	   || GET_CODE (x) == LABEL_REF)
     x = copy_to_suggested_reg (x, NULL_RTX, Pmode);
+
   return x;
 }
 
@@ -8758,7 +8742,7 @@
 	  /* Delay emitting the PIC helper function because it needs to
 	     change the section and we are emitting assembly code.  */
 	  load_pic_register (true);  /* clobbers %o7 */
-	  scratch = legitimize_pic_address (funexp, Pmode, scratch);
+	  scratch = legitimize_pic_address (funexp, scratch);
 	  seq = get_insns ();
 	  end_sequence ();
 	  emit_and_preserve (seq, spill_reg, spill_reg2);