arch/alpha/lib/stxncpy.S

Source file repositories/reference/linux-study-clean/arch/alpha/lib/stxncpy.S

File Facts

System
Linux kernel
Corpus path
arch/alpha/lib/stxncpy.S
Extension
.S
Size
10883 bytes
Lines
347
Domain
Architecture Layer
Bucket
arch/alpha
Inferred role
Architecture Layer: arch/alpha
Status
atlas-only

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 <asm/regdef.h>

	.set noat
	.set noreorder

	.text

/* There is a problem with either gdb (as of 4.16) or gas (as of 2.7) that
   doesn't like putting the entry point for a procedure somewhere in the
   middle of the procedure descriptor.  Work around this by putting the
   aligned copy in its own procedure descriptor */

	.ent stxncpy_aligned
	.align 3
stxncpy_aligned:
	.frame sp, 0, t9, 0
	.prologue 0

	/* On entry to this basic block:
	   t0 == the first destination word for masking back in
	   t1 == the first source word.  */

	/* Create the 1st output word and detect 0's in the 1st input word.  */
	lda	t2, -1		# e1    : build a mask against false zero
	mskqh	t2, a1, t2	# e0    :   detection in the src word
	mskqh	t1, a1, t3	# e0    :
	ornot	t1, t2, t2	# .. e1 :
	mskql	t0, a1, t0	# e0    : assemble the first output word
	cmpbge	zero, t2, t8	# .. e1 : bits set iff null found
	or	t0, t3, t0	# e0    :
	beq	a2, $a_eoc	# .. e1 :
	bne	t8, $a_eos	# .. e1 :

	/* On entry to this basic block:
	   t0 == a source word not containing a null.  */

$a_loop:
	stq_u	t0, 0(a0)	# e0    :
	addq	a0, 8, a0	# .. e1 :
	ldq_u	t0, 0(a1)	# e0    :
	addq	a1, 8, a1	# .. e1 :
	subq	a2, 1, a2	# e0    :
	cmpbge	zero, t0, t8	# .. e1 (stall)
	beq	a2, $a_eoc      # e1    :
	beq	t8, $a_loop	# e1    :

	/* Take care of the final (partial) word store.  At this point
	   the end-of-count bit is set in t8 iff it applies.

	   On entry to this basic block we have:
	   t0 == the source word containing the null
	   t8 == the cmpbge mask that found it.  */

$a_eos:
	negq	t8, t12		# e0    : find low bit set
	and	t8, t12, t12	# e1 (stall)

	/* For the sake of the cache, don't read a destination word
	   if we're not going to need it.  */
	and	t12, 0x80, t6	# e0    :
	bne	t6, 1f		# .. e1 (zdb)

	/* We're doing a partial word store and so need to combine
	   our source and original destination words.  */
	ldq_u	t1, 0(a0)	# e0    :
	subq	t12, 1, t6	# .. e1 :
	or	t12, t6, t8	# e0    :
	unop			#
	zapnot	t0, t8, t0	# e0    : clear src bytes > null
	zap	t1, t8, t1	# .. e1 : clear dst bytes <= null

Annotation

Implementation Notes