Statistics
| Branch: | Revision:

root / cpu-exec.c @ 6e0d8677

History | View | Annotate | Download (48.9 kB)

1 7d13299d bellard
/*
2 7d13299d bellard
 *  i386 emulator main execution loop
3 5fafdf24 ths
 *
4 66321a11 bellard
 *  Copyright (c) 2003-2005 Fabrice Bellard
5 7d13299d bellard
 *
6 3ef693a0 bellard
 * This library is free software; you can redistribute it and/or
7 3ef693a0 bellard
 * modify it under the terms of the GNU Lesser General Public
8 3ef693a0 bellard
 * License as published by the Free Software Foundation; either
9 3ef693a0 bellard
 * version 2 of the License, or (at your option) any later version.
10 7d13299d bellard
 *
11 3ef693a0 bellard
 * This library is distributed in the hope that it will be useful,
12 3ef693a0 bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 3ef693a0 bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 3ef693a0 bellard
 * Lesser General Public License for more details.
15 7d13299d bellard
 *
16 3ef693a0 bellard
 * You should have received a copy of the GNU Lesser General Public
17 3ef693a0 bellard
 * License along with this library; if not, write to the Free Software
18 3ef693a0 bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 7d13299d bellard
 */
20 e4533c7a bellard
#include "config.h"
21 7cb69cae bellard
#define CPU_NO_GLOBAL_REGS
22 93ac68bc bellard
#include "exec.h"
23 956034d7 bellard
#include "disas.h"
24 7cb69cae bellard
#include "tcg.h"
25 7d13299d bellard
26 fbf9eeb3 bellard
#if !defined(CONFIG_SOFTMMU)
27 fbf9eeb3 bellard
#undef EAX
28 fbf9eeb3 bellard
#undef ECX
29 fbf9eeb3 bellard
#undef EDX
30 fbf9eeb3 bellard
#undef EBX
31 fbf9eeb3 bellard
#undef ESP
32 fbf9eeb3 bellard
#undef EBP
33 fbf9eeb3 bellard
#undef ESI
34 fbf9eeb3 bellard
#undef EDI
35 fbf9eeb3 bellard
#undef EIP
36 fbf9eeb3 bellard
#include <signal.h>
37 fbf9eeb3 bellard
#include <sys/ucontext.h>
38 fbf9eeb3 bellard
#endif
39 fbf9eeb3 bellard
40 572a9d4a blueswir1
#if defined(__sparc__) && !defined(HOST_SOLARIS)
41 572a9d4a blueswir1
// Work around ugly bugs in glibc that mangle global register contents
42 572a9d4a blueswir1
#undef env
43 572a9d4a blueswir1
#define env cpu_single_env
44 572a9d4a blueswir1
#endif
45 572a9d4a blueswir1
46 36bdbe54 bellard
int tb_invalidated_flag;
47 b5fc09ae blueswir1
static unsigned long next_tb;
48 36bdbe54 bellard
49 dc99065b bellard
//#define DEBUG_EXEC
50 9de5e440 bellard
//#define DEBUG_SIGNAL
51 7d13299d bellard
52 e4533c7a bellard
void cpu_loop_exit(void)
53 e4533c7a bellard
{
54 bfed01fc ths
    /* NOTE: the register at this point must be saved by hand because
55 bfed01fc ths
       longjmp restore them */
56 bfed01fc ths
    regs_to_env();
57 e4533c7a bellard
    longjmp(env->jmp_env, 1);
58 e4533c7a bellard
}
59 bfed01fc ths
60 e6e5906b pbrook
#if !(defined(TARGET_SPARC) || defined(TARGET_SH4) || defined(TARGET_M68K))
61 3475187d bellard
#define reg_T2
62 3475187d bellard
#endif
63 e4533c7a bellard
64 fbf9eeb3 bellard
/* exit the current TB from a signal handler. The host registers are
65 fbf9eeb3 bellard
   restored in a state compatible with the CPU emulator
66 fbf9eeb3 bellard
 */
67 5fafdf24 ths
void cpu_resume_from_signal(CPUState *env1, void *puc)
68 fbf9eeb3 bellard
{
69 fbf9eeb3 bellard
#if !defined(CONFIG_SOFTMMU)
70 fbf9eeb3 bellard
    struct ucontext *uc = puc;
71 fbf9eeb3 bellard
#endif
72 fbf9eeb3 bellard
73 fbf9eeb3 bellard
    env = env1;
74 fbf9eeb3 bellard
75 fbf9eeb3 bellard
    /* XXX: restore cpu registers saved in host registers */
76 fbf9eeb3 bellard
77 fbf9eeb3 bellard
#if !defined(CONFIG_SOFTMMU)
78 fbf9eeb3 bellard
    if (puc) {
79 fbf9eeb3 bellard
        /* XXX: use siglongjmp ? */
80 fbf9eeb3 bellard
        sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
81 fbf9eeb3 bellard
    }
82 fbf9eeb3 bellard
#endif
83 fbf9eeb3 bellard
    longjmp(env->jmp_env, 1);
84 fbf9eeb3 bellard
}
85 fbf9eeb3 bellard
86 8a40a180 bellard
static TranslationBlock *tb_find_slow(target_ulong pc,
87 8a40a180 bellard
                                      target_ulong cs_base,
88 c068688b j_mayer
                                      uint64_t flags)
89 8a40a180 bellard
{
90 8a40a180 bellard
    TranslationBlock *tb, **ptb1;
91 8a40a180 bellard
    int code_gen_size;
92 8a40a180 bellard
    unsigned int h;
93 8a40a180 bellard
    target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
94 8a40a180 bellard
    uint8_t *tc_ptr;
95 3b46e624 ths
96 8a40a180 bellard
    spin_lock(&tb_lock);
97 8a40a180 bellard
98 8a40a180 bellard
    tb_invalidated_flag = 0;
99 3b46e624 ths
100 8a40a180 bellard
    regs_to_env(); /* XXX: do it just before cpu_gen_code() */
101 3b46e624 ths
102 8a40a180 bellard
    /* find translated block using physical mappings */
103 8a40a180 bellard
    phys_pc = get_phys_addr_code(env, pc);
104 8a40a180 bellard
    phys_page1 = phys_pc & TARGET_PAGE_MASK;
105 8a40a180 bellard
    phys_page2 = -1;
106 8a40a180 bellard
    h = tb_phys_hash_func(phys_pc);
107 8a40a180 bellard
    ptb1 = &tb_phys_hash[h];
108 8a40a180 bellard
    for(;;) {
109 8a40a180 bellard
        tb = *ptb1;
110 8a40a180 bellard
        if (!tb)
111 8a40a180 bellard
            goto not_found;
112 5fafdf24 ths
        if (tb->pc == pc &&
113 8a40a180 bellard
            tb->page_addr[0] == phys_page1 &&
114 5fafdf24 ths
            tb->cs_base == cs_base &&
115 8a40a180 bellard
            tb->flags == flags) {
116 8a40a180 bellard
            /* check next page if needed */
117 8a40a180 bellard
            if (tb->page_addr[1] != -1) {
118 5fafdf24 ths
                virt_page2 = (pc & TARGET_PAGE_MASK) +
119 8a40a180 bellard
                    TARGET_PAGE_SIZE;
120 8a40a180 bellard
                phys_page2 = get_phys_addr_code(env, virt_page2);
121 8a40a180 bellard
                if (tb->page_addr[1] == phys_page2)
122 8a40a180 bellard
                    goto found;
123 8a40a180 bellard
            } else {
124 8a40a180 bellard
                goto found;
125 8a40a180 bellard
            }
126 8a40a180 bellard
        }
127 8a40a180 bellard
        ptb1 = &tb->phys_hash_next;
128 8a40a180 bellard
    }
129 8a40a180 bellard
 not_found:
130 8a40a180 bellard
    /* if no translated code available, then translate it now */
131 8a40a180 bellard
    tb = tb_alloc(pc);
132 8a40a180 bellard
    if (!tb) {
133 8a40a180 bellard
        /* flush must be done */
134 8a40a180 bellard
        tb_flush(env);
135 8a40a180 bellard
        /* cannot fail at this point */
136 8a40a180 bellard
        tb = tb_alloc(pc);
137 8a40a180 bellard
        /* don't forget to invalidate previous TB info */
138 15388002 bellard
        tb_invalidated_flag = 1;
139 8a40a180 bellard
    }
140 8a40a180 bellard
    tc_ptr = code_gen_ptr;
141 8a40a180 bellard
    tb->tc_ptr = tc_ptr;
142 8a40a180 bellard
    tb->cs_base = cs_base;
143 8a40a180 bellard
    tb->flags = flags;
144 d07bde88 blueswir1
    cpu_gen_code(env, tb, &code_gen_size);
145 8a40a180 bellard
    code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
146 3b46e624 ths
147 8a40a180 bellard
    /* check next page if needed */
148 8a40a180 bellard
    virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
149 8a40a180 bellard
    phys_page2 = -1;
150 8a40a180 bellard
    if ((pc & TARGET_PAGE_MASK) != virt_page2) {
151 8a40a180 bellard
        phys_page2 = get_phys_addr_code(env, virt_page2);
152 8a40a180 bellard
    }
153 8a40a180 bellard
    tb_link_phys(tb, phys_pc, phys_page2);
154 3b46e624 ths
155 8a40a180 bellard
 found:
156 8a40a180 bellard
    /* we add the TB in the virtual pc hash table */
157 8a40a180 bellard
    env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
158 8a40a180 bellard
    spin_unlock(&tb_lock);
159 8a40a180 bellard
    return tb;
160 8a40a180 bellard
}
161 8a40a180 bellard
162 8a40a180 bellard
static inline TranslationBlock *tb_find_fast(void)
163 8a40a180 bellard
{
164 8a40a180 bellard
    TranslationBlock *tb;
165 8a40a180 bellard
    target_ulong cs_base, pc;
166 c068688b j_mayer
    uint64_t flags;
167 8a40a180 bellard
168 8a40a180 bellard
    /* we record a subset of the CPU state. It will
169 8a40a180 bellard
       always be the same before a given translated block
170 8a40a180 bellard
       is executed. */
171 8a40a180 bellard
#if defined(TARGET_I386)
172 8a40a180 bellard
    flags = env->hflags;
173 8a40a180 bellard
    flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
174 0573fbfc ths
    flags |= env->intercept;
175 8a40a180 bellard
    cs_base = env->segs[R_CS].base;
176 8a40a180 bellard
    pc = cs_base + env->eip;
177 8a40a180 bellard
#elif defined(TARGET_ARM)
178 8a40a180 bellard
    flags = env->thumb | (env->vfp.vec_len << 1)
179 b5ff1b31 bellard
            | (env->vfp.vec_stride << 4);
180 b5ff1b31 bellard
    if ((env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR)
181 b5ff1b31 bellard
        flags |= (1 << 6);
182 40f137e1 pbrook
    if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30))
183 40f137e1 pbrook
        flags |= (1 << 7);
184 9ee6e8bb pbrook
    flags |= (env->condexec_bits << 8);
185 8a40a180 bellard
    cs_base = 0;
186 8a40a180 bellard
    pc = env->regs[15];
187 8a40a180 bellard
#elif defined(TARGET_SPARC)
188 8a40a180 bellard
#ifdef TARGET_SPARC64
189 a80dde08 bellard
    // Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
190 a80dde08 bellard
    flags = (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
191 a80dde08 bellard
        | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
192 8a40a180 bellard
#else
193 6d5f237a blueswir1
    // FPU enable . Supervisor
194 6d5f237a blueswir1
    flags = (env->psref << 4) | env->psrs;
195 8a40a180 bellard
#endif
196 8a40a180 bellard
    cs_base = env->npc;
197 8a40a180 bellard
    pc = env->pc;
198 8a40a180 bellard
#elif defined(TARGET_PPC)
199 1527c87e j_mayer
    flags = env->hflags;
200 8a40a180 bellard
    cs_base = 0;
201 8a40a180 bellard
    pc = env->nip;
202 8a40a180 bellard
#elif defined(TARGET_MIPS)
203 56b19403 pbrook
    flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
204 cc9442b9 bellard
    cs_base = 0;
205 ead9360e ths
    pc = env->PC[env->current_tc];
206 e6e5906b pbrook
#elif defined(TARGET_M68K)
207 acf930aa pbrook
    flags = (env->fpcr & M68K_FPCR_PREC)  /* Bit  6 */
208 acf930aa pbrook
            | (env->sr & SR_S)            /* Bit  13 */
209 acf930aa pbrook
            | ((env->macsr >> 4) & 0xf);  /* Bits 0-3 */
210 e6e5906b pbrook
    cs_base = 0;
211 e6e5906b pbrook
    pc = env->pc;
212 fdf9b3e8 bellard
#elif defined(TARGET_SH4)
213 823029f9 ths
    flags = env->flags;
214 823029f9 ths
    cs_base = 0;
215 fdf9b3e8 bellard
    pc = env->pc;
216 eddf68a6 j_mayer
#elif defined(TARGET_ALPHA)
217 eddf68a6 j_mayer
    flags = env->ps;
218 eddf68a6 j_mayer
    cs_base = 0;
219 eddf68a6 j_mayer
    pc = env->pc;
220 f1ccf904 ths
#elif defined(TARGET_CRIS)
221 17a594d7 edgar_igl
    flags = env->pregs[PR_CCS] & U_FLAG;
222 cf1d97f0 edgar_igl
    flags |= env->dslot;
223 f1ccf904 ths
    cs_base = 0;
224 f1ccf904 ths
    pc = env->pc;
225 8a40a180 bellard
#else
226 8a40a180 bellard
#error unsupported CPU
227 8a40a180 bellard
#endif
228 bce61846 bellard
    tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
229 8a40a180 bellard
    if (__builtin_expect(!tb || tb->pc != pc || tb->cs_base != cs_base ||
230 8a40a180 bellard
                         tb->flags != flags, 0)) {
231 8a40a180 bellard
        tb = tb_find_slow(pc, cs_base, flags);
232 15388002 bellard
        /* Note: we do it here to avoid a gcc bug on Mac OS X when
233 15388002 bellard
           doing it in tb_find_slow */
234 15388002 bellard
        if (tb_invalidated_flag) {
235 15388002 bellard
            /* as some TB could have been invalidated because
236 15388002 bellard
               of memory exceptions while generating the code, we
237 15388002 bellard
               must recompute the hash index here */
238 b5fc09ae blueswir1
            next_tb = 0;
239 15388002 bellard
        }
240 8a40a180 bellard
    }
241 8a40a180 bellard
    return tb;
242 8a40a180 bellard
}
243 8a40a180 bellard
244 7d13299d bellard
/* main execution loop */
245 7d13299d bellard
246 e4533c7a bellard
int cpu_exec(CPUState *env1)
247 7d13299d bellard
{
248 1057eaa7 pbrook
#define DECLARE_HOST_REGS 1
249 1057eaa7 pbrook
#include "hostregs_helper.h"
250 1057eaa7 pbrook
#if defined(TARGET_SPARC)
251 3475187d bellard
#if defined(reg_REGWPTR)
252 3475187d bellard
    uint32_t *saved_regwptr;
253 3475187d bellard
#endif
254 3475187d bellard
#endif
255 8a40a180 bellard
    int ret, interrupt_request;
256 8a40a180 bellard
    TranslationBlock *tb;
257 c27004ec bellard
    uint8_t *tc_ptr;
258 8c6939c0 bellard
259 bfed01fc ths
    if (cpu_halted(env1) == EXCP_HALTED)
260 bfed01fc ths
        return EXCP_HALTED;
261 5a1e3cfc bellard
262 5fafdf24 ths
    cpu_single_env = env1;
263 6a00d601 bellard
264 7d13299d bellard
    /* first we save global registers */
265 1057eaa7 pbrook
#define SAVE_HOST_REGS 1
266 1057eaa7 pbrook
#include "hostregs_helper.h"
267 c27004ec bellard
    env = env1;
268 e4533c7a bellard
269 0d1a29f9 bellard
    env_to_regs();
270 ecb644f4 ths
#if defined(TARGET_I386)
271 9de5e440 bellard
    /* put eflags in CPU temporary format */
272 fc2b4c48 bellard
    CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
273 fc2b4c48 bellard
    DF = 1 - (2 * ((env->eflags >> 10) & 1));
274 9de5e440 bellard
    CC_OP = CC_OP_EFLAGS;
275 fc2b4c48 bellard
    env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
276 93ac68bc bellard
#elif defined(TARGET_SPARC)
277 3475187d bellard
#if defined(reg_REGWPTR)
278 3475187d bellard
    saved_regwptr = REGWPTR;
279 3475187d bellard
#endif
280 e6e5906b pbrook
#elif defined(TARGET_M68K)
281 e6e5906b pbrook
    env->cc_op = CC_OP_FLAGS;
282 e6e5906b pbrook
    env->cc_dest = env->sr & 0xf;
283 e6e5906b pbrook
    env->cc_x = (env->sr >> 4) & 1;
284 ecb644f4 ths
#elif defined(TARGET_ALPHA)
285 ecb644f4 ths
#elif defined(TARGET_ARM)
286 ecb644f4 ths
#elif defined(TARGET_PPC)
287 6af0bf9c bellard
#elif defined(TARGET_MIPS)
288 fdf9b3e8 bellard
#elif defined(TARGET_SH4)
289 f1ccf904 ths
#elif defined(TARGET_CRIS)
290 fdf9b3e8 bellard
    /* XXXXX */
291 e4533c7a bellard
#else
292 e4533c7a bellard
#error unsupported target CPU
293 e4533c7a bellard
#endif
294 3fb2ded1 bellard
    env->exception_index = -1;
295 9d27abd9 bellard
296 7d13299d bellard
    /* prepare setjmp context for exception handling */
297 3fb2ded1 bellard
    for(;;) {
298 3fb2ded1 bellard
        if (setjmp(env->jmp_env) == 0) {
299 ee8b7021 bellard
            env->current_tb = NULL;
300 3fb2ded1 bellard
            /* if an exception is pending, we execute it here */
301 3fb2ded1 bellard
            if (env->exception_index >= 0) {
302 3fb2ded1 bellard
                if (env->exception_index >= EXCP_INTERRUPT) {
303 3fb2ded1 bellard
                    /* exit request from the cpu execution loop */
304 3fb2ded1 bellard
                    ret = env->exception_index;
305 3fb2ded1 bellard
                    break;
306 3fb2ded1 bellard
                } else if (env->user_mode_only) {
307 3fb2ded1 bellard
                    /* if user mode only, we simulate a fake exception
308 9f083493 ths
                       which will be handled outside the cpu execution
309 3fb2ded1 bellard
                       loop */
310 83479e77 bellard
#if defined(TARGET_I386)
311 5fafdf24 ths
                    do_interrupt_user(env->exception_index,
312 5fafdf24 ths
                                      env->exception_is_int,
313 5fafdf24 ths
                                      env->error_code,
314 3fb2ded1 bellard
                                      env->exception_next_eip);
315 eba01623 bellard
                    /* successfully delivered */
316 eba01623 bellard
                    env->old_exception = -1;
317 83479e77 bellard
#endif
318 3fb2ded1 bellard
                    ret = env->exception_index;
319 3fb2ded1 bellard
                    break;
320 3fb2ded1 bellard
                } else {
321 83479e77 bellard
#if defined(TARGET_I386)
322 3fb2ded1 bellard
                    /* simulate a real cpu exception. On i386, it can
323 3fb2ded1 bellard
                       trigger new exceptions, but we do not handle
324 3fb2ded1 bellard
                       double or triple faults yet. */
325 5fafdf24 ths
                    do_interrupt(env->exception_index,
326 5fafdf24 ths
                                 env->exception_is_int,
327 5fafdf24 ths
                                 env->error_code,
328 d05e66d2 bellard
                                 env->exception_next_eip, 0);
329 678dde13 ths
                    /* successfully delivered */
330 678dde13 ths
                    env->old_exception = -1;
331 ce09776b bellard
#elif defined(TARGET_PPC)
332 ce09776b bellard
                    do_interrupt(env);
333 6af0bf9c bellard
#elif defined(TARGET_MIPS)
334 6af0bf9c bellard
                    do_interrupt(env);
335 e95c8d51 bellard
#elif defined(TARGET_SPARC)
336 1a0c3292 bellard
                    do_interrupt(env->exception_index);
337 b5ff1b31 bellard
#elif defined(TARGET_ARM)
338 b5ff1b31 bellard
                    do_interrupt(env);
339 fdf9b3e8 bellard
#elif defined(TARGET_SH4)
340 fdf9b3e8 bellard
                    do_interrupt(env);
341 eddf68a6 j_mayer
#elif defined(TARGET_ALPHA)
342 eddf68a6 j_mayer
                    do_interrupt(env);
343 f1ccf904 ths
#elif defined(TARGET_CRIS)
344 f1ccf904 ths
                    do_interrupt(env);
345 0633879f pbrook
#elif defined(TARGET_M68K)
346 0633879f pbrook
                    do_interrupt(0);
347 83479e77 bellard
#endif
348 3fb2ded1 bellard
                }
349 3fb2ded1 bellard
                env->exception_index = -1;
350 5fafdf24 ths
            }
351 9df217a3 bellard
#ifdef USE_KQEMU
352 9df217a3 bellard
            if (kqemu_is_ok(env) && env->interrupt_request == 0) {
353 9df217a3 bellard
                int ret;
354 9df217a3 bellard
                env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
355 9df217a3 bellard
                ret = kqemu_cpu_exec(env);
356 9df217a3 bellard
                /* put eflags in CPU temporary format */
357 9df217a3 bellard
                CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
358 9df217a3 bellard
                DF = 1 - (2 * ((env->eflags >> 10) & 1));
359 9df217a3 bellard
                CC_OP = CC_OP_EFLAGS;
360 9df217a3 bellard
                env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
361 9df217a3 bellard
                if (ret == 1) {
362 9df217a3 bellard
                    /* exception */
363 9df217a3 bellard
                    longjmp(env->jmp_env, 1);
364 9df217a3 bellard
                } else if (ret == 2) {
365 9df217a3 bellard
                    /* softmmu execution needed */
366 9df217a3 bellard
                } else {
367 9df217a3 bellard
                    if (env->interrupt_request != 0) {
368 9df217a3 bellard
                        /* hardware interrupt will be executed just after */
369 9df217a3 bellard
                    } else {
370 9df217a3 bellard
                        /* otherwise, we restart */
371 9df217a3 bellard
                        longjmp(env->jmp_env, 1);
372 9df217a3 bellard
                    }
373 9df217a3 bellard
                }
374 3fb2ded1 bellard
            }
375 9df217a3 bellard
#endif
376 9df217a3 bellard
377 b5fc09ae blueswir1
            next_tb = 0; /* force lookup of first TB */
378 3fb2ded1 bellard
            for(;;) {
379 68a79315 bellard
                interrupt_request = env->interrupt_request;
380 0573fbfc ths
                if (__builtin_expect(interrupt_request, 0)
381 0573fbfc ths
#if defined(TARGET_I386)
382 0573fbfc ths
                        && env->hflags & HF_GIF_MASK
383 0573fbfc ths
#endif
384 21b20814 edgar_igl
            && likely(!(env->singlestep_enabled & SSTEP_NOIRQ))) {
385 6658ffb8 pbrook
                    if (interrupt_request & CPU_INTERRUPT_DEBUG) {
386 6658ffb8 pbrook
                        env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
387 6658ffb8 pbrook
                        env->exception_index = EXCP_DEBUG;
388 6658ffb8 pbrook
                        cpu_loop_exit();
389 6658ffb8 pbrook
                    }
390 a90b7318 balrog
#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
391 f1ccf904 ths
    defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS)
392 a90b7318 balrog
                    if (interrupt_request & CPU_INTERRUPT_HALT) {
393 a90b7318 balrog
                        env->interrupt_request &= ~CPU_INTERRUPT_HALT;
394 a90b7318 balrog
                        env->halted = 1;
395 a90b7318 balrog
                        env->exception_index = EXCP_HLT;
396 a90b7318 balrog
                        cpu_loop_exit();
397 a90b7318 balrog
                    }
398 a90b7318 balrog
#endif
399 68a79315 bellard
#if defined(TARGET_I386)
400 3b21e03e bellard
                    if ((interrupt_request & CPU_INTERRUPT_SMI) &&
401 3b21e03e bellard
                        !(env->hflags & HF_SMM_MASK)) {
402 0573fbfc ths
                        svm_check_intercept(SVM_EXIT_SMI);
403 3b21e03e bellard
                        env->interrupt_request &= ~CPU_INTERRUPT_SMI;
404 3b21e03e bellard
                        do_smm_enter();
405 b5fc09ae blueswir1
                        next_tb = 0;
406 474ea849 aurel32
                    } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
407 474ea849 aurel32
                        !(env->hflags & HF_NMI_MASK)) {
408 474ea849 aurel32
                        env->interrupt_request &= ~CPU_INTERRUPT_NMI;
409 474ea849 aurel32
                        env->hflags |= HF_NMI_MASK;
410 474ea849 aurel32
                        do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
411 b5fc09ae blueswir1
                        next_tb = 0;
412 3b21e03e bellard
                    } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
413 0573fbfc ths
                        (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) &&
414 3f337316 bellard
                        !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
415 68a79315 bellard
                        int intno;
416 0573fbfc ths
                        svm_check_intercept(SVM_EXIT_INTR);
417 52621688 ths
                        env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
418 a541f297 bellard
                        intno = cpu_get_pic_interrupt(env);
419 f193c797 bellard
                        if (loglevel & CPU_LOG_TB_IN_ASM) {
420 68a79315 bellard
                            fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
421 68a79315 bellard
                        }
422 d05e66d2 bellard
                        do_interrupt(intno, 0, 0, 0, 1);
423 907a5b26 bellard
                        /* ensure that no TB jump will be modified as
424 907a5b26 bellard
                           the program flow was changed */
425 b5fc09ae blueswir1
                        next_tb = 0;
426 0573fbfc ths
#if !defined(CONFIG_USER_ONLY)
427 0573fbfc ths
                    } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
428 0573fbfc ths
                        (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
429 0573fbfc ths
                         int intno;
430 0573fbfc ths
                         /* FIXME: this should respect TPR */
431 0573fbfc ths
                         env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
432 52621688 ths
                         svm_check_intercept(SVM_EXIT_VINTR);
433 0573fbfc ths
                         intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
434 0573fbfc ths
                         if (loglevel & CPU_LOG_TB_IN_ASM)
435 0573fbfc ths
                             fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno);
436 0573fbfc ths
                         do_interrupt(intno, 0, 0, -1, 1);
437 52621688 ths
                         stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
438 52621688 ths
                                  ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK);
439 b5fc09ae blueswir1
                        next_tb = 0;
440 0573fbfc ths
#endif
441 68a79315 bellard
                    }
442 ce09776b bellard
#elif defined(TARGET_PPC)
443 9fddaa0c bellard
#if 0
444 9fddaa0c bellard
                    if ((interrupt_request & CPU_INTERRUPT_RESET)) {
445 9fddaa0c bellard
                        cpu_ppc_reset(env);
446 9fddaa0c bellard
                    }
447 9fddaa0c bellard
#endif
448 47103572 j_mayer
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
449 e9df014c j_mayer
                        ppc_hw_interrupt(env);
450 e9df014c j_mayer
                        if (env->pending_interrupts == 0)
451 e9df014c j_mayer
                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
452 b5fc09ae blueswir1
                        next_tb = 0;
453 ce09776b bellard
                    }
454 6af0bf9c bellard
#elif defined(TARGET_MIPS)
455 6af0bf9c bellard
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
456 24c7b0e3 ths
                        (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
457 6af0bf9c bellard
                        (env->CP0_Status & (1 << CP0St_IE)) &&
458 24c7b0e3 ths
                        !(env->CP0_Status & (1 << CP0St_EXL)) &&
459 24c7b0e3 ths
                        !(env->CP0_Status & (1 << CP0St_ERL)) &&
460 6af0bf9c bellard
                        !(env->hflags & MIPS_HFLAG_DM)) {
461 6af0bf9c bellard
                        /* Raise it */
462 6af0bf9c bellard
                        env->exception_index = EXCP_EXT_INTERRUPT;
463 6af0bf9c bellard
                        env->error_code = 0;
464 6af0bf9c bellard
                        do_interrupt(env);
465 b5fc09ae blueswir1
                        next_tb = 0;
466 6af0bf9c bellard
                    }
467 e95c8d51 bellard
#elif defined(TARGET_SPARC)
468 66321a11 bellard
                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
469 66321a11 bellard
                        (env->psret != 0)) {
470 66321a11 bellard
                        int pil = env->interrupt_index & 15;
471 66321a11 bellard
                        int type = env->interrupt_index & 0xf0;
472 66321a11 bellard
473 66321a11 bellard
                        if (((type == TT_EXTINT) &&
474 66321a11 bellard
                             (pil == 15 || pil > env->psrpil)) ||
475 66321a11 bellard
                            type != TT_EXTINT) {
476 66321a11 bellard
                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
477 66321a11 bellard
                            do_interrupt(env->interrupt_index);
478 66321a11 bellard
                            env->interrupt_index = 0;
479 327ac2e7 blueswir1
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
480 327ac2e7 blueswir1
                            cpu_check_irqs(env);
481 327ac2e7 blueswir1
#endif
482 b5fc09ae blueswir1
                        next_tb = 0;
483 66321a11 bellard
                        }
484 e95c8d51 bellard
                    } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
485 e95c8d51 bellard
                        //do_interrupt(0, 0, 0, 0, 0);
486 e95c8d51 bellard
                        env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
487 a90b7318 balrog
                    }
488 b5ff1b31 bellard
#elif defined(TARGET_ARM)
489 b5ff1b31 bellard
                    if (interrupt_request & CPU_INTERRUPT_FIQ
490 b5ff1b31 bellard
                        && !(env->uncached_cpsr & CPSR_F)) {
491 b5ff1b31 bellard
                        env->exception_index = EXCP_FIQ;
492 b5ff1b31 bellard
                        do_interrupt(env);
493 b5fc09ae blueswir1
                        next_tb = 0;
494 b5ff1b31 bellard
                    }
495 9ee6e8bb pbrook
                    /* ARMv7-M interrupt return works by loading a magic value
496 9ee6e8bb pbrook
                       into the PC.  On real hardware the load causes the
497 9ee6e8bb pbrook
                       return to occur.  The qemu implementation performs the
498 9ee6e8bb pbrook
                       jump normally, then does the exception return when the
499 9ee6e8bb pbrook
                       CPU tries to execute code at the magic address.
500 9ee6e8bb pbrook
                       This will cause the magic PC value to be pushed to
501 9ee6e8bb pbrook
                       the stack if an interrupt occured at the wrong time.
502 9ee6e8bb pbrook
                       We avoid this by disabling interrupts when
503 9ee6e8bb pbrook
                       pc contains a magic address.  */
504 b5ff1b31 bellard
                    if (interrupt_request & CPU_INTERRUPT_HARD
505 9ee6e8bb pbrook
                        && ((IS_M(env) && env->regs[15] < 0xfffffff0)
506 9ee6e8bb pbrook
                            || !(env->uncached_cpsr & CPSR_I))) {
507 b5ff1b31 bellard
                        env->exception_index = EXCP_IRQ;
508 b5ff1b31 bellard
                        do_interrupt(env);
509 b5fc09ae blueswir1
                        next_tb = 0;
510 b5ff1b31 bellard
                    }
511 fdf9b3e8 bellard
#elif defined(TARGET_SH4)
512 e96e2044 ths
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
513 e96e2044 ths
                        do_interrupt(env);
514 b5fc09ae blueswir1
                        next_tb = 0;
515 e96e2044 ths
                    }
516 eddf68a6 j_mayer
#elif defined(TARGET_ALPHA)
517 eddf68a6 j_mayer
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
518 eddf68a6 j_mayer
                        do_interrupt(env);
519 b5fc09ae blueswir1
                        next_tb = 0;
520 eddf68a6 j_mayer
                    }
521 f1ccf904 ths
#elif defined(TARGET_CRIS)
522 f1ccf904 ths
                    if (interrupt_request & CPU_INTERRUPT_HARD) {
523 f1ccf904 ths
                        do_interrupt(env);
524 b5fc09ae blueswir1
                        next_tb = 0;
525 f1ccf904 ths
                    }
526 0633879f pbrook
#elif defined(TARGET_M68K)
527 0633879f pbrook
                    if (interrupt_request & CPU_INTERRUPT_HARD
528 0633879f pbrook
                        && ((env->sr & SR_I) >> SR_I_SHIFT)
529 0633879f pbrook
                            < env->pending_level) {
530 0633879f pbrook
                        /* Real hardware gets the interrupt vector via an
531 0633879f pbrook
                           IACK cycle at this point.  Current emulated
532 0633879f pbrook
                           hardware doesn't rely on this, so we
533 0633879f pbrook
                           provide/save the vector when the interrupt is
534 0633879f pbrook
                           first signalled.  */
535 0633879f pbrook
                        env->exception_index = env->pending_vector;
536 0633879f pbrook
                        do_interrupt(1);
537 b5fc09ae blueswir1
                        next_tb = 0;
538 0633879f pbrook
                    }
539 68a79315 bellard
#endif
540 9d05095e bellard
                   /* Don't use the cached interupt_request value,
541 9d05095e bellard
                      do_interrupt may have updated the EXITTB flag. */
542 b5ff1b31 bellard
                    if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
543 bf3e8bf1 bellard
                        env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
544 bf3e8bf1 bellard
                        /* ensure that no TB jump will be modified as
545 bf3e8bf1 bellard
                           the program flow was changed */
546 b5fc09ae blueswir1
                        next_tb = 0;
547 bf3e8bf1 bellard
                    }
548 68a79315 bellard
                    if (interrupt_request & CPU_INTERRUPT_EXIT) {
549 68a79315 bellard
                        env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
550 68a79315 bellard
                        env->exception_index = EXCP_INTERRUPT;
551 68a79315 bellard
                        cpu_loop_exit();
552 68a79315 bellard
                    }
553 3fb2ded1 bellard
                }
554 7d13299d bellard
#ifdef DEBUG_EXEC
555 b5ff1b31 bellard
                if ((loglevel & CPU_LOG_TB_CPU)) {
556 3fb2ded1 bellard
                    /* restore flags in standard format */
557 ecb644f4 ths
                    regs_to_env();
558 ecb644f4 ths
#if defined(TARGET_I386)
559 3fb2ded1 bellard
                    env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
560 7fe48483 bellard
                    cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
561 3fb2ded1 bellard
                    env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
562 e4533c7a bellard
#elif defined(TARGET_ARM)
563 7fe48483 bellard
                    cpu_dump_state(env, logfile, fprintf, 0);
564 93ac68bc bellard
#elif defined(TARGET_SPARC)
565 3475187d bellard
                    REGWPTR = env->regbase + (env->cwp * 16);
566 3475187d bellard
                    env->regwptr = REGWPTR;
567 3475187d bellard
                    cpu_dump_state(env, logfile, fprintf, 0);
568 67867308 bellard
#elif defined(TARGET_PPC)
569 7fe48483 bellard
                    cpu_dump_state(env, logfile, fprintf, 0);
570 e6e5906b pbrook
#elif defined(TARGET_M68K)
571 e6e5906b pbrook
                    cpu_m68k_flush_flags(env, env->cc_op);
572 e6e5906b pbrook
                    env->cc_op = CC_OP_FLAGS;
573 e6e5906b pbrook
                    env->sr = (env->sr & 0xffe0)
574 e6e5906b pbrook
                              | env->cc_dest | (env->cc_x << 4);
575 e6e5906b pbrook
                    cpu_dump_state(env, logfile, fprintf, 0);
576 6af0bf9c bellard
#elif defined(TARGET_MIPS)
577 6af0bf9c bellard
                    cpu_dump_state(env, logfile, fprintf, 0);
578 fdf9b3e8 bellard
#elif defined(TARGET_SH4)
579 fdf9b3e8 bellard
                    cpu_dump_state(env, logfile, fprintf, 0);
580 eddf68a6 j_mayer
#elif defined(TARGET_ALPHA)
581 eddf68a6 j_mayer
                    cpu_dump_state(env, logfile, fprintf, 0);
582 f1ccf904 ths
#elif defined(TARGET_CRIS)
583 f1ccf904 ths
                    cpu_dump_state(env, logfile, fprintf, 0);
584 e4533c7a bellard
#else
585 5fafdf24 ths
#error unsupported target CPU
586 e4533c7a bellard
#endif
587 3fb2ded1 bellard
                }
588 7d13299d bellard
#endif
589 8a40a180 bellard
                tb = tb_find_fast();
590 9d27abd9 bellard
#ifdef DEBUG_EXEC
591 c1135f61 bellard
                if ((loglevel & CPU_LOG_EXEC)) {
592 c27004ec bellard
                    fprintf(logfile, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",
593 c27004ec bellard
                            (long)tb->tc_ptr, tb->pc,
594 c27004ec bellard
                            lookup_symbol(tb->pc));
595 3fb2ded1 bellard
                }
596 9d27abd9 bellard
#endif
597 8a40a180 bellard
                /* see if we can patch the calling TB. When the TB
598 8a40a180 bellard
                   spans two pages, we cannot safely do a direct
599 8a40a180 bellard
                   jump. */
600 c27004ec bellard
                {
601 b5fc09ae blueswir1
                    if (next_tb != 0 &&
602 4d7a0880 blueswir1
#ifdef USE_KQEMU
603 f32fc648 bellard
                        (env->kqemu_enabled != 2) &&
604 f32fc648 bellard
#endif
605 ec6338ba bellard
                        tb->page_addr[1] == -1) {
606 3fb2ded1 bellard
                    spin_lock(&tb_lock);
607 b5fc09ae blueswir1
                    tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
608 3fb2ded1 bellard
                    spin_unlock(&tb_lock);
609 3fb2ded1 bellard
                }
610 c27004ec bellard
                }
611 3fb2ded1 bellard
                tc_ptr = tb->tc_ptr;
612 83479e77 bellard
                env->current_tb = tb;
613 3fb2ded1 bellard
                /* execute the generated code */
614 572a9d4a blueswir1
#if defined(__sparc__) && !defined(HOST_SOLARIS)
615 572a9d4a blueswir1
#undef env
616 572a9d4a blueswir1
                env = cpu_single_env;
617 572a9d4a blueswir1
#define env cpu_single_env
618 572a9d4a blueswir1
#endif
619 7cb69cae bellard
                next_tb = tcg_qemu_tb_exec(tc_ptr);
620 83479e77 bellard
                env->current_tb = NULL;
621 4cbf74b6 bellard
                /* reset soft MMU for next block (it can currently
622 4cbf74b6 bellard
                   only be set by a memory fault) */
623 4cbf74b6 bellard
#if defined(TARGET_I386) && !defined(CONFIG_SOFTMMU)
624 3f337316 bellard
                if (env->hflags & HF_SOFTMMU_MASK) {
625 3f337316 bellard
                    env->hflags &= ~HF_SOFTMMU_MASK;
626 4cbf74b6 bellard
                    /* do not allow linking to another block */
627 b5fc09ae blueswir1
                    next_tb = 0;
628 4cbf74b6 bellard
                }
629 4cbf74b6 bellard
#endif
630 f32fc648 bellard
#if defined(USE_KQEMU)
631 f32fc648 bellard
#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
632 f32fc648 bellard
                if (kqemu_is_ok(env) &&
633 f32fc648 bellard
                    (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
634 f32fc648 bellard
                    cpu_loop_exit();
635 f32fc648 bellard
                }
636 f32fc648 bellard
#endif
637 50a518e3 ths
            } /* for(;;) */
638 3fb2ded1 bellard
        } else {
639 0d1a29f9 bellard
            env_to_regs();
640 7d13299d bellard
        }
641 3fb2ded1 bellard
    } /* for(;;) */
642 3fb2ded1 bellard
643 7d13299d bellard
644 e4533c7a bellard
#if defined(TARGET_I386)
645 9de5e440 bellard
    /* restore flags in standard format */
646 fc2b4c48 bellard
    env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
647 e4533c7a bellard
#elif defined(TARGET_ARM)
648 b7bcbe95 bellard
    /* XXX: Save/restore host fpu exception state?.  */
649 93ac68bc bellard
#elif defined(TARGET_SPARC)
650 3475187d bellard
#if defined(reg_REGWPTR)
651 3475187d bellard
    REGWPTR = saved_regwptr;
652 3475187d bellard
#endif
653 67867308 bellard
#elif defined(TARGET_PPC)
654 e6e5906b pbrook
#elif defined(TARGET_M68K)
655 e6e5906b pbrook
    cpu_m68k_flush_flags(env, env->cc_op);
656 e6e5906b pbrook
    env->cc_op = CC_OP_FLAGS;
657 e6e5906b pbrook
    env->sr = (env->sr & 0xffe0)
658 e6e5906b pbrook
              | env->cc_dest | (env->cc_x << 4);
659 6af0bf9c bellard
#elif defined(TARGET_MIPS)
660 fdf9b3e8 bellard
#elif defined(TARGET_SH4)
661 eddf68a6 j_mayer
#elif defined(TARGET_ALPHA)
662 f1ccf904 ths
#elif defined(TARGET_CRIS)
663 fdf9b3e8 bellard
    /* XXXXX */
664 e4533c7a bellard
#else
665 e4533c7a bellard
#error unsupported target CPU
666 e4533c7a bellard
#endif
667 1057eaa7 pbrook
668 1057eaa7 pbrook
    /* restore global registers */
669 1057eaa7 pbrook
#include "hostregs_helper.h"
670 1057eaa7 pbrook
671 6a00d601 bellard
    /* fail safe : never use cpu_single_env outside cpu_exec() */
672 5fafdf24 ths
    cpu_single_env = NULL;
673 7d13299d bellard
    return ret;
674 7d13299d bellard
}
675 6dbad63e bellard
676 fbf9eeb3 bellard
/* must only be called from the generated code as an exception can be
677 fbf9eeb3 bellard
   generated */
678 fbf9eeb3 bellard
void tb_invalidate_page_range(target_ulong start, target_ulong end)
679 fbf9eeb3 bellard
{
680 dc5d0b3d bellard
    /* XXX: cannot enable it yet because it yields to MMU exception
681 dc5d0b3d bellard
       where NIP != read address on PowerPC */
682 dc5d0b3d bellard
#if 0
683 fbf9eeb3 bellard
    target_ulong phys_addr;
684 fbf9eeb3 bellard
    phys_addr = get_phys_addr_code(env, start);
685 fbf9eeb3 bellard
    tb_invalidate_phys_page_range(phys_addr, phys_addr + end - start, 0);
686 dc5d0b3d bellard
#endif
687 fbf9eeb3 bellard
}
688 fbf9eeb3 bellard
689 1a18c71b bellard
#if defined(TARGET_I386) && defined(CONFIG_USER_ONLY)
690 e4533c7a bellard
691 6dbad63e bellard
void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
692 6dbad63e bellard
{
693 6dbad63e bellard
    CPUX86State *saved_env;
694 6dbad63e bellard
695 6dbad63e bellard
    saved_env = env;
696 6dbad63e bellard
    env = s;
697 a412ac57 bellard
    if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
698 a513fe19 bellard
        selector &= 0xffff;
699 5fafdf24 ths
        cpu_x86_load_seg_cache(env, seg_reg, selector,
700 c27004ec bellard
                               (selector << 4), 0xffff, 0);
701 a513fe19 bellard
    } else {
702 5d97559d bellard
        helper_load_seg(seg_reg, selector);
703 a513fe19 bellard
    }
704 6dbad63e bellard
    env = saved_env;
705 6dbad63e bellard
}
706 9de5e440 bellard
707 6f12a2a6 bellard
void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32)
708 d0a1ffc9 bellard
{
709 d0a1ffc9 bellard
    CPUX86State *saved_env;
710 d0a1ffc9 bellard
711 d0a1ffc9 bellard
    saved_env = env;
712 d0a1ffc9 bellard
    env = s;
713 3b46e624 ths
714 6f12a2a6 bellard
    helper_fsave(ptr, data32);
715 d0a1ffc9 bellard
716 d0a1ffc9 bellard
    env = saved_env;
717 d0a1ffc9 bellard
}
718 d0a1ffc9 bellard
719 6f12a2a6 bellard
void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32)
720 d0a1ffc9 bellard
{
721 d0a1ffc9 bellard
    CPUX86State *saved_env;
722 d0a1ffc9 bellard
723 d0a1ffc9 bellard
    saved_env = env;
724 d0a1ffc9 bellard
    env = s;
725 3b46e624 ths
726 6f12a2a6 bellard
    helper_frstor(ptr, data32);
727 d0a1ffc9 bellard
728 d0a1ffc9 bellard
    env = saved_env;
729 d0a1ffc9 bellard
}
730 d0a1ffc9 bellard
731 e4533c7a bellard
#endif /* TARGET_I386 */
732 e4533c7a bellard
733 67b915a5 bellard
#if !defined(CONFIG_SOFTMMU)
734 67b915a5 bellard
735 3fb2ded1 bellard
#if defined(TARGET_I386)
736 3fb2ded1 bellard
737 b56dad1c bellard
/* 'pc' is the host PC at which the exception was raised. 'address' is
738 fd6ce8f6 bellard
   the effective address of the memory exception. 'is_write' is 1 if a
739 fd6ce8f6 bellard
   write caused the exception and otherwise 0'. 'old_set' is the
740 fd6ce8f6 bellard
   signal set which should be restored */
741 2b413144 bellard
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
742 5fafdf24 ths
                                    int is_write, sigset_t *old_set,
743 bf3e8bf1 bellard
                                    void *puc)
744 9de5e440 bellard
{
745 a513fe19 bellard
    TranslationBlock *tb;
746 a513fe19 bellard
    int ret;
747 68a79315 bellard
748 83479e77 bellard
    if (cpu_single_env)
749 83479e77 bellard
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
750 fd6ce8f6 bellard
#if defined(DEBUG_SIGNAL)
751 5fafdf24 ths
    qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
752 bf3e8bf1 bellard
                pc, address, is_write, *(unsigned long *)old_set);
753 9de5e440 bellard
#endif
754 25eb4484 bellard
    /* XXX: locking issue */
755 53a5960a pbrook
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
756 fd6ce8f6 bellard
        return 1;
757 fd6ce8f6 bellard
    }
758 fbf9eeb3 bellard
759 3fb2ded1 bellard
    /* see if it is an MMU fault */
760 6ebbf390 j_mayer
    ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
761 3fb2ded1 bellard
    if (ret < 0)
762 3fb2ded1 bellard
        return 0; /* not an MMU fault */
763 3fb2ded1 bellard
    if (ret == 0)
764 3fb2ded1 bellard
        return 1; /* the MMU fault was handled without causing real CPU fault */
765 3fb2ded1 bellard
    /* now we have a real cpu fault */
766 a513fe19 bellard
    tb = tb_find_pc(pc);
767 a513fe19 bellard
    if (tb) {
768 9de5e440 bellard
        /* the PC is inside the translated code. It means that we have
769 9de5e440 bellard
           a virtual CPU fault */
770 bf3e8bf1 bellard
        cpu_restore_state(tb, env, pc, puc);
771 3fb2ded1 bellard
    }
772 4cbf74b6 bellard
    if (ret == 1) {
773 3fb2ded1 bellard
#if 0
774 5fafdf24 ths
        printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n",
775 4cbf74b6 bellard
               env->eip, env->cr[2], env->error_code);
776 3fb2ded1 bellard
#endif
777 4cbf74b6 bellard
        /* we restore the process signal mask as the sigreturn should
778 4cbf74b6 bellard
           do it (XXX: use sigsetjmp) */
779 4cbf74b6 bellard
        sigprocmask(SIG_SETMASK, old_set, NULL);
780 54ca9095 bellard
        raise_exception_err(env->exception_index, env->error_code);
781 4cbf74b6 bellard
    } else {
782 4cbf74b6 bellard
        /* activate soft MMU for this block */
783 3f337316 bellard
        env->hflags |= HF_SOFTMMU_MASK;
784 fbf9eeb3 bellard
        cpu_resume_from_signal(env, puc);
785 4cbf74b6 bellard
    }
786 3fb2ded1 bellard
    /* never comes here */
787 3fb2ded1 bellard
    return 1;
788 3fb2ded1 bellard
}
789 3fb2ded1 bellard
790 e4533c7a bellard
#elif defined(TARGET_ARM)
791 3fb2ded1 bellard
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
792 bf3e8bf1 bellard
                                    int is_write, sigset_t *old_set,
793 bf3e8bf1 bellard
                                    void *puc)
794 3fb2ded1 bellard
{
795 68016c62 bellard
    TranslationBlock *tb;
796 68016c62 bellard
    int ret;
797 68016c62 bellard
798 68016c62 bellard
    if (cpu_single_env)
799 68016c62 bellard
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
800 68016c62 bellard
#if defined(DEBUG_SIGNAL)
801 5fafdf24 ths
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
802 68016c62 bellard
           pc, address, is_write, *(unsigned long *)old_set);
803 68016c62 bellard
#endif
804 9f0777ed bellard
    /* XXX: locking issue */
805 53a5960a pbrook
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
806 9f0777ed bellard
        return 1;
807 9f0777ed bellard
    }
808 68016c62 bellard
    /* see if it is an MMU fault */
809 6ebbf390 j_mayer
    ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
810 68016c62 bellard
    if (ret < 0)
811 68016c62 bellard
        return 0; /* not an MMU fault */
812 68016c62 bellard
    if (ret == 0)
813 68016c62 bellard
        return 1; /* the MMU fault was handled without causing real CPU fault */
814 68016c62 bellard
    /* now we have a real cpu fault */
815 68016c62 bellard
    tb = tb_find_pc(pc);
816 68016c62 bellard
    if (tb) {
817 68016c62 bellard
        /* the PC is inside the translated code. It means that we have
818 68016c62 bellard
           a virtual CPU fault */
819 68016c62 bellard
        cpu_restore_state(tb, env, pc, puc);
820 68016c62 bellard
    }
821 68016c62 bellard
    /* we restore the process signal mask as the sigreturn should
822 68016c62 bellard
       do it (XXX: use sigsetjmp) */
823 68016c62 bellard
    sigprocmask(SIG_SETMASK, old_set, NULL);
824 68016c62 bellard
    cpu_loop_exit();
825 968c74da aurel32
    /* never comes here */
826 968c74da aurel32
    return 1;
827 3fb2ded1 bellard
}
828 93ac68bc bellard
#elif defined(TARGET_SPARC)
829 93ac68bc bellard
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
830 bf3e8bf1 bellard
                                    int is_write, sigset_t *old_set,
831 bf3e8bf1 bellard
                                    void *puc)
832 93ac68bc bellard
{
833 68016c62 bellard
    TranslationBlock *tb;
834 68016c62 bellard
    int ret;
835 68016c62 bellard
836 68016c62 bellard
    if (cpu_single_env)
837 68016c62 bellard
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
838 68016c62 bellard
#if defined(DEBUG_SIGNAL)
839 5fafdf24 ths
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
840 68016c62 bellard
           pc, address, is_write, *(unsigned long *)old_set);
841 68016c62 bellard
#endif
842 b453b70b bellard
    /* XXX: locking issue */
843 53a5960a pbrook
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
844 b453b70b bellard
        return 1;
845 b453b70b bellard
    }
846 68016c62 bellard
    /* see if it is an MMU fault */
847 6ebbf390 j_mayer
    ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
848 68016c62 bellard
    if (ret < 0)
849 68016c62 bellard
        return 0; /* not an MMU fault */
850 68016c62 bellard
    if (ret == 0)
851 68016c62 bellard
        return 1; /* the MMU fault was handled without causing real CPU fault */
852 68016c62 bellard
    /* now we have a real cpu fault */
853 68016c62 bellard
    tb = tb_find_pc(pc);
854 68016c62 bellard
    if (tb) {
855 68016c62 bellard
        /* the PC is inside the translated code. It means that we have
856 68016c62 bellard
           a virtual CPU fault */
857 68016c62 bellard
        cpu_restore_state(tb, env, pc, puc);
858 68016c62 bellard
    }
859 68016c62 bellard
    /* we restore the process signal mask as the sigreturn should
860 68016c62 bellard
       do it (XXX: use sigsetjmp) */
861 68016c62 bellard
    sigprocmask(SIG_SETMASK, old_set, NULL);
862 68016c62 bellard
    cpu_loop_exit();
863 968c74da aurel32
    /* never comes here */
864 968c74da aurel32
    return 1;
865 93ac68bc bellard
}
866 67867308 bellard
#elif defined (TARGET_PPC)
867 67867308 bellard
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
868 bf3e8bf1 bellard
                                    int is_write, sigset_t *old_set,
869 bf3e8bf1 bellard
                                    void *puc)
870 67867308 bellard
{
871 67867308 bellard
    TranslationBlock *tb;
872 ce09776b bellard
    int ret;
873 3b46e624 ths
874 67867308 bellard
    if (cpu_single_env)
875 67867308 bellard
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
876 67867308 bellard
#if defined(DEBUG_SIGNAL)
877 5fafdf24 ths
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
878 67867308 bellard
           pc, address, is_write, *(unsigned long *)old_set);
879 67867308 bellard
#endif
880 67867308 bellard
    /* XXX: locking issue */
881 53a5960a pbrook
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
882 67867308 bellard
        return 1;
883 67867308 bellard
    }
884 67867308 bellard
885 ce09776b bellard
    /* see if it is an MMU fault */
886 6ebbf390 j_mayer
    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
887 ce09776b bellard
    if (ret < 0)
888 ce09776b bellard
        return 0; /* not an MMU fault */
889 ce09776b bellard
    if (ret == 0)
890 ce09776b bellard
        return 1; /* the MMU fault was handled without causing real CPU fault */
891 ce09776b bellard
892 67867308 bellard
    /* now we have a real cpu fault */
893 67867308 bellard
    tb = tb_find_pc(pc);
894 67867308 bellard
    if (tb) {
895 67867308 bellard
        /* the PC is inside the translated code. It means that we have
896 67867308 bellard
           a virtual CPU fault */
897 bf3e8bf1 bellard
        cpu_restore_state(tb, env, pc, puc);
898 67867308 bellard
    }
899 ce09776b bellard
    if (ret == 1) {
900 67867308 bellard
#if 0
901 5fafdf24 ths
        printf("PF exception: NIP=0x%08x error=0x%x %p\n",
902 ce09776b bellard
               env->nip, env->error_code, tb);
903 67867308 bellard
#endif
904 67867308 bellard
    /* we restore the process signal mask as the sigreturn should
905 67867308 bellard
       do it (XXX: use sigsetjmp) */
906 bf3e8bf1 bellard
        sigprocmask(SIG_SETMASK, old_set, NULL);
907 9fddaa0c bellard
        do_raise_exception_err(env->exception_index, env->error_code);
908 ce09776b bellard
    } else {
909 ce09776b bellard
        /* activate soft MMU for this block */
910 fbf9eeb3 bellard
        cpu_resume_from_signal(env, puc);
911 ce09776b bellard
    }
912 67867308 bellard
    /* never comes here */
913 e6e5906b pbrook
    return 1;
914 e6e5906b pbrook
}
915 e6e5906b pbrook
916 e6e5906b pbrook
#elif defined(TARGET_M68K)
917 e6e5906b pbrook
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
918 e6e5906b pbrook
                                    int is_write, sigset_t *old_set,
919 e6e5906b pbrook
                                    void *puc)
920 e6e5906b pbrook
{
921 e6e5906b pbrook
    TranslationBlock *tb;
922 e6e5906b pbrook
    int ret;
923 e6e5906b pbrook
924 e6e5906b pbrook
    if (cpu_single_env)
925 e6e5906b pbrook
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
926 e6e5906b pbrook
#if defined(DEBUG_SIGNAL)
927 5fafdf24 ths
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
928 e6e5906b pbrook
           pc, address, is_write, *(unsigned long *)old_set);
929 e6e5906b pbrook
#endif
930 e6e5906b pbrook
    /* XXX: locking issue */
931 e6e5906b pbrook
    if (is_write && page_unprotect(address, pc, puc)) {
932 e6e5906b pbrook
        return 1;
933 e6e5906b pbrook
    }
934 e6e5906b pbrook
    /* see if it is an MMU fault */
935 6ebbf390 j_mayer
    ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
936 e6e5906b pbrook
    if (ret < 0)
937 e6e5906b pbrook
        return 0; /* not an MMU fault */
938 e6e5906b pbrook
    if (ret == 0)
939 e6e5906b pbrook
        return 1; /* the MMU fault was handled without causing real CPU fault */
940 e6e5906b pbrook
    /* now we have a real cpu fault */
941 e6e5906b pbrook
    tb = tb_find_pc(pc);
942 e6e5906b pbrook
    if (tb) {
943 e6e5906b pbrook
        /* the PC is inside the translated code. It means that we have
944 e6e5906b pbrook
           a virtual CPU fault */
945 e6e5906b pbrook
        cpu_restore_state(tb, env, pc, puc);
946 e6e5906b pbrook
    }
947 e6e5906b pbrook
    /* we restore the process signal mask as the sigreturn should
948 e6e5906b pbrook
       do it (XXX: use sigsetjmp) */
949 e6e5906b pbrook
    sigprocmask(SIG_SETMASK, old_set, NULL);
950 e6e5906b pbrook
    cpu_loop_exit();
951 e6e5906b pbrook
    /* never comes here */
952 67867308 bellard
    return 1;
953 67867308 bellard
}
954 6af0bf9c bellard
955 6af0bf9c bellard
#elif defined (TARGET_MIPS)
956 6af0bf9c bellard
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
957 6af0bf9c bellard
                                    int is_write, sigset_t *old_set,
958 6af0bf9c bellard
                                    void *puc)
959 6af0bf9c bellard
{
960 6af0bf9c bellard
    TranslationBlock *tb;
961 6af0bf9c bellard
    int ret;
962 3b46e624 ths
963 6af0bf9c bellard
    if (cpu_single_env)
964 6af0bf9c bellard
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
965 6af0bf9c bellard
#if defined(DEBUG_SIGNAL)
966 5fafdf24 ths
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
967 6af0bf9c bellard
           pc, address, is_write, *(unsigned long *)old_set);
968 6af0bf9c bellard
#endif
969 6af0bf9c bellard
    /* XXX: locking issue */
970 53a5960a pbrook
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
971 6af0bf9c bellard
        return 1;
972 6af0bf9c bellard
    }
973 6af0bf9c bellard
974 6af0bf9c bellard
    /* see if it is an MMU fault */
975 6ebbf390 j_mayer
    ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
976 6af0bf9c bellard
    if (ret < 0)
977 6af0bf9c bellard
        return 0; /* not an MMU fault */
978 6af0bf9c bellard
    if (ret == 0)
979 6af0bf9c bellard
        return 1; /* the MMU fault was handled without causing real CPU fault */
980 6af0bf9c bellard
981 6af0bf9c bellard
    /* now we have a real cpu fault */
982 6af0bf9c bellard
    tb = tb_find_pc(pc);
983 6af0bf9c bellard
    if (tb) {
984 6af0bf9c bellard
        /* the PC is inside the translated code. It means that we have
985 6af0bf9c bellard
           a virtual CPU fault */
986 6af0bf9c bellard
        cpu_restore_state(tb, env, pc, puc);
987 6af0bf9c bellard
    }
988 6af0bf9c bellard
    if (ret == 1) {
989 6af0bf9c bellard
#if 0
990 5fafdf24 ths
        printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n",
991 1eb5207b ths
               env->PC, env->error_code, tb);
992 6af0bf9c bellard
#endif
993 6af0bf9c bellard
    /* we restore the process signal mask as the sigreturn should
994 6af0bf9c bellard
       do it (XXX: use sigsetjmp) */
995 6af0bf9c bellard
        sigprocmask(SIG_SETMASK, old_set, NULL);
996 6af0bf9c bellard
        do_raise_exception_err(env->exception_index, env->error_code);
997 6af0bf9c bellard
    } else {
998 6af0bf9c bellard
        /* activate soft MMU for this block */
999 6af0bf9c bellard
        cpu_resume_from_signal(env, puc);
1000 6af0bf9c bellard
    }
1001 6af0bf9c bellard
    /* never comes here */
1002 6af0bf9c bellard
    return 1;
1003 6af0bf9c bellard
}
1004 6af0bf9c bellard
1005 fdf9b3e8 bellard
#elif defined (TARGET_SH4)
1006 fdf9b3e8 bellard
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1007 fdf9b3e8 bellard
                                    int is_write, sigset_t *old_set,
1008 fdf9b3e8 bellard
                                    void *puc)
1009 fdf9b3e8 bellard
{
1010 fdf9b3e8 bellard
    TranslationBlock *tb;
1011 fdf9b3e8 bellard
    int ret;
1012 3b46e624 ths
1013 fdf9b3e8 bellard
    if (cpu_single_env)
1014 fdf9b3e8 bellard
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
1015 fdf9b3e8 bellard
#if defined(DEBUG_SIGNAL)
1016 5fafdf24 ths
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1017 fdf9b3e8 bellard
           pc, address, is_write, *(unsigned long *)old_set);
1018 fdf9b3e8 bellard
#endif
1019 fdf9b3e8 bellard
    /* XXX: locking issue */
1020 fdf9b3e8 bellard
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
1021 fdf9b3e8 bellard
        return 1;
1022 fdf9b3e8 bellard
    }
1023 fdf9b3e8 bellard
1024 fdf9b3e8 bellard
    /* see if it is an MMU fault */
1025 6ebbf390 j_mayer
    ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1026 fdf9b3e8 bellard
    if (ret < 0)
1027 fdf9b3e8 bellard
        return 0; /* not an MMU fault */
1028 fdf9b3e8 bellard
    if (ret == 0)
1029 fdf9b3e8 bellard
        return 1; /* the MMU fault was handled without causing real CPU fault */
1030 fdf9b3e8 bellard
1031 fdf9b3e8 bellard
    /* now we have a real cpu fault */
1032 eddf68a6 j_mayer
    tb = tb_find_pc(pc);
1033 eddf68a6 j_mayer
    if (tb) {
1034 eddf68a6 j_mayer
        /* the PC is inside the translated code. It means that we have
1035 eddf68a6 j_mayer
           a virtual CPU fault */
1036 eddf68a6 j_mayer
        cpu_restore_state(tb, env, pc, puc);
1037 eddf68a6 j_mayer
    }
1038 eddf68a6 j_mayer
#if 0
1039 5fafdf24 ths
        printf("PF exception: NIP=0x%08x error=0x%x %p\n",
1040 eddf68a6 j_mayer
               env->nip, env->error_code, tb);
1041 eddf68a6 j_mayer
#endif
1042 eddf68a6 j_mayer
    /* we restore the process signal mask as the sigreturn should
1043 eddf68a6 j_mayer
       do it (XXX: use sigsetjmp) */
1044 eddf68a6 j_mayer
    sigprocmask(SIG_SETMASK, old_set, NULL);
1045 eddf68a6 j_mayer
    cpu_loop_exit();
1046 eddf68a6 j_mayer
    /* never comes here */
1047 eddf68a6 j_mayer
    return 1;
1048 eddf68a6 j_mayer
}
1049 eddf68a6 j_mayer
1050 eddf68a6 j_mayer
#elif defined (TARGET_ALPHA)
1051 eddf68a6 j_mayer
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1052 eddf68a6 j_mayer
                                    int is_write, sigset_t *old_set,
1053 eddf68a6 j_mayer
                                    void *puc)
1054 eddf68a6 j_mayer
{
1055 eddf68a6 j_mayer
    TranslationBlock *tb;
1056 eddf68a6 j_mayer
    int ret;
1057 3b46e624 ths
1058 eddf68a6 j_mayer
    if (cpu_single_env)
1059 eddf68a6 j_mayer
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
1060 eddf68a6 j_mayer
#if defined(DEBUG_SIGNAL)
1061 5fafdf24 ths
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1062 eddf68a6 j_mayer
           pc, address, is_write, *(unsigned long *)old_set);
1063 eddf68a6 j_mayer
#endif
1064 eddf68a6 j_mayer
    /* XXX: locking issue */
1065 eddf68a6 j_mayer
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
1066 eddf68a6 j_mayer
        return 1;
1067 eddf68a6 j_mayer
    }
1068 eddf68a6 j_mayer
1069 eddf68a6 j_mayer
    /* see if it is an MMU fault */
1070 6ebbf390 j_mayer
    ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1071 eddf68a6 j_mayer
    if (ret < 0)
1072 eddf68a6 j_mayer
        return 0; /* not an MMU fault */
1073 eddf68a6 j_mayer
    if (ret == 0)
1074 eddf68a6 j_mayer
        return 1; /* the MMU fault was handled without causing real CPU fault */
1075 eddf68a6 j_mayer
1076 eddf68a6 j_mayer
    /* now we have a real cpu fault */
1077 fdf9b3e8 bellard
    tb = tb_find_pc(pc);
1078 fdf9b3e8 bellard
    if (tb) {
1079 fdf9b3e8 bellard
        /* the PC is inside the translated code. It means that we have
1080 fdf9b3e8 bellard
           a virtual CPU fault */
1081 fdf9b3e8 bellard
        cpu_restore_state(tb, env, pc, puc);
1082 fdf9b3e8 bellard
    }
1083 fdf9b3e8 bellard
#if 0
1084 5fafdf24 ths
        printf("PF exception: NIP=0x%08x error=0x%x %p\n",
1085 fdf9b3e8 bellard
               env->nip, env->error_code, tb);
1086 fdf9b3e8 bellard
#endif
1087 fdf9b3e8 bellard
    /* we restore the process signal mask as the sigreturn should
1088 fdf9b3e8 bellard
       do it (XXX: use sigsetjmp) */
1089 355fb23d pbrook
    sigprocmask(SIG_SETMASK, old_set, NULL);
1090 355fb23d pbrook
    cpu_loop_exit();
1091 fdf9b3e8 bellard
    /* never comes here */
1092 fdf9b3e8 bellard
    return 1;
1093 fdf9b3e8 bellard
}
1094 f1ccf904 ths
#elif defined (TARGET_CRIS)
1095 f1ccf904 ths
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
1096 f1ccf904 ths
                                    int is_write, sigset_t *old_set,
1097 f1ccf904 ths
                                    void *puc)
1098 f1ccf904 ths
{
1099 f1ccf904 ths
    TranslationBlock *tb;
1100 f1ccf904 ths
    int ret;
1101 f1ccf904 ths
1102 f1ccf904 ths
    if (cpu_single_env)
1103 f1ccf904 ths
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
1104 f1ccf904 ths
#if defined(DEBUG_SIGNAL)
1105 f1ccf904 ths
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
1106 f1ccf904 ths
           pc, address, is_write, *(unsigned long *)old_set);
1107 f1ccf904 ths
#endif
1108 f1ccf904 ths
    /* XXX: locking issue */
1109 f1ccf904 ths
    if (is_write && page_unprotect(h2g(address), pc, puc)) {
1110 f1ccf904 ths
        return 1;
1111 f1ccf904 ths
    }
1112 f1ccf904 ths
1113 f1ccf904 ths
    /* see if it is an MMU fault */
1114 6ebbf390 j_mayer
    ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
1115 f1ccf904 ths
    if (ret < 0)
1116 f1ccf904 ths
        return 0; /* not an MMU fault */
1117 f1ccf904 ths
    if (ret == 0)
1118 f1ccf904 ths
        return 1; /* the MMU fault was handled without causing real CPU fault */
1119 f1ccf904 ths
1120 f1ccf904 ths
    /* now we have a real cpu fault */
1121 f1ccf904 ths
    tb = tb_find_pc(pc);
1122 f1ccf904 ths
    if (tb) {
1123 f1ccf904 ths
        /* the PC is inside the translated code. It means that we have
1124 f1ccf904 ths
           a virtual CPU fault */
1125 f1ccf904 ths
        cpu_restore_state(tb, env, pc, puc);
1126 f1ccf904 ths
    }
1127 f1ccf904 ths
    /* we restore the process signal mask as the sigreturn should
1128 f1ccf904 ths
       do it (XXX: use sigsetjmp) */
1129 f1ccf904 ths
    sigprocmask(SIG_SETMASK, old_set, NULL);
1130 f1ccf904 ths
    cpu_loop_exit();
1131 f1ccf904 ths
    /* never comes here */
1132 f1ccf904 ths
    return 1;
1133 f1ccf904 ths
}
1134 f1ccf904 ths
1135 e4533c7a bellard
#else
1136 e4533c7a bellard
#error unsupported target CPU
1137 e4533c7a bellard
#endif
1138 9de5e440 bellard
1139 2b413144 bellard
#if defined(__i386__)
1140 2b413144 bellard
1141 d8ecc0b9 bellard
#if defined(__APPLE__)
1142 d8ecc0b9 bellard
# include <sys/ucontext.h>
1143 d8ecc0b9 bellard
1144 d8ecc0b9 bellard
# define EIP_sig(context)  (*((unsigned long*)&(context)->uc_mcontext->ss.eip))
1145 d8ecc0b9 bellard
# define TRAP_sig(context)    ((context)->uc_mcontext->es.trapno)
1146 d8ecc0b9 bellard
# define ERROR_sig(context)   ((context)->uc_mcontext->es.err)
1147 d8ecc0b9 bellard
#else
1148 d8ecc0b9 bellard
# define EIP_sig(context)     ((context)->uc_mcontext.gregs[REG_EIP])
1149 d8ecc0b9 bellard
# define TRAP_sig(context)    ((context)->uc_mcontext.gregs[REG_TRAPNO])
1150 d8ecc0b9 bellard
# define ERROR_sig(context)   ((context)->uc_mcontext.gregs[REG_ERR])
1151 d8ecc0b9 bellard
#endif
1152 d8ecc0b9 bellard
1153 5fafdf24 ths
int cpu_signal_handler(int host_signum, void *pinfo,
1154 e4533c7a bellard
                       void *puc)
1155 9de5e440 bellard
{
1156 5a7b542b ths
    siginfo_t *info = pinfo;
1157 9de5e440 bellard
    struct ucontext *uc = puc;
1158 9de5e440 bellard
    unsigned long pc;
1159 bf3e8bf1 bellard
    int trapno;
1160 97eb5b14 bellard
1161 d691f669 bellard
#ifndef REG_EIP
1162 d691f669 bellard
/* for glibc 2.1 */
1163 fd6ce8f6 bellard
#define REG_EIP    EIP
1164 fd6ce8f6 bellard
#define REG_ERR    ERR
1165 fd6ce8f6 bellard
#define REG_TRAPNO TRAPNO
1166 d691f669 bellard
#endif
1167 d8ecc0b9 bellard
    pc = EIP_sig(uc);
1168 d8ecc0b9 bellard
    trapno = TRAP_sig(uc);
1169 ec6338ba bellard
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1170 ec6338ba bellard
                             trapno == 0xe ?
1171 ec6338ba bellard
                             (ERROR_sig(uc) >> 1) & 1 : 0,
1172 ec6338ba bellard
                             &uc->uc_sigmask, puc);
1173 2b413144 bellard
}
1174 2b413144 bellard
1175 bc51c5c9 bellard
#elif defined(__x86_64__)
1176 bc51c5c9 bellard
1177 5a7b542b ths
int cpu_signal_handler(int host_signum, void *pinfo,
1178 bc51c5c9 bellard
                       void *puc)
1179 bc51c5c9 bellard
{
1180 5a7b542b ths
    siginfo_t *info = pinfo;
1181 bc51c5c9 bellard
    struct ucontext *uc = puc;
1182 bc51c5c9 bellard
    unsigned long pc;
1183 bc51c5c9 bellard
1184 bc51c5c9 bellard
    pc = uc->uc_mcontext.gregs[REG_RIP];
1185 5fafdf24 ths
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1186 5fafdf24 ths
                             uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ?
1187 bc51c5c9 bellard
                             (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,
1188 bc51c5c9 bellard
                             &uc->uc_sigmask, puc);
1189 bc51c5c9 bellard
}
1190 bc51c5c9 bellard
1191 83fb7adf bellard
#elif defined(__powerpc__)
1192 2b413144 bellard
1193 83fb7adf bellard
/***********************************************************************
1194 83fb7adf bellard
 * signal context platform-specific definitions
1195 83fb7adf bellard
 * From Wine
1196 83fb7adf bellard
 */
1197 83fb7adf bellard
#ifdef linux
1198 83fb7adf bellard
/* All Registers access - only for local access */
1199 83fb7adf bellard
# define REG_sig(reg_name, context)                ((context)->uc_mcontext.regs->reg_name)
1200 83fb7adf bellard
/* Gpr Registers access  */
1201 83fb7adf bellard
# define GPR_sig(reg_num, context)                REG_sig(gpr[reg_num], context)
1202 83fb7adf bellard
# define IAR_sig(context)                        REG_sig(nip, context)        /* Program counter */
1203 83fb7adf bellard
# define MSR_sig(context)                        REG_sig(msr, context)   /* Machine State Register (Supervisor) */
1204 83fb7adf bellard
# define CTR_sig(context)                        REG_sig(ctr, context)   /* Count register */
1205 83fb7adf bellard
# define XER_sig(context)                        REG_sig(xer, context) /* User's integer exception register */
1206 83fb7adf bellard
# define LR_sig(context)                        REG_sig(link, context) /* Link register */
1207 83fb7adf bellard
# define CR_sig(context)                        REG_sig(ccr, context) /* Condition register */
1208 83fb7adf bellard
/* Float Registers access  */
1209 83fb7adf bellard
# define FLOAT_sig(reg_num, context)                (((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num])
1210 83fb7adf bellard
# define FPSCR_sig(context)                        (*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4)))
1211 83fb7adf bellard
/* Exception Registers access */
1212 83fb7adf bellard
# define DAR_sig(context)                        REG_sig(dar, context)
1213 83fb7adf bellard
# define DSISR_sig(context)                        REG_sig(dsisr, context)
1214 83fb7adf bellard
# define TRAP_sig(context)                        REG_sig(trap, context)
1215 83fb7adf bellard
#endif /* linux */
1216 83fb7adf bellard
1217 83fb7adf bellard
#ifdef __APPLE__
1218 83fb7adf bellard
# include <sys/ucontext.h>
1219 83fb7adf bellard
typedef struct ucontext SIGCONTEXT;
1220 83fb7adf bellard
/* All Registers access - only for local access */
1221 83fb7adf bellard
# define REG_sig(reg_name, context)                ((context)->uc_mcontext->ss.reg_name)
1222 83fb7adf bellard
# define FLOATREG_sig(reg_name, context)        ((context)->uc_mcontext->fs.reg_name)
1223 83fb7adf bellard
# define EXCEPREG_sig(reg_name, context)        ((context)->uc_mcontext->es.reg_name)
1224 83fb7adf bellard
# define VECREG_sig(reg_name, context)                ((context)->uc_mcontext->vs.reg_name)
1225 83fb7adf bellard
/* Gpr Registers access */
1226 83fb7adf bellard
# define GPR_sig(reg_num, context)                REG_sig(r##reg_num, context)
1227 83fb7adf bellard
# define IAR_sig(context)                        REG_sig(srr0, context)        /* Program counter */
1228 83fb7adf bellard
# define MSR_sig(context)                        REG_sig(srr1, context)  /* Machine State Register (Supervisor) */
1229 83fb7adf bellard
# define CTR_sig(context)                        REG_sig(ctr, context)
1230 83fb7adf bellard
# define XER_sig(context)                        REG_sig(xer, context) /* Link register */
1231 83fb7adf bellard
# define LR_sig(context)                        REG_sig(lr, context)  /* User's integer exception register */
1232 83fb7adf bellard
# define CR_sig(context)                        REG_sig(cr, context)  /* Condition register */
1233 83fb7adf bellard
/* Float Registers access */
1234 83fb7adf bellard
# define FLOAT_sig(reg_num, context)                FLOATREG_sig(fpregs[reg_num], context)
1235 83fb7adf bellard
# define FPSCR_sig(context)                        ((double)FLOATREG_sig(fpscr, context))
1236 83fb7adf bellard
/* Exception Registers access */
1237 83fb7adf bellard
# define DAR_sig(context)                        EXCEPREG_sig(dar, context)     /* Fault registers for coredump */
1238 83fb7adf bellard
# define DSISR_sig(context)                        EXCEPREG_sig(dsisr, context)
1239 83fb7adf bellard
# define TRAP_sig(context)                        EXCEPREG_sig(exception, context) /* number of powerpc exception taken */
1240 83fb7adf bellard
#endif /* __APPLE__ */
1241 83fb7adf bellard
1242 5fafdf24 ths
int cpu_signal_handler(int host_signum, void *pinfo,
1243 e4533c7a bellard
                       void *puc)
1244 2b413144 bellard
{
1245 5a7b542b ths
    siginfo_t *info = pinfo;
1246 25eb4484 bellard
    struct ucontext *uc = puc;
1247 25eb4484 bellard
    unsigned long pc;
1248 25eb4484 bellard
    int is_write;
1249 25eb4484 bellard
1250 83fb7adf bellard
    pc = IAR_sig(uc);
1251 25eb4484 bellard
    is_write = 0;
1252 25eb4484 bellard
#if 0
1253 25eb4484 bellard
    /* ppc 4xx case */
1254 83fb7adf bellard
    if (DSISR_sig(uc) & 0x00800000)
1255 25eb4484 bellard
        is_write = 1;
1256 25eb4484 bellard
#else
1257 83fb7adf bellard
    if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000))
1258 25eb4484 bellard
        is_write = 1;
1259 25eb4484 bellard
#endif
1260 5fafdf24 ths
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1261 bf3e8bf1 bellard
                             is_write, &uc->uc_sigmask, puc);
1262 2b413144 bellard
}
1263 2b413144 bellard
1264 2f87c607 bellard
#elif defined(__alpha__)
1265 2f87c607 bellard
1266 5fafdf24 ths
int cpu_signal_handler(int host_signum, void *pinfo,
1267 2f87c607 bellard
                           void *puc)
1268 2f87c607 bellard
{
1269 5a7b542b ths
    siginfo_t *info = pinfo;
1270 2f87c607 bellard
    struct ucontext *uc = puc;
1271 2f87c607 bellard
    uint32_t *pc = uc->uc_mcontext.sc_pc;
1272 2f87c607 bellard
    uint32_t insn = *pc;
1273 2f87c607 bellard
    int is_write = 0;
1274 2f87c607 bellard
1275 8c6939c0 bellard
    /* XXX: need kernel patch to get write flag faster */
1276 2f87c607 bellard
    switch (insn >> 26) {
1277 2f87c607 bellard
    case 0x0d: // stw
1278 2f87c607 bellard
    case 0x0e: // stb
1279 2f87c607 bellard
    case 0x0f: // stq_u
1280 2f87c607 bellard
    case 0x24: // stf
1281 2f87c607 bellard
    case 0x25: // stg
1282 2f87c607 bellard
    case 0x26: // sts
1283 2f87c607 bellard
    case 0x27: // stt
1284 2f87c607 bellard
    case 0x2c: // stl
1285 2f87c607 bellard
    case 0x2d: // stq
1286 2f87c607 bellard
    case 0x2e: // stl_c
1287 2f87c607 bellard
    case 0x2f: // stq_c
1288 2f87c607 bellard
        is_write = 1;
1289 2f87c607 bellard
    }
1290 2f87c607 bellard
1291 5fafdf24 ths
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1292 bf3e8bf1 bellard
                             is_write, &uc->uc_sigmask, puc);
1293 2f87c607 bellard
}
1294 8c6939c0 bellard
#elif defined(__sparc__)
1295 8c6939c0 bellard
1296 5fafdf24 ths
int cpu_signal_handler(int host_signum, void *pinfo,
1297 e4533c7a bellard
                       void *puc)
1298 8c6939c0 bellard
{
1299 5a7b542b ths
    siginfo_t *info = pinfo;
1300 8c6939c0 bellard
    int is_write;
1301 8c6939c0 bellard
    uint32_t insn;
1302 c9e1e2b0 blueswir1
#if !defined(__sparc_v9__) || defined(HOST_SOLARIS)
1303 c9e1e2b0 blueswir1
    uint32_t *regs = (uint32_t *)(info + 1);
1304 c9e1e2b0 blueswir1
    void *sigmask = (regs + 20);
1305 8c6939c0 bellard
    /* XXX: is there a standard glibc define ? */
1306 c9e1e2b0 blueswir1
    unsigned long pc = regs[1];
1307 c9e1e2b0 blueswir1
#else
1308 c9e1e2b0 blueswir1
    struct sigcontext *sc = puc;
1309 c9e1e2b0 blueswir1
    unsigned long pc = sc->sigc_regs.tpc;
1310 c9e1e2b0 blueswir1
    void *sigmask = (void *)sc->sigc_mask;
1311 c9e1e2b0 blueswir1
#endif
1312 c9e1e2b0 blueswir1
1313 8c6939c0 bellard
    /* XXX: need kernel patch to get write flag faster */
1314 8c6939c0 bellard
    is_write = 0;
1315 8c6939c0 bellard
    insn = *(uint32_t *)pc;
1316 8c6939c0 bellard
    if ((insn >> 30) == 3) {
1317 8c6939c0 bellard
      switch((insn >> 19) & 0x3f) {
1318 8c6939c0 bellard
      case 0x05: // stb
1319 8c6939c0 bellard
      case 0x06: // sth
1320 8c6939c0 bellard
      case 0x04: // st
1321 8c6939c0 bellard
      case 0x07: // std
1322 8c6939c0 bellard
      case 0x24: // stf
1323 8c6939c0 bellard
      case 0x27: // stdf
1324 8c6939c0 bellard
      case 0x25: // stfsr
1325 8c6939c0 bellard
        is_write = 1;
1326 8c6939c0 bellard
        break;
1327 8c6939c0 bellard
      }
1328 8c6939c0 bellard
    }
1329 5fafdf24 ths
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1330 bf3e8bf1 bellard
                             is_write, sigmask, NULL);
1331 8c6939c0 bellard
}
1332 8c6939c0 bellard
1333 8c6939c0 bellard
#elif defined(__arm__)
1334 8c6939c0 bellard
1335 5fafdf24 ths
int cpu_signal_handler(int host_signum, void *pinfo,
1336 e4533c7a bellard
                       void *puc)
1337 8c6939c0 bellard
{
1338 5a7b542b ths
    siginfo_t *info = pinfo;
1339 8c6939c0 bellard
    struct ucontext *uc = puc;
1340 8c6939c0 bellard
    unsigned long pc;
1341 8c6939c0 bellard
    int is_write;
1342 3b46e624 ths
1343 4eee57f5 balrog
    pc = uc->uc_mcontext.arm_pc;
1344 8c6939c0 bellard
    /* XXX: compute is_write */
1345 8c6939c0 bellard
    is_write = 0;
1346 5fafdf24 ths
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1347 8c6939c0 bellard
                             is_write,
1348 f3a9676a pbrook
                             &uc->uc_sigmask, puc);
1349 8c6939c0 bellard
}
1350 8c6939c0 bellard
1351 38e584a0 bellard
#elif defined(__mc68000)
1352 38e584a0 bellard
1353 5fafdf24 ths
int cpu_signal_handler(int host_signum, void *pinfo,
1354 38e584a0 bellard
                       void *puc)
1355 38e584a0 bellard
{
1356 5a7b542b ths
    siginfo_t *info = pinfo;
1357 38e584a0 bellard
    struct ucontext *uc = puc;
1358 38e584a0 bellard
    unsigned long pc;
1359 38e584a0 bellard
    int is_write;
1360 3b46e624 ths
1361 38e584a0 bellard
    pc = uc->uc_mcontext.gregs[16];
1362 38e584a0 bellard
    /* XXX: compute is_write */
1363 38e584a0 bellard
    is_write = 0;
1364 5fafdf24 ths
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1365 38e584a0 bellard
                             is_write,
1366 bf3e8bf1 bellard
                             &uc->uc_sigmask, puc);
1367 38e584a0 bellard
}
1368 38e584a0 bellard
1369 b8076a74 bellard
#elif defined(__ia64)
1370 b8076a74 bellard
1371 b8076a74 bellard
#ifndef __ISR_VALID
1372 b8076a74 bellard
  /* This ought to be in <bits/siginfo.h>... */
1373 b8076a74 bellard
# define __ISR_VALID        1
1374 b8076a74 bellard
#endif
1375 b8076a74 bellard
1376 5a7b542b ths
int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
1377 b8076a74 bellard
{
1378 5a7b542b ths
    siginfo_t *info = pinfo;
1379 b8076a74 bellard
    struct ucontext *uc = puc;
1380 b8076a74 bellard
    unsigned long ip;
1381 b8076a74 bellard
    int is_write = 0;
1382 b8076a74 bellard
1383 b8076a74 bellard
    ip = uc->uc_mcontext.sc_ip;
1384 b8076a74 bellard
    switch (host_signum) {
1385 b8076a74 bellard
      case SIGILL:
1386 b8076a74 bellard
      case SIGFPE:
1387 b8076a74 bellard
      case SIGSEGV:
1388 b8076a74 bellard
      case SIGBUS:
1389 b8076a74 bellard
      case SIGTRAP:
1390 fd4a43e4 bellard
          if (info->si_code && (info->si_segvflags & __ISR_VALID))
1391 b8076a74 bellard
              /* ISR.W (write-access) is bit 33:  */
1392 b8076a74 bellard
              is_write = (info->si_isr >> 33) & 1;
1393 b8076a74 bellard
          break;
1394 b8076a74 bellard
1395 b8076a74 bellard
      default:
1396 b8076a74 bellard
          break;
1397 b8076a74 bellard
    }
1398 b8076a74 bellard
    return handle_cpu_signal(ip, (unsigned long)info->si_addr,
1399 b8076a74 bellard
                             is_write,
1400 b8076a74 bellard
                             &uc->uc_sigmask, puc);
1401 b8076a74 bellard
}
1402 b8076a74 bellard
1403 90cb9493 bellard
#elif defined(__s390__)
1404 90cb9493 bellard
1405 5fafdf24 ths
int cpu_signal_handler(int host_signum, void *pinfo,
1406 90cb9493 bellard
                       void *puc)
1407 90cb9493 bellard
{
1408 5a7b542b ths
    siginfo_t *info = pinfo;
1409 90cb9493 bellard
    struct ucontext *uc = puc;
1410 90cb9493 bellard
    unsigned long pc;
1411 90cb9493 bellard
    int is_write;
1412 3b46e624 ths
1413 90cb9493 bellard
    pc = uc->uc_mcontext.psw.addr;
1414 90cb9493 bellard
    /* XXX: compute is_write */
1415 90cb9493 bellard
    is_write = 0;
1416 5fafdf24 ths
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1417 c4b89d18 ths
                             is_write, &uc->uc_sigmask, puc);
1418 c4b89d18 ths
}
1419 c4b89d18 ths
1420 c4b89d18 ths
#elif defined(__mips__)
1421 c4b89d18 ths
1422 5fafdf24 ths
int cpu_signal_handler(int host_signum, void *pinfo,
1423 c4b89d18 ths
                       void *puc)
1424 c4b89d18 ths
{
1425 9617efe8 ths
    siginfo_t *info = pinfo;
1426 c4b89d18 ths
    struct ucontext *uc = puc;
1427 c4b89d18 ths
    greg_t pc = uc->uc_mcontext.pc;
1428 c4b89d18 ths
    int is_write;
1429 3b46e624 ths
1430 c4b89d18 ths
    /* XXX: compute is_write */
1431 c4b89d18 ths
    is_write = 0;
1432 5fafdf24 ths
    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
1433 c4b89d18 ths
                             is_write, &uc->uc_sigmask, puc);
1434 90cb9493 bellard
}
1435 90cb9493 bellard
1436 f54b3f92 aurel32
#elif defined(__hppa__)
1437 f54b3f92 aurel32
1438 f54b3f92 aurel32
int cpu_signal_handler(int host_signum, void *pinfo,
1439 f54b3f92 aurel32
                       void *puc)
1440 f54b3f92 aurel32
{
1441 f54b3f92 aurel32
    struct siginfo *info = pinfo;
1442 f54b3f92 aurel32
    struct ucontext *uc = puc;
1443 f54b3f92 aurel32
    unsigned long pc;
1444 f54b3f92 aurel32
    int is_write;
1445 f54b3f92 aurel32
1446 f54b3f92 aurel32
    pc = uc->uc_mcontext.sc_iaoq[0];
1447 f54b3f92 aurel32
    /* FIXME: compute is_write */
1448 f54b3f92 aurel32
    is_write = 0;
1449 f54b3f92 aurel32
    return handle_cpu_signal(pc, (unsigned long)info->si_addr, 
1450 f54b3f92 aurel32
                             is_write,
1451 f54b3f92 aurel32
                             &uc->uc_sigmask, puc);
1452 f54b3f92 aurel32
}
1453 f54b3f92 aurel32
1454 9de5e440 bellard
#else
1455 2b413144 bellard
1456 3fb2ded1 bellard
#error host CPU specific signal handler needed
1457 2b413144 bellard
1458 9de5e440 bellard
#endif
1459 67b915a5 bellard
1460 67b915a5 bellard
#endif /* !defined(CONFIG_SOFTMMU) */