Ruiyu Ni e6459b9e6c 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
2018-11-08 10:00:05 +08:00
2014-10-14 16:08:15 +00:00

EDK II Project

A modern, feature-rich, cross-platform firmware development environment for the UEFI and PI specifications from www.uefi.org.

Contributions to the EDK II open source project are covered by the TianoCore Contribution Agreement 1.1

The majority of the content in the EDK II open source project uses a BSD 2-Clause License. The EDK II open source project contains the following components that are covered by additional licenses:

The EDK II Project is composed of packages. The maintainers for each package are listed in Maintainers.txt.

Resources

Description
Acidanthera UEFI Development Kit based on EDK II edk2-stable202405
Readme 330 MiB
Languages
C 71.6%
Assembly 16.4%
Python 8.5%
Rich Text Format 1.3%
C++ 0.8%
Other 1%