[movitz-cvs] CVS update: movitz/losp/muerte/integers.lisp
Frode Vatvedt Fjeld
ffjeld at common-lisp.net
Sun Jun 6 14:25:22 UTC 2004
Update of /project/movitz/cvsroot/movitz/losp/muerte
In directory common-lisp.net:/tmp/cvs-serv11557
Modified Files:
integers.lisp
Log Message:
Multiplication of two fixnums, result overflowing into bignums, seems
to work.
Date: Sun Jun 6 07:25:22 2004
Author: ffjeld
Index: movitz/losp/muerte/integers.lisp
diff -u movitz/losp/muerte/integers.lisp:1.21 movitz/losp/muerte/integers.lisp:1.22
--- movitz/losp/muerte/integers.lisp:1.21 Sun Jun 6 03:24:29 2004
+++ movitz/losp/muerte/integers.lisp Sun Jun 6 07:25:22 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.21 2004/06/06 10:24:29 ffjeld Exp $
+;;;; $Id: integers.lisp,v 1.22 2004/06/06 14:25:22 ffjeld Exp $
;;;;
;;;;------------------------------------------------------------------
@@ -754,18 +754,76 @@
(numargs-case
(1 (x) x)
(2 (x y)
- (with-inline-assembly (:returns :eax)
- (:compile-form (:result-mode :eax) x)
- (:compile-form (:result-mode :ebx) y)
- (:movl :eax :ecx)
- (:orl :ebx :ecx)
- (:testb #.movitz::+movitz-fixnum-zmask+ :cl)
- (:jne '(:sub-program (not-fixnum)
- (:int 107)))
- (:movl :ebx :ecx)
- (:sarl #.movitz::+movitz-fixnum-shift+ :ecx)
- (:imull :ecx :eax :edx)
- (:into)))
+ (macrolet
+ ((do-it ()
+ `(number-double-dispatch (x y)
+ ((fixnum fixnum)
+ (let (d0 d1)
+ (with-inline-assembly (:returns :eax)
+ (:compile-two-forms (:eax :ecx) x y)
+ (:sarl ,movitz::+movitz-fixnum-shift+ :ecx)
+ (:std)
+ (:imull :ecx :eax :edx)
+ (:jno 'fixnum-result) ; most likely/optimized path.
+ (:cmpl ,movitz::+movitz-fixnum-factor+ :edx)
+ (:jc 'u32-result)
+ (:cmpl #xfffffffc :edx)
+ (:ja 'u32-negative-result)
+ (:jne 'two-bigits)
+ (:testl :eax :eax)
+ (:jnz 'u32-negative-result)
+ ;; The result requires 2 bigits..
+ two-bigits
+ (:shll ,movitz::+movitz-fixnum-shift+ :edx) ; guaranteed won't overflow.
+ (:cld)
+ (:store-lexical (:lexical-binding d0) :eax :type fixnum)
+ (:store-lexical (:lexical-binding d1) :edx :type fixnum)
+ (:compile-form (:result-mode :eax)
+ (malloc-data-words 3))
+ (:movl ,(dpb 2 (byte 16 16) (movitz:tag :bignum 0))
+ (:eax ,movitz:+other-type-offset+))
+ (:load-lexical (:lexical-binding d0) :ecx)
+ (:movl :ecx (:eax ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0)))
+ (:load-lexical (:lexical-binding d1) :ecx)
+ (:sarl ,movitz:+movitz-fixnum-shift+
+ :ecx)
+ (:shrdl ,movitz:+movitz-fixnum-shift+ :ecx
+ (:eax ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0)))
+ (:sarl ,movitz:+movitz-fixnum-shift+
+ :ecx)
+ (:movl :ecx (:eax ,(+ 4 (bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0))))
+ (:jns 'fixnum-done)
+ ;; if result was negative, we must negate bignum
+ (:notl (:eax ,(+ 4 (bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0))))
+ (:negl (:eax ,(bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0)))
+ (:cmc)
+ (:adcl 0 (:eax ,(+ 4 (bt:slot-offset 'movitz::movitz-bignum 'movitz::bigit0))))
+ (:xorl #xff00 (:eax ,movitz:+other-type-offset+))
+ (:jmp 'fixnum-done)
+
+ u32-result
+ (:movl :eax :ecx)
+ (:shrdl ,movitz::+movitz-fixnum-shift+ :edx :ecx)
+ (:movl :edi :edx)
+ (:cld)
+ (:call-global-constant box-u32-ecx)
+ (:jmp 'fixnum-done)
+
+ u32-negative-result
+ (:movl :eax :ecx)
+ (:shrdl ,movitz::+movitz-fixnum-shift+ :edx :ecx)
+ (:movl :edi :edx)
+ (:cld)
+ (:negl :ecx)
+ (:call-global-constant box-u32-ecx)
+ (:xorl #xff00 (:eax ,movitz:+other-type-offset+))
+ (:jmp 'fixnum-done)
+
+ fixnum-result
+ (:movl :edi :edx)
+ (:cld)
+ fixnum-done))))))
+ (do-it)))
(t (&rest factors)
(declare (dynamic-extent factors))
(if (null factors)
More information about the Movitz-cvs
mailing list