iris6.h (TARGET_IRIX6): New.
authorRichard Henderson <rth@redhat.com>
Sat, 18 Aug 2001 00:25:09 +0000 (17:25 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sat, 18 Aug 2001 00:25:09 +0000 (17:25 -0700)
        * config/mips/iris6.h (TARGET_IRIX6): New.
        (current_section_name, current_section_flags): New.
        (ASM_OUTPUT_ALIGN, ASM_FILE_START, ASM_FILE_END): New.
        (MAX_OFILE_ALIGNMENT): New.
        (ASM_OUTPUT_ALIGNED_LOCAL): Use bss_section.
        * config/mips/mips.c (mips_make_temp_file, temp_filename): Remove.
        (copy_file_data): Split out from
        (mips_asm_file_end): ... here.
        (mips_asm_file_start): Remove extra .section directive.  Use
        tmpfile instead of mips_make_temp_file.
        (mips_unique_section): Use const char * as needed for warnings.
        (iris6_asm_named_section_1): Renamed from iris6_asm_named_section;
        re-add align parameter.
        (iris6_asm_named_section): New.
        (iris_section_align_entry_eq, iris_section_align_entry_hash): New.
        (iris6_asm_output_align, iris6_section_align_1): New.
        (iris6_asm_file_start, iris6_asm_file_end): New.
        * config/mips/mips-protos.h: Update decls.

From-SVN: r44991

gcc/ChangeLog
gcc/config/mips/iris6.h
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c

index 2c27f79b2322940a57db1440c6de87bb21495bb5..da042fe084057e7f510210db8a7e2d30d7c97b02 100644 (file)
@@ -1,3 +1,24 @@
+2001-08-17  Richard Henderson  <rth@redhat.com>
+
+       * config/mips/iris6.h (TARGET_IRIX6): New.
+       (current_section_name, current_section_flags): New.
+       (ASM_OUTPUT_ALIGN, ASM_FILE_START, ASM_FILE_END): New.
+       (MAX_OFILE_ALIGNMENT): New.
+       (ASM_OUTPUT_ALIGNED_LOCAL): Use bss_section.
+       * config/mips/mips.c (mips_make_temp_file, temp_filename): Remove.
+       (copy_file_data): Split out from 
+       (mips_asm_file_end): ... here.
+       (mips_asm_file_start): Remove extra .section directive.  Use
+       tmpfile instead of mips_make_temp_file.
+       (mips_unique_section): Use const char * as needed for warnings.
+       (iris6_asm_named_section_1): Renamed from iris6_asm_named_section;
+       re-add align parameter.
+       (iris6_asm_named_section): New.
+       (iris_section_align_entry_eq, iris_section_align_entry_hash): New.
+       (iris6_asm_output_align, iris6_section_align_1): New.
+       (iris6_asm_file_start, iris6_asm_file_end): New.
+       * config/mips/mips-protos.h: Update decls.
+
 2001-08-17  Janis Johnson  <janis187@us.ibm.com>
 
        * doc/install.texi (Install GCC): Add links to build status pages.
index ee334870efb1e40d1dc5d9ce9dc34f7346ec86c2..ce9df16fff347afc88dc083b5f45152c91552a4d 100644 (file)
@@ -18,6 +18,9 @@ along with GNU CC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
+/* Let mips.c know we need the Irix6 functions.  */
+#define TARGET_IRIX6 1
+
 /* Default to -mabi=n32 and -mips3.  */
 #define MIPS_ISA_DEFAULT 3
 #define MIPS_ABI_DEFAULT ABI_N32
@@ -31,7 +34,7 @@ Boston, MA 02111-1307, USA.  */
 #include "mips/abi64.h"
 
 /* Irix6 assembler does handle DWARF2 directives.  Override setting in
- irix5.h file.  */
  irix5.h file.  */
 #undef DWARF2_UNWIND_INFO
 
 /* The Irix6 assembler will sometimes assign labels to the wrong
@@ -130,6 +133,7 @@ Boston, MA 02111-1307, USA.  */
 /* Force the generation of dwarf .debug_frame sections even if not
    compiling -g.  This guarantees that we can unwind the stack. */
 #define DWARF2_FRAME_INFO 1
+
 /* The size in bytes of a DWARF field indicating an offset or length
    relative to a debug info section, specified to be 4 bytes in the DWARF-2
    specification.  The SGI/MIPS ABI defines it to be the same as PTR_SIZE.  */
@@ -289,13 +293,61 @@ rdata_section ()                                                  \
        fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP_32);        \
       in_section = in_rdata;                                           \
     }                                                                  \
+}                                                                      \
+                                                                       \
+const char *                                                           \
+current_section_name ()                                                        \
+{                                                                      \
+  switch (in_section)                                                  \
+    {                                                                  \
+    case no_section:   return NULL;                                    \
+    case in_text:      return ".text";                                 \
+    case in_data:      return ".data";                                 \
+    case in_sdata:     return ".sdata";                                \
+    case in_bss:       return ".bss";                                  \
+    case in_rdata:                                                     \
+    case in_const:                                                     \
+      if (mips_abi != ABI_32 && mips_abi != ABI_O64)                   \
+       return ".rodata";                                               \
+      else                                                             \
+       return ".rdata";                                                \
+    case in_named:                                                     \
+      return in_named_name;                                            \
+    }                                                                  \
+  abort ();                                                            \
+}                                                                      \
+                                                                       \
+unsigned int                                                           \
+current_section_flags ()                                               \
+{                                                                      \
+  switch (in_section)                                                  \
+    {                                                                  \
+    case no_section:   return 0;                                       \
+    case in_text:      return SECTION_CODE;                            \
+    case in_data:      return SECTION_WRITE;                           \
+    case in_sdata:     return SECTION_WRITE | SECTION_SMALL;           \
+    case in_bss:       return SECTION_WRITE | SECTION_BSS;             \
+    case in_rdata:                                                     \
+    case in_const:     return 0;                                       \
+    case in_named:     return get_named_section_flags (in_named_name); \
+    }                                                                  \
+  abort ();                                                            \
 }
 
 /* Switch into a generic section.  */
 #undef TARGET_ASM_NAMED_SECTION
 #define TARGET_ASM_NAMED_SECTION  iris6_asm_named_section
 
-/* ??? Perhaps just include svr4.h in this file?  */
+/* SGI assembler needs all sorts of extra help to do alignment properly.  */
+#undef ASM_OUTPUT_ALIGN
+#define ASM_OUTPUT_ALIGN iris6_asm_output_align
+#undef ASM_FILE_START
+#define ASM_FILE_START  iris6_asm_file_start
+#undef ASM_FILE_END
+#define ASM_FILE_END   iris6_asm_file_end
+
+#undef MAX_OFILE_ALIGNMENT
+#define MAX_OFILE_ALIGNMENT (32768*8)
 
 /* ??? SGI assembler may core dump when compiling with -g.
    Sometimes as succeeds, but then we get a linker error. (cmds.c in 072.sc)
@@ -317,11 +369,10 @@ do                                                                           \
   {                                                                       \
     if (mips_abi != ABI_32 && mips_abi != ABI_O64)                        \
       {                                                                           \
-       fprintf (STREAM, "%s\n", BSS_SECTION_ASM_OP);                      \
+       bss_section ();                                                    \
        mips_declare_object (STREAM, NAME, "", ":\n", 0);                  \
        ASM_OUTPUT_ALIGN (STREAM, floor_log2 (ALIGN / BITS_PER_UNIT));     \
        ASM_OUTPUT_SKIP (STREAM, SIZE);                                    \
-       fprintf (STREAM, "%s\n", POPSECTION_ASM_OP);                       \
       }                                                                           \
     else                                                                  \
       mips_declare_object (STREAM, NAME, "\n\t.lcomm\t", ",%u\n", (SIZE)); \
index 6a83b0260b3818833430b5e399c9d1f5698e52b1..5cc409c339771bcadc4b8db6d77085b7728a4035 100644 (file)
@@ -29,6 +29,11 @@ Boston, MA 02111-1307, USA.  */
 extern HOST_WIDE_INT   compute_frame_size PARAMS ((HOST_WIDE_INT));
 extern void            mips_asm_file_end PARAMS ((FILE *));
 extern void            mips_asm_file_start PARAMS ((FILE *));
+extern void            iris6_asm_file_start PARAMS ((FILE *));
+extern void            iris6_asm_file_end PARAMS ((FILE *));
+extern void            iris6_asm_output_align PARAMS ((FILE *, unsigned));
+extern const char *    current_section_name PARAMS ((void));
+extern unsigned int    current_section_flags PARAMS ((void));
 extern int             mips_can_use_return_insn PARAMS ((void));
 extern void            mips_declare_object PARAMS ((FILE *, const char *, const char *, const char *, int));
 extern void            mips_expand_epilogue PARAMS ((void));
index 68d9e53dfff1540776a82701e1c0f136d6c46fb7..d9cdcf5d2583ac9a5409cf847c4da2aa55d8fa42 100644 (file)
@@ -40,7 +40,6 @@ Boston, MA 02111-1307, USA.  */
 #include "recog.h"
 #include "toplev.h"
 #include "output.h"
-
 #include "tree.h"
 #include "function.h"
 #include "expr.h"
@@ -50,6 +49,8 @@ Boston, MA 02111-1307, USA.  */
 #include "tm_p.h"
 #include "ggc.h"
 #include "gstab.h"
+#include "hashtab.h"
+#include "debug.h"
 #include "target.h"
 #include "target-def.h"
 
@@ -90,7 +91,6 @@ static void block_move_loop                   PARAMS ((rtx, rtx,
                                                         int,
                                                         rtx, rtx));
 static void block_move_call                    PARAMS ((rtx, rtx, rtx));
-static FILE *mips_make_temp_file               PARAMS ((void));
 static rtx mips_add_large_offset_to_sp         PARAMS ((HOST_WIDE_INT,
                                                         FILE *));
 static void mips_annotate_frame_insn           PARAMS ((rtx, rtx));
@@ -115,8 +115,18 @@ static void mips_add_gc_roots                   PARAMS ((void));
 static void mips_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
 static void mips_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
 static enum processor_type mips_parse_cpu       PARAMS ((const char *));
+static void copy_file_data                     PARAMS ((FILE *, FILE *));
+#ifdef TARGET_IRIX6
+static void iris6_asm_named_section_1          PARAMS ((const char *,
+                                                        unsigned int,
+                                                        unsigned int));
 static void iris6_asm_named_section            PARAMS ((const char *,
                                                         unsigned int));
+static int iris_section_align_entry_eq         PARAMS ((const PTR, const PTR));
+static hashval_t iris_section_align_entry_hash PARAMS ((const PTR));
+static int iris6_section_align_1               PARAMS ((void **, void *));
+#endif
+
 /* Global variables for machine-dependent things.  */
 
 /* Threshold for data being put into the small data/bss area, instead
@@ -276,10 +286,6 @@ struct mips_frame_info current_frame_info;
 /* Zero structure to initialize current_frame_info.  */
 struct mips_frame_info zero_frame_info;
 
-/* Temporary filename used to buffer .text until end of program
-   for -mgpopt.  */
-static char *temp_filename;
-
 /* Pseudo-reg holding the address of the current function when
    generating embedded PIC code.  Created by LEGITIMIZE_ADDRESS, used
    by mips_finalize_pic if it was created.  */
@@ -5786,20 +5792,6 @@ mips_output_external_libcall (file, name)
 }
 #endif
 \f
-/* Compute a string to use as a temporary file name.  */
-
-static FILE *
-mips_make_temp_file ()
-{
-  FILE *stream;
-
-  temp_filename = make_temp_file (0);
-  stream = fopen (temp_filename, "w+");
-  if (!stream)
-    fatal_io_error ("can't open %s", temp_filename);
-  return stream;
-}
-\f
 /* Emit a new filename to a stream.  If this is MIPS ECOFF, watch out
    for .file's that start within a function.  If we are smuggling stabs, try to
    put out a MIPS ECOFF file and a stab.  */
@@ -6045,20 +6037,14 @@ mips_asm_file_start (stream)
   if (TARGET_MIPS16)
     fprintf (stream, "\t.set\tmips16\n");
 
-  /* Start a section, so that the first .popsection directive is guaranteed
-     to have a previously defined section to pop back to.  */
-  if (mips_abi != ABI_32 && mips_abi != ABI_O64 && mips_abi != ABI_EABI)
-    fprintf (stream, "\t.section\t.text\n");
-
   /* This code exists so that we can put all externs before all symbol
      references.  This is necessary for the MIPS assembler's global pointer
      optimizations to work.  */
   if (TARGET_FILE_SWITCHING)
     {
       asm_out_data_file = stream;
-      asm_out_text_file = mips_make_temp_file ();
+      asm_out_text_file = tmpfile ();
     }
-
   else
     asm_out_data_file = asm_out_text_file = stream;
 
@@ -6077,10 +6063,8 @@ void
 mips_asm_file_end (file)
      FILE *file;
 {
-  char buffer[8192];
   tree name_tree;
   struct extern_list *p;
-  int len;
 
   if (HALF_PIC_P ())
     {
@@ -6116,23 +6100,30 @@ mips_asm_file_end (file)
   if (TARGET_FILE_SWITCHING)
     {
       fprintf (file, "\n\t.text\n");
-      rewind (asm_out_text_file);
-      if (ferror (asm_out_text_file))
-       fatal_io_error ("can't rewind %s", temp_filename);
+      copy_file_data (file, asm_out_text_file);
+    }
+}
 
-      while ((len = fread (buffer, 1, sizeof (buffer), asm_out_text_file)) > 0)
-       if ((int) fwrite (buffer, 1, len, file) != len)
-         fatal_io_error ("can't write to %s", asm_file_name);
+static void
+copy_file_data (to, from)
+     FILE *to, *from;
+{
+  char buffer[8192];
+  size_t len;
 
-      if (len < 0)
-       fatal_io_error ("can't read from %s", temp_filename);
+  rewind (from);
+  if (ferror (from))
+    fatal_io_error ("can't rewind temp file");
 
-      if (fclose (asm_out_text_file) != 0)
-       fatal_io_error ("can't close %s", temp_filename);
+  while ((len = fread (buffer, 1, sizeof (buffer), from)) > 0)
+    if (fwrite (buffer, 1, len, to) != len)
+      fatal_io_error ("can't write to output file");
 
-      unlink (temp_filename);
-      free (temp_filename);
-    }
+  if (ferror (from))
+    fatal_io_error ("can't read from temp file");
+
+  if (fclose (from))
+    fatal_io_error ("can't close temp file");
 }
 
 /* Emit either a label, .comm, or .lcomm directive, and mark that the symbol
@@ -9752,43 +9743,6 @@ mips_parse_cpu (cpu_string)
   return cpu;
 }
 
-/* Output assembly to switch to section NAME with attribute FLAGS.  */
-
-static void
-iris6_asm_named_section (name, flags)
-     const char *name;
-     unsigned int flags;
-{
-  unsigned int sh_type, sh_flags, sh_entsize;
-
-  sh_flags = 0;
-  if (!(flags & SECTION_DEBUG))
-    sh_flags |= 2; /* SHF_ALLOC */
-  if (flags & SECTION_WRITE)
-    sh_flags |= 1; /* SHF_WRITE */
-  if (flags & SECTION_CODE)
-    sh_flags |= 4; /* SHF_EXECINSTR */
-  if (flags & SECTION_SMALL)
-    sh_flags |= 0x10000000; /* SHF_MIPS_GPREL */
-  if (strcmp (name, ".debug_frame") == 0)
-    sh_flags |= 0x08000000; /* SHF_MIPS_NOSTRIP */
-
-  if (flags & SECTION_DEBUG)
-    sh_type = 0x7000001e; /* SHT_MIPS_DWARF */
-  else if (flags & SECTION_BSS)
-    sh_type = 8; /* SHT_NOBITS */
-  else
-    sh_type = 1; /* SHT_PROGBITS */
-
-  if (flags & SECTION_CODE)
-    sh_entsize = 4;
-  else
-    sh_entsize = 0;
-
-  fprintf (asm_out_file, "\t.section %s,%u,%u,%u,%u\n",
-          name, sh_type, sh_flags, sh_entsize, 0);
-}
-
 /* Cover function for UNIQUE_SECTION.  */
 
 void
@@ -9797,8 +9751,9 @@ mips_unique_section (decl, reloc)
      int reloc;
 {
   int len, size, sec;
-  char *name, *string, *prefix;
-  static char *prefixes[4][2] = {
+  const char *name, *prefix;
+  char *string;
+  static const char *prefixes[4][2] = {
     { ".text.", ".gnu.linkonce.t." },
     { ".rodata.", ".gnu.linkonce.r." },
     { ".data.", ".gnu.linkonce.d." },
@@ -9860,3 +9815,164 @@ mips_unique_section (decl, reloc)
 
   DECL_SECTION_NAME (decl) = build_string (len, string);
 }
+\f
+#ifdef TARGET_IRIX6
+/* Output assembly to switch to section NAME with attribute FLAGS.  */
+
+static void
+iris6_asm_named_section_1 (name, flags, align)
+     const char *name;
+     unsigned int flags;
+     unsigned int align;
+{
+  unsigned int sh_type, sh_flags, sh_entsize;
+
+  sh_flags = 0;
+  if (!(flags & SECTION_DEBUG))
+    sh_flags |= 2; /* SHF_ALLOC */
+  if (flags & SECTION_WRITE)
+    sh_flags |= 1; /* SHF_WRITE */
+  if (flags & SECTION_CODE)
+    sh_flags |= 4; /* SHF_EXECINSTR */
+  if (flags & SECTION_SMALL)
+    sh_flags |= 0x10000000; /* SHF_MIPS_GPREL */
+  if (strcmp (name, ".debug_frame") == 0)
+    sh_flags |= 0x08000000; /* SHF_MIPS_NOSTRIP */
+
+  if (flags & SECTION_DEBUG)
+    sh_type = 0x7000001e; /* SHT_MIPS_DWARF */
+  else if (flags & SECTION_BSS)
+    sh_type = 8; /* SHT_NOBITS */
+  else
+    sh_type = 1; /* SHT_PROGBITS */
+
+  if (flags & SECTION_CODE)
+    sh_entsize = 4;
+  else
+    sh_entsize = 0;
+
+  fprintf (asm_out_file, "\t.section %s,%#x,%#x,%u,%u\n",
+          name, sh_type, sh_flags, sh_entsize, align);
+}
+
+static void
+iris6_asm_named_section (name, flags)
+     const char *name;
+     unsigned int flags;
+{
+  if (TARGET_FILE_SWITCHING && (flags & SECTION_CODE))
+    asm_out_file = asm_out_text_file;
+  iris6_asm_named_section_1 (name, flags, 0);
+}
+
+/* In addition to emitting a .align directive, record the maximum
+   alignment requested for the current section.  */
+
+struct iris_section_align_entry
+{
+  const char *name;
+  unsigned int log;
+  unsigned int flags;
+};
+
+static htab_t iris_section_align_htab;
+static FILE *iris_orig_asm_out_file;
+
+static int
+iris_section_align_entry_eq (p1, p2)
+     const PTR p1;
+     const PTR p2;
+{
+  const struct iris_section_align_entry *old = p1;
+  const char *new = p2;
+
+  return strcmp (old->name, new) == 0;
+}
+
+static hashval_t
+iris_section_align_entry_hash (p)
+     const PTR p;
+{
+  const struct iris_section_align_entry *old = p;
+  return htab_hash_string (old->name);
+}
+
+void
+iris6_asm_output_align (file, log)
+     FILE *file;
+     unsigned int log;
+{
+  const char *section = current_section_name ();
+  struct iris_section_align_entry **slot, *entry;
+
+  if (! section)
+    abort ();
+
+  slot = (struct iris_section_align_entry **)
+    htab_find_slot_with_hash (iris_section_align_htab, section,
+                             htab_hash_string (section), INSERT);
+  entry = *slot;
+  if (! entry)
+    {
+      entry = (struct iris_section_align_entry *)
+       xmalloc (sizeof (struct iris_section_align_entry));
+      *slot = entry;
+      entry->name = section;
+      entry->log = log;
+      entry->flags = current_section_flags ();
+    }
+  else if (entry->log < log)
+    entry->log = log;
+
+  fprintf (file, "\t.align\t%u\n", log);
+}
+
+/* The Iris assembler does not record alignment from .align directives,
+   but takes it from the first .section directive seen.  Play yet more
+   file switching games so that we can emit a .section directive at the
+   beginning of the file with the proper alignment attached.  */
+   
+void
+iris6_asm_file_start (stream)
+     FILE *stream;
+{
+  mips_asm_file_start (stream);
+
+  iris_orig_asm_out_file = asm_out_file;
+  stream = tmpfile ();
+  asm_out_file = stream;
+  asm_out_data_file = stream;
+  if (! TARGET_FILE_SWITCHING)
+    asm_out_text_file = stream;
+
+  iris_section_align_htab = htab_create (31, iris_section_align_entry_hash,
+                                        iris_section_align_entry_eq, NULL);
+}
+
+static int
+iris6_section_align_1 (slot, data)
+     void **slot;
+     void *data ATTRIBUTE_UNUSED;
+{
+  const struct iris_section_align_entry *entry
+    = *(const struct iris_section_align_entry **) slot;
+
+  iris6_asm_named_section_1 (entry->name, entry->flags, 1 << entry->log);
+  return 1;
+}
+
+void
+iris6_asm_file_end (stream)
+     FILE *stream;
+{
+  /* Emit section directives with the proper alignment at the top of the
+     real output file.  */
+  asm_out_file = iris_orig_asm_out_file;
+  htab_traverse (iris_section_align_htab, iris6_section_align_1, NULL);
+
+  /* Copy the data emitted to the temp file to the real output file.  */
+  copy_file_data (asm_out_file, stream);
+
+  mips_asm_file_end (stream);
+}
+#endif /* TARGET_IRIX6 */