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