Commit 6b7ad61f authored by Avi Kivity's avatar Avi Kivity

KVM: x86 emulator: consolidate emulation of two operand instructions

No need to repeat the same assembly block over and over.
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent dda96d8f
...@@ -365,49 +365,42 @@ static u16 group2_table[] = { ...@@ -365,49 +365,42 @@ static u16 group2_table[] = {
#define ON64(x) #define ON64(x)
#endif #endif
#define ____emulate_2op(_op, _src, _dst, _eflags, _x, _y, _suffix) \
do { \
__asm__ __volatile__ ( \
_PRE_EFLAGS("0", "4", "2") \
_op _suffix " %"_x"3,%1; " \
_POST_EFLAGS("0", "4", "2") \
: "=m" (_eflags), "=m" ((_dst).val), \
"=&r" (_tmp) \
: _y ((_src).val), "i" (EFLAGS_MASK)); \
} while (0);
/* Raw emulation: instruction has two explicit operands. */ /* Raw emulation: instruction has two explicit operands. */
#define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \ #define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \
do { \ do { \
unsigned long _tmp; \ unsigned long _tmp; \
\ \
switch ((_dst).bytes) { \ switch ((_dst).bytes) { \
case 2: \ case 2: \
__asm__ __volatile__ ( \ ____emulate_2op(_op,_src,_dst,_eflags,_wx,_wy,"w"); \
_PRE_EFLAGS("0", "4", "2") \ break; \
_op"w %"_wx"3,%1; " \ case 4: \
_POST_EFLAGS("0", "4", "2") \ ____emulate_2op(_op,_src,_dst,_eflags,_lx,_ly,"l"); \
: "=m" (_eflags), "=m" ((_dst).val), \ break; \
"=&r" (_tmp) \ case 8: \
: _wy ((_src).val), "i" (EFLAGS_MASK)); \ ON64(____emulate_2op(_op,_src,_dst,_eflags,_qx,_qy,"q")); \
break; \ break; \
case 4: \ } \
__asm__ __volatile__ ( \
_PRE_EFLAGS("0", "4", "2") \
_op"l %"_lx"3,%1; " \
_POST_EFLAGS("0", "4", "2") \
: "=m" (_eflags), "=m" ((_dst).val), \
"=&r" (_tmp) \
: _ly ((_src).val), "i" (EFLAGS_MASK)); \
break; \
case 8: \
__emulate_2op_8byte(_op, _src, _dst, \
_eflags, _qx, _qy); \
break; \
} \
} while (0) } while (0)
#define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \ #define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \
do { \ do { \
unsigned long __tmp; \ unsigned long _tmp; \
switch ((_dst).bytes) { \ switch ((_dst).bytes) { \
case 1: \ case 1: \
__asm__ __volatile__ ( \ ____emulate_2op(_op,_src,_dst,_eflags,_bx,_by,"b"); \
_PRE_EFLAGS("0", "4", "2") \
_op"b %"_bx"3,%1; " \
_POST_EFLAGS("0", "4", "2") \
: "=m" (_eflags), "=m" ((_dst).val), \
"=&r" (__tmp) \
: _by ((_src).val), "i" (EFLAGS_MASK)); \
break; \ break; \
default: \ default: \
__emulate_2op_nobyte(_op, _src, _dst, _eflags, \ __emulate_2op_nobyte(_op, _src, _dst, _eflags, \
...@@ -455,22 +448,6 @@ static u16 group2_table[] = { ...@@ -455,22 +448,6 @@ static u16 group2_table[] = {
} \ } \
} while (0) } while (0)
/* Emulate an instruction with quadword operands (x86/64 only). */
#if defined(CONFIG_X86_64)
#define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy) \
do { \
__asm__ __volatile__ ( \
_PRE_EFLAGS("0", "4", "2") \
_op"q %"_qx"3,%1; " \
_POST_EFLAGS("0", "4", "2") \
: "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp) \
: _qy ((_src).val), "i" (EFLAGS_MASK)); \
} while (0)
#elif defined(__i386__)
#define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy)
#endif /* __i386__ */
/* Fetch next part of the instruction being emulated. */ /* Fetch next part of the instruction being emulated. */
#define insn_fetch(_type, _size, _eip) \ #define insn_fetch(_type, _size, _eip) \
({ unsigned long _x; \ ({ unsigned long _x; \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment