m68k: merge m68k and m68knommu arch directories
There is a lot of common code that could be shared between the m68k and m68knommu arch branches. It makes sense to merge the two branches into a single directory structure so that we can more easily share that common code. This is a brute force merge, based on a script from Stephen King <sfking@fdwdc.com>, which was originally written by Arnd Bergmann <arnd@arndb.de>. > The script was inspired by the script Sam Ravnborg used to merge the > includes from m68knommu. For those files common to both arches but > differing in content, the m68k version of the file is renamed to > <file>_mm.<ext> and the m68knommu version of the file is moved into the > corresponding m68k directory and renamed <file>_no.<ext> and a small > wrapper file <file>.<ext> is used to select between the two version. Files > that are common to both but don't differ are removed from the m68knommu > tree and files and directories that are unique to the m68knommu tree are > moved to the m68k tree. Finally, the arch/m68knommu tree is removed. > > To select between the the versions of the files, the wrapper uses > > #ifdef CONFIG_MMU > #include <file>_mm.<ext> > #else > #include <file>_no.<ext> > #endif On top of this file merge I have done a simplistic merge of m68k and m68knommu Kconfig, which primarily attempts to keep existing options and menus in place. Other than a handful of options being moved it produces identical .config outputs on m68k and m68knommu targets I tested it on. With this in place there is now quite a bit of scope for merge cleanups in future patches. Signed-off-by: Greg Ungerer <gerg@uclinux.org>
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
#
|
||||
# Makefile for m68k-specific library files..
|
||||
#
|
||||
|
||||
lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
|
||||
checksum.o string.o uaccess.o
|
||||
ifdef CONFIG_MMU
|
||||
include arch/m68k/lib/Makefile_mm
|
||||
else
|
||||
include arch/m68k/lib/Makefile_no
|
||||
endif
|
||||
|
6
arch/m68k/lib/Makefile_mm
Normal file
6
arch/m68k/lib/Makefile_mm
Normal file
@@ -0,0 +1,6 @@
|
||||
#
|
||||
# Makefile for m68k-specific library files..
|
||||
#
|
||||
|
||||
lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
|
||||
checksum.o string.o uaccess.o
|
7
arch/m68k/lib/Makefile_no
Normal file
7
arch/m68k/lib/Makefile_no
Normal file
@@ -0,0 +1,7 @@
|
||||
#
|
||||
# Makefile for m68knommu specific library files..
|
||||
#
|
||||
|
||||
lib-y := ashldi3.o ashrdi3.o lshrdi3.o \
|
||||
muldi3.o mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \
|
||||
checksum.o memcpy.o memmove.o memset.o delay.o
|
@@ -1,425 +1,5 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
__wsum csum_partial(const void *buff, int len, __wsum 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.
|
||||
*/
|
||||
|
||||
__wsum
|
||||
csum_partial_copy_from_user(const void __user *src, void *dst,
|
||||
int len, __wsum 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);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(csum_partial_copy_from_user);
|
||||
|
||||
|
||||
/*
|
||||
* copy from kernel space while checksumming, otherwise like csum_partial
|
||||
*/
|
||||
|
||||
__wsum
|
||||
csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum 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);
|
||||
}
|
||||
EXPORT_SYMBOL(csum_partial_copy_nocheck);
|
||||
#ifdef CONFIG_MMU
|
||||
#include "checksum_mm.c"
|
||||
#else
|
||||
#include "checksum_no.c"
|
||||
#endif
|
||||
|
425
arch/m68k/lib/checksum_mm.c
Normal file
425
arch/m68k/lib/checksum_mm.c
Normal file
@@ -0,0 +1,425 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
__wsum csum_partial(const void *buff, int len, __wsum 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.
|
||||
*/
|
||||
|
||||
__wsum
|
||||
csum_partial_copy_from_user(const void __user *src, void *dst,
|
||||
int len, __wsum 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);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(csum_partial_copy_from_user);
|
||||
|
||||
|
||||
/*
|
||||
* copy from kernel space while checksumming, otherwise like csum_partial
|
||||
*/
|
||||
|
||||
__wsum
|
||||
csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum 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);
|
||||
}
|
||||
EXPORT_SYMBOL(csum_partial_copy_nocheck);
|
153
arch/m68k/lib/checksum_no.c
Normal file
153
arch/m68k/lib/checksum_no.c
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access kills, so most
|
||||
of the assembly has to go. */
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <net/checksum.h>
|
||||
|
||||
static inline unsigned short from32to16(unsigned long x)
|
||||
{
|
||||
/* add up 16-bit and 16-bit for 16+c bit */
|
||||
x = (x & 0xffff) + (x >> 16);
|
||||
/* add up carry.. */
|
||||
x = (x & 0xffff) + (x >> 16);
|
||||
return x;
|
||||
}
|
||||
|
||||
static unsigned long do_csum(const unsigned char * buff, int len)
|
||||
{
|
||||
int odd, count;
|
||||
unsigned long result = 0;
|
||||
|
||||
if (len <= 0)
|
||||
goto out;
|
||||
odd = 1 & (unsigned long) buff;
|
||||
if (odd) {
|
||||
result = *buff;
|
||||
len--;
|
||||
buff++;
|
||||
}
|
||||
count = len >> 1; /* nr of 16-bit words.. */
|
||||
if (count) {
|
||||
if (2 & (unsigned long) buff) {
|
||||
result += *(unsigned short *) buff;
|
||||
count--;
|
||||
len -= 2;
|
||||
buff += 2;
|
||||
}
|
||||
count >>= 1; /* nr of 32-bit words.. */
|
||||
if (count) {
|
||||
unsigned long carry = 0;
|
||||
do {
|
||||
unsigned long w = *(unsigned long *) buff;
|
||||
count--;
|
||||
buff += 4;
|
||||
result += carry;
|
||||
result += w;
|
||||
carry = (w > result);
|
||||
} while (count);
|
||||
result += carry;
|
||||
result = (result & 0xffff) + (result >> 16);
|
||||
}
|
||||
if (len & 2) {
|
||||
result += *(unsigned short *) buff;
|
||||
buff += 2;
|
||||
}
|
||||
}
|
||||
if (len & 1)
|
||||
result += (*buff << 8);
|
||||
result = from32to16(result);
|
||||
if (odd)
|
||||
result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COLDFIRE
|
||||
/*
|
||||
* This is a version of ip_compute_csum() optimized for IP headers,
|
||||
* which always checksum on 4 octet boundaries.
|
||||
*/
|
||||
__sum16 ip_fast_csum(const void *iph, unsigned int ihl)
|
||||
{
|
||||
return (__force __sum16)~do_csum(iph,ihl*4);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* computes the checksum of a memory block at buff, length len,
|
||||
* and adds in "sum" (32-bit)
|
||||
*
|
||||
* returns a 32-bit number suitable for feeding into itself
|
||||
* or csum_tcpudp_magic
|
||||
*
|
||||
* this function must be called with even lengths, except
|
||||
* for the last fragment, which may be odd
|
||||
*
|
||||
* it's best to have buff aligned on a 32-bit boundary
|
||||
*/
|
||||
__wsum csum_partial(const void *buff, int len, __wsum sum)
|
||||
{
|
||||
unsigned int result = do_csum(buff, len);
|
||||
|
||||
/* add in old sum, and carry.. */
|
||||
result += (__force u32)sum;
|
||||
if ((__force u32)sum > result)
|
||||
result += 1;
|
||||
return (__force __wsum)result;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(csum_partial);
|
||||
|
||||
/*
|
||||
* copy from fs while checksumming, otherwise like csum_partial
|
||||
*/
|
||||
|
||||
__wsum
|
||||
csum_partial_copy_from_user(const void __user *src, void *dst,
|
||||
int len, __wsum sum, int *csum_err)
|
||||
{
|
||||
if (csum_err) *csum_err = 0;
|
||||
memcpy(dst, (__force const void *)src, len);
|
||||
return csum_partial(dst, len, sum);
|
||||
}
|
||||
|
||||
/*
|
||||
* copy from ds while checksumming, otherwise like csum_partial
|
||||
*/
|
||||
|
||||
__wsum
|
||||
csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum)
|
||||
{
|
||||
memcpy(dst, src, len);
|
||||
return csum_partial(dst, len, sum);
|
||||
}
|
21
arch/m68k/lib/delay.c
Normal file
21
arch/m68k/lib/delay.c
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* arch/m68knommu/lib/delay.c
|
||||
*
|
||||
* (C) Copyright 2004, Greg Ungerer <gerg@snapgear.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <asm/param.h>
|
||||
#include <asm/delay.h>
|
||||
|
||||
EXPORT_SYMBOL(udelay);
|
||||
|
||||
void udelay(unsigned long usecs)
|
||||
{
|
||||
_udelay(usecs);
|
||||
}
|
||||
|
125
arch/m68k/lib/divsi3.S
Normal file
125
arch/m68k/lib/divsi3.S
Normal file
@@ -0,0 +1,125 @@
|
||||
/* libgcc1 routines for 68000 w/o floating-point hardware.
|
||||
Copyright (C) 1994, 1996, 1997, 1998 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.
|
||||
|
||||
In addition to the permissions in the GNU General Public License, the
|
||||
Free Software Foundation gives you unlimited permission to link the
|
||||
compiled version of this file with other programs, and to distribute
|
||||
those programs without any restriction coming from the use of this
|
||||
file. (The General Public License restrictions do apply in other
|
||||
respects; for example, they cover modification of the file, and
|
||||
distribution when not linked into another program.)
|
||||
|
||||
This file 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 this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* As a special exception, if you link this library with files
|
||||
compiled with GCC to produce an executable, this does not cause
|
||||
the resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public License. */
|
||||
|
||||
/* Use this one for any 680x0; assumes no floating point hardware.
|
||||
The trailing " '" appearing on some lines is for ANSI preprocessors. Yuk.
|
||||
Some of this code comes from MINIX, via the folks at ericsson.
|
||||
D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992
|
||||
*/
|
||||
|
||||
/* These are predefined by new versions of GNU cpp. */
|
||||
|
||||
#ifndef __USER_LABEL_PREFIX__
|
||||
#define __USER_LABEL_PREFIX__ _
|
||||
#endif
|
||||
|
||||
#ifndef __REGISTER_PREFIX__
|
||||
#define __REGISTER_PREFIX__
|
||||
#endif
|
||||
|
||||
#ifndef __IMMEDIATE_PREFIX__
|
||||
#define __IMMEDIATE_PREFIX__ #
|
||||
#endif
|
||||
|
||||
/* ANSI concatenation macros. */
|
||||
|
||||
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||
#define CONCAT2(a, b) a ## b
|
||||
|
||||
/* Use the right prefix for global labels. */
|
||||
|
||||
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
|
||||
|
||||
/* Use the right prefix for registers. */
|
||||
|
||||
#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
|
||||
|
||||
/* Use the right prefix for immediate values. */
|
||||
|
||||
#define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x)
|
||||
|
||||
#define d0 REG (d0)
|
||||
#define d1 REG (d1)
|
||||
#define d2 REG (d2)
|
||||
#define d3 REG (d3)
|
||||
#define d4 REG (d4)
|
||||
#define d5 REG (d5)
|
||||
#define d6 REG (d6)
|
||||
#define d7 REG (d7)
|
||||
#define a0 REG (a0)
|
||||
#define a1 REG (a1)
|
||||
#define a2 REG (a2)
|
||||
#define a3 REG (a3)
|
||||
#define a4 REG (a4)
|
||||
#define a5 REG (a5)
|
||||
#define a6 REG (a6)
|
||||
#define fp REG (fp)
|
||||
#define sp REG (sp)
|
||||
|
||||
.text
|
||||
.proc
|
||||
.globl SYM (__divsi3)
|
||||
SYM (__divsi3):
|
||||
movel d2, sp@-
|
||||
|
||||
moveq IMM (1), d2 /* sign of result stored in d2 (=1 or =-1) */
|
||||
movel sp@(12), d1 /* d1 = divisor */
|
||||
jpl L1
|
||||
negl d1
|
||||
#if !(defined(__mcf5200__) || defined(__mcoldfire__))
|
||||
negb d2 /* change sign because divisor <0 */
|
||||
#else
|
||||
negl d2 /* change sign because divisor <0 */
|
||||
#endif
|
||||
L1: movel sp@(8), d0 /* d0 = dividend */
|
||||
jpl L2
|
||||
negl d0
|
||||
#if !(defined(__mcf5200__) || defined(__mcoldfire__))
|
||||
negb d2
|
||||
#else
|
||||
negl d2
|
||||
#endif
|
||||
|
||||
L2: movel d1, sp@-
|
||||
movel d0, sp@-
|
||||
jbsr SYM (__udivsi3) /* divide abs(dividend) by abs(divisor) */
|
||||
addql IMM (8), sp
|
||||
|
||||
tstb d2
|
||||
jpl L3
|
||||
negl d0
|
||||
|
||||
L3: movel sp@+, d2
|
||||
rts
|
||||
|
62
arch/m68k/lib/memcpy.c
Normal file
62
arch/m68k/lib/memcpy.c
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
void * memcpy(void * to, const void * from, size_t n)
|
||||
{
|
||||
#ifdef CONFIG_COLDFIRE
|
||||
void *xto = to;
|
||||
size_t temp;
|
||||
|
||||
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;
|
||||
for (; temp; temp--)
|
||||
*lto++ = *lfrom++;
|
||||
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;
|
||||
#else
|
||||
const char *c_from = from;
|
||||
char *c_to = to;
|
||||
while (n-- > 0)
|
||||
*c_to++ = *c_from++;
|
||||
return((void *) to);
|
||||
#endif
|
||||
}
|
105
arch/m68k/lib/memmove.c
Normal file
105
arch/m68k/lib/memmove.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file COPYING in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#define __IN_STRING_C
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
void *memmove(void *dest, const void *src, size_t n)
|
||||
{
|
||||
void *xdest = dest;
|
||||
size_t temp;
|
||||
|
||||
if (!n)
|
||||
return xdest;
|
||||
|
||||
if (dest < src) {
|
||||
if ((long)dest & 1) {
|
||||
char *cdest = dest;
|
||||
const char *csrc = src;
|
||||
*cdest++ = *csrc++;
|
||||
dest = cdest;
|
||||
src = csrc;
|
||||
n--;
|
||||
}
|
||||
if (n > 2 && (long)dest & 2) {
|
||||
short *sdest = dest;
|
||||
const short *ssrc = src;
|
||||
*sdest++ = *ssrc++;
|
||||
dest = sdest;
|
||||
src = ssrc;
|
||||
n -= 2;
|
||||
}
|
||||
temp = n >> 2;
|
||||
if (temp) {
|
||||
long *ldest = dest;
|
||||
const long *lsrc = src;
|
||||
temp--;
|
||||
do
|
||||
*ldest++ = *lsrc++;
|
||||
while (temp--);
|
||||
dest = ldest;
|
||||
src = lsrc;
|
||||
}
|
||||
if (n & 2) {
|
||||
short *sdest = dest;
|
||||
const short *ssrc = src;
|
||||
*sdest++ = *ssrc++;
|
||||
dest = sdest;
|
||||
src = ssrc;
|
||||
}
|
||||
if (n & 1) {
|
||||
char *cdest = dest;
|
||||
const char *csrc = src;
|
||||
*cdest = *csrc;
|
||||
}
|
||||
} else {
|
||||
dest = (char *)dest + n;
|
||||
src = (const char *)src + n;
|
||||
if ((long)dest & 1) {
|
||||
char *cdest = dest;
|
||||
const char *csrc = src;
|
||||
*--cdest = *--csrc;
|
||||
dest = cdest;
|
||||
src = csrc;
|
||||
n--;
|
||||
}
|
||||
if (n > 2 && (long)dest & 2) {
|
||||
short *sdest = dest;
|
||||
const short *ssrc = src;
|
||||
*--sdest = *--ssrc;
|
||||
dest = sdest;
|
||||
src = ssrc;
|
||||
n -= 2;
|
||||
}
|
||||
temp = n >> 2;
|
||||
if (temp) {
|
||||
long *ldest = dest;
|
||||
const long *lsrc = src;
|
||||
temp--;
|
||||
do
|
||||
*--ldest = *--lsrc;
|
||||
while (temp--);
|
||||
dest = ldest;
|
||||
src = lsrc;
|
||||
}
|
||||
if (n & 2) {
|
||||
short *sdest = dest;
|
||||
const short *ssrc = src;
|
||||
*--sdest = *--ssrc;
|
||||
dest = sdest;
|
||||
src = ssrc;
|
||||
}
|
||||
if (n & 1) {
|
||||
char *cdest = dest;
|
||||
const char *csrc = src;
|
||||
*--cdest = *--csrc;
|
||||
}
|
||||
}
|
||||
return xdest;
|
||||
}
|
||||
EXPORT_SYMBOL(memmove);
|
47
arch/m68k/lib/memset.c
Normal file
47
arch/m68k/lib/memset.c
Normal file
@@ -0,0 +1,47 @@
|
||||
#include <linux/types.h>
|
||||
|
||||
void * memset(void * s, int c, size_t count)
|
||||
{
|
||||
void *xs = s;
|
||||
size_t temp;
|
||||
|
||||
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;
|
||||
for (; temp; temp--)
|
||||
*ls++ = c;
|
||||
s = ls;
|
||||
}
|
||||
if (count & 2)
|
||||
{
|
||||
short *ss = s;
|
||||
*ss++ = c;
|
||||
s = ss;
|
||||
}
|
||||
if (count & 1)
|
||||
{
|
||||
char *cs = s;
|
||||
*cs = c;
|
||||
}
|
||||
return xs;
|
||||
}
|
113
arch/m68k/lib/modsi3.S
Normal file
113
arch/m68k/lib/modsi3.S
Normal file
@@ -0,0 +1,113 @@
|
||||
/* libgcc1 routines for 68000 w/o floating-point hardware.
|
||||
Copyright (C) 1994, 1996, 1997, 1998 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.
|
||||
|
||||
In addition to the permissions in the GNU General Public License, the
|
||||
Free Software Foundation gives you unlimited permission to link the
|
||||
compiled version of this file with other programs, and to distribute
|
||||
those programs without any restriction coming from the use of this
|
||||
file. (The General Public License restrictions do apply in other
|
||||
respects; for example, they cover modification of the file, and
|
||||
distribution when not linked into another program.)
|
||||
|
||||
This file 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 this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* As a special exception, if you link this library with files
|
||||
compiled with GCC to produce an executable, this does not cause
|
||||
the resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public License. */
|
||||
|
||||
/* Use this one for any 680x0; assumes no floating point hardware.
|
||||
The trailing " '" appearing on some lines is for ANSI preprocessors. Yuk.
|
||||
Some of this code comes from MINIX, via the folks at ericsson.
|
||||
D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992
|
||||
*/
|
||||
|
||||
/* These are predefined by new versions of GNU cpp. */
|
||||
|
||||
#ifndef __USER_LABEL_PREFIX__
|
||||
#define __USER_LABEL_PREFIX__ _
|
||||
#endif
|
||||
|
||||
#ifndef __REGISTER_PREFIX__
|
||||
#define __REGISTER_PREFIX__
|
||||
#endif
|
||||
|
||||
#ifndef __IMMEDIATE_PREFIX__
|
||||
#define __IMMEDIATE_PREFIX__ #
|
||||
#endif
|
||||
|
||||
/* ANSI concatenation macros. */
|
||||
|
||||
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||
#define CONCAT2(a, b) a ## b
|
||||
|
||||
/* Use the right prefix for global labels. */
|
||||
|
||||
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
|
||||
|
||||
/* Use the right prefix for registers. */
|
||||
|
||||
#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
|
||||
|
||||
/* Use the right prefix for immediate values. */
|
||||
|
||||
#define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x)
|
||||
|
||||
#define d0 REG (d0)
|
||||
#define d1 REG (d1)
|
||||
#define d2 REG (d2)
|
||||
#define d3 REG (d3)
|
||||
#define d4 REG (d4)
|
||||
#define d5 REG (d5)
|
||||
#define d6 REG (d6)
|
||||
#define d7 REG (d7)
|
||||
#define a0 REG (a0)
|
||||
#define a1 REG (a1)
|
||||
#define a2 REG (a2)
|
||||
#define a3 REG (a3)
|
||||
#define a4 REG (a4)
|
||||
#define a5 REG (a5)
|
||||
#define a6 REG (a6)
|
||||
#define fp REG (fp)
|
||||
#define sp REG (sp)
|
||||
|
||||
.text
|
||||
.proc
|
||||
.globl SYM (__modsi3)
|
||||
SYM (__modsi3):
|
||||
movel sp@(8), d1 /* d1 = divisor */
|
||||
movel sp@(4), d0 /* d0 = dividend */
|
||||
movel d1, sp@-
|
||||
movel d0, sp@-
|
||||
jbsr SYM (__divsi3)
|
||||
addql IMM (8), sp
|
||||
movel sp@(8), d1 /* d1 = divisor */
|
||||
#if !(defined(__mcf5200__) || defined(__mcoldfire__))
|
||||
movel d1, sp@-
|
||||
movel d0, sp@-
|
||||
jbsr SYM (__mulsi3) /* d0 = (a/b)*b */
|
||||
addql IMM (8), sp
|
||||
#else
|
||||
mulsl d1,d0
|
||||
#endif
|
||||
movel sp@(4), d1 /* d1 = dividend */
|
||||
subl d0, d1 /* d1 = a - (a/b)*b */
|
||||
movel d1, d0
|
||||
rts
|
||||
|
@@ -1,63 +1,5 @@
|
||||
/* 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;
|
||||
}
|
||||
#ifdef CONFIG_MMU
|
||||
#include "muldi3_mm.c"
|
||||
#else
|
||||
#include "muldi3_no.c"
|
||||
#endif
|
||||
|
63
arch/m68k/lib/muldi3_mm.c
Normal file
63
arch/m68k/lib/muldi3_mm.c
Normal file
@@ -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;
|
||||
}
|
86
arch/m68k/lib/muldi3_no.c
Normal file
86
arch/m68k/lib/muldi3_no.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/* 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 SI_TYPE_SIZE 32
|
||||
|
||||
#define __BITS4 (SI_TYPE_SIZE / 4)
|
||||
#define __ll_B (1L << (SI_TYPE_SIZE / 2))
|
||||
#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
|
||||
#define __ll_highpart(t) ((USItype) (t) / __ll_B)
|
||||
|
||||
#define umul_ppmm(w1, w0, u, v) \
|
||||
do { \
|
||||
USItype __x0, __x1, __x2, __x3; \
|
||||
USItype __ul, __vl, __uh, __vh; \
|
||||
\
|
||||
__ul = __ll_lowpart (u); \
|
||||
__uh = __ll_highpart (u); \
|
||||
__vl = __ll_lowpart (v); \
|
||||
__vh = __ll_highpart (v); \
|
||||
\
|
||||
__x0 = (USItype) __ul * __vl; \
|
||||
__x1 = (USItype) __ul * __vh; \
|
||||
__x2 = (USItype) __uh * __vl; \
|
||||
__x3 = (USItype) __uh * __vh; \
|
||||
\
|
||||
__x1 += __ll_highpart (__x0);/* this can't give carry */ \
|
||||
__x1 += __x2; /* but this indeed can */ \
|
||||
if (__x1 < __x2) /* did we get it? */ \
|
||||
__x3 += __ll_B; /* yes, add it in the proper pos. */ \
|
||||
\
|
||||
(w1) = __x3 + __ll_highpart (__x1); \
|
||||
(w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \
|
||||
} while (0)
|
||||
|
||||
#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;
|
||||
}
|
110
arch/m68k/lib/mulsi3.S
Normal file
110
arch/m68k/lib/mulsi3.S
Normal file
@@ -0,0 +1,110 @@
|
||||
/* libgcc1 routines for 68000 w/o floating-point hardware.
|
||||
Copyright (C) 1994, 1996, 1997, 1998 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.
|
||||
|
||||
In addition to the permissions in the GNU General Public License, the
|
||||
Free Software Foundation gives you unlimited permission to link the
|
||||
compiled version of this file with other programs, and to distribute
|
||||
those programs without any restriction coming from the use of this
|
||||
file. (The General Public License restrictions do apply in other
|
||||
respects; for example, they cover modification of the file, and
|
||||
distribution when not linked into another program.)
|
||||
|
||||
This file 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 this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* As a special exception, if you link this library with files
|
||||
compiled with GCC to produce an executable, this does not cause
|
||||
the resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public License. */
|
||||
|
||||
/* Use this one for any 680x0; assumes no floating point hardware.
|
||||
The trailing " '" appearing on some lines is for ANSI preprocessors. Yuk.
|
||||
Some of this code comes from MINIX, via the folks at ericsson.
|
||||
D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992
|
||||
*/
|
||||
|
||||
/* These are predefined by new versions of GNU cpp. */
|
||||
|
||||
#ifndef __USER_LABEL_PREFIX__
|
||||
#define __USER_LABEL_PREFIX__ _
|
||||
#endif
|
||||
|
||||
#ifndef __REGISTER_PREFIX__
|
||||
#define __REGISTER_PREFIX__
|
||||
#endif
|
||||
|
||||
#ifndef __IMMEDIATE_PREFIX__
|
||||
#define __IMMEDIATE_PREFIX__ #
|
||||
#endif
|
||||
|
||||
/* ANSI concatenation macros. */
|
||||
|
||||
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||
#define CONCAT2(a, b) a ## b
|
||||
|
||||
/* Use the right prefix for global labels. */
|
||||
|
||||
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
|
||||
|
||||
/* Use the right prefix for registers. */
|
||||
|
||||
#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
|
||||
|
||||
/* Use the right prefix for immediate values. */
|
||||
|
||||
#define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x)
|
||||
|
||||
#define d0 REG (d0)
|
||||
#define d1 REG (d1)
|
||||
#define d2 REG (d2)
|
||||
#define d3 REG (d3)
|
||||
#define d4 REG (d4)
|
||||
#define d5 REG (d5)
|
||||
#define d6 REG (d6)
|
||||
#define d7 REG (d7)
|
||||
#define a0 REG (a0)
|
||||
#define a1 REG (a1)
|
||||
#define a2 REG (a2)
|
||||
#define a3 REG (a3)
|
||||
#define a4 REG (a4)
|
||||
#define a5 REG (a5)
|
||||
#define a6 REG (a6)
|
||||
#define fp REG (fp)
|
||||
#define sp REG (sp)
|
||||
|
||||
.text
|
||||
.proc
|
||||
.globl SYM (__mulsi3)
|
||||
SYM (__mulsi3):
|
||||
movew sp@(4), d0 /* x0 -> d0 */
|
||||
muluw sp@(10), d0 /* x0*y1 */
|
||||
movew sp@(6), d1 /* x1 -> d1 */
|
||||
muluw sp@(8), d1 /* x1*y0 */
|
||||
#if !(defined(__mcf5200__) || defined(__mcoldfire__))
|
||||
addw d1, d0
|
||||
#else
|
||||
addl d1, d0
|
||||
#endif
|
||||
swap d0
|
||||
clrw d0
|
||||
movew sp@(6), d1 /* x1 -> d1 */
|
||||
muluw sp@(10), d1 /* x1*y1 */
|
||||
addl d1, d0
|
||||
|
||||
rts
|
||||
|
162
arch/m68k/lib/udivsi3.S
Normal file
162
arch/m68k/lib/udivsi3.S
Normal file
@@ -0,0 +1,162 @@
|
||||
/* libgcc1 routines for 68000 w/o floating-point hardware.
|
||||
Copyright (C) 1994, 1996, 1997, 1998 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.
|
||||
|
||||
In addition to the permissions in the GNU General Public License, the
|
||||
Free Software Foundation gives you unlimited permission to link the
|
||||
compiled version of this file with other programs, and to distribute
|
||||
those programs without any restriction coming from the use of this
|
||||
file. (The General Public License restrictions do apply in other
|
||||
respects; for example, they cover modification of the file, and
|
||||
distribution when not linked into another program.)
|
||||
|
||||
This file 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 this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* As a special exception, if you link this library with files
|
||||
compiled with GCC to produce an executable, this does not cause
|
||||
the resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public License. */
|
||||
|
||||
/* Use this one for any 680x0; assumes no floating point hardware.
|
||||
The trailing " '" appearing on some lines is for ANSI preprocessors. Yuk.
|
||||
Some of this code comes from MINIX, via the folks at ericsson.
|
||||
D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992
|
||||
*/
|
||||
|
||||
/* These are predefined by new versions of GNU cpp. */
|
||||
|
||||
#ifndef __USER_LABEL_PREFIX__
|
||||
#define __USER_LABEL_PREFIX__ _
|
||||
#endif
|
||||
|
||||
#ifndef __REGISTER_PREFIX__
|
||||
#define __REGISTER_PREFIX__
|
||||
#endif
|
||||
|
||||
#ifndef __IMMEDIATE_PREFIX__
|
||||
#define __IMMEDIATE_PREFIX__ #
|
||||
#endif
|
||||
|
||||
/* ANSI concatenation macros. */
|
||||
|
||||
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||
#define CONCAT2(a, b) a ## b
|
||||
|
||||
/* Use the right prefix for global labels. */
|
||||
|
||||
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
|
||||
|
||||
/* Use the right prefix for registers. */
|
||||
|
||||
#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
|
||||
|
||||
/* Use the right prefix for immediate values. */
|
||||
|
||||
#define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x)
|
||||
|
||||
#define d0 REG (d0)
|
||||
#define d1 REG (d1)
|
||||
#define d2 REG (d2)
|
||||
#define d3 REG (d3)
|
||||
#define d4 REG (d4)
|
||||
#define d5 REG (d5)
|
||||
#define d6 REG (d6)
|
||||
#define d7 REG (d7)
|
||||
#define a0 REG (a0)
|
||||
#define a1 REG (a1)
|
||||
#define a2 REG (a2)
|
||||
#define a3 REG (a3)
|
||||
#define a4 REG (a4)
|
||||
#define a5 REG (a5)
|
||||
#define a6 REG (a6)
|
||||
#define fp REG (fp)
|
||||
#define sp REG (sp)
|
||||
|
||||
.text
|
||||
.proc
|
||||
.globl SYM (__udivsi3)
|
||||
SYM (__udivsi3):
|
||||
#if !(defined(__mcf5200__) || defined(__mcoldfire__))
|
||||
movel d2, sp@-
|
||||
movel sp@(12), d1 /* d1 = divisor */
|
||||
movel sp@(8), d0 /* d0 = dividend */
|
||||
|
||||
cmpl IMM (0x10000), d1 /* divisor >= 2 ^ 16 ? */
|
||||
jcc L3 /* then try next algorithm */
|
||||
movel d0, d2
|
||||
clrw d2
|
||||
swap d2
|
||||
divu d1, d2 /* high quotient in lower word */
|
||||
movew d2, d0 /* save high quotient */
|
||||
swap d0
|
||||
movew sp@(10), d2 /* get low dividend + high rest */
|
||||
divu d1, d2 /* low quotient */
|
||||
movew d2, d0
|
||||
jra L6
|
||||
|
||||
L3: movel d1, d2 /* use d2 as divisor backup */
|
||||
L4: lsrl IMM (1), d1 /* shift divisor */
|
||||
lsrl IMM (1), d0 /* shift dividend */
|
||||
cmpl IMM (0x10000), d1 /* still divisor >= 2 ^ 16 ? */
|
||||
jcc L4
|
||||
divu d1, d0 /* now we have 16 bit divisor */
|
||||
andl IMM (0xffff), d0 /* mask out divisor, ignore remainder */
|
||||
|
||||
/* Multiply the 16 bit tentative quotient with the 32 bit divisor. Because of
|
||||
the operand ranges, this might give a 33 bit product. If this product is
|
||||
greater than the dividend, the tentative quotient was too large. */
|
||||
movel d2, d1
|
||||
mulu d0, d1 /* low part, 32 bits */
|
||||
swap d2
|
||||
mulu d0, d2 /* high part, at most 17 bits */
|
||||
swap d2 /* align high part with low part */
|
||||
tstw d2 /* high part 17 bits? */
|
||||
jne L5 /* if 17 bits, quotient was too large */
|
||||
addl d2, d1 /* add parts */
|
||||
jcs L5 /* if sum is 33 bits, quotient was too large */
|
||||
cmpl sp@(8), d1 /* compare the sum with the dividend */
|
||||
jls L6 /* if sum > dividend, quotient was too large */
|
||||
L5: subql IMM (1), d0 /* adjust quotient */
|
||||
|
||||
L6: movel sp@+, d2
|
||||
rts
|
||||
|
||||
#else /* __mcf5200__ || __mcoldfire__ */
|
||||
|
||||
/* Coldfire implementation of non-restoring division algorithm from
|
||||
Hennessy & Patterson, Appendix A. */
|
||||
link a6,IMM (-12)
|
||||
moveml d2-d4,sp@
|
||||
movel a6@(8),d0
|
||||
movel a6@(12),d1
|
||||
clrl d2 | clear p
|
||||
moveq IMM (31),d4
|
||||
L1: addl d0,d0 | shift reg pair (p,a) one bit left
|
||||
addxl d2,d2
|
||||
movl d2,d3 | subtract b from p, store in tmp.
|
||||
subl d1,d3
|
||||
jcs L2 | if no carry,
|
||||
bset IMM (0),d0 | set the low order bit of a to 1,
|
||||
movl d3,d2 | and store tmp in p.
|
||||
L2: subql IMM (1),d4
|
||||
jcc L1
|
||||
moveml sp@,d2-d4 | restore data registers
|
||||
unlk a6 | and return
|
||||
rts
|
||||
#endif /* __mcf5200__ || __mcoldfire__ */
|
||||
|
113
arch/m68k/lib/umodsi3.S
Normal file
113
arch/m68k/lib/umodsi3.S
Normal file
@@ -0,0 +1,113 @@
|
||||
/* libgcc1 routines for 68000 w/o floating-point hardware.
|
||||
Copyright (C) 1994, 1996, 1997, 1998 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.
|
||||
|
||||
In addition to the permissions in the GNU General Public License, the
|
||||
Free Software Foundation gives you unlimited permission to link the
|
||||
compiled version of this file with other programs, and to distribute
|
||||
those programs without any restriction coming from the use of this
|
||||
file. (The General Public License restrictions do apply in other
|
||||
respects; for example, they cover modification of the file, and
|
||||
distribution when not linked into another program.)
|
||||
|
||||
This file 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 this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* As a special exception, if you link this library with files
|
||||
compiled with GCC to produce an executable, this does not cause
|
||||
the resulting executable to be covered by the GNU General Public License.
|
||||
This exception does not however invalidate any other reasons why
|
||||
the executable file might be covered by the GNU General Public License. */
|
||||
|
||||
/* Use this one for any 680x0; assumes no floating point hardware.
|
||||
The trailing " '" appearing on some lines is for ANSI preprocessors. Yuk.
|
||||
Some of this code comes from MINIX, via the folks at ericsson.
|
||||
D. V. Henkel-Wallace (gumby@cygnus.com) Fete Bastille, 1992
|
||||
*/
|
||||
|
||||
/* These are predefined by new versions of GNU cpp. */
|
||||
|
||||
#ifndef __USER_LABEL_PREFIX__
|
||||
#define __USER_LABEL_PREFIX__ _
|
||||
#endif
|
||||
|
||||
#ifndef __REGISTER_PREFIX__
|
||||
#define __REGISTER_PREFIX__
|
||||
#endif
|
||||
|
||||
#ifndef __IMMEDIATE_PREFIX__
|
||||
#define __IMMEDIATE_PREFIX__ #
|
||||
#endif
|
||||
|
||||
/* ANSI concatenation macros. */
|
||||
|
||||
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||
#define CONCAT2(a, b) a ## b
|
||||
|
||||
/* Use the right prefix for global labels. */
|
||||
|
||||
#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
|
||||
|
||||
/* Use the right prefix for registers. */
|
||||
|
||||
#define REG(x) CONCAT1 (__REGISTER_PREFIX__, x)
|
||||
|
||||
/* Use the right prefix for immediate values. */
|
||||
|
||||
#define IMM(x) CONCAT1 (__IMMEDIATE_PREFIX__, x)
|
||||
|
||||
#define d0 REG (d0)
|
||||
#define d1 REG (d1)
|
||||
#define d2 REG (d2)
|
||||
#define d3 REG (d3)
|
||||
#define d4 REG (d4)
|
||||
#define d5 REG (d5)
|
||||
#define d6 REG (d6)
|
||||
#define d7 REG (d7)
|
||||
#define a0 REG (a0)
|
||||
#define a1 REG (a1)
|
||||
#define a2 REG (a2)
|
||||
#define a3 REG (a3)
|
||||
#define a4 REG (a4)
|
||||
#define a5 REG (a5)
|
||||
#define a6 REG (a6)
|
||||
#define fp REG (fp)
|
||||
#define sp REG (sp)
|
||||
|
||||
.text
|
||||
.proc
|
||||
.globl SYM (__umodsi3)
|
||||
SYM (__umodsi3):
|
||||
movel sp@(8), d1 /* d1 = divisor */
|
||||
movel sp@(4), d0 /* d0 = dividend */
|
||||
movel d1, sp@-
|
||||
movel d0, sp@-
|
||||
jbsr SYM (__udivsi3)
|
||||
addql IMM (8), sp
|
||||
movel sp@(8), d1 /* d1 = divisor */
|
||||
#if !(defined(__mcf5200__) || defined(__mcoldfire__))
|
||||
movel d1, sp@-
|
||||
movel d0, sp@-
|
||||
jbsr SYM (__mulsi3) /* d0 = (a/b)*b */
|
||||
addql IMM (8), sp
|
||||
#else
|
||||
mulsl d1,d0
|
||||
#endif
|
||||
movel sp@(4), d1 /* d1 = dividend */
|
||||
subl d0, d1 /* d1 = a - (a/b)*b */
|
||||
movel d1, d0
|
||||
rts
|
||||
|
Reference in New Issue
Block a user