]>
git.proxmox.com Git - qemu.git/blob - op-i386.c
1 typedef unsigned char uint8_t;
2 typedef unsigned short uint16_t;
3 typedef unsigned int uint32_t;
4 typedef unsigned long long uint64_t;
6 typedef signed char int8_t;
7 typedef signed short int16_t;
8 typedef signed int int32_t;
9 typedef signed long long int64_t;
14 register int T0
asm("esi");
15 register int T1
asm("ebx");
16 register int A0
asm("edi");
17 register struct CPUX86State
*env
asm("ebp");
18 #define FORCE_RET() asm volatile ("ret");
21 register int T0
asm("r24");
22 register int T1
asm("r25");
23 register int A0
asm("r26");
24 register struct CPUX86State
*env
asm("r27");
25 #define FORCE_RET() asm volatile ("blr");
28 register int T0
asm("r4");
29 register int T1
asm("r5");
30 register int A0
asm("r6");
31 register struct CPUX86State
*env
asm("r7");
32 #define FORCE_RET() asm volatile ("mov pc, lr");
35 register int T0
asm("s0");
36 register int T1
asm("s1");
37 register int A0
asm("s2");
38 register struct CPUX86State
*env
asm("s3");
39 #define FORCE_RET() asm volatile ("jr $31");
42 register int T0
asm("l0");
43 register int T1
asm("l1");
44 register int A0
asm("l2");
45 register struct CPUX86State
*env
asm("l3");
46 #define FORCE_RET() asm volatile ("retl ; nop");
53 #define xglue(x, y) x ## y
54 #define glue(x, y) xglue(x, y)
56 #define EAX (env->regs[R_EAX])
57 #define ECX (env->regs[R_ECX])
58 #define EDX (env->regs[R_EDX])
59 #define EBX (env->regs[R_EBX])
60 #define ESP (env->regs[R_ESP])
61 #define EBP (env->regs[R_EBP])
62 #define ESI (env->regs[R_ESI])
63 #define EDI (env->regs[R_EDI])
67 #define CC_SRC (env->cc_src)
68 #define CC_DST (env->cc_dst)
69 #define CC_OP (env->cc_op)
72 #define FT0 (env->ft0)
73 #define ST0 (env->fpregs[env->fpstt])
74 #define ST(n) (env->fpregs[(env->fpstt + (n)) & 7])
77 extern int __op_param1
, __op_param2
, __op_param3
;
78 #define PARAM1 ((long)(&__op_param1))
79 #define PARAM2 ((long)(&__op_param2))
80 #define PARAM3 ((long)(&__op_param3))
84 typedef struct CCTable
{
85 int (*compute_all
)(void); /* return all the flags */
86 int (*compute_c
)(void); /* return the C flag */
89 /* NOTE: data are not static to force relocation generation by GCC */
90 extern CCTable cc_table
[];
92 uint8_t parity_table
[256] = {
93 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
94 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
95 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
96 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
97 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
98 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
99 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
100 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
101 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
102 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
103 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
104 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
105 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
106 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
107 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
108 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
109 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
110 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
111 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
112 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
113 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
114 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
115 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
116 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
117 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
118 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
119 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
120 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
121 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
122 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
123 CC_P
, 0, 0, CC_P
, 0, CC_P
, CC_P
, 0,
124 0, CC_P
, CC_P
, 0, CC_P
, 0, 0, CC_P
,
127 /* modulo 17 table */
128 const uint8_t rclw_table
[32] = {
129 0, 1, 2, 3, 4, 5, 6, 7,
130 8, 9,10,11,12,13,14,15,
131 16, 0, 1, 2, 3, 4, 5, 6,
132 7, 8, 9,10,11,12,13,14,
136 const uint8_t rclb_table
[32] = {
137 0, 1, 2, 3, 4, 5, 6, 7,
138 8, 0, 1, 2, 3, 4, 5, 6,
139 7, 8, 0, 1, 2, 3, 4, 5,
140 6, 7, 8, 0, 1, 2, 3, 4,
143 #ifdef USE_X86LDOUBLE
144 /* an array of Intel 80-bit FP constants, to be loaded via integer ops */
145 typedef unsigned short f15ld
[5];
146 const f15ld f15rk
[] =
148 /*0*/ {0x0000,0x0000,0x0000,0x0000,0x0000},
149 /*1*/ {0x0000,0x0000,0x0000,0x8000,0x3fff},
150 /*pi*/ {0xc235,0x2168,0xdaa2,0xc90f,0x4000},
151 /*lg2*/ {0xf799,0xfbcf,0x9a84,0x9a20,0x3ffd},
152 /*ln2*/ {0x79ac,0xd1cf,0x17f7,0xb172,0x3ffe},
153 /*l2e*/ {0xf0bc,0x5c17,0x3b29,0xb8aa,0x3fff},
154 /*l2t*/ {0x8afe,0xcd1b,0x784b,0xd49a,0x4000}
157 /* the same, 64-bit version */
158 typedef unsigned short f15ld
[4];
159 const f15ld f15rk
[] =
161 #ifndef WORDS_BIGENDIAN
162 /*0*/ {0x0000,0x0000,0x0000,0x0000},
163 /*1*/ {0x0000,0x0000,0x0000,0x3ff0},
164 /*pi*/ {0x2d18,0x5444,0x21fb,0x4009},
165 /*lg2*/ {0x79ff,0x509f,0x4413,0x3fd3},
166 /*ln2*/ {0x39ef,0xfefa,0x2e42,0x3fe6},
167 /*l2e*/ {0x82fe,0x652b,0x1547,0x3ff7},
168 /*l2t*/ {0xa371,0x0979,0x934f,0x400a}
170 /*0*/ {0x0000,0x0000,0x0000,0x0000},
171 /*1*/ {0x3ff0,0x0000,0x0000,0x0000},
172 /*pi*/ {0x4009,0x21fb,0x5444,0x2d18},
173 /*lg2*/ {0x3fd3,0x4413,0x509f,0x79ff},
174 /*ln2*/ {0x3fe6,0x2e42,0xfefa,0x39ef},
175 /*l2e*/ {0x3ff7,0x1547,0x652b,0x82fe},
176 /*l2t*/ {0x400a,0x934f,0x0979,0xa371}
181 /* n must be a constant to be efficient */
182 static inline int lshift(int x
, int n
)
190 /* exception support */
191 /* NOTE: not static to force relocation generation by GCC */
192 void raise_exception(int exception_index
)
194 env
->exception_index
= exception_index
;
195 longjmp(env
->jmp_env
, 1);
198 /* we define the various pieces of code used by the JIT */
202 #include "opreg_template.h"
208 #include "opreg_template.h"
214 #include "opreg_template.h"
220 #include "opreg_template.h"
226 #include "opreg_template.h"
232 #include "opreg_template.h"
238 #include "opreg_template.h"
244 #include "opreg_template.h"
250 void OPPROTO
op_addl_T0_T1_cc(void)
257 void OPPROTO
op_orl_T0_T1_cc(void)
263 void OPPROTO
op_adcl_T0_T1_cc(void)
266 T0
= T0
+ T1
+ cc_table
[CC_OP
].compute_c();
270 void OPPROTO
op_sbbl_T0_T1_cc(void)
273 T0
= T0
- T1
- cc_table
[CC_OP
].compute_c();
277 void OPPROTO
op_andl_T0_T1_cc(void)
283 void OPPROTO
op_subl_T0_T1_cc(void)
290 void OPPROTO
op_xorl_T0_T1_cc(void)
296 void OPPROTO
op_cmpl_T0_T1_cc(void)
302 void OPPROTO
op_notl_T0(void)
307 void OPPROTO
op_negl_T0_cc(void)
314 void OPPROTO
op_incl_T0_cc(void)
320 void OPPROTO
op_decl_T0_cc(void)
326 void OPPROTO
op_testl_T0_T1_cc(void)
331 /* multiply/divide */
332 void OPPROTO
op_mulb_AL_T0(void)
335 res
= (uint8_t)EAX
* (uint8_t)T0
;
336 EAX
= (EAX
& 0xffff0000) | res
;
337 CC_SRC
= (res
& 0xff00);
340 void OPPROTO
op_imulb_AL_T0(void)
343 res
= (int8_t)EAX
* (int8_t)T0
;
344 EAX
= (EAX
& 0xffff0000) | (res
& 0xffff);
345 CC_SRC
= (res
!= (int8_t)res
);
348 void OPPROTO
op_mulw_AX_T0(void)
351 res
= (uint16_t)EAX
* (uint16_t)T0
;
352 EAX
= (EAX
& 0xffff0000) | (res
& 0xffff);
353 EDX
= (EDX
& 0xffff0000) | ((res
>> 16) & 0xffff);
357 void OPPROTO
op_imulw_AX_T0(void)
360 res
= (int16_t)EAX
* (int16_t)T0
;
361 EAX
= (EAX
& 0xffff0000) | (res
& 0xffff);
362 EDX
= (EDX
& 0xffff0000) | ((res
>> 16) & 0xffff);
363 CC_SRC
= (res
!= (int16_t)res
);
366 void OPPROTO
op_mull_EAX_T0(void)
369 res
= (uint64_t)((uint32_t)EAX
) * (uint64_t)((uint32_t)T0
);
375 void OPPROTO
op_imull_EAX_T0(void)
378 res
= (int64_t)((int32_t)EAX
) * (int64_t)((int32_t)T0
);
381 CC_SRC
= (res
!= (int32_t)res
);
384 void OPPROTO
op_imulw_T0_T1(void)
387 res
= (int16_t)T0
* (int16_t)T1
;
389 CC_SRC
= (res
!= (int16_t)res
);
392 void OPPROTO
op_imull_T0_T1(void)
395 res
= (int64_t)((int32_t)EAX
) * (int64_t)((int32_t)T1
);
397 CC_SRC
= (res
!= (int32_t)res
);
400 /* division, flags are undefined */
401 /* XXX: add exceptions for overflow & div by zero */
402 void OPPROTO
op_divb_AL_T0(void)
404 unsigned int num
, den
, q
, r
;
406 num
= (EAX
& 0xffff);
408 q
= (num
/ den
) & 0xff;
409 r
= (num
% den
) & 0xff;
410 EAX
= (EAX
& 0xffff0000) | (r
<< 8) | q
;
413 void OPPROTO
op_idivb_AL_T0(void)
419 q
= (num
/ den
) & 0xff;
420 r
= (num
% den
) & 0xff;
421 EAX
= (EAX
& 0xffff0000) | (r
<< 8) | q
;
424 void OPPROTO
op_divw_AX_T0(void)
426 unsigned int num
, den
, q
, r
;
428 num
= (EAX
& 0xffff) | ((EDX
& 0xffff) << 16);
430 q
= (num
/ den
) & 0xffff;
431 r
= (num
% den
) & 0xffff;
432 EAX
= (EAX
& 0xffff0000) | q
;
433 EDX
= (EDX
& 0xffff0000) | r
;
436 void OPPROTO
op_idivw_AX_T0(void)
440 num
= (EAX
& 0xffff) | ((EDX
& 0xffff) << 16);
442 q
= (num
/ den
) & 0xffff;
443 r
= (num
% den
) & 0xffff;
444 EAX
= (EAX
& 0xffff0000) | q
;
445 EDX
= (EDX
& 0xffff0000) | r
;
448 void OPPROTO
op_divl_EAX_T0(void)
450 unsigned int den
, q
, r
;
453 num
= EAX
| ((uint64_t)EDX
<< 32);
461 void OPPROTO
op_idivl_EAX_T0(void)
466 num
= EAX
| ((uint64_t)EDX
<< 32);
476 void OPPROTO
op_movl_T0_im(void)
481 void OPPROTO
op_movl_T1_im(void)
486 void OPPROTO
op_movl_A0_im(void)
493 void OPPROTO
op_ldub_T0_A0(void)
495 T0
= ldub((uint8_t *)A0
);
498 void OPPROTO
op_ldsb_T0_A0(void)
500 T0
= ldsb((int8_t *)A0
);
503 void OPPROTO
op_lduw_T0_A0(void)
505 T0
= lduw((uint8_t *)A0
);
508 void OPPROTO
op_ldsw_T0_A0(void)
510 T0
= ldsw((int8_t *)A0
);
513 void OPPROTO
op_ldl_T0_A0(void)
515 T0
= ldl((uint8_t *)A0
);
518 void OPPROTO
op_ldub_T1_A0(void)
520 T1
= ldub((uint8_t *)A0
);
523 void OPPROTO
op_ldsb_T1_A0(void)
525 T1
= ldsb((int8_t *)A0
);
528 void OPPROTO
op_lduw_T1_A0(void)
530 T1
= lduw((uint8_t *)A0
);
533 void OPPROTO
op_ldsw_T1_A0(void)
535 T1
= ldsw((int8_t *)A0
);
538 void OPPROTO
op_ldl_T1_A0(void)
540 T1
= ldl((uint8_t *)A0
);
543 void OPPROTO
op_stb_T0_A0(void)
545 stb((uint8_t *)A0
, T0
);
548 void OPPROTO
op_stw_T0_A0(void)
550 stw((uint8_t *)A0
, T0
);
553 void OPPROTO
op_stl_T0_A0(void)
555 stl((uint8_t *)A0
, T0
);
562 void OPPROTO
op_jmp_T0(void)
567 void OPPROTO
op_jmp_im(void)
572 void OPPROTO
op_int_im(void)
575 raise_exception(EXCP0D_GPF
);
578 void OPPROTO
op_int3(void)
581 raise_exception(EXCP03_INT3
);
584 void OPPROTO
op_into(void)
587 eflags
= cc_table
[CC_OP
].compute_all();
590 raise_exception(EXCP04_INTO
);
601 #include "ops_template.h"
605 #include "ops_template.h"
609 #include "ops_template.h"
614 void OPPROTO
op_movsbl_T0_T0(void)
619 void OPPROTO
op_movzbl_T0_T0(void)
624 void OPPROTO
op_movswl_T0_T0(void)
629 void OPPROTO
op_movzwl_T0_T0(void)
634 void OPPROTO
op_movswl_EAX_AX(void)
639 void OPPROTO
op_movsbw_AX_AL(void)
641 EAX
= (EAX
& 0xffff0000) | ((int8_t)EAX
& 0xffff);
644 void OPPROTO
op_movslq_EDX_EAX(void)
646 EDX
= (int32_t)EAX
>> 31;
649 void OPPROTO
op_movswl_DX_AX(void)
651 EDX
= (EDX
& 0xffff0000) | (((int16_t)EAX
>> 15) & 0xffff);
655 /* XXX: add 16 bit operand/16 bit seg variants */
657 void op_pushl_T0(void)
661 stl((void *)offset
, T0
);
662 /* modify ESP after to handle exceptions correctly */
666 void op_pushl_T1(void)
670 stl((void *)offset
, T1
);
671 /* modify ESP after to handle exceptions correctly */
675 void op_popl_T0(void)
677 T0
= ldl((void *)ESP
);
681 void op_addl_ESP_im(void)
688 /* slow jumps cases (compute x86 flags) */
689 void OPPROTO
op_jo_cc(void)
692 eflags
= cc_table
[CC_OP
].compute_all();
700 void OPPROTO
op_jb_cc(void)
702 if (cc_table
[CC_OP
].compute_c())
709 void OPPROTO
op_jz_cc(void)
712 eflags
= cc_table
[CC_OP
].compute_all();
720 void OPPROTO
op_jbe_cc(void)
723 eflags
= cc_table
[CC_OP
].compute_all();
724 if (eflags
& (CC_Z
| CC_C
))
731 void OPPROTO
op_js_cc(void)
734 eflags
= cc_table
[CC_OP
].compute_all();
742 void OPPROTO
op_jp_cc(void)
745 eflags
= cc_table
[CC_OP
].compute_all();
753 void OPPROTO
op_jl_cc(void)
756 eflags
= cc_table
[CC_OP
].compute_all();
757 if ((eflags
^ (eflags
>> 4)) & 0x80)
764 void OPPROTO
op_jle_cc(void)
767 eflags
= cc_table
[CC_OP
].compute_all();
768 if (((eflags
^ (eflags
>> 4)) & 0x80) || (eflags
& CC_Z
))
775 /* slow set cases (compute x86 flags) */
776 void OPPROTO
op_seto_T0_cc(void)
779 eflags
= cc_table
[CC_OP
].compute_all();
780 T0
= (eflags
>> 11) & 1;
783 void OPPROTO
op_setb_T0_cc(void)
785 T0
= cc_table
[CC_OP
].compute_c();
788 void OPPROTO
op_setz_T0_cc(void)
791 eflags
= cc_table
[CC_OP
].compute_all();
792 T0
= (eflags
>> 6) & 1;
795 void OPPROTO
op_setbe_T0_cc(void)
798 eflags
= cc_table
[CC_OP
].compute_all();
799 T0
= (eflags
& (CC_Z
| CC_C
)) != 0;
802 void OPPROTO
op_sets_T0_cc(void)
805 eflags
= cc_table
[CC_OP
].compute_all();
806 T0
= (eflags
>> 7) & 1;
809 void OPPROTO
op_setp_T0_cc(void)
812 eflags
= cc_table
[CC_OP
].compute_all();
813 T0
= (eflags
>> 2) & 1;
816 void OPPROTO
op_setl_T0_cc(void)
819 eflags
= cc_table
[CC_OP
].compute_all();
820 T0
= ((eflags
^ (eflags
>> 4)) >> 7) & 1;
823 void OPPROTO
op_setle_T0_cc(void)
826 eflags
= cc_table
[CC_OP
].compute_all();
827 T0
= (((eflags
^ (eflags
>> 4)) & 0x80) || (eflags
& CC_Z
)) != 0;
830 void OPPROTO
op_xor_T0_1(void)
835 void OPPROTO
op_set_cc_op(void)
840 void OPPROTO
op_movl_eflags_T0(void)
843 DF
= 1 - (2 * ((T0
>> 10) & 1));
846 /* XXX: compute only O flag */
847 void OPPROTO
op_movb_eflags_T0(void)
850 of
= cc_table
[CC_OP
].compute_all() & CC_O
;
854 void OPPROTO
op_movl_T0_eflags(void)
856 T0
= cc_table
[CC_OP
].compute_all();
857 T0
|= (DF
& DIRECTION_FLAG
);
860 void OPPROTO
op_cld(void)
865 void OPPROTO
op_std(void)
870 void OPPROTO
op_clc(void)
873 eflags
= cc_table
[CC_OP
].compute_all();
878 void OPPROTO
op_stc(void)
881 eflags
= cc_table
[CC_OP
].compute_all();
886 void OPPROTO
op_cmc(void)
889 eflags
= cc_table
[CC_OP
].compute_all();
894 static int compute_all_eflags(void)
899 static int compute_c_eflags(void)
901 return CC_SRC
& CC_C
;
904 static int compute_c_mul(void)
911 static int compute_all_mul(void)
913 int cf
, pf
, af
, zf
, sf
, of
;
915 pf
= 0; /* undefined */
916 af
= 0; /* undefined */
917 zf
= 0; /* undefined */
918 sf
= 0; /* undefined */
920 return cf
| pf
| af
| zf
| sf
| of
;
923 CCTable cc_table
[CC_OP_NB
] = {
924 [CC_OP_DYNAMIC
] = { /* should never happen */ },
926 [CC_OP_EFLAGS
] = { compute_all_eflags
, compute_c_eflags
},
928 [CC_OP_MUL
] = { compute_all_mul
, compute_c_mul
},
930 [CC_OP_ADDB
] = { compute_all_addb
, compute_c_addb
},
931 [CC_OP_ADDW
] = { compute_all_addw
, compute_c_addw
},
932 [CC_OP_ADDL
] = { compute_all_addl
, compute_c_addl
},
934 [CC_OP_SUBB
] = { compute_all_subb
, compute_c_subb
},
935 [CC_OP_SUBW
] = { compute_all_subw
, compute_c_subw
},
936 [CC_OP_SUBL
] = { compute_all_subl
, compute_c_subl
},
938 [CC_OP_LOGICB
] = { compute_all_logicb
, compute_c_logicb
},
939 [CC_OP_LOGICW
] = { compute_all_logicw
, compute_c_logicw
},
940 [CC_OP_LOGICL
] = { compute_all_logicl
, compute_c_logicl
},
942 [CC_OP_INCB
] = { compute_all_incb
, compute_c_incb
},
943 [CC_OP_INCW
] = { compute_all_incw
, compute_c_incw
},
944 [CC_OP_INCL
] = { compute_all_incl
, compute_c_incl
},
946 [CC_OP_DECB
] = { compute_all_decb
, compute_c_incb
},
947 [CC_OP_DECW
] = { compute_all_decw
, compute_c_incw
},
948 [CC_OP_DECL
] = { compute_all_decl
, compute_c_incl
},
950 [CC_OP_SHLB
] = { compute_all_shlb
, compute_c_shlb
},
951 [CC_OP_SHLW
] = { compute_all_shlw
, compute_c_shlw
},
952 [CC_OP_SHLL
] = { compute_all_shll
, compute_c_shll
},
955 /* floating point support */
957 #ifdef USE_X86LDOUBLE
958 /* use long double functions */
960 #define llrint llrintl
974 extern int lrint(CPU86_LDouble x
);
975 extern int64_t llrint(CPU86_LDouble x
);
976 extern CPU86_LDouble
fabs(CPU86_LDouble x
);
977 extern CPU86_LDouble
sin(CPU86_LDouble x
);
978 extern CPU86_LDouble
cos(CPU86_LDouble x
);
979 extern CPU86_LDouble
sqrt(CPU86_LDouble x
);
980 extern CPU86_LDouble
pow(CPU86_LDouble
, CPU86_LDouble
);
981 extern CPU86_LDouble
log(CPU86_LDouble x
);
982 extern CPU86_LDouble
tan(CPU86_LDouble x
);
983 extern CPU86_LDouble
atan2(CPU86_LDouble
, CPU86_LDouble
);
984 extern CPU86_LDouble
floor(CPU86_LDouble x
);
985 extern CPU86_LDouble
ceil(CPU86_LDouble x
);
986 extern CPU86_LDouble
rint(CPU86_LDouble x
);
988 #define RC_MASK 0xc00
989 #define RC_NEAR 0x000
990 #define RC_DOWN 0x400
992 #define RC_CHOP 0xc00
994 #define MAXTAN 9223372036854775808.0
996 #ifdef USE_X86LDOUBLE
1002 unsigned long long lower
;
1003 unsigned short upper
;
1007 /* the following deal with x86 long double-precision numbers */
1008 #define MAXEXPD 0x7fff
1009 #define EXPBIAS 16383
1010 #define EXPD(fp) (fp.l.upper & 0x7fff)
1011 #define SIGND(fp) ((fp.l.upper) & 0x8000)
1012 #define MANTD(fp) (fp.l.lower)
1013 #define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS
1019 #ifndef WORDS_BIGENDIAN
1021 unsigned long lower
;
1027 unsigned long lower
;
1033 /* the following deal with IEEE double-precision numbers */
1034 #define MAXEXPD 0x7ff
1035 #define EXPBIAS 1023
1036 #define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF)
1037 #define SIGND(fp) ((fp.l.upper) & 0x80000000)
1038 #define MANTD(fp) (fp.ll & ((1LL << 52) - 1))
1039 #define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20)
1044 void OPPROTO
op_flds_FT0_A0(void)
1046 FT0
= ldfl((void *)A0
);
1049 void OPPROTO
op_fldl_FT0_A0(void)
1051 FT0
= ldfq((void *)A0
);
1054 void OPPROTO
op_fild_FT0_A0(void)
1056 FT0
= (CPU86_LDouble
)ldsw((void *)A0
);
1059 void OPPROTO
op_fildl_FT0_A0(void)
1061 FT0
= (CPU86_LDouble
)((int32_t)ldl((void *)A0
));
1064 void OPPROTO
op_fildll_FT0_A0(void)
1066 FT0
= (CPU86_LDouble
)((int64_t)ldq((void *)A0
));
1071 void OPPROTO
op_flds_ST0_A0(void)
1073 ST0
= ldfl((void *)A0
);
1076 void OPPROTO
op_fldl_ST0_A0(void)
1078 ST0
= ldfq((void *)A0
);
1081 void OPPROTO
op_fild_ST0_A0(void)
1083 ST0
= (CPU86_LDouble
)ldsw((void *)A0
);
1086 void OPPROTO
op_fildl_ST0_A0(void)
1088 ST0
= (CPU86_LDouble
)((int32_t)ldl((void *)A0
));
1091 void OPPROTO
op_fildll_ST0_A0(void)
1093 ST0
= (CPU86_LDouble
)((int64_t)ldq((void *)A0
));
1098 void OPPROTO
op_fsts_ST0_A0(void)
1100 stfl((void *)A0
, (float)ST0
);
1103 void OPPROTO
op_fstl_ST0_A0(void)
1105 ST0
= ldfq((void *)A0
);
1108 void OPPROTO
op_fist_ST0_A0(void)
1112 stw((void *)A0
, val
);
1115 void OPPROTO
op_fistl_ST0_A0(void)
1119 stl((void *)A0
, val
);
1122 void OPPROTO
op_fistll_ST0_A0(void)
1126 stq((void *)A0
, val
);
1131 static inline void fpush(void)
1133 env
->fpstt
= (env
->fpstt
- 1) & 7;
1134 env
->fptags
[env
->fpstt
] = 0; /* validate stack entry */
1137 static inline void fpop(void)
1139 env
->fptags
[env
->fpstt
] = 1; /* invvalidate stack entry */
1140 env
->fpstt
= (env
->fpstt
+ 1) & 7;
1143 void OPPROTO
op_fpush(void)
1148 void OPPROTO
op_fpop(void)
1153 void OPPROTO
op_fdecstp(void)
1155 env
->fpstt
= (env
->fpstt
- 1) & 7;
1156 env
->fpus
&= (~0x4700);
1159 void OPPROTO
op_fincstp(void)
1161 env
->fpstt
= (env
->fpstt
+ 1) & 7;
1162 env
->fpus
&= (~0x4700);
1165 void OPPROTO
op_fmov_ST0_FT0(void)
1170 void OPPROTO
op_fmov_FT0_STN(void)
1175 void OPPROTO
op_fmov_ST0_STN(void)
1180 void OPPROTO
op_fmov_STN_ST0(void)
1185 void OPPROTO
op_fxchg_ST0_STN(void)
1193 /* FPU operations */
1195 /* XXX: handle nans */
1196 void OPPROTO
op_fcom_ST0_FT0(void)
1198 env
->fpus
&= (~0x4500); /* (C3,C2,C0) <-- 000 */
1200 env
->fpus
|= 0x100; /* (C3,C2,C0) <-- 001 */
1201 else if (ST0
== FT0
)
1202 env
->fpus
|= 0x4000; /* (C3,C2,C0) <-- 100 */
1206 void OPPROTO
op_fadd_ST0_FT0(void)
1211 void OPPROTO
op_fmul_ST0_FT0(void)
1216 void OPPROTO
op_fsub_ST0_FT0(void)
1221 void OPPROTO
op_fsubr_ST0_FT0(void)
1226 void OPPROTO
op_fdiv_ST0_FT0(void)
1231 void OPPROTO
op_fdivr_ST0_FT0(void)
1236 /* fp operations between STN and ST0 */
1238 void OPPROTO
op_fadd_STN_ST0(void)
1243 void OPPROTO
op_fmul_STN_ST0(void)
1248 void OPPROTO
op_fsub_STN_ST0(void)
1253 void OPPROTO
op_fsubr_STN_ST0(void)
1260 void OPPROTO
op_fdiv_STN_ST0(void)
1265 void OPPROTO
op_fdivr_STN_ST0(void)
1272 /* misc FPU operations */
1273 void OPPROTO
op_fchs_ST0(void)
1278 void OPPROTO
op_fabs_ST0(void)
1283 void OPPROTO
op_fxam_ST0(void)
1285 CPU86_LDoubleU temp
;
1290 env
->fpus
&= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
1292 env
->fpus
|= 0x200; /* C1 <-- 1 */
1294 expdif
= EXPD(temp
);
1295 if (expdif
== MAXEXPD
) {
1296 if (MANTD(temp
) == 0)
1297 env
->fpus
|= 0x500 /*Infinity*/;
1299 env
->fpus
|= 0x100 /*NaN*/;
1300 } else if (expdif
== 0) {
1301 if (MANTD(temp
) == 0)
1302 env
->fpus
|= 0x4000 /*Zero*/;
1304 env
->fpus
|= 0x4400 /*Denormal*/;
1311 void OPPROTO
op_fld1_ST0(void)
1313 ST0
= *(CPU86_LDouble
*)&f15rk
[1];
1316 void OPPROTO
op_fld2t_ST0(void)
1318 ST0
= *(CPU86_LDouble
*)&f15rk
[6];
1321 void OPPROTO
op_fld2e_ST0(void)
1323 ST0
= *(CPU86_LDouble
*)&f15rk
[5];
1326 void OPPROTO
op_fldpi_ST0(void)
1328 ST0
= *(CPU86_LDouble
*)&f15rk
[2];
1331 void OPPROTO
op_fldlg2_ST0(void)
1333 ST0
= *(CPU86_LDouble
*)&f15rk
[3];
1336 void OPPROTO
op_fldln2_ST0(void)
1338 ST0
= *(CPU86_LDouble
*)&f15rk
[4];
1341 void OPPROTO
op_fldz_ST0(void)
1343 ST0
= *(CPU86_LDouble
*)&f15rk
[0];
1346 void OPPROTO
op_fldz_FT0(void)
1348 ST0
= *(CPU86_LDouble
*)&f15rk
[0];
1351 void helper_f2xm1(void)
1353 ST0
= pow(2.0,ST0
) - 1.0;
1356 void helper_fyl2x(void)
1358 CPU86_LDouble fptemp
;
1362 fptemp
= log(fptemp
)/log(2.0); /* log2(ST) */
1366 env
->fpus
&= (~0x4700);
1371 void helper_fptan(void)
1373 CPU86_LDouble fptemp
;
1376 if((fptemp
> MAXTAN
)||(fptemp
< -MAXTAN
)) {
1382 env
->fpus
&= (~0x400); /* C2 <-- 0 */
1383 /* the above code is for |arg| < 2**52 only */
1387 void helper_fpatan(void)
1389 CPU86_LDouble fptemp
, fpsrcop
;
1393 ST1
= atan2(fpsrcop
,fptemp
);
1397 void helper_fxtract(void)
1399 CPU86_LDoubleU temp
;
1400 unsigned int expdif
;
1403 expdif
= EXPD(temp
) - EXPBIAS
;
1404 /*DP exponent bias*/
1411 void helper_fprem1(void)
1413 CPU86_LDouble dblq
, fpsrcop
, fptemp
;
1414 CPU86_LDoubleU fpsrcop1
, fptemp1
;
1420 fpsrcop1
.d
= fpsrcop
;
1422 expdif
= EXPD(fpsrcop1
) - EXPD(fptemp1
);
1424 dblq
= fpsrcop
/ fptemp
;
1425 dblq
= (dblq
< 0.0)? ceil(dblq
): floor(dblq
);
1426 ST0
= fpsrcop
- fptemp
*dblq
;
1427 q
= (int)dblq
; /* cutting off top bits is assumed here */
1428 env
->fpus
&= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
1429 /* (C0,C1,C3) <-- (q2,q1,q0) */
1430 env
->fpus
|= (q
&0x4) << 6; /* (C0) <-- q2 */
1431 env
->fpus
|= (q
&0x2) << 8; /* (C1) <-- q1 */
1432 env
->fpus
|= (q
&0x1) << 14; /* (C3) <-- q0 */
1434 env
->fpus
|= 0x400; /* C2 <-- 1 */
1435 fptemp
= pow(2.0, expdif
-50);
1436 fpsrcop
= (ST0
/ ST1
) / fptemp
;
1437 /* fpsrcop = integer obtained by rounding to the nearest */
1438 fpsrcop
= (fpsrcop
-floor(fpsrcop
) < ceil(fpsrcop
)-fpsrcop
)?
1439 floor(fpsrcop
): ceil(fpsrcop
);
1440 ST0
-= (ST1
* fpsrcop
* fptemp
);
1444 void helper_fprem(void)
1446 CPU86_LDouble dblq
, fpsrcop
, fptemp
;
1447 CPU86_LDoubleU fpsrcop1
, fptemp1
;
1453 fpsrcop1
.d
= fpsrcop
;
1455 expdif
= EXPD(fpsrcop1
) - EXPD(fptemp1
);
1456 if ( expdif
< 53 ) {
1457 dblq
= fpsrcop
/ fptemp
;
1458 dblq
= (dblq
< 0.0)? ceil(dblq
): floor(dblq
);
1459 ST0
= fpsrcop
- fptemp
*dblq
;
1460 q
= (int)dblq
; /* cutting off top bits is assumed here */
1461 env
->fpus
&= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
1462 /* (C0,C1,C3) <-- (q2,q1,q0) */
1463 env
->fpus
|= (q
&0x4) << 6; /* (C0) <-- q2 */
1464 env
->fpus
|= (q
&0x2) << 8; /* (C1) <-- q1 */
1465 env
->fpus
|= (q
&0x1) << 14; /* (C3) <-- q0 */
1467 env
->fpus
|= 0x400; /* C2 <-- 1 */
1468 fptemp
= pow(2.0, expdif
-50);
1469 fpsrcop
= (ST0
/ ST1
) / fptemp
;
1470 /* fpsrcop = integer obtained by chopping */
1471 fpsrcop
= (fpsrcop
< 0.0)?
1472 -(floor(fabs(fpsrcop
))): floor(fpsrcop
);
1473 ST0
-= (ST1
* fpsrcop
* fptemp
);
1477 void helper_fyl2xp1(void)
1479 CPU86_LDouble fptemp
;
1482 if ((fptemp
+1.0)>0.0) {
1483 fptemp
= log(fptemp
+1.0) / log(2.0); /* log2(ST+1.0) */
1487 env
->fpus
&= (~0x4700);
1492 void helper_fsqrt(void)
1494 CPU86_LDouble fptemp
;
1498 env
->fpus
&= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
1504 void helper_fsincos(void)
1506 CPU86_LDouble fptemp
;
1509 if ((fptemp
> MAXTAN
)||(fptemp
< -MAXTAN
)) {
1515 env
->fpus
&= (~0x400); /* C2 <-- 0 */
1516 /* the above code is for |arg| < 2**63 only */
1520 void helper_frndint(void)
1525 void helper_fscale(void)
1527 CPU86_LDouble fpsrcop
, fptemp
;
1530 fptemp
= pow(fpsrcop
,ST1
);
1534 void helper_fsin(void)
1536 CPU86_LDouble fptemp
;
1539 if ((fptemp
> MAXTAN
)||(fptemp
< -MAXTAN
)) {
1543 env
->fpus
&= (~0x400); /* C2 <-- 0 */
1544 /* the above code is for |arg| < 2**53 only */
1548 void helper_fcos(void)
1550 CPU86_LDouble fptemp
;
1553 if((fptemp
> MAXTAN
)||(fptemp
< -MAXTAN
)) {
1557 env
->fpus
&= (~0x400); /* C2 <-- 0 */
1558 /* the above code is for |arg5 < 2**63 only */
1562 /* associated heplers to reduce generated code length and to simplify
1563 relocation (FP constants are usually stored in .rodata section) */
1565 void OPPROTO
op_f2xm1(void)
1570 void OPPROTO
op_fyl2x(void)
1575 void OPPROTO
op_fptan(void)
1580 void OPPROTO
op_fpatan(void)
1585 void OPPROTO
op_fxtract(void)
1590 void OPPROTO
op_fprem1(void)
1596 void OPPROTO
op_fprem(void)
1601 void OPPROTO
op_fyl2xp1(void)
1606 void OPPROTO
op_fsqrt(void)
1611 void OPPROTO
op_fsincos(void)
1616 void OPPROTO
op_frndint(void)
1621 void OPPROTO
op_fscale(void)
1626 void OPPROTO
op_fsin(void)
1631 void OPPROTO
op_fcos(void)
1636 /* main execution loop */
1637 uint8_t code_gen_buffer
[65536];
1639 int cpu_x86_exec(CPUX86State
*env1
)
1641 int saved_T0
, saved_T1
, saved_A0
;
1642 CPUX86State
*saved_env
;
1643 int code_gen_size
, ret
;
1644 void (*gen_func
)(void);
1646 /* first we save global registers */
1653 /* prepare setjmp context for exception handling */
1654 if (setjmp(env
->jmp_env
) == 0) {
1656 cpu_x86_gen_code(code_gen_buffer
, &code_gen_size
, (uint8_t *)env
->pc
);
1657 /* execute the generated code */
1658 gen_func
= (void *)code_gen_buffer
;
1662 ret
= env
->exception_index
;
1664 /* restore global registers */