Commit 31bb950be6d1f144d349d9793c88fbb28ca5fb58
1 parent
8083a3e5
xchg lock, xlat instr
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@49 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
45 additions
and
1 deletions
op-i386.c
opc-i386.h
translate-i386.c
| ... | ... | @@ -2083,7 +2083,40 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) |
| 2083 | 2083 | gen_op_st_T0_A0[ot](); |
| 2084 | 2084 | } |
| 2085 | 2085 | break; |
| 2086 | - | |
| 2086 | + case 0xd7: /* xlat */ | |
| 2087 | + /* handle override */ | |
| 2088 | + gen_op_movl_A0_reg[R_EBX](); | |
| 2089 | + gen_op_addl_A0_AL(); | |
| 2090 | + if (s->aflag == 0) | |
| 2091 | + gen_op_andl_A0_ffff(); | |
| 2092 | + /* XXX: factorize that */ | |
| 2093 | + { | |
| 2094 | + int override, must_add_seg; | |
| 2095 | + override = R_DS; | |
| 2096 | + must_add_seg = s->addseg; | |
| 2097 | + if (s->prefix & (PREFIX_CS | PREFIX_SS | PREFIX_DS | | |
| 2098 | + PREFIX_ES | PREFIX_FS | PREFIX_GS)) { | |
| 2099 | + if (s->prefix & PREFIX_ES) | |
| 2100 | + override = R_ES; | |
| 2101 | + else if (s->prefix & PREFIX_CS) | |
| 2102 | + override = R_CS; | |
| 2103 | + else if (s->prefix & PREFIX_SS) | |
| 2104 | + override = R_SS; | |
| 2105 | + else if (s->prefix & PREFIX_DS) | |
| 2106 | + override = R_DS; | |
| 2107 | + else if (s->prefix & PREFIX_FS) | |
| 2108 | + override = R_FS; | |
| 2109 | + else | |
| 2110 | + override = R_GS; | |
| 2111 | + must_add_seg = 1; | |
| 2112 | + } | |
| 2113 | + if (must_add_seg) { | |
| 2114 | + gen_op_addl_A0_seg(offsetof(CPUX86State,seg_cache[override].base)); | |
| 2115 | + } | |
| 2116 | + } | |
| 2117 | + gen_op_ldub_T0_A0(); | |
| 2118 | + gen_op_mov_reg_T0[OT_BYTE][R_EAX](); | |
| 2119 | + break; | |
| 2087 | 2120 | case 0xb0 ... 0xb7: /* mov R, Ib */ |
| 2088 | 2121 | val = insn_get(s, OT_BYTE); |
| 2089 | 2122 | gen_op_movl_T0_im(val); |
| ... | ... | @@ -2121,8 +2154,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) |
| 2121 | 2154 | } else { |
| 2122 | 2155 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
| 2123 | 2156 | gen_op_mov_TN_reg[ot][0][reg](); |
| 2157 | + /* for xchg, lock is implicit */ | |
| 2158 | + if (!(prefixes & PREFIX_LOCK)) | |
| 2159 | + gen_op_lock(); | |
| 2124 | 2160 | gen_op_ld_T1_A0[ot](); |
| 2125 | 2161 | gen_op_st_T0_A0[ot](); |
| 2162 | + if (!(prefixes & PREFIX_LOCK)) | |
| 2163 | + gen_op_unlock(); | |
| 2126 | 2164 | gen_op_mov_reg_T1[ot][reg](); |
| 2127 | 2165 | } |
| 2128 | 2166 | break; | ... | ... |