1/* 2 * Copyright (c) 2014 Travis Geiselbrecht 3 * 4 * Use of this source code is governed by a MIT-style 5 * license that can be found in the LICENSE file or at 6 * https://opensource.org/licenses/MIT 7 */ 8#include <lk/asm.h> 9#include <arch/arm/cores.h> 10 11.text 12.syntax unified 13.thumb 14.align 2 15 16/* void bcopy(const void *src, void *dest, size_t n); */ 17FUNCTION(bcopy) 18 // swap args for bcopy 19 mov r12, r0 20 mov r0, r1 21 mov r1, r12 22 23/* void *memcpy(void *dest, const void *src, size_t count) */ 24FUNCTION(memcpy) 25 push { r0, r14 } 26 27 // test for zero length or pointers being equivalent 28 cbz r2, .L_done 29 cmp r0, r1 30 beq .L_done 31 32 // check for a short copy len 33 cmp r2, #16 34 blt .L_bytewise 35 36 // check to see if the pointers are similarly dword aligned 37 eors r3, r0, r1 38 ands r3, #7 39 beq .L_prepare_dword 40 41 // see how many bytes we need to move to align dest to word boundary 42 and r3, r0, #3 43 cbz r3, .L_prepare_wordwise 44 rsb r3, #4 45 subs r2, r3 46 47 .align 2 48.L_bytewise_align: 49 // bytewise to align memcpy 50 ldrb r12, [r1], #1 51 subs r3, r3, #1 52 strb r12, [r0], #1 53 bgt .L_bytewise_align 54 55.L_prepare_wordwise: 56 // load the number of words left 57 lsrs r3, r2, #2 58 59 .align 2 60.L_wordwise: 61 // wordwise copy 62 ldr r12, [r1], #4 63 subs r3, r3, #1 64 str r12, [r0], #4 65 bgt .L_wordwise 66 67 // remaining bytes 68 ands r2, #3 69 beq .L_done 70 71 .align 2 72.L_bytewise: 73 // simple bytewise copy 74 ldrb r12, [r1], #1 75 subs r2, r2, #1 76 strb r12, [r0], #1 77 bgt .L_bytewise 78 79.L_done: 80 pop { r0, pc } 81 82// Handle copying by dword (8 bytes at a time) increments 83.L_prepare_dword: 84 // see how many bytes we need to move to align dest to dword boundary 85 and r3, r0, #7 86 cbz r3, .L_prepare_dwordwise 87 rsb r3, #8 88 subs r2, r3 89 90 .align 2 91.L_bytewise_align_dword: 92 // bytewise to align memcpy 93 ldrb r12, [r1], #1 94 subs r3, r3, #1 95 strb r12, [r0], #1 96 bgt .L_bytewise_align_dword 97 98.L_prepare_dwordwise: 99 // load the number of dwords left 100 lsrs r3, r2, #3 101 102 push { r5 } 103 104 .align 2 105.L_dwordwise: 106 // dwordwise copy 107 ldrd r5, r12, [r1], #8 108 subs r3, r3, #1 109 strd r5, r12, [r0], #8 110 bgt .L_dwordwise 111 112 pop { r5 } 113 114 // remaining bytes 115 ands r2, #7 116 beq .L_done 117 118 // finish the remaining bytes and exit 119 b .L_bytewise 120 121