Use + on outputs instead of = and a matching input. Allow not just
memory for the _eflags operand (it turns out that recent gcc produces
worse code when also doing this for _dst.val, so the latter is being
avoided).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -428,7 +428,7 @@ typedef union {
/* Before executing instruction: restore necessary bits in EFLAGS. */
#define _PRE_EFLAGS(_sav, _msk, _tmp) \
/* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); _sav &= ~_msk; */ \
-"movl %"_sav",%"_LO32 _tmp"; " \
+"movl %"_LO32 _sav",%"_LO32 _tmp"; " \
"push %"_tmp"; " \
"push %"_tmp"; " \
"movl %"_msk",%"_LO32 _tmp"; " \
@@ -448,7 +448,7 @@ typedef union {
"pushf; " \
"pop %"_tmp"; " \
"andl %"_msk",%"_LO32 _tmp"; " \
-"orl %"_LO32 _tmp",%"_sav"; "
+"orl %"_LO32 _tmp",%"_LO32 _sav"; "
/* Raw emulation: instruction has two explicit operands. */
#define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy)\
@@ -460,18 +460,16 @@ do{ unsigned long _tmp;
_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), \
- "m" (_eflags), "m" ((_dst).val) ); \
+ : "+g" (_eflags), "+m" ((_dst).val), "=&r" (_tmp) \
+ : _wy ((_src).val), "i" (EFLAGS_MASK) ); \