; ; mullib.a52 ; ; A multiplication library for the CS52 Machine. ; ; Rett Bull ; Pomona College ; February 3, 2016 ; ; ; SEE ALSO: divrlib.a52 and divilib.a52 for recursive ; and iterative division routines. ; ; USAGE: Word values are interpreted as signed integers. ; ; One argument (call it X) is on the stack and another ; argument (Y) is in r3. ; ; The function mlmul leaves X*Y in r3, and X remains ; unchanged on the stack. More precisely, the routine ; leaves the low-order word of X*Y in r3. ; ; ; LABEL CONVENTION: The entry point is mlmul. To avoid ; conflicts with other programs, all local labels start ; with libm. ; ; ; MULTIPLICATION: Essentially, we are doing elementary ; school multiplication in binary. It requires that ; the multiplier Y is non-negative. We will end up with ; the low 16 bits of X*Y. ; ; mlmul(X,Y) { ; if (Y < 0) { ; X = -X; ; Y = -Y; ; } ; P = 0; ; while (Y != 0) { ; if (Y & 1 == 1) ; P += X; ; X = X << 1; ; Y = Y >> 1; ; } ; return P; ; } ; ; X is always in r2 ; Y and P share r3 ; Temporary storage is allocated on the stack, with Y ; on top and P below it. ; ; mlmul ;;; prolog psh r2 ; push the return address psh r0 ; push initial value of P loa r2 r1 6 ; fetch initial value of X ;;; make sure the signs are correct bge r3 r0 libmpos ; test the sign of Y neg r2 r2 ; change sign of X neg r3 r3 ; change sign of Y libmpos ;;; get ready for the loop beq r3 r0 libmdone ; if Y = 0, we are finished psh r3 ; push Y libmloop ;;; the body of the loop and r3 r3 1 ; test low bit of Y, beq r3 r0 libmnadd ; and skip adding if it is 0 loa r3 r1 4 ; fetch P add r3 r3 r2 ; add X to P sto r3 r1 4 ; save P libmnadd loa r3 r1 2 ; recover Y slr r3 r3 1 ; shift Y right (logical shift, why?) sto r3 r1 2 ; store Y back again sal r2 r2 1 ; shift X left bne r3 r0 libmloop ; go back for more if Y != 0 pop r0 ; discard temporary Y libmdone ;;; postscript pop r3 ; get the result P pop r2 ; recover the return address jmp r2 ; return to the caller