OSDN Git Service

1998-10-28 16:10 -0500 Zack Weinberg <zack@rabi.phys.columbia.edu>
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index 1922384..acf3d43 100644 (file)
@@ -24,48 +24,12 @@ Boston, MA 02111-1307, USA.  */
    Error messages and low-level interface to malloc also handled here.  */
 
 #include "config.h"
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#include <stdio.h>
+#undef FLOAT /* This is for hpux. They should change hpux.  */
+#undef FFS  /* Some systems define this in param.h.  */
+#include "system.h"
 #include <signal.h>
 #include <setjmp.h>
-#include <sys/types.h>
-#include <ctype.h>
 #include <sys/stat.h>
-#undef FLOAT
-#ifdef HAVE_SYS_PARAM_H
-#include <sys/param.h>
-#endif
-#if HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#undef FLOAT /* This is for hpux. They should change hpux.  */
-#undef FFS  /* Some systems define this in param.h.  */
-
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-#  include <time.h>
-#endif
-#endif
 
 #ifdef HAVE_SYS_RESOURCE_H
 # include <sys/resource.h>
@@ -80,9 +44,30 @@ Boston, MA 02111-1307, USA.  */
 #include "rtl.h"
 #include "flags.h"
 #include "insn-attr.h"
+#include "insn-codes.h"
+#include "insn-config.h"
+#include "recog.h"
 #include "defaults.h"
 #include "output.h"
 #include "except.h"
+#include "toplev.h"
+#include "expr.h"
+
+#ifdef DWARF_DEBUGGING_INFO
+#include "dwarfout.h"
+#endif
+
+#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
+#include "dwarf2out.h"
+#endif
+
+#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
+#include "dbxout.h"
+#endif
+
+#ifdef SDB_DEBUGGING_INFO
+#include "sdbout.h"
+#endif
 
 #ifdef XCOFF_DEBUGGING_INFO
 #include "xcoffout.h"
@@ -159,7 +144,8 @@ extern char *version_string, *language_string;
 extern int size_directive_output;
 extern tree last_assemble_variable_decl;
 
-extern void init_lex ();
+extern char *init_parse PVPROTO((char *));
+extern void finish_parse ();
 extern void init_decl_processing ();
 extern void init_obstacks ();
 extern void init_tree_codes ();
@@ -179,36 +165,54 @@ extern void print_rtl_with_bb ();
 void rest_of_decl_compilation ();
 void error_with_file_and_line PVPROTO((char *file, int line, char *s, ...));
 void error_with_decl PVPROTO((tree decl, char *s, ...));
-void error_for_asm PVPROTO((rtx insn, char *s, ...));
 void error PVPROTO((char *s, ...));
 void fatal PVPROTO((char *s, ...));
 void warning_with_file_and_line PVPROTO((char *file, int line, char *s, ...));
 void warning_with_decl PVPROTO((tree decl, char *s, ...));
-void warning_for_asm PVPROTO((rtx insn, char *s, ...));
 void warning PVPROTO((char *s, ...));
 void pedwarn PVPROTO((char *s, ...));
 void pedwarn_with_decl PVPROTO((tree decl, char *s, ...));
 void pedwarn_with_file_and_line PVPROTO((char *file, int line, char *s, ...));
 void sorry PVPROTO((char *s, ...));
-void really_sorry PVPROTO((char *s, ...));
-void fancy_abort ();
-void set_target_switch ();
-static char *decl_name ();
-
-void print_version ();
-int print_single_switch ();
-void print_switch_values ();
+static void set_target_switch PROTO((char *));
+static char *decl_name PROTO((tree, int));
+static void vmessage PROTO((char *, char *, va_list));
+static void v_message_with_file_and_line PROTO((char *, int, char *,
+                                               char *, va_list));
+static void v_message_with_decl PROTO((tree, char *, char *, va_list));
+static void file_and_line_for_asm PROTO((rtx, char **, int *));
+static void v_error_with_file_and_line PROTO((char *, int, char *, va_list));
+static void v_error_with_decl PROTO((tree, char *, va_list));
+static void v_error_for_asm PROTO((rtx, char *, va_list));
+static void verror PROTO((char *, va_list));
+static void vfatal PROTO((char *, va_list)) ATTRIBUTE_NORETURN;
+static void v_warning_with_file_and_line PROTO ((char *, int, char *, va_list));
+static void v_warning_with_decl PROTO((tree, char *, va_list));
+static void v_warning_for_asm PROTO((rtx, char *, va_list));
+static void vwarning PROTO((char *, va_list));
+static void vpedwarn PROTO((char *, va_list));
+static void v_pedwarn_with_decl PROTO((tree, char *, va_list));
+static void v_pedwarn_with_file_and_line PROTO((char *, int, char *, va_list));
+static void vsorry PROTO((char *, va_list));
+static void v_really_sorry PROTO((char *, va_list)) ATTRIBUTE_NORETURN;
+static void float_signal PROTO((int)) ATTRIBUTE_NORETURN;
+static void pipe_closed PROTO((int)) ATTRIBUTE_NORETURN;
+static void output_lang_identify PROTO((FILE *));
+static void open_dump_file PROTO((char *, char *));
+static void close_dump_file PROTO((void (*) (FILE *, rtx), rtx));
+static void dump_rtl PROTO((char *, tree, void (*) (FILE *, rtx), rtx));
+static void clean_dump_file PROTO((char *));
+static void compile_file PROTO((char *));
+static void display_help PROTO ((void));
+
+static void print_version PROTO((FILE *, char *));
+static int print_single_switch PROTO((FILE *, int, int, char *, char *, char *,
+                                     char *, char *));
+static void print_switch_values PROTO((FILE *, int, int, char *, char *,
+                                      char *));
 /* Length of line when printing switch values.  */
 #define MAX_LINE 75
 
-#ifdef NEED_DECLARATION_ABORT
-void abort ();
-#endif
-
-#ifdef NEED_DECLARATION_SBRK
-extern char *sbrk ();
-#endif
-
 /* Name of program invoked, sans directories.  */
 
 char *progname;
@@ -228,11 +232,6 @@ char *input_filename;
 
 char *main_input_filename;
 
-#if !USE_CPPLIB
-/* Stream for reading from the input file.  */
-FILE *finput;
-#endif
-
 /* Current line number in real source file.  */
 
 int lineno;
@@ -265,6 +264,7 @@ int rtl_dump_and_exit = 0;
 int jump_opt_dump = 0;
 int addressof_dump = 0;
 int cse_dump = 0;
+int gcse_dump = 0;
 int loop_dump = 0;
 int cse2_dump = 0;
 int branch_prob_dump = 0;
@@ -340,20 +340,20 @@ int sorrycount = 0;
      2: and any other information that might be interesting, such as function
         parameter types in C++.  */
 
-char *(*decl_printable_name) (/* tree decl, int verbosity */);
+char *(*decl_printable_name)           PROTO ((tree, int));
 
 /* Pointer to function to compute rtl for a language-specific tree code.  */
 
-struct rtx_def *(*lang_expand_expr) ();
+typedef rtx (*lang_expand_expr_t)
+  PROTO ((union tree_node *, rtx, enum machine_mode,
+         enum expand_modifier modifier));
+
+lang_expand_expr_t lang_expand_expr = 0;
 
 /* Pointer to function to finish handling an incomplete decl at the
    end of compilation.  */
 
-void (*incomplete_decl_finalize_hook) () = 0;
-
-/* Highest label number used at the end of reload.  */
-
-int max_label_num_after_reload;
+void (*incomplete_decl_finalize_hook) PROTO((tree)) = 0;
 
 /* Nonzero if generating code to do profiling.  */
 
@@ -492,6 +492,11 @@ int flag_move_all_movables = 0;
 
 int flag_reduce_all_givs = 0;
 
+/* Nonzero to perform full register move optimization passes.  This is the
+   default for -O2.  */
+
+int flag_regmove = 0;
+
 /* Nonzero for -fwritable-strings:
    store string constants in data segment and don't uniquize them.  */
 
@@ -513,6 +518,10 @@ int flag_omit_frame_pointer = 0;
 
 int flag_function_sections = 0;
 
+/* ... and similar for data.  */
+int flag_data_sections = 0;
+
 /* Nonzero to inhibit use of define_optimization peephole opts.  */
 
 int flag_no_peephole = 0;
@@ -536,6 +545,10 @@ int flag_volatile_global;
 
 int flag_syntax_only = 0;
 
+/* Nonzero means perform global cse.  */
+
+static int flag_gcse;
+
 /* Nonzero means to rerun cse after loop optimization.  This increases
    compilation time about 20% and picks up a few more common expressions.  */
 
@@ -591,7 +604,12 @@ int flag_pic;
 /* Nonzero means generate extra code for exception handling and enable
    exception handling.  */
 
-int flag_exceptions = 2;
+int flag_exceptions;
+
+/* Nonzero means use the new model for exception handling. Replaces 
+   -DNEW_EH_MODEL as a compile option. */
+
+int flag_new_exceptions = 0;
 
 /* Nonzero means don't place uninitialized global data in common storage
    by default.  */
@@ -632,12 +650,11 @@ int flag_schedule_interblock = 1;
 int flag_schedule_speculative = 1;
 int flag_schedule_speculative_load = 0;
 int flag_schedule_speculative_load_dangerous = 0;
+#endif  /* HAIFA */
 
 /* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple
    by a cheaper branch, on a count register. */
 int flag_branch_on_count_reg;
-#endif  /* HAIFA */
-
 
 /* -finhibit-size-directive inhibits output of .size for ELF.
    This is used only for compiling crtstuff.c, 
@@ -689,8 +706,6 @@ int flag_check_memory_usage = 0;
    -fcheck-memory-usage.  */
 int flag_prefix_function_name = 0;
 
-int flag_regmove = 0;
-
 /* 0 if pointer arguments may alias each other.  True in C.
    1 if pointer arguments may not alias each other but may alias
    global variables.
@@ -699,190 +714,414 @@ int flag_regmove = 0;
    This defaults to 0 for C.  */
 int flag_argument_noalias = 0;
 
+/* Nonzero if we should do (language-dependent) alias analysis.
+   Typically, this analysis will assume that expressions of certain
+   types do not alias expressions of certain other types.  Only used
+   if alias analysis (in general) is enabled.  */
+int flag_strict_aliasing = 0;
+
+/* Instrument functions with calls at entry and exit, for profiling.  */
+int flag_instrument_function_entry_exit = 0;
+
+
+/* Table of supported debugging formats.  */
+static struct
+{
+  char * arg;
+  /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a
+     constant expression, we use NO_DEBUG in its place.  */
+  enum debug_info_type debug_type;
+  int use_extensions_p;
+  char * description;
+} *da,
+debug_args[] =
+{
+  { "g",    NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
+    "Generate default debug format output" },
+  { "ggdb", NO_DEBUG, 1, "Generate default extended debug format output" },
+#ifdef DBX_DEBUGGING_INFO
+  { "gstabs",  DBX_DEBUG, 0, "Generate STABS format debug output" },
+  { "gstabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" },
+#endif
+#ifdef DWARF_DEBUGGING_INFO
+  { "gdwarf",  DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"},
+  { "gdwarf+", DWARF_DEBUG, 1,
+    "Generated extended DWARF-1 format debug output" },
+#endif
+#ifdef DWARF2_DEBUGGING_INFO
+  { "gdwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" },
+#endif
+#ifdef XCOFF_DEBUGGING_INFO
+  { "gxcoff",  XCOFF_DEBUG, 0, "Generate XCOFF format debug output" },
+  { "gxcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" },
+#endif
+#ifdef SDB_DEBUGGING_INFO
+  { "gcoff", SDB_DEBUG, 0, "Generate COFF format debug output" },
+#endif
+  { 0, 0, 0, 0 }
+};
+
+typedef struct
+{
+  char * string;
+  int *  variable;
+  int    on_value;
+  char * description;
+}
+lang_independent_options;
+
+/* Add or remove a leading underscore from user symbols.  */
+int flag_leading_underscore = -1;
+
+/* The user symbol prefix after having resolved same.  */
+char *user_label_prefix;
+
+/* A default for same.  */
+#ifndef USER_LABEL_PREFIX
+#define USER_LABEL_PREFIX ""
+#endif
+
 /* Table of language-independent -f options.
    STRING is the option name.  VARIABLE is the address of the variable.
    ON_VALUE is the value to store in VARIABLE
     if `-fSTRING' is seen as an option.
    (If `-fno-STRING' is seen as an option, the opposite value is stored.)  */
 
-struct { char *string; int *variable; int on_value;} f_options[] =
+lang_independent_options f_options[] =
 {
-  {"float-store", &flag_float_store, 1},
-  {"volatile", &flag_volatile, 1},
-  {"volatile-global", &flag_volatile_global, 1},
-  {"defer-pop", &flag_defer_pop, 1},
-  {"omit-frame-pointer", &flag_omit_frame_pointer, 1},
-  {"cse-follow-jumps", &flag_cse_follow_jumps, 1},
-  {"cse-skip-blocks", &flag_cse_skip_blocks, 1},
-  {"expensive-optimizations", &flag_expensive_optimizations, 1},
-  {"thread-jumps", &flag_thread_jumps, 1},
-  {"strength-reduce", &flag_strength_reduce, 1},
-  {"unroll-loops", &flag_unroll_loops, 1},
-  {"unroll-all-loops", &flag_unroll_all_loops, 1},
-  {"move-all-movables", &flag_move_all_movables, 1},
-  {"reduce-all-givs", &flag_reduce_all_givs, 1},
-  {"writable-strings", &flag_writable_strings, 1},
-  {"peephole", &flag_no_peephole, 0},
-  {"force-mem", &flag_force_mem, 1},
-  {"force-addr", &flag_force_addr, 1},
-  {"function-cse", &flag_no_function_cse, 0},
-  {"inline-functions", &flag_inline_functions, 1},
-  {"keep-inline-functions", &flag_keep_inline_functions, 1},
-  {"inline", &flag_no_inline, 0},
-  {"keep-static-consts", &flag_keep_static_consts, 1},
-  {"syntax-only", &flag_syntax_only, 1},
-  {"shared-data", &flag_shared_data, 1},
-  {"caller-saves", &flag_caller_saves, 1},
-  {"pcc-struct-return", &flag_pcc_struct_return, 1},
-  {"reg-struct-return", &flag_pcc_struct_return, 0},
-  {"delayed-branch", &flag_delayed_branch, 1},
-  {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1},
-  {"rerun-loop-opt", &flag_rerun_loop_opt, 1},
-  {"pretend-float", &flag_pretend_float, 1},
-  {"schedule-insns", &flag_schedule_insns, 1},
-  {"schedule-insns2", &flag_schedule_insns_after_reload, 1},
+  {"float-store", &flag_float_store, 1,
+   "Do not store floats in registers" },
+  {"volatile", &flag_volatile, 1,
+   "Consider all mem refs through pointers as volatile"},
+  {"volatile-global", &flag_volatile_global, 1,
+   "Consider all mem refs to global data to be volatile" },
+  {"defer-pop", &flag_defer_pop, 1,
+   "Defer popping functions args from stack until later" },
+  {"omit-frame-pointer", &flag_omit_frame_pointer, 1,
+   "When possible do not generate stack frames"},
+  {"cse-follow-jumps", &flag_cse_follow_jumps, 1,
+   "When running CSE, follow jumps to their targets" },
+  {"cse-skip-blocks", &flag_cse_skip_blocks, 1,
+   "When running CSE, follow conditional jumps" },
+  {"expensive-optimizations", &flag_expensive_optimizations, 1,
+   "Perform a number of minor, expensive optimisations" },
+  {"thread-jumps", &flag_thread_jumps, 1,
+   "Perform jump threading optimisations"},
+  {"strength-reduce", &flag_strength_reduce, 1,
+   "Perform strength reduction optimisations" },
+  {"unroll-loops", &flag_unroll_loops, 1,
+   "Perform loop unrolling when interation count is known" },
+  {"unroll-all-loops", &flag_unroll_all_loops, 1,
+   "Perform loop unrolling for all loops" },
+  {"move-all-movables", &flag_move_all_movables, 1,
+   "Force all loop invariant computations out of loops" },
+  {"reduce-all-givs", &flag_reduce_all_givs, 1,
+   "Strength reduce all loop general induction variables" },
+  {"writable-strings", &flag_writable_strings, 1,
+   "Store strings in writable data section" },
+  {"peephole", &flag_no_peephole, 0,
+   "Enable machine specific peephole optimisations" },
+  {"force-mem", &flag_force_mem, 1,
+   "Copy memory operands into registers before using" },
+  {"force-addr", &flag_force_addr, 1,
+   "Copy memory address constants into regs before using" },
+  {"function-cse", &flag_no_function_cse, 0,
+   "Allow function addresses to be held in registers" },
+  {"inline-functions", &flag_inline_functions, 1,
+   "Integrate simple functions into their callers" },
+  {"keep-inline-functions", &flag_keep_inline_functions, 1,
+   "Generate code for funcs even if they are fully inlined" },
+  {"inline", &flag_no_inline, 0,
+   "Pay attention to the 'inline' keyword"},
+  {"keep-static-consts", &flag_keep_static_consts, 1,
+   "Emit static const variables even if they are not used" },
+  {"syntax-only", &flag_syntax_only, 1,
+   "Check for syntax errors, then stop" },
+  {"shared-data", &flag_shared_data, 1,
+   "Mark data as shared rather than private" },
+  {"caller-saves", &flag_caller_saves, 1,
+   "Enable saving registers around function calls" },
+  {"pcc-struct-return", &flag_pcc_struct_return, 1,
+   "Return 'short' aggregates in memory, not registers" },
+  {"reg-struct-return", &flag_pcc_struct_return, 0,
+   "Return 'short' aggregates in registers" },
+  {"delayed-branch", &flag_delayed_branch, 1,
+   "Attempt to fill delay slots of branch instructions" },
+  {"gcse", &flag_gcse, 1,
+   "Perform the global common subexpression elimination" },
+  {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1,
+   "Run CSE pass after loop optimisations"},
+  {"rerun-loop-opt", &flag_rerun_loop_opt, 1,
+   "Run the loop optimiser twice"},
+  {"pretend-float", &flag_pretend_float, 1,
+   "Pretend that host and target use the same FP format"},
+  {"schedule-insns", &flag_schedule_insns, 1,
+   "Reschedule instructions to avoid pipeline stalls"},
+  {"schedule-insns2", &flag_schedule_insns_after_reload, 1,
+  "Run two passes of the instruction scheduler"},
 #ifdef HAIFA
-  {"sched-interblock",&flag_schedule_interblock, 1},
-  {"sched-spec",&flag_schedule_speculative, 1},
-  {"sched-spec-load",&flag_schedule_speculative_load, 1},
-  {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1},
-  {"branch-count-reg",&flag_branch_on_count_reg, 1},
+  {"sched-interblock",&flag_schedule_interblock, 1,
+   "Enable scheduling across basic blocks" },
+  {"sched-spec",&flag_schedule_speculative, 1,
+   "Allow speculative motion of non-loads" },
+  {"sched-spec-load",&flag_schedule_speculative_load, 1,
+   "Allow speculative motion of some loads" },
+  {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1,
+   "Allow speculative motion of more loads" },
 #endif  /* HAIFA */
-  {"pic", &flag_pic, 1},
-  {"PIC", &flag_pic, 2},
-  {"exceptions", &flag_exceptions, 1},
-  {"sjlj-exceptions", &exceptions_via_longjmp, 1},
-  {"asynchronous-exceptions", &asynchronous_exceptions, 1},
-  {"profile-arcs", &profile_arc_flag, 1},
-  {"test-coverage", &flag_test_coverage, 1},
-  {"branch-probabilities", &flag_branch_probabilities, 1},
-  {"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},
-  {"regmove", &flag_regmove, 1},
-  {"pack-struct", &flag_pack_struct, 1},
-  {"stack-check", &flag_stack_check, 1},
-  {"argument-alias", &flag_argument_noalias, 0},
-  {"argument-noalias", &flag_argument_noalias, 1},
-  {"argument-noalias-global", &flag_argument_noalias, 2},
-  {"check-memory-usage", &flag_check_memory_usage, 1},
-  {"prefix-function-name", &flag_prefix_function_name, 1}
+  {"branch-count-reg",&flag_branch_on_count_reg, 1,
+   "Replace add,compare,branch with branch on count reg"},
+  {"pic", &flag_pic, 1,
+   "Generate position independent code, if possible"},
+  {"PIC", &flag_pic, 2, ""},
+  {"exceptions", &flag_exceptions, 1,
+   "Enable exception handling" },
+  {"new-exceptions", &flag_new_exceptions, 1,
+   "Use the new model for exception handling" },
+  {"sjlj-exceptions", &exceptions_via_longjmp, 1,
+   "Use setjmp/longjmp to handle exceptions" },
+  {"asynchronous-exceptions", &asynchronous_exceptions, 1,
+   "Support asynchronous exceptions" },
+  {"profile-arcs", &profile_arc_flag, 1,
+   "Insert arc based program profiling code" },
+  {"test-coverage", &flag_test_coverage, 1,
+   "Create data files needed by gcov" },
+  {"branch-probabilities", &flag_branch_probabilities, 1,
+   "Use profiling information for branch porbabilities" },
+  {"fast-math", &flag_fast_math, 1,
+   "Improve FP speed by violating ANSI & IEEE rules" },
+  {"common", &flag_no_common, 0,
+   "Do not put unitialised globals in the common section" },
+  {"inhibit-size-directive", &flag_inhibit_size_directive, 1,
+   "Do not generate .size directives" },
+  {"function-sections", &flag_function_sections, 1,
+   "place each function into its own section" },
+  {"data-sections", &flag_data_sections, 1,
+   "place data items into their own section" },
+  {"verbose-asm", &flag_verbose_asm, 1,
+   "Add extra commentry to assembler output"},
+  {"gnu-linker", &flag_gnu_linker, 1,
+   "Output GNU ld formatted global initialisers"},
+  {"regmove", &flag_regmove, 1,
+   "Enables a register move optimisation"},
+  {"optimize-register-move", &flag_regmove, 1,
+   "Do the full regmove optimization pass"},
+  {"pack-struct", &flag_pack_struct, 1,
+   "Pack structure members together without holes" },
+  {"stack-check", &flag_stack_check, 1,
+   "Insert stack checking code into the program" },
+  {"argument-alias", &flag_argument_noalias, 0,
+   "Specify that arguments may alias each other & globals"},
+  {"argument-noalias", &flag_argument_noalias, 1,
+   "Assume arguments may alias globals but not each other"},
+  {"argument-noalias-global", &flag_argument_noalias, 2,
+   "Assume arguments do not alias each other or globals" },
+  {"strict-aliasing", &flag_strict_aliasing, 1,
+   "Assume strict aliasing rules apply" },
+  {"check-memory-usage", &flag_check_memory_usage, 1,
+   "Generate code to check every memory access" },
+  {"prefix-function-name", &flag_prefix_function_name, 1,
+   "Add a prefix to all function names" },
+  {"dump-unnumbered", &flag_dump_unnumbered, 1,
+   "Suppress output of instruction numbers and line number notes in debugging dumps"},
+  {"instrument-functions", &flag_instrument_function_entry_exit, 1,
+   "Instrument function entry/exit with profiling calls"},
+  {"leading-underscore", &flag_leading_underscore, 1,
+   "External symbols have a leading underscore" }
 };
 
+#define NUM_ELEM(a)  (sizeof (a) / sizeof ((a)[0]))
+
 /* Table of language-specific options.  */
 
-char *lang_options[] =
+static struct lang_opt
 {
-  "-ansi",
-  "-fallow-single-precision",
-
-  "-fsigned-bitfields",
-  "-funsigned-bitfields",
-  "-fno-signed-bitfields",
-  "-fno-unsigned-bitfields",
-  "-fsigned-char",
-  "-funsigned-char",
-  "-fno-signed-char",
-  "-fno-unsigned-char",
-
-  "-ftraditional",
-  "-traditional",
-  "-fnotraditional",
-  "-fno-traditional",
-
-  "-fasm",
-  "-fno-asm",
-  "-fbuiltin",
-  "-fno-builtin",
-  "-fhosted",
-  "-fno-hosted",
-  "-ffreestanding",
-  "-fno-freestanding",
-  "-fcond-mismatch",
-  "-fno-cond-mismatch",
-  "-fdollars-in-identifiers",
-  "-fno-dollars-in-identifiers",
-  "-fident",
-  "-fno-ident",
-  "-fshort-double",
-  "-fno-short-double",
-  "-fshort-enums",
-  "-fno-short-enums",
-
-  "-Wall",
-  "-Wbad-function-cast",
-  "-Wno-bad-function-cast",
-  "-Wcast-qual",
-  "-Wno-cast-qual",
-  "-Wchar-subscripts",
-  "-Wno-char-subscripts",
-  "-Wcomment",
-  "-Wno-comment",
-  "-Wcomments",
-  "-Wno-comments",
-  "-Wconversion",
-  "-Wno-conversion",
-  "-Wformat",
-  "-Wno-format",
-  "-Wimport",
-  "-Wno-import",
-  "-Wimplicit-function-declaration",
-  "-Wno-implicit-function-declaration",
-  "-Werror-implicit-function-declaration",
-  "-Wimplicit-int",
-  "-Wno-implicit-int",
-  "-Wimplicit",
-  "-Wno-implicit",
-  "-Wmain",
-  "-Wno-main",
-  "-Wmissing-braces",
-  "-Wno-missing-braces",
-  "-Wmissing-declarations",
-  "-Wno-missing-declarations",
-  "-Wmissing-prototypes",
-  "-Wno-missing-prototypes",
-  "-Wnested-externs",
-  "-Wno-nested-externs",
-  "-Wparentheses",
-  "-Wno-parentheses",
-  "-Wpointer-arith",
-  "-Wno-pointer-arith",
-  "-Wredundant-decls",
-  "-Wno-redundant-decls",
-  "-Wsign-compare",
-  "-Wno-sign-compare",
-  "-Wunknown-pragmas",
-  "-Wno-unknown-pragmas",
-  "-Wstrict-prototypes",
-  "-Wno-strict-prototypes",
-  "-Wtraditional",
-  "-Wno-traditional",
-  "-Wtrigraphs",
-  "-Wno-trigraphs",
-  "-Wundef",
-  "-Wno-undef",
-  "-Wwrite-strings",
-  "-Wno-write-strings",
-
-  /* these are for obj c */
-  "-lang-objc",
-  "-gen-decls",
-  "-fgnu-runtime",
-  "-fno-gnu-runtime",
-  "-fnext-runtime",
-  "-fno-next-runtime",
-  "-Wselector",
-  "-Wno-selector",
-  "-Wprotocol",
-  "-Wno-protocol",
-  "-print-objc-runtime-info",
+  char * option;
+  char * description;
+}
+documented_lang_options[] =
+{
+  /* In order not to overload the --help output, the convention
+     used here is to only describe those options which are not
+     enabled by default.  */
+
+  { "-ansi", "Compile just for ANSI C" },
+  { "-fallow-single-precision",
+    "Do not promote floats to double if using -traditional" },
+
+  { "-fsigned-bitfields", "" },
+  { "-funsigned-bitfields","Make bitfields by unsigned by default" },
+  { "-fno-signed-bitfields", "" },
+  { "-fno-unsigned-bitfields","" },
+  { "-fsigned-char", "Make 'char' be signed by default"},
+  { "-funsigned-char", "Make 'char' be unsigned by default"},
+  { "-fno-signed-char", "" },
+  { "-fno-unsigned-char", "" },
+
+  { "-ftraditional", "" },
+  { "-traditional", "Attempt to support traditional K&R style C"},
+  { "-fnotraditional", "" },
+  { "-fno-traditional", "" },
+  { "-flang-isoc9x", "Enable C9X features"},
+
+  { "-fasm", "" },
+  { "-fno-asm", "Do not recognise the 'asm' keyword" },
+  { "-fbuiltin", "" },
+  { "-fno-builtin", "Do not recognise any built in functions" },
+  { "-fhosted", "Assume normal C execution environment" },
+  { "-fno-hosted", "" },
+  { "-ffreestanding",
+    "Assume that standard libraries & main might not exist" },
+  { "-fno-freestanding", "" },
+  { "-fcond-mismatch", "Allow different types as args of ? operator"},
+  { "-fno-cond-mismatch", "" },
+  { "-fdollars-in-identifiers", "Allow the use of $ inside indentifiers" },
+  { "-fno-dollars-in-identifiers", "" },
+  { "-fident", "" },
+  { "-fno-ident", "Ignore #ident directives" },
+  { "-fshort-double", "Use the same size for double as for float" },
+  { "-fno-short-double", "" },
+  { "-fshort-enums", "Use the smallest fitting integer to hold enums"},
+  { "-fno-short-enums", "" },
+
+  { "-Wall", "Enable most warning messages" },
+  { "-Wbad-function-cast",
+    "Warn about casting functions to incompatible types" },
+  { "-Wno-bad-function-cast", "" },
+  { "-Wmissing-noreturn",
+    "Warn about functions which might be candidates for attribute noreturn" },
+  { "-Wno-missing-noreturn", "" },
+  { "-Wcast-qual", "Warn about casts which discard qualifiers"},
+  { "-Wno-cast-qual", "" },
+  { "-Wchar-subscripts", "Warn about subscripts whose type is 'char'"},
+  { "-Wno-char-subscripts", "" },
+  { "-Wcomment", "Warn if nested comments are detected" },
+  { "-Wno-comment", "" },
+  { "-Wcomments", "Warn if nested comments are detected" },
+  { "-Wno-comments", "" },
+  { "-Wconversion", "Warn about possibly confusing type conversions" },
+  { "-Wno-conversion", "" },
+  { "-Wformat", "Warn about printf format anomalies" },
+  { "-Wno-format", "" },
+  { "-Wimplicit-function-declaration",
+    "Warn about implicit function declarations" },
+  { "-Wno-implicit-function-declaration", "" },
+  { "-Werror-implicit-function-declaration", "" },
+  { "-Wimplicit-int", "Warn when a declaration does not specify a type" },
+  { "-Wno-implicit-int", "" },
+  { "-Wimplicit", "" },
+  { "-Wno-implicit", "" },
+  { "-Wimport", "Warn about the use of the #import directive" },
+  { "-Wno-import", "" },
+  { "-Wlong-long","" },
+  { "-Wno-long-long", "Do not warn about using 'long long' when -pedantic" },
+  { "-Wmain", "Warn about suspicious declarations of main" },
+  { "-Wno-main", "" },
+  { "-Wmissing-braces",
+    "Warn about possibly missing braces around initialisers" },
+  { "-Wno-missing-braces", "" },
+  { "-Wmissing-declarations",
+    "Warn about global funcs without previous declarations"},
+  { "-Wno-missing-declarations", "" },
+  { "-Wmissing-prototypes", "Warn about global funcs without prototypes" },
+  { "-Wno-missing-prototypes", "" },
+  { "-Wmultichar", "Warn about use of multicharacter literals"},
+  { "-Wno-multichar", "" },
+  { "-Wnested-externs", "Warn about externs not at file scope level" },
+  { "-Wno-nested-externs", "" },
+  { "-Wparentheses", "Warn about possible missing parentheses" },
+  { "-Wno-parentheses", "" },
+  { "-Wpointer-arith", "Warn about function pointer arithmetic" },
+  { "-Wno-pointer-arith", "" },
+  { "-Wredundant-decls",
+    "Warn about multiple declarations of the same object" },
+  { "-Wno-redundant-decls", "" },
+  { "-Wsign-compare", "Warn about signed/unsigned comparisons" },
+  { "-Wno-sign-compare", "" },
+  { "-Wunknown-pragmas", "Warn about unrecognised pragmas" },
+  { "-Wno-unknown-pragmas", "" },
+  { "-Wstrict-prototypes", "Warn about non-prototyped function decls" },
+  { "-Wno-strict-prototypes", "" },
+  { "-Wtraditional", "Warn about constructs whose meaning change in ANSI C"},
+  { "-Wno-traditional", "" },
+  { "-Wtrigraphs", "Warn when trigraphs are encountered" },
+  { "-Wno-trigraphs", "" },
+  { "-Wundef", "" },
+  { "-Wno-undef", "" },
+  { "-Wwrite-strings", "Mark strings as 'const char *'"},
+  { "-Wno-write-strings", "" },
+
+  /* These are for languages with USE_CPPLIB.  */
+  /* These options are already documented in cpplib.c */
+  { "--help", "" },
+  { "-A", "" },
+  { "-D", "" },
+  { "-I", "" },
+  { "-U", "" },
+  { "-H", "" },
+  { "-idirafter", "" },
+  { "-imacros", "" },
+  { "-include", "" },
+  { "-iprefix", "" },
+  { "-isystem", "" },
+  { "-iwithprefix", "" },
+  { "-iwithprefixbefore", "" },
+  { "-lang-c", "" },
+  { "-lang-c89", "" },
+  { "-lang-c++", "" },
+  { "-remap", "" },
+  { "-nostdinc", "" },
+  { "-nostdinc++", "" },
+  { "-trigraphs", "" },
+  { "-undef", "" },
+  
+#define DEFINE_LANG_NAME(NAME) { NULL, NAME },
+  
+  /* These are for obj c.  */
+  DEFINE_LANG_NAME ("Objective C")
+  
+  { "-lang-objc", "" },
+  { "-gen-decls", "Dump decls to a .decl file" },
+  { "-fgnu-runtime", "Generate code for GNU runtime envrionment" },
+  { "-fno-gnu-runtime", "" },
+  { "-fnext-runtime", "Generate code for NeXT runtime environment" },
+  { "-fno-next-runtime", "" },
+  { "-Wselector", "Warn if a selector has multiple methods" },
+  { "-Wno-selector", "" },
+  { "-Wprotocol", "" },
+  { "-Wno-protocol", "Do not warn if inherited methods are unimplemented"},
+  { "-print-objc-runtime-info",
+    "Generate C header of platform specific features" },
 
 #include "options.h"
-  0
+  
 };
+
+/* Here is a table, controlled by the tm.h file, listing each -m switch
+   and which bits in `target_switches' it should set or clear.
+   If VALUE is positive, it is bits to set.
+   If VALUE is negative, -VALUE is bits to clear.
+   (The sign bit is not used so there is no confusion.)  */
+
+struct
+{
+  char * name;
+  int    value;
+  char * description;
+}
+target_switches [] = TARGET_SWITCHES;
+
+/* This table is similar, but allows the switch to have a value.  */
+
+#ifdef TARGET_OPTIONS
+struct
+{
+  char *  prefix;
+  char ** variable;
+  char *  description;
+}
+target_options [] = TARGET_OPTIONS;
+#endif
 \f
 /* Options controlling warnings */
 
@@ -949,16 +1188,21 @@ int warn_aggregate_return;
 
 /* Likewise for -W.  */
 
-struct { char *string; int *variable; int on_value;} W_options[] =
+lang_independent_options W_options[] =
 {
-  {"unused", &warn_unused, 1},
-  {"error", &warnings_are_errors, 1},
-  {"shadow", &warn_shadow, 1},
-  {"switch", &warn_switch, 1},
-  {"aggregate-return", &warn_aggregate_return, 1},
-  {"cast-align", &warn_cast_align, 1},
-  {"uninitialized", &warn_uninitialized, 1},
-  {"inline", &warn_inline, 1}
+  {"unused", &warn_unused, 1, "Warn when a variable is unused" },
+  {"error", &warnings_are_errors, 1, ""},
+  {"shadow", &warn_shadow, 1, "Warn when one local variable shadows another" },
+  {"switch", &warn_switch, 1,
+   "Warn about enumerated switches missing a specific case" },
+  {"aggregate-return", &warn_aggregate_return, 1,
+   "Warn about returning structures, unions or arrays" },
+  {"cast-align", &warn_cast_align, 1,
+   "Warn about pointer casts which increase alignment" },
+  {"uninitialized", &warn_uninitialized, 1,
+   "Warn about unitialized automatic variables"},
+  {"inline", &warn_inline, 1,
+   "Warn when an inlined function cannot be inlined"}
 };
 \f
 /* Output files for assembler code (real compiler output)
@@ -975,6 +1219,7 @@ int varconst_time;
 int integration_time;
 int jump_time;
 int cse_time;
+int gcse_time;
 int loop_time;
 int cse2_time;
 int branch_prob_time;
@@ -1024,8 +1269,17 @@ get_run_time ()
 #ifdef USG
   {
     struct tms tms;
+#   if HAVE_SYSCONF && defined _SC_CLK_TCK
+#    define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */
+#   else
+#    ifdef CLK_TCK
+#     define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */
+#    else
+#     define TICKS_PER_SECOND HZ /* traditional UNIX */
+#    endif
+#   endif
     times (&tms);
-    return (tms.tms_utime + tms.tms_stime) * (1000000 / HZ);
+    return (tms.tms_utime + tms.tms_stime) * (1000000 / TICKS_PER_SECOND);
   }
 #else
 #ifndef VMS
@@ -1153,7 +1407,7 @@ fatal_insn_not_found (insn)
 static char *
 decl_name (decl, verbosity)
      tree decl;
-     int verbosity;
+     int verbosity ATTRIBUTE_UNUSED;
 {
   return IDENTIFIER_POINTER (DECL_NAME (decl));
 }
@@ -1265,17 +1519,7 @@ vmessage (prefix, s, ap)
   if (prefix)
     fprintf (stderr, "%s: ", prefix);
 
-#ifdef HAVE_VPRINTF
   vfprintf (stderr, s, ap);
-#else
-  {
-    HOST_WIDE_INT v1 = va_arg(ap, HOST_WIDE_INT);
-    HOST_WIDE_INT v2 = va_arg(ap, HOST_WIDE_INT);
-    HOST_WIDE_INT v3 = va_arg(ap, HOST_WIDE_INT);
-    HOST_WIDE_INT v4 = va_arg(ap, HOST_WIDE_INT);
-    fprintf (stderr, s, v1, v2, v3, v4);
-  }
-#endif
 }
 
 /* Print a message relevant to line LINE of file FILE.  */
@@ -1348,7 +1592,7 @@ v_message_with_decl (decl, prefix, s, ap)
       while (*p)
        {
          ++p;
-         if (isalpha (*(p - 1) & 0xFF))
+         if (ISALPHA (*(p - 1) & 0xFF))
            break;
        }
     }
@@ -1912,7 +2156,7 @@ do_abort ()
 
 void
 botch (s)
-  char * s;
+  char * s ATTRIBUTE_UNUSED;
 {
   abort ();
 }
@@ -1923,12 +2167,35 @@ char *
 xmalloc (size)
      unsigned size;
 {
-  register char *value = (char *) malloc (size);
-  if (value == 0 && size != 0)
+  register char *value;
+
+  if (size == 0)
+    size = 1;
+
+  value = (char *) malloc (size);
+  if (value == 0)
     fatal ("virtual memory exhausted");
   return value;
 }
 
+/* Same as `calloc' but report error if no memory available.  */
+
+char *
+xcalloc (size1, size2)
+     unsigned size1, size2;
+{
+  register char *value;
+
+  if (size1 == 0 || size2 == 0)
+    size1 = size2 = 1;
+
+  value = (char *) calloc (size1, size2);
+  if (value == 0)
+    fatal ("virtual memory exhausted");
+  return value;
+}
+
+
 /* Same as `realloc' but report error if no memory available.  
    Also handle null PTR even if the vendor realloc gets it wrong.  */
 
@@ -1937,11 +2204,18 @@ xrealloc (ptr, size)
      char *ptr;
      int size;
 {
-  char *result = (ptr
-                 ? (char *) realloc (ptr, size)
-                 : (char *) malloc (size));
+  char *result;
+
+  if (size == 0)
+    size = 1;
+
+  result = (ptr
+           ? (char *) realloc (ptr, size)
+           : (char *) malloc (size));
+
   if (!result)
     fatal ("virtual memory exhausted");
+
   return result;
 }
 
@@ -2002,7 +2276,7 @@ jmp_buf float_handler;
 static void
 float_signal (signo)
      /* If this is missing, some compilers complain.  */
-     int signo;
+     int signo ATTRIBUTE_UNUSED;
 {
   if (float_handled == 0)
     abort ();
@@ -2044,10 +2318,10 @@ push_float_handler (handler, old_handler)
 
   float_handled = 1;
   if (was_handled)
-    bcopy ((char *) float_handler, (char *) old_handler,
+    memcpy ((char *) old_handler, (char *) float_handler,
           sizeof (float_handler));
 
-  bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
+  memcpy ((char *) float_handler, (char *) handler, sizeof (float_handler));
   return was_handled;
 }
 
@@ -2069,7 +2343,7 @@ pop_float_handler (handled, handler)
 static void
 pipe_closed (signo)
      /* If this is missing, some compilers complain.  */
-     int signo;
+     int signo ATTRIBUTE_UNUSED;
 {
   fatal ("output pipe has been closed");
 }
@@ -2133,6 +2407,10 @@ output_file_directive (asm_file, input_name)
     {
       if (na[-1] == '/')
        break;
+#ifdef DIR_SEPARATOR
+      if (na[-1] == DIR_SEPARATOR)
+       break;
+#endif
       na--;
     }
 
@@ -2273,6 +2551,7 @@ compile_file (name)
   integration_time = 0;
   jump_time = 0;
   cse_time = 0;
+  gcse_time = 0;
   loop_time = 0;
   cse2_time = 0;
   branch_prob_time = 0;
@@ -2292,33 +2571,11 @@ compile_file (name)
   symout_time = 0;
   dump_time = 0;
 
-#if !USE_CPPLIB
-  /* Open input file.  */
-
-  if (name == 0 || !strcmp (name, "-"))
-    {
-      finput = stdin;
-      name = "stdin";
-    }
-  else
-    finput = fopen (name, "r");
-  if (finput == 0)
-    pfatal_with_name (name);
-
-#ifdef IO_BUFFER_SIZE
-  setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
-#endif
-#endif /* !USE_CPPLIB */
-
   /* Initialize data in various passes.  */
 
   init_obstacks ();
   init_tree_codes ();
-#if USE_CPPLIB
-  init_parse (name);
-#else
-  init_lex ();
-#endif
+  name = init_parse (name);
   init_rtl ();
   init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
                  || debug_info_level == DINFO_LEVEL_VERBOSE
@@ -2381,6 +2638,8 @@ compile_file (name)
   if (dbr_sched_dump)
     clean_dump_file (".dbr");
 #endif
+  if (gcse_dump)
+    clean_dump_file (".gcse");
 #ifdef STACK_REGS
   if (stack_reg_dump)
     clean_dump_file (".stack");
@@ -2392,32 +2651,37 @@ compile_file (name)
 
   /* Open assembler code output file.  */
 
-  if (! name_specified && asm_file_name == 0)
-    asm_out_file = stdout;
+  if (flag_syntax_only)
+    asm_out_file = NULL;
   else
     {
-      int len = strlen (dump_base_name);
-      register char *dumpname = (char *) xmalloc (len + 6);
-      strcpy (dumpname, dump_base_name);
-      strip_off_ending (dumpname, len);
-      strcat (dumpname, ".s");
-      if (asm_file_name == 0)
-       {
-         asm_file_name = (char *) xmalloc (strlen (dumpname) + 1);
-         strcpy (asm_file_name, dumpname);
-       }
-      if (!strcmp (asm_file_name, "-"))
+      if (! name_specified && asm_file_name == 0)
        asm_out_file = stdout;
       else
-       asm_out_file = fopen (asm_file_name, "w");
-      if (asm_out_file == 0)
-       pfatal_with_name (asm_file_name);
-    }
+       {
+         int len = strlen (dump_base_name);
+         register char *dumpname = (char *) xmalloc (len + 6);
+         strcpy (dumpname, dump_base_name);
+         strip_off_ending (dumpname, len);
+         strcat (dumpname, ".s");
+         if (asm_file_name == 0)
+           {
+             asm_file_name = (char *) xmalloc (strlen (dumpname) + 1);
+             strcpy (asm_file_name, dumpname);
+           }
+         if (!strcmp (asm_file_name, "-"))
+           asm_out_file = stdout;
+         else
+           asm_out_file = fopen (asm_file_name, "w");
+         if (asm_out_file == 0)
+           pfatal_with_name (asm_file_name);
+       }
 
 #ifdef IO_BUFFER_SIZE
-  setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
-          _IOFBF, IO_BUFFER_SIZE);
+      setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
+              _IOFBF, IO_BUFFER_SIZE);
 #endif
+    }
 
   input_filename = name;
 
@@ -2427,63 +2691,50 @@ compile_file (name)
   input_file_stack->next = 0;
   input_file_stack->name = input_filename;
 
-  /* Gross. Gross.  lang_init is (I think) the first callback into
-     the language front end, and is thus the first opportunity to
-     have the selected language override the default value for any
-     -f option.
-
-     So the default value for flag_exceptions is 2 (uninitialized).
-     If we encounter -fno-exceptions or -fexceptions, then flag_exceptions
-     will be set to zero or one respectively.
-
-     flag_exceptions can also be set by lang_init to something other
-     than the default "uninitialized" value of 2.
-
-     After lang_init, if the value is still 2, then we default to
-     -fno-exceptions (value will be reset to zero).
-
-     When our EH mechanism is low enough overhead that we can enable
-     it by default for languages other than C++, then all this braindamage
-     will go away.  */
-  
   /* Perform language-specific initialization.
      This may set main_input_filename.  */
   lang_init ();
 
-  if (flag_exceptions == 2)
-    flag_exceptions = 0;
-     
   /* If the input doesn't start with a #line, use the input name
      as the official input file name.  */
   if (main_input_filename == 0)
     main_input_filename = name;
 
-  ASM_FILE_START (asm_out_file);
+  if (flag_syntax_only)
+    {
+      write_symbols = NO_DEBUG;
+      profile_flag = 0;
+      profile_block_flag = 0;
+    }
+  else
+    {
+      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,
+      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");
-    }
+         /* 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.  */
+      /* Output something to inform GDB that this compilation was by GCC.  */
 #ifndef ASM_IDENTIFY_GCC
-  fprintf (asm_out_file, "gcc2_compiled.:\n");
+      fprintf (asm_out_file, "gcc2_compiled.:\n");
 #else
-  ASM_IDENTIFY_GCC (asm_out_file);
+      ASM_IDENTIFY_GCC (asm_out_file);
 #endif
 
   /* Output something to identify which front-end produced this file.  */
 #ifdef ASM_IDENTIFY_LANGUAGE
-  ASM_IDENTIFY_LANGUAGE (asm_out_file);
+      ASM_IDENTIFY_LANGUAGE (asm_out_file);
 #endif
+    } /* ! flag_syntax_only */
 
 #ifndef ASM_OUTPUT_SECTION_NAME
   if (flag_function_sections)
@@ -2491,6 +2742,11 @@ compile_file (name)
       warning ("-ffunction-sections not supported for this target.");
       flag_function_sections = 0;
     }
+  if (flag_data_sections)
+    {
+      warning ("-fdata-sections not supported for this target.");
+      flag_data_sections = 0;
+    }
 #endif
 
   if (flag_function_sections
@@ -2516,7 +2772,14 @@ compile_file (name)
   /* Don't let the first function fall at the same address
      as gcc_compiled., if profiling.  */
   if (profile_flag || profile_block_flag)
-    assemble_zeros (UNITS_PER_WORD);
+    {
+      /* It's best if we can write a nop here since some
+        assemblers don't tolerate zeros in the text section.  */
+      if (insn_template[CODE_FOR_nop] != 0)
+       output_asm_insn (insn_template[CODE_FOR_nop], NULL_PTR);
+      else
+       assemble_zeros (UNITS_PER_WORD);
+    }
 
   /* If dbx symbol table desired, initialize writing it
      and output the predefined types.  */
@@ -2574,6 +2837,9 @@ compile_file (name)
   parse_time -= integration_time;
   parse_time -= varconst_time;
 
+  if (flag_syntax_only)
+    goto finish_syntax;
+
   globals = getdecls ();
 
   /* Really define vars that have had only a tentative definition.
@@ -2815,8 +3081,9 @@ compile_file (name)
   ASM_FILE_END (asm_out_file);
 #endif
 
-  /* Language-specific end of compilation actions.  */
 
+  /* Language-specific end of compilation actions.  */
+ finish_syntax:
   lang_finish ();
 
   /* Close the dump files.  */
@@ -2839,14 +3106,15 @@ compile_file (name)
      whether fclose returns an error, since the pages might still be on the
      buffer chain while the file is open.  */
 
-#if USE_CPPLIB
   finish_parse ();
-#else
-  fclose (finput);
-#endif
-  if (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0)
+
+  if (! flag_syntax_only
+      && (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0))
     fatal_io_error (asm_file_name);
 
+  /* Free up memory for the benefit of leak detectors.  */
+  free_reg_info ();
+
   /* Print the times.  */
 
   if (! quiet_flag)
@@ -2857,6 +3125,7 @@ compile_file (name)
       print_time ("integration", integration_time);
       print_time ("jump", jump_time);
       print_time ("cse", cse_time);
+      print_time ("gcse", gcse_time);
       print_time ("loop", loop_time);
       print_time ("cse2", cse2_time);
       print_time ("branch-prob", branch_prob_time);
@@ -2958,8 +3227,13 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
 
 void
 rest_of_type_compilation (type, toplev)
+#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) || defined (SDB_DEBUGGING_INFO)
      tree type;
      int toplev;
+#else
+     tree type ATTRIBUTE_UNUSED;
+     int toplev ATTRIBUTE_UNUSED;
+#endif
 {
 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
   if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
@@ -3052,7 +3326,8 @@ rest_of_compilation (decl)
         for those functions that need to be output.  Also defer those
         functions that we are supposed to defer.  We cannot defer
         functions containing nested functions since the nested function
-        data is in our non-saved obstack.  */
+        data is in our non-saved obstack.  We cannot defer nested
+        functions for the same reason.  */
 
       /* If this is a nested inline, remove ADDRESSOF now so we can
         finish compiling ourselves.  Otherwise, wait until EOF.
@@ -3088,7 +3363,8 @@ rest_of_compilation (decl)
              int saved_optimize = optimize;
              optimize = 0;
              find_exception_handler_labels ();
-             jump_optimize (get_insns(), 0, 0, 0);
+             jump_optimize (get_insns(), !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
+                            !JUMP_AFTER_REGSCAN);
              optimize = saved_optimize;
            }
 
@@ -3154,8 +3430,9 @@ rest_of_compilation (decl)
        }
 
       /* If specified extern inline but we aren't inlining it, we are
-        done.  */
-      if (DECL_INLINE (decl) && DECL_EXTERNAL (decl))
+        done.  This goes for anything that gets here with DECL_EXTERNAL
+        set, not just things with DECL_INLINE.  */
+      if (DECL_EXTERNAL (decl))
        goto exit_rest_of_compilation;
     }
 
@@ -3222,7 +3499,8 @@ rest_of_compilation (decl)
      are initialized and to compute whether control can drop off the end
      of the function.  */
   TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
-  TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 1));
+  TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
+                                    JUMP_AFTER_REGSCAN));
 
   /* Now is when we stop if -fsyntax-only and -Wreturn-type.  */
   if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl))
@@ -3251,10 +3529,12 @@ rest_of_compilation (decl)
 
       TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (),
                                         0, rtl_dump_file));
-      TIMEVAR (cse_time, delete_dead_from_cse (insns, max_reg_num ()));
+      TIMEVAR (cse_time, delete_trivially_dead_insns (insns, max_reg_num ()));
 
       if (tem || optimize > 1)
-       TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 0));
+       TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
+                                          !JUMP_NOOP_MOVES,
+                                          !JUMP_AFTER_REGSCAN));
 
       /* Dump rtl code after cse, if we are doing that.  */
       
@@ -3268,6 +3548,18 @@ rest_of_compilation (decl)
   if (addressof_dump)
     dump_rtl (".addressof", decl, print_rtl, insns);
   
+  /* Perform global cse.  */
+
+  if (optimize > 0 && flag_gcse)
+    {
+      if (gcse_dump)
+       open_dump_file (".gcse", IDENTIFIER_POINTER (DECL_NAME (decl)));
+      
+      TIMEVAR (gcse_time, gcse_main (insns, rtl_dump_file));
+
+      if (gcse_dump)
+       close_dump_file (print_rtl, insns);
+    }
   /* Move constant computations out of loops.  */
 
   if (optimize > 0)
@@ -3282,13 +3574,20 @@ rest_of_compilation (decl)
             {
               /* We only want to perform unrolling once.  */
               
-              loop_optimize (insns, rtl_dump_file, 0);
+              loop_optimize (insns, rtl_dump_file, 0, 0);
               
-              /* The regscan pass may not be necessary, but let's
-                 be safe until we can prove otherwise.  */
+       
+              /* The first call to loop_optimize makes some instructions
+                 trivially dead.  We delete those instructions now in the
+                 hope that doing so will make the heuristics in loop work
+                 better and possibly speed up compilation.  */
+              delete_trivially_dead_insns (insns, max_reg_num ());
+
+              /* The regscan pass is currently necessary as the alias
+                 analysis code depends on this information.  */
               reg_scan (insns, max_reg_num (), 1);
             }
-          loop_optimize (insns, rtl_dump_file, flag_unroll_loops);
+          loop_optimize (insns, rtl_dump_file, flag_unroll_loops, 1);
         });
       
       /* Dump rtl code after loop opt, if we are doing that.  */
@@ -3310,13 +3609,17 @@ rest_of_compilation (decl)
             max_reg_num so we must rerun reg_scan afterwards.
             ??? Rework to not call reg_scan so often.  */
          TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
-         TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 1));
+         TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
+                                            !JUMP_NOOP_MOVES,
+                                            JUMP_AFTER_REGSCAN));
          
          TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0));
          TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (),
                                              1, rtl_dump_file));
          if (tem)
-           TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 0));
+           TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
+                                              !JUMP_NOOP_MOVES,
+                                              !JUMP_AFTER_REGSCAN));
        }
 
       if (flag_thread_jumps)
@@ -3384,7 +3687,7 @@ rest_of_compilation (decl)
       TIMEVAR
        (flow_time,
         {
-          find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
+          find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
           life_analysis (insns, max_reg_num (), rtl_dump_file);
         });
 
@@ -3451,6 +3754,7 @@ rest_of_compilation (decl)
   if (!obey_regdecls)
     TIMEVAR (local_alloc_time,
             {
+              recompute_reg_usage (insns);
               regclass (insns, max_reg_num ());
               local_alloc ();
             });
@@ -3470,10 +3774,6 @@ rest_of_compilation (decl)
   if (global_reg_dump)
     open_dump_file (".greg", decl_printable_name (decl, 2));
 
-  /* 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.  */
@@ -3486,11 +3786,6 @@ rest_of_compilation (decl)
               failure = reload (insns, 0, rtl_dump_file);
           });
 
-  if (global_reg_dump)
-    {
-      TIMEVAR (dump_time, dump_global_regs (rtl_dump_file));
-      close_dump_file (print_rtl_with_bb, insns);
-    }
 
   if (failure)
     goto exit_rest_of_compilation;
@@ -3501,6 +3796,15 @@ rest_of_compilation (decl)
   if (optimize > 0)
     reload_cse_regs (insns);
 
+  /* Re-create the death notes which were deleted during reload.  */
+  if (optimize)
+    TIMEVAR
+      (flow_time,
+       {
+        find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+        life_analysis (insns, max_reg_num (), rtl_dump_file);
+       });
+
   /* On some machines, the prologue and epilogue code, or parts thereof,
      can be represented as RTL.  Doing so lets us schedule insns between
      it and the rest of the code and also allows delayed branch
@@ -3508,6 +3812,11 @@ rest_of_compilation (decl)
 
   thread_prologue_and_epilogue_insns (insns);
 
+  if (global_reg_dump)
+    {
+      TIMEVAR (dump_time, dump_global_regs (rtl_dump_file));
+      close_dump_file (print_rtl_with_bb, insns);
+    }
   if (optimize > 0 && flag_schedule_insns_after_reload)
     {
       if (sched2_dump)
@@ -3537,7 +3846,9 @@ rest_of_compilation (decl)
 
   if (optimize > 0)
     {
-      TIMEVAR (jump_time, jump_optimize (insns, 1, 1, 0));
+      TIMEVAR (jump_time, jump_optimize (insns, JUMP_CROSS_JUMP,
+                                        JUMP_NOOP_MOVES,
+                                        !JUMP_AFTER_REGSCAN));
       
       /* Dump rtl code after jump, if we are doing that.  */
 
@@ -3573,6 +3884,9 @@ rest_of_compilation (decl)
           });
 
 #ifdef STACK_REGS
+  if (stack_reg_dump)
+    open_dump_file (".stack", decl_printable_name (decl, 2));
+
   TIMEVAR (stack_reg_time, reg_to_stack (insns, rtl_dump_file));
 
   if (stack_reg_dump)
@@ -3603,7 +3917,8 @@ rest_of_compilation (decl)
             final (insns, asm_out_file, optimize, 0);
             final_end_function (insns, asm_out_file, optimize);
             assemble_end_function (decl, fnname);
-            fflush (asm_out_file);
+            if (! quiet_flag)
+              fflush (asm_out_file);
 
             /* Release all memory held by regsets now */
             regset_release_memory ();
@@ -3658,21 +3973,33 @@ rest_of_compilation (decl)
 
   reload_completed = 0;
 
-  /* Clear out the insn_length contents now that they are no longer valid.  */
-  init_insn_lengths ();
+  TIMEVAR (final_time,
+          {
+             /* Clear out the insn_length contents now that they are no
+                longer valid.  */
+             init_insn_lengths ();
 
-  /* Clear out the real_constant_chain before some of the rtx's
-     it runs through become garbage.  */
+             /* Clear out the real_constant_chain before some of the rtx's
+                it runs through become garbage.  */
+             clear_const_double_mem ();
 
-  clear_const_double_mem ();
+             /* Cancel the effect of rtl_in_current_obstack.  */
+             resume_temporary_allocation ();
 
-  /* Cancel the effect of rtl_in_current_obstack.  */
+             /* Show no temporary slots allocated.  */
+             init_temp_slots ();
+          });
 
-  resume_temporary_allocation ();
+  /* Make sure volatile mem refs aren't considered valid operands for
+     arithmetic insns.  We must call this here if this is a nested inline
+     function, since the above code leaves us in the init_recog state
+     (from final.c), and the function context push/pop code does not
+     save/restore volatile_ok.
 
-  /* Show no temporary slots allocated.  */
+     ??? Maybe it isn't necessary for expand_start_function to call this
+     anymore if we do it here?  */
 
-  init_temp_slots ();
+  init_recog_no_volatile ();
 
   /* The parsing time is all the time spent in yyparse
      *except* what is spent in this function.  */
@@ -3680,15 +4007,261 @@ rest_of_compilation (decl)
   parse_time -= get_run_time () - start_time;
 }
 \f
+static void
+display_help ()
+{
+  int    undoc;
+  unsigned long         i;
+  char * lang;
+  
+#ifndef USE_CPPLIB  
+  printf ("Usage: %s input [switches]\n", progname);
+  printf ("Switches:\n");
+#endif
+  printf ("  -ffixed-<register>      Mark <register> as being unavailable to the compiler\n");
+  printf ("  -fcall-used-<register>  Mark <register> as being corrupted by function calls\n");
+  printf ("  -fcall-saved-<register> Mark <register> as being preserved across functions\n");
+
+  for (i = NUM_ELEM (f_options); i--;)
+    {
+      char * description = f_options[i].description;
+      
+      if (description != NULL && * description != 0)
+       printf ("  -f%-21s %s\n",
+               f_options[i].string, description);
+    }
+  
+  printf ("  -O[number]              Set optimisation level to [number]\n");
+  printf ("  -Os                     Optimise for space rather than speed\n");
+  printf ("  -pedantic               Issue warnings needed by strict compliance to ANSI C\n");
+  printf ("  -pedantic-errors        Like -pedantic except that errors are produced\n");
+  printf ("  -w                      Suppress warnings\n");
+  printf ("  -W                      Enable extra warnings\n");
+  
+  for (i = NUM_ELEM (W_options); i--;)
+    {
+      char * description = W_options[i].description;
+      
+      if (description != NULL && * description != 0)
+       printf ("  -W%-21s %s\n",
+               W_options[i].string, description);
+    }
+  
+  printf ("  -Wid-clash-<num>        Warn if 2 identifiers have the same first <num> chars\n");
+  printf ("  -Wlarger-than-<number>  Warn if an object is larger than <number> bytes\n");
+  printf ("  -p                      Enable function profiling\n");
+#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER)
+  printf ("  -a                      Enable block profiling \n");
+#endif  
+#if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER) || defined FUNCTION_BLOCK_PROFILER_EXIT
+  printf ("  -ax                     Enable jump profiling \n");
+#endif  
+  printf ("  -o <file>               Place output into <file> \n");
+  printf ("  -G <number>             Put global and static data smaller than <number>\n");
+  printf ("                           bytes into a special section (on some targets)\n");
+  
+  for (i = NUM_ELEM (debug_args); i--;)
+    {
+      if (debug_args[i].description != NULL)
+       printf ("  -%-22s %s\n", debug_args[i].arg, debug_args[i].description);
+    }
+  
+  printf ("  -aux-info <file>        Emit declaration info into <file>.X\n");
+  printf ("  -quiet                  Do not display functions compiled or elapsed time\n");
+  printf ("  -version                Display the compiler's version\n");
+  printf ("  -d[letters]             Enable dumps from specific passes of the compiler\n");
+  printf ("  -dumpbase <file>        Base name to be used for dumps from specific passes\n");
+#if defined HAIFA || defined INSN_SCHEDULING
+  printf ("  -sched-verbose-<number> Set the verbosity level of the scheduler\n");
+#endif
+  printf ("  --help                  Display this information\n");
+
+  undoc = 0;
+  lang  = "language";
+  
+  /* Display descriptions of language specific options.
+     If there is no description, note that there is an undocumented option.
+     If the description is empty, do not display anything.  (This allows
+     options to be deliberately undocumented, for whatever reason).
+     If the option string is missing, then this is a marker, indicating
+     that the description string is in fact the name of a language, whose
+     language specific options are to follow.  */
+  
+  if (NUM_ELEM (documented_lang_options) > 1)
+    {
+      printf ("\nLanguage specific options:\n");
+
+      for (i = 0; i < NUM_ELEM (documented_lang_options); i++)
+       {
+         char * description = documented_lang_options[i].description;
+         char * option      = documented_lang_options[i].option;
+
+         if (description == NULL)
+           {
+             undoc = 1;
+
+             if (extra_warnings)
+               printf ("  %-23.23s [undocumented]\n", option);
+           }
+         else if (* description == 0)
+           continue;
+         else if (option == NULL)
+           {
+             if (undoc)
+               printf
+                 ("\nThere are undocumented %s specific options as well.\n",
+                       lang);
+             undoc = 0;
+             
+             printf ("\n Options for %s:\n", description);
+
+             lang = description;
+           }
+         else
+           printf ("  %-23.23s %s\n", option, description);
+       }
+    }
+
+  if (undoc)
+    printf ("\nThere are undocumented %s specific options as well.\n", lang);
+
+  if (NUM_ELEM (target_switches) > 1
+#ifdef TARGET_OPTIONS
+      || NUM_ELEM (target_options) > 1
+#endif
+      )
+    {
+      int doc = 0;
+      
+      undoc = 0;
+  
+      printf ("\nTarget specific options:\n");
+
+      for (i = NUM_ELEM (target_switches); i--;)
+       {
+         char * option      = target_switches[i].name;
+         char * description = target_switches[i].description;
+
+         if (option == NULL || * option == 0)
+           continue;
+         else if (description == NULL)
+           {
+             undoc = 1;
+             
+             if (extra_warnings)
+               printf ("  -m%-21.21s [undocumented]\n", option);
+           }
+         else if (* description != 0)
+           doc += printf ("  -m%-21.21s %s\n", option, description);
+       }
+      
+#ifdef TARGET_OPTIONS      
+      for (i = NUM_ELEM (target_options); i--;)
+       {
+         char * option      = target_options[i].prefix;
+         char * description = target_options[i].description;
+
+         if (option == NULL || * option == 0)
+           continue;
+         else if (description == NULL)
+           {
+             undoc = 1;
+             
+             if (extra_warnings)
+               printf ("  -m%-21.21s [undocumented]\n", option);
+           }
+         else if (* description != 0)
+           doc += printf ("  -m%-21.21s %s\n", option, description);
+       }
+#endif
+      if (undoc)
+       {
+         if (doc)
+           printf ("\nThere are undocumented target specific options as well.\n");
+         else
+           printf ("  They exist, but they are not documented.\n");
+       }
+    }
+}
+
+/* Compare the user specified 'option' with the language
+   specific 'lang_option'.  Return true if they match, or
+   if 'option' is a viable prefix of 'lang_option'.  */
+
+static int
+check_lang_option (option, lang_option)
+     char * option;
+     char * lang_option;
+{
+  lang_independent_options * indep_options;
+  int    len;
+  long    k;
+  char * space;
+  
+  /* Ignore NULL entries.  */
+  if (option == NULL || lang_option == NULL)
+    return 0;
+
+  if ((space = strchr (lang_option, ' ')) != NULL)
+    len = space - lang_option;
+  else
+    len = strlen (lang_option);
+  
+  /* If they do not match to the first n characters then fail.  */
+  if (strncmp (option, lang_option, len) != 0)
+    return 0;
+  
+  /* Do not accept a lang option, if it matches a normal -f or -W
+     option.  Chill defines a -fpack, but we want to support
+     -fpack-struct.  */
+  
+  /* An exact match is OK  */
+  if ((int) strlen (option) == len)
+    return 1;
+  
+  /* If it is not an -f or -W option allow the match */
+  if (option[0] != '-')
+    return 1;
+  
+  switch (option[1])
+    {
+    case 'f': indep_options = f_options; break;
+    case 'W': indep_options = W_options; break;
+    default:  return 1;
+    }
+  
+  /* The option is a -f or -W option.
+     Skip past the prefix and search for the remainder in the
+     appropriate table of options.  */
+  option += 2;
+  
+  if (option[0] == 'n' && option[1] == 'o' && option[2] == '-')
+    option += 3;
+  
+  for (k = NUM_ELEM (indep_options); k--;)
+    {
+      if (!strcmp (option, indep_options[k].string))
+       {
+         /* The option matched a language independent option,
+            do not allow the language specific match.  */
+         
+         return 0;
+       }
+    }
+  
+  /* The option matches the start of the langauge specific option
+     and it is not an exact match for a language independent option.  */
+  return 1;
+}
+\f
 /* Entry point of cc1/c++.  Decode command args, then call compile_file.
    Exit code is 35 if can't open files, 34 if fatal error,
    33 if had nonfatal errors, else success.  */
 
 int
-main (argc, argv, envp)
+main (argc, argv)
      int argc;
      char **argv;
-     char **envp;
 {
   register int i;
   char *filename = 0;
@@ -3728,7 +4301,7 @@ main (argc, argv, envp)
 #endif
 
   decl_printable_name = decl_name;
-  lang_expand_expr = (struct rtx_def *(*)()) do_abort;
+  lang_expand_expr = (lang_expand_expr_t) do_abort;
 
   /* Initialize whether `char' is signed.  */
   flag_signed_char = DEFAULT_SIGNED_CHAR;
@@ -3737,6 +4310,9 @@ main (argc, argv, envp)
   flag_short_enums = DEFAULT_SHORT_ENUMS;
 #endif
 
+  /* Perform language-specific options intialization.  */
+  lang_init_options ();
+
   /* Scan to see what optimization level has been specified.  That will
      determine the default value of many flags.  */
   for (i = 1; i < argc; i++)
@@ -3786,6 +4362,7 @@ main (argc, argv, envp)
     {
       flag_cse_follow_jumps = 1;
       flag_cse_skip_blocks = 1;
+      flag_gcse = 1;
       flag_expensive_optimizations = 1;
       flag_strength_reduce = 1;
       flag_rerun_cse_after_loop = 1;
@@ -3797,6 +4374,7 @@ main (argc, argv, envp)
       flag_schedule_insns_after_reload = 1;
 #endif
       flag_regmove = 1;
+      flag_strict_aliasing = 1;
     }
 
   if (optimize >= 3)
@@ -3819,17 +4397,29 @@ main (argc, argv, envp)
 
   for (i = 1; i < argc; i++)
     {
-      int j;
+      size_t j;
+      
       /* If this is a language-specific option,
         decode it in a language-specific way.  */
-      for (j = 0; lang_options[j] != 0; j++)
-       if (!strncmp (argv[i], lang_options[j],
-                     strlen (lang_options[j])))
+      for (j = NUM_ELEM (documented_lang_options); j--;)
+       if (check_lang_option (argv[i], documented_lang_options[j].option))
          break;
-      if (lang_options[j] != 0)
-       /* If the option is valid for *some* language,
-          treat it as valid even if this language doesn't understand it.  */
-       lang_decode_option (argv[i]);
+      
+      if (j != (size_t)-1)
+       {
+         /* If the option is valid for *some* language,
+            treat it as valid even if this language doesn't understand it.  */
+         int strings_processed = lang_decode_option (argc - i, argv + i);
+         
+         if (!strcmp (argv[i], "--help"))
+           {
+             display_help ();
+             exit (0);
+           }
+         
+         if (strings_processed != 0)
+           i += strings_processed - 1;
+       }
       else if (argv[i][0] == '-' && argv[i][1] != 0)
        {
          register char *str = argv[i] + 1;
@@ -3864,6 +4454,7 @@ main (argc, argv, envp)
                    regmove_dump = 1;
                    rtl_dump = 1;
                    cse_dump = 1, cse2_dump = 1;
+                   gcse_dump = 1;
                    sched_dump = 1;
                    sched2_dump = 1;
 #ifdef STACK_REGS
@@ -3873,14 +4464,12 @@ main (argc, argv, envp)
                    mach_dep_reorg_dump = 1;
 #endif
                    break;
+                 case 'A':
+                   flag_debug_asm = 1;
+                   break;
                  case 'b':
                    branch_prob_dump = 1;
                    break;
-#ifdef STACK_REGS                  
-                 case 'k':
-                   stack_reg_dump = 1;
-                   break;
-#endif
                  case 'c':
                    combine_dump = 1;
                    break;
@@ -3892,18 +4481,26 @@ main (argc, argv, envp)
                  case 'f':
                    flow_dump = 1;
                    break;
+                 case 'F':
+                   addressof_dump = 1;
+                   break;
                  case 'g':
                    global_reg_dump = 1;
                    break;
+                 case 'G':
+                   gcse_dump = 1;
+                   break;
                  case 'j':
                    jump_opt_dump = 1;
                    break;
-                 case 'D':
-                   addressof_dump = 1;
-                   break;
                  case 'J':
                    jump2_opt_dump = 1;
                    break;
+#ifdef STACK_REGS                  
+                 case 'k':
+                   stack_reg_dump = 1;
+                   break;
+#endif
                  case 'l':
                    local_reg_dump = 1;
                    break;
@@ -3924,30 +4521,27 @@ main (argc, argv, envp)
                  case 'r':
                    rtl_dump = 1;
                    break;
+                 case 'R':
+                   sched2_dump = 1;
+                   break;
                  case 's':
                    cse_dump = 1;
                    break;
+                 case 'S':
+                   sched_dump = 1;
+                   break;
                  case 't':
                    cse2_dump = 1;
                    break;
                  case 'N':
                    regmove_dump = 1;
                    break;
-                 case 'S':
-                   sched_dump = 1;
-                   break;
-                 case 'R':
-                   sched2_dump = 1;
-                   break;
                  case 'y':
                    set_yydebug (1);
                    break;
                  case 'x':
                    rtl_dump_and_exit = 1;
                    break;
-                 case 'A':
-                   flag_debug_asm = 1;
-                   break;
                  default:
                    warning ("unrecognised gcc debugging option: %c", p[-1]);
                    break;
@@ -3987,12 +4581,6 @@ main (argc, argv, envp)
 #ifdef INSN_SCHEDULING
              else if (!strncmp (p, "sched-verbose-",14))
                fix_sched_param("verbose",&p[14]);
-             else if (!strncmp (p, "sched-max-",10))
-               fix_sched_param("max",&p[10]);
-             else if (!strncmp (p, "sched-inter-max-b-",18))
-               fix_sched_param("interblock-max-blocks",&p[18]);
-             else if (!strncmp (p, "sched-inter-max-i-",18))
-               fix_sched_param("interblock-max-insns",&p[18]);
 #endif
 #endif  /* HAIFA */
              else if (!strncmp (p, "fixed-", 6))
@@ -4140,38 +4728,9 @@ main (argc, argv, envp)
                 -g and -ggdb don't explicitly set the debugging format so
                 -gdwarf -g3 is equivalent to -gdwarf3.  */
              static int type_explicitly_set_p = 0;
-             /* Table of supported debugging formats.  */
-             static struct {
-               char *arg;
-               /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a
-                  constant expression, we use NO_DEBUG in its place.  */
-               enum debug_info_type debug_type;
-               int use_extensions_p;
-             } *da, debug_args[] = {
-               { "g", NO_DEBUG, DEFAULT_GDB_EXTENSIONS },
-               { "ggdb", NO_DEBUG, 1 },
-#ifdef DBX_DEBUGGING_INFO
-               { "gstabs", DBX_DEBUG, 0 },
-               { "gstabs+", DBX_DEBUG, 1 },
-#endif
-#ifdef DWARF_DEBUGGING_INFO
-               { "gdwarf", DWARF_DEBUG, 0 },
-               { "gdwarf+", DWARF_DEBUG, 1 },
-#endif
-#ifdef DWARF2_DEBUGGING_INFO
-               { "gdwarf-2", DWARF2_DEBUG, 0 },
-#endif
-#ifdef XCOFF_DEBUGGING_INFO
-               { "gxcoff", XCOFF_DEBUG, 0 },
-               { "gxcoff+", XCOFF_DEBUG, 1 },
-#endif
-#ifdef SDB_DEBUGGING_INFO
-               { "gcoff", SDB_DEBUG, 0 },
-#endif
-               { 0, 0, 0 }
-             };
              /* Indexed by enum debug_info_type.  */
-             static char *debug_type_names[] = {
+             static char *debug_type_names[] =
+             {
                "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff"
              };
 
@@ -4278,6 +4837,11 @@ main (argc, argv, envp)
              flag_gen_aux_info = 1;
              aux_info_file_name = (str[8] != '\0' ? str+8 : argv[++i]);
            }
+         else if (!strcmp (str, "-help"))
+           {
+             display_help ();
+             exit (0);
+           }
          else
            error ("Invalid option `%s'", argv[i]);
        }
@@ -4349,6 +4913,21 @@ main (argc, argv, envp)
     warning ("this target machine does not have delayed branches");
 #endif
 
+  user_label_prefix = USER_LABEL_PREFIX;
+  if (flag_leading_underscore != -1)
+    {
+      /* If the default prefix is more complicated than "" or "_", 
+        issue a warning and ignore this option.  */
+      if (user_label_prefix[0] == 0 ||
+         (user_label_prefix[0] == '_' && user_label_prefix[1] == 0))
+       {
+         user_label_prefix = flag_leading_underscore ? "_" : "";
+       }
+      else
+       warning ("-f%sleading-underscore not supported on this target machine",
+                flag_leading_underscore ? "" : "no-");
+    }
+
   /* If we are in verbose mode, write out the version and maybe all the
      option flags in use.  */
   if (version_flag)
@@ -4365,8 +4944,7 @@ main (argc, argv, envp)
     {
       char *lim = (char *) sbrk (0);
 
-      fprintf (stderr, "Data size %d.\n",
-              lim - (char *) &environ);
+      fprintf (stderr, "Data size %ld.\n", (long)(lim - (char *) &environ));
       fflush (stderr);
 
 #ifndef __MSDOS__
@@ -4388,30 +4966,13 @@ main (argc, argv, envp)
 }
 \f
 /* Decode -m switches.  */
-
-/* Here is a table, controlled by the tm.h file, listing each -m switch
-   and which bits in `target_switches' it should set or clear.
-   If VALUE is positive, it is bits to set.
-   If VALUE is negative, -VALUE is bits to clear.
-   (The sign bit is not used so there is no confusion.)  */
-
-struct {char *name; int value;} target_switches []
-  = TARGET_SWITCHES;
-
-/* This table is similar, but allows the switch to have a value.  */
-
-#ifdef TARGET_OPTIONS
-struct {char *prefix; char ** variable;} target_options []
-  = TARGET_OPTIONS;
-#endif
-
 /* Decode the switch -mNAME.  */
 
-void
+static void
 set_target_switch (name)
      char *name;
 {
-  register int j;
+  register size_t j;
   int valid = 0;
 
   for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
@@ -4445,7 +5006,7 @@ set_target_switch (name)
    Each line begins with INDENT (for the case where FILE is the
    assembler output file).  */
 
-void
+static void
 print_version (file, indent)
      FILE *file;
      char *indent;
@@ -4467,7 +5028,7 @@ print_version (file, indent)
    ??? We don't handle error returns from fprintf (disk full); presumably
    other code will catch a disk full though.  */
 
-int
+static int
 print_single_switch (file, pos, max, indent, sep, term, type, name)
      FILE *file;
      int pos, max;
@@ -4498,13 +5059,13 @@ print_single_switch (file, pos, max, indent, sep, term, type, name)
    Each line begins with INDENT and ends with TERM.
    Each switch is separated from the next by SEP.  */
 
-void
+static void
 print_switch_values (file, pos, max, indent, sep, term)
      FILE *file;
      int pos, max;
      char *indent, *sep, *term;
 {
-  int j, flags;
+  size_t j;
   char **p;
 
   /* Print the options as passed.  */
@@ -4548,7 +5109,6 @@ print_switch_values (file, pos, max, indent, sep, term)
 
   /* 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
@@ -4557,7 +5117,6 @@ print_switch_values (file, pos, max, indent, sep, term)
       {
        pos = print_single_switch (file, pos, max, indent, sep, term,
                                   "-m", target_switches[j].name);
-       flags &= ~ target_switches[j].value;
       }
 
 #ifdef TARGET_OPTIONS
@@ -4605,7 +5164,7 @@ debug_start_source_file (filename)
 
 void
 debug_end_source_file (lineno)
-     register unsigned lineno;
+     register unsigned lineno ATTRIBUTE_UNUSED;
 {
 #ifdef DBX_DEBUGGING_INFO
   if (write_symbols == DBX_DEBUG)