Commit 5a9fdfec7eff4f053705cf160be87ebf01a57833
1 parent
d19893da
factorized cpu defines
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@243 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
308 additions
and
253 deletions
cpu-all.h
0 → 100644
1 | +/* | |
2 | + * defines common to all virtual CPUs | |
3 | + * | |
4 | + * Copyright (c) 2003 Fabrice Bellard | |
5 | + * | |
6 | + * This library is free software; you can redistribute it and/or | |
7 | + * modify it under the terms of the GNU Lesser General Public | |
8 | + * License as published by the Free Software Foundation; either | |
9 | + * version 2 of the License, or (at your option) any later version. | |
10 | + * | |
11 | + * This library is distributed in the hope that it will be useful, | |
12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | + * Lesser General Public License for more details. | |
15 | + * | |
16 | + * You should have received a copy of the GNU Lesser General Public | |
17 | + * License along with this library; if not, write to the Free Software | |
18 | + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | + */ | |
20 | +#ifndef CPU_ALL_H | |
21 | +#define CPU_ALL_H | |
22 | + | |
23 | +/* all CPU memory access use these macros */ | |
24 | +static inline int ldub(void *ptr) | |
25 | +{ | |
26 | + return *(uint8_t *)ptr; | |
27 | +} | |
28 | + | |
29 | +static inline int ldsb(void *ptr) | |
30 | +{ | |
31 | + return *(int8_t *)ptr; | |
32 | +} | |
33 | + | |
34 | +static inline void stb(void *ptr, int v) | |
35 | +{ | |
36 | + *(uint8_t *)ptr = v; | |
37 | +} | |
38 | + | |
39 | +/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the | |
40 | + kernel handles unaligned load/stores may give better results, but | |
41 | + it is a system wide setting : bad */ | |
42 | +#if defined(WORDS_BIGENDIAN) || defined(__arm__) | |
43 | + | |
44 | +/* conservative code for little endian unaligned accesses */ | |
45 | +static inline int lduw(void *ptr) | |
46 | +{ | |
47 | +#ifdef __powerpc__ | |
48 | + int val; | |
49 | + __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); | |
50 | + return val; | |
51 | +#else | |
52 | + uint8_t *p = ptr; | |
53 | + return p[0] | (p[1] << 8); | |
54 | +#endif | |
55 | +} | |
56 | + | |
57 | +static inline int ldsw(void *ptr) | |
58 | +{ | |
59 | +#ifdef __powerpc__ | |
60 | + int val; | |
61 | + __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); | |
62 | + return (int16_t)val; | |
63 | +#else | |
64 | + uint8_t *p = ptr; | |
65 | + return (int16_t)(p[0] | (p[1] << 8)); | |
66 | +#endif | |
67 | +} | |
68 | + | |
69 | +static inline int ldl(void *ptr) | |
70 | +{ | |
71 | +#ifdef __powerpc__ | |
72 | + int val; | |
73 | + __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr)); | |
74 | + return val; | |
75 | +#else | |
76 | + uint8_t *p = ptr; | |
77 | + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); | |
78 | +#endif | |
79 | +} | |
80 | + | |
81 | +static inline uint64_t ldq(void *ptr) | |
82 | +{ | |
83 | + uint8_t *p = ptr; | |
84 | + uint32_t v1, v2; | |
85 | + v1 = ldl(p); | |
86 | + v2 = ldl(p + 4); | |
87 | + return v1 | ((uint64_t)v2 << 32); | |
88 | +} | |
89 | + | |
90 | +static inline void stw(void *ptr, int v) | |
91 | +{ | |
92 | +#ifdef __powerpc__ | |
93 | + __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr)); | |
94 | +#else | |
95 | + uint8_t *p = ptr; | |
96 | + p[0] = v; | |
97 | + p[1] = v >> 8; | |
98 | +#endif | |
99 | +} | |
100 | + | |
101 | +static inline void stl(void *ptr, int v) | |
102 | +{ | |
103 | +#ifdef __powerpc__ | |
104 | + __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr)); | |
105 | +#else | |
106 | + uint8_t *p = ptr; | |
107 | + p[0] = v; | |
108 | + p[1] = v >> 8; | |
109 | + p[2] = v >> 16; | |
110 | + p[3] = v >> 24; | |
111 | +#endif | |
112 | +} | |
113 | + | |
114 | +static inline void stq(void *ptr, uint64_t v) | |
115 | +{ | |
116 | + uint8_t *p = ptr; | |
117 | + stl(p, (uint32_t)v); | |
118 | + stl(p + 4, v >> 32); | |
119 | +} | |
120 | + | |
121 | +/* float access */ | |
122 | + | |
123 | +static inline float ldfl(void *ptr) | |
124 | +{ | |
125 | + union { | |
126 | + float f; | |
127 | + uint32_t i; | |
128 | + } u; | |
129 | + u.i = ldl(ptr); | |
130 | + return u.f; | |
131 | +} | |
132 | + | |
133 | +static inline void stfl(void *ptr, float v) | |
134 | +{ | |
135 | + union { | |
136 | + float f; | |
137 | + uint32_t i; | |
138 | + } u; | |
139 | + u.f = v; | |
140 | + stl(ptr, u.i); | |
141 | +} | |
142 | + | |
143 | +#if defined(__arm__) && !defined(WORDS_BIGENDIAN) | |
144 | + | |
145 | +/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */ | |
146 | +static inline double ldfq(void *ptr) | |
147 | +{ | |
148 | + union { | |
149 | + double d; | |
150 | + uint32_t tab[2]; | |
151 | + } u; | |
152 | + u.tab[1] = ldl(ptr); | |
153 | + u.tab[0] = ldl(ptr + 4); | |
154 | + return u.d; | |
155 | +} | |
156 | + | |
157 | +static inline void stfq(void *ptr, double v) | |
158 | +{ | |
159 | + union { | |
160 | + double d; | |
161 | + uint32_t tab[2]; | |
162 | + } u; | |
163 | + u.d = v; | |
164 | + stl(ptr, u.tab[1]); | |
165 | + stl(ptr + 4, u.tab[0]); | |
166 | +} | |
167 | + | |
168 | +#else | |
169 | +static inline double ldfq(void *ptr) | |
170 | +{ | |
171 | + union { | |
172 | + double d; | |
173 | + uint64_t i; | |
174 | + } u; | |
175 | + u.i = ldq(ptr); | |
176 | + return u.d; | |
177 | +} | |
178 | + | |
179 | +static inline void stfq(void *ptr, double v) | |
180 | +{ | |
181 | + union { | |
182 | + double d; | |
183 | + uint64_t i; | |
184 | + } u; | |
185 | + u.d = v; | |
186 | + stq(ptr, u.i); | |
187 | +} | |
188 | +#endif | |
189 | + | |
190 | +#else | |
191 | + | |
192 | +static inline int lduw(void *ptr) | |
193 | +{ | |
194 | + return *(uint16_t *)ptr; | |
195 | +} | |
196 | + | |
197 | +static inline int ldsw(void *ptr) | |
198 | +{ | |
199 | + return *(int16_t *)ptr; | |
200 | +} | |
201 | + | |
202 | +static inline int ldl(void *ptr) | |
203 | +{ | |
204 | + return *(uint32_t *)ptr; | |
205 | +} | |
206 | + | |
207 | +static inline uint64_t ldq(void *ptr) | |
208 | +{ | |
209 | + return *(uint64_t *)ptr; | |
210 | +} | |
211 | + | |
212 | +static inline void stw(void *ptr, int v) | |
213 | +{ | |
214 | + *(uint16_t *)ptr = v; | |
215 | +} | |
216 | + | |
217 | +static inline void stl(void *ptr, int v) | |
218 | +{ | |
219 | + *(uint32_t *)ptr = v; | |
220 | +} | |
221 | + | |
222 | +static inline void stq(void *ptr, uint64_t v) | |
223 | +{ | |
224 | + *(uint64_t *)ptr = v; | |
225 | +} | |
226 | + | |
227 | +/* float access */ | |
228 | + | |
229 | +static inline float ldfl(void *ptr) | |
230 | +{ | |
231 | + return *(float *)ptr; | |
232 | +} | |
233 | + | |
234 | +static inline double ldfq(void *ptr) | |
235 | +{ | |
236 | + return *(double *)ptr; | |
237 | +} | |
238 | + | |
239 | +static inline void stfl(void *ptr, float v) | |
240 | +{ | |
241 | + *(float *)ptr = v; | |
242 | +} | |
243 | + | |
244 | +static inline void stfq(void *ptr, double v) | |
245 | +{ | |
246 | + *(double *)ptr = v; | |
247 | +} | |
248 | +#endif | |
249 | + | |
250 | +/* page related stuff */ | |
251 | + | |
252 | +#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS) | |
253 | +#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1) | |
254 | +#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK) | |
255 | + | |
256 | +extern unsigned long real_host_page_size; | |
257 | +extern unsigned long host_page_bits; | |
258 | +extern unsigned long host_page_size; | |
259 | +extern unsigned long host_page_mask; | |
260 | + | |
261 | +#define HOST_PAGE_ALIGN(addr) (((addr) + host_page_size - 1) & host_page_mask) | |
262 | + | |
263 | +/* same as PROT_xxx */ | |
264 | +#define PAGE_READ 0x0001 | |
265 | +#define PAGE_WRITE 0x0002 | |
266 | +#define PAGE_EXEC 0x0004 | |
267 | +#define PAGE_BITS (PAGE_READ | PAGE_WRITE | PAGE_EXEC) | |
268 | +#define PAGE_VALID 0x0008 | |
269 | +/* original state of the write flag (used when tracking self-modifying | |
270 | + code */ | |
271 | +#define PAGE_WRITE_ORG 0x0010 | |
272 | + | |
273 | +void page_dump(FILE *f); | |
274 | +int page_get_flags(unsigned long address); | |
275 | +void page_set_flags(unsigned long start, unsigned long end, int flags); | |
276 | +void page_unprotect_range(uint8_t *data, unsigned long data_size); | |
277 | + | |
278 | +#define SINGLE_CPU_DEFINES | |
279 | +#ifdef SINGLE_CPU_DEFINES | |
280 | + | |
281 | +#if defined(TARGET_I386) | |
282 | + | |
283 | +#define CPUState CPUX86State | |
284 | +#define cpu_init cpu_x86_init | |
285 | +#define cpu_exec cpu_x86_exec | |
286 | +#define cpu_gen_code cpu_x86_gen_code | |
287 | +#define cpu_interrupt cpu_x86_interrupt | |
288 | +#define cpu_signal_handler cpu_x86_signal_handler | |
289 | + | |
290 | +#elif defined(TARGET_ARM) | |
291 | + | |
292 | +#define CPUState CPUARMState | |
293 | +#define cpu_init cpu_arm_init | |
294 | +#define cpu_exec cpu_arm_exec | |
295 | +#define cpu_gen_code cpu_arm_gen_code | |
296 | +#define cpu_interrupt cpu_arm_interrupt | |
297 | +#define cpu_signal_handler cpu_arm_signal_handler | |
298 | + | |
299 | +#else | |
300 | + | |
301 | +#error unsupported target CPU | |
302 | + | |
303 | +#endif | |
304 | + | |
305 | +#endif | |
306 | + | |
307 | +#endif /* CPU_ALL_H */ | ... | ... |
cpu-i386.h
... | ... | @@ -222,233 +222,6 @@ typedef struct CPUX86State { |
222 | 222 | void *opaque; |
223 | 223 | } CPUX86State; |
224 | 224 | |
225 | -/* all CPU memory access use these macros */ | |
226 | -static inline int ldub(void *ptr) | |
227 | -{ | |
228 | - return *(uint8_t *)ptr; | |
229 | -} | |
230 | - | |
231 | -static inline int ldsb(void *ptr) | |
232 | -{ | |
233 | - return *(int8_t *)ptr; | |
234 | -} | |
235 | - | |
236 | -static inline void stb(void *ptr, int v) | |
237 | -{ | |
238 | - *(uint8_t *)ptr = v; | |
239 | -} | |
240 | - | |
241 | -/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the | |
242 | - kernel handles unaligned load/stores may give better results, but | |
243 | - it is a system wide setting : bad */ | |
244 | -#if defined(WORDS_BIGENDIAN) || defined(__arm__) | |
245 | - | |
246 | -/* conservative code for little endian unaligned accesses */ | |
247 | -static inline int lduw(void *ptr) | |
248 | -{ | |
249 | -#ifdef __powerpc__ | |
250 | - int val; | |
251 | - __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); | |
252 | - return val; | |
253 | -#else | |
254 | - uint8_t *p = ptr; | |
255 | - return p[0] | (p[1] << 8); | |
256 | -#endif | |
257 | -} | |
258 | - | |
259 | -static inline int ldsw(void *ptr) | |
260 | -{ | |
261 | -#ifdef __powerpc__ | |
262 | - int val; | |
263 | - __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr)); | |
264 | - return (int16_t)val; | |
265 | -#else | |
266 | - uint8_t *p = ptr; | |
267 | - return (int16_t)(p[0] | (p[1] << 8)); | |
268 | -#endif | |
269 | -} | |
270 | - | |
271 | -static inline int ldl(void *ptr) | |
272 | -{ | |
273 | -#ifdef __powerpc__ | |
274 | - int val; | |
275 | - __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr)); | |
276 | - return val; | |
277 | -#else | |
278 | - uint8_t *p = ptr; | |
279 | - return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); | |
280 | -#endif | |
281 | -} | |
282 | - | |
283 | -static inline uint64_t ldq(void *ptr) | |
284 | -{ | |
285 | - uint8_t *p = ptr; | |
286 | - uint32_t v1, v2; | |
287 | - v1 = ldl(p); | |
288 | - v2 = ldl(p + 4); | |
289 | - return v1 | ((uint64_t)v2 << 32); | |
290 | -} | |
291 | - | |
292 | -static inline void stw(void *ptr, int v) | |
293 | -{ | |
294 | -#ifdef __powerpc__ | |
295 | - __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr)); | |
296 | -#else | |
297 | - uint8_t *p = ptr; | |
298 | - p[0] = v; | |
299 | - p[1] = v >> 8; | |
300 | -#endif | |
301 | -} | |
302 | - | |
303 | -static inline void stl(void *ptr, int v) | |
304 | -{ | |
305 | -#ifdef __powerpc__ | |
306 | - __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr)); | |
307 | -#else | |
308 | - uint8_t *p = ptr; | |
309 | - p[0] = v; | |
310 | - p[1] = v >> 8; | |
311 | - p[2] = v >> 16; | |
312 | - p[3] = v >> 24; | |
313 | -#endif | |
314 | -} | |
315 | - | |
316 | -static inline void stq(void *ptr, uint64_t v) | |
317 | -{ | |
318 | - uint8_t *p = ptr; | |
319 | - stl(p, (uint32_t)v); | |
320 | - stl(p + 4, v >> 32); | |
321 | -} | |
322 | - | |
323 | -/* float access */ | |
324 | - | |
325 | -static inline float ldfl(void *ptr) | |
326 | -{ | |
327 | - union { | |
328 | - float f; | |
329 | - uint32_t i; | |
330 | - } u; | |
331 | - u.i = ldl(ptr); | |
332 | - return u.f; | |
333 | -} | |
334 | - | |
335 | -static inline void stfl(void *ptr, float v) | |
336 | -{ | |
337 | - union { | |
338 | - float f; | |
339 | - uint32_t i; | |
340 | - } u; | |
341 | - u.f = v; | |
342 | - stl(ptr, u.i); | |
343 | -} | |
344 | - | |
345 | -#if defined(__arm__) && !defined(WORDS_BIGENDIAN) | |
346 | - | |
347 | -/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */ | |
348 | -static inline double ldfq(void *ptr) | |
349 | -{ | |
350 | - union { | |
351 | - double d; | |
352 | - uint32_t tab[2]; | |
353 | - } u; | |
354 | - u.tab[1] = ldl(ptr); | |
355 | - u.tab[0] = ldl(ptr + 4); | |
356 | - return u.d; | |
357 | -} | |
358 | - | |
359 | -static inline void stfq(void *ptr, double v) | |
360 | -{ | |
361 | - union { | |
362 | - double d; | |
363 | - uint32_t tab[2]; | |
364 | - } u; | |
365 | - u.d = v; | |
366 | - stl(ptr, u.tab[1]); | |
367 | - stl(ptr + 4, u.tab[0]); | |
368 | -} | |
369 | - | |
370 | -#else | |
371 | -static inline double ldfq(void *ptr) | |
372 | -{ | |
373 | - union { | |
374 | - double d; | |
375 | - uint64_t i; | |
376 | - } u; | |
377 | - u.i = ldq(ptr); | |
378 | - return u.d; | |
379 | -} | |
380 | - | |
381 | -static inline void stfq(void *ptr, double v) | |
382 | -{ | |
383 | - union { | |
384 | - double d; | |
385 | - uint64_t i; | |
386 | - } u; | |
387 | - u.d = v; | |
388 | - stq(ptr, u.i); | |
389 | -} | |
390 | -#endif | |
391 | - | |
392 | -#else | |
393 | - | |
394 | -static inline int lduw(void *ptr) | |
395 | -{ | |
396 | - return *(uint16_t *)ptr; | |
397 | -} | |
398 | - | |
399 | -static inline int ldsw(void *ptr) | |
400 | -{ | |
401 | - return *(int16_t *)ptr; | |
402 | -} | |
403 | - | |
404 | -static inline int ldl(void *ptr) | |
405 | -{ | |
406 | - return *(uint32_t *)ptr; | |
407 | -} | |
408 | - | |
409 | -static inline uint64_t ldq(void *ptr) | |
410 | -{ | |
411 | - return *(uint64_t *)ptr; | |
412 | -} | |
413 | - | |
414 | -static inline void stw(void *ptr, int v) | |
415 | -{ | |
416 | - *(uint16_t *)ptr = v; | |
417 | -} | |
418 | - | |
419 | -static inline void stl(void *ptr, int v) | |
420 | -{ | |
421 | - *(uint32_t *)ptr = v; | |
422 | -} | |
423 | - | |
424 | -static inline void stq(void *ptr, uint64_t v) | |
425 | -{ | |
426 | - *(uint64_t *)ptr = v; | |
427 | -} | |
428 | - | |
429 | -/* float access */ | |
430 | - | |
431 | -static inline float ldfl(void *ptr) | |
432 | -{ | |
433 | - return *(float *)ptr; | |
434 | -} | |
435 | - | |
436 | -static inline double ldfq(void *ptr) | |
437 | -{ | |
438 | - return *(double *)ptr; | |
439 | -} | |
440 | - | |
441 | -static inline void stfl(void *ptr, float v) | |
442 | -{ | |
443 | - *(float *)ptr = v; | |
444 | -} | |
445 | - | |
446 | -static inline void stfq(void *ptr, double v) | |
447 | -{ | |
448 | - *(double *)ptr = v; | |
449 | -} | |
450 | -#endif | |
451 | - | |
452 | 225 | #ifndef IN_OP_I386 |
453 | 226 | void cpu_x86_outb(CPUX86State *env, int addr, int val); |
454 | 227 | void cpu_x86_outw(CPUX86State *env, int addr, int val); |
... | ... | @@ -482,32 +255,7 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, |
482 | 255 | #define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */ |
483 | 256 | void cpu_x86_dump_state(CPUX86State *env, FILE *f, int flags); |
484 | 257 | |
485 | -/* page related stuff */ | |
486 | 258 | #define TARGET_PAGE_BITS 12 |
487 | -#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS) | |
488 | -#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1) | |
489 | -#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK) | |
490 | - | |
491 | -extern unsigned long real_host_page_size; | |
492 | -extern unsigned long host_page_bits; | |
493 | -extern unsigned long host_page_size; | |
494 | -extern unsigned long host_page_mask; | |
495 | - | |
496 | -#define HOST_PAGE_ALIGN(addr) (((addr) + host_page_size - 1) & host_page_mask) | |
497 | - | |
498 | -/* same as PROT_xxx */ | |
499 | -#define PAGE_READ 0x0001 | |
500 | -#define PAGE_WRITE 0x0002 | |
501 | -#define PAGE_EXEC 0x0004 | |
502 | -#define PAGE_BITS (PAGE_READ | PAGE_WRITE | PAGE_EXEC) | |
503 | -#define PAGE_VALID 0x0008 | |
504 | -/* original state of the write flag (used when tracking self-modifying | |
505 | - code */ | |
506 | -#define PAGE_WRITE_ORG 0x0010 | |
507 | - | |
508 | -void page_dump(FILE *f); | |
509 | -int page_get_flags(unsigned long address); | |
510 | -void page_set_flags(unsigned long start, unsigned long end, int flags); | |
511 | -void page_unprotect_range(uint8_t *data, unsigned long data_size); | |
259 | +#include "cpu-all.h" | |
512 | 260 | |
513 | 261 | #endif /* CPU_I386_H */ | ... | ... |