| #------------------------------------------------------------------------------ | |
| # | |
| # CopyMem() worker for ARM | |
| # | |
| # This file started out as C code that did 64 bit moves if the buffer was | |
| # 32-bit aligned, else it does a byte copy. It also does a byte copy for | |
| # any trailing bytes. Update using VSTM/SLDM to do 128 byte copies. | |
| # | |
| # Copyright (c) 2008 - 2010, Apple Inc. 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. | |
| # | |
| #------------------------------------------------------------------------------ | |
| /** | |
| Copy Length bytes from Source to Destination. Overlap is OK. | |
| This implementation | |
| @param Destination Target of copy | |
| @param Source Place to copy from | |
| @param Length Number of bytes to copy | |
| @return Destination | |
| VOID * | |
| EFIAPI | |
| InternalMemCopyMem ( | |
| OUT VOID *DestinationBuffer, | |
| IN CONST VOID *SourceBuffer, | |
| IN UINTN Length | |
| ) | |
| **/ | |
| .text | |
| .align 2 | |
| GCC_ASM_EXPORT(InternalMemCopyMem) | |
| ASM_PFX(InternalMemCopyMem): | |
| stmfd sp!, {r4, r9, lr} | |
| tst r0, #3 | |
| mov r4, r0 | |
| mov r9, r0 | |
| mov ip, r2 | |
| mov lr, r1 | |
| movne r0, #0 | |
| bne L4 | |
| tst r1, #3 | |
| movne r3, #0 | |
| moveq r3, #1 | |
| cmp r2, #127 | |
| movls r0, #0 | |
| andhi r0, r3, #1 | |
| L4: | |
| cmp r4, r1 | |
| bcc L26 | |
| bls L7 | |
| rsb r3, r1, r4 | |
| cmp ip, r3 | |
| bcc L26 | |
| cmp ip, #0 | |
| beq L7 | |
| add r9, r4, ip | |
| add lr, ip, r1 | |
| b L16 | |
| L29: | |
| sub ip, ip, #8 | |
| cmp ip, #7 | |
| ldrd r2, [lr, #-8]! | |
| movls r0, #0 | |
| cmp ip, #0 | |
| strd r2, [r9, #-8]! | |
| beq L7 | |
| L16: | |
| cmp r0, #0 | |
| bne L29 | |
| sub r3, lr, #1 | |
| sub ip, ip, #1 | |
| ldrb r3, [r3, #0] | |
| sub r2, r9, #1 | |
| cmp ip, #0 | |
| sub r9, r9, #1 | |
| sub lr, lr, #1 | |
| strb r3, [r2, #0] | |
| bne L16 | |
| b L7 | |
| L11: | |
| ldrb r3, [lr], #1 | |
| sub ip, ip, #1 | |
| strb r3, [r9], #1 | |
| L26: | |
| cmp ip, #0 | |
| beq L7 | |
| L30: | |
| cmp r0, #0 | |
| beq L11 | |
| sub ip, ip, #128 // 32 | |
| cmp ip, #127 // 31 | |
| vldm lr!, {d0-d15} | |
| movls r0, #0 | |
| cmp ip, #0 | |
| vstm r9!, {d0-d15} | |
| bne L30 | |
| L7: | |
| dsb | |
| mov r0, r4 | |
| ldmfd sp!, {r4, r9, pc} | |