[PATCH] fix strncpy for alpha (stratcliff failure)
Glen Nakamura
glen@imodulo.com
Sat Sep 21 17:57:00 GMT 2002
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
More information about the Libc-alpha
mailing list