Change the representation of compiled procedures and other entries:
authorGuillermo J. Rozas <edu/mit/csail/zurich/gjr>
Mon, 14 Mar 1988 19:38:53 +0000 (19:38 +0000)
committerGuillermo J. Rozas <edu/mit/csail/zurich/gjr>
Mon, 14 Mar 1988 19:38:53 +0000 (19:38 +0000)
They are now just the address of an instruction with a gc offset
preceding the instruction and an arity/type word preceding that.
Compiled closures are done by creating a tiny fake compiled code block
which jumps to the right place and sets up the free variables for
reference.

Uuo style links are now just jump instructions to the correct address.
All relocators have been updated to reflect this change.

Variable caches have no type code. The relocators know about this.

Incorporate JRM's fix to signal to close interrupt gap in hp-ux.

New types:
TC_COMPILED_ENTRY
TC_MANIFEST_CLOSURE
TC_LINKAGE_SECTION

v7/src/compiler/machines/bobcat/machin.scm
v7/src/compiler/machines/bobcat/make.scm-68040
v7/src/compiler/machines/bobcat/rules1.scm
v7/src/compiler/machines/bobcat/rules3.scm

index 9742b3f8e8aec1e06b521bd3103343ff041b73fb..06bda7dd13ea46a36165a6e8047e249804518169 100644 (file)
@@ -1,6 +1,6 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/bobcat/machin.scm,v 4.2 1987/12/30 07:05:19 cph Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/bobcat/machin.scm,v 4.3 1988/03/14 19:38:06 jinx Exp $
 
 Copyright (c) 1987 Massachusetts Institute of Technology
 
@@ -41,6 +41,9 @@ MIT in each case. |#
 (define ic-block-first-parameter-offset
   2)
 
+(define closure-block-first-offset
+  2)
+
 (define (rtl:expression-cost expression)
   ;; Returns an estimate of the cost of evaluating the expression.
   ;; For simplicity, we try to estimate the actual number of cycles
index eab1b8d6c4e7c50d584758440818a31e4d498f13..01653c2589bad5aeb0cf76ef693c5af516a1c658 100644 (file)
@@ -1,6 +1,6 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/bobcat/make.scm-68040,v 4.6 1988/02/19 20:55:22 jinx Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/bobcat/make.scm-68040,v 4.7 1988/03/14 19:38:20 jinx Exp $
 
 Copyright (c) 1987 Massachusetts Institute of Technology
 
@@ -44,11 +44,11 @@ MIT in each case. |#
     (make-environment
       (define :name "Liar (Bobcat 68020)")
       (define :version 4)
-      (define :modification 6)
+      (define :modification 7)
       (define :files)
 
       (define :rcs-header
-       "$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/bobcat/make.scm-68040,v 4.6 1988/02/19 20:55:22 jinx Exp $")
+       "$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/bobcat/make.scm-68040,v 4.7 1988/03/14 19:38:20 jinx Exp $")
 
       (define :files-lists
        (list
index 352033eedadd43cc35e94a95606cf78c680da5c5..96d3edf045d0118341b1534efa1d2f9fc9268c90 100644 (file)
@@ -1,6 +1,6 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/bobcat/rules1.scm,v 4.3 1988/02/19 20:57:55 jinx Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/bobcat/rules1.scm,v 4.4 1988/03/14 19:38:35 jinx Exp $
 
 Copyright (c) 1987 Massachusetts Institute of Technology
 
@@ -112,14 +112,14 @@ MIT in each case. |#
   (QUALIFIER (pseudo-register? target))
   (LAP (MOV L
            (@PCR ,(free-reference-label name))
-           ,(reference-assignment-alias! target 'DATA))))
+           ,(reference-assignment-alias! target 'ADDRESS))))
 
 (define-rule statement
   (ASSIGN (REGISTER (? target)) (ASSIGNMENT-CACHE (? name)))
   (QUALIFIER (pseudo-register? target))
   (LAP (MOV L
            (@PCR ,(free-assignment-label name))
-           ,(reference-assignment-alias! target 'DATA))))
+           ,(reference-assignment-alias! target 'ADDRESS))))
 
 (define-rule statement
   (ASSIGN (REGISTER (? target)) (REGISTER (? source)))
@@ -175,6 +175,24 @@ MIT in each case. |#
               (MOV L ,reg:temp ,target*))
          (LAP (MOV L ,datum ,target*)
               (MOV B (& ,type) ,target*))))))
+
+(define-rule statement
+  (ASSIGN (REGISTER (? target))
+         (CONS-POINTER (CONSTANT (? type)) (ENTRY:PROCEDURE (? label))))
+  (QUALIFIER (pseudo-register? target))
+  (let ((temp (register-reference (allocate-temporary-register! 'ADDRESS))))
+    (delete-dead-registers!)
+    (let ((target* (coerce->any target)))
+      (if (register-effective-address? target*)
+         (LAP (LEA (@PCR ,(rtl-procedure/external-label (label->object label)))
+                   ,temp)
+              (MOV L ,temp ,reg:temp)
+              (MOV B (& ,type) ,reg:temp)
+              (MOV L ,reg:temp ,target*))
+         (LAP (LEA (@PCR ,(rtl-procedure/external-label (label->object label)))
+                   ,temp)
+              (MOV L ,temp ,target*)
+              (MOV B (& ,type) ,target*))))))
 \f
 ;;;; Transfers to Memory
 
@@ -209,6 +227,16 @@ MIT in each case. |#
     (LAP (MOV L ,(coerce->any r) ,target)
         (MOV B (& ,type) ,target))))
 
+(define-rule statement
+  (ASSIGN (OFFSET (REGISTER (? a)) (? n))
+         (CONS-POINTER (CONSTANT (? type)) (ENTRY:PROCEDURE (? label))))
+  (let* ((target (indirect-reference! a n))
+        (temp (register-reference (allocate-temporary-register! 'ADDRESS))))
+    (LAP (LEA (@PCR ,(rtl-procedure/external-label (label->object label)))
+             ,temp)
+        (MOV L ,temp ,target)
+        (MOV B (& ,type) ,target))))
+
 (define-rule statement
   (ASSIGN (OFFSET (REGISTER (? a0)) (? n0))
          (OFFSET (REGISTER (? a1)) (? n1)))
@@ -240,15 +268,6 @@ MIT in each case. |#
   (ASSIGN (POST-INCREMENT (REGISTER 13) 1) (OFFSET (REGISTER (? r)) (? n)))
   (LAP (MOV L ,(indirect-reference! r n) (@A+ 5))))
 
-(define-rule statement
-  (ASSIGN (POST-INCREMENT (REGISTER 13) 1) (ENTRY:PROCEDURE (? label)))
-  (let ((temporary
-        (register-reference (allocate-temporary-register! 'ADDRESS))))
-    (LAP (LEA (@PCR ,(rtl-procedure/external-label (label->object label)))
-             ,temporary)
-        (MOV L ,temporary (@A+ 5))
-        (MOV B (& ,(ucode-type compiled-expression)) (@AO 5 -4)))))
-
 ;; This pops the top of stack into the heap
 
 (define-rule statement
@@ -275,6 +294,12 @@ MIT in each case. |#
   (LAP (MOV L ,(coerce->any r) (@-A 7))
        (MOV B (& ,type) (@A 7))))
 
+(define-rule statement
+  (ASSIGN (PRE-INCREMENT (REGISTER 15) -1)
+         (CONS-POINTER (CONSTANT (? type)) (ENTRY:PROCEDURE (? label))))
+  (LAP (PEA (@PCR ,(rtl-procedure/external-label (label->object label))))
+       (MOV B (& ,type) (@A 7))))
+
 (define-rule statement
   (ASSIGN (PRE-INCREMENT (REGISTER 15) -1) (OFFSET (REGISTER (? r)) (? n)))
   (LAP (MOV L ,(indirect-reference! r n) (@-A 7))))
@@ -282,4 +307,4 @@ MIT in each case. |#
 (define-rule statement
   (ASSIGN (PRE-INCREMENT (REGISTER 15) -1) (ENTRY:CONTINUATION (? label)))
   (LAP (PEA (@PCR ,label))
-       (MOV B (& ,(ucode-type compiler-return-address)) (@A 7))))
\ No newline at end of file
+       (MOV B (& ,(ucode-type compiled-entry)) (@A 7))))
\ No newline at end of file
index b94267be8761b545de3289ebbc4a5ed4eaa5c2cd..932fe4b4406ca7e64ae8b0cc943682ea2e62156f 100644 (file)
@@ -1,6 +1,6 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/bobcat/rules3.scm,v 4.4 1988/02/19 20:58:21 jinx Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/bobcat/rules3.scm,v 4.5 1988/03/14 19:38:53 jinx Exp $
 
 Copyright (c) 1987 Massachusetts Institute of Technology
 
@@ -59,7 +59,18 @@ MIT in each case. |#
   (INVOCATION:LEXPR (? number-pushed) (? continuation) (? label))
   (LAP ,@(clear-map!)
        ,(load-dnw number-pushed 0)
-       (BRA (@PCR ,label))))
+       (LEA (@PCR ,label) (A 0))
+       (JMP ,entry:compiler-lexpr-apply)))
+
+(define-rule statement
+  (INVOCATION:UUO-LINK (? frame-size) (? continuation) (? name))
+  (LAP ,@(clear-map!)
+       ;; The following assumes that at label there is
+       ;;      (JMP (L <entry>))
+       ;; The other possibility would be
+       ;;       (JMP (@@PCR ,(free-uuo-link-label name frame-size)))
+       ;; and to have <entry> at label, but it is longer and slower.
+       (BRA (@PCR ,(free-uuo-link-label name frame-size)))))
 
 (define-rule statement
   (INVOCATION:CACHE-REFERENCE (? frame-size) (? continuation) (? extension))
@@ -80,19 +91,6 @@ MIT in each case. |#
         ,(load-constant name (INST-EA (D 5)))
         ,(load-dnw frame-size 0)
         (JMP ,entry:compiler-lookup-apply))))
-
-(define-rule statement
-  (INVOCATION:UUO-LINK (? frame-size) (? continuation) (? name))
-  (LAP ,@(clear-map!)
-       ,(load-dnw frame-size 0)
-       (MOV L (@PCR ,(free-uuo-link-label name)) (D 1))
-       (MOV L (D 1) (@-A 7))
-       (AND L (D 7) (D 1))
-       (MOV L (D 1) (A 1))
-       (MOV L (@A 1) (D 1))
-       (AND L (D 7) (D 1))
-       (MOV L (D 1) (A 0))
-       (JMP (@A 0))))
 \f
 (define-rule statement
   (INVOCATION:PRIMITIVE (? frame-size) (? continuation) (? primitive))
@@ -197,6 +195,30 @@ MIT in each case. |#
           (LABEL ,label)
           ,@(generate/move-frame-up* frame-size temp)))))
 
+(define (object->address*dynamic-link frame-size dreg)
+  (let ((label (generate-label))
+       (temp (allocate-temporary-register! 'ADDRESS)))
+    (let ((areg (register-reference temp)))
+      (LAP (AND L ,mask-reference ,dreg)
+          (MOV L ,dreg ,areg)
+          (CMP L ,areg (A 4))
+          (B HS B (@PCR ,label))
+          (MOV L (A 4) ,areg)
+          (LABEL ,label)
+          ,@(generate/move-frame-up* frame-size temp)))))
+
+(define-rule statement
+  (INVOCATION-PREFIX:DYNAMIC-LINK (? frame-size)
+                                 (OBJECT->ADDRESS (REGISTER (? source)))
+                                 (REGISTER 12))
+  (if (and (dead-register? source)
+          (register-has-alias? source 'DATA))
+      (object->address*dynamic-link frame-size
+       (register-reference (register-alias source 'DATA)))
+      (let ((temp (reference-temporary-register! 'DATA)))
+       (LAP (MOV L ,(coerce->any source) ,temp)
+            ,@(object->address*dynamic-link frame-size temp)))))
+
 (define (generate/move-frame-up frame-size destination)
   (let ((temp (allocate-temporary-register! 'ADDRESS)))
     (LAP (LEA ,destination ,(register-reference temp))
@@ -215,60 +237,45 @@ MIT in each case. |#
              (generator (allocate-temporary-register! 'DATA))))
         (MOV L ,(register-reference destination) (A 7)))))
 \f
-;;;; Entry Headers
+;;;; External Labels
 
-(define generate/quotation-header
-  ;; This is invoked by the top level of the LAP generator.
-  (let ((declare-constants
-        (lambda (constants code)
-          (define (inner constants)
-            (if (null? constants)
-                code
-                (let ((entry (car constants)))
-                  (LAP (SCHEME-OBJECT ,(cdr entry) ,(car entry))
-                       ,@(inner (cdr constants))))))
-          (inner constants)))
-       (declare-references
-        (lambda (references entry:single entry:multiple)
-          (if (null? references)
-              (LAP)
-              (LAP (LEA (@PCR ,(cdar references)) (A 1))
-                   ,@(if (null? (cdr references))
-                         (LAP (JSR ,entry:single))
-                         (LAP ,(load-dnw (length references) 1)
-                              (JSR ,entry:multiple)))
-                   ,@(make-external-label (generate-label)))))))
-    (lambda (block-label constants references assignments uuo-links)
-      (declare-constants uuo-links
-       (declare-constants references
-       (declare-constants assignments
-        (declare-constants constants
-         (let ((debugging-information-label (allocate-constant-label))
-               (environment-label (allocate-constant-label)))
-           (LAP
-            ;; Place holder for the debugging info filename
-            (SCHEME-OBJECT ,debugging-information-label DEBUGGING-INFO)
-            (SCHEME-OBJECT ,environment-label ENVIRONMENT)
-            (LEA (@PCR ,environment-label) (A 0))
-            ,@(if (and (null? references)
-                       (null? assignments)
-                       (null? uuo-links))
-                  (LAP ,(load-constant 0 '(@A 0)))
-                  (LAP (MOV L ,reg:environment (@A 0))
-                       (LEA (@PCR ,block-label) (A 0))
-                       ,@(declare-references
-                          references
-                          entry:compiler-cache-variable
-                          entry:compiler-cache-variable-multiple)
-                       ,@(declare-references
-                          assignments
-                          entry:compiler-cache-assignment
-                          entry:compiler-cache-assignment-multiple)
-                       ,@(declare-references
-                          uuo-links
-                          entry:compiler-uuo-link
-                          entry:compiler-uuo-link-multiple))))))))))))
+(define (make-external-label code label)
+  (set! compiler:external-labels 
+       (cons label compiler:external-labels))
+  (LAP (DC UW ,code)
+       (BLOCK-OFFSET ,label)
+       (LABEL ,label)))
+
+;;; Entry point types
+
+(define-integrable (make-code-word min max)
+  (+ (* #x100 min) max))
+
+(define (make-procedure-code-word min max)
+  (define (coerce val)
+    (cond ((and (not (negative? val))
+               (< val 128))
+          val)
+         ((and (negative? val)
+               (> val -128))
+          (+ 256 val))
+         (else
+          (error "make-procedure-code-word: Bad value" val))))
+  (make-code-word (coerce min) (coerce max)))
+
+(define expression-code-word
+  (make-code-word #xff #xff))
+
+(define internal-entry-code-word
+  (make-code-word #xff #xfe))
+
+;; This is the same until information is encoded in them
+
+(define continuation-code-word
+  (make-code-word #x80 #x80))
 \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.
@@ -277,78 +284,166 @@ MIT in each case. |#
 ;;; 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-rule statement
-  (PROCEDURE-HEAP-CHECK (? label))
+(define-integrable (simple-procedure-header code-word label
+                                           entry:compiler-interrupt)
   (let ((gc-label (generate-label)))
-    (LAP ,@(procedure-header (label->object label) gc-label)
+    (LAP (LABEL ,gc-label)
+        (JSR ,entry:compiler-interrupt)
+        ,@(make-external-label code-word label)
         (CMP L ,reg:compiled-memtop (A 5))
         (B GE B (@PCR ,gc-label)))))
 
-;;; Note: do not change the MOVE.W in the setup-lexpr call to a MOVEQ.
-;;; The setup-lexpr code assumes a fixed calling sequence to compute
-;;; the GC address if that is needed.  This could be changed so that
-;;; the microcode determined how far to back up based on the argument,
-;;; or by examining the calling sequence.
+(define-rule statement
+  (CONTINUATION-ENTRY (? internal-label))
+  (make-external-label continuation-code-word
+                      internal-label))
+
+(define-rule statement
+  (CONTINUATION-HEADER (? internal-label))
+  (simple-procedure-header continuation-code-word
+                          internal-label
+                          entry:compiler-interrupt-continuation))
 
 (define-rule statement
-  (SETUP-LEXPR (? label))
-  (let ((procedure (label->object label)))
-    (LAP ,@(procedure-header procedure false)
-        (MOV W
-             (& ,(+ (rtl-procedure/n-required procedure)
-                    (rtl-procedure/n-optional procedure)
-                    (if (rtl-procedure/closure? procedure) 1 0)))
-             (D 1))
-        (MOVEQ (& ,(if (rtl-procedure/rest? procedure) 1 0)) (D 2))
-        (JSR ,entry:compiler-setup-lexpr))))
+  (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
+                               entry:compiler-interrupt-ic-procedure)))))
 
 (define-rule statement
-  (CONTINUATION-HEAP-CHECK (? internal-label))
-  (let ((gc-label (generate-label)))
-    (LAP (LABEL ,gc-label)
-        (JSR ,entry:compiler-interrupt-continuation)
-        ,@(make-external-label internal-label)
-        (CMP L ,reg:compiled-memtop (A 5))
-        (B GE B (@PCR ,gc-label)))))
+  (OPEN-PROCEDURE-HEADER (? internal-label))
+  (simple-procedure-header internal-entry-code-word
+                          internal-label
+                          entry:compiler-interrupt-procedure))
 
 (define-rule statement
-  (CONTINUATION-ENTRY (? internal-label))
-  (LAP ,@(make-external-label internal-label)))
+  (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
+                                 entry:compiler-interrupt-procedure)))
 \f
-(define (procedure-header procedure gc-label)
-  (let ((internal-label (rtl-procedure/label procedure))
-       (external-label (rtl-procedure/external-label procedure)))
-    (LAP ,@(case (rtl-procedure/type procedure)
-            ((IC)
-             (LAP (ENTRY-POINT ,external-label)
-                  (EQUATE ,external-label ,internal-label)))
-            ((CLOSURE)
-             (let ((required (1+ (rtl-procedure/n-required procedure)))
-                   (optional (rtl-procedure/n-optional procedure)))
-               (LAP (ENTRY-POINT ,external-label)
-                    ,@(make-external-label external-label)
-                    ,(test-dnw required 0)
-                    ,@(cond ((rtl-procedure/rest? procedure)
-                             (LAP (B GE B (@PCR ,internal-label))))
-                            ((zero? optional)
-                             (LAP (B EQ B (@PCR ,internal-label))))
-                            (else
-                             (let ((wna-label (generate-label)))
-                               (LAP (B LT B (@PCR ,wna-label))
-                                    ,(test-dnw (+ required optional) 0)
-                                    (B LE B (@PCR ,internal-label))
-                                    (LABEL ,wna-label)))))
-                    (JMP ,entry:compiler-wrong-number-of-arguments))))
-            (else (LAP)))
-        ,@(if gc-label
-              (LAP (LABEL ,gc-label)
-                   (JSR ,entry:compiler-interrupt-procedure))
-              (LAP))
-        ,@(make-external-label internal-label))))
-
-(define (make-external-label label)
-  (set! compiler:external-labels 
-       (cons label compiler:external-labels))
-  (LAP (BLOCK-OFFSET ,label)
-       (LABEL ,label)))
\ No newline at end of file
+;;;; Closures.  These two statements are intertwined:
+
+(define magic-closure-constant
+  (- (* #x1000000 (ucode-type compiled-entry)) 6))
+
+(define-rule statement
+  (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)
+          (JMP ,entry:compiler-interrupt-closure)
+          ,@(make-external-label internal-entry-code-word external-label)
+          (ADD L (& ,magic-closure-constant) (@A 7))
+          (LABEL ,internal-label)
+          (CMP L ,reg:compiled-memtop (A 5))
+          (B GE B (@PCR ,gc-label))))))
+
+(define-rule statement
+  (CONS-CLOSURE (ENTRY:PROCEDURE (? internal-label)) (? min) (? max) (? size))
+  (let* ((temp (allocate-temporary-register! 'ADDRESS))
+        (temp-ref (register-reference temp)))
+    (LAP (LEA (@PCR ,(rtl-procedure/external-label
+                     (label->object internal-label)))
+             ,temp-ref)
+        ,(load-non-pointer (ucode-type manifest-closure) (+ 3 size)
+                           (INST-EA (@A+ 5)))
+        (MOVE L (& ,(+ (* (make-procedure-code-word min max) #x10000)
+                       #x8))
+              (@A+ 5))
+        (MOVE L (A 5) ,reg:enclose-result)
+        (MOVE B (& ,(ucode-type compiled-entry)) ,reg:enclose-result)
+        (MOVE W (& #x4eb9) (@A+ 5))                    ; (JSR (L <entry>))
+        (MOVE L ,temp-ref (@A+ 5))
+        (CLR W (@A+ 5))
+        ,@(increment-anl 5 size))))
+\f
+;;;; Entry Header
+;;; This is invoked by the top level of the LAP generator.
+
+(define generate/quotation-header
+  (let ((uuo-link-tag 0)
+       (reference-tag 1)
+       (assignment-tag 2))
+
+    (define (make-constant-block-tag tag datum)
+      (if (> datum #xffff)
+         (error "make-constant-block-tag: datum too large" datum)
+         (+ (* tag #x10000) datum)))
+
+    (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 `((,(make-constant-block-tag tag (length constants))
+                           . ,label)
+                          ,@constants))))
+         (cons (car info) (inner constants))))
+
+    (define (transmogrifly uuos)
+      (define (inner name assoc)
+       (if (null? assoc)
+           (transmogrifly (cdr uuos))
+           (cons (cons name (cdar assoc))              ; uuo-label
+                 (cons (cons (caar assoc)              ; frame-size
+                             (allocate-constant-label))
+                       (inner name (cdr assoc))))))
+      (if (null? uuos)
+         '()
+         (inner (caar uuos) (cdar uuos))))
+
+    (lambda (block-label constants references assignments uuo-links)
+      (let ((constant-info
+            (declare-constants uuo-link-tag (transmogrifly uuo-links)
+              (declare-constants reference-tag references
+                (declare-constants assignment-tag assignments
+                  (declare-constants #f constants
+                    (cons '() (LAP))))))))
+       (let ((free-ref-label (car constant-info))
+             (constants-code (cdr constant-info))
+             (debugging-information-label (allocate-constant-label))
+             (environment-label (allocate-constant-label)))
+         (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))
+              ,@(if (null? free-ref-label)
+                    (LAP)
+                    (LAP (LEA (@PCR ,environment-label) (A 0))
+                         (MOV L ,reg:environment (@A 0))
+                         (LEA (@PCR ,block-label) (A 0))
+                         (LEA (@PCR ,free-ref-label) (A 1))
+                         ,(load-dnw (+ (if (null? uuo-links) 0 1)
+                                       (if (null? references) 0 1)
+                                       (if (null? assignments) 0 1))
+                                    0)
+                         (JSR ,entry:compiler-link)
+                         ,@(make-external-label continuation-code-word
+                                                (generate-label))))))))))
+\f
+;;; Local Variables: ***
+;;; eval: (put 'declare-constants 'scheme-indent-hook 2) ***
+;;; End: ***