Google
 

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