Update to version match 68k compiler version 4.74.
authorGuillermo J. Rozas <edu/mit/csail/zurich/gjr>
Sun, 22 Jul 1990 18:56:39 +0000 (18:56 +0000)
committerGuillermo J. Rozas <edu/mit/csail/zurich/gjr>
Sun, 22 Jul 1990 18:56:39 +0000 (18:56 +0000)
Multi closures.
Bit-wise fixnum operations.
Add out-of-line multiply and divide (quotient and remainder) routines
that use the floating-point co-processor.

v7/src/compiler/machines/spectrum/compiler.pkg
v7/src/compiler/machines/spectrum/decls.scm
v7/src/compiler/machines/spectrum/lapgen.scm
v7/src/compiler/machines/spectrum/machin.scm
v7/src/compiler/machines/spectrum/make.scm
v7/src/compiler/machines/spectrum/rules1.scm
v7/src/compiler/machines/spectrum/rules3.scm
v7/src/compiler/machines/spectrum/rulfix.scm
v7/src/compiler/machines/spectrum/rulrew.scm

index 5ab6a796fee8e9e50dcc12821f93f6686a609656..b7ae446bd8c21651a61c82254aa4c02a680f5906 100644 (file)
@@ -1,7 +1,7 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/compiler.pkg,v 1.28 1990/03/26 23:46:08 jinx Exp $
-$MC68020-Header: comp.pkg,v 1.27 90/01/22 23:45:02 GMT cph Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/compiler.pkg,v 1.30 1990/07/22 18:49:57 jinx Rel $
+$MC68020-Header: comp.pkg,v 1.30 90/05/03 15:16:59 GMT jinx Exp $
 
 Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
 
@@ -99,7 +99,8 @@ MIT in each case. |#
          compiler:show-phases?
          compiler:show-procedures?
          compiler:show-subphases?
-         compiler:show-time-reports?))
+         compiler:show-time-reports?
+         compiler:use-multiclosures?))
 \f
 (define-package (compiler reference-contexts)
   (files "base/refctx")
@@ -397,7 +398,9 @@ MIT in each case. |#
   (parent (compiler fg-optimizer))
   (export (compiler top-level)
          setup-block-types!
-         setup-closure-contexts!))
+         setup-closure-contexts!)
+  (export (compiler)
+         indirection-block-procedure))
 
 (define-package (compiler fg-optimizer simplicity-analysis)
   (files "fgopt/simple")
@@ -483,9 +486,13 @@ MIT in each case. |#
   (export (compiler rtl-generator)
          generate/rvalue
          load-closure-environment
+         make-cons-closure-indirection
+         make-cons-closure-redirection
+         make-closure-redirection
          make-ic-cons
          make-non-trivial-closure-cons
-         make-trivial-closure-cons))
+         make-trivial-closure-cons
+         redirect-closure))
 
 (define-package (compiler rtl-generator generate/combination)
   (files "rtlgen/rgcomb")
index b0104e2982b3015523ae9414f38369543d515c50..34411a3fbb76e85c0e94bb181b4cf9ee560fbe53 100644 (file)
@@ -1,7 +1,7 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/decls.scm,v 4.26 1990/03/26 23:36:42 jinx Exp $
-$MC68020-Header: decls.scm,v 4.26 90/02/02 18:39:26 GMT cph Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/decls.scm,v 4.27 1990/07/22 18:53:17 jinx Rel $
+$MC68020-Header: decls.scm,v 4.27 90/05/03 15:17:08 GMT jinx Exp $
 
 Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
 
@@ -384,40 +384,44 @@ MIT in each case. |#
                         (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"
-                         "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"))))
+  (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"
+                          "rgraph" "rtlcfg" "rtlobj" "rtlreg" "rtlty1"
+                          "rtlty2"))
+        (cse-base
+         (filename/append "rtlopt"
+                          "rcse1" "rcseht" "rcserq" "rcsesr"))
+        (cse-all
+         (append (filename/append "rtlopt"
+                                  "rcse2" "rcseep")
+                 cse-base))
+        (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)
@@ -509,13 +513,13 @@ MIT in each case. |#
      (append spectrum-base front-end-base rtl-base))
 
     (file-dependency/integration/join
-     (append cse-base
+     (append cse-all
             (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)
+    (file-dependency/integration/join cse-all cse-base)
 
     (file-dependency/integration/join
      (filename/append "rtlopt" "ralloc" "rcompr" "rdebug" "rlife")
index f62893d3a6e4978fc99ac3c82eb4b71ea04553d1..49824c5a103166356a6d4f7474b2f557831c00df 100644 (file)
@@ -1,7 +1,7 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/lapgen.scm,v 4.30 1990/04/09 20:35:44 cph Exp $
-$MC68020-Header: lapgen.scm,v 4.31 90/04/01 22:26:01 GMT jinx Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/lapgen.scm,v 4.35 1990/07/22 18:53:55 jinx Rel $
+$MC68020-Header: lapgen.scm,v 4.35 90/07/20 15:53:40 GMT jinx Exp $
 
 Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
 
@@ -34,6 +34,7 @@ promotional, or sales literature without prior written consent from
 MIT in each case. |#
 
 ;;;; RTL Rules for HPPA.  Shared utilities.
+;;; package: (compiler lap-syntaxer)
 
 (declare (usual-integrations))
 \f
@@ -407,6 +408,7 @@ MIT in each case. |#
     (conversion source (standard-target! target))))
 
 (define (standard-binary-conversion source1 source2 target conversion)
+  ;; The sources are any register, `target' a pseudo register.
   (let ((source1 (standard-source! source1))
        (source2 (standard-source! source2)))
     (conversion source1 source2 (standard-target! target))))
@@ -457,6 +459,9 @@ MIT in each case. |#
   (cdr (or (assq operator (cdr methods))
           (error "Unknown operator" operator))))
 
+(define-integrable (arithmetic-method? operator methods)
+  (assq operator (cdr methods)))  
+
 (define (fits-in-5-bits-signed? value)
   (<= #x-10 value #xF))
 
@@ -553,7 +558,17 @@ MIT in each case. |#
                             (loop (cdr names) (+ 8 index)))))
                 `(BEGIN ,@(loop names start)))))
   (define-hooks 100
-    store-closure-code))
+    store-closure-code
+    store-closure-entry                        ; newer version of store-closure-code.
+    multiply-fixnum
+    fixnum-quotient
+    fixnum-remainder
+    fixnum-lsh))
+
+(define (require-registers! . regs)
+  (let ((code (apply clear-registers! regs)))
+    (need-registers! regs)
+    code))
 
 (define (load-interface-args! first second third fourth)
   (let ((clear-regs
index 3417b697a86182f2b1c226f892d696189a909a75..d160003af8910c3dc0538f936bbd33f28c8cdf4c 100644 (file)
@@ -1,7 +1,7 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/machin.scm,v 4.21 1990/04/02 15:29:23 jinx Exp $
-$MC68020-Header: machin.scm,v 4.21 90/04/01 22:28:28 GMT jinx Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/machin.scm,v 4.22 1990/07/22 18:54:22 jinx Rel $
+$MC68020-Header: machin.scm,v 4.22 90/05/03 15:17:20 GMT jinx Exp $
 
 Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
 
@@ -34,6 +34,7 @@ promotional, or sales literature without prior written consent from
 MIT in each case. |#
 
 ;;; Machine Model for Spectrum
+;;; package: (compiler)
 
 (declare (usual-integrations))
 \f
@@ -84,7 +85,68 @@ MIT in each case. |#
 
 (define-integrable (stack->memory-offset offset) offset)
 (define-integrable ic-block-first-parameter-offset 2)
-(define-integrable closure-block-first-offset 3)
+(define-integrable execute-cache-size 3) ; Long words per UUO link slot
+\f
+;;;; Closures and multi-closures
+
+;; On the 68k, to save space, entries can be at 2 mod 4 addresses,
+;; which makes it impossible to use an arbitrary closure entry-point
+;; to reference closed-over variables since the compiler only uses
+;; long-word offsets.  Instead, all closure entry points are bumped
+;; back to the first entry point, which is always long-word aligned.
+
+;; On the HP-PA, and all other RISCs, all the entry points are
+;; long-word aligned, so there is no need to bump back to the first
+;; entry point.
+
+(define-integrable closure-entry-size
+  #|
+     Long words in a single closure entry:
+       GC offset word
+       LDIL    L'target,26
+       BLE     R'target(5,26)
+       ADDI    -12,31,31
+   |#
+  4)
+
+;; Given: the number of entry points in a closure, and a particular
+;; entry point number, compute the distance from that entry point to
+;; the first variable slot in the closure object (in long words).
+
+(define (closure-first-offset nentries entry)
+  (if (zero? nentries)
+      1                                        ; Strange boundary case
+      (- (* closure-entry-size (- nentries entry)) 1)))
+
+;; Like the above, but from the start of the complete closure object,
+;; viewed as a vector, and including the header word.
+
+(define (closure-object-first-offset nentries)
+  (case nentries
+    ((0)
+     ;; Vector header only
+     1)
+    ((1)
+     ;; Manifest closure header followed by single entry point
+     (+ 1 closure-entry-size))
+    (else
+     ;; Manifest closure header, number of entries, then entries.
+     (+ 1 1 (* closure-entry-size nentries)))))
+
+;; Bump distance in bytes from one entry point to another.
+;; Used for invocation purposes.
+
+(define (closure-entry-distance nentries entry entry*)
+  nentries                             ; ignored
+  (* (* closure-entry-size 4) (- entry* entry)))
+
+;; Bump distance in bytes from one entry point to the entry point used
+;; for variable-reference purposes.
+;; On a RISC, this is the entry point itself.
+
+(define (closure-environment-adjustment nentries entry)
+  nentries entry                       ; ignored
+  0)
 \f
 ;;;; Machine Registers
 
@@ -328,8 +390,7 @@ MIT in each case. |#
   true)
 
 (define compiler:primitives-with-no-open-coding
-  '(MULTIPLY-FIXNUM INTEGER-MULTIPLY &*
-    DIVIDE-FIXNUM GCD-FIXNUM FIXNUM-QUOTIENT FIXNUM-REMAINDER
+  '(INTEGER-MULTIPLY DIVIDE-FIXNUM GCD-FIXNUM
     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
index 09517242b654b285956ded5dc4a0bc6af366f97d..14a54cd4a7c1f10d83bb4f44001a63d94b3e1e13 100644 (file)
@@ -1,7 +1,7 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/make.scm,v 4.72 1990/04/03 06:17:26 jinx Exp $
-$MC68020-Header: make.scm,v 4.72 90/04/03 04:50:08 GMT jinx Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/make.scm,v 4.74 1990/07/22 18:54:44 jinx Exp $
+$MC68020-Header: make.scm,v 4.74 90/06/26 22:07:13 GMT jinx Exp $
 
 Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
 
@@ -42,4 +42,4 @@ MIT in each case. |#
            ((package/reference (find-package name) 'INITIALIZE-PACKAGE!)))
          '((COMPILER MACROS)
            (COMPILER DECLARATIONS)))
-(add-system! (make-system "Liar (HP PA)" 4 72 '()))
\ No newline at end of file
+(add-system! (make-system "Liar (HP PA)" 4 74 '()))
\ No newline at end of file
index 12ac64ec2b9c907d5a1766813955c2942c106fd5..4a5e887afe5f12ed1a543d31b8e1c28025c00da9 100644 (file)
@@ -1,7 +1,7 @@
 #| -*-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 $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/rules1.scm,v 4.33 1990/07/22 18:55:17 jinx Rel $
+$MC68020-Header: rules1.scm,v 4.33 90/05/03 15:17:28 GMT jinx Exp $
 
 Copyright (c) 1989, 1990 Massachusetts Institute of Technology
 
@@ -34,6 +34,7 @@ promotional, or sales literature without prior written consent from
 MIT in each case. |#
 
 ;;;; LAP Generation Rules: Data Transfers
+;;; package: (compiler lap-syntaxer)
 
 (declare (usual-integrations))
 \f
@@ -63,7 +64,8 @@ MIT in each case. |#
   ;; tag the contents of a register
   (ASSIGN (REGISTER (? target))
          (CONS-POINTER (MACHINE-CONSTANT (? type)) (REGISTER (? source))))
-  (QUALIFIER (fits-in-5-bits-signed? type))
+  ;; *** Why doesn't it work when qualifier is used? ***
+  ;; (QUALIFIER (fits-in-5-bits-signed? type))
   (deposit-type type (standard-move-to-target! source target)))
 
 (define-rule statement
@@ -82,13 +84,21 @@ MIT in each case. |#
   (object->address (standard-move-to-target! source target)))
 
 (define-rule statement
-  ;; add a constant to a register's contents
+  ;; add a constant offset (in long words) 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
+  ;; add a constant offset (in bytes) to a register's contents
+  (ASSIGN (REGISTER (? target))
+         (BYTE-OFFSET-ADDRESS (REGISTER (? source)) (? offset)))
+  (standard-unary-conversion source target
+    (lambda (source target)
+      (load-offset offset source target))))
+
 (define-rule statement
   ;; read an object from memory
   (ASSIGN (REGISTER (? target)) (OFFSET (REGISTER (? address)) (? offset)))
index 9e06cfe745f710a614a2b086ebe0f61a70dfad72..16f632e45fa053d6de6773c64685e5b1a4900264 100644 (file)
@@ -1,7 +1,7 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/rules3.scm,v 4.24 1990/04/09 21:07:36 cph Exp $
-$MC68020-Header: rules3.scm,v 4.23 90/01/18 22:44:09 GMT cph Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/rules3.scm,v 4.25 1990/07/22 18:55:38 jinx Exp $
+$MC68020-Header: rules3.scm,v 4.24 90/05/03 15:17:33 GMT jinx Exp $
 
 Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
 
@@ -34,6 +34,7 @@ promotional, or sales literature without prior written consent from
 MIT in each case. |#
 
 ;;;; LAP Generation Rules: Invocations and Entries
+;;; package: (compiler lap-syntaxer)
 
 (declare (usual-integrations))
 \f
@@ -417,75 +418,143 @@ MIT in each case. |#
 \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.
+  ;; 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))
+  (CLOSURE-HEADER (? internal-label) (? nentries) (? entry))
+  entry                                ; Used only if entries may not be word-aligned.
+  (if (zero? nentries)
+      (error "Closure header for closure with no entries!"
+            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)
+          ;; This code must match the code and count in microcode/cmpint2.h
           (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-CLOSURE (ENTRY:PROCEDURE (? procedure-label))
+                       (? min) (? max) (? size)))
+  (cons-closure target procedure-label min max size))
 
 (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))
+         (CONS-MULTICLOSURE (? nentries) (? size) (? entries)))
+  ;; entries is a vector of all the entry points
+  (case nentries
+    ((0)
+     (let ((dest (standard-target! target)))
+       (LAP ,@(load-non-pointer (ucode-type manifest-vector)
+                               (+ 4 size)
+                               dest)
+           (STWM () ,dest (OFFSET 4 0 ,regnum:free-pointer))
+           ,@(load-offset -4 regnum:free-pointer dest))))
+    ((1)
+     (let ((entry (vector-ref entries 0)))
+       (cons-closure
+       target (car entry) (cadr entry) (caddr entry) size)))
+    (else
+     (cons-multiclosure target nentries size (vector->list entries)))))
+\f
+(define (cons-closure target entry min max size)
+  (let* ((flush-reg (require-registers! regnum:first-arg
+                                       #| regnum:addil-result |#
+                                       regnum:ble-return))
+        (target (standard-target! target)))
+    (LAP ,@flush-reg
+        ;; Vector header
+        ,@(load-non-pointer (ucode-type manifest-closure)
+                            (+ size closure-entry-size)
+                            regnum:first-arg)
+        (STWM () ,regnum:first-arg (OFFSET 4 0 ,regnum:free-pointer))
+        ;; Entry point is result.
+        ,@(load-offset 4 regnum:free-pointer target)
+        ,@(cons-closure-entry entry min max 8)
+        ;; Allocate space for closed-over variables
+        ,@(load-offset (* 4 size)
+                       regnum:free-pointer
+                       regnum:free-pointer))))
+
+(define (cons-multiclosure target nentries size entries)
+  (let* ((flush-reg (require-registers! regnum:first-arg
+                                       #| regnum:addil-result |#
+                                       regnum:ble-return))
+        (target (standard-target! target)))
+    (define (generate-entries offset entries)
+      (if (null? entries)
+         (LAP)
+         (let ((entry (car entries)))
+           (LAP ,@(cons-closure-entry (car entry) (cadr entry) (caddr entry)
+                                      offset)
+                ,@(generate-entries (+ offset (* 4 closure-entry-size))
+                                    (cdr entries))))))
+
+    (LAP ,@flush-reg
+        ;; Vector header
+        ,@(load-non-pointer (ucode-type manifest-closure)
+                            (+ 1 (* closure-entry-size nentries) size)
+                            regnum:first-arg)
+        (STWM () ,regnum:first-arg (offset 4 0 ,regnum:free-pointer))
+        ;; Number of closure entries
+        ,@(load-entry-format nentries 0 target)
+        (STWM () ,target (offset 4 0 ,regnum:free-pointer))
+        ;; First entry point is result.
+        ,@(load-offset 4 21 target)
+        ,@(generate-entries 12 entries)
+        ;; Allocate space for closed-over variables
+        ,@(load-offset (* 4 size)
+                       regnum:free-pointer
+                       regnum:free-pointer))))
+\f
+;; 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 "HPPA RTL rules3: 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 (load-entry-format code-word gc-offset dest)
+  (load-immediate (+ (* code-word #x10000)
+                    (quotient gc-offset 2))
+                 dest))
+
+(define (cons-closure-entry entry min max offset)
+  ;; Call an out-of-line hook to do this.
+  ;; Making the instructions is a lot of work!
+  ;; Perhaps there should be a closure hook invoked and the real
+  ;; entry point could follow.  It would also be easier on the GC.
+  (let ((entry-label (rtl-procedure/external-label (label->object entry))))
+    (LAP ,@(load-entry-format (make-procedure-code-word min max)
+                             offset
+                             regnum:first-arg)
+        (BLE ()
+             (OFFSET ,hook:compiler-store-closure-entry
+                     4
+                     ,regnum:scheme-to-interface-ble))
+        (LDO ()
+             (OFFSET (- ,entry-label (+ *PC* 4))
+                     0
+                     ,regnum:ble-return)
+             ,regnum:addil-result))))
 \f
 ;;;; Entry Header
 ;;; This is invoked by the top level of the LAP generator.
index 484af79f43c3d602e752be92b0042f8afa397c35..a74a6062c4de5bbedf9d27bcb771547ece294c26 100644 (file)
@@ -1,7 +1,8 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/rulfix.scm,v 4.34 1990/04/02 15:30:02 jinx Exp $
-$MC68020-Header: rules1.scm,v 4.32 90/01/18 22:43:54 GMT cph Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/rulfix.scm,v 4.35 1990/07/22 18:56:13 jinx Exp $
+$MC68020-Header: rules1.scm,v 4.33 90/05/03 15:17:28 GMT jinx Exp $
+$MC68020-Header: lapgen.scm,v 4.35 90/07/20 15:53:40 GMT jinx Exp $
 
 Copyright (c) 1989, 1990 Massachusetts Institute of Technology
 
@@ -34,6 +35,7 @@ promotional, or sales literature without prior written consent from
 MIT in each case. |#
 
 ;;;; LAP Generation Rules: Fixnum Rules
+;;; package: (compiler lap-syntaxer)
 
 (declare (usual-integrations))
 \f
@@ -85,6 +87,9 @@ MIT in each case. |#
                         (OBJECT->FIXNUM (CONSTANT 4))
                         #F))
   (standard-unary-conversion source target object->index-fixnum))
+\f
+#|
+;; Superseded by code below
 
 ;; This is a patch for the time being.  Probably only one of these pairs
 ;; of rules is needed.
@@ -104,6 +109,7 @@ MIT in each case. |#
                         (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)))
@@ -139,28 +145,20 @@ MIT in each case. |#
          (FIXNUM-1-ARG (? operation)
                        (REGISTER (? source))
                        (? overflow?)))
+  (QUALIFIER (fixnum-1-arg/operator? operation))
   (standard-unary-conversion source target
     (lambda (source target)
       ((fixnum-1-arg/operator operation) target source overflow?))))
 
-(define (fixnum-1-arg/operator operation)
+(define-integrable (fixnum-1-arg/operator operation)
   (lookup-arithmetic-method operation fixnum-methods/1-arg))
 
+(define-integrable (fixnum-1-arg/operator? operation)
+  (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))
@@ -168,28 +166,127 @@ MIT in each case. |#
                         (REGISTER (? source1))
                         (REGISTER (? source2))
                         (? overflow?)))
+  (QUALIFIER (fixnum-2-args/operator? operation))
   (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)
+(define-integrable (fixnum-2-args/operator operation)
   (lookup-arithmetic-method operation fixnum-methods/2-args))
 
+(define-integrable (fixnum-2-args/operator? operation)
+  (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)))))
+;; Some operations are too long to do in-line.
+;; Use out-of-line utilities.
+
+(define-rule statement
+  (ASSIGN (REGISTER (? target))
+         (FIXNUM-2-ARGS (? operation)
+                        (REGISTER (? source1))
+                        (REGISTER (? source2))
+                        (? overflow?)))
+  (QUALIFIER (fixnum-2-args/special-operator? operation))
+  (special-binary-operation
+   operation
+   (fixnum-2-args/special-operator operation)
+   target source1 source2 overflow?))
+
+(define-integrable (fixnum-2-args/special-operator operation)
+  (lookup-arithmetic-method operation fixnum-methods/2-args/special))
+
+(define-integrable (fixnum-2-args/special-operator? operation)
+  (arithmetic-method? operation fixnum-methods/2-args/special))
+
+(define fixnum-methods/2-args/special
+  (list 'FIXNUM-METHODS/2-ARGS/SPECIAL))
+\f
+;; Note: Bit-wise operations never overflow, therefore they always
+;; skip the branch (cond = TR).  Perhaps they should error?
+
+;; Note: The commas in the macros do not follow normal QUASIQUOTE patterns.
+;; This is due to a bad interaction between QUASIQUOTE and LAP!
+
+(let-syntax
+    ((unary-fixnum
+      (macro (name instr nsv fixed-operand)
+       `(define-arithmetic-method ',name fixnum-methods/1-arg
+          (lambda (tgt src overflow?)
+            (if overflow?
+                (LAP (,instr (,nsv) ,fixed-operand ,',src ,',tgt))
+                (LAP (,instr () ,fixed-operand ,',src ,',tgt)))))))
+
+     (binary-fixnum
+      (macro (name instr nsv)
+       `(define-arithmetic-method ',name fixnum-methods/2-args
+          (lambda (tgt src1 src2 overflow?)
+            (if overflow?
+                (LAP (,instr (,nsv) ,',src1 ,',src2 ,',tgt))
+                (LAP (,instr () ,',src1 ,',src2 ,',tgt)))))))
+
+     (binary-out-of-line
+      (macro (name . regs)
+       `(define-arithmetic-method ',name fixnum-methods/2-args/special
+          (cons ,(symbol-append 'HOOK:COMPILER- name)
+                (lambda ()
+                  ,(if (null? regs)
+                       `(LAP)
+                       `(require-registers! ,@regs))))))))
+
+  (unary-fixnum ONE-PLUS-FIXNUM ADDI NSV ,fixnum-1)
+  (unary-fixnum MINUS-ONE-PLUS-FIXNUM ADDI NSV ,(- fixnum-1))
+  (unary-fixnum FIXNUM-NOT SUBI TR ,(- fixnum-1))
+
+  (binary-fixnum PLUS-FIXNUM ADD NSV)
+  (binary-fixnum MINUS-FIXNUM SUB NSV)
+  (binary-fixnum FIXNUM-AND AND TR)
+  (binary-fixnum FIXNUM-ANDC ANDCM TR)
+  (binary-fixnum FIXNUM-OR OR TR)
+  (binary-fixnum FIXNUM-XOR XOR TR)
+
+  (binary-out-of-line MULTIPLY-FIXNUM fp4 fp5)
+  (binary-out-of-line FIXNUM-QUOTIENT fp4 fp5)
+  (binary-out-of-line FIXNUM-REMAINDER fp4 fp5 regnum:addil-result)
+  (binary-out-of-line FIXNUM-LSH))
 \f
+;;; Out of line calls.
+
+;; Arguments are passed in regnum:first-arg and regnum:second-arg.
+;; Result is returned in regnum:first-arg, and a boolean is returned
+;; in regnum:second-arg indicating wheter there was overflow.
+
+(define (special-binary-operation operation hook target source1 source2 ovflw?)
+  (define (->machine-register source machine-reg)
+    (let ((code (load-machine-register! source machine-reg)))
+      ;; Prevent it from being allocated again.
+      (need-register! machine-reg)
+      code))
+
+  (if (not (pair? hook))
+      (error "special-binary-operation: Unknown operation" operation))
+
+  (let* ((extra ((cdr hook)))
+        (load-1 (->machine-register source1 regnum:first-arg))               
+        (load-2 (->machine-register source2 regnum:second-arg)))
+    ;; Make regnum:first-arg the only alias for target
+    (delete-register! target)
+    (add-pseudo-register-alias! target regnum:first-arg)
+    (LAP ,@extra
+        ,@load-1
+        ,@load-2
+        ;; Hopefully a peep-hole optimizer will switch this instruction
+        ;; and the preceding one, and remove the nop.
+        (BLE () (OFFSET ,(car hook) 4 ,regnum:scheme-to-interface-ble))
+        (NOP ())
+        ,@(if (not ovflw?)
+              (LAP)
+              (LAP (COMICLR (=) 0 ,regnum:second-arg 0))))))
+
+;;; Binary operations with one argument constant.
+
 (define-rule statement
   ;; execute binary fixnum operation with constant second arg
   (ASSIGN (REGISTER (? target))
@@ -197,6 +294,8 @@ MIT in each case. |#
                         (REGISTER (? source))
                         (OBJECT->FIXNUM (CONSTANT (? constant)))
                         (? overflow?)))
+  (QUALIFIER
+   (fixnum-2-args/operator/register*constant? operation constant overflow?))
   (standard-unary-conversion source target
     (lambda (source target)
       ((fixnum-2-args/operator/register*constant operation)
@@ -209,6 +308,8 @@ MIT in each case. |#
                         (OBJECT->FIXNUM (CONSTANT (? constant)))
                         (REGISTER (? source))
                         (? overflow?)))
+  (QUALIFIER
+   (fixnum-2-args/operator/constant*register? operation constant overflow?))
   (standard-unary-conversion source target
     (lambda (source target)
       (if (fixnum-2-args/commutative? operation)
@@ -217,16 +318,59 @@ MIT in each case. |#
          ((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 (define-arithconst-method name table qualifier code-gen)
+  (define-arithmetic-method name table
+    (cons code-gen qualifier)))
 
-(define (fixnum-2-args/operator/register*constant operation)
-  (lookup-arithmetic-method operation fixnum-methods/2-args/register*constant))
+(define (fixnum-2-args/commutative? operator)
+  (memq operator '(PLUS-FIXNUM
+                  MULTIPLY-FIXNUM
+                  FIXNUM-AND
+                  FIXNUM-OR
+                  FIXNUM-XOR)))
+
+(define-integrable (fixnum-2-args/operator/register*constant operation)
+  (car (lookup-arithmetic-method operation
+                                fixnum-methods/2-args/register*constant)))
+
+(define (fixnum-2-args/operator/register*constant? operation constant ovflw?)
+  (let ((handler (arithmetic-method? operation
+                                    fixnum-methods/2-args/register*constant)))
+    (and handler
+        ((cddr handler) constant ovflw?))))
 
 (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
+(define-integrable (fixnum-2-args/operator/constant*register operation)
+  (car (lookup-arithmetic-method operation
+                                fixnum-methods/2-args/constant*register)))
+
+(define (fixnum-2-args/operator/constant*register? operation constant ovflw?)
+  (let ((handler (arithmetic-method? operation
+                                    fixnum-methods/2-args/constant*register)))
+    (or (and handler
+            ((cddr handler) constant ovflw?))
+       (and (fixnum-2-args/commutative? operation)
+            (fixnum-2-args/operator/register*constant? operation
+                                                       constant ovflw?)))))
+
+(define fixnum-methods/2-args/constant*register
+  (list 'FIXNUM-METHODS/2-ARGS/CONSTANT*REGISTER))
+
+(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
+(define-arithconst-method 'PLUS-FIXNUM fixnum-methods/2-args/register*constant
+  (lambda (constant ovflw?)
+    ovflw?                                     ; ignored
+    (fits-in-11-bits-signed? (* constant fixnum-1)))
   (lambda (tgt src constant overflow?)
     (guarantee-signed-fixnum constant)
     (let ((value (* constant fixnum-1)))
@@ -241,7 +385,10 @@ MIT in each case. |#
                        (ADD (NSV) ,src ,temp ,tgt)))))
          (load-offset value src tgt)))))
 
-(define-arithmetic-method 'MINUS-FIXNUM fixnum-methods/2-args/register*constant
+(define-arithconst-method 'MINUS-FIXNUM fixnum-methods/2-args/register*constant
+  (lambda (constant ovflw?)
+    ovflw?                                     ; ignored
+    (fits-in-11-bits-signed? (* constant fixnum-1)))
   (lambda (tgt src constant overflow?)
     (guarantee-signed-fixnum constant)
     (let ((value (- (* constant fixnum-1))))
@@ -256,13 +403,10 @@ MIT in each case. |#
                        (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
+(define-arithconst-method 'MINUS-FIXNUM fixnum-methods/2-args/constant*register
+  (lambda (constant ovflw?)
+    ovflw?                                     ; ignored
+    (fits-in-11-bits-signed? (* constant fixnum-1)))
   (lambda (tgt constant src overflow?)
     (guarantee-signed-fixnum constant)
     (let ((value (* constant fixnum-1)))
@@ -275,27 +419,270 @@ MIT in each case. |#
                 ,@(if overflow?
                       (LAP (SUB (NSV) ,temp ,src ,tgt))
                       (LAP (SUB () ,temp ,src ,tgt)))))))))
+\f
+(define-arithconst-method 'FIXNUM-LSH fixnum-methods/2-args/register*constant
+  (lambda (constant ovflw?)
+    constant ovflw?                            ; ignored
+    true)
+  (lambda (tgt src shift overflow?)
+    ;; What does overflow mean for a logical shift?
+    ;; The code commented out below corresponds to arithmetic shift
+    ;; overflow conditions.
+    (guarantee-signed-fixnum shift)
+    (cond ((zero? shift)
+          (cond ((not overflow?)
+                 (copy src tgt))
+                ((= src tgt)
+                 (LAP (SKIP (TR))))
+                (else
+                 (LAP (COPY (TR) ,src ,tgt)))))
+         ((negative? shift)
+          ;; Right shift
+          (let ((shift (- shift)))
+            (cond ((< shift scheme-datum-width)
+                   (LAP (SHD () 0 ,src ,shift ,tgt)
+                        ;; clear shifted bits
+                        (DEP (,(if overflow? 'TR 'NV))
+                              0 31 ,scheme-type-width ,tgt)))
+                  ((not overflow?)
+                   (copy 0 tgt))
+                  (else
+                   (LAP (COPY (TR) 0 ,tgt))))))
+         (else
+          ;; Left shift
+          (cond ((>= shift scheme-datum-width)
+                 (if (not overflow?)
+                     (copy 0 tgt)
+                     #| (LAP (COMICLR (=) 0 ,src ,tgt)) |#
+                     (LAP (COMICLR (TR) 0 ,src ,tgt))))
+                (overflow?
+                 #|
+                 ;; Arithmetic overflow condition accomplished
+                 ;; by skipping all over the place.
+                 ;; Another possibility is to use the shift-and-add
+                 ;; instructions, that compute correct signed overflow
+                 ;; conditions.
+                 (let ((nkept (- 32 shift))
+                       (temp (standard-temporary!)))
+                   (LAP (ZDEP () ,src ,(- nkept 1) ,nkept ,tgt)
+                        (EXTRS (=) ,src ,(- shift 1) ,shift ,temp)
+                        (COMICLR (<>) -1 ,temp 0)
+                        (SKIP (TR))))
+                 |#
+                 (LAP (ZDEP (TR) ,src ,(- nbits 1) ,nbits ,tgt)))
+                (else
+                 (let ((nbits (- 32 shift)))
+                   (LAP (ZDEP () ,src ,(- nbits 1) ,nbits ,tgt)))))))))
+
+(define-integrable (divisible? m n)
+  (zero? (remainder m n)))
+
+(define (integer-log-base-2? n)
+  (let loop ((power 1) (exponent 0))
+    (cond ((< n power) false)
+         ((= n power) exponent)
+         (else
+          (loop (* 2 power) (1+ exponent))))))
+\f
+(define-arithconst-method 'MULTIPLY-FIXNUM
+  fixnum-methods/2-args/register*constant
+  (lambda (constant ovflw?)
+    (let ((factor (abs constant)))
+      (or (integer-log-base-2? factor)
+         (and (<= factor 64)
+              (or (not ovflw?)
+                  (<= factor (expt 2 scheme-type-width)))))))
 
-(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)))
+  (lambda (tgt src constant overflow?)
+    (guarantee-signed-fixnum constant)
+    (let ((skip (if overflow? 'NSV 'NV)))
+      (case constant
+       ((0)
+        (if overflow?
+            (LAP (COPY (TR) 0 ,tgt))
+            (LAP (COPY () 0 ,tgt))))
+       ((1)
+        (if overflow?
+            (LAP (COPY (TR) ,src ,tgt))
+            (copy src tgt)))
+       ((-1)
+        (LAP (SUB (,skip) 0 ,src ,tgt)))
+       (else
+        (let* ((factor (abs constant))
+               (src+ (if (negative? constant) tgt src))
+               (xpt (integer-log-base-2? factor)))
+          (cond ((not overflow?)
+                 (LAP ,@(if (negative? constant)
+                            (LAP (SUB () 0 ,src ,tgt))
+                            (LAP))
+                      ,@(if xpt
+                            (LAP (SHD () ,src+ 0 ,(- 32 xpt) ,tgt))
+                            (expand-factor tgt src+ factor false 'NV
+                                           (lambda ()
+                                             (LAP))))))
+                ((and xpt (> xpt 6))
+                 (let* ((high (standard-temporary!))
+                        (low (if (or (= src tgt) (negative? constant))
+                                 (standard-temporary!)
+                                 src))
+                        (nbits (- 32 xpt))
+                        (core
+                         (LAP (SHD () ,low 0 ,nbits ,tgt)
+                              (SHD (=) ,high ,low ,(-1+ nbits) ,high)
+                              (COMICLR (<>) -1 ,high 0)
+                              (SKIP (TR)))))
+                   (if (negative? constant)
+                       (LAP (EXTRS () ,src 0 1 ,high)
+                            (SUB () 0 ,src ,low)
+                            (SUBB () 0 ,high ,high)
+                            ,@core)
+                       (LAP ,@(if (not (= src low))
+                                  (LAP (COPY () ,src ,low))
+                                  (LAP))
+                            (EXTRS () ,low 0 1 ,high)
+                            ,@core))))
+                (else
+                 (LAP ,@(if (negative? constant)
+                            (LAP (SUB (SV) 0 ,src ,tgt))
+                            (LAP))
+                      ,@(expand-factor tgt src+ factor (negative? constant)
+                                       'NSV
+                                       (lambda ()
+                                         (LAP (SKIP (TR))))))))))))))
+\f
+(define (expand-factor tgt src factor skipping? condition skip)
+  (define (sh3add condition src1 src2 tgt)
+    (LAP (SH3ADD (,condition) ,src1 ,src2 ,tgt)))
+
+  (define (sh2add condition src1 src2 tgt)
+    (LAP (SH2ADD (,condition) ,src1 ,src2 ,tgt)))
+
+  (define (sh1add condition src1 src2 tgt)
+    (LAP (SH1ADD (,condition) ,src1 ,src2 ,tgt)))
+
+  (define (handle factor fixed)
+    (define (wrap instr next value)
+      (let ((code? (car next))
+           (result-reg (cadr next))
+           (temp-reg (caddr next))
+           (code (cadddr next)))
+       (list true
+             tgt
+             temp-reg
+             (LAP ,@code
+                  ,@(if code?
+                        (skip)
+                        (LAP))
+                  ,@(instr condition result-reg value tgt)))))
+
+    (cond ((zero? factor) (list false 0 fixed (LAP)))
+         ((= factor 1) (list false fixed fixed (LAP)))
+         ((divisible? factor 8)
+          (wrap sh3add (handle (/ factor 8) fixed) 0))
+         ((divisible? factor 4)
+          (wrap sh2add (handle (/ factor 4) fixed) 0))
+         ((divisible? factor 2)
+          (wrap sh1add (handle (/ factor 2) fixed) 0))
+         (else
+          (let* ((f1 (-1+ factor))
+                 (fixed (if (or (not (= fixed src))
+                                (not (= src tgt))
+                                (and (integer-log-base-2? f1)
+                                     (< f1 16)))
+                          fixed
+                          (standard-temporary!))))
+            (cond ((divisible? f1 8)
+                   (wrap sh3add (handle (/ f1 8) fixed) fixed))
+                  ((divisible? f1 4)
+                   (wrap sh2add (handle (/ f1 4) fixed) fixed))
+                  (else
+                   (wrap sh1add (handle (/ f1 2) fixed) fixed)))))))
+
+  (let ((result (handle factor src)))
+    (let ((result-reg (cadr result))
+         (temp-reg (caddr result))
+         (code (cadddr result)))
+      
+      (LAP ,@(cond ((= temp-reg src)
+                   (LAP))
+                  ((not skipping?)
+                   (LAP (COPY () ,src ,temp-reg)))
+                  (else
+                   (LAP (COPY (TR) ,src ,temp-reg)
+                        ,@(skip))))
+          ,@code
+          ,@(cond ((= result-reg tgt)
+                   (LAP))
+                  ((eq? concition 'NV)
+                   (LAP (COPY () ,result-reg ,tgt)))
+                  (else
+                   (LAP (COPY (TR) ,result-reg ,tgt)
+                        ,@(skip))))))))
+\f
+;;;; Division
+
+(define-arithconst-method 'FIXNUM-QUOTIENT
+  fixnum-methods/2-args/register*constant
+  (lambda (constant ovflw?)
+    (let ((factor (abs constant)))
+      (and (or (not ovflw?) (= factor 1))
+          (fits-in-11-bits-signed? (* (- factor 1) fixnum-1))
+          (integer-log-base-2? factor))))
+  (lambda (tgt src constant ovflw?)
+    (guarantee-signed-fixnum constant)
+    (case constant
+      ((1)
+       (if ovflw?
+          (LAP (COPY (TR) ,src ,tgt))
+          (copy src tgt)))
+      ((-1)
+       (let ((skip (if ovflw? 'NSV 'NV)))
+        (LAP (SUB (,skip) 0 ,src ,tgt))))
+      (else
+       (let* ((factor (abs constant))
+             (xpt (integer-log-base-2? factor))
+             (sign (standard-temporary!)))
+        (if (or (not xpt) ovflw?)
+            (error "fixnum-quotient: Inconsistency" constant ovflw?))
+        (LAP ,@(if (negative? constant)
+                   (LAP (SUB (>=) 0 ,src ,tgt))
+                   (LAP (ADD (>=) 0 ,src ,tgt)))
+             (ADDI () ,(* (-1+ factor) fixnum-1) ,tgt ,tgt)
+             (EXTRS () ,tgt 0 1 ,sign)
+             (SHD () ,sign ,tgt ,xpt ,tgt)
+             (DEP () 0 31 ,scheme-type-width ,tgt)))))))
+
+(define-arithconst-method 'FIXNUM-REMAINDER
+  fixnum-methods/2-args/register*constant
+  (lambda (constant ovflw?)
+    (and (not ovflw?)
+        (integer-log-base-2? (abs constant))))
+  (lambda (tgt src constant ovflw?)
+    (guarantee-signed-fixnum constant)
+    (case constant
+      ((1 -1)
+       (LAP (COPY () 0 ,tgt)))
+      (else
+       (let ((sign (standard-temporary!))
+            (len (let ((xpt (integer-log-base-2? (abs constant))))
+                   (and xpt (+ xpt scheme-type-width)))))
+        (let ((sgn-len (- 32 len)))
+          (if (or ovflw? (not len))
+              (error "fixnum-remainder: Inconsistency" constant ovflw?))
+          (LAP (EXTRS () ,src 0 1 ,sign)
+               (EXTRU (=) ,src 31 ,len ,tgt)
+               (DEP () ,sign ,(- sgn-len 1) ,sgn-len ,tgt))))))))
 \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.
+;; 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 nullify using NSV (or TR if overflow is
+;; impossible).  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 a peep-hole optimizer
+;; will fix this.  The linearizer attempts to use the "good" branch.
 
 (define-rule predicate
   (OVERFLOW-TEST)
@@ -309,17 +696,10 @@ MIT in each case. |#
 
 (define-rule predicate
   (FIXNUM-PRED-1-ARG (? predicate) (REGISTER (? source)))
-  (compare (fixnum-pred-1->cc predicate)
+  (compare (fixnum-pred->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))
@@ -333,7 +713,7 @@ MIT in each case. |#
                      (REGISTER (? source))
                      (OBJECT->FIXNUM (CONSTANT (? constant))))
   (compare-fixnum/constant*register (invert-condition-noncommutative
-                                    (fixnum-pred-2->cc predicate))
+                                    (fixnum-pred->cc predicate))
                                    constant
                                    (standard-source! source)))
 
@@ -341,7 +721,7 @@ MIT in each case. |#
   (FIXNUM-PRED-2-ARGS (? predicate)
                      (OBJECT->FIXNUM (CONSTANT (? constant)))
                      (REGISTER (? source)))
-  (compare-fixnum/constant*register (fixnum-pred-2->cc predicate)
+  (compare-fixnum/constant*register (fixnum-pred->cc predicate)
                                    constant
                                    (standard-source! source)))
 
@@ -349,9 +729,10 @@ MIT in each case. |#
   (guarantee-signed-fixnum n)
   (compare-immediate cc (* n fixnum-1) r))
 
-(define (fixnum-pred-2->cc predicate)
+(define (fixnum-pred->cc predicate)
   (case predicate
-    ((EQUAL-FIXNUM?) '=)
-    ((LESS-THAN-FIXNUM?) '<)
-    ((GREATER-THAN-FIXNUM?) '>)
-    (else (error "unknown fixnum predicate" predicate))))
\ No newline at end of file
+    ((ZERO-FIXNUM? EQUAL-FIXNUM?) '=)
+    ((NEGATIVE-FIXNUM? LESS-THAN-FIXNUM?) '<)
+    ((POSITIVE-FIXNUM? GREATER-THAN-FIXNUM?) '>)
+    (else
+     (error "fixnum-pred->cc: unknown predicate" predicate))))
\ No newline at end of file
index cfa443f04a6b641f56f79a30adeaef9012e20833..c37f2da27a865750dea7f6d7ebeb3aaf282f771f 100644 (file)
@@ -1,7 +1,7 @@
 #| -*-Scheme-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/rulrew.scm,v 1.2 1990/04/03 04:52:59 jinx Exp $
-$MC68020-Header: rulrew.scm,v 1.2 90/04/03 04:52:22 GMT jinx Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/spectrum/rulrew.scm,v 1.3 1990/07/22 18:56:39 jinx Rel $
+$MC68020-rulrew.scm,v 1.3 90/05/03 15:17:42 GMT jinx Exp $
 
 Copyright (c) 1990 Massachusetts Institute of Technology
 
@@ -34,6 +34,7 @@ promotional, or sales literature without prior written consent from
 MIT in each case. |#
 
 ;;;; RTL Rewrite Rules
+;;; package: (compiler lap-syntaxer)
 
 (declare (usual-integrations))
 \f