static char rcsid[] = "$Header:mlsb.c 12.0$";
/* Copyright (c) 1982, Regents, University of California */

struct vl	{ long high; long low; };
long
mlsb(utop,ubot,vtop,nqhat)
register long *utop, *ubot, *vtop;
register nqhat;
{
	register handy, carry;
	struct vl work;
	
	for(carry = 0; utop >= ubot; utop--) {
		emul(nqhat,*--vtop,carry+*utop,&work);
		carry = work.high;
		handy = work.low;
		*utop = handy & 0x3fffffff;
		carry <<= 2;
		if(handy & 0x80000000) carry += 2;
		if(handy & 0x40000000) carry += 1;
	}
	return(carry);
}
long
adback(utop,ubot,vtop)
register long *utop, *ubot, *vtop;
{
	register handy, carry;
	carry = 0;
	for(; utop >= ubot; utop--) {
		carry += *--vtop;
		carry += *utop;
		*utop = carry & 0x3fffffff;
		/* next junk is faster version of  carry >>= 30; */
		handy = carry;
		carry = 0;
		if(handy & 0x80000000) carry -= 2;
		if(handy & 0x40000000) carry += 1;
	}
	return(carry);
}
long dsdiv(top,bot,div)
register long *top, *bot;
register long div;
{
	struct vl work; char err;
	register long handy, carry = 0;
	for(carry = 0;bot <= top; bot++) {
		handy = *bot;
		if(carry & 1) handy |= 0x40000000;
		if(carry & 2) handy |= 0x80000000;
		carry >>= 2;
		work.low = handy;
		work.high = carry;
		*bot = ediv(&work,div,&err);
		carry = work.high;
	}
	return(carry);
}
dsadd1(top,bot)
long *top, *bot;
{
	register long *p, work, carry = 0;

	/*
	 * this assumes canonical inputs
	 */
	for(p = top; p >= bot; p--) {
		work = *p + carry;
		*p = work & 0x3fffffff;
		carry = 0;
		if (work & 0x40000000) carry += 1;
		if (work & 0x80000000) carry -= 2;
	}
	p[1] = work;
}
long
dsrsh(top,bot,ncnt,mask1)
long *top, *bot;
long ncnt, mask1;
{
	register long *p = bot;
	register r = -ncnt, l = 30+ncnt, carry = 0, work, save;
	long mask = -1 ^ mask1;

	while(p <= top) {
		save = work = *p; save &= mask; work >>= r;
		carry <<= l; work |= carry; *p++ = work;
		carry = save;
	}
	return(carry);
}
