OSDN Git Service

* config/alpha/alpha.c (SYMBOL_FLAG_NEAR, SYMBOL_FLAG_SAMEGP): New.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Apr 2003 19:34:02 +0000 (19:34 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Apr 2003 19:34:02 +0000 (19:34 +0000)
        (samegp_function_operand): Use SYMBOL_FLAG_SAMEGP.
        (direct_call_operand): Use SYMBOL_FLAG_NEAR.
        (local_symbolic_operand): Use SYMBOL_REF_LOCAL_P.
        (small_symbolic_operand): Use SYMBOL_REF_SMALL_P.
        (global_symbolic_operand): Similarly.
        (tls_symbolic_operand_1): Use SYMBOL_REF_TLS_MODEL.
        (tls_symbolic_operand_type): Likewise.
        (alpha_encode_section_info): Use default_encode_section_info.
        (alpha_strip_name_encoding): Remove.
        (get_tls_get_addr): Split out from ...
        (alpha_legitimize_address): ... here.
        (alpha_emit_xfloating_libcall): Use init_one_libfunc.
        (get_some_local_dynamic_name_1): Use SYMBOL_REF_TLS_MODEL.
        (alpha_initialize_trampoline): Use init_one_libfunc.
        (alpha_setup_incoming_varargs): Mark unused parameters.
        (alpha_initial_elimination_offset): Likewise.
        (alpha_end_function): Use SYMBOL_FLAG_NEAR, SYMBOL_FLAG_SAMEGP.
        (unicosmk_unique_section): Use default_strip_name_encoding.
        (unicosmk_ssib_name, unicosmk_output_externs): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@65696 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/alpha/alpha.c

index 898b353..7812d84 100644 (file)
@@ -1,3 +1,26 @@
+2003-04-16  Richard Henderson  <rth@redhat.com>
+
+       * config/alpha/alpha.c (SYMBOL_FLAG_NEAR, SYMBOL_FLAG_SAMEGP): New.
+       (samegp_function_operand): Use SYMBOL_FLAG_SAMEGP.
+       (direct_call_operand): Use SYMBOL_FLAG_NEAR.
+       (local_symbolic_operand): Use SYMBOL_REF_LOCAL_P.
+       (small_symbolic_operand): Use SYMBOL_REF_SMALL_P.
+       (global_symbolic_operand): Similarly.
+       (tls_symbolic_operand_1): Use SYMBOL_REF_TLS_MODEL.
+       (tls_symbolic_operand_type): Likewise.
+       (alpha_encode_section_info): Use default_encode_section_info.
+       (alpha_strip_name_encoding): Remove.
+       (get_tls_get_addr): Split out from ...
+       (alpha_legitimize_address): ... here.
+       (alpha_emit_xfloating_libcall): Use init_one_libfunc.
+       (get_some_local_dynamic_name_1): Use SYMBOL_REF_TLS_MODEL.
+       (alpha_initialize_trampoline): Use init_one_libfunc.
+       (alpha_setup_incoming_varargs): Mark unused parameters.
+       (alpha_initial_elimination_offset): Likewise.
+       (alpha_end_function): Use SYMBOL_FLAG_NEAR, SYMBOL_FLAG_SAMEGP.
+       (unicosmk_unique_section): Use default_strip_name_encoding.
+       (unicosmk_ssib_name, unicosmk_output_externs): Likewise.
+
 2003-04-16  Aldy Hernandez  <aldyh@redhat.com>
 
         * config.gcc: Add t-spe for eabispe.
index cfc3fc5..4d5be29 100644 (file)
@@ -171,6 +171,10 @@ static struct alpha_rtx_cost_data const alpha_rtx_cost_data[PROCESSOR_MAX] =
   },
 };
 
+/* Machine-specific symbol_ref flags.  */
+#define SYMBOL_FLAG_NEAR       (SYMBOL_FLAG_MACH_DEP << 0)
+#define SYMBOL_FLAG_SAMEGP     (SYMBOL_FLAG_MACH_DEP << 1)
+
 /* Declarations of static functions.  */
 static bool alpha_function_ok_for_sibcall
   PARAMS ((tree, tree));
@@ -186,8 +190,8 @@ static bool alpha_in_small_data_p
   PARAMS ((tree));
 static void alpha_encode_section_info
   PARAMS ((tree, int));
-static const char *alpha_strip_name_encoding
-  PARAMS ((const char *));
+static rtx get_tls_get_addr
+  PARAMS ((void));
 static int some_small_symbolic_operand_1
   PARAMS ((rtx *, void *));
 static int split_small_symbolic_operand_1
@@ -299,8 +303,6 @@ static void vms_asm_out_destructor PARAMS ((rtx, int));
 #define TARGET_IN_SMALL_DATA_P alpha_in_small_data_p
 #undef TARGET_ENCODE_SECTION_INFO
 #define TARGET_ENCODE_SECTION_INFO alpha_encode_section_info
-#undef TARGET_STRIP_NAME_ENCODING
-#define TARGET_STRIP_NAME_ENCODING alpha_strip_name_encoding
 
 #if TARGET_ABI_UNICOSMK
 static void unicosmk_asm_named_section PARAMS ((const char *, unsigned int));
@@ -1051,7 +1053,7 @@ samegp_function_operand (op, mode)
 
   /* Otherwise, encode_section_info recorded whether we are to treat
      this symbol as having the same GP.  */
-  return SYMBOL_REF_FLAG (op);
+  return (SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_SAMEGP) != 0;
 }
 
 /* Return 1 if OP is a SYMBOL_REF for which we can make a call via bsr.  */
@@ -1061,6 +1063,8 @@ direct_call_operand (op, mode)
      rtx op;
      enum machine_mode mode;
 {
+  bool is_near;
+
   /* Must share the same GP.  */
   if (!samegp_function_operand (op, mode))
     return 0;
@@ -1075,14 +1079,16 @@ direct_call_operand (op, mode)
   if (!TARGET_PROFILING_NEEDS_GP && profile_flag)
     return 0;
 
+  is_near = (SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_NEAR) != 0;
+
   /* Must be "near" so that the branch is assumed to reach.  With
      -msmall-text, this is true of all local symbols.  */
   if (TARGET_SMALL_TEXT)
-    return op->jump;
+    return is_near;
 
   /* Otherwise, a decl is "near" if it is defined in the same section.
      See alpha_encode_section_info for commentary.  */
-  return op->jump && decl_in_text_section (cfun->decl);
+  return is_near && decl_in_text_section (cfun->decl);
 }
 
 /* Return true if OP is a LABEL_REF, or SYMBOL_REF or CONST referencing
@@ -1093,8 +1099,6 @@ local_symbolic_operand (op, mode)
      rtx op;
      enum machine_mode mode;
 {
-  const char *str;
-
   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
     return 0;
 
@@ -1109,26 +1113,7 @@ local_symbolic_operand (op, mode)
   if (GET_CODE (op) != SYMBOL_REF)
     return 0;
 
-  /* Easy pickings.  */
-  if (CONSTANT_POOL_ADDRESS_P (op) || STRING_POOL_ADDRESS_P (op))
-    return 1;
-
-  /* ??? SYMBOL_REF_FLAG is set for local function symbols, but we
-     run into problems with the rtl inliner in that the symbol was
-     once external, but is local after inlining, which results in
-     unrecognizable insns.  */
-
-  str = XSTR (op, 0);
-
-  /* If @[LS], then alpha_encode_section_info sez it's local.  */
-  if (str[0] == '@' && (str[1] == 'L' || str[1] == 'S'))
-    return 1;
-
-  /* If *$, then ASM_GENERATE_INTERNAL_LABEL sez it's local.  */
-  if (str[0] == '*' && str[1] == '$')
-    return 1;
-
-  return 0;
+  return SYMBOL_REF_LOCAL_P (op) && !SYMBOL_REF_TLS_MODEL (op);
 }
 
 /* Return true if OP is a SYMBOL_REF or CONST referencing a variable
@@ -1139,8 +1124,6 @@ small_symbolic_operand (op, mode)
      rtx op;
      enum machine_mode mode ATTRIBUTE_UNUSED;
 {
-  const char *str;
-
   if (! TARGET_SMALL_DATA)
     return 0;
 
@@ -1155,13 +1138,14 @@ small_symbolic_operand (op, mode)
   if (GET_CODE (op) != SYMBOL_REF)
     return 0;
 
+  /* ??? There's no encode_section_info equivalent for the rtl
+     constant pool, so SYMBOL_FLAG_SMALL never gets set.  */
   if (CONSTANT_POOL_ADDRESS_P (op))
     return GET_MODE_SIZE (get_pool_mode (op)) <= (unsigned) g_switch_value;
-  else
-    {
-      str = XSTR (op, 0);
-      return str[0] == '@' && str[1] == 'S';
-    }
+
+  return (SYMBOL_REF_LOCAL_P (op)
+         && SYMBOL_REF_SMALL_P (op)
+         && SYMBOL_REF_TLS_MODEL (op) == 0);
 }
 
 /* Return true if OP is a SYMBOL_REF or CONST referencing a variable
@@ -1172,8 +1156,6 @@ global_symbolic_operand (op, mode)
      rtx op;
      enum machine_mode mode;
 {
-  const char *str;
-
   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
     return 0;
 
@@ -1185,12 +1167,7 @@ global_symbolic_operand (op, mode)
   if (GET_CODE (op) != SYMBOL_REF)
     return 0;
 
-  if (local_symbolic_operand (op, mode))
-    return 0;
-
-  /* Also verify that it's not a TLS symbol.  */
-  str = XSTR (op, 0);
-  return str[0] != '%' && str[0] != '@';
+  return !SYMBOL_REF_LOCAL_P (op) && !SYMBOL_REF_TLS_MODEL (op);
 }
 
 /* Return 1 if OP is a valid operand for the MEM of a CALL insn.  */
@@ -1251,8 +1228,6 @@ tls_symbolic_operand_1 (op, mode, size, unspec)
      enum machine_mode mode;
      int size, unspec;
 {
-  const char *str;
-
   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
     return 0;
 
@@ -1266,29 +1241,26 @@ tls_symbolic_operand_1 (op, mode, size, unspec)
 
   if (GET_CODE (op) != SYMBOL_REF)
     return 0;
-  str = XSTR (op, 0);
 
-  if (str[0] == '%')
+  if (SYMBOL_REF_LOCAL_P (op))
     {
-      if (size != 64)
+      if (alpha_tls_size > size)
        return 0;
     }
-  else if (str[0] == '@')
+  else
     {
-      if (alpha_tls_size > size)
+      if (size != 64)
        return 0;
     }
-  else
-    return 0;
 
-  switch (str[1])
+  switch (SYMBOL_REF_TLS_MODEL (op))
     {
-    case 'D':
+    case TLS_MODEL_LOCAL_DYNAMIC:
       return unspec == UNSPEC_DTPREL;
-    case 'T':
+    case TLS_MODEL_INITIAL_EXEC:
       return unspec == UNSPEC_TPREL && size == 64;
-    case 't':
-      return unspec == UNSPEC_TPREL && size < 64;
+    case TLS_MODEL_LOCAL_EXEC:
+      return unspec == UNSPEC_TPREL;
     default:
       abort ();
     }
@@ -1833,42 +1805,18 @@ static enum tls_model
 tls_symbolic_operand_type (symbol)
      rtx symbol;
 {
-  const char *str;
+  enum tls_model model;
 
   if (GET_CODE (symbol) != SYMBOL_REF)
     return 0;
-  str = XSTR (symbol, 0);
+  model = SYMBOL_REF_TLS_MODEL (symbol);
 
-  if (str[0] == '%')
-    {
-      /* ??? Be prepared for -ftls-model=local-dynamic.  Perhaps we shouldn't
-        have separately encoded local-ness.  On well, maybe the user will use
-        attribute visibility next time.  At least we don't crash...  */
-      if (str[1] == 'G' || str[1] == 'D')
-       return TLS_MODEL_GLOBAL_DYNAMIC;
-      if (str[1] == 'T')
-       return TLS_MODEL_INITIAL_EXEC;
-    }
-  else if (str[0] == '@')
-    {
-      if (str[1] == 'D')
-       {
-         /* Local dynamic is a waste if we're not going to combine
-            the __tls_get_addr calls.  So avoid it if not optimizing.  */
-         if (optimize)
-           return TLS_MODEL_LOCAL_DYNAMIC;
-         else
-           return TLS_MODEL_GLOBAL_DYNAMIC;
-       }
-      if (str[1] == 'T')
-       return TLS_MODEL_INITIAL_EXEC;
-      if (str[1] == 't')
-       return TLS_MODEL_LOCAL_EXEC;
-    }
+  /* Local-exec with a 64-bit size is the same code as initial-exec.  */
+  if (model == TLS_MODEL_LOCAL_EXEC && alpha_tls_size == 64)
+    model = TLS_MODEL_INITIAL_EXEC;
 
-  return 0;
+  return model;
 }
-
 \f
 /* Return true if the function DECL will be placed in the default text
    section.  */
@@ -1952,33 +1900,21 @@ alpha_in_small_data_p (exp)
 static void
 alpha_encode_section_info (decl, first)
      tree decl;
-     int first ATTRIBUTE_UNUSED;
+     int first;
 {
-  const char *symbol_str;
-  bool is_local;
-  char encoding = 0;
-  rtx rtl, symbol;
-
-  rtl = DECL_P (decl) ? DECL_RTL (decl) : TREE_CST_RTL (decl);
-
-  /* Careful not to prod global register variables.  */
-  if (GET_CODE (rtl) != MEM)
-    return;
-  symbol = XEXP (rtl, 0);
-  if (GET_CODE (symbol) != SYMBOL_REF)
-    return;
-
-  /* A variable is considered "local" if it is defined in this module.  */
-  is_local = (*targetm.binds_local_p) (decl);
-    
+  default_encode_section_info (decl, first);
   if (TREE_CODE (decl) == FUNCTION_DECL)
     {
+      rtx symbol = XEXP (DECL_RTL (decl), 0);
+      int flags = SYMBOL_REF_FLAGS (symbol);
+
       /* Mark whether the decl is "near" in distance.  If -msmall-text is
         in effect, this is trivially true of all local symbols.  */
       if (TARGET_SMALL_TEXT)
        {
-         if (is_local)
-           symbol->jump = 1;
+         if (flags & SYMBOL_FLAG_LOCAL)
+           flags |= SYMBOL_FLAG_NEAR;
        }
       else
        {
@@ -1991,92 +1927,20 @@ alpha_encode_section_info (decl, first)
 
             Delay marking public functions until they are emitted; otherwise
             we don't know that they exist in this unit of translation.  */
+         /* Now we *DO* have access to SYMBOL_REF_DECL.  Fixme.  */
          if (!TREE_PUBLIC (decl) && decl_in_text_section (decl))
-            symbol->jump = 1;
+            flags |= SYMBOL_FLAG_NEAR;
        }
 
       /* Indicate whether the target function shares the same GP as any
         function emitted in this unit of translation.  */
       if (decl_has_samegp (decl))
-       SYMBOL_REF_FLAG (symbol) = 1;
-      return;
-    }
-
-  /* Early out if we're not going to do anything with this data.  */
-  if (! TARGET_EXPLICIT_RELOCS)
-    return;
+       flags |= SYMBOL_FLAG_SAMEGP;
 
-  symbol_str = XSTR (symbol, 0);
-
-  /* Care for TLS variables.  */
-  if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL (decl))
-    {
-      switch (decl_tls_model (decl))
-       {
-       case TLS_MODEL_GLOBAL_DYNAMIC:
-         encoding = 'G';
-         break;
-       case TLS_MODEL_LOCAL_DYNAMIC:
-         encoding = 'D';
-         break;
-       case TLS_MODEL_INITIAL_EXEC:
-         encoding = 'T';
-         break;
-       case TLS_MODEL_LOCAL_EXEC:
-         encoding = (alpha_tls_size == 64 ? 'T' : 't');
-         break;
-       }
-    }
-  else if (is_local)
-    {
-      /* Determine if DECL will wind up in .sdata/.sbss.  */
-      if (alpha_in_small_data_p (decl))
-       encoding = 'S';
-      else
-       encoding = 'L';
-    }
-
-  /* Finally, encode this into the symbol string.  */
-  if (encoding)
-    {
-      char *newstr;
-      size_t len;
-      char want_prefix = (is_local ? '@' : '%');
-      char other_prefix = (is_local ? '%' : '@');
-
-      if (symbol_str[0] == want_prefix)
-       {
-         if (symbol_str[1] == encoding)
-           return;
-         symbol_str += 2;
-       }
-      else if (symbol_str[0] == other_prefix)
-       symbol_str += 2;
-
-      len = strlen (symbol_str) + 1;
-      newstr = alloca (len + 2);
-
-      newstr[0] = want_prefix;
-      newstr[1] = encoding;
-      memcpy (newstr + 2, symbol_str, len);
-         
-      XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2 - 1);
+      SYMBOL_REF_FLAGS (symbol) = flags;
     }
 }
 
-/* Undo the effects of the above.  */
-
-static const char *
-alpha_strip_name_encoding (str)
-     const char *str;
-{
-  if (str[0] == '@' || str[0] == '%')
-    str += 2;
-  if (str[0] == '*')
-    str++;
-  return str;
-}
-
 #if TARGET_ABI_OPEN_VMS
 static bool
 alpha_linkage_symbol_p (symname)
@@ -2208,6 +2072,18 @@ alpha_legitimate_address_p (mode, x, strict)
   return false;
 }
 
+/* Build the SYMBOL_REF for __tls_get_addr.  */
+
+static GTY(()) rtx tls_get_addr_libfunc;
+
+static rtx
+get_tls_get_addr ()
+{
+  if (!tls_get_addr_libfunc)
+    tls_get_addr_libfunc = init_one_libfunc ("__tls_get_addr");
+  return tls_get_addr_libfunc;
+}
+
 /* Try machine-dependent ways of modifying an illegitimate address
    to be legitimate.  If we find one, return the new, valid address.  */
 
@@ -2275,7 +2151,7 @@ alpha_legitimize_address (x, scratch, mode)
 
          r0 = gen_rtx_REG (Pmode, 0);
          r16 = gen_rtx_REG (Pmode, 16);
-         tga = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_addr");
+         tga = get_tls_get_addr ();
          dest = gen_reg_rtx (Pmode);
          seq = GEN_INT (alpha_next_sequence_number++);
          
@@ -2296,7 +2172,7 @@ alpha_legitimize_address (x, scratch, mode)
 
          r0 = gen_rtx_REG (Pmode, 0);
          r16 = gen_rtx_REG (Pmode, 16);
-         tga = gen_rtx_SYMBOL_REF (Pmode, "__tls_get_addr");
+         tga = get_tls_get_addr ();
          scratch = gen_reg_rtx (Pmode);
          seq = GEN_INT (alpha_next_sequence_number++);
 
@@ -4233,7 +4109,7 @@ alpha_emit_xfloating_libcall (func, target, operands, noperands, equiv)
       abort ();
     }
 
-  tmp = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, (char *) func));
+  tmp = gen_rtx_MEM (QImode, init_one_libfunc (func));
   tmp = emit_call_insn (GEN_CALL_VALUE (reg, tmp, const0_rtx,
                                        const0_rtx, const0_rtx));
   CALL_INSN_FUNCTION_USAGE (tmp) = usage;
@@ -5861,14 +5737,11 @@ get_some_local_dynamic_name_1 (px, data)
 {
   rtx x = *px;
 
-  if (GET_CODE (x) == SYMBOL_REF)
+  if (GET_CODE (x) == SYMBOL_REF
+      && SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
     {
-      const char *str = XSTR (x, 0);
-      if (str[0] == '@' && str[1] == 'D')
-       {
-          cfun->machine->some_ld_name = str;
-          return 1;
-       }
+      cfun->machine->some_ld_name = XSTR (x, 0);
+      return 1;
     }
 
   return 0;
@@ -6389,7 +6262,7 @@ alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs)
     }
 
 #ifdef TRANSFER_FROM_TRAMPOLINE
-  emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__enable_execute_stack"),
+  emit_library_call (init_one_libfunc ("__enable_execute_stack"),
                     0, VOIDmode, 1, tramp, Pmode);
 #endif
 
@@ -6576,8 +6449,8 @@ alpha_build_va_list ()
 void   
 alpha_setup_incoming_varargs(cum, mode, type, pretend_size, no_rtl)
      CUMULATIVE_ARGS cum;
-     enum machine_mode mode;
-     tree type;
+     enum machine_mode mode ATTRIBUTE_UNUSED;
+     tree type ATTRIBUTE_UNUSED;
      int *pretend_size;
      int no_rtl;
 {
@@ -7254,8 +7127,8 @@ alpha_sa_size ()
    and the other its replacement, at the start of a routine.  */
 
 HOST_WIDE_INT
-alpha_initial_elimination_offset(from, to)
-     unsigned int from, to;
+alpha_initial_elimination_offset (from, to)
+     unsigned int from, to ATTRIBUTE_UNUSED;
 {
   HOST_WIDE_INT ret;
 
@@ -8217,16 +8090,19 @@ alpha_end_function (file, fnname, decl)
   if ((*targetm.binds_local_p) (decl))
     {
       rtx symbol = XEXP (DECL_RTL (decl), 0);
+      int flags = SYMBOL_REF_FLAGS (symbol);
 
       /* Mark whether the decl is "near".  See the commentary in 
         alpha_encode_section_info wrt the .text section.  */
       if (decl_in_text_section (decl))
-       symbol->jump = 1;
+       flags |= SYMBOL_FLAG_NEAR;
 
       /* Mark whether the decl shares a GP with other functions
         in this unit of translation.  This is trivially true of
         local symbols.  */
-      SYMBOL_REF_FLAG (symbol) = 1;
+      flags |= SYMBOL_FLAG_SAMEGP;
+
+      SYMBOL_REF_FLAGS (symbol) = flags;
     }
 
   /* Output jump tables and the static subroutine information block.  */
@@ -9940,7 +9816,7 @@ unicosmk_unique_section (decl, reloc)
     abort ();
 
   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-  name = alpha_strip_name_encoding (name);
+  name = default_strip_name_encoding (name);
   len = strlen (name);
 
   if (TREE_CODE (decl) == FUNCTION_DECL)
@@ -10171,7 +10047,7 @@ unicosmk_ssib_name ()
   x = XEXP (x, 0);
   if (GET_CODE (x) != SYMBOL_REF)
     abort ();
-  fnname = alpha_strip_name_encoding (XSTR (x, 0));
+  fnname = default_name_encoding (XSTR (x, 0));
 
   len = strlen (fnname);
   if (len + SSIB_PREFIX_LEN > 255)
@@ -10347,7 +10223,7 @@ unicosmk_output_externs (file)
       /* We have to strip the encoding and possibly remove user_label_prefix 
         from the identifier in order to handle -fleading-underscore and
         explicit asm names correctly (cf. gcc.dg/asm-names-1.c).  */
-      real_name = alpha_strip_name_encoding (p->name);
+      real_name = default_strip_name_encoding (p->name);
       if (len && p->name[0] == '*'
          && !memcmp (real_name, user_label_prefix, len))
        real_name += len;