[movitz-cvs] CVS update: movitz/compiler.lisp

Frode Vatvedt Fjeld ffjeld at common-lisp.net
Sun Aug 28 21:03:54 UTC 2005


Update of /project/movitz/cvsroot/movitz
In directory common-lisp.net:/tmp/cvs-serv6248

Modified Files:
	compiler.lisp 
Log Message:
Many fixes to the compiler. Basic change is that LET init-forms are
compiled with compile-form-unprotected, and that
compile-lexical-variable and compile-self-evaluating return binding
only as "returns", not in the form of "code".

Date: Sun Aug 28 23:03:43 2005
Author: ffjeld

Index: movitz/compiler.lisp
diff -u movitz/compiler.lisp:1.160 movitz/compiler.lisp:1.161
--- movitz/compiler.lisp:1.160	Fri Aug 26 23:42:08 2005
+++ movitz/compiler.lisp	Sun Aug 28 23:03:41 2005
@@ -8,7 +8,7 @@
 ;;;; Created at:    Wed Oct 25 12:30:49 2000
 ;;;; Distribution:  See the accompanying file COPYING.
 ;;;;                
-;;;; $Id: compiler.lisp,v 1.160 2005/08/26 21:42:08 ffjeld Exp $
+;;;; $Id: compiler.lisp,v 1.161 2005/08/28 21:03:41 ffjeld Exp $
 ;;;;                
 ;;;;------------------------------------------------------------------
 
@@ -1510,6 +1510,7 @@
 
 
 (defun optimize-code (unoptimized-code &rest args)
+  #+ignore (print-code 'to-optimize unoptimized-code)
   (if (not *compiler-do-optimize*)
       unoptimized-code
     (apply #'optimize-code-internal
@@ -2883,7 +2884,7 @@
   (let* ((count-init-pc (gethash binding var-counts))
 	 (count (car count-init-pc))
 	 (init-pc (second count-init-pc)))
-    ;; (warn "b ~S: count: ~D, init-pc: ~{~&~A~}" binding count init-pc)
+    #+ignore (warn "b ~S: count: ~D, init-pc: ~{~&~A~}" binding count init-pc)
     (cond
      ((and (not *compiler-allow-transients*)
 	   (typep binding 'function-argument))
@@ -2972,7 +2973,7 @@
 	     (take-note-of-binding (binding &optional storep init-pc)
 	       (let ((count-init-pc (or (gethash binding var-counter)
 					(setf (gethash binding var-counter)
-					  (list 0 nil t)))))
+					  (list 0 nil (not storep))))))
 		 (when init-pc
 		   (assert (not (second count-init-pc)))
 		   (setf (second count-init-pc) init-pc))
@@ -2980,10 +2981,17 @@
 		   (unless (eq binding (binding-target binding))
 		     ;; (break "ewfew: ~S" (gethash (binding-target binding) var-counter))
 		     (take-note-of-binding (binding-target binding)))
+		   (setf (third count-init-pc) t)
 		   (incf (car count-init-pc))))
 	       #+ignore
 	       (when (typep binding 'forwarding-binding)
 		 (take-note-of-binding (forwarding-binding-target binding) storep)))
+	     (take-note-of-init (binding init-pc)
+	       (let ((count-init-pc (or (gethash binding var-counter)
+					(setf (gethash binding var-counter)
+					  (list 0 nil nil)))))
+		 (assert (not (second count-init-pc)))
+		 (setf (second count-init-pc) init-pc)))
 	     (do-discover-variables (code env)
 	       (loop for pc on code as instruction in code
 		   when (listp instruction)
@@ -3028,11 +3036,14 @@
 							     protect-registers protect-carry)
 			       (cdr instruction)
 			     (declare (ignore protect-registers protect-carry init-with-type))
-			     (when init-with-register
+			     (cond
+			      ((not init-with-register)
+			       (take-note-of-init binding pc))
+			      (init-with-register
 			       (take-note-of-binding binding t pc)
 			       (when (and (typep init-with-register 'binding)
 					  (not (typep binding 'forwarding-binding))) ; XXX
-				 (take-note-of-binding init-with-register)))))
+				 (take-note-of-binding init-with-register))))))
 			  (t (mapcar #'take-note-of-binding 
 				     (find-read-bindings instruction))
 			     (mapcar #'record-binding-used ; This is just concerning "unused variable"
@@ -3072,34 +3083,35 @@
 	       (let* ((stack-frame-position (env-floor env))
 		      (bindings-to-locate
 		       (loop for binding being the hash-keys of var-counts
-			   when (eq env (binding-extent-env binding))
-			   unless (let ((variable (binding-name binding)))
-				    (cond
-				     ((not (typep binding 'lexical-binding)))
-				     ((typep binding 'lambda-binding))
-				     ((typep binding 'constant-object-binding))
-				     ((typep binding 'forwarding-binding)
-				      ;; Immediately "assign" to target.
-				      (when (plusp (or (car (gethash binding var-counts)) 0))
-					(setf (new-binding-location binding frame-map)
-					  (forwarding-binding-target binding)))
-				      t)
-				     ((typep binding 'borrowed-binding))
-				     ((typep binding 'funobj-binding))
-				     ((and (typep binding 'fixed-required-function-argument)
-					   (plusp (or (car (gethash binding var-counts)) 0)))
-				      (prog1 nil ; may need lending-cons
-					(setf (new-binding-location binding frame-map)
-					  `(:argument-stack ,(function-argument-argnum binding)))))
-				     ((unless (or (movitz-env-get variable 'ignore nil
-								  (binding-env binding) nil)
-						  (movitz-env-get variable 'ignorable nil
-								  (binding-env binding) nil)
-						  (typep binding 'hidden-rest-function-argument)
-						  (third (gethash binding var-counts)))
-					(warn "Unused variable: ~S"
-					      (binding-name binding))))
-				     ((not (plusp (or (car (gethash binding var-counts)) 0))))))
+			   when
+			     (and (eq env (binding-extent-env binding))
+				  (not (let ((variable (binding-name binding)))
+					 (cond
+					  ((not (typep binding 'lexical-binding)))
+					  ((typep binding 'lambda-binding))
+					  ((typep binding 'constant-object-binding))
+					  ((typep binding 'forwarding-binding)
+					   ;; Immediately "assign" to target.
+					   (when (plusp (or (car (gethash binding var-counts)) 0))
+					     (setf (new-binding-location binding frame-map)
+					       (forwarding-binding-target binding)))
+					   t)
+					  ((typep binding 'borrowed-binding))
+					  ((typep binding 'funobj-binding))
+					  ((and (typep binding 'fixed-required-function-argument)
+						(plusp (or (car (gethash binding var-counts)) 0)))
+					   (prog1 nil ; may need lending-cons
+					     (setf (new-binding-location binding frame-map)
+					       `(:argument-stack ,(function-argument-argnum binding)))))
+					  ((unless (or (movitz-env-get variable 'ignore nil
+								       (binding-env binding) nil)
+						       (movitz-env-get variable 'ignorable nil
+								       (binding-env binding) nil)
+						       (typep binding 'hidden-rest-function-argument)
+						       (third (gethash binding var-counts)))
+					     (warn "Unused variable: ~S"
+						   (binding-name binding))))
+					  ((not (plusp (or (car (gethash binding var-counts)) 0))))))))
 			   collect binding))
 		      (bindings-fun-arg-sorted
 		       (when (eq env function-env)
@@ -3371,6 +3383,7 @@
   (etypecase x
     (symbol x)
     (cons (car x))
+    (constant-object-binding :constant-binding)
     (lexical-binding :lexical-binding)
     (dynamic-binding :dynamic-binding)))
 
@@ -3512,7 +3525,8 @@
   (when (movitz-env-get (binding-name binding) 'ignore nil (binding-env binding))
     (warn "The variable ~S is used even if it was declared ignored."
 	  (binding-name binding)))
-  (let ((protect-registers (cons :edx protect-registers)))
+  (let ((binding (ensure-local-binding binding funobj))
+	(protect-registers (cons :edx protect-registers)))
     (labels ((chose-tmp-register (&optional preferred)
 	       (or tmp-register
 		   (unless (member preferred protect-registers)
@@ -3673,7 +3687,9 @@
 	       (t (make-result-and-returns-glue
 		   result-mode :eax
 		   (install-for-single-value binding binding-location :eax t)))))
-	    (t (case (result-mode-type result-mode)
+	    (t (when (integerp result-mode)
+		 (break "result-mode: ~S" result-mode))
+	     (case (result-mode-type result-mode)
 		 ((:single-value :eax :ebx :ecx :edx :esi :esp :ebp)
 		  (install-for-single-value binding binding-location
 					    (single-value-register result-mode) nil))
@@ -3816,6 +3832,14 @@
 		    (t `((:movl ,source :eax)
 			 (,*compiler-global-segment-prefix*
 			  :call (:edi ,(global-constant-offset 'unbox-u32))))))))))
+	     ((member source +boolean-modes+)
+	      (let ((tmp (chose-free-register protect-registers))
+		    (label (gensym "store-lexical-bool-")))
+		(append `((:movl :edi ,tmp))
+			(list (make-branch-on-boolean source label))
+			(list label)
+			(make-store-lexical binding tmp shared-reference-p funobj frame-map
+					    :protect-registers protect-registers))))
 	     ((not (bindingp source))
 	      (error "Unknown source for store-lexical: ~S" source))
 	     ((binding-singleton source)
@@ -4803,8 +4827,9 @@
 		   `((:init-lexvar ,binding)
 		     ,@(when supplied-p-var
 			 `((:init-lexvar ,supplied-p-binding)))
-		     ,@(compiler-call #'compile-self-evaluating
-			 :form (eval-form (optional-function-argument-init-form binding) env nil)
+		     ,@(compiler-call #'compile-form
+			 :form (list 'muerte.cl:quote
+				     (eval-form (optional-function-argument-init-form binding) env nil))
 			 :funobj funobj
 			 :env env
 			 :result-mode :ebx)
@@ -4912,8 +4937,10 @@
 				    `((:init-lexvar ,supplied-p-binding
 						    :init-with-register :edi
 						    :init-with-type null)))
-				  (compiler-call #'compile-self-evaluating
-				    :form (eval-form (optional-function-argument-init-form binding) env)
+				  (compiler-call #'compile-form
+				    :form (list 'muerte.cl:quote
+						(eval-form (optional-function-argument-init-form binding)
+							   env))
 				    :env env
 				    :funobj funobj
 				    :result-mode :eax)
@@ -5115,6 +5142,11 @@
 	   (lexical-binding
 	    (values (append code
 			    `((:load-lexical ,returns-provided ,desired-result)))
+		    desired-result))
+	   (constant-object-binding
+	    (values (if (eq *movitz-nil* (constant-object returns-provided))
+			nil
+		      `((:jmp ',(operands desired-result))))
 		    desired-result))))
 	(:boolean-branch-on-false
 	 (etypecase (operator returns-provided)
@@ -5144,9 +5176,14 @@
 	   (lexical-binding
 	    (values (append code
 			    `((:load-lexical ,returns-provided ,desired-result)))
+		    desired-result))
+	   (constant-object-binding
+	    (values (if (not (eq *movitz-nil* (constant-object returns-provided)))
+			nil
+		      `((:jmp ',(operands desired-result))))
 		    desired-result))))
 	(:untagged-fixnum-ecx
-	 (case returns-provided
+	 (case (result-mode-type returns-provided)
 	   (:untagged-fixnum-ecx
 	    (values code :untagged-fixnum-ecx))
 	   ((:eax :single-value :multiple-values :function)
@@ -5155,10 +5192,19 @@
 			       :call (:edi ,(global-constant-offset 'unbox-u32)))))
 		    :untagged-fixnum-ecx))
 	   (:ecx
+	    ;; In theory (at least..) ECX can only hold non-pointers, so don't check.
 	    (values (append code
-			    `((:testb ,+movitz-fixnum-zmask+ :cl)
-			      (:jnz '(:sub-program (not-an-integer) (:int 107))) ;
-			      (:sarl ,+movitz-fixnum-shift+ :ecx)))
+			    `((:shrl ,+movitz-fixnum-shift+ :ecx)))
+		    :untagged-fixnum-ecx))
+	   ((:ebx :edx)
+	    (values (append code
+			    `((:movl ,returns-provided :eax)
+			      (,*compiler-global-segment-prefix*
+			       :call (:edi ,(global-constant-offset 'unbox-u32)))))
+		    :untagged-fixnum-ecx))
+	   (:lexical-binding
+	    (values (append code
+			    `((:load-lexical ,returns-provided :untagged-fixnum-ecx)))
 		    :untagged-fixnum-ecx))))
 	((:single-value :eax)
 	 (cond
@@ -5226,11 +5272,6 @@
 	   (values (append code `((:load-lexical ,returns-provided ,desired-result)))
 		   desired-result))
 	  (t (case (operator returns-provided)
-	       #+ignore
-	       (:untagged-fixnum-eax
-		(values (append code
-				`((:leal ((:eax 4)) ,desired-result)))
-			desired-result))
 	       (:nothing
 		(values (append code
 				`((:movl :edi ,desired-result)))
@@ -5337,7 +5378,14 @@
 		      :multiple-values)))))
     (unless new-returns-provided
       (multiple-value-setq (new-code new-returns-provided glue-side-effects-p)
-	(ecase (operator returns-provided)
+	(ecase (result-mode-type returns-provided)
+	  (:constant-binding
+	   (case (result-mode-type desired-result)
+	     ((:eax :ebx :ecx :edx :push :lexical-binding)
+	      (values (append code
+			      `((:load-constant ,(constant-object returns-provided)
+						,desired-result)))
+		      desired-result))))
 	  (#.+boolean-modes+
 	   (make-result-and-returns-glue desired-result :eax
 					 (make-result-and-returns-glue :eax returns-provided code
@@ -5900,6 +5948,12 @@
       (:ignore
        (compiler-values ()
 	 :final-form binding))
+      (t (compiler-values ()
+	   :code nil
+	   :final-form binding
+	   :returns binding
+	   :functional-p t))
+      #+ignore
       (t (let ((returns (ecase (result-mode-type result-mode)
 			  ((:function :multiple-values :eax)
 			   :eax)
@@ -6037,13 +6091,15 @@
 	 (compiler-values (self-eval)
 	   :returns :nothing
 	   :type nil))
-	((:eax :single-value :multiple-values :function)
-	 (compiler-values (self-eval)
-	   :code `((:load-lexical ,binding :eax))
-	   :returns :eax))
 	(t (compiler-values (self-eval)
-	     :code `((:load-lexical ,binding ,result-mode))
-	     :returns result-mode))))))
+	     :returns binding))))))
+;;;	((:eax :single-value :multiple-values :function)
+;;;	 (compiler-values (self-eval)
+;;;	   :code `((:load-lexical ,binding :eax))
+;;;	   :returns :eax))
+;;;	(t (compiler-values (self-eval)
+;;;	     :code `((:load-lexical ,binding ,result-mode))
+;;;	     :returns result-mode))))))
 
 (define-compiler compile-implicit-progn (&all all &form forms &top-level-p top-level-p
 					      &result-mode result-mode)
@@ -6738,7 +6794,7 @@
   (destructuring-bind (object result-mode &key (op :movl))
       (cdr instruction)
     (when (and (eq op :movl) (typep result-mode 'binding))
-      (check-type result-mode 'lexical-binding)
+      (check-type result-mode lexical-binding)
       (values result-mode `(eql ,object)))))
 
 (define-extended-code-expander :load-constant (instruction funobj frame-map)
@@ -6795,330 +6851,333 @@
 	   (destination-location (if (or (not (bindingp destination))
 					 (typep destination 'borrowed-binding))
 				     destination
-				   (new-binding-location (binding-target destination) frame-map)))
+				   (new-binding-location (binding-target destination)
+							 frame-map
+							 :default nil)))
 	   (type0 (apply #'encoded-type-decode (binding-store-type term0)))
 	   (type1 (apply #'encoded-type-decode (binding-store-type term1)))
 	   (result-type (multiple-value-call #'encoded-integer-types-add
 			  (values-list (binding-store-type term0))
 			  (values-list (binding-store-type term1)))))
-;;;      (warn "dest: ~S ~S"
-;;;	    (apply #'encoded-type-decode (binding-store-type destination))
-;;;	    result-type)	    
-;;;      (when (binding-lended-p term0)
-;;;	(warn "Add from lend0: ~S" term0))
-;;;      (when (binding-lended-p term1)
-;;;	(warn "Add from lend1: ~S" term1))
-;;;      (when (and (bindingp destination)
-;;;		 (binding-lended-p destination))
-;;;	(warn "Add for lended dest: ~S" destination))
-;;;      (when (typep destination 'borrowed-binding)
-;;;	(warn "Add for borrowed ~S" destination))
-      (let ((loc0 (new-binding-location (binding-target term0) frame-map :default nil))
-	    (loc1 (new-binding-location (binding-target term1) frame-map :default nil)))
-	#+ignore
-	(warn "add: ~A for ~A" instruction result-type)
-	#+ignore
-	(warn "add for: ~S is ~A, from ~A/~A and ~A/~A."
-	      destination result-type
-	      term0 loc0
-	      term1 loc1)
-	#+ignore
-	(when (eql destination-location 9)
-	  (warn "add for: ~S/~S~%= ~A/~A in ~S~&~A/~A in ~S."
-		destination destination-location
-		term0 loc0 (binding-extent-env (binding-target term0))
-		term1 loc1 (binding-extent-env (binding-target term1)))
-	  (print-code 'load-term1 (make-load-lexical term1 :eax funobj nil frame-map))
-	  (print-code 'load-dest (make-load-lexical destination :eax funobj nil frame-map)))
-	(flet ((make-store (source destination)
-		 (cond
-		  ((eq source destination)
-		   nil)
-		  ((member destination '(:eax :ebx :ecx :edx))
-		   `((:movl ,source ,destination)))
-		  (t (make-store-lexical destination source nil funobj frame-map))))
-	       (make-default-add ()
-		 (when (movitz-subtypep result-type '(unsigned-byte 32))
-		   (warn "Defaulting u32 ADD: ~A/~S = ~A/~S + ~A/~S"
-			 destination-location
-			 destination
-			 loc0 term0
-			 loc1 term1))
-		 (append (cond
-			  ((type-specifier-singleton type0)
-			   (append (make-load-lexical term1 :eax funobj nil frame-map)
-				   (make-load-constant (car (type-specifier-singleton type0))
-						       :ebx funobj frame-map)))
-			  ((type-specifier-singleton type1)
-			   (append (make-load-lexical term0 :eax funobj nil frame-map)
-				   (make-load-constant (car (type-specifier-singleton type1))
-						       :ebx funobj frame-map)))
-			  ((and (eq :eax loc0) (eq :ebx loc1))
-			   nil)
-			  ((and (eq :ebx loc0) (eq :eax loc1))
-			   nil)		; terms order isn't important
-			  ((eq :eax loc1)
-			   (append
-			    (make-load-lexical term0 :ebx funobj nil frame-map)))
-			  (t (append
-			      (make-load-lexical term0 :eax funobj nil frame-map)
-			      (make-load-lexical term1 :ebx funobj nil frame-map))))
-			 `((:movl (:edi ,(global-constant-offset '+)) :esi))
-			 (make-compiled-funcall-by-esi 2)
-			 (etypecase destination
-			   (symbol
-			    (unless (eq destination :eax)
-			      `((:movl :eax ,destination))))
-			   (binding
-			    (make-store-lexical destination :eax nil funobj frame-map))))))
-	  (let ((constant0 (let ((x (type-specifier-singleton type0)))
-			     (when (and x (typep (car x) 'movitz-fixnum))
-			       (movitz-immediate-value (car x)))))
-		(constant1 (let ((x (type-specifier-singleton type1)))
-			     (when (and x (typep (car x) 'movitz-fixnum))
-			       (movitz-immediate-value (car x))))))
-	    (cond
-	     ((type-specifier-singleton result-type)
-	      ;; (break "constant add: ~S" instruction)
-	      (make-load-constant (car (type-specifier-singleton result-type))
-				  destination funobj frame-map))
-	     ((movitz-subtypep type0 '(integer 0 0))
-	      (cond
-	       ((eql destination loc1)
-		#+ignore (break "NOP add: ~S" instruction)
-		nil)
-	       ((and (member destination-location '(:eax :ebx :ecx :edx))
-		     (member loc1 '(:eax :ebx :ecx :edx)))
-		`((:movl ,loc1 ,destination-location)))
-	       ((integerp loc1)
-		(make-load-lexical term1 destination-location funobj nil frame-map))
-	       #+ignore
-	       ((integerp destination-location)
-		(make-store-lexical destination-location loc1 nil funobj frame-map))
-	       (t (break "Unknown X zero-add: ~S" instruction))))
-	     ((movitz-subtypep type1 '(integer 0 0))
-	      ;; (warn "zero-add ~S => ~S [~S]" loc0 destination-location result-type)
-	      (cond
-	       ((eql destination loc0)
-		#+ignore (break "NOP add: ~S" instruction)
-		nil)
-	       ((and (member destination-location '(:eax :ebx :ecx :edx))
-		     (member loc0 '(:eax :ebx :ecx :edx)))
-		`((:movl ,loc0 ,destination-location)))
-	       ((integerp loc0)
-		(make-load-lexical term0 destination-location funobj nil frame-map))
-	       #+ignore
-	       ((integerp destination-location)
-		(make-store-lexical destination-location loc0 nil funobj frame-map))
-	       (t (break "Unknown Y zero-add: ~S" instruction))))
-	     ((and (movitz-subtypep type0 'fixnum)
-		   (movitz-subtypep type1 'fixnum)
-		   (movitz-subtypep result-type 'fixnum))
-	      (assert (not (and constant0 (zerop constant0))))
-	      (assert (not (and constant1 (zerop constant1))))
+      ;; A null location means the binding is unused, in which
+      ;; case there's no need to perform the addition.
+      (when destination-location
+	(let ((loc0 (new-binding-location (binding-target term0) frame-map :default nil))
+	      (loc1 (new-binding-location (binding-target term1) frame-map :default nil)))
+	  #+ignore
+	  (warn "add: ~A for ~A" instruction result-type)
+	  #+ignore
+	  (warn "add for: ~S is ~A, from ~A/~A and ~A/~A."
+		destination result-type
+		term0 loc0
+		term1 loc1)
+	  #+ignore
+	  (when (eql destination-location 9)
+	    (warn "add for: ~S/~S~%= ~A/~A in ~S~&~A/~A in ~S."
+		  destination destination-location
+		  term0 loc0 (binding-extent-env (binding-target term0))
+		  term1 loc1 (binding-extent-env (binding-target term1)))
+	    (print-code 'load-term1 (make-load-lexical term1 :eax funobj nil frame-map))
+	    (print-code 'load-dest (make-load-lexical destination :eax funobj nil frame-map)))
+	  (flet ((make-store (source destination)
+		   (cond
+		    ((eq source destination)
+		     nil)
+		    ((member destination '(:eax :ebx :ecx :edx))
+		     `((:movl ,source ,destination)))
+		    (t (make-store-lexical destination source nil funobj frame-map))))
+		 (make-default-add ()
+		   (when (movitz-subtypep result-type '(unsigned-byte 32))
+		     (warn "Defaulting u32 ADD: ~A/~S = ~A/~S + ~A/~S"
+			   destination-location
+			   destination
+			   loc0 term0
+			   loc1 term1))
+		   (append (cond
+			    ((type-specifier-singleton type0)
+			     (append (make-load-lexical term1 :eax funobj nil frame-map)
+				     (make-load-constant (car (type-specifier-singleton type0))
+							 :ebx funobj frame-map)))
+			    ((type-specifier-singleton type1)
+			     (append (make-load-lexical term0 :eax funobj nil frame-map)
+				     (make-load-constant (car (type-specifier-singleton type1))
+							 :ebx funobj frame-map)))
+			    ((and (eq :eax loc0) (eq :ebx loc1))
+			     nil)
+			    ((and (eq :ebx loc0) (eq :eax loc1))
+			     nil)	; terms order isn't important
+			    ((eq :eax loc1)
+			     (append
+			      (make-load-lexical term0 :ebx funobj nil frame-map)))
+			    (t (append
+				(make-load-lexical term0 :eax funobj nil frame-map)
+				(make-load-lexical term1 :ebx funobj nil frame-map))))
+			   `((:movl (:edi ,(global-constant-offset '+)) :esi))
+			   (make-compiled-funcall-by-esi 2)
+			   (etypecase destination
+			     (symbol
+			      (unless (eq destination :eax)
+				`((:movl :eax ,destination))))
+			     (binding
+			      (make-store-lexical destination :eax nil funobj frame-map))))))
+	    (let ((constant0 (let ((x (type-specifier-singleton type0)))
+			       (when (and x (typep (car x) 'movitz-fixnum))
+				 (movitz-immediate-value (car x)))))
+		  (constant1 (let ((x (type-specifier-singleton type1)))
+			       (when (and x (typep (car x) 'movitz-fixnum))
+				 (movitz-immediate-value (car x))))))
 	      (cond
-	       ((and (not (binding-lended-p (binding-target term0)))
-		     (not (binding-lended-p (binding-target term1)))
-		     (not (and (bindingp destination)
-			       (binding-lended-p (binding-target destination)))))
+	       ((type-specifier-singleton result-type)
+		;; (break "constant add: ~S" instruction)
+		(make-load-constant (car (type-specifier-singleton result-type))
+				    destination funobj frame-map))
+	       ((movitz-subtypep type0 '(integer 0 0))
 		(cond
-		 ((and constant0
-		       (equal loc1 destination-location))
-		  (cond
-		   ((member destination-location '(:eax :ebx :ecx :edx))
-		    `((:addl ,constant0 ,destination-location)))
-		   ((integerp loc1)
-		    `((:addl ,constant0 (:ebp ,(stack-frame-offset loc1)))))
-		   ((eq :argument-stack (operator loc1))
-		    `((:addl ,constant0
-			     (:ebp ,(argument-stack-offset (binding-target term1))))))
-		   (t (error "Don't know how to add this for loc1 ~S" loc1))))
-		 ((and constant0
-		       (integerp destination-location)
-		       (eql term1 destination-location))
-		  (break "untested")
-		  `((:addl ,constant0 (:ebp ,(stack-frame-offset destination-location)))))
-		 ((and constant0
-		       (integerp destination-location)
-		       (member loc1 '(:eax :ebx :ecx :edx)))
-		  (break "check this!")
-		  `((:addl ,constant0 ,loc1)
-		    (:movl ,loc1 (:ebp ,(stack-frame-offset destination-location)))))
-		 ((and (integerp loc0)
-		       (integerp loc1)
-		       (member destination-location '(:eax :ebx :ecx :edx)))
-		  (append `((:movl (:ebp ,(stack-frame-offset loc0)) ,destination-location)
-			    (:addl (:ebp ,(stack-frame-offset loc1)) ,destination-location))))
-		 ((and (integerp destination-location)
-		       (eql loc0 destination-location)
-		       constant1)
-		  `((:addl ,constant1 (:ebp ,(stack-frame-offset destination-location)))))
-		 ((and (integerp destination-location)
-		       (eql loc1 destination-location)
-		       constant0)
-		  `((:addl ,constant0 (:ebp ,(stack-frame-offset destination-location)))))
-		 ((and (member destination-location '(:eax :ebx :ecx :edx))
-		       (eq loc0 :untagged-fixnum-ecx)
-		       constant1)
-		  `((:leal ((:ecx ,+movitz-fixnum-factor+) ,constant1)
-			   ,destination-location)))
-		 ((and (member destination-location '(:eax :ebx :ecx :edx))
-		       (integerp loc1)
-		       constant0)
-		  `((:movl (:ebp ,(stack-frame-offset loc1)) ,destination-location)
-		    (:addl ,constant0 ,destination-location)))
+		 ((eql destination loc1)
+		  #+ignore (break "NOP add: ~S" instruction)
+		  nil)
 		 ((and (member destination-location '(:eax :ebx :ecx :edx))
-		       (integerp loc0)
-		       constant1)
-		  `((:movl (:ebp ,(stack-frame-offset loc0)) ,destination-location)
-		    (:addl ,constant1 ,destination-location)))
-		 ((and (member destination-location '(:eax :ebx :ecx :edx))
-		       (integerp loc0)
-		       (member loc1 '(:eax :ebx :ecx :edx))
-		       (not (eq destination-location loc1)))
-		  `((:movl (:ebp ,(stack-frame-offset loc0)) ,destination-location)
-		    (:addl ,loc1 ,destination-location)))
-		 ((and (member destination-location '(:eax :ebx :ecx :edx))
-		       constant0
 		       (member loc1 '(:eax :ebx :ecx :edx)))
-		  `((:leal (,loc1 ,constant0) ,destination-location)))
+		  `((:movl ,loc1 ,destination-location)))
+		 ((integerp loc1)
+		  (make-load-lexical term1 destination funobj nil frame-map))
+		 #+ignore
+		 ((integerp destination-location)
+		  (make-store-lexical destination-location loc1 nil funobj frame-map))
+		 (t (break "Unknown X zero-add: ~S" instruction))))
+	       ((movitz-subtypep type1 '(integer 0 0))
+		;; (warn "zero-add ~S => ~S [~S]" loc0 destination-location result-type)
+		(cond
+		 ((eql destination-location loc0)
+		  #+ignore (break "NOP add: ~S" instruction)
+		  nil)
 		 ((and (member destination-location '(:eax :ebx :ecx :edx))
-		       constant1
 		       (member loc0 '(:eax :ebx :ecx :edx)))
-		  `((:leal (,loc0 ,constant1) ,destination-location)))
-		 ((and (member destination-location '(:eax :ebx :ecx :edx))
-		       constant0
-		       (eq :argument-stack (operator loc1)))
-		  `((:movl (:ebp ,(argument-stack-offset (binding-target term1)))
-			   ,destination-location)
-		    (:addl ,constant0 ,destination-location)))
-		 ((and (member destination-location '(:eax :ebx :ecx :edx))
-		       constant1
-		       (eq :argument-stack (operator loc0)))
-		  `((:movl (:ebp ,(argument-stack-offset (binding-target term0)))
-			   ,destination-location)
-		    (:addl ,constant1 ,destination-location)))
-		 (t (warn "Unknown fixnum ADD: ~A/~S = ~A/~S + ~A/~S"
-			  destination-location
-			  destination
-			  loc0 term0
-			  loc1 term1)
-		    #+ignore (warn "map: ~A" frame-map)
-;;; 	    (warn "ADDI: ~S" instruction)
-		    (append (cond
-			     ((type-specifier-singleton type0)
-			      (append (make-load-lexical term1 :eax funobj nil frame-map)
-				      (make-load-constant (car (type-specifier-singleton type0))
-							  :ebx funobj frame-map)))
-			     ((type-specifier-singleton type1)
-			      (append (make-load-lexical term0 :eax funobj nil frame-map)
-				      (make-load-constant (car (type-specifier-singleton type1))
-							  :ebx funobj frame-map)))
-			     ((and (eq :eax loc0) (eq :ebx loc1))
-			      nil)
-			     ((and (eq :ebx loc0) (eq :eax loc1))
-			      nil)	; terms order isn't important
-			     ((eq :eax loc1)
-			      (append
-			       (make-load-lexical term0 :ebx funobj nil frame-map)))
-			     (t (append
-				 (make-load-lexical term0 :eax funobj nil frame-map)
-				 (make-load-lexical term1 :ebx funobj nil frame-map))))
-			    `((:movl (:edi ,(global-constant-offset '+)) :esi))
-			    (make-compiled-funcall-by-esi 2)
-			    (etypecase destination
-			      (symbol
-			       (unless (eq destination :eax)
-				 `((:movl :eax ,destination))))
-			      (binding
-			       (make-store-lexical destination :eax nil funobj frame-map)))))))
-	       ((and constant0
-		     (integerp destination-location)
-		     (eql loc1 destination-location)
-		     (binding-lended-p (binding-target destination)))
-		(assert (binding-lended-p (binding-target term1)))
-		(append (make-load-lexical destination :eax funobj t frame-map)
-			`((:addl ,constant0 (-1 :eax)))))
-	       ((warn "~S" (list (and (bindingp destination)
-				      (binding-lended-p (binding-target destination)))
-				 (binding-lended-p (binding-target term0))
-				 (binding-lended-p (binding-target term1)))))
-	       (t (warn "Unknown fixnum add: ~S" instruction)
-		  (make-default-add))))
-	     ((and (movitz-subtypep type0 'fixnum)
-		   (movitz-subtypep type1 'fixnum))
-	      (flet ((mkadd-into (src destreg)
-		       (assert (eq destreg :eax) (destreg)
-			 "Movitz' INTO protocol says the overflowed value must be in EAX, ~
-but it's requested to be in ~S."
-			 destreg)
-		       (let ((srcloc (new-binding-location (binding-target src) frame-map)))
-			 (unless (eql srcloc loc1) (break))
-			 (if (integerp srcloc)
-			     `((:addl (:ebp ,(stack-frame-offset srcloc))
-				      ,destreg)
-			       (:into))
-			   (ecase (operator srcloc)
-			     ((:eax :ebx :ecx :edx)
-			      `((:addl ,srcloc ,destreg)
-				(:into)))
-			     ((:argument-stack)
-			      `((:addl (:ebx ,(argument-stack-offset src))
-				       ,destreg)
-				(:into)))
-			     )))))
+		  `((:movl ,loc0 ,destination-location)))
+		 ((member loc0 '(:eax :ebx :ecx :edx))
+		  (make-store-lexical destination loc0 nil funobj frame-map))
+		 ((integerp loc0)
+		  (make-load-lexical term0 destination funobj nil frame-map))
+		 (t (break "Unknown Y zero-add: ~S" instruction))))
+	       ((and (movitz-subtypep type0 'fixnum)
+		     (movitz-subtypep type1 'fixnum)
+		     (movitz-subtypep result-type 'fixnum))
+		(assert (not (and constant0 (zerop constant0))))
+		(assert (not (and constant1 (zerop constant1))))
 		(cond
-		 ((and (not constant0)
-		       (not constant1)
-		       (not (binding-lended-p (binding-target term0)))
+		 ((and (not (binding-lended-p (binding-target term0)))
 		       (not (binding-lended-p (binding-target term1)))
 		       (not (and (bindingp destination)
 				 (binding-lended-p (binding-target destination)))))
 		  (cond
-		   ((and (not (eq loc0 :untagged-fixnum-ecx))
-			 (not (eq loc1 :untagged-fixnum-ecx))
-			 (not (eq destination-location :untagged-fixnum-ecx)))
-		    (append (cond
-			     ((and (eq loc0 :eax) (eq loc1 :eax))
-			      `((:addl :eax :eax)
-				(:into)))
-			     ((eq loc0 :eax)
-			      (mkadd-into term1 :eax))
-			     ((eq loc1 :eax)
-			      (mkadd-into term0 :eax))
-			     (t (append (make-load-lexical term0 :eax funobj nil frame-map
-							   :protect-registers (list loc1))
-					(mkadd-into term1 :eax))))
+		   ((and constant0
+			 (equal loc1 destination-location))
+		    (cond
+		     ((member destination-location '(:eax :ebx :ecx :edx))
+		      `((:addl ,constant0 ,destination-location)))
+		     ((integerp loc1)
+		      `((:addl ,constant0 (:ebp ,(stack-frame-offset loc1)))))
+		     ((eq :argument-stack (operator loc1))
+		      `((:addl ,constant0
+			       (:ebp ,(argument-stack-offset (binding-target term1))))))
+		     (t (error "Don't know how to add this for loc1 ~S" loc1))))
+		   ((and constant0
+			 (integerp destination-location)
+			 (eql term1 destination-location))
+		    (break "untested")
+		    `((:addl ,constant0 (:ebp ,(stack-frame-offset destination-location)))))
+		   ((and constant0
+			 (integerp destination-location)
+			 (member loc1 '(:eax :ebx :ecx :edx)))
+		    `((:addl ,constant0 ,loc1)
+		      (:movl ,loc1 (:ebp ,(stack-frame-offset destination-location)))))
+		   ((and (integerp loc0)
+			 (integerp loc1)
+			 (member destination-location '(:eax :ebx :ecx :edx)))
+		    (append `((:movl (:ebp ,(stack-frame-offset loc0)) ,destination-location)
+			      (:addl (:ebp ,(stack-frame-offset loc1)) ,destination-location))))
+		   ((and (integerp destination-location)
+			 (eql loc0 destination-location)
+			 constant1)
+		    `((:addl ,constant1 (:ebp ,(stack-frame-offset destination-location)))))
+		   ((and (integerp destination-location)
+			 (eql loc1 destination-location)
+			 constant0)
+		    `((:addl ,constant0 (:ebp ,(stack-frame-offset destination-location)))))
+		   ((and (member destination-location '(:eax :ebx :ecx :edx))
+			 (eq loc0 :untagged-fixnum-ecx)
+			 constant1)
+		    `((:leal ((:ecx ,+movitz-fixnum-factor+) ,constant1)
+			     ,destination-location)))
+		   ((and (member destination-location '(:eax :ebx :ecx :edx))
+			 (integerp loc1)
+			 constant0)
+		    `((:movl (:ebp ,(stack-frame-offset loc1)) ,destination-location)
+		      (:addl ,constant0 ,destination-location)))
+		   ((and (member destination-location '(:eax :ebx :ecx :edx))
+			 (integerp loc0)
+			 constant1)
+		    `((:movl (:ebp ,(stack-frame-offset loc0)) ,destination-location)
+		      (:addl ,constant1 ,destination-location)))
+		   ((and (member destination-location '(:eax :ebx :ecx :edx))
+			 (integerp loc0)
+			 (member loc1 '(:eax :ebx :ecx :edx))
+			 (not (eq destination-location loc1)))
+		    `((:movl (:ebp ,(stack-frame-offset loc0)) ,destination-location)
+		      (:addl ,loc1 ,destination-location)))
+		   ((and (member destination-location '(:eax :ebx :ecx :edx))
+			 constant0
+			 (member loc1 '(:eax :ebx :ecx :edx)))
+		    `((:leal (,loc1 ,constant0) ,destination-location)))
+		   ((and (member destination-location '(:eax :ebx :ecx :edx))
+			 constant1
+			 (member loc0 '(:eax :ebx :ecx :edx)))
+		    `((:leal (,loc0 ,constant1) ,destination-location)))
+		   ((and (member destination-location '(:eax :ebx :ecx :edx))
+			 constant0
+			 (eq :argument-stack (operator loc1)))
+		    `((:movl (:ebp ,(argument-stack-offset (binding-target term1)))
+			     ,destination-location)
+		      (:addl ,constant0 ,destination-location)))
+		   ((and (member destination-location '(:eax :ebx :ecx :edx))
+			 constant1
+			 (eq :argument-stack (operator loc0)))
+		    `((:movl (:ebp ,(argument-stack-offset (binding-target term0)))
+			     ,destination-location)
+		      (:addl ,constant1 ,destination-location)))
+		   (constant0
+		    (append (make-load-lexical term1 :eax funobj nil frame-map)
+			    `((:addl ,constant0 :eax))
 			    (make-store :eax destination)))
-		  (t (make-default-add)
-		      #+ignore
-		      (append (make-load-lexical term0 :untagged-fixnum-ecx funobj nil frame-map)
-			      `((,*compiler-local-segment-prefix*
-				 :movl :ecx (:edi ,(global-constant-offset 'raw-scratch0))))
-			      (make-load-lexical term1 :untagged-fixnum-ecx funobj nil frame-map)
-			      `((,*compiler-local-segment-prefix*
-				 :addl (:edi ,(global-constant-offset 'raw-scratch0)) :ecx))
-			      (if (integerp destination-location)
-				  `((,*compiler-local-segment-prefix*
-				     :call (:edi ,(global-constant-offset 'box-u32-ecx)))
-				    (:movl :eax (:ebp ,(stack-frame-offset destination-location))))
-				(ecase (operator destination-location)
-				  ((:untagged-fixnum-ecx)
-				   nil)
-				  ((:eax)
-				   `((,*compiler-local-segment-prefix*
-				      :call (:edi ,(global-constant-offset 'box-u32-ecx)))))
-				  ((:ebx :ecx :edx)
-				   `((,*compiler-local-segment-prefix*
-				      :call (:edi ,(global-constant-offset 'box-u32-ecx)))
-				     (:movl :eax ,destination-location)))
-				  ((:argument-stack)
-				   `((,*compiler-local-segment-prefix*
-				      :call (:edi ,(global-constant-offset 'box-u32-ecx)))
-				     (:movl :eax (:ebp ,(argument-stack-offset
-							 (binding-target destination))))))))))))
-		 (t (make-default-add)))))
-	     (t (make-default-add)))))))))
+		   (constant1
+		    (append (make-load-lexical term0 :eax funobj nil frame-map)
+			    `((:addl ,constant1 :eax))
+			    (make-store :eax destination)))
+		   ((eql loc0 loc1)
+		    (append (make-load-lexical term0 :eax funobj nil frame-map)
+			    `((:addl :eax :eax))
+			    (make-store :eax destination)))
+		   (t (warn "Unknown fixnum ADD: ~A/~S = ~A/~S + ~A/~S"
+			    destination-location
+			    destination
+			    loc0 term0
+			    loc1 term1)
+		      #+ignore (warn "map: ~A" frame-map)
+;;; 	    (warn "ADDI: ~S" instruction)
+		      (append (cond
+			       ((type-specifier-singleton type0)
+				(append (make-load-lexical term1 :eax funobj nil frame-map)
+					(make-load-constant (car (type-specifier-singleton type0))
+							    :ebx funobj frame-map)))
+			       ((type-specifier-singleton type1)
+				(append (make-load-lexical term0 :eax funobj nil frame-map)
+					(make-load-constant (car (type-specifier-singleton type1))
+							    :ebx funobj frame-map)))
+			       ((and (eq :eax loc0) (eq :ebx loc1))
+				nil)
+			       ((and (eq :ebx loc0) (eq :eax loc1))
+				nil)	; terms order isn't important
+			       ((eq :eax loc1)
+				(append
+				 (make-load-lexical term0 :ebx funobj nil frame-map)))
+			       (t (append
+				   (make-load-lexical term0 :eax funobj nil frame-map)
+				   (make-load-lexical term1 :ebx funobj nil frame-map))))
+			      `((:movl (:edi ,(global-constant-offset '+)) :esi))
+			      (make-compiled-funcall-by-esi 2)
+			      (etypecase destination
+				(symbol
+				 (unless (eq destination :eax)
+				   `((:movl :eax ,destination))))
+				(binding
+				 (make-store-lexical destination :eax nil funobj frame-map)))))))
+		 ((and constant0
+		       (integerp destination-location)
+		       (eql loc1 destination-location)
+		       (binding-lended-p (binding-target destination)))
+		  (assert (binding-lended-p (binding-target term1)))
+		  (append (make-load-lexical destination :eax funobj t frame-map)
+			  `((:addl ,constant0 (-1 :eax)))))
+		 ((warn "~S" (list (and (bindingp destination)
+					(binding-lended-p (binding-target destination)))
+				   (binding-lended-p (binding-target term0))
+				   (binding-lended-p (binding-target term1)))))
+		 (t (warn "Unknown fixnum add: ~S" instruction)
+		    (make-default-add))))
+	       ((and (movitz-subtypep type0 'fixnum)
+		     (movitz-subtypep type1 'fixnum))
+		(flet ((mkadd-into (src destreg)
+			 (assert (eq destreg :eax) (destreg)
+			   "Movitz' INTO protocol says the overflowed value must be in EAX, ~
+but it's requested to be in ~S."
+			   destreg)
+			 (let ((srcloc (new-binding-location (binding-target src) frame-map)))
+			   (unless (eql srcloc loc1) (break))
+			   (if (integerp srcloc)
+			       `((:addl (:ebp ,(stack-frame-offset srcloc))
+					,destreg)
+				 (:into))
+			     (ecase (operator srcloc)
+			       ((:eax :ebx :ecx :edx)
+				`((:addl ,srcloc ,destreg)
+				  (:into)))
+			       ((:argument-stack)
+				`((:addl (:ebx ,(argument-stack-offset src))
+					 ,destreg)
+				  (:into)))
+			       )))))
+		  (cond
+		   ((and (not constant0)
+			 (not constant1)
+			 (not (binding-lended-p (binding-target term0)))
+			 (not (binding-lended-p (binding-target term1)))
+			 (not (and (bindingp destination)
+				   (binding-lended-p (binding-target destination)))))
+		    (cond
+		     ((and (not (eq loc0 :untagged-fixnum-ecx))
+			   (not (eq loc1 :untagged-fixnum-ecx))
+			   (not (eq destination-location :untagged-fixnum-ecx)))
+		      (append (cond
+			       ((and (eq loc0 :eax) (eq loc1 :eax))
+				`((:addl :eax :eax)
+				  (:into)))
+			       ((eq loc0 :eax)
+				(mkadd-into term1 :eax))
+			       ((eq loc1 :eax)
+				(mkadd-into term0 :eax))
+			       (t (append (make-load-lexical term0 :eax funobj nil frame-map
+							     :protect-registers (list loc1))
+					  (mkadd-into term1 :eax))))
+			      (make-store :eax destination)))
+		     (t (make-default-add)
+			#+ignore
+			(append (make-load-lexical term0 :untagged-fixnum-ecx funobj nil frame-map)
+				`((,*compiler-local-segment-prefix*
+				   :movl :ecx (:edi ,(global-constant-offset 'raw-scratch0))))
+				(make-load-lexical term1 :untagged-fixnum-ecx funobj nil frame-map)
+				`((,*compiler-local-segment-prefix*
+				   :addl (:edi ,(global-constant-offset 'raw-scratch0)) :ecx))
+				(if (integerp destination-location)
+				    `((,*compiler-local-segment-prefix*
+				       :call (:edi ,(global-constant-offset 'box-u32-ecx)))
+				      (:movl :eax (:ebp ,(stack-frame-offset destination-location))))
+				  (ecase (operator destination-location)
+				    ((:untagged-fixnum-ecx)
+				     nil)
+				    ((:eax)
+				     `((,*compiler-local-segment-prefix*
+					:call (:edi ,(global-constant-offset 'box-u32-ecx)))))
+				    ((:ebx :ecx :edx)
+				     `((,*compiler-local-segment-prefix*
+					:call (:edi ,(global-constant-offset 'box-u32-ecx)))
+				       (:movl :eax ,destination-location)))
+				    ((:argument-stack)
+				     `((,*compiler-local-segment-prefix*
+					:call (:edi ,(global-constant-offset 'box-u32-ecx)))
+				       (:movl :eax (:ebp ,(argument-stack-offset
+							   (binding-target destination))))))))))))
+		   (t (make-default-add)))))
+	       (t (make-default-add))))))))))
 
 ;;;;;;;
 




More information about the Movitz-cvs mailing list