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 <asm/processor.h> 12#include <asm/errno.h> 13#include <asm/ppc_asm.h> 14 15 .section __ex_table,"a" 16#ifdef CONFIG_PPC64 17 .align 3 18#define EXTBL .llong 19#else 20 .align 2 21#define EXTBL .long 22#endif 23 .text 24 25_GLOBAL(strcpy) 26 addi r5,r3,-1 27 addi r4,r4,-1 281: lbzu r0,1(r4) 29 cmpwi 0,r0,0 30 stbu r0,1(r5) 31 bne 1b 32 blr 33 34/* This clears out any unused part of the destination buffer, 35 just as the libc version does. -- paulus */ 36_GLOBAL(strncpy) 37 cmpwi 0,r5,0 38 beqlr 39 mtctr r5 40 addi r6,r3,-1 41 addi r4,r4,-1 421: lbzu r0,1(r4) 43 cmpwi 0,r0,0 44 stbu r0,1(r6) 45 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ 46 bnelr /* if we didn't hit a null char, we're done */ 47 mfctr r5 48 cmpwi 0,r5,0 /* any space left in destination buffer? */ 49 beqlr /* we know r0 == 0 here */ 502: stbu r0,1(r6) /* clear it out if so */ 51 bdnz 2b 52 blr 53 54_GLOBAL(strcat) 55 addi r5,r3,-1 56 addi r4,r4,-1 571: lbzu r0,1(r5) 58 cmpwi 0,r0,0 59 bne 1b 60 addi r5,r5,-1 611: lbzu r0,1(r4) 62 cmpwi 0,r0,0 63 stbu r0,1(r5) 64 bne 1b 65 blr 66 67_GLOBAL(strcmp) 68 addi r5,r3,-1 69 addi r4,r4,-1 701: lbzu r3,1(r5) 71 cmpwi 1,r3,0 72 lbzu r0,1(r4) 73 subf. r3,r0,r3 74 beqlr 1 75 beq 1b 76 blr 77 78_GLOBAL(strlen) 79 addi r4,r3,-1 801: lbzu r0,1(r4) 81 cmpwi 0,r0,0 82 bne 1b 83 subf r3,r3,r4 84 blr 85 86_GLOBAL(memcmp) 87 cmpwi 0,r5,0 88 ble- 2f 89 mtctr r5 90 addi r6,r3,-1 91 addi r4,r4,-1 921: lbzu r3,1(r6) 93 lbzu r0,1(r4) 94 subf. r3,r0,r3 95 bdnzt 2,1b 96 blr 972: li r3,0 98 blr 99 100_GLOBAL(memchr) 101 cmpwi 0,r5,0 102 ble- 2f 103 mtctr r5 104 addi r3,r3,-1 1051: lbzu r0,1(r3) 106 cmpw 0,r0,r4 107 bdnzf 2,1b 108 beqlr 1092: li r3,0 110 blr 111 112_GLOBAL(__clear_user) 113 addi r6,r3,-4 114 li r3,0 115 li r5,0 116 cmplwi 0,r4,4 117 blt 7f 118 /* clear a single word */ 11911: stwu r5,4(r6) 120 beqlr 121 /* clear word sized chunks */ 122 andi. r0,r6,3 123 add r4,r0,r4 124 subf r6,r0,r6 125 srwi r0,r4,2 126 andi. r4,r4,3 127 mtctr r0 128 bdz 7f 1291: stwu r5,4(r6) 130 bdnz 1b 131 /* clear byte sized chunks */ 1327: cmpwi 0,r4,0 133 beqlr 134 mtctr r4 135 addi r6,r6,3 1368: stbu r5,1(r6) 137 bdnz 8b 138 blr 13990: mr r3,r4 140 blr 14191: mfctr r3 142 slwi r3,r3,2 143 add r3,r3,r4 144 blr 14592: mfctr r3 146 blr 147 148 .section __ex_table,"a" 149 EXTBL 11b,90b 150 EXTBL 1b,91b 151 EXTBL 8b,92b 152 .text 153 154_GLOBAL(__strncpy_from_user) 155 addi r6,r3,-1 156 addi r4,r4,-1 157 cmpwi 0,r5,0 158 beq 2f 159 mtctr r5 1601: lbzu r0,1(r4) 161 cmpwi 0,r0,0 162 stbu r0,1(r6) 163 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ 164 beq 3f 1652: addi r6,r6,1 1663: subf r3,r3,r6 167 blr 16899: li r3,-EFAULT 169 blr 170 171 .section __ex_table,"a" 172 EXTBL 1b,99b 173 .text 174 175/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */ 176_GLOBAL(__strnlen_user) 177 addi r7,r3,-1 178 subf r6,r7,r5 /* top+1 - str */ 179 cmplw 0,r4,r6 180 bge 0f 181 mr r6,r4 1820: mtctr r6 /* ctr = min(len, top - str) */ 1831: lbzu r0,1(r7) /* get next byte */ 184 cmpwi 0,r0,0 185 bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */ 186 addi r7,r7,1 187 subf r3,r3,r7 /* number of bytes we have looked at */ 188 beqlr /* return if we found a 0 byte */ 189 cmpw 0,r3,r4 /* did we look at all len bytes? */ 190 blt 99f /* if not, must have hit top */ 191 addi r3,r4,1 /* return len + 1 to indicate no null found */ 192 blr 19399: li r3,0 /* bad address, return 0 */ 194 blr 195 196 .section __ex_table,"a" 197 EXTBL 1b,99b 198