diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-06-05 00:54:09 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-06-05 00:54:09 +0000 |
commit | 3ec9c4fcc649d6a32c3a9fba6add43a996248937 (patch) | |
tree | 65ac233eb74d39e7b9e3ed7eb03b3334d0ac7d42 /exec-i386.h | |
parent | 2f87c60799042f6c9936040cedf6ea8dc690ca22 (diff) |
separated helpers from micro operations
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@204 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'exec-i386.h')
-rw-r--r-- | exec-i386.h | 177 |
1 files changed, 171 insertions, 6 deletions
diff --git a/exec-i386.h b/exec-i386.h index af82370032..d89a318cc3 100644 --- a/exec-i386.h +++ b/exec-i386.h @@ -190,14 +190,21 @@ register struct CPUX86State *env asm("r27"); #endif #ifdef __alpha__ +/* the symbols are considered non exported so a br immediate is generated */ +#define __hidden __attribute__((visibility("hidden"))) +#else +#define __hidden +#endif + +#ifdef __alpha__ /* Suggested by Richard Henderson. This will result in code like ldah $0,__op_param1($29) !gprelhigh lda $0,__op_param1($0) !gprellow We can then conveniently change $29 to $31 and adapt the offsets to emit the appropriate constant. */ -extern int __op_param1 __attribute__((visibility("hidden"))); -extern int __op_param2 __attribute__((visibility("hidden"))); -extern int __op_param3 __attribute__((visibility("hidden"))); +extern int __op_param1 __hidden; +extern int __op_param2 __hidden; +extern int __op_param3 __hidden; #define PARAM1 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param1)); _r; }) #define PARAM2 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param2)); _r; }) #define PARAM3 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param3)); _r; }) @@ -220,15 +227,173 @@ typedef struct CCTable { extern CCTable cc_table[]; void load_seg(int seg_reg, int selector, unsigned cur_eip); -void cpu_lock(void); -void cpu_unlock(void); +void __hidden cpu_lock(void); +void __hidden cpu_unlock(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 cpu_loop_exit(void); +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_cpuid(void); +void helper_lsl(void); +void helper_lar(void); + + +#ifdef USE_X86LDOUBLE +/* use long double functions */ +#define lrint lrintl +#define llrint llrintl +#define fabs fabsl +#define sin sinl +#define cos cosl +#define sqrt sqrtl +#define pow powl +#define log logl +#define tan tanl +#define atan2 atan2l +#define floor floorl +#define ceil ceill +#define rint rintl +#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); +extern CPU86_LDouble pow(CPU86_LDouble, CPU86_LDouble); +extern CPU86_LDouble log(CPU86_LDouble x); +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 +#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; +} CPU86_LDoubleU; + +/* 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 + +#else + +typedef union { + double d; +#ifndef WORDS_BIGENDIAN + struct { + uint32_t lower; + int32_t upper; + } l; +#else + struct { + int32_t upper; + uint32_t lower; + } l; +#endif + int64_t ll; +} CPU86_LDoubleU; + +/* the following deal with IEEE double-precision numbers */ +#define MAXEXPD 0x7ff +#define EXPBIAS 1023 +#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) +#define SIGND(fp) ((fp.l.upper) & 0x80000000) +#define MANTD(fp) (fp.ll & ((1LL << 52) - 1)) +#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20) +#endif + +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; +} + +#ifndef USE_X86LDOUBLE +static inline CPU86_LDouble helper_fldt(uint8_t *ptr) +{ + CPU86_LDoubleU temp; + int upper, e; + /* mantissa */ + upper = lduw(ptr + 8); + /* XXX: handle overflow ? */ + e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */ + e |= (upper >> 4) & 0x800; /* sign */ + temp.ll = ((ldq(ptr) >> 11) & ((1LL << 52) - 1)) | ((uint64_t)e << 52); + return temp.d; +} + +static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr) +{ + CPU86_LDoubleU temp; + int e; + temp.d = f; + /* mantissa */ + stq(ptr, (MANTD(temp) << 11) | (1LL << 63)); + /* exponent + sign */ + e = EXPD(temp) - EXPBIAS + 16383; + e |= SIGND(temp) >> 16; + stw(ptr + 8, e); +} +#endif + +void helper_fldt_ST0_A0(void); +void helper_fstt_ST0_A0(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); +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); + |