162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) Paul Mackerras 1997. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * NOTE: this code runs in 32 bit mode and is packaged as ELF32. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include "ppc_asm.h" 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci .text 1162306a36Sopenharmony_ci .globl strcpy 1262306a36Sopenharmony_cistrcpy: 1362306a36Sopenharmony_ci addi r5,r3,-1 1462306a36Sopenharmony_ci addi r4,r4,-1 1562306a36Sopenharmony_ci1: lbzu r0,1(r4) 1662306a36Sopenharmony_ci cmpwi 0,r0,0 1762306a36Sopenharmony_ci stbu r0,1(r5) 1862306a36Sopenharmony_ci bne 1b 1962306a36Sopenharmony_ci blr 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci .globl strncpy 2262306a36Sopenharmony_cistrncpy: 2362306a36Sopenharmony_ci cmpwi 0,r5,0 2462306a36Sopenharmony_ci beqlr 2562306a36Sopenharmony_ci mtctr r5 2662306a36Sopenharmony_ci addi r6,r3,-1 2762306a36Sopenharmony_ci addi r4,r4,-1 2862306a36Sopenharmony_ci1: lbzu r0,1(r4) 2962306a36Sopenharmony_ci cmpwi 0,r0,0 3062306a36Sopenharmony_ci stbu r0,1(r6) 3162306a36Sopenharmony_ci bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ 3262306a36Sopenharmony_ci blr 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci .globl strcat 3562306a36Sopenharmony_cistrcat: 3662306a36Sopenharmony_ci addi r5,r3,-1 3762306a36Sopenharmony_ci addi r4,r4,-1 3862306a36Sopenharmony_ci1: lbzu r0,1(r5) 3962306a36Sopenharmony_ci cmpwi 0,r0,0 4062306a36Sopenharmony_ci bne 1b 4162306a36Sopenharmony_ci addi r5,r5,-1 4262306a36Sopenharmony_ci1: lbzu r0,1(r4) 4362306a36Sopenharmony_ci cmpwi 0,r0,0 4462306a36Sopenharmony_ci stbu r0,1(r5) 4562306a36Sopenharmony_ci bne 1b 4662306a36Sopenharmony_ci blr 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci .globl strchr 4962306a36Sopenharmony_cistrchr: 5062306a36Sopenharmony_ci addi r3,r3,-1 5162306a36Sopenharmony_ci1: lbzu r0,1(r3) 5262306a36Sopenharmony_ci cmpw 0,r0,r4 5362306a36Sopenharmony_ci beqlr 5462306a36Sopenharmony_ci cmpwi 0,r0,0 5562306a36Sopenharmony_ci bne 1b 5662306a36Sopenharmony_ci li r3,0 5762306a36Sopenharmony_ci blr 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci .globl strcmp 6062306a36Sopenharmony_cistrcmp: 6162306a36Sopenharmony_ci addi r5,r3,-1 6262306a36Sopenharmony_ci addi r4,r4,-1 6362306a36Sopenharmony_ci1: lbzu r3,1(r5) 6462306a36Sopenharmony_ci cmpwi 1,r3,0 6562306a36Sopenharmony_ci lbzu r0,1(r4) 6662306a36Sopenharmony_ci subf. r3,r0,r3 6762306a36Sopenharmony_ci beqlr 1 6862306a36Sopenharmony_ci beq 1b 6962306a36Sopenharmony_ci blr 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci .globl strncmp 7262306a36Sopenharmony_cistrncmp: 7362306a36Sopenharmony_ci mtctr r5 7462306a36Sopenharmony_ci addi r5,r3,-1 7562306a36Sopenharmony_ci addi r4,r4,-1 7662306a36Sopenharmony_ci1: lbzu r3,1(r5) 7762306a36Sopenharmony_ci cmpwi 1,r3,0 7862306a36Sopenharmony_ci lbzu r0,1(r4) 7962306a36Sopenharmony_ci subf. r3,r0,r3 8062306a36Sopenharmony_ci beqlr 1 8162306a36Sopenharmony_ci bdnzt eq,1b 8262306a36Sopenharmony_ci blr 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci .globl strlen 8562306a36Sopenharmony_cistrlen: 8662306a36Sopenharmony_ci addi r4,r3,-1 8762306a36Sopenharmony_ci1: lbzu r0,1(r4) 8862306a36Sopenharmony_ci cmpwi 0,r0,0 8962306a36Sopenharmony_ci bne 1b 9062306a36Sopenharmony_ci subf r3,r3,r4 9162306a36Sopenharmony_ci blr 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci .globl memset 9462306a36Sopenharmony_cimemset: 9562306a36Sopenharmony_ci rlwimi r4,r4,8,16,23 9662306a36Sopenharmony_ci rlwimi r4,r4,16,0,15 9762306a36Sopenharmony_ci addi r6,r3,-4 9862306a36Sopenharmony_ci cmplwi 0,r5,4 9962306a36Sopenharmony_ci blt 7f 10062306a36Sopenharmony_ci stwu r4,4(r6) 10162306a36Sopenharmony_ci beqlr 10262306a36Sopenharmony_ci andi. r0,r6,3 10362306a36Sopenharmony_ci add r5,r0,r5 10462306a36Sopenharmony_ci subf r6,r0,r6 10562306a36Sopenharmony_ci rlwinm r0,r5,32-2,2,31 10662306a36Sopenharmony_ci mtctr r0 10762306a36Sopenharmony_ci bdz 6f 10862306a36Sopenharmony_ci1: stwu r4,4(r6) 10962306a36Sopenharmony_ci bdnz 1b 11062306a36Sopenharmony_ci6: andi. r5,r5,3 11162306a36Sopenharmony_ci7: cmpwi 0,r5,0 11262306a36Sopenharmony_ci beqlr 11362306a36Sopenharmony_ci mtctr r5 11462306a36Sopenharmony_ci addi r6,r6,3 11562306a36Sopenharmony_ci8: stbu r4,1(r6) 11662306a36Sopenharmony_ci bdnz 8b 11762306a36Sopenharmony_ci blr 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci .globl memmove 12062306a36Sopenharmony_cimemmove: 12162306a36Sopenharmony_ci cmplw 0,r3,r4 12262306a36Sopenharmony_ci bgt backwards_memcpy 12362306a36Sopenharmony_ci /* fall through */ 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci .globl memcpy 12662306a36Sopenharmony_cimemcpy: 12762306a36Sopenharmony_ci rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ 12862306a36Sopenharmony_ci addi r6,r3,-4 12962306a36Sopenharmony_ci addi r4,r4,-4 13062306a36Sopenharmony_ci beq 3f /* if less than 8 bytes to do */ 13162306a36Sopenharmony_ci andi. r0,r6,3 /* get dest word aligned */ 13262306a36Sopenharmony_ci mtctr r7 13362306a36Sopenharmony_ci bne 5f 13462306a36Sopenharmony_ci andi. r0,r4,3 /* check src word aligned too */ 13562306a36Sopenharmony_ci bne 3f 13662306a36Sopenharmony_ci1: lwz r7,4(r4) 13762306a36Sopenharmony_ci lwzu r8,8(r4) 13862306a36Sopenharmony_ci stw r7,4(r6) 13962306a36Sopenharmony_ci stwu r8,8(r6) 14062306a36Sopenharmony_ci bdnz 1b 14162306a36Sopenharmony_ci andi. r5,r5,7 14262306a36Sopenharmony_ci2: cmplwi 0,r5,4 14362306a36Sopenharmony_ci blt 3f 14462306a36Sopenharmony_ci lwzu r0,4(r4) 14562306a36Sopenharmony_ci addi r5,r5,-4 14662306a36Sopenharmony_ci stwu r0,4(r6) 14762306a36Sopenharmony_ci3: cmpwi 0,r5,0 14862306a36Sopenharmony_ci beqlr 14962306a36Sopenharmony_ci mtctr r5 15062306a36Sopenharmony_ci addi r4,r4,3 15162306a36Sopenharmony_ci addi r6,r6,3 15262306a36Sopenharmony_ci4: lbzu r0,1(r4) 15362306a36Sopenharmony_ci stbu r0,1(r6) 15462306a36Sopenharmony_ci bdnz 4b 15562306a36Sopenharmony_ci blr 15662306a36Sopenharmony_ci5: subfic r0,r0,4 15762306a36Sopenharmony_ci cmpw cr1,r0,r5 15862306a36Sopenharmony_ci add r7,r0,r4 15962306a36Sopenharmony_ci andi. r7,r7,3 /* will source be word-aligned too? */ 16062306a36Sopenharmony_ci ble cr1,3b 16162306a36Sopenharmony_ci bne 3b /* do byte-by-byte if not */ 16262306a36Sopenharmony_ci mtctr r0 16362306a36Sopenharmony_ci6: lbz r7,4(r4) 16462306a36Sopenharmony_ci addi r4,r4,1 16562306a36Sopenharmony_ci stb r7,4(r6) 16662306a36Sopenharmony_ci addi r6,r6,1 16762306a36Sopenharmony_ci bdnz 6b 16862306a36Sopenharmony_ci subf r5,r0,r5 16962306a36Sopenharmony_ci rlwinm. r7,r5,32-3,3,31 17062306a36Sopenharmony_ci beq 2b 17162306a36Sopenharmony_ci mtctr r7 17262306a36Sopenharmony_ci b 1b 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci .globl backwards_memcpy 17562306a36Sopenharmony_cibackwards_memcpy: 17662306a36Sopenharmony_ci rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ 17762306a36Sopenharmony_ci add r6,r3,r5 17862306a36Sopenharmony_ci add r4,r4,r5 17962306a36Sopenharmony_ci beq 3f 18062306a36Sopenharmony_ci andi. r0,r6,3 18162306a36Sopenharmony_ci mtctr r7 18262306a36Sopenharmony_ci bne 5f 18362306a36Sopenharmony_ci andi. r0,r4,3 18462306a36Sopenharmony_ci bne 3f 18562306a36Sopenharmony_ci1: lwz r7,-4(r4) 18662306a36Sopenharmony_ci lwzu r8,-8(r4) 18762306a36Sopenharmony_ci stw r7,-4(r6) 18862306a36Sopenharmony_ci stwu r8,-8(r6) 18962306a36Sopenharmony_ci bdnz 1b 19062306a36Sopenharmony_ci andi. r5,r5,7 19162306a36Sopenharmony_ci2: cmplwi 0,r5,4 19262306a36Sopenharmony_ci blt 3f 19362306a36Sopenharmony_ci lwzu r0,-4(r4) 19462306a36Sopenharmony_ci subi r5,r5,4 19562306a36Sopenharmony_ci stwu r0,-4(r6) 19662306a36Sopenharmony_ci3: cmpwi 0,r5,0 19762306a36Sopenharmony_ci beqlr 19862306a36Sopenharmony_ci mtctr r5 19962306a36Sopenharmony_ci4: lbzu r0,-1(r4) 20062306a36Sopenharmony_ci stbu r0,-1(r6) 20162306a36Sopenharmony_ci bdnz 4b 20262306a36Sopenharmony_ci blr 20362306a36Sopenharmony_ci5: cmpw cr1,r0,r5 20462306a36Sopenharmony_ci subf r7,r0,r4 20562306a36Sopenharmony_ci andi. r7,r7,3 20662306a36Sopenharmony_ci ble cr1,3b 20762306a36Sopenharmony_ci bne 3b 20862306a36Sopenharmony_ci mtctr r0 20962306a36Sopenharmony_ci6: lbzu r7,-1(r4) 21062306a36Sopenharmony_ci stbu r7,-1(r6) 21162306a36Sopenharmony_ci bdnz 6b 21262306a36Sopenharmony_ci subf r5,r0,r5 21362306a36Sopenharmony_ci rlwinm. r7,r5,32-3,3,31 21462306a36Sopenharmony_ci beq 2b 21562306a36Sopenharmony_ci mtctr r7 21662306a36Sopenharmony_ci b 1b 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci .globl memchr 21962306a36Sopenharmony_cimemchr: 22062306a36Sopenharmony_ci cmpwi 0,r5,0 22162306a36Sopenharmony_ci blelr 22262306a36Sopenharmony_ci mtctr r5 22362306a36Sopenharmony_ci addi r3,r3,-1 22462306a36Sopenharmony_ci1: lbzu r0,1(r3) 22562306a36Sopenharmony_ci cmpw r0,r4 22662306a36Sopenharmony_ci beqlr 22762306a36Sopenharmony_ci bdnz 1b 22862306a36Sopenharmony_ci li r3,0 22962306a36Sopenharmony_ci blr 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci .globl memcmp 23262306a36Sopenharmony_cimemcmp: 23362306a36Sopenharmony_ci cmpwi 0,r5,0 23462306a36Sopenharmony_ci ble 2f 23562306a36Sopenharmony_ci mtctr r5 23662306a36Sopenharmony_ci addi r6,r3,-1 23762306a36Sopenharmony_ci addi r4,r4,-1 23862306a36Sopenharmony_ci1: lbzu r3,1(r6) 23962306a36Sopenharmony_ci lbzu r0,1(r4) 24062306a36Sopenharmony_ci subf. r3,r0,r3 24162306a36Sopenharmony_ci bdnzt 2,1b 24262306a36Sopenharmony_ci blr 24362306a36Sopenharmony_ci2: li r3,0 24462306a36Sopenharmony_ci blr 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci/* 24862306a36Sopenharmony_ci * Flush the dcache and invalidate the icache for a range of addresses. 24962306a36Sopenharmony_ci * 25062306a36Sopenharmony_ci * flush_cache(addr, len) 25162306a36Sopenharmony_ci */ 25262306a36Sopenharmony_ci .global flush_cache 25362306a36Sopenharmony_ciflush_cache: 25462306a36Sopenharmony_ci addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */ 25562306a36Sopenharmony_ci rlwinm. 4,4,27,5,31 25662306a36Sopenharmony_ci mtctr 4 25762306a36Sopenharmony_ci beqlr 25862306a36Sopenharmony_ci1: dcbf 0,3 25962306a36Sopenharmony_ci icbi 0,3 26062306a36Sopenharmony_ci addi 3,3,0x20 26162306a36Sopenharmony_ci bdnz 1b 26262306a36Sopenharmony_ci sync 26362306a36Sopenharmony_ci isync 26462306a36Sopenharmony_ci blr 26562306a36Sopenharmony_ci 266