Commit | Line | Data |
---|---|---|
c906108c | 1 | /* Memory ops header for CGEN-based simulators. |
43ff13b4 | 2 | Copyright (C) 1996, 1997, 1998, 1999 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 | |
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 | ||
43ff13b4 JM |
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). */ | |
c906108c SS |
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 | ||
adf40b2e JM |
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 */ | |
c906108c | 58 | |
c906108c SS |
59 | #undef DECLARE_GETMEM |
60 | \f | |
43ff13b4 | 61 | /* Integer memory write support. */ |
c906108c SS |
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 | ||
adf40b2e JM |
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 */ | |
c906108c | 85 | |
c906108c SS |
86 | #undef DECLARE_SETMEM |
87 | \f | |
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 | ||
adf40b2e JM |
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 */ | |
c906108c SS |
108 | |
109 | #undef DECLARE_GETIMEM | |
110 | \f | |
43ff13b4 JM |
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 | ||
adf40b2e JM |
135 | DECLARE_GETMEM (SF, 4) /* TAGS: GETMEMSF */ |
136 | DECLARE_GETMEM (DF, 8) /* TAGS: GETMEMDF */ | |
43ff13b4 JM |
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 | ||
adf40b2e JM |
154 | DECLARE_SETMEM (SF, 4) /* TAGS: SETMEMSF */ |
155 | DECLARE_SETMEM (DF, 8) /* TAGS: SETMEMDF */ | |
43ff13b4 JM |
156 | |
157 | #undef DECLARE_SETMEM | |
158 | \f | |
c906108c SS |
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 | ||
adf40b2e JM |
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 | |
c906108c SS |
191 | |
192 | #undef DECLARE_GETT | |
193 | \f | |
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 | ||
adf40b2e JM |
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 | |
c906108c SS |
226 | |
227 | #undef DECLARE_SETT | |
228 | ||
229 | #endif /* CGEN_MEM_H */ |