diff options
-rw-r--r-- | sys/lib/libkern/arch/sh/Makefile.inc | 50 | ||||
-rw-r--r-- | sys/lib/libkern/arch/sh/ffs.S | 103 | ||||
-rw-r--r-- | sys/lib/libkern/arch/sh/memcpy.S | 272 | ||||
-rw-r--r-- | sys/lib/libkern/arch/sh/memset.S | 298 | ||||
-rw-r--r-- | sys/lib/libkern/arch/sh/movstr_i4.S | 74 | ||||
-rw-r--r-- | sys/lib/libkern/arch/sh/sdivsi3.S | 93 | ||||
-rw-r--r-- | sys/lib/libkern/arch/sh/udivsi3.S | 107 |
7 files changed, 997 insertions, 0 deletions
diff --git a/sys/lib/libkern/arch/sh/Makefile.inc b/sys/lib/libkern/arch/sh/Makefile.inc new file mode 100644 index 00000000000..91ea18eece9 --- /dev/null +++ b/sys/lib/libkern/arch/sh/Makefile.inc @@ -0,0 +1,50 @@ +# $OpenBSD: Makefile.inc,v 1.1 2006/10/06 21:19:15 mickey Exp $ + +SRCS+= __main.c \ + bcmp.c imax.c imin.c lmax.c lmin.c max.c min.c random.c scanc.c \ + skpc.c strcmp.c strlen.c strncmp.c strncasecmp.c \ + strlcat.c strlcpy.c \ + strncpy.c ulmax.c ulmin.c + +SRCS+= ffs.S movstr_i4.S sdivsi3.S udivsi3.S +SRCS+= memchr.c memcmp.c memcpy.S memset.S + +OBJS+= bzero.o bcopy.o memmove.o +CLEANFILES+= bzero.o bcopy.o memmove.o + +bzero.o: ${M}/memset.S + @echo "${COMPILE.c} -DBZERO ${M}/memset.S -o ${.TARGET}" + @${COMPILE.c} -DBZERO ${M}/memset.S -o ${.TARGET}.o + @${LD} -x -r ${.TARGET}.o -o ${.TARGET} + @rm -f ${.TARGET}.o + +bzero.po: ${M}/memset.S + @echo "${COMPILE.c} -DBZERO ${M}/memset.S -o ${.TARGET}" + @${COMPILE.c} -DBZERO ${M}/memset.S -o ${.TARGET}.o + @${LD} -x -r ${.TARGET}.o -o ${.TARGET} + @rm -f ${.TARGET}.o + +bcopy.o: ${M}/memcpy.S + @echo "${COMPILE.c} -DBCOPY ${M}/memcpy.S -o ${.TARGET}" + @${COMPILE.c} -DBCOPY ${M}/memcpy.S -o ${.TARGET}.o + @${LD} -x -r ${.TARGET}.o -o ${.TARGET} + @rm -f ${.TARGET}.o + +bcopy.po: ${M}/memcpy.S + @echo "${COMPILE.c} -DBCOPY ${M}/memcpy.S -o ${.TARGET}" + @${COMPILE.c} -DBCOPY ${M}/memcpy.S -o ${.TARGET}.o + @${LD} -x -r ${.TARGET}.o -o ${.TARGET} + @rm -f ${.TARGET}.o + +memmove.o: ${M}/memcpy.S + @echo "${COMPILE.c} -DMEMMOVE ${M}/memcpy.S -o ${.TARGET}" + @${COMPILE.c} -DMEMMOVE ${M}/memcpy.S -o ${.TARGET}.o + @${LD} -x -r ${.TARGET}.o -o ${.TARGET} + @rm -f ${.TARGET}.o + +memmove.po: ${M}/memcpy.S + @echo "${COMPILE.c} -DMEMMOVE ${M}/memcpy.S -o ${.TARGET}" + @${COMPILE.c} -DMEMMOVE ${M}/memcpy.S -o ${.TARGET}.o + @${LD} -x -r ${.TARGET}.o -o ${.TARGET} + @rm -f ${.TARGET}.o + diff --git a/sys/lib/libkern/arch/sh/ffs.S b/sys/lib/libkern/arch/sh/ffs.S new file mode 100644 index 00000000000..733694b6f80 --- /dev/null +++ b/sys/lib/libkern/arch/sh/ffs.S @@ -0,0 +1,103 @@ +/* $NetBSD: ffs.S,v 1.1 2005/12/20 19:28:50 christos Exp $ */ + +/*- + * Copyright (c) 2002 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by ITOH Yasufumi. + * + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``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 FOUNDATION OR CONTRIBUTORS + * 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(LIBC_SCCS) && !defined(lint) + RCSID("$NetBSD: ffs.S,v 1.1 2005/12/20 19:28:50 christos Exp $") +#endif + +/* + * ffs - find first bit set + * + * This code makes use of ``test 8bit'' and ``shift 8bit'' instructions. + * The remaining 8bit is tested in every 2bit. + */ + +ENTRY(ffs) + mov r4,r0 ! using r0 specific instructions + tst #0xff,r0 + bf/s L8bit + mov #0+1,r1 ! ret = 1..8 + + tst r0,r0 ! ffs(0) is 0 + bt Lzero ! testing here to accelerate ret=1..8 cases + + shlr8 r0 + tst #0xff,r0 + bf/s L8bit + mov #8+1,r1 ! ret = 9..16 + + shlr8 r0 + tst #0xff,r0 + bf/s L8bit + mov #16+1,r1 ! ret = 17..24 + + shlr8 r0 + mov #24+1,r1 ! ret = 25..32 + +L8bit: + tst #0x0f,r0 + bt 4f + + tst #0x03,r0 + bt 2f + tst #0x01,r0 ! not bit 0 -> T + mov #0,r0 + rts + addc r1,r0 ! 0 + r1 + T -> r0 + +2: tst #0x04,r0 + mov #2,r0 + rts + addc r1,r0 + +4: tst #0x30,r0 + bt 6f + tst #0x10,r0 + mov #4,r0 + rts + addc r1,r0 + +6: tst #0x40,r0 + mov #6,r0 + rts + addc r1,r0 + +Lzero: rts + nop diff --git a/sys/lib/libkern/arch/sh/memcpy.S b/sys/lib/libkern/arch/sh/memcpy.S new file mode 100644 index 00000000000..b80fe524ac4 --- /dev/null +++ b/sys/lib/libkern/arch/sh/memcpy.S @@ -0,0 +1,272 @@ +/* $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(LIBC_SCCS) && !defined(lint) + RCSID("$NetBSD: memcpy.S,v 1.2 2006/04/22 23:53:47 uwe Exp $") +#endif + +#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 diff --git a/sys/lib/libkern/arch/sh/memset.S b/sys/lib/libkern/arch/sh/memset.S new file mode 100644 index 00000000000..6611daba3ac --- /dev/null +++ b/sys/lib/libkern/arch/sh/memset.S @@ -0,0 +1,298 @@ +/* $NetBSD: memset.S,v 1.1 2005/12/20 19:28:50 christos Exp $ */ + +/*- + * Copyright (c) 2002 SHIMIZU Ryo. 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(LIBC_SCCS) && !defined(lint) + RCSID("$NetBSD: memset.S,v 1.1 2005/12/20 19:28:50 christos Exp $") +#endif + +#define REG_PTR r0 +#define REG_TMP1 r1 + +#ifdef BZERO +# define REG_C r2 +# define REG_DST r4 +# define REG_LEN r5 +#else +# define REG_DST0 r3 +# define REG_DST r4 +# define REG_C r5 +# define REG_LEN r6 +#endif + +#ifdef BZERO +ENTRY(bzero) +#else +ENTRY(memset) + mov REG_DST,REG_DST0 /* for return value */ +#endif + /* small amount to fill ? */ + mov #28,REG_TMP1 + cmp/hs REG_TMP1,REG_LEN /* if (len >= 28) goto large; */ + bt/s large + mov #12,REG_TMP1 /* if (len >= 12) goto small; */ + cmp/hs REG_TMP1,REG_LEN + bt/s small +#ifdef BZERO + mov #0,REG_C +#endif + /* very little fill (0 ~ 11 bytes) */ + tst REG_LEN,REG_LEN + add REG_DST,REG_LEN + bt/s done + add #1,REG_DST + + /* unroll 4 loops */ + cmp/eq REG_DST,REG_LEN +1: mov.b REG_C,@-REG_LEN + bt/s done + cmp/eq REG_DST,REG_LEN + mov.b REG_C,@-REG_LEN + bt/s done + cmp/eq REG_DST,REG_LEN + mov.b REG_C,@-REG_LEN + bt/s done + cmp/eq REG_DST,REG_LEN + mov.b REG_C,@-REG_LEN + bf/s 1b + cmp/eq REG_DST,REG_LEN +done: +#ifdef BZERO + rts + nop +#else + rts + mov REG_DST0,r0 +#endif + + +small: + mov REG_DST,r0 + tst #1,r0 + bt/s small_aligned + mov REG_DST,REG_TMP1 + shll REG_LEN + mova 1f,r0 /* 1f must be 4bytes aligned! */ + add #16,REG_TMP1 /* REG_TMP1 = dst+16; */ + sub REG_LEN,r0 + jmp @r0 + mov REG_C,r0 + + .align 2 + mov.b r0,@(15,REG_TMP1) + mov.b r0,@(14,REG_TMP1) + mov.b r0,@(13,REG_TMP1) + mov.b r0,@(12,REG_TMP1) + mov.b r0,@(11,REG_TMP1) + mov.b r0,@(10,REG_TMP1) + mov.b r0,@(9,REG_TMP1) + mov.b r0,@(8,REG_TMP1) + mov.b r0,@(7,REG_TMP1) + mov.b r0,@(6,REG_TMP1) + mov.b r0,@(5,REG_TMP1) + mov.b r0,@(4,REG_TMP1) + mov.b r0,@(3,REG_TMP1) + mov.b r0,@(2,REG_TMP1) + mov.b r0,@(1,REG_TMP1) + mov.b r0,@REG_TMP1 + mov.b r0,@(15,REG_DST) + mov.b r0,@(14,REG_DST) + mov.b r0,@(13,REG_DST) + mov.b r0,@(12,REG_DST) + mov.b r0,@(11,REG_DST) + mov.b r0,@(10,REG_DST) + mov.b r0,@(9,REG_DST) + mov.b r0,@(8,REG_DST) + mov.b r0,@(7,REG_DST) + mov.b r0,@(6,REG_DST) + mov.b r0,@(5,REG_DST) + mov.b r0,@(4,REG_DST) + mov.b r0,@(3,REG_DST) + mov.b r0,@(2,REG_DST) + mov.b r0,@(1,REG_DST) +#ifdef BZERO + rts +1: mov.b r0,@REG_DST +#else + mov.b r0,@REG_DST +1: rts + mov REG_DST0,r0 +#endif + + +/* 2 bytes aligned small fill */ +small_aligned: +#ifndef BZERO + extu.b REG_C,REG_TMP1 /* REG_C = ??????xx, REG_TMP1 = ????00xx */ + shll8 REG_C /* REG_C = ????xx00, REG_TMP1 = ????00xx */ + or REG_TMP1,REG_C /* REG_C = ????xxxx */ +#endif + + mov REG_LEN,r0 + tst #1,r0 /* len is aligned? */ + bt/s 1f + add #-1,r0 + mov.b REG_C,@(r0,REG_DST) /* fill last a byte */ + mov r0,REG_LEN +1: + + mova 1f,r0 /* 1f must be 4bytes aligned! */ + sub REG_LEN,r0 + jmp @r0 + mov REG_C,r0 + + .align 2 + mov.w r0,@(30,REG_DST) + mov.w r0,@(28,REG_DST) + mov.w r0,@(26,REG_DST) + mov.w r0,@(24,REG_DST) + mov.w r0,@(22,REG_DST) + mov.w r0,@(20,REG_DST) + mov.w r0,@(18,REG_DST) + mov.w r0,@(16,REG_DST) + mov.w r0,@(14,REG_DST) + mov.w r0,@(12,REG_DST) + mov.w r0,@(10,REG_DST) + mov.w r0,@(8,REG_DST) + mov.w r0,@(6,REG_DST) + mov.w r0,@(4,REG_DST) + mov.w r0,@(2,REG_DST) +#ifdef BZERO + rts +1: mov.w r0,@REG_DST +#else + mov.w r0,@REG_DST +1: rts + mov REG_DST0,r0 +#endif + + + + .align 2 +large: +#ifdef BZERO + mov #0,REG_C +#else + extu.b REG_C,REG_TMP1 /* REG_C = ??????xx, REG_TMP1 = ????00xx */ + shll8 REG_C /* REG_C = ????xx00, REG_TMP1 = ????00xx */ + or REG_C,REG_TMP1 /* REG_C = ????xx00, REG_TMP1 = ????xxxx */ + swap.w REG_TMP1,REG_C /* REG_C = xxxx????, REG_TMP1 = ????xxxx */ + xtrct REG_TMP1,REG_C /* REG_C = xxxxxxxx */ +#endif + + mov #3,REG_TMP1 + tst REG_TMP1,REG_DST + mov REG_DST,REG_PTR + bf/s unaligned_dst + add REG_LEN,REG_PTR /* REG_PTR = dst + len; */ + tst REG_TMP1,REG_LEN + bf/s unaligned_len + +aligned: + /* fill 32*n bytes */ + mov #32,REG_TMP1 + cmp/hi REG_LEN,REG_TMP1 + bt 9f + .align 2 +1: sub REG_TMP1,REG_PTR + mov.l REG_C,@REG_PTR + sub REG_TMP1,REG_LEN + mov.l REG_C,@(4,REG_PTR) + cmp/hi REG_LEN,REG_TMP1 + mov.l REG_C,@(8,REG_PTR) + mov.l REG_C,@(12,REG_PTR) + mov.l REG_C,@(16,REG_PTR) + mov.l REG_C,@(20,REG_PTR) + mov.l REG_C,@(24,REG_PTR) + bf/s 1b + mov.l REG_C,@(28,REG_PTR) +9: + + /* fill left 4*n bytes */ + cmp/eq REG_DST,REG_PTR + bt 9f + add #4,REG_DST + cmp/eq REG_DST,REG_PTR +1: mov.l REG_C,@-REG_PTR + bt/s 9f + cmp/eq REG_DST,REG_PTR + mov.l REG_C,@-REG_PTR + bt/s 9f + cmp/eq REG_DST,REG_PTR + mov.l REG_C,@-REG_PTR + bt/s 9f + cmp/eq REG_DST,REG_PTR + mov.l REG_C,@-REG_PTR + bf/s 1b + cmp/eq REG_DST,REG_PTR +9: +#ifdef BZERO + rts + nop +#else + rts + mov REG_DST0,r0 +#endif + + +unaligned_dst: + mov #1,REG_TMP1 + tst REG_TMP1,REG_DST /* if (dst & 1) { */ + add #1,REG_TMP1 + bt/s 2f + tst REG_TMP1,REG_DST + mov.b REG_C,@REG_DST /* *dst++ = c; */ + add #1,REG_DST + tst REG_TMP1,REG_DST +2: /* } */ + /* if (dst & 2) { */ + bt 4f + mov.w REG_C,@REG_DST /* *(u_int16_t*)dst++ = c; */ + add #2,REG_DST +4: /* } */ + + + tst #3,REG_PTR /* if (ptr & 3) { */ + bt/s 4f /* */ +unaligned_len: + tst #1,REG_PTR /* if (ptr & 1) { */ + bt/s 2f + tst #2,REG_PTR + mov.b REG_C,@-REG_PTR /* --ptr = c; */ +2: /* } */ + /* if (ptr & 2) { */ + bt 4f + mov.w REG_C,@-REG_PTR /* *--(u_int16_t*)ptr = c; */ +4: /* } */ + /* } */ + + mov REG_PTR,REG_LEN + bra aligned + sub REG_DST,REG_LEN + diff --git a/sys/lib/libkern/arch/sh/movstr_i4.S b/sys/lib/libkern/arch/sh/movstr_i4.S new file mode 100644 index 00000000000..835801d933e --- /dev/null +++ b/sys/lib/libkern/arch/sh/movstr_i4.S @@ -0,0 +1,74 @@ +/* $NetBSD: movstr_i4.S,v 1.5 2006/05/22 21:34:08 uwe Exp $ */ + +/*- + * Copyright (C) 2002 SHIMIZU Ryo. 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> + + +NENTRY(__movstr_i4_odd) + add #-8,r4 + nop +odd_loop: + mov.l @r5+,r0 + add #8,r4 + mov.l @r5+,r1 + dt r6 + mov.l r0,@(0,r4) + bf/s odd_loop + mov.l r1,@(4,r4) + + mov.l @r5+,r0 + mov.l @r5+,r1 + mov.l @r5+,r2 + mov.l r0,@(8,r4) + mov.l r1,@(12,r4) + rts + mov.l r2,@(16,r4) + + +NENTRY(__movstr_i4_even) + add #-8,r4 + nop +even_loop: + mov.l @r5+,r0 + add #8,r4 + mov.l @r5+,r1 + dt r6 + mov.l r0,@(0,r4) + bf/s even_loop + mov.l r1,@(4,r4) + + mov.l @r5+,r0 + mov.l @r5+,r1 + mov.l r0,@(8,r4) + rts + mov.l r1,@(12,r4) + + +/* gcc4 uses movmem, older versions use movstr */ +_C_LABEL(__movmem_i4_odd) = _C_LABEL(__movstr_i4_odd) +_C_LABEL(__movmem_i4_even) = _C_LABEL(__movstr_i4_even) diff --git a/sys/lib/libkern/arch/sh/sdivsi3.S b/sys/lib/libkern/arch/sh/sdivsi3.S new file mode 100644 index 00000000000..23153632033 --- /dev/null +++ b/sys/lib/libkern/arch/sh/sdivsi3.S @@ -0,0 +1,93 @@ +/* $NetBSD: sdivsi3.S,v 1.8 2006/05/22 20:56:44 uwe Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + * + * from: @(#)udivsi3.s 5.1 (Berkeley) 5/15/90 + */ + +#include <machine/asm.h> + +/* r0 <= r4 / r5 */ +NENTRY(__sdivsi3) + mov r4, r0 + mov r5, r1 + + tst r1, r1 + bt div_by_zero + + mov #0, r2 + div0s r2, r0 + subc r3, r3 + subc r2, r0 + div0s r1, r3 +#define DIVSTEP rotcl r0; div1 r1, r3 + /* repeat 32 times */ + DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; + DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; + DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; + DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; +#undef DIVSTEP + rotcl r0 + + rts + addc r2, r0 + +div_by_zero: +#ifdef _KERNEL + rts + mov #0, r0 +#else + mov.l r14, @-r15 + sts.l pr, @-r15 + mov r15, r14 + + mov.l L_raise, r1 +#ifdef PIC +1: bsrf r1 +#else + jsr @r1 +#endif + mov #8, r4 /* delay slot. 8 <- SIGFPE. */ + mov #0, r0 + + lds.l @r15+, pr + rts + mov.l @r15+, r14 + + .align 2 +L_raise: +#ifdef PIC + .long _C_LABEL(raise)-(1b+4) +#else + .long _C_LABEL(raise) +#endif +#endif diff --git a/sys/lib/libkern/arch/sh/udivsi3.S b/sys/lib/libkern/arch/sh/udivsi3.S new file mode 100644 index 00000000000..0483d74337f --- /dev/null +++ b/sys/lib/libkern/arch/sh/udivsi3.S @@ -0,0 +1,107 @@ +/* $NetBSD: udivsi3.S,v 1.7 2006/05/22 20:56:44 uwe Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * William Jolitz. + * + * 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. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + * + * from: @(#)udivsi3.s 5.1 (Berkeley) 5/15/90 + */ + +#include <machine/asm.h> + +/* + * IMPOTANT: This function is special. + * + * This function is an auxiliary function that is referenced by the + * code generated by gcc for integer division. But gcc does NOT treat + * a call to this function as an ordinary function call w.r.t. the set + * of register this call clobbers. See the definition of "udivsi3_i1" + * in gcc/config/sh/sh.md. + * + * Any call to this function MUST NOT clobber any registers besides r4 + * and r0, where the result is returned. At the time of the call the + * r4 contains the first argument, so we are only left with r0, and we + * cannot do anything meaningful using only one register. The + * consequences are: + * + * . this function cannot have _PROF_PROLOGUE + * . this function cannot be called via PLT + */ + + +/* r0 <= r4 / r5 */ +NENTRY(__udivsi3) + tst r5, r5 + bt div_by_zero + + mov #0, r0 + div0u +#define DIVSTEP rotcl r4; div1 r5, r0 + /* repeat 32 times */ + DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; + DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; + DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; + DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; DIVSTEP; +#undef DIVSTEP + rotcl r4 + + rts + mov r4, r0 + +div_by_zero: +#ifdef _KERNEL + rts + mov #0, r0 +#else + mov.l r14, @-r15 + sts.l pr, @-r15 + mov r15, r14 + + mov.l L_raise, r1 +#ifdef PIC +1: bsrf r1 +#else + jsr @r1 +#endif + mov #8, r4 /* delay slot. 8 <- SIGFPE. */ + mov #0, r0 + + lds.l @r15+, pr + rts + mov.l @r15+, r14 + + .align 2 +L_raise: +#ifdef PIC + .long _C_LABEL(raise)-(1b+4) +#else + .long _C_LABEL(raise) +#endif +#endif |