Annotation of sys/lib/libkern/arch/m88k/copy_subr.S, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: copy_subr.S,v 1.1 2006/11/17 22:32:38 miod Exp $ */
2: /*
3: * Mach Operating System
4: * Copyright (c) 1993-1992 Carnegie Mellon University
5: * Copyright (c) 1991 OMRON Corporation
6: * Copyright (c) 1996 Nivas Madhur
7: * Copyright (c) 1998 Steve Murphree, Jr.
8: * All Rights Reserved.
9: *
10: * Permission to use, copy, modify and distribute this software and its
11: * documentation is hereby granted, provided that both the copyright
12: * notice and this permission notice appear in all copies of the
13: * software, derivative works or modified versions, and any portions
14: * thereof, and that both notices appear in supporting documentation.
15: *
16: * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17: * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
18: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19: *
20: * Carnegie Mellon requests users of this software to return to
21: *
22: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23: * School of Computer Science
24: * Carnegie Mellon University
25: * Pittsburgh PA 15213-3890
26: *
27: * any improvements or extensions that they make and grant Carnegie the
28: * rights to redistribute these changes.
29: */
30:
31: #include <machine/asm.h>
32:
33: /*
34: * copy count bytes of data from source to destination
35: * Don Harper (don@omron.co.jp), Omron Corporation.
36: */
37:
38: #if defined(MEMCPY) || defined(MEMMOVE)
39: #define SRC r3
40: #define DST r2
41: #define SAVE r5
42: #else
43: #define SRC r2
44: #define DST r3
45: #endif
46: #define LEN r4
47:
48: #ifdef MEMCPY
49: ENTRY(memcpy)
50: #endif
51: #ifdef MEMMOVE
52: ENTRY(memmove)
53: #endif
54: #ifdef BCOPY
55: ENTRY(bcopy)
56: #endif
57: #ifdef OVBCOPY
58: ENTRY(ovbcopy)
59: #endif
60:
61: #if defined(MEMCPY) || defined(MEMMOVE)
62: or SAVE, DST, r0
63: #endif
64:
65: bcnd eq0,LEN,_ASM_LABEL(bcopy_out) /* nothing to do if == 0 */
66:
67: /*
68: * check position of source and destination data
69: */
70: cmp r9,SRC,DST /* compare source address to destination */
71: bb1 eq,r9,_ASM_LABEL(bcopy_out) /* nothing to do if equal */
72: #if defined(MEMMOVE) || defined(OVBCOPY)
73: bb1 lo,r9,_ASM_LABEL(bcopy_reverse) /* reverse copy if src < dest */
74: #endif
75:
76: /*
77: * source address is greater than destination address, or we do
78: * not have to care about overlapping areas: copy forward
79: */
80: cmp r9,LEN,16 /* see if we have at least 16 bytes */
81: bb1 lt,r9,_ASM_LABEL(f_byte_copy) /* copy bytes for small data length */
82: /*
83: * determine copy strategy based on alignment of source and destination
84: */
85: mask r6,SRC,3 /* get 2 low order bits of source address */
86: mask r7,DST,3 /* get 2 low order bits of destintation addr */
87: mak r6,r6,0<4> /* convert source bits to table offset */
88: mak r7,r7,0<2> /* convert destination bits to table offset */
89: or.u r12,r0,hi16(_ASM_LABEL(f_strat))
90: or r12,r12,lo16(_ASM_LABEL(f_strat))
91: addu r6,r6,r7 /* compute final table offset for strategy */
92: ld r12,r12,r6 /* load the strategy routine */
93: jmp r12 /* branch to strategy routine */
94:
95: /*
96: * Copy three bytes from src to destination then copy words
97: */
98: ASLOCAL(f_3byte_word_copy)
99: ld.bu r6,SRC,0 /* load byte from source */
100: ld.bu r7,SRC,1 /* load byte from source */
101: ld.bu r8,SRC,2 /* load byte from source */
102: st.b r6,DST,0 /* store byte to destination */
103: st.b r7,DST,1 /* store byte to destination */
104: st.b r8,DST,2 /* store byte to destination */
105: addu SRC,SRC,3 /* increment source pointer */
106: addu DST,DST,3 /* increment destination pointer */
107: br.n _ASM_LABEL(f_word_copy) /* copy full words */
108: subu LEN,LEN,3 /* decrement length */
109:
110: /*
111: * Copy 1 halfword from src to destination then copy words
112: */
113: ASLOCAL(f_1half_word_copy)
114: ld.hu r6,SRC,0 /* load half-word from source */
115: st.h r6,DST,0 /* store half-word to destination */
116: addu SRC,SRC,2 /* increment source pointer */
117: addu DST,DST,2 /* increment destination pointer */
118: br.n _ASM_LABEL(f_word_copy) /* copy full words */
119: subu LEN,LEN,2 /* decrement remaining length */
120:
121: /*
122: * Copy 1 byte from src to destination then copy words
123: */
124: ASLOCAL(f_1byte_word_copy)
125: ld.bu r6,SRC,0 /* load 1 byte from source */
126: st.b r6,DST,0 /* store 1 byte to destination */
127: addu SRC,SRC,1 /* increment source pointer */
128: addu DST,DST,1 /* increment destination pointer */
129: subu LEN,LEN,1 /* decrement remaining length */
130: /* FALLTHROUGH */
131: /*
132: * Copy as many full words as possible, 4 words per loop
133: */
134: ASLOCAL(f_word_copy)
135: cmp r10,LEN,16 /* see if we have 16 bytes remaining */
136: bb1 lo,r10,_ASM_LABEL(f_byte_copy) /* not enough left, copy bytes */
137: ld r6,SRC,0 /* load first word */
138: ld r7,SRC,4 /* load second word */
139: ld r8,SRC,8 /* load third word */
140: ld r9,SRC,12 /* load fourth word */
141: st r6,DST,0 /* store first word */
142: st r7,DST,4 /* store second word */
143: st r8,DST,8 /* store third word */
144: st r9,DST,12 /* store fourth word */
145: addu SRC,SRC,16 /* increment source pointer */
146: addu DST,DST,16 /* increment destination pointer */
147: br.n _ASM_LABEL(f_word_copy) /* branch to copy another block */
148: subu LEN,LEN,16 /* decrement remaining length */
149:
150: ASLOCAL(f_1byte_half_copy)
151: ld.bu r6,SRC,0 /* load 1 byte from source */
152: st.b r6,DST,0 /* store 1 byte to destination */
153: addu SRC,SRC,1 /* increment source pointer */
154: addu DST,DST,1 /* increment destination pointer */
155: subu LEN,LEN,1 /* decrement remaining length */
156: /* FALLTHROUGH */
157:
158: ASLOCAL(f_half_copy)
159: cmp r10,LEN,16 /* see if we have 16 bytes remaining */
160: bb1 lo,r10,_ASM_LABEL(f_byte_copy) /* not enough left, copy bytes */
161: ld.hu r6,SRC,0 /* load first half-word */
162: ld.hu r7,SRC,2 /* load second half-word */
163: ld.hu r8,SRC,4 /* load third half-word */
164: ld.hu r9,SRC,6 /* load fourth half-word */
165: ld.hu r10,SRC,8 /* load fifth half-word */
166: ld.hu r11,SRC,10 /* load sixth half-word */
167: ld.hu r12,SRC,12 /* load seventh half-word */
168: ld.hu r13,SRC,14 /* load eighth half-word */
169: st.h r6,DST,0 /* store first half-word */
170: st.h r7,DST,2 /* store second half-word */
171: st.h r8,DST,4 /* store third half-word */
172: st.h r9,DST,6 /* store fourth half-word */
173: st.h r10,DST,8 /* store fifth half-word */
174: st.h r11,DST,10 /* store sixth half-word */
175: st.h r12,DST,12 /* store seventh half-word */
176: st.h r13,DST,14 /* store eighth half-word */
177: addu SRC,SRC,16 /* increment source pointer */
178: addu DST,DST,16 /* increment destination pointer */
179: br.n _ASM_LABEL(f_half_copy) /* branch to copy another block */
180: subu LEN,LEN,16 /* decrement remaining length */
181:
182: ASLOCAL(f_byte_copy)
183: bcnd eq0,LEN,_ASM_LABEL(bcopy_out) /* branch if nothing left to copy */
184: ld.bu r6,SRC,0 /* load byte from source */
185: st.b r6,DST,0 /* store byte in destination */
186: addu SRC,SRC,1 /* increment source pointer */
187: addu DST,DST,1 /* increment destination pointer */
188: br.n _ASM_LABEL(f_byte_copy) /* branch for next byte */
189: subu LEN,LEN,1 /* decrement remaining length */
190:
191: #if defined(MEMMOVE) || defined(OVBCOPY)
192: /*
193: * source address is less than destination address, copy in reverse
194: */
195: ASLOCAL(bcopy_reverse)
196: /*
197: * start copy pointers at end of data
198: */
199: addu SRC,SRC,LEN /* start source at end of data */
200: addu DST,DST,LEN /* start destination at end of data */
201: /*
202: * check for short data
203: */
204: cmp r9,LEN,16 /* see if we have at least 16 bytes */
205: bb1 lt,r9,_ASM_LABEL(r_byte_copy) /* copy bytes for small data length */
206: /*
207: * determine copy strategy based on alignment of source and destination
208: */
209: mask r6,SRC,3 /* get 2 low order bits of source address */
210: mask r7,DST,3 /* get 2 low order bits of destintation addr */
211: mak r6,r6,0<4> /* convert source bits to table offset */
212: mak r7,r7,0<2> /* convert destination bits to table offset */
213: or.u r12,r0,hi16(_ASM_LABEL(r_strat))
214: or r12,r12,lo16(_ASM_LABEL(r_strat))
215: addu r6,r6,r7 /* compute final table offset for strategy */
216: ld r12,r12,r6 /* load the strategy routine */
217: jmp r12 /* branch to strategy routine */
218:
219: /*
220: * Copy three bytes from src to destination then copy words
221: */
222: ASLOCAL(r_3byte_word_copy)
223: subu SRC,SRC,3 /* decrement source pointer */
224: subu DST,DST,3 /* decrement destination pointer */
225: ld.bu r6,SRC,0 /* load byte from source */
226: ld.bu r7,SRC,1 /* load byte from source */
227: ld.bu r8,SRC,2 /* load byte from source */
228: st.b r6,DST,0 /* store byte to destination */
229: st.b r7,DST,1 /* store byte to destination */
230: st.b r8,DST,2 /* store byte to destination */
231: br.n _ASM_LABEL(r_word_copy) /* copy full words */
232: subu LEN,LEN,3 /* decrement length */
233:
234: /*
235: * Copy 1 halfword from src to destination then copy words
236: */
237: ASLOCAL(r_1half_word_copy)
238: subu SRC,SRC,2 /* decrement source pointer */
239: subu DST,DST,2 /* decrement destination pointer */
240: ld.hu r6,SRC,0 /* load half-word from source */
241: st.h r6,DST,0 /* store half-word to destination */
242: br.n _ASM_LABEL(r_word_copy) /* copy full words */
243: subu LEN,LEN,2 /* decrement remaining length */
244:
245: /*
246: * Copy 1 byte from src to destination then copy words
247: */
248: ASLOCAL(r_1byte_word_copy)
249: subu SRC,SRC,1 /* decrement source pointer */
250: subu DST,DST,1 /* decrement destination pointer */
251: ld.bu r6,SRC,0 /* load 1 byte from source */
252: st.b r6,DST,0 /* store 1 byte to destination */
253: subu LEN,LEN,1 /* decrement remaining length */
254: /* FALLTHROUGH */
255: /*
256: * Copy as many full words as possible, 4 words per loop
257: */
258: ASLOCAL(r_word_copy)
259: cmp r10,LEN,16 /* see if we have 16 bytes remaining */
260: bb1 lo,r10,_ASM_LABEL(r_byte_copy) /* not enough left, copy bytes */
261: subu SRC,SRC,16 /* decrement source pointer */
262: subu DST,DST,16 /* decrement destination pointer */
263: ld r6,SRC,0 /* load first word */
264: ld r7,SRC,4 /* load second word */
265: ld r8,SRC,8 /* load third word */
266: ld r9,SRC,12 /* load fourth word */
267: st r6,DST,0 /* store first word */
268: st r7,DST,4 /* store second word */
269: st r8,DST,8 /* store third word */
270: st r9,DST,12 /* store fourth word */
271: br.n _ASM_LABEL(r_word_copy) /* branch to copy another block */
272: subu LEN,LEN,16 /* decrement remaining length */
273:
274: ASLOCAL(r_1byte_half_copy)
275: subu SRC,SRC,1 /* decrement source pointer */
276: subu DST,DST,1 /* decrement destination pointer */
277: ld.bu r6,SRC,0 /* load 1 byte from source */
278: st.b r6,DST,0 /* store 1 byte to destination */
279: subu LEN,LEN,1 /* decrement remaining length */
280: /* FALLTHROUGH */
281:
282: ASLOCAL(r_half_copy)
283: cmp r10,LEN,16 /* see if we have 16 bytes remaining */
284: bb1 lo,r10,_ASM_LABEL(r_byte_copy) /* not enough left, copy bytes */
285: subu SRC,SRC,16 /* decrement source pointer */
286: subu DST,DST,16 /* decrement destination pointer */
287: ld.hu r6,SRC,0 /* load first half-word */
288: ld.hu r7,SRC,2 /* load second half-word */
289: ld.hu r8,SRC,4 /* load third half-word */
290: ld.hu r9,SRC,6 /* load fourth half-word */
291: ld.hu r10,SRC,8 /* load fifth half-word */
292: ld.hu r11,SRC,10 /* load sixth half-word */
293: ld.hu r12,SRC,12 /* load seventh half-word */
294: ld.hu r13,SRC,14 /* load eighth half-word */
295: st.h r6,DST,0 /* store first half-word */
296: st.h r7,DST,2 /* store second half-word */
297: st.h r8,DST,4 /* store third half-word */
298: st.h r9,DST,6 /* store fourth half-word */
299: st.h r10,DST,8 /* store fifth half-word */
300: st.h r11,DST,10 /* store sixth half-word */
301: st.h r12,DST,12 /* store seventh half-word */
302: st.h r13,DST,14 /* store eighth half-word */
303: br.n _ASM_LABEL(r_half_copy) /* branch to copy another block */
304: subu LEN,LEN,16 /* decrement remaining length */
305:
306: ASLOCAL(r_byte_copy)
307: bcnd eq0,LEN,_ASM_LABEL(bcopy_out) /* branch if nothing left to copy */
308: subu SRC,SRC,1 /* decrement source pointer */
309: subu DST,DST,1 /* decrement destination pointer */
310: ld.bu r6,SRC,0 /* load byte from source */
311: st.b r6,DST,0 /* store byte in destination */
312: br.n _ASM_LABEL(r_byte_copy) /* branch for next byte */
313: subu LEN,LEN,1 /* decrement remaining length */
314: #endif /* MEMMOVE || OVBCOPY */
315:
316: ASLOCAL(bcopy_out)
317: #if defined(MEMCPY) || defined(MEMMOVE)
318: jmp.n r1 /* all done, return to caller */
319: or r2, SAVE, r0
320: #else
321: jmp r1 /* all done, return to caller */
322: #endif
323:
324: data
325: align 4
326: ASLOCAL(f_strat)
327: word _ASM_LABEL(f_word_copy)
328: word _ASM_LABEL(f_byte_copy)
329: word _ASM_LABEL(f_half_copy)
330: word _ASM_LABEL(f_byte_copy)
331: word _ASM_LABEL(f_byte_copy)
332: word _ASM_LABEL(f_3byte_word_copy)
333: word _ASM_LABEL(f_byte_copy)
334: word _ASM_LABEL(f_1byte_half_copy)
335: word _ASM_LABEL(f_half_copy)
336: word _ASM_LABEL(f_byte_copy)
337: word _ASM_LABEL(f_1half_word_copy)
338: word _ASM_LABEL(f_byte_copy)
339: word _ASM_LABEL(f_byte_copy)
340: word _ASM_LABEL(f_1byte_half_copy)
341: word _ASM_LABEL(f_byte_copy)
342: word _ASM_LABEL(f_1byte_word_copy)
343:
344: #if defined(MEMMOVE) || defined(OVBCOPY)
345: ASLOCAL(r_strat)
346: word _ASM_LABEL(r_word_copy)
347: word _ASM_LABEL(r_byte_copy)
348: word _ASM_LABEL(r_half_copy)
349: word _ASM_LABEL(r_byte_copy)
350: word _ASM_LABEL(r_byte_copy)
351: word _ASM_LABEL(r_1byte_word_copy)
352: word _ASM_LABEL(r_byte_copy)
353: word _ASM_LABEL(r_1byte_half_copy)
354: word _ASM_LABEL(r_half_copy)
355: word _ASM_LABEL(r_byte_copy)
356: word _ASM_LABEL(r_1half_word_copy)
357: word _ASM_LABEL(r_byte_copy)
358: word _ASM_LABEL(r_byte_copy)
359: word _ASM_LABEL(r_1byte_half_copy)
360: word _ASM_LABEL(r_byte_copy)
361: word _ASM_LABEL(r_3byte_word_copy)
362: #endif
CVSweb