Revision 61a8c4ec

b/Changelog
27 27
  - Floppy fixes for NT4 and NT5 (Mike Nordell)
28 28
  - NT4 IDE fixes (Ben Pfaf, Mike Nordell)
29 29
  - SDL Audio support and SB16 fixes (malc)
30
  - ENTER instruction bug fix (initial patch by Stefan Kisdaroczi)
30 31

  
31 32
version 0.6.0:
32 33

  
b/target-i386/exec.h
167 167
void helper_idivl_EAX_T0(uint32_t eip);
168 168
void helper_cmpxchg8b(void);
169 169
void helper_cpuid(void);
170
void helper_enter_level(int level, int data32);
170 171
void helper_sysenter(void);
171 172
void helper_sysexit(void);
172 173
void helper_rdtsc(void);
b/target-i386/helper.c
1068 1068
    }
1069 1069
}
1070 1070

  
1071
void helper_enter_level(int level, int data32)
1072
{
1073
    uint8_t *ssp;
1074
    uint32_t esp_mask, esp, ebp;
1075

  
1076
    esp_mask = get_sp_mask(env->segs[R_SS].flags);
1077
    ssp = env->segs[R_SS].base;
1078
    ebp = EBP;
1079
    esp = ESP;
1080
    if (data32) {
1081
        /* 32 bit */
1082
        esp -= 4;
1083
        while (--level) {
1084
            esp -= 4;
1085
            ebp -= 4;
1086
            stl(ssp + (esp & esp_mask), ldl(ssp + (ebp & esp_mask)));
1087
        }
1088
        esp -= 4;
1089
        stl(ssp + (esp & esp_mask), T1);
1090
    } else {
1091
        /* 16 bit */
1092
        esp -= 2;
1093
        while (--level) {
1094
            esp -= 2;
1095
            ebp -= 2;
1096
            stw(ssp + (esp & esp_mask), lduw(ssp + (ebp & esp_mask)));
1097
        }
1098
        esp -= 2;
1099
        stw(ssp + (esp & esp_mask), T1);
1100
    }
1101
}
1102

  
1071 1103
void helper_lldt_T0(void)
1072 1104
{
1073 1105
    int selector;
b/target-i386/op.c
695 695
    helper_cpuid();
696 696
}
697 697

  
698
void OPPROTO op_enter_level(void)
699
{
700
    helper_enter_level(PARAM1, PARAM2);
701
}
702

  
698 703
void OPPROTO op_sysenter(void)
699 704
{
700 705
    helper_sysenter();
b/target-i386/translate.c
1690 1690
    gen_op_mov_reg_T1[OT_WORD + s->dflag][R_ESP]();
1691 1691
}
1692 1692

  
1693
/* NOTE: wrap around in 16 bit not fully handled */
1694
/* XXX: check this */
1695 1693
static void gen_enter(DisasContext *s, int esp_addend, int level)
1696 1694
{
1697
    int ot, level1, addend, opsize;
1695
    int ot, opsize;
1698 1696

  
1699 1697
    ot = s->dflag + OT_WORD;
1700 1698
    level &= 0x1f;
1701
    level1 = level;
1702 1699
    opsize = 2 << s->dflag;
1703 1700

  
1704 1701
    gen_op_movl_A0_ESP();
......
1712 1709
    gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
1713 1710
    gen_op_st_T0_A0[ot + s->mem_index]();
1714 1711
    if (level) {
1715
        while (level--) {
1716
            gen_op_addl_A0_im(-opsize);
1717
            gen_op_addl_T0_im(-opsize);
1718
            gen_op_st_T0_A0[ot + s->mem_index]();
1719
        }
1720
        gen_op_addl_A0_im(-opsize);
1721
        gen_op_st_T1_A0[ot + s->mem_index]();
1712
        gen_op_enter_level(level, s->dflag);
1722 1713
    }
1723 1714
    gen_op_mov_reg_T1[ot][R_EBP]();
1724
    addend = -esp_addend;
1725
    if (level1)
1726
        addend -= opsize * (level1 + 1);
1727
    gen_op_addl_T1_im(addend);
1715
    gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
1728 1716
    gen_op_mov_reg_T1[ot][R_ESP]();
1729 1717
}
1730 1718

  
b/tests/test-i386.c
1625 1625
        printf("smc_code2(%d) = %d\n", i, smc_code2(i));
1626 1626
    }
1627 1627
}
1628
    
1628

  
1629
int enter_stack[4096];
1630

  
1631
#define TEST_ENTER(size, stack_type, level)\
1632
{\
1633
    int esp_save, esp_val, ebp_val, ebp_save, i;\
1634
    stack_type *ptr, *stack_end, *stack_ptr;\
1635
    memset(enter_stack, 0, sizeof(enter_stack));\
1636
    stack_end = stack_ptr = (stack_type *)(enter_stack + 4096);\
1637
    ebp_val = (long)stack_ptr;\
1638
    for(i=1;i<=32;i++)\
1639
       *--stack_ptr = i;\
1640
    esp_val = (long)stack_ptr;\
1641
    asm("movl %%esp, %[esp_save]\n"\
1642
        "movl %%ebp, %[ebp_save]\n"\
1643
        "movl %[esp_val], %%esp\n"\
1644
        "movl %[ebp_val], %%ebp\n"\
1645
        "enter" size " $12, $" #level "\n"\
1646
        "movl %%esp, %[esp_val]\n"\
1647
        "movl %%ebp, %[ebp_val]\n"\
1648
        "movl %[esp_save], %%esp\n"\
1649
        "movl %[ebp_save], %%ebp\n"\
1650
        : [esp_save] "=r" (esp_save),\
1651
        [ebp_save] "=r" (ebp_save),\
1652
        [esp_val] "=r" (esp_val),\
1653
        [ebp_val] "=r" (ebp_val)\
1654
        :  "[esp_val]" (esp_val),\
1655
        "[ebp_val]" (ebp_val));\
1656
    printf("level=%d:\n", level);\
1657
    printf("esp_val=0x%08lx\n", esp_val - (long)stack_end);\
1658
    printf("ebp_val=0x%08lx\n", ebp_val - (long)stack_end);\
1659
    for(ptr = (stack_type *)esp_val; ptr < stack_end; ptr++)\
1660
        printf("%08x\n", ptr[0]);\
1661
}
1662

  
1663
static void test_enter(void)
1664
{
1665
    TEST_ENTER("l", uint32_t, 0);
1666
    TEST_ENTER("l", uint32_t, 1);
1667
    TEST_ENTER("l", uint32_t, 2);
1668
    TEST_ENTER("l", uint32_t, 31);
1669

  
1670
    TEST_ENTER("w", uint16_t, 0);
1671
    TEST_ENTER("w", uint16_t, 1);
1672
    TEST_ENTER("w", uint16_t, 2);
1673
    TEST_ENTER("w", uint16_t, 31);
1674
}
1675

  
1676

  
1629 1677
static void *call_end __init_call = NULL;
1630 1678

  
1631 1679
int main(int argc, char **argv)
......
1653 1701
    test_exceptions();
1654 1702
    test_self_modifying_code();
1655 1703
    test_single_step();
1704
    test_enter();
1656 1705
    return 0;
1657 1706
}

Also available in: Unified diff