diff options
author | Guillaume Thouvenin <guillaume.thouvenin@ext.bull.net> | 2008-12-04 08:29:00 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2008-12-31 09:55:42 -0500 |
commit | d175226a5f54817ba427368c6b739aefa7780fb2 (patch) | |
tree | 4fdf34f9ce967a19885f231cc2726630ba6a3763 | |
parent | bfcadf83ec5aafe600e73dd427d997db7bcc1d12 (diff) |
KVM: x86 emulator: add the assembler code for three operands
Add the assembler code for instruction with three operands and one
operand is stored in ECX register
Signed-off-by: Guillaume Thouvenin <guillaume.thouvenin@ext.bull.net>
Signed-off-by: Avi Kivity <avi@redhat.com>
-rw-r--r-- | arch/x86/kvm/x86_emulate.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 0c75306e7a07..9ae6d5b3e962 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c | |||
@@ -431,6 +431,45 @@ static u32 group2_table[] = { | |||
431 | __emulate_2op_nobyte(_op, _src, _dst, _eflags, \ | 431 | __emulate_2op_nobyte(_op, _src, _dst, _eflags, \ |
432 | "w", "r", _LO32, "r", "", "r") | 432 | "w", "r", _LO32, "r", "", "r") |
433 | 433 | ||
434 | /* Instruction has three operands and one operand is stored in ECX register */ | ||
435 | #define __emulate_2op_cl(_op, _cl, _src, _dst, _eflags, _suffix, _type) \ | ||
436 | do { \ | ||
437 | unsigned long _tmp; \ | ||
438 | _type _clv = (_cl).val; \ | ||
439 | _type _srcv = (_src).val; \ | ||
440 | _type _dstv = (_dst).val; \ | ||
441 | \ | ||
442 | __asm__ __volatile__ ( \ | ||
443 | _PRE_EFLAGS("0", "5", "2") \ | ||
444 | _op _suffix " %4,%1 \n" \ | ||
445 | _POST_EFLAGS("0", "5", "2") \ | ||
446 | : "=m" (_eflags), "+r" (_dstv), "=&r" (_tmp) \ | ||
447 | : "c" (_clv) , "r" (_srcv), "i" (EFLAGS_MASK) \ | ||
448 | ); \ | ||
449 | \ | ||
450 | (_cl).val = (unsigned long) _clv; \ | ||
451 | (_src).val = (unsigned long) _srcv; \ | ||
452 | (_dst).val = (unsigned long) _dstv; \ | ||
453 | } while (0) | ||
454 | |||
455 | #define emulate_2op_cl(_op, _cl, _src, _dst, _eflags) \ | ||
456 | do { \ | ||
457 | switch ((_dst).bytes) { \ | ||
458 | case 2: \ | ||
459 | __emulate_2op_cl(_op, _cl, _src, _dst, _eflags, \ | ||
460 | "w", unsigned short); \ | ||
461 | break; \ | ||
462 | case 4: \ | ||
463 | __emulate_2op_cl(_op, _cl, _src, _dst, _eflags, \ | ||
464 | "l", unsigned int); \ | ||
465 | break; \ | ||
466 | case 8: \ | ||
467 | ON64(__emulate_2op_cl(_op, _cl, _src, _dst, _eflags, \ | ||
468 | "q", unsigned long)); \ | ||
469 | break; \ | ||
470 | } \ | ||
471 | } while (0) | ||
472 | |||
434 | #define __emulate_1op(_op, _dst, _eflags, _suffix) \ | 473 | #define __emulate_1op(_op, _dst, _eflags, _suffix) \ |
435 | do { \ | 474 | do { \ |
436 | unsigned long _tmp; \ | 475 | unsigned long _tmp; \ |