summaryrefslogtreecommitdiff
path: root/sys/lib
diff options
context:
space:
mode:
Diffstat (limited to 'sys/lib')
-rw-r--r--sys/lib/libkern/arch/m88k/Makefile.inc4
-rw-r--r--sys/lib/libkern/arch/m88k/bcopy.S4
-rw-r--r--sys/lib/libkern/arch/m88k/bzero.S195
-rw-r--r--sys/lib/libkern/arch/m88k/copy_subr.S362
-rw-r--r--sys/lib/libkern/arch/m88k/memcpy.S4
-rw-r--r--sys/lib/libkern/arch/m88k/memmove.S4
-rw-r--r--sys/lib/libkern/arch/m88k/ovbcopy.S4
7 files changed, 576 insertions, 1 deletions
diff --git a/sys/lib/libkern/arch/m88k/Makefile.inc b/sys/lib/libkern/arch/m88k/Makefile.inc
index d34437d10d7..74bbefb2a4a 100644
--- a/sys/lib/libkern/arch/m88k/Makefile.inc
+++ b/sys/lib/libkern/arch/m88k/Makefile.inc
@@ -1,6 +1,8 @@
-# $OpenBSD: Makefile.inc,v 1.8 2004/04/01 20:39:59 miod Exp $
+# $OpenBSD: Makefile.inc,v 1.9 2006/11/17 22:32:38 miod Exp $
SRCS+= __main.c imax.c imin.c lmax.c lmin.c max.c min.c ulmax.c ulmin.c \
memchr.c memcmp.c memset.c bcmp.c random.c \
strcmp.c strlcat.c strlcpy.c strlen.c strncmp.c \
strncpy.c scanc.c skpc.c strncasecmp.c ffs.c
+
+SRCS+= bcopy.S bzero.S memcpy.S memmove.S ovbcopy.S
diff --git a/sys/lib/libkern/arch/m88k/bcopy.S b/sys/lib/libkern/arch/m88k/bcopy.S
new file mode 100644
index 00000000000..7998a00c64a
--- /dev/null
+++ b/sys/lib/libkern/arch/m88k/bcopy.S
@@ -0,0 +1,4 @@
+/* $OpenBSD: bcopy.S,v 1.1 2006/11/17 22:32:38 miod Exp $ */
+
+#define BCOPY
+#include "copy_subr.S"
diff --git a/sys/lib/libkern/arch/m88k/bzero.S b/sys/lib/libkern/arch/m88k/bzero.S
new file mode 100644
index 00000000000..071b3304998
--- /dev/null
+++ b/sys/lib/libkern/arch/m88k/bzero.S
@@ -0,0 +1,195 @@
+/* $OpenBSD: bzero.S,v 1.1 2006/11/17 22:32:38 miod Exp $ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1992 Carnegie Mellon University
+ * Copyright (c) 1991 OMRON Corporation
+ * Copyright (c) 1996 Nivas Madhur
+ * Copyright (c) 1998 Steve Murphree, Jr.
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+
+/*######################################################################*/
+
+/*
+ * April 1990, Omron Corporation
+ * jfriedl@nff.ncl.omron.co.jp
+ *
+ * void bzero(destination, length)
+ *
+ * Clear (set to zero) LENGTH bytes of memory starting at DESTINATION.
+ * Note that there is no return value.
+ *
+ * This is fast. Really fast. Especially for long lengths.
+ */
+#define R_dest r2
+#define R_len r3
+
+#define R_bytes r4
+#define R_mark_address r5
+#define R_addr r6 /* R_addr && R_temp SHARE */
+#define R_temp r6 /* R_addr && R_temp SHARE */
+
+ENTRY(bzero)
+ /*
+ * If the destination is not word aligned, we'll word align
+ * it first to make things easier.
+ *
+ * We'll check to see first if bit #0 is set and then bit #1
+ * (of the destination address). If either are set, it's
+ * not word aligned.
+ */
+ bb1 0, R_dest, _ASM_LABEL(not_initially_word_aligned)
+ bb1 1, R_dest, _ASM_LABEL(not_initially_word_aligned)
+
+ASLOCAL(now_word_aligned)
+ /*
+ * before we get into the main loop, grab the
+ * address of the label "mark" below.
+ */
+ or.u R_mark_address, r0, hi16(_ASM_LABEL(mark))
+ or R_mark_address, R_mark_address, lo16(_ASM_LABEL(mark))
+
+ASLOCAL(top_of_main_loop)
+#define MAX_AT_ONE_TIME 128
+ /*
+ * Now we find out how many words we can zero-fill in a row.
+ * We do this by doing something like:
+ *
+ * bytes &= 0xfffffffc;
+ * if (bytes > MAX_AT_ONE_TIME)
+ * bytes = MAX_AT_ONE_TIME;
+ */
+
+ /*
+ * Clear lower two bits of length to give us the number of bytes
+ * ALIGNED TO THE WORD LENGTH remaining to move.
+ */
+ clr R_bytes, R_len, 2<0>
+
+ /* if we're done clearing WORDS, jump out */
+ bcnd eq0, R_bytes, _ASM_LABEL(done_doing_words)
+
+ /* if the number of bytes > MAX_AT_ONE_TIME, do only the max */
+ cmp R_temp, R_bytes, MAX_AT_ONE_TIME
+ bb1 lt, R_temp, 1f
+
+ /*
+ * Since we're doing the max, we know exactly where we're
+ * jumping (the first one in the list!), so we can jump
+ * right there. However, we've still got to adjust
+ * the length, so we'll jump to where we ajust the length
+ * which just happens to fall through to the first store zero
+ * in the list.
+ *
+ * Note, however, that we're jumping to an instruction that
+ * would be in the delay slot for the jump in front of it,
+ * so if you change things here, WATCH OUT.
+ */
+ br.n do_max
+ or R_bytes, r0, MAX_AT_ONE_TIME
+
+1:
+ /*
+ * Now we have the number of bytes to zero during this iteration,
+ * (which, as it happens, is the last iteration if we're here).
+ * We'll calculate the proper place to jump and then jump there,
+ * after adjusting the length. NOTE that there is a label between
+ * the "jmp.n" and the "subu" below... the "subu" is NOT always
+ * executed in the delay slot of the "jmp.n".
+ */
+ subu R_addr, R_mark_address, R_bytes
+
+ /* and go there (after adjusting the length via ".n") */
+ jmp.n R_addr
+ASLOCAL(do_max)
+ subu R_len, R_len, R_bytes /* NOTE: this is in the delay slot! */
+
+ st r0, R_dest, 0x7c /* 128 */
+ st r0, R_dest, 0x78 /* 124 */
+ st r0, R_dest, 0x74 /* 120 */
+ st r0, R_dest, 0x70 /* 116 */
+ st r0, R_dest, 0x6c /* 112 */
+ st r0, R_dest, 0x68 /* 108 */
+ st r0, R_dest, 0x64 /* 104 */
+ st r0, R_dest, 0x60 /* 100 */
+ st r0, R_dest, 0x5c /* 96 */
+ st r0, R_dest, 0x58 /* 92 */
+ st r0, R_dest, 0x54 /* 88 */
+ st r0, R_dest, 0x50 /* 84 */
+ st r0, R_dest, 0x4c /* 80 */
+ st r0, R_dest, 0x48 /* 76 */
+ st r0, R_dest, 0x44 /* 72 */
+ st r0, R_dest, 0x40 /* 68 */
+ st r0, R_dest, 0x3c /* 64 */
+ st r0, R_dest, 0x38 /* 60 */
+ st r0, R_dest, 0x34 /* 56 */
+ st r0, R_dest, 0x30 /* 52 */
+ st r0, R_dest, 0x2c /* 44 */
+ st r0, R_dest, 0x28 /* 40 */
+ st r0, R_dest, 0x24 /* 36 */
+ st r0, R_dest, 0x20 /* 32 */
+ st r0, R_dest, 0x1c /* 28 */
+ st r0, R_dest, 0x18 /* 24 */
+ st r0, R_dest, 0x14 /* 20 */
+ st r0, R_dest, 0x10 /* 16 */
+ st r0, R_dest, 0x0c /* 12 */
+ st r0, R_dest, 0x08 /* 8 */
+ st r0, R_dest, 0x04 /* 4 */
+ st r0, R_dest, 0x00 /* 0 */
+
+ASLOCAL(mark)
+ br.n _ASM_LABEL(top_of_main_loop)
+ addu R_dest, R_dest, R_bytes /* bump up the dest address */
+
+ASLOCAL(done_doing_words)
+ bcnd ne0, R_len, 1f
+ jmp r1
+
+1:
+ subu R_len, R_len, 1
+ bcnd.n ne0, R_len, 1b
+ st.b r0, R_dest, R_len
+1:
+ jmp r1
+
+ASLOCAL(not_initially_word_aligned)
+ /*
+ * Bzero to word-align the address (at least if the length allows it).
+ */
+ bcnd eq0, R_len, 1b
+ st.b r0, R_dest, 0
+ addu R_dest, R_dest, 1
+ mask R_temp, R_dest, 0x3
+ bcnd.n eq0, R_temp, _ASM_LABEL(now_word_aligned)
+ subu R_len, R_len, 1
+ br _ASM_LABEL(not_initially_word_aligned)
+
+#undef R_dest
+#undef R_len
+#undef R_bytes
+#undef R_mark_address
+#undef R_addr
+#undef R_temp
+#undef MAX_AT_ONE_TIME
diff --git a/sys/lib/libkern/arch/m88k/copy_subr.S b/sys/lib/libkern/arch/m88k/copy_subr.S
new file mode 100644
index 00000000000..a8aef9c6b44
--- /dev/null
+++ b/sys/lib/libkern/arch/m88k/copy_subr.S
@@ -0,0 +1,362 @@
+/* $OpenBSD: copy_subr.S,v 1.1 2006/11/17 22:32:38 miod Exp $ */
+/*
+ * Mach Operating System
+ * Copyright (c) 1993-1992 Carnegie Mellon University
+ * Copyright (c) 1991 OMRON Corporation
+ * Copyright (c) 1996 Nivas Madhur
+ * Copyright (c) 1998 Steve Murphree, Jr.
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <machine/asm.h>
+
+/*
+ * copy count bytes of data from source to destination
+ * Don Harper (don@omron.co.jp), Omron Corporation.
+ */
+
+#if defined(MEMCPY) || defined(MEMMOVE)
+#define SRC r3
+#define DST r2
+#define SAVE r5
+#else
+#define SRC r2
+#define DST r3
+#endif
+#define LEN r4
+
+#ifdef MEMCPY
+ENTRY(memcpy)
+#endif
+#ifdef MEMMOVE
+ENTRY(memmove)
+#endif
+#ifdef BCOPY
+ENTRY(bcopy)
+#endif
+#ifdef OVBCOPY
+ENTRY(ovbcopy)
+#endif
+
+#if defined(MEMCPY) || defined(MEMMOVE)
+ or SAVE, DST, r0
+#endif
+
+ bcnd eq0,LEN,_ASM_LABEL(bcopy_out) /* nothing to do if == 0 */
+
+/*
+ * check position of source and destination data
+ */
+ cmp r9,SRC,DST /* compare source address to destination */
+ bb1 eq,r9,_ASM_LABEL(bcopy_out) /* nothing to do if equal */
+#if defined(MEMMOVE) || defined(OVBCOPY)
+ bb1 lo,r9,_ASM_LABEL(bcopy_reverse) /* reverse copy if src < dest */
+#endif
+
+/*
+ * source address is greater than destination address, or we do
+ * not have to care about overlapping areas: copy forward
+ */
+ cmp r9,LEN,16 /* see if we have at least 16 bytes */
+ bb1 lt,r9,_ASM_LABEL(f_byte_copy) /* copy bytes for small data length */
+/*
+ * determine copy strategy based on alignment of source and destination
+ */
+ mask r6,SRC,3 /* get 2 low order bits of source address */
+ mask r7,DST,3 /* get 2 low order bits of destintation addr */
+ mak r6,r6,0<4> /* convert source bits to table offset */
+ mak r7,r7,0<2> /* convert destination bits to table offset */
+ or.u r12,r0,hi16(_ASM_LABEL(f_strat))
+ or r12,r12,lo16(_ASM_LABEL(f_strat))
+ addu r6,r6,r7 /* compute final table offset for strategy */
+ ld r12,r12,r6 /* load the strategy routine */
+ jmp r12 /* branch to strategy routine */
+
+/*
+ * Copy three bytes from src to destination then copy words
+ */
+ASLOCAL(f_3byte_word_copy)
+ ld.bu r6,SRC,0 /* load byte from source */
+ ld.bu r7,SRC,1 /* load byte from source */
+ ld.bu r8,SRC,2 /* load byte from source */
+ st.b r6,DST,0 /* store byte to destination */
+ st.b r7,DST,1 /* store byte to destination */
+ st.b r8,DST,2 /* store byte to destination */
+ addu SRC,SRC,3 /* increment source pointer */
+ addu DST,DST,3 /* increment destination pointer */
+ br.n _ASM_LABEL(f_word_copy) /* copy full words */
+ subu LEN,LEN,3 /* decrement length */
+
+/*
+ * Copy 1 halfword from src to destination then copy words
+ */
+ASLOCAL(f_1half_word_copy)
+ ld.hu r6,SRC,0 /* load half-word from source */
+ st.h r6,DST,0 /* store half-word to destination */
+ addu SRC,SRC,2 /* increment source pointer */
+ addu DST,DST,2 /* increment destination pointer */
+ br.n _ASM_LABEL(f_word_copy) /* copy full words */
+ subu LEN,LEN,2 /* decrement remaining length */
+
+/*
+ * Copy 1 byte from src to destination then copy words
+ */
+ASLOCAL(f_1byte_word_copy)
+ ld.bu r6,SRC,0 /* load 1 byte from source */
+ st.b r6,DST,0 /* store 1 byte to destination */
+ addu SRC,SRC,1 /* increment source pointer */
+ addu DST,DST,1 /* increment destination pointer */
+ subu LEN,LEN,1 /* decrement remaining length */
+ /* FALLTHROUGH */
+/*
+ * Copy as many full words as possible, 4 words per loop
+ */
+ASLOCAL(f_word_copy)
+ cmp r10,LEN,16 /* see if we have 16 bytes remaining */
+ bb1 lo,r10,_ASM_LABEL(f_byte_copy) /* not enough left, copy bytes */
+ ld r6,SRC,0 /* load first word */
+ ld r7,SRC,4 /* load second word */
+ ld r8,SRC,8 /* load third word */
+ ld r9,SRC,12 /* load fourth word */
+ st r6,DST,0 /* store first word */
+ st r7,DST,4 /* store second word */
+ st r8,DST,8 /* store third word */
+ st r9,DST,12 /* store fourth word */
+ addu SRC,SRC,16 /* increment source pointer */
+ addu DST,DST,16 /* increment destination pointer */
+ br.n _ASM_LABEL(f_word_copy) /* branch to copy another block */
+ subu LEN,LEN,16 /* decrement remaining length */
+
+ASLOCAL(f_1byte_half_copy)
+ ld.bu r6,SRC,0 /* load 1 byte from source */
+ st.b r6,DST,0 /* store 1 byte to destination */
+ addu SRC,SRC,1 /* increment source pointer */
+ addu DST,DST,1 /* increment destination pointer */
+ subu LEN,LEN,1 /* decrement remaining length */
+ /* FALLTHROUGH */
+
+ASLOCAL(f_half_copy)
+ cmp r10,LEN,16 /* see if we have 16 bytes remaining */
+ bb1 lo,r10,_ASM_LABEL(f_byte_copy) /* not enough left, copy bytes */
+ ld.hu r6,SRC,0 /* load first half-word */
+ ld.hu r7,SRC,2 /* load second half-word */
+ ld.hu r8,SRC,4 /* load third half-word */
+ ld.hu r9,SRC,6 /* load fourth half-word */
+ ld.hu r10,SRC,8 /* load fifth half-word */
+ ld.hu r11,SRC,10 /* load sixth half-word */
+ ld.hu r12,SRC,12 /* load seventh half-word */
+ ld.hu r13,SRC,14 /* load eighth half-word */
+ st.h r6,DST,0 /* store first half-word */
+ st.h r7,DST,2 /* store second half-word */
+ st.h r8,DST,4 /* store third half-word */
+ st.h r9,DST,6 /* store fourth half-word */
+ st.h r10,DST,8 /* store fifth half-word */
+ st.h r11,DST,10 /* store sixth half-word */
+ st.h r12,DST,12 /* store seventh half-word */
+ st.h r13,DST,14 /* store eighth half-word */
+ addu SRC,SRC,16 /* increment source pointer */
+ addu DST,DST,16 /* increment destination pointer */
+ br.n _ASM_LABEL(f_half_copy) /* branch to copy another block */
+ subu LEN,LEN,16 /* decrement remaining length */
+
+ASLOCAL(f_byte_copy)
+ bcnd eq0,LEN,_ASM_LABEL(bcopy_out) /* branch if nothing left to copy */
+ ld.bu r6,SRC,0 /* load byte from source */
+ st.b r6,DST,0 /* store byte in destination */
+ addu SRC,SRC,1 /* increment source pointer */
+ addu DST,DST,1 /* increment destination pointer */
+ br.n _ASM_LABEL(f_byte_copy) /* branch for next byte */
+ subu LEN,LEN,1 /* decrement remaining length */
+
+#if defined(MEMMOVE) || defined(OVBCOPY)
+/*
+ * source address is less than destination address, copy in reverse
+ */
+ASLOCAL(bcopy_reverse)
+/*
+ * start copy pointers at end of data
+ */
+ addu SRC,SRC,LEN /* start source at end of data */
+ addu DST,DST,LEN /* start destination at end of data */
+/*
+ * check for short data
+ */
+ cmp r9,LEN,16 /* see if we have at least 16 bytes */
+ bb1 lt,r9,_ASM_LABEL(r_byte_copy) /* copy bytes for small data length */
+/*
+ * determine copy strategy based on alignment of source and destination
+ */
+ mask r6,SRC,3 /* get 2 low order bits of source address */
+ mask r7,DST,3 /* get 2 low order bits of destintation addr */
+ mak r6,r6,0<4> /* convert source bits to table offset */
+ mak r7,r7,0<2> /* convert destination bits to table offset */
+ or.u r12,r0,hi16(_ASM_LABEL(r_strat))
+ or r12,r12,lo16(_ASM_LABEL(r_strat))
+ addu r6,r6,r7 /* compute final table offset for strategy */
+ ld r12,r12,r6 /* load the strategy routine */
+ jmp r12 /* branch to strategy routine */
+
+/*
+ * Copy three bytes from src to destination then copy words
+ */
+ASLOCAL(r_3byte_word_copy)
+ subu SRC,SRC,3 /* decrement source pointer */
+ subu DST,DST,3 /* decrement destination pointer */
+ ld.bu r6,SRC,0 /* load byte from source */
+ ld.bu r7,SRC,1 /* load byte from source */
+ ld.bu r8,SRC,2 /* load byte from source */
+ st.b r6,DST,0 /* store byte to destination */
+ st.b r7,DST,1 /* store byte to destination */
+ st.b r8,DST,2 /* store byte to destination */
+ br.n _ASM_LABEL(r_word_copy) /* copy full words */
+ subu LEN,LEN,3 /* decrement length */
+
+/*
+ * Copy 1 halfword from src to destination then copy words
+ */
+ASLOCAL(r_1half_word_copy)
+ subu SRC,SRC,2 /* decrement source pointer */
+ subu DST,DST,2 /* decrement destination pointer */
+ ld.hu r6,SRC,0 /* load half-word from source */
+ st.h r6,DST,0 /* store half-word to destination */
+ br.n _ASM_LABEL(r_word_copy) /* copy full words */
+ subu LEN,LEN,2 /* decrement remaining length */
+
+/*
+ * Copy 1 byte from src to destination then copy words
+ */
+ASLOCAL(r_1byte_word_copy)
+ subu SRC,SRC,1 /* decrement source pointer */
+ subu DST,DST,1 /* decrement destination pointer */
+ ld.bu r6,SRC,0 /* load 1 byte from source */
+ st.b r6,DST,0 /* store 1 byte to destination */
+ subu LEN,LEN,1 /* decrement remaining length */
+ /* FALLTHROUGH */
+/*
+ * Copy as many full words as possible, 4 words per loop
+ */
+ASLOCAL(r_word_copy)
+ cmp r10,LEN,16 /* see if we have 16 bytes remaining */
+ bb1 lo,r10,_ASM_LABEL(r_byte_copy) /* not enough left, copy bytes */
+ subu SRC,SRC,16 /* decrement source pointer */
+ subu DST,DST,16 /* decrement destination pointer */
+ ld r6,SRC,0 /* load first word */
+ ld r7,SRC,4 /* load second word */
+ ld r8,SRC,8 /* load third word */
+ ld r9,SRC,12 /* load fourth word */
+ st r6,DST,0 /* store first word */
+ st r7,DST,4 /* store second word */
+ st r8,DST,8 /* store third word */
+ st r9,DST,12 /* store fourth word */
+ br.n _ASM_LABEL(r_word_copy) /* branch to copy another block */
+ subu LEN,LEN,16 /* decrement remaining length */
+
+ASLOCAL(r_1byte_half_copy)
+ subu SRC,SRC,1 /* decrement source pointer */
+ subu DST,DST,1 /* decrement destination pointer */
+ ld.bu r6,SRC,0 /* load 1 byte from source */
+ st.b r6,DST,0 /* store 1 byte to destination */
+ subu LEN,LEN,1 /* decrement remaining length */
+ /* FALLTHROUGH */
+
+ASLOCAL(r_half_copy)
+ cmp r10,LEN,16 /* see if we have 16 bytes remaining */
+ bb1 lo,r10,_ASM_LABEL(r_byte_copy) /* not enough left, copy bytes */
+ subu SRC,SRC,16 /* decrement source pointer */
+ subu DST,DST,16 /* decrement destination pointer */
+ ld.hu r6,SRC,0 /* load first half-word */
+ ld.hu r7,SRC,2 /* load second half-word */
+ ld.hu r8,SRC,4 /* load third half-word */
+ ld.hu r9,SRC,6 /* load fourth half-word */
+ ld.hu r10,SRC,8 /* load fifth half-word */
+ ld.hu r11,SRC,10 /* load sixth half-word */
+ ld.hu r12,SRC,12 /* load seventh half-word */
+ ld.hu r13,SRC,14 /* load eighth half-word */
+ st.h r6,DST,0 /* store first half-word */
+ st.h r7,DST,2 /* store second half-word */
+ st.h r8,DST,4 /* store third half-word */
+ st.h r9,DST,6 /* store fourth half-word */
+ st.h r10,DST,8 /* store fifth half-word */
+ st.h r11,DST,10 /* store sixth half-word */
+ st.h r12,DST,12 /* store seventh half-word */
+ st.h r13,DST,14 /* store eighth half-word */
+ br.n _ASM_LABEL(r_half_copy) /* branch to copy another block */
+ subu LEN,LEN,16 /* decrement remaining length */
+
+ASLOCAL(r_byte_copy)
+ bcnd eq0,LEN,_ASM_LABEL(bcopy_out) /* branch if nothing left to copy */
+ subu SRC,SRC,1 /* decrement source pointer */
+ subu DST,DST,1 /* decrement destination pointer */
+ ld.bu r6,SRC,0 /* load byte from source */
+ st.b r6,DST,0 /* store byte in destination */
+ br.n _ASM_LABEL(r_byte_copy) /* branch for next byte */
+ subu LEN,LEN,1 /* decrement remaining length */
+#endif /* MEMMOVE || OVBCOPY */
+
+ASLOCAL(bcopy_out)
+#if defined(MEMCPY) || defined(MEMMOVE)
+ jmp.n r1 /* all done, return to caller */
+ or r2, SAVE, r0
+#else
+ jmp r1 /* all done, return to caller */
+#endif
+
+ data
+ align 4
+ASLOCAL(f_strat)
+ word _ASM_LABEL(f_word_copy)
+ word _ASM_LABEL(f_byte_copy)
+ word _ASM_LABEL(f_half_copy)
+ word _ASM_LABEL(f_byte_copy)
+ word _ASM_LABEL(f_byte_copy)
+ word _ASM_LABEL(f_3byte_word_copy)
+ word _ASM_LABEL(f_byte_copy)
+ word _ASM_LABEL(f_1byte_half_copy)
+ word _ASM_LABEL(f_half_copy)
+ word _ASM_LABEL(f_byte_copy)
+ word _ASM_LABEL(f_1half_word_copy)
+ word _ASM_LABEL(f_byte_copy)
+ word _ASM_LABEL(f_byte_copy)
+ word _ASM_LABEL(f_1byte_half_copy)
+ word _ASM_LABEL(f_byte_copy)
+ word _ASM_LABEL(f_1byte_word_copy)
+
+#if defined(MEMMOVE) || defined(OVBCOPY)
+ASLOCAL(r_strat)
+ word _ASM_LABEL(r_word_copy)
+ word _ASM_LABEL(r_byte_copy)
+ word _ASM_LABEL(r_half_copy)
+ word _ASM_LABEL(r_byte_copy)
+ word _ASM_LABEL(r_byte_copy)
+ word _ASM_LABEL(r_1byte_word_copy)
+ word _ASM_LABEL(r_byte_copy)
+ word _ASM_LABEL(r_1byte_half_copy)
+ word _ASM_LABEL(r_half_copy)
+ word _ASM_LABEL(r_byte_copy)
+ word _ASM_LABEL(r_1half_word_copy)
+ word _ASM_LABEL(r_byte_copy)
+ word _ASM_LABEL(r_byte_copy)
+ word _ASM_LABEL(r_1byte_half_copy)
+ word _ASM_LABEL(r_byte_copy)
+ word _ASM_LABEL(r_3byte_word_copy)
+#endif
diff --git a/sys/lib/libkern/arch/m88k/memcpy.S b/sys/lib/libkern/arch/m88k/memcpy.S
new file mode 100644
index 00000000000..47666e5eab1
--- /dev/null
+++ b/sys/lib/libkern/arch/m88k/memcpy.S
@@ -0,0 +1,4 @@
+/* $OpenBSD: memcpy.S,v 1.1 2006/11/17 22:32:38 miod Exp $ */
+
+#define MEMCPY
+#include "copy_subr.S"
diff --git a/sys/lib/libkern/arch/m88k/memmove.S b/sys/lib/libkern/arch/m88k/memmove.S
new file mode 100644
index 00000000000..0fefddee50d
--- /dev/null
+++ b/sys/lib/libkern/arch/m88k/memmove.S
@@ -0,0 +1,4 @@
+/* $OpenBSD: memmove.S,v 1.1 2006/11/17 22:32:38 miod Exp $ */
+
+#define MEMMOVE
+#include "copy_subr.S"
diff --git a/sys/lib/libkern/arch/m88k/ovbcopy.S b/sys/lib/libkern/arch/m88k/ovbcopy.S
new file mode 100644
index 00000000000..7448aa1ab30
--- /dev/null
+++ b/sys/lib/libkern/arch/m88k/ovbcopy.S
@@ -0,0 +1,4 @@
+/* $OpenBSD: ovbcopy.S,v 1.1 2006/11/17 22:32:38 miod Exp $ */
+
+#define OVBCOPY
+#include "copy_subr.S"