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; | ... | ... |