mirror of
https://github.com/PDP-10/its.git
synced 2026-01-25 19:56:53 +00:00
1259 lines
27 KiB
Plaintext
1259 lines
27 KiB
Plaintext
;;; -*-MIDAS-*-
|
||
;;; **************************************************************
|
||
;;; ***** MACLISP ****** BIGNUM ARITHMETIC PACKAGE **************
|
||
;;; **************************************************************
|
||
;;; ** (C) COPYRIGHT 1980 MASSACHUSETTS INSTITUTE OF TECHNOLOGY **
|
||
;;; ****** THIS IS A READ-ONLY FILE! (ALL WRITES RESERVED) *******
|
||
;;; **************************************************************
|
||
|
||
|
||
|
||
PGBOT BIG
|
||
|
||
|
||
SUBTTL BIGNUM PACKAGE - RANDOM ROUTINES
|
||
|
||
;THE BIGNUM ARITHMETIC PAGE - SPECIAL STUFF FOR BIGNUM OPERATIONS ONLY
|
||
|
||
YPOCB: PUSH P,[NREVERSE]
|
||
BCOPY: HRRZ C,A ;COPIES A BIGNUM IN ACCUMULATOR A [INTERNAL FORMAT]
|
||
PUSH P,A
|
||
MOVEI AR1,(P) ;CLOBBERS C AR1 TT D
|
||
BCOP1: JUMPE C,POPAJ
|
||
HLRZ TT,(C)
|
||
MOVE TT,(TT)
|
||
PUSHJ P,C1CONS
|
||
HRRM A,(AR1)
|
||
HRRZ AR1,(AR1) ;UPDATE POINTER TO END OF LIST
|
||
HRRZ C,(C) ;GET NEXT OF LIST TO BE COPIED
|
||
JRST BCOP1
|
||
|
||
|
||
BNARSV: PUSH P,C ;SAVE ACCUMULATORS
|
||
PUSH P,AR1
|
||
PUSH P,AR2A
|
||
MOVEM F,FACD
|
||
MOVEM R,FACF
|
||
JRST (T)
|
||
|
||
BNARRS: POP P,AR2A ;RESTORE ACCUMULATORS
|
||
POP P,AR1
|
||
POP P,C
|
||
MOVE F,FACD
|
||
MOVE R,FACF
|
||
JRST (T)
|
||
|
||
|
||
PLOV: PUSH P,AR1 ;OVERFLO WHILE ADDING OR SUBBING TWO FIXNUMS
|
||
SKIPN TT,D
|
||
JRST PLOV2
|
||
TLNN TT,400000
|
||
MOVNS TT
|
||
TLZ TT,400000
|
||
PUSH FXP,TT
|
||
PUSHJ P,ABSOV
|
||
MOVE A,(A)
|
||
HLR B,(A)
|
||
POP FXP,(B)
|
||
SKIPL D
|
||
TLC A,-1
|
||
SKIPA D,A
|
||
PLOV2: MOVE D,BNM236
|
||
POP P,AR1
|
||
JRST T13
|
||
|
||
PL1BN: EXCH D,TT ;FIXNUM SUM MEETS BIGNUM ARG
|
||
PUSHJ P,BNCVTM
|
||
EXCH D,TT
|
||
JRST T11
|
||
|
||
TIMOV: MOVEM T,AGDBT ;OVERFLO WHILE MULING TWO FIXNUMS
|
||
PUSHJ P,BNCV
|
||
MOVE D,A
|
||
MOVE TT,AGDBT
|
||
PUSHJ P,BNCVTM
|
||
JRST BNTIM
|
||
|
||
TIM1BN: JUMPE D,T14EX ;FIXNUM PRODUCT MEETS BIGNUM NEXT ARG
|
||
EXCH D,TT
|
||
PUSHJ P,BNCVTM
|
||
EXCH D,TT
|
||
JRST T11
|
||
|
||
T2: MOVE D,TT
|
||
T12: MOVE A,(F) ;BIGNUM ARITHMETIC LOOP
|
||
JSP T,NVSKIP
|
||
XCT 4(R) ;OPERATE ON TWO BIGNUMS
|
||
JRST 2(R) ;DISPATCH TO OPERATE ON BIGNUM SUM WITH FIXED
|
||
EXCH D,TT ;CONVERT BIGNUM SUM TO FLOATING
|
||
PUSHJ P,FLBIG
|
||
EXCH D,TT
|
||
JRST T7 ;AND ENTER FLOATING POINT LOOP
|
||
|
||
PL2BN: PUSHJ P,BNCVTM ;BIGNUM SUM MEETS FIXNUM NEXT ARG
|
||
JRST T11
|
||
|
||
|
||
TIM2BN: JUMPE TT,T14EX1 ;BIGNUM PRODUCT MEETS FIXNUM NEXT ARG
|
||
PUSHJ P,BNCVTM
|
||
EXCH D,TT
|
||
T11: XCT 4(R) ;TRANSFERS TO BNTIM
|
||
T13: AOBJN F,T12
|
||
T13X: MOVE A,D
|
||
SUB P,PLUS8
|
||
JRST BNCONS
|
||
|
||
BNDF: JSP A,BNPL1 ;DIFFERENCE OF TWO BIGNUMS
|
||
BNPL: JSP A,BNPL1 ;PLUS OF TWO BIGNUMS
|
||
BNPL1: EXCH A,D
|
||
MOVE B,TT
|
||
JSP T,BNARSV
|
||
PUSHJ P,BNADD(D)-BNPL1
|
||
T19A: PUSHJ P,BNTRSZ ;SKIPS 2 IF ALL RIGHT
|
||
MOVE D,[1_43]
|
||
JRST T19B
|
||
MOVE D,A
|
||
HRRZ B,(A) ;WHAT IF OPERATE RESULTS IN SCRUNCHING
|
||
JUMPN B,T19C ;ACCUMULATED VALUE INTO ONE WORD?
|
||
HLRZ D,(A)
|
||
MOVE D,(D)
|
||
JUMPGE A,.+2
|
||
MOVNS D
|
||
T19B: JSP T,BNARRS
|
||
JRST 2,@[T14E]
|
||
|
||
T19C: JSP T,BNARRS
|
||
JRST T13
|
||
|
||
BNXTIM: JUMPE TT,0POPJ ;FIXNUM IN TT TIMES ABS(BIGNUM IN A)
|
||
HRRZ D,(A)
|
||
SETOM REMFL
|
||
PUSHJ P,BNCVTM ;CONVERT FIXNUM TO BIGNUM FOR BNMUL
|
||
BNTIM: JSP T,BNARSV ;PRODUCT OF TWO BIGNUMS
|
||
MOVE A,D
|
||
MOVE B,TT
|
||
PUSHJ P,BNMUL
|
||
JSP T,BNARRS
|
||
MOVE D,A
|
||
SKIPN REMFL
|
||
JRST T13
|
||
SETZM REMFL
|
||
JRST BNCONS ;FOR BNXTIM, CONS UP A REAL BIGNUM
|
||
|
||
DIVSEZ: SKIPA D,BNM235 ;DIVISION BY 1_43 [-2E35.]
|
||
REM2BN: JUMPE TT,BPDLNKJ
|
||
DV2BN: JSP T,BNARSV ;BIGNUM DIVIDEND GETS FIXNUM DIVISOR
|
||
MOVE A,D
|
||
JUMPN TT,DV2BN1
|
||
SKIPN RWG
|
||
JRST OVFLER
|
||
MOVEI TT,1 ;ON ATTEMPT TO DIVIDE BY ZERO [WHEN RWG NOT ZERO]
|
||
JUMPGE A,.+2
|
||
MOVNS TT
|
||
MOVEM TT,BNV1
|
||
MOVE B,BNV2
|
||
PUSHJ P,BNADD
|
||
JRST T19A
|
||
|
||
DV1BN: CAME D,[400000,,] ;FIXNUM DIVIDEND, BIGNUM DIVISOR
|
||
TDZA TT,TT ;ORDINARILY ZERO
|
||
SKIPA D,BNM235 ;BUT -4_41/4_41 => 1, NOT 0
|
||
JRST T14EX1
|
||
BNDV: MOVE B,TT ;BIGNUM QUOTIENT, BIGNUM DIVEND
|
||
MOVE A,D
|
||
JSP T,BNARSV
|
||
PUSHJ P,BNQUO
|
||
SKIPE REMFL
|
||
CAMN TT,XC-1
|
||
JRST T19A
|
||
SETZM REMFL
|
||
JSP T,BNARRS
|
||
MOVE D,A ;DIVIDE OUT NORMALIZATION
|
||
JRST DV2BN
|
||
|
||
DV2BN1: MOVEM A,NORMF ;SO DIVIDE A BIGNUM BY A REGULAR FIXNUM
|
||
PUSHJ P,REVERSE
|
||
MOVE AR1,NORMF ;AR1 HAS SIGN OF ORIGINAL ARG IN LH
|
||
HRR AR2A,A ;AR2A HAS SIGN OF PRODUCT ON COPY
|
||
HLL AR2A,AR1
|
||
JUMPGE TT,DV2BN2
|
||
MOVNS TT
|
||
JUMPL TT,DV2BN3 ;FOO! LOUSY SETZ CASE - PRODUCT WILL BE NEGATIVE
|
||
TLC AR2A,-1
|
||
DV2BN2: HRRZ C,(A)
|
||
MOVE D,TT
|
||
HLRZ F,(A)
|
||
MOVE F,(F)
|
||
MOVEI R,0
|
||
DIV R,D
|
||
MOVE TT,R
|
||
PUSHJ P,C1CONS
|
||
BNFXLP: MOVE B,A
|
||
JUMPE C,D1FIN
|
||
MOVE R,F
|
||
HLRZ F,(C)
|
||
MOVE F,(F)
|
||
DIV R,D
|
||
MOVE TT,R
|
||
PUSHJ P,C1CONS
|
||
HRRM B,(A)
|
||
HRRZ C,(C)
|
||
JRST BNFXLP
|
||
|
||
DV2BN3: MOVE TT,BNM235
|
||
JSP T,BNARRS
|
||
JRST BNDV
|
||
|
||
D1FIN: HLL A,AR2A
|
||
PUSHJ P,BNTRUN
|
||
EXCH A,AR2A
|
||
MOVEI B,NIL
|
||
PUSHJ P,RECLAIM ;RECLAIM ONLY FREE STORAGE
|
||
EXCH A,AR2A
|
||
SKIPN REMFL
|
||
JRST T19A
|
||
MOVE D,F
|
||
JUMPGE AR1,.+2
|
||
MOVNS D
|
||
JSP T,BNARRS
|
||
MOVEI B,TRUTH
|
||
PUSHJ P,RECLAIM ;RECLAIM QUOTIENT SPACE, SINCE ONLY REMAINDER NEEDED
|
||
JRST T14EX
|
||
|
||
SUBTTL GENERAL UTILITY ROUTINES FOR BIGNUM ARITHMETIC
|
||
|
||
BNTRUN: HRR AR1,A ;TRUNCATE OFF LEADING ZEROS FROM BIGNUM
|
||
HRRZ B,(AR1) ;PRESERVE LH OF AR1
|
||
JUMPE B,CPOPJ
|
||
BNTR4: MOVS C,(B)
|
||
SKIPE (C)
|
||
HRR AR1,B
|
||
HLRZ B,C
|
||
JUMPN B,BNTR4
|
||
HRRZ C,(AR1)
|
||
HLRM C,(AR1)
|
||
JUMPE C,CPOPJ ;EXIT IF THERE WERE NO LEADING ZEROS
|
||
EXCH A,C
|
||
PUSHJ P,RECLAIM ;OTHERWISE, RECLAIM SPACE OCCUPIED
|
||
EXCH A,C ; BY LIST HOLDING THEM (B IS ZERO)
|
||
POPJ P,
|
||
|
||
|
||
BNTRSZ: JUMPGE A,BNPJ2 ;SKIPS 2 IF NOT -1_43 IN BIGNUM FORMAT. ELSE NO SKIP
|
||
BNTRS1: HRRZ AR1,(A) ;MUNGS ONLY AR1
|
||
JUMPE AR1,BNPJ2
|
||
MOVS AR1,(AR1)
|
||
TLNE AR1,-1
|
||
JRST BNPJ2
|
||
HLL AR1,(AR1) ;ALL THIS KLUDGERY SO THAT RANDOM
|
||
TLNE AR1,-1 ; NUMERIC QUANTITIES WILL NOT GET
|
||
JRST BNPJ2 ; IN THE RIGHT HALF OF AR1
|
||
HRLZ AR1,(AR1)
|
||
TLC AR1,1
|
||
JUMPN AR1,BNPJ2
|
||
HLRZ AR1,(A)
|
||
SKIPN (AR1)
|
||
POPJ P,
|
||
BNPJ2: POP P,AR1
|
||
JRST 2(AR1)
|
||
|
||
BNCV: PUSH FXP,D
|
||
PUSHJ FXP,SAV5M1
|
||
PUSHJ P,BNCVTM
|
||
MOVE A,TT
|
||
PUSHJ P,BCOPY
|
||
JRST UUOSE1
|
||
|
||
BNCVTM: JUMPL TT,T16 ;CONVERT NUMBER IN TT TO INTERNAL BIGNUM
|
||
T17: MOVEM TT,BNV1
|
||
MOVE TT,BNV2
|
||
POPJ P,
|
||
T16: MOVNS TT
|
||
JUMPL TT,T23 ;400000,,
|
||
PUSHJ P,T17
|
||
TLCA TT,-1
|
||
T23: MOVE TT,BNM235 ;CONVERTED TO BIGNUM -2E35.
|
||
POPJ P,
|
||
|
||
SUBTTL BIGNUM ADDITION SUBROUTINE
|
||
|
||
BNSUB: TLC B,-1 ;CHANGE SIGN OF 2ND ARG
|
||
BNADD: MOVE C,A ;FIRST ARGUMENT TO C
|
||
HLLZ A,C ;SET UP NULL BIGNUM WITH SIGN OF FIRST ARG
|
||
PUSH P,A
|
||
HLLZ F,B ;DITTO SECOND ARG
|
||
MOVEI R,BNADD2 ;SET UP FOR REAL ADD
|
||
CAME A,F ;CHECK FOR SAME SIGNS
|
||
MOVEI R,BNSUB2 ;CHANGE TO SUBTRACT
|
||
MOVE F,P ;F POINTS TO BOTTOM WORD OF ANSWER
|
||
MOVEI TT,0 ;ARITHMETIC DONE IN TT
|
||
BN4: MOVE AR2A,C
|
||
MOVE C,(C) ;CDR C
|
||
MOVE B,(B) ;CDR B
|
||
BN15: MOVEI D,0 ;CLEAR CARRY
|
||
HLRZ AR1,C
|
||
ADD TT,(AR1)
|
||
HLRZ AR1,B
|
||
XCT -1(R) ;ADD/SUB TT,(AR1)
|
||
TLZE TT,400000 ;CARRY OR BORROW
|
||
MOVE D,-2(R) ;PLUS OR MINUS 1
|
||
JSP T,FWCONS
|
||
MOVE AR1,A
|
||
PUSHJ P,ACONS
|
||
HRRM A,(F) ;NCONC ONTO ANSWER
|
||
MOVE F,A ;UPDATE POINTER TO LAST WORD
|
||
BN20: TRNN B,-1 ;END OF SECOND ARG?
|
||
JRST @-3(R)
|
||
BN7: TRNN C,-1 ;END OF FIRST ARG?
|
||
JRST (R)
|
||
BN9: MOVE TT,D ;MOVE CARRY TO TT
|
||
JRST BN4
|
||
|
||
|
||
BN5
|
||
1 ;CARRY
|
||
ADD TT,(AR1)
|
||
BNADD2: JUMPN D,BN8 ;FIRST ARG DONE; IF CARRY, SIMULATE A ZERO
|
||
BN14: HRRM B,(F) ;USE REST OF SECOND ARG
|
||
JRST POPAJ
|
||
BN8: MOVEI C,[R70,,]
|
||
JRST BN9
|
||
|
||
BN5: JUMPN D,BN6 ;2ND ARG EXHAUSTED; IF CARRY, SIMULATE A ZERO
|
||
BN13: HRRM C,(F)
|
||
JRST POPAJ
|
||
BN6: MOVEI B,[R70,,]
|
||
JRST BN7
|
||
|
||
|
||
BN12
|
||
-1 ;BORROW
|
||
SUB TT,(AR1)
|
||
BNSUB2:
|
||
;COME HERE ONLY IF ABS(1)<ABS(2)
|
||
;FIRST ARG DONE, AND (2ND IS NOT DONE, OR THERE IS A BORROW)
|
||
;IT IS NECESSARY TO TAKE THE TWOS COMPLEMENT OF THE PARTIAL ANSWER
|
||
MOVE A,(P)
|
||
TLC A,-1
|
||
MOVEM A,(P)
|
||
MOVSI TT,400000 ;TT IS INITIALIZED TO 400000000000
|
||
;AND UNCHANGED WHILE THE PARTIAL ANSWER IS ZEROS
|
||
;AFTER A NONZERO WORD, TT IS RESET TO 377777777777 AFTER EACH SUBTRACT
|
||
SKIPA C,(A) ;SCAN DOWN NUMBER; LEFT HALF OF C NOW POINTS AT LOW ORDER WORD
|
||
BN10: MOVE C,(C)
|
||
HLRZ AR1,C
|
||
SUBB TT,(AR1)
|
||
SKIPL TT ;IFF TT IS STILL SETZ, (AR1) WAS ZERO AND MUST BE FIXED
|
||
SKIPA TT,[377777777777]
|
||
SETZM (AR1)
|
||
TRNE C,-1
|
||
JRST BN10
|
||
JUMPL D,BN11 ;IF BORROW: THE PARTIAL ANSWER WAS NONZERO TO GENERATE THE BORROW
|
||
;A RECOMPLEMENT BORROW OCCURED. TT IS 377777777777.
|
||
;SHOULD USE REST OF 2ND ARGUMENT
|
||
JUMPL TT,BN14 ;TT<0: THE PARTIAL ANSWER WAS ZERO; 1ST ARG IS PROPER INITIAL SEGMENT OF 2ND ARG
|
||
;USE REST OF 2ND ARG, GUARANTEED TO BE NONZERO
|
||
MOVNI TT,1 ;RECOMPLEMENT BORROW BUT NO ORIGINAL BORROW; USE REST OF 2ND ARG WITH BORROW
|
||
MOVE C,(B) ;SWAP ARGS
|
||
MOVSI B,[0]
|
||
JRST BN15 ;CONTINUE AS A SUBTRACT IN WHICH "2ND" ARG IS EXHAUSTED, AND A BORROW PROPAGATED
|
||
;CURIOUS THINGS HAPPEN IF THE REST OF "1ST" ARG IS ZERO(AN IMPROPER FORMAT)
|
||
|
||
BN11: TLNE B,-1 ;TRY TO AVOID USING THE TRUNCATE ROUTINE
|
||
JRST BN14 ;REST OF 2ND ARG IS NOT NULL, SO USE IT
|
||
BN11A: POP P,A
|
||
SKIPE (AR1) ;AR1 POINTS AT HIGH WORD OF DIFFERENCE
|
||
POPJ P,
|
||
JRST BNTRUN
|
||
|
||
BN12: JUMPN D,BN6 ;2ND ARG EXHAUSTED; IF BORROW, INVENT A ZERO
|
||
TRNE C,-1 ;IF 1ST ARG IS NOT EXHAUSTED, USE REST OF IT
|
||
JRST BN13
|
||
JRST BN11A ;BOTH ARGS EXHAUSTED
|
||
|
||
BNM1: JUMPE D,POPAJ ;SWAP OUT ONLY A NONZERO CARRY
|
||
PUSH P,CPOPAJ ;FOR MULTIPLICATION ROUTINE
|
||
BNM2: EXCH D,TT
|
||
JSP T,FWCONS
|
||
PUSHJ P,ACONS
|
||
EXCH D,TT
|
||
HRRM A,(R) ;NCONC CARRY WORD TO ANSWER BIGNUM
|
||
POPJ P,
|
||
|
||
|
||
SUBTTL BIGNUM MULTIPLICATION SUBROUTINE
|
||
|
||
;MULTIPLY IS DONE IN TWO PARTS: (1) MULTIPLY FIRST ARG BY FIRST WORD OF SECOND ARG
|
||
;(2) MULTIPLY [AND ADD IN TO TOTAL] FIRST ARG BY EACH REMAINING WORD OF THE SECOND ARG
|
||
;SLIGHTLY FASTER IF SECOND ARG IS SHORTER
|
||
BNMUL: MOVE C,A
|
||
HLLZ A,C ;CREATE NULL BIGNUM WITH SIGN OF FIRST ARG
|
||
XOR A,B ;SKIP IF 2ND ARG POSITIVE. CHANGE SIGN OF ANSWER
|
||
PUSH P,A
|
||
MOVE R,P ;R POINTS AT LAST WORD OF ANSWER BIGNUM DURING PART ONE OF MULTIPLY
|
||
MOVE B,(B) ;GET FIRST WORD OF SECOND ARG
|
||
HLRZ F,B
|
||
MOVE F,(F)
|
||
MOVEI D,0 ;ZERO CARRY WORD
|
||
SKIPA AR2A,(C) ;PREPARE TO GOBBLE FIRST ARG
|
||
BNM5: MOVE AR2A,(AR2A)
|
||
HLRZ T,AR2A ;GOBBLE A WORD OF FIRST ARG
|
||
MOVE T,(T)
|
||
MUL T,F ;AFTER MULTIPLY, T<377777777777
|
||
ADD TT,D ;CARRY<400000000000; SUM<777777777777
|
||
MOVE D,T
|
||
TLZE TT,400000 ;CLEAR SIGN BIT AND PROPAGATE
|
||
AOS D ;NEW CARRY<400000000000
|
||
PUSHJ P,C1CONS
|
||
HRRM A,(R)
|
||
MOVE R,A ;UPDATE POINTER TO LAST WORD
|
||
TRNE AR2A,-1 ;END OF FIRST ARG?
|
||
JRST BNM5
|
||
MOVE A,(P)
|
||
HRRM A,BNMSV
|
||
BNM4: TRNN B,-1 ;END OF SECOND ARGUMENT?
|
||
JRST BNM1 ;YES; SWAP OUT CARRY IF NOT ZERO
|
||
PUSHJ P,BNM2
|
||
MOVE B,(B) ;GET NEXT WORD OF SECOND ARG
|
||
HLRZ F,B
|
||
MOVE F,(F)
|
||
MOVE R,@BNMSV
|
||
HRRM R,BNMSV
|
||
MOVE AR2A,(C) ;RESET FIRST ARGUMENT
|
||
MOVEI D,0 ;CLEAR OUT CARRY
|
||
BNM3: HLRZ T,AR2A ;GET A WORD OF FIRST ARG
|
||
MOVE T,(T)
|
||
MUL T,F ;AFTER MULTIPLY, T<377777777777
|
||
ADD TT,D ;CRY<400000000001, SUM<1000000000000
|
||
TLZE TT,400000 ;CLEAR SIGN BIT AND PROPAGATE
|
||
AOS T ;NEW T<400000000000
|
||
HLRZ D,(R) ;GET WORD OF ACCUMULATOR
|
||
ADD TT,(D) ;SUM<777777777777
|
||
TLZE TT,400000 ;CLEAR SIGN BIT AND PROPAGATE
|
||
AOS T ;NEW T<400000000001
|
||
MOVEM TT,(D) ;STORE WORD OF ACCUMULATOR
|
||
MOVE D,T
|
||
TRNN AR2A,-1 ;SKIP IF NOT END OF FIRST ARG
|
||
JRST BNM4
|
||
MOVE AR2A,(AR2A) ;ADVANCE TO NEXT WORD OF FIRST ARG
|
||
MOVE R,(R) ;ADVANCE TO NEXT WORD OF ACCUMULATOR
|
||
JRST BNM3
|
||
|
||
SUBTTL BIGNUM DIVISION SUBROUTINE
|
||
|
||
BNQUO: SETZM NORMF ;INITIALIZE NORMALIZATION FACTOR
|
||
SETZM VETBL0 ;INITIALIZE "FIRST TIME THRU" FLAG
|
||
PUSH P,B ;SETS UP TO TEST FIRST DIVISOR WORD
|
||
PUSH P,A
|
||
BNQUO1: MOVEI D,1
|
||
MOVE C,B
|
||
MOVE C,(C)
|
||
MOVE AR1,(C)
|
||
AOS D
|
||
TRNE AR1,-1
|
||
JRST .-4
|
||
HLRZS AR1
|
||
MOVE F,(AR1)
|
||
CAMGE F,[200000,,0] ;NORMALIZATION TEST
|
||
JRST BQNORM
|
||
SKIPN NORMF
|
||
JRST BQCOPY
|
||
MOVSS C ;GET TOP TWO DIVISOR WORDS
|
||
MOVE C,(C)
|
||
MOVEM F,DVS1
|
||
MOVEM C,DVS2
|
||
MOVEM D,DVSL
|
||
MOVEI C,(A) ;SET UP QUOTIENT
|
||
JUMPGE B,.+2
|
||
TLC A,-1
|
||
HLLZS A
|
||
TLZ B,-1 ;PROB. UNNECESSARY, BUT WHY TAKE CHANCES?
|
||
PUSH P,A
|
||
BQ1: MOVEI R,3 ;THIS GETS DVD WORDS FOR THE QUOTIENT ESTIMATE
|
||
MOVE AR2A,C
|
||
BQ2: MOVE AR2A,(AR2A)
|
||
TRNN AR2A,-1
|
||
JRST BQSRRM ;PARTIAL REMAINDER IS ONLY ONE WORD LONG
|
||
MOVE T,(AR2A)
|
||
TRNN T,-1
|
||
JRST BQSHRM ;PARTIAL REM OR DVD IS 2 WORDS LONG
|
||
MOVE TT,(T)
|
||
TRNE TT,-1
|
||
AOJA R,BQ2
|
||
JRST BQCC
|
||
|
||
|
||
BQCC: MOVSS AR2A
|
||
MOVE AR2A,(AR2A)
|
||
MOVEM AR2A,DD3
|
||
MOVSS T
|
||
MOVE T,(T)
|
||
MOVEM T,DD2
|
||
MOVSS TT
|
||
MOVE TT,(TT)
|
||
MOVEM TT,DD1
|
||
SKIPN VETBL0
|
||
JRST BQVET
|
||
MOVEM R,DDL
|
||
BQGEST: SUB R,DVSL ;CHECKS FOR PARTIAL REMAINDER<DIVISOR
|
||
JUMPL R,BQZQ
|
||
JUMPN R,BQGESS
|
||
EXCH R,DD1 ;SINCE R WAS 0, NOW DD1 IS 0
|
||
exch r,dd2 ;I just fixed this code to move DD2 into DD3
|
||
MOVEM R,DD3 ; as well as 0 -> DD1 -> DD2. I must admit
|
||
JRST BQGESS ; to not understanding why this shift is
|
||
BQZQ: SETZM QHAT ; necessary, but it was clearly wrong the way
|
||
JRST BQ8 ; it was! -Alan 8/6/83
|
||
|
||
|
||
BQCOPY: SETOM NORMF ;COPIES DIVIDEND TO GET WORK SPACE
|
||
PUSHJ P,BCOPY ;CLOBBERS T TT D B C AR1
|
||
MOVEM A,(P)
|
||
MOVE B,-1(P)
|
||
JRST BNQUO1
|
||
|
||
BQNORM: ADDI F,1 ;THIS SECTION MULTIPLIES DVD AND DIV BY NORMF
|
||
MOVEI T,1
|
||
SETZ TT,
|
||
DIV T,F
|
||
MOVEM T,NORMF
|
||
MOVE A,B
|
||
MOVEM T,BNV1
|
||
MOVE B,BNV2
|
||
PUSHJ P,BNMUL
|
||
EXCH A,(P)
|
||
MOVE B,BNV2
|
||
PUSHJ P,BNMUL
|
||
MOVE B,A
|
||
EXCH B,(P)
|
||
MOVEM B,-1(P)
|
||
JRST BNQUO1
|
||
|
||
|
||
BQ6:
|
||
BQSRRM: SETZM QHAT ;COME HERE IF PARTIAL REM IS ONE WORD
|
||
JRST BQ8 ;MEANS QUOTIENT AT THIS STEP IS ZERO
|
||
|
||
BQSHRM: MOVEI R,2 ;COME HERE IF PARTIAL REMAINDER IS 2 WORDS LONG
|
||
MOVSS AR2A
|
||
MOVSS T
|
||
MOVE T,(T)
|
||
MOVE AR2A,(AR2A)
|
||
MOVEM T,DD2
|
||
MOVEM AR2A,DD3
|
||
SETZM DD1
|
||
SKIPE VETBL0
|
||
JRST BQGESS
|
||
JRST BQ10
|
||
|
||
BQVET: MOVEM TT,DD2
|
||
MOVEM T,DD3
|
||
SETZM DD1
|
||
JRST BQ10
|
||
|
||
|
||
BQSHRT: MOVE A,-1(P)
|
||
JUMPE R,BQSH0
|
||
SKIPE REMFL
|
||
JRST REMFIN
|
||
HLLZS R
|
||
HRRM R,-1(P)
|
||
JRST BQ6
|
||
|
||
REMFIN: HLL A,-1(P)
|
||
TRNN A,-1
|
||
MOVE A,-1(P) ;IN CASE DIVIDEND IS REMAINDER
|
||
PUSHJ P,BNTRUN
|
||
MOVE TT,NORMF
|
||
SUB P,R70+3
|
||
POPJ P,
|
||
|
||
|
||
BQ10: SUB R,DVSL ;SETS UP INITIAL ZERO FOR FIRST GUESS
|
||
SKIPG R
|
||
JRST BQSHRT
|
||
SOSN R
|
||
JRST BQ1DF
|
||
MOVEM R,DDL
|
||
MOVE F,C
|
||
BQDD: MOVE F,(F)
|
||
MOVE TT,(F)
|
||
SOJLE R,BQ11
|
||
JRST BQDD
|
||
BQ11: MOVEI A,(TT)
|
||
MOVEI R,0
|
||
HRRM R,(F)
|
||
MOVE C,A
|
||
JRST BQGESS
|
||
|
||
BQ5: MOVE AR2A,[377777777777]
|
||
BQ7: MOVE A,C ;MULTIPLY,SUBTRACT,AND ADD BACK LOOP
|
||
MOVEM AR2A,QHAT
|
||
SETZB AR2A,AR1
|
||
MOVE B,-2(P)
|
||
MOVE D,QHAT
|
||
PUSHJ P,BQSUB
|
||
HLLZS (AR2A)
|
||
TRZ AR2A,777777
|
||
PUSHJ P,BNTRUN
|
||
BQ8: SETOM VETBL0 ;QUOTIENT STORING LOOP
|
||
SKIPE REMFL
|
||
JRST BQ9
|
||
MOVE AR1,A
|
||
EXCH TT,AGDBT
|
||
MOVE TT,QHAT
|
||
PUSHJ P,C1CONS
|
||
MOVE F,(P)
|
||
HRRM F,(A)
|
||
HRRM A,(P)
|
||
MOVE A,AR1
|
||
EXCH TT,AGDBT
|
||
BQ9: MOVE B,-1(P) ;BRING DOWN A NEW DVD WORD
|
||
TRNN B,-1
|
||
JRST BQFIN
|
||
MOVE C,(B)
|
||
TRNN C,-1
|
||
JRST BQEFIN
|
||
BQ9A: MOVE AR1,(C)
|
||
TRNN AR1,-1
|
||
JRST BQ9B
|
||
MOVE B,(B)
|
||
MOVE C,(B)
|
||
JRST BQ9A
|
||
|
||
BQ9B: MOVEI AR1,0
|
||
HRRM AR1,(B)
|
||
HRRM A,(C)
|
||
HRR A,C
|
||
PUSHJ P,BNTRUN
|
||
MOVE C,A
|
||
JRST BQ1
|
||
|
||
|
||
BQEFIN: MOVEI C,0
|
||
HRRM C,-1(P)
|
||
MOVE C,B
|
||
JRST BQ9B
|
||
|
||
BQSH0: HLLZS R
|
||
HRRM R,-1(P)
|
||
JRST BQGESS
|
||
|
||
BQ1DF: HRRZ A,(C)
|
||
MOVEI R,0
|
||
HRRM R,(C)
|
||
MOVE C,A
|
||
BQGESS: JRST 2,@[.+1]
|
||
MOVE D,DVS1 ;CLEARS NO DIVIDE FLAG
|
||
MOVE T,DD1
|
||
MOVE TT,DD2
|
||
DIV T,D ;Computes Q^ into T
|
||
JSP R,.+1
|
||
TLNE R,40 ;If overflow, then Q^ = B-1
|
||
JRST BQ5
|
||
JUMPE T,BQ6 ;If Q^ = 0, then no chek, also skip the whole
|
||
;multiply and subtract loop.
|
||
MOVE AR2A,T ;AR2A is the final home for Q^.
|
||
move r,tt ;Place R^ in R
|
||
move f,dd3 ;(R,F) is doubleword for left half of inequality
|
||
bqchek: mul t,dvs2 ;(T,TT) is doubleword right half of inequality
|
||
camg t,r
|
||
jrst bqc1
|
||
bqc2: add r,d ;inequality was true, adjust Q^ down and R^ up.
|
||
tlne r,400000 ;If R^ overflows then test will fail,
|
||
soja ar2a,bq7 ; and new Q^ is good.
|
||
sosle t,ar2a
|
||
jrst bqchek
|
||
jrst bq6 ;I don't know if this ever happens. -Alan
|
||
|
||
bqc1: caml t,r
|
||
camg tt,f
|
||
jrst bq7
|
||
jrst bqc2
|
||
|
||
;;; I've commented out the following code. Unlike JonL, I understand what
|
||
;;; is supposed to be happening here, and this code was
|
||
;;; obviously broken. I replaced it with the (I believe) correct code
|
||
;;; above. Interested hackers are refered to Volume II of Knuth for the
|
||
;;; explanation.
|
||
;;; -Alan 6/1/83
|
||
;;;
|
||
;;; BQCHEK: MUL T,D
|
||
;;; MOVE R,DD1
|
||
;;; MOVE F,DD2
|
||
;;; SUB F,TT
|
||
;;; TLZ F,400000
|
||
;;; MOVE R,F
|
||
;;; MOVE F,DD3
|
||
;;; MOVE T,DVS2
|
||
;;; MUL T,AR2A
|
||
;;; CAMG T,R
|
||
;;; JRST BQC1
|
||
;;; BQC2: SOJA AR2A,BQ7
|
||
;;; BQC1:
|
||
;;; ;I've commentted out the following code.
|
||
;;; ; not that I claim to understand this, but if the quotient is a number of
|
||
;;; ; the form 1+2^N for N > 36., then the jump to BQC2 seems to be wrong.
|
||
;;; ; also as far as I can tell, no other case gets to that jump instruction.
|
||
;;; ; - JONL - 12/13/79
|
||
;;;
|
||
;;; ;;; CAMN T,R
|
||
;;; ;;; CAMG TT,F
|
||
;;; ;;; JRST BQ7
|
||
;;; ;;; JRST BQC2
|
||
;;;
|
||
;;; JRST BQ7
|
||
|
||
BQFIN: SKIPE REMFL
|
||
JRST REMFIN
|
||
SETZB A,B
|
||
EXCH A,-1(P)
|
||
PUSHJ P,RECLAIM
|
||
EXCH A,-2(P) ;NOTE: RECLAIM RETURNED NIL
|
||
AOSE NORMF
|
||
PUSHJ P,RECLAIM
|
||
POP P,A
|
||
SUB P,R70+2
|
||
JRST BNTRUN
|
||
|
||
BQSUB: MOVEI R,0 ;THIS MULTIPLIES DIVISOR BY PARTIAL QUOTIENT ESTIMATE
|
||
BQSUB0: MOVE AR2A,A ;AND SUBTRACTS FROM THE PARTIAL REMAINDER
|
||
MOVE A,(A) ;AND ADDS BACK IF THE ESTIMATE WAS TOO LARGE
|
||
MOVE B,(B) ;THE NEW PARTIAL REMAINDER IS STORED IN
|
||
HLRZ T,B ;THE SAME WORDS AS THE OLD PART. REM.
|
||
MOVE T,(T)
|
||
MUL T,D
|
||
MOVS AR1,A
|
||
ADD TT,R
|
||
TLZE TT,400000
|
||
AOS T
|
||
EXCH TT,(AR1)
|
||
SUBB TT,(AR1)
|
||
TLZE TT,400000
|
||
AOS T
|
||
MOVEM TT,(AR1)
|
||
TRNN B,-1
|
||
JRST BQSUB1
|
||
BQSUB7: TRNN A,-1
|
||
JRST BQSUB3
|
||
MOVE R,T
|
||
JRST BQSUB0
|
||
|
||
BQSUB1: JUMPN T,BQSUB6
|
||
MOVE A,C
|
||
POPJ P,
|
||
|
||
BQSUB6: MOVEI B,[R70,,NIL]
|
||
JRST BQSUB7
|
||
|
||
;;; KNUTH SAYS THE FOLLOWING PIECE OF CODE (ADDING BACK) IS
|
||
;;; NEEDED IN ONLY ABOUT 3 OR 4 CASES IN 34 BILLION. HERE
|
||
;;; ARE TWO NUMBERS ACCIDENTALLY DISCOVERED BY GOSPER WHICH
|
||
;;; WILL CAUSE THIS ADDING BACK TO HAPPEN:
|
||
;;; THE DIVIDEND IS:
|
||
;;; 2791789817939938387128631852330682768655711099796886
|
||
;;; 76652915704481188064205113686384821261582354
|
||
;;; 6679451522036433421137784129286923496509.
|
||
;;; THE DIVISOR IS:
|
||
;;; 888654299197548479101428655285643704385285845048283
|
||
;;; 973585973531.
|
||
;;; TO SEE WHY HE DISCOVERED IT, TRY LOOKING AT THE QUOTIENT!
|
||
;;;Unfortunately for this comment, the improved code at BQCHEK now detects
|
||
;;;this case early (the case below still causes an addback). Actually it
|
||
;;;is absurdly easy to force the execution of this code. Pick any two
|
||
;;;random bignums A and B and compute (*QUO (SUB1 (TIMES A B)) A). This
|
||
;;;code will almost certainly run (but not always). -Alan 6/1/83
|
||
;;;
|
||
;;; HERE ARE TWO MORE NUMBERS WHICH EXCUTE THIS CODE; FURTHERMORE,
|
||
;;; THEY CAUSE THE OVER-SUBTRACTED DIVIDEND TO BE SHORTER THAN
|
||
;;; THE DIVISOR; THIS IS THE REASON FOR THE COPYING BELOW.
|
||
;;; (GOSPER ALSO DISCOVERED THESE NUMBERS!)
|
||
;;; THE DIVIDEND IS:
|
||
;;; 814814390533794434507378275363751264420699600792121
|
||
;;; 5135985742227369051304412442580926595072.
|
||
;;; THE DIVISOR IS:
|
||
;;; 10889035741470030830827987437816582766593.
|
||
|
||
;;;This commented out code finally proved totally buggious. The following
|
||
;;;two numbers violate its assumptions about the length of the bignum in C
|
||
;;;at this point. Not being completely in tune with whatever invariants
|
||
;;;the original writer of this code knew about the lengths of things, I
|
||
;;;have replaced this routine with one that makes less assumptions. That
|
||
;;;should prove more robust in the long run, as well as fixing the present
|
||
;;;bug. -Alan 6/2/83
|
||
;;;Dividend:
|
||
;;; 561665555565638329055562814312908972367440508802928593356325213525.
|
||
;;;Divisor: 432691404877902302377541360768341.
|
||
;;;
|
||
;;; BQSUB3: HLLZS (AR2A) ;CHOP OFF END OF ANSWER STORAGE
|
||
;;; TRZ AR2A,777777
|
||
;;; MOVE A,C
|
||
;;; PUSHJ P,BNTRUN ;TRUNCATE ANSWER, WHICH IS A NEGATIVE NUMBER IN POSITIVE FORM
|
||
;;; PUSH P,A
|
||
;;; HRRZ A,-4(P) ;GET (ABSOLUTE VALUE OF) DIVISOR
|
||
;;; PUSHJ P,BCOPY ;MUST COPY IT, OR ELSE CARRY
|
||
;;; POP P,B ; TRUNCATION MIGHT CLOBBER IT!
|
||
;;; PUSHJ P,BNADD ;SET UP ANSWER FOR ADD BACK
|
||
;;; SKIPA B,A
|
||
;;; BQSUB4: MOVE B,(B) ;CHOP OFF CARRY
|
||
;;; MOVE C,(B)
|
||
;;; HRRZ AR1,(C)
|
||
;;; JUMPN AR1,BQSUB4
|
||
;;; MOVE AR2A,B ;CARRY WILL BE CHOPPED OFF WHEN THIS POPJ'S
|
||
;;; SOS QHAT ;CORRECT QUOTIENT GUESS
|
||
;;; POPJ P,
|
||
|
||
;;;New version:
|
||
bqsub3: sos qhat ;Q^ was one two large, so decrement it
|
||
move a,c ; and add back.
|
||
move b,-3(p)
|
||
setzi r, ;R contains the carry from previous round.
|
||
bqsub4: move ar2a,a ;We perform the same kludge with AR2A that
|
||
move a,(a) ; the main BQSUB0 loop does.
|
||
move b,(b)
|
||
hlrz t,b
|
||
add r,(t)
|
||
hlrz t,a
|
||
add r,(t)
|
||
setzi tt, ;TT contains proposed cary for next round.
|
||
tlze r,400000 ;Test for carry.
|
||
movei tt,1
|
||
movem r,(t) ;smash it in
|
||
move r,tt
|
||
trnn a,-1
|
||
jrst bqsubz
|
||
trnn b,-1 ;Can this happen? A should never be
|
||
movei b,[r70,,nil] ; longer than B as I understand things.
|
||
jrst bqsub4 ; I don't think it can hurt to do this.
|
||
|
||
bqsubz: move a,c
|
||
popj p,
|
||
|
||
SUBTTL BIGNUM TO FLONUM CONVERSION
|
||
|
||
FLBIGF: JUMPN R,FLBIG
|
||
PUSH P,CFLOAT1
|
||
FLBIG: PUSHJ P,SAVX5 ;RECEIVES BIGNUM HEADER IN TT,
|
||
HLRZ A,TT ;LEAVES SIGN BIT IN AC A
|
||
HRRZ T,(TT) ;LEAVES RESULT AS NUMERIC IN TT
|
||
JUMPE T,FLTB1 ;SAVES ALL OTHER ACS
|
||
PUSHJ P,FLBIGZ
|
||
FADR TT,D ;ROUND UP
|
||
SKIPE RWG
|
||
JFCL 8.,FLBIGX
|
||
JFCL 8.,FLBIGO
|
||
FLBIGX: JUMPE A,.+2
|
||
MOVNS TT
|
||
MOVEM TT,-3(FXP)
|
||
JRST RSTX5
|
||
|
||
|
||
FLBIGZ: PUSHJ P,1HAU ;MUST BE > 27. BITS, OR ELSE WOULDN'T BE HERE
|
||
MOVEI T,(TT)
|
||
MOVEI D,27.
|
||
PUSHJ P,1HAI1 ;1HAI1 LEAVES TRAILING BITS IN TT+1
|
||
ASH TT+1,-8.
|
||
TLO TT,200000 ;INSTALL EXPONENTS
|
||
TLO TT+1,145000
|
||
JFCL 8.,.+1
|
||
TRNE T,-1#377 ;INSURE OVERFLOW IF EXPONENT IS TOO LARGE
|
||
TRO T,377
|
||
FSC TT,(T)
|
||
FSC TT+1,(T)
|
||
POPJ P,
|
||
|
||
FLTB1: HLRZ TT,(TT)
|
||
MOVE TT,(TT) ;ONE-WORD BIGNUM?
|
||
JSP T,IFLOAT
|
||
MOVE D,TT
|
||
JRST FLBIGX
|
||
|
||
FLBIGQ: HRROS (P) ;HACK SO THAT (*QUO <FLONUM> <HUGE-BIGNUM>)
|
||
JRST FLBIG ; WILL CAUSE UNDERFLOW, NOT OVERFLOW
|
||
|
||
FLBIGO: PUSHJ P,RSTX5
|
||
POP P,T
|
||
TLNN T,1 ;IF BIT 3.1 IS SET, SO IS 4.7 (SEE T7O0)
|
||
JRST OVFLER
|
||
AOJA T,T7O0
|
||
|
||
SUBTTL FLONUM TO BIGNUM CONVERSION
|
||
|
||
FIXBIG: MOVE TT,T
|
||
MULI TT,400
|
||
JSP T,BNARSV
|
||
MOVE AR1,A
|
||
MOVE F,D
|
||
SUBI TT,200
|
||
IDIVI TT,43
|
||
SETZ R,
|
||
ASHC R,(D)
|
||
MOVE D,TT
|
||
JUMPE R,FXBFQ
|
||
MOVE TT,R
|
||
JSP T,FWCONS
|
||
PUSHJ P,NCONS
|
||
MOVE TT,F
|
||
MOVE C,A
|
||
FXBFV: JSP T,FWCONS
|
||
PUSHJ P,NCONS
|
||
HRRM C,(A)
|
||
MOVEI C,(A)
|
||
FXBFZ: SOJLE D,FBFIN
|
||
MOVEI TT,0
|
||
PUSHJ P,C1CONS
|
||
HRRM C,(A)
|
||
MOVEI C,(A)
|
||
JRST FXBFZ
|
||
FBFIN: SKIPG (AR1)
|
||
TLC A,-1
|
||
JSP T,BNARRS
|
||
JRST BNCONS
|
||
|
||
FXBFQ: MOVEI C,0
|
||
MOVE TT,F
|
||
JRST FXBFV
|
||
|
||
MNSBG: TLC TT,-1 ;MINUS, FOR BIGNUM
|
||
MOVE A,TT
|
||
PUSH P,AR1
|
||
PUSH P,[POP4J]
|
||
PUSHJ P,BNTRSZ ;FOR 100000000000, CONVERT
|
||
MOVE TT,[1_43] ; TO FIXNUM SETZ, ELSE
|
||
JRST FIX1
|
||
JRST BNCONS ; TO A REGULAR BIGNUM
|
||
POP4J: POP P,AR1
|
||
POPJ P,
|
||
|
||
|
||
SUBTTL ABS AND REMAINDER FOR BIGNUMS
|
||
|
||
ABSBG0: MOVE TT,(A)
|
||
ABSBG: JUMPGE TT,CPOPJ ;ABS FOR BIGNUM
|
||
HRRZ A,TT
|
||
JRST BGNMAK
|
||
|
||
REMBIG: EXCH A,B
|
||
MOVE D,TT ;REMAINDER FOR BIGNUM
|
||
SETZM PLUS8 ;SO THAT ARITHMETIC LOOP WILL RESTORE TO HERE
|
||
SETOM REMFL
|
||
JSP T,NVSKIP
|
||
JRST BNDV ;REMFL WILL STOP ARITHMETIC LOOP
|
||
JRST REM2BN
|
||
JSP T,REMAIR ;FOO! FLONUM ARG NOT COMPREHENSIBLE!
|
||
|
||
GRBB: SETZM NORMF ;GREATERP FOR BIGNUM WITH BIGNUM
|
||
MOVE A,D
|
||
MOVE B,TT
|
||
MOVE AR1,D
|
||
MOVE AR2A,TT
|
||
ASH TT,-43
|
||
ASH D,-43
|
||
CAME D,TT
|
||
JRST GRB13
|
||
SETO C,
|
||
GRBBL: TRNN AR1,-1
|
||
JRST GRB1
|
||
TRNN AR2A,-1
|
||
JRST GRB2
|
||
MOVS AR1,(AR1)
|
||
MOVS AR2A,(AR2A)
|
||
MOVE D,(AR1)
|
||
MOVE TT,(AR2A)
|
||
JUMPGE A,.+3
|
||
MOVNS D
|
||
MOVNS TT
|
||
XCT GRESS0
|
||
JRST GRBF
|
||
SETZ C,
|
||
GRBR: MOVSS AR1
|
||
MOVSS AR2A
|
||
JRST GRBBL
|
||
|
||
SUBTTL GREATERP AND LESSP FOR BIGNUMS
|
||
|
||
GRFXB: SETZM NORMF ;GREATERP FOR FIXNUM WITH BIGNUM
|
||
PUSH FXP,D
|
||
MOVE B,TT
|
||
MOVEI AR2A,QBIGNUM
|
||
MOVEI AR1,QFIXNUM
|
||
TLNE D,400000
|
||
SKIPA D,XC-1
|
||
MOVEI D,1
|
||
JRST GRB14
|
||
|
||
GRBFX: SETZM NORMF ;GREATERP FOR BIGNUM WITH FIXNUM
|
||
PUSH FXP,TT
|
||
MOVE A,D
|
||
MOVEI AR1,QBIGNUM
|
||
MOVEI AR2A,QFIXNUM
|
||
TLNE TT,400000
|
||
SKIPA TT,XC-1
|
||
MOVEI TT,1
|
||
JRST GRB14
|
||
|
||
|
||
GRBF: CAMN D,TT
|
||
JRST GRBR
|
||
SETO C,
|
||
JRST GRBR
|
||
|
||
GRB1: TRNN AR2A,-1
|
||
JRST GRBBEL
|
||
MOVEI D,2
|
||
MOVEI TT,4
|
||
GRB12: TLNE A,1
|
||
EXCH D,TT
|
||
GRB13: MOVEI AR1,QBIGNUM
|
||
MOVEI AR2A,QBIGNUM
|
||
GRB14: XCT GRESS0
|
||
SKIPA C,[-1]
|
||
MOVEI C,0
|
||
JRST GRBBE2
|
||
|
||
GRB2: SETOM NORMF
|
||
MOVEI D,4
|
||
MOVEI TT,2
|
||
JRST GRB12
|
||
|
||
GRBBEL: MOVEI AR1,QBIGNUM
|
||
MOVEI AR2A,QBIGNUM
|
||
GRBBE2: MOVE D,A
|
||
MOVE TT,B
|
||
CAIN AR2A,QFIXNUM
|
||
POP FXP,TT
|
||
CAIN AR1,QFIXNUM
|
||
POP FXP,D
|
||
SKIPE NORMF
|
||
MOVNS C
|
||
SKIPN C
|
||
XCT CSUCE
|
||
XCT CFAIL
|
||
|
||
SUBTTL HAIPART FOR BIGNUMS
|
||
|
||
IFN USELESS,[
|
||
1HAI: JSP T,FXNV2
|
||
JUMPLE D,3HAI
|
||
PUSH FXP,D
|
||
PUSHJ P,1HAU
|
||
POP FXP,D
|
||
CAILE D,35.
|
||
JRST 2HAI
|
||
PUSH P,CFIX1
|
||
] ;END OF IFN USELESS
|
||
;IN USELESS VERSION, 1HAI CALLED ONLY BY FLBIG
|
||
1HAI1: ADDI R,-35.-1(D) ;FINAL ANSWER FITS IN ONE WORD
|
||
HLRZ D,(F) ;SPREAD OUT HIGH WORD AND
|
||
MOVE D,(D) ;NEXT-TO-HIGH WORD INTO TT,D
|
||
HRRZ TT,(F)
|
||
HLRZ TT,(TT)
|
||
MOVE TT,(TT)
|
||
ASHC TT,(R)
|
||
POPJ P,
|
||
|
||
IFN USELESS,[
|
||
2HAI: SUBI TT,(D)
|
||
JUMPLE TT,ABS
|
||
PUSHJ FXP,SAV3 ;COPY BIGNUM, BUT TOSS OUT LOW ORDER BITS
|
||
IDIVI TT,35. ;HOW MANY BITS TO THROW AWAY
|
||
MOVEI F,(A)
|
||
HRRZ F,(F)
|
||
SOJGE TT,.-1
|
||
MOVN C,D
|
||
SUBI D,35.
|
||
HLRZ TT,(F)
|
||
MOVE TT,(TT)
|
||
HRRZ F,(F) ;F IS CDR'ING DOWN INPUT
|
||
JUMPE F,2HAI0
|
||
HLRZ T,(F)
|
||
MOVE T,(T) ;C HOLDS AMNT TO SHIFT RIGHT BY
|
||
ASHC T,(C)
|
||
PUSHJ P,C1CONS
|
||
MOVEI B,(A)
|
||
2HAI2: MOVEI R,(A) ;R HAS PTR TO LAST OF FORMING LIST
|
||
HRRZ F,(F)
|
||
JUMPE F,2HAI3
|
||
ASHC T,(D) ;MOVE T INTO TT
|
||
HLRZ T,(F)
|
||
MOVE T,(T)
|
||
ASHC T,(C)
|
||
PUSHJ P,C1CONS
|
||
HRRM A,(R)
|
||
JRST 2HAI2
|
||
|
||
2HAI0: ASH TT,(C) ;DEFINITELY A BUG TO COME HERE,SINCE WE
|
||
JSP R,RSTR3
|
||
JRST FIX1 ;THINK WE ARE RETURNING A BIGNUM
|
||
|
||
2HAI3: JUMPE T,2HAI4
|
||
MOVE TT,T
|
||
PUSHJ P,C1CONS
|
||
HRRM A,(R)
|
||
2HAI4: MOVEI A,(B)
|
||
PUSHJ P,BGNMAK
|
||
POP P,C
|
||
JRST POP2J
|
||
] ;END OF IFN USELESS
|
||
|
||
|
||
;;; THE CODE FOR 3HAI IS PUTCODED.
|
||
|
||
|
||
IFN USELESS,[
|
||
|
||
SUBTTL GCD FOR BIGNUMS
|
||
|
||
GCDBG: MOVEI F,1 ;INITIALIZE SMALLNUM MATRIX
|
||
MOVEM F,GCD.A
|
||
MOVEM F,GCD.D
|
||
SETZM GCD.B
|
||
SETZM GCD.C
|
||
HLRZ R,(TT) ;GET LOW ORDER WDS OF ARGS
|
||
MOVE R,(R)
|
||
HLRZ F,(D)
|
||
MOVE T,R ;LOW WD OF U
|
||
IOR R,(F)
|
||
PUSH FXP,R
|
||
JUMPE R,GCDBG4 ;BOTH LOW WDS 0
|
||
MOVN R,R
|
||
ANDM R,(FXP) ;GRTST COMMON PWR OF 2 OR 0 IF > 2^35.
|
||
PUSH FXP,(F) ;LOW WD OF V.
|
||
JUMPN T,GCDBG0 ;IF T=0 AND (F) EVEN, XTRA PWR OF 2 WILL
|
||
EXCH A,B ; COME BACK FROM RECURSION, SO SWAP TO
|
||
EXCH TT,D ; UNZERO T, THUS GUARANTEEING RECURSION WITH
|
||
EXCH T,(FXP) ; AT LEAST 1 ODD ARG.
|
||
GCDBG0: MOVEI R,(TT) ;GET HI WDS IF SAME LENGTH.
|
||
MOVEI F,(D)
|
||
HRRZ D,(D)
|
||
HRRZ TT,(TT)
|
||
JUMPE D,GCDBG2
|
||
JUMPN TT,GCDBG0
|
||
EXCH A,B ;B IS LONGER THAN A
|
||
GCDBG1: SUB FXP,R70+2
|
||
PUSH P,B ;A IS LONGER THAN B
|
||
PUSHJ P,REMAINDER ;SO GCD(A,B) = GCD(REMAINDER(A,B),B)
|
||
POP P,B
|
||
JRST GCD
|
||
|
||
GCDBG2: JUMPN TT,GCDBG1 ;U,V UNEQUALLY LONG
|
||
HLRZ R,(R) ;U,V EQUALLY LONG,
|
||
HLRZ F,(F) ; GET ACTUAL HI WDS.
|
||
MOVE TT,(R)
|
||
MOVE D,(F)
|
||
POP FXP,R ;TT,D HAVE HI WDS (OR 0 AND NON0 IF UNEQUAL LENGTH)
|
||
MOVEI F,35. ;T,R HAVE LO WDS
|
||
MOVEM F,GCD.UH ;SHFT CTR
|
||
GCDBGU: TRNE T,1
|
||
JRST GCDBGV ;U IS ODD
|
||
GCDBHU: LSH T,-1
|
||
LSH D,1 ;TT RIGHT 1 REL TO D
|
||
JUMPGE D,.+3
|
||
LSH D,-1
|
||
LSH TT,-1
|
||
MOVE F,GCD.C ;HALVING A, B EQUIV TO DOUBLING C,D
|
||
ADDM F,GCD.C
|
||
MOVE F,GCD.D
|
||
ADDM F,GCD.D
|
||
SOSE GCD.UH
|
||
JRST GCDBGU
|
||
GCDBG4: PUSH P,A
|
||
PUSH P,B
|
||
MOVE TT,GCD.A
|
||
PUSHJ P,BNXTIM
|
||
PUSH P,A ;T <- A*U
|
||
MOVE A,-1(P)
|
||
MOVE TT,GCD.B
|
||
PUSHJ P,BNXTIM
|
||
POP P,B
|
||
PUSHJ P,.PLUS ;T <- T+B*V
|
||
PUSHJ P,BNLWFL
|
||
EXCH A,-1(P)
|
||
MOVE TT,GCD.C
|
||
PUSHJ P,BNXTIM
|
||
EXCH A,(P) ;W <- C*U
|
||
MOVE TT,GCD.D
|
||
PUSHJ P,BNXTIM
|
||
POP P,B
|
||
PUSHJ P,.PLUS ;W <- W+D*V
|
||
PUSHJ P,BNLWFL
|
||
POP P,B ;U <- T
|
||
POP FXP,TT
|
||
CAIN TT,1
|
||
JRST GCD
|
||
PUSH FXP,TT
|
||
PUSHJ P,GCD
|
||
MOVEI B,(FXP)
|
||
SKIPN (B)
|
||
MOVEI B,BN235 ;CAN ONLY HAPPEN WHEN BOTH LO WDS 0
|
||
PUSHJ P,.TIMES
|
||
SUB FXP,R70+1
|
||
POPJ P,
|
||
|
||
GCDBGV: TRNE R,1
|
||
JRST GCDBGO ;BOTH U,V ODD
|
||
GCDBHV: LSH R,-1
|
||
LSH TT,1
|
||
JUMPGE TT,.+3
|
||
LSH TT,-1
|
||
LSH D,-1
|
||
MOVE F,GCD.A
|
||
ADDM F,GCD.A
|
||
MOVE F,GCD.B
|
||
ADDM F,GCD.B
|
||
SOSE GCD.UH
|
||
JRST GCDBGV
|
||
JRST GCDBG4
|
||
|
||
BNLWFL: HRRZ B,(A) ;FLUSH LOW 35. ZEROS OF A
|
||
JUMPE B,BNLWXX
|
||
HRRZ B,(B)
|
||
HRRZ TT,(B) ;GCD only permitted to clobber A,B
|
||
JUMPE TT,BNLWFX ;IF BIGNUM BECOMES FIXNUM
|
||
HRRM B,(A)
|
||
POPJ P,
|
||
|
||
BNLWFX: HLRZ A,(B)
|
||
POPJ P,
|
||
|
||
BNLWXX: SKIPE (A)
|
||
MOVEI A,IN0-1
|
||
POPJ P,
|
||
|
||
GCDBGO: CAML TT,D
|
||
JRST GCDBGT
|
||
SUB D,TT
|
||
SUB R,T
|
||
MOVN F,GCD.A
|
||
ADDM F,GCD.C
|
||
MOVN F,GCD.B
|
||
ADDM F,GCD.D
|
||
JRST GCDBHV
|
||
|
||
GCDBGT: SUB TT,D
|
||
SUB T,R
|
||
MOVN F,GCD.C
|
||
ADDM F,GCD.A
|
||
MOVN F,GCD.D
|
||
ADDM F,GCD.B
|
||
JRST GCDBHU
|
||
|
||
|
||
GCDBX: SKIPN D,(B) ;FIXNUM IS ZERO - RETURN BIGNUM
|
||
JRST ABSBG0 ;MAYBE NEED TO TAKE ABS VALUE
|
||
CAMN D,[400000,,] ;CHECK FOR NASTY -400000000000 CASE
|
||
JRST GCDOV
|
||
PUSH P,B ;ELSE TAKE A REMAINDER
|
||
PUSHJ P,REMAINDER
|
||
POP P,B
|
||
JRST .GCD ;GUARANTEED TO HAVE TWO FIXNUMS NOW
|
||
|
||
GCDOV: MOVEI B,(A) ;HANDLE NASTY -400000000000 CASES
|
||
GCDOV1: PUSHJ P,ABSOV
|
||
JRST GCD
|
||
|
||
] ;END OF IFN USELESS
|
||
|
||
|
||
PGTOP BIG,[BIGNUM-ONLY ARITHMETICS]
|