xref: /netbsd-src/external/gpl3/gdb/dist/sim/common/sim-bits.h (revision 88241920d21b339bf319c0e979ffda80c49a2936)
14e98e3e1Schristos /* The common simulator framework for GDB, the GNU Debugger.
24e98e3e1Schristos 
3*88241920Schristos    Copyright 2002-2024 Free Software Foundation, Inc.
44e98e3e1Schristos 
54e98e3e1Schristos    Contributed by Andrew Cagney and Red Hat.
64e98e3e1Schristos 
74e98e3e1Schristos    This file is part of GDB.
84e98e3e1Schristos 
94e98e3e1Schristos    This program is free software; you can redistribute it and/or modify
104e98e3e1Schristos    it under the terms of the GNU General Public License as published by
114e98e3e1Schristos    the Free Software Foundation; either version 3 of the License, or
124e98e3e1Schristos    (at your option) any later version.
134e98e3e1Schristos 
144e98e3e1Schristos    This program is distributed in the hope that it will be useful,
154e98e3e1Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
164e98e3e1Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
174e98e3e1Schristos    GNU General Public License for more details.
184e98e3e1Schristos 
194e98e3e1Schristos    You should have received a copy of the GNU General Public License
204e98e3e1Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
214e98e3e1Schristos 
224e98e3e1Schristos 
23212397c6Schristos #ifndef SIM_BITS_H
24212397c6Schristos #define SIM_BITS_H
254e98e3e1Schristos 
264e98e3e1Schristos 
274e98e3e1Schristos /* Bit manipulation routines:
284e98e3e1Schristos 
294e98e3e1Schristos    Bit numbering: The bits are numbered according to the target ISA's
304e98e3e1Schristos    convention.  That being controlled by WITH_TARGET_WORD_MSB.  For
314e98e3e1Schristos    the PowerPC (WITH_TARGET_WORD_MSB == 0) the numbering is 0..31
324e98e3e1Schristos    while for the MIPS (WITH_TARGET_WORD_MSB == 31) it is 31..0.
334e98e3e1Schristos 
344e98e3e1Schristos    Size convention: Each macro is in three forms - <MACRO>32 which
354e98e3e1Schristos    operates in 32bit quantity (bits are numbered 0..31); <MACRO>64
364e98e3e1Schristos    which operates using 64bit quantites (and bits are numbered 0..63);
374e98e3e1Schristos    and <MACRO> which operates using the bit size of the target
384e98e3e1Schristos    architecture (bits are still numbered 0..63), with 32bit
394e98e3e1Schristos    architectures ignoring the first 32bits leaving bit 32 as the most
404e98e3e1Schristos    significant.
414e98e3e1Schristos 
424e98e3e1Schristos    NB: Use EXTRACTED, MSEXTRACTED and LSEXTRACTED as a guideline for
434e98e3e1Schristos    naming.  LSMASK and LSMASKED are wrong.
444e98e3e1Schristos 
454e98e3e1Schristos    BIT*(POS): `*' bit constant with just 1 bit set.
464e98e3e1Schristos 
474e98e3e1Schristos    LSBIT*(OFFSET): `*' bit constant with just 1 bit set - LS bit is
484e98e3e1Schristos    zero.
494e98e3e1Schristos 
504e98e3e1Schristos    MSBIT*(OFFSET): `*' bit constant with just 1 bit set - MS bit is
514e98e3e1Schristos    zero.
524e98e3e1Schristos 
534e98e3e1Schristos    MASK*(FIRST, LAST): `*' bit constant with bits [FIRST .. LAST]
544e98e3e1Schristos    set. The <MACRO> (no size) version permits FIRST >= LAST and
554e98e3e1Schristos    generates a wrapped bit mask vis ([0..LAST] | [FIRST..LSB]).
564e98e3e1Schristos 
574e98e3e1Schristos    LSMASK*(FIRST, LAST): Like MASK - LS bit is zero.
584e98e3e1Schristos 
594e98e3e1Schristos    MSMASK*(FIRST, LAST): Like MASK - LS bit is zero.
604e98e3e1Schristos 
614e98e3e1Schristos    MASKED*(VALUE, FIRST, LAST): Masks out all but bits [FIRST
624e98e3e1Schristos    .. LAST].
634e98e3e1Schristos 
644e98e3e1Schristos    LSMASKED*(VALUE, FIRST, LAST): Like MASKED - LS bit is zero.
654e98e3e1Schristos 
664e98e3e1Schristos    MSMASKED*(VALUE, FIRST, LAST): Like MASKED - MS bit is zero.
674e98e3e1Schristos 
684e98e3e1Schristos    EXTRACTED*(VALUE, FIRST, LAST): Masks out bits [FIRST .. LAST] but
694e98e3e1Schristos    also right shifts the masked value so that bit LAST becomes the
704e98e3e1Schristos    least significant (right most).
714e98e3e1Schristos 
724e98e3e1Schristos    LSEXTRACTED*(VALUE, FIRST, LAST): Same as extracted - LS bit is
734e98e3e1Schristos    zero.
744e98e3e1Schristos 
754e98e3e1Schristos    MSEXTRACTED*(VALUE, FIRST, LAST): Same as extracted - MS bit is
764e98e3e1Schristos    zero.
774e98e3e1Schristos 
784e98e3e1Schristos    SHUFFLED**(VALUE, OLD, NEW): Mask then move a single bit from OLD
794e98e3e1Schristos    new NEW.
804e98e3e1Schristos 
814e98e3e1Schristos    MOVED**(VALUE, OLD_FIRST, OLD_LAST, NEW_FIRST, NEW_LAST): Moves
824e98e3e1Schristos    things around so that bits OLD_FIRST..OLD_LAST are masked then
834e98e3e1Schristos    moved to NEW_FIRST..NEW_LAST.
844e98e3e1Schristos 
854e98e3e1Schristos    INSERTED*(VALUE, FIRST, LAST): Takes VALUE and `inserts' the (LAST
864e98e3e1Schristos    - FIRST + 1) least significant bits into bit positions [ FIRST
874e98e3e1Schristos    .. LAST ].  This is almost the complement to EXTRACTED.
884e98e3e1Schristos 
894e98e3e1Schristos    IEA_MASKED(SHOULD_MASK, ADDR): Convert the address to the targets
904e98e3e1Schristos    natural size.  If in 32bit mode, discard the high 32bits.
914e98e3e1Schristos 
924e98e3e1Schristos    EXTEND*(VALUE): Convert the `*' bit value to the targets natural
934e98e3e1Schristos    word size.  Sign extend the value if needed.
944e98e3e1Schristos 
954b169a6bSchristos    align_*(VALUE, BYTES): Round the value so that it is aligned to a
964b169a6bSchristos    BYTES boundary.
974e98e3e1Schristos 
984e98e3e1Schristos    ROT*(VALUE, NR_BITS): Return the `*' bit VALUE rotated by NR_BITS
994e98e3e1Schristos    right (positive) or left (negative).
1004e98e3e1Schristos 
1014e98e3e1Schristos    ROTL*(VALUE, NR_BITS): Return the `*' bit value rotated by NR_BITS
1024e98e3e1Schristos    left.  0 <= NR_BITS <= `*'.
1034e98e3e1Schristos 
1044e98e3e1Schristos    ROTR*(VALUE, NR_BITS): Return the `*' bit value rotated by NR_BITS
1054e98e3e1Schristos    right.  0 <= NR_BITS <= N.
1064e98e3e1Schristos 
1074e98e3e1Schristos    SEXT*(VALUE, SIGN_BIT): Treat SIGN_BIT as VALUEs sign, extend it ti
1084e98e3e1Schristos    `*' bits.
1094e98e3e1Schristos 
1104e98e3e1Schristos    Note: Only the BIT* and MASK* macros return a constant that can be
1114e98e3e1Schristos    used in variable declarations.
1124e98e3e1Schristos 
1134e98e3e1Schristos    */
1144e98e3e1Schristos 
1154e98e3e1Schristos 
1164e98e3e1Schristos /* compute the number of bits between START and STOP */
1174e98e3e1Schristos 
1184e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
1194e98e3e1Schristos #define _MAKE_WIDTH(START, STOP) (STOP - START + 1)
1204e98e3e1Schristos #else
1214e98e3e1Schristos #define _MAKE_WIDTH(START, STOP) (START - STOP + 1)
1224e98e3e1Schristos #endif
1234e98e3e1Schristos 
1244e98e3e1Schristos 
1254e98e3e1Schristos 
1264e98e3e1Schristos /* compute the number shifts required to move a bit between LSB (MSB)
1274e98e3e1Schristos    and POS */
1284e98e3e1Schristos 
1294e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
1304e98e3e1Schristos #define _LSB_SHIFT(WIDTH, POS) (WIDTH - 1 - POS)
1314e98e3e1Schristos #else
1324e98e3e1Schristos #define _LSB_SHIFT(WIDTH, POS) (POS)
1334e98e3e1Schristos #endif
1344e98e3e1Schristos 
1354e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
1364e98e3e1Schristos #define _MSB_SHIFT(WIDTH, POS) (POS)
1374e98e3e1Schristos #else
1384e98e3e1Schristos #define _MSB_SHIFT(WIDTH, POS) (WIDTH - 1 - POS)
1394e98e3e1Schristos #endif
1404e98e3e1Schristos 
1414e98e3e1Schristos 
1424e98e3e1Schristos /* compute the absolute bit position given the OFFSET from the MSB(LSB)
1434e98e3e1Schristos    NB: _MAKE_xxx_POS (WIDTH, _MAKE_xxx_SHIFT (WIDTH, POS)) == POS */
1444e98e3e1Schristos 
1454e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
1464e98e3e1Schristos #define _MSB_POS(WIDTH, SHIFT) (SHIFT)
1474e98e3e1Schristos #else
1484e98e3e1Schristos #define _MSB_POS(WIDTH, SHIFT) (WIDTH - 1 - SHIFT)
1494e98e3e1Schristos #endif
1504e98e3e1Schristos 
1514e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
1524e98e3e1Schristos #define _LSB_POS(WIDTH, SHIFT) (WIDTH - 1 - SHIFT)
1534e98e3e1Schristos #else
1544e98e3e1Schristos #define _LSB_POS(WIDTH, SHIFT) (SHIFT)
1554e98e3e1Schristos #endif
1564e98e3e1Schristos 
1574e98e3e1Schristos 
1584e98e3e1Schristos /* convert a 64 bit position into a corresponding 32bit position. MSB
1594e98e3e1Schristos    pos handles the posibility that the bit lies beyond the 32bit
1604e98e3e1Schristos    boundary */
1614e98e3e1Schristos 
1624e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
1634e98e3e1Schristos #define _MSB_32(START, STOP) (START <= STOP \
1644e98e3e1Schristos 			      ? (START < 32 ? 0 : START - 32) \
1654e98e3e1Schristos 			      : (STOP < 32 ? 0 : STOP - 32))
1664e98e3e1Schristos #define _MSB_16(START, STOP) (START <= STOP \
1674e98e3e1Schristos 			      ? (START < 48 ? 0 : START - 48) \
1684e98e3e1Schristos 			      : (STOP < 48 ? 0 : STOP - 48))
1694e98e3e1Schristos #else
1704e98e3e1Schristos #define _MSB_32(START, STOP) (START >= STOP \
1714e98e3e1Schristos 			      ? (START >= 32 ? 31 : START) \
1724e98e3e1Schristos 			      : (STOP >= 32 ? 31 : STOP))
1734e98e3e1Schristos #define _MSB_16(START, STOP) (START >= STOP \
1744e98e3e1Schristos 			      ? (START >= 16 ? 15 : START) \
1754e98e3e1Schristos 			      : (STOP >= 16 ? 15 : STOP))
1764e98e3e1Schristos #endif
1774e98e3e1Schristos 
1784e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
1794e98e3e1Schristos #define _LSB_32(START, STOP) (START <= STOP \
1804e98e3e1Schristos 			      ? (STOP < 32 ? 0 : STOP - 32) \
1814e98e3e1Schristos 			      : (START < 32 ? 0 : START - 32))
1824e98e3e1Schristos #define _LSB_16(START, STOP) (START <= STOP \
1834e98e3e1Schristos 			      ? (STOP < 48 ? 0 : STOP - 48) \
1844e98e3e1Schristos 			      : (START < 48 ? 0 : START - 48))
1854e98e3e1Schristos #else
1864e98e3e1Schristos #define _LSB_32(START, STOP) (START >= STOP \
1874e98e3e1Schristos 			      ? (STOP >= 32 ? 31 : STOP) \
1884e98e3e1Schristos 			      : (START >= 32 ? 31 : START))
1894e98e3e1Schristos #define _LSB_16(START, STOP) (START >= STOP \
1904e98e3e1Schristos 			      ? (STOP >= 16 ? 15 : STOP) \
1914e98e3e1Schristos 			      : (START >= 16 ? 15 : START))
1924e98e3e1Schristos #endif
1934e98e3e1Schristos 
1944e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
1954e98e3e1Schristos #define _MSB(START, STOP) (START <= STOP ? START : STOP)
1964e98e3e1Schristos #else
1974e98e3e1Schristos #define _MSB(START, STOP) (START >= STOP ? START : STOP)
1984e98e3e1Schristos #endif
1994e98e3e1Schristos 
2004e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
2014e98e3e1Schristos #define _LSB(START, STOP) (START <= STOP ? STOP : START)
2024e98e3e1Schristos #else
2034e98e3e1Schristos #define _LSB(START, STOP) (START >= STOP ? STOP : START)
2044e98e3e1Schristos #endif
2054e98e3e1Schristos 
2064e98e3e1Schristos 
2074e98e3e1Schristos /* LS/MS Bit operations */
2084e98e3e1Schristos 
2094b169a6bSchristos #define LSBIT8(POS)  ((uint8_t) 1 << (POS))
2104b169a6bSchristos #define LSBIT16(POS) ((uint16_t)1 << (POS))
2114b169a6bSchristos #define LSBIT32(POS) ((uint32_t)1 << (POS))
2124b169a6bSchristos #define LSBIT64(POS) ((uint64_t)1 << (POS))
2134e98e3e1Schristos 
2144e98e3e1Schristos #if (WITH_TARGET_WORD_BITSIZE == 64)
2154e98e3e1Schristos #define LSBIT(POS) LSBIT64 (POS)
2164e98e3e1Schristos #endif
2174e98e3e1Schristos #if (WITH_TARGET_WORD_BITSIZE == 32)
2184b169a6bSchristos #define LSBIT(POS) ((uint32_t)((POS) >= 32 \
2194e98e3e1Schristos 		                 ? 0 \
2204e98e3e1Schristos 			         : (1 << ((POS) >= 32 ? 0 : (POS)))))
2214e98e3e1Schristos #endif
2224e98e3e1Schristos #if (WITH_TARGET_WORD_BITSIZE == 16)
2234b169a6bSchristos #define LSBIT(POS) ((uint16_t)((POS) >= 16 \
2244e98e3e1Schristos 		                 ? 0 \
2254e98e3e1Schristos 			         : (1 << ((POS) >= 16 ? 0 : (POS)))))
2264e98e3e1Schristos #endif
2274e98e3e1Schristos 
2284e98e3e1Schristos 
2294b169a6bSchristos #define MSBIT8(POS)  ((uint8_t) 1 << ( 8 - 1 - (POS)))
2304b169a6bSchristos #define MSBIT16(POS) ((uint16_t)1 << (16 - 1 - (POS)))
2314b169a6bSchristos #define MSBIT32(POS) ((uint32_t)1 << (32 - 1 - (POS)))
2324b169a6bSchristos #define MSBIT64(POS) ((uint64_t)1 << (64 - 1 - (POS)))
2334e98e3e1Schristos 
2344e98e3e1Schristos #if (WITH_TARGET_WORD_BITSIZE == 64)
2354e98e3e1Schristos #define MSBIT(POS) MSBIT64 (POS)
2364e98e3e1Schristos #endif
2374e98e3e1Schristos #if (WITH_TARGET_WORD_BITSIZE == 32)
2384b169a6bSchristos #define MSBIT(POS) ((uint32_t)((POS) < 32 \
2394e98e3e1Schristos 		                 ? 0 \
2404e98e3e1Schristos 		                 : (1 << ((POS) < 32 ? 0 : (64 - 1) - (POS)))))
2414e98e3e1Schristos #endif
2424e98e3e1Schristos #if (WITH_TARGET_WORD_BITSIZE == 16)
2434b169a6bSchristos #define MSBIT(POS) ((uint16_t)((POS) < 48 \
2444e98e3e1Schristos 		                 ? 0 \
2454e98e3e1Schristos 		                 : (1 << ((POS) < 48 ? 0 : (64 - 1) - (POS)))))
2464e98e3e1Schristos #endif
2474e98e3e1Schristos 
2484e98e3e1Schristos 
2494e98e3e1Schristos /* Bit operations */
2504e98e3e1Schristos 
2514e98e3e1Schristos #define BIT4(POS)  (1 << _LSB_SHIFT (4, (POS)))
2524e98e3e1Schristos #define BIT5(POS)  (1 << _LSB_SHIFT (5, (POS)))
2534e98e3e1Schristos #define BIT10(POS) (1 << _LSB_SHIFT (10, (POS)))
2544e98e3e1Schristos 
2554e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
2564e98e3e1Schristos #define BIT8  MSBIT8
2574e98e3e1Schristos #define BIT16 MSBIT16
2584e98e3e1Schristos #define BIT32 MSBIT32
2594e98e3e1Schristos #define BIT64 MSBIT64
2604e98e3e1Schristos #define BIT   MSBIT
2614e98e3e1Schristos #else
2624e98e3e1Schristos #define BIT8  LSBIT8
2634e98e3e1Schristos #define BIT16 LSBIT16
2644e98e3e1Schristos #define BIT32 LSBIT32
2654e98e3e1Schristos #define BIT64 LSBIT64
2664e98e3e1Schristos #define BIT   LSBIT
2674e98e3e1Schristos #endif
2684e98e3e1Schristos 
2694e98e3e1Schristos 
2704e98e3e1Schristos 
2714e98e3e1Schristos /* multi bit mask */
2724e98e3e1Schristos 
2734e98e3e1Schristos /* 111111 -> mmll11 -> mm11ll */
2744b169a6bSchristos #define _MASKn(WIDTH, START, STOP) (((uint##WIDTH##_t)(-1) \
2754e98e3e1Schristos 				     >> (_MSB_SHIFT (WIDTH, START) \
2764e98e3e1Schristos 					 + _LSB_SHIFT (WIDTH, STOP))) \
2774e98e3e1Schristos 				    << _LSB_SHIFT (WIDTH, STOP))
2784e98e3e1Schristos 
2794e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
2804e98e3e1Schristos #define _POS_LE(START, STOP) (START <= STOP)
2814e98e3e1Schristos #else
2824e98e3e1Schristos #define _POS_LE(START, STOP) (STOP <= START)
2834e98e3e1Schristos #endif
2844e98e3e1Schristos 
2854e98e3e1Schristos #if (WITH_TARGET_WORD_BITSIZE == 64)
2864e98e3e1Schristos #define MASK(START, STOP) \
2874e98e3e1Schristos      (_POS_LE ((START), (STOP)) \
2884e98e3e1Schristos       ? _MASKn(64, \
2894e98e3e1Schristos 	       _MSB ((START), (STOP)), \
2904e98e3e1Schristos 	       _LSB ((START), (STOP)) ) \
2914e98e3e1Schristos       : (_MASKn(64, _MSB_POS (64, 0), (STOP)) \
2924e98e3e1Schristos 	 | _MASKn(64, (START), _LSB_POS (64, 0))))
2934e98e3e1Schristos #endif
2944e98e3e1Schristos #if (WITH_TARGET_WORD_BITSIZE == 32)
2954e98e3e1Schristos #define MASK(START, STOP) \
2964e98e3e1Schristos      (_POS_LE ((START), (STOP)) \
2974e98e3e1Schristos       ? (_POS_LE ((STOP), _MSB_POS (64, 31)) \
2984e98e3e1Schristos 	 ? 0 \
2994e98e3e1Schristos 	 : _MASKn (32, \
3004e98e3e1Schristos 		   _MSB_32 ((START), (STOP)), \
3014e98e3e1Schristos 		   _LSB_32 ((START), (STOP)))) \
3024e98e3e1Schristos       : (_MASKn (32, \
3034e98e3e1Schristos 		 _LSB_32 ((START), (STOP)), \
3044e98e3e1Schristos 		 _LSB_POS (32, 0)) \
3054e98e3e1Schristos 	 | (_POS_LE ((STOP), _MSB_POS (64, 31)) \
3064e98e3e1Schristos 	    ? 0 \
3074e98e3e1Schristos 	    : _MASKn (32, \
3084e98e3e1Schristos 		      _MSB_POS (32, 0), \
3094e98e3e1Schristos 		      _MSB_32 ((START), (STOP))))))
3104e98e3e1Schristos #endif
3114e98e3e1Schristos #if (WITH_TARGET_WORD_BITSIZE == 16)
3124e98e3e1Schristos #define MASK(START, STOP) \
3134e98e3e1Schristos      (_POS_LE ((START), (STOP)) \
3144e98e3e1Schristos       ? (_POS_LE ((STOP), _MSB_POS (64, 15)) \
3154e98e3e1Schristos 	 ? 0 \
3164e98e3e1Schristos 	 : _MASKn (16, \
3174e98e3e1Schristos 		   _MSB_16 ((START), (STOP)), \
3184e98e3e1Schristos 		   _LSB_16 ((START), (STOP)))) \
3194e98e3e1Schristos       : (_MASKn (16, \
3204e98e3e1Schristos 		 _LSB_16 ((START), (STOP)), \
3214e98e3e1Schristos 		 _LSB_POS (16, 0)) \
3224e98e3e1Schristos 	 | (_POS_LE ((STOP), _MSB_POS (64, 15)) \
3234e98e3e1Schristos 	    ? 0 \
3244e98e3e1Schristos 	    : _MASKn (16, \
3254e98e3e1Schristos 		      _MSB_POS (16, 0), \
3264e98e3e1Schristos 		      _MSB_16 ((START), (STOP))))))
3274e98e3e1Schristos #endif
3284e98e3e1Schristos #if !defined (MASK)
3294e98e3e1Schristos #error "MASK never undefined"
3304e98e3e1Schristos #endif
3314e98e3e1Schristos 
3324e98e3e1Schristos 
3334e98e3e1Schristos /* Multi-bit mask on least significant bits */
3344e98e3e1Schristos 
3354e98e3e1Schristos #define _LSMASKn(WIDTH, FIRST, LAST) _MASKn (WIDTH, \
3364e98e3e1Schristos 					     _LSB_POS (WIDTH, FIRST), \
3374e98e3e1Schristos 					     _LSB_POS (WIDTH, LAST))
3384e98e3e1Schristos 
3394e98e3e1Schristos #define LSMASK8(FIRST, LAST)   _LSMASKn ( 8, (FIRST), (LAST))
3404e98e3e1Schristos #define LSMASK16(FIRST, LAST)  _LSMASKn (16, (FIRST), (LAST))
3414e98e3e1Schristos #define LSMASK32(FIRST, LAST)  _LSMASKn (32, (FIRST), (LAST))
3424e98e3e1Schristos #define LSMASK64(FIRST, LAST)  _LSMASKn (64, (FIRST), (LAST))
3434e98e3e1Schristos 
3444e98e3e1Schristos #define LSMASK(FIRST, LAST) (MASK (_LSB_POS (64, FIRST), _LSB_POS (64, LAST)))
3454e98e3e1Schristos 
3464e98e3e1Schristos 
3474e98e3e1Schristos /* Multi-bit mask on most significant bits */
3484e98e3e1Schristos 
3494e98e3e1Schristos #define _MSMASKn(WIDTH, FIRST, LAST) _MASKn (WIDTH, \
3504e98e3e1Schristos 					     _MSB_POS (WIDTH, FIRST), \
3514e98e3e1Schristos 					     _MSB_POS (WIDTH, LAST))
3524e98e3e1Schristos 
3534e98e3e1Schristos #define MSMASK8(FIRST, LAST)  _MSMASKn ( 8, (FIRST), (LAST))
3544e98e3e1Schristos #define MSMASK16(FIRST, LAST) _MSMASKn (16, (FIRST), (LAST))
3554e98e3e1Schristos #define MSMASK32(FIRST, LAST) _MSMASKn (32, (FIRST), (LAST))
3564e98e3e1Schristos #define MSMASK64(FIRST, LAST) _MSMASKn (64, (FIRST), (LAST))
3574e98e3e1Schristos 
3584e98e3e1Schristos #define MSMASK(FIRST, LAST) (MASK (_MSB_POS (64, FIRST), _MSB_POS (64, LAST)))
3594e98e3e1Schristos 
3604e98e3e1Schristos 
3614e98e3e1Schristos 
3624e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
3634e98e3e1Schristos #define MASK8  MSMASK8
3644e98e3e1Schristos #define MASK16 MSMASK16
3654e98e3e1Schristos #define MASK32 MSMASK32
3664e98e3e1Schristos #define MASK64 MSMASK64
3674e98e3e1Schristos #else
3684e98e3e1Schristos #define MASK8  LSMASK8
3694e98e3e1Schristos #define MASK16 LSMASK16
3704e98e3e1Schristos #define MASK32 LSMASK32
3714e98e3e1Schristos #define MASK64 LSMASK64
3724e98e3e1Schristos #endif
3734e98e3e1Schristos 
3744e98e3e1Schristos 
3754e98e3e1Schristos 
3764e98e3e1Schristos /* mask the required bits, leaving them in place */
3774e98e3e1Schristos 
3784b169a6bSchristos INLINE_SIM_BITS(uint8_t)  LSMASKED8  (uint8_t  word, int first, int last);
3794b169a6bSchristos INLINE_SIM_BITS(uint16_t) LSMASKED16 (uint16_t word, int first, int last);
3804b169a6bSchristos INLINE_SIM_BITS(uint32_t) LSMASKED32 (uint32_t word, int first, int last);
3814b169a6bSchristos INLINE_SIM_BITS(uint64_t) LSMASKED64 (uint64_t word, int first, int last);
3824e98e3e1Schristos 
3834e98e3e1Schristos INLINE_SIM_BITS(unsigned_word) LSMASKED (unsigned_word word, int first, int last);
3844e98e3e1Schristos 
3854b169a6bSchristos INLINE_SIM_BITS(uint8_t)  MSMASKED8  (uint8_t  word, int first, int last);
3864b169a6bSchristos INLINE_SIM_BITS(uint16_t) MSMASKED16 (uint16_t word, int first, int last);
3874b169a6bSchristos INLINE_SIM_BITS(uint32_t) MSMASKED32 (uint32_t word, int first, int last);
3884b169a6bSchristos INLINE_SIM_BITS(uint64_t) MSMASKED64 (uint64_t word, int first, int last);
3894e98e3e1Schristos 
3904e98e3e1Schristos INLINE_SIM_BITS(unsigned_word) MSMASKED (unsigned_word word, int first, int last);
3914e98e3e1Schristos 
3924e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
3934e98e3e1Schristos #define MASKED8  MSMASKED8
3944e98e3e1Schristos #define MASKED16 MSMASKED16
3954e98e3e1Schristos #define MASKED32 MSMASKED32
3964e98e3e1Schristos #define MASKED64 MSMASKED64
3974e98e3e1Schristos #define MASKED   MSMASKED
3984e98e3e1Schristos #else
3994e98e3e1Schristos #define MASKED8  LSMASKED8
4004e98e3e1Schristos #define MASKED16 LSMASKED16
4014e98e3e1Schristos #define MASKED32 LSMASKED32
4024e98e3e1Schristos #define MASKED64 LSMASKED64
4034e98e3e1Schristos #define MASKED LSMASKED
4044e98e3e1Schristos #endif
4054e98e3e1Schristos 
4064e98e3e1Schristos 
4074e98e3e1Schristos 
4084e98e3e1Schristos /* extract the required bits aligning them with the lsb */
4094e98e3e1Schristos 
4104b169a6bSchristos INLINE_SIM_BITS(uint8_t)  LSEXTRACTED8  (uint8_t  val, int start, int stop);
4114b169a6bSchristos INLINE_SIM_BITS(uint16_t) LSEXTRACTED16 (uint16_t val, int start, int stop);
4124b169a6bSchristos INLINE_SIM_BITS(uint32_t) LSEXTRACTED32 (uint32_t val, int start, int stop);
4134b169a6bSchristos INLINE_SIM_BITS(uint64_t) LSEXTRACTED64 (uint64_t val, int start, int stop);
4144e98e3e1Schristos 
4154e98e3e1Schristos INLINE_SIM_BITS(unsigned_word) LSEXTRACTED (unsigned_word val, int start, int stop);
4164e98e3e1Schristos 
4174b169a6bSchristos INLINE_SIM_BITS(uint8_t)  MSEXTRACTED8  (uint8_t  val, int start, int stop);
4184b169a6bSchristos INLINE_SIM_BITS(uint16_t) MSEXTRACTED16 (uint16_t val, int start, int stop);
4194b169a6bSchristos INLINE_SIM_BITS(uint32_t) MSEXTRACTED32 (uint32_t val, int start, int stop);
4204b169a6bSchristos INLINE_SIM_BITS(uint64_t) MSEXTRACTED64 (uint64_t val, int start, int stop);
4214e98e3e1Schristos 
4224e98e3e1Schristos INLINE_SIM_BITS(unsigned_word) MSEXTRACTED (unsigned_word val, int start, int stop);
4234e98e3e1Schristos 
4244e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
4254e98e3e1Schristos #define EXTRACTED8  MSEXTRACTED8
4264e98e3e1Schristos #define EXTRACTED16 MSEXTRACTED16
4274e98e3e1Schristos #define EXTRACTED32 MSEXTRACTED32
4284e98e3e1Schristos #define EXTRACTED64 MSEXTRACTED64
4294e98e3e1Schristos #define EXTRACTED   MSEXTRACTED
4304e98e3e1Schristos #else
4314e98e3e1Schristos #define EXTRACTED8  LSEXTRACTED8
4324e98e3e1Schristos #define EXTRACTED16 LSEXTRACTED16
4334e98e3e1Schristos #define EXTRACTED32 LSEXTRACTED32
4344e98e3e1Schristos #define EXTRACTED64 LSEXTRACTED64
4354e98e3e1Schristos #define EXTRACTED   LSEXTRACTED
4364e98e3e1Schristos #endif
4374e98e3e1Schristos 
4384e98e3e1Schristos 
4394e98e3e1Schristos 
4404e98e3e1Schristos /* move a single bit around */
4414e98e3e1Schristos /* NB: the wierdness (N>O?N-O:0) is to stop a warning from GCC */
4424e98e3e1Schristos #define _SHUFFLEDn(N, WORD, OLD, NEW) \
4434e98e3e1Schristos ((OLD) < (NEW) \
4444b169a6bSchristos  ? (((uint##N##_t)(WORD) \
4454e98e3e1Schristos      >> (((NEW) > (OLD)) ? ((NEW) - (OLD)) : 0)) \
4464e98e3e1Schristos     & MASK32((NEW), (NEW))) \
4474b169a6bSchristos  : (((uint##N##_t)(WORD) \
4484e98e3e1Schristos      << (((OLD) > (NEW)) ? ((OLD) - (NEW)) : 0)) \
4494e98e3e1Schristos     & MASK32((NEW), (NEW))))
4504e98e3e1Schristos 
4514e98e3e1Schristos #define SHUFFLED32(WORD, OLD, NEW) _SHUFFLEDn (32, WORD, OLD, NEW)
4524e98e3e1Schristos #define SHUFFLED64(WORD, OLD, NEW) _SHUFFLEDn (64, WORD, OLD, NEW)
4534e98e3e1Schristos 
4544e98e3e1Schristos #define SHUFFLED(WORD, OLD, NEW) _SHUFFLEDn (_word, WORD, OLD, NEW)
4554e98e3e1Schristos 
4564e98e3e1Schristos 
4574e98e3e1Schristos /* Insert a group of bits into a bit position */
4584e98e3e1Schristos 
4594b169a6bSchristos INLINE_SIM_BITS(uint8_t)  LSINSERTED8  (uint8_t  val, int start, int stop);
4604b169a6bSchristos INLINE_SIM_BITS(uint16_t) LSINSERTED16 (uint16_t val, int start, int stop);
4614b169a6bSchristos INLINE_SIM_BITS(uint32_t) LSINSERTED32 (uint32_t val, int start, int stop);
4624b169a6bSchristos INLINE_SIM_BITS(uint64_t) LSINSERTED64 (uint64_t val, int start, int stop);
4634e98e3e1Schristos INLINE_SIM_BITS(unsigned_word) LSINSERTED (unsigned_word val, int start, int stop);
4644e98e3e1Schristos 
4654b169a6bSchristos INLINE_SIM_BITS(uint8_t)  MSINSERTED8  (uint8_t  val, int start, int stop);
4664b169a6bSchristos INLINE_SIM_BITS(uint16_t) MSINSERTED16 (uint16_t val, int start, int stop);
4674b169a6bSchristos INLINE_SIM_BITS(uint32_t) MSINSERTED32 (uint32_t val, int start, int stop);
4684b169a6bSchristos INLINE_SIM_BITS(uint64_t) MSINSERTED64 (uint64_t val, int start, int stop);
4694e98e3e1Schristos INLINE_SIM_BITS(unsigned_word) MSINSERTED (unsigned_word val, int start, int stop);
4704e98e3e1Schristos 
4714e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
4724e98e3e1Schristos #define INSERTED8  MSINSERTED8
4734e98e3e1Schristos #define INSERTED16 MSINSERTED16
4744e98e3e1Schristos #define INSERTED32 MSINSERTED32
4754e98e3e1Schristos #define INSERTED64 MSINSERTED64
4764e98e3e1Schristos #define INSERTED   MSINSERTED
4774e98e3e1Schristos #else
4784e98e3e1Schristos #define INSERTED8  LSINSERTED8
4794e98e3e1Schristos #define INSERTED16 LSINSERTED16
4804e98e3e1Schristos #define INSERTED32 LSINSERTED32
4814e98e3e1Schristos #define INSERTED64 LSINSERTED64
4824e98e3e1Schristos #define INSERTED   LSINSERTED
4834e98e3e1Schristos #endif
4844e98e3e1Schristos 
4854e98e3e1Schristos 
4864e98e3e1Schristos 
4874e98e3e1Schristos /* MOVE bits from one loc to another (combination of extract/insert) */
4884e98e3e1Schristos 
4894e98e3e1Schristos #define MOVED8(VAL,OH,OL,NH,NL)  INSERTED8 (EXTRACTED8 ((VAL), OH, OL), NH, NL)
4904e98e3e1Schristos #define MOVED16(VAL,OH,OL,NH,NL) INSERTED16(EXTRACTED16((VAL), OH, OL), NH, NL)
4914e98e3e1Schristos #define MOVED32(VAL,OH,OL,NH,NL) INSERTED32(EXTRACTED32((VAL), OH, OL), NH, NL)
4924e98e3e1Schristos #define MOVED64(VAL,OH,OL,NH,NL) INSERTED64(EXTRACTED64((VAL), OH, OL), NH, NL)
4934e98e3e1Schristos #define MOVED(VAL,OH,OL,NH,NL)   INSERTED  (EXTRACTED  ((VAL), OH, OL), NH, NL)
4944e98e3e1Schristos 
4954e98e3e1Schristos 
4964e98e3e1Schristos 
4974e98e3e1Schristos /* Sign extend the quantity to the targets natural word size */
4984e98e3e1Schristos 
4994e98e3e1Schristos #define EXTEND4(X)  (LSSEXT ((X), 3))
5004e98e3e1Schristos #define EXTEND5(X)  (LSSEXT ((X), 4))
501ba340e45Schristos #define EXTEND6(X)  (LSSEXT ((X), 5))
5024b169a6bSchristos #define EXTEND8(X)  ((signed_word)(int8_t)(X))
5034b169a6bSchristos #define EXTEND9(X)  (LSSEXT ((X), 8))
5044e98e3e1Schristos #define EXTEND11(X)  (LSSEXT ((X), 10))
505ba340e45Schristos #define EXTEND12(X)  (LSSEXT ((X), 11))
5064e98e3e1Schristos #define EXTEND15(X)  (LSSEXT ((X), 14))
5074b169a6bSchristos #define EXTEND16(X) ((signed_word)(int16_t)(X))
5084b169a6bSchristos #define EXTEND18(X)  (LSSEXT ((X), 17))
5094b169a6bSchristos #define EXTEND19(X)  (LSSEXT ((X), 18))
5104b169a6bSchristos #define EXTEND21(X)  (LSSEXT ((X), 20))
5114e98e3e1Schristos #define EXTEND24(X)  (LSSEXT ((X), 23))
512ba340e45Schristos #define EXTEND25(X)  (LSSEXT ((X), 24))
5134b169a6bSchristos #define EXTEND26(X)  (LSSEXT ((X), 25))
5144b169a6bSchristos #define EXTEND32(X) ((signed_word)(int32_t)(X))
5154b169a6bSchristos #define EXTEND64(X) ((signed_word)(int64_t)(X))
5164e98e3e1Schristos 
5174e98e3e1Schristos /* depending on MODE return a 64bit or 32bit (sign extended) value */
5184e98e3e1Schristos #if (WITH_TARGET_WORD_BITSIZE == 64)
5194b169a6bSchristos #define EXTENDED(X)     ((int64_t)(int32_t)(X))
5204e98e3e1Schristos #endif
5214e98e3e1Schristos #if (WITH_TARGET_WORD_BITSIZE == 32)
5224e98e3e1Schristos #define EXTENDED(X)     (X)
5234e98e3e1Schristos #endif
5244e98e3e1Schristos #if (WITH_TARGET_WORD_BITSIZE == 16)
5254e98e3e1Schristos #define EXTENDED(X)     (X)
5264e98e3e1Schristos #endif
5274e98e3e1Schristos 
5284e98e3e1Schristos 
5294e98e3e1Schristos /* memory alignment macro's */
5304b169a6bSchristos #define align_up(v, n)		(((v) + (n) - 1) & -(n))
5314b169a6bSchristos #define align_down(v, n)	((v) & -(n))
5324e98e3e1Schristos 
5334e98e3e1Schristos 
5344e98e3e1Schristos /* bit bliting macro's */
5354e98e3e1Schristos #define BLIT32(V, POS, BIT) \
5364e98e3e1Schristos do { \
5374e98e3e1Schristos   if (BIT) \
5384e98e3e1Schristos     V |= BIT32 (POS); \
5394e98e3e1Schristos   else \
5404e98e3e1Schristos     V &= ~BIT32 (POS); \
5414e98e3e1Schristos } while (0)
5424e98e3e1Schristos #define MBLIT32(V, LO, HI, VAL) \
5434e98e3e1Schristos do { \
5444e98e3e1Schristos   (V) = (((V) & ~MASK32 ((LO), (HI))) \
5454e98e3e1Schristos 	 | INSERTED32 (VAL, LO, HI)); \
5464e98e3e1Schristos } while (0)
5474e98e3e1Schristos 
5484e98e3e1Schristos 
5494e98e3e1Schristos 
5504e98e3e1Schristos /* some rotate functions.  The generic macro's ROT, ROTL, ROTR are
5514e98e3e1Schristos    intentionally omited. */
5524e98e3e1Schristos 
5534e98e3e1Schristos 
5544b169a6bSchristos INLINE_SIM_BITS(uint8_t)  ROT8  (uint8_t  val, int shift);
5554b169a6bSchristos INLINE_SIM_BITS(uint16_t) ROT16 (uint16_t val, int shift);
5564b169a6bSchristos INLINE_SIM_BITS(uint32_t) ROT32 (uint32_t val, int shift);
5574b169a6bSchristos INLINE_SIM_BITS(uint64_t) ROT64 (uint64_t val, int shift);
5584e98e3e1Schristos 
5594e98e3e1Schristos 
5604b169a6bSchristos INLINE_SIM_BITS(uint8_t)  ROTL8  (uint8_t  val, int shift);
5614b169a6bSchristos INLINE_SIM_BITS(uint16_t) ROTL16 (uint16_t val, int shift);
5624b169a6bSchristos INLINE_SIM_BITS(uint32_t) ROTL32 (uint32_t val, int shift);
5634b169a6bSchristos INLINE_SIM_BITS(uint64_t) ROTL64 (uint64_t val, int shift);
5644e98e3e1Schristos 
5654e98e3e1Schristos 
5664b169a6bSchristos INLINE_SIM_BITS(uint8_t)  ROTR8  (uint8_t  val, int shift);
5674b169a6bSchristos INLINE_SIM_BITS(uint16_t) ROTR16 (uint16_t val, int shift);
5684b169a6bSchristos INLINE_SIM_BITS(uint32_t) ROTR32 (uint32_t val, int shift);
5694b169a6bSchristos INLINE_SIM_BITS(uint64_t) ROTR64 (uint64_t val, int shift);
5704e98e3e1Schristos 
5714e98e3e1Schristos 
5724e98e3e1Schristos 
5734e98e3e1Schristos /* Sign extension operations */
5744e98e3e1Schristos 
5754b169a6bSchristos INLINE_SIM_BITS(uint8_t)  LSSEXT8  (int8_t  val, int sign_bit);
5764b169a6bSchristos INLINE_SIM_BITS(uint16_t) LSSEXT16 (int16_t val, int sign_bit);
5774b169a6bSchristos INLINE_SIM_BITS(uint32_t) LSSEXT32 (int32_t val, int sign_bit);
5784b169a6bSchristos INLINE_SIM_BITS(uint64_t) LSSEXT64 (int64_t val, int sign_bit);
5794e98e3e1Schristos INLINE_SIM_BITS(unsigned_word) LSSEXT (signed_word val, int sign_bit);
5804e98e3e1Schristos 
5814b169a6bSchristos INLINE_SIM_BITS(uint8_t)  MSSEXT8  (int8_t  val, int sign_bit);
5824b169a6bSchristos INLINE_SIM_BITS(uint16_t) MSSEXT16 (int16_t val, int sign_bit);
5834b169a6bSchristos INLINE_SIM_BITS(uint32_t) MSSEXT32 (int32_t val, int sign_bit);
5844b169a6bSchristos INLINE_SIM_BITS(uint64_t) MSSEXT64 (int64_t val, int sign_bit);
5854e98e3e1Schristos INLINE_SIM_BITS(unsigned_word) MSSEXT (signed_word val, int sign_bit);
5864e98e3e1Schristos 
5874e98e3e1Schristos #if (WITH_TARGET_WORD_MSB == 0)
5884e98e3e1Schristos #define SEXT8  MSSEXT8
5894e98e3e1Schristos #define SEXT16 MSSEXT16
5904e98e3e1Schristos #define SEXT32 MSSEXT32
5914e98e3e1Schristos #define SEXT64 MSSEXT64
5924e98e3e1Schristos #define SEXT   MSSEXT
5934e98e3e1Schristos #else
5944e98e3e1Schristos #define SEXT8  LSSEXT8
5954e98e3e1Schristos #define SEXT16 LSSEXT16
5964e98e3e1Schristos #define SEXT32 LSSEXT32
5974e98e3e1Schristos #define SEXT64 LSSEXT64
5984e98e3e1Schristos #define SEXT   LSSEXT
5994e98e3e1Schristos #endif
6004e98e3e1Schristos 
6014e98e3e1Schristos 
6024e98e3e1Schristos 
6034e98e3e1Schristos #if H_REVEALS_MODULE_P (SIM_BITS_INLINE)
6044e98e3e1Schristos #include "sim-bits.c"
6054e98e3e1Schristos #endif
6064e98e3e1Schristos 
607212397c6Schristos #endif /* SIM_BITS_H */
608