arch/arm64/lib/strcmp.S

Source file repositories/reference/linux-study-clean/arch/arm64/lib/strcmp.S

File Facts

System
Linux kernel
Corpus path
arch/arm64/lib/strcmp.S
Extension
.S
Size
4345 bytes
Lines
191
Domain
Architecture Layer
Bucket
arch/arm64
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/linkage.h>
#include <asm/assembler.h>

/* Assumptions:
 *
 * ARMv8-a, AArch64.
 * MTE compatible.
 */

#define L(label) .L ## label

#define REP8_01 0x0101010101010101
#define REP8_7f 0x7f7f7f7f7f7f7f7f

#define src1		x0
#define src2		x1
#define result		x0

#define data1		x2
#define data1w		w2
#define data2		x3
#define data2w		w3
#define has_nul		x4
#define diff		x5
#define off1		x5
#define syndrome	x6
#define tmp		x6
#define data3		x7
#define zeroones	x8
#define shift		x9
#define off2		x10

/* On big-endian early bytes are at MSB and on little-endian LSB.
   LS_FW means shifting towards early bytes.  */
#ifdef __AARCH64EB__
# define LS_FW lsl
#else
# define LS_FW lsr
#endif

/* NUL detection works on the principle that (X - 1) & (~X) & 0x80
   (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
   can be done in parallel across the entire word.
   Since carry propagation makes 0x1 bytes before a NUL byte appear
   NUL too in big-endian, byte-reverse the data before the NUL check.  */


SYM_FUNC_START(__pi_strcmp)
	sub	off2, src2, src1
	mov	zeroones, REP8_01
	and	tmp, src1, 7
	tst	off2, 7
	b.ne	L(misaligned8)
	cbnz	tmp, L(mutual_align)

	.p2align 4

L(loop_aligned):
	ldr	data2, [src1, off2]
	ldr	data1, [src1], 8
L(start_realigned):
#ifdef __AARCH64EB__
	rev	tmp, data1
	sub	has_nul, tmp, zeroones
	orr	tmp, tmp, REP8_7f
#else
	sub	has_nul, data1, zeroones
	orr	tmp, data1, REP8_7f
#endif
	bics	has_nul, has_nul, tmp	/* Non-zero if NUL terminator.  */

Annotation

Implementation Notes