[project @ 1999-07-14 11:16:43 by simonmar]
[ghc-hetmet.git] / ghc / driver / ghc.lprl
index b499b8a..9886de5 100644 (file)
@@ -1,4 +1,3 @@
-%
 % (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:
+    -E         stop after generating preprocessed, de-litted Haskell (used in conjunction with -cpp)
     -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)
 
@@ -64,9 +63,9 @@ Other commonly-used options are:
 
     -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.
 
@@ -99,11 +98,13 @@ INSTALLING
 
 HOSTPLATFORM TARGETPLATFORM
 
-PROJECTNAME PROJECTVERSION PROJECTPATCHLEVEL
+ProjectName ProjectVersion ProjectVersionInt ProjectPatchLevel 
+
+HscMajorVersion HscMinorVersion CcMajorVersion CcMinorVersion
 
 TOP_PWD
 
-bindir libdir datadir
+bindir libdir libexecdir datadir
 
 CURRENT_DIR TMPDIR
 
@@ -115,10 +116,12 @@ GHC_UNLIT GHC_HSCPP GHC_HSC GHC_SYSMAN
 
 CP RM CONTEXT_DIFF
 
-WAY_*_NAME WAY_*_HC_OPTS
+WAY_*_NAME WAY_*_REAL_OPTS
 
 LeadingUnderscore
 
+GhcWithRegisterised
+
 \end{verbatim}
 
 Establish what executables to run for the various phases, what the
@@ -132,10 +135,12 @@ $TargetPlatform = $TARGETPLATFORM;
 $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}";
-$InstSysLibDir     = ( $INSTALLING ) ? "${InstLibDirGhc}/hslibs" : 
-                       "$TopPwd/hslibs";
 
 $Status  = 0; # just used for exit() status
 $Verbose = '';
@@ -158,9 +163,26 @@ if ( $ENV{'TMPDIR'} ) { # where to make tmp file names
     $ENV{'TMPDIR'} = ${TMPDIR}; # set the env var as well
 }
 
+# Some shells run into real trouble when command line and environment
+# gets big (e.g., cmd lines of >4K to /bin/sh causes havoc on our 
+# Solaris-2.5.1 boxes - even though sysconf(_SC_ARG_MAX) reports 1M ...).
+# To work around any such */bin/sh* problems, we will scribble such
+# awfully long command lines into a temp file and exec that temp file
+# with $(REAL_SHELL) (don't use the SHELL variable directly as this
+# will normally get you the wrong thing when the driver is invoked
+# from within `make'). If the REAL_SHELL variable isn't set, you'll
+# get SHELL. This is all a terrible hack. (in case you hadn't reached
+# the same conclusion by now :-)
+#
+# TBC..
+#
+if ( ! $ENV{'REAL_SHELL'} ) {
+    $ENV{'REAL_SHELL'} = $ENV{'SHELL'};
+}
+
 @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;
@@ -171,16 +193,15 @@ $Cmp  = 'cmp';
 $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   = ();
-$genSPECS_flag = '';           # See ../utils/hscpp/hscpp.prl
-$HsC    = ( $INSTALLING ) ? "$InstLibexecDirGhc/hsc"
+$HsC    = ( $INSTALLING ) ? "$InstLibExecDirGhc/hsc"
                           : "$TopPwd/${CURRENT_DIR}/${GHC_HSC}";
 
 # For PVM fiends only
-$SysMan         = ( $INSTALLING ) ? "$InstLibexecDirGhc/SysMan"
+$SysMan         = ( $INSTALLING ) ? "$InstLibExecDirGhc/SysMan"
                           : "$TopPwd/${CURRENT_DIR}/${GHC_SYSMAN}";
 
 @Unlit_flags   = ();
@@ -202,18 +223,13 @@ These are the default values, which may be changed by user flags.
 
 \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_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_UsageSPInf               = ''; # Off by default
 } # end of setupOptFlags
 
 # Assign defaults to these right away.
@@ -221,9 +237,13 @@ sub setupOptFlags {
 \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;
-@CcBoth_flags  = ('-S');   # flags for *any* C compilation
+@CcBoth_flags  = ('-S','-Wimplicit');   # flags for *any* C compilation
 @CcInjects     = ();
 
 # GCC flags: 
@@ -231,40 +251,60 @@ $CcRegd           = $GHC_OPT_HILEV_ASM;
 #    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 = ();
 
-$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       = ();
+@Dll_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}
 
+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-unused-binds',
+                    '-fwarn-unused-matches',
+                    '-fwarn-incomplete-patterns', 
+                    '-fwarn-unused-imports');
+@MinusWallOpts           = (@MinusWOpts, 
+                    '-fwarn-type-defaults',
+                    '-fwarn-name-shadowing',
+                    '-fwarn-missing-signatures');
+\end{code}
+
 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}
 $BuildTag      = ''; # default is sequential build w/ Appel-style GC
 
 %BuildDescr    = (# system ways begin
-                   '',     'normal sequential',
-                  '_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",
-                  '_2s',   "$WAY_2s_NAME",
-                  '_1s',   "$WAY_1s_NAME",
-                  '_du',   "$WAY_du_NAME",
+                   '',     'Normal Sequential',
+                  '_p',    "Profiling",
+                  '_t',    "Ticky-ticky Profiling",
+                  '_u',    "Unregisterised",
+                  '_mp',   "Parallel",
+                  '_mg',   "Gransim",
                   # system ways end
                   '_a',    "$WAY_a_NAME",
                   '_b',    "$WAY_b_NAME",
@@ -288,153 +328,72 @@ $BuildTag        = ''; # default is sequential build w/ Appel-style GC
 #
 %SetupOpts = 
        (
-       '_a', "$WAY_a_HC_OPTS",
-       '_b', "$WAY_b_HC_OPTS",
-       '_c', "$WAY_c_HC_OPTS",
-       '_d', "$WAY_d_HC_OPTS",
-       '_e', "$WAY_e_HC_OPTS",
-       '_f', "$WAY_f_HC_OPTS",
-       '_g', "$WAY_g_HC_OPTS",
-       '_h', "$WAY_h_HC_OPTS",
-       '_i', "$WAY_i_HC_OPTS",
-       '_j', "$WAY_j_HC_OPTS",
-       '_k', "$WAY_k_HC_OPTS",
-       '_l', "$WAY_l_HC_OPTS",
-       '_m', "$WAY_m_HC_OPTS",
-       '_n', "$WAY_n_HC_OPTS",
-       '_o', "$WAY_o_HC_OPTS",
-       '_A', "$WAY_A_HC_OPTS",
-       '_B', "$WAY_B_HC_OPTS",
+       '_a', "$WAY_a_REAL_OPTS",
+       '_b', "$WAY_b_REAL_OPTS",
+       '_c', "$WAY_c_REAL_OPTS",
+       '_d', "$WAY_d_REAL_OPTS",
+       '_e', "$WAY_e_REAL_OPTS",
+       '_f', "$WAY_f_REAL_OPTS",
+       '_g', "$WAY_g_REAL_OPTS",
+       '_h', "$WAY_h_REAL_OPTS",
+       '_i', "$WAY_i_REAL_OPTS",
+       '_j', "$WAY_j_REAL_OPTS",
+       '_k', "$WAY_k_REAL_OPTS",
+       '_l', "$WAY_l_REAL_OPTS",
+       '_m', "$WAY_m_REAL_OPTS",
+       '_n', "$WAY_n_REAL_OPTS",
+       '_o', "$WAY_o_REAL_OPTS",
+       '_A', "$WAY_A_REAL_OPTS",
+       '_B', "$WAY_B_REAL_OPTS",
 
        # system ways
-       '_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",
-       '_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',    '' );
-
-\end{code}
-
-Import/include directories (\tr{-I} options) are sufficiently weird to
-require special handling.
-
-\begin{code}
-@Import_dir    = ('.'); #-i things
-@Include_dir   = ('.'); #-I things; other default(s) stuck on AFTER option processing
+       '_p',  "-fscc-profiling -DPROFILING -optc-DPROFILING",
+       '_t',  "-fticky-ticky -DTICKY_TICKY -optc-DTICKY_TICKY",
+       '_u',  "-optc-DNO_REGS -optc-DUSE_MINIINTERPRETER -fno-asm-mangling -funregisterised",
+       '_mp', "-fstack-check -fparallel -D__PARALLEL_HASKELL__ -optc-DPAR",
+       '_mg', "-fstack-check -fconcurrent -fgransim -D__GRANSIM__ -D__CONCURRENT_HASKELL__ -optc-DCONCURRENT -optc-DGRAN");
 
-# 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 )
-                   ? ( "$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.
 
-$GhcVersionInfo  = int ($PROJECTVERSION * 100);
-$Haskell1Version = 4; # i.e., Haskell 1.4
+$Haskell1Version = 5; # i.e., Haskell 1.4
 @Cpp_define     = ();
 
-@UserLibrary_dir= ();  #-L things;...
-@UserLibrary           = ();   #-l things asked for by the user
+# Cpp symbols defined when we're processing Haskell source.
+
+@HsSourceCppOpts = 
+       ( "-D__HASKELL1__=$Haskell1Version"
+       , "-D__GLASGOW_HASKELL__=$ProjectVersionInt"
+       , "-D__HASKELL98__"
+       , "-D__CONCURRENT_HASKELL__"
+       );
+
 
 @SysLibrary_dir = ( ( $INSTALLING )    #-syslib things supplied by the system
                    ? $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
-       = ( $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"
+       = ( $INSTALLING ) ? "$InstLibExecDirGhc/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;
@@ -451,8 +410,6 @@ sub initDriverGlobals {
 # reset the following options:
 # RTS flags to use while compiling
 @HsC_rts_flags      = ();
-@HsP_flags     = (); # these are the flags destined solely for
-                     # the flex/yacc parser
 @HsC_flags     = ();
 @HsC_antiflags  = ();
 \end{code}
@@ -465,20 +422,16 @@ $OptLevel      = 0; # no -O == 0; -O == 1; -O2 == 2; -Ofile == 3
 $MinusO2ForC   = 0; # set to 1 if -O2 should be given to C compiler
 $StolenX86Regs = 4; # **HACK*** of the very worst sort
 $CoreLint      = '';
+$USPLint       = '';
 $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
 
+@UserLibrary_dir= ();  #-L things;...
+@UserLibrary           = ();   #-l things asked for by the user
 
+@SysLibrary = (); # will be built up as we go along
 \end{code}
 
 We are given a list of files with various presumably-known suffixes
@@ -492,18 +445,27 @@ Here are the initial defaults applied to all files:
 \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;  # ""
+$Only_generate_dll  = 0;
 $PostprocessCcOutput = 0;
 
+# Win32 only:
+#    static = 0 => produce code for DLLs (when compiling & linking.)
+$Static = 1;
+$Static = 0 if ($EnableWin32DLLs eq 'YES');
+
 # 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 ne 'YES') && $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;
@@ -512,13 +474,13 @@ $PROFing = '';            # set to p or e if profiling
 $PROFgroup = '';       # set to group if an explicit -Ggroup specified
 $PROFauto = '';                # set to relevant hsc flag if -auto or -auto-all
 $PROFcaf  = '';                # set to relevant hsc flag if -caf-all
+$PROFdict = '';                # set to relevant hsc flag if -auto-dicts
 $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
-$CONCURing = '';       # set to c if compiling for CONCURRENT
 $GRANing = '';         # set to g if compiling for GRAN
-$StkChkByPageFaultOK = 1; # may be set to 0 (false) for some builds
+$UNREGing = ($GhcWithRegisterised eq 'YES') ? '' : 'u';
 $Specific_hi_file = '';                # set by -ohi <file>; "-" for stdout
 $Specific_dump_file = '';      # set by -odump <file>; "-" for stdout
 $Using_dump_file = 0;
@@ -526,6 +488,7 @@ $Isuffix    = '';
 $Osuffix    = '';      # default: use the normal suffix for that kind of output
 $HiSuffix   = 'hi';
 $HiSuffix_prelude = '';
+$CompilingPrelude=0;
 $Do_recomp_chkr = 0;   # don't use the recompilatio checker unless asked
 $Do_cc     = -1;   # a MAGIC indeterminate value; will be set to 1 or 0.
 $Do_as     = 1;
@@ -534,12 +497,15 @@ $Keep_hc_file_too = 0;
 $Keep_s_file_too = 0;
 $UseGhcInternals = 0; # if 1, may use GHC* modules
 $SplitObjFiles = 0;
+$DoAsmMangling = 1; # on by default, off by -fno-asm-mangling
 $NoOfSplitFiles = 0;
 $Dump_parser_output = 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)
 
@@ -554,6 +520,9 @@ $NoImplicitPrelude = 0;
 # and whatever else
 @Cmd_opts  = ();
 
+# cmd line options prefixing the unit we're compiling
+@File_options = ();
+
 \end{code}
 
 We inject consistency-checking information into \tr{.hc} files (both
@@ -564,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}
-$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.
-$HsC_major_version = 31;
-$HsC_minor_version = 0;
-$Cc_major_version  = 36;
-$Cc_minor_version  = 0;
+$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:
@@ -589,37 +558,6 @@ $Cc_consist_options  = '';    # we record, in this order:
 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.
@@ -631,11 +569,22 @@ if (  $Status == 0 && $Only_generate_deps ) {
 
     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;
 }
 
+# ..or just to construct a (Haskell) DLL.
+if (  $Status == 0 && $Only_generate_dll && $EnableWin32DLLs ) {
+
+    &createWin32DLL();
+    exit $Status;
+}
+
 # if there are several input files,
 # we don't allow \tr{-o <file>} or \tr{-ohi <file>} options...
 # (except if linking, of course)
@@ -733,161 +682,104 @@ It really really wants to be the last STG-to-STG pass that is run.
 
 sub setupOptimiseFlags {
 
+       # this pass-ordering sequence was agreed by Simon and Andr\'e
+       # (WDP 94/07, 94/11).
+
    @HsC_minusNoO_flags 
-    = (        '-fsimplify',
-         '\(',
-         $Oopt_FB_Support,
-#        '-falways-float-lets-from-lets',      # no idea why this was here (WDP 95/09)
-         '-ffloat-lets-exposing-whnf',
-         '-ffloat-primops-ok',
-         '-fcase-of-case',
-#        '-fdo-lambda-eta-expansion',  # too complicated
-         '-freuse-con',
-#        '-flet-to-case',      # no strictness analysis, so...
-         $Oopt_PedanticBottoms,
-#        $Oopt_MonadEtaExpansion,      # no thanks
-         '-fsimpl-uf-use-threshold0',
-         '-fessential-unfoldings-only',
-#        $Oopt_UnfoldingUseThreshold,  # no thanks
-         $Oopt_MaxSimplifierIterations,
-         '\)',
+    = (        
+       '-fsimplify',
+         '[', 
+               '-finline-phase2',
+               $Oopt_MaxSimplifierIterations,
+         ']',
+
        $Oopt_AddAutoSccs,
-#      '-ffull-laziness',      # removed 95/04 WDP following Andr\'e's lead
-       
        $Oopt_FinalStgProfilingMassage
       );
 
    @HsC_minusO_flags # NOTE: used for *both* -O and -O2 (some conditional bits)
     = (
+       '-ffoldr-build-on',
+
         '-fdo-eta-reduction',
+       '-fdo-lambda-eta-expansion',
+       '-fcase-of-case',
+       '-fcase-merge',
+       '-flet-to-case',
+       $Oopt_PedanticBottoms,
 
        # initial simplify: mk specialiser happy: minimum effort please
-       '-fsimplify',
-         '\(', 
-         $Oopt_FB_Support,
-         '-fkeep-spec-pragma-ids',     # required before specialisation
-         '-fsimpl-uf-use-threshold0',
-         '-fessential-unfoldings-only',
-         '-fmax-simplifier-iterations1',
-         $Oopt_PedanticBottoms,
-         '\)',
-
-       ($Oopt_DoSpecialise) ? (
-         '-fspecialise-overloaded',
-         $Oopt_SpecialiseUnboxed,
-         $Oopt_DoSpecialise,
-       ) : (),
 
-       '-fsimplify',                   # need dependency anal after specialiser ...
-         '\(',                         # need tossing before calc-inlinings ...
-         $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',
-         $Oopt_PedanticBottoms,
-         $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
-         $Oopt_MaxSimplifierIterations,
-         '\)',
-
-#LATER:        '-fcalc-inlinings1', -- pointless for 2.01
-
-#      ($Oopt_FoldrBuildWW) ? (
-#              '-ffoldr-build-ww-anal',
-#              '-ffoldr-build-worker-wrapper',
-#              '-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',
-#                $Oopt_PedanticBottoms,
-#                $Oopt_MonadEtaExpansion,
-#                $Oopt_UnfoldingUseThreshold,
-#                $Oopt_MaxSimplifierIterations,
-#                '\)',
-#       ) : (),
-
-       # this pass-ordering sequence was agreed by Simon and Andr\'e
-       # (WDP 94/07, 94/11).
+       '-fsimplify',
+         '[', 
+               '-finline-phase0',      # Don't inline anything till full laziness has bitten
+                                       # In particular, inlining wrappers inhibits floating
+                                       # e.g. ...(case f x of ...)...
+                                       #  ==> ...(case (case x of I# x# -> fw x#) of ...)...
+                                       #  ==> ...(case x of I# x# -> case fw x# of ...)...
+                                       # and now the redex (f x) isn't floatable any more
+               '-fmax-simplifier-iterations2',
+         ']',
+
+       # Specialisation is best done before full laziness
+       # so that overloaded functions have all their dictionary lambdas manifest
+       ($Oopt_DoSpecialise) ? ( $Oopt_DoSpecialise, ) : (),
        '-ffull-laziness',
+       '-ffloat-inwards',
 
-       ($Oopt_FoldrBuild) ? (
-         '-ffoldr-build-on',           # desugar list comprehensions for foldr/build
-
-         '-fsimplify', 
-           '\(', 
-           '-fignore-inline-pragma',   # **** NB!
-           '-fdo-foldr-build',         # NB
-           $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',        # After full laziness
-           '-freuse-con',
-           $Oopt_PedanticBottoms,
-           $Oopt_MonadEtaExpansion,
-           $Oopt_UnfoldingUseThreshold,
-           $Oopt_MaxSimplifierIterations,
-           '\)',
-       ) : (),
+#      '-fsimplify',
+#        '[', 
+#              # Run the simplifier before specialising, so that overloaded functions
+#              # look like             f = \d -> ...
+#              # (Full laziness may lift out something hiding the \d
+#              '-finline-phase1',
+#              '-fmax-simplifier-iterations1',
+#        ']',
 
-       '-ffloat-inwards',
 
        '-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',
-         ($Oopt_FoldrBuildInline),
-                       # you need to inline foldr and build
-         ($Oopt_FoldrBuild) ? ('-fdo-foldr-build') : (), 
-                       # but do reductions if you see them!
-         $Oopt_PedanticBottoms,
-         $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
-         $Oopt_MaxSimplifierIterations,
-         '\)',
+         '[', 
+               '-finline-phase1',
+               # Want to run with inline phase 1 after the specialiser to give
+               # maximum chance for fusion to work before we inline build/augment
+               # in phase 2.  This made a difference in 'ansi' where an overloaded
+               # function wasn't inlined till too late.
+               $Oopt_MaxSimplifierIterations,  
+         ']',
+
+        $Oopt_UsageSPInf, # infer usage information here in case we need it later.
+                          # (add more of these where you need them --KSW 1999-04)
+
+       '-fsimplify',
+         '[', 
+               # Need inline-phase2 here so that build/augment get 
+               # inlined.  I found that spectral/hartel/genfft lost some useful
+               # strictness in the function sumcode' if augment is not inlined
+               # before strictness analysis runs
+
+               '-finline-phase2',
+               $Oopt_MaxSimplifierIterations,  
+         ']',
+
 
        '-fstrictness',
+       '-fcpr-analyse',
+       '-fworker-wrapper',
 
        '-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',              # Aha! Only done after strictness analysis
-         $Oopt_PedanticBottoms,
-         $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
-         $Oopt_MaxSimplifierIterations,
-         '\)',
-
+         '[', 
+               $Oopt_MaxSimplifierIterations,  
+               # No -finline-phase: allow all Ids to be inlined now
+         ']',
+
+       '-fcse',        # CSE must immediately follow a simplification pass, because it relies
+                       # on the no-shadowing invariant.  See comments at the top of CSE.lhs
+                
+       '-ffull-laziness',      # nofib/spectral/hartel/wang doubles in speed if you
+                               # do full laziness late in the day.  It only happens
+                               # after fusion and other stuff, so the early pass doesn't
+                               # catch it.  For the record, the redex is 
+                               #       f_el22 (f_el21 r_midblock)
        '-ffloat-inwards',
 
 # Case-liberation for -O2.  This should be after
@@ -895,39 +787,20 @@ sub setupOptimiseFlags {
 
 #      ( ($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-lambda-eta-expansion -freuse-con -flet-to-case $Oopt_PedanticBottoms $Oopt_MaxSimplifierIterations $Oopt_ShowSimplifierProgress ]" ),
 
 # Final clean-up simplification:
 
        '-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',
-         '-fignore-inline-pragma',     # **** NB!
-         $Oopt_FoldrBuildInline,       
-         ($Oopt_FoldrBuild) ? ('-fdo-foldr-build') : (), 
-                       # but still do reductions if you see them!
-         $Oopt_PedanticBottoms,
-         $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
-         $Oopt_MaxSimplifierIterations,
-         '\)',
+         '[', 
+               $Oopt_MaxSimplifierIterations,  
+               # No -finline-phase: allow all Ids to be inlined now
+         ']',
 
       #        '-fstatic-args',
 
-#LATER:        '-fcalc-inlinings2', -- pointless for 2.01
-
       # stg2stg passes
-       '-fupdate-analysis',
-       '-flambda-lift',
+#      '-flambda-lift',
        $Oopt_FinalStgProfilingMassage,
        $Oopt_StgStats,
 
@@ -936,6 +809,7 @@ sub setupOptimiseFlags {
 
       # SPECIAL FLAGS for -O2
        ($OptLevel == 2) ? (
+         '-fupdate-analysis',  # virtually useless; relegated to -O2
          '-fsemi-tagging',
        ) : (),
       );
@@ -960,12 +834,13 @@ if ( $OptLevel <= 0 ) {
     &add_Hsc_flags( @HsC_minusO_flags );
     push(@CcBoth_flags, ($MinusO2ForC || $OptLevel == 2) ? '-O2' : '-O'); # not optional!
     # -O? to GCC is not optional! -O2 probably isn't worth it generally,
-    # but it *is* useful in compiling the garbage collectors (so said
-    # Patrick many moons ago...).
+    # but it *is* useful in compiling the garbage collector.
 
 } 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...
 }
 
@@ -979,40 +854,29 @@ if ( $OptLevel <= 0 ) {
 %*                                                                     *
 %************************************************************************
 
-Sort out @$BuildTag@, @$PROFing@, @$CONCURing@, @$PARing@,
-@$GRANing@, @$TICKYing@:
+Sort out @$BuildTag@, @$PROFing@, @$PARing@,
+@$GRANing@, @$TICKYing@, @UNREGing@:
 \begin{code}
 sub setupBuildFlags {
 
 
    # PROFILING stuff after argv mangling:
    if ( ! $PROFing ) {
-     # warn about any scc exprs found (in case scc used as identifier)
-     push(@HsP_flags, '-W');
-
      # add -auto sccs even if not profiling !
      push(@HsC_flags, $UNPROFscc_auto) if $UNPROFscc_auto;
 
    } else {
       push(@HsC_flags, $PROFauto) if $PROFauto;
       push(@HsC_flags, $PROFcaf)  if $PROFcaf;
-      #push(@HsC_flags, $PROFdict) if $PROFdict;
+      push(@HsC_flags, $PROFdict) if $PROFdict;
 
       $Oopt_FinalStgProfilingMassage = '-fmassage-stg-for-profiling';
 
-      push(@HsP_flags, (($PROFignore_scc) ? $PROFignore_scc : '-S'));
-
-      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++;
-      }
+      # Ignore user sccs when auto annotating, but warn when doing so.
+      $PROFignore_scc = '-W' if $PROFauto; 
   }
   #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; }
@@ -1025,13 +889,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; }
-      $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; }
@@ -1049,8 +907,12 @@ sub setupBuildFlags {
 
   } elsif ( $TICKYing eq 't' ) {
       $BuildTag = '_t';
-  }
 
+  } elsif ( $UNREGing eq 'u' ) {
+      if ($GhcWithRegisterised eq 'YES') {
+        $BuildTag = '_u';
+      }
+  }
 \end{code}
 
 After the sanity checks, add flags to the necessary parts of the driver pipeline:
@@ -1077,14 +939,17 @@ Decide what the consistency-checking options are in force for this run:
   # Funny place to put it, but why not.
   #
   if ( $HiSuffix_prelude eq '' ) {
-       local($Tag) = "${BuildTag}";
-       $Tag =~ s/_//;
-       $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}");
 
+       if ($CompilingPrelude) {
+         $HiSuffix_prelude = "$HiSuffix" if $CompilingPrelude;
+       } else {
+         local($Tag) = "${BuildTag}";
+  
+         $Tag =~ s/_//;
+         $Tag =  "${Tag}_" if $Tag ne '';
+         $HiSuffix_prelude="${Tag}hi";
+       }
+  }
 } # setupBuildFlags
 \end{code}
 
@@ -1104,14 +969,9 @@ Note: a few ``always apply'' flags were set at the very beginning.
 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/) {
-      # 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
@@ -1126,35 +986,18 @@ sub setupMachOpts {
         # (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
-      #         the fp (%ebp) for our register maps.  *All* register
-      #         maps (in MachRegs.lh) must steal it.
+      # -fomit-frame-pointer : *must* in .hc files; because we're stealing
+      #         the fp (%ebp) for our register maps.
 
       unshift(@CcRegd_flags_hc, '-fno-defer-pop');
-      unshift(@CcRegd_flags,    '-fomit-frame-pointer');
+      unshift(@CcRegd_flags_hc, '-fomit-frame-pointer');
       unshift(@CcRegd_flags,    "-DSTOLEN_X86_REGS=$StolenX86Regs");
+      
+      unshift(@CcBoth_flags,  ('-DDONT_WANT_WIN32_DLL_SUPPORT')) if ($Static);
 
   } 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!
@@ -1171,27 +1014,33 @@ sub setupMachOpts {
        # 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'));
 
-  } 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
-
   } 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}
 
+%************************************************************************
+%*                                                                     *
+\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
@@ -1204,19 +1053,44 @@ sub setupLinkOpts {
   local($uscore) = ( ${LeadingUnderscore} eq 'YES' ) ? '_' : '';
 
   unshift(@Ld_flags,
-        (($Ld_main) ? (
-          '-u', "${uscore}Main_" . $Ld_main . '_closure',
-        ) : ()
-# What are these? -- SOF
-#         , '-u', "${uscore}STbase_unsafePerformPrimIO_fast1"
-#         , '-u', "${uscore}Prelude_Z91Z93_closure"     # i.e., []
-#         , '-u', "${uscore}Prelude_IZh_static_info"
-#         , '-u', "${uscore}Prelude_False_inregs_info"
-#         , '-u', "${uscore}Prelude_True_inregs_info"
-#         , '-u', "${uscore}Prelude_CZh_static_info"
-#         , '-u', "${uscore}DEBUG_REGS"
-       ))
-         ; # just for fun, now...
+        (($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,
+         ( '-u', "${uscore}PrelBase_Izh_static_info"
+          ,'-u', "${uscore}PrelBase_Czh_static_info"
+          ,'-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}PrelStable_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}PrelStable_StablePtr_con_info"
+          ,'-u', "${uscore}PrelBase_False_static_closure"
+          ,'-u', "${uscore}PrelBase_True_static_closure"
+          ,'-u', "${uscore}PrelPack_unpackCString_closure"
+          ,'-u', "${uscore}PrelException_stackOverflow_closure"
+          ,'-u', "${uscore}PrelException_heapOverflow_closure"
+          ,'-u', "${uscore}PrelException_NonTermination_static_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
 
@@ -1254,23 +1128,23 @@ sub setupSyslibs {
       $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(@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.
   #
-  push(@SysLibrary, '-lwinmm') if $BuildTag ne '' && $TargetPlatform eq 'i386-unknown-cygwin32';
+  push(@SysLibrary, '-lwinmm')   if $TargetPlatform eq 'i386-unknown-cygwin32';
+   # Note: currently only tested with mingw, may cause conflicts when linking
+   #       with libcygwin.a
+  push(@SysLibrary, '-lwsock32') if ($TargetPlatform =~ /-(mingw32|cygwin32)$/);
 
   # 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' ) {
@@ -1279,8 +1153,17 @@ sub setupSyslibs {
   }
 
 # Push the GNU multi-precision arith lib; and the math library
-push(@SysLibrary, '-lgmp');
-push(@SysLibrary, '-lm');
+
+# 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') if !( $TargetPlatform =~ /^.*(cygwin32|mingw32)$/ );
 \end{code}
 
 %************************************************************************
@@ -1331,8 +1214,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");
-    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");
 }
 
@@ -1340,7 +1223,7 @@ if ($#Input_file < 0 && $#Link_file < 0) {
 
 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}
 
@@ -1357,129 +1240,15 @@ foreach $ifile (@Input_file) {
     &ProcessInputFile($ifile);
 }
 
-if ( $Status > 0 ) { # don't link if there were errors...
+# don't link if there were errors...
+if ( $Status > 0 ) { 
     print STDERR $ShortUsage;
     &tidy_up();
     exit $Status;
 }
 
-# append last minute flags linker and consistency flags
-&setupBuildFlags();
-&setupSyslibs();
-&setupLinkOpts();
-
-\end{code}
-
-Link if appropriate.
-\begin{code}
-if ($Do_lnkr) {
-    local($libdirs) = '';
-
-    # glue them together:
-    push(@UserLibrary_dir, @SysLibrary_dir);
-
-    $libdirs = '-L' . join(' -L',@UserLibrary_dir) if $#UserLibrary_dir >= 0;
-
-    # for a linker, use an explicitly given one, or the going C compiler ...
-    local($lnkr) = ( $Lnkr ) ? $Lnkr : $CcRegd;
-
-    local($output) = ($Specific_output_file ne '') ? "-o $Specific_output_file" : '';
-    @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');
-
-    # finally, check the consistency info in the binary
-    local($executable) = $Files_to_tidy[0];
-    @Files_to_tidy = (); # reset; we don't want to nuke it if it's inconsistent
-
-    if ( $LinkChk ) {
-       # dynamically load consistency-chking code; then do it.
-       require('ghc-consist.prl')
-           || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-consist.prl!\n");
-
-       &chk_consistency_info ( $executable );
-    }
-
-    # if PVM parallel stuff, we do truly weird things.
-    # Essentially: (1) move the executable over to where PVM expects
-    # to find it.  (2) create a script in place of the executable
-    # which will cause the program to be run, via SysMan.
-    if ( $PARing eq 'p' ) {
-       local($pvm_executable) = $executable;
-       local($pvm_executable_base);
-
-       if ( $pvm_executable !~ /^\// ) { # a relative path name: make absolute
-           local($pwd) = `pwd`;
-           chop($pwd);
-           $pwd =~ s/^\/tmp_mnt//;
-           $pvm_executable = "$pwd/$pvm_executable";
-       }
-
-       $pvm_executable =~ s|/|=|g; # make /s into =s
-       $pvm_executable_base = $pvm_executable;
-
-       $pvm_executable = $ENV{'PVM_ROOT'} . '/bin/' . $ENV{'PVM_ARCH'}
-                       . "/$pvm_executable";
-
-       &run_something("$Rm -f $pvm_executable; $Cp -p $executable $pvm_executable && $Rm -f $executable", 'Moving binary to PVM land');
-
-       # OK, now create the magic script for "$executable"
-       open(EXEC, "> $executable") || &tidy_up_and_die(1,"$Pgm: couldn't open $executable to write!\n");
-       print EXEC <<EOSCRIPT1;
-eval 'exec perl -S \$0 \${1+"\$@"}'
-  if \$running_under_some_shell;
-# =!=!=!=!=!=!=!=!=!=!=!
-# This script is automatically generated: DO NOT EDIT!!!
-# Generated by Glasgow Haskell, version ${PROJECTVERSION} ${PROJECTPATCHLEVEL}
-#
-\$pvm_executable      = '$pvm_executable';
-\$pvm_executable_base = '$pvm_executable_base';
-\$SysMan = '$SysMan';
-EOSCRIPT1
-
-       print EXEC <<\EOSCRIPT2;
-# first, some magical shortcuts to run "commands" on the binary
-# (which is hidden)
-if ($#ARGV == 1 && $ARGV[0] eq '+RTS' && $ARGV[1] =~ /^--((size|file|strip|rm|nm).*)/ ) {
-    local($cmd) = $1;
-    system("$cmd $pvm_executable");
-    exit(0); # all done
-}
-
-# OK, really run it; process the args first
-$ENV{'PE'} = $pvm_executable_base;
-$debug = '';
-$nprocessors = 2; # the default
-@nonPVM_args = ();
-$in_RTS_args = 0;
-
-# ToDo: handle --RTS
-args: while ($a = shift(@ARGV)) {
-    if ( $a eq '+RTS' ) {
-       $in_RTS_args = 1;
-    } elsif ( $a eq '-RTS' ) {
-       $in_RTS_args = 0;
-    }
-    if ( $a eq '-d' && $in_RTS_args ) {
-       $debug = '-';
-    } elsif ( $a =~ /^-N(\d+)/ && $in_RTS_args ) {
-       $nprocessors = $1;
-    } else {
-       push(@nonPVM_args, $a);
-    }
-}
-
-local($return_val) = 0;
-system("$SysMan $debug $pvm_executable $nprocessors @nonPVM_args");
-$return_val = $?;
-system("mv $ENV{'HOME'}/$pvm_executable_base.???.gr .") if -f "$ENV{'HOME'}/$pvm_executable_base.001.gr";
-exit($return_val);
-EOSCRIPT2
-       close(EXEC) || die "Failed closing $executable\n";
-       chmod 0755, $executable;
-    }
-}
+# Link if appropriate.
+&runLinker() if $Do_lnkr;
 
 # that...  that's all, folks!
 &tidy_up();
@@ -1500,6 +1269,8 @@ sub ProcessInputFile {
                          # 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.
@@ -1514,6 +1285,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 (??)
+       ($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';
@@ -1552,26 +1325,32 @@ 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
 
-    $lit2pgm_hscpp = $ifile if ($ifile =~ /\.hs$/);
+    # OK, let's strip off some literate junk..
+    if ($do_lit2pgm) {
+        &runLit2pgm($in_lit2pgm, $lit2pgm_hscpp)
+    } else {
+        $lit2pgm_hscpp = $ifile;
+    }
 
-    # OK, let's strip off some literate junk:
-    &runLit2pgm($in_lit2pgm, $lit2pgm_hscpp) if ($ifile =~ /\.lhs$/);
     #
     @File_options = ();
 
     # Scan the top of the de-litted file for {-# OPTIONS #-} pragmas
-    &check_for_source_options($lit2pgm_hscpp);
-    # options found in the source file take a back seat, i.e., we scan
+    &check_for_source_options($lit2pgm_hscpp,$ifile);
+
+    # 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).
     #
     if ( $#Input_file >= 0 || $#File_options >= 0) {
-        @File_options = (@File_options, @Cmd_opts);
+        #@File_options = (@File_options, @Cmd_opts);
 
         # Now process the command line
         &initDriverGlobals();
-        &processArgs(@File_options);
+        &processArgs((@File_options,@Cmd_opts));
+       print STDERR "\nEffective command line: " .
+                    join(' ',(@File_options,@Cmd_opts)) . "\n" if $Verbose;
     }
     #
     # Having got the effective command line scanned, set up
@@ -1585,6 +1364,7 @@ Again, we'll do the post-recompilation-checker parts of this later.
     &setupOptimiseFlags();
     &setupMachOpts();
     &setupIncPaths();
+    &setupWarningFlags();
     &setupHeapStackSize();
 
     #
@@ -1597,17 +1377,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;
-    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;
+       $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 =~ /\.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...
@@ -1617,16 +1408,16 @@ Again, we'll do the post-recompilation-checker parts of this later.
     # 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).
-
 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';
 
@@ -1635,7 +1426,7 @@ phase) to @"$ifile_root.<suffix>"@.
     # -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
@@ -1649,7 +1440,7 @@ phase) to @"$ifile_root.<suffix>"@.
     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
     }
@@ -1662,16 +1453,41 @@ Now the Haskell compiler, C compiler, and assembler
 \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);
-       &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;
 
+    # save a copy of the .s file..
+    &saveIntermediate($ifile_root , "s" , $cc_as) if ($do_as && $Keep_s_file_too);
     &runAs($as_out, $ifile_root) if $do_as;
 \end{code}
 
@@ -1682,10 +1498,14 @@ Finally, decide what to queue up for linker input.
 
 #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);
     }
@@ -1704,9 +1524,13 @@ Finally, decide what to queue up for linker input.
 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');
 }
@@ -1716,27 +1540,41 @@ sub runLit2pgm {
 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) {
-       $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);
-       $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');
     }
+   
+    if ( $Only_preprocess_C ) {
+       $to_do = "$Cat $hscpp_hsc";
+       &run_something($to_do, '');
+    }
+
 }
 \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
@@ -1746,48 +1584,56 @@ sub runHscAndProcessInterfaces {
        
     local($source_unchanged) = 1;
 
-# Check if the source file is up to date relative to the target; in
-# that case we say "source is unchanged" and let the compiler bail out
-# early if the import usage information allows it.
+    # Check if the source file is up to date relative to the target; in
+    # that case we say "source is unchanged" and let the compiler bail out
+    # early if the import usage information allows it.
 
     ($i_dev,$i_ino,$i_mode,$i_nlink,$i_uid,$i_gid,$i_rdev,$i_size,
      $i_atime,$i_mtime,$i_ctime,$i_blksize,$i_blocks) = stat($ifile);
 
-    if ( ! -f $ofile_target ) {
-#      print STDERR "$Pgm:compile:Output file $ofile_target doesn't exist\n";
+    # The informational messages below are now conditional on -v being set -- SOF
+    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;
     }
 
     ($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 ) {
-#      print STDERR "$Pgm:compile:Interface file $hifile_target doesn't exist\n";
+    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;
     }
 
     ($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) {
-#      print STDERR "$Pgm:recompile:Input file $ifile newer than $ofile_target\n";
+    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;
     }
 
+    # 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) {
        push(@HsC_flags, '-fsource-unchanged'); 
     }  
 
-# Run the compiler
+    # Indicate whether we're static or not.
+    # This will only ever 
+    push(@HsC_flags, '-static') if $Static;
+
+    # 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;
@@ -1805,8 +1651,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.
        #
-       &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 {   
 
@@ -1831,28 +1679,21 @@ sub runHscAndProcessInterfaces {
 
 
        # 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);
-       
-       # save a copy of the .hc file, even if we are carrying on...
-       if ($HscOut eq '-C=' && $do_cc && $Keep_hc_file_too) {
-           local($to_do) = "$Rm $ifile_root.hc; $Cp $hsc_out $ifile_root.hc";
-           &run_something($to_do, 'Saving copy of .hc file');
+        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);
        }
-       
-       # save a copy of the .s file, even if we are carrying on...
-       if ($HscOut eq '-S=' && $do_as && $Keep_s_file_too) {
-           local($to_do) = "$Rm $ifile_root.s; $Cp $hsc_out $ifile_root.s";
-           &run_something($to_do, 'Saving copy of .s file');
-       }
-       
        # if we're going to split up object files,
        # we inject split markers into the .hc file now
        if ( $HscOut eq '-C=' && $SplitObjFiles ) {
            &inject_split_markers ( $hsc_out );
         }
+
+       # save a copy of the .hc file, even if we are carrying on...
+       if ($HscOut eq '-C=' && $do_cc && $Keep_hc_file_too) {
+            &saveIntermediate($ifile_root , "hc" , $hsc_out);
+       }
+
     }
 }
 \end{code}
@@ -1860,30 +1701,25 @@ sub runHscAndProcessInterfaces {
 
 \begin{code}
 sub runHsc {
-    local($ifile_root, $hsc_out, $hsc_hi, $going_interactive) = @_;
-
-    # prepend comma to HsP flags (so hsc can tell them apart...)
-    foreach $a ( @HsP_flags ) { $a = ",$a" unless $a =~ /^,/; }
+    local($ifile_root, $hsc_out, $hsc_hi, $hsc_out_c_stub, $hsc_out_h_stub, $going_interactive) = @_;
 
     &makeHiMap() unless $HiMapDone;
-#    print STDERR "HiIncludes: $HiIncludeString\n";
     push(@HsC_flags, "-himap=$HiIncludeString");
-#    push(@HsC_flags, "-himap=$HiMapFile");
 
     # here, we may produce .hc/.s and/or .hi files
     local($output) = '';
-    @Files_to_tidy = ();
+    #@Files_to_tidy = ();
 
     if ( $going_interactive ) {
-       # don't need .hi unless going to show it on stdout:
-       $ProduceHi = '-nohifile=' if ! $HiOnStdout;
+       # don't need .hi unless we're going to show it on stdout:
+       $ProduceHi = '-nohifile=' if ! ($HiOnStdout || $Specific_hi_file ne '' );
        $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 ) {
@@ -1894,6 +1730,7 @@ sub runHsc {
     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");
     }
@@ -1905,7 +1742,28 @@ sub runHsc {
     }
 
     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 $USPLint $StgLint $Verbose";
+      close(OPTS);
+      $to_do = "$HsC $hscpp_hsc \@$Tmp_prefix.opts $output +RTS @HsC_rts_flags";
+
+    } else {
+
+    $to_do = "$HsC $hscpp_hsc $dump @HsC_flags $CoreLint $USPLint $StgLint $Verbose $output +RTS @HsC_rts_flags";
+    }
     &run_something($to_do, 'Haskell compiler');
 
     # finish business w/ nofibbish time/bytes-alloc stats
@@ -1916,9 +1774,7 @@ sub runHsc {
 Use \tr{@Import_dir} and \tr{@SysImport_dir} to make a tmp file
 of (module-name, pathname) pairs, one per line, separated by a space.
 \begin{code}
-#%HiMap     = ();
 $HiMapDone = 0;
-$HiMapFile = '';
 $HiIncludeString = ();         # dir1:dir2:dir3, to pass to GHC
 
 sub makeHiMap {
@@ -1928,88 +1784,233 @@ sub makeHiMap {
     local($mod, $path, $d, $e);
 
     # reset the global variables:
-    #%HiMap     = ();
     $HiMapDone = 0;
-    $HiMapFile = '';
     $HiIncludeString = ();             # dir1:dir2:dir3, to pass to GHC
     
     foreach $d ( @Import_dir ) {
-       if ($HiIncludeString) { $HiIncludeString = "$HiIncludeString:$d";
-       } else { $HiIncludeString = $d; }
+       if ($HiIncludeString) { 
+          $HiIncludeString = "$HiIncludeString:${d}%.${HiSuffix}";
+       } else { 
+          $HiIncludeString = "$d%.${HiSuffix}"; 
+       }
 
-# The compiler does the searching now
-#
-#      opendir(DIR, $d) || &tidy_up_and_die(1,"$Pgm: error when reading directory: $d\n");
-#      local(@entry) = readdir(DIR);
-#      foreach $e ( @entry ) {
-#          next unless $e =~ /\b([A-Z][A-Za-z0-9_]*)\.${HiSuffix_prelude}$/o;
-#          $mod  = $1;
-#          $path = "$d/$e";
-#          $path =~ s,^\./,,;
-#
-#          if ( ! defined($HiMap{$mod}) ) {
-#              $HiMap{$mod} = $path;
-#          } else {
-#              &already_mapped_err($mod, $HiMap{$mod}, $path);
-#          }
-#      }
-#      closedir(DIR); # || &tidy_up_and_die(1,"$Pgm: error when closing directory: $d\n");
     }
 
     foreach $d ( @SysImport_dir ) {
-       if ($HiIncludeString) { $HiIncludeString = "$HiIncludeString:$d";
-       } else { $HiIncludeString = $d; }
-
-#      opendir(DIR, $d) || &tidy_up_and_die(1,"$Pgm: error when reading directory: $d\n");
-#      local(@entry) = readdir(DIR);
-#      foreach $e ( @entry ) {
-#          next unless $e =~ /([A-Z][A-Za-z0-9_]*)\.$HiSuffix$/o;
-#          next if $NoImplicitPrelude && $e =~ /Prelude\.$HiSuffix$/o;
-#
-#          $mod  = $1;
-#          $path = "$d/$e";
-#          $path =~ s,^\./,,;
-#
-#          if ( ! defined($HiMap{$mod}) ) {
-#              $HiMap{$mod} = $path;
-#          } elsif ( $mod ne 'Main' )  { # saves useless warnings...
-#              &already_mapped_err($mod, $HiMap{$mod}, $path);
-#          }
-#      }
-#      closedir(DIR); # || &tidy_up_and_die(1,"$Pgm: error when closing directory: $d\n");
+       if ($HiIncludeString) { 
+           $HiIncludeString = "$HiIncludeString:${d}%.${HiSuffix_prelude}";
+       } else { 
+           $HiIncludeString = "${d}%.${HiSuffix_prelude}";
+        }
     }
 
+    $HiMapDone = 1;
+}
+
+\end{code}
+
+Invoke the 'linker' - either the standard linker or the one used to build
+a (Win32) DLL.
+
+\begin{code}
+sub runLinker()
+{
+    local($libdirs) = '';
+
+    # append last minute flags linker and consistency flags
+    &setupBuildFlags();
+    &setupSyslibs();
+    &setupLinkOpts();
+
+    # glue them together:
+    push(@UserLibrary_dir, @SysLibrary_dir);
+
+    $libdirs = '-L' . join(' -L',@UserLibrary_dir) if $#UserLibrary_dir >= 0;
+
+    # 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" : '';
+    @Files_to_tidy = ($Specific_output_file ne '') ? $Specific_output_file : 'a.out'; 
+
+    &prepareWin32DllLink(1);
+
+    local($to_do) = "$lnkr $Verbose @Ld_flags $output @Link_file $TopClosureFile $libdirs @UserLibrary @SysLibrary";
+    &run_something($to_do, 'Linker');
+
+    # finally, check the consistency info in the binary
+    local($executable) = $Files_to_tidy[0];
+    @Files_to_tidy = (); # reset; we don't want to nuke it if it's inconsistent
+
+    if ( $LinkChk ) {
+       # dynamically load consistency-chking code; then do it.
+       require('ghc-consist.prl')
+           || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-consist.prl!\n");
+
+       &chk_consistency_info ( $executable );
+    }
+
+    # if PVM parallel stuff, we do truly weird things.
+    # Essentially: (1) move the executable over to where PVM expects
+    # to find it.  (2) create a script in place of the executable
+    # which will cause the program to be run, via SysMan.
+    if ( $PARing eq 'p' ) {
+       local($pvm_executable) = $executable;
+       local($pvm_executable_base);
+
+       if ( $pvm_executable !~ /^\// ) { # a relative path name: make absolute
+           local($pwd) = `pwd`;
+           chop($pwd);
+           $pwd =~ s/^\/tmp_mnt//;
+           $pvm_executable = "$pwd/$pvm_executable";
+       }
+
+       $pvm_executable =~ s|/|=|g; # make /s into =s
+       $pvm_executable_base = $pvm_executable;
+
+       $pvm_executable = $ENV{'PVM_ROOT'} . '/bin/' . $ENV{'PVM_ARCH'}
+                       . "/$pvm_executable";
+
+       &run_something("$Rm -f $pvm_executable; $Cp -p $executable $pvm_executable && $Rm -f $executable", 'Moving binary to PVM land');
+
+       # OK, now create the magic script for "$executable"
+       open(EXEC, "> $executable") || &tidy_up_and_die(1,"$Pgm: couldn't open $executable to write!\n");
+       print EXEC <<EOSCRIPT1;
+eval 'exec perl -S \$0 \${1+"\$@"}'
+  if \$running_under_some_shell;
+# =!=!=!=!=!=!=!=!=!=!=!
+# This script is automatically generated: DO NOT EDIT!!!
+# Generated by Glasgow Haskell, version ${ProjectVersion} ${ProjectPatchLevel}
 #
-# Not currently used:
-#
-#    $HiMapFile = "$Tmp_prefix.himap";
-#    unlink($HiMapFile);
-#    open(HIMAP, "> $HiMapFile") || &tidy_up_and_die(1,"$Pgm: can't open $HiMapFile\n");
-#    foreach $d (keys %HiMap) {
-#      print HIMAP $d, ' ', $HiMap{$d}, "\n";
-#    }
-#    close(HIMAP) || &tidy_up_and_die(1,"$Pgm: error when closing $HiMapFile\n");
+\$pvm_executable      = '$pvm_executable';
+\$pvm_executable_base = '$pvm_executable_base';
+\$SysMan = '$SysMan';
+EOSCRIPT1
 
-    $HiMapDone = 1;
+       print EXEC <<\EOSCRIPT2;
+# first, some magical shortcuts to run "commands" on the binary
+# (which is hidden)
+if ($#ARGV == 1 && $ARGV[0] eq '+RTS' && $ARGV[1] =~ /^--((size|file|strip|rm|nm).*)/ ) {
+    local($cmd) = $1;
+    system("$cmd $pvm_executable");
+    exit(0); # all done
 }
 
-sub already_mapped_err {
-    local($mod, $mapped_to, $path) = @_;
+# OK, really run it; process the args first
+$ENV{'PE'} = $pvm_executable_base;
+$debug = '';
+$nprocessors = 2; # the default
+@nonPVM_args = ();
+$in_RTS_args = 0;
 
-    # OK, it isn't really an error if $mapped_to and $path turn
-    # out to be the same thing.
-    ($m_dev,$m_ino,$m_mode,$m_nlink,$m_uid,$m_gid,$m_rdev,$m_size,
-     $m_atime,$m_mtime,$m_ctime,$m_blksize,$m_blocks) = stat($mapped_to);
-    ($p_dev,$p_ino,$p_mode,$p_nlink,$p_uid,$p_gid,$p_rdev,$p_size,
-     $p_atime,$p_mtime,$p_ctime,$p_blksize,$p_blocks) = stat($path);
+# ToDo: handle --RTS
+args: while ($a = shift(@ARGV)) {
+    if ( $a eq '+RTS' ) {
+       $in_RTS_args = 1;
+    } elsif ( $a eq '-RTS' ) {
+       $in_RTS_args = 0;
+    }
+    if ( $a eq '-d' && $in_RTS_args ) {
+       $debug = '-';
+    } elsif ( $a =~ /^-N(\d+)/ && $in_RTS_args ) {
+       $nprocessors = $1;
+    } else {
+       push(@nonPVM_args, $a);
+    }
+}
 
-    return if $m_ino == $p_ino; # same inode number
+local($return_val) = 0;
+system("$SysMan $debug $pvm_executable $nprocessors @nonPVM_args");
+$return_val = $?;
+system("mv $ENV{'HOME'}/$pvm_executable_base.???.gr .") if -f "$ENV{'HOME'}/$pvm_executable_base.001.gr";
+exit($return_val);
+EOSCRIPT2
+       close(EXEC) || die "Failed closing $executable\n";
+       chmod 0755, $executable;
+    }
+}
+
+sub createWin32DLL()
+{
+    local ($libdirs);
+
+    # append last minute flags linker and consistency flags
+    &setupBuildFlags();
+    &setupSyslibs();
+    &setupLinkOpts();
+
+    # glue them together:
+    push(@UserLibrary_dir, @SysLibrary_dir);
+
+    $libdirs = '-L' . join(' -L',@UserLibrary_dir) if $#UserLibrary_dir >= 0;
+
+    &prepareWin32DllLink(0);
+
+    local ($bld_dll) = "dllwrap";
 
-    print STDERR "$Pgm: module $mod already mapped to $mapped_to";
-    print STDERR ";\n\tignoring: $path\n";
+    local ($output) = ($Specific_output_file ne '') ? "$Specific_output_file" : 'HSdll.dll';
+    local ($output_dir);
+    local ($output_file);
+    local ($output_lib, $output_def);
+
+    ($output_dir = $output) =~ s|(.*/)[^/]+$|$1|;
+    $output_dir = "" if ($output_dir eq $output);
+    ($output_file = $output) =~ s|.*/([^/]+)$|$1|;
+
+    ($output_lib = $output_file) =~ s|(.+)\.[^\.]*$|${output_dir}lib$1_imp.a|;
+    ($output_def = $output_file) =~ s|(.+)\.[^\.]*$|${output_dir}$1.def|;
+
+    push (@Dll_flags, "-mno-cygwin --target=i386-mingw32") if ($TargetPlatform =~ /^.*mingw32$/);
+    push (@Dll_flags, "--output-lib $output_lib");
+    # If the "--def " option hasn't been supplied, assume everything 
+    # is going to be exported via the DLL.."
+    if (!grep(/--def/, @Dll_flags)) {
+      push (@Dll_flags, "--export-all --output-def $output_def");
+    }
+
+    local($to_do) = "$bld_dll @Dll_flags -o $output @Link_file $libdirs @UserLibrary @SysLibrary";
+    # Make sure the user sees this piece of magic.
+    print STDERR "$to_do\n" if (!$Verbose);
+    &run_something($to_do, 'DLL creator');
+}
+
+sub prepareWin32DllLink ()
+{
+    local($linking_main) = @_;
+
+    #
+    # Win32 DLLs - link with import libraries, not the real archives.
+    # 
+    if ( $TargetPlatform =~ /-mingw32$/ ) {
+       if (!$Static) {
+        #
+        # If the libraries have the form libHSfoo.a, we
+        # transform that into libHSfoo_imp.a - the import
+        # library of the DLL.
+        # 
+         foreach $a ( @SysLibrary ) {
+           $a = "${a}_imp" if ($a =~ /^-lHS/);
+         }
+         foreach $a ( @UserLibrary ) {
+           $a = "${a}_imp" if ($a =~ /^-lHS/);
+         }
+         push(@Link_file, ( $INSTALLING ) ? "$InstLibDirGhc/Main.o"
+                                         : "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR/Main.o") if $linking_main;
+         push(@Link_file, ( $INSTALLING ) ? "$InstLibDirGhc/PrelMain.o"
+                                         : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/PrelMain.o") if $linking_main;
+       }
+       push(@Ld_flags,  "-mno-cygwin");
+    }
 }
 \end{code}
 
+
 %************************************************************************
 %*                                                                     *
 \section[Driver-misc-utils]{Miscellaneous utilities}
@@ -2051,13 +2052,15 @@ sub runGcc {
     local($c_flags) = "@CcBoth_flags";
     local($ddebug_flag) = ( $DEBUGging ) ? '-DDEBUG' : '';
 
+    $c_flags .= " -mno-cygwin" if ( $TargetPlatform =~ /-mingw32$/ );
+
     # "input" files to use that are not in some weird directory;
     # to help C compilers grok .hc files [ToDo: de-hackify]
     local($cc_help)   = "ghc$$.c";
     local($cc_help_s) = "ghc$$.s";
 
     $cc       = $CcRegd;
-    $s_output = ($is_hc_file || $TargetPlatform =~ /^(hppa|i386)/) ? $cc_as_o : $cc_as;
+    $s_output = (($is_hc_file && $DoAsmMangling) || $TargetPlatform =~ /^(powerpc|rs6000|hppa)/) ? $cc_as_o : $cc_as;
     $c_flags .= " @CcRegd_flags";
     $c_flags .= ($is_hc_file) ? " @CcRegd_flags_hc"  : " @CcRegd_flags_c";
 
@@ -2066,32 +2069,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;
-#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;
+    } 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";
 
-    # and #include the real source
     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;
     }
-    @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;
+    if ( $Only_preprocess_hc ) {
+       system("$Cat $Tmp_prefix.ccout");
+    }
     unlink($cc_help, $cc_help_s);
 }
 \end{code}
@@ -2100,56 +2106,32 @@ EOINCL
 sub runMangler {
     local($is_hc_file, $cc_as_o, $cc_as, $ifile_root) = @_;
 
-    if ( $is_hc_file ) {
-       # dynamically load assembler-fiddling code, which we are about to use:
-       require('ghc-asm.prl')
-       || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm.prl!\n");
-    }
-
     print STDERR `cat $cc_as_o` if $Dump_raw_asm; # to stderr, before mangling
 
-    if ($is_hc_file) {
+    if ($is_hc_file && $DoAsmMangling) {
+       # dynamically load assembler-fiddling code, which we are about to use:
+       require('ghc-asm.prl')
+            || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm.prl!\n");
        # 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 =~ /^i386/) {
-       # extremely-minor OFFENSIVE mangling of non-threaded just one file
+    } 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.prl!\n");
-       &mini_mangle_asm_i386($cc_as_o, $cc_as);
+       || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm-powerpc.prl!\n");
+       &mini_mangle_asm_powerpc($cc_as_o, $cc_as);
     }
 
     # save a copy of the .s file, even if we are carrying on...
-    if ($do_as && $Keep_s_file_too) {
-       local($to_do) = "$Rm $ifile_root.s; $Cp $cc_as $ifile_root.s";
-       &run_something($to_do, 'Saving copy of .s file');
-    }
+    #if ($do_as && $Keep_s_file_too) {
+    #    &saveIntermediate($ifile_root , "s" , $cc_as);
+    #}
 }
 \end{code}
 
@@ -2159,9 +2141,12 @@ sub runAs {
 
     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 ) {
-       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...
@@ -2181,7 +2166,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";
-           @Files_to_tidy = ( $split_out );
+           push(@Files_to_tidy, $split_out );
 
            &run_something($to_do, 'Unix assembler');
        }
@@ -2211,23 +2196,38 @@ sub run_something {
     }
 
     local($return_val) = 0;
-    system("$Time $str_to_do");
-    $return_val = $?;
+
+    if ( length($str_to_do) > 4000) { 
+      # 4000 - on the random side, just like the *real* ARG_MAX 
+      # for some shells.
+
+      # With some shells, command lines of this length may
+      # very well cause trouble. To safeguard against this, we squirrel the
+      # command into a file and exec that.
+      local ($sh) = $ENV{'REAL_SHELL'};
+      print STDERR "Backup plan A: saving cmd line in ${Tmp_prefix}.sh and executing that with $sh\n" if $Verbose;
+      open (TEMP, "> ${Tmp_prefix}.sh") || 
+               &tidy_up_and_die(1,"$Pgm: failed to open `$Tmp_prefix.sh'\n");
+      print TEMP "$Time $str_to_do\n";
+      close (TEMP) ||
+               &tidy_up_and_die(1,"$Pgm: failed closing `$Tmp_prefix.sh'\n");
+      system("$sh $Tmp_prefix.sh");
+      $return_val = $?;
+      
+      unlink "${Tmp_prefix}.sh";
+    } else {
+      system("$Time $str_to_do");
+      $return_val = $?;
+    }
 
     if ( $PostprocessCcOutput ) { # hack, continued
        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 /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 .*\.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/;
@@ -2240,7 +2240,6 @@ sub run_something {
         if ($Using_dump_file) {
            print STDERR "Compilation Errors dumped in $Specific_dump_file\n";
        }
-
        &tidy_up_and_die($return_val, '');
     }
     $Using_dump_file = 0;
@@ -2249,7 +2248,7 @@ sub run_something {
 
 %************************************************************************
 %*                                                                     *
-\subsection[Driver-ghctiming]{Emit nofibbish GHC timings}
+\subsection[Driver-ghc-timing]{Emit nofibbish GHC timings}
 %*                                                                     *
 %************************************************************************
 
@@ -2261,20 +2260,31 @@ sub process_ghc_timings {
     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>) {
-       $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 (! /Gen:\s+0/ && ! /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;
        }
 
-       $GCs = $1 if /^\s*([0-9,]+) garbage collections? performed/;
+        $GCs = $1 if /^\s*([0-9,]+) (collections? in generation 0|garbage collections? performed)/;
+
+       if ( /^\s+([0-9]+)\s+Mb total memory/ ) {
+           $TotMem = $1;
+        }
 
-       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;
@@ -2283,8 +2293,10 @@ sub process_ghc_timings {
        }
     }
     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
@@ -2315,7 +2327,7 @@ sub process_ghc_timings {
 
     # print out what we found
     print STDERR "<<$SysSpecificTiming: ",
-       "$BytesAlloc bytes, $GCs GCs, $AvgResidency/$MaxResidency avg/max bytes residency ($ResidencySamples samples), $InitTime INIT ($InitElapsed elapsed), $MutTime MUT ($MutElapsed elapsed), $GcTime GC ($GcElapsed elapsed)",
+       "$BytesAlloc bytes, $GCs GCs, $AvgResidency/$MaxResidency avg/max bytes residency ($ResidencySamples samples), ${TotMem}M in use, $InitTime INIT ($InitElapsed elapsed), $MutTime MUT ($MutElapsed elapsed), $GcTime GC ($GcElapsed elapsed)",
        " :$SysSpecificTiming>>\n";
 
     # OK, party over
@@ -2369,7 +2381,7 @@ nonsensical).
 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); 
@@ -2416,6 +2428,215 @@ sub add_Hsc_flags {
 }
 \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
+       ],
+       com,
+       [  # where to slurp interface files from
+         ( $INSTALLING 
+              ? "$InstLibDirGhc/imports/com"
+              : "$TopPwd/hdirect/lib"
+         )
+       , # where to find the archive to use when linking
+         ( $INSTALLING 
+              ? "$InstLibDirGhc"
+              : "$TopPwd/hdirect/lib"
+         )
+       , ''
+       , 'exts' # Syslib dependencies
+       , ''     # extra ghc opts
+       , ''     # extra cc opts
+       , '-luser32 -lole32 -loleaut32 -ladvapi32'
+                # 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
@@ -2423,22 +2644,41 @@ file for any such pragmas:
 
 \begin{code}
 sub check_for_source_options {
-    local($file) = @_;
+    local($file,$ifile) = @_;
+    local($comment_start,$comment_end);
+
+    if ($ifile =~ /\.hc$/ || 
+        $ifile =~ /_hc$/  || 
+       $ifile =~ /\.s$/  || 
+       $ifile =~ /_s$/ ) {  # `Real' C intermediate
+       $comment_start = "/\\*";
+       $comment_end   = "\\*/";
+    } else { # Assume it is a file containing Haskell source
+       $comment_start = "{-#";
+       $comment_end   = "#-}";
+    }
 
     open(FILE,$file) || return(1); # No big loss
-
+    
     while (<FILE>) {
-       if ( /^{-# OPTIONS (.*)#-}/ ) {
+       if ( /^${comment_start} OPTIONS (.*)${comment_end}$/ ) {
            # add the options found at the back of the command line.
           local(@entries) = split(/\s+/,$1);
+          print STDERR "Found OPTIONS " . join(' ',@entries) . " in $file\n" if $Verbose;
           push(@File_options, @entries);
        }
         elsif ( /^$/ ) { # ignore empty lines
            ;
         }
+        elsif ( /^#line.+$/ ) { # ignore comment lines (unused..ToDo: rm )
+           ;
+        }
+        elsif ( /^{-# LINE.+$/ ) { # ignore line pragmas
+           ;
+        }
         else { # stop looking, something non-empty / not
-              # {-# OPTIONS .. #-} encountered.
-           break;
+              # ${comment_start} OPTIONS .. ${comment_end} encountered.
+           close(FILE);return(0);
         }
     }
     close(FILE);
@@ -2463,11 +2703,11 @@ sub splitCmdLine {
 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, $_); next arg; };
+    /^--?./  && do { push(@Cmd_opts, $_); next arg; };
 
-    if (/\.[oa]$/) {
+    if (/\.([^_]+_)?[oa]$/) {
        push(@Link_file, $_);
     } else {
        push(@Input_file, $_);
@@ -2483,6 +2723,35 @@ arg: while($_ = $args[0]) {
 
 \end{code}
 
+When saving an intermediate file (.hc or .s) away, we 
+have to prefix any OPTIONS found in the original source file.
+
+\begin{code}
+sub saveIntermediate { 
+  local ($final,$suffix,$tmp)= @_ ;
+  local ($to_do);
+
+  # $final  -- root of where to park ${final}.${suffix}
+  # $tmp    -- temporary file where hsc put the intermediate file.
+
+  # Delete the old file
+  $to_do = "$Rm ${final}.${suffix}"; &run_something($to_do, "Removing old .${suffix} file");
+
+  if ( $#File_options >= 0 ) { # OPTIONS found in Haskell source unit
+    # Add OPTION comment to the top of the generated .${suffix} file
+    open(TEMP, "> ${final}.${suffix}") || &tidy_up_and_die(1,"Can't open ${final}.${suffix}\n");
+    print TEMP "/* OPTIONS " . join(' ',@File_options) . " */\n";
+    close(TEMP);
+    print STDERR "Prepending OPTIONS: " . join(' ',@File_options) . " to ${final}.${suffix}\n" if $Verbose;
+  }
+  $to_do = "$Cat $tmp  >> ${final}.${suffix}";
+  &run_something($to_do, "Saving copy of .${suffix} file");
+
+}
+
+\end{code}
+
+
 Command-line processor
 
 \begin{code}
@@ -2498,13 +2767,13 @@ arg: while($_ = $Args[0]) {
     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 ----------------------------------
-    /^-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:
@@ -2519,15 +2788,20 @@ arg: while($_ = $Args[0]) {
                            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
+    /^-hi-with-(.*)$/    && do { $HiOnStdout = 1; $HiWith .= " $1" ; $ProduceHi = '-hifile='; next arg; };
+    # limit ourselves to outputting a particular section.
 
     /^-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');
@@ -2536,6 +2810,8 @@ arg: while($_ = $Args[0]) {
     # stop after preprocessing C
     /^-M$/         && do { $Only_generate_deps = 1; $Do_as = 0; $Do_lnkr = 0; next arg; };
     # only generate dependency information.
+    /^--mk-dll$/    && do { $Only_generate_dll  = 1; $Do_as = 0; $Do_lnkr = 0; next arg; };
+    # Build a Win32 DLL (where supported).
     /^-S$/         && do { $Do_as = 0; $Do_lnkr = 0; next arg; };
     # stop after generating assembler
        
@@ -2543,8 +2819,8 @@ arg: while($_ = $Args[0]) {
     # stop after generating .o files
 
     /^-link-chk$/    && do { $LinkChk = 1; next arg; };
-    /^-no-link-chk$/ && do { $LinkChk = 0; next arg; };
     # don't do consistency-checking after a link
+    /^-no-link-chk$/ && do { $LinkChk = 0; next arg; };
 
     /^-tmpdir$/ && do { $Tmp_prefix = &grab_arg_arg(*Args,'-tmpdir', '');
                        $Tmp_prefix = "$Tmp_prefix/ghc$$";
@@ -2605,6 +2881,7 @@ arg: while($_ = $Args[0]) {
                                    $Status++;
                                }
                            }
+                           $ProduceHi='-hifile=';
                            next arg; };
 
     # The suffix to use when looking for interface files
@@ -2614,13 +2891,6 @@ arg: while($_ = $Args[0]) {
                                $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;
@@ -2635,13 +2905,14 @@ arg: while($_ = $Args[0]) {
 
     /^-prof$/ && do { $PROFing = 'p'; next arg; }; # profiling -- details later!
 
-    /^-auto/ && do {
-               # generate auto SCCs on top level bindings
-               # -auto-all = all top level bindings
-               # -auto     = only top level exported bindings
-               $PROFauto = ( /-all/ )
-                           ? '-fauto-sccs-on-all-toplevs'
-                           : '-fauto-sccs-on-exported-toplevs';
+    /^-auto-dicts$/ && do {
+               $PROFdicts = '-fauto-sccs-on-dicts';
+               next arg; };
+    /^-auto-all$/ && do {
+               $PROFauto = '-fauto-sccs-on-all-toplevs';
+               next arg; };
+    /^-auto$/ && do {
+               $PROFauto = '-fauto-sccs-on-exported-toplevs';
                next arg; };
 
     /^-caf-all/ && do { # generate individual CAF SCC annotations
@@ -2664,13 +2935,12 @@ arg: while($_ = $Args[0]) {
                            : '-fauto-sccs-on-exported-toplevs';
                next arg; };
 
-    #--------- ticky/concurrent/parallel -----------------------------------
+    #--------- ticky/parallel ----------------------------------------------
     # 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
-    /^-parallel$/   && do { $PARing    = 'p'; next arg; }; # parallel Haskell
+    /^-parallel$/   && do { $PARing    = 'p'; &add_syslib('concurrent'); next arg; }; # parallel Haskell
 
     #-------------- "user ways" --------------------------------------------
 
@@ -2706,27 +2976,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);
-                           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; };
 
     #=======================================================================
@@ -2750,20 +3000,17 @@ 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; };
-    /^-optcpp(.*)$/ && do { push(@Cpp_define,       $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; };
+    /^-optdll(.*)$/ && do { push(@Dll_flags,        $1); next arg; };
     /^-optdep(.*)$/ && do { push(@MkDependHS_flags, $1); next arg; };
 
     #---------- Haskell C pre-processor (hscpp) ----------------------------
     /^-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; };
@@ -2773,32 +3020,25 @@ 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; };
 
-    /^-fhaskell-1\.3$/         && do { next arg; }; # a no-op right now
-
     /^-fignore-interface-pragmas$/ && do { push(@HsC_flags, $_); next arg; };
+    /^-fignore-asserts$/           && 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
-     # 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; };
+    /^-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 {
@@ -2813,59 +3053,62 @@ arg: while($_ = $Args[0]) {
                        }
                        next arg; };
 
+    /^-unreg$/             && do { $UNREGing = 'u'; next arg; };
+    /^-funregisterised$/    && do { push(@HsC_flags, $_); next arg; };
+    /^-fno-asm-mangling$/   && do { $DoAsmMangling = 0; next arg; };
+
+    /^-fallow-overlapping-instances$/ && do { push(@HsC_flags, $_); next arg; };
+    /^-fallow-undecidable-instances$/ && do { push(@HsC_flags, $_); next arg; };
+    /^-fhistory-size.*$/             && do { push(@HsC_flags, $_); next arg; };
+    /^-fdicts-strict$/                       && do { push(@HsC_flags, $_); next arg; };
     /^-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; };
 
-    /^-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$/
                && do { $Oopt_DoSpecialise = ''; next arg; };
 
+    /^-fusagesp$/
+                && do {  $Oopt_UsageSPInf = '-fusagesp';
+                         push (@HsC_flags, '-fusagesp-on'); next arg; };
+
+    /^-fcompiling-prelude$/ && do { $CompilingPrelude=1; push(@HsC_flags, $_); next arg; };
 
 # Now the foldr/build options, which are *on* by default (for -O).
 
     /^-ffoldr-build$/
                    && do { $Oopt_FoldrBuild = 1; 
-                           $Oopt_FB_Support = '-fdo-arity-expand';
                            #print "Yes F/B\n";
                            next arg; };
 
     /^-fno-foldr-build$/
                    && do { $Oopt_FoldrBuild = 0; 
-                           $Oopt_FB_Support = ''; 
                            next arg; };
 
-    /^-fno-foldr-build-rule$/
-                   && do { $Oopt_FoldrBuild = 0; 
-                           next arg; };
+    # --------------- Renamer -------------
 
-    /^-fno-enable-tech$/
-                   && do { $Oopt_FB_Support = ''; 
-                           next arg; };
 
-    /^-fno-snapback-to-append$/
-                   && do { $Oopt_FoldrBuildInline .= ' -fdo-not-fold-back-append '; 
-                           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
-    /^-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);
@@ -2874,35 +3117,35 @@ arg: while($_ = $Args[0]) {
     /^-fno-pedantic-bottoms$/
                    && do { $Oopt_PedanticBottoms = ''; next arg; };
 
-    /^-fdo-monad-eta-expansion$/
-                   && do { $Oopt_MonadEtaExpansion = $_; next arg; };
+    /^-fno-pre-inlining$/
+                   && do { push(@HsC_flags, $_); 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; };
+    /^-funbox-strict-fields$/
+                  && do { push(@HsC_flags, $_); next arg; };
 
     # --------------- 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; };
 
+    /^-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,
@@ -2925,6 +3168,9 @@ arg: while($_ = $Args[0]) {
     # -d(no-)core-lint is done this way so it is turn-off-able.
     /^-dcore-lint/       && do { $CoreLint = '-dcore-lint'; next arg; };
     /^-dno-core-lint/    && do { $CoreLint = '';           next arg; };
+    # Ditto for USP lint
+    /^-dusagesp-lint/    && do { $USPLint = '-dusagesp-lint'; next arg; };
+    /^-dno-usagesp-lint/ && do { $USPLint = '';               next arg; };
     # Ditto for STG lint
     /^-dstg-lint/       && do { $StgLint = '-dstg-lint'; next arg; };
     /^-dno-stg-lint/    && do { $StgLint = '';           next arg; };
@@ -2932,6 +3178,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; };
+    /^-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; };
@@ -2964,7 +3211,7 @@ arg: while($_ = $Args[0]) {
        }
        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]$/) {
@@ -3010,7 +3257,8 @@ arg: while($_ = $Args[0]) {
 
     #---------- Linker (gcc, really) ---------------------------------------
 
-    /^-static$/                && do { push(@Ld_flags, $_); next arg; };
+    /^-static$/                && do { $Static=1; 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...