| Haavard Skinnemoen | 5f97f7f | 2006-09-25 23:32:13 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2004-2006 Atmel Corporation | 
|  | 3 | * | 
|  | 4 | * This program is free software; you can redistribute it and/or modify | 
|  | 5 | * it under the terms of the GNU General Public License version 2 as | 
|  | 6 | * published by the Free Software Foundation. | 
|  | 7 | */ | 
|  | 8 |  | 
|  | 9 | /* | 
|  | 10 | * void *memcpy(void *to, const void *from, unsigned long n) | 
|  | 11 | * | 
|  | 12 | * This implementation does word-aligned loads in the main loop, | 
|  | 13 | * possibly sacrificing alignment of stores. | 
|  | 14 | * | 
|  | 15 | * Hopefully, in most cases, both "to" and "from" will be | 
|  | 16 | * word-aligned to begin with. | 
|  | 17 | */ | 
|  | 18 | .text | 
|  | 19 | .global	memcpy | 
|  | 20 | .type	memcpy, @function | 
|  | 21 | memcpy: | 
|  | 22 | mov	r9, r11 | 
|  | 23 | andl	r9, 3, COH | 
|  | 24 | brne	1f | 
|  | 25 |  | 
|  | 26 | /* At this point, "from" is word-aligned */ | 
|  | 27 | 2:	sub	r10, 4 | 
|  | 28 | mov	r9, r12 | 
|  | 29 | brlt	4f | 
|  | 30 |  | 
|  | 31 | 3:	ld.w	r8, r11++ | 
|  | 32 | sub	r10, 4 | 
|  | 33 | st.w	r12++, r8 | 
|  | 34 | brge	3b | 
|  | 35 |  | 
|  | 36 | 4:	neg	r10 | 
|  | 37 | reteq	r9 | 
|  | 38 |  | 
|  | 39 | /* Handle unaligned count */ | 
|  | 40 | lsl	r10, 2 | 
|  | 41 | add	pc, pc, r10 | 
|  | 42 | ld.ub	r8, r11++ | 
|  | 43 | st.b	r12++, r8 | 
|  | 44 | ld.ub	r8, r11++ | 
|  | 45 | st.b	r12++, r8 | 
|  | 46 | ld.ub	r8, r11++ | 
|  | 47 | st.b	r12++, r8 | 
|  | 48 | retal	r9 | 
|  | 49 |  | 
|  | 50 | /* Handle unaligned "from" pointer */ | 
|  | 51 | 1:	sub	r10, 4 | 
|  | 52 | brlt	4b | 
|  | 53 | add	r10, r9 | 
|  | 54 | lsl	r9, 2 | 
|  | 55 | add	pc, pc, r9 | 
|  | 56 | ld.ub	r8, r11++ | 
|  | 57 | st.b	r12++, r8 | 
|  | 58 | ld.ub	r8, r11++ | 
|  | 59 | st.b	r12++, r8 | 
|  | 60 | ld.ub	r8, r11++ | 
|  | 61 | st.b	r12++, r8 | 
|  | 62 | rjmp	2b |