summaryrefslogtreecommitdiff
path: root/lib/std/memops-impl+posixy-x64.s
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2017-07-31 22:36:12 -0700
committerOri Bernstein <ori@eigenstate.org>2017-07-31 22:46:36 -0700
commit1c61d05cba15d7e93d3207d4f3ab3c6043d63b77 (patch)
treef602ad598abbd25985cf302a4dda0085eeb120ab /lib/std/memops-impl+posixy-x64.s
parentd798a21d16cbd1d866752fbde81871012a789ea8 (diff)
downloadmc-1c61d05cba15d7e93d3207d4f3ab3c6043d63b77.tar.gz
Optimize sleq.
Now the comparison is done in assembly, using quads for checking the larger loop, and words for the smaller.
Diffstat (limited to 'lib/std/memops-impl+posixy-x64.s')
-rw-r--r--lib/std/memops-impl+posixy-x64.s43
1 files changed, 39 insertions, 4 deletions
diff --git a/lib/std/memops-impl+posixy-x64.s b/lib/std/memops-impl+posixy-x64.s
index c2a3d14..899aaca 100644
--- a/lib/std/memops-impl+posixy-x64.s
+++ b/lib/std/memops-impl+posixy-x64.s
@@ -1,7 +1,4 @@
-/*
-std.memblit : (dst : byte#, src : byte#, len : std.size -> void)
-std.memfill : (dst : byte#, val : byte, len : std.size -> void)
-*/
+/* std.memblit : (dst : byte#, src : byte#, len : std.size -> void) */
.globl _std$memblit
.globl std$memblit
_std$memblit:
@@ -30,6 +27,7 @@ std$memblit:
.done:
ret
+/* std.memfill : (dst : byte#, val : byte, len : std.size -> void) */
.globl _std$memfill
.globl std$memfill
_std$memfill:
@@ -47,3 +45,40 @@ std$memfill:
andq $7,%rcx
rep stosb
ret
+
+/* std.memeq : (a : byte#, b : byte#, len : std.size -> bool) */
+.globl _std$memeq
+.globl std$memeq
+_std$memeq:
+std$memeq:
+ movq %rdx,%r8
+ andq $~0x7,%r8
+ jz .dotail
+.nextquad:
+ movq (%rdi),%r9
+ movq (%rsi),%r10
+ xorq %r10,%r9
+ jnz .unequal
+ addq $8,%rsi
+ addq $8,%rdi
+ subq $8,%r8
+ jnz .nextquad
+.dotail:
+ andq $0x7,%rdx
+ testq %rdx,%rdx
+ jz .equal
+.nextbyte:
+ movzbl (%rdi),%r9d
+ movzbl (%rsi),%r10d
+ xorl %r10d,%r9d
+ jnz .unequal
+ addq $1,%rsi
+ addq $1,%rdi
+ subq $1,%rdx
+ jnz .nextbyte
+.equal:
+ movq $1,%rax
+ ret
+.unequal:
+ movq $0,%rax
+ ret