exec.h revision d65680efa46fa49e8bf14e67b29b782510ff934c
/*
* i386 execution defines
*
* Copyright (c) 2003 Fabrice Bellard
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Sun LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
* other than GPL or LGPL is available it will apply instead, Sun elects to use only
* the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
* a choice of LGPL license versions is made available with the language indicating
* that LGPLv2 or any later version may be used, or where a choice of which version
* of the LGPL is applied is otherwise unspecified.
*/
#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"
/* at least 4 register variables are defined */
/* no registers can be used */
#else
/* XXX: use unsigned long instead of target_ulong - better code will
be generated for 64 bit CPUs */
/* if more registers are available, we define some registers too */
#ifdef AREG4
#define reg_EAX
#endif
#ifdef AREG5
#define reg_ESP
#endif
#ifdef AREG6
#define reg_EBP
#endif
#ifdef AREG7
#define reg_ECX
#endif
#ifdef AREG8
#define reg_EDX
#endif
#ifdef AREG9
#define reg_EBX
#endif
#ifdef AREG10
#define reg_ESI
#endif
#ifdef AREG11
#define reg_EDI
#endif
#endif /* ! (TARGET_LONG_BITS > HOST_LONG_BITS) */
extern int loglevel;
#ifndef reg_EAX
#endif
#ifndef reg_ECX
#endif
#ifndef reg_EDX
#endif
#ifndef reg_EBX
#endif
#ifndef reg_ESP
#endif
#ifndef reg_EBP
#endif
#ifndef reg_ESI
#endif
#ifndef reg_EDI
#endif
/* float macros */
#ifdef USE_FP_CONVERT
#endif
#include "cpu.h"
#include "exec-all.h"
typedef struct CCTable {
int (*compute_all)(void); /* return all the flags */
int (*compute_c)(void); /* return the C flag */
} CCTable;
void helper_ljmp_protected_T0_T1(int next_eip);
void helper_iret_real(int shift);
void helper_lldt_T0(void);
void helper_ltr_T0(void);
void helper_movl_crN_T0(int reg);
void helper_movl_drN_T0(int reg);
void *retaddr);
void __hidden cpu_unlock(void);
int next_eip_addend);
void raise_exception(int exception_index);
void do_smm_enter(void);
void __hidden cpu_loop_exit(void);
void OPPROTO op_movl_eflags_T0(void);
void OPPROTO op_movl_T0_eflags(void);
#ifdef VBOX
void OPPROTO op_movl_T0_eflags_vme(void);
void OPPROTO op_movw_eflags_T0_vme(void);
void OPPROTO op_cli_vme(void);
void OPPROTO op_sti_vme(void);
#endif
void helper_divl_EAX_T0(void);
void helper_idivl_EAX_T0(void);
void helper_mulq_EAX_T0(void);
void helper_imulq_EAX_T0(void);
void helper_imulq_T0_T1(void);
void helper_divq_EAX_T0(void);
void helper_idivq_EAX_T0(void);
void helper_bswapq_T0(void);
void helper_cmpxchg8b(void);
void helper_single_step(void);
void helper_cpuid(void);
void helper_sysenter(void);
void helper_sysexit(void);
void helper_syscall(int next_eip_addend);
void helper_sysret(int dflag);
void helper_rdtsc(void);
void helper_rdmsr(void);
void helper_wrmsr(void);
void helper_lsl(void);
void helper_lar(void);
void helper_verr(void);
void helper_verw(void);
void helper_rsm(void);
#ifdef VBOX
void helper_external_event(void);
void helper_record_call(void);
/* in helper.c */
#endif
void check_iob_T0(void);
void check_iow_T0(void);
void check_iol_T0(void);
void check_iob_DX(void);
void check_iow_DX(void);
void check_iol_DX(void);
#if !defined(CONFIG_USER_ONLY)
#include "softmmu_exec.h"
{
union {
double d;
uint64_t i;
} u;
return u.d;
}
{
union {
double d;
uint64_t i;
} u;
u.d = v;
}
{
union {
float f;
uint32_t i;
} u;
return u.f;
}
{
union {
float f;
uint32_t i;
} u;
u.f = v;
}
#endif /* !defined(CONFIG_USER_ONLY) */
#ifdef USE_X86LDOUBLE
/* use long double functions */
#define floatx_to_int32 floatx80_to_int32
#define floatx_to_int64 floatx80_to_int64
#define floatx_abs floatx80_abs
#define floatx_chs floatx80_chs
#define floatx_compare floatx80_compare
#ifdef VBOX
#endif /* !VBOX */
#else
#define floatx_to_int32 float64_to_int32
#define floatx_to_int64 float64_to_int64
#define floatx_abs float64_abs
#define floatx_chs float64_chs
#define floatx_compare float64_compare
#endif
#define RC_MASK 0xc00
#define RC_NEAR 0x000
#define RC_DOWN 0x400
#define RC_UP 0x800
#define RC_CHOP 0xc00
#define MAXTAN 9223372036854775808.0
#ifdef USE_X86LDOUBLE
/* only for x86 */
typedef union {
long double d;
struct {
unsigned long long lower;
unsigned short upper;
} l;
/* the following deal with x86 long double-precision numbers */
#define MAXEXPD 0x7fff
#define EXPBIAS 16383
#else
/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */
typedef union {
double d;
#if !defined(WORDS_BIGENDIAN) && !defined(__arm__)
struct {
} l;
#else
struct {
} l;
#endif
#ifndef __arm__
#endif
/* the following deal with IEEE double-precision numbers */
#define MAXEXPD 0x7ff
#define EXPBIAS 1023
#ifdef __arm__
#else
#endif
#endif
static inline void fpush(void)
{
}
static inline void fpop(void)
{
}
#ifndef USE_X86LDOUBLE
{
int upper, e;
/* mantissa */
/* XXX: handle overflow ? */
#ifdef __arm__
#else
#endif
return temp.d;
}
{
int e;
temp.d = f;
/* mantissa */
/* exponent + sign */
}
#else
/* XXX: same endianness assumed */
#ifdef CONFIG_USER_ONLY
{
return *(CPU86_LDouble *)ptr;
}
{
*(CPU86_LDouble *)ptr = f;
}
#else
/* we use memory access macros */
{
return temp.d;
}
{
temp.d = f;
}
#endif /* !CONFIG_USER_ONLY */
#endif /* USE_X86LDOUBLE */
#define FPUS_IE (1 << 0)
#define FPUC_EM 0x3f
void helper_fldt_ST0_A0(void);
void helper_fstt_ST0_A0(void);
void fpu_raise_exception(void);
void helper_fbld_ST0_A0(void);
void helper_fbst_ST0_A0(void);
void helper_f2xm1(void);
void helper_fyl2x(void);
void helper_fptan(void);
void helper_fpatan(void);
void helper_fxtract(void);
void helper_fprem1(void);
void helper_fprem(void);
void helper_fyl2xp1(void);
void helper_fsqrt(void);
void helper_fsincos(void);
void helper_frndint(void);
void helper_fscale(void);
void helper_fsin(void);
void helper_fcos(void);
void helper_fxam_ST0(void);
float approx_rsqrt(float a);
float approx_rcp(float a);
void update_fp_status(void);
void helper_hlt(void);
void helper_monitor(void);
void helper_mwait(void);
static inline uint32_t compute_eflags(void)
{
}
/* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */
{
(eflags & update_mask);
}
static inline void env_to_regs(void)
{
#ifdef reg_EAX
#endif
#ifdef reg_ECX
#endif
#ifdef reg_EDX
#endif
#ifdef reg_EBX
#endif
#ifdef reg_ESP
#endif
#ifdef reg_EBP
#endif
#ifdef reg_ESI
#endif
#ifdef reg_EDI
#endif
}
static inline void regs_to_env(void)
{
#ifdef reg_EAX
#endif
#ifdef reg_ECX
#endif
#ifdef reg_EDX
#endif
#ifdef reg_EBX
#endif
#ifdef reg_ESP
#endif
#ifdef reg_EBP
#endif
#ifdef reg_ESI
#endif
#ifdef reg_EDI
#endif
}