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;
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;
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) )); \
26 typedef struct FILE FILE;
29 extern int fprintf(FILE *, const char *, ...);
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");
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");
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");
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");
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");
62 /* force GCC to generate only one epilog at the end of the function */
63 #define FORCE_RET() asm volatile ("");
69 #define xglue(x, y) x ## y
70 #define glue(x, y) xglue(x, y)
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])
83 #define CC_SRC (env->cc_src)
84 #define CC_DST (env->cc_dst)
85 #define CC_OP (env->cc_op)
88 #define FT0 (env->ft0)
89 #define ST0 (env->fpregs[env->fpstt])
90 #define ST(n) (env->fpregs[(env->fpstt + (n)) & 7])
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))
100 typedef struct CCTable {
101 int (*compute_all)(void); /* return all the flags */
102 int (*compute_c)(void); /* return the C flag */
105 /* NOTE: data are not static to force relocation generation by GCC */
106 extern CCTable cc_table[];
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,
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,
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,
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[] =
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}
173 /* the same, 64-bit version */
174 typedef unsigned short f15ld[4];
175 const f15ld f15rk[] =
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}
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}
197 /* n must be a constant to be efficient */
198 static inline int lshift(int x, int n)
206 /* exception support */
207 /* NOTE: not static to force relocation generation by GCC */
208 void raise_exception(int exception_index)
210 env->exception_index = exception_index;
211 longjmp(env->jmp_env, 1);
214 /* we define the various pieces of code used by the JIT */
218 #include "opreg_template.h"
224 #include "opreg_template.h"
230 #include "opreg_template.h"
236 #include "opreg_template.h"
242 #include "opreg_template.h"
248 #include "opreg_template.h"
254 #include "opreg_template.h"
260 #include "opreg_template.h"
266 void OPPROTO op_addl_T0_T1_cc(void)
273 void OPPROTO op_orl_T0_T1_cc(void)
279 void OPPROTO op_andl_T0_T1_cc(void)
285 void OPPROTO op_subl_T0_T1_cc(void)
292 void OPPROTO op_xorl_T0_T1_cc(void)
298 void OPPROTO op_cmpl_T0_T1_cc(void)
304 void OPPROTO op_notl_T0(void)
309 void OPPROTO op_negl_T0_cc(void)
316 void OPPROTO op_incl_T0_cc(void)
318 CC_SRC = cc_table[CC_OP].compute_c();
323 void OPPROTO op_decl_T0_cc(void)
325 CC_SRC = cc_table[CC_OP].compute_c();
330 void OPPROTO op_testl_T0_T1_cc(void)
335 void OPPROTO op_bswapl_T0(void)
340 /* multiply/divide */
341 void OPPROTO op_mulb_AL_T0(void)
344 res = (uint8_t)EAX * (uint8_t)T0;
345 EAX = (EAX & 0xffff0000) | res;
346 CC_SRC = (res & 0xff00);
349 void OPPROTO op_imulb_AL_T0(void)
352 res = (int8_t)EAX * (int8_t)T0;
353 EAX = (EAX & 0xffff0000) | (res & 0xffff);
354 CC_SRC = (res != (int8_t)res);
357 void OPPROTO op_mulw_AX_T0(void)
360 res = (uint16_t)EAX * (uint16_t)T0;
361 EAX = (EAX & 0xffff0000) | (res & 0xffff);
362 EDX = (EDX & 0xffff0000) | ((res >> 16) & 0xffff);
366 void OPPROTO op_imulw_AX_T0(void)
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);
375 void OPPROTO op_mull_EAX_T0(void)
378 res = (uint64_t)((uint32_t)EAX) * (uint64_t)((uint32_t)T0);
384 void OPPROTO op_imull_EAX_T0(void)
387 res = (int64_t)((int32_t)EAX) * (int64_t)((int32_t)T0);
390 CC_SRC = (res != (int32_t)res);
393 void OPPROTO op_imulw_T0_T1(void)
396 res = (int16_t)T0 * (int16_t)T1;
398 CC_SRC = (res != (int16_t)res);
401 void OPPROTO op_imull_T0_T1(void)
404 res = (int64_t)((int32_t)T0) * (int64_t)((int32_t)T1);
406 CC_SRC = (res != (int32_t)res);
409 /* division, flags are undefined */
410 /* XXX: add exceptions for overflow & div by zero */
411 void OPPROTO op_divb_AL_T0(void)
413 unsigned int num, den, q, r;
415 num = (EAX & 0xffff);
417 q = (num / den) & 0xff;
418 r = (num % den) & 0xff;
419 EAX = (EAX & 0xffff0000) | (r << 8) | q;
422 void OPPROTO op_idivb_AL_T0(void)
428 q = (num / den) & 0xff;
429 r = (num % den) & 0xff;
430 EAX = (EAX & 0xffff0000) | (r << 8) | q;
433 void OPPROTO op_divw_AX_T0(void)
435 unsigned int num, den, q, r;
437 num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
439 q = (num / den) & 0xffff;
440 r = (num % den) & 0xffff;
441 EAX = (EAX & 0xffff0000) | q;
442 EDX = (EDX & 0xffff0000) | r;
445 void OPPROTO op_idivw_AX_T0(void)
449 num = (EAX & 0xffff) | ((EDX & 0xffff) << 16);
451 q = (num / den) & 0xffff;
452 r = (num % den) & 0xffff;
453 EAX = (EAX & 0xffff0000) | q;
454 EDX = (EDX & 0xffff0000) | r;
457 void OPPROTO op_divl_EAX_T0(void)
459 unsigned int den, q, r;
462 num = EAX | ((uint64_t)EDX << 32);
470 void OPPROTO op_idivl_EAX_T0(void)
475 num = EAX | ((uint64_t)EDX << 32);
485 void OPPROTO op_movl_T0_im(void)
490 void OPPROTO op_movl_T1_im(void)
495 void OPPROTO op_movl_A0_im(void)
500 void OPPROTO op_addl_A0_im(void)
505 void OPPROTO op_andl_A0_ffff(void)
512 void OPPROTO op_ldub_T0_A0(void)
514 T0 = ldub((uint8_t *)A0);
517 void OPPROTO op_ldsb_T0_A0(void)
519 T0 = ldsb((int8_t *)A0);
522 void OPPROTO op_lduw_T0_A0(void)
524 T0 = lduw((uint8_t *)A0);
527 void OPPROTO op_ldsw_T0_A0(void)
529 T0 = ldsw((int8_t *)A0);
532 void OPPROTO op_ldl_T0_A0(void)
534 T0 = ldl((uint8_t *)A0);
537 void OPPROTO op_ldub_T1_A0(void)
539 T1 = ldub((uint8_t *)A0);
542 void OPPROTO op_ldsb_T1_A0(void)
544 T1 = ldsb((int8_t *)A0);
547 void OPPROTO op_lduw_T1_A0(void)
549 T1 = lduw((uint8_t *)A0);
552 void OPPROTO op_ldsw_T1_A0(void)
554 T1 = ldsw((int8_t *)A0);
557 void OPPROTO op_ldl_T1_A0(void)
559 T1 = ldl((uint8_t *)A0);
562 void OPPROTO op_stb_T0_A0(void)
564 stb((uint8_t *)A0, T0);
567 void OPPROTO op_stw_T0_A0(void)
569 stw((uint8_t *)A0, T0);
572 void OPPROTO op_stl_T0_A0(void)
574 stl((uint8_t *)A0, T0);
577 /* used for bit operations */
579 void OPPROTO op_add_bitw_A0_T1(void)
581 A0 += ((int32_t)T1 >> 4) << 1;
584 void OPPROTO op_add_bitl_A0_T1(void)
586 A0 += ((int32_t)T1 >> 5) << 2;
591 void OPPROTO op_jmp_T0(void)
596 void OPPROTO op_jmp_im(void)
601 void OPPROTO op_int_im(void)
604 raise_exception(EXCP0D_GPF);
607 void OPPROTO op_int3(void)
610 raise_exception(EXCP03_INT3);
613 void OPPROTO op_into(void)
616 eflags = cc_table[CC_OP].compute_all();
619 raise_exception(EXCP04_INTO);
630 #include "ops_template.h"
634 #include "ops_template.h"
638 #include "ops_template.h"
643 void OPPROTO op_movsbl_T0_T0(void)
648 void OPPROTO op_movzbl_T0_T0(void)
653 void OPPROTO op_movswl_T0_T0(void)
658 void OPPROTO op_movzwl_T0_T0(void)
663 void OPPROTO op_movswl_EAX_AX(void)
668 void OPPROTO op_movsbw_AX_AL(void)
670 EAX = (EAX & 0xffff0000) | ((int8_t)EAX & 0xffff);
673 void OPPROTO op_movslq_EDX_EAX(void)
675 EDX = (int32_t)EAX >> 31;
678 void OPPROTO op_movswl_DX_AX(void)
680 EDX = (EDX & 0xffff0000) | (((int16_t)EAX >> 15) & 0xffff);
684 /* XXX: add 16 bit operand/16 bit seg variants */
686 void op_pushl_T0(void)
690 stl((void *)offset, T0);
691 /* modify ESP after to handle exceptions correctly */
695 void op_pushl_T1(void)
699 stl((void *)offset, T1);
700 /* modify ESP after to handle exceptions correctly */
704 void op_popl_T0(void)
706 T0 = ldl((void *)ESP);
710 void op_addl_ESP_im(void)
717 /* slow jumps cases (compute x86 flags) */
718 void OPPROTO op_jo_cc(void)
721 eflags = cc_table[CC_OP].compute_all();
729 void OPPROTO op_jb_cc(void)
731 if (cc_table[CC_OP].compute_c())
738 void OPPROTO op_jz_cc(void)
741 eflags = cc_table[CC_OP].compute_all();
749 void OPPROTO op_jbe_cc(void)
752 eflags = cc_table[CC_OP].compute_all();
753 if (eflags & (CC_Z | CC_C))
760 void OPPROTO op_js_cc(void)
763 eflags = cc_table[CC_OP].compute_all();
771 void OPPROTO op_jp_cc(void)
774 eflags = cc_table[CC_OP].compute_all();
782 void OPPROTO op_jl_cc(void)
785 eflags = cc_table[CC_OP].compute_all();
786 if ((eflags ^ (eflags >> 4)) & 0x80)
793 void OPPROTO op_jle_cc(void)
796 eflags = cc_table[CC_OP].compute_all();
797 if (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z))
804 /* slow set cases (compute x86 flags) */
805 void OPPROTO op_seto_T0_cc(void)
808 eflags = cc_table[CC_OP].compute_all();
809 T0 = (eflags >> 11) & 1;
812 void OPPROTO op_setb_T0_cc(void)
814 T0 = cc_table[CC_OP].compute_c();
817 void OPPROTO op_setz_T0_cc(void)
820 eflags = cc_table[CC_OP].compute_all();
821 T0 = (eflags >> 6) & 1;
824 void OPPROTO op_setbe_T0_cc(void)
827 eflags = cc_table[CC_OP].compute_all();
828 T0 = (eflags & (CC_Z | CC_C)) != 0;
831 void OPPROTO op_sets_T0_cc(void)
834 eflags = cc_table[CC_OP].compute_all();
835 T0 = (eflags >> 7) & 1;
838 void OPPROTO op_setp_T0_cc(void)
841 eflags = cc_table[CC_OP].compute_all();
842 T0 = (eflags >> 2) & 1;
845 void OPPROTO op_setl_T0_cc(void)
848 eflags = cc_table[CC_OP].compute_all();
849 T0 = ((eflags ^ (eflags >> 4)) >> 7) & 1;
852 void OPPROTO op_setle_T0_cc(void)
855 eflags = cc_table[CC_OP].compute_all();
856 T0 = (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) != 0;
859 void OPPROTO op_xor_T0_1(void)
864 void OPPROTO op_set_cc_op(void)
869 void OPPROTO op_movl_eflags_T0(void)
872 DF = 1 - (2 * ((T0 >> 10) & 1));
875 /* XXX: compute only O flag */
876 void OPPROTO op_movb_eflags_T0(void)
879 of = cc_table[CC_OP].compute_all() & CC_O;
883 void OPPROTO op_movl_T0_eflags(void)
885 T0 = cc_table[CC_OP].compute_all();
886 T0 |= (DF & DIRECTION_FLAG);
889 void OPPROTO op_cld(void)
894 void OPPROTO op_std(void)
899 void OPPROTO op_clc(void)
902 eflags = cc_table[CC_OP].compute_all();
907 void OPPROTO op_stc(void)
910 eflags = cc_table[CC_OP].compute_all();
915 void OPPROTO op_cmc(void)
918 eflags = cc_table[CC_OP].compute_all();
923 static int compute_all_eflags(void)
928 static int compute_c_eflags(void)
930 return CC_SRC & CC_C;
933 static int compute_c_mul(void)
940 static int compute_all_mul(void)
942 int cf, pf, af, zf, sf, of;
944 pf = 0; /* undefined */
945 af = 0; /* undefined */
946 zf = 0; /* undefined */
947 sf = 0; /* undefined */
949 return cf | pf | af | zf | sf | of;
952 CCTable cc_table[CC_OP_NB] = {
953 [CC_OP_DYNAMIC] = { /* should never happen */ },
955 [CC_OP_EFLAGS] = { compute_all_eflags, compute_c_eflags },
957 [CC_OP_MUL] = { compute_all_mul, compute_c_mul },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
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 },
996 /* floating point support */
998 #ifdef USE_X86LDOUBLE
999 /* use long double functions */
1000 #define lrint lrintl
1001 #define llrint llrintl
1009 #define atan2 atan2l
1010 #define floor floorl
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);
1029 #define RC_MASK 0xc00
1030 #define RC_NEAR 0x000
1031 #define RC_DOWN 0x400
1033 #define RC_CHOP 0xc00
1035 #define MAXTAN 9223372036854775808.0
1037 #ifdef USE_X86LDOUBLE
1043 unsigned long long lower;
1044 unsigned short upper;
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
1060 #ifndef WORDS_BIGENDIAN
1062 unsigned long lower;
1068 unsigned long lower;
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)
1085 void OPPROTO op_flds_FT0_A0(void)
1087 FT0 = ldfl((void *)A0);
1090 void OPPROTO op_fldl_FT0_A0(void)
1092 FT0 = ldfq((void *)A0);
1095 void OPPROTO op_fild_FT0_A0(void)
1097 FT0 = (CPU86_LDouble)ldsw((void *)A0);
1100 void OPPROTO op_fildl_FT0_A0(void)
1102 FT0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
1105 void OPPROTO op_fildll_FT0_A0(void)
1107 FT0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
1112 void OPPROTO op_flds_ST0_A0(void)
1114 ST0 = ldfl((void *)A0);
1117 void OPPROTO op_fldl_ST0_A0(void)
1119 ST0 = ldfq((void *)A0);
1122 #ifdef USE_X86LDOUBLE
1123 void OPPROTO op_fldt_ST0_A0(void)
1125 ST0 = *(long double *)A0;
1128 void helper_fldt_ST0_A0(void)
1130 CPU86_LDoubleU temp;
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);
1141 void OPPROTO op_fldt_ST0_A0(void)
1143 helper_fldt_ST0_A0();
1147 void OPPROTO op_fild_ST0_A0(void)
1149 ST0 = (CPU86_LDouble)ldsw((void *)A0);
1152 void OPPROTO op_fildl_ST0_A0(void)
1154 ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
1157 void OPPROTO op_fildll_ST0_A0(void)
1159 ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
1164 void OPPROTO op_fsts_ST0_A0(void)
1166 stfl((void *)A0, (float)ST0);
1169 void OPPROTO op_fstl_ST0_A0(void)
1171 stfq((void *)A0, (double)ST0);
1174 #ifdef USE_X86LDOUBLE
1175 void OPPROTO op_fstt_ST0_A0(void)
1177 *(long double *)A0 = ST0;
1180 void helper_fstt_ST0_A0(void)
1182 CPU86_LDoubleU temp;
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);
1193 void OPPROTO op_fstt_ST0_A0(void)
1195 helper_fstt_ST0_A0();
1199 void OPPROTO op_fist_ST0_A0(void)
1203 stw((void *)A0, val);
1206 void OPPROTO op_fistl_ST0_A0(void)
1210 stl((void *)A0, val);
1213 void OPPROTO op_fistll_ST0_A0(void)
1217 stq((void *)A0, val);
1222 #define MUL10(iv) ( iv + iv + (iv << 3) )
1224 void helper_fbld_ST0_A0(void)
1227 CPU86_LDouble fpsrcop;
1231 /* in this code, seg/m32i will be used as temporary ptr/int */
1232 seg = (uint8_t *)A0 + 8;
1234 /* XXX: raise exception */
1238 /* XXX: raise exception */
1239 if ((v & 0xf0) != 0)
1241 m32i = v; /* <-- d14 */
1243 m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d13 */
1244 m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d12 */
1246 m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d11 */
1247 m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d10 */
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;
1254 m32i = (v >> 4); /* <-- d7 */
1255 m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d6 */
1257 m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d5 */
1258 m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d4 */
1260 m32i = MUL10(m32i) + (v >> 4); /* <-- val * 10 + d3 */
1261 m32i = MUL10(m32i) + (v & 0xf); /* <-- val * 10 + d2 */
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 )
1271 void OPPROTO op_fbld_ST0_A0(void)
1273 helper_fbld_ST0_A0();
1276 void helper_fbst_ST0_A0(void)
1278 CPU86_LDouble fptemp;
1279 CPU86_LDouble fpsrcop;
1281 uint8_t *mem_ref, *mem_end;
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);
1290 stw(mem_end, 0x0000);
1292 while (mem_ref < mem_end) {
1295 fptemp = floor(fpsrcop/10.0);
1296 v = ((int)(fpsrcop - fptemp*10.0));
1297 if (fptemp == 0.0) {
1302 fptemp = floor(fpsrcop/10.0);
1303 v |= (((int)(fpsrcop - fptemp*10.0)) << 4);
1307 while (mem_ref < mem_end) {
1312 void OPPROTO op_fbst_ST0_A0(void)
1314 helper_fbst_ST0_A0();
1319 static inline void fpush(void)
1321 env->fpstt = (env->fpstt - 1) & 7;
1322 env->fptags[env->fpstt] = 0; /* validate stack entry */
1325 static inline void fpop(void)
1327 env->fptags[env->fpstt] = 1; /* invvalidate stack entry */
1328 env->fpstt = (env->fpstt + 1) & 7;
1331 void OPPROTO op_fpush(void)
1336 void OPPROTO op_fpop(void)
1341 void OPPROTO op_fdecstp(void)
1343 env->fpstt = (env->fpstt - 1) & 7;
1344 env->fpus &= (~0x4700);
1347 void OPPROTO op_fincstp(void)
1349 env->fpstt = (env->fpstt + 1) & 7;
1350 env->fpus &= (~0x4700);
1353 void OPPROTO op_fmov_ST0_FT0(void)
1358 void OPPROTO op_fmov_FT0_STN(void)
1363 void OPPROTO op_fmov_ST0_STN(void)
1368 void OPPROTO op_fmov_STN_ST0(void)
1373 void OPPROTO op_fxchg_ST0_STN(void)
1381 /* FPU operations */
1383 /* XXX: handle nans */
1384 void OPPROTO op_fcom_ST0_FT0(void)
1386 env->fpus &= (~0x4500); /* (C3,C2,C0) <-- 000 */
1388 env->fpus |= 0x100; /* (C3,C2,C0) <-- 001 */
1389 else if (ST0 == FT0)
1390 env->fpus |= 0x4000; /* (C3,C2,C0) <-- 100 */
1394 /* XXX: handle nans */
1395 void OPPROTO op_fucom_ST0_FT0(void)
1397 env->fpus &= (~0x4500); /* (C3,C2,C0) <-- 000 */
1399 env->fpus |= 0x100; /* (C3,C2,C0) <-- 001 */
1400 else if (ST0 == FT0)
1401 env->fpus |= 0x4000; /* (C3,C2,C0) <-- 100 */
1405 void OPPROTO op_fadd_ST0_FT0(void)
1410 void OPPROTO op_fmul_ST0_FT0(void)
1415 void OPPROTO op_fsub_ST0_FT0(void)
1420 void OPPROTO op_fsubr_ST0_FT0(void)
1425 void OPPROTO op_fdiv_ST0_FT0(void)
1430 void OPPROTO op_fdivr_ST0_FT0(void)
1435 /* fp operations between STN and ST0 */
1437 void OPPROTO op_fadd_STN_ST0(void)
1442 void OPPROTO op_fmul_STN_ST0(void)
1447 void OPPROTO op_fsub_STN_ST0(void)
1452 void OPPROTO op_fsubr_STN_ST0(void)
1459 void OPPROTO op_fdiv_STN_ST0(void)
1464 void OPPROTO op_fdivr_STN_ST0(void)
1471 /* misc FPU operations */
1472 void OPPROTO op_fchs_ST0(void)
1477 void OPPROTO op_fabs_ST0(void)
1482 void helper_fxam_ST0(void)
1484 CPU86_LDoubleU temp;
1489 env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
1491 env->fpus |= 0x200; /* C1 <-- 1 */
1493 expdif = EXPD(temp);
1494 if (expdif == MAXEXPD) {
1495 if (MANTD(temp) == 0)
1496 env->fpus |= 0x500 /*Infinity*/;
1498 env->fpus |= 0x100 /*NaN*/;
1499 } else if (expdif == 0) {
1500 if (MANTD(temp) == 0)
1501 env->fpus |= 0x4000 /*Zero*/;
1503 env->fpus |= 0x4400 /*Denormal*/;
1509 void OPPROTO op_fxam_ST0(void)
1514 void OPPROTO op_fld1_ST0(void)
1516 ST0 = *(CPU86_LDouble *)&f15rk[1];
1519 void OPPROTO op_fldl2t_ST0(void)
1521 ST0 = *(CPU86_LDouble *)&f15rk[6];
1524 void OPPROTO op_fldl2e_ST0(void)
1526 ST0 = *(CPU86_LDouble *)&f15rk[5];
1529 void OPPROTO op_fldpi_ST0(void)
1531 ST0 = *(CPU86_LDouble *)&f15rk[2];
1534 void OPPROTO op_fldlg2_ST0(void)
1536 ST0 = *(CPU86_LDouble *)&f15rk[3];
1539 void OPPROTO op_fldln2_ST0(void)
1541 ST0 = *(CPU86_LDouble *)&f15rk[4];
1544 void OPPROTO op_fldz_ST0(void)
1546 ST0 = *(CPU86_LDouble *)&f15rk[0];
1549 void OPPROTO op_fldz_FT0(void)
1551 ST0 = *(CPU86_LDouble *)&f15rk[0];
1554 void helper_f2xm1(void)
1556 ST0 = pow(2.0,ST0) - 1.0;
1559 void helper_fyl2x(void)
1561 CPU86_LDouble fptemp;
1565 fptemp = log(fptemp)/log(2.0); /* log2(ST) */
1569 env->fpus &= (~0x4700);
1574 void helper_fptan(void)
1576 CPU86_LDouble fptemp;
1579 if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
1585 env->fpus &= (~0x400); /* C2 <-- 0 */
1586 /* the above code is for |arg| < 2**52 only */
1590 void helper_fpatan(void)
1592 CPU86_LDouble fptemp, fpsrcop;
1596 ST1 = atan2(fpsrcop,fptemp);
1600 void helper_fxtract(void)
1602 CPU86_LDoubleU temp;
1603 unsigned int expdif;
1606 expdif = EXPD(temp) - EXPBIAS;
1607 /*DP exponent bias*/
1614 void helper_fprem1(void)
1616 CPU86_LDouble dblq, fpsrcop, fptemp;
1617 CPU86_LDoubleU fpsrcop1, fptemp1;
1623 fpsrcop1.d = fpsrcop;
1625 expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
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 */
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);
1647 void helper_fprem(void)
1649 CPU86_LDouble dblq, fpsrcop, fptemp;
1650 CPU86_LDoubleU fpsrcop1, fptemp1;
1656 fpsrcop1.d = fpsrcop;
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 */
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);
1680 void helper_fyl2xp1(void)
1682 CPU86_LDouble fptemp;
1685 if ((fptemp+1.0)>0.0) {
1686 fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */
1690 env->fpus &= (~0x4700);
1695 void helper_fsqrt(void)
1697 CPU86_LDouble fptemp;
1701 env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
1707 void helper_fsincos(void)
1709 CPU86_LDouble fptemp;
1712 if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
1718 env->fpus &= (~0x400); /* C2 <-- 0 */
1719 /* the above code is for |arg| < 2**63 only */
1723 void helper_frndint(void)
1728 void helper_fscale(void)
1730 CPU86_LDouble fpsrcop, fptemp;
1733 fptemp = pow(fpsrcop,ST1);
1737 void helper_fsin(void)
1739 CPU86_LDouble fptemp;
1742 if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
1746 env->fpus &= (~0x400); /* C2 <-- 0 */
1747 /* the above code is for |arg| < 2**53 only */
1751 void helper_fcos(void)
1753 CPU86_LDouble fptemp;
1756 if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
1760 env->fpus &= (~0x400); /* C2 <-- 0 */
1761 /* the above code is for |arg5 < 2**63 only */
1765 /* associated heplers to reduce generated code length and to simplify
1766 relocation (FP constants are usually stored in .rodata section) */
1768 void OPPROTO op_f2xm1(void)
1773 void OPPROTO op_fyl2x(void)
1778 void OPPROTO op_fptan(void)
1783 void OPPROTO op_fpatan(void)
1788 void OPPROTO op_fxtract(void)
1793 void OPPROTO op_fprem1(void)
1799 void OPPROTO op_fprem(void)
1804 void OPPROTO op_fyl2xp1(void)
1809 void OPPROTO op_fsqrt(void)
1814 void OPPROTO op_fsincos(void)
1819 void OPPROTO op_frndint(void)
1824 void OPPROTO op_fscale(void)
1829 void OPPROTO op_fsin(void)
1834 void OPPROTO op_fcos(void)
1839 void OPPROTO op_fnstsw_A0(void)
1842 fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
1843 stw((void *)A0, fpus);
1846 void OPPROTO op_fnstsw_EAX(void)
1849 fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
1850 EAX = (EAX & 0xffff0000) | fpus;
1853 void OPPROTO op_fnstcw_A0(void)
1855 stw((void *)A0, env->fpuc);
1858 void OPPROTO op_fldcw_A0(void)
1861 env->fpuc = lduw((void *)A0);
1862 /* set rounding mode */
1863 switch(env->fpuc & RC_MASK) {
1866 rnd_type = FE_TONEAREST;
1869 rnd_type = FE_DOWNWARD;
1872 rnd_type = FE_UPWARD;
1875 rnd_type = FE_TOWARDZERO;
1878 fesetround(rnd_type);
1881 /* main execution loop */
1882 uint8_t code_gen_buffer[65536];
1885 static const char *cc_op_str[] = {
1919 int cpu_x86_exec(CPUX86State *env1)
1921 int saved_T0, saved_T1, saved_A0;
1922 CPUX86State *saved_env;
1923 int code_gen_size, ret;
1924 void (*gen_func)(void);
1926 /* first we save global registers */
1933 /* prepare setjmp context for exception handling */
1934 if (setjmp(env->jmp_env) == 0) {
1939 eflags = cc_table[CC_OP].compute_all();
1940 eflags |= (DF & DIRECTION_FLAG);
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' : '-'
1957 fprintf(logfile, "ST0=%f ST1=%f ST2=%f ST3=%f\n",
1958 (double)ST0, (double)ST1, (double)ST(2), (double)ST(3));
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;
1968 ret = env->exception_index;
1970 /* restore global registers */