"the alignment requirement for spaces in the target.
Must be at least (ASH 1 DESCRIPTOR-LOW-BITS)")
-;;; a GENESIS-time representation of a memory space (e.g. read-only space,
-;;; dynamic space, or static space)
+;;; a GENESIS-time representation of a memory space (e.g. read-only
+;;; space, dynamic space, or static space)
(defstruct (gspace (:constructor %make-gspace)
(:copier nil))
;; name and identifier for this GSPACE
;;; pathname), or NIL if we're not currently cold loading any object file
(defvar *cold-load-filename* nil)
(declaim (type (or string null) *cold-load-filename*))
-
-;;; This is vestigial support for the CMU CL byte-swapping code. CMU
-;;; CL code tested for whether it needed to swap bytes in GENESIS by
-;;; comparing the byte order of *BACKEND* to the byte order of
-;;; *NATIVE-BACKEND*, a concept which doesn't exist in SBCL. Instead,
-;;; in SBCL byte order swapping would need to be explicitly requested
-;;; with a &KEY argument to GENESIS.
-;;;
-;;; I'm not sure whether this is a problem or not, and I don't have a
-;;; machine with different byte order to test to find out for sure.
-;;; The version of the system which is fed to the cross-compiler is
-;;; now written in a subset of Common Lisp which doesn't require
-;;; dumping a lot of things in such a way that machine byte order
-;;; matters. (Mostly this is a matter of not using any specialized
-;;; array type unless there's portable, high-level code to dump it.)
-;;; If it *is* a problem, and you're trying to resurrect this code,
-;;; please test particularly carefully, since I haven't had a chance
-;;; to test the byte-swapping code at all. -- WHN 19990816
-;;;
-;;; When this variable is non-NIL, byte-swapping is enabled wherever
-;;; classic GENESIS would have done it. I.e. the value of this variable
-;;; is the logical complement of
-;;; (EQ (SB!C:BACKEND-BYTE-ORDER SB!C:*NATIVE-BACKEND*)
-;;; (SB!C:BACKEND-BYTE-ORDER SB!C:*BACKEND*))
-;;; from CMU CL.
-(defvar *genesis-byte-order-swap-p*)
\f
;;;; miscellaneous stuff to read and write the core memory
"Push THING onto the given cold-load LIST."
`(setq ,list (cold-cons ,thing ,list)))
-(defun maybe-byte-swap (word)
- (declare (type (unsigned-byte 32) word))
- (aver (= sb!vm:n-word-bits 32))
- (aver (= sb!vm:n-byte-bits 8))
- (if (not *genesis-byte-order-swap-p*)
- word
- (logior (ash (ldb (byte 8 0) word) 24)
- (ash (ldb (byte 8 8) word) 16)
- (ash (ldb (byte 8 16) word) 8)
- (ldb (byte 8 24) word))))
-
-(defun maybe-byte-swap-short (short)
- (declare (type (unsigned-byte 16) short))
- (aver (= sb!vm:n-word-bits 32))
- (aver (= sb!vm:n-byte-bits 8))
- (if (not *genesis-byte-order-swap-p*)
- short
- (logior (ash (ldb (byte 8 0) short) 8)
- (ldb (byte 8 8) short))))
-
;;; BYTE-VECTOR-REF-32 and friends. These are like SAP-REF-n, except
;;; that instead of a SAP we use a byte vector
(macrolet ((make-byte-vector-ref-n
,(* i 8))))
(ash-list-be
(loop for i from 0 to (1- number-octets)
- collect `(ash (aref byte-vector (+ byte-index
- ,(- number-octets 1 i)))
+ collect `(ash (aref byte-vector
+ (+ byte-index
+ ,(- number-octets 1 i)))
,(* i 8))))
(setf-list-le
(loop for i from 0 to (1- number-octets)
(aver (= sb!vm:n-word-bits 32))
(aver (= sb!vm:n-byte-bits 8))
(logior ,@(ecase sb!c:*backend-byte-order*
- (:little-endian ash-list-le)
- (:big-endian ash-list-be))))
- (defun (setf ,name) (new-value byte-vector byte-index)
- (aver (= sb!vm:n-word-bits 32))
- (aver (= sb!vm:n-byte-bits 8))
- (setf ,@(ecase sb!c:*backend-byte-order*
- (:little-endian setf-list-le)
- (:big-endian setf-list-be))))))))
+ (:little-endian ash-list-le)
+ (:big-endian ash-list-be))))
+ (defun (setf ,name) (new-value byte-vector byte-index)
+ (aver (= sb!vm:n-word-bits 32))
+ (aver (= sb!vm:n-byte-bits 8))
+ (setf ,@(ecase sb!c:*backend-byte-order*
+ (:little-endian setf-list-le)
+ (:big-endian setf-list-be))))))))
(make-byte-vector-ref-n 8)
(make-byte-vector-ref-n 16)
(make-byte-vector-ref-n 32))
(bytes (gspace-bytes gspace))
(byte-index (ash (+ index (descriptor-word-offset address))
sb!vm:word-shift))
- ;; KLUDGE: Do we really need to do byte swap here? It seems
- ;; as though we shouldn't.. (This attempts to be a literal
- ;; translation of CMU CL code, and I don't have a big-endian
- ;; machine to test it.) -- WHN 19990817
- (value (maybe-byte-swap (byte-vector-ref-32 bytes byte-index))))
+ (value (byte-vector-ref-32 bytes byte-index)))
(make-random-descriptor value)))
(declaim (ftype (function (descriptor) descriptor) read-memory))
sb!vm:lowtag-mask)
(ash index sb!vm:word-shift))
value)
- ;; Note: There's a MAYBE-BYTE-SWAP in here in CMU CL, which I
- ;; think is unnecessary now that we're doing the write
- ;; byte-by-byte at high level. (I can't test this, though..) --
- ;; WHN 19990817
(let* ((bytes (gspace-bytes (descriptor-intuit-gspace address)))
(byte-index (ash (+ index (descriptor-word-offset address))
sb!vm:word-shift)))
(setf (byte-vector-ref-32 bytes byte-index)
- (maybe-byte-swap (descriptor-bits value))))))
+ (descriptor-bits value)))))
(declaim (ftype (function (descriptor descriptor)) write-memory))
(defun write-memory (address value)
(write-wordindexed des (1+ sb!vm:complex-double-float-imag-slot) low-bits))))
des))
+;;; Copy the given number to the core.
(defun number-to-core (number)
- #!+sb-doc
- "Copy the given number to the core, or flame out if we can't deal with it."
(typecase number
(integer (if (< (integer-length number) 30)
(make-fixnum-descriptor number)
(write-wordindexed dest 1 cdr)
dest))
-;;; Make a simple-vector that holds the specified OBJECTS, and return its
-;;; descriptor.
+;;; Make a simple-vector on the target that holds the specified
+;;; OBJECTS, and return its descriptor.
(defun vector-in-core (&rest objects)
(let* ((size (length objects))
(result (allocate-vector-object *dynamic* sb!vm:n-word-bits size
(defvar *cold-package-symbols*)
(declaim (type list *cold-package-symbols*))
-;;; a map from descriptors to symbols, so that we can back up. The key is the
-;;; address in the target core.
+;;; a map from descriptors to symbols, so that we can back up. The key
+;;; is the address in the target core.
(defvar *cold-symbols*)
(declaim (type hash-table *cold-symbols*))
+;;; sanity check for a symbol we're about to create on the target
+;;;
+;;; Make sure that the symbol has an appropriate package. In
+;;; particular, catch the so-easy-to-make error of typing something
+;;; like SB-KERNEL:%BYTE-BLT in cold sources when what you really
+;;; need is SB!KERNEL:%BYTE-BLT.
+(defun package-ok-for-target-symbol-p (package)
+ (let ((package-name (package-name package)))
+ (or
+ ;; Cold interning things in these standard packages is OK. (Cold
+ ;; interning things in the other standard package, CL-USER, isn't
+ ;; OK. We just use CL-USER to expose symbols whose homes are in
+ ;; other packages. Thus, trying to cold intern a symbol whose
+ ;; home package is CL-USER probably means that a coding error has
+ ;; been made somewhere.)
+ (find package-name '("COMMON-LISP" "KEYWORD") :test #'string=)
+ ;; Cold interning something in one of our target-code packages,
+ ;; which are ever-so-rigorously-and-elegantly distinguished by
+ ;; this prefix on their names, is OK too.
+ (string= package-name "SB!" :end1 3 :end2 3)
+ ;; This one is OK too, since it ends up being COMMON-LISP on the
+ ;; target.
+ (string= package-name "SB-XC")
+ ;; Anything else looks bad. (maybe COMMON-LISP-USER? maybe an extension
+ ;; package in the xc host? something we can't think of
+ ;; a valid reason to cold intern, anyway...)
+ )))
+
+;;; like SYMBOL-PACKAGE, but safe for symbols which end up on the target
+;;;
+;;; Most host symbols we dump onto the target are created by SBCL
+;;; itself, so that as long as we avoid gratuitously
+;;; cross-compilation-unfriendly hacks, it just happens that their
+;;; SYMBOL-PACKAGE in the host system corresponds to their
+;;; SYMBOL-PACKAGE in the target system. However, that's not the case
+;;; in the COMMON-LISP package, where we don't get to create the
+;;; symbols but instead have to use the ones that the xc host created.
+;;; In particular, while ANSI specifies which symbols are exported
+;;; from COMMON-LISP, it doesn't specify that their home packages are
+;;; COMMON-LISP, so the xc host can keep them in random packages which
+;;; don't exist on the target (e.g. CLISP keeping some CL-exported
+;;; symbols in the CLOS package).
+(defun symbol-package-for-target-symbol (symbol)
+ ;; We want to catch weird symbols like CLISP's
+ ;; CL:FIND-METHOD=CLOS::FIND-METHOD, but we don't want to get
+ ;; sidetracked by ordinary symbols like :CHARACTER which happen to
+ ;; have the same SYMBOL-NAME as exports from COMMON-LISP.
+ (multiple-value-bind (cl-symbol cl-status)
+ (find-symbol (symbol-name symbol) *cl-package*)
+ (if (and (eq symbol cl-symbol)
+ (eq cl-status :external))
+ ;; special case, to work around possible xc host weirdness
+ ;; in COMMON-LISP package
+ *cl-package*
+ ;; ordinary case
+ (let ((result (symbol-package symbol)))
+ (aver (package-ok-for-target-symbol-p result))
+ result))))
+
;;; Return a handle on an interned symbol. If necessary allocate the
;;; symbol and record which package the symbol was referenced in. When
;;; we allocate the symbol, make sure we record a reference to the
;;; symbol in the home package so that the package gets set.
-(defun cold-intern (symbol &optional (package (symbol-package symbol)))
+(defun cold-intern (symbol
+ &optional
+ (package (symbol-package-for-target-symbol symbol)))
+
+ (aver (package-ok-for-target-symbol-p package))
;; Anything on the cross-compilation host which refers to the target
;; machinery through the host SB-XC package should be translated to
(when (eq (symbol-package symbol) p)
(setf symbol (intern (symbol-name symbol) *cl-package*))))
- ;; Make sure that the symbol has an appropriate package. In
- ;; particular, catch the so-easy-to-make error of typing something
- ;; like SB-KERNEL:%BYTE-BLT in cold sources when what you really
- ;; need is SB!KERNEL:%BYTE-BLT.
- (let ((package-name (package-name package)))
- (cond ((find package-name '("COMMON-LISP" "KEYWORD") :test #'string=)
- ;; That's OK then.
- (values))
- ((string= package-name "SB!" :end1 3 :end2 3)
- ;; That looks OK, too. (All the target-code packages
- ;; have names like that.)
- (values))
- (t
- ;; looks bad: maybe COMMON-LISP-USER? maybe an extension
- ;; package in the xc host? something we can't think of
- ;; a valid reason to dump, anyway...
- (bug "internal error: PACKAGE-NAME=~S looks too much like a typo."
- package-name))))
-
(let (;; Information about each cold-interned symbol is stored
;; in COLD-INTERN-INFO.
;; (CAR COLD-INTERN-INFO) = descriptor of symbol
;; (CDR COLD-INTERN-INFO) = list of packages, other than symbol's
- ;; own package, referring to symbol
+ ;; own package, referring to symbol
;; (*COLD-PACKAGE-SYMBOLS* and *COLD-SYMBOLS* store basically the
;; same information, but with the mapping running the opposite way.)
(cold-intern-info (get symbol 'cold-intern-info)))
(unless cold-intern-info
- (cond ((eq (symbol-package symbol) package)
+ (cond ((eq (symbol-package-for-target-symbol symbol) package)
(let ((handle (allocate-symbol (symbol-name symbol))))
(setf (gethash (descriptor-bits handle) *cold-symbols*) symbol)
(when (eq package *keyword-package*)
(imported-internal *nil-descriptor*)
(imported-external *nil-descriptor*)
(shadowing *nil-descriptor*))
+ (declare (type package cold-package)) ; i.e. not a target descriptor
(/show "dumping" cold-package symbols)
;; FIXME: Add assertions here to make sure that inappropriate stuff
(dolist (symbol symbols)
(let ((handle (car (get symbol 'cold-intern-info)))
- (imported-p (not (eq (symbol-package symbol) cold-package))))
+ (imported-p (not (eq (symbol-package-for-target-symbol symbol)
+ cold-package))))
(multiple-value-bind (found where)
(find-symbol (symbol-name symbol) cold-package)
(unless (and where (eq found symbol))
(progn
(cold-set 'sb!vm::*fp-constant-0d0* (number-to-core 0d0))
(cold-set 'sb!vm::*fp-constant-1d0* (number-to-core 1d0))
- (cold-set 'sb!vm::*fp-constant-0s0* (number-to-core 0s0))
- (cold-set 'sb!vm::*fp-constant-1s0* (number-to-core 1s0))
+ (cold-set 'sb!vm::*fp-constant-0f0* (number-to-core 0f0))
+ (cold-set 'sb!vm::*fp-constant-1f0* (number-to-core 1f0))
#!+long-float
(progn
(cold-set 'sb!vm::*fp-constant-0l0* (number-to-core 0L0))
sb!vm:fdefn-raw-addr-slot
(make-random-descriptor
(cold-foreign-symbol-address-as-integer
- "undefined_tramp"))))
+ (sb!vm:extern-alien-name "undefined_tramp")))))
fdefn))))
;;; Handle the at-cold-init-time, fset-for-static-linkage operation
(#.sb!vm:closure-header-widetag
(make-random-descriptor
(cold-foreign-symbol-address-as-integer
- "closure_tramp")))))
+ (sb!vm:extern-alien-name "closure_tramp"))))))
fdefn))
(defun initialize-static-fns ()
(:alpha
(ecase kind
(:jmp-hint
- (assert (zerop (ldb (byte 2 0) value)))
- #+nil ;; was commented out in cmucl source too. Don't know what
- ;; it does -dan 2001.05.03
- (setf (sap-ref-16 sap 0)
- (logior (sap-ref-16 sap 0) (ldb (byte 14 0) (ash value -2)))))
+ (assert (zerop (ldb (byte 2 0) value))))
(:bits-63-48
(let* ((value (if (logbitp 15 value) (+ value (ash 1 16)) value))
(value (if (logbitp 31 value) (+ value (ash 1 32)) value))
(ldb (byte 8 0) value)
(byte-vector-ref-8 gspace-bytes (1+ gspace-byte-offset))
(ldb (byte 8 8) value)))))
+ (:ppc
+ (ecase kind
+ (:ba
+ (setf (byte-vector-ref-32 gspace-bytes gspace-byte-offset)
+ (dpb (ash value -2) (byte 24 2)
+ (byte-vector-ref-32 gspace-bytes gspace-byte-offset))))
+ (:ha
+ (let* ((h (ldb (byte 16 16) value))
+ (l (ldb (byte 16 0) value)))
+ (setf (byte-vector-ref-16 gspace-bytes (+ gspace-byte-offset 2))
+ (if (logbitp 15 l) (ldb (byte 16 0) (1+ h)) h))))
+ (:l
+ (setf (byte-vector-ref-16 gspace-bytes (+ gspace-byte-offset 2))
+ (ldb (byte 16 0) value)))))
(:sparc
(ecase kind
(:call
i)))))
(terpri)
+ ;; FIXME: The SPARC has a PSEUDO-ATOMIC-TRAP that differs between
+ ;; platforms. If we export this from the SB!VM package, it gets
+ ;; written out as #define trap_PseudoAtomic, which is confusing as
+ ;; the runtime treats trap_ as the prefix for illegal instruction
+ ;; type things. We therefore don't export it, but instead do
+ #!+sparc
+ (when (boundp 'sb!vm::pseudo-atomic-trap)
+ (format t "#define PSEUDO_ATOMIC_TRAP ~D /* 0x~:*~X */~%" sb!vm::pseudo-atomic-trap)
+ (terpri))
+ ;; possibly this is another candidate for a rename (to
+ ;; pseudo-atomic-trap-number or pseudo-atomic-magic-constant
+ ;; [possibly applicable to other platforms])
+
;; writing primitive object layouts
(let ((structs (sort (copy-list sb!vm:*primitive-objects*) #'string<
:key (lambda (obj)
(dolist (obj structs)
(format t
"struct ~A {~%"
- (nsubstitute #\_ #\-
+ (substitute #\_ #\-
(string-downcase (string (sb!vm:primitive-object-name obj)))))
(when (sb!vm:primitive-object-widetag obj)
(format t " lispobj header;~%"))
(dolist (slot (sb!vm:primitive-object-slots obj))
(format t " ~A ~A~@[[1]~];~%"
(getf (sb!vm:slot-options slot) :c-type "lispobj")
- (nsubstitute #\_ #\-
- (string-downcase (string (sb!vm:slot-name slot))))
+ (substitute #\_ #\-
+ (string-downcase (string (sb!vm:slot-name slot))))
(sb!vm:slot-rest-p slot)))
(format t "};~2%"))
(format t "#else /* LANGUAGE_ASSEMBLY */~2%")
;; FIXME: It would be nice to use longer names than NIL and
;; (particularly) T in #define statements.
(format t "#define ~A LISPOBJ(0x~X)~%"
- (nsubstitute #\_ #\-
- (remove-if (lambda (char)
- (member char '(#\% #\* #\. #\!)))
- (symbol-name symbol)))
+ (substitute #\_ #\-
+ (remove-if (lambda (char)
+ (member char '(#\% #\* #\. #\!)))
+ (symbol-name symbol)))
(if *static* ; if we ran GENESIS
;; We actually ran GENESIS, use the real value.
(descriptor-bits (cold-intern symbol))
;;; the executable which will load the core.
;;; MAP-FILE-NAME gets (?) a map file. (dunno about this -- WHN 19990815)
;;;
-;;; other arguments:
-;;; BYTE-ORDER-SWAP-P controls whether GENESIS tries to swap bytes
-;;; in some places in the output. It's only appropriate when
-;;; cross-compiling from a machine with one byte order to a
-;;; machine with the opposite byte order, which is irrelevant in
-;;; current (19990816) SBCL, since only the X86 architecture is
-;;; supported. If you're trying to add support for more
-;;; architectures, see the comments on DEFVAR
-;;; *GENESIS-BYTE-ORDER-SWAP-P* for more information.
-;;;
;;; FIXME: GENESIS doesn't belong in SB!VM. Perhaps in %KERNEL for now,
;;; perhaps eventually in SB-LD or SB-BOOT.
(defun sb!vm:genesis (&key
symbol-table-file-name
core-file-name
map-file-name
- c-header-file-name
- byte-order-swap-p)
+ c-header-file-name)
(when (and core-file-name
(not symbol-table-file-name))
(let* ((*foreign-symbol-placeholder-value* (if core-file-name nil 0))
(*load-time-value-counter* 0)
- (*genesis-byte-order-swap-p* byte-order-swap-p)
(*cold-fdefn-objects* (make-hash-table :test 'equal))
(*cold-symbols* (make-hash-table :test 'equal))
(*cold-package-symbols* nil)