/*
 * |-----------------------------------------------------------|
 * | Copyright (c) 1991 MIPS Computer Systems, Inc.            |
 * | All Rights Reserved                                       |
 * |-----------------------------------------------------------|
 * |          Restricted Rights Legend                         |
 * | Use, duplication, or disclosure by the Government is      |
 * | subject to restrictions as set forth in                   |
 * | subparagraph (c)(1)(ii) of the Rights in Technical        |
 * | Data and Computer Software Clause of DFARS 52.227-7013.   |
 * |         MIPS Computer Systems, Inc.                       |
 * |         950 DeGuigne Drive                                |
 * |         Sunnyvale, CA 94086                               |
 * |-----------------------------------------------------------|
 */
/* $Header: llshifti.c,v 1.3.2.1 92/06/24 13:59:27 marker Exp $ */

#include <limits.h>
#define bitsperword WORD_BIT
#include "lldefs.h"

/* shift routines */

extern longlong_t
__ll_lshifti (longlong_t left, int right)
{
	llvalue a, r;

	a.ll = left;
	if (right < 0) {
		return __ll_rshifti(left, -right);
	} else if (right >= bitsperword*2) {
		/* right > 64, so everything shifted out */
		return (longlong_t) 0;
	} else if (right >= bitsperword) {
		/* everything shifted to msw */
		r.dw.msw = a.dw.lsw << (right - bitsperword);
		r.dw.lsw = 0;
	} else if (right > 0) {
		/* lsw shifted, then msw combines lsw and msw */
		r.dw.msw = (a.dw.msw << right) 
			| (a.dw.lsw >> (bitsperword - right));
		r.dw.lsw = a.dw.lsw << right;
	} else {
		/* right == 0 */
		return left;
	}
	return r.ll;
}

extern longlong_t
__ll_rshifti (longlong_t left, int right)
{
	llvalue a, r;

	a.ll = left;
	if (right < 0) {
		return __ll_lshifti (left, -right);
	} else if (right >= bitsperword*2) {
		/* right > 64, so everything shifted out */
		return (longlong_t) 0;
	} else if (right >= bitsperword) {
		/* everything shifted to lsw */
		r.dw.lsw = a.dw.msw >> (right - bitsperword);
		r.dw.msw = 0;
	} else if (right > 0) {
                /* msw shifted, then lsw combines lsw and msw */
		r.dw.lsw = (a.dw.lsw >> right) 
			| (a.dw.msw << (bitsperword - right));
		r.dw.msw = a.dw.msw >> right;
	} else {
		/* right == 0 */
		return left;
	}
	return r.ll;
}

