1;------------------------------------------------------------------------------ 2; 3; CopyMem() worker for ARM 4; 5; This file started out as C code that did 64 bit moves if the buffer was 6; 32-bit aligned, else it does a byte copy. It also does a byte copy for 7; any trailing bytes. It was updated to do 32-byte copies using stm/ldm. 8; 9; Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR> 10; This program and the accompanying materials 11; are licensed and made available under the terms and conditions of the BSD License 12; which accompanies this distribution. The full text of the license may be found at 13; http://opensource.org/licenses/bsd-license.php 14; 15; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 16; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 17; 18;------------------------------------------------------------------------------ 19 20/** 21 Copy Length bytes from Source to Destination. Overlap is OK. 22 23 This implementation 24 25 @param Destination Target of copy 26 @param Source Place to copy from 27 @param Length Number of bytes to copy 28 29 @return Destination 30 31 32VOID * 33EFIAPI 34InternalMemCopyMem ( 35 OUT VOID *DestinationBuffer, 36 IN CONST VOID *SourceBuffer, 37 IN UINTN Length 38 ) 39**/ 40 41 INCLUDE AsmMacroExport.inc 42 43 RVCT_ASM_EXPORT InternalMemCopyMem 44 stmfd sp!, {r4-r11, lr} 45 // Save the input parameters in extra registers (r11 = destination, r14 = source, r12 = length) 46 mov r11, r0 47 mov r10, r0 48 mov r12, r2 49 mov r14, r1 50 51memcopy_check_overlapped 52 cmp r11, r1 53 // If (dest < source) 54 bcc memcopy_check_optim_default 55 // If (dest <= source). But with the previous condition -> If (dest == source) 56 bls memcopy_end 57 58 // If (source + length < dest) 59 rsb r3, r1, r11 60 cmp r12, r3 61 bcc memcopy_check_optim_default 62 63 // If (length == 0) 64 cmp r12, #0 65 beq memcopy_end 66 67 b memcopy_check_optim_overlap 68 69memcopy_check_optim_default 70 // Check if we can use an optimized path ((length >= 32) && destination word-aligned && source word-aligned) for the memcopy (optimized path if r0 == 1) 71 tst r0, #0xF 72 movne r0, #0 73 bne memcopy_default 74 tst r1, #0xF 75 movne r3, #0 76 moveq r3, #1 77 cmp r2, #31 78 movls r0, #0 79 andhi r0, r3, #1 80 b memcopy_default 81 82memcopy_check_optim_overlap 83 // r10 = dest_end, r14 = source_end 84 add r10, r11, r12 85 add r14, r12, r1 86 87 // Are we in the optimized case ((length >= 32) && dest_end word-aligned && source_end word-aligned) 88 cmp r2, #31 89 movls r0, #0 90 movhi r0, #1 91 tst r10, #0xF 92 movne r0, #0 93 tst r14, #0xF 94 movne r0, #0 95 b memcopy_overlapped 96 97memcopy_overlapped_non_optim 98 // We read 1 byte from the end of the source buffer 99 sub r3, r14, #1 100 sub r12, r12, #1 101 ldrb r3, [r3, #0] 102 sub r2, r10, #1 103 cmp r12, #0 104 // We write 1 byte at the end of the dest buffer 105 sub r10, r10, #1 106 sub r14, r14, #1 107 strb r3, [r2, #0] 108 bne memcopy_overlapped_non_optim 109 b memcopy_end 110 111// r10 = dest_end, r14 = source_end 112memcopy_overlapped 113 // Are we in the optimized case ? 114 cmp r0, #0 115 beq memcopy_overlapped_non_optim 116 117 // Optimized Overlapped - Read 32 bytes 118 sub r14, r14, #32 119 sub r12, r12, #32 120 cmp r12, #31 121 ldmia r14, {r2-r9} 122 123 // If length is less than 32 then disable optim 124 movls r0, #0 125 126 cmp r12, #0 127 128 // Optimized Overlapped - Write 32 bytes 129 sub r10, r10, #32 130 stmia r10, {r2-r9} 131 132 // while (length != 0) 133 bne memcopy_overlapped 134 b memcopy_end 135 136memcopy_default_non_optim 137 // Byte copy 138 ldrb r3, [r14], #1 139 sub r12, r12, #1 140 strb r3, [r10], #1 141 142memcopy_default 143 cmp r12, #0 144 beq memcopy_end 145 146// r10 = dest, r14 = source 147memcopy_default_loop 148 cmp r0, #0 149 beq memcopy_default_non_optim 150 151 // Optimized memcopy - Read 32 Bytes 152 sub r12, r12, #32 153 cmp r12, #31 154 ldmia r14!, {r2-r9} 155 156 // If length is less than 32 then disable optim 157 movls r0, #0 158 159 cmp r12, #0 160 161 // Optimized memcopy - Write 32 Bytes 162 stmia r10!, {r2-r9} 163 164 // while (length != 0) 165 bne memcopy_default_loop 166 167memcopy_end 168 mov r0, r11 169 ldmfd sp!, {r4-r11, pc} 170 171 END 172 173