]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/varasm.c
c-pragma.h: Define HANDLE_GENERIC_PRAGMAS if REGISTER_TARGET_PRAGMAS is defined.
[gcc.git] / gcc / varasm.c
index 87506a48870b0aef9c808ee75c49cc4d5628b0d7..5a10d65687fdd0b3a2b7788e57a9151a7b621db0 100644 (file)
@@ -156,7 +156,7 @@ static void decode_addr_const               PARAMS ((tree, struct addr_const *));
 static int const_hash                  PARAMS ((tree));
 static int compare_constant            PARAMS ((tree,
                                               struct constant_descriptor *));
-static char *compare_constant_1                PARAMS ((tree, char *));
+static const unsigned char *compare_constant_1  PARAMS ((tree, const unsigned char *));
 static struct constant_descriptor *record_constant PARAMS ((tree));
 static void record_constant_1          PARAMS ((tree));
 static tree copy_constant              PARAMS ((tree));
@@ -175,7 +175,7 @@ static int output_addressed_constants       PARAMS ((tree));
 static void output_after_function_constants PARAMS ((void));
 static void output_constructor         PARAMS ((tree, int));
 #ifdef ASM_WEAKEN_LABEL
-static void remove_from_pending_weak_list      PARAMS ((char *));
+static void remove_from_pending_weak_list      PARAMS ((const char *));
 #endif
 #ifdef ASM_OUTPUT_BSS
 static void asm_output_bss             PARAMS ((FILE *, tree, const char *, int, int));
@@ -519,8 +519,27 @@ void
 make_function_rtl (decl)
      tree decl;
 {
-  char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-  char *new_name = name;
+  const char *name;
+  const char *new_name;
+
+  if (DECL_RTL (decl) != 0)
+    {
+      /* ??? Another way to do this would be to do what halfpic.c does
+        and maintain a hashed table of such critters.  */
+      /* ??? Another way to do this would be to pass a flag bit to
+        ENCODE_SECTION_INFO saying whether this is a new decl or not.  */
+      /* Let the target reassign the RTL if it wants.
+        This is necessary, for example, when one machine specific
+        decl attribute overrides another.  */
+#ifdef REDO_SECTION_INFO_P
+      if (REDO_SECTION_INFO_P (decl))
+       ENCODE_SECTION_INFO (decl);
+#endif
+      return;
+    }
+
+  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+  new_name = name;
 
   /* Rename a nested function to avoid conflicts, unless it's a member of
      a local class, in which case the class name is already unique.  */
@@ -530,59 +549,45 @@ make_function_rtl (decl)
       && DECL_RTL (decl) == 0)
     {
       char *label;
-
-      name = IDENTIFIER_POINTER (DECL_NAME (decl));
       ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
-      name = ggc_alloc_string (label, -1);
       var_labelno++;
+      new_name = label;
     }
-  else
+  /* When -fprefix-function-name is used, every function name is
+     prefixed.  Even static functions are prefixed because they
+     could be declared latter.  Note that a nested function name
+     is not prefixed.  */
+  else if (flag_prefix_function_name)
     {
-      /* When -fprefix-function-name is used, every function name is
-         prefixed.  Even static functions are prefixed because they
-         could be declared latter.  Note that a nested function name
-         is not prefixed.  */
-      if (flag_prefix_function_name)
-        {
-         size_t name_len = strlen (name);
+      size_t name_len = IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl));
+      char *pname;
 
-          new_name = ggc_alloc_string (NULL, name_len + CHKR_PREFIX_SIZE);
-         memcpy (new_name, CHKR_PREFIX, CHKR_PREFIX_SIZE);
-         memcpy (new_name + CHKR_PREFIX_SIZE, name, name_len + 1);
-          name = new_name;
-        }
+      pname = alloca (name_len + CHKR_PREFIX_SIZE + 1);
+      memcpy (pname, CHKR_PREFIX, CHKR_PREFIX_SIZE);
+      memcpy (pname + CHKR_PREFIX_SIZE, name, name_len + 1);
+      new_name = pname;
     }
 
-  if (DECL_RTL (decl) == 0)
+  if (name != new_name)
     {
-      DECL_ASSEMBLER_NAME (decl) = get_identifier (name);
-      DECL_RTL (decl)
-       = gen_rtx_MEM (DECL_MODE (decl),
-                      gen_rtx_SYMBOL_REF (Pmode, name));
-
-      /* Optionally set flags or add text to the name to record information
-        such as that it is a function name.  If the name is changed, the macro
-        ASM_OUTPUT_LABELREF will have to know how to strip this information.  */
-#ifdef ENCODE_SECTION_INFO
-      ENCODE_SECTION_INFO (decl);
-#endif
+      DECL_ASSEMBLER_NAME (decl) = get_identifier (new_name);
+      name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
     }
-  else
-    {
-      /* ??? Another way to do this would be to do what halfpic.c does
-        and maintain a hashed table of such critters.  */
-      /* ??? Another way to do this would be to pass a flag bit to
-        ENCODE_SECTION_INFO saying whether this is a new decl or not.  */
-      /* Let the target reassign the RTL if it wants.
-        This is necessary, for example, when one machine specific
-        decl attribute overrides another.  */
-#ifdef REDO_SECTION_INFO_P
-      if (REDO_SECTION_INFO_P (decl))
-       ENCODE_SECTION_INFO (decl);
+
+  DECL_RTL (decl)
+    = gen_rtx_MEM (DECL_MODE (decl),
+                  gen_rtx_SYMBOL_REF (Pmode, name));
+
+  /* Optionally set flags or add text to the name to record
+     information such as that it is a function name.  If the name
+     is changed, the macro ASM_OUTPUT_LABELREF will have to know
+     how to strip this information.  */
+#ifdef ENCODE_SECTION_INFO
+  ENCODE_SECTION_INFO (decl);
 #endif
-    }
 }
 
+
 /* Given NAME, a putative register name, discard any customary prefixes.  */
 
 static const char *
@@ -640,7 +645,7 @@ decode_reg_name (asmspec)
        static struct { const char *name; int number; } table[]
          = ADDITIONAL_REGISTER_NAMES;
 
-       for (i = 0; i < (int)(sizeof (table) / sizeof (table[0])); i++)
+       for (i = 0; i < (int) ARRAY_SIZE (table); i++)
          if (! strcmp (asmspec, table[i].name))
            return table[i].number;
       }
@@ -672,54 +677,57 @@ make_decl_rtl (decl, asmspec, top_level)
      const char *asmspec;
      int top_level;
 {
-  register char *name = 0;
+  const char *name = 0;
+  const char *new_name = 0;
   int reg_number;
 
-  reg_number = decode_reg_name (asmspec);
-
-  if (DECL_ASSEMBLER_NAME (decl) != NULL_TREE)
-    name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-
-  if (reg_number == -2)
+  /* For a duplicate declaration, we can be called twice on the
+     same DECL node.  Don't discard the RTL already made.  */
+  if (DECL_RTL (decl) != 0)
     {
-      /* ASMSPEC is given, and not the name of a register.  */
-      size_t len = strlen (asmspec);
+      /* If the old RTL had the wrong mode, fix the mode.  */
+      if (GET_MODE (DECL_RTL (decl)) != DECL_MODE (decl))
+       {
+         rtx rtl = DECL_RTL (decl);
+         PUT_MODE (rtl, DECL_MODE (decl));
+       }
 
-      name = ggc_alloc_string (NULL, len + 1);
-      name[0] = '*';
-      memcpy (&name[1], asmspec, len + 1);
+      /* ??? Another way to do this would be to do what halfpic.c does
+        and maintain a hashed table of such critters.  */
+      /* ??? Another way to do this would be to pass a flag bit to
+        ENCODE_SECTION_INFO saying whether this is a new decl or not.  */
+      /* Let the target reassign the RTL if it wants.
+        This is necessary, for example, when one machine specific
+        decl attribute overrides another.  */
+#ifdef REDO_SECTION_INFO_P
+      if (REDO_SECTION_INFO_P (decl))
+       ENCODE_SECTION_INFO (decl);
+#endif
+      return;
     }
 
-  /* For a duplicate declaration, we can be called twice on the
-     same DECL node.  Don't discard the RTL already made.  */
-  if (DECL_RTL (decl) == 0)
+  new_name = name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+
+  reg_number = decode_reg_name (asmspec);
+  if (reg_number == -2)
+    /* ASMSPEC is given, and not the name of a register.  */
+    new_name = asmspec;
+
+  if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))
     {
       /* First detect errors in declaring global registers.  */
-      if (TREE_CODE (decl) != FUNCTION_DECL
-         && DECL_REGISTER (decl) && reg_number == -1)
-       error_with_decl (decl,
-                        "register name not specified for `%s'");
-      else if (TREE_CODE (decl) != FUNCTION_DECL
-              && DECL_REGISTER (decl) && reg_number < 0)
-       error_with_decl (decl,
-                        "invalid register name for `%s'");
-      else if ((reg_number >= 0 || reg_number == -3)
-              && (TREE_CODE (decl) == FUNCTION_DECL
-                  && ! DECL_REGISTER (decl)))
-       error_with_decl (decl,
-                        "register name given for non-register variable `%s'");
-      else if (TREE_CODE (decl) != FUNCTION_DECL
-              && DECL_REGISTER (decl)
-              && TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
+      if (reg_number == -1)
+       error_with_decl (decl, "register name not specified for `%s'");
+      else if (reg_number < 0)
+       error_with_decl (decl, "invalid register name for `%s'");
+      else if (TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
        error_with_decl (decl,
                         "data type of `%s' isn't suitable for a register");
-      else if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl)
-              && ! HARD_REGNO_MODE_OK (reg_number,
-                                       TYPE_MODE (TREE_TYPE (decl))))
+      else if (! HARD_REGNO_MODE_OK (reg_number, TYPE_MODE (TREE_TYPE (decl))))
        error_with_decl (decl,
-                        "register number for `%s' isn't suitable for data type");
+                        "register specified for `%s' isn't suitable for data type");
       /* Now handle properly declared static register variables.  */
-      else if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl))
+      else
        {
          int nregs;
 
@@ -753,106 +761,81 @@ make_decl_rtl (decl, asmspec, top_level)
              while (nregs > 0)
                globalize_reg (reg_number + --nregs);
            }
+
+         /* As a register variable, it has no section.  */
+         return;
        }
-      /* Specifying a section attribute on a variable forces it into a
-         non-.bss section, and thus it cannot be common. */
-      else if (TREE_CODE (decl) == VAR_DECL
-              && DECL_SECTION_NAME (decl) != NULL_TREE
-              && DECL_INITIAL (decl) == NULL_TREE
-              && DECL_COMMON (decl))
-          DECL_COMMON (decl) = 0;
-
-      /* Now handle ordinary static variables and functions (in memory).
-        Also handle vars declared register invalidly.  */
-      if (DECL_RTL (decl) == 0)
-       {
-         /* Can't use just the variable's own name for a variable
-            whose scope is less than the whole file, unless it's a member
-            of a local class (which will already be unambiguous).
-            Concatenate a distinguishing number.  */
-         if (!top_level && !TREE_PUBLIC (decl)
-             && ! (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
-             && asmspec == 0)
-           {
-             char *label;
+    }
 
-             ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
-             name = ggc_alloc_string (label, -1);
-             var_labelno++;
-           }
+  /* Now handle ordinary static variables and functions (in memory).
+     Also handle vars declared register invalidly.  */
 
-         if (name == 0)
-           abort ();
+  if (reg_number >= 0 || reg_number == -3)
+    error_with_decl (decl,
+                    "register name given for non-register variable `%s'");
 
-         /* When -fprefix-function-name is used, the functions
-            names are prefixed.  Only nested function names are not
-            prefixed.  */
-         if (flag_prefix_function_name && TREE_CODE (decl) == FUNCTION_DECL)
-           {
-             size_t name_len = strlen (name);
-             char *new_name;
+  /* Specifying a section attribute on a variable forces it into a
+     non-.bss section, and thus it cannot be common. */
+  if (TREE_CODE (decl) == VAR_DECL
+      && DECL_SECTION_NAME (decl) != NULL_TREE
+      && DECL_INITIAL (decl) == NULL_TREE
+      && DECL_COMMON (decl))
+    DECL_COMMON (decl) = 0;
+
+  /* Can't use just the variable's own name for a variable
+     whose scope is less than the whole file, unless it's a member
+     of a local class (which will already be unambiguous).
+     Concatenate a distinguishing number.  */
+  if (!top_level && !TREE_PUBLIC (decl)
+      && ! (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
+      && asmspec == 0)
+    {
+      char *label;
+      ASM_FORMAT_PRIVATE_NAME (label, name, var_labelno);
+      var_labelno++;
+      new_name = label;
+    }
 
-             new_name = ggc_alloc_string (NULL, name_len + CHKR_PREFIX_SIZE);
-             memcpy (new_name, CHKR_PREFIX, CHKR_PREFIX_SIZE);
-             memcpy (new_name + CHKR_PREFIX_SIZE, name, name_len + 1);
-             name = new_name;
-           }
+  /* When -fprefix-function-name is used, the functions
+     names are prefixed.  Only nested function names are not
+     prefixed.  */
+  else if (flag_prefix_function_name && TREE_CODE (decl) == FUNCTION_DECL)
+    {
+      size_t name_len = IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl));
+      char *pname;
 
-         DECL_ASSEMBLER_NAME (decl)
-           = get_identifier (name[0] == '*' ? name + 1 : name);
-         DECL_RTL (decl) = gen_rtx_MEM (DECL_MODE (decl),
-                                        gen_rtx_SYMBOL_REF (Pmode, name));
-         MEM_ALIAS_SET (DECL_RTL (decl)) = get_alias_set (decl);
-
-         /* If this variable is to be treated as volatile, show its
-            tree node has side effects.  If it has side effects, either
-            because of this test or from TREE_THIS_VOLATILE also
-            being set, show the MEM is volatile.  */
-         if (flag_volatile_global && TREE_CODE (decl) == VAR_DECL
-             && TREE_PUBLIC (decl))
-           TREE_SIDE_EFFECTS (decl) = 1;
-         else if (flag_volatile_static && TREE_CODE (decl) == VAR_DECL
-              && (TREE_PUBLIC (decl) || TREE_STATIC (decl)))
-           TREE_SIDE_EFFECTS (decl) = 1;
-
-         if (TREE_SIDE_EFFECTS (decl))
-           MEM_VOLATILE_P (DECL_RTL (decl)) = 1;
-
-         if (TREE_READONLY (decl))
-           RTX_UNCHANGING_P (DECL_RTL (decl)) = 1;
-         MEM_SET_IN_STRUCT_P (DECL_RTL (decl),
-                              AGGREGATE_TYPE_P (TREE_TYPE (decl)));
-
-         /* Optionally set flags or add text to the name to record information
-            such as that it is a function name.
-            If the name is changed, the macro ASM_OUTPUT_LABELREF
-            will have to know how to strip this information.  */
-#ifdef ENCODE_SECTION_INFO
-         ENCODE_SECTION_INFO (decl);
-#endif
-       }
+      pname = alloca (name_len + CHKR_PREFIX_SIZE + 1);
+      memcpy (pname, CHKR_PREFIX, CHKR_PREFIX_SIZE);
+      memcpy (pname + CHKR_PREFIX_SIZE, name, name_len + 1);
+      new_name = pname;
     }
-  else
+
+  if (name != new_name)
     {
-      /* If the old RTL had the wrong mode, fix the mode.  */
-      if (GET_MODE (DECL_RTL (decl)) != DECL_MODE (decl))
-       {
-         rtx rtl = DECL_RTL (decl);
-         PUT_MODE (rtl, DECL_MODE (decl));
-       }
+      DECL_ASSEMBLER_NAME (decl) = get_identifier (new_name);
+      name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+    }
 
-      /* ??? Another way to do this would be to do what halfpic.c does
-        and maintain a hashed table of such critters.  */
-      /* ??? Another way to do this would be to pass a flag bit to
-        ENCODE_SECTION_INFO saying whether this is a new decl or not.  */
-      /* Let the target reassign the RTL if it wants.
-        This is necessary, for example, when one machine specific
-        decl attribute overrides another.  */
-#ifdef REDO_SECTION_INFO_P
-      if (REDO_SECTION_INFO_P (decl))
-       ENCODE_SECTION_INFO (decl);
+  /* If this variable is to be treated as volatile, show its
+     tree node has side effects.   */
+  if ((flag_volatile_global && TREE_CODE (decl) == VAR_DECL
+       && TREE_PUBLIC (decl))
+      || ((flag_volatile_static && TREE_CODE (decl) == VAR_DECL
+          && (TREE_PUBLIC (decl) || TREE_STATIC (decl)))))
+    TREE_SIDE_EFFECTS (decl) = 1;
+
+  DECL_RTL (decl) = gen_rtx_MEM (DECL_MODE (decl),
+                                gen_rtx_SYMBOL_REF (Pmode, name));
+  if (TREE_CODE (decl) != FUNCTION_DECL)
+    set_mem_attributes (DECL_RTL (decl), decl, 1);
+
+  /* Optionally set flags or add text to the name to record information
+     such as that it is a function name.
+     If the name is changed, the macro ASM_OUTPUT_LABELREF
+     will have to know how to strip this information.  */
+#ifdef ENCODE_SECTION_INFO
+  ENCODE_SECTION_INFO (decl);
 #endif
-    }
 }
 
 /* Make the rtl for variable VAR be volatile.
@@ -1508,7 +1491,8 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
       rounded = (rounded / (BIGGEST_ALIGNMENT / BITS_PER_UNIT)
                 * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
       
-#if !defined(ASM_OUTPUT_ALIGNED_COMMON) && !defined(ASM_OUTPUT_ALIGNED_BSS)
+/* Don't continue this line--convex cc version 4.1 would lose.  */
+#if !defined(ASM_OUTPUT_ALIGNED_COMMON) && !defined(ASM_OUTPUT_ALIGNED_DECL_COMMON) && !defined(ASM_OUTPUT_ALIGNED_BSS)
       if ((unsigned HOST_WIDE_INT) DECL_ALIGN (decl) / BITS_PER_UNIT > rounded)
          warning_with_decl 
            (decl, "requested alignment for %s is greater than implemented alignment of %d.",rounded);
@@ -2130,7 +2114,7 @@ immed_double_const (i0, i1, mode)
 
   push_obstacks_nochange ();
   rtl_in_saveable_obstack ();
-  r = gen_rtx_CONST_DOUBLE (mode, NULL_RTX, i0, i1);
+  r = gen_rtx_CONST_DOUBLE (mode, const0_rtx, i0, i1);
   pop_obstacks ();
 
   /* Don't touch const_double_chain if not inside any function.  */
@@ -2140,11 +2124,6 @@ immed_double_const (i0, i1, mode)
       const_double_chain = r;
     }
 
-  /* Store const0_rtx in mem-slot since this CONST_DOUBLE is on the chain.
-     Actual use of mem-slot is only through force_const_mem.  */
-
-  CONST_DOUBLE_MEM (r) = const0_rtx;
-
   return r;
 }
 
@@ -2210,12 +2189,15 @@ immed_real_const_1 (d, mode)
   PUT_MODE (r, mode);
   bcopy ((char *) &u, (char *) &CONST_DOUBLE_LOW (r), sizeof u);
 
-  /* Don't touch const_double_chain if not inside any function.  */
+  /* If we aren't inside a function, don't put r on the
+     const_double_chain.  */
   if (current_function_decl != 0)
     {
       CONST_DOUBLE_CHAIN (r) = const_double_chain;
       const_double_chain = r;
     }
+  else
+    CONST_DOUBLE_CHAIN (r) = NULL_RTX;
 
   /* Store const0_rtx in CONST_DOUBLE_MEM since this CONST_DOUBLE is on the
      chain, but has not been allocated memory.  Actual use of CONST_DOUBLE_MEM
@@ -2340,7 +2322,7 @@ struct constant_descriptor
   struct constant_descriptor *next;
   char *label;
   rtx rtl;
-  char contents[1];
+  unsigned char contents[1];
 };
 
 #define HASHBITS 30
@@ -2357,7 +2339,7 @@ mark_const_hash_entry (ptr)
 
   while (desc)
     {
-      ggc_mark_string (desc->label);
+      ggc_mark_string ((const char *)desc->label);
       ggc_mark_rtx (desc->rtl);
       desc = desc->next;
     }
@@ -2379,8 +2361,8 @@ const_hash (exp)
   switch (code)
     {
     case INTEGER_CST:
-      p = (char *) &TREE_INT_CST_LOW (exp);
-      len = 2 * sizeof TREE_INT_CST_LOW (exp);
+      p = (char *) &TREE_INT_CST (exp);
+      len = sizeof TREE_INT_CST (exp);
       break;
 
     case REAL_CST:
@@ -2468,7 +2450,8 @@ const_hash (exp)
       return const_hash (TREE_OPERAND (exp, 0)) * 7 + 2;
       
     default:
-      abort ();
+      /* A language specific constant. Just hash the code. */
+      return code % MAX_HASH_TABLE;
     }
 
   /* Compute hashing function */
@@ -2501,12 +2484,12 @@ compare_constant (exp, desc)
    against a subdescriptor, and if it succeeds it returns the
    address of the subdescriptor for the next operand.  */
 
-static char *
+static const unsigned char *
 compare_constant_1 (exp, p)
      tree exp;
-     char *p;
+     const unsigned char *p;
 {
-  register const char *strp;
+  register const unsigned char *strp;
   register int len;
   register enum tree_code code = TREE_CODE (exp);
 
@@ -2523,8 +2506,8 @@ compare_constant_1 (exp, p)
       if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
        return 0;
 
-      strp = (char *) &TREE_INT_CST_LOW (exp);
-      len = 2 * sizeof TREE_INT_CST_LOW (exp);
+      strp = (unsigned char *) &TREE_INT_CST (exp);
+      len = sizeof TREE_INT_CST (exp);
       break;
 
     case REAL_CST:
@@ -2532,7 +2515,7 @@ compare_constant_1 (exp, p)
       if (*p++ != TYPE_PRECISION (TREE_TYPE (exp)))
        return 0;
 
-      strp = (char *) &TREE_REAL_CST (exp);
+      strp = (unsigned char *) &TREE_REAL_CST (exp);
       len = sizeof TREE_REAL_CST (exp);
       break;
 
@@ -2543,7 +2526,7 @@ compare_constant_1 (exp, p)
       if ((enum machine_mode) *p++ != TYPE_MODE (TREE_TYPE (exp)))
        return 0;
 
-      strp = TREE_STRING_POINTER (exp);
+      strp = (unsigned char *)TREE_STRING_POINTER (exp);
       len = TREE_STRING_LENGTH (exp);
       if (bcmp ((char *) &TREE_STRING_LENGTH (exp), p,
                sizeof TREE_STRING_LENGTH (exp)))
@@ -2566,7 +2549,7 @@ compare_constant_1 (exp, p)
          unsigned char *tmp = (unsigned char *) alloca (len);
 
          get_set_constructor_bytes (exp, tmp, len);
-         strp = (char *) tmp;
+         strp = (unsigned char *) tmp;
          if (bcmp ((char *) &xlen, p, sizeof xlen))
            return 0;
 
@@ -2678,7 +2661,7 @@ compare_constant_1 (exp, p)
        struct addr_const value;
 
        decode_addr_const (exp, &value);
-       strp = (char *) &value.offset;
+       strp = (unsigned char *) &value.offset;
        len = sizeof value.offset;
        /* Compare the offset.  */
        while (--len >= 0)
@@ -2686,8 +2669,8 @@ compare_constant_1 (exp, p)
            return 0;
 
        /* Compare symbol name.  */
-       strp = XSTR (value.base, 0);
-       len = strlen (strp) + 1;
+       strp = (unsigned char *) XSTR (value.base, 0);
+       len = strlen ((char *) strp) + 1;
       }
       break;
 
@@ -2706,7 +2689,12 @@ compare_constant_1 (exp, p)
       return compare_constant_1 (TREE_OPERAND (exp, 0), p);
 
     default:
-      abort ();
+      if (lang_expand_constant)
+        {
+          exp = (*lang_expand_constant) (exp);
+          return compare_constant_1 (exp, p);
+        }
+      return 0;
     }
 
   /* Compare constant contents.  */
@@ -2747,7 +2735,7 @@ static void
 record_constant_1 (exp)
      tree exp;
 {
-  register char *strp;
+  register unsigned char *strp;
   register int len;
   register enum tree_code code = TREE_CODE (exp);
 
@@ -2757,13 +2745,13 @@ record_constant_1 (exp)
     {
     case INTEGER_CST:
       obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
-      strp = (char *) &TREE_INT_CST_LOW (exp);
-      len = 2 * sizeof TREE_INT_CST_LOW (exp);
+      strp = (unsigned char *) &TREE_INT_CST (exp);
+      len = sizeof TREE_INT_CST (exp);
       break;
 
     case REAL_CST:
       obstack_1grow (&permanent_obstack, TYPE_PRECISION (TREE_TYPE (exp)));
-      strp = (char *) &TREE_REAL_CST (exp);
+      strp = (unsigned char *) &TREE_REAL_CST (exp);
       len = sizeof TREE_REAL_CST (exp);
       break;
 
@@ -2772,7 +2760,7 @@ record_constant_1 (exp)
        return;
 
       obstack_1grow (&permanent_obstack, TYPE_MODE (TREE_TYPE (exp)));
-      strp = TREE_STRING_POINTER (exp);
+      strp = (unsigned char *) TREE_STRING_POINTER (exp);
       len = TREE_STRING_LENGTH (exp);
       obstack_grow (&permanent_obstack, (char *) &TREE_STRING_LENGTH (exp),
                    sizeof TREE_STRING_LENGTH (exp));
@@ -2904,7 +2892,12 @@ record_constant_1 (exp)
       return;
 
     default:
-      abort ();
+      if (lang_expand_constant)
+        {
+          exp = (*lang_expand_constant) (exp);
+          record_constant_1 (exp);
+        }
+      return;
     }
 
   /* Record constant contents.  */
@@ -3109,10 +3102,7 @@ output_constant_def (exp)
        = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)),
                       gen_rtx_SYMBOL_REF (Pmode, desc->label));
 
-      RTX_UNCHANGING_P (desc->rtl) = 1;
-      if (AGGREGATE_TYPE_P (TREE_TYPE (exp)))
-       MEM_SET_IN_STRUCT_P (desc->rtl, 1);
-
+      set_mem_attributes (desc->rtl, exp, 1);
       pop_obstacks ();
 
       found = 0;
@@ -3668,8 +3658,9 @@ force_const_mem (mode, x)
   /* We have a symbol name; construct the SYMBOL_REF and the MEM.  */
 
   def = gen_rtx_MEM (mode, gen_rtx_SYMBOL_REF (Pmode, found));
-
+  set_mem_attributes (def, type_for_mode (mode, 0), 1);
   RTX_UNCHANGING_P (def) = 1;
+
   /* Mark the symbol_ref as belonging to this constants pool.  */
   CONSTANT_POOL_ADDRESS_P (XEXP (def, 0)) = 1;
   current_function_uses_const_pool = 1;
@@ -3890,13 +3881,13 @@ mark_constant_pool ()
     pool->mark = 0;
 
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
-    if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+    if (INSN_P (insn))
       mark_constants (PATTERN (insn));
 
   for (insn = current_function_epilogue_delay_list;
        insn;
        insn = XEXP (insn, 1))
-    if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+    if (INSN_P (insn))
       mark_constants (PATTERN (insn));
 
   /* It's possible that the only reference to a symbol is in a symbol
@@ -3954,7 +3945,7 @@ mark_constants (x)
   /* Insns may appear inside a SEQUENCE.  Only check the patterns of
      insns, not any notes that may be attached.  We don't want to mark
      a constant just because it happens to appear in a REG_EQUIV note.  */
-  if (GET_RTX_CLASS (GET_CODE (x)) == 'i')
+  if (INSN_P (x))
     {
       mark_constants (PATTERN (x));
       return;
@@ -4370,11 +4361,12 @@ output_constructor (exp, size)
      tree exp;
      int size;
 {
+  tree type = TREE_TYPE (exp);
   register tree link, field = 0;
-  HOST_WIDE_INT min_index = 0;
+  tree min_index = 0;
   /* Number of bytes output or skipped so far.
      In other words, current position within the constructor.  */
-  int total_bytes = 0;
+  HOST_WIDE_INT total_bytes = 0;
   /* Non-zero means BYTE contains part of a byte, to be output.  */
   int byte_buffer_in_use = 0;
   register int byte = 0;
@@ -4382,13 +4374,12 @@ output_constructor (exp, size)
   if (HOST_BITS_PER_WIDE_INT < BITS_PER_UNIT)
     abort ();
 
-  if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
-    field = TYPE_FIELDS (TREE_TYPE (exp));
+  if (TREE_CODE (type) == RECORD_TYPE)
+    field = TYPE_FIELDS (type);
 
-  if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
-      && TYPE_DOMAIN (TREE_TYPE (exp)) != 0)
-    min_index
-      = TREE_INT_CST_LOW (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (exp))));
+  if (TREE_CODE (type) == ARRAY_TYPE
+      && TYPE_DOMAIN (type) != 0)
+    min_index = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
 
   /* As LINK goes through the elements of the constant,
      FIELD goes through the structure fields, if the constant is a structure.
@@ -4407,17 +4398,14 @@ output_constructor (exp, size)
       tree val = TREE_VALUE (link);
       tree index = 0;
 
-      /* the element in a union constructor specifies the proper field.  */
-
-      if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
-         || TREE_CODE (TREE_TYPE (exp)) == UNION_TYPE)
-       {
-         /* if available, use the type given by link */
-         if (TREE_PURPOSE (link) != 0)
-           field = TREE_PURPOSE (link);
-       }
+      /* The element in a union constructor specifies the proper field
+        or index.  */
+      if ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
+          || TREE_CODE (type) == QUAL_UNION_TYPE)
+         && TREE_PURPOSE (link) != 0)
+       field = TREE_PURPOSE (link);
 
-      if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
+      else if (TREE_CODE (type) == ARRAY_TYPE)
        index = TREE_PURPOSE (link);
 
       /* Eliminate the marker that makes a cast not be an lvalue.  */
@@ -4427,10 +4415,11 @@ output_constructor (exp, size)
       if (index && TREE_CODE (index) == RANGE_EXPR)
        {
          register int fieldsize
-           = int_size_in_bytes (TREE_TYPE (TREE_TYPE (exp)));
-         HOST_WIDE_INT lo_index = TREE_INT_CST_LOW (TREE_OPERAND (index, 0));
-         HOST_WIDE_INT hi_index = TREE_INT_CST_LOW (TREE_OPERAND (index, 1));
+           = int_size_in_bytes (TREE_TYPE (type));
+         HOST_WIDE_INT lo_index = tree_low_cst (TREE_OPERAND (index, 0), 0);
+         HOST_WIDE_INT hi_index = tree_low_cst (TREE_OPERAND (index, 1), 0);
          HOST_WIDE_INT index;
+
          for (index = lo_index; index <= hi_index; index++)
            {
              /* Output the element's initial value.  */
@@ -4450,12 +4439,11 @@ output_constructor (exp, size)
          register int fieldsize;
          /* Since this structure is static,
             we know the positions are constant.  */
-         HOST_WIDE_INT bitpos = field ? int_byte_position (field) : 0;
+         HOST_WIDE_INT pos = field ? int_byte_position (field) : 0;
 
          if (index != 0)
-           bitpos
-             = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (val)), 1)
-               * (tree_low_cst (index, 0) - min_index));
+           pos = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (val)), 1)
+                  * (tree_low_cst (index, 0) - tree_low_cst (min_index, 0)));
 
          /* Output any buffered-up bit-fields preceding this element.  */
          if (byte_buffer_in_use)
@@ -4468,22 +4456,24 @@ output_constructor (exp, size)
          /* Advance to offset of this element.
             Note no alignment needed in an array, since that is guaranteed
             if each element has the proper size.  */
-         if ((field != 0 || index != 0) && bitpos != total_bytes)
+         if ((field != 0 || index != 0) && pos != total_bytes)
            {
-             assemble_zeros (bitpos - total_bytes);
-             total_bytes = bitpos;
+             assemble_zeros (pos - total_bytes);
+             total_bytes = pos;
            }
 
+          else if (field != 0 && DECL_PACKED (field))
+           /* Some assemblers automaticallly align a datum according to its
+              size if no align directive is specified.  The datum, however,
+              may be declared with 'packed' attribute, so we have to disable
+              such a feature.  */
+           ASM_OUTPUT_ALIGN (asm_out_file, 0);
+
          /* Determine size this element should occupy.  */
          if (field)
-           {
-             if (TREE_CODE (DECL_SIZE_UNIT (field)) != INTEGER_CST)
-               abort ();
-
-             fieldsize = TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
-           }
+           fieldsize = tree_low_cst (DECL_SIZE_UNIT (field), 1);
          else
-           fieldsize = int_size_in_bytes (TREE_TYPE (TREE_TYPE (exp)));
+           fieldsize = int_size_in_bytes (TREE_TYPE (type));
 
          /* Output the element's initial value.  */
          if (val == 0)
@@ -4544,8 +4534,8 @@ output_constructor (exp, size)
              int this_time;
              int shift;
              HOST_WIDE_INT value;
-             int next_byte = next_offset / BITS_PER_UNIT;
-             int next_bit = next_offset % BITS_PER_UNIT;
+             HOST_WIDE_INT next_byte = next_offset / BITS_PER_UNIT;
+             HOST_WIDE_INT next_bit = next_offset % BITS_PER_UNIT;
 
              /* Advance from byte to byte
                 within this element when necessary.  */
@@ -4566,6 +4556,7 @@ output_constructor (exp, size)
                     first (of the bits that are significant)
                     and put them into bytes from the most significant end.  */
                  shift = end_offset - next_offset - this_time;
+
                  /* Don't try to take a bunch of bits that cross
                     the word boundary in the INTEGER_CST. We can
                     only select bits from the LOW or HIGH part
@@ -4579,9 +4570,7 @@ output_constructor (exp, size)
 
                  /* Now get the bits from the appropriate constant word.  */
                  if (shift < HOST_BITS_PER_WIDE_INT)
-                   {
-                     value = TREE_INT_CST_LOW (val);
-                   }
+                   value = TREE_INT_CST_LOW (val);
                  else if (shift < 2 * HOST_BITS_PER_WIDE_INT)
                    {
                      value = TREE_INT_CST_HIGH (val);
@@ -4589,6 +4578,7 @@ output_constructor (exp, size)
                    }
                  else
                    abort ();
+
                  /* Get the result. This works only when:
                     1 <= this_time <= HOST_BITS_PER_WIDE_INT.  */
                  byte |= (((value >> shift)
@@ -4628,16 +4618,19 @@ output_constructor (exp, size)
                            & (((HOST_WIDE_INT) 2 << (this_time - 1)) - 1))
                           << next_bit);
                }
+
              next_offset += this_time;
              byte_buffer_in_use = 1;
            }
        }
     }
+
   if (byte_buffer_in_use)
     {
       ASM_OUTPUT_BYTE (asm_out_file, byte);
       total_bytes++;
     }
+
   if (total_bytes < size)
     assemble_zeros (size - total_bytes);
 }
@@ -4648,8 +4641,8 @@ output_constructor (exp, size)
    
 int
 add_weak (name, value)
-     char *name;
-     char *value;
+     const char *name;
+     const char *value;
 {
   struct weak_syms *weak;
 
@@ -4716,7 +4709,7 @@ weak_finish ()
 #ifdef ASM_WEAKEN_LABEL
 static void
 remove_from_pending_weak_list (name)
-     char *name ATTRIBUTE_UNUSED;
+     const char *name ATTRIBUTE_UNUSED;
 {
 #ifdef HANDLE_PRAGMA_WEAK
   if (HANDLE_PRAGMA_WEAK)
@@ -4836,3 +4829,74 @@ init_varasm_once ()
                mark_const_hash_entry);
   ggc_add_string_root (&in_named_name, 1);
 }
+
+/* Extra support for EH values.  */
+void
+assemble_eh_label (name)
+     const char *name;
+{
+#ifdef ASM_OUTPUT_EH_LABEL
+  ASM_OUTPUT_EH_LABEL (asm_out_file, name);
+#else
+  assemble_label (name);
+#endif
+}
+
+/* Assemble an alignment pseudo op for an ALIGN-bit boundary.  */
+
+void
+assemble_eh_align (align)
+     int align;
+{
+#ifdef ASM_OUTPUT_EH_ALIGN
+  if (align > BITS_PER_UNIT)
+    ASM_OUTPUT_EH_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
+#else
+  assemble_align (align);
+#endif
+}
+
+
+/* On some platforms, we may want to specify a special mechansim to
+   output EH data when generating with a function..  */
+int
+assemble_eh_integer (x, size, force)
+     rtx x;
+     int size;
+     int force;
+{
+
+  switch (size)
+    {
+#ifdef ASM_OUTPUT_EH_CHAR
+    case 1:
+      ASM_OUTPUT_EH_CHAR (asm_out_file, x);
+      return 1;
+#endif
+
+#ifdef ASM_OUTPUT_EH_SHORT
+    case 2:
+      ASM_OUTPUT_EH_SHORT (asm_out_file, x);
+      return 1;
+#endif
+
+#ifdef ASM_OUTPUT_EH_INT
+    case 4:
+      ASM_OUTPUT_EH_INT (asm_out_file, x);
+      return 1;
+#endif
+
+#ifdef ASM_OUTPUT_EH_DOUBLE_INT
+    case 8:
+      ASM_OUTPUT_EH_DOUBLE_INT (asm_out_file, x);
+      return 1;
+#endif
+
+    default:
+      break;
+    }
+  return (assemble_integer (x, size, force));
+}
+
+
+
This page took 0.055003 seconds and 5 git commands to generate.