 # Ralf Dentzer, 24.2.93
 # DigitType  DigitVecMultAdd (res, a, m, l)
 #			      $4, $5, $6, $7
 #	DigitType *res, *a, m;
 #	int l;
 #     /*	res[0..l-1] += a[0..l-1]*m; return CARRY;   */
 #     /* Special function for multiple digit multiplication */
 # {	Digit_t carry=0, tmp, tmp2,    accu, aa;
 #		$3, 	      $11-$12, $8,   $14
 #	if (l==0)
 #		return 0;
 #	tmp=*a * m;
 #	l--;
 #	a++;
 #	aa=*a;
 #	accu = *res;
 #       for ( ; l>0; l--) {
 #		tmp2=tmp;
 #		tmp=aa*m;
 #		a++;
 #		aa=*a;
 #		accu += tmp2;
 #		carry += (accu < tmp2);
 #		*res ++ = accu;
 #		accu = *res + carry;
 #		carry = (accu < carry);
 #	}
 #	accu+=tmp;
 #	carry+=(accu<tmp);
 #	*res=accu;
 #	return carry;
 #} 
	.text

        .set    noreorder

	.globl	DigitVecMultAdd
	.ent	DigitVecMultAdd
DigitVecMultAdd:
        .frame  $sp, 0, $31
	lw	$14, 0($5)		# aa=*a;
	bne	$7, 0, $32		# if (l==0)
	move	$3, $0			# carry=0;	DELAY
	j	$31			# return
	move	$2, $0			# 0;		DELAY
$32:
	multu	$14, $6			# tmp=aa * m;
	addu	$7, $7, -1		# l--;
	addu	$5, $5, 4		# a++;
	ble	$7, 0, $34		# for ( ; l>0; l--) {
	lw	$8, 0($4)		# accu = *res;	DELAY
$33:
	lw	$14, 0($5)		# aa=*a;
	mflo	$11			#
	mfhi	$12			# tmp2=tmp;
	addu	$5, $5, 4		# a++;
	addu	$8, $8, $11		# accu+=LOW(tmp2);
	multu	$14, $6			# tmp=aa*m;
	sltu	$15, $8, $11		# (accu < LOW(tmp2))
	addu	$3, $3, $15		# carry += (accu < LOW(tmp2));
	sw	$8, 0($4)		# *res=accu;
	addu	$4, $4, 4		# res++;
	lw	$24, 0($4)		# *res
	addu	$3, $3, $12		# carry += HIGH(tmp2);
	addu	$7, $7, -1		# l--;
	addu	$8, $24, $3		# accu = *res + carry;
	bgt	$7, 0, $33		# } for ( ; l>0; l--)
	sltu	$3, $8, $3		# carry = (accu < carry); DELAY
$34:
	mflo	$11
	mfhi	$12
	addu	$8, $8, $11		# accu+=LOW(tmp);
	sltu	$25, $8, $11		# (accu<LOW(tmp));
	addu	$3, $3, $25		# carry += (accu < LOW(tmp));
	sw	$8, 0($4)		# *res=accu;
	j	$31			# return
	addu	$2, $3, $12		# carry + HIGH(tmp);

	.end	DigitVecMultAdd

        .set    reorder
