summaryrefslogtreecommitdiff
path: root/MdePkg
diff options
context:
space:
mode:
authorRuiyu Ni <ruiyu.ni@intel.com>2018-11-07 23:51:51 +0800
committerRuiyu Ni <ruiyu.ni@intel.com>2018-11-08 10:00:05 +0800
commite6459b9e6c9fc84414c87631df3662ce9cfbeabc (patch)
tree8dc62749813b6183126a67fde72c3b2fc8b7ca26 /MdePkg
parentc60d36b4d1ee1f69b7cca897d3621dfa951895c2 (diff)
downloadedk2-e6459b9e6c9fc84414c87631df3662ce9cfbeabc.zip
edk2-e6459b9e6c9fc84414c87631df3662ce9cfbeabc.tar.gz
edk2-e6459b9e6c9fc84414c87631df3662ce9cfbeabc.tar.bz2
MdePkg/BaseSynchronizationLib: Fix InternalSync[De|In]crement
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1303 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 <ruiyu.ni@intel.com> Cc: Liming Gao <liming.gao@intel.com> Cc: Michael Kinney <michael.d.kinney@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Philippe Mathieu-Daudé <philmd@redhat.com> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Tested-by: Laszlo Ersek <lersek@redhat.com> Suggested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Fixes: 8a94eb9283fa09a30f5f06f0c12cf0ee4e14fbcf Fixes: 17634d026f968c404b039a8d8431b6389dd396ea
Diffstat (limited to 'MdePkg')
-rw-r--r--MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c4
-rw-r--r--MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c4
2 files changed, 4 insertions, 4 deletions
diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
index af39bde..760a020 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 edb904c..767d462 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",