Update of /project/movitz/cvsroot/movitz/losp/muerte In directory common-lisp.net:/tmp/cvs-serv1342
Modified Files: integers.lisp Log Message: Improved truncate a good bit.
Date: Sat Jun 5 18:53:48 2004 Author: ffjeld
Index: movitz/losp/muerte/integers.lisp diff -u movitz/losp/muerte/integers.lisp:1.18 movitz/losp/muerte/integers.lisp:1.19 --- movitz/losp/muerte/integers.lisp:1.18 Fri Jun 4 06:33:16 2004 +++ movitz/losp/muerte/integers.lisp Sat Jun 5 18:53:48 2004 @@ -9,7 +9,7 @@ ;;;; Created at: Wed Nov 8 18:44:57 2000 ;;;; Distribution: See the accompanying file COPYING. ;;;; -;;;; $Id: integers.lisp,v 1.18 2004/06/04 13:33:16 ffjeld Exp $ +;;;; $Id: integers.lisp,v 1.19 2004/06/06 01:53:48 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------
@@ -116,22 +116,65 @@ ,(* 2 movitz:+movitz-most-negative-fixnum+)) (:jmp 'fix-fix-ok))) fix-fix-ok)) + ((positive-bignum positive-fixnum) + (break "Hello?") + (+ y x)) ((positive-fixnum positive-bignum) (with-inline-assembly (:returns :eax) + (:compile-form (:result-mode :eax) x) + (:testl :eax :eax) + (:jz 'pfix-pbig-done) (:compile-form (:result-mode :eax) y) - (:jecxz 'pfix-pbig-done) - (:movzxw (:eax #.(bt:slot-offset 'movitz::movitz-bignum 'movitz::length)) :ecx) + (:movzxw (:eax ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::length)) :ecx) (:cmpl 1 :ecx) (:jne 'not-size1) (:compile-form (:result-mode :ecx) x) (:sarl ,movitz:+movitz-fixnum-shift+ :ecx) - (:addl (:eax #.(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0)) :ecx) + (:addl (:eax ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0)) :ecx) (:jc '(:sub-program () (:break))) (:call-global-constant box-u32-ecx) (:jmp 'pfix-pbig-done) not-size1 - (:break) + (:declare-label-set retry-jumper (not-size1)) + (:locally (:movl :esp (:edi (:edi-offset atomically-esp)))) + (:locally (:movl '(:funcall ,(movitz::atomically-status-jumper-fn t :esp) + 'retry-jumper) + (:edi (:edi-offset atomically-status)))) + (:leal ((:ecx ,movitz:+movitz-fixnum-factor+) ,(* 2 movitz:+movitz-fixnum-factor+)) + :eax) ; Number of words + (:call-global-constant get-cons-pointer) + (:load-lexical (:lexical-binding y) :ebx) ; bignum + (:movzxw (:ebx ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::length)) :ecx) + (:leal ((:ecx #.movitz:+movitz-fixnum-factor+) + #.movitz:+movitz-fixnum-factor+) + :edx) + (:movl 0 (:eax :edx ,movitz:+other-type-offset+)) ; MSB + copy-bignum-loop + (:subl ,movitz:+movitz-fixnum-factor+ :edx) + (:movl (:ebx :edx ,movitz:+other-type-offset+) :ecx) + (:movl :ecx (:eax :edx ,movitz:+other-type-offset+)) + (:jnz 'copy-bignum-loop) + + (:load-lexical (:lexical-binding x) :ecx) + (:shrl ,movitz:+movitz-fixnum-shift+ :ecx) + (:xorl :ebx :ebx) + (:addl :ecx (:eax ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0))) + (:jnc 'add-bignum-done) + add-bignum-loop + (:addl 4 :ebx) + (:addl 1 (:eax :ebx ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0))) + (:jc 'add-bignum-loop) + add-bignum-done + (:movzxw (:eax ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::length)) :ecx) + (:leal ((:ecx ,movitz:+movitz-fixnum-factor+) #+ignore ,movitz:+movitz-fixnum-factor+) + :ebx) +;;; (:cmpl 0 (:eax ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0) + + (:call-global-constant cons-commit) + (:locally (:movl ,(bt:enum-value 'movitz::atomically-status :inactive) + (:edi (:edi-offset atomically-status)))) + pfix-pbig-done)) ))) (do-it))) @@ -797,88 +840,100 @@ (:movb 2 :cl) ; return values: qutient, remainder. (:stc))) ((positive-bignum positive-fixnum) - (let (r n) - (with-inline-assembly (:returns :multiple-values) - (:compile-form (:result-mode :ebx) number) - (:movzxw (:ebx #.(bt:slot-offset 'movitz::movitz-bignum 'movitz::length)) :ecx) - (:cmpl 1 :ecx) - (:jne 'not-size1) - (:compile-form (:result-mode :ecx) divisor) - (:shrl #.movitz:+movitz-fixnum-shift+ :ecx) - (:std) - (:movl (:ebx #.(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0)) :eax) - (:xorl :edx :edx) - (:divl :ecx :eax :edx) - (:movl :eax :ecx) - (:shll #.movitz:+movitz-fixnum-shift+ :edx) - (:movl :edi :eax) - (:cld) - (:pushl :edx) - (:call-global-constant box-u32-ecx) - (:popl :ebx) - (:jmp 'done) - not-size1 - (:cmpl 2 :ecx) - (:jne 'not-size2) - (:compile-form (:result-mode :ecx) divisor) - (:shrl #.movitz:+movitz-fixnum-shift+ :ecx) - (:std) - (:movl (:ebx #.(cl:+ 4 (bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0))) - :edx) - (:cmpl :ecx :edx) - (:jae 'not-size2) - (:movl (:ebx #.(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0)) :eax) - (:divl :ecx :eax :edx) - (:movl :eax :ecx) - (:shll #.movitz:+movitz-fixnum-shift+ :edx) - (:movl :edi :eax) - (:cld) - (:pushl :edx) - (:call-global-constant box-u32-ecx) - (:popl :ebx) - (:jmp 'done) - not-size2 - (:cmpl :ecx (:ebx #.(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0) - -4 (:ecx 4))) - (:jc 'shrink-not-size2) - not-shrink - (:leal ((:ecx #.movitz:+movitz-fixnum-factor+)) :eax) - (:compile-form (:result-mode :eax) - (malloc-words (with-inline-assembly (:returns :eax)))) - (:store-lexical (:lexical-binding r) :eax :type t) - (:compile-form (:result-mode :ebx) number) - (:movl (:ebx #.movitz:+other-type-offset+) :ecx) - (:movl :ecx (:eax #.movitz:+other-type-offset+)) - (:shrl 16 :ecx) + (macrolet + ((do-it () + `(let (r n) + (with-inline-assembly (:returns :multiple-values) + (:compile-form (:result-mode :ebx) number) + (:cmpw 1 (:ebx #.(bt:slot-offset 'movitz::movitz-bignum 'movitz::length))) + (:jne 'not-size1) + (:compile-form (:result-mode :ecx) divisor) + (:shrl #.movitz:+movitz-fixnum-shift+ :ecx) + (:std) + (:movl (:ebx #.(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0)) :eax) + (:xorl :edx :edx) + (:divl :ecx :eax :edx) + (:movl :eax :ecx) + (:shll #.movitz:+movitz-fixnum-shift+ :edx) + (:movl :edi :eax) + (:cld) + (:pushl :edx) + (:call-global-constant box-u32-ecx) + (:popl :ebx) + (:jmp 'done) + not-size1 + (:compile-form (:result-mode :ebx) number) + (:movzxw (:ebx #.(bt:slot-offset 'movitz::movitz-bignum 'movitz::length)) + :ecx) + + (:declare-label-set retry-jumper (not-size1)) + (:locally (:movl :esp (:edi (:edi-offset atomically-esp)))) + (:locally (:movl '(:funcall ,(movitz::atomically-status-jumper-fn t :esp) + 'retry-jumper) + (:edi (:edi-offset atomically-status)))) + + (:leal ((:ecx #.movitz:+movitz-fixnum-factor+) #.movitz:+movitz-fixnum-factor+) + :eax) ; Number of words + (:call-global-constant get-cons-pointer) ; New bignum into EAX + + + (:store-lexical (:lexical-binding r) :eax :type bignum) + (:compile-form (:result-mode :ebx) number) + (:movl (:ebx #.movitz:+other-type-offset+) :ecx) + (:movl :ecx (:eax #.movitz:+other-type-offset+)) + (:shrl 16 :ecx) - (:xorl :edx :edx) ; edx=hi-digit=0 + (:xorl :edx :edx) ; edx=hi-digit=0 ; eax=lo-digit=msd(number) - (:std) - (:compile-form (:result-mode :esi) divisor) - (:shrl #.movitz:+movitz-fixnum-shift+ :esi) - - divide-loop - (:load-lexical (:lexical-binding number) :ebx) - (:movl (:ebx #.(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0) - -4 (:ecx 4)) - :eax) - (:divl :esi :eax :edx) - (:load-lexical (:lexical-binding r) :ebx) - (:movl :eax (:ebx #.(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0) - -4 (:ecx 4))) - (:subl 1 :ecx) - (:jnz 'divide-loop) - (:movl :ebx :eax) - (:leal ((:edx #.movitz:+movitz-fixnum-factor+)) :ebx) - (:movl :edi :edx) - (:movl (:ebp -4) :esi) - (:cld) - (:jmp 'done) - shrink-not-size2 - (:int 107) - done - (:movl 2 :ecx) - (:stc)))) + (:std) + (:compile-form (:result-mode :esi) divisor) + (:shrl #.movitz:+movitz-fixnum-shift+ :esi) + + divide-loop + (:load-lexical (:lexical-binding number) :ebx) + (:movl (:ebx #.(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0) + -4 (:ecx 4)) + :eax) + (:divl :esi :eax :edx) + (:load-lexical (:lexical-binding r) :ebx) + (:movl :eax (:ebx #.(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0) + -4 (:ecx 4))) + (:subl 1 :ecx) + (:jnz 'divide-loop) + (:movl :edi :eax) ; safe value + (:leal ((:edx ,movitz:+movitz-fixnum-factor+)) :edx) + (:movl (:ebp -4) :esi) + (:cld) + (:movl :ebx :eax) + (:movl :edx :ebx) + + (:movzxw (:eax #.(bt:slot-offset 'movitz::movitz-bignum 'movitz::length)) + :ecx) + (:leal ((:ecx ,movitz:+movitz-fixnum-factor+) #.movitz:+movitz-fixnum-factor+) + :ecx) + (:cmpl 0 (:eax :ecx ,(+ -8 (bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0)))) + (:jne 'no-more-shrinkage) + + (:subw 1 (:eax #.(bt:slot-offset 'movitz::movitz-bignum 'movitz::length))) + (:subl ,movitz:+movitz-fixnum-factor+ :ecx) + (:cmpl ,(* 2 movitz:+movitz-fixnum-factor+) :ecx) + (:jne 'no-more-shrinkage) + (:cmpl ,movitz:+movitz-most-positive-fixnum+ + (:eax ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0))) + (:jnc 'no-more-shrinkage) + (:movl (:eax ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0)) + :ecx) + (:leal ((:ecx ,movitz:+movitz-fixnum-factor+)) :eax) + (:jmp 'fixnum-result) ; don't commit the bignum + no-more-shrinkage + (:call-global-constant cons-commit) + fixnum-result + (:locally (:movl ,(bt:enum-value 'movitz::atomically-status :inactive) + (:edi (:edi-offset atomically-status)))) + done + (:movl 2 :ecx) + (:stc))))) + (do-it))) ))))
(defun round (number &optional (divisor 1)) @@ -1268,17 +1323,22 @@ (t (n &optional (divisor 1)) (floor n divisor))))
+(define-compiler-macro %bignum-bigits (x) + `(with-inline-assembly (:returns :eax) + (:compile-form (:result-mode :eax) ,x) + (:movzxw (:eax #.(bt:slot-offset 'movitz::movitz-bignum + 'movitz::length)) + :ecx) + (:leal ((:ecx #.movitz:+movitz-fixnum-factor+)) + :eax))) + +(defun %bignum-bigits (x) + (%bignum-bigits x)) + (defun copy-bignum (old) (check-type old bignum) - (let* ((length (with-inline-assembly (:returns :eax) - (:compile-form (:result-mode :eax) old) - (:movzxw (:eax #.(bt:slot-offset 'movitz::movitz-bignum - 'movitz::length)) - :ecx) - (:leal ((:ecx #.movitz:+movitz-fixnum-factor+) - #.movitz:+movitz-fixnum-factor+) - :eax))) - (new (malloc-data-clumps length))) + (let* ((length (1+ (%bignum-bigits old))) + (new (malloc-data-words length))) (with-inline-assembly (:returns :eax) (:compile-two-forms (:eax :ebx) new old) (:compile-form (:result-mode :edx) length) @@ -1287,3 +1347,10 @@ (:movl (:ebx :edx #.movitz:+other-type-offset+) :ecx) (:movl :ecx (:eax :edx #.movitz:+other-type-offset+)) (:jnz 'copy-bignum-loop)))) + +(defun print-bignum (x) + (check-type x bignum) + (loop for i from 0 to (%bignum-bigits x) + do (format t "~8,'0X " (memref x -6 i :unsigned-byte32))) + (terpri) + (values)) \ No newline at end of file