forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
3.5 KiB
265 lines
3.5 KiB
/* SPDX-License-Identifier: GPL-2.0-or-later */ |
|
/* |
|
* Copyright (C) Paul Mackerras 1997. |
|
* |
|
* NOTE: this code runs in 32 bit mode and is packaged as ELF32. |
|
*/ |
|
|
|
#include "ppc_asm.h" |
|
|
|
.text |
|
.globl strcpy |
|
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 |
|
|
|
.globl strncpy |
|
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 |
|
|
|
.globl strcat |
|
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 |
|
|
|
.globl strchr |
|
strchr: |
|
addi r3,r3,-1 |
|
1: lbzu r0,1(r3) |
|
cmpw 0,r0,r4 |
|
beqlr |
|
cmpwi 0,r0,0 |
|
bne 1b |
|
li r3,0 |
|
blr |
|
|
|
.globl strcmp |
|
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 |
|
|
|
.globl strncmp |
|
strncmp: |
|
mtctr r5 |
|
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 |
|
bdnzt eq,1b |
|
blr |
|
|
|
.globl strlen |
|
strlen: |
|
addi r4,r3,-1 |
|
1: lbzu r0,1(r4) |
|
cmpwi 0,r0,0 |
|
bne 1b |
|
subf r3,r3,r4 |
|
blr |
|
|
|
.globl memset |
|
memset: |
|
rlwimi r4,r4,8,16,23 |
|
rlwimi r4,r4,16,0,15 |
|
addi r6,r3,-4 |
|
cmplwi 0,r5,4 |
|
blt 7f |
|
stwu r4,4(r6) |
|
beqlr |
|
andi. r0,r6,3 |
|
add r5,r0,r5 |
|
subf r6,r0,r6 |
|
rlwinm r0,r5,32-2,2,31 |
|
mtctr r0 |
|
bdz 6f |
|
1: stwu r4,4(r6) |
|
bdnz 1b |
|
6: andi. r5,r5,3 |
|
7: cmpwi 0,r5,0 |
|
beqlr |
|
mtctr r5 |
|
addi r6,r6,3 |
|
8: stbu r4,1(r6) |
|
bdnz 8b |
|
blr |
|
|
|
.globl memmove |
|
memmove: |
|
cmplw 0,r3,r4 |
|
bgt backwards_memcpy |
|
/* fall through */ |
|
|
|
.globl memcpy |
|
memcpy: |
|
rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ |
|
addi r6,r3,-4 |
|
addi r4,r4,-4 |
|
beq 3f /* if less than 8 bytes to do */ |
|
andi. r0,r6,3 /* get dest word aligned */ |
|
mtctr r7 |
|
bne 5f |
|
andi. r0,r4,3 /* check src word aligned too */ |
|
bne 3f |
|
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) |
|
addi r5,r5,-4 |
|
stwu r0,4(r6) |
|
3: cmpwi 0,r5,0 |
|
beqlr |
|
mtctr r5 |
|
addi r4,r4,3 |
|
addi r6,r6,3 |
|
4: lbzu r0,1(r4) |
|
stbu r0,1(r6) |
|
bdnz 4b |
|
blr |
|
5: subfic r0,r0,4 |
|
cmpw cr1,r0,r5 |
|
add r7,r0,r4 |
|
andi. r7,r7,3 /* will source be word-aligned too? */ |
|
ble cr1,3b |
|
bne 3b /* do byte-by-byte if not */ |
|
mtctr r0 |
|
6: lbz r7,4(r4) |
|
addi r4,r4,1 |
|
stb r7,4(r6) |
|
addi r6,r6,1 |
|
bdnz 6b |
|
subf r5,r0,r5 |
|
rlwinm. r7,r5,32-3,3,31 |
|
beq 2b |
|
mtctr r7 |
|
b 1b |
|
|
|
.globl backwards_memcpy |
|
backwards_memcpy: |
|
rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ |
|
add r6,r3,r5 |
|
add r4,r4,r5 |
|
beq 3f |
|
andi. r0,r6,3 |
|
mtctr r7 |
|
bne 5f |
|
andi. r0,r4,3 |
|
bne 3f |
|
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: cmpw cr1,r0,r5 |
|
subf r7,r0,r4 |
|
andi. r7,r7,3 |
|
ble cr1,3b |
|
bne 3b |
|
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 |
|
|
|
.globl memchr |
|
memchr: |
|
cmpwi 0,r5,0 |
|
blelr |
|
mtctr r5 |
|
addi r3,r3,-1 |
|
1: lbzu r0,1(r3) |
|
cmpw r0,r4 |
|
beqlr |
|
bdnz 1b |
|
li r3,0 |
|
blr |
|
|
|
.globl memcmp |
|
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 |
|
|
|
|
|
/* |
|
* Flush the dcache and invalidate the icache for a range of addresses. |
|
* |
|
* flush_cache(addr, len) |
|
*/ |
|
.global flush_cache |
|
flush_cache: |
|
addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */ |
|
rlwinm. 4,4,27,5,31 |
|
mtctr 4 |
|
beqlr |
|
1: dcbf 0,3 |
|
icbi 0,3 |
|
addi 3,3,0x20 |
|
bdnz 1b |
|
sync |
|
isync |
|
blr |
|
|
|
|