]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/varasm.c
Enhance to fill the last delay slot of a call with an unconditional jump.
[gcc.git] / gcc / varasm.c
index 23964c0230d34f3c5c3438c4279f3252c082adbd..ff27b17bf6eddc91b2ea629956825f0d61a041ae 100644 (file)
@@ -35,9 +35,15 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "expr.h"
 #include "hard-reg-set.h"
 #include "regs.h"
+#include "defaults.h"
+#include "real.h"
 
 #include "obstack.h"
 
+#ifdef XCOFF_DEBUGGING_INFO
+#include "xcoffout.h"
+#endif
+
 #ifndef ASM_STABS_OP
 #define ASM_STABS_OP ".stabs"
 #endif
@@ -53,7 +59,6 @@ extern struct obstack *current_obstack;
 extern struct obstack *saveable_obstack;
 extern struct obstack permanent_obstack;
 #define obstack_chunk_alloc xmalloc
-extern int xmalloc ();
 
 /* Number for making the label on the next
    constant that is stored in memory.  */
@@ -77,6 +82,9 @@ void assemble_name ();
 int output_addressed_constants ();
 void output_constant ();
 void output_constructor ();
+void text_section ();
+void readonly_data_section ();
+void data_section ();
 \f
 #ifdef EXTRA_SECTIONS
 static enum in_section {no_section, in_text, in_data, EXTRA_SECTIONS} in_section
@@ -103,19 +111,6 @@ text_section ()
     }
 }
 
-/* Tell assembler to switch to read-only data section.  This is normally
-   the text section.  */
-
-void
-readonly_data_section ()
-{
-#ifdef READONLY_DATA_SECTION
-  READONLY_DATA_SECTION ();
-#else
-  text_section ();
-#endif
-}
-
 /* Tell assembler to switch to data section.  */
 
 void
@@ -138,6 +133,19 @@ data_section ()
     }
 }
 
+/* Tell assembler to switch to read-only data section.  This is normally
+   the text section.  */
+
+void
+readonly_data_section ()
+{
+#ifdef READONLY_DATA_SECTION
+  READONLY_DATA_SECTION ();  /* Note this can call data_section.  */
+#else
+  text_section ();
+#endif
+}
+
 /* Determine if we're in the text section. */
 
 int
@@ -189,9 +197,28 @@ make_function_rtl (decl)
   function_defined = 1;
 }
 
+/* Given NAME, a putative register name, discard any customary prefixes.  */
+
+static char *
+strip_reg_name (name)
+     char *name;
+{
+#ifdef REGISTER_PREFIX
+  if (!strncmp (name, REGISTER_PREFIX, strlen (REGISTER_PREFIX)))
+    name += strlen (REGISTER_PREFIX);
+#endif
+  if (name[0] == '%' || name[0] == '#')
+    name++;
+  return name;
+}
+\f
 /* Decode an `asm' spec for a declaration as a register name.
    Return the register number, or -1 if nothing specified,
-   or -2 if the name is not a register.  */
+   or -2 if the ASMSPEC is not `cc' or `memory' and is not recognized,
+   or -3 if ASMSPEC is `cc' and is not recognized,
+   or -4 if ASMSPEC is `memory' and is not recognized.
+   Accept an exact spelling or a decimal number.
+   Prefixes such as % are optional.  */
 
 int
 decode_reg_name (asmspec)
@@ -201,15 +228,27 @@ decode_reg_name (asmspec)
     {
       int i;
 
+      /* Get rid of confusing prefixes.  */
+      asmspec = strip_reg_name (asmspec);
+       
+      /* Allow a decimal number as a "register name".  */
+      for (i = strlen (asmspec) - 1; i >= 0; i--)
+       if (! (asmspec[i] >= '0' && asmspec[i] <= '9'))
+         break;
+      if (asmspec[0] != 0 && i < 0)
+       {
+         i = atoi (asmspec);
+         if (i < FIRST_PSEUDO_REGISTER && i >= 0)
+           return i;
+         else
+           return -2;
+       }
+
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-       if (reg_names[i][0] && ! strcmp (asmspec, reg_names[i]))
+       if (reg_names[i][0]
+           && ! strcmp (asmspec, strip_reg_name (reg_names[i])))
          return i;
 
-      if (asmspec[0] == '%')
-       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-         if (reg_names[i][0] && ! strcmp (asmspec + 1, reg_names[i]))
-           return i;
-
 #ifdef ADDITIONAL_REGISTER_NAMES
       {
        static struct { char *name; int number; } table[]
@@ -218,14 +257,15 @@ decode_reg_name (asmspec)
        for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
          if (! strcmp (asmspec, table[i].name))
            return table[i].number;
-
-       if (asmspec[0] == '%')
-         for (i = 0; i < sizeof (table) / sizeof (table[0]); i++)
-           if (! strcmp (asmspec + 1, table[i].name))
-             return table[i].number;
       }
 #endif /* ADDITIONAL_REGISTER_NAMES */
 
+      if (!strcmp (asmspec, "memory"))
+       return -4;
+
+      if (!strcmp (asmspec, "cc"))
+       return -3;
+
       return -2;
     }
 
@@ -271,21 +311,21 @@ make_decl_rtl (decl, asmspec, top_level)
       DECL_RTL (decl) = 0;
 
       /* First detect errors in declaring global registers.  */
-      if (TREE_REGDECL (decl) && reg_number == -1)
+      if (DECL_REGISTER (decl) && reg_number == -1)
        error_with_decl (decl,
                         "register name not specified for `%s'");
-      else if (TREE_REGDECL (decl) && reg_number == -2)
+      else if (DECL_REGISTER (decl) && reg_number < 0)
        error_with_decl (decl,
                         "invalid register name for `%s'");
-      else if (reg_number >= 0 && ! TREE_REGDECL (decl))
+      else if ((reg_number >= 0 || reg_number == -3) && ! DECL_REGISTER (decl))
        error_with_decl (decl,
                         "register name given for non-register variable `%s'");
-      else if (TREE_REGDECL (decl) && TREE_CODE (decl) == FUNCTION_DECL)
+      else if (DECL_REGISTER (decl) && TREE_CODE (decl) == FUNCTION_DECL)
        error ("function declared `register'");
-      else if (TREE_REGDECL (decl) && TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
+      else if (DECL_REGISTER (decl) && TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
        error_with_decl (decl, "data type of `%s' isn't suitable for a register");
       /* Now handle properly declared static register variables.  */
-      else if (TREE_REGDECL (decl))
+      else if (DECL_REGISTER (decl))
        {
          int nregs;
 #if 0 /* yylex should print the warning for this */
@@ -322,7 +362,7 @@ make_decl_rtl (decl, asmspec, top_level)
          /* Can't use just the variable's own name for a variable
             whose scope is less than the whole file.
             Concatenate a distinguishing number.  */
-         if (!top_level && !TREE_EXTERNAL (decl) && asmspec == 0)
+         if (!top_level && !DECL_EXTERNAL (decl) && asmspec == 0)
            {
              char *label;
 
@@ -354,6 +394,18 @@ make_decl_rtl (decl, asmspec, top_level)
        }
     }
 }
+
+/* Make the rtl for variable VAR be volatile.
+   Use this only for static variables.  */
+
+make_var_volatile (var)
+     tree var;
+{
+  if (GET_CODE (DECL_RTL (var)) != MEM)
+    abort ();
+
+  MEM_VOLATILE_P (DECL_RTL (var)) = 1;
+}
 \f
 /* Output a string of literal assembler code
    for an `asm' keyword used between functions.  */
@@ -370,11 +422,10 @@ assemble_asm (string)
   fprintf (asm_out_file, "\t%s\n", TREE_STRING_POINTER (string));
 }
 
-/* Tiemann: please get rid of this conditional and put appropriate
-   definitions in each of the files that should have them.
-   The type of debugging format is not the right parameter to
-   control how some other aspect of assembler output is done.  */
-
+#if 0 /* This should no longer be needed, because
+        flag_gnu_linker should be 0 on these systems,
+        which should prevent any output
+        if ASM_OUTPUT_CONSTRUCTOR and ASM_OUTPUT_DESTRUCTOR are absent.  */
 #if !(defined(DBX_DEBUGGING_INFO) && !defined(FASCIST_ASSEMBLER))
 #ifndef ASM_OUTPUT_CONSTRUCTOR
 #define ASM_OUTPUT_CONSTRUCTOR(file, name)
@@ -383,6 +434,7 @@ assemble_asm (string)
 #define ASM_OUTPUT_DESTRUCTOR(file, name)
 #endif
 #endif
+#endif /* 0 */
 
 /* Record an element in the table of global destructors.
    How this is done depends on what sort of assembler and linker
@@ -486,9 +538,9 @@ assemble_start_function (decl, fnname)
 #endif
 
 #ifdef DBX_DEBUGGING_INFO
-  /* Output SDB definition of the function.  */
+  /* Output DBX definition of the function.  */
   if (write_symbols == DBX_DEBUG)
-    dbxout_begin_function ();
+    dbxout_begin_function (decl);
 #endif
 
   /* Make function name accessible from other files, if appropriate.  */
@@ -582,33 +634,7 @@ assemble_string (p, size)
       if (thissize > maximum)
        thissize = maximum;
 
-#ifdef ASM_OUTPUT_ASCII
       ASM_OUTPUT_ASCII (asm_out_file, p, thissize);
-#else
-      fprintf (asm_out_file, "\t.ascii \"");
-
-      for (i = 0; i < thissize; i++)
-       {
-         register int c = p[i];
-         if (c == '\"' || c == '\\')
-           putc ('\\', asm_out_file);
-         if (c >= ' ' && c < 0177)
-           putc (c, asm_out_file);
-         else
-           {
-             fprintf (asm_out_file, "\\%o", c);
-             /* After an octal-escape, if a digit follows,
-                terminate one string constant and start another.
-                The Vax assembler fails to stop reading the escape
-                after three digits, so this is the only way we
-                can get it to parse the data properly.  */
-             if (i < thissize - 1
-                 && p[i + 1] >= '0' && p[i + 1] <= '9')
-               fprintf (asm_out_file, "\"\n\t.ascii \"");
-           }
-       }
-      fprintf (asm_out_file, "\"\n");
-#endif /* no ASM_OUTPUT_ASCII */
 
       pos += thissize;
       p += thissize;
@@ -643,9 +669,10 @@ assemble_variable (decl, top_level, at_end)
        return;
       TREE_ASM_WRITTEN (decl) = 1;
 
-#ifdef DBX_DEBUGGING_INFO
+#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
       /* File-scope global variables are output here.  */
-      if (write_symbols == DBX_DEBUG && top_level)
+      if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
+         && top_level)
        dbxout_symbol (decl, 0);
 #endif
 #ifdef SDB_DEBUGGING_INFO
@@ -670,7 +697,7 @@ assemble_variable (decl, top_level, at_end)
   /* Normally no need to say anything for external references,
      since assembler considers all undefined symbols external.  */
 
-  if (TREE_EXTERNAL (decl))
+  if (DECL_EXTERNAL (decl))
     return;
 
   /* Output no assembler code for a function declaration.
@@ -692,7 +719,7 @@ assemble_variable (decl, top_level, at_end)
     {
       error_with_file_and_line (DECL_SOURCE_FILE (decl),
                                DECL_SOURCE_LINE (decl),
-                               "storage size of static var `%s' isn't known",
+                               "storage size of `%s' isn't known",
                                IDENTIFIER_POINTER (DECL_NAME (decl)));
       return;
     }
@@ -732,7 +759,7 @@ assemble_variable (decl, top_level, at_end)
      Error message was already made.  */
 
   if (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
-    return;
+    goto finish;
 
   app_disable ();
 
@@ -743,7 +770,7 @@ assemble_variable (decl, top_level, at_end)
   if (TREE_INT_CST_HIGH (size_tree) != 0)
     {
       error_with_decl (decl, "size of variable `%s' is too large");
-      return;
+      goto finish;
     }
 
   name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
@@ -802,7 +829,7 @@ assemble_variable (decl, top_level, at_end)
            ASM_OUTPUT_LOCAL (asm_out_file, name, size, rounded);
 #endif
        }
-      return;
+      goto finish;
     }
 
   /* Handle initialized definitions.  */
@@ -893,25 +920,45 @@ assemble_variable (decl, top_level, at_end)
   else
     /* Leave space for it.  */
     assemble_zeros (int_size_in_bytes (TREE_TYPE (decl)));
+
+ finish:
+#ifdef XCOFF_DEBUGGING_INFO
+  /* Unfortunately, the IBM assembler cannot handle stabx before the actual
+     declaration.  When something like ".stabx  "aa:S-2",aa,133,0" is emitted 
+     and `aa' hasn't been output yet, the assembler generates a stab entry with
+     a value of zero, in addition to creating an unnecessary external entry
+     for `aa'.  Hence, we must postpone dbxout_symbol to here at the end.  */
+
+  /* File-scope global variables are output here.  */
+  if (write_symbols == XCOFF_DEBUG && top_level)
+    dbxout_symbol (decl, 0);
+#else
+  /* There must be a statement after a label.  */
+  ;
+#endif
 }
 
 /* Output something to declare an external symbol to the assembler.
-   (Most assemblers don't need this, so we normally output nothing.)  */
+   (Most assemblers don't need this, so we normally output nothing.)
+   Do nothing if DECL is not external.  */
 
 void
 assemble_external (decl)
      tree decl;
 {
-  rtx rtl = DECL_RTL (decl);
-
 #ifdef ASM_OUTPUT_EXTERNAL
-  if (TREE_PUBLIC (decl)
-      && GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
-      && ! SYMBOL_REF_USED (XEXP (rtl, 0)))
+  if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd'
+      && DECL_EXTERNAL (decl) && TREE_PUBLIC (decl))
     {
-      /* Some systems do require some output.  */
-      SYMBOL_REF_USED (XEXP (rtl, 0)) = 1;
-      ASM_OUTPUT_EXTERNAL (asm_out_file, decl, XSTR (XEXP (rtl, 0), 0));
+      rtx rtl = DECL_RTL (decl);
+
+      if (GET_CODE (rtl) == MEM && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF
+         && ! SYMBOL_REF_USED (XEXP (rtl, 0)))
+       {
+         /* Some systems do require some output.  */
+         SYMBOL_REF_USED (XEXP (rtl, 0)) = 1;
+         ASM_OUTPUT_EXTERNAL (asm_out_file, decl, XSTR (XEXP (rtl, 0), 0));
+       }
     }
 #endif
 }
@@ -1107,11 +1154,16 @@ assemble_integer (x, size, force)
          if (word == 0)
            break;
 
-         assemble_integer (word, UNITS_PER_WORD);
+         if (! assemble_integer (word, UNITS_PER_WORD, 0))
+           break;
        }
 
       if (i == size / UNITS_PER_WORD)
        return 1;
+      /* If we output at least one word and then could not finish,
+        there is no valid way to continue.  */
+      if (i > 0)
+       abort ();
     }
 
   if (force)
@@ -1166,7 +1218,7 @@ assemble_real (d, mode)
       abort ();
     }
 
-  set_float_handler (0);
+  set_float_handler (NULL_PTR);
 }
 \f
 /* Here we combine duplicate floating constants to make
@@ -1187,7 +1239,7 @@ static rtx const_double_chain;
 
 rtx
 immed_double_const (i0, i1, mode)
-     int i0, i1;
+     HOST_WIDE_INT i0, i1;
      enum machine_mode mode;
 {
   register rtx r;
@@ -1199,22 +1251,24 @@ immed_double_const (i0, i1, mode)
         sign bit are all one.  So we get either a reasonable negative value
         or a reasonable unsigned value for this mode.  */
       int width = GET_MODE_BITSIZE (mode);
-      if (width < HOST_BITS_PER_INT
-         && ((i0 & ((-1) << (width - 1))) != ((-1) << (width - 1))))
-       i0 &= (1 << width) - 1, i1 = 0;
-      else if (width == HOST_BITS_PER_INT
+      if (width < HOST_BITS_PER_WIDE_INT
+         && ((i0 & ((HOST_WIDE_INT) (-1) << (width - 1)))
+             != ((HOST_WIDE_INT) (-1) << (width - 1))))
+       i0 &= ((HOST_WIDE_INT) 1 << width) - 1, i1 = 0;
+      else if (width == HOST_BITS_PER_WIDE_INT
               && ! (i1 == ~0 && i0 < 0))
        i1 = 0;
-      else if (width > 2 * HOST_BITS_PER_INT)
+      else if (width > 2 * HOST_BITS_PER_WIDE_INT)
        /* We cannot represent this value as a constant.  */
        abort ();
 
-      /* If MODE fits within HOST_BITS_PER_INT, always use a CONST_INT.
+      /* If MODE fits within HOST_BITS_PER_WIDE_INT, always use a CONST_INT.
 
         ??? Strictly speaking, this is wrong if we create a CONST_INT
         for a large unsigned constant with the size of MODE being
-        HOST_BITS_PER_INT and later try to interpret that constant in a wider
-        mode.  In that case we will mis-interpret it as a negative number.
+        HOST_BITS_PER_WIDE_INT and later try to interpret that constant in a
+        wider mode.  In that case we will mis-interpret it as a negative
+        number.
 
         Unfortunately, the only alternative is to make a CONST_DOUBLE
         for any constant in any mode if it is an unsigned constant larger
@@ -1225,13 +1279,13 @@ immed_double_const (i0, i1, mode)
         We have always been making CONST_INTs in this case, so nothing new
         is being broken.  */
 
-      if (width <= HOST_BITS_PER_INT)
+      if (width <= HOST_BITS_PER_WIDE_INT)
        i1 = (i0 < 0) ? ~0 : 0;
 
       /* If this integer fits in one word, return a CONST_INT.  */
       if ((i1 == 0 && i0 >= 0)
          || (i1 == ~0 && i0 < 0))
-       return gen_rtx (CONST_INT, VOIDmode, i0);
+       return GEN_INT (i0);
 
       /* We use VOIDmode for integers.  */
       mode = VOIDmode;
@@ -1288,12 +1342,13 @@ immed_real_const_1 (d, mode)
 
   /* Detect special cases.  */
 
-  if (REAL_VALUES_EQUAL (dconst0, d))
+  /* Avoid REAL_VALUES_EQUAL here in order to distinguish minus zero.  */
+  if (!bcmp (&dconst0, &d, sizeof d))
     return CONST0_RTX (mode);
   else if (REAL_VALUES_EQUAL (dconst1, d))
     return CONST1_RTX (mode);
 
-  if (sizeof u == 2 * sizeof (int))
+  if (sizeof u == 2 * sizeof (HOST_WIDE_INT))
     return immed_double_const (u.i[0], u.i[1], mode);
 
   /* The rest of this function handles the case where
@@ -1371,7 +1426,7 @@ clear_const_double_mem ()
 struct addr_const
 {
   rtx base;
-  int offset;
+  HOST_WIDE_INT offset;
 };
 
 static void
@@ -1490,14 +1545,19 @@ const_hash (exp)
       /* For record type, include the type in the hashing.
         We do not do so for array types
         because (1) the sizes of the elements are sufficient
-        and (2) distinct array types can have the same constructor.  */
+        and (2) distinct array types can have the same constructor.
+        Instead, we include the array size because the constructor could
+        be shorter.  */
       if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
-       hi = ((int) TREE_TYPE (exp) & ((1 << HASHBITS) - 1)) % MAX_HASH_TABLE;
+       hi = ((HOST_WIDE_INT) TREE_TYPE (exp) & ((1 << HASHBITS) - 1))
+         % MAX_HASH_TABLE;
       else
-       hi = 5;
+       hi = ((5 + int_size_in_bytes (TREE_TYPE (exp)))
+              & ((1 << HASHBITS) - 1)) % MAX_HASH_TABLE;
 
       for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
-       hi = (hi * 603 + const_hash (TREE_VALUE (link))) % MAX_HASH_TABLE;
+       if (TREE_VALUE (link))
+         hi = (hi * 603 + const_hash (TREE_VALUE (link))) % MAX_HASH_TABLE;
 
       return hi;
     }
@@ -1623,9 +1683,32 @@ compare_constant_1 (exp, p)
        return 0;
       p += sizeof type;
 
+      /* For arrays, insist that the size in bytes match.  */
+      if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
+       {
+         int size = int_size_in_bytes (TREE_TYPE (exp));
+         if (bcmp (&size, p, sizeof size))
+           return 0;
+         p += sizeof size;
+       }
+
       for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
-       if ((p = compare_constant_1 (TREE_VALUE (link), p)) == 0)
-         return 0;
+       {
+         if (TREE_VALUE (link))
+           {
+             if ((p = compare_constant_1 (TREE_VALUE (link), p)) == 0)
+               return 0;
+           }
+         else
+           {
+             tree zero = 0;
+
+             if (bcmp (&zero, p, sizeof zero))
+               return 0;
+             p += sizeof zero;
+           }
+       }
+
       return p;
     }
   else if (code == ADDR_EXPR)
@@ -1737,8 +1820,25 @@ record_constant_1 (exp)
        type = 0;
       obstack_grow (&permanent_obstack, (char *) &type, sizeof type);
 
+      /* For arrays, insist that the size in bytes match.  */
+      if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
+       {
+         int size = int_size_in_bytes (TREE_TYPE (exp));
+         obstack_grow (&permanent_obstack, (char *) &size, sizeof size);
+       }
+
       for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
-       record_constant_1 (TREE_VALUE (link));
+       {
+         if (TREE_VALUE (link))
+           record_constant_1 (TREE_VALUE (link));
+         else
+           {
+             tree zero = 0;
+
+             obstack_grow (&permanent_obstack, (char *) &zero, sizeof zero);
+           }
+       }
+
       return;
     }
   else if (code == ADDR_EXPR)
@@ -1840,6 +1940,9 @@ output_constant_def (exp)
   TREE_CST_RTL (exp)
     = gen_rtx (MEM, TYPE_MODE (TREE_TYPE (exp)), def);
   RTX_UNCHANGING_P (TREE_CST_RTL (exp)) = 1;
+  if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
+      || TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
+    MEM_IN_STRUCT_P (TREE_CST_RTL (exp)) = 1;
 
   pop_obstacks ();
 
@@ -1947,7 +2050,7 @@ static struct pool_sym *const_rtx_sym_hash_table[MAX_RTX_HASH_TABLE];
    The argument is XSTR (... , 0)  */
 
 #define SYMHASH(LABEL) \
-  ((((int) (LABEL)) & ((1 << HASHBITS) - 1))  % MAX_RTX_HASH_TABLE)
+  ((((HOST_WIDE_INT) (LABEL)) & ((1 << HASHBITS) - 1))  % MAX_RTX_HASH_TABLE)
 \f
 /* Initialize constant pool hashing for next function.  */
 
@@ -2455,6 +2558,14 @@ output_constant (exp, size)
   if (size == 0)
     return;
 
+  /* Allow a constructor with no elements for any data type.
+     This means to fill the space with zeros.  */
+  if (TREE_CODE (exp) == CONSTRUCTOR && CONSTRUCTOR_ELTS (exp) == 0)
+    {
+      assemble_zeros (size);
+      return;
+    }
+
   /* Eliminate the NOP_EXPR that makes a cast not be an lvalue.
      That way we get the constant (we hope) inside it.  */
   if (TREE_CODE (exp) == NOP_EXPR
@@ -2472,7 +2583,7 @@ output_constant (exp, size)
             || TREE_CODE (exp) == NON_LVALUE_EXPR)
        exp = TREE_OPERAND (exp, 0);
 
-      if (! assemble_integer (expand_expr (exp, 0, VOIDmode,
+      if (! assemble_integer (expand_expr (exp, NULL_RTX, VOIDmode,
                                           EXPAND_INITIALIZER),
                              size, 0))
        error ("initializer for integer value is too complicated");
@@ -2547,7 +2658,7 @@ output_constructor (exp, size)
   int byte_buffer_in_use = 0;
   register int byte;
 
-  if (HOST_BITS_PER_INT < BITS_PER_UNIT)
+  if (HOST_BITS_PER_WIDE_INT < BITS_PER_UNIT)
     abort ();
 
   if (TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE)
@@ -2569,8 +2680,8 @@ output_constructor (exp, size)
        field = TREE_PURPOSE (link);
 
       /* Eliminate the marker that makes a cast not be an lvalue.  */
-      if (val != 0 && TREE_CODE (val) == NON_LVALUE_EXPR)
-       val = TREE_OPERAND (val, 0);
+      if (val != 0)
+       STRIP_NOPS (val);
 
       if (field == 0 || !DECL_BIT_FIELD (field))
        {
@@ -2671,7 +2782,7 @@ output_constructor (exp, size)
             separate bytes, and combine each byte with previous or
             following bit-fields.  */
 
-         /* next_offset is the offset n fbits from the begining of
+         /* next_offset is the offset n fbits from the beginning of
             the structure to the next bit of this element to be processed.
             end_offset is the offset of the first bit past the end of
             this element.  */
@@ -2702,26 +2813,27 @@ output_constructor (exp, size)
              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.  */
-             if (shift < HOST_BITS_PER_INT
-                 && shift + this_time > HOST_BITS_PER_INT)
+             if (shift < HOST_BITS_PER_WIDE_INT
+                 && shift + this_time > HOST_BITS_PER_WIDE_INT)
                {
-                 this_time -= (HOST_BITS_PER_INT - shift);
-                 shift = HOST_BITS_PER_INT;
+                 this_time -= (HOST_BITS_PER_WIDE_INT - shift);
+                 shift = HOST_BITS_PER_WIDE_INT;
                }
 
              /* Now get the bits from the appropriate constant word.  */
-             if (shift < HOST_BITS_PER_INT)
+             if (shift < HOST_BITS_PER_WIDE_INT)
                {
                  value = TREE_INT_CST_LOW (val);
                }
-             else if (shift < 2 * HOST_BITS_PER_INT)
+             else if (shift < 2 * HOST_BITS_PER_WIDE_INT)
                {
                  value = TREE_INT_CST_HIGH (val);
-                 shift -= HOST_BITS_PER_INT;
+                 shift -= HOST_BITS_PER_WIDE_INT;
                }
              else
                abort ();
-             byte |= (((value >> shift) & ((1 << this_time) - 1))
+             byte |= (((value >> shift)
+                       & (((HOST_WIDE_INT) 1 << this_time) - 1))
                       << (BITS_PER_UNIT - this_time - next_bit));
 #else
              /* On little-endian machines,
@@ -2732,24 +2844,25 @@ output_constructor (exp, size)
                       - TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)));
              /* Don't try to take a bunch of bits that cross
                 the word boundary in the INTEGER_CST.  */
-             if (shift < HOST_BITS_PER_INT
-                 && shift + this_time > HOST_BITS_PER_INT)
+             if (shift < HOST_BITS_PER_WIDE_INT
+                 && shift + this_time > HOST_BITS_PER_WIDE_INT)
                {
-                 this_time -= (HOST_BITS_PER_INT - shift);
-                 shift = HOST_BITS_PER_INT;
+                 this_time -= (HOST_BITS_PER_WIDE_INT - shift);
+                 shift = HOST_BITS_PER_WIDE_INT;
                }
 
              /* Now get the bits from the appropriate constant word.  */
              if (shift < HOST_BITS_PER_INT)
                value = TREE_INT_CST_LOW (val);
-             else if (shift < 2 * HOST_BITS_PER_INT)
+             else if (shift < 2 * HOST_BITS_PER_WIDE_INT)
                {
                  value = TREE_INT_CST_HIGH (val);
-                 shift -= HOST_BITS_PER_INT;
+                 shift -= HOST_BITS_PER_WIDE_INT;
                }
              else
                abort ();
-             byte |= ((value >> shift) & ((1 << this_time) - 1)) << next_bit;
+             byte |= ((value >> shift)
+                      & (((HOST_WIDE_INT) 1 << this_time) - 1)) << next_bit;
 #endif
              next_offset += this_time;
              byte_buffer_in_use = 1;
This page took 0.052363 seconds and 5 git commands to generate.