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, ®_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, ®_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