Revision: 16966
          http://sourceforge.net/p/edk2/code/16966
Author:   lersek
Date:     2015-02-28 20:31:54 +0000 (Sat, 28 Feb 2015)
Log Message:
-----------
MdePkg/BaseSynchronizationLib: Add InterlockedCompareExchange16

This implements the function InterlockedCompareExchange16 () for all
architectures, using architecture and toolchain specific intrinsics
or primitive assembler instructions.

Contributed-under: TianoCore Contribution Agreement 1.0
Reviewed-by: Olivier Martin <[email protected]>
Acked-by: Jordan Justen <[email protected]>
Reviewed-by: Michael Kinney <[email protected]>
Signed-off-by: Ard Biesheuvel <[email protected]>
Signed-off-by: Laszlo Ersek <[email protected]>

Modified Paths:
--------------
    trunk/edk2/MdePkg/Include/Library/SynchronizationLib.h
    trunk/edk2/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
    trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
    trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
    trunk/edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
    
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
    trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
    trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
    trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
    trunk/edk2/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
    trunk/edk2/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
    trunk/edk2/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c

Added Paths:
-----------
    
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
    
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
    
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
    
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
    
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c

Modified: trunk/edk2/MdePkg/Include/Library/SynchronizationLib.h
===================================================================
--- trunk/edk2/MdePkg/Include/Library/SynchronizationLib.h      2015-02-28 
20:31:40 UTC (rev 16965)
+++ trunk/edk2/MdePkg/Include/Library/SynchronizationLib.h      2015-02-28 
20:31:54 UTC (rev 16966)
@@ -184,6 +184,32 @@
 
 
 /**
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer
+  specified by Value.  If Value is equal to CompareValue, then Value is set to
+  ExchangeValue and CompareValue is returned.  If Value is not equal to 
CompareValue,
+  then Value is returned.  The compare exchange operation must be performed 
using
+  MP safe mechanisms.
+
+  If Value is NULL, then ASSERT().
+
+  @param  Value         A pointer to the 16-bit value for the compare exchange
+                        operation.
+  @param  CompareValue  16-bit value used in compare operation.
+  @param  ExchangeValue 16-bit value used in exchange operation.
+
+  @return The original *Value before exchange.
+**/
+UINT16
+EFIAPI
+InterlockedCompareExchange16 (
+  IN OUT  UINT16                    *Value,
+  IN      UINT16                    CompareValue,
+  IN      UINT16                    ExchangeValue
+  );
+
+/**
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.
 
   Performs an atomic compare exchange operation on the 32-bit unsigned integer

Modified: 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S
===================================================================
--- trunk/edk2/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S  
2015-02-28 20:31:40 UTC (rev 16965)
+++ trunk/edk2/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S  
2015-02-28 20:31:54 UTC (rev 16966)
@@ -16,12 +16,56 @@
 .text
 .align 3
 
+GCC_ASM_EXPORT(InternalSyncCompareExchange16)
 GCC_ASM_EXPORT(InternalSyncCompareExchange32)
 GCC_ASM_EXPORT(InternalSyncCompareExchange64)
 GCC_ASM_EXPORT(InternalSyncIncrement)
 GCC_ASM_EXPORT(InternalSyncDecrement)
 
 /**
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer
+  specified by Value.  If Value is equal to CompareValue, then Value is set to
+  ExchangeValue and CompareValue is returned.  If Value is not equal to 
CompareValue,
+  then Value is returned.  The compare exchange operation must be performed 
using
+  MP safe mechanisms.
+
+  @param  Value         A pointer to the 16-bit value for the compare exchange
+                        operation.
+  @param  CompareValue  16-bit value used in compare operation.
+  @param  ExchangeValue 16-bit value used in exchange operation.
+
+  @return The original *Value before exchange.
+
+**/
+//UINT16
+//EFIAPI
+//InternalSyncCompareExchange16 (
+//  IN      volatile UINT16           *Value,
+//  IN      UINT16                    CompareValue,
+//  IN      UINT16                    ExchangeValue
+//  )
+ASM_PFX(InternalSyncCompareExchange16):
+  uxth    w1, w1
+  uxth    w2, w2
+  dmb     sy
+
+InternalSyncCompareExchange16Again:
+  ldxrh   w3, [x0]
+  cmp     w3, w1
+  bne     InternalSyncCompareExchange16Fail
+
+InternalSyncCompareExchange16Exchange:
+  stxrh   w4, w2, [x0]
+  cbnz    w4, InternalSyncCompareExchange16Again
+
+InternalSyncCompareExchange16Fail:
+  dmb     sy
+  mov     w0, w3
+  ret
+
+/**
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.
 
   Performs an atomic compare exchange operation on the 32-bit unsigned integer

Modified: trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S
===================================================================
--- trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S      
2015-02-28 20:31:40 UTC (rev 16965)
+++ trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S      
2015-02-28 20:31:54 UTC (rev 16966)
@@ -1,6 +1,7 @@
 //  Implementation of synchronization functions for ARM architecture
 //
 //  Copyright (c) 2012-2015, ARM Limited. All rights reserved.
+//  Copyright (c) 2015, Linaro Limited. All rights reserved.
 //
 //  This program and the accompanying materials
 //  are licensed and made available under the terms and conditions of the BSD 
License
@@ -15,12 +16,55 @@
 .text
 .align 3
 
+GCC_ASM_EXPORT(InternalSyncCompareExchange16)
 GCC_ASM_EXPORT(InternalSyncCompareExchange32)
 GCC_ASM_EXPORT(InternalSyncCompareExchange64)
 GCC_ASM_EXPORT(InternalSyncIncrement)
 GCC_ASM_EXPORT(InternalSyncDecrement)
 
 /**
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer
+  specified by Value.  If Value is equal to CompareValue, then Value is set to
+  ExchangeValue and CompareValue is returned.  If Value is not equal to 
CompareValue,
+  then Value is returned.  The compare exchange operation must be performed 
using
+  MP safe mechanisms.
+
+  @param  Value         A pointer to the 16-bit value for the compare exchange
+                        operation.
+  @param  CompareValue  16-bit value used in compare operation.
+  @param  ExchangeValue 16-bit value used in exchange operation.
+
+  @return The original *Value before exchange.
+
+**/
+//UINT16
+//EFIAPI
+//InternalSyncCompareExchange16 (
+//  IN      volatile UINT16           *Value,
+//  IN      UINT16                    CompareValue,
+//  IN      UINT16                    ExchangeValue
+//  )
+ASM_PFX(InternalSyncCompareExchange16):
+  dmb
+
+InternalSyncCompareExchange16Again:
+  ldrexh  r3, [r0]
+  cmp     r3, r1
+  bne     InternalSyncCompareExchange16Fail
+
+InternalSyncCompareExchange16Exchange:
+  strexh  ip, r2, [r0]
+  cmp     ip, #0
+  bne     InternalSyncCompareExchange16Again
+
+InternalSyncCompareExchange16Fail:
+  dmb
+  mov     r0, r3
+  bx      lr
+
+/**
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.
 
   Performs an atomic compare exchange operation on the 32-bit unsigned integer

Modified: 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm
===================================================================
--- trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm    
2015-02-28 20:31:40 UTC (rev 16965)
+++ trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm    
2015-02-28 20:31:54 UTC (rev 16966)
@@ -1,6 +1,7 @@
 //  Implementation of synchronization functions for ARM architecture
 //
 //  Copyright (c) 2012-2015, ARM Limited. All rights reserved.
+//  Copyright (c) 2015, Linaro Limited. All rights reserved.
 //
 //  This program and the accompanying materials
 //  are licensed and made available under the terms and conditions of the BSD 
License
@@ -12,6 +13,7 @@
 //
 //
 
+    EXPORT  InternalSyncCompareExchange16
     EXPORT  InternalSyncCompareExchange32
     EXPORT  InternalSyncCompareExchange64
     EXPORT  InternalSyncIncrement
@@ -20,6 +22,48 @@
     AREA   ArmSynchronization, CODE, READONLY
 
 /**
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer
+  specified by Value.  If Value is equal to CompareValue, then Value is set to
+  ExchangeValue and CompareValue is returned.  If Value is not equal to 
CompareValue,
+  then Value is returned.  The compare exchange operation must be performed 
using
+  MP safe mechanisms.
+
+  @param  Value         A pointer to the 16-bit value for the compare exchange
+                        operation.
+  @param  CompareValue  16-bit value used in compare operation.
+  @param  ExchangeValue 16-bit value used in exchange operation.
+
+  @return The original *Value before exchange.
+
+**/
+//UINT16
+//EFIAPI
+//InternalSyncCompareExchange16 (
+//  IN      volatile UINT16           *Value,
+//  IN      UINT16                    CompareValue,
+//  IN      UINT16                    ExchangeValue
+//  )
+InternalSyncCompareExchange16
+  dmb
+
+InternalSyncCompareExchange16Again
+  ldrexh  r3, [r0]
+  cmp     r3, r1
+  bne     InternalSyncCompareExchange16Fail
+
+InternalSyncCompareExchange16Exchange
+  strexh  ip, r2, [r0]
+  cmp     ip, #0
+  bne     InternalSyncCompareExchange16Again
+
+InternalSyncCompareExchange16Fail
+  dmb
+  mov     r0, r3
+  bx      lr
+
+/**
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.
 
   Performs an atomic compare exchange operation on the 32-bit unsigned integer

Modified: 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
===================================================================
--- trunk/edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf 
2015-02-28 20:31:40 UTC (rev 16965)
+++ trunk/edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf 
2015-02-28 20:31:54 UTC (rev 16966)
@@ -32,12 +32,14 @@
 [Sources.IA32]
   Ia32/InterlockedCompareExchange64.c | MSFT 
   Ia32/InterlockedCompareExchange32.c | MSFT 
+  Ia32/InterlockedCompareExchange16.c | MSFT
   Ia32/InterlockedDecrement.c | MSFT 
   Ia32/InterlockedIncrement.c | MSFT 
   SynchronizationMsc.c  | MSFT
 
   Ia32/InterlockedCompareExchange64.asm | INTEL 
   Ia32/InterlockedCompareExchange32.asm | INTEL 
+  Ia32/InterlockedCompareExchange16.asm | INTEL
   Ia32/InterlockedDecrement.asm | INTEL 
   Ia32/InterlockedIncrement.asm | INTEL 
   Synchronization.c | INTEL
@@ -48,9 +50,11 @@
 [Sources.X64]
   X64/InterlockedCompareExchange64.c | MSFT
   X64/InterlockedCompareExchange32.c | MSFT
+  X64/InterlockedCompareExchange16.c | MSFT
   
   X64/InterlockedCompareExchange64.asm | INTEL
   X64/InterlockedCompareExchange32.asm | INTEL
+  X64/InterlockedCompareExchange16.asm | INTEL
   
   X64/InterlockedDecrement.c | MSFT 
   X64/InterlockedIncrement.c | MSFT 
@@ -67,6 +71,7 @@
   Ipf/Synchronization.c
   Ipf/InterlockedCompareExchange64.s
   Ipf/InterlockedCompareExchange32.s
+  Ipf/InterlockedCompareExchange16.s
 
   Synchronization.c     | INTEL 
   SynchronizationMsc.c  | MSFT 

Modified: 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
===================================================================
--- 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
  2015-02-28 20:31:40 UTC (rev 16965)
+++ 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h
  2015-02-28 20:31:54 UTC (rev 16966)
@@ -63,6 +63,32 @@
 
 
 /**
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer
+  specified by Value.  If Value is equal to CompareValue, then Value is set to
+  ExchangeValue and CompareValue is returned.  If Value is not equal to 
CompareValue,
+  then Value is returned.  The compare exchange operation must be performed 
using
+  MP safe mechanisms.
+
+  @param  Value         A pointer to the 16-bit value for the compare exchange
+                        operation.
+  @param  CompareValue  A 16-bit value used in compare operation.
+  @param  ExchangeValue A 16-bit value used in exchange operation.
+
+  @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+  IN      volatile UINT16           *Value,
+  IN      UINT16                    CompareValue,
+  IN      UINT16                    ExchangeValue
+  );
+
+
+/**
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.
 
   Performs an atomic compare exchange operation on the 32-bit unsigned integer

Modified: trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c
===================================================================
--- trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c      
2015-02-28 20:31:40 UTC (rev 16965)
+++ trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c      
2015-02-28 20:31:54 UTC (rev 16966)
@@ -13,6 +13,37 @@
 **/
 
 /**
+  Performs an atomic compare exchange operation on a 16-bit
+  unsigned integer.
+
+  Performs an atomic compare exchange operation on the 16-bit
+  unsigned integer specified by Value.  If Value is equal to
+  CompareValue, then Value is set to ExchangeValue and
+  CompareValue is returned.  If Value is not equal to
+  CompareValue, then Value is returned. The compare exchange
+  operation must be performed using MP safe mechanisms.
+
+  @param  Value         A pointer to the 16-bit value for the
+                        compare exchange operation.
+  @param  CompareValue  16-bit value used in compare operation.
+  @param  ExchangeValue 16-bit value used in exchange operation.
+
+  @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+  IN      volatile UINT16           *Value,
+  IN      UINT16                    CompareValue,
+  IN      UINT16                    ExchangeValue
+  )
+{
+  return *Value != CompareValue ? *Value :
+           ((*Value = ExchangeValue), CompareValue);
+}
+
+/**
   Performs an atomic compare exchange operation on a 32-bit
   unsigned integer.
 

Modified: trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c
===================================================================
--- trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c   
2015-02-28 20:31:40 UTC (rev 16965)
+++ trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c   
2015-02-28 20:31:54 UTC (rev 16966)
@@ -88,6 +88,48 @@
 }
 
 /**
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer
+  specified by Value.  If Value is equal to CompareValue, then Value is set to
+  ExchangeValue and CompareValue is returned.  If Value is not equal to 
CompareValue,
+  then Value is returned.  The compare exchange operation must be performed 
using
+  MP safe mechanisms.
+
+
+  @param  Value         A pointer to the 16-bit value for the compare exchange
+                        operation.
+  @param  CompareValue  16-bit value used in compare operation.
+  @param  ExchangeValue 16-bit value used in exchange operation.
+
+  @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+  IN OUT volatile  UINT16           *Value,
+  IN      UINT16                    CompareValue,
+  IN      UINT16                    ExchangeValue
+  )
+{
+
+  __asm__ __volatile__ (
+    "                     \n\t"
+    "lock                 \n\t"
+    "cmpxchgw    %1, %2   \n\t"
+    : "=a" (CompareValue)
+    : "q"  (ExchangeValue),
+      "m"  (*Value),
+      "0"  (CompareValue)
+    : "memory",
+      "cc"
+    );
+
+  return CompareValue;
+}
+
+/**
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.
 
   Performs an atomic compare exchange operation on the 32-bit unsigned integer

Added: 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
===================================================================
--- 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
                              (rev 0)
+++ 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm
      2015-02-28 20:31:54 UTC (rev 16966)
@@ -0,0 +1,46 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD 
License
+; which accompanies this distribution.  The full text of the license may be 
found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Module Name:
+;
+;   InterlockedCompareExchange16.Asm
+;
+; Abstract:
+;
+;   InterlockedCompareExchange16 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+    .486
+    .model  flat,C
+    .code
+
+;------------------------------------------------------------------------------
+; UINT16
+; EFIAPI
+; InternalSyncCompareExchange16 (
+;   IN      UINT16                    *Value,
+;   IN      UINT16                    CompareValue,
+;   IN      UINT16                    ExchangeValue
+;   );
+;------------------------------------------------------------------------------
+InternalSyncCompareExchange16   PROC
+    mov     ecx, [esp + 4]
+    mov     ax, [esp + 8]
+    mov     dx, [esp + 12]
+    lock    cmpxchg [ecx], dx
+    ret
+InternalSyncCompareExchange16   ENDP
+
+    END

Added: 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
===================================================================
--- 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
                                (rev 0)
+++ 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c
        2015-02-28 20:31:54 UTC (rev 16966)
@@ -0,0 +1,51 @@
+/** @file
+  InterlockedCompareExchange16 function
+
+  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD 
License
+  which accompanies this distribution.  The full text of the license may be 
found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+
+
+/**
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer
+  specified by Value.  If Value is equal to CompareValue, then Value is set to
+  ExchangeValue and CompareValue is returned.  If Value is not equal to 
CompareValue,
+  then Value is returned.  The compare exchange operation must be performed 
using
+  MP safe mechanisms.
+
+  @param  Value         A pointer to the 16-bit value for the compare exchange
+                        operation.
+  @param  CompareValue  16-bit value used in compare operation.
+  @param  ExchangeValue 16-bit value used in exchange operation.
+
+  @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+  IN      UINT16                    *Value,
+  IN      UINT16                    CompareValue,
+  IN      UINT16                    ExchangeValue
+  )
+{
+  _asm {
+    mov     ecx, Value
+    mov     ax, CompareValue
+    mov     dx, ExchangeValue
+    lock    cmpxchg [ecx], dx
+  }
+}
+

Added: 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
===================================================================
--- 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
                         (rev 0)
+++ 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s
 2015-02-28 20:31:54 UTC (rev 16966)
@@ -0,0 +1,30 @@
+/// @file
+///   Contains an implementation of InterlockedCompareExchange16 on Itanium-
+///   based architecture.
+///
+/// Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+/// Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
+/// This program and the accompanying materials
+/// are licensed and made available under the terms and conditions of the BSD 
License
+/// which accompanies this distribution.  The full text of the license may be 
found at
+/// http://opensource.org/licenses/bsd-license.php.
+///
+/// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+/// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
IMPLIED.
+///
+/// Module Name:  InterlockedCompareExchange16.s
+///
+///
+
+.auto
+.text
+
+.proc   InternalSyncCompareExchange16
+.type   InternalSyncCompareExchange16, @function
+InternalSyncCompareExchange16::
+        zxt2                r33 = r33
+        mov                 ar.ccv = r33
+        cmpxchg2.rel        r8  = [r32], r34
+        mf
+        br.ret.sptk.many    b0
+.endp   InternalSyncCompareExchange16

Modified: trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Synchronization.c
===================================================================
--- trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Synchronization.c  
2015-02-28 20:31:40 UTC (rev 16965)
+++ trunk/edk2/MdePkg/Library/BaseSynchronizationLib/Synchronization.c  
2015-02-28 20:31:54 UTC (rev 16966)
@@ -277,6 +277,37 @@
 }
 
 /**
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer
+  specified by Value.  If Value is equal to CompareValue, then Value is set to
+  ExchangeValue and CompareValue is returned.  If Value is not equal to 
CompareValue,
+  then Value is returned.  The compare exchange operation must be performed 
using
+  MP safe mechanisms.
+
+  If Value is NULL, then ASSERT().
+
+  @param  Value         A pointer to the 16-bit value for the compare exchange
+                        operation.
+  @param  CompareValue  16-bit value used in compare operation.
+  @param  ExchangeValue 16-bit value used in exchange operation.
+
+  @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InterlockedCompareExchange16 (
+  IN OUT  UINT16                    *Value,
+  IN      UINT16                    CompareValue,
+  IN      UINT16                    ExchangeValue
+  )
+{
+  ASSERT (Value != NULL);
+  return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
+}
+
+/**
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.
 
   Performs an atomic compare exchange operation on the 32-bit unsigned integer

Modified: trunk/edk2/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c
===================================================================
--- trunk/edk2/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c       
2015-02-28 20:31:40 UTC (rev 16965)
+++ trunk/edk2/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c       
2015-02-28 20:31:54 UTC (rev 16966)
@@ -293,6 +293,37 @@
 }
 
 /**
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer
+  specified by Value.  If Value is equal to CompareValue, then Value is set to
+  ExchangeValue and CompareValue is returned.  If Value is not equal to 
CompareValue,
+  then Value is returned.  The compare exchange operation must be performed 
using
+  MP safe mechanisms.
+
+  If Value is NULL, then ASSERT().
+
+  @param  Value         A pointer to the 16-bit value for the compare exchange
+                        operation.
+  @param  CompareValue  A 16-bit value used in compare operation.
+  @param  ExchangeValue A 16-bit value used in exchange operation.
+
+  @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InterlockedCompareExchange16 (
+  IN OUT  UINT16                    *Value,
+  IN      UINT16                    CompareValue,
+  IN      UINT16                    ExchangeValue
+  )
+{
+  ASSERT (Value != NULL);
+  return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
+}
+
+/**
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.
 
   Performs an atomic compare exchange operation on the 32-bit unsigned integer

Modified: trunk/edk2/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c
===================================================================
--- trunk/edk2/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c       
2015-02-28 20:31:40 UTC (rev 16965)
+++ trunk/edk2/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c       
2015-02-28 20:31:54 UTC (rev 16966)
@@ -295,6 +295,37 @@
 }
 
 /**
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer
+  specified by Value.  If Value is equal to CompareValue, then Value is set to
+  ExchangeValue and CompareValue is returned.  If Value is not equal to 
CompareValue,
+  then Value is returned.  The compare exchange operation must be performed 
using
+  MP safe mechanisms.
+
+  If Value is NULL, then ASSERT().
+
+  @param  Value         A pointer to the 16-bit value for the compare exchange
+                        operation.
+  @param  CompareValue  A 16-bit value used in a compare operation.
+  @param  ExchangeValue A 16-bit value used in an exchange operation.
+
+  @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InterlockedCompareExchange16 (
+  IN OUT  UINT16                    *Value,
+  IN      UINT16                    CompareValue,
+  IN      UINT16                    ExchangeValue
+  )
+{
+  ASSERT (Value != NULL);
+  return InternalSyncCompareExchange16 (Value, CompareValue, ExchangeValue);
+}
+
+/**
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.
 
   Performs an atomic compare exchange operation on the 32-bit unsigned integer

Modified: trunk/edk2/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c
===================================================================
--- trunk/edk2/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c    
2015-02-28 20:31:40 UTC (rev 16965)
+++ trunk/edk2/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c    
2015-02-28 20:31:54 UTC (rev 16966)
@@ -89,6 +89,50 @@
 
 
 /**
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer
+  specified by Value.  If Value is equal to CompareValue, then Value is set to
+  ExchangeValue and CompareValue is returned.  If Value is not equal to 
CompareValue,
+  then Value is returned.  The compare exchange operation must be performed 
using
+  MP safe mechanisms.
+
+
+  @param  Value         A pointer to the 16-bit value for the compare exchange
+                        operation.
+  @param  CompareValue  16-bit value used in compare operation.
+  @param  ExchangeValue 16-bit value used in exchange operation.
+
+  @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+  IN OUT volatile  UINT16           *Value,
+  IN      UINT16                    CompareValue,
+  IN      UINT16                    ExchangeValue
+  )
+{
+
+
+  __asm__ __volatile__ (
+    "lock                 \n\t"
+    "cmpxchgw    %3, %1       "
+    : "=a" (CompareValue),
+      "=m" (*Value)
+    : "a"  (CompareValue),
+      "r"  (ExchangeValue),
+      "m"  (*Value)
+    : "memory",
+      "cc"
+    );
+
+  return CompareValue;
+}
+
+
+/**
   Performs an atomic compare exchange operation on a 32-bit unsigned integer.
 
   Performs an atomic compare exchange operation on the 32-bit unsigned integer

Added: 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
===================================================================
--- 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
                               (rev 0)
+++ 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm
       2015-02-28 20:31:54 UTC (rev 16966)
@@ -0,0 +1,42 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
+; This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD 
License
+; which accompanies this distribution.  The full text of the license may be 
found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Module Name:
+;
+;   InterlockedCompareExchange16.Asm
+;
+; Abstract:
+;
+;   InterlockedCompareExchange16 function
+;
+; Notes:
+;
+;------------------------------------------------------------------------------
+
+    .code
+
+;------------------------------------------------------------------------------
+; UINT16
+; EFIAPI
+; InterlockedCompareExchange16 (
+;   IN      UINT16                    *Value,
+;   IN      UINT16                    CompareValue,
+;   IN      UINT16                    ExchangeValue
+;   );
+;------------------------------------------------------------------------------
+InternalSyncCompareExchange16   PROC
+    mov     ax, dx
+    lock    cmpxchg [rcx], r8w
+    ret
+InternalSyncCompareExchange16   ENDP
+
+    END

Added: 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
===================================================================
--- 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
                         (rev 0)
+++ 
trunk/edk2/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c
 2015-02-28 20:31:54 UTC (rev 16966)
@@ -0,0 +1,54 @@
+/** @file
+  InterlockedCompareExchange16 function
+
+  Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2015, Linaro Ltd. All rights reserved.<BR>
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD 
License
+  which accompanies this distribution.  The full text of the license may be 
found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+/**
+  Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics.
+**/
+
+__int16 _InterlockedCompareExchange16(
+   __int16 volatile * Destination,
+   __int16 Exchange,
+   __int16 Comperand
+);
+
+#pragma intrinsic(_InterlockedCompareExchange16)
+
+/**
+  Performs an atomic compare exchange operation on a 16-bit unsigned integer.
+
+  Performs an atomic compare exchange operation on the 16-bit unsigned integer 
specified
+  by Value.  If Value is equal to CompareValue, then Value is set to 
ExchangeValue and
+  CompareValue is returned.  If Value is not equal to CompareValue, then Value 
is returned.
+  The compare exchange operation must be performed using MP safe mechanisms.
+
+  @param  Value         A pointer to the 16-bit value for the compare exchange
+                        operation.
+  @param  CompareValue  16-bit value used in compare operation.
+  @param  ExchangeValue 16-bit value used in exchange operation.
+
+  @return The original *Value before exchange.
+
+**/
+UINT16
+EFIAPI
+InternalSyncCompareExchange16 (
+  IN      UINT16                    *Value,
+  IN      UINT16                    CompareValue,
+  IN      UINT16                    ExchangeValue
+  )
+{
+  return _InterlockedCompareExchange16 (Value, ExchangeValue, CompareValue);
+}
+


------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to