This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] fix strncpy for alpha (stratcliff failure)


Aloha,

This patch fixes the glibc-2.2.94 stratcliff failure on alpha-pc-linux.
With this patch, in addition to:
    http://sources.redhat.com/ml/libc-alpha/2002-09/msg00346.html
    http://sources.redhat.com/ml/libc-alpha/2002-09/msg00355.html
make check runs successfully on my system:
    alpha-pc-linux
    gcc-3.2.1 (cvs)
    binutils-2.13.90.0.4


2002-09-21  Glen Nakamura  <glen@imodulo.com>

	* sysdeps/alpha/stxncpy.S (__stxncpy):  Reschedule insns to avoid
	an extra load at the tail of the SRC buffer which may SEGV.

Index: stxncpy.S
===================================================================
RCS file: /cvs/glibc/libc/sysdeps/alpha/stxncpy.S,v
retrieving revision 1.4
diff -u -3 -p -r1.4 stxncpy.S
--- stxncpy.S	6 Jul 2001 04:55:46 -0000	1.4
+++ stxncpy.S	22 Sep 2002 00:07:46 -0000
@@ -162,7 +162,7 @@ __stxncpy:
    and cope.  We have to be very careful about not reading too much and
    causing a SEGV.  */
 
-	.align 3
+	.align 4
 $u_head:
 	/* We know just enough now to be able to assemble the first
 	   full source word.  We can still find a zero at the end of it
@@ -193,6 +193,7 @@ $u_head:
 	addq	a0, 8, a0		# .. e1 :
 	subq	a2, 1, a2		# e0    :
 	bne	t7, $u_late_head_exit	# .. e1 :
+	beq	a2, $u_eoc		# e1    :
 
 	/* Finally, we've got all the stupid leading edge cases taken care
 	   of and we can set up to enter the main loop.  */
@@ -200,9 +201,11 @@ $u_head:
 	extql	t2, a1, t1	# e0    : position hi-bits of lo word
 	ldq_u	t2, 8(a1)	# .. e1 : read next high-order source word
 	addq	a1, 8, a1	# e0    :
-	cmpbge	zero, t2, t7	# e1 (stall)
-	beq	a2, $u_eoc	# e1    :
+	addq	a0, 8, a0	# .. e1 :
+	extqh	t2, a1, t0	# e0    : position lo-bits of hi word
+	cmpbge	zero, t2, t7	# .. e1 : test new word for eos
 	bne	t7, $u_eos	# e1    :
+	nop			# ..    :
 
 	/* Unaligned copy main loop.  In order to avoid reading too much,
 	   the loop is structured to detect zeros in aligned source words.
@@ -212,6 +215,7 @@ $u_head:
 	   to run as fast as possible.
 
 	   On entry to this basic block:
+	   t0 == the shifted low-order bits from the current source word
 	   t1 == the shifted high-order bits from the previous source word
 	   t2 == the unshifted current source word
 
@@ -219,18 +223,18 @@ $u_head:
 
 	.align 3
 $u_loop:
-	extqh	t2, a1, t0	# e0    : extract high bits for current word
-	addq	a1, 8, a1	# .. e1 :
-	extql	t2, a1, t3	# e0    : extract low bits for next time
-	addq	a0, 8, a0	# .. e1 :
 	or	t0, t1, t0	# e0    : current dst word now complete
-	ldq_u	t2, 0(a1)	# .. e1 : load high word for next time
+	subq	a2, 1, a2	# .. e1 : decrement word count
 	stq_u	t0, -8(a0)	# e0    : save the current word
-	mov	t3, t1		# .. e1 :
-	subq	a2, 1, a2	# e0    :
+	beq	a2, $u_eoc	# .. e1 :
+	extql	t2, a1, t1	# e0    : extract low bits for next time
+	ldq_u	t2, 8(a1)	# .. e1 : load high word for next time
+	addq	a1, 8, a1	# e0    :
+	addq	a0, 8, a0	# .. e1 :
+	extqh	t2, a1, t0	# e0    : extract high bits for current word
 	cmpbge	zero, t2, t7	# .. e1 : test new word for eos
-	beq	a2, $u_eoc	# e1    :
 	beq	t7, $u_loop	# e1    :
+	nop			# ..    :
 
 	/* We've found a zero somewhere in the source word we just read.
 	   If it resides in the lower half, we have one (probably partial)
@@ -238,11 +242,12 @@ $u_loop:
 	   have one full and one partial word left to write out.
 
 	   On entry to this basic block:
+	   t0 == the shifted low-order bits from the current source word
 	   t1 == the shifted high-order bits from the previous source word
 	   t2 == the unshifted current source word.  */
 $u_eos:
-	extqh	t2, a1, t0	# e0    :
-	or	t0, t1, t0	# e1    : first (partial) source word complete
+	subq	a0, 8, a0	# e0    : correct pre-incremented dst address
+	or	t0, t1, t0	# .. e1 : first (partial) source word complete
 
 	cmpbge	zero, t0, t7	# e0    : is the null in this first bit?
 	bne	t7, $u_final	# .. e1 (zdb)
@@ -280,8 +285,16 @@ $u_final:
 	ret	(t9)		# .. e1 :
 
 $u_eoc:				# end-of-count
-	extqh	t2, a1, t0
-	or	t0, t1, t0
+	extql	t2, a1, t0	# e0    : extract low bits for last word
+	and	a1, 7, t6	# .. e1 :
+	sll	t10, t6, t6	# e1    :
+	zapnot	t6, 1, t6	# e0    :
+	bne	t6, 1f		# e1    : avoid src word load if we can
+
+	ldq_u	t2, 8(a1)	# .. e0 : load final src word
+	extqh	t2, a1, t1	# e0    : extract high bits for last word
+	or	t0, t1, t0	# e1    :
+1:
 	cmpbge	zero, t0, t7
 
 $u_eocfin:			# end-of-count, final word


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]