aboutsummaryrefslogtreecommitdiff
path: root/target-i386
diff options
context:
space:
mode:
authorBlue Swirl <blauwirbel@gmail.com>2011-07-13 12:44:15 +0000
committerBlue Swirl <blauwirbel@gmail.com>2011-07-30 09:41:14 +0000
commit3e4571724fb92c77de81d8b54957de8232be6706 (patch)
tree22ed3dd4f120e05ecef8e946fe79ea8b8b27c72c /target-i386
parent104bf02eb50e080ac9d0de5905f80f9a09730154 (diff)
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.h3
-rw-r--r--target-i386/exec.h142
-rw-r--r--target-i386/helper.c2
-rw-r--r--target-i386/op_helper.c165
4 files changed, 164 insertions, 148 deletions
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 9819b5fdb9..dd6c5fab3b 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 dd9bce4eed..0000000000
--- 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 e9be104293..182009a4c2 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 315e18b9a4..138093454d 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;