/* SPDX-License-Identifier: GPL-2.0-only */12#include <linux/linkage.h>3#include <asm/asm.h>4#include <asm/alternative-macros.h>5#include <asm/hwcap.h>67/* int strncmp(const char *cs, const char *ct, size_t count) */8SYM_FUNC_START(strncmp)910__ALTERNATIVE_CFG("nop", "j strncmp_zbb", 0, RISCV_ISA_EXT_ZBB,11IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB))1213/*14* Returns15* a0 - comparison result, value like strncmp16*17* Parameters18* a0 - string119* a1 - string220* a2 - number of characters to compare21*22* Clobbers23* t0, t1, t224*/25li t2, 0261:27beq a2, t2, 2f28lbu t0, 0(a0)29lbu t1, 0(a1)30addi a0, a0, 131addi a1, a1, 132bne t0, t1, 3f33addi t2, t2, 134bnez t0, 1b352:36li a0, 037ret383:39/*40* strncmp only needs to return (< 0, 0, > 0) values41* not necessarily -1, 0, +142*/43sub a0, t0, t144ret4546/*47* Variant of strncmp using the ZBB extension if available48*/49#if defined(CONFIG_RISCV_ISA_ZBB) && defined(CONFIG_TOOLCHAIN_HAS_ZBB)50strncmp_zbb:5152.option push53.option arch,+zbb5455/*56* Returns57* a0 - comparison result, like strncmp58*59* Parameters60* a0 - string161* a1 - string262* a2 - number of characters to compare63*64* Clobbers65* t0, t1, t2, t3, t4, t5, t666*/6768or t2, a0, a169li t5, -170and t2, t2, SZREG-171add t4, a0, a272bnez t2, 3f7374/* Adjust limit for fast-path. */75andi t6, t4, -SZREG7677/* Main loop for aligned string. */78.p2align 3791:80bge a0, t6, 3f81REG_L t0, 0(a0)82REG_L t1, 0(a1)83orc.b t3, t084bne t3, t5, 2f85orc.b t3, t186bne t3, t5, 2f87addi a0, a0, SZREG88addi a1, a1, SZREG89beq t0, t1, 1b9091/*92* Words don't match, and no null byte in the first93* word. Get bytes in big-endian order and compare.94*/95#ifndef CONFIG_CPU_BIG_ENDIAN96rev8 t0, t097rev8 t1, t198#endif99100/* Synthesize (t0 >= t1) ? 1 : -1 in a branchless sequence. */101sltu a0, t0, t1102neg a0, a0103ori a0, a0, 1104ret1051062:107/*108* Found a null byte.109* If words don't match, fall back to simple loop.110*/111bne t0, t1, 3f112113/* Otherwise, strings are equal. */114li a0, 0115ret116117/* Simple loop for misaligned strings. */118.p2align 31193:120bge a0, t4, 5f121lbu t0, 0(a0)122lbu t1, 0(a1)123addi a0, a0, 1124addi a1, a1, 1125bne t0, t1, 4f126bnez t0, 3b1271284:129sub a0, t0, t1130ret1311325:133li a0, 0134ret135136.option pop137#endif138SYM_FUNC_END(strncmp)139SYM_FUNC_ALIAS(__pi_strncmp, strncmp)140EXPORT_SYMBOL(strncmp)141142143