;;; -*- Mode:Lisp; Package:(NC LISP); Readtable:CL; Base:10 -*- ;;; 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. ;;; ;;; Copyright (c) 1985 David Kranz (defun generate-set-location (node) ;; cont type-primop value . args (ecase (length (call-args node)) (4 (generate-set-fixed-accessor node)) (5 (generate-set-vector-elt node)))) (defun generate-set-fixed-accessor (node) (destructure (((nil type value loc) (call-args node))) (let ((prim (leaf-value type))) (cond ((lambda-node? value) (let ((access (access/make-closure node value))) (if access (protect-access access) (lock AN)) (cond ((and (eq prim primop/cell-value) (eq (variable-support (leaf-value loc)) 'one)) (kill (leaf-value loc)) ; force into closure (emit lm/move (access-value node (leaf-value loc)) AN)) (t (let ((reg (->register 'pointer node (leaf-value loc) '*))) (generate-move (if access access AN) (reg-offset reg (primop.location-specs prim)))))) (if access (release-access access) (unlock AN)))) (t (let ((access (access-with-rep node (leaf-value value) 'rep/pointer))) (protect-access access) (cond ((and (eq prim primop/cell-value) (member (variable-support (leaf-value loc)) '(one nil))) ;eq 'one (let ((lc (access-value node (leaf-value loc)))) (generate-move access lc) (let ((lc (and (register? lc) (temp-loc (leaf-value loc))))) (cond (lc (setf (temp-node lc) nil) (setf (temp-loc (leaf-value loc)) nil)))))) (t (let ((reg (->register 'pointer node (leaf-value loc) '*))) (emit lm/move (reg-offset reg (primop.location-specs prim)) access)))) (release-access access))))))) #||| (define (generate-set-vector-type-length node) (destructure (((#f vec val) (call-args node))) (let ((reg (->register 'pointer node (leaf-value vec) '*)) (val (leaf-value val))) (lock reg) (let ((scratch (get-register 'scratch node '*))) (cond ((variable? val) (generate-move (access-value node val) scratch) (emit m68/asl .l (machine-num (if (eq? (variable-rep val) 'rep/pointer) 6 8)) scratch)) (else (emit m68/move .l (machine-num (fixnum-ashl val 8)) scratch))) (emit m68/move .b (reg-offset reg 1) scratch) (emit m68/move .l scratch (reg-offset reg -2)) (unlock reg))))) (define (generate-set-vector-elt node) (destructure (((#f type value loc idex) (call-args node))) (let ((idex (leaf-value idex)) (rep (primop.rep-wants (leaf-value type)))) (cond ((eq? rep 'rep/pointer) (let* ((access (if (lambda-node? value) (access/make-closure node value) (access-value node (leaf-value value)))) (value-acc (if access access AN))) (if access (protect-access access) (lock AN)) (let* ((i-acc (access-with-rep node idex 'rep/pointer)) (i-reg (cond ((register? i-acc) i-acc) (else (emit m68/move .l i-acc SCRATCH) SCRATCH))) (reg (->register 'pointer node (leaf-value loc) '*))) (generate-move value-acc (indexer reg tag/extend i-reg)) (if access (release-access access) (unlock AN))))) (else (let* ((i-acc (access-with-rep node idex 'rep/integer)) (i-reg (cond ((register? i-acc) i-acc) (else (let ((i (get-register 'scratch node '*))) (emit m68/move .l i-acc i) i)))) (reg (->register 'pointer node (leaf-value loc) '*)) (value (leaf-value value))) (lock i-reg) (lock reg) (cond ((variable? value) (let ((acc (access-value node value))) (protect-access acc) (really-rep-convert node acc (variable-rep value) (indexer reg tag/extend i-reg) rep) (release-access acc))) (else (really-rep-convert node (value-with-rep value rep) rep (indexer reg tag/extend i-reg) rep))) (unlock i-reg) (unlock reg))))))) |||# (defun generate-contents-location (node) (ecase (length (call-args node)) (3 (generate-fixed-accessor node)) (4 (generate-vector-elt node)))) (defun generate-fixed-accessor (node) (destructure (((cont type loc) (call-args node))) (if (or (leaf-node? cont) (used? (car (lambda-variables cont)))) (multiple-value-bind (t-spec t-rep) (continuation-wants cont) (let* ((type (leaf-value type)) (base (leaf-value loc)) (target (get-target-register node t-spec))) (cond ((and (eq type primop/cell-value) (member (variable-support base) '(one nil))) ;eq 'one (really-rep-convert node (access-value node base) 'rep/pointer target t-rep)) (t (let ((reg (->register 'pointer node base '*))) (really-rep-convert node (reg-offset reg (primop.location-specs type)) 'rep/pointer target t-rep)))) (let ((node (reg-node target))) (cond (node (setf (register-loc node) nil)))) (mark-continuation node target)))))) #||| (define (generate-vector-type-length node) (destructure (((cont vec) (call-args node))) (receive (t-spec t-rep) (continuation-wants cont) (let* ((base (leaf-value vec)) (target (get-target-register node t-spec)) (reg (->register 'pointer node base '*)) (temp (if (eq? (reg-type target) 'scratch) target SCRATCH))) (emit m68/move .l (reg-offset reg -2) temp) (emit m68/asr .l (machine-num 8) temp) (if (eq? t-rep 'rep/pointer) (emit m68/asl .l (machine-num 2) temp)) (generate-move temp target) (cond ((reg-node target) => (lambda (node) (set (register-loc node) nil)))) (mark-continuation node target))))) (define (generate-vector-elt node) (destructure (((cont type loc idex) (call-args node))) (receive (t-spec t-rep) (continuation-wants cont) (let* ((base (leaf-value loc)) (rep (primop.rep-wants (leaf-value type))) (idex (leaf-value idex)) (t-reg (get-target-register node t-spec)) (reg (->register 'pointer node base '*))) (lock reg) (cond ((fixnum? idex) (really-rep-convert node (reg-offset reg (fx+ (if (eq? rep 'rep/pointer) (fx* idex 4) idex) tag/extend)) (primop.rep-wants (leaf-value type)) t-reg t-rep)) (else (let* ((i-acc (access-with-rep node idex (if (eq? rep 'rep/pointer) 'rep/pointer 'rep/integer))) (i-reg (cond ((register? i-acc) i-acc) (else (let ((i (get-register 'scratch node '*))) (emit m68/move .l i-acc i) i))))) (really-rep-convert node (indexer reg tag/extend i-reg) rep t-reg t-rep)))) (unlock reg) (cond ((reg-node t-reg) => (lambda (node) (set (register-loc node) nil)))) (mark-continuation node t-reg))))) (define (generate-make-pointer node) (destructure (((cont loc idex) (call-args node))) (receive (t-spec t-rep) (continuation-wants cont) (let ((t-reg (get-target-register node t-spec)) (reg (->register 'pointer node (leaf-value loc) '*))) (lock reg) (let* ((i-acc (access-with-rep node (leaf-value idex) 'rep/pointer)) (i-reg (cond ((register? i-acc) i-acc) (else (let ((i (get-register 'scratch node '*))) (emit m68/move .l i-acc i) i))))) (emit m68/lea (indexer reg 4 i-reg) t-reg)) (unlock reg) (cond ((reg-node t-reg) => (lambda (node) (set (register-loc node) nil)))) (mark-continuation node t-reg))))) (define (generate-location-access node) ((xselect (length (call-args node)) ((3) defer-fixed-accessor) ((4) defer-vector-elt)) node)) (define (defer-fixed-accessor node) (destructure (((cont type loc) (call-args node))) (let* ((type (leaf-value type)) (base (leaf-value loc)) (reg (->register 'pointer node base '*))) (lock reg) (set (register-loc (car (lambda-variables cont))) (cons reg (primop.location-specs type))) (allocate-call (lambda-body cont))))) (define (defer-vector-elt node) (destructure (((cont type loc index) (call-args node))) (let* ((base (leaf-value loc)) (rep (primop.rep-wants (leaf-value type))) (index (leaf-value index)) (reg (->register 'pointer node base '*))) (lock reg) (cond ((fixnum? index) (set (register-loc (car (lambda-variables cont))) (cons reg (fx+ (if (eq? rep 'rep/pointer) (fx* 4 index) index) tag/extend)))) (else (let* ((i-acc (access-with-rep node index (if (eq? rep 'rep/pointer) 'rep/pointer 'rep/integer))) (i-reg (cond ((register? i-acc) i-acc) (else (let ((i (get-register 'scratch node '*))) (emit m68/move .l i-acc i) i))))) (unlock reg) (kill-if-dying index node) (lock reg) (lock i-reg) (set (register-loc (car (lambda-variables cont))) (cons (cons reg i-reg) 2))))) (allocate-call (lambda-body cont))))) (define (generate-%chdr node) (destructure (((#f vec val) (call-args node))) (let ((reg (->register 'pointer node (leaf-value vec) '*)) (val (leaf-value val))) (lock reg) (cond ((fixnum? val) (if (fx= val 1) (emit m68/add .l (machine-num 1) (reg-offset reg offset/string-base)) (emit m68/add .l (machine-num val) (reg-offset reg offset/string-base))) (emit m68/sub .l (machine-num (fixnum-ashl val 8)) (reg-offset reg -2))) (else (let* ((n (access-with-rep node val 'rep/integer)) (data-reg (if (and (register? n) (dying? val node)) n SCRATCH))) (generate-move n data-reg) (emit m68/add .l data-reg (reg-offset reg offset/string-base)) (emit m68/asl .l (machine-num 8) data-reg) (emit m68/sub .l data-reg (reg-offset reg -2))))) (unlock reg)))) |||#