diff options
author | Avi Kivity <avi@qumranet.com> | 2007-10-31 04:27:04 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 10:52:59 -0500 |
commit | 3c118e24af821d68dca0ba81e9499820c840c133 (patch) | |
tree | 7fbf595f037f37d75119f50f2638ac0098f2eb51 | |
parent | de7d789acd7f373268194bb48dc0690c975ab8e6 (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.c | 80 |
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 | ||
523 | static 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 | |||
523 | int | 551 | int |
524 | x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | 552 | x86_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) { |