New compiler port.
authorGuillermo J. Rozas <edu/mit/csail/zurich/gjr>
Thu, 25 Jan 1990 16:45:49 +0000 (16:45 +0000)
committerGuillermo J. Rozas <edu/mit/csail/zurich/gjr>
Thu, 25 Jan 1990 16:45:49 +0000 (16:45 +0000)
14 files changed:
v7/src/compiler/machines/spectrum/assmd.scm
v7/src/compiler/machines/spectrum/coerce.scm
v7/src/compiler/machines/spectrum/dassm1.scm [new file with mode: 0644]
v7/src/compiler/machines/spectrum/dassm2.scm [new file with mode: 0644]
v7/src/compiler/machines/spectrum/decls.scm [new file with mode: 0644]
v7/src/compiler/machines/spectrum/lapgen.scm
v7/src/compiler/machines/spectrum/machin.scm
v7/src/compiler/machines/spectrum/rgspcm.scm [new file with mode: 0644]
v7/src/compiler/machines/spectrum/rules1.scm [new file with mode: 0644]
v7/src/compiler/machines/spectrum/rules2.scm [new file with mode: 0644]
v7/src/compiler/machines/spectrum/rules3.scm [new file with mode: 0644]
v7/src/compiler/machines/spectrum/rules4.scm [new file with mode: 0644]
v7/src/compiler/machines/spectrum/rulfix.scm [new file with mode: 0644]
v7/src/compiler/machines/spectrum/rulflo.scm [new file with mode: 0644]

index 2f19b496412ac27405adb46f1502ab998d141812..93aa0705ee718cfb5a2c8c834390d51bf81e607b 100644 (file)
@@ -1,8 +1,9 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/assmd.scm,v 1.29 1987/03/19 00:54:40 cph Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/assmd.scm,v 1.30 1990/01/25 16:28:57 jinx Rel $
+$MC68020-Header: assmd.scm,v 1.36 89/08/28 18:33:33 GMT cph Exp $
 
-Copyright (c) 1987 Massachusetts Institute of Technology
+Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
 
 This material was developed by the Scheme project at the Massachusetts
 Institute of Technology, Department of Electrical Engineering and
@@ -36,23 +37,55 @@ MIT in each case. |#
 
 (declare (usual-integrations))
 \f
-(define addressing-granularity 8)
-(define scheme-object-width 32)
+(let-syntax ((ucode-type (macro (name) `',(microcode-type name))))
 
-(define make-nmv-header)
-(let ()
+(define-integrable maximum-padding-length
+  ;; Instruction length is always a multiple of 32 bits
+  ;; Would 0 work here?
+  32)
 
-(set! make-nmv-header
-(named-lambda (make-nmv-header n)
-  (bit-string-append (unsigned-integer->bit-string 24 n)
-                    nmv-type-string)))
+(define padding-string
+  ;; Pad with `DIAG SCM' instructions
+  (unsigned-integer->bit-string maximum-padding-length
+                               #b00010100010100110100001101001101))
 
-(define nmv-type-string
-  (unsigned-integer->bit-string 8 (microcode-type 'MANIFEST-NM-VECTOR)))
+(define-integrable block-offset-width
+  ;; Block offsets are always 16 bit words
+  16)
+
+(define-integrable maximum-block-offset
+  ;; PC always aligned on longword boundary.  Use the extra bit.
+  (- (expt 2 (1+ block-offset-width)) 4))
+
+(define (block-offset->bit-string offset start?)
+  (unsigned-integer->bit-string block-offset-width
+                               (+ (quotient offset 2)
+                                  (if start? 0 1))))
 
-)
+(define (make-nmv-header n)
+  (bit-string-append (unsigned-integer->bit-string scheme-datum-width n)
+                    nmv-type-string))
+
+(define nmv-type-string
+  (unsigned-integer->bit-string scheme-type-width
+                               (ucode-type manifest-nm-vector)))
 
 (define (object->bit-string object)
   (bit-string-append
-   (unsigned-integer->bit-string 24 (primitive-datum object))
-   (unsigned-integer->bit-string 8 (primitive-type object))))
\ No newline at end of file
+   (unsigned-integer->bit-string scheme-datum-width
+                                (careful-object-datum object))
+   (unsigned-integer->bit-string scheme-type-width (object-type object))))
+
+;;; Machine dependent instruction order
+
+(define (instruction-insert! bits block position receiver)
+  (let* ((l (bit-string-length bits))
+        (new-position (- position l)))
+    (bit-substring-move-right! bits 0 l block new-position)
+    (receiver new-position)))
+
+(define instruction-initial-position bit-string-length)
+(define-integrable instruction-append bit-string-append-reversed)
+
+;;; end let-syntax
+)
\ No newline at end of file
index eb8c4c818d1a9525b308c0734ec829be07979931..e9e74a1eaf55e192c6ae97cecc38bd4df7e9cdcd 100644 (file)
@@ -1,8 +1,9 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/coerce.scm,v 1.4 1987/03/19 00:54:46 cph Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/coerce.scm,v 1.5 1990/01/25 16:30:05 jinx Rel $
+$MC68020-Header: coerce.scm,v 1.10 88/08/31 05:56:37 GMT cph Exp $
 
-Copyright (c) 1987 Massachusetts Institute of Technology
+Copyright (c) 1987, 1988, 1989, 1990 Massachusetts Institute of Technology
 
 This material was developed by the Scheme project at the Massachusetts
 Institute of Technology, Department of Electrical Engineering and
@@ -32,39 +33,10 @@ Technology nor of any adaptation thereof in any advertising,
 promotional, or sales literature without prior written consent from
 MIT in each case. |#
 
-;;;; Spectrum Specific Coercions
-
 (declare (usual-integrations))
 \f
-(define (parse-word expression tail)
-  (expand-descriptors (cdr expression)
-    (lambda (instruction size)
-      (if (not (zero? (remainder size 32)))
-         (error "PARSE-WORD: Instructions must be 32 bit multiples" size))
-      (let ((instruction (apply optimize-group-syntax instruction)))
-       (if (null? tail)
-           `(CONS ,instruction '())
-           `(CONS-SYNTAX ,instruction (CONS ,(car tail) '())))))))
-
-(define (expand-descriptors descriptors receiver)
-  (if (null? descriptors)
-      (receiver '() 0)
-      (expand-descriptors (cdr descriptors)
-       (lambda (instruction* size*)
-         (expand-descriptor (car descriptors)
-           (lambda (instruction size)
-             (receiver (append! instruction instruction*)
-                       (+ size size*))))))))
-
-(define (expand-descriptor descriptor receiver)
-  (let ((size (car descriptor)))
-    (receiver `(,(integer-syntaxer (cadr descriptor)
-                                  (if (null? (cddr descriptor))
-                                      'UNSIGNED
-                                      (caddr descriptor))
-                                  size))
-             size)))
-\f
+;;;; Strange hppa coercions
+
 (define (coerce-right-signed nbits)
   (let ((offset (1+ (expt 2 nbits))))
     (lambda (n)
@@ -73,57 +45,80 @@ MIT in each case. |#
                                        (+ (* n 2) offset)
                                        (* n 2))))))
 
-(define coerce-assemble3:x
-  (standard-coercion
-   (lambda (n)
-     (+ (* (land n 3) 2) (quotient n 4)))))
-
-(define coerce-assemble12:X
-  (standard-coercion
-   (lambda (n)
-     (let ((qr (integer-divide n 4)))
-       (if (not (zero? (integer-divide-remainder qr)))
-          (error "COERCE-ASSEMBLE12:X: offset not multiple of 4" n))
-       (let ((n (integer-divide-quotient qr)))
-        (+ (* (land n #x3FF) 2) (quotient (land n #x400) #x400)))))))
-
-(define coerce-assemble12:Y
-  (standard-coercion
-   (lambda (n)
-     (quotient (land (quotient n 4) #x800) #x800))))
-
-(define coerce-assemble17:X
-  (standard-coercion
-   (lambda (n)
-     (let ((qr (integer-divide n 4)))
-       (if (not (zero? (integer-divide-remainder qr)))
-          (error "COERCE-ASSEMBLE17:X: offset not multiple of 4" n))
-       (quotient (land (integer-divide-quotient qr) #xF800) #x800)))))
-
-(define coerce-assemble17:Y
-  (standard-coercion
-   (lambda (n)
-     (let ((n (quotient n 4)))
-       (+ (quotient (land n #x400) #x400) (* (land n #x3FF) 2))))))
-
-(define coerce-assemble17:Z
-  (standard-coercion
-   (lambda (n)
-     (+ (quotient (land (quotient n 4) #x10000) #x10000)))))
-
-(define coerce-assemble21:X
-  (standard-coercion
-   (lambda (n)
-     (+ (* (land n #x7C) #x4000)
-       (* (land n #x180) #x80)
-       (* (land n #x3) #x1000)
-       (quotient (land n #xFFE00) #x100)
-       (quotient (land n #x100000) #x100000)))))
+(define (coerce-assemble12:x nbits)
+  (let ((range (expt 2 11)))
+    (lambda (n)
+      (let ((n (machine-word-offset n range))
+           (r (unsigned-integer->bit-string nbits 0)))
+       (bit-substring-move-right! n 0 10 r 1)
+       (bit-substring-move-right! n 10 11 r 0)
+       r))))
+
+(define (coerce-assemble12:y nbits)
+  (let ((range (expt 2 11)))
+    (lambda (n)
+      (let ((r (unsigned-integer->bit-string nbits 0)))
+       (bit-substring-move-right! (machine-word-offset n range) 11 12 r 0)
+       r))))
+
+(define (coerce-assemble17:x nbits)
+  (let ((range (expt 2 16)))
+    (lambda (n)
+      (let ((r (unsigned-integer->bit-string nbits 0)))
+       (bit-substring-move-right! (machine-word-offset n range) 11 16 r 0)
+       r))))
+
+(define (coerce-assemble17:y nbits)
+  (let ((range (expt 2 16)))
+    (lambda (n)
+      (let ((n (machine-word-offset n range))
+           (r (unsigned-integer->bit-string nbits 0)))
+       (bit-substring-move-right! n 0 10 r 1)
+       (bit-substring-move-right! n 10 11 r 0)
+       r))))
+
+(define (coerce-assemble17:z nbits)
+  (let ((range (expt 2 16)))
+    (lambda (n)
+      (let ((r (unsigned-integer->bit-string nbits 0)))
+       (bit-substring-move-right! (machine-word-offset n range) 16 17 r 0)
+       r))))
+
+(define (coerce-assemble21:x nbits)
+  ;; This one does not check for range.  Should it?
+  (lambda (n)
+    (let ((n (integer->word n))
+         (r (unsigned-integer->bit-string nbits 0)))
+      (bit-substring-move-right! n 0 2 r 12)
+      (bit-substring-move-right! n 2 7 r 16)
+      (bit-substring-move-right! n 7 9 r 14)
+      (bit-substring-move-right! n 9 20 r 1)
+      (bit-substring-move-right! n 20 21 r 0)
+      r)))
+
+(define (machine-word-offset n range)
+  (let ((value (integer-divide n 4)))
+    (if (not (zero? (integer-divide-remainder value)))
+       (error "machine-word-offset: Invalid offset" n))
+    (let ((result (integer-divide-quotient value)))
+      (if (and (< result range)
+              (>= result (- range)))
+         (integer->word result)
+         (error "machine-word-offset: Doesn't fit" n range)))))
+
+(define (integer->word x)
+  (unsigned-integer->bit-string
+   32
+   (let ((x (if (negative? x) (+ x #x100000000) x)))
+     (if (not (and (not (negative? x)) (< x #x100000000)))
+        (error "Integer too large to be encoded" x))
+     x)))
 \f
+;;; Coercion top level
+
 (define make-coercion
   (coercion-maker
-   `((ASSEMBLE3:X . ,coerce-assemble3:x)
-     (ASSEMBLE12:X . ,coerce-assemble12:x)
+   `((ASSEMBLE12:X . ,coerce-assemble12:x)
      (ASSEMBLE12:Y . ,coerce-assemble12:y)
      (ASSEMBLE17:X . ,coerce-assemble17:x)
      (ASSEMBLE17:Y . ,coerce-assemble17:y)
@@ -133,34 +128,34 @@ MIT in each case. |#
      (UNSIGNED . ,coerce-unsigned-integer)
      (SIGNED . ,coerce-signed-integer))))
 
-(define-coercion 'UNSIGNED 1)
-(define-coercion 'UNSIGNED 2)
-(define-coercion 'UNSIGNED 3)
-(define-coercion 'UNSIGNED 4)
-(define-coercion 'UNSIGNED 5)
-(define-coercion 'UNSIGNED 6)
-(define-coercion 'UNSIGNED 7)
-(define-coercion 'UNSIGNED 8)
-(define-coercion 'UNSIGNED 9)
-(define-coercion 'UNSIGNED 10)
-(define-coercion 'UNSIGNED 11)
-(define-coercion 'UNSIGNED 12)
-(define-coercion 'UNSIGNED 13)
-(define-coercion 'UNSIGNED 14)
-(define-coercion 'UNSIGNED 16)
-(define-coercion 'UNSIGNED 32)
-
-(define-coercion 'SIGNED 8)
-(define-coercion 'SIGNED 16)
-(define-coercion 'SIGNED 32)
-
-(define-coercion 'RIGHT-SIGNED 5)
-(define-coercion 'RIGHT-SIGNED 11)
-(define-coercion 'RIGHT-SIGNED 14)
-(define-coercion 'ASSEMBLE3:X 3)
-(define-coercion 'ASSEMBLE12:X 11)
-(define-coercion 'ASSEMBLE12:Y 1)
-(define-coercion 'ASSEMBLE17:X 5)
-(define-coercion 'ASSEMBLE17:Y 11)
-(define-coercion 'ASSEMBLE17:Z 1)
-(define-coercion 'ASSEMBLE21:X 21)
\ No newline at end of file
+(define coerce-1-bit-unsigned (make-coercion 'UNSIGNED 1))
+(define coerce-2-bit-unsigned (make-coercion 'UNSIGNED 2))
+(define coerce-3-bit-unsigned (make-coercion 'UNSIGNED 3))
+(define coerce-4-bit-unsigned (make-coercion 'UNSIGNED 4))
+(define coerce-5-bit-unsigned (make-coercion 'UNSIGNED 5))
+(define coerce-6-bit-unsigned (make-coercion 'UNSIGNED 6))
+(define coerce-7-bit-unsigned (make-coercion 'UNSIGNED 7))
+(define coerce-8-bit-unsigned (make-coercion 'UNSIGNED 8))
+(define coerce-9-bit-unsigned (make-coercion 'UNSIGNED 9))
+(define coerce-10-bit-unsigned (make-coercion 'UNSIGNED 10))
+(define coerce-11-bit-unsigned (make-coercion 'UNSIGNED 11))
+(define coerce-12-bit-unsigned (make-coercion 'UNSIGNED 12))
+(define coerce-13-bit-unsigned (make-coercion 'UNSIGNED 13))
+(define coerce-14-bit-unsigned (make-coercion 'UNSIGNED 14))
+(define coerce-15-bit-unsigned (make-coercion 'UNSIGNED 15))
+(define coerce-16-bit-unsigned (make-coercion 'UNSIGNED 16))
+(define coerce-32-bit-unsigned (make-coercion 'UNSIGNED 32))
+
+(define coerce-8-bit-signed (make-coercion 'SIGNED 8))
+(define coerce-16-bit-signed (make-coercion 'SIGNED 16))
+(define coerce-32-bit-signed (make-coercion 'SIGNED 32))
+
+(define coerce-5-bit-right-signed (make-coercion 'RIGHT-SIGNED 5))
+(define coerce-11-bit-right-signed (make-coercion 'RIGHT-SIGNED 11))
+(define coerce-14-bit-right-signed (make-coercion 'RIGHT-SIGNED 14))
+(define coerce-11-bit-assemble12:x (make-coercion 'ASSEMBLE12:X 11))
+(define coerce-1-bit-assemble12:y (make-coercion 'ASSEMBLE12:Y 1))
+(define coerce-5-bit-assemble17:x (make-coercion 'ASSEMBLE17:X 5))
+(define coerce-11-bit-assemble17:y (make-coercion 'ASSEMBLE17:Y 11))
+(define coerce-1-bit-assemble17:z (make-coercion 'ASSEMBLE17:Z 1))
+(define coerce-21-bit-assemble21:x (make-coercion 'ASSEMBLE21:X 21))
\ No newline at end of file
diff --git a/v7/src/compiler/machines/spectrum/dassm1.scm b/v7/src/compiler/machines/spectrum/dassm1.scm
new file mode 100644 (file)
index 0000000..3d51ec2
--- /dev/null
@@ -0,0 +1,289 @@
+#| -*-Scheme-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/dassm1.scm,v 4.14 1990/01/25 16:31:23 jinx Exp $
+$MC68020-Header: dassm1.scm,v 4.14 89/10/26 07:37:28 GMT cph Exp $
+
+Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science.  Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. |#
+
+;;;; Disassembler: User Level
+
+(declare (usual-integrations))
+\f
+;;; Flags that control disassembler behavior
+
+(define disassembler/symbolize-output? true)
+(define disassembler/compiled-code-heuristics? true)
+(define disassembler/write-offsets? true)
+(define disassembler/write-addresses? false)
+
+;;;; Top level entries
+
+(define (compiler:write-lap-file filename #!optional symbol-table?)
+  (let ((pathname (->pathname filename)))
+    (with-output-to-file (pathname-new-type pathname "lap")
+      (lambda ()
+       (let ((com-file (pathname-new-type pathname "com")))
+         (let ((object (fasload com-file))
+               (info
+                (let ((pathname (pathname-new-type pathname "binf")))
+                  (and (if (default-object? symbol-table?)
+                           (file-exists? pathname)
+                           symbol-table?)
+                       (fasload pathname)))))
+           (if (compiled-code-address? object)
+               (disassembler/write-compiled-code-block
+                (compiled-code-address->block object)
+                info)
+               (begin
+                 (if (not
+                      (and (scode/comment? object)
+                           (dbg-info-vector? (scode/comment-text object))))
+                     (error "Not a compiled file" com-file))
+                 (let ((items
+                        (vector->list
+                         (dbg-info-vector/blocks-vector
+                          (scode/comment-text object)))))
+                   (if (not (null? items))
+                       (if (false? info)
+                           (let loop ((items items))
+                             (disassembler/write-compiled-code-block
+                              (car items)
+                              false)
+                             (if (not (null? (cdr items)))
+                                 (begin
+                                   (write-char #\page)
+                                   (loop (cdr items)))))
+                           (let loop
+                               ((items items) (info (vector->list info)))
+                             (disassembler/write-compiled-code-block
+                              (car items)
+                              (car info))
+                             (if (not (null? (cdr items)))
+                                 (begin
+                                   (write-char #\page)
+                                   (loop (cdr items) (cdr info))))))))))))))))
+
+(define disassembler/base-address)
+
+(define (compiler:disassemble entry)
+  (let ((block (compiled-entry/block entry)))
+    (let ((info (compiled-code-block/dbg-info block true)))
+      (fluid-let ((disassembler/write-offsets? true)
+                 (disassembler/write-addresses? true)
+                 (disassembler/base-address (object-datum block)))
+       (newline)
+       (newline)
+       (disassembler/write-compiled-code-block block info)))))
+\f
+;;; Operations exported from the disassembler package
+
+(define disassembler/instructions)
+(define disassembler/instructions/null?)
+(define disassembler/instructions/read)
+(define disassembler/lookup-symbol)
+(define disassembler/read-variable-cache)
+(define disassembler/read-procedure-cache)
+(define compiled-code-block/objects-per-procedure-cache)
+(define compiled-code-block/objects-per-variable-cache)
+
+(define (disassembler/write-compiled-code-block block info)
+  (let ((symbol-table (and info (dbg-info/labels info))))
+    (write-string "Disassembly of ")
+    (write block)
+    (write-string ":\n")
+    (write-string "Code:\n\n")
+    (disassembler/write-instruction-stream
+     symbol-table
+     (disassembler/instructions/compiled-code-block block symbol-table))
+    (write-string "\nConstants:\n\n")
+    (disassembler/write-constants-block block symbol-table)
+    (newline)))
+
+(define (disassembler/instructions/compiled-code-block block symbol-table)
+  (disassembler/instructions block
+                            (compiled-code-block/code-start block)
+                            (compiled-code-block/code-end block)
+                            symbol-table))
+
+(define (disassembler/instructions/address start-address end-address)
+  (disassembler/instructions false start-address end-address false))
+
+(define (disassembler/write-instruction-stream symbol-table instruction-stream)
+  (fluid-let ((*unparser-radix* 16))
+    (disassembler/for-each-instruction instruction-stream
+      (lambda (offset instruction)
+       (disassembler/write-instruction symbol-table
+                                       offset
+                                       (lambda () (display instruction)))))))
+
+(define (disassembler/for-each-instruction instruction-stream procedure)
+  (let loop ((instruction-stream instruction-stream))
+    (if (not (disassembler/instructions/null? instruction-stream))
+       (disassembler/instructions/read instruction-stream
+         (lambda (offset instruction instruction-stream)
+           (procedure offset instruction)
+           (loop (instruction-stream)))))))
+\f
+(define (disassembler/write-constants-block block symbol-table)
+  (fluid-let ((*unparser-radix* 16))
+    (let ((end (system-vector-length block)))
+      (let loop ((index (compiled-code-block/constants-start block)))
+       (cond ((not (< index end)) 'DONE)
+             ((object-type?
+               (let-syntax ((ucode-type
+                             (macro (name) (microcode-type name))))
+                 (ucode-type linkage-section))
+               (system-vector-ref block index))
+              (loop (disassembler/write-linkage-section block
+                                                        symbol-table
+                                                        index)))
+             (else
+              (disassembler/write-instruction
+               symbol-table
+               (compiled-code-block/index->offset index)
+               (lambda ()
+                 (write-constant block
+                                 symbol-table
+                                 (system-vector-ref block index))))
+              (loop (1+ index))))))))
+
+(define (write-constant block symbol-table constant)
+  (write-string (cdr (write-to-string constant 60)))
+  (cond ((lambda? constant)
+        (let ((expression (lambda-body constant)))
+          (if (and (compiled-code-address? expression)
+                   (eq? (compiled-code-address->block expression) block))
+              (begin
+                (write-string "  (")
+                (let ((offset (compiled-code-address->offset expression)))
+                  (let ((label
+                         (disassembler/lookup-symbol symbol-table offset)))
+                    (if label
+                        (write-string label)
+                        (write offset))))
+                (write-string ")")))))
+       ((compiled-code-address? constant)
+        (write-string "  (offset ")
+        (write (compiled-code-address->offset constant))
+        (write-string " in ")
+        (write (compiled-code-address->block constant))
+        (write-string ")"))
+       (else false)))
+\f
+(define (disassembler/write-linkage-section block symbol-table index)
+  (define (write-caches index size how-many writer)
+    (let loop ((index index) (how-many how-many))
+      (if (zero? how-many)
+         'DONE
+         (begin
+           (disassembler/write-instruction
+            symbol-table
+            (compiled-code-block/index->offset index)
+            (lambda ()
+              (writer block index)))
+           (loop (+ size index) (-1+ how-many))))))
+
+  (let* ((field (object-datum (system-vector-ref block index)))
+        (descriptor (integer-divide field #x10000)))
+    (let ((kind (integer-divide-quotient descriptor))
+         (length (integer-divide-remainder descriptor)))
+      (disassembler/write-instruction
+       symbol-table
+       (compiled-code-block/index->offset index)
+       (lambda ()
+        (write-string "#[LINKAGE-SECTION ")
+        (write field)
+        (write-string "]")))
+      (write-caches
+       (1+ index)
+       compiled-code-block/objects-per-procedure-cache
+       (quotient length compiled-code-block/objects-per-procedure-cache)
+       (case kind
+        ((0)
+         disassembler/write-procedure-cache)
+        ((1)
+         (lambda (block index)
+           (disassembler/write-variable-cache "Reference" block index)))
+        ((2)
+         (lambda (block index)
+           (disassembler/write-variable-cache "Assignment" block index)))
+        (else
+         (error "disassembler/write-linkage-section: Unknown section kind"
+                kind))))
+      (1+ (+ index length)))))
+\f
+(define-integrable (variable-cache-name cache)
+  ((ucode-primitive primitive-object-ref 2) cache 1))
+
+(define (disassembler/write-variable-cache kind block index)
+  (write-string kind)
+  (write-string " cache to ")
+  (write (variable-cache-name (disassembler/read-variable-cache block index))))
+
+(define (disassembler/write-procedure-cache block index)
+  (let ((result (disassembler/read-procedure-cache block index)))
+    (write (vector-ref result 2))
+    (write-string " argument procedure cache to ")
+    (case (vector-ref result 0)
+      ((COMPILED INTERPRETED)
+       (write (vector-ref result 1)))
+      ((VARIABLE)
+       (write-string "variable ")
+       (write (vector-ref result 1)))
+      (else
+       (error "disassembler/write-procedure-cache: Unknown cache kind"
+             (vector-ref result 0))))))
+
+(define (disassembler/write-instruction symbol-table offset write-instruction)
+  (if symbol-table
+      (let ((label (dbg-labels/find-offset symbol-table offset)))
+       (if label
+           (begin
+             (write-char #\Tab)
+             (write-string (dbg-label/name label))
+             (write-char #\:)
+             (newline)))))
+
+  (if disassembler/write-addresses?
+      (begin
+       (write-string
+        (number->string (+ offset disassembler/base-address) 16))
+       (write-char #\Tab)))
+  
+  (if disassembler/write-offsets?
+      (begin
+       (write-string (number->string offset 16))
+       (write-char #\Tab)))
+
+  (if symbol-table
+      (write-string "    "))
+  (write-instruction)
+  (newline))
diff --git a/v7/src/compiler/machines/spectrum/dassm2.scm b/v7/src/compiler/machines/spectrum/dassm2.scm
new file mode 100644 (file)
index 0000000..8940e99
--- /dev/null
@@ -0,0 +1,254 @@
+#| -*-Scheme-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/dassm2.scm,v 4.16 1990/01/25 16:32:26 jinx Exp $
+$MC68020-Header: dassm2.scm,v 4.16 89/12/11 06:16:42 GMT cph Exp $
+
+Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science.  Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. |#
+
+;;;; Spectrum Disassembler: Top Level
+
+(declare (usual-integrations))
+\f
+(set! compiled-code-block/bytes-per-object 4)
+(set! compiled-code-block/objects-per-procedure-cache 3)
+(set! compiled-code-block/objects-per-variable-cache 1)
+
+(set! disassembler/read-variable-cache
+      (lambda (block index)
+       (let-syntax ((ucode-type
+                     (macro (name) (microcode-type name)))
+                    (ucode-primitive
+                     (macro (name arity)
+                       (make-primitive-procedure name arity))))
+         ((ucode-primitive primitive-object-set-type 2)
+          (ucode-type quad)
+          (system-vector-ref block index)))))
+
+(set! disassembler/read-procedure-cache
+      (lambda (block index)
+       (fluid-let ((*block block))
+         (let* ((offset (compiled-code-block/index->offset index)))
+           ;; For now
+           (error "disassembler/read-procedure-cache: Not written")))))
+\f
+(set! disassembler/instructions
+  (lambda (block start-offset end-offset symbol-table)
+    (let loop ((offset start-offset) (state (disassembler/initial-state)))
+      (if (and end-offset (< offset end-offset))
+         (disassemble-one-instruction block offset symbol-table state
+           (lambda (offset* instruction state)
+             (make-instruction offset
+                               instruction
+                               (lambda () (loop offset* state)))))
+         '()))))
+
+(set! disassembler/instructions/null?
+  null?)
+
+(set! disassembler/instructions/read
+  (lambda (instruction-stream receiver)
+    (receiver (instruction-offset instruction-stream)
+             (instruction-instruction instruction-stream)
+             (instruction-next instruction-stream))))
+
+(define-structure (instruction (type vector))
+  (offset false read-only true)
+  (instruction false read-only true)
+  (next false read-only true))
+
+(define *block)
+(define *current-offset)
+(define *symbol-table)
+(define *ir)
+(define *valid?)
+
+(define (disassemble-one-instruction block offset symbol-table state receiver)
+  (fluid-let ((*block block)
+             (*current-offset offset)
+             (*symbol-table symbol-table)
+             (*ir)
+             (*valid? true))
+    (set! *ir (get-longword))
+    (let ((start-offset *current-offset))
+      (if (external-label-marker? symbol-table offset state)
+         (receiver *current-offset
+                   (make-external-label *ir)
+                   'INSTRUCTION)
+         (let ((instruction (disassemble-word *ir)))
+           (if (not *valid?)
+               (let ((inst (make-word *ir)))
+                 (receiver start-offset
+                           inst
+                           (disassembler/next-state inst state)))
+               (let ((next-state (disassembler/next-state instruction state)))
+                 (receiver
+                  *current-offset
+                  (cond ((and (pair? state)
+                              (eq? (car state) 'PC-REL-LOW-OFFSET))
+                         (pc-relative-inst offset instruction (cadr state)))
+                       ((and (eq? 'PC-REL-OFFSET state)
+                             (not (pair? next-state)))
+                        (pc-relative-inst offset instruction false))
+                       (else
+                        instruction))
+                  next-state))))))))
+\f
+(define (pc-relative-inst start-address instruction left-side)
+  (let ((opcode (car instruction)))
+    (if (not (memq opcode '(LDO LDW)))
+       instruction
+       (let ((offset-exp (caddr instruction))
+             (target (cadddr instruction)))
+         (let ((offset (cadr offset-exp))
+               (space-reg (caddr offset-exp))
+               (base-reg (cadddr offset-exp)))
+           (let* ((real-address
+                   (+ start-address
+                      offset
+                      (if (not left-side)
+                          0
+                          (- (let ((val (* left-side #x800)))
+                               (if (>= val #x80000000)
+                                   (- val #x100000000)
+                                   val))
+                             4))))
+                  (label
+                   (disassembler/lookup-symbol *symbol-table real-address)))
+             (if (not label)
+                 instruction
+                 `(,opcode () (OFFSET ,(if left-side
+                                           `(RIGHT (- ,label (- *PC* 4)))
+                                           `(- ,label *PC*))
+                                      ,space-reg
+                                      ,base-reg)
+                           ,target))))))))         
+
+(define (disassembler/initial-state)
+  'INSTRUCTION-NEXT)
+
+(define (disassembler/next-state instruction state)
+  (cond ((not disassembler/compiled-code-heuristics?)
+        'INSTRUCTION)
+       ((and (eq? state 'INSTRUCTION)
+             (equal? instruction '(BL () 1 (@PCO 0))))
+        'PC-REL-DEP)
+       ((and (eq? state 'PC-REL-DEP)
+             (equal? instruction '(DEP () 0 31 2 1)))
+        'PC-REL-OFFSET)
+       ((and (eq? state 'PC-REL-OFFSET)
+             (= (length instruction) 4)
+             (equal? (list (car instruction)
+                           (cadr instruction)
+                           (cadddr instruction))
+                     '(ADDIL () 1)))
+        (list 'PC-REL-LOW-OFFSET (caddr instruction)))
+       ((memq (car instruction) '(B BV BLE))
+        'EXTERNAL-LABEL)
+       (else
+        'INSTRUCTION)))
+\f
+(set! disassembler/lookup-symbol
+  (lambda (symbol-table offset)
+    (and symbol-table
+        (let ((label (dbg-labels/find-offset symbol-table offset)))
+          (and label 
+               (dbg-label/name label))))))
+
+(define (external-label-marker? symbol-table offset state)
+  (if symbol-table
+      (let ((label (dbg-labels/find-offset symbol-table (+ offset 4))))
+       (and label
+            (dbg-label/external? label)))
+      (and *block
+          (not (eq? state 'INSTRUCTION))
+          (let loop ((offset (+ offset 4)))
+            (let ((contents (read-bits (- offset 2) 16)))
+              (if (bit-string-clear! contents 0)
+                  (let ((offset
+                         (- offset (* 2 (bit-string->unsigned-integer contents)))))
+                    (and (positive? offset)
+                         (loop offset)))
+                  (= offset (* 2 (bit-string->unsigned-integer contents)))))))))
+
+(define (make-word bit-string)
+  `(UWORD ,(bit-string->unsigned-integer bit-string)))
+
+(define (make-external-label bit-string)
+  `(EXTERNAL-LABEL ,(extract bit-string 16 32)
+                  (@PCO ,(* 4 (extract bit-string 1 16)))))
+
+#|
+;;; 68k version
+
+(define (read-procedure offset)
+  (with-absolutely-no-interrupts
+   (lambda ()
+     (let-syntax ((ucode-type
+                  (macro (name) (microcode-type name)))
+                 (ucode-primitive
+                  (macro (name arity)
+                    (make-primitive-procedure name arity))))
+       ((ucode-primitive primitive-object-set-type 2)
+       (ucode-type compiled-entry)
+       ((ucode-primitive make-non-pointer-object 1)
+        (read-unsigned-integer offset 32)))))))
+|#
+
+(define (read-procedure offset)
+  (error "read-procedure: Called" offset))
+
+(define (read-unsigned-integer offset size)
+  (bit-string->unsigned-integer (read-bits offset size)))
+
+(define (read-bits offset size-in-bits)
+  (let ((word (bit-string-allocate size-in-bits))
+       (bit-offset (* offset addressing-granularity)))
+    (with-absolutely-no-interrupts
+     (lambda ()
+       (if *block
+          (read-bits! *block bit-offset word)
+          (read-bits! offset 0 word))))
+    word))
+
+(define (invalid-instruction)
+  (set! *valid? false)
+  false)
+
+(define (offset->pc-relative pco reference-offset)
+  (if (not disassembler/symbolize-output?)
+      `(@PCO ,pco)
+      ;; Only add 4 because it has already been bumped to the
+      ;; next instruction.
+      (let* ((absolute (+ pco (+ 4 reference-offset)))
+            (label (disassembler/lookup-symbol *symbol-table absolute)))
+       (if label
+           `(@PCR ,label)
+           `(@PCO ,pco)))))
\ No newline at end of file
diff --git a/v7/src/compiler/machines/spectrum/decls.scm b/v7/src/compiler/machines/spectrum/decls.scm
new file mode 100644 (file)
index 0000000..566eace
--- /dev/null
@@ -0,0 +1,618 @@
+#| -*-Scheme-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/decls.scm,v 4.25 1990/01/25 16:34:14 jinx Exp $
+$MC68020-Header: decls.scm,v 4.25 90/01/18 22:43:31 GMT cph Exp $
+
+Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science.  Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. |#
+
+;;;; Compiler File Dependencies
+
+(declare (usual-integrations))
+\f
+(define (initialize-package!)
+  (add-event-receiver! event:after-restore reset-source-nodes!)
+  (reset-source-nodes!))
+
+(define (reset-source-nodes!)
+  (set! source-filenames '())
+  (set! source-hash)
+  (set! source-nodes)
+  (set! source-nodes/by-rank))
+
+(define (maybe-setup-source-nodes!)
+  (if (null? source-filenames)
+      (setup-source-nodes!)))
+
+(define (setup-source-nodes!)
+  (let ((filenames
+        (mapcan (lambda (subdirectory)
+                  (map (lambda (pathname)
+                         (string-append subdirectory
+                                        "/"
+                                        (pathname-name pathname)))
+                       (directory-read
+                        (string-append subdirectory
+                                       "/"
+                                       source-file-expression))))
+                '("back" "base" "fggen" "fgopt" "rtlbase" "rtlgen" "rtlopt"
+                         "machines/spectrum"))))
+    (if (null? filenames)
+       (error "Can't find source files of compiler"))
+    (set! source-filenames filenames))
+  (set! source-hash
+       (make/hash-table
+        101
+        string-hash-mod
+        (lambda (filename source-node)
+          (string=? filename (source-node/filename source-node)))
+        make/source-node))
+  (set! source-nodes
+       (map (lambda (filename)
+              (hash-table/intern! source-hash
+                                  filename
+                                  identity-procedure
+                                  identity-procedure))
+            source-filenames))
+  (initialize/syntax-dependencies!)
+  (initialize/integration-dependencies!)
+  (initialize/expansion-dependencies!)
+  (source-nodes/rank!))
+
+(define source-file-expression "*.scm")
+(define source-filenames)
+(define source-hash)
+(define source-nodes)
+(define source-nodes/by-rank)
+
+(define (filename/append directory . names)
+  (map (lambda (name) (string-append directory "/" name)) names))
+\f
+(define-structure (source-node
+                  (conc-name source-node/)
+                  (constructor make/source-node (filename)))
+  (filename false read-only true)
+  (pathname (string->pathname filename) read-only true)
+  (forward-links '())
+  (backward-links '())
+  (forward-closure '())
+  (backward-closure '())
+  (dependencies '())
+  (dependents '())
+  (rank false)
+  (syntax-table false)
+  (declarations '())
+  (modification-time false))
+
+(define (filename->source-node filename)
+  (hash-table/lookup source-hash
+                    filename
+                    identity-procedure
+                    (lambda () (error "Unknown source file" filename))))
+
+(define (source-node/circular? node)
+  (memq node (source-node/backward-closure node)))
+
+(define (source-node/link! node dependency)
+  (if (not (memq dependency (source-node/backward-links node)))
+      (begin
+       (set-source-node/backward-links!
+        node
+        (cons dependency (source-node/backward-links node)))
+       (set-source-node/forward-links!
+        dependency
+        (cons node (source-node/forward-links dependency)))
+       (source-node/close! node dependency))))
+
+(define (source-node/close! node dependency)
+  (if (not (memq dependency (source-node/backward-closure node)))
+      (begin
+       (set-source-node/backward-closure!
+        node
+        (cons dependency (source-node/backward-closure node)))
+       (set-source-node/forward-closure!
+        dependency
+        (cons node (source-node/forward-closure dependency)))
+       (for-each (lambda (dependency)
+                   (source-node/close! node dependency))
+                 (source-node/backward-closure dependency))
+       (for-each (lambda (node)
+                   (source-node/close! node dependency))
+                 (source-node/forward-closure node)))))
+\f
+;;;; Rank
+
+(define (source-nodes/rank!)
+  (compute-dependencies! source-nodes)
+  (compute-ranks! source-nodes)
+  (set! source-nodes/by-rank (source-nodes/sort-by-rank source-nodes)))
+
+(define (compute-dependencies! nodes)
+  (for-each (lambda (node)
+             (set-source-node/dependencies!
+              node
+              (list-transform-negative (source-node/backward-closure node)
+                (lambda (node*)
+                  (memq node (source-node/backward-closure node*)))))
+             (set-source-node/dependents!
+              node
+              (list-transform-negative (source-node/forward-closure node)
+                (lambda (node*)
+                  (memq node (source-node/forward-closure node*))))))
+           nodes))
+
+(define (compute-ranks! nodes)
+  (let loop ((nodes nodes) (unranked-nodes '()))
+    (if (null? nodes)
+       (if (not (null? unranked-nodes))
+           (loop unranked-nodes '()))
+       (loop (cdr nodes)
+             (let ((node (car nodes)))
+               (let ((rank (source-node/rank* node)))
+                 (if rank
+                     (begin
+                       (set-source-node/rank! node rank)
+                       unranked-nodes)
+                     (cons node unranked-nodes))))))))
+
+(define (source-node/rank* node)
+  (let loop ((nodes (source-node/dependencies node)) (rank -1))
+    (if (null? nodes)
+       (1+ rank)
+       (let ((rank* (source-node/rank (car nodes))))
+         (and rank*
+              (loop (cdr nodes) (max rank rank*)))))))
+
+(define (source-nodes/sort-by-rank nodes)
+  (sort nodes (lambda (x y) (< (source-node/rank x) (source-node/rank y)))))
+\f
+;;;; File Syntaxer
+
+(define (syntax-files!)
+  (maybe-setup-source-nodes!)
+  (for-each
+   (lambda (node)
+     (let ((modification-time
+           (let ((source (modification-time node "scm"))
+                 (binary (modification-time node "bin")))
+             (if (not source)
+                 (error "Missing source file" (source-node/filename node)))
+             (and binary (< source binary) binary))))
+     (set-source-node/modification-time! node modification-time)
+     (if (not modification-time)
+        (begin (write-string "\nSource file newer than binary: ")
+               (write (source-node/filename node))))))
+   source-nodes)
+  (if compiler:enable-integration-declarations?
+      (begin
+       (for-each
+        (lambda (node)
+          (let ((time (source-node/modification-time node)))
+            (if (and time
+                     (there-exists? (source-node/dependencies node)
+                       (lambda (node*)
+                         (let ((newer?
+                                (let ((time*
+                                       (source-node/modification-time node*)))
+                                  (or (not time*)
+                                      (> time* time)))))
+                           (if newer?
+                               (begin
+                                 (write-string "\nBinary file ")
+                                 (write (source-node/filename node))
+                                 (write-string " newer than dependency ")
+                                 (write (source-node/filename node*))))
+                           newer?))))
+                (set-source-node/modification-time! node false))))
+        source-nodes)
+       (for-each
+        (lambda (node)
+          (if (not (source-node/modification-time node))
+              (for-each (lambda (node*)
+                          (if (source-node/modification-time node*)
+                              (begin
+                                (write-string "\nBinary file ")
+                                (write (source-node/filename node*))
+                                (write-string " depends on ")
+                                (write (source-node/filename node))))
+                          (set-source-node/modification-time! node* false))
+                        (source-node/forward-closure node))))
+        source-nodes)))
+  (for-each (lambda (node)
+             (if (not (source-node/modification-time node))
+                 (pathname-delete!
+                  (pathname-new-type (source-node/pathname node) "ext"))))
+           source-nodes/by-rank)
+  (write-string "\n\nBegin pass 1:")
+  (for-each (lambda (node)
+             (if (not (source-node/modification-time node))
+                 (source-node/syntax! node)))
+           source-nodes/by-rank)
+  (if (there-exists? source-nodes/by-rank
+       (lambda (node)
+         (and (not (source-node/modification-time node))
+              (source-node/circular? node))))
+      (begin
+       (write-string "\n\nBegin pass 2:")
+       (for-each (lambda (node)
+                   (if (not (source-node/modification-time node))
+                       (if (source-node/circular? node)
+                           (source-node/syntax! node)
+                           (source-node/touch! node))))
+                 source-nodes/by-rank))))
+\f
+(define (source-node/touch! node)
+  (with-values
+      (lambda ()
+       (sf/pathname-defaulting (source-node/pathname node) "" false))
+    (lambda (input-pathname bin-pathname spec-pathname)
+      input-pathname
+      (pathname-touch! bin-pathname)
+      (pathname-touch! (pathname-new-type bin-pathname "ext"))
+      (if spec-pathname (pathname-touch! spec-pathname)))))
+
+(define (pathname-touch! pathname)
+  (if (file-exists? pathname)
+      (begin
+       (write-string "\nTouch file: ")
+       (write (pathname->string pathname))
+       (file-touch pathname))))
+
+(define (pathname-delete! pathname)
+  (if (file-exists? pathname)
+      (begin
+       (write-string "\nDelete file: ")
+       (write (pathname->string pathname))
+       (delete-file pathname))))
+
+(define (sc filename)
+  (maybe-setup-source-nodes!)
+  (source-node/syntax! (filename->source-node filename)))
+
+(define (source-node/syntax! node)
+  (with-values
+      (lambda ()
+       (sf/pathname-defaulting (source-node/pathname node) "" false))
+    (lambda (input-pathname bin-pathname spec-pathname)
+      (sf/internal
+       input-pathname bin-pathname spec-pathname
+       (source-node/syntax-table node)
+       ((if compiler:enable-integration-declarations?
+           identity-procedure
+           (lambda (declarations)
+             (list-transform-negative declarations
+               integration-declaration?)))
+       ((if compiler:enable-expansion-declarations?
+            identity-procedure
+            (lambda (declarations)
+              (list-transform-negative declarations
+                expansion-declaration?)))
+        (source-node/declarations node)))))))
+
+(define-integrable (modification-time node type)
+  (file-modification-time
+   (pathname-new-type (source-node/pathname node) type)))
+\f
+;;;; Syntax dependencies
+
+(define (initialize/syntax-dependencies!)
+  (let ((file-dependency/syntax/join
+        (lambda (filenames syntax-table)
+          (for-each (lambda (filename)
+                      (set-source-node/syntax-table!
+                       (filename->source-node filename)
+                       syntax-table))
+                    filenames))))
+    (file-dependency/syntax/join
+     (append (filename/append "base"
+                             "blocks" "cfg1" "cfg2" "cfg3" "constr"
+                             "contin" "crstop" "ctypes" "debug" "enumer"
+                             "infnew" "lvalue" "object" "pmerly" "proced"
+                             "refctx" "rvalue" "scode" "sets" "subprb"
+                             "toplev" "utils")
+            (filename/append "back"
+                             "asmmac" "bittop" "bitutl" "insseq" "lapgn1"
+                             "lapgn2" "lapgn3" "linear" "regmap" "symtab"
+                             "syntax")
+            (filename/append "machines/spectrum"
+                             "dassm1" "insmac" "machin" "rgspcm" "rulrew"
+                             "switch")
+            (filename/append "fggen"
+                             "declar" "fggen" "canon")
+            (filename/append "fgopt"
+                             "blktyp" "closan" "conect" "contan" "delint"
+                             "desenv" "envopt" "folcon" "offset" "operan"
+                             "order" "outer" "param" "reord" "reteqv" "reuse"
+                             "sideff" "simapp" "simple" "subfre" "varind")
+            (filename/append "rtlbase"
+                             "regset" "rgraph" "rtlcfg" "rtlcon" "rtlexp"
+                             "rtline" "rtlobj" "rtlreg" "rtlty1" "rtlty2"
+                             "valclass")
+            (filename/append "rtlgen"
+                             "fndblk" "fndvar" "opncod" "rgcomb" "rgproc"
+                             "rgretn" "rgrval" "rgstmt" "rtlgen")
+            (filename/append "rtlopt"
+                             "ralloc" "rcompr" "rcse1" "rcse2" "rcseep"
+                             "rcseht" "rcserq" "rcsesr" "rdebug" "rdflow"
+                             "rerite" "rinvex" "rlife" "rtlcsm"))
+     compiler-syntax-table)
+    (file-dependency/syntax/join
+     (filename/append "machines/spectrum"
+                     "lapgen"
+                     "rules1" "rules2" "rules3" "rules4" "rulfix" "rulflo")
+     lap-generator-syntax-table)
+    (file-dependency/syntax/join
+     (filename/append "machines/spectrum" "instr1" "instr2" "instr3")
+     assembler-syntax-table)))
+\f
+;;;; Integration Dependencies
+
+(define (initialize/integration-dependencies!)
+
+  (define (add-declaration! declaration filenames)
+    (for-each (lambda (filenames)
+               (let ((node (filename->source-node filenames)))
+                 (set-source-node/declarations!
+                  node
+                  (cons declaration
+                        (source-node/declarations node)))))
+             filenames))
+
+  (let ((front-end-base
+        (filename/append "base"
+                         "blocks" "cfg1" "cfg2" "cfg3"
+                         "contin" "ctypes" "enumer" "lvalue"
+                         "object" "proced" "rvalue"
+                         "scode" "subprb" "utils"))
+       (spectrum-base
+        (filename/append "machines/spectrum" "machin"))
+       (rtl-base
+        (filename/append "rtlbase"
+                         "regset" "rgraph" "rtlcfg" "rtlobj"
+                         "rtlreg" "rtlty1" "rtlty2"))
+       (cse-base
+        (filename/append "rtlopt"
+                         "rcse1" "rcse2" "rcseep" "rcseht" "rcserq" "rcsesr"))
+       (instruction-base
+        (filename/append "machines/spectrum" "assmd" "machin"))
+       (lapgen-base
+        (append (filename/append "back" "lapgn3" "regmap")
+                (filename/append "machines/spectrum" "lapgen")))
+       (assembler-base
+        (append (filename/append "back" "symtab")
+                (filename/append "machines/spectrum" "instr1")))
+       (lapgen-body
+        (append
+         (filename/append "back" "lapgn1" "lapgn2" "syntax")
+         (filename/append "machines/spectrum"
+                          "rules1" "rules2" "rules3" "rules4"
+                          "rulfix" "rulflo")))
+       (assembler-body
+        (append
+         (filename/append "back" "bittop")
+         (filename/append "machines/spectrum"
+                          "instr1" "instr2" "instr3"))))
+
+    (define (file-dependency/integration/join filenames dependencies)
+      (for-each (lambda (filename)
+                 (file-dependency/integration/make filename dependencies))
+               filenames))
+
+    (define (file-dependency/integration/make filename dependencies)
+      (let ((node (filename->source-node filename)))
+       (for-each (lambda (dependency)
+                   (let ((node* (filename->source-node dependency)))
+                     (if (not (eq? node node*))
+                         (source-node/link! node node*))))
+                 dependencies)))
+
+    (define (define-integration-dependencies directory name directory* . names)
+      (file-dependency/integration/make
+       (string-append directory "/" name)
+       (apply filename/append directory* names)))
+
+    (define-integration-dependencies "base" "object" "base" "enumer")
+    (define-integration-dependencies "base" "enumer" "base" "object")
+    (define-integration-dependencies "base" "utils" "base" "scode")
+    (define-integration-dependencies "base" "cfg1" "base" "object")
+    (define-integration-dependencies "base" "cfg2" "base"
+      "cfg1" "cfg3" "object")
+    (define-integration-dependencies "base" "cfg3" "base" "cfg1" "cfg2")
+    (define-integration-dependencies "base" "ctypes" "base"
+      "blocks" "cfg1" "cfg2" "cfg3" "contin" "lvalue" "object" "subprb")
+    (define-integration-dependencies "base" "rvalue" "base"
+      "blocks" "cfg1" "cfg2" "cfg3" "enumer" "lvalue" "object" "utils")
+    (define-integration-dependencies "base" "lvalue" "base"
+      "blocks" "object" "proced" "rvalue" "utils")
+    (define-integration-dependencies "base" "blocks" "base"
+      "enumer" "lvalue" "object" "proced" "rvalue" "scode")
+    (define-integration-dependencies "base" "proced" "base"
+      "blocks" "cfg1" "cfg2" "cfg3" "contin" "enumer" "lvalue" "object"
+      "rvalue" "utils")
+    (define-integration-dependencies "base" "contin" "base"
+      "blocks" "cfg3" "ctypes")
+    (define-integration-dependencies "base" "subprb" "base"
+      "cfg3" "contin" "enumer" "object" "proced")
+
+    (define-integration-dependencies "machines/spectrum" "machin" "rtlbase"
+      "rtlreg" "rtlty1" "rtlty2")
+
+    (define-integration-dependencies "rtlbase" "regset" "base")
+    (define-integration-dependencies "rtlbase" "rgraph" "base" "cfg1" "cfg2")
+    (define-integration-dependencies "rtlbase" "rgraph" "machines/spectrum"
+      "machin")
+    (define-integration-dependencies "rtlbase" "rtlcfg" "base"
+      "cfg1" "cfg2" "cfg3")
+    (define-integration-dependencies "rtlbase" "rtlcon" "base" "cfg3" "utils")
+    (define-integration-dependencies "rtlbase" "rtlcon" "machines/spectrum"
+      "machin")
+    (define-integration-dependencies "rtlbase" "rtlexp" "rtlbase"
+      "rtlreg" "rtlty1")
+    (define-integration-dependencies "rtlbase" "rtline" "base" "cfg1" "cfg2")
+    (define-integration-dependencies "rtlbase" "rtline" "rtlbase"
+      "rtlcfg" "rtlty2")
+    (define-integration-dependencies "rtlbase" "rtlobj" "base"
+      "cfg1" "object" "utils")
+    (define-integration-dependencies "rtlbase" "rtlreg" "machines/spectrum"
+      "machin")
+    (define-integration-dependencies "rtlbase" "rtlreg" "rtlbase"
+      "rgraph" "rtlty1")
+    (define-integration-dependencies "rtlbase" "rtlty1" "rtlbase" "rtlcfg")
+    (define-integration-dependencies "rtlbase" "rtlty2" "base" "scode")
+    (define-integration-dependencies "rtlbase" "rtlty2" "machines/spectrum"
+      "machin")
+    (define-integration-dependencies "rtlbase" "rtlty2" "rtlbase" "rtlty1")
+
+    (file-dependency/integration/join
+     (append
+      (filename/append "base" "refctx")
+      (filename/append "fggen"
+                      "declar" "fggen") ; "canon" needs no integrations
+      (filename/append "fgopt"
+                      "blktyp" "closan" "conect" "contan" "delint" "desenv"
+                      "envopt" "folcon" "offset" "operan" "order" "param"
+                      "outer" "reuse" "reteqv" "sideff" "simapp" "simple"
+                      "subfre" "varind"))
+     (append spectrum-base front-end-base))
+
+    (define-integration-dependencies "fgopt" "reuse" "fgopt" "reord")
+
+    (file-dependency/integration/join
+     (filename/append "rtlgen"
+                     "fndblk" "fndvar" "opncod" "rgcomb" "rgproc" "rgretn"
+                     "rgrval" "rgstmt" "rtlgen")
+     (append spectrum-base front-end-base rtl-base))
+
+    (file-dependency/integration/join
+     (append cse-base
+            (filename/append "rtlopt" "ralloc" "rcompr" "rdebug" "rdflow"
+                             "rerite" "rinvex" "rlife" "rtlcsm")
+            (filename/append "machines/spectrum" "rulrew"))
+     (append spectrum-base rtl-base))
+
+    (file-dependency/integration/join cse-base cse-base)
+
+    (define-integration-dependencies "rtlopt" "rcseht" "base" "object")
+    (define-integration-dependencies "rtlopt" "rcserq" "base" "object")
+    (define-integration-dependencies "rtlopt" "rlife"  "base" "cfg2")
+
+    (let ((dependents
+          (append instruction-base
+                  lapgen-base
+                  lapgen-body
+                  assembler-base
+                  assembler-body
+                  (filename/append "back" "linear" "syerly"))))
+      (add-declaration! '(USUAL-DEFINITION (SET EXPT)) dependents)
+      (file-dependency/integration/join dependents instruction-base))
+
+    (file-dependency/integration/join (append lapgen-base lapgen-body)
+                                     lapgen-base)
+
+    (file-dependency/integration/join (append assembler-base assembler-body)
+                                     assembler-base)
+
+    (define-integration-dependencies "back" "lapgn1" "base"
+      "cfg1" "cfg2" "utils")
+    (define-integration-dependencies "back" "lapgn1" "rtlbase"
+      "regset" "rgraph" "rtlcfg")
+    (define-integration-dependencies "back" "lapgn2" "rtlbase" "rtlreg")
+    (define-integration-dependencies "back" "lapgn3" "rtlbase" "rtlcfg")
+    (define-integration-dependencies "back" "linear" "base" "cfg1" "cfg2")
+    (define-integration-dependencies "back" "linear" "rtlbase" "rtlcfg")
+    (define-integration-dependencies "back" "mermap" "back" "regmap")
+    (define-integration-dependencies "back" "regmap" "base" "utils")
+    (define-integration-dependencies "back" "symtab" "base" "utils"))
+
+  (for-each (lambda (node)
+             (let ((links (source-node/backward-links node)))
+               (if (not (null? links))
+                   (set-source-node/declarations!
+                    node
+                    (cons (make-integration-declaration
+                           (source-node/pathname node)
+                           (map source-node/pathname links))
+                          (source-node/declarations node))))))
+           source-nodes))
+
+(define (make-integration-declaration pathname integration-dependencies)
+  `(INTEGRATE-EXTERNAL
+    ,@(map (let ((default
+                 (make-pathname
+                  false
+                  false
+                  (make-list (length (pathname-directory pathname)) 'UP)
+                  false
+                  false
+                  false)))
+            (lambda (pathname)
+              (merge-pathnames pathname default)))
+          integration-dependencies)))
+
+(define-integrable (integration-declaration? declaration)
+  (eq? (car declaration) 'INTEGRATE-EXTERNAL))
+\f
+;;;; Expansion Dependencies
+
+(define (initialize/expansion-dependencies!)
+  (let ((file-dependency/expansion/join
+        (lambda (filenames expansions)
+          (for-each (lambda (filename)
+                      (let ((node (filename->source-node filename)))
+                        (set-source-node/declarations!
+                         node
+                         (cons (make-expansion-declaration expansions)
+                               (source-node/declarations node)))))
+                    filenames))))
+    (file-dependency/expansion/join
+     (filename/append "machines/spectrum"
+                     "lapgen" "rules1" "rules2" "rules3" "rules4"
+                     "rulfix" "rulflo")
+     (map (lambda (entry)
+           `(,(car entry)
+             (PACKAGE/REFERENCE (FIND-PACKAGE '(COMPILER LAP-SYNTAXER))
+                                ',(cadr entry))))
+         '((LAP:SYNTAX-INSTRUCTION LAP:SYNTAX-INSTRUCTION-EXPANDER)
+           (INSTRUCTION->INSTRUCTION-SEQUENCE
+            INSTRUCTION->INSTRUCTION-SEQUENCE-EXPANDER)
+           (SYNTAX-EVALUATION SYNTAX-EVALUATION-EXPANDER)
+           (CONS-SYNTAX CONS-SYNTAX-EXPANDER)
+           (OPTIMIZE-GROUP-EARLY OPTIMIZE-GROUP-EXPANDER)
+           (EA-KEYWORD-EARLY EA-KEYWORD-EXPANDER)
+           (EA-MODE-EARLY EA-MODE-EXPANDER)
+           (EA-REGISTER-EARLY EA-REGISTER-EXPANDER)
+           (EA-EXTENSION-EARLY EA-EXTENSION-EXPANDER)
+           (EA-CATEGORIES-EARLY EA-CATEGORIES-EXPANDER))))))
+
+(define-integrable (make-expansion-declaration expansions)
+  `(EXPAND-OPERATOR ,@expansions))
+
+(define-integrable (expansion-declaration? declaration)
+  (eq? (car declaration) 'EXPAND-OPERATOR))
\ No newline at end of file
index ce8d90ebf360567d14dbb3d6ff8e02614f423b9d..a59d81c2c384096311ddb6b3b50faea00189ec8f 100644 (file)
@@ -1,8 +1,9 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/lapgen.scm,v 1.137 1987/04/12 00:25:26 cph Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/lapgen.scm,v 4.26 1990/01/25 16:38:08 jinx Exp $
+$MC68020-Header: lapgen.scm,v 4.26 90/01/18 22:43:36 GMT cph Exp $
 
-Copyright (c) 1987 Massachusetts Institute of Technology
+Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
 
 This material was developed by the Scheme project at the Massachusetts
 Institute of Technology, Department of Electrical Engineering and
@@ -32,1010 +33,538 @@ Technology nor of any adaptation thereof in any advertising,
 promotional, or sales literature without prior written consent from
 MIT in each case. |#
 
-;;;; RTL Rules for Spectrum
+;;;; RTL Rules for HPPA.  Shared utilities.
 
 (declare (usual-integrations))
 \f
-;;;; Interface to Allocator
-
-(define (register->register-transfer source destination)
-  `(,(machine->machine-register source destination)))
+;;;; Register-Allocator Interface
+
+(define (register->register-transfer source target)
+  (if (not (register-types-compatible? source target))
+      (error "Moving between incompatible register types" source target))
+  (case (register-type source)
+    ((GENERAL) (copy source target))
+    ((FLOAT) (fp-copy source target))
+    (else (error "unknown register type" source))))
+
+(define (home->register-transfer source target)
+  (memory->register-transfer (pseudo-register-displacement source)
+                            regnum:regs-pointer
+                            target))
+
+(define (register->home-transfer source target)
+  (register->memory-transfer source
+                            (pseudo-register-displacement target)
+                            regnum:regs-pointer))
+
+(define (reference->register-transfer source target)
+  (case (ea/mode source)
+    ((GR)
+     (copy (register-ea/register source) target))
+    ((FPR)
+     (fp-copy (fpr->float-register (register-ea/register source)) target))
+    ((OFFSET)
+     (memory->register-transfer (offset-ea/offset source)
+                               (offset-ea/register source)
+                               target))
+    (else
+     (error "unknown effective-address mode" source))))
+
+(define (pseudo-register-home register)
+  ;; Register block consists of 16 4-byte registers followed by 256
+  ;; 8-byte temporaries.
+  (INST-EA (OFFSET ,(pseudo-register-displacement register)
+                  0
+                  ,regnum:regs-pointer)))
+\f
+(define-integrable (sort-machine-registers registers)
+  registers)
+
+(define available-machine-registers
+  ;; g1 removed from this list since it is the target of ADDIL,
+  ;; needed to expand some rules.  g31 may want to be removed
+  ;; too.
+  (list
+   ;; g0 g1 g2 g3 g4 g5
+   g6 g7 g8 g9 g10 g11 g12 g13 g14 g15 g16 g17 g18
+   ;; g19 g20 g21 g22
+   g23 g24 g25 g26
+   ;; g27
+   g28 g29
+   ;; g30
+   g31
+   ;; fp0 fp1 fp2 fp3
+   fp4 fp5 fp6 fp6 fp7 fp8 fp9 fp10 fp11 fp12 fp13 fp14 fp15
+   ))
+
+(define-integrable (float-register? register)
+  (eq? (register-type register) 'FLOAT))
+
+(define-integrable (general-register? register)
+  (eq? (register-type register) 'GENERAL))
+
+(define-integrable (word-register? register)
+  (eq? (register-type register) 'GENERAL))
+      
+(define (register-types-compatible? type1 type2)
+  (boolean=? (eq? type1 'FLOAT) (eq? type2 'FLOAT)))
+
+(define (register-type register)
+  (cond ((machine-register? register)
+        (vector-ref
+         '#(GENERAL GENERAL GENERAL GENERAL GENERAL GENERAL GENERAL GENERAL
+            GENERAL GENERAL GENERAL GENERAL GENERAL GENERAL GENERAL GENERAL
+            GENERAL GENERAL GENERAL GENERAL GENERAL GENERAL GENERAL GENERAL
+            GENERAL GENERAL GENERAL GENERAL GENERAL GENERAL GENERAL GENERAL
+            FLOAT FLOAT FLOAT FLOAT FLOAT FLOAT FLOAT FLOAT
+            FLOAT FLOAT FLOAT FLOAT FLOAT FLOAT FLOAT FLOAT)
+         register))
+       ((register-value-class=word? register) 'GENERAL)
+       ((register-value-class=float? register) 'FLOAT)
+       (else (error "unable to determine register type" register))))
+
+(define register-reference
+  (let ((references (make-vector number-of-machine-registers)))
+    (let loop ((register 0))
+      (if (< register 32)
+         (begin
+           (vector-set! references register (INST-EA (GR ,register)))
+           (loop (1+ register)))))
+    (let loop ((register 32) (fpr 0))
+      (if (< register 48)
+         (begin
+           (vector-set! references register (INST-EA (FPR ,fpr)))
+           (loop (1+ register) (1+ fpr)))))
+    (lambda (register)
+      (vector-ref references register))))
+\f
+;;;; Useful Cliches
+
+(define (memory->register-transfer offset base target)
+  (case (register-type target)
+    ((GENERAL) (load-word offset base target))
+    ((FLOAT) (fp-load-doubleword offset base target))
+    (else (error "unknown register type" target))))
+
+(define (register->memory-transfer source offset base)
+  (case (register-type source)
+    ((GENERAL) (store-word source offset base))
+    ((FLOAT) (fp-store-doubleword source offset base))
+    (else (error "unknown register type" source))))
+
+(define (load-constant constant target)
+  ;; Load a Scheme constant into a machine register.
+  (if (non-pointer-object? constant)
+      (load-immediate (non-pointer->literal constant) target)
+      (load-pc-relative (constant->label constant) target)))
 
-(define (home->register-transfer source destination)
-  `(,(pseudo->machine-register source destination)))
+(define (load-non-pointer type datum target)
+  ;; Load a Scheme non-pointer constant, defined by type and datum,
+  ;; into a machine register.
+  (load-immediate (make-non-pointer-literal type datum) target))
 
-(define (register->home-transfer source destination)
-  `(,(machine->pseudo-register source destination)))
+(define (non-pointer->literal constant)
+  (make-non-pointer-literal (object-type constant)
+                           (careful-object-datum constant)))
 
-(define-integrable (pseudo->machine-register source target)
-  (memory->machine-register (pseudo-register-home source) target))
+(define-integrable (make-non-pointer-literal type datum)
+  (+ (* type type-scale-factor) datum))
 
-(define-integrable (machine->pseudo-register source target)
-  (machine-register->memory source (pseudo-register-home target)))
+(define-integrable type-scale-factor
+  (expt 2 scheme-datum-width))
 
-(define-integrable (pseudo-register-home register)
-  (index-reference regnum:regs-pointer
-                  (+ #x000A (register-renumber register))))
+(define-integrable (deposit-type type target)
+  (deposit-immediate type (-1+ scheme-type-width) scheme-type-width target))
 \f
-;;;; Basic machine instructions
-
-(define-integrable (machine->machine-register source target)
-  `(OR () ,source 0 ,target))
-
-(define-integrable (machine-register->memory source target)
-  `(STW () ,source ,target))
+;;;; Regularized Machine Instructions
+
+(define (copy r t)
+  (if (= r t)
+      (LAP)
+      (LAP (COPY () ,r ,t))))
+
+(define (load-immediate i t)
+  (if (fits-in-14-bits-signed? i)
+      (LAP (LDI () ,i ,t))
+      (let ((split (integer-divide i (expt 2 11))))
+       (LAP (LDIL () ,(integer-divide-quotient split) ,t)
+            ,@(let ((r%i (integer-divide-remainder split)))
+                (if (zero? r%i)
+                    (LAP)
+                    (LAP (LDO () (OFFSET ,r%i 0 ,t) ,t))))))))
+
+(define (deposit-immediate i p len t)
+  (if (fits-in-5-bits-signed? i)
+      (LAP (DEPI () ,i ,p ,len ,t))
+      (LAP ,@(load-immediate i regnum:addil-result)
+          (DEP () ,regnum:addil-result ,p ,len ,t))))
+
+(define (load-offset d b t)
+  (cond ((and (zero? d) (= b t))
+        (LAP))
+       ((fits-in-14-bits-signed? d)
+        (LAP (LDO () (OFFSET ,d 0 ,b) ,t)))
+       (else
+        (let ((split (integer-divide d (expt 2 11))))
+          (LAP (ADDIL () ,(integer-divide-quotient split) ,b)
+               (LDO () (OFFSET ,(integer-divide-remainder split) 0 1) ,t))))))
+
+(define (load-word d b t)
+  (if (fits-in-14-bits-signed? d)
+      (LAP (LDW () (OFFSET ,d 0 ,b) ,t))
+      (let ((split (integer-divide d (expt 2 11))))
+       (LAP (ADDIL () ,(integer-divide-quotient split) ,b)
+            (LDW () (OFFSET ,(integer-divide-remainder split) 0 1) ,t)))))
+
+(define (load-byte d b t)
+  (if (fits-in-14-bits-signed? d)
+      (LAP (LDB () (OFFSET ,d 0 ,b) ,t))
+      (let ((split (integer-divide d (expt 2 11))))
+       (LAP (ADDIL () ,(integer-divide-quotient split) ,b)
+            (LDB () (OFFSET ,(integer-divide-remainder split) 0 1) ,t)))))
+
+(define (store-word b d t)
+  (if (fits-in-14-bits-signed? d)
+      (LAP (STW () ,b (OFFSET ,d 0 ,t)))
+      (let ((split (integer-divide d (expt 2 11))))
+       (LAP (ADDIL () ,(integer-divide-quotient split) ,t)
+            (STW () ,b (OFFSET ,(integer-divide-remainder split) 0 1))))))
+
+(define (store-byte b d t)
+  (if (fits-in-14-bits-signed? d)
+      (LAP (STB () ,b (OFFSET ,d 0 ,t)))
+      (let ((split (integer-divide d (expt 2 11))))
+       (LAP (ADDIL () ,(integer-divide-quotient split) ,t)
+            (STB () ,b (OFFSET ,(integer-divide-remainder split) 0 1))))))
+\f
+(define (fp-copy r t)
+  (if (= r t)
+      (LAP)
+      (LAP (FCPY (DBL) ,(float-register->fpr r) ,(float-register->fpr t)))))
+
+(define (fp-load-doubleword d b t)
+  (let ((t (float-register->fpr t)))
+    (if (fits-in-5-bits-signed? d)
+       (LAP (FLDDS () (OFFSET ,d 0 ,b) ,t))
+       (LAP ,@(load-offset d b regnum:addil-result)
+            (FLDDS () (OFFSET 0 0 ,regnum:addil-result) ,t)))))
+
+(define (fp-store-doubleword r d b)
+  (let ((r (float-register->fpr r)))
+    (if (fits-in-5-bits-signed? d)
+       (LAP (FSTDS () ,r (OFFSET ,d 0 ,b)))
+       (LAP ,@(load-offset d b regnum:addil-result)
+            (FSTDS () ,r (OFFSET 0 0 ,regnum:addil-result))))))
+
+(define (load-pc-relative label target)
+  ;; Load a pc-relative location's contents into a machine register.
+  ;; This assumes that the offset fits in 14 bits!
+  ;; We should have a pseudo-op for LDW that does some "branch" tensioning.
+  (LAP (BL () ,regnum:addil-result (@PCO 0))
+       ;; Clear the privilege level, making this a memory address.
+       (DEP () 0 31 2 ,regnum:addil-result)
+       (LDW () (OFFSET (- ,label *PC*) 0 ,regnum:addil-result) ,target)))
+
+(define (load-pc-relative-address label target)
+  ;; Load a pc-relative address into a machine register.
+  ;; This assumes that the offset fits in 14 bits!
+  ;; We should have a pseudo-op for LDO that does some "branch" tensioning.
+  (LAP (BL () ,regnum:addil-result (@PCO 0))
+       ;; Clear the privilege level, making this a memory address.
+       (DEP () 0 31 2 ,regnum:addil-result)
+       (LDO () (OFFSET (- ,label *PC*) 0 ,regnum:addil-result) ,target)))
+\f
+;; NOPs are inserted since conditional nullification only nullifies
+;; depending on the sign of the branch offset, which is unknown at
+;; this point.  Linearizer can be changed, fairly easily, to tell us
+;; which direction the branch goes so we can decide whether the NOP is
+;; needed.
+
+(define (compare-immediate cc i r2)
+  (cond ((zero? i)
+        (compare cc 0 r2))
+       ((fits-in-5-bits-signed? i)
+        (let* ((inverted? (memq cc '(TR <> >= > >>= >> NSV EV
+                                        LTGT GTEQ GT GTGTEQ GTGT)))
+               (cc (if inverted? (invert-condition cc) cc))
+               (set-branches!
+                (lambda (if-true if-false)
+                  (if inverted?
+                      (set-current-branches! if-false if-true)
+                      (set-current-branches! if-true if-false)))))
+       
+          (set-branches!
+           (lambda (label)
+             (LAP (COMIBT (,cc) ,i ,r2 (@PCR ,label))
+                  (NOP ())))
+           (lambda (label)
+             (LAP (COMIBF (,cc) ,i ,r2 (@PCR ,label))
+                  (NOP ()))))
+          (LAP)))
+       ((fits-in-11-bits-signed? i)
+        (set-current-branches!
+         (lambda (label)
+           (LAP (COMICLR (,(invert-condition cc)) ,i ,r2 0)
+                (B (N) (@PCR ,label))))
+         (lambda (label)
+           (LAP (COMICLR (,cc) ,i ,r2 0)
+                (B (N) (@PCR ,label)))))
+        (LAP))
+       (else
+        (let ((temp (standard-temporary!)))
+          (LAP ,@(load-immediate i temp)
+               ,@(compare cc temp r2))))))
+
+(define (compare condition r1 r2)
+  (set-current-branches!
+   (lambda (label)
+     (LAP (COMB (,condition) ,r1 ,r2 (@PCR ,label))
+         (NOP ())))
+   (lambda (label)
+     (LAP (COMB (,(invert-condition condition)) ,r1 ,r2 (@PCR ,label))
+         (NOP ()))))
+  (LAP))
+\f
+;;;; Conditions
+
+(define (invert-condition condition)
+  (let ((place (assq condition condition-inversion-table)))
+    (if (not place)
+       (error "unknown condition" condition))
+    (cadr place)))
+
+(define (invert-condition-noncommutative condition)
+  (let ((place (assq condition condition-inversion-table)))
+    (if (not place)
+       (error "unknown condition" condition))
+    (caddr place)))
+
+(define condition-inversion-table
+  '((=         <>              =)
+    (<         >=              >)
+    (>         <=              <)
+    (NUV       UV              NUV)
+    (TR                NV              TR)
+    (<<                >>=             >>)
+    (>>                <<=             <<)
+    (<>                =               <>)
+    (<=                >               >=)
+    (>=                <               <=)
+    (<<=       >>              >>=)
+    (>>=       <<              <<=)
+    (NV                TR              NV)
+    (EQ                LTGT            EQ)
+    (LT                GTEQ            GT)
+    (SBZ       NBZ             SBZ)
+    (LTEQ      GT              GTEQ)
+    (SHZ       NHZ             SHZ)
+    (LTLT      GTGTEQ          GTGT)
+    (SDC       NDC             SDC)
+    (LTLTEQ    GTGT            GTGTEQ)
+    (ZNV       VNZ             ZNV)
+    (SV                NSV             SV)
+    (SBC       NBC             SBC)
+    (OD                EV              OD)
+    (SHC       NHC             SHC)
+    (LTGT      EQ              LTGT)
+    (GTEQ      LT              LTEQ)
+    (NBZ       SBZ             NBZ)
+    (GT                LTEQ            LT)
+    (NHZ       SHZ             NHZ)
+    (GTGTEQ    LTLT            LTLTEQ)
+    (UV                NUV             UV)
+    (NDC       SDC             NDC)
+    (GTGT      LTLTEQ          LTLT)
+    (VNZ       ZNV             NVZ)
+    (NSV       SV              NSV)
+    (NBC       SBC             NBC)
+    (EV                OD              EV)
+    (NHC       SHC             NHC)))
+\f
+;;;; Miscellaneous
+
+(define-integrable (object->datum src tgt)
+  (LAP (ZDEP () ,src 31 ,scheme-datum-width ,tgt)))
+
+(define-integrable (object->address reg)
+  (LAP (DEP ()
+           ,regnum:quad-bitmask
+           ,(-1+ scheme-type-width)
+           ,scheme-type-width
+           ,reg)))
+
+(define-integrable (object->type src tgt)
+  (LAP (EXTRU () ,src ,(-1+ scheme-type-width) ,scheme-type-width ,tgt)))
+
+(define (standard-unary-conversion source target conversion)
+  ;; `source' is any register, `target' a pseudo register.
+  (let ((source (standard-source! source)))
+    (conversion source (standard-target! target))))
+
+(define (standard-binary-conversion source1 source2 target conversion)
+  (let ((source1 (standard-source! source1))
+       (source2 (standard-source! source2)))
+    (conversion source1 source2 (standard-target! target))))
+
+(define (standard-source! register)
+  (load-alias-register! register (register-type register)))
+
+(define (standard-target! register)
+  (delete-dead-registers!)
+  (allocate-alias-register! register (register-type register)))
+
+(define-integrable (standard-temporary!)
+  (allocate-temporary-register! 'GENERAL))
+
+(define (standard-move-to-target! source target)
+  (move-to-alias-register! source (register-type source) target))
+
+(define (standard-move-to-temporary! source)
+  (move-to-temporary-register! source (register-type source)))
+
+(define (register-expression expression)
+  (case (rtl:expression-type expression)
+    ((REGISTER)
+     (rtl:register-number expression))
+    ((CONSTANT)
+     (let ((object (rtl:constant-value expression)))
+       (and (zero? (object-type object))
+           (zero? (object-datum object))
+           0)))
+    ((CONS-POINTER)
+     (and (let ((type (rtl:cons-pointer-type expression)))
+           (and (rtl:machine-constant? type)
+                (zero? (rtl:machine-constant-value type))))
+         (let ((datum (rtl:cons-pointer-datum expression)))
+           (and (rtl:machine-constant? datum)
+                (zero? (rtl:machine-constant-value datum))))
+         0))
+    (else false)))
+\f
+(define (define-arithmetic-method operator methods method)
+  (let ((entry (assq operator (cdr methods))))
+    (if entry
+       (set-cdr! entry method)
+       (set-cdr! methods (cons (cons operator method) (cdr methods)))))
+  operator)
 
-(define-integrable (machine-register->memory-post-increment source target)
-  ;; Used for heap allocation
-  `(STWM () ,source ,(index-reference target 1)))
+(define (lookup-arithmetic-method operator methods)
+  (cdr (or (assq operator (cdr methods))
+          (error "Unknown operator" operator))))
 
-(define-integrable (machine-register->memory-pre-decrement source target)
-  ;; Used for stack push
-  `(STWM () ,source ,(index-reference target -1)))
+(define (fits-in-5-bits-signed? value)
+  (<= #x-10 value #xF))
 
-(define-integrable (memory->machine-register source target)
-  `(LDW () ,source ,target))
+(define (fits-in-11-bits-signed? value)
+  (<= #x-400 value #x3FF))
 
-(define-integrable (memory-post-increment->machine-register source target)
-  ;; Used for stack pop
-  `(LDWM () ,(index-reference source 1) ,target))
+(define (fits-in-14-bits-signed? value)
+  (<= #x-2000 value #x1FFF))
 
-(define-integrable (invoke-entry entry)
-  `(BE (N) ,entry))
+(define-integrable (ea/mode ea) (car ea))
+(define-integrable (register-ea/register ea) (cadr ea))
+(define-integrable (offset-ea/offset ea) (cadr ea))
+(define-integrable (offset-ea/space ea) (caddr ea))
+(define-integrable (offset-ea/register ea) (cadddr ea))
 
-(define (assign&invoke-entry number target entry)
-  (if (<= -8192 number 8191)
-      `((BE () ,entry)
-       (LDI () ,number ,target))
-      `((LDIL () (LEFT ,number) ,target)
-       (BE () ,entry)
-       (LDO () (OFFSET (RIGHT ,number) ,target) ,target))))
+(define (pseudo-register-displacement register)
+  ;; Register block consists of 16 4-byte registers followed by 256
+  ;; 8-byte temporaries.
+  (+ (* 4 16) (* 8 (register-renumber register))))
 
-(define (branch->label label)
-  `(BL (N) ,(label-relative-expression label) 0))
+(define-integrable (float-register->fpr register)
+  ;; Float registers are represented by 32 through 47 in the RTL,
+  ;; corresponding to registers 0 through 15 in the machine.
+  (- register 32))
 
-(define-integrable (index-reference register offset)
-  `(INDEX ,(* 4 offset) 0 ,(register-reference register)))
+(define-integrable (fpr->float-register register)
+  (+ register 32))
 
-(define-integrable (offset-reference register offset)
-  `(OFFSET ,(* 4 offset) ,(register-reference register)))
+(define-integrable reg:memtop
+  (INST-EA (OFFSET #x0000 0 ,regnum:regs-pointer)))
 
-(define-integrable (short-offset? offset)
-  (< offset 2048))
+(define-integrable reg:environment
+  (INST-EA (OFFSET #x000C 0 ,regnum:regs-pointer)))
 
-(define (load-memory source offset target)
-  `(LDW () ,(index-reference source offset) ,target))
+(define-integrable reg:lexpr-primitive-arity
+  (INST-EA (OFFSET #x001C 0 ,regnum:regs-pointer)))
 
-(define (store-memory source target offset)
-  `(STW () ,source ,(index-reference target offset)))
+(define (lap:make-label-statement label)
+  (INST (LABEL ,label)))
 
-(define (load-memory-increment source offset target)
-  `(LDWM () ,(index-reference source offset) ,target))
+(define (lap:make-unconditional-branch label)
+  (INST (B (N) (@PCR ,label))))
 
-(define (store-memory-increment source target offset)
-  `(STWM () ,source ,(index-reference target offset)))
-\f
-;;;; Instruction Sequence Generators
-
-(define (indirect-reference! register offset)
-  (index-reference
-   (if (machine-register? register)
-       register
-       (or (register-alias register false)
-          ;; This means that someone has written an address out
-          ;; to memory, something that should never happen.
-          (error "Needed to load indirect register!" register)))
-   offset))
-
-(define (object->address source #!optional target)
-  (if (unassigned? target) (set! target source))
-  `((EXTRU () ,source 31 24 ,target)
-    (OR () ,regnum:address-offset ,target ,target)))
-
-(define (register->machine-register register target)
-  (if (machine-register? register)
-      (machine->machine-register register target)
-      (let ((alias (register-alias register false)))
-       (if alias
-           (machine->machine-register alias target)
-           (pseudo->machine-register register target)))))
-
-(define (expression->machine-register! expression register)
-  (let ((result
-        (case (car expression)
-          ((REGISTER)
-           `(,(register->machine-register (cadr expression) register)))
-          ((OFFSET)
-           `(,(memory->machine-register
-               (indirect-reference! (cadadr expression) (caddr expression))
-               register)))
-          ((CONSTANT)
-           (scheme-constant->machine-register (cadr expression) register))
-          (else (error "Bad expression type" (car expression))))))
-    (delete-machine-register! register)
-    result))
-
-(package (register->memory
-         register->memory-post-increment
-         register->memory-pre-decrement)
-  (define ((->memory machine-register->memory) register target)
-    `(,(machine-register->memory (guarantee-machine-register! register false)
-                                target)))
-  (define-export register->memory
-    (->memory machine-register->memory))
-  (define-export register->memory-post-increment
-    (->memory machine-register->memory-post-increment))
-  (define-export register->memory-pre-decrement
-    (->memory machine-register->memory-pre-decrement)))
-\f
-(package (memory->memory
-         memory->memory-post-increment
-         memory->memory-pre-decrement)
-  (define ((->memory machine-register->memory) source target)
-    `(,(memory->machine-register source r1)
-      ,(machine-register->memory r1 target)))
-  (define-export memory->memory
-    (->memory machine-register->memory))
-  (define-export memory->memory-post-increment
-    (->memory machine-register->memory-post-increment))
-  (define-export memory->memory-pre-decrement
-    (->memory machine-register->memory-pre-decrement)))
-
-(package (memory-post-increment->memory
-         memory-post-increment->memory-post-increment
-         memory-post-increment->memory-pre-decrement)
-  (define ((->memory machine-register->memory) source target)
-    `(,(memory-post-increment->machine-register source r1)
-      ,(machine-register->memory r1 target)))
-  (define-export memory-post-increment->memory
-    (->memory machine-register->memory))
-  (define-export memory-post-increment->memory-post-increment
-    (->memory machine-register->memory-post-increment))
-  (define-export memory-post-increment->memory-pre-decrement
-    (->memory machine-register->memory-pre-decrement)))
-
-(package (scheme-constant->memory
-         scheme-constant->memory-post-increment
-         scheme-constant->memory-pre-decrement)
-  (define ((->memory machine-register->memory) constant target)
-    `(,@(scheme-constant->machine-register constant r1)
-      ,(machine-register->memory r1 target)))
-  (define-export scheme-constant->memory
-    (->memory machine-register->memory))
-  (define-export scheme-constant->memory-post-increment
-    (->memory machine-register->memory-post-increment))
-  (define-export scheme-constant->memory-pre-decrement
-    (->memory machine-register->memory-pre-decrement)))
-
-(define (scheme-constant->machine-register constant target)
-  (if (non-pointer-object? constant)
-      (non-pointer->machine-register (primitive-type constant)
-                                    (primitive-datum constant)
-                                    target)
-      `(,(memory->machine-register (scheme-constant-reference constant)
-                                  target))))
-
-(define-integrable (scheme-constant-reference constant)
-  `(INDEX ,(label->machine-constant (constant->label constant))
-         0
-         ,regnum:code-object-base))
-\f
-(define (non-pointer->machine-register type datum target)
-  (if (and (zero? datum)
-          (deposit-type-constant? type))
-      (if (zero? type)
-         `((OR () 0 0 ,target))
-         (with-type-deposit-parameters type
-           (lambda (const end)
-             `((ZDEPI () ,const ,end 5 ,target)))))
-      (let ((number (make-non-pointer type datum)))
-       (if (<= -8192 number 8191)
-           `((LDI () ,number ,target))
-           `((LDIL () (LEFT ,number) ,target)
-             (LDO () (OFFSET (RIGHT ,number) ,target) ,target))))))
-
-(package (non-pointer->memory
-         non-pointer->memory-post-increment
-         non-pointer->memory-pre-decrement)
-  (define ((->memory machine-register->memory) constant target)
-    `(,@(non-pointer->machine-register constant r1)
-      ,(machine-register->memory r1 target)))
-  (define-export non-pointer->memory
-    (->memory machine-register->memory))
-  (define-export non-pointer->memory-post-increment
-    (->memory machine-register->memory-post-increment))
-  (define-export non-pointer->memory-pre-decrement
-    (->memory machine-register->memory-pre-decrement)))
-
-(define (machine-constant->machine-register constant target)
-  (non-pointer->machine-register (machine-constant->type constant)
-                                (machine-constant->datum constant)
-                                target))
-
-(package (machine-constant->memory
-         machine-constant->memory-post-increment
-         machine-constant->memory-pre-decrement)
-  (define ((->memory machine-register->memory) constant target)
-    `(,@(machine-constant->machine-register constant r1)
-      ,(machine-register->memory r1 target)))
-  (define-export machine-constant->memory
-    (->memory machine-register->memory))
-  (define-export machine-constant->memory-post-increment
-    (->memory machine-register->memory-post-increment))
-  (define-export machine-constant->memory-pre-decrement
-    (->memory machine-register->memory-pre-decrement)))
-\f
-(define (label->machine-register label target)
-  (let ((constant (label->machine-constant label)))
-    `((ADDIL () (LEFT ,constant) ,regnum:code-object-base)
-      (LDO () (OFFSET (RIGHT ,constant) ,r1) ,target))))
-
-(define-integrable (label->machine-constant label)
-  `(- ,label ,(code-object-base)))
-
-(package (label->memory
-         label->memory-post-increment
-         label->memory-pre-decrement)
-  (define ((->memory machine-register->memory) type label target)
-    (let ((temp (allocate-temporary-register! false)))
-      `(,@(label->machine-register type label temp)
-       ,(machine-register->memory temp target))))
-  (define-export label->memory
-    (->memory machine-register->memory))
-  (define-export label->memory-post-increment
-    (->memory machine-register->memory-post-increment))
-  (define-export label->memory-pre-decrement
-    (->memory machine-register->memory-pre-decrement)))
-
-(define (typed-label->machine-register type label target)
-  `(,@(label->machine-register label target)
-    ,@(cons-pointer->machine-register type target target)))
-
-(package (typed-label->memory
-         typed-label->memory-post-increment
-         typed-label->memory-pre-decrement)
-  (define ((->memory machine-register->memory) type label target)
-    (let ((temp (allocate-temporary-register! false)))
-      `(,@(typed-label->machine-register type label temp)
-       ,(machine-register->memory temp target))))
-  (define-export typed-label->memory
-    (->memory machine-register->memory))
-  (define-export typed-label->memory-post-increment
-    (->memory machine-register->memory-post-increment))
-  (define-export typed-label->memory-pre-decrement
-    (->memory machine-register->memory-pre-decrement)))
+(define (lap:make-entry-point label block-start-label)
+  block-start-label
+  (LAP (ENTRY-POINT ,label)
+       ,@(make-external-label expression-code-word label)))
 \f
-(define (cons-pointer->machine-register type source target)
-  (let ((source (guarantee-machine-register! source false)))
-    (if (eqv? source target)
-       (let ((temp (allocate-temporary-register! false)))
-         `(,@(cons-pointer->machine-register type source temp)
-           ,(machine->machine-register temp source)))
-       `(,@(if (deposit-type-constant? type)
-               (with-type-deposit-parameters type
-                 (lambda (type end)
-                   `((ZDEPI () ,type ,end 5 ,target))))
-               `((LDI () ,type ,target)
-                 (ZDEP () ,target 7 8 ,target)))
-         (DEP () ,source 31 24 ,target)))))
-
-(package (cons-pointer->memory
-         cons-pointer->memory-post-increment
-         cons-pointer->memory-pre-decrement)
-  (define ((->memory machine-register->memory) type source target)
-    (let ((temp (allocate-temporary-register! false)))
-      `(,@(cons-pointer->machine-register type source temp)
-       ,(machine-register->memory temp target))))
-  (define cons-pointer->memory
-    (->memory machine-register->memory))
-  (define cons-pointer->memory-post-increment
-    (->memory machine-register->memory-post-increment))
-  (define cons-pointer->memory-pre-decrement
-    (->memory machine-register->memory-pre-decrement)))
-\f
-(define (test:machine/machine-register condition source0 source1 receiver)
-  (let ((make-branch
-        (lambda (completer)
-          (lambda (label)
-            `((COMB (,completer N) ,source0 ,source1
-                    ,(label-relative-expression label)))))))
-    (receiver '()
-             (make-branch condition)
-             (make-branch (invert-test-completer condition)))))
-
-(define (test:short-machine-constant/machine-register condition constant source
-                                                     receiver)
-  (let ((make-branch
-        (lambda (completer)
-          (lambda (label)
-            `((COMIB (,completer N) ,constant ,source
-                     ,(label-relative-expression label)))))))
-    (receiver '()
-             (make-branch condition)
-             (make-branch (invert-test-completer condition)))))
-
-(define (invert-test-completer completer)
-  (cdr (or (assq completer
-                '((EQ . LTGT) (LTGT . EQ)
-                  (LT . GTEQ) (GTEQ . LT)
-                  (GT . LTEQ) (GT . LTEQ)
-                  (LTLT . GTGTEQ) (GTGTEQ . LTLT)
-                  (GTGT . LTLTEQ) (GTGT . LTLTEQ)
-                  ))
-          (error "Unknown test completer" completer))))
-
-(define (test:machine-constant/machine-register condition constant source
-                                               receiver)
-  (cond ((zero? constant)
-        (test:machine/machine-register condition 0 source receiver))
-       ((test-short-constant? constant)
-        (test:short-machine-constant/machine-register condition constant
-                                                      source receiver))
-       (else
-        `(,@(non-pointer->machine-register 0 constant r1)
-          ,@(test:machine/machine-register condition r1 source receiver)))))
-
-(define (test:machine-constant/register condition constant source receiver)
-  (test:machine-constant/machine-register
-   condition constant (guarantee-machine-register! source false) receiver))
-
-(define (test:machine-constant/memory condition constant source receiver)
-  (let ((temp (allocate-temporary-register! false)))
-    `(,(memory->machine-register source temp)
-      ,@(test:machine-constant/machine-register condition constant temp
-                                               receiver))))
-\f
-(define (test:type/machine-register condition type source receiver)
-  (let ((temp (allocate-temporary-register! false)))
-    `(,(extract-type-machine->machine-register source temp)
-      ,@(test:machine-constant/machine-register condition type temp
-                                               receiver))))
-
-(define (test:type/register condition type source receiver)
-  (test:type/machine-register condition type
-                             (guarantee-machine-register! source false)
-                             receiver))
-
-(define (test:type/memory condition type source receiver)
-  (let ((temp (allocate-temporary-register! false)))
-    `(,(memory->machine-register source temp)
-      ,@(cond ((zero? type)
-              (test:machine/machine-register condition 0 temp receiver))
-             ((test-short-constant? type)
-              `(,(extract-type-machine->machine-register temp temp)
-                ,@(test:short-machine-constant/machine-register condition
-                                                                type
-                                                                temp
-                                                                receiver)))
-             (else
-              `(,@(non-pointer->machine-register 0 type r1)
-                ,(extract-type-machine->machine-register temp temp)
-                ,@(test:machine/machine-register condition r1 temp
-                                                 receiver)))))))
-
-(define (standard-predicate-receiver prefix consequent alternative)
-  (set-current-branches! consequent alternative)
-  prefix)
-
-(define ((inline-predicate-receiver label) prefix consequent alternative)
-  `(,@prefix ,@(consequent label)))
-
-(define-integrable (extract-type-machine->machine-register source target)
-  `(EXTRU () ,source 7 8 ,target))
-
-(define-integrable (test-short-constant? constant)
-  (<= -16 constant 15))
-\f
-(define (deposit-type-constant? n)
-  ;; Assume that (<= 0 n 127).
-  (or (< n 16)
-      (zero? (remainder n
-                       (cond ((< n 32) 2)
-                             ((< n 64) 4)
-                             (else 8))))))
-
-(define (with-type-deposit-parameters type receiver)
-  ;; This one is for type codes, assume that (<= 0 n 127).
-  ;; Also assume that `(deposit-type-constant? type)' is true.
-  (cond ((< type 16) (receiver type 7))
-       ((< type 32) (receiver (quotient type 2) 6))
-       ((< type 64) (receiver (quotient type 4) 5))
-       (else (receiver (quotient type 8) 4))))
-
-(define (code-object-label-initialize code-object)
-  (cond ((procedure? code-object) false)
-       ((continuation? code-object) (continuation-label code-object))
-       ((quotation? code-object) (quotation-label code-object))
-       (else
-        (error "CODE-OBJECT-LABEL-INITIALIZE: Unknown code object type"
-               code-object))))
-
-(define (code-object-base)
-  ;; This will fail if the difference between the beginning of the
-  ;; code-object and LABEL is greater than 11 bits (signed).
-  (or *code-object-label*
-      (let ((label (generate-label)))
-       (prefix-instructions!
-        `((BL () 0 ,regnum:code-object-base)
-          (LABEL ,label)))
-       (let ((label `(+ ,label 4)))
-         (set! *code-object-label* label)
-         label))))
-
-(define (generate-n-times n limit prefix suffix with-counter)
-  (if (<= n limit)
-      (let loop ((n n))
-       (if (zero? n)
-           '()
-           `(,@prefix
-             ,suffix
-             ,@(loop (-1+ n)))))
-      (let ((loop (generate-label 'LOOP)))
-       (with-counter
-        (lambda (counter)
-          `(,@(machine-constant->machine-register (-1+ n) counter)
-            (LABEL ,loop)
-            ,@prefix
-            (ADDIBF (EQ) -1 ,counter ,(label-relative-expression loop))
-            ,suffix))))))
-
-(define-integrable (label-relative-expression label)
-  `(- (- ,label *PC*) 8))
-\f
-;;;; Registers/Entries
+;;;; Codes and Hooks
 
-(let-syntax ((define-entries
-              (macro names
+(let-syntax ((define-codes
+              (macro (start . names)
                 (define (loop names index)
                   (if (null? names)
                       '()
-                      (cons `(DEFINE ,(symbol-append 'ENTRY:COMPILER-
-                                                     (car names))
-                               `(INDEX ,,index 5 ,regnum:regs-pointer))
-                            (loop (cdr names) (+ index 8)))))
-                `(BEGIN ,@(loop names #x00F0)))))
-  (define-entries apply error wrong-number-of-arguments interrupt-procedure
-    interrupt-continuation lookup-apply lookup access unassigned? unbound?
-    set! define primitive-apply enclose setup-lexpr setup-ic-procedure))
-
-(define reg:temp `(INDEX #x0010 0 ,regnum:regs-pointer))
-(define reg:compiled-memtop `(INDEX 0 0 ,regnum:regs-pointer))
-
-(define popper:apply-closure `(INDEX 400 5 ,regnum:regs-pointer))
-(define popper:apply-stack `(INDEX 528 5 ,regnum:regs-pointer))
-(define popper:value `(INDEX 656 5 ,regnum:regs-pointer))
-
-(package (type->machine-constant
-         make-non-pointer
-         machine-constant->type
-         machine-constant->datum)
-  (define type-scale-factor
-    (expt 2 24))
-  (define-export (type->machine-constant type)
-    (* type type-scale-factor))
-  (define-export (make-non-pointer type datum)
-    (+ (* type type-scale-factor) datum))
-  (define-export (machine-constant->type constant)
-    (quotient constant type-scale-factor))
-  (define-export (machine-constant->datum constant)
-    (remainder constant type-scale-factor)))
-
-(define constant:compiled-expression
-  (type->machine-constant (ucode-type compiled-expression)))
-
-(define constant:return-address
-  (type->machine-constant (ucode-type return-address)))
-
-(define constant:unassigned
-  (make-non-pointer (ucode-type unassigned) 0))
-
-(define constant:false
-  (make-non-pointer (ucode-type false) 0))
-\f
-;;;; Transfers to Registers
-
-;;; All assignments to pseudo registers are required to delete the
-;;; dead registers BEFORE performing the assignment.  This is because
-;;; the register being assigned may be PSEUDO-REGISTER=? to one of the
-;;; dead registers, and thus would be flushed if the deletions
-;;; happened after the assignment.
-
-(define-rule statement
-  (ASSIGN (REGISTER 30) (OFFSET-ADDRESS (REGISTER 30) (? n)))
-  `((LDO () ,(offset-reference regnum:stack-pointer n) ,r30)))
-
-(define-rule statement
-  (ASSIGN (REGISTER (? target)) (CONSTANT (? source)))
-  (QUALIFIER (pseudo-register? target))
-  (scheme-constant->machine-register source
-                                    (allocate-assignment-alias! target
-                                                                false)))
-
-(define-rule statement
-  (ASSIGN (REGISTER (? target)) (REGISTER (? source)))
-  (QUALIFIER (pseudo-register? target))
-  (move-to-alias-register! source false target)
-  '())
-
-(define-rule statement
-  (ASSIGN (REGISTER (? target)) (OBJECT->ADDRESS (REGISTER (? source))))
-  (QUALIFIER (pseudo-register? target))
-  (object->address (move-to-alias-register! source false target)))
-
-(define-rule statement
-  (ASSIGN (REGISTER (? target)) (OBJECT->TYPE (REGISTER (? source))))
-  (QUALIFIER (pseudo-register? target))
-  (let ((target (move-to-alias-register! source false target)))
-    `(,(extract-type-machine->machine-register target target))))
-
-(define-rule statement
-  (ASSIGN (REGISTER (? target)) (OFFSET (REGISTER (? address)) (? offset)))
-  (QUALIFIER (and (pseudo-register? target) (short-offset? offset)))
-  (let ((source (indirect-reference! address offset))) ;force eval order.
-    `(,(memory->machine-register source
-                                (allocate-assignment-alias! target false)))))
-
-(define-rule statement
-  (ASSIGN (REGISTER (? target)) (POST-INCREMENT (REGISTER (? source)) 1))
-  (QUALIFIER (pseudo-register? target))
-  (memory-post-increment->machine-register
-   source
-   (allocate-assignment-alias! target false)))
-
-(define-rule statement
-  (ASSIGN (REGISTER (? target))
-         (CONS-POINTER (CONSTANT (? type)) (REGISTER (? datum))))
-  (QUALIFIER (pseudo-register? target))
-  (cons-pointer->machine-register type datum
-                                 (allocate-assignment-alias! target false)))
-\f
-;;;; Transfers to Memory
-
-(define-rule statement
-  (ASSIGN (OFFSET (REGISTER (? a)) (? n))
-         (CONSTANT (? object)))
-  (QUALIFIER (short-offset? n))
-  (scheme-constant->memory object (indirect-reference! a n)))
-
-(define-rule statement
-  (ASSIGN (OFFSET (REGISTER (? a)) (? n))
-         (REGISTER (? r)))
-  (QUALIFIER (short-offset? n))
-  (register->memory r (indirect-reference! a n)))
-
-(define-rule statement
-  (ASSIGN (OFFSET (REGISTER (? a)) (? n))
-         (POINTER-INCREMENT (REGISTER (? source)) 1))
-  (QUALIFIER (short-offset? n))
-  (memory-post-increment->memory source (indirect-reference! a n)))
-
-(define-rule statement
-  ;; The code assumes r cannot be trashed
-  (ASSIGN (OFFSET (REGISTER (? a)) (? n))
-         (CONS-POINTER (CONSTANT (? type)) (REGISTER (? r))))
-  (QUALIFIER (short-offset? n))
-  (cons-pointer->memory type r (indirect-reference! a n)))
-
-(define-rule statement
-  (ASSIGN (OFFSET (REGISTER (? r-target)) (? n-target))
-         (OFFSET (REGISTER (? r-source)) (? n-source)))
-  (QUALIFIER (and (short-offset? n-target) (short-offset? n-source)))
-  (memory->memory (indirect-reference! r-source n-source)
-                 (indirect-reference! r-target n-target)))
-\f
-;;;; Consing
-
-(define-rule statement
-  (ASSIGN (POST-INCREMENT (REGISTER 25) 1) (CONSTANT (? object)))
-  (scheme-constant->memory-post-increment object r25))
-
-(define-rule statement
-  (ASSIGN (POST-INCREMENT (REGISTER 25) 1) (REGISTER (? r)))
-  (register->memory-post-increment r r25))
-
-(define-rule statement
-  (ASSIGN (POST-INCREMENT (REGISTER 25) 1) (OFFSET (REGISTER (? r)) (? n)))
-  (memory->memory-post-increment (indirect-reference! r n) r25))
-
-(define-rule statement
-  (ASSIGN (POST-INCREMENT (REGISTER 25) 1) (ENTRY:PROCEDURE (? procedure)))
-  (typed-label->memory-post-increment (ucode-type compiled-expression)
-                                     (procedure-external-label procedure)
-                                     r25))
-\f
-;;;; Pushes
-
-(define-rule statement
-  (ASSIGN (PRE-INCREMENT (REGISTER 30) -1) (CONSTANT (? object)))
-  (scheme-constant->memory-pre-decrement object r30))
-
-(define-rule statement
-  (ASSIGN (PRE-INCREMENT (REGISTER 30) -1) (UNASSIGNED))
-  (scheme-constant->memory-pre-decrement constant:unassigned r30))
-
-(define-rule statement
-  (ASSIGN (PRE-INCREMENT (REGISTER 30) -1) (REGISTER (? r)))
-  (register->memory-pre-decrement r r30))
-
-(define-rule statement
-  (ASSIGN (PRE-INCREMENT (REGISTER 30) -1)
-         (CONS-POINTER (CONSTANT (? type)) (REGISTER (? r))))
-  (cons-pointer->memory-pre-decrement type r r30))
-
-(define-rule statement
-  (ASSIGN (PRE-INCREMENT (REGISTER 30) -1) (OFFSET (REGISTER (? r)) (? n)))
-  (QUALIFIER (short-offset? n))
-  (memory->memory-pre-decrement (indirect-reference! r n) r30))
-
-(define-rule statement
-  (ASSIGN (PRE-INCREMENT (REGISTER 30) -1)
-         (OFFSET-ADDRESS (REGISTER 30) (? n)))
-  (QUALIFIER (short-offset? n))
-  (let ((temp (allocate-temporary-register! false)))
-    `((LDI () ,(ucode-type stack-environment) ,temp)
-      (LDO () ,(offset-reference r30 n) ,r1)
-      (DEP () ,temp 7 8 ,r1)
-      ,@(register->memory-pre-decrement r1 r30))))
-
-(define-rule statement
-  (ASSIGN (PRE-INCREMENT (REGISTER 30) -1)
-         (ENTRY:CONTINUATION (? continuation)))
-  (typed-label->memory-pre-decrement (ucode-type return-address)
-                                    (continuation-label continuation)
-                                    r30))
-\f
-;;;; Predicates
-
-(define-rule predicate
-  (TRUE-TEST (REGISTER (? register)))
-  (test:machine-constant/register 'LTGT constant:false register
-                                 standard-predicate-receiver))
-
-(define-rule predicate
-  (TRUE-TEST (OFFSET (REGISTER (? register)) (? offset)))
-  (test:machine-constant/memory 'LTGT constant:false
-                               (indirect-reference! register offset)
-                               standard-predicate-receiver))
-
-(define-rule predicate
-  (TYPE-TEST (REGISTER (? register)) (? type))
-  (test:machine-constant/machine-register 'LTGT type register
-                                         standard-predicate-receiver))
-
-(define-rule predicate
-  (TYPE-TEST (OBJECT->TYPE (REGISTER (? register))) (? type))
-  (test:type/register 'LTGT type register standard-predicate-receiver))
-
-(define-rule predicate
-  (UNASSIGNED-TEST (REGISTER (? register)))
-  (test:machine-constant/register 'LTGT constant:unassigned register
-                                 standard-predicate-receiver))
-
-(define-rule predicate
-  (UNASSIGNED-TEST (OFFSET (REGISTER (? register)) (? offset)))
-  (test:machine-constant/memory 'LTGT constant:unassigned
-                               (indirect-reference! register offset)
-                               standard-predicate-receiver))
-\f
-;;;; Invocations
-
-(define-rule statement
-  (INVOCATION:APPLY (? number-pushed) (? prefix) (? continuation))
-  `(,@(generate-invocation-prefix prefix)
-    ,@(assign&invoke-entry number-pushed regnum:frame-size
-                          entry:compiler-apply)))
-
-(define-rule statement
-  (INVOCATION:JUMP (? n)
-                  (APPLY-CLOSURE (? frame-size) (? receiver-offset))
-                  (? continuation) (? procedure))
-  `(,@(clear-map!)
-    ,@(apply-closure-sequence frame-size receiver-offset
-                             (procedure-label procedure))))
-
-(define-rule statement
-  (INVOCATION:JUMP (? n)
-                  (APPLY-STACK (? frame-size) (? receiver-offset)
-                               (? n-levels))
-                  (? continuation) (? procedure))
-  `(,@(clear-map!)
-    ,@(apply-stack-sequence frame-size receiver-offset n-levels
-                           (procedure-label procedure))))
-
-(define-rule statement
-  (INVOCATION:JUMP (? number-pushed) (? prefix) (? continuation) (? procedure))
-  (QUALIFIER (not (memq (car prefix) '(APPLY-CLOSURE APPLY-STACK))))
-  `(,@(generate-invocation-prefix prefix)
-    ,(branch->label (procedure-label procedure))))
-
-(define-rule statement
-  (INVOCATION:LEXPR (? number-pushed) (? prefix) (? continuation)
-                   (? procedure))
-  `(,@(generate-invocation-prefix prefix)
-    ,@(machine-constant->machine-register number-pushed regnum:frame-size)
-    ,(branch->label (procedure-label procedure))))
-\f
-(define-rule statement
-  (INVOCATION:LOOKUP (? number-pushed) (? prefix) (? continuation)
-                    (? environment) (? name))
-  (let ((set-environment
-        (expression->machine-register! environment regnum:call-argument-0)))
-    (delete-dead-registers!)
-    `(,@set-environment
-      ,@(generate-invocation-prefix prefix)
-      ,@(scheme-constant->machine-register name regnum:call-argument-1)
-      ,@(assign&invoke-entry (1+ number-pushed) regnum:frame-size
-                            entry:compiler-lookup-apply))))
-
-(define-rule statement
-  (INVOCATION:PRIMITIVE (? number-pushed) (? prefix) (? continuation)
-                       (? primitive))
-  `(,@(generate-invocation-prefix prefix)
-    ,@(if (eq? primitive compiled-error-procedure)
-         (assign&invoke-entry number-pushed regnum:frame-size
-                              entry:compiler-error)
-         ;; Simple thing for now.
-         (assign&invoke-entry (primitive-datum primitive)
-                              regnum:call-argument-0
-                              entry:compiler-primitive-apply))))
-
-(define-rule statement
-  (RETURN)
-  `(,@(clear-map!)
-    ,(memory-post-increment->machine-register regnum:stack-pointer
-                                             regnum:code-object-base)
-    ,@(object->address regnum:code-object-base)
-    (BE (N) (INDEX 0 1 ,regnum:code-object-base))))
-\f
-(define (generate-invocation-prefix prefix)
-  `(,@(clear-map!)
-    ,@(case (car prefix)
-       ((NULL) '())
-       ((MOVE-FRAME-UP)
-        (apply generate-invocation-prefix:move-frame-up (cdr prefix)))
-       ((APPLY-CLOSURE)
-        (apply generate-invocation-prefix:apply-closure (cdr prefix)))
-       ((APPLY-STACK)
-        (apply generate-invocation-prefix:apply-stack (cdr prefix)))
-       (else (error "GENERATE-INVOCATION-PREFIX: bad prefix type" prefix)))))
-
-(define (generate-invocation-prefix:move-frame-up frame-size how-far)
-  (cond ((or (zero? frame-size) (zero? how-far)) '())
-       ((= frame-size 1)
-        `(,(load-memory-increment regnum:stack-pointer (+ frame-size how-far)
-                                  r1)
-          ,(store-memory r1 regnum:stack-pointer 0)))
-       ((= frame-size 2)
-        (let ((temp (allocate-temporary-register! false)))
-          `(,(load-memory-increment regnum:stack-pointer 1 r1)
-            ,(load-memory-increment regnum:stack-pointer (-1+ how-far) temp)
-            ,(store-memory r1 regnum:stack-pointer 0)
-            ,(store-memory temp regnum:stack-pointer 1))))
-       (else
-        (let ((temp0 (allocate-temporary-register! false))
-              (temp1 (allocate-temporary-register! false)))
-          `((LDO ()
-                 ,(offset-reference regnum:stack-pointer frame-size)
-                 ,temp0)
-            (LDO ()
-                 ,(offset-reference regnum:stack-pointer
-                                    (+ frame-size how-far))
-                 ,temp1)
-            ,@(generate-n-times
-               frame-size 5
-               `(,(load-memory-increment temp0 -1 r1))
-               (store-memory-increment r1 temp1 -1)
-               (lambda (generator)
-                 (generator (allocate-temporary-register! false))))
-            ,(machine->machine-register temp1 regnum:stack-pointer))))))
-
-(define (generate-invocation-prefix:apply-closure frame-size receiver-offset)
-  (let ((label (generate-label)))
-    `(,@(apply-closure-sequence frame-size receiver-offset label)
-      (LABEL ,label))))
-
-(define (generate-invocation-prefix:apply-stack frame-size receiver-offset
-                                               n-levels)
-  (let ((label (generate-label)))
-    `(,@(apply-stack-sequence frame-size receiver-offset n-levels label)
-      (LABEL ,label))))
-\f
-;;;; Environment Calls
-
-(define-rule statement
-  (INTERPRETER-CALL:ACCESS (? environment) (? name))
-  (lookup-call entry:compiler-access environment name))
-
-(define-rule statement
-  (INTERPRETER-CALL:LOOKUP (? environment) (? name))
-  (lookup-call entry:compiler-lookup environment name))
-
-(define-rule statement
-  (INTERPRETER-CALL:UNASSIGNED? (? environment) (? name))
-  (lookup-call entry:compiler-unassigned? environment name))
-
-(define-rule statement
-  (INTERPRETER-CALL:UNBOUND? (? environment) (? name))
-  (lookup-call entry:compiler-unbound? environment name))
-
-(define (lookup-call entry environment name)
-  (let ((set-environment
-        (expression->machine-register! environment regnum:call-argument-0)))
-    (let ((clear-map (clear-map!)))
-      `(,@set-environment
-       ,@clear-map
-       ,(scheme-constant->machine-register name regnum:argument-1)
-       (BLE (N) ,entry)
-       ,@(make-external-label (generate-label))))))
-
-(define-rule statement
-  (INTERPRETER-CALL:ENCLOSE (? number-pushed))
-  `(,@(cons-pointer->machine-register (ucode-type vector) regnum:free-pointer
-                                     regnum:call-value)
-    ,@(non-pointer->memory-post-increment (ucode-type manifest-vector)
-                                         number-pushed
-                                         regnum:free-pointer)
-    ,@(generate-n-times number-pushed 5
-                       `(,(load-memory-increment regnum:stack-pointer 1 r1))
-                       (store-memory-increment r1 regnum:free-pointer 1)
-       (lambda (generator)
-         (generator (allocate-temporary-register! false))))))
-\f
-(define-rule statement
-  (INTERPRETER-CALL:DEFINE (? environment) (? name) (? value))
-  (QUALIFIER (not (eq? 'CONS-POINTER (car value))))
-  (assignment-call:default entry:compiler-define environment name value))
-
-(define-rule statement
-  (INTERPRETER-CALL:SET! (? environment) (? name) (? value))
-  (QUALIFIER (not (eq? 'CONS-POINTER (car value))))
-  (assignment-call:default entry:compiler-set! environment name value))
-
-(define (assignment-call:default entry environment name value)
-  (let ((set-environment
-        (expression->machine-register! environment regnum:call-argument-0)))
-    (let ((set-value
-          (expression->machine-register! value regnum:call-argument-2)))
-      (let ((clear-map (clear-map!)))
-       `(,@set-environment
-         ,@set-value
-         ,@clear-map
-         ,@(scheme-constant->machine-register name regnum:call-argument-1)
-         (BLE (N) ,entry)
-         ,@(make-external-label (generate-label)))))))
-
-(define-rule statement
-  (INTERPRETER-CALL:DEFINE (? environment) (? name)
-                          (CONS-POINTER (CONSTANT (? type))
-                                        (REGISTER (? datum))))
-  (assignment-call:cons-pointer entry:compiler-define environment name type
-                               datum))
-
-(define-rule statement
-  (INTERPRETER-CALL:SET! (? environment) (? name)
-                        (CONS-POINTER (CONSTANT (? type))
-                                      (REGISTER (? datum))))
-  (assignment-call:cons-pointer entry:compiler-set! environment name type
-                               datum))
-
-(define (assignment-call:cons-pointer entry environment name type datum)
-  (let ((set-environment
-        (expression->machine-register! environment regnum:call-argument-0)))
-    (let ((set-value
-          (cons-pointer->machine-register type datum regnum:call-argument-2)))
-      (let ((clear-map (clear-map!)))
-       `(,@set-environment
-         ,@set-value
-         ,@clear-map
-         ,@(scheme-constant->machine-register name regnum:call-argument-1)
-         (BLE (N) ,entry)
-         ,@(make-external-label (generate-label)))))))
-\f
-;;;; Procedure/Continuation Entries
-
-;;; The following calls MUST appear as the first thing at the entry
-;;; point of a procedure.  They assume that the register map is clear
-;;; and that no register contains anything of value.
-
-;;; **** The only reason that this is true is that no register is live
-;;; across calls.  If that were not true, then we would have to save
-;;; any such registers on the stack so that they would be GC'ed
-;;; appropriately.
-
-(define-rule statement
-  (PROCEDURE-HEAP-CHECK (? procedure))
-  (let ((label (generate-label)))
-    `(,@(procedure-header procedure)
-      (COMBT (LT N) ,regnum:free-pointer ,regnum:memtop-pointer
-            ,(label-relative-expression label))
-      (BLE (N) ,entry:compiler-interrupt-procedure)
-      (LABEL ,label))))
-
-(define-rule statement
-  (CONTINUATION-HEAP-CHECK (? continuation))
-  (let ((label (generate-label)))
-    `(,@(make-external-label (continuation-label continuation))
-      (COMBT (LT N) ,regnum:free-pointer ,regnum:memtop-pointer
-            ,(label-relative-expression label))
-      (BLE (N) ,entry:compiler-interrupt-procedure)
-      (LABEL ,label))))
-\f
-(define (procedure-header procedure)
-  (let ((internal-label (procedure-label procedure)))
-    (append! (if (procedure/closure? procedure)
-                (let ((required (1+ (length (procedure-required procedure))))
-                      (optional (length (procedure-optional procedure)))
-                      (label (procedure-external-label procedure)))
-                  (if (and (procedure-rest procedure)
-                           (zero? required))
-                      (begin (set-procedure-external-label! procedure
-                                                            internal-label)
-                             `((ENTRY-POINT ,internal-label)))
-                      `((ENTRY-POINT ,label)
-                        ,@(make-external-label label)
-                        ,@(cond ((procedure-rest procedure)
-                                 (test:machine-constant/machine-register
-                                  'GTEQ required regnum:frame-size
-                                  (inline-predicate-receiver internal-label)))
-                                ((zero? optional)
-                                 (test:machine-constant/machine-register
-                                  'EQ required regnum:frame-size
-                                  (inline-predicate-receiver internal-label)))
-                                (else
-                                 (let ((wna-label (generate-label)))
-                                   `(,@(test:machine-constant/machine-register
-                                        'LT required regnum:frame-size
-                                        (inline-predicate-receiver wna-label))
-                                     ,@(test:machine-constant/machine-register
-                                        'LTEQ (+ required optional)
-                                        regnum:frame-size
-                                        (inline-predicate-receiver
-                                         internal-label))
-                                     (LABEL ,wna-label)))))
-                        ,(invoke-entry
-                          entry:compiler-wrong-number-of-arguments))))
-                '())
-            `(,@(make-external-label internal-label)))))
-
-(define *block-start-label*)
-
-(define (make-external-label label)
-  `((WORD (- ,label ,*block-start-label*))
-    (LABEL ,label)))
-\f
-;;;; Poppers
-
-(define-rule statement
-  (MESSAGE-RECEIVER:CLOSURE (? frame-size))
-  (machine-constant->memory-pre-decrement (* frame-size 4) r30))
-
-(define-rule statement
-  (MESSAGE-RECEIVER:STACK (? frame-size))
-  (machine-constant->memory-pre-decrement (+ #x00200000 (* frame-size 4))
-                                              r30))
-
-(define-rule statement
-  (MESSAGE-RECEIVER:SUBPROBLEM (? continuation))
-  `(,@(typed-label->memory-pre-decrement (ucode-type return-address)
-                                        (continuation-label continuation)
-                                        r30)
-    ,@(machine-constant->memory-pre-decrement #x00400000 r30)))
-
-(define (apply-closure-sequence frame-size receiver-offset label)
-  `(,@(machine-constant->machine-register (* frame-size 4) r19)
-    (LDO () ,(offset-reference r30 (* receiver-offset 4)) ,r20)
-    ,@(label->machine-register label r21)
-    (BLE (N) ,popper:apply-closure)))
-
-(define (apply-stack-sequence frame-size receiver-offset n-levels label)
-  `(,@(machine-constant->machine-register (* frame-size 4) r19)
-    (LDO () ,(offset-reference r30 (* receiver-offset 4)) ,r20)
-    ,@(label->machine-register label r21)
-    ,@(machine-constant->machine-register n-levels r22)
-    (BLE (N) ,popper:apply-stack)))
-
-(define-rule statement
-  (MESSAGE-SENDER:VALUE (? receiver-offset))
-  `(,@(clear-map!)
-    (LDO () ,(offset-reference r30 (* receiver-offset 4)) ,r30)
-    (BLE (N) ,popper:value)))
\ No newline at end of file
+                      (cons `(DEFINE-INTEGRABLE
+                               ,(symbol-append 'CODE:COMPILER-
+                                               (car names))
+                               ,index)
+                            (loop (cdr names) (1+ index)))))
+                `(BEGIN ,@(loop names start)))))
+  (define-codes #x012
+    primitive-apply primitive-lexpr-apply
+    apply error lexpr-apply link
+    interrupt-closure interrupt-dlink interrupt-procedure 
+    interrupt-continuation interrupt-ic-procedure
+    assignment-trap cache-reference-apply
+    reference-trap safe-reference-trap unassigned?-trap
+    -1+ &/ &= &> 1+ &< &- &* negative? &+ positive? zero?
+    access lookup safe-lookup unassigned? unbound?
+    set! define lookup-apply))
+
+(define-integrable (invoke-interface-ble code)
+  ;; Jump to scheme-to-interface-ble
+  (LAP (BLE () (OFFSET 0 4 ,regnum:scheme-to-interface-ble))
+       (LDI () ,code 28)))
+
+;;; trampoline-to-interface uses (OFFSET 4 4 ,regnum:scheme-to-interface-ble)
+
+(define-integrable (invoke-interface code)
+  ;; Jump to scheme-to-interface
+  (LAP (BLE () (OFFSET 12 4 ,regnum:scheme-to-interface-ble))
+       (LDI () ,code 28)))
+
+(let-syntax ((define-hooks
+              (macro (start . names)
+                (define (loop names index)
+                  (if (null? names)
+                      '()
+                      (cons `(DEFINE-INTEGRABLE
+                               ,(symbol-append 'HOOK:COMPILER-
+                                               (car names))
+                               ,index)
+                            (loop (cdr names) (+ 8 index)))))
+                `(BEGIN ,@(loop names start)))))
+  (define-hooks 100
+    store-closure-code))
+
+(define (load-interface-args! first second third fourth)
+  (let ((clear-regs
+        (apply clear-registers!
+               (append (if first (list first) '())
+                       (if second (list second) '())
+                       (if third (list third) '())
+                       (if fourth (list fourth) '()))))
+       (load-reg
+        (lambda (reg arg)
+          (if reg (load-machine-register! reg arg) (LAP)))))
+    (let ((load-regs
+          (LAP ,@(load-reg first regnum:first-arg)
+               ,@(load-reg second regnum:second-arg)
+               ,@(load-reg third regnum:third-arg)
+               ,@(load-reg fourth regnum:fourth-arg))))
+      (LAP ,@clear-regs
+          ,@load-regs
+          ,@(clear-map!)))))
\ No newline at end of file
index ac31a85c6ac935b41bd2a3176d996e300ca9fae8..d74e0ea069ee278ea319ece0d4429991f8765348 100644 (file)
@@ -1,8 +1,9 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/machin.scm,v 1.41 1987/03/19 00:55:54 cph Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/machin.scm,v 4.20 1990/01/25 16:27:42 jinx Exp $
+$MC68020-Header: machin.scm,v 4.20 90/01/18 22:43:44 GMT cph Exp $
 
-Copyright (c) 1987 Massachusetts Institute of Technology
+Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
 
 This material was developed by the Scheme project at the Massachusetts
 Institute of Technology, Department of Electrical Engineering and
@@ -32,152 +33,290 @@ Technology nor of any adaptation thereof in any advertising,
 promotional, or sales literature without prior written consent from
 MIT in each case. |#
 
-;;;; Machine Model for Spectrum
+;;; Machine Model for Spectrum
 
 (declare (usual-integrations))
 \f
-(define (rtl:message-receiver-size:closure) 1)
-(define (rtl:message-receiver-size:stack) 1)
-(define (rtl:message-receiver-size:subproblem) 1)
+;;;; Architecture Parameters
 
-(define-integrable (stack->memory-offset offset)
-  offset)
+(define-integrable endianness 'BIG)
+(define-integrable addressing-granularity 8)
+(define-integrable scheme-object-width 32)
+(define-integrable scheme-type-width 6)        ;or 8
 
-(define (rtl:expression-cost expression)
-  ;; Returns an estimate of the cost of evaluating the expression.
-  ;; For time being, disable this feature.
-  1)
+(define-integrable scheme-datum-width
+  (- scheme-object-width scheme-type-width))
 
-(define (rtl:machine-register? rtl-register)
-  (case rtl-register
-    ((STACK-POINTER) (interpreter-stack-pointer))
-    ((INTERPRETER-CALL-RESULT:ACCESS) (interpreter-register:access))
-    ((INTERPRETER-CALL-RESULT:ENCLOSE) (interpreter-register:enclose))
-    ((INTERPRETER-CALL-RESULT:LOOKUP) (interpreter-register:lookup))
-    ((INTERPRETER-CALL-RESULT:UNASSIGNED?) (interpreter-register:unassigned?))
-    ((INTERPRETER-CALL-RESULT:UNBOUND?) (interpreter-register:unbound?))
-    (else false)))
+(define-integrable type-scale-factor
+  (expt 2 (- 8 scheme-type-width)))
 
-(define (rtl:interpreter-register? rtl-register)
-  (case rtl-register
-    ((MEMORY_TOP) 0)
-    ((STACK_GUARD) 1)
-    ((VALUE) 2)
-    ((ENVIRONMENT) 3)
-    ((TEMPORARY) 4)
-    (else false)))
+(define-integrable flonum-size 2)
+(define-integrable float-alignment 64)
 
-(define (rtl:interpreter-register->offset locative)
-  (or (rtl:interpreter-register? locative)
-      (error "Unknown register type" locative)))
-\f
-(define-integrable r0 0)
-(define-integrable r1 1)
-(define-integrable r2 2)
-(define-integrable r3 3)
-(define-integrable r4 4)
-(define-integrable r5 5)
-(define-integrable r6 6)
-(define-integrable r7 7)
-(define-integrable r8 8)
-(define-integrable r9 9)
-(define-integrable r10 10)
-(define-integrable r11 11)
-(define-integrable r12 12)
-(define-integrable r13 13)
-(define-integrable r14 14)
-(define-integrable r15 15)
-(define-integrable r16 16)
-(define-integrable r17 17)
-(define-integrable r18 18)
-(define-integrable r19 19)
-(define-integrable r20 20)
-(define-integrable r21 21)
-(define-integrable r22 22)
-(define-integrable r23 23)
-(define-integrable r24 24)
-(define-integrable r25 25)
-(define-integrable r26 26)
-(define-integrable r27 27)
-(define-integrable r28 28)
-(define-integrable r29 29)
-(define-integrable r30 30)
-(define-integrable r31 31)
-
-(define number-of-machine-registers 32)
-
-(define-integrable (sort-machine-registers registers)
-  registers)
-
-(define (pseudo-register=? x y)
-  (= (register-renumber x) (register-renumber y)))
-
-(define available-machine-registers
-  (list r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18
-       r19 r20 r21 r22))
-
-(define-integrable (register-contains-address? register)
-  (memv register '(23 24 25 30)))
-
-(define-integrable (register-type register)
-  false)
+;;; It is currently required that both packed characters and objects
+;;; be integrable numbers of address units.  Furthermore, the number
+;;; of address units per object must be an integral multiple of the
+;;; number of address units per character.  This will cause problems
+;;; on a machine that is word addressed, in which case we will have to
+;;; rethink the character addressing strategy.
 
-(define-integrable (register-reference register)
-  register)
-\f
-(define-integrable regnum:frame-size r3)
-(define-integrable regnum:call-argument-0 r4)
-(define-integrable regnum:call-argument-1 r5)
-(define-integrable regnum:call-argument-2 r6)
-(define-integrable regnum:call-value r28)
-
-(define-integrable regnum:memtop-pointer r23)
-(define-integrable regnum:regs-pointer r24)
-(define-integrable regnum:free-pointer r25)
-(define-integrable regnum:code-object-base r26)
-(define-integrable regnum:address-offset r27)
-(define-integrable regnum:stack-pointer r30)
+(define-integrable address-units-per-object
+  (quotient scheme-object-width addressing-granularity))
 
-(define-integrable (interpreter-register:access)
-  (rtl:make-machine-register regnum:call-value))
-
-(define-integrable (interpreter-register:enclose)
-  (rtl:make-machine-register regnum:call-value))
+(define-integrable address-units-per-packed-char 1)
 
-(define-integrable (interpreter-register:lookup)
-  (rtl:make-machine-register regnum:call-value))
+(define-integrable signed-fixnum/upper-limit (expt 2 (-1+ scheme-datum-width)))
+(define-integrable signed-fixnum/lower-limit (- signed-fixnum/upper-limit))
+(define-integrable unsigned-fixnum/upper-limit (* 2 signed-fixnum/upper-limit))
 
-(define-integrable (interpreter-register:unassigned?)
-  (rtl:make-machine-register regnum:call-value))
-
-(define-integrable (interpreter-register:unbound?)
-  (rtl:make-machine-register regnum:call-value))
+(define-integrable (stack->memory-offset offset) offset)
+(define-integrable ic-block-first-parameter-offset 2)
+(define-integrable closure-block-first-offset 3)
+\f
+;;;; Machine Registers
+
+(define-integrable g0 0)
+(define-integrable g1 1)
+(define-integrable g2 2)
+(define-integrable g3 3)
+(define-integrable g4 4)
+(define-integrable g5 5)
+(define-integrable g6 6)
+(define-integrable g7 7)
+(define-integrable g8 8)
+(define-integrable g9 9)
+(define-integrable g10 10)
+(define-integrable g11 11)
+(define-integrable g12 12)
+(define-integrable g13 13)
+(define-integrable g14 14)
+(define-integrable g15 15)
+(define-integrable g16 16)
+(define-integrable g17 17)
+(define-integrable g18 18)
+(define-integrable g19 19)
+(define-integrable g20 20)
+(define-integrable g21 21)
+(define-integrable g22 22)
+(define-integrable g23 23)
+(define-integrable g24 24)
+(define-integrable g25 25)
+(define-integrable g26 26)
+(define-integrable g27 27)
+(define-integrable g28 28)
+(define-integrable g29 29)
+(define-integrable g30 30)
+(define-integrable g31 31)
+
+;; fp0 - fp3 are status registers.  The rest are real registers
+(define-integrable fp0 32)
+(define-integrable fp1 33)
+(define-integrable fp2 34)
+(define-integrable fp3 35)
+(define-integrable fp4 36)
+(define-integrable fp5 37)
+(define-integrable fp6 38)
+(define-integrable fp7 39)
+(define-integrable fp8 40)
+(define-integrable fp9 41)
+(define-integrable fp10 42)
+(define-integrable fp11 43)
+(define-integrable fp12 44)
+(define-integrable fp13 45)
+(define-integrable fp14 46)
+(define-integrable fp15 47)
+
+(define-integrable number-of-machine-registers 48)
+(define-integrable number-of-temporary-registers 256)
+\f
+;;; Fixed-use registers for Scheme compiled code.
+(define-integrable regnum:return-value g2)
+(define-integrable regnum:scheme-to-interface-ble g3)
+(define-integrable regnum:regs-pointer g4)
+(define-integrable regnum:quad-bitmask g5)
+(define-integrable regnum:dynamic-link g19)
+(define-integrable regnum:memtop-pointer g20)
+(define-integrable regnum:free-pointer g21)
+(define-integrable regnum:stack-pointer g22)
+
+;;; Fixed-use registers due to architecture or OS calling conventions.
+(define-integrable regnum:zero g0)
+(define-integrable regnum:addil-result g1)
+(define-integrable regnum:C-global-pointer g27)
+(define-integrable regnum:C-return-value g28)
+(define-integrable regnum:C-stack-pointer g30)
+(define-integrable regnum:ble-return g31)
+(define-integrable regnum:fourth-arg g23)
+(define-integrable regnum:third-arg g24)
+(define-integrable regnum:second-arg g25)
+(define-integrable regnum:first-arg g26)
+
+(define (machine-register-value-class register)
+  (cond ((or (= register 0)
+            (<= 6 register 18)
+            (<= 23 register 26)
+            (= register 29)
+            (= register 31))
+        value-class=word)
+       ((or (= register 2) (= register 28))
+        value-class=object)
+       ((or (= register 1) (= register 3))
+        value-class=unboxed)
+       ((or (= register 4)
+            (<= 19 register 22)
+            (= register 27)
+            (= register 30))
+        value-class=address)
+       ((= register 5)
+        value-class=immediate)
+       ((<= 32 register 47)
+        value-class=float)
+       (else
+        (error "illegal machine register" register))))
+
+(define-integrable (machine-register-known-value register)
+  register                             ;ignore
+  false)
+\f
+;;;; Interpreter Registers
 
 (define-integrable (interpreter-free-pointer)
   (rtl:make-machine-register regnum:free-pointer))
 
-(define-integrable (interpreter-free-pointer? register)
-  (= (rtl:register-number register) regnum:free-pointer))
+(define (interpreter-free-pointer? expression)
+  (and (rtl:register? expression)
+       (= (rtl:register-number expression) regnum:free-pointer)))
 
 (define-integrable (interpreter-regs-pointer)
   (rtl:make-machine-register regnum:regs-pointer))
 
-(define-integrable (interpreter-regs-pointer? register)
-  (= (rtl:register-number register) regnum:regs-pointer))
+(define (interpreter-regs-pointer? expression)
+  (and (rtl:register? expression)
+       (= (rtl:register-number expression) regnum:regs-pointer)))
+
+(define-integrable (interpreter-value-register)
+  (rtl:make-machine-register regnum:return-value))
+
+(define (interpreter-value-register? expression)
+  (and (rtl:register? expression)
+       (= (rtl:register-number expression) regnum:return-value)))
 
 (define-integrable (interpreter-stack-pointer)
   (rtl:make-machine-register regnum:stack-pointer))
 
-(define-integrable (interpreter-stack-pointer? register)
-  (= (rtl:register-number register) regnum:stack-pointer))
+(define (interpreter-stack-pointer? expression)
+  (and (rtl:register? expression)
+       (= (rtl:register-number expression) regnum:stack-pointer)))
+
+(define-integrable (interpreter-dynamic-link)
+  (rtl:make-machine-register regnum:dynamic-link))
+
+(define (interpreter-dynamic-link? expression)
+  (and (rtl:register? expression)
+       (= (rtl:register-number expression) regnum:dynamic-link)))
+
+(define-integrable (interpreter-environment-register)
+  (rtl:make-offset (interpreter-regs-pointer) 3))
+
+(define (interpreter-environment-register? expression)
+  (and (rtl:offset? expression)
+       (interpreter-regs-pointer? (rtl:offset-base expression))
+       (= 3 (rtl:offset-number expression))))
+
+(define-integrable (interpreter-register:access)
+  (rtl:make-machine-register g28))
+
+(define-integrable (interpreter-register:cache-reference)
+  (rtl:make-machine-register g28))
+
+(define-integrable (interpreter-register:cache-unassigned?)
+  (rtl:make-machine-register g28))
+
+(define-integrable (interpreter-register:lookup)
+  (rtl:make-machine-register g28))
+
+(define-integrable (interpreter-register:unassigned?)
+  (rtl:make-machine-register g28))
+
+(define-integrable (interpreter-register:unbound?)
+  (rtl:make-machine-register g28))
 \f
-(define (lap:make-label-statement label)
-  `(LABEL ,label))
+;;;; RTL Registers, Constants, and Primitives
 
-(define (lap:make-unconditional-branch label)
-  `((BL (N) (- (- ,label *PC*) 8) 0)))
+(define (rtl:machine-register? rtl-register)
+  (case rtl-register
+    ((STACK-POINTER)
+     (interpreter-stack-pointer))
+    ((DYNAMIC-LINK)
+     (interpreter-dynamic-link))
+    ((VALUE)
+     (interpreter-value-register))
+    ((INTERPRETER-CALL-RESULT:ACCESS)
+     (interpreter-register:access))
+    ((INTERPRETER-CALL-RESULT:CACHE-REFERENCE)
+     (interpreter-register:cache-reference))
+    ((INTERPRETER-CALL-RESULT:CACHE-UNASSIGNED?)
+     (interpreter-register:cache-unassigned?))
+    ((INTERPRETER-CALL-RESULT:LOOKUP)
+     (interpreter-register:lookup))
+    ((INTERPRETER-CALL-RESULT:UNASSIGNED?)
+     (interpreter-register:unassigned?))
+    ((INTERPRETER-CALL-RESULT:UNBOUND?)
+     (interpreter-register:unbound?))
+    (else false)))
+
+(define (rtl:interpreter-register? rtl-register)
+  (case rtl-register
+    ((MEMORY-TOP) 0)
+    ((STACK-GUARD) 1)
+    ((ENVIRONMENT) 3)
+    ((TEMPORARY) 4)
+    (else false)))
+
+(define (rtl:interpreter-register->offset locative)
+  (or (rtl:interpreter-register? locative)
+      (error "Unknown register type" locative)))
 
-(define (lap:make-entry-point label block-start-label)
-  `((ENTRY-POINT ,label)
-    (WORD (- ,label ,block-start-label))
-    (LABEL ,label)))
\ No newline at end of file
+(define (rtl:constant-cost expression)
+  ;; Magic numbers.
+  (let ((if-integer
+        (lambda (value)
+          (cond ((zero? value) 1)
+                ((fits-in-5-bits-signed? value) 2)
+                (else 3)))))
+    (let ((if-synthesized-constant
+          (lambda (type datum)
+            (if-integer (make-non-pointer-literal type datum)))))
+      (case (rtl:expression-type expression)
+       ((CONSTANT)
+        (let ((value (rtl:constant-value expression)))
+          (if (non-pointer-object? value)
+              (if-synthesized-constant (object-type value)
+                                       (object-datum value))
+              3)))
+       ((MACHINE-CONSTANT)
+        (if-integer (rtl:machine-constant-value expression)))
+       ((ENTRY:PROCEDURE
+         ENTRY:CONTINUATION
+         ASSIGNMENT-CACHE
+         VARIABLE-CACHE
+         OFFSET-ADDRESS)
+        3)
+       ((CONS-POINTER)
+        (and (rtl:machine-constant? (rtl:cons-pointer-type expression))
+             (rtl:machine-constant? (rtl:cons-pointer-datum expression))
+             (if-synthesized-constant
+              (rtl:machine-constant-value (rtl:cons-pointer-type expression))
+              (rtl:machine-constant-value
+               (rtl:cons-pointer-datum expression)))))
+       (else false)))))
+
+(define compiler:open-code-floating-point-arithmetic?
+  true)
+
+(define compiler:primitives-with-no-open-coding
+  '(MULTIPLY-FIXNUM INTEGER-MULTIPLY &*
+    DIVIDE-FIXNUM GCD-FIXNUM FIXNUM-QUOTIENT FIXNUM-REMAINDER
+    INTEGER-QUOTIENT INTEGER-REMAINDER &/
+    FLONUM-SIN FLONUM-COS FLONUM-TAN FLONUM-ASIN FLONUM-ACOS
+    FLONUM-ATAN FLONUM-EXP FLONUM-LOG FLONUM-TRUNCATE))
\ No newline at end of file
diff --git a/v7/src/compiler/machines/spectrum/rgspcm.scm b/v7/src/compiler/machines/spectrum/rgspcm.scm
new file mode 100644 (file)
index 0000000..d0b56e8
--- /dev/null
@@ -0,0 +1,75 @@
+#| -*-Scheme-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/rgspcm.scm,v 4.1 1990/01/25 16:39:03 jinx Rel $
+$MC68020-Header: rgspcm.scm,v 4.1 87/12/30 07:05:38 GMT cph Exp $
+
+Copyright (c) 1987, 1989, 1990 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science.  Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. |#
+
+;;;; RTL Generation: Special primitive combinations.  Spectrum version.
+
+(declare (usual-integrations))
+\f
+(define (define-special-primitive-handler name handler)
+  (let ((primitive (make-primitive-procedure name true)))
+    (let ((entry (assq primitive special-primitive-handlers)))
+      (if entry
+         (set-cdr! entry handler)
+         (set! special-primitive-handlers
+               (cons (cons primitive handler)
+                     special-primitive-handlers)))))
+  name)
+
+(define (special-primitive-handler primitive)
+  (let ((entry (assq primitive special-primitive-handlers)))
+    (and entry
+        (cdr entry))))
+
+(define special-primitive-handlers
+  '())
+
+(define (define-special-primitive/standard primitive)
+  (define-special-primitive-handler primitive
+    rtl:make-invocation:special-primitive))
+
+(define-special-primitive/standard '&+)
+(define-special-primitive/standard '&-)
+;; (define-special-primitive/standard '&*)
+(define-special-primitive/standard '&/)
+(define-special-primitive/standard '&=)
+(define-special-primitive/standard '&<)
+(define-special-primitive/standard '&>)
+(define-special-primitive/standard '1+)
+(define-special-primitive/standard '-1+)
+(define-special-primitive/standard 'zero?)
+(define-special-primitive/standard 'positive?)
+(define-special-primitive/standard 'negative?)
+
+
diff --git a/v7/src/compiler/machines/spectrum/rules1.scm b/v7/src/compiler/machines/spectrum/rules1.scm
new file mode 100644 (file)
index 0000000..12ac64e
--- /dev/null
@@ -0,0 +1,268 @@
+#| -*-Scheme-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/rules1.scm,v 4.32 1990/01/25 16:39:51 jinx Exp $
+$MC68020-Header: rules1.scm,v 4.32 90/01/18 22:43:54 GMT cph Exp $
+
+Copyright (c) 1989, 1990 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science.  Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. |#
+
+;;;; LAP Generation Rules: Data Transfers
+
+(declare (usual-integrations))
+\f
+;;;; Simple Operations
+
+;;; All assignments to pseudo registers are required to delete the
+;;; dead registers BEFORE performing the assignment.  However, it is
+;;; necessary to derive the effective address of the source
+;;; expression(s) before deleting the dead registers.  Otherwise any
+;;; source expression containing dead registers might refer to aliases
+;;; which have been reused.
+
+(define-rule statement
+  (ASSIGN (REGISTER (? target)) (REGISTER (? source)))
+  (standard-move-to-target! source target)
+  (LAP))
+
+(define-rule statement
+  ;; tag the contents of a register
+  (ASSIGN (REGISTER (? target))
+         (CONS-POINTER (REGISTER (? type)) (REGISTER (? datum))))
+  (let* ((type (standard-source! type))
+        (target (standard-move-to-target! datum target)))
+    (LAP (DEP () ,type ,(-1+ scheme-type-width) ,scheme-type-width ,target))))
+
+(define-rule statement
+  ;; tag the contents of a register
+  (ASSIGN (REGISTER (? target))
+         (CONS-POINTER (MACHINE-CONSTANT (? type)) (REGISTER (? source))))
+  (QUALIFIER (fits-in-5-bits-signed? type))
+  (deposit-type type (standard-move-to-target! source target)))
+
+(define-rule statement
+  ;; extract the type part of a register's contents
+  (ASSIGN (REGISTER (? target)) (OBJECT->TYPE (REGISTER (? source))))
+  (standard-unary-conversion source target object->type))
+
+(define-rule statement
+  ;; extract the datum part of a register's contents
+  (ASSIGN (REGISTER (? target)) (OBJECT->DATUM (REGISTER (? source))))
+  (standard-unary-conversion source target object->datum))
+
+(define-rule statement
+  ;; convert the contents of a register to an address
+  (ASSIGN (REGISTER (? target)) (OBJECT->ADDRESS (REGISTER (? source))))
+  (object->address (standard-move-to-target! source target)))
+
+(define-rule statement
+  ;; add a constant to a register's contents
+  (ASSIGN (REGISTER (? target))
+         (OFFSET-ADDRESS (REGISTER (? source)) (? offset)))
+  (standard-unary-conversion source target
+    (lambda (source target)
+      (load-offset (* 4 offset) source target))))
+
+(define-rule statement
+  ;; read an object from memory
+  (ASSIGN (REGISTER (? target)) (OFFSET (REGISTER (? address)) (? offset)))
+  (standard-unary-conversion address target
+    (lambda (address target)
+      (load-word (* 4 offset) address target))))
+
+(define-rule statement
+  ;; pop an object off the stack
+  (ASSIGN (REGISTER (? target)) (POST-INCREMENT (REGISTER 22) 1))
+  (LAP (LDWM () (OFFSET 4 0 22) ,(standard-target! target))))
+\f
+;;;; Loading of Constants
+
+(define-rule statement
+  ;; load a machine constant
+  (ASSIGN (REGISTER (? target)) (MACHINE-CONSTANT (? source)))
+  (load-immediate source (standard-target! target)))
+
+(define-rule statement
+  ;; load a Scheme constant
+  (ASSIGN (REGISTER (? target)) (CONSTANT (? source)))
+  (load-constant source (standard-target! target)))
+
+(define-rule statement
+  ;; load the type part of a Scheme constant
+  (ASSIGN (REGISTER (? target)) (OBJECT->TYPE (CONSTANT (? constant))))
+  (load-non-pointer 0 (object-type constant) (standard-target! target)))
+
+(define-rule statement
+  ;; load the datum part of a Scheme constant
+  (ASSIGN (REGISTER (? target)) (OBJECT->DATUM (CONSTANT (? constant))))
+  (QUALIFIER (non-pointer-object? constant))
+  (load-non-pointer 0
+                   (careful-object-datum constant)
+                   (standard-target! target)))
+
+(define-rule statement
+  ;; load a synthesized constant
+  (ASSIGN (REGISTER (? target))
+         (CONS-POINTER (MACHINE-CONSTANT (? type))
+                       (MACHINE-CONSTANT (? datum))))
+  (load-non-pointer type datum (standard-target! target)))
+
+(define-rule statement
+  ;; load the address of a variable reference cache
+  (ASSIGN (REGISTER (? target)) (VARIABLE-CACHE (? name)))
+  (load-pc-relative (free-reference-label name) 
+                   (standard-target! target)))
+
+(define-rule statement
+  ;; load the address of an assignment cache
+  (ASSIGN (REGISTER (? target)) (ASSIGNMENT-CACHE (? name)))
+  (load-pc-relative (free-assignment-label name)
+                   (standard-target! target)))
+
+(define-rule statement
+  ;; load the address of a procedure's entry point
+  (ASSIGN (REGISTER (? target)) (ENTRY:PROCEDURE (? label)))
+  (load-pc-relative-address label (standard-target! target)))
+
+(define-rule statement
+  ;; load the address of a continuation
+  (ASSIGN (REGISTER (? target)) (ENTRY:CONTINUATION (? label)))
+  (load-pc-relative-address label (standard-target! target)))
+
+;;; Spectrum optimizations
+
+(define (load-entry label target)
+  (let ((target (standard-target! target)))
+    (LAP ,@(load-pc-relative-address label target)
+        ,@(address->entry target))))
+
+(define-rule statement
+  ;; load a procedure object
+  (ASSIGN (REGISTER (? target))
+         (CONS-POINTER (MACHINE-CONSTANT (? type))
+                       (ENTRY:PROCEDURE (? label))))
+  (QUALIFIER (= type (ucode-type compiled-entry)))
+  (load-entry label target))
+
+(define-rule statement
+  ;; load a return address object
+  (ASSIGN (REGISTER (? target))
+         (CONS-POINTER (MACHINE-CONSTANT (? type))
+                       (ENTRY:CONTINUATION (? label))))
+  (QUALIFIER (= type (ucode-type compiled-entry)))
+  (load-entry label target))
+\f
+;;;; Transfers to Memory
+                   
+(define-rule statement
+  ;; store an object in memory
+  (ASSIGN (OFFSET (REGISTER (? address)) (? offset))
+         (? source register-expression))
+  (QUALIFIER (word-register? source))
+  (store-word (standard-source! source)
+             (* 4 offset)
+             (standard-source! address)))
+
+(define-rule statement
+  ;; Push an object register on the heap
+  (ASSIGN (POST-INCREMENT (REGISTER 21) 1) (? source register-expression))
+  (QUALIFIER (word-register? source))
+  (LAP (STWM () ,(standard-source! source) (OFFSET 4 0 21))))
+
+(define-rule statement
+  ;; Push an object register on the stack
+  (ASSIGN (PRE-INCREMENT (REGISTER 22) -1) (? source register-expression))
+  (QUALIFIER (word-register? source))
+  (LAP (STWM () ,(standard-source! source) (OFFSET -4 0 22))))
+
+;; Cheaper, common patterns.
+
+(define-rule statement
+  (ASSIGN (OFFSET (REGISTER (? address)) (? offset)) (MACHINE-CONSTANT 0))
+  (store-word 0
+             (* 4 offset)
+             (standard-source! address)))
+
+(define-rule statement
+  (ASSIGN (POST-INCREMENT (REGISTER 21) 1) (MACHINE-CONSTANT 0))
+  (LAP (STWM () 0 (OFFSET 4 0 21))))
+
+(define-rule statement
+  (ASSIGN (PRE-INCREMENT (REGISTER 22) -1) (MACHINE-CONSTANT 0))
+  (LAP (STWM () 0 (OFFSET -4 0 22))))
+\f
+;;;; CHAR->ASCII/BYTE-OFFSET
+
+(define-rule statement
+  ;; load char object from memory and convert to ASCII byte
+  (ASSIGN (REGISTER (? target))
+         (CHAR->ASCII (OFFSET (REGISTER (? address)) (? offset))))
+  (standard-unary-conversion address target
+    (lambda (address target)
+      (load-byte (+ 3 (* 4 offset)) address target))))
+
+(define-rule statement
+  ;; load ASCII byte from memory
+  (ASSIGN (REGISTER (? target))
+         (BYTE-OFFSET (REGISTER (? address)) (? offset)))
+  (standard-unary-conversion address target
+    (lambda (address target)
+      (load-byte offset address target))))
+
+(define-rule statement
+  ;; convert char object to ASCII byte
+  ;; Missing optimization: If source is home and this is the last
+  ;; reference (it is dead afterwards), an LDB could be done instead
+  ;; of an LDW followed by an object->datum.  This is unlikely since
+  ;; the value will be home only if we've spilled it, which happens
+  ;; rarely.
+  (ASSIGN (REGISTER (? target))
+         (CHAR->ASCII (REGISTER (? source))))
+  (standard-unary-conversion source target
+    (lambda (source target)
+      (LAP (EXTRU () ,source 31 8 ,target)))))
+
+(define-rule statement
+  ;; store null byte in memory
+  (ASSIGN (BYTE-OFFSET (REGISTER (? source)) (? offset))
+         (CHAR->ASCII (CONSTANT #\NUL)))
+  (store-byte 0 offset (standard-source! source)))
+
+(define-rule statement
+  ;; store ASCII byte in memory
+  (ASSIGN (BYTE-OFFSET (REGISTER (? address)) (? offset))
+         (REGISTER (? source)))
+  (store-byte (standard-source! source) offset (standard-source! address)))
+
+(define-rule statement
+  ;; convert char object to ASCII byte and store it in memory
+  ;; register + byte offset <- contents of register (clear top bits)
+  (ASSIGN (BYTE-OFFSET (REGISTER (? address)) (? offset))
+         (CHAR->ASCII (REGISTER (? source))))
+  (store-byte (standard-source! source) offset (standard-source! address)))
\ No newline at end of file
diff --git a/v7/src/compiler/machines/spectrum/rules2.scm b/v7/src/compiler/machines/spectrum/rules2.scm
new file mode 100644 (file)
index 0000000..c67240d
--- /dev/null
@@ -0,0 +1,85 @@
+#| -*-Scheme-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/rules2.scm,v 4.12 1990/01/25 16:40:55 jinx Rel $
+$MC68020-Header: rules2.scm,v 4.12 90/01/18 22:44:04 GMT cph Exp $
+
+Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science.  Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. |#
+
+;;;; LAP Generation Rules: Predicates
+
+(declare (usual-integrations))
+\f
+(define-rule predicate
+  ;; test for two registers EQ?
+  (EQ-TEST (REGISTER (? source1)) (REGISTER (? source2)))
+  (compare '= (standard-source! source1) (standard-source! source2)))
+
+(define-rule predicate
+  ;; test for register EQ? to constant
+  (EQ-TEST (CONSTANT (? constant)) (REGISTER (? register)))
+  (eq-test/constant*register constant register))
+
+(define-rule predicate
+  ;; test for register EQ? to constant
+  (EQ-TEST (REGISTER (? register)) (CONSTANT (? constant)))
+  (eq-test/constant*register constant register))
+
+(define (eq-test/constant*register constant source)
+  (let ((source (standard-source! source)))
+    (if (non-pointer-object? constant)
+       (compare-immediate '= (non-pointer->literal constant) source)
+       (let ((temp (standard-temporary!)))
+         (LAP ,@(load-constant constant temp)
+              ,@(compare '= temp source))))))
+
+(define-rule predicate
+  ;; test for register EQ? to synthesized constant
+  (EQ-TEST (CONS-POINTER (MACHINE-CONSTANT (? type))
+                        (MACHINE-CONSTANT (? datum)))
+          (REGISTER (? register)))
+  (eq-test/synthesized-constant*register type datum register))
+
+(define-rule predicate
+  ;; test for register EQ? to synthesized constant
+  (EQ-TEST (REGISTER (? register))
+          (CONS-POINTER (MACHINE-CONSTANT (? type))
+                        (MACHINE-CONSTANT (? datum))))
+  (eq-test/synthesized-constant*register type datum register))
+
+(define (eq-test/synthesized-constant*register type datum source)
+  (compare-immediate '=
+                    (make-non-pointer-literal type datum)
+                    (standard-source! source)))
+
+(define-rule predicate
+  ;; Branch if virtual register contains the specified type number
+  (TYPE-TEST (REGISTER (? register)) (? type))
+  (compare-immediate '= type (standard-source! register)))
\ No newline at end of file
diff --git a/v7/src/compiler/machines/spectrum/rules3.scm b/v7/src/compiler/machines/spectrum/rules3.scm
new file mode 100644 (file)
index 0000000..da0ad69
--- /dev/null
@@ -0,0 +1,588 @@
+#| -*-Scheme-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/rules3.scm,v 4.23 1990/01/25 16:42:42 jinx Exp $
+$MC68020-Header: rules3.scm,v 4.23 90/01/18 22:44:09 GMT cph Exp $
+
+Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science.  Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. |#
+
+;;;; LAP Generation Rules: Invocations and Entries
+
+(declare (usual-integrations))
+\f
+;;;; Invocations
+
+(define-rule statement
+  (POP-RETURN)
+  (pop-return))
+
+(define (pop-return)
+  (let ((temp (standard-temporary!)))
+    (LAP ,@(clear-map!)
+        ;; This assumes that the return address is always longword aligned
+        ;; (it better be, since instructions should be longword aligned).
+        ;; Thus the bottom two bits of temp are 0, representing the
+        ;; highest privilege level, and the privilege level will
+        ;; not be changed by the BV instruction.
+        (LDWM () (OFFSET 4 0 22) ,temp)
+        ,@(object->address temp)
+        (BV (N) 0 ,temp))))
+
+(define-rule statement
+  (INVOCATION:APPLY (? frame-size) (? continuation))
+  continuation                         ;ignore
+  (LAP ,@(clear-map!)
+       ,@(load-immediate frame-size regnum:second-arg)
+       (LDWM () (OFFSET 4 0 22) ,regnum:first-arg) ; procedure
+       ,@(invoke-interface code:compiler-apply)))
+
+(define-rule statement
+  (INVOCATION:JUMP (? frame-size) (? continuation) (? label))
+  frame-size continuation              ;ignore
+  (LAP ,@(clear-map!)
+       (B (N) (@PCR ,label))))
+
+(define-rule statement
+  (INVOCATION:COMPUTED-JUMP (? frame-size) (? continuation))
+  frame-size continuation              ;ignore
+  ;; It expects the procedure at the top of the stack
+  (pop-return))
+
+(define-rule statement
+  (INVOCATION:LEXPR (? number-pushed) (? continuation) (? label))
+  continuation                         ;ignore
+  (LAP ,@(clear-map!)
+       ,@(load-immediate number-pushed regnum:second-arg)
+       ,@(load-pc-relative-address label regnum:first-arg)
+       ,@(invoke-interface code:compiler-lexpr-apply)))
+
+(define-rule statement
+  (INVOCATION:COMPUTED-LEXPR (? number-pushed) (? continuation))
+  continuation                         ;ignore
+  ;; Destination address is at TOS; pop it into first-arg
+  (LAP ,@(clear-map!)
+       (LDWM () (OFFSET 4 0 22) ,regnum:first-arg)
+       ,@(load-immediate number-pushed regnum:second-arg)
+       ,@(object->address regnum:first-arg)
+       ,@(invoke-interface code:compiler-lexpr-apply)))
+
+(define-rule statement
+  (INVOCATION:UUO-LINK (? frame-size) (? continuation) (? name))
+  continuation                         ;ignore
+  (LAP ,@(clear-map!)
+       (B (N) (@PCR ,(free-uuo-link-label name frame-size)))))
+
+(define-rule statement
+  (INVOCATION:CACHE-REFERENCE (? frame-size)
+                             (? continuation)
+                             (? extension register-expression))
+  continuation                         ;ignore
+  (LAP ,@(load-interface-args! extension false false false)
+       ,@(load-immediate frame-size regnum:third-arg)
+       ,@(load-pc-relative-address *block-label* regnum:second-arg)
+       ,@(invoke-interface code:compiler-cache-reference-apply)))
+\f
+(define-rule statement
+  (INVOCATION:LOOKUP (? frame-size)
+                    (? continuation)
+                    (? environment register-expression)
+                    (? name))
+  continuation                         ;ignore
+  (LAP ,@(load-interface-args! environment false false false)
+       ,(load-constant name regnum:second-arg)
+       ,(load-immediate frame-size regnum:third-arg)
+       ,@(invoke-interface code:compiler-lookup-apply)))
+
+(define-rule statement
+  (INVOCATION:PRIMITIVE (? frame-size) (? continuation) (? primitive))
+  continuation                         ;ignore
+  (if (eq? primitive compiled-error-procedure)
+      (LAP ,@(clear-map!)
+          ,@(load-immediate frame-size regnum:first-arg)
+          ,@(invoke-interface code:compiler-error))
+      (LAP ,@(clear-map!)
+          ,@(load-pc-relative (constant->label primitive)
+                              regnum:first-arg)
+          ,@(let ((arity (primitive-procedure-arity primitive)))
+              (cond ((not (negative? arity))
+                     (invoke-interface code:compiler-primitive-apply))
+                    ((= arity -1)
+                     (LAP ,@(load-immediate (-1+ frame-size) 1)
+                          (STW () 1 ,reg:lexpr-primitive-arity)
+                          ,@(invoke-interface
+                             code:compiler-primitive-lexpr-apply)))
+                    (else
+                     ;; Unknown primitive arity.  Go through apply.
+                     (LAP ,@(load-immediate frame-size regnum:second-arg)
+                          ,@(invoke-interface code:compiler-apply))))))))
+
+(let-syntax
+    ((define-special-primitive-invocation
+       (macro (name)
+        `(define-rule statement
+           (INVOCATION:SPECIAL-PRIMITIVE
+            (? frame-size)
+            (? continuation)
+            ,(make-primitive-procedure name true))
+           frame-size continuation
+           ,(list 'LAP
+                  (list 'UNQUOTE-SPLICING '(clear-map!))
+                  (list 'UNQUOTE-SPLICING
+                        `(INVOKE-INTERFACE ,(symbol-append 'CODE:COMPILER-
+                                                           name))))))))
+  (define-special-primitive-invocation &+)
+  (define-special-primitive-invocation &-)
+  (define-special-primitive-invocation &*)
+  (define-special-primitive-invocation &/)
+  (define-special-primitive-invocation &=)
+  (define-special-primitive-invocation &<)
+  (define-special-primitive-invocation &>)
+  (define-special-primitive-invocation 1+)
+  (define-special-primitive-invocation -1+)
+  (define-special-primitive-invocation zero?)
+  (define-special-primitive-invocation positive?)
+  (define-special-primitive-invocation negative?))
+\f
+;;;; Invocation Prefixes
+
+;;; MOVE-FRAME-UP size address
+;;;
+;;; Moves up the last <size> words of the stack so that the first of
+;;; these words is at location <address>, and resets the stack pointer
+;;; to the last of these words.  That is, it pops off all the words
+;;; between <address> and TOS+/-<size>.
+
+(define-rule statement
+  ;; Move up 0 words back to top of stack : a No-Op
+  (INVOCATION-PREFIX:MOVE-FRAME-UP 0 (REGISTER 22))
+  (LAP))
+
+(define-rule statement
+  ;; Move <frame-size> words back to dynamic link marker
+  (INVOCATION-PREFIX:MOVE-FRAME-UP (? frame-size) (REGISTER 19))
+  (generate/move-frame-up frame-size
+                         (lambda (reg) (LAP (COPY () 19 ,reg)))))
+
+(define-rule statement
+  ;; Move <frame-size> words back to SP+offset
+  (INVOCATION-PREFIX:MOVE-FRAME-UP (? frame-size)
+                                  (OFFSET-ADDRESS (REGISTER 22) (? offset)))
+  (let ((how-far (* 4 (- offset frame-size))))
+    (cond ((zero? how-far)
+          (LAP))
+         ((negative? how-far)
+          (error "invocation-prefix:move-frame-up: bad specs"
+                 frame-size offset))
+         ((zero? frame-size)
+          (load-offset how-far 22 22))
+         ((= frame-size 1)
+          (let ((temp (standard-temporary!)))
+            (LAP (LDWM () (OFFSET ,how-far 0 22) ,temp)
+                 (STW () ,temp (OFFSET 0 0 22)))))
+         ((= frame-size 2)
+          (let ((temp1 (standard-temporary!))
+                (temp2 (standard-temporary!)))
+            (LAP (LDWM () (OFFSET 4 0 22) ,temp1)
+                 (LDWM () (OFFSET ,(- how-far 4) 0 22) ,temp2)
+                 (STW () ,temp1 (OFFSET 0 0 22))
+                 (STW () ,temp2 (OFFSET 4 0 22)))))
+         (else
+          (generate/move-frame-up frame-size
+            (lambda (reg)
+              (load-offset (* 4 offset) 22 reg)))))))
+
+(define-rule statement
+  ;; Move <frame-size> words back to base virtual register + offset
+  (INVOCATION-PREFIX:MOVE-FRAME-UP (? frame-size)
+                                  (OFFSET-ADDRESS (REGISTER (? base))
+                                                  (? offset)))
+  (generate/move-frame-up frame-size
+    (lambda (reg)
+      (load-offset (* 4 offset) (standard-source! base) reg))))
+\f
+;;; DYNAMIC-LINK instructions have a <frame-size>, <new frame end>,
+;;; and <current dynamic link> as arguments.  They pop the stack by
+;;; removing the lesser of the amount needed to move the stack pointer
+;;; back to the <new frame end> or <current dynamic link>.  The last
+;;; <frame-size> words on the stack (the stack frame for the procedure
+;;; about to be called) are then put back onto the newly adjusted
+;;; stack.
+
+(define-rule statement
+  (INVOCATION-PREFIX:DYNAMIC-LINK (? frame-size)
+                                 (REGISTER (? source))
+                                 (REGISTER 19))
+  (if (and (zero? frame-size)
+          (= source regnum:stack-pointer))
+      (LAP)
+      (let ((env-reg (standard-move-to-temporary! source)))
+       (LAP (SUB (<<=) ,env-reg 19 0)  ; skip if env LS dyn link
+            (COPY () 19 ,env-reg)      ; env <- dyn link
+            ,@(generate/move-frame-up* frame-size env-reg)))))
+
+(define (generate/move-frame-up frame-size destination-generator)
+  (let ((temp (standard-temporary!)))
+    (LAP ,@(destination-generator temp)
+        ,@(generate/move-frame-up* frame-size temp))))
+
+(define (generate/move-frame-up* frame-size destination)
+  ;; Destination is guaranteed to be a machine register number; that
+  ;; register has the destination base address for the frame.  The stack
+  ;; pointer is reset to the top end of the copied area.
+  (LAP ,@(case frame-size
+          ((0)
+           (LAP))
+          ((1)
+           (let ((temp (standard-temporary!)))
+             (LAP (LDW () (OFFSET 0 0 22) ,temp)
+                  (STWM () ,temp (OFFSET -4 0 ,destination)))))
+          (else
+           (generate/move-frame-up** frame-size destination)))
+       (COPY () ,destination 22)))
+
+(define (generate/move-frame-up** frame-size dest)
+  (let ((from (standard-temporary!))
+       (temp1 (standard-temporary!))
+       (temp2 (standard-temporary!)))
+    (LAP ,@(load-offset (* 4 frame-size) regnum:stack-pointer from)
+        ,@(if (<= frame-size 3)
+              ;; This code can handle any number > 1 (handled above),
+              ;; but we restrict it to 3 for space reasons.
+              (let loop ((n frame-size))
+                (case n
+                  ((0)
+                   (LAP))
+                  ((3)
+                   (let ((temp3 (standard-temporary!)))
+                     (LAP (LDWM () (OFFSET -4 0 ,from) ,temp1)
+                          (LDWM () (OFFSET -4 0 ,from) ,temp2)
+                          (LDWM () (OFFSET -4 0 ,from) ,temp3)
+                          (STWM () ,temp1 (OFFSET -4 0 ,dest))
+                          (STWM () ,temp2 (OFFSET -4 0 ,dest))
+                          (STWM () ,temp3 (OFFSET -4 0 ,dest)))))
+                  (else
+                   (LAP (LDWM () (OFFSET -4 0 ,from) ,temp1)
+                        (LDWM () (OFFSET -4 0 ,from) ,temp2)
+                        (STWM () ,temp1 (OFFSET -4 0 ,dest))
+                        (STWM () ,temp2 (OFFSET -4 0 ,dest))
+                        ,@(loop (- n 2))))))
+              (LAP ,@(load-immediate frame-size temp2)
+                   (LDWM () (OFFSET -4 0 ,from) ,temp1)
+                   (ADDIBF (=) -1 ,temp2 (@PCO -12))
+                   (STWM () ,temp1 (OFFSET -4 0 ,dest)))))))
+\f
+;;;; External Labels
+
+(define (make-external-label code label)
+  (set! *external-labels* (cons label *external-labels*))
+  (LAP (EXTERNAL-LABEL () ,code (@PCR ,label))
+       (LABEL ,label)))
+
+;;; Entry point types
+
+(define-integrable (make-code-word min max)
+  (+ (* #x100 min) max))
+
+(define (make-procedure-code-word min max)
+  ;; The "min" byte must be less than #x80; the "max" byte may not
+  ;; equal #x80 but can take on any other value.
+  (if (or (negative? min) (>= min #x80))
+      (error "MAKE-PROCEDURE-CODE-WORD: minimum out of range" min))
+  (if (>= (abs max) #x80)
+      (error "MAKE-PROCEDURE-CODE-WORD: maximum out of range" max))
+  (make-code-word min (if (negative? max) (+ #x100 max) max)))
+
+(define expression-code-word
+  (make-code-word #xff #xff))
+
+(define internal-entry-code-word
+  (make-code-word #xff #xfe))
+
+(define (continuation-code-word label)
+  (let ((offset
+        (if label
+            (rtl-continuation/next-continuation-offset (label->object label))
+            0)))
+    (cond ((not offset)
+          (make-code-word #xff #xfc))
+         ((< offset #x2000)
+          ;; This uses up through (#xff #xdf).
+          (let ((qr (integer-divide offset #x80)))
+            (make-code-word (+ #x80 (integer-divide-remainder qr))
+                            (+ #x80 (integer-divide-quotient qr)))))
+         (else
+          (error "Unable to encode continuation offset" offset)))))
+\f
+;;;; Procedure headers
+
+;;; The following calls MUST appear as the first thing at the entry
+;;; point of a procedure.  They assume that the register map is clear
+;;; and that no register contains anything of value.
+
+;;; **** The only reason that this is true is that no register is live
+;;; across calls.  If that were not true, then we would have to save
+;;; any such registers on the stack so that they would be GC'ed
+;;; appropriately.
+;;;
+;;; **** This is not strictly true: the dynamic link register may
+;;; contain a valid dynamic link, but the gc handler determines that
+;;; and saves it as appropriate.
+
+(define (simple-procedure-header code-word label code)
+  (let ((gc-label (generate-label)))    
+    (LAP (LABEL ,gc-label)
+        ,@(invoke-interface-ble code)
+        ,@(make-external-label code-word label)
+        ,@(interrupt-check gc-label))))
+
+(define (dlink-procedure-header code-word label)
+  (let ((gc-label (generate-label)))    
+    (LAP (LABEL ,gc-label)
+        (COPY () ,regnum:dynamic-link ,regnum:second-arg)
+        ,@(invoke-interface-ble code:compiler-interrupt-dlink)
+        ,@(make-external-label code-word label)
+        ,@(interrupt-check gc-label))))
+
+(define (interrupt-check gc-label)
+  (LAP (COMB (>=) ,regnum:free-pointer ,regnum:memtop-pointer (@PCR ,gc-label))
+       (LDW () ,reg:memtop ,regnum:memtop-pointer)))
+
+(define-rule statement
+  (CONTINUATION-ENTRY (? internal-label))
+  (make-external-label (continuation-code-word internal-label)
+                      internal-label))
+
+(define-rule statement
+  (CONTINUATION-HEADER (? internal-label))
+  (simple-procedure-header (continuation-code-word internal-label)
+                          internal-label
+                          code:compiler-interrupt-continuation))
+
+(define-rule statement
+  (IC-PROCEDURE-HEADER (? internal-label))
+  (let ((procedure (label->object internal-label)))
+    (let ((external-label (rtl-procedure/external-label procedure)))
+    (LAP (ENTRY-POINT ,external-label)
+        (EQUATE ,external-label ,internal-label)
+        ,@(simple-procedure-header expression-code-word
+                                   internal-label
+                                   code:compiler-interrupt-ic-procedure)))))
+
+(define-rule statement
+  (OPEN-PROCEDURE-HEADER (? internal-label))
+  (let ((rtl-proc (label->object internal-label)))
+    (LAP (EQUATE ,(rtl-procedure/external-label rtl-proc) ,internal-label)
+        ,@((if (rtl-procedure/dynamic-link? rtl-proc)
+               dlink-procedure-header 
+               (lambda (code-word label)
+                 (simple-procedure-header code-word label
+                                          code:compiler-interrupt-procedure)))
+           internal-entry-code-word
+           internal-label))))
+
+(define-rule statement
+  (PROCEDURE-HEADER (? internal-label) (? min) (? max))
+  (LAP (EQUATE ,(rtl-procedure/external-label (label->object internal-label))
+              ,internal-label)
+       ,@(simple-procedure-header (make-procedure-code-word min max)
+                                 internal-label
+                                 code:compiler-interrupt-procedure)))
+\f
+;;;; Closures.  These two statements are intertwined:
+
+;; Magic for compiled entries.
+
+(define compiled-entry-type-im5
+  (let* ((qr (integer-divide (ucode-type compiled-entry) 2))
+        (immed (integer-divide-quotient qr)))
+    (if (or (not (= scheme-type-width 6))
+           (not (zero? (integer-divide-remainder qr)))
+           (not (<= 0 immed #x1F)))
+       (error "closure header rule assumptions violated!"))
+    (if (<= immed #x0F)
+       immed
+       (- immed #x20))))
+
+(define-integrable (address->entry register)
+  (LAP (DEPI () ,compiled-entry-type-im5 4 5 ,register)))
+
+(define-rule statement
+  ;; This depends on the following facts:
+  ;; 1- tc_compiled_entry is a multiple of two.
+  ;; 2- all the top 6 bits in a data address are 0 except the quad bit
+  ;; 3- type codes are 6 bits long.
+  (CLOSURE-HEADER (? internal-label))
+  (let ((procedure (label->object internal-label)))
+    (let ((gc-label (generate-label))
+         (external-label (rtl-procedure/external-label procedure)))
+      (LAP (LABEL ,gc-label)
+          ,@(invoke-interface code:compiler-interrupt-closure)
+          ,@(make-external-label internal-entry-code-word external-label)
+          (DEP () 0 31 2 ,regnum:ble-return)
+          ,@(address->entry regnum:ble-return)
+          (STWM () ,regnum:ble-return (OFFSET -4 0 22))
+          (LABEL ,internal-label)
+          ,@(interrupt-check gc-label)))))
+
+(define (cons-closure target label min max size ->entry?)
+  (let ((flush-reg (clear-registers! regnum:ble-return)))
+    (need-register! regnum:ble-return)
+    (let ((dest (standard-target! target)))
+      ;; Note: dest is used as a temporary before the BLE instruction,
+      ;; and is written immediately afterwards.
+      (LAP ,@flush-reg
+          ,@(load-non-pointer (ucode-type manifest-closure) (+ 4 size) dest)
+          (STWM () ,dest (OFFSET 4 0 21))
+          ,@(load-immediate
+             (+ (* (make-procedure-code-word min max) #x10000) 4)
+             dest)
+          (STWM () ,dest (OFFSET 4 0 21))
+          ,@(load-pc-relative-address
+             (rtl-procedure/external-label (label->object label))
+             1)
+          (BLE ()
+               (OFFSET ,hook:compiler-store-closure-code
+                       4
+                       ,regnum:scheme-to-interface-ble))
+          (COPY () ,regnum:free-pointer ,dest)
+          ,@(if ->entry?
+                (address->entry dest)
+                (LAP))
+          ,@(load-offset (* 4 size)
+                         regnum:free-pointer
+                         regnum:free-pointer)))))
+
+(define-rule statement
+  (ASSIGN (REGISTER (? target))
+         (CONS-POINTER (MACHINE-CONSTANT (? type))
+                       (CONS-CLOSURE (ENTRY:PROCEDURE (? procedure-label))
+                                     (? min) (? max) (? size))))
+  (QUALIFIER (= type (ucode-type compiled-entry)))
+  (cons-closure target procedure-label min max size true))
+
+(define-rule statement
+  (ASSIGN (REGISTER (? target))
+         (CONS-CLOSURE (ENTRY:PROCEDURE (? procedure-label))
+                       (? min) (? max) (? size)))
+  (QUALIFIER (= type (ucode-type compiled-entry)))
+  (cons-closure target procedure-label min max size false))
+\f
+;;;; Entry Header
+;;; This is invoked by the top level of the LAP generator.
+
+(define (generate/quotation-header environment-label free-ref-label n-sections)
+  ;; Calls the linker
+  (LAP (LDW () ,reg:environment 2)
+       ,@(load-pc-relative-address environment-label 1)
+       (STW () 2 (OFFSET 0 0 1))
+       ,@(load-pc-relative-address *block-label* regnum:second-arg)
+       ,@(load-pc-relative-address free-ref-label regnum:third-arg)
+       ,@(load-immediate n-sections regnum:fourth-arg)
+       ,@(invoke-interface-ble code:compiler-link)
+       ,@(make-external-label (continuation-code-word false)
+                             (generate-label))))
+
+(define (generate/remote-link code-block-label
+                             environment-offset
+                             free-ref-offset
+                             n-sections)
+  ;; Link all of the top level procedures within the file
+  (LAP ,@(load-pc-relative code-block-label regnum:second-arg)
+       ,@(object->address regnum:second-arg)
+       (LDW () ,reg:environment 2)
+       ,@(load-offset environment-offset regnum:second-arg 1)
+       (STW () 2 (OFFSET 0 0 1))
+       ,@(load-offset free-ref-offset regnum:second-arg regnum:third-arg)
+       ,@(load-immediate n-sections regnum:fourth-arg)
+       ,@(invoke-interface-ble code:compiler-link)
+       ,@(make-external-label (continuation-code-word false)
+                             (generate-label))))
+\f
+(define (generate/constants-block constants references assignments uuo-links)
+  (let ((constant-info
+        (declare-constants 0 (transmogrifly uuo-links)
+          (declare-constants 1 references
+            (declare-constants 2 assignments
+              (declare-constants false constants
+                (cons false (LAP))))))))
+    (let ((free-ref-label (car constant-info))
+         (constants-code (cdr constant-info))
+         (debugging-information-label (allocate-constant-label))
+         (environment-label (allocate-constant-label))
+         (n-sections
+          (+ (if (null? uuo-links) 0 1)
+             (if (null? references) 0 1)
+             (if (null? assignments) 0 1))))
+      (values
+       (LAP ,@constants-code
+           ;; Place holder for the debugging info filename
+           (SCHEME-OBJECT ,debugging-information-label DEBUGGING-INFO)
+           ;; Place holder for the load time environment if needed
+           (SCHEME-OBJECT ,environment-label
+                          ,(if (null? free-ref-label) 0 'ENVIRONMENT)))
+       environment-label
+       free-ref-label
+       n-sections))))
+
+(define (declare-constants tag constants info)
+  (define (inner constants)
+    (if (null? constants)
+       (cdr info)
+       (let ((entry (car constants)))
+         (LAP (SCHEME-OBJECT ,(cdr entry) ,(car entry))
+              ,@(inner (cdr constants))))))
+  (if (and tag (not (null? constants)))
+      (let ((label (allocate-constant-label)))
+       (cons label
+             (inner
+              `((,(let ((datum (length constants)))
+                    (if (> datum #xffff)
+                        (error "datum too large" datum))
+                    (+ (* tag #x10000) datum))
+                 . ,label)
+                ,@constants))))
+      (cons (car info) (inner constants))))
+
+(define (transmogrifly uuos)
+  (define (inner name assoc)
+    (if (null? assoc)
+       (transmogrifly (cdr uuos))
+       `((,name . ,(cdar assoc))               ; uuo-label     LDIL
+         (0 . ,(allocate-constant-label))      ; spare         BLE
+         (,(caar assoc) .                      ; frame-size
+          ,(allocate-constant-label))
+         ,@(inner name (cdr assoc)))))
+  (if (null? uuos)
+      '()
+      (inner (caar uuos) (cdar uuos))))
+\f
+;;; Local Variables: ***
+;;; eval: (put 'declare-constants 'scheme-indent-hook 2) ***
+;;; End: ***
diff --git a/v7/src/compiler/machines/spectrum/rules4.scm b/v7/src/compiler/machines/spectrum/rules4.scm
new file mode 100644 (file)
index 0000000..db92bfa
--- /dev/null
@@ -0,0 +1,101 @@
+#| -*-Scheme-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/rules4.scm,v 4.11 1990/01/25 16:43:39 jinx Rel $
+$MC68020-Header: rules4.scm,v 4.11 90/01/20 07:26:13 GMT cph Exp $
+
+Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science.  Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. |#
+
+;;;; LAP Generation Rules: Interpreter Calls
+
+(declare (usual-integrations))
+\f
+;;;; Interpreter Calls
+
+(define-rule statement
+  (INTERPRETER-CALL:ACCESS (? environment register-expression) (? name))
+  (lookup-call code:compiler-access environment name))
+
+(define-rule statement
+  (INTERPRETER-CALL:LOOKUP (? environment register-expression)
+                          (? name)
+                          (? safe?))
+  (lookup-call (if safe? code:compiler-safe-lookup code:compiler-lookup)
+              environment
+              name))
+
+(define-rule statement
+  (INTERPRETER-CALL:UNASSIGNED? (? environment register-expression) (? name))
+  (lookup-call code:compiler-unassigned? environment name))
+
+(define-rule statement
+  (INTERPRETER-CALL:UNBOUND? (? environment register-expression) (? name))
+  (lookup-call code:compiler-unbound? environment name))
+
+(define (lookup-call code environment name)
+  (LAP ,@(load-interface-args! false environment false false)
+       ,@(load-constant name regnum:third-arg)
+       ,@(invoke-interface-ble code)))
+
+(define-rule statement
+  (INTERPRETER-CALL:DEFINE (? environment register-expression)
+                          (? name)
+                          (? value register-expression))
+  (assignment-call code:compiler-define environment name value))
+
+(define-rule statement
+  (INTERPRETER-CALL:SET! (? environment register-expression)
+                        (? name)
+                        (? value register-expression))
+  (assignment-call code:compiler-set! environment name value))
+
+(define (assignment-call code environment name value)
+  (LAP ,@(load-interface-args! false environment false value)
+       ,@(load-constant name regnum:third-arg)
+       ,@(invoke-interface-ble code)))
+
+(define-rule statement
+  (INTERPRETER-CALL:CACHE-REFERENCE (REGISTER (? extension)) (? safe?))
+  (LAP ,@(load-interface-args! false extension false false)
+       ,@(invoke-interface-ble
+         (if safe?
+             code:compiler-safe-reference-trap
+             code:compiler-reference-trap))))
+
+(define-rule statement
+  (INTERPRETER-CALL:CACHE-ASSIGNMENT (REGISTER (? extension))
+                                    (? value register-expression))
+  (LAP ,@(load-interface-args! false extension value false)
+       ,@(invoke-interface-ble code:compiler-assignment-trap)))
+
+(define-rule statement
+  (INTERPRETER-CALL:CACHE-UNASSIGNED? (REGISTER (? extension)))
+  (LAP ,@(load-interface-args! false extension false false)
+       ,@(invoke-interface-ble code:compiler-unassigned?-trap)))
\ No newline at end of file
diff --git a/v7/src/compiler/machines/spectrum/rulfix.scm b/v7/src/compiler/machines/spectrum/rulfix.scm
new file mode 100644 (file)
index 0000000..5efc3fd
--- /dev/null
@@ -0,0 +1,356 @@
+#| -*-Scheme-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/rulfix.scm,v 4.32 1990/01/25 16:44:44 jinx Exp $
+$MC68020-Header: rules1.scm,v 4.32 90/01/18 22:43:54 GMT cph Exp $
+
+Copyright (c) 1989, 1990 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science.  Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. |#
+
+;;;; LAP Generation Rules: Fixnum Rules
+
+(declare (usual-integrations))
+\f
+;;;; Conversions
+
+(define-rule statement
+  ;; convert a fixnum object to a "fixnum integer"
+  (ASSIGN (REGISTER (? target)) (OBJECT->FIXNUM (REGISTER (? source))))
+  (standard-unary-conversion source target object->fixnum))
+
+(define-rule statement
+  ;; load a fixnum constant as a "fixnum integer"
+  (ASSIGN (REGISTER (? target)) (OBJECT->FIXNUM (CONSTANT (? constant))))
+  (load-fixnum-constant constant (standard-target! target)))
+
+(define-rule statement
+  ;; convert a memory address to a "fixnum integer"
+  (ASSIGN (REGISTER (? target)) (ADDRESS->FIXNUM (REGISTER (? source))))
+  (standard-unary-conversion source target address->fixnum))
+
+(define-rule statement
+  ;; convert an object's address to a "fixnum integer"
+  (ASSIGN (REGISTER (? target))
+         (ADDRESS->FIXNUM (OBJECT->ADDRESS (REGISTER (? source)))))
+  (standard-unary-conversion source target object->fixnum))
+
+(define-rule statement
+  ;; convert a "fixnum integer" to a fixnum object
+  (ASSIGN (REGISTER (? target)) (FIXNUM->OBJECT (REGISTER (? source))))
+  (standard-unary-conversion source target fixnum->object))
+
+(define-rule statement
+  ;; convert a "fixnum integer" to a memory address
+  (ASSIGN (REGISTER (? target)) (FIXNUM->ADDRESS (REGISTER (? source))))
+  (standard-unary-conversion source target fixnum->address))
+
+(define-rule statement
+  (ASSIGN (REGISTER (? target))
+         (FIXNUM-2-ARGS MULTIPLY-FIXNUM
+                        (OBJECT->FIXNUM (CONSTANT 4))
+                        (OBJECT->FIXNUM (REGISTER (? source)))
+                        #F))
+  (standard-unary-conversion source target object->index-fixnum))
+
+(define-rule statement
+  (ASSIGN (REGISTER (? target))
+         (FIXNUM-2-ARGS MULTIPLY-FIXNUM
+                        (OBJECT->FIXNUM (REGISTER (? source)))
+                        (OBJECT->FIXNUM (CONSTANT 4))
+                        #F))
+  (standard-unary-conversion source target object->index-fixnum))
+
+;; This is a patch for the time being.  Probably only one of these pairs
+;; of rules is needed.
+
+(define-rule statement
+  (ASSIGN (REGISTER (? target))
+         (FIXNUM-2-ARGS MULTIPLY-FIXNUM
+                        (OBJECT->FIXNUM (CONSTANT 4))
+                        (REGISTER (? source))
+                        #F))
+  (standard-unary-conversion source target fixnum->index-fixnum))
+
+(define-rule statement
+  (ASSIGN (REGISTER (? target))
+         (FIXNUM-2-ARGS MULTIPLY-FIXNUM
+                        (REGISTER (? source))
+                        (OBJECT->FIXNUM (CONSTANT 4))
+                        #F))
+  (standard-unary-conversion source target fixnum->index-fixnum))
+
+(define-integrable (fixnum->index-fixnum src tgt)
+  (LAP (SHD () ,src 0 30 ,tgt)))
+
+(define-integrable (object->fixnum src tgt)
+  (LAP (SHD () ,src 0 ,scheme-datum-width ,tgt)))
+
+(define-integrable (object->index-fixnum src tgt)
+  (LAP (SHD () ,src 0 ,(- scheme-datum-width 2) ,tgt)))
+
+(define-integrable (address->fixnum src tgt)
+  (LAP (SHD () ,src 0 ,scheme-datum-width ,tgt)))
+
+(define-integrable (fixnum->object src tgt)
+  (LAP ,@(load-immediate (ucode-type fixnum) regnum:addil-result)
+       (SHD () ,regnum:addil-result ,src ,scheme-type-width ,tgt)))
+
+(define (fixnum->address src tgt)
+  (LAP (SHD () ,regnum:quad-bitmask ,src ,scheme-type-width ,tgt)))
+
+(define (load-fixnum-constant constant target)
+  (load-immediate (* constant fixnum-1) target))
+
+(define-integrable fixnum-1
+  (expt 2 scheme-type-width))
+\f
+;;;; Arithmetic Operations
+
+(define-rule statement
+  ;; execute a unary fixnum operation
+  (ASSIGN (REGISTER (? target))
+         (FIXNUM-1-ARG (? operation)
+                       (REGISTER (? source))
+                       (? overflow?)))
+  (standard-unary-conversion source target
+    (lambda (source target)
+      ((fixnum-1-arg/operator operation) target source overflow?))))
+
+(define (fixnum-1-arg/operator operation)
+  (lookup-arithmetic-method operation fixnum-methods/1-arg))
+
+(define fixnum-methods/1-arg
+  (list 'FIXNUM-METHODS/1-ARG))
+
+(define-arithmetic-method 'ONE-PLUS-FIXNUM fixnum-methods/1-arg
+  (lambda (tgt src overflow?)
+    (if overflow?
+       (LAP (ADDI (NSV) ,fixnum-1 ,src ,tgt))
+       (LAP (ADDI () ,fixnum-1 ,src ,tgt)))))
+
+(define-arithmetic-method 'MINUS-ONE-PLUS-FIXNUM fixnum-methods/1-arg
+  (lambda (tgt src overflow?)
+    (if overflow?
+       (LAP (ADDI (NSV) ,(- fixnum-1) ,src ,tgt))
+       (LAP (ADDI () ,(- fixnum-1) ,src ,tgt)))))
+
+(define-rule statement
+  ;; execute a binary fixnum operation
+  (ASSIGN (REGISTER (? target))
+         (FIXNUM-2-ARGS (? operation)
+                        (REGISTER (? source1))
+                        (REGISTER (? source2))
+                        (? overflow?)))
+  (standard-binary-conversion source1 source2 target
+    (lambda (source1 source2 target)
+      ((fixnum-2-args/operator operation) target source1 source2 overflow?))))
+
+(define (fixnum-2-args/operator operation)
+  (lookup-arithmetic-method operation fixnum-methods/2-args))
+
+(define fixnum-methods/2-args
+  (list 'FIXNUM-METHODS/2-ARGS))
+
+(define-arithmetic-method 'PLUS-FIXNUM fixnum-methods/2-args
+  (lambda (tgt src1 src2 overflow?)
+    (if overflow?
+       (LAP (ADD (NSV) ,src1 ,src2 ,tgt))
+       (LAP (ADD () ,src1 ,src2 ,tgt)))))
+
+(define-arithmetic-method 'MINUS-FIXNUM fixnum-methods/2-args
+  (lambda (tgt src1 src2 overflow?)
+    (if overflow?
+       (LAP (SUB (NSV) ,src1 ,src2 ,tgt))
+       (LAP (SUB () ,src1 ,src2 ,tgt)))))
+\f
+(define-rule statement
+  ;; execute binary fixnum operation with constant second arg
+  (ASSIGN (REGISTER (? target))
+         (FIXNUM-2-ARGS (? operation)
+                        (REGISTER (? source))
+                        (OBJECT->FIXNUM (CONSTANT (? constant)))
+                        (? overflow?)))
+  (standard-unary-conversion source target
+    (lambda (source target)
+      ((fixnum-2-args/operator/register*constant operation)
+       target source constant overflow?))))
+
+(define-rule statement
+  ;; execute binary fixnum operation with constant first arg
+  (ASSIGN (REGISTER (? target))
+         (FIXNUM-2-ARGS (? operation)
+                        (OBJECT->FIXNUM (CONSTANT (? constant)))
+                        (REGISTER (? source))
+                        (? overflow?)))
+  (standard-unary-conversion source target
+    (lambda (source target)
+      (if (fixnum-2-args/commutative? operation)
+         ((fixnum-2-args/operator/register*constant operation)
+          target source constant overflow?)
+         ((fixnum-2-args/operator/constant*register operation)
+          target constant source overflow?)))))
+\f
+(define (fixnum-2-args/commutative? operator)
+  (memq operator '(PLUS-FIXNUM MULTIPLY-FIXNUM)))
+
+(define (fixnum-2-args/operator/register*constant operation)
+  (lookup-arithmetic-method operation fixnum-methods/2-args/register*constant))
+
+(define fixnum-methods/2-args/register*constant
+  (list 'FIXNUM-METHODS/2-ARGS/REGISTER*CONSTANT))
+
+(define-arithmetic-method 'PLUS-FIXNUM fixnum-methods/2-args/register*constant
+  (lambda (tgt src constant overflow?)
+    (guarantee-signed-fixnum constant)
+    (let ((value (* constant fixnum-1)))
+      (if overflow?
+         (cond ((zero? constant)
+                (LAP (SKIP (TR))))
+               ((fits-in-11-bits-signed? value)
+                (LAP (ADDI (NSV) ,value ,src ,tgt)))
+               (else
+                (let ((temp (standard-temporary!)))
+                  (LAP ,@(load-fixnum-constant constant temp)
+                       (ADD (NSV) ,src ,temp ,tgt)))))
+         (load-offset value src tgt)))))
+
+(define-arithmetic-method 'MINUS-FIXNUM fixnum-methods/2-args/register*constant
+  (lambda (tgt src constant overflow?)
+    (guarantee-signed-fixnum constant)
+    (let ((value (- (* constant fixnum-1))))
+      (if overflow?
+         (cond ((zero? constant)
+                (LAP (SKIP (TR))))
+               ((fits-in-11-bits-signed? value)
+                (LAP (ADDI (NSV) ,value ,src ,tgt)))
+               (else
+                (let ((temp (standard-temporary!)))
+                  (LAP ,@(load-fixnum-constant constant temp)
+                       (SUB (NSV) ,src ,temp ,tgt)))))
+         (load-offset value src tgt)))))
+
+(define (fixnum-2-args/operator/constant*register operation)
+  (lookup-arithmetic-method operation fixnum-methods/2-args/constant*register))
+
+(define fixnum-methods/2-args/constant*register
+  (list 'FIXNUM-METHODS/2-ARGS/CONSTANT*REGISTER))
+
+(define-arithmetic-method 'MINUS-FIXNUM fixnum-methods/2-args/constant*register
+  (lambda (tgt constant src overflow?)
+    (guarantee-signed-fixnum constant)
+    (let ((value (* constant fixnum-1)))
+      (if (fits-in-11-bits-signed? value)
+         (if overflow?
+             (LAP (SUBI (NSV) ,value ,src ,tgt))
+             (LAP (SUBI () ,value ,src ,tgt)))
+         (let ((temp (standard-temporary!)))
+           (LAP ,@(load-fixnum-constant constant temp)
+                ,@(if overflow?
+                      (LAP (SUB (NSV) ,temp ,src ,tgt))
+                      (LAP (SUB () ,temp ,src ,tgt)))))))))
+
+(define (guarantee-signed-fixnum n)
+  (if (not (signed-fixnum? n)) (error "Not a signed fixnum" n))
+  n)
+
+(define (signed-fixnum? n)
+  (and (exact-integer? n)
+       (>= n signed-fixnum/lower-limit)
+       (< n signed-fixnum/upper-limit)))
+\f
+;;;; Predicates
+
+;;; This is a kludge.  It assumes that the last instruction of the
+;;; arithmetic operation that may cause an overflow condition will
+;;; skip the following instruction if there was no overflow.  Ie., the
+;;; last instruction will conditionally nullify using NSV.  The code
+;;; for the alternative is a real kludge because we can't force the
+;;; arithmetic instruction that precedes this code to use the inverted
+;;; condition.  Hopefully the peephole optimizer will fix this if it
+;;; is ever generated.  The linearizer attempts not to use this
+;;; branch.
+
+(define-rule predicate
+  (OVERFLOW-TEST)
+  (set-current-branches!
+   (lambda (label)
+     (LAP (B (N) (@PCR ,label))))
+   (lambda (label)
+     (LAP (SKIP (TR))
+         (B (N) (@PCR ,label)))))
+  (LAP))
+
+(define-rule predicate
+  (FIXNUM-PRED-1-ARG (? predicate) (REGISTER (? source)))
+  (compare (fixnum-pred-1->cc predicate)
+          (standard-source! source)
+          0))
+
+(define (fixnum-pred-1->cc predicate)
+  (case predicate
+    ((ZERO-FIXNUM?) '=)
+    ((NEGATIVE-FIXNUM?) '<)
+    ((POSITIVE-FIXNUM?) '>)
+    (else (error "unknown fixnum predicate" predicate))))
+\f
+(define-rule predicate
+  (FIXNUM-PRED-2-ARGS (? predicate)
+                     (REGISTER (? source1))
+                     (REGISTER (? source2)))
+  (compare (fixnum-pred-2->cc predicate)
+          (standard-source! source1)
+          (standard-source! source2)))
+
+(define-rule predicate
+  (FIXNUM-PRED-2-ARGS (? predicate)
+                     (REGISTER (? source))
+                     (OBJECT->FIXNUM (CONSTANT (? constant))))
+  (compare-fixnum/constant*register (invert-condition-noncommutative
+                                    (fixnum-pred-2->cc predicate))
+                                   constant
+                                   (standard-source! source)))
+
+(define-rule predicate
+  (FIXNUM-PRED-2-ARGS (? predicate)
+                     (OBJECT->FIXNUM (CONSTANT (? constant)))
+                     (REGISTER (? source)))
+  (compare-fixnum/constant*register (fixnum-pred-2->cc predicate)
+                                   constant
+                                   (standard-source! source)))
+
+(define-integrable (compare-fixnum/constant*register cc n r)
+  (guarantee-signed-fixnum n)
+  (compare-immediate cc (* n fixnum-1) r))
+
+(define (fixnum-pred-2->cc predicate)
+  (case predicate
+    ((EQUAL-FIXNUM?) '=)
+    ((LESS-THAN-FIXNUM?) '<)
+    ((GREATER-THAN-FIXNUM?) '>)
+    (else (error "unknown fixnum predicate" predicate))))
\ No newline at end of file
diff --git a/v7/src/compiler/machines/spectrum/rulflo.scm b/v7/src/compiler/machines/spectrum/rulflo.scm
new file mode 100644 (file)
index 0000000..90f09b0
--- /dev/null
@@ -0,0 +1,187 @@
+#| -*-Scheme-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/rulflo.scm,v 4.32 1990/01/25 16:45:49 jinx Rel $
+$MC68020-Header: rules1.scm,v 4.32 90/01/18 22:43:54 GMT cph Exp $
+
+Copyright (c) 1989, 1990 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science.  Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. |#
+
+;;;; LAP Generation Rules: Flonum rules
+
+(declare (usual-integrations))
+\f
+(define (flonum-source! register)
+  (float-register->fpr (load-alias-register! register 'FLOAT)))
+
+(define (flonum-target! pseudo-register)
+  (delete-dead-registers!)
+  (float-register->fpr (allocate-alias-register! pseudo-register 'FLOAT)))
+
+(define (flonum-temporary!)
+  (float-register->fpr (allocate-temporary-register! 'FLOAT)))
+
+(define-rule statement
+  ;; convert a floating-point number to a flonum object
+  (ASSIGN (REGISTER (? target))
+         (FLOAT->OBJECT (REGISTER (? source))))
+  (let ((source (flonum-source! source))
+       (temp (standard-temporary!)))
+    (let ((target (standard-target! target)))
+      (LAP ; (STW () 0 (OFFSET 0 0 21))        ; make heap parsable forwards
+          (DEPI () #b100 31 3 21)      ; quad align
+          (COPY () 21 ,target)
+          ,@(deposit-type (ucode-type flonum) target)
+          ,@(load-non-pointer (ucode-type manifest-nm-vector) 2 temp)
+          (STWM () ,temp (OFFSET 4 0 21))
+          (FSTDS (MA) ,source (OFFSET 8 0 21))))))
+
+(define-rule statement
+  ;; convert a flonum object address to a floating-point number
+  (ASSIGN (REGISTER (? target)) (@ADDRESS->FLOAT (REGISTER (? source))))
+  (let ((source (standard-source! source)))
+    (LAP (FLDDS () (OFFSET 4 0 ,source) ,(flonum-target! target)))))
+\f
+;;;; Flonum Arithmetic
+
+(define-rule statement
+  (ASSIGN (REGISTER (? target))
+         (FLONUM-1-ARG (? operation) (REGISTER (? source)) (? overflow?)))
+  overflow?                            ;ignore
+  (let ((source (flonum-source! source)))
+    ((flonum-1-arg/operator operation) (flonum-target! target) source)))
+
+(define (flonum-1-arg/operator operation)
+  (lookup-arithmetic-method operation flonum-methods/1-arg))
+
+(define flonum-methods/1-arg
+  (list 'FLONUM-METHODS/1-ARG))
+
+;;; Notice the weird ,', syntax here.
+;;; If LAP changes, this may also have to change.
+
+(let-syntax
+    ((define-flonum-operation
+       (macro (primitive-name opcode)
+        `(define-arithmetic-method ',primitive-name flonum-methods/1-arg
+           (lambda (target source)
+             (LAP (,opcode (DBL) ,',source ,',target)))))))
+  (define-flonum-operation flonum-abs FABS)
+  (define-flonum-operation flonum-sqrt FSQRT)
+  (define-flonum-operation flonum-round FRND))
+
+(define-arithmetic-method 'FLONUM-NEGATE flonum-methods/1-arg
+  (lambda (target source)
+    #|
+    ;; No zero on the floating-point co-processor.  Need to create one.
+    (let ((temp (if (= target source) (flonum-temporary!) target)))
+      (LAP (FSUB (DBL) ,temp ,temp ,temp)
+          (FSUB (DBL) ,temp ,source ,target)))
+    |#
+    ;; The status register (fr0) reads as 0 for non-store instructions.
+    (LAP (FSUB (DBL) 0 ,source ,target))))
+
+(define-rule statement
+  (ASSIGN (REGISTER (? target))
+         (FLONUM-2-ARGS (? operation)
+                        (REGISTER (? source1))
+                        (REGISTER (? source2))
+                        (? overflow?)))
+  overflow?                            ;ignore
+  (let ((source1 (flonum-source! source1))
+       (source2 (flonum-source! source2)))
+    ((flonum-2-args/operator operation) (flonum-target! target)
+                                       source1
+                                       source2)))
+
+(define (flonum-2-args/operator operation)
+  (lookup-arithmetic-method operation flonum-methods/2-args))
+
+(define flonum-methods/2-args
+  (list 'FLONUM-METHODS/2-ARGS))
+
+(let-syntax
+    ((define-flonum-operation
+       (macro (primitive-name opcode)
+        `(define-arithmetic-method ',primitive-name flonum-methods/2-args
+           (lambda (target source1 source2)
+             (LAP (,opcode (DBL) ,',source1 ,',source2 ,',target)))))))
+  (define-flonum-operation flonum-add fadd)
+  (define-flonum-operation flonum-subtract fsub)
+  (define-flonum-operation flonum-multiply fmpy)
+  (define-flonum-operation flonum-divide fdiv)
+  (define-flonum-operation flonum-remainder frem))
+\f
+;;;; Flonum Predicates
+
+(define-rule predicate
+  (FLONUM-PRED-1-ARG (? predicate) (REGISTER (? source)))
+  #|
+  ;; No immediate zeros, easy to generate by subtracting from itself
+  (let ((temp (flonum-temporary!)))
+    (LAP (FSUB (DBL) ,temp ,temp ,temp)
+        ,@(flonum-compare
+           (case predicate
+             ((FLONUM-ZERO?) '=)
+             ((FLONUM-NEGATIVE?) '<)
+             ((FLONUM-POSITIVE?) '>)
+             (else (error "unknown flonum predicate" predicate)))
+           (flonum-source! source)
+           temp)))
+  |#
+  ;; The status register (fr0) reads as 0 for non-store instructions.
+  (flonum-compare (case predicate
+                   ((FLONUM-ZERO?) '=)
+                   ((FLONUM-NEGATIVE?) '<)
+                   ((FLONUM-POSITIVE?) '>)
+                   (else (error "unknown flonum predicate" predicate)))
+                 (flonum-source! source)
+                 0))
+
+(define-rule predicate
+  (FLONUM-PRED-2-ARGS (? predicate)
+                     (REGISTER (? source1))
+                     (REGISTER (? source2)))
+  (flonum-compare (case predicate
+                   ((FLONUM-EQUAL?) '=)
+                   ((FLONUM-LESS?) '<)
+                   ((FLONUM-GREATER?) '>)
+                   (else (error "unknown flonum predicate" predicate)))
+                 (flonum-source! source1)
+                 (flonum-source! source2)))
+
+(define (flonum-compare cc r1 r2)
+  (set-current-branches!
+   (lambda (label)
+     (LAP (B (N) (@PCR ,label))))
+   (lambda (label)
+     (LAP (SKIP (TR))
+         (B (N) (@PCR ,label)))))
+  (LAP (FCMP (,(invert-condition cc) DBL) ,r1 ,r2)
+       (FTEST ())))
\ No newline at end of file