/* * String handling functions for PowerPC. * * Copyright (C) 1996 Paul Mackerras. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #include <asm/processor.h> #include <asm/errno.h> #include <asm/ppc_asm.h> _GLOBAL(strcpy) addi r5,r3,-1 addi r4,r4,-1 1: lbzu r0,1(r4) cmpwi 0,r0,0 stbu r0,1(r5) bne 1b blr _GLOBAL(strncpy) cmpwi 0,r5,0 beqlr mtctr r5 addi r6,r3,-1 addi r4,r4,-1 1: lbzu r0,1(r4) cmpwi 0,r0,0 stbu r0,1(r6) bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ blr _GLOBAL(strcat) addi r5,r3,-1 addi r4,r4,-1 1: lbzu r0,1(r5) cmpwi 0,r0,0 bne 1b addi r5,r5,-1 1: lbzu r0,1(r4) cmpwi 0,r0,0 stbu r0,1(r5) bne 1b blr _GLOBAL(strcmp) addi r5,r3,-1 addi r4,r4,-1 1: lbzu r3,1(r5) cmpwi 1,r3,0 lbzu r0,1(r4) subf. r3,r0,r3 beqlr 1 beq 1b blr _GLOBAL(strlen) addi r4,r3,-1 1: lbzu r0,1(r4) cmpwi 0,r0,0 bne 1b subf r3,r3,r4 blr _GLOBAL(memset) neg r0,r3 rlwimi r4,r4,8,16,23 andi. r0,r0,7 /* # bytes to be 8-byte aligned */ rlwimi r4,r4,16,0,15 cmplw cr1,r5,r0 /* do we get that far? */ rldimi r4,r4,32,0 mtcrf 1,r0 mr r6,r3 blt cr1,8f beq+ 3f /* if already 8-byte aligned */ subf r5,r0,r5 bf 31,1f stb r4,0(r6) addi r6,r6,1 1: bf 30,2f sth r4,0(r6) addi r6,r6,2 2: bf 29,3f stw r4,0(r6) addi r6,r6,4 3: srdi. r0,r5,6 clrldi r5,r5,58 mtctr r0 beq 5f 4: std r4,0(r6) std r4,8(r6) std r4,16(r6) std r4,24(r6) std r4,32(r6) std r4,40(r6) std r4,48(r6) std r4,56(r6) addi r6,r6,64 bdnz 4b 5: srwi. r0,r5,3 clrlwi r5,r5,29 mtcrf 1,r0 beq 8f bf 29,6f std r4,0(r6) std r4,8(r6) std r4,16(r6) std r4,24(r6) addi r6,r6,32 6: bf 30,7f std r4,0(r6) std r4,8(r6) addi r6,r6,16 7: bf 31,8f std r4,0(r6) addi r6,r6,8 8: cmpwi r5,0 mtcrf 1,r5 beqlr+ bf 29,9f stw r4,0(r6) addi r6,r6,4 9: bf 30,10f sth r4,0(r6) addi r6,r6,2 10: bflr 31 stb r4,0(r6) blr _GLOBAL(memmove) cmplw 0,r3,r4 bgt .backwards_memcpy b .memcpy _GLOBAL(backwards_memcpy) rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ add r6,r3,r5 add r4,r4,r5 beq 2f andi. r0,r6,3 mtctr r7 bne 5f 1: lwz r7,-4(r4) lwzu r8,-8(r4) stw r7,-4(r6) stwu r8,-8(r6) bdnz 1b andi. r5,r5,7 2: cmplwi 0,r5,4 blt 3f lwzu r0,-4(r4) subi r5,r5,4 stwu r0,-4(r6) 3: cmpwi 0,r5,0 beqlr mtctr r5 4: lbzu r0,-1(r4) stbu r0,-1(r6) bdnz 4b blr 5: mtctr r0 6: lbzu r7,-1(r4) stbu r7,-1(r6) bdnz 6b subf r5,r0,r5 rlwinm. r7,r5,32-3,3,31 beq 2b mtctr r7 b 1b _GLOBAL(memcmp) cmpwi 0,r5,0 ble- 2f mtctr r5 addi r6,r3,-1 addi r4,r4,-1 1: lbzu r3,1(r6) lbzu r0,1(r4) subf. r3,r0,r3 bdnzt 2,1b blr 2: li r3,0 blr _GLOBAL(memchr) cmpwi 0,r5,0 ble- 2f mtctr r5 addi r3,r3,-1 1: lbzu r0,1(r3) cmpw 0,r0,r4 bdnzf 2,1b beqlr 2: li r3,0 blr _GLOBAL(__clear_user) addi r6,r3,-4 li r3,0 li r5,0 cmplwi 0,r4,4 blt 7f /* clear a single word */ 11: stwu r5,4(r6) beqlr /* clear word sized chunks */ andi. r0,r6,3 add r4,r0,r4 subf r6,r0,r6 srwi r0,r4,2 andi. r4,r4,3 mtctr r0 bdz 7f 1: stwu r5,4(r6) bdnz 1b /* clear byte sized chunks */ 7: cmpwi 0,r4,0 beqlr mtctr r4 addi r6,r6,3 8: stbu r5,1(r6) bdnz 8b blr 90: mr r3,r4 blr 91: mfctr r3 slwi r3,r3,2 add r3,r3,r4 blr 92: mfctr r3 blr .section __ex_table,"a" .align 3 .llong 11b,90b .llong 1b,91b .llong 8b,92b .text /* r3 = dst, r4 = src, r5 = count */ _GLOBAL(__strncpy_from_user) addi r6,r3,-1 addi r4,r4,-1 cmpwi 0,r5,0 beq 2f mtctr r5 1: lbzu r0,1(r4) cmpwi 0,r0,0 stbu r0,1(r6) bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ beq 3f 2: addi r6,r6,1 3: subf r3,r3,r6 blr 99: li r3,-EFAULT blr .section __ex_table,"a" .align 3 .llong 1b,99b .text /* r3 = str, r4 = len (> 0) */ _GLOBAL(__strnlen_user) addi r7,r3,-1 mtctr r4 /* ctr = len */ 1: lbzu r0,1(r7) /* get next byte */ cmpwi 0,r0,0 bdnzf 2,1b /* loop if --ctr != 0 && byte != 0 */ addi r7,r7,1 subf r3,r3,r7 /* number of bytes we have looked at */ beqlr /* return if we found a 0 byte */ cmpw 0,r3,r4 /* did we look at all len bytes? */ blt 99f /* if not, must have hit top */ addi r3,r4,1 /* return len + 1 to indicate no null found */ blr 99: li r3,0 /* bad address, return 0 */ blr .section __ex_table,"a" .align 3 .llong 1b,99b