diff options
author | Avi Kivity <avi@redhat.com> | 2008-11-26 08:14:10 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2008-12-31 09:55:03 -0500 |
commit | dda96d8f1b3de692cce09969ce28fe22e58e5acf (patch) | |
tree | 366d3a2c3f01cca808d535859acbe32d87aa1fdf /arch/x86 | |
parent | ecc5589f19a52e7e6501fe449047b19087ae11bb (diff) |
KVM: x86 emulator: reduce duplication in one operand emulation thunks
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kvm/x86_emulate.c | 66 |
1 files changed, 23 insertions, 43 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 8f60ace13874..5f87d3e59195 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c | |||
@@ -359,6 +359,12 @@ static u16 group2_table[] = { | |||
359 | "andl %"_msk",%"_LO32 _tmp"; " \ | 359 | "andl %"_msk",%"_LO32 _tmp"; " \ |
360 | "orl %"_LO32 _tmp",%"_sav"; " | 360 | "orl %"_LO32 _tmp",%"_sav"; " |
361 | 361 | ||
362 | #ifdef CONFIG_X86_64 | ||
363 | #define ON64(x) x | ||
364 | #else | ||
365 | #define ON64(x) | ||
366 | #endif | ||
367 | |||
362 | /* Raw emulation: instruction has two explicit operands. */ | 368 | /* Raw emulation: instruction has two explicit operands. */ |
363 | #define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \ | 369 | #define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \ |
364 | do { \ | 370 | do { \ |
@@ -425,42 +431,27 @@ static u16 group2_table[] = { | |||
425 | __emulate_2op_nobyte(_op, _src, _dst, _eflags, \ | 431 | __emulate_2op_nobyte(_op, _src, _dst, _eflags, \ |
426 | "w", "r", _LO32, "r", "", "r") | 432 | "w", "r", _LO32, "r", "", "r") |
427 | 433 | ||
428 | /* Instruction has only one explicit operand (no source operand). */ | 434 | #define __emulate_1op(_op, _dst, _eflags, _suffix) \ |
429 | #define emulate_1op(_op, _dst, _eflags) \ | ||
430 | do { \ | 435 | do { \ |
431 | unsigned long _tmp; \ | 436 | unsigned long _tmp; \ |
432 | \ | 437 | \ |
438 | __asm__ __volatile__ ( \ | ||
439 | _PRE_EFLAGS("0", "3", "2") \ | ||
440 | _op _suffix " %1; " \ | ||
441 | _POST_EFLAGS("0", "3", "2") \ | ||
442 | : "=m" (_eflags), "+m" ((_dst).val), \ | ||
443 | "=&r" (_tmp) \ | ||
444 | : "i" (EFLAGS_MASK)); \ | ||
445 | } while (0) | ||
446 | |||
447 | /* Instruction has only one explicit operand (no source operand). */ | ||
448 | #define emulate_1op(_op, _dst, _eflags) \ | ||
449 | do { \ | ||
433 | switch ((_dst).bytes) { \ | 450 | switch ((_dst).bytes) { \ |
434 | case 1: \ | 451 | case 1: __emulate_1op(_op, _dst, _eflags, "b"); break; \ |
435 | __asm__ __volatile__ ( \ | 452 | case 2: __emulate_1op(_op, _dst, _eflags, "w"); break; \ |
436 | _PRE_EFLAGS("0", "3", "2") \ | 453 | case 4: __emulate_1op(_op, _dst, _eflags, "l"); break; \ |
437 | _op"b %1; " \ | 454 | case 8: ON64(__emulate_1op(_op, _dst, _eflags, "q")); break; \ |
438 | _POST_EFLAGS("0", "3", "2") \ | ||
439 | : "=m" (_eflags), "=m" ((_dst).val), \ | ||
440 | "=&r" (_tmp) \ | ||
441 | : "i" (EFLAGS_MASK)); \ | ||
442 | break; \ | ||
443 | case 2: \ | ||
444 | __asm__ __volatile__ ( \ | ||
445 | _PRE_EFLAGS("0", "3", "2") \ | ||
446 | _op"w %1; " \ | ||
447 | _POST_EFLAGS("0", "3", "2") \ | ||
448 | : "=m" (_eflags), "=m" ((_dst).val), \ | ||
449 | "=&r" (_tmp) \ | ||
450 | : "i" (EFLAGS_MASK)); \ | ||
451 | break; \ | ||
452 | case 4: \ | ||
453 | __asm__ __volatile__ ( \ | ||
454 | _PRE_EFLAGS("0", "3", "2") \ | ||
455 | _op"l %1; " \ | ||
456 | _POST_EFLAGS("0", "3", "2") \ | ||
457 | : "=m" (_eflags), "=m" ((_dst).val), \ | ||
458 | "=&r" (_tmp) \ | ||
459 | : "i" (EFLAGS_MASK)); \ | ||
460 | break; \ | ||
461 | case 8: \ | ||
462 | __emulate_1op_8byte(_op, _dst, _eflags); \ | ||
463 | break; \ | ||
464 | } \ | 455 | } \ |
465 | } while (0) | 456 | } while (0) |
466 | 457 | ||
@@ -476,19 +467,8 @@ static u16 group2_table[] = { | |||
476 | : _qy ((_src).val), "i" (EFLAGS_MASK)); \ | 467 | : _qy ((_src).val), "i" (EFLAGS_MASK)); \ |
477 | } while (0) | 468 | } while (0) |
478 | 469 | ||
479 | #define __emulate_1op_8byte(_op, _dst, _eflags) \ | ||
480 | do { \ | ||
481 | __asm__ __volatile__ ( \ | ||
482 | _PRE_EFLAGS("0", "3", "2") \ | ||
483 | _op"q %1; " \ | ||
484 | _POST_EFLAGS("0", "3", "2") \ | ||
485 | : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \ | ||
486 | : "i" (EFLAGS_MASK)); \ | ||
487 | } while (0) | ||
488 | |||
489 | #elif defined(__i386__) | 470 | #elif defined(__i386__) |
490 | #define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) | 471 | #define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) |
491 | #define __emulate_1op_8byte(_op, _dst, _eflags) | ||
492 | #endif /* __i386__ */ | 472 | #endif /* __i386__ */ |
493 | 473 | ||
494 | /* Fetch next part of the instruction being emulated. */ | 474 | /* Fetch next part of the instruction being emulated. */ |