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/ppc_asm.tmpl> 12#include <asm/processor.h> 13#include <asm/errno.h> 14 15_GLOBAL(strcpy) 16 addi r5,r3,-1 17 addi r4,r4,-1 181: lbzu r0,1(r4) 19 cmpwi 0,r0,0 20 stbu r0,1(r5) 21 bne 1b 22 blr 23 24_GLOBAL(strncpy) 25 cmpwi 0,r5,0 26 beqlr 27 mtctr r5 28 addi r6,r3,-1 29 addi r4,r4,-1 301: lbzu r0,1(r4) 31 cmpwi 0,r0,0 32 stbu r0,1(r6) 33 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ 34 blr 35 36_GLOBAL(strcat) 37 addi r5,r3,-1 38 addi r4,r4,-1 391: lbzu r0,1(r5) 40 cmpwi 0,r0,0 41 bne 1b 42 addi r5,r5,-1 431: lbzu r0,1(r4) 44 cmpwi 0,r0,0 45 stbu r0,1(r5) 46 bne 1b 47 blr 48 49_GLOBAL(strcmp) 50 addi r5,r3,-1 51 addi r4,r4,-1 521: lbzu r3,1(r5) 53 cmpwi 1,r3,0 54 lbzu r0,1(r4) 55 subf. r3,r0,r3 56 beqlr 1 57 beq 1b 58 blr 59 60_GLOBAL(strlen) 61 addi r4,r3,-1 621: lbzu r0,1(r4) 63 cmpwi 0,r0,0 64 bne 1b 65 subf r3,r3,r4 66 blr 67 68_GLOBAL(memset) 69 rlwimi r4,r4,8,16,23 70 rlwimi r4,r4,16,0,15 71 addi r6,r3,-4 72 cmplwi 0,r5,4 73 blt 7f 74 stwu r4,4(r6) 75 beqlr 76 andi. r0,r6,3 77 add r5,r0,r5 78 subf r6,r0,r6 79 srwi r0,r5,2 80 mtctr r0 81 bdz 6f 821: stwu r4,4(r6) 83 bdnz 1b 846: andi. r5,r5,3 857: cmpwi 0,r5,0 86 beqlr 87 mtctr r5 88 addi r6,r6,3 898: stbu r4,1(r6) 90 bdnz 8b 91 blr 92 93_GLOBAL(memmove) 94 cmplw 0,r3,r4 95 bgt .backwards_memcpy 96 b .memcpy 97 98_GLOBAL(backwards_memcpy) 99 rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ 100 add r6,r3,r5 101 add r4,r4,r5 102 beq 2f 103 andi. r0,r6,3 104 mtctr r7 105 bne 5f 1061: lwz r7,-4(r4) 107 lwzu r8,-8(r4) 108 stw r7,-4(r6) 109 stwu r8,-8(r6) 110 bdnz 1b 111 andi. r5,r5,7 1122: cmplwi 0,r5,4 113 blt 3f 114 lwzu r0,-4(r4) 115 subi r5,r5,4 116 stwu r0,-4(r6) 1173: cmpwi 0,r5,0 118 beqlr 119 mtctr r5 1204: lbzu r0,-1(r4) 121 stbu r0,-1(r6) 122 bdnz 4b 123 blr 1245: mtctr r0 1256: lbzu r7,-1(r4) 126 stbu r7,-1(r6) 127 bdnz 6b 128 subf r5,r0,r5 129 rlwinm. r7,r5,32-3,3,31 130 beq 2b 131 mtctr r7 132 b 1b 133 134_GLOBAL(memcmp) 135 cmpwi 0,r5,0 136 ble- 2f 137 mtctr r5 138 addi r6,r3,-1 139 addi r4,r4,-1 1401: lbzu r3,1(r6) 141 lbzu r0,1(r4) 142 subf. r3,r0,r3 143 bdnzt 2,1b 144 blr 1452: li r3,0 146 blr 147 148_GLOBAL(memchr) 149 cmpwi 0,r5,0 150 ble- 2f 151 mtctr r5 152 addi r3,r3,-1 1531: lbzu r0,1(r3) 154 cmpw 0,r0,r4 155 bdnzf 2,1b 156 beqlr 1572: li r3,0 158 blr 159 160_GLOBAL(__clear_user) 161 addi r6,r3,-4 162 li r3,0 163 li r5,0 164 cmplwi 0,r4,4 165 blt 7f 166 /* clear a single word */ 16711: stwu r5,4(r6) 168 beqlr 169 /* clear word sized chunks */ 170 andi. r0,r6,3 171 add r4,r0,r4 172 subf r6,r0,r6 173 srwi r0,r4,2 174 andi. r4,r4,3 175 mtctr r0 176 bdz 7f 1771: stwu r5,4(r6) 178 bdnz 1b 179 /* clear byte sized chunks */ 1807: cmpwi 0,r4,0 181 beqlr 182 mtctr r4 183 addi r6,r6,3 1848: stbu r5,1(r6) 185 bdnz 8b 186 blr 18790: mr r3,r4 188 blr 18991: mfctr r3 190 slwi r3,r3,2 191 add r3,r3,r4 192 blr 19392: mfctr r3 194 blr 195 196 .section __ex_table,"a" 197 .align 3 198 .llong 11b,90b 199 .llong 1b,91b 200 .llong 8b,92b 201 .text 202 203_GLOBAL(__strncpy_from_user) 204 addi r6,r3,-1 205 addi r4,r4,-1 206 cmpwi 0,r5,0 207 beq 2f 208 mtctr r5 2091: lbzu r0,1(r4) 210 cmpwi 0,r0,0 211 stbu r0,1(r6) 212 bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ 213 beq 3f 2142: addi r6,r6,1 2153: subf r3,r3,r6 216 blr 21799: li r3,-EFAULT 218 blr 219 220 .section __ex_table,"a" 221 .align 3 222 .llong 1b,99b 223 .text 224 225/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */ 226_GLOBAL(__strnlen_user) 227 addi r7,r3,-1 228 subf r6,r7,r5 /* top+1 - str */ 229 cmplw 0,r4,r6 230 bge 0f 231 mr r6,r4 2320: mtctr r6 /* ctr = min(len, top - str) */ 2331: lbzu r0,1(r7) /* get next byte */ 234 cmpwi 0,r0,0 235 bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */ 236 addi r7,r7,1 237 subf r3,r3,r7 /* number of bytes we have looked at */ 238 beqlr /* return if we found a 0 byte */ 239 cmpw 0,r3,r4 /* did we look at all len bytes? */ 240 blt 99f /* if not, must have hit top */ 241 addi r3,r4,1 /* return len + 1 to indicate no null found */ 242 blr 24399: li r3,0 /* bad address, return 0 */ 244 blr 245 246 .section __ex_table,"a" 247 .align 3 248 .llong 1b,99b 249