694ee8f1dcf4e959be7dda36c0b41ec7377bc5fd
[platform/upstream/glibc.git] / sysdeps / mips / memset.S
1 /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Hartvig Ekner <hartvige@mips.com>, 2002.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <sysdep.h>
21 #include <endian.h>
22
23
24 /* void *memset(void *s, int c, size_t n).  */
25
26 #if __BYTE_ORDER == __BIG_ENDIAN
27 # define SWHI   swl             /* high part is left in big-endian      */
28 #else
29 # define SWHI   swr             /* high part is right in little-endian  */
30 #endif
31
32 ENTRY (memset)
33         .set    noreorder
34
35         slti    t1, a2, 8               # Less than 8?
36         bne     t1, zero, L(last8)
37         move    v0, a0                  # Setup exit value before too late
38
39         beq     a1, zero, L(ueven)      # If zero pattern, no need to extend
40         andi    a1, 0xff                # Avoid problems with bogus arguments
41         sll     t0, a1, 8
42         or      a1, t0
43         sll     t0, a1, 16
44         or      a1, t0                  # a1 is now pattern in full word
45
46 L(ueven):       
47         subu    t0, zero, a0            # Unaligned address?
48         andi    t0, 0x3
49         beq     t0, zero, L(chkw)
50         subu    a2, t0
51         SWHI    a1, 0(a0)               # Yes, handle first unaligned part
52         addu    a0, t0                  # Now both a0 and a2 are updated
53
54 L(chkw):        
55         andi    t0, a2, 0x7             # Enough left for one loop iteration?
56         beq     t0, a2, L(chkl)
57         subu    a3, a2, t0
58         addu    a3, a0                  # a3 is last loop address +1
59         move    a2, t0                  # a2 is now # of bytes left after loop
60 L(loopw):       
61         addiu   a0, 8                   # Handle 2 words pr. iteration
62         sw      a1, -8(a0)
63         bne     a0, a3, L(loopw)
64         sw      a1, -4(a0)
65
66 L(chkl):        
67         andi    t0, a2, 0x4             # Check if there is at least a full
68         beq     t0, zero, L(last8)      #  word remaining after the loop
69         subu    a2, t0
70         sw      a1, 0(a0)               # Yes...
71         addiu   a0, 4
72
73 L(last8):       
74         blez    a2, L(exit)             # Handle last 8 bytes (if cnt>0)
75         addu    a3, a2, a0              # a3 is last address +1
76 L(lst8l):       
77         addiu   a0, 1
78         bne     a0, a3, L(lst8l)
79         sb      a1, -1(a0)
80 L(exit):        
81         j       ra                      # Bye, bye
82         nop
83
84         .set    reorder
85 END (memset)
86 libc_hidden_builtin_def (memset)