[movitz-cvs] CVS update: movitz/losp/muerte/bignums.lisp

Frode Vatvedt Fjeld ffjeld at common-lisp.net
Sun Jul 18 08:45:40 UTC 2004


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

Modified Files:
	bignums.lisp 
Log Message:
Wrote %bignum-subf.

Date: Sun Jul 18 01:45:39 2004
Author: ffjeld

Index: movitz/losp/muerte/bignums.lisp
diff -u movitz/losp/muerte/bignums.lisp:1.1 movitz/losp/muerte/bignums.lisp:1.2
--- movitz/losp/muerte/bignums.lisp:1.1	Sat Jul 17 12:30:09 2004
+++ movitz/losp/muerte/bignums.lisp	Sun Jul 18 01:45:39 2004
@@ -10,7 +10,7 @@
 ;;;; Author:        Frode Vatvedt Fjeld <frodef at acm.org>
 ;;;; Created at:    Sat Jul 17 19:42:57 2004
 ;;;;                
-;;;; $Id: bignums.lisp,v 1.1 2004/07/17 19:30:09 ffjeld Exp $
+;;;; $Id: bignums.lisp,v 1.2 2004/07/18 08:45:39 ffjeld Exp $
 ;;;;                
 ;;;;------------------------------------------------------------------
 
@@ -64,7 +64,7 @@
 
 (defun copy-bignum (old)
   (check-type old bignum)
-  (let* ((length (%bignum-bigits old))
+  (let* ((length (ceiling (integer-length old) 32))
 	 (new (malloc-non-pointer-words (1+ length))))
     (with-inline-assembly (:returns :eax)
       (:compile-two-forms (:eax :ebx) new old)
@@ -172,3 +172,55 @@
 	      add-bignum-done)))
        (do-it)))))
 
+(defun %bignum-subf (bignum delta)
+  "Destructively subtract (abs delta) from bignum."
+  (check-type bignum bignum)
+  (etypecase delta
+    (positive-fixnum
+     (%bignum-addf-fixnum bignum (- delta)))
+    (negative-fixnum
+     (%bignum-addf-fixnum bignum delta))
+    (bignum
+     (macrolet
+	 ((do-it ()
+	    `(with-inline-assembly (:returns :eax)
+	      not-size1
+	       (:load-lexical (:lexical-binding bignum) :eax) ; EAX = bignum
+	       (:load-lexical (:lexical-binding delta) :ebx) ;  EBX = delta
+	       (:xorl :edx :edx)	; Counter
+	       (:xorl :ecx :ecx)	; Carry
+	      sub-bignum-loop
+	       (:cmpw :dx (:eax (:offset movitz-bignum length)))
+	       (:jbe '(:sub-program (overflow) (:int 4)))
+	       (:addl (:ebx :edx (:offset movitz-bignum :bigit0))
+		      :ecx)
+	       (:jz 'carry+digit-overflowed) ; If CF=1, then ECX=0.
+	       (:subl :ecx (:eax :edx (:offset movitz-bignum bigit0)))
+	      carry+digit-overflowed
+	       (:sbbl :ecx :ecx)
+	       (:negl :ecx)		; ECX = Add's Carry.
+	       (:addl 4 :edx)
+	       (:cmpw :dx (:ebx (:offset movitz-bignum length)))
+	       (:ja 'sub-bignum-loop)
+	       ;; Now, if there's a carry we must propagate it.
+	       (:jecxz 'sub-bignum-done)
+	      carry-propagate-loop
+	       (:cmpw :dx (:eax (:offset movitz-bignum length)))
+	       (:jbe '(:sub-program (overflow) (:int 4)))
+	       (:addl 4 :edx)
+	       (:subl 1 (:eax :edx (:offset movitz-bignum bigit0 -4)))
+	       (:jc 'carry-propagate-loop)
+      sub-bignum-done)))
+       (do-it)))))
+
+(defun %bignum-set-zerof (bignum)
+  (check-type bignum bignum)
+  (dotimes (i (logior 1 (%bignum-bigits bignum)))
+    (setf (memref bignum -2 i :lisp) 0))
+  bignum)
+
+(defun %bignum= (x y)
+  (compiler-macro-call %bignum= x y))
+
+(defun %bignum< (x y)
+  (compiler-macro-call %bignum< x y))





More information about the Movitz-cvs mailing list