From dd68e9e8b4273bb7f91680e04f5cda6ec74a73a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Fri, 26 Oct 2007 17:07:23 +0000 Subject: [PATCH] More of the libc... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22738 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/libroot/posix/arch/m68k/Jamfile | 17 ++ src/system/libroot/posix/arch/m68k/setjmp.S | 20 +++ .../libroot/posix/arch/m68k/setjmp_internal.h | 26 +++ .../libroot/posix/arch/m68k/siglongjmp.S | 26 +++ .../libroot/posix/arch/m68k/sigsetjmp.S | 27 ++++ .../libroot/posix/glibc/arch/generic/strlen.c | 152 ++++++++++++++++++ .../libroot/posix/glibc/arch/m68k/Jamfile | 16 +- .../libroot/posix/glibc/arch/m68k/add_n.S | 76 +++++++++ .../libroot/posix/glibc/arch/m68k/addmul_1.S | 80 +++++++++ .../libroot/posix/glibc/arch/m68k/lshift.S | 147 +++++++++++++++++ .../libroot/posix/glibc/arch/m68k/mul_1.S | 87 ++++++++++ .../libroot/posix/glibc/arch/m68k/rshift.S | 146 +++++++++++++++++ .../libroot/posix/glibc/arch/m68k/sub_n.S | 76 +++++++++ .../libroot/posix/glibc/arch/m68k/submul_1.S | 80 +++++++++ .../posix/glibc/include/arch/m68k/sysdep.h | 2 +- src/system/libroot/posix/stdlib/strtod.c | 3 +- .../posix/string/arch/m68k/arch_string.S | 27 ++++ 17 files changed, 1000 insertions(+), 8 deletions(-) create mode 100644 src/system/libroot/posix/arch/m68k/Jamfile create mode 100644 src/system/libroot/posix/arch/m68k/setjmp.S create mode 100644 src/system/libroot/posix/arch/m68k/setjmp_internal.h create mode 100644 src/system/libroot/posix/arch/m68k/siglongjmp.S create mode 100644 src/system/libroot/posix/arch/m68k/sigsetjmp.S create mode 100644 src/system/libroot/posix/glibc/arch/generic/strlen.c create mode 100644 src/system/libroot/posix/glibc/arch/m68k/add_n.S create mode 100644 src/system/libroot/posix/glibc/arch/m68k/addmul_1.S create mode 100644 src/system/libroot/posix/glibc/arch/m68k/lshift.S create mode 100644 src/system/libroot/posix/glibc/arch/m68k/mul_1.S create mode 100644 src/system/libroot/posix/glibc/arch/m68k/rshift.S create mode 100644 src/system/libroot/posix/glibc/arch/m68k/sub_n.S create mode 100644 src/system/libroot/posix/glibc/arch/m68k/submul_1.S create mode 100644 src/system/libroot/posix/string/arch/m68k/arch_string.S diff --git a/src/system/libroot/posix/arch/m68k/Jamfile b/src/system/libroot/posix/arch/m68k/Jamfile new file mode 100644 index 0000000000..2d26ed8bbe --- /dev/null +++ b/src/system/libroot/posix/arch/m68k/Jamfile @@ -0,0 +1,17 @@ +SubDir HAIKU_TOP src system libroot posix arch m68k ; + +local genericSources = + setjmp_save_sigs.c + longjmp_return.c +; + +MergeObject posix_arch_$(TARGET_ARCH).o : + setjmp.S + sigsetjmp.S + siglongjmp.S + + $(genericSources) +; + +SEARCH on [ FGristFiles $(genericSources) ] + = [ FDirName $(SUBDIR) $(DOTDOT) generic ] ; diff --git a/src/system/libroot/posix/arch/m68k/setjmp.S b/src/system/libroot/posix/arch/m68k/setjmp.S new file mode 100644 index 0000000000..ae446a1f69 --- /dev/null +++ b/src/system/libroot/posix/arch/m68k/setjmp.S @@ -0,0 +1,20 @@ +/* + * Copyright 2005, Ingo Weinhold . All rights + * reserved. Distributed under the terms of the Haiku License. + */ + +#include "setjmp_internal.h" + +/* int setjmp(jmp_buf buffer) */ +FUNCTION(setjmp): + move.l (%a7)+,%a0 + move.l (%a7)+,%d0 + clr.l -(%a7) /* push 0 as 2nd arg */ + move.l %d0,-(%a7) + move.l %a0,-(%a7) + // call __sigsetjmp with saveMask = 0 + jmp __sigsetjmp + + +#pragma weak _setjmp=setjmp + diff --git a/src/system/libroot/posix/arch/m68k/setjmp_internal.h b/src/system/libroot/posix/arch/m68k/setjmp_internal.h new file mode 100644 index 0000000000..49b5c21818 --- /dev/null +++ b/src/system/libroot/posix/arch/m68k/setjmp_internal.h @@ -0,0 +1,26 @@ +/* + * Copyright 2005, Ingo Weinhold . All rights + * reserved. Distributed under the terms of the Haiku License. + */ +#ifndef SETJMP_INTERNAL_H +#define SETJMP_INTERNAL_H + +/* M68K function call ABI register use: + d0 - return value + d1 - volatile (return value?) + d2-d7 - local vars + a0 - return value + a1 - volatile (return value?) + a2-a6 - local vars + a6 - (stack frame ?) + a7 - stack pointer +*/ + +/* These are the fields of the __jmp_regs structure */ +#define JMP_REGS_D2 0 +#define JMP_REGS_PC (4*(6+6)) +#define JMP_REGS_CCR (4*(6+6)+4) + +#define FUNCTION(x) .global x; .type x,@function; x + +#endif /* SETJMP_INTERNAL_H */ diff --git a/src/system/libroot/posix/arch/m68k/siglongjmp.S b/src/system/libroot/posix/arch/m68k/siglongjmp.S new file mode 100644 index 0000000000..321c231977 --- /dev/null +++ b/src/system/libroot/posix/arch/m68k/siglongjmp.S @@ -0,0 +1,26 @@ +/* + * Copyright 2005, Ingo Weinhold . All rights + * reserved. Distributed under the terms of the Haiku License. + */ + +#include "setjmp_internal.h" + +/* int __siglongjmp(jmp_buf buffer, int value) */ +FUNCTION(siglongjmp): +FUNCTION(longjmp): +FUNCTION(_longjmp): + // a0: buffer, d0: saveMask + move.l (4,%a7),%a0 + move.l (8,%a7),%d0 + + // restore non-volatile general purpose registers + movem.l (%a0),%d2-%d7/%a2-%a7 + + // restore special registers (link, condition) + move.w (JMP_REGS_CCR,%a0),%d0 + move %d0,%ccr + move.l (JMP_REGS_PC,%a0),(%a7) + + jmp __longjmp_return + +#pragma weak longjmp=siglongjmp diff --git a/src/system/libroot/posix/arch/m68k/sigsetjmp.S b/src/system/libroot/posix/arch/m68k/sigsetjmp.S new file mode 100644 index 0000000000..7fd1f2464e --- /dev/null +++ b/src/system/libroot/posix/arch/m68k/sigsetjmp.S @@ -0,0 +1,27 @@ +/* + * Copyright 2005, Ingo Weinhold . All rights + * reserved. Distributed under the terms of the Haiku License. + */ + +#include "setjmp_internal.h" + +/* int sigsetjmp(jmp_buf buffer, int saveMask) */ +FUNCTION(__sigsetjmp): +FUNCTION(sigsetjmp): + // a0: buffer, d0: saveMask + move.l (4,%a7),%a0 + move.l (8,%a7),%d0 + + // store non-volatile general purpose registers +#warning M68K: do we want to save a7 there ?? + movem.l %d2-%d7/%a2-%a7,(%a0) + + // store special registers (link, condition) + clr.l %d0 + move %ccr,%d0 + move.w %d0,(JMP_REGS_CCR,%a0) + move.l (%a7),(JMP_REGS_PC,%a0) + +#warning M68K: check this. + + jmp __setjmp_save_sigs diff --git a/src/system/libroot/posix/glibc/arch/generic/strlen.c b/src/system/libroot/posix/glibc/arch/generic/strlen.c new file mode 100644 index 0000000000..3dca47f6c0 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/generic/strlen.c @@ -0,0 +1,152 @@ +/* Copyright (C) 1991, 1993, 1997, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Written by Torbjorn Granlund (tege@sics.se), + with help from Dan Sahlin (dan@sics.se); + commentary by Jim Blandy (jimb@ai.mit.edu). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +#undef strlen + +/* Return the length of the null-terminated string STR. Scan for + the null terminator quickly by testing four bytes at a time. */ +size_t +strlen (str) + const char *str; +{ + const char *char_ptr; + const unsigned long int *longword_ptr; + unsigned long int longword, magic_bits, himagic, lomagic; + + /* Handle the first few characters by reading one character at a time. + Do this until CHAR_PTR is aligned on a longword boundary. */ + for (char_ptr = str; ((unsigned long int) char_ptr + & (sizeof (longword) - 1)) != 0; + ++char_ptr) + if (*char_ptr == '\0') + return char_ptr - str; + + /* All these elucidatory comments refer to 4-byte longwords, + but the theory applies equally well to 8-byte longwords. */ + + longword_ptr = (unsigned long int *) char_ptr; + + /* Bits 31, 24, 16, and 8 of this number are zero. Call these bits + the "holes." Note that there is a hole just to the left of + each byte, with an extra at the end: + + bits: 01111110 11111110 11111110 11111111 + bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD + + The 1-bits make sure that carries propagate to the next 0-bit. + The 0-bits provide holes for carries to fall into. */ + magic_bits = 0x7efefeffL; + himagic = 0x80808080L; + lomagic = 0x01010101L; + if (sizeof (longword) > 4) + { + /* 64-bit version of the magic. */ + /* Do the shift in two steps to avoid a warning if long has 32 bits. */ + magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL; + himagic = ((himagic << 16) << 16) | himagic; + lomagic = ((lomagic << 16) << 16) | lomagic; + } + if (sizeof (longword) > 8) + abort (); + + /* Instead of the traditional loop which tests each character, + we will test a longword at a time. The tricky part is testing + if *any of the four* bytes in the longword in question are zero. */ + for (;;) + { + /* We tentatively exit the loop if adding MAGIC_BITS to + LONGWORD fails to change any of the hole bits of LONGWORD. + + 1) Is this safe? Will it catch all the zero bytes? + Suppose there is a byte with all zeros. Any carry bits + propagating from its left will fall into the hole at its + least significant bit and stop. Since there will be no + carry from its most significant bit, the LSB of the + byte to the left will be unchanged, and the zero will be + detected. + + 2) Is this worthwhile? Will it ignore everything except + zero bytes? Suppose every byte of LONGWORD has a bit set + somewhere. There will be a carry into bit 8. If bit 8 + is set, this will carry into bit 16. If bit 8 is clear, + one of bits 9-15 must be set, so there will be a carry + into bit 16. Similarly, there will be a carry into bit + 24. If one of bits 24-30 is set, there will be a carry + into bit 31, so all of the hole bits will be changed. + + The one misfire occurs when bits 24-30 are clear and bit + 31 is set; in this case, the hole at bit 31 is not + changed. If we had access to the processor carry flag, + we could close this loophole by putting the fourth hole + at bit 32! + + So it ignores everything except 128's, when they're aligned + properly. */ + + longword = *longword_ptr++; + + if ( +#if 0 + /* Add MAGIC_BITS to LONGWORD. */ + (((longword + magic_bits) + + /* Set those bits that were unchanged by the addition. */ + ^ ~longword) + + /* Look at only the hole bits. If any of the hole bits + are unchanged, most likely one of the bytes was a + zero. */ + & ~magic_bits) +#else + ((longword - lomagic) & himagic) +#endif + != 0) + { + /* Which of the bytes was the zero? If none of them were, it was + a misfire; continue the search. */ + + const char *cp = (const char *) (longword_ptr - 1); + + if (cp[0] == 0) + return cp - str; + if (cp[1] == 0) + return cp - str + 1; + if (cp[2] == 0) + return cp - str + 2; + if (cp[3] == 0) + return cp - str + 3; + if (sizeof (longword) > 4) + { + if (cp[4] == 0) + return cp - str + 4; + if (cp[5] == 0) + return cp - str + 5; + if (cp[6] == 0) + return cp - str + 6; + if (cp[7] == 0) + return cp - str + 7; + } + } + } +} diff --git a/src/system/libroot/posix/glibc/arch/m68k/Jamfile b/src/system/libroot/posix/glibc/arch/m68k/Jamfile index 0dfa579b4b..4632f560e2 100644 --- a/src/system/libroot/posix/glibc/arch/m68k/Jamfile +++ b/src/system/libroot/posix/glibc/arch/m68k/Jamfile @@ -20,6 +20,7 @@ if $(OPTIM) = -O0 { DEBUG = 0 ; SubDirCcFlags -D_GNU_SOURCE -D_IEEE_LIBM ; +SubDirAsFlags -DMOTOROLA_SYNTAX ; # Note: There is no *l() support yet. Our compiler says sizeof(long double) = 8, # while there are only 96 and 128 bit implementation in glibc. @@ -111,6 +112,9 @@ local genericSources = w_remainder.c w_remainderf.c # w_remainderl.c w_scalb.c w_scalbf.c # w_scalbl.c w_sinh.c w_sinhf.c # w_sinhl.c + # no asm for m68k in glibc + strlen.c + w_sqrt.c w_sqrtf.c # w_sqrtl.c ; MergeObject posix_gnu_arch_$(TARGET_ARCH)_generic.o : @@ -119,15 +123,15 @@ MergeObject posix_gnu_arch_$(TARGET_ARCH)_generic.o : MergeObject posix_gnu_arch_$(TARGET_ARCH)_other.o : -# add_n.S -# addmul_1.S + add_n.S + addmul_1.S feholdexcpt.c fraiseexcpt.c fesetenv.c fesetround.c ftestexcept.c # ldbl2mpn.c -# lshift.S rshift.S -# mul_1.S + lshift.S rshift.S + mul_1.S # strlen.S -# sub_n.S -# submul_1.S + sub_n.S + submul_1.S # # e_sqrt.c e_sqrtf.c # e_sqrtl.c # s_copysign.S s_copysignf.S # s_copysignl.S diff --git a/src/system/libroot/posix/glibc/arch/m68k/add_n.S b/src/system/libroot/posix/glibc/arch/m68k/add_n.S new file mode 100644 index 0000000000..a9558491e8 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/add_n.S @@ -0,0 +1,76 @@ +/* mc68020 __mpn_add_n -- Add two limb vectors of the same length > 0 and store + sum in a third limb vector. + +Copyright (C) 1992, 1994, 1996, 1998 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s1_ptr (sp + 8) + s2_ptr (sp + 16) + size (sp + 12) +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + + TEXT +ENTRY(__mpn_add_n) +/* Save used registers on the stack. */ + movel R(d2),MEM_PREDEC(sp) + movel R(a2),MEM_PREDEC(sp) + +/* Copy the arguments to registers. Better use movem? */ + movel MEM_DISP(sp,12),R(a2) + movel MEM_DISP(sp,16),R(a0) + movel MEM_DISP(sp,20),R(a1) + movel MEM_DISP(sp,24),R(d2) + + eorw #1,R(d2) + lsrl #1,R(d2) + bcc L(L1) + subql #1,R(d2) /* clears cy as side effect */ + +L(Loop:) + movel MEM_POSTINC(a0),R(d0) + movel MEM_POSTINC(a1),R(d1) + addxl R(d1),R(d0) + movel R(d0),MEM_POSTINC(a2) +L(L1:) movel MEM_POSTINC(a0),R(d0) + movel MEM_POSTINC(a1),R(d1) + addxl R(d1),R(d0) + movel R(d0),MEM_POSTINC(a2) + + dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */ + subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */ + subl #0x10000,R(d2) + bcs L(L2) + addl R(d0),R(d0) /* restore cy */ + bra L(Loop) + +L(L2:) + negl R(d0) + +/* Restore used registers from stack frame. */ + movel MEM_POSTINC(sp),R(a2) + movel MEM_POSTINC(sp),R(d2) + + rts +END(__mpn_add_n) diff --git a/src/system/libroot/posix/glibc/arch/m68k/addmul_1.S b/src/system/libroot/posix/glibc/arch/m68k/addmul_1.S new file mode 100644 index 0000000000..05d1d8a804 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/addmul_1.S @@ -0,0 +1,80 @@ +/* mc68020 __mpn_addmul_1 -- Multiply a limb vector with a limb and add + the result to a second limb vector. + +Copyright (C) 1992, 1994, 1996, 1998 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s1_ptr (sp + 8) + s1_size (sp + 12) + s2_limb (sp + 16) +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + + TEXT +ENTRY(__mpn_addmul_1) + +#define res_ptr a0 +#define s1_ptr a1 +#define s1_size d2 +#define s2_limb d4 + +/* Save used registers on the stack. */ + moveml R(d2)-R(d5),MEM_PREDEC(sp) + +/* Copy the arguments to registers. Better use movem? */ + movel MEM_DISP(sp,20),R(res_ptr) + movel MEM_DISP(sp,24),R(s1_ptr) + movel MEM_DISP(sp,28),R(s1_size) + movel MEM_DISP(sp,32),R(s2_limb) + + eorw #1,R(s1_size) + clrl R(d1) + clrl R(d5) + lsrl #1,R(s1_size) + bcc L(L1) + subql #1,R(s1_size) + subl R(d0),R(d0) /* (d0,cy) <= (0,0) */ + +L(Loop:) + movel MEM_POSTINC(s1_ptr),R(d3) + mulul R(s2_limb),R(d1):R(d3) + addxl R(d0),R(d3) + addxl R(d5),R(d1) + addl R(d3),MEM_POSTINC(res_ptr) +L(L1:) movel MEM_POSTINC(s1_ptr),R(d3) + mulul R(s2_limb),R(d0):R(d3) + addxl R(d1),R(d3) + addxl R(d5),R(d0) + addl R(d3),MEM_POSTINC(res_ptr) + + dbf R(s1_size),L(Loop) + addxl R(d5),R(d0) + subl #0x10000,R(s1_size) + bcc L(Loop) + +/* Restore used registers from stack frame. */ + moveml MEM_POSTINC(sp),R(d2)-R(d5) + + rts +END(__mpn_addmul_1) diff --git a/src/system/libroot/posix/glibc/arch/m68k/lshift.S b/src/system/libroot/posix/glibc/arch/m68k/lshift.S new file mode 100644 index 0000000000..434b344bd4 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/lshift.S @@ -0,0 +1,147 @@ +/* mc68020 __mpn_lshift -- Shift left a low-level natural-number integer. + +Copyright (C) 1996, 1998 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s_ptr (sp + 8) + s_size (sp + 16) + cnt (sp + 12) +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + +#define res_ptr a1 +#define s_ptr a0 +#define s_size d6 +#define cnt d4 + + TEXT +ENTRY(__mpn_lshift) + +/* Save used registers on the stack. */ + moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp) + +/* Copy the arguments to registers. */ + movel MEM_DISP(sp,28),R(res_ptr) + movel MEM_DISP(sp,32),R(s_ptr) + movel MEM_DISP(sp,36),R(s_size) + movel MEM_DISP(sp,40),R(cnt) + + moveql #1,R(d5) + cmpl R(d5),R(cnt) + bne L(Lnormal) + cmpl R(s_ptr),R(res_ptr) + bls L(Lspecial) /* jump if s_ptr >= res_ptr */ +#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) + lea MEM_INDX1(s_ptr,s_size,l,4),R(a2) +#else /* not mc68020 */ + movel R(s_size),R(d0) + asll #2,R(d0) + lea MEM_INDX(s_ptr,d0,l),R(a2) +#endif + cmpl R(res_ptr),R(a2) + bls L(Lspecial) /* jump if res_ptr >= s_ptr + s_size */ + +L(Lnormal:) + moveql #32,R(d5) + subl R(cnt),R(d5) + +#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) + lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr) + lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr) +#else /* not mc68000 */ + movel R(s_size),R(d0) + asll #2,R(d0) + addl R(s_size),R(s_ptr) + addl R(s_size),R(res_ptr) +#endif + movel MEM_PREDEC(s_ptr),R(d2) + movel R(d2),R(d0) + lsrl R(d5),R(d0) /* compute carry limb */ + + lsll R(cnt),R(d2) + movel R(d2),R(d1) + subql #1,R(s_size) + beq L(Lend) + lsrl #1,R(s_size) + bcs L(L1) + subql #1,R(s_size) + +L(Loop:) + movel MEM_PREDEC(s_ptr),R(d2) + movel R(d2),R(d3) + lsrl R(d5),R(d3) + orl R(d3),R(d1) + movel R(d1),MEM_PREDEC(res_ptr) + lsll R(cnt),R(d2) +L(L1:) + movel MEM_PREDEC(s_ptr),R(d1) + movel R(d1),R(d3) + lsrl R(d5),R(d3) + orl R(d3),R(d2) + movel R(d2),MEM_PREDEC(res_ptr) + lsll R(cnt),R(d1) + + dbf R(s_size),L(Loop) + subl #0x10000,R(s_size) + bcc L(Loop) + +L(Lend:) + movel R(d1),MEM_PREDEC(res_ptr) /* store least significant limb */ + +/* Restore used registers from stack frame. */ + moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) + rts + +/* We loop from least significant end of the arrays, which is only + permissible if the source and destination don't overlap, since the + function is documented to work for overlapping source and destination. */ + +L(Lspecial:) + clrl R(d0) /* initialize carry */ + eorw #1,R(s_size) + lsrl #1,R(s_size) + bcc L(LL1) + subql #1,R(s_size) + +L(LLoop:) + movel MEM_POSTINC(s_ptr),R(d2) + addxl R(d2),R(d2) + movel R(d2),MEM_POSTINC(res_ptr) +L(LL1:) + movel MEM_POSTINC(s_ptr),R(d2) + addxl R(d2),R(d2) + movel R(d2),MEM_POSTINC(res_ptr) + + dbf R(s_size),L(LLoop) + addxl R(d0),R(d0) /* save cy in lsb */ + subl #0x10000,R(s_size) + bcs L(LLend) + lsrl #1,R(d0) /* restore cy */ + bra L(LLoop) + +L(LLend:) +/* Restore used registers from stack frame. */ + moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) + rts +END(__mpn_lshift) diff --git a/src/system/libroot/posix/glibc/arch/m68k/mul_1.S b/src/system/libroot/posix/glibc/arch/m68k/mul_1.S new file mode 100644 index 0000000000..f3e450ed93 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/mul_1.S @@ -0,0 +1,87 @@ +/* mc68020 __mpn_mul_1 -- Multiply a limb vector with a limb and store + the result in a second limb vector. + +Copyright (C) 1992, 1994, 1996, 1998 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s1_ptr (sp + 8) + s1_size (sp + 12) + s2_limb (sp + 16) +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + + TEXT +ENTRY(__mpn_mul_1) + +#define res_ptr a0 +#define s1_ptr a1 +#define s1_size d2 +#define s2_limb d4 + +/* Save used registers on the stack. */ + moveml R(d2)-R(d4),MEM_PREDEC(sp) +#if 0 + movel R(d2),MEM_PREDEC(sp) + movel R(d3),MEM_PREDEC(sp) + movel R(d4),MEM_PREDEC(sp) +#endif + +/* Copy the arguments to registers. Better use movem? */ + movel MEM_DISP(sp,16),R(res_ptr) + movel MEM_DISP(sp,20),R(s1_ptr) + movel MEM_DISP(sp,24),R(s1_size) + movel MEM_DISP(sp,28),R(s2_limb) + + eorw #1,R(s1_size) + clrl R(d1) + lsrl #1,R(s1_size) + bcc L(L1) + subql #1,R(s1_size) + subl R(d0),R(d0) /* (d0,cy) <= (0,0) */ + +L(Loop:) + movel MEM_POSTINC(s1_ptr),R(d3) + mulul R(s2_limb),R(d1):R(d3) + addxl R(d0),R(d3) + movel R(d3),MEM_POSTINC(res_ptr) +L(L1:) movel MEM_POSTINC(s1_ptr),R(d3) + mulul R(s2_limb),R(d0):R(d3) + addxl R(d1),R(d3) + movel R(d3),MEM_POSTINC(res_ptr) + + dbf R(s1_size),L(Loop) + clrl R(d3) + addxl R(d3),R(d0) + subl #0x10000,R(s1_size) + bcc L(Loop) + +/* Restore used registers from stack frame. */ + moveml MEM_POSTINC(sp),R(d2)-R(d4) +#if 0 + movel MEM_POSTINC(sp),R(d4) + movel MEM_POSTINC(sp),R(d3) + movel MEM_POSTINC(sp),R(d2) +#endif + rts +END(__mpn_mul_1) diff --git a/src/system/libroot/posix/glibc/arch/m68k/rshift.S b/src/system/libroot/posix/glibc/arch/m68k/rshift.S new file mode 100644 index 0000000000..5e6abceb97 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/rshift.S @@ -0,0 +1,146 @@ +/* mc68020 __mpn_rshift -- Shift right a low-level natural-number integer. + +Copyright (C) 1996, 1998 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s_ptr (sp + 8) + s_size (sp + 16) + cnt (sp + 12) +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + +#define res_ptr a1 +#define s_ptr a0 +#define s_size d6 +#define cnt d4 + + TEXT +ENTRY(__mpn_rshift) +/* Save used registers on the stack. */ + moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp) + +/* Copy the arguments to registers. */ + movel MEM_DISP(sp,28),R(res_ptr) + movel MEM_DISP(sp,32),R(s_ptr) + movel MEM_DISP(sp,36),R(s_size) + movel MEM_DISP(sp,40),R(cnt) + + moveql #1,R(d5) + cmpl R(d5),R(cnt) + bne L(Lnormal) + cmpl R(res_ptr),R(s_ptr) + bls L(Lspecial) /* jump if res_ptr >= s_ptr */ +#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) + lea MEM_INDX1(res_ptr,s_size,l,4),R(a2) +#else /* not mc68020 */ + movel R(s_size),R(d0) + asll #2,R(d0) + lea MEM_INDX(res_ptr,d0,l),R(a2) +#endif + cmpl R(s_ptr),R(a2) + bls L(Lspecial) /* jump if s_ptr >= res_ptr + s_size */ + +L(Lnormal:) + moveql #32,R(d5) + subl R(cnt),R(d5) + movel MEM_POSTINC(s_ptr),R(d2) + movel R(d2),R(d0) + lsll R(d5),R(d0) /* compute carry limb */ + + lsrl R(cnt),R(d2) + movel R(d2),R(d1) + subql #1,R(s_size) + beq L(Lend) + lsrl #1,R(s_size) + bcs L(L1) + subql #1,R(s_size) + +L(Loop:) + movel MEM_POSTINC(s_ptr),R(d2) + movel R(d2),R(d3) + lsll R(d5),R(d3) + orl R(d3),R(d1) + movel R(d1),MEM_POSTINC(res_ptr) + lsrl R(cnt),R(d2) +L(L1:) + movel MEM_POSTINC(s_ptr),R(d1) + movel R(d1),R(d3) + lsll R(d5),R(d3) + orl R(d3),R(d2) + movel R(d2),MEM_POSTINC(res_ptr) + lsrl R(cnt),R(d1) + + dbf R(s_size),L(Loop) + subl #0x10000,R(s_size) + bcc L(Loop) + +L(Lend:) + movel R(d1),MEM(res_ptr) /* store most significant limb */ + +/* Restore used registers from stack frame. */ + moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) + rts + +/* We loop from most significant end of the arrays, which is only + permissible if the source and destination don't overlap, since the + function is documented to work for overlapping source and destination. */ + +L(Lspecial:) +#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) + lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr) + lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr) +#else /* not mc68000 */ + movel R(s_size),R(d0) + asll #2,R(d0) + addl R(s_size),R(s_ptr) + addl R(s_size),R(res_ptr) +#endif + + clrl R(d0) /* initialize carry */ + eorw #1,R(s_size) + lsrl #1,R(s_size) + bcc L(LL1) + subql #1,R(s_size) + +L(LLoop:) + movel MEM_PREDEC(s_ptr),R(d2) + roxrl #1,R(d2) + movel R(d2),MEM_PREDEC(res_ptr) +L(LL1:) + movel MEM_PREDEC(s_ptr),R(d2) + roxrl #1,R(d2) + movel R(d2),MEM_PREDEC(res_ptr) + + dbf R(s_size),L(LLoop) + roxrl #1,R(d0) /* save cy in msb */ + subl #0x10000,R(s_size) + bcs L(LLend) + addl R(d0),R(d0) /* restore cy */ + bra L(LLoop) + +L(LLend:) +/* Restore used registers from stack frame. */ + moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2) + rts +END(__mpn_rshift) diff --git a/src/system/libroot/posix/glibc/arch/m68k/sub_n.S b/src/system/libroot/posix/glibc/arch/m68k/sub_n.S new file mode 100644 index 0000000000..5833dd2719 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/sub_n.S @@ -0,0 +1,76 @@ +/* mc68020 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and + store difference in a third limb vector. + +Copyright (C) 1992, 1994, 1996, 1998 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s1_ptr (sp + 8) + s2_ptr (sp + 16) + size (sp + 12) +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + + TEXT +ENTRY(__mpn_sub_n) +/* Save used registers on the stack. */ + movel R(d2),MEM_PREDEC(sp) + movel R(a2),MEM_PREDEC(sp) + +/* Copy the arguments to registers. Better use movem? */ + movel MEM_DISP(sp,12),R(a2) + movel MEM_DISP(sp,16),R(a0) + movel MEM_DISP(sp,20),R(a1) + movel MEM_DISP(sp,24),R(d2) + + eorw #1,R(d2) + lsrl #1,R(d2) + bcc L(L1) + subql #1,R(d2) /* clears cy as side effect */ + +L(Loop:) + movel MEM_POSTINC(a0),R(d0) + movel MEM_POSTINC(a1),R(d1) + subxl R(d1),R(d0) + movel R(d0),MEM_POSTINC(a2) +L(L1:) movel MEM_POSTINC(a0),R(d0) + movel MEM_POSTINC(a1),R(d1) + subxl R(d1),R(d0) + movel R(d0),MEM_POSTINC(a2) + + dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */ + subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */ + subl #0x10000,R(d2) + bcs L(L2) + addl R(d0),R(d0) /* restore cy */ + bra L(Loop) + +L(L2:) + negl R(d0) + +/* Restore used registers from stack frame. */ + movel MEM_POSTINC(sp),R(a2) + movel MEM_POSTINC(sp),R(d2) + + rts +END(__mpn_sub_n) diff --git a/src/system/libroot/posix/glibc/arch/m68k/submul_1.S b/src/system/libroot/posix/glibc/arch/m68k/submul_1.S new file mode 100644 index 0000000000..7522046b43 --- /dev/null +++ b/src/system/libroot/posix/glibc/arch/m68k/submul_1.S @@ -0,0 +1,80 @@ +/* mc68020 __mpn_submul_1 -- Multiply a limb vector with a limb and subtract + the result from a second limb vector. + +Copyright (C) 1992, 1994, 1996, 1998 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Lesser General Public +License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +/* + INPUT PARAMETERS + res_ptr (sp + 4) + s1_ptr (sp + 8) + s1_size (sp + 12) + s2_limb (sp + 16) +*/ + +#include "sysdep.h" +#include "asm-syntax.h" + + TEXT +ENTRY(__mpn_submul_1) + +#define res_ptr a0 +#define s1_ptr a1 +#define s1_size d2 +#define s2_limb d4 + +/* Save used registers on the stack. */ + moveml R(d2)-R(d5),MEM_PREDEC(sp) + +/* Copy the arguments to registers. Better use movem? */ + movel MEM_DISP(sp,20),R(res_ptr) + movel MEM_DISP(sp,24),R(s1_ptr) + movel MEM_DISP(sp,28),R(s1_size) + movel MEM_DISP(sp,32),R(s2_limb) + + eorw #1,R(s1_size) + clrl R(d1) + clrl R(d5) + lsrl #1,R(s1_size) + bcc L(L1) + subql #1,R(s1_size) + subl R(d0),R(d0) /* (d0,cy) <= (0,0) */ + +L(Loop:) + movel MEM_POSTINC(s1_ptr),R(d3) + mulul R(s2_limb),R(d1):R(d3) + addxl R(d0),R(d3) + addxl R(d5),R(d1) + subl R(d3),MEM_POSTINC(res_ptr) +L(L1:) movel MEM_POSTINC(s1_ptr),R(d3) + mulul R(s2_limb),R(d0):R(d3) + addxl R(d1),R(d3) + addxl R(d5),R(d0) + subl R(d3),MEM_POSTINC(res_ptr) + + dbf R(s1_size),L(Loop) + addxl R(d5),R(d0) + subl #0x10000,R(s1_size) + bcc L(Loop) + +/* Restore used registers from stack frame. */ + moveml MEM_POSTINC(sp),R(d2)-R(d5) + + rts +END(__mpn_submul_1) diff --git a/src/system/libroot/posix/glibc/include/arch/m68k/sysdep.h b/src/system/libroot/posix/glibc/include/arch/m68k/sysdep.h index 554b92d334..cb8a1cd66c 100644 --- a/src/system/libroot/posix/glibc/include/arch/m68k/sysdep.h +++ b/src/system/libroot/posix/glibc/include/arch/m68k/sysdep.h @@ -17,7 +17,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include +#include_next #ifdef __ASSEMBLER__ diff --git a/src/system/libroot/posix/stdlib/strtod.c b/src/system/libroot/posix/stdlib/strtod.c index dcf51170eb..6040732092 100644 --- a/src/system/libroot/posix/stdlib/strtod.c +++ b/src/system/libroot/posix/stdlib/strtod.c @@ -114,7 +114,8 @@ */ #if defined(__i386__) || defined(__ia64__) || defined(__alpha__) || \ - defined(__sparc64__) || defined(__powerpc__) || defined(__POWERPC__) + defined(__sparc64__) || defined(__powerpc__) || defined(__POWERPC__) || \ + defined(__m68k__) || defined(__M68K__) # include # if BYTE_ORDER == BIG_ENDIAN # define IEEE_BIG_ENDIAN diff --git a/src/system/libroot/posix/string/arch/m68k/arch_string.S b/src/system/libroot/posix/string/arch/m68k/arch_string.S new file mode 100644 index 0000000000..7c04a42bc3 --- /dev/null +++ b/src/system/libroot/posix/string/arch/m68k/arch_string.S @@ -0,0 +1,27 @@ +/* +** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Distributed under the terms of the NewOS License. +*/ + +#warning M68K: optimize memcpy +#if 0 +#define FUNCTION(x) .global x; .type x,@function; x + +/* that should be enough for now */ + +.align 4 +FUNCTION(memcpy): +/* void *memcpy(void *dest, const void *src, size_t count) */ + move.l (4,%a7),%a1 + move.l (8,%a7),%a0 + move.l (12,%a7),%d0 + addi.l #-1,%d0 + blt _memcpy_out +_memcpy_loop: + move.b (%a0)+,(%a1)+ + dbf %d0,_memcpy_loop +_memcpy_out: + move.l (4,%a7),%a0 + move.l %a0,%d0 + rts +#endif