summaryrefslogtreecommitdiffstats
path: root/sys/lib/libkern/arch/sparc
diff options
context:
space:
mode:
authormiod <miod@openbsd.org>2013-06-15 19:36:59 +0000
committermiod <miod@openbsd.org>2013-06-15 19:36:59 +0000
commitee1d997df80d1c8f741874295196e52533381462 (patch)
tree63060f7c74f71292a39d720a457e3a9d2366b9be /sys/lib/libkern/arch/sparc
parentMake bcopy() involve memmove(), not memcpy(). (diff)
downloadwireguard-openbsd-ee1d997df80d1c8f741874295196e52533381462.tar.xz
wireguard-openbsd-ee1d997df80d1c8f741874295196e52533381462.zip
Preserve %o5 around Lbcopy_doubles; prevents the return value from memcpy()
and memmove() to be incorrect for copies of 32 bytes or more, when the source and destination addresses are nicely aligned.
Diffstat (limited to 'sys/lib/libkern/arch/sparc')
-rw-r--r--sys/lib/libkern/arch/sparc/memmove.S9
1 files changed, 5 insertions, 4 deletions
diff --git a/sys/lib/libkern/arch/sparc/memmove.S b/sys/lib/libkern/arch/sparc/memmove.S
index 8d2d3e62c96..504037dbbc6 100644
--- a/sys/lib/libkern/arch/sparc/memmove.S
+++ b/sys/lib/libkern/arch/sparc/memmove.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: memmove.S,v 1.4 2013/06/13 19:33:58 deraadt Exp $ */
+/* $OpenBSD: memmove.S,v 1.5 2013/06/15 19:36:59 miod Exp $ */
/*
* Copyright (c) 1996
@@ -197,16 +197,19 @@ Lbcopy_fancy:
dec 4, %o2 ! }
1:
Lbcopy_doubles:
+ mov %o5, %o3 ! save return value
+1:
ldd [%o0], %o4 ! do {
std %o4, [%o1] ! *(double *)dst = *(double *)src;
inc 8, %o0 ! dst += 8, src += 8;
deccc 8, %o2 ! } while ((len -= 8) >= 0);
- bge Lbcopy_doubles
+ bge 1b
inc 8, %o1
! check for a usual case again (save work)
btst 7, %o2 ! if ((len & 7) == 0)
be Lbcopy_done ! goto bcopy_done;
+ mov %o3, %o5 ! [delay slot: restore return value]
btst 4, %o2 ! if ((len & 4) == 0)
be,a Lbcopy_mopw ! goto mop_up_word_and_byte;
@@ -415,5 +418,3 @@ Lback_mopb:
stb %o4, [%o1 - 1] ! }
retl ! dst[-1] = b;
mov %o5, %o0 ! return (dst)
-
-