Update of /project/movitz/cvsroot/movitz In directory common-lisp.net:/tmp/cvs-serv2870
Modified Files: compiler.lisp Log Message: Improved various aspects related to compiling :incf-lexvar.
Date: Fri Feb 13 05:40:15 2004 Author: ffjeld
Index: movitz/compiler.lisp diff -u movitz/compiler.lisp:1.23 movitz/compiler.lisp:1.24 --- movitz/compiler.lisp:1.23 Thu Feb 12 16:57:05 2004 +++ movitz/compiler.lisp Fri Feb 13 05:40:14 2004 @@ -8,7 +8,7 @@ ;;;; Created at: Wed Oct 25 12:30:49 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: compiler.lisp,v 1.23 2004/02/12 21:57:05 ffjeld Exp $ +;;;; $Id: compiler.lisp,v 1.24 2004/02/13 10:40:14 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------
@@ -2709,6 +2709,14 @@ mode) (t default-mode)))
+(defun chose-free-register (unfree-registers &optional (preferred-register :eax)) + (cond + ((not (member preferred-register unfree-registers)) + preferred-register) + ((find-if (lambda (r) (not (member r unfree-registers))) + '(:eax :ebx :ecx :edx))) + (t (error "Unable to find a free register.")))) + (defun make-indirect-reference (base-register offset) "Make the shortest possible assembly indirect reference, explointing the constant edi register." (if (<= #x-80 offset #x7f) @@ -2874,51 +2882,55 @@ (install-for-single-value binding binding-location :eax nil))) ))))))))
-(defun make-store-lexical (binding source shared-reference-p frame-map) +(defun make-store-lexical (binding source shared-reference-p frame-map + &key protect-registers) (assert (not (and shared-reference-p (not (binding-lended-p binding)))) (binding) "funny binding: ~W" binding) - (cond - ((typep binding 'borrowed-binding) - (let ((slot (borrowed-binding-reference-slot binding))) - (if (not shared-reference-p) - (let ((tmp-reg (if (eq source :eax) :ebx :eax))) - `((:movl (:esi ,(+ (slot-offset 'movitz-funobj 'constant0) (* 4 slot))) - ,tmp-reg) - (:movl ,source (-1 ,tmp-reg)))) - `((:movl ,source (:esi ,(+ (slot-offset 'movitz-funobj 'constant0) (* 4 slot)))))))) - ((typep binding 'forwarding-binding) - (assert (not (binding-lended-p binding)) (binding)) - (make-store-lexical (forwarding-binding-target binding) - source shared-reference-p frame-map)) - ((not (new-binding-located-p binding frame-map)) - ;; (warn "Can't store to unlocated binding ~S." binding) - nil) - ((and (binding-lended-p binding) - (not shared-reference-p)) - (let ((tmp-reg (if (eq source :eax) :ebx :eax)) - (location (new-binding-location binding frame-map))) - (if (integerp location) - `((:movl (:ebp ,(stack-frame-offset location)) ,tmp-reg) - (:movl ,source (,tmp-reg -1))) - (ecase location - (:argument-stack - (assert (<= 2 (function-argument-argnum binding)) () - "store-lexical argnum can't be ~A." (function-argument-argnum binding)) - `((:movl (:ebp ,(argument-stack-offset binding)) ,tmp-reg) - (:movl ,source (,tmp-reg -1)))))))) - (t (let ((location (new-binding-location binding frame-map))) + (let ((protect-registers (cons source protect-registers))) + (cond + ((typep binding 'borrowed-binding) + (let ((slot (borrowed-binding-reference-slot binding))) + (if (not shared-reference-p) + (let ((tmp-reg (chose-free-register protect-registers) + #+ignore(if (eq source :eax) :ebx :eax))) + `((:movl (:esi ,(+ (slot-offset 'movitz-funobj 'constant0) (* 4 slot))) + ,tmp-reg) + (:movl ,source (-1 ,tmp-reg)))) + `((:movl ,source (:esi ,(+ (slot-offset 'movitz-funobj 'constant0) (* 4 slot)))))))) + ((typep binding 'forwarding-binding) + (assert (not (binding-lended-p binding)) (binding)) + (make-store-lexical (forwarding-binding-target binding) + source shared-reference-p frame-map)) + ((not (new-binding-located-p binding frame-map)) + ;; (warn "Can't store to unlocated binding ~S." binding) + nil) + ((and (binding-lended-p binding) + (not shared-reference-p)) + (let ((tmp-reg (chose-free-register protect-registers) + #+ignore (if (eq source :eax) :ebx :eax)) + (location (new-binding-location binding frame-map))) (if (integerp location) - `((:movl ,source (:ebp ,(stack-frame-offset location)))) + `((:movl (:ebp ,(stack-frame-offset location)) ,tmp-reg) + (:movl ,source (,tmp-reg -1))) (ecase location - ((:eax :ebx :edx) - (unless (eq source location) - `((:movl ,source ,location)))) (:argument-stack (assert (<= 2 (function-argument-argnum binding)) () "store-lexical argnum can't be ~A." (function-argument-argnum binding)) - `((:movl ,source (:ebp ,(argument-stack-offset binding))))))))))) + `((:movl (:ebp ,(argument-stack-offset binding)) ,tmp-reg) + (:movl ,source (,tmp-reg -1)))))))) + (t (let ((location (new-binding-location binding frame-map))) + (if (integerp location) + `((:movl ,source (:ebp ,(stack-frame-offset location)))) + (ecase location + ((:eax :ebx :edx) + (unless (eq source location) + `((:movl ,source ,location)))) + (:argument-stack + (assert (<= 2 (function-argument-argnum binding)) () + "store-lexical argnum can't be ~A." (function-argument-argnum binding)) + `((:movl ,source (:ebp ,(argument-stack-offset binding))))))))))))
(defun finalize-code (code funobj frame-map) (labels ((actual-binding (b) @@ -5333,17 +5345,17 @@ ;;;;;;;;;;;;;;;;;; incf-lexvar
(define-find-write-binding-and-type :incf-lexvar (instruction) - (destructuring-bind (binding delta) + (destructuring-bind (binding delta &key protect-registers) (cdr instruction) - (declare (ignore delta)) + (declare (ignore delta protect-registers)) (values binding 'integer)))
-(define-find-read-bindings :incf-lexvar (binding delta) - (declare (ignore delta)) +(define-find-read-bindings :incf-lexvar (binding delta &key protect-registers) + (declare (ignore delta protect-registers)) binding)
(define-extended-code-expander :incf-lexvar (instruction funobj frame-map) - (destructuring-bind (binding delta) + (destructuring-bind (binding delta &key protect-registers) (cdr instruction) (check-type binding binding) (check-type delta integer) @@ -5353,32 +5365,38 @@ "Weird encoded-type: ~S" (binding-store-type binding)) (cond ((and location + (not (binding-lended-p binding)) (multiple-value-call #'encoded-subtypep (values-list (binding-store-type binding)) (type-specifier-encode 'integer))) - #+ignore - (warn "incf ~S type: ~S location: ~S" - binding - (apply #'encoded-type-decode (binding-store-type binding)) - location) + ;; This is an optimized incf that doesn't have to do type-checking. (check-type location (integer 1 *)) `((:addl ,(* delta +movitz-fixnum-factor+) (:ebp ,(stack-frame-offset location))) (:into))) ((multiple-value-call #'encoded-subtypep - (values-list (binding-store-type binding)) - (type-specifier-encode 'integer)) - `(,@(make-load-lexical (ensure-local-binding binding funobj) :eax funobj nil frame-map) - (:addl ,(* delta +movitz-fixnum-factor+) :eax) - (:into) - ,@(make-store-lexical (ensure-local-binding binding funobj) - :eax nil frame-map))) - (t `(,@(make-load-lexical (ensure-local-binding binding funobj) :eax funobj nil frame-map) - (:testb ,+movitz-fixnum-zmask+ :al) - (:jnz '(:sub-program (,(gensym "not-integer-")) - (:int 107) - (:jmp (:pc+ -4)))) + (values-list (binding-store-type binding)) + (type-specifier-encode 'integer)) + (let ((register (chose-free-register protect-registers))) + `(,@(make-load-lexical (ensure-local-binding binding funobj) + register funobj nil frame-map + :protect-registers protect-registers) (:addl ,(* delta +movitz-fixnum-factor+) :eax) (:into) - ,@(make-store-lexical (ensure-local-binding binding funobj) :eax nil frame-map))))))) + ,@(make-store-lexical (ensure-local-binding binding funobj) + register nil frame-map + :protect-registers protect-registers)))) + (t (let ((register (chose-free-register protect-registers))) + `(,@(make-load-lexical (ensure-local-binding binding funobj) + register funobj nil frame-map + :protect-registers protect-registers) + (:testb ,+movitz-fixnum-zmask+ ,(register32-to-low8 register)) + (:jnz '(:sub-program (,(gensym "not-integer-")) + (:int 107) + (:jmp (:pc+ -4)))) + (:addl ,(* delta +movitz-fixnum-factor+) ,register) + (:into) + ,@(make-store-lexical (ensure-local-binding binding funobj) + register nil frame-map + :protect-registers protect-registers))))))))