Update of /project/movitz/cvsroot/movitz/losp/muerte
In directory common-lisp.net:/tmp/cvs-serv4874
Modified Files:
memref.lisp
Log Message:
*** empty log message ***
Date: Sun May 22 00:37:32 2005
Author: ffjeld
Index: movitz/losp/muerte/memref.lisp
diff -u movitz/losp/muerte/memref.lisp:1.45 movitz/losp/muerte/memref.lisp:1.46
--- movitz/losp/muerte/memref.lisp:1.45 Fri Apr 15 09:03:47 2005
+++ movitz/losp/muerte/memref.lisp Sun May 22 00:37:32 2005
@@ -10,7 +10,7 @@
;;;; Author: Frode Vatvedt Fjeld <frodef(a)acm.org>
;;;; Created at: Tue Mar 6 21:25:49 2001
;;;;
-;;;; $Id: memref.lisp,v 1.45 2005/04/15 07:03:47 ffjeld Exp $
+;;;; $Id: memref.lisp,v 1.46 2005/05/21 22:37:32 ffjeld Exp $
;;;;
;;;;------------------------------------------------------------------
@@ -18,15 +18,9 @@
(in-package muerte)
-(define-compiler-macro memref (&whole form object offset
- &key (index 0) (type :lisp) (localp nil) (endian :host)
- (physicalp nil)
- &environment env)
- (if (or (not (movitz:movitz-constantp type env))
- (not (movitz:movitz-constantp localp env))
- (not (movitz:movitz-constantp endian env))
- (not (movitz:movitz-constantp physicalp env)))
- form
+(eval-when (:compile-toplevel)
+ (defun extract-constant-delta (form env)
+ "Try to extract at compile-time an integer offset from form, repeatedly."
(labels ((sub-extract-constant-delta (form)
"Try to extract at compile-time an integer offset from form."
(cond
@@ -49,369 +43,329 @@
(incf x sub-value)
(push sub-form f))
finally (return (values x (cons '+ (nreverse f))))))))
- (t #+ignore (warn "extract from: ~S" form)
- (values 0 form))))))
- (extract-constant-delta (form)
- "Try to extract at compile-time an integer offset from form, repeatedly."
- (multiple-value-bind (constant-term variable-term)
- (sub-extract-constant-delta form)
- (if (= 0 constant-term)
- (values 0 variable-term)
- (multiple-value-bind (sub-constant-term sub-variable-term)
- (extract-constant-delta variable-term)
- (values (+ constant-term sub-constant-term)
- sub-variable-term))))))
- (multiple-value-bind (constant-index index)
- (extract-constant-delta index)
- (multiple-value-bind (constant-offset offset)
- (extract-constant-delta offset)
- (flet ((offset-by (element-size)
- (+ constant-offset (* constant-index element-size))))
- #+ignore
- (warn "o: ~S, co: ~S, i: ~S, ci: ~S"
- offset constant-offset
- index constant-index)
- (let ((type (movitz:movitz-eval type env))
- (physicalp (movitz:movitz-eval physicalp env)))
- (when (and physicalp (not (eq type :unsigned-byte32)))
- (warn "(memref physicalp) unsupported for type ~S." type))
- (case type
- (:unsigned-byte8
+ (t (values 0 form)))))))
+ (multiple-value-bind (constant-term variable-term)
+ (sub-extract-constant-delta form)
+ (if (= 0 constant-term)
+ (values 0 variable-term)
+ (multiple-value-bind (sub-constant-term sub-variable-term)
+ (extract-constant-delta variable-term env)
+ (values (+ constant-term sub-constant-term)
+ sub-variable-term)))))))
+
+(define-compiler-macro memref (&whole form object offset
+ &key (index 0) (type :lisp) (localp nil) (endian :host)
+ (physicalp nil)
+ &environment env)
+ (if (or (not (movitz:movitz-constantp type env))
+ (not (movitz:movitz-constantp localp env))
+ (not (movitz:movitz-constantp endian env))
+ (not (movitz:movitz-constantp physicalp env)))
+ form
+ (multiple-value-bind (constant-index index)
+ (extract-constant-delta index env)
+ (multiple-value-bind (constant-offset offset)
+ (extract-constant-delta offset env)
+ (flet ((offset-by (element-size)
+ (+ constant-offset (* constant-index element-size))))
+ #+ignore
+ (warn "o: ~S, co: ~S, i: ~S, ci: ~S"
+ offset constant-offset
+ index constant-index)
+ (let ((type (movitz:movitz-eval type env))
+ (physicalp (movitz:movitz-eval physicalp env)))
+ (when (and physicalp (not (eq type :unsigned-byte32)))
+ (warn "(memref physicalp) unsupported for type ~S." type))
+ (case type
+ (:unsigned-byte8
+ (cond
+ ((and (eql 0 offset) (eql 0 index))
+ `(with-inline-assembly (:returns :untagged-fixnum-ecx :type (unsigned-byte 8))
+ (:compile-form (:result-mode :eax) ,object)
+ (:movzxb (:eax ,(offset-by 1)) :ecx)))
+ ((eql 0 index)
+ (let ((object-var (gensym "memref-object-"))
+ (offset-var (gensym "memref-offset-")))
+ `(let ((,object-var ,object)
+ (,offset-var ,offset))
+ (with-inline-assembly (:returns :untagged-fixnum-ecx
+ :type (unsigned-byte 8))
+ (:compile-two-forms (:eax :untagged-fixnum-ecx) ,object-var ,offset-var)
+ ;; (:sarl ,movitz:+movitz-fixnum-shift+ :ecx)
+ (:movzxb (:eax :ecx ,(offset-by 1)) :ecx)
+ ))))
+ ((eql 0 offset)
+ `(with-inline-assembly (:returns :untagged-fixnum-ecx :type (unsigned-byte 8))
+ (:compile-two-forms (:eax :untagged-fixnum-ecx) ,object ,index)
+ (:movzxb (:eax :ecx ,(offset-by 1)) :ecx)))
+ (t (let ((object-var (gensym "memref-object-")))
+ `(let ((,object-var ,object))
+ (with-inline-assembly (:returns :untagged-fixnum-ecx :type (unsigned-byte 8))
+ (:compile-two-forms (:ecx :ebx) ,offset ,index)
+ (:load-lexical (:lexical-binding ,object-var) :eax)
+ (:addl :ebx :ecx) ; index += offset
+ (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
+ (:movzxb (:eax :ecx ,(offset-by 1)) :ecx)))))))
+ (:unsigned-byte16
+ (let* ((endian (ecase (movitz:movitz-eval endian env)
+ ((:host :little) :little)
+ (:big :big)))
+ (endian-fix-ecx (ecase endian
+ (:little nil)
+ (:big `((:xchgb :cl :ch))))))
(cond
((and (eql 0 offset) (eql 0 index))
- `(with-inline-assembly (:returns :untagged-fixnum-ecx :type (unsigned-byte 8))
+ `(with-inline-assembly (:returns :untagged-fixnum-ecx
+ :type (unsigned-byte 16))
(:compile-form (:result-mode :eax) ,object)
- (:movzxb (:eax ,(offset-by 1)) :ecx)))
+ (:movzxw (:eax ,(offset-by 2)) :ecx)
+ ,@endian-fix-ecx))
((eql 0 index)
(let ((object-var (gensym "memref-object-"))
(offset-var (gensym "memref-offset-")))
`(let ((,object-var ,object)
(,offset-var ,offset))
(with-inline-assembly (:returns :untagged-fixnum-ecx
- :type (unsigned-byte 8))
- (:compile-two-forms (:eax :untagged-fixnum-ecx) ,object-var ,offset-var)
- ;; (:sarl ,movitz:+movitz-fixnum-shift+ :ecx)
- (:movzxb (:eax :ecx ,(offset-by 1)) :ecx)
- ))))
+ :type (unsigned-byte 16))
+ (:compile-two-forms (:eax :ecx) ,object-var ,offset-var)
+ (:sarl ,movitz:+movitz-fixnum-shift+ :ecx)
+ (:movzxw (:eax :ecx ,(offset-by 2)) :ecx)
+ ,@endian-fix-ecx))))
((eql 0 offset)
- `(with-inline-assembly (:returns :untagged-fixnum-ecx :type (unsigned-byte 8))
- (:compile-two-forms (:eax :untagged-fixnum-ecx) ,object ,index)
- (:movzxb (:eax :ecx ,(offset-by 1)) :ecx)))
- (t (let ((object-var (gensym "memref-object-")))
- `(let ((,object-var ,object))
- (with-inline-assembly (:returns :untagged-fixnum-ecx :type (unsigned-byte 8))
- (:compile-two-forms (:ecx :ebx) ,offset ,index)
- (:load-lexical (:lexical-binding ,object-var) :eax)
- (:addl :ebx :ecx) ; index += offset
- (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
- (:movzxb (:eax :ecx ,(offset-by 1)) :ecx)))))))
- (:unsigned-byte16
- (let* ((endian (ecase (movitz:movitz-eval endian env)
- ((:host :little) :little)
- (:big :big)))
- (endian-fix-ecx (ecase endian
- (:little nil)
- (:big `((:xchgb :cl :ch))))))
- (cond
- ((and (eql 0 offset) (eql 0 index))
- `(with-inline-assembly (:returns :untagged-fixnum-ecx
- :type (unsigned-byte 16))
- (:compile-form (:result-mode :eax) ,object)
- (:movzxw (:eax ,(offset-by 2)) :ecx)
- ,@endian-fix-ecx))
- ((eql 0 index)
- (let ((object-var (gensym "memref-object-"))
- (offset-var (gensym "memref-offset-")))
- `(let ((,object-var ,object)
- (,offset-var ,offset))
- (with-inline-assembly (:returns :untagged-fixnum-ecx
- :type (unsigned-byte 16))
- (:compile-two-forms (:eax :ecx) ,object-var ,offset-var)
- (:sarl ,movitz:+movitz-fixnum-shift+ :ecx)
- (:movzxw (:eax :ecx ,(offset-by 2)) :ecx)
- ,@endian-fix-ecx))))
- ((eql 0 offset)
- (let ((object-var (gensym "memref-object-"))
- (index-var (gensym "memref-index-")))
- `(let ((,object-var ,object)
- (,index-var ,index))
- (with-inline-assembly (:returns :untagged-fixnum-ecx
- :type (unsigned-byte 16))
- (:compile-two-forms (:eax :ecx) ,object-var ,index-var)
- (:sarl ,(1- movitz:+movitz-fixnum-shift+) :ecx)
- (:movzxw (:eax :ecx ,(offset-by 2)) :ecx)
- ,@endian-fix-ecx))))
- (t (let ((object-var (gensym "memref-object-"))
- (offset-var (gensym "memref-offset-"))
- (index-var (gensym "memref-index-")))
- `(let ((,object-var ,object)
- (,offset-var ,offset)
- (,index-var ,index))
- (with-inline-assembly (:returns :untagged-fixnum-ecx
- :type (unsigned-byte 16))
- (:compile-two-forms (:ecx :ebx) ,offset-var ,index-var)
- (:leal (:ecx (:ebx 2)) :ecx)
- (:load-lexical (:lexical-binding ,object-var) :eax)
- (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
- (:movzxw (:eax :ecx ,(offset-by 2)) :ecx)
- ,@endian-fix-ecx)))))))
- (:unsigned-byte14
- (cond
- ((and (eq 0 offset) (eq 0 index))
- `(with-inline-assembly (:returns :ecx :type (unsigned-byte 14))
- (:compile-form (:result-mode :eax) ,object)
- (:movzxw (:eax ,(offset-by 2)) :ecx)
- (:testb ,movitz:+movitz-fixnum-zmask+ :cl)
- (:jnz '(:sub-program () (:int 63)))))
- ((eq 0 offset)
(let ((object-var (gensym "memref-object-"))
(index-var (gensym "memref-index-")))
`(let ((,object-var ,object)
(,index-var ,index))
- (with-inline-assembly (:returns :ecx)
+ (with-inline-assembly (:returns :untagged-fixnum-ecx
+ :type (unsigned-byte 16))
(:compile-two-forms (:eax :ecx) ,object-var ,index-var)
(:sarl ,(1- movitz:+movitz-fixnum-shift+) :ecx)
(:movzxw (:eax :ecx ,(offset-by 2)) :ecx)
- (:testb ,movitz:+movitz-fixnum-zmask+ :cl)
- (:jnz '(:sub-program () (:int 63)))))))
+ ,@endian-fix-ecx))))
(t (let ((object-var (gensym "memref-object-"))
(offset-var (gensym "memref-offset-"))
(index-var (gensym "memref-index-")))
`(let ((,object-var ,object)
(,offset-var ,offset)
(,index-var ,index))
- (with-inline-assembly (:returns :ecx)
+ (with-inline-assembly (:returns :untagged-fixnum-ecx
+ :type (unsigned-byte 16))
(:compile-two-forms (:ecx :ebx) ,offset-var ,index-var)
(:leal (:ecx (:ebx 2)) :ecx)
(:load-lexical (:lexical-binding ,object-var) :eax)
(:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
(:movzxw (:eax :ecx ,(offset-by 2)) :ecx)
- (:testb ,movitz:+movitz-fixnum-shift+ :cl)
- (:jnz '(:sub-program () (:int 63)))))))))
- (:unsigned-byte29+3
- ;; Two values: the 29 upper bits as unsigned integer,
- ;; and secondly the lower 3 bits as unsigned.
- (assert (= 2 movitz::+movitz-fixnum-shift+))
- `(with-inline-assembly (:returns :multiple-values)
- (:compile-form (:result-mode :push) ,object)
- (:compile-two-forms (:ecx :ebx) ,offset ,index)
- (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
- (:addl :ebx :ecx)
- (:popl :eax) ; object
- (:movl (:eax :ecx ,(offset-by 4)) :ecx)
- (:leal ((:ecx 4)) :ebx)
- (:shrl 1 :ecx)
- (:andl #b11100 :ebx)
- (:andl -4 :ecx)
- (:movl :ecx :eax)
- (:movl 2 :ecx)
- (:stc)))
- (:signed-byte30+2
- ;; Two values: the 30 upper bits as signed integer,
- ;; and secondly the lower 2 bits as unsigned.
- (assert (= 2 movitz::+movitz-fixnum-shift+))
- (let ((fix-ecx `((:leal ((:ecx 4)) :ebx)
- (:andl -4 :ecx)
- (:andl #b1100 :ebx)
- (:movl :ecx :eax)
- (:movl 2 :ecx)
- (:stc))))
- (cond
- ((and (eq 0 offset) (eq 0 index))
- `(with-inline-assembly (:returns :multiple-values)
- (:compile-form (:result-mode :eax) ,object)
- (:movl (:eax ,(offset-by 4)) :ecx)
- ,@fix-ecx))
- ((eq 0 offset)
- `(with-inline-assembly (:returns :multiple-values)
- (:compile-two-forms (:eax :ecx) ,object ,index)
- (:movl (:eax :ecx ,(offset-by 4)) :ecx)
- ,@fix-ecx))
- (t (let ((object-var (gensym "memref-object-")))
- `(let ((,object-var ,object))
- (with-inline-assembly (:returns :multiple-values)
- (:compile-two-forms (:ecx :ebx) ,offset ,index)
- (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
- (:load-lexical (:lexical-binding ,object-var) :eax)
- (:addl :ebx :ecx)
- (:movl (:eax :ecx ,(offset-by 4)) :ecx)
- ,@fix-ecx))))))
- #+ignore
- `(with-inline-assembly (:returns :multiple-values)
- (:compile-form (:result-mode :push) ,object)
- (:compile-two-forms (:ecx :ebx) ,offset ,index)
- (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
- (:addl :ebx :ecx)
- (:popl :eax) ; object
- (:movl (:eax :ecx ,(offset-by 4)) :ecx)
- (:leal ((:ecx 4)) :ebx)
- (:andl #b1100 :ebx)
- (:andl -4 :ecx)
- (:movl :ecx :eax)
- (:movl 2 :ecx)
- (:stc)))
- (:character
- (when (eq 0 index) (warn "memref zero char index!"))
- (cond
- ((eq 0 offset)
- `(with-inline-assembly (:returns :eax)
- (:compile-two-forms (:ebx :ecx) ,object ,index)
- (:xorl :eax :eax)
- (:movb ,(movitz:tag :character) :al)
- (:sarl ,movitz::+movitz-fixnum-shift+ :ecx) ; scale index
- (:movb (:ebx :ecx ,(offset-by 1)) :ah)))
- (t (let ((object-var (gensym "memref-object-")))
- `(let ((,object-var ,object))
- (with-inline-assembly (:returns :eax)
- (:compile-two-forms (:ecx :ebx) ,offset ,index)
- (:addl :ebx :ecx)
- (:xorl :eax :eax)
- (:movb ,(movitz:tag :character) :al)
- (:load-lexical (:lexical-binding ,object-var) :ebx)
- (:sarl ,movitz::+movitz-fixnum-shift+ :ecx) ; scale offset+index
- (:movb (:ebx :ecx ,(offset-by 1)) :ah)))))))
- (:location
- (assert (= 4 movitz::+movitz-fixnum-factor+))
+ ,@endian-fix-ecx)))))))
+ (:unsigned-byte14
+ (cond
+ ((and (eq 0 offset) (eq 0 index))
+ `(with-inline-assembly (:returns :ecx :type (unsigned-byte 14))
+ (:compile-form (:result-mode :eax) ,object)
+ (:movzxw (:eax ,(offset-by 2)) :ecx)
+ (:testb ,movitz:+movitz-fixnum-zmask+ :cl)
+ (:jnz '(:sub-program () (:int 63)))))
+ ((eq 0 offset)
+ (let ((object-var (gensym "memref-object-"))
+ (index-var (gensym "memref-index-")))
+ `(let ((,object-var ,object)
+ (,index-var ,index))
+ (with-inline-assembly (:returns :ecx)
+ (:compile-two-forms (:eax :ecx) ,object-var ,index-var)
+ (:sarl ,(1- movitz:+movitz-fixnum-shift+) :ecx)
+ (:movzxw (:eax :ecx ,(offset-by 2)) :ecx)
+ (:testb ,movitz:+movitz-fixnum-zmask+ :cl)
+ (:jnz '(:sub-program () (:int 63)))))))
+ (t (let ((object-var (gensym "memref-object-"))
+ (offset-var (gensym "memref-offset-"))
+ (index-var (gensym "memref-index-")))
+ `(let ((,object-var ,object)
+ (,offset-var ,offset)
+ (,index-var ,index))
+ (with-inline-assembly (:returns :ecx)
+ (:compile-two-forms (:ecx :ebx) ,offset-var ,index-var)
+ (:leal (:ecx (:ebx 2)) :ecx)
+ (:load-lexical (:lexical-binding ,object-var) :eax)
+ (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
+ (:movzxw (:eax :ecx ,(offset-by 2)) :ecx)
+ (:testb ,movitz:+movitz-fixnum-shift+ :cl)
+ (:jnz '(:sub-program () (:int 63)))))))))
+ (:unsigned-byte29+3
+ ;; Two values: the 29 upper bits as unsigned integer,
+ ;; and secondly the lower 3 bits as unsigned.
+ (assert (= 2 movitz::+movitz-fixnum-shift+))
+ `(with-inline-assembly (:returns :multiple-values)
+ (:compile-form (:result-mode :push) ,object)
+ (:compile-two-forms (:ecx :ebx) ,offset ,index)
+ (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
+ (:addl :ebx :ecx)
+ (:popl :eax) ; object
+ (:movl (:eax :ecx ,(offset-by 4)) :ecx)
+ (:leal ((:ecx 4)) :ebx)
+ (:shrl 1 :ecx)
+ (:andl #b11100 :ebx)
+ (:andl -4 :ecx)
+ (:movl :ecx :eax)
+ (:movl 2 :ecx)
+ (:stc)))
+ (:signed-byte30+2
+ ;; Two values: the 30 upper bits as signed integer,
+ ;; and secondly the lower 2 bits as unsigned.
+ (assert (= 2 movitz::+movitz-fixnum-shift+))
+ (let ((fix-ecx `((:leal ((:ecx 4)) :ebx)
+ (:andl -4 :ecx)
+ (:andl #b1100 :ebx)
+ (:movl :ecx :eax)
+ (:movl 2 :ecx)
+ (:stc))))
(cond
((and (eq 0 offset) (eq 0 index))
- `(with-inline-assembly (:returns :ecx :type (signed-byte 30))
+ `(with-inline-assembly (:returns :multiple-values)
(:compile-form (:result-mode :eax) ,object)
(:movl (:eax ,(offset-by 4)) :ecx)
- (:andl -4 :ecx)))
+ ,@fix-ecx))
((eq 0 offset)
- `(with-inline-assembly (:returns :ecx :type (signed-byte 30))
+ `(with-inline-assembly (:returns :multiple-values)
(:compile-two-forms (:eax :ecx) ,object ,index)
(:movl (:eax :ecx ,(offset-by 4)) :ecx)
- (:andl -4 :ecx)))
+ ,@fix-ecx))
(t (let ((object-var (gensym "memref-object-")))
`(let ((,object-var ,object))
- (with-inline-assembly (:returns :ecx :type (signed-byte 30))
+ (with-inline-assembly (:returns :multiple-values)
(:compile-two-forms (:ecx :ebx) ,offset ,index)
(:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
(:load-lexical (:lexical-binding ,object-var) :eax)
(:addl :ebx :ecx)
(:movl (:eax :ecx ,(offset-by 4)) :ecx)
- (:andl -4 :ecx)))))))
- (:tag
+ ,@fix-ecx))))))
+ #+ignore
+ `(with-inline-assembly (:returns :multiple-values)
+ (:compile-form (:result-mode :push) ,object)
+ (:compile-two-forms (:ecx :ebx) ,offset ,index)
+ (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
+ (:addl :ebx :ecx)
+ (:popl :eax) ; object
+ (:movl (:eax :ecx ,(offset-by 4)) :ecx)
+ (:leal ((:ecx 4)) :ebx)
+ (:andl #b1100 :ebx)
+ (:andl -4 :ecx)
+ (:movl :ecx :eax)
+ (:movl 2 :ecx)
+ (:stc)))
+ (:character
+ (when (eq 0 index) (warn "memref zero char index!"))
+ (cond
+ ((eq 0 offset)
+ `(with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:ebx :ecx) ,object ,index)
+ (:xorl :eax :eax)
+ (:movb ,(movitz:tag :character) :al)
+ (:sarl ,movitz::+movitz-fixnum-shift+ :ecx) ; scale index
+ (:movb (:ebx :ecx ,(offset-by 1)) :ah)))
+ (t (let ((object-var (gensym "memref-object-")))
+ `(let ((,object-var ,object))
+ (with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:ecx :ebx) ,offset ,index)
+ (:addl :ebx :ecx)
+ (:xorl :eax :eax)
+ (:movb ,(movitz:tag :character) :al)
+ (:load-lexical (:lexical-binding ,object-var) :ebx)
+ (:sarl ,movitz::+movitz-fixnum-shift+ :ecx) ; scale offset+index
+ (:movb (:ebx :ecx ,(offset-by 1)) :ah)))))))
+ (:location
+ (assert (= 4 movitz::+movitz-fixnum-factor+))
+ (cond
+ ((and (eq 0 offset) (eq 0 index))
+ `(with-inline-assembly (:returns :ecx :type (signed-byte 30))
+ (:compile-form (:result-mode :eax) ,object)
+ (:movl (:eax ,(offset-by 4)) :ecx)
+ (:andl -4 :ecx)))
+ ((eq 0 offset)
+ `(with-inline-assembly (:returns :ecx :type (signed-byte 30))
+ (:compile-two-forms (:eax :ecx) ,object ,index)
+ (:movl (:eax :ecx ,(offset-by 4)) :ecx)
+ (:andl -4 :ecx)))
+ (t (let ((object-var (gensym "memref-object-")))
+ `(let ((,object-var ,object))
+ (with-inline-assembly (:returns :ecx :type (signed-byte 30))
+ (:compile-two-forms (:ecx :ebx) ,offset ,index)
+ (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
+ (:load-lexical (:lexical-binding ,object-var) :eax)
+ (:addl :ebx :ecx)
+ (:movl (:eax :ecx ,(offset-by 4)) :ecx)
+ (:andl -4 :ecx)))))))
+ (:tag
+ (assert (= 4 movitz::+movitz-fixnum-factor+))
+ (cond
+ ((and (eq 0 offset) (eq 0 index))
+ `(with-inline-assembly (:returns :untagged-fixnum-ecx :type (unsigned-byte 3))
+ (:compile-form (:result-mode :eax) ,object)
+ (:movl (:eax ,(offset-by 4)) :ecx)
+ (:andl 7 :ecx)))
+ ((eq 0 offset)
+ `(with-inline-assembly (:returns :untagged-fixnum-ecx :type (unsigned-byte 3))
+ (:compile-two-forms (:eax :ecx) ,object ,index)
+ (:movl (:eax :ecx ,(offset-by 4)) :ecx)
+ (:andl 7 :ecx)))
+ (t (let ((object-var (gensym "memref-object-")))
+ `(let ((,object-var ,object))
+ (with-inline-assembly (:returns :untagged-fixnum-ecx :type (unsigned-byte 3))
+ (:compile-two-forms (:ecx :ebx) ,offset ,index)
+ (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
+ (:load-lexical (:lexical-binding ,object-var) :eax)
+ (:addl :ebx :ecx)
+ (:movl (:eax :ecx ,(offset-by 4)) :ecx)
+ (:andl 7 :ecx)))))))
+ (:unsigned-byte32
+ (let ((prefixes (if (not physicalp)
+ ()
+ movitz:*compiler-physical-segment-prefix*))
+ (fix-endian (ecase (movitz:movitz-eval endian env)
+ ((:host :little) ())
+ (:big `((:bswap :ecx))))))
(assert (= 4 movitz::+movitz-fixnum-factor+))
(cond
((and (eq 0 offset) (eq 0 index))
- `(with-inline-assembly (:returns :untagged-fixnum-ecx :type (unsigned-byte 3))
+ `(with-inline-assembly (:returns :untagged-fixnum-ecx
+ :type (unsigned-byte 32))
(:compile-form (:result-mode :eax) ,object)
- (:movl (:eax ,(offset-by 4)) :ecx)
- (:andl 7 :ecx)))
+ (,prefixes :movl (:eax ,(offset-by 4)) :ecx)
+ ,@fix-endian))
((eq 0 offset)
- `(with-inline-assembly (:returns :untagged-fixnum-ecx :type (unsigned-byte 3))
+ `(with-inline-assembly (:returns :untagged-fixnum-ecx
+ :type (unsigned-byte 32))
(:compile-two-forms (:eax :ecx) ,object ,index)
- (:movl (:eax :ecx ,(offset-by 4)) :ecx)
- (:andl 7 :ecx)))
+ (,prefixes :movl (:eax :ecx ,(offset-by 4)) :ecx)
+ ,@fix-endian))
(t (let ((object-var (gensym "memref-object-")))
`(let ((,object-var ,object))
- (with-inline-assembly (:returns :untagged-fixnum-ecx :type (unsigned-byte 3))
+ (with-inline-assembly (:returns :untagged-fixnum-ecx
+ :type (unsigned-byte 32))
(:compile-two-forms (:ecx :ebx) ,offset ,index)
(:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
(:load-lexical (:lexical-binding ,object-var) :eax)
(:addl :ebx :ecx)
- (:movl (:eax :ecx ,(offset-by 4)) :ecx)
- (:andl 7 :ecx)))))))
- (:unsigned-byte32
- (let ((endian (movitz:movitz-eval endian env))
- (prefixes (if (not physicalp)
- ()
- movitz:*compiler-physical-segment-prefix*)))
- (assert (member endian '(:host :little)))
- (assert (= 4 movitz::+movitz-fixnum-factor+))
- (cond
- ((and (eq 0 offset) (eq 0 index))
- `(with-inline-assembly (:returns :untagged-fixnum-ecx
- :type (unsigned-byte 32))
- (:compile-form (:result-mode :eax) ,object)
- (,prefixes :movl (:eax ,(offset-by 4)) :ecx)))
- ((eq 0 offset)
- `(with-inline-assembly (:returns :untagged-fixnum-ecx
- :type (unsigned-byte 32))
- (:compile-two-forms (:eax :ecx) ,object ,index)
- (,prefixes :movl (:eax :ecx ,(offset-by 4)) :ecx)))
- (t (let ((object-var (gensym "memref-object-")))
- `(let ((,object-var ,object))
- (with-inline-assembly (:returns :untagged-fixnum-ecx
- :type (unsigned-byte 32))
- (:compile-two-forms (:ecx :ebx) ,offset ,index)
- (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
- (:load-lexical (:lexical-binding ,object-var) :eax)
- (:addl :ebx :ecx)
- (,prefixes :movl (:eax :ecx ,(offset-by 4)) :ecx))))))))
- (:lisp
- (let* ((localp (movitz:movitz-eval localp env))
- (prefixes (if localp
- nil
- movitz:*compiler-nonlocal-lispval-read-segment-prefix*)))
- (cond
- ((and (eql 0 index) (eql 0 offset))
- `(with-inline-assembly (:returns :register)
- (:compile-form (:result-mode :register) ,object)
- (,prefixes :movl ((:result-register) ,(offset-by 4)) (:result-register))))
- ((eql 0 offset)
- `(with-inline-assembly (:returns :eax)
- (:compile-two-forms (:eax :ecx) ,object ,index)
- ,@(when (cl:plusp (cl:- movitz::+movitz-fixnum-shift+ 2))
- `((:sarl ,(cl:- movitz::+movitz-fixnum-shift+ 2)) :ecx))
- (,prefixes :movl (:eax :ecx ,(offset-by 4)) :eax)))
- ((eql 0 index)
- `(with-inline-assembly (:returns :eax)
- (:compile-two-forms (:eax :untagged-fixnum-ecx) ,object ,offset)
- (,prefixes :movl (:eax :ecx ,(offset-by 4)) :eax)))
- (t (assert (not (movitz:movitz-constantp offset env)))
- (assert (not (movitz:movitz-constantp index env)))
- (let ((object-var (gensym "memref-object-")))
- (assert (= 4 movitz:+movitz-fixnum-factor+))
- `(let ((,object-var ,object))
- (with-inline-assembly (:returns :eax)
- (:compile-two-forms (:ecx :ebx) ,offset ,index)
- (:sarl ,movitz:+movitz-fixnum-shift+ :ecx)
- (:load-lexical (:lexical-binding ,object-var) :eax)
- (:addl :ebx :ecx)
- (,prefixes :movl (:eax :ecx ,(offset-by 4)) :eax))))))))
- (:code-vector
- ;; A code-vector is like a normal lisp word pointer,
- ;; except it's known to point to a code-vector, and
- ;; the pointer value is offset by 2. The trick is to
- ;; perform this pointer arithmetics while never
- ;; keeping a non-lisp-word pointer in a register.
+ (,prefixes :movl (:eax :ecx ,(offset-by 4)) :ecx)
+ ,@fix-endian)))))))
+ (:lisp
+ (let* ((localp (movitz:movitz-eval localp env))
+ (prefixes (if localp
+ nil
+ movitz:*compiler-nonlocal-lispval-read-segment-prefix*)))
(cond
((and (eql 0 index) (eql 0 offset))
- `(with-inline-assembly (:returns :eax)
- (:compile-form (:result-mode :ebx) ,object)
- (:movl ,(ldb (byte 32 0) (- movitz:+code-vector-word-offset+)) :eax)
- (:addl (:ebx ,(offset-by 4)) :eax)))
+ `(with-inline-assembly (:returns :register)
+ (:compile-form (:result-mode :register) ,object)
+ (,prefixes :movl ((:result-register) ,(offset-by 4)) (:result-register))))
((eql 0 offset)
`(with-inline-assembly (:returns :eax)
- (:compile-two-forms (:ebx :ecx) ,object ,index)
+ (:compile-two-forms (:eax :ecx) ,object ,index)
,@(when (cl:plusp (cl:- movitz::+movitz-fixnum-shift+ 2))
`((:sarl ,(cl:- movitz::+movitz-fixnum-shift+ 2)) :ecx))
- (:movl ,(ldb (byte 32 0) (- movitz:+code-vector-word-offset+)) :eax)
- (:addl (:ebx :ecx ,(offset-by 4)) :eax)))
+ (,prefixes :movl (:eax :ecx ,(offset-by 4)) :eax)))
((eql 0 index)
`(with-inline-assembly (:returns :eax)
- (:compile-two-forms (:ebx :untagged-fixnum-ecx) ,object ,offset)
- (:movl ,(ldb (byte 32 0) (- movitz:+code-vector-word-offset+)) :eax)
- (:addl (:ebx :ecx ,(offset-by 4)) :eax)))
- (t (let ((object-var (gensym "memref-object-"))
- (offset-var (gensym "memref-offset-"))
- (index-var (gensym "memref-index-")))
- `(let ((,object-var ,object)
- (,offset-var ,offset)
- (,index-var ,index))
- (with-inline-assembly (:returns :eax)
- (:load-lexical (:lexical-binding ,offset-var) :untagged-fixnum-ecx)
- (:load-lexical (:lexical-binding ,object-var) :ebx)
- (:load-lexical (:lexical-binding ,index-var) :edx)
- (:addl :edx :ecx)
- (:movl ,(ldb (byte 32 0) (- movitz:+code-vector-word-offset+)) :eax)
- (:addl (:ebx :ecx ,(offset-by 4)) :eax)))))
- #+ignore
- (t (error "variable memref type :code-vector not implemented."))
- #+ignore
+ (:compile-two-forms (:eax :untagged-fixnum-ecx) ,object ,offset)
+ (,prefixes :movl (:eax :ecx ,(offset-by 4)) :eax)))
(t (assert (not (movitz:movitz-constantp offset env)))
(assert (not (movitz:movitz-constantp index env)))
(let ((object-var (gensym "memref-object-")))
@@ -422,9 +376,60 @@
(:sarl ,movitz:+movitz-fixnum-shift+ :ecx)
(:load-lexical (:lexical-binding ,object-var) :eax)
(:addl :ebx :ecx)
- (:movl (:eax :ecx ,(offset-by 4)) :eax)))))))
- (t (error "Unknown memref type: ~S" (movitz:movitz-eval type nil nil))
- form)))))))))
+ (,prefixes :movl (:eax :ecx ,(offset-by 4)) :eax))))))))
+ (:code-vector
+ ;; A code-vector is like a normal lisp word pointer,
+ ;; except it's known to point to a code-vector, and
+ ;; the pointer value is offset by 2. The trick is to
+ ;; perform this pointer arithmetics while never
+ ;; keeping a non-lisp-word pointer in a register.
+ (cond
+ ((and (eql 0 index) (eql 0 offset))
+ `(with-inline-assembly (:returns :eax)
+ (:compile-form (:result-mode :ebx) ,object)
+ (:movl ,(ldb (byte 32 0) (- movitz:+code-vector-word-offset+)) :eax)
+ (:addl (:ebx ,(offset-by 4)) :eax)))
+ ((eql 0 offset)
+ `(with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:ebx :ecx) ,object ,index)
+ ,@(when (cl:plusp (cl:- movitz::+movitz-fixnum-shift+ 2))
+ `((:sarl ,(cl:- movitz::+movitz-fixnum-shift+ 2)) :ecx))
+ (:movl ,(ldb (byte 32 0) (- movitz:+code-vector-word-offset+)) :eax)
+ (:addl (:ebx :ecx ,(offset-by 4)) :eax)))
+ ((eql 0 index)
+ `(with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:ebx :untagged-fixnum-ecx) ,object ,offset)
+ (:movl ,(ldb (byte 32 0) (- movitz:+code-vector-word-offset+)) :eax)
+ (:addl (:ebx :ecx ,(offset-by 4)) :eax)))
+ (t (let ((object-var (gensym "memref-object-"))
+ (offset-var (gensym "memref-offset-"))
+ (index-var (gensym "memref-index-")))
+ `(let ((,object-var ,object)
+ (,offset-var ,offset)
+ (,index-var ,index))
+ (with-inline-assembly (:returns :eax)
+ (:load-lexical (:lexical-binding ,offset-var) :untagged-fixnum-ecx)
+ (:load-lexical (:lexical-binding ,object-var) :ebx)
+ (:load-lexical (:lexical-binding ,index-var) :edx)
+ (:addl :edx :ecx)
+ (:movl ,(ldb (byte 32 0) (- movitz:+code-vector-word-offset+)) :eax)
+ (:addl (:ebx :ecx ,(offset-by 4)) :eax)))))
+ #+ignore
+ (t (error "variable memref type :code-vector not implemented."))
+ #+ignore
+ (t (assert (not (movitz:movitz-constantp offset env)))
+ (assert (not (movitz:movitz-constantp index env)))
+ (let ((object-var (gensym "memref-object-")))
+ (assert (= 4 movitz:+movitz-fixnum-factor+))
+ `(let ((,object-var ,object))
+ (with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:ecx :ebx) ,offset ,index)
+ (:sarl ,movitz:+movitz-fixnum-shift+ :ecx)
+ (:load-lexical (:lexical-binding ,object-var) :eax)
+ (:addl :ebx :ecx)
+ (:movl (:eax :ecx ,(offset-by 4)) :eax)))))))
+ (t (error "Unknown memref type: ~S" (movitz:movitz-eval type nil nil))
+ form))))))))
(defun memref (object offset &key (index 0) (type :lisp) localp (endian :host))
(ecase type
@@ -451,374 +456,403 @@
(not (movitz:movitz-constantp localp env))
(not (movitz:movitz-constantp endian env)))
form
- (case (movitz::eval-form type)
- (:character
- (cond
- ((and (movitz:movitz-constantp value env)
- (movitz:movitz-constantp offset env)
- (movitz:movitz-constantp index env))
- (let ((value (movitz:movitz-eval value env)))
- (check-type value movitz::movitz-character)
- `(progn
- (with-inline-assembly (:returns :nothing)
- (:compile-form (:result-mode :ebx) ,object)
- (:movb ,(movitz:movitz-intern value)
- (:ebx ,(+ (movitz:movitz-eval offset env)
- (* 1 (movitz:movitz-eval index env))))))
- ,value)))
- ((and (movitz:movitz-constantp offset env)
- (movitz:movitz-constantp index env))
- `(with-inline-assembly (:returns :eax)
- (:compile-two-forms (:eax :ebx) ,value ,object)
- (:movb :ah (:ebx ,(+ (movitz:movitz-eval offset env)
- (* 1 (movitz:movitz-eval index env)))))))
- ((movitz:movitz-constantp offset env)
- (let ((value-var (gensym "memref-value-")))
- `(let ((,value-var ,value))
- (with-inline-assembly (:returns :eax)
- (:compile-two-forms (:ebx :untagged-fixnum-ecx) ,object ,index)
- (:load-lexical (:lexical-binding ,value-var) :eax)
- (:movb :ah (:ebx :ecx ,(+ (movitz:movitz-eval offset env))))))))
- (t (let ((object-var (gensym "memref-object-"))
- (offset-var (gensym "memref-offset-")))
- `(let ((,object-var ,object) (,offset-var ,offset))
- (with-inline-assembly (:returns :nothing)
- (:compile-two-forms (:ecx :eax) ,index ,value)
- (:load-lexical (:lexical-binding ,offset-var) :ebx)
- (:addl :ebx :ecx)
- (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
- (:load-lexical (:lexical-binding ,object-var) :ebx)
- (:movb :ah (:ebx :ecx))))))))
- (:unsigned-byte32
- (let ((endian (movitz:movitz-eval endian env)))
- (assert (member endian '(:host :little))))
- (assert (= 4 movitz::+movitz-fixnum-factor+))
- (cond
- ((and (movitz:movitz-constantp value env)
- (movitz:movitz-constantp offset env)
- (movitz:movitz-constantp index env))
- (let ((value (movitz:movitz-eval value env)))
- (check-type value (unsigned-byte 32))
- `(progn
- (with-inline-assembly (:returns :nothing)
- (:compile-form (:result-mode :ebx) ,object)
- (:movl ,value (:ebx ,(+ (movitz:movitz-eval offset env)
- (* 4 (movitz:movitz-eval index env))))))
- ,value)))
- ((and (movitz:movitz-constantp offset env)
- (movitz:movitz-constantp index env))
- `(with-inline-assembly (:returns :untagged-fixnum-ecx)
- (:compile-two-forms (:untagged-fixnum-ecx :ebx) ,value ,object)
- (:movl :ecx (:ebx ,(+ (movitz:movitz-eval offset env)
- (* 4 (movitz:movitz-eval index env)))))))
- ((and (movitz:movitz-constantp offset env)
- (movitz:movitz-constantp value env))
- (let ((value (movitz:movitz-eval value env)))
- (check-type value (unsigned-byte 32))
- `(progn
- (with-inline-assembly (:returns :nothing)
- (:compile-two-forms (:ecx :ebx) ,index ,object)
- (:movl ,value (:ebx :ecx ,(movitz:movitz-eval offset env))))
- ,value)))
- ((movitz:movitz-constantp offset env)
- (let ((value-var (gensym "memref-value-"))
- (object-var (gensym "memref-object-"))
- (index-var (gensym "memref-index-")))
- `(let ((,value-var ,value)
- (,object-var ,object)
- (,index-var ,index))
- (with-inline-assembly (:returns :untagged-fixnum-ecx)
- (:load-lexical (:lexical-binding ,value-var) :untagged-fixnum-ecx)
- (:compile-two-forms (:ebx :eax) ,object-var ,index-var)
- (:movl :ecx (:eax :ebx ,(movitz:movitz-eval offset env)))))))
- (t (let ((value-var (gensym "memref-value-"))
- (object-var (gensym "memref-object-"))
- (offset-var (gensym "memref-offset-"))
- (index-var (gensym "memref-index-")))
- (assert (= 4 movitz:+movitz-fixnum-factor+))
- `(let ((,value-var ,value)
- (,object-var ,object)
- (,offset-var ,offset)
- (,index-var ,index))
- (with-inline-assembly (:returns :untagged-fixnum-ecx)
- (:load-lexical (:lexical-binding ,value-var) :eax)
- (:call-global-pf unbox-u32)
- (:compile-two-forms (:eax :edx) ,index-var ,offset-var)
- (:load-lexical (:lexical-binding ,object-var) :ebx)
- (:std)
- (:sarl ,movitz::+movitz-fixnum-shift+ :edx)
- (:addl :eax :edx) ; EDX = offset+index
- (:movl :ecx (:ebx :edx))
- (:movl :edi :edx)
- (:cld)))))))
- (:unsigned-byte16
- (let ((endian (ecase (movitz:movitz-eval endian env)
- ((:host :little) :little)
- (:big :big))))
- (cond
- ((and (movitz:movitz-constantp value env)
- (movitz:movitz-constantp offset env)
- (movitz:movitz-constantp index env))
- (let* ((host-value (movitz:movitz-eval value env))
- (value (ecase endian
- (:little host-value)
- (:big (dpb (ldb (byte 8 0) host-value)
- (byte 8 8)
- (ldb (byte 8 8) host-value))))))
- (check-type value (unsigned-byte 16))
- `(progn
- (with-inline-assembly (:returns :nothing)
- (:compile-form (:result-mode :ebx) ,object)
- (:movw ,value (:ebx ,(+ (movitz:movitz-eval offset env)
- (* 2 (movitz:movitz-eval index env))))))
- ,value)))
- ((and (movitz:movitz-constantp offset env)
- (movitz:movitz-constantp index env))
- `(with-inline-assembly (:returns :untagged-fixnum-ecx)
- (:compile-two-forms (:untagged-fixnum-ecx :ebx) ,value ,object)
- ,@(ecase endian
- (:little nil)
- (:big `((:xchg :cl :ch))))
- (:movw :cx (:ebx ,(+ (movitz:movitz-eval offset env)
- (* 2 (movitz:movitz-eval index env)))))))
- ((and (movitz:movitz-constantp offset env)
- (movitz:movitz-constantp value env))
- (let ((value (movitz:movitz-eval value env))
- (index-var (gensym "memref-index-"))
- (object-var (gensym "memref-object-")))
- (check-type value (unsigned-byte 16))
- `(let ((,object-var ,object)
- (,index-var ,index))
- (with-inline-assembly (:returns :nothing)
- (:compile-two-forms (:ecx :ebx) ,index-var ,object-var)
- (:sarl ,(1- movitz:+movitz-fixnum-shift+) :ecx)
- (:movw ,value (:ebx :ecx ,(movitz:movitz-eval offset env))))
- ,value)))
- ((movitz:movitz-constantp offset env)
- (let ((value-var (gensym "memref-value-"))
- (index-var (gensym "memref-index-"))
- (object-var (gensym "memref-object-")))
- (if (<= 16 movitz:*compiler-allow-untagged-word-bits*)
- `(let ((,value-var ,value)
- (,object-var ,object)
- (,index-var ,index))
- (with-inline-assembly (:returns :untagged-fixnum-eax)
- (:compile-two-forms (:ebx :ecx) ,object-var ,index-var)
- (:load-lexical (:lexical-binding ,value-var) :untagged-fixnum-eax)
- (:sarl ,(1- movitz:+movitz-fixnum-shift+) :ecx)
- (:movw :ax (:ebx :ecx ,(movitz:movitz-eval offset env)))))
- `(let ((,value-var ,value)
- (,object-var ,object)
- (,index-var ,index))
- (with-inline-assembly (:returns :nothing)
- (:compile-two-forms (:ebx :ecx) ,object-var ,index-var)
- (:load-lexical (:lexical-binding ,value-var) :eax)
- (:sarl ,(1- movitz:+movitz-fixnum-shift+) :ecx)
- (:movl :edi :edx)
- (:std)
- (:shrl ,movitz:+movitz-fixnum-shift+ :eax)
- ,@(ecase endian
- (:little nil)
- (:big `((:xchgb :al :ah))))
- (:movw :ax (:ebx :ecx ,(movitz:movitz-eval offset env)))
- (:movl :edi :eax)
- (:cld))
- ,value-var))))
- (t (let ((value-var (gensym "memref-value-"))
- (object-var (gensym "memref-object-"))
- (offset-var (gensym "memref-offset-"))
- (index-var (gensym "memref-index-")))
- (if (<= 16 movitz:*compiler-allow-untagged-word-bits*)
+ (multiple-value-bind (constant-index xindex)
+ (extract-constant-delta index env)
+ (multiple-value-bind (constant-offset xoffset)
+ (extract-constant-delta offset env)
+ (flet ((offset-by (element-size)
+ (+ constant-offset (* constant-index element-size))))
+ (case (movitz::movitz-eval type env)
+ (:character
+ (cond
+ ((and (movitz:movitz-constantp value env)
+ (movitz:movitz-constantp offset env)
+ (movitz:movitz-constantp index env))
+ (let ((value (movitz:movitz-eval value env)))
+ (check-type value movitz::movitz-character)
+ `(progn
+ (with-inline-assembly (:returns :nothing)
+ (:compile-form (:result-mode :ebx) ,object)
+ (:movb ,(movitz:movitz-intern value)
+ (:ebx ,(+ (movitz:movitz-eval offset env)
+ (* 1 (movitz:movitz-eval index env))))))
+ ,value)))
+ ((and (movitz:movitz-constantp offset env)
+ (movitz:movitz-constantp index env))
+ `(with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:eax :ebx) ,value ,object)
+ (:movb :ah (:ebx ,(+ (movitz:movitz-eval offset env)
+ (* 1 (movitz:movitz-eval index env)))))))
+ ((movitz:movitz-constantp offset env)
+ (let ((value-var (gensym "memref-value-")))
+ `(let ((,value-var ,value))
+ (with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:ebx :untagged-fixnum-ecx) ,object ,index)
+ (:load-lexical (:lexical-binding ,value-var) :eax)
+ (:movb :ah (:ebx :ecx ,(+ (movitz:movitz-eval offset env))))))))
+ (t (let ((object-var (gensym "memref-object-"))
+ (offset-var (gensym "memref-offset-")))
+ `(let ((,object-var ,object) (,offset-var ,offset))
+ (with-inline-assembly (:returns :nothing)
+ (:compile-two-forms (:ecx :eax) ,index ,value)
+ (:load-lexical (:lexical-binding ,offset-var) :ebx)
+ (:addl :ebx :ecx)
+ (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
+ (:load-lexical (:lexical-binding ,object-var) :ebx)
+ (:movb :ah (:ebx :ecx))))))))
+ (:unsigned-byte32
+ (let ((endian (ecase (movitz:movitz-eval endian env)
+ ((:host :little) :little)
+ (:big :big))))
+ (assert (= 4 movitz::+movitz-fixnum-factor+))
+ (cond
+ ((and (movitz:movitz-constantp value env)
+ (movitz:movitz-constantp offset env)
+ (movitz:movitz-constantp index env))
+ (let ((value (movitz:movitz-eval value env)))
+ (check-type value (unsigned-byte 32))
+ `(progn
+ (with-inline-assembly (:returns :nothing)
+ (:compile-form (:result-mode :ebx) ,object)
+ (:movl ,value (:ebx ,(+ (movitz:movitz-eval offset env)
+ (* 4 (movitz:movitz-eval index env))))))
+ ,value)))
+ ((and (movitz:movitz-constantp offset env)
+ (movitz:movitz-constantp index env))
+ `(with-inline-assembly (:returns :untagged-fixnum-ecx)
+ (:compile-two-forms (:untagged-fixnum-ecx :ebx) ,value ,object)
+ ,@(when (eq endian :big)
+ `((:bswap :ecx)))
+ (:movl :ecx (:ebx ,(+ (movitz:movitz-eval offset env)
+ (* 4 (movitz:movitz-eval index env)))))))
+ ((and (movitz:movitz-constantp offset env)
+ (movitz:movitz-constantp value env))
+ (let ((value (movitz:movitz-eval value env)))
+ (check-type value (unsigned-byte 32))
+ (let ((value (ecase endian
+ (:little value)
+ (:big (logior (ash (ldb (byte 8 0) value) 24)
+ (ash (ldb (byte 8 8) value) 16)
+ (ash (ldb (byte 8 16) value) 8)
+ (ash (ldb (byte 8 24) value) 0))))))
+ `(progn
+ (with-inline-assembly (:returns :nothing)
+ (:compile-two-forms (:ecx :ebx) ,index ,object)
+ (:movl ,value (:ebx :ecx ,(movitz:movitz-eval offset env))))
+ ,value))))
+ ((movitz:movitz-constantp offset env)
+ (let ((value-var (gensym "memref-value-"))
+ (object-var (gensym "memref-object-"))
+ (index-var (gensym "memref-index-")))
`(let ((,value-var ,value)
(,object-var ,object)
- (,offset-var ,offset)
(,index-var ,index))
- (with-inline-assembly (:returns :untagged-fixnum-eax)
- (:compile-two-forms (:ebx :ecx) ,offset-var ,index-var)
- (:load-lexical (:lexical-binding ,value-var) :eax)
- (:andl ,(* movitz:+movitz-fixnum-factor+ #xffff) :eax)
- (:leal (:ebx (:ecx 2)) :ecx)
- (:shrl ,movitz:+movitz-fixnum-shift+ :eax)
- (:sarl ,movitz:+movitz-fixnum-shift+ :ecx)
- (:load-lexical (:lexical-binding ,object-var) :ebx)
- (:movw :ax (:ebx :ecx))))
+ (with-inline-assembly (:returns :untagged-fixnum-ecx)
+ (:load-lexical (:lexical-binding ,value-var) :untagged-fixnum-ecx)
+ (:compile-two-forms (:ebx :eax) ,object-var ,index-var)
+ ,@(when (eq endian :big)
+ `((:bswap :ecx)))
+ (:movl :ecx (:eax :ebx ,(movitz:movitz-eval offset env)))))))
+ (t (let ((value-var (gensym "memref-value-"))
+ (object-var (gensym "memref-object-"))
+ (offset-var (gensym "memref-offset-"))
+ (index-var (gensym "memref-index-")))
+ (assert (= 4 movitz:+movitz-fixnum-factor+))
+ `(let ((,value-var ,value)
+ (,object-var ,object)
+ (,offset-var ,offset)
+ (,index-var ,index))
+ (with-inline-assembly (:returns :untagged-fixnum-ecx)
+ (:load-lexical (:lexical-binding ,value-var) :eax)
+ (:call-global-pf unbox-u32)
+ (:compile-two-forms (:eax :edx) ,index-var ,offset-var)
+ (:load-lexical (:lexical-binding ,object-var) :ebx)
+ ,@(when (eq endian :big)
+ `((:bswap :ecx)))
+ (:std)
+ (:sarl ,movitz::+movitz-fixnum-shift+ :edx)
+ (:addl :eax :edx) ; EDX = offset+index
+ (:movl :ecx (:ebx :edx))
+ (:movl :edi :edx)
+ (:cld))))))))
+ (:unsigned-byte16
+ (let ((endian (ecase (movitz:movitz-eval endian env)
+ ((:host :little) :little)
+ (:big :big))))
+ (cond
+ ((and (movitz:movitz-constantp value env)
+ (movitz:movitz-constantp offset env)
+ (movitz:movitz-constantp index env))
+ (let* ((host-value (movitz:movitz-eval value env))
+ (value (ecase endian
+ (:little host-value)
+ (:big (dpb (ldb (byte 8 0) host-value)
+ (byte 8 8)
+ (ldb (byte 8 8) host-value))))))
+ (check-type value (unsigned-byte 16))
+ `(progn
+ (with-inline-assembly (:returns :nothing)
+ (:compile-form (:result-mode :ebx) ,object)
+ (:movw ,value (:ebx ,(+ (movitz:movitz-eval offset env)
+ (* 2 (movitz:movitz-eval index env))))))
+ ,value)))
+ ((and (movitz:movitz-constantp offset env)
+ (movitz:movitz-constantp index env))
+ `(with-inline-assembly (:returns :untagged-fixnum-ecx)
+ (:compile-two-forms (:untagged-fixnum-ecx :ebx) ,value ,object)
+ ,@(ecase endian
+ (:little nil)
+ (:big `((:xchg :cl :ch))))
+ (:movw :cx (:ebx ,(+ (movitz:movitz-eval offset env)
+ (* 2 (movitz:movitz-eval index env)))))))
+ ((and (movitz:movitz-constantp offset env)
+ (movitz:movitz-constantp value env))
+ (let ((value (movitz:movitz-eval value env))
+ (index-var (gensym "memref-index-"))
+ (object-var (gensym "memref-object-")))
+ (check-type value (unsigned-byte 16))
+ `(let ((,object-var ,object)
+ (,index-var ,index))
+ (with-inline-assembly (:returns :nothing)
+ (:compile-two-forms (:ecx :ebx) ,index-var ,object-var)
+ (:sarl ,(1- movitz:+movitz-fixnum-shift+) :ecx)
+ (:movw ,value (:ebx :ecx ,(movitz:movitz-eval offset env))))
+ ,value)))
+ ((movitz:movitz-constantp offset env)
+ (let ((value-var (gensym "memref-value-"))
+ (index-var (gensym "memref-index-"))
+ (object-var (gensym "memref-object-")))
+ (if (<= 16 movitz:*compiler-allow-untagged-word-bits*)
+ `(let ((,value-var ,value)
+ (,object-var ,object)
+ (,index-var ,index))
+ (with-inline-assembly (:returns :untagged-fixnum-eax)
+ (:compile-two-forms (:ebx :ecx) ,object-var ,index-var)
+ (:load-lexical (:lexical-binding ,value-var) :untagged-fixnum-eax)
+ (:sarl ,(1- movitz:+movitz-fixnum-shift+) :ecx)
+ (:movw :ax (:ebx :ecx ,(movitz:movitz-eval offset env)))))
+ `(let ((,value-var ,value)
+ (,object-var ,object)
+ (,index-var ,index))
+ (with-inline-assembly (:returns :nothing)
+ (:compile-two-forms (:ebx :ecx) ,object-var ,index-var)
+ (:load-lexical (:lexical-binding ,value-var) :eax)
+ (:sarl ,(1- movitz:+movitz-fixnum-shift+) :ecx)
+ (:movl :edi :edx)
+ (:std)
+ (:shrl ,movitz:+movitz-fixnum-shift+ :eax)
+ ,@(ecase endian
+ (:little nil)
+ (:big `((:xchgb :al :ah))))
+ (:movw :ax (:ebx :ecx ,(movitz:movitz-eval offset env)))
+ (:movl :edi :eax)
+ (:cld))
+ ,value-var))))
+ (t (let ((value-var (gensym "memref-value-"))
+ (object-var (gensym "memref-object-"))
+ (offset-var (gensym "memref-offset-"))
+ (index-var (gensym "memref-index-")))
+ (if (<= 16 movitz:*compiler-allow-untagged-word-bits*)
+ `(let ((,value-var ,value)
+ (,object-var ,object)
+ (,offset-var ,offset)
+ (,index-var ,index))
+ (with-inline-assembly (:returns :untagged-fixnum-eax)
+ (:compile-two-forms (:ebx :ecx) ,offset-var ,index-var)
+ (:load-lexical (:lexical-binding ,value-var) :eax)
+ (:andl ,(* movitz:+movitz-fixnum-factor+ #xffff) :eax)
+ (:leal (:ebx (:ecx 2)) :ecx)
+ (:shrl ,movitz:+movitz-fixnum-shift+ :eax)
+ (:sarl ,movitz:+movitz-fixnum-shift+ :ecx)
+ (:load-lexical (:lexical-binding ,object-var) :ebx)
+ (:movw :ax (:ebx :ecx))))
+ `(let ((,value-var ,value)
+ (,object-var ,object)
+ (,offset-var ,offset)
+ (,index-var ,index))
+ (with-inline-assembly (:returns :nothing)
+ (:compile-two-forms (:ebx :ecx) ,offset-var ,index-var)
+ (:load-lexical (:lexical-binding ,value-var) :eax)
+ (:leal (:ebx (:ecx 2)) :ecx)
+ (:sarl ,movitz:+movitz-fixnum-shift+ :ecx)
+ (:load-lexical (:lexical-binding ,object-var) :ebx)
+ (:std)
+ (:shrl ,movitz:+movitz-fixnum-shift+ :eax)
+ ,@(ecase endian
+ (:little nil)
+ (:big `((:xchgb :al :ah))))
+ (:movw :ax (:ebx :ecx))
+ (:shll ,movitz:+movitz-fixnum-shift+ :eax)
+ (:movl :edi :edx)
+ (:cld))
+ ,value-var)))))))
+ (:unsigned-byte8
+ (cond
+ ((and (movitz:movitz-constantp value env)
+ (eql 0 xoffset)
+ (eql 0 xindex))
+ (let ((value (movitz:movitz-eval value env)))
+ (check-type value (unsigned-byte 8))
+ `(progn
+ (with-inline-assembly (:returns :nothing)
+ (:compile-form (:result-mode :ebx) ,object)
+ (:movb ,value (:ebx ,(offset-by 1))))
+ ,value)))
+ ((eql 0 xindex)
+ (let ((value-var (gensym "memref-value-"))
+ (object-var (gensym "memref-object-"))
+ (offset-var (gensym "memref-offset-")))
`(let ((,value-var ,value)
(,object-var ,object)
- (,offset-var ,offset)
- (,index-var ,index))
+ (,offset-var ,xoffset))
(with-inline-assembly (:returns :nothing)
- (:compile-two-forms (:ebx :ecx) ,offset-var ,index-var)
+ (:load-lexical (:lexical-binding ,offset-var) :untagged-fixnum-ecx)
(:load-lexical (:lexical-binding ,value-var) :eax)
- (:leal (:ebx (:ecx 2)) :ecx)
- (:sarl ,movitz:+movitz-fixnum-shift+ :ecx)
(:load-lexical (:lexical-binding ,object-var) :ebx)
- (:std)
- (:shrl ,movitz:+movitz-fixnum-shift+ :eax)
- ,@(ecase endian
- (:little nil)
- (:big `((:xchgb :al :ah))))
- (:movw :ax (:ebx :ecx))
- (:shll ,movitz:+movitz-fixnum-shift+ :eax)
- (:movl :edi :edx)
- (:cld))
- ,value-var)))))))
- (:unsigned-byte8
- (cond
- ((and (movitz:movitz-constantp value env)
- (movitz:movitz-constantp offset env)
- (movitz:movitz-constantp index env))
- (let ((value (movitz:movitz-eval value env)))
- (check-type value (unsigned-byte 8))
- `(progn
- (with-inline-assembly (:returns :nothing)
- (:compile-form (:result-mode :ebx) ,object)
- (:movb ,value (:ebx ,(+ (movitz:movitz-eval offset env)
- (* 1 (movitz:movitz-eval index env))))))
- ,value)))
- ((and (movitz:movitz-constantp offset env)
- (movitz:movitz-constantp index env))
- `(with-inline-assembly (:returns :untagged-fixnum-ecx)
- (:compile-two-forms (:ecx :ebx) ,value ,object)
- (:shrl ,movitz:+movitz-fixnum-shift+ :ecx)
- (:movb :cl (:ebx ,(+ (movitz:movitz-eval offset env)
- (* 1 (movitz:movitz-eval index env)))))))
- ((and (movitz:movitz-constantp offset env)
- (movitz:movitz-constantp value env))
- (let ((value (movitz:movitz-eval value env)))
- (check-type value (unsigned-byte 8))
- `(progn
- (with-inline-assembly (:returns :untagged-fixnum-ecx)
- (:compile-two-forms (:eax :ecx) ,object ,index)
- (:sarl ,movitz:+movitz-fixnum-shift+ :ecx)
- (:movb ,value (:eax :ecx ,(movitz:movitz-eval offset env))))
- value)))
- ((movitz:movitz-constantp offset env)
- (let ((value-var (gensym "memref-value-")))
- `(let ((,value-var ,value))
- (with-inline-assembly (:returns :nothing)
- (:compile-two-forms (:ebx :ecx) ,object ,index)
- (:load-lexical (:lexical-binding ,value-var) :eax)
- (:sarl ,movitz:+movitz-fixnum-shift+ :ecx)
- (:shll ,(- 8 movitz:+movitz-fixnum-shift+) :eax) ; value into :AH
- (:movb :ah (:ebx :ecx ,(movitz:movitz-eval offset env))))
- ,value-var)))
- (t (let ((value-var (gensym "memref-value-"))
- (object-var (gensym "memref-object-")))
- `(let ((,value-var ,value) (,object-var ,object))
- (with-inline-assembly (:returns :nothing)
- (:compile-two-forms (:ebx :ecx) ,offset ,index)
- (:load-lexical (:lexical-binding ,value-var) :eax)
- (:addl :ebx :ecx)
- (:load-lexical (:lexical-binding ,object-var) :ebx) ; value into :AH
- (:shll ,(- 8 movitz:+movitz-fixnum-shift+) :eax)
- (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
- (:movb :ah (:ebx :ecx)))
- ,value-var)))))
- (:unsigned-byte14
- (cond
- ((and (movitz:movitz-constantp offset env)
- (movitz:movitz-constantp index env))
- `(with-inline-assembly (:returns :eax)
- (:compile-two-forms (:eax :ebx) ,value ,object)
- (:andl ,(mask-field (byte 14 2) -1) :eax)
- (:movw :ax (:ebx ,(+ (movitz:movitz-eval offset env)
- (* 4 (movitz:movitz-eval index env)))))))
- ((movitz:movitz-constantp offset env)
- (let ((value-var (gensym "memref-value-")))
- `(let ((,value-var ,value))
- (with-inline-assembly (:returns :eax)
- (:compile-two-forms (:ebx :ecx) ,object ,index)
- (:load-lexical (:lexical-binding ,value-var) :eax)
- ,@(when (plusp (- movitz:+movitz-fixnum-shift+ 2))
- `((:sarl ,(- movitz:+movitz-fixnum-shift+ 2)) :ecx))
- (:andl ,(mask-field (byte 14 2) -1) :eax)
- (:movw :ax (:ebx :ecx ,(movitz:movitz-eval offset env)))))))
- (t (let ((value-var (gensym "memref-value-"))
- (object-var (gensym "memref-object-")))
- `(let ((,value-var ,value) (,object-var ,object))
- (with-inline-assembly (:returns :eax)
- (:compile-two-forms (:untagged-fixnum-ecx :ebx) ,offset ,index)
- (:load-lexical (:lexical-binding ,value-var) :eax)
- ,@(when (cl:plusp (cl:- movitz::+movitz-fixnum-shift+ 2))
- `((:sarl ,(cl:- movitz::+movitz-fixnum-shift+ 2)) :ebx))
- (:addl :ebx :ecx) ; index += offset
- (:load-lexical (:lexical-binding ,object-var) :ebx)
+ (:shll ,(- 8 movitz:+movitz-fixnum-shift+) :eax)
+ (:movb :ah (:ebx :ecx ,(offset-by 1))))
+ ,value-var)))
+ ((and (eql 0 xoffset) (eql 0 xindex))
+ `(with-inline-assembly (:returns :untagged-fixnum-ecx)
+ (:compile-two-forms (:untagged-fixnum-ecx :ebx) ,value ,object)
+ (:movb :cl (:ebx ,(offset-by 1)))))
+ ((and (movitz:movitz-constantp offset env)
+ (movitz:movitz-constantp value env))
+ (let ((value (movitz:movitz-eval value env)))
+ (check-type value (unsigned-byte 8))
+ `(progn
+ (with-inline-assembly (:returns :untagged-fixnum-ecx)
+ (:compile-two-forms (:eax :ecx) ,object ,index)
+ (:sarl ,movitz:+movitz-fixnum-shift+ :ecx)
+ (:movb ,value (:eax :ecx ,(movitz:movitz-eval offset env))))
+ value)))
+ ((movitz:movitz-constantp offset env)
+ (let ((value-var (gensym "memref-value-")))
+ `(let ((,value-var ,value))
+ (with-inline-assembly (:returns :nothing)
+ (:compile-two-forms (:ebx :ecx) ,object ,index)
+ (:load-lexical (:lexical-binding ,value-var) :eax)
+ (:sarl ,movitz:+movitz-fixnum-shift+ :ecx)
+ (:shll ,(- 8 movitz:+movitz-fixnum-shift+) :eax) ; value into :AH
+ (:movb :ah (:ebx :ecx ,(movitz:movitz-eval offset env))))
+ ,value-var)))
+ (t (let ((value-var (gensym "memref-value-"))
+ (object-var (gensym "memref-object-")))
+ `(let ((,value-var ,value) (,object-var ,object))
+ (with-inline-assembly (:returns :nothing)
+ (:compile-two-forms (:ebx :ecx) ,offset ,index)
+ (:load-lexical (:lexical-binding ,value-var) :eax)
+ (:addl :ebx :ecx)
+ (:load-lexical (:lexical-binding ,object-var) :ebx) ; value into :AH
+ (:shll ,(- 8 movitz:+movitz-fixnum-shift+) :eax)
+ (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
+ (:movb :ah (:ebx :ecx)))
+ ,value-var)))))
+ (:unsigned-byte14
+ (cond
+ ((and (movitz:movitz-constantp offset env)
+ (movitz:movitz-constantp index env))
+ `(with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:eax :ebx) ,value ,object)
(:andl ,(mask-field (byte 14 2) -1) :eax)
- (:movl :ax (:ebx :ecx))))))))
- (:lisp
- (let* ((localp (movitz:movitz-eval localp env))
- (prefixes (if localp
- nil
- movitz:*compiler-nonlocal-lispval-write-segment-prefix*)))
- (cond
- ((and (movitz:movitz-constantp offset env)
- (movitz:movitz-constantp index env))
- `(with-inline-assembly (:returns :eax)
- (:compile-two-forms (:eax :ebx) ,value ,object)
- (,prefixes :movl :eax (:ebx ,(+ (movitz:movitz-eval offset env)
- (* 4 (movitz:movitz-eval index env)))))))
- ((movitz:movitz-constantp offset env)
- (let ((value-var (gensym "memref-value-")))
- `(let ((,value-var ,value))
- (with-inline-assembly (:returns :eax)
- (:compile-two-forms (:ebx :ecx) ,object ,index)
- (:load-lexical (:lexical-binding ,value-var) :eax)
- ,@(when (plusp (- movitz:+movitz-fixnum-shift+ 2))
- `((:sarl ,(- movitz:+movitz-fixnum-shift+ 2)) :ecx))
- (,prefixes :movl :eax (:ebx :ecx ,(movitz:movitz-eval offset env)))))))
- (t (let ((value-var (gensym "memref-value-"))
- (object-var (gensym "memref-object-")))
- `(let ((,value-var ,value) (,object-var ,object))
- (with-inline-assembly (:returns :eax)
- (:compile-two-forms (:untagged-fixnum-ecx :ebx) ,offset ,index)
- (:load-lexical (:lexical-binding ,value-var) :eax)
- ,@(when (cl:plusp (cl:- movitz::+movitz-fixnum-shift+ 2))
- `((:sarl ,(cl:- movitz::+movitz-fixnum-shift+ 2)) :ebx))
- (:addl :ebx :ecx) ; index += offset
- (:load-lexical (:lexical-binding ,object-var) :ebx)
- (,prefixes :movl :eax (:ebx :ecx)))))))))
- (:code-vector
- (let ((prefixes (if localp
- nil
- movitz:*compiler-nonlocal-lispval-write-segment-prefix*)))
- (cond
- ((and (movitz:movitz-constantp offset env)
- (movitz:movitz-constantp index env))
- `(with-inline-assembly (:returns :eax)
- (:compile-two-forms (:eax :ebx) ,value ,object)
- (:movl ,movitz:+code-vector-word-offset+
- (:ebx ,(+ (movitz:movitz-eval offset env)
- (* 4 (movitz:movitz-eval index env)))))
- (,prefixes
- :addl :eax (:ebx ,(+ (movitz:movitz-eval offset env)
- (* 4 (movitz:movitz-eval index env)))))))
- ((movitz:movitz-constantp offset env)
- (let ((value-var (gensym "memref-value-")))
- `(let ((,value-var ,value))
- (with-inline-assembly (:returns :eax)
- (:compile-two-forms (:ebx :ecx) ,object ,index)
- (:load-lexical (:lexical-binding ,value-var) :eax)
- ,@(when (plusp (- movitz:+movitz-fixnum-shift+ 2))
- `((:sarl ,(- movitz:+movitz-fixnum-shift+ 2)) :ecx))
- (:movl ,movitz:+code-vector-word-offset+
- (:ebx :ecx ,(movitz:movitz-eval offset env)))
- (,prefixes
- :addl :eax (:ebx :ecx ,(movitz:movitz-eval offset env)))))))
- (t (let ((value-var (gensym "memref-value-"))
- (object-var (gensym "memref-object-")))
- `(let ((,value-var ,value)
- (,object-var ,object))
- (with-inline-assembly (:returns :eax)
- (:compile-two-forms (:untagged-fixnum-ecx :ebx) ,offset ,index)
- (:load-lexical (:lexical-binding ,value-var) :eax)
- ,@(when (cl:plusp (cl:- movitz::+movitz-fixnum-shift+ 2))
- `((:sarl ,(cl:- movitz::+movitz-fixnum-shift+ 2)) :ebx))
- (:addl :ebx :ecx) ; index += offset
- (:load-lexical (:lexical-binding ,object-var) :ebx)
- (:movl ,movitz:+code-vector-word-offset+ (:ebx :ecx))
- (,prefixes :addl :eax (:ebx :ecx)))))))))
- (t ;; (warn "Can't handle inline MEMREF: ~S" form)
- form))))
+ (:movw :ax (:ebx ,(+ (movitz:movitz-eval offset env)
+ (* 4 (movitz:movitz-eval index env)))))))
+ ((movitz:movitz-constantp offset env)
+ (let ((value-var (gensym "memref-value-")))
+ `(let ((,value-var ,value))
+ (with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:ebx :ecx) ,object ,index)
+ (:load-lexical (:lexical-binding ,value-var) :eax)
+ ,@(when (plusp (- movitz:+movitz-fixnum-shift+ 2))
+ `((:sarl ,(- movitz:+movitz-fixnum-shift+ 2)) :ecx))
+ (:andl ,(mask-field (byte 14 2) -1) :eax)
+ (:movw :ax (:ebx :ecx ,(movitz:movitz-eval offset env)))))))
+ (t (let ((value-var (gensym "memref-value-"))
+ (object-var (gensym "memref-object-")))
+ `(let ((,value-var ,value) (,object-var ,object))
+ (with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:untagged-fixnum-ecx :ebx) ,offset ,index)
+ (:load-lexical (:lexical-binding ,value-var) :eax)
+ ,@(when (cl:plusp (cl:- movitz::+movitz-fixnum-shift+ 2))
+ `((:sarl ,(cl:- movitz::+movitz-fixnum-shift+ 2)) :ebx))
+ (:addl :ebx :ecx) ; index += offset
+ (:load-lexical (:lexical-binding ,object-var) :ebx)
+ (:andl ,(mask-field (byte 14 2) -1) :eax)
+ (:movl :ax (:ebx :ecx))))))))
+ (:lisp
+ (let* ((localp (movitz:movitz-eval localp env))
+ (prefixes (if localp
+ nil
+ movitz:*compiler-nonlocal-lispval-write-segment-prefix*)))
+ (cond
+ ((and (movitz:movitz-constantp offset env)
+ (movitz:movitz-constantp index env))
+ `(with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:eax :ebx) ,value ,object)
+ (,prefixes :movl :eax (:ebx ,(+ (movitz:movitz-eval offset env)
+ (* 4 (movitz:movitz-eval index env)))))))
+ ((movitz:movitz-constantp offset env)
+ (let ((value-var (gensym "memref-value-")))
+ `(let ((,value-var ,value))
+ (with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:ebx :ecx) ,object ,index)
+ (:load-lexical (:lexical-binding ,value-var) :eax)
+ ,@(when (plusp (- movitz:+movitz-fixnum-shift+ 2))
+ `((:sarl ,(- movitz:+movitz-fixnum-shift+ 2)) :ecx))
+ (,prefixes :movl :eax (:ebx :ecx ,(movitz:movitz-eval offset env)))))))
+ (t (let ((value-var (gensym "memref-value-"))
+ (object-var (gensym "memref-object-")))
+ `(let ((,value-var ,value) (,object-var ,object))
+ (with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:untagged-fixnum-ecx :ebx) ,offset ,index)
+ (:load-lexical (:lexical-binding ,value-var) :eax)
+ ,@(when (cl:plusp (cl:- movitz::+movitz-fixnum-shift+ 2))
+ `((:sarl ,(cl:- movitz::+movitz-fixnum-shift+ 2)) :ebx))
+ (:addl :ebx :ecx) ; index += offset
+ (:load-lexical (:lexical-binding ,object-var) :ebx)
+ (,prefixes :movl :eax (:ebx :ecx)))))))))
+ (:code-vector
+ (let ((prefixes (if localp
+ nil
+ movitz:*compiler-nonlocal-lispval-write-segment-prefix*)))
+ (cond
+ ((and (movitz:movitz-constantp offset env)
+ (movitz:movitz-constantp index env))
+ `(with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:eax :ebx) ,value ,object)
+ (:movl ,movitz:+code-vector-word-offset+
+ (:ebx ,(+ (movitz:movitz-eval offset env)
+ (* 4 (movitz:movitz-eval index env)))))
+ (,prefixes
+ :addl :eax (:ebx ,(+ (movitz:movitz-eval offset env)
+ (* 4 (movitz:movitz-eval index env)))))))
+ ((movitz:movitz-constantp offset env)
+ (let ((value-var (gensym "memref-value-")))
+ `(let ((,value-var ,value))
+ (with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:ebx :ecx) ,object ,index)
+ (:load-lexical (:lexical-binding ,value-var) :eax)
+ ,@(when (plusp (- movitz:+movitz-fixnum-shift+ 2))
+ `((:sarl ,(- movitz:+movitz-fixnum-shift+ 2)) :ecx))
+ (:movl ,movitz:+code-vector-word-offset+
+ (:ebx :ecx ,(movitz:movitz-eval offset env)))
+ (,prefixes
+ :addl :eax (:ebx :ecx ,(movitz:movitz-eval offset env)))))))
+ (t (let ((value-var (gensym "memref-value-"))
+ (object-var (gensym "memref-object-")))
+ `(let ((,value-var ,value)
+ (,object-var ,object))
+ (with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:untagged-fixnum-ecx :ebx) ,offset ,index)
+ (:load-lexical (:lexical-binding ,value-var) :eax)
+ ,@(when (cl:plusp (cl:- movitz::+movitz-fixnum-shift+ 2))
+ `((:sarl ,(cl:- movitz::+movitz-fixnum-shift+ 2)) :ebx))
+ (:addl :ebx :ecx) ; index += offset
+ (:load-lexical (:lexical-binding ,object-var) :ebx)
+ (:movl ,movitz:+code-vector-word-offset+ (:ebx :ecx))
+ (,prefixes :addl :eax (:ebx :ecx)))))))))
+ (t ;; (warn "Can't handle inline MEMREF: ~S" form)
+ form)))))))
(defun (setf memref) (value object offset &key (index 0) (type :lisp) localp (endian :host))
(ecase type
@@ -1165,3 +1199,34 @@
(defun %copy-words (destination source count &optional (start1 0) (start2 0))
(%copy-words destination source count start1 start2))
+
+;; (define-compiler-macro memrange (object ))
+
+(defun memrange (object offset index length type)
+ (ecase type
+ (:unsigned-byte8
+ (let ((vector (make-array length :element-type '(unsigned-byte 8))))
+ (loop for i upfrom index as j upfrom 0 repeat length
+ do (setf (aref vector j) (memref object offset :index i :type :unsigned-byte8)))
+ vector))))
+
+(defun (setf memrange) (value object offset index length type)
+ (ecase type
+ (:unsigned-byte8
+ (etypecase value
+ ((unsigned-byte 8)
+ (loop for i upfrom index repeat length
+ do (setf (memref object offset :index i :type :unsigned-byte8) value)))
+ (vector
+ (loop for i upfrom index as x across value repeat length
+ do (setf (memref object offset :index i :type :unsigned-byte8) x)))))
+ (:character
+ (etypecase value
+ (character
+ (loop for i upfrom index repeat length
+ do (setf (memref object offset :index i :type :character) value)))
+ (string
+ (loop for i upfrom index as x across value repeat length
+ do (setf (memref object offset :index i :type :character) x))))))
+ value)
+