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 cmpwi 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 cmpwi 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 r5,0 74 beqlr 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 85 86_GLOBAL(strlen) 87 addi r4,r3,-1 881: lbzu r0,1(r4) 89 cmpwi 0,r0,0 90 bne 1b 91 subf r3,r3,r4 92 blr 93 94_GLOBAL(memcmp) 95 cmpwi 0,r5,0 96 ble- 2f 97 mtctr r5 98 addi r6,r3,-1 99 addi r4,r4,-1 1001: lbzu r3,1(r6) 101 lbzu r0,1(r4) 102 subf. r3,r0,r3 103 bdnzt 2,1b 104 blr 1052: li r3,0 106 blr 107 108_GLOBAL(memchr) 109 cmpwi 0,r5,0 110 ble- 2f 111 mtctr r5 112 addi r3,r3,-1 1131: lbzu r0,1(r3) 114 cmpw 0,r0,r4 115 bdnzf 2,1b 116 beqlr 1172: li r3,0 118 blr 119 120_GLOBAL(__clear_user) 121 addi r6,r3,-4 122 li r3,0 123 li r5,0 124 cmplwi 0,r4,4 125 blt 7f 126 /* clear a single word */ 12711: stwu r5,4(r6) 128 beqlr 129 /* clear word sized chunks */ 130 andi. r0,r6,3 131 add r4,r0,r4 132 subf r6,r0,r6 133 srwi r0,r4,2 134 andi. r4,r4,3 135 mtctr r0 136 bdz 7f 1371: stwu r5,4(r6) 138 bdnz 1b 139 /* clear byte sized chunks */ 1407: cmpwi 0,r4,0 141 beqlr 142 mtctr r4 143 addi r6,r6,3 1448: stbu r5,1(r6) 145 bdnz 8b 146 blr 14790: mr r3,r4 148 blr 14991: mfctr r3 150 slwi r3,r3,2 151 add r3,r3,r4 152 blr 15392: mfctr r3 154 blr 155 156 .section __ex_table,"a" 157 PPC_LONG 11b,90b 158 PPC_LONG 1b,91b 159 PPC_LONG 8b,92b 160 .text 161 162_GLOBAL(__strncpy_from_user) 163 addi r6,r3,-1 164 addi r4,r4,-1 165 cmpwi 0,r5,0 166 beq 2f 167 mtctr r5 1681: lbzu r0,1(r4) 169 cmpwi 0,r0,0 170 stbu r0,1(r6) 171 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ 172 beq 3f 1732: addi r6,r6,1 1743: subf r3,r3,r6 175 blr 17699: li r3,-EFAULT 177 blr 178 179 .section __ex_table,"a" 180 PPC_LONG 1b,99b 181 .text 182 183/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */ 184_GLOBAL(__strnlen_user) 185 addi r7,r3,-1 186 subf r6,r7,r5 /* top+1 - str */ 187 cmplw 0,r4,r6 188 bge 0f 189 mr r6,r4 1900: mtctr r6 /* ctr = min(len, top - str) */ 1911: lbzu r0,1(r7) /* get next byte */ 192 cmpwi 0,r0,0 193 bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */ 194 addi r7,r7,1 195 subf r3,r3,r7 /* number of bytes we have looked at */ 196 beqlr /* return if we found a 0 byte */ 197 cmpw 0,r3,r4 /* did we look at all len bytes? */ 198 blt 99f /* if not, must have hit top */ 199 addi r3,r4,1 /* return len + 1 to indicate no null found */ 200 blr 20199: li r3,0 /* bad address, return 0 */ 202 blr 203 204 .section __ex_table,"a" 205 PPC_LONG 1b,99b 206