OSDN Git Service

Add -mabi=n32 support.
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index 052f703..5d5eb45 100644 (file)
@@ -138,9 +138,14 @@ void fancy_abort ();
 void abort ();
 #endif
 void set_target_switch ();
-static void print_switch_values ();
 static char *decl_name ();
 
+void print_version ();
+int print_single_switch ();
+void print_switch_values ();
+/* Length of line when printing switch values.  */
+#define MAX_LINE 75
+
 #ifdef __alpha
 extern char *sbrk ();
 #endif
@@ -272,6 +277,10 @@ void (*incomplete_decl_finalize_hook) () = 0;
 
 void (*interim_eh_hook)        PROTO((tree));
 
+/* Highest label number used at the end of reload.  */
+
+int max_label_num_after_reload;
+
 /* Nonzero if generating code to do profiling.  */
 
 int profile_flag = 0;
@@ -403,6 +412,11 @@ int flag_no_function_cse = 0;
 
 int flag_omit_frame_pointer = 0;
 
+/* Nonzero means place each function into its own section on those platforms
+   which support arbitrary section names and unlimited numbers of sections.  */
+
+int flag_function_sections = 0;
+
 /* Nonzero to inhibit use of define_optimization peephole opts.  */
 
 int flag_no_peephole = 0;
@@ -473,7 +487,8 @@ int flag_short_temps;
 
 int flag_pic;
 
-/* Nonzero means place uninitialized global data in the bss section. */
+/* Nonzero means don't place uninitialized global data in common storage
+   by default. */
 
 int flag_no_common;
 
@@ -505,9 +520,20 @@ int flag_inhibit_size_directive = 0;
 /* -fverbose-asm causes extra commentary information to be produced in
    the generated assembly code (to make it more readable).  This option
    is generally only of use to those who actually need to read the
-   generated assembly code (perhaps while debugging the compiler itself).  */
+   generated assembly code (perhaps while debugging the compiler itself).
+   -fverbose-asm is the default.  -fno-verbose-asm causes the extra information
+   to be omitted and is useful when comparing two assembler files.  */
 
-int flag_verbose_asm = 0;
+int flag_verbose_asm = 1;
+
+/* -dA causes debug commentary information to be produced in
+   the generated assembly code (to make it more readable).  This option
+   is generally only of use to those who actually need to read the
+   generated assembly code (perhaps while debugging the compiler itself).
+   Currently, this switch is only used by dwarfout.c; however, it is intended
+   to be a catchall for printing debug information in the assembler file.  */
+
+int flag_debug_asm = 0;
 
 /* -fgnu-linker specifies use of the GNU linker for initializations.
    (Or, more generally, a linker that handles initializations.)
@@ -564,6 +590,7 @@ struct { char *string; int *variable; int on_value;} f_options[] =
   {"fast-math", &flag_fast_math, 1},
   {"common", &flag_no_common, 0},
   {"inhibit-size-directive", &flag_inhibit_size_directive, 1},
+  {"function-sections", &flag_function_sections, 1},
   {"verbose-asm", &flag_verbose_asm, 1},
   {"gnu-linker", &flag_gnu_linker, 1},
   {"pack-struct", &flag_pack_struct, 1},
@@ -936,6 +963,8 @@ fatal_insn (message, insn)
     fflush (dbr_sched_dump_file);
   if (stack_reg_dump_file)
     fflush (stack_reg_dump_file);
+  fflush (stdout);
+  fflush (stderr);
   abort ();
 }
 
@@ -1755,6 +1784,20 @@ xrealloc (ptr, size)
     fatal ("virtual memory exhausted");
   return result;
 }
+
+/* Same as `strdup' but report error if no memory available.  */
+
+char *
+xstrdup (s)
+     register char *s;
+{
+  register char *result = (char *) malloc (strlen (s) + 1);
+
+  if (! result)
+    fatal ("virtual memory exhausted");
+  strcpy (result, s);
+  return result;
+}
 \f
 /* Return the logarithm of X, base 2, considering X unsigned,
    if X is a power of 2.  Otherwise, returns -1.
@@ -2151,6 +2194,19 @@ compile_file (name)
   if (!output_bytecode)
     {
       ASM_FILE_START (asm_out_file);
+
+#ifdef ASM_COMMENT_START
+      if (flag_verbose_asm)
+       {
+         /* Print the list of options in effect.  */
+         print_version (asm_out_file, ASM_COMMENT_START);
+         print_switch_values (asm_out_file, 0, MAX_LINE,
+                              ASM_COMMENT_START, " ", "\n");
+         /* Add a blank line here so it appears in assembler output but not
+            screen output.  */
+         fprintf (asm_out_file, "\n");
+       }
+#endif
     }
 
   /* Output something to inform GDB that this compilation was by GCC.  Also
@@ -2171,6 +2227,24 @@ compile_file (name)
   ASM_IDENTIFY_LANGUAGE (asm_out_file);
 #endif
 
+#ifndef ASM_OUTPUT_SECTION_NAME
+  if (flag_function_sections)
+    {
+      warning ("-ffunction-sections not supported for this target.");
+      flag_function_sections = 0;
+    }
+#endif
+
+  if (flag_function_sections
+      && (profile_flag || profile_block_flag))
+    {
+      warning ("-ffunction-sections disabled; it makes profiling impossible.");
+      flag_function_sections = 0;
+    }
+
+  if (flag_function_sections && write_symbols != NO_DEBUG)
+    warning ("-ffunction-sections may affect debugging on some targets.");
+
   if (output_bytecode)
     {
       if (profile_flag || profile_block_flag)
@@ -2353,6 +2427,7 @@ compile_file (name)
                || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
            && DECL_INITIAL (decl) == 0
            && DECL_EXTERNAL (decl)
+           && ! DECL_ARTIFICIAL (decl)
            && ! TREE_PUBLIC (decl))
          {
            pedwarn_with_decl (decl, 
@@ -2594,7 +2669,8 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
                        && (DECL_INITIAL (decl) == 0
                            || DECL_INITIAL (decl) == error_mark_node)))
                   assemble_variable (decl, top_level, at_end, 0);
-              if (decl == last_assemble_variable_decl)
+              if (!output_bytecode
+                  && decl == last_assemble_variable_decl)
                 {
                   ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
                                              top_level, at_end);
@@ -3072,6 +3148,10 @@ rest_of_compilation (decl)
             fprintf (global_reg_dump_file, "\n;; Function %s\n\n",
                      IDENTIFIER_POINTER (DECL_NAME (decl))));
 
+  /* Save the last label number used so far, so reorg can tell
+     when it's safe to kill spill regs.  */
+  max_label_num_after_reload = max_label_num ();
+
   /* Unless we did stupid register allocation,
      allocate remaining pseudo-regs, then do the reload pass
      fixing up any insns that are invalid.  */
@@ -3520,10 +3600,12 @@ main (argc, argv, envp)
                  case 'y':
                    set_yydebug (1);
                    break;
-
                  case 'x':
                    rtl_dump_and_exit = 1;
                    break;
+                 case 'A':
+                   flag_debug_asm = 1;
+                   break;
                  }
            }
          else if (str[0] == 'f')
@@ -3665,10 +3747,7 @@ main (argc, argv, envp)
            }
          else if (!strcmp (str, "p"))
            {
-             if (!output_bytecode)
-               profile_flag = 1;
-             else
-               error ("profiling not supported in bytecode compilation");
+             profile_flag = 1;
            }
          else if (!strcmp (str, "a"))
            {
@@ -3912,20 +3991,9 @@ You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
      option flags in use.  */
   if (version_flag)
     {
-      fprintf (stderr, "%s version %s", language_string, version_string);
-#ifdef TARGET_VERSION
-      TARGET_VERSION;
-#endif
-#ifdef __GNUC__
-#ifndef __VERSION__
-#define __VERSION__ "[unknown]"
-#endif
-      fprintf (stderr, " compiled by GNU C version %s.\n", __VERSION__);
-#else
-      fprintf (stderr, " compiled by CC.\n");
-#endif
+      print_version (stderr, "");
       if (! quiet_flag)
-       print_switch_values ();
+       print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n");
     }
 
   compile_file (filename);
@@ -4009,51 +4077,128 @@ set_target_switch (name)
     error ("Invalid option `%s'", name);
 }
 \f
-/* Variable used for communication between the following two routines.  */
-
-static int line_position;
-
-/* Print an option value and adjust the position in the line.  */
+/* Print version information to FILE.
+   Each line begins with INDENT (for the case where FILE is the
+   assembler output file).  */
 
-static void
-print_single_switch (type, name)
-     char *type, *name;
+void
+print_version (file, indent)
+     FILE *file;
+     char *indent;
 {
-  fprintf (stderr, " %s%s", type, name);
+  fprintf (file, "%s%s%s version %s", indent, *indent != 0 ? " " : "",
+          language_string, version_string);
+  fprintf (file, " (%s)", TARGET_NAME);
+#ifdef __GNUC__
+#ifndef __VERSION__
+#define __VERSION__ "[unknown]"
+#endif
+  fprintf (file, " compiled by GNU C version %s.\n", __VERSION__);
+#else
+  fprintf (file, " compiled by CC.\n");
+#endif
+}
 
-  line_position += strlen (type) + strlen (name) + 1;
+/* Print an option value and return the adjusted position in the line.
+   ??? We don't handle error returns from fprintf (disk full).  */
 
-  if (line_position > 65)
+int
+print_single_switch (file, pos, max, indent, sep, term, type, name)
+     FILE *file;
+     int pos, max;
+     char *indent, *sep, *term, *type, *name;
+{
+  if (pos != 0
+      && pos + strlen (sep) + strlen (type) + strlen (name) > max)
+    {
+      fprintf (file, "%s", term);
+      pos = 0;
+    }
+  if (pos == 0)
     {
-      fprintf (stderr, "\n\t");
-      line_position = 8;
+      pos = fprintf (file, "%s", indent);
     }
+  pos += fprintf (file, "%s%s%s", sep, type, name);
+  return pos;
 }
      
-/* Print default target switches for -version.  */
+/* Print active target switches to FILE.
+   POS is the current cursor position and MAX is the size of a "line".
+   Each line begins with INDENT and ends with TERM.
+   Each switch is separated from the next by SEP.  */
 
-static void
-print_switch_values ()
+void
+print_switch_values (file, pos, max, indent, sep, term)
+     FILE *file;
+     int pos, max;
+     char *indent, *sep, *term;
 {
-  register int j;
+  int j, flags;
+  char **p;
+
+  /* Print the options as passed.  */
+
+  pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term,
+                            "options passed: ", "");
+
+  for (p = &save_argv[1]; *p != NULL; p++)
+    if (**p == '-')
+      {
+       /* Ignore these.  */
+       if (strcmp (*p, "-o") == 0)
+         {
+           if (p[1] != NULL)
+             p++;
+           continue;
+         }
+       if (strcmp (*p, "-quiet") == 0)
+         continue;
+       if (strcmp (*p, "-version") == 0)
+         continue;
+       if ((*p)[1] == 'd')
+         continue;
+
+       pos = print_single_switch (file, pos, max, indent, sep, term, *p, "");
+      }
+  if (pos > 0)
+    fprintf (file, "%s", term);
+
+  /* Print the -f and -m options that have been enabled.
+     We don't handle language specific options but printing argv
+     should suffice.  */
 
-  fprintf (stderr, "enabled:");
-  line_position = 8;
+  pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term,
+                            "options enabled: ", "");
 
   for (j = 0; j < sizeof f_options / sizeof f_options[0]; j++)
     if (*f_options[j].variable == f_options[j].on_value)
-      print_single_switch ("-f", f_options[j].string);
+      pos = print_single_switch (file, pos, max, indent, sep, term,
+                                "-f", f_options[j].string);
 
-  for (j = 0; j < sizeof W_options / sizeof W_options[0]; j++)
-    if (*W_options[j].variable == W_options[j].on_value)
-      print_single_switch ("-W", W_options[j].string);
+  /* Print target specific options.  */
 
+  flags = target_flags;
   for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
     if (target_switches[j].name[0] != '\0'
        && target_switches[j].value > 0
        && ((target_switches[j].value & target_flags)
            == target_switches[j].value))
-      print_single_switch ("-m", target_switches[j].name);
+      {
+       pos = print_single_switch (file, pos, max, indent, sep, term,
+                                  "-m", target_switches[j].name);
+       flags &= ~ target_switches[j].value;
+      }
+
+#ifdef TARGET_OPTIONS
+  for (j = 0; j < sizeof target_options / sizeof target_options[0]; j++)
+    if (*target_options[j].variable != NULL)
+      {
+       char prefix[256];
+       sprintf (prefix, "-m%s", target_options[j].prefix);
+       pos = print_single_switch (file, pos, max, indent, sep, term,
+                                  prefix, *target_options[j].variable);
+      }
+#endif
 
-  fprintf (stderr, "\n");
+  fprintf (file, "%s", term);
 }