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
| @@ -489,6 +489,11 @@ void OPPROTO op_addl_A0_im(void) | @@ -489,6 +489,11 @@ void OPPROTO op_addl_A0_im(void) | ||
| 489 | A0 += PARAM1; | 489 | A0 += PARAM1; |
| 490 | } | 490 | } |
| 491 | 491 | ||
| 492 | +void OPPROTO op_addl_A0_AL(void) | ||
| 493 | +{ | ||
| 494 | + A0 += (EAX & 0xff); | ||
| 495 | +} | ||
| 496 | + | ||
| 492 | void OPPROTO op_andl_A0_ffff(void) | 497 | void OPPROTO op_andl_A0_ffff(void) |
| 493 | { | 498 | { |
| 494 | A0 = A0 & 0xffff; | 499 | A0 = A0 & 0xffff; |
opc-i386.h
| @@ -210,6 +210,7 @@ DEF(addl_T1_im) | @@ -210,6 +210,7 @@ DEF(addl_T1_im) | ||
| 210 | DEF(movl_T1_A0) | 210 | DEF(movl_T1_A0) |
| 211 | DEF(movl_A0_im) | 211 | DEF(movl_A0_im) |
| 212 | DEF(addl_A0_im) | 212 | DEF(addl_A0_im) |
| 213 | +DEF(addl_A0_AL) | ||
| 213 | DEF(andl_A0_ffff) | 214 | DEF(andl_A0_ffff) |
| 214 | DEF(ldub_T0_A0) | 215 | DEF(ldub_T0_A0) |
| 215 | DEF(ldsb_T0_A0) | 216 | DEF(ldsb_T0_A0) |
translate-i386.c
| @@ -2083,7 +2083,40 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2083,7 +2083,40 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 2083 | gen_op_st_T0_A0[ot](); | 2083 | gen_op_st_T0_A0[ot](); |
| 2084 | } | 2084 | } |
| 2085 | break; | 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 | case 0xb0 ... 0xb7: /* mov R, Ib */ | 2120 | case 0xb0 ... 0xb7: /* mov R, Ib */ |
| 2088 | val = insn_get(s, OT_BYTE); | 2121 | val = insn_get(s, OT_BYTE); |
| 2089 | gen_op_movl_T0_im(val); | 2122 | gen_op_movl_T0_im(val); |
| @@ -2121,8 +2154,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2121,8 +2154,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) | ||
| 2121 | } else { | 2154 | } else { |
| 2122 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); | 2155 | gen_lea_modrm(s, modrm, ®_addr, &offset_addr); |
| 2123 | gen_op_mov_TN_reg[ot][0][reg](); | 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 | gen_op_ld_T1_A0[ot](); | 2160 | gen_op_ld_T1_A0[ot](); |
| 2125 | gen_op_st_T0_A0[ot](); | 2161 | gen_op_st_T0_A0[ot](); |
| 2162 | + if (!(prefixes & PREFIX_LOCK)) | ||
| 2163 | + gen_op_unlock(); | ||
| 2126 | gen_op_mov_reg_T1[ot][reg](); | 2164 | gen_op_mov_reg_T1[ot][reg](); |
| 2127 | } | 2165 | } |
| 2128 | break; | 2166 | break; |