summaryrefslogtreecommitdiff
path: root/sys/lib/libkern
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2013-06-13 14:45:01 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2013-06-13 14:45:01 +0000
commit51ffac1371515194f46b23cc56e869a529549f1c (patch)
tree412b50c3744510ed5dc939990aa6563865e4c859 /sys/lib/libkern
parentada43d7ee5afa7d9bd682921dbeb51dc0ba346b1 (diff)
rework the memcpy family to all use one function body and implement
desired semantics. ok deraadt
Diffstat (limited to 'sys/lib/libkern')
-rw-r--r--sys/lib/libkern/arch/sh/bcopy.S3
-rw-r--r--sys/lib/libkern/arch/sh/memcpy.S269
-rw-r--r--sys/lib/libkern/arch/sh/memmove.S248
3 files changed, 248 insertions, 272 deletions
diff --git a/sys/lib/libkern/arch/sh/bcopy.S b/sys/lib/libkern/arch/sh/bcopy.S
index 09b4a2a5c54..c9361568da4 100644
--- a/sys/lib/libkern/arch/sh/bcopy.S
+++ b/sys/lib/libkern/arch/sh/bcopy.S
@@ -1,2 +1 @@
-#define BCOPY
-#include "memcpy.S"
+/* This code is contained in memmove.S */
diff --git a/sys/lib/libkern/arch/sh/memcpy.S b/sys/lib/libkern/arch/sh/memcpy.S
index 78a960d8eb8..c9361568da4 100644
--- a/sys/lib/libkern/arch/sh/memcpy.S
+++ b/sys/lib/libkern/arch/sh/memcpy.S
@@ -1,268 +1 @@
-/* $NetBSD: memcpy.S,v 1.2 2006/04/22 23:53:47 uwe Exp $ */
-
-/*
- * Copyright (c) 2000 SHIMIZU Ryo <ryo@misakimix.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <machine/asm.h>
-
-#if !defined(MEMCOPY) && !defined(MEMMOVE) && !defined(BCOPY)
-#define MEMCOPY
-#endif
-
-#if defined(MEMCOPY) || defined(MEMMOVE)
-#define REG_DST0 r3
-#define REG_SRC r5
-#define REG_DST r4
-#else
-#define REG_SRC r4
-#define REG_DST r5
-#endif
-
-#define REG_LEN r6
-
-#if defined(MEMCOPY)
-ENTRY(memcpy)
-#elif defined(MEMMOVE)
-ENTRY(memmove)
-#elif defined(BCOPY)
-ENTRY(bcopy)
-ALTENTRY(ovbcopy)
-#endif
-#ifdef REG_DST0
- mov REG_DST,REG_DST0
-#endif
- cmp/eq REG_DST,REG_SRC /* if ( src == dst ) return; */
- bt/s bcopy_return
- cmp/hi REG_DST,REG_SRC
- bf/s bcopy_overlap
-
- mov REG_SRC,r0
- xor REG_DST,r0
- and #3,r0
- mov r0,r1
- tst r0,r0 /* (src ^ dst) & 3 */
- bf/s word_align
-
-longword_align:
- tst REG_LEN,REG_LEN /* if ( len==0 ) return; */
- bt/s bcopy_return
-
-
- mov REG_SRC,r0
- tst #1,r0 /* if ( src & 1 ) */
- bt 1f
- mov.b @REG_SRC+,r0 /* *dst++ = *src++; */
- add #-1,REG_LEN
- mov.b r0,@REG_DST
- add #1,REG_DST
-1:
-
-
- mov #1,r0
- cmp/hi r0,REG_LEN /* if ( (len > 1) && */
- bf/s 1f
- mov REG_SRC,r0
- tst #2,r0 /* (src & 2) { */
- bt 1f
- mov.w @REG_SRC+,r0 /* *((unsigned short*)dst)++ = *((unsigned short*)src)++; */
- add #-2,REG_LEN /* len -= 2; */
- mov.w r0,@REG_DST
- add #2,REG_DST /* } */
-1:
-
-
- mov #3,r1
- cmp/hi r1,REG_LEN /* while ( len > 3 ) { */
- bf/s no_align_delay
- tst REG_LEN,REG_LEN
-2:
- mov.l @REG_SRC+,r0 /* *((unsigned long*)dst)++ = *((unsigned long*)src)++; */
- add #-4,REG_LEN /* len -= 4; */
- mov.l r0,@REG_DST
- cmp/hi r1,REG_LEN
- bt/s 2b
- add #4,REG_DST /* } */
-
- bra no_align_delay
- tst REG_LEN,REG_LEN
-
-
-word_align:
- mov r1,r0
- tst #1,r0
- bf/s no_align_delay
- tst REG_LEN,REG_LEN /* if ( len == 0 ) return; */
- bt bcopy_return
-
-
- mov REG_SRC,r0 /* if ( src & 1 ) */
- tst #1,r0
- bt 1f
- mov.b @REG_SRC+,r0 /* *dst++ = *src++; */
- add #-1,REG_LEN
- mov.b r0,@REG_DST
- add #1,REG_DST
-1:
-
-
- mov #1,r1
- cmp/hi r1,REG_LEN /* while ( len > 1 ) { */
- bf/s no_align_delay
- tst REG_LEN,REG_LEN
-2:
- mov.w @REG_SRC+,r0 /* *((unsigned short*)dst)++ = *((unsigned short*)src)++; */
- add #-2,REG_LEN /* len -= 2; */
- mov.w r0,@REG_DST
- cmp/hi r1,REG_LEN
- bt/s 2b
- add #2,REG_DST /* } */
-
-
-no_align:
- tst REG_LEN,REG_LEN /* while ( len!= ) { */
-no_align_delay:
- bt bcopy_return
-1:
- mov.b @REG_SRC+,r0 /* *dst++ = *src++; */
- add #-1,REG_LEN /* len--; */
- mov.b r0,@REG_DST
- tst REG_LEN,REG_LEN
- bf/s 1b
- add #1,REG_DST /* } */
-bcopy_return:
- rts
-#ifdef REG_DST0
- mov REG_DST0,r0
-#else
- nop
-#endif
-
-
-bcopy_overlap:
- add REG_LEN,REG_SRC
- add REG_LEN,REG_DST
-
- mov REG_SRC,r0
- xor REG_DST,r0
- and #3,r0
- mov r0,r1
- tst r0,r0 /* (src ^ dst) & 3 */
- bf/s ov_word_align
-
-ov_longword_align:
- tst REG_LEN,REG_LEN /* if ( len==0 ) return; */
- bt/s bcopy_return
-
-
- mov REG_SRC,r0
- tst #1,r0 /* if ( src & 1 ) */
- bt 1f
- add #-1,REG_SRC /* *--dst = *--src; */
- mov.b @REG_SRC,r0
- mov.b r0,@-REG_DST
- add #-1,REG_LEN
-1:
-
-
- mov #1,r0
- cmp/hi r0,REG_LEN /* if ( (len > 1) && */
- bf/s 1f
- mov REG_SRC,r0
- tst #2,r0 /* (src & 2) { */
- bt 1f
- add #-2,REG_SRC /* *--((unsigned short*)dst) = *--((unsigned short*)src); */
- mov.w @REG_SRC,r0
- add #-2,REG_LEN /* len -= 2; */
- mov.w r0,@-REG_DST /* } */
-1:
-
-
- mov #3,r1
- cmp/hi r1,REG_LEN /* while ( len > 3 ) { */
- bf/s ov_no_align_delay
- tst REG_LEN,REG_LEN
-2:
- add #-4,REG_SRC
- mov.l @REG_SRC,r0 /* *((unsigned long*)dst)++ = *((unsigned long*)src)++; */
- add #-4,REG_LEN /* len -= 4; */
- cmp/hi r1,REG_LEN
- bt/s 2b
- mov.l r0,@-REG_DST /* } */
-
- bra ov_no_align_delay
- tst REG_LEN,REG_LEN
-
-
-ov_word_align:
- mov r1,r0
- tst #1,r0
- bf/s ov_no_align_delay
- tst REG_LEN,REG_LEN /* if ( len == 0 ) return; */
- bt bcopy_return
-
-
- mov REG_SRC,r0 /* if ( src & 1 ) */
- tst #1,r0
- bt 1f
- add #-1,REG_SRC
- mov.b @REG_SRC,r0 /* *--dst = *--src; */
- add #-1,REG_LEN
- mov.b r0,@-REG_DST
-1:
-
-
- mov #1,r1
- cmp/hi r1,REG_LEN /* while ( len > 1 ) { */
- bf/s ov_no_align_delay
- tst REG_LEN,REG_LEN
-2:
- add #-2,REG_SRC
- mov.w @REG_SRC,r0 /* *--((unsigned short*)dst) = *--((unsigned short*)src); */
- add #-2,REG_LEN /* len -= 2; */
- cmp/hi r1,REG_LEN
- bt/s 2b
- mov.w r0,@-REG_DST /* } */
-
-
-ov_no_align:
- tst REG_LEN,REG_LEN /* while ( len!= ) { */
-ov_no_align_delay:
- bt 9f
-1:
- add #-1,REG_SRC
- mov.b @REG_SRC,r0 /* *--dst = *--src; */
- add #-1,REG_LEN /* len--; */
- tst REG_LEN,REG_LEN
- bf/s 1b
- mov.b r0,@-REG_DST /* } */
-9:
- rts
-#ifdef REG_DST0
- mov REG_DST0,r0
-#else
- nop
-#endif
+/* This code is contained in memmove.S */
diff --git a/sys/lib/libkern/arch/sh/memmove.S b/sys/lib/libkern/arch/sh/memmove.S
index beda60b986a..eb82a8aa98e 100644
--- a/sys/lib/libkern/arch/sh/memmove.S
+++ b/sys/lib/libkern/arch/sh/memmove.S
@@ -1,2 +1,246 @@
-#define MEMMOVE
-#include "memcpy.S"
+/* $NetBSD: memcpy.S,v 1.2 2006/04/22 23:53:47 uwe Exp $ */
+
+/*
+ * Copyright (c) 2000 SHIMIZU Ryo <ryo@misakimix.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+
+#define REG_DST0 r3
+#define REG_SRC r5
+#define REG_DST r4
+#define REG_LEN r6
+
+ENTRY(bcopy)
+ /* swap registers, use DST0 as a temporary */
+ mov REG_DST,REG_DST0
+ mov REG_SRC,REG_DST
+ mov REG_DST0,REG_SRC
+
+ENTRY(memmove)
+ mov REG_DST,REG_DST0
+ cmp/hi REG_DST,REG_SRC
+ bf/s bcopy_overlap
+
+ENTRY(memcpy)
+ cmp/eq REG_DST,REG_SRC /* if ( src == dst ) return; */
+ bt/s bcopy_return
+ mov REG_SRC,r0
+ xor REG_DST,r0
+ and #3,r0
+ mov r0,r1
+ tst r0,r0 /* (src ^ dst) & 3 */
+ bf/s word_align
+
+longword_align:
+ tst REG_LEN,REG_LEN /* if ( len==0 ) return; */
+ bt/s bcopy_return
+
+
+ mov REG_SRC,r0
+ tst #1,r0 /* if ( src & 1 ) */
+ bt 1f
+ mov.b @REG_SRC+,r0 /* *dst++ = *src++; */
+ add #-1,REG_LEN
+ mov.b r0,@REG_DST
+ add #1,REG_DST
+1:
+
+ mov #1,r0
+ cmp/hi r0,REG_LEN /* if ( (len > 1) && */
+ bf/s 1f
+ mov REG_SRC,r0
+ tst #2,r0 /* (src & 2) { */
+ bt 1f
+ mov.w @REG_SRC+,r0 /* *((unsigned short*)dst)++ = *((unsigned short*)src)++; */
+ add #-2,REG_LEN /* len -= 2; */
+ mov.w r0,@REG_DST
+ add #2,REG_DST /* } */
+1:
+
+
+ mov #3,r1
+ cmp/hi r1,REG_LEN /* while ( len > 3 ) { */
+ bf/s no_align_delay
+ tst REG_LEN,REG_LEN
+2:
+ mov.l @REG_SRC+,r0 /* *((unsigned long*)dst)++ = *((unsigned long*)src)++; */
+ add #-4,REG_LEN /* len -= 4; */
+ mov.l r0,@REG_DST
+ cmp/hi r1,REG_LEN
+ bt/s 2b
+ add #4,REG_DST /* } */
+
+ bra no_align_delay
+ tst REG_LEN,REG_LEN
+
+
+word_align:
+ mov r1,r0
+ tst #1,r0
+ bf/s no_align_delay
+ tst REG_LEN,REG_LEN /* if ( len == 0 ) return; */
+ bt bcopy_return
+
+
+ mov REG_SRC,r0 /* if ( src & 1 ) */
+ tst #1,r0
+ bt 1f
+ mov.b @REG_SRC+,r0 /* *dst++ = *src++; */
+ add #-1,REG_LEN
+ mov.b r0,@REG_DST
+ add #1,REG_DST
+1:
+
+
+ mov #1,r1
+ cmp/hi r1,REG_LEN /* while ( len > 1 ) { */
+ bf/s no_align_delay
+ tst REG_LEN,REG_LEN
+2:
+ mov.w @REG_SRC+,r0 /* *((unsigned short*)dst)++ = *((unsigned short*)src)++; */
+ add #-2,REG_LEN /* len -= 2; */
+ mov.w r0,@REG_DST
+ cmp/hi r1,REG_LEN
+ bt/s 2b
+ add #2,REG_DST /* } */
+
+
+no_align:
+ tst REG_LEN,REG_LEN /* while ( len!= ) { */
+no_align_delay:
+ bt bcopy_return
+1:
+ mov.b @REG_SRC+,r0 /* *dst++ = *src++; */
+ add #-1,REG_LEN /* len--; */
+ mov.b r0,@REG_DST
+ tst REG_LEN,REG_LEN
+ bf/s 1b
+ add #1,REG_DST /* } */
+bcopy_return:
+ rts
+ mov REG_DST0,r0
+
+bcopy_overlap:
+ add REG_LEN,REG_SRC
+ add REG_LEN,REG_DST
+
+ mov REG_SRC,r0
+ xor REG_DST,r0
+ and #3,r0
+ mov r0,r1
+ tst r0,r0 /* (src ^ dst) & 3 */
+ bf/s ov_word_align
+
+ov_longword_align:
+ tst REG_LEN,REG_LEN /* if ( len==0 ) return; */
+ bt/s bcopy_return
+
+
+ mov REG_SRC,r0
+ tst #1,r0 /* if ( src & 1 ) */
+ bt 1f
+ add #-1,REG_SRC /* *--dst = *--src; */
+ mov.b @REG_SRC,r0
+ mov.b r0,@-REG_DST
+ add #-1,REG_LEN
+1:
+
+
+ mov #1,r0
+ cmp/hi r0,REG_LEN /* if ( (len > 1) && */
+ bf/s 1f
+ mov REG_SRC,r0
+ tst #2,r0 /* (src & 2) { */
+ bt 1f
+ add #-2,REG_SRC /* *--((unsigned short*)dst) = *--((unsigned short*)src); */
+ mov.w @REG_SRC,r0
+ add #-2,REG_LEN /* len -= 2; */
+ mov.w r0,@-REG_DST /* } */
+1:
+
+
+ mov #3,r1
+ cmp/hi r1,REG_LEN /* while ( len > 3 ) { */
+ bf/s ov_no_align_delay
+ tst REG_LEN,REG_LEN
+2:
+ add #-4,REG_SRC
+ mov.l @REG_SRC,r0 /* *((unsigned long*)dst)++ = *((unsigned long*)src)++; */
+ add #-4,REG_LEN /* len -= 4; */
+ cmp/hi r1,REG_LEN
+ bt/s 2b
+ mov.l r0,@-REG_DST /* } */
+
+ bra ov_no_align_delay
+ tst REG_LEN,REG_LEN
+
+
+ov_word_align:
+ mov r1,r0
+ tst #1,r0
+ bf/s ov_no_align_delay
+ tst REG_LEN,REG_LEN /* if ( len == 0 ) return; */
+ bt bcopy_return
+
+
+ mov REG_SRC,r0 /* if ( src & 1 ) */
+ tst #1,r0
+ bt 1f
+ add #-1,REG_SRC
+ mov.b @REG_SRC,r0 /* *--dst = *--src; */
+ add #-1,REG_LEN
+ mov.b r0,@-REG_DST
+1:
+
+
+ mov #1,r1
+ cmp/hi r1,REG_LEN /* while ( len > 1 ) { */
+ bf/s ov_no_align_delay
+ tst REG_LEN,REG_LEN
+2:
+ add #-2,REG_SRC
+ mov.w @REG_SRC,r0 /* *--((unsigned short*)dst) = *--((unsigned short*)src); */
+ add #-2,REG_LEN /* len -= 2; */
+ cmp/hi r1,REG_LEN
+ bt/s 2b
+ mov.w r0,@-REG_DST /* } */
+
+
+ov_no_align:
+ tst REG_LEN,REG_LEN /* while ( len!= ) { */
+ov_no_align_delay:
+ bt 9f
+1:
+ add #-1,REG_SRC
+ mov.b @REG_SRC,r0 /* *--dst = *--src; */
+ add #-1,REG_LEN /* len--; */
+ tst REG_LEN,REG_LEN
+ bf/s 1b
+ mov.b r0,@-REG_DST /* } */
+9:
+ rts
+ mov REG_DST0,r0