root / cpu-all.h @ 97eb5b14
History | View | Annotate | Download (15 kB)
1 | 5a9fdfec | bellard | /*
|
---|---|---|---|
2 | 5a9fdfec | bellard | * defines common to all virtual CPUs
|
3 | 5a9fdfec | bellard | *
|
4 | 5a9fdfec | bellard | * Copyright (c) 2003 Fabrice Bellard
|
5 | 5a9fdfec | bellard | *
|
6 | 5a9fdfec | bellard | * This library is free software; you can redistribute it and/or
|
7 | 5a9fdfec | bellard | * modify it under the terms of the GNU Lesser General Public
|
8 | 5a9fdfec | bellard | * License as published by the Free Software Foundation; either
|
9 | 5a9fdfec | bellard | * version 2 of the License, or (at your option) any later version.
|
10 | 5a9fdfec | bellard | *
|
11 | 5a9fdfec | bellard | * This library is distributed in the hope that it will be useful,
|
12 | 5a9fdfec | bellard | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 5a9fdfec | bellard | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | 5a9fdfec | bellard | * Lesser General Public License for more details.
|
15 | 5a9fdfec | bellard | *
|
16 | 5a9fdfec | bellard | * You should have received a copy of the GNU Lesser General Public
|
17 | 5a9fdfec | bellard | * License along with this library; if not, write to the Free Software
|
18 | 5a9fdfec | bellard | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19 | 5a9fdfec | bellard | */
|
20 | 5a9fdfec | bellard | #ifndef CPU_ALL_H
|
21 | 5a9fdfec | bellard | #define CPU_ALL_H
|
22 | 5a9fdfec | bellard | |
23 | 0ac4bd56 | bellard | #if defined(__arm__) || defined(__sparc__)
|
24 | 0ac4bd56 | bellard | #define WORDS_ALIGNED
|
25 | 0ac4bd56 | bellard | #endif
|
26 | 0ac4bd56 | bellard | |
27 | 0ac4bd56 | bellard | /* some important defines:
|
28 | 0ac4bd56 | bellard | *
|
29 | 0ac4bd56 | bellard | * WORDS_ALIGNED : if defined, the host cpu can only make word aligned
|
30 | 0ac4bd56 | bellard | * memory accesses.
|
31 | 0ac4bd56 | bellard | *
|
32 | 0ac4bd56 | bellard | * WORDS_BIGENDIAN : if defined, the host cpu is big endian and
|
33 | 0ac4bd56 | bellard | * otherwise little endian.
|
34 | 0ac4bd56 | bellard | *
|
35 | 0ac4bd56 | bellard | * (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet))
|
36 | 0ac4bd56 | bellard | *
|
37 | 0ac4bd56 | bellard | * TARGET_WORDS_BIGENDIAN : same for target cpu
|
38 | 0ac4bd56 | bellard | */
|
39 | 0ac4bd56 | bellard | |
40 | 0ac4bd56 | bellard | /* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
|
41 | 0ac4bd56 | bellard | typedef union { |
42 | 0ac4bd56 | bellard | double d;
|
43 | 0ac4bd56 | bellard | #if !defined(WORDS_BIGENDIAN) && !defined(__arm__)
|
44 | 0ac4bd56 | bellard | struct {
|
45 | 0ac4bd56 | bellard | uint32_t lower; |
46 | 0ac4bd56 | bellard | uint32_t upper; |
47 | 0ac4bd56 | bellard | } l; |
48 | 0ac4bd56 | bellard | #else
|
49 | 0ac4bd56 | bellard | struct {
|
50 | 0ac4bd56 | bellard | uint32_t upper; |
51 | 0ac4bd56 | bellard | uint32_t lower; |
52 | 0ac4bd56 | bellard | } l; |
53 | 0ac4bd56 | bellard | #endif
|
54 | 0ac4bd56 | bellard | uint64_t ll; |
55 | 0ac4bd56 | bellard | } CPU_DoubleU; |
56 | 0ac4bd56 | bellard | |
57 | 61382a50 | bellard | /* CPU memory access without any memory or io remapping */
|
58 | 61382a50 | bellard | |
59 | 83d73968 | bellard | /*
|
60 | 83d73968 | bellard | * the generic syntax for the memory accesses is:
|
61 | 83d73968 | bellard | *
|
62 | 83d73968 | bellard | * load: ld{type}{sign}{size}{endian}_{access_type}(ptr)
|
63 | 83d73968 | bellard | *
|
64 | 83d73968 | bellard | * store: st{type}{size}{endian}_{access_type}(ptr, val)
|
65 | 83d73968 | bellard | *
|
66 | 83d73968 | bellard | * type is:
|
67 | 83d73968 | bellard | * (empty): integer access
|
68 | 83d73968 | bellard | * f : float access
|
69 | 83d73968 | bellard | *
|
70 | 83d73968 | bellard | * sign is:
|
71 | 83d73968 | bellard | * (empty): for floats or 32 bit size
|
72 | 83d73968 | bellard | * u : unsigned
|
73 | 83d73968 | bellard | * s : signed
|
74 | 83d73968 | bellard | *
|
75 | 83d73968 | bellard | * size is:
|
76 | 83d73968 | bellard | * b: 8 bits
|
77 | 83d73968 | bellard | * w: 16 bits
|
78 | 83d73968 | bellard | * l: 32 bits
|
79 | 83d73968 | bellard | * q: 64 bits
|
80 | 83d73968 | bellard | *
|
81 | 83d73968 | bellard | * endian is:
|
82 | 83d73968 | bellard | * (empty): target cpu endianness or 8 bit access
|
83 | 83d73968 | bellard | * r : reversed target cpu endianness (not implemented yet)
|
84 | 83d73968 | bellard | * be : big endian (not implemented yet)
|
85 | 83d73968 | bellard | * le : little endian (not implemented yet)
|
86 | 83d73968 | bellard | *
|
87 | 83d73968 | bellard | * access_type is:
|
88 | 83d73968 | bellard | * raw : host memory access
|
89 | 83d73968 | bellard | * user : user mode access using soft MMU
|
90 | 83d73968 | bellard | * kernel : kernel mode access using soft MMU
|
91 | 83d73968 | bellard | */
|
92 | 61382a50 | bellard | static inline int ldub_raw(void *ptr) |
93 | 5a9fdfec | bellard | { |
94 | 5a9fdfec | bellard | return *(uint8_t *)ptr;
|
95 | 5a9fdfec | bellard | } |
96 | 5a9fdfec | bellard | |
97 | 61382a50 | bellard | static inline int ldsb_raw(void *ptr) |
98 | 5a9fdfec | bellard | { |
99 | 5a9fdfec | bellard | return *(int8_t *)ptr;
|
100 | 5a9fdfec | bellard | } |
101 | 5a9fdfec | bellard | |
102 | 61382a50 | bellard | static inline void stb_raw(void *ptr, int v) |
103 | 5a9fdfec | bellard | { |
104 | 5a9fdfec | bellard | *(uint8_t *)ptr = v; |
105 | 5a9fdfec | bellard | } |
106 | 5a9fdfec | bellard | |
107 | 5a9fdfec | bellard | /* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
|
108 | 5a9fdfec | bellard | kernel handles unaligned load/stores may give better results, but
|
109 | 5a9fdfec | bellard | it is a system wide setting : bad */
|
110 | 0ac4bd56 | bellard | #if !defined(TARGET_WORDS_BIGENDIAN) && (defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
|
111 | 5a9fdfec | bellard | |
112 | 5a9fdfec | bellard | /* conservative code for little endian unaligned accesses */
|
113 | 61382a50 | bellard | static inline int lduw_raw(void *ptr) |
114 | 5a9fdfec | bellard | { |
115 | 5a9fdfec | bellard | #ifdef __powerpc__
|
116 | 5a9fdfec | bellard | int val;
|
117 | 5a9fdfec | bellard | __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); |
118 | 5a9fdfec | bellard | return val;
|
119 | 5a9fdfec | bellard | #else
|
120 | 5a9fdfec | bellard | uint8_t *p = ptr; |
121 | 5a9fdfec | bellard | return p[0] | (p[1] << 8); |
122 | 5a9fdfec | bellard | #endif
|
123 | 5a9fdfec | bellard | } |
124 | 5a9fdfec | bellard | |
125 | 61382a50 | bellard | static inline int ldsw_raw(void *ptr) |
126 | 5a9fdfec | bellard | { |
127 | 5a9fdfec | bellard | #ifdef __powerpc__
|
128 | 5a9fdfec | bellard | int val;
|
129 | 5a9fdfec | bellard | __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); |
130 | 5a9fdfec | bellard | return (int16_t)val;
|
131 | 5a9fdfec | bellard | #else
|
132 | 5a9fdfec | bellard | uint8_t *p = ptr; |
133 | 5a9fdfec | bellard | return (int16_t)(p[0] | (p[1] << 8)); |
134 | 5a9fdfec | bellard | #endif
|
135 | 5a9fdfec | bellard | } |
136 | 5a9fdfec | bellard | |
137 | 61382a50 | bellard | static inline int ldl_raw(void *ptr) |
138 | 5a9fdfec | bellard | { |
139 | 5a9fdfec | bellard | #ifdef __powerpc__
|
140 | 5a9fdfec | bellard | int val;
|
141 | 5a9fdfec | bellard | __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr)); |
142 | 5a9fdfec | bellard | return val;
|
143 | 5a9fdfec | bellard | #else
|
144 | 5a9fdfec | bellard | uint8_t *p = ptr; |
145 | 5a9fdfec | bellard | return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); |
146 | 5a9fdfec | bellard | #endif
|
147 | 5a9fdfec | bellard | } |
148 | 5a9fdfec | bellard | |
149 | 61382a50 | bellard | static inline uint64_t ldq_raw(void *ptr) |
150 | 5a9fdfec | bellard | { |
151 | 5a9fdfec | bellard | uint8_t *p = ptr; |
152 | 5a9fdfec | bellard | uint32_t v1, v2; |
153 | 61382a50 | bellard | v1 = ldl_raw(p); |
154 | 61382a50 | bellard | v2 = ldl_raw(p + 4);
|
155 | 5a9fdfec | bellard | return v1 | ((uint64_t)v2 << 32); |
156 | 5a9fdfec | bellard | } |
157 | 5a9fdfec | bellard | |
158 | 61382a50 | bellard | static inline void stw_raw(void *ptr, int v) |
159 | 5a9fdfec | bellard | { |
160 | 5a9fdfec | bellard | #ifdef __powerpc__
|
161 | 5a9fdfec | bellard | __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr)); |
162 | 5a9fdfec | bellard | #else
|
163 | 5a9fdfec | bellard | uint8_t *p = ptr; |
164 | 5a9fdfec | bellard | p[0] = v;
|
165 | 5a9fdfec | bellard | p[1] = v >> 8; |
166 | 5a9fdfec | bellard | #endif
|
167 | 5a9fdfec | bellard | } |
168 | 5a9fdfec | bellard | |
169 | 61382a50 | bellard | static inline void stl_raw(void *ptr, int v) |
170 | 5a9fdfec | bellard | { |
171 | 5a9fdfec | bellard | #ifdef __powerpc__
|
172 | 5a9fdfec | bellard | __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr)); |
173 | 5a9fdfec | bellard | #else
|
174 | 5a9fdfec | bellard | uint8_t *p = ptr; |
175 | 5a9fdfec | bellard | p[0] = v;
|
176 | 5a9fdfec | bellard | p[1] = v >> 8; |
177 | 5a9fdfec | bellard | p[2] = v >> 16; |
178 | 5a9fdfec | bellard | p[3] = v >> 24; |
179 | 5a9fdfec | bellard | #endif
|
180 | 5a9fdfec | bellard | } |
181 | 5a9fdfec | bellard | |
182 | 61382a50 | bellard | static inline void stq_raw(void *ptr, uint64_t v) |
183 | 5a9fdfec | bellard | { |
184 | 5a9fdfec | bellard | uint8_t *p = ptr; |
185 | 61382a50 | bellard | stl_raw(p, (uint32_t)v); |
186 | 61382a50 | bellard | stl_raw(p + 4, v >> 32); |
187 | 5a9fdfec | bellard | } |
188 | 5a9fdfec | bellard | |
189 | 5a9fdfec | bellard | /* float access */
|
190 | 5a9fdfec | bellard | |
191 | 61382a50 | bellard | static inline float ldfl_raw(void *ptr) |
192 | 5a9fdfec | bellard | { |
193 | 5a9fdfec | bellard | union {
|
194 | 5a9fdfec | bellard | float f;
|
195 | 5a9fdfec | bellard | uint32_t i; |
196 | 5a9fdfec | bellard | } u; |
197 | 61382a50 | bellard | u.i = ldl_raw(ptr); |
198 | 5a9fdfec | bellard | return u.f;
|
199 | 5a9fdfec | bellard | } |
200 | 5a9fdfec | bellard | |
201 | 61382a50 | bellard | static inline void stfl_raw(void *ptr, float v) |
202 | 5a9fdfec | bellard | { |
203 | 5a9fdfec | bellard | union {
|
204 | 5a9fdfec | bellard | float f;
|
205 | 5a9fdfec | bellard | uint32_t i; |
206 | 5a9fdfec | bellard | } u; |
207 | 5a9fdfec | bellard | u.f = v; |
208 | 61382a50 | bellard | stl_raw(ptr, u.i); |
209 | 5a9fdfec | bellard | } |
210 | 5a9fdfec | bellard | |
211 | 61382a50 | bellard | static inline double ldfq_raw(void *ptr) |
212 | 5a9fdfec | bellard | { |
213 | 0ac4bd56 | bellard | CPU_DoubleU u; |
214 | 0ac4bd56 | bellard | u.l.lower = ldl_raw(ptr); |
215 | 0ac4bd56 | bellard | u.l.upper = ldl_raw(ptr + 4);
|
216 | 5a9fdfec | bellard | return u.d;
|
217 | 5a9fdfec | bellard | } |
218 | 5a9fdfec | bellard | |
219 | 61382a50 | bellard | static inline void stfq_raw(void *ptr, double v) |
220 | 5a9fdfec | bellard | { |
221 | 0ac4bd56 | bellard | CPU_DoubleU u; |
222 | 5a9fdfec | bellard | u.d = v; |
223 | 0ac4bd56 | bellard | stl_raw(ptr, u.l.lower); |
224 | 0ac4bd56 | bellard | stl_raw(ptr + 4, u.l.upper);
|
225 | 5a9fdfec | bellard | } |
226 | 5a9fdfec | bellard | |
227 | 0ac4bd56 | bellard | #elif defined(TARGET_WORDS_BIGENDIAN) && (!defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED))
|
228 | 93ac68bc | bellard | |
229 | 61382a50 | bellard | static inline int lduw_raw(void *ptr) |
230 | 93ac68bc | bellard | { |
231 | 83d73968 | bellard | #if defined(__i386__)
|
232 | 83d73968 | bellard | int val;
|
233 | 83d73968 | bellard | asm volatile ("movzwl %1, %0\n" |
234 | 83d73968 | bellard | "xchgb %b0, %h0\n"
|
235 | 83d73968 | bellard | : "=q" (val)
|
236 | 83d73968 | bellard | : "m" (*(uint16_t *)ptr));
|
237 | 83d73968 | bellard | return val;
|
238 | 83d73968 | bellard | #else
|
239 | 93ac68bc | bellard | uint8_t *b = (uint8_t *) ptr; |
240 | 83d73968 | bellard | return ((b[0] << 8) | b[1]); |
241 | 83d73968 | bellard | #endif
|
242 | 93ac68bc | bellard | } |
243 | 93ac68bc | bellard | |
244 | 61382a50 | bellard | static inline int ldsw_raw(void *ptr) |
245 | 93ac68bc | bellard | { |
246 | 83d73968 | bellard | #if defined(__i386__)
|
247 | 83d73968 | bellard | int val;
|
248 | 83d73968 | bellard | asm volatile ("movzwl %1, %0\n" |
249 | 83d73968 | bellard | "xchgb %b0, %h0\n"
|
250 | 83d73968 | bellard | : "=q" (val)
|
251 | 83d73968 | bellard | : "m" (*(uint16_t *)ptr));
|
252 | 83d73968 | bellard | return (int16_t)val;
|
253 | 83d73968 | bellard | #else
|
254 | 83d73968 | bellard | uint8_t *b = (uint8_t *) ptr; |
255 | 83d73968 | bellard | return (int16_t)((b[0] << 8) | b[1]); |
256 | 83d73968 | bellard | #endif
|
257 | 93ac68bc | bellard | } |
258 | 93ac68bc | bellard | |
259 | 61382a50 | bellard | static inline int ldl_raw(void *ptr) |
260 | 93ac68bc | bellard | { |
261 | 83d73968 | bellard | #if defined(__i386__)
|
262 | 83d73968 | bellard | int val;
|
263 | 83d73968 | bellard | asm volatile ("movl %1, %0\n" |
264 | 83d73968 | bellard | "bswap %0\n"
|
265 | 83d73968 | bellard | : "=r" (val)
|
266 | 83d73968 | bellard | : "m" (*(uint32_t *)ptr));
|
267 | 83d73968 | bellard | return val;
|
268 | 83d73968 | bellard | #else
|
269 | 93ac68bc | bellard | uint8_t *b = (uint8_t *) ptr; |
270 | 83d73968 | bellard | return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]; |
271 | 83d73968 | bellard | #endif
|
272 | 93ac68bc | bellard | } |
273 | 93ac68bc | bellard | |
274 | 61382a50 | bellard | static inline uint64_t ldq_raw(void *ptr) |
275 | 93ac68bc | bellard | { |
276 | 93ac68bc | bellard | uint32_t a,b; |
277 | 9f05cc34 | bellard | a = ldl_raw(ptr); |
278 | 9f05cc34 | bellard | b = ldl_raw(ptr+4);
|
279 | 93ac68bc | bellard | return (((uint64_t)a<<32)|b); |
280 | 93ac68bc | bellard | } |
281 | 93ac68bc | bellard | |
282 | 61382a50 | bellard | static inline void stw_raw(void *ptr, int v) |
283 | 93ac68bc | bellard | { |
284 | 83d73968 | bellard | #if defined(__i386__)
|
285 | 83d73968 | bellard | asm volatile ("xchgb %b0, %h0\n" |
286 | 83d73968 | bellard | "movw %w0, %1\n"
|
287 | 83d73968 | bellard | : "=q" (v)
|
288 | 83d73968 | bellard | : "m" (*(uint16_t *)ptr), "0" (v)); |
289 | 83d73968 | bellard | #else
|
290 | 93ac68bc | bellard | uint8_t *d = (uint8_t *) ptr; |
291 | 93ac68bc | bellard | d[0] = v >> 8; |
292 | 93ac68bc | bellard | d[1] = v;
|
293 | 83d73968 | bellard | #endif
|
294 | 93ac68bc | bellard | } |
295 | 93ac68bc | bellard | |
296 | 61382a50 | bellard | static inline void stl_raw(void *ptr, int v) |
297 | 93ac68bc | bellard | { |
298 | 83d73968 | bellard | #if defined(__i386__)
|
299 | 83d73968 | bellard | asm volatile ("bswap %0\n" |
300 | 83d73968 | bellard | "movl %0, %1\n"
|
301 | 83d73968 | bellard | : "=r" (v)
|
302 | 83d73968 | bellard | : "m" (*(uint32_t *)ptr), "0" (v)); |
303 | 83d73968 | bellard | #else
|
304 | 93ac68bc | bellard | uint8_t *d = (uint8_t *) ptr; |
305 | 93ac68bc | bellard | d[0] = v >> 24; |
306 | 93ac68bc | bellard | d[1] = v >> 16; |
307 | 93ac68bc | bellard | d[2] = v >> 8; |
308 | 93ac68bc | bellard | d[3] = v;
|
309 | 83d73968 | bellard | #endif
|
310 | 93ac68bc | bellard | } |
311 | 93ac68bc | bellard | |
312 | 61382a50 | bellard | static inline void stq_raw(void *ptr, uint64_t v) |
313 | 93ac68bc | bellard | { |
314 | 0ac4bd56 | bellard | stl_raw(ptr, v >> 32);
|
315 | 0ac4bd56 | bellard | stl_raw(ptr + 4, v);
|
316 | 0ac4bd56 | bellard | } |
317 | 0ac4bd56 | bellard | |
318 | 0ac4bd56 | bellard | /* float access */
|
319 | 0ac4bd56 | bellard | |
320 | 0ac4bd56 | bellard | static inline float ldfl_raw(void *ptr) |
321 | 0ac4bd56 | bellard | { |
322 | 0ac4bd56 | bellard | union {
|
323 | 0ac4bd56 | bellard | float f;
|
324 | 0ac4bd56 | bellard | uint32_t i; |
325 | 0ac4bd56 | bellard | } u; |
326 | 0ac4bd56 | bellard | u.i = ldl_raw(ptr); |
327 | 0ac4bd56 | bellard | return u.f;
|
328 | 0ac4bd56 | bellard | } |
329 | 0ac4bd56 | bellard | |
330 | 0ac4bd56 | bellard | static inline void stfl_raw(void *ptr, float v) |
331 | 0ac4bd56 | bellard | { |
332 | 0ac4bd56 | bellard | union {
|
333 | 0ac4bd56 | bellard | float f;
|
334 | 0ac4bd56 | bellard | uint32_t i; |
335 | 0ac4bd56 | bellard | } u; |
336 | 0ac4bd56 | bellard | u.f = v; |
337 | 0ac4bd56 | bellard | stl_raw(ptr, u.i); |
338 | 0ac4bd56 | bellard | } |
339 | 0ac4bd56 | bellard | |
340 | 0ac4bd56 | bellard | static inline double ldfq_raw(void *ptr) |
341 | 0ac4bd56 | bellard | { |
342 | 0ac4bd56 | bellard | CPU_DoubleU u; |
343 | 0ac4bd56 | bellard | u.l.upper = ldl_raw(ptr); |
344 | 0ac4bd56 | bellard | u.l.lower = ldl_raw(ptr + 4);
|
345 | 0ac4bd56 | bellard | return u.d;
|
346 | 0ac4bd56 | bellard | } |
347 | 0ac4bd56 | bellard | |
348 | 0ac4bd56 | bellard | static inline void stfq_raw(void *ptr, double v) |
349 | 0ac4bd56 | bellard | { |
350 | 0ac4bd56 | bellard | CPU_DoubleU u; |
351 | 0ac4bd56 | bellard | u.d = v; |
352 | 0ac4bd56 | bellard | stl_raw(ptr, u.l.upper); |
353 | 0ac4bd56 | bellard | stl_raw(ptr + 4, u.l.lower);
|
354 | 93ac68bc | bellard | } |
355 | 93ac68bc | bellard | |
356 | 5a9fdfec | bellard | #else
|
357 | 5a9fdfec | bellard | |
358 | 61382a50 | bellard | static inline int lduw_raw(void *ptr) |
359 | 5a9fdfec | bellard | { |
360 | 5a9fdfec | bellard | return *(uint16_t *)ptr;
|
361 | 5a9fdfec | bellard | } |
362 | 5a9fdfec | bellard | |
363 | 61382a50 | bellard | static inline int ldsw_raw(void *ptr) |
364 | 5a9fdfec | bellard | { |
365 | 5a9fdfec | bellard | return *(int16_t *)ptr;
|
366 | 5a9fdfec | bellard | } |
367 | 5a9fdfec | bellard | |
368 | 61382a50 | bellard | static inline int ldl_raw(void *ptr) |
369 | 5a9fdfec | bellard | { |
370 | 5a9fdfec | bellard | return *(uint32_t *)ptr;
|
371 | 5a9fdfec | bellard | } |
372 | 5a9fdfec | bellard | |
373 | 61382a50 | bellard | static inline uint64_t ldq_raw(void *ptr) |
374 | 5a9fdfec | bellard | { |
375 | 5a9fdfec | bellard | return *(uint64_t *)ptr;
|
376 | 5a9fdfec | bellard | } |
377 | 5a9fdfec | bellard | |
378 | 61382a50 | bellard | static inline void stw_raw(void *ptr, int v) |
379 | 5a9fdfec | bellard | { |
380 | 5a9fdfec | bellard | *(uint16_t *)ptr = v; |
381 | 5a9fdfec | bellard | } |
382 | 5a9fdfec | bellard | |
383 | 61382a50 | bellard | static inline void stl_raw(void *ptr, int v) |
384 | 5a9fdfec | bellard | { |
385 | 5a9fdfec | bellard | *(uint32_t *)ptr = v; |
386 | 5a9fdfec | bellard | } |
387 | 5a9fdfec | bellard | |
388 | 61382a50 | bellard | static inline void stq_raw(void *ptr, uint64_t v) |
389 | 5a9fdfec | bellard | { |
390 | 5a9fdfec | bellard | *(uint64_t *)ptr = v; |
391 | 5a9fdfec | bellard | } |
392 | 5a9fdfec | bellard | |
393 | 5a9fdfec | bellard | /* float access */
|
394 | 5a9fdfec | bellard | |
395 | 61382a50 | bellard | static inline float ldfl_raw(void *ptr) |
396 | 5a9fdfec | bellard | { |
397 | 5a9fdfec | bellard | return *(float *)ptr; |
398 | 5a9fdfec | bellard | } |
399 | 5a9fdfec | bellard | |
400 | 61382a50 | bellard | static inline double ldfq_raw(void *ptr) |
401 | 5a9fdfec | bellard | { |
402 | 5a9fdfec | bellard | return *(double *)ptr; |
403 | 5a9fdfec | bellard | } |
404 | 5a9fdfec | bellard | |
405 | 61382a50 | bellard | static inline void stfl_raw(void *ptr, float v) |
406 | 5a9fdfec | bellard | { |
407 | 5a9fdfec | bellard | *(float *)ptr = v;
|
408 | 5a9fdfec | bellard | } |
409 | 5a9fdfec | bellard | |
410 | 61382a50 | bellard | static inline void stfq_raw(void *ptr, double v) |
411 | 5a9fdfec | bellard | { |
412 | 5a9fdfec | bellard | *(double *)ptr = v;
|
413 | 5a9fdfec | bellard | } |
414 | 5a9fdfec | bellard | #endif
|
415 | 5a9fdfec | bellard | |
416 | 61382a50 | bellard | /* MMU memory access macros */
|
417 | 61382a50 | bellard | |
418 | 61382a50 | bellard | #if defined(CONFIG_USER_ONLY)
|
419 | 61382a50 | bellard | |
420 | 61382a50 | bellard | /* if user mode, no other memory access functions */
|
421 | 61382a50 | bellard | #define ldub(p) ldub_raw(p)
|
422 | 61382a50 | bellard | #define ldsb(p) ldsb_raw(p)
|
423 | 61382a50 | bellard | #define lduw(p) lduw_raw(p)
|
424 | 61382a50 | bellard | #define ldsw(p) ldsw_raw(p)
|
425 | 61382a50 | bellard | #define ldl(p) ldl_raw(p)
|
426 | 61382a50 | bellard | #define ldq(p) ldq_raw(p)
|
427 | 61382a50 | bellard | #define ldfl(p) ldfl_raw(p)
|
428 | 61382a50 | bellard | #define ldfq(p) ldfq_raw(p)
|
429 | 61382a50 | bellard | #define stb(p, v) stb_raw(p, v)
|
430 | 61382a50 | bellard | #define stw(p, v) stw_raw(p, v)
|
431 | 61382a50 | bellard | #define stl(p, v) stl_raw(p, v)
|
432 | 61382a50 | bellard | #define stq(p, v) stq_raw(p, v)
|
433 | 61382a50 | bellard | #define stfl(p, v) stfl_raw(p, v)
|
434 | 61382a50 | bellard | #define stfq(p, v) stfq_raw(p, v)
|
435 | 61382a50 | bellard | |
436 | 61382a50 | bellard | #define ldub_code(p) ldub_raw(p)
|
437 | 61382a50 | bellard | #define ldsb_code(p) ldsb_raw(p)
|
438 | 61382a50 | bellard | #define lduw_code(p) lduw_raw(p)
|
439 | 61382a50 | bellard | #define ldsw_code(p) ldsw_raw(p)
|
440 | 61382a50 | bellard | #define ldl_code(p) ldl_raw(p)
|
441 | 61382a50 | bellard | |
442 | 61382a50 | bellard | #define ldub_kernel(p) ldub_raw(p)
|
443 | 61382a50 | bellard | #define ldsb_kernel(p) ldsb_raw(p)
|
444 | 61382a50 | bellard | #define lduw_kernel(p) lduw_raw(p)
|
445 | 61382a50 | bellard | #define ldsw_kernel(p) ldsw_raw(p)
|
446 | 61382a50 | bellard | #define ldl_kernel(p) ldl_raw(p)
|
447 | 0ac4bd56 | bellard | #define ldfl_kernel(p) ldfl_raw(p)
|
448 | 0ac4bd56 | bellard | #define ldfq_kernel(p) ldfq_raw(p)
|
449 | 61382a50 | bellard | #define stb_kernel(p, v) stb_raw(p, v)
|
450 | 61382a50 | bellard | #define stw_kernel(p, v) stw_raw(p, v)
|
451 | 61382a50 | bellard | #define stl_kernel(p, v) stl_raw(p, v)
|
452 | 61382a50 | bellard | #define stq_kernel(p, v) stq_raw(p, v)
|
453 | 0ac4bd56 | bellard | #define stfl_kernel(p, v) stfl_raw(p, v)
|
454 | 0ac4bd56 | bellard | #define stfq_kernel(p, vt) stfq_raw(p, v)
|
455 | 61382a50 | bellard | |
456 | 61382a50 | bellard | #endif /* defined(CONFIG_USER_ONLY) */ |
457 | 61382a50 | bellard | |
458 | 5a9fdfec | bellard | /* page related stuff */
|
459 | 5a9fdfec | bellard | |
460 | 5a9fdfec | bellard | #define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS) |
461 | 5a9fdfec | bellard | #define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1) |
462 | 5a9fdfec | bellard | #define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK) |
463 | 5a9fdfec | bellard | |
464 | 5a9fdfec | bellard | extern unsigned long real_host_page_size; |
465 | 5a9fdfec | bellard | extern unsigned long host_page_bits; |
466 | 5a9fdfec | bellard | extern unsigned long host_page_size; |
467 | 5a9fdfec | bellard | extern unsigned long host_page_mask; |
468 | 5a9fdfec | bellard | |
469 | 5a9fdfec | bellard | #define HOST_PAGE_ALIGN(addr) (((addr) + host_page_size - 1) & host_page_mask) |
470 | 5a9fdfec | bellard | |
471 | 5a9fdfec | bellard | /* same as PROT_xxx */
|
472 | 5a9fdfec | bellard | #define PAGE_READ 0x0001 |
473 | 5a9fdfec | bellard | #define PAGE_WRITE 0x0002 |
474 | 5a9fdfec | bellard | #define PAGE_EXEC 0x0004 |
475 | 5a9fdfec | bellard | #define PAGE_BITS (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
|
476 | 5a9fdfec | bellard | #define PAGE_VALID 0x0008 |
477 | 5a9fdfec | bellard | /* original state of the write flag (used when tracking self-modifying
|
478 | 5a9fdfec | bellard | code */
|
479 | 5a9fdfec | bellard | #define PAGE_WRITE_ORG 0x0010 |
480 | 5a9fdfec | bellard | |
481 | 5a9fdfec | bellard | void page_dump(FILE *f);
|
482 | 5a9fdfec | bellard | int page_get_flags(unsigned long address); |
483 | 5a9fdfec | bellard | void page_set_flags(unsigned long start, unsigned long end, int flags); |
484 | 5a9fdfec | bellard | void page_unprotect_range(uint8_t *data, unsigned long data_size); |
485 | 5a9fdfec | bellard | |
486 | 5a9fdfec | bellard | #define SINGLE_CPU_DEFINES
|
487 | 5a9fdfec | bellard | #ifdef SINGLE_CPU_DEFINES
|
488 | 5a9fdfec | bellard | |
489 | 5a9fdfec | bellard | #if defined(TARGET_I386)
|
490 | 5a9fdfec | bellard | |
491 | 5a9fdfec | bellard | #define CPUState CPUX86State
|
492 | 5a9fdfec | bellard | #define cpu_init cpu_x86_init
|
493 | 5a9fdfec | bellard | #define cpu_exec cpu_x86_exec
|
494 | 5a9fdfec | bellard | #define cpu_gen_code cpu_x86_gen_code
|
495 | 5a9fdfec | bellard | #define cpu_interrupt cpu_x86_interrupt
|
496 | 5a9fdfec | bellard | #define cpu_signal_handler cpu_x86_signal_handler
|
497 | 09683d35 | bellard | #define cpu_dump_state cpu_x86_dump_state
|
498 | 5a9fdfec | bellard | |
499 | 5a9fdfec | bellard | #elif defined(TARGET_ARM)
|
500 | 5a9fdfec | bellard | |
501 | 5a9fdfec | bellard | #define CPUState CPUARMState
|
502 | 5a9fdfec | bellard | #define cpu_init cpu_arm_init
|
503 | 5a9fdfec | bellard | #define cpu_exec cpu_arm_exec
|
504 | 5a9fdfec | bellard | #define cpu_gen_code cpu_arm_gen_code
|
505 | 5a9fdfec | bellard | #define cpu_interrupt cpu_arm_interrupt
|
506 | 5a9fdfec | bellard | #define cpu_signal_handler cpu_arm_signal_handler
|
507 | 09683d35 | bellard | #define cpu_dump_state cpu_arm_dump_state
|
508 | 5a9fdfec | bellard | |
509 | 93ac68bc | bellard | #elif defined(TARGET_SPARC)
|
510 | 93ac68bc | bellard | |
511 | 93ac68bc | bellard | #define CPUState CPUSPARCState
|
512 | 93ac68bc | bellard | #define cpu_init cpu_sparc_init
|
513 | 93ac68bc | bellard | #define cpu_exec cpu_sparc_exec
|
514 | 93ac68bc | bellard | #define cpu_gen_code cpu_sparc_gen_code
|
515 | 93ac68bc | bellard | #define cpu_interrupt cpu_sparc_interrupt
|
516 | 93ac68bc | bellard | #define cpu_signal_handler cpu_sparc_signal_handler
|
517 | 09683d35 | bellard | #define cpu_dump_state cpu_sparc_dump_state
|
518 | 93ac68bc | bellard | |
519 | 67867308 | bellard | #elif defined(TARGET_PPC)
|
520 | 67867308 | bellard | |
521 | 67867308 | bellard | #define CPUState CPUPPCState
|
522 | 67867308 | bellard | #define cpu_init cpu_ppc_init
|
523 | 67867308 | bellard | #define cpu_exec cpu_ppc_exec
|
524 | 67867308 | bellard | #define cpu_gen_code cpu_ppc_gen_code
|
525 | 67867308 | bellard | #define cpu_interrupt cpu_ppc_interrupt
|
526 | 67867308 | bellard | #define cpu_signal_handler cpu_ppc_signal_handler
|
527 | 09683d35 | bellard | #define cpu_dump_state cpu_ppc_dump_state
|
528 | 67867308 | bellard | |
529 | 5a9fdfec | bellard | #else
|
530 | 5a9fdfec | bellard | |
531 | 5a9fdfec | bellard | #error unsupported target CPU
|
532 | 5a9fdfec | bellard | |
533 | 5a9fdfec | bellard | #endif
|
534 | 5a9fdfec | bellard | |
535 | 972ddf78 | bellard | #endif /* SINGLE_CPU_DEFINES */ |
536 | 972ddf78 | bellard | |
537 | 3b0dca51 | bellard | #define DEFAULT_GDBSTUB_PORT 1234 |
538 | 3b0dca51 | bellard | |
539 | 972ddf78 | bellard | void cpu_abort(CPUState *env, const char *fmt, ...); |
540 | e2f22898 | bellard | extern CPUState *cpu_single_env;
|
541 | 9acbed06 | bellard | extern int code_copy_enabled; |
542 | 5a9fdfec | bellard | |
543 | 9acbed06 | bellard | #define CPU_INTERRUPT_EXIT 0x01 /* wants exit from main loop */ |
544 | 9acbed06 | bellard | #define CPU_INTERRUPT_HARD 0x02 /* hardware interrupt pending */ |
545 | 9acbed06 | bellard | #define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */ |
546 | 4690764b | bellard | void cpu_interrupt(CPUState *s, int mask); |
547 | 68a79315 | bellard | |
548 | 4c3a88a2 | bellard | int cpu_breakpoint_insert(CPUState *env, uint32_t pc);
|
549 | 4c3a88a2 | bellard | int cpu_breakpoint_remove(CPUState *env, uint32_t pc);
|
550 | c33a346e | bellard | void cpu_single_step(CPUState *env, int enabled); |
551 | 4c3a88a2 | bellard | |
552 | 13eb76e0 | bellard | /* Return the physical page corresponding to a virtual one. Use it
|
553 | 13eb76e0 | bellard | only for debugging because no protection checks are done. Return -1
|
554 | 13eb76e0 | bellard | if no page found. */
|
555 | 13eb76e0 | bellard | target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr); |
556 | 13eb76e0 | bellard | |
557 | 34865134 | bellard | #define CPU_LOG_ALL 1 |
558 | 34865134 | bellard | void cpu_set_log(int log_flags); |
559 | 34865134 | bellard | void cpu_set_log_filename(const char *filename); |
560 | 34865134 | bellard | |
561 | 09683d35 | bellard | /* IO ports API */
|
562 | 09683d35 | bellard | |
563 | 09683d35 | bellard | /* NOTE: as these functions may be even used when there is an isa
|
564 | 09683d35 | bellard | brige on non x86 targets, we always defined them */
|
565 | 09683d35 | bellard | #ifndef NO_CPU_IO_DEFS
|
566 | 09683d35 | bellard | void cpu_outb(CPUState *env, int addr, int val); |
567 | 09683d35 | bellard | void cpu_outw(CPUState *env, int addr, int val); |
568 | 09683d35 | bellard | void cpu_outl(CPUState *env, int addr, int val); |
569 | 09683d35 | bellard | int cpu_inb(CPUState *env, int addr); |
570 | 09683d35 | bellard | int cpu_inw(CPUState *env, int addr); |
571 | 09683d35 | bellard | int cpu_inl(CPUState *env, int addr); |
572 | 09683d35 | bellard | #endif
|
573 | 09683d35 | bellard | |
574 | 33417e70 | bellard | /* memory API */
|
575 | 33417e70 | bellard | |
576 | edf75d59 | bellard | extern int phys_ram_size; |
577 | edf75d59 | bellard | extern int phys_ram_fd; |
578 | edf75d59 | bellard | extern uint8_t *phys_ram_base;
|
579 | 1ccde1cb | bellard | extern uint8_t *phys_ram_dirty;
|
580 | edf75d59 | bellard | |
581 | edf75d59 | bellard | /* physical memory access */
|
582 | edf75d59 | bellard | #define IO_MEM_NB_ENTRIES 256 |
583 | edf75d59 | bellard | #define TLB_INVALID_MASK (1 << 3) |
584 | edf75d59 | bellard | #define IO_MEM_SHIFT 4 |
585 | edf75d59 | bellard | |
586 | edf75d59 | bellard | #define IO_MEM_RAM (0 << IO_MEM_SHIFT) /* hardcoded offset */ |
587 | edf75d59 | bellard | #define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */ |
588 | edf75d59 | bellard | #define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT) |
589 | 1ccde1cb | bellard | #define IO_MEM_CODE (3 << IO_MEM_SHIFT) /* used internally, never use directly */ |
590 | 1ccde1cb | bellard | #define IO_MEM_NOTDIRTY (4 << IO_MEM_SHIFT) /* used internally, never use directly */ |
591 | edf75d59 | bellard | |
592 | 1ccde1cb | bellard | /* NOTE: vaddr is only used internally. Never use it except if you know what you do */
|
593 | 1ccde1cb | bellard | typedef void CPUWriteMemoryFunc(uint32_t addr, uint32_t value, uint32_t vaddr); |
594 | 33417e70 | bellard | typedef uint32_t CPUReadMemoryFunc(uint32_t addr);
|
595 | 33417e70 | bellard | |
596 | 33417e70 | bellard | void cpu_register_physical_memory(unsigned long start_addr, unsigned long size, |
597 | 33417e70 | bellard | long phys_offset);
|
598 | 33417e70 | bellard | int cpu_register_io_memory(int io_index, |
599 | 33417e70 | bellard | CPUReadMemoryFunc **mem_read, |
600 | 33417e70 | bellard | CPUWriteMemoryFunc **mem_write); |
601 | 33417e70 | bellard | |
602 | 13eb76e0 | bellard | void cpu_physical_memory_rw(CPUState *env, uint8_t *buf, target_ulong addr,
|
603 | 13eb76e0 | bellard | int len, int is_write); |
604 | 13eb76e0 | bellard | int cpu_memory_rw_debug(CPUState *env,
|
605 | 13eb76e0 | bellard | uint8_t *buf, target_ulong addr, int len, int is_write); |
606 | 13eb76e0 | bellard | |
607 | 1ccde1cb | bellard | /* read dirty bit (return 0 or 1) */
|
608 | 1ccde1cb | bellard | static inline int cpu_physical_memory_is_dirty(target_ulong addr) |
609 | 1ccde1cb | bellard | { |
610 | 1ccde1cb | bellard | return phys_ram_dirty[addr >> TARGET_PAGE_BITS];
|
611 | 1ccde1cb | bellard | } |
612 | 1ccde1cb | bellard | |
613 | 1ccde1cb | bellard | static inline void cpu_physical_memory_set_dirty(target_ulong addr) |
614 | 1ccde1cb | bellard | { |
615 | 1ccde1cb | bellard | phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 1;
|
616 | 1ccde1cb | bellard | } |
617 | 1ccde1cb | bellard | |
618 | 1ccde1cb | bellard | void cpu_physical_memory_reset_dirty(target_ulong start, target_ulong end);
|
619 | 1ccde1cb | bellard | |
620 | 3b0dca51 | bellard | /* gdb stub API */
|
621 | 3b0dca51 | bellard | extern int gdbstub_fd; |
622 | 3b0dca51 | bellard | CPUState *cpu_gdbstub_get_env(void *opaque);
|
623 | 4c3a88a2 | bellard | int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port); |
624 | 3b0dca51 | bellard | |
625 | 5a9fdfec | bellard | #endif /* CPU_ALL_H */ |