• 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 bzero(void *s, size_t n); */
32FUNCTION(bzero)
33    mov     r2, r1
34    movs    r1, #0
35
36/* void *memset(void *s, int c, size_t n); */
37FUNCTION(memset)
38    // save the original pointer
39    push    { r0, lr }
40
41    // check for zero length
42    cbz     r2, .L_done
43
44    // short memsets aren't worth optimizing and make sure we have
45    // enough headroom to try to do dwordwise move optimization
46    cmp     r2, #16
47    blt     .L_bytewise
48
49    // see how many bytes we need to move to align to dword boundaries
50    and     r3, r0, #7
51    cbz     r3, .L_prepare_dwordwise
52    rsb     r3, #8
53    subs    r2, r3
54
55.L_bytewise_align:
56    // bytewise to align memset
57    subs    r3, r3, #1
58    strb    r1, [r0], #1
59    bgt     .L_bytewise_align
60
61.L_prepare_dwordwise:
62    // fill a pair of 32 bit registers with the 8 bit value
63    uxtb    r1, r1
64    orr     r1, r1, r1, lsl #8
65    orr     r1, r1, r1, lsl #16
66    mov     r12, r1
67
68    // load the number of dwords left
69    lsrs    r3, r2, #3
70
71.L_dwordwise:
72    // dwordwise memset
73    subs    r3, r3, #1
74    strd    r1, r12, [r0], #8
75    bgt     .L_dwordwise
76
77    // remaining bytes
78    ands     r2, #7
79    beq     .L_done
80
81.L_bytewise:
82    // bytewise memset
83    subs    r2, r2, #1
84    strb    r1, [r0], #1
85    bgt     .L_bytewise
86
87.L_done:
88    // restore the base pointer as return value
89    pop     { r0, pc }
90
91