summaryrefslogtreecommitdiff
path: root/sys/lib/libkern/arch/mips64/bcopy.S
diff options
context:
space:
mode:
Diffstat (limited to 'sys/lib/libkern/arch/mips64/bcopy.S')
-rw-r--r--sys/lib/libkern/arch/mips64/bcopy.S96
1 files changed, 96 insertions, 0 deletions
diff --git a/sys/lib/libkern/arch/mips64/bcopy.S b/sys/lib/libkern/arch/mips64/bcopy.S
new file mode 100644
index 00000000000..abf52789ee2
--- /dev/null
+++ b/sys/lib/libkern/arch/mips64/bcopy.S
@@ -0,0 +1,96 @@
+/* $OpenBSD: bcopy.S,v 1.1 2004/08/11 10:29:59 pefo Exp $ */
+
+#include "DEFS.h"
+
+
+/*
+ * memcpy(to, from, len)
+ * {ov}bcopy(from, to, len)
+ */
+LEAF(memcpy)
+ .set noreorder
+ move v0, a0 # swap from and to
+ move a0, a1
+ move a1, v0
+ALEAF(bcopy)
+ALEAF(ovbcopy)
+ .set noreorder
+ addu t0, a0, a2 # t0 = end of s1 region
+ sltu t1, a1, t0
+ sltu t2, a0, a1
+ and t1, t1, t2 # t1 = true if from < to < (from+len)
+ beq t1, zero, forward # non overlapping, do forward copy
+ slt t2, a2, 12 # check for small copy
+
+ ble a2, zero, 2f
+ addu t1, a1, a2 # t1 = end of to region
+1:
+ lb v1, -1(t0) # copy bytes backwards,
+ subu t0, t0, 1 # doesnt happen often so do slow way
+ subu t1, t1, 1
+ bne t0, a0, 1b
+ sb v1, 0(t1)
+2:
+ j ra
+ nop
+forward:
+ bne t2, zero, smallcpy # do a small bcopy
+ xor v1, a0, a1 # compare low two bits of addresses
+ and v1, v1, 3
+ subu a3, zero, a1 # compute # bytes to word align address
+ beq v1, zero, aligned # addresses can be word aligned
+ and a3, a3, 3
+
+ beq a3, zero, 1f
+ subu a2, a2, a3 # subtract from remaining count
+ LWHI v1, 0(a0) # get next 4 bytes (unaligned)
+ LWLO v1, 3(a0)
+ addu a0, a0, a3
+ SWHI v1, 0(a1) # store 1, 2, or 3 bytes to align a1
+ addu a1, a1, a3
+1:
+ and v1, a2, 3 # compute number of words left
+ subu a3, a2, v1
+ move a2, v1
+ addu a3, a3, a0 # compute ending address
+2:
+ LWHI v1, 0(a0) # copy words a0 unaligned, a1 aligned
+ LWLO v1, 3(a0)
+ addu a0, a0, 4
+ sw v1, 0(a1)
+ addu a1, a1, 4
+ bne a0, a3, 2b
+ nop # We have to do this mmu-bug.
+ b smallcpy
+ nop
+aligned:
+ beq a3, zero, 1f
+ subu a2, a2, a3 # subtract from remaining count
+ LWHI v1, 0(a0) # copy 1, 2, or 3 bytes to align
+ addu a0, a0, a3
+ SWHI v1, 0(a1)
+ addu a1, a1, a3
+1:
+ and v1, a2, 3 # compute number of whole words left
+ subu a3, a2, v1
+ move a2, v1
+ addu a3, a3, a0 # compute ending address
+2:
+ lw v1, 0(a0) # copy words
+ addu a0, a0, 4
+ sw v1, 0(a1)
+ bne a0, a3, 2b
+ addu a1, a1, 4
+smallcpy:
+ ble a2, zero, 2f
+ addu a3, a2, a0 # compute ending address
+1:
+ lbu v1, 0(a0) # copy bytes
+ addu a0, a0, 1
+ sb v1, 0(a1)
+ bne a0, a3, 1b
+ addu a1, a1, 1 # MMU BUG ? can not do -1(a1) at 0x80000000!!
+2:
+ j ra
+ nop
+END(memcpy)