Index: /branches/ia32/level-0/X86/X8632/x8632-bignum.lisp
===================================================================
--- /branches/ia32/level-0/X86/X8632/x8632-bignum.lisp	(revision 7903)
+++ /branches/ia32/level-0/X86/X8632/x8632-bignum.lisp	(revision 7903)
@@ -0,0 +1,171 @@
+(in-package "CCL")
+
+;;; %BIGNUM-REF needs to access bignums as obviously as possible, and it needs
+;;; to be able to return 32 bits somewhere no one looks for real objects.
+;;;
+;;; The easiest thing to do is to store the 32 raw bits in two fixnums
+;;; and return multiple values.
+(defx8632lapfunction %bignum-ref ((bignum arg_y) (i arg_z))
+  (movzwl (@ x8632::misc-data-offset (% bignum) (% i)) (% imm0))
+  (box-fixnum imm0 temp1)		;low
+  (movzwl (@ (+ 2 x8632::misc-data-offset) (% bignum) (% i)) (% imm0))
+  (box-fixnum imm0 temp0)		;high
+  (push (% temp0))
+  (push (% temp1))
+  (set-nargs 2)
+  (jmp-subprim .SPvalues))
+
+;;; Set the 0th element of DEST (a bignum or some other 32-bit ivector)
+;;; to the Ith element of the bignum SRC.
+(defx8632lapfunction %ref-digit ((bignum 4) #|(ra 0)|# (i arg_y) (dest arg_z))
+  (movl (@ bignum (% esp)) (% temp0))
+  (movl (@ x8632::misc-data-offset (% temp0) (% i)) (% imm0))
+  (svset dest 0 imm0)
+  (single-value-return 3))
+
+;;; BIGNUM[I] := DIGIT[0]
+(defx8632lapfunction %set-digit ((bignum 4) #|(ra 0)|# (i arg_y) (digit arg_z))
+  (movl (@ bignum (% esp)) (% temp0))
+  (svref digit 0 imm0)
+  (movl (% imm0) (@ x8632::misc-data-offset (% temp0) (% i)))
+  (single-value-return 3))
+
+;;; Return 0 if the 0th digit in X is 0.
+(defx8632lapfunction %digit-zerop ((x arg_z))
+  (svref x 0 imm0)
+  (xorl (% arg_z) (% arg_z))
+  (testl (% imm0) (% imm0))
+  (cmovnz ($ x8632::nil-value) (% arg_z))
+  (single-value-return))
+
+;;; store the sign of bignum (0 or -1) in the one-word bignum "digit".
+(defx8632lapfunction %bignum-sign-digit ((bignum arg_y) (digit arg_z))
+  (vector-length bignum imm0)
+  (movl (@ (- 4 x8632::misc-data-offset) (% bignum) (% imm0)) (% imm0))
+  (shr ($ 31) (% imm0))			       ;propagate sign bit
+  (svset digit 0 imm0)
+  (single-value-return))
+
+;;; Return the sign of bignum (0 or -1) as a fixnum
+(defx8632lapfunction %bignum-sign ((bignum arg_z))
+  (vector-length bignum imm0)
+  (movl (@ (- 4 x8632::misc-data-offset) (% bignum) (% imm0)) (% imm0))
+  (shr ($ 31) (% imm0))			       ;propagate sign bit
+  (box-fixnum imm0 arg_z)
+  (single-value-return))
+
+;;; Count the sign bits in the most significant digit of bignum;
+;;; return fixnum count.
+(defx8632lapfunction %bignum-sign-bits ((bignum arg_z))
+  (vector-size bignum imm0 imm0)
+  (movl (@ (- x8632::misc-data-offset 4) (% bignum) (% imm0) 4) (% imm0))
+  (mark-as-imm temp0)
+  (movl (% imm0) (% temp0))
+  (notl (% imm0))
+  (testl (% temp0) (% temp0))
+  (js @wasneg)
+  (notl (% imm0))
+  @wasneg
+  (bsrl (% imm0) (% imm0))
+  (sete (% temp0.b))
+  (xorl ($ 31) (% imm0))
+  (addb (% temp0.b) (% imm0.b))
+  (box-fixnum imm0 arg_z)
+  (mark-as-node temp0)
+  (single-value-return))
+
+(defx8632lapfunction %digit-0-or-plusp ((bignum arg_y) (idx arg_z))
+  (xorl (% imm0) (% imm0))
+  (testl (@ x8632::misc-data-offset (% bignum) (% idx)) (% imm0))
+  (cmovbl ($ x8632::nil-value) (% arg_z))
+  (single-value-return))
+
+;;; For oddp, evenp
+(defx8632lapfunction %bignum-oddp ((bignum arg_z))
+  (testb ($ 1) (@ x8632::misc-data-offset (% bignum)))
+  (cmovzl ($ x8632::nil-value) (% arg_z))
+  (single-value-return))
+
+(defx8632lapfunction bignum-plusp ((bignum arg_z))
+  (vector-length bignum imm0)
+  (movl (@ (- 4 x8632::misc-data-offset) (% bignum)) (% imm0))
+  (testl ($ #x8000000) (% imm0))
+  (cmovnzl ($ x8632::nil-value) (% arg_z))
+  (single-value-return))
+
+(defx8632lapfunction %fixnum-to-bignum-set ((bignum arg_y) (fixnum arg_z))
+  (unbox-fixnum fixnum imm0)
+  (movl (% imm0) (@ x8632::misc-data-offset (% bignum)))
+  (single-value-return))
+
+(defx8632lapfunction bignum-minusp ((bignum arg_z))
+  (vector-length bignum imm0)
+  (movl (@ (- 4 x8632::misc-data-offset) (% bignum) (% imm0)))
+  (testl ($ #x8000000) (% imm0))
+  (cmovzl ($ x8632::nil-value) (% arg_z))
+  (single-value-return))
+
+;;; Add the digits A[I] and B[J], and the incoming carry C (a fixnum).
+;;; Store the result in R[K], and return the outgoing carry.
+;;; If I is NIL, A is a fixnum.  If J is NIL, B is a fixnum.
+(defx8632lapfunction %add-with-carry ((r 20) (k 16) (c 12) (a 8) (i 4) #|(ra 0)|# (b arg_y) (j arg_z))
+  (mark-as-imm temp0)
+  (unbox-fixnum b imm0)			;assume that j is going to be nil
+  (cmpl ($ x8632::nil-value) (% j))	;is j in fact nil?
+  (jne @got-b)
+  (movl (@ x8632::misc-data-offset (% b) (% j)) (% imm0))
+  @got-b
+  (movl (@ a (% esp)) (% arg_y))
+  (unbox-fixnum arg_y temp0)		;assume that i is going be nil
+  (movl (@ i (% esp)) (% arg_z))
+  (cmpl ($ x8632::nil-value) (% arg_z))	;is i in fact nil?
+  (jne @got-a)
+  (movl (@ x8632::misc-data-offset (% arg_y) (% arg_z)) (% temp0))
+  @got-a
+  ;; unboxed a or a[i] now in temp0
+  ;; unboxed b or b[j] now in imm0
+  (xorl (% arg_z) (% arg_z))
+  (movl (@ c (% esp)) (% arg_y))
+  (testl (% arg_y) (% arg_y))		;clears carry flag
+  (jz @add)
+  (stc)
+  @add
+  (adc (% temp0) (% imm0))
+  (cmovcl ($ fixnumone) (% arg_z))
+  (movl (@ r (% esp)) (% temp0))
+  (movl (@ k (% esp)) (% temp1))
+  (movl (% imm0) (@ x8632::misc-data-offset (% temp0) (% temp1)))
+  (mark-as-node temp0)
+  (single-value-return 7))
+
+;;; Store the result of A[I] - B[J] - borrow into R[K], returning the borrow.
+;;; If I is NIL, A is a fixnum; likewise for J and B.
+(defx8632lapfunction %subtract-with-borrow ((r 20) (k 16) (borrow 12) (a 8) (i 4) #|(ra 0)|# (b arg_y) (j arg_z))
+  (mark-as-imm temp0)
+  (unbox-fixnum b imm0)			;assume that j is going to be nil
+  (cmpl ($ x8632::nil-value) (% j))	;is j in fact nil?
+  (jne @got-b)
+  (movl (@ x8632::misc-data-offset (% b) (% j)) (% imm0))
+  @got-b
+  (movl (@ a (% esp)) (% arg_y))
+  (unbox-fixnum arg_y temp0)		;assume that i is going be nil
+  (movl (@ i (% esp)) (% arg_z))
+  (cmpl ($ x8632::nil-value) (% arg_z))	;is i in fact nil?
+  (jne @got-a)
+  (movl (@ x8632::misc-data-offset (% arg_y) (% arg_z)) (% temp0))
+  @got-a
+  ;; unboxed a or a[i] now in temp0
+  ;; unboxed b or b[j] now in imm0
+  (xorl (% arg_z) (% arg_z))
+  (movl (@ borrow (% esp)) (% arg_y))
+  (testl (% arg_y) (% arg_y))		;clears carry flag
+  (jz @sub)
+  (stc)
+  @sub
+  (sbb (% imm0) (% temp0))
+  (cmovcl ($ fixnumone) (% arg_z))
+  (movl (@ r (% esp)) (% temp0))
+  (movl (@ k (% esp)) (% temp1))
+  (movl (% imm0) (@ x8632::misc-data-offset (% temp0) (% temp1)))
+  (mark-as-node temp0)
+  (single-value-return 7))
