aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86_emulate.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2008-11-26 08:30:45 -0500
committerAvi Kivity <avi@redhat.com>2008-12-31 09:55:03 -0500
commit6b7ad61ffb9ca110add6f7fb36cc8a4dd89696a4 (patch)
tree21c1aa0a976dec1ea46410184cd2131aa13c8158 /arch/x86/kvm/x86_emulate.c
parentdda96d8f1b3de692cce09969ce28fe22e58e5acf (diff)
KVM: x86 emulator: consolidate emulation of two operand instructions
No need to repeat the same assembly block over and over. Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86_emulate.c')
-rw-r--r--arch/x86/kvm/x86_emulate.c79
1 files changed, 28 insertions, 51 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
index 5f87d3e59195..a11af6f74d68 100644
--- a/arch/x86/kvm/x86_emulate.c
+++ b/arch/x86/kvm/x86_emulate.c
@@ -365,49 +365,42 @@ static u16 group2_table[] = {
365#define ON64(x) 365#define ON64(x)
366#endif 366#endif
367 367
368#define ____emulate_2op(_op, _src, _dst, _eflags, _x, _y, _suffix) \
369 do { \
370 __asm__ __volatile__ ( \
371 _PRE_EFLAGS("0", "4", "2") \
372 _op _suffix " %"_x"3,%1; " \
373 _POST_EFLAGS("0", "4", "2") \
374 : "=m" (_eflags), "=m" ((_dst).val), \
375 "=&r" (_tmp) \
376 : _y ((_src).val), "i" (EFLAGS_MASK)); \
377 } while (0);
378
379
368/* Raw emulation: instruction has two explicit operands. */ 380/* Raw emulation: instruction has two explicit operands. */
369#define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \ 381#define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \
370 do { \ 382 do { \
371 unsigned long _tmp; \ 383 unsigned long _tmp; \
372 \ 384 \
373 switch ((_dst).bytes) { \ 385 switch ((_dst).bytes) { \
374 case 2: \ 386 case 2: \
375 __asm__ __volatile__ ( \ 387 ____emulate_2op(_op,_src,_dst,_eflags,_wx,_wy,"w"); \
376 _PRE_EFLAGS("0", "4", "2") \ 388 break; \
377 _op"w %"_wx"3,%1; " \ 389 case 4: \
378 _POST_EFLAGS("0", "4", "2") \ 390 ____emulate_2op(_op,_src,_dst,_eflags,_lx,_ly,"l"); \
379 : "=m" (_eflags), "=m" ((_dst).val), \ 391 break; \
380 "=&r" (_tmp) \ 392 case 8: \
381 : _wy ((_src).val), "i" (EFLAGS_MASK)); \ 393 ON64(____emulate_2op(_op,_src,_dst,_eflags,_qx,_qy,"q")); \
382 break; \ 394 break; \
383 case 4: \ 395 } \
384 __asm__ __volatile__ ( \
385 _PRE_EFLAGS("0", "4", "2") \
386 _op"l %"_lx"3,%1; " \
387 _POST_EFLAGS("0", "4", "2") \
388 : "=m" (_eflags), "=m" ((_dst).val), \
389 "=&r" (_tmp) \
390 : _ly ((_src).val), "i" (EFLAGS_MASK)); \
391 break; \
392 case 8: \
393 __emulate_2op_8byte(_op, _src, _dst, \
394 _eflags, _qx, _qy); \
395 break; \
396 } \
397 } while (0) 396 } while (0)
398 397
399#define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \ 398#define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \
400 do { \ 399 do { \
401 unsigned long __tmp; \ 400 unsigned long _tmp; \
402 switch ((_dst).bytes) { \ 401 switch ((_dst).bytes) { \
403 case 1: \ 402 case 1: \
404 __asm__ __volatile__ ( \ 403 ____emulate_2op(_op,_src,_dst,_eflags,_bx,_by,"b"); \
405 _PRE_EFLAGS("0", "4", "2") \
406 _op"b %"_bx"3,%1; " \
407 _POST_EFLAGS("0", "4", "2") \
408 : "=m" (_eflags), "=m" ((_dst).val), \
409 "=&r" (__tmp) \
410 : _by ((_src).val), "i" (EFLAGS_MASK)); \
411 break; \ 404 break; \
412 default: \ 405 default: \
413 __emulate_2op_nobyte(_op, _src, _dst, _eflags, \ 406 __emulate_2op_nobyte(_op, _src, _dst, _eflags, \
@@ -455,22 +448,6 @@ static u16 group2_table[] = {
455 } \ 448 } \
456 } while (0) 449 } while (0)
457 450
458/* Emulate an instruction with quadword operands (x86/64 only). */
459#if defined(CONFIG_X86_64)
460#define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) \
461 do { \
462 __asm__ __volatile__ ( \
463 _PRE_EFLAGS("0", "4", "2") \
464 _op"q %"_qx"3,%1; " \
465 _POST_EFLAGS("0", "4", "2") \
466 : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \
467 : _qy ((_src).val), "i" (EFLAGS_MASK)); \
468 } while (0)
469
470#elif defined(__i386__)
471#define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy)
472#endif /* __i386__ */
473
474/* Fetch next part of the instruction being emulated. */ 451/* Fetch next part of the instruction being emulated. */
475#define insn_fetch(_type, _size, _eip) \ 452#define insn_fetch(_type, _size, _eip) \
476({ unsigned long _x; \ 453({ unsigned long _x; \