1/* 2 * String handling functions. 3 * 4 * Copyright IBM Corp. 2012 5 */ 6 7#include <linux/linkage.h> 8#include <asm/export.h> 9 10/* 11 * void *memmove(void *dest, const void *src, size_t n) 12 */ 13ENTRY(memmove) 14 ltgr %r4,%r4 15 lgr %r1,%r2 16 bzr %r14 17 aghi %r4,-1 18 clgr %r2,%r3 19 jnh .Lmemmove_forward 20 la %r5,1(%r4,%r3) 21 clgr %r2,%r5 22 jl .Lmemmove_reverse 23.Lmemmove_forward: 24 srlg %r0,%r4,8 25 ltgr %r0,%r0 26 jz .Lmemmove_forward_remainder 27.Lmemmove_forward_loop: 28 mvc 0(256,%r1),0(%r3) 29 la %r1,256(%r1) 30 la %r3,256(%r3) 31 brctg %r0,.Lmemmove_forward_loop 32.Lmemmove_forward_remainder: 33 larl %r5,.Lmemmove_mvc 34 ex %r4,0(%r5) 35 br %r14 36.Lmemmove_reverse: 37 ic %r0,0(%r4,%r3) 38 stc %r0,0(%r4,%r1) 39 brctg %r4,.Lmemmove_reverse 40 ic %r0,0(%r4,%r3) 41 stc %r0,0(%r4,%r1) 42 br %r14 43.Lmemmove_mvc: 44 mvc 0(1,%r1),0(%r3) 45EXPORT_SYMBOL(memmove) 46 47/* 48 * memset implementation 49 * 50 * This code corresponds to the C construct below. We do distinguish 51 * between clearing (c == 0) and setting a memory array (c != 0) simply 52 * because nearly all memset invocations in the kernel clear memory and 53 * the xc instruction is preferred in such cases. 54 * 55 * void *memset(void *s, int c, size_t n) 56 * { 57 * if (likely(c == 0)) 58 * return __builtin_memset(s, 0, n); 59 * return __builtin_memset(s, c, n); 60 * } 61 */ 62ENTRY(memset) 63 ltgr %r4,%r4 64 bzr %r14 65 ltgr %r3,%r3 66 jnz .Lmemset_fill 67 aghi %r4,-1 68 srlg %r3,%r4,8 69 ltgr %r3,%r3 70 lgr %r1,%r2 71 jz .Lmemset_clear_remainder 72.Lmemset_clear_loop: 73 xc 0(256,%r1),0(%r1) 74 la %r1,256(%r1) 75 brctg %r3,.Lmemset_clear_loop 76.Lmemset_clear_remainder: 77 larl %r3,.Lmemset_xc 78 ex %r4,0(%r3) 79 br %r14 80.Lmemset_fill: 81 stc %r3,0(%r2) 82 cghi %r4,1 83 lgr %r1,%r2 84 ber %r14 85 aghi %r4,-2 86 srlg %r3,%r4,8 87 ltgr %r3,%r3 88 jz .Lmemset_fill_remainder 89.Lmemset_fill_loop: 90 mvc 1(256,%r1),0(%r1) 91 la %r1,256(%r1) 92 brctg %r3,.Lmemset_fill_loop 93.Lmemset_fill_remainder: 94 larl %r3,.Lmemset_mvc 95 ex %r4,0(%r3) 96 br %r14 97.Lmemset_xc: 98 xc 0(1,%r1),0(%r1) 99.Lmemset_mvc: 100 mvc 1(1,%r1),0(%r1) 101EXPORT_SYMBOL(memset) 102 103/* 104 * memcpy implementation 105 * 106 * void *memcpy(void *dest, const void *src, size_t n) 107 */ 108ENTRY(memcpy) 109 ltgr %r4,%r4 110 bzr %r14 111 aghi %r4,-1 112 srlg %r5,%r4,8 113 ltgr %r5,%r5 114 lgr %r1,%r2 115 jnz .Lmemcpy_loop 116.Lmemcpy_remainder: 117 larl %r5,.Lmemcpy_mvc 118 ex %r4,0(%r5) 119 br %r14 120.Lmemcpy_loop: 121 mvc 0(256,%r1),0(%r3) 122 la %r1,256(%r1) 123 la %r3,256(%r3) 124 brctg %r5,.Lmemcpy_loop 125 j .Lmemcpy_remainder 126.Lmemcpy_mvc: 127 mvc 0(1,%r1),0(%r3) 128EXPORT_SYMBOL(memcpy) 129