]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/mips/memcpy.S
Replace FSF snail mail address by URL.
[thirdparty/glibc.git] / sysdeps / mips / memcpy.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, see
17 <http://www.gnu.org/licenses/>. */
18
19 #include <sysdep.h>
20 #include <endian.h>
21
22
23 /* void *memcpy(void *s1, const void *s2, size_t n); */
24
25 #if __BYTE_ORDER == __BIG_ENDIAN
26 # define LWHI lwl /* high part is left in big-endian */
27 # define SWHI swl /* high part is left in big-endian */
28 # define LWLO lwr /* low part is right in big-endian */
29 # define SWLO swr /* low part is right in big-endian */
30 #else
31 # define LWHI lwr /* high part is right in little-endian */
32 # define SWHI swr /* high part is right in little-endian */
33 # define LWLO lwl /* low part is left in little-endian */
34 # define SWLO swl /* low part is left in little-endian */
35 #endif
36
37 ENTRY (memcpy)
38 .set noreorder
39
40 slti t0, a2, 8 # Less than 8?
41 bne t0, zero, L(last8)
42 move v0, a0 # Setup exit value before too late
43
44 xor t0, a1, a0 # Find a0/a1 displacement
45 andi t0, 0x3
46 bne t0, zero, L(shift) # Go handle the unaligned case
47 subu t1, zero, a1
48 andi t1, 0x3 # a0/a1 are aligned, but are we
49 beq t1, zero, L(chk8w) # starting in the middle of a word?
50 subu a2, t1
51 LWHI t0, 0(a1) # Yes we are... take care of that
52 addu a1, t1
53 SWHI t0, 0(a0)
54 addu a0, t1
55
56 L(chk8w):
57 andi t0, a2, 0x1f # 32 or more bytes left?
58 beq t0, a2, L(chk1w)
59 subu a3, a2, t0 # Yes
60 addu a3, a1 # a3 = end address of loop
61 move a2, t0 # a2 = what will be left after loop
62 L(lop8w):
63 lw t0, 0(a1) # Loop taking 8 words at a time
64 lw t1, 4(a1)
65 lw t2, 8(a1)
66 lw t3, 12(a1)
67 lw t4, 16(a1)
68 lw t5, 20(a1)
69 lw t6, 24(a1)
70 lw t7, 28(a1)
71 addiu a0, 32
72 addiu a1, 32
73 sw t0, -32(a0)
74 sw t1, -28(a0)
75 sw t2, -24(a0)
76 sw t3, -20(a0)
77 sw t4, -16(a0)
78 sw t5, -12(a0)
79 sw t6, -8(a0)
80 bne a1, a3, L(lop8w)
81 sw t7, -4(a0)
82
83 L(chk1w):
84 andi t0, a2, 0x3 # 4 or more bytes left?
85 beq t0, a2, L(last8)
86 subu a3, a2, t0 # Yes, handle them one word at a time
87 addu a3, a1 # a3 again end address
88 move a2, t0
89 L(lop1w):
90 lw t0, 0(a1)
91 addiu a0, 4
92 addiu a1, 4
93 bne a1, a3, L(lop1w)
94 sw t0, -4(a0)
95
96 L(last8):
97 blez a2, L(lst8e) # Handle last 8 bytes, one at a time
98 addu a3, a2, a1
99 L(lst8l):
100 lb t0, 0(a1)
101 addiu a0, 1
102 addiu a1, 1
103 bne a1, a3, L(lst8l)
104 sb t0, -1(a0)
105 L(lst8e):
106 jr ra # Bye, bye
107 nop
108
109 L(shift):
110 subu a3, zero, a0 # Src and Dest unaligned
111 andi a3, 0x3 # (unoptimized case...)
112 beq a3, zero, L(shft1)
113 subu a2, a3 # a2 = bytes left
114 LWHI t0, 0(a1) # Take care of first odd part
115 LWLO t0, 3(a1)
116 addu a1, a3
117 SWHI t0, 0(a0)
118 addu a0, a3
119 L(shft1):
120 andi t0, a2, 0x3
121 subu a3, a2, t0
122 addu a3, a1
123 L(shfth):
124 LWHI t1, 0(a1) # Limp through, word by word
125 LWLO t1, 3(a1)
126 addiu a0, 4
127 addiu a1, 4
128 bne a1, a3, L(shfth)
129 sw t1, -4(a0)
130 b L(last8) # Handle anything which may be left
131 move a2, t0
132
133 .set reorder
134 END (memcpy)
135 libc_hidden_builtin_def (memcpy)