Revision 8f091a59 target-i386/translate.c

b/target-i386/translate.c
1627 1627
        override = R_DS;
1628 1628
    }
1629 1629
    if (must_add_seg) {
1630
        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
1630
#ifdef TARGET_X86_64
1631
        if (CODE64(s)) {
1632
            gen_op_addq_A0_seg(offsetof(CPUX86State,segs[override].base));
1633
        } else 
1634
#endif
1635
        {
1636
            gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
1637
        }
1631 1638
    }
1632 1639
}
1633 1640

  
......
1948 1955
{
1949 1956
#ifdef TARGET_X86_64
1950 1957
    if (CODE64(s)) {
1951
        /* XXX: check 16 bit behaviour */
1952 1958
        gen_op_movq_A0_reg[R_ESP]();
1953
        gen_op_subq_A0_8();
1954
        gen_op_st_T0_A0[OT_QUAD + s->mem_index]();
1959
        if (s->dflag) {
1960
            gen_op_subq_A0_8();
1961
            gen_op_st_T0_A0[OT_QUAD + s->mem_index]();
1962
        } else {
1963
            gen_op_subq_A0_2();
1964
            gen_op_st_T0_A0[OT_WORD + s->mem_index]();
1965
        }
1955 1966
        gen_op_movq_ESP_A0();
1956 1967
    } else 
1957 1968
#endif
......
1985 1996
{
1986 1997
#ifdef TARGET_X86_64
1987 1998
    if (CODE64(s)) {
1988
        /* XXX: check 16 bit behaviour */
1989 1999
        gen_op_movq_A0_reg[R_ESP]();
1990
        gen_op_subq_A0_8();
1991
        gen_op_st_T1_A0[OT_QUAD + s->mem_index]();
2000
        if (s->dflag) {
2001
            gen_op_subq_A0_8();
2002
            gen_op_st_T1_A0[OT_QUAD + s->mem_index]();
2003
        } else {
2004
            gen_op_subq_A0_2();
2005
            gen_op_st_T0_A0[OT_WORD + s->mem_index]();
2006
        }
1992 2007
        gen_op_movq_ESP_A0();
1993 2008
    } else 
1994 2009
#endif
......
2020 2035
{
2021 2036
#ifdef TARGET_X86_64
2022 2037
    if (CODE64(s)) {
2023
        /* XXX: check 16 bit behaviour */
2024 2038
        gen_op_movq_A0_reg[R_ESP]();
2025
        gen_op_ld_T0_A0[OT_QUAD + s->mem_index]();
2039
        gen_op_ld_T0_A0[(s->dflag ? OT_QUAD : OT_WORD) + s->mem_index]();
2026 2040
    } else 
2027 2041
#endif
2028 2042
    {
......
2041 2055
static void gen_pop_update(DisasContext *s)
2042 2056
{
2043 2057
#ifdef TARGET_X86_64
2044
    if (CODE64(s)) {
2058
    if (CODE64(s) && s->dflag) {
2045 2059
        gen_stack_update(s, 8);
2046 2060
    } else
2047 2061
#endif
......
2105 2119
{
2106 2120
    int ot, opsize;
2107 2121

  
2108
    ot = s->dflag + OT_WORD;
2109 2122
    level &= 0x1f;
2110
    opsize = 2 << s->dflag;
2111

  
2112
    gen_op_movl_A0_ESP();
2113
    gen_op_addl_A0_im(-opsize);
2114
    if (!s->ss32)
2115
        gen_op_andl_A0_ffff();
2116
    gen_op_movl_T1_A0();
2117
    if (s->addseg)
2118
        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
2119
    /* push bp */
2120
    gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
2121
    gen_op_st_T0_A0[ot + s->mem_index]();
2122
    if (level) {
2123
        gen_op_enter_level(level, s->dflag);
2123
#ifdef TARGET_X86_64
2124
    if (CODE64(s)) {
2125
        ot = s->dflag ? OT_QUAD : OT_WORD;
2126
        opsize = 1 << ot;
2127
        
2128
        gen_op_movl_A0_ESP();
2129
        gen_op_addq_A0_im(-opsize);
2130
        gen_op_movl_T1_A0();
2131

  
2132
        /* push bp */
2133
        gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
2134
        gen_op_st_T0_A0[ot + s->mem_index]();
2135
        if (level) {
2136
            gen_op_enter64_level(level, (ot == OT_QUAD));
2137
        }
2138
        gen_op_mov_reg_T1[ot][R_EBP]();
2139
        gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
2140
        gen_op_mov_reg_T1[OT_QUAD][R_ESP]();
2141
    } else 
2142
#endif
2143
    {
2144
        ot = s->dflag + OT_WORD;
2145
        opsize = 2 << s->dflag;
2146
        
2147
        gen_op_movl_A0_ESP();
2148
        gen_op_addl_A0_im(-opsize);
2149
        if (!s->ss32)
2150
            gen_op_andl_A0_ffff();
2151
        gen_op_movl_T1_A0();
2152
        if (s->addseg)
2153
            gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
2154
        /* push bp */
2155
        gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
2156
        gen_op_st_T0_A0[ot + s->mem_index]();
2157
        if (level) {
2158
            gen_op_enter_level(level, s->dflag);
2159
        }
2160
        gen_op_mov_reg_T1[ot][R_EBP]();
2161
        gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
2162
        gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
2124 2163
    }
2125
    gen_op_mov_reg_T1[ot][R_EBP]();
2126
    gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
2127
    gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
2128 2164
}
2129 2165

  
2130 2166
static void gen_exception(DisasContext *s, int trapno, target_ulong cur_eip)
......
2901 2937
            if (mod != 3) 
2902 2938
                goto illegal_op;
2903 2939
#ifdef TARGET_X86_64
2904
            if (CODE64(s)) {
2940
            if (s->aflag == 2) {
2905 2941
                gen_op_movq_A0_reg[R_EDI]();
2906 2942
            } else 
2907 2943
#endif
......
3697 3733
        break;
3698 3734
    case 0xc8: /* enter */
3699 3735
        {
3700
            /* XXX: long mode support */
3701 3736
            int level;
3702 3737
            val = lduw_code(s->pc);
3703 3738
            s->pc += 2;
......
3707 3742
        break;
3708 3743
    case 0xc9: /* leave */
3709 3744
        /* XXX: exception not precise (ESP is updated before potential exception) */
3710
        /* XXX: may be invalid for 16 bit in long mode */
3711 3745
        if (CODE64(s)) {
3712 3746
            gen_op_mov_TN_reg[OT_QUAD][0][R_EBP]();
3713 3747
            gen_op_mov_reg_T0[OT_QUAD][R_ESP]();
......
3926 3960
            else
3927 3961
                ot = dflag + OT_WORD;
3928 3962
#ifdef TARGET_X86_64
3929
            if (CODE64(s)) {
3963
            if (s->aflag == 2) {
3930 3964
                offset_addr = ldq_code(s->pc);
3931 3965
                s->pc += 8;
3932 3966
                if (offset_addr == (int32_t)offset_addr)
......
3955 3989
        break;
3956 3990
    case 0xd7: /* xlat */
3957 3991
#ifdef TARGET_X86_64
3958
        if (CODE64(s)) {
3992
        if (s->aflag == 2) {
3959 3993
            gen_op_movq_A0_reg[R_EBX]();
3960 3994
            gen_op_addq_A0_AL();
3961 3995
        } else 
......
4779 4813
        val = ldsw_code(s->pc);
4780 4814
        s->pc += 2;
4781 4815
        gen_pop_T0(s);
4816
        if (CODE64(s) && s->dflag)
4817
            s->dflag = 2;
4782 4818
        gen_stack_update(s, val + (2 << s->dflag));
4783 4819
        if (s->dflag == 0)
4784 4820
            gen_op_andl_T0_ffff();
......
5782 5818
            break;
5783 5819
        case 5: /* lfence */
5784 5820
        case 6: /* mfence */
5785
        case 7: /* sfence */
5786 5821
            if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE))
5787 5822
                goto illegal_op;
5788 5823
            break;
5824
        case 7: /* sfence / clflush */
5825
            if ((modrm & 0xc7) == 0xc0) {
5826
                /* sfence */
5827
                if (!(s->cpuid_features & CPUID_SSE))
5828
                    goto illegal_op;
5829
            } else {
5830
                /* clflush */
5831
                if (!(s->cpuid_features & CPUID_CLFLUSH))
5832
                    goto illegal_op;
5833
                gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5834
            }
5835
            break;
5789 5836
        default:
5790 5837
            goto illegal_op;
5791 5838
        }
5792 5839
        break;
5840
    case 0x10d: /* prefetch */
5841
        modrm = ldub_code(s->pc++);
5842
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5843
        /* ignore for now */
5844
        break;
5793 5845
    case 0x110 ... 0x117:
5794 5846
    case 0x128 ... 0x12f:
5795 5847
    case 0x150 ... 0x177:

Also available in: Unified diff