public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Gao, Liming" <liming.gao@intel.com>
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
	"leif.lindholm@linaro.org" <leif.lindholm@linaro.org>
Cc: "Kinney, Michael D" <michael.d.kinney@intel.com>
Subject: Re: [PATCH v2 1/3] MdePkg/BaseMemoryLib: widen aligned accesses to 32 or 64 bits
Date: Wed, 7 Sep 2016 03:03:11 +0000	[thread overview]
Message-ID: <4A89E2EF3DFEDB4C8BFDE51014F606A14B3E2F42@shsmsx102.ccr.corp.intel.com> (raw)
In-Reply-To: <1473171813-24595-2-git-send-email-ard.biesheuvel@linaro.org>

Ard:
In InternalMemSetMem, Value64 = (((UINT64)Value32) << 32) | Value32; may cause the below link error with VS IA32 build. It (<<) should be replaced by BaseLib LShift API

BaseMemoryLib.lib(SetMem.obj) : error LNK2001: unresolved external symbol __allshl

Thanks
Liming
> -----Original Message-----
> From: Ard Biesheuvel [mailto:ard.biesheuvel@linaro.org]
> Sent: Tuesday, September 06, 2016 10:24 PM
> To: edk2-devel@lists.01.org; leif.lindholm@linaro.org; Gao, Liming
> <liming.gao@intel.com>
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Ard Biesheuvel
> <ard.biesheuvel@linaro.org>
> Subject: [PATCH v2 1/3] MdePkg/BaseMemoryLib: widen aligned accesses to
> 32 or 64 bits
> 
> Since the default BaseMemoryLib should be callable from any context,
> including ones where unaligned accesses are not allowed, it implements
> InternalCopyMem() and InternalSetMem() using byte accesses only.
> However, especially in a context where the MMU is off, such narrow
> accesses may be disproportionately costly, and so if the size and
> alignment of the access allow it, use 32-bit or even 64-bit loads and
> stores (the latter may be beneficial even on a 32-bit architectures like
> ARM, which has load pair/store pair instructions)
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
>  MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf |   2 +-
>  MdePkg/Library/BaseMemoryLib/CopyMem.c         | 112
> ++++++++++++++++++--
>  MdePkg/Library/BaseMemoryLib/SetMem.c          |  40 ++++++-
>  3 files changed, 140 insertions(+), 14 deletions(-)
> 
> diff --git a/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
> b/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
> index 6d906e93faf3..358eeed4f449 100644
> --- a/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
> +++ b/MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
> @@ -26,7 +26,7 @@ [Defines]
> 
> 
>  #
> -#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
> +#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC ARM AARCH64
>  #
> 
>  [Sources]
> diff --git a/MdePkg/Library/BaseMemoryLib/CopyMem.c
> b/MdePkg/Library/BaseMemoryLib/CopyMem.c
> index 37f03660df5f..6f4fd900df5d 100644
> --- a/MdePkg/Library/BaseMemoryLib/CopyMem.c
> +++ b/MdePkg/Library/BaseMemoryLib/CopyMem.c
> @@ -4,6 +4,9 @@
>    particular platform easily if an optimized version is desired.
> 
>    Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.<BR>
> +  Copyright (c) 2016, 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
> @@ -44,18 +47,107 @@ InternalMemCopyMem (
>    //
>    volatile UINT8                    *Destination8;
>    CONST UINT8                       *Source8;
> +  volatile UINT32                   *Destination32;
> +  CONST UINT32                      *Source32;
> +  volatile UINT64                   *Destination64;
> +  CONST UINT64                      *Source64;
> +  UINTN                             Alignment;
> +
> +  if ((((UINTN)DestinationBuffer & 0x7) == 0) && (((UINTN)SourceBuffer &
> 0x7) == 0) && (Length >= 8)) {
> +    if (SourceBuffer > DestinationBuffer) {
> +      Destination64 = (UINT64*)DestinationBuffer;
> +      Source64 = (CONST UINT64*)SourceBuffer;
> +      while (Length >= 8) {
> +        *(Destination64++) = *(Source64++);
> +        Length -= 8;
> +      }
> +
> +      // Finish if there are still some bytes to copy
> +      Destination8 = (UINT8*)Destination64;
> +      Source8 = (CONST UINT8*)Source64;
> +      while (Length-- != 0) {
> +        *(Destination8++) = *(Source8++);
> +      }
> +    } else if (SourceBuffer < DestinationBuffer) {
> +      Destination64 = (UINT64*)((UINTN)DestinationBuffer + Length);
> +      Source64 = (CONST UINT64*)((UINTN)SourceBuffer + Length);
> +
> +      // Destination64 and Source64 were aligned on a 64-bit boundary
> +      // but if length is not a multiple of 8 bytes then they won't be
> +      // anymore.
> +
> +      Alignment = Length & 0x7;
> +      if (Alignment != 0) {
> +        Destination8 = (UINT8*)Destination64;
> +        Source8 = (CONST UINT8*)Source64;
> +
> +        while (Alignment-- != 0) {
> +          *(--Destination8) = *(--Source8);
> +          --Length;
> +        }
> +        Destination64 = (UINT64*)Destination8;
> +        Source64 = (CONST UINT64*)Source8;
> +      }
> +
> +      while (Length > 0) {
> +        *(--Destination64) = *(--Source64);
> +        Length -= 8;
> +      }
> +    }
> +  } else if ((((UINTN)DestinationBuffer & 0x3) == 0) &&
> (((UINTN)SourceBuffer & 0x3) == 0) && (Length >= 4)) {
> +    if (SourceBuffer > DestinationBuffer) {
> +      Destination32 = (UINT32*)DestinationBuffer;
> +      Source32 = (CONST UINT32*)SourceBuffer;
> +      while (Length >= 4) {
> +        *(Destination32++) = *(Source32++);
> +        Length -= 4;
> +      }
> +
> +      // Finish if there are still some bytes to copy
> +      Destination8 = (UINT8*)Destination32;
> +      Source8 = (CONST UINT8*)Source32;
> +      while (Length-- != 0) {
> +        *(Destination8++) = *(Source8++);
> +      }
> +    } else if (SourceBuffer < DestinationBuffer) {
> +      Destination32 = (UINT32*)((UINTN)DestinationBuffer + Length);
> +      Source32 = (CONST UINT32*)((UINTN)SourceBuffer + Length);
> +
> +      // Destination32 and Source32 were aligned on a 32-bit boundary
> +      // but if length is not a multiple of 4 bytes then they won't be
> +      // anymore.
> +
> +      Alignment = Length & 0x3;
> +      if (Alignment != 0) {
> +        Destination8 = (UINT8*)Destination32;
> +        Source8 = (CONST UINT8*)Source32;
> +
> +        while (Alignment-- != 0) {
> +          *(--Destination8) = *(--Source8);
> +          --Length;
> +        }
> +        Destination32 = (UINT32*)Destination8;
> +        Source32 = (CONST UINT32*)Source8;
> +      }
> 
> -  if (SourceBuffer > DestinationBuffer) {
> -    Destination8 = (UINT8*)DestinationBuffer;
> -    Source8 = (CONST UINT8*)SourceBuffer;
> -    while (Length-- != 0) {
> -      *(Destination8++) = *(Source8++);
> +      while (Length > 0) {
> +        *(--Destination32) = *(--Source32);
> +        Length -= 4;
> +      }
>      }
> -  } else if (SourceBuffer < DestinationBuffer) {
> -    Destination8 = (UINT8*)DestinationBuffer + Length;
> -    Source8 = (CONST UINT8*)SourceBuffer + Length;
> -    while (Length-- != 0) {
> -      *(--Destination8) = *(--Source8);
> +  } else {
> +    if (SourceBuffer > DestinationBuffer) {
> +      Destination8 = (UINT8*)DestinationBuffer;
> +      Source8 = (CONST UINT8*)SourceBuffer;
> +      while (Length-- != 0) {
> +        *(Destination8++) = *(Source8++);
> +      }
> +    } else if (SourceBuffer < DestinationBuffer) {
> +      Destination8 = (UINT8*)DestinationBuffer + Length;
> +      Source8 = (CONST UINT8*)SourceBuffer + Length;
> +      while (Length-- != 0) {
> +        *(--Destination8) = *(--Source8);
> +      }
>      }
>    }
>    return DestinationBuffer;
> diff --git a/MdePkg/Library/BaseMemoryLib/SetMem.c
> b/MdePkg/Library/BaseMemoryLib/SetMem.c
> index 5e74085c56f0..932c61e959f3 100644
> --- a/MdePkg/Library/BaseMemoryLib/SetMem.c
> +++ b/MdePkg/Library/BaseMemoryLib/SetMem.c
> @@ -5,6 +5,9 @@
>    is desired.
> 
>    Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2012 - 2013, ARM Ltd. All rights reserved.<BR>
> +  Copyright (c) 2016, 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
> @@ -43,11 +46,42 @@ InternalMemSetMem (
>    // volatile to prevent the optimizer from replacing this function with
>    // the intrinsic memset()
>    //
> -  volatile UINT8                    *Pointer;
> +  volatile UINT8                    *Pointer8;
> +  volatile UINT32                   *Pointer32;
> +  volatile UINT64                   *Pointer64;
> +  UINT32                            Value32;
> +  UINT64                            Value64;
> +
> +  if ((((UINTN)Buffer & 0x7) == 0) && (Length >= 8)) {
> +    // Generate the 64bit value
> +    Value32 = (Value << 24) | (Value << 16) | (Value << 8) | Value;
> +    Value64 = (((UINT64)Value32) << 32) | Value32;
> +
> +    Pointer64 = (UINT64*)Buffer;
> +    while (Length >= 8) {
> +      *(Pointer64++) = Value64;
> +      Length -= 8;
> +    }
> 
> -  Pointer = (UINT8*)Buffer;
> +    // Finish with bytes if needed
> +    Pointer8 = (UINT8*)Pointer64;
> +  } else if ((((UINTN)Buffer & 0x3) == 0) && (Length >= 4)) {
> +    // Generate the 32bit value
> +    Value32 = (Value << 24) | (Value << 16) | (Value << 8) | Value;
> +
> +    Pointer32 = (UINT32*)Buffer;
> +    while (Length >= 4) {
> +      *(Pointer32++) = Value32;
> +      Length -= 4;
> +    }
> +
> +    // Finish with bytes if needed
> +    Pointer8 = (UINT8*)Pointer32;
> +  } else {
> +    Pointer8 = (UINT8*)Buffer;
> +  }
>    while (Length-- > 0) {
> -    *(Pointer++) = Value;
> +    *(Pointer8++) = Value;
>    }
>    return Buffer;
>  }
> --
> 2.7.4



  reply	other threads:[~2016-09-07  3:03 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-06 14:23 [PATCH v2 0/3] MdePkg: add ARM/AARCH64 support to BaseMemoryLib Ard Biesheuvel
2016-09-06 14:23 ` [PATCH v2 1/3] MdePkg/BaseMemoryLib: widen aligned accesses to 32 or 64 bits Ard Biesheuvel
2016-09-07  3:03   ` Gao, Liming [this message]
2016-09-07  6:50     ` Ard Biesheuvel
2016-09-06 14:23 ` [PATCH v2 2/3] MdePkg/BaseMemoryLibOptDxe: add accelerated ARM routines Ard Biesheuvel
2016-09-06 14:23 ` [PATCH v2 3/3] MdePkg/BaseMemoryLibOptDxe: add accelerated AARCH64 routines Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4A89E2EF3DFEDB4C8BFDE51014F606A14B3E2F42@shsmsx102.ccr.corp.intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox