[project @ 1999-02-01 18:04:46 by simonm]
[ghc-hetmet.git] / ghc / driver / ghc.lprl
index 25e3deb..049ef82 100644 (file)
@@ -1,4 +1,3 @@
-%
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1997
 %
 
@@ -101,6 +100,8 @@ HOSTPLATFORM TARGETPLATFORM
 
 ProjectName ProjectVersion ProjectVersionInt ProjectPatchLevel 
 
+HscMajorVersion HscMinorVersion CcMajorVersion CcMinorVersion
+
 TOP_PWD
 
 bindir libdir libexecdir datadir
@@ -194,7 +195,6 @@ $HsCpp       = # but this is re-set to "cat" (after options) if -cpp not seen
                           : "$TopPwd/${CURRENT_DIR}/${GHC_HSCPP}";
 
 @HsCpp_flags   = ();
-$genSPECS_flag = '';           # See ../utils/hscpp/hscpp.prl
 $HsC    = ( $INSTALLING ) ? "$InstLibExecDirGhc/hsc"
                           : "$TopPwd/${CURRENT_DIR}/${GHC_HSC}";
 
@@ -221,13 +221,11 @@ 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            = '-fspecialise';
    $Oopt_FoldrBuild              = 0; # *Off* by default!
    $Oopt_FB_Support              = ''; # was '-fdo-arity-expand';
@@ -241,9 +239,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: 
@@ -251,15 +253,15 @@ $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       = ();
 
 # 'nm' is used for consistency checking (ToDo: mk-world-ify)
 # ToDo: check the OS or something ("alpha" is surely not the crucial question)
@@ -285,7 +287,8 @@ these are turned off by -Wnot.
                     '-fwarn-unused-imports');
 @MinusWallOpts           = (@MinusWOpts, 
                     '-fwarn-unused-matches',
-                    '-fwarn-name-shadowing');
+                    '-fwarn-name-shadowing',
+                    '-fwarn-missing-signatures');
 \end{code}
 
 What options \tr{-user-setup-a} turn into (user-defined ``packages''
@@ -300,14 +303,8 @@ $BuildTag  = ''; # default is sequential build w/ Appel-style GC
                   '_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",
                   # system ways end
                   '_a',    "$WAY_a_NAME",
                   '_b',    "$WAY_b_NAME",
@@ -353,14 +350,8 @@ $BuildTag  = ''; # default is sequential build w/ Appel-style GC
        '_p',  "$WAY_p_HC_OPTS",
        '_t',  "$WAY_t_HC_OPTS",
        '_u',  "$WAY_u_HC_OPTS",
-       '_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" );
+       '_mg', "$WAY_mg_HC_OPTS");
 
 \end{code}
 
@@ -379,10 +370,18 @@ require special handling.
 # 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  = $ProjectVersionInt;
-$Haskell1Version = 4; # i.e., Haskell 1.4
+$Haskell1Version = 5; # i.e., Haskell 1.4
 @Cpp_define     = ();
 
+# Cpp symbols defined when we're processing Haskell source.
+
+@HsSourceCppOpts = 
+       ( "-D__HASKELL1__=$Haskell1Version"
+       , "-D__GLASGOW_HASKELL__=$ProjectVersionInt"
+       # not yet -- SDM
+       # , "-D__CONCURRENT_HASKELL__"
+       );
+
 @UserLibrary_dir= ();  #-L things;...
 @UserLibrary           = ();   #-l things asked for by the user
 
@@ -397,8 +396,9 @@ $Haskell1Version = 4; # i.e., Haskell 1.4
 @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
@@ -438,14 +438,6 @@ $StolenX86Regs = 4; # **HACK*** of the very worst sort
 $CoreLint      = '';
 $StgLint       = '';
 
-@CcBoth_flags  = ('-S');   # flags for *any* C compilation
-@CcInjects     = ();
-
-# GCC flags: those for all files, those only for .c files; those only for .hc files
-@CcRegd_flags    = ('-ansi', '-D__STG_GCC_REGS__', '-D__STG_TAILJUMPS__');
-@CcRegd_flags_c        = ();
-@CcRegd_flags_hc = ();
-
 @Import_dir    = ('.'); #-i things
 @Include_dir   = ('.'); #-I things; other default(s) stuck on AFTER option processing
 
@@ -471,8 +463,8 @@ $PostprocessCcOutput = 0;
 $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)-/;
+    if $HaveNativeCodeGen && $TargetPlatform =~ /^(alpha)-/;
+# TEMP: disable x86 & Sparc if $HaveNativeCodeGen && $TargetPlatform =~ /^(i386|alpha|sparc)-/;
 $ProduceHi    = '-hifile=';
 $HiOnStdout   = 0;
 $HiWith       = '';
@@ -490,9 +482,7 @@ $PROFignore_scc = '';       # set to relevant parser flag if explicit sccs ignored
 $UNPROFscc_auto = '';  # set to relevant hsc flag if forcing auto sccs without profiling
 $TICKYing = '';        # set to t if compiling for ticky-ticky profiling
 $PARing = '';          # set to p if compiling for PAR
-$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
 $Specific_hi_file = '';                # set by -ohi <file>; "-" for stdout
 $Specific_dump_file = '';      # set by -odump <file>; "-" for stdout
 $Using_dump_file = 0;
@@ -508,12 +498,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)
 
@@ -541,14 +534,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 = 33;
-$HsC_minor_version = 0;
-$Cc_major_version  = 36;
-$Cc_minor_version  = 1;
+$HsC_major_version = $HscMajorVersion;
+$HsC_minor_version = $HscMinorVersion;
+$Cc_major_version  = $CcMajorVersion;
+$Cc_minor_version  = $CcMinorVersion;
 
 # options: these must always agree
 $HsC_consist_options = '';    # we record, in this order:
@@ -577,12 +570,11 @@ if (  $Status == 0 && $Only_generate_deps ) {
 
     push (@MkDependHS_flags, "-o$Osuffix") if $Osuffix;
     push (@MkDependHS_flags, "-s$BuildTag") if $BuildTag;
-    push (@MkDependHS_flags, "-D__HASKELL1__=$Haskell1Version");
     # 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 -- @Cmd_opts -- @Input_file" ;
+    local($to_do) = "$MkDependHS @MkDependHS_flags @HsSourceCppOpts -- @Cmd_opts -- @Input_file" ;
     &run_something($to_do, 'Haskell dependencies');
     exit $Status;
 }
@@ -706,7 +698,19 @@ sub setupOptimiseFlags {
 #        '-fsimpl-uf-use-threshold0',
 #        '-fessential-unfoldings-only',
 
-         $Oopt_UnfoldingUseThreshold,
+         #
+         # The presence of -fclone-binds is *temporary* to work around
+          # the fact that the desugarer in 3.0{2.3} does generate
+         # bindings with identical ids, and the type checker doesn't perform
+         # properly cloned type substitutions. Instead, we make sure that all 
+         # binders are cloned first time through the simplifier.
+          #
+         # Will be properly fixed in the `new compiler` I hear, at which point
+         # the cloning can be turned off here.
+         #
+          # Let's find out..
+          #'-fclone-binds',
+
          $Oopt_MaxSimplifierIterations,
          $Oopt_ShowSimplifierProgress,
          ']',
@@ -737,22 +741,33 @@ sub setupOptimiseFlags {
 #      f  = E
 #      g* = f
 #      ...f...
-# The g=f will get reverse-substituted later, but it's untidy.
+# The g=f will get reverse-substituted later, but it's untidy. --SLPJ
 #
-#        '-fessential-unfoldings-only',
-#        '-fsimpl-uf-use-threshold0',
+# SDM: Here's why it's necessary.
+#
+#   If we unfold in the first pass before the specialiser is run
+#   we miss opportunities for specialisation because eg. wrappers
+#   have been inlined for specialisable functions.  
+#
+#   This shows up in PrelArr.lhs - the specialised instance for newArray 
+#   calls the generic rangeSize, because rangeSize is strict and is
+#   replaced by its wrapper by the simplifier.
+
+         '-fessential-unfoldings-only',
+         '-fsimpl-uf-use-threshold0',
+
+         # See remark re: cloning in defn of minusnotO
+         '-fclone-binds',
 
          '-fmax-simplifier-iterations1',
          $Oopt_PedanticBottoms,
          ']',
 
        ($Oopt_DoSpecialise) ? (
-         '-fspecialise-overloaded',
-         $Oopt_SpecialiseUnboxed,
          $Oopt_DoSpecialise,
        ) : (),
 
-       '-fsimplify',                   # need dependency anal after specialiser ...
+       '-fsimplify',           # need dependency anal after specialiser ...
          '[',                  # need tossing before calc-inlinings ...
          $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
@@ -765,7 +780,6 @@ sub setupOptimiseFlags {
          '-freuse-con',
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_ShowSimplifierProgress,
          #
@@ -779,8 +793,6 @@ sub setupOptimiseFlags {
           '-fclone-binds',
          ']',
 
-#LATER:        '-fcalc-inlinings1', -- pointless for 2.01
-
 #      ($Oopt_FoldrBuildWW) ? (
 #              '-ffoldr-build-ww-anal',
 #              '-ffoldr-build-worker-wrapper',
@@ -797,7 +809,6 @@ sub setupOptimiseFlags {
 #                '-freuse-con',
 #                $Oopt_PedanticBottoms,
 #                $Oopt_MonadEtaExpansion,
-#                $Oopt_UnfoldingUseThreshold,
 #                $Oopt_MaxSimplifierIterations,
 #                $Oopt_ShowSimplifierProgress,
 #                ']',
@@ -825,7 +836,6 @@ sub setupOptimiseFlags {
            '-freuse-con',
            $Oopt_PedanticBottoms,
            $Oopt_MonadEtaExpansion,
-           $Oopt_UnfoldingUseThreshold,
            $Oopt_MaxSimplifierIterations,
            $Oopt_ShowSimplifierProgress,
            ']',
@@ -850,7 +860,6 @@ sub setupOptimiseFlags {
                        # but do reductions if you see them!
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_ShowSimplifierProgress,
          ']',
@@ -871,7 +880,6 @@ sub setupOptimiseFlags {
          '-flet-to-case',              # Aha! Only done after strictness analysis
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_ShowSimplifierProgress,
          ']',
@@ -883,7 +891,7 @@ 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 $Oopt_ShowSimplifierProgress ]" ),
+#      : "-fliberate-case -fsimplify [ $Oopt_FB_Support -ffloat-lets-exposing-whnf -ffloat-primops-ok -fcase-of-case -fdo-case-elim -fcase-merge -fdo-eta-reduction -fdo-lambda-eta-expansion -freuse-con -flet-to-case $Oopt_PedanticBottoms $Oopt_MonadEtaExpansion $Oopt_MaxSimplifierIterations $Oopt_ShowSimplifierProgress ]" ),
 
 # Final clean-up simplification:
 
@@ -905,7 +913,6 @@ sub setupOptimiseFlags {
                        # but still do reductions if you see them!
          $Oopt_PedanticBottoms,
          $Oopt_MonadEtaExpansion,
-         $Oopt_UnfoldingUseThreshold,
          $Oopt_MaxSimplifierIterations,
          $Oopt_ShowSimplifierProgress,
          ']',
@@ -915,7 +922,6 @@ sub setupOptimiseFlags {
 #LATER:        '-fcalc-inlinings2', -- pointless for 2.01
 
       # stg2stg passes
-       '-fupdate-analysis',
        '-flambda-lift',
        $Oopt_FinalStgProfilingMassage,
        $Oopt_StgStats,
@@ -925,6 +931,7 @@ sub setupOptimiseFlags {
 
       # SPECIAL FLAGS for -O2
        ($OptLevel == 2) ? (
+         '-fupdate-analysis',  # virtually useless; relegated to -O2
          '-fsemi-tagging',
        ) : (),
       );
@@ -949,8 +956,7 @@ 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...
 
@@ -970,7 +976,7 @@ if ( $OptLevel <= 0 ) {
 %*                                                                     *
 %************************************************************************
 
-Sort out @$BuildTag@, @$PROFing@, @$CONCURing@, @$PARing@,
+Sort out @$BuildTag@, @$PROFing@, @$PARing@,
 @$GRANing@, @$TICKYing@:
 \begin{code}
 sub setupBuildFlags {
@@ -995,18 +1001,9 @@ sub setupBuildFlags {
       $PROFignore_scc = '-W' if $PROFauto; 
 
       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++;
-      }
   }
   #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; }
@@ -1019,13 +1016,7 @@ sub setupBuildFlags {
       if ($PARing   eq 'p') { print STDERR "$Pgm: Can't do profiling with -parallel.\n"; exit 1; }
       if ($GRANing  eq 'g') { print STDERR "$Pgm: Can't do profiling with -gransim.\n"; exit 1; }
       if ($TICKYing eq 't') { print STDERR "$Pgm: Can't do profiling with -ticky.\n"; exit 1; }
-      $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; }
@@ -1076,9 +1067,6 @@ Decide what the consistency-checking options are in force for this run:
        $Tag = "${Tag}_" if $Tag ne '';
        $HiSuffix_prelude="${Tag}hi";
   }
-  #push(@HsC_flags, "-hisuf-prelude=.${HiSuffix_prelude}"); # use appropriate Prelude .hi files
-  #push(@HsC_flags, "-hisuf=.${HiSuffix}");
-
 } # setupBuildFlags
 \end{code}
 
@@ -1098,14 +1086,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
@@ -1120,31 +1103,16 @@ 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");
 
   } 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!
@@ -1161,22 +1129,12 @@ 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-|^rs6000-/) {
-      # 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;
       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}
@@ -1211,14 +1169,34 @@ sub setupLinkOpts {
 
   unshift(@Ld_flags,
         (($Ld_main) ? ( '-u', "${uscore}Main_" . $Ld_main . '_closure' ) : ()));
+
+  # things that are referenced by the RTS - make sure that we pull 'em in
   unshift(@Ld_flags,
-       (  '-u', "${uscore}PrelBase_Z91Z93_closure"      # i.e., []
-          ,'-u', "${uscore}PrelBase_IZh_static_info"
-          ,'-u', "${uscore}PrelBase_CZh_static_info"
-          ,'-u', "${uscore}PrelBase_False_inregs_info"
-          ,'-u', "${uscore}PrelBase_True_inregs_info"
-          ,'-u', "${uscore}DEBUG_REGS"
+         ( '-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"
        ));
+  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')); 
@@ -1261,23 +1239,20 @@ 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';
 
   # 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' ) {
@@ -1286,7 +1261,16 @@ sub setupSyslibs {
   }
 
 # Push the GNU multi-precision arith lib; and the math library
-push(@SysLibrary, '-lgmp');
+
+# If this machine has GMP already installed, then we'll get the installed
+# lib here, because presumably the one in the tree won't have been built.
+
+if ($LibGmp eq 'not-installed') {
+  push(@SysLibrary, "-lgmp");
+} else {
+  push(@SysLibrary, "-l$LibGmp");
+}
+
 push(@SysLibrary, '-lm');
 \end{code}
 
@@ -1513,6 +1497,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.
@@ -1527,6 +1513,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';
@@ -1617,7 +1605,9 @@ 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 ($Only_preprocess_hc) { # stop after having run $Cc -E
        $do_as=0;
@@ -1629,10 +1619,14 @@ Again, we'll do the post-recompilation-checker parts of this later.
     } 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...
@@ -1648,7 +1642,6 @@ Again, we'll do the post-recompilation-checker parts of this later.
 
 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>"@.
@@ -1688,7 +1681,30 @@ 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) {
@@ -1710,8 +1726,7 @@ Finally, decide what to queue up for linker input.
 
 #ToDo:    local($or_isuf) = ($Isuffix eq '') ? '' : "|$Isuffix";
 
-
-    if ( $ifile !~ /\.(lhs|hs|hc|c|s|a)$/ && $ifile !~ /_hc$/ ) {
+    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$/ ) {
@@ -1769,7 +1784,7 @@ sub runHscpp {
        &run_something($to_do, 'Ineffective C pre-processor');
     } else {
        local($includes) = '-I' . join(' -I',@Include_dir);
-       $to_do .= "$HsCpp $Verbose $genSPECS_flag @HsCpp_flags -D__HASKELL1__=$Haskell1Version -D__GLASGOW_HASKELL__=$GhcVersionInfo $includes $lit2pgm_hscpp >> $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');
     }
@@ -1785,7 +1800,9 @@ sub runHscpp {
 
 \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
@@ -1824,6 +1841,9 @@ sub runHscAndProcessInterfaces {
        $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) {
@@ -1832,7 +1852,7 @@ sub runHscAndProcessInterfaces {
 
     # 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
@@ -1905,13 +1925,12 @@ sub runHscAndProcessInterfaces {
 
 \begin{code}
 sub runHsc {
-    local($ifile_root, $hsc_out, $hsc_hi, $going_interactive) = @_;
+    local($ifile_root, $hsc_out, $hsc_hi, $hsc_out_c_stub, $hsc_out_h_stub, $going_interactive) = @_;
 
     # prepend comma to HsP flags (so hsc can tell them apart...)
     foreach $a ( @HsP_flags ) { $a = ",$a" unless $a =~ /^,/; }
 
     &makeHiMap() unless $HiMapDone;
-    #print STDERR "HiIncludes: $HiIncludeString\n";
     push(@HsC_flags, "-himap=$HiIncludeString");
 
     # here, we may produce .hc/.s and/or .hi files
@@ -1919,15 +1938,15 @@ sub runHsc {
     #@Files_to_tidy = ();
 
     if ( $going_interactive ) {
-       # don't need .hi unless going to show it on stdout:
+       # don't need .hi unless we're going to show it on stdout:
        $ProduceHi = '-nohifile=' if ! $HiOnStdout;
        $do_cc = 0; $do_as = 0; $Do_lnkr = 0; # and we won't go any further...
     }
 
     # set up for producing output/.hi; note that flag twiddling
     # may mean that nothing will actually be produced:
-    $output = "$ProduceHi$hsc_hi $HscOut$hsc_out";
-    push(@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 ) {
@@ -1950,7 +1969,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 $StgLint $Verbose";
+      close(OPTS);
+      $to_do = "$HsC @HsP_flags ,$hscpp_hsc \@$Tmp_prefix.opts $output +RTS @HsC_rts_flags";
+
+    } else {
+
+      $to_do = "$HsC @HsP_flags ,$hscpp_hsc $dump @HsC_flags $CoreLint $StgLint $Verbose $output +RTS @HsC_rts_flags";
+    }
     &run_something($to_do, 'Haskell compiler');
 
     # finish business w/ nofibbish time/bytes-alloc stats
@@ -2043,7 +2083,7 @@ sub runGcc {
     local($cc_help_s) = "ghc$$.s";
 
     $cc       = $CcRegd;
-    $s_output = ($is_hc_file || $TargetPlatform =~ /^(powerpc|rs6000|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";
 
@@ -2052,27 +2092,24 @@ 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");
 
     # 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 -D__HASKELL1__=$Haskell1Version $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 )";
-    # note: __GLASGOW_HASKELL__ is pointedly *not* #defined at the C level.
+    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;
@@ -2092,38 +2129,15 @@ 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')
@@ -2135,11 +2149,6 @@ sub runMangler {
        require('ghc-asm.prl')
        || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm-powerpc.prl!\n");
        &mini_mangle_asm_powerpc($cc_as_o, $cc_as);
-    } elsif ($TargetPlatform =~ /^i386/) {
-       # extremely-minor OFFENSIVE mangling of non-threaded just one file
-       require('ghc-asm.prl')
-       || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm.prl!\n");
-       &mini_mangle_asm_i386($cc_as_o, $cc_as);
     }
 
     # save a copy of the .s file, even if we are carrying on...
@@ -2155,8 +2164,11 @@ 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";
+       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');
 
@@ -2235,16 +2247,10 @@ sub run_something {
        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/;
@@ -2257,7 +2263,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;
@@ -2283,7 +2288,7 @@ sub process_ghc_timings {
     local($tot_samples) = 0;
 
     while (<STATS>) {
-       if (! /Minor/ && /^\s*\d+\s+\d+\s+(\d+)\s+\d+\.\d+\%/ ) {
+       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;
@@ -2294,7 +2299,11 @@ sub process_ghc_timings {
            $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;
+        }
 
        # The presence of -? in the following pattern is only there to
        # accommodate 0.29 && <= 2.05 RTS'
@@ -2322,6 +2331,7 @@ sub process_ghc_timings {
     print STDERR "Warning: MutElapsed not found in stats file\n" unless defined($MutElapsed);
     print STDERR "Warning: GcTime inot found in stats file\n" unless defined($GcTime);
     print STDERR "Warning: GcElapsed not found in stats file\n" unless defined($GcElapsed);
+    print STDERR "Warning: total memory not found in stats file\n" unless defined($TotMem);
 
     # things we didn't necessarily expect to find
     $MaxResidency     = 0 unless defined($MaxResidency);
@@ -2341,7 +2351,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
@@ -2442,23 +2452,194 @@ 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
+       ]
+    );
+
+    # check if it's supported..
     
-    unshift(@SysImport_dir,
-           $INSTALLING ? "$InstLibDirGhc/imports/$syslib"
-                         : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/$syslib");
+    if ( !exists $Supported_syslibs{$syslib} ) {
+       print STDERR "$Pgm: no such system library (-syslib): $syslib\n";
+       $Status++;
+       return;
+    }
 
-    push(@SysLibrary_dir,
-        $INSTALLING ? ("$InstLibDirGhc")
-                       : ("$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/$syslib",
-                         "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/$syslib/cbits"));
+    # 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")
-          unless $syslib eq 'contrib' || $syslib eq 'exts' || $syslib eq 'conc';
-         #HACK! they have no cbits
+    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}
 
@@ -2528,7 +2709,7 @@ sub splitCmdLine {
 arg: while($_ = $args[0]) {
     shift(@args);
     # sigh, we have to deal with these -option arg specially here.
-    /^-(tmpdir|odir|ohi|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; };
 
@@ -2713,13 +2894,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;
@@ -2763,14 +2937,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'; &add_syslib('conc'); next arg; }; 
-                         # concurrent Haskell; implies -syslib conc
-    /^-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" --------------------------------------------
 
@@ -2806,24 +2978,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 =~ /^(exts|misc|posix)$/;
-
-                           #
-                           # The posix library is a `special' in that it relies on
-                           # the ghc system library (packed strings). Wielding our
-                           # sledgehammer, the problem is solved by silently including
-                           # the ghc system library as well.
-                           # (ToDo: `nub' -syslib list)
-                           #
                            &add_syslib($syslib);
-                           if ( $syslib eq 'posix' ) {
-                               &add_syslib('misc');
-                           } elsif ( $syslib eq 'misc' && 
-                                     $TargetName =~ /-solaris2$/ ) {
-                               # needed for Berkeley socket/nwork stuff.
-                               push(@SysLibrary, '-lnsl');
-                           }
                            next arg; };
 
     #=======================================================================
@@ -2858,10 +3013,6 @@ arg: while($_ = $Args[0]) {
     /^-D(.*)/      && do { push(@HsCpp_flags, "'-D".&grab_arg_arg(*Args,'-D',$1)."'"); next arg; };
     /^-U(.*)/      && do { push(@HsCpp_flags, "'-U".&grab_arg_arg(*Args,'-U',$1)."'"); next arg; };
 
-    /^-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; };
@@ -2871,28 +3022,23 @@ 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; };
 
     /^-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; };
 
-    /^-split-objs/     && do {
+    /^-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";
@@ -2908,21 +3054,19 @@ arg: while($_ = $Args[0]) {
                        }
                        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; };
     /^-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$/
@@ -2967,46 +3111,30 @@ arg: while($_ = $Args[0]) {
 
     # ---------------
 
-    /^(-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);
                            next arg; };
-    /^(-fshow-simplifier-progress)/
-                   && do { $Oopt_ShowSimplifierProgress = $1;
-                           next arg; };
 
     /^-fno-pedantic-bottoms$/
                    && do { $Oopt_PedanticBottoms = ''; next arg; };
 
+    /^-fno-pre-inlining$/
+                   && do { push(@HsC_flags, $_); next arg };
+
     /^-fdo-monad-eta-expansion$/
                    && do { $Oopt_MonadEtaExpansion = $_; next arg; };
 
     /^-fno-let-from-(case|app|strict-let)$/ # experimental, really (WDP 95/10)
                    && do { push(@HsC_flags, $_); next arg; };
 
-    /^(-freturn-in-regs-threshold)(.*)$/
-                   && do { local($what) = $1;
-                           local($num)  = &grab_arg_arg(*Args,$what, $2);
-                           if ($num < 2 || $num > 8) {
-                               die "Bad experimental flag: $_\n";
-                           } else {
-                               $HscOut = '-C='; # force using C compiler
-                               push(@HsC_flags, "$what$num");
-                               push(@CcRegd_flags, "-D__STG_REGS_AVAIL__=$num");
-                           }
-                           next arg; };
-
     # --------------- Warnings etc. ------
 
-    /^-fshow-import-specs/
-                   && do { push(@HsC_flags, $_); next arg; };
-
-    /^-fsignatures-required/      
-                   && do { push(@HsC_flags, $_); next arg; };
-
     /^-fwarn-(.*)$/      && do { push(@HsC_flags, $_); next arg; };
 
     /^-fno-(.*)$/   && do { push(@HsC_antiflags, "-f$1");
@@ -3021,6 +3149,10 @@ arg: while($_ = $Args[0]) {
                            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,
@@ -3130,6 +3262,7 @@ arg: while($_ = $Args[0]) {
     #---------- Linker (gcc, really) ---------------------------------------
 
     /^-static$/                && do { push(@Ld_flags, $_); next arg; };
+    /^-no-hs-main$/    && do { $NoHaskellMain=1; next arg;    };
 
     #---------- mixed cc and linker magic ----------------------------------
     # this optimisation stuff is finally sorted out later on...