VirtualBox

root/trunk/src/recompiler/cpu-all.h

Revision 13839, 30.4 kB (checked in by vboxsync, 2 months ago)

And yet more %V* -> %R* changes...

  • Property svn:eol-style set to native
Line 
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
21 /*
22  * Sun LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
23  * other than GPL or LGPL is available it will apply instead, Sun elects to use only
24  * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
25  * a choice of LGPL license versions is made available with the language indicating
26  * that LGPLv2 or any later version may be used, or where a choice of which version
27  * of the LGPL is applied is otherwise unspecified.
28  */
29 #ifndef CPU_ALL_H
30 #define CPU_ALL_H
31
32 #ifdef VBOX
33 # ifndef LOG_GROUP
34 include <VBox/log.h>
35 define LOG_GROUP LOG_GROUP_REM
36 # endif
37 # include <VBox/pgm.h> /* PGM_DYNAMIC_RAM_ALLOC */
38 #endif
39
40 #if defined(__arm__) || defined(__sparc__)
41 #define WORDS_ALIGNED
42 #endif
43
44 /* some important defines:
45  *
46  * WORDS_ALIGNED : if defined, the host cpu can only make word aligned
47  * memory accesses.
48  *
49  * WORDS_BIGENDIAN : if defined, the host cpu is big endian and
50  * otherwise little endian.
51  *
52  * (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet))
53  *
54  * TARGET_WORDS_BIGENDIAN : same for target cpu
55  */
56
57 #include "bswap.h"
58
59 #if defined(WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
60 #define BSWAP_NEEDED
61 #endif
62
63 #ifdef BSWAP_NEEDED
64
65 static inline uint16_t tswap16(uint16_t s)
66 {
67     return bswap16(s);
68 }
69
70 static inline uint32_t tswap32(uint32_t s)
71 {
72     return bswap32(s);
73 }
74
75 static inline uint64_t tswap64(uint64_t s)
76 {
77     return bswap64(s);
78 }
79
80 static inline void tswap16s(uint16_t *s)
81 {
82     *s = bswap16(*s);
83 }
84
85 static inline void tswap32s(uint32_t *s)
86 {
87     *s = bswap32(*s);
88 }
89
90 static inline void tswap64s(uint64_t *s)
91 {
92     *s = bswap64(*s);
93 }
94
95 #else
96
97 static inline uint16_t tswap16(uint16_t s)
98 {
99     return s;
100 }
101
102 static inline uint32_t tswap32(uint32_t s)
103 {
104     return s;
105 }
106
107 static inline uint64_t tswap64(uint64_t s)
108 {
109     return s;
110 }
111
112 static inline void tswap16s(uint16_t *s)
113 {
114 }
115
116 static inline void tswap32s(uint32_t *s)
117 {
118 }
119
120 static inline void tswap64s(uint64_t *s)
121 {
122 }
123
124 #endif
125
126 #if TARGET_LONG_SIZE == 4
127 #define tswapl(s) tswap32(s)
128 #define tswapls(s) tswap32s((uint32_t *)(s))
129 #define bswaptls(s) bswap32s(s)
130 #else
131 #define tswapl(s) tswap64(s)
132 #define tswapls(s) tswap64s((uint64_t *)(s))
133 #define bswaptls(s) bswap64s(s)
134 #endif
135
136 /* NOTE: arm FPA is horrible as double 32 bit words are stored in big
137    endian ! */
138 typedef union {
139     float64 d;
140 #if defined(WORDS_BIGENDIAN) \
141     || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
142     struct {
143         uint32_t upper;
144         uint32_t lower;
145     } l;
146 #else
147     struct {
148         uint32_t lower;
149         uint32_t upper;
150     } l;
151 #endif
152     uint64_t ll;
153 } CPU_DoubleU;
154
155 /* CPU memory access without any memory or io remapping */
156
157 /*
158  * the generic syntax for the memory accesses is:
159  *
160  * load: ld{type}{sign}{size}{endian}_{access_type}(ptr)
161  *
162  * store: st{type}{size}{endian}_{access_type}(ptr, val)
163  *
164  * type is:
165  * (empty): integer access
166  *   f    : float access
167  *
168  * sign is:
169  * (empty): for floats or 32 bit size
170  *   u    : unsigned
171  *   s    : signed
172  *
173  * size is:
174  *   b: 8 bits
175  *   w: 16 bits
176  *   l: 32 bits
177  *   q: 64 bits
178  *
179  * endian is:
180  * (empty): target cpu endianness or 8 bit access
181  *   r    : reversed target cpu endianness (not implemented yet)
182  *   be   : big endian (not implemented yet)
183  *   le   : little endian (not implemented yet)
184  *
185  * access_type is:
186  *   raw    : host memory access
187  *   user   : user mode access using soft MMU
188  *   kernel : kernel mode access using soft MMU
189  */
190 #ifdef VBOX
191
192 void     remR3PhysRead(RTGCPHYS SrcGCPhys, void *pvDst, unsigned cb);
193 uint8_t  remR3PhysReadU8(RTGCPHYS SrcGCPhys);
194 int8_t   remR3PhysReadS8(RTGCPHYS SrcGCPhys);
195 uint16_t remR3PhysReadU16(RTGCPHYS SrcGCPhys);
196 int16_t  remR3PhysReadS16(RTGCPHYS SrcGCPhys);
197 uint32_t remR3PhysReadU32(RTGCPHYS SrcGCPhys);
198 int32_t  remR3PhysReadS32(RTGCPHYS SrcGCPhys);
199 uint64_t remR3PhysReadU64(RTGCPHYS SrcGCPhys);
200 int64_t  remR3PhysReadS64(RTGCPHYS SrcGCPhys);
201 void     remR3PhysWrite(RTGCPHYS DstGCPhys, const void *pvSrc, unsigned cb);
202 void     remR3PhysWriteU8(RTGCPHYS DstGCPhys, uint8_t val);
203 void     remR3PhysWriteU16(RTGCPHYS DstGCPhys, uint16_t val);
204 void     remR3PhysWriteU32(RTGCPHYS DstGCPhys, uint32_t val);
205 void     remR3PhysWriteU64(RTGCPHYS DstGCPhys, uint64_t val);
206
207 #ifndef VBOX_WITH_NEW_PHYS_CODE
208 void     remR3GrowDynRange(unsigned long physaddr);
209 #endif
210 #if 0 /*defined(RT_ARCH_AMD64) && defined(VBOX_STRICT)*/
211 # define VBOX_CHECK_ADDR(ptr) do { if ((uintptr_t)(ptr) >= _4G) __asm__("int3"); } while (0)
212 #else
213 # define VBOX_CHECK_ADDR(ptr) do { } while (0)
214 #endif
215
216 static inline int ldub_p(void *ptr)
217 {
218     VBOX_CHECK_ADDR(ptr);
219     return remR3PhysReadU8((uintptr_t)ptr);
220 }
221
222 static inline int ldsb_p(void *ptr)
223 {
224     VBOX_CHECK_ADDR(ptr);
225     return remR3PhysReadS8((uintptr_t)ptr);
226 }
227
228 static inline void stb_p(void *ptr, int v)
229 {
230     VBOX_CHECK_ADDR(ptr);
231     remR3PhysWriteU8((uintptr_t)ptr, v);
232 }
233
234 static inline int lduw_le_p(void *ptr)
235 {
236     VBOX_CHECK_ADDR(ptr);
237     return remR3PhysReadU16((uintptr_t)ptr);
238 }
239
240 static inline int ldsw_le_p(void *ptr)
241 {
242     VBOX_CHECK_ADDR(ptr);
243     return remR3PhysReadS16((uintptr_t)ptr);
244 }
245
246 static inline void stw_le_p(void *ptr, int v)
247 {
248     VBOX_CHECK_ADDR(ptr);
249     remR3PhysWriteU16((uintptr_t)ptr, v);
250 }
251
252 static inline int ldl_le_p(void *ptr)
253 {
254     VBOX_CHECK_ADDR(ptr);
255     return remR3PhysReadU32((uintptr_t)ptr);
256 }
257
258 static inline void stl_le_p(void *ptr, int v)
259 {
260     VBOX_CHECK_ADDR(ptr);
261     remR3PhysWriteU32((uintptr_t)ptr, v);
262 }
263
264 static inline void stq_le_p(void *ptr, uint64_t v)
265 {
266     VBOX_CHECK_ADDR(ptr);
267     remR3PhysWriteU64((uintptr_t)ptr, v);
268 }
269
270 static inline uint64_t ldq_le_p(void *ptr)
271 {
272     VBOX_CHECK_ADDR(ptr);
273     return remR3PhysReadU64((uintptr_t)ptr);
274 }
275
276 #undef VBOX_CHECK_ADDR
277
278 /* float access */
279
280 static inline float32 ldfl_le_p(void *ptr)
281 {
282     union {
283         float32 f;
284         uint32_t i;
285     } u;
286     u.i = ldl_le_p(ptr);
287     return u.f;
288 }
289
290 static inline void stfl_le_p(void *ptr, float32 v)
291 {
292     union {
293         float32 f;
294         uint32_t i;
295     } u;
296     u.f = v;
297     stl_le_p(ptr, u.i);
298 }
299
300 static inline float64 ldfq_le_p(void *ptr)
301 {
302     CPU_DoubleU u;
303     u.l.lower = ldl_le_p(ptr);
304     u.l.upper = ldl_le_p(ptr + 4);
305     return u.d;
306 }
307
308 static inline void stfq_le_p(void *ptr, float64 v)
309 {
310     CPU_DoubleU u;
311     u.d = v;
312     stl_le_p(ptr, u.l.lower);
313     stl_le_p(ptr + 4, u.l.upper);
314 }
315
316 #else  /* !VBOX */
317
318 static inline int ldub_p(void *ptr)
319 {
320     return *(uint8_t *)ptr;
321 }
322
323 static inline int ldsb_p(void *ptr)
324 {
325     return *(int8_t *)ptr;
326 }
327
328 static inline void stb_p(void *ptr, int v)
329 {
330     *(uint8_t *)ptr = v;
331 }
332
333 /* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
334    kernel handles unaligned load/stores may give better results, but
335    it is a system wide setting : bad */
336 #if defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
337
338 /* conservative code for little endian unaligned accesses */
339 static inline int lduw_le_p(void *ptr)
340 {
341 #ifdef __powerpc__
342     int val;
343     __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
344     return val;
345 #else
346     uint8_t *p = ptr;
347     return p[0] | (p[1] << 8);
348 #endif
349 }
350
351 static inline int ldsw_le_p(void *ptr)
352 {
353 #ifdef __powerpc__
354     int val;
355     __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
356     return (int16_t)val;
357 #else
358     uint8_t *p = ptr;
359     return (int16_t)(p[0] | (p[1] << 8));
360 #endif
361 }
362
363 static inline int ldl_le_p(void *ptr)
364 {
365 #ifdef __powerpc__
366     int val;
367     __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
368     return val;
369 #else
370     uint8_t *p = ptr;
371     return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
372 #endif
373 }
374
375 static inline uint64_t ldq_le_p(void *ptr)
376 {
377     uint8_t *p = ptr;
378     uint32_t v1, v2;
379     v1 = ldl_le_p(p);
380     v2 = ldl_le_p(p + 4);
381     return v1 | ((uint64_t)v2 << 32);
382 }
383
384 static inline void stw_le_p(void *ptr, int v)
385 {
386 #ifdef __powerpc__
387     __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
388 #else
389     uint8_t *p = ptr;
390     p[0] = v;
391     p[1] = v >> 8;
392 #endif
393 }
394
395 static inline void stl_le_p(void *ptr, int v)
396 {
397 #ifdef __powerpc__
398     __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
399 #else
400     uint8_t *p = ptr;
401     p[0] = v;
402     p[1] = v >> 8;
403     p[2] = v >> 16;
404     p[3] = v >> 24;
405 #endif
406 }
407
408 static inline void stq_le_p(void *ptr, uint64_t v)
409 {
410     uint8_t *p = ptr;
411     stl_le_p(p, (uint32_t)v);
412     stl_le_p(p + 4, v >> 32);
413 }
414
415 /* float access */
416
417 static inline float32 ldfl_le_p(void *ptr)
418 {
419     union {
420         float32 f;
421         uint32_t i;
422     } u;
423     u.i = ldl_le_p(ptr);
424     return u.f;
425 }
426
427 static inline void stfl_le_p(void *ptr, float32 v)
428 {
429     union {
430         float32 f;
431         uint32_t i;
432     } u;
433     u.f = v;
434     stl_le_p(ptr, u.i);
435 }
436
437 static inline float64 ldfq_le_p(void *ptr)
438 {
439     CPU_DoubleU u;
440     u.l.lower = ldl_le_p(ptr);
441     u.l.upper = ldl_le_p(ptr + 4);
442     return u.d;
443 }
444
445 static inline void stfq_le_p(void *ptr, float64 v)
446 {
447     CPU_DoubleU u;
448     u.d = v;
449     stl_le_p(ptr, u.l.lower);
450     stl_le_p(ptr + 4, u.l.upper);
451 }
452
453 #else
454
455 static inline int lduw_le_p(void *ptr)
456 {
457     return *(uint16_t *)ptr;
458 }
459
460 static inline int ldsw_le_p(void *ptr)
461 {
462     return *(int16_t *)ptr;
463 }
464
465 static inline int ldl_le_p(void *ptr)
466 {
467     return *(uint32_t *)ptr;
468 }
469
470 static inline uint64_t ldq_le_p(void *ptr)
471 {
472     return *(uint64_t *)ptr;
473 }
474
475 static inline void stw_le_p(void *ptr, int v)
476 {
477     *(uint16_t *)ptr = v;
478 }
479
480 static inline void stl_le_p(void *ptr, int v)
481 {
482     *(uint32_t *)ptr = v;
483 }
484
485 static inline void stq_le_p(void *ptr, uint64_t v)
486 {
487     *(uint64_t *)ptr = v;
488 }
489
490 /* float access */
491
492 static inline float32 ldfl_le_p(void *ptr)
493 {
494     return *(float32 *)ptr;
495 }
496
497 static inline float64 ldfq_le_p(void *ptr)
498 {
499     return *(float64 *)ptr;
500 }
501
502 static inline void stfl_le_p(void *ptr, float32 v)
503 {
504     *(float32 *)ptr = v;
505 }
506
507 static inline void stfq_le_p(void *ptr, float64 v)
508 {
509     *(float64 *)ptr = v;
510 }
511 #endif
512 #endif /* !VBOX */
513
514 #if !defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
515
516 static inline int lduw_be_p(void *ptr)
517 {
518 #if defined(__i386__)
519     int val;
520     asm volatile ("movzwl %1, %0\n"
521                   "xchgb %b0, %h0\n"
522                   : "=q" (val)
523                   : "m" (*(uint16_t *)ptr));
524     return val;
525 #else
526     uint8_t *b = (uint8_t *) ptr;
527     return ((b[0] << 8) | b[1]);
528 #endif
529 }
530
531 static inline int ldsw_be_p(void *ptr)
532 {
533 #if defined(__i386__)
534     int val;
535     asm volatile ("movzwl %1, %0\n"
536                   "xchgb %b0, %h0\n"
537                   : "=q" (val)
538                   : "m" (*(uint16_t *)ptr));
539     return (int16_t)val;
540 #else
541     uint8_t *b = (uint8_t *) ptr;
542     return (int16_t)((b[0] << 8) | b[1]);
543 #endif
544 }
545
546 static inline int ldl_be_p(void *ptr)
547 {
548 #if defined(__i386__) || defined(__x86_64__)
549     int val;
550     asm volatile ("movl %1, %0\n"
551                   "bswap %0\n"
552                   : "=r" (val)
553                   : "m" (*(uint32_t *)ptr));
554     return val;
555 #else
556     uint8_t *b = (uint8_t *) ptr;
557     return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
558 #endif
559 }
560
561 static inline uint64_t ldq_be_p(void *ptr)
562 {
563     uint32_t a,b;
564     a = ldl_be_p(ptr);
565     b = ldl_be_p(ptr+4);
566     return (((uint64_t)a<<32)|b);
567 }
568
569 static inline void stw_be_p(void *ptr, int v)
570 {
571 #if defined(__i386__)
572     asm volatile ("xchgb %b0, %h0\n"
573                   "movw %w0, %1\n"
574                   : "=q" (v)
575                   : "m" (*(uint16_t *)ptr), "0" (v));
576 #else
577     uint8_t *d = (uint8_t *) ptr;
578     d[0] = v >> 8;
579     d[1] = v;
580 #endif
581 }
582
583 static inline void stl_be_p(void *ptr, int v)
584 {
585 #if defined(__i386__) || defined(__x86_64__)
586     asm volatile ("bswap %0\n"
587                   "movl %0, %1\n"
588                   : "=r" (v)
589                   : "m" (*(uint32_t *)ptr), "0" (v));
590 #else
591     uint8_t *d = (uint8_t *) ptr;
592     d[0] = v >> 24;
593     d[1] = v >> 16;
594     d[2] = v >> 8;
595     d[3] = v;
596 #endif
597 }
598
599 static inline void stq_be_p(void *ptr, uint64_t v)
600 {
601     stl_be_p(ptr, v >> 32);
602     stl_be_p(ptr + 4, v);
603 }
604
605 /* float access */
606
607 static inline float32 ldfl_be_p(void *ptr)
608 {
609     union {
610         float32 f;
611         uint32_t i;
612     } u;
613     u.i = ldl_be_p(ptr);
614     return u.f;
615 }
616
617 static inline void stfl_be_p(void *ptr, float32 v)
618 {
619     union {
620         float32 f;
621         uint32_t i;
622     } u;
623     u.f = v;
624     stl_be_p(ptr, u.i);
625 }
626
627 static inline float64 ldfq_be_p(void *ptr)
628 {
629     CPU_DoubleU u;
630     u.l.upper = ldl_be_p(ptr);
631     u.l.lower = ldl_be_p(ptr + 4);
632     return u.d;
633 }
634
635 static inline void stfq_be_p(void *ptr, float64 v)
636 {
637     CPU_DoubleU u;
638     u.d = v;
639     stl_be_p(ptr, u.l.upper);
640     stl_be_p(ptr + 4, u.l.lower);
641 }
642
643 #else
644
645 static inline int lduw_be_p(void *ptr)
646 {
647     return *(uint16_t *)ptr;
648 }
649
650 static inline int ldsw_be_p(void *ptr)
651 {
652     return *(int16_t *)ptr;
653 }
654
655 static inline int ldl_be_p(void *ptr)
656 {
657     return *(uint32_t *)ptr;
658 }
659
660 static inline uint64_t ldq_be_p(void *ptr)
661 {
662     return *(uint64_t *)ptr;
663 }
664
665 static inline void stw_be_p(void *ptr, int v)
666 {
667     *(uint16_t *)ptr = v;
668 }
669
670 static inline void stl_be_p(void *ptr, int v)
671 {
672     *(uint32_t *)ptr = v;
673 }
674
675 static inline void stq_be_p(void *ptr, uint64_t v)
676 {
677     *(uint64_t *)ptr = v;
678 }
679
680 /* float access */
681
682 static inline float32 ldfl_be_p(void *ptr)
683 {
684     return *(float32 *)ptr;
685 }
686
687 static inline float64 ldfq_be_p(void *ptr)
688 {
689     return *(float64 *)ptr;
690 }
691
692 static inline void stfl_be_p(void *ptr, float32 v)
693 {
694     *(float32 *)ptr = v;
695 }
696
697 static inline void stfq_be_p(void *ptr, float64 v)
698 {
699     *(float64 *)ptr = v;
700 }
701
702 #endif
703
704 /* target CPU memory access functions */
705 #if defined(TARGET_WORDS_BIGENDIAN)
706 #define lduw_p(p) lduw_be_p(p)
707 #define ldsw_p(p) ldsw_be_p(p)
708 #define ldl_p(p) ldl_be_p(p)
709 #define ldq_p(p) ldq_be_p(p)
710 #define ldfl_p(p) ldfl_be_p(p)
711 #define ldfq_p(p) ldfq_be_p(p)
712 #define stw_p(p, v) stw_be_p(p, v)
713 #define stl_p(p, v) stl_be_p(p, v)
714 #define stq_p(p, v) stq_be_p(p, v)
715 #define stfl_p(p, v) stfl_be_p(p, v)
716 #define stfq_p(p, v) stfq_be_p(p, v)
717 #else
718 #define lduw_p(p) lduw_le_p(p)
719 #define ldsw_p(p) ldsw_le_p(p)
720 #define ldl_p(p) ldl_le_p(p)
721 #define ldq_p(p) ldq_le_p(p)
722 #define ldfl_p(p) ldfl_le_p(p)
723 #define ldfq_p(p) ldfq_le_p(p)
724 #define stw_p(p, v) stw_le_p(p, v)
725 #define stl_p(p, v) stl_le_p(p, v)
726 #define stq_p(p, v) stq_le_p(p, v)
727 #define stfl_p(p, v) stfl_le_p(p, v)
728 #define stfq_p(p, v) stfq_le_p(p, v)
729 #endif
730
731 /* MMU memory access macros */
732
733 #if defined(CONFIG_USER_ONLY)
734 /* On some host systems the guest address space is reserved on the host.
735  * This allows the guest address space to be offset to a convenient location.
736  */
737 //#define GUEST_BASE 0x20000000
738 #define GUEST_BASE 0
739
740 /* All direct uses of g2h and h2g need to go away for usermode softmmu.  */
741 #define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
742 #define h2g(x) ((target_ulong)(x - GUEST_BASE))
743
744 #define saddr(x) g2h(x)
745 #define laddr(x) g2h(x)
746
747 #else /* !CONFIG_USER_ONLY */
748 /* NOTE: we use double casts if pointers and target_ulong have
749    different sizes */
750 #define saddr(x) (uint8_t *)(long)(x)
751 #define laddr(x) (uint8_t *)(long)(x)
752 #endif
753
754 #define ldub_raw(p) ldub_p(laddr((p)))
755 #define ldsb_raw(p) ldsb_p(laddr((p)))
756 #define lduw_raw(p) lduw_p(laddr((p)))
757 #define ldsw_raw(p) ldsw_p(laddr((p)))
758 #define ldl_raw(p) ldl_p(laddr((p)))
759 #define ldq_raw(p) ldq_p(laddr((p)))
760 #define ldfl_raw(p) ldfl_p(laddr((p)))
761 #define ldfq_raw(p) ldfq_p(laddr((p)))
762 #define stb_raw(p, v) stb_p(saddr((p)), v)
763 #define stw_raw(p, v) stw_p(saddr((p)), v)
764 #define stl_raw(p, v) stl_p(saddr((p)), v)
765 #define stq_raw(p, v) stq_p(saddr((p)), v)
766 #define stfl_raw(p, v) stfl_p(saddr((p)), v)
767 #define stfq_raw(p, v) stfq_p(saddr((p)), v)
768
769
770 #if defined(CONFIG_USER_ONLY)
771
772 /* if user mode, no other memory access functions */
773 #define ldub(p) ldub_raw(p)
774 #define ldsb(p) ldsb_raw(p)
775 #define lduw(p) lduw_raw(p)
776 #define ldsw(p) ldsw_raw(p)
777 #define ldl(p) ldl_raw(p)
778 #define ldq(p) ldq_raw(p)
779 #define ldfl(p) ldfl_raw(p)
780 #define ldfq(p) ldfq_raw(p)
781 #define stb(p, v) stb_raw(p, v)
782 #define stw(p, v) stw_raw(p, v)
783 #define stl(p, v) stl_raw(p, v)
784 #define stq(p, v) stq_raw(p, v)
785 #define stfl(p, v) stfl_raw(p, v)
786 #define stfq(p, v) stfq_raw(p, v)
787
788 #define ldub_code(p) ldub_raw(p)
789 #define ldsb_code(p) ldsb_raw(p)
790 #define lduw_code(p) lduw_raw(p)
791 #define ldsw_code(p) ldsw_raw(p)
792 #define ldl_code(p) ldl_raw(p)
793
794 #define ldub_kernel(p) ldub_raw(p)
795 #define ldsb_kernel(p) ldsb_raw(p)
796 #define lduw_kernel(p) lduw_raw(p)
797 #define ldsw_kernel(p) ldsw_raw(p)
798 #define ldl_kernel(p) ldl_raw(p)
799 #define ldfl_kernel(p) ldfl_raw(p)
800 #define ldfq_kernel(p) ldfq_raw(p)
801 #define stb_kernel(p, v) stb_raw(p, v)
802 #define stw_kernel(p, v) stw_raw(p, v)
803 #define stl_kernel(p, v) stl_raw(p, v)
804 #define stq_kernel(p, v) stq_raw(p, v)
805 #define stfl_kernel(p, v) stfl_raw(p, v)
806 #define stfq_kernel(p, vt) stfq_raw(p, v)
807
808 #endif /* defined(CONFIG_USER_ONLY) */
809
810 /* page related stuff */
811
812 #define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
813 #define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
814 #define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
815
816 /* ??? These should be the larger of unsigned long and target_ulong.  */
817 extern unsigned long qemu_real_host_page_size;
818 extern unsigned long qemu_host_page_bits;
819 extern unsigned long qemu_host_page_size;
820 extern unsigned long qemu_host_page_mask;
821
822 #define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
823
824 /* same as PROT_xxx */
825 #define PAGE_READ      0x0001
826 #define PAGE_WRITE     0x0002
827 #define PAGE_EXEC      0x0004
828 #define PAGE_BITS      (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
829 #define PAGE_VALID     0x0008
830 /* original state of the write flag (used when tracking self-modifying
831    code */
832 #define PAGE_WRITE_ORG 0x0010
833
834 void page_dump(FILE *f);
835 int page_get_flags(target_ulong address);
836 void page_set_flags(target_ulong start, target_ulong end, int flags);
837 void page_unprotect_range(target_ulong data, target_ulong data_size);
838
839 #define SINGLE_CPU_DEFINES
840 #ifdef SINGLE_CPU_DEFINES
841
842 #if defined(TARGET_I386)
843
844 #define CPUState CPUX86State
845 #define cpu_init cpu_x86_init
846 #define cpu_exec cpu_x86_exec
847 #define cpu_gen_code cpu_x86_gen_code
848 #define cpu_signal_handler cpu_x86_signal_handler
849
850 #elif defined(TARGET_ARM)
851
852 #define CPUState CPUARMState
853 #define cpu_init cpu_arm_init
854 #define cpu_exec cpu_arm_exec
855 #define cpu_gen_code cpu_arm_gen_code
856 #define cpu_signal_handler cpu_arm_signal_handler
857
858 #elif defined(TARGET_SPARC)
859
860 #define CPUState CPUSPARCState
861 #define cpu_init cpu_sparc_init
862 #define cpu_exec cpu_sparc_exec
863 #define cpu_gen_code cpu_sparc_gen_code
864 #define cpu_signal_handler cpu_sparc_signal_handler
865
866 #elif defined(TARGET_PPC)
867
868 #define CPUState CPUPPCState
869 #define cpu_init cpu_ppc_init
870 #define cpu_exec cpu_ppc_exec
871 #define cpu_gen_code cpu_ppc_gen_code
872 #define cpu_signal_handler cpu_ppc_signal_handler
873
874 #elif defined(TARGET_M68K)
875 #define CPUState CPUM68KState
876 #define cpu_init cpu_m68k_init
877 #define cpu_exec cpu_m68k_exec
878 #define cpu_gen_code cpu_m68k_gen_code
879 #define cpu_signal_handler cpu_m68k_signal_handler
880
881 #elif defined(TARGET_MIPS)
882 #define CPUState CPUMIPSState
883 #define cpu_init cpu_mips_init
884 #define cpu_exec cpu_mips_exec
885 #define cpu_gen_code cpu_mips_gen_code
886 #define cpu_signal_handler cpu_mips_signal_handler
887
888 #elif defined(TARGET_SH4)
889 #define CPUState CPUSH4State
890 #define cpu_init cpu_sh4_init
891 #define cpu_exec cpu_sh4_exec
892 #define cpu_gen_code cpu_sh4_gen_code
893 #define cpu_signal_handler cpu_sh4_signal_handler
894
895 #else
896
897 #error unsupported target CPU
898
899 #endif
900
901 #endif /* SINGLE_CPU_DEFINES */
902
903 void cpu_dump_state(CPUState *env, FILE *f,
904                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
905                     int flags);
906
907 DECLNORETURN(void) cpu_abort(CPUState *env, const char *fmt, ...);
908 extern CPUState *first_cpu;
909 extern CPUState *cpu_single_env;
910 extern int code_copy_enabled;
911
912 #define CPU_INTERRUPT_EXIT   0x01 /* wants exit from main loop */
913 #define CPU_INTERRUPT_HARD   0x02 /* hardware interrupt pending */
914 #define CPU_INTERRUPT_EXITTB 0x04 /* exit the current TB (use for x86 a20 case) */
915 #define CPU_INTERRUPT_TIMER  0x08 /* internal timer exception pending */
916 #define CPU_INTERRUPT_FIQ    0x10 /* Fast interrupt pending.  */
917 #define CPU_INTERRUPT_HALT   0x20 /* CPU halt wanted */
918 #define CPU_INTERRUPT_SMI    0x40 /* (x86 only) SMI interrupt pending */
919
920 #ifdef VBOX
921 /** Executes a single instruction. cpu_exec() will normally return EXCP_SINGLE_INSTR. */
922 #define CPU_INTERRUPT_SINGLE_INSTR              0x0200
923 /** Executing a CPU_INTERRUPT_SINGLE_INSTR request, quit the cpu_loop. (for exceptions and suchlike) */
924 #define CPU_INTERRUPT_SINGLE_INSTR_IN_FLIGHT    0x0400
925 /** VM execution was interrupted by VMR3Reset, VMR3Suspend or VMR3PowerOff. */
926 #define CPU_INTERRUPT_RC                        0x0800
927 /** Exit current TB to process an external interrupt request (also in op.c!!) */
928 #define CPU_INTERRUPT_EXTERNAL_EXIT             0x1000
929 /** Exit current TB to process an external interrupt request (also in op.c!!) */
930 #define CPU_INTERRUPT_EXTERNAL_HARD             0x2000
931 /** Exit current TB to process an external interrupt request (also in op.c!!) */
932 #define CPU_INTERRUPT_EXTERNAL_TIMER            0x4000
933 /** Exit current TB to process an external interrupt request (also in op.c!!) */
934 #define CPU_INTERRUPT_EXTERNAL_DMA              0x8000
935 #endif /* VBOX */
936 void cpu_interrupt(CPUState *s, int mask);
937 void cpu_reset_interrupt(CPUState *env, int mask);
938
939 int cpu_breakpoint_insert(CPUState *env, target_ulong pc);
940 int cpu_breakpoint_remove(CPUState *env, target_ulong pc);
941 void cpu_single_step(CPUState *env, int enabled);
942 void cpu_reset(CPUState *s);
943
944 /* Return the physical page corresponding to a virtual one. Use it
945    only for debugging because no protection checks are done. Return -1
946    if no page found. */
947 target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
948
949 #