Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+28 −51
Original line number Diff line number Diff line
@@ -365,6 +365,18 @@ static u16 group2_table[] = {
#define ON64(x)
#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. */
#define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy) \
	do {								\
@@ -372,42 +384,23 @@ static u16 group2_table[] = {
									\
		switch ((_dst).bytes) {					\
		case 2:							\
			__asm__ __volatile__ (				    \
				_PRE_EFLAGS("0", "4", "2")		    \
				_op"w %"_wx"3,%1; "			    \
				_POST_EFLAGS("0", "4", "2")		    \
				: "=m" (_eflags), "=m" ((_dst).val),        \
				  "=&r" (_tmp)				    \
				: _wy ((_src).val), "i" (EFLAGS_MASK));     \
			____emulate_2op(_op,_src,_dst,_eflags,_wx,_wy,"w"); \
			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));     \
			____emulate_2op(_op,_src,_dst,_eflags,_lx,_ly,"l"); \
			break;						\
		case 8:							\
			__emulate_2op_8byte(_op, _src, _dst,		    \
					    _eflags, _qx, _qy);		    \
			ON64(____emulate_2op(_op,_src,_dst,_eflags,_qx,_qy,"q")); \
			break;						\
		}							\
	} while (0)

#define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \
	do {								     \
		unsigned long __tmp;					     \
		unsigned long _tmp;					     \
		switch ((_dst).bytes) {				             \
		case 1:							     \
			__asm__ __volatile__ (				     \
				_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));      \
			____emulate_2op(_op,_src,_dst,_eflags,_bx,_by,"b");  \
			break;						     \
		default:						     \
			__emulate_2op_nobyte(_op, _src, _dst, _eflags,	     \
@@ -455,22 +448,6 @@ static u16 group2_table[] = {
		}							\
	} 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. */
#define insn_fetch(_type, _size, _eip)                                  \
({	unsigned long _x;						\