Trailing-Edge
-
PDP-10 Archives
-
FORTRAN-10_V7wLink_Feb83
-
mthcpx.mac
There are 9 other files named mthcpx.mac in the archive. Click here to see a list.
SEARCH MTHPRM
TV MTHCPX COMPLEX ROUTINES ,7(3220)
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1981, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
SUBTTL REVISION HISTORY
COMMENT \
***** Begin Revision History *****
1351 EDS 16-Mar-81 Q10-04786
Fix TWOSEG and RELOC problems.
1405 DAW 6-Apr-81
Support extended addressing.
1464 DAW 12-May-81
Error messages.
1673 CDM 9-Sept-81
Added complex routines.
(CMPL.I, CMPL.C, CMPL.D)
***** Begin Mathlib *****
3024 CDM 17-Nov-81
Changed REAL. to REAL.C, defining REAL. to have integer
arguments as in ANSI-77 standard.
3200 JLC 10-May-82
Mathlib integration. Change all LERRs to $LCALLs. Change
TWOSEG/RELOC to SEGMENT macros.
3201 RVM 20-May-82
Add the routine CMPL.G (convert two gfloating numbers to
complex).
3217 JLC 8-Oct-82
Modify SIXBIT names of the complex multiply and divide routines
so that TRACE won't look for an argument block.
3220 PLB 12-Oct-82
Remove IFIWs from invocations of FUNCT macro, so that we
can put IFIW into the defn of FUNCT.
***** End Revision History *****
\
PRGEND
TITLE CABS COMPLEX ABSOLUTE VALUE FUNCTION
; (SINGLE PRECISION FLOATING POINT)
SUBTTL IMSL, INC. JUNE 1, 1979
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1979, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
SEARCH MTHPRM
NOSYM
ENTRY CABS
EXTERN CABS.
CABS=CABS.
PRGEND
TITLE CABS. COMPLEX ABSOLUTE VALUE FUNCTION
; (SINGLE PRECISION FLOATING POINT)
SUBTTL IMSL, INC. JUNE 1, 1979
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1979, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
;CABS(Z) IS CALCULATED AS FOLLOWS
; LET Z = X + I*Y
; V = MAX(ABS(X),ABS(Y))
; W = MIN(ABS(X),ABS(Y))
; THEN
; CABS = V*SQRT(1.0 + (W/V)**2)
;THE RANGE OF DEFINITION FOR CABS IS THE REPRESENTABLE REAL NUMBERS.
; AN OVERFLOW CAN OCCUR, IN WHICH CASE CABS = + MACHINE INFINITY.
;REQUIRED (CALLED) ROUTINES: SQRT
;REGISTER T2 WAS SAVED, USED, AND RESTORED
;THE ROUTINE HAS THE FOLLOWING CALLING SEQUENCE:
; XMOVEI L,ARG
; PUSHJ P,CABS
;THE ANSWER IS RETURNED IN ACCUMULATOR T0
SEARCH MTHPRM
SEGMENT CODE
SALL
HELLO (CABS,.) ;ENTRY TO MODULUS ROUTINE
PUSH P,T2
XMOVEI T2,@(L)
MOVM T0,(T2) ;ABS(X)
MOVM T2,1(T2) ;ABS(Y)
; OBTAIN MAX(ABS(X),ABS(Y))IN T2
; AND MIN IN T0
CAML T0,T2
EXCH T2,T0 ;THEN CALCULATE CABS
JUMPE T2,RET ;Z = 0, HENCE CABS = O
FDVR T0,T2 ;U/V
JFCL ANS ;NO OVERFLOW, RATIO NEGLIGIBLE IF UNDERFLOW
CAMG T0,TWOM14 ;IF RATIO .LE. 2**-14,
JRST ANS ;RATIO IS NEGLIGIBLE.
FMPR T0,T0 ;**2
FADRI T0,201400 ;+1.0
MOVEM T0,TEMP
FUNCT SQRT.,<TEMP> ;[3220] SQUARE ROOT IS IN AC T0
FMPR T0,T2 ;*V
JFCL OVFL ;NO UNDERFLOW, GET MESSAGE ON OVERFLOW
RET: POP P,T2
GOODBY (1) ;RETURN
OVFL: $LCALL ROV,RET
; LERR (LIB,%,<CABS: result overflow>,RET)
ANS: MOVE T0,T2 ;ANSWER = ABS(LARGER) TO T0
POP P,T2 ;RESTORE T2
GOODBY (1) ;RETURN
TWOM14: 163400000000 ;2**-14
SEGMENT DATA
TEMP: 0 ;TEMPORARY STORAGE USED FOR SQRT CALL
PRGEND
TITLE CEXP COMPLEX EXPONENTIAL FUNCTION
; (SINGLE PRECISION FLOATING POINT)
SUBTTL IMSL, INC. JUNE 1, 1979
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1979, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
SEARCH MTHPRM
NOSYM
ENTRY CEXP
EXTERN CEXP.
CEXP=CEXP.
PRGEND
TITLE CEXP. COMPLEX EXPONENTIAL FUNCTION
; (SINGLE PRECISION FLOATING POINT)
SUBTTL IMSL, INC. JUNE 1, 1979
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1979, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;CEXP(Z), WHERE Z = X + I*Y, IS CALCULATED AS FOLLOWS
; CEXP(Z) = EXP(X)*(COS(Y)+I*SIN(Y))
;THE RANGE OF DEFINITION FOR CEXP IS AS FOLLOWS
;FOR Z = X+I*Y, IF ABS(Y) .GT. 36394.429 THE RESULT IS SET TO
; (0.0,0.0) AND AN ERROR MESSAGE IS RETURNED.
;FOR X.LT.-89.415986 THE RESULT IS SET TO (0.0,0.0) AND AN ERROR
; MESSAGE IS RETURNED.
;FOR X .GT. 88.029692;
; IF Y = 0.0, THE RESULT IS SET TO (+INFINITY,0.0) AND AN
; ERROR MESSAGE IS RETURNED.
; IF X/2. IS .GT. 88.029692, THE ABS(REAL(RESULT)) IS SET TO
; +INFINITY AND ABS(AIMAG(RESULT)) IS SET TO +INFINITY AND
; AN ERROR MESSAGE IS RETURNED.
;REQUIRED (CALLED) ROUTINES: EXP,SIN,COS
;REGISTERS T2, T3, AND T4 WERE SAVED, USED, AND RESTORED
;THE ROUTINE HAS THE FOLLOWING CALLING SEQUENCE:
; MOVEI L,ARG
; PUSHJ P,CEXP
;THE REAL PART OF THE SOLUTION IS RETURNED IN ACCUMULATOR T0
;THE IMAG PART OF THE SOLUTION IS RETURNED IN ACCUMULATOR T1
SEARCH MTHPRM
SEGMENT CODE
SALL
HELLO (CEXP,.) ;ENTRY TO NAME ROUTINE
PUSH P,T2 ;SAVE REGISTER T2
PUSH P,T3 ;SAVE REGISTER T3
PUSH P,T4 ;SAVE REGISTER T4
XMOVEI T1,@(L) ;GET ADDRESS OF Z
MOVE T0,(T1) ;X=REAL(Z)
MOVE T1,1(T1) ;Y=IMAG(Z)
MOVEM T1,YSAVE ;SAVE Y
MOVM T1,T1 ;T1=ABS(T1)
CAMG T1,YMAX ;IF ABS(Y) IS NOT TOO LARGE
JRST YOK ;GO TO YOK
$LCALL AIZ
;LERR (LIB,%,<CEXP: AIMAG(arg) too large in absolute value; result=(0,0)>)
SETZ T0, ;REAL PART OF SOLUTION IS ZERO
SETZ T1, ;IMAG PART OF SOLUTION IS ZERO
JRST RET ;RETURN
YOK: MOVEM T0,XSAVE ;SAVE X
CAML T0,NEGCON ;IF X IS NOT TOO SMALL
JRST XOK ;GO TO XOK
SETZ T0, ;REAL PART OF SOLUTION IS ZERO
SETZ T1, ;IMAG PART OF SOLUTION IS ZERO
JRST YCHK ;CHECK Y
XOK: FUNCT COS.,<YSAVE> ;[3220] COSY=COS(Y)
MOVEM T0,COSY
FUNCT SIN.,<YSAVE> ;[3220] SINY=SIN(Y)
MOVEM T0,SINY
MOVE T2,XSAVE ;T2=X
MOVE T1,YSAVE ;T1=Y
CAMG T2,TBIG ;IF X IS NOT TOO LARGE
JRST ALG ;GO TO ALG
CAIN T1,0 ;ELSE, IF Y=0
JRST ERR0 ;GO TO ERR
FSC T2,-1 ;ELSE, S=X/2
CAMLE T2,TBIG ;IF S IS TOO LARGE
JRST STIM ;GO TO STIM
MOVEM T2,XSAVE
FUNCT EXP.,<XSAVE> ;T=EXP(S)
MOVE T1,T0
FMPR T1,SINY ;V=T*SINY
MOVM T1,T1 ;V=ABS(V)
HRLOI T4,377777 ;T4=XMAX
FDVR T4,T0 ;Q=XMAX/T
CAIG T1,T4 ;IF V IS LESS THAN OR EQUAL TO Q
JRST GETI ;GO TO GETI
STIM: HRLOI T1,377777 ;ELSE, SET IMAG SOLUTION TO XMAX
$LCALL IPO
;LERR (LIB,%,<CEXP: imaginary part overflow>)
JRST D2
GETI: FMPR T1,T0 ;IRES = V*T
D2: MOVE T4,SINY
CAIGE T4, ;IF SINY IS LESS THAN 0.0
MOVN T1,T1 ;THEN NEGATE IRES
CAMLE T2,TBIG ;IF S IS TOO LARGE
JRST ERR0 ;GO TO ERR
MOVE T2,T0
FMPR T0,COSY ;V = T*COSY
MOVM T0,T0 ;V = ABS(V)
HRLOI T3,377777 ;T3=XMAX
FDVR T3,T2 ;Q = XMAX/T
CAIG T0,T3 ;IF V IS LESS THAN OR EQUAL TO Q
JRST LAB ; THEN GO TO LAB
ERR0: HRLOI T0,377777 ;RRES=XMAX
$LCALL RPO
;LERR (LIB,%,<CEXP: real part overflow>)
JRST DD2
LAB: FMPR T0,T2 ;RRES = V*T
DD2: MOVE T2,COSY
CAIGE T2, ;IF COSY.LT. 0.0
MOVN T0,T0 ;THEN NEGATE RRES
JRST RET ;RETURN
ALG: MOVEM T2,XSAVE
FUNCT EXP.,<XSAVE> ;EXPX = EXP(X)
MOVEM T0,EXPX
MOVE T1,EXPX
FMPR T1,SINY ;IRES = EXPX*SINY
JFCL
FMPR T0,COSY ;RRES = EXPX*COSY
JFCL
CAIE T1, ;IF IRES .NE. 0.0
JRST RCHK ;THEN GO CHECK RRES
YCHK: MOVE T2,YSAVE
CAIN T2, ;IF Y .NE. 0
JRST RCHK ;THEN GO CHECK RRES
$LCALL IPU
;LERR (LIB,%,<CEXP: imaginary part underflow>)
RCHK: CAIN T0, ;IF R = 0.0
$LCALL RPU
;LERR (LIB,%,<CEXP: real part underflow>)
RET: POP P,T4
POP P,T3
POP P,T2
GOODBY (1) ;RETURN
YMAX: 36394.4290E0
TBIG: 207540074636 ;88.029692
NEGCON: 570232254037 ;-89.415986
SEGMENT DATA
SINY: 0
COSY: 0
XSAVE: 0
EXPX: 0
YSAVE: 0
PRGEND
TITLE CEXP2 COMPLEX ** INTEGER
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1981, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
SEARCH MTHPRM
NOSYM
ENTRY CEXP2
EXTERN CEXP2.
CEXP2=CEXP2.
PRGEND
TITLE CEXP3 COMPLEX ** COMPLEX
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1981, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
SEARCH MTHPRM
NOSYM
ENTRY CEXP3
EXTERN CEXP3.
CEXP3=CEXP3.
PRGEND
TITLE CEXP3. Complex ** complex exponenentiation
SUBTTL Mary Payne /MHP 29-May-81
; New Routine for CEXP3; Mary Payne, May 29, 1981.
;
;This routine calculates (X + iY)**(A + iB), where i is SQRT(-1).
SEARCH MTHPRM
SEGMENT CODE
SALL
HELLO (CEXP2,.) ;CEXP2, complex ** integer
MOVEM T2,SAVT2 ;Save registers T2
MOVEM T3,SAVT3 ; and T3
MOVEM T4,SAVT4 ; and T4
DMOVE T1,@(L) ;X and Y to T1 and T2.
MOVE T3,@1(L) ;N to T3.
PUSHJ P,DFL.3## ;T3 and T4 = DFLOAT(T3)
JRST CJOIN ;Join main routine
HELLO (CEXP3,.) ;CEXP3, complex ** complex
;
; *****************
; * BLOCK 1 *
; *****************
;
;Separate out the special cases: X = Y = 0 and A = B = 0:
MOVEM T2,SAVT2 ;Save Registers T2
MOVEM T3,SAVT3 ; and T3
MOVEM T4,SAVT4 ; and T4
DMOVE T1,@(L) ;X and Y to T1 and T2.
DMOVE T3,@1(L) ;A and B to T3 and T4.
CJOIN: JUMPN T1,NXTST ;If X not zero, continue
; with main flow below.
JUMPN T2,XIS0 ;Special case: X = 0, Y not.
; Treated in BLOCK 2 after
; its main flow is complete.
; >>>> Special Case: X = Y = 0 <<<<
;
;In the following block of code X = Y = 0. No detailed
;calculations are needed. If A > 0, both the real and
;imaginary parts of the result are zero. If A = 0
;the complex result has modulus one, and indeterminate
;direction, so both its real and imaginary parts should
;be identified as indeterminate. If A < 0, the complex
;result has modulus infinity, and indeterminate direction.
;The real and imaginary parts should probably be identified
;as indeterminate. A is in T3.
;
JUMPG T3,ZERO ;If A > 0, result is (0,0).
HRLOI T0,377777 ;Else results are indeterminate
HRLOI T1,377777 ;Provide something for storage
JUMPE T3,BTHIND ;If A = 0, results indeterminate.
$LCALL ZZZ ;zero**zero is indeterminate, result = zero
SETZB T0,T1 ;Return (0,0)
JRST RST234 ;Restore registers 2, 3, and 4.
BTHIND: $LCALL ZCI ;(0,0)**(negative,any) is indeterminate
JRST RST234 ;Restore registers 2, 3, and 4.
ZERO: SETZ T0, ;Result is (0,0). Clear T0.
; T1 already has 0.
JRST RST234 ;Restore registers 2, 3, and 4.
;
; >>>> End of X = Y = 0 <<<<
;
; >>>> Main Flow continues at NXTST <<<<
;
NXTST: JUMPN T3,POLAR ;If A and B are not both zero,
JUMPN T4,POLAR ; continue with main flow.
; in BLOCK 2.
;
; >>>> Special Case: A = B = 0 (X,Y not both 0) <<<<
;
MOVE T0,SPONE ;A = B = 0; X, Y not both zero
SETZ T1, ; so result is (1,0)
RST234: MOVE T2,SAVT2 ;Restore registers 2
MOVE T3,SAVT3 ; and 3
MOVE T4,SAVT4 ; and 4
POPJ P, ;and return.
;
; >>>> End of A = B = 0 <<<<
;
;End of BLOCK 1. The cases corresponding to X = Y = 0 and/or
;A = B = 0 are complete.
;
; *****************
; * BLOCK 2 *
; *****************
;
;In this block of code X and Y are not both zero. A and B
;are not used. (X + iY) is rewritten in the form
;EXP(CDLOG(X + iY)), and the CDLOG routine is invoked. The
;real part of CDLOG is stored in LNRHO, and its imaginary
;part in THETA. Either, but not both of, THETA and LNRHO
;can underflow, and code is inserted to return scaled values
;instead of zero for these cases. On entry to this block X
;and Y are in T1 and T2. T3 and T4, which contain A and B,
;are used here, but A and B will be recovered later, when
;they are needed,from REXP and IEXP, respectively.
;
POLAR: MOVEM T5,SAVT5 ;Save another register.
SETZ T5, ;Clear T5 for initialization
MOVEM T5,RSIGN ; of flags for signs of the
MOVEM T5,ISIGN ; real and imaginary parts
; of the final result.
MOVEM T5,PHIFLG ;Initialize flag for
; underflow of PHI.
DMOVEM T4,IEXP ;B is now zero extended.
; Store B in double precision.
SETZ T4, ;Zero extend A, and store
DMOVEM T3,REXP ; it in double precision.
MOVE T4,T1 ;Y in T2, copy X to T4
SETZ T3, ;Zero extend Y to double.
; Already done for X in T4,T5.
;
;Separate out cases leading to underflow of THETA and
;LNRHO, so as to calculate scaled values. All branches follow
;completion of the main flow for this BLOCK.
;
MOVE T0,T2 ;Copy of Y to T0.
FDV T0,T1 ;S.P. chopped DIV shows
JFCL EXCEP ; possible exceptions.
MOVM T0,T0 ;Test |Y/X|.
CAML T0,TWO63 ;If |Y/X| huge: |THETA| = PI/2.
JRST YMGTX ; Go to special cases.
CAMG T0,TWOM63 ;If |Y/X| tiny: |THETA| = 0 or
JRST XMGTY ; PI. Go to special cases.
;
;
DMOVEM T4,ARG1 ;Prepare to get CDLOG
DMOVEM T2,ARG1+2 ; of (X,Y). There will be
FUNCT CDLOG,<ARG1,LNRHO> ; no exceptions.
JRST PHI0 ;Go to BLOCK 3.0 for PHI. Neither
; THETA nor LNRHO is scaled.
;
;Main Flow for BLOCK 2 is complete. Now take care of the
;special cases.
;
EXCEP: JUMPN T0,YMGTX ;On overflow, |Y| >> |X|.
;
; >>>> Treatment of underflow on Y/X. <<<<
;
JUMPL T4,THETPI ;Underflow and X < 0: THETA is PI.
;Underflow implies |X| not 1.
;Also |X| >> |Y|; hence LNRHO
DMOVEM T4,LNARG ; is LN(|X|) which is not 0.
; X > 0, so |X| = X. Get
FUNCT DLOG.,<LNARG> ; LN(X) = LN(RHO)
DMOVEM T0,LNRHO ; and store it.
;
;Since Y/X underflows and X > 0
; Theta underflows. Get and
; store a scaled value.
FSC T2,150 ;Scale Y by 2**96 and X by
FSC T4,-150 ; 2**(-96). No exceptions on
DFDV T2,T4 ;Y/X scaled up by 2**192
DMOVEM T2,THETA ;Store scaled THETA.
JRST PHI1 ;Continue with main flow in
; BLOCK 3.2; THETA is scaled
; and LNRHO is not.
;
THETPI: DMOVE T0,PI ;Underflow on Y/X, and X < 0
JUMPGE T2,GETLN ;THETA is PI for Y > 0
DMOVN T0,T0 ; or -PI for Y < 0.
MOVN T2,T4 ; T2 <-- |X|.
JRST GETLN ;Go store THETA and get LNRHO.
;
; >>>> End of underflow on Y/X <<<<
;
; >>>> Treatment of very large |Y/X| <<<<
;
YMGTX: MOVM T1,T2 ;Get |Y|. If it is not 1, then
CAME T1,SPONE ; neither THETA nor LNRHO will
JRST XIS0 ; underflow; Merge with XIS0.
DMOVE T0,PIOV2 ;If |Y| = 1, LNRHO may underflow.
JUMPGE T2,THPOS ;THETA is PI/2
DMOVN T0,T0 ; or -PI/2 if Y < 0. |Y| = 1 so
THPOS: MOVE T2,T4 ;LNRHO = (X**2)/2. Get X in
JRST GETLOG ; T2 and T4. To GETLOG to store
; THETA and get scaled LNRHO.
;
; >>>> End of treatment of very large |Y/X| <<<<
;
; >>>> Treatment of |Y/X| very small; no underflow <<<<
;
XMGTY: JUMPGE T4,TINYTH ;If X > 0, THETA tiny but not 0.
MOVN T4,T4 ;If X < 0, change its sign.
DMOVE T0,PI ; THETA is PI
JUMPGE T2,ISX1 ; if Y > 0, or
DMOVN T0,T0 ; -PI, if Y < 0.
JRST ISX1 ;Go test whether |X| = 1.
;
TINYTH: DMOVE T0,T2 ;Get Y to T0,T1, and calculate
DFDV T0,T4 ; DP value for small THETA.
; No exceptions on DFDV.
;
ISX1: MOVM T2,T2 ;|Y| to T2.
CAMN T4,SPONE ;If |X| is 1, LNRHO may underflow.
JRST XIS1 ; Go find out.
DMOVEM T4,LNARG ;X not 1, so no underflow on LNRHO.
JRST STHETA ;Go store THETA and get LNRHO.
;
XIS1: MOVE T4,T2 ;THETA is not scaled.
JRST GETLOG ;Get LNRHO = (Y**2)/2.
;
; >>>> END of treatment for very small |Y/X| <<<<
;
; >>>> Special case X = 0 from BLOCK 1 <<<<
; >>>> Also branch from |Y/X| very large <<<<
;
XIS0: DMOVE T0,PIOV2 ;If X = 0, or |Y| >> |X|
MOVEM T3,REXP ;Store real part of exponent
MOVEM T4,IEXP ;Store imaginary part of exponent
SETZM PHIFLG ;Initialize flag for underflow of PHI
SETZM RSIGN ;Clear flags for signs of
SETZM ISIGN ; final result
JUMPGE T2,GETLN ;THETA is PI/2
DMOVN T0,T0 ; or -PI/2 if Y < 0.
MOVN T2,T2 ; T2 <-- |Y|. Now LN(RHO)
; will be LN(|Y|). Go store
; THETA and get LNRHO. No
; underflow on LNRHO because
; if X not 0, |Y| is not 1 and
; if X = 0, LN(|Y|) cannot underflow.
;
; >>>> End of special case X = 0 <<<<
; >>>> LNRHO from CALL to LOG routine <<<<
;
GETLN: DMOVEM T2,LNARG ;|X| not 1 and >> |Y|
; or |Y| not 1 and >> |X|
STHETA: DMOVEM T0,THETA ;Store THETA.
FUNCT DLOG.,<LNARG> ;Get LN of larger
DMOVEM T0,LNRHO ; and store it.
JRST PHI0 ;Continue with main flow in
; BLOCK 3.0; neither THETA
; not LNRHO is scaled.
;
; >>>> End of LNRHO by CALL to LOG routine <<<<
;
; >>>> LNRHO for RHO = 1 + (X**2 or Y**2) <<<<
;
GETLOG: DMOVEM T0,THETA ;Store unscaled THETA.
DFMP T4,T4 ;Get X**2 or Y**2. Copy of X or Y
JFCL LNUND ; in T2, in case of underflow.
FSC T4,-1 ;DIV by 2.
JFCL LNUND ; Underflow may occur.
DMOVEM T4,LNRHO ;Store unscaled LNRHO if no
; underflows occurred.
JRST PHI0 ;Continue with main flow in
; BLOCK 3.0; neither THETA
; not LNRHO is scaled.
;
LNUND: FSC T2,150 ;Scale up saved X or Y.
DFMP T2,T2 ;Square. No exceptions possible.
FSC T2,-1 ;DIV by 2. No exceptions possible.
DMOVEM T2,LNRHO ;Store scaled LNRHO
JRST PHI2 ;Rejoin main flow at BLOCK 3.1 with
; THETA unscaled, LNRHO scaled.
;
; >>>> End of LNRHO for RHO near 1 <<<<
;
;End of BLOCK 2. The CDLOG(X + iY) has real part LNRHO and
;imaginary part THETA, which are stored in locations with
;these names. If no exceptions occur, the main flow continues
;in BLOCK 3.0 at PHI0. No overflows occur. Either, but
;not both of THETA and LNRHO may underflow. For these
;cases values scaled up by 2**192 decimal, or 2**300
;octal, have been stored, and the main flow continues
;in BLOCK 3.2 at PHI1 for underflow of THETA, and in
;BLOCK 3.1 at PHI2 for underflow of LNRHO.
; *****************
; * BLOCK 3 *
; *****************
;
;The complex power function is to be evaluated as the
;complex exponential of (A + iB)*(LNRHO + iTHETA), which
;has real part ALPHA = A*LNRHO - B*THETA, and imaginary
;part PHI = A*THETA + B*LNRHO. The calculation of PHI is carried
;out in BLOCK 3. There are three sub-blocks 3.0, 3.2, and
;3.1 for the cases of no underflow, underflow of THETA and
;underflow of LNRHO, respectively.
;
;Since it is ultimately EXP(i*PHI) that is needed, it would
;appear that SIN and COS of PHI are the final parameters
;needed. However, these functions will get multiplied by
;EXP(ALPHA), and the handling of exception boundaries on
;the product will be expedited by using instead LN(SIN(PHI))
;and LN(COS(PHI)), which will be added to ALPHA before
;invoking the EXP function. Actually is is the absolute
;values of SIN and COS which will be used as arguments to
;the LN function; the signs of SIN and COS will be stored
;in flags for use in determining the signs for the real and
;imaginary parts of the complex exponential. Recall that these
;flags were initialized to zero at the beginning of BLOCK 2.
;
; *****************
; * BLOCK 3.0 *
; *****************
;
;Neither THETA nor LNRHO is scaled.
;
PHI0: DMOVE T0,LNRHO ;Get LNRHO and multiply
DFMP T0,IEXP ; by B.
JFCL PHI0A ; Branch on exception.
DMOVE T2,THETA ;Get THETA and multiply
DFMP T2,REXP ; by A.
JFCL PHI0B ; Branch on exception
DMOVE T4,T0 ;Get copy of B*LNRHO in case
; of exception on next step.
;
;Rejoin the main flow of BLOCK 3.0 here for underflows
; that do no harm. No exception on DFAD for such cases.
;
PHISUM: DFAD T0,T2 ;PHI = A*THETA + B*LNRHO.
JFCL PHI0C ; Branch on exception.
DMOVE T4,T0 ;Get copy of PHI and
JUMPGE T4,ABSARG ; test its sign.
DMOVN T4,T4 ; Get absolute value
ABSARG: CAMGE T4,ARGHI ;Test |PHI| against limit
JRST ARGOK ; for argument reduction
CAMG T4,ARGHI ; in SIN/COS routines.
CAML T5,ARGLO ; If >/= INT(PI*2**31)
JRST PHIBIG ; |PHI| is too big.
ARGOK: DMOVEM T0,TRGARG ;Else, store PHI.
FUNCT DSIN.,<TRGARG> ;Get SIN(PHI) and
DMOVEM T0,SPHI ; store for future use.
;
FUNCT DCOS.,<TRGARG> ;Get COS(PHI) and
DMOVEM T0,CPHI ; store for future use.
;
JRST ALF0 ;PHI calculation is complete.
;Go to BLOCK 4.0 for ALPHA.
;Main flow of BLOCK 3.0 is complete. Now take care of
;special cases.
;
; >>>> B*LNRHO and A*THETA OK; exception on sum <<<<
;
PHI0C: JUMPN T0,PHIBIG ;If overflow, PHI is too big.
DMOVE T0,T4 ;Get B*LNRHO back to T0.
FSC T0,300 ;Scale both B*LNRHO and A*THETA
FSC T2,300 ; up by 2**192.
JRST SCLPHI ;Join with other cases to
; get scaled PHI, etc.
;
; >>>> End of handling exception on sum <<<<
;
; >>>> B*LNRHO OK, exception on A*THETA <<<<
;
PHI0B: JUMPN T2,PHIBIG ;If overflow, PHI is too big.
MOVM T4,T0 ;Get |B*LNRHO|. If it is
CAML T4,TWOM66 ; > 2**(-66), underflow does
JRST PHISUM ; no harm. Go to main flow.
FSC T0,300 ;Else scale B*LNRHO up by 2**192
DMOVE T2,THETA ;Also get THETA and A and
DMOVE T4,REXP ; scale each up by 2**96
FSC T2,150 ; so that resulting product
FSC T4,150 ; has same scaling as B*LNRHO.
DFMP T2,T4 ;No exceptions on either the
JRST SCLPHI ; MUL or subsequent operations
; in getting scaled PHI, etc.
;
; >>>> End of B*LNRHO OK; exception on A*THETA <<<<
;
; >>>> Exception on B*LNRHO <<<<
;
PHI0A: JUMPN T0,PHIBIG ;If overflow, |PHI| too big.
DMOVE T2,THETA ;B*LNRHO underflows. Get
DFMP T2,REXP ; A*THETA before scaling.
JFCL PHI0D ;Branch on exception.
MOVM T4,T2 ;If |A*THETA| is big enough
CAML T4,TWOM66 ; main flow can be rejoined
JRST PHISUM ; with 0 for negligible B*LNRHO
FSC T2,300 ;Else scale A*THETA up by 2**192
JRST SCLBLN ; and go scale B*LNRHO
;
; >>>> End of exception on B*LNRHO <<<<
; >>>> Underflow on B*LNRHO and exception on A*THETA <<<<
;
PHI0D: JUMPN T2,PHIBIG ;If overflow, PHI is too big.
DMOVE T2,THETA ;Both products underflow. Get
DMOVE T4,REXP ;THETA and A and scale each
FSC T2,150 ; up by 2**96, so that product
FSC T4,150 ; will be scaled up by 2**192
DFMP T2,T4 ;No exception on product.
SCLBLN: DMOVE T0,LNRHO ;Get LNRHO and B and scale
DMOVE T4,IEXP ; each up by 2**96 so
FSC T0,150 ; that product will be
FSC T4,150 ; scaled up by 2**192.
DFMP T0,T4 ;No exception on product.
SCLPHI: DFAD T0,T2 ;No exception on sum.
HRLZI T5,400000 ;Set sign bit of T5.
MOVEM T5,PHIFLG ;Set PHIFLG to indicate
; underflow of PHI.
JUMPGE T0,PHIPL0 ;If scaled PHI < 0
MOVEM T5,ISIGN ; Use T5 to indicate that
; imaginary part is negative.
DMOVN T0,T0 ; Get |PHI| in T0.
PHIPL0: DMOVE T0,LNARG ;Store scaled |PHI|
FUNCT DLOG.,<LNARG> ; and get its LOG
DFAD T0,LN300 ; and add -192*LN(2) to
DMOVEM T0,SPHI ; get LN(SIN(|PHI|))
SETZ T0, ;Clear T0 and T1 in order to
SETZ T1, ; store 0 for LN(COS(|PHI|))
DMOVEM T0,CPHI ; Since COS(TINY) > 0
; real part will be > 0.
JRST ALF0 ;Continue with main flow
; at BLOCK 4.0.
; >>>> End of underflow on both products <<<<
; >>>> PHI is too large <<<<
;
PHIBIG: $LCALL BPI ;Both parts indeterminate
HRLOI T0,377777 ;Store biggest number in
MOVE T1,T0 ; both REAL and IMAG.
JRST RESTOR ;Go to end of BLOCK 6
; to restore registers.
;
;****If |PHI| is too large something should be stored
; in T0,T1, and an error message returned saying that
; neither the real nor the imaginary parts of the
; result are determinate. If |PHI| > int (2**31 * pi), the
; argument reduction for SIN and COS breaks down.
;
;End of BLOCK 3.0. Calculation continues at BLOCK 4.0,
;which also applies to the case in which neither LNRHO
;nor THETA underflows. At this point SPHI contains SIN(PHI)
;or, if PHI underflows, LN(SIN(|PHI|)) = LN(|PHI|). CPHI
;contains COS(PHI) or, if PHI underflows, LN(COS(|PHI|)) = 0.
;If PHI underflows, RSIGN and ISIGN contain the signs of the
;real and imaginary parts of the final result, respectively.
;PHIFLG has 0 or 1 in its sign bit, according as PHI has not
;or has underflowed.
;
; *****************
; * BLOCK 3.1 *
; *****************
;
;LNRHO is scaled up by 2**192. THETA is not scaled. The
;following transformation makes it possible to use the code
;in BLOCK 3.2 for this case also.
;
PHI2: HRLZI T0,400000 ;Must exchange LNRHO,THETA
MOVE T0,XCHFLG ; and A,B. Set sign bit of
; XCHFLG to indicate that
; this has been done.
DMOVE T0,LNRHO ;Get LNRHO
DMOVE T2,THETA ; and THETA
DMOVEM T0,THETA ; and exchange
DMOVEM T2,LNRHO ; them.
MOVE T0,REXP ;Get A
MOVE T2,IEXP ; and B
MOVEM T0,IEXP ; and exchange
MOVEM T2,REXP ; them.
;
;Continue at PHI1 in BLOCK 3.2, which will now carry out
;the PHI calculation correctly for this case.
;
; *****************
; * BLOCK 3.2 *
; *****************
;
;THETA is scaled up by 2**192. LNRHO is not scaled.
;
;However, the same code is used for LNRHO scaled and THETA
;not scaled on JRST from BLOCK 3.1. For this case read
;THETA for LNRHO, LNRHO for THETA, IEXP for REXP and REXP
;for IEXP throughout.
;
PHI1: DMOVE T0,LNRHO ;Get LNRHO and multiply
DFMP T0,IEXP ; by B.
JFCL PHI1A ; Branch on exception.
DMOVE T2,THETA ;Get THETA and multiply
DFMP T2,REXP ; by A.
JFCL PHI1B ; Branch on exception.
DMOVE T4,T2 ;Save copy of A*THETA
FSC T2,-300 ;Try to unscale A*THETA.
JFCL T2,PHI1C ; On failure, branch.
DMOVE T4,T0 ;Save copy of B*LNRHO.
DFAD T0,T2 ;PHI = A*THETA + B*LNRHO.
JFCL PHI1D ; Branch on exception.
;
;Rejoin the main flow of BLOCK 3.2 here for underflows
; that do no harm. PHI is unscaled and ready for final
; processing.
;
PHIOK1: DMOVE T4,T0 ;Get copy of PHI and
JUMPGE T4,ABARG1 ; test its sign.
DMOVN T4,T4 ; Get absolute value
ABARG1: CAMGE T4,ARGHI ;Test |PHI| against limit
JRST ARGOK1 ; for argument reduction
CAMG T4,ARGHI ; in SIN/COS routines.
CAML T5,ARGLO ; If >/= INT(PI*2**31)
JRST PHIBIG ; |PHI| is too big.
ARGOK1: DMOVEM T0,TRGARG ;Store unscaled PHI
FUNCT DSIN.,<TRGARG> ;Get its SIN
DMOVEM T0,SPHI ; and store it.
FUNCT DCOS.,<TRGARG> ;Get COS(PHI)
DMOVEM T0,CPHI ; and store it.
JRST ALF1 ;PHI calculation is complete.
;Go to BLOCK 4.1 for ALPHA.
;Main Flow of BLOCK 3.2 is complete. Now take care of
;special cases.
;
; >>>> B*LNRHO OK, unscaled A*THETA OK <<<<
;
; >>>> Exception on their sum <<<<
;There was no exception on A*(scaled THETA). Hence the unscaled
;product < 2**(-100), hence sum could not overflow, hence sum
;underflowed. T4 has unscaled B*LNRHO and T2 has scaled A*THETA.
;
PHI1D: DMOVE T0,T4 ;Get B*LNRHO to T0
FSC T0,300 ;Scale it up by 2**192.
FSC T2,300 ;Rescale A*THETA
DFAD T0,T2 ;No exceptions on scaled PHI.
JRST SCPHI1 ;Go finish up for scaled PHI.
;
; >>>> End of exception on sum of unscaled products <<<<
;
; >>>> B*LNRHO OK, A*(scaled THETA) OK <<<<
; >>>> Unscaled A*THETA underflows <<<<
;T0 has B*LNRHO and T4 has A*(scaled THETA).
;
PHI1C: MOVM T2,T0 ;Get |B*LNRHO| in T2
CAML T2,TWOM66 ;If it is big enough
JRST PHIOK1 ; underflow of A*THETA is
; harmless: A*THETA is
; negligible. Rejoin main
; flow at PHIOK1 above.
DMOVE T2,T4 ;A*(Scaled THETA) back to T2.
JRST SCBLN1 ;Go scale B*LNRHO up and
; add to A*(scaled THETA)
; in T2 to get scaled PHI.
;
; >>>> End of small B*LNRHO + underflowed A*THETA <<<<
;
; >>>> B*LNRHO OK, exception on A*(scaled THETA) <<<<
;
PHI1B: JUMPE T2,PHIOK1 ;A*(scaled THETA) underflows,
; hence A*THETA is negligible.
; Rejoin main flow at PHIOK1 above.
JRST REMOV1 ;Overflow on A*(scaled THETA) can
; be removed by unscaling product.
;
; >>>> End of B*LNRHO OK, exception on A*(scaled THETA) <<<<
; >>>> Exception on B*LNRHO <<<<
;
PHI1A: JUMPN T0,PHIBIG ;If overflow, PHI is too big.
DMOVE T2,THETA ;B*LNRHO underflows. Get
DFMP T2,REXP ; THETA and multiply by A.
JFCL PHI1E ; Branch on exception.
JRST SCBLN1 ;Go scale B*LNRHO up and add
; to scaled A*THETA in T2 to
; get scaled PHI.
;
PHI1E: JUMPE T2,SCBLN1 ;B*LNRHO and A*(scaled THETA)
; both underflow. A*THETA is
; negligible. Go scale B*LNRHO
; to get scaled PHI, with 0 in
; T2 for negligible A*THETA.
;
;If A*(scaled THETA) overflows, removal of scaling brings
;unscaled |A*THETA| into range between 2**(-100) to 2**100.
;Hence underflowed B*LNRHO is negligible. Code in REMOV1
;will add in 0 (for negligible B*LNRHO) to unscaled A*THETA
;to get unscaled PHI.
;
;Branch from PHI1B to remove overflow from A*(scaled THETA)
;joins here, with B*LNRHO OK and in T0 to be added to
;unscaled A*THETA.
;
REMOV1: DMOVE T2,THETA ;Overflow can be removed by
DMOVE T4,REXP ; scaling THETA and A down by
FSC T2,-150 ; 2**(-96) each, to get
FSC T4,-150 ; unscaled product.
DFMP T2,T4 ;No exceptions.
DFAD T0,T2 ;No exceptions since |A*THETA| is
; between 2**(-100) and 2**100
JRST PHIOK1 ;Rejoin main flow at PHIOK1 to get
; SIN and COS of unscaled PHI.
;
; >>>> End handling exception on B*LNRHO <<<<
;
; >>>> Completion of calculation for scaled PHI <<<<
;
SCBLN1: DMOVE T0,LNRHO ;Get LNRHO and B and
DMOVE T4,IEXP ; scale each up by 2**96
FSC T4,150 ; so as to get product
FSC T4,150 ; scaled up by 2**192.
DFMP T0,T4 ;No exception on product or
DFAD T0,T2 ; on ADD to scaled A*THETA.
;
;T0 now has scaled PHI. Branches from other special cases
;join in here to get signs of the final real and
;imaginary parts, LN(SIN(|PHI|)) and LN(COS(|PHI|)).
;
SCPHI1: HRLZI T4,400000 ;Set sign bit of T4
MOVEM T4,PHIFLG ;Set flag for PHI scaled.
JUMPGE T0,PHIPL1 ;If scaled PHI is negative
DMOVN T0,T0 ; get |scaled PHI| in T0.
MOVEM T4,ISIGN ; Imaginary part negative.
PHIPL1: DMOVEM T0,LNARG ;Store scaled PHI
FUNCT DLOG.,<LNARG> ; and get its LOG.
DFAD T0,LN300 ; and subtract 192*LN(2).
DMOVEM T0,SPHI ;SPHI gets LN(|PHI|) which
; = LN(SIN(|PHI|)).
SETZ T2, ;Clear T2 and T3 so as to
SETZ T3, ; store 0 for LN(COS|PHI|))
DMOVEM T2,CPHI ; since COS(TINY) = 1. Real
; part of result is positive.
JRST ALF1 ;Now go get ALPHA for LNRHO
; unscaled, THETA scaled.
;
; >>>> End of calculation for scaled PHI <<<<
;
;End of BLOCK 3.2. All paths lead either to the error return
;PHIBIG or to ALF1 for the calculation of ALPHA for the case
;LNRHO unscaled and THETA scaled up by 2**192. If PHI is
;unscaled, PHIFLG is clear and SPHI and CPHI contain SIN(PHI)
;and COS(PHI), respectively. IF PHI is scaled, SPHI contains
;LN(SIN(|PHI|)), CPHI contains LN(COS(|PHI|)) = 0, PHIFLG
;has its sign bit set, and RSIGN and ISIGN contain the signs
;of the real and imaginary parts of the final result.
;
; *****************
; * BLOCK 4 *
; *****************
;
;The real and imaginary parts of the final answer are
;given by EXP(ALPHA) times COS(PHI) and SIN(PHI),
;respectively. ALPHA = A*LNRHO - B*THETA is calculated
;in BLOCK 4.0 for no scaling of THETA or LNRHO. It is
;calculated in BLOCK 4.1 otherwise. It can be shown that
;if ALPHA overflows, neither the SIN nor the COS of PHI
;can underflow sufficiently to bring EXP(ALPHA) back into
;range. If ALPHA overflows and is positive both parts
;of the result overflow: Code providing a message and
;signed largest numbers for the real and imaginary parts
;is given in EXPOV at the end of BLOCK 4.1. The signs of
;the largest numbers are determined by COS(PHI) and SIN(PHI),
;respectively. If ALPHA overflows and is negative, EXP(ALPHA)
;underflows. The code providing a message and returning 0 for
;both parts is deferred to BLOCK 5, in which similar cases
;occur.
;
; *****************
; * BLOCK 4.0 *
; *****************
;
;Neither THETA nor LNRHO is scaled. ALPHA = A*LNRHO - B*THETA.
;
ALF0: DMOVE T0,LNRHO ;Get LNRHO and multiply
DFMP T0,REXP ; by A.
JFCL ALF0A ; Branch on exception.
DMOVE T2,THETA ;Get THETA and multiply
DFMP T2,IEXP ; by B.
JFCL ALF0B ; Branch on exception
DFSB T0,T2 ;ALPHA = A*LNRHO - B*THETA.
JFCL ALF0C ; Branch on exception.
DMOVEM T0,ALPHA ;Store ALPHA for future use.
;
JRST ANS0 ;Calculation of ALPHA complete.
;Go to BLOCK 5.0 for final answer.
;
;Main flow of BLOCK 4.0 is complete. Now take care of
;special cases.
;
; >>>> A*LNRHO and B*THETA OK; exception on difference <<<<
;
ALF0C: JUMPN T0,DIFFOV ;Exception on final results.
DMOVEM T0,ALPHA ;Zero is acceptable if
; ALPHA underflows.
JRST ANS0 ;Calculation of ALPHA complete.
;Go to BLOCK 5.0 for final answer.
;
DIFFOV: JUMPL T2,EXPOV ;Overflow with negative B*THETA
; means overflow on final results.
JRST EXPUND ;Underflow on final results
; for B*THETA positive.
;
; >>>> End of handling exception on difference <<<<
;
; >>>> Exception on A*LNRHO <<<<
;
ALF0A: JUMPN T0,ALNOV ;Exception on final reaults.
DMOVE T2,THETA ;A*LNRHO underflows. Get
DFMP T2,REXP ; B*THETA.
JFCL ALF0B ;Branch on exception.
DMOVN T2,T2 ;Underflow on A*LNRHO means it
DMOVEM T2,ALPHA ; is negligible. ALPHA = -B*THETA.
JRST ANS0 ;Go to BLOCK 5 for final answer.
;
ALNOV: DMOVE T2,THETA ;A*LNRHO overflows. What about
DFMP T2,IEXP ; B*THETA?
JFCL BOTHEX ; On exception to BOTHEX.
JRST ALNOV1 ;A*LNRHO overflows, B*THETA doesn't.
;
;A*LNRHO overflows and B*THETA has exception.
;
BOTHEX: JUMPE T2,ALNOV1 ;B*THETA underflows.
DMOVE T0,LNRHO ;Both products overflow.
DMOVE T2,REXP ; Get A and LNRHO and scale
FSC T0,-150 ; each down to get scaled
FSC T2,-150 ; A*LNRHO.
DFMP T0,T2 ;No exception
DMOVE T2,THETA ;Get B and THETA
DMOVE T4,IEXP ; and scale each down
FSC T2,-150 ; so get B*THETA
FSC T4,-150 ; scaled like B*LNRHO
DFMP T2,T4 ;No exception.
DFSB T0,T2 ;No exception on scaled ALPHA.
JUMPL T0,EXPUND ;Results underflow if ALPHA < 0.
JRST EXPOV ;Results overflow if ALPHA > 0.
;
;End of overflow on both A*LNRHO and B*THETA.
;
;A*LNRHO overflows, B*THETA does not. Sign of ALPHA is
;determined by sign of A*LNRHO. Neither A nor LNRHO is 0.
;
;NOTE: A similar case from BLOCK 4.1 joins in here.
;
ALNOV1: SKIPL T0,LNRHO ;If LNRHO > 0
JRST LNPOS ; go test B.
SKIPL T0,REXP ;LNRHO < 0. If A
JRST ALNNEG ; > 0, A*LNRHO < 0.
JRST ALNPOS ;Else A*LNRHO > 0.
LNPOS: SKIPL T0,REXP ;LNRHO > 0. If A
JRST ALNPOS ; > 0, A*LNRHO > 0.
ALNNEG: JRST EXPUND ;A*LNRHO < 0 means
; final results underflow.
ALNPOS: JRST EXPOV ;A*LNRHO > 0 means
; final results overflow.
;
; >>>> End of exception on A*LNRHO <<<<
;
; >>>> A*LNRHO OK or underflows, exception on B*THETA <<<<
;
ALF0B: JUMPN T2,BTHOV ;Exception on final results.
DMOVEM T0,ALPHA ;Underflow on B*THETA means it
; is negligible. ALPHA = A*LNRHO.
; Note that if A*LNRHO underflows
; it is also negligible and 0 is
; an acceptable result for ALPHA.
JRST ANS0 ;Go to BLOCK 5 for final answer.
;
;On overflow of B*THETA, neither B nor THETA is 0. A*LNRHO OK
;or underflows so sign of ALPHA is negative of sign
;of overflowed B*THETA.
;
BTHOV: SKIPL T0,THETA ;If THETA > 0
JRST THPOS1 ; go test B.
SKIPL T0,IEXP ;THETA < 0. If B
JRST BTHNEG ; > 0, B*THETA < 0.
JRST BTHPOS ;Else B*THETA > 0.
THPOS1: SKIPL T0,IEXP ;THETA > 0. If B
JRST BTHPOS ; > 0, B*THETA > 0.
BTHNEG: JRST EXPOV ;B*THETA < 0 means -B*THETA > 0,
; so final results overflow.
BTHPOS: JRST EXPUND ;B*THETA > 0 means -B*THETA < 0,
; so final results underflow.
;
; >>>> End of A*LNRHO OK; exception on B*THETA <<<<
;
;End of BLOCK 4.0. All paths lead to EXPOV, at the end
;of BLOCK 4.1 or to ANS0 or EXPUND, both in BLOCK 5.
;
; *****************
; * BLOCK 4.1 *
; *****************
;
;If PHIFLG = 0, THETA is scaled up by 2**192 and LNRHO is not
;scaled. If PHIFLG < 0,LNRHO is scaled up by 2**192, and THETA
;is not scaled.
;
;The code, as written, applies to PHIFLG = 0.
;
;For PHIFLG < 0, read THETA for LNRHO, LNRHO for THETA, (-IEXP)
;for REXP and (-REXP) for IEXP throughout.
;
ALF1: SKIPL PHIFLG ;If PHIFLG set,
JRST ALF2 ; to code for THETA scaled.
MOVN T0,REXP ;Else, exchange already done
MOVEM T0,REXP ; for THETA,LNRHO and A,B.
MOVN T0,IEXP ; Negate exchanged A,B to use
MOVEM T0,IEXP ; the code for scaled LNRHO,
; instead of scaled THETA.
;
ALF2: DMOVE T0,LNRHO ;Get LNRHO and multiply
DFMP T0,REXP ; by A.
JFCL ALF2A ; Branch on exception.
DMOVE T2,THETA ;Get THETA and multiply
DFMP T2,IEXP ; by B.
JFCL ALF2B ; Branch on exception
DMOVE T4,T2 ;Save a copy of B*THETA
FSC T2,-300 ; and try to remove scaling.
JFCL STALF ; Didn't work: B*THETA
; underflows and hence is
; negligible. ALPHA is
; A*LNRHO in To.
DFSB T0,T2 ;Neither product has an exception.
;ALPHA = A*LNRHO - B*THETA.
JFCL ALF2C ; Branch on exception.
STALF: DMOVEM T0,ALPHA ;Store ALPHA for future use.
JRST ANS0 ;Calculation of ALPHA complete.
;Go to BLOCK 5.0 for final answer.
;
;
;Main flow of BLOCK 4.1 is complete. Now take care of
;special cases.
;
; >>>> A*LNRHO and B*THETA OK, exception on difference <<<<
;
ALF2C: JUMPE T0,STALF1 ;On underflow 0 OK for ALPHA.
JUMPL T2,EXPOV ;On overflow ALPHA has sign
JRST EXPUND ; opposite to B*THETA. Hence
; results overflow for T2 < 0
; and underflow for T2 > 0.
;
; >>>> End of exception on difference <<<<
;
; >>>> Exception on A*LNRHO <<<<
;
ALF2A: JUMPN T0,ALNOV1 ;A*LNRHO overflows, B*THETA
; will be negligible. Final
; results will overflow
; or underflow. Go merge with
; similar case in BLOCK 4.0.
DMOVE T2,THETA ;A*LNRHO underflows and is
DFMP T2,IEXP ; negligible. Get B*(scaled
JFCL ALF2D ; THETA). Branch on exception.
FSC T2,-300 ;Try to unscale B*THETA.
JFCL ; Failed: B*THETA underflows too.
; Hence 0 is acceptable for ALPHA.
STALF1: DMOVEM T0,ALPHA ;Store 0 for ALPHA and go to
JRST ANS0 ; BLOCK 5 for final answer.
;
;Exception on B*(scaled THETA); A*LNRHO underflows.
;
ALF2D: JUMPN T2,REMOV2 ;Go unscale overflowed
; B*(scaled THETA). Negligible
; A*LNRHO stored as 0 in T0.
DMOVEM T0,ALPHA ;Both products underflow so
JRST ANS0 ; 0 is acceptable for ALPHA
; To BLOCK 5 for final answer.
;
; >>>> End of Exception on A*LNRHO <<<<
;
; >>>> A*LNRHO OK, exception on B*(scaled THETA) <<<<
;
ALF2B: JUMPN T2,REMOV2 ;Overflow: unscale A*THETa.
DMOVEM T0,ALPHA ;Underflow: A*THETA negligible.
; ALPHA = A*LNRHO (or 0 if
; here from ALF2C).
JRST ANS0 ;ALPHA done. Go to BLOCK 5.
;
REMOV2: DMOVE T2,THETA ;Get scaled THETA and B
DMOVE T4,IEXP ; and scale each down by
FSC T2,-150 ; 2**-96 to remove scaling
FSC T4,-150 ; from product.
DFMP T2,T4 ;|B*THETA| in 2**(-100) to 2**100
DFSB T0,T2 ; so no exception on DFSB.
DMOVEM T0,ALPHA ;Store ALPHA and go to
JRST ANS0 ; to get final answer.
;
; >>>> End of exception on A*(scaled THETA) <<<<
;
; >>>> Overflow of EXP(ALPHA) <<<<
;
EXPOV: HRLOI T0,377777 ;Get biggest number in T0.
SKIPN T0,PHIFLG ;If PHI underflowed get
JRST EXPOV1 ; signs from ISIGN and RSIGN.
DMOVE T2,SPHI ;Get SIN(PHI)
JUMPN T2,EXPOV2 ;If SIN(PHI) is not 0
JUMPN T3,EXPOV2 ; both parts overflow.
SETZ T1, ;If SIN(PHI) = 0, so does
; imaginary part. Real part
SKIPGE T0,CPHI ; overflows. If COS(PHI) < 0
MOVN T0,T0 ; real part is negative.
$LCALL RPO ;Real part overflow
JRST RESTOR ;Go restore registers and exit.
;
EXPOV2: MOVE T1,T0 ;Get Biggest in T1 too.
SKIPGE T0,CPHI ;If COS(PHI) < 0, so
MOVN T0,T0 ; is real part.
SKIPGE T0,SPHI ;If SIN(PHI) < 0, so
MOVN T1,T1 ; so is imaginary part.
JRST ERRMSG ;Go get error message.
;
EXPOV1: MOVE T1,T0 ;Get Biggest in T1 too.
SKIPGE T0,RSIGN ;If real part is negative
MOVN T0,T0 ; negate biggest number.
SKIPGE T0,ISIGN ;If imaginary part is negative
MOVN T1,T1 ; negate biggest number.
ERRMSG: $LCALL BPO ;Both parts overflow
JRST RESTOR ;Go restore registers and exit.
;
;RESTOR for restoring registers is at the end of BLOCK 5.
;
; >>>> End of overflow of EXP(ALPHA) <<<<
;
;End of BLOCK 4.1. All paths lead to ANS0 or EXPUND, both
;in BLOCK 5, or to RESTOR at the end of BLOCK 6.
; *****************
; * BLOCK 5 *
; *****************
;
;The main flow for this BLOCK starts at ANS0. If PHIFLG
;is 0, SPHI and CPHI contain SIN(PHI) and COS(PHI). PHI
;did not underflow. ALPHA is in ALPHA; no tests on its size
;have yet been made. The special cases, including PHIFLG = 1
;start at ANS1, following completion of the main flow.
;
ANS0: DMOVE T0,ALPHA ;Get ALPHA. Will EXP(ALPHA)
CAMLE T0,AMINHI ; underflow? If ALFHI > AMINHI
JRST EXPOK ; EXP(ALPHA) won't underflow.
CAML T0,AMINHI ;If ALFHI < AMINHI, EXP(ALPHA)
; underflows, and so do both
; parts of answer.
CAMLE T1,AMINLO ;ALFHI = AMINHI; test LO's
JRST EXPUND ; ALFLO </= AMINLO: underflow.
EXPOK: SKIPGE T0,PHIFLG ;Was PHI scaled? If so
JRST ANS2 ; go to alternate code.
CAML T0,AMAXHI ;If ALFHI >/= AMAXHI
JRST ANS1 ; use LOG approach.
FUNCT DEXP.,<ALPHA> ;No exception on EXP(ALPHA).
DMOVE T2,T0 ;Keep copy of EXP(ALPHA)
DFMP T0,SPHI ;Get imaginary part; no overflow
JFCL IMUND ; get message on underflow.
STIMP: DMOVEM T0,IMAG ;Store imaginary part.
DFMP T2,CPHI ;Get real part, no overflow
JFCL RLUND ; get message on underflow
STRLP: DMOVEM T2,REAL ;Store real part.
JRST DPTOSP ;Go convert to single precision.
; in BLOCK 6. Main Flow of
; BLOCK 5 complete.
;
; >>>> Underflow on MUL by SIN(PHI) <<<<
;
IMUND: $LCALL IPU ;Imaginary part underflow
JRST STIMP ;Rejoin main flow above.
;
; >>>> End of underflow on MUL by SIN(PHI) <<<<
;
; >>>> Underflow on MUL by COS(PHI) <<<<
;
RLUND: $LCALL RPU ;Real part underflow
JRST STRLP ;Rejoin main flow above.
;
; >>>> End of underflow on MUL by COS(PHI) <<<<
;
; >>>> Underflow on EXP(ALPHA) <<<<
;
;Multiplication by SIN(PHI) and COS(PHI) can only aggravate
;the underflow of EXP(ALPHA). Hence both real and imaginary
;parts underflow.
;
;NOTE: Other cases for underflow of EXP(ALPHA) from
;BLOCK 4 join here.
;
EXPUND: ;Write a message saying that EXP(ALPHA) underflows
;and hence both parts of answer also underflow.
$LCALL BPU ;Both parts underflow
SETZ T0, ;Store zero for real part.
SETZ T1, ;Store zero for imaginary part.
JRST RESTOR ;Go to end of BLOCK 6 and
; restore registers 2 through 5.
;
; >>>> End of underflow on EXP(ALPHA) <<<<
;
; >>>> Overflow on EXP(ALPHA) <<<<
;
;On entry to the following code, SPHI and CPHI contain
;SIN and COS of PHI. Multiplication by SIN and/or COS
;might compensate the overflow expected on EXP(ALPHA).
;Hence get LN(SIN(|PHI|)) and LN(|COS(PHI)|) and set the
;sign flags for the real and imaginary parts of the
;results. Then merge at ANS2 with the case for underflow
;of PHI (PHIFLG = 1), where this has already been done, to
;complete the calculation.
;
ANS1: SKIPL T2,SPHI ;Get SPHI, and if >/= 0
JRST PLUSI ; no changes needed.
MOVSI T5,400000 ;Set sign bit of T5
MOVEM ISIGN ; and copy to ISIGN.
DMOVN T2,T2 ;Get |SIN(PHI)|
PLUSI: DMOVEM LNARG ; and copy to memory.
FUNCT DLOG.,<LNARG> ;Get LN(|SIN(PHI)|)
DMOVEM T0,SPHI ; and store in SPHI.
;
SKIPL T2,CPHI ;Get CPHI, and if >/= 0
JRST PLUSR ; no changes needed.
MOVSI T5,400000 ;Else set sign bit of T5
MOVEM RSIGN ; and copy to RSIGN.
DMOVN CPHI ;Get |COS(PHI)|)
PLUSR: DMOVEM LNARG ; and copy to memory.
FUNCT DLOG.,<LNARG> ;Get LN(|COS(PHI)|)
DMOVEM T0,CPHI ; and store in CPHI.
;
; >>>> End of overflow on EXP(ALPHA) <<<<
;
; >>>> Code for PHIFLG negative <<<<
;
;The code for ANS1 merges here. SPHI and CPHI contain,
;respectively, LN(SIN(|PHI|)) and LN(|COS(PHI)|). ISIGN
;and RSIGN contain the signs for the imaginary and real
;parts, and ALPHA contains ALPHA, which has already had
;the case for underflow of EXP(ALPHA) separated out. No
;test for overflow has yet been made. However, the
;magnitudes of the real and imaginary parts will be
;calculated as
;
; EXP(ALPHA + SPHI) and EXP(ALPHA + CPHI)
;
;respectively. Tests for overflow on EXP will be postponed
;until after ALPHA + SPHI and ALPHA + CPHI are calculated.
;
; >>>> Calculate EXP(ALPHA + SPHI) <<<<
;
ANS2: DMOVE T0,ALPHA ;Get ALPHA and make
DMOVE T2,ALPHA ; a copy.
DFAD T0,SPHI ;Add in SPHI. On exception
JFCL IMEX ; branch to special case.
CAMGE T0,AMAXHI ;If T0 is not too big,
JRST NOVIM ; no overflow on imag. part.
CAMG T0,AMAXHI ;If T0 > AMAXHI, overflow
; on imaginary part.
CAML T1,AMAXLO ;T0 = AMAXHI. Test LO's.
JRST IMOV ; Overflow for T1 >/= AMAXLO.
NOVIM: CAMLE T0,AMINHI ;Next test for EXP underflow:
JRST IMOK ; If T0 > AMINHI, no underflow.
CAML T0,AMINHI ;If T0 </= AMINHI, EXP will
; underflow, and also imag. part.
CAMG T1,AMINLO ;T0 = AMINHI. If T1 </= AMINLO
JRST IMUND1 ; imaginary part underflows.
IMOK: DMOVE T0,EXPARG ;Copy argument for EXP
FUNCT DEXP.,<EXPARG> ; and invoke EXP function.
STIMP1: SKIPGE T0,ISIGN ;No exceptions. If ISIGN < 0
DMOVN T0,T0 ; so is imaginary part.
DMOVEM T0, IMAG ;Store imaginary part.
JRST ANS3 ;Now get real part
;
; >>>> End of main flow for EXP(ALPHA + SPHI) <<<<
;
; >>>> Exceptions on EXP(ALPHA + SPHI) <<<<
;
IMEX: JUMPE T0,IMAG1 ;Underflow on sum: |imag. part| = 1.
JUMPL T2,IMUND1 ;On overflow ALPHA and SPHI have
; same signs. EXP underflows
; if they are negative.
IMOV: $LCALL IPO ;Imaginary part overflow
HRLOI T0,377777 ;Store zero extended
SETZ T1, ; biggest number.
JRST STIMP1 ;Return to main flow in ANS2 to
; get correct sign, and store.
IMUND1: $LCALL IPU ;Imaginary part underflow
SETZ T0, ;Store double precision
SETZ T1, ; zero for imaginary part
DMOVEM T0,IMAG ; and return to main flow
JRST ANS3 ; in ANS2 to get real part.
IMAG1: MOVE T0,SPONE ;Store double precision
SETZ T1, ; unity for imaginary part
JRST STIMP1 ;Return to main flow in ANS2 to
; get correct sign, and store.
;
; >>>> End of exceptions on imaginary part <<<<
;
; >>>> Continue main flow: Get real part <<<<
;
ANS3: DMOVE T0,ALPHA ;Get ALPHA and make
DMOVE T2,ALPHA ; a copy.
DFAD T0,CPHI ;Add in CPHI. On exception
JFCL RLEX ; branch to special case.
CAMGE T0,AMAXHI ;If T0 is not too big, no
JRST NOVRL ; overflow on real part.
CAMG T0,AMAXHI ;If T0 > AMAXHI, overflow
; on real part.
CAML T1,AMAXLO ;T0 = AMAXHI. Test LO's.
JRST RLOV ; Overflow for T0 >/= AMAXLO
NOVRL: CAMLE T0,AMINHI ;Next test for EXP underflow:
JRST RLOK ; If T0 > AMINHI, no underflow.
CAML T0,AMINHI ;If T0 < AMINHI, EXP will
; underflow, and also real part.
CAMG T1,AMINLO ;T0 = AMINHI. If T1 </= AMINLO
JRST RLUND1 ; real part underflows.
RLOK: DMOVE T0,EXPARG ;Copy argument for EXP
FUNCT DEXP.,<EXPARG> ; and invoke EXP function.
STRLP1: SKIPGE T0,RSIGN ;No exceptions. If RSIGN < 0
DMOVN T0,T0 ; so is real part.
DMOVEM T0, REAL ;Store real part.
JRST DPTOSP ;Go to BLOCK 6 to convert
; to single precision.
;
; >>>> Exceptions on EXP(ALPHA + CPHI) <<<<
;
RLEX: JUMPE T0,REAL1 ;Underflow on sum: |real part| = 1.
JUMPL T2,RLUND1 ;On overflow ALPHA and CPHI have
; same signs. EXP underflows
; if they are negative.
RLOV: $LCALL RPO ;Real part overflow
HRLOI T0,377777 ;Store zero extended
SETZ T1, ; biggest number.
JRST STRLP1 ;Return to main flow in ANS3 to
; get correct sign, and store.
;
RLUND1: $LCALL RPU ;Real part underflow
SETZ T0, ;Store double precision
SETZ T1, ; zero for real part
DMOVEM T0,REAL ; and continue with main
JRST DPTOSP ; flow in BLOCK 6 to convert
; to single precision.
;
REAL1: MOVE T0,SPONE ;Store double precision
SETZ T1, ; unity for real part
JRST STRLP1 ;Return to main flow in ANS3 to
; get correct sign, and store.
;
; >>>> End of exceptions on real part <<<<
;
;End of BLOCK 5. All exceptions in the double precision
;calculations have been properly handled. All paths lead to
;DPTOSP, in BLOCK 6, for conversion to single precision.
;
; *****************
; * BLOCK 6 *
; *****************
;
DPTOSP: DMOVE T0,REAL ;Get D.P. real part to T0.
JUMPL T0,RNEG ;Branch if real part < 0.
TLNE T1,(1B1) ;Is rounding bit 1?
TRON T0,1 ;Yes. If possible round by
JRST IMCVT ; setting LSB. Go convert
; imaginary part.
MOVE T1,T0 ;Else, get copy of high word.
AND T0,[777000,,1] ;Construct unnormalized LSB
; with same exponent.
FAD T0,T1 ;Round DP to SP
JFCL RCVTX1 ;Branch on exception.
JRST IMCVT ;Go convert imaginary part.
;
RNEG: DMOVN T0,T0 ;REAL < 0; get magnitude.
TLNE T1,(1B1) ;Is rounding bit 1?
TRON T0,1 ;Yes. If possible round by
; setting LSB. Go restore
JRST MINUS1 ; minus sign.
MOVE T1,T0 ;Else, get copy of high word.
AND T0,[777000,,1] ;Construct unnormalized LSB
FAD T0,T1 ;Round DP to SP
JFCL RCVTX2 ;Branch on exception.
;
MINUS1: MOVN T0,T0 ;Restore minus sign.
JRST IMCVT ;Now convert imaginary part.
;
; >>>> Exceptions on conversion of real part. <<<<
;
RCVTX1: JUMPE T0,RCVTUN ;Branch on underflow.
; Write message that real part overflows on conversion
$LCALL RPO ;Real part overflow
HRLOI T0,377777 ;Store positive biggest for real.
JRST IMCVT ; and go convert imaginary part.
;
RCVTX2: JUMPE T0,RCVTUN ;Branch on underflow.
; Write message that real part overflows on conversion.
$LCALL RPO ;Real part overflow
HRLOI T0,400000 ;Store negative biggest
TRO T0,(1B1) ; for real part.
JRST IMCVT ;Now convert imaginary part.
;
RCVTUN: SETZ T0, ;Zero for underflow of real part.
; Write message that real part underflows on conversion.
$LCALL RPU ;Real part underflow
JRST IMCVT ;Now convert imaginary part.
;
; *****************
; * BLOCK 6.1 *
; *****************
;
IMCVT: DMOVE T1,IMAG ;Get D.P. imaginary part to T1.
JUMPL T1,INEG ;Branch if imaginary part < 0.
TLNE T2,(1B1) ;Is rounding bit 1?
TRON T1,1 ;Yes. If possible round by
JRST RESTOR ; setting LSB. Go restore
; registers and exit.
MOVE T2,T1 ;Else, get copy of high word.
AND T1,[777000,,1] ;Construct unnormalized LSB
; with same exponent.
FAD T1,T2 ;Round DP to SP
JFCL ICVTX1 ;Branch on exception.
JRST RESTOR ;Go restore registers and exit.
;
INEG: DMOVN T1,T1 ;IMAG < 0; get magnitude.
TLNE T2,(1B1) ;Is rounding bit 1?
TRON T1,1 ;Yes. If possible round by
; setting LSB. Go restore
JRST MINUS2 ; minus sign.
MOVE T2,T1 ;Else, get copy of high word.
AND T1,[777000,,1] ;Construct unnormalized LSB
FAD T1,T2 ;Round DP to SP
JFCL ICVTX2 ;Branch on exception.
;
MINUS2: MOVN T1,T1 ;Restore minus sign.
JRST RESTOR ;Go restore registers and exit.
;
; >>>> Exceptions on conversion of imaginary part. <<<<
;
ICVTX1: JUMPE T1,ICVTUN ;Branch on underflow.
; Write message that imaginary part overflows on conversion
$LCALL IPO ;Imaginary part overflow
HRLOI T1,377777 ;Store positive biggest for
JRST RESTOR ; imaginary part, go restore
; registers, and exit.
;
ICVTX2: JUMPE T1,ICVTUN ;Branch on underflow.
; Write message that imaginary part overflows on conversion.
$LCALL IPO ;Imaginary part overflow
HRLOI T1,400000 ;Store negative biggest
TRO T1,(1B1) ; for imaginary part.
JRST RESTOR ;Go restore registers and exit.
;
ICVTUN: SETZ T1, ;Zero for underflow of
; imaginary part.
; Write message that imaginary part underflows on conversion.
$LCALL IPU ;Imaginary part underflow
RESTOR: MOVE T2,SAVT2 ;Restore registers T2,
MOVE T3,SAVT3 ; T3,
MOVE T4,SAVT4 ; T4,
MOVE T5,SAVT5 ; and T5.
;
GOODBY (1) ;Return.
;Constants
PI: EXP 202622077325,021026430215 ;pi
PIOV2: EXP 201622077325,021026430215 ;pi/2
LN300: EXP 210412126217,316725563320 ;192 * ln(2) for LOG of
; underflowed PHI
SPONE: EXP 201400000000 ;1.0
ARGHI: EXP 241622077325 ;Double precision threshold
ARGLO: EXP 020000000000 ; for argument reduction in
; SIN/COS routines.
TWO63: EXP 300400000000 ;2**63 Threshold for |THETA| = PI/2
TWOM63: EXP 102400000000 ;2**-63 Threshold for |THETA| = PI
; or THETA = Y/X
TWOM66: EXP 077400000000 ;2**-66 Threshold for underflow
; negligible.
AMAXHI: EXP 207540074636 ;88. ... double precision
AMAXLO: EXP 077042573256 ; overflow boundary for EXP.
AMINHI: EXP 570232254036 ;-88. ... double precision
AMINLO: EXP 301750634730 ; underflow boundary for EXP.
;Data
SEGMENT DATA
LNRHO: BLOCK 2 ;LNRHO and THETA must be
THETA: BLOCK 2 ; contiguous since they
; provide output for CDLOG.
REXP: BLOCK 2 ;Temporary storage for A
IEXP: BLOCK 2 ;Temporary storage for B
CPHI: BLOCK 2 ;For COS(PHI) or LN(COS(|PHI|))
SPHI: BLOCK 2 ;For SIN(PHI) or LN(SIN(|PHI|))
ALPHA: BLOCK 2 ;Storage for ALPHA.
ARG1: BLOCK 4 ;Temporary storage for inputs to CDLOG.
LNARG: BLOCK 2 ;Temporary storage for inputs
TRGARG: BLOCK 2 ; to DLOG, DSIN, and
EXPARG: BLOCK 2 ; DCOS and DEXP routines.
REAL: BLOCK 2 ;Real part of result
IMAG: BLOCK 2 ;Imaginary part of result
RSIGN: BLOCK 1 ;Storage for signs of real and
ISIGN: BLOCK 1 ; imaginary parts of result.
PHIFLG: BLOCK 1 ;Storage for flag indicating
; underflow of PHI.
XCHFLG: BLOCK 1 ;Storage for flag indicating
; exchange of LNRHO,THETA and A,B.
SAVT2: BLOCK 1 ;SAVT2, SAVT3, SAVT4,
SAVT3: BLOCK 1 ; must be contiguous. The
SAVT4: BLOCK 1 ; corresponding registers are
SAVT5: BLOCK 1 ; restored by DMOVEs.
PRGEND
TITLE CLOG COMPLEX NATURAL LOG FUNCTION
; (SINGLE PRECISION FLOATING POINT)
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1981, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
SEARCH MTHPRM
NOSYM
ENTRY CLOG
EXTERN CLOG.
CLOG=CLOG.
PRGEND
TITLE CLOG. COMPLEX NATURAL LOG FUNCTION
; (SINGLE PRECISION FLOATING POINT)
SUBTTL Mary Payne 16-Oct-81
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1979, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;CLOG(Z) IS CALCULATED AS FOLLOWS
; LET Z = X + I*Y
; IF Y IS NOT ZERO, THEN
; CLOG(Z) = U + I*V
; U = (1/2)*ALOG(X**2 + Y**2)
; V = ATAN2(Y,X)
; IF X IS NOT ZERO AND Y IS ZERO, THEN
; IF X IS POSITIVE, CLOG(Z) = ALOG(X) + I*0
; IF X IS NEGATIVE, CLOG(Z) = ALOG(ABS(X)) + I*PI
; IF X AND Y ARE ZERO, THEN
; CLOG(Z) = -MACHINE INFINITY + I*0
; AND AN ERROR MESSAGE IS RETURNED
; THE APPROXIMATION USED FOR ALOG IS FORMULA 2662 FROM
; "COMPUTER APPROXIMATIONS" BY HART ET AL.
;THE REAL PART OF THE RESULT IS RETURNED IN REGISTER T0.
;THE IMAGINARY PART OF THE RESULT IS RETURNED IN REGISTER T1.
;REQUIRED (CALLED) ROUTINES: ALOG, ATAN, AND ATAN2
;REGISTERS T2, T3, T4, AND T5 WERE SAVED, USED, AND RESTORED
;THE ROUTINE HAS THE FOLLOWING CALLING SEQUENCE:
; XMOVEI L,ARG
; PUSHJ P,CLOG
;THE RESULT IS RETURNED IN ACCUMULATORS T0 AND T1
EXTERN SNG.0
SEARCH MTHPRM
SEGMENT CODE
SALL
HELLO (CLOG,.) ;ENTRY TO CLOG ROUTINE
DMOVE T0,@(L) ;REAL PART OF ARGUMENT TO T0
; IMAGINARY PART TO T1
JUMPE T1,YZRO ;Y = 0 IS A SPECIAL CASE
JUMPE T0,XZRO ;X = 0 IS A SPECIAL CASE
PUSH P,T2 ;SAVE REGISTERS T2
PUSH P,T3 ; AND T3
MOVM T2,T0 ;GET ABSOLUTE VALUES OF
MOVM T3,T1 ; X AND Y
AND T2,MASK ;ISOLATE EXPONENT FIELDS
AND T3,MASK ; OF X AND Y
SUB T3,T2 ;EXPONENT OF Y - EXPONENT OF X
CAML T3,P14 ;IF DIFFERENCE > 14
JRST BIG ; |Y/X| IS LARGE.
CAMGE T3,M14 ;IF DIFFERENCE < -14
JRST SMALL ; |Y/X| IS SMALL
PUSH P,T4 ;SAVE REGISTERS T4
PUSH P,T5 ; AND T5
MOVM T4,T0 ;SAVE MAGNITUDES OF X
MOVM T5,T1 ; AND Y IN T4,T5
MOVEM T0,TT0 ;STORE X AND Y FOR CALL
MOVEM T1,TT2 ; TO ATAN2.
FUNCT ATAN2.,<TT2,TT0> ;NO EXCEPTIONS
MOVE T3,T0 ;SAVE IMAG. PART IN T3
CAML T4,T5 ;COMPARE |X| AND |Y|
JRST NOXCH ; AND GET LARGER = A IN T4
EXCH T4,T5 ; AND SMALLER = B IN T5
NOXCH: MOVE T2,T4 ;LARGER TO T2
LSH T2,-33 ;ISOLATE ITS BIASED EXPONENT
SUBI T2,200 ; AND UNBIAS IT
JUMPLE T2,LE ;IF UNBIASED EXPONENT > 0,
SUBI T2,1 ; DECREMENT IT
LE: MOVN T2,T2 ;NEGATE SCALE INDEX
FSC T4,(T2) ;SCALE A TO [1/2,2) AND B BY
FSC T5,(T2) ; SAME FACTOR. NO EXCEPTIONS
LSH T2,1 ;MULTIPLY NEGATED SCALE INDEX BY 2
DMOVE T0,T4 ;COPY |X| AND |Y| TO T0,T1
FMPR T0,T0 ;SQUARE LARGER. NO EXCEPTIONS
FMPR T1,T1 ;SQUARE SMALLER. NO OVERFLOW AND
JFCL ; UNDERFLOW WON'T MATTER
MOVEM T1,SMALSQ ;SAVE SMALLER SQUARED
FADR T1,T0 ;GET SCALED SQUARE OF MODULUS
CAMLE T1,RT2 ;IF T1 .GT. SQRT(2)
JRST MORE ; GO TO MORE SCALING
CAMGE T1,RT2O2 ;IF T1 .LT. SQRT(1/2)
JRST MORE ; GO TO MORE SCALING
JUMPN T2,JOIN ;IF SCALE INDEX NOT 0, GO TO JOIN
;At this point the scale index is zero, implying that (A**2 + B**2)
;is unscaled. Also (A**2 + B**2) is between SQRT(1/2) and SQRT(2),
;which implies that a damaging loss of significance can occur in the
;calculation of (A**2 + B**2 - 1), which is one factor of Z, used
;in the approximation. Growth of error due to loss of significance
;can be avoided by calculating instead (A - 1) * (A + 1) + B**2,
;which is done in the following lines of code:
MOVE T0,T4 ;COPY LARGER TO T0
FSBR T0,ONE ;GET A - 1
FADR T4,ONE ;AND A + 1
FMPR T4,T0 ;AND THEIR PRODUCT
FADR T4,SMALSQ ;T4 NOW HAS A**2 + B**2 - 1
MOVE T1,T4 ; = NUMERATOR OF Z. COPY TO T1
FADR T1,TWO ;GET DENOMINATOR OF Z IN T1
JRST MERGE ;MERGE FOR POLYNOMIAL APPROX
;The following code applies to scaled values of (A**2 + B**2) lying
;outside the interval (SQRT(1/2),SQRT(2)); it carries out more
;scaling to get the scaled (A**2 + B**2) inside this interval.
MORE: MOVE T4,T1 ;MAKE COPY OF A**2 + B**2
LSH T4,-33 ;ISOLATE ITS BIASED EXPONENT
SUBI T4,200 ;UNBIAS THE EXPONENT
MOVN T4,T4 ; AND NEGATE IT
FSC T1,(T4) ;SCALED MODULUS NOW IN [1/2,1)
ADD T2,T4 ;TOTAL NEGATED SCALE INDEX TO T2
CAML T1,RT2O2 ;IF T1 .GT. SQRT(1/2)
JRST JOIN ; SCALING IS DONE
FSC T1,1 ;SCALE T1 TO [1,SQRT(2)]
ADDI T2,1 ; AND INCREMENT NEGATED INDEX
;At this point the scaled (A**2 + B**2) is in the interval
;[SQRT(1/2),SQRT(2)]. T2 contains the negative of the index
;necessary to compensate later for the scaling. In the following
;lines of code, a polynomial approximation is used to evaluate
;the natural log of the scaled (A**2 + B**2).
JOIN: MOVN T2,T2 ;RESTORE SIGN OF SCALE INDEX
MOVE T4,T1 ;GET COPY OF SCALED (A**2 + B**2)
FSBR T4,ONE ; -1 = NUMERATOR OF Z
FADR T1,ONE ;GET DENOMINATOR OF Z IN T1
;The following code is taken from the AlOG routine. The constants
;L3, L4, and L5 are those used in ALOG.
MERGE: FDVR T4,T1 ;Z = ZNUM / ZDEN. NO EXCEPTIONS
MOVE T5,T4 ;SAVE A COPY OF Z
FMPR T4,T4 ;W = Z**2
MOVE T0,T4 ; AND MAKE COPY
FMPR T0,L3 ;FORM P(Z) = W*L3
FADR T0,L4 ; + L4
FMPR T0,T4 ; *W
FADR T0,L5 ; + L5
FMPR T0,T4 ; *W
FMPR T0,T5 ; *Z. NO EXCEPTIONS
FSC T5,1 ;GET 2*Z
;2*Z still needs to be added into P(Z).
JUMPN T2,REST ;IF SCALE INDEX = 0,
FADR T0,T5 ; COMPLETE P(Z) BY ADDING IN Z
JRST FINISH ;GO FINISH UP
;The following lines of code complete the calculation of the real
;part for the index not zero. The real part is the double
;precision sum of INDEX*LN(2), Z, and P(Z), rounded to single
;precision.
REST: MOVE T4,T5 ;GET 2*Z IN DOUBLE
SETZB T1,T5 ; PRECISION
DFAD T0,T4 ;GET DP SUM. FLOAT SCALE
FLTR T4,T2 ;INDEX -- DP SINCE T5 HAS 0
DFMP T4,LN2 ;GET INDEX*LN(2)
DFAD T0,T4 ;AND ADD TO PREVIOUS SUM
PUSHJ P,SNG.0 ;ROUND TO SINGLE PRECISION
FINISH: FSC T0,-1 ;DIVIDE BY 2 TO GET LN(MODULUS)
MOVE T1,T3 ;IMAG PART TO T1
POP P,T5 ;POP REGISTERS
POP P,T4 ; IN REVERSE
POP P,T3 ; ORDER IN WHICH
POP P,T2 ; THEY WERE PUSHED
GOODBY (1)
BIG: DMOVE T2,T0 ;SAVE X AND Y
MOVMM T3,TT0 ;STORE |Y| FOR ALOG
FUNCT ALOG.,<TT0>
MOVE T1,PIO2 ;IMAGINARY PART NEAR +/- PI/2
JUMPGE T3,PO2POS ; + FOR Y POSITIVE
MOVN T1,T1 ; - FOR Y NEGATIVE
PO2POS: FDVR T2,T3 ;GET X/Y; NO OVERFLOW
JFCL UND1 ; UNDERFLOW IS POSSIBLE
FSBR T1,T2 ;SMALL CORRECTION TO IMAG
FMPR T2,T2 ;GET (X/Y)**2. NO OVERFLOW
JFCL UND1 ; UNDERFLOW IS POSSIBLE
FSC T2,-1 ;(1/2)*(X/Y)**2. NO OVERFLOW
JFCL UND1 ; UNDERFLOW IS POSSIBLE
FADR T0,T2 ;+ LN(|Y|) = REAL. NO EXCEPTIONS
JRST REST23 ;GO RESTORE T2 AND T3
SMALL: DMOVE T2,T0 ;SAVE X AND Y
MOVMM T2,TT0 ;STORE |X| FOR ALOG
FUNCT ALOG.,<TT0>
SETZ T1, ;IMAG. PART NEAR 0 OR +/- PI
JUMPGE T2,IMAGOK ; 0 FOR X POSITIVE
MOVE T1,CPI ; +/- PI FOR X NEGATIVE
JUMPGE T3,IMAGOK ; + PI FOR Y POSITIVE
MOVN T1,T1 ; - PI FOR Y NEGATIVE
IMAGOK: FDVR T3,T2 ;GET Y/X; NO OVERFLOW
JFCL UND2 ; UNDERFLOW IS POSSIBLE
FADR T1,T3 ;SMALL CORRECTION FOR IMAG.
FMPR T3,T3 ;GET (X/Y)**2. NO OVERFLOW
JFCL UND1 ; UNDERFLOW IS POSSIBLE
FSC T3,-1 ;(1/2)*(X/Y)**2. NO OVERFLOW
JRST UND1 ; UNDERFLOW IS POSSIBLE
FADR T0,T3 ;+ LN(|X|) = REAL. NO EXCEPTIONS
JRST REST23 ;GO RESTORE REGISTERS T2 AND T3
UND2: JUMPN T1,REST23 ;DONE IF |IMAG| NEAR PI OR PI/2
$LCALL IPU
;LERR (LIB,%,<CLOG: Imaginary part underflow>)
UND1: JUMPN T0,REST23 ;DONE IF LN(|X| OR |Y|) NOT 0
$LCALL RPU
;LERR (LIB,%,<CLOG: Real part underflow>)
REST23: POP P,T3 ;RESTORE REGISTERS
POP P,T2 ; T2 AND T3
GOODBY (1)
YZRO: JUMPE T0,XYZRO ;X = Y = 0 IS A SPECIAL CASE
JUMPGE T0,RPOS ;Y IS 0, X ISN'T. IF X < 0
MOVN T0,T0 ;X=ABS(X)
MOVE T1,CPI ;V=PI
RPOS: MOVEM T1,TT2 ;SAVE IMAGINARY PART
MOVEM T0,TT0 ;MOVE X TO MEMORY
FUNCT ALOG.,<TT0> ;COMPUTE U=DLOG(X)
MOVE T1,TT2 ;RESTORE IMAGINARY PART
GOODBY (1) ;RETURN; RESULT IN T0,T1
XZRO: MOVE T0,T1 ;X IS 0, Y ISN'T. COPY Y TO T0
MOVE T1,PIO2 ;IMAG PART IS +/- PI/2
JUMPGE T0,YPLUS ;IF Y < 0,
MOVN T0,T0 ; MAKE IT POSITIVE, AND
MOVN T1,T1 ; MAKE IMAG PART NEGATIVE
YPLUS: MOVEM T0,TT0 ;PREPARE TO GET LOG
MOVEM T1,TT2 ;SAVE IMAGINARY PART
FUNCT ALOG.,<TT0> ;GET LOG(|Y|), NO EXCEPTIONS
MOVE T1,TT2 ;RESTORE IMAGINARY PART.
GOODBY (1) ;RETURN: RESULTS IN T0, T1
XYZRO: $LCALL ZIZ
;LERR (LIB,%,<entry CLOG; arg is (0.0,0.0); result=(-infinity,0.0)>)
MOVE T0,[400000000001] ;REAL ANSWER IS NEGATIVE INFINITY
GOODBY (1) ;RETURN; RESULT IN T0,T1
;CONSTANTS
MASK: EXP 377000000000 ;MASK FOR EXPONENT FIELD
P14: EXP 016000000000 ;HIGH 9 BITS = 16 OCTAL
M14: EXP 762000000000 ;HIGH 9 BITS = -16 OCTAL
ONE: EXP 201400000000 ;1.0
TWO: EXP 202400000000 ;2.0
CPI: EXP 202622077325 ;PI
PIO2: EXP 201622077325 ;PI / 2
RT2O2: EXP 200552023632 ;SQRT(2) / 2
RT2: EXP 201552023632 ;SQRT(2)
L3: EXP 177464164321 ;.301003281
L4: EXP 177631177674 ;.39965794919
L5: EXP 200525253320 ;.666669484507
LN2: EXP 200542710277,276434757153 ;LN(2)
;DATA
SEGMENT DATA
TT0: BLOCK 1 ;FOR ATAN2 AND ALOG CALLS
TT2: BLOCK 1 ;FOR ATAN2 CALL
SMALSQ: BLOCK 1
PRGEND
TITLE CSIN COMPLEX SINE FUNCTION
; (SINGLE PRECISION)
SUBTTL IMSL, INC. JUNE 1, 1979
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1979, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
SEARCH MTHPRM
NOSYM
ENTRY CSIN
EXTERN CSIN.
CSIN=CSIN.
PRGEND
TITLE CCOS COMPLEX COSINE FUNCTION
; (SINGLE PRECISION)
SUBTTL IMSL, INC. JUNE 1, 1979
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1979, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
SEARCH MTHPRM
NOSYM
ENTRY CCOS
EXTERN CCOS.
CCOS=CCOS.
PRGEND
TITLE CSIN. COMPLEX SINE AND COSINE ROUTINES
; (SINGLE PRECISION)
SUBTTL IMSL, INC. JUNE 1, 1979
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1979, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;CSIN(Z) AND CCOS(Z), WHERE Z = X + I*Y, ARE CALCULATED AS FOLLOWS
; CSIN(Z) = SIN(X)*COSH(Y) + I*COS(X)*SINH(Y)
; CCOS(Z) = COS(X)*COSH(Y) - I*SIN(X)*SINH(Y)
; THE FUNCTIONS SINH AND COSH ARE CODED IN LINE.
; THE REAL PART OF THE RESULT CANNOT UNDERFLOW BECAUSE
; COSH(Y) IS NEVER LESS THAN 1.
; THE IMAGINARY PART OF THE RESULT MAY UNDERFLOW; IF THIS HAPPENS THE
; IMAGINARY PART IS SET TO 0 AND A MESSAGE IS PROVIDED.
;THE RANGE OF DEFINITION FOR CSIN AND CCOS IS AS FOLLOWS
;FOR
; Z = X+I*Y. IF ABS(X) > 36394.429 THE RESULT IS SET TO 0.0 AND
; AN ERROR MESSAGE IS RETURNED.
;FOR ABS(Y) > 88.029692 CALCULATIONS PROCEED AS FOLLOWS:
; FOR THE REAL PART OF THE RESULT
; LET T = ABS(SIN(X)), THEN
; FOR T = 0.0 THE REAL PART OF THE RESULT IS SET TO 0.0
; FOR LOG(T) + ABS(Y) > 88.722839 THE REAL PART OF THE
; RESULT IS SET TO PLUS OR MINUS MACHINE INFINITY AND
; AN ERROR MESSAGE IS RETURNED. (88.722839=88.029692+LN2)
; FOR THE IMAGINARY PART OF THE RESULT
; LET T = ABS(COS(X)), THEN
; FOR T = 0.0 THE IMAGINARY PART OF THE RESULT IS SET TO 0.0
; FOR LOG(T) + ABS(Y) > 88.722839 THE IMAGINARY PART OF THE
; RESULT IS SET TO PLUS OR MINUS MACHINE INFINITY AND
; AN ERROR MESSAGE IS RETURNED. (88.722839=88.029692+LN2)
;REQUIRED (CALLED) ROUTINES: SIN,COS,EXP,ALOG
;REGISTERS T2, T3, T4, AND T5 WERE SAVED, USED, AND RESTORED
;THE ROUTINE HAS THE FOLLOWING CALLING SEQUENCE:
; MOVEI L,ARG
; PUSHJ P,CSIN
; OR
; PUSHJ P,CCOS
;THE COMPLEX ANSWER IS RETURNED IN ACCUMULATORS T0 AND T1.
SEARCH MTHPRM
SEGMENT CODE
SALL
HELLO (CCOS,.) ;ENTRY TO CCOS ROUTINE
PUSH P,T3
MOVEI T3,1 ;SET FLAG TO 1 FOR CCOS
JRST CSIN1 ;GO TO CSIN ROUTINE
HELLO (CSIN,.) ;ENTRY TO CMPLX SINE ROUTINE
PUSH P,T3
SETZI T3, ;SET FLAG TO 0 FOR CSIN
CSIN1: PUSH P,T2
PUSH P,T4
PUSH P,T5
XMOVEI T1,@(L) ;GET ADDRESS OF ARG
MOVE T0,(T1) ;X = REAL(Z)
MOVM T2,T0 ; GET ABS(X)
CAMG T2,CUT ;IF ABS(X) IS NOT TOO LARGE
JRST XOK ; GO TO GET Y
$LCALL ARZ
;LERR (LIB,%,<CSIN or CCOS: ABS(REAL(arg)) too large; result = (0.0,0.0)>)
SETZI T0, ;SET REAL(RESULT) TO 0.0
SETZI T1, ;SET IMAG(RESULT) TO 0.0
JRST RET ;RETURN
XOK: MOVE T1,1(T1) ;Y = IMAG(Z)
MOVEM T1,YSAVE ;SAVE Y
MOVEM T0,ARGSAV
FUNCT SIN.,<ARGSAV> ;CALCULATE SIN(X)
MOVEM T0,SX ;SX = SIN(X)
FUNCT COS.,<ARGSAV> ;CALCULATE COS(X)
MOVEM T0,CX ;CX = COS(X)
SKIPN T3 ;IF THIS IS THE CSIN ROUTINE
JRST NOSWT ;THEN GO TO NOSWT
MOVN T2,SX ;OTHERWISE, PUT -SIN(X)
EXCH T2,CX ;IN CX, AND COS(X)
MOVEM T2,SX ;IN SX.
NOSWT: SKIPN T1,YSAVE ;SKIP UNLESS Z IS REAL, IN
JRST CSIN2 ;WHICH CASE, GO TO THE SIMPLE CASE
MOVM T2,T1 ;AY = ABS(YSAVE)
CAMLE T2,XMAX ;IF AY IS TOO LARGE FOR SIMPLE
JRST OVFL ;SINH OR COSH, GO TO OVFL.
CAMG T2,TWOM14 ;IF |Y| <= 2**(-14),
JRST EASY ; SINH = Y, COSH = 1
MOVEM T2,ARGSAV
FUNCT EXP.,<ARGSAV> ;CALCULATE EXP(AY)
MOVE T3,T0
MOVE T5,ONE
FDVR T5,T3
CAMLE T2,ONE ;IF AY IS GREATER THAN 1
JRST GTET ;THEN GO TO GTET
MOVE T1,T2 ;GET COPY OF |Y|
FMPR T1,T1 ;SS = AY**2
MOVE T4,T1
FMPR T4,R4 ;SS = SS*R4
FADR T4,R3 ;SS = SS+R3
FMPR T4,T1 ;SS = SS*(AY**2)
FADR T4,R2 ;SS = SS+R2
FMPR T4,T1 ;SS=SS*(AY**2)
FADR T4,R1 ;SS = SS+R1
FMPR T1,T4 ;SS = SS*(AY**2)
FMPR T1,T2 ;SS = SS*AY
FADR T1,T2 ;SS = SS+AY
JRST CCCC ;GO TO CCCC
GTET: MOVN T1,T5
FADR T1,T3 ;SS = T+SS
FSC T1,-1 ;SS = SS/2.
CCCC: MOVE T0,T5
FADR T0,T1 ;CC = SS+(1/T)
MOVE T3,YSAVE ;RESTORE Y
CAIGE T3,0 ;IF Y IS LESS THAN 0.0
MOVN T1,T1 ;THEN NEGATE SS
FMPR T0,SX ;GET REAL PART OF RESULT
FMPR T1,CX ;GET IMAG PART OF RESULT
JFCL IMUND
JRST RET ;RETURN
EASY: MOVE T0,SX ;REAL PART = 1 * SX
FMPR T1,CX ;IMAG PART = Y * CX
JFCL IMUND ;UNDERFLOW POSSIBLE
JRST RET ;RETURN
IMUND: $LCALL IPO,RET
;LERR (LIB,%,<CSIN or CCOS: imaginary part overflow>,RET)
OVFL: MOVM T0,SX ;T=ABS(SX)
CAIN T0, ;IF T IS EQUAL TO 0.
JRST GOTR ;THEN GO TO GOTR
MOVEM T0,ARGSAV ;OTHERWISE,
FUNCT ALOG.,<ARGSAV> ;CALCULATE LOG(T)
FADR T0,T2 ;T = LOG(T)+AY
FADR T0,LN2 ;T = T-LOG(2.0)
CAMG T0,XMAX ;IF T IS .LE. XMAX
JRST CONTIN ;THEN GO TO CONTIN
$LCALL RPO
;LERR (LIB,%,<CSIN or CCOS: real part overflow>)
HRLOI T0,377777 ;REAL PART OF RESULT SET TO INFINITY
JRST SKP2 ;SKIP NEXT 2 INSTRUCTIONS
CONTIN: MOVEM T0,ARGSAV
FUNCT EXP.,<ARGSAV> ;RRES = EXP(T)
SKP2: SKIPGE SX ;IF SX IS LESS THAN 0.
MOVN T0,T0 ;THEN NEGATE RRES
GOTR: SKIPN T1,CX ;IF CX = 0,
JRST RET ;THEN RETURN
MOVEM T0,SX ;OTHERWISE SAVE RRES
MOVMM T1,ARGSAV ;T = ABS(CX)
FUNCT ALOG.,<ARGSAV> ;CALCULATE T=LOG(T)
MOVE T1,T0
FADR T1,T2 ;T = T+AY
FADR T1,LN2 ;T = T-LOG(2)
CAMG T1,XMAX ;IF T IS .LE. XMAX
JRST CONTN2 ; THEN GO TO CONTN2
$LCALL IPO
;LERR (LIB,%,<CSIN or CCOS: imaginary part overflow>)
HRLOI T1,377777 ;SET IRES TO INFINITY
JRST SKP3 ;SKIP NEXT 3 INSTRUCTIONS
CONTN2: MOVEM T1,ARGSAV
FUNCT EXP.,<ARGSAV> ;IRES = EXP(T)
MOVE T1,T0
SKP3: MOVE T0,SX
MOVE T2,YSAVE
XOR T2,CX ;T2 HAS THE SIGN OF CX*Y
JUMPGE T2,RET ;IF SIGNS ARE THEN SAME, DONE
MOVN T1,T1 ;OTHERWISE NEGATE IMAG PART OF RESULT
JRST RET ;RETURN
CSIN2: MOVE T0,SX ;SIMPLE CASE, Z IS REAL
RET: POP P,T5
POP P,T4
POP P,T2
POP P,T3
GOODBY (1)
TWOM14: 163400000000 ;2**(-14)
LN2: 577235067500 ;-(NATURAL LOG OF 2.0)
XMAX: 207540074636 ;88.029692
R1: 176525252524 ;1.666666643E-1
R2: 172421042352 ;8.333352593E-3
R3: 164637771324 ;1.983581245E-4
R4: 156572227373 ;2.818523951E-6
ONE: 201400000000 ;1.0
CUT: 234622077325 ;2**26 * PI
SEGMENT DATA
CX: 0
SX: 0
YSAVE: 0
ARGSAV: 0
PRGEND
TITLE CSQRT COMPLEX SQUARE ROOT FUNCTION
; (SINGLE PRECISION FLOATING POINT)
SUBTTL IMSL, INC. JUNE 1, 1979
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1979, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
SEARCH MTHPRM
NOSYM
ENTRY CSQRT
EXTERN CSQRT.
CSQRT=CSQRT.
PRGEND
TITLE CSQRT. COMPLEX SQUARE ROOT FUNCTION
; (SINGLE PRECISION FLOATING POINT)
SUBTTL IMSL, INC. JUNE 1, 1979
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1979, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
; LET Z = X + I*Y
; THEN THE ANSWER CSQRT(Z) = U + I*V IS DEFINED AS FOLLOWS
; IF X AND Y ARE BOTH >= 0.0, THEN
; U = SQRT((ABS(X)+CABS(Z))/2.0)
; V = Y/(2.0*U)
; IF X >= 0.0 AND Y < 0.0, THEN
; U = SQRT((ABS(X)+CABS(Z))/2.0)
; V = Y/(2.0*U)
; IF X < 0.0 AND Y >= 0.0, THEN
; U = Y/(2.0*V)
; V = SQRT((ABS(X)+CABS(Z))/2.0)
; IF X AND Y ARE BOTH < 0.0, THEN
; U = Y/(2.0*V)
; V = -SQRT((ABS(X)+CABS(Z))/2.0)
; THE RESULT IS IN THE RIGHT HALF PLANE, THAT IS, THE POLAR ANGLE OF THE
; RESULT LIES IN THE INTERVAL [-PI/2,+PI/2].
;REQUIRED (CALLED) ROUTINES: SQRT
;REGISTERS T2, T3, T4, T5, AND G1 WERE SAVED, USED, AND RESTORED
;THE ROUTINE HAS THE FOLLOWING CALLING SEQUENCE:
; MOVEI L,ARG
; PUSHJ P,CSQRT
;THE REAL PART OF THE ANSWER IS RETURNED IN ACCUMULATOR T0
;THE IMAG PART OF THE ANSWER IS RETURNED IN ACCUMULATOR T1
SEARCH MTHPRM
SEGMENT CODE
SALL
HELLO (CSQRT,.) ;ENTRY TO COMPLEX SQUARE ROOT ROUTINE.
XMOVEI T1,@0(L) ;PICK UP ADDRESS OF ARGUMENT
MOVE T0,(T1) ;PICK UP X IN AC T0.
MOVE T1,1(T1) ;PICK UP Y IN AC T1.
PUSH P,T2 ;SAVE AC T2.
JUMPE T1,ZREAL ;JUMP IF Y=0
JUMPE T0,ZIMAG ;JUMP IF X=0
MOVM T2,T0 ;ABS(X) TO AC T2.
PUSH P,T3 ;SAVE REGISTER T3.
PUSH P,T4 ;SAVE REGISTER T4
PUSH P,T5 ;SAVE REGISTER T5
PUSH P,G1 ;SAVE REGISTER G1
MOVE T4,T0 ;SAVE X IN AC T4.
MOVE T5,T1 ;SAVE Y IN AC T5.
MOVM T3,T1 ;ABS(Y) TO AC T3.
SETZ G1, ;G1 CONTAINS 0 IF ABS(X)
CAMLE T2,T3 ;<= ABS(Y), ELSE IT CONTAINS 1. PUT
AOJA G1,DWN2 ;THE LARGER OF ABS(X),ABS(Y) IN AC T2
EXCH T2,T3 ;AND THE SMALLER IN AC T3.
DWN2: FDVR T3,T2 ;CALC S/L.
JFCL ;NO UNDERFLOW ERROR MESSAGE ALLOWED.
FMPR T3,T3 ;CALC (S/L)**2.
JFCL ;NO UNDERFLOW ERROR MESSAGE ALLOWED.
FADRI T3,201400 ;HAVE (1+(S/L)**2) IN AC T3.
MOVEM T3,TEMP
FUNCT SQRT.,<TEMP> ;[3220] CALC. THE SQRT OF
;(1+(S/L)**2)=1+EPS.
JUMPE G1,YGTX ;GO TO YGTX IF ABS(Y) > ABS(X).
XGTY: FADRI T0,201400 ;CALC. 2 + EPS.
FSC T0,-1 ;CALC. 1+EPS/2.
MOVMM T0,TEMP ;PUT IN TEMP FOR
FUNCT SQRT.,<TEMP> ;[3220] CALL TO SQRT
MOVE T3,T0 ;SAVE SQRT(1+EPS/2) IN AC T3.
MOVEM T2,TEMP
FUNCT SQRT.,<TEMP> ;[3220] CALC.
FMPR T0,T3 ;CALC. SQRT(ABS(X)*(1+EPS/2)).
JRST OUT1 ;GO TO REST OF CALC.
YGTX: CAMGE T2,[1.0] ;IF ABS(Y)>1, GO TO POSSIBLE OVERFLOW CASE.
JRST YXSMAL ;ELSE, GO TO POSSIBLE UNDERFLOW.
FSC T0,-3 ;CALC. (1+EPS)/8.
FMPR T2,T0 ;CALC. ABS(Y)*(1+EPS)/8.
MOVM T3,T4 ;ABS(X) TO AC T3.
FSC T3,-3 ;CALC. ABS(X)/8.
JFCL ;SUPPRESS UNDERFLOW ERROR MESSAGE.
FADR T3,T2 ;CALC.(ABS(X)/8)+(ABS(Y)*(1+EPS)/8).
MOVEM T3,TEMP
FUNCT SQRT.,<TEMP> ;[3220] CALC.
FSC T0,1
OUT1: MOVM T1,T5 ;ABS(Y) TO AC T1.
FDVR T1,T0 ;DIVIDE ABS(Y)/2 BY THE
JFCL UNDFL
FSC T1,-1 ;SQRT TERM.
JFCL UNDFL
JRST SIGNS ;GO TO REST OF CALC.
YXSMAL: FMPR T0,T2 ;ABS(Y)*(1+EPS) = CDABS(Z).
MOVM T3,T4 ;ABS(X) TO AC T3.
FADR T3,T0 ;GET |X| + CDABS(Z)
FSC T3,1 ;GET 2*(|X| + CABS(Z))
MOVEM T3,TEMP
FUNCT SQRT.,<TEMP> ;[3220] CALC. SQRT OF 2*(|X| + CABS(Z))
MOVE T3,T0 ;GET SQRT((|X| + CABS(Z))*2)
FSC T0,-1 ;GET SQRT((|X| + CABS(Z))/2)
FDVR T2,T3 ;GET |Y| / SQRT(2*(|X| + CABS(Z))).
MOVE T1,T2 ;PUT A TEMP ANSWER IN AC T1.
SIGNS: CAIGE T4,0 ;SET UP THE REAL AND
EXCH T1,T0 ;THE IMAGINARY ANSWERS WITH
CAIGE T5,0 ;THE APPROPRIATE
MOVN T1,T1 ;SIGNS.
POP P,G1 ;RESTORE AC G1
POP P,T5 ;RESTORE AC T5
POP P,T4 ;RESTORE AC T4
POP P,T3 ;RESTORE AC T3
POP P,T2 ;RESTORE AC T2
GOODBY (1) ;RETURN
ZREAL: JUMPE T0,DONE ;Y = 0, HOW ABOUT X?
MOVE T2,T0 ;X NOT ZERO; SAVE IT.
MOVMM T2,TEMP ;GET ABS(X) FOR SQRT.
FUNCT SQRT.,<TEMP> ;[3220] T0 GETS SQRT(ABS(X)).
SETZ T1, ;T1 smashed by call; Set to 0 again
JUMPG T2,DONE ;T0,T1 OK FOR X>0.
EXCH T0,T1 ; INTERCHANGE FOR X<0.
POP P,T2 ;RESTORE T2.
GOODBY (1) ;RETURN.
ZIMAG: MOVE T2,T1 ;X = 0, SAVE Y.
FSC T1,-1 ;DIVIDE Y BY 2.
MOVMM T1,TEMP ;GET ABS(Y/2) FOR SQRT.
FUNCT SQRT.,<TEMP> ;[3220] T0 GETS SQRT(ABS(Y/2)).
MOVE T1,T0 ;SO DOES T1.
JUMPG T2,DONE ; DONE IF Y>0.
MOVN T1,T1 ;NEGATE IMAG PART IF Y<0.
DONE: POP P,T2 ;RESTORE T2.
GOODBY (1) ;RETURN
UNDFL: CAIGE T4,0 ;SKIP IF REAL & IMAG SWITCHED
$LCALL RPU,SIGNS
; LERR (LIB,%,<CEXP: real part underflow>,SIGNS)
$LCALL IPU,SIGNS
; LERR (LIB,%,<CEXP: imaginary part underflow>,SIGNS)
SQ2: 201552023632 ;SQRT(2).
SEGMENT DATA
TEMP: 0 ;TEMPORARY STORAGE FOR SQRT ARGS
PRGEND
TITLE CFM COMPLEX MULTIPLICATION
SUBTTL KAREN KOLLING /KK/CKS 28-Oct-81
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1980, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
;FROM LIB40 VERSION .027
;FROM V.021 16-OCT-70
;COMPLEX FLOATING MULTIPLY ROUTINE.
;THIS ROUTINE MULTIPLIES TWO COMPLEX NUMBERS ACCORDING
;TO THE RULE:
; (A+IB)*(C+ID)=(A*C-B*D)+I*(B*C+A*D)
;IF EITHER PRODUCT IN EITHER TERM OVER OR UNDERFLOWS,
;A JUMP IS MADE TO A SPECIAL CASE CALCULATION. OVER
;AND UNDERFLOW ERROR MESSAGES ARE RETURNED ONLY IF THE
;ENTIRE TERM OVER OR UNDERFLOWS.
;THERE ARE TWO SETS OF ENTRY POINTS TO THIS ROUTINE:
;THE MULTIPLY, AND THE MULTIPLY-TO-MEMORY.
;THE CALLING SEQUENCE FOR THE MULTIPLY ROUTINES IS AS
;FOLLOWS:
; XMOVEI L,ARG2
; PUSHJ P,CFM.N
;WHERE N=0,2,4,6,10,12,14. ARG1 IS ASSUMED TO BE IN
;AC'S N AND N+1, AND THE RESULTS ARE LEFT IN AC'S N AND N+1.
;THE CALLING SEQUENCE FOR THE MULTIPLY TO MEMORY ROUTINES IS AS
;FOLLOWS:
; XMOVEI L,ARG2
; PUSHJ P,CMM.N
;WHERE N AND ARG1 ARE AS BEFORE AND THE RESULTS ARE
;LEFT IN ARG2 AND ARG2+1.
SEARCH MTHPRM
SEGMENT CODE
SALL
DEFINE SYM (N)<
ENTRY CFM.'N,CMM.'N
SIXBIT / CFM.'N/
CFM.'N: DMOVEM N,ARG11 ;STORE FIRST ARG
IFN N,< DMOVEM 0,SAVE0 > ;SAVE REGS 0-1
DMOVE 0,(L) ;GET SECOND ARG
PUSHJ P,CFM ;MULTIPLY
IFN N,< DMOVE N,0 ;STORE RESULT
DMOVE 0,SAVE0 > ;RESTORE REGS 0-1
POPJ P, ;RETURN
SIXBIT / CMM.'N/
CMM.'N: DMOVEM N,ARG11 ;STORE FIRST ARG
DMOVEM 0,SAVE0 ;SAVE REGS 0-1
DMOVE 0,(L) ;GET SECOND ARG
PUSHJ P,CFM ;MULTIPLY
DMOVEM 0,(L) ;STORE RESULT
DMOVE 0,SAVE0 ;RESTORE REGS 0-1
POPJ P, ;RETURN
>
XLIST ;GENERATE CFM.0 ... CFM.14 AND CMM.0 ... CMM.14
.N.=16
REPEAT 7,<SYM(\<.N.==.N.-2>)>
LIST
CFM: DMOVEM T0,ARG21 ;STORE SECOND ARG
DMOVEM T2,SAVE2 ;SAVE SCRATCH REGISTERS
PUSHJ P,CALC ;CALC (A*C-B*D)
MOVEM T0,REAL ;SAVE REAL(ANS) IN REAL.
MOVE T0,ARG12 ;SET UP
EXCH T0,ARG11 ;AND CALCULATE
MOVNM T0,ARG12 ;(B*C+A*D)
PUSHJ P,CALC ;AND LEAVE IT IN T0.
MOVE T1,T0 ;STORE IMAG(ANS) IN T1
MOVE T0,REAL ;GET REAL(ANS) IN T0
DMOVE T2,SAVE2 ;RESTORE SCRATCH REGISTERS
POPJ P, ;RETURN
CALC: MOVE T0,ARG11 ;"A" TO AC0.
MOVE T2,ARG12 ;"B" TO AC2.
FMPR T0,ARG21 ;CALC A*C AND IF
JFCL OUFLO1 ;IT OVER/UNDERFLOWS, GO TO OUFLO1.
SECOND: FMPR T2,ARG22 ;CALC B*D AND IF
JFCL OUFLO2 ;IT OVER/UNDERFLOWS, GO TO OUFLO2.
FSBR T0,T2 ;CALC A*C-B*D AND
POPJ P, ;RETURN.
OUFLO1: MOVE T3,ARG22 ;"D" TO AC3.
JUMPE T0,UNDER1 ;UNDERFLOW, GO TO UNDER1
FMPRB T2,T3 ;CALC B*D AND
JFCL OFL1OU ;IF OVER/UNDERFLOW GO TO OFL1OU.
XOR T3,T0 ;OVERFLOW + NORMAL CASE
JUMPGE T3,SROVNM ;IF SIGNS ARE THE SAME, GO TO SROVNM
INFIN: MOVEM T0,ANSTMP ;STORE ANSWER.
INFIN1: $LCALL 999
;LERR (999,%,Complex overflow at $1L,<T1>)
MOVE T0,ANSTMP ;PICK UP ANSWER.
POPJ P, ;RETURN.
OFL1OU: JUMPE T2,INFIN ;OVERFLOW + UNDERFLOW CASE GOES TO INFIN.
XOR T3,T0 ;OVERFLOW + OVERFLOW CASE.
JUMPGE T3,SROVOV ;IF SIGNS ARE THE SAME, GO TO SROVOV
JRST INFIN ;O'E, GO TO INFIN.
SROVNM: JUMPE T2,INFIN ;OVERFLOW + ZERO, GO TO INFIN.
MOVE T0,ARG21 ;C TO AC0.
FSC T0,-1 ;CALC. C/2.
FMPR T0,ARG11 ;CALC. (C/2)*A AND IF
JFCL SROV1 ;IT OVERFLOWS, IMMEDIATELY RETURN.
FSBRM T0,T2 ;CALC ((C/2*A)-(B*D).
FADR T0,T2 ;CALC (A*C-B*D) AND
POPJ P, ;RETURN.
SROV1: MOVEM T0,ANSTMP ;STORE ANSWER
JRST INFIN1 ;GO TO ERROR
SROVOV: MOVE T0,ARG21 ;C TO AC0.
FDVR T0,ARG22 ;CALC. (C/D).
MOVE T1,ARG12 ;B TO AC1.
FDVR T1,ARG11 ;CALC. (B/A).
FSBR T0,T1 ;CALC. ((C/D)-(B/A)) AND
JFCL FIXUP ;IF IT UNDERFLOWS, GO TO FIXUP.
FMPR T0,ARG22 ;CALC. ((C)-(B/A)*D)) AND
JFCL ;SUPPRESS OVERFLOW MESSAGE.
FMPR T0,ARG11 ;CALC (A*C-B*D) AND
POPJ P, ;RETURN.
FIXUP: FMPR T1,ARG22 ;CALC. ((B/A)*D).
MOVE T0,ARG21 ;C TO AC0.
FSBR T0,T1 ;CALC. (C-(B/A)*D).
FMPR T0,ARG11 ;CALC. (A*C-B*D) AND
POPJ P, ;RETURN.
UNDER1: FMPR T2,T3 ;CALC. B*D AND GO
JFCL U1OU ;TO U1OU IF OVER/UNDERFLOW.
MOVM T3,T2 ;IF B*D IS <2**-105,
CAMGE T3,[030400000000] ;GO
JRST UNDR0 ;TO .+3.
MOVN T0,T2 ;NO BITS CAN BE SAVED,
POPJ P, ;FIX SIGN AND RETURN.
UNDR0: FSC T2,32 ;CALC B*D*(2**27).
UNDR1: MOVE T0,ARG11 ;CALC
FSC T0,32 ;A*C*(2**27)
FMPR T0,ARG21 ;AND SUPPRESS AN
JFCL ;ERROR MESSAGE.
UNDR4: FSBR T0,T2 ;CALC (2**27)(A*C-B*D),
UNDR5: FSC T0,-32 ;CALC (A*C-B*D) AND
POPJ P, ;RETURN.
U1OU: JUMPE T2,U1OU1 ;IF OVERFLOW + UNDERFLOW, GO
MOVNM T2,ANSTMP ;TO ERROR
JRST INFIN1 ;RETURN.
U1OU1: MOVE T2,ARG12 ;O'E, TRY TO SAVE BITS.
FSC T2,32 ;CALC. B*(2**27).
FMPR T2,ARG22 ;CALC B*D*(2**27)
JFCL ;AND SUPPRESS UNDERFLOW MESSAGE
MOVE T0,ARG11 ;CALC. A*(2**27) AND
FSC T0,32 ;A*(2**27)*C
FMPR T0,ARG21 ;AND SUPPRESS
JFCL ;UNDERFLOW MESSAGE.
JUMPN T2,UNDR4 ;IF BOTH UNDERFLOW, RETURN
JUMPN T0,UNDR5 ;AN ERROR MESSAGE. O'E,
$LCALL 888
;LERR (888,%,Complex underflow at $1L,<T1>)
SETZ T0, ;CLEAR AC0
POPJ P, ;CALC.
OUFLO2: JUMPN T2,OUFLO3 ;JUMP AHEAD IF (B*D) OVERFLOWED.
CAML T0,[030400000000] ;IF NO BITS CAN BE SAVED,
POPJ P, ;RETURN.
FSC T0,32 ;CALC. (2**27)*(A*C)
MOVE T2,ARG12 ;AND
FSC T2,32 ;THEN
FMPR T2,ARG22 ;(2**27)*(B*D)
JFCL ;AND GO TO THE REST
JRST UNDR4 ;OF THE CALC.
OUFLO3: MOVEM T2,T1 ;OVERFLOW + NORMAL.
XOR T1,T0 ;IF THE SIGNS ARE THE SAME,
JUMPGE T1,SROVN ;GO TO SROVN
MOVNM T2,ANSTMP ;THE ANSWER AND
JRST INFIN1 ;GO TO ERROR EXIT.
SROVN: MOVE T3,ARG22 ;"D" TO AC3.
FSC T3,-2 ;CALC (D/2).
FMPR T3,ARG12 ;CALC (B*(D/2)) AND IF
JFCL FIXUP2 ;IT OVERFLOWS, GO TO FIXUP2.
FSBR T0,T3 ;CALC. ((A*C)-(B*(D/2))).
FSBR T0,T3 ;CALC (A*C-B*D) AND
POPJ P, ;RETURN.
FIXUP2: MOVNM T3,ANSTMP ;SET UP THE ANSWER
JRST INFIN1 ;AND GO TO ERROR EXIT.
SEGMENT DATA
SAVE0: BLOCK 2
SAVE2: BLOCK 2
ARG11: BLOCK 1
ARG12: BLOCK 1
ARG21: BLOCK 1
ARG22: BLOCK 1
REAL: BLOCK 1
ANSTMP: BLOCK 1
PRGEND
TITLE CFDV COMPLEX DIVISION
SUBTTL KAREN KOLLING /KK/CKS 28-Oct-81
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1980, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
;FROM LIB40 VERSION .027
;FROM V.026 24-MAR-70
;THIS PROGRAM CALCULATES THE QUOTIENT OF TWO FLOATING POINT
;NUMBERS IN THE FOLLOWING MANNER:
;(A+IB)/(C+ID) = [(AC+BD)+I(BC-AD)]/(C**2+D**2)
;IF OVER OR UNDERFLOW OCCURS AT ANY POINT IN THE
;CALCULATION, THE PROGRAM JUMPS TO A MORE
;INVOLVED ROUTINE IN WHICH THE ORDER IN WHICH THE
;TERMS ARE MULTIPLIED OR DIVIDED TOGETHER IS VERY
;IMPORTANT. OVER OR UNDERFLOW IS NOT PERMITTED
;UNLESS THE FINAL ANSWER OVER OR UNDERFLOWS.
;THERE ARE TWO SETS OF ENTRY POINTS FOR THE PROGRAM - ONE
;FOR THE DIVIDE ROUTINES AND ONE FOR THE DIVIDE-TO-MEMORY
;ROUTINES. THE CALLING SEQUENCE FOR THE DIVIDE ROUTINES IS
; XMOVEI L,ARG2
; PUSHJ P,CFD.N
;WHERE N=0,2,4,6,10,12,14. ARG1 IS ASSUMED TO BE IN AC N AND (N+1),
;AND THE RESULTS ARE RETURNED IN AC N AND AC (N+1)
;THE CALLING SEQUENCE FOR THE DIVIDE-TO-MEMORY ROUTINES IS
;AS FOLLOWS:
; XMOVEI L,ARG2
; PUSHJ P,CDM.N
;WHERE N AND ARG2 ARE AS ABOVE AND THE RESULTS ARE RETURNED IN
;ARG2 AND ARG2+1.
SEARCH MTHPRM
SEGMENT CODE
SALL
DEFINE SYM (N) <
ENTRY CFD.'N,CDM.'N
SIXBIT / CFD.'N/
CFD.'N: DMOVEM N,SAB ;STORE NUMERATOR
IFN N,< DMOVEM 0,SAVE0 > ;SAVE REGS 0-1
DMOVE 0,(L) ;GET SECOND ARG
PUSHJ P,CFD ;DIVIDE
IFN N,< DMOVE N,0 ;STORE RESULT
DMOVE 0,SAVE0 > ;RESTORE REGS 0-1
POPJ P, ;RETURN
SIXBIT / CDM.'N/
CDM.'N: DMOVEM N,SAB ;STORE NUMERATOR
DMOVEM 0,SAVE0 ;SAVE 0-1
DMOVE 0,(L) ;GET SECOND ARG
PUSHJ P,CFD ;DIVIDE
DMOVEM 0,(L) ;STORE RESULT
DMOVE 0,SAVE0 ;RESTORE 0-1
POPJ P,
>
XLIST ;GENERATE CFD.0 ... CFD.14 AND CDM.0 ... CDM.14
.N.==16
REPEAT 7,<SYM(\<.N.==.N.-2>)>
LIST
CFD: DMOVEM T0,SCD ;STORE DENOMINATOR IN SCD AND LCD
JUMPE T0,CZERO ;GO TO CZERO IF C=0, TO
JUMPE T1,DZERO ;DZERO IF D=0,
SKIPE SAB ;TO NORMAL IF ONLY
JRST NORMAL ;ONE OF A AND B
SKIPE LAB ;=0, TO ABEQZR
JRST NORMAL ;IF
ABEQZR: SETZB T0,REAL ;A=B=0
JRST OUT1 ;RETURN (0,0)
DZERO: MOVE T0,SAB ;D IS ZERO, SO REAL (ANS)
FDVR T0,SCD ;= A/C AND
MOVEM T0,REAL ;IMAG (ANS) =
MOVE T0,LAB ;B/C
FDVR T0,SCD ;AND THEN
JRST OUT1 ;GO TO EXIT
CZERO: MOVE T0,LAB ;C IS ZERO (POSSIBLY D IS
FDVR T0,LCD ;ZERO ALSO). REAL (ANS) =
MOVEM T0,REAL ;B/D AND
MOVN T0,SAB ;IMAG (ANS) =
FDVR T0,LCD ;-A/D AND THEN
JRST OUT1 ;GO TO EXIT.
NORMAL: FMPR T0,SCD ;THIS SIMPLE ROUTINE
JFCL NTSMPL ;CALCULATES
FMPR T1,LCD ;REAL (ANS) =
JFCL NTSMPL ;(A*C+B*D)/(C(2)+D(2))
FADR T0,T1 ;AND
JFCL NTSMPL ;IMAG (ANS) =
MOVEM T0,TEMP ;(B*C-A*D)/(C(2)+D(2))
MOVE T0,SCD ;BUT
FMPR T0,SAB ;IF
JFCL NTSMPL ;AT
MOVE T1,LAB ;ANY
FMPR T1,LCD ;POINT
JFCL NTSMPL ;OVER
FADR T0,T1 ;OR
JFCL NTSMPL ;UNDERFW
FDVR T0,TEMP ;OCCURS
JFCL NTSMPL ;IT
MOVEM T0,REAL ;JUMPS
MOVE T0,SAB ;TO
FMPR T0,LCD ;NTSMPL
JFCL NTSMPL ;FOR
MOVE T1,LAB ;A
FMPR T1,SCD ;DIFFERENT
JFCL NTSMPL ;CALCULATION.
FSBRM T1,T0 ;IF THERE IS
JFCL NTSMPL ;OVER OR
FDVR T0,TEMP ;UNDERFLOW
JRST OUT1 ;IT EXITS TO OUT1.
NTSMPL: DMOVEM T2,SAVE2 ;SAVE THE CONTENTS OF AC2-3.
MOVEM T4,SAVE4 ;SAVE THE CONTENTS OF AC4.
MOVE T2,SAB ;REARRANGE THE REAL
MOVM T0,SAB ;AND IMAG PARTS OF
MOVM T1,LAB ;THE 1ST ARG
MOVEI T4,1 ;SO THAT THE SMALLER ONE
CAMG T0,T1 ;(IN MAGNITUDE) IS IN
JRST NTSMP1 ;SAB, AND THE OTHER IS IN
EXCH T2,LAB ;LAB AND SET UP AC4 AS
MOVEM T2,SAB ;A FLAG WORD TO TELL
MOVN T4,T4 ;WHICH PART IS WHERE.
NTSMP1: MOVE T2,SCD ;REARRANGE THE REAL
MOVM T0,SCD ;AND IMAG PARTS OF THE OTHER ARG
MOVM T1,LCD ;SO THAT THE SMALLER ONE
CAMG T0,T1 ;(IN MAGNITUDE) IS IN SCD AND
JRST NTSMP2 ;THE OTHER IS IN LCD AND
EXCH T2,LCD ;FIX AC4 TO TELL WHICH
MOVEM T2,SCD ;PART
IMULI T4,3 ;IS WHERE.
NTSMP2: MOVE T3,LCD ;CALCULATE
FDVRB T2,T3 ;THE
JFCL ;TERM
FMPR T2,T2 ;1+(SCD/LCD)**2
JFCL ;AND
FADRI T2,(1.0) ;STORE IT IN
MOVEM T2,DENOM ;DENOM.
MOVE T0,SAB ;CALCULATE
FDVR T0,LAB ;(SCD/LCD)*(SAB/LAB)
JFCL ;SUPPRESSING
FMPRM T0,T3 ;UNDERFLOW
JFCL ;IF NECESSARY.
CAIN T4,1 ;FIX THE AC FLAG WORD
MOVNI T4,2 ;FOR
ADDI T4,1 ;EASY COMPARISONS.
SKIPL T4 ;CALCULATE
MOVN T3,T3 ;+-1 +-(SCD/LCD)*(SAB/LAB),
FADRI T3,(1.0) ;WHERE THE SIGNS
SKIPN T4 ;DEPEND ON
MOVN T3,T3 ;THE AC FLAG WORD.
PUSHJ P,CALC34 ;JUMP TO CALC OF (LAB/LCD)*(AC3/DENOM).
MOVEM T0,REAL ;STORE IT IN REAL(ANS) AND
MOVEM T0,IMAG ;IMAG(ANS)(THE TEMP. LOCATIONS).
MOVE T3,SAB ;CALCULATE
MOVE T2,SCD ;+-(SAB/LAB)+-(SCD/LCD)
CAMN T4,[-2] ;WHERE THE SIGNS
MOVN T2,T2 ;AGAIN DEPENDS ON
CAMN T4,[-1] ;THE AC FLAG WORD,
MOVN T3,T3 ;AND IF UNDERFLOW
MOVE T0,T2 ;OCCURS JUMP TO
MOVE T1,T3 ;THE
FDVR T3,LAB ;SPECIAL
JFCL OVER1 ;ROUTINES-
FDVR T2,LCD ;OVER1,
JFCL OVER2 ;OVER2,
ADD2: FADR T3,T2 ;OR
JFCL OVER3 ;OVER3.
CALCIR: PUSHJ P,CALC34 ;JUMP TO CALC OF(LAB/LCD)*(AC3/DENOM).
STIR: JUMPGE T4,STR ;STORE THIS IN
MOVEM T0,IMAG ;THE CORRECT
JRST STX ;PART OF THE
STR: MOVEM T0,REAL ;ANSWER (TEMP. LOCATION).
STX: DMOVE T2,SAVE2 ;RESTORE THE CONTENTS OF AC2-3.
MOVE T4,SAVE4 ;RESTORE THE CONTENTS OF AC4.
OUT: SKIPA T1,IMAG ;PICK UP THE IMAG (ANS)
OUT1: MOVE T1,T0 ;STORE IMAG IN T1
MOVE T0,REAL ;GET REAL PART
POPJ P, ;DONE
CALC34: MOVM T1,LAB ;CALC34 CALCS. (LAB/LCD)*(AC3/DENOM).
MOVM T2,LCD ;/LAB/ TO AC T1 AND /LCD/ TO AC 2.
MOVM T0,T3 ;/AC3/ TO AC 0.
CAMGE T2,ONE ;GO TO CASEA IF
JRST CASEA ;/LCD/<1.0. O'E, STAY HERE.
CAMGE T1,ONE ;GO TO CASEB IF /LCD/>1.0 AND
JRST CASEB ;/LAB/<1.0 OR IF
CAMGE T0,ONE ;(>1)(<1)/(>1)(>1).
JRST CASEB ;STAY HERE IF (>1)(>1)/
FDVR T2,T1 ;(>1)(>1).
STD: FDVR T0,DENOM ;CALCULATE
FDVR T0,T2 ;IT AND GO
JRST SETSGN ;TO SETSGN.
CASEB: FMPR T0,T1 ;CALCULATE CASE B AND
JRST STD ;GO TO SETSGN (EVENTUALLY).
CASEA: FMPR T2,DENOM ;CONDENSE THE DENOMINATOR INTO AC 2.
CAMLE T1,ONE ;THEN (<1)(<1)/(<1) GOES
JRST CHKAGN ;TO SR, AND (>1)(><1)/(<>1)
CAMLE T0,ONE ;GOES TO CHKAGN,
JRST NOTRVS ;AND EVERYTHING ELSE
CAMG T2,ONE ;GOES TO
JRST SR ;NOTRVS.
NOTRVS: FMPRM T1,T0 ;CALCULATE
JFCL SETSGN ;NOTRVS AND GO
FDVR T0,T2 ;TO
JRST SETSGN ;SETSGN.
CHKAGN: CAMG T0,ONE ;(>1)(<1)/(<>1)
JRST NOTRVS ;AND (>1)(>1)/(<1)
CAMG T2,ONE ;GO TO
JRST NOTRVS ;NOTRVS.
FDVR T1,T2 ;(>1)(>1)/(>1) IS
FMPRM T1,T0 ;CALCULATED AND
JRST SETSGN ;GOES TO SETSGN.
SR: MOVEM T1,TEMP ;SR CALCULATES
FDVR T1,T2 ;(<1)(<1)/(<1)
JFCL OV1 ;AND SINCE
FMPRM T1,T0 ;(<1)/(<1)
JRST SETSGN ;CAN
OV1: MOVE T1,TEMP ;OVERFLOW, IT
MOVEM T0,TEMP ;CALCULATES
FDVR T0,T2 ;IT
JFCL OV2 ;WHICHEVER
FMPRM T1,T0 ;WAY
JRST SETSGN ;IS
OV2: MOVE T0,TEMP ;NECESSARY
FMPRM T1,T0 ;AND
FDVR T0,T2 ;THEN GOES TO SETSGN.
SETSGN: MOVE T1,LAB ;GET THE
XOR T1,LCD ;SIGN OF THE
XOR T1,T3 ;RESULT IN AC 1.
SKIPG T1 ;SET THE SIGN OF
MOVN T0,T0 ;THE ANSWER
POPJ P, ;AND EXIT.
OVER1: FDVR T2,LCD ;IF ONE
JFCL UU ;TERM
MOVE T3,T2 ;UNDERFLOWS
MOVE T0,T1 ;AND THE OTHER
MOVE T2,LAB ;TERM IS SO LARGE
JRST OVER21 ;THAT NO BITS
OVER2: MOVE T2,LCD ;CAN BE
OVER21: MOVEM T2,SAVE5 ;SAVED,
JUMPE T3,UU ;THEN
MOVM T1,T3 ;RETURN
CAML T1,[030400000000] ;RIGHT
JRST CALCIR ;AWAY.
FSC T3,70 ;O'E, TRY TO
FSC T0,70 ;SAVE SOME BITS
FDVRM T0,T2 ;BY MULTIPLYING
JFCL ;THE TERMS BY 2**56,
FADRB T3,T2 ;ADDING THE TERMS, AND THEN / BY 2**56.
FSC T3,-70 ;IF THE RESULT UNDERFLOWS, GO
JFCL SRX ;TO SRX, O'E GO BACK
JRST CALCIR ;TO THE MAIN ROUTINE.
OVER3: MOVE T3,T1 ;SET UP
FDVR T3,LAB ;AC 2 FOR
FSC T3,70 ;SRX. AC 2 WILL
FSC T2,70 ;CONTAIN THE TERM
FADR T2,T3 ;*(2**56).
SRX: MOVEM T5,SAVE5 ;SAVE THE CONTENTS OF AC 5.
MOVE T0,LCD ;THIS IS AN
MOVE T1,LAB ;ALTERNATE
MOVM T5,T1 ;CALCULATION TO
CAMGE T5,ONE ;CALC34, AND TAKES
JRST SRX2 ;ADVANTAGE OF
FMPR T1,T2 ;THE FACT THAT HERE
MOVM T5,T0 ;DENOM CONTAINS 1.0.
CAML T5,ONE ;THE ORDER OF
JRST SRY ;CALCULATION
FSC T0,70 ;DEPENDS
FDVRM T1,T0 ;ON THE SIZE OF
JRST SETSN2 ;THE TERMS. AFTER
SRY: FDVRM T1,T0 ;THE CALCULATION A
FSC T0,-70 ;TRANSFER
JRST SETSN2 ;IS
SRX2: FDVRM T2,T0 ;MADE
FMPR T0,T1 ;TO
FSC T0,-70 ;SETSN2
SETSN2: MOVE T5,SAVE5 ;RESTORE THE CONTENTS OF AC 5.
JRST STIR ;GO BACK TO MAIN ROUTINE.
UU: MOVEM T0,SAB ;ANOTHER ALTERNATE
MOVEM T1,SCD ;CALCULATION TO
FMPR T1,LCD ;CALC34
FMPR T0,LAB ;USED WHEN
FADR T0,T1 ;S/L FOR
JFCL UND ;BOTH SETS
FDVR T0,LCD ;HAS UNDERFLOWED
FDVR T0,LCD ;OR FOR
JRST STIR ;UNDERFLOW PLUS
UND: $LCALL 888
;LERR (888,%,Complex underflow at $1L,<T1>)
JRST STIR ;TO ADD2+3.
ONE: 201400000000
SEGMENT DATA
SAVE0: BLOCK 0
SAVE2: BLOCK 1
SAVE3: BLOCK 1
SAVE4: BLOCK 1
SAVE5: BLOCK 1
SAB: BLOCK 1
LAB: BLOCK 1
SCD: BLOCK 1
LCD: BLOCK 1
TEMP: BLOCK 1
REAL: BLOCK 1
IMAG: BLOCK 1
DENOM: BLOCK 1
PRGEND
TITLE REAL.C COMPLEX TO REAL CONVERSION
SUBTTL H. P. WEISS/HPW/CKS/CDM 17-Nov-81
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1980, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
;FROM V.005
;COMPLEX TO REAL CONVERSION FUNCTION
;THIS ROUTINE RETURNS THE REAL PART OF A COMPLEX NUMBER
;THE ROUTINE IS CALLED IN THE FOLLOWING MANNER:
; XMOVEI L,ARGLST
; PUSHJ P,REAL.C
;THE ANSWER IS RETURNED IN ACCUMULATOR A
SEARCH MTHPRM
NOSYM
SEGMENT CODE
SALL
ENTRY REAL.C
REAL.C: MOVE T0,@(L) ;GET REAL PART OF ARGUMENT
GOODBY (1) ;RETURN
PRGEND
TITLE AIMAG COMPLEX TO REAL CONVERSION
SUBTTL H. P. WEISS/HPW/CKS 28-Oct-81
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1980, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
SEARCH MTHPRM
NOSYM
ENTRY AIMAG
EXTERN AIMAG.
AIMAG=AIMAG.
PRGEND
TITLE AIMAG. COMPLEX TO REAL COVERSION
SUBTTL H. P. WEISS/HPW/CKS 28-Oct-81
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1980, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
;FROM LIB40 V.022
;FROM V.005
;COMPLEX TO IMAGINARY CONVERSION FUNCTION
;THIS ROUTINE RETURNS THE IMAGINARY PART OF A COMPLEX NUMBER
;THE ROUTINE IS CALLED IN THE FOLLOWING MANNER:
; XMOVEI L,ARGLST
; PUSHJ P,AIMAG.
;THE ANSWER IS RETURNED IN ACCUMULATOR T0
SEARCH MTHPRM
NOSYM
SEGMENT CODE
SALL
HELLO (AIMAG,.) ;ENTRY TO AIMAG ROUTINE
XMOVEI T1,@(L) ;PUT IMAG(ARG)
MOVE T0,1(T1) ;IN AC T0
GOODBY (1) ;RETURN
PRGEND
TITLE CONJG COMPLEX CONJUGATE FUNCTION
SUBTTL H. P. WEISS/HPW/CKS 28-Oct-81
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1980, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
SEARCH MTHPRM
NOSYM
ENTRY CONJG
EXTERN CONJG.
CONJG=CONJG.
PRGEND
TITLE CONJG. COMPLEX CONJUGATE FUNCTION
SUBTTL H. P. WEISS/HPW/CKS 28-Oct-81
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1980, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
;FROM LIB40 V.022
;COMPLEX CONJUGATE FUNCTION
;THIS ROUTINE CALCULATES THE COMPLEX CONJUGATE OF ITS ARGUMENT
;THE REAL PART OF THE ANSWER IS LEFT IN ACCUMULATOR T0, AND THE
;IMAGINARY PART IN ACCUMULATOR T1
SEARCH MTHPRM
NOSYM
SEGMENT CODE
SALL
HELLO (CONJG,.) ;ENTRY TO CONJG ROUTINE
DMOVE T0,@(L) ;GET COMPLEX ARGUMENT
MOVN T1,T1 ;NEGATE IMAGINARY PART
GOODBY ;RETURN
PRGEND
TITLE CMPLX REAL TO COMPLEX CONVERSION
SUBTTL H. P. WEISS/HPW/CKS 28-Oct-81
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1980, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
SEARCH MTHPRM
NOSYM
ENTRY CMPLX
EXTERN CMPLX.
CMPLX=CMPLX.
PRGEND
TITLE CMPLX. REAL TO COMPLEX CONVERSION
SUBTTL H. P. WEISS/HPW/CKS 28-Oct-81
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1980, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
;FROM LIB40 V.022
;REAL TO COMPLEX CONVERSION FUNCTION
;THIS ROUTINE CONVERTS TWO REAL ARGUMENTS TO A COMPLEX NUMBER
;OF THE FORM ARG1+I*ARG2
;THE ROUTINE IS CALLED IN THE FOLLOWING MANNER:
; MOVEI L,ARG
; PUSHJ P,CMPLX
;THE REAL PART OF THE ANSWER IS LEFT IN ACCUMULATOR A, AND THE
;IMAGINARY PART IS LEFT IN ACCUMULATOR B
SEARCH MTHPRM
NOSYM
SEGMENT CODE
SALL
HELLO (CMPLX,.) ;ENTRY TO CMPLX ROUTINE
MOVE T0,@(L) ;GET REAL PART OF COMPLEX ANSWER
MOVE T1,@1(L) ;GET IMAGINARY PART OF COMPLEX ANS
GOODBY (2) ;RETURN
PRGEND
TITLE CMPL.C Conversion from complexes to complex
SUBTTL C. McCutcheon - 28-Oct-81
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1981, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
; Fortran Instrinsic Function to return a complex number for
; two complex numbers passed to it.
; From ANSI-77 standard:
; CMPLX(A1,A2) is the complex value whose real part is REAL(A1)
; and whose imaginary part is REAL(A2).
; Required (called) routines: SNG.0, SNG.2
SEARCH MTHPRM
SALL
SEGMENT CODE
SALL
HELLO (CMPL.C,.) ;Enter routine
MOVE T0,@(L) ;Real half.
MOVE T1,@1(L) ;Imaginary half
GOODBYE ;Return
PRGEND
TITLE CMPL.D Conversion from double prec to complex
SUBTTL C. McCutcheon - 28-Oct-81
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1981, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
; Fortran Instrinsic Function to return a complex number for
; two double precision numbers passed to it.
; Required (called) routines: SNG.0, SNG.2
SEARCH MTHPRM
SALL
SEGMENT CODE
SALL
EXTERN SNG.0 ;Located in
EXTERN SNG.2 ; FORDBL.MAC
HELLO (CMPL.D,.) ;Enter routine
PUSH P,T2 ;Save Ac's
PUSH P,T3
DMOVE T0,@(L) ;Real half.
PUSHJ P,SNG.0 ;Round DP to Real.
DMOVE T2,@1(L) ;Imaginary half.
PUSHJ P,SNG.2 ;Round DP to Real.
;(There is no SNG.1 for optimizing ac's)
MOVE T1,T2 ;Set up complex #.
POP P,T3 ;Restore AC's.
POP P,T2
GOODBYE ;Return
PRGEND
TITLE CMPL.G Conversion from gfloating to complex
SUBTTL Randy Meyers -- Created by Edit [3201] 17-May-82
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1981, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
; Fortran Instrinsic Function to return a complex number for
; two gfloating numbers passed to it.
SEARCH MTHPRM
SALL
SEGMENT CODE
SALL
HELLO (CMPL.G,.) ;Enter routine
PUSH P,T2 ;Save Ac
DMOVE T0,@0(L) ;Real half.
EXTEND T0,[GSNGL T0] ;Round gfloating to Real.
DMOVE T1,@1(L) ;Imaginary half.
EXTEND T1,[GSNGL T1] ;Round gfloating to Real.
POP P,T2 ;Restore AC.
GOODBYE ;Return
PRGEND
TITLE CMPL.I Conversion from integers to complex
SUBTTL C. McCutcheon - 28-Oct-81
;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1981, 1983
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
;TRANSFERRED.
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
;AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
; Fortran Instrinsic Function to return a complex number for
; two integer numbers passed to it.
SEARCH MTHPRM
SALL
SEGMENT CODE
SALL
HELLO (CMPL.I,.) ;Enter routine
MOVE T0,@(L) ;Real half
MOVE T1,@1(L) ;Imaginary half
FLTR T0,T0 ;Convert to
FLTR T1,T1 ; real
GOODBYE ;Return
END