shithub: mc

Download patch

ref: 1c61d05cba15d7e93d3207d4f3ab3c6043d63b77
parent: d798a21d16cbd1d866752fbde81871012a789ea8
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Jul 31 18:36:12 EDT 2017

Optimize sleq.

	Now the comparison is done in assembly, using quads for
	checking the larger loop, and words for the smaller.

--- a/lib/std/memops-impl+plan9-x64.s
+++ b/lib/std/memops-impl+plan9-x64.s
@@ -42,3 +42,36 @@
 	ANDQ	$7,CX
 	REP; STOSB 
 	RET
+
+TEXT std$memeq+0(SB),$0
+	MOVQ	DX,R8
+	ANDQ	$~0x7,R8
+	JZ	.dotail
+.nextquad:
+	MOVQ	(DI),R9
+	MOVQ	(SI),R10
+	XORQ	R10,R9
+	JNZ .unequal
+	ADDQ	$8,SI
+	ADDQ	$8,DI
+	SUBQ	$8,R8
+	JNZ .nextquad
+.dotail:
+	ANDQ	$0x7,DX
+	TESTQ	DX,DX
+	JZ .equal
+.nextbyte:
+	MOVBLZX	(DI),R9
+	MOVBLZX	(SI),R10
+	XORL	R10,R9
+	JNZ .unequal
+	ADDQ	$1,SI
+	ADDQ	$1,DI
+	SUBQ	$1,DX
+	JNZ .nextbyte
+.equal:
+	MOVQ	$1,AX
+	RET
+.unequal:
+	MOVQ	$0,AX
+	RET
--- 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 @@
 .done:
 	ret
 
+/* std.memfill	: (dst : byte#, val : byte, len : std.size -> void) */
 .globl _std$memfill
 .globl std$memfill
 _std$memfill:
@@ -46,4 +44,41 @@
 	movq	%rdx,%rcx
 	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
--- a/lib/std/memops-impl.myr
+++ b/lib/std/memops-impl.myr
@@ -3,6 +3,7 @@
 pkg std =
 	pkglocal const memblit	: (dst : byte#, src : byte#, len : std.size -> void)
 	pkglocal const memfill	: (dst : byte#, val : byte, len : std.size -> void)
+	pkglocal const memeq	: (a : byte#, b : byte#, len : std.size -> bool)
 ;;
 
 
@@ -35,5 +36,18 @@
 	for var i = 0; i < d.len; i++
 		d[i] = val
 	;;
+}
+
+const memeq = {a, b, len
+	var sa, sb
+
+	sa = a[:len]
+	sb = b[:len]
+	for i = 0; i < len; i++
+		if sa[i] != sb[i]
+			-> false
+		;;
+	;;
+	-> true
 }
 
--- a/lib/std/memops.myr
+++ b/lib/std/memops.myr
@@ -3,5 +3,6 @@
 pkg std =
 	pkglocal extern const memblit	: (dst : byte#, src : byte#, len : std.size -> void)
 	pkglocal extern const memfill	: (dst : byte#, val : byte, len : std.size -> void)
+	pkglocal extern const memeq	: (a : byte#, b : byte#, len : std.size -> bool)
 ;;
 
--- a/lib/std/sleq.myr
+++ b/lib/std/sleq.myr
@@ -1,18 +1,14 @@
+use "types"
+use "memops"
+
 pkg std =
 	generic sleq	: (a : @a[:], b : @a[:] -> bool)
 ;;
 
 generic sleq = {a, b
-	var i
-
-	if a.len != b.len
+	if a.len == b.len
+		-> memeq((a : byte#), (b : byte#), a.len)
+	else
 		-> false
 	;;
-
-	for i = 0; i < a.len; i++
-		if a[i] != b[i]
-			-> false
-		;;
-	;;
-	-> true
 }