Statistics
| Branch: | Revision:

root / exec-all.h @ 41c1b1c9

History | View | Annotate | Download (12.3 kB)

1 d4e8164f bellard
/*
2 d4e8164f bellard
 * internal execution defines for qemu
3 5fafdf24 ths
 *
4 d4e8164f bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 d4e8164f bellard
 *
6 d4e8164f bellard
 * This library is free software; you can redistribute it and/or
7 d4e8164f bellard
 * modify it under the terms of the GNU Lesser General Public
8 d4e8164f bellard
 * License as published by the Free Software Foundation; either
9 d4e8164f bellard
 * version 2 of the License, or (at your option) any later version.
10 d4e8164f bellard
 *
11 d4e8164f bellard
 * This library is distributed in the hope that it will be useful,
12 d4e8164f bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 d4e8164f bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 d4e8164f bellard
 * Lesser General Public License for more details.
15 d4e8164f bellard
 *
16 d4e8164f bellard
 * You should have received a copy of the GNU Lesser General Public
17 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 d4e8164f bellard
 */
19 d4e8164f bellard
20 875cdcf6 aliguori
#ifndef _EXEC_ALL_H_
21 875cdcf6 aliguori
#define _EXEC_ALL_H_
22 7d99a001 blueswir1
23 7d99a001 blueswir1
#include "qemu-common.h"
24 7d99a001 blueswir1
25 b346ff46 bellard
/* allow to see translation results - the slowdown should be negligible, so we leave it */
26 de9a95f0 aurel32
#define DEBUG_DISAS
27 b346ff46 bellard
28 41c1b1c9 Paul Brook
/* Page tracking code uses ram addresses in system mode, and virtual
29 41c1b1c9 Paul Brook
   addresses in userspace mode.  Define tb_page_addr_t to be an appropriate
30 41c1b1c9 Paul Brook
   type.  */
31 41c1b1c9 Paul Brook
#if defined(CONFIG_USER_ONLY)
32 41c1b1c9 Paul Brook
typedef target_ulong tb_page_addr_t;
33 41c1b1c9 Paul Brook
#else
34 41c1b1c9 Paul Brook
typedef ram_addr_t tb_page_addr_t;
35 41c1b1c9 Paul Brook
#endif
36 41c1b1c9 Paul Brook
37 b346ff46 bellard
/* is_jmp field values */
38 b346ff46 bellard
#define DISAS_NEXT    0 /* next instruction can be analyzed */
39 b346ff46 bellard
#define DISAS_JUMP    1 /* only pc was modified dynamically */
40 b346ff46 bellard
#define DISAS_UPDATE  2 /* cpu state was modified dynamically */
41 b346ff46 bellard
#define DISAS_TB_JUMP 3 /* only pc was modified statically */
42 b346ff46 bellard
43 2e70f6ef pbrook
typedef struct TranslationBlock TranslationBlock;
44 b346ff46 bellard
45 b346ff46 bellard
/* XXX: make safe guess about sizes */
46 b689c622 Aurelien Jarno
#define MAX_OP_PER_INSTR 96
47 0115be31 pbrook
/* A Call op needs up to 6 + 2N parameters (N = number of arguments).  */
48 0115be31 pbrook
#define MAX_OPC_PARAM 10
49 6db73509 Aurelien Jarno
#define OPC_BUF_SIZE 640
50 b346ff46 bellard
#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR)
51 b346ff46 bellard
52 a208e54a pbrook
/* Maximum size a TCG op can expand to.  This is complicated because a
53 0cbfcd2b Aurelien Jarno
   single op may require several host instructions and register reloads.
54 0cbfcd2b Aurelien Jarno
   For now take a wild guess at 192 bytes, which should allow at least
55 a208e54a pbrook
   a couple of fixup instructions per argument.  */
56 0cbfcd2b Aurelien Jarno
#define TCG_MAX_OP_SIZE 192
57 a208e54a pbrook
58 0115be31 pbrook
#define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * MAX_OPC_PARAM)
59 b346ff46 bellard
60 c27004ec bellard
extern target_ulong gen_opc_pc[OPC_BUF_SIZE];
61 c27004ec bellard
extern target_ulong gen_opc_npc[OPC_BUF_SIZE];
62 66e85a21 bellard
extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
63 b346ff46 bellard
extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
64 2e70f6ef pbrook
extern uint16_t gen_opc_icount[OPC_BUF_SIZE];
65 c3278b7b bellard
extern target_ulong gen_opc_jump_pc[2];
66 30d6cb84 bellard
extern uint32_t gen_opc_hflags[OPC_BUF_SIZE];
67 b346ff46 bellard
68 79383c9c blueswir1
#include "qemu-log.h"
69 b346ff46 bellard
70 2cfc5f17 ths
void gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
71 2cfc5f17 ths
void gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
72 d2856f1a aurel32
void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
73 d2856f1a aurel32
                 unsigned long searched_pc, int pc_pos, void *puc);
74 d2856f1a aurel32
75 d07bde88 blueswir1
unsigned long code_gen_max_block_size(void);
76 57fec1fe bellard
void cpu_gen_init(void);
77 4c3a88a2 bellard
int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
78 d07bde88 blueswir1
                 int *gen_code_size_ptr);
79 5fafdf24 ths
int cpu_restore_state(struct TranslationBlock *tb,
80 58fe2f10 bellard
                      CPUState *env, unsigned long searched_pc,
81 58fe2f10 bellard
                      void *puc);
82 5fafdf24 ths
int cpu_restore_state_copy(struct TranslationBlock *tb,
83 58fe2f10 bellard
                           CPUState *env, unsigned long searched_pc,
84 58fe2f10 bellard
                           void *puc);
85 2e12669a bellard
void cpu_resume_from_signal(CPUState *env1, void *puc);
86 2e70f6ef pbrook
void cpu_io_recompile(CPUState *env, void *retaddr);
87 2e70f6ef pbrook
TranslationBlock *tb_gen_code(CPUState *env, 
88 2e70f6ef pbrook
                              target_ulong pc, target_ulong cs_base, int flags,
89 2e70f6ef pbrook
                              int cflags);
90 6a00d601 bellard
void cpu_exec_init(CPUState *env);
91 a5e50b26 malc
void QEMU_NORETURN cpu_loop_exit(void);
92 53a5960a pbrook
int page_unprotect(target_ulong address, unsigned long pc, void *puc);
93 41c1b1c9 Paul Brook
void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
94 2e12669a bellard
                                   int is_cpu_write_access);
95 4390df51 bellard
void tb_invalidate_page_range(target_ulong start, target_ulong end);
96 2e12669a bellard
void tlb_flush_page(CPUState *env, target_ulong addr);
97 ee8b7021 bellard
void tlb_flush(CPUState *env, int flush_global);
98 c527ee8f Paul Brook
#if !defined(CONFIG_USER_ONLY)
99 5fafdf24 ths
int tlb_set_page_exec(CPUState *env, target_ulong vaddr,
100 c227f099 Anthony Liguori
                      target_phys_addr_t paddr, int prot,
101 6ebbf390 j_mayer
                      int mmu_idx, int is_softmmu);
102 4d7a0880 blueswir1
static inline int tlb_set_page(CPUState *env1, target_ulong vaddr,
103 c227f099 Anthony Liguori
                               target_phys_addr_t paddr, int prot,
104 6ebbf390 j_mayer
                               int mmu_idx, int is_softmmu)
105 84b7b8e7 bellard
{
106 84b7b8e7 bellard
    if (prot & PAGE_READ)
107 84b7b8e7 bellard
        prot |= PAGE_EXEC;
108 4d7a0880 blueswir1
    return tlb_set_page_exec(env1, vaddr, paddr, prot, mmu_idx, is_softmmu);
109 84b7b8e7 bellard
}
110 c527ee8f Paul Brook
#endif
111 d4e8164f bellard
112 d4e8164f bellard
#define CODE_GEN_ALIGN           16 /* must be >= of the size of a icache line */
113 d4e8164f bellard
114 4390df51 bellard
#define CODE_GEN_PHYS_HASH_BITS     15
115 4390df51 bellard
#define CODE_GEN_PHYS_HASH_SIZE     (1 << CODE_GEN_PHYS_HASH_BITS)
116 4390df51 bellard
117 26a5f13b bellard
#define MIN_CODE_GEN_BUFFER_SIZE     (1024 * 1024)
118 d4e8164f bellard
119 4390df51 bellard
/* estimated block size for TB allocation */
120 4390df51 bellard
/* XXX: use a per code average code fragment size and modulate it
121 4390df51 bellard
   according to the host CPU */
122 4390df51 bellard
#if defined(CONFIG_SOFTMMU)
123 4390df51 bellard
#define CODE_GEN_AVG_BLOCK_SIZE 128
124 4390df51 bellard
#else
125 4390df51 bellard
#define CODE_GEN_AVG_BLOCK_SIZE 64
126 4390df51 bellard
#endif
127 4390df51 bellard
128 a8cd70fc Filip Navara
#if defined(_ARCH_PPC) || defined(__x86_64__) || defined(__arm__) || defined(__i386__)
129 d4e8164f bellard
#define USE_DIRECT_JUMP
130 d4e8164f bellard
#endif
131 d4e8164f bellard
132 2e70f6ef pbrook
struct TranslationBlock {
133 2e12669a bellard
    target_ulong pc;   /* simulated PC corresponding to this block (EIP + CS base) */
134 2e12669a bellard
    target_ulong cs_base; /* CS base for this block */
135 c068688b j_mayer
    uint64_t flags; /* flags defining in which context the code was generated */
136 d4e8164f bellard
    uint16_t size;      /* size of target code for this block (1 <=
137 d4e8164f bellard
                           size <= TARGET_PAGE_SIZE) */
138 58fe2f10 bellard
    uint16_t cflags;    /* compile flags */
139 2e70f6ef pbrook
#define CF_COUNT_MASK  0x7fff
140 2e70f6ef pbrook
#define CF_LAST_IO     0x8000 /* Last insn may be an IO access.  */
141 58fe2f10 bellard
142 d4e8164f bellard
    uint8_t *tc_ptr;    /* pointer to the translated code */
143 4390df51 bellard
    /* next matching tb for physical address. */
144 5fafdf24 ths
    struct TranslationBlock *phys_hash_next;
145 4390df51 bellard
    /* first and second physical page containing code. The lower bit
146 4390df51 bellard
       of the pointer tells the index in page_next[] */
147 5fafdf24 ths
    struct TranslationBlock *page_next[2];
148 41c1b1c9 Paul Brook
    tb_page_addr_t page_addr[2];
149 4390df51 bellard
150 d4e8164f bellard
    /* the following data are used to directly call another TB from
151 d4e8164f bellard
       the code of this one. */
152 d4e8164f bellard
    uint16_t tb_next_offset[2]; /* offset of original jump target */
153 d4e8164f bellard
#ifdef USE_DIRECT_JUMP
154 4cbb86e1 bellard
    uint16_t tb_jmp_offset[4]; /* offset of jump instruction */
155 d4e8164f bellard
#else
156 57fec1fe bellard
    unsigned long tb_next[2]; /* address of jump generated code */
157 d4e8164f bellard
#endif
158 d4e8164f bellard
    /* list of TBs jumping to this one. This is a circular list using
159 d4e8164f bellard
       the two least significant bits of the pointers to tell what is
160 d4e8164f bellard
       the next pointer: 0 = jmp_next[0], 1 = jmp_next[1], 2 =
161 d4e8164f bellard
       jmp_first */
162 5fafdf24 ths
    struct TranslationBlock *jmp_next[2];
163 d4e8164f bellard
    struct TranslationBlock *jmp_first;
164 2e70f6ef pbrook
    uint32_t icount;
165 2e70f6ef pbrook
};
166 d4e8164f bellard
167 b362e5e0 pbrook
static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc)
168 b362e5e0 pbrook
{
169 b362e5e0 pbrook
    target_ulong tmp;
170 b362e5e0 pbrook
    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
171 b5e19d4c edgar_igl
    return (tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK;
172 b362e5e0 pbrook
}
173 b362e5e0 pbrook
174 8a40a180 bellard
static inline unsigned int tb_jmp_cache_hash_func(target_ulong pc)
175 d4e8164f bellard
{
176 b362e5e0 pbrook
    target_ulong tmp;
177 b362e5e0 pbrook
    tmp = pc ^ (pc >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS));
178 b5e19d4c edgar_igl
    return (((tmp >> (TARGET_PAGE_BITS - TB_JMP_PAGE_BITS)) & TB_JMP_PAGE_MASK)
179 b5e19d4c edgar_igl
            | (tmp & TB_JMP_ADDR_MASK));
180 d4e8164f bellard
}
181 d4e8164f bellard
182 41c1b1c9 Paul Brook
static inline unsigned int tb_phys_hash_func(tb_page_addr_t pc)
183 4390df51 bellard
{
184 4390df51 bellard
    return pc & (CODE_GEN_PHYS_HASH_SIZE - 1);
185 4390df51 bellard
}
186 4390df51 bellard
187 c27004ec bellard
TranslationBlock *tb_alloc(target_ulong pc);
188 2e70f6ef pbrook
void tb_free(TranslationBlock *tb);
189 0124311e bellard
void tb_flush(CPUState *env);
190 41c1b1c9 Paul Brook
void tb_link_page(TranslationBlock *tb,
191 41c1b1c9 Paul Brook
                  tb_page_addr_t phys_pc, tb_page_addr_t phys_page2);
192 41c1b1c9 Paul Brook
void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr);
193 d4e8164f bellard
194 4390df51 bellard
extern TranslationBlock *tb_phys_hash[CODE_GEN_PHYS_HASH_SIZE];
195 d4e8164f bellard
extern uint8_t *code_gen_ptr;
196 26a5f13b bellard
extern int code_gen_max_blocks;
197 d4e8164f bellard
198 4390df51 bellard
#if defined(USE_DIRECT_JUMP)
199 4390df51 bellard
200 e58ffeb3 malc
#if defined(_ARCH_PPC)
201 810260a8 malc
extern void ppc_tb_set_jmp_target(unsigned long jmp_addr, unsigned long addr);
202 810260a8 malc
#define tb_set_jmp_target1 ppc_tb_set_jmp_target
203 57fec1fe bellard
#elif defined(__i386__) || defined(__x86_64__)
204 4390df51 bellard
static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
205 4390df51 bellard
{
206 4390df51 bellard
    /* patch the branch destination */
207 4390df51 bellard
    *(uint32_t *)jmp_addr = addr - (jmp_addr + 4);
208 1235fc06 ths
    /* no need to flush icache explicitly */
209 4390df51 bellard
}
210 811d4cf4 balrog
#elif defined(__arm__)
211 811d4cf4 balrog
static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
212 811d4cf4 balrog
{
213 3233f0d4 balrog
#if QEMU_GNUC_PREREQ(4, 1)
214 3233f0d4 balrog
    void __clear_cache(char *beg, char *end);
215 3233f0d4 balrog
#else
216 811d4cf4 balrog
    register unsigned long _beg __asm ("a1");
217 811d4cf4 balrog
    register unsigned long _end __asm ("a2");
218 811d4cf4 balrog
    register unsigned long _flg __asm ("a3");
219 3233f0d4 balrog
#endif
220 811d4cf4 balrog
221 811d4cf4 balrog
    /* we could use a ldr pc, [pc, #-4] kind of branch and avoid the flush */
222 87b78ad1 Laurent Desnogues
    *(uint32_t *)jmp_addr =
223 87b78ad1 Laurent Desnogues
        (*(uint32_t *)jmp_addr & ~0xffffff)
224 87b78ad1 Laurent Desnogues
        | (((addr - (jmp_addr + 8)) >> 2) & 0xffffff);
225 811d4cf4 balrog
226 3233f0d4 balrog
#if QEMU_GNUC_PREREQ(4, 1)
227 3233f0d4 balrog
    __clear_cache((char *) jmp_addr, (char *) jmp_addr + 4);
228 3233f0d4 balrog
#else
229 811d4cf4 balrog
    /* flush icache */
230 811d4cf4 balrog
    _beg = jmp_addr;
231 811d4cf4 balrog
    _end = jmp_addr + 4;
232 811d4cf4 balrog
    _flg = 0;
233 811d4cf4 balrog
    __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
234 3233f0d4 balrog
#endif
235 811d4cf4 balrog
}
236 4390df51 bellard
#endif
237 d4e8164f bellard
238 5fafdf24 ths
static inline void tb_set_jmp_target(TranslationBlock *tb,
239 4cbb86e1 bellard
                                     int n, unsigned long addr)
240 4cbb86e1 bellard
{
241 4cbb86e1 bellard
    unsigned long offset;
242 4cbb86e1 bellard
243 4cbb86e1 bellard
    offset = tb->tb_jmp_offset[n];
244 4cbb86e1 bellard
    tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
245 4cbb86e1 bellard
    offset = tb->tb_jmp_offset[n + 2];
246 4cbb86e1 bellard
    if (offset != 0xffff)
247 4cbb86e1 bellard
        tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
248 4cbb86e1 bellard
}
249 4cbb86e1 bellard
250 d4e8164f bellard
#else
251 d4e8164f bellard
252 d4e8164f bellard
/* set the jump target */
253 5fafdf24 ths
static inline void tb_set_jmp_target(TranslationBlock *tb,
254 d4e8164f bellard
                                     int n, unsigned long addr)
255 d4e8164f bellard
{
256 95f7652d bellard
    tb->tb_next[n] = addr;
257 d4e8164f bellard
}
258 d4e8164f bellard
259 d4e8164f bellard
#endif
260 d4e8164f bellard
261 5fafdf24 ths
static inline void tb_add_jump(TranslationBlock *tb, int n,
262 d4e8164f bellard
                               TranslationBlock *tb_next)
263 d4e8164f bellard
{
264 cf25629d bellard
    /* NOTE: this test is only needed for thread safety */
265 cf25629d bellard
    if (!tb->jmp_next[n]) {
266 cf25629d bellard
        /* patch the native jump address */
267 cf25629d bellard
        tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr);
268 3b46e624 ths
269 cf25629d bellard
        /* add in TB jmp circular list */
270 cf25629d bellard
        tb->jmp_next[n] = tb_next->jmp_first;
271 cf25629d bellard
        tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n));
272 cf25629d bellard
    }
273 d4e8164f bellard
}
274 d4e8164f bellard
275 a513fe19 bellard
TranslationBlock *tb_find_pc(unsigned long pc_ptr);
276 a513fe19 bellard
277 33417e70 bellard
extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
278 33417e70 bellard
extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
279 a4193c8a bellard
extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
280 33417e70 bellard
281 d5975363 pbrook
#include "qemu-lock.h"
282 d4e8164f bellard
283 c227f099 Anthony Liguori
extern spinlock_t tb_lock;
284 d4e8164f bellard
285 36bdbe54 bellard
extern int tb_invalidated_flag;
286 6e59c1db bellard
287 e95c8d51 bellard
#if !defined(CONFIG_USER_ONLY)
288 6e59c1db bellard
289 6ebbf390 j_mayer
void tlb_fill(target_ulong addr, int is_write, int mmu_idx,
290 6e59c1db bellard
              void *retaddr);
291 6e59c1db bellard
292 79383c9c blueswir1
#include "softmmu_defs.h"
293 79383c9c blueswir1
294 6ebbf390 j_mayer
#define ACCESS_TYPE (NB_MMU_MODES + 1)
295 6e59c1db bellard
#define MEMSUFFIX _code
296 6e59c1db bellard
#define env cpu_single_env
297 6e59c1db bellard
298 6e59c1db bellard
#define DATA_SIZE 1
299 6e59c1db bellard
#include "softmmu_header.h"
300 6e59c1db bellard
301 6e59c1db bellard
#define DATA_SIZE 2
302 6e59c1db bellard
#include "softmmu_header.h"
303 6e59c1db bellard
304 6e59c1db bellard
#define DATA_SIZE 4
305 6e59c1db bellard
#include "softmmu_header.h"
306 6e59c1db bellard
307 c27004ec bellard
#define DATA_SIZE 8
308 c27004ec bellard
#include "softmmu_header.h"
309 c27004ec bellard
310 6e59c1db bellard
#undef ACCESS_TYPE
311 6e59c1db bellard
#undef MEMSUFFIX
312 6e59c1db bellard
#undef env
313 6e59c1db bellard
314 6e59c1db bellard
#endif
315 4390df51 bellard
316 4390df51 bellard
#if defined(CONFIG_USER_ONLY)
317 41c1b1c9 Paul Brook
static inline tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr)
318 4390df51 bellard
{
319 4390df51 bellard
    return addr;
320 4390df51 bellard
}
321 4390df51 bellard
#else
322 4390df51 bellard
/* NOTE: this function can trigger an exception */
323 1ccde1cb bellard
/* NOTE2: the returned address is not exactly the physical address: it
324 1ccde1cb bellard
   is the offset relative to phys_ram_base */
325 41c1b1c9 Paul Brook
static inline tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong addr)
326 4390df51 bellard
{
327 4d7a0880 blueswir1
    int mmu_idx, page_index, pd;
328 5579c7f3 pbrook
    void *p;
329 4390df51 bellard
330 4d7a0880 blueswir1
    page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
331 4d7a0880 blueswir1
    mmu_idx = cpu_mmu_index(env1);
332 551bd27f ths
    if (unlikely(env1->tlb_table[mmu_idx][page_index].addr_code !=
333 551bd27f ths
                 (addr & TARGET_PAGE_MASK))) {
334 c27004ec bellard
        ldub_code(addr);
335 c27004ec bellard
    }
336 4d7a0880 blueswir1
    pd = env1->tlb_table[mmu_idx][page_index].addr_code & ~TARGET_PAGE_MASK;
337 2a4188a3 bellard
    if (pd > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) {
338 647de6ca ths
#if defined(TARGET_SPARC) || defined(TARGET_MIPS)
339 e18231a3 blueswir1
        do_unassigned_access(addr, 0, 1, 0, 4);
340 6c36d3fa blueswir1
#else
341 4d7a0880 blueswir1
        cpu_abort(env1, "Trying to execute code outside RAM or ROM at 0x" TARGET_FMT_lx "\n", addr);
342 6c36d3fa blueswir1
#endif
343 4390df51 bellard
    }
344 5579c7f3 pbrook
    p = (void *)(unsigned long)addr
345 5579c7f3 pbrook
        + env1->tlb_table[mmu_idx][page_index].addend;
346 5579c7f3 pbrook
    return qemu_ram_addr_from_host(p);
347 4390df51 bellard
}
348 2e70f6ef pbrook
349 bf20dc07 ths
/* Deterministic execution requires that IO only be performed on the last
350 2e70f6ef pbrook
   instruction of a TB so that interrupts take effect immediately.  */
351 2e70f6ef pbrook
static inline int can_do_io(CPUState *env)
352 2e70f6ef pbrook
{
353 2e70f6ef pbrook
    if (!use_icount)
354 2e70f6ef pbrook
        return 1;
355 2e70f6ef pbrook
356 2e70f6ef pbrook
    /* If not executing code then assume we are ok.  */
357 2e70f6ef pbrook
    if (!env->current_tb)
358 2e70f6ef pbrook
        return 1;
359 2e70f6ef pbrook
360 2e70f6ef pbrook
    return env->can_do_io != 0;
361 2e70f6ef pbrook
}
362 4390df51 bellard
#endif
363 9df217a3 bellard
364 dde2367e aliguori
typedef void (CPUDebugExcpHandler)(CPUState *env);
365 dde2367e aliguori
366 dde2367e aliguori
CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler);
367 1b530a6d aurel32
368 1b530a6d aurel32
/* vl.c */
369 1b530a6d aurel32
extern int singlestep;
370 1b530a6d aurel32
371 875cdcf6 aliguori
#endif