From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.151; helo=mga17.intel.com; envelope-from=ruiyu.ni@intel.com; receiver=edk2-devel@lists.01.org Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 4204F21184E83 for ; Wed, 7 Nov 2018 07:53:13 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Nov 2018 07:53:13 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,475,1534834800"; d="scan'208";a="106101388" Received: from ray-dev.ccr.corp.intel.com ([10.239.9.11]) by fmsmga001.fm.intel.com with ESMTP; 07 Nov 2018 07:53:12 -0800 From: Ruiyu Ni To: edk2-devel@lists.01.org Cc: Liming Gao , Michael Kinney , Laszlo Ersek , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Ard Biesheuvel Date: Wed, 7 Nov 2018 23:54:33 +0800 Message-Id: <20181107155433.177700-1-ruiyu.ni@intel.com> X-Mailer: git-send-email 2.16.1.windows.1 MIME-Version: 1.0 Subject: [PATCH v2] MdePkg/BaseSynchronizationLib: Fix InternalSync[De|In]crement X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 07 Nov 2018 15:53:14 -0000 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Today's code generates assembly code as below for InternalSyncIncrement: __asm__ __volatile__ ( "movl $1, %%eax \n\t" "lock \n\t" "xadd %%eax, %1 \n\t" "inc %%eax \n\t" : "=a" (Result), // %0 "+m" (*Value) // %1 : // no inputs that aren't also outputs : "memory", "cc" ); 0: 55 pushl %ebp 1: 89 e5 movl %esp, %ebp 3: 8b 45 08 movl 8(%ebp), %eax 6: b8 01 00 00 00 movl $1, %eax b: f0 lock c: 0f c1 00 xaddl %eax, _InternalSyncIncrement(%eax) f: 40 incl %eax 10: 5d popl %ebp 11: c3 retl Line #3 and Line #6 both use EAX as destination register. Line #c uses EAX and (EAX). The output operand "=a" tells GCC that EAX is used for output. But GCC only assumes that EAX will be used in the very last instruction. Per GCC document, "Use the ‘&’ constraint modifier on all output operands that must not overlap an input. Otherwise, GCC may allocate the output operand in the same register as an unrelated input operand, on the assumption that the assembler code consumes its inputs before producing outputs. This assumption may be false if the assembler code actually consists of more than one instruction." "=&a" should be used to tell GCC not use EAX before the assembly. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ruiyu Ni Cc: Liming Gao Cc: Michael Kinney Cc: Laszlo Ersek Cc: Philippe Mathieu-Daudé Cc: Ard Biesheuvel --- MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c | 4 ++-- MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c index af39bdeb51..760a020a32 100644 --- a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c @@ -40,7 +40,7 @@ InternalSyncIncrement ( "lock \n\t" "xadd %%eax, %1 \n\t" "inc %%eax \n\t" - : "=a" (Result), // %0 + : "=&a" (Result), // %0 "+m" (*Value) // %1 : // no inputs that aren't also outputs : "memory", @@ -76,7 +76,7 @@ InternalSyncDecrement ( "lock \n\t" "xadd %%eax, %1 \n\t" "dec %%eax \n\t" - : "=a" (Result), // %0 + : "=&a" (Result), // %0 "+m" (*Value) // %1 : // no inputs that aren't also outputs : "memory", diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c index edb904c007..767d4626b8 100644 --- a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c +++ b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c @@ -40,7 +40,7 @@ InternalSyncIncrement ( "lock \n\t" "xadd %%eax, %1 \n\t" "inc %%eax \n\t" - : "=a" (Result), // %0 + : "=&a" (Result), // %0 "+m" (*Value) // %1 : // no inputs that aren't also outputs : "memory", @@ -76,7 +76,7 @@ InternalSyncDecrement ( "lock \n\t" "xadd %%eax, %1 \n\t" "dec %%eax \n\t" - : "=a" (Result), // %0 + : "=&a" (Result), // %0 "+m" (*Value) // %1 : // no inputs that aren't also outputs : "memory", -- 2.16.1.windows.1