1 /* $NetBSD: bcopy.S,v 1.1 2005/12/20 19:28:49 christos Exp $ */
4 * Copyright (c) 1995 Carnegie-Mellon University.
7 * Author: Trevor Blackwell. Support for use as memcpy() and memmove()
8 * added by Chris Demetriou.
10 * Permission to use, copy, modify and distribute this software and
11 * its 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.
16 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
18 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
20 * Carnegie Mellon requests users of this software to return to
22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
23 * School of Computer Science
24 * Carnegie Mellon University
25 * Pittsburgh PA 15213-3890
27 * any improvements or extensions that they make and grant Carnegie the
28 * rights to redistribute these changes.
31 #include <machine/asm.h>
33 #if defined(MEMCOPY) || defined(MEMMOVE)
35 #define FUNCTION memcpy
37 #define FUNCTION memmove
41 #else /* !(defined(MEMCOPY) || defined(MEMMOVE)) */
42 #define FUNCTION bcopy
45 #endif /* !(defined(MEMCOPY) || defined(MEMMOVE)) */
52 * void bcopy(char *from, char *to, size_t len);
53 * char *memcpy(void *to, const void *from, size_t len);
54 * char *memmove(void *to, const void *from, size_t len);
56 * No matter how invoked, the source and destination registers
57 * for calculation. There's no point in copying them to "working"
58 * registers, since the code uses their values "in place," and
59 * copying them would be slower.
64 #if defined(MEMCOPY) || defined(MEMMOVE)
65 /* set up return value, while we still can */
69 /* Check for negative length */
70 ble SIZEREG,bcopy_done
72 /* Check for overlap */
77 /* a3 = end address */
78 addq SRCREG,SIZEREG,a3
80 /* Get the first word */
83 /* Do they have the same alignment? */
87 bne t0,bcopy_different_alignment
89 /* src & dst have same alignment */
90 beq t1,bcopy_all_aligned
93 addq SIZEREG,t1,SIZEREG
98 /* Dst is 8-byte aligned */
101 /* If less than 8 bytes,skip loop */
103 and SIZEREG,7,SIZEREG
105 beq t0,bcopy_samealign_lp_end
113 bne t0,bcopy_samealign_lp
115 bcopy_samealign_lp_end:
116 /* If we're done, exit */
117 bne SIZEREG,bcopy_small_left
129 bcopy_different_alignment:
131 * this is the fun part
133 addq SRCREG,SIZEREG,a3
135 bne t0,bcopy_da_finish
137 beq t1,bcopy_da_noentry
139 /* Do the initial partial word */
151 addq SRCREG,t0,SRCREG
152 addq DSTREG,t0,DSTREG
153 subq SIZEREG,t0,SIZEREG
159 and SIZEREG,7,SIZEREG
160 beq t0,bcopy_da_finish2
171 beq t0,bcopy_da_finish1
183 /* Do the last new word */
187 /* Do the last partial word */
192 br zero,bcopy_samealign_lp_end
195 /* Do the last word in the next source word */
207 addq DSTREG,SIZEREG,a4
222 * Basically equivalent to previous case, only backwards.
223 * Not quite as highly optimized
225 addq SRCREG,SIZEREG,a3
226 addq DSTREG,SIZEREG,a4
228 /* less than 8 bytes - don't worry about overlap */
230 bne t0,bcopy_ov_short
232 /* Possibly do a partial first word */
234 beq t4,bcopy_ov_nostart2
238 subq SIZEREG,t4,SIZEREG
251 and SIZEREG,7,SIZEREG
252 beq t4,bcopy_ov_lp_end
255 /* This could be more pipelined, but it doesn't seem worth it */
268 beq SIZEREG,bcopy_done
286 br zero,bcopy_da_finish