--- a/src/cold/shared.lisp
+++ b/src/cold/shared.lisp
@@ -101,39 +101,149 @@
     (rename-file x path)))
 (compile 'rename-file-a-la-unix)
 
+;;; other miscellaneous tools
+(load "src/cold/read-from-file.lisp")
+(load "src/cold/rename-package-carefully.lisp")
+(load "src/cold/with-stuff.lisp")
+
+;;; Try to minimize/conceal any non-standardness of the host Common Lisp.
+(load "src/cold/ansify.lisp")
+
+;;;; special read-macros for building the cold system (and even for
+;;;; building some of our tools for building the cold system)
+
+(load "src/cold/shebang.lisp")
+
+;;; When cross-compiling, the *FEATURES* set for the target Lisp is
+;;; not in general the same as the *FEATURES* set for the host Lisp.
+;;; In order to refer to target features specifically, we refer to
+;;; *SHEBANG-FEATURES* instead of *FEATURES*, and use the #!+ and #!-
+;;; readmacros instead of the ordinary #+ and #- readmacros.
+(setf *shebang-features*
+      (let* ((default-features
+               (append (read-from-file "base-target-features.lisp-expr")
+                       (read-from-file "local-target-features.lisp-expr")))
+             (customizer-file-name "customize-target-features.lisp")
+             (customizer (if (probe-file customizer-file-name)
+                             (compile nil
+                                      (read-from-file customizer-file-name))
+                             #'identity)))
+        (funcall customizer default-features)))
+(let ((*print-length* nil)
+      (*print-level* nil))
+  (format t
+          "target features *SHEBANG-FEATURES*=~@<~S~:>~%"
+          *shebang-features*))
+
+(defvar *shebang-backend-subfeatures*
+  (let* ((default-subfeatures nil)
+         (customizer-file-name "customize-backend-subfeatures.lisp")
+         (customizer (if (probe-file customizer-file-name)
+                         (compile nil
+                                  (read-from-file customizer-file-name))
+                         #'identity)))
+    (funcall customizer default-subfeatures)))
+(let ((*print-length* nil)
+      (*print-level* nil))
+  (format t
+          "target backend-subfeatures *SHEBANG-BACKEND-FEATURES*=~@<~S~:>~%"
+          *shebang-backend-subfeatures*))
+
+;;;; cold-init-related PACKAGE and SYMBOL tools
+
+;;; Once we're done with possibly ANSIfying the COMMON-LISP package,
+;;; it's probably a mistake if we change it (beyond changing the
+;;; values of special variables such as *** and +, anyway). Set up
+;;; machinery to warn us when/if we change it.
+;;;
+;;; All code depending on this is itself dependent on #!+SB-SHOW.
+#!+sb-show
+(progn
+  (load "src/cold/snapshot.lisp")
+  (defvar *cl-snapshot* (take-snapshot "COMMON-LISP")))
+
+;;;; master list of source files and their properties
+
+;;; flags which can be used to describe properties of source files
+(defparameter
+  *expected-stem-flags*
+  '(;; meaning: This file is not to be compiled when building the
+    ;; cross-compiler which runs on the host ANSI Lisp. ("not host
+    ;; code", i.e. does not execute on host -- but may still be
+    ;; cross-compiled by the host, so that it executes on the target)
+    :not-host
+    ;; meaning: This file is not to be compiled as part of the target
+    ;; SBCL. ("not target code" -- but still presumably host code,
+    ;; used to support the cross-compilation process)
+    :not-target
+    ;; meaning: The #'COMPILE-STEM argument :TRACE-FILE should be T.
+    ;; When the compiler is SBCL's COMPILE-FILE or something like it,
+    ;; compiling "foo.lisp" will generate "foo.trace" which contains lots
+    ;; of exciting low-level information about representation selection,
+    ;; VOPs used by the compiler, and bits of assembly.
+    :trace-file
+    ;; meaning: This file is to be processed with the SBCL assembler,
+    ;; not COMPILE-FILE. (Note that this doesn't make sense unless
+    ;; :NOT-HOST is also set, since the SBCL assembler doesn't exist
+    ;; while the cross-compiler is being built in the host ANSI Lisp.)
+    :assem
+    ;; meaning: The #'COMPILE-STEM argument called :IGNORE-FAILURE-P
+    ;; should be true. (This is a KLUDGE: I'd like to get rid of it.
+    ;; For now, it exists so that compilation can proceed through the
+    ;; legacy warnings in src/compiler/x86/array.lisp, which I've
+    ;; never figured out but which were apparently acceptable in CMU
+    ;; CL. Eventually, it would be great to just get rid of all
+    ;; warnings and remove support for this flag. -- WHN 19990323)
+    :ignore-failure-p))
+
+(defparameter *stems-and-flags* (read-from-file "build-order.lisp-expr"))
+
+(defmacro do-stems-and-flags ((stem flags) &body body)
+  (let ((stem-and-flags (gensym "STEM-AND-FLAGS")))
+    `(dolist (,stem-and-flags *stems-and-flags*)
+       (let ((,stem (first ,stem-and-flags))
+             (,flags (rest ,stem-and-flags)))
+         ,@body))))
+
+;;; Determine the source path for a stem.
+(defun stem-source-path (stem)
+  (concatenate 'string "" stem ".lisp"))
+(compile 'stem-source-path)
+
+;;; Determine the object path for a stem/mode combination.
+(defun stem-object-path (stem mode)
+  (multiple-value-bind
+        (obj-prefix obj-suffix)
+      (ecase mode
+        (:host-compile (values *host-obj-prefix* *host-obj-suffix*))
+        (:target-compile (values *target-obj-prefix* *target-obj-suffix*)))
+    (concatenate 'string obj-prefix stem obj-suffix)))
+(compile 'stem-object-path)
+
+;;; Check for stupid typos in FLAGS list keywords.
+(let ((stems (make-hash-table :test 'equal)))
+  (do-stems-and-flags (stem flags)
+    (if (gethash stem stems)
+      (error "duplicate stem ~S in *STEMS-AND-FLAGS*" stem)
+      (setf (gethash stem stems) t))
+    (let ((set-difference (set-difference flags *expected-stem-flags*)))
+      (when set-difference
+        (error "found unexpected flag(s) in *STEMS-AND-FLAGS*: ~S"
+               set-difference)))))
+
+;;;; tools to compile SBCL sources to create the cross-compiler
+
 ;;; a wrapper for compilation/assembly, used mostly to centralize
 ;;; the procedure for finding full filenames from "stems"
 ;;;
 ;;; Compile the source file whose basic name is STEM, using some
 ;;; standard-for-the-SBCL-build-process procedures to generate the
 ;;; full pathnames of source file and object file. Return the pathname
-;;; of the object file for STEM. Several &KEY arguments are accepted:
-;;;   :SRC-PREFIX, :SRC-SUFFIX =
-;;;      strings to be concatenated to STEM to produce source filename
-;;;   :OBJ-PREFIX, :OBJ-SUFFIX =
-;;;      strings to be concatenated to STEM to produce object filename
-;;;   :TMP-OBJ-SUFFIX-SUFFIX =
-;;;      string to be appended to the name of an object file to produce
-;;;      the name of a temporary object file
-;;;   :COMPILE-FILE, :IGNORE-FAILURE-P =
-;;;     :COMPILE-FILE is a function to use for compiling the file
-;;;     (with the same calling conventions as ANSI CL:COMPILE-FILE).
-;;;     If the third return value (FAILURE-P) of this function is
-;;;     true, a continuable error will be signalled, unless
-;;;     :IGNORE-FAILURE-P is set, in which case only a warning will be
-;;;     signalled.
-(defun compile-stem (stem
-                     &key
-                     (obj-prefix "")
-                     (obj-suffix (error "missing OBJ-SUFFIX"))
-                     (tmp-obj-suffix-suffix "-tmp")
-                     (src-prefix "")
-                     (src-suffix ".lisp")
-                     (compile-file #'compile-file)
-                     trace-file
-                     ignore-failure-p)
-
-  (declare (type function compile-file))
+;;; of the object file for STEM.
+;;;
+;;; STEM and FLAGS are as per DO-STEMS-AND-FLAGS.  MODE is one of
+;;; :HOST-COMPILE and :TARGET-COMPILE.
+(defun compile-stem (stem flags mode)
 
   (let* (;; KLUDGE: Note that this CONCATENATE 'STRING stuff is not The Common
          ;; Lisp Way, although it works just fine for common UNIX environments.
@@ -143,9 +253,18 @@
          ;; machinery instead of just using strings. In the absence of such a
          ;; port, it might or might be a good idea to do the rewrite.
          ;; -- WHN 19990815
-         (src (concatenate 'string src-prefix stem src-suffix))
-         (obj (concatenate 'string obj-prefix stem obj-suffix))
-         (tmp-obj (concatenate 'string obj tmp-obj-suffix-suffix)))
+         (src (stem-source-path stem))
+         (obj (stem-object-path stem mode))
+         (tmp-obj (concatenate 'string obj "-tmp"))
+
+         (compile-file (ecase mode
+                         (:host-compile #'compile-file)
+                         (:target-compile (if (find :assem flags)
+                                              *target-assemble-file*
+                                              *target-compile-file*))))
+         (trace-file (find :trace-file flags))
+         (ignore-failure-p (find :ignore-failure-p flags)))
+    (declare (type function compile-file))
 
     (ensure-directories-exist obj :verbose t)
 
@@ -230,123 +349,6 @@
     (pathname obj)))
 (compile 'compile-stem)
 
-;;; other miscellaneous tools
-(load "src/cold/read-from-file.lisp")
-(load "src/cold/rename-package-carefully.lisp")
-(load "src/cold/with-stuff.lisp")
-
-;;; Try to minimize/conceal any non-standardness of the host Common Lisp.
-(load "src/cold/ansify.lisp")
-
-;;;; special read-macros for building the cold system (and even for
-;;;; building some of our tools for building the cold system)
-
-(load "src/cold/shebang.lisp")
-
-;;; When cross-compiling, the *FEATURES* set for the target Lisp is
-;;; not in general the same as the *FEATURES* set for the host Lisp.
-;;; In order to refer to target features specifically, we refer to
-;;; *SHEBANG-FEATURES* instead of *FEATURES*, and use the #!+ and #!-
-;;; readmacros instead of the ordinary #+ and #- readmacros.
-(setf *shebang-features*
-      (let* ((default-features
-               (append (read-from-file "base-target-features.lisp-expr")
-                       (read-from-file "local-target-features.lisp-expr")))
-             (customizer-file-name "customize-target-features.lisp")
-             (customizer (if (probe-file customizer-file-name)
-                             (compile nil
-                                      (read-from-file customizer-file-name))
-                             #'identity)))
-        (funcall customizer default-features)))
-(let ((*print-length* nil)
-      (*print-level* nil))
-  (format t
-          "target features *SHEBANG-FEATURES*=~@<~S~:>~%"
-          *shebang-features*))
-
-(defvar *shebang-backend-subfeatures*
-  (let* ((default-subfeatures nil)
-         (customizer-file-name "customize-backend-subfeatures.lisp")
-         (customizer (if (probe-file customizer-file-name)
-                         (compile nil
-                                  (read-from-file customizer-file-name))
-                         #'identity)))
-    (funcall customizer default-subfeatures)))
-(let ((*print-length* nil)
-      (*print-level* nil))
-  (format t
-          "target backend-subfeatures *SHEBANG-BACKEND-FEATURES*=~@<~S~:>~%"
-          *shebang-backend-subfeatures*))
-
-;;;; cold-init-related PACKAGE and SYMBOL tools
-
-;;; Once we're done with possibly ANSIfying the COMMON-LISP package,
-;;; it's probably a mistake if we change it (beyond changing the
-;;; values of special variables such as *** and +, anyway). Set up
-;;; machinery to warn us when/if we change it.
-;;;
-;;; All code depending on this is itself dependent on #!+SB-SHOW.
-#!+sb-show
-(progn
-  (load "src/cold/snapshot.lisp")
-  (defvar *cl-snapshot* (take-snapshot "COMMON-LISP")))
-
-;;;; master list of source files and their properties
-
-;;; flags which can be used to describe properties of source files
-(defparameter
-  *expected-stem-flags*
-  '(;; meaning: This file is not to be compiled when building the
-    ;; cross-compiler which runs on the host ANSI Lisp. ("not host
-    ;; code", i.e. does not execute on host -- but may still be
-    ;; cross-compiled by the host, so that it executes on the target)
-    :not-host
-    ;; meaning: This file is not to be compiled as part of the target
-    ;; SBCL. ("not target code" -- but still presumably host code,
-    ;; used to support the cross-compilation process)
-    :not-target
-    ;; meaning: The #'COMPILE-STEM argument :TRACE-FILE should be T.
-    ;; When the compiler is SBCL's COMPILE-FILE or something like it,
-    ;; compiling "foo.lisp" will generate "foo.trace" which contains lots
-    ;; of exciting low-level information about representation selection,
-    ;; VOPs used by the compiler, and bits of assembly.
-    :trace-file
-    ;; meaning: This file is to be processed with the SBCL assembler,
-    ;; not COMPILE-FILE. (Note that this doesn't make sense unless
-    ;; :NOT-HOST is also set, since the SBCL assembler doesn't exist
-    ;; while the cross-compiler is being built in the host ANSI Lisp.)
-    :assem
-    ;; meaning: The #'COMPILE-STEM argument called :IGNORE-FAILURE-P
-    ;; should be true. (This is a KLUDGE: I'd like to get rid of it.
-    ;; For now, it exists so that compilation can proceed through the
-    ;; legacy warnings in src/compiler/x86/array.lisp, which I've
-    ;; never figured out but which were apparently acceptable in CMU
-    ;; CL. Eventually, it would be great to just get rid of all
-    ;; warnings and remove support for this flag. -- WHN 19990323)
-    :ignore-failure-p))
-
-(defparameter *stems-and-flags* (read-from-file "build-order.lisp-expr"))
-
-(defmacro do-stems-and-flags ((stem flags) &body body)
-  (let ((stem-and-flags (gensym "STEM-AND-FLAGS")))
-    `(dolist (,stem-and-flags *stems-and-flags*)
-       (let ((,stem (first ,stem-and-flags))
-             (,flags (rest ,stem-and-flags)))
-         ,@body))))
-
-;;; Check for stupid typos in FLAGS list keywords.
-(let ((stems (make-hash-table :test 'equal)))
-  (do-stems-and-flags (stem flags)
-    (if (gethash stem stems)
-      (error "duplicate stem ~S in *STEMS-AND-FLAGS*" stem)
-      (setf (gethash stem stems) t))
-    (let ((set-difference (set-difference flags *expected-stem-flags*)))
-      (when set-difference
-        (error "found unexpected flag(s) in *STEMS-AND-FLAGS*: ~S"
-               set-difference)))))
-
-;;;; tools to compile SBCL sources to create the cross-compiler
-
 ;;; Execute function FN in an environment appropriate for compiling the
 ;;; cross-compiler's source code in the cross-compilation host.
 (defun in-host-compilation-mode (fn)
@@ -364,26 +366,17 @@
 ;;; Process a file as source code for the cross-compiler, compiling it
 ;;; (if necessary) in the appropriate environment, then loading it
 ;;; into the cross-compilation host Common lisp.
-(defun host-cload-stem (stem &key ignore-failure-p)
+(defun host-cload-stem (stem flags)
   (let ((compiled-filename (in-host-compilation-mode
                             (lambda ()
-                              (compile-stem
-                               stem
-                               :obj-prefix *host-obj-prefix*
-                               :obj-suffix *host-obj-suffix*
-                               :compile-file #'cl:compile-file
-                               :ignore-failure-p ignore-failure-p)))))
+                              (compile-stem stem flags :host-compile)))))
     (load compiled-filename)))
 (compile 'host-cload-stem)
 
 ;;; like HOST-CLOAD-STEM, except that we don't bother to compile
-(defun host-load-stem (stem &key ignore-failure-p)
-  (declare (ignore ignore-failure-p)) ; (It's only relevant when
-  ;; compiling.) KLUDGE: It's untidy to have the knowledge of how to
-  ;; construct complete filenames from stems in here as well as in
-  ;; COMPILE-STEM. It should probably be factored out somehow. -- WHN
-  ;; 19990815
-  (load (concatenate 'simple-string *host-obj-prefix* stem *host-obj-suffix*)))
+(defun host-load-stem (stem flags)
+  (declare (ignore flags)) ; (It's only relevant when compiling.)
+  (load (stem-object-path stem :host-compile)))
 (compile 'host-load-stem)
 
 ;;;; tools to compile SBCL sources to create object files which will
@@ -391,17 +384,10 @@
 
 ;;; Run the cross-compiler on a file in the source directory tree to
 ;;; produce a corresponding file in the target object directory tree.
-(defun target-compile-stem (stem &key assem-p ignore-failure-p trace-file)
+(defun target-compile-stem (stem flags)
   (funcall *in-target-compilation-mode-fn*
            (lambda ()
-             (compile-stem stem
-                           :obj-prefix *target-obj-prefix*
-                           :obj-suffix *target-obj-suffix*
-                          :trace-file trace-file
-                           :ignore-failure-p ignore-failure-p
-                           :compile-file (if assem-p
-                                             *target-assemble-file*
-                                             *target-compile-file*)))))
+             (compile-stem stem flags :target-compile))))
 (compile 'target-compile-stem)
 
 ;;; (This function is not used by the build process, but is intended