| /* The common simulator framework for GDB, the GNU Debugger. |
| |
| Copyright 2002-2021 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 _SIM_BITS_C_ |
| #define _SIM_BITS_C_ |
| |
| /* This must come before any other includes. */ |
| #include "defs.h" |
| |
| #include "sim-basics.h" |
| #include "sim-assert.h" |
| #include "sim-io.h" |
| |
| |
| INLINE_SIM_BITS\ |
| (unsigned_word) |
| LSMASKED (unsigned_word val, |
| int start, |
| int stop) |
| { |
| /* NOTE - start, stop can wrap */ |
| val &= LSMASK (start, stop); |
| return val; |
| } |
| |
| |
| INLINE_SIM_BITS\ |
| (unsigned_word) |
| MSMASKED (unsigned_word val, |
| int start, |
| int stop) |
| { |
| /* NOTE - start, stop can wrap */ |
| val &= MSMASK (start, stop); |
| return val; |
| } |
| |
| |
| INLINE_SIM_BITS\ |
| (unsigned_word) |
| LSEXTRACTED (unsigned_word val, |
| int start, |
| int stop) |
| { |
| ASSERT (start >= stop); |
| #if (WITH_TARGET_WORD_BITSIZE == 64) |
| return LSEXTRACTED64 (val, start, stop); |
| #endif |
| #if (WITH_TARGET_WORD_BITSIZE == 32) |
| if (stop >= 32) |
| return 0; |
| else |
| { |
| if (start < 32) |
| val &= LSMASK (start, 0); |
| val >>= stop; |
| return val; |
| } |
| #endif |
| #if (WITH_TARGET_WORD_BITSIZE == 16) |
| if (stop >= 16) |
| return 0; |
| else |
| { |
| if (start < 16) |
| val &= LSMASK (start, 0); |
| val >>= stop; |
| return val; |
| } |
| #endif |
| } |
| |
| |
| INLINE_SIM_BITS\ |
| (unsigned_word) |
| MSEXTRACTED (unsigned_word val, |
| int start, |
| int stop) |
| { |
| ASSERT (start <= stop); |
| #if (WITH_TARGET_WORD_BITSIZE == 64) |
| return MSEXTRACTED64 (val, start, stop); |
| #endif |
| #if (WITH_TARGET_WORD_BITSIZE == 32) |
| if (stop < 32) |
| return 0; |
| else |
| { |
| if (start >= 32) |
| val &= MSMASK (start, 64 - 1); |
| val >>= (64 - stop - 1); |
| return val; |
| } |
| #endif |
| #if (WITH_TARGET_WORD_BITSIZE == 16) |
| if (stop < 16) |
| return 0; |
| else |
| { |
| if (start >= 16) |
| val &= MSMASK (start, 64 - 1); |
| val >>= (64 - stop - 1); |
| return val; |
| } |
| #endif |
| } |
| |
| |
| INLINE_SIM_BITS\ |
| (unsigned_word) |
| LSINSERTED (unsigned_word val, |
| int start, |
| int stop) |
| { |
| ASSERT (start >= stop); |
| #if (WITH_TARGET_WORD_BITSIZE == 64) |
| return LSINSERTED64 (val, start, stop); |
| #endif |
| #if (WITH_TARGET_WORD_BITSIZE == 32) |
| /* Bit numbers are 63..0, even for 32 bit targets. |
| On 32 bit targets we ignore 63..32 */ |
| if (stop >= 32) |
| return 0; |
| else |
| { |
| val <<= stop; |
| val &= LSMASK (start, stop); |
| return val; |
| } |
| #endif |
| #if (WITH_TARGET_WORD_BITSIZE == 16) |
| /* Bit numbers are 63..0, even for 16 bit targets. |
| On 16 bit targets we ignore 63..16 */ |
| if (stop >= 16) |
| return 0; |
| else |
| { |
| val <<= stop; |
| val &= LSMASK (start, stop); |
| return val; |
| } |
| #endif |
| } |
| |
| INLINE_SIM_BITS\ |
| (unsigned_word) |
| MSINSERTED (unsigned_word val, |
| int start, |
| int stop) |
| { |
| ASSERT (start <= stop); |
| #if (WITH_TARGET_WORD_BITSIZE == 64) |
| return MSINSERTED64 (val, start, stop); |
| #endif |
| #if (WITH_TARGET_WORD_BITSIZE == 32) |
| /* Bit numbers are 0..63, even for 32 bit targets. |
| On 32 bit targets we ignore 0..31. */ |
| if (stop < 32) |
| return 0; |
| else |
| { |
| val <<= ((64 - 1) - stop); |
| val &= MSMASK (start, stop); |
| return val; |
| } |
| #endif |
| #if (WITH_TARGET_WORD_BITSIZE == 16) |
| /* Bit numbers are 0..63, even for 16 bit targets. |
| On 16 bit targets we ignore 0..47. */ |
| if (stop < 32 + 16) |
| return 0; |
| else |
| { |
| val <<= ((64 - 1) - stop); |
| val &= MSMASK (start, stop); |
| return val; |
| } |
| #endif |
| } |
| |
| |
| |
| INLINE_SIM_BITS\ |
| (unsigned_word) |
| LSSEXT (signed_word val, |
| int sign_bit) |
| { |
| ASSERT (sign_bit < 64); |
| #if (WITH_TARGET_WORD_BITSIZE == 64) |
| return LSSEXT64 (val, sign_bit); |
| #endif |
| #if (WITH_TARGET_WORD_BITSIZE == 32) |
| if (sign_bit >= 32) |
| return val; |
| else { |
| val = LSSEXT32 (val, sign_bit); |
| return val; |
| } |
| #endif |
| #if (WITH_TARGET_WORD_BITSIZE == 16) |
| if (sign_bit >= 16) |
| return val; |
| else { |
| val = LSSEXT16 (val, sign_bit); |
| return val; |
| } |
| #endif |
| } |
| |
| INLINE_SIM_BITS\ |
| (unsigned_word) |
| MSSEXT (signed_word val, |
| int sign_bit) |
| { |
| ASSERT (sign_bit < 64); |
| #if (WITH_TARGET_WORD_BITSIZE == 64) |
| return MSSEXT64 (val, sign_bit); |
| #endif |
| #if (WITH_TARGET_WORD_BITSIZE == 32) |
| if (sign_bit < 32) |
| return val; |
| else { |
| val = MSSEXT32 (val, sign_bit - 32); |
| return val; |
| } |
| #endif |
| #if (WITH_TARGET_WORD_BITSIZE == 16) |
| if (sign_bit < 32 + 16) |
| return val; |
| else { |
| val = MSSEXT16 (val, sign_bit - 32 - 16); |
| return val; |
| } |
| #endif |
| } |
| |
| |
| |
| #define N 8 |
| #include "sim-n-bits.h" |
| #undef N |
| |
| #define N 16 |
| #include "sim-n-bits.h" |
| #undef N |
| |
| #define N 32 |
| #include "sim-n-bits.h" |
| #undef N |
| |
| #define N 64 |
| #include "sim-n-bits.h" |
| #undef N |
| |
| #endif /* _SIM_BITS_C_ */ |