aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64/amd64/support.S
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2018-09-13 14:53:51 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2018-09-13 14:53:51 +0000
commit13ea074dc3d60682bd7e56a9499e045546ef28da (patch)
treee7443fd9dbd7f1425032ded49cc1d39ec4e2c16a /sys/amd64/amd64/support.S
parente6f0c1bba2ecb4b0aba897bca22232d1a04139ed (diff)
downloadsrc-13ea074dc3d60682bd7e56a9499e045546ef28da.tar.gz
src-13ea074dc3d60682bd7e56a9499e045546ef28da.zip
amd64: implement ERMS-based memmove, memcpy and memset
Reviewed by: kib Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D17124
Notes
Notes: svn path=/head/; revision=338645
Diffstat (limited to 'sys/amd64/amd64/support.S')
-rw-r--r--sys/amd64/amd64/support.S64
1 files changed, 58 insertions, 6 deletions
diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S
index 714f100a9749..db89a6fadd3c 100644
--- a/sys/amd64/amd64/support.S
+++ b/sys/amd64/amd64/support.S
@@ -96,7 +96,7 @@ END(sse2_pagezero)
* Adapted from bcopy written by:
* ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
*/
-ENTRY(memmove)
+ENTRY(memmove_std)
PUSH_FRAME_POINTER
movq %rdi,%r9
movq %rdx,%rcx
@@ -142,7 +142,37 @@ ENTRY(memmove)
movq %r9,%rax
POP_FRAME_POINTER
ret
-END(memmove)
+END(memmove_std)
+
+ENTRY(memmove_erms)
+ PUSH_FRAME_POINTER
+ movq %rdi,%r9
+ movq %rdx,%rcx
+
+ movq %rdi,%rax
+ subq %rsi,%rax
+ cmpq %rcx,%rax /* overlapping && src < dst? */
+ jb 1f
+
+ rep
+ movsb
+ movq %r9,%rax
+ POP_FRAME_POINTER
+ ret
+
+1:
+ addq %rcx,%rdi /* copy backwards */
+ addq %rcx,%rsi
+ decq %rdi
+ decq %rsi
+ std
+ rep
+ movsb
+ cld
+ movq %r9,%rax
+ POP_FRAME_POINTER
+ ret
+END(memmove_erms)
/*
* memcpy(dst, src, len)
@@ -150,7 +180,7 @@ END(memmove)
*
* Note: memcpy does not support overlapping copies
*/
-ENTRY(memcpy)
+ENTRY(memcpy_std)
PUSH_FRAME_POINTER
movq %rdi,%rax
movq %rdx,%rcx
@@ -167,13 +197,23 @@ ENTRY(memcpy)
movsb
POP_FRAME_POINTER
ret
-END(memcpy)
+END(memcpy_std)
+
+ENTRY(memcpy_erms)
+ PUSH_FRAME_POINTER
+ movq %rdi,%rax
+ movq %rdx,%rcx
+ rep
+ movsb
+ POP_FRAME_POINTER
+ ret
+END(memcpy_erms)
/*
* memset(dst, c, len)
* rdi, rsi, rdx
*/
-ENTRY(memset)
+ENTRY(memset_std)
PUSH_FRAME_POINTER
movq %rdi,%r9
movq %rdx,%rcx
@@ -195,7 +235,19 @@ ENTRY(memset)
movq %r9,%rax
POP_FRAME_POINTER
ret
-END(memset)
+END(memset_std)
+
+ENTRY(memset_erms)
+ PUSH_FRAME_POINTER
+ movq %rdi,%r9
+ movq %rdx,%rcx
+ movb %sil,%al
+ rep
+ stosb
+ movq %r9,%rax
+ POP_FRAME_POINTER
+ ret
+END(memset_erms)
/* fillw(pat, base, cnt) */
/* %rdi,%rsi, %rdx */