xchg lock, xlat instr
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 26 Mar 2003 22:33:47 +0000 (22:33 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 26 Mar 2003 22:33:47 +0000 (22:33 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@49 c046a42c-6fe2-441c-8c8c-71466251a162

op-i386.c
opc-i386.h
translate-i386.c

index fb3ff1d59b8eab4a8bc58f44bf4f26222487dd83..eac73ed93a37b6afbd4b292b8f527beb5f36aaa2 100644 (file)
--- a/op-i386.c
+++ b/op-i386.c
@@ -489,6 +489,11 @@ void OPPROTO op_addl_A0_im(void)
     A0 += PARAM1;
 }
 
+void OPPROTO op_addl_A0_AL(void)
+{
+    A0 += (EAX & 0xff);
+}
+
 void OPPROTO op_andl_A0_ffff(void)
 {
     A0 = A0 & 0xffff;
index 9d9f8471b5569ea3c594a06096d2854f56d9d864..eceecf41b8e758a1a8e4ab54e97a34663af0ff36 100644 (file)
@@ -210,6 +210,7 @@ DEF(addl_T1_im)
 DEF(movl_T1_A0)
 DEF(movl_A0_im)
 DEF(addl_A0_im)
+DEF(addl_A0_AL)
 DEF(andl_A0_ffff)
 DEF(ldub_T0_A0)
 DEF(ldsb_T0_A0)
index afe7f3543a3e8a84de63363233f19a63632d2bd2..d7f6520e8fe97e1d314859d1de86feea02bdfb90 100644 (file)
@@ -2083,7 +2083,40 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
             gen_op_st_T0_A0[ot]();
         }
         break;
-
+    case 0xd7: /* xlat */
+        /* handle override */
+        gen_op_movl_A0_reg[R_EBX]();
+        gen_op_addl_A0_AL();
+        if (s->aflag == 0)
+            gen_op_andl_A0_ffff();
+        /* XXX: factorize that */
+        {
+            int override, must_add_seg;
+            override = R_DS;
+            must_add_seg = s->addseg;
+            if (s->prefix & (PREFIX_CS | PREFIX_SS | PREFIX_DS | 
+                             PREFIX_ES | PREFIX_FS | PREFIX_GS)) {
+                if (s->prefix & PREFIX_ES)
+                    override = R_ES;
+                else if (s->prefix & PREFIX_CS)
+                    override = R_CS;
+                else if (s->prefix & PREFIX_SS)
+                    override = R_SS;
+                else if (s->prefix & PREFIX_DS)
+                    override = R_DS;
+                else if (s->prefix & PREFIX_FS)
+                    override = R_FS;
+                else
+                    override = R_GS;
+                must_add_seg = 1;
+            }
+            if (must_add_seg) {
+                gen_op_addl_A0_seg(offsetof(CPUX86State,seg_cache[override].base));
+            }
+        }
+        gen_op_ldub_T0_A0();
+        gen_op_mov_reg_T0[OT_BYTE][R_EAX]();
+        break;
     case 0xb0 ... 0xb7: /* mov R, Ib */
         val = insn_get(s, OT_BYTE);
         gen_op_movl_T0_im(val);
@@ -2121,8 +2154,13 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
         } else {
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
             gen_op_mov_TN_reg[ot][0][reg]();
+            /* for xchg, lock is implicit */
+            if (!(prefixes & PREFIX_LOCK))
+                gen_op_lock();
             gen_op_ld_T1_A0[ot]();
             gen_op_st_T0_A0[ot]();
+            if (!(prefixes & PREFIX_LOCK))
+                gen_op_unlock();
             gen_op_mov_reg_T1[ot][reg]();
         }
         break;