#| -*-Scheme-*-
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/bobcat/lapgen.scm,v 4.32 1990/05/03 15:17:14 jinx Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/machines/bobcat/lapgen.scm,v 4.33 1990/06/26 22:16:23 jinx Exp $
Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
(else (error "FIXNUM-PREDICATE->CC: Unknown predicate" predicate))))
(define (fixnum-2-args/commutative? operator)
- (memq operator '(PLUS-FIXNUM MULTIPLY-FIXNUM)))
+ (memq operator '(PLUS-FIXNUM MULTIPLY-FIXNUM
+ FIXNUM-AND FIXNUM-OR FIXNUM-XOR)))
\f
(define (define-fixnum-method operator methods method)
(let ((entry (assq operator (cdr methods))))
(lambda (reference)
(LAP (SUB L (& ,fixnum-1) ,reference))))
-(define-fixnum-method 'PLUS-FIXNUM fixnum-methods/2-args
+(define-fixnum-method 'FIXNUM-NOT fixnum-methods/1-arg
+ (lambda (reference)
+ (LAP (NOT L ,reference)
+ ,@(word->fixnum reference))))
+
+(let-syntax
+ ((binary-fixnum
+ (macro (name instr identity?)
+ `(begin
+ (define-fixnum-method ',name fixnum-methods/2-args
+ (lambda (target source)
+ (LAP (,instr L ,',source ,',target))))
+ (define-fixnum-method ',name fixnum-methods/2-args-constant
+ (lambda (target n)
+ (if (,identity? n)
+ (LAP)
+ (LAP (,instr L (& ,',(* n fixnum-1)) ,',target)))))))))
+
+ (binary-fixnum PLUS-FIXNUM ADD zero?)
+ (binary-fixnum FIXNUM-OR OR zero?)
+ (binary-fixnum FIXNUM-AND AND
+ (lambda (n)
+ (declare (integrate n))
+ (fix:= n -1))))
+\f
+;; XOR is weird because the first operand for an EOR instruction
+;; must be a D register!
+
+(define-fixnum-method 'FIXNUM-XOR fixnum-methods/2-args
(lambda (target source)
- (LAP (ADD L ,source ,target))))
+ (if (effective-address/data-register? source)
+ (LAP (EOR L ,source ,target))
+ (let ((temp (reference-temporary-register! 'DATA)))
+ (LAP (MOV L ,source ,temp)
+ (EOR L ,temp ,target))))))
-(define-fixnum-method 'PLUS-FIXNUM fixnum-methods/2-args-constant
+(define-fixnum-method 'FIXNUM-XOR fixnum-methods/2-args-constant
(lambda (target n)
- (cond ((zero? n) (LAP))
- (else (LAP (ADD L (& ,(* n fixnum-1)) ,target))))))
+ (if (zero? n)
+ (LAP)
+ (LAP (EOR L (& ,(* n fixnum-1)) ,target)))))
+
+;; Multiply is hairy, since numbers are shifted by the type code width.
+;; Rather than unshift, multiply, and shift, we unshift one and then
+;; multiply, but we have to be careful if the source is the same
+;; as the destination.
(define-fixnum-method 'MULTIPLY-FIXNUM fixnum-methods/2-args
(lambda (target source)
- (if (equal? target source)
- (if (even? scheme-type-width)
+ (cond ((not (equal? target source))
+ (LAP
+ (AS R L (& ,scheme-type-width) ,target)
+ (MUL S L ,source ,target)))
+ ((even? scheme-type-width)
(LAP
(AS R L (& ,(quotient scheme-type-width 2)) ,target)
- (MUL S L ,source ,target))
+ (MUL S L ,source ,target)))
+ (else
+ #|
+ ;; This is no good because the MUL instruction is
+ ;; not last, and thus the overflow condition is
+ ;; not set appropriately.
(LAP
(AS R L (& ,scheme-type-width) ,target)
(MUL S L ,source ,target)
- (AS L L (& ,scheme-type-width) ,target)))
- (LAP
- (AS R L (& ,scheme-type-width) ,target)
- (MUL S L ,source ,target)))))
+ (AS L L (& ,scheme-type-width) ,target))
+ |#
+ (let ((temp (reference-temporary-register! 'DATA)))
+ (LAP
+ (MOV L ,source ,temp)
+ (AS R L (& ,scheme-type-width) ,target)
+ (MUL S L ,temp ,target)))))))
(define-fixnum-method 'MULTIPLY-FIXNUM fixnum-methods/2-args-constant
(lambda (target n)
((= n -1) (LAP (NEG L ,target)))
(else
(let ((power-of-2 (integer-log-base-2? n)))
- (if power-of-2
- (if (> power-of-2 8)
- (let ((temp (reference-temporary-register! 'DATA)))
- (LAP (MOV L (& ,power-of-2) ,temp)
- (AS L L ,temp ,target)))
- (LAP (AS L L (& ,power-of-2) ,target)))
- (LAP (MUL S L (& ,n) ,target))))))))
-\f
+ (cond ((not power-of-2)
+ (LAP (MUL S L (& ,n) ,target)))
+ ((> power-of-2 8)
+ (let ((temp (reference-temporary-register! 'DATA)))
+ (LAP (MOV L (& ,power-of-2) ,temp)
+ (AS L L ,temp ,target))))
+ (else
+ (LAP (AS L L (& ,power-of-2) ,target)))))))))
+
(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-fixnum-method 'MINUS-FIXNUM fixnum-methods/2-args
(lambda (target source)
(LAP (SUB L ,source ,target))))
(define-fixnum-method 'MINUS-FIXNUM fixnum-methods/2-args-constant
(lambda (target n)
- (cond ((zero? n) (LAP))
- (else (LAP (SUB L (& ,(* n fixnum-1)) ,target))))))
+ (if (zero? n)
+ (LAP)
+ (LAP (SUB L (& ,(* n fixnum-1)) ,target)))))
+
+(define-fixnum-method 'FIXNUM-ANDC fixnum-methods/2-args
+ (lambda (target source)
+ (let ((temp (reference-temporary-register! 'DATA)))
+ (LAP (MOV L ,source ,temp)
+ (NOT L ,temp)
+ (AND L ,temp ,target)))))
+
+(define-fixnum-method 'FIXNUM-ANDC fixnum-methods/2-args-constant
+ (lambda (target n)
+ (if (zero? n)
+ (LAP)
+ (LAP (AND L (& ,(* (fix:not n) fixnum-1)) ,target)))))
(define-fixnum-method 'FIXNUM-QUOTIENT fixnum-methods/2-args
(lambda (target source)
(lambda (target n)
(cond ((= n 1) (LAP))
((= n -1) (LAP (NEG L ,target)))
- (else (LAP (DIV S L (& ,n) ,target))))))
+ ((integer-log-base-2? n)
+ =>
+ (lambda (power-of-2)
+ (let ((label (generate-uninterned-symbol "quoshift")))
+ (LAP (TST L ,target)
+ (B GE (@PCR ,label))
+ (ADD L (& ,(* (-1+ n) fixnum-1)) ,target)
+ (LABEL ,label)
+ ,@(if (<= power-of-2 8)
+ (LAP (AS R L (& ,power-of-2) ,target))
+ (let ((temp (reference-temporary-register! 'DATA)))
+ (LAP (MOV L (& ,power-of-2) ,temp)
+ (AS R L ,temp ,target))))
+ ,@(word->fixnum target)))))
+ (else
+ ;; This includes negative n
+ (LAP (DIV S L (& ,n) ,target))))))
+;; This renormalizes a fixnum after a bit-wise boolean operation
+
+(define-integrable fixnum-bits-mask
+ (fix:not scheme-type-mask))
+
+(define (word->fixnum target)
+ (cond ((= scheme-type-width 8)
+ (LAP (CLR B ,target)))
+ ((< scheme-type-width 8)
+ (LAP (AND B (& ,fixnum-bits-mask) ,target)))
+ (else
+ (LAP (AND L (& ,fixnum-bits-mask) ,target)))))
+\f
(define-fixnum-method 'FIXNUM-REMAINDER fixnum-methods/2-args
(lambda (target source)
(let ((temp (reference-temporary-register! 'DATA)))
- (LAP
- (DIV S L ,source ,temp ,target)
- (MOV L ,temp ,target)))))
+ (LAP (DIVL S L ,source ,temp ,target)
+ (MOV L ,temp ,target)))))
(define-fixnum-method 'FIXNUM-REMAINDER fixnum-methods/2-args-constant
(lambda (target n)
(if (or (= n 1) (= n -1))
(LAP (CLR L ,target))
- (let ((temp (reference-temporary-register! 'DATA)))
- (LAP
- (DIV S L (& ,(* n fixnum-1)) ,temp ,target)
- (MOV L ,temp ,target))))))
+ (let ((xpt (integer-log-base-2? n)))
+ (if (or (not xpt)
+ (not use-68020-instructions?) )
+ ;; This includes negative n
+ (let ((temp (reference-temporary-register! 'DATA)))
+ (LAP (DIVL S L (& ,(* n fixnum-1)) ,temp ,target)
+ (MOV L ,temp ,target)))
+ (let ((sign (reference-temporary-register! 'DATA))
+ (label (generate-uninterned-symbol "remmerge"))
+ (shift (- scheme-datum-width xpt)))
+ (LAP (CLR L ,sign)
+ (BFTST ,target (& ,shift) (& ,xpt))
+ (B EQ (@PCR ,label))
+ (BFEXTS ,target (& 0) (& 1) ,sign)
+ (LABEL ,label)
+ (BFINS ,target (& 0) (& ,shift) ,sign))))))))
\f
;;;; Flonum Operators
;; (-1+ (expt 2 scheme-type-width)) ***
#x3f)
-(define use-68020-instructions? true)
+(define-integrable use-68020-instructions? true)
(define (object->type source target)
;; `Source' must be a data register or non-volatile memory reference.
#| -*-Scheme-*-
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/rtlgen/opncod.scm,v 4.37 1990/05/03 15:11:44 jinx Exp $
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/compiler/rtlgen/opncod.scm,v 4.38 1990/06/26 22:16:41 jinx Exp $
Copyright (c) 1988, 1989, 1990 Massachusetts Institute of Technology
primitive))))
\f
(define (open-code:type-check expression type)
- (if compiler:generate-type-checks?
+ (if (and compiler:generate-type-checks?
+ type)
(generate-type-test type
expression
make-false-pcfg
;; This is not reasonable since the port may not include such open codings.
(define (open-code:range-check index-expression limit-locative)
- (if compiler:generate-range-checks?
+ (if (and compiler:generate-range-checks?
+ limit-locative)
(pcfg*pcfg->pcfg!
(generate-nonnegative-check index-expression)
(pcfg/prefer-consequent!
(unknown-index)))
(unknown-index))))))
+(define object-memory-reference
+ (indexed-memory-reference
+ false
+ (lambda (expression)
+ expression ; ignored
+ false)
+ (index-locative-generator rtl:locative-offset 0 address-units-per-object)))
+
(define vector-memory-reference
(indexed-memory-reference
(ucode-type vector)
compiler:generate-range-checks?))))
'(VECTOR-REF SYSTEM-VECTOR-REF))
+(define-open-coder/value 'PRIMITIVE-OBJECT-REF
+ (simple-open-coder
+ (object-memory-reference 'PRIMITIVE-OBJECT-REF false
+ (lambda (locative expressions finish)
+ expressions
+ (finish (rtl:make-fetch locative))))
+ '(0 1)
+ false))
+
;; For now SYSTEM-XXXX side effect procedures are considered
;; dangerous to the garbage collector's health. Some day we will
;; again be able to enable them.
(or compiler:generate-type-checks?
compiler:generate-range-checks?))))
'(VECTOR-SET! #| SYSTEM-VECTOR-SET! |#))
+
+(define-open-coder/effect 'PRIMITIVE-OBJECT-SET!
+ (simple-open-coder
+ (object-memory-reference 'PRIMITIVE-OBJECT-SET! false
+ (lambda (locative expressions finish)
+ (finish-vector-assignment locative
+ (caddr expressions)
+ finish)))
+ '(0 1 2)
+ false))
\f
;;;; Character/String Primitives
'(PLUS-FIXNUM
MINUS-FIXNUM
MULTIPLY-FIXNUM
- DIVIDE-FIXNUM
- GCD-FIXNUM))
+ ;; DIVIDE-FIXNUM
+ GCD-FIXNUM
+ FIXNUM-QUOTIENT
+ FIXNUM-REMAINDER
+ FIXNUM-ANDC
+ FIXNUM-AND
+ FIXNUM-OR
+ FIXNUM-XOR))
(for-each (lambda (fixnum-operator)
(define-open-coder/value fixnum-operator
false))))
'(0)
false)))
- '(ONE-PLUS-FIXNUM MINUS-ONE-PLUS-FIXNUM))
+ '(ONE-PLUS-FIXNUM MINUS-ONE-PLUS-FIXNUM FIXNUM-NOT))
(for-each (lambda (fixnum-pred)
(define-open-coder/predicate fixnum-pred