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 PPC_LONG_ALIGN 17 .text 18 19_GLOBAL(strcpy) 20 addi r5,r3,-1 21 addi r4,r4,-1 221: lbzu r0,1(r4) 23 cmpwi 0,r0,0 24 stbu r0,1(r5) 25 bne 1b 26 blr 27 28/* This clears out any unused part of the destination buffer, 29 just as the libc version does. -- paulus */ 30_GLOBAL(strncpy) 31 PPC_LCMPI 0,r5,0 32 beqlr 33 mtctr r5 34 addi r6,r3,-1 35 addi r4,r4,-1 361: lbzu r0,1(r4) 37 cmpwi 0,r0,0 38 stbu r0,1(r6) 39 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ 40 bnelr /* if we didn't hit a null char, we're done */ 41 mfctr r5 42 PPC_LCMPI 0,r5,0 /* any space left in destination buffer? */ 43 beqlr /* we know r0 == 0 here */ 442: stbu r0,1(r6) /* clear it out if so */ 45 bdnz 2b 46 blr 47 48_GLOBAL(strcat) 49 addi r5,r3,-1 50 addi r4,r4,-1 511: lbzu r0,1(r5) 52 cmpwi 0,r0,0 53 bne 1b 54 addi r5,r5,-1 551: lbzu r0,1(r4) 56 cmpwi 0,r0,0 57 stbu r0,1(r5) 58 bne 1b 59 blr 60 61_GLOBAL(strcmp) 62 addi r5,r3,-1 63 addi r4,r4,-1 641: lbzu r3,1(r5) 65 cmpwi 1,r3,0 66 lbzu r0,1(r4) 67 subf. r3,r0,r3 68 beqlr 1 69 beq 1b 70 blr 71 72_GLOBAL(strncmp) 73 PPC_LCMPI 0,r5,0 74 beq- 2f 75 mtctr r5 76 addi r5,r3,-1 77 addi r4,r4,-1 781: lbzu r3,1(r5) 79 cmpwi 1,r3,0 80 lbzu r0,1(r4) 81 subf. r3,r0,r3 82 beqlr 1 83 bdnzt eq,1b 84 blr 852: li r3,0 86 blr 87 88_GLOBAL(strlen) 89 addi r4,r3,-1 901: lbzu r0,1(r4) 91 cmpwi 0,r0,0 92 bne 1b 93 subf r3,r3,r4 94 blr 95 96_GLOBAL(memcmp) 97 PPC_LCMPI 0,r5,0 98 beq- 2f 99 mtctr r5 100 addi r6,r3,-1 101 addi r4,r4,-1 1021: lbzu r3,1(r6) 103 lbzu r0,1(r4) 104 subf. r3,r0,r3 105 bdnzt 2,1b 106 blr 1072: li r3,0 108 blr 109 110_GLOBAL(memchr) 111 PPC_LCMPI 0,r5,0 112 beq- 2f 113 mtctr r5 114 addi r3,r3,-1 1151: lbzu r0,1(r3) 116 cmpw 0,r0,r4 117 bdnzf 2,1b 118 beqlr 1192: li r3,0 120 blr 121 122_GLOBAL(__clear_user) 123 addi r6,r3,-4 124 li r3,0 125 li r5,0 126 cmplwi 0,r4,4 127 blt 7f 128 /* clear a single word */ 12911: stwu r5,4(r6) 130 beqlr 131 /* clear word sized chunks */ 132 andi. r0,r6,3 133 add r4,r0,r4 134 subf r6,r0,r6 135 srwi r0,r4,2 136 andi. r4,r4,3 137 mtctr r0 138 bdz 7f 1391: stwu r5,4(r6) 140 bdnz 1b 141 /* clear byte sized chunks */ 1427: cmpwi 0,r4,0 143 beqlr 144 mtctr r4 145 addi r6,r6,3 1468: stbu r5,1(r6) 147 bdnz 8b 148 blr 14990: mr r3,r4 150 blr 15191: mfctr r3 152 slwi r3,r3,2 153 add r3,r3,r4 154 blr 15592: mfctr r3 156 blr 157 158 .section __ex_table,"a" 159 PPC_LONG 11b,90b 160 PPC_LONG 1b,91b 161 PPC_LONG 8b,92b 162 .text 163 164_GLOBAL(__strncpy_from_user) 165 addi r6,r3,-1 166 addi r4,r4,-1 167 cmpwi 0,r5,0 168 beq 2f 169 mtctr r5 1701: lbzu r0,1(r4) 171 cmpwi 0,r0,0 172 stbu r0,1(r6) 173 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ 174 beq 3f 1752: addi r6,r6,1 1763: subf r3,r3,r6 177 blr 17899: li r3,-EFAULT 179 blr 180 181 .section __ex_table,"a" 182 PPC_LONG 1b,99b 183 .text 184 185/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */ 186_GLOBAL(__strnlen_user) 187 addi r7,r3,-1 188 subf r6,r7,r5 /* top+1 - str */ 189 cmplw 0,r4,r6 190 bge 0f 191 mr r6,r4 1920: mtctr r6 /* ctr = min(len, top - str) */ 1931: lbzu r0,1(r7) /* get next byte */ 194 cmpwi 0,r0,0 195 bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */ 196 addi r7,r7,1 197 subf r3,r3,r7 /* number of bytes we have looked at */ 198 beqlr /* return if we found a 0 byte */ 199 cmpw 0,r3,r4 /* did we look at all len bytes? */ 200 blt 99f /* if not, must have hit top */ 201 addi r3,r4,1 /* return len + 1 to indicate no null found */ 202 blr 20399: li r3,0 /* bad address, return 0 */ 204 blr 205 206 .section __ex_table,"a" 207 PPC_LONG 1b,99b 208