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 strncmp(const char *cs, const char *ct, size_t count) */ 9SYM_FUNC_START(strncmp) 10 11 ALTERNATIVE("nop", "j strncmp_zbb", 0, RISCV_ISA_EXT_ZBB, CONFIG_RISCV_ISA_ZBB) 12 13 /* 14 * Returns 15 * a0 - comparison result, value like strncmp 16 * 17 * Parameters 18 * a0 - string1 19 * a1 - string2 20 * a2 - number of characters to compare 21 * 22 * Clobbers 23 * t0, t1, t2 24 */ 25 li t2, 0 261: 27 beq a2, t2, 2f 28 lbu t0, 0(a0) 29 lbu t1, 0(a1) 30 addi a0, a0, 1 31 addi a1, a1, 1 32 bne t0, t1, 3f 33 addi t2, t2, 1 34 bnez t0, 1b 352: 36 li a0, 0 37 ret 383: 39 /* 40 * strncmp only needs to return (< 0, 0, > 0) values 41 * not necessarily -1, 0, +1 42 */ 43 sub a0, t0, t1 44 ret 45 46/* 47 * Variant of strncmp using the ZBB extension if available 48 */ 49#ifdef CONFIG_RISCV_ISA_ZBB 50strncmp_zbb: 51 52.option push 53.option arch,+zbb 54 55 /* 56 * Returns 57 * a0 - comparison result, like strncmp 58 * 59 * Parameters 60 * a0 - string1 61 * a1 - string2 62 * a2 - number of characters to compare 63 * 64 * Clobbers 65 * t0, t1, t2, t3, t4, t5, t6 66 */ 67 68 or t2, a0, a1 69 li t5, -1 70 and t2, t2, SZREG-1 71 add t4, a0, a2 72 bnez t2, 3f 73 74 /* Adjust limit for fast-path. */ 75 andi t6, t4, -SZREG 76 77 /* Main loop for aligned string. */ 78 .p2align 3 791: 80 bge a0, t6, 3f 81 REG_L t0, 0(a0) 82 REG_L t1, 0(a1) 83 orc.b t3, t0 84 bne t3, t5, 2f 85 orc.b t3, t1 86 bne t3, t5, 2f 87 addi a0, a0, SZREG 88 addi a1, a1, SZREG 89 beq t0, t1, 1b 90 91 /* 92 * Words don't match, and no null byte in the first 93 * word. Get bytes in big-endian order and compare. 94 */ 95#ifndef CONFIG_CPU_BIG_ENDIAN 96 rev8 t0, t0 97 rev8 t1, t1 98#endif 99 100 /* Synthesize (t0 >= t1) ? 1 : -1 in a branchless sequence. */ 101 sltu a0, t0, t1 102 neg a0, a0 103 ori a0, a0, 1 104 ret 105 1062: 107 /* 108 * Found a null byte. 109 * If words don't match, fall back to simple loop. 110 */ 111 bne t0, t1, 3f 112 113 /* Otherwise, strings are equal. */ 114 li a0, 0 115 ret 116 117 /* Simple loop for misaligned strings. */ 118 .p2align 3 1193: 120 bge a0, t4, 5f 121 lbu t0, 0(a0) 122 lbu t1, 0(a1) 123 addi a0, a0, 1 124 addi a1, a1, 1 125 bne t0, t1, 4f 126 bnez t0, 3b 127 1284: 129 sub a0, t0, t1 130 ret 131 1325: 133 li a0, 0 134 ret 135 136.option pop 137#endif 138SYM_FUNC_END(strncmp) 139