Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / sim / common / cgen-mem.h
1 /* Memory ops header for CGEN-based simulators.
2 Copyright (C) 1996-2022 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 3 of the License, or
10 (at your option) 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
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #ifndef CGEN_MEM_H
21 #define CGEN_MEM_H
22
23 /* TODO: This should get moved into sim-inline.h. */
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 #define DECLARE_GETMEM_EXTERN(mode, size) \
37 extern mode XCONCAT2 (GETMEM,mode) (SIM_CPU *, IADDR, ADDR);
38
39 #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
40 #define DECLARE_GETMEM(mode, size) \
41 DECLARE_GETMEM_EXTERN (mode, size) \
42 MEMOPS_INLINE mode \
43 XCONCAT2 (GETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a) \
44 { \
45 PROFILE_COUNT_READ (cpu, a, XCONCAT2 (MODE_,mode)); \
46 /* Don't read anything into "unaligned" here. Bad name choice. */\
47 return XCONCAT2 (sim_core_read_unaligned_,size) (cpu, pc, read_map, a); \
48 }
49 #else
50 #define DECLARE_GETMEM(mode, size) DECLARE_GETMEM_EXTERN (mode, size)
51 #endif
52
53 DECLARE_GETMEM (QI, 1) /* TAGS: GETMEMQI */
54 DECLARE_GETMEM (UQI, 1) /* TAGS: GETMEMUQI */
55 DECLARE_GETMEM (HI, 2) /* TAGS: GETMEMHI */
56 DECLARE_GETMEM (UHI, 2) /* TAGS: GETMEMUHI */
57 DECLARE_GETMEM (SI, 4) /* TAGS: GETMEMSI */
58 DECLARE_GETMEM (USI, 4) /* TAGS: GETMEMUSI */
59 DECLARE_GETMEM (DI, 8) /* TAGS: GETMEMDI */
60 DECLARE_GETMEM (UDI, 8) /* TAGS: GETMEMUDI */
61
62 #undef DECLARE_GETMEM
63 #undef DECLARE_GETMEM_EXTERN
64 \f
65 /* Integer memory write support. */
66
67 #define DECLARE_SETMEM_EXTERN(mode, size) \
68 extern void XCONCAT2 (SETMEM,mode) (SIM_CPU *, IADDR, ADDR, mode);
69
70 #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
71 #define DECLARE_SETMEM(mode, size) \
72 DECLARE_SETMEM_EXTERN (mode, size) \
73 MEMOPS_INLINE void \
74 XCONCAT2 (SETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a, mode val) \
75 { \
76 PROFILE_COUNT_WRITE (cpu, a, XCONCAT2 (MODE_,mode)); \
77 /* Don't read anything into "unaligned" here. Bad name choice. */ \
78 XCONCAT2 (sim_core_write_unaligned_,size) (cpu, pc, write_map, a, val); \
79 }
80 #else
81 #define DECLARE_SETMEM(mode, size) DECLARE_SETMEM_EXTERN (mode, size)
82 #endif
83
84 DECLARE_SETMEM (QI, 1) /* TAGS: SETMEMQI */
85 DECLARE_SETMEM (UQI, 1) /* TAGS: SETMEMUQI */
86 DECLARE_SETMEM (HI, 2) /* TAGS: SETMEMHI */
87 DECLARE_SETMEM (UHI, 2) /* TAGS: SETMEMUHI */
88 DECLARE_SETMEM (SI, 4) /* TAGS: SETMEMSI */
89 DECLARE_SETMEM (USI, 4) /* TAGS: SETMEMUSI */
90 DECLARE_SETMEM (DI, 8) /* TAGS: SETMEMDI */
91 DECLARE_SETMEM (UDI, 8) /* TAGS: SETMEMUDI */
92
93 #undef DECLARE_SETMEM
94 #undef DECLARE_SETMEM_EXTERN
95 \f
96 /* Instruction read support. */
97
98 #define DECLARE_GETIMEM_EXTERN(mode, size) \
99 extern mode XCONCAT2 (GETIMEM,mode) (SIM_CPU *, ADDR);
100
101 #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
102 #define DECLARE_GETIMEM(mode, size) \
103 DECLARE_GETIMEM_EXTERN (mode, size) \
104 MEMOPS_INLINE mode \
105 XCONCAT2 (GETIMEM,mode) (SIM_CPU *cpu, IADDR a) \
106 { \
107 /*PROFILE_COUNT_READ (cpu, a, XCONCAT2 (MODE_,mode));*/ \
108 /* Don't read anything into "unaligned" here. Bad name choice. */\
109 return XCONCAT2 (sim_core_read_unaligned_,size) (cpu, a, exec_map, a); \
110 }
111 #else
112 #define DECLARE_GETIMEM(mode, size) DECLARE_GETIMEM_EXTERN (mode, size)
113 #endif
114
115 DECLARE_GETIMEM (UQI, 1) /* TAGS: GETIMEMUQI */
116 DECLARE_GETIMEM (UHI, 2) /* TAGS: GETIMEMUHI */
117 DECLARE_GETIMEM (USI, 4) /* TAGS: GETIMEMUSI */
118 DECLARE_GETIMEM (UDI, 8) /* TAGS: GETIMEMUDI */
119
120 #undef DECLARE_GETIMEM
121 #undef DECLARE_GETIMEM_EXTERN
122 \f
123 /* Floating point support.
124
125 ??? One can specify that the integer memory ops should be used instead,
126 and treat fp values as just a series of bits. One might even bubble
127 that notion up into the description language. However, that departs from
128 gcc. One could cross over from gcc's notion and a "series of bits" notion
129 between there and here, and thus still not require these routines. However,
130 that's a complication of its own (not that having these fns isn't).
131 But for now, we do things this way. */
132
133 #define DECLARE_GETMEM_EXTERN(mode, size) \
134 extern mode XCONCAT2 (GETMEM,mode) (SIM_CPU *, IADDR, ADDR);
135
136 #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
137 #define DECLARE_GETMEM(mode, size) \
138 DECLARE_GETMEM_EXTERN (mode, size) \
139 MEMOPS_INLINE mode \
140 XCONCAT2 (GETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a) \
141 { \
142 PROFILE_COUNT_READ (cpu, a, XCONCAT2 (MODE_,mode)); \
143 /* Don't read anything into "unaligned" here. Bad name choice. */\
144 return XCONCAT2 (sim_core_read_unaligned_,size) (cpu, pc, read_map, a); \
145 }
146 #else
147 #define DECLARE_GETMEM(mode, size) DECLARE_GETMEM_EXTERN (mode, size)
148 #endif
149
150 DECLARE_GETMEM (SF, 4) /* TAGS: GETMEMSF */
151 DECLARE_GETMEM (DF, 8) /* TAGS: GETMEMDF */
152
153 #undef DECLARE_GETMEM
154 #undef DECLARE_GETMEM_EXTERN
155
156 #define DECLARE_SETMEM_EXTERN(mode, size) \
157 extern void XCONCAT2 (SETMEM,mode) (SIM_CPU *, IADDR, ADDR, mode);
158
159 #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE)
160 #define DECLARE_SETMEM(mode, size) \
161 DECLARE_SETMEM_EXTERN (mode, size) \
162 MEMOPS_INLINE void \
163 XCONCAT2 (SETMEM,mode) (SIM_CPU *cpu, IADDR pc, ADDR a, mode val) \
164 { \
165 PROFILE_COUNT_WRITE (cpu, a, XCONCAT2 (MODE_,mode)); \
166 /* Don't read anything into "unaligned" here. Bad name choice. */ \
167 XCONCAT2 (sim_core_write_unaligned_,size) (cpu, pc, write_map, a, val); \
168 }
169 #else
170 #define DECLARE_SETMEM(mode, size) DECLARE_SETMEM_EXTERN (mode, size
171 #endif
172
173 DECLARE_SETMEM (SF, 4) /* TAGS: SETMEMSF */
174 DECLARE_SETMEM (DF, 8) /* TAGS: SETMEMDF */
175
176 #undef DECLARE_SETMEM
177 #undef DECLARE_SETMEM_EXTERN
178 \f
179 /* GETT<mode>: translate target value at P to host value.
180 This needn't be very efficient (i.e. can call memcpy) as this is
181 only used when interfacing with the outside world (e.g. gdb). */
182
183 #define DECLARE_GETT_EXTERN(mode, size) \
184 extern mode XCONCAT2 (GETT,mode) (unsigned char *);
185
186 #if defined (MEMOPS_DEFINE_INLINE)
187 #define DECLARE_GETT(mode, size) \
188 DECLARE_GETT_EXTERN (mode, size) \
189 mode \
190 XCONCAT2 (GETT,mode) (unsigned char *p) \
191 { \
192 mode tmp; \
193 memcpy (&tmp, p, sizeof (mode)); \
194 return XCONCAT2 (T2H_,size) (tmp); \
195 }
196 #else
197 #define DECLARE_GETT(mode, size) DECLARE_GETT_EXTERN (mode, size)
198 #endif
199
200 DECLARE_GETT (QI, 1) /* TAGS: GETTQI */
201 DECLARE_GETT (UQI, 1) /* TAGS: GETTUQI */
202 DECLARE_GETT (HI, 2) /* TAGS: GETTHI */
203 DECLARE_GETT (UHI, 2) /* TAGS: GETTUHI */
204 DECLARE_GETT (SI, 4) /* TAGS: GETTSI */
205 DECLARE_GETT (USI, 4) /* TAGS: GETTUSI */
206 DECLARE_GETT (DI, 8) /* TAGS: GETTDI */
207 DECLARE_GETT (UDI, 8) /* TAGS: GETTUDI */
208
209 #if 0 /* ??? defered until necessary */
210 DECLARE_GETT (SF, 4) /* TAGS: GETTSF */
211 DECLARE_GETT (DF, 8) /* TAGS: GETTDF */
212 DECLARE_GETT (TF, 16) /* TAGS: GETTTF */
213 #endif
214
215 #undef DECLARE_GETT
216 #undef DECLARE_GETT_EXTERN
217 \f
218 /* SETT<mode>: translate host value to target value and store at P.
219 This needn't be very efficient (i.e. can call memcpy) as this is
220 only used when interfacing with the outside world (e.g. gdb). */
221
222 #define DECLARE_SETT_EXTERN(mode, size) \
223 extern void XCONCAT2 (SETT,mode) (unsigned char *, mode);
224
225 #if defined (MEMOPS_DEFINE_INLINE)
226 #define DECLARE_SETT(mode, size) \
227 DECLARE_SETT_EXTERN (mode, size) \
228 void \
229 XCONCAT2 (SETT,mode) (unsigned char *buf, mode val) \
230 { \
231 mode tmp; \
232 tmp = XCONCAT2 (H2T_,size) (val); \
233 memcpy (buf, &tmp, sizeof (mode)); \
234 }
235 #else
236 #define DECLARE_SETT(mode, size) DECLARE_SETT_EXTERN (mode, size)
237 #endif
238
239 DECLARE_SETT (QI, 1) /* TAGS: SETTQI */
240 DECLARE_SETT (UQI, 1) /* TAGS: SETTUQI */
241 DECLARE_SETT (HI, 2) /* TAGS: SETTHI */
242 DECLARE_SETT (UHI, 2) /* TAGS: SETTUHI */
243 DECLARE_SETT (SI, 4) /* TAGS: SETTSI */
244 DECLARE_SETT (USI, 4) /* TAGS: SETTUSI */
245 DECLARE_SETT (DI, 8) /* TAGS: SETTDI */
246 DECLARE_SETT (UDI, 8) /* TAGS: SETTUDI */
247
248 #if 0 /* ??? defered until necessary */
249 DECLARE_SETT (SF, 4) /* TAGS: SETTSF */
250 DECLARE_SETT (DF, 8) /* TAGS: SETTDF */
251 DECLARE_SETT (TF, 16) /* TAGS: SETTTF */
252 #endif
253
254 #undef DECLARE_SETT
255 #undef DECLARE_SETT_EXTERN
256
257 #endif /* CGEN_MEM_H */
This page took 0.034837 seconds and 4 git commands to generate.