KVM: x86 emulator: Avoid pushing back ModRM byte fetched for group decoding
authorTakuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Mon, 30 Apr 2012 08:48:25 +0000 (17:48 +0900)
committerAvi Kivity <avi@redhat.com>
Sun, 6 May 2012 13:15:58 +0000 (16:15 +0300)
Although ModRM byte is fetched for group decoding, it is soon pushed
back to make decode_modrm() fetch it later again.

Now that ModRM flag can be found in the top level opcode tables, fetch
ModRM byte before group decoding to make the code simpler.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Avi Kivity <avi@redhat.com>
arch/x86/kvm/emulate.c

index 8d2c3d04cfec97eceb814d32e08b27d8ce02069a..7fd25763b0e0334135320cb270de5b79202c51ce 100644 (file)
@@ -972,7 +972,6 @@ static int decode_modrm(struct x86_emulate_ctxt *ctxt,
                ctxt->modrm_rm = base_reg = (ctxt->rex_prefix & 1) << 3; /* REG.B */
        }
 
-       ctxt->modrm = insn_fetch(u8, ctxt);
        ctxt->modrm_mod |= (ctxt->modrm & 0xc0) >> 6;
        ctxt->modrm_reg |= (ctxt->modrm & 0x38) >> 3;
        ctxt->modrm_rm |= (ctxt->modrm & 0x07);
@@ -3976,17 +3975,16 @@ done_prefixes:
        }
        ctxt->d = opcode.flags;
 
+       if (ctxt->d & ModRM)
+               ctxt->modrm = insn_fetch(u8, ctxt);
+
        while (ctxt->d & GroupMask) {
                switch (ctxt->d & GroupMask) {
                case Group:
-                       ctxt->modrm = insn_fetch(u8, ctxt);
-                       --ctxt->_eip;
                        goffset = (ctxt->modrm >> 3) & 7;
                        opcode = opcode.u.group[goffset];
                        break;
                case GroupDual:
-                       ctxt->modrm = insn_fetch(u8, ctxt);
-                       --ctxt->_eip;
                        goffset = (ctxt->modrm >> 3) & 7;
                        if ((ctxt->modrm >> 6) == 3)
                                opcode = opcode.u.gdual->mod3[goffset];