X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=target-i386%2Fexec.h;h=4ff527f8414e1c63de56c93557aaaf31a28ba5ab;hb=68cae3d8c10f914296dfc52cebe214264031df7d;hp=f6c717eedbc8011836bb027a3a418d981b5418e2;hpb=4136f33c7e3c034b17bb0032fa5d4297ae2f317a;p=qemu diff --git a/target-i386/exec.h b/target-i386/exec.h index f6c717e..4ff527f 100644 --- a/target-i386/exec.h +++ b/target-i386/exec.h @@ -17,57 +17,81 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "config.h" #include "dyngen-exec.h" -/* at least 4 register variables are defines */ +/* 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 */ register struct CPUX86State *env asm(AREG0); -register uint32_t T0 asm(AREG1); -register uint32_t T1 asm(AREG2); -register uint32_t T2 asm(AREG3); -#define A0 T2 +#if TARGET_LONG_BITS > HOST_LONG_BITS + +/* no registers can be used */ +#define T0 (env->t0) +#define T1 (env->t1) +#define T2 (env->t2) + +#else + +/* XXX: use unsigned long instead of target_ulong - better code will + be generated for 64 bit CPUs */ +register target_ulong T0 asm(AREG1); +register target_ulong T1 asm(AREG2); +register target_ulong T2 asm(AREG3); /* if more registers are available, we define some registers too */ #ifdef AREG4 -register uint32_t EAX asm(AREG4); +register target_ulong EAX asm(AREG4); #define reg_EAX #endif #ifdef AREG5 -register uint32_t ESP asm(AREG5); +register target_ulong ESP asm(AREG5); #define reg_ESP #endif #ifdef AREG6 -register uint32_t EBP asm(AREG6); +register target_ulong EBP asm(AREG6); #define reg_EBP #endif #ifdef AREG7 -register uint32_t ECX asm(AREG7); +register target_ulong ECX asm(AREG7); #define reg_ECX #endif #ifdef AREG8 -register uint32_t EDX asm(AREG8); +register target_ulong EDX asm(AREG8); #define reg_EDX #endif #ifdef AREG9 -register uint32_t EBX asm(AREG9); +register target_ulong EBX asm(AREG9); #define reg_EBX #endif #ifdef AREG10 -register uint32_t ESI asm(AREG10); +register target_ulong ESI asm(AREG10); #define reg_ESI #endif #ifdef AREG11 -register uint32_t EDI asm(AREG11); +register target_ulong EDI asm(AREG11); #define reg_EDI #endif +#endif /* ! (TARGET_LONG_BITS > HOST_LONG_BITS) */ + +#define A0 T2 + extern FILE *logfile; extern int loglevel; @@ -104,8 +128,8 @@ extern int loglevel; /* float macros */ #define FT0 (env->ft0) -#define ST0 (env->fpregs[env->fpstt]) -#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7]) +#define ST0 (env->fpregs[env->fpstt].d) +#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d) #define ST1 ST(1) #ifdef USE_FP_CONVERT @@ -122,49 +146,56 @@ typedef struct CCTable { extern CCTable cc_table[]; -void load_seg(int seg_reg, int selector, unsigned cur_eip); -void helper_ljmp_protected_T0_T1(void); +void load_seg(int seg_reg, int selector); +void helper_ljmp_protected_T0_T1(int next_eip); void helper_lcall_real_T0_T1(int shift, int next_eip); void helper_lcall_protected_T0_T1(int shift, int next_eip); void helper_iret_real(int shift); -void helper_iret_protected(int shift); +void helper_iret_protected(int shift, int next_eip); void helper_lret_protected(int shift, int addend); 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 helper_invlpg(unsigned int addr); -void cpu_x86_update_cr0(CPUX86State *env); -void cpu_x86_update_cr3(CPUX86State *env); -void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr); -int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, +void helper_invlpg(target_ulong addr); +void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0); +void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3); +void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4); +void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr); +int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, int is_write, int is_user, int is_softmmu); -void tlb_fill(unsigned long addr, int is_write, int is_user, +void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr); void __hidden cpu_lock(void); void __hidden cpu_unlock(void); void do_interrupt(int intno, int is_int, int error_code, - unsigned int next_eip, int is_hw); + target_ulong next_eip, int is_hw); void do_interrupt_user(int intno, int is_int, int error_code, - unsigned int next_eip); + target_ulong next_eip); void raise_interrupt(int intno, int is_int, int error_code, - unsigned int next_eip); + int next_eip_addend); void raise_exception_err(int exception_index, int error_code); void raise_exception(int exception_index); void __hidden cpu_loop_exit(void); -void helper_fsave(uint8_t *ptr, int data32); -void helper_frstor(uint8_t *ptr, int data32); void OPPROTO op_movl_eflags_T0(void); void OPPROTO op_movl_T0_eflags(void); -void raise_interrupt(int intno, int is_int, int error_code, - unsigned int next_eip); -void raise_exception_err(int exception_index, int error_code); -void raise_exception(int exception_index); -void helper_divl_EAX_T0(uint32_t eip); -void helper_idivl_EAX_T0(uint32_t eip); +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_cpuid(void); +void helper_enter_level(int level, int data32); +void helper_enter64_level(int level, int data64); +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); @@ -180,74 +211,11 @@ void check_iob_DX(void); void check_iow_DX(void); void check_iol_DX(void); -/* XXX: move that to a generic header */ #if !defined(CONFIG_USER_ONLY) -#define ldul_user ldl_user -#define ldul_kernel ldl_kernel - -#define ACCESS_TYPE 0 -#define MEMSUFFIX _kernel -#define DATA_SIZE 1 -#include "softmmu_header.h" - -#define DATA_SIZE 2 -#include "softmmu_header.h" - -#define DATA_SIZE 4 -#include "softmmu_header.h" - -#define DATA_SIZE 8 -#include "softmmu_header.h" -#undef ACCESS_TYPE -#undef MEMSUFFIX - -#define ACCESS_TYPE 1 -#define MEMSUFFIX _user -#define DATA_SIZE 1 -#include "softmmu_header.h" - -#define DATA_SIZE 2 -#include "softmmu_header.h" - -#define DATA_SIZE 4 -#include "softmmu_header.h" - -#define DATA_SIZE 8 -#include "softmmu_header.h" -#undef ACCESS_TYPE -#undef MEMSUFFIX - -/* these access are slower, they must be as rare as possible */ -#define ACCESS_TYPE 2 -#define MEMSUFFIX _data -#define DATA_SIZE 1 -#include "softmmu_header.h" - -#define DATA_SIZE 2 -#include "softmmu_header.h" - -#define DATA_SIZE 4 -#include "softmmu_header.h" - -#define DATA_SIZE 8 -#include "softmmu_header.h" -#undef ACCESS_TYPE -#undef MEMSUFFIX - -#define ldub(p) ldub_data(p) -#define ldsb(p) ldsb_data(p) -#define lduw(p) lduw_data(p) -#define ldsw(p) ldsw_data(p) -#define ldl(p) ldl_data(p) -#define ldq(p) ldq_data(p) - -#define stb(p, v) stb_data(p, v) -#define stw(p, v) stw_data(p, v) -#define stl(p, v) stl_data(p, v) -#define stq(p, v) stq_data(p, v) +#include "softmmu_exec.h" -static inline double ldfq(void *ptr) +static inline double ldfq(target_ulong ptr) { union { double d; @@ -257,7 +225,7 @@ static inline double ldfq(void *ptr) return u.d; } -static inline void stfq(void *ptr, double v) +static inline void stfq(target_ulong ptr, double v) { union { double d; @@ -267,7 +235,7 @@ static inline void stfq(void *ptr, double v) stq(ptr, u.i); } -static inline float ldfl(void *ptr) +static inline float ldfl(target_ulong ptr) { union { float f; @@ -277,7 +245,7 @@ static inline float ldfl(void *ptr) return u.f; } -static inline void stfl(void *ptr, float v) +static inline void stfl(target_ulong ptr, float v) { union { float f; @@ -291,9 +259,15 @@ static inline void stfl(void *ptr, float v) #ifdef USE_X86LDOUBLE /* use long double functions */ -#define lrint lrintl -#define llrint llrintl -#define fabs fabsl +#define floatx_to_int32 floatx80_to_int32 +#define floatx_to_int64 floatx80_to_int64 +#define floatx_to_int32_round_to_zero floatx80_to_int32_round_to_zero +#define floatx_to_int64_round_to_zero floatx80_to_int64_round_to_zero +#define floatx_abs floatx80_abs +#define floatx_chs floatx80_chs +#define floatx_round_to_int floatx80_round_to_int +#define floatx_compare floatx80_compare +#define floatx_compare_quiet floatx80_compare_quiet #define sin sinl #define cos cosl #define sqrt sqrtl @@ -303,12 +277,19 @@ static inline void stfl(void *ptr, float v) #define atan2 atan2l #define floor floorl #define ceil ceill -#define rint rintl +#define ldexp ldexpl +#else +#define floatx_to_int32 float64_to_int32 +#define floatx_to_int64 float64_to_int64 +#define floatx_to_int32_round_to_zero float64_to_int32_round_to_zero +#define floatx_to_int64_round_to_zero float64_to_int64_round_to_zero +#define floatx_abs float64_abs +#define floatx_chs float64_chs +#define floatx_round_to_int float64_round_to_int +#define floatx_compare float64_compare +#define floatx_compare_quiet float64_compare_quiet #endif -extern int lrint(CPU86_LDouble x); -extern int64_t llrint(CPU86_LDouble x); -extern CPU86_LDouble fabs(CPU86_LDouble x); extern CPU86_LDouble sin(CPU86_LDouble x); extern CPU86_LDouble cos(CPU86_LDouble x); extern CPU86_LDouble sqrt(CPU86_LDouble x); @@ -318,7 +299,6 @@ extern CPU86_LDouble tan(CPU86_LDouble x); extern CPU86_LDouble atan2(CPU86_LDouble, CPU86_LDouble); extern CPU86_LDouble floor(CPU86_LDouble x); extern CPU86_LDouble ceil(CPU86_LDouble x); -extern CPU86_LDouble rint(CPU86_LDouble x); #define RC_MASK 0xc00 #define RC_NEAR 0x000 @@ -328,13 +308,6 @@ extern CPU86_LDouble rint(CPU86_LDouble x); #define MAXTAN 9223372036854775808.0 -#ifdef __arm__ -/* we have no way to do correct rounding - a FPU emulator is needed */ -#define FE_DOWNWARD FE_TONEAREST -#define FE_UPWARD FE_TONEAREST -#define FE_TOWARDZERO FE_TONEAREST -#endif - #ifdef USE_X86LDOUBLE /* only for x86 */ @@ -401,7 +374,7 @@ static inline void fpop(void) } #ifndef USE_X86LDOUBLE -static inline CPU86_LDouble helper_fldt(uint8_t *ptr) +static inline CPU86_LDouble helper_fldt(target_ulong ptr) { CPU86_LDoubleU temp; int upper, e; @@ -422,7 +395,7 @@ static inline CPU86_LDouble helper_fldt(uint8_t *ptr) return temp.d; } -static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr) +static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr) { CPU86_LDoubleU temp; int e; @@ -441,12 +414,12 @@ static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr) #ifdef CONFIG_USER_ONLY -static inline CPU86_LDouble helper_fldt(uint8_t *ptr) +static inline CPU86_LDouble helper_fldt(target_ulong ptr) { return *(CPU86_LDouble *)ptr; } -static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr) +static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr) { *(CPU86_LDouble *)ptr = f; } @@ -455,7 +428,7 @@ static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr) /* we use memory access macros */ -static inline CPU86_LDouble helper_fldt(uint8_t *ptr) +static inline CPU86_LDouble helper_fldt(target_ulong ptr) { CPU86_LDoubleU temp; @@ -464,7 +437,7 @@ static inline CPU86_LDouble helper_fldt(uint8_t *ptr) return temp.d; } -static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr) +static inline void helper_fstt(CPU86_LDouble f, target_ulong ptr) { CPU86_LDoubleU temp; @@ -477,10 +450,24 @@ static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr) #endif /* USE_X86LDOUBLE */ -const CPU86_LDouble f15rk[7]; +#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 + +extern const CPU86_LDouble f15rk[7]; void helper_fldt_ST0_A0(void); void helper_fstt_ST0_A0(void); +void fpu_raise_exception(void); +CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b); void helper_fbld_ST0_A0(void); void helper_fbst_ST0_A0(void); void helper_f2xm1(void); @@ -498,14 +485,21 @@ void helper_fscale(void); void helper_fsin(void); void helper_fcos(void); void helper_fxam_ST0(void); -void helper_fstenv(uint8_t *ptr, int data32); -void helper_fldenv(uint8_t *ptr, int data32); -void helper_fsave(uint8_t *ptr, int data32); -void helper_frstor(uint8_t *ptr, int data32); - -const uint8_t parity_table[256]; -const uint8_t rclw_table[32]; -const uint8_t rclb_table[32]; +void helper_fstenv(target_ulong ptr, int data32); +void helper_fldenv(target_ulong ptr, int data32); +void helper_fsave(target_ulong ptr, int data32); +void helper_frstor(target_ulong ptr, int data32); +void helper_fxsave(target_ulong ptr, int data64); +void helper_fxrstor(target_ulong ptr, int data64); +void restore_native_fp_state(CPUState *env); +void save_native_fp_state(CPUState *env); +float approx_rsqrt(float a); +float approx_rcp(float a); +void update_fp_status(void); + +extern const uint8_t parity_table[256]; +extern const uint8_t rclw_table[32]; +extern const uint8_t rclb_table[32]; static inline uint32_t compute_eflags(void) { @@ -521,3 +515,58 @@ static inline void load_eflags(int eflags, int update_mask) (eflags & update_mask); } +static inline void env_to_regs(void) +{ +#ifdef reg_EAX + EAX = env->regs[R_EAX]; +#endif +#ifdef reg_ECX + ECX = env->regs[R_ECX]; +#endif +#ifdef reg_EDX + EDX = env->regs[R_EDX]; +#endif +#ifdef reg_EBX + EBX = env->regs[R_EBX]; +#endif +#ifdef reg_ESP + ESP = env->regs[R_ESP]; +#endif +#ifdef reg_EBP + EBP = env->regs[R_EBP]; +#endif +#ifdef reg_ESI + ESI = env->regs[R_ESI]; +#endif +#ifdef reg_EDI + EDI = env->regs[R_EDI]; +#endif +} + +static inline void regs_to_env(void) +{ +#ifdef reg_EAX + env->regs[R_EAX] = EAX; +#endif +#ifdef reg_ECX + env->regs[R_ECX] = ECX; +#endif +#ifdef reg_EDX + env->regs[R_EDX] = EDX; +#endif +#ifdef reg_EBX + env->regs[R_EBX] = EBX; +#endif +#ifdef reg_ESP + env->regs[R_ESP] = ESP; +#endif +#ifdef reg_EBP + env->regs[R_EBP] = EBP; +#endif +#ifdef reg_ESI + env->regs[R_ESI] = ESI; +#endif +#ifdef reg_EDI + env->regs[R_EDI] = EDI; +#endif +}