Statistics
| Branch: | Revision:

root / cpu-exec.c @ 1ffc346f

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