[project @ 1996-06-27 15:55:53 by partain]
authorpartain <unknown>
Thu, 27 Jun 1996 16:00:09 +0000 (16:00 +0000)
committerpartain <unknown>
Thu, 27 Jun 1996 16:00:09 +0000 (16:00 +0000)
partain 1.3 changes to 960626

61 files changed:
ANNOUNCE-2.01 [new file with mode: 0644]
Makefile.in
STARTUP.in
config.guess
config.sub
configure.in
ghc/Jmakefile
ghc/Makefile.BOOT
ghc/PATCHLEVEL
ghc/README
ghc/docs/Jmakefile
ghc/docs/install_guide/installing.lit
ghc/docs/release_notes/release.lit
ghc/docs/state_interface/state-interface.verb
ghc/docs/users_guide/gone_wrong.lit
ghc/docs/users_guide/prof-compiler-options.lit
ghc/docs/users_guide/prof-output.lit
ghc/docs/users_guide/prof-rts-options.lit
ghc/docs/users_guide/profiling.lit
ghc/docs/users_guide/user.lit
ghc/docs/users_guide/utils.lit
ghc/docs/users_guide/vs_haskell.lit
ghc/driver/Jmakefile
ghc/driver/driver.lit [deleted file]
ghc/driver/ghc-asm-alpha.lprl [deleted file]
ghc/driver/ghc-asm-hppa.lprl [deleted file]
ghc/driver/ghc-asm-m68k.lprl [deleted file]
ghc/driver/ghc-asm-mips.lprl [deleted file]
ghc/driver/ghc-asm-sgi.prl [deleted file]
ghc/driver/ghc-asm-solaris.lprl [deleted file]
ghc/driver/ghc-asm-sparc.lprl [deleted file]
ghc/driver/ghc-asm.lprl
ghc/driver/ghc-iface.lprl [new file with mode: 0644]
ghc/driver/ghc-recomp.lprl [new file with mode: 0644]
ghc/driver/ghc-split.lprl
ghc/driver/ghc.lprl
ghc/includes/COptJumps.lh
ghc/includes/COptWraps.lh
ghc/includes/CostCentre.lh
ghc/includes/GranSim.lh
ghc/includes/Jmakefile
ghc/includes/Parallel.lh
ghc/includes/RtsFlags.lh
ghc/includes/RtsTypes.lh
ghc/includes/SMClosures.lh
ghc/includes/SMInfoTables.lh
ghc/includes/SMcompact.lh
ghc/includes/SMcopying.lh
ghc/includes/SMinterface.lh
ghc/includes/SMmark.lh
ghc/includes/SMupdate.lh
ghc/includes/StgMacros.lh
ghc/includes/StgTypes.lh
ghc/includes/Threads.lh
ghc/includes/config.h.in
ghc/includes/ghcSockets.h
ghc/includes/libposix.h
ghc/includes/mkNativeHdr.lc
ghc/includes/stgdefs.h
ghc/includes/stgio.h
ghc/includes/timezone.h

diff --git a/ANNOUNCE-2.01 b/ANNOUNCE-2.01
new file mode 100644 (file)
index 0000000..0fc4ab0
--- /dev/null
@@ -0,0 +1,165 @@
+            The Glasgow Haskell Compiler -- version 2.01
+            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We are proud to announce the first public release of the Glasgow
+Haskell Compiler (GHC) for the revised Haskell 1.3 language. Sources
+and binaries are freely available by anonymous FTP and on the
+World-Wide Web; details below.
+
+GHC 2.01 is a test-quality release, worth trying if you are a gung-ho
+Haskell user or if you want to ensure that we quickly fix bugs that
+affect your programs :-) We advise *AGAINST* deleting your copy of
+that old workhorse GHC 0.26 (for Haskell 1.2), and *AGAINST* relying
+on this compiler (2.01) in any way.  With your help in testing 2.01,
+we hope to release a more solid Haskell 1.3 compiler relatively soon.
+
+Haskell is "the" standard lazy functional programming language [see
+SIGPLAN Notices, May 1992].  The current language version is 1.3,
+agreed in May, 1996.
+
+The Glasgow Haskell project seeks to bring the power and elegance of
+functional programming to bear on real-world problems.  To that end,
+GHC lets you call C (including cross-system garbage collection),
+provides good profiling tools, supports ever richer I/O, and
+concurrency and parallelism.  Our goal is to make it the "tool of
+choice for real-world applications".
+
+GHC 2.01 is quite different from 0.26 (July 1995), as the new version
+number suggests.  (The 1.xx numbers are reserved for any Haskell-1.2
+compiler releases.)  Changes worth noting include:
+
+.......
+
+  * Concurrent Haskell: with this, you can build programs out of many
+    I/O-performing, interacting `threads'.  We have a draft paper
+    about Concurrent Haskell, and our forthcoming Haggis GUI toolkit
+    uses it.
+
+  * Parallel Haskell, running on top of PVM (Parallel Virtual Machine)
+    and hence portable to pretty much any parallel architecture,
+    whether shared memory or distributed memory.  With this, your
+    Haskell program runs on multiple processors, guided by `par` and
+    `seq` annotations.  The first pretty-much-everyone-can-try-it
+    parallel functional programming system!  NB: The parallel stuff is
+    "research-tool quality"... consider this an alpha release.
+
+  * "Foldr/build" deforestation (by Andy Gill) is in, as are
+    "SPECIALIZE instance" pragmas (by Patrick Sansom).
+
+  * The LibPosix library provides an even richer I/O interface than
+    the standard 1.3 I/O library.  A program like a shell or an FTP
+    client can be written in Haskell -- examples included.
+
+  * Yet more cool libraries: Readline (GNU command-line editing),
+    Socket (BSD sockets), Regex and MatchPS (GNU regular expressions).
+    By Darren Moffat and Sigbjorn Finne.
+
+  * New ports -- Linux (a.out) and MIPS (Silicon Graphics).
+
+  * NB: configuration has changed yet again -- for the better, of
+    course :-)
+
+Please see the release notes for a complete discussion of What's New.
+
+To run this release, you need a machine with 16+MB memory, GNU C
+(`gcc'), and `perl'.  We have seen GHC 0.26 work on these platforms:
+alpha-dec-osf2, hppa1.1-hp-hpux9, i386-unknown-linuxaout,
+m68k-sun-sunos4, mips-sgi-irix5, and sparc-sun-{sunos4,solaris2}.
+Similar platforms should work with minimal hacking effort.
+The installer's guide give a full what-ports-work report.
+
+Binaries are now distributed in `bundles', e.g. a "profiling bundle"
+or a "concurrency bundle" for your platform.  Just grab the ones you
+need.
+
+Once you have the distribution, please follow the pointers in
+ghc/README to find all of the documentation about this release.  NB:
+preserve modification times when un-tarring the files (no `m' option
+for tar, please)!
+
+We run mailing lists for GHC users and bug reports; to subscribe, send
+mail to glasgow-haskell-{users,bugs}-request@dcs.glasgow.ac.uk.
+Please send bug reports to glasgow-haskell-bugs.
+
+Particular thanks to: Jim Mattson (author of much of the code) who has
+now moved to HP in California; and the Turing Institute who donated a
+lot of SGI cycles for the SGI port.
+
+Simon Peyton Jones and Will Partain
+
+Dated: 95/07/24
+
+Relevant URLs on the World-Wide Web:
+
+GHC home page            http://www.dcs.glasgow.ac.uk/fp/software/ghc.html
+Glasgow FP group page     http://www.dcs.glasgow.ac.uk/fp/
+comp.lang.functional FAQ  http://www.cs.nott.ac.uk/Department/Staff/mpj/faq.html
+
+======================================================================
+How to get GHC 0.26:
+
+This release is available by anonymous FTP from the main Haskell
+archive sites, in the directory pub/haskell/glasgow:
+
+       ftp.dcs.glasgow.ac.uk  (130.209.240.50)
+       ftp.cs.chalmers.se     (129.16.227.140)
+       haskell.cs.yale.edu    (128.36.11.43)
+
+The Glasgow site is mirrored by src.doc.ic.ac.uk (146.169.43.1), in
+computing/programming/languages/haskell/glasgow.
+
+These are the available files (.gz files are gzipped) -- some are `on
+demand', ask if you don't see them:
+
+ghc-0.26-src.tar.gz    The source distribution; about 3MB.
+
+ghc-0.26.ANNOUNCE      This file.
+
+ghc-0.26.{README,RELEASE-NOTES} From the distribution; for those who
+                       want to peek before FTPing...
+
+ghc-0.26-ps-docs.tar.gz        Main GHC documents in PostScript format; in
+                       case your TeX setup doesn't agree with our
+                       DVI files...
+
+ghc-0.26-<platform>.tar.gz Basic binary distribution for a particular
+                       <platform>.  Unpack and go: you can compile
+                       and run Haskell programs with nothing but one
+                       of these files.  NB: does *not* include
+                       profiling (see below).
+
+       <platform> ==>  alpha-dec-osf2
+                       hppa1.1-hp-hpux9
+                       i386-unknown-linuxaout
+                       i386-unknown-solaris2
+                       m68k-sun-sunos4
+                       mips-sgi-irix5
+                       sparc-sun-sunos4
+                       sparc-sun-solaris2
+
+ghc-0.26-<bundle>-<platform>.tar.gz
+
+       <platform> ==>  as above
+       <bundle>   ==>  prof (profiling)
+                       conc (concurrent Haskell)
+                       par  (parallel)
+                       gran (GranSim parallel simulator)
+                       ticky (`ticky-ticky' counts -- for implementors)
+                       prof-conc (profiling for "conc[urrent]")
+                       prof-ticky (ticky for "conc[urrent]")
+
+ghc-0.26-hc-files.tar.gz Basic set of intermediate C (.hc) files for the
+                        compiler proper, the prelude, and `Hello,
+                        world'.  Used for bootstrapping the system.
+                        About 4MB.
+
+ghc-0.26-<bundle>-hc-files.tar.gz Further sets of .hc files, for
+                       building other "bundles", e.g., profiling.
+
+ghc-0.26-hi-files-<blah>.tar.gz Sometimes it's more convenient to
+                       use a different set of interface files than
+                       the ones in *-src.tar.gz.  (The installation
+                       guide will advise you of this.)
+
+We could provide diffs from previous versions of GHC, should you
+require them.  A full set would be very large (7MB).
index 3626858..93b4582 100644 (file)
@@ -31,6 +31,6 @@ Makefile: Makefile.in config.status
 config.status: configure
        $(SHELL) config.status --recheck
 configure: configure.in
-       cd $(srcdir); autoconf < configure.in > configure.new
+       cd $(srcdir) && autoconf < configure.in > configure.new
        grep -v '# Generated automatically from' < configure.new > configure
     
index 814426a..0416b7f 100644 (file)
@@ -30,15 +30,15 @@ esac
 
 for i in @DoingMkWorld@ @DoingGlaFpUtils@ @DoingLiterate@ ; do
   if [ -d $i ] ; then
-    ( set -e;                                                                  \
-      cd $i ;                                                                  \
-      echo '' ;                                                                        \
-      echo "*** configuring $i ..." ;                                          \
-      make -f Makefile.BOOT BOOT_DEFINES="-P none -S std -DTopDirPwd=$hardtop";        \
-      echo '' ;                                                                        \
-      echo "*** making Makefiles in $i ..." ;                                  \
-      make Makefile ;                                                          \
-      make Makefiles                                                           \
+    ( set -e;                                                          \
+      cd $i ;                                                          \
+      echo '' ;                                                                \
+      echo "*** configuring $i ..." ;                                  \
+      @MakeCmd@ -f Makefile.BOOT BOOT_DEFINES="-P none -S std -DTopDirPwd=$hardtop";   \
+      echo '' ;                                                                \
+      echo "*** making Makefiles in $i ..." ;                          \
+      @MakeCmd@ Makefile ;                                             \
+      @MakeCmd@ Makefiles                                              \
     )
   else
     echo warning: $i is not a directory -- doing nothing for it
@@ -49,14 +49,14 @@ done
 
 for i in @DoingMkWorld@ @DoingGlaFpUtils@ @DoingLiterate@ ; do
   if [ -d $i ] ; then
-    ( set -e;                                                                  \
-      cd $i ;                                                                  \
-      echo '' ;                                                                        \
-      echo "*** making dependencies in $i ..." ;                               \
-      make depend ;                                                            \
-      echo '' ;                                                                        \
-      echo "*** making all in $i ..." ;                                                \
-      make all                                                                 \
+    ( set -e;                                                          \
+      cd $i ;                                                          \
+      echo '' ;                                                                \
+      echo "*** making dependencies in $i ..." ;                       \
+      @MakeCmd@ depend ;                                               \
+      echo '' ;                                                                \
+      echo "*** making all in $i ..." ;                                        \
+      @MakeCmd@ all                                                    \
     )
   else
     echo warning: $i is not a directory -- doing nothing for it
@@ -67,22 +67,22 @@ done
 
 passed_in_setup="-S @MkWorldSetup@"
 
-for i in @DoingGHC@ @DoingHappy@ @DoingHaggis@ @DoingNoFib@ EndOfList ; do
+for i in @DoingGHC@ @DoingHsLibs@ @DoingHappy@ @DoingHaggis@ @DoingNoFib@ EndOfList ; do
   if [ $i = nofib ] ; then
      setup=$passed_in_setup
   else
      setup=''
   fi
   if [ -d $i ] ; then
-    ( set -e;                                                                  \
-      cd $i ;                                                                  \
-      echo '' ;                                                                        \
-      echo "*** configuring $i ..." ;                                          \
-      make -f Makefile.BOOT BOOT_DEFINES="-P $i $setup -C mkworld -DTopDirPwd=$hardtop"; \
-      echo '' ;                                                                        \
-      echo "*** making Makefiles in $i ..." ;                                  \
-      make Makefile ;                                                          \
-      make Makefiles                                                           \
+    ( set -e;                                                          \
+      cd $i ;                                                          \
+      echo '' ;                                                                \
+      echo "*** configuring $i ..." ;                                  \
+      @MakeCmd@ -f Makefile.BOOT BOOT_DEFINES="-P $i $setup -C mkworld -DTopDirPwd=$hardtop"; \
+      echo '' ;                                                                \
+      echo "*** making Makefiles in $i ..." ;                          \
+      @MakeCmd@ Makefile ;                                             \
+      @MakeCmd@ Makefiles                                              \
     )
   else
     if [ $i != EndOfList ] ; then
@@ -93,13 +93,13 @@ done
 
 # Finally, the dependencies
 
-for i in @DoingGHC@ @DoingHappy@ @DoingHaggis@ @DoingNoFib@ EndOfList ; do
+for i in @DoingGHC@ @DoingHsLibs@ @DoingHappy@ @DoingHaggis@ @DoingNoFib@ EndOfList ; do
   if [ -d $i ] ; then
-    ( set -e;                                                                  \
-      cd $i ;                                                                  \
-      echo '' ;                                                                        \
-      echo "*** making dependencies in $i ..." ;                               \
-      make depend                                                              \
+    ( set -e;                                                          \
+      cd $i ;                                                          \
+      echo '' ;                                                                \
+      echo "*** making dependencies in $i ..." ;                       \
+      @MakeCmd@ depend                                                         \
     )
   else
     if [ $i != EndOfList ] ; then
@@ -112,7 +112,7 @@ echo ''
 echo '*******************************************************************'
 echo "* Looking good! All you should need to do now is...               *"
 echo '*                                                                 *'
-for i in @DoingGHC@ @DoingHappy@ @DoingHaggis@ @DoingNoFib@ EndOfList ; do
+for i in @DoingGHC@ @DoingHsLibs@ @DoingHappy@ @DoingHaggis@ @DoingNoFib@ EndOfList ; do
     if [ $i != EndOfList ] ; then
        echo "        cd $i"
        if [ $i = nofib ] ; then
index 41f828a..c3c4e79 100644 (file)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+#   Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
 #
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
@@ -14,7 +14,7 @@
 #
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 #
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -51,14 +51,21 @@ trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
 # Note: order is significant - the case branches are not exclusive.
 
 case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
-    alpha:OSF1:V*:*)
+    alpha:OSF1:[VX]*:*)
        # After 1.2, OSF1 uses "V1.3" for uname -r.
-       echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^V//'`
+       # After 4.x, OSF1 uses "X4.x" for uname -r.
+       echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VX]//'`
        exit 0 ;;
     alpha:OSF1:*:*)
        # 1.2 uses "1.2" for uname -r.
        echo alpha-dec-osf${UNAME_RELEASE}
         exit 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-cbm-sysv4
+       exit 0;;
     amiga:NetBSD:*:*)
       echo m68k-cbm-netbsd${UNAME_RELEASE}
       exit 0 ;;
@@ -111,9 +118,15 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     VAX*:ULTRIX*:*:*)
        echo vax-dec-ultrix${UNAME_RELEASE}
        exit 0 ;;
+    mips:*:4*:UMIPS)
+       echo mips-mips-riscos4sysv
+       exit 0 ;;
     mips:*:5*:RISCos)
        echo mips-mips-riscos${UNAME_RELEASE}
        exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
     m88k:CX/UX:7*:*)
        echo m88k-harris-cxux7
        exit 0 ;;
@@ -124,12 +137,17 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        echo m88k-motorola-sysv3
        exit 0 ;;
     AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`uname -p`
+        if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88100 ] ; then
        if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
             -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
                echo m88k-dg-dgux${UNAME_RELEASE}
        else
                echo m88k-dg-dguxbcs${UNAME_RELEASE}
        fi
+        else echo i586-dg-dgux${UNAME_RELEASE}
+        fi
        exit 0 ;;
     M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
        echo m88k-dolphin-sysv3
@@ -181,10 +199,8 @@ EOF
        else
                IBM_ARCH=powerpc
        fi
-       if grep bos410 /usr/include/stdio.h >/dev/null 2>&1; then
-               IBM_REV=4.1
-       elif grep bos411 /usr/include/stdio.h >/dev/null 2>&1; then
-               IBM_REV=4.1.1
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
        else
                IBM_REV=4.${UNAME_RELEASE}
        fi
@@ -215,7 +231,7 @@ EOF
        case "${UNAME_MACHINE}" in
            9000/31? )            HP_ARCH=m68000 ;;
            9000/[34]?? )         HP_ARCH=m68k ;;
-           9000/7?? | 9000/8?7 ) HP_ARCH=hppa1.1 ;;
+           9000/7?? | 9000/8?[679] ) HP_ARCH=hppa1.1 ;;
            9000/8?? )            HP_ARCH=hppa1.0 ;;
        esac
        HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
@@ -251,13 +267,13 @@ EOF
        rm -f dummy.c dummy
        echo unknown-hitachi-hiuxwe2
        exit 0 ;;
-    9000/7??:4.3bsd:*:* | 9000/8?7:4.3bsd:*:* )
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
        echo hppa1.1-hp-bsd
        exit 0 ;;
     9000/8??:4.3bsd:*:*)
        echo hppa1.0-hp-bsd
        exit 0 ;;
-    hp7??:OSF1:*:* | hp8?7:OSF1:*:* )
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
        echo hppa1.1-hp-osf
        exit 0 ;;
     hp8??:OSF1:*:*)
@@ -308,19 +324,38 @@ EOF
     *:NetBSD:*:*)
        echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
        exit 0 ;;
+    i*:CYGWIN*:*)
+       echo i386-unknown-cygwin32
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin32
+       exit 0 ;;
     *:GNU:*:*)
        echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
        exit 0 ;;
     *:Linux:*:*)
-       # Systems without a BFD linker
-       if test -d /usr/lib/ldscripts/. ; then
-         :
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us.
+       ld_help_string=`ld --help 2>&1`
+       if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i[345]86"; then
+         echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
+       elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86linux"; then
+         echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
+       elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86coff"; then
+         echo "${UNAME_MACHINE}-unknown-linuxcoff" ; exit 0
+       elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then
+         echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
+       elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then
+         echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
+       elif test "${UNAME_MACHINE}" = "alpha" ; then
+         echo alpha-unknown-linux ; exit 0
        else
-         echo "${UNAME_MACHINE}-unknown-linuxoldld"
-         exit 0
-       fi
-       # Determine whether the default compiler is a.out or elf
-       cat >dummy.c <<EOF
+         # Either a pre-BFD a.out linker (linuxoldld) or one that does not give us
+         # useful --help.  Gcc wants to distinguish between linuxoldld and linuxaout.
+         test ! -d /usr/lib/ldscripts/. \
+           && echo "${UNAME_MACHINE}-unknown-linuxoldld" && exit 0
+         # Determine whether the default compiler is a.out or elf
+         cat >dummy.c <<EOF
 main(argc, argv)
 int argc;
 char *argv[];
@@ -333,8 +368,9 @@ char *argv[];
   return 0;
 }
 EOF
-       ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
-       rm -f dummy.c dummy;;
+         ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+         rm -f dummy.c dummy
+       fi ;;
 # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.  earlier versions
 # are messed up and put the nodename in both sysname and nodename.
     i[34]86:DYNIX/ptx:4*:*)
@@ -354,6 +390,8 @@ EOF
        elif /bin/uname -X 2>/dev/null >/dev/null ; then
                UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
                (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
                echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL
        else
                echo ${UNAME_MACHINE}-unknown-sysv32
@@ -384,19 +422,19 @@ EOF
     3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
         uname -p 2>/dev/null | grep 86 >/dev/null \
           && echo i486-ncr-sysv4 && exit 0 ;;
-    m680[234]0:LynxOS:2.2*:*)
+    m680[234]0:LynxOS:2.[23]*:*)
        echo m68k-lynx-lynxos${UNAME_RELEASE}
        exit 0 ;;
     mc68030:UNIX_System_V:4.*:*)
        echo m68k-atari-sysv4
        exit 0 ;;
-    i[34]86:LynxOS:2.2*:*)
+    i[34]86:LynxOS:2.[23]*:*)
        echo i386-lynx-lynxos${UNAME_RELEASE}
        exit 0 ;;
-    TSUNAMI:LynxOS:2.2*:*)
+    TSUNAMI:LynxOS:2.[23]*:*)
        echo sparc-lynx-lynxos${UNAME_RELEASE}
        exit 0 ;;
-    rs6000:LynxOS:2.2*:*)
+    rs6000:LynxOS:2.[23]*:*)
        echo rs6000-lynx-lynxos${UNAME_RELEASE}
        exit 0 ;;
     RM*:SINIX-*:*:*)
@@ -410,12 +448,26 @@ EOF
                echo ns32k-sni-sysv
        fi
        exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    R3000:*System_V*:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit 0 ;;
 esac
 
 #echo '(No uname command or uname output not recognized.)' 1>&2
 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
 
 cat >dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
 main ()
 {
 #if defined (sony)
@@ -479,7 +531,18 @@ main ()
 #endif
 
 #if defined (_SEQUENT_)
-  printf ("i386-sequent-ptx\n"); exit (0);
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
 #endif
 
 #if defined (vax)
index 93371be..c462f8a 100644 (file)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Configuration validation subroutine script, version 1.1.
-#   Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+#   Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
 # can handle that machine.  It does not imply ALL GNU software can. 
@@ -17,7 +17,8 @@
 #
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
 
 # As a special exception to the GNU General Public License, if you
 # distribute this file as part of a program that contains a
@@ -84,9 +85,27 @@ case $os in
                os=
                basic_machine=$1
                ;;
+       -sim | -cisco | -oki | -wec | -winbond )        # CYGNUS LOCAL
+               os=
+               basic_machine=$1
+               ;;
+       -apple*)                                        # CYGNUS LOCAL
+               os=
+               basic_machine=$1
+               ;;
+       -scout)                                         # CYGNUS LOCAL
+               ;;
+       -wrs)                                           # CYGNUS LOCAL
+               os=vxworks
+               basic_machine=$1
+               ;;
        -hiux*)
                os=-hiuxwe2
                ;;
+       -sco5)
+               os=sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+               ;;
        -sco4)
                os=-sco3.2v4
                basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
@@ -122,19 +141,31 @@ case $os in
        -windowsnt*)
                os=`echo $os | sed -e 's/windowsnt/winnt/'`
                ;;
+       -psos*)
+               os=-psos
+               ;;
 esac
 
 # Decode aliases for certain CPU-COMPANY combinations.
 case $basic_machine in
        # Recognize the basic CPU types without company name.
        # Some are omitted here because they have special meanings below.
-       tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm \
+       tahoe | i[3456]86 | i860 | m68k | m68000 | m88k | ns32k | arm \
                | arme[lb] | pyramid \
                | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
-               | alpha | we32k | ns16k | clipper | sparclite | i370 | sh \
-               | powerpc | powerpcle | sparc64 | 1750a | dsp16xx | mips64 | mipsel \
+               | alpha | we32k | ns16k | clipper | i370 | sh \
+               | powerpc | powerpcle | 1750a | dsp16xx | mips64 | mipsel \
                | pdp11 | mips64el | mips64orion | mips64orionel \
-               | sparc)
+               | sparc | sparclet | sparclite | sparc64)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m88110 | m680[01234]0 | m683?2 | m68360 | z8k | v70 | h8500 | w65) # CYGNUS LOCAL
+               basic_machine=$basic_machine-unknown
+               ;;
+       mips64vr4300 | mips64vr4300el) # CYGNUS LOCAL jsmith/vr4300
+               basic_machine=$basic_machine-unknown
+               ;;
+       mips64vr4100 | mips64vr4100el) # CYGNUS LOCAL jsmith/vr4100
                basic_machine=$basic_machine-unknown
                ;;
        # Object if more than one company name word.
@@ -143,8 +174,8 @@ case $basic_machine in
                exit 1
                ;;
        # Recognize the basic CPU types with company name.
-       vax-* | tahoe-* | i[345]86-* | i860-* | m68k-* | m68000-* | m88k-* \
-             | sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \
+       vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \
+             | sparc-* | ns32k-* | fx80-* | arm-* | arme[lb]-* | c[123]* \
              | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
              | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
              | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
@@ -152,14 +183,32 @@ case $basic_machine in
              | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \
              | mips64el-* | mips64orion-* | mips64orionel-*)
                ;;
+       m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | h8500-*) # CYGNUS LOCAL
+               ;;
+       mips64vr4300-* | mips64vr4300el-*) # CYGNUS LOCAL jsmith/vr4300
+               ;;
+       mips64vr4100-* | mips64vr4100el-*) # CYGNUS LOCAL jsmith/vr4100
+               ;;
        # Recognize the various machine names and aliases which stand
        # for a CPU type and a company and sometimes even an OS.
+       386bsd)                                         # CYGNUS LOCAL
+               basic_machine=i386-unknown
+               os=-bsd
+               ;;
        3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
                basic_machine=m68000-att
                ;;
        3b*)
                basic_machine=we32k-att
                ;;
+       a29khif)                                        # CYGNUS LOCAL
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       adobe68k)                                       # CYGNUS LOCAL
+               basic_machine=m68010-adobe
+               os=-scout
+               ;;
        alliant | fx80)
                basic_machine=fx80-alliant
                ;;
@@ -189,6 +238,18 @@ case $basic_machine in
                basic_machine=m68k-apollo
                os=-sysv
                ;;
+       apollo68bsd)                                    # CYGNUS LOCAL
+               basic_machine=m68k-apollo
+               os=-bsd
+               ;;
+       arm | armel | armeb)
+               basic_machine=arm-arm
+               os=-aout
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
        balance)
                basic_machine=ns32k-sequent
                os=-dynix
@@ -257,6 +318,10 @@ case $basic_machine in
        encore | umax | mmax)
                basic_machine=ns32k-encore
                ;;
+       es1800 | OSE68k | ose68k | ose | OSE)           # CYGNUS LOCAL
+               basic_machine=m68k-ericsson
+               os=-ose
+               ;;
        fx2800)
                basic_machine=i860-alliant
                ;;
@@ -275,6 +340,14 @@ case $basic_machine in
                basic_machine=h8300-hitachi
                os=-hms
                ;;
+       h8300xray)                                      # CYGNUS LOCAL
+               basic_machine=h8300-hitachi
+               os=-xray
+               ;;
+       h8500hms)                                       # CYGNUS LOCAL
+               basic_machine=h8500-hitachi
+               os=-hms
+               ;;
        harris)
                basic_machine=m88k-harris
                os=-sysv3
@@ -290,6 +363,22 @@ case $basic_machine in
                basic_machine=m68k-hp
                os=-hpux
                ;;
+        w89k-*)                                                # CYGNUS LOCAL
+                basic_machine=hppa1.1-winbond
+                os=-proelf
+                ;;
+        op50n-*)                                       # CYGNUS LOCAL
+                basic_machine=hppa1.1-oki
+                os=-proelf
+                ;;
+        op60c-*)                                       # CYGNUS LOCAL
+                basic_machine=hppa1.1-oki
+                os=-proelf
+                ;;
+        hppro)                                         # CYGNUS LOCAL
+                basic_machine=hppa1.1-hp
+                os=-proelf
+                ;;
        hp9k2[0-9][0-9] | hp9k31[0-9])
                basic_machine=m68000-hp
                ;;
@@ -302,27 +391,43 @@ case $basic_machine in
        hp9k8[0-9][0-9] | hp8[0-9][0-9])
                basic_machine=hppa1.0-hp
                ;;
+       hppaosf)                                        # CYGNUS LOCAL
+               basic_machine=hppa1.1-hp
+               os=-osf
+               ;;
        i370-ibm* | ibm*)
                basic_machine=i370-ibm
                os=-mvs
                ;;
 # I'm not sure what "Sysv32" means.  Should this be sysv3.2?
-       i[345]86v32)
+       i[3456]86v32)
                basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
                os=-sysv32
                ;;
-       i[345]86v4*)
+       i[3456]86v4*)
                basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
                os=-sysv4
                ;;
-       i[345]86v)
+       i[3456]86v)
                basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
                os=-sysv
                ;;
-       i[345]86sol2)
+       i[3456]86sol2)
                basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
                os=-solaris2
                ;;
+       i386mach)                                       # CYGNUS LOCAL
+               basic_machine=i386-mach
+               os=-mach
+               ;;
+       i386-vsta | vsta)                               # CYGNUS LOCAL
+               basic_machine=i386-unknown
+               os=-vsta
+               ;;
+       i386-go32 | go32)                               # CYGNUS LOCAL
+               basic_machine=i386-unknown
+               os=-go32
+               ;;
        iris | iris4d)
                basic_machine=mips-sgi
                case $os in
@@ -357,10 +462,22 @@ case $basic_machine in
        mips3*)
                basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
                ;;
+       monitor)                                        # CYGNUS LOCAL
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       msdos)                                          # CYGNUS LOCAL
+               basic_machine=i386-unknown      
+               os=-msdos
+               ;;
        ncr3000)
                basic_machine=i486-ncr
                os=-sysv4
                ;;
+       netbsd386)
+               basic_machine=i386-unknown              # CYGNUS LOCAL
+               os=-netbsd
+               ;;
        news | news700 | news800 | news900)
                basic_machine=m68k-sony
                os=-newsos
@@ -373,6 +490,10 @@ case $basic_machine in
                basic_machine=mips-sony
                os=-newsos
                ;;
+       necv70)                                         # CYGNUS LOCAL
+               basic_machine=v70-nec
+               os=-sysv
+               ;;
        next | m*-next )
                basic_machine=m68k-next
                case $os in
@@ -398,9 +519,21 @@ case $basic_machine in
                basic_machine=i960-intel
                os=-nindy
                ;;
+       mon960)
+               basic_machine=i960-intel
+               os=-mon960
+               ;;
        np1)
                basic_machine=np1-gould
                ;;
+       OSE68000 | ose68000)                            # CYGNUS LOCAL
+               basic_machine=m68000-ericsson
+               os=-ose
+               ;;
+       os68k)                                          # CYGNUS LOCAL
+               basic_machine=m68k-none
+               os=-os68k
+               ;;
        pa-hitachi)
                basic_machine=hppa1.1-hitachi
                os=-hiuxwe2
@@ -418,14 +551,18 @@ case $basic_machine in
         pc532 | pc532-*)
                basic_machine=ns32k-pc532
                ;;
-       pentium | p5 | p6)
-               # We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium
+       pentium | p5)
                basic_machine=i586-intel
                ;;
-       pentium-* | p5-* | p6-*)
-               # We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium
+       pentiumpro | p6)
+               basic_machine=i686-intel
+               ;;
+       pentium-* | p5-*)
                basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
                ;;
+       pentiumpro-* | p6-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
        k5)
                # We don't have specific support for AMD's K5 yet, so just call it a Pentium
                basic_machine=i586-amd
@@ -452,12 +589,20 @@ case $basic_machine in
        ps2)
                basic_machine=i386-ibm
                ;;
+       rom68k)                                         # CYGNUS LOCAL
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
        rm[46]00)
                basic_machine=mips-siemens
                ;;
        rtpc | rtpc-*)
                basic_machine=romp-ibm
                ;;
+       sa29200)                                        # CYGNUS LOCAL
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
        sequent)
                basic_machine=i386-sequent
                ;;
@@ -465,6 +610,10 @@ case $basic_machine in
                basic_machine=sh-hitachi
                os=-hms
                ;;
+       sparclite-wrs)                                  # CYGNUS LOCAL
+               basic_machine=sparclite-wrs
+               os=-vxworks
+               ;;
        sps7)
                basic_machine=m68k-bull
                os=-sysv2
@@ -472,6 +621,13 @@ case $basic_machine in
        spur)
                basic_machine=spur-unknown
                ;;
+       st2000)                                         # CYGNUS LOCAL
+               basic_machine=m68k-tandem
+               ;;
+       stratus)                                        # CYGNUS LOCAL
+               basic_machine=i860-stratus
+               os=-sysv4
+               ;;
        sun2)
                basic_machine=m68000-sun
                ;;
@@ -527,6 +683,10 @@ case $basic_machine in
                basic_machine=a29k-nyu
                os=-sym1
                ;;
+       v810 | necv810)                                 # CYGNUS LOCAL
+               basic_machine=v810-nec
+               os=-none
+               ;;
        vaxv)
                basic_machine=vax-dec
                os=-sysv
@@ -547,6 +707,10 @@ case $basic_machine in
                basic_machine=a29k-wrs
                os=-vxworks
                ;;
+       w65*)                                           # CYGNUS LOCAL
+               basic_machine=w65-wdc
+               os=-none
+               ;;
        xmp)
                basic_machine=xmp-cray
                os=-unicos
@@ -554,6 +718,10 @@ case $basic_machine in
         xps | xps100)
                basic_machine=xps100-honeywell
                ;;
+       z8k-*-coff)                                     # CYGNUS LOCAL
+               basic_machine=z8k-unknown
+               os=-sim
+               ;;
        none)
                basic_machine=none-none
                os=-none
@@ -561,6 +729,15 @@ case $basic_machine in
 
 # Here we handle the default manufacturer of certain CPU types.  It is in
 # some cases the only manufacturer, in others, it is the most popular.
+       w89k)                                           # CYGNUS LOCAL
+               basic_machine=hppa1.1-winbond
+               ;;
+       op50n)                                          # CYGNUS LOCAL
+               basic_machine=hppa1.1-oki
+               ;;
+       op60c)                                          # CYGNUS LOCAL
+               basic_machine=hppa1.1-oki
+               ;;
        mips)
                basic_machine=mips-mips
                ;;
@@ -591,6 +768,12 @@ case $basic_machine in
        orion105)
                basic_machine=clipper-highlevel
                ;;
+       mac | mpw | mac-mpw)                            # CYGNUS LOCAL
+               basic_machine=m68k-apple
+               ;;
+       pmac | pmac-mpw)                                # CYGNUS LOCAL
+               basic_machine=powerpc-apple
+               ;;
        *)
                echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
                exit 1
@@ -632,17 +815,27 @@ case $os in
        # Each alternative MUST END IN A *, to match a version number.
        # -sysv* is not here because it comes later, after sysvr4.
        -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-             | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[345]* \
+             | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[3456]* \
              | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
-             | -amigados* | -msdos* | -newsos* | -unicos* | -aos* \
-             | -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \
+             | -amigados* | -msdos* | -moss* | -newsos* | -unicos* | -aos* | -aof* \
+             | -nindy* | -mon960* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \
              | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \
              | -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* \
              | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
              | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
-             | -udi* | -eabi* | -lites* )
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -cygwin32* | -pe* | -psos*)
        # Remember, each alternative MUST END IN *, to match a version number.
                ;;
+       # CYGNUS LOCAL
+       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+             | -windows* | -osx | -abug |  -netware* | -proelf | -os9* \
+             | -macos* | -mpw* | -magic*)
+               ;;
+       -mac*)
+               os=`echo $os | sed -e 's|mac|macos|'`
+               ;;
+       # END CYGNUS LOCAL
        -sunos5*)
                os=`echo $os | sed -e 's|sunos5|solaris2|'`
                ;;
@@ -664,9 +857,15 @@ case $os in
        -acis*)
                os=-aos
                ;;
+       -386bsd)                                        # CYGNUS LOCAL
+               os=-bsd
+               ;;
        -ctix* | -uts*)
                os=-sysv
                ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
        # Preserve the version number of sinix5.
        -sinix5.*)
                os=`echo $os | sed -e 's|sinix|sysv|'`
@@ -692,6 +891,12 @@ case $os in
        # This must come after -sysvr4.
        -sysv*)
                ;;
+       -ose*)                                          # CYGNUS LOCAL
+               os=-ose
+               ;;
+       -es1800*)                                       # CYGNUS LOCAL
+               os=-ose
+               ;;
        -xenix)
                os=-xenix
                ;;
@@ -741,6 +946,12 @@ case $basic_machine in
                # default.
                # os=-sunos4
                ;;
+       m68*-cisco)                                     # CYGNUS LOCAL
+               os=-aout
+               ;;
+       mips*-cisco)                                    # CYGNUS LOCAL
+               os=-elf
+               ;;
        *-tti)  # must be before sparc entry or we get the wrong os.
                os=-sysv3
                ;;
@@ -750,6 +961,15 @@ case $basic_machine in
        *-ibm)
                os=-aix
                ;;
+       *-wec)                                          # CYGNUS LOCAL
+               os=-proelf
+               ;;
+       *-winbond)                                      # CYGNUS LOCAL
+               os=-proelf
+               ;;
+       *-oki)                                          # CYGNUS LOCAL
+               os=-proelf
+               ;;
        *-hp)
                os=-hpux
                ;;
@@ -774,6 +994,9 @@ case $basic_machine in
        m88k-omron*)
                os=-luna
                ;;
+       *-next )
+               os=-nextstep
+               ;;
        *-sequent)
                os=-ptx
                ;;
@@ -807,6 +1030,15 @@ case $basic_machine in
        *-masscomp)
                os=-rtu
                ;;
+       *-rom68k)                                       # CYGNUS LOCAL
+               os=-coff
+               ;;
+       *-*bug)                                         # CYGNUS LOCAL
+               os=-coff
+               ;;
+       *-apple)                                        # CYGNUS LOCAL
+               os=-macos
+               ;;
        *)
                os=-none
                ;;
@@ -825,6 +1057,9 @@ case $basic_machine in
                        -sunos*)
                                vendor=sun
                                ;;
+                       -bosx*)                         # CYGNUS LOCAL
+                               vendor=bull
+                               ;;
                        -lynxos*)
                                vendor=lynx
                                ;;
@@ -858,6 +1093,15 @@ case $basic_machine in
                        -vxworks*)
                                vendor=wrs
                                ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+                       -hms*)                          # CYGNUS LOCAL
+                               vendor=hitachi
+                               ;;
+                       -mpw* | -macos*)                # CYGNUS LOCAL
+                               vendor=apple
+                               ;;
                esac
                basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
                ;;
index c3f058c..3a57a3c 100644 (file)
@@ -17,7 +17,8 @@ AC_INIT(STARTUP.in)
 #
 # Prepare to generate the following header files
 #
-AC_CONFIG_HEADER(ghc/includes/config.h literate/config.h)
+AC_CONFIG_HEADER(ghc/includes/config.h)
+# and  literate/config.h ???
 # ToDo !!!!!!!!!!!!!!!!
 #
 # No, we don't do `--srcdir'...
@@ -27,15 +28,16 @@ if test x"$srcdir" != 'x.' ; then
 fi
 
 # -------------------------------------------------------------------------
-dnl ** choose what blobs to build (ghc,haggis,happy,nofib,????)
+dnl ** choose what blobs to build (ghc,hslibs,haggis,happy,nofib,????)
 
 # set to the name for the dir if doing it, otherwise empty
 DoingGHC='ghc'
+DoingHsLibs=''
 DoingNoFib=''
 DoingHappy=''
 DoingHaggis=''
+DoingLiterate=''
 # the following are not normally changed
-DoingLiterate='literate'
 DoingMkWorld='mkworld'
 DoingGlaFpUtils='glafp-utils'
 
@@ -48,7 +50,7 @@ AC_ARG_ENABLE(ghc,
 **********************************************************************
 
 First, select *which* of the tools you want to build,
-with --{enable,disable}-{ghc,nofib,happy,haggis}.
+with --{enable,disable}-{ghc,hslibs,nofib,happy,haggis}.
 (The default is: only GHC (Glasgow Haskell compiler).)
 
 Second, you may set one of a few applies-in-all-cases options.
@@ -91,6 +93,26 @@ if test "xxx$DoingGHC" = 'xxx' ; then
 #   ghc_includes_config_h=''
 fi
 
+AC_ARG_ENABLE(hslibs,
+   [--enable-hslibs   build suite of Haskell libraries],
+   [case "$enableval" in
+        yes) DoingHsLibs='hslibs'
+             ;;
+        no)  DoingHsLibs=''
+             ;;
+        *)   echo "I don't understand this option: --enable-hslibs=$enableval"
+             exit 1
+             ;;
+    esac])
+if test "xxx$DoingHsLibs" = 'xxxhslibs' -a \( ! -d hslibs \) ; then
+    DoingHsLibs=''
+    echo 'Doing --disable-hslibs, as there is no hslibs directory'
+fi
+hslibs_mkworld_site_hslibs_jm='hslibs/mkworld/site-hslibs.jm'
+if test "xxx$DoingHsLibs" = 'xxx' ; then
+    hslibs_mkworld_site_hslibs_jm=''
+fi
+
 AC_ARG_ENABLE(nofib,
    [--enable-nofib    build NoFib suite as part of Glasgow FP tools],
    [case "$enableval" in
@@ -128,7 +150,7 @@ if test "xxx$DoingHappy" = 'xxxhappy' -a \( ! -d happy \) ; then
 fi
 
 AC_ARG_ENABLE(haggis,
-   [--disable-haggis  build Haggis GUI toolkit as part of Glasgow FP tools],
+   [--enable-haggis   build Haggis GUI toolkit as part of Glasgow FP tools],
    [case "$enableval" in
         yes) DoingHaggis='haggis'
              ;;
@@ -194,6 +216,7 @@ if test "xxx$DoingGlaFpUtils" = 'xxxglafp-utils' -a \( ! -d glafp-utils \) ; the
 fi
 
 AC_SUBST(DoingGHC)
+AC_SUBST(DoingHsLibs)
 AC_SUBST(DoingNoFib)
 AC_SUBST(DoingHappy)
 AC_SUBST(DoingHaggis)
@@ -207,7 +230,7 @@ dnl ** choose host(/target/build) platform
 # Partly stolen from GCC "configure".
 #
 if test "x$target" = xNONE ; then
-    if test "x$nonopt" != xNONE; then
+    if test "x$nonopt" != xNONE ; then
         target=$nonopt
     else
         # This way of testing the result of a command substitution is
@@ -217,8 +240,7 @@ if test "x$target" = xNONE ; then
         else
             echo 'Config.guess failed to determine the host type.  You need \
 to specify one.' 1>&2
-            if [ -r config.status ]
-            then
+            if test -r config.status ; then
                 tail +2 config.status 1>&2
             fi
             exit 1
@@ -254,7 +276,7 @@ fi
 # We also record the architecture, vendor, and operating system (OS)
 # separately.
 case $HostPlatform in
-alpha-dec-osf1* | alpha-dec-osf2*)
+alpha-dec-osf[[1234]]*)
        HostPlatform=alpha-dec-osf1 # canonicalise for our purposes
        TargetPlatform=alpha-dec-osf1 # this will work for now... (hack)
        BuildPlatform=alpha-dec-osf1 #hack
@@ -272,7 +294,7 @@ hppa1.1-hp-hpux*)
         HostVendor_CPP='hp'
         HostOS_CPP='hpux'
         ;;
-i386-*-linuxaout*)
+i[[3456]]86-*-linuxaout*)
        HostPlatform=i386-unknown-linuxaout # hack again
        TargetPlatform=i386-unknown-linuxaout
        BuildPlatform=i386-unknown-linuxaout
@@ -281,16 +303,7 @@ i386-*-linuxaout*)
         HostVendor_CPP='unknown'
         HostOS_CPP='linuxaout'
         ;;
-i486-*-linuxaout*)
-       HostPlatform=i386-unknown-linuxaout # hack again: NB: name for arch is *i386*!
-       TargetPlatform=i386-unknown-linuxaout
-       BuildPlatform=i386-unknown-linuxaout
-        HostPlatform_CPP='i386_unknown_linuxaout'
-        HostArch_CPP='i386'
-        HostVendor_CPP='unknown'
-        HostOS_CPP='linuxaout'
-        ;;
-i386-*-linux*)
+i[[3456]]86-*-linux*)
        HostPlatform=i386-unknown-linux # hack again
        TargetPlatform=i386-unknown-linux
        BuildPlatform=i386-unknown-linux
@@ -299,40 +312,25 @@ i386-*-linux*)
         HostVendor_CPP='unknown'
         HostOS_CPP='linux'
         ;;
-i486-*-linux*)
-       HostPlatform=i386-unknown-linux # hack again: NB: name for arch is *i386*!
-       TargetPlatform=i386-unknown-linux
-       BuildPlatform=i386-unknown-linux
-        HostPlatform_CPP='i386_unknown_linux'
-        HostArch_CPP='i386'
-        HostVendor_CPP='unknown'
-        HostOS_CPP='linux'
-        ;;
-i386-*-freebsd*)
-        HostPlatform_CPP='i386_unknown_freebsd'
-        HostArch_CPP='i386'
-        HostVendor_CPP='unknown'
-        HostOS_CPP='freebsd'
-        ;;
-i486-*-freebsd*)
+i[[3456]]86-*-freebsd*)
+       HostPlatform=i386-unknown-freebsd # hack again
+       TargetPlatform=i386-unknown-freebsd
+       BuildPlatform=i386-unknown-freebsd
         HostPlatform_CPP='i386_unknown_freebsd'
         HostArch_CPP='i386'
         HostVendor_CPP='unknown'
         HostOS_CPP='freebsd'
         ;;
-i386-*-netbsd*)
+i[[3456]]86-*-netbsd*)
+       HostPlatform=i386-unknown-netbsd # hack again
+       TargetPlatform=i386-unknown-netbsd
+       BuildPlatform=i386-unknown-netbsd
         HostPlatform_CPP='i386_unknown_netbsd'
         HostArch_CPP='i386'
         HostVendor_CPP='unknown'
         HostOS_CPP='netbsd'
         ;;
-i486-*-netbsd*)
-        HostPlatform_CPP='i386_unknown_netbsd'
-        HostArch_CPP='i386'
-        HostVendor_CPP='unknown'
-        HostOS_CPP='netbsd'
-        ;;
-i386-*-solaris2*)
+i[[3456]]86-*-solaris2*)
        HostPlatform=i386-unknown-solaris2 # hack again
        TargetPlatform=i386-unknown-solaris2
        BuildPlatform=i386-unknown-solaris2
@@ -353,7 +351,7 @@ m68k-next-nextstep3)
         HostVendor_CPP='next'
         HostOS_CPP='nextstep3'
         ;;
-i386-next-nextstep3)
+i[[3456]]86-next-nextstep3)
        HostPlatform=i386-next-nextstep3 # hack again
        TargetPlatform=i386-next-nextstep3
        BuildPlatform=i386-next-nextstep3
@@ -617,6 +615,10 @@ if test -z "$YaccCmd"; then
     fi
 fi
 
+dnl ** Find lex command (lex or flex) and library (-ll or -lfl)
+#
+AC_PROG_LEX
+
 #--------------------------------------------------------------
 WithHc='haskell-compiler-unspecified'
 WithHcType='HC_UNSPECIFIED'
@@ -689,14 +691,37 @@ esac
 AC_SUBST(WithHc)
 AC_SUBST(WithHcType)
 
+dnl ** Possibly use something else instead of 'gcc'.
+WhatGccIsCalled=gcc
+AC_ARG_WITH(gcc,
+   [--with-gcc=<gcc command>
+       Use a different command instead of 'gcc' for the GNU C compiler.],
+   [HaveGcc=YES; WhatGccIsCalled="$withval"])
+AC_SUBST(WhatGccIsCalled)
+
+dnl ** Choose which make to use (default 'make -r')
+MakeCmd='make -r'
+AC_ARG_WITH(make,
+   [ 
+--with-make=<make command> 
+       Use an alternate command instead of 'make'.  This is useful
+       when GNU make is required (for instance when the default make
+       supplied by the system won't work, as is the case on FreeBSD
+       and NetBSD).  You probably want to include the '-r' flag with
+       make, to exclude implicit suffix rules.],
+   [MakeCmd="$withval"]) 
+AC_SUBST(MakeCmd)
+
 dnl ** possibly choose a different tmpdir (default /tmp)
 # let the user decide where the best tmpdir is
 # /tmp is the default; /usr/tmp is sometimes a good choice.
 # Very site-specific.
 TmpDir='/tmp'
 AC_ARG_WITH(tmpdir,
-   [--with-tmpdir=<temp directory> Use an alternative directory for
-temporary files (presumably because /tmp is too small).],
+   [
+--with-tmpdir=<temp directory> 
+       Use an alternative directory for temporary files (presumably
+       because /tmp is too small).],
    [TmpDir="$withval"])
 AC_SUBST(TmpDir)
 
@@ -707,8 +732,9 @@ HcMaxHeapWasSet='NO'
 HcMaxHeap='0'
 AC_ARG_WITH(max-heap,
    [
---with-max-heap=<heap size, e.g., 32m> Do all Haskell compilations
-with a heap of this size.  (If you've got it, flaunt it.)],
+--with-max-heap=<heap size, e.g., 32m> 
+       Do all Haskell compilations with a heap of this size.  (If
+       you've got it, flaunt it.)],
    [HcMaxHeapWasSet='YES'
     HcMaxHeap="$withval"])
 AC_SUBST(HcMaxHeapWasSet)
@@ -769,6 +795,9 @@ elif $ArCmd clq conftest.a >/dev/null 2>/dev/null; then
 elif $ArCmd cq conftest.a >/dev/null 2>/dev/null; then
     ArCmd="$ArCmd cq"
     NeedRanLib='YES'
+elif $ArCmd cq conftest.a 2>&1 | grep 'no archive members specified' >/dev/null 2>/dev/null; then
+    ArCmd="$ArCmd cq"
+    NeedRanLib='YES'
 else
     echo "I can't figure out how to use your $ArCmd"
     exit 1
@@ -815,21 +844,6 @@ dnl ** determine the type of signal()
 #
 AC_TYPE_SIGNAL
 #
-dnl ** decide whether or not flex lexers need to be linked with -lfl
-#
-AC_CHECK_LIB(fl,yywrap,
-    FlexLibAvailable='YES',
-    FlexLibAvailable='NO')
-AC_SUBST(FlexLibAvailable)
-#
-dnl ** Decide whether or not lex lexers need to be linked with -ll
-# (Linux, for example, does not have "lex", only "flex")
-#
-AC_CHECK_LIB(l,yywrap,
-    LexLibAvailable='YES',
-    LexLibAvailable='NO')
-AC_SUBST(LexLibAvailable)
-#
 dnl ** check for specific library functions that we are interested in
 #
 AC_CHECK_FUNCS(access ftime getclock getpagesize getrusage gettimeofday mktime mprotect setitimer stat sysconf timelocal times vadvise vfork)
@@ -1047,224 +1061,226 @@ AC_ARG_ENABLE(gc-du,
              ;;
     esac])
 
-dnl  some seds only allow 99 commands, meaning no more
-dnl  than 99 AC_SUBSTs.  AARRGGHH!!
-dnl AC_ARG_ENABLE(user-way-a,
-dnl    [--enable-user-way-a    build for \`user way a' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_a='YES'
-dnl              ;;
-dnl         no)  GhcBuild_a='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-a=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-b,
-dnl    [--enable-user-way-b    build for \`user way b' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_b='YES'
-dnl              ;;
-dnl         no)  GhcBuild_b='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-b=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-c,
-dnl    [--enable-user-way-c    build for \`user way c' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_c='YES'
-dnl              ;;
-dnl         no)  GhcBuild_c='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-c=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-d,
-dnl    [--enable-user-way-d    build for \`user way d' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_d='YES'
-dnl              ;;
-dnl         no)  GhcBuild_d='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-d=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-e,
-dnl    [--enable-user-way-e    build for \`user way e' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_e='YES'
-dnl              ;;
-dnl         no)  GhcBuild_e='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-e=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-f,
-dnl    [--enable-user-way-f    build for \`user way f' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_f='YES'
-dnl              ;;
-dnl         no)  GhcBuild_f='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-f=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-g,
-dnl    [--enable-user-way-g    build for \`user way g' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_g='YES'
-dnl              ;;
-dnl         no)  GhcBuild_g='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-g=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-h,
-dnl    [--enable-user-way-h    build for \`user way h' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_h='YES'
-dnl              ;;
-dnl         no)  GhcBuild_h='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-h=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-i,
-dnl    [--enable-user-way-i    build for \`user way i' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_i='YES'
-dnl              ;;
-dnl         no)  GhcBuild_i='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-i=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-j,
-dnl    [--enable-user-way-j    build for \`user way j' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_j='YES'
-dnl              ;;
-dnl         no)  GhcBuild_j='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-j=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-k,
-dnl    [--enable-user-way-k    build for \`user way k' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_k='YES'
-dnl              ;;
-dnl         no)  GhcBuild_k='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-k=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-l,
-dnl    [--enable-user-way-l    build for \`user way l' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_l='YES'
-dnl              ;;
-dnl         no)  GhcBuild_l='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-l=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-m,
-dnl    [--enable-user-way-m    build for \`user way m' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_m='YES'
-dnl              ;;
-dnl         no)  GhcBuild_m='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-m=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-n,
-dnl    [--enable-user-way-n    build for \`user way n' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_n='YES'
-dnl              ;;
-dnl         no)  GhcBuild_n='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-n=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-o,
-dnl    [--enable-user-way-o    build for \`user way o' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_o='YES'
-dnl              ;;
-dnl         no)  GhcBuild_o='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-o=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-A,
-dnl    [--enable-user-way-A    build for \`user way A' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_A='YES'
-dnl              ;;
-dnl         no)  GhcBuild_A='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-A=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-dnl AC_ARG_ENABLE(user-way-B,
-dnl    [--enable-user-way-B    build for \`user way B' (mostly for implementors)],
-dnl    [case "$enableval" in
-dnl         yes) GhcBuild_B='YES'
-dnl              ;;
-dnl         no)  GhcBuild_B='NO'
-dnl              ;;
-dnl         *)   echo "I don't understand this option: --enable-user-way-B=$enableval"
-dnl              exit 1
-dnl              ;;
-dnl     esac])
-dnl 
-AC_SUBST(GhcBuild_normal)
-AC_SUBST(GhcBuild_p)
-AC_SUBST(GhcBuild_t)
-AC_SUBST(GhcBuild_u)
-AC_SUBST(GhcBuild_mc)
-AC_SUBST(GhcBuild_mr)
-AC_SUBST(GhcBuild_mt)
-AC_SUBST(GhcBuild_mp)
-AC_SUBST(GhcBuild_mg)
-AC_SUBST(GhcBuild_2s)
-AC_SUBST(GhcBuild_1s)
-AC_SUBST(GhcBuild_du)
+AC_ARG_ENABLE(user-way-a,
+   [--enable-user-way-a    build for \`user way a' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_a='YES'
+             ;;
+        no)  GhcBuild_a='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-a=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-b,
+   [--enable-user-way-b    build for \`user way b' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_b='YES'
+             ;;
+        no)  GhcBuild_b='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-b=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-c,
+   [--enable-user-way-c    build for \`user way c' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_c='YES'
+             ;;
+        no)  GhcBuild_c='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-c=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-d,
+   [--enable-user-way-d    build for \`user way d' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_d='YES'
+             ;;
+        no)  GhcBuild_d='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-d=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-e,
+   [--enable-user-way-e    build for \`user way e' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_e='YES'
+             ;;
+        no)  GhcBuild_e='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-e=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-f,
+   [--enable-user-way-f    build for \`user way f' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_f='YES'
+             ;;
+        no)  GhcBuild_f='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-f=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-g,
+   [--enable-user-way-g    build for \`user way g' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_g='YES'
+             ;;
+        no)  GhcBuild_g='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-g=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-h,
+   [--enable-user-way-h    build for \`user way h' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_h='YES'
+             ;;
+        no)  GhcBuild_h='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-h=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-i,
+   [--enable-user-way-i    build for \`user way i' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_i='YES'
+             ;;
+        no)  GhcBuild_i='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-i=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-j,
+   [--enable-user-way-j    build for \`user way j' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_j='YES'
+             ;;
+        no)  GhcBuild_j='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-j=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-k,
+   [--enable-user-way-k    build for \`user way k' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_k='YES'
+             ;;
+        no)  GhcBuild_k='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-k=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-l,
+   [--enable-user-way-l    build for \`user way l' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_l='YES'
+             ;;
+        no)  GhcBuild_l='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-l=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-m,
+   [--enable-user-way-m    build for \`user way m' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_m='YES'
+             ;;
+        no)  GhcBuild_m='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-m=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-n,
+   [--enable-user-way-n    build for \`user way n' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_n='YES'
+             ;;
+        no)  GhcBuild_n='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-n=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-o,
+   [--enable-user-way-o    build for \`user way o' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_o='YES'
+             ;;
+        no)  GhcBuild_o='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-o=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-A,
+   [--enable-user-way-A    build for \`user way A' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_A='YES'
+             ;;
+        no)  GhcBuild_A='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-A=$enableval"
+             exit 1
+             ;;
+    esac])
+
+AC_ARG_ENABLE(user-way-B,
+   [--enable-user-way-B    build for \`user way B' (mostly for implementors)],
+   [case "$enableval" in
+        yes) GhcBuild_B='YES'
+             ;;
+        no)  GhcBuild_B='NO'
+             ;;
+        *)   echo "I don't understand this option: --enable-user-way-B=$enableval"
+             exit 1
+             ;;
+    esac])
+
+dnl We do not use AC_SUBST to communicate the GhcBuild_* info,
+dnl as some seds (notably OSF) only allow 99 commands (!!!).
+dnl We will do the equivalent by a HACK further down.
+
+dnl AC_SUBST(GhcBuild_normal)
+dnl AC_SUBST(GhcBuild_p)
+dnl AC_SUBST(GhcBuild_t)
+dnl AC_SUBST(GhcBuild_u)
+dnl AC_SUBST(GhcBuild_mc)
+dnl AC_SUBST(GhcBuild_mr)
+dnl AC_SUBST(GhcBuild_mt)
+dnl AC_SUBST(GhcBuild_mp)
+dnl AC_SUBST(GhcBuild_mg)
+dnl AC_SUBST(GhcBuild_2s)
+dnl AC_SUBST(GhcBuild_1s)
+dnl AC_SUBST(GhcBuild_du)
 dnl AC_SUBST(GhcBuild_a)
 dnl AC_SUBST(GhcBuild_b)
 dnl AC_SUBST(GhcBuild_c)
@@ -1291,7 +1307,7 @@ dnl ** which Haskell compiler to bootstrap GHC with?
 # first, the defaults...
 WithGhcHc='haskell-compiler-unspecified'
 WithGhcHcType='HC_UNSPECIFIED'
-GhcBuilderVersion='26'
+GhcBuilderVersion='28'
 
 AC_ARG_WITH(hc-for-ghc,
    [
@@ -1534,9 +1550,100 @@ AC_ARG_ENABLE(ghci,
     esac])
 AC_SUBST(BuildGHCI)
 
+# Here, by HACK means, we dump all the GhcBuild_ info
+# into a file.  See comment above.
+rm -f ghc/mkworld/buildinfo.jm
+echo creating ghc/mkworld/buildinfo.jm
+cat > ghc/mkworld/buildinfo.jm <<EOF
+XCOMM ** DO NOT EDIT! **
+XCOMM This file is obliterated every time 'configure' is run!
+
+EOF
+for xx in normal p t u mc mr mt mp mg 2s 1s du a b c d e f g h i j k l m n o A B ; do
+    eval "yy=\$GhcBuild_$xx"
+    echo "#ifndef GhcBuild_$xx"     >> ghc/mkworld/buildinfo.jm
+    echo "#define GhcBuild_$xx $yy" >> ghc/mkworld/buildinfo.jm
+    echo "#endif"                  >> ghc/mkworld/buildinfo.jm
+done
+
 # here ends a very big if DoingGHC = 'ghc' ...
 fi
 
+# -------------------------------------------------------------------------
+dnl
+dnl * `HsLibs' CONFIGURATION STUFF
+
+if test "xxx$DoingHsLibs" = 'xxxhslibs' ; then
+# a very big "if"!
+
+dnl ** which Haskell compiler to use on hslibs?
+WithHsLibsHc='haskell-compiler-unspecified'
+WithHsLibsHcType='HC_UNSPECIFIED'
+
+AC_ARG_WITH(hc-for-hslibs,
+   [
+*******************************************************************
+** \`HsLibs' HASKELL LIBRARIES OPTIONS:
+
+The Haskell compiler to compile the Haskell Libraries suite; this
+option, if used, overrides --with-hc=<...>:
+
+    --with-hc-for-hslibs=<Haskell compiler>
+          ghc*     => Glasgow Haskell invoked by the name given
+                      and you want to use it un-installed ("in-place").],
+   [case "$withval" in
+        ghc* | glhc* )
+                WithHsLibsHc=$withval
+                ;;
+        in-place )
+                WithHsLibsHc='IN-PLACE'
+                ;;
+        *)      echo "I don't understand this option: --with-hc-for-hslibs=$withval"
+                exit 1
+                ;;
+    esac])
+
+# make sure that what they said makes sense.... set WithHsLibsHcType
+case $WithHsLibsHc in
+    haskell-compiler-unspecified ) # maybe they said something earlier...
+           if test $WithHc = 'haskell-compiler-unspecified' ; then
+               echo "Neither --with-hc nor --with-hc-for-hslibs was properly set"
+               exit 1
+           fi
+           ;;
+    ghc* | glhc* )
+           WithHsLibsHcType='HC_GLASGOW_GHC'
+            AC_CHECK_PROG(have_ghc_hslibs,$WithHsLibsHc,$ac_dir/$ac_word)
+            if test -z "$have_ghc_hslibs"; then
+                echo "Can't find Glasgow Haskell to compile HsLibs with: $WithHsLibsHc"
+               exit 1
+            fi
+            ;;
+    IN-PLACE) WithHsLibsHcType='HC_GLASGOW_GHC'
+           ;;
+esac
+AC_SUBST(WithHsLibsHc)
+AC_SUBST(WithHsLibsHcType)
+
+# Here, by HACK means, we dump all the GhcBuild_ info
+# into a file.  See comment above.
+rm -f hslibs/mkworld/buildinfo.jm
+echo creating hslibs/mkworld/buildinfo.jm
+cat > hslibs/mkworld/buildinfo.jm <<EOF
+XCOMM ** DO NOT EDIT! **
+XCOMM This file is obliterated every time 'configure' is run!
+
+EOF
+dnl Do not really know what to put here:
+dnl for xx in normal p t u mc mr mt mp mg 2s 1s du a b c d e f g h i j k l m n o A B ; do
+dnl     eval "yy=\$GhcBuild_$xx"
+dnl    echo "#ifndef GhcBuild_$xx"     >> ghc/mkworld/buildinfo.jm
+dnl    echo "#define GhcBuild_$xx $yy" >> ghc/mkworld/buildinfo.jm
+dnl    echo "#endif"               >> ghc/mkworld/buildinfo.jm
+dnl done
+
+# here ends a very big if DoingHsLibs = 'hslibs' ...
+fi
 #
 # -------------------------------------------------------------------------
 dnl
@@ -1816,8 +1923,7 @@ fi
 IncludeRealNoFibTests='YES'    # defaults
 IncludeSpectralNoFibTests='YES'
 IncludeImaginaryNoFibTests='YES'
-IncludePENDINGNoFibTests='NO'
-IncludeUNUSEDNoFibTests='NO'
+IncludeSpecialiseNoFibTests='NO'
 IncludeGHC_ONLYNoFibTests='NO'
 IncludePRIVATENoFibTests='NO'
 IncludeParallelNoFibTests='NO'
@@ -1830,15 +1936,13 @@ only if using GHC):
 
 --enable-all-tests    do *all* tests],
    [case "$enableval" in
-        yes) IncludePENDINGNoFibTests='YES'
-            IncludeUNUSEDNoFibTests='YES'
-            IncludeGHC_ONLYNoFibTests='YES'
+        yes) IncludeGHC_ONLYNoFibTests='YES'
+            IncludeSpecialiseNoFibTests='YES'
             IncludePRIVATENoFibTests='YES'
             IncludeParallelNoFibTests='YES'
              ;;
-        no) IncludePENDINGNoFibTests='NO'
-            IncludeUNUSEDNoFibTests='NO'
-            IncludeGHC_ONLYNoFibTests='NO'
+        no)  IncludeGHC_ONLYNoFibTests='NO'
+            IncludeSpecialiseNoFibTests='NO'
             IncludePRIVATENoFibTests='NO'
             IncludeParallelNoFibTests='NO'
 
@@ -1892,38 +1996,26 @@ AC_ARG_ENABLE(real-tests,
              ;;
     esac])
 
-AC_ARG_ENABLE(PENDING-tests,
-   [--enable-PENDING-tests    include PENDING tests],
-   [case "$enableval" in
-        yes) IncludePENDINGNoFibTests='YES'
-             ;;
-        no)  IncludePENDINGNoFibTests='NO'
-             ;;
-        *)   echo "I don't understand this option: --enable-PENDING-tests=$enableval"
-             exit 1
-             ;;
-    esac])
-
-AC_ARG_ENABLE(UNUSED-tests,
-   [--enable-UNUSED-tests     include UNUSED tests],
+AC_ARG_ENABLE(GHC-ONLY-tests,
+   [--enable-GHC-ONLY-tests   include GHC_ONLY tests],
    [case "$enableval" in
-        yes) IncludeUNUSEDNoFibTests='YES'
+        yes) IncludeGHC_ONLYNoFibTests='YES'
              ;;
-        no)  IncludeUNUSEDNoFibTests='NO'
+        no)  IncludeGHC_ONLYNoFibTests='NO'
              ;;
-        *)   echo "I don't understand this option: --enable-UNUSED-tests=$enableval"
+        *)   echo "I don't understand this option: --enable-GHC-ONLY-tests=$enableval"
              exit 1
              ;;
     esac])
 
-AC_ARG_ENABLE(GHC-ONLY-tests,
-   [--enable-GHC-ONLY-tests   include GHC_ONLY tests],
+AC_ARG_ENABLE(specialise-tests,
+   [--enable-specialise-tests  include specialisation tests],
    [case "$enableval" in
-        yes) IncludeGHC_ONLYNoFibTests='YES'
+        yes) IncludeSpecialiseNoFibTests='YES'
              ;;
-        no)  IncludeGHC_ONLYNoFibTests='NO'
+        no)  IncludeSpecialiseNoFibTests='NO'
              ;;
-        *)   echo "I don't understand this option: --enable-GHC-ONLY-tests=$enableval"
+        *)   echo "I don't understand this option: --enable-specialise-tests=$enableval"
              exit 1
              ;;
     esac])
@@ -1953,15 +2045,31 @@ AC_ARG_ENABLE(parallel-tests,
              ;;
     esac])
 
-AC_SUBST(IncludeRealNoFibTests)
-AC_SUBST(IncludeSpectralNoFibTests)
-AC_SUBST(IncludeImaginaryNoFibTests)
-AC_SUBST(IncludePENDINGNoFibTests)
-AC_SUBST(IncludeUNUSEDNoFibTests)
-AC_SUBST(IncludeGHC_ONLYNoFibTests)
-AC_SUBST(IncludeSpecialiseNoFibTests)
-AC_SUBST(IncludePRIVATENoFibTests)
-AC_SUBST(IncludeParallelNoFibTests)
+dnl not AC_SUBSTd because of 99-command seds (sigh)
+dnl (See what follows instead)
+dnl AC_SUBST(IncludeRealNoFibTests)
+dnl AC_SUBST(IncludeSpectralNoFibTests)
+dnl AC_SUBST(IncludeImaginaryNoFibTests)
+dnl AC_SUBST(IncludeGHC_ONLYNoFibTests)
+dnl AC_SUBST(IncludeSpecialiseNoFibTests)
+dnl AC_SUBST(IncludePRIVATENoFibTests)
+dnl AC_SUBST(IncludeParallelNoFibTests)
+
+# Here, by HACK means, we dump all the Include*NoFibTests info
+# into a file.  See comment above.
+rm -f nofib/mkworld/buildinfo.jm
+echo creating nofib/mkworld/buildinfo.jm
+cat > nofib/mkworld/buildinfo.jm <<EOF
+XCOMM ** DO NOT EDIT! **
+XCOMM This file is obliterated every time 'configure' is run!
+
+EOF
+for xx in Real Spectral Imaginary GHC_ONLY Specialise PRIVATE Parallel ; do
+    eval "yy=\$Include${xx}NoFibTests"
+    echo "#ifndef Include${xx}NoFibTests"     >> nofib/mkworld/buildinfo.jm
+    echo "#define Include${xx}NoFibTests $yy" >> nofib/mkworld/buildinfo.jm
+    echo "#endif"                            >> nofib/mkworld/buildinfo.jm
+done
 
 # here ends a very big if DoingNoFib = 'nofib' ...
 fi
@@ -1972,7 +2080,7 @@ dnl * extract non-header files with substitution (end)
 #
 AC_SUBST(MkWorldSetup)
 
-AC_OUTPUT(Makefile STARTUP mkworld/site.jm mkworld/platform.h mkworld/config.h $ghc_mkworld_site_ghc_jm $ghc_includes_platform_h $nofib_mkworld_site_nofib_jm)
+AC_OUTPUT(Makefile STARTUP mkworld/site.jm mkworld/platform.h mkworld/config.h $ghc_mkworld_site_ghc_jm $ghc_includes_platform_h $hslibs_mkworld_site_hslibs_jm $nofib_mkworld_site_nofib_jm)
 
 echo '************************************************'
 echo '*** NOW DO: sh < STARTUP'
index e2d68ee..f6bae9d 100644 (file)
@@ -1,7 +1,5 @@
 #define IHaveSubdirs
 
-MsubNeededHere( ./glue_TAGS_files )
-
 /* order in SUBDIRS is not supposed to be important but ...
        "compiler" must be before "lib", because we use
        the compiler just built to compile pieces of "lib".
@@ -38,10 +36,3 @@ SUBDIRS = includes \
 whoami::
        @echo using a \`$(BUILDPLATFORM)\' host to build a Haskell compiler to run on a
        @echo \`$(HOSTPLATFORM)\' host that will generate \`C\' target code
-
-fulltags : ./glue_TAGS_files
-       $(RM) ./TAGS
-       ./glue_TAGS_files `find . -type f -name TAGS -print`
-
-/* this line makes sure perl gets picked up from the right place */
-MsubProgramScriptTarget(PerlCmd,./glue_TAGS_files,./glue_TAGS_files.prl,,)
index 8d0e797..72b7dbf 100644 (file)
@@ -40,7 +40,7 @@ JMAKE_CMD = $(NEWTOP)$(JMAKE) -I$(NEWTOP)$(JMAKESRC) $(BOOTSTRAPCFLAGS) -DTopDir
 Makefile:: $(JMAKE)
 
 $(JMAKE):
-       @(cd $(JMAKESRC); if [ -f Makefile ]; then \
+       @(cd $(JMAKESRC) && if [ -f Makefile ]; then \
        echo "checking $@ in $(JMAKESRC) first..."; $(MAKE) all; else \
        echo "bootstrapping $@ from Makefile.BOOT in $(JMAKESRC) first..."; \
        $(MAKE) -f Makefile.BOOT BOOTSTRAPCFLAGS=$(BOOTSTRAPCFLAGS); fi; \
index 936caf5..916eaba 100644 (file)
@@ -1 +1,2 @@
-The Glamorous Glasgow Haskell Compiler, version 0.27, patchlevel 0
+The Glamorous Glasgow Haskell Compiler, version 2.01, patchlevel 0
+(for Haskell 1.3)
index ccc3edb..ea726df 100644 (file)
@@ -1,6 +1,6 @@
-This is version 0.26 of the Glorious Glasgow Haskell compilation
+This is version 2.01 of the Glorious Glasgow Haskell compilation
 system (GHC).  This is a major public release.  The top-level file
-"ANNOUNCE-0.26" says more.
+"ANNOUNCE-0.28" says more.
 
 Haskell is "the" standard lazy functional programming language [see
 SIGPLAN Notices, May 1992]. Some general merits of GHC are given at
index 799f3e0..9e9510c 100644 (file)
@@ -2,6 +2,7 @@
 
 /* just documents here */
 #define NoAllTargetForSubdirs
+#define NoDependTargetForSubdirs
 #define NoRunTestsTargetForSubdirs
 #define NoInstallTargetForSubdirs
 #define NoTagTargetForSubdirs
index 13df5b5..5cdd189 100644 (file)
@@ -1,5 +1,5 @@
 %
-% $Header: /srv/cvs/cvs.haskell.org/fptools/ghc/docs/install_guide/Attic/installing.lit,v 1.1 1996/01/08 20:25:19 partain Exp $
+% $Header: /srv/cvs/cvs.haskell.org/fptools/ghc/docs/install_guide/Attic/installing.lit,v 1.2 1996/06/27 15:57:32 partain Exp $
 %
 \begin{onlystandalone}
 \documentstyle[11pt,literate]{article}
@@ -12,7 +12,7 @@ University of Glasgow\\
 Glasgow, Scotland\\
 G12 8QQ\\
 \\
-Email: glasgow-haskell-\{request,bugs\}\@dcs.glasgow.ac.uk}
+Email: glasgow-haskell-\{users,bugs\}-request\@dcs.glasgow.ac.uk}
 \maketitle
 \begin{rawlatex}
 \tableofcontents
index 16e4d24..b98df34 100644 (file)
@@ -8,7 +8,7 @@ University of Glasgow\\
 Glasgow, Scotland\\
 G12 8QQ\\
 \\
-Email: glasgow-haskell-\{bugs,request\}\@dcs.glasgow.ac.uk}
+Email: glasgow-haskell-\{users,bugs\}-request\@dcs.glasgow.ac.uk}
 \maketitle
 \begin{rawlatex}
 \tableofcontents
index 3767205..c51193a 100644 (file)
@@ -349,8 +349,8 @@ data StateAndFloat#  s     = StateAndFloat#  (State# s) Float#
 data StateAndDouble# s     = StateAndDouble# (State# s) Double#  
 data StateAndAddr#   s     = StateAndAddr#   (State# s) Addr#
 
-data StateAndStablePtr# s a = StateAndStablePtr# (State# s) (StablePtr# a)
-data StateAndMallocPtr# s   = StateAndMallocPtr# (State# s) MallocPtr#
+data StateAndStablePtr# s a = StateAndStablePtr#  (State# s) (StablePtr# a)
+data StateAndForeignObj# s  = StateAndForeignObj# (State# s) ForeignObj#
 data StateAndSynchVar#  s a = StateAndSynchVar#  (State# s) (SynchVar# a)
 
 data StateAndArray#            s elt = StateAndArray#        (State# s) (Array# elt) 
@@ -461,47 +461,68 @@ deRefStablePointer# :: StablePtr# a -> State# _RealWorld -> StateAndPtr _RealWor
 @
 There is also a C procedure @FreeStablePtr@ which frees a stable pointer.
 
-\subsubsection{``Malloc'' pointers}
+%
+% Rewritten and updated for MallocPtr++ -- 4/96 SOF
+%
+\subsubsection{Foreign objects}
 
-A ``malloc'' pointer is an ordinary pointer from outside the Haskell world
-(i.e., from the C world) where the Haskell world has been told ``Let me
+A \tr{ForeignObj} is a reference to an object outside the Haskell
+world (i.e., from the C world, or a reference to an object on another
+machine completely.), where the Haskell world has been told ``Let me
 know when you're finished with this ...''.
 
-The ``malloc'' pointer type is just a special @Addr#@ ({\em not} parameterised).
+The \tr{ForeignObj} type is just a special @Addr#@ ({\em not} parameterised).
 @
-type MallocPtr#
+type ForeignObj#
 @
-{\em ToDo: say more about this and how it's used...}
 
-The main point is that when Haskell discards a 
-value of type @MallocPtr#@, it calls the procedure @FreeMallocPtr@, which
-must be provided by the C world.  @FreeMallocPtr@ might in turn call
-the GHC-provided procedure @FreeStablePtr@, to deallocate a stable pointer.
-No other GHC runtime system procedures should be called by @FreeMallocPtr@.
+A typical use of \tr{ForeignObj} is in constructing Haskell bindings
+to external libraries. A good example is that of writing a binding to
+an image-processing library (which was actually the main motivation
+for implementing \tr{ForeignObj}'s precursor, \tr{MallocPtr}). The
+images manipulated are not stored in the Haskell heap, either because
+the library insist on allocating them internally or we (sensibly)
+decide to spare the GC from having to heave heavy images around.
 
-(Implementation: a linked list of all @MallocPtr#@s is maintained to allow the
-garbage collector to detect when a @MallocPtr#@ becomes garbage.)
+@
+data Image = Image ForeignObj#
 
-Like @Array@, @MallocPtr#@s are represented by heap objects.
+instance _CCallable Image
+@
 
-{\bf ToDo --- Important:} Ian Poole reports a need for functions to return a list of
-CHPs.  Should we add a @CHeapPtrArray@ type too? or just
-hack something up?
+The \tr{ForeignObj#} type is then used to refer to the externally
+allocated image, and to acheive some type safety, the Haskell binding
+defines the @Image@ data type. So, a value of type \tr{ForeignObj#} is
+used to ``box'' up an external reference into a Haskell heap object
+that we can then indirectly reference:
 
-The only Haskell operation we might want on @MallocPtr#@s is an
-equality test.  However, this is easily implemented if desired:
 @
->      eqCHP x y = (_runST (_ccall_ equal x y) == 1::Int)
+createImage :: (Int,Int) -> PrimIO Image
+@
+
+So far, this looks just like an @Addr#@ type, but \tr{ForeignObj#}
+offers a bit more, namely that we can specify a {\em finalisation
+routine} to invoke when the \tr{ForeignObj#} is discarded by the
+GC. The garbage collector invokes the finalisation routine associated
+with the \tr{ForeignObj#}, saying `` Thanks, I'm through with this
+now..'' For the image-processing library, the finalisation routine could for
+the images free up memory allocated for them. The finalisation routine has
+currently to be written in C (the finalisation routine can in turn call on
+@FreeStablePtr@ to deallocate a stable pointer.).
 
-C>     equal (x, y)
-C>     {
-C>     return (x == y ? 1 : 0);
-C>     }
+Associating a finalisation routine with an external object is done by 
+\tr{makeForeignObj#}:
+
+@
+makeForeignObj# :: Addr# -- foreign reference
+                -> Addr# -- pointer to finalisation routine
+               -> StateAndForeignObj# _RealWorld ForeignObj#
 @
 
-The C world must provide a function @FreeCHeapPointer@ which
-will be called (with a C Heap pointer as argument) when the garbage
-collector releases a CHP.
+(Implementation: a linked list of all @ForeignObj#@s is maintained to allow the
+ garbage collector to detect when a @ForeignObj#@ becomes garbage.)
+
+Like @Array@, @ForeignObj#@s are represented by heap objects.
 
 {\bf ToDo:} Decide whether @FreeCHeapPointer@ is allowed to call on a
 stable pointer. (I sincerely hope not since we will still be in the
@@ -803,14 +824,14 @@ writeCharArray  :: Ix ix => _MutableByteArray s ix -> ix -> Char -> _ST s ()
 
 @
 freezeArray :: Ix ix => _MutableArray s ix elt -> _ST s (Array ix elt)
-freezeCharArray :: Ix ix => _MutableByteArray s ix -> _ST s (_ByteArray ix Char)
+freezeCharArray :: Ix ix => _MutableByteArray s ix -> _ST s (_ByteArray ix)
 ...
 @
 
 We have no need on one-function-per-type for unsafe freezing:
 @
 unsafeFreezeArray :: Ix ix => _MutableArray s ix elt -> _ST s (Array ix elt)  
-unsafeFreezeByteArray :: Ix ix => _MutableByteArray s ix -> _ST s (_ByteArray ix elt)
+unsafeFreezeByteArray :: Ix ix => _MutableByteArray s ix -> _ST s (_ByteArray ix)
 @
 
 Sometimes we want to snaffle the bounds of one of these beasts:
@@ -854,11 +875,13 @@ makeStablePointer :: a -> _StablePtr a
 freeStablePointer :: _StablePtr a -> PrimIO ()
 @
 
-\subsection{``Malloc'' pointers}
+\subsection{Foreign objects}
 
 Again, just boxing up.
 @
-data _MallocPtr = _MallocPtr MallocPtr#
+data _ForeignObj = _ForeignObj ForeignObj#
+
+makeForeignObj :: _Addr -> _Addr -> PrimIO _ForeignObj
 @
 
 \subsection{C calls}
@@ -899,22 +922,22 @@ table summarises (including the standard boxed-primitive types):
 Boxed              Type of transferd   Corresp.     Which is
 Type               Prim. component     C type       *probably*...
 ------             ---------------     ------       -------------
-Char               Char#               StgChar      unsigned char
-Int                Int#                StgInt       long int
-_Word              Word#               StgWord      unsigned long int
-_Addr              Addr#               StgAddr      char *
-Float              Float#              StgFloat     float
-Double             Double#             StgDouble    double
-
-Array              Array#              StgArray     StgPtr
-_ByteArray         ByteArray#          StgByteArray StgPtr
-_MutableArray      MutableArray#       StgArray     StgPtr
-_MutableByteArray   MutableByteArray#  StgByteArray StgPtr
+Char               Char#               StgChar       unsigned char
+Int                Int#                StgInt        long int
+_Word              Word#               StgWord       unsigned long int
+_Addr              Addr#               StgAddr       char *
+Float              Float#              StgFloat      float
+Double             Double#             StgDouble     double
+
+Array              Array#              StgArray      StgPtr
+_ByteArray         ByteArray#          StgByteArray  StgPtr
+_MutableArray      MutableArray#       StgArray      StgPtr
+_MutableByteArray   MutableByteArray#  StgByteArray  StgPtr
 
 _State             State#              nothing!
 
-_StablePtr         StablePtr#          StgStablePtr StgPtr
-_MallocPtr         MallocPtr#          StgMallocPtr StgPtr
+_StablePtr         StablePtr#          StgStablePtr  StgPtr
+_ForeignObj        ForeignObj#         StgForeignObj StgPtr
 @
 
 All of the above are {\em C-returnable} except:
@@ -959,8 +982,10 @@ are stored on the heap.
 
 ... details omitted ...
 
-More importantly, it must construct a C Heap Pointer heap-object after
-a @_ccall_@ which returns a @MallocPtr#@.
+%
+%More importantly, it must construct a C Heap Pointer heap-object after
+%a @_ccall_@ which returns a @MallocPtr#@.
+%
 
 %--------------------------------------------------------
 \section{Non-primitive stuff that must be wired into GHC}
@@ -977,7 +1002,7 @@ data Integer = J# Int# Int# ByteArray#
 
 -- and the other boxed-primitive types:
     Array, _ByteArray, _MutableArray, _MutableByteArray,
-    _StablePtr, _MallocPtr
+    _StablePtr, _ForeignObj
 
 data Bool     = False | True
 data CMP_TAG# = LT# | EQ# | GT#  -- used in derived comparisons
index 4403d20..960d3b7 100644 (file)
@@ -52,7 +52,7 @@ This is a bug just as surely as a ``panic.'' Please report it.
 \item[``Some confusion about a value specialised to a type...''  Huh???]
 (A deeply obscure and unfriendly error message.)
 
-This message crops up when the typechecker is sees a reference in an
+This message crops up when the typechecker sees a reference in an
 interface pragma to a specialisation of an overloaded value
 (function); for example, \tr{elem} specialised for type \tr{[Char]}
 (\tr{String}).  The problem is: it doesn't {\em know} that such a
index 21d8ca6..0f870b4 100644 (file)
@@ -53,6 +53,12 @@ declared in the module. If no group is specified it defaults to the
 module name.
 \end{description}
 
+In addition to the \tr{-prof} option your system might be setup to
+enable you to compile and link with the \tr{-prof-details}
+\index{\tr{-prof-details option}} option instead. This enables
+additional detailed counts to be reported with the \tr{-P} RTS option.
+%-prof-details should also enable age profiling if we get it going again ...
+
 %Alternative profiling semantics have also been implemented. To use
 %these the runtime system and prelude libraries must have been built
 %for the alternative profiling setup. This is done using a particular
index a246b38..868c98c 100644 (file)
@@ -3,7 +3,7 @@
 %
 
 When you run your profiled program with the \tr{-p} RTS option
-\index{\tr{-p<sort> RTS option (profiling)}, you get the following
+\index{\tr{-p<sort> RTS option (profiling)}}, you get the following
 information about your ``cost centres'':
 
 \begin{description}
@@ -19,12 +19,6 @@ different modules.
 How many times this cost-centre was entered; think
 of it as ``I got to the \tr{_scc_} construct this many times...''
 %-------------------------------------------------------------
-\item[\tr{subcc}:]
-How many times this cost-centre ``passed control'' to another
-cost-centre; for example, \tr{scc=4} plus \tr{subscc=8} means
-``This \tr{_scc_} was entered four times, but went out to
-other \tr{_scc_s} eight times.''
-%-------------------------------------------------------------
 \item[\tr{%time}:]
 What part of the time was spent in this cost-centre (see also ``ticks,''
 below).
@@ -32,18 +26,43 @@ below).
 \item[\tr{%alloc}:]
 What part of the memory allocation was done in this cost-centre
 (see also ``bytes,'' below).
+%-------------------------------------------------------------
+\item[\tr{inner}:]
+How many times this cost-centre ``passed control'' to an inner
+cost-centre; for example, \tr{scc=4} plus \tr{subscc=8} means
+``This \tr{_scc_} was entered four times, but went out to
+other \tr{_scc_s} eight times.''
+%-------------------------------------------------------------
+\item[\tr{cafs}:]
+How many CAFs this cost centre evaluated.
+%-------------------------------------------------------------
+\item[\tr{dicts}:]
+How many dictionaries this cost centre evaluated.
+\end{description}
+
+In addition you can use the \tr{-P} RTS option \index{\tr{-P<sort> RTS
+    option (profiling)}} to get the following additional information: 
+\begin{description}
+%-------------------------------------------------------------
+\item[\tr{ticks}:]  The raw number of time ``ticks'' which were
+attributed to this cost-centre; from this, we get the \tr{%time}
+figure mentioned above.
+%-------------------------------------------------------------
+\item[\tr{bytes}:] Number of bytes allocated in the heap while in
+this cost-centre; again, this is the raw number from which we
+get the \tr{%alloc} figure mentioned above.
 \end{description}
 
-If you use the \tr{-P} RTS option
-\index{\tr{-P<sort> RTS option (profiling)}, you will also get the
-following information:
+Finally if you built your program with \tr{-prof-details}
+\index{\tr{-prof-details option}} the \tr{-P} RTS option will also
+produce the following information:
 \begin{description}
 %-------------------------------------------------------------
-\item[\tr{cafcc}:] Two columns, analogous to the \tr{scc} and \tr{subcc}
-columns, except these are for CAF cost-centres: the first column
-is how many times this top-level CAF cost-centre was entered;
-the second column is how many times this cost-centre (CAF or otherwise)
-entered another CAF cost-centre.
+\item[\tr{closures}:]
+How many heap objects were allocated; these objects may be of varying
+size.  If you divide the number of bytes (mentioned below) by this
+number of ``closures'', then you will get the average object size.
+(Not too interesting, but still...)
 %-------------------------------------------------------------
 \item[\tr{thunks}:]
 How many times we entered (evaluated) a thunk---an unevaluated
@@ -60,18 +79,4 @@ How many times we entered (evaluated) a partial application (PAP), i.e.,
 a function applied to fewer arguments than it needs.  For example, \tr{Int}
 addition applied to one argument would be a PAP.  A PAP is really
 just a particular form for a function.
-%-------------------------------------------------------------
-\item[\tr{closures}:]
-How many heap objects were allocated; these objects may be of varying
-size.  If you divide the number of bytes (mentioned below) by this
-number of ``closures'', then you will get the average object size.
-(Not too interesting, but still...)
-%-------------------------------------------------------------
-\item[\tr{ticks}:]  The raw number of time ``ticks'' which were
-attributed to this cost-centre; from this, we get the \tr{%time}
-figure mentioned above.
-%-------------------------------------------------------------
-\item[\tr{bytes}:] Number of bytes allocated in the heap while in
-this cost-centre; again, this is the raw number from which we
-get the \tr{%alloc} figure mentioned above.
 \end{description}
index 022d4e3..12325d5 100644 (file)
@@ -64,10 +64,10 @@ The heap space profile may be broken down by different criteria:
 \item[\tr{-hG}:] cost centre group which produced the closure.
 \item[\tr{-hD}:] closure description --- a string describing the closure.
 \item[\tr{-hY}:] closure type --- a string describing the closure's type.
-\item[\tr{-hT<ints>,<start>}:] the time interval the closure was
-created. \tr{<ints>} specifies the no. of interval bands plotted
-(default 18) and \tr{<start>} the number of seconds after which the
-reported intervals start (default 0.0).
+%\item[\tr{-hT<ints>,<start>}:] the time interval the closure was
+%created. \tr{<ints>} specifies the no. of interval bands plotted
+%(default 18) and \tr{<start>} the number of seconds after which the
+%reported intervals start (default 0.0).
 \end{description}
 By default all live closures in the heap are profiled, but particular
 closures of interest can be selected (see below). 
@@ -107,14 +107,14 @@ Selects closures which are of one of the specified closure kinds.
 Valid closure kinds are \tr{CON} (constructor), \tr{FN} (manifest
 function), \tr{PAP} (partial application), \tr{BH} (black hole) and
 \tr{THK} (thunk).
-\item[\tr{-a<age>}:]
-\index{-a<age> RTS option (profiling)}
-Selects closures which have survived \pl{<age>} complete intervals.
+%\item[\tr{-a<age>}:]
+%\index{-a<age> RTS option (profiling)}
+%Selects closures which have survived \pl{<age>} complete intervals.
 \end{description}
 The space occupied by a closure will be reported in the heap profile
 if the closure satisfies the following logical expression:
 \begin{display}
-([-c] or [-m] or [-g]) and ([-d] or [-y] or [-k]) and [-a]
+([-c] or [-m] or [-g]) and ([-d] or [-y] or [-k]) %and [-a]
 \end{display}
 where a particular option is true if the closure (or its attached cost
 centre) is selected by the option (or the option is not specified).
index 68d4a7e..9f55739 100644 (file)
@@ -8,7 +8,7 @@ University of Glasgow\\
 Glasgow, Scotland\\
 G12 8QQ\\
 \\
-Email: glasgow-haskell-\{bugs,request\}\@dcs.glasgow.ac.uk}
+Email: glasgow-haskell-\{users,bugs\}-request\@dcs.glasgow.ac.uk}
 \maketitle
 \begin{rawlatex}
 \tableofcontents
index 51f63e2..858a12b 100644 (file)
@@ -8,7 +8,7 @@ University of Glasgow\\
 Glasgow, Scotland\\
 G12 8QQ\\
 \\
-Email: glasgow-haskell-\{bugs,request\}\@dcs.glasgow.ac.uk}
+Email: glasgow-haskell-\{bugs,users\}-request\@dcs.glasgow.ac.uk}
 \maketitle
 \begin{rawlatex}
 \tableofcontents
index d007621..6ec326e 100644 (file)
@@ -27,7 +27,9 @@ HCFLAGS = -fhaskell-1.3 -cpp -hi-diffs $(EXTRA_HC_OPTS)
 SRCS = Main.lhs Foo.lhs Bar.lhs
 OBJS = Main.o   Foo.o   Bar.o
 
-.SUFFIXES : .o .lhs
+.SUFFIXES : .o .hi .lhs
+.o.hi:
+       @:
 .lhs.o:
         $(RM) $@
         $(HC) -c $< $(HCFLAGS)
@@ -37,6 +39,14 @@ cool_pgm : $(OBJS)
         $(HC) -o $@ $(HCFLAGS) $(OBJS)
 \end{verbatim}
 
+Note the cheesy \tr{.o.hi} rule: It records the dependency of the
+interface (\tr{.hi}) file on the source.  The rule says a \tr{.hi}
+file can be made from a \tr{.o} file by doing... nothing.  Which is
+true.
+
+(Sophisticated \tr{make} variants may achieve some of the above more
+elegantly.  What we've shown should work with any \tr{make}.)
+
 The only thing lacking in the above \tr{Makefile} is interface-file
 dependencies.  If \tr{Foo.lhs} imports module \tr{Bar} and the
 \tr{Bar} interface changes, then \tr{Foo.lhs} needs to be recompiled.
@@ -64,6 +74,9 @@ effect.  However, a \tr{make} run that does nothing {\em does} mean
 mutually-recursive modules but, again, it may take multiple
 iterations to ``settle.''
 
+To see \tr{mkdependHS}'s command-line flags, give it a duff flag,
+e.g., \tr{mkdependHS -help}.
+
 %************************************************************************
 %*                                                                      *
 \subsection[hstags]{Emacs `TAGS' for Haskell: \tr{hstags}}
index c4fc5e5..912e2df 100644 (file)
@@ -362,13 +362,13 @@ Here is our ``crib sheet'' for converting 1.2 I/O to 1.3.  In most cases,
 it's really easy.
 \begin{enumerate}
 \item
-Change \tr{readChan stdin} to \tr{hGetContents stdin}.
+Change \tr{readChan stdin} to \tr{getContents}.
 \item
 Change \tr{appendChan stdout} to \tr{putStr}, which is equivalent to
 \tr{hPutStr stdout}.
 Change \tr{appendChan stderr} to \tr{hPutStr stderr}.
 \item
-You need to \tr{import LibSystem} if you used @getArgs@, @getEnv@,
+You need to \tr{import System} if you used @getArgs@, @getEnv@,
 or @getProgName@.
 \item
 Assuming continuation-style @Dialogue@ code, change \tr{... exit done $}
@@ -378,6 +378,36 @@ If you had any functions named \tr{(>>)}, \tr{(>>=)}, or \tr{return},
 change them to something else.
 \end{enumerate}
 
+Also:
+1.3 I/O all the way.
+\tr{Dialogue} usually turns into \tr{IO ()}.
+Use of \tr{StatusFile} request: rewrite (no equivalent exists).
+Add \tr{import Ratio} if you use \tr{Rationals} at all.
+Ditto: \tr{import Complex} if you use complex numbers.
+Ditto: \tr{import Array} if you use arrays.  Also: note that
+Arrays now use ordinary pairs, rather than a separate \tr{Assoc} type.
+May be easier to do:
+infix 1 =:
+(=:) a b = (a,b)
+and switch := to =:
+This can happen: \tr{LiteralInt.leStringToInt}; add spaces.
+For \tr{minInt}/\tr{maxInt}, \tr{minChar}/\tr{maxChar} (???)
+use the \tr{Bounded} class methods, \tr{minBound} and \tr{maxBound}.
+Replace class \tr{Text} with \tr{Show}; on rare occasions,
+you may need to do something for \tr{Read}, too.
+The functions \tr{ord} and \tr{chr} have been replaced by
+the class methods \tr{fromEnum} and \tr{toEnum}, respectively.
+The changes, however, can lead to ambiguous overloading.
+Need \tr{import IO} for anything interesting.
+What was called \tr{handle} is now called \tr{catch}.
+New keyword: \tr{do}.
+Other clashes: e.g., \tr{seq}, \tr{fail}.
+\tr{readDec} no longer exists; use ???.
+Type of \tr{fail} changed?
+\tr{(a `op` b) c = ...} is bogus.
+`failWith x' now `fail x'
+`fail x' now `fail (userError x)'
+
 %************************************************************************
 %*                                                                      *
 \subsection[nonio-1-3]{Non-I/O things from the 1.3-DRAFT proposal}
@@ -444,10 +474,10 @@ The error type is called \tr{IOError13}, rather than \tr{IOError}
 so...)  You probably shouldn't be messing with \tr{IOError} much,
 anyway.
 
-Some of the 1.3 I/O code, notably the Extremely Cool \tr{LibPosix}
+Some of the 1.3 I/O code, notably the Extremely Cool \tr{Posix}
 stuff, is relatively untested.  Go for it, but be wary...
-\index{LibPosix bugs}
-\index{bugs, LibPosix}
+\index{Posix library bugs}
+\index{bugs, Posix library}
 
 %************************************************************************
 %*                                                                     *
@@ -470,7 +500,7 @@ required) and put into \tr{Lib*} interfaces (import required).
 
 GHC~0.26 still provides the I/O functions via \tr{Prelude.hi} (no
 import required).  Ignore the ``June draft'' pleadings for
-\tr{import LibIO}, and you'll be fine.
+\tr{import IO}, and you'll be fine.
 
 {\em There is no guarantee that the final 1.3 proposal will look
 anything like the current DRAFT.}  It ain't a standard until the fat
@@ -557,11 +587,11 @@ with \tr{-fhaskell-1.3}...)
 
 To subvert the above process, you need only provide
 a @mainPrimIO :: PrimIO ()@ of your own
-(in a module named \tr{Main}).  Do {\em not} use a \tr{-fhaskell-1.3} flag!
+(in a module named \tr{GHCmain}).  Do {\em not} use a \tr{-fhaskell-1.3} flag!
 
 Here's a little example, stolen from Alastair Reid:
 \begin{verbatim}
-module Main ( mainPrimIO ) where
+module GHCmain ( mainPrimIO ) where
 
 import PreludeGlaST
 
index 97e9100..5070553 100644 (file)
@@ -1,29 +1,19 @@
 /* stuff to have before we get going */
 MsubNeededHere(ghc)
-#if BuildDataParallelHaskell == YES
-MsubNeededHere(dphc)
-#endif
-LitStuffNeededHere(depend)
+UnlitNeededHere(depend)
 InfoStuffNeededHere(docs)
 
 DYN_LOADABLE_BITS = \
-       ghc-asm-sparc.prl \
-       ghc-asm-solaris.prl \
-       ghc-asm-m68k.prl \
        ghc-asm.prl \
-       ghc-asm-alpha.prl \
-       ghc-asm-hppa.prl \
-       ghc-asm-mips.prl \
+       ghc-recomp.prl \
+       ghc-iface.prl \
        ghc-consist.prl \
        ghc-split.prl
 
 /* Literate-pgmming suffix rules used herein */
-LitSuffixRule(.lprl,.prl)
+UnlitSuffixRule(.lprl,.prl)
 
 MsubMakefileDependentProgramScriptTarget(PerlCmd,ghc,ghc.prl,/*no flags*/,/*Makefile*/)
-#if BuildDataParallelHaskell == YES
-MsubMakefileDependentProgramScriptTarget(PerlCmd,dphc,dphc.prl,,/*Makefile*/)
-#endif
 AllTarget( $(DYN_LOADABLE_BITS) )
 
 /* installation is hackish: because we may want to install w/ a diff name */
@@ -36,13 +26,6 @@ install::
        $(MV) $(INSTBINDIR_GHC)/ghc-v-temp-name $(INSTBINDIR_GHC)/$(GHC_DRIVER_INST_NAME)
        $(RM) $(INSTBINDIR_GHC)/ghc-v-temp-name
 
-#if BuildDataParallelHaskell == YES
-InstallMsubbedScriptTarget(PerlCmd,dphc-v-temp-name,dphc.prl,$(INSTBINDIR_GHC))
-install::
-       $(MV) $(INSTBINDIR_GHC)/dphc-v-temp-name $(INSTBINDIR_GHC)/dphc
-       $(RM) $(INSTBINDIR_GHC)/dphc-v-temp-name
-#endif /* DPH */
-
 dyn_loadable_bits : $(DYN_LOADABLE_BITS)
 
 InstallMultNonExecTargets(dyn_loadable_bits, $(DYN_LOADABLE_BITS), $(INSTLIBDIR_GHC))
@@ -60,5 +43,3 @@ ClearTagsFile()
 
 DYN_LOADABLE_LPRLS = $(DYN_LOADABLE_BITS:.prl=.lprl)
 PerlTagsTarget( ghc.lprl $(DYN_LOADABLE_LPRLS) )
-
-LitDocRootTargetWithNamedOutput(driver,lit,driver-standalone)
diff --git a/ghc/driver/driver.lit b/ghc/driver/driver.lit
deleted file mode 100644 (file)
index ca4a876..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-\begin{onlystandalone}
-\documentstyle[11pt,literate,a4wide]{article}
-\begin{document}
-\title{Driver: @ghc@}
-\author{The GRASP team}
-\date{January 1993}
-\maketitle
-\begin{rawlatex}
-\tableofcontents
-\end{rawlatex}
-\end{onlystandalone}
-
-\begin{onlypartofdoc}
-\section[Driver-for-compilation-system]{@ghc@: Driver for the compilation system}
-\downsection
-\end{onlypartofdoc}
-
-\input{ghc.lprl}
-
-\section[Driver-support]{Support code for the @ghc@ driver}
-\downsection
-\input{ghc-asm.lprl}
-\input{ghc-consist.lprl}
-\input{ghc-split.lprl}
-\upsection
-
-\begin{onlypartofdoc}
-\upsection
-\end{onlypartofdoc}
-\begin{onlystandalone}
-\printindex
-\end{document}
-\end{onlystandalone}
diff --git a/ghc/driver/ghc-asm-alpha.lprl b/ghc/driver/ghc-asm-alpha.lprl
deleted file mode 100644 (file)
index 23ee45a..0000000
+++ /dev/null
@@ -1,521 +0,0 @@
-%************************************************************************
-%*                                                                     *
-\section[Driver-asm-fiddling]{Fiddling with assembler files (alpha)}
-%*                                                                     *
-%************************************************************************
-
-Tasks:
-\begin{itemize}
-\item
-Utterly stomp out C functions' prologues and epilogues; i.e., the
-stuff to do with the C stack.
-\item
-Any other required tidying up.
-\end{itemize}
-
-\begin{code}
-sub mangle_asm {
-    local($in_asmf, $out_asmf) = @_;
-
-    # multi-line regexp matching:
-    local($*) = 1;
-    local($i, $c);
-    &init_FUNNY_THINGS();
-
-    open(INASM, "< $in_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$in_asmf' (to read)\n");
-    open(OUTASM,"> $out_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$out_asmf' (to write)\n");
-
-    # read whole file, divide into "chunks":
-    #  record some info about what we've found...
-
-    @chk = ();         # contents of the chunk
-    $numchks = 0;      # number of them
-    @chkcat = ();      # what category of thing in each chunk
-    @chksymb = ();     # what symbol(base) is defined in this chunk
-    %slowchk = ();     # ditto, its regular "slow" entry code
-    %fastchk = ();     # ditto, fast entry code
-    %closurechk = ();  # ditto, the (static) closure
-    %infochk = ();     # given a symbol base, say what chunk its info tbl is in
-    %vectorchk = ();    # ditto, return vector table
-    %directchk = ();    # ditto, direct return code
-
-    $i = 0;
-    $chkcat[0] = 'misc';
-
-    while (<INASM>) {
-#???   next if /^\.stab.*___stg_split_marker/;
-#???   next if /^\.stab.*ghc.*c_ID/;
-
-       next if /^\s*$/;
-
-       if ( /^\s+/ ) { # most common case first -- a simple line!
-           # duplicated from the bottom
-           $chk[$i] .= $_;
-
-       } elsif ( /\.\.ng:$/ ) { # Local labels not to be confused with new chunks
-           $chk[$i] .= $_;
-
-       } elsif ( /^\$C(\d+):$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'string';
-           $chksymb[$i] = $1;
-
-       } elsif ( /^__stg_split_marker(\d+):$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'splitmarker';
-           $chksymb[$i] = $1;
-
-       } elsif ( /^([A-Za-z0-9_]+)_info:$/ ) {
-           $symb = $1;
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'infotbl';
-           $chksymb[$i] = $symb;
-
-           die "Info table already? $symb; $i\n" if defined($infochk{$symb});
-
-           $infochk{$symb} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)_entry:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'slow';
-           $chksymb[$i] = $1;
-
-           $slowchk{$1} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)_fast\d+:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'fast';
-           $chksymb[$i] = $1;
-
-           $fastchk{$1} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)_closure:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'closure';
-           $chksymb[$i] = $1;
-
-           $closurechk{$1} = $i;
-
-       } elsif ( /^ghc.*c_ID:/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'consist';
-
-       } elsif ( /^(__gnu_compiled_c|gcc2_compiled\.):/ ) {
-           ; # toss it
-
-       } elsif ( /^ErrorIO_call_count:/         # HACK!!!!
-              || /^[A-Za-z0-9_]+\.\d+:$/
-              || /^.*_CAT:/                    # PROF: _entryname_CAT
-              || /^CC_.*_struct:/              # PROF: _CC_ccident_struct
-              || /^.*_done:/                   # PROF: _module_done
-              || /^_module_registered:/        # PROF: _module_registered
-              ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'data';
-           $chksymb[$i] = '';
-
-       } elsif ( /^(ret_|djn_)/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } elsif ( /^vtbl_([A-Za-z0-9_]+):$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'vector';
-           $chksymb[$i] = $1;
-
-           $vectorchk{$1} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)DirectReturn:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'direct';
-           $chksymb[$i] = $1;
-
-           $directchk{$1} = $i;
-
-       } elsif ( /^[A-Za-z0-9_]+_upd:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } elsif ( /^[A-Za-z0-9_]/ ) {
-           local($thing);
-           chop($thing = $_);
-           print STDERR "Funny global thing?: $_"
-               unless $KNOWN_FUNNY_THING{$thing}
-                   || /^_(PRIn|PRStart).*:/    # pointer reversal GC routines
-                   || /^CC_.*:/                # PROF: _CC_ccident
-                   || /^_reg.*:/;              # PROF: _reg<module>
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } else { # simple line (duplicated at the top)
-           $chk[$i] .= $_;
-       }
-    }
-    $numchks = $#chk + 1;
-
-#    print STDERR "\nCLOSURES:\n";
-#    foreach $s (sort (keys %closurechk)) {
-#      print STDERR "$s:\t\t",$closurechk{$s},"\n";
-#    }
-#    print STDERR "\nINFOS:\n";
-#    foreach $s (sort (keys %infochk)) {
-#      print STDERR "$s:\t\t",$infochk{$s},"\n";
-#    }
-#    print STDERR "SLOWS:\n";
-#    foreach $s (sort (keys %slowchk)) {
-#      print STDERR "$s:\t\t",$slowchk{$s},"\n";
-#    }
-#    print STDERR "\nFASTS:\n";
-#    foreach $s (sort (keys %fastchk)) {
-#      print STDERR "$s:\t\t",$fastchk{$s},"\n";
-#    }
-
-    # the division into chunks is imperfect;
-    # we throw some things over the fence into the next
-    # chunk.
-    #
-    # also, there are things we would like to know
-    # about the whole module before we start spitting
-    # output.
-
-    # NB: we start meddling at chunk 1, not chunk 0
-
-    # the first ".rdata" is quite magical; as of GCC 2.7.x, it
-    # spits a ".quad 0" in after the v first ".rdata"; we
-    # detect this special case (tossing the ".quad 0")!
-    $magic_rdata_seen = 0;
-
-    for ($i = 1; $i < $numchks; $i++) {
-       $c = $chk[$i]; # convenience copy
-
-#      print STDERR "\nCHK $i (BEFORE):\n", $c;
-
-       # pin a funny end-thing on (for easier matching):
-       $c .= 'FUNNY#END#THING';
-
-       if ( ! $magic_rdata_seen && $c =~ /^\s*\.rdata\n\t\.quad 0\n\t\.align \d\n/ ) {
-           $c =~ s/^\s*\.rdata\n\t\.quad 0\n\t\.align (\d)\n/\.rdata\n\t\.align $1\n/;
-           $magic_rdata_seen = 1;
-       }
-
-       # pick some end-things and move them to the next chunk
-
-       while ( $c =~ /^(\s*\.align\s+\d+\n)FUNNY#END#THING/
-            || $c =~ /^(\s*\.(globl|ent)\s+\S+\n)FUNNY#END#THING/
-             || $c =~ /^(\s*\#.*\n)FUNNY#END#THING/
-             || $c =~ /^(\s*\.(file|loc)\s+\S+\s+\S+\n)FUNNY#END#THING/
-            || $c =~ /^(\s*\.text\n|\s*\.r?data\n)FUNNY#END#THING/ ) {
-           $to_move = $1;
-
-            if ( $to_move =~ /^\s*(\#|\.(file|globl|ent|loc))/ && $i < ($numchks - 1) ) {
-               $chk[$i + 1] = $to_move . $chk[$i + 1];
-               # otherwise they're tossed
-           }
-
-           $c =~ s/^.*\nFUNNY#END#THING/FUNNY#END#THING/;
-       }
-
-       if ($c =~ /^\t\.ent\s+(\S+)/) {
-           $ent = $1;
-           # toss all prologue stuff, except for loading gp, and the ..ng address
-           if (($p, $r) = split(/^\t\.prologue/, $c)) {
-# print STDERR "$ent: prologue:\n$p\nrest:\n$r\n";
-               if (($keep, $junk) = split(/\.\.ng:/, $p)) {
-                   $c = $keep . "..ng:\n";
-               } else {
-                   print STDERR "malformed code block ($ent)?\n"
-               }
-           }
-           $c .= "\t.frame \$30,0,\$26,0\n\t.prologue" . $r;
-       }
-
-       $c =~ s/FUNNY#END#THING//;
-       $chk[$i] = $c; # update w/ convenience copy
-
-#      print STDERR "\nCHK $i (AFTER):\n", $c;
-    }
-
-    # print out the header stuff first
-
-    $chk[0] =~ s/^(\t\.file.*)"(ghc\d+\.c)"/\1"$ifile_root.hc"/;
-    print OUTASM $chk[0];
-
-    # print out all the literal strings second
-    for ($i = 1; $i < $numchks; $i++) {
-       if ( $chkcat[$i] eq 'string' ) {
-           print OUTASM "\.rdata\n\t\.align 3\n";
-           print OUTASM $chk[$i];
-           
-           $chkcat[$i] = 'DONE ALREADY';
-       }
-    }
-
-    for ($i = 1; $i < $numchks; $i++) {
-#      print STDERR "$i: cat $chkcat[$i], symb $chksymb[$i]\n";
-
-       next if $chkcat[$i] eq 'DONE ALREADY';
-
-       if ( $chkcat[$i] eq 'misc' ) {
-           print OUTASM "\.text\n\t\.align 3\n";
-           print OUTASM $chk[$i];
-
-       } elsif ( $chkcat[$i] eq 'data' ) {
-           print OUTASM "\.data\n\t\.align 3\n";
-           print OUTASM $chk[$i];
-
-       } elsif ( $chkcat[$i] eq 'consist' ) {
-           if ( $chk[$i] =~ /\.ascii.*\)(hsc|cc) (.*)\\11"\n\t\.ascii\s+"(.*)\\0"/ ) {
-               local($consist) = "$1.$2.$3";
-               $consist =~ s/,/./g;
-               $consist =~ s/\//./g;
-               $consist =~ s/-/_/g;
-               $consist =~ s/[^A-Za-z0-9_.]/ZZ/g; # ToDo: properly?
-               print OUTASM "\.text\n$consist:\n";
-           } else {
-               print STDERR "Couldn't grok consistency: ", $chk[$i];
-           }
-
-       } elsif ( $chkcat[$i] eq 'splitmarker' ) {
-           # we can just re-constitute this one...
-           # ignore the final split marker, to save an empty object module
-           # Use _three_ underscores so that ghc-split doesn't get overly complicated
-           print OUTASM "___stg_split_marker",$chksymb[$i],":\n";
-
-       } elsif ( $chkcat[$i] eq 'closure'
-              || $chkcat[$i] eq 'infotbl'
-              || $chkcat[$i] eq 'slow'
-              || $chkcat[$i] eq 'fast' ) { # do them in that order
-           $symb = $chksymb[$i];
-
-           # CLOSURE
-           if ( defined($closurechk{$symb}) ) {
-               print OUTASM "\.data\n\t\.align 3\n";
-               print OUTASM $chk[$closurechk{$symb}];
-               $chkcat[$closurechk{$symb}] = 'DONE ALREADY';
-           }
-
-           # INFO TABLE
-           if ( defined($infochk{$symb}) ) {
-
-               print OUTASM "\.text\n\t\.align 3\n";
-               print OUTASM &rev_tbl($symb, $chk[$infochk{$symb}], 1);
-               # entry code will be put here!
-
-               # paranoia
-               if ( $chk[$infochk{$symb}] =~ /\.quad\s+([A-Za-z0-9_]+_entry)$/
-                 && $1 ne "${symb}_entry" ) {
-                   print STDERR "!!! entry point???\n",$chk[$infochk{$symb}];
-               }
-
-               $chkcat[$infochk{$symb}] = 'DONE ALREADY';
-           }
-
-           # STD ENTRY POINT
-           if ( defined($slowchk{$symb}) ) {
-
-               # teach it to drop through to the fast entry point:
-               $c = $chk[$slowchk{$symb}];
-               if ( defined($fastchk{$symb}) ) {
-                   $c =~ s/^\tjmp \$31,\(\$27\),0\n\t\.align 4\n\t\.end/\t.align 4\n\t.end/;
-               }
-
-               # NB: no very good way to look for "dangling" references
-               # to fast-entry pt
-
-               print OUTASM "\.text\n\t\.align 3\n";
-               print OUTASM $c;
-               $chkcat[$slowchk{$symb}] = 'DONE ALREADY';
-           }
-           
-           # FAST ENTRY POINT
-           if ( defined($fastchk{$symb}) ) {
-               $c = $chk[$fastchk{$symb}];
-               if ( ! defined($slowchk{$symb}) ) {
-                   print OUTASM "\.text\n\t\.align 3\n";
-               }
-               print OUTASM $c;
-               $chkcat[$fastchk{$symb}] = 'DONE ALREADY';
-           }
-
-       } elsif ( $chkcat[$i] eq 'vector'
-              || $chkcat[$i] eq 'direct' ) { # do them in that order
-           $symb = $chksymb[$i];
-
-           # VECTOR TABLE
-           if ( defined($vectorchk{$symb}) ) {
-               print OUTASM "\.text\n\t\.align 3\n";
-               print OUTASM &rev_tbl($symb, $chk[$vectorchk{$symb}], 0);
-               # direct return code will be put here!
-               $chkcat[$vectorchk{$symb}] = 'DONE ALREADY';
-           }
-
-           # DIRECT RETURN
-           if ( defined($directchk{$symb}) ) {
-               print OUTASM "\.text\n\t\.align 3\n";
-               print OUTASM $chk[$directchk{$symb}];
-               $chkcat[$directchk{$symb}] = 'DONE ALREADY';
-           } else {
-                # The commented nop is for the splitter, to ensure
-                # that no module ends with a label as the very last
-                # thing.  (The linker will adjust the label to point
-                # to the first code word of the next module linked in,
-                # even if alignment constraints cause the label to move!)
-
-               print OUTASM "\t# nop\n";
-           }
-       } else {
-           &tidy_up_and_die(1,"$Pgm: unknown chkcat (ghc-asm alpha)\n$chkcat[$i]\n$chk[$i]\n");
-       }
-    }
-
-    # finished:
-    close(OUTASM) || &tidy_up_and_die(1,"Failed writing to $out_asmf\n");
-    close(INASM)  || &tidy_up_and_die(1,"Failed reading from $in_asmf\n");
-}
-\end{code}
-
-\begin{code}
-sub init_FUNNY_THINGS {
-    %KNOWN_FUNNY_THING = (
-       'CheckHeapCode:', 1,
-       'CommonUnderflow:', 1,
-       'Continue:', 1,
-       'EnterNodeCode:', 1,
-       'ErrorIO_call_count:', 1,
-       'ErrorIO_innards:', 1,
-       'IndUpdRetDir:', 1,
-       'IndUpdRetV0:', 1,
-       'IndUpdRetV1:', 1,
-       'IndUpdRetV2:', 1,
-       'IndUpdRetV3:', 1,
-       'IndUpdRetV4:', 1,
-       'IndUpdRetV5:', 1,
-       'IndUpdRetV6:', 1,
-       'IndUpdRetV7:', 1,
-       'PrimUnderflow:', 1,
-       'StackUnderflowEnterNode:', 1,
-       'StdErrorCode:', 1,
-       'UnderflowVect0:', 1,
-       'UnderflowVect1:', 1,
-       'UnderflowVect2:', 1,
-       'UnderflowVect3:', 1,
-       'UnderflowVect4:', 1,
-       'UnderflowVect5:', 1,
-       'UnderflowVect6:', 1,
-       'UnderflowVect7:', 1,
-       'UpdErr:', 1,
-       'UpdatePAP:', 1,
-       'WorldStateToken:', 1,
-       '_Enter_Internal:', 1,
-       '_PRMarking_MarkNextAStack:', 1,
-       '_PRMarking_MarkNextBStack:', 1,
-       '_PRMarking_MarkNextCAF:', 1,
-       '_PRMarking_MarkNextGA:', 1,
-       '_PRMarking_MarkNextRoot:', 1,
-       '_PRMarking_MarkNextSpark:', 1,
-       '_Scavenge_Forward_Ref:', 1,
-       '__std_entry_error__:', 1,
-       '_startMarkWorld:', 1,
-       'resumeThread:', 1,
-       'startCcRegisteringWorld:', 1,
-       'startEnterFloat:', 1,
-       'startEnterInt:', 1,
-       'startPerformIO:', 1,
-       'startStgWorld:', 1,
-       'stopPerformIO:', 1
-  );
-}
-\end{code}
-
-The following table reversal is used for both info tables and return
-vectors.  In both cases, we remove the first entry from the table,
-reverse the table, put the label at the end, and paste some code
-(that which is normally referred to by the first entry in the table)
-right after the table itself.  (The code pasting is done elsewhere.)
-
-\begin{code}
-sub rev_tbl {
-    local($symb, $tbl, $discard1) = @_;
-
-    local($before) = '';
-    local($label) = '';
-    local(@words) = ();
-    local($after) = '';
-    local(@lines) = split(/\n/, $tbl);
-    local($i);
-
-    for ($i = 0; $i <= $#lines && $lines[$i] !~ /^\t\.quad\s+/; $i++) {
-       $label .= $lines[$i] . "\n",
-           next if $lines[$i] =~ /^[A-Za-z0-9_]+:$/
-                || $lines[$i] =~ /^\t\.globl/;
-
-       $before .= $lines[$i] . "\n"; # otherwise...
-    }
-
-    for ( ; $i <= $#lines && $lines[$i] =~ /^\t\.quad\s+/; $i++) {
-       push(@words, $lines[$i]);
-    }
-    # now throw away the first word (entry code):
-    shift(@words) if $discard1;
-
-    for (; $i <= $#lines; $i++) {
-       $after .= $lines[$i] . "\n";
-    }
-
-    # If we have anonymous text (not part of a procedure), the linker
-    # may complain about missing exception information.  Bleh.
-    if ($label =~ /^([A-Za-z0-9_]+):$/) {
-       $before = "\t.ent $1\n" . $before;
-       $after .= "\t.end $1\n";
-    }
-
-    $tbl = $before . join("\n", (reverse @words)) . "\n" . $label . $after;
-
-#    print STDERR "before=$before\n";
-#    print STDERR "label=$label\n";
-#    print STDERR "words=",(reverse @words),"\n";
-#    print STDERR "after=$after\n";
-
-    $tbl;
-}
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[Driver-asm-info]{Collect interesting (static) info from an assembler file}
-%*                                                                     *
-%************************************************************************
-
-How many times is each asm instruction used?
-
-\begin{code}
-%AsmInsn = (); # init
-
-sub dump_asm_insn_counts {
-    local($asmf) = @_;
-
-    open(INASM, "< $asmf")  || &tidy_up_and_die(1,"$Pgm: failed to open `$asmf' (to read)\n");
-    while (<INASM>) {
-       if ( /^\t([a-z][a-z0-9]+)\b/ ) {
-           $AsmInsn{$1} ++;
-       }
-    }
-    close(INASM) || &tidy_up_and_die(1,"Failed reading from $asmf\n");
-
-    # OK, now print what we collected (to stderr)
-    foreach $i (sort (keys %AsmInsn)) {
-       print STDERR "INSN:: $i\t",$AsmInsn{$i},"\n";
-    }
-}
-
-sub dump_asm_globals_info {
-}
-
-# make "require"r happy...
-1;
-\end{code}
diff --git a/ghc/driver/ghc-asm-hppa.lprl b/ghc/driver/ghc-asm-hppa.lprl
deleted file mode 100644 (file)
index 1032a36..0000000
+++ /dev/null
@@ -1,582 +0,0 @@
-%************************************************************************
-%*                                                                     *
-\section[Driver-asm-fiddling]{Fiddling with assembler files (HP-PA)}
-%*                                                                     *
-%************************************************************************
-
-Tasks:
-\begin{itemize}
-\item
-Utterly stomp out C functions' prologues and epilogues; i.e., the
-stuff to do with the C stack.
-\item
-Any other required tidying up.
-\end{itemize}
-
-HP specific notes:
-\begin{itemize}
-\item
-The HP linker is very picky about symbols being in the appropriate
-space (code vs. data).  When we mangle the threaded code to put the
-info tables just prior to the code, they wind up in code space
-rather than data space.  This means that references to *_info from
-un-mangled parts of the RTS (e.g. unthreaded GC code) get
-unresolved symbols.  Solution:  mini-mangler for .c files on HP.  I
-think this should really be triggered in the driver by a new -rts
-option, so that user code doesn't get mangled inappropriately.
-\item
-With reversed tables, jumps are to the _info label rather than to
-the _entry label.  The _info label is just an address in code
-space, rather than an entry point with the descriptive blob we
-talked about yesterday.  As a result, you can't use the call-style
-JMP_ macro.  However, some JMP_ macros take _info labels as targets
-and some take code entry points within the RTS.  The latter won't
-work with the goto-style JMP_ macro.  Sigh.  Solution: Use the goto
-style JMP_ macro, and mangle some more assembly, changing all
-"RP'literal" and "LP'literal" references to "R'literal" and
-"L'literal," so that you get the real address of the code, rather
-than the descriptive blob.  Also change all ".word P%literal"
-entries in info tables and vector tables to just ".word literal,"
-for the same reason.  Advantage: No more ridiculous call sequences.
-\end{itemize}
-
-\begin{code}
-sub mangle_asm {
-    local($in_asmf, $out_asmf) = @_;
-
-    # multi-line regexp matching:
-    local($*) = 1;
-    local($i, $c);
-    &init_FUNNY_THINGS();
-
-    open(INASM, "< $in_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$in_asmf' (to read)\n");
-    open(OUTASM,"> $out_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$out_asmf' (to write)\n");
-
-    # read whole file, divide into "chunks":
-    #  record some info about what we've found...
-
-    @chk = ();         # contents of the chunk
-    $numchks = 0;      # number of them
-    @chkcat = ();      # what category of thing in each chunk
-    @chksymb = ();     # what symbol(base) is defined in this chunk
-    %slowchk = ();     # ditto, its regular "slow" entry code
-    %fastchk = ();     # ditto, fast entry code
-    %closurechk = ();  # ditto, the (static) closure
-    %infochk = ();     # ditto, normal info tbl
-    %vectorchk = ();    # ditto, return vector table
-    %directchk = ();    # ditto, direct return code
-
-    $i = 0;
-    $chkcat[0] = 'misc';
-
-    while (<INASM>) {
-#???   next if /^\.stab.*___stg_split_marker/;
-#???   next if /^\.stab.*ghc.*c_ID/;
-
-       next if /^;/;
-
-       if ( /^\s+/ ) { # most common case first -- a simple line!
-           # duplicated from the bottom
-           $chk[$i] .= $_;
-
-       } elsif ( /^L\$C(\d+)$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'literal';
-           $chksymb[$i] = $1;
-
-       } elsif ( /^__stg_split_marker(\d+)$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'splitmarker';
-           $chksymb[$i] = $1;
-
-       } elsif ( /^([A-Za-z0-9_]+)_info$/ ) {
-           $symb = $1;
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'infotbl';
-           $chksymb[$i] = $symb;
-
-           die "Info table already? $symb; $i\n" if defined($infochk{$symb});
-
-           $infochk{$symb} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)_entry$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'slow';
-           $chksymb[$i] = $1;
-
-           $slowchk{$1} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)_fast\d+$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'fast';
-           $chksymb[$i] = $1;
-
-           $fastchk{$1} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)_closure$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'closure';
-           $chksymb[$i] = $1;
-
-           $closurechk{$1} = $i;
-
-       } elsif ( /^ghc.*c_ID/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'consist';
-
-       } elsif ( /^(__gnu_compiled_c|gcc2_compiled\.)/ ) {
-           ; # toss it
-
-       } elsif ( /^ErrorIO_call_count/  # HACK!!!!
-              || /^[A-Za-z0-9_]+\.\d+$/
-              || /^.*_CAT/                     # PROF: _entryname_CAT
-              || /^CC_.*_struct/               # PROF: _CC_ccident_struct
-              || /^.*_done/                    # PROF: _module_done
-              || /^_module_registered/         # PROF: _module_registered
-              ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'data';
-           $chksymb[$i] = '';
-
-       } elsif ( /^([A-Za-z0-9_]+)\s+\.comm/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'bss';
-           $chksymb[$i] = $1;
-
-       } elsif ( /^(ret_|djn_)/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } elsif ( /^vtbl_([A-Za-z0-9_]+)$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'vector';
-           $chksymb[$i] = $1;
-
-           $vectorchk{$1} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)DirectReturn$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'direct';
-           $chksymb[$i] = $1;
-
-           $directchk{$1} = $i;
-
-       } elsif ( /^[A-Za-z0-9_]+_upd$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } elsif ( /^[A-Za-z0-9_]/ && ! /^L\$\d+$/) {
-           local($thing);
-           chop($thing = $_);
-           print STDERR "Funny global thing?: $_"
-               unless $KNOWN_FUNNY_THING{$thing}
-                   || /^_(PRIn|PRStart)/       # pointer reversal GC routines
-                   || /^CC_.*/                 # PROF: _CC_ccident
-                   || /^_reg.*/;               # PROF: _reg<module>
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } else { # simple line (duplicated at the top)
-           $chk[$i] .= $_;
-       }
-    }
-    $numchks = $#chk + 1;
-
-#    print STDERR "\nCLOSURES:\n";
-#    foreach $s (sort (keys %closurechk)) {
-#      print STDERR "$s:\t\t",$closurechk{$s},"\n";
-#    }
-#    print STDERR "\nNORMAL INFOS:\n";
-#    foreach $s (sort (keys %infochk)) {
-#      print STDERR "$s:\t\t",$infochk{$s},"\n";
-#    }
-#    print STDERR "SLOWS:\n";
-#    foreach $s (sort (keys %slowchk)) {
-#      print STDERR "$s:\t\t",$slowchk{$s},"\n";
-#    }
-#    print STDERR "\nFASTS:\n";
-#    foreach $s (sort (keys %fastchk)) {
-#      print STDERR "$s:\t\t",$fastchk{$s},"\n";
-#    }
-
-    # the division into chunks is imperfect;
-    # we throw some things over the fence into the next
-    # chunk.
-    #
-    # also, there are things we would like to know
-    # about the whole module before we start spitting
-    # output.
-
-    # NB: we start meddling at chunk 1, not chunk 0
-
-    for ($i = 1; $i < $numchks; $i++) {
-       $c = $chk[$i]; # convenience copy
-
-#      print STDERR "\nCHK $i (BEFORE):\n", $c;
-
-       # toss all prologue stuff
-       $c =~ s/^\s+\.ENTRY[^\0]*--- BEGIN ---/\t.ENTRY/;
-
-        # Lie about our .CALLINFO
-        $c =~ s/^\s+\.CALLINFO.*$/\t.CALLINFO NO_CALLS,NO_UNWIND/;
-
-       # Get rid of P'
-
-       $c =~ s/LP'/L'/g;
-       $c =~ s/RP'/R'/g;
-
-#      print STDERR "\nCHK $i (STEP 1):\n", $c;
-
-       # toss all epilogue stuff
-       $c =~ s/^\s+--- END ---[^\0]*\.EXIT/\t.EXIT/;
-
-#      print STDERR "\nCHK $i (STEP 2):\n", $c;
-
-       # Sorry; we moved the _info stuff to the code segment.
-       $c =~ s/_info,DATA/_info,CODE/g;
-
-       # pin a funny end-thing on (for easier matching):
-       $c .= 'FUNNY#END#THING';
-
-       # pick some end-things and move them to the next chunk
-
-#      print STDERR "\nCHK $i (STEP 3):\n", $c;
-       while ($c =~ /^(\s+\.(IMPORT|EXPORT|PARAM).*\n)FUNNY#END#THING/
-             || $c =~ /^(\s+\.align\s+\d+\n)FUNNY#END#THING/
-            || $c =~ /^(\s+\.(SPACE|SUBSPA)\s+\S+\n)FUNNY#END#THING/
-             ||  $c =~ /^(\s*\n)FUNNY#END#THING/ ) {
-           $to_move = $1;
-
-           if ( $i < ($numchks - 1) && ($to_move =~ /^\s+\.(IMPORT|EXPORT)/ 
-                || ($to_move =~ /align/ && $chkcat[$i+1] eq 'literal')) ) {
-               $chk[$i + 1] = $to_move . $chk[$i + 1];
-               # otherwise they're tossed
-           }
-           $c =~ s/^.*\nFUNNY#END#THING/FUNNY#END#THING/;
-       }
-#      print STDERR "\nCHK $i (STEP 4):\n", $c;
-
-       $c =~ s/FUNNY#END#THING//;
-       $chk[$i] = $c; # update w/ convenience copy
-    }
-
-    # print out the header stuff first
-
-    print OUTASM $chk[0];
-
-    # print out all the literals second
-    
-    for ($i = 1; $i < $numchks; $i++) {
-       if ( $chkcat[$i] eq 'literal' ) {
-           print OUTASM "\t.SPACE \$TEXT\$\n\t.SUBSPA \$LIT\$\n";
-           print OUTASM $chk[$i];
-           print OUTASM "; end literal\n"; # for the splitter
-
-           $chkcat[$i] = 'DONE ALREADY';
-       }
-    }
-
-    # print out all the bss third
-    
-    for ($i = 1; $i < $numchks; $i++) {
-       if ( $chkcat[$i] eq 'bss' ) {
-           print OUTASM "\t.SPACE \$PRIVATE\$\n\t.SUBSPA \$BSS\$\n\t.align 4\n";
-           print OUTASM $chk[$i];
-           
-           $chkcat[$i] = 'DONE ALREADY';
-       }
-    }
-
-    for ($i = 1; $i < $numchks; $i++) {
-#      print STDERR "$i: cat $chkcat[$i], symb $chksymb[$i]\n";
-
-       next if $chkcat[$i] eq 'DONE ALREADY';
-
-       if ( $chkcat[$i] eq 'misc' ) {
-           print OUTASM "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
-           print OUTASM $chk[$i];
-
-       } elsif ( $chkcat[$i] eq 'data' ) {
-           print OUTASM "\t.SPACE \$PRIVATE\$\n\t.SUBSPA \$DATA\$\n\t\.align 4\n";
-           print OUTASM $chk[$i];
-
-       } elsif ( $chkcat[$i] eq 'consist' ) {
-           if ( $chk[$i] =~ /\.STRING.*\)(hsc|cc) (.*)\\x09(.*)\\x00/ ) {
-               local($consist) = "$1.$2.$3";
-               $consist =~ s/,/./g;
-               $consist =~ s/\//./g;
-               $consist =~ s/-/_/g;
-               $consist =~ s/[^A-Za-z0-9_.]/ZZ/g; # ToDo: properly?
-               print OUTASM "\t.SPACE \$TEXT\$\n\t.SUBSPA \$LIT\$\n$consist\n";
-           } else {
-               print STDERR "Couldn't grok consistency: ", $chk[$i];
-           }
-
-       } elsif ( $chkcat[$i] eq 'splitmarker' ) {
-           # we can just re-constitute this one...
-           # ignore the final split marker, to save an empty object module
-           # Use _three_ underscores so that ghc-split doesn't get overly complicated
-           print OUTASM "___stg_split_marker$chksymb[$i]\n";
-
-       } elsif ( $chkcat[$i] eq 'closure'
-              || $chkcat[$i] eq 'infotbl'
-              || $chkcat[$i] eq 'slow'
-              || $chkcat[$i] eq 'fast' ) { # do them in that order
-           $symb = $chksymb[$i];
-
-           # CLOSURE
-           if ( defined($closurechk{$symb}) ) {
-               print OUTASM "\t.SPACE \$PRIVATE\$\n\t.SUBSPA \$DATA\$\n\t\.align 4\n";
-               print OUTASM $chk[$closurechk{$symb}];
-               $chkcat[$closurechk{$symb}] = 'DONE ALREADY';
-           }
-
-           # INFO TABLE
-           if ( defined($infochk{$symb}) ) {
-               print OUTASM "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
-               print OUTASM &rev_tbl($symb, $chk[$infochk{$symb}], 1);
-               # entry code will be put here!
-
-               # paranoia
-               if ( $chk[$infochk{$symb}] =~ /\.word\s+([A-Za-z0-9_]+_entry)$/
-                 && $1 ne "${symb}_entry" ) {
-                   print STDERR "!!! entry point???\n",$chk[$infochk{$symb}];
-               }
-
-               $chkcat[$infochk{$symb}] = 'DONE ALREADY';
-           }
-
-           # STD ENTRY POINT
-           if ( defined($slowchk{$symb}) ) {
-
-               # teach it to drop through to the fast entry point:
-               $c = $chk[$slowchk{$symb}];
-               if ( defined($fastchk{$symb}) ) {
-                   $c =~ s/^\s+ldil.*\n\s+ldo.*\n\s+bv.*\n(.*\n)?\s+\.EXIT/$1\t.EXIT/;
-               }
-
-               # ToDo: ???? any good way to look for "dangling" references
-               # to fast-entry pt ???
-
-               print OUTASM "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
-               print OUTASM $c;
-               $chkcat[$slowchk{$symb}] = 'DONE ALREADY';
-           }
-           
-           # FAST ENTRY POINT
-           if ( defined($fastchk{$symb}) ) {
-               $c = $chk[$fastchk{$symb}];
-               if ( ! defined($slowchk{$symb}) ) {
-                   print OUTASM "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
-               }
-               print OUTASM $c;
-               $chkcat[$fastchk{$symb}] = 'DONE ALREADY';
-           }
-
-       } elsif ( $chkcat[$i] eq 'vector'
-              || $chkcat[$i] eq 'direct' ) { # do them in that order
-           $symb = $chksymb[$i];
-
-           # VECTOR TABLE
-           if ( defined($vectorchk{$symb}) ) {
-               print OUTASM "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
-               print OUTASM &rev_tbl($symb, $chk[$vectorchk{$symb}], 0);
-               # direct return code will be put here!
-               $chkcat[$vectorchk{$symb}] = 'DONE ALREADY';
-           }
-
-           # DIRECT RETURN
-           if ( defined($directchk{$symb}) ) {
-               print OUTASM "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
-               print OUTASM $chk[$directchk{$symb}];
-               $chkcat[$directchk{$symb}] = 'DONE ALREADY';
-           }
-       } else {
-           &tidy_up_and_die(1,"$Pgm: unknown chkcat (ghc-asm hppa)\n$chkcat[$i]\n$chk[$i]\n");
-       }
-    }
-
-    # finished:
-    close(OUTASM) || &tidy_up_and_die(1,"Failed writing to $out_asmf\n");
-    close(INASM)  || &tidy_up_and_die(1,"Failed reading from $in_asmf\n");
-}
-\end{code}
-
-The HP is a major nuisance.  The threaded code mangler moved info tables
-from data space to code space, but unthreaded code in the RTS still has
-references to info tables in data space.  Since the HP linker is very precise
-about where symbols live, we need to patch the references in the unthreaded
-RTS as well.
-
-\begin{code}
-
-sub mini_mangle_asm {
-    local($in_asmf, $out_asmf) = @_;
-
-    open(INASM, "< $in_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$in_asmf' (to read)\n");
-    open(OUTASM,"> $out_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$out_asmf' (to write)\n");
-
-    while (<INASM>) {
-       s/_info,DATA/_info,CODE/;   # Move _info references to code space
-       s/P%_PR/_PR/;
-       print OUTASM;
-    }
-
-    # finished:
-    close(OUTASM) || &tidy_up_and_die(1,"Failed writing to $out_asmf\n");
-    close(INASM)  || &tidy_up_and_die(1,"Failed reading from $in_asmf\n");
-}
-
-\end{code}
-
-\begin{code}
-sub init_FUNNY_THINGS {
-    %KNOWN_FUNNY_THING = (
-       'CheckHeapCode', 1,
-       'CommonUnderflow', 1,
-       'Continue', 1,
-       'EnterNodeCode', 1,
-       'ErrorIO_call_count', 1,
-       'ErrorIO_innards', 1,
-       'IndUpdRetDir', 1,
-       'IndUpdRetV0', 1,
-       'IndUpdRetV1', 1,
-       'IndUpdRetV2', 1,
-       'IndUpdRetV3', 1,
-       'IndUpdRetV4', 1,
-       'IndUpdRetV5', 1,
-       'IndUpdRetV6', 1,
-       'IndUpdRetV7', 1,
-       'PrimUnderflow', 1,
-       'StackUnderflowEnterNode', 1,
-       'StdErrorCode', 1,
-       'UnderflowVect0', 1,
-       'UnderflowVect1', 1,
-       'UnderflowVect2', 1,
-       'UnderflowVect3', 1,
-       'UnderflowVect4', 1,
-       'UnderflowVect5', 1,
-       'UnderflowVect6', 1,
-       'UnderflowVect7', 1,
-       'UpdErr', 1,
-       'UpdatePAP', 1,
-       'WorldStateToken', 1,
-       '_Enter_Internal', 1,
-       '_PRMarking_MarkNextAStack', 1,
-       '_PRMarking_MarkNextBStack', 1,
-       '_PRMarking_MarkNextCAF', 1,
-       '_PRMarking_MarkNextGA', 1,
-       '_PRMarking_MarkNextRoot', 1,
-       '_PRMarking_MarkNextSpark', 1,
-       '_Scavenge_Forward_Ref', 1,
-       '__std_entry_error__', 1,
-       '_startMarkWorld', 1,
-       'resumeThread', 1,
-       'startCcRegisteringWorld', 1,
-       'startEnterFloat', 1,
-       'startEnterInt', 1,
-       'startPerformIO', 1,
-       'startStgWorld', 1,
-       'stopPerformIO', 1
-    );
-}
-\end{code}
-
-The following table reversal is used for both info tables and return
-vectors.  In both cases, we remove the first entry from the table,
-reverse the table, put the label at the end, and paste some code
-(that which is normally referred to by the first entry in the table)
-right after the table itself.  (The code pasting is done elsewhere.)
-
-\begin{code}
-sub rev_tbl {
-    local($symb, $tbl, $discard1) = @_;
-
-    local($before) = '';
-    local($label) = '';
-    local(@imports) = ();
-    local(@words) = ();
-    local($after) = '';
-    local(@lines) = split(/\n/, $tbl);
-    local($i);
-
-    for ($i = 0; $i <= $#lines && $lines[$i] !~ /^\s+\.word\s+/; $i++) {
-       $label .= $lines[$i] . "\n",
-           next if $lines[$i] =~ /^[A-Za-z0-9_]+$/
-                || $lines[$i] =~ /^\s+\.EXPORT/;
-
-       $before .= $lines[$i] . "\n"; # otherwise...
-    }
-
-    for ( ; $i <= $#lines && $lines[$i] =~ /^\s+\.(word|IMPORT)/; $i++) {
-       if ($lines[$i] =~ /^\s+\.IMPORT/) {
-           push(@imports, $lines[$i]);
-       } else {
-           # We don't use HP's ``function pointers''
-            # We just use labels in code space, like normal people
-           $lines[$i] =~ s/P%//;
-           push(@words, $lines[$i]);
-       }
-    }
-    # now throw away the first word (entry code):
-    if ($discard1) {
-       shift(@words);
-    }
-
-    for (; $i <= $#lines; $i++) {
-       $after .= $lines[$i] . "\n";
-    }
-
-    $tbl = $before . join("\n", @imports) . "\n" .
-           join("\n", (reverse @words)) . "\n" . $label . $after;
-
-#    print STDERR "before=$before\n";
-#    print STDERR "label=$label\n";
-#    print STDERR "words=",(reverse @words),"\n";
-#    print STDERR "after=$after\n";
-
-    $tbl;
-}
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[Driver-asm-info]{Collect interesting (static) info from an assembler file}
-%*                                                                     *
-%************************************************************************
-
-How many times is each asm instruction used?
-
-\begin{code}
-%AsmInsn = (); # init
-
-sub dump_asm_insn_counts {
-    local($asmf) = @_;
-
-    open(INASM, "< $asmf")  || &tidy_up_and_die(1,"$Pgm: failed to open `$asmf' (to read)\n");
-    while (<INASM>) {
-       if ( /^\t([a-z][a-z0-9]+)\b/ ) {
-           $AsmInsn{$1} ++;
-       }
-    }
-    close(INASM) || &tidy_up_and_die(1,"Failed reading from $asmf\n");
-
-    # OK, now print what we collected (to stderr)
-    foreach $i (sort (keys %AsmInsn)) {
-       print STDERR "INSN:: $i\t",$AsmInsn{$i},"\n";
-    }
-}
-
-sub dump_asm_globals_info {
-}
-
-# make "require"r happy...
-1;
-\end{code}
diff --git a/ghc/driver/ghc-asm-m68k.lprl b/ghc/driver/ghc-asm-m68k.lprl
deleted file mode 100644 (file)
index e3a1431..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-%************************************************************************
-%*                                                                     *
-\section[Driver-asm-fiddling]{Fiddling with assembler files (m68k)}
-%*                                                                     *
-%************************************************************************
-
-Tasks:
-\begin{itemize}
-\item
-Utterly stomp out C functions' prologues and epilogues; i.e., the
-stuff to do with the C stack.
-\item
-Any other required tidying up.
-\end{itemize}
-
-\begin{code}
-sub mangle_asm {
-    local($in_asmf, $out_asmf) = @_;
-
-    # multi-line regexp matching:
-    local($*) = 1;
-    local($i, $c);
-    &init_FUNNY_THINGS();
-
-    open(INASM, "< $in_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$in_asmf' (to read)\n");
-    open(OUTASM,"> $out_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$out_asmf' (to write)\n");
-
-    # read whole file, divide into "chunks":
-    #  record some info about what we've found...
-
-    @chk = ();         # contents of the chunk
-    $numchks = 0;      # number of them
-    @chkcat = ();      # what category of thing in each chunk
-    @chksymb = ();     # what symbol(base) is defined in this chunk
-    %slowchk = ();     # ditto, its regular "slow" entry code
-    %fastchk = ();     # ditto, fast entry code
-    %closurechk = ();  # ditto, the (static) closure
-    %infochk = ();     # given a symbol base, say what chunk its info tbl is in
-    %vectorchk = ();    # ditto, return vector table
-    %directchk = ();    # ditto, direct return code
-
-    $i = 0;
-    $chkcat[0] = 'misc';
-
-    while (<INASM>) {
-       next if /^\.stab.*___stg_split_marker/;
-       next if /^\.stab.*ghc.*c_ID/;
-       next if /^#(NO_)?APP/;
-
-       if ( /^\s+/ ) { # most common case first -- a simple line!
-           # duplicated from the bottom
-
-           $chk[$i] .= $_;
-
-       } elsif ( /^LC(\d+):$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'string';
-           $chksymb[$i] = $1;
-
-       } elsif ( /^___stg_split_marker(\d+):$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'splitmarker';
-           $chksymb[$i] = $1;
-
-       } elsif ( /^_([A-Za-z0-9_]+)_info:$/ ) {
-           $symb = $1;
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'infotbl';
-           $chksymb[$i] = $symb;
-
-           die "Info table already? $symb; $i\n" if defined($infochk{$symb});
-
-           $infochk{$symb} = $i;
-
-       } elsif ( /^_([A-Za-z0-9_]+)_entry:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'slow';
-           $chksymb[$i] = $1;
-
-           $slowchk{$1} = $i;
-
-       } elsif ( /^_([A-Za-z0-9_]+)_fast\d+:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'fast';
-           $chksymb[$i] = $1;
-
-           $fastchk{$1} = $i;
-
-       } elsif ( /^_([A-Za-z0-9_]+)_closure:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'closure';
-           $chksymb[$i] = $1;
-
-           $closurechk{$1} = $i;
-
-       } elsif ( /^_ghc.*c_ID:/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'consist';
-
-       } elsif ( /^(___gnu_compiled_c|gcc2_compiled\.):/ ) {
-           ; # toss it
-
-       } elsif ( /^_ErrorIO_call_count:/        # HACK!!!!
-              || /^_[A-Za-z0-9_]+\.\d+:$/
-              || /^_.*_CAT:/                   # PROF: _entryname_CAT
-              || /^_CC_.*_struct:/             # PROF: _CC_ccident_struct
-              || /^_.*_done:/                  # PROF: _module_done
-              || /^__module_registered:/       # PROF: _module_registered
-              ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'data';
-           $chksymb[$i] = '';
-
-       } elsif ( /^_(ret_|djn_)/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } elsif ( /^_vtbl_([A-Za-z0-9_]+):$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'vector';
-           $chksymb[$i] = $1;
-
-           $vectorchk{$1} = $i;
-
-       } elsif ( /^_([A-Za-z0-9_]+)DirectReturn:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'direct';
-           $chksymb[$i] = $1;
-
-           $directchk{$1} = $i;
-
-       } elsif ( /^_[A-Za-z0-9_]+_upd:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } elsif ( /^_[A-Za-z0-9_]/ ) {
-           local($thing);
-           chop($thing = $_);
-           print STDERR "Funny global thing?: $_"
-               unless $KNOWN_FUNNY_THING{$thing}
-                   || /^__(PRIn|PRStart).*:/   # pointer reversal GC routines
-                   || /^_CC_.*:/               # PROF: _CC_ccident
-                   || /^__reg.*:/;             # PROF: __reg<module>
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } else { # simple line (duplicated at the top)
-
-           $chk[$i] .= $_;
-       }
-    }
-    $numchks = $#chk + 1;
-
-    # the division into chunks is imperfect;
-    # we throw some things over the fence into the next
-    # chunk.
-    #
-    # also, there are things we would like to know
-    # about the whole module before we start spitting
-    # output.
-
-    # NB: we start meddling at chunk 1, not chunk 0
-
-    for ($i = 1; $i < $numchks; $i++) {
-       $c = $chk[$i]; # convenience copy
-
-#      print STDERR "\nCHK $i (BEFORE) (",$chkcat[$i],"):\n", $c;
-
-       # toss all prologue stuff;
-       # be slightly paranoid to make sure there's
-       # nothing surprising in there
-       if ( $c =~ /--- BEGIN ---/ ) {
-           if (($p, $r) = split(/--- BEGIN ---/, $c)) {
-               $p =~ s/^\tlink a6,#-?\d.*\n//;
-               $p =~ s/^\tmovel d2,sp\@-\n//;
-               $p =~ s/^\tmovel d5,sp\@-\n//; # SMmark.* only?
-               $p =~ s/^\tmoveml \#0x[0-9a-f]+,sp\@-\n//; # SMmark.* only?
-               die "Prologue junk?: $p\n" if $p =~ /^\t[^\.]/;
-
-               # glue together what's left
-               $c = $p . $r;
-           }
-       }
-
-       # toss all epilogue stuff; again, paranoidly
-       if ( $c =~ /--- END ---/ ) {
-           if (($r, $e) = split(/--- END ---/, $c)) {
-               $e =~ s/^\tunlk a6\n//;
-               $e =~ s/^\trts\n//;
-               die "Epilogue junk?: $e\n" if $e =~ /^\t[^\.]/;
-
-               # glue together what's left
-               $c = $r . $e;
-           }
-       }
-
-       # toss all calls to __DISCARD__
-       $c =~ s/^\tjbsr ___DISCARD__\n//g;
-
-       # toss stack adjustment after DoSparks
-       $c =~ s/^(\tjbsr _DoSparks\n)\taddqw #8,sp/$1/g;
-
-       # pin a funny end-thing on (for easier matching):
-       $c .= 'FUNNY#END#THING';
-
-       # pick some end-things and move them to the next chunk
-
-       while ( $c =~ /^\s*(\.align\s+\d+\n|\.proc\s+\d+\n|\.const\n|\.cstring\n|\.globl\s+\S+\n|\.text\n|\.data\n|\.even\n|\.stab[^n].*\n)FUNNY#END#THING/ ) {
-           $to_move = $1;
-
-           if ( $to_move =~ /\.(globl|proc|stab)/ && $i < ($numchks - 1) ) {
-               $chk[$i + 1] = $to_move . $chk[$i + 1];
-               # otherwise they're tossed
-           }
-
-           $c =~ s/^.*\nFUNNY#END#THING/FUNNY#END#THING/;
-       }
-
-       $c =~ s/FUNNY#END#THING//;
-       $chk[$i] = $c; # update w/ convenience copy
-    }
-
-    # print out all the literal strings first
-    for ($i = 0; $i < $numchks; $i++) {
-       if ( $chkcat[$i] eq 'string' ) {
-           print OUTASM "\.text\n\t\.even\n";
-           print OUTASM $chk[$i];
-           
-           $chkcat[$i] = 'DONE ALREADY';
-       }
-    }
-
-    for ($i = 0; $i < $numchks; $i++) {
-#      print STDERR "$i: cat $chkcat[$i], symb $chksymb[$i]\n";
-
-       next if $chkcat[$i] eq 'DONE ALREADY';
-
-       if ( $chkcat[$i] eq 'misc' ) {
-           print OUTASM "\.text\n\t\.even\n";
-           print OUTASM $chk[$i];
-
-       } elsif ( $chkcat[$i] eq 'data' ) {
-           print OUTASM "\.data\n\t\.even\n";
-           print OUTASM $chk[$i];
-
-       } elsif ( $chkcat[$i] eq 'consist' ) {
-           if ( $chk[$i] =~ /\.ascii.*\)(hsc|cc) (.*)\\11"\n\t\.ascii\s+"(.*)\\0"/ ) {
-               local($consist) = "$1.$2.$3";
-               $consist =~ s/,/./g;
-               $consist =~ s/\//./g;
-               $consist =~ s/-/_/g;
-               $consist =~ s/[^A-Za-z0-9_.]/ZZ/g; # ToDo: properly?
-               print OUTASM "\.text\n$consist:\n";
-           } else {
-               print STDERR "Couldn't grok consistency: ", $chk[$i];
-           }
-
-       } elsif ( $chkcat[$i] eq 'splitmarker' ) {
-           # we can just re-constitute this one...
-           print OUTASM "___stg_split_marker",$chksymb[$i],":\n";
-
-       } elsif ( $chkcat[$i] eq 'closure'
-              || $chkcat[$i] eq 'infotbl'
-              || $chkcat[$i] eq 'slow'
-              || $chkcat[$i] eq 'fast' ) { # do them in that order
-           $symb = $chksymb[$i];
-
-           # CLOSURE
-           if ( defined($closurechk{$symb}) ) {
-               print OUTASM "\.data\n\t\.even\n";
-               print OUTASM $chk[$closurechk{$symb}];
-               $chkcat[$closurechk{$symb}] = 'DONE ALREADY';
-           }
-
-           # INFO TABLE
-           if ( defined($infochk{$symb}) ) {
-
-               print OUTASM "\.text\n\t\.even\n";
-               print OUTASM &rev_tbl($symb, $chk[$infochk{$symb}], 1);
-               # entry code will be put here!
-
-               # paranoia
-               if ( $chk[$infochk{$symb}] =~ /\.long\s+([A-Za-z0-9_]+_entry)$/
-                 && $1 ne "_${symb}_entry" ) {
-                   print STDERR "!!! entry point???\n",$chk[$infochk{$symb}];
-               }
-
-               $chkcat[$infochk{$symb}] = 'DONE ALREADY';
-           }
-
-           # STD ENTRY POINT
-           if ( defined($slowchk{$symb}) ) {
-
-               # teach it to drop through to the fast entry point:
-               $c = $chk[$slowchk{$symb}];
-
-               if ( defined($fastchk{$symb}) ) {
-                   $c =~ s/^\tjmp _${symb}_fast\d+.*\n\tnop\n//;
-                   $c =~ s/^\tjmp _${symb}_fast\d+.*\n//;
-               }
-
-               print STDERR "still has jump to fast entry point:\n$c"
-                   if $c =~ /_${symb}_fast/; # NB: paranoia
-
-               print OUTASM "\.text\n\t\.even\n";
-               print OUTASM $c;
-               $chkcat[$slowchk{$symb}] = 'DONE ALREADY';
-           }
-           
-           # FAST ENTRY POINT
-           if ( defined($fastchk{$symb}) ) {
-               print OUTASM "\.text\n\t\.even\n";
-               print OUTASM $chk[$fastchk{$symb}];
-               $chkcat[$fastchk{$symb}] = 'DONE ALREADY';
-           }
-
-       } elsif ( $chkcat[$i] eq 'vector'
-              || $chkcat[$i] eq 'direct' ) { # do them in that order
-           $symb = $chksymb[$i];
-
-           # VECTOR TABLE
-           if ( defined($vectorchk{$symb}) ) {
-               print OUTASM "\.text\n\t\.even\n";
-               print OUTASM &rev_tbl($symb, $chk[$vectorchk{$symb}], 0);
-               # direct return code will be put here!
-               $chkcat[$vectorchk{$symb}] = 'DONE ALREADY';
-           }
-
-           # DIRECT RETURN
-           if ( defined($directchk{$symb}) ) {
-               print OUTASM "\.text\n\t\.even\n";
-               print OUTASM $chk[$directchk{$symb}];
-               $chkcat[$directchk{$symb}] = 'DONE ALREADY';
-           }
-           
-       } else {
-           &tidy_up_and_die(1,"$Pgm: unknown chkcat (ghc-asm m68k)\n$chkcat[$i]\n$chk[$i]\n");
-       }
-    }
-
-    # finished:
-    close(OUTASM) || &tidy_up_and_die(1,"Failed writing to $out_asmf\n");
-    close(INASM)  || &tidy_up_and_die(1,"Failed reading from $in_asmf\n");
-}
-\end{code}
-
-\begin{code}
-sub init_FUNNY_THINGS {
-    %KNOWN_FUNNY_THING = (
-       '_CheckHeapCode:', 1,
-       '_CommonUnderflow:', 1,
-       '_Continue:', 1,
-       '_EnterNodeCode:', 1,
-       '_ErrorIO_call_count:', 1,
-       '_ErrorIO_innards:', 1,
-       '_IndUpdRetDir:', 1,
-       '_IndUpdRetV0:', 1,
-       '_IndUpdRetV1:', 1,
-       '_IndUpdRetV2:', 1,
-       '_IndUpdRetV3:', 1,
-       '_IndUpdRetV4:', 1,
-       '_IndUpdRetV5:', 1,
-       '_IndUpdRetV6:', 1,
-       '_IndUpdRetV7:', 1,
-       '_PrimUnderflow:', 1,
-       '_StackUnderflowEnterNode:', 1,
-       '_StdErrorCode:', 1,
-       '_UnderflowVect0:', 1,
-       '_UnderflowVect1:', 1,
-       '_UnderflowVect2:', 1,
-       '_UnderflowVect3:', 1,
-       '_UnderflowVect4:', 1,
-       '_UnderflowVect5:', 1,
-       '_UnderflowVect6:', 1,
-       '_UnderflowVect7:', 1,
-       '_UpdErr:', 1,
-       '_UpdatePAP:', 1,
-       '_WorldStateToken:', 1,
-       '__Enter_Internal:', 1,
-       '__PRMarking_MarkNextAStack:', 1,
-       '__PRMarking_MarkNextBStack:', 1,
-       '__PRMarking_MarkNextCAF:', 1,
-       '__PRMarking_MarkNextGA:', 1,
-       '__PRMarking_MarkNextRoot:', 1,
-       '__PRMarking_MarkNextSpark:', 1,
-       '__Scavenge_Forward_Ref:', 1,
-       '___std_entry_error__:', 1,
-       '__startMarkWorld:', 1,
-       '_resumeThread:', 1,
-       '_startCcRegisteringWorld:', 1,
-       '_startEnterFloat:', 1,
-       '_startEnterInt:', 1,
-       '_startPerformIO:', 1,
-       '_startStgWorld:', 1,
-       '_stopPerformIO:', 1
-    );
-}
-\end{code}
-
-The following table reversal is used for both info tables and return
-vectors.  In both cases, we remove the first entry from the table,
-reverse the table, put the label at the end, and paste some code
-(that which is normally referred to by the first entry in the table)
-right after the table itself.  (The code pasting is done elsewhere.)
-
-\begin{code}
-sub rev_tbl {
-    local($symb, $tbl, $discard1) = @_;
-
-    local($before) = '';
-    local($label) = '';
-    local(@words) = ();
-    local($after) = '';
-    local(@lines) = split(/\n/, $tbl);
-    local($i);
-
-    for ($i = 0; $i <= $#lines && $lines[$i] !~ /^\t\.long\s+/; $i++) {
-       $label .= $lines[$i] . "\n",
-           next if $lines[$i] =~ /^[A-Za-z0-9_]+_info:$/
-                || $lines[$i] =~ /^\.globl/
-                || $lines[$i] =~ /^_vtbl_\S+:$/;
-
-       $before .= $lines[$i] . "\n"; # otherwise...
-    }
-
-    for ( ; $i <= $#lines && $lines[$i] =~ /^\t\.long\s+/; $i++) {
-       push(@words, $lines[$i]);
-    }
-    # now throw away the first word (entry code):
-    shift(@words) if $discard1;
-
-    for (; $i <= $#lines; $i++) {
-       $after .= $lines[$i] . "\n";
-    }
-
-    $tbl = $before . join("\n", (reverse @words)) . "\n" . $label . $after;
-
-#   print STDERR "before=$before\n";
-#   print STDERR "label=$label\n";
-#   print STDERR "words=",(reverse @words),"\n";
-#   print STDERR "after=$after\n";
-
-    $tbl;
-}
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[Driver-asm-info]{Collect interesting (static) info from an assembler file}
-%*                                                                     *
-%************************************************************************
-
-How many times is each asm instruction used?
-
-\begin{code}
-%AsmInsn = (); # init
-
-sub dump_asm_insn_counts {
-    local($asmf) = @_;
-
-    open(INASM, "< $asmf")  || &tidy_up_and_die(1,"$Pgm: failed to open `$asmf' (to read)\n");
-    while (<INASM>) {
-       if ( /^\t([a-z][a-z0-9]+)\b/ ) {
-           $AsmInsn{$1} ++;
-       }
-    }
-    close(INASM) || &tidy_up_and_die(1,"Failed reading from $asmf\n");
-
-    # OK, now print what we collected (to stderr)
-    foreach $i (sort (keys %AsmInsn)) {
-       print STDERR "INSN:: $i\t",$AsmInsn{$i},"\n";
-    }
-}
-
-sub dump_asm_globals_info {
-}
-
-# make "require"r happy...
-1;
-
-\end{code}
diff --git a/ghc/driver/ghc-asm-mips.lprl b/ghc/driver/ghc-asm-mips.lprl
deleted file mode 100644 (file)
index 3c210cb..0000000
+++ /dev/null
@@ -1,529 +0,0 @@
-%************************************************************************
-%*                                                                     *
-\section[Driver-asm-fiddling]{Fiddling with assembler files (SGI MIPS box)}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-sub mangle_asm {
-    local($in_asmf, $out_asmf) = @_;
-
-    # multi-line regexp matching:
-    local($*) = 1;
-    local($i, $c);
-    &init_FUNNY_THINGS();
-
-    open(INASM, "< $in_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$in_asmf' (to read)\n");
-    open(OUTASM,"> $out_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$out_asmf' (to write)\n");
-
-    # read whole file, divide into "chunks":
-    #  record some info about what we've found...
-
-    @chk = ();         # contents of the chunk
-    $numchks = 0;      # number of them
-    @chkcat = ();      # what category of thing in each chunk
-    @chksymb = ();     # what symbol(base) is defined in this chunk
-    %slowchk = ();     # ditto, its regular "slow" entry code
-    %fastchk = ();     # ditto, fast entry code
-    %closurechk = ();  # ditto, the (static) closure
-    %infochk = ();     # given a symbol base, say what chunk its info tbl is in
-    %vectorchk = ();    # ditto, return vector table
-    %directchk = ();    # ditto, direct return code
-    $EXTERN_DECLS = '';        # .globl <foo> .text
-
-    $i = 0;
-    $chkcat[0] = 'misc';
-
-    while (<INASM>) {
-
-       next if /^$/; # blank line
-       next if /^\s*#(NO_)?APP/;
-       next if /^\t\.file\t/;
-       next if /^ # /;
-
-       if ( /^\t\.(globl \S+ \.text|comm\t)/ ) {
-           $EXTERN_DECLS .= $_ unless /(__DISCARD__|\b(PK_|ASSIGN_)(FLT|DBL)\b)/;
-
-       } elsif ( /^\s+/ ) { # most common case first -- a simple line!
-           # duplicated from the bottom
-           $chk[$i] .= $_;
-
-       # NB: all the rest start with a non-space
-
-       } elsif ( /^\d+:/ ) { # a funny-looking very-local label
-           $chk[$i] .= $_;
-
-       } elsif ( /^\$LC(\d+):$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'string';
-           $chksymb[$i] = $1;
-
-       } elsif ( /^__stg_split_marker(\d+):$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'splitmarker';
-           $chksymb[$i] = $1;
-
-       } elsif ( /^([A-Za-z0-9_]+)_info:$/ ) {
-           $symb = $1;
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'infotbl';
-           $chksymb[$i] = $symb;
-
-           die "Info table already? $symb; $i\n" if defined($infochk{$symb});
-
-           $infochk{$symb} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)_entry:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'slow';
-           $chksymb[$i] = $1;
-
-           $slowchk{$1} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)_fast\d+:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'fast';
-           $chksymb[$i] = $1;
-
-           $fastchk{$1} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)_closure:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'closure';
-           $chksymb[$i] = $1;
-
-           $closurechk{$1} = $i;
-
-       } elsif ( /^ghc.*c_ID:/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'consist';
-
-       } elsif ( /^(__gnu_compiled_c|gcc2_compiled\.):/ ) {
-           ; # toss it
-
-       } elsif ( /^ErrorIO_call_count:/         # HACK!!!!
-              || /^[A-Za-z0-9_]+\.\d+:$/
-              || /^.*_CAT:/                    # PROF: _entryname_CAT
-              || /^CC_.*_struct:/              # PROF: _CC_ccident_struct
-              || /^.*_done:/                   # PROF: _module_done
-              || /^_module_registered:/        # PROF: _module_registered
-              ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'data';
-           $chksymb[$i] = '';
-
-       } elsif ( /^(ret_|djn_)/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } elsif ( /^vtbl_([A-Za-z0-9_]+):$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'vector';
-           $chksymb[$i] = $1;
-
-           $vectorchk{$1} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)DirectReturn:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'direct';
-           $chksymb[$i] = $1;
-
-           $directchk{$1} = $i;
-
-       } elsif ( /^[A-Za-z0-9_]+_upd:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } elsif ( /^[A-Za-z0-9_]/ ) {
-           local($thing);
-           chop($thing = $_);
-           print STDERR "Funny global thing? ($.): $_"
-               unless $KNOWN_FUNNY_THING{$thing}
-                   || /^_(PRIn|PRStart).*:/    # pointer reversal GC routines
-                   || /^CC_.*:/                # PROF: _CC_ccident
-                   || /^_reg.*:/;              # PROF: _reg<module>
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } else { # simple line (duplicated at the top)
-           $chk[$i] .= $_;
-       }
-    }
-    $numchks = $#chk + 1;
-
-#    print STDERR "\nCLOSURES:\n";
-#    foreach $s (sort (keys %closurechk)) {
-#      print STDERR "$s:\t\t",$closurechk{$s},"\n";
-#    }
-#    print STDERR "\nINFOS:\n";
-#    foreach $s (sort (keys %infochk)) {
-#      print STDERR "$s:\t\t",$infochk{$s},"\n";
-#    }
-#    print STDERR "SLOWS:\n";
-#    foreach $s (sort (keys %slowchk)) {
-#      print STDERR "$s:\t\t",$slowchk{$s},"\n";
-#    }
-#    print STDERR "\nFASTS:\n";
-#    foreach $s (sort (keys %fastchk)) {
-#      print STDERR "$s:\t\t",$fastchk{$s},"\n";
-#    }
-
-    # the division into chunks is imperfect;
-    # we throw some things over the fence into the next
-    # chunk.
-    #
-    # also, there are things we would like to know
-    # about the whole module before we start spitting
-    # output.
-
-    # NB: we start meddling at chunk 1, not chunk 0
-
-    for ($i = 1; $i < $numchks; $i++) {
-       $c = $chk[$i]; # convenience copy
-
-#      print STDERR "\nCHK $i (BEFORE):\n", $c;
-
-       # pin a funny end-thing on (for easier matching):
-       $c .= 'FUNNY#END#THING';
-
-       # pick some end-things and move them to the next chunk
-
-       while ( $c =~ /^(\s*\.align\s+\d+\n)FUNNY#END#THING/
-            || $c =~ /^(\s*\.(globl|ent)\s+\S+\n)FUNNY#END#THING/
-            || $c =~ /^(\s*\.text\n|\s*\.r?data\n)FUNNY#END#THING/ ) {
-           $to_move = $1;
-
-           if ( $to_move =~ /\.(globl|ent)/ && $i < ($numchks - 1) ) {
-               $chk[$i + 1] = $to_move . $chk[$i + 1];
-               # otherwise they're tossed
-           }
-
-           $c =~ s/^.*\nFUNNY#END#THING/FUNNY#END#THING/;
-       }
-
-       # toss all prologue stuff;
-       # be slightly paranoid to make sure there's
-       # nothing surprising in there
-       if ( $c =~ /--- BEGIN ---/ ) {
-           if (($p, $r) = split(/--- BEGIN ---/, $c)) {
-               # the .frame/.mask/.fmask that we use is the same
-               # as that produced by GCC for miniInterpret; this
-               # gives GDB some chance of figuring out what happened
-               $FRAME = "\t.frame\t\$sp,2168,\$31\n\t.mask\t0x90000000,-4\n\t.fmask\t0x00000000,0\n";
-               $p =~ s/^\t\.(frame).*\n/__FRAME__/g;
-               $p =~ s/^\t\.(mask|fmask).*\n//g;
-               $p =~ s/^\t\.cprestore.*\n/\t\.cprestore 416\n/; # 16 + 100 4-byte args
-               $p =~ s/^\tsubu\t\$sp,\$sp,\d+\n//;
-               $p =~ s/^\tsw\t\$31,\d+\(\$sp\)\n//;
-               $p =~ s/^\tsw\t\$fp,\d+\(\$sp\)\n//;
-               $p =~ s/^\tsw\t\$28,\d+\(\$sp\)\n//;
-               $p =~ s/__FRAME__/$FRAME/;
-               die "Prologue junk?: $p\n" if $p =~ /^\t[^\.]/;
-
-               # glue together what's left
-               $c = $p . $r;
-               $c =~ s/\n\t\n/\n/; # junk blank line
-           }
-       }
-
-       # toss all epilogue stuff; again, paranoidly;
-       # first, this basic sequence may occur "--- END ---" or not
-       $c =~ s/^\tlw\t\$31,\d+\(\$sp\)\n\taddu\t\$sp,\$sp,\d+\n\tj\t\$31\n\t\.end/\t\.end/;
-
-       if ( $c =~ /--- END ---/ ) {
-           if (($r, $e) = split(/--- END ---/, $c)) {
-               $e =~ s/^\tlw\t\$31,\d+\(\$sp\)\n//;
-               $e =~ s/^\tlw\t\$fp,\d+\(\$sp\)\n//;
-               $e =~ s/^\taddu\t\$sp,\$sp,\d+\n//;
-               $e =~ s/^\tj\t\$31\n//;
-               die "Epilogue junk?: $e\n" if $e =~ /^\t[^\.]/;
-
-               # glue together what's left
-               $c = $r . $e;
-               $c =~ s/\n\t\n/\n/; # junk blank line
-           }
-       }
-
-       # toss all calls to __DISCARD__
-       $c =~ s/^\tjal\t__DISCARD__\n//g;
-       # that may leave some gratuitous asm macros around
-       # (no harm done; but we get rid of them to be tidier)
-       $c =~ s/^\t\.set\tnoreorder\n\t\.set\tnomacro\n\taddu\t(\S+)\n\t\.set\tmacro\n\t\.set\treorder\n/\taddu\t$1\n/;
-
-       $c =~ s/FUNNY#END#THING//;
-       $chk[$i] = $c; # update w/ convenience copy
-
-       print STDERR "NB: Contains magic stuff!\n$c\n" if $c =~ /^\t[^\.].*(\$28)\b/;
-
-#      print STDERR "\nCHK $i (AFTER):\n", $c;
-
-    }
-
-    # print out the header stuff first
-    $chk[0] = "\t\.file\t1 \"$ifile_root.hc\"\n" . $chk[0];
-
-    # get rid of horrible "<dollar>Revision: .*$" strings
-    local(@lines0) = split(/\n/, $chk[0]);
-    local($z) = 0;
-    while ( $z <= $#lines0 ) {
-       if ( $lines0[$z] =~ /^\t\.byte\t0x24,0x52,0x65,0x76,0x69,0x73,0x69,0x6f$/ ) {
-           undef($lines0[$z]);
-           $z++;
-           while ( $z <= $#lines0 ) {
-               undef($lines0[$z]);
-               last if $lines0[$z] =~ /[,\t]0x0$/;
-               $z++;
-           }
-       }
-       $z++;
-    }
-    $chk[0] = join("\n", @lines0);
-    $chk[0] =~ s/\n\n+/\n/;
-    print OUTASM $chk[0];
-
-    # print out all the literal strings second
-    for ($i = 1; $i < $numchks; $i++) {
-       if ( $chkcat[$i] eq 'string' ) {
-           print OUTASM "\t\.rdata\n\t\.align 2\n";
-           print OUTASM $chk[$i];
-           
-           $chkcat[$i] = 'DONE ALREADY';
-       }
-    }
-
-    for ($i = 1; $i < $numchks; $i++) {
-#      print STDERR "$i: cat $chkcat[$i], symb $chksymb[$i]\n";
-
-       next if $chkcat[$i] eq 'DONE ALREADY';
-
-       if ( $chkcat[$i] eq 'misc' ) {
-           print OUTASM "\t\.text\n\t\.align 2\n";
-           print OUTASM $chk[$i];
-
-       } elsif ( $chkcat[$i] eq 'data' ) {
-           print OUTASM "\t\.data\n\t\.align 2\n";
-           print OUTASM $chk[$i];
-
-       } elsif ( $chkcat[$i] eq 'consist' ) {
-#? consistency string is just a v
-#? horrible bunch of .bytes,
-#? which I am too lazy to sort out (WDP 95/05)
-#?         if ( $chk[$i] =~ /\.ascii.*\)(hsc|cc) (.*)\\11"\n\t\.ascii\s+"(.*)\\0"/ ) {
-#?             local($consist) = "$1.$2.$3";
-#?             $consist =~ s/,/./g;
-#?             $consist =~ s/\//./g;
-#?             $consist =~ s/-/_/g;
-#?             $consist =~ s/[^A-Za-z0-9_.]/ZZ/g; # ToDo: properly?
-#?             print OUTASM "\t\.text\n$consist:\n";
-#?         } else {
-#?             print STDERR "Couldn't grok consistency: ", $chk[$i];
-#?         }
-
-       } elsif ( $chkcat[$i] eq 'splitmarker' ) {
-           # we can just re-constitute this one...
-           # ignore the final split marker, to save an empty object module
-           # Use _three_ underscores so that ghc-split doesn't get overly complicated
-           print OUTASM "___stg_split_marker",$chksymb[$i],":\n";
-
-       } elsif ( $chkcat[$i] eq 'closure'
-              || $chkcat[$i] eq 'infotbl'
-              || $chkcat[$i] eq 'slow'
-              || $chkcat[$i] eq 'fast' ) { # do them in that order
-           $symb = $chksymb[$i];
-
-           # CLOSURE
-           if ( defined($closurechk{$symb}) ) {
-               print OUTASM "\t\.data\n\t\.align 2\n";
-               print OUTASM $chk[$closurechk{$symb}];
-               $chkcat[$closurechk{$symb}] = 'DONE ALREADY';
-           }
-
-           # INFO TABLE
-           if ( defined($infochk{$symb}) ) {
-
-               print OUTASM "\t\.text\n\t\.align 2\n";
-               print OUTASM &rev_tbl($symb, $chk[$infochk{$symb}], 1);
-               # entry code will be put here!
-
-               # paranoia
-               if ( $chk[$infochk{$symb}] =~ /\.word\s+([A-Za-z0-9_]+_entry)$/
-                 && $1 ne "${symb}_entry" ) {
-                   print STDERR "!!! entry point???\n",$chk[$infochk{$symb}];
-               }
-
-               $chkcat[$infochk{$symb}] = 'DONE ALREADY';
-           }
-
-           # STD ENTRY POINT
-           if ( defined($slowchk{$symb}) ) {
-
-               # teach it to drop through to the fast entry point:
-               $c = $chk[$slowchk{$symb}];
-
-               if ( defined($fastchk{$symb}) ) {
-                   $c =~ s/^\tjmp \$31,\(\$27\),0\n\t\.align 4\n\t\.end/\t.align 4\n\t.end/;
-               }
-
-               # ToDo??? any good way to look for "dangling" references
-               # to fast-entry pt ???
-
-               print OUTASM "\t\.text\n\t\.align 2\n";
-               print OUTASM $c;
-               $chkcat[$slowchk{$symb}] = 'DONE ALREADY';
-           }
-           
-           # FAST ENTRY POINT
-           if ( defined($fastchk{$symb}) ) {
-               $c = $chk[$fastchk{$symb}];
-               if ( ! defined($slowchk{$symb}) ) {
-                   print OUTASM "\t\.text\n\t\.align 2\n";
-               }
-               print OUTASM $c;
-               $chkcat[$fastchk{$symb}] = 'DONE ALREADY';
-           }
-
-       } elsif ( $chkcat[$i] eq 'vector'
-              || $chkcat[$i] eq 'direct' ) { # do them in that order
-           $symb = $chksymb[$i];
-
-           # VECTOR TABLE
-           if ( defined($vectorchk{$symb}) ) {
-               print OUTASM "\t\.text\n\t\.align 2\n";
-               print OUTASM &rev_tbl($symb, $chk[$vectorchk{$symb}], 0);
-               # direct return code will be put here!
-               $chkcat[$vectorchk{$symb}] = 'DONE ALREADY';
-           }
-
-           # DIRECT RETURN
-           if ( defined($directchk{$symb}) ) {
-               print OUTASM "\t\.text\n\t\.align 2\n";
-               print OUTASM $chk[$directchk{$symb}];
-               $chkcat[$directchk{$symb}] = 'DONE ALREADY';
-           } else {
-                # The commented nop is for the splitter, to ensure
-                # that no module ends with a label as the very last
-                # thing.  (The linker will adjust the label to point
-                # to the first code word of the next module linked in,
-                # even if alignment constraints cause the label to move!)
-
-               print OUTASM "\t# nop\n";
-           }
-       } else {
-           &tidy_up_and_die(1,"$Pgm: unknown chkcat (ghc-asm alpha)\n$chkcat[$i]\n$chk[$i]\n");
-       }
-    }
-
-    print OUTASM $EXTERN_DECLS;
-
-    # finished:
-    close(OUTASM) || &tidy_up_and_die(1,"Failed writing to $out_asmf\n");
-    close(INASM)  || &tidy_up_and_die(1,"Failed reading from $in_asmf\n");
-}
-\end{code}
-
-\begin{code}
-sub init_FUNNY_THINGS {
-    %KNOWN_FUNNY_THING = (
-       'CheckHeapCode:', 1,
-       'CommonUnderflow:', 1,
-       'Continue:', 1,
-       'EnterNodeCode:', 1,
-       'ErrorIO_call_count:', 1,
-       'ErrorIO_innards:', 1,
-       'IndUpdRetDir:', 1,
-       'IndUpdRetV0:', 1,
-       'IndUpdRetV1:', 1,
-       'IndUpdRetV2:', 1,
-       'IndUpdRetV3:', 1,
-       'IndUpdRetV4:', 1,
-       'IndUpdRetV5:', 1,
-       'IndUpdRetV6:', 1,
-       'IndUpdRetV7:', 1,
-       'PrimUnderflow:', 1,
-       'StackUnderflowEnterNode:', 1,
-       'StdErrorCode:', 1,
-       'UnderflowVect0:', 1,
-       'UnderflowVect1:', 1,
-       'UnderflowVect2:', 1,
-       'UnderflowVect3:', 1,
-       'UnderflowVect4:', 1,
-       'UnderflowVect5:', 1,
-       'UnderflowVect6:', 1,
-       'UnderflowVect7:', 1,
-       'UpdErr:', 1,
-       'UpdatePAP:', 1,
-       'WorldStateToken:', 1,
-       '_Enter_Internal:', 1,
-       '_PRMarking_MarkNextAStack:', 1,
-       '_PRMarking_MarkNextBStack:', 1,
-       '_PRMarking_MarkNextCAF:', 1,
-       '_PRMarking_MarkNextGA:', 1,
-       '_PRMarking_MarkNextRoot:', 1,
-       '_PRMarking_MarkNextSpark:', 1,
-       '_Scavenge_Forward_Ref:', 1,
-       '__std_entry_error__:', 1,
-       '_startMarkWorld:', 1,
-       'resumeThread:', 1,
-       'startCcRegisteringWorld:', 1,
-       'startEnterFloat:', 1,
-       'startEnterInt:', 1,
-       'startPerformIO:', 1,
-       'startStgWorld:', 1,
-       'stopPerformIO:', 1
-  );
-}
-\end{code}
-
-The following table reversal is used for both info tables and return
-vectors.  In both cases, we remove the first entry from the table,
-reverse the table, put the label at the end, and paste some code
-(that which is normally referred to by the first entry in the table)
-right after the table itself.  (The code pasting is done elsewhere.)
-
-\begin{code}
-sub rev_tbl {
-    local($symb, $tbl, $discard1) = @_;
-
-    local($before) = '';
-    local($label) = '';
-    local(@words) = ();
-    local($after) = '';
-    local(@lines) = split(/\n/, $tbl);
-    local($i);
-
-    for ($i = 0; $i <= $#lines && $lines[$i] !~ /^\t\.word\s+/; $i++) {
-       $label .= $lines[$i] . "\n",
-           next if $lines[$i] =~ /^[A-Za-z0-9_]+:$/
-                || $lines[$i] =~ /^\t\.globl/;
-
-       $before .= $lines[$i] . "\n"; # otherwise...
-    }
-
-    for ( ; $i <= $#lines && $lines[$i] =~ /^\t\.word\s+/; $i++) {
-       push(@words, $lines[$i]);
-    }
-    # now throw away the first word (entry code):
-    shift(@words) if $discard1;
-
-    for (; $i <= $#lines; $i++) {
-       $after .= $lines[$i] . "\n";
-    }
-
-    $tbl = $before . join("\n", (reverse @words)) . "\n" . $label . $after;
-
-#    print STDERR "before=$before\n";
-#    print STDERR "label=$label\n";
-#    print STDERR "words=",(reverse @words),"\n";
-#    print STDERR "after=$after\n";
-
-    $tbl;
-}
-
-# make "require"r happy...
-1;
-\end{code}
diff --git a/ghc/driver/ghc-asm-sgi.prl b/ghc/driver/ghc-asm-sgi.prl
deleted file mode 100644 (file)
index 2bb357b..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-# line 10 "ghc-asm-sgi.lprl"
-sub mangle_asm {
-
-    local($in_asmf, $out_asmf) = @_;
-    local($fun_code);
-
-    # multi-line regexp matching:
-    local($*) = 1;
-    local($i, $c);
-    &init_FUNNY_THINGS();
-
-    open(INASM, "< $in_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$in_asmf' (to read)\n");
-    open(OUTASM,"> $out_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$out_asmf' (to write)\n");
-
-    # just copy through now...
-    while (<INASM>) {
-       print OUTASM $_;
-    }
-
-    close(OUTASM) || &tidy_up_and_die(1,"Failed writing to $out_asmf\n");
-    close(INASM)  || &tidy_up_and_die(1,"Failed reading from $in_asmf\n");
-}
-# line 36 "ghc-asm-sgi.lprl"
-sub init_FUNNY_THINGS {
-    print STDERR "SGI: init_FUNNY_THINGS\n";
-}
-# line 48 "ghc-asm-sgi.lprl"
-sub rev_tbl {
-    local($symb, $tbl, $discard1) = @_;
-
-    local($before) = '';
-    local($label) = '';
-    local(@words) = ();
-    local($after) = '';
-    local(@lines) = split(/\n/, $tbl);
-    local($i);
-
-    for ($i = 0; $i <= $#lines && $lines[$i] !~ /^\t\.word\s+/; $i++) {
-       $label .= $lines[$i] . "\n",
-           next if $lines[$i] =~ /^[A-Za-z0-9_]+:$/
-                || $lines[$i] =~ /^\t\.global/;
-
-       $before .= $lines[$i] . "\n"; # otherwise...
-    }
-
-    for ( ; $i <= $#lines && $lines[$i] =~ /^\t\.word\s+/; $i++) {
-       push(@words, $lines[$i]);
-    }
-    # now throw away the first word (entry code):
-    shift(@words) if $discard1;
-
-    for (; $i <= $#lines; $i++) {
-       $after .= $lines[$i] . "\n";
-    }
-
-    $tbl = $before . join("\n", (reverse @words)) . "\n" . $label . $after;
-
-#    print STDERR "before=$before\n";
-#    print STDERR "label=$label\n";
-#    print STDERR "words=",(reverse @words),"\n";
-#    print STDERR "after=$after\n";
-
-    $tbl;
-}
-# line 88 "ghc-asm-sgi.lprl"
-# make "require"r happy...
-1;
diff --git a/ghc/driver/ghc-asm-solaris.lprl b/ghc/driver/ghc-asm-solaris.lprl
deleted file mode 100644 (file)
index 6359c66..0000000
+++ /dev/null
@@ -1,498 +0,0 @@
-%************************************************************************
-%*                                                                     *
-\section[Driver-asm-fiddling]{Fiddling with assembler files (SPARC)}
-%*                                                                     *
-%************************************************************************
-
-Tasks:
-\begin{itemize}
-\item
-Utterly stomp out C functions' prologues and epilogues; i.e., the
-stuff to do with the C stack.
-\item
-(SPARC) [Related] Utterly stomp out the changing of register windows.
-\item
-Any other required tidying up.
-\end{itemize}
-
-\begin{code}
-sub mangle_asm {
-    local($in_asmf, $out_asmf) = @_;
-
-    # multi-line regexp matching:
-    local($*) = 1;
-    local($i, $c);
-    &init_FUNNY_THINGS();
-
-    open(INASM, "< $in_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$in_asmf' (to read)\n");
-    open(OUTASM,"> $out_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$out_asmf' (to write)\n");
-
-    # read whole file, divide into "chunks":
-    #  record some info about what we've found...
-
-    @chk = ();         # contents of the chunk
-    $numchks = 0;      # number of them
-    @chkcat = ();      # what category of thing in each chunk
-    @chksymb = ();     # what symbol(base) is defined in this chunk
-    %slowchk = ();     # ditto, its regular "slow" entry code
-    %fastchk = ();     # ditto, fast entry code
-    %closurechk = ();  # ditto, the (static) closure
-    %infochk = ();     # given a symbol base, say what chunk its info tbl is in
-    %vectorchk = ();    # ditto, return vector table
-    %directchk = ();    # ditto, direct return code
-
-    $i = 0;
-    $chkcat[0] = 'misc';
-
-    while (<INASM>) {
-
-       if ( /^\s+/ ) { # most common case first -- a simple line!
-           # duplicated from the bottom
-
-           $chk[$i] .= $_;
-
-       } elsif ( /^\.LLC(\d+):$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'string';
-           $chksymb[$i] = $1;
-
-       } elsif ( /^__stg_split_marker(\d+):$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'splitmarker';
-           $chksymb[$i] = $1;
-
-       } elsif ( /^([A-Za-z0-9_]+)_info:$/ ) {
-           $symb = $1;
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'infotbl';
-           $chksymb[$i] = $symb;
-
-           die "Info table already? $symb; $i\n" if defined($infochk{$symb});
-
-           $infochk{$symb} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)_entry:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'slow';
-           $chksymb[$i] = $1;
-
-           $slowchk{$1} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)_fast\d+:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'fast';
-           $chksymb[$i] = $1;
-
-           $fastchk{$1} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)_closure:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'closure';
-           $chksymb[$i] = $1;
-
-           $closurechk{$1} = $i;
-
-       } elsif ( /^ghc.*c_ID:/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'consist';
-
-       } elsif ( /^(__gnu_compiled_c|gcc2_compiled\.):/ ) {
-           ; # toss it
-
-       } elsif ( /^ErrorIO_call_count:/         # HACK!!!!
-              || /^[A-Za-z0-9_]+\.\d+:$/
-              || /_CAT:/                       # PROF: _entryname_CAT
-              || /^CC_.*_struct:/              # PROF: _CC_ccident_struct
-              || /_done:/                      # PROF: _module_done
-              || /^_module_registered:/        # PROF: _module_registered
-              ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'data';
-           $chksymb[$i] = '';
-
-       } elsif ( /^(ret_|djn_)/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } elsif ( /^vtbl_([A-Za-z0-9_]+):$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'vector';
-           $chksymb[$i] = $1;
-
-           $vectorchk{$1} = $i;
-
-       } elsif ( /^([A-Za-z0-9_]+)DirectReturn:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'direct';
-           $chksymb[$i] = $1;
-
-           $directchk{$1} = $i;
-
-       } elsif ( /^[A-Za-z0-9_]+_upd:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } elsif ( /^[A-Za-z0-9_]/ ) {
-           local($thing);
-           chop($thing = $_);
-           print STDERR "Funny global thing?: $_"
-               unless $KNOWN_FUNNY_THING{$thing}
-                   || /^_(PRIn|PRStart).*:/    # pointer reversal GC routines
-                   || /^CC_.*:/                # PROF: _CC_ccident
-                   || /^_reg.*:/;              # PROF: __reg<module>
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } else { # simple line (duplicated at the top)
-
-           $chk[$i] .= $_;
-       }
-    }
-    $numchks = $#chk + 1;
-
-#    print STDERR "\nCLOSURES:\n";
-#    foreach $s (sort (keys %closurechk)) {
-#      print STDERR "$s:\t\t",$closurechk{$s},"\n";
-#    }
-#    print STDERR "\nINFOS:\n";
-#    foreach $s (sort (keys %infochk)) {
-#      print STDERR "$s:\t\t",$infochk{$s},"\n";
-#    }
-#    print STDERR "SLOWS:\n";
-#    foreach $s (sort (keys %slowchk)) {
-#      print STDERR "$s:\t\t",$slowchk{$s},"\n";
-#    }
-#    print STDERR "\nFASTS:\n";
-#    foreach $s (sort (keys %fastchk)) {
-#      print STDERR "$s:\t\t",$fastchk{$s},"\n";
-#    }
-
-    # the division into chunks is imperfect;
-    # we throw some things over the fence into the next
-    # chunk.
-    #
-    # also, there are things we would like to know
-    # about the whole module before we start spitting
-    # output.
-
-    # NB: we start meddling at chunk 1, not chunk 0
-
-    for ($i = 1; $i < $numchks; $i++) {
-       $c = $chk[$i]; # convenience copy
-
-#      print STDERR "\nCHK $i (BEFORE):\n", $c;
-
-       # toss all reg-window stuff (save/restore/ret[l] s):
-       $c =~ s/^\t(save .*|restore|ret|retl)\n//g;
-       # throw away PROLOGUE comments
-       $c =~ s/^\t!#PROLOGUE# 0\n\t!#PROLOGUE# 1\n//;
-
-       # pin a funny end-thing on (for easier matching):
-       $c .= 'FUNNY#END#THING';
-
-       # pick some end-things and move them to the next chunk
-
-       while ( $c =~ /^(\s+\.align\s+\d+\n|\s+\.proc\s+\d+\n|\s+\.global\s+\S+\n|\.text\n|\.data\n|\.stab.*\n|\.section.*\n|\s+\.type.*\n|\s+\.size.*\n)FUNNY#END#THING/ ) {
-           $to_move = $1;
-
-           if ( $to_move =~ /\.(global|proc|stab)/ && $i < ($numchks - 1) ) {
-               $chk[$i + 1] = $to_move . $chk[$i + 1];
-               # otherwise they're tossed
-           }
-
-           $c =~ s/^.*\nFUNNY#END#THING/FUNNY#END#THING/;
-       }
-
-       $c =~ s/FUNNY#END#THING//;
-       $chk[$i] = $c; # update w/ convenience copy
-    }
-
-    # print out all the literal strings first
-    for ($i = 0; $i < $numchks; $i++) {
-       if ( $chkcat[$i] eq 'string' ) {
-           print OUTASM "\.text\n\t\.align 8\n";
-           print OUTASM $chk[$i];
-           
-           $chkcat[$i] = 'DONE ALREADY';
-       }
-    }
-
-    for ($i = 1; $i < $numchks; $i++) {
-#      print STDERR "$i: cat $chkcat[$i], symb $chksymb[$i]\n";
-
-       next if $chkcat[$i] eq 'DONE ALREADY';
-
-       if ( $chkcat[$i] eq 'misc' ) {
-           print OUTASM "\.text\n\t\.align 4\n";
-           print OUTASM $chk[$i];
-
-       } elsif ( $chkcat[$i] eq 'data' ) {
-           print OUTASM "\.data\n\t\.align 8\n";
-           print OUTASM $chk[$i];
-
-       } elsif ( $chkcat[$i] eq 'consist' ) {
-           if ( $chk[$i] =~ /\.asciz.*\)(hsc|cc) (.*)\\t(.*)"/ ) {
-               local($consist) = "$1.$2.$3";
-               $consist =~ s/,/./g;
-               $consist =~ s/\//./g;
-               $consist =~ s/-/_/g;
-               $consist =~ s/[^A-Za-z0-9_.]/ZZ/g; # ToDo: properly?
-               print OUTASM "\.text\n$consist:\n";
-           } else {
-               print STDERR "Couldn't grok consistency: ", $chk[$i];
-           }
-
-       } elsif ( $chkcat[$i] eq 'splitmarker' ) {
-           # we can just re-constitute this one...
-           print OUTASM "___stg_split_marker",$chksymb[$i],":\n";
-
-       } elsif ( $chkcat[$i] eq 'closure'
-              || $chkcat[$i] eq 'infotbl'
-              || $chkcat[$i] eq 'slow'
-              || $chkcat[$i] eq 'fast' ) { # do them in that order
-           $symb = $chksymb[$i];
-
-           # CLOSURE
-           if ( defined($closurechk{$symb}) ) {
-               print OUTASM "\.data\n\t\.align 4\n";
-               print OUTASM $chk[$closurechk{$symb}];
-               $chkcat[$closurechk{$symb}] = 'DONE ALREADY';
-           }
-
-           # INFO TABLE
-           if ( defined($infochk{$symb}) ) {
-
-               print OUTASM "\.text\n\t\.align 4\n";
-               print OUTASM &rev_tbl($symb, $chk[$infochk{$symb}], 1);
-               # entry code will be put here!
-
-               # paranoia
-               if ( $chk[$infochk{$symb}] =~ /\.word\s+([A-Za-z0-9_]+_entry)$/
-                 && $1 ne "${symb}_entry" ) {
-                   print STDERR "!!! entry point???\n",$chk[$infochk{$symb}];
-               }
-
-               $chkcat[$infochk{$symb}] = 'DONE ALREADY';
-           }
-
-           # STD ENTRY POINT
-           if ( defined($slowchk{$symb}) ) {
-
-               # teach it to drop through to the fast entry point:
-               $c = $chk[$slowchk{$symb}];
-
-               if ( defined($fastchk{$symb}) ) {
-                   $c =~ s/^\tcall ${symb}_fast\d+,.*\n\tnop\n//;
-                   $c =~ s/^\tcall ${symb}_fast\d+,.*\n(\t[a-z].*\n)/\1/;
-               }
-
-               print STDERR "still has jump to fast entry point:\n$c"
-                   if $c =~ /${symb}_fast/; # NB: paranoia
-
-               print OUTASM "\.text\n\t\.align 4\n";
-               print OUTASM $c;
-               $chkcat[$slowchk{$symb}] = 'DONE ALREADY';
-           }
-           
-           # FAST ENTRY POINT
-           if ( defined($fastchk{$symb}) ) {
-               print OUTASM "\.text\n\t\.align 4\n";
-               print OUTASM $chk[$fastchk{$symb}];
-               $chkcat[$fastchk{$symb}] = 'DONE ALREADY';
-           }
-
-       } elsif ( $chkcat[$i] eq 'vector'
-              || $chkcat[$i] eq 'direct' ) { # do them in that order
-           $symb = $chksymb[$i];
-
-           # VECTOR TABLE
-           if ( defined($vectorchk{$symb}) ) {
-               print OUTASM "\.text\n\t\.align 4\n";
-               print OUTASM &rev_tbl($symb, $chk[$vectorchk{$symb}], 0);
-               # direct return code will be put here!
-               $chkcat[$vectorchk{$symb}] = 'DONE ALREADY';
-           }
-
-           # DIRECT RETURN
-           if ( defined($directchk{$symb}) ) {
-               print OUTASM "\.text\n\t\.align 4\n";
-               print OUTASM $chk[$directchk{$symb}];
-               $chkcat[$directchk{$symb}] = 'DONE ALREADY';
-           }
-           
-       } else {
-           &tidy_up_and_die(1,"$Pgm: unknown chkcat (ghc-asm SPARC)\n$chkcat[$i]\n$chk[$i]\n");
-       }
-    }
-
-    # finished:
-    close(OUTASM) || &tidy_up_and_die(1,"Failed writing to $out_asmf\n");
-    close(INASM)  || &tidy_up_and_die(1,"Failed reading from $in_asmf\n");
-}
-\end{code}
-
-\begin{code}
-sub init_FUNNY_THINGS {
-    %KNOWN_FUNNY_THING = (
-       'CheckHeapCode:', 1,
-       'CommonUnderflow:', 1,
-       'Continue:', 1,
-       'EnterNodeCode:', 1,
-       'ErrorIO_call_count:', 1,
-       'ErrorIO_innards:', 1,
-       'IndUpdRetDir:', 1,
-       'IndUpdRetV0:', 1,
-       'IndUpdRetV1:', 1,
-       'IndUpdRetV2:', 1,
-       'IndUpdRetV3:', 1,
-       'IndUpdRetV4:', 1,
-       'IndUpdRetV5:', 1,
-       'IndUpdRetV6:', 1,
-       'IndUpdRetV7:', 1,
-       'PrimUnderflow:', 1,
-       'StackUnderflowEnterNode:', 1,
-       'StdErrorCode:', 1,
-       'UnderflowVect0:', 1,
-       'UnderflowVect1:', 1,
-       'UnderflowVect2:', 1,
-       'UnderflowVect3:', 1,
-       'UnderflowVect4:', 1,
-       'UnderflowVect5:', 1,
-       'UnderflowVect6:', 1,
-       'UnderflowVect7:', 1,
-       'UpdErr:', 1,
-       'UpdatePAP:', 1,
-       'WorldStateToken:', 1,
-       '_Enter_Internal:', 1,
-       '_PRMarking_MarkNextAStack:', 1,
-       '_PRMarking_MarkNextBStack:', 1,
-       '_PRMarking_MarkNextCAF:', 1,
-       '_PRMarking_MarkNextGA:', 1,
-       '_PRMarking_MarkNextRoot:', 1,
-       '_PRMarking_MarkNextSpark:', 1,
-       '_Scavenge_Forward_Ref:', 1,
-       '__std_entry_error__:', 1,
-       '_startMarkWorld:', 1,
-       'resumeThread:', 1,
-       'startCcRegisteringWorld:', 1,
-       'startEnterFloat:', 1,
-       'startEnterInt:', 1,
-       'startPerformIO:', 1,
-       'startStgWorld:', 1,
-       'stopPerformIO:', 1
-    );
-}
-\end{code}
-
-The following table reversal is used for both info tables and return
-vectors.  In both cases, we remove the first entry from the table,
-reverse the table, put the label at the end, and paste some code
-(that which is normally referred to by the first entry in the table)
-right after the table itself.  (The code pasting is done elsewhere.)
-
-\begin{code}
-sub rev_tbl {
-    local($symb, $tbl, $discard1) = @_;
-
-    local($before) = '';
-    local($label) = '';
-    local(@words) = ();
-    local($after) = '';
-    local(@lines) = split(/\n/, $tbl);
-    local($i);
-
-    for ($i = 0; $i <= $#lines && $lines[$i] !~ /^\t\.word\s+/; $i++) {
-       $label .= $lines[$i] . "\n",
-           next if $lines[$i] =~ /^[A-Za-z0-9_]+:$/
-                || $lines[$i] =~ /^\t\.global/;
-
-       $before .= $lines[$i] . "\n"; # otherwise...
-    }
-
-    for ( ; $i <= $#lines && $lines[$i] =~ /^\t\.word\s+/; $i++) {
-       push(@words, $lines[$i]);
-    }
-    # now throw away the first word (entry code):
-    shift(@words) if $discard1;
-
-    for (; $i <= $#lines; $i++) {
-       $after .= $lines[$i] . "\n";
-    }
-
-    $tbl = $before . join("\n", (reverse @words)) . "\n" . $label . $after;
-
-#    print STDERR "before=$before\n";
-#    print STDERR "label=$label\n";
-#    print STDERR "words=",(reverse @words),"\n";
-#    print STDERR "after=$after\n";
-
-    $tbl;
-}
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[Driver-asm-info]{Collect interesting (static) info from an assembler file}
-%*                                                                     *
-%************************************************************************
-
-How many times is each asm instruction used?
-
-\begin{code}
-%AsmInsn = (); # init
-
-sub dump_asm_insn_counts {
-    local($asmf) = @_;
-
-    open(INASM, "< $asmf")  || &tidy_up_and_die(1,"$Pgm: failed to open `$asmf' (to read)\n");
-    while (<INASM>) {
-       if ( /^\t([a-z][a-z0-9]+)\b/ ) {
-           $AsmInsn{$1} ++;
-       }
-    }
-    close(INASM) || &tidy_up_and_die(1,"Failed reading from $asmf\n");
-
-    # OK, now print what we collected (to stderr)
-    foreach $i (sort (keys %AsmInsn)) {
-       print STDERR "INSN:: $i\t",$AsmInsn{$i},"\n";
-    }
-}
-\end{code}
-
-How many times is each ``global variable'' used in a \tr{sethi}
-instruction (SPARC)?  This can give some guidance about what should be
-put in machine registers...
-
-\begin{code}
-%SethiGlobal = (); # init
-
-sub dump_asm_globals_info {
-    local($asmf) = @_;
-
-    local($globl);
-
-    open(INASM, "< $asmf")  || &tidy_up_and_die(1,"$Pgm: failed to open `$asmf' (to read)\n");
-    while (<INASM>) {
-       if ( /^\tsethi \%hi\(_([_A-Za-z0-9]+)/ ) {
-           $globl = $1;
-           next if $globl =~ /(ds|fail|stg|tpl|vtbl)_[0-9]+/;
-
-           $SethiGlobal{$globl} ++;
-       }
-    }
-    close(INASM) || &tidy_up_and_die(1,"Failed reading from $asmf\n");
-
-    # OK, now print what we collected (to stderr)
-    foreach $i (sort (keys %SethiGlobal)) {
-       print STDERR "GLOBAL:: $i\t",$SethiGlobal{$i},"\n";
-    }
-}
-
-# make "require"r happy...
-1;
-\end{code}
diff --git a/ghc/driver/ghc-asm-sparc.lprl b/ghc/driver/ghc-asm-sparc.lprl
deleted file mode 100644 (file)
index ffe91ae..0000000
+++ /dev/null
@@ -1,487 +0,0 @@
-%************************************************************************
-%*                                                                     *
-\section[Driver-asm-fiddling]{Fiddling with assembler files (SPARC)}
-%*                                                                     *
-%************************************************************************
-
-Tasks:
-\begin{itemize}
-\item
-Utterly stomp out C functions' prologues and epilogues; i.e., the
-stuff to do with the C stack.
-\item
-(SPARC) [Related] Utterly stomp out the changing of register windows.
-\item
-Any other required tidying up.
-\end{itemize}
-
-\begin{code}
-sub mangle_asm {
-    local($in_asmf, $out_asmf) = @_;
-
-    # multi-line regexp matching:
-    local($*) = 1;
-    local($i, $c);
-    &init_FUNNY_THINGS();
-
-    open(INASM, "< $in_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$in_asmf' (to read)\n");
-    open(OUTASM,"> $out_asmf")
-       || &tidy_up_and_die(1,"$Pgm: failed to open `$out_asmf' (to write)\n");
-
-    # read whole file, divide into "chunks":
-    #  record some info about what we've found...
-
-    @chk = ();         # contents of the chunk
-    $numchks = 0;      # number of them
-    @chkcat = ();      # what category of thing in each chunk
-    @chksymb = ();     # what symbol(base) is defined in this chunk
-    %slowchk = ();     # ditto, its regular "slow" entry code
-    %fastchk = ();     # ditto, fast entry code
-    %closurechk = ();  # ditto, the (static) closure
-    %infochk = ();     # given a symbol base, say what chunk its info tbl is in
-    %vectorchk = ();    # ditto, return vector table
-    %directchk = ();    # ditto, direct return code
-
-    $i = 0;
-    $chkcat[0] = 'misc';
-
-    while (<INASM>) {
-       next if /^\.stab.*___stg_split_marker/;
-       next if /^\.stab.*ghc.*c_ID/;
-
-       if ( /^\s+/ ) { # most common case first -- a simple line!
-           # duplicated from the bottom
-
-           $chk[$i] .= $_;
-
-       } elsif ( /^LC(\d+):$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'string';
-           $chksymb[$i] = $1;
-
-       } elsif ( /^___stg_split_marker(\d+):$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'splitmarker';
-           $chksymb[$i] = $1;
-
-       } elsif ( /^_([A-Za-z0-9_]+)_info:$/ ) {
-           $symb = $1;
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'infotbl';
-           $chksymb[$i] = $symb;
-
-           die "Info table already? $symb; $i\n" if defined($infochk{$symb});
-
-           $infochk{$symb} = $i;
-
-       } elsif ( /^_([A-Za-z0-9_]+)_entry:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'slow';
-           $chksymb[$i] = $1;
-
-           $slowchk{$1} = $i;
-
-       } elsif ( /^_([A-Za-z0-9_]+)_fast\d+:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'fast';
-           $chksymb[$i] = $1;
-
-           $fastchk{$1} = $i;
-
-       } elsif ( /^_([A-Za-z0-9_]+)_closure:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'closure';
-           $chksymb[$i] = $1;
-
-           $closurechk{$1} = $i;
-
-       } elsif ( /^_ghc.*c_ID:/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'consist';
-
-       } elsif ( /^(___gnu_compiled_c|gcc2_compiled\.):/ ) {
-           ; # toss it
-
-       } elsif ( /^_ErrorIO_call_count:/        # HACK!!!!
-              || /^_[A-Za-z0-9_]+\.\d+:$/
-              || /^_.*_CAT:/                   # PROF: _entryname_CAT
-              || /^_CC_.*_struct:/             # PROF: _CC_ccident_struct
-              || /^_.*_done:/                  # PROF: _module_done
-              || /^__module_registered:/       # PROF: _module_registered
-              ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'data';
-           $chksymb[$i] = '';
-
-       } elsif ( /^_(ret_|djn_)/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } elsif ( /^_vtbl_([A-Za-z0-9_]+):$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'vector';
-           $chksymb[$i] = $1;
-
-           $vectorchk{$1} = $i;
-
-       } elsif ( /^_([A-Za-z0-9_]+)DirectReturn:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'direct';
-           $chksymb[$i] = $1;
-
-           $directchk{$1} = $i;
-
-       } elsif ( /^_[A-Za-z0-9_]+_upd:$/ ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } elsif ( /^_[A-Za-z0-9_]/ ) {
-           local($thing);
-           chop($thing = $_);
-           print STDERR "Funny global thing?: $_"
-               unless $KNOWN_FUNNY_THING{$thing}
-                   || /^__(PRIn|PRStart).*:/   # pointer reversal GC routines
-                   || /^_CC_.*:/               # PROF: _CC_ccident
-                   || /^__reg.*:/;             # PROF: __reg<module>
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
-           $chksymb[$i] = '';
-
-       } else { # simple line (duplicated at the top)
-
-           $chk[$i] .= $_;
-       }
-    }
-    $numchks = $#chk + 1;
-
-    # the division into chunks is imperfect;
-    # we throw some things over the fence into the next
-    # chunk.
-    #
-    # also, there are things we would like to know
-    # about the whole module before we start spitting
-    # output.
-
-    # NB: we start meddling at chunk 1, not chunk 0
-
-    for ($i = 1; $i < $numchks; $i++) {
-       $c = $chk[$i]; # convenience copy
-
-#      print STDERR "\nCHK $i (BEFORE):\n", $c;
-
-       # toss all reg-window stuff (save/restore/ret[l] s):
-       $c =~ s/^\t(save .*|restore|ret|retl)\n//g;
-       # throw away PROLOGUE comments
-       $c =~ s/^\t!#PROLOGUE# 0\n\t!#PROLOGUE# 1\n//;
-
-       # pin a funny end-thing on (for easier matching):
-       $c .= 'FUNNY#END#THING';
-
-       # pick some end-things and move them to the next chunk
-
-       while ( $c =~ /^(\s+\.align\s+\d+\n|\s+\.proc\s+\d+\n|\s+\.global\s+\S+\n|\.text\n|\.data\n|\.stab.*\n)FUNNY#END#THING/ ) {
-           $to_move = $1;
-
-           if ( $to_move =~ /\.(global|proc|stab)/ && $i < ($numchks - 1) ) {
-               $chk[$i + 1] = $to_move . $chk[$i + 1];
-               # otherwise they're tossed
-           }
-
-           $c =~ s/^.*\nFUNNY#END#THING/FUNNY#END#THING/;
-       }
-
-       $c =~ s/FUNNY#END#THING//;
-       $chk[$i] = $c; # update w/ convenience copy
-
-#      print STDERR "\nCHK $i (AFTER):\n", $c;
-    }
-
-    # print out all the literal strings first
-    for ($i = 0; $i < $numchks; $i++) {
-       if ( $chkcat[$i] eq 'string' ) {
-           print OUTASM "\.text\n\t\.align 8\n";
-           print OUTASM $chk[$i];
-           
-           $chkcat[$i] = 'DONE ALREADY';
-       }
-    }
-
-    for ($i = 0; $i < $numchks; $i++) {
-#      print STDERR "$i: cat $chkcat[$i], symb $chksymb[$i]\n";
-
-       next if $chkcat[$i] eq 'DONE ALREADY';
-
-       if ( $chkcat[$i] eq 'misc' ) {
-           print OUTASM "\.text\n\t\.align 4\n";
-           print OUTASM $chk[$i];
-
-       } elsif ( $chkcat[$i] eq 'data' ) {
-           print OUTASM "\.data\n\t\.align 8\n";
-           print OUTASM $chk[$i];
-
-       } elsif ( $chkcat[$i] eq 'consist' ) {
-           if ( $chk[$i] =~ /\.ascii.*\)(hsc|cc) (.*)\\11"\n\t\.ascii\s+"(.*)\\0"/ ) {
-               local($consist) = "$1.$2.$3";
-               $consist =~ s/,/./g;
-               $consist =~ s/\//./g;
-               $consist =~ s/-/_/g;
-               $consist =~ s/[^A-Za-z0-9_.]/ZZ/g; # ToDo: properly?
-               print OUTASM "\.text\n$consist:\n";
-           } else {
-               print STDERR "Couldn't grok consistency: ", $chk[$i];
-           }
-
-       } elsif ( $chkcat[$i] eq 'splitmarker' ) {
-           # we can just re-constitute this one...
-           print OUTASM "___stg_split_marker",$chksymb[$i],":\n";
-
-       } elsif ( $chkcat[$i] eq 'closure'
-              || $chkcat[$i] eq 'infotbl'
-              || $chkcat[$i] eq 'slow'
-              || $chkcat[$i] eq 'fast' ) { # do them in that order
-           $symb = $chksymb[$i];
-
-#      print STDERR "$i: cat $chkcat[$i], symb $symb ",defined($closurechk{$symb}),":",defined($infochk{$symb}),":",defined($slowchk{$symb}),":",defined($fastchk{$symb}),"\n";
-
-           # CLOSURE
-           if ( defined($closurechk{$symb}) ) {
-               print OUTASM "\.data\n\t\.align 4\n";
-               print OUTASM $chk[$closurechk{$symb}];
-               $chkcat[$closurechk{$symb}] = 'DONE ALREADY';
-           }
-
-           # INFO TABLE
-           if ( defined($infochk{$symb}) ) {
-
-               print OUTASM "\.text\n\t\.align 4\n";
-               print OUTASM &rev_tbl($symb, $chk[$infochk{$symb}], 1);
-               # entry code will follow, here!
-
-               # paranoia
-               if ( $chk[$infochk{$symb}] =~ /\.word\s+([A-Za-z0-9_]+_entry)$/
-                 && $1 ne "_${symb}_entry" ) {
-                   print STDERR "!!! entry point???\n",$chk[$infochk{$symb}];
-               }
-
-               $chkcat[$infochk{$symb}] = 'DONE ALREADY';
-           }
-
-           # STD ENTRY POINT
-           if ( defined($slowchk{$symb}) ) {
-
-               # teach it to drop through to the fast entry point:
-               $c = $chk[$slowchk{$symb}];
-
-               if ( defined($fastchk{$symb}) ) {
-                   $c =~ s/^\tcall _${symb}_fast\d+,.*\n\tnop\n//;
-                   $c =~ s/^\tcall _${symb}_fast\d+,.*\n(\t[a-z].*\n)/\1/;
-               }
-
-               print STDERR "still has jump to fast entry point:\n$c"
-                   if $c =~ /_${symb}_fast/; # NB: paranoia
-
-               print OUTASM "\.text\n\t\.align 4\n";
-               print OUTASM $c;
-               $chkcat[$slowchk{$symb}] = 'DONE ALREADY';
-           }
-           
-           # FAST ENTRY POINT
-           if ( defined($fastchk{$symb}) ) {
-               print OUTASM "\.text\n\t\.align 4\n";
-               print OUTASM $chk[$fastchk{$symb}];
-               $chkcat[$fastchk{$symb}] = 'DONE ALREADY';
-           }
-
-       } elsif ( $chkcat[$i] eq 'vector'
-              || $chkcat[$i] eq 'direct' ) { # do them in that order
-           $symb = $chksymb[$i];
-
-           # VECTOR TABLE
-           if ( defined($vectorchk{$symb}) ) {
-               print OUTASM "\.text\n\t\.align 4\n";
-               print OUTASM &rev_tbl($symb, $chk[$vectorchk{$symb}], 0);
-               # direct return code will be put here!
-               $chkcat[$vectorchk{$symb}] = 'DONE ALREADY';
-           }
-
-           # DIRECT RETURN
-           if ( defined($directchk{$symb}) ) {
-               print OUTASM "\.text\n\t\.align 4\n";
-               print OUTASM $chk[$directchk{$symb}];
-               $chkcat[$directchk{$symb}] = 'DONE ALREADY';
-           }
-           
-       } else {
-           &tidy_up_and_die(1,"$Pgm: unknown chkcat (ghc-asm SPARC)\n$chkcat[$i]\n$chk[$i]\n");
-       }
-    }
-
-    # finished:
-    close(OUTASM) || &tidy_up_and_die(1,"Failed writing to $out_asmf\n");
-    close(INASM)  || &tidy_up_and_die(1,"Failed reading from $in_asmf\n");
-}
-\end{code}
-
-\begin{code}
-sub init_FUNNY_THINGS {
-    %KNOWN_FUNNY_THING = (
-       '_CheckHeapCode:', 1,
-       '_CommonUnderflow:', 1,
-       '_Continue:', 1,
-       '_EnterNodeCode:', 1,
-       '_ErrorIO_call_count:', 1,
-       '_ErrorIO_innards:', 1,
-       '_IndUpdRetDir:', 1,
-       '_IndUpdRetV0:', 1,
-       '_IndUpdRetV1:', 1,
-       '_IndUpdRetV2:', 1,
-       '_IndUpdRetV3:', 1,
-       '_IndUpdRetV4:', 1,
-       '_IndUpdRetV5:', 1,
-       '_IndUpdRetV6:', 1,
-       '_IndUpdRetV7:', 1,
-       '_PrimUnderflow:', 1,
-       '_StackUnderflowEnterNode:', 1,
-       '_StdErrorCode:', 1,
-       '_UnderflowVect0:', 1,
-       '_UnderflowVect1:', 1,
-       '_UnderflowVect2:', 1,
-       '_UnderflowVect3:', 1,
-       '_UnderflowVect4:', 1,
-       '_UnderflowVect5:', 1,
-       '_UnderflowVect6:', 1,
-       '_UnderflowVect7:', 1,
-       '_UpdErr:', 1,
-       '_UpdatePAP:', 1,
-       '_WorldStateToken:', 1,
-       '__Enter_Internal:', 1,
-       '__PRMarking_MarkNextAStack:', 1,
-       '__PRMarking_MarkNextBStack:', 1,
-       '__PRMarking_MarkNextCAF:', 1,
-       '__PRMarking_MarkNextGA:', 1,
-       '__PRMarking_MarkNextRoot:', 1,
-       '__PRMarking_MarkNextSpark:', 1,
-       '__Scavenge_Forward_Ref:', 1,
-       '___std_entry_error__:', 1,
-       '__startMarkWorld:', 1,
-       '_resumeThread:', 1,
-       '_startCcRegisteringWorld:', 1,
-       '_startEnterFloat:', 1,
-       '_startEnterInt:', 1,
-       '_startPerformIO:', 1,
-       '_startStgWorld:', 1,
-       '_stopPerformIO:', 1
-    );
-}
-\end{code}
-
-The following table reversal is used for both info tables and return
-vectors.  In both cases, we remove the first entry from the table,
-reverse the table, put the label at the end, and paste some code
-(that which is normally referred to by the first entry in the table)
-right after the table itself.  (The code pasting is done elsewhere.)
-
-\begin{code}
-sub rev_tbl {
-    local($symb, $tbl, $discard1) = @_;
-
-    local($before) = '';
-    local($label) = '';
-    local(@words) = ();
-    local($after) = '';
-    local(@lines) = split(/\n/, $tbl);
-    local($i);
-
-    for ($i = 0; $i <= $#lines && $lines[$i] !~ /^\t\.word\s+/; $i++) {
-       $label .= $lines[$i] . "\n",
-           next if $lines[$i] =~ /^[A-Za-z0-9_]+:$/
-                || $lines[$i] =~ /^\t\.global/;
-
-       $before .= $lines[$i] . "\n"; # otherwise...
-    }
-
-    for ( ; $i <= $#lines && $lines[$i] =~ /^\t\.word\s+/; $i++) {
-       push(@words, $lines[$i]);
-    }
-    # now throw away the first word (entry code):
-    shift(@words) if $discard1;
-
-    for (; $i <= $#lines; $i++) {
-       $after .= $lines[$i] . "\n";
-    }
-
-    $tbl = $before . join("\n", (reverse @words)) . "\n" . $label . $after;
-
-#    print STDERR "before=$before\n";
-#    print STDERR "label=$label\n";
-#    print STDERR "words=",(reverse @words),"\n";
-#    print STDERR "after=$after\n";
-
-    $tbl;
-}
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[Driver-asm-info]{Collect interesting (static) info from an assembler file}
-%*                                                                     *
-%************************************************************************
-
-How many times is each asm instruction used?
-
-\begin{code}
-%AsmInsn = (); # init
-
-sub dump_asm_insn_counts {
-    local($asmf) = @_;
-
-    open(INASM, "< $asmf")  || &tidy_up_and_die(1,"$Pgm: failed to open `$asmf' (to read)\n");
-    while (<INASM>) {
-       if ( /^\t([a-z][a-z0-9]+)\b/ ) {
-           $AsmInsn{$1} ++;
-       }
-    }
-    close(INASM) || &tidy_up_and_die(1,"Failed reading from $asmf\n");
-
-    # OK, now print what we collected (to stderr)
-    foreach $i (sort (keys %AsmInsn)) {
-       print STDERR "INSN:: $i\t",$AsmInsn{$i},"\n";
-    }
-}
-\end{code}
-
-How many times is each ``global variable'' used in a \tr{sethi}
-instruction (SPARC)?  This can give some guidance about what should be
-put in machine registers...
-
-\begin{code}
-%SethiGlobal = (); # init
-
-sub dump_asm_globals_info {
-    local($asmf) = @_;
-
-    local($globl);
-
-    open(INASM, "< $asmf")  || &tidy_up_and_die(1,"$Pgm: failed to open `$asmf' (to read)\n");
-    while (<INASM>) {
-       if ( /^\tsethi \%hi\(_([_A-Za-z0-9]+)/ ) {
-           $globl = $1;
-           next if $globl =~ /(ds|fail|stg|tpl|vtbl)_[0-9]+/;
-
-           $SethiGlobal{$globl} ++;
-       }
-    }
-    close(INASM) || &tidy_up_and_die(1,"Failed reading from $asmf\n");
-
-    # OK, now print what we collected (to stderr)
-    foreach $i (sort (keys %SethiGlobal)) {
-       print STDERR "GLOBAL:: $i\t",$SethiGlobal{$i},"\n";
-    }
-}
-
-# make "require"r happy...
-1;
-\end{code}
index 4a4834c..0907b09 100644 (file)
@@ -13,6 +13,33 @@ stuff to do with the C stack.
 Any other required tidying up.
 \end{itemize}
 
+HPPA specific notes:
+\begin{itemize}
+\item
+The HP linker is very picky about symbols being in the appropriate
+space (code vs. data).  When we mangle the threaded code to put the
+info tables just prior to the code, they wind up in code space
+rather than data space.  This means that references to *_info from
+un-mangled parts of the RTS (e.g. unthreaded GC code) get
+unresolved symbols.  Solution:  mini-mangler for .c files on HP.  I
+think this should really be triggered in the driver by a new -rts
+option, so that user code doesn't get mangled inappropriately.
+\item
+With reversed tables, jumps are to the _info label rather than to
+the _entry label.  The _info label is just an address in code
+space, rather than an entry point with the descriptive blob we
+talked about yesterday.  As a result, you can't use the call-style
+JMP_ macro.  However, some JMP_ macros take _info labels as targets
+and some take code entry points within the RTS.  The latter won't
+work with the goto-style JMP_ macro.  Sigh.  Solution: Use the goto
+style JMP_ macro, and mangle some more assembly, changing all
+"RP'literal" and "LP'literal" references to "R'literal" and
+"L'literal," so that you get the real address of the code, rather
+than the descriptive blob.  Also change all ".word P%literal"
+entries in info tables and vector tables to just ".word literal,"
+for the same reason.  Advantage: No more ridiculous call sequences.
+\end{itemize}
+
 %************************************************************************
 %*                                                                     *
 \subsection{Constants for various architectures}
@@ -22,7 +49,62 @@ Any other required tidying up.
 \begin{code}
 sub init_TARGET_STUFF {
 
-    if ( $TargetPlatform =~ /^i386-.*-linuxaout/ ) {
+    #--------------------------------------------------------#
+    if ( $TargetPlatform =~ /^alpha-.*-.*/ ) {
+
+    $T_STABBY      = 0; # 1 iff .stab things (usually if a.out format)
+    $T_US          = ''; # _ if symbols have an underscore on the front
+    $T_DO_GC       = 'PerformGC_wrapper';
+    $T_PRE_APP     = 'DONT THINK THIS APPLIES'; # regexp that says what comes before APP/NO_APP
+    $T_CONST_LBL    = '^\$C(\d+):$'; # regexp for what such a lbl looks like
+    $T_POST_LBL            = ':';
+
+    $T_MOVE_DIRVS   = '^(\s*(\.align\s+\d+|\.(globl|ent)\s+\S+|\#.*|\.(file|loc)\s+\S+\s+\S+|\.text|\.r?data)\n)';
+    $T_COPY_DIRVS   = '^\s*(\#|\.(file|globl|ent|loc))';
+
+    $T_hsc_cc_PAT   = '\.ascii.*\)(hsc|cc) (.*)\\\\11"\n\t\.ascii\s+"(.*)\\\\0"';
+    $T_DOT_WORD            = '\.quad';
+    $T_DOT_GLOBAL   = "\t\.globl";
+    $T_HDR_literal  = "\.rdata\n\t\.align 3\n";
+    $T_HDR_misc            = "\.text\n\t\.align 3\n";
+    $T_HDR_data            = "\.data\n\t\.align 3\n";
+    $T_HDR_consist  = "\.text\n";
+    $T_HDR_closure  = "\.data\n\t\.align 3\n";
+    $T_HDR_info            = "\.text\n\t\.align 3\n";
+    $T_HDR_entry    = "\.text\n\t\.align 3\n";
+    $T_HDR_fast            = "\.text\n\t\.align 3\n";
+    $T_HDR_vector   = "\.text\n\t\.align 3\n";
+    $T_HDR_direct   = "\.text\n\t\.align 3\n";
+
+    #--------------------------------------------------------#
+    } elsif ( $TargetPlatform =~ /^hppa/ ) {
+
+    $T_STABBY      = 0; # 1 iff .stab things (usually if a.out format)
+    $T_US          = ''; # _ if symbols have an underscore on the front
+    $T_DO_GC       = 'PerformGC_wrapper';
+    $T_PRE_APP     = 'DONT THINK THIS APPLIES'; # regexp that says what comes before APP/NO_APP
+    $T_CONST_LBL    = '^L\$C(\d+)$'; # regexp for what such a lbl looks like
+    $T_POST_LBL            = '';
+
+    $T_MOVE_DIRVS   = '^((\s+\.(IMPORT|EXPORT|PARAM).*|\s+\.align\s+\d+|\s+\.(SPACE|SUBSPA)\s+\S+|\s*)\n)';
+    $T_COPY_DIRVS   = '^\s+\.(IMPORT|EXPORT)';
+
+    $T_hsc_cc_PAT   = '\.STRING.*\)(hsc|cc) (.*)\\\\x09(.*)\\\\x00';
+    $T_DOT_WORD            = '\.word';
+    $T_DOT_GLOBAL   = '\s+\.EXPORT';
+    $T_HDR_literal  = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$LIT\$\n";
+    $T_HDR_misc            = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
+    $T_HDR_data            = "\t.SPACE \$PRIVATE\$\n\t.SUBSPA \$DATA\$\n\t\.align 4\n";
+    $T_HDR_consist  = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$LIT\$\n";
+    $T_HDR_closure  = "\t.SPACE \$PRIVATE\$\n\t.SUBSPA \$DATA\$\n\t\.align 4\n";
+    $T_HDR_info            = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
+    $T_HDR_entry    = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
+    $T_HDR_fast            = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
+    $T_HDR_vector   = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
+    $T_HDR_direct   = "\t.SPACE \$TEXT\$\n\t.SUBSPA \$CODE\$\n\t\.align 4\n";
+
+    #--------------------------------------------------------#
+    } elsif ( $TargetPlatform =~ /^i386-.*-(linuxaout|freebsd)/ ) {
 
     $T_STABBY      = 1; # 1 iff .stab things (usually if a.out format)
     $T_US          = '_'; # _ if symbols have an underscore on the front
@@ -30,26 +112,28 @@ sub init_TARGET_STUFF {
     $T_PRE_APP     = '^#'; # regexp that says what comes before APP/NO_APP
     $T_CONST_LBL    = '^LC(\d+):$';
     $T_POST_LBL            = ':';
-    $T_PRE_LLBL_PAT = 'L';
-    $T_PRE_LLBL            = 'L';
+    $T_X86_PRE_LLBL_PAT = 'L';
+    $T_X86_PRE_LLBL        = 'L';
     $T_X86_BADJMP   = '^\tjmp [^L\*]';
 
-    $T_MOVE_DIRVS   = '^\s*(\.align\s+\d+(,0x90)?\n|\.globl\s+\S+\n|\.text\n|\.data\n|\.stab[^n].*\n)';
+    $T_MOVE_DIRVS   = '^(\s*(\.align\s+\d+(,0x90)?|\.globl\s+\S+|\.text|\.data|\.stab[^n].*|\.type\s+.*|\.size\s+.*)\n)';
     $T_COPY_DIRVS   = '\.(globl|stab)';
     $T_hsc_cc_PAT   = '\.ascii.*\)(hsc|cc) (.*)\\\\11"\n\t\.ascii\s+"(.*)\\\\0"';
     $T_DOT_WORD            = '\.long';
-    $T_HDR_string   = "\.text\n\t\.align 4\n"; # .align 4 is 486-cache friendly
-    $T_HDR_misc            = "\.text\n\t\.align 4\n";
+    $T_DOT_GLOBAL   = '\.globl';
+    $T_HDR_literal  = "\.text\n\t\.align 2\n"; # .align 4 is 486-cache friendly
+    $T_HDR_misc            = "\.text\n\t\.align 2,0x90\n";
     $T_HDR_data            = "\.data\n\t\.align 2\n"; # ToDo: change align??
     $T_HDR_consist  = "\.text\n";
     $T_HDR_closure  = "\.data\n\t\.align 2\n"; # ToDo: change align?
-    $T_HDR_info            = "\.text\n\t\.align 4\n"; # NB: requires padding
+    $T_HDR_info            = "\.text\n\t\.align 2\n"; # NB: requires padding
     $T_HDR_entry    = "\.text\n"; # no .align so we're right next to _info (arguably wrong...?)
-    $T_HDR_fast            = "\.text\n\t\.align 4\n";
-    $T_HDR_vector   = "\.text\n\t\.align 4\n"; # NB: requires padding
-    $T_HDR_direct   = "\.text\n\t\.align 4\n";
+    $T_HDR_fast            = "\.text\n\t\.align 2,0x90\n";
+    $T_HDR_vector   = "\.text\n\t\.align 2\n"; # NB: requires padding
+    $T_HDR_direct   = "\.text\n\t\.align 2,0x90\n";
 
-    } elsif ( $TargetPlatform =~ /^i386-.*-solaris2/ ) {
+    #--------------------------------------------------------#
+    } elsif ( $TargetPlatform =~ /^i386-.*-(solaris2|linux)$/ ) {
 
     $T_STABBY      = 0; # 1 iff .stab things (usually if a.out format)
     $T_US          = ''; # _ if symbols have an underscore on the front
@@ -57,16 +141,17 @@ sub init_TARGET_STUFF {
     $T_PRE_APP     = '/'; # regexp that says what comes before APP/NO_APP
     $T_CONST_LBL    = '^\.LC(\d+):$'; # regexp for what such a lbl looks like
     $T_POST_LBL            = ':';
-    $T_PRE_LLBL_PAT = '\.L';
-    $T_PRE_LLBL            = '.L';
+    $T_X86_PRE_LLBL_PAT = '\.L';
+    $T_X86_PRE_LLBL        = '.L';
     $T_X86_BADJMP   = '^\tjmp [^\.\*]';
 
-    $T_MOVE_DIRVS   = '^\s*(\.align\s+\d+(,0x90)?\n|\.globl\s+\S+\n|\.text\n|\.data\n|\.section\s+.*\n|\.type\s+.*\n|\.Lfe.*\n\t\.size\s+.*\n|\.size\s+.*\n|\.ident.*\n)';
+    $T_MOVE_DIRVS   = '^(\s*(\.align\s+\d+(,0x90)?|\.globl\s+\S+|\.text|\.data|\.section\s+.*|\.type\s+.*|\.Lfe.*\n\t\.size\s+.*|\.size\s+.*|\.ident.*)\n)';
     $T_COPY_DIRVS   = '\.(globl)';
 
     $T_hsc_cc_PAT   = '\.string.*\)(hsc|cc) (.*)\\\\t(.*)"';
     $T_DOT_WORD            = '\.long';
-    $T_HDR_string   = "\.section\t\.rodata\n"; # or just use .text??? (WDP 95/11)
+    $T_DOT_GLOBAL   = '\.globl';
+    $T_HDR_literal  = "\.section\t\.rodata\n"; # or just use .text??? (WDP 95/11)
     $T_HDR_misc            = "\.text\n\t\.align 16\n";
     $T_HDR_data            = "\.data\n\t\.align 4\n"; # ToDo: change align??
     $T_HDR_consist  = "\.text\n";
@@ -77,6 +162,61 @@ sub init_TARGET_STUFF {
     $T_HDR_vector   = "\.text\n\t\.align 16\n"; # NB: requires padding
     $T_HDR_direct   = "\.text\n\t\.align 16\n";
 
+    #--------------------------------------------------------#
+    } elsif ( $TargetPlatform =~ /^m68k-.*-sunos4/ ) {
+
+    $T_STABBY      = 1; # 1 iff .stab things (usually if a.out format)
+    $T_US          = '_'; # _ if symbols have an underscore on the front
+    $T_DO_GC       = '_PerformGC_wrapper';
+    $T_PRE_APP     = '^# MAY NOT APPLY'; # regexp that says what comes before APP/NO_APP
+    $T_CONST_LBL    = '^LC(\d+):$';
+    $T_POST_LBL            = ':';
+
+    $T_MOVE_DIRVS   = '(\s*(\.align\s+\d+|\.proc\s+\d+|\.const|\.cstring|\.globl\s+\S+|\.text|\.data|\.even|\.stab[^n].*)\n)';
+    $T_COPY_DIRVS   = '\.(globl|proc|stab)';
+    $T_hsc_cc_PAT   = '\.ascii.*\)(hsc|cc) (.*)\\\\11"\n\t\.ascii\s+"(.*)\\\\0"';
+
+    $T_DOT_WORD            = '\.long';
+    $T_DOT_GLOBAL   = '\.globl';
+    $T_HDR_literal  = "\.text\n\t\.even\n";
+    $T_HDR_misc            = "\.text\n\t\.even\n";
+    $T_HDR_data            = "\.data\n\t\.even\n";
+    $T_HDR_consist  = "\.text\n";
+    $T_HDR_closure  = "\.data\n\t\.even\n";
+    $T_HDR_info            = "\.text\n\t\.even\n";
+    $T_HDR_entry    = "\.text\n\t\.even\n";
+    $T_HDR_fast            = "\.text\n\t\.even\n";
+    $T_HDR_vector   = "\.text\n\t\.even\n";
+    $T_HDR_direct   = "\.text\n\t\.even\n";
+
+    #--------------------------------------------------------#
+    } elsif ( $TargetPlatform =~ /^mips-.*/ ) {
+
+    $T_STABBY      = 0; # 1 iff .stab things (usually if a.out format)
+    $T_US          = ''; # _ if symbols have an underscore on the front
+    $T_DO_GC       = 'PerformGC_wrapper';
+    $T_PRE_APP     = '^\s*#'; # regexp that says what comes before APP/NO_APP
+    $T_CONST_LBL    = '^\$LC(\d+):$'; # regexp for what such a lbl looks like
+    $T_POST_LBL            = ':';
+
+    $T_MOVE_DIRVS   = '(\s*(\.align\s+\d+|\.(globl|ent)\s+\S+|\.text|\.r?data)\n)';
+    $T_COPY_DIRVS   = '\.(globl|ent)';
+
+    $T_hsc_cc_PAT   = 'I WAS TOO LAZY TO DO THIS BIT (WDP 95/05)';
+    $T_DOT_WORD            = '\.word';
+    $T_DOT_GLOBAL   = '\t\.globl';
+    $T_HDR_literal  = "\t\.rdata\n\t\.align 2\n";
+    $T_HDR_misc            = "\t\.text\n\t\.align 2\n";
+    $T_HDR_data            = "\t\.data\n\t\.align 2\n";
+    $T_HDR_consist  = 'TOO LAZY TO DO THIS TOO';
+    $T_HDR_closure  = "\t\.data\n\t\.align 2\n";
+    $T_HDR_info            = "\t\.text\n\t\.align 2\n";
+    $T_HDR_entry    = "\t\.text\n\t\.align 2\n";
+    $T_HDR_fast            = "\t\.text\n\t\.align 2\n";
+    $T_HDR_vector   = "\t\.text\n\t\.align 2\n";
+    $T_HDR_direct   = "\t\.text\n\t\.align 2\n";
+
+    #--------------------------------------------------------#
     } elsif ( $TargetPlatform =~ /^powerpc-.*/ ) {
 
     $T_STABBY      = 0; # 1 iff .stab things (usually if a.out format)
@@ -85,16 +225,14 @@ sub init_TARGET_STUFF {
     $T_PRE_APP     = 'NOT APPLICABLE'; # regexp that says what comes before APP/NO_APP
     $T_CONST_LBL    = '^LC\.\.(\d+):$'; # regexp for what such a lbl looks like
     $T_POST_LBL            = ':';
-    $T_PRE_LLBL_PAT = '\.L';
-    $T_PRE_LLBL            = '.L';
-    $T_X86_BADJMP   = 'NOT APPLICABLE';
 
-    $T_MOVE_DIRVS   = '^\s*(\.align\s+\d+(,0x90)?\n|\.globl\s+\S+\n|\.text\n|\.data\n|\.section\s+.*\n|\.type\s+.*\n|\.Lfe.*\n\t\.size\s+.*\n|\.size\s+.*\n|\.ident.*\n)';
+    $T_MOVE_DIRVS   = '^(\s*(\.align\s+\d+(,0x90)?|\.globl\s+\S+|\.text|\.data|\.section\s+.*|\.type\s+.*|\.Lfe.*\n\t\.size\s+.*|\.size\s+.*|\.ident.*)\n)';
     $T_COPY_DIRVS   = '\.(globl)';
 
     $T_hsc_cc_PAT   = '\.string.*\)(hsc|cc) (.*)\\\\t(.*)"';
     $T_DOT_WORD            = '\.long';
-    $T_HDR_string   = "\.section\t\.rodata\n"; # or just use .text??? (WDP 95/11)
+    $T_DOT_GLOBAL   = '\.globl';
+    $T_HDR_literal  = "\.section\t\.rodata\n"; # or just use .text??? (WDP 95/11)
     $T_HDR_misc            = "\.text\n\t\.align 16\n";
     $T_HDR_data            = "\.data\n\t\.align 4\n"; # ToDo: change align??
     $T_HDR_consist  = "\.text\n";
@@ -104,6 +242,65 @@ sub init_TARGET_STUFF {
     $T_HDR_fast            = "\.text\n\t\.align 16\n";
     $T_HDR_vector   = "\.text\n\t\.align 16\n"; # NB: requires padding
     $T_HDR_direct   = "\.text\n\t\.align 16\n";
+
+    #--------------------------------------------------------#
+    } elsif ( $TargetPlatform =~ /^sparc-.*-solaris2/ ) {
+
+    $T_STABBY      = 0; # 1 iff .stab things (usually if a.out format)
+    $T_US          = ''; # _ if symbols have an underscore on the front
+    $T_DO_GC       = 'PerformGC_wrapper';
+    $T_PRE_APP     = 'DOES NOT SEEM TO APPLY'; # regexp that says what comes before APP/NO_APP
+    $T_CONST_LBL    = '^\.LLC(\d+):$'; # regexp for what such a lbl looks like
+    $T_POST_LBL            = ':';
+
+    $T_MOVE_DIRVS   = '^((\s+\.align\s+\d+|\s+\.proc\s+\d+|\s+\.global\s+\S+|\.text|\.data|\.stab.*|\.section.*|\s+\.type.*|\s+\.size.*)\n)';
+    $T_COPY_DIRVS   = '\.(global|proc|stab)';
+
+    $T_hsc_cc_PAT   = '\.asciz.*\)(hsc|cc) (.*)\\\\t(.*)"';
+    $T_DOT_WORD            = '\.word';
+    $T_DOT_GLOBAL   = '\.global';
+    $T_HDR_literal  = "\.text\n\t\.align 8\n";
+    $T_HDR_misc            = "\.text\n\t\.align 4\n";
+    $T_HDR_data            = "\.data\n\t\.align 8\n";
+    $T_HDR_consist  = "\.text\n";
+    $T_HDR_closure  = "\.data\n\t\.align 4\n";
+    $T_HDR_info            = "\.text\n\t\.align 4\n";
+    $T_HDR_entry    = "\.text\n\t\.align 4\n";
+    $T_HDR_fast            = "\.text\n\t\.align 4\n";
+    $T_HDR_vector   = "\.text\n\t\.align 4\n";
+    $T_HDR_direct   = "\.text\n\t\.align 4\n";
+
+    #--------------------------------------------------------#
+    } elsif ( $TargetPlatform =~ /^sparc-.*-sunos4/ ) {
+
+    $T_STABBY      = 1; # 1 iff .stab things (usually if a.out format)
+    $T_US          = '_'; # _ if symbols have an underscore on the front
+    $T_DO_GC       = '_PerformGC_wrapper';
+    $T_PRE_APP     = '^# DOES NOT SEEM TO APPLY'; # regexp that says what comes before APP/NO_APP
+    $T_CONST_LBL    = '^LC(\d+):$';
+    $T_POST_LBL            = ':';
+
+    $T_MOVE_DIRVS   = '^((\s+\.align\s+\d+|\s+\.proc\s+\d+|\s+\.global\s+\S+|\.text|\.data|\.stab.*)\n)';
+    $T_COPY_DIRVS   = '\.(global|proc|stab)';
+    $T_hsc_cc_PAT   = '\.ascii.*\)(hsc|cc) (.*)\\\\11"\n\t\.ascii\s+"(.*)\\\\0"';
+
+    $T_DOT_WORD            = '\.word';
+    $T_DOT_GLOBAL   = '^\t\.global';
+    $T_HDR_literal  = "\.text\n\t\.align 8\n";
+    $T_HDR_misc            = "\.text\n\t\.align 4\n";
+    $T_HDR_data            = "\.data\n\t\.align 8\n";
+    $T_HDR_consist  = "\.text\n";
+    $T_HDR_closure  = "\.data\n\t\.align 4\n";
+    $T_HDR_info            = "\.text\n\t\.align 4\n";
+    $T_HDR_entry    = "\.text\n\t\.align 4\n";
+    $T_HDR_fast            = "\.text\n\t\.align 4\n";
+    $T_HDR_vector   = "\.text\n\t\.align 4\n";
+    $T_HDR_direct   = "\.text\n\t\.align 4\n";
+
+    #--------------------------------------------------------#
+    } else {
+       print STDERR "$Pgm: don't know how to mangle assembly language for: $TargetPlatform\n";
+       exit 1;
     }
 
 if ( 0 ) {
@@ -113,15 +310,16 @@ print STDERR "T_DO_GC: $T_DO_GC\n";
 print STDERR "T_PRE_APP: $T_PRE_APP\n";
 print STDERR "T_CONST_LBL: $T_CONST_LBL\n";
 print STDERR "T_POST_LBL: $T_POST_LBL\n";
-print STDERR "T_PRE_LLBL_PAT: $T_PRE_LLBL_PAT\n";
-print STDERR "T_PRE_LLBL: $T_PRE_LLBL\n";
-print STDERR "T_X86_BADJMP: $T_X86_BADJMP\n";
-
+if ( $TargetPlatform =~ /^i386-/ ) {
+    print STDERR "T_X86_PRE_LLBL_PAT: $T_X86_PRE_LLBL_PAT\n";
+    print STDERR "T_X86_PRE_LLBL: $T_X86_PRE_LLBL\n";
+    print STDERR "T_X86_BADJMP: $T_X86_BADJMP\n";
+}
 print STDERR "T_MOVE_DIRVS: $T_MOVE_DIRVS\n";
 print STDERR "T_COPY_DIRVS: $T_COPY_DIRVS\n";
 print STDERR "T_hsc_cc_PAT: $T_hsc_cc_PAT\n";
 print STDERR "T_DOT_WORD: $T_DOT_WORD\n";
-print STDERR "T_HDR_string: $T_HDR_string\n";
+print STDERR "T_HDR_literal: $T_HDR_literal\n";
 print STDERR "T_HDR_misc: $T_HDR_misc\n";
 print STDERR "T_HDR_data: $T_HDR_data\n";
 print STDERR "T_HDR_consist: $T_HDR_consist\n";
@@ -170,34 +368,52 @@ sub mangle_asm {
     %infochk = ();     # given a symbol base, say what chunk its info tbl is in
     %vectorchk = ();    # ditto, return vector table
     %directchk = ();    # ditto, direct return code
+    $EXTERN_DECLS = '';        # .globl <foo> .text (MIPS only)
 
-    $i = 0;
-    $chkcat[0] = 'misc';
+    $i = 0; $chkcat[0] = 'misc'; $chk[0] = '';
 
     while (<INASM>) {
        next if $T_STABBY && /^\.stab.*${T_US}__stg_split_marker/o;
        next if $T_STABBY && /^\.stab.*ghc.*c_ID/;
        next if /${T_PRE_APP}(NO_)?APP/o;
 
-       if ( /^\s+/ ) { # most common case first -- a simple line!
+       next if /^;/ && $TargetPlatform =~ /^hppa/;
+
+       next if /(^$|^\t\.file\t|^ # )/ && $TargetPlatform =~ /^mips-/;
+
+       if ( $TargetPlatform =~ /^mips-/ 
+         && /^\t\.(globl \S+ \.text|comm\t)/ ) {
+           $EXTERN_DECLS .= $_ unless /(__DISCARD__|\b(PK_|ASSIGN_)(FLT|DBL)\b)/;
+  
+       } elsif ( /^\s+/ ) { # most common case first -- a simple line!
            # duplicated from the bottom
 
            $chk[$i] .= $_;
 
+       } elsif ( /\.\.ng:$/ && $TargetPlatform =~ /^alpha-/ ) {
+           # Alphas: Local labels not to be confused with new chunks
+           $chk[$i] .= $_;
+  
+       # NB: all the rest start with a non-space
+
+       } elsif ( $TargetPlatform =~ /^mips-/
+              && /^\d+:/ ) { # a funny-looking very-local label
+           $chk[$i] .= $_;
+
        } elsif ( /$T_CONST_LBL/o ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'string';
+           $chk[++$i]   = $_;
+           $chkcat[$i]  = 'literal';
            $chksymb[$i] = $1;
 
        } elsif ( /^${T_US}__stg_split_marker(\d+)${T_POST_LBL}$/o ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'splitmarker';
+           $chk[++$i]   = $_;
+           $chkcat[$i]  = 'splitmarker';
            $chksymb[$i] = $1;
 
        } elsif ( /^${T_US}([A-Za-z0-9_]+)_info${T_POST_LBL}$/o ) {
            $symb = $1;
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'infotbl';
+           $chk[++$i]   = $_;
+           $chkcat[$i]  = 'infotbl';
            $chksymb[$i] = $symb;
 
            die "Info table already? $symb; $i\n" if defined($infochk{$symb});
@@ -205,31 +421,31 @@ sub mangle_asm {
            $infochk{$symb} = $i;
 
        } elsif ( /^${T_US}([A-Za-z0-9_]+)_entry${T_POST_LBL}$/o ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'slow';
+           $chk[++$i]   = $_;
+           $chkcat[$i]  = 'slow';
            $chksymb[$i] = $1;
 
            $slowchk{$1} = $i;
 
        } elsif ( /^${T_US}([A-Za-z0-9_]+)_fast\d+${T_POST_LBL}$/o ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'fast';
+           $chk[++$i]   = $_;
+           $chkcat[$i]  = 'fast';
            $chksymb[$i] = $1;
 
            $fastchk{$1} = $i;
 
        } elsif ( /^${T_US}([A-Za-z0-9_]+)_closure${T_POST_LBL}$/o ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'closure';
+           $chk[++$i]   = $_;
+           $chkcat[$i]  = 'closure';
            $chksymb[$i] = $1;
 
            $closurechk{$1} = $i;
 
        } elsif ( /^${T_US}ghc.*c_ID${T_POST_LBL}/o ) {
-           $chk[++$i] .= $_;
+           $chk[++$i]  = $_;
            $chkcat[$i] = 'consist';
 
-       } elsif ( /^(___gnu_compiled_c|gcc2_compiled\.)${T_POST_LBL}/o ) {
+       } elsif ( /^(${T_US}__gnu_compiled_c|gcc2_compiled\.)${T_POST_LBL}/o ) {
            ; # toss it
 
        } elsif ( /^${T_US}ErrorIO_call_count${T_POST_LBL}$/o   # HACK!!!!
@@ -239,32 +455,37 @@ sub mangle_asm {
               || /^${T_US}.*_done${T_POST_LBL}$/o              # PROF: _module_done
               || /^${T_US}_module_registered${T_POST_LBL}$/o   # PROF: _module_registered
               ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'data';
+           $chk[++$i]   = $_;
+           $chkcat[$i]  = 'data';
            $chksymb[$i] = '';
 
+       } elsif ( /^([A-Za-z0-9_]+)\s+\.comm/ && $TargetPlatform =~ /^hppa/ ) {
+           $chk[++$i]   = $_;
+           $chkcat[$i]  = 'bss';
+           $chksymb[$i] = $1;
+
        } elsif ( /^${T_US}(ret_|djn_)/o ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
+           $chk[++$i]   = $_;
+           $chkcat[$i]  = 'misc';
            $chksymb[$i] = '';
 
        } elsif ( /^${T_US}vtbl_([A-Za-z0-9_]+)${T_POST_LBL}$/o ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'vector';
+           $chk[++$i]   = $_;
+           $chkcat[$i]  = 'vector';
            $chksymb[$i] = $1;
 
            $vectorchk{$1} = $i;
 
        } elsif ( /^${T_US}([A-Za-z0-9_]+)DirectReturn${T_POST_LBL}$/o ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'direct';
+           $chk[++$i]   = $_;
+           $chkcat[$i]  = 'direct';
            $chksymb[$i] = $1;
 
            $directchk{$1} = $i;
 
        } elsif ( /^${T_US}[A-Za-z0-9_]+_upd${T_POST_LBL}$/o ) {
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
+           $chk[++$i]   = $_;
+           $chkcat[$i]  = 'misc';
            $chksymb[$i] = '';
 
        } elsif ( $TargetPlatform =~ /^i386-.*-solaris2/
@@ -278,20 +499,22 @@ sub mangle_asm {
            # Haskell, make a call to your own C wrapper, then
            # put that C wrapper (which calls one of these) in a
            # plain .c file.  WDP 95/12
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'toss';
+           $chk[++$i]   = $_;
+           $chkcat[$i]  = 'toss';
            $chksymb[$i] = $1;
 
-       } elsif ( /^${T_US}[A-Za-z0-9_]/o ) {
+       } elsif ( /^${T_US}[A-Za-z0-9_]/o
+               && ( $TargetPlatform !~ /^hppa/ # need to avoid local labels in this case
+                  || /^L\$\d+$/ ) ) {
            local($thing);
            chop($thing = $_);
            print STDERR "Funny global thing?: $_"
                unless $KNOWN_FUNNY_THING{$thing}
                    || /^${T_US}_(PRIn|PRStart).*${T_POST_LBL}$/o # pointer reversal GC routines
-                   || /^${T_US}CC_.*${T_POST_LBL}$/            # PROF: _CC_ccident
-                   || /^${T_US}_reg.*${T_POST_LBL}$/;          # PROF: __reg<module>
-           $chk[++$i] .= $_;
-           $chkcat[$i] = 'misc';
+                   || /^${T_US}CC_.*${T_POST_LBL}$/o           # PROF: _CC_ccident
+                   || /^${T_US}_reg.*${T_POST_LBL}$/o;         # PROF: __reg<module>
+           $chk[++$i]   = $_;
+           $chkcat[$i]  = 'misc';
            $chksymb[$i] = '';
 
        } else { # simple line (duplicated at the top)
@@ -309,19 +532,58 @@ sub mangle_asm {
     # about the whole module before we start spitting
     # output.
 
-    for ($i = 0; $i < $numchks; $i++) {
+    local($FIRST_MANGLABLE) = ($TargetPlatform =~ /^(alpha-|hppa|mips-)/) ? 1 : 0;
+
+#   print STDERR "first chunk to mangle: $FIRST_MANGLABLE\n";
+
+    # Alphas: NB: we start meddling at chunk 1, not chunk 0
+    # The first ".rdata" is quite magical; as of GCC 2.7.x, it
+    # spits a ".quad 0" in after the v first ".rdata"; we
+    # detect this special case (tossing the ".quad 0")!
+    local($magic_rdata_seen) = 0;
+  
+    # HPPAs, MIPSen: also start medding at chunk 1
+
+    for ($i = $FIRST_MANGLABLE; $i < $numchks; $i++) {
        $c = $chk[$i]; # convenience copy
 
 #      print STDERR "\nCHK $i (BEFORE) (",$chkcat[$i],"):\n", $c;
 
-       # toss all prologue stuff;
+       # toss all prologue stuff; HPPA is pretty weird
+       # (see elsewhere)
+       $c = &mash_hppa_prologue($c) if $TargetPlatform =~ /^hppa/;
+
        # be slightly paranoid to make sure there's
        # nothing surprising in there
        if ( $c =~ /--- BEGIN ---/ ) {
            if (($p, $r) = split(/--- BEGIN ---/, $c)) {
-               $p =~ s/^\tpushl \%edi\n//;
-               $p =~ s/^\tpushl \%esi\n//;
-               $p =~ s/^\tsubl \$\d+,\%esp\n//;
+
+               if ($TargetPlatform =~ /^i386-/) {
+                   $p =~ s/^\tpushl \%edi\n//;
+                   $p =~ s/^\tpushl \%esi\n//;
+                   $p =~ s/^\tsubl \$\d+,\%esp\n//;
+               } elsif ($TargetPlatform =~ /^m68k-/) {
+                   $p =~ s/^\tlink a6,#-?\d.*\n//;
+                   $p =~ s/^\tmovel d2,sp\@-\n//;
+                   $p =~ s/^\tmovel d5,sp\@-\n//; # SMmark.* only?
+                   $p =~ s/^\tmoveml \#0x[0-9a-f]+,sp\@-\n//; # SMmark.* only?
+               } elsif ($TargetPlatform =~ /^mips-/) {
+                   # the .frame/.mask/.fmask that we use is the same
+                   # as that produced by GCC for miniInterpret; this
+                   # gives GDB some chance of figuring out what happened
+                   $FRAME = "\t.frame\t\$sp,2168,\$31\n\t.mask\t0x90000000,-4\n\t.fmask\t0x00000000,0\n";
+                   $p =~ s/^\t\.(frame).*\n/__FRAME__/g;
+                   $p =~ s/^\t\.(mask|fmask).*\n//g;
+                   $p =~ s/^\t\.cprestore.*\n/\t\.cprestore 416\n/; # 16 + 100 4-byte args
+                   $p =~ s/^\tsubu\t\$sp,\$sp,\d+\n//;
+                   $p =~ s/^\tsw\t\$31,\d+\(\$sp\)\n//;
+                   $p =~ s/^\tsw\t\$fp,\d+\(\$sp\)\n//;
+                   $p =~ s/^\tsw\t\$28,\d+\(\$sp\)\n//;
+                   $p =~ s/__FRAME__/$FRAME/;
+               } else {
+                   print STDERR "$Pgm: unknown prologue mangling? $TargetPlatform\n";
+               }
+
                die "Prologue junk?: $p\n" if $p =~ /^\t[^\.]/;
 
                # glue together what's left
@@ -332,29 +594,71 @@ sub mangle_asm {
        # toss all epilogue stuff; again, paranoidly
        if ( $c =~ /--- END ---/ ) {
            if (($r, $e) = split(/--- END ---/, $c)) {
-               $e =~ s/^\tret\n//;
-               $e =~ s/^\tpopl \%edi\n//;
-               $e =~ s/^\tpopl \%esi\n//;
-               $e =~ s/^\taddl \$\d+,\%esp\n//;
+               if ($TargetPlatform =~ /^i386-/) {
+                   $e =~ s/^\tret\n//;
+                   $e =~ s/^\tpopl \%edi\n//;
+                   $e =~ s/^\tpopl \%esi\n//;
+                   $e =~ s/^\taddl \$\d+,\%esp\n//;
+               } elsif ($TargetPlatform =~ /^m68k-/) {
+                   $e =~ s/^\tunlk a6\n//;
+                   $e =~ s/^\trts\n//;
+               } elsif ($TargetPlatform =~ /^mips-/) {
+                   $e =~ s/^\tlw\t\$31,\d+\(\$sp\)\n//;
+                   $e =~ s/^\tlw\t\$fp,\d+\(\$sp\)\n//;
+                   $e =~ s/^\taddu\t\$sp,\$sp,\d+\n//;
+                   $e =~ s/^\tj\t\$31\n//;
+               } else {
+                   print STDERR "$Pgm: unknown epilogue mangling? $TargetPlatform\n";
+               }
                die "Epilogue junk?: $e\n" if $e =~ /^\t[^\.]/;
 
                # glue together what's left
                $c = $r . $e;
+               $c =~ s/\n\t\n/\n/; # junk blank line
            }
        }
 
+       # On SPARCs, we don't do --- BEGIN/END ---, we just
+       # toss the register-windowing save/restore/ret* instructions
+       # directly:
+       if ( $TargetPlatform =~ /^sparc-/ ) {
+           $c =~ s/^\t(save .*|restore|ret|retl)\n//g;
+           # throw away PROLOGUE comments
+           $c =~ s/^\t!#PROLOGUE# 0\n\t!#PROLOGUE# 1\n//;
+       }
+
+       # On Alphas, the prologue mangling is done a little later (below)
+
        # toss all calls to __DISCARD__
-       $c =~ s/^\tcall ${T_US}__DISCARD__\n//go;
+       $c =~ s/^\t(call|jbsr|jal) ${T_US}__DISCARD__\n//go;
+
+       # MIPS: that may leave some gratuitous asm macros around
+       # (no harm done; but we get rid of them to be tidier)
+       $c =~ s/^\t\.set\tnoreorder\n\t\.set\tnomacro\n\taddu\t(\S+)\n\t\.set\tmacro\n\t\.set\treorder\n/\taddu\t$1\n/
+           if $TargetPlatform =~ /^mips-/;
+
+       # toss stack adjustment after DoSparks
+       $c =~ s/^(\tjbsr _DoSparks\n)\taddqw #8,sp/$1/g
+               if $TargetPlatform =~ /^m68k-/; # this looks old...
+
+       if ( $TargetPlatform =~ /^alpha-/ &&
+          ! $magic_rdata_seen &&
+          $c =~ /^\s*\.rdata\n\t\.quad 0\n\t\.align \d\n/ ) {
+           $c =~ s/^\s*\.rdata\n\t\.quad 0\n\t\.align (\d)\n/\.rdata\n\t\.align $1\n/;
+           $magic_rdata_seen = 1;
+       }
+
+       # pick some end-things and move them to the next chunk
 
        # pin a funny end-thing on (for easier matching):
        $c .= 'FUNNY#END#THING';
 
-       # pick some end-things and move them to the next chunk
-
        while ( $c =~ /${T_MOVE_DIRVS}FUNNY#END#THING/o ) {
            $to_move = $1;
 
-           if ( $to_move =~ /${T_COPY_DIRVS}/ && $i < ($numchks - 1) ) {
+           if ( $i < ($numchks - 1)
+             && ( $to_move =~ /${T_COPY_DIRVS}/
+               || ($TargetPlatform =~ /^hppa/ && $to_move =~ /align/ && $chkcat[$i+1] eq 'literal') )) {
                $chk[$i + 1] = $to_move . $chk[$i + 1];
                # otherwise they're tossed
            }
@@ -362,6 +666,19 @@ sub mangle_asm {
            $c =~ s/${T_MOVE_DIRVS}FUNNY#END#THING/FUNNY#END#THING/o;
        }
 
+       if ( $TargetPlatform =~ /^alpha-/ && $c =~ /^\t\.ent\s+(\S+)/ ) {
+           $ent = $1;
+           # toss all prologue stuff, except for loading gp, and the ..ng address
+           if (($p, $r) = split(/^\t\.prologue/, $c)) {
+               if (($keep, $junk) = split(/\.\.ng:/, $p)) {
+                   $c = $keep . "..ng:\n";
+               } else {
+                   print STDERR "malformed code block ($ent)?\n"
+               }
+           }
+           $c .= "\t.frame \$30,0,\$26,0\n\t.prologue" . $r;
+       }
+  
        $c =~ s/FUNNY#END#THING//;
 
 #      print STDERR "\nCHK $i (AFTER) (",$chkcat[$i],"):\n", $c;
@@ -369,30 +686,78 @@ sub mangle_asm {
        $chk[$i] = $c; # update w/ convenience copy
     }
 
-    # print out all the literal strings first
+    if ( $TargetPlatform =~ /^alpha-/ ) {
+       # print out the header stuff first
+       $chk[0] =~ s/^(\t\.file.*)"(ghc\d+\.c)"/$1"$ifile_root.hc"/;
+       print OUTASM $chk[0];
+
+    } elsif ( $TargetPlatform =~ /^hppa/ ) {
+       print OUTASM $chk[0];
+
+    } elsif ( $TargetPlatform =~ /^mips-/ ) {
+       $chk[0] = "\t\.file\t1 \"$ifile_root.hc\"\n" . $chk[0];
+
+       # get rid of horrible "<dollar>Revision: .*$" strings
+       local(@lines0) = split(/\n/, $chk[0]);
+       local($z) = 0;
+       while ( $z <= $#lines0 ) {
+           if ( $lines0[$z] =~ /^\t\.byte\t0x24,0x52,0x65,0x76,0x69,0x73,0x69,0x6f$/ ) {
+               undef($lines0[$z]);
+               $z++;
+               while ( $z <= $#lines0 ) {
+                   undef($lines0[$z]);
+                   last if $lines0[$z] =~ /[,\t]0x0$/;
+                   $z++;
+               }
+           }
+           $z++;
+       }
+       $chk[0] = join("\n", @lines0);
+       $chk[0] =~ s/\n\n+/\n/;
+       print OUTASM $chk[0];
+    }
+
+    # print out all the literal strings next
     for ($i = 0; $i < $numchks; $i++) {
-       if ( $chkcat[$i] eq 'string' ) {
-           print OUTASM $T_HDR_string, $chk[$i];
-           
+       if ( $chkcat[$i] eq 'literal' ) {
+           print OUTASM $T_HDR_literal, $chk[$i];
+           print OUTASM "; end literal\n" if $TargetPlatform =~ /^hppa/; # for the splitter
+
            $chkcat[$i] = 'DONE ALREADY';
        }
     }
 
-    for ($i = 0; $i < $numchks; $i++) {
+    # on the HPPA, print out all the bss next
+    if ( $TargetPlatform =~ /^hppa/ ) {
+       for ($i = 1; $i < $numchks; $i++) {
+           if ( $chkcat[$i] eq 'bss' ) {
+               print OUTASM "\t.SPACE \$PRIVATE\$\n\t.SUBSPA \$BSS\$\n\t.align 4\n";
+               print OUTASM $chk[$i];
+
+               $chkcat[$i] = 'DONE ALREADY';
+           }
+       }
+    }
+
+    for ($i = $FIRST_MANGLABLE; $i < $numchks; $i++) {
 #      print STDERR "$i: cat $chkcat[$i], symb $chksymb[$i]\n";
 
        next if $chkcat[$i] eq 'DONE ALREADY';
 
        if ( $chkcat[$i] eq 'misc' ) {
-           print OUTASM $T_HDR_misc;
-           &print_doctored($chk[$i], 0);
+           if ($chk[$i] ne '') {
+               print OUTASM $T_HDR_misc;
+               &print_doctored($chk[$i], 0);
+           }
 
        } elsif ( $chkcat[$i] eq 'toss' ) {
            print STDERR "*** NB: TOSSING code for $chksymb[$i] !!! ***\n";
 
        } elsif ( $chkcat[$i] eq 'data' ) {
-           print OUTASM $T_HDR_data;
-           print OUTASM $chk[$i];
+           if ($chk[$i] ne '') {
+               print OUTASM $T_HDR_data;
+               print OUTASM $chk[$i];
+           }
 
        } elsif ( $chkcat[$i] eq 'consist' ) {
            if ( $chk[$i] =~ /$T_hsc_cc_PAT/o ) {
@@ -401,14 +766,17 @@ sub mangle_asm {
                $consist =~ s/\//./g;
                $consist =~ s/-/_/g;
                $consist =~ s/[^A-Za-z0-9_.]/ZZ/g; # ToDo: properly?
-               print OUTASM $T_HDR_consist, "${consist}${T_POST_LBL}\n";
+               print OUTASM $T_HDR_consist, "${consist}${T_POST_LBL}\n"
+                   if $TargetPlatform !~ /^mips-/; # we just don't try in that case
            } else {
                print STDERR "Couldn't grok consistency: ", $chk[$i];
            }
 
        } elsif ( $chkcat[$i] eq 'splitmarker' ) {
            # we can just re-constitute this one...
-           print OUTASM "${T_US}__stg_split_marker",$chksymb[$i],"${T_POST_LBL}\n";
+           # NB: we emit _three_ underscores no matter what,
+           # so ghc-split doesn't have to care.
+           print OUTASM "___stg_split_marker",$chksymb[$i],"${T_POST_LBL}\n";
 
        } elsif ( $chkcat[$i] eq 'closure'
               || $chkcat[$i] eq 'infotbl'
@@ -446,12 +814,33 @@ sub mangle_asm {
                $c = $chk[$slowchk{$symb}];
 
                if ( defined($fastchk{$symb}) ) {
-                   $c =~ s/^\tmovl \$${T_US}${symb}_fast\d+,\%edx\n\tjmp \*\%edx\n//;
-                   $c =~ s/^\tmovl \$${T_US}${symb}_fast\d+,\%eax\n\tjmp \*\%eax\n//;
+                   if ( $TargetPlatform =~ /^alpha-/ ) {
+                       $c =~ s/^\tjmp \$31,\(\$27\),0\n\t\.align 4\n\t\.end/\t.align 4\n\t.end/;
+                   } elsif ( $TargetPlatform =~ /^hppa/ ) {
+                       $c =~ s/^\s+ldil.*\n\s+ldo.*\n\s+bv.*\n(.*\n)?\s+\.EXIT/$1\t.EXIT/;
+                   } elsif ( $TargetPlatform =~ /^i386-/ ) {
+                       $c =~ s/^\tmovl \$${T_US}${symb}_fast\d+,\%edx\n\tjmp \*\%edx\n//;
+                       $c =~ s/^\tmovl \$${T_US}${symb}_fast\d+,\%eax\n\tjmp \*\%eax\n//;
+                   } elsif ( $TargetPlatform =~ /^mips-/ ) {
+                       $c =~ s/^\tjmp \$31,\(\$27\),0\n\t\.align 4\n\t\.end/\t.align 4\n\t.end/;
+                   } elsif ( $TargetPlatform =~ /^m68k-/ ) {
+                       $c =~ s/^\tjmp ${T_US}${symb}_fast\d+.*\n\tnop\n//;
+                       $c =~ s/^\tjmp ${T_US}${symb}_fast\d+.*\n//;
+                   } elsif ( $TargetPlatform =~ /^sparc-/ ) {
+                       $c =~ s/^\tcall ${T_US}${symb}_fast\d+,.*\n\tnop\n//;
+                       $c =~ s/^\tcall ${T_US}${symb}_fast\d+,.*\n(\t[a-z].*\n)/$1/;
+                   } else {
+                       print STDERR "$Pgm: mystery slow-fast dropthrough: $TargetPlatform\n";
+                   }
                }
 
-               print STDERR "still has jump to fast entry point:\n$c"
-                   if $c =~ /${T_US}${symb}_fast/; # NB: paranoia
+               if ( $TargetPlatform !~ /^(alpha-|hppa|mips-)/ ) {
+                   # On alphas, hppa: no very good way to look for "dangling"
+                   # references to fast-entry point.
+                   # (questionable re hppa and mips...)
+                   print STDERR "still has jump to fast entry point:\n$c"
+                       if $c =~ /${T_US}${symb}_fast/; # NB: paranoia
+               }
 
                print OUTASM $T_HDR_entry;
 
@@ -462,7 +851,13 @@ sub mangle_asm {
            
            # FAST ENTRY POINT
            if ( defined($fastchk{$symb}) ) {
-               print OUTASM $T_HDR_fast;
+               if ( ! defined($slowchk{$symb})
+                  # ToDo: the || clause can go once we're no longer
+                  # concerned about producing exactly the same output as before
+                  || $TargetPlatform =~ /^(m68k|sparc|i386)-/
+                  ) {
+                   print OUTASM $T_HDR_fast;
+               }
                &print_doctored($chk[$fastchk{$symb}], 0);
                $chkcat[$fastchk{$symb}] = 'DONE ALREADY';
            }
@@ -484,6 +879,15 @@ sub mangle_asm {
                print OUTASM $T_HDR_direct;
                &print_doctored($chk[$directchk{$symb}], 0);
                $chkcat[$directchk{$symb}] = 'DONE ALREADY';
+
+           } elsif ( $TargetPlatform =~ /^alpha-/ ) {
+               # Alphas: the commented nop is for the splitter, to ensure
+               # that no module ends with a label as the very last
+               # thing.  (The linker will adjust the label to point
+               # to the first code word of the next module linked in,
+               # even if alignment constraints cause the label to move!)
+
+               print OUTASM "\t# nop\n";
            }
            
        } else {
@@ -497,6 +901,31 @@ sub mangle_asm {
 \end{code}
 
 \begin{code}
+sub mash_hppa_prologue { # OK, epilogue, too
+    local($_) = @_;
+
+    # toss all prologue stuff
+    s/^\s+\.ENTRY[^\0]*--- BEGIN ---/\t.ENTRY/;
+
+    # Lie about our .CALLINFO
+    s/^\s+\.CALLINFO.*$/\t.CALLINFO NO_CALLS,NO_UNWIND/;
+
+    # Get rid of P'
+
+    s/LP'/L'/g;
+    s/RP'/R'/g;
+
+    # toss all epilogue stuff
+    s/^\s+--- END ---[^\0]*\.EXIT/\t.EXIT/;
+
+    # Sorry; we moved the _info stuff to the code segment.
+    s/_info,DATA/_info,CODE/g;
+
+    return($_);
+}
+\end{code}
+
+\begin{code}
 sub print_doctored {
     local($_, $need_fallthru_patch) = @_;
 
@@ -631,13 +1060,13 @@ sub print_doctored {
 
     # fix _all_ non-local jumps:
 
-    s/^\tjmp \*${T_PRE_LLBL_PAT}/\tJMP___SL/go;
-    s/^\tjmp ${T_PRE_LLBL_PAT}/\tJMP___L/go;
+    s/^\tjmp \*${T_X86_PRE_LLBL_PAT}/\tJMP___SL/go;
+    s/^\tjmp ${T_X86_PRE_LLBL_PAT}/\tJMP___L/go;
 
     s/^(\tjmp .*\n)/$exit_patch$1/g; # here's the fix...
 
-    s/^\tJMP___SL/\tjmp \*${T_PRE_LLBL}/go;
-    s/^\tJMP___L/\tjmp ${T_PRE_LLBL}/go;
+    s/^\tJMP___SL/\tjmp \*${T_X86_PRE_LLBL}/go;
+    s/^\tJMP___L/\tjmp ${T_X86_PRE_LLBL}/go;
 
     # fix post-PerformGC wrapper (re-)entries ???
 
@@ -656,14 +1085,29 @@ sub print_doctored {
 #=         if /^\t(jmp|call) .*\%ecx/;
     }
 
-    # final peephole fix
+    # final peephole fixes
 
     s/^\tmovl \%eax,36\(\%ebx\)\n\tjmp \*36\(\%ebx\)\n/\tmovl \%eax,36\(\%ebx\)\n\tjmp \*\%eax\n/;
+    s/^\tmovl \$_(.*),(\%e[abcd]x)\n\tjmp \*$2/\tjmp _$1/g;
+
+    # Hacks to eliminate some reloads of Hp.  Worth about 5% code size.
+    # We could do much better than this, but at least it catches about
+    # half of the unnecessary reloads.
+    # Note that these will stop working if either:
+    #  (i) the offset of Hp from BaseReg changes from 80, or
+    #  (ii) the register assignment of BaseReg changes from %ebx
+
+    s/^\tmovl 80\(\%ebx\),\%e.x\n\tmovl \$(.*),(-?[0-9]*)\(\%e.x\)\n\tmovl 80\(\%ebx\),\%e(.)x/\tmovl 80\(\%ebx\),\%e$3x\n\tmovl \$$1,$2\(\%e$3x\)/g;
+
+    s/^\tmovl 80\(\%ebx\),\%e(.)x\n\tmovl (.*),\%e(.)x\n\tmovl \%e$3x,(-?[0-9]*\(\%e$1x\))\n\tmovl 80\(\%ebx\),\%e$1x/\tmovl 80\(\%ebx\),\%e$1x\n\tmovl $2,\%e$3x\n\tmovl \%e$3x,$4/g;
+
+    s/^\tmovl 80\(\%ebx\),\%edx((\n\t(movl|addl) .*,((-?[0-9]*\(.*)|(\%e[abc]x)))+)\n\tmovl 80\(\%ebx\),\%edx/\tmovl 80\(\%ebx\),\%edx$1/g;
+    s/^\tmovl 80\(\%ebx\),\%eax((\n\t(movl|addl) .*,((-?[0-9]*\(.*)|(\%e[bcd]x)))+)\n\tmovl 80\(\%ebx\),\%eax/\tmovl 80\(\%ebx\),\%eax$1/g;
 
     # --------------------------------------------------------
     # that's it -- print it
     #
-    die "Funny jumps?\n$_" if /${T_X86_BADJMP}/o; # paranoia
+    #die "Funny jumps?\n$_" if /${T_X86_BADJMP}/o; # paranoia
 
     print OUTASM $_;
 
@@ -739,37 +1183,64 @@ sub rev_tbl {
 
     local($before) = '';
     local($label) = '';
+    local(@imports) = (); # hppa only
     local(@words) = ();
     local($after) = '';
     local(@lines) = split(/\n/, $tbl);
     local($i, $extra, $words_to_pad, $j);
 
-    for ($i = 0; $i <= $#lines && $lines[$i] !~ /^\t\.long\s+/; $i++) {
+    for ($i = 0; $i <= $#lines && $lines[$i] !~ /^\t${T_DOT_WORD}\s+/o; $i++) {
        $label .= $lines[$i] . "\n",
-           next if $lines[$i] =~ /^[A-Za-z0-9_]+_info:$/
-                || $lines[$i] =~ /^\.globl/
-                || $lines[$i] =~ /^${T_US}vtbl_\S+:$/;
+           next if $lines[$i] =~ /^[A-Za-z0-9_]+_info${T_POST_LBL}$/o
+                || $lines[$i] =~ /^${T_DOT_GLOBAL}/o
+                || $lines[$i] =~ /^${T_US}vtbl_\S+${T_POST_LBL}$/o;
 
        $before .= $lines[$i] . "\n"; # otherwise...
     }
 
-    for ( ; $i <= $#lines && $lines[$i] =~ /^\t\.long\s+/; $i++) {
-       push(@words, $lines[$i]);
+    if ( $TargetPlatform !~ /^hppa/ ) {
+       for ( ; $i <= $#lines && $lines[$i] =~ /^\t${T_DOT_WORD}\s+/o; $i++) {
+           push(@words, $lines[$i]);
+       }
+    } else { # hppa weirdness
+       for ( ; $i <= $#lines && $lines[$i] =~ /^\s+\.(word|IMPORT)/; $i++) {
+           if ($lines[$i] =~ /^\s+\.IMPORT/) {
+               push(@imports, $lines[$i]);
+           } else {
+               # We don't use HP's ``function pointers''
+               # We just use labels in code space, like normal people
+               $lines[$i] =~ s/P%//;
+               push(@words, $lines[$i]);
+           }
+       }
     }
+
     # now throw away the first word (entry code):
     shift(@words) if $discard1;
 
+# Padding removed to reduce code size and improve performance on Pentiums.
+# Simon M. 13/4/96
     # for 486-cache-friendliness, we want our tables aligned
     # on 16-byte boundaries (.align 4).  Let's pad:
-    $extra = ($#words + 1) % 4;
-    $words_to_pad = ($extra == 0) ? 0 : 4 - $extra;
-    for ($j = 0; $j < $words_to_pad; $j++) { push(@words, "\t\.long 0"); }
+#    $extra = ($#words + 1) % 4;
+#    $words_to_pad = ($extra == 0) ? 0 : 4 - $extra;
+#    for ($j = 0; $j < $words_to_pad; $j++) { push(@words, "\t${T_DOT_WORD} 0"); }
 
     for (; $i <= $#lines; $i++) {
        $after .= $lines[$i] . "\n";
     }
 
-    $tbl = $before . join("\n", (reverse @words)) . "\n" . $label . $after;
+    # Alphas:If we have anonymous text (not part of a procedure), the
+    # linker may complain about missing exception information.  Bleh.
+    if ( $TargetPlatform =~ /^alpha-/ && $label =~ /^([A-Za-z0-9_]+):$/) {
+       $before = "\t.ent $1\n" . $before;
+       $after .= "\t.end $1\n";
+    }
+
+    $tbl = $before
+        . (($TargetPlatform !~ /^hppa/) ? '' : join("\n", @imports) . "\n")
+        . join("\n", (reverse @words)) . "\n"
+        . $label . $after;
 
 #   print STDERR "before=$before\n";
 #   print STDERR "label=$label\n";
@@ -781,7 +1252,7 @@ sub rev_tbl {
 \end{code}
 
 \begin{code}
-sub mini_mangle_asm {
+sub mini_mangle_asm_i386 {
     local($in_asmf, $out_asmf) = @_;
 
     &init_TARGET_STUFF();
@@ -804,6 +1275,33 @@ sub mini_mangle_asm {
     close(OUTASM) || &tidy_up_and_die(1,"Failed writing to $out_asmf\n");
     close(INASM)  || &tidy_up_and_die(1,"Failed reading from $in_asmf\n");
 }
+\end{code}
+
+The HP is a major nuisance.  The threaded code mangler moved info
+tables from data space to code space, but unthreaded code in the RTS
+still has references to info tables in data space.  Since the HP
+linker is very precise about where symbols live, we need to patch the
+references in the unthreaded RTS as well.
+
+\begin{code}
+sub mini_mangle_asm_hppa {
+    local($in_asmf, $out_asmf) = @_;
+
+    open(INASM, "< $in_asmf")
+       || &tidy_up_and_die(1,"$Pgm: failed to open `$in_asmf' (to read)\n");
+    open(OUTASM,"> $out_asmf")
+       || &tidy_up_and_die(1,"$Pgm: failed to open `$out_asmf' (to write)\n");
+
+    while (<INASM>) {
+       s/_info,DATA/_info,CODE/;   # Move _info references to code space
+       s/P%_PR/_PR/;
+       print OUTASM;
+    }
+
+    # finished:
+    close(OUTASM) || &tidy_up_and_die(1,"Failed writing to $out_asmf\n");
+    close(INASM)  || &tidy_up_and_die(1,"Failed reading from $in_asmf\n");
+}
 
 # make "require"r happy...
 1;
diff --git a/ghc/driver/ghc-iface.lprl b/ghc/driver/ghc-iface.lprl
new file mode 100644 (file)
index 0000000..5f0fe31
--- /dev/null
@@ -0,0 +1,271 @@
+%************************************************************************
+%*                                                                     *
+\section[Driver-iface-thing]{Interface-file handling}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+sub postprocessHiFile {
+    local($hsc_hi,             # The iface info produced by hsc.
+         $hifile_target,       # The name both of the .hi file we
+                               # already have and which we *might*
+                               # replace.
+         $going_interactive) = @_;
+
+    local($new_hi) = "$Tmp_prefix.hi-new";
+
+#   print STDERR `$Cat $hsc_hi`;
+
+    &constructNewHiFile($hsc_hi, $hifile_target, $new_hi);
+
+    # run diff if they asked for it
+    if ($HiDiff_flag && ! $HiOnStdout && ! $going_interactive && -f $hifile_target) {
+       &run_something("$Cmp -s $hifile_target $new_hi || $Diff $hifile_target $new_hi 1>&2 || exit 0",
+           "Diff'ing old and new .$HiSuffix files"); # NB: to stderr
+    }
+
+    # if we produced an interface file "no matter what",
+    # print what we got on stderr (ToDo: honor -ohi flag)
+    if ( $HiOnStdout ) {
+       print STDERR `$Cat $new_hi`;
+    } else {
+       &run_something("$Cmp -s $hifile_target $new_hi || ( $Rm $hifile_target && $Cp $new_hi $hifile_target )",
+          "Replace .$HiSuffix file, if changed");
+    }
+}
+\end{code}
+
+\begin{code}
+sub constructNewHiFile {
+    local($hsc_hi,         # The iface info produced by hsc.
+         $hifile_target,   # Pre-existing .hi filename (if it exists)
+         $new_hi) = @_;    # Filename for new one
+
+    &readHiFile('old',$hifile_target) unless $HiHasBeenRead{'old'} == 1;
+    &readHiFile('new',$hsc_hi)       unless $HiHasBeenRead{'new'} == 1;
+
+    open(NEWHI, "> $new_hi") || &tidy_up_and_die(1,"Can't open $new_hi (write)\n");
+
+    local($new_module_version) = &calcNewModuleVersion();
+    print NEWHI "interface ", $ModuleName{'new'}, " $new_module_version\n";
+
+    print NEWHI "__usages__\n", $Stuff{'new:usages'} unless $Stuff{'new:usages'} eq '';
+
+    local(@version_keys) = sort (keys %Version);
+    local($num_ver_things) = 0;
+    foreach $v (@version_keys) {
+       next unless $v =~ /^new:(.*$)/;
+       last if $num_ver_things >= 1;
+       $num_ver_things++;
+    }
+
+    print NEWHI "__versions__\n" unless $num_ver_things < 1;
+    foreach $v (@version_keys) {
+       next unless $v =~ /^new:(.*$)/;
+       $v = $1;
+
+       &printNewItemVersion($v, $new_module_version), "\n";
+    }
+
+    print NEWHI "__exports__\n";
+    print NEWHI $Stuff{'new:exports'};
+
+    if ( $Stuff{'new:instance_modules'} ) {
+       print NEWHI "__instance_modules__\n";
+       print NEWHI $Stuff{'new:instance_modules'};
+    }
+
+    if ( $Stuff{'new:fixities'} ) {
+       print NEWHI "__fixities__\n";
+       print NEWHI $Stuff{'new:fixities'};
+    }
+
+    if ( $Stuff{'new:declarations'} ) {
+       print NEWHI "__declarations__\n";
+       print NEWHI $Stuff{'new:declarations'};
+    }
+
+    if ( $Stuff{'new:instances'} ) {
+       print NEWHI "__instances__\n";
+       print NEWHI $Stuff{'new:instances'};
+    }
+
+    if ( $Stuff{'new:pragmas'} ) {
+       print NEWHI "__pragmas__\n";
+       print NEWHI $Stuff{'new:pragmas'};
+    }
+
+    close(NEWHI) || &tidy_up_and_die(1,"Failed writing to $new_hi\n");
+}
+\end{code}
+
+\begin{code}
+%Version = ();
+%Decl   = (); # details about individual definitions
+%Stuff  = (); # where we glom things together
+%HiExists      = ('old',-1,  'new',-1); # 1 <=> definitely exists; 0 <=> doesn't
+%HiHasBeenRead = ('old', 0,  'new', 0);
+%ModuleVersion = ('old', 0,  'new', 0);
+
+sub readHiFile {
+    local($mod,                    # module to read; can be special tag 'old'
+                           # (old .hi file for module being compiled) or
+                           # 'new' (new proto-.hi file for...)
+         $hifile) = @_;    # actual file to read
+
+    # info about the old version of this module's interface
+    $HiExists{$mod}      = -1; # 1 <=> definitely exists; 0 <=> doesn't
+    $HiHasBeenRead{$mod} = 0;
+    $ModuleVersion{$mod} = 0;
+    $Stuff{"$mod:usages"}          = ''; # stuff glommed together
+    $Stuff{"$mod:exports"}         = '';
+    $Stuff{"$mod:instance_modules"} = '';
+    $Stuff{"$mod:instances"}       = '';
+    $Stuff{"$mod:fixities"}        = '';
+    $Stuff{"$mod:declarations"}            = '';
+    $Stuff{"$mod:pragmas"}         = '';
+
+    if (! -f $hifile) { # no pre-existing .hi file
+       $HiExists{$mod} = 0;
+       return();
+    }
+
+    open(HIFILE, "< $hifile") || &tidy_up_and_die(1,"Can't open $hifile (read)\n");
+    $HiExists{$mod} = 1;
+    local($now_in) = '';
+    hi_line: while (<HIFILE>) {
+       next if /^ *$/; # blank line
+
+       # avoid pre-1.3 interfaces
+#print STDERR "now_in:$now_in:$_";
+       if ( /\{-# GHC_PRAGMA INTERFACE VERSION . #-\}/ ) {
+           $HiExists{$mod} = 0;
+           last hi_line;
+       }
+
+       if ( /^interface ([A-Z]\S*) (\d+)/ ) {
+           $ModuleName{$mod}    = $1; # not sure this is used much...
+           $ModuleVersion{$mod} = $2;
+
+       } elsif ( /^interface ([A-Z]\S*)/ && $mod eq 'new' ) { # special case: no version
+           $ModuleName{'new'} = $1;
+
+       } elsif ( /^__([a-z]+)__$/ ) {
+           $now_in = $1;
+
+       } elsif ( $now_in eq 'usages' && /^(\S+)\s+(\d+)\s+:: (.*)/ ) {
+           $Stuff{"$mod:usages"} .= $_; # save the whole thing
+
+       } elsif ( $now_in eq 'versions' && /^(\S+) (\d+)/ ) {
+           local($item) = $1;
+           local($n)    = $2;
+#print STDERR "version read:item=$item, n=$n, line=$_";
+           $Version{"$mod:$item"} = $n;
+
+       } elsif ( $now_in eq 'versions' && /^(\S+)/ && $mod eq 'new') { # doesn't have versions
+           local($item) = $1;
+#print STDERR "new version read:item=$item, line=$_";
+           $Version{"$mod:$item"} = 'y'; # stub value...
+
+       } elsif ( $now_in =~ /^(exports|instance_modules|instances|fixities|pragmas)$/ ) {
+           $Stuff{"$mod:$1"} .= $_; # just save it up
+
+       } elsif ( $now_in eq 'declarations' ) { # relatively special treatment needed...
+           $Stuff{"$mod:declarations"} .= $_; # just save it up
+
+           if ( /^[A-Z][A-Za-z0-9_']*\.(\S+)\s+::\s+/ ) {
+               $Decl{"$mod:$1"} = $_;
+
+           } elsif ( /^type\s+[A-Z][A-Za-z0-9_']*\.(\S+)/ ) {
+               $Decl{"$mod:$1"} = $_;
+
+           } elsif ( /^(newtype|data)\s+(.*\s+=>\s+)?[A-Z][A-Za-z0-9_']*\.(\S+)\s+/ ) {
+               $Decl{"$mod:$3"} = $_;
+
+           } elsif ( /class\s+(.*\s+=>\s+)?[A-Z][A-Za-z0-9_']*\.(\S+)\s+.*where\s+\{.*\};/ ) {
+               $Decl{"$mod:$2"} = $_; # must be wary of => bit matching after "where"...
+           } elsif ( /class\s+(.*\s+=>\s+)?[A-Z][A-Za-z0-9_']*\.(\S+)\s+/ ) {
+               $Decl{"$mod:$2"} = $_;
+
+           } else { # oh, well...
+               print STDERR "$Pgm: decl line didn't match?\n$_";
+           }
+
+       } else {
+           print STDERR "$Pgm:junk old iface line?:section:$now_in:$_";
+       }
+    }
+
+#   foreach $i ( sort (keys %Decl)) {
+#      print STDERR "$i: ",$Decl{$i}, "\n";
+#   }
+
+    close(HIFILE) || &tidy_up_and_die(1,"Failed reading from $hifile\n");
+    $HiHasBeenRead{$mod} = 1;
+}
+\end{code}
+
+\begin{code}
+sub calcNewModuleVersion {
+
+    return(&mv_change(1,'no old .hi file')) if $HiExists{'old'} == 0;
+       # could use "time()" as initial version; if a module existed, then was deleted,
+       # then comes back, we don't want the resurrected one to have an
+       # lower version number than the original (in case there are any
+       # lingering references to the original in other .hi files).
+
+    local($unchanged_version) = $ModuleVersion{'old'}; # will return one of these two
+    local($changed_version)   = $unchanged_version + 1;
+
+    return(&mv_change($changed_version,'usages changed')) if $Stuff{'old:usages'} ne $Stuff{'new:usages'};
+
+    foreach $t ( 'exports', 'instance_modules', 'instances', 'fixities', 'declarations', 'pragmas' ) {
+       return(&mv_change($changed_version,"$t changed")) if $Stuff{"old:$t"} ne $Stuff{"new:$t"};
+    }
+
+    return($unchanged_version);
+}
+
+sub mv_change {
+    local($mv, $str) = @_;
+
+    print STDERR "$Pgm: module version changed to $mv; reason: $str\n";
+    return($mv);
+}
+
+sub printNewItemVersion {
+    local($item, $mod_version) = @_;
+
+    if (! defined($Decl{"new:$item"}) ) {
+       print STDERR "$item: no decl?! (nothing into __versions__)\n";
+       return;
+    }
+
+    local($idecl) = $Decl{"new:$item"};
+
+    if (! defined($Decl{"old:$item"})) {
+       print STDERR "new: $item\n";
+       print NEWHI  "$item $mod_version\n";
+    } elsif ($idecl ne $Decl{"old:$item"})  {
+       print STDERR "changed: $item\n";
+       print NEWHI  "$item $mod_version\n";
+    } elsif (! defined($Version{"old:$item"}) ) {
+       print STDERR "$item: no old version?!\n" 
+    } else {
+       print NEWHI  "$item ", $Version{"old:$item"}, "\n";
+    }
+    return;
+}
+\end{code}
+
+\begin{code}
+sub findHiChanges {
+    local($hsc_hi,             # The iface info produced by hsc.
+         $hifile_target) = @_; # Pre-existing .hi filename (if it exists)
+}
+\end{code}
+
+\begin{code}
+# make "require"r happy...
+1;
+\end{code}
diff --git a/ghc/driver/ghc-recomp.lprl b/ghc/driver/ghc-recomp.lprl
new file mode 100644 (file)
index 0000000..3414605
--- /dev/null
@@ -0,0 +1,135 @@
+%************************************************************************
+%*                                                                     *
+\section[Driver-recomp-chking]{Recompilation checker}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+sub runRecompChkr {
+    local($ifile,      # originating input file
+         $ifile_hs,    # post-unlit, post-cpp, etc., input file
+         $ifile_root,  # input filename minus suffix
+         $ofile_target,# the output file that we ultimately hope to produce
+         $hifile_target# the .hi file ... (ditto)
+        ) = @_;
+
+    ($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";
+       return(1);
+    }
+
+    ($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";
+       return(1);
+    }
+
+    ($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 ($i_mtime > $o_mtime)\n";
+       return(1);
+    }
+
+    # OK, let's see what we used last time; if none of it has
+    # changed, then we don't need to continue with this compilation.
+    require('ghc-iface.prl')
+       || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-iface.prl (recomp)!\n");
+    &tidy_up_and_die(1,"$Pgm:recomp:why has $hifile_target already been read?\n")
+       if $HiHasBeenRead{'old'} == 1;
+
+    &readHiFile('old',$hifile_target);
+    %ModUsed = ();
+    %Used    = ();
+
+    foreach $ul ( split(/;\n/, $Stuff{'old:usages'}) ) {
+
+       $ul =~ /^(\S+)\s+(\d+)\s+:: (.*)/ || die "$Pgm: bad old usages line!\n";
+       local($mod)    = $1;
+       local($modver) = $2;
+       local(@thing)  = split(/\s+/, $3);
+
+       $ModUsed{$mod} = $modver;
+
+       local($key, $n);
+       while ( $#thing >= 0 ) {
+           $key = "$mod:" . $thing[0];
+           $n   = $thing[1];
+           $Used{$key} = $n;
+           shift @thing; shift @thing; # toss two
+       }
+    }
+
+    # see if we can avoid recompilation just by peering at the
+    # module-version numbers:
+
+    &makeHiMap() unless $HiMapDone;
+
+    local($used_modules_have_changed) = 0;
+    used_mod: foreach $um ( keys %ModUsed ) {
+       if ( ! defined($HiMap{$um}) ) {
+           print STDERR "$Pgm:recompile:interface for used module $um no longer exists\n";
+           foreach $hm ( keys %HiMap ) {
+               print STDERR "$hm ==> ", $HiMap{$hm}, "\n";
+           }
+           return 1;
+       } else {
+           if ( $HiHasBeenRead{$um} ) {
+               print STDERR "$Pgm:very strange that $um.hi has already been read?!?\n"
+           } else {
+               &readHiFile($um, $HiMap{$um});
+           }
+       }
+       if ( $ModUsed{$um} != $ModuleVersion{$um} ) {
+           print STDERR "used module version: $um: was: ",$ModUsed{$um}, "; is ", $ModuleVersion{$um}, "\n";
+           $used_modules_have_changed = 1;
+           last used_mod; # no point continuing...
+       }
+    }
+    return 0 if ! $used_modules_have_changed;
+
+    # well, some module version has changed, but maybe no
+    # entity of interest has...
+print STDERR "considering used entities...\n";
+    local($used_entities_have_changed) = 0;
+
+    used_entity: foreach $ue ( keys %Used ) {
+       $ue =~ /([A-Z][A-Za-z0-9_']*):(.+)/;
+       local($ue_m) = $1;
+       local($ue_n) = $2;
+
+       die "$Pgm:interface for used-entity module $ue_m doesn't exist\n"
+           if ! defined($HiMap{$ue_m});
+
+       &readHiFile($ue_m, $HiMap{$ue_m}) unless $HiHasBeenRead{$ue_m};
+       # we might not have read it before...
+
+       if ( !defined($Version{$ue}) ) {
+           print STDERR "No version info for $ue?!\n";
+
+       } elsif ( $Used{$ue} != $Version{$ue} ) {
+           print STDERR "$Pgm:recompile: used entity changed: $ue: was version ",$Used{$ue},"; is ", $Version{$ue}, "\n";
+           $used_entities_have_changed = 1;
+           last used_entity; # no point continuing...
+       }
+    }
+    return 0 if ! $used_entities_have_changed;
+
+    print STDERR "ifile  $ifile:\t$i_mtime\n";
+    print STDERR "ofile  $ofile_target:\t$o_mtime\n";
+    print STDERR "hifile $hifile_target:\t$hi_mtime\n";
+
+    return(1); # OK, *recompile*
+}
+\end{code}
+
+\begin{code}
+# make "require"r happy...
+1;
+\end{code}
index 00c116e..3a4dadb 100644 (file)
@@ -9,7 +9,7 @@ sub inject_split_markers {
     local($hc_file) = @_;
 
     unlink("$Tmp_prefix.unmkd");
-    local($to_do) = "cp $hc_file $Tmp_prefix.unmkd";
+    local($to_do) = "$Cp $hc_file $Tmp_prefix.unmkd";
     &run_something($to_do, 'Prepare to number split markers');
 
     open(TMPI, "< $Tmp_prefix.unmkd") || &tidy_up_and_die(1,"$Pgm: failed to open `$Tmp_prefix.unmkd' (to read)\n");
@@ -191,8 +191,8 @@ sub process_asm_block_sparc {
     if ( $OptimiseC ) {
        $str =~ s/_?__stg_split_marker.*:\n//;
     } else {
-       $str =~ s/(\.text\n\t\.align .\n)\t\.global\s+.*_?__stg_split_marker.*\n\t\.proc.*\n/\1/;
-       $str =~ s/(\t\.align .\n)\t\.global\s+.*_?__stg_split_marker.*\n\t\.proc.*\n/\1/;
+       $str =~ s/(\.text\n\t\.align .\n)\t\.global\s+.*_?__stg_split_marker.*\n\t\.proc.*\n/$1/;
+       $str =~ s/(\t\.align .\n)\t\.global\s+.*_?__stg_split_marker.*\n\t\.proc.*\n/$1/;
     }
 
     # make sure the *.hc filename gets saved; not just ghc*.c (temp name)
@@ -226,10 +226,10 @@ sub process_asm_block_sparc {
 sub process_asm_block_m68k {
     local($str) = @_;
 
-    # strip the marker (ToDo: something special for unregisterized???)
+    # strip the marker
 
-    $str =~ s/(\.text\n\t\.even\n)\t\.globl\s+.*_?__stg_split_marker.*\n/\1/;
-    $str =~ s/(\t\.even\n)\t\.globl\s+.*_?__stg_split_marker.*\n/\1/;
+    $str =~ s/(\.text\n\t\.even\n)\t\.globl\s+.*_?__stg_split_marker.*\n/$1/;
+    $str =~ s/(\t\.even\n)\t\.globl\s+.*_?__stg_split_marker.*\n/$1/;
 
     # it seems prudent to stick on one of these:
     $str = "\.text\n\t.even\n" . $str;
@@ -266,7 +266,7 @@ sub process_asm_block_alpha {
     if ( $OptimiseC ) {
        $str =~ s/_?__stg_split_marker.*:\n//;
     } else {
-       $str =~ s/(\t\.align .\n)\t\.globl\s+.*_?__stg_split_marker.*\n\t\.ent.*\n/\1/;
+       $str =~ s/(\t\.align .\n)\t\.globl\s+.*_?__stg_split_marker.*\n\t\.ent.*\n/$1/;
     }
 
     # remove/record any literal constants defined here
@@ -292,7 +292,7 @@ sub process_asm_block_alpha {
     # Slide the dummy direct return code into the vtbl .ent/.end block,
     # to keep the label fixed if it's the last thing in a module, and
     # to avoid having any anonymous text that the linker will complain about
-    $str =~ s/(\t\.end [A-Za-z0-9_]+)\n\t# nop/\tnop\n\1/g;
+    $str =~ s/(\t\.end [A-Za-z0-9_]+)\n\t# nop/\tnop\n$1/g;
 
     print STDERR "### STRIPPED BLOCK (alpha):\n$str" if $Dump_asm_splitting_info;
 
@@ -302,10 +302,10 @@ sub process_asm_block_alpha {
 sub process_asm_block_iX86 {
     local($str) = @_;
 
-    # strip the marker (ToDo: something special for unregisterized???)
+    # strip the marker
 
-    $str =~ s/(\.text\n\t\.align .(,0x90)?\n)\.globl\s+.*_?__stg_split_marker.*\n/\1/;
-    $str =~ s/(\t\.align .(,0x90)?\n)\.globl\s+.*_?__stg_split_marker.*\n/\1/;
+    $str =~ s/(\.text\n\t\.align .(,0x90)?\n)\.globl\s+.*_?__stg_split_marker.*\n/$1/;
+    $str =~ s/(\t\.align .(,0x90)?\n)\.globl\s+.*_?__stg_split_marker.*\n/$1/;
 
     # it seems prudent to stick on one of these:
     $str = "\.text\n\t.align 4\n" . $str;
@@ -396,7 +396,7 @@ sub process_asm_block_mips {
     if ( $OptimiseC ) {
        $str =~ s/_?__stg_split_marker.*:\n//;
     } else {
-       $str =~ s/(\t\.align .\n)\t\.globl\s+.*_?__stg_split_marker.*\n\t\.ent.*\n/\1/;
+       $str =~ s/(\t\.align .\n)\t\.globl\s+.*_?__stg_split_marker.*\n\t\.ent.*\n/$1/;
     }
 
     # remove/record any literal constants defined here
@@ -422,7 +422,7 @@ sub process_asm_block_mips {
     # Slide the dummy direct return code into the vtbl .ent/.end block,
     # to keep the label fixed if it's the last thing in a module, and
     # to avoid having any anonymous text that the linker will complain about
-    $str =~ s/(\t\.end [A-Za-z0-9_]+)\n\t# nop/\tnop\n\1/g;
+    $str =~ s/(\t\.end [A-Za-z0-9_]+)\n\t# nop/\tnop\n$1/g;
 
     $str .= $UNDEFINED_FUNS; # pin on gratuitiously-large amount of info
 
index 8ccef55..09f1bef 100644 (file)
@@ -37,7 +37,7 @@ possible phases of a compilation:
 For each input file, the phase to START with is determined by the
 file's suffix:
     - .lhs     literate Haskell: lit2pgm
-    - .hs      illiterate Haskell: hsp
+    - .hs      illiterate Haskell: hsc
     - .hc      C from the Haskell compiler: gcc
     - .c       C not from the Haskell compiler: gcc
     - .s       assembly language: as
@@ -56,7 +56,7 @@ option:
 
 Other commonly-used options are:
 
-    -O         An `optimising' package of options, to produce faster code
+    -O         An `optimising' package of compiler flags, for faster code
 
     -prof      Compile for cost-centre profiling
                (add -auto for automagic cost-centres on top-level functions)
@@ -108,17 +108,19 @@ if (! $ENV{'GLASGOW_HASKELL_ROOT'}) { # good -- death to environment variables
     $TopPwd        = '$(TOP_PWD)';
     $InstLibDirGhc  = '$(INSTLIBDIR_GHC)';
     $InstDataDirGhc = '$(INSTDATADIR_GHC)';
+#   $InstSysLibDir  = '$(INSTLIBDIR_HSLIBS)'; ToDo ToDo
+    $InstSysLibDir  = '$(TOP_PWD)/hslibs';
 } else {
     $TopPwd = $ENV{'GLASGOW_HASKELL_ROOT'};
 
-    if ( '$(INSTLIBDIR_GHC)' =~ /^\/(local\/fp|usr\/local)(\/.*)/ ) {
-       $InstLibDirGhc  = $ENV{'GLASGOW_HASKELL_ROOT'} . $2;
+    if ('$(INSTLIBDIR_GHC)' =~ /.*(\/lib\/ghc\/\d\.\d\d\/[^-]-[^-]-[^-]\/.*)/) {
+       $InstLibDirGhc  = $ENV{'GLASGOW_HASKELL_ROOT'} . $1;
     } else {
        print STDERR "GLASGOW_HASKELL_ROOT environment variable is set;\nBut can't untangle $(INSTLIBDIR_GHC).\n(Installation error)\n";
        exit(1);
     }
 
-    if ( '$(INSTDATADIR_GHC)' =~ /\/(local\/fp|usr\/local)(\/.*)/ ) {
+    if ('$(INSTDATADIR_GHC)' =~ /.*(\/lib\/ghc\/\d\.\d\d\/.*)/) {
        $InstDataDirGhc = $ENV{'GLASGOW_HASKELL_ROOT'} . $2;
     } else {
        print STDERR "GLASGOW_HASKELL_ROOT environment variable is set;\nBut can't untangle $(INSTDATADIR_GHC).\n(Installation error)\n";
@@ -128,8 +130,6 @@ if (! $ENV{'GLASGOW_HASKELL_ROOT'}) { # good -- death to environment variables
 
 $Status  = 0; # just used for exit() status
 $Verbose = '';
-$CoreLint = '';
-$Time = '';    # ToDo: mkworld-ize the timing command
 
 # set up signal handler
 sub quit_upon_signal { &tidy_up_and_die(1, ''); }
@@ -138,7 +138,7 @@ $SIG{'QUIT'} = 'quit_upon_signal';
 
 # where to get "require"d .prl files at runtime (poor man's dynamic loading)
 #   (use LIB, not DATA, because we can't be sure of arch-independence)
-@INC = ( ( $(INSTALLING) ) ? "$InstLibDirGhc"
+@INC = ( ( $(INSTALLING) ) ? $InstLibDirGhc
                           : "$TopPwd/$(CURRENT_DIR)" );
 
 if ( $ENV{'TMPDIR'} ) { # where to make tmp file names
@@ -154,7 +154,12 @@ $Unlit = ( $(INSTALLING) ) ? "$InstLibDirGhc/unlit"
                             : "$TopPwd/$(CURRENT_DIR)/$(GHC_UNLIT)";
 @Unlit_flags   = ();
 
-$Cat    = "cat";
+$Cp   = '$(CP)';
+$Rm   = '$(RM)';
+$Diff = '$(CONTEXT_DIFF)';
+$Cat  = 'cat';
+$Cmp  = 'cmp';
+$Time = '';
 
 $HsCpp  = # but this is re-set to "cat" (after options) if -cpp not seen
           ( $(INSTALLING) ) ? "$InstLibDirGhc/hscpp"
@@ -162,10 +167,6 @@ $HsCpp      = # but this is re-set to "cat" (after options) if -cpp not seen
 @HsCpp_flags   = ();
 $genSPECS_flag = '';           # See ../utils/hscpp/hscpp.prl
 
-$HsP    = ( $(INSTALLING) ) ? "$InstLibDirGhc/hsp"
-                            : "$TopPwd/$(CURRENT_DIR)/$(GHC_HSP)";
-@HsP_flags = ();
-
 $HsC    = ( $(INSTALLING) ) ? "$InstLibDirGhc/hsc"
                             : "$TopPwd/$(CURRENT_DIR)/$(GHC_HSC)";
 
@@ -177,10 +178,11 @@ $SysMan    = ( $(INSTALLING) ) ? "$InstLibDirGhc/SysMan"
 #   terrible things to cache behavior.
 $Specific_heap_size = 6 * 1000 * 1000;
 $Specific_stk_size  = 1000 * 1000;
-$Scale_sizes_by = 1.0;
-$RTS_style = $(GHC_RTS_STYLE);
-@HsC_rts_flags = ();
+$Scale_sizes_by     = 1.0;
+@HsC_rts_flags      = ();
 
+@HsP_flags     = (); # these are the flags destined solely for
+                     # the flex/yacc parser
 @HsC_flags     = ();
 @HsC_antiflags  = ();
 \end{code}
@@ -189,9 +191,10 @@ The optimisations/etc to be done by the compiler are {\em normally}
 expressed with a \tr{-O} (or \tr{-O2}) flag, or by its absence.
 
 \begin{code}
-$OptLevel = 0;     # no -O == 0; -O == 1; -O2 == 2; -Ofile == 3
-$MinusO2ForC = 0;   # set to 1 if -O2 should be given to C compiler
+$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      = '';
 \end{code}
 
 These variables represent parts of the -O/-O2/etc ``templates,''
@@ -202,41 +205,31 @@ $Oopt_UnfoldingUseThreshold       = '-fsimpl-uf-use-threshold3';
 $Oopt_MaxSimplifierIterations  = '-fmax-simplifier-iterations4';
 $Oopt_PedanticBottoms          = '-fpedantic-bottoms'; # ON by default
 $Oopt_MonadEtaExpansion                = '';
-#OLD:$Oopt_LambdaLift          = '';
-$Oopt_AddAutoSccs              = '';
 $Oopt_FinalStgProfilingMassage = '';
 $Oopt_StgStats                 = '';
 $Oopt_SpecialiseUnboxed                = '';
 $Oopt_DoSpecialise             = '-fspecialise';
 $Oopt_FoldrBuild               = 1; # On by default!
-$Oopt_FB_Support               = '-fdo-new-occur-anal -fdo-arity-expand';
+$Oopt_FB_Support               = '-fdo-arity-expand';
 #$Oopt_FoldrBuildWW            = 0; # Off by default
 $Oopt_FoldrBuildInline         = '-fdo-inline-foldr-build';
 \end{code}
 
 Things to do with C compilers/etc:
 \begin{code}
-$CcUnregd      = '$(GHC_DEBUG_HILEV_ASM)'; # our high-level assembler (non-optimising)
-$CcRegd                = '$(GHC_OPT_HILEV_ASM)';   # our high-level assembler (optimising)
-$GccAvailable  = $(GHC_GCC_IS_AVAILABLE);  # whether GCC avail or not for optimising
-
+$CcRegd                = 'gcc';
 @CcBoth_flags  = ('-S');   # flags for *any* C compilation
 @CcInjects     = ();
 
-# non-registerizing flags: those for all files, those only for .c files; those only for .hc files
-@CcUnregd_flags   = ( $GccAvailable ) ? ('-ansi', '-pedantic') : ();
-@CcUnregd_flags_c = ();
-@CcUnregd_flags_hc= ();
-
-# ditto; but for registerizing (we must have GCC for this)
+# 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 = ();
 
-$As            = ''; # assembler is normally the same pgm as used for C compilation
+$As            = ''; # "assembler" is normally GCC
 @As_flags      = ();
 
-$Lnkr          = ''; # linker is normally the same pgm as used for C compilation
+$Lnkr          = ''; # "linker" is normally GCC
 @Ld_flags      = ();
 
 # 'nm' is used for consistency checking (ToDo: mk-world-ify)
@@ -283,7 +276,7 @@ $BuildTag   = ''; # default is sequential build w/ Appel-style GC
 %BuildDescr    = ('',      'normal sequential',
                   '_p',    'profiling',
                   '_t',    'ticky-ticky profiling',
-                  '_u',    'unregisterized (using portable C only)',
+#OLD:             '_u',    'unregisterized (using portable C only)',
                   '_mc',   'concurrent',
                   '_mr',   'profiled concurrent',
                   '_mt',   'ticky concurrent',
@@ -341,12 +334,15 @@ $BuildTag = ''; # default is sequential build w/ Appel-style GC
                   '_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\');',
 
-                           # unregisterized (ToDo????)
-                  '_u',    '',
+#OLD:                      # unregisterized (ToDo????)
+#                 '_u',    '',
 
                            # concurrent
                   '_mc',   '$StkChkByPageFaultOK = 0;
@@ -374,7 +370,8 @@ $BuildTag   = ''; # default is sequential build w/ Appel-style GC
 
                            # GranSim
                   '_mg',   '$StkChkByPageFaultOK = 0;
-                            push(@HsC_flags,  \'-fconcurrent\');
+                            push(@HsC_flags,  \'-fconcurrent\', \'-fgransim\');
+                            push(@HsCpp_flags,\'-D__GRANSIM__\',   \'-DGRAN\');
                             push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DGRAN\');',
 
                   '_2s',   'push (@CcBoth_flags, \'-DGC2s\');',
@@ -409,17 +406,17 @@ require special handling.
 @SysImport_dir = ( $(INSTALLING) )
                    ? ( "$InstDataDirGhc/imports" )
                    : ( "$TopPwd/$(CURRENT_DIR)/$(GHC_LIBSRC)/prelude"
-                     );
+                     , "$TopPwd/$(CURRENT_DIR)/$(GHC_LIBSRC)/required" );
 
-$ghc_version_info = $(PROJECTVERSION) * 100;
-$haskell1_version = 2; # i.e., Haskell 1.2
-@Cpp_define    = ();
+$GhcVersionInfo  = 201; # ToDo: int ($(PROJECTVERSION) * 100);
+$Haskell1Version = 3; # i.e., Haskell 1.3
+@Cpp_define     = ();
 
 @UserLibrary_dir= ();  #-L things;...
 @UserLibrary           = ();   #-l things asked for by the user
 
 @SysLibrary_dir = ( ( $(INSTALLING) )  #-syslib things supplied by the system
-                   ? "$InstLibDirGhc"
+                   ? $InstLibDirGhc
                    : ("$TopPwd/$(CURRENT_DIR)/$(GHC_RUNTIMESRC)",
                       "$TopPwd/$(CURRENT_DIR)/$(GHC_RUNTIMESRC)/gmp",
                       "$TopPwd/$(CURRENT_DIR)/$(GHC_LIBSRC)")
@@ -440,35 +437,28 @@ start with.  Linking is weird and kept track of separately.
 
 Here are the initial defaults applied to all files:
 \begin{code}
-$Do_lit2pgm = 1;
-$Do_hscpp   = 1;       # but we run 'cat' by default (see after arg check)
 $Cpp_flag_set = 0;     # (hack)
 $Only_preprocess_C = 0;        # pretty hackish
-$ProduceHi  = 1;       # but beware magical value "2"! (hack)
 $PostprocessCcOutput = 0;
-$HiDiff_flag= 0;
 
 # native code-gen or via C?
 $HaveNativeCodeGen = $(GHC_WITH_NATIVE_CODEGEN);
-$ProduceS = '';
-if ($HaveNativeCodeGen) {
-    if ($TargetPlatform =~ /^(alpha|sparc)-/) {
-       $ProduceS = $TargetPlatform;
-    }
-}
-$ProduceC = ($ProduceS) ? 0 : 1;
+$HscOut = '-C='; # '-C=' ==> .hc output; '-S=' ==> .s output; '-N=' ==> neither
+$HscOut = '-S='
+    if $HaveNativeCodeGen && $TargetPlatform =~ /^(alpha|sparc|i386)-/;
+$ProduceHi   = '-hifile=';
+$HiOnStdout  = 0;
+$HiDiff_flag = 0;
 
 $CollectingGCstats = 0;
 $CollectGhcTimings = 0;
-$RegisteriseC  = '';    # set to 'o', if using optimised C code (only if avail)
-                       #   or if generating equiv asm code
 $DEBUGging = '';       # -DDEBUG and all that it entails (um... not really)
 $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
-#UNUSED:$PROFdict  = '';        # set to relevant hsc flag if -dict-all
 $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
@@ -479,23 +469,22 @@ $Specific_output_file = '';       # set by -o <file>; "-" for stdout
 $Specific_hi_file = '';                # set by -ohi <file>; "-" for stdout
 $Specific_dump_file = '';      # set by -odump <file>; "-" for stdout
 $Using_dump_file = 0;
-$Osuffix    = '.o';
-$HiSuffix   = '.hi';
-$Do_hsp            = 2;    # 1 for "old" parser; 2 for "new" parser (in hsc)
-$Do_hsc            = 1;
+$Osuffix    = '';      # default: use the normal suffix for that kind of output
+$HiSuffix   = 'hi';
+$SysHiSuffix= 'hi';
+$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;
 $Do_lnkr    = 1;
 $Keep_hc_file_too = 0;
 $Keep_s_file_too = 0;
-$CompilingPrelude = 0;
+$UseGhcInternals = 0; # if 1, may use GHC* modules
 $SplitObjFiles = 0;
 $NoOfSplitFiles = 0;
 $Dump_parser_output = 0;
 $Dump_raw_asm = 0;
-$Dump_asm_insn_counts = 0;
-$Dump_asm_globals_info = 0;
 $Dump_asm_splitting_info = 0;
+$NoImplicitPrelude = 0;
 
 # and the list of files
 @Input_file = ();
@@ -516,16 +505,16 @@ $LinkChk = 1;     # 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 = 29;
+$HsC_major_version = 30;
 $HsC_minor_version = 0;
-$Cc_major_version  = 33;
+$Cc_major_version  = 35;
 $Cc_minor_version  = 0;
 
 # options: these must always agree
 $HsC_consist_options = '';    # we record, in this order:
                              #     Build tag; debugging?
 $Cc_consist_options  = '';    # we record, in this order:
-                             #     Build tag; debugging? registerised?
+                             #     Build tag; debugging?
 \end{code}
 
 %************************************************************************
@@ -556,11 +545,10 @@ if (grep(/^-user-prelude$/, @ARGV)) {
                 @ARGV);
 
     unshift(@ARGV,
-       '-prelude',
+       '-fcompiling-ghc-internals=???', # ToDo!!!!
         '-O',
         '-fshow-pragma-name-errs',
         '-fshow-import-specs',
-        '-fomit-reexported-instances',
         '-fglasgow-exts',
         '-genSPECS',
         '-DUSE_FOLDR_BUILD',
@@ -580,25 +568,25 @@ arg: while($_ = $ARGV[0]) {
     /^-v$/         && do { $Verbose = '-v'; $Time = 'time'; next arg; };
 
     #---------- what phases are to be run ----------------------------------
+    /^-short$/     && do { $Do_recomp_chkr = 1; next arg; };
+
     /^-cpp$/       && do { $Cpp_flag_set = 1; next arg; };
     # change the global default:
     # we won't run cat; we'll run the real thing
        
-    /^-C$/         && do { $Do_cc = 0; $Do_as = 0; $Do_lnkr = 0;
-                           $ProduceC = 1; $ProduceS = '';
+    /^-C$/         && do { $Do_cc = 0; $Do_as = 0; $Do_lnkr = 0; $HscOut = '-C=';
                            next arg; };
     # stop after generating C
        
-    /^-noC$/       && do { $ProduceC = 0; $ProduceS = ''; $ProduceHi = 0;
+    /^-noC$/       && do { $HscOut = '-N='; $ProduceHi = '-nohifile=';
                            $Do_cc = 0; $Do_as = 0; $Do_lnkr = 0;
                            next arg; };
     # leave out actual C generation (debugging) [also turns off interface gen]
 
-    /^-hi$/        && do { $ProduceHi = 2; next arg; };
+    /^-hi$/        && do { $HiOnStdout = 1; $ProduceHi = '-hifile='; next arg; };
     # _do_ generate an interface; usually used as: -noC -hi
-    # NB: magic value "2" for $ProduceHi (hack)
 
-    /^-nohi$/      && do { $ProduceHi = 0; next arg; };
+    /^-nohi$/      && do { $ProduceHi = '-nohifile='; next arg; };
     # don't generate an interface (even if generating C)
 
     /^-hi-diffs$/    && do { $HiDiff_flag = 1; next arg; };
@@ -620,24 +608,6 @@ arg: while($_ = $ARGV[0]) {
     /^-no-link-chk$/ && do { $LinkChk = 0; next arg; };
     # don't do consistency-checking after a link
 
-    # generate code for a different target architecture; e.g., m68k
-    # ToDo: de-Glasgow-ize & probably more...
-# OLD:
-#    /^-target$/ && do { $TargetPlatform = &grab_arg_arg('-target', ''); 
-#                        if ($TargetPlatform ne $HostPlatform) {
-#                          if ( $TargetPlatform =~ /^m68k-/ ) {
-#                              $CcUnregd = $CcRegd = 'gcc-m68k';
-#                          } else {
-#                              print STDERR "$Pgm: Can't handle -target $TargetPlatform\n";
-#                              $Status++;
-#                          }
-#                      }
-#                      next arg; };
-
-    /^-unregisteri[sz]ed$/ && do { $RegisteriseC = 'no';
-                                  $ProduceC = 1; $ProduceS = ''; # via C, definitely
-                                  next arg; };
-
     /^-tmpdir$/ && do { $Tmp_prefix = &grab_arg_arg('-tmpdir', '');
                        $Tmp_prefix = "$Tmp_prefix/ghc$$";
                        $ENV{'TMPDIR'} = $Tmp_prefix; # for those who use it...
@@ -650,6 +620,13 @@ arg: while($_ = $ARGV[0]) {
     # "-o -" sends it to stdout
     # if <file> has a directory component, that dir must already exist
 
+    /^-odir$/      && do { $Specific_output_dir = &grab_arg_arg('-odir', '');
+                           if (! -d $Specific_output_dir) {
+                               print STDERR "$Pgm: -odir: no such directory: $Specific_output_dir\n";
+                               $Status++;
+                           }
+                           next arg; };
+
     /^-o$/         && do { $Specific_output_file = &grab_arg_arg('-o', '');
                            if ($Specific_output_file ne '-'
                             && $Specific_output_file =~ /(.*)\/[^\/]*$/) {
@@ -661,6 +638,13 @@ arg: while($_ = $ARGV[0]) {
                            }
                            next arg; };
 
+    /^-osuf$/      && do { $Osuffix  = &grab_arg_arg('-osuf', '');
+                           if ($Osuffix =~ /\./ ) {
+                               print STDERR "$Pgm: -osuf suffix shouldn't contain a .\n";
+                               $Status++;
+                           }
+                           next arg; };
+
     # -ohi <file>; send the interface to <file>; "-ohi -" to send to stdout
     /^-ohi$/       && do { $Specific_hi_file = &grab_arg_arg('-ohi', '');
                            if ($Specific_hi_file ne '-'
@@ -673,6 +657,20 @@ arg: while($_ = $ARGV[0]) {
                            }
                            next arg; };
 
+    /^-hisuf$/     && do { $HiSuffix = &grab_arg_arg('-hisuf', '');
+                           if ($HiSuffix =~ /\./ ) {
+                               print STDERR "$Pgm: -hisuf suffix shouldn't contain a .\n";
+                               $Status++;
+                           }
+                           next arg; };
+    /^-hisuf-prelude$/ && do { # as esoteric as they come...
+                           $SysHiSuffix = &grab_arg_arg('-hisuf-prelude', '');
+                           if ($SysHiSuffix =~ /\./ ) {
+                               print STDERR "$Pgm: -hisuf-prelude suffix shouldn't contain a .\n";
+                               $Status++;
+                           }
+                           next arg; };
+
     /^-odump$/     && do { $Specific_dump_file = &grab_arg_arg('-odump', '');
                            if ($Specific_dump_file =~ /(.*)\/[^\/]*$/) {
                                local($dir_part) = $1;
@@ -683,23 +681,6 @@ arg: while($_ = $ARGV[0]) {
                            }
                            next arg; };
 
-    /^-odir$/      && do { $Specific_output_dir = &grab_arg_arg('-odir', '');
-                           if (! -d $Specific_output_dir) {
-                               print STDERR "$Pgm: -odir: no such directory: $Specific_output_dir\n";
-                               $Status++;
-                           }
-                           next arg; };
-
-    /^-osuf$/      && do { $Osuffix  = &grab_arg_arg('-osuf', ''); next arg; };
-    /^-hisuf$/     && do { $HiSuffix = &grab_arg_arg('-hisuf', '');
-                           push(@HsP_flags, "-h$HiSuffix");
-                           next arg; };
-
-    /^-hisuf-prelude$/ && do { # as esoteric as they come...
-                           local($suffix) = &grab_arg_arg('-hisuf-prelude', '');
-                           push(@HsP_flags, "-g$suffix");
-                           next arg; };
-
     #-------------- scc & Profiling Stuff ----------------------------------
 
     /^-prof$/ && do { $PROFing = 'p'; next arg; }; # profiling -- details later!
@@ -717,19 +698,22 @@ arg: while($_ = $ARGV[0]) {
                $PROFcaf = '-fauto-sccs-on-individual-cafs';
                next arg; };
 
-# UNUSED:
-#    /^-dict-all/ && do { # generate individual SCC annotations on dictionaries
-#              $PROFdict = '-fauto-sccs-on-individual-dicts';
-#              next arg; };
-
     /^-ignore-scc$/ && do {
                # forces ignore of scc annotations even if profiling
                $PROFignore_scc = '-W';
                next arg; };
 
-    /^-G(.*)$/ && do { push(@HsC_flags, $_);   # set group for cost centres
+    /^-G(.*)$/ && do { push(@HsC_flags, "-G=$1");   # set group for cost centres
                        next arg; };
 
+    /^-unprof-scc-auto/ && do {
+               # generate auto SCCs on top level bindings when not profiling
+               # used to measure optimisation effects of presence of sccs
+               $UNPROFscc_auto = ( /-all/ )
+                           ? '-fauto-sccs-on-all-toplevs'
+                           : '-fauto-sccs-on-exported-toplevs';
+               next arg; };
+
     #--------- ticky/concurrent/parallel -----------------------------------
     # we sort out the details a bit later on
 
@@ -816,12 +800,12 @@ arg: while($_ = $ARGV[0]) {
 
     /^-syslib(.*)/  && do { local($syslib) = &grab_arg_arg('-syslib',$1);
                            print STDERR "$Pgm: no such system library (-syslib): $syslib\n",
-                             $Status++ unless $syslib =~ /^(hbc|ghc|contrib)$/;
+                             $Status++ unless $syslib =~ /^(hbc|ghc|posix|contrib)$/;
 
                            unshift(@SysImport_dir,
                                $(INSTALLING)
-                               ? "$InstDataDirGhc/imports/$syslib"
-                               : "$TopPwd/$(CURRENT_DIR)/$(GHC_LIBSRC)/$syslib");
+                               ? "$InstSysLibDir/$syslib/imports"
+                               : "$TopPwd/hslibs/$syslib/src");
 
                            unshift(@SysLibrary, ('-lHS' . $syslib ));
 
@@ -836,10 +820,8 @@ arg: while($_ = $ARGV[0]) {
     # these change what executable is run for each phase:
     /^-pgmL(.*)$/   && do { $Unlit   = $1; next arg; };
     /^-pgmP(.*)$/   && do { $HsCpp   = $1; next arg; };
-    /^-pgmp(.*)$/   && do { $HsP     = $1; next arg; };
     /^-pgmC(.*)$/   && do { $HsC     = $1; next arg; };
-    /^-pgmcO(.*)$/  && do { $CcRegd   = $1; next arg; };
-    /^-pgmc(.*)$/   && do { $CcUnregd  = $1; next arg; };
+    /^-pgmcO?(.*)$/ && do { $CcRegd  = $1; next arg; }; # the O? for back compat
     /^-pgma(.*)$/   && do { $As      = $1; next arg; };
     /^-pgml(.*)$/   && do { $Lnkr    = $1; next arg; };
 
@@ -847,15 +829,8 @@ arg: while($_ = $ARGV[0]) {
     # these allow arbitrary option-strings to go to any phase:
     /^-optL(.*)$/   && do { push(@Unlit_flags,   $1); next arg; };
     /^-optP(.*)$/   && do { push(@HsCpp_flags,   $1); next arg; };
-    /^-optp(.*)$/   && do { push(@HsP_flags,     $1); next arg; };
     /^-optCrts(.*)$/&& do { push(@HsC_rts_flags, $1); next arg; };
     /^-optC(.*)$/   && do { push(@HsC_flags,     $1); next arg; };
-    /^-optcNhc(.*)$/ && do { push(@CcUnregd_flags_hc,$1); next arg; };
-    /^-optcNc(.*)$/  && do { push(@CcUnregd_flags_c,$1); next arg; };
-    /^-optcN(.*)$/  && do { push(@CcUnregd_flags,   $1); next arg; };
-    /^-optcOhc(.*)$/&& do { push(@CcRegd_flags_hc,$1); next arg; };
-    /^-optcOc(.*)$/ && do { push(@CcRegd_flags_c, $1); next arg; };
-    /^-optcO(.*)$/  && do { push(@CcRegd_flags,   $1); next arg; };
     /^-optc(.*)$/   && do { push(@CcBoth_flags,  $1); next arg; };
     /^-opta(.*)$/   && do { push(@As_flags,      $1); next arg; };
     /^-optl(.*)$/   && do { push(@Ld_flags,      $1); next arg; };
@@ -868,46 +843,27 @@ arg: while($_ = $ARGV[0]) {
                           $genSPECS_flag = $_;
                            next arg; };
 
-    #---------- Haskell parser (hsp) ---------------------------------------
-    /^-ddump-parser$/ && do { $Dump_parser_output = 1; next arg; };
-
     #---------- post-Haskell "assembler"------------------------------------
-    /^-ddump-raw-asm$/         && do { $Dump_raw_asm          = 1; next arg; };
-    /^-ddump-asm-insn-counts$/  && do { $Dump_asm_insn_counts  = 1; next arg; };
-    /^-ddump-asm-globals-info$/ && do { $Dump_asm_globals_info = 1; next arg; };
-
+    /^-ddump-raw-asm$/           && do { $Dump_raw_asm        = 1; next arg; };
     /^-ddump-asm-splitting-info$/ && do { $Dump_asm_splitting_info = 1; next arg; };
 
     #---------- Haskell compiler (hsc) -------------------------------------
 
-# possibly resurrect LATER
-#   /^-fspat-profiling$/  && do { push(@HsC_flags, '-fticky-ticky');
-#                          $ProduceS = ''; $ProduceC = 1; # must use C compiler
-#                          push(@CcBoth_flags, '-DDO_SPAT_PROFILING');
-#                          push(@CcBoth_flags, '-fno-schedule-insns'); # not essential
-#                          next arg; };
-
     /^-keep-hc-files?-too$/    && do { $Keep_hc_file_too = 1; next arg; };
     /^-keep-s-files?-too$/     && do { $Keep_s_file_too = 1;  next arg; };
 
-    /^-fhaskell-1\.3$/         && do { $haskell1_version = 3;
-                                       push(@HsP_flags, '-3');
-                                       push(@HsC_flags, $_);
-                                       $TopClosureFile =~ s/TopClosureXXXX/TopClosure13XXXX/;
-                                       unshift(@SysImport_dir,
-                                           $(INSTALLING)
-                                           ? "$InstDataDirGhc/imports/haskell-1.3"
-                                           : "$TopPwd/$(CURRENT_DIR)/$(GHC_LIBSRC)/haskell-1.3");
+    /^-fhaskell-1\.3$/         && do { next arg; }; # a no-op right now
 
-                                       unshift(@SysLibrary, '-lHS13');
+    /^-fignore-interface-pragmas$/ && do { push(@HsC_flags, $_); next arg; };
 
-                                       next arg; };
+    /^-fno-implicit-prelude$/      && do { $NoImplicitPrelude= 1; push(@HsC_flags, $_); next arg; };
 
-    /^-fno-implicit-prelude$/      && do { push(@HsP_flags, '-P'); next arg; };
-    /^-fignore-interface-pragmas$/ && do { push(@HsP_flags, '-p'); next arg; };
+    # ToDo: rename to -fcompiling-ghc-internals=<module>
+    /^-fcompiling-ghc-internals(.*)/   && do { local($m) = &grab_arg_arg('-fcompiling-ghc-internals',$1);
+                                       push(@HsC_flags, "-fcompiling-ghc-internals=$m");
+                                       next arg; };
 
-    /^-prelude$/               && do { $CompilingPrelude = 1;
-                                       push(@HsC_flags, $_); next arg; };
+    /^-fusing-ghc-internals$/ && do { $UsingGhcInternals = 1; next arg; };
 
     /^-user-prelude-force/     && do { # ignore if not -user-prelude
                                        next arg; };
@@ -916,37 +872,36 @@ arg: while($_ = $ARGV[0]) {
                        local($sname) = &grab_arg_arg('-split-objs', $1);
                        $sname =~ s/ //g; # no spaces
 
-                       if ( $TargetPlatform =~ /^(alpha|hppa1\.1|i386|m68k|mips|powerpc|sparc)-/ ) {
+                       if ( $TargetPlatform !~ /^(alpha|hppa1\.1|i386|m68k|mips|powerpc|sparc)-/ ) {
+                           $SplitObjFiles = 0;
+                           print STDERR "WARNING: don't know how to split objects on this platform: $TargetPlatform\n`-split-objs' option ignored\n";
+                       } else {
                            $SplitObjFiles = 1;
-                           $ProduceS = '';
-                           $ProduceC = 1;
+                           $HscOut = '-C=';
 
-                           push(@HsC_flags, "-fglobalise-toplev-names$sname"); 
+                           push(@HsC_flags, "-fglobalise-toplev-names=$sname"); 
                            push(@CcBoth_flags, '-DUSE_SPLIT_MARKERS');
 
                            require('ghc-split.prl')
                             || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-split.prl!\n");
-                       } else {
-                           $SplitObjFiles = 0;
-                           print STDERR "WARNING: don't know how to split objects on this platform: $TargetPlatform\n`-split-objs' option ignored\n";
                        }
                        next arg; };
 
     /^-f(hide-builtin-names|min-builtin-names)$/
                && do { push(@HsC_flags, $_);
-                       push(@HsP_flags, '-P'); # don't read Prelude.hi
-                       push(@HsP_flags, '-N'); # allow foo# names
+#                      push(@HsC_flags, '-fno-implicit-prelude'); # don't read Prelude.hi
+#                      push(@HsP_flags, '-N'); # allow foo# names
                        next arg; };
-    /^-f(glasgow-exts|hide-builtin-instances)$/
+    /^-fglasgow-exts$/
                && do { push(@HsC_flags, $_);
                        push(@HsP_flags, '-N');
 
 #                      push(@HsC_flags, '-fshow-import-specs');
 
-                       if ( ! $(INSTALLING) ) {
-                           unshift(@SysImport_dir,
-                               "$TopPwd/$(CURRENT_DIR)/$(GHC_LIBSRC)/glaExts");
-                       }
+#                      if ( ! $(INSTALLING) ) {
+#                          unshift(@SysImport_dir,
+#                              "$TopPwd/$(CURRENT_DIR)/$(GHC_LIBSRC)/glaExts");
+#                      }
                        next arg; };
 
     /^-fspeciali[sz]e-unboxed$/
@@ -954,18 +909,16 @@ arg: while($_ = $ARGV[0]) {
                        $Oopt_SpecialiseUnboxed = '-fspecialise-unboxed';
                        next arg; };
     /^-fspeciali[sz]e$/
-               && do { $Oopt_DoSpecialise      = '-fspecialise';
-                       next arg; };
+               && do { $Oopt_DoSpecialise = '-fspecialise'; next arg; };
     /^-fno-speciali[sz]e$/
-               && do { $Oopt_DoSpecialise      = '';
-                       next arg; };
+               && do { $Oopt_DoSpecialise = ''; next arg; };
 
 
 # Now the foldr/build options, which are *on* by default (for -O).
 
     /^-ffoldr-build$/
                    && do { $Oopt_FoldrBuild = 1; 
-                           $Oopt_FB_Support = '-fdo-new-occur-anal -fdo-arity-expand';
+                           $Oopt_FB_Support = '-fdo-arity-expand';
                            #print "Yes F/B\n";
                            next arg; };
 
@@ -991,16 +944,10 @@ arg: while($_ = $ARGV[0]) {
 #                  && do { $Oopt_FoldrBuildWW = 1; next arg; };
 
 
-    /^-fasm-(.*)$/  && do { $ProduceS = $1; $ProduceC = 0; # force using nativeGen
-                           push(@HsC_flags, $_); # if from the command line
-                           next arg; };
+    # ---------------
 
-    /^-fvia-C$/            && do { $ProduceS = ''; $ProduceC = 1; # force using C compiler
-                           next arg; };
-
-    /^-f(no-)?omit-frame-pointer$/ && do {
-                           unshift(@CcBoth_flags, ( $_ ));
-                           next arg; };
+    /^-fasm-(.*)$/  && do { $HscOut = '-S='; next arg; }; # force using nativeGen
+    /^-fvia-C$/            && do { $HscOut = '-C='; next arg; }; # force using C compiler
 
     # ---------------
 
@@ -1027,15 +974,12 @@ arg: while($_ = $ARGV[0]) {
                            if ($num < 2 || $num > 8) {
                                die "Bad experimental flag: $_\n";
                            } else {
-                               $ProduceS = ''; $ProduceC = 1; # force using C compiler
+                               $HscOut = '-C='; # force using C compiler
                                push(@HsC_flags, "$what$num");
                                push(@CcRegd_flags, "-D__STG_REGS_AVAIL__=$num");
                            }
                            next arg; };
 
-#    /^-flambda-lift$/ # so Simon can do some testing; ToDo:rm
-#                  && do { $Oopt_LambdaLift = $_; next arg; };
-
     # ---------------
 
     /^-fno-(.*)$/   && do { push(@HsC_antiflags, "-f$1");
@@ -1059,27 +1003,8 @@ arg: while($_ = $ARGV[0]) {
                            $StolenX86Regs = $1;
                            next arg; };
 
-    /^-mtoggle-sp-mangling/ && do { # for iX86 boxes only; for RTS only
-                           print STDERR "$Pgm: warning: -mtoggle-sp-mangling is no longer supported\n";
-#                          $SpX86Mangling = 1 - $SpX86Mangling;
-                           next arg; };
-
     #*************** ... and lots of debugging ones (form: -d* )
 
-    /^-darity-checks$/ && do {
-                           push(@HsC_flags, $_);
-                           push(@CcBoth_flags, '-D__DO_ARITY_CHKS__'); 
-                           next arg; };
-    /^-darity-checks-C-only$/ && do {
-                           # so we'll have arity-checkable .hc files
-                           # should we decide we need them later...
-                           push(@HsC_flags, '-darity-checks');
-                           next arg; };
-    /^-dno-stk-checks$/        && do {
-                           push(@HsC_flags, '-dno-stk-chks');
-                           push(@CcBoth_flags, '-D__OMIT_STK_CHKS__'); 
-                           next arg; };
-
     # -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; };
@@ -1093,9 +1018,6 @@ arg: while($_ = $ARGV[0]) {
 
     #*************** ... and now all these -R* ones for its runtime system...
 
-    /^-Rhbc$/      && do { $RTS_style = 'hbc'; next arg; };
-    /^-Rghc$/      && do { $RTS_style = 'ghc'; next arg; };
-
     /^-Rscale-sizes?(.*)/ && do {
        $Scale_sizes_by = &grab_arg_arg('-Rscale-sizes', $1);
        next arg; };
@@ -1149,11 +1071,6 @@ arg: while($_ = $ARGV[0]) {
     /^-Rghc-timing/ && do { $CollectGhcTimings = 1; next arg; };
 
     #---------- C high-level assembler (gcc) -------------------------------
-# OLD: and dangerous
-#    /^-g$/            && do { push(@CcBoth_flags, $_); next arg; };
-#    /^-(p|pg)$/               && do { push(@CcBoth_flags, $_); push(@Ld_flags, $_); next arg; };
-#    /^-(fpic|fPIC)$/  && do { push(@CcBoth_flags, $_); push(@As_flags, $_); next arg; };
-
     /^-(Wall|ansi|pedantic)$/ && do { push(@CcBoth_flags, $_); next arg; };
 
     # -dgcc-lint is a useful way of making GCC very fussy.
@@ -1176,20 +1093,14 @@ arg: while($_ = $ARGV[0]) {
     #---------- mixed cc and linker magic ----------------------------------
     # this optimisation stuff is finally sorted out later on...
 
-#    /^-O0$/   && do { # turn all optimisation *OFF*
-#              $OptLevel = -1;
-#              $ProduceS = ''; $ProduceC = 1; # force use of C compiler
-#              next arg; };
-
     /^-O2-for-C$/ && do { $MinusO2ForC = 1; next arg; };
 
     /^-O[1-2]?$/ && do {
+#              print STDERR "$Pgm: NOTE: this version of GHC doesn't support -O or -O2\n";
                local($opt_lev) = ( /^-O2$/ ) ? 2 : 1; # max 'em
                $OptLevel = ( $opt_lev > $OptLevel ) ? $opt_lev : $OptLevel;
 
-               if ( $OptLevel == 2 ) { # force use of C compiler
-                   $ProduceS = ''; $ProduceC = 1;
-               }
+               $HscOut = '-C=' if $OptLevel == 2; # force use of C compiler
                next arg; };
 
     /^-Onot$/  && do { $OptLevel = 0; next arg; }; # # set it to <no opt>
@@ -1278,17 +1189,20 @@ if ($Specific_output_dir ne '' && $Specific_output_file ne '') {
 if ( ! $PROFing ) {
     # warn about any scc exprs found (in case scc used as identifier)
     push(@HsP_flags, '-W');
-} else {
-    $Oopt_AddAutoSccs = '-fadd-auto-sccs' if $PROFauto;
-    $Oopt_FinalStgProfilingMassage = '-fmassage-stg-for-profiling';
 
+    # 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;
-#UNUSED:    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 && ! $CompilingPrelude) {
+    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...)
@@ -1366,19 +1280,10 @@ It really really wants to be the last STG-to-STG pass that is run.
 \end{description}
 
 \begin{code}
-# OLD:
-#@HsC_minusO0_flags
-#  = (         $Oopt_AddAutoSccs,
-#      '-fsimplify', # would rather *not* run the simplifier (ToDo)
-#        '\(', '\)', # nothing special at all ????
-#
-#      $Oopt_FinalStgProfilingMassage
-#   );
-
 @HsC_minusNoO_flags
   = (  '-fsimplify',
          '\(',
-         "$Oopt_FB_Support",
+         $Oopt_FB_Support,
 #        '-falways-float-lets-from-lets',      # no idea why this was here (WDP 95/09)
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
@@ -1386,12 +1291,12 @@ It really really wants to be the last STG-to-STG pass that is run.
 #        '-fdo-lambda-eta-expansion',  # too complicated
          '-freuse-con',
 #        '-flet-to-case',      # no strictness analysis, so...
-         "$Oopt_PedanticBottoms",
-#        "$Oopt_MonadEtaExpansion",    # no thanks
+         $Oopt_PedanticBottoms,
+#        $Oopt_MonadEtaExpansion,      # no thanks
          '-fsimpl-uf-use-threshold0',
          '-fessential-unfoldings-only',
-#        "$Oopt_UnfoldingUseThreshold",        # no thanks
-         "$Oopt_MaxSimplifierIterations",
+#        $Oopt_UnfoldingUseThreshold,  # no thanks
+         $Oopt_MaxSimplifierIterations,
          '\)',
        $Oopt_AddAutoSccs,
 #      '-ffull-laziness',      # removed 95/04 WDP following Andr\'e's lead
@@ -1402,19 +1307,17 @@ It really really wants to be the last STG-to-STG pass that is run.
 
 @HsC_minusO_flags # NOTE: used for *both* -O and -O2 (some conditional bits)
   = (
-       # initial simplify: mk specialiser and autoscc happy: minimum effort please
+       # initial simplify: mk specialiser happy: minimum effort please
        '-fsimplify',
          '\(', 
-         "$Oopt_FB_Support",
+         $Oopt_FB_Support,
          '-fkeep-spec-pragma-ids',     # required before specialisation
          '-fsimpl-uf-use-threshold0',
          '-fessential-unfoldings-only',
          '-fmax-simplifier-iterations1',
-         "$Oopt_PedanticBottoms",
+         $Oopt_PedanticBottoms,
          '\)',
 
-       $Oopt_AddAutoSccs,              # need some basic simplification first
-
        ($Oopt_DoSpecialise) ? (
          '-fspecialise-overloaded',
          $Oopt_SpecialiseUnboxed,
@@ -1423,7 +1326,7 @@ It really really wants to be the last STG-to-STG pass that is run.
 
        '-fsimplify',                   # need dependency anal after specialiser ...
          '\(',                         # need tossing before calc-inlinings ...
-         "$Oopt_FB_Support",
+         $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          '-fcase-of-case',
@@ -1431,10 +1334,10 @@ It really really wants to be the last STG-to-STG pass that is run.
          '-fdo-eta-reduction',
          '-fdo-lambda-eta-expansion',
          '-freuse-con',
-         "$Oopt_PedanticBottoms",
-         "$Oopt_MonadEtaExpansion",
-         "$Oopt_UnfoldingUseThreshold",
-         "$Oopt_MaxSimplifierIterations",
+         $Oopt_PedanticBottoms,
+         $Oopt_MonadEtaExpansion,
+         $Oopt_UnfoldingUseThreshold,
+         $Oopt_MaxSimplifierIterations,
          '\)',
 
        '-fcalc-inlinings1',
@@ -1444,7 +1347,7 @@ It really really wants to be the last STG-to-STG pass that is run.
 #              '-ffoldr-build-worker-wrapper',
 #              '-fsimplify', 
 #                '\(', 
-#                "$Oopt_FB_Support",
+#                $Oopt_FB_Support,
 #                '-ffloat-lets-exposing-whnf',
 #                '-ffloat-primops-ok',
 #                '-fcase-of-case',
@@ -1452,10 +1355,10 @@ It really really wants to be the last STG-to-STG pass that is run.
 #                '-fdo-eta-reduction',
 #                '-fdo-lambda-eta-expansion',
 #                '-freuse-con',
-#                "$Oopt_PedanticBottoms",
-#                "$Oopt_MonadEtaExpansion",
-#                "$Oopt_UnfoldingUseThreshold",
-#                "$Oopt_MaxSimplifierIterations",
+#                $Oopt_PedanticBottoms,
+#                $Oopt_MonadEtaExpansion,
+#                $Oopt_UnfoldingUseThreshold,
+#                $Oopt_MaxSimplifierIterations,
 #                '\)',
 #       ) : (),
 
@@ -1470,7 +1373,7 @@ It really really wants to be the last STG-to-STG pass that is run.
            '\(', 
            '-fignore-inline-pragma',   # **** NB!
            '-fdo-foldr-build',         # NB
-           "$Oopt_FB_Support",
+           $Oopt_FB_Support,
            '-ffloat-lets-exposing-whnf',
            '-ffloat-primops-ok',
            '-fcase-of-case',
@@ -1478,10 +1381,10 @@ It really really wants to be the last STG-to-STG pass that is run.
            '-fdo-eta-reduction',
            '-fdo-lambda-eta-expansion',
            '-freuse-con',
-           "$Oopt_PedanticBottoms",
-           "$Oopt_MonadEtaExpansion",
-           "$Oopt_UnfoldingUseThreshold",
-           "$Oopt_MaxSimplifierIterations",
+           $Oopt_PedanticBottoms,
+           $Oopt_MonadEtaExpansion,
+           $Oopt_UnfoldingUseThreshold,
+           $Oopt_MaxSimplifierIterations,
            '\)',
        ) : (),
 
@@ -1489,7 +1392,7 @@ It really really wants to be the last STG-to-STG pass that is run.
 
        '-fsimplify',
          '\(', 
-         "$Oopt_FB_Support",
+         $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          '-fcase-of-case',
@@ -1501,17 +1404,17 @@ It really really wants to be the last STG-to-STG pass that is run.
                        # 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",
+         $Oopt_PedanticBottoms,
+         $Oopt_MonadEtaExpansion,
+         $Oopt_UnfoldingUseThreshold,
+         $Oopt_MaxSimplifierIterations,
          '\)',
 
        '-fstrictness',
 
        '-fsimplify',
          '\(', 
-         "$Oopt_FB_Support",
+         $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          '-fcase-of-case',
@@ -1520,10 +1423,10 @@ It really really wants to be the last STG-to-STG pass that is run.
          '-fdo-lambda-eta-expansion',
          '-freuse-con',
          '-flet-to-case',              # Aha! Only done after strictness analysis
-         "$Oopt_PedanticBottoms",
-         "$Oopt_MonadEtaExpansion",
-         "$Oopt_UnfoldingUseThreshold",
-         "$Oopt_MaxSimplifierIterations",
+         $Oopt_PedanticBottoms,
+         $Oopt_MonadEtaExpansion,
+         $Oopt_UnfoldingUseThreshold,
+         $Oopt_MaxSimplifierIterations,
          '\)',
 
        '-ffloat-inwards',
@@ -1533,13 +1436,13 @@ It really really wants to be the last STG-to-STG pass that is run.
 
 #      ( ($OptLevel != 2)
 #        ? ''
-#      : "-fliberate-case -fsimplify \\( "$Oopt_FB_Support" -ffloat-lets-exposing-whnf -ffloat-primops-ok -fcase-of-case -fdo-case-elim -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 -fdo-eta-reduction -fdo-lambda-eta-expansion -freuse-con -flet-to-case $Oopt_PedanticBottoms $Oopt_MonadEtaExpansion $Oopt_UnfoldingUseThreshold $Oopt_MaxSimplifierIterations \\)" ),
 
 # Final clean-up simplification:
 
        '-fsimplify',
          '\(', 
-         "$Oopt_FB_Support",
+         $Oopt_FB_Support,
          '-ffloat-lets-exposing-whnf',
          '-ffloat-primops-ok',
          '-fcase-of-case',
@@ -1552,10 +1455,10 @@ It really really wants to be the last STG-to-STG pass that is run.
          $Oopt_FoldrBuildInline,       
          ($Oopt_FoldrBuild) ? ('-fdo-foldr-build') : (), 
                        # but still do reductions if you see them!
-         "$Oopt_PedanticBottoms",
-         "$Oopt_MonadEtaExpansion",
-         "$Oopt_UnfoldingUseThreshold",
-         "$Oopt_MaxSimplifierIterations",
+         $Oopt_PedanticBottoms,
+         $Oopt_MonadEtaExpansion,
+         $Oopt_UnfoldingUseThreshold,
+         $Oopt_MaxSimplifierIterations,
          '\)',
 
       #        '-fstatic-args',
@@ -1581,14 +1484,10 @@ It really really wants to be the last STG-to-STG pass that is run.
 Sort out what we're going to do about optimising.  First, the @hsc@
 flags and regular @cc@ flags to worry about:
 \begin{code}
-#if    ( $OptLevel < 0 ) {
-
-#   &add_Hsc_flags( @HsC_minusO0_flags );
-
 if ( $OptLevel <= 0 ) {
 
     # for this level, we tell the parser -fignore-interface-pragmas
-    push(@HsP_flags, '-p');
+    push(@HsC_flags, '-fignore-interface-pragmas');
     # and tell the compiler not to produce them
     push(@HsC_flags, '-fomit-interface-pragmas');
 
@@ -1612,31 +1511,24 @@ if ( $OptLevel <= 0 ) {
 
 %************************************************************************
 %*                                                                     *
-\subsection{Check for registerising, consistency, etc.}
+\subsection{Check for consistency, etc.}
 %*                                                                     *
 %************************************************************************
 
-Are we capable of generating ``registerisable'' C (either using
-C or via equivalent native code)?
-
-\begin{code}
-$RegisteriseC = ( $GccAvailable
-               && $RegisteriseC ne 'no'    # not explicitly *un*set...
-               && ($TargetPlatform =~ /^(alpha|hppa1\.1|i386|m68k|mips|powerpc|sparc)-/)
-               ) ? 'o' : '';
-\end{code}
-
 Sort out @$BuildTag@, @$PROFing@, @$CONCURing@, @$PARing@,
 @$GRANing@, @$TICKYing@:
 \begin{code}
 if ( $BuildTag ne '' ) {
     local($b) = $BuildDescr{$BuildTag};
-    if ($PROFing   eq 'p') { print STDERR "$Pgm: Can't mix $b with profiling.\n"; exit 1; }
     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; }
 
+    # ok to have a user-way profiling build
+    # eval the profiling opts ... but leave user-way BuildTag 
+    if ($PROFing   eq 'p') { eval($EvaldSetupOpts{'_p'}); }
+
 } elsif ( $PROFing eq 'p' ) {
     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; }
@@ -1671,11 +1563,9 @@ if ( $BuildTag ne '' ) {
 \begin{code}
 if ( $BuildTag ne '' ) { # something other than normal sequential...
 
-    push(@HsP_flags, "-g$BuildTag.hi"); # use appropriate Prelude .hi files
+    push(@HsP_flags, "-syshisuffix=$BuildTag.hi"); # use appropriate Prelude .hi files
 
-    $ProduceC = 1; $ProduceS = ''; # must go via C
-
-#    print STDERR "eval...",$EvaldSetupOpts{$BuildTag},"\n";
+    $HscOut = '-C='; # must go via C
 
     eval($EvaldSetupOpts{$BuildTag});
 }
@@ -1684,7 +1574,7 @@ if ( $BuildTag ne '' ) { # something other than normal sequential...
 Decide what the consistency-checking options are in force for this run:
 \begin{code}
 $HsC_consist_options = "${BuildTag},${DEBUGging}";
-$Cc_consist_options  = "${BuildTag},${DEBUGging},${RegisteriseC}";
+$Cc_consist_options  = "${BuildTag},${DEBUGging}";
 \end{code}
 
 %************************************************************************
@@ -1704,28 +1594,24 @@ 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')) if $GccAvailable;
+    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')) if $GccAvailable;
+    unshift(@CcBoth_flags,  ('-static'));
     # We don't put in '-mlong-calls', because it's only
     # needed for very big modules (sigh), and we don't want
     # to hobble ourselves further on all the other modules
     # (most of them).
-    unshift(@CcBoth_flags,  ('-D_HPUX_SOURCE')) if $GccAvailable;
+    unshift(@CcBoth_flags,  ('-D_HPUX_SOURCE'));
         # ___HPUX_SOURCE, not _HPUX_SOURCE, is #defined if -ansi!
         # (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 !~ /linux/;
-       # NB: cannot do required signal magic on Linux for such stk chks */
-
-    unshift(@CcRegd_flags, ('-m486')); # not worth not doing
+    unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK;
 
     # -fno-defer-pop : basically the same game as for m68k
     #
@@ -1737,8 +1623,6 @@ if ($TargetPlatform =~ /^alpha-/) {
     unshift(@CcRegd_flags,    '-fomit-frame-pointer');
     unshift(@CcRegd_flags,    "-DSTOLEN_X86_REGS=$StolenX86Regs");
 
-    unshift(@CcBoth_flags,  ('-static')) if $GccAvailable; # maybe unnecessary???
-
 } elsif ($TargetPlatform =~ /^m68k-/) {
     # we know how to *mangle* asm for m68k
     unshift (@CcRegd_flags, ('-D__STG_REV_TBLS__'));
@@ -1759,6 +1643,12 @@ if ($TargetPlatform =~ /^alpha-/) {
        # maybe gives reg alloc a better time
        # 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__'));
@@ -1769,11 +1659,6 @@ if ($TargetPlatform =~ /^alpha-/) {
     unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__'));
     unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK;
 
-} 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')) if $GccAvailable;
 }
 \end{code}
 
@@ -1783,36 +1668,27 @@ Should really be whether or not we prepend underscores to global symbols,
 not an architecture test.  (JSM)
 
 \begin{code}
+$Under = (   $TargetPlatform =~ /^alpha-/
+         || $TargetPlatform =~ /^hppa/
+         || $TargetPlatform =~ /^mips-sgi-irix/
+         || $TargetPlatform =~ /^powerpc-/
+         || $TargetPlatform =~ /-solaris/
+         || $TargetPlatform =~ /-linux$/
+        )
+        ? '' : '_';
+
 unshift(@Ld_flags,
-    (   $TargetPlatform =~ /^alpha-/
-     || $TargetPlatform =~ /^hppa/
-     || $TargetPlatform =~ /^mips-sgi-irix/
-     || $TargetPlatform =~ /^powerpc-/
-     || $TargetPlatform =~ /-solaris/
-    )
-    ? (($Ld_main) ? (
-        '-u', 'Main_' . $Ld_main . '_closure',
-       ) : (),
-       '-u', 'unsafePerformPrimIO_fast1',
-       '-u', 'Nil_closure',
-       '-u', 'IZh_static_info',
-       '-u', 'False_inregs_info',
-       '-u', 'True_inregs_info',
-       '-u', 'CZh_static_info',
-       '-u', 'DEBUG_REGS') # just for fun, now...
-
-    # nice friendly a.out machines...
-    : (($Ld_main) ? (
-        '-u', '_Main_' . $Ld_main . '_closure',
+      (($Ld_main) ? (
+        '-u', "${Under}Main_" . $Ld_main . '_closure',
        ) : (),
-       '-u', '_unsafePerformPrimIO_fast1',
-       '-u', '_Nil_closure',
-       '-u', '_IZh_static_info',
-       '-u', '_False_inregs_info',
-       '-u', '_True_inregs_info',
-       '-u', '_CZh_static_info',
-       '-u', '_DEBUG_REGS')
-    );
+       '-u', "${Under}GHCbase_unsafePerformPrimIO_fast1",
+       '-u', "${Under}Prelude_Z91Z93_closure", # i.e., []
+       '-u', "${Under}Prelude_IZh_static_info",
+       '-u', "${Under}Prelude_False_inregs_info",
+       '-u', "${Under}Prelude_True_inregs_info",
+       '-u', "${Under}Prelude_CZh_static_info",
+       '-u', "${Under}DEBUG_REGS"))
+       ; # just for fun, now...
 \end{code}
 
 %************************************************************************
@@ -1827,19 +1703,18 @@ Ready for Business.
 
 \begin{code}
 # default includes must be added AFTER option processing
-if ( $(INSTALLING) ) {
+if ( ! $(INSTALLING) ) {
+    push (@Include_dir, "$TopPwd/$(CURRENT_DIR)/$(GHC_INCLUDESRC)");
+} else {
     push (@Include_dir, "$InstLibDirGhc/includes");
     push (@Include_dir, "$InstDataDirGhc/includes");
-    
-} else {
-    push (@Include_dir, "$TopPwd/$(CURRENT_DIR)/$(GHC_INCLUDESRC)");
 }
 \end{code}
 
 \begin{code}
 local($f);
 foreach $f (@SysLibrary) {
-    $f .= "${BuildTag}" if $f =~ /^-lHS/;
+    $f .= $BuildTag if $f =~ /^-lHS/;
 }
 
 # fiddle the TopClosure file name...
@@ -1896,7 +1771,7 @@ Record largest specific heapsize, if any.
 $Specific_heap_size = $Specific_heap_size * $Scale_sizes_by;
 push(@HsC_rts_flags, '-H'.$Specific_heap_size);
 $Specific_stk_size = $Specific_stk_size * $Scale_sizes_by;
-push(@HsC_rts_flags, (($RTS_style eq 'ghc') ? '-K' : '-A').$Specific_stk_size);
+push(@HsC_rts_flags, "-K$Specific_stk_size");
 
 # hack to avoid running hscpp
 $HsCpp = $Cat if ! $Cpp_flag_set;
@@ -1906,15 +1781,19 @@ If no input or link files seen, then we let 'em feed in stdin; this is
 mainly for debugging.
 \begin{code}
 if ($#Input_file < 0 && $#Link_file < 0) {
-    push(@Input_file, '-');
+    @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 $_; }
+    close(INF) || &tidy_up_and_die(1,"Failed writing to $Tmp_prefix.hs\n");
 }
 \end{code}
 
 Tell the world who we are, if they asked.
 \begin{code}
-if ($Verbose) {
-    print STDERR "$(PROJECTNAME), version $(PROJECTVERSION) $(PROJECTPATCHLEVEL)\n";
-}
+print STDERR "$(PROJECTNAME), version $(PROJECTVERSION) $(PROJECTPATCHLEVEL)\n"
+    if $Verbose;
 \end{code}
 
 %************************************************************************
@@ -1940,19 +1819,18 @@ if ( $Status > 0 ) { # don't link if there were errors...
 Link if appropriate.
 \begin{code}
 if ($Do_lnkr) {
-    local($libdirs);
+    local($libdirs) = '';
+
     # glue them together:
     push(@UserLibrary_dir, @SysLibrary_dir);
-    if ($#UserLibrary_dir < 0) {
-       $libdirs = '';
-    } else {
-       $libdirs = '-L' . join(' -L',@UserLibrary_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 : ($RegisteriseC ? $CcRegd : $CcUnregd );
+    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($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');
@@ -1990,7 +1868,7 @@ if ($Do_lnkr) {
        $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');
+       &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");
@@ -2042,7 +1920,7 @@ print STDERR "Exec failed!!!: $SysMan $debug $nprocessors @nonPVM_args\n";
 exit(1); 
 EOSCRIPT2
        close(EXEC) || die "Failed closing $executable\n";
-       chmod 0755, "$executable";
+       chmod 0755, $executable;
     }
 }
 
@@ -2059,452 +1937,383 @@ exit $Status; # will still be 0 if all went well
 
 \begin{code}
 sub ProcessInputFile {
-    local($ifile) = @_;        # input file name
-    local($ifile_root);        # root of or basename of input file
-    local($ifile_root_file); # non-directory part of $ifile_root
+    local($ifile) = @_;          # input file name
+    local($ifile_root);          # root of or basename of input file
+    local($ofile_target); # ultimate output file we hope to produce
+                         # from input file (need to know for recomp
+                         # checking purposes)
+    local($hifile_target);# ditto (but .hi file)
 \end{code}
 
 Handle the weirdity of input from stdin.
 \begin{code}
-    if ($ifile eq '-') {
-       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 $_; }
-       close(INF) || &tidy_up_and_die(1,"Failed writing to $Tmp_prefix.hs\n");
-       $ifile = "$Tmp_prefix.hs";
-       $ifile_root = '_stdin';
-       $ifile_root_file = $ifile_root;
+    if ($ifile ne '-') {
+       ($ifile_root  = $ifile) =~ s/\.[^\.\/]+$//;
+       $ofile_target = # may be reset later...
+                       ($Specific_output_file ne '' && ! $Do_lnkr)
+                       ? $Specific_output_file
+                       : &odir_ify($ifile_root, 'o');
+       $hifile_target= ($Specific_hi_file ne '')
+                       ? $Specific_hi_file
+                       : "$ifile_root.$HiSuffix"; # ToDo: odirify?
+                       # NB: may change if $ifile_root isn't module name (??)
     } else {
-       ($ifile_root = $ifile) =~ s/\.[^\.\/]+$//;
-       ($ifile_root_file = $ifile_root) =~ s|.*/||;
+       $ifile = "$Tmp_prefix.hs"; # we know that's where we put the input
+       $ifile_root   = '_stdin';
+       $ofile_target = '_stdout'; # gratuitous?
+       $hifile_target= '_stdout'; # ditto?
     }
 \end{code}
 
-We now decide what phases of the compilation system we will run over
-this file.  The defaults are the ones established when processing flags.
-(That established what the last phase run for all files is.)
+We need to decide what phases of the compilation system we will run
+over this file.  The defaults are the ones established when processing
+flags.  (That established what the last phase run for all files is.)
 
-The lower-case names are the local ones (as is usual), just for this
-one file.
+We do the pre-recompilation-checker phases here; the rest later.
 \begin{code}
-    local($do_lit2pgm) = $Do_lit2pgm;
-    local($do_hscpp)   = $Do_hscpp;
-    local($do_hsp)     = $Do_hsp;
-    local($do_hsc)     = $Do_hsc;
-    local($do_as)      = $Do_as;
-    local($do_cc)      = ( $Do_cc != -1) # i.e., it was set explicitly
-                         ? $Do_cc
-                         : ( ($ProduceC) ? 1 : 0 );
 \end{code}
 
 Look at the suffix and decide what initial phases of compilation may
 be dropped off for this file.  Also the rather boring business of
 which files are coming-in/going-out.
+
+Again, we'll do the post-recompilation-checker parts of this later.
 \begin{code}
+    local($do_lit2pgm) = ($ifile =~ /\.lhs$/) ? 1 : 0;
+    local($do_hscpp)   = 1; # but "hscpp" might really be "cat"
+    local($do_hsc)     = 1;
+    local($do_cc)      = ( $Do_cc != -1) # i.e., it was set explicitly
+                         ? $Do_cc
+                         : ( ($HscOut eq '-C=') ? 1 : 0 );
+    local($do_as)      = $Do_as;
+
     # names of the files to stuff between phases
     # defaults are temporaries
     local($in_lit2pgm)   = $ifile;
     local($lit2pgm_hscpp) = "$Tmp_prefix.lpp";
-    local($hscpp_hsp)    = "$Tmp_prefix.cpp";
-    local($hsp_hsc)      = "$Tmp_prefix.hsp";
-    local($hsc_cc)       = "$Tmp_prefix.hc";
-
-    # to help C compilers grok .hc files [ToDo: de-hackify]
-    local($cc_help)      = "ghc$$.c";
-    local($cc_help_s)    = "ghc$$.s";
-
-    local($hsc_hi)       = "$Tmp_prefix$HiSuffix";
+    local($hscpp_hsc)    = "$Tmp_prefix.cpp";
+    local($hsc_out)      = ( $HscOut eq '-C=' ) ? "$Tmp_prefix.hc" : "$Tmp_prefix.s" ;
+    local($hsc_hi)       = "$Tmp_prefix.hi";
     local($cc_as_o)      = "${Tmp_prefix}_o.s"; # temporary for raw .s file if opt C
-    local($cc_as)        = "$Tmp_prefix.s";
-    local($as_out)       = ($Specific_output_file ne '' && ! $Do_lnkr)
-                               ? $Specific_output_file
-                               : &odir_ify("${ifile_root}${Osuffix}");
+    local($cc_as)        = "$Tmp_prefix.s";     # mangled or hsc-produced .s code
+    local($as_out)       = $ofile_target;
 
-    local($is_hc_file)   = 1; #Is the C code .hc or .c
+    local($is_hc_file) = 1; #Is the C code .hc or .c? Assume .hc for now
 
     if ($ifile =~ /\.lhs$/) {
-       push(@Link_file, &odir_ify("${ifile_root}${Osuffix}"));
+       ; # nothing to change
     } elsif ($ifile =~ /\.hs$/) {
        $do_lit2pgm = 0;
        $lit2pgm_hscpp = $ifile;
-       push(@Link_file, &odir_ify("${ifile_root}${Osuffix}"));
     } elsif ($ifile =~ /\.hc$/) {
-       $do_lit2pgm = 0; $do_hscpp = 0; $do_hsp = 0; $do_hsc = 0; $do_cc = 1;
-       $hsc_cc = $ifile;    
-       push(@Link_file, &odir_ify("${ifile_root}${Osuffix}"));
+       $do_lit2pgm = 0; $do_hscpp = 0; $do_hsc = 0; $do_cc = 1;
+       $hsc_out = $ifile;    
     } elsif ($ifile =~ /\.c$/) {
-       $do_lit2pgm = 0; $do_hscpp = 0; $do_hsp = 0; $do_hsc = 0; $do_cc = 1;
-       $hsc_cc = $ifile; $is_hc_file = 0;
-       push(@Link_file, &odir_ify("${ifile_root}${Osuffix}"));
+       $do_lit2pgm = 0; $do_hscpp = 0; $do_hsc = 0; $do_cc = 1;
+       $hsc_out = $ifile; $is_hc_file = 0;
     } elsif ($ifile =~ /\.s$/) {
-       $do_lit2pgm = 0; $do_hscpp = 0; $do_hsp = 0; $do_hsc = 0; $do_cc = 0;
+       $do_lit2pgm = 0; $do_hscpp = 0; $do_hsc = 0; $do_cc = 0;
        $cc_as = $ifile;    
-       push(@Link_file, &odir_ify("${ifile_root}${Osuffix}"));
-    } else {
-       if ($ifile !~ /\.a$/) {
-           print STDERR "$Pgm: don't recognise suffix on `$ifile'; passing it through to linker\n";
-       }
-       $do_lit2pgm = 0; $do_hscpp = 0; $do_hsp = 0; $do_hsc = 0; $do_cc = 0; $do_as = 0;
-       push(@Link_file, $ifile);
+    } else { # don't know what it is, but nothing to do herein...
+       $do_lit2pgm = 0; $do_hscpp = 0; $do_hsc = 0; $do_cc = 0; $do_as = 0;
     }
+
+    # OK, have a bash on the first two phases:
+    &runLit2pgm($in_lit2pgm, $lit2pgm_hscpp)
+       if $do_lit2pgm;
+
+    &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>"@.
+not} going to run, set its input (i.e., the output of its preceding
+phase) to @"$ifile_root.<suffix>"@.
 \begin{code}
-    # lit2pgm -- no preceding phase
-    if (! $do_hscpp) {
-       $lit2pgm_hscpp = "$ifile_root.lpp????"; # not done
-    }
-    if (! $do_hsp) {
-       $hscpp_hsp = "$ifile_root.cpp????"; # not done
-    }
-    if (! $do_hsc) {
-       $hsp_hsc = "$ifile_root.hsp????"; # not done
-    }
-    if (! $do_cc) {
-       $hsc_cc = &odir_ify("$ifile_root.hc");
-    }
-    if (! $do_as) {
-       if ($Specific_output_file ne '') {
-           $cc_as  = $Specific_output_file;
-       } else {
-           $cc_as  = &odir_ify(( $Only_preprocess_C ) ? "$ifile_root.i" : "$ifile_root.s");
-       }
-    }
-\end{code}
+    local($going_interactive) = $HscOut eq '-N=' || $ifile_root eq '_stdin';
 
-OK, now do it!  Note that we don't come back from a @run_something@ if
-it fails.
-\begin{code}
-    if ($do_lit2pgm) {
-       local($to_do) = "echo '#line 1 \"$in_lit2pgm\"' > $lit2pgm_hscpp; ".
-                       "$Unlit @Unlit_flags $in_lit2pgm -  >> $lit2pgm_hscpp";
-       @Files_to_tidy = ( $lit2pgm_hscpp );
-       &run_something($to_do, 'literate pre-processor');
-    }
-    if ($do_hscpp) {
-       # ToDo: specific output?
-       if ($HsCpp eq $Cat) {
-           local($to_do) = "echo '#line 1 \"$in_lit2pgm\"' > $hscpp_hsp; ".
-                           "$HsCpp $lit2pgm_hscpp >> $hscpp_hsp";
-           @Files_to_tidy = ( $hscpp_hsp );
-           &run_something($to_do, 'Ineffective C pre-processor');
-       } else {
-           local($includes) = '-I' . join(' -I',@Include_dir);
-           local($to_do) = "echo '#line 1 \"$in_lit2pgm\"' > $hscpp_hsp; ".
-                           "$HsCpp $Verbose $genSPECS_flag @HsCpp_flags -D__HASKELL1__=$haskell1_version -D__GLASGOW_HASKELL__=$ghc_version_info $includes $lit2pgm_hscpp >> $hscpp_hsp";
-           @Files_to_tidy = ( $hscpp_hsp );
-           &run_something($to_do, 'Haskellised C pre-processor');
-       }
-    }
-    if ($do_hsp) {
-       # glue imports onto HsP_flags
-       # if new parser, then put a comma on the front of all of them.
-       local($hsprefix) = ($do_hsp == 2) ? ',' : '';
-
-       foreach $a   ( @HsP_flags  )    { $a = "$hsprefix$a" unless $a =~ /^,/; }
-       foreach $dir ( @Import_dir )    { push(@HsP_flags, "$hsprefix-I$dir"); }
-       foreach $dir ( @SysImport_dir ) { push(@HsP_flags, "$hsprefix-J$dir"); }
+    if (! $do_cc && ! $do_as) { # stopping after hsc
+       $hsc_out = ($Specific_output_file ne '')
+                ? $Specific_output_file
+                : &odir_ify($ifile_root, ($HscOut eq '-C=') ? 'hc' : 's');
+
+       $ofile_target = $hsc_out; # reset
     }
 
-    if ($do_hsp == 1) { # "old" parser
-       local($to_do) = "$HsP $Verbose @HsP_flags $hscpp_hsp > $hsp_hsc";
-       @Files_to_tidy = ( $hsp_hsc );
-       &run_something($to_do, 'Haskell parser');
-       if ($Dump_parser_output) {
-           print STDERR `$Cat $hsp_hsc`;
-       }
-       @HsP_flags = (); # reset!
+    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');
+
+       $ofile_target = $cc_as; # reset
     }
-    if ($do_hsc) {
-       # here, we may produce .hc and/or .hi files
-       local($output)    = '';
-       local($c_source)  = "$ifile_root.hc";
-       local($c_output)  = $hsc_cc;         # defaults
-       local($s_output)  = $cc_as;
-       local($hi_output) = "$ifile_root$HiSuffix";
-       local($going_interactive) = 0;
-
-       if ($Specific_output_file ne '' && ! $do_cc) {
-           $c_source = $c_output = $Specific_output_file;
-           @Files_to_tidy = ( $Specific_output_file ) if $Specific_output_file ne '-';
-       }
-       if ($Specific_hi_file ne '') {
-           # we change the suffix (-hisuf) even if a specific -ohi file:
-           $Specific_hi_file =~ s/\.hi$/$HiSuffix/;
-           $hi_output = $Specific_hi_file;
-           @Files_to_tidy = ( $Specific_hi_file ) if $Specific_hi_file ne '-';
-       }
 
-       if ( ! ($ProduceC || $ProduceS)
-           || $ifile_root eq '_stdin'  # going interactive...
-           || ($c_output eq '-' && $hi_output eq '-')) {
-           $going_interactive = 1;
-#OLD:      $output = '1>&2';   # interactive/debugging, to stderr
-           @Files_to_tidy = ();
-           # don't need .hi (unless magic value "2" says we wanted it anyway):
-           if ( $ProduceHi == 2 ) {
-               $output .= " -hi$hsc_hi";
-               unlink($hsc_hi); # needs to be cleared; will be appended to
-           } else {
-               $ProduceHi = 0;
-           }
-           $do_cc = 0; $do_as = 0; $Do_lnkr = 0; # and we won't go any further...
-       }
+\end{code}
 
-       if ( ! $going_interactive ) {
-           if ( $ProduceHi ) {
-               # we always go to a temp file for these (for later diff'ing)
-               $output = "-hi$hsc_hi";
-               unlink($hsc_hi); # needs to be cleared; will be appended to
-               @Files_to_tidy = ( $hsc_hi );
-           }
-           if ( $ProduceC ) {
-               $output .= " -C$c_output";
-               push(@Files_to_tidy, $c_output);
-
-               open(CFILE, "> $c_output") || &tidy_up_and_die(1,"$Pgm: failed to open `$c_output' (to write)\n");
-               print CFILE "#line 2 \"$c_source\"\n";
-               close(CFILE) || &tidy_up_and_die(1,"Failed writing to $c_output\n");
-               # the "real" C output will then be appended
-           }
-           if ( $ProduceS ) {
-               $output .= " -fasm-$ProduceS -S$s_output";
-               push(@Files_to_tidy, $s_output);
-
-               # ToDo: ummm,... this isn't doing anything (WDP 94/11)
-               open(SFILE, "> $s_output") || &tidy_up_and_die(1,"$Pgm: failed to open `$s_output' (to write)\n");
-               close(SFILE) || &tidy_up_and_die(1,"Failed writing to $s_output\n");
-               # the "real" assembler output will then be appended
-           }
-       }
+Check if hsc needs to be run at all.
 
-       # if we're compiling foo.hs, we want the GC stats to end up in foo.stat
-       if ( $CollectingGCstats ) {
-           if ($RTS_style eq 'hbc') {
-               push(@HsC_rts_flags, '-S'); # puts it in "STAT"
-           } else {
-               push(@HsC_rts_flags, "-S$ifile_root.stat");
-               push(@Files_to_tidy, "$ifile_root.stat");
-           }
-       }
+\begin{code}
+    local($more_processing_required) = 1;
 
-       if ( $CollectGhcTimings ) { # assume $RTS_style eq 'ghc'
-           # emit nofibbish time/bytes-alloc stats to stderr;
-           # see later .stat file post-processing
-           push(@HsC_rts_flags, "-s$Tmp_prefix.stat");
-           push(@Files_to_tidy, "$Tmp_prefix.stat");
-       }
+    if ( $Do_recomp_chkr  && $do_hsc && ! $going_interactive ) {
+       # recompilation-checking is important enough to live off by itself
+       require('ghc-recomp.prl')
+           || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-recomp.prl!\n");
 
-       local($dump);
-       if ($Specific_dump_file ne '') {
-           $dump = "2>> $Specific_dump_file";
-           $Using_dump_file = 1;
-        } else {
-           $dump = '';
-        }
-
-       local($to_do);
-       if ($RTS_style eq 'hbc') {
-           # NB: no parser flags
-           $to_do = "$HsC < $hsp_hsc $dump @HsC_rts_flags - @HsC_flags $CoreLint $Verbose $output";
-       } elsif ($do_hsp == 1) { # old style parser -- no HsP_flags
-           $to_do = "$HsC < $hsp_hsc $dump @HsC_flags $CoreLint $Verbose $output +RTS @HsC_rts_flags";
-       } else { # new style
-           $to_do = "$HsC ,-H @HsP_flags ,$hscpp_hsp $dump @HsC_flags $CoreLint $Verbose $output +RTS @HsC_rts_flags";
-       }
-       &run_something($to_do, 'Haskell compiler');
+       $more_processing_required
+           = &runRecompChkr($ifile, $hscpp_hsc, $ifile_root, $ofile_target, $hifile_target);
 
-       # compensate further for HBC's -S rts opt:
-       if ($CollectingGCstats && $RTS_style eq 'hbc') {
-           unlink("$ifile_root.stat");
-           rename('STAT', "$ifile_root.stat");
-       }
+       print STDERR "$Pgm:recompile: NOT NEEDED!\n" if ! $more_processing_required;
+    }
 
-       # finish business w/ nofibbish time/bytes-alloc stats
-       &process_ghc_timings() if $CollectGhcTimings;
+    $do_hsc = 0, $do_cc = 0, $do_as = 0 if ! $more_processing_required;
+\end{code}
 
-       # if non-interactive, heave in the consistency info at the end
-       # NB: pretty hackish (depends on how $output is set)
-       if ( ! $going_interactive ) {
-           if ( $ProduceC ) {
-           $to_do = "echo 'static char ghc_hsc_ID[] = \"\@(#)hsc $ifile\t$HsC_major_version.$HsC_minor_version,$HsC_consist_options\";' >> $c_output";
-           }
-           if ( $ProduceS ) {
-               local($consist) = "hsc.$ifile.$HsC_major_version.$HsC_minor_version.$HsC_consist_options";
-               $consist =~ s/,/./g;
-               $consist =~ s/\//./g;
-               $consist =~ s/-/_/g;
-               $consist =~ s/[^A-Za-z0-9_.]/ZZ/g; # ToDo: properly?
-               $to_do = "echo '\n\t.text\n$consist:' >> $s_output";
-           }
-           &run_something($to_do, 'Pin on Haskell consistency info');  
-       }
+\begin{code}
+    if ( $do_hsc ) {
+
+       &runHsc($ifile_root, $hsc_out, $hsc_hi, $going_interactive);
 
-       # call the special mangler to produce the .hi/.h(h?) files...
-       &diff_hi_file($hsc_hi, $hi_output)
-               if $ProduceHi == 1 && ! $going_interactive;
-#OLD:  &extract_c_and_hi_files("$Tmp_prefix.hsc", $c_output, $hi_output, $c_source)
+       # 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");
 
-       # if we produced an interface file "no matter what",
-       # print what we got on stderr (ToDo: honor -ohi flag)
-       if ( $ProduceHi == 2 ) {
-           print STDERR `$Cat $hsc_hi`;
-       }
+       &postprocessHiFile($hsc_hi, $hifile_target, $going_interactive);
 
        # save a copy of the .hc file, even if we are carrying on...
-       if ($ProduceC && $do_cc && $Keep_hc_file_too) {
-           local($to_do) = "$(RM) $ifile_root.hc; cp $c_output $ifile_root.hc";
+       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');
        }
 
        # save a copy of the .s file, even if we are carrying on...
-       if ($ProduceS && $do_as && $Keep_s_file_too) {
-           local($to_do) = "$(RM) $ifile_root.s; cp $cc_as $ifile_root.s";
+       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 ( $ProduceC && $SplitObjFiles ) {
-           &inject_split_markers ( $c_output );
+       if ( $HscOut eq '-C=' && $SplitObjFiles ) {
+           &inject_split_markers ( $hsc_out );
        }
     }
+
     if ($do_cc) {
+       &runGcc    ($is_hc_file, $hsc_out, $cc_as_o);
+       &runMangler($is_hc_file, $cc_as_o, $cc_as, $ifile_root);
+    }
+
+    &split_asm_file($cc_as)  if $do_as && $SplitObjFiles;
+
+    &runAs($as_out, $ifile_root) if $do_as;
+\end{code}
+
+Finally, decide what to queue up for linker input.
+\begin{code}
+    # tentatively assume we will eventually produce linker input:
+    push(@Link_file, &odir_ify($ifile_root, 'o'));
+
+    if ($ifile !~ /\.(lhs|hs|hc|c|s)$/) {
+       print STDERR "$Pgm: don't recognise suffix on `$ifile'; passing it through to linker\n"
+           if $ifile !~ /\.a$/;
+
+       # oops; we tentatively pushed the wrong thing; fix & do the right thing
+       pop(@Link_file); push(@Link_file, $ifile);
+    }
+
+} # end of ProcessInputFile
+\end{code}
+
+%************************************************************************
+%*                                                                     *
+\section[Driver-run-phases]{Routines to run the various phases}
+%*                                                                     *
+%************************************************************************
+
+\begin{code}
+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 );
+
+    &run_something($to_do, 'literate pre-processor');
+}
+\end{code}
+
+\begin{code}
+sub runHscpp {
+    local($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc) = @_;
+
+    local($to_do);
+
+    if ($HsCpp eq $Cat) {
+       $to_do = "echo '#line 1 \"$in_lit2pgm\"' > $hscpp_hsc && ".
+                       "$HsCpp $lit2pgm_hscpp >> $hscpp_hsc";
+       @Files_to_tidy = ( $hscpp_hsc );
+       &run_something($to_do, 'Ineffective C pre-processor');
+    } else {
        local($includes) = '-I' . join(' -I',@Include_dir);
-       local($cc);
-       local($s_output);
-       local($c_flags) = "@CcBoth_flags";
-       local($ddebug_flag) = ( $DEBUGging ) ? '-DDEBUG' : '';
-       if ($RegisteriseC) {
-           $cc       = $CcRegd;
-           $s_output = ($is_hc_file || $TargetPlatform =~ /^(hppa|i386)/) ? $cc_as_o : $cc_as;
-           $c_flags .= " @CcRegd_flags";
-           $c_flags .= ($is_hc_file) ? " @CcRegd_flags_hc"  : " @CcRegd_flags_c";
-       } else {
-           $cc       = $CcUnregd;
-           $s_output = $cc_as;
-           $c_flags .= " @CcUnregd_flags";
-           $c_flags .= ($is_hc_file) ? " @CcUnregd_flags_hc" : " @CcUnregd_flags_c";
-       }
-
-       # C compiler won't like the .hc extension.  So we create
-       # a tmp .c file which #include's the needful.
-       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"
-EOINCL
-           # user may have asked for #includes to be injected...
-           print TMP @CcInjects if $#CcInjects >= 0;
-       }
-       # 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";
+       $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 );
+       &run_something($to_do, 'Haskellised C pre-processor');
+    }
+}
+\end{code}
 
-       # and #include the real source
-       print TMP "#include \"$hsc_cc\"\n";
-       close(TMP) || &tidy_up_and_die(1,"Failed writing to $cc_help\n");
+\begin{code}
+sub runHsc {
+    local($ifile_root, $hsc_out, $hsc_hi, $going_interactive) = @_;
 
-       local($to_do) = "$cc $Verbose $ddebug_flag $c_flags @Cpp_define -D__HASKELL1__=$haskell1_version $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!
-           $to_do =~ s/ -S\b//g;
-       }
-       @Files_to_tidy = ( $cc_help, $cc_help_s, $s_output );
-       $PostprocessCcOutput = 1;       # hack, dear hack...
-       &run_something($to_do, 'C compiler');
-       $PostprocessCcOutput = 0;
-       unlink($cc_help, $cc_help_s);
-
-       if ( ($RegisteriseC && $is_hc_file)
-         || $Dump_asm_insn_counts
-         || $Dump_asm_globals_info ) {
-           # dynamically load assembler-fiddling code, which we are about to use
-           local($target) = 'oops';
-           $target = '-alpha'   if $TargetPlatform =~ /^alpha-/;
-           $target = '-hppa'    if $TargetPlatform =~ /^hppa/;
-           $target = ''         if $TargetPlatform =~ /^i386-/;
-           $target = '-m68k'    if $TargetPlatform =~ /^m68k-/;
-           $target = '-mips'    if $TargetPlatform =~ /^mips-/;
-           $target = ''         if $TargetPlatform =~ /^powerpc-/;
-           $target = '-solaris' if $TargetPlatform =~ /^sparc-sun-solaris2/;
-           $target = '-sparc'   if $TargetPlatform =~ /^sparc-sun-sunos4/;
-
-           $target ne 'oops'
-           || &tidy_up_and_die(1,"$Pgm: panic: can't decipher $TargetPlatform!\n");
-           require("ghc-asm$target.prl")
-           || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm$target.prl!\n");
-       }
+    # prepend comma to HsP flags (so hsc can tell them apart...)
+    foreach $a ( @HsP_flags ) { $a = ",$a" unless $a =~ /^,/; }
 
-       if ( $Dump_raw_asm ) { # to stderr, before mangling
-           local($to_pr) = ($RegisteriseC) ? $cc_as_o : $cc_as ;
-           print STDERR `cat $to_pr`;
-       }
+    &makeHiMap() unless $HiMapDone;
+    push(@HsC_flags, "-himap=$HiMapFile");
 
-       if ($RegisteriseC) {
-            if ($is_hc_file) {
-               # post-process the assembler [.hc files only]
-               &mangle_asm($cc_as_o, $cc_as);
-
-           } elsif ($TargetPlatform =~ /^hppa/) {
-               # minor mangling of non-threaded files for hp-pa only
-               require('ghc-asm-hppa.prl')
-               || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm-hppa.prl!\n");
-               &mini_mangle_asm($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($cc_as_o, $cc_as);
-           }
-       }
+    # here, we may produce .hc/.s and/or .hi files
+    local($output) = '';
+    @Files_to_tidy = ();
 
-       # collect interesting (static-use) info
-       &dump_asm_insn_counts($cc_as)  if $Dump_asm_insn_counts;
-       &dump_asm_globals_info($cc_as) if $Dump_asm_globals_info;
+    if ( $going_interactive ) {
+       # don't need .hi unless 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...
+    }
 
-       # 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');
-       }
+    # 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 );
+
+    # if we're compiling foo.hs, we want the GC stats to end up in foo.stat
+    if ( $CollectingGCstats ) {
+       push(@HsC_rts_flags, "-S$ifile_root.stat");
+       push(@Files_to_tidy, "$ifile_root.stat");
     }
 
-    if ($do_as) {
-       # if we're splitting .o files...
-       if ( $SplitObjFiles ) {
-           &split_asm_file ( $cc_as );
-       }
+    if ( $CollectGhcTimings ) { # assume $RTS_style eq 'ghc'
+       # emit nofibbish time/bytes-alloc stats to stderr;
+       # see later .stat file post-processing
+       push(@HsC_rts_flags, "-s$Tmp_prefix.stat");
+       push(@Files_to_tidy, "$Tmp_prefix.stat");
+    }
 
-       local($asmblr) = ( $As ) ? $As : ($RegisteriseC ? $CcRegd : $CcUnregd );
+    local($dump) = '';
+    if ($Specific_dump_file ne '') {
+       $dump = "2>> $Specific_dump_file";
+       $Using_dump_file = 1;
+    }
 
-       if ( ! $SplitObjFiles ) {
-           local($to_do)  = "$asmblr -o $as_out -c @As_flags $cc_as";
-           @Files_to_tidy = ( $as_out );
-           &run_something($to_do, 'Unix assembler');
+    local($to_do);
+    $to_do = "$HsC @HsP_flags ,$hscpp_hsc $dump @HsC_flags $CoreLint $Verbose $output +RTS @HsC_rts_flags";
+    &run_something($to_do, 'Haskell compiler');
+
+    # finish business w/ nofibbish time/bytes-alloc stats
+    &process_ghc_timings() if $CollectGhcTimings;
+
+    # if non-interactive, heave in the consistency info at the end
+    # NB: pretty hackish (depends on how $output is set)
+    if ( ! $going_interactive ) {
+       if ( $HscOut eq '-C=' ) {
+       $to_do = "echo 'static char ghc_hsc_ID[] = \"\@(#)hsc $ifile\t$HsC_major_version.$HsC_minor_version,$HsC_consist_options\";' >> $hsc_out";
+
+       } elsif ( $HscOut eq '-S=' ) {
+           local($consist) = "hsc.$ifile.$HsC_major_version.$HsC_minor_version.$HsC_consist_options";
+           $consist =~ s/,/./g;
+           $consist =~ s/\//./g;
+           $consist =~ s/-/_/g;
+           $consist =~ s/[^A-Za-z0-9_.]/ZZ/g; # ToDo: properly?
+           $to_do = "echo '\n\t.text\n$consist:' >> $hsc_out";
+       }
+       &run_something($to_do, 'Pin on Haskell consistency info');      
+    }
+}
+\end{code}
 
-       } else { # more complicated split-ification...
+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 = '';
 
-           # must assemble files $Tmp_prefix__[1 .. $NoOfSplitFiles].s
+sub makeHiMap {
 
-           for ($f = 1; $f <= $NoOfSplitFiles; $f++ ) {
-               local($split_out) = &odir_ify("${ifile_root}__${f}${Osuffix}");
-               local($to_do) = "$asmblr -o $split_out -c @As_flags ${Tmp_prefix}__${f}.s";
-               @Files_to_tidy = ( $split_out );
+    # collect in %HiMap; write later; also used elsewhere in driver
 
-               &run_something($to_do, 'Unix assembler');
+    local($mod, $path, $d, $e);
+    
+    foreach $d ( @Import_dir ) {
+       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;
+           $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");
     }
-} # end of ProcessInputFile
+
+    foreach $d ( @SysImport_dir ) {
+       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_]*)\.$SysHiSuffix$/o;
+           next if $NoImplicitPrelude && $e =~ /Prelude\.$SysHiSuffix$/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");
+    }
+
+    $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");
+
+    $HiMapDone = 1;
+}
+
+sub already_mapped_err {
+    local($mod, $mapped_to, $path) = @_;
+
+    # 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);
+
+    return if $m_ino == $p_ino; # same inode number
+
+    print STDERR "$Pgm: module $mod already mapped to $mapped_to (inode $m_ino)";
+    print STDERR ";\n\tignoring: $path (inode $p_ino)\n";
+}
 \end{code}
 
 %************************************************************************
@@ -2520,14 +2329,157 @@ EOINCL
 %************************************************************************
 
 \begin{code}
+sub osuf_ify {
+    local($ofile,$def_suffix) = @_;
+
+    return(($Osuffix eq '') ? "$ofile.$def_suffix" : "$ofile.$Osuffix" );
+}
+
 sub odir_ify {
-    local($orig_file) = @_;
+    local($orig_file, $def_suffix) = @_;
     if ($Specific_output_dir eq '') {   # do nothing
-       return($orig_file);
+       &osuf_ify($orig_file, $def_suffix);
     } else {
        local ($orig_file_only);
        ($orig_file_only = $orig_file) =~ s|.*/||;
-       return("$Specific_output_dir/$orig_file_only");
+       &osuf_ify("$Specific_output_dir/$orig_file_only",$def_suffix);
+    }
+}
+\end{code}
+
+\begin{code}
+sub runGcc {
+    local($is_hc_file, $hsc_out, $cc_as_o) = @_;
+
+    local($includes) = '-I' . join(' -I', @Include_dir);
+    local($cc);
+    local($s_output);
+    local($c_flags) = "@CcBoth_flags";
+    local($ddebug_flag) = ( $DEBUGging ) ? '-DDEBUG' : '';
+
+    # "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;
+    $c_flags .= " @CcRegd_flags";
+    $c_flags .= ($is_hc_file) ? " @CcRegd_flags_hc"  : " @CcRegd_flags_c";
+
+    # C compiler won't like the .hc extension.  So we create
+    # a tmp .c file which #include's the needful.
+    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"
+EOINCL
+       # user may have asked for #includes to be injected...
+       print TMP @CcInjects if $#CcInjects >= 0;
+    }
+    # 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!
+       $to_do =~ s/ -S\b//g;
+    }
+    @Files_to_tidy = ( $cc_help, $cc_help_s, $s_output );
+    $PostprocessCcOutput = 1;  # hack, dear hack...
+    &run_something($to_do, 'C compiler');
+    $PostprocessCcOutput = 0;
+    unlink($cc_help, $cc_help_s);
+}
+\end{code}
+
+\begin{code}
+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) {
+       # post-process the assembler [.hc files only]
+       &mangle_asm($cc_as_o, $cc_as);
+
+#OLD: for sanity:
+       local($target) = 'oops';
+       $target = '-alpha'      if $TargetPlatform =~ /^alpha-/;
+       $target = '-hppa'       if $TargetPlatform =~ /^hppa/;
+       $target = ''            if $TargetPlatform =~ /^i386-/;
+       $target = '-m68k'       if $TargetPlatform =~ /^m68k-/;
+       $target = '-mips'       if $TargetPlatform =~ /^mips-/;
+       $target = ''            if $TargetPlatform =~ /^powerpc-/;
+       $target = '-solaris'    if $TargetPlatform =~ /^sparc-sun-solaris2/;
+       $target = '-sparc'      if $TargetPlatform =~ /^sparc-sun-sunos4/;
+
+       if ( $target ne '' ) {
+           require("ghc-asm$target.prl")
+           || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm$target.prl!\n");
+           &mangle_asm($cc_as_o, "$cc_as-2"); # the OLD one!
+           &run_something("$Cmp -s $cc_as-2 $cc_as || $Diff $cc_as-2 $cc_as 1>&2 || exit 0",
+               "Diff'ing old and new mangled .s files"); # NB: to stderr
+       }
+
+    } 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
+       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...
+    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');
+    }
+}
+\end{code}
+
+\begin{code}
+sub runAs {
+    local($as_out, $ifile_root) = @_;
+
+    local($asmblr) = ( $As ) ? $As : $CcRegd;
+
+    if ( ! $SplitObjFiles ) {
+       local($to_do)  = "$asmblr -o $as_out -c @As_flags $cc_as";
+       @Files_to_tidy = ( $as_out );
+       &run_something($to_do, 'Unix assembler');
+
+    } else { # more complicated split-ification...
+
+       # must assemble files $Tmp_prefix__[1 .. $NoOfSplitFiles].s
+
+       for ($f = 1; $f <= $NoOfSplitFiles; $f++ ) {
+           local($split_out) = &odir_ify("${ifile_root}__${f}",'o');
+           local($to_do) = "$asmblr -o $split_out -c @As_flags ${Tmp_prefix}__${f}.s";
+           @Files_to_tidy = ( $split_out );
+
+           &run_something($to_do, 'Unix assembler');
+       }
     }
 }
 \end{code}
@@ -2592,60 +2544,6 @@ sub run_something {
 
 %************************************************************************
 %*                                                                     *
-\subsection[Driver-demangle-C-and-hi]{@extract_c_and_hi_files@: Unscramble Haskell-compiler output}
-%*                                                                     *
-%************************************************************************
-
-Update interface if the tmp one is newer...
-We first have to fish the module name out of the interface.
-\begin{code}
-sub diff_hi_file {
-    local($tmp_hi_file, $hi_file) = @_;
-    local($if_modulename) = '';
-
-    # extract the module name
-
-    open(TMP,   "< $tmp_hi_file")|| &tidy_up_and_die(1,"$Pgm: failed to open `$tmp_hi_file' (to read)\n");
-    while (<TMP>) {
-       if ( /^interface ([A-Za-z0-9'_]+) / ) {
-           $if_modulename = $1;
-       }
-    }
-    close(TMP) || &tidy_up_and_die(1,"Failed reading from $tmp_hi_file\n");
-    &tidy_up_and_die(1,"No module name in $tmp_hi_file\n")
-       if ! $if_modulename;
-
-    #compare/diff with old one
-
-    if ($hi_file eq '-') {
-       &run_something("cat $tmp_hi_file", "copy interface to stdout");
-
-    } else {
-       if ($Specific_hi_file eq '' && $if_modulename ne '') {
-           if ( $hi_file =~ /\// ) {
-                $hi_file =~ s/\/[^\/]+$//;
-                $hi_file .= "/$if_modulename$HiSuffix";
-           } else {
-               $hi_file = "$if_modulename$HiSuffix";
-           }
-           print STDERR "interface really going into: $hi_file\n" if $Verbose;
-       }
-
-       if ($HiDiff_flag && -f $hi_file) {
-           local($diffcmd) = '$(CONTEXT_DIFF)';
-
-           &run_something("cmp -s $tmp_hi_file $hi_file || $(CONTEXT_DIFF) $hi_file $tmp_hi_file 1>&2 || exit 0",
-               "Diff'ing old and new $HiSuffix files"); # NB: to stderr
-       }
-
-       &run_something("cmp -s $tmp_hi_file $hi_file || ( $(RM) $hi_file && $(CP) $tmp_hi_file $hi_file )",
-                      "Comparing old and new $HiSuffix files");
-    }
-}
-\end{code}
-
-%************************************************************************
-%*                                                                     *
 \subsection[Driver-ghctiming]{Emit nofibbish GHC timings}
 %*                                                                     *
 %************************************************************************
@@ -2728,7 +2626,7 @@ sub process_ghc_timings {
 
 \begin{code}
 sub tidy_up {
-    local($to_do) = "\n$(RM) $Tmp_prefix*";
+    local($to_do) = "\n$Rm $Tmp_prefix*";
     if ( $Tmp_prefix !~ /^\s*$/ ) {
        print STDERR "$to_do\n" if $Verbose;
        system($to_do);
@@ -2812,3 +2710,4 @@ sub add_Hsc_flags {
     }
 }
 \end{code}
+
index db8516d..458c93c 100644 (file)
@@ -254,7 +254,8 @@ register void *_procedure __asm__("$27");
 \begin{code}
 #if i386_TARGET_ARCH
 
-#ifdef solaris2_TARGET_OS
+/* *not* a good way to do this (WDP 96/05) */
+#if defined(solaris2_TARGET_OS) || defined(linux_TARGET_OS)
 #define MINI_INTERPRET_END   "miniInterpretEnd"
 #else
 #define MINI_INTERPRET_END   "_miniInterpretEnd"
index da57a40..4334cae 100644 (file)
@@ -69,9 +69,23 @@ but unfortunately, we have to cater to ANSI C as well.)
     do {SaveAllStgRegs(); PerformGC(args); RestoreAllStgRegs();} while(0)
 #define DO_STACKOVERFLOW(headroom,args)            \
     do {SaveAllStgRegs(); StackOverflow(headroom,args); RestoreAllStgRegs();} while(0)
+
+#if defined(GRAN)
+
+#define DO_YIELD(args)   DO_GRAN_YIELD(args)
+#define DO_GRAN_YIELD(liveness)                    \
+    do {SaveAllStgRegs(); Yield(liveness); RestoreAllStgRegs();} while(0)
+
+#define DO_PERFORM_RESCHEDULE(liveness_mask,reenter)               \
+    do {SaveAllStgRegs(); PerformReschedule(liveness_mask,reenter); RestoreAllStgRegs();} while(0)
+
+#else
+
 #define DO_YIELD(args)             \
     do {SaveAllStgRegs(); Yield(args); RestoreAllStgRegs();} while(0)
 
+#endif   /* GRAN */
+
 \end{code}
 
 %************************************************************************
@@ -168,12 +182,35 @@ extern void callWrapper_safe(STG_NO_ARGS);
 void PerformGC_wrapper PROTO((W_));
 void StackOverflow_wrapper PROTO((W_, W_));
 void Yield_wrapper PROTO((W_));
+#  ifdef GRAN
+void PerformReschedule_wrapper PROTO((W_, W_));
+void GranSimAllocate_wrapper PROTO((I_, P_, W_));
+void GranSimUnallocate_wrapper PROTO((I_, P_, W_));
+void GranSimFetch_wrapper PROTO((P_));
+void GranSimExec_wrapper PROTO((W_, W_, W_, W_, W_));
+#  endif
 #endif
 
 #define DO_GC(args)                    PerformGC_wrapper(args)
 #define DO_STACKOVERFLOW(headroom,args) StackOverflow_wrapper(headroom,args)
+
+#  ifdef GRAN
+
+#define DO_YIELD(args)   DO_GRAN_YIELD(args)
+#define DO_GRAN_YIELD(liveness)                        Yield_wrapper(liveness)
+
+#define DO_PERFORMRESCHEDULE(liveness, always_reenter_node) PerformReschedule_wrapper(liveness, always_reenter_node)
+#define DO_GRANSIMALLOCATE(n, node, liveness)   GranSimAllocate_wrapper(n, node, liveness)
+#define DO_GRANSIMUNALLOCATE(n, node, liveness) GranSimUnallocate_wrapper(n, node, liveness)
+#define DO_GRANSIMFETCH(node)                   GranSimFetch_wrapper(node)
+#define DO_GRANSIMEXEC(arith,branch,load,store,floats) GranSimExec_wrapper(arith,branch,load,store,floats)
+
+#  else
+
 #define DO_YIELD(args)                 Yield_wrapper(args)
 
+#  endif
+
 #endif /* __GNUC__ && __STG_GCC_REGS__ */
 \end{code}
 
@@ -377,7 +414,7 @@ gets whatever it's after.
 
 #define WRAPPER_NAME(f) /*nothing*/
 
-#ifdef solaris2_TARGET_OS
+#if defined(solaris2_TARGET_OS) || defined(linux_TARGET_OS)
 #define REAL_NAME(f)   #f
 #else
 #define REAL_NAME(f)   "_" #f
@@ -566,7 +603,6 @@ gets whatever it's after.
 %************************************************************************
 
 \begin{code}
-
 #if sparc_TARGET_ARCH
 
 #define MAGIC_CALL_SETUP       \
@@ -577,6 +613,11 @@ gets whatever it's after.
        "\tstd %i2,[%fp-32]\n"  \
        "\tstd %i4,[%fp-24]");
 
+/* We leave nothing to chance here; we have seen
+   GCC stick "unwanted" code in the branch delay
+   slot, causing mischief (WDP 96/05)
+*/
+#ifdef GRAN
 #define MAGIC_CALL             \
     __asm__ volatile (         \
         "ld [%%fp-40],%%o5\n"  \
@@ -590,6 +631,21 @@ gets whatever it's after.
     __asm__ volatile (         \
        "std %f0,[%fp-40]\n"    \
        "\tstd %o0,[%fp-32]");
+#else
+#define MAGIC_CALL             \
+    __asm__ volatile (         \
+        "ld [%%fp-40],%%o5\n"  \
+       "\tld [%%fp-36],%%o0\n" \
+       "\tld [%%fp-32],%%o1\n" \
+       "\tld [%%fp-28],%%o2\n" \
+       "\tld [%%fp-24],%%o3\n" \
+       "\tld [%%fp-20],%%o4\n" \
+       "\tcall %%o5\n"         \
+       "\tnop\n"               \
+       "\tstd %%f0,[%%fp-40]\n"\
+       "\tstd %%o0,[%%fp-32]"  \
+       : : : "%o0", "%o1", "%o2", "%o3", "%o4", "%o5", "%f0", "%g1", "%g2", "%g3", "%g4", "memory");
+#endif
 
 #define MAGIC_RETURN           \
     __asm__ volatile (         \
index ed1fe26..79c4272 100644 (file)
@@ -44,19 +44,19 @@ The compiler declares a static block for each @_scc_@ annotation in the
 source using the @CC_DECLARE@ macro where @label@, @module@ and
 @group@ are strings and @ident@ the cost centre identifier.
 
-\begin{code}
-# define CC_IS_CAF  'C'
-# define CC_IS_DICT 'D'
+\begin{code} 
+# define CC_IS_CAF      'c'
+# define CC_IS_DICT     'd'
 # define CC_IS_SUBSUMED 'S'
-# define CC_IS_BORING '\0'
+# define CC_IS_BORING   'B'
 
 # define STATIC_CC_REF(cc_ident) &CAT2(cc_ident,_struct)
 # define DYN_CC_REF(cc_ident)    cc_ident /* unused */
 
-# define CC_DECLARE(cc_ident,name,module,group,subsumed,is_local) \
-     is_local struct cc CAT2(cc_ident,_struct)                 \
-       = {NOT_REGISTERED, UNHASHED, name, module, group,       \
-          subsumed, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};       \
+# define CC_DECLARE(cc_ident,name,module,group,subsumed,is_local)      \
+     is_local struct cc CAT2(cc_ident,_struct)                         \
+       = {NOT_REGISTERED, UNHASHED, name, module, group,               \
+          subsumed, INIT_CC_STATS};                                    \
      is_local CostCentre cc_ident = STATIC_CC_REF(cc_ident)
 
 #endif /* defined(PROFILING) || defined(CONCURRENT) */
@@ -96,7 +96,9 @@ turn on @PROFILING@.  Get them out of the way....
 # define SET_CC_HDR(closure, cc)       /* Dont set CC header */
 # define SET_STATIC_CC_HDR(cc)         /* No static CC header */
 
-# define SET_CCC(cc_ident,is_dupd)
+# define SET_CCC(cc_ident,do_scc_count)
+# define SET_DICT_CCC(cc_ident,do_scc_count)
+# define SET_CCC_RTS(cc_ident,do_sub_count,do_count)
 
 # define RESTORE_CCC(cc)
 
@@ -104,6 +106,9 @@ turn on @PROFILING@.  Get them out of the way....
 # define ENTER_CC_TCL(closure)
 # define ENTER_CC_F(cc)
 # define ENTER_CC_FCL(closure)
+# define ENTER_CC_FSUB()
+# define ENTER_CC_FCAF(cc)
+# define ENTER_CC_FLOAD(cc)
 # define ENTER_CC_PAP(cc)
 # define ENTER_CC_PAP_CL(closure)
 
@@ -152,7 +157,7 @@ CC_EXTERN(CC_CAFs);         /* prelude cost centre (CAFs  only) */
 CC_EXTERN(CC_DICTs);           /* prelude cost centre (DICTs only) */
 
 # define IS_CAF_OR_DICT_CC(cc) \
-    (((cc)->is_subsumed == CC_IS_CAF) || ((cc)->is_subsumed == CC_IS_DICT))
+    ((cc)->is_subsumed & ' ')  /* tests for lower case character */
 
 # define IS_SUBSUMED_CC(cc) ((cc)->is_subsumed == CC_IS_SUBSUMED)
 
@@ -200,14 +205,23 @@ not count the entry to avoid large counts arising from simple
 recursion.  (Huh?  WDP 94/07)
 
 \begin{code}
-# define SET_CCC_X(cc,is_dupd)                                                 \
-       do {                                                                    \
-       if (!(is_dupd)) { CCC->sub_scc_count++; } /* inc subcc count of CCC */  \
-       CCC = (CostCentre)(cc);         /* set CCC to ident cc */               \
-       if (!(is_dupd)) { CCC->scc_count++; }    /* inc scc count of new CCC*/  \
+# define SET_CCC_X(cc,do_subcc_count,do_subdict_count,do_scc_count)                            \
+       do {                                                                                    \
+       if ((do_subcc_count)) { CCC->sub_scc_count++; }       /* inc subcc count of CCC */      \
+       if ((do_subdict_count)) { CCC->sub_dictcc_count++; }  /* inc sub dict count of CCC */   \
+       CCC = (CostCentre)(cc);                               /* set CCC to ident cc */         \
+       ASSERT_IS_REGISTERED(CCC,1);                                                            \
+       if ((do_scc_count)) { CCC->scc_count++; }             /* inc scc count of new CCC*/     \
        } while(0)
 
-# define SET_CCC(cc_ident,is_dupd) SET_CCC_X(STATIC_CC_REF(cc_ident),is_dupd)
+# define SET_CCC(cc_ident,do_scc_count) \
+        SET_CCC_X(STATIC_CC_REF(cc_ident),do_scc_count,0,do_scc_count)
+
+# define SET_DICT_CCC(cc_ident,do_scc_count) \
+        SET_CCC_X(STATIC_CC_REF(cc_ident),0,do_scc_count,do_scc_count)
+
+# define SET_CCC_RTS(cc_ident,do_sub_count,do_scc_count) \
+        SET_CCC_X(STATIC_CC_REF(cc_ident),do_sub_count,0,do_scc_count)
 \end{code}
 
 We have this @RESTORE_CCC@ macro, rather than just an assignment,
@@ -225,9 +239,9 @@ On entry to top level CAFs we count the scc ...
 # define ENTER_CC_CAF_X(cc)                                            \
        do {                                                            \
        CCC->sub_cafcc_count++; /* inc subcaf count of CCC */           \
-       CCC = (CostCentre)(cc);         /* set CCC to ident cc */       \
+       CCC = (CostCentre)(cc); /* set CCC to ident cc */               \
        ASSERT_IS_REGISTERED(CCC,1);                                    \
-       CCC->cafcc_count++; /* inc cafcc count of CCC */                \
+       CCC->scc_count++;       /* inc scc count of CAF cc */           \
        } while(0)
 
 # define ENTER_CC_CAF(cc_ident)   ENTER_CC_CAF_X(STATIC_CC_REF(cc_ident))
@@ -236,14 +250,14 @@ On entry to top level CAFs we count the scc ...
 
 On entering a closure we only count the enter to thunks ...
 \begin{code}
-# define ENTER_CC_T(cc)                                                \
-       do {                                                    \
-       CCC = (CostCentre)(cc);                                 \
-       ASSERT_IS_REGISTERED(CCC,1);                            \
-       CCC->thunk_count++; /* inc thunk count of new CCC */    \
+# define ENTER_CC_T(cc)                                        \
+       do {                                            \
+       CCC = (CostCentre)(cc);                         \
+       ASSERT_IS_REGISTERED(CCC,1);                    \
+       CCC_DETAIL_COUNT(CCC->thunk_count);             \
        } while(0)      
 
-# define ENTER_CC_TCL(closure)                                 \
+# define ENTER_CC_TCL(closure)                         \
        ENTER_CC_T(CC_HDR(closure))
 
 /* Here is our special "hybrid" case when we do *not* set the CCC.
@@ -256,13 +270,38 @@ On entering a closure we only count the enter to thunks ...
        ASSERT_IS_REGISTERED(cc,1);                     \
        if ( ! IS_CAF_OR_DICT_CC(cc) ) {                \
            CCC = cc;                                   \
+       } else {                                        \
+           CCC_DETAIL_COUNT(cc->caffun_subsumed);      \
+           CCC_DETAIL_COUNT(CCC->subsumed_caf_count);  \
        }                                               \
-       CCC->function_count++;                          \
+       CCC_DETAIL_COUNT(CCC->function_count);          \
        } while(0)
 
 # define ENTER_CC_FCL(closure)                         \
        ENTER_CC_F(CC_HDR(closure))
 
+# define ENTER_CC_FSUB()                               \
+       do {                                            \
+       CCC_DETAIL_COUNT(CCC->subsumed_fun_count);      \
+       CCC_DETAIL_COUNT(CCC->function_count);          \
+       } while(0)
+
+# define ENTER_CC_FCAF(centre)                         \
+       do {                                            \
+       CostCentre cc = (CostCentre) (centre);          \
+       ASSERT_IS_REGISTERED(cc,1);                     \
+       CCC_DETAIL_COUNT(cc->caffun_subsumed);          \
+       CCC_DETAIL_COUNT(CCC->subsumed_caf_count);      \
+       CCC_DETAIL_COUNT(CCC->function_count);          \
+       } while(0)
+
+# define ENTER_CC_FLOAD(cc)                            \
+       do {                                            \
+       CCC = (CostCentre)(cc);                         \
+       ASSERT_IS_REGISTERED(CCC,1);                    \
+       CCC_DETAIL_COUNT(CCC->function_count);          \
+       } while(0)
+
 /* These ENTER_CC_PAP things are only used in the RTS */
 
 # define ENTER_CC_PAP(centre)                          \
@@ -271,13 +310,22 @@ On entering a closure we only count the enter to thunks ...
        ASSERT_IS_REGISTERED(cc,1);                     \
        if ( ! IS_CAF_OR_DICT_CC(cc) ) {                \
            CCC = cc;                                   \
+       } else {                                        \
+           CCC_DETAIL_COUNT(cc->caffun_subsumed);      \
+           CCC_DETAIL_COUNT(CCC->subsumed_caf_count);  \
        }                                               \
-       CCC->pap_count++;                               \
+       CCC_DETAIL_COUNT(CCC->pap_count);               \
        } while(0)                      
                                        
 # define ENTER_CC_PAP_CL(closure)                      \
        ENTER_CC_PAP(CC_HDR(closure))
 
+# if defined(PROFILING_DETAIL_COUNTS)
+# define CCC_DETAIL_COUNT(inc_this) ((inc_this)++)
+# else
+# define CCC_DETAIL_COUNT(inc_this) /*nothing*/
+# endif
+
 #endif /* PROFILING */
 \end{code}
 
@@ -357,7 +405,7 @@ We don't want to attribute costs to an unregistered cost-centre:
 # define ASSERT_IS_REGISTERED(cc,chk_not_overhead) /*nothing*/
 #else
 # define ASSERT_IS_REGISTERED(cc,chk_not_overhead)                             \
-       do {                                                                    \
+       do {    /* beware of cc name-capture */                                 \
        CostCentre c_c = (CostCentre) (cc);                                     \
        if (c_c->registered == NOT_REGISTERED) {                                \
            fprintf(stderr,"Entering unregistered CC: %s\n",c_c->label);        \
@@ -398,6 +446,8 @@ reuse @CON_K@ (or something) in runtime/main/StgStartup.lhc.
 Similarily, the SP stuff should probably be the highly uninformative
 @INTERNAL_KIND@.
 
+SOF 4/96: Renamed MallocPtr_K to ForeignObj_K 
+
 \begin{code}
 #if defined(PROFILING)
 
@@ -409,7 +459,7 @@ Similarily, the SP stuff should probably be the highly uninformative
 # define ARR_K         6
 
 # ifndef PAR
-#  define MallocPtr_K  7  /* Malloc Pointer */
+#  define ForeignObj_K 7  /* Malloc Pointer */
 #  define SPT_K                8  /* Stable Pointer Table */
 # endif /* !PAR */
 
@@ -569,19 +619,19 @@ extern hash_t index_type PROTO((ClCategory clcat));
 memory alloc macros.
 
 \begin{code}
-# define CC_TICK(cc)                                                   \
-       do { CostCentre centre = (CostCentre) (cc);                     \
-       ASSERT_IS_REGISTERED(centre,1);                                 \
-       centre->time_ticks += 1;                                        \
+# define CC_TICK(centre)                                               \
+       do { CostCentre cc = (CostCentre) (centre);                     \
+       ASSERT_IS_REGISTERED(cc,1);                                     \
+       cc->time_ticks += 1;                                            \
        } while(0)
 
 # if defined(PROFILING)
-#  define CC_ALLOC(cc, size, kind)                                     \
-       do { CostCentre cc_ = (CostCentre) (cc);                        \
-       ASSERT_IS_REGISTERED(cc_,0/*OK if OVERHEAD*/);                  \
-       cc_->mem_allocs += 1;                                           \
-       cc_->mem_alloc  += (size) - (PROF_FIXED_HDR + TICKY_FIXED_HDR); \
-       } while(0) /* beware name-capture by ASSERT_IS...! */
+# define CC_ALLOC(centre, size, kind)                                  \
+       do { CostCentre cc = (CostCentre) (centre);                     \
+       ASSERT_IS_REGISTERED(cc,0/*OK if OVERHEAD*/);                   \
+       CCC_DETAIL_COUNT(cc->mem_allocs);                               \
+       cc->mem_alloc += (size) - (PROF_FIXED_HDR + TICKY_FIXED_HDR);   \
+       } while(0) 
 # endif
 \end{code}
 
@@ -610,13 +660,7 @@ rtsBool cc_to_ignore PROTO((CostCentre));
 \begin{code}
 # if defined(PROFILING)
 
-extern I_ heap_profile_init PROTO((char *select_cc_str,
-                                  char *select_mod_str,
-                                  char *select_grp_str,
-                                  char *select_descr_str,
-                                  char *select_typ_str,
-                                  char *select_kind_str,
-                                  char *argv[]));
+I_ heap_profile_init PROTO((char *argv[]));
 
 extern void heap_profile_finish(STG_NO_ARGS);
 
@@ -628,8 +672,11 @@ extern void (* heap_profile_fn) PROTO((P_ closure,I_ size));
 extern I_ earlier_ticks;               /* no. of earlier ticks grouped */
 extern hash_t time_intervals;          /* no. of time intervals reported -- 18 */
 
-#  define HEAP_PROFILE_CLOSURE(closure,size) \
-       STGCALL2(void,(void *, P_, I_),(*heap_profile_fn),closure,size)                 /*R SM2s.lh */
+# define HEAP_PROFILE_CLOSURE(closure,size)    \
+       do {                                    \
+       if (heap_profile_fn) {                  \
+           STGCALL2(void,(void *, P_, I_),(*heap_profile_fn),closure,size); \
+       }} while(0)
 
 # endif        /* PROFILING */
 \end{code}
index eea0b24..e2da0d1 100644 (file)
 %*                                                                     *
 %************************************************************************
 
+Dummy definitions if we are not compiling for GrAnSim.
+
+\begin{code}
+#ifndef GRAN 
+#define GRAN_ALLOC_HEAP(n,liveness)                    /* nothing */
+#define GRAN_UNALLOC_HEAP(n,liveness)                  /* nothing */
+#define GRAN_FETCH()                                   /* nothing */
+#define GRAN_FETCH_AND_RESCHEDULE(liveness)            /* nothing */
+#define GRAN_RESCHEDULE(liveness, reenter)             /* nothing */
+#define GRAN_EXEC(arith,branch,loads,stores,floats)    /* nothing */
+#define GRAN_SPARK()                                   /* nothing */
+#endif
+\end{code}
+
+First the basic types specific to GrAnSim.
+
 \begin{code}
-#ifdef GRAN
-
-#  define IS_IDLE(proc)        ((IdleProcs & PE_NUMBER((long)proc)) != 0l)
-#  define ANY_IDLE     (Idlers > 0)
-#  define MAKE_IDLE(proc) do { if(!IS_IDLE(proc)) { ++Idlers; IdleProcs |= PE_NUMBER(proc);  } } while(0)
-#  define MAKE_BUSY(proc) do { if(IS_IDLE(proc))  { --Idlers; IdleProcs &= ~PE_NUMBER(proc); } } while(0)
-
-/* Event Types */
-#  define STARTTHREAD     0    /* Start a newly created thread */
-#  define CONTINUETHREAD  1     /* Continue running the first thread in the queue */
-#  define RESUMETHREAD    2     /* Resume a previously running thread */
-#  define MOVESPARK       3     /* Move a spark from one PE to another */
-#  define MOVETHREAD      4     /* Move a thread from one PE to another */
-#  define FINDWORK        5     /* Search for work */
-#  define FETCHNODE       6     /* Fetch a node */
-#  define FETCHREPLY      7     /* Receive a node */
-
-#  define EVENT_PROC(evt)      (evt->proc)
-#  define EVENT_CREATOR(evt)   (evt->creator)
-#  define EVENT_TIME(evt)      (evt->time)
-#  define EVENT_TYPE(evt)      (evt->evttype)
-#  define EVENT_TSO(evt)       (evt->tso)
-#  define EVENT_NODE(evt)      (evt->node)
-#  define EVENT_SPARK(evt)     (evt->spark)
-#  define EVENT_NEXT(evt)      (eventq)(evt->next)
-
-#endif /* GRAN */
+#if defined(GRAN)
+#define GRANSIMSTATS_BINARY   RTSflags.GranFlags.granSimStats_Binary
+#elif defined(PAR)
+#define GRANSIMSTATS_BINARY   RTSflags.ParFlags.granSimStats_Binary
+#endif
+
+#ifdef PAR
+ullong msTime(STG_NO_ARGS);
+#  define CURRENT_TIME msTime()
+#  define TIME_ON_PROC(p) msTime()
+
+#  define CURRENT_PROC thisPE
+#endif
+
+#if defined(GRAN)
+
+#if !defined(COMPILING_GHC)
+#include "RtsFlags.h"
+#endif
+
+#  define CURRENT_TIME CurrentTime[CurrentProc]
+#  define TIME_ON_PROC(p) CurrentTime[p]
+#  define CURRENT_PROC CurrentProc
+#endif
 
 #if defined(GRAN) || defined(PAR)
+
+/* Granularity event types for output (see DumpGranEvent) */
+enum gran_event_types {
+    GR_START = 0, GR_STARTQ, 
+    GR_STEALING, GR_STOLEN, GR_STOLENQ, 
+    GR_FETCH, GR_REPLY, GR_BLOCK, GR_RESUME, GR_RESUMEQ,
+    GR_SCHEDULE, GR_DESCHEDULE,
+    GR_END,
+    SP_SPARK, SP_SPARKAT, SP_USED, SP_PRUNED, SP_EXPORTED, SP_ACQUIRED,
+    GR_ALLOC,
+    GR_TERMINATE,
+    GR_SYSTEM_START, GR_SYSTEM_END,            /* only for debugging */
+    GR_EVENT_MAX
+};
+
+/* Prototypes of functions needed both in GRAN and PAR setup */
 void DumpGranEvent PROTO((enum gran_event_types name, P_ tso));
-void DumpSparkGranEvent PROTO((enum gran_event_types name, W_ id));
-void DumpGranEventAndNode PROTO((enum gran_event_types name, P_ tso, P_ node, PROC proc));
-void DumpRawGranEvent PROTO((PROC pe, enum gran_event_types name, W_ id));
-void DumpGranInfo PROTO((PROC pe, P_ tso, rtsBool mandatory_thread));
+void DumpRawGranEvent PROTO((PROC proc, PROC p, enum gran_event_types name, P_ tso, P_ node, I_ len));
+void DumpStartEventAt PROTO((TIME time, PROC proc, PROC p, enum gran_event_types name,
+                            P_ tso, P_ node, I_ len));
+void DumpGranInfo PROTO((PROC proc, P_ tso, rtsBool mandatory_thread));
+void DumpTSO PROTO((P_ tso));
+
 void grterminate PROTO((TIME v));
+void grputw PROTO((TIME v));
+
+extern unsigned CurrentProc;
+    /* I have no idea what this is supposed to be in the PAR case WDP 96/03 */
+
+#endif  /* GRAN || PAR */
+
+/* ----------  The rest of this file is GRAN only  ---------- */
+
+#if defined(GRAN)
+rtsBool any_idle PROTO((STG_NO_ARGS));
+int     idlers   PROTO((STG_NO_ARGS));
+
+enum proc_status {
+  Idle = 0,             /* empty threadq */
+  Sparking,             /* non-empty sparkq; FINDWORK has been issued */
+  Starting,             /* STARTTHREAD has been issue */
+  Fetching,             /* waiting for remote data (only if block-on-fetch) */
+  Fishing,              /* waiting for remote spark/thread */
+  Busy                  /* non-empty threadq, with head of queue active */
+};
+
+typedef struct event {
+  PROC proc;            /* Processor id */
+  PROC creator;         /* Processor id of PE that created the event */
+  EVTTYPE evttype;      /* Event type */
+  TIME time;            /* Time at which event happened */
+  P_ tso;               /* Associated TSO, if relevant, Nil_closure otherwise*/
+  P_ node;              /* Associated node, if relevant, Nil_closure otherwise*/
+  sparkq spark;         /* Associated SPARK, if relevant, NULL otherwise */
+  I_  gc_info;          /* Counter of heap objects to mark (used in GC only)*/
+  struct event *next;
+  } *eventq;
+
+/* Macros for accessing components of the event structure */ 
+#define EVENT_PROC(evt)        (evt->proc)
+#define EVENT_CREATOR(evt)     (evt->creator)
+#define EVENT_TIME(evt)        (evt->time)
+#define EVENT_TYPE(evt)        (evt->evttype)
+#define EVENT_TSO(evt) (evt->tso)
+#define EVENT_NODE(evt)        (evt->node)
+#define EVENT_SPARK(evt)       (evt->spark)
+#define EVENT_GC_INFO(evt) (evt->gc_info)
+#define EVENT_NEXT(evt)        (eventq)(evt->next)
+
+/* Maximum number of PEs that can be simulated */
+#define MAX_PROC (BITS_IN(W_))
+
+#if 0
+extern W_ IdleProcs, Idlers; 
+#endif
+
+/* Processor numbers to bitmasks and vice-versa */
+#define MainProc            0           /* Id of main processor */
+#define MAX_PRI              10000       /* max possible priority */
+#define MAIN_PRI             MAX_PRI     /* priority of main thread */ 
+
+/* GrAnSim uses IdleProcs as bitmask to indicate which procs are idle */
+#define PE_NUMBER(n)          (1l << (long)n)
+#define ThisPE               PE_NUMBER(CurrentProc)
+#define MainPE               PE_NUMBER(MainProc)
+#define Everywhere           (~0l)
+#define Nowhere                      (0l)
+
+#define IS_LOCAL_TO(ga,proc)  ((1l << (long) proc) & ga)
+
+#define GRAN_TIME_SLICE       1000        /* max time between 2 ReSchedules */
+
+#if 1
+
+#define IS_IDLE(proc)        (procStatus[proc] == Idle)
+#define IS_SPARKING(proc)    (procStatus[proc] == Sparking)
+#define IS_STARTING(proc)    (procStatus[proc] == Starting)
+#define IS_FETCHING(proc)    (procStatus[proc] == Fetching)
+#define IS_FISHING(proc)     (procStatus[proc] == Fishing)
+#define IS_BUSY(proc)        (procStatus[proc] == Busy)    
+#define ANY_IDLE             (any_idle())
+#define MAKE_IDLE(proc)      do { procStatus[proc] = Idle; } while(0)
+#define MAKE_SPARKING(proc)  do { procStatus[proc] = Sparking; } while(0)
+#define MAKE_STARTING(proc)  do { procStatus[proc] = Starting; } while(0)
+#define MAKE_FETCHING(proc)  do { procStatus[proc] = Fetching; } while(0)
+#define MAKE_FISHING(proc)   do { procStatus[proc] = Fishing; } while(0)
+#define MAKE_BUSY(proc)      do { procStatus[proc] = Busy; } while(0)
+
+#else 
+
+#define IS_IDLE(proc)  ((IdleProcs & PE_NUMBER((long)proc)) != 0l)
+#define ANY_IDLE       (Idlers > 0)
+#define MAKE_IDLE(proc) do { \
+                          if (!IS_IDLE(proc)) { \
+                            ++Idlers; \
+                           IdleProcs |= PE_NUMBER(proc); \
+                           procStatus[proc] = Idle; \
+                         } \
+                        } while(0)
+#define MAKE_BUSY(proc) do { \
+                         if (IS_IDLE(proc)) { \
+                           --Idlers; \
+                           IdleProcs &= ~PE_NUMBER(proc); \
+                           procStatus[proc] = Busy; \
+                          } \
+                        } while(0)
+#endif
+
+/* Number of last event type */
+#define MAX_EVENT       9
+/* Event Types (internal use only) */
+#define STARTTHREAD     0     /* Start a newly created thread */
+#define CONTINUETHREAD  1     /* Continue running the first thread in the queue */
+#define RESUMETHREAD    2     /* Resume a previously running thread */
+#define MOVESPARK       3     /* Move a spark from one PE to another */
+#define MOVETHREAD      4     /* Move a thread from one PE to another */
+#define FINDWORK        5     /* Search for work */
+#define FETCHNODE       6     /* Fetch a node */
+#define FETCHREPLY      7     /* Receive a node */
+#define GLOBALBLOCK     8     /* Block a TSO on a remote node */
+#define UNBLOCKTHREAD   9     /* Make a TSO runnable */
+
+#if defined(GRAN_CHECK)
+/* Prototypes of GrAnSim debugging functions */
+void G_PRINT_NODE(P_);
+void G_TREE(P_); 
+void G_INFO_TABLE(P_);
+void G_CURR_THREADQ(I_);
+void G_THREADQ(P_, I_);
+void G_TSO(P_, I_);
+void G_EVENT(eventq, I_);
+void G_EVENTQ(I_);
+void G_PE_EQ(PROC, I_);
+void G_SPARK(sparkq, I_);
+void G_SPARKQ(sparkq, I_);
+void G_CURR_SPARKQ(I_);
+void G_PROC(I_, I_);
+void GP(I_);
+void GCP();
+void GT(P_);
+void GCT();
+void GEQ();
+void GTQ(PROC);
+void GCTQ();
+void GSQ(PROC);
+void GCSQ();
+void GN(P_);
+void GIT(P_);
+void pC(P_);
+void DN(P_);
+void DIT(P_);
+void DT(P_);
+/* void DS(P_); */
+#endif
+
+/* Interface to event queues */
+extern eventq EventHd;             /* global event queue */
+extern char *event_names[];
+eventq get_next_event PROTO(());
+TIME get_time_of_next_event PROTO(());
+void newevent PROTO((PROC proc, PROC creator, TIME time, EVTTYPE
+                           evttype, P_ tso, P_ node, sparkq spark));
+void prepend_event PROTO((eventq event));
+eventq grab_event PROTO((STG_NO_ARGS));
+void print_event PROTO((eventq event));
+void print_eventq PROTO((eventq hd));
+void print_spark PROTO((sparkq spark));
+void print_sparkq PROTO((sparkq hd));
+
+/* void DumpPruneEvent PROTO((PROC proc, sparkq spark)); */
 
-# ifdef GRAN
 I_ SaveSparkRoots PROTO((I_));
 I_ SaveEventRoots PROTO((I_));
 
@@ -53,19 +250,179 @@ I_ RestoreEventRoots PROTO((I_));
 
 IF_RTS(int init_gr_simulation PROTO((int, char **, int, char **));)
 IF_RTS(void end_gr_simulation(STG_NO_ARGS);)
-# endif
 
-# ifdef PAR
-ullong msTime(STG_NO_ARGS);
-#  define CURRENT_TIME msTime()
+/* These constants are defaults for the RTS flags of GranSim */
 
-#  define CURRENT_PROC thisPE
+/* Communication Cost Model (EDS-like), max_proc > 2. */
 
-# else /* GRAN */
+#define LATENCY                           1000 /* Latency for single packet */
+#define ADDITIONAL_LATENCY         100 /* Latency for additional packets */
+#define BASICBLOCKTIME              10
+#define FETCHTIME              (LATENCY*2+MSGUNPACKTIME)
+#define LOCALUNBLOCKTIME            10
+#define GLOBALUNBLOCKTIME      (LATENCY+MSGUNPACKTIME)
 
-#  define CURRENT_TIME CurrentTime[CurrentProc]
-#  define CURRENT_PROC CurrentProc
-# endif
+#define        MSGPACKTIME                  0  /* Cost of creating a packet */
+#define        MSGUNPACKTIME                0  /* Cost of receiving a packet */
+#define MSGTIDYTIME                  0  /* Cost of cleaning up after send */
+
+#define MAX_FISHES                   1  /* max no. of outstanding spark steals */
+/* How much to increase GrAnSims internal packet size if an overflow 
+   occurs.
+   NB: This is a GrAnSim internal variable and is independent of the
+   simulated packet buffer size.
+*/
+
+#define GRANSIM_DEFAULT_PACK_BUFFER_SIZE     200
+#define REALLOC_SZ                           50
 
+/* extern W_ gran_mpacktime, gran_mtidytime, gran_munpacktime; */
+
+/* Thread cost model */
+#define THREADCREATETIME          (25+THREADSCHEDULETIME)
+#define THREADQUEUETIME                    12  /* Cost of adding a thread to the running/runnable queue */
+#define THREADDESCHEDULETIME       75  /* Cost of descheduling a thread */
+#define THREADSCHEDULETIME         75  /* Cost of scheduling a thread */
+#define THREADCONTEXTSWITCHTIME            (THREADDESCHEDULETIME+THREADSCHEDULETIME)
+
+/* Instruction Cost model (SPARC, including cache misses) */
+#define ARITH_COST                1
+#define BRANCH_COST               2
+#define LOAD_COST                 4
+#define STORE_COST                4
+#define FLOAT_COST                1 /* ? */
+
+#define HEAPALLOC_COST             11
+
+#define PRI_SPARK_OVERHEAD    5
+#define PRI_SCHED_OVERHEAD    5
+
+/* Miscellaneous Parameters */
+extern rtsBool DoFairSchedule;
+extern rtsBool DoReScheduleOnFetch;
+extern rtsBool SimplifiedFetch;
+extern rtsBool DoStealThreadsFirst;
+extern rtsBool DoAlwaysCreateThreads;
+extern rtsBool DoThreadMigration;
+extern rtsBool DoGUMMFetching;
+extern I_ FetchStrategy;
+extern rtsBool PreferSparksOfLocalNodes;
+extern rtsBool DoPrioritySparking, DoPriorityScheduling;
+extern I_ SparkPriority, SparkPriority2, ThunksToPack;
+/* These come from debug options -bD? */
+extern rtsBool NoForward;
+extern rtsBool PrintFetchMisses;
+
+extern TIME TimeOfNextEvent, EndOfTimeSlice; /* checked from the threaded world! */
+extern I_ avoidedCS; /* Unused!! ToDo: Remake libraries and nuke this var */
+extern rtsBool IgnoreEvents; /* HACK only for testing */
+
+#if defined(GRAN_CHECK)
+/* Variables for gathering misc statistics */
+extern I_ tot_low_pri_sparks;
+extern I_ rs_sp_count, rs_t_count, ntimes_total, fl_total, no_of_steals;
+extern I_ tot_packets, tot_packet_size, tot_cuts, tot_thunks,
+          tot_sq_len, tot_sq_probes,  tot_sparks, withered_sparks,
+          tot_add_threads, tot_tq_len, non_end_add_threads;
+#endif 
+
+extern I_ fetch_misses;
+#if defined(GRAN_COUNT)
+extern I_ nUPDs, nUPDs_old, nUPDs_new, nUPDs_BQ, nPAPs, BQ_lens;
 #endif
+
+extern FILE *gr_file;
+/* extern rtsBool no_gr_profile; */
+/* extern rtsBool do_sp_profile; */ 
+
+extern rtsBool NeedToReSchedule;
+
+void GranSimAllocate                PROTO((I_ n, P_ node, W_ liveness));
+void GranSimUnAllocate              PROTO((I_ n, P_ node, W_ liveness));
+I_   GranSimFetch                   PROTO((P_ node));
+void GranSimExec                    PROTO((W_ ariths, W_ branches, W_ loads, W_ stores, W_ floats));
+void GranSimSpark                   PROTO((W_ local, P_ node));
+void GranSimSparkAt                 PROTO((sparkq spark, P_ where, I_ identifier));
+void GranSimSparkAtAbs              PROTO((sparkq spark, PROC proc, I_ identifier));
+void GranSimBlock                   PROTO((P_ tso, PROC proc, P_ node));
+void PerformReschedule              PROTO((W_, rtsBool));
+
+#define GRAN_ALLOC_HEAP(n,liveness)       \
+       GranSimAllocate_wrapper(n,0,0);
+
+#define GRAN_UNALLOC_HEAP(n,liveness)     \
+       GranSimUnallocate_wrapper(n,0,0);
+
+#if 0 
+
+#define GRAN_FETCH()                      \
+       GranSimFetch_wrapper(Node);
+
+#define GRAN_FETCH_AND_RESCHEDULE(liveness_mask,reenter)       \
+       do { if(liveness_mask&LIVENESS_R1)                      \
+            SaveAllStgRegs();                                  \
+             GranSimFetch(Node);                               \
+            PerformReschedule(liveness_mask,reenter);          \
+            RestoreAllStgRegs();                               \
+          } while(0)
+
+#define GRAN_RESCHEDULE(liveness_mask,reenter) \
+        PerformReschedule_wrapper(liveness_mask,reenter)
+
+#else
+
+#define GRAN_FETCH()                      /*nothing */
+
+#define GRAN_FETCH_AND_RESCHEDULE(liveness_mask,reenter)       \
+       do { if(liveness_mask&LIVENESS_R1)                      \
+            SaveAllStgRegs();                                  \
+             GranSimFetch(Node);                               \
+            PerformReschedule(liveness_mask,reenter);          \
+            RestoreAllStgRegs();                               \
+          } while(0)
+
+#define GRAN_RESCHEDULE(liveness_mask,reenter)  GRAN_FETCH_AND_RESCHEDULE(liveness_mask,reenter)
+
+#endif
+
+#define THREAD_CONTEXT_SWITCH(liveness_mask,reenter)   \
+        do { \
+       if (context_switch /* OR_INTERVAL_EXPIRED */) { \
+          GRAN_RESCHEDULE(liveness_mask,reenter); \
+        } }while(0)
+
+#if 0
+
+#define GRAN_EXEC(arith,branch,load,store,floats)       \
+        GranSimExec_wrapper(arith,branch,load,store,floats);
+
+#else
+
+#define GRAN_EXEC(arith,branch,load,store,floats)       \
+        { \
+          W_ cost = RTSflags.GranFlags.gran_arith_cost*arith +   \
+                    RTSflags.GranFlags.gran_branch_cost*branch + \
+                    RTSflags.GranFlags.gran_load_cost*load +   \
+                    RTSflags.GranFlags.gran_store_cost*store +   \
+                    RTSflags.GranFlags.gran_float_cost*floats;   \
+          TSO_EXECTIME(CurrentTSO) += cost;                      \
+          CurrentTime[CurrentProc] += cost;                      \
+        }
+
+#endif
+               
+#define GRAN_YIELD(liveness)                                   \
+        do {                                                   \
+          if ( (CurrentTime[CurrentProc]>=EndOfTimeSlice) ||   \
+               ((CurrentTime[CurrentProc]>=TimeOfNextEvent) && \
+               (TimeOfNextEvent!=0) && !IgnoreEvents )) {     \
+           DO_GRAN_YIELD(liveness);                           \
+         }                                                    \
+       } while (0);
+
+#define ADD_TO_SPARK_QUEUE(spark)            \
+   STGCALL1(void,(),add_to_spark_queue,spark) \
+
+#endif  /* GRAN */
+       
 \end{code}
index 74ab648..90a2819 100644 (file)
@@ -63,12 +63,14 @@ PLAT_H_FILES = config.h platform.h
 #undef __native_h
 
 /* Literate-pgmming suffix rules used herein */
-LitSuffixRule(.lh,.h)
-LitSuffixRule(.lc,.c)
+UnlitSuffixRule(.lh,.h)
+UnlitSuffixRule(.lc,.c)
 
 all :: /* so it is first */
        @:
 
+UnlitNeededHere(depend)
+
 #if GhcWithNativeCodeGen == YES
 
 GhcDriverNeededHere(depend all mkNativeHdr.o) /* we use its C-compiling know-how */
@@ -101,9 +103,3 @@ ExtraStuffToClean( $(H_FILES_FROM_LH_FILES) )
 EtagsNeededHere(tags) /* need this to do "make tags" */
 ClearTagsFile()
 CTagsTarget( $(H_FILES) )
-
-LitStuffNeededHere(docs depend)
-InfoStuffNeededHere(docs)
-
-LitDocRootTargetWithNamedOutput(root,lit,root-standalone)
-LitDocRootTargetWithNamedOutput(c-as-asm,lit,c-as-asm-standalone)
index cbf0e55..4d060cf 100644 (file)
@@ -115,8 +115,9 @@ Get this out of the way.  These are all null definitions.
   
 #  define SET_TASK_ACTIVITY(act)               /* nothing */
 
-# else
-# ifdef GRAN
+#endif
+
+#if defined(GRAN)
 
 #  define GA_HDR_SIZE                  1
 
@@ -130,13 +131,10 @@ Get this out of the way.  These are all null definitions.
        PROCS(closure) = (W_)(procs)    /* Set closure's location */
 #  define SET_GRAN_HDR(closure,pe)     SET_PROCS(closure,pe)
 
-#  if defined(GRAN_TNG)
 #   define SET_STATIC_PROCS(closure)   , (W_) (Everywhere)
-#  else
-#   define SET_STATIC_PROCS(closure)   , (W_) (MainPE)
-#  endif   /* GRAN_TNG */
 
 #  define SET_TASK_ACTIVITY(act)       /* nothing */
+#endif
 \end{code}
 
 %************************************************************************
@@ -154,7 +152,7 @@ for local closures that have no global address), and @setGA@ to store a new
 global address for a local closure which did not previously have one.
 
 \begin{code}
-# else /* it must be PARallel (to end of file) */
+#if defined(PAR) 
 
 #  define GA_HDR_SIZE                  0
   
@@ -445,13 +443,8 @@ Special info-table for local blocking queues.
 %************************************************************************
 
 \begin{code}
-#  ifdef GRAN
-#   define HAVE_SPARK ((PendingSparksHd[REQUIRED_POOL] != Nil_closure) ||      \
-                   (PendingSparksHd[ADVISORY_POOL] != Nil_closure))
-#  else
 #   define HAVE_SPARK ((PendingSparksHd[REQUIRED_POOL] < PendingSparksTl[REQUIRED_POOL]) \
                ||  (PendingSparksHd[ADVISORY_POOL] < PendingSparksTl[ADVISORY_POOL]))
-#  endif
 
 #  define HAVE_WORK    (RUNNING_THREAD || HAVE_SPARK)
 #  define RUNNING_THREAD  (CurrentTSO != NULL)
@@ -470,33 +463,31 @@ This constant defines how many words of data we can pack into a single
 packet in the parallel (GUM) system.
 
 \begin{code}
-#  ifdef PAR
 void   InitPackBuffer(STG_NO_ARGS);
-P_      PackNearbyGraph PROTO((P_ closure,W_ *size));
 P_      PackTSO PROTO((P_ tso, W_ *size));
 P_      PackStkO PROTO((P_ stko, W_ *size));
 P_     AllocateHeap PROTO((W_ size)); /* Doesn't belong */
 
-P_      get_closure_info PROTO((P_ closure, W_ *size, W_ *ptrs, W_ *nonptrs, W_ *vhs));
-
-rtsBool isOffset PROTO((globalAddr *ga)),
-       isFixed PROTO((globalAddr *ga));
-
 void    InitClosureQueue (STG_NO_ARGS);
 P_      DeQueueClosure(STG_NO_ARGS);
 void    QueueClosure PROTO((P_ closure));
 rtsBool QueueEmpty(STG_NO_ARGS);
 void    PrintPacket PROTO((P_ buffer));
-void    doGlobalGC(STG_NO_ARGS);
 
-P_ UnpackGraph PROTO((W_ *buffer, globalAddr **gamap, W_ *nGAs));
-#  endif
+P_      get_closure_info PROTO((P_ closure, W_ *size, W_ *ptrs, W_ *nonptrs, W_ *vhs, char *type));
+
+rtsBool isOffset PROTO((globalAddr *ga)),
+       isFixed PROTO((globalAddr *ga));
 
+void    doGlobalGC(STG_NO_ARGS);
+
+P_      PackNearbyGraph PROTO((P_ closure,W_ *size));
+P_      UnpackGraph PROTO((W_ *buffer, globalAddr **gamap, W_ *nGAs));
 \end{code}
 
 \begin{code}
-#  define PACK_HEAP_REQUIRED  \
-    ((RTSflags.ParFlags.packBufferSize - PACK_HDR_SIZE) / (PACK_GA_SIZE + _FHS) * (SPEC_HS + 2))
+#    define PACK_HEAP_REQUIRED  \
+      ((RTSflags.ParFlags.packBufferSize - PACK_HDR_SIZE) / (PACK_GA_SIZE + _FHS) * (SPEC_HS + 2))
 
 extern W_      *PackBuffer;      /* size: can be set via option */
 extern long *buffer;             /* HWL_ */
@@ -518,12 +509,55 @@ extern void    AllocClosureQueue(W_ size);
 #  define PACK_HDR_SIZE        1       /* Words of header in a packet */
 
 #  define PACK_PLC_SIZE        2       /* Size of a packed PLC in words */
-  
+
+#endif
 \end{code}
-End multi-slurp protection:
 \begin{code}
-# endif /* yes, it is PARallel */
-#endif /* it was GRAN or PARallel */
+
+#if defined(GRAN)
+/* ToDo: Check which of the PAR routines are needed in GranSim -- HWL */
+void  InitPackBuffer(STG_NO_ARGS);
+P_    AllocateHeap PROTO((W_ size)); /* Doesn't belong */
+P_    PackNearbyGraph PROTO((P_ closure, P_ tso, W_ *packbuffersize));
+P_    PackOneNode PROTO((P_ closure, P_ tso, W_ *packbuffersize));
+P_    UnpackGraph PROTO((P_ buffer));
+
+void    InitClosureQueue (STG_NO_ARGS);
+P_      DeQueueClosure(STG_NO_ARGS);
+void    QueueClosure PROTO((P_ closure));
+rtsBool QueueEmpty(STG_NO_ARGS);
+void    PrintPacket PROTO((P_ buffer));
+
+P_      get_closure_info PROTO((P_ closure, W_ *size, W_ *ptrs, W_ *nonptrs, W_ *vhs, char *type));
+
+/* These are needed in the packing code to get the size of the packet
+   right. The closures itself are never built in GrAnSim. */
+#  define FETCHME_VHS                          IND_VHS
+#  define FETCHME_HS                           IND_HS
+  
+#  define FETCHME_GA_LOCN                       FETCHME_HS
+  
+#  define FETCHME_CLOSURE_SIZE(closure)                IND_CLOSURE_SIZE(closure)
+#  define FETCHME_CLOSURE_NoPTRS(closure)              0L
+#  define FETCHME_CLOSURE_NoNONPTRS(closure)   (IND_CLOSURE_SIZE(closure)-IND_VHS)
+  
+#  define MAX_GAS      (RTSflags.GranFlags.packBufferSize / PACK_GA_SIZE)
+#  define PACK_GA_SIZE 3       /* Size of a packed GA in words */
+                               /* Size of a packed fetch-me in words */
+#  define PACK_FETCHME_SIZE (PACK_GA_SIZE + FIXED_HS)
+#  define PACK_HDR_SIZE        4       /* Words of header in a packet */
+
+#    define PACK_HEAP_REQUIRED  \
+      ((RTSflags.GranFlags.packBufferSize - PACK_HDR_SIZE) / (PACK_GA_SIZE + _FHS) * (SPEC_HS + 2))
+
+#    define PACK_FLAG_LOCN           0  
+#    define PACK_TSO_LOCN            1
+#    define PACK_UNPACKED_SIZE_LOCN  2
+#    define PACK_SIZE_LOCN           3
+#    define MAGIC_PACK_FLAG 0xfabc
+#endif  
 
 #endif /* Parallel_H */
 \end{code}
+
+
index 9a7bbaa..c7a8af9 100644 (file)
@@ -31,14 +31,14 @@ struct GC_FLAGS {
                    2 set: details of minor collections
                    4 set: details of major collections, except marking
                    8 set: ditto, but marking this time
-                  16 set: GC of MallocPtrs
+                  16 set: GC of ForeignObjs
                   32 set: GC of Concurrent things
            */
-#define DEBUG_TRACE_MINOR_GC   2
-#define DEBUG_TRACE_MAJOR_GC   4
-#define DEBUG_TRACE_MARKING    8
-#define DEBUG_TRACE_MALLOCPTRS 16
-#define DEBUG_TRACE_CONCURRENT 32
+#define DEBUG_TRACE_MINOR_GC    2
+#define DEBUG_TRACE_MAJOR_GC    4
+#define DEBUG_TRACE_MARKING     8
+#define DEBUG_TRACE_FOREIGNOBJS 16
+#define DEBUG_TRACE_CONCURRENT  32
 
     rtsBool lazyBlackHoling;
     rtsBool doSelectorsAtGC;
@@ -86,6 +86,13 @@ struct PROFILING_FLAGS {
 # define DESCRchar 'D'
 # define TYPEchar  'Y'
 # define TIMEchar  'T'
+
+    char *ccSelector;
+    char *modSelector;
+    char *grpSelector;
+    char *descrSelector;
+    char *typeSelector;
+    char *kindSelector;
 };
 #endif
 
@@ -113,6 +120,83 @@ struct PAR_FLAGS {
 
 #ifdef GRAN
 struct GRAN_FLAGS {
+    rtsBool granSimStats;  /* Full .gr profile (rtsTrue) or only END events? */
+    rtsBool granSimStats_suppressed; /* No .gr profile at all */
+    rtsBool granSimStats_Binary;
+    rtsBool granSimStats_Sparks;
+    rtsBool granSimStats_Heap;
+    rtsBool labelling;
+    W_     packBufferSize;
+    W_     packBufferSize_internal;
+
+    I_ proc;                      /* number of processors */
+    I_ max_fishes;                /* max number of spark or thread steals */
+    TIME time_slice;              /* max time slice of one reduction thread */
+
+    /* Communication Cost Variables -- set in main program */
+    W_ gran_latency;              /* Latency for single packet */
+    W_ gran_additional_latency;   /* Latency for additional packets */
+    W_ gran_fetchtime;            
+    W_ gran_lunblocktime;         /* Time for local unblock */
+    W_ gran_gunblocktime;         /* Time for global unblock */
+    W_ gran_mpacktime;            /* Cost of creating a packet */     
+    W_ gran_munpacktime;         /* Cost of receiving a packet */    
+    W_ gran_mtidytime;           /* Cost of cleaning up after send */
+
+    W_ gran_threadcreatetime;     /* Thread creation costs */
+    W_ gran_threadqueuetime;      /* Cost of adding a thread to the running/runnable queue */
+    W_ gran_threaddescheduletime; /* Cost of descheduling a thread */
+    W_ gran_threadscheduletime;   /* Cost of scheduling a thread */
+    W_ gran_threadcontextswitchtime;  /* Cost of context switch  */
+
+    /* Instruction Costs */
+    W_ gran_arith_cost;        /* arithmetic instructions (+,i,< etc) */
+    W_ gran_branch_cost;       /* branch instructions */ 
+    W_ gran_load_cost;         /* load into register */
+    W_ gran_store_cost;        /* store into memory */
+    W_ gran_float_cost;        /* floating point operations */
+
+    W_ gran_heapalloc_cost;    /* heap allocation costs */
+
+    /* Overhead for granularity control mechanisms */
+    /* overhead per elem of spark queue */
+    W_ gran_pri_spark_overhead;
+    /* overhead per elem of thread queue */
+    W_ gran_pri_sched_overhead;
+
+    /* GrAnSim-Light: This version puts no bound on the number of
+         processors but in exchange doesn't model communication costs
+         (all communication is 0 cost). Mainly intended to show maximal
+         degree of parallelism in the program (*not* to simulate the
+         execution on a real machine). */
+   
+    rtsBool Light;
+
+    rtsBool DoFairSchedule ;        /* fair scheduling alg? default: unfair */
+    rtsBool DoReScheduleOnFetch ;   /* async. communication? */
+    rtsBool DoStealThreadsFirst;    /* prefer threads over sparks when stealing */
+    rtsBool SimplifiedFetch;        /* fast but inaccurate fetch modelling */
+    rtsBool DoAlwaysCreateThreads;  /* eager thread creation */
+    rtsBool DoGUMMFetching;         /* bulk fetching */
+    rtsBool DoThreadMigration;      /* allow to move threads */
+    I_      FetchStrategy;          /* what to do when waiting for data */
+    rtsBool PreferSparksOfLocalNodes; /* prefer local over global sparks */
+    rtsBool DoPrioritySparking;     /* sparks sorted by priorities */
+    rtsBool DoPriorityScheduling;   /* threads sorted by priorities */
+    I_      SparkPriority;          /* threshold for cut-off mechanism */
+    I_      SparkPriority2;
+    rtsBool RandomPriorities;
+    rtsBool InversePriorities;
+    rtsBool IgnorePriorities;
+    I_      ThunksToPack;           /* number of thunks in packet + 1 */ 
+    rtsBool RandomSteal;            /* steal spark/thread from random proc */
+    rtsBool NoForward;              /* no forwarding of fetch messages */
+    rtsBool PrintFetchMisses;       /* print number of fetch misses */
+
+    W_     debug;
+    rtsBool event_trace;
+    rtsBool event_trace_all;
+   
 };
 #endif /* GRAN */
 
index a72694c..7e22652 100644 (file)
@@ -70,43 +70,6 @@ typedef W_ TIME;
 typedef GLOBAL_TASK_ID PROC;
 #endif
 
-#if defined(GRAN) || defined(PAR)
-/* Granularity event types for output */
-enum gran_event_types {
-    GR_START = 0, GR_STARTQ, 
-    GR_STEALING, GR_STOLEN, GR_STOLENQ, 
-    GR_FETCH, GR_REPLY, GR_BLOCK, GR_RESUME, GR_RESUMEQ,
-    GR_SCHEDULE, GR_DESCHEDULE,
-    GR_END,
-    SP_SPARK, SP_SPARKAT, SP_USED, SP_PRUNED, SP_EXPORTED, SP_ACQUIRED,
-    GR_TERMINATE,
-    GR_EVENT_MAX
-};
-
-#endif
-
-#ifdef GRAN
-
-typedef struct spark
-{
-  struct spark *prev, *next;
-  P_ node;
-  I_ name, global;
-} *sparkq;
-
-typedef struct event {
-  PROC proc;            /* Processor id */
-  PROC creator;         /* Processor id of PE that created the event */
-  EVTTYPE evttype;      /* Event type */
-  TIME time;            /* Time at which event happened */
-  P_ tso;               /* Associated TSO, if relevant, Nil_closure otherwise*/
-  P_ node;              /* Associated node, if relevant, Nil_closure otherwise*/
-  sparkq spark;         /* Associated SPARK, if relevant, NULL otherwise */
-  struct event *next;
-  } *eventq;
-
-#endif
-
 \end{code}
 
 A cost centre is represented by a pointer to a static structure
@@ -124,24 +87,32 @@ typedef struct cc {
     char *module;              /* name of module in which _scc_ occurs */
     char *group;               /* name of group  in which _scc_ occurs */
 
-    char is_subsumed;          /* '\0' => *not* a CAF or dict cc       */
-                               /* 'C'  => *is* a CAF cc                */
-                               /* 'D'  => *is* a dictionary cc         */
+    char is_subsumed;          /* 'B'  => *not* a CAF/dict/sub cc      */
+                               /* 'S'  => *is* a subsumed cc           */
+                               /* 'c'  => *is* a CAF cc                */
+                               /* 'd'  => *is* a dictionary cc         */
+                               /* IS_CAF_OR_DICT tests for lowercase bit */
 
     /* Statistics Gathered */
 
     W_ scc_count;              /* no of scc expression instantiations  */
     W_ sub_scc_count;          /* no of scc's set inside this cc       */
-    W_ cafcc_count;            /* no of scc expression instantiations  */
     W_ sub_cafcc_count;        /* no of scc's set inside this cc       */
+    W_ sub_dictcc_count;       /* no of scc's set inside this cc       */
 
+#if defined(PROFILING_DETAIL_COUNTS)
     W_ thunk_count;            /* no of {thunk,function,PAP} enters    */
     W_ function_count;         /*    in this cost centre               */
     W_ pap_count;
+    W_ mem_allocs;             /* no of allocations                    */
+
+    W_ subsumed_fun_count;     /* no of functions subsumed             */
+    W_ subsumed_caf_count;     /* no of caf/dict funs subsumed         */
+    W_ caffun_subsumed;                /* no of subsumes from this caf/dict    */
+#endif
 
     W_ time_ticks;             /* no of timer interrupts -- current interval */
     W_ prev_ticks;             /* no of timer interrupts -- previous intervals */
-    W_ mem_allocs;             /* no of allocations                    */
     W_ mem_alloc;              /* no of words allocated (excl CC_HDR)  */
 
     /* Heap Profiling by Cost Centre */
@@ -150,6 +121,12 @@ typedef struct cc {
 
 } *CostCentre;
 
+#if defined(PROFILING_DETAIL_COUNTS)
+#define INIT_CC_STATS  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+#else
+#define INIT_CC_STATS  0,0,0,0,0,0,0,0
+#endif
+
 #endif /* defined(PROFILING) || defined(CONCURRENT) */
 \end{code}
 
index 326eaf3..fc20664 100644 (file)
@@ -506,71 +506,75 @@ they will hear about it soon enough (WDP 95/05).
 
 %************************************************************************
 %*                                                                     *
-\subsubsection[MallocPtr-closures]{@MallocPtr@ closure macros}
+\subsubsection[ForeignObj-closures]{@ForeignObj@ closure macros}
 %*                                                                     *
 %************************************************************************
 
-Here's what a MallocPtr looks like:
+Here's what a ForeignObj looks like:
 
 \begin{verbatim}
             <Var  Hdr> 
-+----------+----------+------+------+
-| Info Ptr | Forward  | Data | List |
-+----------+----------+------+------+
++----------+----------+------+-------------+------+
+| Info Ptr | Forward  | Data | FreeRoutine | List |
++----------+----------+------+-------------+------+
 \end{verbatim}
 
-The list is a pointer to the next MallocPtr in the list of all
-MallocPtrs.  Note that it is essential that the garbage collector {\em
+@List@ is a pointer to the next ForeignObj in the list of all
+ForeignObjs.  Note that it is essential that the garbage collector {\em
 not\/} follow this link but that the link must get updated with the
 new address.
 
 The optional @Forward@ field is used by copying collectors to insert
 the forwarding pointer into.  (If we overwrite the @Data@ part, we
-don't know which MallocPtr has just died; if we overwrite the @List@ part,
-we can't traverse the list of all MallocPtrs.)
+don't know which ForeignObj has just died; if we overwrite the @List@ part,
+we can't traverse the list of all ForeignObjs.)
+
+The @FreeRoutine@ is a reference to the finalisation routine to call
+when the @ForeignObj@ becomes garbage -- SOF 4/96
 
 \begin{code}
 #if !defined(PAR)
 
 # if defined(_INFO_COPYING)
-#  define MallocPtr_VHS                                1
+#  define ForeignObj_VHS                       1
 # else
-#  define MallocPtr_VHS                                0
+#  define ForeignObj_VHS                       0
 # endif
 
-# define MallocPtr_HS                  (FIXED_HS + MallocPtr_VHS)
-# define MallocPtr_SIZE                        (MallocPtr_VHS + 2)
+# define ForeignObj_HS                 (FIXED_HS + ForeignObj_VHS)
+# define ForeignObj_SIZE               (ForeignObj_VHS + 3)
 
-# define MallocPtr_CLOSURE_NoPTRS(closure)  0
-# define MallocPtr_CLOSURE_DATA(closure)    (((StgMallocPtr *)(closure))[MallocPtr_HS + 0])
-# define MallocPtr_CLOSURE_LINK(closure)    (((StgPtrPtr) (closure))[MallocPtr_HS + 1])
+# define ForeignObj_CLOSURE_NoPTRS(closure)     0
+# define ForeignObj_CLOSURE_DATA(closure)       (((StgForeignObj *)(closure))[ForeignObj_HS + 0])
+# define ForeignObj_CLOSURE_FINALISER(closure)  (((StgForeignObj *)(closure))[ForeignObj_HS + 1])
+# define ForeignObj_CLOSURE_LINK(closure)       (((StgPtrPtr) (closure))[ForeignObj_HS + 2])
 
-# define SET_MallocPtr_HDR(closure,infolbl,cc,size,ptrs) \
+# define SET_ForeignObj_HDR(closure,infolbl,cc,size,ptrs) \
                                        SET_FIXED_HDR(closure,infolbl,cc)
 \end{code}
 
-And to check that a Malloc ptr closure is valid
+And to check that a Foreign ptr closure is valid
 
 \begin{code}
-EXTDATA_RO(MallocPtr_info);
+EXTDATA_RO(ForeignObj_info);
 
 # if defined(DEBUG)
 
-#  define CHECK_MallocPtr_CLOSURE( closure ) \
+#  define CHECK_ForeignObj_CLOSURE( closure ) \
 do {                                       \
-  CHECK_MallocPtr_InfoTable( closure );    \
+  CHECK_ForeignObj_InfoTable( closure );    \
 } while (0)
 
-#  define CHECK_MallocPtr_InfoTable( closure ) \
-  ASSERT( (*((PP_)(closure))) == MallocPtr_info )
+#  define CHECK_ForeignObj_InfoTable( closure ) \
+  ASSERT( (*((PP_)(closure))) == ForeignObj_info )
 
-extern void Validate_MallocPtrList( P_ MPlist );
-#  define VALIDATE_MallocPtrList( mplist ) Validate_MallocPtrList( mplist )
+extern void Validate_ForeignObjList( P_ MPlist );
+#  define VALIDATE_ForeignObjList( mplist ) Validate_ForeignObjList( mplist )
 
 # else /* !DEBUG */
 
-#  define CHECK_MallocPtr_CLOSURE( closure ) /* nothing */
-#  define VALIDATE_MallocPtrList( mplist ) /* nothing */
+#  define CHECK_ForeignObj_CLOSURE( closure ) /* nothing */
+#  define VALIDATE_ForeignObjList( mplist ) /* nothing */
 
 # endif /* !DEBUG */
 #endif /* !PAR */
@@ -812,8 +816,8 @@ variable header):
 #define DATA_CLOSURE_NoPTRS(closure)    ((I_)0)
 #define DATA_CLOSURE_NoNONPTRS(closure) (DATA_CLOSURE_SIZE(closure) - DATA_VHS)
 
-#define SET_DATA_HDR(closure,infolbl,cc,size,ptrs/*==0*/)      \
-       { SET_FIXED_HDR(closure,infolbl,cc);                    \
+#define SET_DATA_HDR(closure,infolbl,cc,size,ptrs)     \
+       { SET_FIXED_HDR(closure,infolbl,cc);            \
          DATA_CLOSURE_SIZE(closure) = (W_)(size); }
 \end{code}
 
index 5cbbf06..071bce3 100644 (file)
@@ -96,8 +96,8 @@ It can have the following values (defined in CostCentre.lh):
   A black hole.
   \item[@ARR_K@]
   An array.
-  \item[@MP_K@]
-  A Malloc Pointer.
+  \item[@ForeignObj_K@]
+  A Foreign object (non-Haskell heap resident).
   \item[@SPT_K@]
   The Stable Pointer table.  (There should only be one of these but it
   represents a form of weak space leak since it can't shrink to meet
@@ -336,7 +336,7 @@ Otherwise, we add the RBH info table pointer to the end of the normal
 info table and vice versa.
 
 \begin{code}
-#ifdef PAR
+#if defined(PAR) || defined(GRAN)
 # define RBH_INFO_OFFSET           (GEN_INFO_OFFSET+GEN_INFO_WORDS)
 
 # define INCLUDE_SPEC_PADDING                          \
@@ -363,8 +363,13 @@ info table and vice versa.
 
 EXTFUN(RBH_entry);
 P_ convertToRBH PROTO((P_ closure));
+#if defined(GRAN)
+void convertFromRBH PROTO((P_ closure));
+#elif defined(PAR)
 void convertToFetchMe PROTO((P_ closure, globalAddr *ga));
 #endif
+
+#endif
 \end{code}
 
 %************************************************************************
@@ -711,7 +716,7 @@ MAYBE_DECLARE_RTBL(Spec_S,12,12)
                             CAT2(_ScanMove_,size),CAT2(_PRIn_,ptrs))           \
        }
 
-#ifdef PAR
+#if defined(PAR) || defined(GRAN)
 # define SPEC_U_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) \
     entry_localness(CAT2(RBH_,entry_code));            \
     localness W_ infolbl[];                    \
@@ -873,7 +878,7 @@ Compacting: only the PRStart (marking) routine needs to be special.
 
 \begin{code}
 
-#ifdef PAR
+#if defined(PAR) || defined(GRAN)
 # define SELECT_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,select_word_i,kind,descr,type) \
     entry_localness(CAT2(RBH_,entry_code));            \
     localness W_ infolbl[];                    \
@@ -1000,7 +1005,7 @@ MAYBE_DECLARE_RTBL(Gen_S,,)
        INCLUDE_COMPACTING_INFO(_ScanLink_S_N,_PRStart_N,_ScanMove_S,_PRIn_I)   \
        }
 
-#ifdef PAR
+#if defined(PAR) || defined(GRAN)
 # define GEN_U_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) \
     entry_localness(CAT2(RBH_,entry_code));            \
     localness W_ infolbl[];                    \
@@ -1274,7 +1279,7 @@ MAYBE_DECLARE_RTBL(Static,,)
 
 %************************************************************************
 %*                                                                     *
-\subsection[MallocPtr_ITBL]{@MallocPtr_TBL@: @MallocPtr@ info-table}
+\subsection[ForeignObj_ITBL]{@ForeignObj_TBL@: @ForeignObj@ info-table}
 %*                                                                     *
 %************************************************************************
 
@@ -1287,25 +1292,25 @@ I'm assuming @SPEC_N@, so that we don't need to pad out the info table. (JSM)
 \begin{code}
 #if !defined(PAR)
 
-# define MallocPtr_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) /*size,ptrs unused*/ \
+# define ForeignObj_ITBL(infolbl,entry_code,upd_code,liveness,tag,size,ptrs,localness,entry_localness,kind,descr,type) /*size,ptrs unused*/ \
     CAT_DECLARE(infolbl,kind,descr,type)       \
     entry_localness(entry_code);               \
     localness W_ infolbl[] = {                 \
         (W_) entry_code                                \
        ,(W_) tag                               \
-       ,(W_) MK_REP_REF(MallocPtr,,)           \
+       ,(W_) MK_REP_REF(ForeignObj,,)          \
        INCLUDE_PROFILING_INFO(infolbl)         \
     }
 
-MAYBE_DECLARE_RTBL(MallocPtr,,)
+MAYBE_DECLARE_RTBL(ForeignObj,,)
 
-# define MallocPtr_RTBL() \
-    const W_ MK_REP_LBL(MallocPtr,,)[] = { \
+# define ForeignObj_RTBL() \
+    const W_ MK_REP_LBL(ForeignObj,,)[] = { \
        INCLUDE_TYPE_INFO(INTERNAL)                             \
-       INCLUDE_SIZE_INFO(MallocPtr_SIZE, 0L)                   \
+       INCLUDE_SIZE_INFO(ForeignObj_SIZE, 0L)                  \
        INCLUDE_PAR_INFO                                        \
-       INCLUDE_COPYING_INFO(_Evacuate_MallocPtr,_Scavenge_MallocPtr)   \
-       SPEC_COMPACTING_INFO(_ScanLink_MallocPtr,_PRStart_MallocPtr,_ScanMove_MallocPtr,_PRIn_0) \
+       INCLUDE_COPYING_INFO(_Evacuate_ForeignObj,_Scavenge_ForeignObj)         \
+       SPEC_COMPACTING_INFO(_ScanLink_ForeignObj,_PRStart_ForeignObj,_ScanMove_ForeignObj,_PRIn_0) \
        }
 
 #endif /* !PAR */
@@ -1737,7 +1742,7 @@ during a return.
 
 /* Declare the phantom info table vectors (just Bool at the moment) */
 #ifndef COMPILING_GHC
-EXTDATA_RO(Bool_itblvtbl);
+EXTDATA_RO(Prelude_Bool_itblvtbl);
 #endif
 
 \end{code}
index 9fb25d8..c491b5b 100644 (file)
@@ -85,7 +85,7 @@ extern StgScanFun _ScanLink_MuTuple;
 extern StgScanFun _ScanLink_PI;
 #endif
 
-#ifdef PAR
+#if defined(PAR) || defined(GRAN)
 extern StgScanFun _ScanLink_RBH_2_1;
 extern StgScanFun _ScanLink_RBH_3_1;
 extern StgScanFun _ScanLink_RBH_3_3;
@@ -117,10 +117,11 @@ extern StgScanFun _ScanMove_RBH_11;
 extern StgScanFun _ScanMove_RBH_12;
 
 extern StgScanFun _ScanMove_RBH_S;
+#endif /* PAR || GRAN */
 
-#else
-extern StgScanFun _ScanLink_MallocPtr;
-#endif /* PAR */
+#if !defined(PAR) || defined(GRAN)
+extern StgScanFun _ScanLink_ForeignObj;
+#endif
 
 extern StgScanFun _ScanLink_BH_N;
 extern StgScanFun _ScanLink_BH_U;
@@ -158,7 +159,7 @@ extern StgScanFun _ScanMove_PI;
 #endif
 
 #ifndef PAR
-extern StgScanFun _ScanMove_MallocPtr;
+extern StgScanFun _ScanMove_ForeignObj;
 #endif /* !PAR */
 
 extern StgScanFun _ScanMove_ImmuTuple;
index 252fbfc..7667fb2 100644 (file)
@@ -84,7 +84,7 @@ extern StgScavFun _Scavenge_Data;
 extern StgEvacFun _Evacuate_MuTuple;
 extern StgScavFun _Scavenge_MuTuple;
 
-#ifdef PAR
+#if defined(PAR) || defined(GRAN)
 extern StgEvacFun _Evacuate_RBH_2;
 extern StgEvacFun _Evacuate_RBH_3;
 extern StgEvacFun _Evacuate_RBH_4;
@@ -117,11 +117,14 @@ extern StgScavFun _Scavenge_RBH_12_12;
 extern StgScavFun _Scavenge_RBH_N;
 extern StgScavFun _Scavenge_FetchMe;
 extern StgScavFun _Scavenge_BF;
-#else
-extern StgEvacFun _Evacuate_MallocPtr;
-extern StgScavFun _Scavenge_MallocPtr;
+#endif /* PAR || GRAN */
+
+#if !defined(PAR) || defined(GRAN)
+extern StgEvacFun _Evacuate_ForeignObj;
+extern StgScavFun _Scavenge_ForeignObj;
 #endif /* PAR */
 
+
 extern StgEvacFun _Evacuate_BH_N;
 extern StgScavFun _Scavenge_BH_N;
 
index 3069989..6b27286 100644 (file)
@@ -54,10 +54,10 @@ typedef struct {
 #endif
 
 #ifndef PAR
-    P_ MallocPtrList;     /* List of all Malloc Pointers (in new generation) */
+    P_ ForeignObjList;     /* List of all Foreign objects (in new generation) */
 
 #if defined(GCap) || defined(GCgn)
-    P_ OldMallocPtrList;  /* List of all Malloc Pointers in old generation */
+    P_ OldForeignObjList;  /* List of all Foreign objects in old generation */
 #endif
 
     P_ StablePointerTable;
@@ -82,9 +82,8 @@ Answer: They're on the heap in a "Stable Pointer Table". (ADR)
 #else
 # ifndef PAR
 #   ifdef GRAN
-#    define SM_MAXROOTS (10 + (MAX_PROC*4) + 2 + (MAX_PROC*2) + MAX_SPARKS)
-                               /* unthreaded + spark/thread queues + Current/Main TSOs
-                                  + events + sparks */
+#    define SM_MAXROOTS (10 + (MAX_PROC*2) + 2 )
+                    /* unthreaded + hd/tl thread queues + Current/Main TSOs */
 #   else
 #     define SM_MAXROOTS 5      /* See c-as-asm/HpOverflow.lc */
 #   endif
@@ -150,7 +149,7 @@ roots.  If we are using Appel's collector it also initialises the
 @OldLim@ field.
 
 In the sequential system, it also initialises the stable pointer table
-and the @MallocPtr@ (and @OldMallocPtrList@) fields.
+and the @ForeignObjList@ (and @OldForeignObjList@) fields.
 
 @collectHeap@ invokes the garbage collector that was requested at
 compile time. @reqsize@ is the size of the request (in words) that
@@ -197,9 +196,9 @@ B stack arising from any update frame ``squeezing'' [sequential only].
 \item The elements of @CAFlist@ and the stable pointers will be
 updated to point to the new locations of the closures they reference.
 
-\item Any members of @MallocPtrList@ which became garbage should have
-been reported (by calling @FreeMallocPtr@; and the @(Old)MallocPtrList@
-updated to contain only those Malloc Pointers which are still live.
+\item Any members of @ForeignObjList@ which became garbage should have
+been reported (by calling their finalising routines; and the @(Old)ForeignObjList@
+updated to contain only those Foreign objects which are still live.
 \end{itemize}
 
 \end{description}
@@ -433,7 +432,7 @@ same, but without the saved SuA pointer.
 We store the following information concerning the stacks in a global
 structure. (sequential only).
 \begin{code}
-#ifndef CONCURRENT
+#if 1 /* ndef CONCURRENT * /? HWL */
 
 typedef struct {
     PP_        botA;   /* Points to bottom-most word of A stack */
@@ -470,7 +469,7 @@ in the info-table.
 #define _INFO_MARKING
 
 #else
-/* NO_INFO_SPECIFIED (ToDo: an #error ???) */
+/* NO_INFO_SPECIFIED (ToDo: an #error ?) */
 #endif
 #endif
 #endif
index 2c6cb0b..764f418 100644 (file)
@@ -49,7 +49,7 @@ extern F_ _PRStart_MuTuple(STG_NO_ARGS);
 extern F_ _PRStart_PI(STG_NO_ARGS);
 #endif
 
-#ifdef PAR
+#if defined(PAR) || defined(GRAN)
 extern F_ _PRStart_RBH_0(STG_NO_ARGS);
 extern F_ _PRStart_RBH_1(STG_NO_ARGS);
 extern F_ _PRStart_RBH_2(STG_NO_ARGS);
@@ -66,9 +66,11 @@ extern F_ _PRStart_RBH_12(STG_NO_ARGS);
 extern F_ _PRStart_RBH_N(STG_NO_ARGS);
 extern F_ _PRStart_FetchMe(STG_NO_ARGS);
 extern F_ _PRStart_BF(STG_NO_ARGS);
-#else
-extern F_ _PRStart_MallocPtr(STG_NO_ARGS);
-#endif /* PAR */
+#endif /* PAR || GRAN */
+
+#if !defined(PAR) || defined(GRAN)
+extern F_ _PRStart_ForeignObj(STG_NO_ARGS);
+#endif
 
 #if defined(CONCURRENT)
 extern F_ _PRStart_StkO(STG_NO_ARGS);
@@ -117,7 +119,7 @@ extern F_ _PRIn_I_Dyn(STG_NO_ARGS);
 extern F_ _PRIn_I_Tuple(STG_NO_ARGS);
 extern F_ _PRIn_I_MuTuple(STG_NO_ARGS);
 
-#ifdef PAR
+#if defined(PAR) || defined(GRAN)
 extern F_ _PRIn_BF(STG_NO_ARGS);
 extern F_ _PRIn_RBH_0(STG_NO_ARGS);
 extern F_ _PRIn_RBH_1(STG_NO_ARGS);
@@ -133,9 +135,11 @@ extern F_ _PRIn_RBH_10(STG_NO_ARGS);
 extern F_ _PRIn_RBH_11(STG_NO_ARGS);
 extern F_ _PRIn_RBH_12(STG_NO_ARGS);
 extern F_ _PRIn_RBH_I(STG_NO_ARGS);
-#else
-extern F_ _PRIn_I_MallocPtr(STG_NO_ARGS);
-#endif /* PAR */
+#endif /* PAR || GRAN */
+
+#if !defined(PAR) || defined(GRAN)
+extern F_ _PRIn_I_ForeignObj(STG_NO_ARGS);
+#endif
 
 extern F_ _PRIn_Error(STG_NO_ARGS);
 
index 7da6a10..de1d35c 100644 (file)
@@ -348,7 +348,7 @@ EXTFUN(UpdatePAP);
     (IS_MUTABLE(INFO_PTR(closure)) && MUT_LINK(closure) != MUT_NOT_LINKED)
 
 # if defined(GRAN)
-extern I_ AwakenBlockingQueue PROTO((P_));
+extern P_ AwakenBlockingQueue PROTO((P_));
 # else
 extern void AwakenBlockingQueue PROTO((P_));
 # endif
index 5435220..baefd80 100644 (file)
@@ -54,7 +54,15 @@ Mere abbreviations:
 General things; note: general-but-``machine-dependent'' macros are
 given in \tr{StgMachDeps.lh}.
 \begin{code}
-#define STG_MAX(a,b)   (((a)>=(b)) ? (a) : (b))
+I_ STG_MAX PROTO((I_, I_)); /* GCC -Wall loves prototypes */
+
+extern STG_INLINE
+I_
+STG_MAX(I_ a, I_ b) { return((a >= b) ? a : b); }
+/* NB: the naive #define macro version of STG_MAX
+   can lead to exponential CPP explosion, if you
+   have very-nested STG_MAXes.
+*/
 
 /*
 Macros to combine two short words into a single
@@ -1012,10 +1020,10 @@ which uses these anyway.)
 
 #if ! defined(__GNUC__) || ! defined(__STG_GCC_REGS__)
 
-extern void        ASSIGN_DBL PROTO((W_ [], StgDouble));
-extern StgDouble    PK_DBL     PROTO((W_ []));
-extern void        ASSIGN_FLT PROTO((W_ [], StgFloat));
-extern StgFloat            PK_FLT     PROTO((W_ []));
+void       ASSIGN_DBL PROTO((W_ [], StgDouble));
+StgDouble   PK_DBL     PROTO((W_ []));
+void       ASSIGN_FLT PROTO((W_ [], StgFloat));
+StgFloat    PK_FLT     PROTO((W_ []));
 
 #else /* yes, its __GNUC__ && we really want them */
 
@@ -1036,6 +1044,12 @@ extern StgFloat      PK_FLT     PROTO((W_ []));
 
 #else /* ! sparc */
 
+/* (not very) forward prototype declarations */
+void       ASSIGN_DBL PROTO((W_ [], StgDouble));
+StgDouble   PK_DBL     PROTO((W_ []));
+void       ASSIGN_FLT PROTO((W_ [], StgFloat));
+StgFloat    PK_FLT     PROTO((W_ []));
+
 extern STG_INLINE
 void
 ASSIGN_DBL(W_ p_dest[], StgDouble src)
@@ -1291,14 +1305,14 @@ void newArrZh_init PROTO((P_ result, I_ n, P_ init));
 %************************************************************************
 
 \begin{code}
-ED_(Nil_closure);
+ED_(Prelude_Z91Z93_closure);
 
 #define newSynchVarZh(r, hp)                           \
 {                                                      \
   ALLOC_PRIM(MUTUPLE_HS,3,0,MUTUPLE_HS+3) /* ticky ticky */; \
   CC_ALLOC(CCC,MUTUPLE_HS+3,ARR_K); /* cc prof */      \
   SET_SVAR_HDR(hp,EmptySVar_info,CCC);                 \
-  SVAR_HEAD(hp) = SVAR_TAIL(hp) = SVAR_VALUE(hp) = Nil_closure;        \
+  SVAR_HEAD(hp) = SVAR_TAIL(hp) = SVAR_VALUE(hp) = Prelude_Z91Z93_closure;     \
   r = hp;                                              \
 }
 \end{code}
@@ -1311,17 +1325,17 @@ extern void Yield PROTO((W_));
 #define takeMVarZh(r, liveness, node)                  \
 {                                                      \
   while (INFO_PTR(node) != (W_) FullSVar_info) {       \
-    if (SVAR_HEAD(node) == Nil_closure)                \
+    if (SVAR_HEAD(node) == Prelude_Z91Z93_closure)             \
       SVAR_HEAD(node) = CurrentTSO;                    \
     else                                               \
       TSO_LINK(SVAR_TAIL(node)) = CurrentTSO;          \
-    TSO_LINK(CurrentTSO) = (P_) Nil_closure;           \
+    TSO_LINK(CurrentTSO) = (P_) Prelude_Z91Z93_closure;                \
     SVAR_TAIL(node) = CurrentTSO;                      \
     DO_YIELD(liveness << 1);                           \
   }                                                    \
   SET_INFO_PTR(node, EmptySVar_info);                  \
   r = SVAR_VALUE(node);                                        \
-  SVAR_VALUE(node) = Nil_closure;                      \
+  SVAR_VALUE(node) = Prelude_Z91Z93_closure;                           \
 }
 
 #else
@@ -1336,7 +1350,7 @@ extern void Yield PROTO((W_));
   }                                                    \
   SET_INFO_PTR(node, EmptySVar_info);                  \
   r = SVAR_VALUE(node);                                        \
-  SVAR_VALUE(node) = Nil_closure;                      \
+  SVAR_VALUE(node) = Prelude_Z91Z93_closure;                           \
 }
 
 #endif
@@ -1364,18 +1378,18 @@ extern void Yield PROTO((W_));
   SET_INFO_PTR(node, FullSVar_info);                   \
   SVAR_VALUE(node) = value;                            \
   tso = SVAR_HEAD(node);                               \
-  if (tso != (P_) Nil_closure) {                       \
+  if (tso != (P_) Prelude_Z91Z93_closure) {                            \
     if (DO_QP_PROF)                                    \
       STGCALL3(void,(void *, char *, P_, P_),QP_Event2,do_qp_prof > 1 ? "RA" : "RG",tso,CurrentTSO);   \
-    if (ThreadQueueHd == Nil_closure)                  \
+    if (ThreadQueueHd == Prelude_Z91Z93_closure)               \
       ThreadQueueHd = tso;                     \
     else                                               \
       TSO_LINK(ThreadQueueTl) = tso;           \
     ThreadQueueTl = tso;                               \
     SVAR_HEAD(node) = TSO_LINK(tso);                   \
-    TSO_LINK(tso) = (P_) Nil_closure;                  \
-    if(SVAR_HEAD(node) == (P_) Nil_closure)            \
-      SVAR_TAIL(node) = (P_) Nil_closure;              \
+    TSO_LINK(tso) = (P_) Prelude_Z91Z93_closure;                       \
+    if(SVAR_HEAD(node) == (P_) Prelude_Z91Z93_closure)                 \
+      SVAR_TAIL(node) = (P_) Prelude_Z91Z93_closure;           \
   }                                                    \
 }
 
@@ -1393,18 +1407,18 @@ extern void Yield PROTO((W_));
   SET_INFO_PTR(node, FullSVar_info);                   \
   SVAR_VALUE(node) = value;                            \
   tso = SVAR_HEAD(node);                               \
-  if (tso != (P_) Nil_closure) {                       \
+  if (tso != (P_) Prelude_Z91Z93_closure) {                            \
     if (DO_QP_PROF)                                    \
       STGCALL3(void,(void *, char *, P_, P_),QP_Event2,do_qp_prof > 1 ? "RA" : "RG",tso,CurrentTSO);   \
-    if (RunnableThreadsHd == Nil_closure)              \
+    if (RunnableThreadsHd == Prelude_Z91Z93_closure)                   \
       RunnableThreadsHd = tso;                         \
     else                                               \
       TSO_LINK(RunnableThreadsTl) = tso;               \
     RunnableThreadsTl = tso;                           \
     SVAR_HEAD(node) = TSO_LINK(tso);                   \
-    TSO_LINK(tso) = (P_) Nil_closure;                  \
-    if(SVAR_HEAD(node) == (P_) Nil_closure)            \
-      SVAR_TAIL(node) = (P_) Nil_closure;              \
+    TSO_LINK(tso) = (P_) Prelude_Z91Z93_closure;                       \
+    if(SVAR_HEAD(node) == (P_) Prelude_Z91Z93_closure)                 \
+      SVAR_TAIL(node) = (P_) Prelude_Z91Z93_closure;           \
   }                                                    \
 }
 
@@ -1434,11 +1448,11 @@ extern void Yield PROTO((W_));
 #define readIVarZh(r, liveness, node)                  \
 {                                                      \
   if (INFO_PTR(node) != (W_) ImMutArrayOfPtrs_info) {  \
-    if (SVAR_HEAD(node) == Nil_closure)                \
+    if (SVAR_HEAD(node) == Prelude_Z91Z93_closure)             \
       SVAR_HEAD(node) = CurrentTSO;                    \
     else                                               \
       TSO_LINK(SVAR_TAIL(node)) = CurrentTSO;          \
-    TSO_LINK(CurrentTSO) = (P_) Nil_closure;           \
+    TSO_LINK(CurrentTSO) = (P_) Prelude_Z91Z93_closure;                \
     SVAR_TAIL(node) = CurrentTSO;                      \
     DO_YIELD(liveness << 1);                           \
   }                                                    \
@@ -1481,12 +1495,12 @@ extern void Yield PROTO((W_));
     EXIT(EXIT_FAILURE);                                        \
   }                                                    \
   tso = SVAR_HEAD(node);                               \
-  if (tso != (P_) Nil_closure) {                       \
-    if (ThreadQueueHd == Nil_closure)                  \
+  if (tso != (P_) Prelude_Z91Z93_closure) {                            \
+    if (ThreadQueueHd == Prelude_Z91Z93_closure)               \
       ThreadQueueHd = tso;                     \
     else                                               \
       TSO_LINK(ThreadQueueTl) = tso;           \
-    while(TSO_LINK(tso) != Nil_closure) {              \
+    while(TSO_LINK(tso) != Prelude_Z91Z93_closure) {                   \
       if (DO_QP_PROF)                                  \
         STGCALL3(void,(void *, char *, P_, P_),QP_Event2,do_qp_prof > 1 ? "RA" : "RG",tso,CurrentTSO); \
       tso = TSO_LINK(tso);                             \
@@ -1513,12 +1527,12 @@ extern void Yield PROTO((W_));
     EXIT(EXIT_FAILURE);                                        \
   }                                                    \
   tso = SVAR_HEAD(node);                               \
-  if (tso != (P_) Nil_closure) {                       \
-    if (RunnableThreadsHd == Nil_closure)              \
+  if (tso != (P_) Prelude_Z91Z93_closure) {                            \
+    if (RunnableThreadsHd == Prelude_Z91Z93_closure)                   \
       RunnableThreadsHd = tso;                         \
     else                                               \
       TSO_LINK(RunnableThreadsTl) = tso;               \
-    while(TSO_LINK(tso) != Nil_closure) {              \
+    while(TSO_LINK(tso) != Prelude_Z91Z93_closure) {                   \
       if (DO_QP_PROF)                                  \
         STGCALL3(void,(void *, char *, P_, P_),QP_Event2,do_qp_prof > 1 ? "RA" : "RG",tso,CurrentTSO); \
       tso = TSO_LINK(tso);                             \
@@ -1568,12 +1582,12 @@ extern void Yield PROTO((W_));
 
 #define delayZh(liveness, us)                          \
   {                                                    \
-    if (WaitingThreadsTl == Nil_closure)               \
+    if (WaitingThreadsTl == Prelude_Z91Z93_closure)            \
       WaitingThreadsHd = CurrentTSO;                   \
     else                                               \
       TSO_LINK(WaitingThreadsTl) = CurrentTSO;         \
     WaitingThreadsTl = CurrentTSO;                     \
-    TSO_LINK(CurrentTSO) = Nil_closure;                        \
+    TSO_LINK(CurrentTSO) = Prelude_Z91Z93_closure;                     \
     TSO_EVENT(CurrentTSO) = (W_) ((us) < 1 ? 1 : (us)); \
     DO_YIELD(liveness << 1);                           \
   }
@@ -1593,24 +1607,55 @@ extern void Yield PROTO((W_));
 
 /* ToDo: something for GRAN */
 
-#define waitZh(liveness, fd)                           \
+#define waitReadZh(liveness, fd)                       \
   {                                                    \
-    if (WaitingThreadsTl == Nil_closure)               \
+    if (WaitingThreadsTl == Prelude_Z91Z93_closure)            \
       WaitingThreadsHd = CurrentTSO;                   \
     else                                               \
       TSO_LINK(WaitingThreadsTl) = CurrentTSO;         \
     WaitingThreadsTl = CurrentTSO;                     \
-    TSO_LINK(CurrentTSO) = Nil_closure;                        \
+    TSO_LINK(CurrentTSO) = Prelude_Z91Z93_closure;                     \
     TSO_EVENT(CurrentTSO) = (W_) (-(fd));              \
     DO_YIELD(liveness << 1);                           \
   }
 
 #else
 
-#define waitZh(liveness, fd)                           \
+#define waitReadZh(liveness, fd)                       \
+  {                                                    \
+    fflush(stdout);                                    \
+    fprintf(stderr, "waitRead#: unthreaded build.\n");         \
+    EXIT(EXIT_FAILURE);                                        \
+  }
+
+#endif
+
+#ifdef CONCURRENT
+
+/* ToDo: something for GRAN */
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif  HAVE_SYS_TYPES_H */
+
+#define waitWriteZh(liveness, fd)                      \
+  {                                                    \
+    if (WaitingThreadsTl == Prelude_Z91Z93_closure)            \
+      WaitingThreadsHd = CurrentTSO;                   \
+    else                                               \
+      TSO_LINK(WaitingThreadsTl) = CurrentTSO;         \
+    WaitingThreadsTl = CurrentTSO;                     \
+    TSO_LINK(CurrentTSO) = Prelude_Z91Z93_closure;                     \
+    TSO_EVENT(CurrentTSO) = (W_) (-(fd+FD_SETSIZE));   \
+    DO_YIELD(liveness << 1);                           \
+  }
+
+#else
+
+#define waitWriteZh(liveness, fd)                      \
   {                                                    \
     fflush(stdout);                                    \
-    fprintf(stderr, "wait#: unthreaded build.\n");     \
+    fprintf(stderr, "waitWrite#: unthreaded build.\n"); \
     EXIT(EXIT_FAILURE);                                        \
   }
 
@@ -1806,6 +1851,7 @@ do {                                                                  \
                                                                    \
   newSP = SPT_POP(StorageMgrInfo.StablePointerTable);              \
   SPT_SPTR(StorageMgrInfo.StablePointerTable, newSP) = unstablePtr; \
+  CHECK_SPT_CLOSURE( StorageMgrInfo.StablePointerTable );           \
   stablePtr = newSP;                                               \
 } while (0)
 
@@ -1864,53 +1910,100 @@ Anything with tag >= 0 is in WHNF, so we discard it.
 \begin{code}
 #ifdef CONCURRENT
 
-ED_(Nil_closure);
+ED_(Prelude_Z91Z93_closure);
 ED_(True_closure);
 
 #if defined(GRAN)
-#define parZh(r,hp,node,rest)                          \
-       PARZh(r,hp,node,rest,0,0)
+#define parZh(r,node)                          \
+       PARZh(r,node,1,0,0,0,0,0)
+
+#define parAtZh(r,node,where,identifier,gran_info,size_info,par_info,rest) \
+       parATZh(r,node,where,identifier,gran_info,size_info,par_info,rest,1)
 
-#define parAtZh(r,hp,node,where,identifier,rest)       \
-       parATZh(r,hp,node,where,identifier,rest,1)
+#define parAtAbsZh(r,node,proc,identifier,gran_info,size_info,par_info,rest) \
+       parATZh(r,node,proc,identifier,gran_info,size_info,par_info,rest,2)
 
-#define parAtForNowZh(r,hp,node,where,identifier,rest) \
-       parATZh(r,hp,node,where,identifier,rest,0)
+#define parAtRelZh(r,node,proc,identifier,gran_info,size_info,par_info,rest) \
+       parATZh(r,node,proc,identifier,gran_info,size_info,par_info,rest,3)
 
-#define parATZh(r,hp,node,where,identifier,rest,local) \
+#define parAtForNowZh(r,node,where,identifier,gran_info,size_info,par_info,rest)       \
+       parATZh(r,node,where,identifier,gran_info,size_info,par_info,rest,0)
+
+#define parATZh(r,node,where,identifier,gran_info,size_info,par_info,rest,local)       \
 {                                                      \
   sparkq result;                                               \
   if (SHOULD_SPARK(node)) {                            \
-    result = NewSpark((P_)node,identifier,local);      \
-    SAFESTGCALL3(void,(W_),GranSimSparkAt,result,where,identifier);    \
+    SaveAllStgRegs();                                  \
+    { sparkq result;                                           \
+      result = NewSpark((P_)node,identifier,gran_info,size_info,par_info,local);       \
+      if (local==2) {         /* special case for parAtAbs */   \
+        GranSimSparkAtAbs(result,(I_)where,identifier);\
+      } else if (local==3) {  /* special case for parAtRel */   \
+        GranSimSparkAtAbs(result,(I_)(CurrentProc+where),identifier);  \
+      } else {       \
+        GranSimSparkAt(result,where,identifier);       \
+      }        \
+      context_switch = 1;                              \
+    }                                                   \
+    RestoreAllStgRegs();                               \
   } else if (do_qp_prof) {                             \
     I_ tid = threadId++;                               \
     SAFESTGCALL2(void,(I_, P_),QP_Event0,tid,node);    \
   }                                                    \
-  r = (rest);                                          \
+  r = 1; /* return code for successful spark -- HWL */ \
 }
 
-#define parLocalZh(r,hp,node,identifier,rest)          \
-       PARZh(r,hp,node,rest,identifier,1)
+#define parLocalZh(r,node,identifier,gran_info,size_info,par_info,rest)        \
+       PARZh(r,node,rest,identifier,gran_info,size_info,par_info,1)
+
+#define parGlobalZh(r,node,identifier,gran_info,size_info,par_info,rest) \
+       PARZh(r,node,rest,identifier,gran_info,size_info,par_info,0)
 
-#define parGlobalZh(r,hp,node,identifier,rest)         \
-       PARZh(r,hp,node,rest,identifier,0)
+#if 1
 
-#define PARZh(r,hp,node,rest,identifier,local)         \
+#define PARZh(r,node,rest,identifier,gran_info,size_info,par_info,local) \
+{                                                      \
+  if (SHOULD_SPARK(node)) {                            \
+    SaveAllStgRegs();                                  \
+    { sparkq result;                                           \
+      result = NewSpark((P_)node,identifier,gran_info,size_info,par_info,local);\
+      add_to_spark_queue(result);                              \
+      GranSimSpark(local,(P_)node);                                    \
+      context_switch = 1;                              \
+    }                                                   \
+    RestoreAllStgRegs();                               \
+  } else if (do_qp_prof) {                             \
+    I_ tid = threadId++;                               \
+    SAFESTGCALL2(void,(I_, P_),QP_Event0,tid,node);    \
+  }                                                    \
+  r = 1; /* return code for successful spark -- HWL */ \
+}
+
+#else
+
+#define PARZh(r,node,rest,identifier,gran_info,size_info,par_info,local) \
 {                                                      \
   sparkq result;                                               \
   if (SHOULD_SPARK(node)) {                            \
-    result = NewSpark((P_)node,identifier,local);      \
+    result = NewSpark((P_)node,identifier,gran_info,size_info,par_info,local);\
     ADD_TO_SPARK_QUEUE(result);                                \
     SAFESTGCALL2(void,(W_),GranSimSpark,local,(P_)node);       \
-    /* context_switch = 1;  not needed any more -- HWL */                                      \
+    /* context_switch = 1;  not needed any more -- HWL */      \
   } else if (do_qp_prof) {                             \
     I_ tid = threadId++;                               \
     SAFESTGCALL2(void,(I_, P_),QP_Event0,tid,node);    \
   }                                                    \
-  r = (rest);                                          \
+  r = 1; /* return code for successful spark -- HWL */ \
 }
 
+#endif 
+
+#define copyableZh(r,node)                             \
+  /* copyable not yet implemented!! */
+
+#define noFollowZh(r,node)                             \
+  /* noFollow not yet implemented!! */
+
 #else  /* !GRAN */
 
 extern I_ required_thread_count;
@@ -1958,6 +2051,7 @@ extern I_ required_thread_count;
   r = 1; /* Should not be necessary */                 \
 }
 
+#endif  /* GRAN */ 
 \end{code}
 
 The following seq# code should only be used in unoptimized code.
@@ -1979,8 +2073,8 @@ ED_RO_(vtbl_seq);
 #define seqZh(r,liveness,node)             \
   ({                                       \
     __label__ cont;                        \
-    STK_CHK(liveness,0,2,0,0,0,0);         \
-    SpB -= BREL(2);                        \
+    /* STK_CHK(liveness,0,2,0,0,0,0); */    \
+    /* SpB -= BREL(2); */                  \
     SpB[BREL(0)] = (W_) RetReg;                    \
     SpB[BREL(1)] = (W_) &&cont;                    \
     RetReg = (StgRetAddr) vtbl_seq;        \
@@ -1992,23 +2086,27 @@ ED_RO_(vtbl_seq);
     r = 1; /* Should be unnecessary */     \
   })
 
-#endif  /* GRAN */ 
 #endif /* CONCURRENT */
 \end{code}
 
 %************************************************************************
 %*                                                                     *
-\subsubsection[StgMacros-malloc-ptrs]{Malloc Pointers}
+\subsubsection[StgMacros-foreign-objects]{Foreign Objects}
 %*                                                                     *
 %************************************************************************
 
-This macro is used to construct a MallocPtr on the heap after a ccall.
-Since MallocPtr's are like arrays in many ways, this is heavily based
-on the stuff for arrays above.
+[Based on previous MallocPtr comments -- SOF]
+
+This macro is used to construct a ForeignObj on the heap.
 
 What this does is plug the pointer (which will be in a local
-variable), into a fresh heap object and then sets a result (which will
-be a register) to point to the fresh heap object.
+variable) together with its finalising/free routine, into a fresh heap
+object and then sets a result (which will be a register) to point
+to the fresh heap object.
+
+To accommodate per-object finalisation, augment the macro with a
+finalisation routine argument. Nothing spectacular, just plug the
+pointer to the routine into the ForeignObj -- SOF 4/96
 
 Question: what's this "SET_ACTIVITY" stuff - should I be doing this
 too?  (It's if you want to use the SPAT profiling tools to
@@ -2016,42 +2114,45 @@ characterize program behavior by ``activity'' -- tail-calling,
 heap-checking, etc. -- see Ticky.lh.  It is quite specialized.
 WDP 95/1)
 
+(Swapped first two arguments to make it come into line with what appears
+to be `standard' format, return register then liveness mask. -- SOF 4/96)
+
 \begin{code}
 #ifndef PAR
 
-StgInt eqMallocPtr PROTO((StgMallocPtr p1, StgMallocPtr p2));
-void FreeMallocPtr PROTO((StgMallocPtr mp));
+StgInt eqForeignObj PROTO((StgForeignObj p1, StgForeignObj p2));
 
-#define constructMallocPtr(liveness, r, mptr)          \
-do {                                                   \
-  P_ result;                                           \
-                                                       \
-  HEAP_CHK(liveness, _FHS + MallocPtr_SIZE,0);         \
-  CC_ALLOC(CCC,_FHS + MallocPtr_SIZE,MallocPtr_K); /* cc prof */   \
+#define makeForeignObjZh(r, liveness, mptr, finalise)    \
+do {                                                    \
+  P_ result;                                            \
+                                                        \
+  HEAP_CHK((W_)liveness, _FHS + ForeignObj_SIZE,0);             \
+  CC_ALLOC(CCC,_FHS + ForeignObj_SIZE,ForeignObj_K); /* cc prof */   \
                                                                   \
-  result = Hp + 1 - (_FHS + MallocPtr_SIZE);                      \
-  SET_MallocPtr_HDR(result,MallocPtr_info,CCC,_FHS + MallocPtr_SIZE,0); \
-  MallocPtr_CLOSURE_DATA(result) = mptr;                          \
-  MallocPtr_CLOSURE_LINK(result) = StorageMgrInfo.MallocPtrList;   \
-  StorageMgrInfo.MallocPtrList = result;                          \
+  result = Hp + 1 - (_FHS + ForeignObj_SIZE);                     \
+  SET_ForeignObj_HDR(result,ForeignObj_info,CCC,_FHS + ForeignObj_SIZE,0); \
+  ForeignObj_CLOSURE_DATA(result)      = (P_)mptr;                        \
+  ForeignObj_CLOSURE_FINALISER(result) = (P_)finalise;                    \
+  ForeignObj_CLOSURE_LINK(result) = StorageMgrInfo.ForeignObjList; \
+  StorageMgrInfo.ForeignObjList = result;                         \
                                                        \
 /*                                                     \
-  printf("DEBUG: MallocPtr(0x%x) = <0x%x, 0x%x, 0x%x, 0x%x>\n",        \
+  printf("DEBUG: ForeignObj(0x%x) = <0x%x, 0x%x, 0x%x, 0x%x>\n",       \
       result,                                          \
       result[0],result[1],                             \
       result[2],result[3]);                            \
 */                                                     \
-  CHECK_MallocPtr_CLOSURE( result );                   \
-  VALIDATE_MallocPtrList( StorageMgrInfo.MallocPtrList ); \
+  CHECK_ForeignObj_CLOSURE( result );                  \
+  VALIDATE_ForeignObjList( StorageMgrInfo.ForeignObjList ); \
                                                        \
   (r) = (P_) result;                                   \
 } while (0)
 
 #else
-#define constructMallocPtr(liveness, r, mptr)                      \
+#define makeForeignObjZh(r, liveness, mptr, finalise)              \
 do {                                                               \
     fflush(stdout);                                                \
-    fprintf(stderr, "constructMallocPtr: no malloc pointer support.\n");\
+    fprintf(stderr, "makeForeignObj#: no foreign object support.\n");\
     EXIT(EXIT_FAILURE);                                                    \
 } while(0)
 
index 9a8dda1..24783ae 100644 (file)
@@ -25,7 +25,7 @@ StgFloat      &       float                           \\
 StgDouble      &       double                          \\
 StgChar                &       unsigned char                   \\\hline
 StgStablePtr   &       long                            \\
-StgMallocPtr   &       (long *)                        \\
+StgForeignObj  &       (long *)                        \\
 \end{tabular}
 %partain:\end{center}
 
@@ -112,8 +112,8 @@ typedef StgChar             *StgByteArray;
 typedef StgByteArray   B_;
 
 typedef I_             StgStablePtr;   /* Index into Stable Pointer Table */
-typedef P_             StgMallocPtr;   /* (Probably) Pointer to object in C Heap */
-/* On any architecture, StgMallocPtr should be big enough to hold
+typedef P_             StgForeignObj;  /* (Probably) Pointer to object in C Heap */
+/* On any architecture, StgForeignObj should be big enough to hold
    the largest possible pointer. */
 
 /* These are used to pass the do_full_collection flag to RealPerformGC
index 7236d7d..4b9a722 100644 (file)
@@ -9,18 +9,23 @@
 \end{code}
 
 \begin{code}
-#ifndef GRAN 
-#define GRAN_ALLOC_HEAP(n,liveness)                    /* nothing */
-#define GRAN_UNALLOC_HEAP(n,liveness)                  /* nothing */
-#define GRAN_FETCH()                                   /* nothing */
-#define GRAN_FETCH_AND_RESCHEDULE(liveness)            /* nothing */
-#define GRAN_RESCHEDULE(liveness, reenter)             /* nothing */
-#define GRAN_EXEC(arith,branch,loads,stores,floats)    /* nothing */
-#define GRAN_SPARK()                                   /* nothing */
-#endif
-\end{code}
+#if defined(GRAN)
+
+#define sparkq sparkq 
+#define TYPE_OF_SPARK    struct spark
+#define TYPE_OF_SPARK_PTR sparkq
+#define SIZE_OF_SPARK    (sizeof(TYPE_OF_SPARK))
+
+typedef struct spark
+{
+  struct spark *prev, *next;
+  P_ node;
+  I_ name, global;
+  I_ gran_info;
+} *sparkq;
+
+#endif 
 
-\begin{code}
 #ifndef CONCURRENT
 
 #define OR_CONTEXT_SWITCH
@@ -54,10 +59,15 @@ extern I_ context_switch;                   /* Flag set by signal handler */
 #define ADVISORY_POOL  1
 #define SPARK_POOLS    2
 
-#ifndef GRAN
+#if !defined(GRAN) 
 
-extern PP_ PendingSparksBase[SPARK_POOLS], PendingSparksLim[SPARK_POOLS];
-extern PP_ PendingSparksHd[SPARK_POOLS], PendingSparksTl[SPARK_POOLS];
+#define TYPE_OF_SPARK    PP_
+#define SIZE_OF_SPARK    (sizeof(TYPE_OF_SPARK))
+
+extern TYPE_OF_SPARK PendingSparksBase[SPARK_POOLS], 
+                     PendingSparksLim[SPARK_POOLS];
+extern TYPE_OF_SPARK PendingSparksHd[SPARK_POOLS], 
+                     PendingSparksTl[SPARK_POOLS];
 
 extern I_ SparkLimit[SPARK_POOLS];
 
@@ -70,7 +80,10 @@ IF_RTS(extern void AwaitEvent(I_);)
 
 #else /* GRAN */
 
-extern sparkq PendingSparksHd[][SPARK_POOLS], PendingSparksTl[][SPARK_POOLS];
+extern TYPE_OF_SPARK_PTR PendingSparksBase[][SPARK_POOLS], 
+                         PendingSparksLim[][SPARK_POOLS];
+extern TYPE_OF_SPARK_PTR PendingSparksHd[][SPARK_POOLS], 
+                         PendingSparksTl[][SPARK_POOLS];
 extern P_ RunnableThreadsHd[], RunnableThreadsTl[],
           WaitThreadsHd[], WaitThreadsTl[];
 
@@ -85,7 +98,7 @@ extern P_ RunnableThreadsHd[], RunnableThreadsTl[],
 
 IF_RTS(extern void PruneSparks(STG_NO_ARGS);)
 
-#ifdef GRAN
+#if defined(GRAN)
 
 /* Codes that can be used as params for ReSchedule */
 /* I distinguish them from the values 0/1 in the -UGRAN setup for security */
@@ -94,177 +107,23 @@ IF_RTS(extern void PruneSparks(STG_NO_ARGS);)
 #define SAME_THREAD    11
 #define NEW_THREAD     SAME_THREAD
 #define CHANGE_THREAD  13
+#define END_OF_WORLD    14
 
-#define MAX_PROC (BITS_IN(W_))                 /* Maximum number of PEs that can be simulated */
-extern W_ max_proc;
-
-extern W_ IdleProcs, Idlers; 
-
-extern unsigned CurrentProc;
-extern W_ CurrentTime[];
 extern W_ SparksAvail, SurplusThreads;
 
-/* Processor numbers to bitmasks and vice-versa */
-#define MainProc            0
-
-#define PE_NUMBER(n)          (1l << (long)n)
-#define ThisPE               PE_NUMBER(CurrentProc)
-#define MainPE               PE_NUMBER(MainProc)
-
-#define IS_LOCAL_TO(ga,proc)  ((1l << (long) proc) & ga)
-
-/* These constants should eventually be program parameters */
-
-/* Communication Cost Model (EDS-like), max_proc > 2. */
-
-#define LATENCY                           1000 /* Latency for single packet */
-#define ADDITIONAL_LATENCY         100 /* Latency for additional packets */
-#define BASICBLOCKTIME              10
-#define FETCHTIME              (LATENCY*2+MSGUNPACKTIME)
-#define LOCALUNBLOCKTIME            10
-#define GLOBALUNBLOCKTIME      (LATENCY+MSGUNPACKTIME)
-
-extern W_ gran_latency, gran_additional_latency, gran_fetchtime, 
-          gran_lunblocktime, gran_gunblocktime;
-
-#define        MSGPACKTIME                  0  /* Cost of creating a packet */
-#define        MSGUNPACKTIME                0  /* Cost of receiving a packet */
-
-extern W_ gran_mpacktime, gran_mtidytime, gran_munpacktime;
-
-/* Thread cost model */
-#define THREADCREATETIME          (25+THREADSCHEDULETIME)
-#define THREADQUEUETIME                    12  /* Cost of adding a thread to the running/runnable queue */
-#define THREADDESCHEDULETIME       75  /* Cost of descheduling a thread */
-#define THREADSCHEDULETIME         75  /* Cost of scheduling a thread */
-#define THREADCONTEXTSWITCHTIME            (THREADDESCHEDULETIME+THREADSCHEDULETIME)
-
-extern W_ gran_threadcreatetime, gran_threadqueuetime, 
-          gran_threadscheduletime, gran_threaddescheduletime, 
-          gran_threadcontextswitchtime;
-
-/* Instruction Cost model (SPARC, including cache misses) */
-#define ARITH_COST                1
-#define BRANCH_COST               2
-#define LOAD_COST                 4
-#define STORE_COST                4
-#define FLOAT_COST                1 /* ? */
-
-extern W_ gran_arith_cost, gran_branch_cost, 
-          gran_load_cost, gran_store_cost, gran_float_cost,
-          gran_heapalloc_cost;
-
-/* Miscellaneous Parameters */
-extern I_ DoFairSchedule;
-extern I_ DoReScheduleOnFetch;
-extern I_ SimplifiedFetch;
-extern I_ DoStealThreadsFirst;
-extern I_ DoAlwaysCreateThreads;
-extern I_ DoThreadMigration;
-extern I_ DoGUMMFetching;
-extern I_ FetchStrategy;
-extern I_ PreferSparksOfLocalNodes;
-/* These come from debug options -bD? */
-extern I_ NoForward;
-extern I_ PrintFetchMisses, fetch_misses;
-#if defined(COUNT)
-extern I_ nUPDs, nUPDs_old, nUPDs_new, nUPDs_BQ, nPAPs, BQ_lens;
-#endif
-
-extern I_ no_gr_profile;
-extern I_ do_sp_profile;
-
-extern I_ NeedToReSchedule;
-
-extern void GranSimAllocate                PROTO((I_, P_, W_));
-extern void GranSimUnAllocate              PROTO((I_, P_, W_));
-extern I_   GranSimFetch                   PROTO((P_));
-extern void GranSimExec                    PROTO((W_,W_,W_,W_,W_));
-extern void GranSimSpark                   PROTO((W_,P_));
-extern void GranSimBlock                   (STG_NO_ARGS);
-extern void PerformReschedule              PROTO((W_, W_));
-
-#if 0   /* 'ngo Dochmey */
-
-#define GRAN_ALLOC_HEAP(n,liveness)       STGCALL3(void,(),GranSimAllocate,n,0,0)
-#define GRAN_UNALLOC_HEAP(n,liveness)     STGCALL3(void,(),GranSimUnallocate,n,0,0)
-
-#define GRAN_FETCH()                      STGCALL1(I_,(),GranSimFetch,Node)
-
-#define GRAN_FETCH_AND_RESCHEDULE(liveness_mask)       \
-       do { if(liveness_mask&LIVENESS_R1)  \
-             STGCALL1(I_,(),GranSimFetch,Node); \
-            GRAN_RESCHEDULE(liveness_mask,1);  \
-          } while(0)
-
-#define GRAN_RESCHEDULE(liveness_mask,reenter) \
-        STGCALL2_GC(void,(),     \
-                PerformReschedule,liveness_mask,reenter)
-
-#define THREAD_CONTEXT_SWITCH(liveness_mask,reenter)   \
-        do { \
-       if (context_switch /* OR_INTERVAL_EXPIRED */) { \
-          GRAN_RESCHEDULE(liveness_mask,reenter); \
-        } }while(0)
-
-#define GRAN_EXEC(arith,branch,load,store,floats)      \
-                                       STGCALL5(void,(),GranSimExec,arith,branch,load,store,floats)
-
-
-#else  /* 1 */ /* chu' Dochmey */
-
-#define GRAN_ALLOC_HEAP(n,liveness)       \
-       SaveAllStgRegs();                  \
-       GranSimAllocate(n,0,0);            \
-       RestoreAllStgRegs();
-
-#define GRAN_UNALLOC_HEAP(n,liveness)     \
-       SaveAllStgRegs();                  \
-       GranSimUnallocate(n,0,0);          \
-       RestoreAllStgRegs();
-
-#define GRAN_FETCH()                      \
-       SaveAllStgRegs();                  \
-       GranSimFetch(Node);                \
-       RestoreAllStgRegs();
-
-#define GRAN_FETCH_AND_RESCHEDULE(liveness_mask)       \
-       do { if(liveness_mask&LIVENESS_R1)              \
-            SaveAllStgRegs();                  \
-             GranSimFetch(Node);                       \
-            RestoreAllStgRegs();                       \
-            GRAN_RESCHEDULE(liveness_mask,1);          \
-          } while(0)
-
-#define GRAN_RESCHEDULE(liveness_mask,reenter) \
-        PerformReschedule_wrapper(liveness_mask,reenter)
-
-#define THREAD_CONTEXT_SWITCH(liveness_mask,reenter)   \
-        do { \
-       if (context_switch /* OR_INTERVAL_EXPIRED */) { \
-          GRAN_RESCHEDULE(liveness_mask,reenter); \
-        } }while(0)
-
-#define GRAN_EXEC(arith,branch,load,store,floats)      \
-       SaveAllStgRegs();                               \
-       GranSimExec(arith,branch,load,store,floats);    \
-       RestoreAllStgRegs();
-
-#endif
-       
+extern W_ CurrentTime[];
+extern I_ OutstandingFetches[], OutstandingFishes[];
+extern enum proc_status procStatus[];
 
-#define ADD_TO_SPARK_QUEUE(spark)                      \
-    SPARK_NEXT(spark) = NULL;                          \
-    SPARK_PREV(spark) = PendingSparksTl[CurrentProc][ADVISORY_POOL];   \
-    if (PendingSparksHd[CurrentProc][ADVISORY_POOL] == NULL)           \
-       PendingSparksHd[CurrentProc][ADVISORY_POOL] = spark;            \
-    else                                               \
-       SPARK_NEXT(PendingSparksTl[CurrentProc][ADVISORY_POOL]) = spark;        \
-    PendingSparksTl[CurrentProc][ADVISORY_POOL] = spark;               \
+#  if defined(GRAN_CHECK) && defined(GRAN) /* Just for testing */
+# define FETCH_MASK_TSO  0x08000000      /* only bits 0, 1, 2 should be used */
+                                        /* normally */
+extern P_ BlockedOnFetch[];
+#  endif
 
 #endif     /* GRAN */
 
-extern P_ CurrentTSO;                          /* thread state object now in use */
+extern P_ CurrentTSO;                   /* thread state object now in use */
 
 extern P_ AvailableStack;
 extern P_ AvailableTSO;
@@ -272,13 +131,29 @@ extern P_ AvailableTSO;
 extern I_ threadId;
 
 void ScheduleThreads PROTO((P_ topClosure));
+
 #if defined(GRAN)
+#define OLD_SPARKNAME_MASK        0xffff0000
+#define NEW_SPARKNAME_MASK        0x0000ffff
+
 void ReSchedule PROTO((int what_next)) STG_NORETURN;
-#else
+void add_to_spark_queue PROTO((sparkq));
+int set_sparkname PROTO((P_, int));
+int reset_sparkname PROTO((P_)); 
+I_ spark_queue_len PROTO((PROC, I_));
+sparkq delete_from_spark_queue PROTO((sparkq, sparkq));
+I_ thread_queue_len PROTO((PROC));
+void DisposeSparkQ PROTO((sparkq));
+
+#else /* !GRAN */
+
 void ReSchedule PROTO((int again)) STG_NORETURN;
+
 #endif
+
 void EndThread(STG_NO_ARGS) STG_NORETURN;
 
+/* ToDo: Check if these are still needed -- HWL */
 void QP_Event0 PROTO((I_, P_));
 void QP_Event1 PROTO((char *, P_));
 void QP_Event2 PROTO((char *, P_, P_));
@@ -331,7 +206,8 @@ table for those values).
 #endif
 
 #if defined(GRAN) || defined(PAR)
-#define TSO_GRAN_WORDS 15
+           /* do we really need a whole statistics buffer in PAR setup? HWL*/
+#define TSO_GRAN_WORDS 17
 #else
 #define TSO_GRAN_WORDS 0
 #endif
@@ -385,6 +261,8 @@ table for those values).
 #define TSO_GLOBALSPARKS_LOCN          (TSO_GRAN_START + 12)
 #define TSO_LOCALSPARKS_LOCN           (TSO_GRAN_START + 13)
 #define TSO_QUEUE_LOCN         (TSO_GRAN_START + 14)
+#define TSO_PRI_LOCN           (TSO_GRAN_START + 15)
+#define TSO_CLOCK_LOCN         (TSO_GRAN_START + 16)
 #endif
 
 #define TSO_LINK(closure)          (((PP_)closure)[TSO_LINK_LOCN])
@@ -416,6 +294,9 @@ table for those values).
 #define TSO_GLOBALSPARKS(closure)   (((P_)closure)[TSO_GLOBALSPARKS_LOCN])
 #define TSO_LOCALSPARKS(closure)    (((P_)closure)[TSO_LOCALSPARKS_LOCN])
 #define TSO_QUEUE(closure)         (((P_)closure)[TSO_QUEUE_LOCN])
+#define TSO_PRI(closure)           (((P_)closure)[TSO_PRI_LOCN])
+/* TSO_CLOCK is only needed in GrAnSim-Light */
+#define TSO_CLOCK(closure)         (((P_)closure)[TSO_CLOCK_LOCN])
 
 #define TSO_INTERNAL_PTR(closure)          \
   ((STGRegisterTable *)(((W_)(((P_)closure) \
@@ -451,6 +332,7 @@ Here are the various queues for GrAnSim-type events.
 #define Q_RUNNABLE  'A'
 #define Q_BLOCKED   'R'
 #define Q_FETCHING  'Y'
+#define Q_MIGRATING 'B'
 \end{code}
 
 %************************************************************************
@@ -472,23 +354,33 @@ rtsBool Spark PROTO((P_ closure, rtsBool required));
 #ifdef GRAN   /* For GrAnSim sparks are currently mallocated -- HWL */
 
 void DisposeSpark PROTO((sparkq spark));
+sparkq NewSpark PROTO((P_,I_,I_,I_,I_,I_));
+
+/* # define MAX_EVENTS         1000 */  /* For GC Roots Purposes */
+# define MAX_SPARKS            0        /* i.e. infinite */
 
-# define MAX_SPARKS            2000  /* For GC Roots Purposes */
-# if defined(GRAN_TNG)
-extern sparkq NewSpark         PROTO((P_,I_,I_,I_));
-# else /* !GRAN_TNG */
-extern sparkq NewSpark         PROTO((P_,I_,I_));
-# endif  /* GRAN_TNG */
+#if defined(GRAN_JSM_SPARKS)
+/* spark is a pointer into some sparkq (which is for JSM sparls just an 
+   array of (struct sparks) */
 
+# define SPARK_PREV(spark)     { fprintf(stderr,"Error: SPARK_PREV not supported for JSM sparks") \
+                                  EXIT(EXIT_FAILURE); }
+/* NB: SPARK_NEXT may only be used as a rhs but NOT as a lhs */
+# define SPARK_NEXT(spark)     (spark++)
+# define SPARK_NODE(spark)     (P_)(spark->node)
+# define SPARK_NAME(spark)     (spark->name)
+# define SPARK_GRAN_INFO(spark) (spark->gran_info)
+# define SPARK_GLOBAL(spark)   (spark->global)
+# define SPARK_EXPORTED(spark) (SPARK_GLOBAL(spark) > 1)
+#else
 # define SPARK_PREV(spark)     (spark->prev)
 # define SPARK_NEXT(spark)     (sparkq)(spark->next)
-# define SPARK_NODE(spark)     (P_)(spark->node)
+# define SPARK_NODE(spark)     (spark->node)
 # define SPARK_NAME(spark)     (spark->name)
-# if defined(GRAN_TNG)
-#  define SPARK_GRAN_INFO(spark) (spark->gran_info)
-# endif  /* GRAN_TNG */
+# define SPARK_GRAN_INFO(spark) (spark->gran_info)
 # define SPARK_GLOBAL(spark)   (spark->global)
 # define SPARK_EXPORTED(spark) (SPARK_GLOBAL(spark) > 1)
+#endif
 
 #endif      /* GRAN */
 \end{code}
index 37bc54c..3c4c682 100644 (file)
 /* Define if you have the <termios.h> header file.  */
 #undef HAVE_TERMIOS_H
 
-/* Define if you have the <types.h> header file.  */
+/* Define if you have the <time.h> header file.  */
 #undef HAVE_TIME_H
 
 /* Define if you have the <types.h> header file.  */
index 5e7351f..53152cb 100644 (file)
 #include <ctype.h>
 #include <unistd.h>
 
+/* acceptSocket.lc */
+StgInt acceptSocket PROTO((StgInt, StgAddr, StgAddr));
+
+/* bindSocket.lc */
+StgInt bindSocket PROTO((StgInt, StgAddr, StgInt, StgInt));
+
+/* connectSocket.lc */
+StgInt connectSocket PROTO((StgInt, StgAddr, StgInt, StgInt));
+
+/* createSocket.lc */
+StgInt createSocket PROTO((StgInt, StgInt, StgInt));
+
+/* getSockName.lc */
+StgInt getSockName PROTO((StgInt, StgAddr, StgAddr));
+
+/* getPeerName.lc */
+StgInt getPeerName PROTO((StgInt, StgAddr, StgAddr));
+
+/* listenSocket.lc */
+StgInt listenSocket PROTO((StgInt, StgInt));
+
+/* shutdownSocket.lc */
+StgInt shutdownSocket PROTO((StgInt, StgInt));
+
+/* readDescriptor.lc */
+StgInt readDescriptor PROTO((StgInt, StgAddr, StgInt));
+
+/* writeDescriptor.lc */
+StgInt writeDescriptor PROTO((StgInt, StgAddr, StgInt));
+
+
 #endif /* !GHC_SOCKETS_H */
index 4535061..4ce0cea 100644 (file)
@@ -1,8 +1,4 @@
 #ifndef LIBPOSIX_H
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif /* HAVE_SYS_TYPES_H */
-
 #ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
 #endif /* HAVE_SYS_WAIT_H */
index 2e2ae88..e590043 100644 (file)
@@ -42,8 +42,8 @@
 #define SM_CAFLIST OFFSET(StorageMgrInfo, StorageMgrInfo.CAFlist)
 #define SM_OLDMUTABLES OFFSET(StorageMgrInfo, StorageMgrInfo.OldMutables)
 #define SM_OLDLIM OFFSET(StorageMgrInfo, StorageMgrInfo.OldLim)
-#define SM_MALLOCPTRLIST OFFSET(StorageMgrInfo, StorageMgrInfo.MallocPtrList)
-#define SM_OLDMALLOCPTRLIST OFFSET(StorageMgrInfo, StorageMgrInfo.OldMallocPtrList)
+#define SM_FOREIGNOBJLIST OFFSET(StorageMgrInfo, StorageMgrInfo.ForeignObjList)
+#define SM_OLDFOREIGNOBJLIST OFFSET(StorageMgrInfo, StorageMgrInfo.OldForeignObjList)
 #define SM_STABLEPOINTERTABLE OFFSET(StorageMgrInfo, StorageMgrInfo.StablePointerTable)
 
 STGRegisterTable MainRegTable;
@@ -98,9 +98,9 @@ main()
     printf("#define SM_OLDLIM %d\n", SM_OLDLIM);
 #endif
 #ifndef PAR
-    printf("#define SM_MALLOCPTRLIST %d\n", SM_MALLOCPTRLIST);
+    printf("#define SM_FOREIGNOBJLIST %d\n", SM_FOREIGNOBJLIST);
 #if defined(GCap) || defined(GCgn)
-    printf("#define SM_OLDMALLOCPTRLIST %d\n", SM_OLDMALLOCPTRLIST);
+    printf("#define SM_OLDFOREIGNOBJLIST %d\n", SM_OLDFOREIGNOBJLIST);
 #endif
     printf("#define SM_STABLEPOINTERTABLE %d\n", SM_STABLEPOINTERTABLE);
 #endif
index 88b0f40..d6d7f66 100644 (file)
@@ -87,6 +87,22 @@ extern int sscanf PROTO((const char *, const char *, ...));
 /* end of hack */
 #endif /* STDC_HEADERS */
 
+/*
+ * threadWaitWrite# uses FD_SETSIZE to distinguish
+ * between read file descriptors and write fd's.
+ * Hence we need to include <sys/types.h>, but
+ * is this the best place to do it?
+ * (the following has been moved from libposix.h)
+ */
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif  /* HAVE_SYS_TYPES_H */
+
+#ifndef FD_SETSIZE
+#define FD_SETSIZE 1024
+#endif
+
 #if ! defined(EXIT_SUCCESS) || ! defined(EXIT_FAILURE)
 /* "stdlib.h" should have defined these; but at least
    on SunOS 4.1.3, this is not so.
@@ -188,13 +204,18 @@ extern StgFunPtr returnMain(STG_NO_ARGS);
 extern StgFunPtr impossible_jump_after_switch(STG_NO_ARGS);
 
 /* hooks: user might write some of their own */
-extern void ErrorHdrHook       PROTO((FILE *));
-extern void OutOfHeapHook      PROTO((W_));
-extern void StackOverflowHook  PROTO((I_));
-extern void MallocFailHook     PROTO((I_, char *));
-extern void PatErrorHdrHook    PROTO((FILE *));
-extern void PreTraceHook       PROTO((FILE *));
-extern void PostTraceHook      PROTO((FILE *));
+void ErrorHdrHook      PROTO((FILE *));
+void OutOfHeapHook     PROTO((W_));
+void StackOverflowHook PROTO((I_));
+#ifdef CONCURRENT
+void NoRunnableThreadsHook (STG_NO_ARGS);
+#endif
+void MallocFailHook    PROTO((I_, char *));
+void PatErrorHdrHook   PROTO((FILE *));
+void PreTraceHook      PROTO((FILE *));
+void PostTraceHook     PROTO((FILE *));
+void defaultsHook      (STG_NO_ARGS);
+void initEachPEHook    (STG_NO_ARGS);
 
 EXTFUN(startStgWorld);
 #ifdef CONCURRENT
index 972b96e..26f09ee 100644 (file)
@@ -17,7 +17,7 @@ StgInt createDirectory PROTO((StgByteArray));
 char * strDup          PROTO((const char *));
 int    setenviron      PROTO((char **));
 int    copyenv         (STG_NO_ARGS);
-int    setenv          PROTO((char *));
+int    _setenv         PROTO((char *));
 int    delenv          PROTO((char *));
 
 /* errno.lc */
@@ -122,4 +122,39 @@ StgAddr toClockSec PROTO((StgInt, StgInt, StgInt, StgInt, StgInt, StgInt, StgInt
 /* writeFile.lc */
 StgInt writeFile PROTO((StgAddr, StgAddr, StgInt));
 
+/* SOCKET THINGS ALL TOGETHER: */
+
+#if 0
+LATER
+/* acceptSocket.lc */
+StgInt acceptSocket(I_ sockfd, A_ peer, A_ addrlen);
+
+/* bindSocket.lc */
+StgInt bindSocket(I_ sockfd, A_ myaddr, I_ addrlen, I_ isUnixDomain);
+
+/* connectSocket.lc */
+StgInt connectSocket(I_ sockfd, A_ servaddr, I_ addrlen, I_ isUnixDomain);
+
+/* createSocket.lc */
+StgInt createSocket(I_ family, I_ type, I_ protocol);
+
+/* getPeerName.lc */
+StgInt getPeerName(int sockfd, struct sockaddr *peer, int *namelen);
+
+/* getSockName.lc */
+StgInt getSockName(int sockfd, struct sockaddr *peer, int *namelen);
+
+/* listenSocket.lc */
+StgInt listenSocket(int sockfd, int backlog);
+
+/* readDescriptor.lc */
+StgInt readDescriptor(int fd, char *buf, int nbytes);
+
+/* shutdownSocket.lc */
+StgInt shutdownSocket(int sockfd, int how);
+
+/* writeDescriptor.lc */
+StgInt writeDescriptor(int fd, char *buf, int nbytes);
+#endif /* 0 */
+
 #endif /* ! STGIO_H */
index 75a287f..bedafdf 100644 (file)
@@ -21,8 +21,8 @@
 #else 
 #if HAVE_TZNAME
 extern time_t timezone, altzone;
-extern char *tmzone[2];
-#define ZONE(x)                 (((struct tm *)x)->tm_isdst ? tmzone[1] : tmzone[0])
+extern char *tzname[2];
+#define ZONE(x)                 (((struct tm *)x)->tm_isdst ? tzname[1] : tzname[0])
 #define SETZONE(x,z)
 #define GMTOFF(x)       (((struct tm *)x)->tm_isdst ? altzone : timezone)
 #endif