Web pdp-10.trailing-edge.com

Trailing-Edge - PDP-10 Archives - decuslib10-04 - 43,50325/muldiv.b11
There are no other files named muldiv.b11 in the archive.
```! File:   MULDIV.B11
!
!    This work was supported by the Advanced Research
!    Projects Agency of the Office of the Secretary of
!    Defense (F44620-73-C-0074) and is monitored by the
!    Air Force Office of Scientific Research.

MODULE MULDIV=
BEGIN

%<  The BLISS-11 out of line multiply, divide, and mod routines  >%

! Both multiply and divide operations are defined only on
! signed, two's complement integers.  The multiply routine uses
! the time-honored "shift and add" algorithm, terminating when
! either the multiplier or the multiplicand becomes zero.  The
! divide/mod routine uses a "shift and subtract" algorithm
! after first converting the operands to positive values and
! remembering the signs.  Sign of the quotient is determined by
! the rules of algebra.  The MOD operator is defined here as
! the remainder after division, and the sign of the result is
! made the same as that of the dividend (consistent with
! PDP-11/45 hardware divide definition).
!
!					December 1972
!					R. Johnsson

GLOBAL ROUTINE MUL(XA,XB)=
BEGIN
REGISTER S,A,B;
S_0;
A_.XA;  B_.XB;
WHILE 1 DO
BEGIN
IF .B THEN S_.S+.A;
IF (A_.A*2) EQL 0 THEN EXITLOOP;
IF (B_.B/2) EQL 0 THEN EXITLOOP;
END;
.S
END;

ROUTINE DIVMOD(S,R,RET,W)=
! W=0 for DIV, 1 for MOD
! RET is the return address for DIVR or MODR
!
! This routine returns .A/.B or .A MOD .B, sample values are:
!
!	 4 /  3 =  1	 4 MOD  3 =  1
!	-4 / -3 =  1	-4 MOD -3 = -1
!	-4 /  3 = -1	-4 MOD  3 = -1
!	 4 / -3 = -1	 4 MOD -3 =  1
!
! In general, B*(A/B) + (A MOD B) = A
!
BEGIN
LOCAL ANEG,BNEG,C;
REGISTER Q,A,B;
IF (A_.S) EQL 0 THEN RETURN 0;
IF (B_.R) EQL 0 THEN RETURN 0;
ANEG_BNEG_0;
IF .A LSS 0 THEN (A_-.A; ANEG_.ANEG+1);
IF .B LSS 0 THEN (B_-.B; BNEG_.BNEG+1);
C_0;
UNTIL .B GEQ .A OR .B<14,1> DO (B_.B*2; C_.C+1);
Q_0;
WHILE 1 DO
BEGIN
Q_.Q*2;
IF .B LEQ .A THEN (Q_.Q+1; IF (A_.A-.B) EQL 0 THEN EXITLOOP);
IF (C_.C-1) LSS 0 THEN EXITLOOP;
B_.B/2;
END;
IF .W NEQ 0 THEN (IF .ANEG NEQ 0 THEN A_-.A; RETURN .A);
IF .ANEG NEQ .BNEG THEN Q_-.Q;
UNTIL (C_.C-1) LSS 0 DO Q_.Q*2;
.Q
END;

GLOBAL ROUTINE DIVR=DIVMOD(0);

GLOBAL ROUTINE MODR=DIVMOD(.PC);

END
```