Annotation of sys/lib/libkern/arch/sh/memcpy.S, Revision 1.1.1.1
1.1 nbrk 1: /* $NetBSD: memcpy.S,v 1.2 2006/04/22 23:53:47 uwe Exp $ */
2:
3: /*
4: * Copyright (c) 2000 SHIMIZU Ryo <ryo@misakimix.org>
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. The name of the author may not be used to endorse or promote products
16: * derived from this software without specific prior written permission.
17: *
18: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28: */
29:
30: #include <machine/asm.h>
31:
32: #if defined(LIBC_SCCS) && !defined(lint)
33: RCSID("$NetBSD: memcpy.S,v 1.2 2006/04/22 23:53:47 uwe Exp $")
34: #endif
35:
36: #if !defined(MEMCOPY) && !defined(MEMMOVE) && !defined(BCOPY)
37: #define MEMCOPY
38: #endif
39:
40: #if defined(MEMCOPY) || defined(MEMMOVE)
41: #define REG_DST0 r3
42: #define REG_SRC r5
43: #define REG_DST r4
44: #else
45: #define REG_SRC r4
46: #define REG_DST r5
47: #endif
48:
49: #define REG_LEN r6
50:
51: #if defined(MEMCOPY)
52: ENTRY(memcpy)
53: #elif defined(MEMMOVE)
54: ENTRY(memmove)
55: #elif defined(BCOPY)
56: ENTRY(bcopy)
57: ALTENTRY(ovbcopy)
58: #endif
59: #ifdef REG_DST0
60: mov REG_DST,REG_DST0
61: #endif
62: cmp/eq REG_DST,REG_SRC /* if ( src == dst ) return; */
63: bt/s bcopy_return
64: cmp/hi REG_DST,REG_SRC
65: bf/s bcopy_overlap
66:
67: mov REG_SRC,r0
68: xor REG_DST,r0
69: and #3,r0
70: mov r0,r1
71: tst r0,r0 /* (src ^ dst) & 3 */
72: bf/s word_align
73:
74: longword_align:
75: tst REG_LEN,REG_LEN /* if ( len==0 ) return; */
76: bt/s bcopy_return
77:
78:
79: mov REG_SRC,r0
80: tst #1,r0 /* if ( src & 1 ) */
81: bt 1f
82: mov.b @REG_SRC+,r0 /* *dst++ = *src++; */
83: add #-1,REG_LEN
84: mov.b r0,@REG_DST
85: add #1,REG_DST
86: 1:
87:
88:
89: mov #1,r0
90: cmp/hi r0,REG_LEN /* if ( (len > 1) && */
91: bf/s 1f
92: mov REG_SRC,r0
93: tst #2,r0 /* (src & 2) { */
94: bt 1f
95: mov.w @REG_SRC+,r0 /* *((unsigned short*)dst)++ = *((unsigned short*)src)++; */
96: add #-2,REG_LEN /* len -= 2; */
97: mov.w r0,@REG_DST
98: add #2,REG_DST /* } */
99: 1:
100:
101:
102: mov #3,r1
103: cmp/hi r1,REG_LEN /* while ( len > 3 ) { */
104: bf/s no_align_delay
105: tst REG_LEN,REG_LEN
106: 2:
107: mov.l @REG_SRC+,r0 /* *((unsigned long*)dst)++ = *((unsigned long*)src)++; */
108: add #-4,REG_LEN /* len -= 4; */
109: mov.l r0,@REG_DST
110: cmp/hi r1,REG_LEN
111: bt/s 2b
112: add #4,REG_DST /* } */
113:
114: bra no_align_delay
115: tst REG_LEN,REG_LEN
116:
117:
118: word_align:
119: mov r1,r0
120: tst #1,r0
121: bf/s no_align_delay
122: tst REG_LEN,REG_LEN /* if ( len == 0 ) return; */
123: bt bcopy_return
124:
125:
126: mov REG_SRC,r0 /* if ( src & 1 ) */
127: tst #1,r0
128: bt 1f
129: mov.b @REG_SRC+,r0 /* *dst++ = *src++; */
130: add #-1,REG_LEN
131: mov.b r0,@REG_DST
132: add #1,REG_DST
133: 1:
134:
135:
136: mov #1,r1
137: cmp/hi r1,REG_LEN /* while ( len > 1 ) { */
138: bf/s no_align_delay
139: tst REG_LEN,REG_LEN
140: 2:
141: mov.w @REG_SRC+,r0 /* *((unsigned short*)dst)++ = *((unsigned short*)src)++; */
142: add #-2,REG_LEN /* len -= 2; */
143: mov.w r0,@REG_DST
144: cmp/hi r1,REG_LEN
145: bt/s 2b
146: add #2,REG_DST /* } */
147:
148:
149: no_align:
150: tst REG_LEN,REG_LEN /* while ( len!= ) { */
151: no_align_delay:
152: bt bcopy_return
153: 1:
154: mov.b @REG_SRC+,r0 /* *dst++ = *src++; */
155: add #-1,REG_LEN /* len--; */
156: mov.b r0,@REG_DST
157: tst REG_LEN,REG_LEN
158: bf/s 1b
159: add #1,REG_DST /* } */
160: bcopy_return:
161: rts
162: #ifdef REG_DST0
163: mov REG_DST0,r0
164: #else
165: nop
166: #endif
167:
168:
169: bcopy_overlap:
170: add REG_LEN,REG_SRC
171: add REG_LEN,REG_DST
172:
173: mov REG_SRC,r0
174: xor REG_DST,r0
175: and #3,r0
176: mov r0,r1
177: tst r0,r0 /* (src ^ dst) & 3 */
178: bf/s ov_word_align
179:
180: ov_longword_align:
181: tst REG_LEN,REG_LEN /* if ( len==0 ) return; */
182: bt/s bcopy_return
183:
184:
185: mov REG_SRC,r0
186: tst #1,r0 /* if ( src & 1 ) */
187: bt 1f
188: add #-1,REG_SRC /* *--dst = *--src; */
189: mov.b @REG_SRC,r0
190: mov.b r0,@-REG_DST
191: add #-1,REG_LEN
192: 1:
193:
194:
195: mov #1,r0
196: cmp/hi r0,REG_LEN /* if ( (len > 1) && */
197: bf/s 1f
198: mov REG_SRC,r0
199: tst #2,r0 /* (src & 2) { */
200: bt 1f
201: add #-2,REG_SRC /* *--((unsigned short*)dst) = *--((unsigned short*)src); */
202: mov.w @REG_SRC,r0
203: add #-2,REG_LEN /* len -= 2; */
204: mov.w r0,@-REG_DST /* } */
205: 1:
206:
207:
208: mov #3,r1
209: cmp/hi r1,REG_LEN /* while ( len > 3 ) { */
210: bf/s ov_no_align_delay
211: tst REG_LEN,REG_LEN
212: 2:
213: add #-4,REG_SRC
214: mov.l @REG_SRC,r0 /* *((unsigned long*)dst)++ = *((unsigned long*)src)++; */
215: add #-4,REG_LEN /* len -= 4; */
216: cmp/hi r1,REG_LEN
217: bt/s 2b
218: mov.l r0,@-REG_DST /* } */
219:
220: bra ov_no_align_delay
221: tst REG_LEN,REG_LEN
222:
223:
224: ov_word_align:
225: mov r1,r0
226: tst #1,r0
227: bf/s ov_no_align_delay
228: tst REG_LEN,REG_LEN /* if ( len == 0 ) return; */
229: bt bcopy_return
230:
231:
232: mov REG_SRC,r0 /* if ( src & 1 ) */
233: tst #1,r0
234: bt 1f
235: add #-1,REG_SRC
236: mov.b @REG_SRC,r0 /* *--dst = *--src; */
237: add #-1,REG_LEN
238: mov.b r0,@-REG_DST
239: 1:
240:
241:
242: mov #1,r1
243: cmp/hi r1,REG_LEN /* while ( len > 1 ) { */
244: bf/s ov_no_align_delay
245: tst REG_LEN,REG_LEN
246: 2:
247: add #-2,REG_SRC
248: mov.w @REG_SRC,r0 /* *--((unsigned short*)dst) = *--((unsigned short*)src); */
249: add #-2,REG_LEN /* len -= 2; */
250: cmp/hi r1,REG_LEN
251: bt/s 2b
252: mov.w r0,@-REG_DST /* } */
253:
254:
255: ov_no_align:
256: tst REG_LEN,REG_LEN /* while ( len!= ) { */
257: ov_no_align_delay:
258: bt 9f
259: 1:
260: add #-1,REG_SRC
261: mov.b @REG_SRC,r0 /* *--dst = *--src; */
262: add #-1,REG_LEN /* len--; */
263: tst REG_LEN,REG_LEN
264: bf/s 1b
265: mov.b r0,@-REG_DST /* } */
266: 9:
267: rts
268: #ifdef REG_DST0
269: mov REG_DST0,r0
270: #else
271: nop
272: #endif
CVSweb