diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2013-06-15 19:37:00 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2013-06-15 19:37:00 +0000 |
commit | 8e54dcd1841ec6d62c7bb7f1f19e6a3d71045296 (patch) | |
tree | 993784a5855eb248f67ef54ba5599a0f022161f9 /sys/lib | |
parent | 98f094e4f0eaf4c4d07540dd6ba46acd600cf50b (diff) |
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')
-rw-r--r-- | sys/lib/libkern/arch/sparc/memmove.S | 9 |
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) - - |