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 190 #endif
191 191  
192 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 200 /* Suggested by Richard Henderson. This will result in code like
194 201 ldah $0,__op_param1($29) !gprelhigh
195 202 lda $0,__op_param1($0) !gprellow
196 203 We can then conveniently change $29 to $31 and adapt the offsets to
197 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 208 #define PARAM1 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param1)); _r; })
202 209 #define PARAM2 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param2)); _r; })
203 210 #define PARAM3 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param3)); _r; })
... ... @@ -220,15 +227,173 @@ typedef struct CCTable {
220 227 extern CCTable cc_table[];
221 228  
222 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 232 void raise_interrupt(int intno, int is_int, int error_code,
226 233 unsigned int next_eip);
227 234 void raise_exception_err(int exception_index, int error_code);
228 235 void raise_exception(int exception_index);
229   -void cpu_loop_exit(void);
  236 +void __hidden cpu_loop_exit(void);
230 237 void helper_fsave(uint8_t *ptr, int data32);
231 238 void helper_frstor(uint8_t *ptr, int data32);
232 239  
233 240 void OPPROTO op_movl_eflags_T0(void);
234 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 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 629 void OPPROTO op_raise_interrupt(void)
719 630 {
720 631 int intno;
... ... @@ -833,7 +744,7 @@ label ## n:\
833 744 #define JUMP_TB(tbparam, n, eip)\
834 745 do {\
835 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 748 label ## n:\
838 749 T0 = (long)(tbparam) + (n);\
839 750 EIP = eip;\
... ... @@ -1044,46 +955,6 @@ void OPPROTO op_rdtsc(void)
1044 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 958 void OPPROTO op_cpuid(void)
1088 959 {
1089 960 helper_cpuid();
... ... @@ -1221,79 +1092,6 @@ void OPPROTO op_das(void)
1221 1092  
1222 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 1095 void OPPROTO op_movl_seg_T0(void)
1298 1096 {
1299 1097 load_seg(PARAM1, T0 & 0xffff, PARAM2);
... ... @@ -1326,61 +1124,11 @@ void OPPROTO op_addl_A0_seg(void)
1326 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 1127 void OPPROTO op_lsl(void)
1357 1128 {
1358 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 1132 void OPPROTO op_lar(void)
1385 1133 {
1386 1134 helper_lar();
... ... @@ -1678,37 +1426,6 @@ CCTable cc_table[CC_OP_NB] = {
1678 1426 functions comes from the LGPL'ed x86 emulator found in the Willows
1679 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 1429 #if defined(__powerpc__)
1713 1430 extern CPU86_LDouble copysign(CPU86_LDouble, CPU86_LDouble);
1714 1431  
... ... @@ -1729,60 +1446,6 @@ double qemu_rint(double x)
1729 1446 #define rint qemu_rint
1730 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 1449 /* fp load FT0 */
1787 1450  
1788 1451 void OPPROTO op_flds_FT0_A0(void)
... ... @@ -1899,24 +1562,6 @@ void OPPROTO op_fldt_ST0_A0(void)
1899 1562 ST0 = *(long double *)A0;
1900 1563 }
1901 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 1565 void OPPROTO op_fldt_ST0_A0(void)
1921 1566 {
1922 1567 helper_fldt_ST0_A0();
... ... @@ -2013,25 +1658,6 @@ void OPPROTO op_fstt_ST0_A0(void)
2013 1658 *(long double *)A0 = ST0;
2014 1659 }
2015 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 1661 void OPPROTO op_fstt_ST0_A0(void)
2036 1662 {
2037 1663 helper_fstt_ST0_A0();
... ... @@ -2080,98 +1706,11 @@ void OPPROTO op_fistll_ST0_A0(void)
2080 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 1709 void OPPROTO op_fbld_ST0_A0(void)
2135 1710 {
2136 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 1714 void OPPROTO op_fbst_ST0_A0(void)
2176 1715 {
2177 1716 helper_fbst_ST0_A0();
... ... @@ -2179,18 +1718,6 @@ void OPPROTO op_fbst_ST0_A0(void)
2179 1718  
2180 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 1721 void OPPROTO op_fpush(void)
2195 1722 {
2196 1723 fpush();
... ... @@ -2370,33 +1897,6 @@ void OPPROTO op_fabs_ST0(void)
2370 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 1900 void OPPROTO op_fxam_ST0(void)
2401 1901 {
2402 1902 helper_fxam_ST0();
... ... @@ -2442,217 +1942,6 @@ void OPPROTO op_fldz_FT0(void)
2442 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 1945 /* associated heplers to reduce generated code length and to simplify
2657 1946 relocation (FP constants are usually stored in .rodata section) */
2658 1947  
... ... @@ -2789,129 +2078,6 @@ void OPPROTO op_fninit(void)
2789 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 2081 void OPPROTO op_fnstenv_A0(void)
2916 2082 {
2917 2083 helper_fstenv((uint8_t *)A0, PARAM1);
... ... @@ -2942,3 +2108,4 @@ void OPPROTO op_unlock(void)
2942 2108 {
2943 2109 cpu_unlock();
2944 2110 }
  2111 +
... ...