diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 15:20:36 -0700 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/m68k/lib |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/m68k/lib')
-rw-r--r-- | arch/m68k/lib/Makefile | 8 | ||||
-rw-r--r-- | arch/m68k/lib/ashldi3.c | 62 | ||||
-rw-r--r-- | arch/m68k/lib/ashrdi3.c | 63 | ||||
-rw-r--r-- | arch/m68k/lib/checksum.c | 422 | ||||
-rw-r--r-- | arch/m68k/lib/lshrdi3.c | 62 | ||||
-rw-r--r-- | arch/m68k/lib/memcmp.c | 11 | ||||
-rw-r--r-- | arch/m68k/lib/memcpy.c | 75 | ||||
-rw-r--r-- | arch/m68k/lib/memset.c | 68 | ||||
-rw-r--r-- | arch/m68k/lib/muldi3.c | 63 | ||||
-rw-r--r-- | arch/m68k/lib/semaphore.S | 53 |
10 files changed, 887 insertions, 0 deletions
diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile new file mode 100644 index 000000000000..34b6dbc29c85 --- /dev/null +++ b/arch/m68k/lib/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for m68k-specific library files.. +# + +EXTRA_AFLAGS := -traditional + +lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ + checksum.o memcmp.o memcpy.o memset.o semaphore.o diff --git a/arch/m68k/lib/ashldi3.c b/arch/m68k/lib/ashldi3.c new file mode 100644 index 000000000000..7729f33878d1 --- /dev/null +++ b/arch/m68k/lib/ashldi3.c @@ -0,0 +1,62 @@ +/* ashrdi3.c extracted from gcc-2.95.2/libgcc2.c which is: */ +/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#define BITS_PER_UNIT 8 + +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int word_type __attribute__ ((mode (__word__))); + +struct DIstruct {SItype high, low;}; + +typedef union +{ + struct DIstruct s; + DItype ll; +} DIunion; + +DItype +__ashldi3 (DItype u, word_type b) +{ + DIunion w; + word_type bm; + DIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (SItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + w.s.low = 0; + w.s.high = (USItype)uu.s.low << -bm; + } + else + { + USItype carries = (USItype)uu.s.low >> bm; + w.s.low = (USItype)uu.s.low << b; + w.s.high = ((USItype)uu.s.high << b) | carries; + } + + return w.ll; +} diff --git a/arch/m68k/lib/ashrdi3.c b/arch/m68k/lib/ashrdi3.c new file mode 100644 index 000000000000..18ea5f7ed921 --- /dev/null +++ b/arch/m68k/lib/ashrdi3.c @@ -0,0 +1,63 @@ +/* ashrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */ +/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#define BITS_PER_UNIT 8 + +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int word_type __attribute__ ((mode (__word__))); + +struct DIstruct {SItype high, low;}; + +typedef union +{ + struct DIstruct s; + DItype ll; +} DIunion; + +DItype +__ashrdi3 (DItype u, word_type b) +{ + DIunion w; + word_type bm; + DIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (SItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + /* w.s.high = 1..1 or 0..0 */ + w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1); + w.s.low = uu.s.high >> -bm; + } + else + { + USItype carries = (USItype)uu.s.high << bm; + w.s.high = uu.s.high >> b; + w.s.low = ((USItype)uu.s.low >> b) | carries; + } + + return w.ll; +} diff --git a/arch/m68k/lib/checksum.c b/arch/m68k/lib/checksum.c new file mode 100644 index 000000000000..4a5c5445c610 --- /dev/null +++ b/arch/m68k/lib/checksum.c @@ -0,0 +1,422 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * IP/TCP/UDP checksumming routines + * + * Authors: Jorge Cwik, <jorge@laser.satlink.net> + * Arnt Gulbrandsen, <agulbra@nvg.unit.no> + * Tom May, <ftom@netcom.com> + * Andreas Schwab, <schwab@issan.informatik.uni-dortmund.de> + * Lots of code moved from tcp.c and ip.c; see those files + * for more names. + * + * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek: + * Fixed some nasty bugs, causing some horrible crashes. + * A: At some points, the sum (%0) was used as + * length-counter instead of the length counter + * (%1). Thanks to Roman Hodek for pointing this out. + * B: GCC seems to mess up if one uses too many + * data-registers to hold input values and one tries to + * specify d0 and d1 as scratch registers. Letting gcc + * choose these registers itself solves the problem. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * 1998/8/31 Andreas Schwab: + * Zero out rest of buffer on exception in + * csum_partial_copy_from_user. + */ + +#include <linux/module.h> +#include <net/checksum.h> + +/* + * computes a partial checksum, e.g. for TCP/UDP fragments + */ + +unsigned int +csum_partial (const unsigned char *buff, int len, unsigned int sum) +{ + unsigned long tmp1, tmp2; + /* + * Experiments with ethernet and slip connections show that buff + * is aligned on either a 2-byte or 4-byte boundary. + */ + __asm__("movel %2,%3\n\t" + "btst #1,%3\n\t" /* Check alignment */ + "jeq 2f\n\t" + "subql #2,%1\n\t" /* buff%4==2: treat first word */ + "jgt 1f\n\t" + "addql #2,%1\n\t" /* len was == 2, treat only rest */ + "jra 4f\n" + "1:\t" + "addw %2@+,%0\n\t" /* add first word to sum */ + "clrl %3\n\t" + "addxl %3,%0\n" /* add X bit */ + "2:\t" + /* unrolled loop for the main part: do 8 longs at once */ + "movel %1,%3\n\t" /* save len in tmp1 */ + "lsrl #5,%1\n\t" /* len/32 */ + "jeq 2f\n\t" /* not enough... */ + "subql #1,%1\n" + "1:\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "dbra %1,1b\n\t" + "clrl %4\n\t" + "addxl %4,%0\n\t" /* add X bit */ + "clrw %1\n\t" + "subql #1,%1\n\t" + "jcc 1b\n" + "2:\t" + "movel %3,%1\n\t" /* restore len from tmp1 */ + "andw #0x1c,%3\n\t" /* number of rest longs */ + "jeq 4f\n\t" + "lsrw #2,%3\n\t" + "subqw #1,%3\n" + "3:\t" + /* loop for rest longs */ + "movel %2@+,%4\n\t" + "addxl %4,%0\n\t" + "dbra %3,3b\n\t" + "clrl %4\n\t" + "addxl %4,%0\n" /* add X bit */ + "4:\t" + /* now check for rest bytes that do not fit into longs */ + "andw #3,%1\n\t" + "jeq 7f\n\t" + "clrl %4\n\t" /* clear tmp2 for rest bytes */ + "subqw #2,%1\n\t" + "jlt 5f\n\t" + "movew %2@+,%4\n\t" /* have rest >= 2: get word */ + "swap %4\n\t" /* into bits 16..31 */ + "tstw %1\n\t" /* another byte? */ + "jeq 6f\n" + "5:\t" + "moveb %2@,%4\n\t" /* have odd rest: get byte */ + "lslw #8,%4\n\t" /* into bits 8..15; 16..31 untouched */ + "6:\t" + "addl %4,%0\n\t" /* now add rest long to sum */ + "clrl %4\n\t" + "addxl %4,%0\n" /* add X bit */ + "7:\t" + : "=d" (sum), "=d" (len), "=a" (buff), + "=&d" (tmp1), "=&d" (tmp2) + : "0" (sum), "1" (len), "2" (buff) + ); + return(sum); +} + +EXPORT_SYMBOL(csum_partial); + + +/* + * copy from user space while checksumming, with exception handling. + */ + +unsigned int +csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, + int len, int sum, int *csum_err) +{ + /* + * GCC doesn't like more than 10 operands for the asm + * statements so we have to use tmp2 for the error + * code. + */ + unsigned long tmp1, tmp2; + + __asm__("movel %2,%4\n\t" + "btst #1,%4\n\t" /* Check alignment */ + "jeq 2f\n\t" + "subql #2,%1\n\t" /* buff%4==2: treat first word */ + "jgt 1f\n\t" + "addql #2,%1\n\t" /* len was == 2, treat only rest */ + "jra 4f\n" + "1:\n" + "10:\t" + "movesw %2@+,%4\n\t" /* add first word to sum */ + "addw %4,%0\n\t" + "movew %4,%3@+\n\t" + "clrl %4\n\t" + "addxl %4,%0\n" /* add X bit */ + "2:\t" + /* unrolled loop for the main part: do 8 longs at once */ + "movel %1,%4\n\t" /* save len in tmp1 */ + "lsrl #5,%1\n\t" /* len/32 */ + "jeq 2f\n\t" /* not enough... */ + "subql #1,%1\n" + "1:\n" + "11:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "12:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "13:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "14:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "15:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "16:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "17:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "18:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "dbra %1,1b\n\t" + "clrl %5\n\t" + "addxl %5,%0\n\t" /* add X bit */ + "clrw %1\n\t" + "subql #1,%1\n\t" + "jcc 1b\n" + "2:\t" + "movel %4,%1\n\t" /* restore len from tmp1 */ + "andw #0x1c,%4\n\t" /* number of rest longs */ + "jeq 4f\n\t" + "lsrw #2,%4\n\t" + "subqw #1,%4\n" + "3:\n" + /* loop for rest longs */ + "19:\t" + "movesl %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "dbra %4,3b\n\t" + "clrl %5\n\t" + "addxl %5,%0\n" /* add X bit */ + "4:\t" + /* now check for rest bytes that do not fit into longs */ + "andw #3,%1\n\t" + "jeq 7f\n\t" + "clrl %5\n\t" /* clear tmp2 for rest bytes */ + "subqw #2,%1\n\t" + "jlt 5f\n\t" + "20:\t" + "movesw %2@+,%5\n\t" /* have rest >= 2: get word */ + "movew %5,%3@+\n\t" + "swap %5\n\t" /* into bits 16..31 */ + "tstw %1\n\t" /* another byte? */ + "jeq 6f\n" + "5:\n" + "21:\t" + "movesb %2@,%5\n\t" /* have odd rest: get byte */ + "moveb %5,%3@+\n\t" + "lslw #8,%5\n\t" /* into bits 8..15; 16..31 untouched */ + "6:\t" + "addl %5,%0\n\t" /* now add rest long to sum */ + "clrl %5\n\t" + "addxl %5,%0\n\t" /* add X bit */ + "7:\t" + "clrl %5\n" /* no error - clear return value */ + "8:\n" + ".section .fixup,\"ax\"\n" + ".even\n" + /* If any exception occurs zero out the rest. + Similarities with the code above are intentional :-) */ + "90:\t" + "clrw %3@+\n\t" + "movel %1,%4\n\t" + "lsrl #5,%1\n\t" + "jeq 1f\n\t" + "subql #1,%1\n" + "91:\t" + "clrl %3@+\n" + "92:\t" + "clrl %3@+\n" + "93:\t" + "clrl %3@+\n" + "94:\t" + "clrl %3@+\n" + "95:\t" + "clrl %3@+\n" + "96:\t" + "clrl %3@+\n" + "97:\t" + "clrl %3@+\n" + "98:\t" + "clrl %3@+\n\t" + "dbra %1,91b\n\t" + "clrw %1\n\t" + "subql #1,%1\n\t" + "jcc 91b\n" + "1:\t" + "movel %4,%1\n\t" + "andw #0x1c,%4\n\t" + "jeq 1f\n\t" + "lsrw #2,%4\n\t" + "subqw #1,%4\n" + "99:\t" + "clrl %3@+\n\t" + "dbra %4,99b\n\t" + "1:\t" + "andw #3,%1\n\t" + "jeq 9f\n" + "100:\t" + "clrw %3@+\n\t" + "tstw %1\n\t" + "jeq 9f\n" + "101:\t" + "clrb %3@+\n" + "9:\t" +#define STR(X) STR1(X) +#define STR1(X) #X + "moveq #-" STR(EFAULT) ",%5\n\t" + "jra 8b\n" + ".previous\n" + ".section __ex_table,\"a\"\n" + ".long 10b,90b\n" + ".long 11b,91b\n" + ".long 12b,92b\n" + ".long 13b,93b\n" + ".long 14b,94b\n" + ".long 15b,95b\n" + ".long 16b,96b\n" + ".long 17b,97b\n" + ".long 18b,98b\n" + ".long 19b,99b\n" + ".long 20b,100b\n" + ".long 21b,101b\n" + ".previous" + : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), + "=&d" (tmp1), "=d" (tmp2) + : "0" (sum), "1" (len), "2" (src), "3" (dst) + ); + + *csum_err = tmp2; + + return(sum); +} + +/* + * copy from kernel space while checksumming, otherwise like csum_partial + */ + +unsigned int +csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, int sum) +{ + unsigned long tmp1, tmp2; + __asm__("movel %2,%4\n\t" + "btst #1,%4\n\t" /* Check alignment */ + "jeq 2f\n\t" + "subql #2,%1\n\t" /* buff%4==2: treat first word */ + "jgt 1f\n\t" + "addql #2,%1\n\t" /* len was == 2, treat only rest */ + "jra 4f\n" + "1:\t" + "movew %2@+,%4\n\t" /* add first word to sum */ + "addw %4,%0\n\t" + "movew %4,%3@+\n\t" + "clrl %4\n\t" + "addxl %4,%0\n" /* add X bit */ + "2:\t" + /* unrolled loop for the main part: do 8 longs at once */ + "movel %1,%4\n\t" /* save len in tmp1 */ + "lsrl #5,%1\n\t" /* len/32 */ + "jeq 2f\n\t" /* not enough... */ + "subql #1,%1\n" + "1:\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "dbra %1,1b\n\t" + "clrl %5\n\t" + "addxl %5,%0\n\t" /* add X bit */ + "clrw %1\n\t" + "subql #1,%1\n\t" + "jcc 1b\n" + "2:\t" + "movel %4,%1\n\t" /* restore len from tmp1 */ + "andw #0x1c,%4\n\t" /* number of rest longs */ + "jeq 4f\n\t" + "lsrw #2,%4\n\t" + "subqw #1,%4\n" + "3:\t" + /* loop for rest longs */ + "movel %2@+,%5\n\t" + "addxl %5,%0\n\t" + "movel %5,%3@+\n\t" + "dbra %4,3b\n\t" + "clrl %5\n\t" + "addxl %5,%0\n" /* add X bit */ + "4:\t" + /* now check for rest bytes that do not fit into longs */ + "andw #3,%1\n\t" + "jeq 7f\n\t" + "clrl %5\n\t" /* clear tmp2 for rest bytes */ + "subqw #2,%1\n\t" + "jlt 5f\n\t" + "movew %2@+,%5\n\t" /* have rest >= 2: get word */ + "movew %5,%3@+\n\t" + "swap %5\n\t" /* into bits 16..31 */ + "tstw %1\n\t" /* another byte? */ + "jeq 6f\n" + "5:\t" + "moveb %2@,%5\n\t" /* have odd rest: get byte */ + "moveb %5,%3@+\n\t" + "lslw #8,%5\n" /* into bits 8..15; 16..31 untouched */ + "6:\t" + "addl %5,%0\n\t" /* now add rest long to sum */ + "clrl %5\n\t" + "addxl %5,%0\n" /* add X bit */ + "7:\t" + : "=d" (sum), "=d" (len), "=a" (src), "=a" (dst), + "=&d" (tmp1), "=&d" (tmp2) + : "0" (sum), "1" (len), "2" (src), "3" (dst) + ); + return(sum); +} diff --git a/arch/m68k/lib/lshrdi3.c b/arch/m68k/lib/lshrdi3.c new file mode 100644 index 000000000000..d06442d3a328 --- /dev/null +++ b/arch/m68k/lib/lshrdi3.c @@ -0,0 +1,62 @@ +/* lshrdi3.c extracted from gcc-2.7.2/libgcc2.c which is: */ +/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#define BITS_PER_UNIT 8 + +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int word_type __attribute__ ((mode (__word__))); + +struct DIstruct {SItype high, low;}; + +typedef union +{ + struct DIstruct s; + DItype ll; +} DIunion; + +DItype +__lshrdi3 (DItype u, word_type b) +{ + DIunion w; + word_type bm; + DIunion uu; + + if (b == 0) + return u; + + uu.ll = u; + + bm = (sizeof (SItype) * BITS_PER_UNIT) - b; + if (bm <= 0) + { + w.s.high = 0; + w.s.low = (USItype)uu.s.high >> -bm; + } + else + { + USItype carries = (USItype)uu.s.high << bm; + w.s.high = (USItype)uu.s.high >> b; + w.s.low = ((USItype)uu.s.low >> b) | carries; + } + + return w.ll; +} diff --git a/arch/m68k/lib/memcmp.c b/arch/m68k/lib/memcmp.c new file mode 100644 index 000000000000..f4796febb773 --- /dev/null +++ b/arch/m68k/lib/memcmp.c @@ -0,0 +1,11 @@ +#include <linux/types.h> + +int memcmp(const void * cs,const void * ct,size_t count) +{ + const unsigned char *su1, *su2; + + for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) + if (*su1 != *su2) + return((*su1 < *su2) ? -1 : +1); + return(0); +} diff --git a/arch/m68k/lib/memcpy.c b/arch/m68k/lib/memcpy.c new file mode 100644 index 000000000000..73e181823d9b --- /dev/null +++ b/arch/m68k/lib/memcpy.c @@ -0,0 +1,75 @@ +#include <linux/types.h> + +void * memcpy(void * to, const void * from, size_t n) +{ + void *xto = to; + size_t temp, temp1; + + if (!n) + return xto; + if ((long) to & 1) + { + char *cto = to; + const char *cfrom = from; + *cto++ = *cfrom++; + to = cto; + from = cfrom; + n--; + } + if (n > 2 && (long) to & 2) + { + short *sto = to; + const short *sfrom = from; + *sto++ = *sfrom++; + to = sto; + from = sfrom; + n -= 2; + } + temp = n >> 2; + if (temp) + { + long *lto = to; + const long *lfrom = from; + + __asm__ __volatile__("movel %2,%3\n\t" + "andw #7,%3\n\t" + "lsrl #3,%2\n\t" + "negw %3\n\t" + "jmp %%pc@(1f,%3:w:2)\n\t" + "4:\t" + "movel %0@+,%1@+\n\t" + "movel %0@+,%1@+\n\t" + "movel %0@+,%1@+\n\t" + "movel %0@+,%1@+\n\t" + "movel %0@+,%1@+\n\t" + "movel %0@+,%1@+\n\t" + "movel %0@+,%1@+\n\t" + "movel %0@+,%1@+\n\t" + "1:\t" + "dbra %2,4b\n\t" + "clrw %2\n\t" + "subql #1,%2\n\t" + "jpl 4b\n\t" + : "=a" (lfrom), "=a" (lto), "=d" (temp), + "=&d" (temp1) + : "0" (lfrom), "1" (lto), "2" (temp) + ); + to = lto; + from = lfrom; + } + if (n & 2) + { + short *sto = to; + const short *sfrom = from; + *sto++ = *sfrom++; + to = sto; + from = sfrom; + } + if (n & 1) + { + char *cto = to; + const char *cfrom = from; + *cto = *cfrom; + } + return xto; +} diff --git a/arch/m68k/lib/memset.c b/arch/m68k/lib/memset.c new file mode 100644 index 000000000000..d55fdb2ee9d3 --- /dev/null +++ b/arch/m68k/lib/memset.c @@ -0,0 +1,68 @@ +#include <linux/types.h> + +void * memset(void * s, int c, size_t count) +{ + void *xs = s; + size_t temp, temp1; + + if (!count) + return xs; + c &= 0xff; + c |= c << 8; + c |= c << 16; + if ((long) s & 1) + { + char *cs = s; + *cs++ = c; + s = cs; + count--; + } + if (count > 2 && (long) s & 2) + { + short *ss = s; + *ss++ = c; + s = ss; + count -= 2; + } + temp = count >> 2; + if (temp) + { + long *ls = s; + + __asm__ __volatile__("movel %1,%2\n\t" + "andw #7,%2\n\t" + "lsrl #3,%1\n\t" + "negw %2\n\t" + "jmp %%pc@(2f,%2:w:2)\n\t" + "1:\t" + "movel %3,%0@+\n\t" + "movel %3,%0@+\n\t" + "movel %3,%0@+\n\t" + "movel %3,%0@+\n\t" + "movel %3,%0@+\n\t" + "movel %3,%0@+\n\t" + "movel %3,%0@+\n\t" + "movel %3,%0@+\n\t" + "2:\t" + "dbra %1,1b\n\t" + "clrw %1\n\t" + "subql #1,%1\n\t" + "jpl 1b\n\t" + : "=a" (ls), "=d" (temp), "=&d" (temp1) + : "d" (c), "0" (ls), "1" (temp) + ); + s = ls; + } + if (count & 2) + { + short *ss = s; + *ss++ = c; + s = ss; + } + if (count & 1) + { + char *cs = s; + *cs = c; + } + return xs; +} diff --git a/arch/m68k/lib/muldi3.c b/arch/m68k/lib/muldi3.c new file mode 100644 index 000000000000..be4f275649e3 --- /dev/null +++ b/arch/m68k/lib/muldi3.c @@ -0,0 +1,63 @@ +/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and + gcc-2.7.2.3/longlong.h which is: */ +/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#define BITS_PER_UNIT 8 + +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mulu%.l %3,%1:%0" \ + : "=d" ((USItype)(w0)), \ + "=d" ((USItype)(w1)) \ + : "%0" ((USItype)(u)), \ + "dmi" ((USItype)(v))) + +#define __umulsidi3(u, v) \ + ({DIunion __w; \ + umul_ppmm (__w.s.high, __w.s.low, u, v); \ + __w.ll; }) + +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef int word_type __attribute__ ((mode (__word__))); + +struct DIstruct {SItype high, low;}; + +typedef union +{ + struct DIstruct s; + DItype ll; +} DIunion; + +DItype +__muldi3 (DItype u, DItype v) +{ + DIunion w; + DIunion uu, vv; + + uu.ll = u, + vv.ll = v; + + w.ll = __umulsidi3 (uu.s.low, vv.s.low); + w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high + + (USItype) uu.s.high * (USItype) vv.s.low); + + return w.ll; +} diff --git a/arch/m68k/lib/semaphore.S b/arch/m68k/lib/semaphore.S new file mode 100644 index 000000000000..0215624c1602 --- /dev/null +++ b/arch/m68k/lib/semaphore.S @@ -0,0 +1,53 @@ +/* + * linux/arch/m68k/lib/semaphore.S + * + * Copyright (C) 1996 Linus Torvalds + * + * m68k version by Andreas Schwab + */ + +#include <linux/linkage.h> +#include <asm/semaphore.h> + +/* + * The semaphore operations have a special calling sequence that + * allow us to do a simpler in-line version of them. These routines + * need to convert that sequence back into the C sequence when + * there is contention on the semaphore. + */ +ENTRY(__down_failed) + moveml %a0/%d0/%d1,-(%sp) + movel %a1,-(%sp) + jbsr __down + movel (%sp)+,%a1 + moveml (%sp)+,%a0/%d0/%d1 + rts + +ENTRY(__down_failed_interruptible) + movel %a0,-(%sp) + movel %d1,-(%sp) + movel %a1,-(%sp) + jbsr __down_interruptible + movel (%sp)+,%a1 + movel (%sp)+,%d1 + movel (%sp)+,%a0 + rts + +ENTRY(__down_failed_trylock) + movel %a0,-(%sp) + movel %d1,-(%sp) + movel %a1,-(%sp) + jbsr __down_trylock + movel (%sp)+,%a1 + movel (%sp)+,%d1 + movel (%sp)+,%a0 + rts + +ENTRY(__up_wakeup) + moveml %a0/%d0/%d1,-(%sp) + movel %a1,-(%sp) + jbsr __up + movel (%sp)+,%a1 + moveml (%sp)+,%a0/%d0/%d1 + rts + |