1 1.1 christos /* Memory ops header for CGEN-based simulators. 2 1.1.1.11 christos Copyright (C) 1996-2024 Free Software Foundation, Inc. 3 1.1 christos Contributed by Cygnus Solutions. 4 1.1 christos 5 1.1 christos This file is part of the GNU Simulators. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.1 christos #ifndef CGEN_MEM_H 21 1.1 christos #define CGEN_MEM_H 22 1.1 christos 23 1.1.1.11 christos #include "symcat.h" 24 1.1.1.11 christos 25 1.1.1.5 christos /* TODO: This should get moved into sim-inline.h. */ 26 1.1 christos #ifdef MEMOPS_DEFINE_INLINE 27 1.1 christos #define MEMOPS_INLINE 28 1.1 christos #else 29 1.1.1.5 christos #define MEMOPS_INLINE EXTERN_INLINE 30 1.1 christos #endif 31 1.1 christos 32 1.1 christos /* Integer memory read support. 33 1.1 christos 34 1.1 christos There is no floating point support. In this context there are no 35 1.1 christos floating point modes, only floating point operations (whose arguments 36 1.1 christos and results are arrays of bits that we treat as integer modes). */ 37 1.1 christos 38 1.1.1.10 christos #define DECLARE_GETMEM_EXTERN(mode, size) \ 39 1.1.1.10 christos extern mode XCONCAT2 (GETMEM,mode) (SIM_CPU *, IADDR, ADDR); 40 1.1.1.10 christos 41 1.1 christos #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) 42 1.1 christos #define DECLARE_GETMEM(mode, size) \ 43 1.1.1.10 christos DECLARE_GETMEM_EXTERN (mode, size) \ 44 1.1 christos MEMOPS_INLINE mode \ 45 1.1 christos XCONCAT2 (GETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a) \ 46 1.1 christos { \ 47 1.1 christos PROFILE_COUNT_READ (cpu, a, XCONCAT2 (MODE_,mode)); \ 48 1.1 christos /* Don't read anything into "unaligned" here. Bad name choice. */\ 49 1.1 christos return XCONCAT2 (sim_core_read_unaligned_,size) (cpu, pc, read_map, a); \ 50 1.1 christos } 51 1.1 christos #else 52 1.1.1.10 christos #define DECLARE_GETMEM(mode, size) DECLARE_GETMEM_EXTERN (mode, size) 53 1.1 christos #endif 54 1.1 christos 55 1.1 christos DECLARE_GETMEM (QI, 1) /* TAGS: GETMEMQI */ 56 1.1 christos DECLARE_GETMEM (UQI, 1) /* TAGS: GETMEMUQI */ 57 1.1 christos DECLARE_GETMEM (HI, 2) /* TAGS: GETMEMHI */ 58 1.1 christos DECLARE_GETMEM (UHI, 2) /* TAGS: GETMEMUHI */ 59 1.1 christos DECLARE_GETMEM (SI, 4) /* TAGS: GETMEMSI */ 60 1.1 christos DECLARE_GETMEM (USI, 4) /* TAGS: GETMEMUSI */ 61 1.1 christos DECLARE_GETMEM (DI, 8) /* TAGS: GETMEMDI */ 62 1.1 christos DECLARE_GETMEM (UDI, 8) /* TAGS: GETMEMUDI */ 63 1.1 christos 64 1.1 christos #undef DECLARE_GETMEM 65 1.1.1.10 christos #undef DECLARE_GETMEM_EXTERN 66 1.1 christos 67 1.1 christos /* Integer memory write support. */ 69 1.1.1.10 christos 70 1.1.1.10 christos #define DECLARE_SETMEM_EXTERN(mode, size) \ 71 1.1.1.10 christos extern void XCONCAT2 (SETMEM,mode) (SIM_CPU *, IADDR, ADDR, mode); 72 1.1 christos 73 1.1 christos #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) 74 1.1.1.10 christos #define DECLARE_SETMEM(mode, size) \ 75 1.1 christos DECLARE_SETMEM_EXTERN (mode, size) \ 76 1.1 christos MEMOPS_INLINE void \ 77 1.1 christos XCONCAT2 (SETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a, mode val) \ 78 1.1 christos { \ 79 1.1 christos PROFILE_COUNT_WRITE (cpu, a, XCONCAT2 (MODE_,mode)); \ 80 1.1 christos /* Don't read anything into "unaligned" here. Bad name choice. */ \ 81 1.1 christos XCONCAT2 (sim_core_write_unaligned_,size) (cpu, pc, write_map, a, val); \ 82 1.1 christos } 83 1.1.1.10 christos #else 84 1.1 christos #define DECLARE_SETMEM(mode, size) DECLARE_SETMEM_EXTERN (mode, size) 85 1.1 christos #endif 86 1.1 christos 87 1.1 christos DECLARE_SETMEM (QI, 1) /* TAGS: SETMEMQI */ 88 1.1 christos DECLARE_SETMEM (UQI, 1) /* TAGS: SETMEMUQI */ 89 1.1 christos DECLARE_SETMEM (HI, 2) /* TAGS: SETMEMHI */ 90 1.1 christos DECLARE_SETMEM (UHI, 2) /* TAGS: SETMEMUHI */ 91 1.1 christos DECLARE_SETMEM (SI, 4) /* TAGS: SETMEMSI */ 92 1.1 christos DECLARE_SETMEM (USI, 4) /* TAGS: SETMEMUSI */ 93 1.1 christos DECLARE_SETMEM (DI, 8) /* TAGS: SETMEMDI */ 94 1.1 christos DECLARE_SETMEM (UDI, 8) /* TAGS: SETMEMUDI */ 95 1.1 christos 96 1.1.1.10 christos #undef DECLARE_SETMEM 97 1.1 christos #undef DECLARE_SETMEM_EXTERN 98 1.1 christos 99 1.1 christos /* Instruction read support. */ 101 1.1.1.10 christos 102 1.1.1.10 christos #define DECLARE_GETIMEM_EXTERN(mode, size) \ 103 1.1 christos extern mode XCONCAT2 (GETIMEM,mode) (SIM_CPU *, ADDR); 104 1.1 christos 105 1.1.1.10 christos #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) 106 1.1 christos #define DECLARE_GETIMEM(mode, size) \ 107 1.1 christos DECLARE_GETIMEM_EXTERN (mode, size) \ 108 1.1 christos MEMOPS_INLINE mode \ 109 1.1 christos XCONCAT2 (GETIMEM,mode) (SIM_CPU *cpu, IADDR a) \ 110 1.1 christos { \ 111 1.1 christos /*PROFILE_COUNT_READ (cpu, a, XCONCAT2 (MODE_,mode));*/ \ 112 1.1 christos /* Don't read anything into "unaligned" here. Bad name choice. */\ 113 1.1 christos return XCONCAT2 (sim_core_read_unaligned_,size) (cpu, a, exec_map, a); \ 114 1.1.1.10 christos } 115 1.1 christos #else 116 1.1 christos #define DECLARE_GETIMEM(mode, size) DECLARE_GETIMEM_EXTERN (mode, size) 117 1.1 christos #endif 118 1.1 christos 119 1.1 christos DECLARE_GETIMEM (UQI, 1) /* TAGS: GETIMEMUQI */ 120 1.1 christos DECLARE_GETIMEM (UHI, 2) /* TAGS: GETIMEMUHI */ 121 1.1 christos DECLARE_GETIMEM (USI, 4) /* TAGS: GETIMEMUSI */ 122 1.1 christos DECLARE_GETIMEM (UDI, 8) /* TAGS: GETIMEMUDI */ 123 1.1.1.10 christos 124 1.1 christos #undef DECLARE_GETIMEM 125 1.1 christos #undef DECLARE_GETIMEM_EXTERN 126 1.1 christos 127 1.1 christos /* Floating point support. 129 1.1 christos 130 1.1 christos ??? One can specify that the integer memory ops should be used instead, 131 1.1 christos and treat fp values as just a series of bits. One might even bubble 132 1.1 christos that notion up into the description language. However, that departs from 133 1.1 christos gcc. One could cross over from gcc's notion and a "series of bits" notion 134 1.1 christos between there and here, and thus still not require these routines. However, 135 1.1.1.10 christos that's a complication of its own (not that having these fns isn't). 136 1.1.1.10 christos But for now, we do things this way. */ 137 1.1.1.10 christos 138 1.1 christos #define DECLARE_GETMEM_EXTERN(mode, size) \ 139 1.1 christos extern mode XCONCAT2 (GETMEM,mode) (SIM_CPU *, IADDR, ADDR); 140 1.1.1.10 christos 141 1.1 christos #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) 142 1.1 christos #define DECLARE_GETMEM(mode, size) \ 143 1.1 christos DECLARE_GETMEM_EXTERN (mode, size) \ 144 1.1 christos MEMOPS_INLINE mode \ 145 1.1 christos XCONCAT2 (GETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a) \ 146 1.1 christos { \ 147 1.1 christos PROFILE_COUNT_READ (cpu, a, XCONCAT2 (MODE_,mode)); \ 148 1.1 christos /* Don't read anything into "unaligned" here. Bad name choice. */\ 149 1.1.1.10 christos return XCONCAT2 (sim_core_read_unaligned_,size) (cpu, pc, read_map, a); \ 150 1.1 christos } 151 1.1 christos #else 152 1.1 christos #define DECLARE_GETMEM(mode, size) DECLARE_GETMEM_EXTERN (mode, size) 153 1.1 christos #endif 154 1.1 christos 155 1.1 christos DECLARE_GETMEM (SF, 4) /* TAGS: GETMEMSF */ 156 1.1.1.10 christos DECLARE_GETMEM (DF, 8) /* TAGS: GETMEMDF */ 157 1.1.1.10 christos 158 1.1.1.10 christos #undef DECLARE_GETMEM 159 1.1.1.10 christos #undef DECLARE_GETMEM_EXTERN 160 1.1 christos 161 1.1 christos #define DECLARE_SETMEM_EXTERN(mode, size) \ 162 1.1 christos extern void XCONCAT2 (SETMEM,mode) (SIM_CPU *, IADDR, ADDR, mode); 163 1.1.1.10 christos 164 1.1 christos #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) 165 1.1 christos #define DECLARE_SETMEM(mode, size) \ 166 1.1 christos DECLARE_SETMEM_EXTERN (mode, size) \ 167 1.1 christos MEMOPS_INLINE void \ 168 1.1 christos XCONCAT2 (SETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a, mode val) \ 169 1.1 christos { \ 170 1.1 christos PROFILE_COUNT_WRITE (cpu, a, XCONCAT2 (MODE_,mode)); \ 171 1.1 christos /* Don't read anything into "unaligned" here. Bad name choice. */ \ 172 1.1.1.10 christos XCONCAT2 (sim_core_write_unaligned_,size) (cpu, pc, write_map, a, val); \ 173 1.1 christos } 174 1.1 christos #else 175 1.1 christos #define DECLARE_SETMEM(mode, size) DECLARE_SETMEM_EXTERN (mode, size 176 1.1 christos #endif 177 1.1 christos 178 1.1 christos DECLARE_SETMEM (SF, 4) /* TAGS: SETMEMSF */ 179 1.1.1.10 christos DECLARE_SETMEM (DF, 8) /* TAGS: SETMEMDF */ 180 1.1 christos 181 1.1 christos #undef DECLARE_SETMEM 182 1.1 christos #undef DECLARE_SETMEM_EXTERN 183 1.1 christos 184 1.1 christos /* GETT<mode>: translate target value at P to host value. 186 1.1.1.10 christos This needn't be very efficient (i.e. can call memcpy) as this is 187 1.1.1.10 christos only used when interfacing with the outside world (e.g. gdb). */ 188 1.1 christos 189 1.1 christos #define DECLARE_GETT_EXTERN(mode, size) \ 190 1.1.1.10 christos extern mode XCONCAT2 (GETT,mode) (const unsigned char *); 191 1.1 christos 192 1.1.1.10 christos #if defined (MEMOPS_DEFINE_INLINE) 193 1.1 christos #define DECLARE_GETT(mode, size) \ 194 1.1 christos DECLARE_GETT_EXTERN (mode, size) \ 195 1.1 christos mode \ 196 1.1 christos XCONCAT2 (GETT,mode) (const unsigned char *p) \ 197 1.1 christos { \ 198 1.1 christos mode tmp; \ 199 1.1.1.10 christos memcpy (&tmp, p, sizeof (mode)); \ 200 1.1 christos return XCONCAT2 (T2H_,size) (tmp); \ 201 1.1 christos } 202 1.1 christos #else 203 1.1 christos #define DECLARE_GETT(mode, size) DECLARE_GETT_EXTERN (mode, size) 204 1.1 christos #endif 205 1.1 christos 206 1.1 christos DECLARE_GETT (QI, 1) /* TAGS: GETTQI */ 207 1.1 christos DECLARE_GETT (UQI, 1) /* TAGS: GETTUQI */ 208 1.1 christos DECLARE_GETT (HI, 2) /* TAGS: GETTHI */ 209 1.1 christos DECLARE_GETT (UHI, 2) /* TAGS: GETTUHI */ 210 1.1 christos DECLARE_GETT (SI, 4) /* TAGS: GETTSI */ 211 1.1 christos DECLARE_GETT (USI, 4) /* TAGS: GETTUSI */ 212 1.1 christos DECLARE_GETT (DI, 8) /* TAGS: GETTDI */ 213 1.1 christos DECLARE_GETT (UDI, 8) /* TAGS: GETTUDI */ 214 1.1 christos 215 1.1 christos #if 0 /* ??? defered until necessary */ 216 1.1 christos DECLARE_GETT (SF, 4) /* TAGS: GETTSF */ 217 1.1 christos DECLARE_GETT (DF, 8) /* TAGS: GETTDF */ 218 1.1.1.10 christos DECLARE_GETT (TF, 16) /* TAGS: GETTTF */ 219 1.1 christos #endif 220 1.1 christos 221 1.1 christos #undef DECLARE_GETT 222 1.1 christos #undef DECLARE_GETT_EXTERN 223 1.1 christos 224 1.1.1.10 christos /* SETT<mode>: translate host value to target value and store at P. 226 1.1.1.10 christos This needn't be very efficient (i.e. can call memcpy) as this is 227 1.1 christos only used when interfacing with the outside world (e.g. gdb). */ 228 1.1 christos 229 1.1.1.10 christos #define DECLARE_SETT_EXTERN(mode, size) \ 230 1.1 christos extern void XCONCAT2 (SETT,mode) (unsigned char *, mode); 231 1.1 christos 232 1.1 christos #if defined (MEMOPS_DEFINE_INLINE) 233 1.1 christos #define DECLARE_SETT(mode, size) \ 234 1.1 christos DECLARE_SETT_EXTERN (mode, size) \ 235 1.1 christos void \ 236 1.1 christos XCONCAT2 (SETT,mode) (unsigned char *buf, mode val) \ 237 1.1 christos { \ 238 1.1.1.10 christos mode tmp; \ 239 1.1 christos tmp = XCONCAT2 (H2T_,size) (val); \ 240 1.1 christos memcpy (buf, &tmp, sizeof (mode)); \ 241 1.1 christos } 242 1.1 christos #else 243 1.1 christos #define DECLARE_SETT(mode, size) DECLARE_SETT_EXTERN (mode, size) 244 1.1 christos #endif 245 1.1 christos 246 1.1 christos DECLARE_SETT (QI, 1) /* TAGS: SETTQI */ 247 1.1 christos DECLARE_SETT (UQI, 1) /* TAGS: SETTUQI */ 248 1.1 christos DECLARE_SETT (HI, 2) /* TAGS: SETTHI */ 249 1.1 christos DECLARE_SETT (UHI, 2) /* TAGS: SETTUHI */ 250 1.1 christos DECLARE_SETT (SI, 4) /* TAGS: SETTSI */ 251 1.1 christos DECLARE_SETT (USI, 4) /* TAGS: SETTUSI */ 252 1.1 christos DECLARE_SETT (DI, 8) /* TAGS: SETTDI */ 253 1.1 christos DECLARE_SETT (UDI, 8) /* TAGS: SETTUDI */ 254 1.1 christos 255 1.1 christos #if 0 /* ??? defered until necessary */ 256 1.1 christos DECLARE_SETT (SF, 4) /* TAGS: SETTSF */ 257 1.1.1.10 christos DECLARE_SETT (DF, 8) /* TAGS: SETTDF */ 258 1.1 christos DECLARE_SETT (TF, 16) /* TAGS: SETTTF */ 259 1.1 christos #endif 260 261 #undef DECLARE_SETT 262 #undef DECLARE_SETT_EXTERN 263 264 #endif /* CGEN_MEM_H */ 265