File Index
Files and directories
Sign in
FILE

strlen.S

File preview with syntax highlighting.

linux-6.19.14/arch/riscv/lib/strlen.S GAS
  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 strlen(const char *s) */
  9SYM_FUNC_START(strlen)
 10
 11	__ALTERNATIVE_CFG("nop", "j strlen_zbb", 0, RISCV_ISA_EXT_ZBB,
 12		IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB))
 13
 14	/*
 15	 * Returns
 16	 *   a0 - string length
 17	 *
 18	 * Parameters
 19	 *   a0 - String to measure
 20	 *
 21	 * Clobbers:
 22	 *   t0, t1
 23	 */
 24	mv	t1, a0
 251:
 26	lbu	t0, 0(t1)
 27	beqz	t0, 2f
 28	addi	t1, t1, 1
 29	j	1b
 302:
 31	sub	a0, t1, a0
 32	ret
 33
 34/*
 35 * Variant of strlen using the ZBB extension if available
 36 */
 37#if defined(CONFIG_RISCV_ISA_ZBB) && defined(CONFIG_TOOLCHAIN_HAS_ZBB)
 38strlen_zbb:
 39
 40#ifdef CONFIG_CPU_BIG_ENDIAN
 41# define CZ	clz
 42# define SHIFT	sll
 43#else
 44# define CZ	ctz
 45# define SHIFT	srl
 46#endif
 47
 48.option push
 49.option arch,+zbb
 50
 51	/*
 52	 * Returns
 53	 *   a0 - string length
 54	 *
 55	 * Parameters
 56	 *   a0 - String to measure
 57	 *
 58	 * Clobbers
 59	 *   t0, t1, t2, t3
 60	 */
 61
 62	/* Number of irrelevant bytes in the first word. */
 63	andi	t2, a0, SZREG-1
 64
 65	/* Align pointer. */
 66	andi	t0, a0, -SZREG
 67
 68	li	t3, SZREG
 69	sub	t3, t3, t2
 70	slli	t2, t2, 3
 71
 72	/* Get the first word.  */
 73	REG_L	t1, 0(t0)
 74
 75	/*
 76	 * Shift away the partial data we loaded to remove the irrelevant bytes
 77	 * preceding the string with the effect of adding NUL bytes at the
 78	 * end of the string's first word.
 79	 */
 80	SHIFT	t1, t1, t2
 81
 82	/* Convert non-NUL into 0xff and NUL into 0x00. */
 83	orc.b	t1, t1
 84
 85	/* Convert non-NUL into 0x00 and NUL into 0xff. */
 86	not	t1, t1
 87
 88	/*
 89	 * Search for the first set bit (corresponding to a NUL byte in the
 90	 * original chunk).
 91	 */
 92	CZ	t1, t1
 93
 94	/*
 95	 * The first chunk is special: compare against the number
 96	 * of valid bytes in this chunk.
 97	 */
 98	srli	a0, t1, 3
 99	bgtu	t3, a0, 2f
100
101	/* Prepare for the word comparison loop. */
102	addi	t2, t0, SZREG
103	li	t3, -1
104
105	/*
106	 * Our critical loop is 4 instructions and processes data in
107	 * 4 byte or 8 byte chunks.
108	 */
109	.p2align 3
1101:
111	REG_L	t1, SZREG(t0)
112	addi	t0, t0, SZREG
113	orc.b	t1, t1
114	beq	t1, t3, 1b
115
116	not	t1, t1
117	CZ	t1, t1
118	srli	t1, t1, 3
119
120	/* Get number of processed bytes. */
121	sub	t2, t0, t2
122
123	/* Add number of characters in the first word.  */
124	add	a0, a0, t2
125
126	/* Add number of characters in the last word.  */
127	add	a0, a0, t1
1282:
129	ret
130
131.option pop
132#endif
133SYM_FUNC_END(strlen)
134SYM_FUNC_ALIAS(__pi_strlen, strlen)
135EXPORT_SYMBOL(strlen)
~/ Read-only file preview.