add memset asm code
[ti-x.git] / src / arch / arm / lib / memset.S
blobec4f7e1d66f596600a0fa31521e6691e7383ed0e
1 /* the ti-x embed operation system
2  * 
3  * it is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  * 
8  * it is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  * 
13  * You should have received a copy of the GNU General Public License
14  * along with it; If not, see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>
15  * 
16  * Copyright (C) 2009, Ruki All rights reserved.
17  * Home: <a href="http://www.xxx.org">http://www.xxx.org</a>
18  *
19  * \author              ruki
20  * \date                09.12.07
21  * \file                memset.S
22  *
23  */
25 /* ////////////////////////////////////////////////////////////
26  * includes
27  */
28 #include "prefix.s.h"
30 /* ////////////////////////////////////////////////////////////
31  * internal implemetion
32  */
33         .text
34         .align  5
35         .word   0
37 1:      subs    r2, r2, #4                      // 1 do we have enough
38         blt             5f                                      // 1 bytes to align with?
39         cmp     r3, #2                                  // 1
40         strltb  r1, [r0], #1            // 1
41         strleb  r1, [r0], #1            // 1
42         strb    r1, [r0], #1            // 1
43         add             r2, r2, r3                      // 1 (r2 = r2 - (4 - r3))
45 /* the pointer is now aligned and the length is adjusted.  Try doing the
46  * memset again.
47  */
49 TI_ASM_EXPORT(memset)
50 TI_ASM_EXPORT(__memset)
51         ands    r3, r0, #3                      // 1 unaligned?
52         bne             1b                                      // 1
54         // we know that the pointer in r0 is aligned to a word boundary.
55         orr             r1, r1, r1, lsl #8
56         orr             r1, r1, r1, lsl #16
57         mov             r3, r1
58         cmp             r2, #16
59         blt             4f
61         /* we need an extra register for this loop 
62          * - save the return address and use the LR
63          */
64         str             lr, [sp, #-4]!
65         mov             ip, r1
66         mov             lr, r1
68 2:      subs    r2, r2, #64
69         stmgeia r0!, {r1, r3, ip, lr}   // 64 bytes at a time.
70         stmgeia r0!, {r1, r3, ip, lr}
71         stmgeia r0!, {r1, r3, ip, lr}
72         stmgeia r0!, {r1, r3, ip, lr}
73         bgt             2b
74         ldmeqfd sp!, {pc}                               // Now < 64 bytes to go.
76         /* no need to correct the count
77          * we're only testing bits from now on
78          */
79         tst     r2, #32
80         stmneia r0!, {r1, r3, ip, lr}
81         stmneia r0!, {r1, r3, ip, lr}
82         tst     r2, #16
83         stmneia r0!, {r1, r3, ip, lr}
84         ldr     lr, [sp], #4
86 4:      tst     r2, #8
87         stmneia r0!, {r1, r3}
88         tst     r2, #4
89         strne   r1, [r0], #4
91         /* when we get here, we've got less than 4 bytes to zero.  
92          * We may have an unaligned pointer as well.
93          */
94 5:      tst     r2, #2
95         strneb  r1, [r0], #1
96         strneb  r1, [r0], #1
97         tst     r2, #1
98         strneb  r1, [r0], #1
99         mov     pc, lr