cpu-exec.c revision 8b23a6c7e1aee255004dd19098d4c2462b61b849
18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *  i386 emulator main execution loop
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *  Copyright (c) 2003-2005 Fabrice Bellard
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This library is free software; you can redistribute it and/or
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * modify it under the terms of the GNU Lesser General Public
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * License as published by the Free Software Foundation; either
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * version 2 of the License, or (at your option) any later version.
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This library is distributed in the hope that it will be useful,
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Lesser General Public License for more details.
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * You should have received a copy of the GNU Lesser General Public
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * License along with this library; if not, write to the Free Software
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "config.h"
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define CPU_NO_GLOBAL_REGS
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "exec.h"
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "disas.h"
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "tcg.h"
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(CONFIG_SOFTMMU)
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef EAX
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef ECX
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef EDX
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef EBX
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef ESP
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef EBP
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef ESI
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef EDI
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef EIP
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <signal.h>
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/ucontext.h>
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(__sparc__) && !defined(HOST_SOLARIS)
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project// Work around ugly bugs in glibc that mangle global register contents
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef env
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define env cpu_single_env
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint tb_invalidated_flag;
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//#define DEBUG_EXEC
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//#define DEBUG_SIGNAL
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid cpu_loop_exit(void)
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* NOTE: the register at this point must be saved by hand because
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       longjmp restore them */
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    regs_to_env();
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    longjmp(env->jmp_env, 1);
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !(defined(TARGET_SPARC) || defined(TARGET_SH4) || defined(TARGET_M68K))
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define reg_T2
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* exit the current TB from a signal handler. The host registers are
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   restored in a state compatible with the CPU emulator
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid cpu_resume_from_signal(CPUState *env1, void *puc)
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(CONFIG_SOFTMMU)
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ucontext *uc = puc;
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env = env1;
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: restore cpu registers saved in host registers */
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(CONFIG_SOFTMMU)
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (puc) {
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* XXX: use siglongjmp ? */
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    longjmp(env->jmp_env, 1);
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Execute the code without caching the generated code. An interpreter
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   could be used if available. */
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb)
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long next_tb;
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TranslationBlock *tb;
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Should never happen.
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       We only end up here when an existing TB is too long.  */
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (max_cycles > CF_COUNT_MASK)
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        max_cycles = CF_COUNT_MASK;
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     max_cycles);
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->current_tb = tb;
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* execute the generated code */
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    next_tb = tcg_qemu_tb_exec(tb->tc_ptr);
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((next_tb & 3) == 2) {
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Restore PC.  This may happen if async event occurs before
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           the TB starts executing.  */
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        CPU_PC_FROM_TB(env, tb);
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb_phys_invalidate(tb, -1);
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb_free(tb);
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic TranslationBlock *tb_find_slow(target_ulong pc,
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                      target_ulong cs_base,
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                      uint64_t flags)
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TranslationBlock *tb, **ptb1;
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned int h;
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb_invalidated_flag = 0;
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    regs_to_env(); /* XXX: do it just before cpu_gen_code() */
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* find translated block using physical mappings */
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    phys_pc = get_phys_addr_code(env, pc);
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    phys_page1 = phys_pc & TARGET_PAGE_MASK;
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    phys_page2 = -1;
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    h = tb_phys_hash_func(phys_pc);
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ptb1 = &tb_phys_hash[h];
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(;;) {
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tb = *ptb1;
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!tb)
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto not_found;
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (tb->pc == pc &&
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tb->page_addr[0] == phys_page1 &&
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tb->cs_base == cs_base &&
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            tb->flags == flags) {
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* check next page if needed */
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (tb->page_addr[1] != -1) {
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                virt_page2 = (pc & TARGET_PAGE_MASK) +
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    TARGET_PAGE_SIZE;
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                phys_page2 = get_phys_addr_code(env, virt_page2);
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (tb->page_addr[1] == phys_page2)
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    goto found;
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                goto found;
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ptb1 = &tb->phys_hash_next;
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project not_found:
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* if no translated code available, then translate it now */
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb = tb_gen_code(env, pc, cs_base, flags, 0);
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project found:
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we add the TB in the virtual pc hash table */
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return tb;
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline TranslationBlock *tb_find_fast(void)
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TranslationBlock *tb;
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    target_ulong cs_base, pc;
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t flags;
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we record a subset of the CPU state. It will
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       always be the same before a given translated block
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       is executed. */
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(TARGET_I386)
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flags = env->hflags;
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cs_base = env->segs[R_CS].base;
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = cs_base + env->eip;
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ARM)
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flags = env->thumb | (env->vfp.vec_len << 1)
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            | (env->vfp.vec_stride << 4);
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR)
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        flags |= (1 << 6);
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30))
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        flags |= (1 << 7);
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flags |= (env->condexec_bits << 8);
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cs_base = 0;
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = env->regs[15];
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SPARC)
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TARGET_SPARC64
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flags = ((env->pstate & PS_AM) << 2)
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        | (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    // FPU enable . Supervisor
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flags = (env->psref << 4) | env->psrs;
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cs_base = env->npc;
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = env->pc;
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_PPC)
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flags = env->hflags;
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cs_base = 0;
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = env->nip;
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_MIPS)
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cs_base = 0;
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = env->active_tc.PC;
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_M68K)
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flags = (env->fpcr & M68K_FPCR_PREC)  /* Bit  6 */
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            | (env->sr & SR_S)            /* Bit  13 */
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            | ((env->macsr >> 4) & 0xf);  /* Bits 0-3 */
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cs_base = 0;
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = env->pc;
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SH4)
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flags = (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    | DELAY_SLOT_TRUE | DELAY_SLOT_CLEARME))   /* Bits  0- 3 */
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            | (env->fpscr & (FPSCR_FR | FPSCR_SZ | FPSCR_PR))  /* Bits 19-21 */
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            | (env->sr & (SR_MD | SR_RB));                     /* Bits 29-30 */
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cs_base = 0;
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = env->pc;
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ALPHA)
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flags = env->ps;
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cs_base = 0;
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = env->pc;
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_CRIS)
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flags = env->pregs[PR_CCS] & (P_FLAG | U_FLAG | X_FLAG);
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    flags |= env->dslot;
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cs_base = 0;
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = env->pc;
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#error unsupported CPU
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 tb->flags != flags)) {
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        tb = tb_find_slow(pc, cs_base, flags);
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return tb;
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* main execution loop */
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_exec(CPUState *env1)
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DECLARE_HOST_REGS 1
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "hostregs_helper.h"
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret, interrupt_request;
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TranslationBlock *tb;
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t *tc_ptr;
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long next_tb;
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cpu_halted(env1) == EXCP_HALTED)
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return EXCP_HALTED;
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_single_env = env1;
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* first we save global registers */
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define SAVE_HOST_REGS 1
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "hostregs_helper.h"
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env = env1;
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env_to_regs();
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(TARGET_I386)
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* put eflags in CPU temporary format */
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DF = 1 - (2 * ((env->eflags >> 10) & 1));
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CC_OP = CC_OP_EFLAGS;
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SPARC)
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_M68K)
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->cc_op = CC_OP_FLAGS;
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->cc_dest = env->sr & 0xf;
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->cc_x = (env->sr >> 4) & 1;
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ALPHA)
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ARM)
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_PPC)
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_MIPS)
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SH4)
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_CRIS)
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXXXX */
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#error unsupported target CPU
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->exception_index = -1;
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* prepare setjmp context for exception handling */
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(;;) {
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (setjmp(env->jmp_env) == 0) {
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env->current_tb = NULL;
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* if an exception is pending, we execute it here */
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (env->exception_index >= 0) {
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (env->exception_index >= EXCP_INTERRUPT) {
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* exit request from the cpu execution loop */
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    ret = env->exception_index;
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    break;
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                } else if (env->user_mode_only) {
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* if user mode only, we simulate a fake exception
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       which will be handled outside the cpu execution
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       loop */
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(TARGET_I386)
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    do_interrupt_user(env->exception_index,
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                      env->exception_is_int,
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                      env->error_code,
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                      env->exception_next_eip);
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* successfully delivered */
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    env->old_exception = -1;
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    ret = env->exception_index;
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    break;
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                } else {
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(TARGET_I386)
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* simulate a real cpu exception. On i386, it can
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       trigger new exceptions, but we do not handle
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       double or triple faults yet. */
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    do_interrupt(env->exception_index,
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                 env->exception_is_int,
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                 env->error_code,
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                 env->exception_next_eip, 0);
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* successfully delivered */
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    env->old_exception = -1;
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_PPC)
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    do_interrupt(env);
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_MIPS)
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    do_interrupt(env);
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SPARC)
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    do_interrupt(env);
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ARM)
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    do_interrupt(env);
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SH4)
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    do_interrupt(env);
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ALPHA)
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    do_interrupt(env);
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_CRIS)
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    do_interrupt(env);
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_M68K)
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    do_interrupt(0);
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->exception_index = -1;
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef USE_KQEMU
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (kqemu_is_ok(env) && env->interrupt_request == 0) {
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                int ret;
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ret = kqemu_cpu_exec(env);
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* put eflags in CPU temporary format */
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                DF = 1 - (2 * ((env->eflags >> 10) & 1));
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                CC_OP = CC_OP_EFLAGS;
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (ret == 1) {
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* exception */
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    longjmp(env->jmp_env, 1);
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                } else if (ret == 2) {
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* softmmu execution needed */
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                } else {
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (env->interrupt_request != 0) {
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        /* hardware interrupt will be executed just after */
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    } else {
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        /* otherwise, we restart */
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        longjmp(env->jmp_env, 1);
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            next_tb = 0; /* force lookup of first TB */
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(;;) {
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                interrupt_request = env->interrupt_request;
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (unlikely(interrupt_request) &&
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    likely(!(env->singlestep_enabled & SSTEP_NOIRQ))) {
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (interrupt_request & CPU_INTERRUPT_DEBUG) {
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        env->exception_index = EXCP_DEBUG;
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        cpu_loop_exit();
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS)
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (interrupt_request & CPU_INTERRUPT_HALT) {
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        env->interrupt_request &= ~CPU_INTERRUPT_HALT;
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        env->halted = 1;
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        env->exception_index = EXCP_HLT;
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        cpu_loop_exit();
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(TARGET_I386)
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (env->hflags2 & HF2_GIF_MASK) {
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if ((interrupt_request & CPU_INTERRUPT_SMI) &&
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            !(env->hflags & HF_SMM_MASK)) {
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            svm_check_intercept(SVM_EXIT_SMI);
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            env->interrupt_request &= ~CPU_INTERRUPT_SMI;
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            do_smm_enter();
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            next_tb = 0;
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                   !(env->hflags2 & HF2_NMI_MASK)) {
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            env->interrupt_request &= ~CPU_INTERRUPT_NMI;
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            env->hflags2 |= HF2_NMI_MASK;
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            next_tb = 0;
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                   (((env->hflags2 & HF2_VINTR_MASK) &&
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                     (env->hflags2 & HF2_HIF_MASK)) ||
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    (!(env->hflags2 & HF2_VINTR_MASK) &&
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                     (env->eflags & IF_MASK &&
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                      !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            int intno;
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            svm_check_intercept(SVM_EXIT_INTR);
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            intno = cpu_get_pic_interrupt(env);
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            if (loglevel & CPU_LOG_TB_IN_ASM) {
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            }
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            do_interrupt(intno, 0, 0, 0, 1);
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            /* ensure that no TB jump will be modified as
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                               the program flow was changed */
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            next_tb = 0;
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(CONFIG_USER_ONLY)
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                   (env->eflags & IF_MASK) &&
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                   !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            int intno;
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            /* FIXME: this should respect TPR */
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            svm_check_intercept(SVM_EXIT_VINTR);
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            if (loglevel & CPU_LOG_TB_IN_ASM)
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno);
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            do_interrupt(intno, 0, 0, 0, 1);
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            next_tb = 0;
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_PPC)
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if ((interrupt_request & CPU_INTERRUPT_RESET)) {
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        cpu_ppc_reset(env);
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (interrupt_request & CPU_INTERRUPT_HARD) {
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        ppc_hw_interrupt(env);
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (env->pending_interrupts == 0)
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        next_tb = 0;
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_MIPS)
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        (env->CP0_Status & (1 << CP0St_IE)) &&
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        !(env->CP0_Status & (1 << CP0St_EXL)) &&
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        !(env->CP0_Status & (1 << CP0St_ERL)) &&
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        !(env->hflags & MIPS_HFLAG_DM)) {
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        /* Raise it */
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        env->exception_index = EXCP_EXT_INTERRUPT;
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        env->error_code = 0;
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        do_interrupt(env);
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        next_tb = 0;
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SPARC)
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			(env->psret != 0)) {
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			int pil = env->interrupt_index & 15;
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			int type = env->interrupt_index & 0xf0;
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			if (((type == TT_EXTINT) &&
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			     (pil == 15 || pil > env->psrpil)) ||
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			    type != TT_EXTINT) {
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			    env->interrupt_request &= ~CPU_INTERRUPT_HARD;
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            env->exception_index = env->interrupt_index;
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            do_interrupt(env);
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			    env->interrupt_index = 0;
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            cpu_check_irqs(env);
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        next_tb = 0;
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			}
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			//do_interrupt(0, 0, 0, 0, 0);
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project			env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    }
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ARM)
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (interrupt_request & CPU_INTERRUPT_FIQ
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        && !(env->uncached_cpsr & CPSR_F)) {
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        env->exception_index = EXCP_FIQ;
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        do_interrupt(env);
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        next_tb = 0;
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* ARMv7-M interrupt return works by loading a magic value
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       into the PC.  On real hardware the load causes the
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       return to occur.  The qemu implementation performs the
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       jump normally, then does the exception return when the
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       CPU tries to execute code at the magic address.
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       This will cause the magic PC value to be pushed to
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       the stack if an interrupt occured at the wrong time.
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       We avoid this by disabling interrupts when
4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       pc contains a magic address.  */
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (interrupt_request & CPU_INTERRUPT_HARD
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        && ((IS_M(env) && env->regs[15] < 0xfffffff0)
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            || !(env->uncached_cpsr & CPSR_I))) {
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        env->exception_index = EXCP_IRQ;
4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        do_interrupt(env);
4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        next_tb = 0;
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SH4)
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (interrupt_request & CPU_INTERRUPT_HARD) {
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        do_interrupt(env);
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        next_tb = 0;
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ALPHA)
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (interrupt_request & CPU_INTERRUPT_HARD) {
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        do_interrupt(env);
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        next_tb = 0;
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_CRIS)
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (interrupt_request & CPU_INTERRUPT_HARD
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        && (env->pregs[PR_CCS] & I_FLAG)) {
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        env->exception_index = EXCP_IRQ;
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        do_interrupt(env);
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        next_tb = 0;
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (interrupt_request & CPU_INTERRUPT_NMI
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        && (env->pregs[PR_CCS] & M_FLAG)) {
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        env->exception_index = EXCP_NMI;
5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        do_interrupt(env);
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        next_tb = 0;
5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_M68K)
5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (interrupt_request & CPU_INTERRUPT_HARD
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        && ((env->sr & SR_I) >> SR_I_SHIFT)
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            < env->pending_level) {
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        /* Real hardware gets the interrupt vector via an
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                           IACK cycle at this point.  Current emulated
5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                           hardware doesn't rely on this, so we
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                           provide/save the vector when the interrupt is
5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                           first signalled.  */
5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        env->exception_index = env->pending_vector;
5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        do_interrupt(1);
5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        next_tb = 0;
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   /* Don't use the cached interupt_request value,
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      do_interrupt may have updated the EXITTB flag. */
5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        /* ensure that no TB jump will be modified as
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                           the program flow was changed */
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        next_tb = 0;
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (interrupt_request & CPU_INTERRUPT_EXIT) {
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        env->exception_index = EXCP_INTERRUPT;
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        cpu_loop_exit();
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_EXEC
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ((loglevel & CPU_LOG_TB_CPU)) {
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* restore flags in standard format */
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    regs_to_env();
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(TARGET_I386)
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    cpu_dump_state(env, logfile, fprintf, X86_DUMP_CCOP);
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ARM)
5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    cpu_dump_state(env, logfile, fprintf, 0);
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SPARC)
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    cpu_dump_state(env, logfile, fprintf, 0);
5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_PPC)
5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    cpu_dump_state(env, logfile, fprintf, 0);
5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_M68K)
5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    cpu_m68k_flush_flags(env, env->cc_op);
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    env->cc_op = CC_OP_FLAGS;
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    env->sr = (env->sr & 0xffe0)
5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              | env->cc_dest | (env->cc_x << 4);
5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    cpu_dump_state(env, logfile, fprintf, 0);
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_MIPS)
5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    cpu_dump_state(env, logfile, fprintf, 0);
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SH4)
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project		    cpu_dump_state(env, logfile, fprintf, 0);
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ALPHA)
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    cpu_dump_state(env, logfile, fprintf, 0);
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_CRIS)
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    cpu_dump_state(env, logfile, fprintf, 0);
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#error unsupported target CPU
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                spin_lock(&tb_lock);
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                tb = tb_find_fast();
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* Note: we do it here to avoid a gcc bug on Mac OS X when
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   doing it in tb_find_slow */
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (tb_invalidated_flag) {
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* as some TB could have been invalidated because
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       of memory exceptions while generating the code, we
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       must recompute the hash index here */
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    next_tb = 0;
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    tb_invalidated_flag = 0;
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_EXEC
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ((loglevel & CPU_LOG_EXEC)) {
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    fprintf(logfile, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            (long)tb->tc_ptr, tb->pc,
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            lookup_symbol(tb->pc));
6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* see if we can patch the calling TB. When the TB
6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   spans two pages, we cannot safely do a direct
6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   jump. */
6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (next_tb != 0 &&
6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef USE_KQEMU
6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        (env->kqemu_enabled != 2) &&
6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        tb->page_addr[1] == -1) {
6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                spin_unlock(&tb_lock);
6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                env->current_tb = tb;
6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                while (env->current_tb) {
6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    tc_ptr = tb->tc_ptr;
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* execute the generated code */
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(__sparc__) && !defined(HOST_SOLARIS)
6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#undef env
6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    env = cpu_single_env;
6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define env cpu_single_env
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    next_tb = tcg_qemu_tb_exec(tc_ptr);
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    env->current_tb = NULL;
6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if ((next_tb & 3) == 2) {
6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        /* Instruction counter expired.  */
6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        int insns_left;
6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        tb = (TranslationBlock *)(long)(next_tb & ~3);
6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        /* Restore PC.  */
6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        CPU_PC_FROM_TB(env, tb);
6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        insns_left = env->icount_decr.u32;
6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (env->icount_extra && insns_left >= 0) {
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            /* Refill decrementer and continue execution.  */
6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            env->icount_extra += insns_left;
6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            if (env->icount_extra > 0xffff) {
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                insns_left = 0xffff;
6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            } else {
6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                insns_left = env->icount_extra;
6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            }
6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            env->icount_extra -= insns_left;
6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            env->icount_decr.u16.low = insns_left;
6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        } else {
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            if (insns_left > 0) {
6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                /* Execute remaining instructions.  */
6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                cpu_exec_nocache(insns_left, tb);
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            }
6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            env->exception_index = EXCP_INTERRUPT;
6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            next_tb = 0;
6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            cpu_loop_exit();
6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* reset soft MMU for next block (it can currently
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   only be set by a memory fault) */
6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(USE_KQEMU)
6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (kqemu_is_ok(env) &&
6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    cpu_loop_exit();
6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } /* for(;;) */
6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            env_to_regs();
6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } /* for(;;) */
6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(TARGET_I386)
6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* restore flags in standard format */
6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ARM)
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: Save/restore host fpu exception state?.  */
6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SPARC)
6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_PPC)
6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_M68K)
6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_m68k_flush_flags(env, env->cc_op);
6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->cc_op = CC_OP_FLAGS;
6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env->sr = (env->sr & 0xffe0)
6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              | env->cc_dest | (env->cc_x << 4);
6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_MIPS)
6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SH4)
6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ALPHA)
6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_CRIS)
6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXXXX */
6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#error unsupported target CPU
6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* restore global registers */
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "hostregs_helper.h"
6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* fail safe : never use cpu_single_env outside cpu_exec() */
6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_single_env = NULL;
6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* must only be called from the generated code as an exception can be
7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   generated */
7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid tb_invalidate_page_range(target_ulong start, target_ulong end)
7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: cannot enable it yet because it yields to MMU exception
7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       where NIP != read address on PowerPC */
7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    target_ulong phys_addr;
7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    phys_addr = get_phys_addr_code(env, start);
7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb_invalidate_phys_page_range(phys_addr, phys_addr + end - start, 0);
7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(TARGET_I386) && defined(CONFIG_USER_ONLY)
7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CPUX86State *saved_env;
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    saved_env = env;
7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env = s;
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        selector &= 0xffff;
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_x86_load_seg_cache(env, seg_reg, selector,
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                               (selector << 4), 0xffff, 0);
7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        helper_load_seg(seg_reg, selector);
7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env = saved_env;
7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32)
7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CPUX86State *saved_env;
7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    saved_env = env;
7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env = s;
7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    helper_fsave(ptr, data32);
7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env = saved_env;
7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32)
7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CPUX86State *saved_env;
7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    saved_env = env;
7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env = s;
7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    helper_frstor(ptr, data32);
7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    env = saved_env;
7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* TARGET_I386 */
7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(CONFIG_SOFTMMU)
7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(TARGET_I386)
7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 'pc' is the host PC at which the exception was raised. 'address' is
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   the effective address of the memory exception. 'is_write' is 1 if a
7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   write caused the exception and otherwise 0'. 'old_set' is the
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   signal set which should be restored */
7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int handle_cpu_signal(unsigned long pc, unsigned long address,
7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    int is_write, sigset_t *old_set,
7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    void *puc)
7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TranslationBlock *tb;
7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cpu_single_env)
7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env = cpu_single_env; /* XXX: find a correct solution for multithread */
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(DEBUG_SIGNAL)
7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                pc, address, is_write, *(unsigned long *)old_set);
7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: locking issue */
7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (is_write && page_unprotect(h2g(address), pc, puc)) {
7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* see if it is an MMU fault */
7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0; /* not an MMU fault */
7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret == 0)
7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1; /* the MMU fault was handled without causing real CPU fault */
7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* now we have a real cpu fault */
7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb = tb_find_pc(pc);
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tb) {
7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* the PC is inside the translated code. It means that we have
7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           a virtual CPU fault */
7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_restore_state(tb, env, pc, puc);
7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret == 1) {
7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n",
7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               env->eip, env->cr[2], env->error_code);
7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* we restore the process signal mask as the sigreturn should
8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           do it (XXX: use sigsetjmp) */
8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sigprocmask(SIG_SETMASK, old_set, NULL);
8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        raise_exception_err(env->exception_index, env->error_code);
8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* activate soft MMU for this block */
8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env->hflags |= HF_SOFTMMU_MASK;
8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_resume_from_signal(env, puc);
8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* never comes here */
8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 1;
8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_ARM)
8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int handle_cpu_signal(unsigned long pc, unsigned long address,
8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    int is_write, sigset_t *old_set,
8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    void *puc)
8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TranslationBlock *tb;
8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cpu_single_env)
8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env = cpu_single_env; /* XXX: find a correct solution for multithread */
8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(DEBUG_SIGNAL)
8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           pc, address, is_write, *(unsigned long *)old_set);
8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: locking issue */
8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (is_write && page_unprotect(h2g(address), pc, puc)) {
8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* see if it is an MMU fault */
8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0; /* not an MMU fault */
8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret == 0)
8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1; /* the MMU fault was handled without causing real CPU fault */
8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* now we have a real cpu fault */
8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb = tb_find_pc(pc);
8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tb) {
8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* the PC is inside the translated code. It means that we have
8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           a virtual CPU fault */
8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_restore_state(tb, env, pc, puc);
8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we restore the process signal mask as the sigreturn should
8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       do it (XXX: use sigsetjmp) */
8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sigprocmask(SIG_SETMASK, old_set, NULL);
8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_loop_exit();
8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* never comes here */
8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 1;
8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_SPARC)
8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int handle_cpu_signal(unsigned long pc, unsigned long address,
8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    int is_write, sigset_t *old_set,
8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    void *puc)
8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TranslationBlock *tb;
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cpu_single_env)
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env = cpu_single_env; /* XXX: find a correct solution for multithread */
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(DEBUG_SIGNAL)
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           pc, address, is_write, *(unsigned long *)old_set);
8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: locking issue */
8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (is_write && page_unprotect(h2g(address), pc, puc)) {
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* see if it is an MMU fault */
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0; /* not an MMU fault */
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret == 0)
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1; /* the MMU fault was handled without causing real CPU fault */
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* now we have a real cpu fault */
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb = tb_find_pc(pc);
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tb) {
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* the PC is inside the translated code. It means that we have
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           a virtual CPU fault */
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_restore_state(tb, env, pc, puc);
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we restore the process signal mask as the sigreturn should
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       do it (XXX: use sigsetjmp) */
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sigprocmask(SIG_SETMASK, old_set, NULL);
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_loop_exit();
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* never comes here */
8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 1;
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined (TARGET_PPC)
8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int handle_cpu_signal(unsigned long pc, unsigned long address,
8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    int is_write, sigset_t *old_set,
8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    void *puc)
8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TranslationBlock *tb;
8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cpu_single_env)
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env = cpu_single_env; /* XXX: find a correct solution for multithread */
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(DEBUG_SIGNAL)
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           pc, address, is_write, *(unsigned long *)old_set);
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: locking issue */
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (is_write && page_unprotect(h2g(address), pc, puc)) {
9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* see if it is an MMU fault */
9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0; /* not an MMU fault */
9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret == 0)
9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1; /* the MMU fault was handled without causing real CPU fault */
9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* now we have a real cpu fault */
9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb = tb_find_pc(pc);
9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tb) {
9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* the PC is inside the translated code. It means that we have
9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           a virtual CPU fault */
9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_restore_state(tb, env, pc, puc);
9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret == 1) {
9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("PF exception: NIP=0x%08x error=0x%x %p\n",
9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               env->nip, env->error_code, tb);
9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we restore the process signal mask as the sigreturn should
9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       do it (XXX: use sigsetjmp) */
9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sigprocmask(SIG_SETMASK, old_set, NULL);
9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        do_raise_exception_err(env->exception_index, env->error_code);
9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* activate soft MMU for this block */
9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_resume_from_signal(env, puc);
9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* never comes here */
9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 1;
9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(TARGET_M68K)
9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int handle_cpu_signal(unsigned long pc, unsigned long address,
9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    int is_write, sigset_t *old_set,
9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    void *puc)
9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TranslationBlock *tb;
9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cpu_single_env)
9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env = cpu_single_env; /* XXX: find a correct solution for multithread */
9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(DEBUG_SIGNAL)
9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           pc, address, is_write, *(unsigned long *)old_set);
9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: locking issue */
9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (is_write && page_unprotect(address, pc, puc)) {
9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* see if it is an MMU fault */
9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0; /* not an MMU fault */
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret == 0)
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1; /* the MMU fault was handled without causing real CPU fault */
9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* now we have a real cpu fault */
9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb = tb_find_pc(pc);
9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tb) {
9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* the PC is inside the translated code. It means that we have
9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           a virtual CPU fault */
9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_restore_state(tb, env, pc, puc);
9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we restore the process signal mask as the sigreturn should
9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       do it (XXX: use sigsetjmp) */
9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sigprocmask(SIG_SETMASK, old_set, NULL);
9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_loop_exit();
9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* never comes here */
9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 1;
9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined (TARGET_MIPS)
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int handle_cpu_signal(unsigned long pc, unsigned long address,
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    int is_write, sigset_t *old_set,
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    void *puc)
9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TranslationBlock *tb;
9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cpu_single_env)
9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env = cpu_single_env; /* XXX: find a correct solution for multithread */
9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(DEBUG_SIGNAL)
9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           pc, address, is_write, *(unsigned long *)old_set);
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: locking issue */
9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (is_write && page_unprotect(h2g(address), pc, puc)) {
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* see if it is an MMU fault */
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0; /* not an MMU fault */
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret == 0)
10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1; /* the MMU fault was handled without causing real CPU fault */
10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* now we have a real cpu fault */
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb = tb_find_pc(pc);
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tb) {
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* the PC is inside the translated code. It means that we have
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           a virtual CPU fault */
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_restore_state(tb, env, pc, puc);
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret == 1) {
10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n",
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               env->PC, env->error_code, tb);
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we restore the process signal mask as the sigreturn should
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       do it (XXX: use sigsetjmp) */
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sigprocmask(SIG_SETMASK, old_set, NULL);
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        do_raise_exception_err(env->exception_index, env->error_code);
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* activate soft MMU for this block */
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_resume_from_signal(env, puc);
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* never comes here */
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 1;
10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined (TARGET_SH4)
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int handle_cpu_signal(unsigned long pc, unsigned long address,
10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    int is_write, sigset_t *old_set,
10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    void *puc)
10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TranslationBlock *tb;
10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cpu_single_env)
10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env = cpu_single_env; /* XXX: find a correct solution for multithread */
10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(DEBUG_SIGNAL)
10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           pc, address, is_write, *(unsigned long *)old_set);
10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: locking issue */
10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (is_write && page_unprotect(h2g(address), pc, puc)) {
10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* see if it is an MMU fault */
10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0; /* not an MMU fault */
10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret == 0)
10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1; /* the MMU fault was handled without causing real CPU fault */
10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* now we have a real cpu fault */
10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb = tb_find_pc(pc);
10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tb) {
10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* the PC is inside the translated code. It means that we have
10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           a virtual CPU fault */
10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_restore_state(tb, env, pc, puc);
10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("PF exception: NIP=0x%08x error=0x%x %p\n",
10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               env->nip, env->error_code, tb);
10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we restore the process signal mask as the sigreturn should
10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       do it (XXX: use sigsetjmp) */
10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sigprocmask(SIG_SETMASK, old_set, NULL);
10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_loop_exit();
10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* never comes here */
10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 1;
10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined (TARGET_ALPHA)
10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int handle_cpu_signal(unsigned long pc, unsigned long address,
10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    int is_write, sigset_t *old_set,
10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    void *puc)
10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TranslationBlock *tb;
10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cpu_single_env)
10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env = cpu_single_env; /* XXX: find a correct solution for multithread */
10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(DEBUG_SIGNAL)
10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           pc, address, is_write, *(unsigned long *)old_set);
10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: locking issue */
10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (is_write && page_unprotect(h2g(address), pc, puc)) {
10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* see if it is an MMU fault */
10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0; /* not an MMU fault */
10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret == 0)
10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1; /* the MMU fault was handled without causing real CPU fault */
10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* now we have a real cpu fault */
11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb = tb_find_pc(pc);
11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tb) {
11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* the PC is inside the translated code. It means that we have
11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           a virtual CPU fault */
11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_restore_state(tb, env, pc, puc);
11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("PF exception: NIP=0x%08x error=0x%x %p\n",
11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               env->nip, env->error_code, tb);
11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we restore the process signal mask as the sigreturn should
11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       do it (XXX: use sigsetjmp) */
11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sigprocmask(SIG_SETMASK, old_set, NULL);
11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_loop_exit();
11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* never comes here */
11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 1;
11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined (TARGET_CRIS)
11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int handle_cpu_signal(unsigned long pc, unsigned long address,
11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    int is_write, sigset_t *old_set,
11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    void *puc)
11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    TranslationBlock *tb;
11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (cpu_single_env)
11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        env = cpu_single_env; /* XXX: find a correct solution for multithread */
11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(DEBUG_SIGNAL)
11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           pc, address, is_write, *(unsigned long *)old_set);
11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: locking issue */
11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (is_write && page_unprotect(h2g(address), pc, puc)) {
11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* see if it is an MMU fault */
11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0)
11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0; /* not an MMU fault */
11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret == 0)
11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1; /* the MMU fault was handled without causing real CPU fault */
11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* now we have a real cpu fault */
11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    tb = tb_find_pc(pc);
11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (tb) {
11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* the PC is inside the translated code. It means that we have
11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           a virtual CPU fault */
11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        cpu_restore_state(tb, env, pc, puc);
11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* we restore the process signal mask as the sigreturn should
11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       do it (XXX: use sigsetjmp) */
11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sigprocmask(SIG_SETMASK, old_set, NULL);
11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cpu_loop_exit();
11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* never comes here */
11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 1;
11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#error unsupported target CPU
11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(__i386__)
11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(__APPLE__)
11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# include <sys/ucontext.h>
11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define EIP_sig(context)  (*((unsigned long*)&(context)->uc_mcontext->ss.eip))
11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define TRAP_sig(context)    ((context)->uc_mcontext->es.trapno)
11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define ERROR_sig(context)   ((context)->uc_mcontext->es.err)
11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define EIP_sig(context)     ((context)->uc_mcontext.gregs[REG_EIP])
11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define TRAP_sig(context)    ((context)->uc_mcontext.gregs[REG_TRAPNO])
11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define ERROR_sig(context)   ((context)->uc_mcontext.gregs[REG_ERR])
11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_signal_handler(int host_signum, void *pinfo,
11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       void *puc)
11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    siginfo_t *info = pinfo;
11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ucontext *uc = puc;
11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long pc;
11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int trapno;
11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef REG_EIP
11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* for glibc 2.1 */
11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define REG_EIP    EIP
11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define REG_ERR    ERR
11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define REG_TRAPNO TRAPNO
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = EIP_sig(uc);
11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    trapno = TRAP_sig(uc);
11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             trapno == 0xe ?
11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             (ERROR_sig(uc) >> 1) & 1 : 0,
11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             &uc->uc_sigmask, puc);
11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__x86_64__)
11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_signal_handler(int host_signum, void *pinfo,
12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       void *puc)
12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    siginfo_t *info = pinfo;
12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ucontext *uc = puc;
12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long pc;
12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = uc->uc_mcontext.gregs[REG_RIP];
12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ?
12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,
12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             &uc->uc_sigmask, puc);
12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__powerpc__)
12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/***********************************************************************
12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * signal context platform-specific definitions
12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * From Wine
12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef linux
12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* All Registers access - only for local access */
12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define REG_sig(reg_name, context)		((context)->uc_mcontext.regs->reg_name)
12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Gpr Registers access  */
12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define GPR_sig(reg_num, context)		REG_sig(gpr[reg_num], context)
12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define IAR_sig(context)			REG_sig(nip, context)	/* Program counter */
12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define MSR_sig(context)			REG_sig(msr, context)   /* Machine State Register (Supervisor) */
12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define CTR_sig(context)			REG_sig(ctr, context)   /* Count register */
12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define XER_sig(context)			REG_sig(xer, context) /* User's integer exception register */
12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define LR_sig(context)			REG_sig(link, context) /* Link register */
12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define CR_sig(context)			REG_sig(ccr, context) /* Condition register */
12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Float Registers access  */
12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define FLOAT_sig(reg_num, context)		(((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num])
12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define FPSCR_sig(context)			(*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4)))
12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Exception Registers access */
12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define DAR_sig(context)			REG_sig(dar, context)
12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define DSISR_sig(context)			REG_sig(dsisr, context)
12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define TRAP_sig(context)			REG_sig(trap, context)
12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* linux */
12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef __APPLE__
12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# include <sys/ucontext.h>
12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct ucontext SIGCONTEXT;
12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* All Registers access - only for local access */
12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define REG_sig(reg_name, context)		((context)->uc_mcontext->ss.reg_name)
12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define FLOATREG_sig(reg_name, context)	((context)->uc_mcontext->fs.reg_name)
12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define EXCEPREG_sig(reg_name, context)	((context)->uc_mcontext->es.reg_name)
12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define VECREG_sig(reg_name, context)		((context)->uc_mcontext->vs.reg_name)
12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Gpr Registers access */
12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define GPR_sig(reg_num, context)		REG_sig(r##reg_num, context)
12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define IAR_sig(context)			REG_sig(srr0, context)	/* Program counter */
12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define MSR_sig(context)			REG_sig(srr1, context)  /* Machine State Register (Supervisor) */
12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define CTR_sig(context)			REG_sig(ctr, context)
12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define XER_sig(context)			REG_sig(xer, context) /* Link register */
12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define LR_sig(context)			REG_sig(lr, context)  /* User's integer exception register */
12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define CR_sig(context)			REG_sig(cr, context)  /* Condition register */
12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Float Registers access */
12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define FLOAT_sig(reg_num, context)		FLOATREG_sig(fpregs[reg_num], context)
12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define FPSCR_sig(context)			((double)FLOATREG_sig(fpscr, context))
12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Exception Registers access */
12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define DAR_sig(context)			EXCEPREG_sig(dar, context)     /* Fault registers for coredump */
12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define DSISR_sig(context)			EXCEPREG_sig(dsisr, context)
12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define TRAP_sig(context)			EXCEPREG_sig(exception, context) /* number of powerpc exception taken */
12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* __APPLE__ */
12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_signal_handler(int host_signum, void *pinfo,
12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       void *puc)
12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    siginfo_t *info = pinfo;
12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ucontext *uc = puc;
12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long pc;
12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int is_write;
12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = IAR_sig(uc);
12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    is_write = 0;
12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* ppc 4xx case */
12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (DSISR_sig(uc) & 0x00800000)
12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        is_write = 1;
12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000))
12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        is_write = 1;
12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             is_write, &uc->uc_sigmask, puc);
12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__alpha__)
12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_signal_handler(int host_signum, void *pinfo,
12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                           void *puc)
12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    siginfo_t *info = pinfo;
12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ucontext *uc = puc;
12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t *pc = uc->uc_mcontext.sc_pc;
12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t insn = *pc;
12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int is_write = 0;
12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: need kernel patch to get write flag faster */
12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (insn >> 26) {
13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0x0d: // stw
13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0x0e: // stb
13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0x0f: // stq_u
13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0x24: // stf
13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0x25: // stg
13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0x26: // sts
13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0x27: // stt
13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0x2c: // stl
13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0x2d: // stq
13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0x2e: // stl_c
13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 0x2f: // stq_c
13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	is_write = 1;
13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             is_write, &uc->uc_sigmask, puc);
13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__sparc__)
13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_signal_handler(int host_signum, void *pinfo,
13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       void *puc)
13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    siginfo_t *info = pinfo;
13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int is_write;
13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t insn;
13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(__arch64__) || defined(HOST_SOLARIS)
13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint32_t *regs = (uint32_t *)(info + 1);
13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    void *sigmask = (regs + 20);
13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: is there a standard glibc define ? */
13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long pc = regs[1];
13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct sigcontext *sc = puc;
13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long pc = sc->sigc_regs.tpc;
13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    void *sigmask = (void *)sc->sigc_mask;
13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: need kernel patch to get write flag faster */
13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    is_write = 0;
13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    insn = *(uint32_t *)pc;
13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((insn >> 30) == 3) {
13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      switch((insn >> 19) & 0x3f) {
13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case 0x05: // stb
13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case 0x06: // sth
13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case 0x04: // st
13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case 0x07: // std
13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case 0x24: // stf
13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case 0x27: // stdf
13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case 0x25: // stfsr
13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	is_write = 1;
13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	break;
13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             is_write, sigmask, NULL);
13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__arm__)
13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_signal_handler(int host_signum, void *pinfo,
13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       void *puc)
13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    siginfo_t *info = pinfo;
13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ucontext *uc = puc;
13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long pc;
13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int is_write;
13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = uc->uc_mcontext.gregs[R15];
13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = uc->uc_mcontext.arm_pc;
13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: compute is_write */
13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    is_write = 0;
13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             is_write,
13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             &uc->uc_sigmask, puc);
13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__mc68000)
13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_signal_handler(int host_signum, void *pinfo,
13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       void *puc)
13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    siginfo_t *info = pinfo;
13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ucontext *uc = puc;
13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long pc;
13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int is_write;
13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = uc->uc_mcontext.gregs[16];
13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: compute is_write */
13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    is_write = 0;
13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             is_write,
13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             &uc->uc_sigmask, puc);
13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__ia64)
13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef __ISR_VALID
13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  /* This ought to be in <bits/siginfo.h>... */
14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# define __ISR_VALID	1
14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_signal_handler(int host_signum, void *pinfo, void *puc)
14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    siginfo_t *info = pinfo;
14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ucontext *uc = puc;
14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long ip;
14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int is_write = 0;
14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ip = uc->uc_mcontext.sc_ip;
14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (host_signum) {
14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case SIGILL:
14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case SIGFPE:
14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case SIGSEGV:
14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case SIGBUS:
14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case SIGTRAP:
14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	  if (info->si_code && (info->si_segvflags & __ISR_VALID))
14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	      /* ISR.W (write-access) is bit 33:  */
14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	      is_write = (info->si_isr >> 33) & 1;
14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	  break;
14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      default:
14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	  break;
14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return handle_cpu_signal(ip, (unsigned long)info->si_addr,
14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             is_write,
14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             &uc->uc_sigmask, puc);
14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__s390__)
14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_signal_handler(int host_signum, void *pinfo,
14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       void *puc)
14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    siginfo_t *info = pinfo;
14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ucontext *uc = puc;
14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long pc;
14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int is_write;
14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = uc->uc_mcontext.psw.addr;
14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: compute is_write */
14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    is_write = 0;
14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             is_write, &uc->uc_sigmask, puc);
14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__mips__)
14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_signal_handler(int host_signum, void *pinfo,
14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       void *puc)
14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    siginfo_t *info = pinfo;
14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ucontext *uc = puc;
14548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    greg_t pc = uc->uc_mcontext.pc;
14558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int is_write;
14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* XXX: compute is_write */
14588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    is_write = 0;
14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
14608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             is_write, &uc->uc_sigmask, puc);
14618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined(__hppa__)
14648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint cpu_signal_handler(int host_signum, void *pinfo,
14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       void *puc)
14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct siginfo *info = pinfo;
14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct ucontext *uc = puc;
14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long pc;
14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int is_write;
14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pc = uc->uc_mcontext.sc_iaoq[0];
14748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* FIXME: compute is_write */
14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    is_write = 0;
14768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             is_write,
14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             &uc->uc_sigmask, puc);
14798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#error host CPU specific signal handler needed
14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* !defined(CONFIG_SOFTMMU) */
1488