[project @ 1998-12-02 13:17:09 by simonm]
[ghc-hetmet.git] / ghc / driver / ghc.lprl
index 78b5e59..f5b8d39 100644 (file)
@@ -1,4 +1,3 @@
-%
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1997
 %
 
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1997
 %
 
@@ -46,8 +45,8 @@ to stdout or stderr, however).
 
 The phase at which to STOP processing is determined by a command-line
 option:
 
 The phase at which to STOP processing is determined by a command-line
 option:
+    -E         stop after generating preprocessed, de-litted Haskell (used in conjunction with -cpp)
     -C         stop after generating C (.hc output)
     -C         stop after generating C (.hc output)
-    -E         stop after generating preprocessed C (.i output)
     -S         stop after generating assembler (.s output)
     -c         stop after generating object files (.o output)
 
     -S         stop after generating assembler (.s output)
     -c         stop after generating object files (.o output)
 
@@ -64,9 +63,9 @@ Other commonly-used options are:
 
     -M          Output the Makefile rules recording the
                 dependencies of a list of Haskell files.
 
     -M          Output the Makefile rules recording the
                 dependencies of a list of Haskell files.
-               (ghc driver just calls upon the help of a
-                 compatible mkdependHS script to do the
-                 actual processing)
+               (ghc driver script calls upon the help of a
+                 compatible mkdependHS script to do the actual
+                processing)
 
 The User's Guide has more information about GHC's *many* options.
 
 
 The User's Guide has more information about GHC's *many* options.
 
@@ -99,11 +98,13 @@ INSTALLING
 
 HOSTPLATFORM TARGETPLATFORM
 
 
 HOSTPLATFORM TARGETPLATFORM
 
-PROJECTNAME PROJECTVERSION PROJECTPATCHLEVEL
+ProjectName ProjectVersion ProjectVersionInt ProjectPatchLevel 
+
+HscMajorVersion HscMinorVersion CcMajorVersion CcMinorVersion
 
 TOP_PWD
 
 
 TOP_PWD
 
-bindir libdir datadir
+bindir libdir libexecdir datadir
 
 CURRENT_DIR TMPDIR
 
 
 CURRENT_DIR TMPDIR
 
@@ -132,10 +133,12 @@ $TargetPlatform = $TARGETPLATFORM;
 $TopPwd                   = "${TOP_PWD}";
 $InstBinDirGhc     = "${bindir}";
 $InstLibDirGhc     = "${libdir}";
 $TopPwd                   = "${TOP_PWD}";
 $InstBinDirGhc     = "${bindir}";
 $InstLibDirGhc     = "${libdir}";
-$InstLibexecDirGhc = "${libexecdir}";
+#
+# Normally the same as InstLibDirGhc, but we accommodate
+# for it being separate.
+#
+$InstLibExecDirGhc = "${libexecdir}";
 $InstDataDirGhc    = "${datadir}";
 $InstDataDirGhc    = "${datadir}";
-$InstSysLibDir     = ( $INSTALLING ) ? "${InstLibDirGhc}/hslibs" : 
-                       "$TopPwd/hslibs";
 
 $Status  = 0; # just used for exit() status
 $Verbose = '';
 
 $Status  = 0; # just used for exit() status
 $Verbose = '';
@@ -177,7 +180,7 @@ if ( ! $ENV{'REAL_SHELL'} ) {
 
 @Files_to_tidy = (); # files we nuke in the case of abnormal termination
 
 
 @Files_to_tidy = (); # files we nuke in the case of abnormal termination
 
-$Unlit = ( $INSTALLING ) ? "$InstLibexecDirGhc/unlit"
+$Unlit = ( $INSTALLING ) ? "$InstLibExecDirGhc/unlit"
                         : "$TopPwd/${CURRENT_DIR}/${GHC_UNLIT}";
 
 $Cp   = $CP;
                         : "$TopPwd/${CURRENT_DIR}/${GHC_UNLIT}";
 
 $Cp   = $CP;
@@ -188,16 +191,15 @@ $Cmp  = 'cmp';
 $Time = '';
 
 $HsCpp  = # but this is re-set to "cat" (after options) if -cpp not seen
 $Time = '';
 
 $HsCpp  = # but this is re-set to "cat" (after options) if -cpp not seen
-          ( $INSTALLING ) ? "$InstLibexecDirGhc/hscpp"
+          ( $INSTALLING ) ? "$InstLibExecDirGhc/hscpp"
                           : "$TopPwd/${CURRENT_DIR}/${GHC_HSCPP}";
 
 @HsCpp_flags   = ();
                           : "$TopPwd/${CURRENT_DIR}/${GHC_HSCPP}";
 
 @HsCpp_flags   = ();
-$genSPECS_flag = '';           # See ../utils/hscpp/hscpp.prl
-$HsC    = ( $INSTALLING ) ? "$InstLibexecDirGhc/hsc"
+$HsC    = ( $INSTALLING ) ? "$InstLibExecDirGhc/hsc"
                           : "$TopPwd/${CURRENT_DIR}/${GHC_HSC}";
 
 # For PVM fiends only
                           : "$TopPwd/${CURRENT_DIR}/${GHC_HSC}";
 
 # For PVM fiends only
-$SysMan         = ( $INSTALLING ) ? "$InstLibexecDirGhc/SysMan"
+$SysMan         = ( $INSTALLING ) ? "$InstLibExecDirGhc/SysMan"
                           : "$TopPwd/${CURRENT_DIR}/${GHC_SYSMAN}";
 
 @Unlit_flags   = ();
                           : "$TopPwd/${CURRENT_DIR}/${GHC_SYSMAN}";
 
 @Unlit_flags   = ();
@@ -219,18 +221,17 @@ These are the default values, which may be changed by user flags.
 
 \begin{code}
 sub setupOptFlags {
 
 \begin{code}
 sub setupOptFlags {
-   $Oopt_UnfoldingUseThreshold   = '-fsimpl-uf-use-threshold3';
    $Oopt_MaxSimplifierIterations  = '-fmax-simplifier-iterations4';
    $Oopt_PedanticBottoms         = '-fpedantic-bottoms'; # ON by default
    $Oopt_MonadEtaExpansion       = '';
    $Oopt_FinalStgProfilingMassage = '';
    $Oopt_StgStats                = '';
    $Oopt_MaxSimplifierIterations  = '-fmax-simplifier-iterations4';
    $Oopt_PedanticBottoms         = '-fpedantic-bottoms'; # ON by default
    $Oopt_MonadEtaExpansion       = '';
    $Oopt_FinalStgProfilingMassage = '';
    $Oopt_StgStats                = '';
-   $Oopt_SpecialiseUnboxed       = '';
-   $Oopt_DoSpecialise            = ''; # ToDo:LATER: '-fspecialise';
+   $Oopt_DoSpecialise            = '-fspecialise';
    $Oopt_FoldrBuild              = 0; # *Off* by default!
    $Oopt_FB_Support              = ''; # was '-fdo-arity-expand';
 #  $Oopt_FoldrBuildWW            = 0; # Off by default
    $Oopt_FoldrBuildInline        = ''; # was '-fdo-inline-foldr-build';
    $Oopt_FoldrBuild              = 0; # *Off* by default!
    $Oopt_FB_Support              = ''; # was '-fdo-arity-expand';
 #  $Oopt_FoldrBuildWW            = 0; # Off by default
    $Oopt_FoldrBuildInline        = ''; # was '-fdo-inline-foldr-build';
+   $Oopt_ShowSimplifierProgress   = '';
 } # end of setupOptFlags
 
 # Assign defaults to these right away.
 } # end of setupOptFlags
 
 # Assign defaults to these right away.
@@ -238,9 +239,13 @@ sub setupOptFlags {
 \end{code}
 
 Things to do with C compilers/etc:
 \end{code}
 
 Things to do with C compilers/etc:
+
+(added -Wimplicit: implicit prototypes cause very hard-to-find
+problems, so I'm turing on the warnings -- SDM 4/5/98)
+
 \begin{code}
 $CcRegd                = $GHC_OPT_HILEV_ASM;
 \begin{code}
 $CcRegd                = $GHC_OPT_HILEV_ASM;
-@CcBoth_flags  = ('-S');   # flags for *any* C compilation
+@CcBoth_flags  = ('-S','-Wimplicit');   # flags for *any* C compilation
 @CcInjects     = ();
 
 # GCC flags: 
 @CcInjects     = ();
 
 # GCC flags: 
@@ -248,22 +253,46 @@ $CcRegd           = $GHC_OPT_HILEV_ASM;
 #    those only for .c files;
 #    those only for .hc files
 
 #    those only for .c files;
 #    those only for .hc files
 
-@CcRegd_flags    = ('-ansi', '-D__STG_GCC_REGS__', '-D__STG_TAILJUMPS__');
-@CcRegd_flags_c        = ();
+@CcRegd_flags    = ();
+@CcRegd_flags_c         = ();
 @CcRegd_flags_hc = ();
 
 @CcRegd_flags_hc = ();
 
-$As            = ''; # "assembler" is normally GCC
-@As_flags      = ();
+$As             = ''; # "assembler" is normally GCC
+@As_flags       = ();
 
 
-$Lnkr          = ''; # "linker" is normally GCC
-@Ld_flags      = ();
+$Lnkr           = ''; # "linker" is normally GCC
+@Ld_flags       = ();
 
 # 'nm' is used for consistency checking (ToDo: mk-world-ify)
 # ToDo: check the OS or something ("alpha" is surely not the crucial question)
 $Nm = ($TargetPlatform =~ /^alpha-/) ? 'nm -B' : 'nm';
 \end{code}
 
 
 # 'nm' is used for consistency checking (ToDo: mk-world-ify)
 # ToDo: check the OS or something ("alpha" is surely not the crucial question)
 $Nm = ($TargetPlatform =~ /^alpha-/) ? 'nm -B' : 'nm';
 \end{code}
 
+Warning packages that are controlled by -W and -Wall.  The 'standard'
+warnings that you get all the time are
+       
+       -fwarn-overlapping-patterns
+       -fwarn-missing-methods
+       -fwarn-duplicate-exports
+
+these are turned off by -Wnot.
+
+\begin{code}
+@StandardWarnings = ('-fwarn-overlapping-patterns', 
+                    '-fwarn-missing-methods',
+                    '-fwarn-duplicate-exports');
+@MinusWOpts              = (@StandardWarnings, 
+                    '-fwarn-incomplete-patterns', 
+                    '-fwarn-unused-binds',
+                    '-fwarn-unused-imports');
+@MinusWallOpts           = (@MinusWOpts, 
+                    '-fwarn-unused-matches',
+                    '-fwarn-name-shadowing',
+                    '-fwarn-missing-signatures');
+\end{code}
+
 What options \tr{-user-setup-a} turn into (user-defined ``packages''
 What options \tr{-user-setup-a} turn into (user-defined ``packages''
+
 of options).  Note that a particular user-setup implies a particular
 Prelude ({\em including} its interface file(s)).
 \begin{code}
 of options).  Note that a particular user-setup implies a particular
 Prelude ({\em including} its interface file(s)).
 \begin{code}
@@ -274,14 +303,8 @@ $BuildTag  = ''; # default is sequential build w/ Appel-style GC
                   '_p',    "$WAY_p_NAME",
                   '_t',    "$WAY_t_NAME",
                   '_u',    "$WAY_u_NAME",
                   '_p',    "$WAY_p_NAME",
                   '_t',    "$WAY_t_NAME",
                   '_u',    "$WAY_u_NAME",
-                  '_mc',   "$WAY_mc_NAME",
-                  '_mr',   "$WAY_mr_NAME",
-                  '_mt',   "$WAY_mt_NAME",
                   '_mp',   "$WAY_mp_NAME",
                   '_mg',   "$WAY_mg_NAME",
                   '_mp',   "$WAY_mp_NAME",
                   '_mg',   "$WAY_mg_NAME",
-                  '_2s',   "$WAY_2s_NAME",
-                  '_1s',   "$WAY_1s_NAME",
-                  '_du',   "$WAY_du_NAME",
                   # system ways end
                   '_a',    "$WAY_a_NAME",
                   '_b',    "$WAY_b_NAME",
                   # system ways end
                   '_a',    "$WAY_a_NAME",
                   '_b',    "$WAY_b_NAME",
@@ -327,83 +350,8 @@ $BuildTag  = ''; # default is sequential build w/ Appel-style GC
        '_p',  "$WAY_p_HC_OPTS",
        '_t',  "$WAY_t_HC_OPTS",
        '_u',  "$WAY_u_HC_OPTS",
        '_p',  "$WAY_p_HC_OPTS",
        '_t',  "$WAY_t_HC_OPTS",
        '_u',  "$WAY_u_HC_OPTS",
-       '_mc', "$WAY_mc_HC_OPTS",
-       '_mr', "$WAY_mr_HC_OPTS",
-       '_mt', "$WAY_mt_HC_OPTS",
        '_mp', "$WAY_mp_HC_OPTS",
        '_mp', "$WAY_mp_HC_OPTS",
-       '_mg', "$WAY_mg_HC_OPTS",
-       '_2s', "$WAY_2s_HC_OPTS",
-       '_1s', "$WAY_1s_HC_OPTS",
-       '_du', "$WAY_B_HC_OPTS" );
-
-# per-build code fragments which are eval'd
-#%EvaldSetupOpts       = ('',      '', # this one must *not* be set!
-
-#                          # profiled sequential
-#                 '_p',    'push(@HsC_flags,  \'-fscc-profiling\');
-#                           push(@CcBoth_flags, \'-DPROFILING\');',
-
-#                          #and maybe ...
-#                          #push(@CcBoth_flags, '-DPROFILING_DETAIL_COUNTS');
-
-#                          # ticky-ticky sequential
-#                 '_t',    'push(@HsC_flags, \'-fticky-ticky\');
-#                           push(@CcBoth_flags, \'-DTICKY_TICKY\');',
-
-##OLD:                     # unregisterized (ToDo????)
-##                '_u',    '',
-
-#                          # concurrent
-#                 '_mc',   '$StkChkByPageFaultOK = 0;
-#                           push(@HsC_flags,  \'-fconcurrent\');
-#                           push(@HsCpp_flags,\'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\');
-#                           push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\');',
-
-#                          # profiled concurrent
-#                 '_mr',   '$StkChkByPageFaultOK = 0;
-#                           push(@HsC_flags,  \'-fconcurrent\', \'-fscc-profiling\');
-#                           push(@HsCpp_flags,\'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\');
-#                           push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DPROFILING\');',
-
-#                          # ticky-ticky concurrent
-#                 '_mt',   '$StkChkByPageFaultOK = 0;
-#                           push(@HsC_flags,  \'-fconcurrent\', \'-fticky-ticky\');
-#                           push(@HsCpp_flags,\'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\');
-#                           push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DTICKY_TICKY\');',
-
-#                          # parallel
-#                 '_mp',   '$StkChkByPageFaultOK = 0;
-#                           push(@HsC_flags,  \'-fconcurrent\');
-#                           push(@HsCpp_flags,\'-D__PARALLEL_HASKELL__\',   \'-DPAR\');
-#                           push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DPAR\');',
-
-#                          # GranSim
-#                 '_mg',   '$StkChkByPageFaultOK = 0;
-#                           push(@HsC_flags,  \'-fconcurrent\', \'-fgransim\');
-#                           push(@HsCpp_flags,\'-D__GRANSIM__\',   \'-DGRAN\');
-#                           push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DGRAN\');',
-
-#                 '_2s',   'push (@CcBoth_flags, \'-DGC2s\');',
-#                 '_1s',   'push (@CcBoth_flags, \'-DGC1s\');',
-#                 '_du',   'push (@CcBoth_flags, \'-DGCdu\');',
-
-#                 '_a',    '', # these user-way guys should not be set!
-#                 '_b',    '',
-#                 '_c',    '',
-#                 '_d',    '',
-#                 '_e',    '',
-#                 '_f',    '',
-#                 '_g',    '',
-#                 '_h',    '',
-#                 '_i',    '',
-#                 '_j',    '',
-#                 '_k',    '',
-#                 '_l',    '',
-#                 '_m',    '',
-#                 '_n',    '',
-#                 '_o',    '',
-#                 '_A',    '',
-#                 '_B',    '' );
+       '_mg', "$WAY_mg_HC_OPTS");
 
 \end{code}
 
 
 \end{code}
 
@@ -414,21 +362,26 @@ require special handling.
 @Import_dir    = ('.'); #-i things
 @Include_dir   = ('.'); #-I things; other default(s) stuck on AFTER option processing
 
 @Import_dir    = ('.'); #-i things
 @Include_dir   = ('.'); #-I things; other default(s) stuck on AFTER option processing
 
-# where to look for interface files (system hi's, i.e., prelude and hslibs)
+# where to look for interface files (system hi's, i.e., prelude and syslibs)
 @SysImport_dir = ( $INSTALLING )
 @SysImport_dir = ( $INSTALLING )
-                   ? ( "$InstLibDirGhc/imports" )
-                   : ( "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/required"
-                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/ghc"
-                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/glaExts"
-                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/concurrent" );
+                   ? ( "$InstLibDirGhc/imports/std" )
+                   : ( "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/std" );
 
 # We need to look in ghc/ and glaExts/ when searching for implicitly needed .hi files, but 
 # we should really *not* look there for explicitly imported modules.
 
 
 # We need to look in ghc/ and glaExts/ when searching for implicitly needed .hi files, but 
 # we should really *not* look there for explicitly imported modules.
 
-$GhcVersionInfo  = int ($PROJECTVERSION * 100);
 $Haskell1Version = 4; # i.e., Haskell 1.4
 @Cpp_define     = ();
 
 $Haskell1Version = 4; # i.e., Haskell 1.4
 @Cpp_define     = ();
 
+# Cpp symbols defined when we're processing Haskell source.
+
+@HsSourceCppOpts = 
+       ( "-D__HASKELL1__=$Haskell1Version"
+       , "-D__GLASGOW_HASKELL__=$ProjectVersionInt"
+       # not yet -- SDM
+       # , "-D__CONCURRENT_HASKELL__"
+       );
+
 @UserLibrary_dir= ();  #-L things;...
 @UserLibrary           = ();   #-l things asked for by the user
 
 @UserLibrary_dir= ();  #-L things;...
 @UserLibrary           = ();   #-l things asked for by the user
 
@@ -436,22 +389,23 @@ $Haskell1Version = 4; # i.e., Haskell 1.4
                    ? $InstLibDirGhc
                    : ( "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR"
                      , "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR/gmp"
                    ? $InstLibDirGhc
                    : ( "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR"
                      , "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR/gmp"
-                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR"
-                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/cbits"
+                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/std"
+                     , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/std/cbits"
                      )
                  );
 @SysLibrary = (); # will be built up as we go along
 
 $TopClosureFile # defaults to 1.2 one; will be mangled later
                      )
                  );
 @SysLibrary = (); # will be built up as we go along
 
 $TopClosureFile # defaults to 1.2 one; will be mangled later
-       = ( $INSTALLING)  ? "$InstLibDirGhc/TopClosureXXXX.o"
-                         : "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR/main/TopClosureXXXX.o";
+       = '';
+#      ( $INSTALLING)  ? "$InstLibDirGhc/TopClosureXXXX.o"
+#                        : "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR/main/TopClosureXXXX.o";
 
 # make depend for Haskell
 $MkDependHS
        = ( $INSTALLING ) ? "$InstBinDirGhc/mkdependHS"
                          : "$TopPwd/$CURRENT_DIR/$GHC_UTILS_DIR/mkdependHS/mkdependHS";
 # Fill in later
 
 # make depend for Haskell
 $MkDependHS
        = ( $INSTALLING ) ? "$InstBinDirGhc/mkdependHS"
                          : "$TopPwd/$CURRENT_DIR/$GHC_UTILS_DIR/mkdependHS/mkdependHS";
 # Fill in later
-@MkDependHS_flags = ( );
+@MkDependHS_flags = ();
 
 # do_link flag should not be reset while rescanning the cmd-line.
 $Do_lnkr    = 1;
 
 # do_link flag should not be reset while rescanning the cmd-line.
 $Do_lnkr    = 1;
@@ -484,14 +438,6 @@ $StolenX86Regs = 4; # **HACK*** of the very worst sort
 $CoreLint      = '';
 $StgLint       = '';
 
 $CoreLint      = '';
 $StgLint       = '';
 
-@CcBoth_flags  = ('-S');   # flags for *any* C compilation
-@CcInjects     = ();
-
-# GCC flags: those for all files, those only for .c files; those only for .hc files
-@CcRegd_flags    = ('-ansi', '-D__STG_GCC_REGS__', '-D__STG_TAILJUMPS__');
-@CcRegd_flags_c        = ();
-@CcRegd_flags_hc = ();
-
 @Import_dir    = ('.'); #-i things
 @Include_dir   = ('.'); #-I things; other default(s) stuck on AFTER option processing
 
 @Import_dir    = ('.'); #-i things
 @Include_dir   = ('.'); #-I things; other default(s) stuck on AFTER option processing
 
@@ -509,18 +455,21 @@ Here are the initial defaults applied to all files:
 \begin{code}
 $Cpp_flag_set = 0;       # (hack)
 $Only_preprocess_C = 0;          # pretty hackish
 \begin{code}
 $Cpp_flag_set = 0;       # (hack)
 $Only_preprocess_C = 0;          # pretty hackish
-$Only_generate_deps = 0;  #
+$Only_preprocess_hc = 0;  # ditto
+$Only_generate_deps = 0;  # "
 $PostprocessCcOutput = 0;
 
 # native code-gen or via C?
 $HaveNativeCodeGen = $GhcWithNativeCodeGen;
 $HscOut = '-C='; # '-C=' ==> .hc output; '-S=' ==> .s output; '-N=' ==> neither
 $HscOut = '-S='
 $PostprocessCcOutput = 0;
 
 # native code-gen or via C?
 $HaveNativeCodeGen = $GhcWithNativeCodeGen;
 $HscOut = '-C='; # '-C=' ==> .hc output; '-S=' ==> .s output; '-N=' ==> neither
 $HscOut = '-S='
-    if $HaveNativeCodeGen && $TargetPlatform =~ /^(alpha|sparc)-/;
-# TEMP: disable x86  if $HaveNativeCodeGen && $TargetPlatform =~ /^(i386|alpha|sparc)-/;
-$ProduceHi   = '-hifile=';
-$HiOnStdout  = 0;
-$HiDiff_flag = '';
+    if $HaveNativeCodeGen && $TargetPlatform =~ /^(alpha)-/;
+# TEMP: disable x86 & Sparc if $HaveNativeCodeGen && $TargetPlatform =~ /^(i386|alpha|sparc)-/;
+$ProduceHi    = '-hifile=';
+$HiOnStdout   = 0;
+$HiWith       = '';
+$HiDiff_flag  = '';
+$Keep_HiDiffs = 0;
 
 $CollectingGCstats = 0;
 $CollectGhcTimings = 0;
 
 $CollectingGCstats = 0;
 $CollectGhcTimings = 0;
@@ -533,9 +482,7 @@ $PROFignore_scc = '';       # set to relevant parser flag if explicit sccs ignored
 $UNPROFscc_auto = '';  # set to relevant hsc flag if forcing auto sccs without profiling
 $TICKYing = '';        # set to t if compiling for ticky-ticky profiling
 $PARing = '';          # set to p if compiling for PAR
 $UNPROFscc_auto = '';  # set to relevant hsc flag if forcing auto sccs without profiling
 $TICKYing = '';        # set to t if compiling for ticky-ticky profiling
 $PARing = '';          # set to p if compiling for PAR
-$CONCURing = '';       # set to c if compiling for CONCURRENT
 $GRANing = '';         # set to g if compiling for GRAN
 $GRANing = '';         # set to g if compiling for GRAN
-$StkChkByPageFaultOK = 1; # may be set to 0 (false) for some builds
 $Specific_hi_file = '';                # set by -ohi <file>; "-" for stdout
 $Specific_dump_file = '';      # set by -odump <file>; "-" for stdout
 $Using_dump_file = 0;
 $Specific_hi_file = '';                # set by -ohi <file>; "-" for stdout
 $Specific_dump_file = '';      # set by -odump <file>; "-" for stdout
 $Using_dump_file = 0;
@@ -556,7 +503,9 @@ $Dump_parser_output = 0;
 $Dump_raw_asm = 0;
 $Dump_asm_splitting_info = 0;
 $NoImplicitPrelude = 0;
 $Dump_raw_asm = 0;
 $Dump_asm_splitting_info = 0;
 $NoImplicitPrelude = 0;
-
+# 1 => don't tell the linker to hoist in PrelMain.Main, as an 
+# external main is provided instead.
+$NoHaskellMain=0;
 
 } # end of initDriverGlobals (Sigh)
 
 
 } # end of initDriverGlobals (Sigh)
 
@@ -584,14 +533,14 @@ linking.)  The checking is done by introducing/munging
 \tr{what(1)}-style strings.  Anyway, here are the relevant global
 variables and their defaults:
 \begin{code}
 \tr{what(1)}-style strings.  Anyway, here are the relevant global
 variables and their defaults:
 \begin{code}
-$LinkChk = 1;  # set to 0 if the link check should *not* be done
+$LinkChk = 0;  # set to 0 if the link check should *not* be done
 
 # major & minor version numbers; major numbers must always agree;
 # minor disagreements yield a warning.
 
 # major & minor version numbers; major numbers must always agree;
 # minor disagreements yield a warning.
-$HsC_major_version = 32;
-$HsC_minor_version = 0;
-$Cc_major_version  = 36;
-$Cc_minor_version  = 1;
+$HsC_major_version = $HscMajorVersion;
+$HsC_minor_version = $HscMinorVersion;
+$Cc_major_version  = $CcMajorVersion;
+$Cc_minor_version  = $CcMinorVersion;
 
 # options: these must always agree
 $HsC_consist_options = '';    # we record, in this order:
 
 # options: these must always agree
 $HsC_consist_options = '';    # we record, in this order:
@@ -609,37 +558,6 @@ $Cc_consist_options  = '';    # we record, in this order:
 Now slurp through the arguments.
 \begin{code}
 
 Now slurp through the arguments.
 \begin{code}
 
-#---------- user defined prelude ---------------------------------------
-
-if (grep(/^-user-prelude$/, @ARGV)) {
-
-    # If ARGV contains -user-prelude we are compiling a piece of 
-    # prelude for the user, probably with additional specialise pragmas
-
-    # We strip out the -O -f and -user-prelude flags provided on
-    # the command line and add the ones used to compile the prelude
-    # ToDo: get these options from a common definition in mkworld
-
-    # We also enable any options forced through with -user-prelude-force
-
-    # Hey, Check out this grep statement ;-)  (PS)
-
-    @ARGV = grep((!/^-O/ && !/^-f/ && !/^-user-prelude$/) || s/^-user-prelude-force//,
-                @ARGV);
-
-    unshift(@ARGV,
-       '-fcompiling-ghc-internals=???', # ToDo!!!!
-        '-O',
-        '-fshow-pragma-name-errs',
-        '-fshow-import-specs',
-        '-fglasgow-exts',
-        '-genSPECS',
-        '-DUSE_FOLDR_BUILD',
-       '-dcore-lint');
-
-    print STDERR "ghc: -user-prelude options:\n", "@ARGV", "\n";
-}
-
 &initDriverGlobals();
 &splitCmdLine(@ARGV);
 # Run through the cmd-line first time.
 &initDriverGlobals();
 &splitCmdLine(@ARGV);
 # Run through the cmd-line first time.
@@ -651,7 +569,11 @@ if (  $Status == 0 && $Only_generate_deps ) {
 
     push (@MkDependHS_flags, "-o$Osuffix") if $Osuffix;
     push (@MkDependHS_flags, "-s$BuildTag") if $BuildTag;
 
     push (@MkDependHS_flags, "-o$Osuffix") if $Osuffix;
     push (@MkDependHS_flags, "-s$BuildTag") if $BuildTag;
-    local($to_do) = "$MkDependHS @MkDependHS_flags -- @Cmd_opts -- @Input_file" ;
+    # They're not (currently) needed, but we need to quote any -#include options
+    foreach (@Cmd_opts) {
+       s/-#include.*$/'$&'/g;
+    };
+    local($to_do) = "$MkDependHS @MkDependHS_flags @HsSourceCppOpts -- @Cmd_opts -- @Input_file" ;
     &run_something($to_do, 'Haskell dependencies');
     exit $Status;
 }
     &run_something($to_do, 'Haskell dependencies');
     exit $Status;
 }
@@ -755,11 +677,12 @@ sub setupOptimiseFlags {
 
    @HsC_minusNoO_flags 
     = (        '-fsimplify',
 
    @HsC_minusNoO_flags 
     = (        '-fsimplify',
-         '\(',
+         '[',
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          '-fcase-of-case',
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          '-fcase-of-case',
+         '-fdo-case-elim',
 #        '-fdo-lambda-eta-expansion',  # too complicated
          '-freuse-con',
 #        '-flet-to-case',              # no strictness analysis, so...
 #        '-fdo-lambda-eta-expansion',  # too complicated
          '-freuse-con',
 #        '-flet-to-case',              # no strictness analysis, so...
@@ -774,9 +697,22 @@ sub setupOptimiseFlags {
 #        '-fsimpl-uf-use-threshold0',
 #        '-fessential-unfoldings-only',
 
 #        '-fsimpl-uf-use-threshold0',
 #        '-fessential-unfoldings-only',
 
-         $Oopt_UnfoldingUseThreshold,
+         #
+         # The presence of -fclone-binds is *temporary* to work around
+          # the fact that the desugarer in 3.0{2.3} does generate
+         # bindings with identical ids, and the type checker doesn't perform
+         # properly cloned type substitutions. Instead, we make sure that all 
+         # binders are cloned first time through the simplifier.
+          #
+         # Will be properly fixed in the `new compiler` I hear, at which point
+         # the cloning can be turned off here.
+         #
+          # Let's find out..
+          #'-fclone-binds',
+
          $Oopt_MaxSimplifierIterations,
          $Oopt_MaxSimplifierIterations,
-         '\)',
+         $Oopt_ShowSimplifierProgress,
+         ']',
        $Oopt_AddAutoSccs,
 #      '-ffull-laziness',      # removed 95/04 WDP following Andr\'e's lead
        
        $Oopt_AddAutoSccs,
 #      '-ffull-laziness',      # removed 95/04 WDP following Andr\'e's lead
        
@@ -789,7 +725,7 @@ sub setupOptimiseFlags {
 
        # initial simplify: mk specialiser happy: minimum effort please
        '-fsimplify',
 
        # initial simplify: mk specialiser happy: minimum effort please
        '-fsimplify',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-fkeep-spec-pragma-ids',     # required before specialisation
 
          $Oopt_FB_Support,
          '-fkeep-spec-pragma-ids',     # required before specialisation
 
@@ -804,23 +740,34 @@ sub setupOptimiseFlags {
 #      f  = E
 #      g* = f
 #      ...f...
 #      f  = E
 #      g* = f
 #      ...f...
-# The g=f will get reverse-substituted later, but it's untidy.
+# The g=f will get reverse-substituted later, but it's untidy. --SLPJ
 #
 #
-#        '-fessential-unfoldings-only',
-#        '-fsimpl-uf-use-threshold0',
+# SDM: Here's why it's necessary.
+#
+#   If we unfold in the first pass before the specialiser is run
+#   we miss opportunities for specialisation because eg. wrappers
+#   have been inlined for specialisable functions.  
+#
+#   This shows up in PrelArr.lhs - the specialised instance for newArray 
+#   calls the generic rangeSize, because rangeSize is strict and is
+#   replaced by its wrapper by the simplifier.
+
+         '-fessential-unfoldings-only',
+         '-fsimpl-uf-use-threshold0',
+
+         # See remark re: cloning in defn of minusnotO
+         '-fclone-binds',
 
          '-fmax-simplifier-iterations1',
          $Oopt_PedanticBottoms,
 
          '-fmax-simplifier-iterations1',
          $Oopt_PedanticBottoms,
-         '\)',
+         ']',
 
        ($Oopt_DoSpecialise) ? (
 
        ($Oopt_DoSpecialise) ? (
-         '-fspecialise-overloaded',
-         $Oopt_SpecialiseUnboxed,
          $Oopt_DoSpecialise,
        ) : (),
 
          $Oopt_DoSpecialise,
        ) : (),
 
-       '-fsimplify',                   # need dependency anal after specialiser ...
-         '\(',                         # need tossing before calc-inlinings ...
+       '-fsimplify',           # need dependency anal after specialiser ...
+         '[',                  # need tossing before calc-inlinings ...
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
@@ -832,17 +779,24 @@ sub setupOptimiseFlags {
          '-freuse-con',
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
          '-freuse-con',
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_MaxSimplifierIterations,
-         '\)',
-
-#LATER:        '-fcalc-inlinings1', -- pointless for 2.01
+         $Oopt_ShowSimplifierProgress,
+         #
+         # The presence of -fclone-binds is *crucial* here as
+         # -ffull-laziness (which we're about to do next) floats
+         # bindings outwards, so we better make sure that this
+         # doesn't result in the floating out of bindings
+         # with identical uniques, i.e., -ffull-laziness needs
+         # to be preceeded by a simplifier pass with -fclone-binds
+         # set.
+          '-fclone-binds',
+         ']',
 
 #      ($Oopt_FoldrBuildWW) ? (
 #              '-ffoldr-build-ww-anal',
 #              '-ffoldr-build-worker-wrapper',
 #              '-fsimplify', 
 
 #      ($Oopt_FoldrBuildWW) ? (
 #              '-ffoldr-build-ww-anal',
 #              '-ffoldr-build-worker-wrapper',
 #              '-fsimplify', 
-#                '\(', 
+#                '[', 
 #                $Oopt_FB_Support,
 #                '-ffloat-lets-exposing-whnf',
 #                '-ffloat-primops-ok',
 #                $Oopt_FB_Support,
 #                '-ffloat-lets-exposing-whnf',
 #                '-ffloat-primops-ok',
@@ -854,9 +808,9 @@ sub setupOptimiseFlags {
 #                '-freuse-con',
 #                $Oopt_PedanticBottoms,
 #                $Oopt_MonadEtaExpansion,
 #                '-freuse-con',
 #                $Oopt_PedanticBottoms,
 #                $Oopt_MonadEtaExpansion,
-#                $Oopt_UnfoldingUseThreshold,
 #                $Oopt_MaxSimplifierIterations,
 #                $Oopt_MaxSimplifierIterations,
-#                '\)',
+#                $Oopt_ShowSimplifierProgress,
+#                ']',
 #       ) : (),
 
        # this pass-ordering sequence was agreed by Simon and Andr\'e
 #       ) : (),
 
        # this pass-ordering sequence was agreed by Simon and Andr\'e
@@ -867,7 +821,7 @@ sub setupOptimiseFlags {
          '-ffoldr-build-on',           # desugar list comprehensions for foldr/build
 
          '-fsimplify', 
          '-ffoldr-build-on',           # desugar list comprehensions for foldr/build
 
          '-fsimplify', 
-           '\(', 
+           '[', 
            '-fignore-inline-pragma',   # **** NB!
            '-fdo-foldr-build',         # NB
            $Oopt_FB_Support,
            '-fignore-inline-pragma',   # **** NB!
            '-fdo-foldr-build',         # NB
            $Oopt_FB_Support,
@@ -881,15 +835,15 @@ sub setupOptimiseFlags {
            '-freuse-con',
            $Oopt_PedanticBottoms,
            $Oopt_MonadEtaExpansion,
            '-freuse-con',
            $Oopt_PedanticBottoms,
            $Oopt_MonadEtaExpansion,
-           $Oopt_UnfoldingUseThreshold,
            $Oopt_MaxSimplifierIterations,
            $Oopt_MaxSimplifierIterations,
-           '\)',
+           $Oopt_ShowSimplifierProgress,
+           ']',
        ) : (),
 
        '-ffloat-inwards',
 
        '-fsimplify',
        ) : (),
 
        '-ffloat-inwards',
 
        '-fsimplify',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
@@ -905,14 +859,14 @@ sub setupOptimiseFlags {
                        # but do reductions if you see them!
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
                        # but do reductions if you see them!
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_MaxSimplifierIterations,
-         '\)',
+         $Oopt_ShowSimplifierProgress,
+         ']',
 
        '-fstrictness',
 
        '-fsimplify',
 
        '-fstrictness',
 
        '-fsimplify',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
@@ -925,9 +879,9 @@ sub setupOptimiseFlags {
          '-flet-to-case',              # Aha! Only done after strictness analysis
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
          '-flet-to-case',              # Aha! Only done after strictness analysis
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_MaxSimplifierIterations,
-         '\)',
+         $Oopt_ShowSimplifierProgress,
+         ']',
 
        '-ffloat-inwards',
 
 
        '-ffloat-inwards',
 
@@ -936,12 +890,12 @@ sub setupOptimiseFlags {
 
 #      ( ($OptLevel != 2)
 #        ? ''
 
 #      ( ($OptLevel != 2)
 #        ? ''
-#      : "-fliberate-case -fsimplify \\( $Oopt_FB_Support -ffloat-lets-exposing-whnf -ffloat-primops-ok -fcase-of-case -fdo-case-elim -fcase-merge -fdo-eta-reduction -fdo-lambda-eta-expansion -freuse-con -flet-to-case $Oopt_PedanticBottoms $Oopt_MonadEtaExpansion $Oopt_UnfoldingUseThreshold $Oopt_MaxSimplifierIterations \\)" ),
+#      : "-fliberate-case -fsimplify [ $Oopt_FB_Support -ffloat-lets-exposing-whnf -ffloat-primops-ok -fcase-of-case -fdo-case-elim -fcase-merge -fdo-eta-reduction -fdo-lambda-eta-expansion -freuse-con -flet-to-case $Oopt_PedanticBottoms $Oopt_MonadEtaExpansion $Oopt_MaxSimplifierIterations $Oopt_ShowSimplifierProgress ]" ),
 
 # Final clean-up simplification:
 
        '-fsimplify',
 
 # Final clean-up simplification:
 
        '-fsimplify',
-         '\(', 
+         '[', 
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
@@ -958,16 +912,15 @@ sub setupOptimiseFlags {
                        # but still do reductions if you see them!
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
                        # but still do reductions if you see them!
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_MaxSimplifierIterations,
-         '\)',
+         $Oopt_ShowSimplifierProgress,
+         ']',
 
       #        '-fstatic-args',
 
 #LATER:        '-fcalc-inlinings2', -- pointless for 2.01
 
       # stg2stg passes
 
       #        '-fstatic-args',
 
 #LATER:        '-fcalc-inlinings2', -- pointless for 2.01
 
       # stg2stg passes
-       '-fupdate-analysis',
        '-flambda-lift',
        $Oopt_FinalStgProfilingMassage,
        $Oopt_StgStats,
        '-flambda-lift',
        $Oopt_FinalStgProfilingMassage,
        $Oopt_StgStats,
@@ -977,6 +930,7 @@ sub setupOptimiseFlags {
 
       # SPECIAL FLAGS for -O2
        ($OptLevel == 2) ? (
 
       # SPECIAL FLAGS for -O2
        ($OptLevel == 2) ? (
+         '-fupdate-analysis',  # virtually useless; relegated to -O2
          '-fsemi-tagging',
        ) : (),
       );
          '-fsemi-tagging',
        ) : (),
       );
@@ -1007,6 +961,8 @@ if ( $OptLevel <= 0 ) {
 } else { # -Ofile, then...
 
     &add_Hsc_flags( @HsC_minusO3_flags );
 } else { # -Ofile, then...
 
     &add_Hsc_flags( @HsC_minusO3_flags );
+    push(@HsC_flags, $Oopt_FinalStgProfilingMassage) if $Oopt_FinalStgProfilingMassage;
+
     push(@CcBoth_flags, ($MinusO2ForC) ? '-O2' : '-O');        # possibly to be elaborated...
 }
 
     push(@CcBoth_flags, ($MinusO2ForC) ? '-O2' : '-O');        # possibly to be elaborated...
 }
 
@@ -1020,7 +976,7 @@ if ( $OptLevel <= 0 ) {
 %*                                                                     *
 %************************************************************************
 
 %*                                                                     *
 %************************************************************************
 
-Sort out @$BuildTag@, @$PROFing@, @$CONCURing@, @$PARing@,
+Sort out @$BuildTag@, @$PROFing@, @$PARing@,
 @$GRANing@, @$TICKYing@:
 \begin{code}
 sub setupBuildFlags {
 @$GRANing@, @$TICKYing@:
 \begin{code}
 sub setupBuildFlags {
@@ -1041,19 +997,13 @@ sub setupBuildFlags {
 
       $Oopt_FinalStgProfilingMassage = '-fmassage-stg-for-profiling';
 
 
       $Oopt_FinalStgProfilingMassage = '-fmassage-stg-for-profiling';
 
-      push(@HsP_flags, (($PROFignore_scc) ? $PROFignore_scc : '-S'));
+      # Ignore user sccs when auto annotating, but warn when doing so.
+      $PROFignore_scc = '-W' if $PROFauto; 
 
 
-      if ( $SplitObjFiles ) {
-        # can't split with cost centres -- would need global and externs
-        print STDERR "$Pgm: WARNING: splitting objects when profiling will *BREAK* if any _scc_s are present!\n";
-        # (but it's fine if there aren't any _scc_s around...)
-#       $SplitObjFiles = 0; # unset
-        #not an error: for now: $Status++;
-      }
+      push(@HsP_flags, (($PROFignore_scc) ? $PROFignore_scc : '-S'));
   }
   #if ( $BuildTag ne '' ) {
   #    local($b) = $BuildDescr{$BuildTag};
   }
   #if ( $BuildTag ne '' ) {
   #    local($b) = $BuildDescr{$BuildTag};
-  #    if ($CONCURing eq 'c') { print STDERR "$Pgm: Can't mix $b with -concurrent.\n"; exit 1; }
   #    if ($PARing    eq 'p') { print STDERR "$Pgm: Can't mix $b with -parallel.\n"; exit 1; }
   #    if ($GRANing   eq 'g') { print STDERR "$Pgm: Can't mix $b with -gransim.\n"; exit 1; }
   #    if ($TICKYing  eq 't') { print STDERR "$Pgm: Can't mix $b with -ticky.\n"; exit 1; }
   #    if ($PARing    eq 'p') { print STDERR "$Pgm: Can't mix $b with -parallel.\n"; exit 1; }
   #    if ($GRANing   eq 'g') { print STDERR "$Pgm: Can't mix $b with -gransim.\n"; exit 1; }
   #    if ($TICKYing  eq 't') { print STDERR "$Pgm: Can't mix $b with -ticky.\n"; exit 1; }
@@ -1066,13 +1016,7 @@ sub setupBuildFlags {
       if ($PARing   eq 'p') { print STDERR "$Pgm: Can't do profiling with -parallel.\n"; exit 1; }
       if ($GRANing  eq 'g') { print STDERR "$Pgm: Can't do profiling with -gransim.\n"; exit 1; }
       if ($TICKYing eq 't') { print STDERR "$Pgm: Can't do profiling with -ticky.\n"; exit 1; }
       if ($PARing   eq 'p') { print STDERR "$Pgm: Can't do profiling with -parallel.\n"; exit 1; }
       if ($GRANing  eq 'g') { print STDERR "$Pgm: Can't do profiling with -gransim.\n"; exit 1; }
       if ($TICKYing eq 't') { print STDERR "$Pgm: Can't do profiling with -ticky.\n"; exit 1; }
-      $BuildTag = ($CONCURing eq 'c') ? '_mr' : '_p' ; # possibly "profiled concurrent"...
-
-  } elsif ( $CONCURing eq 'c' ) {
-      if ($PARing  eq 'p') { print STDERR "$Pgm: Can't mix -concurrent with -parallel.\n"; exit 1; }
-      if ($GRANing eq 'g') { print STDERR "$Pgm: Can't mix -concurrent with -gransim.\n"; exit 1; }
-      $BuildTag = ($TICKYing eq 't')  ? '_mt' : '_mc' ; # possibly "ticky concurrent"...
-      # "profiled concurrent" already acct'd for...
+      $BuildTag = '_p' ;
 
   } elsif ( $PARing eq 'p' ) {
       if ($GRANing  eq 'g') { print STDERR "$Pgm: Can't mix -parallel with -gransim.\n"; exit 1; }
 
   } elsif ( $PARing eq 'p' ) {
       if ($GRANing  eq 'g') { print STDERR "$Pgm: Can't mix -parallel with -gransim.\n"; exit 1; }
@@ -1123,9 +1067,6 @@ Decide what the consistency-checking options are in force for this run:
        $Tag = "${Tag}_" if $Tag ne '';
        $HiSuffix_prelude="${Tag}hi";
   }
        $Tag = "${Tag}_" if $Tag ne '';
        $HiSuffix_prelude="${Tag}hi";
   }
-  #push(@HsC_flags, "-hisuf-prelude=.${HiSuffix_prelude}"); # use appropriate Prelude .hi files
-  #push(@HsC_flags, "-hisuf=.${HiSuffix}");
-
 } # setupBuildFlags
 \end{code}
 
 } # setupBuildFlags
 \end{code}
 
@@ -1145,14 +1086,9 @@ Note: a few ``always apply'' flags were set at the very beginning.
 sub setupMachOpts {
 
   if ($TargetPlatform =~ /^alpha-/) {
 sub setupMachOpts {
 
   if ($TargetPlatform =~ /^alpha-/) {
-      # we know how to *mangle* asm for alpha
-      unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__'));
-      unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK;
       unshift(@CcBoth_flags,  ('-static'));
 
   } elsif ($TargetPlatform =~ /^hppa/) {
       unshift(@CcBoth_flags,  ('-static'));
 
   } elsif ($TargetPlatform =~ /^hppa/) {
-      # we know how to *mangle* asm for hppa
-      unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__'));
       unshift(@CcBoth_flags,  ('-static'));
       #
       # We don't put in '-mlong-calls', because it's only
       unshift(@CcBoth_flags,  ('-static'));
       #
       # We don't put in '-mlong-calls', because it's only
@@ -1167,13 +1103,6 @@ sub setupMachOpts {
         # (very nice, but too bad the HP /usr/include files don't agree.)
 
   } elsif ($TargetPlatform =~ /^i386-/) {
         # (very nice, but too bad the HP /usr/include files don't agree.)
 
   } elsif ($TargetPlatform =~ /^i386-/) {
-      # we know how to *mangle* asm for X86
-      unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__'));
-      unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK && $TargetPlatform !~ /nextstep/;
-      # I do not know how to do STACK_CHECK_BY_PAGE_FAULT
-      # on NeXTs (my fault, not theirs), so I don't.
-      # CaS
-
       # -fno-defer-pop : basically the same game as for m68k
       #
       # -fomit-frame-pointer : *must* ; because we're stealing
       # -fno-defer-pop : basically the same game as for m68k
       #
       # -fomit-frame-pointer : *must* ; because we're stealing
@@ -1185,13 +1114,6 @@ sub setupMachOpts {
       unshift(@CcRegd_flags,    "-DSTOLEN_X86_REGS=$StolenX86Regs");
 
   } elsif ($TargetPlatform =~ /^m68k-/) {
       unshift(@CcRegd_flags,    "-DSTOLEN_X86_REGS=$StolenX86Regs");
 
   } elsif ($TargetPlatform =~ /^m68k-/) {
-      # we know how to *mangle* asm for m68k
-      unshift (@CcRegd_flags, ('-D__STG_REV_TBLS__'));
-      unshift (@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK && $TargetPlatform !~ /nextstep/;
-      # I do not know how to do STACK_CHECK_BY_PAGE_FAULT
-      # on NeXTs (my fault, not theirs), so I don't.
-      # CaS
-
       # -fno-defer-pop : for the .hc files, we want all the pushing/
       #    popping of args to routines to be explicit; if we let things
       #    be deferred 'til after an STGJUMP, imminent death is certain!
       # -fno-defer-pop : for the .hc files, we want all the pushing/
       #    popping of args to routines to be explicit; if we let things
       #    be deferred 'til after an STGJUMP, imminent death is certain!
@@ -1208,29 +1130,33 @@ sub setupMachOpts {
        # also: -fno-defer-pop is not sufficiently well-behaved without it
 
   } elsif ($TargetPlatform =~ /^mips-/) {
        # also: -fno-defer-pop is not sufficiently well-behaved without it
 
   } elsif ($TargetPlatform =~ /^mips-/) {
-      # we (hope to) know how to *mangle* asm for MIPSen
-      unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__'));
-      unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK;
       unshift(@CcBoth_flags,  ('-static'));
 
       unshift(@CcBoth_flags,  ('-static'));
 
-  } elsif ($TargetPlatform =~ /^powerpc-/) {
-      # we know how to *mangle* asm for PowerPC
-# :-(   unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__'));
-      unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK;
+  } elsif ($TargetPlatform =~ /^powerpc-|^rs6000-/) {
       unshift(@CcBoth_flags,  ('-static')); # always easier to start with
       unshift(@CcRegd_flags, ('-finhibit-size-directive')); # avoids traceback tables
       unshift(@CcBoth_flags,  ('-static')); # always easier to start with
       unshift(@CcRegd_flags, ('-finhibit-size-directive')); # avoids traceback tables
-#      unshift(@Ld_flags, ('-Xlinker -bbigtoc -Xlinker -bnoquiet')); # we have lots of toc entries..
-      unshift(@Ld_flags, ('-Xlinker -bbigtoc')); # we have lots of toc entries...
-
   } elsif ($TargetPlatform =~ /^sparc-/) {
   } elsif ($TargetPlatform =~ /^sparc-/) {
-      # we know how to *mangle* asm for SPARC
-      unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__'));
-      unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK;
-
   }
 } # end of setupMachOpts
 \end{code}
 
   }
 } # end of setupMachOpts
 \end{code}
 
+%************************************************************************
+%*                                                                     *
+\subsection{Set up for warnings}
+%*                                                                     *
+%************************************************************************
+
+Several warnings are turned on by default.  These are supposed to be
+the 'I'm pretty sure you've made a mistake here' kind of warnings.
+The rest are turned on by the -W and -Wall options, or individually
+via their -fwarn and -fno-warn flags.
+
+\begin{code}
+sub setupWarningFlags {
+&add_Hsc_flags( @StandardWarnings );
+}
+\end{code}
+
 Same unshifting magic, but for special linker flags.
 
 The configure script determines whether the object file symbol tables
 Same unshifting magic, but for special linker flags.
 
 The configure script determines whether the object file symbol tables
@@ -1244,16 +1170,39 @@ sub setupLinkOpts {
 
   unshift(@Ld_flags,
         (($Ld_main) ? ( '-u', "${uscore}Main_" . $Ld_main . '_closure' ) : ()));
 
   unshift(@Ld_flags,
         (($Ld_main) ? ( '-u', "${uscore}Main_" . $Ld_main . '_closure' ) : ()));
+
+  # things that are referenced by the RTS - make sure that we pull 'em in
   unshift(@Ld_flags,
   unshift(@Ld_flags,
-       (  '-u', "${uscore}PrelBase_Z91Z93_closure"      # i.e., []
-          ,'-u', "${uscore}PrelBase_IZh_static_info"
+         ( '-u', "${uscore}PrelBase_IZh_static_info"
           ,'-u', "${uscore}PrelBase_CZh_static_info"
           ,'-u', "${uscore}PrelBase_CZh_static_info"
-          ,'-u', "${uscore}PrelBase_False_inregs_info"
-          ,'-u', "${uscore}PrelBase_True_inregs_info"
-         ,'-u', "${uscore}STBase_SZh_static_info"
-          ,'-u', "${uscore}DEBUG_REGS"
+          ,'-u', "${uscore}PrelBase_FZh_static_info"
+          ,'-u', "${uscore}PrelBase_DZh_static_info"
+          ,'-u', "${uscore}PrelAddr_AZh_static_info"
+          ,'-u', "${uscore}PrelAddr_WZh_static_info"
+          ,'-u', "${uscore}PrelAddr_I64Zh_static_info"
+          ,'-u', "${uscore}PrelAddr_W64Zh_static_info"
+          ,'-u', "${uscore}PrelForeign_StablePtr_static_info"
+         ,'-u', "${uscore}PrelBase_IZh_con_info"
+          ,'-u', "${uscore}PrelBase_CZh_con_info"
+          ,'-u', "${uscore}PrelBase_FZh_con_info"
+          ,'-u', "${uscore}PrelBase_DZh_con_info"
+          ,'-u', "${uscore}PrelAddr_AZh_con_info"
+          ,'-u', "${uscore}PrelAddr_WZh_con_info"
+          ,'-u', "${uscore}PrelAddr_I64Zh_con_info"
+          ,'-u', "${uscore}PrelAddr_W64Zh_con_info"
+          ,'-u', "${uscore}PrelForeign_StablePtr_con_info"
+          ,'-u', "${uscore}PrelBase_False_static_closure"
+          ,'-u', "${uscore}PrelBase_True_static_closure"
+          ,'-u', "${uscore}PrelPack_unpackCString_closure"
        ));
        ));
-
+  if (!$NoHaskellMain) {
+   unshift (@Ld_flags,'-u', "${uscore}PrelMain_mainIO_closure");
+  }
+  if ($TargetPlatform =~ /^powerpc-|^rs6000-/) {
+    # sometimes we have lots of toc entries...
+    #  unshift(@Ld_flags, ('-Xlinker -bbigtoc -Xlinker -bnoquiet')); 
+    unshift(@Ld_flags, ('-Xlinker -bbigtoc')); 
+  }
 
 } # end of setupLinkOpts
 
 
 } # end of setupLinkOpts
 
@@ -1291,23 +1240,20 @@ sub setupSyslibs {
       $f .= $BuildTag if $f =~ /^-lHS/;
   }
 
       $f .= $BuildTag if $f =~ /^-lHS/;
   }
 
-  # fiddle the TopClosure file name...
-  $TopClosureFile =~ s/XXXX//;
-
   # Push library HSrts, plus boring clib bit
   push(@SysLibrary, "-lHSrts${BuildTag}");
   # Push library HSrts, plus boring clib bit
   push(@SysLibrary, "-lHSrts${BuildTag}");
-  push(@SysLibrary, '-lHSclib');
+
   #
   # RTS compiled with cygwin32, uses the WinMM API
   # to implement the itimers, since cygwin.dll does not
   # support it. Only reqd. for `ways' that use itimers.
   #
   #
   # RTS compiled with cygwin32, uses the WinMM API
   # to implement the itimers, since cygwin.dll does not
   # support it. Only reqd. for `ways' that use itimers.
   #
-  push(@SysLibrary, '-lwinmm') if $BuildTag ne '' && $TargetPlatform eq 'i386-unknown-cygwin32';
+  push(@SysLibrary, '-lwinmm') if $TargetPlatform eq 'i386-unknown-cygwin32';
 
   # Push the pvm libraries
   if ($BuildTag eq '_mp') {
       $pvmlib = "$ENV{'PVM_ROOT'}/lib/$ENV{'PVM_ARCH'}";
 
   # Push the pvm libraries
   if ($BuildTag eq '_mp') {
       $pvmlib = "$ENV{'PVM_ROOT'}/lib/$ENV{'PVM_ARCH'}";
-      push(@SysLibrary, "-L$pvmlib", '-lpvm3', '-lgpvm3');
+      push(@SysLibrary, "-L$pvmlib", '-lgpvm3', '-lpvm3');
       if ( $ENV{'PVM_ARCH'} eq 'SUNMP' ) {
           push(@SysLibrary, '-lthread', '-lsocket', '-lnsl');
       } elsif ( $ENV{'PVM_ARCH'} eq 'SUN4SOL2' ) {
       if ( $ENV{'PVM_ARCH'} eq 'SUNMP' ) {
           push(@SysLibrary, '-lthread', '-lsocket', '-lnsl');
       } elsif ( $ENV{'PVM_ARCH'} eq 'SUN4SOL2' ) {
@@ -1316,7 +1262,16 @@ sub setupSyslibs {
   }
 
 # Push the GNU multi-precision arith lib; and the math library
   }
 
 # Push the GNU multi-precision arith lib; and the math library
-push(@SysLibrary, '-lgmp');
+
+# If this machine has GMP already installed, then we'll get the installed
+# lib here, because presumably the one in the tree won't have been built.
+
+if ($LibGmp eq 'not-installed') {
+  push(@SysLibrary, "-lgmp");
+} else {
+  push(@SysLibrary, "-l$LibGmp");
+}
+
 push(@SysLibrary, '-lm');
 \end{code}
 
 push(@SysLibrary, '-lm');
 \end{code}
 
@@ -1368,8 +1323,8 @@ if ($#Input_file < 0 && $#Link_file < 0) {
     @Input_file = ( '-' );
 
     open(INF, "> $Tmp_prefix.hs") || &tidy_up_and_die(1,"Can't open $Tmp_prefix.hs\n");
     @Input_file = ( '-' );
 
     open(INF, "> $Tmp_prefix.hs") || &tidy_up_and_die(1,"Can't open $Tmp_prefix.hs\n");
-    print STDERR "Enter your Haskell program, end with ^D (on a line of its own):\n";
-    while (<>) { print INF $_; }
+    print STDERR "Enter your Haskell program, end with ^D (on a line of its own):\n" if -t;
+    while (<STDIN>) { print INF $_; }
     close(INF) || &tidy_up_and_die(1,"Failed writing to $Tmp_prefix.hs\n");
 }
 
     close(INF) || &tidy_up_and_die(1,"Failed writing to $Tmp_prefix.hs\n");
 }
 
@@ -1377,7 +1332,7 @@ if ($#Input_file < 0 && $#Link_file < 0) {
 
 Tell the world who we are, if they asked.
 \begin{code}
 
 Tell the world who we are, if they asked.
 \begin{code}
-print STDERR "${PROJECTNAME}, version ${PROJECTVERSION}, patchlevel ${PROJECTPATCHLEVEL}\n"
+print STDERR "${ProjectName}, version ${ProjectVersion}, patchlevel ${ProjectPatchLevel}\n"
     if $Verbose;
 \end{code}
 
     if $Verbose;
 \end{code}
 
@@ -1420,8 +1375,14 @@ if ($Do_lnkr) {
     # for a linker, use an explicitly given one, or the going C compiler ...
     local($lnkr) = ( $Lnkr ) ? $Lnkr : $CcRegd;
 
     # for a linker, use an explicitly given one, or the going C compiler ...
     local($lnkr) = ( $Lnkr ) ? $Lnkr : $CcRegd;
 
+    if ( ($Specific_output_file eq '') && 
+         ($TargetPlatform eq 'i386-unknown-cygwin32') ) {
+         $Specific_output_file = 'main.exe';
+         print STDERR "Output file not specified, defaulting to \"main.exe\"\n";
+    }
+
     local($output) = ($Specific_output_file ne '') ? "-o $Specific_output_file" : '';
     local($output) = ($Specific_output_file ne '') ? "-o $Specific_output_file" : '';
-    @Files_to_tidy = ($Specific_output_file ne '') ? $Specific_output_file : 'a.out';
+    @Files_to_tidy = ($Specific_output_file ne '') ? $Specific_output_file : 'a.out'; 
 
     local($to_do) = "$lnkr $Verbose @Ld_flags $output @Link_file $TopClosureFile $libdirs @UserLibrary @SysLibrary";
     &run_something($to_do, 'Linker');
 
     local($to_do) = "$lnkr $Verbose @Ld_flags $output @Link_file $TopClosureFile $libdirs @UserLibrary @SysLibrary";
     &run_something($to_do, 'Linker');
@@ -1468,7 +1429,7 @@ eval 'exec perl -S \$0 \${1+"\$@"}'
   if \$running_under_some_shell;
 # =!=!=!=!=!=!=!=!=!=!=!
 # This script is automatically generated: DO NOT EDIT!!!
   if \$running_under_some_shell;
 # =!=!=!=!=!=!=!=!=!=!=!
 # This script is automatically generated: DO NOT EDIT!!!
-# Generated by Glasgow Haskell, version ${PROJECTVERSION} ${PROJECTPATCHLEVEL}
+# Generated by Glasgow Haskell, version ${ProjectVersion} ${ProjectPatchLevel}
 #
 \$pvm_executable      = '$pvm_executable';
 \$pvm_executable_base = '$pvm_executable_base';
 #
 \$pvm_executable      = '$pvm_executable';
 \$pvm_executable_base = '$pvm_executable_base';
@@ -1537,6 +1498,8 @@ sub ProcessInputFile {
                          # from input file (need to know for recomp
                          # checking purposes)
     local($hifile_target);# ditto (but .hi file)
                          # from input file (need to know for recomp
                          # checking purposes)
     local($hifile_target);# ditto (but .hi file)
+    local($ofile_c_stub_target); 
+    local($ofile_h_stub_target); 
 \end{code}
 
 Handle the weirdity of input from stdin.
 \end{code}
 
 Handle the weirdity of input from stdin.
@@ -1551,6 +1514,8 @@ Handle the weirdity of input from stdin.
                        ? $Specific_hi_file
                        : "$ifile_root.$HiSuffix"; # ToDo: odirify?
                        # NB: may change if $ifile_root isn't module name (??)
                        ? $Specific_hi_file
                        : "$ifile_root.$HiSuffix"; # ToDo: odirify?
                        # NB: may change if $ifile_root isn't module name (??)
+       ($ofile_c_stub_target = $ifile) =~s/\.[^\.\/]+$/_stub.c/;
+       ($ofile_h_stub_target = $ifile) =~s/\.[^\.\/]+$/_stub.h/;
     } else {
        $ifile = "$Tmp_prefix.hs"; # we know that's where we put the input
        $ifile_root   = '_stdin';
     } else {
        $ifile = "$Tmp_prefix.hs"; # we know that's where we put the input
        $ifile_root   = '_stdin';
@@ -1590,7 +1555,7 @@ Again, we'll do the post-recompilation-checker parts of this later.
     local($is_hc_file) = 1; #Is the C code .hc or .c? Assume .hc for now
 
     # OK, let's strip off some literate junk..
     local($is_hc_file) = 1; #Is the C code .hc or .c? Assume .hc for now
 
     # OK, let's strip off some literate junk..
-    if ($ifile =~ /\.lhs$/) {
+    if ($do_lit2pgm) {
         &runLit2pgm($in_lit2pgm, $lit2pgm_hscpp)
     } else {
         $lit2pgm_hscpp = $ifile;
         &runLit2pgm($in_lit2pgm, $lit2pgm_hscpp)
     } else {
         $lit2pgm_hscpp = $ifile;
@@ -1601,7 +1566,8 @@ Again, we'll do the post-recompilation-checker parts of this later.
 
     # Scan the top of the de-litted file for {-# OPTIONS #-} pragmas
     &check_for_source_options($lit2pgm_hscpp,$ifile);
 
     # Scan the top of the de-litted file for {-# OPTIONS #-} pragmas
     &check_for_source_options($lit2pgm_hscpp,$ifile);
-    # options found in the source file take a back seat, i.e., we scan
+
+    # Options found in the source file take a back seat, i.e., we scan
     # them first. Only process the command line again if source file
     # contained anything of interest *or* there's more than one
     # input file (we have to reset the options).
     # them first. Only process the command line again if source file
     # contained anything of interest *or* there's more than one
     # input file (we have to reset the options).
@@ -1627,6 +1593,7 @@ Again, we'll do the post-recompilation-checker parts of this later.
     &setupOptimiseFlags();
     &setupMachOpts();
     &setupIncPaths();
     &setupOptimiseFlags();
     &setupMachOpts();
     &setupIncPaths();
+    &setupWarningFlags();
     &setupHeapStackSize();
 
     #
     &setupHeapStackSize();
 
     #
@@ -1639,17 +1606,28 @@ Again, we'll do the post-recompilation-checker parts of this later.
                          ? $Do_cc
                          : ( ($HscOut eq '-C=') ? 1 : 0 );
     local($do_as)      = $Do_as;
                          ? $Do_cc
                          : ( ($HscOut eq '-C=') ? 1 : 0 );
     local($do_as)      = $Do_as;
-    local($hsc_out)      = ( $HscOut eq '-C=' ) ? "$Tmp_prefix.hc" : "$Tmp_prefix.s" ;
+    local($hsc_out)       = ( $HscOut eq '-C=' ) ? "$Tmp_prefix.hc" : "$Tmp_prefix.s" ;
+    local($hsc_out_c_stub) = ( $HscOut eq '-C=' ) ? "${Tmp_prefix}_stb.c" : "";
+    local($hsc_out_h_stub) = ( $HscOut eq '-C=' ) ? "${Tmp_prefix}_stb.h" : "";
 
 
-    if ($ifile =~ /.lhs$/ || $ifile =~ /.hs$/ ) {
+    if ($Only_preprocess_hc) { # stop after having run $Cc -E
+       $do_as=0;
+    }
+    if ($Only_preprocess_C)     { # stop after having run $hscpp
+       $do_hsc=0; $do_cc = 0; $do_as=0;
+    } elsif ($ifile =~ /.lhs$/ || $ifile =~ /.hs$/ ) {
        ;
     } elsif ($ifile =~ /\.hc$/ || $ifile =~ /_hc$/ ) { # || $ifile =~ /\.$Isuffix$/o) # ToDo: better
        $do_hscpp = 0; $do_hsc = 0; $do_cc = 1;
        $hsc_out = $ifile;
        ;
     } elsif ($ifile =~ /\.hc$/ || $ifile =~ /_hc$/ ) { # || $ifile =~ /\.$Isuffix$/o) # ToDo: better
        $do_hscpp = 0; $do_hsc = 0; $do_cc = 1;
        $hsc_out = $ifile;
+       $hsc_out_c_stub = '';
+       $hsc_out_h_stub = '';
     } elsif ($ifile =~ /\.c$/) {
        $do_hscpp = 0; $do_hsc = 0; $do_cc = 1;
        $hsc_out = $ifile; $is_hc_file = 0;
     } elsif ($ifile =~ /\.c$/) {
        $do_hscpp = 0; $do_hsc = 0; $do_cc = 1;
        $hsc_out = $ifile; $is_hc_file = 0;
-    } elsif ($ifile =~ /\.s$/) {
+       $hsc_out_c_stub = '';
+       $hsc_out_h_stub = '';
+    } elsif ($ifile =~ /\.[sS]$/) {
        $do_hscpp = 0; $do_hsc = 0; $do_cc = 0;
        $cc_as = $ifile;    
     } else { # don't know what it is, but nothing to do herein...
        $do_hscpp = 0; $do_hsc = 0; $do_cc = 0;
        $cc_as = $ifile;    
     } else { # don't know what it is, but nothing to do herein...
@@ -1659,16 +1637,16 @@ Again, we'll do the post-recompilation-checker parts of this later.
     # hack to avoid running hscpp
     $HsCpp = $Cat if ! $Cpp_flag_set;
 
     # hack to avoid running hscpp
     $HsCpp = $Cat if ! $Cpp_flag_set;
 
-    &runHscpp($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc)
-       if $do_hscpp;
+    &runHscpp($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc) if $do_hscpp;
+
 \end{code}
 
 We now think about whether to run hsc/cc or not (when hsc produces .s
 stuff, it effectively takes the place of both phases).
 \end{code}
 
 We now think about whether to run hsc/cc or not (when hsc produces .s
 stuff, it effectively takes the place of both phases).
-
 To get the output file name right: for each phase that we are {\em
 not} going to run, set its input (i.e., the output of its preceding
 phase) to @"$ifile_root.<suffix>"@.
 To get the output file name right: for each phase that we are {\em
 not} going to run, set its input (i.e., the output of its preceding
 phase) to @"$ifile_root.<suffix>"@.
+
 \begin{code}
     local($going_interactive) = $HscOut eq '-N=' || $ifile_root eq '_stdin';
 
 \begin{code}
     local($going_interactive) = $HscOut eq '-N=' || $ifile_root eq '_stdin';
 
@@ -1677,7 +1655,7 @@ phase) to @"$ifile_root.<suffix>"@.
     # -fvia-C (or the equivalent)
     #
     if ( $HscOut ne '-C=' && $Keep_hc_file_too ) {
     # -fvia-C (or the equivalent)
     #
     if ( $HscOut ne '-C=' && $Keep_hc_file_too ) {
-       print STDERR "Warning: Native code generator to be used, -keep-hc-file-too will be ignored\n";
+       print STDERR "$Pgm: warning: Native code generator to be used, -keep-hc-file-too will be ignored\n";
     }
 
     if (! $do_cc && ! $do_as) { # stopping after hsc
     }
 
     if (! $do_cc && ! $do_as) { # stopping after hsc
@@ -1691,7 +1669,7 @@ phase) to @"$ifile_root.<suffix>"@.
     if (! $do_as) { # stopping after gcc (or hsc)
        $cc_as = ($Specific_output_file ne '')
                 ? $Specific_output_file
     if (! $do_as) { # stopping after gcc (or hsc)
        $cc_as = ($Specific_output_file ne '')
                 ? $Specific_output_file
-                : &odir_ify($ifile_root, ( $Only_preprocess_C ) ? 'i' : 's');
+                : &odir_ify($ifile_root, ( $Only_preprocess_hc ) ? 'i' : 's');
 
        $ofile_target = $cc_as; # reset
     }
 
        $ofile_target = $cc_as; # reset
     }
@@ -1704,12 +1682,35 @@ Now the Haskell compiler, C compiler, and assembler
 \begin{code}
    if ($do_hsc) {
        &runHscAndProcessInterfaces( $ifile, $hscpp_hsc, $ifile_root, 
 \begin{code}
    if ($do_hsc) {
        &runHscAndProcessInterfaces( $ifile, $hscpp_hsc, $ifile_root, 
-                                    $ofile_target, $hifile_target);
+                                    $ofile_target, $hifile_target,
+                                    $going_interactive);
+    }
+
+    if (-f $hsc_out_h_stub) {
+       &run_something("cp $hsc_out_h_stub $ofile_h_stub_target", 'Copy foreign export header file');
+    }
+
+    if (-f $hsc_out_c_stub) {
+       &run_something("cp $hsc_out_c_stub $ofile_c_stub_target", 'Copy foreign export C stubs');
+       local ($hsc_out_s_stub);
+       local ($hsc_out_o_stub);
+       ($ofile_s_stub_target = $ofile_c_stub_target) =~ s/\.(.*)$/\.s/;
+       ($ofile_o_stub_target = $ofile_c_stub_target) =~ s/\.(.*)$/\.o/;
+       &runGcc    (0, $ofile_c_stub_target, $ofile_s_stub_target);
+        &runAs     ($ofile_o_stub_target, $ofile_s_stub_target);
+       #
+       # Bring the C stub protos into scope when compiling the .hc file.
+       #
+       push (@CcInjects, "#include \"${hsc_out_h_stub}\"\n");
+       # Hack - ensure that the stub .h file is included in the OPTIONS section
+       #        if the .hc file is saved.
+       push (@File_options, "-#include \"${ofile_h_stub_target}\"\n");
+       
     }
 
     if ($do_cc) {
        &runGcc    ($is_hc_file, $hsc_out, $cc_as_o);
     }
 
     if ($do_cc) {
        &runGcc    ($is_hc_file, $hsc_out, $cc_as_o);
-       &runMangler($is_hc_file, $cc_as_o, $cc_as, $ifile_root);
+       &runMangler($is_hc_file, $cc_as_o, $cc_as, $ifile_root) if ! $Only_preprocess_hc;
     }
 
     &split_asm_file($cc_as)  if $do_as && $SplitObjFiles;
     }
 
     &split_asm_file($cc_as)  if $do_as && $SplitObjFiles;
@@ -1726,10 +1727,14 @@ Finally, decide what to queue up for linker input.
 
 #ToDo:    local($or_isuf) = ($Isuffix eq '') ? '' : "|$Isuffix";
 
 
 #ToDo:    local($or_isuf) = ($Isuffix eq '') ? '' : "|$Isuffix";
 
-    if ( $ifile !~ /\.(lhs|hs|hc|c|s)$/ && $ifile !~ /_hc$/ ) {
-       print STDERR "$Pgm: don't recognise suffix on `$ifile'; passing it through to linker\n"
-           if $ifile !~ /\.a$/;
-
+    if ( $ifile !~ /\.(lhs|hs|hc|c|s|a|S)$/ && $ifile !~ /_hc$/ ) {
+        # There's sometimes confusion regarding .hi files; users
+       # supplying them on the command line.
+        if ( $ifile =~ /\.hi$/ ) {
+           print STDERR "$Pgm: warning: found `$ifile' on command line; interface files should not be supplied here - ignoring it.\n";
+        } else {
+          print STDERR "$Pgm: don't recognise suffix on `$ifile'; passing it through to linker\n";
+        }
        # oops; we tentatively pushed the wrong thing; fix & do the right thing
        pop(@Link_file); push(@Link_file, $ifile);
     }
        # oops; we tentatively pushed the wrong thing; fix & do the right thing
        pop(@Link_file); push(@Link_file, $ifile);
     }
@@ -1748,9 +1753,13 @@ Finally, decide what to queue up for linker input.
 sub runLit2pgm {
     local($in_lit2pgm, $lit2pgm_hscpp) = @_;
 
 sub runLit2pgm {
     local($in_lit2pgm, $lit2pgm_hscpp) = @_;
 
-    local($to_do) = "echo '#line 1 \"$in_lit2pgm\"' > $lit2pgm_hscpp && ".
-                   "$Unlit @Unlit_flags $in_lit2pgm -  >> $lit2pgm_hscpp";
-    @Files_to_tidy = ( $lit2pgm_hscpp );
+    local($to_do) = "";
+
+    # Only add #line pragma if we're going to need it.
+    $to_do  = "echo '#line 1 \"$in_lit2pgm\"' > $lit2pgm_hscpp && " if ($Cpp_flag_set);
+    $to_do .= "$Unlit @Unlit_flags $in_lit2pgm -  >> $lit2pgm_hscpp";
+     
+    push(@Files_to_tidy, $lit2pgm_hscpp );
 
     &run_something($to_do, 'literate pre-processor');
 }
 
     &run_something($to_do, 'literate pre-processor');
 }
@@ -1760,27 +1769,41 @@ sub runLit2pgm {
 sub runHscpp {
     local($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc) = @_;
 
 sub runHscpp {
     local($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc) = @_;
 
-    local($to_do);
+    local($to_do) = "";
+
+    # Strictly speaking, echoing of the following line pragma is only required
+    # on non-delit'ed input, as we've already added it during de-lit. However,
+    # hscpp will then add a {-# LINE 1 "$lit2pgm_hsc" -} to the top of the file,
+    # which is not very informative (but harmless). Hence, we uniformly have
+    # {-# LINE 1 "$in_lit2pgm" #-} as the first line to all cpp'ed hsc input.
+    #
+    $to_do = "echo '{-# LINE 1 \"$in_lit2pgm\" -}' > $hscpp_hsc && ";
 
     if ($HsCpp eq $Cat) {
 
     if ($HsCpp eq $Cat) {
-       $to_do = "echo '#line 1 \"$in_lit2pgm\"' > $hscpp_hsc && ".
-                       "$HsCpp $lit2pgm_hscpp >> $hscpp_hsc";
-       @Files_to_tidy = ( $hscpp_hsc );
+       $to_do .= "$HsCpp $lit2pgm_hscpp >> $hscpp_hsc";
+       push(@Files_to_tidy, $hscpp_hsc );
        &run_something($to_do, 'Ineffective C pre-processor');
     } else {
        local($includes) = '-I' . join(' -I',@Include_dir);
        &run_something($to_do, 'Ineffective C pre-processor');
     } else {
        local($includes) = '-I' . join(' -I',@Include_dir);
-       $to_do = "echo '#line 1 \"$in_lit2pgm\"' > $hscpp_hsc && ".
-                       "$HsCpp $Verbose $genSPECS_flag @HsCpp_flags -D__HASKELL1__=$Haskell1Version -D__GLASGOW_HASKELL__=$GhcVersionInfo $includes $lit2pgm_hscpp >> $hscpp_hsc";
-       @Files_to_tidy = ( $hscpp_hsc );
+       $to_do .= "$HsCpp $Verbose @HsCpp_flags @HsSourceCppOpts $includes $lit2pgm_hscpp >> $hscpp_hsc";
+       push(@Files_to_tidy, $hscpp_hsc );
        &run_something($to_do, 'Haskellised C pre-processor');
     }
        &run_something($to_do, 'Haskellised C pre-processor');
     }
+   
+    if ( $Only_preprocess_C ) {
+       $to_do = "$Cat $hscpp_hsc";
+       &run_something($to_do, '');
+    }
+
 }
 \end{code}
 
 
 \begin{code}
 sub runHscAndProcessInterfaces {
 }
 \end{code}
 
 
 \begin{code}
 sub runHscAndProcessInterfaces {
-    local($ifile, $hscpp_hsc, $ifile_root, $ofile_target, $hifile_target) = @_;
+    local($ifile, $hscpp_hsc, $ifile_root, 
+          $ofile_target, $hifile_target,
+         $going_interactive) = @_;
 
        # $ifile                is the original input file
        # $hscpp_hsc            post-unlit, post-cpp, etc., input file
 
        # $ifile                is the original input file
        # $hscpp_hsc            post-unlit, post-cpp, etc., input file
@@ -1798,7 +1821,7 @@ sub runHscAndProcessInterfaces {
      $i_atime,$i_mtime,$i_ctime,$i_blksize,$i_blocks) = stat($ifile);
 
     # The informational messages below are now conditional on -v being set -- SOF
      $i_atime,$i_mtime,$i_ctime,$i_blksize,$i_blocks) = stat($ifile);
 
     # The informational messages below are now conditional on -v being set -- SOF
-    if ( ! -f $ofile_target ) {
+    if ( $ofile_target ne "_stdin.s" && ! -f $ofile_target ) {
         print STDERR "$Pgm:compile:Output file $ofile_target doesn't exist\n" if $Verbose;
        $source_unchanged = 0;
     }
         print STDERR "$Pgm:compile:Output file $ofile_target doesn't exist\n" if $Verbose;
        $source_unchanged = 0;
     }
@@ -1806,7 +1829,7 @@ sub runHscAndProcessInterfaces {
     ($o_dev,$o_ino,$o_mode,$o_nlink,$o_uid,$o_gid,$o_rdev,$o_size,
      $o_atime,$o_mtime,$o_ctime,$o_blksize,$o_blocks) = stat(_); # stat info from -f test
 
     ($o_dev,$o_ino,$o_mode,$o_nlink,$o_uid,$o_gid,$o_rdev,$o_size,
      $o_atime,$o_mtime,$o_ctime,$o_blksize,$o_blocks) = stat(_); # stat info from -f test
 
-    if ( ! -f $hifile_target ) {
+    if ( $hifile_target ne "_stdout" && ! -f $hifile_target ) {
         print STDERR "$Pgm:compile:Interface file $hifile_target doesn't exist\n" if $Verbose;
        $source_unchanged = 0;
     }
         print STDERR "$Pgm:compile:Interface file $hifile_target doesn't exist\n" if $Verbose;
        $source_unchanged = 0;
     }
@@ -1814,11 +1837,14 @@ sub runHscAndProcessInterfaces {
     ($hi_dev,$hi_ino,$hi_mode,$hi_nlink,$hi_uid,$hi_gid,$hi_rdev,$hi_size,
      $hi_atime,$hi_mtime,$hi_ctime,$hi_blksize,$hi_blocks) = stat(_); # stat info from -f test
 
     ($hi_dev,$hi_ino,$hi_mode,$hi_nlink,$hi_uid,$hi_gid,$hi_rdev,$hi_size,
      $hi_atime,$hi_mtime,$hi_ctime,$hi_blksize,$hi_blocks) = stat(_); # stat info from -f test
 
-    if ($i_mtime > $o_mtime) {
+    if ( $ofile_target ne "_stdin.s" && $i_mtime > $o_mtime) {
        print STDERR "$Pgm:recompile:Input file $ifile newer than $ofile_target\n" if $Verbose;
        $source_unchanged = 0;
     }
 
        print STDERR "$Pgm:recompile:Input file $ifile newer than $ofile_target\n" if $Verbose;
        $source_unchanged = 0;
     }
 
+    # Tell the compiler which version we're using
+    push(@HsC_flags, "-fhi-version=${ProjectVersionInt}");
+
     # So if source_unchanged is still "1", we pass on the good news to the compiler
     # The -recomp flag can disable this, forcing recompilation
     if ($Do_recomp_chkr && $source_unchanged) {
     # So if source_unchanged is still "1", we pass on the good news to the compiler
     # The -recomp flag can disable this, forcing recompilation
     if ($Do_recomp_chkr && $source_unchanged) {
@@ -1827,12 +1853,12 @@ sub runHscAndProcessInterfaces {
 
     # Run the compiler
 
 
     # Run the compiler
 
-    &runHsc($ifile_root, $hsc_out, $hsc_hi, $going_interactive);
+    &runHsc($ifile_root, $hsc_out, $hsc_hi, $hsc_out_c_stub, $hsc_out_h_stub, $going_interactive);
 
    # See if it bailed out early, saying nothing needed doing.  
    # We work this out by seeing if it created an output .hi file
 
 
    # See if it bailed out early, saying nothing needed doing.  
    # We work this out by seeing if it created an output .hi file
 
-    if ( ! -f $hsc_hi ) {
+    if ( ! -f $hsc_hi && $ProduceHi !~ /-nohifile=/ ) {
        # Doesn't exist, so we bailed out early.
        # Tell the C compiler and assembler not to run
        $do_cc = 0; $do_as = 0;
        # Doesn't exist, so we bailed out early.
        # Tell the C compiler and assembler not to run
        $do_cc = 0; $do_as = 0;
@@ -1850,8 +1876,10 @@ sub runHscAndProcessInterfaces {
        # out early, we still need to touch the interface file of B. The reason
         # for this is that B may export A's interface.
        #
        # out early, we still need to touch the interface file of B. The reason
         # for this is that B may export A's interface.
        #
-       &run_something("touch $ofile_target $hifile_target", 
-                      "Touch $ofile_target $hifile_target,  to propagate dependencies");
+       &run_something("touch $ofile_target",
+                      "Touch $ofile_target,  to propagate dependencies") if $HscOut ne '-N=';
+       &run_something("touch $hifile_target", 
+                      "Touch $hifile_target,  to propagate dependencies") if $ProduceHi =~ /-nohifile=/ ;
 
     } else {   
 
 
     } else {   
 
@@ -1876,9 +1904,10 @@ sub runHscAndProcessInterfaces {
 
 
        # Interface-handling is important enough to live off by itself
 
 
        # Interface-handling is important enough to live off by itself
-       require('ghc-iface.prl') || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-iface.prl!\n");
-       &postprocessHiFile($hsc_hi, $hifile_target, $going_interactive);
-       
+        if ( $ProduceHi !~ /-nohifile=/ ) { # If we've produced one, process it.
+          require('ghc-iface.prl') || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-iface.prl!\n");
+          &postprocessHiFile($hsc_hi, $hifile_target, $going_interactive);
+       }
        # if we're going to split up object files,
        # we inject split markers into the .hc file now
        if ( $HscOut eq '-C=' && $SplitObjFiles ) {
        # if we're going to split up object files,
        # we inject split markers into the .hc file now
        if ( $HscOut eq '-C=' && $SplitObjFiles ) {
@@ -1897,29 +1926,28 @@ sub runHscAndProcessInterfaces {
 
 \begin{code}
 sub runHsc {
 
 \begin{code}
 sub runHsc {
-    local($ifile_root, $hsc_out, $hsc_hi, $going_interactive) = @_;
+    local($ifile_root, $hsc_out, $hsc_hi, $hsc_out_c_stub, $hsc_out_h_stub, $going_interactive) = @_;
 
     # prepend comma to HsP flags (so hsc can tell them apart...)
     foreach $a ( @HsP_flags ) { $a = ",$a" unless $a =~ /^,/; }
 
     &makeHiMap() unless $HiMapDone;
 
     # prepend comma to HsP flags (so hsc can tell them apart...)
     foreach $a ( @HsP_flags ) { $a = ",$a" unless $a =~ /^,/; }
 
     &makeHiMap() unless $HiMapDone;
-    #print STDERR "HiIncludes: $HiIncludeString\n";
     push(@HsC_flags, "-himap=$HiIncludeString");
 
     # here, we may produce .hc/.s and/or .hi files
     local($output) = '';
     push(@HsC_flags, "-himap=$HiIncludeString");
 
     # here, we may produce .hc/.s and/or .hi files
     local($output) = '';
-    @Files_to_tidy = ();
+    #@Files_to_tidy = ();
 
     if ( $going_interactive ) {
 
     if ( $going_interactive ) {
-       # don't need .hi unless going to show it on stdout:
+       # don't need .hi unless we're going to show it on stdout:
        $ProduceHi = '-nohifile=' if ! $HiOnStdout;
        $do_cc = 0; $do_as = 0; $Do_lnkr = 0; # and we won't go any further...
     }
 
     # set up for producing output/.hi; note that flag twiddling
     # may mean that nothing will actually be produced:
        $ProduceHi = '-nohifile=' if ! $HiOnStdout;
        $do_cc = 0; $do_as = 0; $Do_lnkr = 0; # and we won't go any further...
     }
 
     # set up for producing output/.hi; note that flag twiddling
     # may mean that nothing will actually be produced:
-    $output = "$ProduceHi$hsc_hi $HscOut$hsc_out";
-    @Files_to_tidy = ( $hsc_hi, $hsc_out );
+    $output = "$ProduceHi$hsc_hi $HscOut$hsc_out -F=$hsc_out_c_stub -FH=$hsc_out_h_stub";
+    push(@Files_to_tidy, $hsc_hi, $hsc_out, $hsc_out_c_stub, $hsc_out_h_stub );
 
     # if we're compiling foo.hs, we want the GC stats to end up in foo.stat
     if ( $CollectingGCstats ) {
 
     # if we're compiling foo.hs, we want the GC stats to end up in foo.stat
     if ( $CollectingGCstats ) {
@@ -1930,6 +1958,7 @@ sub runHsc {
     if ( $CollectGhcTimings ) { # assume $RTS_style eq 'ghc'
        # emit nofibbish time/bytes-alloc stats to stderr;
        # see later .stat file post-processing
     if ( $CollectGhcTimings ) { # assume $RTS_style eq 'ghc'
        # emit nofibbish time/bytes-alloc stats to stderr;
        # see later .stat file post-processing
+       print STDERR "warning: both -Rgc-stats and -Rghc-timing used, -Rghc-timing wins." if $CollectingGCstats;
        push(@HsC_rts_flags, "-s$Tmp_prefix.stat");
        push(@Files_to_tidy, "$Tmp_prefix.stat");
     }
        push(@HsC_rts_flags, "-s$Tmp_prefix.stat");
        push(@Files_to_tidy, "$Tmp_prefix.stat");
     }
@@ -1941,7 +1970,28 @@ sub runHsc {
     }
 
     local($to_do);
     }
 
     local($to_do);
-    $to_do = "$HsC @HsP_flags ,$hscpp_hsc $dump @HsC_flags $CoreLint $StgLint $Verbose $output +RTS @HsC_rts_flags";
+    # Win32 only: If the command processor used by system()
+    # exec()s the application as an ordinary Win32 executable,
+    # we're in trouble here, since the command line is likely
+    # to be > 255 chars long. To work around this situation,
+    # $HsC also understands `at-files',  i.e., `@file' on the
+    # command line will cause $HsC to add the contents of `file'
+    # to the command line.
+    #
+    #  [ Note: support for `at-files' is not compiled in by default ]
+    $cmd_line_opts_via_at_file=0;
+    if ($cmd_line_opts_via_at_file) {
+
+      local($to_do_opts) = "$Tmp_prefix.opts";
+      open(OPTS, "> $Tmp_prefix.opts") || &tidy_up_and_die(1,"Can't open $Tmp_prefix.opts\n");
+      print OPTS "$dump @HsC_flags $CoreLint $StgLint $Verbose";
+      close(OPTS);
+      $to_do = "$HsC @HsP_flags ,$hscpp_hsc \@$Tmp_prefix.opts $output +RTS @HsC_rts_flags";
+
+    } else {
+
+      $to_do = "$HsC @HsP_flags ,$hscpp_hsc $dump @HsC_flags $CoreLint $StgLint $Verbose $output +RTS @HsC_rts_flags";
+    }
     &run_something($to_do, 'Haskell compiler');
 
     # finish business w/ nofibbish time/bytes-alloc stats
     &run_something($to_do, 'Haskell compiler');
 
     # finish business w/ nofibbish time/bytes-alloc stats
@@ -2034,7 +2084,7 @@ sub runGcc {
     local($cc_help_s) = "ghc$$.s";
 
     $cc       = $CcRegd;
     local($cc_help_s) = "ghc$$.s";
 
     $cc       = $CcRegd;
-    $s_output = ($is_hc_file || $TargetPlatform =~ /^(powerpc|hppa|i386)/) ? $cc_as_o : $cc_as;
+    $s_output = ($is_hc_file || $TargetPlatform =~ /^(powerpc|rs6000|hppa)/) ? $cc_as_o : $cc_as;
     $c_flags .= " @CcRegd_flags";
     $c_flags .= ($is_hc_file) ? " @CcRegd_flags_hc"  : " @CcRegd_flags_c";
 
     $c_flags .= " @CcRegd_flags";
     $c_flags .= ($is_hc_file) ? " @CcRegd_flags_hc"  : " @CcRegd_flags_c";
 
@@ -2043,32 +2093,35 @@ sub runGcc {
     open(TMP, "> $cc_help") || &tidy_up_and_die(1,"$Pgm: failed to open `$cc_help' (to write)\n");
     if ( $is_hc_file ) {
        print TMP <<EOINCL;
     open(TMP, "> $cc_help") || &tidy_up_and_die(1,"$Pgm: failed to open `$cc_help' (to write)\n");
     if ( $is_hc_file ) {
        print TMP <<EOINCL;
-#ifdef __STG_GCC_REGS__
-# if ! (defined(MAIN_REG_MAP) || defined(MARK_REG_MAP) || defined(SCAN_REG_MAP) || defined(SCAV_REG_MAP) || defined(FLUSH_REG_MAP))
-#  define MAIN_REG_MAP
-# endif
-#endif
-#include "stgdefs.h"
+#include "Stg.h"
 EOINCL
        # user may have asked for #includes to be injected...
        print TMP @CcInjects if $#CcInjects >= 0;
 EOINCL
        # user may have asked for #includes to be injected...
        print TMP @CcInjects if $#CcInjects >= 0;
+    } else {
+       # Straight .c files may want to know that they're being used
+       # with a particular version of GHC, so we define __GLASGOW_HASKELL__ for their benefit.
+        print TMP "#define __GLASGOW_HASKELL__ ${ProjectVersionInt}\n";
     }
     # heave in the consistency info
     print TMP "static char ghc_cc_ID[] = \"\@(#)cc $ifile\t$Cc_major_version.$Cc_minor_version,$Cc_consist_options\";\n";
 
     }
     # heave in the consistency info
     print TMP "static char ghc_cc_ID[] = \"\@(#)cc $ifile\t$Cc_major_version.$Cc_minor_version,$Cc_consist_options\";\n";
 
-    # and #include the real source
     print TMP "#include \"$hsc_out\"\n";
     close(TMP) || &tidy_up_and_die(1,"Failed writing to $cc_help\n");
 
     print TMP "#include \"$hsc_out\"\n";
     close(TMP) || &tidy_up_and_die(1,"Failed writing to $cc_help\n");
 
-    local($to_do) = "$cc $Verbose $ddebug_flag $c_flags @Cpp_define -D__HASKELL1__=$Haskell1Version $includes $cc_help > $Tmp_prefix.ccout 2>&1 && ( if [ $cc_help_s != $s_output ] ; then mv $cc_help_s $s_output ; else exit 0 ; fi )";
-    # note: __GLASGOW_HASKELL__ is pointedly *not* #defined at the C level.
-    if ( $Only_preprocess_C ) { # HACK ALERT!
+    # Don't redirect stderr into intermediate file if slamming output onto stdout (e.g., with -E)
+    local($fuse_stderr) = "2>&1" if ! $Only_preprocess_hc;
+    local($to_do) = "$cc $Verbose $ddebug_flag $c_flags @Cpp_define $includes $cc_help > $Tmp_prefix.ccout $fuse_stderr && ( if [ $cc_help_s != $s_output ] ; then mv $cc_help_s $s_output ; else exit 0 ; fi )";
+
+    if ( $Only_preprocess_hc ) { # HACK ALERT!
        $to_do =~ s/ -S\b//g;
     }
        $to_do =~ s/ -S\b//g;
     }
-    @Files_to_tidy = ( $cc_help, $cc_help_s, $s_output );
-    $PostprocessCcOutput = 1;  # hack, dear hack...
+    push(@Files_to_tidy, $cc_help, $cc_help_s, $s_output );
+    $PostprocessCcOutput = 1 if ! $Only_preprocess_hc; # hack, dear hack...
     &run_something($to_do, 'C compiler');
     $PostprocessCcOutput = 0;
     &run_something($to_do, 'C compiler');
     $PostprocessCcOutput = 0;
+    if ( $Only_preprocess_hc ) {
+       system("$Cat $Tmp_prefix.ccout");
+    }
     unlink($cc_help, $cc_help_s);
 }
 \end{code}
     unlink($cc_help, $cc_help_s);
 }
 \end{code}
@@ -2089,42 +2142,17 @@ sub runMangler {
        # post-process the assembler [.hc files only]
        &mangle_asm($cc_as_o, $cc_as);
 
        # post-process the assembler [.hc files only]
        &mangle_asm($cc_as_o, $cc_as);
 
-
-#OLD: for sanity:
-#OLD:  local($target) = 'oops';
-#OLD:  $target = '-alpha'      if $TargetPlatform =~ /^alpha-/;
-#OLD:  $target = '-hppa'       if $TargetPlatform =~ /^hppa/;
-#OLD:  $target = '-old-asm'    if $TargetPlatform =~ /^i386-/;
-#OLD:  $target = '-m68k'       if $TargetPlatform =~ /^m68k-/;
-#OLD:  $target = '-mips'       if $TargetPlatform =~ /^mips-/;
-#OLD:  $target = ''            if $TargetPlatform =~ /^powerpc-/;
-#OLD:  $target = '-solaris'    if $TargetPlatform =~ /^sparc-sun-solaris2/;
-#OLD:  $target = '-sparc'      if $TargetPlatform =~ /^sparc-sun-sunos4/;
-#OLD:
-#OLD:  if ( $target ne '' ) {
-#OLD:      require("ghc-asm$target.prl")
-#OLD:      || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm$target.prl!\n");
-#OLD:      &mangle_asm($cc_as_o, "$cc_as-2"); # the OLD one!
-#OLD:      &run_something("$Cmp -s $cc_as-2 $cc_as || $Diff $cc_as-2 $cc_as 1>&2 || exit 0",
-#OLD:          "Diff'ing old and new mangled .s files"); # NB: to stderr
-#OLD:  }
-
     } elsif ($TargetPlatform =~ /^hppa/) {
        # minor mangling of non-threaded files for hp-pa only
        require('ghc-asm.prl')
        || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm-hppa.prl!\n");
        &mini_mangle_asm_hppa($cc_as_o, $cc_as);
 
     } elsif ($TargetPlatform =~ /^hppa/) {
        # minor mangling of non-threaded files for hp-pa only
        require('ghc-asm.prl')
        || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm-hppa.prl!\n");
        &mini_mangle_asm_hppa($cc_as_o, $cc_as);
 
-    } elsif ($TargetPlatform =~ /^powerpc/) {
-       # minor mangling of non-threaded files for hp-pa only
+    } elsif ($TargetPlatform =~ /^powerpc|^rs6000/) {
+       # minor mangling of non-threaded files for powerpcs and rs6000s 
        require('ghc-asm.prl')
        || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm-powerpc.prl!\n");
        &mini_mangle_asm_powerpc($cc_as_o, $cc_as);
        require('ghc-asm.prl')
        || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm-powerpc.prl!\n");
        &mini_mangle_asm_powerpc($cc_as_o, $cc_as);
-    } elsif ($TargetPlatform =~ /^i386/) {
-       # extremely-minor OFFENSIVE mangling of non-threaded just one file
-       require('ghc-asm.prl')
-       || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm.prl!\n");
-       &mini_mangle_asm_i386($cc_as_o, $cc_as);
     }
 
     # save a copy of the .s file, even if we are carrying on...
     }
 
     # save a copy of the .s file, even if we are carrying on...
@@ -2140,9 +2168,12 @@ sub runAs {
 
     local($asmblr) = ( $As ) ? $As : $CcRegd;
 
 
     local($asmblr) = ( $As ) ? $As : $CcRegd;
 
+    # need to add the -I flags in case the file is going through cpp (.S files)
+    local($includes) = '-I' . join(' -I', @Include_dir);
+
     if ( ! $SplitObjFiles ) {
     if ( ! $SplitObjFiles ) {
-       local($to_do)  = "$asmblr -o $as_out -c @As_flags $cc_as";
-       @Files_to_tidy = ( $as_out );
+       local($to_do)  = "$asmblr -o $as_out -c @As_flags $includes $cc_as";
+       push(@Files_to_tidy, $as_out );
        &run_something($to_do, 'Unix assembler');
 
     } else { # more complicated split-ification...
        &run_something($to_do, 'Unix assembler');
 
     } else { # more complicated split-ification...
@@ -2162,7 +2193,7 @@ sub runAs {
        for ($f = 1; $f <= $NoOfSplitFiles; $f++ ) {
            local($split_out) = &odir_ify("${ifile_root}__${f}",'o');
            local($to_do) = "$asmblr -o $split_out -c @As_flags ${Tmp_prefix}__${f}.s";
        for ($f = 1; $f <= $NoOfSplitFiles; $f++ ) {
            local($split_out) = &odir_ify("${ifile_root}__${f}",'o');
            local($to_do) = "$asmblr -o $split_out -c @As_flags ${Tmp_prefix}__${f}.s";
-           @Files_to_tidy = ( $split_out );
+           push(@Files_to_tidy, $split_out );
 
            &run_something($to_do, 'Unix assembler');
        }
 
            &run_something($to_do, 'Unix assembler');
        }
@@ -2220,16 +2251,10 @@ sub run_something {
        open(CCOUT, "< $Tmp_prefix.ccout")
            || &tidy_up_and_die(1,"$Pgm: failed to open `$Tmp_prefix.ccout'\n");
        while ( <CCOUT> ) {
        open(CCOUT, "< $Tmp_prefix.ccout")
            || &tidy_up_and_die(1,"$Pgm: failed to open `$Tmp_prefix.ccout'\n");
        while ( <CCOUT> ) {
-           next if /attribute directive ignored/;
            next if /call-clobbered/;
            next if /call-clobbered/;
-           next if /from .*COptRegs\.lh/;
-           next if /from .*(stg|rts)defs\.h:/;
+           next if /control reaches end/;
+           next if /from .*Stg\.h:/;
            next if /from ghc\d+.c:\d+:/;
            next if /from ghc\d+.c:\d+:/;
-           next if /from .*\.lc/;
-           next if /from .*SMinternal\.l?h/;
-           next if /ANSI C does not support \`long long\'/;
-           next if /warning:.*was declared \`extern\' and later \`static\'/;
-           next if /warning: assignment discards \`const\' from pointer target type/;
            next if /: At top level:$/;
            next if /: In function \`.*\':$/;
            next if /\`ghc_cc_ID\' defined but not used/;
            next if /: At top level:$/;
            next if /: In function \`.*\':$/;
            next if /\`ghc_cc_ID\' defined but not used/;
@@ -2242,7 +2267,6 @@ sub run_something {
         if ($Using_dump_file) {
            print STDERR "Compilation Errors dumped in $Specific_dump_file\n";
        }
         if ($Using_dump_file) {
            print STDERR "Compilation Errors dumped in $Specific_dump_file\n";
        }
-
        &tidy_up_and_die($return_val, '');
     }
     $Using_dump_file = 0;
        &tidy_up_and_die($return_val, '');
     }
     $Using_dump_file = 0;
@@ -2263,20 +2287,27 @@ sub process_ghc_timings {
     local($SysSpecificTiming) = 'ghc';
 
     open(STATS, $StatsFile) || die "Failed when opening $StatsFile\n";
     local($SysSpecificTiming) = 'ghc';
 
     open(STATS, $StatsFile) || die "Failed when opening $StatsFile\n";
-    local($tot_live) = 0; # for calculating avg residency
+    local($max_live)    = 0; 
+    local($tot_live)    = 0; # for calculating residency stuff
+    local($tot_samples) = 0;
 
     while (<STATS>) {
 
     while (<STATS>) {
-       $tot_live += $1 if /^\s*\d+\s+\d+\s+\d+\.\d+\%\s+(\d+)\s+\d+\.\d+\%/;
-
-       $BytesAlloc = $1 if /^\s*([0-9,]+) bytes allocated in the heap/;
+       if (! /Minor/ && /^\s*\d+\s+\d+\s+(\d+)\s+\d+\.\d+\%/ ) {
+               $max_live = $1 if $max_live < $1;
+               $tot_live += $1;
+               $tot_samples += 1;
+       }
+        $BytesAlloc = $1 if /^\s*([0-9,]+) bytes allocated in the heap/;
 
        if ( /^\s*([0-9,]+) bytes maximum residency .* (\d+) sample/ ) {
            $MaxResidency = $1; $ResidencySamples = $2;
        }
 
 
        if ( /^\s*([0-9,]+) bytes maximum residency .* (\d+) sample/ ) {
            $MaxResidency = $1; $ResidencySamples = $2;
        }
 
-       $GCs = $1 if /^\s*([0-9,]+) garbage collections? performed/;
+        $GCs = $1 if /^\s*([0-9,]+) garbage collections? performed/;
 
 
-       if ( /^\s*INIT\s+time\s*(\d+\.\d\d)s\s*\(\s*(\d+\.\d\d)s elapsed\)/ ) {
+       # The presence of -? in the following pattern is only there to
+       # accommodate 0.29 && <= 2.05 RTS'
+       if ( /^\s*INIT\s+time\s*(\d+\.\d\d)s\s*\(\s*-?(\d+\.\d\d)s elapsed\)/ ) {
            $InitTime = $1; $InitElapsed = $2;
        } elsif ( /^\s*MUT\s+time\s*(\d+\.\d\d)s\s*\(\s*(\d+\.\d\d)s elapsed\)/ ) {
            $MutTime = $1; $MutElapsed = $2;
            $InitTime = $1; $InitElapsed = $2;
        } elsif ( /^\s*MUT\s+time\s*(\d+\.\d\d)s\s*\(\s*(\d+\.\d\d)s elapsed\)/ ) {
            $MutTime = $1; $MutElapsed = $2;
@@ -2285,8 +2316,10 @@ sub process_ghc_timings {
        }
     }
     close(STATS) || die "Failed when closing $StatsFile\n";
        }
     }
     close(STATS) || die "Failed when closing $StatsFile\n";
-    if ( defined($ResidencySamples) && $ResidencySamples > 0 ) {
-       $AvgResidency = int ($tot_live / $ResidencySamples) ;
+    if ( $tot_samples > 0 ) {
+       $ResidencySamples = $tot_samples;
+       $MaxResidency = $max_live;
+       $AvgResidency = int ($tot_live / $tot_samples) ;
     }
 
     # warn about what we didn't find
     }
 
     # warn about what we didn't find
@@ -2371,7 +2404,7 @@ nonsensical).
 sub grab_arg_arg {
     local(*Args, $option, $rest_of_arg) = @_;
     
 sub grab_arg_arg {
     local(*Args, $option, $rest_of_arg) = @_;
     
-    if ($rest_of_arg) {
+    if ($rest_of_arg ne '') {
        return($rest_of_arg);
     } elsif ($#Args >= 0) {
        local($temp) = $Args[0]; shift(@Args); 
        return($rest_of_arg);
     } elsif ($#Args >= 0) {
        local($temp) = $Args[0]; shift(@Args); 
@@ -2418,6 +2451,197 @@ sub add_Hsc_flags {
 }
 \end{code}
 
 }
 \end{code}
 
+To add another system library, you'll need to augment the
+Supported_syslibs variable with name and info on your addition
+to the syslib family. The info bit consist of the following:
+
+   - interface file directory
+       see the misc or posix entry for how to distinguish
+       between using installed and build tree directories.
+       
+   - directory location of archives
+       
+   - location of (way-independent) C support libs.
+       not all libraries need this - if you don't, just
+       give the empty string.
+   - list of syslibs you depend on.
+
+   - additional ghc command line flags that should be used.
+   - additional C compiler command line flags that should be used.
+   - link 
+
+
+\begin{code}
+
+# Hash to keep track of 
+%Syslibs_added = ();
+
+sub add_syslib {
+    local($syslib) = @_;
+
+    # Lifting this out of this sub brings it out of scope - why??
+    %Supported_syslibs =
+     ( exts,
+       [  # where to slurp interface files from
+         ( $INSTALLING 
+              ? "$InstLibDirGhc/imports/exts"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/exts"
+         )
+       , # where to find the archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/exts"
+         )
+       , '' # no cbits
+       , '' # Syslib dependencies
+       , '' # extra ghc opts
+       , '' # extra cc opts
+       , '' # extra ld opts
+       ],
+
+       misc,
+       [  # where to slurp interface files from
+         ( $INSTALLING 
+              ? "$InstLibDirGhc/imports/misc"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/misc"
+         )
+       , # where to find the archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/misc"
+         )
+       , # where to find the cbits archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/misc/cbits"
+         )
+       , 'exts' # Syslib dependencies
+       , ''     # extra ghc opts
+       , ''     # extra cc opts
+       , ( $TargetPlatform =~ /-solaris2$/  ? '-lnsl -lsocket' : '')
+       ],
+       hbc,
+       [  # where to slurp interface files from
+         ( $INSTALLING 
+              ? "$InstLibDirGhc/imports/hbc"
+              : "$TopPwd/CONTRIB/libraries/hbc/src"
+         )
+       , # where to find the archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/CONTRIB/libraries/src/hbc"
+         )
+       , # where to find the cbits archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/CONTRIB/libraries/hbc/cbits"
+         )
+       , 'exts' # Syslib dependencies
+       , ''     # extra ghc opts
+       , ''     # extra cc opts
+       , ''
+       ],
+       posix,
+       [  # where to slurp interface files from
+         ( $INSTALLING 
+              ? "$InstLibDirGhc/imports/posix"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/posix"
+         )
+       , # where to find the archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/posix"
+         )
+       , # where to find the cbits archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/posix/cbits"
+         )
+       , 'misc' # Syslib dependencies
+       , ''     # extra ghc opts
+       , ''     # extra cc opts
+       , ''     # extra ld opts
+       ],
+       concurrent,
+       [  # where to slurp interface files from
+         ( $INSTALLING 
+              ? "$InstLibDirGhc/imports/concurrent"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/concurrent"
+         )
+       , # where to find the archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/concurrent"
+         )
+       , '' # where to find the cbits archive to use when linking
+       , '' # Syslib dependencies
+       , '' # extra ghc opts
+       , '' # extra cc opts
+       , '' # extra ld opts
+       ],
+       win32,
+       [  # where to slurp interface files from
+         ( $INSTALLING 
+              ? "$InstLibDirGhc/imports/win32"
+              : "$TopPwd/hslibs/win32/src"
+         )
+       , # where to find the archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/hslibs/win32/src"
+         )
+       , ''
+       , 'exts' # Syslib dependencies
+       , ''     # extra ghc opts
+       , ''     # extra cc opts
+       , '-luser32 -lgdi32'     # extra ld opts
+       ]
+    );
+
+    # check if it's supported..
+    
+    if ( !exists $Supported_syslibs{$syslib} ) {
+       print STDERR "$Pgm: no such system library (-syslib): $syslib\n";
+       $Status++;
+       return;
+    }
+
+    # This check is here to avoid syslib loops from
+    # spoiling the party. A side-effect of it is that
+    # it disallows multiple mentions of a syslib on a command-line,
+    # explicit *and* implicit ones (i.e., "-syslib exts -syslib misc"
+    # is not equal to "-syslib exts -syslib misc -syslib exts",
+    # which it needs to be)
+    # 
+    # Since our current collection of syslibs don't have any
+    # loops, this test is disabled.
+    #
+    # ToDo: loop avoidance scheme when the need arises
+    #
+    #return if ( exists $Syslibs_added{$syslib} );
+       
+    $Syslibs_added{$syslib} = 1;
+
+    local ($hi_dir, $lib_dir, $lib_cbits_dir,
+          $syslib_deps, $syslib_ghc_opts,
+          $syslib_cc_opts, $syslib_ld_opts) = @{ $Supported_syslibs{$syslib} };
+
+
+    unshift(@SysImport_dir, $hi_dir);
+    push(@SysLibrary_dir, $lib_dir);
+    push(@SysLibrary_dir, $lib_cbits_dir) if ( $lib_cbits_dir ne '');
+
+    push(@SysLibrary, "-lHS$syslib");
+    push(@SysLibrary, "-lHS${syslib}_cbits") if ( $lib_cbits_dir ne '');
+    push(@SysLibrary, $syslib_ld_opts) if ($syslib_ld_opts ne '');   
+
+    # Add on any extra dependencies.
+    foreach $lib (split(' ',$syslib_deps)) {
+      &add_syslib($lib);
+    }
+}
+\end{code}
+
 Source files may have {-# OPTIONS ... #-} pragmas at the top, containing
 command line options we want to append to collection of commands specified
 directly. @check_for_source_options@ looks at the top of a de-lit'ified Haskell
 Source files may have {-# OPTIONS ... #-} pragmas at the top, containing
 command line options we want to append to collection of commands specified
 directly. @check_for_source_options@ looks at the top of a de-lit'ified Haskell
@@ -2451,7 +2675,10 @@ sub check_for_source_options {
         elsif ( /^$/ ) { # ignore empty lines
            ;
         }
         elsif ( /^$/ ) { # ignore empty lines
            ;
         }
-        elsif ( /^#line.+$/ ) { # ignore comment lines
+        elsif ( /^#line.+$/ ) { # ignore comment lines (unused..ToDo: rm )
+           ;
+        }
+        elsif ( /^{-# LINE.+$/ ) { # ignore line pragmas
            ;
         }
         else { # stop looking, something non-empty / not
            ;
         }
         else { # stop looking, something non-empty / not
@@ -2481,11 +2708,11 @@ sub splitCmdLine {
 arg: while($_ = $args[0]) {
     shift(@args);
     # sigh, we have to deal with these -option arg specially here.
 arg: while($_ = $args[0]) {
     shift(@args);
     # sigh, we have to deal with these -option arg specially here.
-    /^-(tmpdir|odir|o|isuf|osuf|hisuf|hisuf-prelude|odump|syslib)$/ && 
+    /^-(tmpdir|odir|ohi|o|isuf|osuf|hisuf|odump|syslib)$/ && 
        do { push(@Cmd_opts, $_); push(@Cmd_opts,$args[0]); shift(@args); next arg; };
        do { push(@Cmd_opts, $_); push(@Cmd_opts,$args[0]); shift(@args); next arg; };
-    /^-./  && do { push(@Cmd_opts, $_); next arg; };
+    /^--?./  && do { push(@Cmd_opts, $_); next arg; };
 
 
-    if (/\.[oa]$/) {
+    if (/\.([^_]+_)?[oa]$/) {
        push(@Link_file, $_);
     } else {
        push(@Input_file, $_);
        push(@Link_file, $_);
     } else {
        push(@Input_file, $_);
@@ -2545,13 +2772,13 @@ arg: while($_ = $Args[0]) {
     if (/^-\?$/ || /^--?help$/) { print $LongUsage; exit $Status; }
 
     #-----------version ----------------------------------------------------
     if (/^-\?$/ || /^--?help$/) { print $LongUsage; exit $Status; }
 
     #-----------version ----------------------------------------------------
-    /^--version$/   && do { print STDERR "${PROJECTNAME}, version ${PROJECTVERSION}, patchlevel ${PROJECTPATCHLEVEL}\n"; exit $Status; };
+    /^--version$/   && do { print STDERR "${ProjectName}, version ${ProjectVersion}, patchlevel ${ProjectPatchLevel}\n"; exit $Status; };
 
     #---------- verbosity and such -----------------------------------------
     /^-v$/         && do { $Verbose = '-v'; $Time = 'time'; next arg; };
 
     #---------- what phases are to be run ----------------------------------
 
     #---------- verbosity and such -----------------------------------------
     /^-v$/         && do { $Verbose = '-v'; $Time = 'time'; next arg; };
 
     #---------- what phases are to be run ----------------------------------
-    /^-recomp/     && do { $Do_recomp_chkr = 1; next arg; };
+    /^-(no-)?recomp/       && do { $Do_recomp_chkr = ($1 eq '') ? 1 : 0; next arg; };
 
     /^-cpp$/       && do { $Cpp_flag_set = 1; next arg; };
     # change the global default:
 
     /^-cpp$/       && do { $Cpp_flag_set = 1; next arg; };
     # change the global default:
@@ -2566,15 +2793,18 @@ arg: while($_ = $Args[0]) {
                            next arg; };
     # leave out actual C generation (debugging) [also turns off interface gen]
 
                            next arg; };
     # leave out actual C generation (debugging) [also turns off interface gen]
 
-    /^-hi$/        && do { $HiOnStdout = 1; $ProduceHi = '-hifile='; next arg; };
+
+    /^-hi$/             && do { $HiOnStdout = 1; $ProduceHi = '-hifile='; next arg; };
     # _do_ generate an interface; usually used as: -noC -hi
 
     /^-nohi$/      && do { $ProduceHi = '-nohifile='; next arg; };
     # don't generate an interface (even if generating C)
 
     # _do_ generate an interface; usually used as: -noC -hi
 
     /^-nohi$/      && do { $ProduceHi = '-nohifile='; next arg; };
     # don't generate an interface (even if generating C)
 
-    /^-hi-diffs$/             && do { $HiDiff_flag = 'normal'; next arg; };
-    /^-hi-diffs-with-usages$/ && do { $HiDiff_flag = 'usages'; next arg; };
-    /^-no-hi-diffs$/          && do { $HiDiff_flag = '';       next arg; };
+    /^-hi-diffs$/             && do { $HiDiff_flag  = 'normal'; next arg; };
+    /^-hi-diffs-with-usages$/ && do { $HiDiff_flag  = 'usages'; next arg; };
+    /^-no-hi-diffs$/          && do { $HiDiff_flag  = '';       next arg; };
+    /^-keep-hi-diffs$/       && do { $Keep_HiDiffs = 1; next arg; };
+
     # show/disable diffs if the interface file changes
 
     /^-E$/         && do { push(@CcBoth_flags, '-E');
     # show/disable diffs if the interface file changes
 
     /^-E$/         && do { push(@CcBoth_flags, '-E');
@@ -2661,13 +2891,6 @@ arg: while($_ = $Args[0]) {
                                $Status++;
                            }
                            next arg; };
                                $Status++;
                            }
                            next arg; };
-    # ToDo: remove, not a `normal' user thing to do (should be automatic)
-    /^-hisuf-prelude$/     && do { $HiSuffix_prelude = &grab_arg_arg(*Args,'-hisuf-prelude', '');
-                           if ($HiSuffix =~ /\./ ) {
-                               print STDERR "$Pgm: -hisuf-prelude suffix shouldn't contain a .\n";
-                               $Status++;
-                           }
-                           next arg; };
     /^-odump$/     && do { $Specific_dump_file = &grab_arg_arg(*Args,'-odump', '');
                            if ($Specific_dump_file =~ /(.*)\/[^\/]*$/) {
                                local($dir_part) = $1;
     /^-odump$/     && do { $Specific_dump_file = &grab_arg_arg(*Args,'-odump', '');
                            if ($Specific_dump_file =~ /(.*)\/[^\/]*$/) {
                                local($dir_part) = $1;
@@ -2711,13 +2934,12 @@ arg: while($_ = $Args[0]) {
                            : '-fauto-sccs-on-exported-toplevs';
                next arg; };
 
                            : '-fauto-sccs-on-exported-toplevs';
                next arg; };
 
-    #--------- ticky/concurrent/parallel -----------------------------------
+    #--------- ticky/parallel ----------------------------------------------
     # we sort out the details a bit later on
 
     # we sort out the details a bit later on
 
-    /^-concurrent$/ && do { $CONCURing = 'c'; next arg; }; # concurrent Haskell
-    /^-gransim$/    && do { $GRANing   = 'g'; next arg; }; # GranSim
+    /^-gransim$/    && do { $GRANing   = 'g'; &add_syslib('concurrent'); next arg; }; # GranSim
     /^-ticky$/     && do { $TICKYing  = 't'; next arg; }; # ticky-ticky
     /^-ticky$/     && do { $TICKYing  = 't'; next arg; }; # ticky-ticky
-    /^-parallel$/   && do { $PARing    = 'p'; next arg; }; # parallel Haskell
+    /^-parallel$/   && do { $PARing    = 'p'; &add_syslib('concurrent'); next arg; }; # parallel Haskell
 
     #-------------- "user ways" --------------------------------------------
 
 
     #-------------- "user ways" --------------------------------------------
 
@@ -2753,27 +2975,7 @@ arg: while($_ = $Args[0]) {
     /^-l(.*)/      && do { push(@UserLibrary,'-l'.&grab_arg_arg(*Args,'-l', $1)); next arg; };
 
     /^-syslib(.*)/  && do { local($syslib) = &grab_arg_arg(*Args,'-syslib',$1);
     /^-l(.*)/      && do { push(@UserLibrary,'-l'.&grab_arg_arg(*Args,'-l', $1)); next arg; };
 
     /^-syslib(.*)/  && do { local($syslib) = &grab_arg_arg(*Args,'-syslib',$1);
-                           print STDERR "$Pgm: no such system library (-syslib): $syslib\n",
-                             $Status++ unless $syslib =~ /^(hbc|ghc|posix|contrib)$/;
-
-                           unshift(@SysImport_dir,
-                               ${INSTALLING}
-                               ? "$InstSysLibDir/$syslib/imports"
-                               : "$TopPwd/hslibs/$syslib/src");
-
-                           if ( ${INSTALLING} ) {
-                               push(@SysLibrary_dir,
-                                       ("$InstSysLibDir"));
-                           } else {
-                               push(@SysLibrary_dir,
-                                       ("$TopPwd/hslibs/$syslib"
-                                       ,"$TopPwd/hslibs/$syslib/cbits"));
-                           }
-
-                           push(@SysLibrary, "-lHS$syslib");
-                           push(@SysLibrary, "-lHS${syslib}_cbits")
-                             unless $syslib eq 'contrib'; #HACK! it has no cbits
-
+                           &add_syslib($syslib);
                            next arg; };
 
     #=======================================================================
                            next arg; };
 
     #=======================================================================
@@ -2797,7 +2999,8 @@ arg: while($_ = $Args[0]) {
     /^-optP(.*)$/   && do { push(@HsCpp_flags,      $1); next arg; };
     /^-optCrts(.*)$/&& do { push(@HsC_rts_flags,    $1); next arg; };
     /^-optC(.*)$/   && do { push(@HsC_flags,        $1); next arg; };
     /^-optP(.*)$/   && do { push(@HsCpp_flags,      $1); next arg; };
     /^-optCrts(.*)$/&& do { push(@HsC_rts_flags,    $1); next arg; };
     /^-optC(.*)$/   && do { push(@HsC_flags,        $1); next arg; };
-    /^-optcpp(.*)$/ && do { push(@Cpp_define,       $1); next arg; };
+    /^-optp(.*)$/   && do { push(@HsP_flags,        $1); next arg; };
+    /^-optcpp(.*)$/ && do { push(@Cpp_define,       $1); $Only_preprocess_hc = ($1 eq "-E"); next arg; };
     /^-optc(.*)$/   && do { push(@CcBoth_flags,     $1); next arg; };
     /^-opta(.*)$/   && do { push(@As_flags,         $1); next arg; };
     /^-optl(.*)$/   && do { push(@Ld_flags,         $1); next arg; };
     /^-optc(.*)$/   && do { push(@CcBoth_flags,     $1); next arg; };
     /^-opta(.*)$/   && do { push(@As_flags,         $1); next arg; };
     /^-optl(.*)$/   && do { push(@Ld_flags,         $1); next arg; };
@@ -2807,10 +3010,6 @@ arg: while($_ = $Args[0]) {
     /^-D(.*)/      && do { push(@HsCpp_flags, "'-D".&grab_arg_arg(*Args,'-D',$1)."'"); next arg; };
     /^-U(.*)/      && do { push(@HsCpp_flags, "'-U".&grab_arg_arg(*Args,'-U',$1)."'"); next arg; };
 
     /^-D(.*)/      && do { push(@HsCpp_flags, "'-D".&grab_arg_arg(*Args,'-D',$1)."'"); next arg; };
     /^-U(.*)/      && do { push(@HsCpp_flags, "'-U".&grab_arg_arg(*Args,'-U',$1)."'"); next arg; };
 
-    /^-genSPECS/   && do { $Cpp_flag_set = 1;
-                          $genSPECS_flag = $_;
-                           next arg; };
-
     #---------- post-Haskell "assembler"------------------------------------
     /^-ddump-raw-asm$/           && do { $Dump_raw_asm        = 1; next arg; };
     /^-ddump-asm-splitting-info$/ && do { $Dump_asm_splitting_info = 1; next arg; };
     #---------- post-Haskell "assembler"------------------------------------
     /^-ddump-raw-asm$/           && do { $Dump_raw_asm        = 1; next arg; };
     /^-ddump-asm-splitting-info$/ && do { $Dump_asm_splitting_info = 1; next arg; };
@@ -2820,32 +3019,24 @@ arg: while($_ = $Args[0]) {
     /^-keep-hc-files?-too$/    && do { $Keep_hc_file_too = 1; next arg; };
     /^-keep-s-files?-too$/     && do { $Keep_s_file_too = 1;  next arg; };
 
     /^-keep-hc-files?-too$/    && do { $Keep_hc_file_too = 1; next arg; };
     /^-keep-s-files?-too$/     && do { $Keep_s_file_too = 1;  next arg; };
 
-    /^-fhaskell-1\.3$/         && do { next arg; }; # a no-op right now
-
     /^-fignore-interface-pragmas$/ && do { push(@HsC_flags, $_); next arg; };
 
     /^-fno-implicit-prelude$/      && do { $NoImplicitPrelude= 1; push(@HsC_flags, $_); next arg; };
     /^-fignore-interface-pragmas$/ && do { push(@HsC_flags, $_); next arg; };
 
     /^-fno-implicit-prelude$/      && do { $NoImplicitPrelude= 1; push(@HsC_flags, $_); next arg; };
-     # don't do stack checking using page fault `trick'.
-     # (esoteric).
-    /^-fstack-check$/             && do { $StkChkByPageFaultOK = 0; next arg; };
+
      #
      # have the compiler proper generate concurrent code,
      # really only used when you want to configure your own
      #
      # have the compiler proper generate concurrent code,
      # really only used when you want to configure your own
-     # special user compilation way. (Use -concurrent when
-     # compiling `Concurrent Haskell' programs).
+     # special user compilation way.
      #
      #
-     # (ditto for -fgransim, fscc-profiling and -fticky-ticky)
+     # (ditto for -fgransim, fscc-profiling, -fparallel and -fticky-ticky)
      #
      #
-    /^-fconcurrent$/      && do { push(@HsC_flags,$_); next arg; };
     /^-fscc-profiling$/   && do { push(@HsC_flags,$_); next arg; };
     /^-fticky-ticky$/     && do { push(@HsC_flags,$_); next arg; };
     /^-fgransim$/        && do { push(@HsC_flags,$_); next arg; };
     /^-fscc-profiling$/   && do { push(@HsC_flags,$_); next arg; };
     /^-fticky-ticky$/     && do { push(@HsC_flags,$_); next arg; };
     /^-fgransim$/        && do { push(@HsC_flags,$_); next arg; };
+    /^-fparallel$/        && do { push(@HsC_flags,$_); next arg; };
 
 
-    /^-user-prelude-force/     && do { # ignore if not -user-prelude
-                                       next arg; };
-
-    /^-split-objs/     && do {
-                       if ( $TargetPlatform !~ /^(alpha|hppa1\.1|i386|m68k|mips|powerpc|sparc)-/ ) {
+    /^-split-objs$/    && do {
+                       if ( $TargetPlatform !~ /^(alpha|hppa1\.1|i386|m68k|mips|powerpc|rs6000|sparc)-/ ) {
                            $SplitObjFiles = 0;
                            print STDERR "WARNING: don't know how to split objects on this platform: $TargetPlatform\n`-split-objs' option ignored\n";
                        } else {
                            $SplitObjFiles = 0;
                            print STDERR "WARNING: don't know how to split objects on this platform: $TargetPlatform\n`-split-objs' option ignored\n";
                        } else {
@@ -2860,18 +3051,17 @@ arg: while($_ = $Args[0]) {
                        }
                        next arg; };
 
                        }
                        next arg; };
 
+    /^-fallow-overlapping-instances$/ && do { push(@HsC_flags, $_); next arg; };
+    /^-fallow-undecidable-instances$/ && do { push(@HsC_flags, $_); next arg; };
     /^-fglasgow-exts$/
                && do { push(@HsC_flags, $_);
                        push(@HsP_flags, '-N');
 
     /^-fglasgow-exts$/
                && do { push(@HsC_flags, $_);
                        push(@HsP_flags, '-N');
 
-#                      push(@HsC_flags, '-fshow-import-specs');
+                       # -fglasgow-exts implies -syslib exts
+                       &add_syslib('exts');
 
                        next arg; };
 
 
                        next arg; };
 
-    /^-fspeciali[sz]e-unboxed$/
-               && do { $Oopt_DoSpecialise      = '-fspecialise';
-                       $Oopt_SpecialiseUnboxed = '-fspecialise-unboxed';
-                       next arg; };
     /^-fspeciali[sz]e$/
                && do { $Oopt_DoSpecialise = '-fspecialise'; next arg; };
     /^-fno-speciali[sz]e$/
     /^-fspeciali[sz]e$/
                && do { $Oopt_DoSpecialise = '-fspecialise'; next arg; };
     /^-fno-speciali[sz]e$/
@@ -2906,19 +3096,21 @@ arg: while($_ = $Args[0]) {
     # --------------- Renamer -------------
 
 
     # --------------- Renamer -------------
 
 
-    /^-fno-tycon-pruning$/ 
-                   && do { push(@HsC_flags, $_); next arg; };
+    /^-fno-prune-tydecls$/     && do { push(@HsC_flags, $_); next arg; };
+    /^-fno-prune-instdecls$/     && do { push(@HsC_flags, $_); next arg; };
 
     # ---------------
 
     /^-fasm-(.*)$/  && do { $HscOut = '-S='; next arg; }; # force using nativeGen
 
     # ---------------
 
     /^-fasm-(.*)$/  && do { $HscOut = '-S='; next arg; }; # force using nativeGen
-    /^-fvia-C$/            && do { $HscOut = '-C='; next arg; }; # force using C compiler
+    /^-fvia-[cC]$/         && do { $HscOut = '-C='; next arg; }; # force using C compiler
 
     # ---------------
 
 
     # ---------------
 
-    /^(-funfolding-use-threshold)(.*)$/
-                   && do { $Oopt_UnfoldingUseThreshold = $1 . &grab_arg_arg(*Args,$1, $2);
-                           next arg; };
+    /^-funfolding-.*$/
+                   && do { push(@HsC_flags, $_); next arg };
+
+    /^-funfold-casms-in-hi-file$/
+                   && do { push(@HsC_flags, $_); next arg };
 
     /^(-fmax-simplifier-iterations)(.*)$/
                    && do { $Oopt_MaxSimplifierIterations = $1 . &grab_arg_arg(*Args,$1, $2);
 
     /^(-fmax-simplifier-iterations)(.*)$/
                    && do { $Oopt_MaxSimplifierIterations = $1 . &grab_arg_arg(*Args,$1, $2);
@@ -2927,35 +3119,35 @@ arg: while($_ = $Args[0]) {
     /^-fno-pedantic-bottoms$/
                    && do { $Oopt_PedanticBottoms = ''; next arg; };
 
     /^-fno-pedantic-bottoms$/
                    && do { $Oopt_PedanticBottoms = ''; next arg; };
 
+    /^-fno-pre-inlining$/
+                   && do { push(@HsC_flags, $_); next arg };
+
     /^-fdo-monad-eta-expansion$/
                    && do { $Oopt_MonadEtaExpansion = $_; next arg; };
 
     /^-fno-let-from-(case|app|strict-let)$/ # experimental, really (WDP 95/10)
                    && do { push(@HsC_flags, $_); next arg; };
 
     /^-fdo-monad-eta-expansion$/
                    && do { $Oopt_MonadEtaExpansion = $_; next arg; };
 
     /^-fno-let-from-(case|app|strict-let)$/ # experimental, really (WDP 95/10)
                    && do { push(@HsC_flags, $_); next arg; };
 
-    /^(-freturn-in-regs-threshold)(.*)$/
-                   && do { local($what) = $1;
-                           local($num)  = &grab_arg_arg(*Args,$what, $2);
-                           if ($num < 2 || $num > 8) {
-                               die "Bad experimental flag: $_\n";
-                           } else {
-                               $HscOut = '-C='; # force using C compiler
-                               push(@HsC_flags, "$what$num");
-                               push(@CcRegd_flags, "-D__STG_REGS_AVAIL__=$num");
-                           }
-                           next arg; };
-
     # --------------- Warnings etc. ------
 
     # --------------- Warnings etc. ------
 
-    /^-f(show-import-specs)/
-                   && do { push(@HsC_flags, $_); next arg; };
+    /^-fwarn-(.*)$/      && do { push(@HsC_flags, $_); next arg; };
 
 
-    # for now, just -fwarn-name-shadowing
-    /^-fwarn-(.*)$/   && do { push(@HsC_flags, $_); next arg; };
     /^-fno-(.*)$/   && do { push(@HsC_antiflags, "-f$1");
                            &squashHscFlag("-f$1");
                            next arg; };
 
     /^-fno-(.*)$/   && do { push(@HsC_antiflags, "-f$1");
                            &squashHscFlag("-f$1");
                            next arg; };
 
+    /^-W$/         && do { push(@HsC_flags, @MinusWOpts); next arg; };
+    /^-Wall$/      && do { push(@HsC_flags, @MinusWallOpts); next arg; };
+    /^(-Wnot|w)$/   && do { foreach (@Hsc_flags) {
+                               /^-fwarn-(.*)$/ && do { $_=''; };
+                           };
+                           push(@HsC_antiflags, @StandardWarnings);
+                           next arg; };
+
+    # --------------- fun stuff ----------------
+
+    /^-freport-compile$/ && do { push(@HsC_flags, $_); next arg; };
+
     # --------------- platform specific flags (for gcc mostly) ----------------
 
     /^-mlong-calls$/ && do { # for GCC for HP-PA boxes,
     # --------------- platform specific flags (for gcc mostly) ----------------
 
     /^-mlong-calls$/ && do { # for GCC for HP-PA boxes,
@@ -2985,6 +3177,7 @@ arg: while($_ = $Args[0]) {
     /^-d(dump|ppr)-/         && do { push(@HsC_flags, $_); next arg; };
     /^-dverbose-(simpl|stg)/ && do { push(@HsC_flags, $_); next arg; };
     /^-dshow-passes/        && do { push(@HsC_flags, $_); next arg; };
     /^-d(dump|ppr)-/         && do { push(@HsC_flags, $_); next arg; };
     /^-dverbose-(simpl|stg)/ && do { push(@HsC_flags, $_); next arg; };
     /^-dshow-passes/        && do { push(@HsC_flags, $_); next arg; };
+    /^-dshow-rn-stats/      && do { push(@HsC_flags, $_); next arg; };
     /^-dshow-rn-trace/      && do { push(@HsC_flags, $_); next arg; };
     /^-dsource-stats/        && do { push(@HsC_flags, $_); next arg; };
     /^-dsimplifier-stats/    && do { push(@HsC_flags, $_); next arg; };
     /^-dshow-rn-trace/      && do { push(@HsC_flags, $_); next arg; };
     /^-dsource-stats/        && do { push(@HsC_flags, $_); next arg; };
     /^-dsimplifier-stats/    && do { push(@HsC_flags, $_); next arg; };
@@ -3017,7 +3210,7 @@ arg: while($_ = $Args[0]) {
        }
        next arg; };
 
        }
        next arg; };
 
-    /^-(K|Rmax-(stk|stack)size)(.*)/ && do {
+    /^(-K|Rmax-(stk|stack)size)(.*)/ && do {
         local($flag) = $1;
        local($stk_size) = &grab_arg_arg(*Args,'-Rmax-stksize', $3);
        if ($stk_size =~ /(\d+)[Kk]$/) {
         local($flag) = $1;
        local($stk_size) = &grab_arg_arg(*Args,'-Rmax-stksize', $3);
        if ($stk_size =~ /(\d+)[Kk]$/) {
@@ -3064,6 +3257,7 @@ arg: while($_ = $Args[0]) {
     #---------- Linker (gcc, really) ---------------------------------------
 
     /^-static$/                && do { push(@Ld_flags, $_); next arg; };
     #---------- Linker (gcc, really) ---------------------------------------
 
     /^-static$/                && do { push(@Ld_flags, $_); next arg; };
+    /^-no-hs-main$/    && do { $NoHaskellMain=1; next arg;    };
 
     #---------- mixed cc and linker magic ----------------------------------
     # this optimisation stuff is finally sorted out later on...
 
     #---------- mixed cc and linker magic ----------------------------------
     # this optimisation stuff is finally sorted out later on...