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