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