* sysdeps/mips/mips64/memcpy.S, sysdeps/mips/mips64/memset.S: New.
[kopensolaris-gnu/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):       subu    t0, zero, a0            # Unaligned address?
47         andi    t0, 0x3
48         beq     t0, zero, L(chkw)
49         subu    a2, t0
50         SWHI    a1, 0(a0)               # Yes, handle first unaligned part
51         addu    a0, t0                  # Now both a0 and a2 are updated
52
53 L(chkw):        andi    t0, a2, 0x7             # Enough left for one loop iteration?
54         beq     t0, a2, L(chkl)
55         subu    a3, a2, t0
56         addu    a3, a0                  # a3 is last loop address +1
57         move    a2, t0                  # a2 is now # of bytes left after loop
58 L(loopw):       addiu   a0, 8                   # Handle 2 words pr. iteration
59         sw      a1, -8(a0)
60         bne     a0, a3, L(loopw)
61         sw      a1, -4(a0)
62
63 L(chkl):        andi    t0, a2, 0x4             # Check if there is at least a full
64         beq     t0, zero, L(last8)      #  word remaining after the loop
65         subu    a2, t0
66         sw      a1, 0(a0)               # Yes...
67         addiu   a0, 4
68
69 L(last8):       blez    a2, L(exit)             # Handle last 8 bytes (if cnt>0)
70         addu    a3, a2, a0              # a3 is last address +1
71 L(lst8l):       addiu   a0, 1
72         bne     a0, a3, L(lst8l)
73         sb      a1, -1(a0)
74 L(exit):        j       ra                      # Bye, bye
75         nop
76
77         .set    reorder
78 END (memset)