Update of /project/movitz/cvsroot/movitz/losp/muerte In directory common-lisp.net:/tmp/cvs-serv29249
Modified Files: integers.lisp Log Message: More bignum fixes. Added some slow-but-working implementations of * and truncate for bignums.
Date: Mon Jul 12 19:29:15 2004 Author: ffjeld
Index: movitz/losp/muerte/integers.lisp diff -u movitz/losp/muerte/integers.lisp:1.47 movitz/losp/muerte/integers.lisp:1.48 --- movitz/losp/muerte/integers.lisp:1.47 Mon Jul 12 07:17:14 2004 +++ movitz/losp/muerte/integers.lisp Mon Jul 12 19:29:15 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.47 2004/07/12 14:17:14 ffjeld Exp $ +;;;; $Id: integers.lisp,v 1.48 2004/07/13 02:29:15 ffjeld Exp $ ;;;; ;;;;------------------------------------------------------------------
@@ -68,6 +68,36 @@ (defun oddp (x) (not (evenp x)))
+ + +;;; Types + +(define-typep integer (x &optional (min '*) (max '*)) + (and (typep x 'integer) + (or (eq min '*) (<= min x)) + (or (eq max '*) (<= x max)))) + +(deftype signed-byte (&optional (size '*)) + (cond + ((eq size '*) + 'integer) + ((typep size '(integer 1 *)) + (list 'integer + (- (ash 1 (1- size))) + (1- (ash 1 (1- size))))) + (t (error "Illegal size for signed-byte.")))) + +(deftype unsigned-byte (&optional (size '*)) + (cond + ((eq size '*) + '(integer 0)) + ((typep size '(integer 1 *)) + (list 'integer 0 (1- (ash 1 size)))) + (t (error "Illegal size for unsigned-byte.")))) + +(define-simple-typep (bit bitp) (x) + (or (eq x 0) (eq x 1))) + ;;; Addition
(define-compiler-macro + (&whole form &rest operands &environment env) @@ -400,7 +430,7 @@ (:movl (:eax ,movitz:+other-type-offset+) :ecx) (:cmpb ,(movitz:tag :bignum) :cl) (:jne 'not-a-number) - (:cmpl ,(dpb 1 (byte 16 16) (movitz:tag :bignum 0)) :ecx) + (:cmpl ,(dpb 4 (byte 16 16) (movitz:tag :bignum 0)) :ecx) (:jne 'not-most-negative-fixnum) (:cmpl ,(- most-negative-fixnum) (:eax ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0))) @@ -423,15 +453,50 @@ ))) (do-it))) (2 (minuend subtrahend) - (cond - ((eq 0 minuend) - (- subtrahend)) - (t (check-type minuend fixnum) - (check-type subtrahend fixnum) - (with-inline-assembly (:returns :eax :side-effects nil) - (:compile-two-forms (:eax :ebx) minuend subtrahend) - (:subl :ebx :eax) - (:into))))) + (macrolet + ((do-it () + `(number-double-dispatch (minuend subtrahend) + ((t (eql 0)) + minuend) + (((eql 0) t) + (- subtrahend)) + ((fixnum fixnum) + (with-inline-assembly (:returns :eax :side-effects nil) + (:compile-two-forms (:eax :ebx) minuend subtrahend) + (:subl :ebx :eax) + (:into))) + ((bignum fixnum) + (+ (- subtrahend) minuend)) + ((fixnum bignum) + (- (+ (- minuend) subtrahend))) + ((positive-bignum positive-bignum) + (cond + ((= minuend subtrahend) + 0) + ((< minuend subtrahend) + (- (- subtrahend minuend))) + (t (%bignum-canonicalize + (with-inline-assembly (:returns :eax) + (:compile-two-forms (:eax :ebx) (copy-bignum minuend) subtrahend) + (:xorl :edx :edx) ; counter + (:xorl :ecx :ecx) ; carry + sub-loop + (:addl (:ebx :edx ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0)) + :ecx) + (:sbbl :ecx + (:eax :edx ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0))) + (:sbbl :ecx :ecx) + (:negl :ecx) + (:addl 4 :edx) + (:cmpw :dx (:ebx ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::length))) + (:jne 'sub-loop) + (:subl :ecx + (:eax :edx ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0))) + (:jc '(:sub-program (should-not-happen) + (:int 107))) + ))))) + ))) + (do-it))) (t (minuend &rest subtrahends) (declare (dynamic-extent subtrahends)) (if subtrahends @@ -1025,34 +1090,6 @@ ;;; (:andb #.(cl:logxor #xff movitz::+movitz-fixnum-zmask+) :al))) ;;; (t (if (= 0 integer) 0 (error "Illegal ash count: ~D" count)))))
-;;; Types - -(define-typep integer (x &optional (min '*) (max '*)) - (and (typep x 'integer) - (or (eq min '*) (<= min x)) - (or (eq max '*) (<= x max)))) - -(deftype signed-byte (&optional (size '*)) - (cond - ((eq size '*) - 'integer) - ((typep size '(integer 1 *)) - (list 'integer - (- (ash 1 (1- size))) - (1- (ash 1 (1- size))))) - (t (error "Illegal size for signed-byte.")))) - -(deftype unsigned-byte (&optional (size '*)) - (cond - ((eq size '*) - '(integer 0)) - ((typep size '(integer 1 *)) - (list 'integer 0 (1- (ash 1 size)))) - (t (error "Illegal size for unsigned-byte.")))) - -(define-simple-typep (bit bitp) (x) - (or (eq x 0) (eq x 1))) - ;;;;
(defun integer-length (integer) @@ -1267,10 +1304,11 @@ positive-result ))) ((positive-bignum positive-bignum) - (do ((f y) + (do ((mx (* most-positive-fixnum x)) + (f y) (r 0)) ((typep f 'fixnum) (+ r (* f x))) - (setf r (+ r (* most-positive-fixnum x))) + (setf r (+ r mx)) (setf f (- f most-positive-fixnum)))) ))) (do-it))) @@ -1402,7 +1440,9 @@ (cond ((= number divisor) (values 1 0)) ((< number divisor) (values 0 number)) - (t (error "Don't know how to divide ~S with ~S." number divisor)))) + (t (do ((q 0 (1+ q)) + (r number (- r divisor))) + ((< r divisor) (values q r)))))) ))))
(defun / (number &rest denominators)