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