float fixes - added bsr/bsf support
[qemu] / op-i386.c
1 #define DEBUG_EXEC
2
3 typedef unsigned char uint8_t;
4 typedef unsigned short uint16_t;
5 typedef unsigned int uint32_t;
6 typedef unsigned long long uint64_t;
7
8 typedef signed char int8_t;
9 typedef signed short int16_t;
10 typedef signed int int32_t;
11 typedef signed long long int64_t;
12
13 #define bswap32(x) \
14 ({ \
15         uint32_t __x = (x); \
16         ((uint32_t)( \
17                 (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
18                 (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) <<  8) | \
19                 (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >>  8) | \
20                 (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
21 })
22
23 #define NULL 0
24 #include <fenv.h>
25
26 typedef struct FILE FILE;
27 extern FILE *logfile;
28 extern int loglevel;
29 extern int fprintf(FILE *, const char *, ...);
30
31 #ifdef __i386__
32 register unsigned int T0 asm("ebx");
33 register unsigned int T1 asm("esi");
34 register unsigned int A0 asm("edi");
35 register struct CPUX86State *env asm("ebp");
36 #endif
37 #ifdef __powerpc__
38 register unsigned int T0 asm("r24");
39 register unsigned int T1 asm("r25");
40 register unsigned int A0 asm("r26");
41 register struct CPUX86State *env asm("r27");
42 #endif
43 #ifdef __arm__
44 register unsigned int T0 asm("r4");
45 register unsigned int T1 asm("r5");
46 register unsigned int A0 asm("r6");
47 register struct CPUX86State *env asm("r7");
48 #endif
49 #ifdef __mips__
50 register unsigned int T0 asm("s0");
51 register unsigned int T1 asm("s1");
52 register unsigned int A0 asm("s2");
53 register struct CPUX86State *env asm("s3");
54 #endif
55 #ifdef __sparc__
56 register unsigned int T0 asm("l0");
57 register unsigned int T1 asm("l1");
58 register unsigned int A0 asm("l2");
59 register struct CPUX86State *env asm("l3");
60 #endif
61
62 /* force GCC to generate only one epilog at the end of the function */
63 #define FORCE_RET() asm volatile ("");
64
65 #ifndef OPPROTO
66 #define OPPROTO
67 #endif
68
69 #define xglue(x, y) x ## y
70 #define glue(x, y) xglue(x, y)
71
72 #define EAX (env->regs[R_EAX])
73 #define ECX (env->regs[R_ECX])
74 #define EDX (env->regs[R_EDX])
75 #define EBX (env->regs[R_EBX])
76 #define ESP (env->regs[R_ESP])
77 #define EBP (env->regs[R_EBP])
78 #define ESI (env->regs[R_ESI])
79 #define EDI (env->regs[R_EDI])
80 #define PC  (env->pc)
81 #define DF  (env->df)
82
83 #define CC_SRC (env->cc_src)
84 #define CC_DST (env->cc_dst)
85 #define CC_OP  (env->cc_op)
86
87 /* float macros */
88 #define FT0    (env->ft0)
89 #define ST0    (env->fpregs[env->fpstt])
90 #define ST(n)  (env->fpregs[(env->fpstt + (n)) & 7])
91 #define ST1    ST(1)
92
93 extern int __op_param1, __op_param2, __op_param3;
94 #define PARAM1 ((long)(&__op_param1))
95 #define PARAM2 ((long)(&__op_param2))
96 #define PARAM3 ((long)(&__op_param3))
97
98 #include "cpu-i386.h"
99
100 typedef struct CCTable {
101     int (*compute_all)(void); /* return all the flags */
102     int (*compute_c)(void);  /* return the C flag */
103 } CCTable;
104
105 /* NOTE: data are not static to force relocation generation by GCC */
106 extern CCTable cc_table[];
107
108 uint8_t parity_table[256] = {
109     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
110     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
111     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
112     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
113     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
114     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
115     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
116     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
117     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
118     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
119     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
120     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
121     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
122     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
123     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
124     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
125     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
126     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
127     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
128     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
129     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
130     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
131     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
132     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
133     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
134     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
135     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
136     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
137     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
138     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
139     CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
140     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
141 };
142
143 /* modulo 17 table */
144 const uint8_t rclw_table[32] = {
145     0, 1, 2, 3, 4, 5, 6, 7, 
146     8, 9,10,11,12,13,14,15,
147    16, 0, 1, 2, 3, 4, 5, 6,
148     7, 8, 9,10,11,12,13,14,
149 };
150
151 /* modulo 9 table */
152 const uint8_t rclb_table[32] = {
153     0, 1, 2, 3, 4, 5, 6, 7, 
154     8, 0, 1, 2, 3, 4, 5, 6,
155     7, 8, 0, 1, 2, 3, 4, 5, 
156     6, 7, 8, 0, 1, 2, 3, 4,
157 };
158
159 #ifdef USE_X86LDOUBLE
160 /* an array of Intel 80-bit FP constants, to be loaded via integer ops */
161 typedef unsigned short f15ld[5];
162 const f15ld f15rk[] =
163 {
164 /*0*/   {0x0000,0x0000,0x0000,0x0000,0x0000},
165 /*1*/   {0x0000,0x0000,0x0000,0x8000,0x3fff},
166 /*pi*/  {0xc235,0x2168,0xdaa2,0xc90f,0x4000},
167 /*lg2*/ {0xf799,0xfbcf,0x9a84,0x9a20,0x3ffd},
168 /*ln2*/ {0x79ac,0xd1cf,0x17f7,0xb172,0x3ffe},
169 /*l2e*/ {0xf0bc,0x5c17,0x3b29,0xb8aa,0x3fff},
170 /*l2t*/ {0x8afe,0xcd1b,0x784b,0xd49a,0x4000}
171 };
172 #else
173 /* the same, 64-bit version */
174 typedef unsigned short f15ld[4];
175 const f15ld f15rk[] =
176 {
177 #ifndef WORDS_BIGENDIAN
178 /*0*/   {0x0000,0x0000,0x0000,0x0000},
179 /*1*/   {0x0000,0x0000,0x0000,0x3ff0},
180 /*pi*/  {0x2d18,0x5444,0x21fb,0x4009},
181 /*lg2*/ {0x79ff,0x509f,0x4413,0x3fd3},
182 /*ln2*/ {0x39ef,0xfefa,0x2e42,0x3fe6},
183 /*l2e*/ {0x82fe,0x652b,0x1547,0x3ff7},
184 /*l2t*/ {0xa371,0x0979,0x934f,0x400a}
185 #else
186 /*0*/   {0x0000,0x0000,0x0000,0x0000},
187 /*1*/   {0x3ff0,0x0000,0x0000,0x0000},
188 /*pi*/  {0x4009,0x21fb,0x5444,0x2d18},
189 /*lg2*/ {0x3fd3,0x4413,0x509f,0x79ff},
190 /*ln2*/ {0x3fe6,0x2e42,0xfefa,0x39ef},
191 /*l2e*/ {0x3ff7,0x1547,0x652b,0x82fe},
192 /*l2t*/ {0x400a,0x934f,0x0979,0xa371}
193 #endif
194 };
195 #endif
196     
197 /* n must be a constant to be efficient */
198 static inline int lshift(int x, int n)
199 {
200     if (n >= 0)
201         return x << n;
202     else
203         return x >> (-n);
204 }
205
206 /* exception support */
207 /* NOTE: not static to force relocation generation by GCC */
208 void raise_exception(int exception_index)
209 {
210     env->exception_index = exception_index;
211     longjmp(env->jmp_env, 1);
212 }
213
214 /* we define the various pieces of code used by the JIT */
215
216 #define REG EAX
217 #define REGNAME _EAX
218 #include "opreg_template.h"
219 #undef REG
220 #undef REGNAME
221
222 #define REG ECX
223 #define REGNAME _ECX
224 #include "opreg_template.h"
225 #undef REG
226 #undef REGNAME
227
228 #define REG EDX
229 #define REGNAME _EDX
230 #include "opreg_template.h"
231 #undef REG
232 #undef REGNAME
233
234 #define REG EBX
235 #define REGNAME _EBX
236 #include "opreg_template.h"
237 #undef REG
238 #undef REGNAME
239
240 #define REG ESP
241 #define REGNAME _ESP
242 #include "opreg_template.h"
243 #undef REG
244 #undef REGNAME
245
246 #define REG EBP
247 #define REGNAME _EBP
248 #include "opreg_template.h"
249 #undef REG
250 #undef REGNAME
251
252 #define REG ESI
253 #define REGNAME _ESI
254 #include "opreg_template.h"
255 #undef REG
256 #undef REGNAME
257
258 #define REG EDI
259 #define REGNAME _EDI
260 #include "opreg_template.h"
261 #undef REG
262 #undef REGNAME
263
264 /* operations */
265
266 void OPPROTO op_addl_T0_T1_cc(void)
267 {
268     CC_SRC = T0;
269     T0 += T1;
270     CC_DST = T0;
271 }
272
273 void OPPROTO op_orl_T0_T1_cc(void)
274 {
275     T0 |= T1;
276     CC_DST = T0;
277 }
278
279 void OPPROTO op_andl_T0_T1_cc(void)
280 {
281     T0 &= T1;
282     CC_DST = T0;
283 }
284
285 void OPPROTO op_subl_T0_T1_cc(void)
286 {
287     CC_SRC = T0;
288     T0 -= T1;
289     CC_DST = T0;
290 }
291
292 void OPPROTO op_xorl_T0_T1_cc(void)
293 {
294     T0 ^= T1;
295     CC_DST = T0;
296 }
297
298 void OPPROTO op_cmpl_T0_T1_cc(void)
299 {
300     CC_SRC = T0;
301     CC_DST = T0 - T1;
302 }
303
304 void OPPROTO op_notl_T0(void)
305 {
306     T0 = ~T0;
307 }
308
309 void OPPROTO op_negl_T0_cc(void)
310 {
311     CC_SRC = 0;
312     T0 = -T0;
313     CC_DST = T0;
314 }
315
316 void OPPROTO op_incl_T0_cc(void)
317 {
318     CC_SRC = cc_table[CC_OP].compute_c();
319     T0++;
320     CC_DST = T0;
321 }
322
323 void OPPROTO op_decl_T0_cc(void)
324 {
325     CC_SRC = cc_table[CC_OP].compute_c();
326     T0--;
327     CC_DST = T0;
328 }
329
330 void OPPROTO op_testl_T0_T1_cc(void)
331 {
332     CC_DST = T0 & T1;
333 }
334
335 void OPPROTO op_bswapl_T0(void)
336 {
337     T0 = bswap32(T0);
338 }
339
340 /* multiply/divide */
341 void OPPROTO op_mulb_AL_T0(void)
342 {
343     unsigned int res;
344     res = (uint8_t)EAX * (uint8_t)T0;
345     EAX = (EAX & 0xffff0000) | res;
346     CC_SRC = (res & 0xff00);
347 }
348
349 void OPPROTO op_imulb_AL_T0(void)
350 {
351     int res;
352     res = (int8_t)EAX * (int8_t)T0;
353     EAX = (EAX & 0xffff0000) | (res & 0xffff);
354     CC_SRC = (res != (int8_t)res);
355 }
356
357 void OPPROTO op_mulw_AX_T0(void)
358 {
359     unsigned int res;
360     res = (uint16_t)EAX * (uint16_t)T0;
361     EAX = (EAX & 0xffff0000) | (res & 0xffff);
362     EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff);
363     CC_SRC = res >> 16;
364 }
365
366 void OPPROTO op_imulw_AX_T0(void)
367 {
368     int res;
369     res = (int16_t)EAX * (int16_t)T0;
370     EAX = (EAX & 0xffff0000) | (res & 0xffff);
371     EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff);
372     CC_SRC = (res != (int16_t)res);
373 }
374
375 void OPPROTO op_mull_EAX_T0(void)
376 {
377     uint64_t res;
378     res = (uint64_t)((uint32_t)EAX) * (uint64_t)((uint32_t)T0);
379     EAX = res;
380     EDX = res >> 32;
381     CC_SRC = res >> 32;
382 }
383
384 void OPPROTO op_imull_EAX_T0(void)
385 {
386     int64_t res;
387     res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T0);
388     EAX = res;
389     EDX = res >> 32;
390     CC_SRC = (res != (int32_t)res);
391 }
392
393 void OPPROTO op_imulw_T0_T1(void)
394 {
395     int res;
396     res = (int16_t)T0 * (int16_t)T1;
397     T0 = res;
398     CC_SRC = (res != (int16_t)res);
399 }
400
401 void OPPROTO op_imull_T0_T1(void)
402 {
403     int64_t res;
404     res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
405     T0 = res;
406     CC_SRC = (res != (int32_t)res);
407 }
408
409 /* division, flags are undefined */
410 /* XXX: add exceptions for overflow & div by zero */
411 void OPPROTO op_divb_AL_T0(void)
412 {
413     unsigned int num, den, q, r;
414
415     num = (EAX & 0xffff);
416     den = (T0 & 0xff);
417     q = (num / den) & 0xff;
418     r = (num % den) & 0xff;
419     EAX = (EAX & 0xffff0000) | (r << 8) | q;
420 }
421
422 void OPPROTO op_idivb_AL_T0(void)
423 {
424     int num, den, q, r;
425
426     num = (int16_t)EAX;
427     den = (int8_t)T0;
428     q = (num / den) & 0xff;
429     r = (num % den) & 0xff;
430     EAX = (EAX & 0xffff0000) | (r << 8) | q;
431 }
432
433 void OPPROTO op_divw_AX_T0(void)
434 {
435     unsigned int num, den, q, r;
436
437     num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
438     den = (T0 & 0xffff);
439     q = (num / den) & 0xffff;
440     r = (num % den) & 0xffff;
441     EAX = (EAX & 0xffff0000) | q;
442     EDX = (EDX & 0xffff0000) | r;
443 }
444
445 void OPPROTO op_idivw_AX_T0(void)
446 {
447     int num, den, q, r;
448
449     num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
450     den = (int16_t)T0;
451     q = (num / den) & 0xffff;
452     r = (num % den) & 0xffff;
453     EAX = (EAX & 0xffff0000) | q;
454     EDX = (EDX & 0xffff0000) | r;
455 }
456
457 void OPPROTO op_divl_EAX_T0(void)
458 {
459     unsigned int den, q, r;
460     uint64_t num;
461     
462     num = EAX | ((uint64_t)EDX << 32);
463     den = T0;
464     q = (num / den);
465     r = (num % den);
466     EAX = q;
467     EDX = r;
468 }
469
470 void OPPROTO op_idivl_EAX_T0(void)
471 {
472     int den, q, r;
473     int64_t num;
474     
475     num = EAX | ((uint64_t)EDX << 32);
476     den = T0;
477     q = (num / den);
478     r = (num % den);
479     EAX = q;
480     EDX = r;
481 }
482
483 /* constant load */
484
485 void OPPROTO op_movl_T0_im(void)
486 {
487     T0 = PARAM1;
488 }
489
490 void OPPROTO op_movl_T1_im(void)
491 {
492     T1 = PARAM1;
493 }
494
495 void OPPROTO op_movl_A0_im(void)
496 {
497     A0 = PARAM1;
498 }
499
500 void OPPROTO op_addl_A0_im(void)
501 {
502     A0 += PARAM1;
503 }
504
505 void OPPROTO op_andl_A0_ffff(void)
506 {
507     A0 = A0 & 0xffff;
508 }
509
510 /* memory access */
511
512 void OPPROTO op_ldub_T0_A0(void)
513 {
514     T0 = ldub((uint8_t *)A0);
515 }
516
517 void OPPROTO op_ldsb_T0_A0(void)
518 {
519     T0 = ldsb((int8_t *)A0);
520 }
521
522 void OPPROTO op_lduw_T0_A0(void)
523 {
524     T0 = lduw((uint8_t *)A0);
525 }
526
527 void OPPROTO op_ldsw_T0_A0(void)
528 {
529     T0 = ldsw((int8_t *)A0);
530 }
531
532 void OPPROTO op_ldl_T0_A0(void)
533 {
534     T0 = ldl((uint8_t *)A0);
535 }
536
537 void OPPROTO op_ldub_T1_A0(void)
538 {
539     T1 = ldub((uint8_t *)A0);
540 }
541
542 void OPPROTO op_ldsb_T1_A0(void)
543 {
544     T1 = ldsb((int8_t *)A0);
545 }
546
547 void OPPROTO op_lduw_T1_A0(void)
548 {
549     T1 = lduw((uint8_t *)A0);
550 }
551
552 void OPPROTO op_ldsw_T1_A0(void)
553 {
554     T1 = ldsw((int8_t *)A0);
555 }
556
557 void OPPROTO op_ldl_T1_A0(void)
558 {
559     T1 = ldl((uint8_t *)A0);
560 }
561
562 void OPPROTO op_stb_T0_A0(void)
563 {
564     stb((uint8_t *)A0, T0);
565 }
566
567 void OPPROTO op_stw_T0_A0(void)
568 {
569     stw((uint8_t *)A0, T0);
570 }
571
572 void OPPROTO op_stl_T0_A0(void)
573 {
574     stl((uint8_t *)A0, T0);
575 }
576
577 /* used for bit operations */
578
579 void OPPROTO op_add_bitw_A0_T1(void)
580 {
581     A0 += ((int32_t)T1 >> 4) << 1;
582 }
583
584 void OPPROTO op_add_bitl_A0_T1(void)
585 {
586     A0 += ((int32_t)T1 >> 5) << 2;
587 }
588
589 /* indirect jump */
590
591 void OPPROTO op_jmp_T0(void)
592 {
593     PC = T0;
594 }
595
596 void OPPROTO op_jmp_im(void)
597 {
598     PC = PARAM1;
599 }
600
601 void OPPROTO op_int_im(void)
602 {
603     PC = PARAM1;
604     raise_exception(EXCP0D_GPF);
605 }
606
607 void OPPROTO op_int3(void)
608 {
609     PC = PARAM1;
610     raise_exception(EXCP03_INT3);
611 }
612
613 void OPPROTO op_into(void)
614 {
615     int eflags;
616     eflags = cc_table[CC_OP].compute_all();
617     if (eflags & CC_O) {
618         PC = PARAM1;
619         raise_exception(EXCP04_INTO);
620     } else {
621         PC = PARAM2;
622     }
623 }
624
625 /* string ops */
626
627 #define ldul ldl
628
629 #define SHIFT 0
630 #include "ops_template.h"
631 #undef SHIFT
632
633 #define SHIFT 1
634 #include "ops_template.h"
635 #undef SHIFT
636
637 #define SHIFT 2
638 #include "ops_template.h"
639 #undef SHIFT
640
641 /* sign extend */
642
643 void OPPROTO op_movsbl_T0_T0(void)
644 {
645     T0 = (int8_t)T0;
646 }
647
648 void OPPROTO op_movzbl_T0_T0(void)
649 {
650     T0 = (uint8_t)T0;
651 }
652
653 void OPPROTO op_movswl_T0_T0(void)
654 {
655     T0 = (int16_t)T0;
656 }
657
658 void OPPROTO op_movzwl_T0_T0(void)
659 {
660     T0 = (uint16_t)T0;
661 }
662
663 void OPPROTO op_movswl_EAX_AX(void)
664 {
665     EAX = (int16_t)EAX;
666 }
667
668 void OPPROTO op_movsbw_AX_AL(void)
669 {
670     EAX = (EAX & 0xffff0000) | ((int8_t)EAX & 0xffff);
671 }
672
673 void OPPROTO op_movslq_EDX_EAX(void)
674 {
675     EDX = (int32_t)EAX >> 31;
676 }
677
678 void OPPROTO op_movswl_DX_AX(void)
679 {
680     EDX = (EDX & 0xffff0000) | (((int16_t)EAX >> 15) & 0xffff);
681 }
682
683 /* push/pop */
684 /* XXX: add 16 bit operand/16 bit seg variants */
685
686 void op_pushl_T0(void)
687 {
688     uint32_t offset;
689     offset = ESP - 4;
690     stl((void *)offset, T0);
691     /* modify ESP after to handle exceptions correctly */
692     ESP = offset;
693 }
694
695 void op_pushl_T1(void)
696 {
697     uint32_t offset;
698     offset = ESP - 4;
699     stl((void *)offset, T1);
700     /* modify ESP after to handle exceptions correctly */
701     ESP = offset;
702 }
703
704 void op_popl_T0(void)
705 {
706     T0 = ldl((void *)ESP);
707     ESP += 4;
708 }
709
710 void op_addl_ESP_im(void)
711 {
712     ESP += PARAM1;
713 }
714
715 /* flags handling */
716
717 /* slow jumps cases (compute x86 flags) */
718 void OPPROTO op_jo_cc(void)
719 {
720     int eflags;
721     eflags = cc_table[CC_OP].compute_all();
722     if (eflags & CC_O)
723         PC = PARAM1;
724     else
725         PC = PARAM2;
726     FORCE_RET();
727 }
728
729 void OPPROTO op_jb_cc(void)
730 {
731     if (cc_table[CC_OP].compute_c())
732         PC = PARAM1;
733     else
734         PC = PARAM2;
735     FORCE_RET();
736 }
737
738 void OPPROTO op_jz_cc(void)
739 {
740     int eflags;
741     eflags = cc_table[CC_OP].compute_all();
742     if (eflags & CC_Z)
743         PC = PARAM1;
744     else
745         PC = PARAM2;
746     FORCE_RET();
747 }
748
749 void OPPROTO op_jbe_cc(void)
750 {
751     int eflags;
752     eflags = cc_table[CC_OP].compute_all();
753     if (eflags & (CC_Z | CC_C))
754         PC = PARAM1;
755     else
756         PC = PARAM2;
757     FORCE_RET();
758 }
759
760 void OPPROTO op_js_cc(void)
761 {
762     int eflags;
763     eflags = cc_table[CC_OP].compute_all();
764     if (eflags & CC_S)
765         PC = PARAM1;
766     else
767         PC = PARAM2;
768     FORCE_RET();
769 }
770
771 void OPPROTO op_jp_cc(void)
772 {
773     int eflags;
774     eflags = cc_table[CC_OP].compute_all();
775     if (eflags & CC_P)
776         PC = PARAM1;
777     else
778         PC = PARAM2;
779     FORCE_RET();
780 }
781
782 void OPPROTO op_jl_cc(void)
783 {
784     int eflags;
785     eflags = cc_table[CC_OP].compute_all();
786     if ((eflags ^ (eflags >> 4)) & 0x80)
787         PC = PARAM1;
788     else
789         PC = PARAM2;
790     FORCE_RET();
791 }
792
793 void OPPROTO op_jle_cc(void)
794 {
795     int eflags;
796     eflags = cc_table[CC_OP].compute_all();
797     if (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z))
798         PC = PARAM1;
799     else
800         PC = PARAM2;
801     FORCE_RET();
802 }
803
804 /* slow set cases (compute x86 flags) */
805 void OPPROTO op_seto_T0_cc(void)
806 {
807     int eflags;
808     eflags = cc_table[CC_OP].compute_all();
809     T0 = (eflags >> 11) & 1;
810 }
811
812 void OPPROTO op_setb_T0_cc(void)
813 {
814     T0 = cc_table[CC_OP].compute_c();
815 }
816
817 void OPPROTO op_setz_T0_cc(void)
818 {
819     int eflags;
820     eflags = cc_table[CC_OP].compute_all();
821     T0 = (eflags >> 6) & 1;
822 }
823
824 void OPPROTO op_setbe_T0_cc(void)
825 {
826     int eflags;
827     eflags = cc_table[CC_OP].compute_all();
828     T0 = (eflags & (CC_Z | CC_C)) != 0;
829 }
830
831 void OPPROTO op_sets_T0_cc(void)
832 {
833     int eflags;
834     eflags = cc_table[CC_OP].compute_all();
835     T0 = (eflags >> 7) & 1;
836 }
837
838 void OPPROTO op_setp_T0_cc(void)
839 {
840     int eflags;
841     eflags = cc_table[CC_OP].compute_all();
842     T0 = (eflags >> 2) & 1;
843 }
844
845 void OPPROTO op_setl_T0_cc(void)
846 {
847     int eflags;
848     eflags = cc_table[CC_OP].compute_all();
849     T0 = ((eflags ^ (eflags >> 4)) >> 7) & 1;
850 }
851
852 void OPPROTO op_setle_T0_cc(void)
853 {
854     int eflags;
855     eflags = cc_table[CC_OP].compute_all();
856     T0 = (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) != 0;
857 }
858
859 void OPPROTO op_xor_T0_1(void)
860 {
861     T0 ^= 1;
862 }
863
864 void OPPROTO op_set_cc_op(void)
865 {
866     CC_OP = PARAM1;
867 }
868
869 void OPPROTO op_movl_eflags_T0(void)
870 {
871     CC_SRC = T0;
872     DF = 1 - (2 * ((T0 >> 10) & 1));
873 }
874
875 /* XXX: compute only O flag */
876 void OPPROTO op_movb_eflags_T0(void)
877 {
878     int of;
879     of = cc_table[CC_OP].compute_all() & CC_O;
880     CC_SRC = T0 | of;
881 }
882
883 void OPPROTO op_movl_T0_eflags(void)
884 {
885     T0 = cc_table[CC_OP].compute_all();
886     T0 |= (DF & DIRECTION_FLAG);
887 }
888
889 void OPPROTO op_cld(void)
890 {
891     DF = 1;
892 }
893
894 void OPPROTO op_std(void)
895 {
896     DF = -1;
897 }
898
899 void OPPROTO op_clc(void)
900 {
901     int eflags;
902     eflags = cc_table[CC_OP].compute_all();
903     eflags &= ~CC_C;
904     CC_SRC = eflags;
905 }
906
907 void OPPROTO op_stc(void)
908 {
909     int eflags;
910     eflags = cc_table[CC_OP].compute_all();
911     eflags |= CC_C;
912     CC_SRC = eflags;
913 }
914
915 void OPPROTO op_cmc(void)
916 {
917     int eflags;
918     eflags = cc_table[CC_OP].compute_all();
919     eflags ^= CC_C;
920     CC_SRC = eflags;
921 }
922
923 static int compute_all_eflags(void)
924 {
925     return CC_SRC;
926 }
927
928 static int compute_c_eflags(void)
929 {
930     return CC_SRC & CC_C;
931 }
932
933 static int compute_c_mul(void)
934 {
935     int cf;
936     cf = (CC_SRC != 0);
937     return cf;
938 }
939
940 static int compute_all_mul(void)
941 {
942     int cf, pf, af, zf, sf, of;
943     cf = (CC_SRC != 0);
944     pf = 0; /* undefined */
945     af = 0; /* undefined */
946     zf = 0; /* undefined */
947     sf = 0; /* undefined */
948     of = cf << 11;
949     return cf | pf | af | zf | sf | of;
950 }
951     
952 CCTable cc_table[CC_OP_NB] = {
953     [CC_OP_DYNAMIC] = { /* should never happen */ },
954
955     [CC_OP_EFLAGS] = { compute_all_eflags, compute_c_eflags },
956
957     [CC_OP_MUL] = { compute_all_mul, compute_c_mul },
958
959     [CC_OP_ADDB] = { compute_all_addb, compute_c_addb },
960     [CC_OP_ADDW] = { compute_all_addw, compute_c_addw  },
961     [CC_OP_ADDL] = { compute_all_addl, compute_c_addl  },
962
963     [CC_OP_ADCB] = { compute_all_adcb, compute_c_adcb },
964     [CC_OP_ADCW] = { compute_all_adcw, compute_c_adcw  },
965     [CC_OP_ADCL] = { compute_all_adcl, compute_c_adcl  },
966
967     [CC_OP_SUBB] = { compute_all_subb, compute_c_subb  },
968     [CC_OP_SUBW] = { compute_all_subw, compute_c_subw  },
969     [CC_OP_SUBL] = { compute_all_subl, compute_c_subl  },
970     
971     [CC_OP_SBBB] = { compute_all_sbbb, compute_c_sbbb  },
972     [CC_OP_SBBW] = { compute_all_sbbw, compute_c_sbbw  },
973     [CC_OP_SBBL] = { compute_all_sbbl, compute_c_sbbl  },
974     
975     [CC_OP_LOGICB] = { compute_all_logicb, compute_c_logicb },
976     [CC_OP_LOGICW] = { compute_all_logicw, compute_c_logicw },
977     [CC_OP_LOGICL] = { compute_all_logicl, compute_c_logicl },
978     
979     [CC_OP_INCB] = { compute_all_incb, compute_c_incl },
980     [CC_OP_INCW] = { compute_all_incw, compute_c_incl },
981     [CC_OP_INCL] = { compute_all_incl, compute_c_incl },
982     
983     [CC_OP_DECB] = { compute_all_decb, compute_c_incl },
984     [CC_OP_DECW] = { compute_all_decw, compute_c_incl },
985     [CC_OP_DECL] = { compute_all_decl, compute_c_incl },
986     
987     [CC_OP_SHLB] = { compute_all_shlb, compute_c_shll },
988     [CC_OP_SHLW] = { compute_all_shlw, compute_c_shll },
989     [CC_OP_SHLL] = { compute_all_shll, compute_c_shll },
990
991     [CC_OP_SARB] = { compute_all_sarb, compute_c_shll },
992     [CC_OP_SARW] = { compute_all_sarw, compute_c_shll },
993     [CC_OP_SARL] = { compute_all_sarl, compute_c_shll },
994 };
995
996 /* floating point support */
997
998 #ifdef USE_X86LDOUBLE
999 /* use long double functions */
1000 #define lrint lrintl
1001 #define llrint llrintl
1002 #define fabs fabsl
1003 #define sin sinl
1004 #define cos cosl
1005 #define sqrt sqrtl
1006 #define pow powl
1007 #define log logl
1008 #define tan tanl
1009 #define atan2 atan2l
1010 #define floor floorl
1011 #define ceil ceill
1012 #define rint rintl
1013 #endif
1014
1015 extern int lrint(CPU86_LDouble x);
1016 extern int64_t llrint(CPU86_LDouble x);
1017 extern CPU86_LDouble fabs(CPU86_LDouble x);
1018 extern CPU86_LDouble sin(CPU86_LDouble x);
1019 extern CPU86_LDouble cos(CPU86_LDouble x);
1020 extern CPU86_LDouble sqrt(CPU86_LDouble x);
1021 extern CPU86_LDouble pow(CPU86_LDouble, CPU86_LDouble);
1022 extern CPU86_LDouble log(CPU86_LDouble x);
1023 extern CPU86_LDouble tan(CPU86_LDouble x);
1024 extern CPU86_LDouble atan2(CPU86_LDouble, CPU86_LDouble);
1025 extern CPU86_LDouble floor(CPU86_LDouble x);
1026 extern CPU86_LDouble ceil(CPU86_LDouble x);
1027 extern CPU86_LDouble rint(CPU86_LDouble x);
1028
1029 #define RC_MASK         0xc00
1030 #define RC_NEAR         0x000
1031 #define RC_DOWN         0x400
1032 #define RC_UP           0x800
1033 #define RC_CHOP         0xc00
1034
1035 #define MAXTAN 9223372036854775808.0
1036
1037 #ifdef USE_X86LDOUBLE
1038
1039 /* only for x86 */
1040 typedef union {
1041     long double d;
1042     struct {
1043         unsigned long long lower;
1044         unsigned short upper;
1045     } l;
1046 } CPU86_LDoubleU;
1047
1048 /* the following deal with x86 long double-precision numbers */
1049 #define MAXEXPD 0x7fff
1050 #define EXPBIAS 16383
1051 #define EXPD(fp)        (fp.l.upper & 0x7fff)
1052 #define SIGND(fp)       ((fp.l.upper) & 0x8000)
1053 #define MANTD(fp)       (fp.l.lower)
1054 #define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS
1055
1056 #else
1057
1058 typedef union {
1059     double d;
1060 #ifndef WORDS_BIGENDIAN
1061     struct {
1062         unsigned long lower;
1063         long upper;
1064     } l;
1065 #else
1066     struct {
1067         long upper;
1068         unsigned long lower;
1069     } l;
1070 #endif
1071     long long ll;
1072 } CPU86_LDoubleU;
1073
1074 /* the following deal with IEEE double-precision numbers */
1075 #define MAXEXPD 0x7ff
1076 #define EXPBIAS 1023
1077 #define EXPD(fp)        (((fp.l.upper) >> 20) & 0x7FF)
1078 #define SIGND(fp)       ((fp.l.upper) & 0x80000000)
1079 #define MANTD(fp)       (fp.ll & ((1LL << 52) - 1))
1080 #define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20)
1081 #endif
1082
1083 /* fp load FT0 */
1084
1085 void OPPROTO op_flds_FT0_A0(void)
1086 {
1087     FT0 = ldfl((void *)A0);
1088 }
1089
1090 void OPPROTO op_fldl_FT0_A0(void)
1091 {
1092     FT0 = ldfq((void *)A0);
1093 }
1094
1095 void OPPROTO op_fild_FT0_A0(void)
1096 {
1097     FT0 = (CPU86_LDouble)ldsw((void *)A0);
1098 }
1099
1100 void OPPROTO op_fildl_FT0_A0(void)
1101 {
1102     FT0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
1103 }
1104
1105 void OPPROTO op_fildll_FT0_A0(void)
1106 {
1107     FT0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
1108 }
1109
1110 /* fp load ST0 */
1111
1112 void OPPROTO op_flds_ST0_A0(void)
1113 {
1114     ST0 = ldfl((void *)A0);
1115 }
1116
1117 void OPPROTO op_fldl_ST0_A0(void)
1118 {
1119     ST0 = ldfq((void *)A0);
1120 }
1121
1122 #ifdef USE_X86LDOUBLE
1123 void OPPROTO op_fldt_ST0_A0(void)
1124 {
1125     ST0 = *(long double *)A0;
1126 }
1127 #else
1128 void helper_fldt_ST0_A0(void)
1129 {
1130     CPU86_LDoubleU temp;
1131     int upper, e;
1132     /* mantissa */
1133     upper = lduw((uint8_t *)A0 + 8);
1134     /* XXX: handle overflow ? */
1135     e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */
1136     e |= (upper >> 4) & 0x800; /* sign */
1137     temp.ll = ((ldq((void *)A0) >> 11) & ((1LL << 52) - 1)) | ((uint64_t)e << 52);
1138     ST0 = temp.d;
1139 }
1140
1141 void OPPROTO op_fldt_ST0_A0(void)
1142 {
1143     helper_fldt_ST0_A0();
1144 }
1145 #endif
1146
1147 void OPPROTO op_fild_ST0_A0(void)
1148 {
1149     ST0 = (CPU86_LDouble)ldsw((void *)A0);
1150 }
1151
1152 void OPPROTO op_fildl_ST0_A0(void)
1153 {
1154     ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
1155 }
1156
1157 void OPPROTO op_fildll_ST0_A0(void)
1158 {
1159     ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
1160 }
1161
1162 /* fp store */
1163
1164 void OPPROTO op_fsts_ST0_A0(void)
1165 {
1166     stfl((void *)A0, (float)ST0);
1167 }
1168
1169 void OPPROTO op_fstl_ST0_A0(void)
1170 {
1171     stfq((void *)A0, (double)ST0);
1172 }
1173
1174 #ifdef USE_X86LDOUBLE
1175 void OPPROTO op_fstt_ST0_A0(void)
1176 {
1177     *(long double *)A0 = ST0;
1178 }
1179 #else
1180 void helper_fstt_ST0_A0(void)
1181 {
1182     CPU86_LDoubleU temp;
1183     int e;
1184     temp.d = ST0;
1185     /* mantissa */
1186     stq((void *)A0, (MANTD(temp) << 11) | (1LL << 63));
1187     /* exponent + sign */
1188     e = EXPD(temp) - EXPBIAS + 16383;
1189     e |= SIGND(temp) >> 16;
1190     stw((uint8_t *)A0 + 8, e);
1191 }
1192
1193 void OPPROTO op_fstt_ST0_A0(void)
1194 {
1195     helper_fstt_ST0_A0();
1196 }
1197 #endif
1198
1199 void OPPROTO op_fist_ST0_A0(void)
1200 {
1201     int val;
1202     val = lrint(ST0);
1203     stw((void *)A0, val);
1204 }
1205
1206 void OPPROTO op_fistl_ST0_A0(void)
1207 {
1208     int val;
1209     val = lrint(ST0);
1210     stl((void *)A0, val);
1211 }
1212
1213 void OPPROTO op_fistll_ST0_A0(void)
1214 {
1215     int64_t val;
1216     val = llrint(ST0);
1217     stq((void *)A0, val);
1218 }
1219
1220 /* BCD ops */
1221
1222 #define MUL10(iv) ( iv + iv + (iv << 3) )
1223
1224 void helper_fbld_ST0_A0(void)
1225 {
1226     uint8_t *seg;
1227     CPU86_LDouble fpsrcop;
1228     int m32i;
1229     unsigned int v;
1230
1231     /* in this code, seg/m32i will be used as temporary ptr/int */
1232     seg = (uint8_t *)A0 + 8;
1233     v = ldub(seg--);
1234     /* XXX: raise exception */
1235     if (v != 0)
1236         return;
1237     v = ldub(seg--);
1238     /* XXX: raise exception */
1239     if ((v & 0xf0) != 0)
1240         return;
1241     m32i = v;  /* <-- d14 */
1242     v = ldub(seg--);
1243     m32i = MUL10(m32i) + (v >> 4);  /* <-- val * 10 + d13 */
1244     m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d12 */
1245     v = ldub(seg--);
1246     m32i = MUL10(m32i) + (v >> 4);  /* <-- val * 10 + d11 */
1247     m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d10 */
1248     v = ldub(seg--);
1249     m32i = MUL10(m32i) + (v >> 4);  /* <-- val * 10 + d9 */
1250     m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d8 */
1251     fpsrcop = ((CPU86_LDouble)m32i) * 100000000.0;
1252
1253     v = ldub(seg--);
1254     m32i = (v >> 4);  /* <-- d7 */
1255     m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d6 */
1256     v = ldub(seg--);
1257     m32i = MUL10(m32i) + (v >> 4);  /* <-- val * 10 + d5 */
1258     m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d4 */
1259     v = ldub(seg--);
1260     m32i = MUL10(m32i) + (v >> 4);  /* <-- val * 10 + d3 */
1261     m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d2 */
1262     v = ldub(seg);
1263     m32i = MUL10(m32i) + (v >> 4);  /* <-- val * 10 + d1 */
1264     m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d0 */
1265     fpsrcop += ((CPU86_LDouble)m32i);
1266     if ( ldub(seg+9) & 0x80 )
1267         fpsrcop = -fpsrcop;
1268     ST0 = fpsrcop;
1269 }
1270
1271 void OPPROTO op_fbld_ST0_A0(void)
1272 {
1273     helper_fbld_ST0_A0();
1274 }
1275
1276 void helper_fbst_ST0_A0(void)
1277 {
1278     CPU86_LDouble fptemp;
1279     CPU86_LDouble fpsrcop;
1280     int v;
1281     uint8_t *mem_ref, *mem_end;
1282
1283     fpsrcop = rint(ST0);
1284     mem_ref = (uint8_t *)A0;
1285     mem_end = mem_ref + 8;
1286     if ( fpsrcop < 0.0 ) {
1287         stw(mem_end, 0x8000);
1288         fpsrcop = -fpsrcop;
1289     } else {
1290         stw(mem_end, 0x0000);
1291     }
1292     while (mem_ref < mem_end) {
1293         if (fpsrcop == 0.0)
1294             break;
1295         fptemp = floor(fpsrcop/10.0);
1296         v = ((int)(fpsrcop - fptemp*10.0));
1297         if  (fptemp == 0.0)  { 
1298             stb(mem_ref++, v); 
1299             break; 
1300         }
1301         fpsrcop = fptemp;
1302         fptemp = floor(fpsrcop/10.0);
1303         v |= (((int)(fpsrcop - fptemp*10.0)) << 4);
1304         stb(mem_ref++, v);
1305         fpsrcop = fptemp;
1306     }
1307     while (mem_ref < mem_end) {
1308         stb(mem_ref++, 0);
1309     }
1310 }
1311
1312 void OPPROTO op_fbst_ST0_A0(void)
1313 {
1314     helper_fbst_ST0_A0();
1315 }
1316
1317 /* FPU move */
1318
1319 static inline void fpush(void)
1320 {
1321     env->fpstt = (env->fpstt - 1) & 7;
1322     env->fptags[env->fpstt] = 0; /* validate stack entry */
1323 }
1324
1325 static inline void fpop(void)
1326 {
1327     env->fptags[env->fpstt] = 1; /* invvalidate stack entry */
1328     env->fpstt = (env->fpstt + 1) & 7;
1329 }
1330
1331 void OPPROTO op_fpush(void)
1332 {
1333     fpush();
1334 }
1335
1336 void OPPROTO op_fpop(void)
1337 {
1338     fpop();
1339 }
1340
1341 void OPPROTO op_fdecstp(void)
1342 {
1343     env->fpstt = (env->fpstt - 1) & 7;
1344     env->fpus &= (~0x4700);
1345 }
1346
1347 void OPPROTO op_fincstp(void)
1348 {
1349     env->fpstt = (env->fpstt + 1) & 7;
1350     env->fpus &= (~0x4700);
1351 }
1352
1353 void OPPROTO op_fmov_ST0_FT0(void)
1354 {
1355     ST0 = FT0;
1356 }
1357
1358 void OPPROTO op_fmov_FT0_STN(void)
1359 {
1360     FT0 = ST(PARAM1);
1361 }
1362
1363 void OPPROTO op_fmov_ST0_STN(void)
1364 {
1365     ST0 = ST(PARAM1);
1366 }
1367
1368 void OPPROTO op_fmov_STN_ST0(void)
1369 {
1370     ST(PARAM1) = ST0;
1371 }
1372
1373 void OPPROTO op_fxchg_ST0_STN(void)
1374 {
1375     CPU86_LDouble tmp;
1376     tmp = ST(PARAM1);
1377     ST(PARAM1) = ST0;
1378     ST0 = tmp;
1379 }
1380
1381 /* FPU operations */
1382
1383 /* XXX: handle nans */
1384 void OPPROTO op_fcom_ST0_FT0(void)
1385 {
1386     env->fpus &= (~0x4500);     /* (C3,C2,C0) <-- 000 */
1387     if (ST0 < FT0)
1388         env->fpus |= 0x100;     /* (C3,C2,C0) <-- 001 */
1389     else if (ST0 == FT0)
1390         env->fpus |= 0x4000; /* (C3,C2,C0) <-- 100 */
1391     FORCE_RET();
1392 }
1393
1394 /* XXX: handle nans */
1395 void OPPROTO op_fucom_ST0_FT0(void)
1396 {
1397     env->fpus &= (~0x4500);     /* (C3,C2,C0) <-- 000 */
1398     if (ST0 < FT0)
1399         env->fpus |= 0x100;     /* (C3,C2,C0) <-- 001 */
1400     else if (ST0 == FT0)
1401         env->fpus |= 0x4000; /* (C3,C2,C0) <-- 100 */
1402     FORCE_RET();
1403 }
1404
1405 void OPPROTO op_fadd_ST0_FT0(void)
1406 {
1407     ST0 += FT0;
1408 }
1409
1410 void OPPROTO op_fmul_ST0_FT0(void)
1411 {
1412     ST0 *= FT0;
1413 }
1414
1415 void OPPROTO op_fsub_ST0_FT0(void)
1416 {
1417     ST0 -= FT0;
1418 }
1419
1420 void OPPROTO op_fsubr_ST0_FT0(void)
1421 {
1422     ST0 = FT0 - ST0;
1423 }
1424
1425 void OPPROTO op_fdiv_ST0_FT0(void)
1426 {
1427     ST0 /= FT0;
1428 }
1429
1430 void OPPROTO op_fdivr_ST0_FT0(void)
1431 {
1432     ST0 = FT0 / ST0;
1433 }
1434
1435 /* fp operations between STN and ST0 */
1436
1437 void OPPROTO op_fadd_STN_ST0(void)
1438 {
1439     ST(PARAM1) += ST0;
1440 }
1441
1442 void OPPROTO op_fmul_STN_ST0(void)
1443 {
1444     ST(PARAM1) *= ST0;
1445 }
1446
1447 void OPPROTO op_fsub_STN_ST0(void)
1448 {
1449     ST(PARAM1) -= ST0;
1450 }
1451
1452 void OPPROTO op_fsubr_STN_ST0(void)
1453 {
1454     CPU86_LDouble *p;
1455     p = &ST(PARAM1);
1456     *p = ST0 - *p;
1457 }
1458
1459 void OPPROTO op_fdiv_STN_ST0(void)
1460 {
1461     ST(PARAM1) /= ST0;
1462 }
1463
1464 void OPPROTO op_fdivr_STN_ST0(void)
1465 {
1466     CPU86_LDouble *p;
1467     p = &ST(PARAM1);
1468     *p = ST0 / *p;
1469 }
1470
1471 /* misc FPU operations */
1472 void OPPROTO op_fchs_ST0(void)
1473 {
1474     ST0 = -ST0;
1475 }
1476
1477 void OPPROTO op_fabs_ST0(void)
1478 {
1479     ST0 = fabs(ST0);
1480 }
1481
1482 void helper_fxam_ST0(void)
1483 {
1484     CPU86_LDoubleU temp;
1485     int expdif;
1486
1487     temp.d = ST0;
1488
1489     env->fpus &= (~0x4700);  /* (C3,C2,C1,C0) <-- 0000 */
1490     if (SIGND(temp))
1491         env->fpus |= 0x200; /* C1 <-- 1 */
1492
1493     expdif = EXPD(temp);
1494     if (expdif == MAXEXPD) {
1495         if (MANTD(temp) == 0)
1496             env->fpus |=  0x500 /*Infinity*/;
1497         else
1498             env->fpus |=  0x100 /*NaN*/;
1499     } else if (expdif == 0) {
1500         if (MANTD(temp) == 0)
1501             env->fpus |=  0x4000 /*Zero*/;
1502         else
1503             env->fpus |= 0x4400 /*Denormal*/;
1504     } else {
1505         env->fpus |= 0x400;
1506     }
1507 }
1508
1509 void OPPROTO op_fxam_ST0(void)
1510 {
1511     helper_fxam_ST0();
1512 }
1513
1514 void OPPROTO op_fld1_ST0(void)
1515 {
1516     ST0 = *(CPU86_LDouble *)&f15rk[1];
1517 }
1518
1519 void OPPROTO op_fldl2t_ST0(void)
1520 {
1521     ST0 = *(CPU86_LDouble *)&f15rk[6];
1522 }
1523
1524 void OPPROTO op_fldl2e_ST0(void)
1525 {
1526     ST0 = *(CPU86_LDouble *)&f15rk[5];
1527 }
1528
1529 void OPPROTO op_fldpi_ST0(void)
1530 {
1531     ST0 = *(CPU86_LDouble *)&f15rk[2];
1532 }
1533
1534 void OPPROTO op_fldlg2_ST0(void)
1535 {
1536     ST0 = *(CPU86_LDouble *)&f15rk[3];
1537 }
1538
1539 void OPPROTO op_fldln2_ST0(void)
1540 {
1541     ST0 = *(CPU86_LDouble *)&f15rk[4];
1542 }
1543
1544 void OPPROTO op_fldz_ST0(void)
1545 {
1546     ST0 = *(CPU86_LDouble *)&f15rk[0];
1547 }
1548
1549 void OPPROTO op_fldz_FT0(void)
1550 {
1551     ST0 = *(CPU86_LDouble *)&f15rk[0];
1552 }
1553
1554 void helper_f2xm1(void)
1555 {
1556     ST0 = pow(2.0,ST0) - 1.0;
1557 }
1558
1559 void helper_fyl2x(void)
1560 {
1561     CPU86_LDouble fptemp;
1562     
1563     fptemp = ST0;
1564     if (fptemp>0.0){
1565         fptemp = log(fptemp)/log(2.0);   /* log2(ST) */
1566         ST1 *= fptemp;
1567         fpop();
1568     } else { 
1569         env->fpus &= (~0x4700);
1570         env->fpus |= 0x400;
1571     }
1572 }
1573
1574 void helper_fptan(void)
1575 {
1576     CPU86_LDouble fptemp;
1577
1578     fptemp = ST0;
1579     if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
1580         env->fpus |= 0x400;
1581     } else {
1582         ST0 = tan(fptemp);
1583         fpush();
1584         ST0 = 1.0;
1585         env->fpus &= (~0x400);  /* C2 <-- 0 */
1586         /* the above code is for  |arg| < 2**52 only */
1587     }
1588 }
1589
1590 void helper_fpatan(void)
1591 {
1592     CPU86_LDouble fptemp, fpsrcop;
1593
1594     fpsrcop = ST1;
1595     fptemp = ST0;
1596     ST1 = atan2(fpsrcop,fptemp);
1597     fpop();
1598 }
1599
1600 void helper_fxtract(void)
1601 {
1602     CPU86_LDoubleU temp;
1603     unsigned int expdif;
1604
1605     temp.d = ST0;
1606     expdif = EXPD(temp) - EXPBIAS;
1607     /*DP exponent bias*/
1608     ST0 = expdif;
1609     fpush();
1610     BIASEXPONENT(temp);
1611     ST0 = temp.d;
1612 }
1613
1614 void helper_fprem1(void)
1615 {
1616     CPU86_LDouble dblq, fpsrcop, fptemp;
1617     CPU86_LDoubleU fpsrcop1, fptemp1;
1618     int expdif;
1619     int q;
1620
1621     fpsrcop = ST0;
1622     fptemp = ST1;
1623     fpsrcop1.d = fpsrcop;
1624     fptemp1.d = fptemp;
1625     expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
1626     if (expdif < 53) {
1627         dblq = fpsrcop / fptemp;
1628         dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);
1629         ST0 = fpsrcop - fptemp*dblq;
1630         q = (int)dblq; /* cutting off top bits is assumed here */
1631         env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
1632                                 /* (C0,C1,C3) <-- (q2,q1,q0) */
1633         env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */
1634         env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */
1635         env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */
1636     } else {
1637         env->fpus |= 0x400;  /* C2 <-- 1 */
1638         fptemp = pow(2.0, expdif-50);
1639         fpsrcop = (ST0 / ST1) / fptemp;
1640         /* fpsrcop = integer obtained by rounding to the nearest */
1641         fpsrcop = (fpsrcop-floor(fpsrcop) < ceil(fpsrcop)-fpsrcop)?
1642             floor(fpsrcop): ceil(fpsrcop);
1643         ST0 -= (ST1 * fpsrcop * fptemp);
1644     }
1645 }
1646
1647 void helper_fprem(void)
1648 {
1649     CPU86_LDouble dblq, fpsrcop, fptemp;
1650     CPU86_LDoubleU fpsrcop1, fptemp1;
1651     int expdif;
1652     int q;
1653     
1654     fpsrcop = ST0;
1655     fptemp = ST1;
1656     fpsrcop1.d = fpsrcop;
1657     fptemp1.d = fptemp;
1658     expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
1659     if ( expdif < 53 ) {
1660         dblq = fpsrcop / fptemp;
1661         dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);
1662         ST0 = fpsrcop - fptemp*dblq;
1663         q = (int)dblq; /* cutting off top bits is assumed here */
1664         env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
1665                                 /* (C0,C1,C3) <-- (q2,q1,q0) */
1666         env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */
1667         env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */
1668         env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */
1669     } else {
1670         env->fpus |= 0x400;  /* C2 <-- 1 */
1671         fptemp = pow(2.0, expdif-50);
1672         fpsrcop = (ST0 / ST1) / fptemp;
1673         /* fpsrcop = integer obtained by chopping */
1674         fpsrcop = (fpsrcop < 0.0)?
1675             -(floor(fabs(fpsrcop))): floor(fpsrcop);
1676         ST0 -= (ST1 * fpsrcop * fptemp);
1677     }
1678 }
1679
1680 void helper_fyl2xp1(void)
1681 {
1682     CPU86_LDouble fptemp;
1683
1684     fptemp = ST0;
1685     if ((fptemp+1.0)>0.0) {
1686         fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */
1687         ST1 *= fptemp;
1688         fpop();
1689     } else { 
1690         env->fpus &= (~0x4700);
1691         env->fpus |= 0x400;
1692     }
1693 }
1694
1695 void helper_fsqrt(void)
1696 {
1697     CPU86_LDouble fptemp;
1698
1699     fptemp = ST0;
1700     if (fptemp<0.0) { 
1701         env->fpus &= (~0x4700);  /* (C3,C2,C1,C0) <-- 0000 */
1702         env->fpus |= 0x400;
1703     }
1704     ST0 = sqrt(fptemp);
1705 }
1706
1707 void helper_fsincos(void)
1708 {
1709     CPU86_LDouble fptemp;
1710
1711     fptemp = ST0;
1712     if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
1713         env->fpus |= 0x400;
1714     } else {
1715         ST0 = sin(fptemp);
1716         fpush();
1717         ST0 = cos(fptemp);
1718         env->fpus &= (~0x400);  /* C2 <-- 0 */
1719         /* the above code is for  |arg| < 2**63 only */
1720     }
1721 }
1722
1723 void helper_frndint(void)
1724 {
1725     ST0 = rint(ST0);
1726 }
1727
1728 void helper_fscale(void)
1729 {
1730     CPU86_LDouble fpsrcop, fptemp;
1731
1732     fpsrcop = 2.0;
1733     fptemp = pow(fpsrcop,ST1);
1734     ST0 *= fptemp;
1735 }
1736
1737 void helper_fsin(void)
1738 {
1739     CPU86_LDouble fptemp;
1740
1741     fptemp = ST0;
1742     if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
1743         env->fpus |= 0x400;
1744     } else {
1745         ST0 = sin(fptemp);
1746         env->fpus &= (~0x400);  /* C2 <-- 0 */
1747         /* the above code is for  |arg| < 2**53 only */
1748     }
1749 }
1750
1751 void helper_fcos(void)
1752 {
1753     CPU86_LDouble fptemp;
1754
1755     fptemp = ST0;
1756     if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
1757         env->fpus |= 0x400;
1758     } else {
1759         ST0 = cos(fptemp);
1760         env->fpus &= (~0x400);  /* C2 <-- 0 */
1761         /* the above code is for  |arg5 < 2**63 only */
1762     }
1763 }
1764
1765 /* associated heplers to reduce generated code length and to simplify
1766    relocation (FP constants are usually stored in .rodata section) */
1767
1768 void OPPROTO op_f2xm1(void)
1769 {
1770     helper_f2xm1();
1771 }
1772
1773 void OPPROTO op_fyl2x(void)
1774 {
1775     helper_fyl2x();
1776 }
1777
1778 void OPPROTO op_fptan(void)
1779 {
1780     helper_fptan();
1781 }
1782
1783 void OPPROTO op_fpatan(void)
1784 {
1785     helper_fpatan();
1786 }
1787
1788 void OPPROTO op_fxtract(void)
1789 {
1790     helper_fxtract();
1791 }
1792
1793 void OPPROTO op_fprem1(void)
1794 {
1795     helper_fprem1();
1796 }
1797
1798
1799 void OPPROTO op_fprem(void)
1800 {
1801     helper_fprem();
1802 }
1803
1804 void OPPROTO op_fyl2xp1(void)
1805 {
1806     helper_fyl2xp1();
1807 }
1808
1809 void OPPROTO op_fsqrt(void)
1810 {
1811     helper_fsqrt();
1812 }
1813
1814 void OPPROTO op_fsincos(void)
1815 {
1816     helper_fsincos();
1817 }
1818
1819 void OPPROTO op_frndint(void)
1820 {
1821     helper_frndint();
1822 }
1823
1824 void OPPROTO op_fscale(void)
1825 {
1826     helper_fscale();
1827 }
1828
1829 void OPPROTO op_fsin(void)
1830 {
1831     helper_fsin();
1832 }
1833
1834 void OPPROTO op_fcos(void)
1835 {
1836     helper_fcos();
1837 }
1838
1839 void OPPROTO op_fnstsw_A0(void)
1840 {
1841     int fpus;
1842     fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
1843     stw((void *)A0, fpus);
1844 }
1845
1846 void OPPROTO op_fnstsw_EAX(void)
1847 {
1848     int fpus;
1849     fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
1850     EAX = (EAX & 0xffff0000) | fpus;
1851 }
1852
1853 void OPPROTO op_fnstcw_A0(void)
1854 {
1855     stw((void *)A0, env->fpuc);
1856 }
1857
1858 void OPPROTO op_fldcw_A0(void)
1859 {
1860     int rnd_type;
1861     env->fpuc = lduw((void *)A0);
1862     /* set rounding mode */
1863     switch(env->fpuc & RC_MASK) {
1864     default:
1865     case RC_NEAR:
1866         rnd_type = FE_TONEAREST;
1867         break;
1868     case RC_DOWN:
1869         rnd_type = FE_DOWNWARD;
1870         break;
1871     case RC_UP:
1872         rnd_type = FE_UPWARD;
1873         break;
1874     case RC_CHOP:
1875         rnd_type = FE_TOWARDZERO;
1876         break;
1877     }
1878     fesetround(rnd_type);
1879 }
1880
1881 /* main execution loop */
1882 uint8_t code_gen_buffer[65536];
1883
1884 #ifdef DEBUG_EXEC
1885 static const char *cc_op_str[] = {
1886     "DYNAMIC",
1887     "EFLAGS",
1888     "MUL",
1889     "ADDB",
1890     "ADDW",
1891     "ADDL",
1892     "ADCB",
1893     "ADCW",
1894     "ADCL",
1895     "SUBB",
1896     "SUBW",
1897     "SUBL",
1898     "SBBB",
1899     "SBBW",
1900     "SBBL",
1901     "LOGICB",
1902     "LOGICW",
1903     "LOGICL",
1904     "INCB",
1905     "INCW",
1906     "INCL",
1907     "DECB",
1908     "DECW",
1909     "DECL",
1910     "SHLB",
1911     "SHLW",
1912     "SHLL",
1913     "SARB",
1914     "SARW",
1915     "SARL",
1916 };
1917 #endif
1918
1919 int cpu_x86_exec(CPUX86State *env1)
1920 {
1921     int saved_T0, saved_T1, saved_A0;
1922     CPUX86State *saved_env;
1923     int code_gen_size, ret;
1924     void (*gen_func)(void);
1925
1926     /* first we save global registers */
1927     saved_T0 = T0;
1928     saved_T1 = T1;
1929     saved_A0 = A0;
1930     saved_env = env;
1931     env = env1;
1932     
1933     /* prepare setjmp context for exception handling */
1934     if (setjmp(env->jmp_env) == 0) {
1935         for(;;) {
1936 #ifdef DEBUG_EXEC
1937             if (loglevel) {
1938                 int eflags;
1939                 eflags = cc_table[CC_OP].compute_all();
1940                 eflags |= (DF & DIRECTION_FLAG);
1941                 fprintf(logfile, 
1942                         "EAX=%08x EBX=%08X ECX=%08x EDX=%08x\n"
1943                         "ESI=%08x EDI=%08X EBP=%08x ESP=%08x\n"
1944                         "CCS=%08x CCD=%08x CCO=%-8s EFL=%c%c%c%c%c%c%c\n",
1945                         env->regs[R_EAX], env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX], 
1946                         env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP], env->regs[R_ESP], 
1947                         env->cc_src, env->cc_dst, cc_op_str[env->cc_op],
1948                         eflags & DIRECTION_FLAG ? 'D' : '-',
1949                         eflags & CC_O ? 'O' : '-',
1950                         eflags & CC_S ? 'S' : '-',
1951                         eflags & CC_Z ? 'Z' : '-',
1952                         eflags & CC_A ? 'A' : '-',
1953                         eflags & CC_P ? 'P' : '-',
1954                         eflags & CC_C ? 'C' : '-'
1955                         );
1956 #if 1
1957                 fprintf(logfile, "ST0=%f ST1=%f ST2=%f ST3=%f\n", 
1958                         (double)ST0, (double)ST1, (double)ST(2), (double)ST(3));
1959 #endif
1960             }
1961 #endif
1962             cpu_x86_gen_code(code_gen_buffer, &code_gen_size, (uint8_t *)env->pc);
1963             /* execute the generated code */
1964             gen_func = (void *)code_gen_buffer;
1965             gen_func();
1966         }
1967     }
1968     ret = env->exception_index;
1969
1970     /* restore global registers */
1971     T0 = saved_T0;
1972     T1 = saved_T1;
1973     A0 = saved_A0;
1974     env = saved_env;
1975     return ret;
1976 }