Statistics
| Branch: | Revision:

root / op-i386.c @ 586314f2

History | View | Annotate | Download (32.4 kB)

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