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