/* 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 strcmp(const char *cs, const char *ct) */8SYM_FUNC_START(strcmp)910__ALTERNATIVE_CFG("nop", "j strcmp_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 strcmp16*17* Parameters18* a0 - string119* a1 - string220*21* Clobbers22* t0, t123*/241:25lbu t0, 0(a0)26lbu t1, 0(a1)27addi a0, a0, 128addi a1, a1, 129bne t0, t1, 2f30bnez t0, 1b31li a0, 032ret332:34/*35* strcmp only needs to return (< 0, 0, > 0) values36* not necessarily -1, 0, +137*/38sub a0, t0, t139ret4041/*42* Variant of strcmp using the ZBB extension if available.43* The code was published as part of the bitmanip manual44* in Appendix A.45*/46#if defined(CONFIG_RISCV_ISA_ZBB) && defined(CONFIG_TOOLCHAIN_HAS_ZBB)47strcmp_zbb:4849.option push50.option arch,+zbb5152/*53* Returns54* a0 - comparison result, value like strcmp55*56* Parameters57* a0 - string158* a1 - string259*60* Clobbers61* t0, t1, t2, t3, t462*/6364or t2, a0, a165li t4, -166and t2, t2, SZREG-167bnez t2, 3f6869/* Main loop for aligned string. */70.p2align 3711:72REG_L t0, 0(a0)73REG_L t1, 0(a1)74orc.b t3, t075bne t3, t4, 2f76addi a0, a0, SZREG77addi a1, a1, SZREG78beq t0, t1, 1b7980/*81* Words don't match, and no null byte in the first82* word. Get bytes in big-endian order and compare.83*/84#ifndef CONFIG_CPU_BIG_ENDIAN85rev8 t0, t086rev8 t1, t187#endif8889/* Synthesize (t0 >= t1) ? 1 : -1 in a branchless sequence. */90sltu a0, t0, t191neg a0, a092ori a0, a0, 193ret94952:96/*97* Found a null byte.98* If words don't match, fall back to simple loop.99*/100bne t0, t1, 3f101102/* Otherwise, strings are equal. */103li a0, 0104ret105106/* Simple loop for misaligned strings. */107.p2align 31083:109lbu t0, 0(a0)110lbu t1, 0(a1)111addi a0, a0, 1112addi a1, a1, 1113bne t0, t1, 4f114bnez t0, 3b1151164:117sub a0, t0, t1118ret119120.option pop121#endif122SYM_FUNC_END(strcmp)123SYM_FUNC_ALIAS(__pi_strcmp, strcmp)124EXPORT_SYMBOL(strcmp)125126127