1/* 2 * String handling functions for PowerPC. 3 * 4 * Copyright (C) 1996 Paul Mackerras. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11#include <linux/config.h> 12#include <asm/processor.h> 13#include <asm/errno.h> 14#include <asm/ppc_asm.h> 15 16 .section __ex_table,"a" 17#ifdef CONFIG_PPC64 18 .align 3 19#define EXTBL .llong 20#else 21 .align 2 22#define EXTBL .long 23#endif 24 .text 25 26_GLOBAL(strcpy) 27 addi r5,r3,-1 28 addi r4,r4,-1 291: lbzu r0,1(r4) 30 cmpwi 0,r0,0 31 stbu r0,1(r5) 32 bne 1b 33 blr 34 35/* This clears out any unused part of the destination buffer, 36 just as the libc version does. -- paulus */ 37_GLOBAL(strncpy) 38 cmpwi 0,r5,0 39 beqlr 40 mtctr r5 41 addi r6,r3,-1 42 addi r4,r4,-1 431: lbzu r0,1(r4) 44 cmpwi 0,r0,0 45 stbu r0,1(r6) 46 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ 47 bnelr /* if we didn't hit a null char, we're done */ 48 mfctr r5 49 cmpwi 0,r5,0 /* any space left in destination buffer? */ 50 beqlr /* we know r0 == 0 here */ 512: stbu r0,1(r6) /* clear it out if so */ 52 bdnz 2b 53 blr 54 55_GLOBAL(strcat) 56 addi r5,r3,-1 57 addi r4,r4,-1 581: lbzu r0,1(r5) 59 cmpwi 0,r0,0 60 bne 1b 61 addi r5,r5,-1 621: lbzu r0,1(r4) 63 cmpwi 0,r0,0 64 stbu r0,1(r5) 65 bne 1b 66 blr 67 68_GLOBAL(strcmp) 69 addi r5,r3,-1 70 addi r4,r4,-1 711: lbzu r3,1(r5) 72 cmpwi 1,r3,0 73 lbzu r0,1(r4) 74 subf. r3,r0,r3 75 beqlr 1 76 beq 1b 77 blr 78 79_GLOBAL(strlen) 80 addi r4,r3,-1 811: lbzu r0,1(r4) 82 cmpwi 0,r0,0 83 bne 1b 84 subf r3,r3,r4 85 blr 86 87_GLOBAL(memcmp) 88 cmpwi 0,r5,0 89 ble- 2f 90 mtctr r5 91 addi r6,r3,-1 92 addi r4,r4,-1 931: lbzu r3,1(r6) 94 lbzu r0,1(r4) 95 subf. r3,r0,r3 96 bdnzt 2,1b 97 blr 982: li r3,0 99 blr 100 101_GLOBAL(memchr) 102 cmpwi 0,r5,0 103 ble- 2f 104 mtctr r5 105 addi r3,r3,-1 1061: lbzu r0,1(r3) 107 cmpw 0,r0,r4 108 bdnzf 2,1b 109 beqlr 1102: li r3,0 111 blr 112 113_GLOBAL(__clear_user) 114 addi r6,r3,-4 115 li r3,0 116 li r5,0 117 cmplwi 0,r4,4 118 blt 7f 119 /* clear a single word */ 12011: stwu r5,4(r6) 121 beqlr 122 /* clear word sized chunks */ 123 andi. r0,r6,3 124 add r4,r0,r4 125 subf r6,r0,r6 126 srwi r0,r4,2 127 andi. r4,r4,3 128 mtctr r0 129 bdz 7f 1301: stwu r5,4(r6) 131 bdnz 1b 132 /* clear byte sized chunks */ 1337: cmpwi 0,r4,0 134 beqlr 135 mtctr r4 136 addi r6,r6,3 1378: stbu r5,1(r6) 138 bdnz 8b 139 blr 14090: mr r3,r4 141 blr 14291: mfctr r3 143 slwi r3,r3,2 144 add r3,r3,r4 145 blr 14692: mfctr r3 147 blr 148 149 .section __ex_table,"a" 150 EXTBL 11b,90b 151 EXTBL 1b,91b 152 EXTBL 8b,92b 153 .text 154 155_GLOBAL(__strncpy_from_user) 156 addi r6,r3,-1 157 addi r4,r4,-1 158 cmpwi 0,r5,0 159 beq 2f 160 mtctr r5 1611: lbzu r0,1(r4) 162 cmpwi 0,r0,0 163 stbu r0,1(r6) 164 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ 165 beq 3f 1662: addi r6,r6,1 1673: subf r3,r3,r6 168 blr 16999: li r3,-EFAULT 170 blr 171 172 .section __ex_table,"a" 173 EXTBL 1b,99b 174 .text 175 176/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */ 177_GLOBAL(__strnlen_user) 178 addi r7,r3,-1 179 subf r6,r7,r5 /* top+1 - str */ 180 cmplw 0,r4,r6 181 bge 0f 182 mr r6,r4 1830: mtctr r6 /* ctr = min(len, top - str) */ 1841: lbzu r0,1(r7) /* get next byte */ 185 cmpwi 0,r0,0 186 bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */ 187 addi r7,r7,1 188 subf r3,r3,r7 /* number of bytes we have looked at */ 189 beqlr /* return if we found a 0 byte */ 190 cmpw 0,r3,r4 /* did we look at all len bytes? */ 191 blt 99f /* if not, must have hit top */ 192 addi r3,r4,1 /* return len + 1 to indicate no null found */ 193 blr 19499: li r3,0 /* bad address, return 0 */ 195 blr 196 197 .section __ex_table,"a" 198 EXTBL 1b,99b 199