/*  This file is part of the program psim.

    Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au>
    Copyright (C) 1997, Free Software Foundation, Inc.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
    */


#ifndef N
#error "N must be #defined"
#endif

#include "symcat.h"

#if defined(__STDC__) && defined(signed)
/* If signed were defined to be say __signed (ie, some versions of Linux),
   then the signedN macro would not work correctly.  If we have a standard
   compiler, we have signed.  */
#undef signed
#endif

/* NOTE: See end of file for #undef */
#define unsignedN XCONCAT2(unsigned,N)
#define signedN XCONCAT2(signed,N)
#define LSMASKn XCONCAT2(LSMASK,N)
#define MSMASKn XCONCAT2(MSMASK,N)
#define LSMASKEDn XCONCAT2(LSMASKED,N)
#define MSMASKEDn XCONCAT2(MSMASKED,N)
#define LSEXTRACTEDn XCONCAT2(LSEXTRACTED,N)
#define MSEXTRACTEDn XCONCAT2(MSEXTRACTED,N)
#define LSINSERTEDn XCONCAT2(LSINSERTED,N)
#define MSINSERTEDn XCONCAT2(MSINSERTED,N)
#define ROTn XCONCAT2(ROT,N)
#define ROTLn XCONCAT2(ROTL,N)
#define ROTRn XCONCAT2(ROTR,N)
#define MSSEXTn XCONCAT2(MSSEXT,N)
#define LSSEXTn XCONCAT2(LSSEXT,N)

/* TAGS: LSMASKED16 LSMASKED32 LSMASKED64 */

INLINE_SIM_BITS\
(unsignedN)
LSMASKEDn (unsignedN word,
	   int start,
	   int stop)
{
  word &= LSMASKn (start, stop);
  return word;
}

/* TAGS: MSMASKED16 MSMASKED32 MSMASKED64 */

INLINE_SIM_BITS\
(unsignedN)
MSMASKEDn (unsignedN word,
	   int start,
	   int stop)
{
  word &= MSMASKn (start, stop);
  return word;
}

/* TAGS: LSEXTRACTED16 LSEXTRACTED32 LSEXTRACTED64 */

INLINE_SIM_BITS\
(unsignedN)
LSEXTRACTEDn (unsignedN val,
	      int start,
	      int stop)
{
  val <<= (N - 1 - start); /* drop high bits */
  val >>= (N - 1 - start) + (stop); /* drop low bits */
  return val;
}

/* TAGS: MSEXTRACTED16 MSEXTRACTED32 MSEXTRACTED64 */

INLINE_SIM_BITS\
(unsignedN)
MSEXTRACTEDn (unsignedN val,
	      int start,
	      int stop)
{
  val <<= (start); /* drop high bits */
  val >>= (start) + (N - 1 - stop); /* drop low bits */
  return val;
}

/* TAGS: LSINSERTED16 LSINSERTED32 LSINSERTED64 */

INLINE_SIM_BITS\
(unsignedN)
LSINSERTEDn (unsignedN val,
	     int start,
	     int stop)
{
  val <<= stop;
  val &= LSMASKn (start, stop);
  return val;
}

/* TAGS: MSINSERTED16 MSINSERTED32 MSINSERTED64 */

INLINE_SIM_BITS\
(unsignedN)
MSINSERTEDn (unsignedN val,
	     int start,
	     int stop)
{
  val <<= ((N - 1) - stop);
  val &= MSMASKn (start, stop);
  return val;
}

/* TAGS: ROT16 ROT32 ROT64 */

INLINE_SIM_BITS\
(unsignedN)
ROTn (unsignedN val,
      int shift)
{
  if (shift > 0)
    return ROTRn (val, shift);
  else if (shift < 0)
    return ROTLn (val, -shift);
  else
    return val;
}

/* TAGS: ROTL16 ROTL32 ROTL64 */

INLINE_SIM_BITS\
(unsignedN)
ROTLn (unsignedN val,
       int shift)
{
  unsignedN result;
  ASSERT (shift <= N);
  result = (((val) << (shift)) | ((val) >> ((N)-(shift))));
  return result;
}

/* TAGS: ROTR16 ROTR32 ROTR64 */

INLINE_SIM_BITS\
(unsignedN)
ROTRn (unsignedN val,
       int shift)
{
  unsignedN result;
  ASSERT (shift <= N);
  result = (((val) >> (shift)) | ((val) << ((N)-(shift))));
  return result;
}

/* TAGS: LSSEXT16 LSSEXT32 LSSEXT64 */

INLINE_SIM_BITS\
(unsignedN)
LSSEXTn (signedN val,
	 int sign_bit)
{
  int shift;
  /* make the sign-bit most significant and then smear it back into
     position */
  ASSERT (sign_bit < N);
  shift = ((N - 1) - sign_bit);
  val <<= shift;
  val >>= shift;
  return val;
}

/* TAGS: MSSEXT16 MSSEXT32 MSSEXT64 */

INLINE_SIM_BITS\
(unsignedN)
MSSEXTn (signedN val,
	 int sign_bit)
{
  /* make the sign-bit most significant and then smear it back into
     position */
  ASSERT (sign_bit < N);
  val <<= sign_bit;
  val >>= sign_bit;
  return val;
}


/* NOTE: See start of file for #define */
#undef LSSEXTn
#undef MSSEXTn
#undef ROTLn
#undef ROTRn
#undef ROTn
#undef LSINSERTEDn
#undef MSINSERTEDn
#undef LSEXTRACTEDn
#undef MSEXTRACTEDn
#undef LSMASKEDn
#undef LSMASKn
#undef MSMASKEDn
#undef MSMASKn
#undef signedN
#undef unsignedN
