Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Copyright (C) Paul Mackerras 1997.
0004  *
0005  * NOTE: this code runs in 32 bit mode and is packaged as ELF32.
0006  */
0007 
0008 #include "ppc_asm.h"
0009 
0010     .text
0011     .globl  strcpy
0012 strcpy:
0013     addi    r5,r3,-1
0014     addi    r4,r4,-1
0015 1:  lbzu    r0,1(r4)
0016     cmpwi   0,r0,0
0017     stbu    r0,1(r5)
0018     bne 1b
0019     blr
0020 
0021     .globl  strncpy
0022 strncpy:
0023     cmpwi   0,r5,0
0024     beqlr
0025     mtctr   r5
0026     addi    r6,r3,-1
0027     addi    r4,r4,-1
0028 1:  lbzu    r0,1(r4)
0029     cmpwi   0,r0,0
0030     stbu    r0,1(r6)
0031     bdnzf   2,1b        /* dec ctr, branch if ctr != 0 && !cr0.eq */
0032     blr
0033 
0034     .globl  strcat
0035 strcat:
0036     addi    r5,r3,-1
0037     addi    r4,r4,-1
0038 1:  lbzu    r0,1(r5)
0039     cmpwi   0,r0,0
0040     bne 1b
0041     addi    r5,r5,-1
0042 1:  lbzu    r0,1(r4)
0043     cmpwi   0,r0,0
0044     stbu    r0,1(r5)
0045     bne 1b
0046     blr
0047 
0048     .globl  strchr
0049 strchr:
0050     addi    r3,r3,-1
0051 1:  lbzu    r0,1(r3)
0052     cmpw    0,r0,r4
0053     beqlr
0054     cmpwi   0,r0,0
0055     bne 1b
0056     li  r3,0
0057     blr
0058 
0059     .globl  strcmp
0060 strcmp:
0061     addi    r5,r3,-1
0062     addi    r4,r4,-1
0063 1:  lbzu    r3,1(r5)
0064     cmpwi   1,r3,0
0065     lbzu    r0,1(r4)
0066     subf.   r3,r0,r3
0067     beqlr   1
0068     beq 1b
0069     blr
0070 
0071     .globl  strncmp
0072 strncmp:
0073     mtctr   r5
0074     addi    r5,r3,-1
0075     addi    r4,r4,-1
0076 1:  lbzu    r3,1(r5)
0077     cmpwi   1,r3,0
0078     lbzu    r0,1(r4)
0079     subf.   r3,r0,r3
0080     beqlr   1
0081     bdnzt   eq,1b
0082     blr
0083 
0084     .globl  strlen
0085 strlen:
0086     addi    r4,r3,-1
0087 1:  lbzu    r0,1(r4)
0088     cmpwi   0,r0,0
0089     bne 1b
0090     subf    r3,r3,r4
0091     blr
0092 
0093     .globl  memset
0094 memset:
0095     rlwimi  r4,r4,8,16,23
0096     rlwimi  r4,r4,16,0,15
0097     addi    r6,r3,-4
0098     cmplwi  0,r5,4
0099     blt 7f
0100     stwu    r4,4(r6)
0101     beqlr
0102     andi.   r0,r6,3
0103     add r5,r0,r5
0104     subf    r6,r0,r6
0105     rlwinm  r0,r5,32-2,2,31
0106     mtctr   r0
0107     bdz 6f
0108 1:  stwu    r4,4(r6)
0109     bdnz    1b
0110 6:  andi.   r5,r5,3
0111 7:  cmpwi   0,r5,0
0112     beqlr
0113     mtctr   r5
0114     addi    r6,r6,3
0115 8:  stbu    r4,1(r6)
0116     bdnz    8b
0117     blr
0118 
0119     .globl  memmove
0120 memmove:
0121     cmplw   0,r3,r4
0122     bgt backwards_memcpy
0123     /* fall through */
0124 
0125     .globl  memcpy
0126 memcpy:
0127     rlwinm. r7,r5,32-3,3,31     /* r7 = r5 >> 3 */
0128     addi    r6,r3,-4
0129     addi    r4,r4,-4
0130     beq 3f          /* if less than 8 bytes to do */
0131     andi.   r0,r6,3         /* get dest word aligned */
0132     mtctr   r7
0133     bne 5f
0134     andi.   r0,r4,3         /* check src word aligned too */
0135     bne 3f
0136 1:  lwz r7,4(r4)
0137     lwzu    r8,8(r4)
0138     stw r7,4(r6)
0139     stwu    r8,8(r6)
0140     bdnz    1b
0141     andi.   r5,r5,7
0142 2:  cmplwi  0,r5,4
0143     blt 3f
0144     lwzu    r0,4(r4)
0145     addi    r5,r5,-4
0146     stwu    r0,4(r6)
0147 3:  cmpwi   0,r5,0
0148     beqlr
0149     mtctr   r5
0150     addi    r4,r4,3
0151     addi    r6,r6,3
0152 4:  lbzu    r0,1(r4)
0153     stbu    r0,1(r6)
0154     bdnz    4b
0155     blr
0156 5:  subfic  r0,r0,4
0157     cmpw    cr1,r0,r5
0158     add r7,r0,r4
0159     andi.   r7,r7,3         /* will source be word-aligned too? */
0160     ble cr1,3b
0161     bne 3b          /* do byte-by-byte if not */
0162     mtctr   r0
0163 6:  lbz r7,4(r4)
0164     addi    r4,r4,1
0165     stb r7,4(r6)
0166     addi    r6,r6,1
0167     bdnz    6b
0168     subf    r5,r0,r5
0169     rlwinm. r7,r5,32-3,3,31
0170     beq 2b
0171     mtctr   r7
0172     b   1b
0173 
0174     .globl  backwards_memcpy
0175 backwards_memcpy:
0176     rlwinm. r7,r5,32-3,3,31     /* r7 = r5 >> 3 */
0177     add r6,r3,r5
0178     add r4,r4,r5
0179     beq 3f
0180     andi.   r0,r6,3
0181     mtctr   r7
0182     bne 5f
0183     andi.   r0,r4,3
0184     bne 3f
0185 1:  lwz r7,-4(r4)
0186     lwzu    r8,-8(r4)
0187     stw r7,-4(r6)
0188     stwu    r8,-8(r6)
0189     bdnz    1b
0190     andi.   r5,r5,7
0191 2:  cmplwi  0,r5,4
0192     blt 3f
0193     lwzu    r0,-4(r4)
0194     subi    r5,r5,4
0195     stwu    r0,-4(r6)
0196 3:  cmpwi   0,r5,0
0197     beqlr
0198     mtctr   r5
0199 4:  lbzu    r0,-1(r4)
0200     stbu    r0,-1(r6)
0201     bdnz    4b
0202     blr
0203 5:  cmpw    cr1,r0,r5
0204     subf    r7,r0,r4
0205     andi.   r7,r7,3
0206     ble cr1,3b
0207     bne 3b
0208     mtctr   r0
0209 6:  lbzu    r7,-1(r4)
0210     stbu    r7,-1(r6)
0211     bdnz    6b
0212     subf    r5,r0,r5
0213     rlwinm. r7,r5,32-3,3,31
0214     beq 2b
0215     mtctr   r7
0216     b   1b
0217 
0218     .globl  memchr
0219 memchr:
0220     cmpwi   0,r5,0
0221     blelr
0222     mtctr   r5
0223     addi    r3,r3,-1
0224 1:  lbzu    r0,1(r3)
0225     cmpw    r0,r4
0226     beqlr
0227     bdnz    1b
0228     li  r3,0
0229     blr
0230 
0231     .globl  memcmp
0232 memcmp:
0233     cmpwi   0,r5,0
0234     ble 2f
0235     mtctr   r5
0236     addi    r6,r3,-1
0237     addi    r4,r4,-1
0238 1:  lbzu    r3,1(r6)
0239     lbzu    r0,1(r4)
0240     subf.   r3,r0,r3
0241     bdnzt   2,1b
0242     blr
0243 2:  li  r3,0
0244     blr
0245 
0246 
0247 /*
0248  * Flush the dcache and invalidate the icache for a range of addresses.
0249  *
0250  * flush_cache(addr, len)
0251  */
0252     .global flush_cache
0253 flush_cache:
0254     addi    4,4,0x1f    /* len = (len + 0x1f) / 0x20 */
0255     rlwinm. 4,4,27,5,31
0256     mtctr   4
0257     beqlr
0258 1:  dcbf    0,3
0259     icbi    0,3
0260     addi    3,3,0x20
0261     bdnz    1b
0262     sync
0263     isync
0264     blr
0265