Add library code for 32-bit multiplication, division, and modulo operations on 68000 and 68010 --- Makefile | 3 ++ divsi3.S | 68 +++++++++++++++++++++++++++++++++++++++++++++++ memcpy.c | 16 +++++++++++ memset.c | 6 ++++ modsi3.S | 60 ++++++++++++++++++++++++++++++++++++++++++ muldi3.c | 39 +++++++++++++++++++++++++++ mulsi3.S | 57 ++++++++++++++++++++++++++++++++++++++++ udivsi3.S | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ umodsi3.S | 60 ++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 397 insertions(+) --- linux-m68k-2.6.8.1+uc0/arch/m68k/lib/Makefile 2004-04-27 20:46:54.000000000 +0200 +++ uClinux-amiga-2.6.8.1/arch/m68k/lib/Makefile 2004-05-03 21:45:14.000000000 +0200 @@ -6,3 +6,6 @@ EXTRA_AFLAGS := -traditional lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ checksum.o memcmp.o memcpy.o memset.o semaphore.o + +lib-$(CONFIG_M68000) += divsi3.o modsi3.o mulsi3.o udivsi3.o umodsi3.o +lib-$(CONFIG_M68010) += divsi3.o modsi3.o mulsi3.o udivsi3.o umodsi3.o --- linux-m68k-2.6.8.1+uc0/arch/m68k/lib/divsi3.S 1970-01-01 01:00:00.000000000 +0100 +++ uClinux-amiga-2.6.8.1/arch/m68k/lib/divsi3.S 2004-05-03 21:45:14.000000000 +0200 @@ -0,0 +1,68 @@ +/* divsi3 based on gcc-2.7.2.2/config/m68k/lb1sf68.asm */ +/* libgcc1 routines for 68000 w/o floating-point hardware. */ +/* Copyright (C) 1994 Free Software Foundation, Inc. + +This file 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 +*/ + +#include + + + .text + .proc +ENTRY(__divsi3) + movel %d2, %sp@- + + moveb #1, %d2 /* sign of result stored in d2 (=1 or =-1) */ + movel %sp@(12), %d1 /* d1 = divisor */ + jpl L1 + negl %d1 + negb %d2 /* change sign because divisor <0 */ +L1: movel %sp@(8), %d0 /* d0 = dividend */ + jpl L2 + negl %d0 + negb %d2 + +L2: movel %d1, %sp@- + movel %d0, %sp@- + jbsr __udivsi3 /* divide abs(dividend) by abs(divisor) */ + addql #8, %sp + + tstb %d2 + jpl L3 + negl %d0 + +L3: movel %sp@+, %d2 + rts --- linux-m68k-2.6.8.1+uc0/arch/m68k/lib/memcpy.c 1996-09-25 09:47:40.000000000 +0200 +++ uClinux-amiga-2.6.8.1/arch/m68k/lib/memcpy.c 2004-05-03 21:45:14.000000000 +0200 @@ -1,3 +1,4 @@ +#include #include void * memcpy(void * to, const void * from, size_t n) @@ -7,6 +8,15 @@ void * memcpy(void * to, const void * fr if (!n) return xto; +#if defined(CONFIG_M68000) || defined(CONFIG_M68010) + if (((long)from & 1) != ((long)to & 1)) { + char *cto = to; + const char *cfrom = from; + while (n-- > 0) + *cto++ = *cfrom++; + return xto; + } +#endif /* M68000 || M68010 */ if ((long) to & 1) { char *cto = to; @@ -35,7 +45,13 @@ void * memcpy(void * to, const void * fr "andw #7,%3\n\t" "lsrl #3,%2\n\t" "negw %3\n\t" +#if defined(CONFIG_M68000) || defined(CONFIG_M68010) + "addw %3,%3\n\t" + "jmp %%pc@(1f,%3:w)\n\t" +#else /* 68020 or higher */ "jmp %%pc@(1f,%3:w:2)\n\t" +#endif /* 68020 or higher */ + "4:\t" "movel %0@+,%1@+\n\t" "movel %0@+,%1@+\n\t" --- linux-m68k-2.6.8.1+uc0/arch/m68k/lib/memset.c 1996-09-25 09:47:40.000000000 +0200 +++ uClinux-amiga-2.6.8.1/arch/m68k/lib/memset.c 2004-05-03 21:45:14.000000000 +0200 @@ -1,3 +1,4 @@ +#include #include void * memset(void * s, int c, size_t count) @@ -33,7 +34,12 @@ void * memset(void * s, int c, size_t co "andw #7,%2\n\t" "lsrl #3,%1\n\t" "negw %2\n\t" +#if defined(CONFIG_M68000) || defined(CONFIG_M68010) + "addw %2,%2\n\t" + "jmp %%pc@(2f,%2:w)\n\t" +#else /* 68020 or higher */ "jmp %%pc@(2f,%2:w:2)\n\t" +#endif /* 68020 or higher */ "1:\t" "movel %3,%0@+\n\t" "movel %3,%0@+\n\t" --- linux-m68k-2.6.8.1+uc0/arch/m68k/lib/modsi3.S 1970-01-01 01:00:00.000000000 +0100 +++ uClinux-amiga-2.6.8.1/arch/m68k/lib/modsi3.S 2004-05-03 21:45:14.000000000 +0200 @@ -0,0 +1,60 @@ +/* modsi3 based on gcc-2.7.2.2/config/m68k/lb1sf68.asm */ +/* libgcc1 routines for 68000 w/o floating-point hardware. */ +/* Copyright (C) 1994 Free Software Foundation, Inc. + +This file 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 +*/ + +#include + + + .text + .proc +ENTRY(__modsi3) + movel %sp@(8), %d1 /* d1 = divisor */ + movel %sp@(4), %d0 /* d0 = dividend */ + movel %d1, %sp@- + movel %d0, %sp@- + jbsr __divsi3 + addql #8, %sp + movel %sp@(8), %d1 /* d1 = divisor */ + movel %d1, %sp@- + movel %d0, %sp@- + jbsr __mulsi3 /* d0 = (a/b)*b */ + addql #8, %sp + movel %sp@(4), %d1 /* d1 = dividend */ + subl %d0, %d1 /* d1 = a - (a/b)*b */ + movel %d1, %d0 + rts --- linux-m68k-2.6.8.1+uc0/arch/m68k/lib/muldi3.c 2004-05-24 11:13:22.000000000 +0200 +++ uClinux-amiga-2.6.8.1/arch/m68k/lib/muldi3.c 2004-06-26 17:17:37.000000000 +0200 @@ -21,6 +21,43 @@ Boston, MA 02111-1307, USA. */ #define BITS_PER_UNIT 8 +#include + +#if defined(CONFIG_M68000) || defined(CONFIG_M68010) + +#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) + +#else /* 68020 or higher */ + #define umul_ppmm(w1, w0, u, v) \ __asm__ ("mulu%.l %3,%1:%0" \ : "=d" ((USItype)(w0)), \ @@ -28,6 +63,8 @@ Boston, MA 02111-1307, USA. */ : "%0" ((USItype)(u)), \ "dmi" ((USItype)(v))) +#endif /* 68020 or higher */ + #define __umulsidi3(u, v) \ ({DIunion __w; \ umul_ppmm (__w.s.high, __w.s.low, u, v); \ --- linux-m68k-2.6.8.1+uc0/arch/m68k/lib/mulsi3.S 1970-01-01 01:00:00.000000000 +0100 +++ uClinux-amiga-2.6.8.1/arch/m68k/lib/mulsi3.S 2004-05-03 21:45:14.000000000 +0200 @@ -0,0 +1,57 @@ +/* mulsi3 based on gcc-2.7.2.2/config/m68k/lb1sf68.asm */ +/* libgcc1 routines for 68000 w/o floating-point hardware. */ +/* Copyright (C) 1994 Free Software Foundation, Inc. + +This file 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 +*/ + +#include + + + .text + .proc +ENTRY(__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 */ + addw %d1, %d0 + swap %d0 + clrw %d0 + movew %sp@(6), %d1 /* x1 -> d1 */ + muluw %sp@(10), %d1 /* x1*y1 */ + addl %d1, %d0 + + rts --- linux-m68k-2.6.8.1+uc0/arch/m68k/lib/udivsi3.S 1970-01-01 01:00:00.000000000 +0100 +++ uClinux-amiga-2.6.8.1/arch/m68k/lib/udivsi3.S 2004-05-03 21:45:14.000000000 +0200 @@ -0,0 +1,88 @@ +/* udivsi3 based on gcc-2.7.2.2/config/m68k/lb1sf68.asm */ +/* libgcc1 routines for 68000 w/o floating-point hardware. */ +/* Copyright (C) 1994 Free Software Foundation, Inc. + +This file 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 +*/ + +#include + + + .text + .proc +ENTRY(__udivsi3) + movel %d2, %sp@- + movel %sp@(12), %d1 /* d1 = divisor */ + movel %sp@(8), %d0 /* d0 = dividend */ + + cmpl #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 #1, %d1 /* shift divisor */ + lsrl #1, %d0 /* shift dividend */ + cmpl #0x10000, %d1 /* still divisor >= 2 ^ 16 ? */ + jcc L4 + divu %d1, %d0 /* now we have 16 bit divisor */ + andl #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 */ + btst #0, %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 #1, %d0 /* adjust quotient */ + +L6: movel %sp@+, %d2 + rts --- linux-m68k-2.6.8.1+uc0/arch/m68k/lib/umodsi3.S 1970-01-01 01:00:00.000000000 +0100 +++ uClinux-amiga-2.6.8.1/arch/m68k/lib/umodsi3.S 2004-05-03 21:45:14.000000000 +0200 @@ -0,0 +1,60 @@ +/* umodsi3 based on gcc-2.7.2.2/config/m68k/lb1sf68.asm */ +/* libgcc1 routines for 68000 w/o floating-point hardware. */ +/* Copyright (C) 1994 Free Software Foundation, Inc. + +This file 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 +*/ + +#include + + + .text + .proc +ENTRY(__umodsi3) + movel %sp@(8), %d1 /* d1 = divisor */ + movel %sp@(4), %d0 /* d0 = dividend */ + movel %d1, %sp@- + movel %d0, %sp@- + jbsr __udivsi3 + addql #8, %sp + movel %sp@(8), %d1 /* d1 = divisor */ + movel %d1, %sp@- + movel %d0, %sp@- + jbsr __mulsi3 /* d0 = (a/b)*b */ + addql #8, %sp + movel %sp@(4), %d1 /* d1 = dividend */ + subl %d0, %d1 /* d1 = a - (a/b)*b */ + movel %d1, %d0 + rts