aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/amd64
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2018-12-01 14:20:32 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2018-12-01 14:20:32 +0000
commitddf6571230dd508f458982c911ba332da0fcbab4 (patch)
tree64e0c9ef61c5768dae12e66b81a486619d1a2c74 /lib/libc/amd64
parentdf5ceb3b666f4a6492219040cf36f6114fa234f6 (diff)
downloadsrc-ddf6571230dd508f458982c911ba332da0fcbab4.tar.gz
src-ddf6571230dd508f458982c911ba332da0fcbab4.zip
amd64: align target memmove buffer to 16 bytes before using rep movs
See the review for sample test results. Reviewed by: kib (kernel part) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D18401
Notes
Notes: svn path=/head/; revision=341364
Diffstat (limited to 'lib/libc/amd64')
-rw-r--r--lib/libc/amd64/string/memmove.S30
1 files changed, 30 insertions, 0 deletions
diff --git a/lib/libc/amd64/string/memmove.S b/lib/libc/amd64/string/memmove.S
index 5a466f7a7d69..accc86440610 100644
--- a/lib/libc/amd64/string/memmove.S
+++ b/lib/libc/amd64/string/memmove.S
@@ -139,6 +139,8 @@ __FBSDID("$FreeBSD$");
ALIGN_TEXT
1256:
+ testb $15,%dil
+ jnz 100f
.if \erms == 1
rep
movsb
@@ -152,6 +154,34 @@ __FBSDID("$FreeBSD$");
.endif
\end
ret
+100:
+ movq (%rsi),%r8
+ movq 8(%rsi),%r9
+ movq %rdi,%r10
+ movq %rdi,%rcx
+ andq $15,%rcx
+ leaq -16(%rdx,%rcx),%rdx
+ neg %rcx
+ leaq 16(%rdi,%rcx),%rdi
+ leaq 16(%rsi,%rcx),%rsi
+ movq %rdx,%rcx
+.if \erms == 1
+ rep
+ movsb
+ movq %r8,(%r10)
+ movq %r9,8(%r10)
+.else
+ shrq $3,%rcx /* copy by 64-bit words */
+ rep
+ movsq
+ movq %r8,(%r10)
+ movq %r9,8(%r10)
+ movq %rdx,%rcx
+ andl $7,%ecx /* any bytes left? */
+ jne 100408b
+.endif
+ \end
+ ret
.if \overlap == 1
/*