Commit | Line | Data |
---|---|---|
c906108c | 1 | /* Memory ops header for CGEN-based simulators. |
ecd75fc8 | 2 | Copyright (C) 1996-2014 Free Software Foundation, Inc. |
c906108c SS |
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 | |
4744ac1b JB |
9 | the Free Software Foundation; either version 3 of the License, or |
10 | (at your option) any later version. | |
c906108c SS |
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 | ||
4744ac1b JB |
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/>. */ | |
c906108c SS |
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 | ||
43ff13b4 JM |
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). */ | |
c906108c SS |
34 | |
35 | #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) | |
36 | #define DECLARE_GETMEM(mode, size) \ | |
37 | MEMOPS_INLINE mode \ | |
38 | XCONCAT2 (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) \ | |
46 | extern mode XCONCAT2 (GETMEM,mode) (SIM_CPU *, IADDR, ADDR); | |
47 | #endif | |
48 | ||
adf40b2e JM |
49 | DECLARE_GETMEM (QI, 1) /* TAGS: GETMEMQI */ |
50 | DECLARE_GETMEM (UQI, 1) /* TAGS: GETMEMUQI */ | |
51 | DECLARE_GETMEM (HI, 2) /* TAGS: GETMEMHI */ | |
52 | DECLARE_GETMEM (UHI, 2) /* TAGS: GETMEMUHI */ | |
53 | DECLARE_GETMEM (SI, 4) /* TAGS: GETMEMSI */ | |
54 | DECLARE_GETMEM (USI, 4) /* TAGS: GETMEMUSI */ | |
55 | DECLARE_GETMEM (DI, 8) /* TAGS: GETMEMDI */ | |
56 | DECLARE_GETMEM (UDI, 8) /* TAGS: GETMEMUDI */ | |
c906108c | 57 | |
c906108c SS |
58 | #undef DECLARE_GETMEM |
59 | \f | |
43ff13b4 | 60 | /* Integer memory write support. */ |
c906108c SS |
61 | |
62 | #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) | |
63 | #define DECLARE_SETMEM(mode, size) \ | |
64 | MEMOPS_INLINE void \ | |
65 | XCONCAT2 (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) \ | |
73 | extern void XCONCAT2 (SETMEM,mode) (SIM_CPU *, IADDR, ADDR, mode); | |
74 | #endif | |
75 | ||
adf40b2e JM |
76 | DECLARE_SETMEM (QI, 1) /* TAGS: SETMEMQI */ |
77 | DECLARE_SETMEM (UQI, 1) /* TAGS: SETMEMUQI */ | |
78 | DECLARE_SETMEM (HI, 2) /* TAGS: SETMEMHI */ | |
79 | DECLARE_SETMEM (UHI, 2) /* TAGS: SETMEMUHI */ | |
80 | DECLARE_SETMEM (SI, 4) /* TAGS: SETMEMSI */ | |
81 | DECLARE_SETMEM (USI, 4) /* TAGS: SETMEMUSI */ | |
82 | DECLARE_SETMEM (DI, 8) /* TAGS: SETMEMDI */ | |
83 | DECLARE_SETMEM (UDI, 8) /* TAGS: SETMEMUDI */ | |
c906108c | 84 | |
c906108c SS |
85 | #undef DECLARE_SETMEM |
86 | \f | |
87 | /* Instruction read support. */ | |
88 | ||
89 | #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) | |
90 | #define DECLARE_GETIMEM(mode, size) \ | |
91 | MEMOPS_INLINE mode \ | |
92 | XCONCAT2 (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) \ | |
100 | extern mode XCONCAT2 (GETIMEM,mode) (SIM_CPU *, ADDR); | |
101 | #endif | |
102 | ||
adf40b2e JM |
103 | DECLARE_GETIMEM (UQI, 1) /* TAGS: GETIMEMUQI */ |
104 | DECLARE_GETIMEM (UHI, 2) /* TAGS: GETIMEMUHI */ | |
105 | DECLARE_GETIMEM (USI, 4) /* TAGS: GETIMEMUSI */ | |
106 | DECLARE_GETIMEM (UDI, 8) /* TAGS: GETIMEMUDI */ | |
c906108c SS |
107 | |
108 | #undef DECLARE_GETIMEM | |
109 | \f | |
43ff13b4 JM |
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) \ | |
122 | MEMOPS_INLINE mode \ | |
123 | XCONCAT2 (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) \ | |
131 | extern mode XCONCAT2 (GETMEM,mode) (SIM_CPU *, IADDR, ADDR); | |
132 | #endif | |
133 | ||
adf40b2e JM |
134 | DECLARE_GETMEM (SF, 4) /* TAGS: GETMEMSF */ |
135 | DECLARE_GETMEM (DF, 8) /* TAGS: GETMEMDF */ | |
43ff13b4 JM |
136 | |
137 | #undef DECLARE_GETMEM | |
138 | ||
139 | #if defined (__GNUC__) || defined (MEMOPS_DEFINE_INLINE) | |
140 | #define DECLARE_SETMEM(mode, size) \ | |
141 | MEMOPS_INLINE void \ | |
142 | XCONCAT2 (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) \ | |
150 | extern void XCONCAT2 (SETMEM,mode) (SIM_CPU *, IADDR, ADDR, mode); | |
151 | #endif | |
152 | ||
adf40b2e JM |
153 | DECLARE_SETMEM (SF, 4) /* TAGS: SETMEMSF */ |
154 | DECLARE_SETMEM (DF, 8) /* TAGS: SETMEMDF */ | |
43ff13b4 JM |
155 | |
156 | #undef DECLARE_SETMEM | |
157 | \f | |
c906108c SS |
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 | ||
ca25db52 | 162 | #if defined (MEMOPS_DEFINE_INLINE) |
c906108c | 163 | #define DECLARE_GETT(mode, size) \ |
ca25db52 | 164 | mode \ |
c906108c SS |
165 | XCONCAT2 (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) \ | |
173 | extern mode XCONCAT2 (GETT,mode) (unsigned char *); | |
174 | #endif | |
175 | ||
adf40b2e JM |
176 | DECLARE_GETT (QI, 1) /* TAGS: GETTQI */ |
177 | DECLARE_GETT (UQI, 1) /* TAGS: GETTUQI */ | |
178 | DECLARE_GETT (HI, 2) /* TAGS: GETTHI */ | |
179 | DECLARE_GETT (UHI, 2) /* TAGS: GETTUHI */ | |
180 | DECLARE_GETT (SI, 4) /* TAGS: GETTSI */ | |
181 | DECLARE_GETT (USI, 4) /* TAGS: GETTUSI */ | |
182 | DECLARE_GETT (DI, 8) /* TAGS: GETTDI */ | |
183 | DECLARE_GETT (UDI, 8) /* TAGS: GETTUDI */ | |
184 | ||
185 | #if 0 /* ??? defered until necessary */ | |
186 | DECLARE_GETT (SF, 4) /* TAGS: GETTSF */ | |
187 | DECLARE_GETT (DF, 8) /* TAGS: GETTDF */ | |
188 | DECLARE_GETT (TF, 16) /* TAGS: GETTTF */ | |
189 | #endif | |
c906108c SS |
190 | |
191 | #undef DECLARE_GETT | |
192 | \f | |
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 | ||
ca25db52 | 197 | #if defined (MEMOPS_DEFINE_INLINE) |
c906108c | 198 | #define DECLARE_SETT(mode, size) \ |
ca25db52 | 199 | void \ |
c906108c SS |
200 | XCONCAT2 (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) \ | |
ca25db52 | 208 | extern mode XCONCAT2 (SETT,mode) (unsigned char *, mode); |
c906108c SS |
209 | #endif |
210 | ||
adf40b2e JM |
211 | DECLARE_SETT (QI, 1) /* TAGS: SETTQI */ |
212 | DECLARE_SETT (UQI, 1) /* TAGS: SETTUQI */ | |
213 | DECLARE_SETT (HI, 2) /* TAGS: SETTHI */ | |
214 | DECLARE_SETT (UHI, 2) /* TAGS: SETTUHI */ | |
215 | DECLARE_SETT (SI, 4) /* TAGS: SETTSI */ | |
216 | DECLARE_SETT (USI, 4) /* TAGS: SETTUSI */ | |
217 | DECLARE_SETT (DI, 8) /* TAGS: SETTDI */ | |
218 | DECLARE_SETT (UDI, 8) /* TAGS: SETTUDI */ | |
219 | ||
220 | #if 0 /* ??? defered until necessary */ | |
221 | DECLARE_SETT (SF, 4) /* TAGS: SETTSF */ | |
222 | DECLARE_SETT (DF, 8) /* TAGS: SETTDF */ | |
223 | DECLARE_SETT (TF, 16) /* TAGS: SETTTF */ | |
224 | #endif | |
c906108c SS |
225 | |
226 | #undef DECLARE_SETT | |
227 | ||
228 | #endif /* CGEN_MEM_H */ |