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