summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@kanga.twiddle.net>2003-07-16 07:24:40 -0700
committerRichard Henderson <rth@kanga.twiddle.net>2003-07-16 07:24:40 -0700
commitfd1f3351485ebb28d8aad17e3d0cb540190151b5 (patch)
treec278b25eac1f8ab27eb29dc0ae39e81206544269
parentf3596aae38f06b98f76951df36a4111df25fc6d5 (diff)
[ALPHA] Do ISO C90 strncpy buffer zeroing.
-rw-r--r--arch/alpha/lib/strncpy.S59
1 files changed, 52 insertions, 7 deletions
diff --git a/arch/alpha/lib/strncpy.S b/arch/alpha/lib/strncpy.S
index 7d64d21d5af3..338551c7113c 100644
--- a/arch/alpha/lib/strncpy.S
+++ b/arch/alpha/lib/strncpy.S
@@ -16,7 +16,7 @@
.text
- .align 3
+ .align 4
.globl strncpy
.ent strncpy
strncpy:
@@ -24,13 +24,58 @@ strncpy:
.prologue 0
mov $16, $0 # set return value now
- beq $18, 0f
- mov $26, $23 # set return address
- br __stxncpy # do the work of the copy
+ beq $18, $zerolen
+ unop
+ bsr $23, __stxncpy # do the work of the copy
+
+ unop
+ bne $18, $multiword # do we have full words left?
+ subq $24, 1, $3 # nope
+ subq $27, 1, $4
+
+ or $3, $24, $3 # clear the bits between the last
+ or $4, $27, $4 # written byte and the last byte in COUNT
+ andnot $4, $3, $4
+ zap $1, $4, $1
+
+ stq_u $1, 0($16)
+ ret
+
+ .align 4
+$multiword:
+ subq $24, 1, $2 # clear the final bits in the prev word
+ or $2, $24, $2
+ zapnot $1, $2, $1
+ subq $18, 1, $18
+
+ stq_u $1, 0($16)
+ addq $16, 8, $16
+ unop
+ beq $18, 1f
-0: ret
- nop
nop
+ unop
nop
+ blbc $18, 0f
+
+ stq_u $31, 0($16) # zero one word
+ subq $18, 1, $18
+ addq $16, 8, $16
+ beq $18, 1f
+
+0: stq_u $31, 0($16) # zero two words
+ subq $18, 2, $18
+ stq_u $31, 8($16)
+ addq $16, 16, $16
+ bne $18, 0b
+
+1: ldq_u $1, 0($16) # clear the leading bits in the final word
+ subq $27, 1, $2
+ or $2, $27, $2
+
+ zap $1, $2, $1
+ stq_u $1, 0($16)
+$zerolen:
+ ret
- .end strncpy
+ .end strncpy