cpu-exec.c revision 8d3f9624838fe3f51aa71276ada9759b407a0ad3
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * i386 emulator main execution loop
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * Copyright (c) 2003-2005 Fabrice Bellard
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * This library is free software; you can redistribute it and/or
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * modify it under the terms of the GNU Lesser General Public
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * License as published by the Free Software Foundation; either
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * version 2 of the License, or (at your option) any later version.
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * This library is distributed in the hope that it will be useful,
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * but WITHOUT ANY WARRANTY; without even the implied warranty of
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * Lesser General Public License for more details.
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * You should have received a copy of the GNU Lesser General Public
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * License along with this library; if not, write to the Free Software
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * Sun LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * other than GPL or LGPL is available it will apply instead, Sun elects to use only
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * a choice of LGPL license versions is made available with the language indicating
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * that LGPLv2 or any later version may be used, or where a choice of which version
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely * of the LGPL is applied is otherwise unspecified.
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely// Work around ugly bugs in glibc that mangle global register contents
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely//#define DEBUG_EXEC
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely//#define DEBUG_SIGNAL
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely /* NOTE: the register at this point must be saved by hand because
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely longjmp restore them */
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely#if !(defined(TARGET_SPARC) || defined(TARGET_SH4) || defined(TARGET_M68K))
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely/* exit the current TB from a signal handler. The host registers are
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidely restored in a state compatible with the CPU emulator
24d6db06810f2ea747f6dff60d483e4fca3aaa13davidelyvoid cpu_resume_from_signal(CPUState *env1, void *puc)
#if !defined(CONFIG_SOFTMMU)
#if !defined(CONFIG_SOFTMMU)
if (puc) {
unsigned long next_tb;
tb_invalidated_flag = 0;
if (!tb)
goto not_found;
goto found;
goto found;
return tb;
#ifndef VBOX
#if defined(TARGET_I386)
cs_base = 0;
#ifdef TARGET_SPARC64
cs_base = 0;
cs_base = 0;
cs_base = 0;
cs_base = 0;
cs_base = 0;
cs_base = 0;
return tb;
#ifdef VBOX
#include "hostregs_helper.h"
unsigned long next_tb;
#include "hostregs_helper.h"
env_to_regs();
#if defined(TARGET_I386)
Log(("do_interrupt %d %d %RGv\n", env->exception_index, env->exception_is_int, env->exception_next_eip));
#ifndef VBOX
do_smm_enter();
next_tb = 0;
int intno;
if (intno >= 0)
next_tb = 0;
next_tb = 0;
if (tb_invalidated_flag) {
next_tb = 0;
tb_invalidated_flag = 0;
if (next_tb != 0
int insns_left;
if (insns_left > 0) {
next_tb = 0;
next_tb = 0;
env_to_regs();
#ifdef VBOX_HIGH_RES_TIMERS_HACK
#if defined(TARGET_I386)
#include "hostregs_helper.h"
return ret;
#include "hostregs_helper.h"
unsigned long next_tb;
return EXCP_HALTED;
#include "hostregs_helper.h"
env_to_regs();
#if defined(TARGET_I386)
#if defined(TARGET_I386)
#if defined(TARGET_I386)
do_interrupt(0);
#ifdef USE_KQEMU
int ret;
#if defined(TARGET_I386)
do_smm_enter();
next_tb = 0;
next_tb = 0;
int intno;
next_tb = 0;
#if !defined(CONFIG_USER_ONLY)
int intno;
next_tb = 0;
next_tb = 0;
next_tb = 0;
next_tb = 0;
next_tb = 0;
next_tb = 0;
next_tb = 0;
next_tb = 0;
next_tb = 0;
next_tb = 0;
next_tb = 0;
next_tb = 0;
#ifdef DEBUG_EXEC
regs_to_env();
#if defined(TARGET_I386)
if (tb_invalidated_flag) {
next_tb = 0;
tb_invalidated_flag = 0;
#ifdef DEBUG_EXEC
if (next_tb != 0 &&
#ifdef USE_KQEMU
int insns_left;
if (insns_left > 0) {
next_tb = 0;
#if defined(USE_KQEMU)
env_to_regs();
#if defined(TARGET_I386)
#include "hostregs_helper.h"
return ret;
env = s;
env = s;
env = s;
#if !defined(CONFIG_SOFTMMU)
#if defined(TARGET_I386)
void *puc)
int ret;
if (cpu_single_env)
#if defined(DEBUG_SIGNAL)
if (ret < 0)
if (ret == 0)
if (tb) {
void *puc)
int ret;
if (cpu_single_env)
#if defined(DEBUG_SIGNAL)
if (ret < 0)
if (ret == 0)
if (tb) {
void *puc)
int ret;
if (cpu_single_env)
#if defined(DEBUG_SIGNAL)
if (ret < 0)
if (ret == 0)
if (tb) {
void *puc)
int ret;
if (cpu_single_env)
#if defined(DEBUG_SIGNAL)
if (ret < 0)
if (ret == 0)
if (tb) {
void *puc)
int ret;
if (cpu_single_env)
#if defined(DEBUG_SIGNAL)
if (ret < 0)
if (ret == 0)
if (tb) {
void *puc)
int ret;
if (cpu_single_env)
#if defined(DEBUG_SIGNAL)
if (ret < 0)
if (ret == 0)
if (tb) {
void *puc)
int ret;
if (cpu_single_env)
#if defined(DEBUG_SIGNAL)
if (ret < 0)
if (ret == 0)
if (tb) {
#if defined(__i386__)
#if defined(__APPLE__)
void *puc)
unsigned long pc;
int trapno;
#ifndef REG_EIP
void *puc)
unsigned long pc;
#ifdef linux
# define FLOAT_sig(reg_num, context) (((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num])
#ifdef __APPLE__
void *puc)
unsigned long pc;
int is_write;
is_write = 0;
void *puc)
int is_write = 0;
void *puc)
unsigned long pc;
int is_write;
is_write = 0;
void *puc)
unsigned long pc;
int is_write;
is_write = 0;
void *puc)
unsigned long pc;
int is_write;
is_write = 0;
#ifndef __ISR_VALID
unsigned long ip;
int is_write = 0;
switch (host_signum) {
case SIGILL:
case SIGFPE:
case SIGSEGV:
case SIGBUS:
case SIGTRAP:
void *puc)
unsigned long pc;
int is_write;
is_write = 0;