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 <[email protected]>
Cc: Liming Gao <[email protected]>
Cc: Michael Kinney <[email protected]>
Cc: Laszlo Ersek <[email protected]>
Cc: Philippe Mathieu-Daudé <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
---
 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

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to