;;;-*- Mode:LISP; Package:NEW-MATH; Base:10; Readtable:CL -*- ;;; ;;; Written by Youcef Bennour. ;;; ;;;*********************************** ;;;* * ;;;* D I S P A T C H T A B L E * ;;;* * ;;;*********************************** (defafun binary-bignum-op-dispatch-table (x y) (alu L+R+C md a0 a1 ch-return next-pc-return unboxed-md) ; 0 is for ADD (alu L-R-C md a0 a1 ch-return next-pc-return unboxed-md) ; 1 is for SUB AND (alu AND md a0 a1 ch-return next-pc-return unboxed-md) ; 2 is for AND OR (alu OR md a0 a1 ch-return next-pc-return unboxed-md) ; 3 is for IOR (alu XOR md a0 a1 ch-return next-pc-return unboxed-md) ; 4 is for XOR (alu XNOR md a0 a1 ch-return next-pc-return unboxed-md) ; 5 is for EQV (branch NOT (alu AND a2 a0 a1 boxed)) ; 6 is for NAND (branch NOT (alu OR a2 a0 a1 boxed)) ; 7 is for NOR (branch AND (alu not-r a0 ignore a0 boxed)) ; 8 is for ANDC1 (branch AND (alu not-r a1 ignore a1 boxed)) ; 9 is for ANDC2 (branch OR (alu not-r a0 ignore a0 boxed)) ; 10 is for ORC1 (branch OR (alu not-r a1 ignore a1 boxed)) ; 11 is for ORC2 NOT (alu not-r md ignore a2 ch-return next-pc-return unboxed-md) ; complement answer and return. ) ;;;**************************************** ;;;* * ;;;* B I G N U M O P E R A T I O N S * ;;;* * ;;;**************************************** (defun add-bignum (a b) (binary-bignum-operation a b 0 0)) (defun subtract-bignum (a b) (binary-bignum-operation a b 1 hw:$$alu-status-carry)) (defun logand-bignum (a b) (binary-bignum-operation a b 2 0)) (defun logior-bignum (a b) (binary-bignum-operation a b 3 0)) (defun logxor-bignum (a b) (binary-bignum-operation a b 4 0)) (defun logxnor-bignum (a b) (binary-bignum-operation a b 5 0)) (defun lognand-bignum (a b) (binary-bignum-operation a b 6 0)) (defun lognor-bignum (a b) (binary-bignum-operation a b 7 0)) (defun logandc1-bignum (a b) (binary-bignum-operation a b 8 0)) (defun logandc2-bignum (a b) (binary-bignum-operation a b 9 0)) (defun logorc1-bignum (a b) (binary-bignum-operation a b 10. 0)) (defun logorc2-bignum (a b) (binary-bignum-operation a b 11. 0)) (defafun binary-bignum-operation (bignum1 bignum2 operation starting-status-reg) ;; a0 <---- bignum 1 pointer ;; a1 <---- bignum 2 pointer ;; a2 <---- operation ;; a3 <---- status register to load before the operation. ;; Locals ;; a4 <----- length of first bignum ;; a5 <----- length of second bignum ;; a6 <----- Sign extension of shorter bignum ;; a7 <----- 32 bit word from first operand ;; a8 <----- 32 bit word from second operand ;; a9 <----- temp for initial status overflow. ;; a10 <----- pointer to result bignum structure. ;; a11 <----- index stepping through the words of bignums ;; a13 <----- Flag to indicate swap of arguments. Needed for subtraction. --wkf (move vma-start-read a0 boxed-vma boxed-md) ; read header of first bignum (move a13 gr:*zero*) ; Initialize the flag. (alu merge-r a4 gr:*zero* MD bw-24 boxed) ; length of first bignum in a4 (move vma-start-read a1 boxed-vma boxed-md) ; read header of second bignum (alu L+1 a11 a4 ignore bw-24 boxed) ; size of bignum result structure (while waiting on md) (alu merge-r a5 gr:*zero* MD bw-24 boxed) ; length of second bignum in a5 (alu L-R nop a4 a5 bw-24 unboxed) ; difference of length (alu L-R nop a4 a5 bw-24 unboxed br-equal) ; test for equal length (branch alloc-struc-for-res () br-greater-than) ; length are equal go to start. otherwise test for less than (branch sign-ext-of-shorter-bignum ()) second->-first ;; Swap pointers such that a0 will have the pointer of the bignum with the most words, a1 will have the other. ;; Sign extension of shorter bignum in a7. a4 has the max of length and a5 the min. ;; use a11 as a temp. (move a11 a0) (move a0 a1) (move a1 a11) ;; Swap lengths (move a11 a4) (move a4 a5) (move a5 a11) (move a13 a2) ;;Record the fact that we swapped the arguments. sign-ext-of-shorter-bignum ;; Start reading the most significant word of shorter bignum (alu L+R vma-start-read-no-transport a1 a5 unboxed-vma unboxed-md) ;; while waiting compute size of result bignum structure. (alu L+1 a11 a4 ignore bw-24 boxed) ; size of bignum result structure ;; wait until you get the result of the read (move a6 MD) (alu SIGN a6 ignore ignore unboxed) ; sign extension of the shorter bignum. alloc-struc-for-res ;; already computed. (alu L+1 a11 a4 ignore bw-24 boxed) ; size of bignum structure (OPEN-CALL (allocate-bignum 1) a10 (O0 a11)) ; allocate the structure. ;; Start the operation. (movei a11 1 unboxed) ; initialize index. (movea a12 (binary-bignum-op-dispatch-table 2)) ; get address of the dispatch table (alu L+R a12 a2 a12 boxed) ; compute the dispatch address. next-word (alu L+R vma-start-read-no-transport a11 a0 bw-24 unboxed-vma unboxed-md) ; get next word of bignum pointed to by a0 (nop) (move O0 MD CH-OPEN) ; first argument in open 0 (alu L+R vma-start-read-no-transport a11 a1 bw-24 unboxed-vma unboxed-md) ; get next word of bignum pointed to by a1 (nop) ;; dispatch to the right operation. (move nop a12) (move O1 MD) ; second argument in open 1 (alu load-status-r nop ignore a3 ch-call next-pc-dispatch) ; Dispatch to appropriate operation. (alu pass-status a3 ignore ignore unboxed) ; save status for next operation (alu L+R vma-start-write-no-gc-trap a11 a10 bw-24 unboxed-vma); write result (alu L-R nop a11 a5 bw-24 unboxed) ; are we done? (alu L+1 a11 a11 ignore bw-24 br-less-than unboxed) ; increment counter while deciding if we are done with this. (branch next-word ()) any-remaining-words (alu L-R nop a11 a4 bw-24 unboxed) (test br-greater-than) (branch computation-done ()) (alu L+R vma-start-read-no-transport a0 a11 bw-24 unboxed-vma unboxed-md) ; get next word of bignum pointed to by a0 (move O1 a6 CH-OPEN) ; first argument in open 0 (move nop a12) ; Set up dispatch address (move O0 MD) ; word from memory must be here now. (alu load-status-r nop ignore a3 ch-call next-pc-dispatch) ; Dispatch to appropriate operation. (alu pass-status a3 ignore ignore unboxed) ; Save status (alu L+R vma-start-write-no-gc-trap a10 a11 bw-24 unboxed-vma) ; Write answer (unconditional-branch any-remaining-words (alu L+1 a11 a11 ignore bw-24 unboxed)) ; Increment for the next word. computation-done (alu-field field-xor a15 a3 gr:*all-zero* (byte 15. 17.) unboxed) ;last word = extend(N xor V) = (byte 1 14.) of status (alu SIGN MD ignore ignore unboxed-md) (alu L+R vma-start-write-no-gc-trap a11 a10 unboxed-vma) ;; try to see if we can shrink this. (alu L-R nop a13 gr:*one* bw-24 unboxed) (test br-equal) (branch negate-answer ()) (tail-open-call (shrink-bignum-structure 1) (o0 a10)) negate-answer (tail-open-call (negate-bignum 1) (o0 a10)) ) (defafun negate-bignum (bignum) ;; Should build a new bignum of size 1+ current one. @@@ This is rarely true, answer is normally same size. --wkf ;; Flip bits and add one. ;; Edge cases are: ;; 1) #x800000 becomes fixnum #x-800000 ;; 2) #x80000000 (n+1 words) becomes #x-80000000 (n words) ;; a0 <---- pointer to bignum. ;; LOCALS ;; a1 <---- Index counter. ;; a2 <---- Bignum length. ;; a4 <---- Save register status - Must be initialized with carry = 1 ;; a5 <---- Save status of overflow traps. ;; a6 <---- Temp ;; a7 <---- pointer to bignum result. (move vma-start-read a0 boxed-vma boxed-md) ; Read bignum header. (movei a1 1) ; Init counter loop. (movei a4 hw:$$alu-status-carry) ; Save status register with carry set initially. (alu merge-r a2 gr:*zero* MD bw-24 boxed) ; Get length of bignum. (alu R+1 a6 ignore a2 bw-24 boxed) ; Expected size of bignum result. (OPEN-CALL (allocate-bignum 1) a7 (O0 a6)) ; allocate a bignum structure. next-word (alu L+R vma-start-read-no-transport a1 a0 unboxed-vma unboxed-md) ; Get next word (alu load-status-r nop ignore a4 unboxed) ; Restore status register (alu L-R-C MD gr:*all-zero* MD unboxed-md) ; If there was a carry, it is added to the next word. (alu pass-status a4 ignore ignore unboxed) ; Save status for next time around. (alu L+R vma-start-write-no-gc-trap a7 a1 unboxed-vma) ; Write word back to storage. (alu L-R nop a1 a2 bw-24 unboxed) ; Are we done? (alu L+1 a1 a1 ignore bw-24 br-less-than unboxed) ; Increment counter. (branch next-word ()) (alu-field field-xor a6 a4 gr:*all-zero* (byte 15. 17.) unboxed) ;last word = extend(N xor V) = (byte 1 14.) of status (alu SIGN MD ignore ignore unboxed-md) (alu L+R vma-start-write-no-gc-trap a7 a1 unboxed-vma) ; Write it. (tail-open-call (shrink-bignum-structure 1) (O0 a7)) ; Call shrink bignum routine. ) (defafun lognot-bignum (bignum) ;; a0 <---- pointer to bignum ;; LOCALS ;; a1 <---- Index counter. ;; a2 <---- Length of bignum. ;; a3 <---- pointer to bignum result. (move vma-start-read a0 boxed-vma boxed-md) ; Read bignum header. (movei a1 '1) ; Init counter for loop. (alu merge-r a2 gr:*zero* MD bw-24 boxed) ; Get the bignum length (OPEN-CALL (allocate-bignum 1) a3 (O0 a2)) ; allocate a new bignum structure of same size. next-word (alu L+R vma-start-read-no-transport a1 a0 bw-24 unboxed-vma unboxed-md) ; Get next word. (nop) (alu not-r MD ignore MD unboxed) ; Complement the word. (alu L+R vma-start-write-no-gc-trap a1 a3 unboxed-vma) ; write the word back to result. (alu L-R nop a1 a2 bw-24 unboxed) ; Are we done? (alu L+1 a1 a1 ignore bw-24 br-less-than unboxed) ; Increment counter. (branch next-word ()) (tail-open-call (shrink-bignum-structure 1) (o0 a3)) ) (defafun zero-bignum-internal (bignum) ;;; not a user routine, modifies the passed bignum! ;; a0 <---- pointer to bignum ;; Returns a bignum with all the words containing zero. ;; Must have the same length as before, do not call the shrink routine. ;; LOCALS ;; a1 <---- Index to bignum words. ;; a2 <---- Length of bignum in words. (move vma-start-read a0 boxed-vma boxed-md) ; Read bignum header (movei a1 '1) ; Init index register (alu merge-r a2 ignore MD bw-24 boxed) ; Get the length of the bignum. (movei md 0 unboxed-md) ; Value to write into bignum words next-word (alu L+R vma-start-write-no-gc-trap a1 a0 bw-24 unboxed-vma) ; write 0 to current word. (alu L-R nop a1 a2 bw-24 unboxed) ; Are we done? (alu L+1 a1 a1 ignore bw-24 br-less-than unboxed) ; Increment counter. (branch next-word ()) (return a0 boxed-right) ) ;;;***************************************** ;;;* * ;;;* M U L T P L I C A T I O N S * ;;;* * ;;;***************************************** ;;; A = (-AS * 2**(n-1)) + AM ;;; B = (-BS * 2**(m-1)) + BM ;;; ;;; A * B = (AS * BS * 2**(n+m-2)) ---> non-zero if both negative ;;; - (AS * BM * 2**(n-1)) ---> non-zero if A negative ;;; - (BS * AM * 2**(m-1)) ---> non-zero if B negative ;;; + (AM * BM) ---> product of all but the sign bits (unsigned multiply) ;;; ;;; AM = (AH * 2**(n/2)) + AL ;;; BM = (BH * 2***m/2)) + BL ;;; ;;; AM * BM = (AH * BH * 2**((m+n)/2)) ; wallace tree ;;; + (AH * BL * 2**(n/2)) ;;; + (BH * AL * 2**(m/2)) ;;; + (AL * BL) (defun multiply-bignum (a-ptr b-ptr) ;;; C = A * B (let* ((a-size (hw:dpb (%vm-read a-ptr) vinc:%%bignum-words gr:*zero*)) (b-size (hw:dpb (%vm-read b-ptr) vinc:%%bignum-words gr:*zero*)) (c-size (+ a-size b-size)) (c-ptr (allocate-bignum c-size)) (a-data (%vm-read24 a-ptr a-size)) (b-data (%vm-read24 b-ptr b-size)) (a-sign (hw:ldb a-data vinc:%%bignum-sign-high-word gr:*zero*)) (b-sign (hw:ldb b-data vinc:%%bignum-sign-high-word gr:*zero*))) ;; (zero-bignum-internal c-ptr) ;;||| Not needed. 9/26/88 --wkf (when (not (or (zerop a-sign) (zerop b-sign))) (%vm-write24 c-ptr c-size (hw:unboxed-constant #x40000000))) (when (not (zerop a-sign)) (subtract-shifted-bignum-from-result b-ptr b-size c-ptr c-size a-size)) (when (not (zerop b-sign)) (subtract-shifted-bignum-from-result a-ptr a-size c-ptr c-size b-size)) (do ((a-index 1 (1+ a-index))) ((> a-index a-size)) (setq a-data (if (= a-index a-size) (hw:dpb-unboxed (%vm-read24 a-ptr a-index) vinc:%%bignum-non-sign-high-word gr:*all-zero*) (%vm-read24 a-ptr a-index))) (do ((b-index 1 (1+ b-index))) ((> b-index b-size)) (setq b-data (if (= b-index b-size) (hw:dpb-unboxed (%vm-read24 b-ptr b-index) vinc:%%bignum-non-sign-high-word gr:*all-zero*) (%vm-read24 b-ptr b-index))) (umul32-and-add-to-result a-data b-data (1- (+ a-index b-index)) c-ptr c-size))) (shrink-bignum-structure c-ptr))) (defafun umul32-and-add-to-result (a-data b-data c-offset c-ptr c-size) ;; a0 <---- multiplicand a ;; a1 <---- multiplier b ;; a2 <---- c offset fixnum ;; a3 <---- c-ptr ;; a4 <---- c-size fixnum +++ This code requires that c-size is big enough so that we can not carry beyond edge of c-ptr bignum 9/26/88 --wkf ;; Result will be in ;; Q reg for low product ;; a14 for high product. ;; Returns 2 registers value ;; low-product return register ;; high-product a14 (alu load-q-r nop a0 a0 unboxed) (alu umul-first a14 a1 gr:*all-zero* unboxed) (alu umul-step a14 a1 a14 unboxed) (alu umul-step a14 a1 a14 unboxed) (alu umul-step a14 a1 a14 unboxed) (alu umul-step a14 a1 a14 unboxed) (alu umul-step a14 a1 a14 unboxed) (alu umul-step a14 a1 a14 unboxed) (alu umul-step a14 a1 a14 unboxed) (alu umul-step a14 a1 a14 unboxed) (alu umul-step a14 a1 a14 unboxed) (alu umul-step a14 a1 a14 unboxed) (alu umul-step a14 a1 a14 unboxed) (alu umul-step a14 a1 a14 unboxed) (alu umul-step a14 a1 a14 unboxed) (alu umul-step a14 a1 a14 unboxed) (alu umul-step a14 a1 a14 unboxed) (alu umul-last a14 a1 a14 unboxed) ;high result (alu l+r vma-start-read-no-transport a2 a3 bw-24 unboxed-vma unboxed-md) (alu pass-q a15 ignore ignore unboxed) ;low result (alu l+r md-start-write-no-gc-trap a15 md unboxed-md) (alu pass-status a15 ignore ignore unboxed) (alu r+1 a2 ignore a2 bw-24) (alu l+r vma-start-read-no-transport a2 a3 bw-24 unboxed-vma unboxed-md) (alu load-status-r nop ignore a15) (alu l+r+c md-start-write-no-gc-trap a14 md unboxed-md) add-loop ;;; ||| This whole loop redone to speed it up and fix bug. 9/26/88 --wkf (alu l+r+c a15 gr:*all-zero* gr:*all-zero* unboxed) (alu r+1 a2 ignore a2 bw-24 br-zero) ;; (test br-zero) When there is no carry bit we are done. --wkf (branch done (alu l+r vma-start-read-no-transport a2 a3 bw-24 unboxed-vma unboxed-md)) ;; +++ The following removed since bignum c is guaranteed by caller to be big enough so carry is inside it without overflowing. --wkf ;; (alu l-r nop a2 a4 bw-24) ;; (test br-greater-or-equal) ;;Isn't br-equal sufficient? 9/26/88 --wkf ;; (branch done ()) (alu pass-status nop ignore ignore) ;;Wait for the MD to be filled with result of read. --wkf (unconditional-branch add-loop (alu l+r md-start-write-no-gc-trap a15 md unboxed-md)) done (return a3 boxed-right) ) (defafun subtract-shifted-bignum-from-result (from-ptr from-size to-ptr to-size shift) ; a0 - from-ptr ; a1 - from-size ; a2 - to-ptr ; a3 - to-size ; a4 - shift this many words less one bit (to-index) ; a5 - from index ; a6 - from high data ; a7 - from low data ; a8 - saved status reg ; a9 - current word to be summed (alu r+1 vma-start-read-no-transport ignore a0 unboxed-vma unboxed-md) (movei a5 1 unboxed) (move a7 gr:*all-zero* unboxed) (movei a8 hw:$$alu-status-carry unboxed) (move a6 md) sub-loop (alu l+r vma-start-read-no-transport a2 a4 unboxed-vma unboxed-md) (alu-field field-extract-lr a9 a6 a7 (byte 32. -1.)) (alu load-status-r nop ignore a8) (alu r-l-c md-start-write-no-gc-trap a9 md unboxed-md) (alu pass-status a8 ignore ignore unboxed) (alu l-r nop a4 a3 bw-24) (alu l-r nop a5 a1 bw-24 br-greater-or-equal) (branch done (alu r+1 a4 ignore a4 bw-24 br-greater-or-equal)) (branch from-extend (alu r+1 a5 ignore a5 bw-24)) (alu l+r vma-start-read-no-transport a0 a5 unboxed-vma unboxed-md) (move a7 a6) (unconditional-branch sub-loop (move a6 md)) from-extend (alu-field field-extract-r a7 ignore a6 (byte 31. 0.)) (unconditional-branch sub-loop (move a6 gr:*all-zero*)) done (return a2 boxed-right) ) ;;;******************************* ;;;* * ;;;* D I V I S I O N S * ;;;* * ;;;******************************* (defun divide-bignum (dividend divisor) (let* ((dividend-size (hw:ldb (%vm-read dividend) vinc:%%fixnum-field 0)) (divisor-size (hw:ldb (%vm-read divisor) vinc:%%fixnum-field 0)) (dividend-data (%vm-read32 dividend dividend-size)) (divisor-data (%vm-read32 divisor divisor-size)) (quotient (allocate-bignum dividend-size)) (remainder (allocate-bignum divisor-size)) ) (cond ((and (hw:32zerop divisor-data) (= divisor-size 1)) ;zero divide only possible by coercion (trap:illop "Zero divide error")) ((= divisor-size 1) (if (= dividend-size 1) (divide-bignum-one-word-long dividend-data divisor-data quotient remainder) (let ((status 0)) (do ((index dividend-size (1- index)) (first t nil)) ((zerop index)) (setq status (divide-bignum-one-word-divisor dividend divisor-data quotient remainder index status first))) (divide-bignum-return-results quotient dividend-size remainder divisor-size status dividend-data divisor)))) (t (let ((status 0)) (do ((index dividend-size (1- index)) (first t nil)) ((zerop index)) (setq status (divide-bignum-internal dividend divisor divisor-size divisor-data quotient remainder index status first))) (divide-bignum-return-results quotient dividend-size remainder divisor-size status dividend-data divisor)))))) (defafun divide-bignum-one-word-divisor (dividend divisor-data quotient remainder index status first) ; a0 - dividend pointer ; a1 - divisor data ; a2 - quotient pointer ; a3 - remainder pointer ; a4 - dividend/quotient index ; a5 - status word ; a6 - first time flag ; ; a8 - remainder sign extend ; a9 - remainder data ; a10 - divisor sign extend ; a13 - outer loop count (alu l+r vma-start-read-no-transport a0 a4 unboxed-vma unboxed-md) ;read dividend word (alu-field nb-shift-ar-r a10 ignore a1 (byte 0. -32.) unboxed) ;sign extension of divisor (move nop a6) (movei a13 '32 br-not-zero) ;32 iterations in outer loop (branch setup-first (alu load-q-r nop ignore md)) ;Q = dividend word (alu r+1 vma-start-read-no-transport ignore a3 unboxed-vma unboxed-md) ;midpoint correct remainder (alu load-status-r nop ignore a5) (alu shift-dn-0f-r a15 ignore md) (alu shift-up-0f-rq a9 ignore a15 unboxed-md) (unconditional-branch outer-loop-setup (alu pass-status a5 ignore ignore unboxed)) setup-first (alu sign a9 ignore ignore unboxed-md) ;initialize remainder for first pass (alu sdiv-first a9 a10 a9 unboxed-md) (alu pass-status a5 ignore ignore unboxed) outer-loop-setup (alu-field nb-shift-ar-r a8 ignore a9 (byte 0. -32.) unboxed) ;sign extension of remainder outer-loop (alu r-1 a13 ignore a13 bw-24) (alu load-status-r nop ignore a5 br-zero) (branch last-loop (alu mp-div-step1 a9 a1 a9 unboxed)) (alu mp-sdiv-step3 a8 a10 a8 unboxed) (unconditional-branch outer-loop (alu pass-status a5 ignore ignore unboxed)) last-loop (alu mp-sdiv-step3 a8 a10 a8 unboxed) (alu pass-status a5 ignore ignore unboxed) (move md a9 unboxed-md) (alu r+1 vma-start-write-no-gc-trap ignore a3 unboxed-vma) ;save remainder (nop) (alu pass-q md ignore ignore unboxed-md) ;save quotient (alu l+r vma-start-write-no-gc-trap a2 a4 unboxed-vma) (return a5 boxed-right) ) (defafun divide-bignum-internal (dividend divisor divisor-size divisor-high quotient remainder index status first) ; a0 - dividend pointer ; a1 - divisor pointer ; a2 - divisor size ; a3 - divisor high data ; a4 - quotient pointer ; a5 - remainder pointer ; a6 - dividend/quotient index ; a7 - status word ; a8 - first time flag ; ; a10 - current index ; a11 - current dividend data ; a12 - current divisor data ; a13 - outer loop count (alu l+r vma-start-read-no-transport a0 a6 unboxed-vma unboxed-md) ;read dividend word (movei a13 '32) ;32 iterations in outer loop (move nop a8) (move a15 a2 br-not-zero) (branch setup-first (alu load-q-r nop ignore md)) ;Q = dividend word (alu r+1 vma-start-read-no-transport ignore a5 unboxed-vma unboxed-md) ;midpoint correct remainder (alu load-status-r nop ignore a7) (alu shift-dn-0f-r a15 ignore md) (alu shift-up-0f-rq md-start-write-no-gc-trap ignore a15 unboxed-md) (unconditional-branch outer-loop (alu pass-status a7 ignore ignore unboxed)) setup-first (alu sign md ignore ignore unboxed-md) ;initialize remainder for first pass setup-loop (alu l+r vma-start-write-no-gc-trap a5 a15 unboxed-vma) (alu r-1 a15 ignore a15 bw-24) (test br-not-zero) (branch setup-loop ()) (alu r+l vma-start-read-no-transport a2 a1 unboxed-vma unboxed-md) ;divisor hi (nop) (move r3 md) (alu r+1 vma-start-read-no-transport ignore a5 unboxed-vma unboxed-md) ;remainder lo (nop) (alu sdiv-first md-start-write-no-gc-trap r3 md unboxed-md) (alu pass-status a7 ignore ignore unboxed) outer-loop (movei a10 '0) ;index = 0 inner-loop (alu l+r+c vma-start-read-no-transport a1 a10 unboxed-vma unboxed-md carry-1) ;A8 = divisor word (alu r+1 a10 ignore a10 bw-24) (move a8 md) (alu l+r vma-start-read-no-transport a5 a10 unboxed-vma unboxed-md) ;MD = remainder word (alu l-r nop a10 gr:*one* bw-24) (alu l-r nop a10 a2 br-equal bw-24) (branch first (alu load-status-r nop ignore a7 br-equal)) (branch last (alu load-status-r nop ignore a7)) middle (alu mp-div-step2 md-start-write-no-gc-trap a8 md unboxed-md) (unconditional-branch inner-loop (alu pass-status a7 gr:*zero* gr:*zero* bw-24)) first (alu mp-div-step1 md-start-write-no-gc-trap a8 md unboxed-md) (unconditional-branch inner-loop (alu pass-status a7 gr:*zero* gr:*zero* bw-24)) last (alu mp-sdiv-step3 md-start-write-no-gc-trap a8 md unboxed-md) (alu pass-status a7 gr:*zero* gr:*zero* bw-24) (alu r-1 a13 ignore a13 bw-24) (test br-not-zero) (branch outer-loop (alu pass-q md ignore ignore unboxed-md)) (alu l+r vma-start-write-no-gc-trap a4 a6 unboxed-vma) (return a7 boxed-right) ) (defafun divide-bignum-one-word-long (dividend-data divisor-data quotient-ptr remainder-ptr) (alu load-q-r a4 a0 a0 ) ;q <- dividend (alu sign a4 a0 a0 bw-32) ;sign extend initial remainder (alu sdiv-first a4 a1 a4) ;step 1 (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-step a4 a1 a4) (alu sdiv-last1 a4 a1 a4) ;first fixup (alu pass-q a5 a1 a1 br-equal) ;no fixup2 if zero, save quotient maybe (branch done (alu setr md ignore a5 unboxed-md)) (alu sdiv-last2 nop a1 a4) ;second fixup (move nop a4) (alu rem-corr a4 a1 a4) (alu pass-q a5 a1 a1) ;save fixed quotient (alu quo-corr md a5 a5 unboxed-md) ;final fixup done (alu pass-status a14 gr:*zero* gr:*zero* boxed bw-24) (alu r+1 vma-start-write-no-gc-trap ignore a2) (nop) (move md a4 unboxed-md) (alu r+1 vma-start-write-no-gc-trap ignore a3) (open-call (shrink-bignum-structure 1) a13 (o0 a3)) (open-call (shrink-bignum-structure 1) a2 (o0 a2)) (movei gr:*number-of-return-values* '3 boxed) (move gr:*return-1* gr:*return-0*) (move gr:*return-0* a13) (return-mv a2 boxed-right) ) (defafun divide-bignum-return-results (quotient quotient-size remainder remainder-size status dividend-high divisor) ; a0 - quotient pointer ; a1 - dividend/quotient size ; a2 - remainder pointer ; a3 - divisor/remainder size ; a4 - status ; a5 - dividend high word ; a6 - divisor pointer ; ; a7 - divisor high word ; a8 - remainder high word ; a9 - quotient high word ; a10 - index ; a11 - temp status ; a12 - remainder zero flag (movei a12 '1) (move a10 a3) down-shift-remainder-loop (alu l+r vma-start-read-no-transport a2 a10 unboxed-vma unboxed-md) (alu load-status-r nop ignore a4) (alu shift-dn-lf-r md-start-write-no-gc-trap ignore md unboxed-md) (alu pass-status a4 ignore ignore unboxed) (alu r-1 a10 ignore a10 bw-24) (alu-field extract-bit-right a15 ignore a4 hw:%%alu-status-zero unboxed br-not-zero) (branch down-shift-remainder-loop (alu and a12 a15 a12 bw-24)) set-quotient-lsb (alu r+1 vma-start-read-no-transport ignore a0 unboxed-vma unboxed-md) (move nop a12 bw-24) (alu-field set-bit-right md-start-write-no-gc-trap ignore md (byte 1. 0.) unboxed-md br-not-zero) ;set quotient lsb (branch correction-done ()) ;done if remainder = 0 now (alu l+r vma-start-read-no-transport a0 a1 unboxed-vma unboxed-md) (nop) (move a9 md) ;quotient high word (alu l+r vma-start-read-no-transport a2 a3 unboxed-vma unboxed-md) (nop) (move a8 md) ;remainder high word (alu or nop a8 a5) (alu and nop a8 a5 br-not-negative) (branch correction-done (alu setr nop ignore a9 br-negative)) (branch neg-divd-rem (alu setr a11 ignore gr:*all-zero* br-negative)) (branch inc-q-and-sub-divs-from-rem (alu setr a10 ignore gr:*one*)) dec-q-and-add-divs-to-rem (alu l+r vma-start-read-no-transport a6 a10 unboxed-vma unboxed-md) (nop) (move a15 md) (alu l+r vma-start-read-no-transport a2 a10 unboxed-vma unboxed-md) (alu load-status-r nop ignore a11) (alu l+r+c md-start-write-no-gc-trap a15 md unboxed-md) (alu pass-status a11 ignore ignore unboxed) (alu l-r nop a10 a3 bw-24) (alu r+1 a10 ignore a10 bw-24 br-less-than) (branch dec-q-and-add-divs-to-rem ()) dec-q (move a10 gr:*one*) (move a11 gr:*all-zero*) dec-q-loop (alu l+r vma-start-read-no-transport a0 a10 unboxed-vma unboxed-md) (alu load-status-r nop ignore a11) (alu r-l-c md-start-write-no-gc-trap gr:*all-zero* md unboxed-md) (alu pass-status a11 ignore ignore unboxed) (alu l-r nop a10 a1 bw-24) (alu r+1 a10 ignore a10 bw-24 br-less-than) (branch dec-q-loop ()) (unconditional-branch correction-done ()) inc-q-and-sub-divs-from-rem (movei a11 hw:$$alu-status-carry unboxed) sub-divs-from-rem (alu l+r vma-start-read-no-transport a6 a10 unboxed-vma unboxed-md) (nop) (move a15 md) (alu l+r vma-start-read-no-transport a2 a10 unboxed-vma unboxed-md) (alu load-status-r nop ignore a11) (alu r-l-c md-start-write-no-gc-trap a15 md unboxed-md) (alu pass-status a11 ignore ignore unboxed) (alu l-r nop a10 a3 bw-24) (alu r+1 a10 ignore a10 bw-24 br-less-than) (branch sub-divs-from-rem ()) inc-q (move a10 gr:*one*) (movei a11 hw:$$alu-status-carry unboxed) inc-q-loop (alu l+r vma-start-read-no-transport a0 a10 unboxed-vma unboxed-md) (alu load-status-r nop ignore a11) (alu l+r+c md-start-write-no-gc-trap gr:*all-zero* md unboxed-md) (alu pass-status a11 ignore ignore unboxed) (alu l-r nop a10 a1 bw-24) (alu r+1 a10 ignore a10 bw-24 br-less-than) (branch inc-q-loop ()) (alu-field extract-bit-right nop ignore a11 hw:%%alu-status-overflow) (test br-zero) (branch correction-done ()) quotient-overflow (alu r+1 a15 ignore a1 bw-24) (open-call (allocate-bignum 1) a15 (o0 a15)) quotient-overflow-copy-loop (alu l+r vma-start-read-no-transport a0 a1 unboxed-vma unboxed-md) (nop) (move md md unboxed-md) (alu l+r vma-start-write-no-gc-trap a15 a1 unboxed-vma) (alu r-1 a1 ignore a1 bw-24) (test br-not-zero) (branch quotient-overflow-copy-loop ()) (unconditional-branch correction-done (alu setr a0 ignore a15)) neg-divd-rem (alu l+r vma-start-read-no-transport a6 a3 unboxed-vma unboxed-md) (movei a10 '1) (move a7 md) (movei a11 0 unboxed br-not-negative) (branch rem-plus-abs-divs ()) (movei a11 hw:$$alu-status-carry unboxed) rem-plus-abs-divs (alu l+r vma-start-read-no-transport a2 a10 unboxed-vma unboxed-md) (move nop a7) (move a15 md br-negative) (branch rem-plus-abs-neg-div (alu l+r vma-start-read-no-transport a6 a10 unboxed-vma unboxed-md)) rem-plus-abs-pos-div (alu load-status-r nop ignore a11) (alu l+r+c nop a15 md) (unconditional-branch rem-plus-abs-div-end (alu pass-status a11 ignore ignore unboxed)) rem-plus-abs-neg-div (alu load-status-r nop ignore a11) (alu r-l-c nop a15 md) (alu pass-status a11 ignore ignore unboxed) rem-plus-abs-div-end (alu l-r nop a10 a3 bw-24 br-not-zero) (branch correction-done (alu r+1 a10 ignore a10 bw-24 br-less-than)) (branch rem-plus-abs-divs ()) zero-rem (open-call (zero-bignum-internal 1) a2 (o0 a2)) ; remainder = 0 (move nop a9) (test br-negative) (branch dec-q ()) (unconditional-branch inc-q ()) correction-done (open-call (shrink-bignum-structure 1) a13 (o0 a2)) ;shrink remainder (open-call (shrink-bignum-structure 1) ignore (o0 a0)) ;shrink quotient (movei gr:*number-of-return-values* '5 boxed) (move gr:*return-0* a13) (return-mv a0 boxed-right) ) ;;;************************************************** ;;; * ;;; COMPARE FUNCTIONS * ;;; * ;;;************************************************** ;; changed by Peter Cerrato on 4/27 (defun compare-bignum (ptr1 ptr2) (let* ((size1 (vinc:make-fixnum (%vm-read ptr1))) (size2 (vinc:make-fixnum (%vm-read ptr2))) (data1 (%vm-read32 ptr1 size1)) (data2 (%vm-read32 ptr2 size2)) (sign1 (hw:ldb data1 vinc:%%bignum-sign-high-word 0)) (sign2 (hw:ldb data2 vinc:%%bignum-sign-high-word 0))) (labels ((check-signs () (if (not (zerop (logxor sign1 sign2))) (if (zerop sign1) ;different signs (plus) (minus)) (if (not (= size1 size2)) (if (zerop sign1) (if (> size1 size2) (plus) (minus)) (if (> size1 size2) (minus) (plus))) (scan-equal (1- size1))))) (scan-equal (size) (if (hw:32= data1 data2) (if (zerop size) (zero) (progn (setq data1 (%vm-read32 ptr1 size)) (setq data2 (%vm-read32 ptr2 size)) (scan-equal (1- size)))) ;; ||| Changed following condition 10/14/88 --wkf (if (zerop (hw:ldb (hw:32- data1 data2) vinc:%%bignum-sign-high-word 0)) ;; positive difference (if (zerop sign1) (plus) (minus)) (if (zerop sign1) (minus) (plus))))) (zero () (values 0 hw:$$alu-status-zero-and-others)) (plus () (values 1 hw:$$alu-status-positive)) (minus () (values -1 hw:$$alu-status-negative-and-others))) (check-signs)))) ;(defafun compare-bignum (bignum1 bignum2) ; ;; a0 <---- bignum1 pointer ; ;; a1 <---- bignum2 pointer ; ;; ; ;; LOCALS ; ;; a3 <---- bignum1 's length ; ;; a4 <---- bignum2 's length ; ;; a5 <---- current word of bignum1 ; ;; a6 <---- current word of bignum2 ; (move vma-start-read a0 boxed-vma boxed-md) ; (nop) ; (move a3 md) ; (move vma-start-read a1 boxed-vma boxed-md) ; (nop) ; (move a4 md) ; (alu l+r vma-start-read-no-transport a0 a3 unboxed-vma unboxed-md) ; (movei gr:*number-of-return-values* '5 boxed) ; (move a5 md) ; (alu l+r vma-start-read-no-transport a1 a4 unboxed-vma unboxed-md br-negative) ; (branch 1-neg ()) ;1-pos ; (move a6 md) ; (alu xor nop a5 a6) ; (test br-not-negative) ; (branch check-lengths-1-pos ()) ;greater-than ; (alu l-r nop gr:*one* gr:*zero* bw-24) ; (alu pass-status a14 gr:*zero* gr:*zero* bw-24) ; (return gr:*one*) ;1-neg ; (move a6 md) ; (alu xor nop a5 a6) ; (test br-not-negative) ; (branch check-lengths-1-neg ()) ;less-than ; (alu l-r nop gr:*minus-one* gr:*zero* bw-24) ; (alu pass-status a14 gr:*zero* gr:*zero* bw-24) ; (return gr:*minus-one*) ;check-lengths-1-pos ; (alu l-r nop a3 a4 bw-24) ; (alu l-r nop a3 a4 bw-24 br-greater-than) ; (branch greater-than () br-less-than) ; (branch less-than ()) ; (unconditional-branch compare-equal-len-pos ()) ;check-lengths-1-neg ; (alu l-r nop a3 a4 bw-24) ; (alu l-r nop a3 a4 bw-24 br-greater-than) ; (branch less-than () br-less-than) ; (branch greater-than ()) ;compare-equal-len-neg ; (alu l-r nop a5 a6) ; (alu l-r nop a5 a6 br-greater-than) ; (branch greater-than (alu setr a13 ignore a0 br-less-than)) ; (branch less-than (alu setr a0 ignore a1)) ; (unconditional-branch compare-equal-len (alu setr a1 ignore a13)) ;compare-equal-len-pos ; (alu l-r nop a5 a6) ; (alu l-r nop a5 a6 br-greater-than) ; (branch greater-than ()) ; (branch less-than ()) ;compare-equal-len ; (alu r-1 a3 ignore a3 bw-24) ; (alu r-1 a4 ignore a4 bw-24 br-zero) ; (branch equal (alu l+r vma-start-read-no-transport a0 a3 unboxed-vma unboxed-md)) ; (nop) ; (move a5 md) ; (alu l+r vma-start-read-no-transport a1 a4 unboxed-vma unboxed-md) ; (nop) ; (unconditional-branch compare-equal-len-pos (move a6 md)) ;equal ; (alu l-r nop gr:*zero* gr:*zero* bw-24) ; (alu pass-status a14 gr:*zero* gr:*zero* bw-24) ; (return gr:*zero*) ; ) (defun test-bignum (ptr) (let* ((size (vinc:make-fixnum (%vm-read ptr))) (data (%vm-read24 ptr size)) (sign (hw:ldb data vinc:%%bignum-sign-high-word 0))) (if (zerop sign) (labels ((scan-zero () (if (hw:32= data gr:*all-zero*) (if (zerop (setq size (1- size))) (values 0 hw:$$alu-status-zero-and-others) (progn (setq data (%vm-read24 ptr size)) (scan-zero))) (values 1 hw:$$alu-status-positive)))) (scan-zero)) (values -1 hw:$$alu-status-negative-and-others)))) ;;||| Constant changed here and above 10/12/88 --wkf ;(defafun test-bignum (ptr) ;;;; Note - bignums are only greater or less than zero. Zero is a fixnum. (except when coerced!) ; (move vma-start-read a0 boxed-vma boxed-md) ; (nop) ; (move a1 md) ; (alu l+r vma-start-read-no-transport a0 a1 unboxed-vma unboxed-md) ; (movei a15 '5) ; (move a2 md) ; (alu pass-status a14 gr:*zero* gr:*zero* bw-24 br-negative) ; (branch neg (move a3 gr:*minus-one* br-greater-than)) ; (return gr:*one*) ;neg ; (return gr:*minus-one*) ; ) ;******************************************************************************* ; ASH Bignum (shift must be a fixnum) ;******************************************************************************* ; a0 - bignum argument ; a1 - shift amount argument ; ; a2 - |shift| mod 32 ; a3 - number of words in bignum argument -- a fixnum ; a4 - number of words to allocate for answer -- a fixnum ; a5 - result bignum pointer ; a6 - current result index -- a fixnum ; a7 - current source index -- a fixnum ; a9 - current source word hi ; a10- current source word lo ; a11- extraction shift constant ; (defafun ash-bignum (num shift) (alu-field aligned-field-xor nop gr:*zero* a1 vinc:%%data-type) ;only fixnum shifts are legal (move vma-start-read a0 boxed-vma boxed-md br-zero) (branch got-shift-size (alu sex-r a1 ignore a1 bw-24 unboxed)) bad-ash (open-call (big-ash-illop 0) ignore ()) got-shift-size (alu setr nop a1 a1 bw-24 boxed dt-none br-negative) ;;zero test (branch shift-down (alu merge-r a3 gr:*zero* MD bw-24 boxed br-negative) br-not-zero) (branch shift-up (alu l+r vma-start-read-no-transport a3 a0 bw-24 unboxed-vma unboxed-md)) ;read top source word of bignum zero-shift (movei (register *number-of-return-values* 11 15) (quote 2) boxed) (alu-field set-bit-right nop ignore md (byte 1 0)) ;;top source word sign to status (alu pass-status (register *return-0* 10 0) ignore a3 bw-24 boxed) ;; Get fixnum datatype from a3 (move return-mv a0 boxed-right ch-return next-pc-return) shift-up (movei a4 31. unboxed) ;allocate (+ old-length (ash (+ shift 31.) -5)) words for result (alu l+r a4 a1 a4 unboxed) (alu-field nb-shift-ar-r a4 ignore a4 (byte 32. -5.) unboxed) (alu l+r a4 a4 a3 bw-24 boxed) (open-call (allocate-bignum 1) a5 (o0 a4)) (open-call (zero-bignum-internal 1) ignore (o0 a5)) ;;;@@@ Do we need to zero it? (alu-field field-extract-r a2 ignore a1 (byte 5. 0.) unboxed) ;shift mod 32 (movei a11 32. unboxed) ;compute extract constant (alu l-r a11 a11 a2 bw-8 unboxed) (alu neg-r a11 ignore a11 bw-8 unboxed) (alu load-status-r nop ignore a11 bw-16) (move a6 a4) ; result index (move a7 a3) ; source index (move a10 md) ;top source word (alu sign a9 ignore ignore unboxed) ;sign extension of source shift-up-loop (alu-field field-extract-lr md a9 a10 (byte 32. 0.) pw-ri unboxed-md) (alu l+r vma-start-write-no-gc-trap a6 a5 bw-24 unboxed-vma) (alu r-1 a7 ignore a7 bw-24) (alu r-1 a6 ignore a6 br-zero bw-24) (branch shift-up-finish (alu l+r vma-start-read-no-transport a7 a0 bw-24 unboxed-vma unboxed-md)) (move a9 a10 unboxed) (unconditional-branch shift-up-loop (alu setr a10 ignore md unboxed)) shift-up-finish (alu-field field-extract-lr md a10 gr:*all-zero* (byte 32. 0.) pw-ri unboxed-md) (alu l+r vma-start-write-no-gc-trap a6 a5 bw-24 unboxed-vma) (tail-open-call (shrink-bignum-structure 1) (o0 a5)) shift-down (alu neg-r a1 ignore a1 unboxed) (alu-field nb-shift-ar-r a4 ignore a1 (byte 32. -5.) unboxed) (alu r-l a4 a4 a3 bw-24 boxed) (test br-greater-than) (branch shift-down-allocate ()) shift-down-till-nothing-left (alu l+r vma-start-read-no-transport a3 a0 bw-24 unboxed-vma unboxed-md) (movei a15 '5) (alu-field nb-shift-ar-r a10 ignore md (byte 32. -32.) unboxed) (alu pass-status a14 gr:*zero* gr:*zero* bw-24) (alu merge-r return gr:*zero* a10 bw-24 boxed ch-return next-pc-return) shift-down-allocate (open-call (%allocate-bignum 1) a5 (o0 a4)) (alu l+r vma-start-read-no-transport a3 a0 bw-24 unboxed-vma unboxed-md) ;read top source word (move a6 a4) ; result index (move a7 a3) ; source index (alu-field field-extract-r a2 ignore a1 (byte 5. 0.) unboxed) ;shift mod 32 (alu neg-r a2 ignore a2 bw-8 br-greater-or-equal) (branch shift-down-more-setup ()) (movei a2 '#x00e0) shift-down-more-setup (alu load-status-r nop ignore a2 bw-16) (move a10 md) ;top source word (alu sign a9 ignore ignore unboxed) ;sign extension of source shift-down-loop (alu-field field-extract-lr md a9 a10 (byte 32. 0.) pw-ri unboxed-md) (alu l+r vma-start-write-no-gc-trap a6 a5 bw-24 unboxed-vma) (alu r-1 a6 ignore a6 bw-24) (alu r-1 a7 ignore a7 br-zero bw-24) (branch shift-down-finish (alu l+r vma-start-read-no-transport a7 a0 bw-24 unboxed-vma unboxed-md)) (move a9 a10 unboxed) (unconditional-branch shift-down-loop (alu setr a10 ignore md unboxed)) shift-down-finish (tail-open-call (shrink-bignum-structure 1) (o0 a5)) ) (defun big-ash-illop () (li:tail-error "Bad bignum ash shift amount (This used to be an illop.)")) ;******************************************************************************* ; Field Pass Bignum ;******************************************************************************* ; a0 - from argument a1 - to argument a2 - byte spec argument ; ; a3 - position a4 - size a5 - from size in words ; a6 - to size in words a7 - result size a8 - from index ; a9 - to index a10- a11- result pointer ; a12- shift value a13- from word high a14- from word low ; a15- to word r0 - 32 r1 - ; r2 - r3 - current bit r4 - pos + size ; r5 - (mod (- 32 pos) 32) r6 - current + 32 ; DPB: (cond ; ((>= cur (+ pos size)) ; (just-copy-word)) ; ((>= cur pos) ; (setq extract (mod (- 32. pos) 32) ; shift 0 ; width (min 32. (- (+ pos size) cur)))) ; ((> (+ cur 32.) pos) ; (setq extract 0 ; shift (mod pos 32.) ; width (min size (- (+ cur 32.) pos))))) ; (t ; (just-copy-word))) (defun field-pass-bignum (from to byte-spec ldb-p) (multiple-value-bind (size position) (resolve-byte-spec-internal byte-spec ldb-p) (field-pass-bignum-internal from to position size))) ; a0 - FROM argument a1 - TO argument a2 - POSITION argument ; a3 - SIZE argument a4 - FROM size in words a5 - result ptr ; a6 - TO size in words a7 - result size a8 - from index ; a9 - 32 a10 - current-bit a11 - (mod pos 32) ;a12 - TO hi word a13 - TO lo word a14 - current TO index ;a15 - (+ pos size) r1 - FROM word r2 - (- 32 (mod pos 32)) (defafun field-pass-bignum-internal (from to position size) (move vma-start-read a0 boxed-vma boxed-md) (nop) (move a4 md bw-24 unboxed) ;;from # words without a header (move vma-start-read a1 boxed-vma boxed-md) (move nop a3) (test br-negative) (branch ldb (alu merge-r a6 gr:*zero* md boxed bw-24)) ;;make a fixnum dpb (movei a9 '32 boxed) (alu l+r a7 a3 a9 boxed-right bw-24) ; len = (max (ash (+ 32 position size) -5) to-size) (alu l+r a7 a2 a7 boxed-right bw-24) ;;@@@ This is too long sometimes if zeros in top of from --wkf (alu-field field-pass a7 a7 gr:*zero* (byte 19. -5.) boxed-right) (alu l-r nop a6 a7 bw-24) (test br-less-or-equal) (branch dpb-allocate-result ()) (move a7 a6) dpb-allocate-result (move o0 a1 ch-open) (call (copy-bignum-with-extension 2) a5 (o1 a7)) ;copy TO bignum to result area with sign extension (movei a8 '1 boxed) (alu-field field-pass a11 a2 gr:*zero* (byte 5. 0.) boxed-right) ; (mod pos 32) (alu-field field-pass a14 a2 gr:*zero* (byte 19. -5.) boxed-right) ; (div pos 32) (alu l+r+c vma-start-read-no-transport a14 a5 bw-24 unboxed-vma unboxed-md carry-1) (move a10 a2) (alu l+r a15 a2 a3 bw-24 boxed-right) (alu l-r r2 a9 a11 bw-24 boxed-right) (move a12 md) dpb-loop (alu-field field-pass a14 a10 gr:*zero* (byte 19. -5.) boxed-right) (alu r+2 a14 ignore a14 bw-24 boxed-right) (alu l-r nop a14 a7 bw-24) (move a13 a12 br-greater-than) (branch dpb-extract (alu sign a12 ignore ignore unboxed)) (alu l+r vma-start-read-no-transport a14 a5 bw-24 unboxed-vma unboxed-md) (nop) (move a12 md) dpb-extract (alu l-r nop a8 a4 bw-24) (alu-field nb-shift-ar-r r1 ignore r1 (byte 32. -32.) unboxed br-greater-than) (branch dpb-insert (alu r-1 a14 ignore a14 bw-24 boxed-right)) (alu l+r vma-start-read-no-transport a8 a0 bw-24 unboxed-vma unboxed-md) (nop) (move r1 md) dpb-insert (move r14 r2) (alu l-r nop r2 a3 bw-24) (alu-field field-pass r15 r2 gr:*zero* vinc:%%byte-size boxed-right br-less-or-equal) (branch dpb-insert-lo (alu l+r vma a5 a14 unboxed-vma)) (alu-field field-pass r15 a3 gr:*zero* vinc:%%byte-size boxed-right) (move r14 a3) dpb-insert-lo (alu merge-l r15 a11 r15 bw-8 boxed-right) (alu load-status-r nop ignore r15 bw-16) (alu field-pass md-start-write-no-gc-trap r1 a13 pw-rr unboxed-md) (alu l-r a3 a3 r14 bw-24 boxed-right) (alu l-r r14 a9 r14 bw-24 boxed-right br-less-or-equal) (branch dpb-done (alu neg-r r13 r2 r2 bw-8 br-equal boxed-right)) (branch dpb-next (alu load-status-r nop ignore r13 bw-16)) (alu l-r nop r14 a3 bw-24) (test br-less-or-equal) (branch dpb-insert-hi (alu field-extract-r r1 ignore r1 pw-rr boxed-right)) (move r14 a3) dpb-insert-hi (alu-field field-pass r15 r14 gr:*zero* vinc:%%byte-size boxed-right) (alu l-r a3 a3 r14 bw-24 boxed-right) (alu load-status-r nop ignore r15 br-less-or-equal bw-16) (branch dpb-final-write (alu field-pass a12 r1 a12 pw-rr boxed-right)) dpb-next (alu r+1 a8 ignore a8 bw-24 boxed-right) (alu r+1 a14 ignore a14 bw-24 boxed-right) (unconditional-branch dpb-loop (alu l+r a10 a9 a10 bw-24 boxed-right)) dpb-final-write (move md a12 unboxed-md) (alu l+r+c vma-start-write-no-gc-trap a14 a5 bw-24 unboxed-vma carry-1) dpb-done (tail-open-call (shrink-bignum-structure 1) (o0 a5)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; a0 - from argument a1 - to argument a5 - byte spec argument/result ptr ; ; a2 - position a3 - size a4 - from word size ; a6 - to word size a7 - result word size a8 - current-bit number ; a9 - (mod pos 32.) a10 - (+ pos size) a11 - high from word ;a12 - low from word a13 - temp a14 - result index ldb (alu neg-r a2 ignore a2 bw-24 boxed-right) ; make position positive (movei a7 '32. boxed) ; len = (max (ash (+ 32 size) -5) to-size) (alu l+r a7 a3 a7 boxed-right bw-24) (alu-field field-pass a7 a7 gr:*zero* (byte 19. -5.) boxed-right) (alu l-r nop a6 a7 bw-24) (test br-less-or-equal) (branch ldb-allocate-result ()) (move a7 a6) ldb-allocate-result (move o0 a1 ch-open) (call (copy-bignum-with-extension 2) a5 (o1 a7)) ;copy TO bignum to result area with sign extension (movei a14 '1 boxed) (alu-field field-pass a13 a2 gr:*zero* (byte 19. -5.) boxed-right) ;read first from word (alu l+r+c vma-start-read-no-transport a13 a0 bw-24 unboxed-vma unboxed-md carry-1) (alu l+r a10 a2 a3 bw-24 boxed-right) ;a10 = (+ pos size) (alu-field field-pass a9 a2 gr:*zero* (byte 5. 0.) boxed-right) ;a9 = -(mod pos 32.) (alu neg-r a9 ignore a9 bw-8 boxed-right) (move a8 a2) (move a11 md) (movei r1 '32 boxed) ldb-loop (move a12 a11) (alu-field field-pass a13 a8 gr:*zero* (byte 19. -5.) boxed-right) (alu r+2 a13 ignore a13 bw-24 boxed-right) (alu l-r nop a13 a4 bw-24) (alu-field nb-shift-ar-r a11 ignore a12 (byte 32. -32.) unboxed br-greater-than) (branch extract-from ()) (alu l+r vma-start-read-no-transport a13 a0 bw-24 unboxed-vma unboxed-md) (nop) (move a11 md) extract-from ;added no-transport to below inst ; below must be bw-24 to avoid smashing the data type. (alu l+r vma-start-read-no-transport a14 a5 bw-24 unboxed-vma unboxed-md) (movei a15 '0 boxed) (alu l-r nop a3 r1 bw-24) (alu load-status-r nop ignore a9 bw-16 br-greater-or-equal) (branch store-it (alu field-extract-lr a13 a11 a12 pw-rr boxed-right)) (alu-field field-pass a15 a3 gr:*zero* vinc:%%byte-size boxed-right) store-it (alu load-status-r nop ignore a15 bw-16) (alu field-pass md-start-write-no-gc-trap a13 md pw-rr unboxed-md) (alu l+r a8 a8 r1 bw-24 boxed-right) (alu l-r a3 a3 r1 bw-24 boxed-right) (alu r+1 a14 ignore a14 bw-24 boxed-right br-greater-than) (branch ldb-loop ()) (tail-open-call (shrink-bignum-structure 1) (o0 a5)) ) (defafun copy-bignum-with-extension (from to-size) (open-call (allocate-bignum 1) a2 (o0 a1)) (move vma-start-read a0 boxed-vma boxed-md) (movei a4 1) ;;;counter of current word being copied. (move a3 md) ;;;length of from bignum in words loop (alu l-r nop a4 a3 bw-24) (alu-field nb-shift-ar-r md ignore a5 (byte 32. -32.) unboxed-md br-greater-than) (branch write ()) ;;;@@@ This always branches except first time through. -wkf (alu l+r vma-start-read-no-transport a4 a0 unboxed-vma unboxed-md) (nop) (move a5 md unboxed) (move md a5 unboxed-md) ;;;@@@ Is this needed??? --wkf write (alu l-r nop a4 a1 bw-24) (alu l+r vma-start-write-no-gc-trap a4 a2 unboxed-vma br-less-than) (branch loop (alu r+1 a4 ignore a4)) (return a2 boxed-right) )