Update of /project/movitz/cvsroot/movitz
In directory common-lisp.net:/tmp/cvs-serv17081
Modified Files:
compiler.lisp
Log Message:
Added code to align calls such that return-addresses are
distinguisable from immediate values.
Date: Thu Sep 2 11:16:43 2004
Author: ffjeld
Index: movitz/compiler.lisp
diff -u movitz/compiler.lisp:1.97 movitz/compiler.lisp:1.98
--- movitz/compiler.lisp:1.97 Thu Aug 19 02:22:02 2004
+++ movitz/compiler.lisp Thu Sep 2 11:16:42 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.97 2004/08/19 00:22:02 ffjeld Exp $
+;;;; $Id: compiler.lisp,v 1.98 2004/09/02 09:16:42 ffjeld Exp $
;;;;
;;;;------------------------------------------------------------------
@@ -98,6 +98,28 @@
(or (member (car list) (cdr list))
(duplicatesp (cdr list)))))
+(defun compute-call-extra-prefix (instr env size)
+ (let* ((return-pointer-tag (ldb (byte 3 0)
+ (+ (ia-x86::assemble-env-current-pc env)
+ size))))
+ (cond
+ ((not (and (ia-x86::instruction-operands instr)
+ (typep (car (ia-x86::instruction-operands instr))
+ 'ia-x86::operand-indirect-register)
+ (eq 'ia-x86::esi
+ (ia-x86::operand-register (car (ia-x86::instruction-operands instr))))))
+ nil)
+ ((or (= (tag :even-fixnum) return-pointer-tag)
+ (= (tag :odd-fixnum) return-pointer-tag))
+ ;; Insert a NOP
+ '(#x90))
+ ((= 3 return-pointer-tag)
+ ;; Insert two NOPs, 3 -> 5
+ '(#x90 #x90))
+ ((= (tag :character) return-pointer-tag)
+ ;; Insert three NOPs, 2 -> 5
+ '(#x90 #x90 #x90)))))
+
(defun make-compiled-primitive (form environment top-level-p docstring)
"Primitive functions have no funobj, no stack-frame, and no implied
parameter/return value passing conventions."
@@ -113,14 +135,16 @@
(resolved-code (finalize-code body-code nil nil))
(function-code (ia-x86:read-proglist resolved-code)))
(multiple-value-bind (code-vector symtab)
- (ia-x86:proglist-encode :octet-vector
- :32-bit
- #x00000000
- function-code
- :symtab-lookup
- #'(lambda (label)
- (case label
- (:nil-value (image-nil-word *image*)))))
+ (let ((ia-x86:*instruction-compute-extra-prefix-map*
+ '((:call . compute-call-extra-prefix))))
+ (ia-x86:proglist-encode :octet-vector
+ :32-bit
+ #x00000000
+ function-code
+ :symtab-lookup
+ #'(lambda (label)
+ (case label
+ (:nil-value (image-nil-word *image*))))))
(values (make-movitz-vector (length code-vector)
:element-type 'code
:initial-contents code-vector)
@@ -888,27 +912,29 @@
(defun assemble-funobj (funobj combined-code)
(multiple-value-bind (code-vector code-symtab)
- (ia-x86:proglist-encode :octet-vector :32-bit #x00000000
- (ia-x86:read-proglist (append combined-code
- `((% bytes 8 0 0 0))))
- :symtab-lookup
- (lambda (label)
- (case label
- (:nil-value (image-nil-word *image*))
- (t (let ((set (cdr (assoc label
- (movitz-funobj-jumpers-map funobj)))))
- (when set
- (let ((pos (search set (movitz-funobj-const-list funobj)
- :end2 (movitz-funobj-num-jumpers funobj))))
- (assert pos ()
- "Couldn't find for ~s set ~S in ~S."
- label set (subseq (movitz-funobj-const-list funobj)
- 0 (movitz-funobj-num-jumpers funobj)))
- (* 4 pos))))))))
+ (let ((ia-x86:*instruction-compute-extra-prefix-map*
+ '((:call . compute-call-extra-prefix))))
+ (ia-x86:proglist-encode :octet-vector :32-bit #x00000000
+ (ia-x86:read-proglist (append combined-code
+ #+ignore `((% bytes 8 0 0 0))))
+ :symtab-lookup
+ (lambda (label)
+ (case label
+ (:nil-value (image-nil-word *image*))
+ (t (let ((set (cdr (assoc label
+ (movitz-funobj-jumpers-map funobj)))))
+ (when set
+ (let ((pos (search set (movitz-funobj-const-list funobj)
+ :end2 (movitz-funobj-num-jumpers funobj))))
+ (assert pos ()
+ "Couldn't find for ~s set ~S in ~S."
+ label set (subseq (movitz-funobj-const-list funobj)
+ 0 (movitz-funobj-num-jumpers funobj)))
+ (* 4 pos)))))))))
(setf (movitz-funobj-symtab funobj) code-symtab)
- (let ((code-length (- (length code-vector) 3)))
- (assert (not (mismatch #(0 0 0) code-vector :start2 code-length)) ()
- "No space in code-vector was allocated for entry-points.")
+ (let ((code-length (- (length code-vector) 3 -3)))
+;;; (assert (not (mismatch #(0 0 0) code-vector :start2 code-length)) ()
+;;; "No space in code-vector was allocated for entry-points.")
(setf (fill-pointer code-vector) code-length)
;; debug info
(setf (ldb (byte 1 5) (slot-value funobj 'debug-info))
@@ -921,16 +947,17 @@
(setf (ldb (byte 5 0) (slot-value funobj 'debug-info)) x))
(t (warn "Can't encode start-stack-frame-setup label ~D into debug-info for ~S."
x (movitz-funobj-name funobj)))))
- (loop for ((entry-label slot-name) . rest) on '((entry%1op code-vector%1op)
- (entry%2op code-vector%2op)
- (entry%3op code-vector%3op))
+ (loop for ((entry-label slot-name)) on '((entry%1op code-vector%1op)
+ (entry%2op code-vector%2op)
+ (entry%3op code-vector%3op))
do (cond
((assoc entry-label code-symtab)
(let ((offset (cdr (assoc entry-label code-symtab))))
(setf (slot-value funobj slot-name)
(cons offset funobj))
- (when (< offset #x100)
- (vector-push offset code-vector))))
+ #+ignore (when (< offset #x100)
+ (vector-push offset code-vector))))
+ #+ignore
((some (lambda (label) (assoc label code-symtab))
(mapcar #'car rest))
(vector-push 0 code-vector))))
@@ -4394,14 +4421,16 @@
(not last-optional-p))
`((:pushl :ebx))) ; protect ebx
,@(if (optional-function-argument-init-form binding)
- (append '((:pushl :ecx))
+ (append `((:shll ,+movitz-fixnum-shift+ :ecx)
+ (:pushl :ecx))
(when (= 0 (function-argument-argnum binding))
`((:pushl :ebx)))
init-code-edx
`((:store-lexical ,binding :edx :type t))
(when (= 0 (function-argument-argnum binding))
`((:popl :ebx)))
- `((:popl :ecx)))
+ `((:popl :ecx)
+ (:shrl ,+movitz-fixnum-shift+ :ecx)))
(progn (error "Unsupported situation.")
#+ignore `((:store-lexical ,binding :edi :type null))))
,@(when (and (= 0 (function-argument-argnum binding))
@@ -5511,13 +5540,7 @@
((:function :multiple-values :eax)
:eax)
(:lexical-binding
- ;; We can use ECX as temporary storage,
- ;; because this value will be reachable
- ;; from at least one variable.
- ;; XXXX But, probably we shouldn't decide
- ;; on this here, rather use binding
- ;; as result-mode in :load-lexical.
- result-mode #+ignore :ecx)
+ result-mode)
((:ebx :ecx :edx :esi :push
:untagged-fixnum-eax
:untagged-fixnum-ecx
@@ -5619,13 +5642,18 @@
:type `(eql ,movitz-obj)
:final-form binding
:functional-p t)
- (if (eq :ignore (operator result-mode))
- (compiler-values (self-eval)
- :returns :nothing
- :type nil)
- (compiler-values (self-eval)
- :code `((:load-lexical ,binding ,result-mode))
- :returns result-mode)))))
+ (case (operator result-mode)
+ (:ignore
+ (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))))))
(define-compiler compile-implicit-progn (&all all &form forms &top-level-p top-level-p
&result-mode result-mode)
@@ -5731,6 +5759,39 @@
return-mode)
`((:jmp ',to-label)))))
(t (error "unknown!")))))
+
+(defun make-compiled-push-current-values ()
+ "Return code that pushes the current values onto the stack, and returns
+in ECX the number of values (as fixnum)."
+ (let ((not-single-value (gensym "not-single-value-"))
+ (push-values-done (gensym "push-values-done-"))
+ (push-values-loop (gensym "push-values-loop-")))
+ `((:jc ',not-single-value)
+ (:movl 4 :ecx)
+ (:pushl :eax)
+ (:jmp ',push-values-done)
+ ,not-single-value
+ (:shll ,+movitz-fixnum-shift+ :ecx)
+ (:jz ',push-values-done)
+ (:xorl :edx :edx)
+ (:pushl :eax)
+ (:addl 4 :edx)
+ (:cmpl :edx :ecx)
+ (:je ',push-values-done)
+ (:pushl :ebx)
+ (:addl 4 :edx)
+ (:cmpl :edx :ecx)
+ (:je ',push-values-done)
+ ,push-values-loop
+ (:locally (:pushl (:edi (:edi-offset values) :edx -8)))
+ (:addl 4 :edx)
+ (:cmpl :edx :ecx)
+ (:jne ',push-values-loop)
+ ,push-values-done)))
+
+;;;(:load-lexical ,numargs-binding :eax)
+;;; (:addl :ecx :eax)
+;;; (:store-lexical ,numargs-binding :eax :type fixnum))))
(defun stack-delta (inner-env outer-env)
"Calculate the amount of stack-space used (in 32-bit stack slots) at the time