 # Integer Version 2.1, RD, 3.5.93, Mips       idigitvecmultsub.s
 # 
 # DigitType  DigitVecMultSub (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 division */
 # {	Digit_t carry=0, tmp, tmp2,    accu, aa, accu2;
 #		$3, 	      $11-$12, $8,   $14, $15
 #	if (l==0)
 #		return 0;
 #	tmp=*a * m;
 #	l--;
 #	a++;
 #	aa=*a;
 #      for ( ; l>0; l--) {
 #		tmp2=tmp;
 #		tmp=aa*m;
 #		a++;
 #		aa=*a;
 #		accu = tmp2+carry;
 #		carry = (accu < carry); /* + HIGH(tmp2) */
 #		accu2 = *res - accu;
 #		carry += (*res < accu2);
 #		*res ++ = accu;
 #	}
 #	accu=tmp + carry;
 #	carry=(accu<tmp);	/* +HIGH(tmp) */
 #	accu2 = *res - accu;
 #	carry += (*res < accu2);

 #	*res=accu2;
 #	return carry;
 #} 

 #	*res++=accu2;
 #	accu = *res - carry;
 #	carry = (*res < accu);
 #	*res = accu;
 #	return carry;
 #} 

	.text

        .set    noreorder

	.globl	DigitVecMultSub
	.ent	DigitVecMultSub
DigitVecMultSub:
        .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--;
	lw	$15, 0($4)		# accu2 = *res;
	ble	$7, 0, $34		# for ( ; l>0; l--) {
	addu	$5, $5, 4		# a++;		DELAY
$33:
	lw	$14, 0($5)		# aa=*a;
	mflo	$11			#
	mfhi	$12			# tmp2=tmp;
	addu	$5, $5, 4		# a++;
	addu	$8, $3, $11		# accu=carry + LOW(tmp2);
	multu	$14, $6			# tmp=aa*m;
	sltu	$3, $8, $3		# carry=(accu < carry);
	addu	$3, $3, $12		# carry += HIGH(tmp2);
	subu	$8, $15, $8		# accu = *res - accu;
	sw	$8, 0($4)		# *res=accu;
	addu	$4, $4, 4		# res++;
	sltu	$11, $15, $8		# (*res < accu)
	addu	$3, $3, $11		# carry += (*res < accu);
	addu	$7, $7, -1		# l--;
	bgt	$7, 0, $33		# } for ( ; l>0; l--)
	lw	$15, 0($4)		# accu2 = *res;
$34:
	mflo	$11
	mfhi	$12
	addu	$8, $3, $11		# accu=carry + LOW(tmp);
	sltu	$3, $8, $3		# carry=(accu<carry);
	addu	$3, $3, $12		# carry += HIGH(tmp2);
	subu	$8, $15, $8		# accu = *res - accu;
	sltu	$11, $15, $8		# (*res < accu)
	sw	$8, 0($4)		# *res=accu;
	j	$31			# return
	addu	$2, $3, $11		# carry += (*res (alt) < accu);

	.end	DigitVecMultSub

        .set    reorder

