|
[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 |