]>
git.proxmox.com Git - qemu.git/blob - op-i386.c
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 void OPPROTO
op_fild_ST0_A0(void)
1124 ST0
= (CPU86_LDouble
)ldsw((void *)A0
);
1127 void OPPROTO
op_fildl_ST0_A0(void)
1129 ST0
= (CPU86_LDouble
)((int32_t)ldl((void *)A0
));
1132 void OPPROTO
op_fildll_ST0_A0(void)
1134 ST0
= (CPU86_LDouble
)((int64_t)ldq((void *)A0
));
1139 void OPPROTO
op_fsts_ST0_A0(void)
1141 stfl((void *)A0
, (float)ST0
);
1144 void OPPROTO
op_fstl_ST0_A0(void)
1146 ST0
= ldfq((void *)A0
);
1149 void OPPROTO
op_fist_ST0_A0(void)
1153 stw((void *)A0
, val
);
1156 void OPPROTO
op_fistl_ST0_A0(void)
1160 stl((void *)A0
, val
);
1163 void OPPROTO
op_fistll_ST0_A0(void)
1167 stq((void *)A0
, val
);
1172 static inline void fpush(void)
1174 env
->fpstt
= (env
->fpstt
- 1) & 7;
1175 env
->fptags
[env
->fpstt
] = 0; /* validate stack entry */
1178 static inline void fpop(void)
1180 env
->fptags
[env
->fpstt
] = 1; /* invvalidate stack entry */
1181 env
->fpstt
= (env
->fpstt
+ 1) & 7;
1184 void OPPROTO
op_fpush(void)
1189 void OPPROTO
op_fpop(void)
1194 void OPPROTO
op_fdecstp(void)
1196 env
->fpstt
= (env
->fpstt
- 1) & 7;
1197 env
->fpus
&= (~0x4700);
1200 void OPPROTO
op_fincstp(void)
1202 env
->fpstt
= (env
->fpstt
+ 1) & 7;
1203 env
->fpus
&= (~0x4700);
1206 void OPPROTO
op_fmov_ST0_FT0(void)
1211 void OPPROTO
op_fmov_FT0_STN(void)
1216 void OPPROTO
op_fmov_ST0_STN(void)
1221 void OPPROTO
op_fmov_STN_ST0(void)
1226 void OPPROTO
op_fxchg_ST0_STN(void)
1234 /* FPU operations */
1236 /* XXX: handle nans */
1237 void OPPROTO
op_fcom_ST0_FT0(void)
1239 env
->fpus
&= (~0x4500); /* (C3,C2,C0) <-- 000 */
1241 env
->fpus
|= 0x100; /* (C3,C2,C0) <-- 001 */
1242 else if (ST0
== FT0
)
1243 env
->fpus
|= 0x4000; /* (C3,C2,C0) <-- 100 */
1247 void OPPROTO
op_fadd_ST0_FT0(void)
1252 void OPPROTO
op_fmul_ST0_FT0(void)
1257 void OPPROTO
op_fsub_ST0_FT0(void)
1262 void OPPROTO
op_fsubr_ST0_FT0(void)
1267 void OPPROTO
op_fdiv_ST0_FT0(void)
1272 void OPPROTO
op_fdivr_ST0_FT0(void)
1277 /* fp operations between STN and ST0 */
1279 void OPPROTO
op_fadd_STN_ST0(void)
1284 void OPPROTO
op_fmul_STN_ST0(void)
1289 void OPPROTO
op_fsub_STN_ST0(void)
1294 void OPPROTO
op_fsubr_STN_ST0(void)
1301 void OPPROTO
op_fdiv_STN_ST0(void)
1306 void OPPROTO
op_fdivr_STN_ST0(void)
1313 /* misc FPU operations */
1314 void OPPROTO
op_fchs_ST0(void)
1319 void OPPROTO
op_fabs_ST0(void)
1324 void OPPROTO
op_fxam_ST0(void)
1326 CPU86_LDoubleU temp
;
1331 env
->fpus
&= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
1333 env
->fpus
|= 0x200; /* C1 <-- 1 */
1335 expdif
= EXPD(temp
);
1336 if (expdif
== MAXEXPD
) {
1337 if (MANTD(temp
) == 0)
1338 env
->fpus
|= 0x500 /*Infinity*/;
1340 env
->fpus
|= 0x100 /*NaN*/;
1341 } else if (expdif
== 0) {
1342 if (MANTD(temp
) == 0)
1343 env
->fpus
|= 0x4000 /*Zero*/;
1345 env
->fpus
|= 0x4400 /*Denormal*/;
1352 void OPPROTO
op_fld1_ST0(void)
1354 ST0
= *(CPU86_LDouble
*)&f15rk
[1];
1357 void OPPROTO
op_fld2t_ST0(void)
1359 ST0
= *(CPU86_LDouble
*)&f15rk
[6];
1362 void OPPROTO
op_fld2e_ST0(void)
1364 ST0
= *(CPU86_LDouble
*)&f15rk
[5];
1367 void OPPROTO
op_fldpi_ST0(void)
1369 ST0
= *(CPU86_LDouble
*)&f15rk
[2];
1372 void OPPROTO
op_fldlg2_ST0(void)
1374 ST0
= *(CPU86_LDouble
*)&f15rk
[3];
1377 void OPPROTO
op_fldln2_ST0(void)
1379 ST0
= *(CPU86_LDouble
*)&f15rk
[4];
1382 void OPPROTO
op_fldz_ST0(void)
1384 ST0
= *(CPU86_LDouble
*)&f15rk
[0];
1387 void OPPROTO
op_fldz_FT0(void)
1389 ST0
= *(CPU86_LDouble
*)&f15rk
[0];
1392 void helper_f2xm1(void)
1394 ST0
= pow(2.0,ST0
) - 1.0;
1397 void helper_fyl2x(void)
1399 CPU86_LDouble fptemp
;
1403 fptemp
= log(fptemp
)/log(2.0); /* log2(ST) */
1407 env
->fpus
&= (~0x4700);
1412 void helper_fptan(void)
1414 CPU86_LDouble fptemp
;
1417 if((fptemp
> MAXTAN
)||(fptemp
< -MAXTAN
)) {
1423 env
->fpus
&= (~0x400); /* C2 <-- 0 */
1424 /* the above code is for |arg| < 2**52 only */
1428 void helper_fpatan(void)
1430 CPU86_LDouble fptemp
, fpsrcop
;
1434 ST1
= atan2(fpsrcop
,fptemp
);
1438 void helper_fxtract(void)
1440 CPU86_LDoubleU temp
;
1441 unsigned int expdif
;
1444 expdif
= EXPD(temp
) - EXPBIAS
;
1445 /*DP exponent bias*/
1452 void helper_fprem1(void)
1454 CPU86_LDouble dblq
, fpsrcop
, fptemp
;
1455 CPU86_LDoubleU fpsrcop1
, fptemp1
;
1461 fpsrcop1
.d
= fpsrcop
;
1463 expdif
= EXPD(fpsrcop1
) - EXPD(fptemp1
);
1465 dblq
= fpsrcop
/ fptemp
;
1466 dblq
= (dblq
< 0.0)? ceil(dblq
): floor(dblq
);
1467 ST0
= fpsrcop
- fptemp
*dblq
;
1468 q
= (int)dblq
; /* cutting off top bits is assumed here */
1469 env
->fpus
&= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
1470 /* (C0,C1,C3) <-- (q2,q1,q0) */
1471 env
->fpus
|= (q
&0x4) << 6; /* (C0) <-- q2 */
1472 env
->fpus
|= (q
&0x2) << 8; /* (C1) <-- q1 */
1473 env
->fpus
|= (q
&0x1) << 14; /* (C3) <-- q0 */
1475 env
->fpus
|= 0x400; /* C2 <-- 1 */
1476 fptemp
= pow(2.0, expdif
-50);
1477 fpsrcop
= (ST0
/ ST1
) / fptemp
;
1478 /* fpsrcop = integer obtained by rounding to the nearest */
1479 fpsrcop
= (fpsrcop
-floor(fpsrcop
) < ceil(fpsrcop
)-fpsrcop
)?
1480 floor(fpsrcop
): ceil(fpsrcop
);
1481 ST0
-= (ST1
* fpsrcop
* fptemp
);
1485 void helper_fprem(void)
1487 CPU86_LDouble dblq
, fpsrcop
, fptemp
;
1488 CPU86_LDoubleU fpsrcop1
, fptemp1
;
1494 fpsrcop1
.d
= fpsrcop
;
1496 expdif
= EXPD(fpsrcop1
) - EXPD(fptemp1
);
1497 if ( expdif
< 53 ) {
1498 dblq
= fpsrcop
/ fptemp
;
1499 dblq
= (dblq
< 0.0)? ceil(dblq
): floor(dblq
);
1500 ST0
= fpsrcop
- fptemp
*dblq
;
1501 q
= (int)dblq
; /* cutting off top bits is assumed here */
1502 env
->fpus
&= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
1503 /* (C0,C1,C3) <-- (q2,q1,q0) */
1504 env
->fpus
|= (q
&0x4) << 6; /* (C0) <-- q2 */
1505 env
->fpus
|= (q
&0x2) << 8; /* (C1) <-- q1 */
1506 env
->fpus
|= (q
&0x1) << 14; /* (C3) <-- q0 */
1508 env
->fpus
|= 0x400; /* C2 <-- 1 */
1509 fptemp
= pow(2.0, expdif
-50);
1510 fpsrcop
= (ST0
/ ST1
) / fptemp
;
1511 /* fpsrcop = integer obtained by chopping */
1512 fpsrcop
= (fpsrcop
< 0.0)?
1513 -(floor(fabs(fpsrcop
))): floor(fpsrcop
);
1514 ST0
-= (ST1
* fpsrcop
* fptemp
);
1518 void helper_fyl2xp1(void)
1520 CPU86_LDouble fptemp
;
1523 if ((fptemp
+1.0)>0.0) {
1524 fptemp
= log(fptemp
+1.0) / log(2.0); /* log2(ST+1.0) */
1528 env
->fpus
&= (~0x4700);
1533 void helper_fsqrt(void)
1535 CPU86_LDouble fptemp
;
1539 env
->fpus
&= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
1545 void helper_fsincos(void)
1547 CPU86_LDouble fptemp
;
1550 if ((fptemp
> MAXTAN
)||(fptemp
< -MAXTAN
)) {
1556 env
->fpus
&= (~0x400); /* C2 <-- 0 */
1557 /* the above code is for |arg| < 2**63 only */
1561 void helper_frndint(void)
1566 void helper_fscale(void)
1568 CPU86_LDouble fpsrcop
, fptemp
;
1571 fptemp
= pow(fpsrcop
,ST1
);
1575 void helper_fsin(void)
1577 CPU86_LDouble fptemp
;
1580 if ((fptemp
> MAXTAN
)||(fptemp
< -MAXTAN
)) {
1584 env
->fpus
&= (~0x400); /* C2 <-- 0 */
1585 /* the above code is for |arg| < 2**53 only */
1589 void helper_fcos(void)
1591 CPU86_LDouble fptemp
;
1594 if((fptemp
> MAXTAN
)||(fptemp
< -MAXTAN
)) {
1598 env
->fpus
&= (~0x400); /* C2 <-- 0 */
1599 /* the above code is for |arg5 < 2**63 only */
1603 /* associated heplers to reduce generated code length and to simplify
1604 relocation (FP constants are usually stored in .rodata section) */
1606 void OPPROTO
op_f2xm1(void)
1611 void OPPROTO
op_fyl2x(void)
1616 void OPPROTO
op_fptan(void)
1621 void OPPROTO
op_fpatan(void)
1626 void OPPROTO
op_fxtract(void)
1631 void OPPROTO
op_fprem1(void)
1637 void OPPROTO
op_fprem(void)
1642 void OPPROTO
op_fyl2xp1(void)
1647 void OPPROTO
op_fsqrt(void)
1652 void OPPROTO
op_fsincos(void)
1657 void OPPROTO
op_frndint(void)
1662 void OPPROTO
op_fscale(void)
1667 void OPPROTO
op_fsin(void)
1672 void OPPROTO
op_fcos(void)
1677 void OPPROTO
op_fnstsw_A0(void)
1680 fpus
= (env
->fpus
& ~0x3800) | (env
->fpstt
& 0x7) << 11;
1681 stw((void *)A0
, fpus
);
1684 void OPPROTO
op_fnstcw_A0(void)
1686 stw((void *)A0
, env
->fpuc
);
1689 void OPPROTO
op_fldcw_A0(void)
1692 env
->fpuc
= lduw((void *)A0
);
1693 /* set rounding mode */
1694 switch(env
->fpuc
& RC_MASK
) {
1697 rnd_type
= FE_TONEAREST
;
1700 rnd_type
= FE_DOWNWARD
;
1703 rnd_type
= FE_UPWARD
;
1706 rnd_type
= FE_TOWARDZERO
;
1709 fesetround(rnd_type
);
1712 /* main execution loop */
1713 uint8_t code_gen_buffer
[65536];
1716 static const char *cc_op_str
[] = {
1750 int cpu_x86_exec(CPUX86State
*env1
)
1752 int saved_T0
, saved_T1
, saved_A0
;
1753 CPUX86State
*saved_env
;
1754 int code_gen_size
, ret
;
1755 void (*gen_func
)(void);
1757 /* first we save global registers */
1764 /* prepare setjmp context for exception handling */
1765 if (setjmp(env
->jmp_env
) == 0) {
1770 eflags
= cc_table
[CC_OP
].compute_all();
1771 eflags
|= (DF
& DIRECTION_FLAG
);
1773 "EAX=%08x EBX=%08X ECX=%08x EDX=%08x\n"
1774 "ESI=%08x EDI=%08X EBP=%08x ESP=%08x\n"
1775 "CCS=%08x CCD=%08x CCO=%-8s EFL=%c%c%c%c%c%c%c\n",
1776 env
->regs
[R_EAX
], env
->regs
[R_EBX
], env
->regs
[R_ECX
], env
->regs
[R_EDX
],
1777 env
->regs
[R_ESI
], env
->regs
[R_EDI
], env
->regs
[R_EBP
], env
->regs
[R_ESP
],
1778 env
->cc_src
, env
->cc_dst
, cc_op_str
[env
->cc_op
],
1779 eflags
& DIRECTION_FLAG
? 'D' : '-',
1780 eflags
& CC_O
? 'O' : '-',
1781 eflags
& CC_S
? 'S' : '-',
1782 eflags
& CC_Z
? 'Z' : '-',
1783 eflags
& CC_A
? 'A' : '-',
1784 eflags
& CC_P
? 'P' : '-',
1785 eflags
& CC_C
? 'C' : '-'
1789 cpu_x86_gen_code(code_gen_buffer
, &code_gen_size
, (uint8_t *)env
->pc
);
1790 /* execute the generated code */
1791 gen_func
= (void *)code_gen_buffer
;
1795 ret
= env
->exception_index
;
1797 /* restore global registers */