Commit 3ec9c4fcc649d6a32c3a9fba6add43a996248937

Authored by bellard
1 parent 2f87c607

separated helpers from micro operations


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@204 c046a42c-6fe2-441c-8c8c-71466251a162
exec-i386.h
@@ -190,14 +190,21 @@ register struct CPUX86State *env asm("r27"); @@ -190,14 +190,21 @@ register struct CPUX86State *env asm("r27");
190 #endif 190 #endif
191 191
192 #ifdef __alpha__ 192 #ifdef __alpha__
  193 +/* the symbols are considered non exported so a br immediate is generated */
  194 +#define __hidden __attribute__((visibility("hidden")))
  195 +#else
  196 +#define __hidden
  197 +#endif
  198 +
  199 +#ifdef __alpha__
193 /* Suggested by Richard Henderson. This will result in code like 200 /* Suggested by Richard Henderson. This will result in code like
194 ldah $0,__op_param1($29) !gprelhigh 201 ldah $0,__op_param1($29) !gprelhigh
195 lda $0,__op_param1($0) !gprellow 202 lda $0,__op_param1($0) !gprellow
196 We can then conveniently change $29 to $31 and adapt the offsets to 203 We can then conveniently change $29 to $31 and adapt the offsets to
197 emit the appropriate constant. */ 204 emit the appropriate constant. */
198 -extern int __op_param1 __attribute__((visibility("hidden")));  
199 -extern int __op_param2 __attribute__((visibility("hidden")));  
200 -extern int __op_param3 __attribute__((visibility("hidden"))); 205 +extern int __op_param1 __hidden;
  206 +extern int __op_param2 __hidden;
  207 +extern int __op_param3 __hidden;
201 #define PARAM1 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param1)); _r; }) 208 #define PARAM1 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param1)); _r; })
202 #define PARAM2 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param2)); _r; }) 209 #define PARAM2 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param2)); _r; })
203 #define PARAM3 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param3)); _r; }) 210 #define PARAM3 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param3)); _r; })
@@ -220,15 +227,173 @@ typedef struct CCTable { @@ -220,15 +227,173 @@ typedef struct CCTable {
220 extern CCTable cc_table[]; 227 extern CCTable cc_table[];
221 228
222 void load_seg(int seg_reg, int selector, unsigned cur_eip); 229 void load_seg(int seg_reg, int selector, unsigned cur_eip);
223 -void cpu_lock(void);  
224 -void cpu_unlock(void); 230 +void __hidden cpu_lock(void);
  231 +void __hidden cpu_unlock(void);
225 void raise_interrupt(int intno, int is_int, int error_code, 232 void raise_interrupt(int intno, int is_int, int error_code,
226 unsigned int next_eip); 233 unsigned int next_eip);
227 void raise_exception_err(int exception_index, int error_code); 234 void raise_exception_err(int exception_index, int error_code);
228 void raise_exception(int exception_index); 235 void raise_exception(int exception_index);
229 -void cpu_loop_exit(void); 236 +void __hidden cpu_loop_exit(void);
230 void helper_fsave(uint8_t *ptr, int data32); 237 void helper_fsave(uint8_t *ptr, int data32);
231 void helper_frstor(uint8_t *ptr, int data32); 238 void helper_frstor(uint8_t *ptr, int data32);
232 239
233 void OPPROTO op_movl_eflags_T0(void); 240 void OPPROTO op_movl_eflags_T0(void);
234 void OPPROTO op_movl_T0_eflags(void); 241 void OPPROTO op_movl_T0_eflags(void);
  242 +void raise_interrupt(int intno, int is_int, int error_code,
  243 + unsigned int next_eip);
  244 +void raise_exception_err(int exception_index, int error_code);
  245 +void raise_exception(int exception_index);
  246 +void helper_cpuid(void);
  247 +void helper_lsl(void);
  248 +void helper_lar(void);
  249 +
  250 +
  251 +#ifdef USE_X86LDOUBLE
  252 +/* use long double functions */
  253 +#define lrint lrintl
  254 +#define llrint llrintl
  255 +#define fabs fabsl
  256 +#define sin sinl
  257 +#define cos cosl
  258 +#define sqrt sqrtl
  259 +#define pow powl
  260 +#define log logl
  261 +#define tan tanl
  262 +#define atan2 atan2l
  263 +#define floor floorl
  264 +#define ceil ceill
  265 +#define rint rintl
  266 +#endif
  267 +
  268 +extern int lrint(CPU86_LDouble x);
  269 +extern int64_t llrint(CPU86_LDouble x);
  270 +extern CPU86_LDouble fabs(CPU86_LDouble x);
  271 +extern CPU86_LDouble sin(CPU86_LDouble x);
  272 +extern CPU86_LDouble cos(CPU86_LDouble x);
  273 +extern CPU86_LDouble sqrt(CPU86_LDouble x);
  274 +extern CPU86_LDouble pow(CPU86_LDouble, CPU86_LDouble);
  275 +extern CPU86_LDouble log(CPU86_LDouble x);
  276 +extern CPU86_LDouble tan(CPU86_LDouble x);
  277 +extern CPU86_LDouble atan2(CPU86_LDouble, CPU86_LDouble);
  278 +extern CPU86_LDouble floor(CPU86_LDouble x);
  279 +extern CPU86_LDouble ceil(CPU86_LDouble x);
  280 +extern CPU86_LDouble rint(CPU86_LDouble x);
  281 +
  282 +#define RC_MASK 0xc00
  283 +#define RC_NEAR 0x000
  284 +#define RC_DOWN 0x400
  285 +#define RC_UP 0x800
  286 +#define RC_CHOP 0xc00
  287 +
  288 +#define MAXTAN 9223372036854775808.0
  289 +
  290 +#ifdef USE_X86LDOUBLE
  291 +
  292 +/* only for x86 */
  293 +typedef union {
  294 + long double d;
  295 + struct {
  296 + unsigned long long lower;
  297 + unsigned short upper;
  298 + } l;
  299 +} CPU86_LDoubleU;
  300 +
  301 +/* the following deal with x86 long double-precision numbers */
  302 +#define MAXEXPD 0x7fff
  303 +#define EXPBIAS 16383
  304 +#define EXPD(fp) (fp.l.upper & 0x7fff)
  305 +#define SIGND(fp) ((fp.l.upper) & 0x8000)
  306 +#define MANTD(fp) (fp.l.lower)
  307 +#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS
  308 +
  309 +#else
  310 +
  311 +typedef union {
  312 + double d;
  313 +#ifndef WORDS_BIGENDIAN
  314 + struct {
  315 + uint32_t lower;
  316 + int32_t upper;
  317 + } l;
  318 +#else
  319 + struct {
  320 + int32_t upper;
  321 + uint32_t lower;
  322 + } l;
  323 +#endif
  324 + int64_t ll;
  325 +} CPU86_LDoubleU;
  326 +
  327 +/* the following deal with IEEE double-precision numbers */
  328 +#define MAXEXPD 0x7ff
  329 +#define EXPBIAS 1023
  330 +#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
  331 +#define SIGND(fp) ((fp.l.upper) & 0x80000000)
  332 +#define MANTD(fp) (fp.ll & ((1LL << 52) - 1))
  333 +#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20)
  334 +#endif
  335 +
  336 +static inline void fpush(void)
  337 +{
  338 + env->fpstt = (env->fpstt - 1) & 7;
  339 + env->fptags[env->fpstt] = 0; /* validate stack entry */
  340 +}
  341 +
  342 +static inline void fpop(void)
  343 +{
  344 + env->fptags[env->fpstt] = 1; /* invvalidate stack entry */
  345 + env->fpstt = (env->fpstt + 1) & 7;
  346 +}
  347 +
  348 +#ifndef USE_X86LDOUBLE
  349 +static inline CPU86_LDouble helper_fldt(uint8_t *ptr)
  350 +{
  351 + CPU86_LDoubleU temp;
  352 + int upper, e;
  353 + /* mantissa */
  354 + upper = lduw(ptr + 8);
  355 + /* XXX: handle overflow ? */
  356 + e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */
  357 + e |= (upper >> 4) & 0x800; /* sign */
  358 + temp.ll = ((ldq(ptr) >> 11) & ((1LL << 52) - 1)) | ((uint64_t)e << 52);
  359 + return temp.d;
  360 +}
  361 +
  362 +static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr)
  363 +{
  364 + CPU86_LDoubleU temp;
  365 + int e;
  366 + temp.d = f;
  367 + /* mantissa */
  368 + stq(ptr, (MANTD(temp) << 11) | (1LL << 63));
  369 + /* exponent + sign */
  370 + e = EXPD(temp) - EXPBIAS + 16383;
  371 + e |= SIGND(temp) >> 16;
  372 + stw(ptr + 8, e);
  373 +}
  374 +#endif
  375 +
  376 +void helper_fldt_ST0_A0(void);
  377 +void helper_fstt_ST0_A0(void);
  378 +void helper_fbld_ST0_A0(void);
  379 +void helper_fbst_ST0_A0(void);
  380 +void helper_f2xm1(void);
  381 +void helper_fyl2x(void);
  382 +void helper_fptan(void);
  383 +void helper_fpatan(void);
  384 +void helper_fxtract(void);
  385 +void helper_fprem1(void);
  386 +void helper_fprem(void);
  387 +void helper_fyl2xp1(void);
  388 +void helper_fsqrt(void);
  389 +void helper_fsincos(void);
  390 +void helper_frndint(void);
  391 +void helper_fscale(void);
  392 +void helper_fsin(void);
  393 +void helper_fcos(void);
  394 +void helper_fxam_ST0(void);
  395 +void helper_fstenv(uint8_t *ptr, int data32);
  396 +void helper_fldenv(uint8_t *ptr, int data32);
  397 +void helper_fsave(uint8_t *ptr, int data32);
  398 +void helper_frstor(uint8_t *ptr, int data32);
  399 +
helper-i386.c 0 โ†’ 100644
  1 +/*
  2 + * i386 helpers
  3 + *
  4 + * Copyright (c) 2003 Fabrice Bellard
  5 + *
  6 + * This library is free software; you can redistribute it and/or
  7 + * modify it under the terms of the GNU Lesser General Public
  8 + * License as published by the Free Software Foundation; either
  9 + * version 2 of the License, or (at your option) any later version.
  10 + *
  11 + * This library is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14 + * Lesser General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU Lesser General Public
  17 + * License along with this library; if not, write to the Free Software
  18 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19 + */
  20 +#include "exec-i386.h"
  21 +
  22 +#if 0
  23 +/* full interrupt support (only useful for real CPU emulation, not
  24 + finished) - I won't do it any time soon, finish it if you want ! */
  25 +void raise_interrupt(int intno, int is_int, int error_code,
  26 + unsigned int next_eip)
  27 +{
  28 + SegmentDescriptorTable *dt;
  29 + uint8_t *ptr;
  30 + int type, dpl, cpl;
  31 + uint32_t e1, e2;
  32 +
  33 + dt = &env->idt;
  34 + if (intno * 8 + 7 > dt->limit)
  35 + raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
  36 + ptr = dt->base + intno * 8;
  37 + e1 = ldl(ptr);
  38 + e2 = ldl(ptr + 4);
  39 + /* check gate type */
  40 + type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;
  41 + switch(type) {
  42 + case 5: /* task gate */
  43 + case 6: /* 286 interrupt gate */
  44 + case 7: /* 286 trap gate */
  45 + case 14: /* 386 interrupt gate */
  46 + case 15: /* 386 trap gate */
  47 + break;
  48 + default:
  49 + raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
  50 + break;
  51 + }
  52 + dpl = (e2 >> DESC_DPL_SHIFT) & 3;
  53 + cpl = env->segs[R_CS] & 3;
  54 + /* check privledge if software int */
  55 + if (is_int && dpl < cpl)
  56 + raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
  57 + /* check valid bit */
  58 + if (!(e2 & DESC_P_MASK))
  59 + raise_exception_err(EXCP0B_NOSEG, intno * 8 + 2);
  60 +}
  61 +
  62 +#else
  63 +
  64 +/*
  65 + * is_int is TRUE if coming from the int instruction. next_eip is the
  66 + * EIP value AFTER the interrupt instruction. It is only relevant if
  67 + * is_int is TRUE.
  68 + */
  69 +void raise_interrupt(int intno, int is_int, int error_code,
  70 + unsigned int next_eip)
  71 +{
  72 + SegmentDescriptorTable *dt;
  73 + uint8_t *ptr;
  74 + int dpl, cpl;
  75 + uint32_t e2;
  76 +
  77 + dt = &env->idt;
  78 + ptr = dt->base + (intno * 8);
  79 + e2 = ldl(ptr + 4);
  80 +
  81 + dpl = (e2 >> DESC_DPL_SHIFT) & 3;
  82 + cpl = 3;
  83 + /* check privledge if software int */
  84 + if (is_int && dpl < cpl)
  85 + raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
  86 +
  87 + /* Since we emulate only user space, we cannot do more than
  88 + exiting the emulation with the suitable exception and error
  89 + code */
  90 + if (is_int)
  91 + EIP = next_eip;
  92 + env->exception_index = intno;
  93 + env->error_code = error_code;
  94 +
  95 + cpu_loop_exit();
  96 +}
  97 +
  98 +#endif
  99 +
  100 +/* shortcuts to generate exceptions */
  101 +void raise_exception_err(int exception_index, int error_code)
  102 +{
  103 + raise_interrupt(exception_index, 0, error_code, 0);
  104 +}
  105 +
  106 +void raise_exception(int exception_index)
  107 +{
  108 + raise_interrupt(exception_index, 0, 0, 0);
  109 +}
  110 +
  111 +/* We simulate a pre-MMX pentium as in valgrind */
  112 +#define CPUID_FP87 (1 << 0)
  113 +#define CPUID_VME (1 << 1)
  114 +#define CPUID_DE (1 << 2)
  115 +#define CPUID_PSE (1 << 3)
  116 +#define CPUID_TSC (1 << 4)
  117 +#define CPUID_MSR (1 << 5)
  118 +#define CPUID_PAE (1 << 6)
  119 +#define CPUID_MCE (1 << 7)
  120 +#define CPUID_CX8 (1 << 8)
  121 +#define CPUID_APIC (1 << 9)
  122 +#define CPUID_SEP (1 << 11) /* sysenter/sysexit */
  123 +#define CPUID_MTRR (1 << 12)
  124 +#define CPUID_PGE (1 << 13)
  125 +#define CPUID_MCA (1 << 14)
  126 +#define CPUID_CMOV (1 << 15)
  127 +/* ... */
  128 +#define CPUID_MMX (1 << 23)
  129 +#define CPUID_FXSR (1 << 24)
  130 +#define CPUID_SSE (1 << 25)
  131 +#define CPUID_SSE2 (1 << 26)
  132 +
  133 +void helper_cpuid(void)
  134 +{
  135 + if (EAX == 0) {
  136 + EAX = 1; /* max EAX index supported */
  137 + EBX = 0x756e6547;
  138 + ECX = 0x6c65746e;
  139 + EDX = 0x49656e69;
  140 + } else if (EAX == 1) {
  141 + /* EAX = 1 info */
  142 + EAX = 0x52b;
  143 + EBX = 0;
  144 + ECX = 0;
  145 + EDX = CPUID_FP87 | CPUID_DE | CPUID_PSE |
  146 + CPUID_TSC | CPUID_MSR | CPUID_MCE |
  147 + CPUID_CX8;
  148 + }
  149 +}
  150 +
  151 +/* only works if protected mode and not VM86 */
  152 +void load_seg(int seg_reg, int selector, unsigned cur_eip)
  153 +{
  154 + SegmentCache *sc;
  155 + SegmentDescriptorTable *dt;
  156 + int index;
  157 + uint32_t e1, e2;
  158 + uint8_t *ptr;
  159 +
  160 + sc = &env->seg_cache[seg_reg];
  161 + if ((selector & 0xfffc) == 0) {
  162 + /* null selector case */
  163 + if (seg_reg == R_SS) {
  164 + EIP = cur_eip;
  165 + raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
  166 + } else {
  167 + /* XXX: each access should trigger an exception */
  168 + sc->base = NULL;
  169 + sc->limit = 0;
  170 + sc->seg_32bit = 1;
  171 + }
  172 + } else {
  173 + if (selector & 0x4)
  174 + dt = &env->ldt;
  175 + else
  176 + dt = &env->gdt;
  177 + index = selector & ~7;
  178 + if ((index + 7) > dt->limit) {
  179 + EIP = cur_eip;
  180 + raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
  181 + }
  182 + ptr = dt->base + index;
  183 + e1 = ldl(ptr);
  184 + e2 = ldl(ptr + 4);
  185 + if (!(e2 & DESC_S_MASK) ||
  186 + (e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) {
  187 + EIP = cur_eip;
  188 + raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
  189 + }
  190 +
  191 + if (seg_reg == R_SS) {
  192 + if ((e2 & (DESC_CS_MASK | DESC_W_MASK)) == 0) {
  193 + EIP = cur_eip;
  194 + raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
  195 + }
  196 + } else {
  197 + if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) {
  198 + EIP = cur_eip;
  199 + raise_exception_err(EXCP0D_GPF, selector & 0xfffc);
  200 + }
  201 + }
  202 +
  203 + if (!(e2 & DESC_P_MASK)) {
  204 + EIP = cur_eip;
  205 + if (seg_reg == R_SS)
  206 + raise_exception_err(EXCP0C_STACK, selector & 0xfffc);
  207 + else
  208 + raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);
  209 + }
  210 +
  211 + sc->base = (void *)((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
  212 + sc->limit = (e1 & 0xffff) | (e2 & 0x000f0000);
  213 + if (e2 & (1 << 23))
  214 + sc->limit = (sc->limit << 12) | 0xfff;
  215 + sc->seg_32bit = (e2 >> 22) & 1;
  216 +#if 0
  217 + fprintf(logfile, "load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx seg_32bit=%d\n",
  218 + selector, (unsigned long)sc->base, sc->limit, sc->seg_32bit);
  219 +#endif
  220 + }
  221 + env->segs[seg_reg] = selector;
  222 +}
  223 +
  224 +void helper_lsl(void)
  225 +{
  226 + unsigned int selector, limit;
  227 + SegmentDescriptorTable *dt;
  228 + int index;
  229 + uint32_t e1, e2;
  230 + uint8_t *ptr;
  231 +
  232 + CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;
  233 + selector = T0 & 0xffff;
  234 + if (selector & 0x4)
  235 + dt = &env->ldt;
  236 + else
  237 + dt = &env->gdt;
  238 + index = selector & ~7;
  239 + if ((index + 7) > dt->limit)
  240 + return;
  241 + ptr = dt->base + index;
  242 + e1 = ldl(ptr);
  243 + e2 = ldl(ptr + 4);
  244 + limit = (e1 & 0xffff) | (e2 & 0x000f0000);
  245 + if (e2 & (1 << 23))
  246 + limit = (limit << 12) | 0xfff;
  247 + T1 = limit;
  248 + CC_SRC |= CC_Z;
  249 +}
  250 +
  251 +void helper_lar(void)
  252 +{
  253 + unsigned int selector;
  254 + SegmentDescriptorTable *dt;
  255 + int index;
  256 + uint32_t e2;
  257 + uint8_t *ptr;
  258 +
  259 + CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;
  260 + selector = T0 & 0xffff;
  261 + if (selector & 0x4)
  262 + dt = &env->ldt;
  263 + else
  264 + dt = &env->gdt;
  265 + index = selector & ~7;
  266 + if ((index + 7) > dt->limit)
  267 + return;
  268 + ptr = dt->base + index;
  269 + e2 = ldl(ptr + 4);
  270 + T1 = e2 & 0x00f0ff00;
  271 + CC_SRC |= CC_Z;
  272 +}
  273 +
  274 +/* FPU helpers */
  275 +
  276 +#ifndef USE_X86LDOUBLE
  277 +void helper_fldt_ST0_A0(void)
  278 +{
  279 + ST0 = helper_fldt((uint8_t *)A0);
  280 +}
  281 +
  282 +void helper_fstt_ST0_A0(void)
  283 +{
  284 + helper_fstt(ST0, (uint8_t *)A0);
  285 +}
  286 +#endif
  287 +
  288 +/* BCD ops */
  289 +
  290 +#define MUL10(iv) ( iv + iv + (iv << 3) )
  291 +
  292 +void helper_fbld_ST0_A0(void)
  293 +{
  294 + uint8_t *seg;
  295 + CPU86_LDouble fpsrcop;
  296 + int m32i;
  297 + unsigned int v;
  298 +
  299 + /* in this code, seg/m32i will be used as temporary ptr/int */
  300 + seg = (uint8_t *)A0 + 8;
  301 + v = ldub(seg--);
  302 + /* XXX: raise exception */
  303 + if (v != 0)
  304 + return;
  305 + v = ldub(seg--);
  306 + /* XXX: raise exception */
  307 + if ((v & 0xf0) != 0)
  308 + return;
  309 + m32i = v; /* <-- d14 */
  310 + v = ldub(seg--);
  311 + m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d13 */
  312 + m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d12 */
  313 + v = ldub(seg--);
  314 + m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d11 */
  315 + m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d10 */
  316 + v = ldub(seg--);
  317 + m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d9 */
  318 + m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d8 */
  319 + fpsrcop = ((CPU86_LDouble)m32i) * 100000000.0;
  320 +
  321 + v = ldub(seg--);
  322 + m32i = (v >> 4); /* <-- d7 */
  323 + m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d6 */
  324 + v = ldub(seg--);
  325 + m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d5 */
  326 + m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d4 */
  327 + v = ldub(seg--);
  328 + m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d3 */
  329 + m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d2 */
  330 + v = ldub(seg);
  331 + m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d1 */
  332 + m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d0 */
  333 + fpsrcop += ((CPU86_LDouble)m32i);
  334 + if ( ldub(seg+9) & 0x80 )
  335 + fpsrcop = -fpsrcop;
  336 + ST0 = fpsrcop;
  337 +}
  338 +
  339 +void helper_fbst_ST0_A0(void)
  340 +{
  341 + CPU86_LDouble fptemp;
  342 + CPU86_LDouble fpsrcop;
  343 + int v;
  344 + uint8_t *mem_ref, *mem_end;
  345 +
  346 + fpsrcop = rint(ST0);
  347 + mem_ref = (uint8_t *)A0;
  348 + mem_end = mem_ref + 8;
  349 + if ( fpsrcop < 0.0 ) {
  350 + stw(mem_end, 0x8000);
  351 + fpsrcop = -fpsrcop;
  352 + } else {
  353 + stw(mem_end, 0x0000);
  354 + }
  355 + while (mem_ref < mem_end) {
  356 + if (fpsrcop == 0.0)
  357 + break;
  358 + fptemp = floor(fpsrcop/10.0);
  359 + v = ((int)(fpsrcop - fptemp*10.0));
  360 + if (fptemp == 0.0) {
  361 + stb(mem_ref++, v);
  362 + break;
  363 + }
  364 + fpsrcop = fptemp;
  365 + fptemp = floor(fpsrcop/10.0);
  366 + v |= (((int)(fpsrcop - fptemp*10.0)) << 4);
  367 + stb(mem_ref++, v);
  368 + fpsrcop = fptemp;
  369 + }
  370 + while (mem_ref < mem_end) {
  371 + stb(mem_ref++, 0);
  372 + }
  373 +}
  374 +
  375 +void helper_f2xm1(void)
  376 +{
  377 + ST0 = pow(2.0,ST0) - 1.0;
  378 +}
  379 +
  380 +void helper_fyl2x(void)
  381 +{
  382 + CPU86_LDouble fptemp;
  383 +
  384 + fptemp = ST0;
  385 + if (fptemp>0.0){
  386 + fptemp = log(fptemp)/log(2.0); /* log2(ST) */
  387 + ST1 *= fptemp;
  388 + fpop();
  389 + } else {
  390 + env->fpus &= (~0x4700);
  391 + env->fpus |= 0x400;
  392 + }
  393 +}
  394 +
  395 +void helper_fptan(void)
  396 +{
  397 + CPU86_LDouble fptemp;
  398 +
  399 + fptemp = ST0;
  400 + if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
  401 + env->fpus |= 0x400;
  402 + } else {
  403 + ST0 = tan(fptemp);
  404 + fpush();
  405 + ST0 = 1.0;
  406 + env->fpus &= (~0x400); /* C2 <-- 0 */
  407 + /* the above code is for |arg| < 2**52 only */
  408 + }
  409 +}
  410 +
  411 +void helper_fpatan(void)
  412 +{
  413 + CPU86_LDouble fptemp, fpsrcop;
  414 +
  415 + fpsrcop = ST1;
  416 + fptemp = ST0;
  417 + ST1 = atan2(fpsrcop,fptemp);
  418 + fpop();
  419 +}
  420 +
  421 +void helper_fxtract(void)
  422 +{
  423 + CPU86_LDoubleU temp;
  424 + unsigned int expdif;
  425 +
  426 + temp.d = ST0;
  427 + expdif = EXPD(temp) - EXPBIAS;
  428 + /*DP exponent bias*/
  429 + ST0 = expdif;
  430 + fpush();
  431 + BIASEXPONENT(temp);
  432 + ST0 = temp.d;
  433 +}
  434 +
  435 +void helper_fprem1(void)
  436 +{
  437 + CPU86_LDouble dblq, fpsrcop, fptemp;
  438 + CPU86_LDoubleU fpsrcop1, fptemp1;
  439 + int expdif;
  440 + int q;
  441 +
  442 + fpsrcop = ST0;
  443 + fptemp = ST1;
  444 + fpsrcop1.d = fpsrcop;
  445 + fptemp1.d = fptemp;
  446 + expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
  447 + if (expdif < 53) {
  448 + dblq = fpsrcop / fptemp;
  449 + dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);
  450 + ST0 = fpsrcop - fptemp*dblq;
  451 + q = (int)dblq; /* cutting off top bits is assumed here */
  452 + env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
  453 + /* (C0,C1,C3) <-- (q2,q1,q0) */
  454 + env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */
  455 + env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */
  456 + env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */
  457 + } else {
  458 + env->fpus |= 0x400; /* C2 <-- 1 */
  459 + fptemp = pow(2.0, expdif-50);
  460 + fpsrcop = (ST0 / ST1) / fptemp;
  461 + /* fpsrcop = integer obtained by rounding to the nearest */
  462 + fpsrcop = (fpsrcop-floor(fpsrcop) < ceil(fpsrcop)-fpsrcop)?
  463 + floor(fpsrcop): ceil(fpsrcop);
  464 + ST0 -= (ST1 * fpsrcop * fptemp);
  465 + }
  466 +}
  467 +
  468 +void helper_fprem(void)
  469 +{
  470 + CPU86_LDouble dblq, fpsrcop, fptemp;
  471 + CPU86_LDoubleU fpsrcop1, fptemp1;
  472 + int expdif;
  473 + int q;
  474 +
  475 + fpsrcop = ST0;
  476 + fptemp = ST1;
  477 + fpsrcop1.d = fpsrcop;
  478 + fptemp1.d = fptemp;
  479 + expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
  480 + if ( expdif < 53 ) {
  481 + dblq = fpsrcop / fptemp;
  482 + dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);
  483 + ST0 = fpsrcop - fptemp*dblq;
  484 + q = (int)dblq; /* cutting off top bits is assumed here */
  485 + env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
  486 + /* (C0,C1,C3) <-- (q2,q1,q0) */
  487 + env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */
  488 + env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */
  489 + env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */
  490 + } else {
  491 + env->fpus |= 0x400; /* C2 <-- 1 */
  492 + fptemp = pow(2.0, expdif-50);
  493 + fpsrcop = (ST0 / ST1) / fptemp;
  494 + /* fpsrcop = integer obtained by chopping */
  495 + fpsrcop = (fpsrcop < 0.0)?
  496 + -(floor(fabs(fpsrcop))): floor(fpsrcop);
  497 + ST0 -= (ST1 * fpsrcop * fptemp);
  498 + }
  499 +}
  500 +
  501 +void helper_fyl2xp1(void)
  502 +{
  503 + CPU86_LDouble fptemp;
  504 +
  505 + fptemp = ST0;
  506 + if ((fptemp+1.0)>0.0) {
  507 + fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */
  508 + ST1 *= fptemp;
  509 + fpop();
  510 + } else {
  511 + env->fpus &= (~0x4700);
  512 + env->fpus |= 0x400;
  513 + }
  514 +}
  515 +
  516 +void helper_fsqrt(void)
  517 +{
  518 + CPU86_LDouble fptemp;
  519 +
  520 + fptemp = ST0;
  521 + if (fptemp<0.0) {
  522 + env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
  523 + env->fpus |= 0x400;
  524 + }
  525 + ST0 = sqrt(fptemp);
  526 +}
  527 +
  528 +void helper_fsincos(void)
  529 +{
  530 + CPU86_LDouble fptemp;
  531 +
  532 + fptemp = ST0;
  533 + if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
  534 + env->fpus |= 0x400;
  535 + } else {
  536 + ST0 = sin(fptemp);
  537 + fpush();
  538 + ST0 = cos(fptemp);
  539 + env->fpus &= (~0x400); /* C2 <-- 0 */
  540 + /* the above code is for |arg| < 2**63 only */
  541 + }
  542 +}
  543 +
  544 +void helper_frndint(void)
  545 +{
  546 + ST0 = rint(ST0);
  547 +}
  548 +
  549 +void helper_fscale(void)
  550 +{
  551 + CPU86_LDouble fpsrcop, fptemp;
  552 +
  553 + fpsrcop = 2.0;
  554 + fptemp = pow(fpsrcop,ST1);
  555 + ST0 *= fptemp;
  556 +}
  557 +
  558 +void helper_fsin(void)
  559 +{
  560 + CPU86_LDouble fptemp;
  561 +
  562 + fptemp = ST0;
  563 + if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
  564 + env->fpus |= 0x400;
  565 + } else {
  566 + ST0 = sin(fptemp);
  567 + env->fpus &= (~0x400); /* C2 <-- 0 */
  568 + /* the above code is for |arg| < 2**53 only */
  569 + }
  570 +}
  571 +
  572 +void helper_fcos(void)
  573 +{
  574 + CPU86_LDouble fptemp;
  575 +
  576 + fptemp = ST0;
  577 + if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
  578 + env->fpus |= 0x400;
  579 + } else {
  580 + ST0 = cos(fptemp);
  581 + env->fpus &= (~0x400); /* C2 <-- 0 */
  582 + /* the above code is for |arg5 < 2**63 only */
  583 + }
  584 +}
  585 +
  586 +void helper_fxam_ST0(void)
  587 +{
  588 + CPU86_LDoubleU temp;
  589 + int expdif;
  590 +
  591 + temp.d = ST0;
  592 +
  593 + env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
  594 + if (SIGND(temp))
  595 + env->fpus |= 0x200; /* C1 <-- 1 */
  596 +
  597 + expdif = EXPD(temp);
  598 + if (expdif == MAXEXPD) {
  599 + if (MANTD(temp) == 0)
  600 + env->fpus |= 0x500 /*Infinity*/;
  601 + else
  602 + env->fpus |= 0x100 /*NaN*/;
  603 + } else if (expdif == 0) {
  604 + if (MANTD(temp) == 0)
  605 + env->fpus |= 0x4000 /*Zero*/;
  606 + else
  607 + env->fpus |= 0x4400 /*Denormal*/;
  608 + } else {
  609 + env->fpus |= 0x400;
  610 + }
  611 +}
  612 +
  613 +void helper_fstenv(uint8_t *ptr, int data32)
  614 +{
  615 + int fpus, fptag, exp, i;
  616 + uint64_t mant;
  617 + CPU86_LDoubleU tmp;
  618 +
  619 + fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
  620 + fptag = 0;
  621 + for (i=7; i>=0; i--) {
  622 + fptag <<= 2;
  623 + if (env->fptags[i]) {
  624 + fptag |= 3;
  625 + } else {
  626 + tmp.d = env->fpregs[i];
  627 + exp = EXPD(tmp);
  628 + mant = MANTD(tmp);
  629 + if (exp == 0 && mant == 0) {
  630 + /* zero */
  631 + fptag |= 1;
  632 + } else if (exp == 0 || exp == MAXEXPD
  633 +#ifdef USE_X86LDOUBLE
  634 + || (mant & (1LL << 63)) == 0
  635 +#endif
  636 + ) {
  637 + /* NaNs, infinity, denormal */
  638 + fptag |= 2;
  639 + }
  640 + }
  641 + }
  642 + if (data32) {
  643 + /* 32 bit */
  644 + stl(ptr, env->fpuc);
  645 + stl(ptr + 4, fpus);
  646 + stl(ptr + 8, fptag);
  647 + stl(ptr + 12, 0);
  648 + stl(ptr + 16, 0);
  649 + stl(ptr + 20, 0);
  650 + stl(ptr + 24, 0);
  651 + } else {
  652 + /* 16 bit */
  653 + stw(ptr, env->fpuc);
  654 + stw(ptr + 2, fpus);
  655 + stw(ptr + 4, fptag);
  656 + stw(ptr + 6, 0);
  657 + stw(ptr + 8, 0);
  658 + stw(ptr + 10, 0);
  659 + stw(ptr + 12, 0);
  660 + }
  661 +}
  662 +
  663 +void helper_fldenv(uint8_t *ptr, int data32)
  664 +{
  665 + int i, fpus, fptag;
  666 +
  667 + if (data32) {
  668 + env->fpuc = lduw(ptr);
  669 + fpus = lduw(ptr + 4);
  670 + fptag = lduw(ptr + 8);
  671 + }
  672 + else {
  673 + env->fpuc = lduw(ptr);
  674 + fpus = lduw(ptr + 2);
  675 + fptag = lduw(ptr + 4);
  676 + }
  677 + env->fpstt = (fpus >> 11) & 7;
  678 + env->fpus = fpus & ~0x3800;
  679 + for(i = 0;i < 7; i++) {
  680 + env->fptags[i] = ((fptag & 3) == 3);
  681 + fptag >>= 2;
  682 + }
  683 +}
  684 +
  685 +void helper_fsave(uint8_t *ptr, int data32)
  686 +{
  687 + CPU86_LDouble tmp;
  688 + int i;
  689 +
  690 + helper_fstenv(ptr, data32);
  691 +
  692 + ptr += (14 << data32);
  693 + for(i = 0;i < 8; i++) {
  694 + tmp = ST(i);
  695 +#ifdef USE_X86LDOUBLE
  696 + *(long double *)ptr = tmp;
  697 +#else
  698 + helper_fstt(tmp, ptr);
  699 +#endif
  700 + ptr += 10;
  701 + }
  702 +
  703 + /* fninit */
  704 + env->fpus = 0;
  705 + env->fpstt = 0;
  706 + env->fpuc = 0x37f;
  707 + env->fptags[0] = 1;
  708 + env->fptags[1] = 1;
  709 + env->fptags[2] = 1;
  710 + env->fptags[3] = 1;
  711 + env->fptags[4] = 1;
  712 + env->fptags[5] = 1;
  713 + env->fptags[6] = 1;
  714 + env->fptags[7] = 1;
  715 +}
  716 +
  717 +void helper_frstor(uint8_t *ptr, int data32)
  718 +{
  719 + CPU86_LDouble tmp;
  720 + int i;
  721 +
  722 + helper_fldenv(ptr, data32);
  723 + ptr += (14 << data32);
  724 +
  725 + for(i = 0;i < 8; i++) {
  726 +#ifdef USE_X86LDOUBLE
  727 + tmp = *(long double *)ptr;
  728 +#else
  729 + tmp = helper_fldt(ptr);
  730 +#endif
  731 + ST(i) = tmp;
  732 + ptr += 10;
  733 + }
  734 +}
  735 +
op-i386.c
@@ -626,95 +626,6 @@ void OPPROTO op_jmp_im(void) @@ -626,95 +626,6 @@ void OPPROTO op_jmp_im(void)
626 EIP = PARAM1; 626 EIP = PARAM1;
627 } 627 }
628 628
629 -#if 0  
630 -/* full interrupt support (only useful for real CPU emulation, not  
631 - finished) - I won't do it any time soon, finish it if you want ! */  
632 -void raise_interrupt(int intno, int is_int, int error_code,  
633 - unsigned int next_eip)  
634 -{  
635 - SegmentDescriptorTable *dt;  
636 - uint8_t *ptr;  
637 - int type, dpl, cpl;  
638 - uint32_t e1, e2;  
639 -  
640 - dt = &env->idt;  
641 - if (intno * 8 + 7 > dt->limit)  
642 - raise_exception_err(EXCP0D_GPF, intno * 8 + 2);  
643 - ptr = dt->base + intno * 8;  
644 - e1 = ldl(ptr);  
645 - e2 = ldl(ptr + 4);  
646 - /* check gate type */  
647 - type = (e2 >> DESC_TYPE_SHIFT) & 0x1f;  
648 - switch(type) {  
649 - case 5: /* task gate */  
650 - case 6: /* 286 interrupt gate */  
651 - case 7: /* 286 trap gate */  
652 - case 14: /* 386 interrupt gate */  
653 - case 15: /* 386 trap gate */  
654 - break;  
655 - default:  
656 - raise_exception_err(EXCP0D_GPF, intno * 8 + 2);  
657 - break;  
658 - }  
659 - dpl = (e2 >> DESC_DPL_SHIFT) & 3;  
660 - cpl = env->segs[R_CS] & 3;  
661 - /* check privledge if software int */  
662 - if (is_int && dpl < cpl)  
663 - raise_exception_err(EXCP0D_GPF, intno * 8 + 2);  
664 - /* check valid bit */  
665 - if (!(e2 & DESC_P_MASK))  
666 - raise_exception_err(EXCP0B_NOSEG, intno * 8 + 2);  
667 -}  
668 -  
669 -#else  
670 -  
671 -/*  
672 - * is_int is TRUE if coming from the int instruction. next_eip is the  
673 - * EIP value AFTER the interrupt instruction. It is only relevant if  
674 - * is_int is TRUE.  
675 - */  
676 -void raise_interrupt(int intno, int is_int, int error_code,  
677 - unsigned int next_eip)  
678 -{  
679 - SegmentDescriptorTable *dt;  
680 - uint8_t *ptr;  
681 - int dpl, cpl;  
682 - uint32_t e2;  
683 -  
684 - dt = &env->idt;  
685 - ptr = dt->base + (intno * 8);  
686 - e2 = ldl(ptr + 4);  
687 -  
688 - dpl = (e2 >> DESC_DPL_SHIFT) & 3;  
689 - cpl = 3;  
690 - /* check privledge if software int */  
691 - if (is_int && dpl < cpl)  
692 - raise_exception_err(EXCP0D_GPF, intno * 8 + 2);  
693 -  
694 - /* Since we emulate only user space, we cannot do more than  
695 - exiting the emulation with the suitable exception and error  
696 - code */  
697 - if (is_int)  
698 - EIP = next_eip;  
699 - env->exception_index = intno;  
700 - env->error_code = error_code;  
701 -  
702 - cpu_loop_exit();  
703 -}  
704 -  
705 -#endif  
706 -  
707 -/* shortcuts to generate exceptions */  
708 -void raise_exception_err(int exception_index, int error_code)  
709 -{  
710 - raise_interrupt(exception_index, 0, error_code, 0);  
711 -}  
712 -  
713 -void raise_exception(int exception_index)  
714 -{  
715 - raise_interrupt(exception_index, 0, 0, 0);  
716 -}  
717 -  
718 void OPPROTO op_raise_interrupt(void) 629 void OPPROTO op_raise_interrupt(void)
719 { 630 {
720 int intno; 631 int intno;
@@ -833,7 +744,7 @@ label ## n:\ @@ -833,7 +744,7 @@ label ## n:\
833 #define JUMP_TB(tbparam, n, eip)\ 744 #define JUMP_TB(tbparam, n, eip)\
834 do {\ 745 do {\
835 static void __attribute__((unused)) *__op_label ## n = &&label ## n;\ 746 static void __attribute__((unused)) *__op_label ## n = &&label ## n;\
836 - goto *((TranslationBlock *)tbparam)->tb_next[n];\ 747 + goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\
837 label ## n:\ 748 label ## n:\
838 T0 = (long)(tbparam) + (n);\ 749 T0 = (long)(tbparam) + (n);\
839 EIP = eip;\ 750 EIP = eip;\
@@ -1044,46 +955,6 @@ void OPPROTO op_rdtsc(void) @@ -1044,46 +955,6 @@ void OPPROTO op_rdtsc(void)
1044 EDX = val >> 32; 955 EDX = val >> 32;
1045 } 956 }
1046 957
1047 -/* We simulate a pre-MMX pentium as in valgrind */  
1048 -#define CPUID_FP87 (1 << 0)  
1049 -#define CPUID_VME (1 << 1)  
1050 -#define CPUID_DE (1 << 2)  
1051 -#define CPUID_PSE (1 << 3)  
1052 -#define CPUID_TSC (1 << 4)  
1053 -#define CPUID_MSR (1 << 5)  
1054 -#define CPUID_PAE (1 << 6)  
1055 -#define CPUID_MCE (1 << 7)  
1056 -#define CPUID_CX8 (1 << 8)  
1057 -#define CPUID_APIC (1 << 9)  
1058 -#define CPUID_SEP (1 << 11) /* sysenter/sysexit */  
1059 -#define CPUID_MTRR (1 << 12)  
1060 -#define CPUID_PGE (1 << 13)  
1061 -#define CPUID_MCA (1 << 14)  
1062 -#define CPUID_CMOV (1 << 15)  
1063 -/* ... */  
1064 -#define CPUID_MMX (1 << 23)  
1065 -#define CPUID_FXSR (1 << 24)  
1066 -#define CPUID_SSE (1 << 25)  
1067 -#define CPUID_SSE2 (1 << 26)  
1068 -  
1069 -void helper_cpuid(void)  
1070 -{  
1071 - if (EAX == 0) {  
1072 - EAX = 1; /* max EAX index supported */  
1073 - EBX = 0x756e6547;  
1074 - ECX = 0x6c65746e;  
1075 - EDX = 0x49656e69;  
1076 - } else if (EAX == 1) {  
1077 - /* EAX = 1 info */  
1078 - EAX = 0x52b;  
1079 - EBX = 0;  
1080 - ECX = 0;  
1081 - EDX = CPUID_FP87 | CPUID_DE | CPUID_PSE |  
1082 - CPUID_TSC | CPUID_MSR | CPUID_MCE |  
1083 - CPUID_CX8;  
1084 - }  
1085 -}  
1086 -  
1087 void OPPROTO op_cpuid(void) 958 void OPPROTO op_cpuid(void)
1088 { 959 {
1089 helper_cpuid(); 960 helper_cpuid();
@@ -1221,79 +1092,6 @@ void OPPROTO op_das(void) @@ -1221,79 +1092,6 @@ void OPPROTO op_das(void)
1221 1092
1222 /* segment handling */ 1093 /* segment handling */
1223 1094
1224 -/* only works if protected mode and not VM86 */  
1225 -void load_seg(int seg_reg, int selector, unsigned cur_eip)  
1226 -{  
1227 - SegmentCache *sc;  
1228 - SegmentDescriptorTable *dt;  
1229 - int index;  
1230 - uint32_t e1, e2;  
1231 - uint8_t *ptr;  
1232 -  
1233 - sc = &env->seg_cache[seg_reg];  
1234 - if ((selector & 0xfffc) == 0) {  
1235 - /* null selector case */  
1236 - if (seg_reg == R_SS) {  
1237 - EIP = cur_eip;  
1238 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
1239 - } else {  
1240 - /* XXX: each access should trigger an exception */  
1241 - sc->base = NULL;  
1242 - sc->limit = 0;  
1243 - sc->seg_32bit = 1;  
1244 - }  
1245 - } else {  
1246 - if (selector & 0x4)  
1247 - dt = &env->ldt;  
1248 - else  
1249 - dt = &env->gdt;  
1250 - index = selector & ~7;  
1251 - if ((index + 7) > dt->limit) {  
1252 - EIP = cur_eip;  
1253 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
1254 - }  
1255 - ptr = dt->base + index;  
1256 - e1 = ldl(ptr);  
1257 - e2 = ldl(ptr + 4);  
1258 - if (!(e2 & DESC_S_MASK) ||  
1259 - (e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) {  
1260 - EIP = cur_eip;  
1261 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
1262 - }  
1263 -  
1264 - if (seg_reg == R_SS) {  
1265 - if ((e2 & (DESC_CS_MASK | DESC_W_MASK)) == 0) {  
1266 - EIP = cur_eip;  
1267 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
1268 - }  
1269 - } else {  
1270 - if ((e2 & (DESC_CS_MASK | DESC_R_MASK)) == DESC_CS_MASK) {  
1271 - EIP = cur_eip;  
1272 - raise_exception_err(EXCP0D_GPF, selector & 0xfffc);  
1273 - }  
1274 - }  
1275 -  
1276 - if (!(e2 & DESC_P_MASK)) {  
1277 - EIP = cur_eip;  
1278 - if (seg_reg == R_SS)  
1279 - raise_exception_err(EXCP0C_STACK, selector & 0xfffc);  
1280 - else  
1281 - raise_exception_err(EXCP0B_NOSEG, selector & 0xfffc);  
1282 - }  
1283 -  
1284 - sc->base = (void *)((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));  
1285 - sc->limit = (e1 & 0xffff) | (e2 & 0x000f0000);  
1286 - if (e2 & (1 << 23))  
1287 - sc->limit = (sc->limit << 12) | 0xfff;  
1288 - sc->seg_32bit = (e2 >> 22) & 1;  
1289 -#if 0  
1290 - fprintf(logfile, "load_seg: sel=0x%04x base=0x%08lx limit=0x%08lx seg_32bit=%d\n",  
1291 - selector, (unsigned long)sc->base, sc->limit, sc->seg_32bit);  
1292 -#endif  
1293 - }  
1294 - env->segs[seg_reg] = selector;  
1295 -}  
1296 -  
1297 void OPPROTO op_movl_seg_T0(void) 1095 void OPPROTO op_movl_seg_T0(void)
1298 { 1096 {
1299 load_seg(PARAM1, T0 & 0xffff, PARAM2); 1097 load_seg(PARAM1, T0 & 0xffff, PARAM2);
@@ -1326,61 +1124,11 @@ void OPPROTO op_addl_A0_seg(void) @@ -1326,61 +1124,11 @@ void OPPROTO op_addl_A0_seg(void)
1326 A0 += *(unsigned long *)((char *)env + PARAM1); 1124 A0 += *(unsigned long *)((char *)env + PARAM1);
1327 } 1125 }
1328 1126
1329 -void helper_lsl(void)  
1330 -{  
1331 - unsigned int selector, limit;  
1332 - SegmentDescriptorTable *dt;  
1333 - int index;  
1334 - uint32_t e1, e2;  
1335 - uint8_t *ptr;  
1336 -  
1337 - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;  
1338 - selector = T0 & 0xffff;  
1339 - if (selector & 0x4)  
1340 - dt = &env->ldt;  
1341 - else  
1342 - dt = &env->gdt;  
1343 - index = selector & ~7;  
1344 - if ((index + 7) > dt->limit)  
1345 - return;  
1346 - ptr = dt->base + index;  
1347 - e1 = ldl(ptr);  
1348 - e2 = ldl(ptr + 4);  
1349 - limit = (e1 & 0xffff) | (e2 & 0x000f0000);  
1350 - if (e2 & (1 << 23))  
1351 - limit = (limit << 12) | 0xfff;  
1352 - T1 = limit;  
1353 - CC_SRC |= CC_Z;  
1354 -}  
1355 -  
1356 void OPPROTO op_lsl(void) 1127 void OPPROTO op_lsl(void)
1357 { 1128 {
1358 helper_lsl(); 1129 helper_lsl();
1359 } 1130 }
1360 1131
1361 -void helper_lar(void)  
1362 -{  
1363 - unsigned int selector;  
1364 - SegmentDescriptorTable *dt;  
1365 - int index;  
1366 - uint32_t e2;  
1367 - uint8_t *ptr;  
1368 -  
1369 - CC_SRC = cc_table[CC_OP].compute_all() & ~CC_Z;  
1370 - selector = T0 & 0xffff;  
1371 - if (selector & 0x4)  
1372 - dt = &env->ldt;  
1373 - else  
1374 - dt = &env->gdt;  
1375 - index = selector & ~7;  
1376 - if ((index + 7) > dt->limit)  
1377 - return;  
1378 - ptr = dt->base + index;  
1379 - e2 = ldl(ptr + 4);  
1380 - T1 = e2 & 0x00f0ff00;  
1381 - CC_SRC |= CC_Z;  
1382 -}  
1383 -  
1384 void OPPROTO op_lar(void) 1132 void OPPROTO op_lar(void)
1385 { 1133 {
1386 helper_lar(); 1134 helper_lar();
@@ -1678,37 +1426,6 @@ CCTable cc_table[CC_OP_NB] = { @@ -1678,37 +1426,6 @@ CCTable cc_table[CC_OP_NB] = {
1678 functions comes from the LGPL'ed x86 emulator found in the Willows 1426 functions comes from the LGPL'ed x86 emulator found in the Willows
1679 TWIN windows emulator. */ 1427 TWIN windows emulator. */
1680 1428
1681 -#ifdef USE_X86LDOUBLE  
1682 -/* use long double functions */  
1683 -#define lrint lrintl  
1684 -#define llrint llrintl  
1685 -#define fabs fabsl  
1686 -#define sin sinl  
1687 -#define cos cosl  
1688 -#define sqrt sqrtl  
1689 -#define pow powl  
1690 -#define log logl  
1691 -#define tan tanl  
1692 -#define atan2 atan2l  
1693 -#define floor floorl  
1694 -#define ceil ceill  
1695 -#define rint rintl  
1696 -#endif  
1697 -  
1698 -extern int lrint(CPU86_LDouble x);  
1699 -extern int64_t llrint(CPU86_LDouble x);  
1700 -extern CPU86_LDouble fabs(CPU86_LDouble x);  
1701 -extern CPU86_LDouble sin(CPU86_LDouble x);  
1702 -extern CPU86_LDouble cos(CPU86_LDouble x);  
1703 -extern CPU86_LDouble sqrt(CPU86_LDouble x);  
1704 -extern CPU86_LDouble pow(CPU86_LDouble, CPU86_LDouble);  
1705 -extern CPU86_LDouble log(CPU86_LDouble x);  
1706 -extern CPU86_LDouble tan(CPU86_LDouble x);  
1707 -extern CPU86_LDouble atan2(CPU86_LDouble, CPU86_LDouble);  
1708 -extern CPU86_LDouble floor(CPU86_LDouble x);  
1709 -extern CPU86_LDouble ceil(CPU86_LDouble x);  
1710 -extern CPU86_LDouble rint(CPU86_LDouble x);  
1711 -  
1712 #if defined(__powerpc__) 1429 #if defined(__powerpc__)
1713 extern CPU86_LDouble copysign(CPU86_LDouble, CPU86_LDouble); 1430 extern CPU86_LDouble copysign(CPU86_LDouble, CPU86_LDouble);
1714 1431
@@ -1729,60 +1446,6 @@ double qemu_rint(double x) @@ -1729,60 +1446,6 @@ double qemu_rint(double x)
1729 #define rint qemu_rint 1446 #define rint qemu_rint
1730 #endif 1447 #endif
1731 1448
1732 -#define RC_MASK 0xc00  
1733 -#define RC_NEAR 0x000  
1734 -#define RC_DOWN 0x400  
1735 -#define RC_UP 0x800  
1736 -#define RC_CHOP 0xc00  
1737 -  
1738 -#define MAXTAN 9223372036854775808.0  
1739 -  
1740 -#ifdef USE_X86LDOUBLE  
1741 -  
1742 -/* only for x86 */  
1743 -typedef union {  
1744 - long double d;  
1745 - struct {  
1746 - unsigned long long lower;  
1747 - unsigned short upper;  
1748 - } l;  
1749 -} CPU86_LDoubleU;  
1750 -  
1751 -/* the following deal with x86 long double-precision numbers */  
1752 -#define MAXEXPD 0x7fff  
1753 -#define EXPBIAS 16383  
1754 -#define EXPD(fp) (fp.l.upper & 0x7fff)  
1755 -#define SIGND(fp) ((fp.l.upper) & 0x8000)  
1756 -#define MANTD(fp) (fp.l.lower)  
1757 -#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS  
1758 -  
1759 -#else  
1760 -  
1761 -typedef union {  
1762 - double d;  
1763 -#ifndef WORDS_BIGENDIAN  
1764 - struct {  
1765 - uint32_t lower;  
1766 - int32_t upper;  
1767 - } l;  
1768 -#else  
1769 - struct {  
1770 - int32_t upper;  
1771 - uint32_t lower;  
1772 - } l;  
1773 -#endif  
1774 - int64_t ll;  
1775 -} CPU86_LDoubleU;  
1776 -  
1777 -/* the following deal with IEEE double-precision numbers */  
1778 -#define MAXEXPD 0x7ff  
1779 -#define EXPBIAS 1023  
1780 -#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)  
1781 -#define SIGND(fp) ((fp.l.upper) & 0x80000000)  
1782 -#define MANTD(fp) (fp.ll & ((1LL << 52) - 1))  
1783 -#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20)  
1784 -#endif  
1785 -  
1786 /* fp load FT0 */ 1449 /* fp load FT0 */
1787 1450
1788 void OPPROTO op_flds_FT0_A0(void) 1451 void OPPROTO op_flds_FT0_A0(void)
@@ -1899,24 +1562,6 @@ void OPPROTO op_fldt_ST0_A0(void) @@ -1899,24 +1562,6 @@ void OPPROTO op_fldt_ST0_A0(void)
1899 ST0 = *(long double *)A0; 1562 ST0 = *(long double *)A0;
1900 } 1563 }
1901 #else 1564 #else
1902 -static inline CPU86_LDouble helper_fldt(uint8_t *ptr)  
1903 -{  
1904 - CPU86_LDoubleU temp;  
1905 - int upper, e;  
1906 - /* mantissa */  
1907 - upper = lduw(ptr + 8);  
1908 - /* XXX: handle overflow ? */  
1909 - e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */  
1910 - e |= (upper >> 4) & 0x800; /* sign */  
1911 - temp.ll = ((ldq(ptr) >> 11) & ((1LL << 52) - 1)) | ((uint64_t)e << 52);  
1912 - return temp.d;  
1913 -}  
1914 -  
1915 -void helper_fldt_ST0_A0(void)  
1916 -{  
1917 - ST0 = helper_fldt((uint8_t *)A0);  
1918 -}  
1919 -  
1920 void OPPROTO op_fldt_ST0_A0(void) 1565 void OPPROTO op_fldt_ST0_A0(void)
1921 { 1566 {
1922 helper_fldt_ST0_A0(); 1567 helper_fldt_ST0_A0();
@@ -2013,25 +1658,6 @@ void OPPROTO op_fstt_ST0_A0(void) @@ -2013,25 +1658,6 @@ void OPPROTO op_fstt_ST0_A0(void)
2013 *(long double *)A0 = ST0; 1658 *(long double *)A0 = ST0;
2014 } 1659 }
2015 #else 1660 #else
2016 -  
2017 -static inline void helper_fstt(CPU86_LDouble f, uint8_t *ptr)  
2018 -{  
2019 - CPU86_LDoubleU temp;  
2020 - int e;  
2021 - temp.d = f;  
2022 - /* mantissa */  
2023 - stq(ptr, (MANTD(temp) << 11) | (1LL << 63));  
2024 - /* exponent + sign */  
2025 - e = EXPD(temp) - EXPBIAS + 16383;  
2026 - e |= SIGND(temp) >> 16;  
2027 - stw(ptr + 8, e);  
2028 -}  
2029 -  
2030 -void helper_fstt_ST0_A0(void)  
2031 -{  
2032 - helper_fstt(ST0, (uint8_t *)A0);  
2033 -}  
2034 -  
2035 void OPPROTO op_fstt_ST0_A0(void) 1661 void OPPROTO op_fstt_ST0_A0(void)
2036 { 1662 {
2037 helper_fstt_ST0_A0(); 1663 helper_fstt_ST0_A0();
@@ -2080,98 +1706,11 @@ void OPPROTO op_fistll_ST0_A0(void) @@ -2080,98 +1706,11 @@ void OPPROTO op_fistll_ST0_A0(void)
2080 stq((void *)A0, val); 1706 stq((void *)A0, val);
2081 } 1707 }
2082 1708
2083 -/* BCD ops */  
2084 -  
2085 -#define MUL10(iv) ( iv + iv + (iv << 3) )  
2086 -  
2087 -void helper_fbld_ST0_A0(void)  
2088 -{  
2089 - uint8_t *seg;  
2090 - CPU86_LDouble fpsrcop;  
2091 - int m32i;  
2092 - unsigned int v;  
2093 -  
2094 - /* in this code, seg/m32i will be used as temporary ptr/int */  
2095 - seg = (uint8_t *)A0 + 8;  
2096 - v = ldub(seg--);  
2097 - /* XXX: raise exception */  
2098 - if (v != 0)  
2099 - return;  
2100 - v = ldub(seg--);  
2101 - /* XXX: raise exception */  
2102 - if ((v & 0xf0) != 0)  
2103 - return;  
2104 - m32i = v; /* <-- d14 */  
2105 - v = ldub(seg--);  
2106 - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d13 */  
2107 - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d12 */  
2108 - v = ldub(seg--);  
2109 - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d11 */  
2110 - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d10 */  
2111 - v = ldub(seg--);  
2112 - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d9 */  
2113 - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d8 */  
2114 - fpsrcop = ((CPU86_LDouble)m32i) * 100000000.0;  
2115 -  
2116 - v = ldub(seg--);  
2117 - m32i = (v >> 4); /* <-- d7 */  
2118 - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d6 */  
2119 - v = ldub(seg--);  
2120 - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d5 */  
2121 - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d4 */  
2122 - v = ldub(seg--);  
2123 - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d3 */  
2124 - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d2 */  
2125 - v = ldub(seg);  
2126 - m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d1 */  
2127 - m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d0 */  
2128 - fpsrcop += ((CPU86_LDouble)m32i);  
2129 - if ( ldub(seg+9) & 0x80 )  
2130 - fpsrcop = -fpsrcop;  
2131 - ST0 = fpsrcop;  
2132 -}  
2133 -  
2134 void OPPROTO op_fbld_ST0_A0(void) 1709 void OPPROTO op_fbld_ST0_A0(void)
2135 { 1710 {
2136 helper_fbld_ST0_A0(); 1711 helper_fbld_ST0_A0();
2137 } 1712 }
2138 1713
2139 -void helper_fbst_ST0_A0(void)  
2140 -{  
2141 - CPU86_LDouble fptemp;  
2142 - CPU86_LDouble fpsrcop;  
2143 - int v;  
2144 - uint8_t *mem_ref, *mem_end;  
2145 -  
2146 - fpsrcop = rint(ST0);  
2147 - mem_ref = (uint8_t *)A0;  
2148 - mem_end = mem_ref + 8;  
2149 - if ( fpsrcop < 0.0 ) {  
2150 - stw(mem_end, 0x8000);  
2151 - fpsrcop = -fpsrcop;  
2152 - } else {  
2153 - stw(mem_end, 0x0000);  
2154 - }  
2155 - while (mem_ref < mem_end) {  
2156 - if (fpsrcop == 0.0)  
2157 - break;  
2158 - fptemp = floor(fpsrcop/10.0);  
2159 - v = ((int)(fpsrcop - fptemp*10.0));  
2160 - if (fptemp == 0.0) {  
2161 - stb(mem_ref++, v);  
2162 - break;  
2163 - }  
2164 - fpsrcop = fptemp;  
2165 - fptemp = floor(fpsrcop/10.0);  
2166 - v |= (((int)(fpsrcop - fptemp*10.0)) << 4);  
2167 - stb(mem_ref++, v);  
2168 - fpsrcop = fptemp;  
2169 - }  
2170 - while (mem_ref < mem_end) {  
2171 - stb(mem_ref++, 0);  
2172 - }  
2173 -}  
2174 -  
2175 void OPPROTO op_fbst_ST0_A0(void) 1714 void OPPROTO op_fbst_ST0_A0(void)
2176 { 1715 {
2177 helper_fbst_ST0_A0(); 1716 helper_fbst_ST0_A0();
@@ -2179,18 +1718,6 @@ void OPPROTO op_fbst_ST0_A0(void) @@ -2179,18 +1718,6 @@ void OPPROTO op_fbst_ST0_A0(void)
2179 1718
2180 /* FPU move */ 1719 /* FPU move */
2181 1720
2182 -static inline void fpush(void)  
2183 -{  
2184 - env->fpstt = (env->fpstt - 1) & 7;  
2185 - env->fptags[env->fpstt] = 0; /* validate stack entry */  
2186 -}  
2187 -  
2188 -static inline void fpop(void)  
2189 -{  
2190 - env->fptags[env->fpstt] = 1; /* invvalidate stack entry */  
2191 - env->fpstt = (env->fpstt + 1) & 7;  
2192 -}  
2193 -  
2194 void OPPROTO op_fpush(void) 1721 void OPPROTO op_fpush(void)
2195 { 1722 {
2196 fpush(); 1723 fpush();
@@ -2370,33 +1897,6 @@ void OPPROTO op_fabs_ST0(void) @@ -2370,33 +1897,6 @@ void OPPROTO op_fabs_ST0(void)
2370 ST0 = fabs(ST0); 1897 ST0 = fabs(ST0);
2371 } 1898 }
2372 1899
2373 -void helper_fxam_ST0(void)  
2374 -{  
2375 - CPU86_LDoubleU temp;  
2376 - int expdif;  
2377 -  
2378 - temp.d = ST0;  
2379 -  
2380 - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */  
2381 - if (SIGND(temp))  
2382 - env->fpus |= 0x200; /* C1 <-- 1 */  
2383 -  
2384 - expdif = EXPD(temp);  
2385 - if (expdif == MAXEXPD) {  
2386 - if (MANTD(temp) == 0)  
2387 - env->fpus |= 0x500 /*Infinity*/;  
2388 - else  
2389 - env->fpus |= 0x100 /*NaN*/;  
2390 - } else if (expdif == 0) {  
2391 - if (MANTD(temp) == 0)  
2392 - env->fpus |= 0x4000 /*Zero*/;  
2393 - else  
2394 - env->fpus |= 0x4400 /*Denormal*/;  
2395 - } else {  
2396 - env->fpus |= 0x400;  
2397 - }  
2398 -}  
2399 -  
2400 void OPPROTO op_fxam_ST0(void) 1900 void OPPROTO op_fxam_ST0(void)
2401 { 1901 {
2402 helper_fxam_ST0(); 1902 helper_fxam_ST0();
@@ -2442,217 +1942,6 @@ void OPPROTO op_fldz_FT0(void) @@ -2442,217 +1942,6 @@ void OPPROTO op_fldz_FT0(void)
2442 ST0 = *(CPU86_LDouble *)&f15rk[0]; 1942 ST0 = *(CPU86_LDouble *)&f15rk[0];
2443 } 1943 }
2444 1944
2445 -void helper_f2xm1(void)  
2446 -{  
2447 - ST0 = pow(2.0,ST0) - 1.0;  
2448 -}  
2449 -  
2450 -void helper_fyl2x(void)  
2451 -{  
2452 - CPU86_LDouble fptemp;  
2453 -  
2454 - fptemp = ST0;  
2455 - if (fptemp>0.0){  
2456 - fptemp = log(fptemp)/log(2.0); /* log2(ST) */  
2457 - ST1 *= fptemp;  
2458 - fpop();  
2459 - } else {  
2460 - env->fpus &= (~0x4700);  
2461 - env->fpus |= 0x400;  
2462 - }  
2463 -}  
2464 -  
2465 -void helper_fptan(void)  
2466 -{  
2467 - CPU86_LDouble fptemp;  
2468 -  
2469 - fptemp = ST0;  
2470 - if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {  
2471 - env->fpus |= 0x400;  
2472 - } else {  
2473 - ST0 = tan(fptemp);  
2474 - fpush();  
2475 - ST0 = 1.0;  
2476 - env->fpus &= (~0x400); /* C2 <-- 0 */  
2477 - /* the above code is for |arg| < 2**52 only */  
2478 - }  
2479 -}  
2480 -  
2481 -void helper_fpatan(void)  
2482 -{  
2483 - CPU86_LDouble fptemp, fpsrcop;  
2484 -  
2485 - fpsrcop = ST1;  
2486 - fptemp = ST0;  
2487 - ST1 = atan2(fpsrcop,fptemp);  
2488 - fpop();  
2489 -}  
2490 -  
2491 -void helper_fxtract(void)  
2492 -{  
2493 - CPU86_LDoubleU temp;  
2494 - unsigned int expdif;  
2495 -  
2496 - temp.d = ST0;  
2497 - expdif = EXPD(temp) - EXPBIAS;  
2498 - /*DP exponent bias*/  
2499 - ST0 = expdif;  
2500 - fpush();  
2501 - BIASEXPONENT(temp);  
2502 - ST0 = temp.d;  
2503 -}  
2504 -  
2505 -void helper_fprem1(void)  
2506 -{  
2507 - CPU86_LDouble dblq, fpsrcop, fptemp;  
2508 - CPU86_LDoubleU fpsrcop1, fptemp1;  
2509 - int expdif;  
2510 - int q;  
2511 -  
2512 - fpsrcop = ST0;  
2513 - fptemp = ST1;  
2514 - fpsrcop1.d = fpsrcop;  
2515 - fptemp1.d = fptemp;  
2516 - expdif = EXPD(fpsrcop1) - EXPD(fptemp1);  
2517 - if (expdif < 53) {  
2518 - dblq = fpsrcop / fptemp;  
2519 - dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);  
2520 - ST0 = fpsrcop - fptemp*dblq;  
2521 - q = (int)dblq; /* cutting off top bits is assumed here */  
2522 - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */  
2523 - /* (C0,C1,C3) <-- (q2,q1,q0) */  
2524 - env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */  
2525 - env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */  
2526 - env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */  
2527 - } else {  
2528 - env->fpus |= 0x400; /* C2 <-- 1 */  
2529 - fptemp = pow(2.0, expdif-50);  
2530 - fpsrcop = (ST0 / ST1) / fptemp;  
2531 - /* fpsrcop = integer obtained by rounding to the nearest */  
2532 - fpsrcop = (fpsrcop-floor(fpsrcop) < ceil(fpsrcop)-fpsrcop)?  
2533 - floor(fpsrcop): ceil(fpsrcop);  
2534 - ST0 -= (ST1 * fpsrcop * fptemp);  
2535 - }  
2536 -}  
2537 -  
2538 -void helper_fprem(void)  
2539 -{  
2540 - CPU86_LDouble dblq, fpsrcop, fptemp;  
2541 - CPU86_LDoubleU fpsrcop1, fptemp1;  
2542 - int expdif;  
2543 - int q;  
2544 -  
2545 - fpsrcop = ST0;  
2546 - fptemp = ST1;  
2547 - fpsrcop1.d = fpsrcop;  
2548 - fptemp1.d = fptemp;  
2549 - expdif = EXPD(fpsrcop1) - EXPD(fptemp1);  
2550 - if ( expdif < 53 ) {  
2551 - dblq = fpsrcop / fptemp;  
2552 - dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);  
2553 - ST0 = fpsrcop - fptemp*dblq;  
2554 - q = (int)dblq; /* cutting off top bits is assumed here */  
2555 - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */  
2556 - /* (C0,C1,C3) <-- (q2,q1,q0) */  
2557 - env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */  
2558 - env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */  
2559 - env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */  
2560 - } else {  
2561 - env->fpus |= 0x400; /* C2 <-- 1 */  
2562 - fptemp = pow(2.0, expdif-50);  
2563 - fpsrcop = (ST0 / ST1) / fptemp;  
2564 - /* fpsrcop = integer obtained by chopping */  
2565 - fpsrcop = (fpsrcop < 0.0)?  
2566 - -(floor(fabs(fpsrcop))): floor(fpsrcop);  
2567 - ST0 -= (ST1 * fpsrcop * fptemp);  
2568 - }  
2569 -}  
2570 -  
2571 -void helper_fyl2xp1(void)  
2572 -{  
2573 - CPU86_LDouble fptemp;  
2574 -  
2575 - fptemp = ST0;  
2576 - if ((fptemp+1.0)>0.0) {  
2577 - fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */  
2578 - ST1 *= fptemp;  
2579 - fpop();  
2580 - } else {  
2581 - env->fpus &= (~0x4700);  
2582 - env->fpus |= 0x400;  
2583 - }  
2584 -}  
2585 -  
2586 -void helper_fsqrt(void)  
2587 -{  
2588 - CPU86_LDouble fptemp;  
2589 -  
2590 - fptemp = ST0;  
2591 - if (fptemp<0.0) {  
2592 - env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */  
2593 - env->fpus |= 0x400;  
2594 - }  
2595 - ST0 = sqrt(fptemp);  
2596 -}  
2597 -  
2598 -void helper_fsincos(void)  
2599 -{  
2600 - CPU86_LDouble fptemp;  
2601 -  
2602 - fptemp = ST0;  
2603 - if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {  
2604 - env->fpus |= 0x400;  
2605 - } else {  
2606 - ST0 = sin(fptemp);  
2607 - fpush();  
2608 - ST0 = cos(fptemp);  
2609 - env->fpus &= (~0x400); /* C2 <-- 0 */  
2610 - /* the above code is for |arg| < 2**63 only */  
2611 - }  
2612 -}  
2613 -  
2614 -void helper_frndint(void)  
2615 -{  
2616 - ST0 = rint(ST0);  
2617 -}  
2618 -  
2619 -void helper_fscale(void)  
2620 -{  
2621 - CPU86_LDouble fpsrcop, fptemp;  
2622 -  
2623 - fpsrcop = 2.0;  
2624 - fptemp = pow(fpsrcop,ST1);  
2625 - ST0 *= fptemp;  
2626 -}  
2627 -  
2628 -void helper_fsin(void)  
2629 -{  
2630 - CPU86_LDouble fptemp;  
2631 -  
2632 - fptemp = ST0;  
2633 - if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {  
2634 - env->fpus |= 0x400;  
2635 - } else {  
2636 - ST0 = sin(fptemp);  
2637 - env->fpus &= (~0x400); /* C2 <-- 0 */  
2638 - /* the above code is for |arg| < 2**53 only */  
2639 - }  
2640 -}  
2641 -  
2642 -void helper_fcos(void)  
2643 -{  
2644 - CPU86_LDouble fptemp;  
2645 -  
2646 - fptemp = ST0;  
2647 - if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {  
2648 - env->fpus |= 0x400;  
2649 - } else {  
2650 - ST0 = cos(fptemp);  
2651 - env->fpus &= (~0x400); /* C2 <-- 0 */  
2652 - /* the above code is for |arg5 < 2**63 only */  
2653 - }  
2654 -}  
2655 -  
2656 /* associated heplers to reduce generated code length and to simplify 1945 /* associated heplers to reduce generated code length and to simplify
2657 relocation (FP constants are usually stored in .rodata section) */ 1946 relocation (FP constants are usually stored in .rodata section) */
2658 1947
@@ -2789,129 +2078,6 @@ void OPPROTO op_fninit(void) @@ -2789,129 +2078,6 @@ void OPPROTO op_fninit(void)
2789 env->fptags[7] = 1; 2078 env->fptags[7] = 1;
2790 } 2079 }
2791 2080
2792 -void helper_fstenv(uint8_t *ptr, int data32)  
2793 -{  
2794 - int fpus, fptag, exp, i;  
2795 - uint64_t mant;  
2796 - CPU86_LDoubleU tmp;  
2797 -  
2798 - fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;  
2799 - fptag = 0;  
2800 - for (i=7; i>=0; i--) {  
2801 - fptag <<= 2;  
2802 - if (env->fptags[i]) {  
2803 - fptag |= 3;  
2804 - } else {  
2805 - tmp.d = env->fpregs[i];  
2806 - exp = EXPD(tmp);  
2807 - mant = MANTD(tmp);  
2808 - if (exp == 0 && mant == 0) {  
2809 - /* zero */  
2810 - fptag |= 1;  
2811 - } else if (exp == 0 || exp == MAXEXPD  
2812 -#ifdef USE_X86LDOUBLE  
2813 - || (mant & (1LL << 63)) == 0  
2814 -#endif  
2815 - ) {  
2816 - /* NaNs, infinity, denormal */  
2817 - fptag |= 2;  
2818 - }  
2819 - }  
2820 - }  
2821 - if (data32) {  
2822 - /* 32 bit */  
2823 - stl(ptr, env->fpuc);  
2824 - stl(ptr + 4, fpus);  
2825 - stl(ptr + 8, fptag);  
2826 - stl(ptr + 12, 0);  
2827 - stl(ptr + 16, 0);  
2828 - stl(ptr + 20, 0);  
2829 - stl(ptr + 24, 0);  
2830 - } else {  
2831 - /* 16 bit */  
2832 - stw(ptr, env->fpuc);  
2833 - stw(ptr + 2, fpus);  
2834 - stw(ptr + 4, fptag);  
2835 - stw(ptr + 6, 0);  
2836 - stw(ptr + 8, 0);  
2837 - stw(ptr + 10, 0);  
2838 - stw(ptr + 12, 0);  
2839 - }  
2840 -}  
2841 -  
2842 -void helper_fldenv(uint8_t *ptr, int data32)  
2843 -{  
2844 - int i, fpus, fptag;  
2845 -  
2846 - if (data32) {  
2847 - env->fpuc = lduw(ptr);  
2848 - fpus = lduw(ptr + 4);  
2849 - fptag = lduw(ptr + 8);  
2850 - }  
2851 - else {  
2852 - env->fpuc = lduw(ptr);  
2853 - fpus = lduw(ptr + 2);  
2854 - fptag = lduw(ptr + 4);  
2855 - }  
2856 - env->fpstt = (fpus >> 11) & 7;  
2857 - env->fpus = fpus & ~0x3800;  
2858 - for(i = 0;i < 7; i++) {  
2859 - env->fptags[i] = ((fptag & 3) == 3);  
2860 - fptag >>= 2;  
2861 - }  
2862 -}  
2863 -  
2864 -void helper_fsave(uint8_t *ptr, int data32)  
2865 -{  
2866 - CPU86_LDouble tmp;  
2867 - int i;  
2868 -  
2869 - helper_fstenv(ptr, data32);  
2870 -  
2871 - ptr += (14 << data32);  
2872 - for(i = 0;i < 8; i++) {  
2873 - tmp = ST(i);  
2874 -#ifdef USE_X86LDOUBLE  
2875 - *(long double *)ptr = tmp;  
2876 -#else  
2877 - helper_fstt(tmp, ptr);  
2878 -#endif  
2879 - ptr += 10;  
2880 - }  
2881 -  
2882 - /* fninit */  
2883 - env->fpus = 0;  
2884 - env->fpstt = 0;  
2885 - env->fpuc = 0x37f;  
2886 - env->fptags[0] = 1;  
2887 - env->fptags[1] = 1;  
2888 - env->fptags[2] = 1;  
2889 - env->fptags[3] = 1;  
2890 - env->fptags[4] = 1;  
2891 - env->fptags[5] = 1;  
2892 - env->fptags[6] = 1;  
2893 - env->fptags[7] = 1;  
2894 -}  
2895 -  
2896 -void helper_frstor(uint8_t *ptr, int data32)  
2897 -{  
2898 - CPU86_LDouble tmp;  
2899 - int i;  
2900 -  
2901 - helper_fldenv(ptr, data32);  
2902 - ptr += (14 << data32);  
2903 -  
2904 - for(i = 0;i < 8; i++) {  
2905 -#ifdef USE_X86LDOUBLE  
2906 - tmp = *(long double *)ptr;  
2907 -#else  
2908 - tmp = helper_fldt(ptr);  
2909 -#endif  
2910 - ST(i) = tmp;  
2911 - ptr += 10;  
2912 - }  
2913 -}  
2914 -  
2915 void OPPROTO op_fnstenv_A0(void) 2081 void OPPROTO op_fnstenv_A0(void)
2916 { 2082 {
2917 helper_fstenv((uint8_t *)A0, PARAM1); 2083 helper_fstenv((uint8_t *)A0, PARAM1);
@@ -2942,3 +2108,4 @@ void OPPROTO op_unlock(void) @@ -2942,3 +2108,4 @@ void OPPROTO op_unlock(void)
2942 { 2108 {
2943 cpu_unlock(); 2109 cpu_unlock();
2944 } 2110 }
  2111 +