1/* SPDX-License-Identifier: GPL-2.0-only */ 2 3#include <linux/linkage.h> 4#include <asm/asm.h> 5#include <asm/alternative-macros.h> 6#include <asm/hwcap.h> 7 8/* int strcmp(const char *cs, const char *ct) */ 9SYM_FUNC_START(strcmp) 10 11 ALTERNATIVE("nop", "j strcmp_zbb", 0, RISCV_ISA_EXT_ZBB, CONFIG_RISCV_ISA_ZBB) 12 13 /* 14 * Returns 15 * a0 - comparison result, value like strcmp 16 * 17 * Parameters 18 * a0 - string1 19 * a1 - string2 20 * 21 * Clobbers 22 * t0, t1 23 */ 241: 25 lbu t0, 0(a0) 26 lbu t1, 0(a1) 27 addi a0, a0, 1 28 addi a1, a1, 1 29 bne t0, t1, 2f 30 bnez t0, 1b 31 li a0, 0 32 ret 332: 34 /* 35 * strcmp only needs to return (< 0, 0, > 0) values 36 * not necessarily -1, 0, +1 37 */ 38 sub a0, t0, t1 39 ret 40 41/* 42 * Variant of strcmp using the ZBB extension if available. 43 * The code was published as part of the bitmanip manual 44 * in Appendix A. 45 */ 46#ifdef CONFIG_RISCV_ISA_ZBB 47strcmp_zbb: 48 49.option push 50.option arch,+zbb 51 52 /* 53 * Returns 54 * a0 - comparison result, value like strcmp 55 * 56 * Parameters 57 * a0 - string1 58 * a1 - string2 59 * 60 * Clobbers 61 * t0, t1, t2, t3, t4 62 */ 63 64 or t2, a0, a1 65 li t4, -1 66 and t2, t2, SZREG-1 67 bnez t2, 3f 68 69 /* Main loop for aligned string. */ 70 .p2align 3 711: 72 REG_L t0, 0(a0) 73 REG_L t1, 0(a1) 74 orc.b t3, t0 75 bne t3, t4, 2f 76 addi a0, a0, SZREG 77 addi a1, a1, SZREG 78 beq t0, t1, 1b 79 80 /* 81 * Words don't match, and no null byte in the first 82 * word. Get bytes in big-endian order and compare. 83 */ 84#ifndef CONFIG_CPU_BIG_ENDIAN 85 rev8 t0, t0 86 rev8 t1, t1 87#endif 88 89 /* Synthesize (t0 >= t1) ? 1 : -1 in a branchless sequence. */ 90 sltu a0, t0, t1 91 neg a0, a0 92 ori a0, a0, 1 93 ret 94 952: 96 /* 97 * Found a null byte. 98 * If words don't match, fall back to simple loop. 99 */ 100 bne t0, t1, 3f 101 102 /* Otherwise, strings are equal. */ 103 li a0, 0 104 ret 105 106 /* Simple loop for misaligned strings. */ 107 .p2align 3 1083: 109 lbu t0, 0(a0) 110 lbu t1, 0(a1) 111 addi a0, a0, 1 112 addi a1, a1, 1 113 bne t0, t1, 4f 114 bnez t0, 3b 115 1164: 117 sub a0, t0, t1 118 ret 119 120.option pop 121#endif 122SYM_FUNC_END(strcmp) 123