Revision 0ecfa993 op-i386.c
b/op-i386.c | ||
---|---|---|
10 | 10 |
|
11 | 11 |
#define NULL 0 |
12 | 12 |
|
13 |
typedef struct FILE FILE; |
|
14 |
|
|
15 |
extern FILE *stderr; |
|
16 |
extern int fprintf(FILE *, const char *, ...); |
|
17 |
|
|
18 | 13 |
#ifdef __i386__ |
19 | 14 |
register int T0 asm("esi"); |
20 | 15 |
register int T1 asm("ebx"); |
... | ... | |
91 | 86 |
int (*compute_c)(void); /* return the C flag */ |
92 | 87 |
} CCTable; |
93 | 88 |
|
89 |
/* NOTE: data are not static to force relocation generation by GCC */ |
|
94 | 90 |
extern CCTable cc_table[]; |
95 | 91 |
|
96 | 92 |
uint8_t parity_table[256] = { |
... | ... | |
191 | 187 |
return x >> (-n); |
192 | 188 |
} |
193 | 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 |
|
|
194 | 198 |
/* we define the various pieces of code used by the JIT */ |
195 | 199 |
|
196 | 200 |
#define REG EAX |
... | ... | |
321 | 325 |
|
322 | 326 |
void OPPROTO op_testl_T0_T1_cc(void) |
323 | 327 |
{ |
324 |
CC_SRC = T0; |
|
325 | 328 |
CC_DST = T0 & T1; |
326 | 329 |
} |
327 | 330 |
|
... | ... | |
555 | 558 |
/* jumps */ |
556 | 559 |
|
557 | 560 |
/* indirect jump */ |
561 |
|
|
558 | 562 |
void OPPROTO op_jmp_T0(void) |
559 | 563 |
{ |
560 | 564 |
PC = T0; |
... | ... | |
565 | 569 |
PC = PARAM1; |
566 | 570 |
} |
567 | 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 |
|
|
568 | 596 |
/* string ops */ |
569 | 597 |
|
570 | 598 |
#define ldul ldl |
... | ... | |
663 | 691 |
int eflags; |
664 | 692 |
eflags = cc_table[CC_OP].compute_all(); |
665 | 693 |
if (eflags & CC_O) |
666 |
PC += PARAM1;
|
|
694 |
PC = PARAM1; |
|
667 | 695 |
else |
668 |
PC += PARAM2; |
|
696 |
PC = PARAM2; |
|
697 |
FORCE_RET(); |
|
669 | 698 |
} |
670 | 699 |
|
671 | 700 |
void OPPROTO op_jb_cc(void) |
672 | 701 |
{ |
673 | 702 |
if (cc_table[CC_OP].compute_c()) |
674 |
PC += PARAM1;
|
|
703 |
PC = PARAM1; |
|
675 | 704 |
else |
676 |
PC += PARAM2; |
|
705 |
PC = PARAM2; |
|
706 |
FORCE_RET(); |
|
677 | 707 |
} |
678 | 708 |
|
679 | 709 |
void OPPROTO op_jz_cc(void) |
... | ... | |
681 | 711 |
int eflags; |
682 | 712 |
eflags = cc_table[CC_OP].compute_all(); |
683 | 713 |
if (eflags & CC_Z) |
684 |
PC += PARAM1;
|
|
714 |
PC = PARAM1; |
|
685 | 715 |
else |
686 |
PC += PARAM2; |
|
716 |
PC = PARAM2; |
|
717 |
FORCE_RET(); |
|
687 | 718 |
} |
688 | 719 |
|
689 | 720 |
void OPPROTO op_jbe_cc(void) |
... | ... | |
691 | 722 |
int eflags; |
692 | 723 |
eflags = cc_table[CC_OP].compute_all(); |
693 | 724 |
if (eflags & (CC_Z | CC_C)) |
694 |
PC += PARAM1;
|
|
725 |
PC = PARAM1; |
|
695 | 726 |
else |
696 |
PC += PARAM2; |
|
727 |
PC = PARAM2; |
|
728 |
FORCE_RET(); |
|
697 | 729 |
} |
698 | 730 |
|
699 | 731 |
void OPPROTO op_js_cc(void) |
... | ... | |
701 | 733 |
int eflags; |
702 | 734 |
eflags = cc_table[CC_OP].compute_all(); |
703 | 735 |
if (eflags & CC_S) |
704 |
PC += PARAM1;
|
|
736 |
PC = PARAM1; |
|
705 | 737 |
else |
706 |
PC += PARAM2; |
|
738 |
PC = PARAM2; |
|
739 |
FORCE_RET(); |
|
707 | 740 |
} |
708 | 741 |
|
709 | 742 |
void OPPROTO op_jp_cc(void) |
... | ... | |
711 | 744 |
int eflags; |
712 | 745 |
eflags = cc_table[CC_OP].compute_all(); |
713 | 746 |
if (eflags & CC_P) |
714 |
PC += PARAM1;
|
|
747 |
PC = PARAM1; |
|
715 | 748 |
else |
716 |
PC += PARAM2; |
|
749 |
PC = PARAM2; |
|
750 |
FORCE_RET(); |
|
717 | 751 |
} |
718 | 752 |
|
719 | 753 |
void OPPROTO op_jl_cc(void) |
... | ... | |
721 | 755 |
int eflags; |
722 | 756 |
eflags = cc_table[CC_OP].compute_all(); |
723 | 757 |
if ((eflags ^ (eflags >> 4)) & 0x80) |
724 |
PC += PARAM1;
|
|
758 |
PC = PARAM1; |
|
725 | 759 |
else |
726 |
PC += PARAM2; |
|
760 |
PC = PARAM2; |
|
761 |
FORCE_RET(); |
|
727 | 762 |
} |
728 | 763 |
|
729 | 764 |
void OPPROTO op_jle_cc(void) |
... | ... | |
731 | 766 |
int eflags; |
732 | 767 |
eflags = cc_table[CC_OP].compute_all(); |
733 | 768 |
if (((eflags ^ (eflags >> 4)) & 0x80) || (eflags & CC_Z)) |
734 |
PC += PARAM1;
|
|
769 |
PC = PARAM1; |
|
735 | 770 |
else |
736 |
PC += PARAM2; |
|
771 |
PC = PARAM2; |
|
772 |
FORCE_RET(); |
|
737 | 773 |
} |
738 | 774 |
|
739 | 775 |
/* slow set cases (compute x86 flags) */ |
... | ... | |
1600 | 1636 |
/* main execution loop */ |
1601 | 1637 |
uint8_t code_gen_buffer[65536]; |
1602 | 1638 |
|
1603 |
|
|
1604 | 1639 |
int cpu_x86_exec(CPUX86State *env1) |
1605 | 1640 |
{ |
1606 | 1641 |
int saved_T0, saved_T1, saved_A0; |
1607 | 1642 |
CPUX86State *saved_env; |
1608 |
int code_gen_size; |
|
1643 |
int code_gen_size, ret;
|
|
1609 | 1644 |
void (*gen_func)(void); |
1610 |
|
|
1645 |
|
|
1611 | 1646 |
/* first we save global registers */ |
1612 | 1647 |
saved_T0 = T0; |
1613 | 1648 |
saved_T1 = T1; |
... | ... | |
1615 | 1650 |
saved_env = env; |
1616 | 1651 |
env = env1; |
1617 | 1652 |
|
1618 |
for(;;) { |
|
1619 |
cpu_x86_gen_code(code_gen_buffer, &code_gen_size, (uint8_t *)env->pc); |
|
1620 |
/* execute the generated code */ |
|
1621 |
gen_func = (void *)code_gen_buffer; |
|
1622 |
gen_func(); |
|
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 |
} |
|
1623 | 1661 |
} |
1624 |
|
|
1662 |
ret = env->exception_index; |
|
1663 |
|
|
1625 | 1664 |
/* restore global registers */ |
1626 | 1665 |
T0 = saved_T0; |
1627 | 1666 |
T1 = saved_T1; |
1628 | 1667 |
A0 = saved_A0; |
1629 | 1668 |
env = saved_env; |
1630 |
return 0;
|
|
1669 |
return ret;
|
|
1631 | 1670 |
} |
Also available in: Unified diff