diff options
author | Blue Swirl <blauwirbel@gmail.com> | 2011-07-13 12:44:15 +0000 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2011-07-30 09:41:14 +0000 |
commit | 3e4571724fb92c77de81d8b54957de8232be6706 (patch) | |
tree | 22ed3dd4f120e05ecef8e946fe79ea8b8b27c72c /target-i386 | |
parent | 104bf02eb50e080ac9d0de5905f80f9a09730154 (diff) | |
download | qemu-3e4571724fb92c77de81d8b54957de8232be6706.zip qemu-3e4571724fb92c77de81d8b54957de8232be6706.tar.gz qemu-3e4571724fb92c77de81d8b54957de8232be6706.tar.bz2 |
exec.h cleanup
Move softmmu_exec.h include directives from target-*/exec.h to
target-*/op_helper.c. Move also various other stuff only used in
op_helper.c there.
Define global env in dyngen-exec.h.
For i386, move wrappers for segment and FPU helpers from user-exec.c
to op_helper.c. Implement raise_exception_err_env() to handle dynamic
CPUState. Move the function declarations to cpu.h since they can be
used outside of op_helper.c context.
LM32, s390x, UniCore32: remove unused cpu_halted(), regs_to_env() and
env_to_regs().
ARM: make raise_exception() static.
Convert
#include "exec.h"
to
#include "cpu.h"
#include "dyngen-exec.h"
and remove now unused target-*/exec.h.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-i386')
-rw-r--r-- | target-i386/cpu.h | 3 | ||||
-rw-r--r-- | target-i386/exec.h | 142 | ||||
-rw-r--r-- | target-i386/helper.c | 2 | ||||
-rw-r--r-- | target-i386/op_helper.c | 165 |
4 files changed, 164 insertions, 148 deletions
diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 9819b5f..dd6c5fa 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -1050,6 +1050,9 @@ void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank, /* op_helper.c */ void do_interrupt(CPUState *env); void do_interrupt_x86_hardirq(CPUState *env, int intno, int is_hw); +void QEMU_NORETURN raise_exception_env(int exception_index, CPUState *nenv); +void QEMU_NORETURN raise_exception_err_env(CPUState *nenv, int exception_index, + int error_code); void do_smm_enter(CPUState *env1); diff --git a/target-i386/exec.h b/target-i386/exec.h deleted file mode 100644 index dd9bce4..0000000 --- a/target-i386/exec.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * i386 execution defines - * - * Copyright (c) 2003 Fabrice Bellard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ -#include "config.h" -#include "dyngen-exec.h" - -/* XXX: factorize this mess */ -#ifdef TARGET_X86_64 -#define TARGET_LONG_BITS 64 -#else -#define TARGET_LONG_BITS 32 -#endif - -#include "cpu-defs.h" - -register struct CPUX86State *env asm(AREG0); - -#include "qemu-common.h" -#include "qemu-log.h" - -#include "cpu.h" - -/* op_helper.c */ -void QEMU_NORETURN raise_exception_err(int exception_index, int error_code); -void QEMU_NORETURN raise_exception(int exception_index); -void QEMU_NORETURN raise_exception_env(int exception_index, CPUState *nenv); - -/* n must be a constant to be efficient */ -static inline target_long lshift(target_long x, int n) -{ - if (n >= 0) - return x << n; - else - return x >> (-n); -} - -#include "helper.h" - -#if !defined(CONFIG_USER_ONLY) - -#include "softmmu_exec.h" - -#endif /* !defined(CONFIG_USER_ONLY) */ - -#define RC_MASK 0xc00 -#define RC_NEAR 0x000 -#define RC_DOWN 0x400 -#define RC_UP 0x800 -#define RC_CHOP 0xc00 - -#define MAXTAN 9223372036854775808.0 - -/* the following deal with x86 long double-precision numbers */ -#define MAXEXPD 0x7fff -#define EXPBIAS 16383 -#define EXPD(fp) (fp.l.upper & 0x7fff) -#define SIGND(fp) ((fp.l.upper) & 0x8000) -#define MANTD(fp) (fp.l.lower) -#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS - -static inline void fpush(void) -{ - env->fpstt = (env->fpstt - 1) & 7; - env->fptags[env->fpstt] = 0; /* validate stack entry */ -} - -static inline void fpop(void) -{ - env->fptags[env->fpstt] = 1; /* invvalidate stack entry */ - env->fpstt = (env->fpstt + 1) & 7; -} - -static inline floatx80 helper_fldt(target_ulong ptr) -{ - CPU_LDoubleU temp; - - temp.l.lower = ldq(ptr); - temp.l.upper = lduw(ptr + 8); - return temp.d; -} - -static inline void helper_fstt(floatx80 f, target_ulong ptr) -{ - CPU_LDoubleU temp; - - temp.d = f; - stq(ptr, temp.l.lower); - stw(ptr + 8, temp.l.upper); -} - -#define FPUS_IE (1 << 0) -#define FPUS_DE (1 << 1) -#define FPUS_ZE (1 << 2) -#define FPUS_OE (1 << 3) -#define FPUS_UE (1 << 4) -#define FPUS_PE (1 << 5) -#define FPUS_SF (1 << 6) -#define FPUS_SE (1 << 7) -#define FPUS_B (1 << 15) - -#define FPUC_EM 0x3f - -static inline uint32_t compute_eflags(void) -{ - return env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK); -} - -/* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */ -static inline void load_eflags(int eflags, int update_mask) -{ - CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); - DF = 1 - (2 * ((eflags >> 10) & 1)); - env->eflags = (env->eflags & ~update_mask) | - (eflags & update_mask) | 0x2; -} - -/* load efer and update the corresponding hflags. XXX: do consistency - checks with cpuid bits ? */ -static inline void cpu_load_efer(CPUState *env, uint64_t val) -{ - env->efer = val; - env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK); - if (env->efer & MSR_EFER_LMA) - env->hflags |= HF_LMA_MASK; - if (env->efer & MSR_EFER_SVME) - env->hflags |= HF_SVME_MASK; -} diff --git a/target-i386/helper.c b/target-i386/helper.c index e9be104..182009a 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1027,8 +1027,6 @@ int check_hw_breakpoints(CPUState *env, int force_dr6_update) static CPUDebugExcpHandler *prev_debug_excp_handler; -void raise_exception_env(int exception_index, CPUState *env); - static void breakpoint_handler(CPUState *env) { CPUBreakpoint *bp; diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c index 315e18b..1380934 100644 --- a/target-i386/op_helper.c +++ b/target-i386/op_helper.c @@ -18,12 +18,20 @@ */ #include <math.h> -#include "exec.h" +#include "cpu.h" +#include "dyngen-exec.h" #include "host-utils.h" #include "ioport.h" +#include "qemu-common.h" +#include "qemu-log.h" +#include "cpu-defs.h" +#include "helper.h" -//#define DEBUG_PCALL +#if !defined(CONFIG_USER_ONLY) +#include "softmmu_exec.h" +#endif /* !defined(CONFIG_USER_ONLY) */ +//#define DEBUG_PCALL #ifdef DEBUG_PCALL # define LOG_PCALL(...) qemu_log_mask(CPU_LOG_PCALL, ## __VA_ARGS__) @@ -34,6 +42,101 @@ # define LOG_PCALL_STATE(env) do { } while (0) #endif +/* n must be a constant to be efficient */ +static inline target_long lshift(target_long x, int n) +{ + if (n >= 0) { + return x << n; + } else { + return x >> (-n); + } +} + +#define RC_MASK 0xc00 +#define RC_NEAR 0x000 +#define RC_DOWN 0x400 +#define RC_UP 0x800 +#define RC_CHOP 0xc00 + +#define MAXTAN 9223372036854775808.0 + +/* the following deal with x86 long double-precision numbers */ +#define MAXEXPD 0x7fff +#define EXPBIAS 16383 +#define EXPD(fp) (fp.l.upper & 0x7fff) +#define SIGND(fp) ((fp.l.upper) & 0x8000) +#define MANTD(fp) (fp.l.lower) +#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS + +static inline void fpush(void) +{ + env->fpstt = (env->fpstt - 1) & 7; + env->fptags[env->fpstt] = 0; /* validate stack entry */ +} + +static inline void fpop(void) +{ + env->fptags[env->fpstt] = 1; /* invvalidate stack entry */ + env->fpstt = (env->fpstt + 1) & 7; +} + +static inline floatx80 helper_fldt(target_ulong ptr) +{ + CPU_LDoubleU temp; + + temp.l.lower = ldq(ptr); + temp.l.upper = lduw(ptr + 8); + return temp.d; +} + +static inline void helper_fstt(floatx80 f, target_ulong ptr) +{ + CPU_LDoubleU temp; + + temp.d = f; + stq(ptr, temp.l.lower); + stw(ptr + 8, temp.l.upper); +} + +#define FPUS_IE (1 << 0) +#define FPUS_DE (1 << 1) +#define FPUS_ZE (1 << 2) +#define FPUS_OE (1 << 3) +#define FPUS_UE (1 << 4) +#define FPUS_PE (1 << 5) +#define FPUS_SF (1 << 6) +#define FPUS_SE (1 << 7) +#define FPUS_B (1 << 15) + +#define FPUC_EM 0x3f + +static inline uint32_t compute_eflags(void) +{ + return env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK); +} + +/* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */ +static inline void load_eflags(int eflags, int update_mask) +{ + CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); + DF = 1 - (2 * ((eflags >> 10) & 1)); + env->eflags = (env->eflags & ~update_mask) | + (eflags & update_mask) | 0x2; +} + +/* load efer and update the corresponding hflags. XXX: do consistency + checks with cpuid bits ? */ +static inline void cpu_load_efer(CPUState *env, uint64_t val) +{ + env->efer = val; + env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK); + if (env->efer & MSR_EFER_LMA) { + env->hflags |= HF_LMA_MASK; + } + if (env->efer & MSR_EFER_SVME) { + env->hflags |= HF_SVME_MASK; + } +} #if 0 #define raise_exception_err(a, b)\ @@ -43,6 +146,9 @@ do {\ } while (0) #endif +static void QEMU_NORETURN raise_exception_err(int exception_index, + int error_code); + static const uint8_t parity_table[256] = { CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0, 0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P, @@ -1381,12 +1487,20 @@ static void QEMU_NORETURN raise_interrupt(int intno, int is_int, int error_code, /* shortcuts to generate exceptions */ -void raise_exception_err(int exception_index, int error_code) +static void QEMU_NORETURN raise_exception_err(int exception_index, + int error_code) +{ + raise_interrupt(exception_index, 0, error_code, 0); +} + +void raise_exception_err_env(CPUState *nenv, int exception_index, + int error_code) { + env = nenv; raise_interrupt(exception_index, 0, error_code, 0); } -void raise_exception(int exception_index) +static void QEMU_NORETURN raise_exception(int exception_index) { raise_interrupt(exception_index, 0, 0, 0); } @@ -4426,6 +4540,49 @@ void helper_frstor(target_ulong ptr, int data32) } } + +#if defined(CONFIG_USER_ONLY) +void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector) +{ + CPUX86State *saved_env; + + saved_env = env; + env = s; + if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) { + selector &= 0xffff; + cpu_x86_load_seg_cache(env, seg_reg, selector, + (selector << 4), 0xffff, 0); + } else { + helper_load_seg(seg_reg, selector); + } + env = saved_env; +} + +void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32) +{ + CPUX86State *saved_env; + + saved_env = env; + env = s; + + helper_fsave(ptr, data32); + + env = saved_env; +} + +void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32) +{ + CPUX86State *saved_env; + + saved_env = env; + env = s; + + helper_frstor(ptr, data32); + + env = saved_env; +} +#endif + void helper_fxsave(target_ulong ptr, int data64) { int fpus, fptag, i, nb_xmm_regs; |