From cbd5f1a1e51fb0ea06167ddc208d4e8f6935b2d0 Mon Sep 17 00:00:00 2001 From: rth Date: Sat, 18 Aug 2001 00:25:09 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44991 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 21 ++++ gcc/config/mips/iris6.h | 59 ++++++++- gcc/config/mips/mips-protos.h | 5 + gcc/config/mips/mips.c | 278 ++++++++++++++++++++++++++++++------------ 4 files changed, 278 insertions(+), 85 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2c27f79..da042fe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2001-08-17 Richard Henderson + + * 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 * doc/install.texi (Install GCC): Add links to build status pages. diff --git a/gcc/config/mips/iris6.h b/gcc/config/mips/iris6.h index ee33487..ce9df16 100644 --- a/gcc/config/mips/iris6.h +++ b/gcc/config/mips/iris6.h @@ -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)); \ diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 6a83b02..5cc409c 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -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)); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 68d9e53..d9cdcf5 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -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 -/* 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; -} - /* 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); } + +#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 */ -- 2.7.4