home *** CD-ROM | disk | FTP | other *** search
- (herald (back_end spgen)
- (env t (orbit_top defs)))
-
- ;;; Copyright (c) 1985 Yale University
- ;;; Authors: N Adams, R Kelsey, D Kranz, J Philbin, J Rees.
- ;;; This material was developed by the T Project at the Yale University Computer
- ;;; Science Department. Permission to copy this software, to redistribute it,
- ;;; and to use it for any purpose is granted, subject to the following restric-
- ;;; tions 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 T Project at Yale any improvements or extensions that they make,
- ;;; so that these may be included in future releases; and (b) to inform
- ;;; the T Project 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. Yale has made no warrantee or representation that the operation of
- ;;; this software will be error-free, and Yale 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 Yale University nor of any
- ;;; adaptation thereof in any advertising, promotional, or sales literature
- ;;; without prior written consent from Yale in each case.
- ;;;
-
- ;;; GENERATE-HANDLER The situation is that the object is in A1 and its template
- ;;; is in TP. The operation is in P. We must use only the register AN.
-
- (define (hacked-get-register node)
- (cond ((reg-node an)
- (cond ((reg-node an+1) => kill))
- AN+1)
- (else
- AN)))
-
- (define (generate-handler node obj)
- (let ((leaves (call-args (lambda-body ((call-arg 3) (lambda-body node)))))
- (methods (cdddr (call-args (lambda-body node)))))
- (cond ((null? methods)
- (emit sparc/jmpl (reg-offset link-reg 0) zero)
- (generate-move nil-reg AN))
- (else
- (bind ((get-register hacked-get-register))
- (mark (lambda-self-var *heap-env*) A1)
- (generate-jump (car leaves))
- (let ((last ((call-arg 3) (lambda-body node))))
- (do ((l leaves (cdr l))
- (methods methods (cdr methods)))
- ((null? l)
- (emit-tag last)
- (emit sparc/jmpl (reg-offset link-reg 0) zero)
- (generate-move nil-reg AN)
- (clear-slots))
- (generate-handler-test obj (car l)
- (car methods)
- (if (null? (cdr l)) last (cadr l))))))))))
-
-
- (define (generate-handler-test obj leaf method next)
- (emit-tag leaf)
- (let ((el-hacko (cons nil nil)))
- (emit-compare jump-op/jn= (->register nil (leaf-value leaf)) P next el-hacko)
- (emit-tag el-hacko))
- (lambda-queue method)
- (let ((offset (handler-diff method obj)))
- (emit sparc/sethi offset AN)
- (emit risc/or offset AN AN)
- (emit risc/add AN vector AN)) ;entry point in vector
- (emit sparc/jmpl (reg-offset link-reg 0) zero)
- (emit-noop))
-
-
-
- ;;; %undefined-effect arg = A1
- (define (generate-undefined-effect node)
- (let ((acc (lookup-value node (leaf-value ((call-arg 1) node)))))
- (generate-slink-jump slink/undefined-effect)
- (generate-move acc A1)
- (clear-slots)))
-
-
- ;;; %set vcell = parassign-extra
-
- (define (generate-set node location value)
- (let ((access (if (lambda-node? value)
- (access/make-closure node value)
- (->register node (leaf-value value)))))
- (protect-access access)
- (let ((loc (lookup node (get-lvalue (leaf-value location)) nil))
- (hack1 (cons nil nil))
- (hack2 (cons nil nil)))
- (release-access access)
- (generate-move loc parassign-extra)
- (generate-move access (reg-offset parassign-extra 2))
- (free-register node AN)
- (lock AN)
- (free-register node AN-1)
- (unlock AN)
- (emit risc/load 'ub (reg-offset parassign-extra 0) scratch)
- (emit-compare jump-op/jn= zero scratch hack1 hack2)
- (emit-tag hack1)
- (generate-slink-call slink/set)
- (generate-jump hack2)
- (emit-tag hack2))))
-
-
- (define (generate-remove-state-object node)
- (let ((cont (car (call-args node))))
- (if (and (lambda-node? cont)
- (not (lambda-rest-var cont))
- (variable-refs (lambda-cont-var cont)))
- (mark-continuation node AN+1))))
-
-
- #|
- (define (generate-multiply lvar l-acc r-acc t-reg)
- (if (representable-fixnum? lvar 'add)
- (emit risc/add (machine-num lvar) zero ass-reg) ;%o0
- (emit risc/sra (machine-num 2) l-acc ass-reg)) ;%o0
- (generate-move r-acc extra-args) ;%o1
- (generate-slink-call slink/fx*)
- (generate-move ass-reg t-reg))
-
- (define (generate-divide lvar l-acc r-acc t-reg)
- (cond ((representable-fixnum? lvar 'add)
- (generate-move-addressable lvar extra-args))
- (else
- (generate-move l-acc extra-args)))
- (generate-move r-acc ass-reg)
- (generate-slink-call slink/fx/)
- (emit risc/sll (machine-num 2) ass-reg t-reg))
-
- (define (generate-remainder lvar l-acc r-acc t-reg)
- (cond ((representable-fixnum? lvar 'add)
- (generate-move-addressable lvar extra-args))
- (else
- (generate-move l-acc extra-args)))
- (generate-move r-acc ass-reg)
- (generate-slink-call slink/fx-rem)
- (generate-move ass-reg t-reg))
- |#
-
- (define (generate-extend node n)
- ;; don't include template
- (generate-move (machine-num (fx- n CELL)) SCRATCH)
- (generate-slink-call slink/make-extend)) ; delay slot
-
-
-
- (define (generate-extra-args-cons len)
- (generate-move (machine-num (* len CELL 2)) SCRATCH)
- (generate-slink-call slink/make-extra-args))
-
-
- (define (generate-extra-arg-move n)
- (generate-move (reg-offset extra-args
- (+ (* (- n *first-stack-register*) 8) 1)) n))
-
- ;;; This stuff almost duplicates code in parassign
- ;;; do-trivial-lambda and indirect-lambda and do-immediate
-
- (define (generate-extra-arg-store node arg n)
- (let ((ro (reg-offset extra-args (+ (* n 8) 1))))
- (cond ((lambda-node? arg)
- (cond ((eq? (environment-closure (lambda-env arg)) *unit*)
- (lambda-queue arg)
- (generate-move (lookup node arg nil) ro))
- (else
- (let ((offset (environment-cic-offset (lambda-env arg))))
- (cond ((fx= offset 0)
- (generate-move AN ro))
- (else
- (generate-move-address (reg-offset AN offset) ro)))))))
- ((not (addressable? (leaf-value arg)))
- (generate-move (lookup-value node (reference-variable arg)) ro))
- (else
- (generate-move-addressable (leaf-value arg) ro)))))
-
- (define (generate-two-fixnums node)
- (destructure (((then else () ref1 ref2) (call-args node)))
- (let ((reg1 (->register node (leaf-value ref1))))
- (lock reg1)
- (let ((reg2 (->register node (leaf-value ref2))))
- (unlock reg1)
- (cond ((target-fixnum? (leaf-value ref2))
- (emit risc/and (machine-num 3) reg1 SCRATCH))
- (else
- (emit risc/or reg1 reg2 SCRATCH)
- (emit risc/and (machine-num 3) SCRATCH SCRATCH)))
- (emit-compare jump-op/jn= SCRATCH zero else then)))))
-
- (define (generate-op-with-overflow node op)
- (destructure (((then else () ref1 ref2) (call-args node)))
- (let ((reg1 (->register node (leaf-value ref1))))
- (lock reg1)
- (let ((reg2 (->register node (leaf-value ref2))))
- (lock reg2)
- (let ((target (get-register node))
- (hack (cons nil nil)))
- (unlock reg1)
- (unlock reg2)
- (xcase op
- ((add)
- (emit risc/add reg2 reg1 target)
- (emit risc/xor reg2 reg1 scratch)
- (emit-compare jump-op/j>= scratch zero hack then)
- (emit-tag hack)
- (emit risc/xor reg2 target scratch)
- (emit-compare jump-op/j>= scratch zero else then))
- ((subtract)
- (emit risc/sub reg2 reg1 target)
- (emit risc/xor reg2 reg1 scratch)
- (emit-compare jump-op/j>= scratch zero then hack)
- (emit-tag hack)
- (emit risc/xor reg2 target scratch)
- (emit-compare jump-op/j>= scratch zero then else)))
- (mark (car (lambda-variables else)) target))))))
-
- (define (generate-foreign-call node)
- (destructure (((#f foreign rep-list value-rep . args) (call-args node)))
- (emit risc/store 'l sp (reg-offset nil-reg slink/saved-sp))
- (emit risc/store 'l ssp (reg-offset nil-reg slink/saved-ssp))
- (emit risc/store 'l crit-reg (reg-offset nil-reg slink/saved-crit))
- (let* ((rep-list (map cadr (leaf-value rep-list))))
- (iterate loop ((outs os) ;%o0
- (in A1)
- (reps (reverse! rep-list)))
- (cond ((null? reps))
- ((null? outs)
- (do ((i (* 23 4) (fx+ i 4)) ;see sparc stack frame
- (reps reps (cdr reps))
- (in in (fx+ in 1)))
- ((null? reps))
- (cond ((eq? (car reps) 'rep/double)
- (bug "Can't handle double in this position"))
- (else
- (cond ((fx< in AN)
- (pointer->rep in AN (car reps)))
- (else
- (emit risc/load 'l
- (reg-offset extra-args (+ (* (- in AN) 8) %%car))
- parassign-extra)
- (pointer->rep parassign-extra AN (car reps))))
- (emit risc/store 'l AN (reg-offset ssp i))))))
- ((eq? (car reps) 'rep/double)
- (emit risc/load 'l (reg-offset in 2) (car outs))
- (emit risc/load 'l (reg-offset in 6) (cadr outs))
- (loop (cddr outs) (fx+ in 1) (cdr reps)))
- (else
- (pointer->rep in (car outs) (car reps))
- (loop (cdr outs) (fx+ in 1) (cdr reps))))))
- (generate-move (lookup-value node (leaf-value foreign)) P)
- (emit risc/load 'l (reg-offset P 6) P)
- (generate-move link-reg A5) ;save continuation
- (emit sparc/jmpl (reg-offset p 0) link-reg)
- (emit sparc/noop)
- (generate-move A5 link-reg)
- (emit risc/load 'l (reg-offset nil-reg slink/saved-sp) sp) ;g1
- (generate-move (machine-num header/true) t-reg) ;g2
- (generate-move zero an+1) ;g3
- (generate-move zero extra-args) ;o1
- (generate-move zero extra) ;o2
- (generate-move zero parassign-extra) ;o3
- (generate-move zero vector) ;o4
- (emit risc/store 'l zero (reg-offset nil-reg slink/saved-sp))
- (case (leaf-value value-rep)
- ((rep/undefined ignore))
- ((rep/double)
- (generate-move (machine-num header/double-float) AN)
- (generate-move (machine-num 8) scratch)
- (generate-slink-call slink/make-extend)
- (emit sparc/fstore 0 (reg-offset AN 2))
- (emit sparc/fstore 1 (reg-offset AN 6))
- (generate-move AN A1))
- (else
- (rep->pointer ass-reg A1 (leaf-value value-rep)))) ;ass-reg = %o0
- (generate-move zero ass-reg)))
-
- (define os (list ass-reg extra-args extra parassign-extra vector scratch))
-
- (define (pointer->rep from to rep)
- (case rep
- ((rep/pointer) (generate-move from to))
- ((rep/extend) (emit risc/add (machine-num 2) from to))
- ((rep/c-pointer)
- (emit risc/add (machine-num 2) from to)
- (emit risc/srl (machine-num 2) to to)
- (emit risc/sll (machine-num 2) to to))
- ((rep/string)
- (emit risc/load 'l (reg-offset from 6) to)
- (emit risc/load 'l (reg-offset from 2) from)
- (emit risc/add from to to)
- (emit risc/add (machine-num 2) to to))
- ((rep/char)
- (emit risc/srl (machine-num 8) from to))
- (else
- (emit risc/sra (machine-num 2) from to))))
-
- (define (rep->pointer from to rep)
- (case rep
- ((rep/pointer) (generate-move from to))
- ((rep/extend) (emit risc/sub (machine-num 2) from to))
- ((rep/char)
- (emit risc/sll (machine-num 8) from to)
- (emit risc/or (machine-num header/char) to to))
- (else
- (emit risc/sll (machine-num 2) from to))))
-
-