18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) Paul Mackerras 1997. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * NOTE: this code runs in 32 bit mode and is packaged as ELF32. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include "ppc_asm.h" 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci .text 118c2ecf20Sopenharmony_ci .globl strcpy 128c2ecf20Sopenharmony_cistrcpy: 138c2ecf20Sopenharmony_ci addi r5,r3,-1 148c2ecf20Sopenharmony_ci addi r4,r4,-1 158c2ecf20Sopenharmony_ci1: lbzu r0,1(r4) 168c2ecf20Sopenharmony_ci cmpwi 0,r0,0 178c2ecf20Sopenharmony_ci stbu r0,1(r5) 188c2ecf20Sopenharmony_ci bne 1b 198c2ecf20Sopenharmony_ci blr 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci .globl strncpy 228c2ecf20Sopenharmony_cistrncpy: 238c2ecf20Sopenharmony_ci cmpwi 0,r5,0 248c2ecf20Sopenharmony_ci beqlr 258c2ecf20Sopenharmony_ci mtctr r5 268c2ecf20Sopenharmony_ci addi r6,r3,-1 278c2ecf20Sopenharmony_ci addi r4,r4,-1 288c2ecf20Sopenharmony_ci1: lbzu r0,1(r4) 298c2ecf20Sopenharmony_ci cmpwi 0,r0,0 308c2ecf20Sopenharmony_ci stbu r0,1(r6) 318c2ecf20Sopenharmony_ci bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ 328c2ecf20Sopenharmony_ci blr 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci .globl strcat 358c2ecf20Sopenharmony_cistrcat: 368c2ecf20Sopenharmony_ci addi r5,r3,-1 378c2ecf20Sopenharmony_ci addi r4,r4,-1 388c2ecf20Sopenharmony_ci1: lbzu r0,1(r5) 398c2ecf20Sopenharmony_ci cmpwi 0,r0,0 408c2ecf20Sopenharmony_ci bne 1b 418c2ecf20Sopenharmony_ci addi r5,r5,-1 428c2ecf20Sopenharmony_ci1: lbzu r0,1(r4) 438c2ecf20Sopenharmony_ci cmpwi 0,r0,0 448c2ecf20Sopenharmony_ci stbu r0,1(r5) 458c2ecf20Sopenharmony_ci bne 1b 468c2ecf20Sopenharmony_ci blr 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci .globl strchr 498c2ecf20Sopenharmony_cistrchr: 508c2ecf20Sopenharmony_ci addi r3,r3,-1 518c2ecf20Sopenharmony_ci1: lbzu r0,1(r3) 528c2ecf20Sopenharmony_ci cmpw 0,r0,r4 538c2ecf20Sopenharmony_ci beqlr 548c2ecf20Sopenharmony_ci cmpwi 0,r0,0 558c2ecf20Sopenharmony_ci bne 1b 568c2ecf20Sopenharmony_ci li r3,0 578c2ecf20Sopenharmony_ci blr 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci .globl strcmp 608c2ecf20Sopenharmony_cistrcmp: 618c2ecf20Sopenharmony_ci addi r5,r3,-1 628c2ecf20Sopenharmony_ci addi r4,r4,-1 638c2ecf20Sopenharmony_ci1: lbzu r3,1(r5) 648c2ecf20Sopenharmony_ci cmpwi 1,r3,0 658c2ecf20Sopenharmony_ci lbzu r0,1(r4) 668c2ecf20Sopenharmony_ci subf. r3,r0,r3 678c2ecf20Sopenharmony_ci beqlr 1 688c2ecf20Sopenharmony_ci beq 1b 698c2ecf20Sopenharmony_ci blr 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci .globl strncmp 728c2ecf20Sopenharmony_cistrncmp: 738c2ecf20Sopenharmony_ci mtctr r5 748c2ecf20Sopenharmony_ci addi r5,r3,-1 758c2ecf20Sopenharmony_ci addi r4,r4,-1 768c2ecf20Sopenharmony_ci1: lbzu r3,1(r5) 778c2ecf20Sopenharmony_ci cmpwi 1,r3,0 788c2ecf20Sopenharmony_ci lbzu r0,1(r4) 798c2ecf20Sopenharmony_ci subf. r3,r0,r3 808c2ecf20Sopenharmony_ci beqlr 1 818c2ecf20Sopenharmony_ci bdnzt eq,1b 828c2ecf20Sopenharmony_ci blr 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci .globl strlen 858c2ecf20Sopenharmony_cistrlen: 868c2ecf20Sopenharmony_ci addi r4,r3,-1 878c2ecf20Sopenharmony_ci1: lbzu r0,1(r4) 888c2ecf20Sopenharmony_ci cmpwi 0,r0,0 898c2ecf20Sopenharmony_ci bne 1b 908c2ecf20Sopenharmony_ci subf r3,r3,r4 918c2ecf20Sopenharmony_ci blr 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci .globl memset 948c2ecf20Sopenharmony_cimemset: 958c2ecf20Sopenharmony_ci rlwimi r4,r4,8,16,23 968c2ecf20Sopenharmony_ci rlwimi r4,r4,16,0,15 978c2ecf20Sopenharmony_ci addi r6,r3,-4 988c2ecf20Sopenharmony_ci cmplwi 0,r5,4 998c2ecf20Sopenharmony_ci blt 7f 1008c2ecf20Sopenharmony_ci stwu r4,4(r6) 1018c2ecf20Sopenharmony_ci beqlr 1028c2ecf20Sopenharmony_ci andi. r0,r6,3 1038c2ecf20Sopenharmony_ci add r5,r0,r5 1048c2ecf20Sopenharmony_ci subf r6,r0,r6 1058c2ecf20Sopenharmony_ci rlwinm r0,r5,32-2,2,31 1068c2ecf20Sopenharmony_ci mtctr r0 1078c2ecf20Sopenharmony_ci bdz 6f 1088c2ecf20Sopenharmony_ci1: stwu r4,4(r6) 1098c2ecf20Sopenharmony_ci bdnz 1b 1108c2ecf20Sopenharmony_ci6: andi. r5,r5,3 1118c2ecf20Sopenharmony_ci7: cmpwi 0,r5,0 1128c2ecf20Sopenharmony_ci beqlr 1138c2ecf20Sopenharmony_ci mtctr r5 1148c2ecf20Sopenharmony_ci addi r6,r6,3 1158c2ecf20Sopenharmony_ci8: stbu r4,1(r6) 1168c2ecf20Sopenharmony_ci bdnz 8b 1178c2ecf20Sopenharmony_ci blr 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci .globl memmove 1208c2ecf20Sopenharmony_cimemmove: 1218c2ecf20Sopenharmony_ci cmplw 0,r3,r4 1228c2ecf20Sopenharmony_ci bgt backwards_memcpy 1238c2ecf20Sopenharmony_ci /* fall through */ 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci .globl memcpy 1268c2ecf20Sopenharmony_cimemcpy: 1278c2ecf20Sopenharmony_ci rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ 1288c2ecf20Sopenharmony_ci addi r6,r3,-4 1298c2ecf20Sopenharmony_ci addi r4,r4,-4 1308c2ecf20Sopenharmony_ci beq 3f /* if less than 8 bytes to do */ 1318c2ecf20Sopenharmony_ci andi. r0,r6,3 /* get dest word aligned */ 1328c2ecf20Sopenharmony_ci mtctr r7 1338c2ecf20Sopenharmony_ci bne 5f 1348c2ecf20Sopenharmony_ci andi. r0,r4,3 /* check src word aligned too */ 1358c2ecf20Sopenharmony_ci bne 3f 1368c2ecf20Sopenharmony_ci1: lwz r7,4(r4) 1378c2ecf20Sopenharmony_ci lwzu r8,8(r4) 1388c2ecf20Sopenharmony_ci stw r7,4(r6) 1398c2ecf20Sopenharmony_ci stwu r8,8(r6) 1408c2ecf20Sopenharmony_ci bdnz 1b 1418c2ecf20Sopenharmony_ci andi. r5,r5,7 1428c2ecf20Sopenharmony_ci2: cmplwi 0,r5,4 1438c2ecf20Sopenharmony_ci blt 3f 1448c2ecf20Sopenharmony_ci lwzu r0,4(r4) 1458c2ecf20Sopenharmony_ci addi r5,r5,-4 1468c2ecf20Sopenharmony_ci stwu r0,4(r6) 1478c2ecf20Sopenharmony_ci3: cmpwi 0,r5,0 1488c2ecf20Sopenharmony_ci beqlr 1498c2ecf20Sopenharmony_ci mtctr r5 1508c2ecf20Sopenharmony_ci addi r4,r4,3 1518c2ecf20Sopenharmony_ci addi r6,r6,3 1528c2ecf20Sopenharmony_ci4: lbzu r0,1(r4) 1538c2ecf20Sopenharmony_ci stbu r0,1(r6) 1548c2ecf20Sopenharmony_ci bdnz 4b 1558c2ecf20Sopenharmony_ci blr 1568c2ecf20Sopenharmony_ci5: subfic r0,r0,4 1578c2ecf20Sopenharmony_ci cmpw cr1,r0,r5 1588c2ecf20Sopenharmony_ci add r7,r0,r4 1598c2ecf20Sopenharmony_ci andi. r7,r7,3 /* will source be word-aligned too? */ 1608c2ecf20Sopenharmony_ci ble cr1,3b 1618c2ecf20Sopenharmony_ci bne 3b /* do byte-by-byte if not */ 1628c2ecf20Sopenharmony_ci mtctr r0 1638c2ecf20Sopenharmony_ci6: lbz r7,4(r4) 1648c2ecf20Sopenharmony_ci addi r4,r4,1 1658c2ecf20Sopenharmony_ci stb r7,4(r6) 1668c2ecf20Sopenharmony_ci addi r6,r6,1 1678c2ecf20Sopenharmony_ci bdnz 6b 1688c2ecf20Sopenharmony_ci subf r5,r0,r5 1698c2ecf20Sopenharmony_ci rlwinm. r7,r5,32-3,3,31 1708c2ecf20Sopenharmony_ci beq 2b 1718c2ecf20Sopenharmony_ci mtctr r7 1728c2ecf20Sopenharmony_ci b 1b 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci .globl backwards_memcpy 1758c2ecf20Sopenharmony_cibackwards_memcpy: 1768c2ecf20Sopenharmony_ci rlwinm. r7,r5,32-3,3,31 /* r7 = r5 >> 3 */ 1778c2ecf20Sopenharmony_ci add r6,r3,r5 1788c2ecf20Sopenharmony_ci add r4,r4,r5 1798c2ecf20Sopenharmony_ci beq 3f 1808c2ecf20Sopenharmony_ci andi. r0,r6,3 1818c2ecf20Sopenharmony_ci mtctr r7 1828c2ecf20Sopenharmony_ci bne 5f 1838c2ecf20Sopenharmony_ci andi. r0,r4,3 1848c2ecf20Sopenharmony_ci bne 3f 1858c2ecf20Sopenharmony_ci1: lwz r7,-4(r4) 1868c2ecf20Sopenharmony_ci lwzu r8,-8(r4) 1878c2ecf20Sopenharmony_ci stw r7,-4(r6) 1888c2ecf20Sopenharmony_ci stwu r8,-8(r6) 1898c2ecf20Sopenharmony_ci bdnz 1b 1908c2ecf20Sopenharmony_ci andi. r5,r5,7 1918c2ecf20Sopenharmony_ci2: cmplwi 0,r5,4 1928c2ecf20Sopenharmony_ci blt 3f 1938c2ecf20Sopenharmony_ci lwzu r0,-4(r4) 1948c2ecf20Sopenharmony_ci subi r5,r5,4 1958c2ecf20Sopenharmony_ci stwu r0,-4(r6) 1968c2ecf20Sopenharmony_ci3: cmpwi 0,r5,0 1978c2ecf20Sopenharmony_ci beqlr 1988c2ecf20Sopenharmony_ci mtctr r5 1998c2ecf20Sopenharmony_ci4: lbzu r0,-1(r4) 2008c2ecf20Sopenharmony_ci stbu r0,-1(r6) 2018c2ecf20Sopenharmony_ci bdnz 4b 2028c2ecf20Sopenharmony_ci blr 2038c2ecf20Sopenharmony_ci5: cmpw cr1,r0,r5 2048c2ecf20Sopenharmony_ci subf r7,r0,r4 2058c2ecf20Sopenharmony_ci andi. r7,r7,3 2068c2ecf20Sopenharmony_ci ble cr1,3b 2078c2ecf20Sopenharmony_ci bne 3b 2088c2ecf20Sopenharmony_ci mtctr r0 2098c2ecf20Sopenharmony_ci6: lbzu r7,-1(r4) 2108c2ecf20Sopenharmony_ci stbu r7,-1(r6) 2118c2ecf20Sopenharmony_ci bdnz 6b 2128c2ecf20Sopenharmony_ci subf r5,r0,r5 2138c2ecf20Sopenharmony_ci rlwinm. r7,r5,32-3,3,31 2148c2ecf20Sopenharmony_ci beq 2b 2158c2ecf20Sopenharmony_ci mtctr r7 2168c2ecf20Sopenharmony_ci b 1b 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci .globl memchr 2198c2ecf20Sopenharmony_cimemchr: 2208c2ecf20Sopenharmony_ci cmpwi 0,r5,0 2218c2ecf20Sopenharmony_ci blelr 2228c2ecf20Sopenharmony_ci mtctr r5 2238c2ecf20Sopenharmony_ci addi r3,r3,-1 2248c2ecf20Sopenharmony_ci1: lbzu r0,1(r3) 2258c2ecf20Sopenharmony_ci cmpw r0,r4 2268c2ecf20Sopenharmony_ci beqlr 2278c2ecf20Sopenharmony_ci bdnz 1b 2288c2ecf20Sopenharmony_ci li r3,0 2298c2ecf20Sopenharmony_ci blr 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci .globl memcmp 2328c2ecf20Sopenharmony_cimemcmp: 2338c2ecf20Sopenharmony_ci cmpwi 0,r5,0 2348c2ecf20Sopenharmony_ci ble 2f 2358c2ecf20Sopenharmony_ci mtctr r5 2368c2ecf20Sopenharmony_ci addi r6,r3,-1 2378c2ecf20Sopenharmony_ci addi r4,r4,-1 2388c2ecf20Sopenharmony_ci1: lbzu r3,1(r6) 2398c2ecf20Sopenharmony_ci lbzu r0,1(r4) 2408c2ecf20Sopenharmony_ci subf. r3,r0,r3 2418c2ecf20Sopenharmony_ci bdnzt 2,1b 2428c2ecf20Sopenharmony_ci blr 2438c2ecf20Sopenharmony_ci2: li r3,0 2448c2ecf20Sopenharmony_ci blr 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci/* 2488c2ecf20Sopenharmony_ci * Flush the dcache and invalidate the icache for a range of addresses. 2498c2ecf20Sopenharmony_ci * 2508c2ecf20Sopenharmony_ci * flush_cache(addr, len) 2518c2ecf20Sopenharmony_ci */ 2528c2ecf20Sopenharmony_ci .global flush_cache 2538c2ecf20Sopenharmony_ciflush_cache: 2548c2ecf20Sopenharmony_ci addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */ 2558c2ecf20Sopenharmony_ci rlwinm. 4,4,27,5,31 2568c2ecf20Sopenharmony_ci mtctr 4 2578c2ecf20Sopenharmony_ci beqlr 2588c2ecf20Sopenharmony_ci1: dcbf 0,3 2598c2ecf20Sopenharmony_ci icbi 0,3 2608c2ecf20Sopenharmony_ci addi 3,3,0x20 2618c2ecf20Sopenharmony_ci bdnz 1b 2628c2ecf20Sopenharmony_ci sync 2638c2ecf20Sopenharmony_ci isync 2648c2ecf20Sopenharmony_ci blr 2658c2ecf20Sopenharmony_ci 266