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