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