• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2014 Travis Geiselbrecht
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23#include <asm.h>
24#include <arch/arm/cores.h>
25
26.text
27.syntax unified
28.thumb
29.align 2
30
31/* void bcopy(const void *src, void *dest, size_t n); */
32FUNCTION(bcopy)
33    // swap args for bcopy
34    mov     r12, r0
35    mov     r0, r1
36    mov     r1, r12
37
38/* void *memcpy(void *dest, const void *src, size_t count) */
39FUNCTION(memcpy)
40    push    { r0, r14 }
41
42    // test for zero length or pointers being equivalent
43    cbz     r2, .L_done
44    cmp     r0, r1
45    beq     .L_done
46
47    // check for a short copy len
48    cmp     r2, #16
49    blt     .L_bytewise
50
51    // check to see if the pointers are similarly dword aligned
52    eors    r3, r0, r1
53    ands    r3, #7
54    beq     .L_prepare_dword
55
56    // see how many bytes we need to move to align dest to word boundary
57    and     r3, r0, #3
58    cbz     r3, .L_prepare_wordwise
59    rsb     r3, #4
60    subs    r2, r3
61
62    .align 2
63.L_bytewise_align:
64    // bytewise to align memcpy
65    ldrb    r12, [r1], #1
66    subs    r3, r3, #1
67    strb    r12, [r0], #1
68    bgt     .L_bytewise_align
69
70.L_prepare_wordwise:
71    // load the number of words left
72    lsrs    r3, r2, #2
73
74    .align 2
75.L_wordwise:
76    // wordwise copy
77    ldr     r12, [r1], #4
78    subs    r3, r3, #1
79    str     r12, [r0], #4
80    bgt     .L_wordwise
81
82    // remaining bytes
83    ands     r2, #3
84    beq     .L_done
85
86    .align 2
87.L_bytewise:
88    // simple bytewise copy
89    ldrb    r12, [r1], #1
90    subs    r2, r2, #1
91    strb    r12, [r0], #1
92    bgt     .L_bytewise
93
94.L_done:
95    pop     { r0, pc }
96
97// Handle copying by dword (8 bytes at a time) increments
98.L_prepare_dword:
99    // see how many bytes we need to move to align dest to dword boundary
100    and     r3, r0, #7
101    cbz     r3, .L_prepare_dwordwise
102    rsb     r3, #8
103    subs    r2, r3
104
105    .align 2
106.L_bytewise_align_dword:
107    // bytewise to align memcpy
108    ldrb    r12, [r1], #1
109    subs    r3, r3, #1
110    strb    r12, [r0], #1
111    bgt     .L_bytewise_align_dword
112
113.L_prepare_dwordwise:
114    // load the number of dwords left
115    lsrs    r3, r2, #3
116
117    push    { r5 }
118
119    .align 2
120.L_dwordwise:
121    // dwordwise copy
122    ldrd    r5, r12, [r1], #8
123    subs    r3, r3, #1
124    strd    r5, r12, [r0], #8
125    bgt     .L_dwordwise
126
127    pop     { r5 }
128
129    // remaining bytes
130    ands     r2, #7
131    beq     .L_done
132
133    // finish the remaining bytes and exit
134    b       .L_bytewise
135
136