]> git.proxmox.com Git - qemu.git/blame - cpu-all.h
target-i386: remove old code handling float64
[qemu.git] / cpu-all.h
CommitLineData
5a9fdfec
FB
1/*
2 * defines common to all virtual CPUs
5fafdf24 3 *
5a9fdfec
FB
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
8167ee88 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
5a9fdfec
FB
18 */
19#ifndef CPU_ALL_H
20#define CPU_ALL_H
21
7d99a001 22#include "qemu-common.h"
1ad2134f 23#include "cpu-common.h"
0ac4bd56 24
5fafdf24
TS
25/* some important defines:
26 *
0ac4bd56
FB
27 * WORDS_ALIGNED : if defined, the host cpu can only make word aligned
28 * memory accesses.
5fafdf24 29 *
e2542fe2 30 * HOST_WORDS_BIGENDIAN : if defined, the host cpu is big endian and
0ac4bd56 31 * otherwise little endian.
5fafdf24 32 *
0ac4bd56 33 * (TARGET_WORDS_ALIGNED : same for target cpu (not supported yet))
5fafdf24 34 *
0ac4bd56
FB
35 * TARGET_WORDS_BIGENDIAN : same for target cpu
36 */
37
939ef593 38#include "softfloat.h"
f193c797 39
e2542fe2 40#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
f193c797
FB
41#define BSWAP_NEEDED
42#endif
43
44#ifdef BSWAP_NEEDED
45
46static inline uint16_t tswap16(uint16_t s)
47{
48 return bswap16(s);
49}
50
51static inline uint32_t tswap32(uint32_t s)
52{
53 return bswap32(s);
54}
55
56static inline uint64_t tswap64(uint64_t s)
57{
58 return bswap64(s);
59}
60
61static inline void tswap16s(uint16_t *s)
62{
63 *s = bswap16(*s);
64}
65
66static inline void tswap32s(uint32_t *s)
67{
68 *s = bswap32(*s);
69}
70
71static inline void tswap64s(uint64_t *s)
72{
73 *s = bswap64(*s);
74}
75
76#else
77
78static inline uint16_t tswap16(uint16_t s)
79{
80 return s;
81}
82
83static inline uint32_t tswap32(uint32_t s)
84{
85 return s;
86}
87
88static inline uint64_t tswap64(uint64_t s)
89{
90 return s;
91}
92
93static inline void tswap16s(uint16_t *s)
94{
95}
96
97static inline void tswap32s(uint32_t *s)
98{
99}
100
101static inline void tswap64s(uint64_t *s)
102{
103}
104
105#endif
106
107#if TARGET_LONG_SIZE == 4
108#define tswapl(s) tswap32(s)
109#define tswapls(s) tswap32s((uint32_t *)(s))
0a962c02 110#define bswaptls(s) bswap32s(s)
f193c797
FB
111#else
112#define tswapl(s) tswap64(s)
113#define tswapls(s) tswap64s((uint64_t *)(s))
0a962c02 114#define bswaptls(s) bswap64s(s)
f193c797
FB
115#endif
116
0ca9d380
AJ
117typedef union {
118 float32 f;
119 uint32_t l;
120} CPU_FloatU;
121
832ed0fa
FB
122/* NOTE: arm FPA is horrible as double 32 bit words are stored in big
123 endian ! */
0ac4bd56 124typedef union {
53cd6637 125 float64 d;
e2542fe2 126#if defined(HOST_WORDS_BIGENDIAN) \
9d60cac0 127 || (defined(__arm__) && !defined(__VFP_FP__) && !defined(CONFIG_SOFTFLOAT))
0ac4bd56 128 struct {
0ac4bd56 129 uint32_t upper;
832ed0fa 130 uint32_t lower;
0ac4bd56
FB
131 } l;
132#else
133 struct {
0ac4bd56 134 uint32_t lower;
832ed0fa 135 uint32_t upper;
0ac4bd56
FB
136 } l;
137#endif
138 uint64_t ll;
139} CPU_DoubleU;
140
602308f0
AJ
141#if defined(FLOATX80)
142typedef union {
143 floatx80 d;
144 struct {
145 uint64_t lower;
146 uint16_t upper;
147 } l;
148} CPU_LDoubleU;
149#endif
150
c8f930c0 151#if defined(CONFIG_SOFTFLOAT)
1f587329
BS
152typedef union {
153 float128 q;
c8f930c0 154#if defined(HOST_WORDS_BIGENDIAN)
1f587329
BS
155 struct {
156 uint32_t upmost;
157 uint32_t upper;
158 uint32_t lower;
159 uint32_t lowest;
160 } l;
161 struct {
162 uint64_t upper;
163 uint64_t lower;
164 } ll;
165#else
166 struct {
167 uint32_t lowest;
168 uint32_t lower;
169 uint32_t upper;
170 uint32_t upmost;
171 } l;
172 struct {
173 uint64_t lower;
174 uint64_t upper;
175 } ll;
176#endif
177} CPU_QuadU;
178#endif
179
61382a50
FB
180/* CPU memory access without any memory or io remapping */
181
83d73968
FB
182/*
183 * the generic syntax for the memory accesses is:
184 *
185 * load: ld{type}{sign}{size}{endian}_{access_type}(ptr)
186 *
187 * store: st{type}{size}{endian}_{access_type}(ptr, val)
188 *
189 * type is:
190 * (empty): integer access
191 * f : float access
5fafdf24 192 *
83d73968
FB
193 * sign is:
194 * (empty): for floats or 32 bit size
195 * u : unsigned
196 * s : signed
197 *
198 * size is:
199 * b: 8 bits
200 * w: 16 bits
201 * l: 32 bits
202 * q: 64 bits
5fafdf24 203 *
83d73968
FB
204 * endian is:
205 * (empty): target cpu endianness or 8 bit access
206 * r : reversed target cpu endianness (not implemented yet)
207 * be : big endian (not implemented yet)
208 * le : little endian (not implemented yet)
209 *
210 * access_type is:
211 * raw : host memory access
212 * user : user mode access using soft MMU
213 * kernel : kernel mode access using soft MMU
214 */
8bba3ea1 215static inline int ldub_p(const void *ptr)
5a9fdfec
FB
216{
217 return *(uint8_t *)ptr;
218}
219
8bba3ea1 220static inline int ldsb_p(const void *ptr)
5a9fdfec
FB
221{
222 return *(int8_t *)ptr;
223}
224
c27004ec 225static inline void stb_p(void *ptr, int v)
5a9fdfec
FB
226{
227 *(uint8_t *)ptr = v;
228}
229
230/* NOTE: on arm, putting 2 in /proc/sys/debug/alignment so that the
231 kernel handles unaligned load/stores may give better results, but
232 it is a system wide setting : bad */
e2542fe2 233#if defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
5a9fdfec
FB
234
235/* conservative code for little endian unaligned accesses */
8bba3ea1 236static inline int lduw_le_p(const void *ptr)
5a9fdfec 237{
e58ffeb3 238#ifdef _ARCH_PPC
5a9fdfec
FB
239 int val;
240 __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
241 return val;
242#else
e01fe6d5 243 const uint8_t *p = ptr;
5a9fdfec
FB
244 return p[0] | (p[1] << 8);
245#endif
246}
247
8bba3ea1 248static inline int ldsw_le_p(const void *ptr)
5a9fdfec 249{
e58ffeb3 250#ifdef _ARCH_PPC
5a9fdfec
FB
251 int val;
252 __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
253 return (int16_t)val;
254#else
e01fe6d5 255 const uint8_t *p = ptr;
5a9fdfec
FB
256 return (int16_t)(p[0] | (p[1] << 8));
257#endif
258}
259
8bba3ea1 260static inline int ldl_le_p(const void *ptr)
5a9fdfec 261{
e58ffeb3 262#ifdef _ARCH_PPC
5a9fdfec
FB
263 int val;
264 __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
265 return val;
266#else
e01fe6d5 267 const uint8_t *p = ptr;
5a9fdfec
FB
268 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
269#endif
270}
271
8bba3ea1 272static inline uint64_t ldq_le_p(const void *ptr)
5a9fdfec 273{
e01fe6d5 274 const uint8_t *p = ptr;
5a9fdfec 275 uint32_t v1, v2;
f0aca822
FB
276 v1 = ldl_le_p(p);
277 v2 = ldl_le_p(p + 4);
5a9fdfec
FB
278 return v1 | ((uint64_t)v2 << 32);
279}
280
2df3b95d 281static inline void stw_le_p(void *ptr, int v)
5a9fdfec 282{
e58ffeb3 283#ifdef _ARCH_PPC
5a9fdfec
FB
284 __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
285#else
286 uint8_t *p = ptr;
287 p[0] = v;
288 p[1] = v >> 8;
289#endif
290}
291
2df3b95d 292static inline void stl_le_p(void *ptr, int v)
5a9fdfec 293{
e58ffeb3 294#ifdef _ARCH_PPC
5a9fdfec
FB
295 __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
296#else
297 uint8_t *p = ptr;
298 p[0] = v;
299 p[1] = v >> 8;
300 p[2] = v >> 16;
301 p[3] = v >> 24;
302#endif
303}
304
2df3b95d 305static inline void stq_le_p(void *ptr, uint64_t v)
5a9fdfec
FB
306{
307 uint8_t *p = ptr;
f0aca822
FB
308 stl_le_p(p, (uint32_t)v);
309 stl_le_p(p + 4, v >> 32);
5a9fdfec
FB
310}
311
312/* float access */
313
8bba3ea1 314static inline float32 ldfl_le_p(const void *ptr)
5a9fdfec
FB
315{
316 union {
53cd6637 317 float32 f;
5a9fdfec
FB
318 uint32_t i;
319 } u;
2df3b95d 320 u.i = ldl_le_p(ptr);
5a9fdfec
FB
321 return u.f;
322}
323
2df3b95d 324static inline void stfl_le_p(void *ptr, float32 v)
5a9fdfec
FB
325{
326 union {
53cd6637 327 float32 f;
5a9fdfec
FB
328 uint32_t i;
329 } u;
330 u.f = v;
2df3b95d 331 stl_le_p(ptr, u.i);
5a9fdfec
FB
332}
333
8bba3ea1 334static inline float64 ldfq_le_p(const void *ptr)
5a9fdfec 335{
0ac4bd56 336 CPU_DoubleU u;
2df3b95d
FB
337 u.l.lower = ldl_le_p(ptr);
338 u.l.upper = ldl_le_p(ptr + 4);
5a9fdfec
FB
339 return u.d;
340}
341
2df3b95d 342static inline void stfq_le_p(void *ptr, float64 v)
5a9fdfec 343{
0ac4bd56 344 CPU_DoubleU u;
5a9fdfec 345 u.d = v;
2df3b95d
FB
346 stl_le_p(ptr, u.l.lower);
347 stl_le_p(ptr + 4, u.l.upper);
5a9fdfec
FB
348}
349
2df3b95d
FB
350#else
351
8bba3ea1 352static inline int lduw_le_p(const void *ptr)
2df3b95d
FB
353{
354 return *(uint16_t *)ptr;
355}
356
8bba3ea1 357static inline int ldsw_le_p(const void *ptr)
2df3b95d
FB
358{
359 return *(int16_t *)ptr;
360}
93ac68bc 361
8bba3ea1 362static inline int ldl_le_p(const void *ptr)
2df3b95d
FB
363{
364 return *(uint32_t *)ptr;
365}
366
8bba3ea1 367static inline uint64_t ldq_le_p(const void *ptr)
2df3b95d
FB
368{
369 return *(uint64_t *)ptr;
370}
371
372static inline void stw_le_p(void *ptr, int v)
373{
374 *(uint16_t *)ptr = v;
375}
376
377static inline void stl_le_p(void *ptr, int v)
378{
379 *(uint32_t *)ptr = v;
380}
381
382static inline void stq_le_p(void *ptr, uint64_t v)
383{
384 *(uint64_t *)ptr = v;
385}
386
387/* float access */
388
8bba3ea1 389static inline float32 ldfl_le_p(const void *ptr)
2df3b95d
FB
390{
391 return *(float32 *)ptr;
392}
393
8bba3ea1 394static inline float64 ldfq_le_p(const void *ptr)
2df3b95d
FB
395{
396 return *(float64 *)ptr;
397}
398
399static inline void stfl_le_p(void *ptr, float32 v)
400{
401 *(float32 *)ptr = v;
402}
403
404static inline void stfq_le_p(void *ptr, float64 v)
405{
406 *(float64 *)ptr = v;
407}
408#endif
409
e2542fe2 410#if !defined(HOST_WORDS_BIGENDIAN) || defined(WORDS_ALIGNED)
2df3b95d 411
8bba3ea1 412static inline int lduw_be_p(const void *ptr)
93ac68bc 413{
83d73968
FB
414#if defined(__i386__)
415 int val;
416 asm volatile ("movzwl %1, %0\n"
417 "xchgb %b0, %h0\n"
418 : "=q" (val)
419 : "m" (*(uint16_t *)ptr));
420 return val;
421#else
e01fe6d5 422 const uint8_t *b = ptr;
83d73968
FB
423 return ((b[0] << 8) | b[1]);
424#endif
93ac68bc
FB
425}
426
8bba3ea1 427static inline int ldsw_be_p(const void *ptr)
93ac68bc 428{
83d73968
FB
429#if defined(__i386__)
430 int val;
431 asm volatile ("movzwl %1, %0\n"
432 "xchgb %b0, %h0\n"
433 : "=q" (val)
434 : "m" (*(uint16_t *)ptr));
435 return (int16_t)val;
436#else
e01fe6d5 437 const uint8_t *b = ptr;
83d73968
FB
438 return (int16_t)((b[0] << 8) | b[1]);
439#endif
93ac68bc
FB
440}
441
8bba3ea1 442static inline int ldl_be_p(const void *ptr)
93ac68bc 443{
4f2ac237 444#if defined(__i386__) || defined(__x86_64__)
83d73968
FB
445 int val;
446 asm volatile ("movl %1, %0\n"
447 "bswap %0\n"
448 : "=r" (val)
449 : "m" (*(uint32_t *)ptr));
450 return val;
451#else
e01fe6d5 452 const uint8_t *b = ptr;
83d73968
FB
453 return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
454#endif
93ac68bc
FB
455}
456
8bba3ea1 457static inline uint64_t ldq_be_p(const void *ptr)
93ac68bc
FB
458{
459 uint32_t a,b;
2df3b95d 460 a = ldl_be_p(ptr);
4d7a0880 461 b = ldl_be_p((uint8_t *)ptr + 4);
93ac68bc
FB
462 return (((uint64_t)a<<32)|b);
463}
464
2df3b95d 465static inline void stw_be_p(void *ptr, int v)
93ac68bc 466{
83d73968
FB
467#if defined(__i386__)
468 asm volatile ("xchgb %b0, %h0\n"
469 "movw %w0, %1\n"
470 : "=q" (v)
471 : "m" (*(uint16_t *)ptr), "0" (v));
472#else
93ac68bc
FB
473 uint8_t *d = (uint8_t *) ptr;
474 d[0] = v >> 8;
475 d[1] = v;
83d73968 476#endif
93ac68bc
FB
477}
478
2df3b95d 479static inline void stl_be_p(void *ptr, int v)
93ac68bc 480{
4f2ac237 481#if defined(__i386__) || defined(__x86_64__)
83d73968
FB
482 asm volatile ("bswap %0\n"
483 "movl %0, %1\n"
484 : "=r" (v)
485 : "m" (*(uint32_t *)ptr), "0" (v));
486#else
93ac68bc
FB
487 uint8_t *d = (uint8_t *) ptr;
488 d[0] = v >> 24;
489 d[1] = v >> 16;
490 d[2] = v >> 8;
491 d[3] = v;
83d73968 492#endif
93ac68bc
FB
493}
494
2df3b95d 495static inline void stq_be_p(void *ptr, uint64_t v)
93ac68bc 496{
2df3b95d 497 stl_be_p(ptr, v >> 32);
4d7a0880 498 stl_be_p((uint8_t *)ptr + 4, v);
0ac4bd56
FB
499}
500
501/* float access */
502
8bba3ea1 503static inline float32 ldfl_be_p(const void *ptr)
0ac4bd56
FB
504{
505 union {
53cd6637 506 float32 f;
0ac4bd56
FB
507 uint32_t i;
508 } u;
2df3b95d 509 u.i = ldl_be_p(ptr);
0ac4bd56
FB
510 return u.f;
511}
512
2df3b95d 513static inline void stfl_be_p(void *ptr, float32 v)
0ac4bd56
FB
514{
515 union {
53cd6637 516 float32 f;
0ac4bd56
FB
517 uint32_t i;
518 } u;
519 u.f = v;
2df3b95d 520 stl_be_p(ptr, u.i);
0ac4bd56
FB
521}
522
8bba3ea1 523static inline float64 ldfq_be_p(const void *ptr)
0ac4bd56
FB
524{
525 CPU_DoubleU u;
2df3b95d 526 u.l.upper = ldl_be_p(ptr);
4d7a0880 527 u.l.lower = ldl_be_p((uint8_t *)ptr + 4);
0ac4bd56
FB
528 return u.d;
529}
530
2df3b95d 531static inline void stfq_be_p(void *ptr, float64 v)
0ac4bd56
FB
532{
533 CPU_DoubleU u;
534 u.d = v;
2df3b95d 535 stl_be_p(ptr, u.l.upper);
4d7a0880 536 stl_be_p((uint8_t *)ptr + 4, u.l.lower);
93ac68bc
FB
537}
538
5a9fdfec
FB
539#else
540
8bba3ea1 541static inline int lduw_be_p(const void *ptr)
5a9fdfec
FB
542{
543 return *(uint16_t *)ptr;
544}
545
8bba3ea1 546static inline int ldsw_be_p(const void *ptr)
5a9fdfec
FB
547{
548 return *(int16_t *)ptr;
549}
550
8bba3ea1 551static inline int ldl_be_p(const void *ptr)
5a9fdfec
FB
552{
553 return *(uint32_t *)ptr;
554}
555
8bba3ea1 556static inline uint64_t ldq_be_p(const void *ptr)
5a9fdfec
FB
557{
558 return *(uint64_t *)ptr;
559}
560
2df3b95d 561static inline void stw_be_p(void *ptr, int v)
5a9fdfec
FB
562{
563 *(uint16_t *)ptr = v;
564}
565
2df3b95d 566static inline void stl_be_p(void *ptr, int v)
5a9fdfec
FB
567{
568 *(uint32_t *)ptr = v;
569}
570
2df3b95d 571static inline void stq_be_p(void *ptr, uint64_t v)
5a9fdfec
FB
572{
573 *(uint64_t *)ptr = v;
574}
575
576/* float access */
577
8bba3ea1 578static inline float32 ldfl_be_p(const void *ptr)
5a9fdfec 579{
53cd6637 580 return *(float32 *)ptr;
5a9fdfec
FB
581}
582
8bba3ea1 583static inline float64 ldfq_be_p(const void *ptr)
5a9fdfec 584{
53cd6637 585 return *(float64 *)ptr;
5a9fdfec
FB
586}
587
2df3b95d 588static inline void stfl_be_p(void *ptr, float32 v)
5a9fdfec 589{
53cd6637 590 *(float32 *)ptr = v;
5a9fdfec
FB
591}
592
2df3b95d 593static inline void stfq_be_p(void *ptr, float64 v)
5a9fdfec 594{
53cd6637 595 *(float64 *)ptr = v;
5a9fdfec 596}
2df3b95d
FB
597
598#endif
599
600/* target CPU memory access functions */
601#if defined(TARGET_WORDS_BIGENDIAN)
602#define lduw_p(p) lduw_be_p(p)
603#define ldsw_p(p) ldsw_be_p(p)
604#define ldl_p(p) ldl_be_p(p)
605#define ldq_p(p) ldq_be_p(p)
606#define ldfl_p(p) ldfl_be_p(p)
607#define ldfq_p(p) ldfq_be_p(p)
608#define stw_p(p, v) stw_be_p(p, v)
609#define stl_p(p, v) stl_be_p(p, v)
610#define stq_p(p, v) stq_be_p(p, v)
611#define stfl_p(p, v) stfl_be_p(p, v)
612#define stfq_p(p, v) stfq_be_p(p, v)
613#else
614#define lduw_p(p) lduw_le_p(p)
615#define ldsw_p(p) ldsw_le_p(p)
616#define ldl_p(p) ldl_le_p(p)
617#define ldq_p(p) ldq_le_p(p)
618#define ldfl_p(p) ldfl_le_p(p)
619#define ldfq_p(p) ldfq_le_p(p)
620#define stw_p(p, v) stw_le_p(p, v)
621#define stl_p(p, v) stl_le_p(p, v)
622#define stq_p(p, v) stq_le_p(p, v)
623#define stfl_p(p, v) stfl_le_p(p, v)
624#define stfq_p(p, v) stfq_le_p(p, v)
5a9fdfec
FB
625#endif
626
61382a50
FB
627/* MMU memory access macros */
628
53a5960a 629#if defined(CONFIG_USER_ONLY)
0e62fd79
AJ
630#include <assert.h>
631#include "qemu-types.h"
632
53a5960a
PB
633/* On some host systems the guest address space is reserved on the host.
634 * This allows the guest address space to be offset to a convenient location.
635 */
379f6698
PB
636#if defined(CONFIG_USE_GUEST_BASE)
637extern unsigned long guest_base;
638extern int have_guest_base;
68a1c816 639extern unsigned long reserved_va;
379f6698 640#define GUEST_BASE guest_base
18e9ea8a 641#define RESERVED_VA reserved_va
379f6698
PB
642#else
643#define GUEST_BASE 0ul
18e9ea8a 644#define RESERVED_VA 0ul
379f6698 645#endif
53a5960a
PB
646
647/* All direct uses of g2h and h2g need to go away for usermode softmmu. */
648#define g2h(x) ((void *)((unsigned long)(x) + GUEST_BASE))
b9f83121
RH
649
650#if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS
651#define h2g_valid(x) 1
652#else
653#define h2g_valid(x) ({ \
654 unsigned long __guest = (unsigned long)(x) - GUEST_BASE; \
655 __guest < (1ul << TARGET_VIRT_ADDR_SPACE_BITS); \
656})
657#endif
658
0e62fd79
AJ
659#define h2g(x) ({ \
660 unsigned long __ret = (unsigned long)(x) - GUEST_BASE; \
661 /* Check if given address fits target address space */ \
b9f83121 662 assert(h2g_valid(x)); \
0e62fd79
AJ
663 (abi_ulong)__ret; \
664})
53a5960a
PB
665
666#define saddr(x) g2h(x)
667#define laddr(x) g2h(x)
668
669#else /* !CONFIG_USER_ONLY */
c27004ec
FB
670/* NOTE: we use double casts if pointers and target_ulong have
671 different sizes */
53a5960a
PB
672#define saddr(x) (uint8_t *)(long)(x)
673#define laddr(x) (uint8_t *)(long)(x)
674#endif
675
676#define ldub_raw(p) ldub_p(laddr((p)))
677#define ldsb_raw(p) ldsb_p(laddr((p)))
678#define lduw_raw(p) lduw_p(laddr((p)))
679#define ldsw_raw(p) ldsw_p(laddr((p)))
680#define ldl_raw(p) ldl_p(laddr((p)))
681#define ldq_raw(p) ldq_p(laddr((p)))
682#define ldfl_raw(p) ldfl_p(laddr((p)))
683#define ldfq_raw(p) ldfq_p(laddr((p)))
684#define stb_raw(p, v) stb_p(saddr((p)), v)
685#define stw_raw(p, v) stw_p(saddr((p)), v)
686#define stl_raw(p, v) stl_p(saddr((p)), v)
687#define stq_raw(p, v) stq_p(saddr((p)), v)
688#define stfl_raw(p, v) stfl_p(saddr((p)), v)
689#define stfq_raw(p, v) stfq_p(saddr((p)), v)
c27004ec
FB
690
691
5fafdf24 692#if defined(CONFIG_USER_ONLY)
61382a50
FB
693
694/* if user mode, no other memory access functions */
695#define ldub(p) ldub_raw(p)
696#define ldsb(p) ldsb_raw(p)
697#define lduw(p) lduw_raw(p)
698#define ldsw(p) ldsw_raw(p)
699#define ldl(p) ldl_raw(p)
700#define ldq(p) ldq_raw(p)
701#define ldfl(p) ldfl_raw(p)
702#define ldfq(p) ldfq_raw(p)
703#define stb(p, v) stb_raw(p, v)
704#define stw(p, v) stw_raw(p, v)
705#define stl(p, v) stl_raw(p, v)
706#define stq(p, v) stq_raw(p, v)
707#define stfl(p, v) stfl_raw(p, v)
708#define stfq(p, v) stfq_raw(p, v)
709
710#define ldub_code(p) ldub_raw(p)
711#define ldsb_code(p) ldsb_raw(p)
712#define lduw_code(p) lduw_raw(p)
713#define ldsw_code(p) ldsw_raw(p)
714#define ldl_code(p) ldl_raw(p)
bc98a7ef 715#define ldq_code(p) ldq_raw(p)
61382a50
FB
716
717#define ldub_kernel(p) ldub_raw(p)
718#define ldsb_kernel(p) ldsb_raw(p)
719#define lduw_kernel(p) lduw_raw(p)
720#define ldsw_kernel(p) ldsw_raw(p)
721#define ldl_kernel(p) ldl_raw(p)
bc98a7ef 722#define ldq_kernel(p) ldq_raw(p)
0ac4bd56
FB
723#define ldfl_kernel(p) ldfl_raw(p)
724#define ldfq_kernel(p) ldfq_raw(p)
61382a50
FB
725#define stb_kernel(p, v) stb_raw(p, v)
726#define stw_kernel(p, v) stw_raw(p, v)
727#define stl_kernel(p, v) stl_raw(p, v)
728#define stq_kernel(p, v) stq_raw(p, v)
0ac4bd56
FB
729#define stfl_kernel(p, v) stfl_raw(p, v)
730#define stfq_kernel(p, vt) stfq_raw(p, v)
61382a50
FB
731
732#endif /* defined(CONFIG_USER_ONLY) */
733
5a9fdfec
FB
734/* page related stuff */
735
03875444 736#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
5a9fdfec
FB
737#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
738#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
739
53a5960a 740/* ??? These should be the larger of unsigned long and target_ulong. */
83fb7adf
FB
741extern unsigned long qemu_real_host_page_size;
742extern unsigned long qemu_host_page_bits;
743extern unsigned long qemu_host_page_size;
744extern unsigned long qemu_host_page_mask;
5a9fdfec 745
83fb7adf 746#define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
5a9fdfec
FB
747
748/* same as PROT_xxx */
749#define PAGE_READ 0x0001
750#define PAGE_WRITE 0x0002
751#define PAGE_EXEC 0x0004
752#define PAGE_BITS (PAGE_READ | PAGE_WRITE | PAGE_EXEC)
753#define PAGE_VALID 0x0008
754/* original state of the write flag (used when tracking self-modifying
755 code */
5fafdf24 756#define PAGE_WRITE_ORG 0x0010
2e9a5713
PB
757#if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
758/* FIXME: Code that sets/uses this is broken and needs to go away. */
50a9569b 759#define PAGE_RESERVED 0x0020
2e9a5713 760#endif
5a9fdfec 761
b480d9b7 762#if defined(CONFIG_USER_ONLY)
5a9fdfec 763void page_dump(FILE *f);
5cd2c5b6 764
b480d9b7
PB
765typedef int (*walk_memory_regions_fn)(void *, abi_ulong,
766 abi_ulong, unsigned long);
5cd2c5b6
RH
767int walk_memory_regions(void *, walk_memory_regions_fn);
768
53a5960a
PB
769int page_get_flags(target_ulong address);
770void page_set_flags(target_ulong start, target_ulong end, int flags);
3d97b40b 771int page_check_range(target_ulong start, target_ulong len, int flags);
b480d9b7 772#endif
5a9fdfec 773
c5be9f08 774CPUState *cpu_copy(CPUState *env);
950f1472 775CPUState *qemu_get_cpu(int cpu);
c5be9f08 776
f5c848ee
JK
777#define CPU_DUMP_CODE 0x00010000
778
9a78eead 779void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
7fe48483 780 int flags);
9a78eead
SW
781void cpu_dump_statistics(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
782 int flags);
7fe48483 783
a5e50b26 784void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...)
2c80e423 785 GCC_FMT_ATTR(2, 3);
f0aca822 786extern CPUState *first_cpu;
e2f22898 787extern CPUState *cpu_single_env;
db1a4972 788
9c76219e
RH
789/* Flags for use in ENV->INTERRUPT_PENDING.
790
791 The numbers assigned here are non-sequential in order to preserve
792 binary compatibility with the vmstate dump. Bit 0 (0x0001) was
793 previously used for CPU_INTERRUPT_EXIT, and is cleared when loading
794 the vmstate dump. */
795
796/* External hardware interrupt pending. This is typically used for
797 interrupts from devices. */
798#define CPU_INTERRUPT_HARD 0x0002
799
800/* Exit the current TB. This is typically used when some system-level device
801 makes some change to the memory mapping. E.g. the a20 line change. */
802#define CPU_INTERRUPT_EXITTB 0x0004
803
804/* Halt the CPU. */
805#define CPU_INTERRUPT_HALT 0x0020
806
807/* Debug event pending. */
808#define CPU_INTERRUPT_DEBUG 0x0080
809
810/* Several target-specific external hardware interrupts. Each target/cpu.h
811 should define proper names based on these defines. */
812#define CPU_INTERRUPT_TGT_EXT_0 0x0008
813#define CPU_INTERRUPT_TGT_EXT_1 0x0010
814#define CPU_INTERRUPT_TGT_EXT_2 0x0040
815#define CPU_INTERRUPT_TGT_EXT_3 0x0200
816#define CPU_INTERRUPT_TGT_EXT_4 0x1000
817
818/* Several target-specific internal interrupts. These differ from the
819 preceeding target-specific interrupts in that they are intended to
820 originate from within the cpu itself, typically in response to some
821 instruction being executed. These, therefore, are not masked while
822 single-stepping within the debugger. */
823#define CPU_INTERRUPT_TGT_INT_0 0x0100
824#define CPU_INTERRUPT_TGT_INT_1 0x0400
825#define CPU_INTERRUPT_TGT_INT_2 0x0800
826
827/* First unused bit: 0x2000. */
828
3125f763
RH
829/* The set of all bits that should be masked when single-stepping. */
830#define CPU_INTERRUPT_SSTEP_MASK \
831 (CPU_INTERRUPT_HARD \
832 | CPU_INTERRUPT_TGT_EXT_0 \
833 | CPU_INTERRUPT_TGT_EXT_1 \
834 | CPU_INTERRUPT_TGT_EXT_2 \
835 | CPU_INTERRUPT_TGT_EXT_3 \
836 | CPU_INTERRUPT_TGT_EXT_4)
98699967 837
ec6959d0
JK
838#ifndef CONFIG_USER_ONLY
839typedef void (*CPUInterruptHandler)(CPUState *, int);
840
841extern CPUInterruptHandler cpu_interrupt_handler;
842
843static inline void cpu_interrupt(CPUState *s, int mask)
844{
845 cpu_interrupt_handler(s, mask);
846}
847#else /* USER_ONLY */
848void cpu_interrupt(CPUState *env, int mask);
849#endif /* USER_ONLY */
850
b54ad049 851void cpu_reset_interrupt(CPUState *env, int mask);
68a79315 852
3098dba0
AJ
853void cpu_exit(CPUState *s);
854
6a4955a8
AL
855int qemu_cpu_has_work(CPUState *env);
856
a1d1bb31
AL
857/* Breakpoint/watchpoint flags */
858#define BP_MEM_READ 0x01
859#define BP_MEM_WRITE 0x02
860#define BP_MEM_ACCESS (BP_MEM_READ | BP_MEM_WRITE)
06d55cc1 861#define BP_STOP_BEFORE_ACCESS 0x04
6e140f28 862#define BP_WATCHPOINT_HIT 0x08
a1d1bb31 863#define BP_GDB 0x10
2dc9f411 864#define BP_CPU 0x20
a1d1bb31
AL
865
866int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags,
867 CPUBreakpoint **breakpoint);
868int cpu_breakpoint_remove(CPUState *env, target_ulong pc, int flags);
869void cpu_breakpoint_remove_by_ref(CPUState *env, CPUBreakpoint *breakpoint);
870void cpu_breakpoint_remove_all(CPUState *env, int mask);
871int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len,
872 int flags, CPUWatchpoint **watchpoint);
873int cpu_watchpoint_remove(CPUState *env, target_ulong addr,
874 target_ulong len, int flags);
875void cpu_watchpoint_remove_by_ref(CPUState *env, CPUWatchpoint *watchpoint);
876void cpu_watchpoint_remove_all(CPUState *env, int mask);
60897d36
EI
877
878#define SSTEP_ENABLE 0x1 /* Enable simulated HW single stepping */
879#define SSTEP_NOIRQ 0x2 /* Do not use IRQ while single stepping */
880#define SSTEP_NOTIMER 0x4 /* Do not Timers while single stepping */
881
c33a346e 882void cpu_single_step(CPUState *env, int enabled);
d95dc32d 883void cpu_reset(CPUState *s);
3ae9501c 884int cpu_is_stopped(CPUState *env);
e82bcec2 885void run_on_cpu(CPUState *env, void (*func)(void *data), void *data);
4c3a88a2 886
5fafdf24 887#define CPU_LOG_TB_OUT_ASM (1 << 0)
9fddaa0c 888#define CPU_LOG_TB_IN_ASM (1 << 1)
f193c797
FB
889#define CPU_LOG_TB_OP (1 << 2)
890#define CPU_LOG_TB_OP_OPT (1 << 3)
891#define CPU_LOG_INT (1 << 4)
892#define CPU_LOG_EXEC (1 << 5)
893#define CPU_LOG_PCALL (1 << 6)
fd872598 894#define CPU_LOG_IOPORT (1 << 7)
9fddaa0c 895#define CPU_LOG_TB_CPU (1 << 8)
eca1bdf4 896#define CPU_LOG_RESET (1 << 9)
f193c797
FB
897
898/* define log items */
899typedef struct CPULogItem {
900 int mask;
901 const char *name;
902 const char *help;
903} CPULogItem;
904
c7cd6a37 905extern const CPULogItem cpu_log_items[];
f193c797 906
34865134
FB
907void cpu_set_log(int log_flags);
908void cpu_set_log_filename(const char *filename);
f193c797 909int cpu_str_to_log_mask(const char *str);
34865134 910
b3755a91
PB
911#if !defined(CONFIG_USER_ONLY)
912
4fcc562b
PB
913/* Return the physical page corresponding to a virtual one. Use it
914 only for debugging because no protection checks are done. Return -1
915 if no page found. */
916target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr);
917
33417e70
FB
918/* memory API */
919
edf75d59 920extern int phys_ram_fd;
c227f099 921extern ram_addr_t ram_size;
f471a17e 922
cd19cfa2
HY
923/* RAM is pre-allocated and passed into qemu_ram_alloc_from_ptr */
924#define RAM_PREALLOC_MASK (1 << 0)
925
f471a17e
AW
926typedef struct RAMBlock {
927 uint8_t *host;
928 ram_addr_t offset;
929 ram_addr_t length;
cd19cfa2 930 uint32_t flags;
cc9e98cb 931 char idstr[256];
f471a17e 932 QLIST_ENTRY(RAMBlock) next;
04b16653
AW
933#if defined(__linux__) && !defined(TARGET_S390X)
934 int fd;
935#endif
f471a17e
AW
936} RAMBlock;
937
938typedef struct RAMList {
939 uint8_t *phys_dirty;
f471a17e
AW
940 QLIST_HEAD(ram, RAMBlock) blocks;
941} RAMList;
942extern RAMList ram_list;
edf75d59 943
c902760f
MT
944extern const char *mem_path;
945extern int mem_prealloc;
946
edf75d59 947/* physical memory access */
0f459d16
PB
948
949/* MMIO pages are identified by a combination of an IO device index and
950 3 flags. The ROMD code stores the page ram offset in iotlb entry,
951 so only a limited number of ids are avaiable. */
952
98699967 953#define IO_MEM_NB_ENTRIES (1 << (TARGET_PAGE_BITS - IO_MEM_SHIFT))
edf75d59 954
0f459d16
PB
955/* Flags stored in the low bits of the TLB virtual address. These are
956 defined so that fast path ram access is all zeros. */
957/* Zero if TLB entry is valid. */
958#define TLB_INVALID_MASK (1 << 3)
959/* Set if TLB entry references a clean RAM page. The iotlb entry will
960 contain the page physical address. */
961#define TLB_NOTDIRTY (1 << 4)
962/* Set if TLB entry is an IO callback. */
963#define TLB_MMIO (1 << 5)
964
74576198
AL
965#define VGA_DIRTY_FLAG 0x01
966#define CODE_DIRTY_FLAG 0x02
74576198 967#define MIGRATION_DIRTY_FLAG 0x08
0a962c02 968
1ccde1cb 969/* read dirty bit (return 0 or 1) */
c227f099 970static inline int cpu_physical_memory_is_dirty(ram_addr_t addr)
1ccde1cb 971{
f471a17e 972 return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] == 0xff;
0a962c02
FB
973}
974
ca39b46e
YT
975static inline int cpu_physical_memory_get_dirty_flags(ram_addr_t addr)
976{
f471a17e 977 return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS];
ca39b46e
YT
978}
979
c227f099 980static inline int cpu_physical_memory_get_dirty(ram_addr_t addr,
0a962c02
FB
981 int dirty_flags)
982{
f471a17e 983 return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags;
1ccde1cb
FB
984}
985
c227f099 986static inline void cpu_physical_memory_set_dirty(ram_addr_t addr)
1ccde1cb 987{
f471a17e 988 ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] = 0xff;
1ccde1cb
FB
989}
990
ca39b46e
YT
991static inline int cpu_physical_memory_set_dirty_flags(ram_addr_t addr,
992 int dirty_flags)
993{
f471a17e 994 return ram_list.phys_dirty[addr >> TARGET_PAGE_BITS] |= dirty_flags;
ca39b46e
YT
995}
996
997static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start,
998 int length,
999 int dirty_flags)
1000{
1001 int i, mask, len;
1002 uint8_t *p;
1003
1004 len = length >> TARGET_PAGE_BITS;
1005 mask = ~dirty_flags;
f471a17e 1006 p = ram_list.phys_dirty + (start >> TARGET_PAGE_BITS);
ca39b46e
YT
1007 for (i = 0; i < len; i++) {
1008 p[i] &= mask;
1009 }
1010}
1011
c227f099 1012void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
0a962c02 1013 int dirty_flags);
04c504cc 1014void cpu_tlb_update_dirty(CPUState *env);
1ccde1cb 1015
74576198
AL
1016int cpu_physical_memory_set_dirty_tracking(int enable);
1017
1018int cpu_physical_memory_get_dirty_tracking(void);
1019
c227f099
AL
1020int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
1021 target_phys_addr_t end_addr);
2bec46dc 1022
e5896b12
AP
1023int cpu_physical_log_start(target_phys_addr_t start_addr,
1024 ram_addr_t size);
1025
1026int cpu_physical_log_stop(target_phys_addr_t start_addr,
1027 ram_addr_t size);
1028
055403b2 1029void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
b3755a91
PB
1030#endif /* !CONFIG_USER_ONLY */
1031
1032int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
1033 uint8_t *buf, int len, int is_write);
1034
5a9fdfec 1035#endif /* CPU_ALL_H */