First version
[3rdparty/ote_partner/tlk.git] / lib / libc / string / arch / arm / memset.S
1 /*
2  * Copyright (c) 2008 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 .align 2
28
29 /* void bzero(void *s, size_t n); */
30 FUNCTION(bzero)
31         mov             r2, r1
32         mov             r1, #0
33
34 /* void *memset(void *s, int c, size_t n); */
35 FUNCTION(memset)
36         // check for zero length
37         cmp             r2, #0
38         bxeq    lr
39
40         // save the original pointer
41         mov             r12, r0
42
43         // short memsets aren't worth optimizing
44         cmp             r2, #(32 + 16)
45         blt             .L_bytewise
46
47         // fill a 32 bit register with the 8 bit value
48         and             r1, r1, #0xff
49         orr             r1, r1, r1, lsl #8
50         orr             r1, r1, r1, lsl #16
51
52         // check for 16 byte alignment
53         tst             r0, #15
54         bne             .L_not16bytealigned
55
56 .L_bigset:
57         // dump some registers to make space for our values
58         stmfd   sp!, { r4-r5 }
59         
60         // fill a bunch of registers with the set value
61         mov             r3, r1
62         mov             r4, r1
63         mov             r5, r1
64
65         // prepare the count register so we can avoid an extra compare
66         sub     r2, r2, #32
67
68         // 32 bytes at a time
69 .L_bigset_loop:
70         stmia   r0!, { r1, r3, r4, r5 }
71         subs    r2, r2, #32
72         stmia   r0!, { r1, r3, r4, r5 }
73         bge             .L_bigset_loop
74
75         // restore our dumped registers
76         ldmfd   sp!, { r4-r5 }
77
78         // see if we're done
79         adds    r2, r2, #32
80         beq             .L_done
81
82 .L_bytewise:
83         // bytewise memset
84         subs    r2, r2, #1
85         strb    r1, [r0], #1
86         bgt             .L_bytewise
87
88 .L_done:
89         // restore the base pointer as return value
90         mov             r0, r12
91         bx              lr
92
93 .L_not16bytealigned:
94         // dst is not 16 byte aligned, so we will set up to 15 bytes to get it aligned.
95
96         // set the condition flags based on the alignment.
97         lsl     r3, r0, #28
98         rsb     r3, r3, #0
99         msr     CPSR_f, r3             // move into NZCV fields in CPSR
100
101         // move as many bytes as necessary to get the dst aligned
102         strvsb  r1, [r0], #1                    // V set
103         strcsh  r1, [r0], #2                    // C set
104         streq   r1, [r0], #4                    // Z set
105         strmi   r1, [r0], #4                    // N set
106         strmi   r1, [r0], #4                    // N set
107
108         // fix the remaining len
109         sub     r2, r2, r3, lsr #28
110
111         // do the large memset
112         b       .L_bigset
113