[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit compare-exchange
On 25 February 2015 at 21:56, Kinney, Michael D <michael.d.kinney@xxxxxxxxx> wrote: > Ard Biesheuvel, > > Thank you for providing the implementation of this new function for all > supported CPU architectures. The one for IPF looks correct and passes builds. Good. Thanks for confirming that. > However, I am seeing some build breaks and some issues with the IA32 and X64 > versions. The following changes are required to your patch to build with > VS20xx compilers and for the code generated by asm/Inline asm to match code > generated by VS20xx compiler intrinsics. OK, I will update the patch with your suggested changes. > I have not built and disassembled GCC yet, but I think GCC inline asm should > generate the expected 16-bit register load operations that have been > addressed here. > This is what I get for X64 and IA32, respectively: Disassembly of section .text.InternalSyncCompareExchange16: 0000000000000000 <InternalSyncCompareExchange16>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 48 89 4d 10 mov %rcx,0x10(%rbp) 8: 89 d0 mov %edx,%eax a: 44 89 c2 mov %r8d,%edx d: 66 89 45 18 mov %ax,0x18(%rbp) 11: 66 89 55 20 mov %dx,0x20(%rbp) 15: 4c 8b 45 10 mov 0x10(%rbp),%r8 19: 0f b7 45 18 movzwl 0x18(%rbp),%eax 1d: 0f b7 55 20 movzwl 0x20(%rbp),%edx 21: 48 8b 4d 10 mov 0x10(%rbp),%rcx 25: f0 66 41 0f b1 10 lock cmpxchg %dx,(%r8) 2b: 66 89 45 18 mov %ax,0x18(%rbp) 2f: 0f b7 45 18 movzwl 0x18(%rbp),%eax 33: 5d pop %rbp 34: c3 retq Disassembly of section .text.InternalSyncCompareExchange16: 00000000 <InternalSyncCompareExchange16>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 8b 45 0c mov 0xc(%ebp),%eax 6: 8b 55 10 mov 0x10(%ebp),%edx 9: 8b 4d 08 mov 0x8(%ebp),%ecx c: f0 66 0f b1 11 lock cmpxchg %dx,(%ecx) 11: 5d pop %ebp 12: c3 ret The latter looks equivalent to me, but perhaps you could confirm that the former does the right thing? Thanks a lot for taking the time, Ard. > --- Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm > Mon Jan 19 14:26:36 1970 > +++ Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm > Mon Jan 19 14:26:36 1970 > @@ -37,8 +37,8 @@ > > ;------------------------------------------------------------------------------ > InternalSyncCompareExchange16 PROC > mov ecx, [esp + 4] > - mov eax, [esp + 8] > - mov edx, [esp + 12] > + mov ax, [esp + 8] > + mov dx, [esp + 12] > lock cmpxchg [ecx], dx > ret > InternalSyncCompareExchange16 ENDP > --- Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c Mon > Jan 19 14:26:36 1970 > +++ Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c Mon > Jan 19 14:26:36 1970 > @@ -43,8 +43,8 @@ > { > _asm { > mov ecx, Value > - mov eax, CompareValue > - mov edx, ExchangeValue > + mov ax, CompareValue > + mov dx, ExchangeValue > lock cmpxchg [ecx], dx > } > } > --- Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm Mon > Jan 19 14:26:36 1970 > +++ Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm Mon > Jan 19 14:26:36 1970 > @@ -34,7 +34,7 @@ > ; ); > > ;------------------------------------------------------------------------------ > InternalSyncCompareExchange16 PROC > - mov eax, edx > + mov ax, dx > lock cmpxchg [rcx], r8w > ret > InternalSyncCompareExchange16 ENDP > > Best regards, > > Mike > > -----Original Message----- > From: Ard Biesheuvel [mailto:ard.biesheuvel@xxxxxxxxxx] > Sent: Thursday, February 12, 2015 3:19 AM > To: edk2-devel@xxxxxxxxxxxxxxxxxxxxx; olivier.martin@xxxxxxx; > lersek@xxxxxxxxxx; roy.franz@xxxxxxxxxx; leif.lindholm@xxxxxxxxxx; > stefano.stabellini@xxxxxxxxxxxxx; ian.campbell@xxxxxxxxxx; > anthony.perard@xxxxxxxxxx; xen-devel@xxxxxxxxxxxxx; julien.grall@xxxxxxxxxx; > Justen, Jordan L; Kinney, Michael D; Tian, Feng > Cc: Ard Biesheuvel > Subject: [PATCH v4 14/29] MdePkg/BaseSynchronizationLib: implement 16-bit > compare-exchange > > 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 <olivier.martin@xxxxxxx> > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx> > --- > MdePkg/Include/Library/SynchronizationLib.h > | 26 ++++++++++++++++++++++++++ > MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S > | 44 ++++++++++++++++++++++++++++++++++++++++++++ > MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S > | 44 ++++++++++++++++++++++++++++++++++++++++++++ > MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm > | 44 ++++++++++++++++++++++++++++++++++++++++++++ > MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf > | 5 +++++ > MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h > | 26 ++++++++++++++++++++++++++ > MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c > | 31 +++++++++++++++++++++++++++++++ > MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c > | 42 ++++++++++++++++++++++++++++++++++++++++++ > MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm > | 46 ++++++++++++++++++++++++++++++++++++++++++++++ > MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c > | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ > MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s > | 30 ++++++++++++++++++++++++++++++ > MdePkg/Library/BaseSynchronizationLib/Synchronization.c > | 31 +++++++++++++++++++++++++++++++ > MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c > | 31 +++++++++++++++++++++++++++++++ > MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c > | 31 +++++++++++++++++++++++++++++++ > MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c > | 44 ++++++++++++++++++++++++++++++++++++++++++++ > MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm > | 42 ++++++++++++++++++++++++++++++++++++++++++ > MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c > | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 17 files changed, 622 insertions(+) > > diff --git a/MdePkg/Include/Library/SynchronizationLib.h > b/MdePkg/Include/Library/SynchronizationLib.h > index f97569739914..7b97683ca0af 100644 > --- a/MdePkg/Include/Library/SynchronizationLib.h > +++ b/MdePkg/Include/Library/SynchronizationLib.h > @@ -184,6 +184,32 @@ InterlockedDecrement ( > > > /** > + 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 > diff --git a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S > b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S > index 601b00495f26..ecb87fc12755 100644 > --- a/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S > +++ b/MdePkg/Library/BaseSynchronizationLib/AArch64/Synchronization.S > @@ -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 > diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S > b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S > index 0128f8f016bd..d699eb40d2a2 100644 > --- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S > +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.S > @@ -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 > diff --git a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm > b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm > index f9f80737774a..dbc599114093 100644 > --- a/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm > +++ b/MdePkg/Library/BaseSynchronizationLib/Arm/Synchronization.asm > @@ -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 > diff --git a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf > b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf > index 5e3b4e6b9bf2..bd1bec3fb5e7 100755 > --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf > +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf > @@ -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 > diff --git > a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h > b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h > index e42824c75d12..76f702324156 100644 > --- a/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h > +++ b/MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLibInternals.h > @@ -63,6 +63,32 @@ 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 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 > diff --git a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c > b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c > index 9c34b9f128ed..a57860203b12 100644 > --- a/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c > +++ b/MdePkg/Library/BaseSynchronizationLib/Ebc/Synchronization.c > @@ -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. > > diff --git a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c > b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c > index b5a7827fc0e8..bd81aad6c243 100644 > --- a/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c > +++ b/MdePkg/Library/BaseSynchronizationLib/Ia32/GccInline.c > @@ -88,6 +88,48 @@ 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 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 > diff --git > a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm > b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm > new file mode 100644 > index 000000000000..f8705042661d > --- /dev/null > +++ > b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.asm > @@ -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 eax, [esp + 8] > + mov edx, [esp + 12] > + lock cmpxchg [ecx], dx > + ret > +InternalSyncCompareExchange16 ENDP > + > + END > diff --git > a/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c > b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c > new file mode 100644 > index 000000000000..3d06dd9baa63 > --- /dev/null > +++ > b/MdePkg/Library/BaseSynchronizationLib/Ia32/InterlockedCompareExchange16.c > @@ -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 eax, CompareValue > + mov edx, ExchangeValue > + lock cmpxchg [ecx], dx > + } > +} > + > diff --git > a/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s > b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s > new file mode 100644 > index 000000000000..1e56942a98cb > --- /dev/null > +++ b/MdePkg/Library/BaseSynchronizationLib/Ipf/InterlockedCompareExchange16.s > @@ -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 > diff --git a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c > b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c > index 0eea40ba1622..4218a265a0ec 100644 > --- a/MdePkg/Library/BaseSynchronizationLib/Synchronization.c > +++ b/MdePkg/Library/BaseSynchronizationLib/Synchronization.c > @@ -277,6 +277,37 @@ InterlockedDecrement ( > } > > /** > + 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 > diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c > b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c > index badf73c1a6ce..587f5a771c35 100644 > --- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c > +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationGcc.c > @@ -293,6 +293,37 @@ InterlockedDecrement ( > } > > /** > + 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 > diff --git a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c > b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c > index 9b20236acfa6..ca21f5dccee5 100644 > --- a/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c > +++ b/MdePkg/Library/BaseSynchronizationLib/SynchronizationMsc.c > @@ -295,6 +295,37 @@ InterlockedDecrement ( > } > > /** > + 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 > diff --git a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c > b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c > index ceb80aed94f8..6347073fee51 100644 > --- a/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c > +++ b/MdePkg/Library/BaseSynchronizationLib/X64/GccInline.c > @@ -89,6 +89,50 @@ 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 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 > diff --git > a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm > b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm > new file mode 100644 > index 000000000000..8fe2aae1a28b > --- /dev/null > +++ > b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.asm > @@ -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 eax, edx > + lock cmpxchg [rcx], r8w > + ret > +InternalSyncCompareExchange16 ENDP > + > + END > diff --git > a/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c > b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c > new file mode 100644 > index 000000000000..76aa6fbc0e81 > --- /dev/null > +++ b/MdePkg/Library/BaseSynchronizationLib/X64/InterlockedCompareExchange16.c > @@ -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); > +} > + > -- > 1.8.3.2 > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |