Home | History | Annotate | Download | only in Ia32
      1 #------------------------------------------------------------------------------
      2 #
      3 # Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
      4 # This program and the accompanying materials
      5 # are licensed and made available under the terms and conditions of the BSD License
      6 # which accompanies this distribution.  The full text of the license may be found at
      7 # http://opensource.org/licenses/bsd-license.php.
      8 #
      9 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 #
     12 # Module Name:
     13 #
     14 #   CopyMem.S
     15 #
     16 # Abstract:
     17 #
     18 #   CopyMem function
     19 #
     20 # Notes:
     21 #
     22 #------------------------------------------------------------------------------
     23 
     24 ASM_GLOBAL ASM_PFX(InternalMemCopyMem)
     25 
     26 #------------------------------------------------------------------------------
     27 #  VOID *
     28 #  EFIAPI
     29 #  InternalMemCopyMem (
     30 #    IN VOID   *Destination,
     31 #    IN VOID   *Source,
     32 #    IN UINTN  Count
     33 #    );
     34 #------------------------------------------------------------------------------
     35 ASM_PFX(InternalMemCopyMem):
     36     push    %esi
     37     push    %edi
     38     movl    16(%esp), %esi              # esi <- Source
     39     movl    12(%esp), %edi              # edi <- Destination
     40     movl    20(%esp), %edx              # edx <- Count
     41     leal    -1(%esi,%edx,), %eax        # eax <- End of Source
     42     cmpl    %edi, %esi
     43     jae     L0
     44     cmpl    %edi, %eax                  # Overlapped?
     45     jae     L_CopyBackward               # Copy backward if overlapped
     46 L0:
     47     xorl    %ecx, %ecx
     48     subl    %edi, %ecx
     49     andl    $15, %ecx                   # ecx + edi aligns on 16-byte boundary
     50     jz      L1
     51     cmpl    %edx, %ecx
     52     cmova   %edx, %ecx
     53     subl    %ecx, %edx                  # edx <- remaining bytes to copy
     54     rep
     55     movsb
     56 L1:
     57     movl    %edx, %ecx
     58     andl    $15, %edx
     59     shrl    $4, %ecx                    # ecx <- # of DQwords to copy
     60     jz      L_CopyBytes
     61     addl    $-16, %esp
     62     movdqu  %xmm0, (%esp)
     63 L2:
     64     movdqu  (%esi), %xmm0
     65     movntdq %xmm0, (%edi)
     66     addl    $16, %esi
     67     addl    $16, %edi
     68     loop    L2
     69     mfence
     70     movdqu  (%esp),%xmm0
     71     addl    $16, %esp                   # stack cleanup
     72     jmp     L_CopyBytes
     73 L_CopyBackward:
     74     movl    %eax, %esi                  # esi <- Last byte in Source
     75     leal    -1(%edi,%edx,), %edi        # edi <- Last byte in Destination
     76     std
     77 L_CopyBytes:
     78     movl    %edx, %ecx
     79     rep
     80     movsb
     81     cld
     82     movl    12(%esp), %eax              # eax <- Destination as return value
     83     pop     %edi
     84     pop     %esi
     85     ret
     86