aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-10-31 04:27:04 -0400
committerAvi Kivity <avi@qumranet.com>2008-01-30 10:52:59 -0500
commit3c118e24af821d68dca0ba81e9499820c840c133 (patch)
tree7fbf595f037f37d75119f50f2638ac0098f2eb51
parentde7d789acd7f373268194bb48dc0690c975ab8e6 (diff)
KVM: x86 emulator: Extract the common code of SrcReg and DstReg
Share the common parts of SrcReg and DstReg decoding. Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r--drivers/kvm/x86_emulate.c80
1 files changed, 31 insertions, 49 deletions
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c
index 087a8208f873..58ceb6616364 100644
--- a/drivers/kvm/x86_emulate.c
+++ b/drivers/kvm/x86_emulate.c
@@ -520,6 +520,34 @@ static int test_cc(unsigned int condition, unsigned int flags)
520 return (!!rc ^ (condition & 1)); 520 return (!!rc ^ (condition & 1));
521} 521}
522 522
523static void decode_register_operand(struct operand *op,
524 struct decode_cache *c,
525 int highbyte_regs,
526 int inhibit_bytereg)
527{
528 op->type = OP_REG;
529 if ((c->d & ByteOp) && !inhibit_bytereg) {
530 op->ptr = decode_register(c->modrm_reg, c->regs, highbyte_regs);
531 op->val = *(u8 *)op->ptr;
532 op->bytes = 1;
533 } else {
534 op->ptr = decode_register(c->modrm_reg, c->regs, 0);
535 op->bytes = c->op_bytes;
536 switch (op->bytes) {
537 case 2:
538 op->val = *(u16 *)op->ptr;
539 break;
540 case 4:
541 op->val = *(u32 *)op->ptr;
542 break;
543 case 8:
544 op->val = *(u64 *) op->ptr;
545 break;
546 }
547 }
548 op->orig_val = op->val;
549}
550
523int 551int
524x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) 552x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
525{ 553{
@@ -809,31 +837,7 @@ modrm_done:
809 case SrcNone: 837 case SrcNone:
810 break; 838 break;
811 case SrcReg: 839 case SrcReg:
812 c->src.type = OP_REG; 840 decode_register_operand(&c->src, c, rex_prefix == 0, 0);
813 if (c->d & ByteOp) {
814 c->src.ptr =
815 decode_register(c->modrm_reg, c->regs,
816 (rex_prefix == 0));
817 c->src.val = c->src.orig_val = *(u8 *)c->src.ptr;
818 c->src.bytes = 1;
819 } else {
820 c->src.ptr =
821 decode_register(c->modrm_reg, c->regs, 0);
822 switch ((c->src.bytes = c->op_bytes)) {
823 case 2:
824 c->src.val = c->src.orig_val =
825 *(u16 *) c->src.ptr;
826 break;
827 case 4:
828 c->src.val = c->src.orig_val =
829 *(u32 *) c->src.ptr;
830 break;
831 case 8:
832 c->src.val = c->src.orig_val =
833 *(u64 *) c->src.ptr;
834 break;
835 }
836 }
837 break; 841 break;
838 case SrcMem16: 842 case SrcMem16:
839 c->src.bytes = 2; 843 c->src.bytes = 2;
@@ -891,30 +895,8 @@ modrm_done:
891 /* Special instructions do their own operand decoding. */ 895 /* Special instructions do their own operand decoding. */
892 return 0; 896 return 0;
893 case DstReg: 897 case DstReg:
894 c->dst.type = OP_REG; 898 decode_register_operand(&c->dst, c, rex_prefix == 0,
895 if ((c->d & ByteOp) 899 c->twobyte && (c->b == 0xb6 || c->b == 0xb7));
896 && !(c->twobyte &&
897 (c->b == 0xb6 || c->b == 0xb7))) {
898 c->dst.ptr =
899 decode_register(c->modrm_reg, c->regs,
900 (rex_prefix == 0));
901 c->dst.val = *(u8 *) c->dst.ptr;
902 c->dst.bytes = 1;
903 } else {
904 c->dst.ptr =
905 decode_register(c->modrm_reg, c->regs, 0);
906 switch ((c->dst.bytes = c->op_bytes)) {
907 case 2:
908 c->dst.val = *(u16 *)c->dst.ptr;
909 break;
910 case 4:
911 c->dst.val = *(u32 *)c->dst.ptr;
912 break;
913 case 8:
914 c->dst.val = *(u64 *)c->dst.ptr;
915 break;
916 }
917 }
918 break; 900 break;
919 case DstMem: 901 case DstMem:
920 if ((c->d & ModRM) && c->modrm_mod == 3) { 902 if ((c->d & ModRM) && c->modrm_mod == 3) {