~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/riscv/lib/strncmp.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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) */
  9 SYM_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
 26 1:
 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
 35 2:
 36         li      a0, 0
 37         ret
 38 3:
 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
 50 strncmp_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
 79 1:
 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 
106 2:
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
119 3:
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 
128 4:
129         sub     a0, t0, t1
130         ret
131 
132 5:
133         li      a0, 0
134         ret
135 
136 .option pop
137 #endif
138 SYM_FUNC_END(strncmp)
139 SYM_FUNC_ALIAS(__pi_strncmp, strncmp)
140 EXPORT_SYMBOL(strncmp)

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php