| Heiko Carstens | 535c611 | 2012-08-14 13:20:20 +0200 | [diff] [blame] | 1 | /* | 
 | 2 |  * String handling functions. | 
 | 3 |  * | 
 | 4 |  * Copyright IBM Corp. 2012 | 
 | 5 |  */ | 
 | 6 |  | 
 | 7 | #include <linux/linkage.h> | 
 | 8 |  | 
 | 9 | /* | 
 | 10 |  * memset implementation | 
 | 11 |  * | 
 | 12 |  * This code corresponds to the C construct below. We do distinguish | 
 | 13 |  * between clearing (c == 0) and setting a memory array (c != 0) simply | 
 | 14 |  * because nearly all memset invocations in the kernel clear memory and | 
 | 15 |  * the xc instruction is preferred in such cases. | 
 | 16 |  * | 
 | 17 |  * void *memset(void *s, int c, size_t n) | 
 | 18 |  * { | 
 | 19 |  *	if (likely(c == 0)) | 
 | 20 |  *		return __builtin_memset(s, 0, n); | 
 | 21 |  *	return __builtin_memset(s, c, n); | 
 | 22 |  * } | 
 | 23 |  */ | 
 | 24 | ENTRY(memset) | 
 | 25 | 	basr	%r5,%r0 | 
 | 26 | .Lmemset_base: | 
 | 27 | 	ltr	%r4,%r4 | 
 | 28 | 	bzr	%r14 | 
 | 29 | 	ltr	%r3,%r3 | 
 | 30 | 	jnz	.Lmemset_fill | 
 | 31 | 	ahi	%r4,-1 | 
 | 32 | 	lr	%r3,%r4 | 
 | 33 | 	srl	%r3,8 | 
 | 34 | 	ltr	%r3,%r3 | 
 | 35 | 	lr	%r1,%r2 | 
 | 36 | 	je	.Lmemset_clear_rest | 
 | 37 | .Lmemset_clear_loop: | 
 | 38 | 	xc	0(256,%r1),0(%r1) | 
 | 39 | 	la	%r1,256(%r1) | 
 | 40 | 	brct	%r3,.Lmemset_clear_loop | 
 | 41 | .Lmemset_clear_rest: | 
 | 42 | 	ex	%r4,.Lmemset_xc-.Lmemset_base(%r5) | 
 | 43 | 	br	%r14 | 
 | 44 | .Lmemset_fill: | 
 | 45 | 	stc	%r3,0(%r2) | 
 | 46 | 	chi	%r4,1 | 
 | 47 | 	lr	%r1,%r2 | 
 | 48 | 	ber	%r14 | 
 | 49 | 	ahi	%r4,-2 | 
 | 50 | 	lr	%r3,%r4 | 
 | 51 | 	srl	%r3,8 | 
 | 52 | 	ltr	%r3,%r3 | 
 | 53 | 	je	.Lmemset_fill_rest | 
 | 54 | .Lmemset_fill_loop: | 
 | 55 | 	mvc	1(256,%r1),0(%r1) | 
 | 56 | 	la	%r1,256(%r1) | 
 | 57 | 	brct	%r3,.Lmemset_fill_loop | 
 | 58 | .Lmemset_fill_rest: | 
 | 59 | 	ex	%r4,.Lmemset_mvc-.Lmemset_base(%r5) | 
 | 60 | 	br	%r14 | 
 | 61 | .Lmemset_xc: | 
 | 62 | 	xc	0(1,%r1),0(%r1) | 
 | 63 | .Lmemset_mvc: | 
 | 64 | 	mvc	1(1,%r1),0(%r1) | 
 | 65 |  | 
 | 66 | /* | 
 | 67 |  * memcpy implementation | 
 | 68 |  * | 
 | 69 |  * void *memcpy(void *dest, const void *src, size_t n) | 
 | 70 |  */ | 
 | 71 | ENTRY(memcpy) | 
 | 72 | 	basr	%r5,%r0 | 
 | 73 | .Lmemcpy_base: | 
 | 74 | 	ltr	%r4,%r4 | 
 | 75 | 	bzr	%r14 | 
 | 76 | 	ahi	%r4,-1 | 
 | 77 | 	lr	%r0,%r4 | 
 | 78 | 	srl	%r0,8 | 
 | 79 | 	ltr	%r0,%r0 | 
 | 80 | 	lr	%r1,%r2 | 
 | 81 | 	jnz	.Lmemcpy_loop | 
 | 82 | .Lmemcpy_rest: | 
 | 83 | 	ex	%r4,.Lmemcpy_mvc-.Lmemcpy_base(%r5) | 
 | 84 | 	br	%r14 | 
 | 85 | .Lmemcpy_loop: | 
 | 86 | 	mvc	0(256,%r1),0(%r3) | 
 | 87 | 	la	%r1,256(%r1) | 
 | 88 | 	la	%r3,256(%r3) | 
 | 89 | 	brct	%r0,.Lmemcpy_loop | 
 | 90 | 	j	.Lmemcpy_rest | 
 | 91 | .Lmemcpy_mvc: | 
 | 92 | 	mvc	0(1,%r1),0(%r3) |