Commit 31bb950be6d1f144d349d9793c88fbb28ca5fb58

Authored by bellard
1 parent 8083a3e5

xchg lock, xlat instr


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@49 c046a42c-6fe2-441c-8c8c-71466251a162
op-i386.c
... ... @@ -489,6 +489,11 @@ void OPPROTO op_addl_A0_im(void)
489 489 A0 += PARAM1;
490 490 }
491 491  
  492 +void OPPROTO op_addl_A0_AL(void)
  493 +{
  494 + A0 += (EAX & 0xff);
  495 +}
  496 +
492 497 void OPPROTO op_andl_A0_ffff(void)
493 498 {
494 499 A0 = A0 & 0xffff;
... ...
opc-i386.h
... ... @@ -210,6 +210,7 @@ DEF(addl_T1_im)
210 210 DEF(movl_T1_A0)
211 211 DEF(movl_A0_im)
212 212 DEF(addl_A0_im)
  213 +DEF(addl_A0_AL)
213 214 DEF(andl_A0_ffff)
214 215 DEF(ldub_T0_A0)
215 216 DEF(ldsb_T0_A0)
... ...
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, &reg_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;
... ...