/* The common simulator framework for GDB, the GNU Debugger.

   Copyright 2002-2022 Free Software Foundation, Inc.

   Contributed by Andrew Cagney and Red Hat.

   This file is part of GDB.

   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 3 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, see <http://www.gnu.org/licenses/>.  */


#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 XCONCAT3(uint,N,_t)
#define signedN XCONCAT3(int,N,_t)
#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
