diff options
Diffstat (limited to 'sysdeps/m68k')
244 files changed, 8157 insertions, 0 deletions
diff --git a/sysdeps/m68k/Implies b/sysdeps/m68k/Implies new file mode 100644 index 0000000..5c778d4 --- /dev/null +++ b/sysdeps/m68k/Implies @@ -0,0 +1,5 @@ +wordsize-32 +# 68k uses IEEE 754 floating point. +ieee754/ldbl-96 +ieee754/dbl-64 +ieee754/flt-32 diff --git a/sysdeps/m68k/Makefile b/sysdeps/m68k/Makefile new file mode 100644 index 0000000..fab6bd5 --- /dev/null +++ b/sysdeps/m68k/Makefile @@ -0,0 +1,38 @@ +# Copyright (C) 1993, 1994, 1996, 1997, 2003 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# 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. + +# The mpn functions need this. All existing 68k ports use MIT syntax. If +# a new port wants to use Motorola or Sony syntax, it can redefine this +# variable. +ifndef m68k-syntax-flag +m68k-syntax-flag = -DMIT_SYNTAX +endif + +asm-CPPFLAGS += $(m68k-syntax-flag) + +pic-ccflag = -fpic + +# Make sure setjmp.c is compiled with a frame pointer +CFLAGS-setjmp.c := -fno-omit-frame-pointer + +# The 68k `long double' is a distinct type we support. +long-double-fcts = yes + +ifeq ($(subdir),elf) +CFLAGS-rtld.c += -Wno-uninitialized -Wno-unused +endif diff --git a/sysdeps/m68k/Versions b/sysdeps/m68k/Versions new file mode 100644 index 0000000..2b020f8 --- /dev/null +++ b/sysdeps/m68k/Versions @@ -0,0 +1,6 @@ +libc { + GLIBC_2.0 { + # Functions from libgcc. + __divdi3; __moddi3; __udivdi3; __umoddi3; + } +} diff --git a/sysdeps/m68k/__longjmp.c b/sysdeps/m68k/__longjmp.c new file mode 100644 index 0000000..89ff5ba --- /dev/null +++ b/sysdeps/m68k/__longjmp.c @@ -0,0 +1,55 @@ +/* Copyright (C) 1991, 92, 93, 94, 95, 97 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <setjmp.h> +#include <stdlib.h> + +/* Jump to the position specified by ENV, causing the + setjmp call there to return VAL, or 1 if VAL is 0. */ +void +__longjmp (__jmp_buf env, int val) +{ + /* This restores the FP and SP that setjmp's caller had, + and puts the return address into A0 and VAL into D0. */ + +#if defined(__HAVE_68881__) || defined(__HAVE_FPU__) + /* Restore the floating-point registers. */ + asm volatile("fmovem%.x %0, %/fp0-%/fp7" : + /* No outputs. */ : "g" (env[0].__fpregs[0])); +#endif + + /* Put VAL in D0. */ + asm volatile("move%.l %0, %/d0" : /* No outputs. */ : + "g" (val == 0 ? 1 : val) : "d0"); + + asm volatile(/* Restore the data and address registers. */ + "movem%.l %0, %/d1-%/d7/%/a0-%/a7\n" + /* Return to setjmp's caller. */ +#ifdef __motorola__ + "jmp (%/a0)" +#else + "jmp %/a0@" +#endif + : /* No outputs. */ : "g" (env[0].__dregs[0]) + /* We don't bother with the clobbers, + because this code always jumps out anyway. */ + ); + + /* Avoid `volatile function does return' warnings. */ + for (;;); +} diff --git a/sysdeps/m68k/abort-instr.h b/sysdeps/m68k/abort-instr.h new file mode 100644 index 0000000..b43c9ef --- /dev/null +++ b/sysdeps/m68k/abort-instr.h @@ -0,0 +1,2 @@ +/* An instruction which should crash any program is `illegal'. */ +#define ABORT_INSTRUCTION asm ("illegal") diff --git a/sysdeps/m68k/add_n.S b/sysdeps/m68k/add_n.S new file mode 100644 index 0000000..a955849 --- /dev/null +++ b/sysdeps/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/sysdeps/m68k/asm-syntax.h b/sysdeps/m68k/asm-syntax.h new file mode 100644 index 0000000..8e2a4ca --- /dev/null +++ b/sysdeps/m68k/asm-syntax.h @@ -0,0 +1,109 @@ +/* Definitions for 68k syntax variations. + Copyright (C) 1992, 1994, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. Its master source is NOT part of + the C library, however. The master source lives in the GNU MP Library. + + 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. */ + +#ifdef HAVE_ELF + +/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */ +#define ALIGNARG(log2) 1<<log2 +/* For ELF we need the `.type' directive to make shared libs work right. */ +#define PROLOG(name) .type name,@function +#define EPILOG(name) .size name,.-name +/* For ELF we need to prefix register names and local labels. */ +#ifdef __STDC__ +#define R_(r) %##r +#define R(r) R_(r) +#define L(label) .##label +#else +#define R(r) %/**/r +#define L(label) ./**/label +#endif + +#else + +#define ALIGNARG(log2) log2 +#define PROLOG(name) /* Nothing. */ +#define EPILOG(name) /* Nothing. */ +#define R(r) r +#define L(label) label + +#endif + +#ifdef MIT_SYNTAX +#define MEM(base)R(base)@ +#define MEM_DISP(base,displacement)R(base)@(displacement) +#define MEM_INDX(base,idx,size_suffix)R(base)@(R(idx):size_suffix) +#define MEM_INDX1(base,idx,size_suffix,scale)R(base)@(R(idx):size_suffix:scale) +#define MEM_PREDEC(memory_base)R(memory_base)@- +#define MEM_POSTINC(memory_base)R(memory_base)@+ +#define TEXT .text +#define ALIGN .even +#define GLOBL .globl +/* Use variable sized opcodes. */ +#define bcc jcc +#define bcs jcs +#define bls jls +#define beq jeq +#define bne jne +#define bra jra +#endif + +#ifdef MOTOROLA_SYNTAX +#define MEM(base)(R(base)) +#define MEM_DISP(base,displacement)(displacement,R(base)) +#define MEM_PREDEC(memory_base)-(R(memory_base)) +#define MEM_POSTINC(memory_base)(R(memory_base))+ +#ifdef __STDC__ +#define MEM_INDX_(base,idx,size_suffix)(R(base),R(idx##.##size_suffix)) +#define MEM_INDX(base,idx,size_suffix)MEM_INDX_(base,idx,size_suffix) +#define MEM_INDX1_(base,idx,size_suffix,scale)(R(base),R(idx##.##size_suffix*scale)) +#define MEM_INDX1(base,idx,size_suffix,scale)MEM_INDX1_(base,idx,size_suffix,scale) +#else +#define MEM_INDX(base,idx,size_suffix)(R(base),R(idx).size_suffix) +#define MEM_INDX1(base,idx,size_suffix,scale)(R(base),R(idx).size_suffix*scale) +#endif +#define TEXT .text +#define ALIGN .align ALIGNARG(2) +#define GLOBL .globl +#define bcc jbcc +#define bcs jbcs +#define bls jbls +#define beq jbeq +#define bne jbne +#define bra jbra +#define movel move.l +#define moveml movem.l +#define moveql moveq.l +#define cmpl cmp.l +#define orl or.l +#define clrl clr.l +#define eorw eor.w +#define lsrl lsr.l +#define lsll lsl.l +#define roxrl roxr.l +#define roxll roxl.l +#define addl add.l +#define addxl addx.l +#define addql addq.l +#define subl sub.l +#define subxl subx.l +#define subql subq.l +#define negl neg.l +#define mulul mulu.l +#endif diff --git a/sysdeps/m68k/bits/byteswap.h b/sysdeps/m68k/bits/byteswap.h new file mode 100644 index 0000000..549d445 --- /dev/null +++ b/sysdeps/m68k/bits/byteswap.h @@ -0,0 +1,67 @@ +/* Macros to swap the order of bytes in integer values. m68k version. + Copyright (C) 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +#if !defined _BYTESWAP_H && !defined _NETINET_IN_H +# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead." +#endif + +#ifndef _BITS_BYTESWAP_H +#define _BITS_BYTESWAP_H 1 + +/* Swap bytes in 16 bit value. We don't provide an assembler version + because GCC is smart enough to generate optimal assembler output, and + this allows for better cse. */ +#define __bswap_16(x) \ + ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)) + +/* Swap bytes in 32 bit value. */ +#define __bswap_constant_32(x) \ + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) + +#if defined __GNUC__ && __GNUC__ >= 2 +# define __bswap_32(x) \ + __extension__ \ + ({ unsigned int __bswap_32_v; \ + if (__builtin_constant_p (x)) \ + __bswap_32_v = __bswap_constant_32 (x); \ + else \ + __asm__ __volatile__ ("ror%.w %#8, %0;" \ + "swap %0;" \ + "ror%.w %#8, %0" \ + : "=d" (__bswap_32_v) \ + : "0" ((unsigned int) (x))); \ + __bswap_32_v; }) +#else +# define __bswap_32(x) __bswap_constant_32 (x) +#endif + +#if defined __GNUC__ && __GNUC__ >= 2 +/* Swap bytes in 64 bit value. */ +# define __bswap_64(x) \ + __extension__ \ + ({ union { unsigned long long int __ll; \ + unsigned long int __l[2]; } __bswap_64_v, __bswap_64_r; \ + __bswap_64_v.__ll = (x); \ + __bswap_64_r.__l[0] = __bswap_32 (__bswap_64_v.__l[1]); \ + __bswap_64_r.__l[1] = __bswap_32 (__bswap_64_v.__l[0]); \ + __bswap_64_r.__ll; }) +#endif + +#endif /* _BITS_BYTESWAP_H */ diff --git a/sysdeps/m68k/bits/endian.h b/sysdeps/m68k/bits/endian.h new file mode 100644 index 0000000..bf4ecb6 --- /dev/null +++ b/sysdeps/m68k/bits/endian.h @@ -0,0 +1,7 @@ +/* m68k is big-endian. */ + +#ifndef _ENDIAN_H +# error "Never use <bits/endian.h> directly; include <endian.h> instead." +#endif + +#define __BYTE_ORDER __BIG_ENDIAN diff --git a/sysdeps/m68k/bits/huge_vall.h b/sysdeps/m68k/bits/huge_vall.h new file mode 100644 index 0000000..8b9630c --- /dev/null +++ b/sysdeps/m68k/bits/huge_vall.h @@ -0,0 +1,43 @@ +/* `HUGE_VALL' constant for m68k (where it is infinity). + Used by <stdlib.h> and <math.h> functions for overflow. + Copyright (C) 1992, 1995, 1996, 1997, 1999, 2000, 2004 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +#ifndef _MATH_H +# error "Never use <bits/huge_val.h> directly; include <math.h> instead." +#endif + +#if __GNUC_PREREQ(3,3) +# define HUGE_VALL (__builtin_huge_vall ()) +#elif __GNUC_PREREQ(2,96) +# define HUGE_VALL (__extension__ 0x1.0p32767L) +#elif defined__GNUC__ + +# define HUGE_VALL \ + (__extension__ \ + ((union { unsigned long __l[3]; long double __ld; }) \ + { __l: { 0x7fff0000UL, 0x80000000UL, 0UL } }).__ld) + +#else /* not GCC */ + +static union { unsigned char __c[12]; long double __ld; } __huge_vall = + { { 0x7f, 0xff, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0 } }; +# define HUGE_VALL (__huge_vall.__ld) + +#endif /* GCC 2.95. */ diff --git a/sysdeps/m68k/bits/setjmp.h b/sysdeps/m68k/bits/setjmp.h new file mode 100644 index 0000000..2c2b3ee --- /dev/null +++ b/sysdeps/m68k/bits/setjmp.h @@ -0,0 +1,46 @@ +/* Copyright (C) 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +/* Define the machine-dependent type `jmp_buf'. m68k version. */ + +#ifndef _SETJMP_H +# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead." +#endif + +typedef struct + { + /* There are eight 4-byte data registers, but D0 is not saved. */ + long int __dregs[7]; + + /* There are six 4-byte address registers, plus the FP and SP. */ + int *__aregs[6]; + int *__fp; + int *__sp; + +#if defined __HAVE_68881__ || defined __HAVE_FPU__ + /* There are eight floating point registers which + are saved in IEEE 96-bit extended format. */ + char __fpregs[8 * (96 / 8)]; +#endif + + } __jmp_buf[1]; + +/* Test if longjmp to JMPBUF would unwind the frame + containing a local variable at ADDRESS. */ +#define _JMPBUF_UNWINDS(jmpbuf, address) \ + ((void *) (address) < (void *) (jmpbuf)->__sp) diff --git a/sysdeps/m68k/bsd-_setjmp.c b/sysdeps/m68k/bsd-_setjmp.c new file mode 100644 index 0000000..a6b404a --- /dev/null +++ b/sysdeps/m68k/bsd-_setjmp.c @@ -0,0 +1,22 @@ +/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'. m68k version. + Copyright (C) 1994, 1997, 2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +#define BSD__SETJMP +#include <sysdeps/m68k/setjmp.c> +libc_hidden_def (_setjmp) diff --git a/sysdeps/m68k/bsd-setjmp.c b/sysdeps/m68k/bsd-setjmp.c new file mode 100644 index 0000000..59b5acf --- /dev/null +++ b/sysdeps/m68k/bsd-setjmp.c @@ -0,0 +1,21 @@ +/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'. m68k version. + Copyright (C) 1994, 1997, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +#define BSD_SETJMP +#include <sysdeps/m68k/setjmp.c> diff --git a/sysdeps/m68k/dl-machine.h b/sysdeps/m68k/dl-machine.h new file mode 100644 index 0000000..146c586 --- /dev/null +++ b/sysdeps/m68k/dl-machine.h @@ -0,0 +1,316 @@ +/* Machine-dependent ELF dynamic relocation inline functions. m68k version. + Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +#ifndef dl_machine_h +#define dl_machine_h + +#define ELF_MACHINE_NAME "m68k" + +#include <sys/param.h> + +/* Return nonzero iff ELF header is compatible with the running host. */ +static inline int +elf_machine_matches_host (const Elf32_Ehdr *ehdr) +{ + return ehdr->e_machine == EM_68K; +} + + +/* Return the link-time address of _DYNAMIC. Conveniently, this is the + first element of the GOT. This must be inlined in a function which + uses global data. */ +static inline Elf32_Addr +elf_machine_dynamic (void) +{ + register Elf32_Addr *got asm ("%a5"); + return *got; +} + + +/* Return the run-time load address of the shared object. */ +static inline Elf32_Addr +elf_machine_load_address (void) +{ + Elf32_Addr addr; + asm ("lea _dl_start(%%pc), %0\n\t" + "sub.l _dl_start@GOT.w(%%a5), %0" + : "=a" (addr)); + return addr; +} + + +/* Set up the loaded object described by L so its unrelocated PLT + entries will jump to the on-demand fixup code in dl-runtime.c. */ + +static inline int __attribute__ ((always_inline)) +elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) +{ + Elf32_Addr *got; + extern void _dl_runtime_resolve (Elf32_Word); + extern void _dl_runtime_profile (Elf32_Word); + + if (l->l_info[DT_JMPREL] && lazy) + { + /* The GOT entries for functions in the PLT have not yet been + filled in. Their initial contents will arrange when called + to push an offset into the .rela.plt section, push + _GLOBAL_OFFSET_TABLE_[1], and then jump to + _GLOBAL_OFFSET_TABLE_[2]. */ + got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]); + got[1] = (Elf32_Addr) l; /* Identify this shared object. */ + + /* The got[2] entry contains the address of a function which gets + called to get the address of a so far unresolved function and + jump to it. The profiling extension of the dynamic linker allows + to intercept the calls to collect information. In this case we + don't store the address in the GOT so that all future calls also + end in this function. */ + if (profile) + { + got[2] = (Elf32_Addr) &_dl_runtime_profile; + + if (_dl_name_match_p (GLRO(dl_profile), l)) + { + /* This is the object we are looking for. Say that we really + want profiling and the timers are started. */ + GL(dl_profile_map) = l; + } + } + else + /* This function will get called to fix up the GOT entry indicated by + the offset on the stack, and then jump to the resolved address. */ + got[2] = (Elf32_Addr) &_dl_runtime_resolve; + } + + return lazy; +} + +/* This code is used in dl-runtime.c to call the `fixup' function + and then redirect to the address it returns. */ +#define TRAMPOLINE_TEMPLATE(tramp_name, fixup_name) \ +"| Trampoline for " #fixup_name "\n\ + .globl " #tramp_name "\n\ + .type " #tramp_name ", @function\n\ +" #tramp_name ":\n\ + | Save %a0 (struct return address) and %a1.\n\ + move.l %a0, -(%sp)\n\ + move.l %a1, -(%sp)\n\ + | Call the real address resolver.\n\ + jbsr " #fixup_name "\n\ + | Restore register %a0 and %a1.\n\ + move.l (%sp)+, %a1\n\ + move.l (%sp)+, %a0\n\ + | Pop parameters\n\ + addq.l #8, %sp\n\ + | Call real function.\n\ + jmp (%d0)\n\ + .size " #tramp_name ", . - " #tramp_name "\n" +#ifndef PROF +#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ +asm (TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup) \ + TRAMPOLINE_TEMPLATE (_dl_runtime_profile, profile_fixup)); +#else +#define ELF_MACHINE_RUNTIME_TRAMPOLINE \ +asm (TRAMPOLINE_TEMPLATE (_dl_runtime_resolve, fixup) \ + ".globl _dl_runtime_profile\n" \ + ".set _dl_runtime_profile, _dl_runtime_resolve"); +#endif +#define ELF_MACHINE_RUNTIME_FIXUP_ARGS long int save_a0, long int save_a1 + + +/* Mask identifying addresses reserved for the user program, + where the dynamic linker should not map anything. */ +#define ELF_MACHINE_USER_ADDRESS_MASK 0x80000000UL + +/* Initial entry point code for the dynamic linker. + The C function `_dl_start' is the real entry point; + its return value is the user program's entry point. */ + +#define RTLD_START asm ("\ + .text\n\ + .globl _start\n\ + .type _start,@function\n\ +_start:\n\ + move.l %sp, -(%sp)\n\ + jbsr _dl_start\n\ + addq.l #4, %sp\n\ + /* FALLTHRU */\n\ +\n\ + .globl _dl_start_user\n\ + .type _dl_start_user,@function\n\ +_dl_start_user:\n\ + | Save the user entry point address in %a4.\n\ + move.l %d0, %a4\n\ + | See if we were run as a command with the executable file\n\ + | name as an extra leading argument.\n\ + move.l _dl_skip_args(%pc), %d0\n\ + | Pop the original argument count\n\ + move.l (%sp)+, %d1\n\ + | Subtract _dl_skip_args from it.\n\ + sub.l %d0, %d1\n\ + | Adjust the stack pointer to skip _dl_skip_args words.\n\ + lea (%sp, %d0*4), %sp\n\ + | Push back the modified argument count.\n\ + move.l %d1, -(%sp)\n\ + # Call _dl_init (struct link_map *main_map, int argc, char **argv, char **env)\n\ + pea 8(%sp, %d1*4)\n\ + pea 8(%sp)\n\ + move.l %d1, -(%sp)\n\ + move.l _rtld_local(%pc), -(%sp)\n\ + jbsr _dl_init_internal@PLTPC\n\ + addq.l #8, %sp\n\ + addq.l #8, %sp\n\ + | Pass our finalizer function to the user in %a1.\n\ + lea _dl_fini(%pc), %a1\n\ + | Initialize %fp with the stack pointer.\n\ + move.l %sp, %fp\n\ + | Jump to the user's entry point.\n\ + jmp (%a4)\n\ + .size _dl_start_user, . - _dl_start_user\n\ + .previous"); + +/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so + PLT entries should not be allowed to define the value. + ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one + of the main executable's symbols, as for a COPY reloc. */ +#define elf_machine_type_class(type) \ + ((((type) == R_68K_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_68K_COPY) * ELF_RTYPE_CLASS_COPY)) + +/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ +#define ELF_MACHINE_JMP_SLOT R_68K_JMP_SLOT + +/* The m68k never uses Elf32_Rel relocations. */ +#define ELF_MACHINE_NO_REL 1 + +static inline Elf32_Addr +elf_machine_fixup_plt (struct link_map *map, lookup_t t, + const Elf32_Rela *reloc, + Elf32_Addr *reloc_addr, Elf32_Addr value) +{ + return *reloc_addr = value; +} + +/* Return the final value of a plt relocation. On the m68k the JMP_SLOT + relocation ignores the addend. */ +static inline Elf32_Addr +elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc, + Elf32_Addr value) +{ + return value; +} + +#endif /* !dl_machine_h */ + +#ifdef RESOLVE + +/* Perform the relocation specified by RELOC and SYM (which is fully resolved). + MAP is the object containing the reloc. */ + +auto inline void __attribute__ ((unused, always_inline)) +elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + const Elf32_Sym *sym, const struct r_found_version *version, + void *const reloc_addr_arg) +{ + Elf32_Addr *const reloc_addr = reloc_addr_arg; + const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); + + if (__builtin_expect (r_type == R_68K_RELATIVE, 0)) + *reloc_addr = map->l_addr + reloc->r_addend; + else + { + const Elf32_Sym *const refsym = sym; + Elf32_Addr value = RESOLVE (&sym, version, r_type); + if (sym) + value += sym->st_value; + + switch (r_type) + { + case R_68K_COPY: + if (sym == NULL) + /* This can happen in trace mode if an object could not be + found. */ + break; + if (sym->st_size > refsym->st_size + || (sym->st_size < refsym->st_size && GLRO(dl_verbose))) + { + const char *strtab; + + strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]); + _dl_error_printf ("\ +%s: Symbol `%s' has different size in shared object, consider re-linking\n", + rtld_progname ?: "<program name unknown>", + strtab + refsym->st_name); + } + memcpy (reloc_addr_arg, (void *) value, + MIN (sym->st_size, refsym->st_size)); + break; + case R_68K_GLOB_DAT: + case R_68K_JMP_SLOT: + *reloc_addr = value; + break; + case R_68K_8: + *(char *) reloc_addr = value + reloc->r_addend; + break; + case R_68K_16: + *(short *) reloc_addr = value + reloc->r_addend; + break; + case R_68K_32: + *reloc_addr = value + reloc->r_addend; + break; + case R_68K_PC8: + *(char *) reloc_addr + = value + reloc->r_addend - (Elf32_Addr) reloc_addr; + break; + case R_68K_PC16: + *(short *) reloc_addr + = value + reloc->r_addend - (Elf32_Addr) reloc_addr; + break; + case R_68K_PC32: + *reloc_addr = value + reloc->r_addend - (Elf32_Addr) reloc_addr; + break; + case R_68K_NONE: /* Alright, Wilbur. */ + break; + default: + _dl_reloc_bad_type (map, r_type, 0); + break; + } + } +} + +auto inline void __attribute__ ((unused, always_inline)) +elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, + void *const reloc_addr_arg) +{ + Elf32_Addr *const reloc_addr = reloc_addr_arg; + *reloc_addr = l_addr + reloc->r_addend; +} + +auto inline void __attribute__ ((unused, always_inline)) +elf_machine_lazy_rel (struct link_map *map, + Elf32_Addr l_addr, const Elf32_Rela *reloc) +{ + Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); + if (ELF32_R_TYPE (reloc->r_info) == R_68K_JMP_SLOT) + *reloc_addr += l_addr; + else + _dl_reloc_bad_type (map, ELF32_R_TYPE (reloc->r_info), 1); +} + +#endif /* RESOLVE */ diff --git a/sysdeps/m68k/elf/start.S b/sysdeps/m68k/elf/start.S new file mode 100644 index 0000000..8c89b37 --- /dev/null +++ b/sysdeps/m68k/elf/start.S @@ -0,0 +1,100 @@ +/* Startup code compliant to the ELF m68k ABI. + Copyright (C) 1996, 1997, 1998, 2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. + + In addition to the permissions in the GNU Lesser 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 GNU Lesser 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.) + + Note that people who make modified versions of this file are not + obligated to grant this special exception for their modified + versions; it is their choice whether to do so. The GNU Lesser + General Public License gives permission to release a modified + version without this exception; this exception also makes it + possible to release a modified version which carries forward this + exception. + + 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. */ + +/* This is the canonical entry point, usually the first thing in the text + segment. The SVR4/m68k ABI says that when the entry point runs, + most registers' values are unspecified, except for: + + %a1 Contains a function pointer to be registered with `atexit'. + This is how the dynamic linker arranges to have DT_FINI + functions called for shared libraries that have been loaded + before this code runs. + + %sp The stack contains the arguments and environment: + 0(%sp) argc + 4(%sp) argv[0] + ... + (4*argc)(%sp) NULL + (4*(argc+1))(%sp) envp[0] + ... + NULL +*/ + + .text + .globl _start + .type _start,@function +_start: + /* Clear the frame pointer. The ABI suggests this be done, to mark + the outermost frame obviously. */ + sub.l %fp, %fp + + /* Extract the arguments as encoded on the stack and set up the + arguments for `main': argc, argv. envp will be determined + later in __libc_start_main. */ + move.l (%sp)+, %d0 /* Pop the argument count. */ + move.l %sp, %a0 /* The argument vector starts just at the + current stack top. */ + + /* Provide the highest stack address to the user code (for stacks + which grow downward). */ + pea (%sp) + + pea (%a1) /* Push address of the shared library + termination function. */ + + /* Push the address of our own entry points to `.fini' and + `.init'. */ + pea __libc_csu_fini + pea __libc_csu_init + + pea (%a0) /* Push second argument: argv. */ + move.l %d0, -(%sp) /* Push first argument: argc. */ + + pea main + + /* Call the user's main function, and exit with its value. But + let the libc call main. */ + jbsr __libc_start_main + + illegal /* Crash if somehow `exit' does return. */ + +/* Define a symbol for the first piece of initialized data. */ + .data + .globl __data_start +__data_start: + .long 0 + .weak data_start + data_start = __data_start diff --git a/sysdeps/m68k/ffs.c b/sysdeps/m68k/ffs.c new file mode 100644 index 0000000..189936b --- /dev/null +++ b/sysdeps/m68k/ffs.c @@ -0,0 +1,48 @@ +/* ffs -- find first set bit in a word, counted from least significant end. + For mc68020, mc68030, mc68040. + This file is part of the GNU C Library. + Copyright (C) 1991, 1992, 1997, 1998, 2004 Free Software Foundation, Inc. + Contributed by Torbjorn Granlund (tege@sics.se). + + 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. */ + +#define ffsl __something_else +#include <string.h> + +#undef ffs + +#if defined (__GNUC__) && defined (__mc68020__) + +int +__ffs (x) + int x; +{ + int cnt; + + asm ("bfffo %1{#0:#0},%0" : "=d" (cnt) : "dm" (x & -x)); + + return 32 - cnt; +} +weak_alias (__ffs, ffs) +libc_hidden_builtin_def (ffs) +#undef ffsl +weak_alias (__ffs, ffsl) + +#else + +#include <sysdeps/generic/ffs.c> + +#endif diff --git a/sysdeps/m68k/fpu/Dist b/sysdeps/m68k/fpu/Dist new file mode 100644 index 0000000..e649e8d --- /dev/null +++ b/sysdeps/m68k/fpu/Dist @@ -0,0 +1 @@ +mathimpl.h diff --git a/sysdeps/m68k/fpu/Makefile b/sysdeps/m68k/fpu/Makefile new file mode 100644 index 0000000..42db638 --- /dev/null +++ b/sysdeps/m68k/fpu/Makefile @@ -0,0 +1,11 @@ +ifeq ($(subdir),math) +ifndef math-twiddled + +# Avoid twiddling in generic/Makefile. +math-twiddled := t + +endif + +bsdmath_dirs := $(bsdmath_dirs) mc68881 + +endif diff --git a/sysdeps/m68k/fpu/bits/fenv.h b/sysdeps/m68k/fpu/bits/fenv.h new file mode 100644 index 0000000..7c0bcb6 --- /dev/null +++ b/sysdeps/m68k/fpu/bits/fenv.h @@ -0,0 +1,79 @@ +/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +#ifndef _FENV_H +# error "Never use <bits/fenv.h> directly; include <fenv.h> instead." +#endif + + +/* Define bits representing the exception. We use the bit positions of + the appropriate bits in the FPSR Accrued Exception Byte. */ +enum + { + FE_INEXACT = 1 << 3, +#define FE_INEXACT FE_INEXACT + FE_DIVBYZERO = 1 << 4, +#define FE_DIVBYZERO FE_DIVBYZERO + FE_UNDERFLOW = 1 << 5, +#define FE_UNDERFLOW FE_UNDERFLOW + FE_OVERFLOW = 1 << 6, +#define FE_OVERFLOW FE_OVERFLOW + FE_INVALID = 1 << 7 +#define FE_INVALID FE_INVALID + }; + +#define FE_ALL_EXCEPT \ + (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) + +/* The m68k FPU supports all of the four defined rounding modes. We use + the bit positions in the FPCR Mode Control Byte as the values for the + appropriate macros. */ +enum + { + FE_TONEAREST = 0, +#define FE_TONEAREST FE_TONEAREST + FE_TOWARDZERO = 1 << 4, +#define FE_TOWARDZERO FE_TOWARDZERO + FE_DOWNWARD = 2 << 4, +#define FE_DOWNWARD FE_DOWNWARD + FE_UPWARD = 3 << 4 +#define FE_UPWARD FE_UPWARD + }; + + +/* Type representing exception flags. */ +typedef unsigned int fexcept_t; + + +/* Type representing floating-point environment. This structure + corresponds to the layout of the block written by `fmovem'. */ +typedef struct + { + unsigned int __control_register; + unsigned int __status_register; + unsigned int __instruction_address; + } +fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((__const fenv_t *) -1) + +#ifdef __USE_GNU +/* Floating-point environment where none of the exceptions are masked. */ +# define FE_NOMASK_ENV ((__const fenv_t *) -2) +#endif diff --git a/sysdeps/m68k/fpu/bits/mathdef.h b/sysdeps/m68k/fpu/bits/mathdef.h new file mode 100644 index 0000000..65cf8d4 --- /dev/null +++ b/sysdeps/m68k/fpu/bits/mathdef.h @@ -0,0 +1,38 @@ +/* Copyright (C) 1997, 1998, 1999, 2000, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +#if !defined _MATH_H && !defined _COMPLEX_H +# error "Never use <bits/mathdef.h> directly; include <math.h> instead" +#endif + +#if defined __USE_ISOC99 && defined _MATH_H && !defined _MATH_H_MATHDEF +# define _MATH_H_MATHDEF 1 + +/* The m68k FPUs evaluate all values in the 96 bit floating-point format + which is also available for the user as `long double'. Therefore we + define: */ +typedef long double float_t; /* `float' expressions are evaluated as + `long double'. */ +typedef long double double_t; /* `double' expressions are evaluated as + `long double'. */ + +/* The values returned by `ilogb' for 0 and NaN respectively. */ +# define FP_ILOGB0 (-2147483647 - 1) +# define FP_ILOGBNAN (2147483647) + +#endif /* ISO C99 */ diff --git a/sysdeps/m68k/fpu/bits/mathinline.h b/sysdeps/m68k/fpu/bits/mathinline.h new file mode 100644 index 0000000..acbac47 --- /dev/null +++ b/sysdeps/m68k/fpu/bits/mathinline.h @@ -0,0 +1,445 @@ +/* Definitions of inline math functions implemented by the m68881/2. + Copyright (C) 1991,92,93,94,96,97,98,99,2000,2002, 2003, 2004 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +#ifdef __GNUC__ + +#ifdef __USE_ISOC99 +/* GCC 3.1 and up have builtins that actually can be used. */ +# if !__GNUC_PREREQ (3,1) +/* ISO C99 defines some macros to perform unordered comparisons. The + m68k FPU supports this with special opcodes and we should use them. + These must not be inline functions since we have to be able to handle + all floating-point types. */ +# undef isgreater +# undef isgreaterequal +# undef isless +# undef islessequal +# undef islessgreater +# undef isunordered +# define isgreater(x, y) \ + __extension__ \ + ({ char __result; \ + __asm__ ("fcmp%.x %2,%1; fsogt %0" \ + : "=dm" (__result) : "f" (x), "f" (y)); \ + __result != 0; }) + +# define isgreaterequal(x, y) \ + __extension__ \ + ({ char __result; \ + __asm__ ("fcmp%.x %2,%1; fsoge %0" \ + : "=dm" (__result) : "f" (x), "f" (y)); \ + __result != 0; }) + +# define isless(x, y) \ + __extension__ \ + ({ char __result; \ + __asm__ ("fcmp%.x %2,%1; fsolt %0" \ + : "=dm" (__result) : "f" (x), "f" (y)); \ + __result != 0; }) + +# define islessequal(x, y) \ + __extension__ \ + ({ char __result; \ + __asm__ ("fcmp%.x %2,%1; fsole %0" \ + : "=dm" (__result) : "f" (x), "f" (y)); \ + __result != 0; }) + +# define islessgreater(x, y) \ + __extension__ \ + ({ char __result; \ + __asm__ ("fcmp%.x %2,%1; fsogl %0" \ + : "=dm" (__result) : "f" (x), "f" (y)); \ + __result != 0; }) + +# define isunordered(x, y) \ + __extension__ \ + ({ char __result; \ + __asm__ ("fcmp%.x %2,%1; fsun %0" \ + : "=dm" (__result) : "f" (x), "f" (y)); \ + __result != 0; }) +# endif /* GCC 3.1 */ +#endif + + +#if (!defined __NO_MATH_INLINES && defined __OPTIMIZE__) \ + || defined __LIBC_INTERNAL_MATH_INLINES + +#ifdef __LIBC_INTERNAL_MATH_INLINES +/* This is used when defining the functions themselves. Define them with + __ names, and with `static inline' instead of `extern inline' so the + bodies will always be used, never an external function call. */ +# define __m81_u(x) __CONCAT(__,x) +# define __m81_inline static __inline +#else +# define __m81_u(x) x +# ifdef __cplusplus +# define __m81_inline __inline +# else +# define __m81_inline extern __inline +# endif +# define __M81_MATH_INLINES 1 +#endif + +/* Define a const math function. */ +#define __m81_defun(rettype, func, args) \ + __m81_inline rettype __attribute__((__const__)) \ + __m81_u(func) args + +/* Define the three variants of a math function that has a direct + implementation in the m68k fpu. FUNC is the name for C (which will be + suffixed with f and l for the float and long double version, resp). OP + is the name of the fpu operation (without leading f). */ + +#if defined __USE_MISC || defined __USE_ISOC99 +# define __inline_mathop(func, op) \ + __inline_mathop1(double, func, op) \ + __inline_mathop1(float, __CONCAT(func,f), op) \ + __inline_mathop1(long double, __CONCAT(func,l), op) +#else +# define __inline_mathop(func, op) \ + __inline_mathop1(double, func, op) +#endif + +#define __inline_mathop1(float_type,func, op) \ + __m81_defun (float_type, func, (float_type __mathop_x)) \ + { \ + float_type __result; \ + __asm("f" __STRING(op) "%.x %1, %0" : "=f" (__result) : "f" (__mathop_x));\ + return __result; \ + } + +__inline_mathop(__atan, atan) +__inline_mathop(__cos, cos) +__inline_mathop(__sin, sin) +__inline_mathop(__tan, tan) +__inline_mathop(__tanh, tanh) +__inline_mathop(__fabs, abs) + +#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99 +__inline_mathop(__rint, int) +__inline_mathop(__expm1, etoxm1) +__inline_mathop(__log1p, lognp1) +#endif + +#ifdef __USE_MISC +__inline_mathop(__significand, getman) +#endif + +#ifdef __USE_ISOC99 +__inline_mathop(__trunc, intrz) +#endif + +#if !defined __NO_MATH_INLINES && defined __OPTIMIZE__ + +__inline_mathop(atan, atan) +__inline_mathop(cos, cos) +__inline_mathop(sin, sin) +__inline_mathop(tan, tan) +__inline_mathop(tanh, tanh) + +# if defined __USE_MISC || defined __USE_XOPEN_EXTENDED || defined __USE_ISOC99 +__inline_mathop(rint, int) +__inline_mathop(expm1, etoxm1) +__inline_mathop(log1p, lognp1) +# endif + +# ifdef __USE_MISC +__inline_mathop(significand, getman) +# endif + +# ifdef __USE_ISOC99 +__inline_mathop(trunc, intrz) +# endif + +#endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */ + +/* This macro contains the definition for the rest of the inline + functions, using FLOAT_TYPE as the domain type and S as the suffix + for the function names. */ + +#define __inline_functions(float_type, s) \ +__m81_defun (float_type, __CONCAT(__floor,s), (float_type __x)) \ +{ \ + float_type __result; \ + unsigned long int __ctrl_reg; \ + __asm __volatile__ ("fmove%.l %!, %0" : "=dm" (__ctrl_reg)); \ + /* Set rounding towards negative infinity. */ \ + __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \ + : "dmi" ((__ctrl_reg & ~0x10) | 0x20)); \ + /* Convert X to an integer, using -Inf rounding. */ \ + __asm __volatile__ ("fint%.x %1, %0" : "=f" (__result) : "f" (__x)); \ + /* Restore the previous rounding mode. */ \ + __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \ + : "dmi" (__ctrl_reg)); \ + return __result; \ +} \ + \ +__m81_defun (float_type, __CONCAT(__ceil,s), (float_type __x)) \ +{ \ + float_type __result; \ + unsigned long int __ctrl_reg; \ + __asm __volatile__ ("fmove%.l %!, %0" : "=dm" (__ctrl_reg)); \ + /* Set rounding towards positive infinity. */ \ + __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \ + : "dmi" (__ctrl_reg | 0x30)); \ + /* Convert X to an integer, using +Inf rounding. */ \ + __asm __volatile__ ("fint%.x %1, %0" : "=f" (__result) : "f" (__x)); \ + /* Restore the previous rounding mode. */ \ + __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \ + : "dmi" (__ctrl_reg)); \ + return __result; \ +} + +__inline_functions(double,) +#if defined __USE_MISC || defined __USE_ISOC99 +__inline_functions(float,f) +__inline_functions(long double,l) +#endif +#undef __inline_functions + +#ifdef __USE_MISC + +# define __inline_functions(float_type, s) \ +__m81_defun (int, __CONCAT(__isinf,s), (float_type __value)) \ +{ \ + /* There is no branch-condition for infinity, \ + so we must extract and examine the condition codes manually. */ \ + unsigned long int __fpsr; \ + __asm("ftst%.x %1\n" \ + "fmove%.l %/fpsr, %0" : "=dm" (__fpsr) : "f" (__value)); \ + return (__fpsr & (2 << 24)) ? (__fpsr & (8 << 24) ? -1 : 1) : 0; \ +} \ + \ +__m81_defun (int, __CONCAT(__finite,s), (float_type __value)) \ +{ \ + /* There is no branch-condition for infinity, so we must extract and \ + examine the condition codes manually. */ \ + unsigned long int __fpsr; \ + __asm ("ftst%.x %1\n" \ + "fmove%.l %/fpsr, %0" : "=dm" (__fpsr) : "f" (__value)); \ + return (__fpsr & (3 << 24)) == 0; \ +} \ + \ +__m81_defun (float_type, __CONCAT(__scalbn,s), \ + (float_type __x, int __n)) \ +{ \ + float_type __result; \ + __asm ("fscale%.l %1, %0" : "=f" (__result) : "dmi" (__n), "0" (__x)); \ + return __result; \ +} + +__inline_functions(double,) +__inline_functions(float,f) +__inline_functions(long double,l) +# undef __inline_functions + +#endif /* Use misc. */ + +#if defined __USE_MISC || defined __USE_XOPEN + +# define __inline_functions(float_type, s) \ +__m81_defun (int, __CONCAT(__isnan,s), (float_type __value)) \ +{ \ + char __result; \ + __asm("ftst%.x %1\n" \ + "fsun %0" : "=dm" (__result) : "f" (__value)); \ + return __result; \ +} + +__inline_functions(double,) +# ifdef __USE_MISC +__inline_functions(float,f) +__inline_functions(long double,l) +# endif +# undef __inline_functions + +#endif + +#ifdef __USE_ISOC99 + +# define __inline_functions(float_type, s) \ +__m81_defun (int, __CONCAT(__signbit,s), (float_type __value)) \ +{ \ + /* There is no branch-condition for the sign bit, so we must extract \ + and examine the condition codes manually. */ \ + unsigned long int __fpsr; \ + __asm ("ftst%.x %1\n" \ + "fmove%.l %/fpsr, %0" : "=dm" (__fpsr) : "f" (__value)); \ + return (__fpsr >> 27) & 1; \ +} \ + \ + __m81_defun (float_type, __CONCAT(__scalbln,s), \ + (float_type __x, long int __n)) \ +{ \ + return __CONCAT(__scalbn,s) (__x, __n); \ +} \ + \ +__m81_defun (float_type, __CONCAT(__nearbyint,s), (float_type __x)) \ +{ \ + float_type __result; \ + unsigned long int __ctrl_reg; \ + __asm __volatile__ ("fmove%.l %!, %0" : "=dm" (__ctrl_reg)); \ + /* Temporarily disable the inexact exception. */ \ + __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \ + : "dmi" (__ctrl_reg & ~0x200)); \ + __asm __volatile__ ("fint%.x %1, %0" : "=f" (__result) : "f" (__x)); \ + __asm __volatile__ ("fmove%.l %0, %!" : /* No outputs. */ \ + : "dmi" (__ctrl_reg)); \ + return __result; \ +} \ + \ +__m81_defun (long int, __CONCAT(__lrint,s), (float_type __x)) \ +{ \ + long int __result; \ + __asm ("fmove%.l %1, %0" : "=dm" (__result) : "f" (__x)); \ + return __result; \ +} \ + \ +__m81_inline float_type \ +__m81_u(__CONCAT(__fma,s))(float_type __x, float_type __y, \ + float_type __z) \ +{ \ + return (__x * __y) + __z; \ +} + +__inline_functions (double,) +__inline_functions (float,f) +__inline_functions (long double,l) +# undef __inline_functions + +#endif /* Use ISO C9x */ + +#ifdef __USE_GNU + +# define __inline_functions(float_type, s) \ +__m81_inline void \ +__m81_u(__CONCAT(__sincos,s))(float_type __x, float_type *__sinx, \ + float_type *__cosx) \ +{ \ + __asm ("fsincos%.x %2,%1:%0" \ + : "=f" (*__sinx), "=f" (*__cosx) : "f" (__x)); \ +} + +__inline_functions (double,) +__inline_functions (float,f) +__inline_functions (long double,l) +# undef __inline_functions + +#endif + +#if !defined __NO_MATH_INLINES && defined __OPTIMIZE__ + +/* Define inline versions of the user visible functions. */ + +/* Note that there must be no whitespace before the argument passed for + NAME, to make token pasting work correctly with -traditional. */ +# define __inline_forward_c(rettype, name, args1, args2) \ +extern __inline rettype __attribute__((__const__)) \ + name args1 \ +{ \ + return __CONCAT(__,name) args2; \ +} + +# define __inline_forward(rettype, name, args1, args2) \ +extern __inline rettype name args1 \ +{ \ + return __CONCAT(__,name) args2; \ +} + +__inline_forward_c(double,floor, (double __x), (__x)) +__inline_forward_c(double,ceil, (double __x), (__x)) +# ifdef __USE_MISC +# ifndef __USE_ISOC99 /* Conflict with macro of same name. */ +__inline_forward_c(int,isinf, (double __value), (__value)) +# endif +__inline_forward_c(int,finite, (double __value), (__value)) +__inline_forward_c(double,scalbn, (double __x, int __n), (__x, __n)) +# endif +# if defined __USE_MISC || defined __USE_XOPEN +# ifndef __USE_ISOC99 /* Conflict with macro of same name. */ +__inline_forward_c(int,isnan, (double __value), (__value)) +# endif +# endif +# ifdef __USE_ISOC99 +__inline_forward_c(double,scalbln, (double __x, long int __n), (__x, __n)) +__inline_forward_c(double,nearbyint, (double __value), (__value)) +__inline_forward_c(long int,lrint, (double __value), (__value)) +__inline_forward_c(double,fma, (double __x, double __y, double __z), + (__x, __y, __z)) +# endif +# ifdef __USE_GNU +__inline_forward(void,sincos, (double __x, double *__sinx, double *__cosx), + (__x, __sinx, __cosx)) +# endif + +# if defined __USE_MISC || defined __USE_ISOC99 + +__inline_forward_c(float,floorf, (float __x), (__x)) +__inline_forward_c(float,ceilf, (float __x), (__x)) +# ifdef __USE_MISC +__inline_forward_c(int,isinff, (float __value), (__value)) +__inline_forward_c(int,finitef, (float __value), (__value)) +__inline_forward_c(float,scalbnf, (float __x, int __n), (__x, __n)) +__inline_forward_c(int,isnanf, (float __value), (__value)) +# endif +# ifdef __USE_ISOC99 +__inline_forward_c(float,scalblnf, (float __x, long int __n), (__x, __n)) +__inline_forward_c(float,nearbyintf, (float __value), (__value)) +__inline_forward_c(long int,lrintf, (float __value), (__value)) +__inline_forward_c(float,fmaf, (float __x, float __y, float __z), + (__x, __y, __z)) +# endif +# ifdef __USE_GNU +__inline_forward(void,sincosf, (float __x, float *__sinx, float *__cosx), + (__x, __sinx, __cosx)) +# endif + +__inline_forward_c(long double,floorl, (long double __x), (__x)) +__inline_forward_c(long double,ceill, (long double __x), (__x)) +# ifdef __USE_MISC +__inline_forward_c(int,isinfl, (long double __value), (__value)) +__inline_forward_c(int,finitel, (long double __value), (__value)) +__inline_forward_c(long double,scalbnl, (long double __x, int __n), (__x, __n)) +__inline_forward_c(int,isnanl, (long double __value), (__value)) +# endif +# ifdef __USE_ISOC99 +__inline_forward_c(long double,scalblnl, (long double __x, long int __n), + (__x, __n)) +__inline_forward_c(long double,nearbyintl, (long double __value), (__value)) +__inline_forward_c(long int,lrintl, (long double __value), (__value)) +__inline_forward_c(long double,fmal, + (long double __x, long double __y, long double __z), + (__x, __y, __z)) +# endif +# ifdef __USE_GNU +__inline_forward(void,sincosl, + (long double __x, long double *__sinx, long double *__cosx), + (__x, __sinx, __cosx)) +# endif + +#endif /* Use misc or ISO C99 */ + +#undef __inline_forward +#undef __inline_forward_c + +#endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */ + +#endif +#endif /* GCC. */ diff --git a/sysdeps/m68k/fpu/branred.c b/sysdeps/m68k/fpu/branred.c new file mode 100644 index 0000000..1cc8931 --- /dev/null +++ b/sysdeps/m68k/fpu/branred.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/m68k/fpu/doasin.c b/sysdeps/m68k/fpu/doasin.c new file mode 100644 index 0000000..1cc8931 --- /dev/null +++ b/sysdeps/m68k/fpu/doasin.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/m68k/fpu/dosincos.c b/sysdeps/m68k/fpu/dosincos.c new file mode 100644 index 0000000..1cc8931 --- /dev/null +++ b/sysdeps/m68k/fpu/dosincos.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/m68k/fpu/e_acos.c b/sysdeps/m68k/fpu/e_acos.c new file mode 100644 index 0000000..c9f6c6a --- /dev/null +++ b/sysdeps/m68k/fpu/e_acos.c @@ -0,0 +1,35 @@ +/* Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> +#include "math_private.h" +#include "mathimpl.h" + +#ifndef FUNC +#define FUNC __ieee754_acos +#endif +#ifndef float_type +#define float_type double +#endif + +float_type +FUNC (x) + float_type x; +{ + return __m81_u(FUNC)(x); +} diff --git a/sysdeps/m68k/fpu/e_acosf.c b/sysdeps/m68k/fpu/e_acosf.c new file mode 100644 index 0000000..9066508 --- /dev/null +++ b/sysdeps/m68k/fpu/e_acosf.c @@ -0,0 +1,5 @@ +#ifndef FUNC +#define FUNC __ieee754_acosf +#endif +#define float_type float +#include <e_acos.c> diff --git a/sysdeps/m68k/fpu/e_acosl.c b/sysdeps/m68k/fpu/e_acosl.c new file mode 100644 index 0000000..e3dcd17 --- /dev/null +++ b/sysdeps/m68k/fpu/e_acosl.c @@ -0,0 +1,5 @@ +#ifndef FUNC +#define FUNC __ieee754_acosl +#endif +#define float_type long double +#include <e_acos.c> diff --git a/sysdeps/m68k/fpu/e_asin.c b/sysdeps/m68k/fpu/e_asin.c new file mode 100644 index 0000000..b6176c7 --- /dev/null +++ b/sysdeps/m68k/fpu/e_asin.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_asin +#include <e_acos.c> diff --git a/sysdeps/m68k/fpu/e_asinf.c b/sysdeps/m68k/fpu/e_asinf.c new file mode 100644 index 0000000..05fb826 --- /dev/null +++ b/sysdeps/m68k/fpu/e_asinf.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_asinf +#include <e_acosf.c> diff --git a/sysdeps/m68k/fpu/e_asinl.c b/sysdeps/m68k/fpu/e_asinl.c new file mode 100644 index 0000000..0dd89fb --- /dev/null +++ b/sysdeps/m68k/fpu/e_asinl.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_asinl +#include <e_acosl.c> diff --git a/sysdeps/m68k/fpu/e_atan2.c b/sysdeps/m68k/fpu/e_atan2.c new file mode 100644 index 0000000..551b14d --- /dev/null +++ b/sysdeps/m68k/fpu/e_atan2.c @@ -0,0 +1,104 @@ +/* Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> +#include "math_private.h" +#include "mathimpl.h" + +#ifndef SUFF +#define SUFF +#endif +#ifndef float_type +#define float_type double +#endif + +#define CONCATX(a,b) __CONCAT(a,b) +#define s(name) CONCATX(name,SUFF) +#define m81(func) __m81_u(s(func)) + +float_type +s(__ieee754_atan2) (float_type y, float_type x) +{ + float_type pi, pi_2, z; + unsigned long y_cond, x_cond; + + __asm ("fmovecr%.x %#0, %0" : "=f" (pi)); + __asm ("fscale%.w %#-1, %0" : "=f" (pi_2) : "0" (pi)); + y_cond = __m81_test (y); + x_cond = __m81_test (x); + + if ((x_cond | y_cond) & __M81_COND_NAN) + z = x + y; + else if (y_cond & __M81_COND_ZERO) + { + if (x_cond & __M81_COND_NEG) + z = y_cond & __M81_COND_NEG ? -pi : pi; + else + z = y; + } + else if (x_cond & __M81_COND_INF) + { + if (y_cond & __M81_COND_INF) + { + float_type pi_4; + __asm ("fscale%.w %#-2, %0" : "=f" (pi_4) : "0" (pi)); + z = x_cond & __M81_COND_NEG ? 3 * pi_4 : pi_4; + } + else + z = x_cond & __M81_COND_NEG ? pi : 0; + if (y_cond & __M81_COND_NEG) + z = -z; + } + else if (y_cond & __M81_COND_INF) + z = y_cond & __M81_COND_NEG ? -pi_2 : pi_2; + else if (x_cond & __M81_COND_NEG) + { + if (y_cond & __M81_COND_NEG) + { + if (-x > -y) + z = -pi + m81(__atan) (y / x); + else + z = -pi_2 - m81(__atan) (x / y); + } + else + { + if (-x > y) + z = pi + m81(__atan) (y / x); + else + z = pi_2 - m81(__atan) (x / y); + } + } + else + { + if (y_cond & __M81_COND_NEG) + { + if (x > -y) + z = m81(__atan) (y / x); + else + z = -pi_2 - m81(__atan) (x / y); + } + else + { + if (x > y) + z = m81(__atan) (y / x); + else + z = pi_2 - m81(__atan) (x / y); + } + } + return z; +} diff --git a/sysdeps/m68k/fpu/e_atan2f.c b/sysdeps/m68k/fpu/e_atan2f.c new file mode 100644 index 0000000..a0c750a --- /dev/null +++ b/sysdeps/m68k/fpu/e_atan2f.c @@ -0,0 +1,3 @@ +#define SUFF f +#define float_type float +#include <e_atan2.c> diff --git a/sysdeps/m68k/fpu/e_atan2l.c b/sysdeps/m68k/fpu/e_atan2l.c new file mode 100644 index 0000000..426ca94 --- /dev/null +++ b/sysdeps/m68k/fpu/e_atan2l.c @@ -0,0 +1,3 @@ +#define SUFF l +#define float_type long double +#include <e_atan2.c> diff --git a/sysdeps/m68k/fpu/e_atanh.c b/sysdeps/m68k/fpu/e_atanh.c new file mode 100644 index 0000000..11bf430 --- /dev/null +++ b/sysdeps/m68k/fpu/e_atanh.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_atanh +#include <e_acos.c> diff --git a/sysdeps/m68k/fpu/e_atanhf.c b/sysdeps/m68k/fpu/e_atanhf.c new file mode 100644 index 0000000..7a8f92e --- /dev/null +++ b/sysdeps/m68k/fpu/e_atanhf.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_atanhf +#include <e_acosf.c> diff --git a/sysdeps/m68k/fpu/e_atanhl.c b/sysdeps/m68k/fpu/e_atanhl.c new file mode 100644 index 0000000..d8975d6 --- /dev/null +++ b/sysdeps/m68k/fpu/e_atanhl.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_atanhl +#include <e_acosl.c> diff --git a/sysdeps/m68k/fpu/e_cosh.c b/sysdeps/m68k/fpu/e_cosh.c new file mode 100644 index 0000000..93d753c --- /dev/null +++ b/sysdeps/m68k/fpu/e_cosh.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_cosh +#include <e_acos.c> diff --git a/sysdeps/m68k/fpu/e_coshf.c b/sysdeps/m68k/fpu/e_coshf.c new file mode 100644 index 0000000..433faf1 --- /dev/null +++ b/sysdeps/m68k/fpu/e_coshf.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_coshf +#include <e_acosf.c> diff --git a/sysdeps/m68k/fpu/e_coshl.c b/sysdeps/m68k/fpu/e_coshl.c new file mode 100644 index 0000000..39144fd --- /dev/null +++ b/sysdeps/m68k/fpu/e_coshl.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_coshl +#include <e_acosl.c> diff --git a/sysdeps/m68k/fpu/e_exp.c b/sysdeps/m68k/fpu/e_exp.c new file mode 100644 index 0000000..1e95ac47 --- /dev/null +++ b/sysdeps/m68k/fpu/e_exp.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_exp +#include <e_acos.c> diff --git a/sysdeps/m68k/fpu/e_exp10.c b/sysdeps/m68k/fpu/e_exp10.c new file mode 100644 index 0000000..a1dd224 --- /dev/null +++ b/sysdeps/m68k/fpu/e_exp10.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_exp10 +#include <e_acos.c> diff --git a/sysdeps/m68k/fpu/e_exp10f.c b/sysdeps/m68k/fpu/e_exp10f.c new file mode 100644 index 0000000..1b78bc3 --- /dev/null +++ b/sysdeps/m68k/fpu/e_exp10f.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_exp10f +#include <e_acosf.c> diff --git a/sysdeps/m68k/fpu/e_exp10l.c b/sysdeps/m68k/fpu/e_exp10l.c new file mode 100644 index 0000000..5e90199 --- /dev/null +++ b/sysdeps/m68k/fpu/e_exp10l.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_exp10l +#include <e_acosl.c> diff --git a/sysdeps/m68k/fpu/e_exp2.c b/sysdeps/m68k/fpu/e_exp2.c new file mode 100644 index 0000000..24fac4f --- /dev/null +++ b/sysdeps/m68k/fpu/e_exp2.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_exp2 +#include <e_acos.c> diff --git a/sysdeps/m68k/fpu/e_exp2f.c b/sysdeps/m68k/fpu/e_exp2f.c new file mode 100644 index 0000000..593842e --- /dev/null +++ b/sysdeps/m68k/fpu/e_exp2f.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_exp2f +#include <e_acosf.c> diff --git a/sysdeps/m68k/fpu/e_exp2l.c b/sysdeps/m68k/fpu/e_exp2l.c new file mode 100644 index 0000000..0ab2a42 --- /dev/null +++ b/sysdeps/m68k/fpu/e_exp2l.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_exp2l +#include <e_acosl.c> diff --git a/sysdeps/m68k/fpu/e_expf.c b/sysdeps/m68k/fpu/e_expf.c new file mode 100644 index 0000000..2aeaacf --- /dev/null +++ b/sysdeps/m68k/fpu/e_expf.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_expf +#include <e_acosf.c> diff --git a/sysdeps/m68k/fpu/e_expl.c b/sysdeps/m68k/fpu/e_expl.c new file mode 100644 index 0000000..8805a1b --- /dev/null +++ b/sysdeps/m68k/fpu/e_expl.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_expl +#include <e_acosl.c> diff --git a/sysdeps/m68k/fpu/e_fmod.c b/sysdeps/m68k/fpu/e_fmod.c new file mode 100644 index 0000000..bd229ae --- /dev/null +++ b/sysdeps/m68k/fpu/e_fmod.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> +#include "math_private.h" +#include "mathimpl.h" + +#ifndef FUNC +#define FUNC __ieee754_fmod +#endif +#ifndef float_type +#define float_type double +#endif + +float_type +FUNC (x, y) + float_type x; + float_type y; +{ + return __m81_u(FUNC)(x, y); +} diff --git a/sysdeps/m68k/fpu/e_fmodf.c b/sysdeps/m68k/fpu/e_fmodf.c new file mode 100644 index 0000000..88c350c --- /dev/null +++ b/sysdeps/m68k/fpu/e_fmodf.c @@ -0,0 +1,5 @@ +#ifndef FUNC +#define FUNC __ieee754_fmodf +#endif +#define float_type float +#include <e_fmod.c> diff --git a/sysdeps/m68k/fpu/e_fmodl.c b/sysdeps/m68k/fpu/e_fmodl.c new file mode 100644 index 0000000..a46f19e --- /dev/null +++ b/sysdeps/m68k/fpu/e_fmodl.c @@ -0,0 +1,5 @@ +#ifndef FUNC +#define FUNC __ieee754_fmodl +#endif +#define float_type long double +#include <e_fmod.c> diff --git a/sysdeps/m68k/fpu/e_log.c b/sysdeps/m68k/fpu/e_log.c new file mode 100644 index 0000000..146dc0c --- /dev/null +++ b/sysdeps/m68k/fpu/e_log.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_log +#include <e_acos.c> diff --git a/sysdeps/m68k/fpu/e_log10.c b/sysdeps/m68k/fpu/e_log10.c new file mode 100644 index 0000000..06a9b87 --- /dev/null +++ b/sysdeps/m68k/fpu/e_log10.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_log10 +#include <e_acos.c> diff --git a/sysdeps/m68k/fpu/e_log10f.c b/sysdeps/m68k/fpu/e_log10f.c new file mode 100644 index 0000000..3896864 --- /dev/null +++ b/sysdeps/m68k/fpu/e_log10f.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_log10f +#include <e_acosf.c> diff --git a/sysdeps/m68k/fpu/e_log10l.c b/sysdeps/m68k/fpu/e_log10l.c new file mode 100644 index 0000000..6dcfc5a --- /dev/null +++ b/sysdeps/m68k/fpu/e_log10l.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_log10l +#include <e_acosl.c> diff --git a/sysdeps/m68k/fpu/e_log2.c b/sysdeps/m68k/fpu/e_log2.c new file mode 100644 index 0000000..5528922 --- /dev/null +++ b/sysdeps/m68k/fpu/e_log2.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_log2 +#include <e_acos.c> diff --git a/sysdeps/m68k/fpu/e_log2f.c b/sysdeps/m68k/fpu/e_log2f.c new file mode 100644 index 0000000..6b49076 --- /dev/null +++ b/sysdeps/m68k/fpu/e_log2f.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_log2f +#include <e_acosf.c> diff --git a/sysdeps/m68k/fpu/e_log2l.c b/sysdeps/m68k/fpu/e_log2l.c new file mode 100644 index 0000000..4c92a11 --- /dev/null +++ b/sysdeps/m68k/fpu/e_log2l.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_log2l +#include <e_acosl.c> diff --git a/sysdeps/m68k/fpu/e_logf.c b/sysdeps/m68k/fpu/e_logf.c new file mode 100644 index 0000000..bc23217 --- /dev/null +++ b/sysdeps/m68k/fpu/e_logf.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_logf +#include <e_acosf.c> diff --git a/sysdeps/m68k/fpu/e_logl.c b/sysdeps/m68k/fpu/e_logl.c new file mode 100644 index 0000000..03b1830 --- /dev/null +++ b/sysdeps/m68k/fpu/e_logl.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_logl +#include <e_acosl.c> diff --git a/sysdeps/m68k/fpu/e_pow.c b/sysdeps/m68k/fpu/e_pow.c new file mode 100644 index 0000000..0b6cee6 --- /dev/null +++ b/sysdeps/m68k/fpu/e_pow.c @@ -0,0 +1,126 @@ +/* Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> +#include "math_private.h" +#include "mathimpl.h" + +#ifndef SUFF +#define SUFF +#endif +#ifndef float_type +#define float_type double +#endif + +#define CONCATX(a,b) __CONCAT(a,b) +#define s(name) CONCATX(name,SUFF) +#define m81(func) __m81_u(s(func)) + +float_type +s(__ieee754_pow) (float_type x, float_type y) +{ + float_type z; + float_type ax; + unsigned long x_cond, y_cond; + + y_cond = __m81_test (y); + if (y_cond & __M81_COND_ZERO) + return 1.0; + if (y_cond & __M81_COND_NAN) + return x == 1.0 ? x : x + y; + + x_cond = __m81_test (x); + if (x_cond & __M81_COND_NAN) + return x + y; + + if (y_cond & __M81_COND_INF) + { + ax = s(fabs) (x); + if (ax == 1.0) + return ax; + if (ax > 1.0) + return y_cond & __M81_COND_NEG ? 0 : y; + else + return y_cond & __M81_COND_NEG ? -y : 0; + } + + if (s(fabs) (y) == 1.0) + return y_cond & __M81_COND_NEG ? 1 / x : x; + + if (y == 2) + return x * x; + if (y == 0.5 && !(x_cond & __M81_COND_NEG)) + return m81(__ieee754_sqrt) (x); + + if (x == 10.0) + { + __asm ("ftentox%.x %1, %0" : "=f" (z) : "f" (y)); + return z; + } + if (x == 2.0) + { + __asm ("ftwotox%.x %1, %0" : "=f" (z) : "f" (y)); + return z; + } + + ax = s(fabs) (x); + if (x_cond & (__M81_COND_INF | __M81_COND_ZERO) || ax == 1.0) + { + z = ax; + if (y_cond & __M81_COND_NEG) + z = 1 / z; + if (x_cond & __M81_COND_NEG) + { + if (y != m81(__rint) (y)) + { + if (x == -1) + z = (z - z) / (z - z); + } + else + goto maybe_negate; + } + return z; + } + + if (x_cond & __M81_COND_NEG) + { + if (y == m81(__rint) (y)) + { + z = m81(__ieee754_exp) (y * m81(__ieee754_log) (-x)); + maybe_negate: + /* We always use the long double format, since y is already in + this format and rounding won't change the result. */ + { + int32_t exponent; + u_int32_t i0, i1; + GET_LDOUBLE_WORDS (exponent, i0, i1, y); + exponent = (exponent & 0x7fff) - 0x3fff; + if (exponent <= 31 + ? i0 & (1 << (31 - exponent)) + : (exponent <= 63 + && i1 & (1 << (63 - exponent)))) + z = -z; + } + } + else + z = (y - y) / (y - y); + } + else + z = m81(__ieee754_exp) (y * m81(__ieee754_log) (x)); + return z; +} diff --git a/sysdeps/m68k/fpu/e_powf.c b/sysdeps/m68k/fpu/e_powf.c new file mode 100644 index 0000000..3790143 --- /dev/null +++ b/sysdeps/m68k/fpu/e_powf.c @@ -0,0 +1,3 @@ +#define SUFF f +#define float_type float +#include <e_pow.c> diff --git a/sysdeps/m68k/fpu/e_powl.c b/sysdeps/m68k/fpu/e_powl.c new file mode 100644 index 0000000..f71fa34 --- /dev/null +++ b/sysdeps/m68k/fpu/e_powl.c @@ -0,0 +1,3 @@ +#define SUFF l +#define float_type long double +#include <e_pow.c> diff --git a/sysdeps/m68k/fpu/e_rem_pio2.c b/sysdeps/m68k/fpu/e_rem_pio2.c new file mode 100644 index 0000000..1347b04 --- /dev/null +++ b/sysdeps/m68k/fpu/e_rem_pio2.c @@ -0,0 +1,3 @@ +/* Empty. This file is only meant to avoid compiling the file with the + same name in the libm-ieee754 directory. The code is not used since + there is an assembler version for all users of this file. */ diff --git a/sysdeps/m68k/fpu/e_rem_pio2f.c b/sysdeps/m68k/fpu/e_rem_pio2f.c new file mode 100644 index 0000000..1347b04 --- /dev/null +++ b/sysdeps/m68k/fpu/e_rem_pio2f.c @@ -0,0 +1,3 @@ +/* Empty. This file is only meant to avoid compiling the file with the + same name in the libm-ieee754 directory. The code is not used since + there is an assembler version for all users of this file. */ diff --git a/sysdeps/m68k/fpu/e_rem_pio2l.c b/sysdeps/m68k/fpu/e_rem_pio2l.c new file mode 100644 index 0000000..1347b04 --- /dev/null +++ b/sysdeps/m68k/fpu/e_rem_pio2l.c @@ -0,0 +1,3 @@ +/* Empty. This file is only meant to avoid compiling the file with the + same name in the libm-ieee754 directory. The code is not used since + there is an assembler version for all users of this file. */ diff --git a/sysdeps/m68k/fpu/e_remainder.c b/sysdeps/m68k/fpu/e_remainder.c new file mode 100644 index 0000000..aa31bc0 --- /dev/null +++ b/sysdeps/m68k/fpu/e_remainder.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_remainder +#include <e_fmod.c> diff --git a/sysdeps/m68k/fpu/e_remainderf.c b/sysdeps/m68k/fpu/e_remainderf.c new file mode 100644 index 0000000..b04f0c8 --- /dev/null +++ b/sysdeps/m68k/fpu/e_remainderf.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_remainderf +#include <e_fmodf.c> diff --git a/sysdeps/m68k/fpu/e_remainderl.c b/sysdeps/m68k/fpu/e_remainderl.c new file mode 100644 index 0000000..b9dc540 --- /dev/null +++ b/sysdeps/m68k/fpu/e_remainderl.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_remainderl +#include <e_fmodl.c> diff --git a/sysdeps/m68k/fpu/e_scalb.c b/sysdeps/m68k/fpu/e_scalb.c new file mode 100644 index 0000000..88edba1 --- /dev/null +++ b/sysdeps/m68k/fpu/e_scalb.c @@ -0,0 +1,60 @@ +/* Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>. + + 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 <math.h> +#include "math_private.h" +#include "mathimpl.h" + +#ifndef SUFF +#define SUFF +#endif +#ifndef float_type +#define float_type double +#endif + +#define CONCATX(a,b) __CONCAT(a,b) +#define s(name) CONCATX(name,SUFF) +#define m81(func) __m81_u(s(func)) + +float_type +s(__ieee754_scalb) (float_type x, float_type fn) +{ + float_type retval; + unsigned long x_cond = __m81_test (x); + unsigned long fn_cond = __m81_test (fn); + + if ((x_cond | fn_cond) & __M81_COND_NAN) + return x * fn; + + if (fn_cond & __M81_COND_INF) + { + if (!(fn_cond & __M81_COND_NEG)) + return x * fn; + else if (x_cond & __M81_COND_ZERO) + return x; + else + return x / -fn; + } + + if (m81(__rint) (fn) != fn) + return (x - x) / (x - x); + + __asm ("fscale%.x %1, %0" : "=f" (retval) : "f" (fn), "0" (x)); + return retval; +} diff --git a/sysdeps/m68k/fpu/e_scalbf.c b/sysdeps/m68k/fpu/e_scalbf.c new file mode 100644 index 0000000..7943571 --- /dev/null +++ b/sysdeps/m68k/fpu/e_scalbf.c @@ -0,0 +1,3 @@ +#define SUFF f +#define float_type float +#include <e_scalb.c> diff --git a/sysdeps/m68k/fpu/e_scalbl.c b/sysdeps/m68k/fpu/e_scalbl.c new file mode 100644 index 0000000..35fb2dc --- /dev/null +++ b/sysdeps/m68k/fpu/e_scalbl.c @@ -0,0 +1,3 @@ +#define SUFF l +#define float_type long double +#include <e_scalb.c> diff --git a/sysdeps/m68k/fpu/e_sinh.c b/sysdeps/m68k/fpu/e_sinh.c new file mode 100644 index 0000000..c6fed7f --- /dev/null +++ b/sysdeps/m68k/fpu/e_sinh.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_sinh +#include <e_acos.c> diff --git a/sysdeps/m68k/fpu/e_sinhf.c b/sysdeps/m68k/fpu/e_sinhf.c new file mode 100644 index 0000000..b5034b7 --- /dev/null +++ b/sysdeps/m68k/fpu/e_sinhf.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_sinhf +#include <e_acosf.c> diff --git a/sysdeps/m68k/fpu/e_sinhl.c b/sysdeps/m68k/fpu/e_sinhl.c new file mode 100644 index 0000000..2f42d96 --- /dev/null +++ b/sysdeps/m68k/fpu/e_sinhl.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_sinhl +#include <e_acosl.c> diff --git a/sysdeps/m68k/fpu/e_sqrt.c b/sysdeps/m68k/fpu/e_sqrt.c new file mode 100644 index 0000000..70f1971 --- /dev/null +++ b/sysdeps/m68k/fpu/e_sqrt.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_sqrt +#include <e_acos.c> diff --git a/sysdeps/m68k/fpu/e_sqrtf.c b/sysdeps/m68k/fpu/e_sqrtf.c new file mode 100644 index 0000000..5dc1904 --- /dev/null +++ b/sysdeps/m68k/fpu/e_sqrtf.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_sqrtf +#include <e_acosf.c> diff --git a/sysdeps/m68k/fpu/e_sqrtl.c b/sysdeps/m68k/fpu/e_sqrtl.c new file mode 100644 index 0000000..fede102 --- /dev/null +++ b/sysdeps/m68k/fpu/e_sqrtl.c @@ -0,0 +1,2 @@ +#define FUNC __ieee754_sqrtl +#include <e_acosl.c> diff --git a/sysdeps/m68k/fpu/fclrexcpt.c b/sysdeps/m68k/fpu/fclrexcpt.c new file mode 100644 index 0000000..bcd7a3f --- /dev/null +++ b/sysdeps/m68k/fpu/fclrexcpt.c @@ -0,0 +1,50 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <fenv.h> + +int +__feclearexcept (int excepts) +{ + fexcept_t fpsr; + + /* Mask out unsupported bits/exceptions. */ + excepts &= FE_ALL_EXCEPT; + + /* Fetch the fpu status register. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + /* Clear the relevant bits. */ + fpsr &= ~excepts; + + /* Put the new data in effect. */ + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr)); + + /* Success. */ + return 0; +} + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__feclearexcept, __old_feclearexcept) +compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1); +#endif + +versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2); diff --git a/sysdeps/m68k/fpu/fedisblxcpt.c b/sysdeps/m68k/fpu/fedisblxcpt.c new file mode 100644 index 0000000..416e0ba --- /dev/null +++ b/sysdeps/m68k/fpu/fedisblxcpt.c @@ -0,0 +1,39 @@ +/* Disable floating-point exceptions. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@suse.de>, 2000. + + 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 <fenv.h> + +int +fedisableexcept (int excepts) +{ + unsigned int old_exc, new_exc; + + /* Get the current control register contents. */ + __asm__ ("fmove%.l %!,%0" : "=dm" (new_exc)); + + old_exc = (new_exc >> 6) & FE_ALL_EXCEPT; + + excepts &= FE_ALL_EXCEPT; + + new_exc &= ~(excepts << 6); + __asm__ ("fmove%.l %0,%!" : : "dm" (new_exc)); + + return old_exc; +} diff --git a/sysdeps/m68k/fpu/feenablxcpt.c b/sysdeps/m68k/fpu/feenablxcpt.c new file mode 100644 index 0000000..f963acf --- /dev/null +++ b/sysdeps/m68k/fpu/feenablxcpt.c @@ -0,0 +1,39 @@ +/* Enable floating-point exceptions. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@suse.de>, 2000. + + 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 <fenv.h> + +int +feenableexcept (int excepts) +{ + unsigned int new_exc, old_exc; + + /* Get the current control register contents. */ + __asm__ ("fmove%.l %!,%0" : "=dm" (new_exc)); + + old_exc = (new_exc >> 6) & FE_ALL_EXCEPT; + + excepts &= FE_ALL_EXCEPT; + + new_exc |= excepts << 6; + __asm__ ("fmove%.l %0,%!" : : "dm" (new_exc)); + + return old_exc; +} diff --git a/sysdeps/m68k/fpu/fegetenv.c b/sysdeps/m68k/fpu/fegetenv.c new file mode 100644 index 0000000..6c94b07 --- /dev/null +++ b/sysdeps/m68k/fpu/fegetenv.c @@ -0,0 +1,38 @@ +/* Store current floating-point environment. + Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <fenv.h> + +int +__fegetenv (fenv_t *envp) +{ + __asm__ ("fmovem%.l %/fpcr/%/fpsr/%/fpiar,%0" : "=m" (*envp)); + + /* Success. */ + return 0; +} + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__fegetenv, __old_fegetenv) +compat_symbol (libm, __old_fegetenv, fegetenv, GLIBC_2_1); +#endif + +versioned_symbol (libm, __fegetenv, fegetenv, GLIBC_2_2); diff --git a/sysdeps/m68k/fpu/fegetexcept.c b/sysdeps/m68k/fpu/fegetexcept.c new file mode 100644 index 0000000..b34b2c1 --- /dev/null +++ b/sysdeps/m68k/fpu/fegetexcept.c @@ -0,0 +1,32 @@ +/* Get enabled floating-point exceptions. + Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@suse.de>, 2000. + + 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 <fenv.h> + +int +fegetexcept (void) +{ + unsigned int exc; + + /* Get the current control register contents. */ + __asm__ ("fmove%.l %!,%0" : "=dm" (exc)); + + return (exc >> 6) & FE_ALL_EXCEPT; +} diff --git a/sysdeps/m68k/fpu/fegetround.c b/sysdeps/m68k/fpu/fegetround.c new file mode 100644 index 0000000..74fc56f --- /dev/null +++ b/sysdeps/m68k/fpu/fegetround.c @@ -0,0 +1,31 @@ +/* Return current rounding direction. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <fenv.h> + +int +fegetround (void) +{ + int fpcr; + + __asm__ ("fmove%.l %!,%0" : "=dm" (fpcr)); + + return fpcr & FE_UPWARD; +} diff --git a/sysdeps/m68k/fpu/feholdexcpt.c b/sysdeps/m68k/fpu/feholdexcpt.c new file mode 100644 index 0000000..88fb1c5 --- /dev/null +++ b/sysdeps/m68k/fpu/feholdexcpt.c @@ -0,0 +1,39 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <fenv.h> + +int +feholdexcept (fenv_t *envp) +{ + fexcept_t fpcr, fpsr; + + /* Store the environment. */ + __asm__ ("fmovem%.l %/fpcr/%/fpsr/%/fpiar,%0" : "=m" (*envp)); + + /* Now clear all exceptions. */ + fpsr = envp->__status_register & ~FE_ALL_EXCEPT; + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr)); + /* And set all exceptions to non-stop. */ + fpcr = envp->__control_register & ~(FE_ALL_EXCEPT << 6); + __asm__ __volatile__ ("fmove%.l %0,%!" : : "dm" (fpcr)); + + return 0; +} diff --git a/sysdeps/m68k/fpu/fesetenv.c b/sysdeps/m68k/fpu/fesetenv.c new file mode 100644 index 0000000..20653f0 --- /dev/null +++ b/sysdeps/m68k/fpu/fesetenv.c @@ -0,0 +1,60 @@ +/* Install given floating-point environment. + Copyright (C) 1997,99,2000,01,02 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <fenv.h> + +int +__fesetenv (const fenv_t *envp) +{ + fenv_t temp; + + /* Install the environment specified by ENVP. But there are a few + values which we do not want to come from the saved environment. + Therefore, we get the current environment and replace the values + we want to use from the environment specified by the parameter. */ + __asm__ ("fmovem%.l %/fpcr/%/fpsr/%/fpiar,%0" : "=m" (*&temp)); + + temp.__status_register &= ~FE_ALL_EXCEPT; + temp.__control_register &= ~((FE_ALL_EXCEPT << 6) | FE_UPWARD); + if (envp == FE_DFL_ENV) + ; + else if (envp == FE_NOMASK_ENV) + temp.__control_register |= FE_ALL_EXCEPT << 6; + else + { + temp.__control_register |= (envp->__control_register + & ((FE_ALL_EXCEPT << 6) | FE_UPWARD)); + temp.__status_register |= envp->__status_register & FE_ALL_EXCEPT; + } + + __asm__ __volatile__ ("fmovem%.l %0,%/fpcr/%/fpsr/%/fpiar" : : "m" (*&temp)); + + /* Success. */ + return 0; +} + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__fesetenv, __old_fesetenv) +compat_symbol (libm, __old_fesetenv, fesetenv, GLIBC_2_1); +#endif + +libm_hidden_ver (__fesetenv, fesetenv) +versioned_symbol (libm, __fesetenv, fesetenv, GLIBC_2_2); diff --git a/sysdeps/m68k/fpu/fesetround.c b/sysdeps/m68k/fpu/fesetround.c new file mode 100644 index 0000000..956325d --- /dev/null +++ b/sysdeps/m68k/fpu/fesetround.c @@ -0,0 +1,38 @@ +/* Set current rounding direction. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <fenv.h> + +int +fesetround (int round) +{ + fexcept_t fpcr; + + if (round & ~FE_UPWARD) + /* ROUND is no valid rounding mode. */ + return 1; + + __asm__ ("fmove%.l %!,%0" : "=dm" (fpcr)); + fpcr &= ~FE_UPWARD; + fpcr |= round; + __asm__ __volatile__ ("fmove%.l %0,%!" : : "dm" (fpcr)); + + return 0; +} diff --git a/sysdeps/m68k/fpu/feupdateenv.c b/sysdeps/m68k/fpu/feupdateenv.c new file mode 100644 index 0000000..2a68313 --- /dev/null +++ b/sysdeps/m68k/fpu/feupdateenv.c @@ -0,0 +1,50 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <fenv.h> + +int +__feupdateenv (const fenv_t *envp) +{ + fexcept_t fpsr; + + /* Save current exceptions. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + fpsr &= FE_ALL_EXCEPT; + + /* Install new environment. */ + fesetenv (envp); + + /* Raise the saved exception. Incidently for us the implementation + defined format of the values in objects of type fexcept_t is the + same as the ones specified using the FE_* constants. */ + feraiseexcept ((int) fpsr); + + /* Success. */ + return 0; +} + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__feupdateenv, __old_feupdateenv) +compat_symbol (libm, __old_feupdateenv, feupdateenv, GLIBC_2_1); +#endif + +versioned_symbol (libm, __feupdateenv, feupdateenv, GLIBC_2_2); diff --git a/sysdeps/m68k/fpu/fgetexcptflg.c b/sysdeps/m68k/fpu/fgetexcptflg.c new file mode 100644 index 0000000..764b900 --- /dev/null +++ b/sysdeps/m68k/fpu/fgetexcptflg.c @@ -0,0 +1,43 @@ +/* Store current representation for exceptions. + Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <fenv.h> + +int +__fegetexceptflag (fexcept_t *flagp, int excepts) +{ + fexcept_t fpsr; + + /* Get the current exceptions. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + *flagp = fpsr & excepts & FE_ALL_EXCEPT; + + /* Success. */ + return 0; +} + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__fegetexceptflag, __old_fegetexceptflag) +compat_symbol (libm, __old_fegetexceptflag, fegetexceptflag, GLIBC_2_1); +#endif + +versioned_symbol (libm, __fegetexceptflag, fegetexceptflag, GLIBC_2_2); diff --git a/sysdeps/m68k/fpu/fraiseexcpt.c b/sysdeps/m68k/fpu/fraiseexcpt.c new file mode 100644 index 0000000..69f746c --- /dev/null +++ b/sysdeps/m68k/fpu/fraiseexcpt.c @@ -0,0 +1,83 @@ +/* Raise given exceptions. + Copyright (C) 1997,99,2000,01,02 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <fenv.h> +#include <float.h> +#include <math.h> + +int +__feraiseexcept (int excepts) +{ + /* Raise exceptions represented by EXCEPTS. But we must raise only one + signal at a time. It is important that if the overflow/underflow + exception and the divide by zero exception are given at the same + time, the overflow/underflow exception follows the divide by zero + exception. */ + + /* First: invalid exception. */ + if (excepts & FE_INVALID) + { + /* One example of a invalid operation is 0 * Infinity. */ + double d = HUGE_VAL; + __asm__ __volatile__ ("fmul%.s %#0r0,%0; fnop" : "=f" (d) : "0" (d)); + } + + /* Next: division by zero. */ + if (excepts & FE_DIVBYZERO) + { + double d = 1.0; + __asm__ __volatile__ ("fdiv%.s %#0r0,%0; fnop" : "=f" (d) : "0" (d)); + } + + /* Next: overflow. */ + if (excepts & FE_OVERFLOW) + { + long double d = LDBL_MAX; + + __asm__ __volatile__ ("fmul%.x %0,%0; fnop" : "=f" (d) : "0" (d)); + } + + /* Next: underflow. */ + if (excepts & FE_UNDERFLOW) + { + long double d = -LDBL_MAX; + + __asm__ __volatile__ ("fetox%.x %0; fnop" : "=f" (d) : "0" (d)); + } + + /* Last: inexact. */ + if (excepts & FE_INEXACT) + { + long double d = 1.0; + __asm__ __volatile__ ("fdiv%.s %#0r3,%0; fnop" : "=f" (d) : "0" (d)); + } + + /* Success. */ + return 0; +} + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__feraiseexcept, __old_feraiseexcept) +compat_symbol (libm, __old_feraiseexcept, feraiseexcept, GLIBC_2_1); +#endif + +libm_hidden_ver (__feraiseexcept, feraiseexcept) +versioned_symbol (libm, __feraiseexcept, feraiseexcept, GLIBC_2_2); diff --git a/sysdeps/m68k/fpu/fsetexcptflg.c b/sysdeps/m68k/fpu/fsetexcptflg.c new file mode 100644 index 0000000..51b086a --- /dev/null +++ b/sysdeps/m68k/fpu/fsetexcptflg.c @@ -0,0 +1,49 @@ +/* Set floating-point environment exception handling. + Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <fenv.h> +#include <math.h> + +int +__fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fexcept_t fpsr; + + /* Get the current status register. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + /* Install the new exception bits in the Accrued Exception Byte. */ + fpsr &= ~(excepts & FE_ALL_EXCEPT); + fpsr |= *flagp & excepts & FE_ALL_EXCEPT; + + /* Store the new status register. */ + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr)); + + /* Success. */ + return 0; +} + +#include <shlib-compat.h> +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__fesetexceptflag, __old_fesetexceptflag) +compat_symbol (libm, __old_fesetexceptflag, fesetexceptflag, GLIBC_2_1); +#endif + +versioned_symbol (libm, __fesetexceptflag, fesetexceptflag, GLIBC_2_2); diff --git a/sysdeps/m68k/fpu/ftestexcept.c b/sysdeps/m68k/fpu/ftestexcept.c new file mode 100644 index 0000000..3157c90 --- /dev/null +++ b/sysdeps/m68k/fpu/ftestexcept.c @@ -0,0 +1,32 @@ +/* Test exception in current environment. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <fenv.h> + +int +fetestexcept (int excepts) +{ + fexcept_t fpsr; + + /* Get current exceptions. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + return fpsr & excepts & FE_ALL_EXCEPT; +} diff --git a/sysdeps/m68k/fpu/halfulp.c b/sysdeps/m68k/fpu/halfulp.c new file mode 100644 index 0000000..1cc8931 --- /dev/null +++ b/sysdeps/m68k/fpu/halfulp.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/m68k/fpu/k_cos.c b/sysdeps/m68k/fpu/k_cos.c new file mode 100644 index 0000000..dd6c215 --- /dev/null +++ b/sysdeps/m68k/fpu/k_cos.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> +#include "math_private.h" + +#ifndef FUNC +#define FUNC cos +#endif +#ifndef float_type +#define float_type double +#endif + +#define __CONCATX(a,b) __CONCAT(a,b) + +float_type +__CONCATX(__kernel_,FUNC) (x, y) + float_type x; + float_type y; +{ + float_type sin_x, cos_x, sin_y, cos_y; + __asm__ __volatile__ ("fsincosx %2,%0:%1" : "=f" (cos_x), "=f" (sin_x) + : "f" (x)); + __asm__ __volatile__ ("fsincosx %2,%0:%1" : "=f" (cos_y), "=f" (sin_y) + : "f" (y)); + return cos_x * cos_y - sin_x * sin_y; +} diff --git a/sysdeps/m68k/fpu/k_cosf.c b/sysdeps/m68k/fpu/k_cosf.c new file mode 100644 index 0000000..2a366d0 --- /dev/null +++ b/sysdeps/m68k/fpu/k_cosf.c @@ -0,0 +1,3 @@ +#define FUNC cosf +#define float_type float +#include <k_cos.c> diff --git a/sysdeps/m68k/fpu/k_cosl.c b/sysdeps/m68k/fpu/k_cosl.c new file mode 100644 index 0000000..983b665 --- /dev/null +++ b/sysdeps/m68k/fpu/k_cosl.c @@ -0,0 +1,3 @@ +#define FUNC cosl +#define float_type long double +#include <k_cos.c> diff --git a/sysdeps/m68k/fpu/k_rem_pio2.c b/sysdeps/m68k/fpu/k_rem_pio2.c new file mode 100644 index 0000000..1347b04 --- /dev/null +++ b/sysdeps/m68k/fpu/k_rem_pio2.c @@ -0,0 +1,3 @@ +/* Empty. This file is only meant to avoid compiling the file with the + same name in the libm-ieee754 directory. The code is not used since + there is an assembler version for all users of this file. */ diff --git a/sysdeps/m68k/fpu/k_rem_pio2f.c b/sysdeps/m68k/fpu/k_rem_pio2f.c new file mode 100644 index 0000000..1347b04 --- /dev/null +++ b/sysdeps/m68k/fpu/k_rem_pio2f.c @@ -0,0 +1,3 @@ +/* Empty. This file is only meant to avoid compiling the file with the + same name in the libm-ieee754 directory. The code is not used since + there is an assembler version for all users of this file. */ diff --git a/sysdeps/m68k/fpu/k_rem_pio2l.c b/sysdeps/m68k/fpu/k_rem_pio2l.c new file mode 100644 index 0000000..1347b04 --- /dev/null +++ b/sysdeps/m68k/fpu/k_rem_pio2l.c @@ -0,0 +1,3 @@ +/* Empty. This file is only meant to avoid compiling the file with the + same name in the libm-ieee754 directory. The code is not used since + there is an assembler version for all users of this file. */ diff --git a/sysdeps/m68k/fpu/k_sin.c b/sysdeps/m68k/fpu/k_sin.c new file mode 100644 index 0000000..652ca0e --- /dev/null +++ b/sysdeps/m68k/fpu/k_sin.c @@ -0,0 +1,45 @@ +/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> +#include "math_private.h" + +#ifndef FUNC +#define FUNC sin +#endif +#ifndef float_type +#define float_type double +#endif + +#define __CONCATX(a,b) __CONCAT(a,b) + +float_type +__CONCATX(__kernel_,FUNC) (x, y, iy) + float_type x; + float_type y; + int iy; +{ + float_type sin_x, cos_x, sin_y, cos_y; + if (iy == 0) + return __m81_u(__CONCATX(__,FUNC)) (x); + __asm__ __volatile__ ("fsincosx %2,%0:%1" : "=f" (cos_x), "=f" (sin_x) + : "f" (x)); + __asm__ __volatile__ ("fsincosx %2,%0:%1" : "=f" (cos_y), "=f" (sin_y) + : "f" (y)); + return sin_x * cos_y + cos_x * sin_y; +} diff --git a/sysdeps/m68k/fpu/k_sinf.c b/sysdeps/m68k/fpu/k_sinf.c new file mode 100644 index 0000000..7050347 --- /dev/null +++ b/sysdeps/m68k/fpu/k_sinf.c @@ -0,0 +1,3 @@ +#define FUNC sinf +#define float_type float +#include <k_sin.c> diff --git a/sysdeps/m68k/fpu/k_sinl.c b/sysdeps/m68k/fpu/k_sinl.c new file mode 100644 index 0000000..5a647ca --- /dev/null +++ b/sysdeps/m68k/fpu/k_sinl.c @@ -0,0 +1,3 @@ +#define FUNC sinl +#define float_type long double +#include <k_sin.c> diff --git a/sysdeps/m68k/fpu/k_tan.c b/sysdeps/m68k/fpu/k_tan.c new file mode 100644 index 0000000..28f6a80 --- /dev/null +++ b/sysdeps/m68k/fpu/k_tan.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> +#include "math_private.h" + +#ifndef FUNC +#define FUNC tan +#endif +#ifndef float_type +#define float_type double +#endif + +#define __CONCATX(a,b) __CONCAT(a,b) + +float_type +__CONCATX(__kernel_,FUNC) (x, y, iy) + float_type x; + float_type y; + int iy; +{ + float_type tan_x, tan_y; + tan_x = __m81_u(__CONCATX(__,FUNC)) (x); + tan_y = __m81_u(__CONCATX(__,FUNC)) (y); + if (iy > 0) + return (tan_x + tan_y) / (1 - tan_x * tan_y); + else + return (tan_x * tan_y - 1) / (tan_x + tan_y); +} diff --git a/sysdeps/m68k/fpu/k_tanf.c b/sysdeps/m68k/fpu/k_tanf.c new file mode 100644 index 0000000..777af1b --- /dev/null +++ b/sysdeps/m68k/fpu/k_tanf.c @@ -0,0 +1,3 @@ +#define FUNC tanf +#define float_type float +#include <k_tan.c> diff --git a/sysdeps/m68k/fpu/k_tanl.c b/sysdeps/m68k/fpu/k_tanl.c new file mode 100644 index 0000000..f2570e6 --- /dev/null +++ b/sysdeps/m68k/fpu/k_tanl.c @@ -0,0 +1,3 @@ +#define FUNC tanl +#define float_type long double +#include <k_tan.c> diff --git a/sysdeps/m68k/fpu/libm-test-ulps b/sysdeps/m68k/fpu/libm-test-ulps new file mode 100644 index 0000000..cab9501 --- /dev/null +++ b/sysdeps/m68k/fpu/libm-test-ulps @@ -0,0 +1,1165 @@ +# Begin of automatic generation + +# acosh +Test "acosh (7) == 2.63391579384963341725009269461593689": +ildouble: 1 +ldouble: 1 + +# asinh +Test "asinh (0.75) == 0.693147180559945309417232121458176568": +ildouble: 1 +ldouble: 1 + +# atan2 +Test "atan2 (0.390625, .00029) == 1.57005392693128974780151246612928941": +ildouble: 1 +ldouble: 1 +Test "atan2 (1.390625, 0.9296875) == 0.981498387184244311516296577615519772": +ildouble: 1 +ldouble: 1 + +# atanh +Test "atanh (0.75) == 0.972955074527656652552676371721589865": +ildouble: 1 +ldouble: 1 + +# cacos +Test "Real part of: cacos (0.75 + 1.25 i) == 1.11752014915610270578240049553777969 - 1.13239363160530819522266333696834467 i": +float: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: cacos (0.75 + 1.25 i) == 1.11752014915610270578240049553777969 - 1.13239363160530819522266333696834467 i": +float: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +# cacosh +Test "Real part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i": +double: 1 +float: 7 +idouble: 1 +ifloat: 7 +ildouble: 6 +ldouble: 6 +Test "Imaginary part of: cacosh (-2 - 3 i) == -1.9833870299165354323470769028940395 + 2.1414491111159960199416055713254211 i": +double: 1 +idouble: 1 +ildouble: 2 +ldouble: 2 +Test "Real part of: cacosh (0.75 + 1.25 i) == 1.13239363160530819522266333696834467 + 1.11752014915610270578240049553777969 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: cacosh (0.75 + 1.25 i) == 1.13239363160530819522266333696834467 + 1.11752014915610270578240049553777969 i": +float: 1 +ifloat: 1 + +# casin +Test "Real part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i": +double: 1 +float: 5 +idouble: 1 +ifloat: 5 +ildouble: 3 +ldouble: 3 +Test "Imaginary part of: casin (0.75 + 1.25 i) == 0.453276177638793913448921196101971749 + 1.13239363160530819522266333696834467 i": +float: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +# casinh +Test "Real part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i": +double: 6 +float: 19 +idouble: 6 +ifloat: 19 +ildouble: 5 +ldouble: 5 +Test "Imaginary part of: casinh (-2 - 3 i) == -1.9686379257930962917886650952454982 - 0.96465850440760279204541105949953237 i": +double: 13 +float: 1 +idouble: 13 +ifloat: 1 +ildouble: 6 +ldouble: 6 +Test "Real part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: casinh (0.75 + 1.25 i) == 1.03171853444778027336364058631006594 + 0.911738290968487636358489564316731207 i": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +# catan +Test "Imaginary part of: catan (-2 - 3 i) == -1.4099210495965755225306193844604208 - 0.22907268296853876629588180294200276 i": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "Real part of: catan (0.75 + 1.25 i) == 1.10714871779409050301706546017853704 + 0.549306144334054845697622618461262852 i": +ildouble: 1 +ldouble: 1 + +# catanh +Test "Real part of: catanh (-2 - 3 i) == -0.14694666622552975204743278515471595 - 1.3389725222944935611241935759091443 i": +ildouble: 1 +ldouble: 1 + +# cbrt +Test "cbrt (-0.001) == -0.1": +ildouble: 1 +ldouble: 1 +Test "cbrt (0.9921875) == 0.997389022060725270579075195353955217": +ildouble: 1 +ldouble: 1 + +# ccos +Test "Real part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: ccos (-2 - 3 i) == -4.18962569096880723013255501961597373 - 9.10922789375533659797919726277886212 i": +float: 1 +ifloat: 1 +Test "Real part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: ccos (0.75 + 1.25 i) == 1.38173873063425888530729933139078645 - 1.09193013555397466170919531722024128 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +# ccosh +Test "Real part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: ccosh (-2 - 3 i) == -3.72454550491532256547397070325597253 + 0.511822569987384608834463849801875634 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Real part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: ccosh (0.75 + 1.25 i) == 0.408242591877968807788852146397499084 + 0.780365930845853240391326216300863152 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +# cexp +Test "Real part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: cexp (-2.0 - 3.0 i) == -0.13398091492954261346140525546115575 - 0.019098516261135196432576240858800925 i": +float: 1 +ifloat: 1 +Test "Real part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i": +float: 2 +ifloat: 2 +Test "Imaginary part of: cexp (0.75 + 1.25 i) == 0.667537446429131586942201977015932112 + 2.00900045494094876258347228145863909 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +# clog +Test "Real part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog (0.75 + 1.25 i) == 0.376885901188190075998919126749298416 + 1.03037682652431246378774332703115153 i": +ildouble: 1 +ldouble: 1 + +# clog10 +Test "Imaginary part of: clog10 (-0 + inf i) == inf + pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (-0 - inf i) == inf - pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Real part of: clog10 (-2 - 3 i) == 0.556971676153418384603252578971164214 - 0.937554462986374708541507952140189646 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (-3 + inf i) == inf + pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (-3 - inf i) == inf - pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (-inf + 0 i) == inf + pi*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (-inf + 1 i) == inf + pi*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (-inf + inf i) == inf + 3/4 pi*log10(e) i": +double: 1 +idouble: 1 +Test "Imaginary part of: clog10 (-inf - 0 i) == inf - pi*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (-inf - 1 i) == inf - pi*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (0 + inf i) == inf + pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (0 - inf i) == inf - pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Real part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: clog10 (0.75 + 1.25 i) == 0.163679467193165171449476605077428975 + 0.447486970040493067069984724340855636 i": +double: 1 +idouble: 1 +ildouble: 2 +ldouble: 2 +Test "Imaginary part of: clog10 (3 + inf i) == inf + pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (3 - inf i) == inf - pi/2*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (inf + inf i) == inf + pi/4*log10(e) i": +float: 1 +ifloat: 1 +Test "Imaginary part of: clog10 (inf - inf i) == inf - pi/4*log10(e) i": +float: 1 +ifloat: 1 + +# cos +Test "cos (M_PI_6l * 2.0) == 0.5": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "cos (M_PI_6l * 4.0) == -0.5": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "cos (pi/2) == 0": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +# cpow +Test "Real part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.0 + 1.0 i) == 0.331825439177608832276067945276730566 + 0.131338600281188544930936345230903032 i": +float: 1 +ifloat: 1 +Test "Real part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i": +float: 1 +ifloat: 1 +ildouble: 9 +ldouble: 9 +Test "Imaginary part of: cpow (0.75 + 1.25 i, 0.75 + 1.25 i) == 0.117506293914473555420279832210420483 + 0.346552747708338676483025352060418001 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i": +float: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 +Test "Imaginary part of: cpow (0.75 + 1.25 i, 1.0 + 0.0 i) == 0.75 + 1.25 i": +float: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 +Test "Real part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 15 +ldouble: 15 +Test "Imaginary part of: cpow (0.75 + 1.25 i, 1.0 + 1.0 i) == 0.0846958290317209430433805274189191353 + 0.513285749182902449043287190519090481 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Real part of: cpow (2 + 0 i, 10 + 0 i) == 1024.0 + 0.0 i": +ildouble: 5 +ldouble: 5 +Test "Real part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 4 +ldouble: 4 +Test "Imaginary part of: cpow (2 + 3 i, 4 + 0 i) == -119.0 - 120.0 i": +float: 6 +ifloat: 6 +ildouble: 2 +ldouble: 2 +Test "Real part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: cpow (e + 0 i, 0 + 2 * M_PIl i) == 1.0 + 0.0 i": +double: 2 +float: 3 +idouble: 2 +ifloat: 3 +ildouble: 1 +ldouble: 1 + +# csin +Test "Real part of: csin (-2 - 3 i) == -9.15449914691142957346729954460983256 + 4.16890695996656435075481305885375484 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: csin (-2 - 3 i) == -9.15449914691142957346729954460983256 + 4.16890695996656435075481305885375484 i": +float: 1 +ifloat: 1 +Test "Real part of: csin (0.75 + 1.25 i) == 1.28722291002649188575873510790565441 + 1.17210635989270256101081285116138863 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: csin (0.75 + 1.25 i) == 1.28722291002649188575873510790565441 + 1.17210635989270256101081285116138863 i": +float: 1 +ifloat: 1 + +# csinh +Test "Real part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i": +float: 1 +ifloat: 1 +Test "Imaginary part of: csinh (-2 - 3 i) == 3.59056458998577995201256544779481679 - 0.530921086248519805267040090660676560 i": +float: 1 +ifloat: 1 +Test "Real part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: csinh (0.75 + 1.25 i) == 0.259294854551162779153349830618433028 + 1.22863452409509552219214606515777594 i": +float: 1 +ifloat: 1 + +# ctan +Test "Real part of: ctan (-2 - 3 i) == 0.376402564150424829275122113032269084e-2 - 1.00323862735360980144635859782192726 i": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 +Test "Real part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: ctan (0.75 + 1.25 i) == 0.160807785916206426725166058173438663 + 0.975363285031235646193581759755216379 i": +ildouble: 2 +ldouble: 2 + +# ctanh +Test "Imaginary part of: ctanh (-2 - 3 i) == -0.965385879022133124278480269394560686 + 0.988437503832249372031403430350121098e-2 i": +ildouble: 1 +ldouble: 1 +Test "Imaginary part of: ctanh (0 + pi/4 i) == 0.0 + 1.0 i": +double: 1 +idouble: 1 +Test "Imaginary part of: ctanh (0.75 + 1.25 i) == 1.37260757053378320258048606571226857 + 0.385795952609750664177596760720790220 i": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +# erfc +Test "erfc (0.75) == 0.288844366346484868401062165408589223": +float: 1 +ifloat: 1 +Test "erfc (1.25) == 0.0770998717435417698634765188027188596": +ildouble: 1 +ldouble: 1 +Test "erfc (4.125) == 0.542340079956506600531223408575531062e-8": +float: 1 +ifloat: 1 + +# expm1 +Test "expm1 (1) == M_El - 1.0": +ildouble: 1 +ldouble: 1 + +# gamma +Test "gamma (-0.5) == log(2*sqrt(pi))": +ildouble: 1 +ldouble: 1 +Test "gamma (0.5) == log(sqrt(pi))": +ildouble: 1 +ldouble: 1 +Test "gamma (3) == M_LN2l": +ildouble: 1 +ldouble: 1 + +# hypot +Test "hypot (-0.7, -12.4) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 +Test "hypot (-0.7, 12.4) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 +Test "hypot (-12.4, -0.7) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 +Test "hypot (-12.4, 0.7) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 +Test "hypot (0.7, -12.4) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 +Test "hypot (0.7, 12.4) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 +Test "hypot (12.4, -0.7) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 +Test "hypot (12.4, 0.7) == 12.419742348374220601176836866763271": +float: 1 +ifloat: 1 + +# j0 +Test "j0 (-4.0) == -3.9714980986384737228659076845169804197562E-1": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "j0 (0.75) == 0.864242275166648623555731103820923211": +float: 1 +ifloat: 1 +Test "j0 (1.5) == 0.511827671735918128749051744283411720": +float: 1 +ifloat: 1 +Test "j0 (10.0) == -0.245935764451348335197760862485328754": +double: 1 +idouble: 1 +Test "j0 (4.0) == -3.9714980986384737228659076845169804197562E-1": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +# j1 +Test "j1 (-1.0) == -0.440050585744933515959682203718914913": +float: 1 +ifloat: 1 +Test "j1 (1.0) == 0.440050585744933515959682203718914913": +float: 1 +ifloat: 1 +Test "j1 (1.5) == 0.557936507910099641990121213156089400": +float: 1 +ifloat: 1 +Test "j1 (10.0) == 0.0434727461688614366697487680258592883": +float: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 +Test "j1 (2.0) == 0.576724807756873387202448242269137087": +float: 1 +ifloat: 1 +Test "j1 (8.0) == 0.234636346853914624381276651590454612": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +# jn +Test "jn (0, -4.0) == -3.9714980986384737228659076845169804197562E-1": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "jn (0, 0.75) == 0.864242275166648623555731103820923211": +float: 1 +ifloat: 1 +Test "jn (0, 1.5) == 0.511827671735918128749051744283411720": +float: 1 +ifloat: 1 +Test "jn (0, 10.0) == -0.245935764451348335197760862485328754": +double: 1 +idouble: 1 +Test "jn (0, 4.0) == -3.9714980986384737228659076845169804197562E-1": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "jn (1, -1.0) == -0.440050585744933515959682203718914913": +float: 1 +ifloat: 1 +Test "jn (1, 1.0) == 0.440050585744933515959682203718914913": +float: 1 +ifloat: 1 +Test "jn (1, 1.5) == 0.557936507910099641990121213156089400": +float: 1 +ifloat: 1 +Test "jn (1, 10.0) == 0.0434727461688614366697487680258592883": +float: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 +Test "jn (1, 2.0) == 0.576724807756873387202448242269137087": +float: 1 +ifloat: 1 +Test "jn (1, 8.0) == 0.234636346853914624381276651590454612": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "jn (10, -1.0) == 0.263061512368745320699785368779050294e-9": +float: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 +Test "jn (10, 0.125) == 0.250543369809369890173993791865771547e-18": +float: 1 +ifloat: 1 +Test "jn (10, 0.75) == 0.149621713117596814698712483621682835e-10": +float: 2 +ifloat: 2 +ildouble: 2 +ldouble: 2 +Test "jn (10, 1.0) == 0.263061512368745320699785368779050294e-9": +float: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 +Test "jn (10, 10.0) == 0.207486106633358857697278723518753428": +double: 1 +float: 5 +idouble: 1 +ifloat: 5 +ildouble: 2 +ldouble: 2 +Test "jn (10, 2.0) == 0.251538628271673670963516093751820639e-6": +float: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 +Test "jn (3, -1.0) == -0.0195633539826684059189053216217515083": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "jn (3, 1.0) == 0.0195633539826684059189053216217515083": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "jn (3, 10.0) == 0.0583793793051868123429354784103409563": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "jn (3, 2.0) == 0.128943249474402051098793332969239835": +ildouble: 1 +ldouble: 1 + +# lgamma +Test "lgamma (-0.5) == log(2*sqrt(pi))": +ildouble: 1 +ldouble: 1 +Test "lgamma (0.5) == log(sqrt(pi))": +ildouble: 1 +ldouble: 1 +Test "lgamma (0.7) == 0.260867246531666514385732417016759578": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "lgamma (1.2) == -0.853740900033158497197028392998854470e-1": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 +Test "lgamma (3) == M_LN2l": +ildouble: 1 +ldouble: 1 + +# log +Test "log (0.75) == -0.287682072451780927439219005993827432": +ildouble: 1 +ldouble: 1 +Test "log (2) == M_LN2l": +ildouble: 1 +ldouble: 1 +Test "log (e) == 1": +float: 1 +ifloat: 1 + +# log10 +Test "log10 (0.75) == -0.124938736608299953132449886193870744": +ildouble: 2 +ldouble: 2 +Test "log10 (e) == log10(e)": +float: 1 +ifloat: 1 + +# log1p +Test "log1p (-0.25) == -0.287682072451780927439219005993827432": +ildouble: 1 +ldouble: 1 + +# log2 +Test "log2 (0.75) == -.415037499278843818546261056052183492": +ildouble: 1 +ldouble: 1 + +# pow +Test "pow (0.75, 1.25) == 0.697953644326574699205914060237425566": +ildouble: 1 +ldouble: 1 + +# sincos +Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.5 in cos_res": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "sincos (M_PI_6l*2.0, &sin_res, &cos_res) puts 0.86602540378443864676372317075293616 in sin_res": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "sincos (pi/2, &sin_res, &cos_res) puts 0 in cos_res": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +# sinh +Test "sinh (0.75) == 0.822316731935829980703661634446913849": +ildouble: 1 +ldouble: 1 + +# tan +Test "tan (0.75) == 0.931596459944072461165202756573936428": +ildouble: 1 +ldouble: 1 +Test "tan (pi/4) == 1": +double: 1 +idouble: 1 + +# tgamma +Test "tgamma (-0.5) == -2 sqrt (pi)": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "tgamma (0.5) == sqrt (pi)": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "tgamma (0.7) == 1.29805533264755778568117117915281162": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "tgamma (4) == 6": +ildouble: 1 +ldouble: 1 + +# y0 +Test "y0 (0.125) == -1.38968062514384052915582277745018693": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "y0 (0.75) == -0.137172769385772397522814379396581855": +double: 1 +idouble: 1 +ildouble: 2 +ldouble: 2 +Test "y0 (1.0) == 0.0882569642156769579829267660235151628": +ildouble: 1 +ldouble: 1 +Test "y0 (1.5) == 0.382448923797758843955068554978089862": +ildouble: 1 +ldouble: 1 +Test "y0 (10.0) == 0.0556711672835993914244598774101900481": +ildouble: 1 +ldouble: 1 +Test "y0 (2.0) == 0.510375672649745119596606592727157873": +float: 1 +ifloat: 1 +Test "y0 (8.0) == 0.223521489387566220527323400498620359": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +# y1 +Test "y1 (0.125) == -5.19993611253477499595928744876579921": +ildouble: 1 +ldouble: 1 +Test "y1 (1.0) == -0.781212821300288716547150000047964821": +double: 1 +idouble: 1 +Test "y1 (10.0) == 0.249015424206953883923283474663222803": +float: 1 +ifloat: 1 +Test "y1 (2.0) == -0.107032431540937546888370772277476637": +float: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 +Test "y1 (8.0) == -0.158060461731247494255555266187483550": +ildouble: 1 +ldouble: 1 + +# yn +Test "yn (0, 0.125) == -1.38968062514384052915582277745018693": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "yn (0, 0.75) == -0.137172769385772397522814379396581855": +double: 1 +idouble: 1 +ildouble: 2 +ldouble: 2 +Test "yn (0, 1.0) == 0.0882569642156769579829267660235151628": +ildouble: 1 +ldouble: 1 +Test "yn (0, 1.5) == 0.382448923797758843955068554978089862": +ildouble: 1 +ldouble: 1 +Test "yn (0, 10.0) == 0.0556711672835993914244598774101900481": +ildouble: 1 +ldouble: 1 +Test "yn (0, 2.0) == 0.510375672649745119596606592727157873": +float: 1 +ifloat: 1 +Test "yn (0, 8.0) == 0.223521489387566220527323400498620359": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "yn (1, 0.125) == -5.19993611253477499595928744876579921": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 +Test "yn (1, 0.75) == -1.03759455076928541973767132140642198": +float: 1 +ifloat: 1 +Test "yn (1, 1.0) == -0.781212821300288716547150000047964821": +double: 1 +idouble: 1 +Test "yn (1, 10.0) == 0.249015424206953883923283474663222803": +float: 1 +ifloat: 1 +Test "yn (1, 2.0) == -0.107032431540937546888370772277476637": +float: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 +Test "yn (1, 8.0) == -0.158060461731247494255555266187483550": +ildouble: 1 +ldouble: 1 +Test "yn (10, 0.125) == -127057845771019398.252538486899753195": +double: 1 +idouble: 1 +ildouble: 2 +ldouble: 2 +Test "yn (10, 0.75) == -2133501638.90573424452445412893839236": +float: 1 +ifloat: 1 +ildouble: 4 +ldouble: 4 +Test "yn (10, 10.0) == -0.359814152183402722051986577343560609": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +Test "yn (3, 0.125) == -2612.69757350066712600220955744091741": +ildouble: 1 +ldouble: 1 +Test "yn (3, 0.75) == -12.9877176234475433186319774484809207": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 +Test "yn (3, 2.0) == -1.12778377684042778608158395773179238": +float: 1 +ifloat: 1 + +# Maximal error of functions: +Function: "acosh": +ildouble: 1 +ldouble: 1 + +Function: "asinh": +ildouble: 1 +ldouble: 1 + +Function: "atan2": +ildouble: 1 +ldouble: 1 + +Function: "atanh": +ildouble: 1 +ldouble: 1 + +Function: Real part of "cacos": +float: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "cacos": +float: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "cacosh": +double: 1 +float: 7 +idouble: 1 +ifloat: 7 +ildouble: 6 +ldouble: 6 + +Function: Imaginary part of "cacosh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "casin": +double: 1 +float: 5 +idouble: 1 +ifloat: 5 +ildouble: 3 +ldouble: 3 + +Function: Imaginary part of "casin": +float: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: Real part of "casinh": +double: 6 +float: 19 +idouble: 6 +ifloat: 19 +ildouble: 5 +ldouble: 5 + +Function: Imaginary part of "casinh": +double: 13 +float: 1 +idouble: 13 +ifloat: 1 +ildouble: 6 +ldouble: 6 + +Function: Real part of "catan": +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "catan": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 + +Function: Real part of "catanh": +ildouble: 1 +ldouble: 1 + +Function: "cbrt": +ildouble: 1 +ldouble: 1 + +Function: Real part of "ccos": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "ccos": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "ccosh": +float: 1 +ifloat: 1 + +Function: Imaginary part of "ccosh": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "cexp": +float: 2 +ifloat: 2 + +Function: Imaginary part of "cexp": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "clog": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "clog": +ildouble: 1 +ldouble: 1 + +Function: Real part of "clog10": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "clog10": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "cos": +double: 2 +float: 1 +idouble: 2 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Real part of "cpow": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 15 +ldouble: 15 + +Function: Imaginary part of "cpow": +double: 2 +float: 6 +idouble: 2 +ifloat: 6 +ildouble: 2 +ldouble: 2 + +Function: Real part of "csin": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "csin": +float: 1 +ifloat: 1 + +Function: Real part of "csinh": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "csinh": +float: 1 +ifloat: 1 + +Function: Real part of "ctan": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: Imaginary part of "ctan": +ildouble: 2 +ldouble: 2 + +Function: Imaginary part of "ctanh": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "erfc": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "expm1": +ildouble: 1 +ldouble: 1 + +Function: "gamma": +ildouble: 1 +ldouble: 1 + +Function: "hypot": +float: 1 +ifloat: 1 + +Function: "j0": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "j1": +float: 2 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "jn": +double: 1 +float: 5 +idouble: 1 +ifloat: 5 +ildouble: 2 +ldouble: 2 + +Function: "lgamma": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "log": +float: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "log10": +float: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "log1p": +ildouble: 1 +ldouble: 1 + +Function: "log2": +ildouble: 1 +ldouble: 1 + +Function: "pow": +ildouble: 1 +ldouble: 1 + +Function: "sincos": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "sinh": +ildouble: 1 +ldouble: 1 + +Function: "tan": +double: 1 +idouble: 1 +ildouble: 1 +ldouble: 1 + +Function: "tgamma": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 1 +ldouble: 1 + +Function: "y0": +double: 1 +float: 1 +idouble: 1 +ifloat: 1 +ildouble: 2 +ldouble: 2 + +Function: "y1": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 1 +ldouble: 1 + +Function: "yn": +double: 1 +float: 2 +idouble: 1 +ifloat: 2 +ildouble: 4 +ldouble: 4 + +# end of automatic generation diff --git a/sysdeps/m68k/fpu/mathimpl.h b/sysdeps/m68k/fpu/mathimpl.h new file mode 100644 index 0000000..bbcaf84 --- /dev/null +++ b/sysdeps/m68k/fpu/mathimpl.h @@ -0,0 +1,94 @@ +/* Definitions of libc internal inline math functions implemented + by the m68881/2. + Copyright (C) 1991,92,93,94,96,97,98,99 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +/* This file contains the definitions of the inline math functions that + are only used internally inside libm, not visible to the user. */ + +__inline_mathop (__ieee754_acos, acos) +__inline_mathop (__ieee754_asin, asin) +__inline_mathop (__ieee754_cosh, cosh) +__inline_mathop (__ieee754_sinh, sinh) +__inline_mathop (__ieee754_exp, etox) +__inline_mathop (__ieee754_exp2, twotox) +__inline_mathop (__ieee754_exp10, tentox) +__inline_mathop (__ieee754_log10, log10) +__inline_mathop (__ieee754_log2, log2) +__inline_mathop (__ieee754_log, logn) +__inline_mathop (__ieee754_sqrt, sqrt) +__inline_mathop (__ieee754_atanh, atanh) + +__m81_defun (double, __ieee754_remainder, (double __x, double __y)) +{ + double __result; + __asm ("frem%.x %1, %0" : "=f" (__result) : "f" (__y), "0" (__x)); + return __result; +} + +__m81_defun (float, __ieee754_remainderf, (float __x, float __y)) +{ + float __result; + __asm ("frem%.x %1, %0" : "=f" (__result) : "f" (__y), "0" (__x)); + return __result; +} + +__m81_defun (long double, + __ieee754_remainderl, (long double __x, long double __y)) +{ + long double __result; + __asm ("frem%.x %1, %0" : "=f" (__result) : "f" (__y), "0" (__x)); + return __result; +} + +__m81_defun (double, __ieee754_fmod, (double __x, double __y)) +{ + double __result; + __asm ("fmod%.x %1, %0" : "=f" (__result) : "f" (__y), "0" (__x)); + return __result; +} + +__m81_defun (float, __ieee754_fmodf, (float __x, float __y)) +{ + float __result; + __asm ("fmod%.x %1, %0" : "=f" (__result) : "f" (__y), "0" (__x)); + return __result; +} + +__m81_defun (long double, + __ieee754_fmodl, (long double __x, long double __y)) +{ + long double __result; + __asm ("fmod%.x %1, %0" : "=f" (__result) : "f" (__y), "0" (__x)); + return __result; +} + +/* Get the m68881 condition codes, to quickly check multiple conditions. */ +static __inline__ unsigned long +__m81_test (long double __val) +{ + unsigned long __fpsr; + __asm ("ftst%.x %1; fmove%.l %/fpsr,%0" : "=dm" (__fpsr) : "f" (__val)); + return __fpsr; +} + +/* Bit values returned by __m81_test. */ +#define __M81_COND_NAN (1 << 24) +#define __M81_COND_INF (2 << 24) +#define __M81_COND_ZERO (4 << 24) +#define __M81_COND_NEG (8 << 24) diff --git a/sysdeps/m68k/fpu/mpa.c b/sysdeps/m68k/fpu/mpa.c new file mode 100644 index 0000000..1cc8931 --- /dev/null +++ b/sysdeps/m68k/fpu/mpa.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/m68k/fpu/mpatan.c b/sysdeps/m68k/fpu/mpatan.c new file mode 100644 index 0000000..1cc8931 --- /dev/null +++ b/sysdeps/m68k/fpu/mpatan.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/m68k/fpu/mpatan2.c b/sysdeps/m68k/fpu/mpatan2.c new file mode 100644 index 0000000..1cc8931 --- /dev/null +++ b/sysdeps/m68k/fpu/mpatan2.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/m68k/fpu/mpexp.c b/sysdeps/m68k/fpu/mpexp.c new file mode 100644 index 0000000..1cc8931 --- /dev/null +++ b/sysdeps/m68k/fpu/mpexp.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/m68k/fpu/mplog.c b/sysdeps/m68k/fpu/mplog.c new file mode 100644 index 0000000..1cc8931 --- /dev/null +++ b/sysdeps/m68k/fpu/mplog.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/m68k/fpu/mpsqrt.c b/sysdeps/m68k/fpu/mpsqrt.c new file mode 100644 index 0000000..1cc8931 --- /dev/null +++ b/sysdeps/m68k/fpu/mpsqrt.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/m68k/fpu/mptan.c b/sysdeps/m68k/fpu/mptan.c new file mode 100644 index 0000000..1cc8931 --- /dev/null +++ b/sysdeps/m68k/fpu/mptan.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/m68k/fpu/s_atan.c b/sysdeps/m68k/fpu/s_atan.c new file mode 100644 index 0000000..8cca490 --- /dev/null +++ b/sysdeps/m68k/fpu/s_atan.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> + +#ifndef FUNC +#define FUNC atan +#endif +#ifndef float_type +#define float_type double +#endif + +#define __CONCATX(a,b) __CONCAT(a,b) + +float_type +__CONCATX(__,FUNC) (x) + float_type x; +{ + return __m81_u(__CONCATX(__,FUNC))(x); +} + +#define weak_aliasx(a,b) weak_alias(a,b) +weak_aliasx (__CONCATX(__,FUNC), FUNC) diff --git a/sysdeps/m68k/fpu/s_atanf.c b/sysdeps/m68k/fpu/s_atanf.c new file mode 100644 index 0000000..c98559a --- /dev/null +++ b/sysdeps/m68k/fpu/s_atanf.c @@ -0,0 +1,5 @@ +#ifndef FUNC +#define FUNC atanf +#endif +#define float_type float +#include <s_atan.c> diff --git a/sysdeps/m68k/fpu/s_atanl.c b/sysdeps/m68k/fpu/s_atanl.c new file mode 100644 index 0000000..b7e608a --- /dev/null +++ b/sysdeps/m68k/fpu/s_atanl.c @@ -0,0 +1,5 @@ +#ifndef FUNC +#define FUNC atanl +#endif +#define float_type long double +#include <s_atan.c> diff --git a/sysdeps/m68k/fpu/s_ccos.c b/sysdeps/m68k/fpu/s_ccos.c new file mode 100644 index 0000000..d302d3d --- /dev/null +++ b/sysdeps/m68k/fpu/s_ccos.c @@ -0,0 +1,73 @@ +/* Complex cosine function. m68k fpu version + Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>. + + 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 <complex.h> +#include <math.h> +#include "mathimpl.h" + +#ifndef SUFF +#define SUFF +#endif +#ifndef float_type +#define float_type double +#endif + +#define CONCATX(a,b) __CONCAT(a,b) +#define s(name) CONCATX(name,SUFF) +#define m81(func) __m81_u(s(func)) + +__complex__ float_type +s(__ccos) (__complex__ float_type x) +{ + __complex__ float_type retval; + unsigned long rx_cond = __m81_test (__real__ x); + + if ((rx_cond & (__M81_COND_INF|__M81_COND_NAN)) == 0) + { + /* Real part is finite. */ + float_type sin_rx, cos_rx; + + __asm ("fsincos%.x %2,%1:%0" : "=f" (sin_rx), "=f" (cos_rx) + : "f" (__real__ x)); + __real__ retval = cos_rx * m81(__ieee754_cosh) (__imag__ x); + if (rx_cond & __M81_COND_ZERO) + __imag__ retval = (m81(__signbit) (__imag__ x) + ? __real__ x : -__real__ x); + else + __imag__ retval = -sin_rx * m81(__ieee754_sinh) (__imag__ x); + } + else + { + unsigned long ix_cond = __m81_test (__imag__ x); + + if (ix_cond & __M81_COND_INF) + __real__ retval = s(fabs) (__imag__ x); + else + __real__ retval = __real__ x - __real__ x; + if (ix_cond & __M81_COND_ZERO) + __imag__ retval = __imag__ x; + else + __imag__ retval = __real__ x - __real__ x; + } + + return retval; +} +#define weak_aliasx(a,b) weak_alias(a,b) +weak_aliasx (s(__ccos), s(ccos)) diff --git a/sysdeps/m68k/fpu/s_ccosf.c b/sysdeps/m68k/fpu/s_ccosf.c new file mode 100644 index 0000000..f5e8a41 --- /dev/null +++ b/sysdeps/m68k/fpu/s_ccosf.c @@ -0,0 +1,3 @@ +#define SUFF f +#define float_type float +#include <s_ccos.c> diff --git a/sysdeps/m68k/fpu/s_ccosh.c b/sysdeps/m68k/fpu/s_ccosh.c new file mode 100644 index 0000000..1698881 --- /dev/null +++ b/sysdeps/m68k/fpu/s_ccosh.c @@ -0,0 +1,78 @@ +/* Complex cosine hyperbole function. m68k fpu version + Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>. + + 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 <complex.h> +#include <math.h> +#include "mathimpl.h" + +#ifndef SUFF +#define SUFF +#endif +#ifndef float_type +#define float_type double +#endif + +#define CONCATX(a,b) __CONCAT(a,b) +#define s(name) CONCATX(name,SUFF) +#define m81(func) __m81_u(s(func)) + +__complex__ float_type +s(__ccosh) (__complex__ float_type x) +{ + __complex__ float_type retval; + unsigned long ix_cond = __m81_test (__imag__ x); + + if ((ix_cond & (__M81_COND_INF|__M81_COND_NAN)) == 0) + { + /* Imaginary part is finite. */ + float_type sin_ix, cos_ix; + + __asm ("fsincos%.x %2,%1:%0" : "=f" (sin_ix), "=f" (cos_ix) + : "f" (__imag__ x)); + __real__ retval = cos_ix * m81(__ieee754_cosh) (__real__ x); + if (ix_cond & __M81_COND_ZERO) + __imag__ retval = (m81(__signbit) (__real__ x) + ? -__imag__ x : __imag__ x); + else + __imag__ retval = sin_ix * m81(__ieee754_sinh) (__real__ x); + } + else + { + unsigned long rx_cond = __m81_test (__real__ x); + + if (rx_cond & __M81_COND_ZERO) + { + __real__ retval = __imag__ x - __imag__ x; + __imag__ retval = __real__ x; + } + else + { + if (rx_cond & __M81_COND_INF) + __real__ retval = s(fabs) (__real__ x); + else + __real__ retval = 0.0/0.0; + __imag__ retval = __imag__ x - __imag__ x; + } + } + + return retval; +} +#define weak_aliasx(a,b) weak_alias(a,b) +weak_aliasx (s(__ccosh), s(ccosh)) diff --git a/sysdeps/m68k/fpu/s_ccoshf.c b/sysdeps/m68k/fpu/s_ccoshf.c new file mode 100644 index 0000000..3c8e7c7 --- /dev/null +++ b/sysdeps/m68k/fpu/s_ccoshf.c @@ -0,0 +1,3 @@ +#define SUFF f +#define float_type float +#include <s_ccosh.c> diff --git a/sysdeps/m68k/fpu/s_ccoshl.c b/sysdeps/m68k/fpu/s_ccoshl.c new file mode 100644 index 0000000..772d578 --- /dev/null +++ b/sysdeps/m68k/fpu/s_ccoshl.c @@ -0,0 +1,3 @@ +#define SUFF l +#define float_type long double +#include <s_ccosh.c> diff --git a/sysdeps/m68k/fpu/s_ccosl.c b/sysdeps/m68k/fpu/s_ccosl.c new file mode 100644 index 0000000..aaff365 --- /dev/null +++ b/sysdeps/m68k/fpu/s_ccosl.c @@ -0,0 +1,3 @@ +#define SUFF l +#define float_type long double +#include <s_ccos.c> diff --git a/sysdeps/m68k/fpu/s_ceil.c b/sysdeps/m68k/fpu/s_ceil.c new file mode 100644 index 0000000..93d5ad7 --- /dev/null +++ b/sysdeps/m68k/fpu/s_ceil.c @@ -0,0 +1,2 @@ +#define FUNC ceil +#include <s_atan.c> diff --git a/sysdeps/m68k/fpu/s_ceilf.c b/sysdeps/m68k/fpu/s_ceilf.c new file mode 100644 index 0000000..b3ba6a5 --- /dev/null +++ b/sysdeps/m68k/fpu/s_ceilf.c @@ -0,0 +1,2 @@ +#define FUNC ceilf +#include <s_atanf.c> diff --git a/sysdeps/m68k/fpu/s_ceill.c b/sysdeps/m68k/fpu/s_ceill.c new file mode 100644 index 0000000..2bf95b0 --- /dev/null +++ b/sysdeps/m68k/fpu/s_ceill.c @@ -0,0 +1,2 @@ +#define FUNC ceill +#include <s_atanl.c> diff --git a/sysdeps/m68k/fpu/s_cexp.c b/sysdeps/m68k/fpu/s_cexp.c new file mode 100644 index 0000000..4babf12 --- /dev/null +++ b/sysdeps/m68k/fpu/s_cexp.c @@ -0,0 +1,117 @@ +/* Complex exponential function. m68k fpu version + Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <complex.h> +#include <math.h> +#include "mathimpl.h" + +#ifndef SUFF +#define SUFF +#endif +#ifndef float_type +#define float_type double +#endif + +#define CONCATX(a,b) __CONCAT(a,b) +#define s(name) CONCATX(name,SUFF) +#define m81(func) __m81_u(s(func)) + +__complex__ float_type +s(__cexp) (__complex__ float_type x) +{ + __complex__ float_type retval; + unsigned long ix_cond; + + ix_cond = __m81_test (__imag__ x); + + if ((ix_cond & (__M81_COND_NAN|__M81_COND_INF)) == 0) + { + /* Imaginary part is finite. */ + float_type exp_val = m81(__ieee754_exp) (__real__ x); + + __real__ retval = __imag__ retval = exp_val; + if (m81(__finite) (exp_val)) + { + float_type sin_ix, cos_ix; + __asm ("fsincos%.x %2,%1:%0" : "=f" (sin_ix), "=f" (cos_ix) + : "f" (__imag__ x)); + __real__ retval *= cos_ix; + if (ix_cond & __M81_COND_ZERO) + __imag__ retval = __imag__ x; + else + __imag__ retval *= sin_ix; + } + else + { + /* Compute the sign of the result. */ + float_type remainder, pi_2; + int quadrant; + + __asm ("fmovecr %#0,%0\n\tfscale%.w %#-1,%0" : "=f" (pi_2)); + __asm ("fmod%.x %2,%0\n\tfmove%.l %/fpsr,%1" + : "=f" (remainder), "=dm" (quadrant) + : "f" (pi_2), "0" (__imag__ x)); + quadrant = (quadrant >> 16) & 0x83; + if (quadrant & 0x80) + quadrant ^= 0x83; + switch (quadrant) + { + default: + break; + case 1: + __real__ retval = -__real__ retval; + break; + case 2: + __real__ retval = -__real__ retval; + case 3: + __imag__ retval = -__imag__ retval; + break; + } + if (ix_cond & __M81_COND_ZERO && !m81(__isnan) (exp_val)) + __imag__ retval = __imag__ x; + } + } + else + { + unsigned long rx_cond = __m81_test (__real__ x); + + if (rx_cond & __M81_COND_INF) + { + /* Real part is infinite. */ + if (rx_cond & __M81_COND_NEG) + { + __real__ retval = __imag__ retval = 0.0; + if (ix_cond & __M81_COND_NEG) + __imag__ retval = -__imag__ retval; + } + else + { + __real__ retval = __real__ x; + __imag__ retval = __imag__ x - __imag__ x; + } + } + else + __real__ retval = __imag__ retval = __imag__ x - __imag__ x; + } + + return retval; +} +#define weak_aliasx(a,b) weak_alias(a,b) +weak_aliasx (s(__cexp), s(cexp)) diff --git a/sysdeps/m68k/fpu/s_cexpf.c b/sysdeps/m68k/fpu/s_cexpf.c new file mode 100644 index 0000000..177a360 --- /dev/null +++ b/sysdeps/m68k/fpu/s_cexpf.c @@ -0,0 +1,3 @@ +#define SUFF f +#define float_type float +#include <s_cexp.c> diff --git a/sysdeps/m68k/fpu/s_cexpl.c b/sysdeps/m68k/fpu/s_cexpl.c new file mode 100644 index 0000000..bbda4ba --- /dev/null +++ b/sysdeps/m68k/fpu/s_cexpl.c @@ -0,0 +1,3 @@ +#define SUFF l +#define float_type long double +#include <s_cexp.c> diff --git a/sysdeps/m68k/fpu/s_cos.c b/sysdeps/m68k/fpu/s_cos.c new file mode 100644 index 0000000..9c96076 --- /dev/null +++ b/sysdeps/m68k/fpu/s_cos.c @@ -0,0 +1,2 @@ +#define FUNC cos +#include <s_atan.c> diff --git a/sysdeps/m68k/fpu/s_cosf.c b/sysdeps/m68k/fpu/s_cosf.c new file mode 100644 index 0000000..db965b8 --- /dev/null +++ b/sysdeps/m68k/fpu/s_cosf.c @@ -0,0 +1,2 @@ +#define FUNC cosf +#include <s_atanf.c> diff --git a/sysdeps/m68k/fpu/s_cosl.c b/sysdeps/m68k/fpu/s_cosl.c new file mode 100644 index 0000000..4198fee --- /dev/null +++ b/sysdeps/m68k/fpu/s_cosl.c @@ -0,0 +1,2 @@ +#define FUNC cosl +#include <s_atanl.c> diff --git a/sysdeps/m68k/fpu/s_csin.c b/sysdeps/m68k/fpu/s_csin.c new file mode 100644 index 0000000..7c590e4 --- /dev/null +++ b/sysdeps/m68k/fpu/s_csin.c @@ -0,0 +1,69 @@ +/* Complex sine function. m68k fpu version + Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>. + + 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 <complex.h> +#include <math.h> +#include "mathimpl.h" + +#ifndef SUFF +#define SUFF +#endif +#ifndef float_type +#define float_type double +#endif + +#define CONCATX(a,b) __CONCAT(a,b) +#define s(name) CONCATX(name,SUFF) +#define m81(func) __m81_u(s(func)) + +__complex__ float_type +s(__csin) (__complex__ float_type x) +{ + __complex__ float_type retval; + unsigned long rx_cond = __m81_test (__real__ x); + + if ((rx_cond & (__M81_COND_INF|__M81_COND_NAN)) == 0) + { + /* Real part is finite. */ + float_type sin_rx, cos_rx; + + __asm ("fsincos%.x %2,%1:%0" : "=f" (sin_rx), "=f" (cos_rx) + : "f" (__real__ x)); + if (rx_cond & __M81_COND_ZERO) + __real__ retval = __real__ x; + else + __real__ retval = sin_rx * m81(__ieee754_cosh) (__imag__ x); + __imag__ retval = cos_rx * m81(__ieee754_sinh) (__imag__ x); + } + else + { + unsigned long ix_cond = __m81_test (__imag__ x); + + __real__ retval = __real__ x - __real__ x; + if (ix_cond & (__M81_COND_ZERO|__M81_COND_INF|__M81_COND_NAN)) + __imag__ retval = __imag__ x; + else + __imag__ retval = __real__ retval; + } + + return retval; +} +#define weak_aliasx(a,b) weak_alias(a,b) +weak_aliasx (s(__csin), s(csin)) diff --git a/sysdeps/m68k/fpu/s_csinf.c b/sysdeps/m68k/fpu/s_csinf.c new file mode 100644 index 0000000..b760e19 --- /dev/null +++ b/sysdeps/m68k/fpu/s_csinf.c @@ -0,0 +1,3 @@ +#define SUFF f +#define float_type float +#include <s_csin.c> diff --git a/sysdeps/m68k/fpu/s_csinh.c b/sysdeps/m68k/fpu/s_csinh.c new file mode 100644 index 0000000..dafb82a --- /dev/null +++ b/sysdeps/m68k/fpu/s_csinh.c @@ -0,0 +1,71 @@ +/* Complex sine hyperbole function. m68k fpu version + Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>. + + 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 <complex.h> +#include <math.h> +#include "mathimpl.h" + +#ifndef SUFF +#define SUFF +#endif +#ifndef float_type +#define float_type double +#endif + +#define CONCATX(a,b) __CONCAT(a,b) +#define s(name) CONCATX(name,SUFF) +#define m81(func) __m81_u(s(func)) + +__complex__ float_type +s(__csinh) (__complex__ float_type x) +{ + __complex__ float_type retval; + unsigned long ix_cond; + + ix_cond = __m81_test (__imag__ x); + + if ((ix_cond & (__M81_COND_INF|__M81_COND_NAN)) == 0) + { + /* Imaginary part is finite. */ + float_type sin_ix, cos_ix; + + __asm ("fsincos%.x %2,%1:%0" : "=f" (sin_ix), "=f" (cos_ix) + : "f" (__imag__ x)); + __real__ retval = cos_ix * m81(__ieee754_sinh) (__real__ x); + if (ix_cond & __M81_COND_ZERO) + __imag__ retval = __imag__ x; + else + __imag__ retval = sin_ix * m81(__ieee754_cosh) (__real__ x); + } + else + { + unsigned long rx_cond = __m81_test (__real__ x); + + __imag__ retval = __imag__ x - __imag__ x; + if (rx_cond & (__M81_COND_ZERO|__M81_COND_INF|__M81_COND_NAN)) + __real__ retval = __real__ x; + else + __real__ retval = __imag__ retval; + } + + return retval; +} +#define weak_aliasx(a,b) weak_alias(a,b) +weak_aliasx (s(__csinh), s(csinh)) diff --git a/sysdeps/m68k/fpu/s_csinhf.c b/sysdeps/m68k/fpu/s_csinhf.c new file mode 100644 index 0000000..2f7a43e --- /dev/null +++ b/sysdeps/m68k/fpu/s_csinhf.c @@ -0,0 +1,3 @@ +#define SUFF f +#define float_type float +#include <s_csinh.c> diff --git a/sysdeps/m68k/fpu/s_csinhl.c b/sysdeps/m68k/fpu/s_csinhl.c new file mode 100644 index 0000000..026a20e --- /dev/null +++ b/sysdeps/m68k/fpu/s_csinhl.c @@ -0,0 +1,3 @@ +#define SUFF l +#define float_type long double +#include <s_csinh.c> diff --git a/sysdeps/m68k/fpu/s_csinl.c b/sysdeps/m68k/fpu/s_csinl.c new file mode 100644 index 0000000..ea2dad0 --- /dev/null +++ b/sysdeps/m68k/fpu/s_csinl.c @@ -0,0 +1,3 @@ +#define SUFF l +#define float_type long double +#include <s_csin.c> diff --git a/sysdeps/m68k/fpu/s_expm1.c b/sysdeps/m68k/fpu/s_expm1.c new file mode 100644 index 0000000..1ef99e2 --- /dev/null +++ b/sysdeps/m68k/fpu/s_expm1.c @@ -0,0 +1,2 @@ +#define FUNC expm1 +#include <s_atan.c> diff --git a/sysdeps/m68k/fpu/s_expm1f.c b/sysdeps/m68k/fpu/s_expm1f.c new file mode 100644 index 0000000..84935b1 --- /dev/null +++ b/sysdeps/m68k/fpu/s_expm1f.c @@ -0,0 +1,2 @@ +#define FUNC expm1f +#include <s_atanf.c> diff --git a/sysdeps/m68k/fpu/s_expm1l.c b/sysdeps/m68k/fpu/s_expm1l.c new file mode 100644 index 0000000..feee07a --- /dev/null +++ b/sysdeps/m68k/fpu/s_expm1l.c @@ -0,0 +1,3 @@ +#define FUNC expm1l +#include <s_atanl.c> +libm_hidden_def (__expm1l) diff --git a/sysdeps/m68k/fpu/s_fabs.c b/sysdeps/m68k/fpu/s_fabs.c new file mode 100644 index 0000000..1f0631e --- /dev/null +++ b/sysdeps/m68k/fpu/s_fabs.c @@ -0,0 +1,2 @@ +#define FUNC fabs +#include <s_atan.c> diff --git a/sysdeps/m68k/fpu/s_fabsf.c b/sysdeps/m68k/fpu/s_fabsf.c new file mode 100644 index 0000000..8f94219 --- /dev/null +++ b/sysdeps/m68k/fpu/s_fabsf.c @@ -0,0 +1,2 @@ +#define FUNC fabsf +#include <s_atanf.c> diff --git a/sysdeps/m68k/fpu/s_fabsl.c b/sysdeps/m68k/fpu/s_fabsl.c new file mode 100644 index 0000000..8ac14d5 --- /dev/null +++ b/sysdeps/m68k/fpu/s_fabsl.c @@ -0,0 +1,2 @@ +#define FUNC fabsl +#include <s_atanl.c> diff --git a/sysdeps/m68k/fpu/s_finite.c b/sysdeps/m68k/fpu/s_finite.c new file mode 100644 index 0000000..dafbd59 --- /dev/null +++ b/sysdeps/m68k/fpu/s_finite.c @@ -0,0 +1,2 @@ +#define FUNC finite +#include <s_isinf.c> diff --git a/sysdeps/m68k/fpu/s_finitef.c b/sysdeps/m68k/fpu/s_finitef.c new file mode 100644 index 0000000..b81342e --- /dev/null +++ b/sysdeps/m68k/fpu/s_finitef.c @@ -0,0 +1,2 @@ +#define FUNC finitef +#include <s_isinff.c> diff --git a/sysdeps/m68k/fpu/s_finitel.c b/sysdeps/m68k/fpu/s_finitel.c new file mode 100644 index 0000000..bd346a2 --- /dev/null +++ b/sysdeps/m68k/fpu/s_finitel.c @@ -0,0 +1,2 @@ +#define FUNC finitel +#include <s_isinfl.c> diff --git a/sysdeps/m68k/fpu/s_floor.c b/sysdeps/m68k/fpu/s_floor.c new file mode 100644 index 0000000..e1219c6 --- /dev/null +++ b/sysdeps/m68k/fpu/s_floor.c @@ -0,0 +1,2 @@ +#define FUNC floor +#include <s_atan.c> diff --git a/sysdeps/m68k/fpu/s_floorf.c b/sysdeps/m68k/fpu/s_floorf.c new file mode 100644 index 0000000..f4f9b9a --- /dev/null +++ b/sysdeps/m68k/fpu/s_floorf.c @@ -0,0 +1,2 @@ +#define FUNC floorf +#include <s_atanf.c> diff --git a/sysdeps/m68k/fpu/s_floorl.c b/sysdeps/m68k/fpu/s_floorl.c new file mode 100644 index 0000000..2c1ffd7 --- /dev/null +++ b/sysdeps/m68k/fpu/s_floorl.c @@ -0,0 +1,2 @@ +#define FUNC floorl +#include <s_atanl.c> diff --git a/sysdeps/m68k/fpu/s_fpclassifyl.c b/sysdeps/m68k/fpu/s_fpclassifyl.c new file mode 100644 index 0000000..a8cb099 --- /dev/null +++ b/sysdeps/m68k/fpu/s_fpclassifyl.c @@ -0,0 +1,44 @@ +/* Return classification value corresponding to argument. m68k version. + Copyright (C) 1997, 2001, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + Fixed for m68k by Andreas Schwab <schwab@suse.de>. + + 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 <math.h> + +#include "math_private.h" + + +int +__fpclassifyl (long double x) +{ + u_int32_t ex, hx, lx; + int retval = FP_NORMAL; + + GET_LDOUBLE_WORDS (ex, hx, lx, x); + ex &= 0x7fff; + if ((ex | hx | lx) == 0) + retval = FP_ZERO; + else if (ex == 0 && (hx & 0x80000000) == 0) + retval = FP_SUBNORMAL; + else if (ex == 0x7fff) + retval = ((hx & 0x7fffffff) | lx) != 0 ? FP_NAN : FP_INFINITE; + + return retval; +} +libm_hidden_def (__fpclassifyl) diff --git a/sysdeps/m68k/fpu/s_frexp.c b/sysdeps/m68k/fpu/s_frexp.c new file mode 100644 index 0000000..b061412 --- /dev/null +++ b/sysdeps/m68k/fpu/s_frexp.c @@ -0,0 +1,56 @@ +/* Copyright (C) 1996, 1997, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> + +#ifndef FUNC +#define FUNC frexp +#endif +#ifndef float_type +#define float_type double +#endif + +#define __CONCATX(a,b) __CONCAT(a,b) + +float_type +__CONCATX(__,FUNC) (float_type value, int *expptr) +{ + float_type mantissa, exponent; + int iexponent; + unsigned long fpsr; + + __asm ("ftst%.x %1\n" + "fmove%.l %/fpsr, %0" + : "=dm" (fpsr) : "f" (value)); + if (fpsr & (7 << 24)) + { + /* Not finite or zero. */ + *expptr = 0; + return value; + } + __asm ("fgetexp%.x %1, %0" : "=f" (exponent) : "f" (value)); + iexponent = (int) exponent + 1; + *expptr = iexponent; + __asm ("fscale%.l %2, %0" + : "=f" (mantissa) + : "0" (value), "dmi" (-iexponent)); + return mantissa; +} + +#define weak_aliasx(a,b) weak_alias(a,b) +weak_aliasx (__CONCATX(__,FUNC), FUNC) diff --git a/sysdeps/m68k/fpu/s_frexpf.c b/sysdeps/m68k/fpu/s_frexpf.c new file mode 100644 index 0000000..893b6ad --- /dev/null +++ b/sysdeps/m68k/fpu/s_frexpf.c @@ -0,0 +1,3 @@ +#define FUNC frexpf +#define float_type float +#include <s_frexp.c> diff --git a/sysdeps/m68k/fpu/s_frexpl.c b/sysdeps/m68k/fpu/s_frexpl.c new file mode 100644 index 0000000..f9a5315 --- /dev/null +++ b/sysdeps/m68k/fpu/s_frexpl.c @@ -0,0 +1,59 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> + +long double +__frexpl (long double value, int *expptr) +{ + long double mantissa, exponent; + int iexponent; + unsigned long fpsr; + + __asm ("ftst%.x %1\n" + "fmove%.l %/fpsr, %0" + : "=dm" (fpsr) : "f" (value)); + if (fpsr & (7 << 24)) + { + /* Not finite or zero. */ + *expptr = 0; + return value; + } + __asm ("fgetexp%.x %1, %0" : "=f" (exponent) : "f" (value)); + iexponent = (int) exponent + 1; + *expptr = iexponent; + /* Unnormalized numbers must be handled specially, otherwise fscale + results in overflow. */ + if (iexponent <= -16384) + { + value *= 0x1p16383L; + iexponent += 16383; + } + else if (iexponent >= 16384) + { + value *= 0x1p-16383L; + iexponent -= 16383; + } + + __asm ("fscale%.l %2, %0" + : "=f" (mantissa) + : "0" (value), "dmi" (-iexponent)); + return mantissa; +} + +weak_alias (__frexpl, frexpl) diff --git a/sysdeps/m68k/fpu/s_ilogb.c b/sysdeps/m68k/fpu/s_ilogb.c new file mode 100644 index 0000000..ee1e397 --- /dev/null +++ b/sysdeps/m68k/fpu/s_ilogb.c @@ -0,0 +1,51 @@ +/* Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> +#include "mathimpl.h" + +#ifndef SUFF +#define SUFF +#endif +#ifndef float_type +#define float_type double +#endif + +#define CONCATX(a,b) __CONCAT(a,b) +#define s(name) CONCATX(name,SUFF) +#define m81(func) __m81_u(s(func)) + +int +s(__ilogb) (float_type x) +{ + float_type result; + unsigned long x_cond; + + x_cond = __m81_test (x); + /* We must return consistent values for zero and NaN. */ + if (x_cond & __M81_COND_ZERO) + return FP_ILOGB0; + if (x_cond & (__M81_COND_NAN | __M81_COND_INF)) + return FP_ILOGBNAN; + + __asm ("fgetexp%.x %1, %0" : "=f" (result) : "f" (x)); + return (int) result; +} + +#define weak_aliasx(a,b) weak_alias(a,b) +weak_aliasx (s(__ilogb), s(ilogb)) diff --git a/sysdeps/m68k/fpu/s_ilogbf.c b/sysdeps/m68k/fpu/s_ilogbf.c new file mode 100644 index 0000000..4031c42 --- /dev/null +++ b/sysdeps/m68k/fpu/s_ilogbf.c @@ -0,0 +1,3 @@ +#define SUFF f +#define float_type float +#include <s_ilogb.c> diff --git a/sysdeps/m68k/fpu/s_ilogbl.c b/sysdeps/m68k/fpu/s_ilogbl.c new file mode 100644 index 0000000..9c55a11 --- /dev/null +++ b/sysdeps/m68k/fpu/s_ilogbl.c @@ -0,0 +1,3 @@ +#define SUFF l +#define float_type long double +#include <s_ilogb.c> diff --git a/sysdeps/m68k/fpu/s_isinf.c b/sysdeps/m68k/fpu/s_isinf.c new file mode 100644 index 0000000..5fb43ea --- /dev/null +++ b/sysdeps/m68k/fpu/s_isinf.c @@ -0,0 +1,40 @@ +/* Copyright (C) 1996, 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> + +#ifndef FUNC +#define FUNC isinf +#endif +#ifndef float_type +#define float_type double +#endif + +#define __CONCATX(a,b) __CONCAT(a,b) + +int +__CONCATX(__,FUNC) (x) + float_type x; +{ + return __m81_u(__CONCATX(__,FUNC))(x); +} + +#define hidden_defx(a) hidden_def(a) +hidden_defx(__CONCATX(__,FUNC)) +#define weak_aliasx(a,b) weak_alias(a,b) +weak_aliasx (__CONCATX(__,FUNC), FUNC) diff --git a/sysdeps/m68k/fpu/s_isinff.c b/sysdeps/m68k/fpu/s_isinff.c new file mode 100644 index 0000000..ebf4f2a --- /dev/null +++ b/sysdeps/m68k/fpu/s_isinff.c @@ -0,0 +1,5 @@ +#ifndef FUNC +#define FUNC isinff +#endif +#define float_type float +#include <s_isinf.c> diff --git a/sysdeps/m68k/fpu/s_isinfl.c b/sysdeps/m68k/fpu/s_isinfl.c new file mode 100644 index 0000000..963725a --- /dev/null +++ b/sysdeps/m68k/fpu/s_isinfl.c @@ -0,0 +1,5 @@ +#ifndef FUNC +#define FUNC isinfl +#endif +#define float_type long double +#include <s_isinf.c> diff --git a/sysdeps/m68k/fpu/s_isnan.c b/sysdeps/m68k/fpu/s_isnan.c new file mode 100644 index 0000000..151d6dc --- /dev/null +++ b/sysdeps/m68k/fpu/s_isnan.c @@ -0,0 +1,2 @@ +#define FUNC isnan +#include <s_isinf.c> diff --git a/sysdeps/m68k/fpu/s_isnanf.c b/sysdeps/m68k/fpu/s_isnanf.c new file mode 100644 index 0000000..667bca7 --- /dev/null +++ b/sysdeps/m68k/fpu/s_isnanf.c @@ -0,0 +1,2 @@ +#define FUNC isnanf +#include <s_isinff.c> diff --git a/sysdeps/m68k/fpu/s_isnanl.c b/sysdeps/m68k/fpu/s_isnanl.c new file mode 100644 index 0000000..bbacb64 --- /dev/null +++ b/sysdeps/m68k/fpu/s_isnanl.c @@ -0,0 +1,2 @@ +#define FUNC isnanl +#include <s_isinfl.c> diff --git a/sysdeps/m68k/fpu/s_llrint.c b/sysdeps/m68k/fpu/s_llrint.c new file mode 100644 index 0000000..8f24429 --- /dev/null +++ b/sysdeps/m68k/fpu/s_llrint.c @@ -0,0 +1,76 @@ +/* Round argument to nearest integral value according to current rounding + direction. + Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <math.h> +#include "math_private.h" +#include "mathimpl.h" + +long long int +__llrint (double x) +{ + int32_t e; + u_int32_t h, l, s; + long long int result; + + x = __m81_u(__rint) (x); + + /* We could use __fixxfdi from libgcc, but here we can take advantage of + the known floating point format. */ + EXTRACT_WORDS (h, l, x); + + e = ((h >> 20) & 0x7ff) - 0x3ff; + if (e < 0) + return 0; + s = h; + h &= 0xfffff; + h |= 0x100000; + + if (e < 63) + { + if (e > 52) + { + h <<= e - 52; + h |= l >> (84 - e); + l <<= e - 52; + result = ((long long int) h << 32) | l; + } + else if (e > 20) + { + l >>= 52 - e; + l |= h << (e - 20); + h >>= 52 - e; + result = ((long long int) h << 32) | l; + } + else + result = h >> (20 - e); + if (s & 0x80000000) + result = -result; + } + else + /* The number is too large or not finite. The standard leaves it + undefined what to return when the number is too large to fit in a + `long long int'. */ + result = -1LL; + + return result; +} + +weak_alias (__llrint, llrint) diff --git a/sysdeps/m68k/fpu/s_llrintf.c b/sysdeps/m68k/fpu/s_llrintf.c new file mode 100644 index 0000000..bd573b2 --- /dev/null +++ b/sysdeps/m68k/fpu/s_llrintf.c @@ -0,0 +1,66 @@ +/* Round argument to nearest integral value according to current rounding + direction. + Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <math.h> +#include "math_private.h" +#include "mathimpl.h" + +long long int +__llrintf (float x) +{ + int32_t e; + u_int32_t i, s; + long long int result; + + x = __m81_u(__rintf) (x); + + GET_FLOAT_WORD (i, x); + + e = ((i >> 23) & 0xff) - 0x7f; + if (e < 0) + return 0; + s = i; + i &= 0x7fffff; + i |= 0x800000; + + if (e < 63) + { + if (e > 55) + result = (long long int) (i << (e - 55)) << 32; + else if (e > 31) + result = (((long long int) (i >> (55 - e)) << 32) | (i << (e - 23))); + else if (e > 23) + result = i << (e - 23); + else + result = i >> (23 - e); + if (s & 0x80000000) + result = -result; + } + else + /* The number is too large or not finite. The standard leaves it + undefined what to return when the number is too large to fit in a + `long long int'. */ + result = -1LL; + + return result; +} + +weak_alias (__llrintf, llrintf) diff --git a/sysdeps/m68k/fpu/s_llrintl.c b/sysdeps/m68k/fpu/s_llrintl.c new file mode 100644 index 0000000..d749f35 --- /dev/null +++ b/sysdeps/m68k/fpu/s_llrintl.c @@ -0,0 +1,65 @@ +/* Round argument to nearest integral value according to current rounding + direction. + Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <math.h> +#include "math_private.h" +#include "mathimpl.h" + +long long int +__llrintl (long double x) +{ + int32_t e, s; + u_int32_t h, l; + long long int result; + + x = __m81_u(__rintl) (x); + + GET_LDOUBLE_WORDS (e, h, l, x); + + s = e; + e = (e & 0x7fff) - 0x3fff; + if (e < 0) + return 0; + + if (e < 63) + { + if (e > 31) + { + l >>= 63 - e; + l |= h << (e - 31); + h >>= 63 - e; + result = ((long long int) h << 32) | l; + } + else + result = h >> (31 - e); + if (s & 0x8000) + result = -result; + } + else + /* The number is too large or not finite. The standard leaves it + undefined what to return when the number is too large to fit in a + `long long int'. */ + result = -1LL; + + return result; +} + +weak_alias (__llrintl, llrintl) diff --git a/sysdeps/m68k/fpu/s_log1p.c b/sysdeps/m68k/fpu/s_log1p.c new file mode 100644 index 0000000..1840ced --- /dev/null +++ b/sysdeps/m68k/fpu/s_log1p.c @@ -0,0 +1,2 @@ +#define FUNC log1p +#include <s_atan.c> diff --git a/sysdeps/m68k/fpu/s_log1pf.c b/sysdeps/m68k/fpu/s_log1pf.c new file mode 100644 index 0000000..cb7235a --- /dev/null +++ b/sysdeps/m68k/fpu/s_log1pf.c @@ -0,0 +1,2 @@ +#define FUNC log1pf +#include <s_atanf.c> diff --git a/sysdeps/m68k/fpu/s_log1pl.c b/sysdeps/m68k/fpu/s_log1pl.c new file mode 100644 index 0000000..8dbef89 --- /dev/null +++ b/sysdeps/m68k/fpu/s_log1pl.c @@ -0,0 +1,2 @@ +#define FUNC log1pl +#include <s_atanl.c> diff --git a/sysdeps/m68k/fpu/s_lrint.c b/sysdeps/m68k/fpu/s_lrint.c new file mode 100644 index 0000000..0a23f29 --- /dev/null +++ b/sysdeps/m68k/fpu/s_lrint.c @@ -0,0 +1,40 @@ +/* Round argument to nearest integral value according to current rounding + direction. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <math.h> + +#ifndef suffix +#define suffix /*empty*/ +#endif +#ifndef float_type +#define float_type double +#endif + +#define CONCATX(a,b) __CONCAT(a,b) + +long int +CONCATX(__lrint,suffix) (float_type x) +{ + return __m81_u(CONCATX(__lrint,suffix)) (x); +} + +#define weak_aliasx(a,b) weak_alias(a,b) +weak_aliasx (CONCATX(__lrint,suffix), CONCATX(lrint,suffix)) diff --git a/sysdeps/m68k/fpu/s_lrintf.c b/sysdeps/m68k/fpu/s_lrintf.c new file mode 100644 index 0000000..44924cb --- /dev/null +++ b/sysdeps/m68k/fpu/s_lrintf.c @@ -0,0 +1,3 @@ +#define suffix f +#define float_type float +#include <s_lrint.c> diff --git a/sysdeps/m68k/fpu/s_lrintl.c b/sysdeps/m68k/fpu/s_lrintl.c new file mode 100644 index 0000000..cd0bd23 --- /dev/null +++ b/sysdeps/m68k/fpu/s_lrintl.c @@ -0,0 +1,3 @@ +#define suffix l +#define float_type long double +#include <s_lrint.c> diff --git a/sysdeps/m68k/fpu/s_modf.c b/sysdeps/m68k/fpu/s_modf.c new file mode 100644 index 0000000..2f5a83d --- /dev/null +++ b/sysdeps/m68k/fpu/s_modf.c @@ -0,0 +1,56 @@ +/* Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> +#include "mathimpl.h" + +#ifndef SUFF +#define SUFF +#endif +#ifndef float_type +#define float_type double +#endif + +#define CONCATX(a,b) __CONCAT(a,b) +#define s(name) CONCATX(name,SUFF) +#define m81(func) __m81_u(s(func)) + +float_type +s(__modf) (float_type x, float_type *iptr) +{ + float_type x_int, result; + unsigned long x_cond; + + __asm ("fintrz%.x %1, %0" : "=f" (x_int) : "f" (x)); + *iptr = x_int; + x_cond = __m81_test (x); + if (x_cond & __M81_COND_INF) + { + result = 0; + if (x_cond & __M81_COND_NEG) + result = -result; + } + else if (x_cond & __M81_COND_ZERO) + result = x; + else + result = x - x_int; + return result; +} + +#define weak_aliasx(a,b) weak_alias(a,b) +weak_aliasx(s(__modf), s(modf)) diff --git a/sysdeps/m68k/fpu/s_modff.c b/sysdeps/m68k/fpu/s_modff.c new file mode 100644 index 0000000..0c44d7c --- /dev/null +++ b/sysdeps/m68k/fpu/s_modff.c @@ -0,0 +1,3 @@ +#define SUFF f +#define float_type float +#include <s_modf.c> diff --git a/sysdeps/m68k/fpu/s_modfl.c b/sysdeps/m68k/fpu/s_modfl.c new file mode 100644 index 0000000..c7075b3 --- /dev/null +++ b/sysdeps/m68k/fpu/s_modfl.c @@ -0,0 +1,3 @@ +#define SUFF l +#define float_type long double +#include <s_modf.c> diff --git a/sysdeps/m68k/fpu/s_nearbyint.c b/sysdeps/m68k/fpu/s_nearbyint.c new file mode 100644 index 0000000..b87f5e2 --- /dev/null +++ b/sysdeps/m68k/fpu/s_nearbyint.c @@ -0,0 +1,2 @@ +#define FUNC nearbyint +#include <s_atan.c> diff --git a/sysdeps/m68k/fpu/s_nearbyintf.c b/sysdeps/m68k/fpu/s_nearbyintf.c new file mode 100644 index 0000000..70d08ab --- /dev/null +++ b/sysdeps/m68k/fpu/s_nearbyintf.c @@ -0,0 +1,2 @@ +#define FUNC nearbyintf +#include <s_atanf.c> diff --git a/sysdeps/m68k/fpu/s_nearbyintl.c b/sysdeps/m68k/fpu/s_nearbyintl.c new file mode 100644 index 0000000..230cd77 --- /dev/null +++ b/sysdeps/m68k/fpu/s_nearbyintl.c @@ -0,0 +1,2 @@ +#define FUNC nearbyintl +#include <s_atanl.c> diff --git a/sysdeps/m68k/fpu/s_nextafterl.c b/sysdeps/m68k/fpu/s_nextafterl.c new file mode 100644 index 0000000..70ab5a4 --- /dev/null +++ b/sysdeps/m68k/fpu/s_nextafterl.c @@ -0,0 +1,109 @@ +/* s_nextafterl.c -- long double version of s_nextafter.c. + * Conversion to long double by Ulrich Drepper, + * Cygnus Support, drepper@cygnus.com. + * Fixed for m68k by Andreas Schwab <schwab@suse.de>. + */ + +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#if defined(LIBM_SCCS) && !defined(lint) +static char rcsid[] = "$NetBSD: $"; +#endif + +/* IEEE functions + * nextafterl(x,y) + * return the next machine floating-point number of x in the + * direction toward y. + * Special cases: + */ + +#include "math.h" +#include "math_private.h" + +#ifdef __STDC__ + long double __nextafterl(long double x, long double y) +#else + long double __nextafterl(x,y) + long double x,y; +#endif +{ + int32_t ix,iy,esx,esy; + u_int32_t hx,hy,lx,ly; + + GET_LDOUBLE_WORDS(esx,hx,lx,x); + GET_LDOUBLE_WORDS(esy,hy,ly,y); + ix = esx&0x7fff; /* |x| */ + iy = esy&0x7fff; /* |y| */ + + if(((ix==0x7fff)&&((hx&0x7fffffff)|lx)!=0) || /* x is nan */ + ((iy==0x7fff)&&((hy&0x7fffffff)|ly)!=0)) /* y is nan */ + return x+y; + if(x==y) return y; /* x=y, return y */ + if((ix|hx|lx)==0) { /* x == 0 */ + SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */ + y = x*x; + if(y==x) return y; else return x; /* raise underflow flag */ + } + if(esx>=0) { /* x > 0 */ + if(esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))) { + /* x > y, x -= ulp */ + if(lx==0) { + if (ix != 0 && hx == 0x80000000) hx = 0; + if (hx==0) esx -= 1; + hx -= 1; + } + lx -= 1; + } else { /* x < y, x += ulp */ + lx += 1; + if(lx==0) { + hx += 1; + if (hx==0) { + hx = 0x80000000; + esx += 1; + } + } + } + } else { /* x < 0 */ + if(esy>=0||esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))){ + /* x < y, x -= ulp */ + if(lx==0) { + if (ix != 0 && hx == 0x80000000) hx = 0; + if (hx==0) esx -= 1; + hx -= 1; + } + lx -= 1; + } else { /* x > y, x += ulp */ + lx += 1; + if(lx==0) { + hx += 1; + if (hx==0) { + hx = 0x80000000; + esx += 1; + } + } + } + } + esy = esx&0x7fff; + if(esy==0x7fff) return x+x; /* overflow */ + if(esy==0 && (hx & 0x80000000) == 0) { /* underflow */ + y = x*x; + if(y!=x) { /* raise underflow flag */ + SET_LDOUBLE_WORDS(y,esx,hx,lx); + return y; + } + } + SET_LDOUBLE_WORDS(x,esx,hx,lx); + return x; +} +weak_alias (__nextafterl, nextafterl) +strong_alias (__nextafterl, __nexttowardl) +weak_alias (__nextafterl, nexttowardl) diff --git a/sysdeps/m68k/fpu/s_remquo.c b/sysdeps/m68k/fpu/s_remquo.c new file mode 100644 index 0000000..5b65f85 --- /dev/null +++ b/sysdeps/m68k/fpu/s_remquo.c @@ -0,0 +1,48 @@ +/* Compute remainder and a congruent to the quotient. m68k fpu version + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> + + 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 <math.h> + +#ifndef SUFF +#define SUFF +#endif +#ifndef float_type +#define float_type double +#endif + +#define CONCATX(a,b) __CONCAT(a,b) +#define s(name) CONCATX(name,SUFF) + +float_type +s(__remquo) (float_type x, float_type y, int *quo) +{ + float_type result; + int cquo, fpsr; + + __asm ("frem%.x %2,%0\n\tfmove%.l %/fpsr,%1" + : "=f" (result), "=dm" (fpsr) : "f" (y), "0" (x)); + cquo = (fpsr >> 16) & 0x7f; + if (fpsr & (1 << 23)) + cquo = -cquo; + *quo = cquo; + return result; +} +#define weak_aliasx(a,b) weak_alias(a,b) +weak_aliasx (s(__remquo), s(remquo)) diff --git a/sysdeps/m68k/fpu/s_remquof.c b/sysdeps/m68k/fpu/s_remquof.c new file mode 100644 index 0000000..8a292fc --- /dev/null +++ b/sysdeps/m68k/fpu/s_remquof.c @@ -0,0 +1,3 @@ +#define SUFF f +#define float_type float +#include <s_remquo.c> diff --git a/sysdeps/m68k/fpu/s_remquol.c b/sysdeps/m68k/fpu/s_remquol.c new file mode 100644 index 0000000..d236cfd --- /dev/null +++ b/sysdeps/m68k/fpu/s_remquol.c @@ -0,0 +1,3 @@ +#define SUFF l +#define float_type long double +#include <s_remquo.c> diff --git a/sysdeps/m68k/fpu/s_rint.c b/sysdeps/m68k/fpu/s_rint.c new file mode 100644 index 0000000..f0f18c7 --- /dev/null +++ b/sysdeps/m68k/fpu/s_rint.c @@ -0,0 +1,2 @@ +#define FUNC rint +#include <s_atan.c> diff --git a/sysdeps/m68k/fpu/s_rintf.c b/sysdeps/m68k/fpu/s_rintf.c new file mode 100644 index 0000000..4e00cab --- /dev/null +++ b/sysdeps/m68k/fpu/s_rintf.c @@ -0,0 +1,2 @@ +#define FUNC rintf +#include <s_atanf.c> diff --git a/sysdeps/m68k/fpu/s_rintl.c b/sysdeps/m68k/fpu/s_rintl.c new file mode 100644 index 0000000..305667b --- /dev/null +++ b/sysdeps/m68k/fpu/s_rintl.c @@ -0,0 +1,2 @@ +#define FUNC rintl +#include <s_atanl.c> diff --git a/sysdeps/m68k/fpu/s_scalbln.c b/sysdeps/m68k/fpu/s_scalbln.c new file mode 100644 index 0000000..1009713 --- /dev/null +++ b/sysdeps/m68k/fpu/s_scalbln.c @@ -0,0 +1,2 @@ +/* Nothing to do. This function is the same as scalbn. So we define an + alias. */ diff --git a/sysdeps/m68k/fpu/s_scalblnf.c b/sysdeps/m68k/fpu/s_scalblnf.c new file mode 100644 index 0000000..5e558c3 --- /dev/null +++ b/sysdeps/m68k/fpu/s_scalblnf.c @@ -0,0 +1,2 @@ +/* Nothing to do. This function is the same as scalbnf. So we define an + alias. */ diff --git a/sysdeps/m68k/fpu/s_scalblnl.c b/sysdeps/m68k/fpu/s_scalblnl.c new file mode 100644 index 0000000..cda2ec1 --- /dev/null +++ b/sysdeps/m68k/fpu/s_scalblnl.c @@ -0,0 +1,2 @@ +/* Nothing to do. This function is the same as scalbnl. So we define an + alias. */ diff --git a/sysdeps/m68k/fpu/s_scalbn.c b/sysdeps/m68k/fpu/s_scalbn.c new file mode 100644 index 0000000..d76d94d --- /dev/null +++ b/sysdeps/m68k/fpu/s_scalbn.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +#define scalbln __no_scalbln_decl +#define scalblnf __no_scalblnf_decl +#define scalblnl __no_scalblnl_decl +#define __scalbln __no__scalbln_decl +#define __scalblnf __no__scalblnf_decl +#define __scalblnl __no__scalblnl_decl +#include <math.h> +#undef scalbln +#undef scalblnf +#undef scalblnl +#undef __scalbln +#undef __scalblnf +#undef __scalblnl + +#ifndef suffix +#define suffix /*empty*/ +#endif +#ifndef float_type +#define float_type double +#endif + +#define __CONCATX(a,b) __CONCAT(a,b) + +float_type +__CONCATX(__scalbn,suffix) (x, exp) + float_type x; + int exp; +{ + return __m81_u(__CONCATX(__scalbn,suffix))(x, exp); +} + +#define weak_aliasx(a,b) weak_alias(a,b) +#define strong_aliasx(a,b) strong_alias(a,b) +weak_aliasx (__CONCATX(__scalbn,suffix), __CONCATX(scalbn,suffix)) +strong_aliasx (__CONCATX(__scalbn,suffix), __CONCATX(__scalbln,suffix)) +weak_aliasx (__CONCATX(__scalbn,suffix), __CONCATX(scalbln,suffix)) diff --git a/sysdeps/m68k/fpu/s_scalbnf.c b/sysdeps/m68k/fpu/s_scalbnf.c new file mode 100644 index 0000000..5479718 --- /dev/null +++ b/sysdeps/m68k/fpu/s_scalbnf.c @@ -0,0 +1,3 @@ +#define suffix f +#define float_type float +#include <s_scalbn.c> diff --git a/sysdeps/m68k/fpu/s_scalbnl.c b/sysdeps/m68k/fpu/s_scalbnl.c new file mode 100644 index 0000000..874bafb --- /dev/null +++ b/sysdeps/m68k/fpu/s_scalbnl.c @@ -0,0 +1,3 @@ +#define suffix l +#define float_type long double +#include <s_scalbn.c> diff --git a/sysdeps/m68k/fpu/s_significand.c b/sysdeps/m68k/fpu/s_significand.c new file mode 100644 index 0000000..34d4ea3 --- /dev/null +++ b/sysdeps/m68k/fpu/s_significand.c @@ -0,0 +1,2 @@ +#define FUNC significand +#include <s_atan.c> diff --git a/sysdeps/m68k/fpu/s_significandf.c b/sysdeps/m68k/fpu/s_significandf.c new file mode 100644 index 0000000..4e769ca --- /dev/null +++ b/sysdeps/m68k/fpu/s_significandf.c @@ -0,0 +1,2 @@ +#define FUNC significandf +#include <s_atanf.c> diff --git a/sysdeps/m68k/fpu/s_significandl.c b/sysdeps/m68k/fpu/s_significandl.c new file mode 100644 index 0000000..8c6fc7e --- /dev/null +++ b/sysdeps/m68k/fpu/s_significandl.c @@ -0,0 +1,2 @@ +#define FUNC significandl +#include <s_atanl.c> diff --git a/sysdeps/m68k/fpu/s_sin.c b/sysdeps/m68k/fpu/s_sin.c new file mode 100644 index 0000000..0d4abdb --- /dev/null +++ b/sysdeps/m68k/fpu/s_sin.c @@ -0,0 +1,2 @@ +#define FUNC sin +#include <s_atan.c> diff --git a/sysdeps/m68k/fpu/s_sincos.c b/sysdeps/m68k/fpu/s_sincos.c new file mode 100644 index 0000000..5df4a5a --- /dev/null +++ b/sysdeps/m68k/fpu/s_sincos.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> + +#ifndef FUNC +#define FUNC sincos +#endif +#ifndef float_type +#define float_type double +#endif + +#define CONCATX(a,b) __CONCAT(a,b) + +void +CONCATX(__,FUNC) (x, sinx, cosx) + float_type x, *sinx, *cosx; +{ + __m81_u(CONCATX(__,FUNC))(x, sinx, cosx); +} + +#define weak_aliasx(a,b) weak_alias(a,b) +weak_aliasx (CONCATX(__,FUNC), FUNC) diff --git a/sysdeps/m68k/fpu/s_sincosf.c b/sysdeps/m68k/fpu/s_sincosf.c new file mode 100644 index 0000000..7ee2ec6 --- /dev/null +++ b/sysdeps/m68k/fpu/s_sincosf.c @@ -0,0 +1,3 @@ +#define FUNC sincosf +#define float_type float +#include <s_sincos.c> diff --git a/sysdeps/m68k/fpu/s_sincosl.c b/sysdeps/m68k/fpu/s_sincosl.c new file mode 100644 index 0000000..f998cc0 --- /dev/null +++ b/sysdeps/m68k/fpu/s_sincosl.c @@ -0,0 +1,3 @@ +#define FUNC sincosl +#define float_type long double +#include <s_sincos.c> diff --git a/sysdeps/m68k/fpu/s_sinf.c b/sysdeps/m68k/fpu/s_sinf.c new file mode 100644 index 0000000..9b23d48 --- /dev/null +++ b/sysdeps/m68k/fpu/s_sinf.c @@ -0,0 +1,2 @@ +#define FUNC sinf +#include <s_atanf.c> diff --git a/sysdeps/m68k/fpu/s_sinl.c b/sysdeps/m68k/fpu/s_sinl.c new file mode 100644 index 0000000..9ac532c --- /dev/null +++ b/sysdeps/m68k/fpu/s_sinl.c @@ -0,0 +1,2 @@ +#define FUNC sinl +#include <s_atanl.c> diff --git a/sysdeps/m68k/fpu/s_tan.c b/sysdeps/m68k/fpu/s_tan.c new file mode 100644 index 0000000..ca7fb0e --- /dev/null +++ b/sysdeps/m68k/fpu/s_tan.c @@ -0,0 +1,2 @@ +#define FUNC tan +#include <s_atan.c> diff --git a/sysdeps/m68k/fpu/s_tanf.c b/sysdeps/m68k/fpu/s_tanf.c new file mode 100644 index 0000000..95fe9c7 --- /dev/null +++ b/sysdeps/m68k/fpu/s_tanf.c @@ -0,0 +1,2 @@ +#define FUNC tanf +#include <s_atanf.c> diff --git a/sysdeps/m68k/fpu/s_tanh.c b/sysdeps/m68k/fpu/s_tanh.c new file mode 100644 index 0000000..ac2e7db --- /dev/null +++ b/sysdeps/m68k/fpu/s_tanh.c @@ -0,0 +1,2 @@ +#define FUNC tanh +#include <s_atan.c> diff --git a/sysdeps/m68k/fpu/s_tanhf.c b/sysdeps/m68k/fpu/s_tanhf.c new file mode 100644 index 0000000..1addaae --- /dev/null +++ b/sysdeps/m68k/fpu/s_tanhf.c @@ -0,0 +1,2 @@ +#define FUNC tanhf +#include <s_atanf.c> diff --git a/sysdeps/m68k/fpu/s_tanhl.c b/sysdeps/m68k/fpu/s_tanhl.c new file mode 100644 index 0000000..6e99791 --- /dev/null +++ b/sysdeps/m68k/fpu/s_tanhl.c @@ -0,0 +1,2 @@ +#define FUNC tanhl +#include <s_atanl.c> diff --git a/sysdeps/m68k/fpu/s_tanl.c b/sysdeps/m68k/fpu/s_tanl.c new file mode 100644 index 0000000..64fcb54 --- /dev/null +++ b/sysdeps/m68k/fpu/s_tanl.c @@ -0,0 +1,2 @@ +#define FUNC tanl +#include <s_atanl.c> diff --git a/sysdeps/m68k/fpu/s_trunc.c b/sysdeps/m68k/fpu/s_trunc.c new file mode 100644 index 0000000..96f29a7 --- /dev/null +++ b/sysdeps/m68k/fpu/s_trunc.c @@ -0,0 +1,2 @@ +#define FUNC trunc +#include <s_atan.c> diff --git a/sysdeps/m68k/fpu/s_truncf.c b/sysdeps/m68k/fpu/s_truncf.c new file mode 100644 index 0000000..44dca74 --- /dev/null +++ b/sysdeps/m68k/fpu/s_truncf.c @@ -0,0 +1,2 @@ +#define FUNC truncf +#include <s_atanf.c> diff --git a/sysdeps/m68k/fpu/s_truncl.c b/sysdeps/m68k/fpu/s_truncl.c new file mode 100644 index 0000000..8d35777 --- /dev/null +++ b/sysdeps/m68k/fpu/s_truncl.c @@ -0,0 +1,2 @@ +#define FUNC truncl +#include <s_atanl.c> diff --git a/sysdeps/m68k/fpu/sincos32.c b/sysdeps/m68k/fpu/sincos32.c new file mode 100644 index 0000000..1cc8931 --- /dev/null +++ b/sysdeps/m68k/fpu/sincos32.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/m68k/fpu/slowexp.c b/sysdeps/m68k/fpu/slowexp.c new file mode 100644 index 0000000..1cc8931 --- /dev/null +++ b/sysdeps/m68k/fpu/slowexp.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/m68k/fpu/slowpow.c b/sysdeps/m68k/fpu/slowpow.c new file mode 100644 index 0000000..1cc8931 --- /dev/null +++ b/sysdeps/m68k/fpu/slowpow.c @@ -0,0 +1 @@ +/* Not needed. */ diff --git a/sysdeps/m68k/fpu/switch/68881-sw.h b/sysdeps/m68k/fpu/switch/68881-sw.h new file mode 100644 index 0000000..c5a0f71 --- /dev/null +++ b/sysdeps/m68k/fpu/switch/68881-sw.h @@ -0,0 +1,64 @@ +/* Copyright (C) 1991, 1992, 1997, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +#ifndef _68881_SWITCH_H + +#define _68881_SWITCH_H 1 +#include <sys/cdefs.h> + +/* This is the format of the data at the code label for a function which + wants to switch depending on whether or not a 68881 is present. + + Initially, `insn' is a `jsr' instruction, and `target' is __68881_switch. + The first time such a function is called, __68881_switch determines whether + or not a 68881 is present, and modifies the function accordingly. + Then `insn' is a `jmp' instruction, and `target' is the value of `fpu' + if there is 68881, or the value of `soft' if not. */ + +struct switch_caller + { + unsigned short int insn; /* The `jsr' or `jmp' instruction. */ + void *target; /* The target of the instruction. */ + void *soft; /* The address of the soft function. */ + void *fpu; /* The address of the 68881 function. */ + }; + +/* These are opcodes (values for `insn', above) for `jmp' and `jsr' + instructions, respectively, to 32-bit absolute addresses. */ +#define JMP 0x4ef9 +#define JSR 0x4eb9 + + +/* Function to determine whether or not a 68881 is available, + and modify its caller (which must be a `struct switch_caller', above, + in data space) to use the appropriate version. */ +extern void __68881_switch (int __dummy) __THROW; + + +/* Define FUNCTION as a `struct switch_caller' which will call + `__FUNCTION_68881' if a 68881 is present, and `__FUNCTION_soft' if not. +#define switching_function(FUNCTION) \ + struct switch_caller FUNCTION = \ + { \ + JSR, (__ptr_t) __68881_switch, \ + __CONCAT(__CONCAT(__,FUNCTION),_soft), \ + __CONCAT(__CONCAT(__,FUNCTION),_68881) \ + } + + +#endif /* 68881-switch.h */ diff --git a/sysdeps/m68k/fpu/switch/Dist b/sysdeps/m68k/fpu/switch/Dist new file mode 100644 index 0000000..9288bdd --- /dev/null +++ b/sysdeps/m68k/fpu/switch/Dist @@ -0,0 +1,2 @@ +68881-sw.h +switch.c diff --git a/sysdeps/m68k/fpu/switch/Makefile b/sysdeps/m68k/fpu/switch/Makefile new file mode 100644 index 0000000..c041071 --- /dev/null +++ b/sysdeps/m68k/fpu/switch/Makefile @@ -0,0 +1,51 @@ +# Copyright (C) 1991, 1992, 1997 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# 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. + +ifeq ($(subdir),math) + +sysdep_routines := $(sysdep_routines) switch + +# Find all the sources that have 68881 versions. ++68881-sources := \ + $(notdir $(wildcard $(addprefix $(filter %/fpu,$(sysdirs)),$(sources)))) + +# Sysdep directories other than fpu and fpu/switch (this one). ++non68881-dirs := $(filter-out %/fpu %/fpu/switch,$(+sysdep_dirs)) + +# Get a non-68881 version of the target. ++non68881-version = $(firstword $(wildcard $(addsuffix /$@,$(+non68881-dirs)))) + +# Directory containing 68881 sources. ++68881-dir := $(filter %/fpu,$(+sysdep_dirs)) + +# For all the files that have 68881 versions and don't exist already in +# the source directory (math), automatically make ones that switch between +# 68881 and soft versions. +$(addprefix $(objpfx), \ + $(filter-out $(wildcard $(+68881-sources)),$(+68881-sources))): + (echo '#include <68881-sw.h>' ;\ + echo '#define $* __$*_68881' ;\ + echo '#include <$(+68881-dir)/$@>' ;\ + echo '#undef $*' ;\ + echo '#define $* __$*_soft' ;\ + echo '#include <$(non68881-version)>' ;\ + echo '#undef $*' ;\ + echo 'switching_function($*);') > $@-tmp + mv $@-tmp $@ + +endif diff --git a/sysdeps/m68k/fpu/switch/bits/mathinline.h b/sysdeps/m68k/fpu/switch/bits/mathinline.h new file mode 100644 index 0000000..c0f6966 --- /dev/null +++ b/sysdeps/m68k/fpu/switch/bits/mathinline.h @@ -0,0 +1 @@ +/* We don't want any inlines when we might not have a 68881. */ diff --git a/sysdeps/m68k/fpu/switch/switch.c b/sysdeps/m68k/fpu/switch/switch.c new file mode 100644 index 0000000..e055817 --- /dev/null +++ b/sysdeps/m68k/fpu/switch/switch.c @@ -0,0 +1,87 @@ +/* Copyright (C) 1991, 1992, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <signal.h> +#include <68881-sw.h> + + +/* The signal that is sent when a 68881 instruction + is executed and there is no 68881. */ +#ifndef TRAPSIG +#define TRAPSIG SIGILL +#endif + +/* Zero if no 68881, one if we have a 68881, or -1 if we don't know yet. */ +static int have_fpu = -1; + + +/* Signal handler for the trap that happens if we don't have a 68881. */ +static void +trap (sig) + int sig; +{ + have_fpu = 0; +} + +/* This function is called by functions that want to switch. + The calling function must be a `struct switch_caller' in data space. + It determines whether a 68881 is present, and modifies its caller + to be a static jump to either the 68881 version or the soft version. + It then returns into the function it has chosen to do the work. */ +void +__68881_switch (dummy) + int dummy; +{ + void **return_address_location = &((void **) &dummy)[-1]; + struct switch_caller *const caller + = (struct switch_caller *) (((short int *) *return_address_location) - 1); + + if (have_fpu < 0) + { + /* Figure out whether or not we have a 68881. */ + __sighandler_t handler = signal (TRAPSIG, trap); + if (handler == SIG_ERR) + /* We can't figure it out, so assume we don't have a 68881. + This assumption will never cause us any problems other than + lost performance, while the reverse assumption could cause + the program to crash. */ + have_fpu = 0; + else + { + /* We set `have_fpu' to nonzero, and then execute a 68881 + no-op instruction. If we have a 68881, this will do nothing. + If we don't have one, this will trap and the signal handler + will clear `have_fpu'. */ + have_fpu = 1; + asm ("fnop"); + + /* Restore the old signal handler. */ + (void) signal (TRAPSIG, handler); + } + } + + /* Modify the caller to be a jump to the appropriate address. */ + caller->insn = JMP; + caller->target = have_fpu ? caller->fpu : caller->soft; + + /* Make the address we will return to be the target we have chosen. + Our return will match the `jsr' done by the caller we have + just modified, and it will be just as if that had instead + been a `jmp' to the new target. */ + *return_address_location = caller->target; +} diff --git a/sysdeps/m68k/fpu/t_exp.c b/sysdeps/m68k/fpu/t_exp.c new file mode 100644 index 0000000..fd37963 --- /dev/null +++ b/sysdeps/m68k/fpu/t_exp.c @@ -0,0 +1 @@ +/* Empty. Not needed. */ diff --git a/sysdeps/m68k/fpu_control.h b/sysdeps/m68k/fpu_control.h new file mode 100644 index 0000000..86358e6 --- /dev/null +++ b/sysdeps/m68k/fpu_control.h @@ -0,0 +1,101 @@ +/* 68k FPU control word definitions. + Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +#ifndef _FPU_CONTROL_H +#define _FPU_CONTROL_H + +/* + * Motorola floating point control register bits. + * + * 31-16 -> reserved (read as 0, ignored on write) + * 15 -> enable trap for BSUN exception + * 14 -> enable trap for SNAN exception + * 13 -> enable trap for OPERR exception + * 12 -> enable trap for OVFL exception + * 11 -> enable trap for UNFL exception + * 10 -> enable trap for DZ exception + * 9 -> enable trap for INEX2 exception + * 8 -> enable trap for INEX1 exception + * 7-6 -> Precision Control + * 5-4 -> Rounding Control + * 3-0 -> zero (read as 0, write as 0) + * + * + * Precision Control: + * 00 - round to extended precision + * 01 - round to single precision + * 10 - round to double precision + * 11 - undefined + * + * Rounding Control: + * 00 - rounding to nearest (RN) + * 01 - rounding toward zero (RZ) + * 10 - rounding (down)toward minus infinity (RM) + * 11 - rounding (up) toward plus infinity (RP) + * + * The hardware default is 0x0000. I choose 0x5400. + */ + +#include <features.h> + +/* masking of interrupts */ +#define _FPU_MASK_BSUN 0x8000 +#define _FPU_MASK_SNAN 0x4000 +#define _FPU_MASK_OPERR 0x2000 +#define _FPU_MASK_OVFL 0x1000 +#define _FPU_MASK_UNFL 0x0800 +#define _FPU_MASK_DZ 0x0400 +#define _FPU_MASK_INEX1 0x0200 +#define _FPU_MASK_INEX2 0x0100 + +/* precision control */ +#define _FPU_EXTENDED 0x00 /* RECOMMENDED */ +#define _FPU_DOUBLE 0x80 +#define _FPU_SINGLE 0x40 /* DO NOT USE */ + +/* rounding control */ +#define _FPU_RC_NEAREST 0x00 /* RECOMMENDED */ +#define _FPU_RC_ZERO 0x10 +#define _FPU_RC_DOWN 0x20 +#define _FPU_RC_UP 0x30 + +#define _FPU_RESERVED 0xFFFF000F /* Reserved bits in fpucr */ + + +/* Now two recommended fpucr */ + +/* The fdlibm code requires no interrupts for exceptions. Don't + change the rounding mode, it would break long double I/O! */ +#define _FPU_DEFAULT 0x00000000 + +/* IEEE: same as above, but exceptions. We must make it non-zero so + that __setfpucw works. This bit will be ignored. */ +#define _FPU_IEEE 0x00000001 + +/* Type of the control word. */ +typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__))); + +/* Macros for accessing the hardware control word. */ +#define _FPU_GETCW(cw) __asm__ ("fmove%.l %!, %0" : "=dm" (cw)) +#define _FPU_SETCW(cw) __asm__ volatile ("fmove%.l %0, %!" : : "dm" (cw)) + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif /* _M68K_FPU_CONTROL_H */ diff --git a/sysdeps/m68k/gccframe.h b/sysdeps/m68k/gccframe.h new file mode 100644 index 0000000..452f53f --- /dev/null +++ b/sysdeps/m68k/gccframe.h @@ -0,0 +1,22 @@ +/* Definition of object in frame unwind info. m68k version. + Copyright (C) 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +#define FIRST_PSEUDO_REGISTER 24 + +#include <sysdeps/generic/gccframe.h> diff --git a/sysdeps/m68k/lshift.S b/sysdeps/m68k/lshift.S new file mode 100644 index 0000000..434b344 --- /dev/null +++ b/sysdeps/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/sysdeps/m68k/m68020/Makefile b/sysdeps/m68k/m68020/Makefile new file mode 100644 index 0000000..b176354 --- /dev/null +++ b/sysdeps/m68k/m68020/Makefile @@ -0,0 +1,3 @@ +ifeq ($(subdir),db2) +CPPFLAGS += -DHAVE_SPINLOCKS=1 -DHAVE_ASSEM_MC68020_GCC=1 +endif diff --git a/sysdeps/m68k/m68020/addmul_1.S b/sysdeps/m68k/m68020/addmul_1.S new file mode 100644 index 0000000..05d1d8a --- /dev/null +++ b/sysdeps/m68k/m68020/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/sysdeps/m68k/m68020/bits/atomic.h b/sysdeps/m68k/m68020/bits/atomic.h new file mode 100644 index 0000000..6b6db71 --- /dev/null +++ b/sysdeps/m68k/m68020/bits/atomic.h @@ -0,0 +1,254 @@ +/* Copyright (C) 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@suse.de>, 2003. + + 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 <stdint.h> + + +typedef int8_t atomic8_t; +typedef uint8_t uatomic8_t; +typedef int_fast8_t atomic_fast8_t; +typedef uint_fast8_t uatomic_fast8_t; + +typedef int16_t atomic16_t; +typedef uint16_t uatomic16_t; +typedef int_fast16_t atomic_fast16_t; +typedef uint_fast16_t uatomic_fast16_t; + +typedef int32_t atomic32_t; +typedef uint32_t uatomic32_t; +typedef int_fast32_t atomic_fast32_t; +typedef uint_fast32_t uatomic_fast32_t; + +typedef int64_t atomic64_t; +typedef uint64_t uatomic64_t; +typedef int_fast64_t atomic_fast64_t; +typedef uint_fast64_t uatomic_fast64_t; + +typedef intptr_t atomicptr_t; +typedef uintptr_t uatomicptr_t; +typedef intmax_t atomic_max_t; +typedef uintmax_t uatomic_max_t; + +#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \ + ({ __typeof (*(mem)) __ret; \ + __asm __volatile ("cas%.b %0,%2,%1" \ + : "=d" (__ret), "+m" (*(mem)) \ + : "d" (newval), "0" (oldval)); \ + __ret; }) + +#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \ + ({ __typeof (*(mem)) __ret; \ + __asm __volatile ("cas%.w %0,%2,%1" \ + : "=d" (__ret), "+m" (*(mem)) \ + : "d" (newval), "0" (oldval)); \ + __ret; }) + +#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \ + ({ __typeof (*(mem)) __ret; \ + __asm __volatile ("cas%.l %0,%2,%1" \ + : "=d" (__ret), "+m" (*(mem)) \ + : "d" (newval), "0" (oldval)); \ + __ret; }) + +# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \ + ({ __typeof (*(mem)) __ret; \ + __typeof (mem) __memp = (mem); \ + __asm __volatile ("cas2%.l %0:%R0,%1:%R1,(%2):(%3)" \ + : "=d" (__ret) \ + : "d" (newval), "r" (__memp), \ + "r" ((char *) __memp + 4), "0" (oldval) \ + : "memory"); \ + __ret; }) + +#define atomic_exchange_acq(mem, newvalue) \ + ({ __typeof (*(mem)) __result = *(mem); \ + if (sizeof (*(mem)) == 1) \ + __asm __volatile ("1: cas%.b %0,%2,%1;" \ + " jbne 1b" \ + : "=d" (__result), "+m" (*(mem)) \ + : "d" (newvalue), "0" (__result)); \ + else if (sizeof (*(mem)) == 2) \ + __asm __volatile ("1: cas%.w %0,%2,%1;" \ + " jbne 1b" \ + : "=d" (__result), "+m" (*(mem)) \ + : "d" (newvalue), "0" (__result)); \ + else if (sizeof (*(mem)) == 4) \ + __asm __volatile ("1: cas%.l %0,%2,%1;" \ + " jbne 1b" \ + : "=d" (__result), "+m" (*(mem)) \ + : "d" (newvalue), "0" (__result)); \ + else \ + { \ + __typeof (mem) __memp = (mem); \ + __asm __volatile ("1: cas2%.l %0:%R0,%1:%R1,(%2):(%3);" \ + " jbne 1b" \ + : "=d" (__result) \ + : "d" (newvalue), "r" (__memp), \ + "r" ((char *) __memp + 4), "0" (__result) \ + : "memory"); \ + } \ + __result; }) + +#define atomic_exchange_and_add(mem, value) \ + ({ __typeof (*(mem)) __result = *(mem); \ + __typeof (*(mem)) __temp; \ + if (sizeof (*(mem)) == 1) \ + __asm __volatile ("1: move%.b %0,%2;" \ + " add%.b %3,%2;" \ + " cas%.b %0,%2,%1;" \ + " jbne 1b" \ + : "=d" (__result), "+m" (*(mem)), \ + "=&d" (__temp) \ + : "d" (value), "0" (__result)); \ + else if (sizeof (*(mem)) == 2) \ + __asm __volatile ("1: move%.w %0,%2;" \ + " add%.w %3,%2;" \ + " cas%.w %0,%2,%1;" \ + " jbne 1b" \ + : "=d" (__result), "+m" (*(mem)), \ + "=&d" (__temp) \ + : "d" (value), "0" (__result)); \ + else if (sizeof (*(mem)) == 4) \ + __asm __volatile ("1: move%.l %0,%2;" \ + " add%.l %3,%2;" \ + " cas%.l %0,%2,%1;" \ + " jbne 1b" \ + : "=d" (__result), "+m" (*(mem)), \ + "=&d" (__temp) \ + : "d" (value), "0" (__result)); \ + else \ + { \ + __typeof (mem) __memp = (mem); \ + __asm __volatile ("1: move%.l %0,%1;" \ + " move%.l %R0,%R1;" \ + " add%.l %2,%1;" \ + " addx%.l %R2,%R1;" \ + " cas2%.l %0:%R0,%1:%R1,(%3):(%4);" \ + " jbne 1b" \ + : "=d" (__result), "=&d" (__temp) \ + : "d" (value), "r" (__memp), \ + "r" ((char *) __memp + 4), "0" (__result) \ + : "memory"); \ + } \ + __result; }) + +#define atomic_add(mem, value) \ + (void) ({ if (sizeof (*(mem)) == 1) \ + __asm __volatile ("add%.b %1,%0" \ + : "+m" (*(mem)) \ + : "id" (value)); \ + else if (sizeof (*(mem)) == 2) \ + __asm __volatile ("add%.w %1,%0" \ + : "+m" (*(mem)) \ + : "id" (value)); \ + else if (sizeof (*(mem)) == 4) \ + __asm __volatile ("add%.l %1,%0" \ + : "+m" (*(mem)) \ + : "id" (value)); \ + else \ + { \ + __typeof (mem) __memp = (mem); \ + __typeof (*(mem)) __oldval = *__memp; \ + __typeof (*(mem)) __temp; \ + __asm __volatile ("1: move%.l %0,%1;" \ + " move%.l %R0,%R1;" \ + " add%.l %2,%1;" \ + " addx%.l %R2,%R1;" \ + " cas2%.l %0:%R0,%1:%R1,(%3):(%4);" \ + " jbne 1b" \ + : "=d" (__oldval), "=&d" (__temp) \ + : "d" (value), "r" (__memp), \ + "r" ((char *) __memp + 4), "0" (__oldval) \ + : "memory"); \ + } \ + }) + +#define atomic_increment_and_test(mem) \ + ({ char __result; \ + if (sizeof (*(mem)) == 1) \ + __asm __volatile ("addq%.b %#1,%1; seq %0" \ + : "=dm" (__result), "+m" (*(mem))); \ + else if (sizeof (*(mem)) == 2) \ + __asm __volatile ("addq%.w %#1,%1; seq %0" \ + : "=dm" (__result), "+m" (*(mem))); \ + else if (sizeof (*(mem)) == 4) \ + __asm __volatile ("addq%.l %#1,%1; seq %0" \ + : "=dm" (__result), "+m" (*(mem))); \ + else \ + { \ + __typeof (mem) __memp = (mem); \ + __typeof (*(mem)) __oldval = *__memp; \ + __typeof (*(mem)) __temp; \ + __asm __volatile ("1: move%.l %1,%2;" \ + " move%.l %R1,%R2;" \ + " addq%.l %#1,%2;" \ + " addx%.l %5,%R2;" \ + " seq %0;" \ + " cas2%.l %1:%R1,%2:%R2,(%3):(%4);" \ + " jbne 1b" \ + : "=&dm" (__result), "=d" (__oldval), \ + "=&d" (__temp) \ + : "r" (__memp), "r" ((char *) __memp + 4), \ + "d" (0), "1" (__oldval) \ + : "memory"); \ + } \ + __result; }) + +#define atomic_decrement_and_test(mem) \ + ({ char __result; \ + if (sizeof (*(mem)) == 1) \ + __asm __volatile ("subq%.b %#1,%1; seq %0" \ + : "=dm" (__result), "+m" (*(mem))); \ + else if (sizeof (*(mem)) == 2) \ + __asm __volatile ("subq%.w %#1,%1; seq %0" \ + : "=dm" (__result), "+m" (*(mem))); \ + else if (sizeof (*(mem)) == 4) \ + __asm __volatile ("subq%.l %#1,%1; seq %0" \ + : "=dm" (__result), "+m" (*(mem))); \ + else \ + { \ + __typeof (mem) __memp = (mem); \ + __typeof (*(mem)) __oldval = *__memp; \ + __typeof (*(mem)) __temp; \ + __asm __volatile ("1: move%.l %1,%2;" \ + " move%.l %R1,%R2;" \ + " subq%.l %#1,%2;" \ + " subx%.l %5,%R2;" \ + " seq %0;" \ + " cas2%.l %1:%R1,%2:%R2,(%3):(%4);" \ + " jbne 1b" \ + : "=&dm" (__result), "=d" (__oldval), \ + "=&d" (__temp) \ + : "r" (__memp), "r" ((char *) __memp + 4), \ + "d" (0), "1" (__oldval) \ + : "memory"); \ + } \ + __result; }) + +#define atomic_bit_set(mem, bit) \ + __asm __volatile ("bfset %0{%1,#1}" \ + : "+m" (*(mem)) \ + : "di" (sizeof (*(mem)) * 8 - (bit) - 1)) + +#define atomic_bit_test_set(mem, bit) \ + ({ char __result; \ + __asm __volatile ("bfset %1{%2,#1}; sne %0" \ + : "=dm" (__result), "+m" (*(mem)) \ + : "di" (sizeof (*(mem)) * 8 - (bit) - 1)); \ + __result; }) diff --git a/sysdeps/m68k/m68020/bits/string.h b/sysdeps/m68k/m68020/bits/string.h new file mode 100644 index 0000000..84be224 --- /dev/null +++ b/sysdeps/m68k/m68020/bits/string.h @@ -0,0 +1,26 @@ +/* Optimized, inlined string functions. m680x0 version, x >= 2. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +#ifndef _STRING_H +# error "Never use <bits/string.h> directly; include <string.h> instead." +#endif + +/* Currently the only purpose of this file is to tell the generic inline + macros that unaligned memory access is possible. */ +#define _STRING_ARCH_unaligned 1 diff --git a/sysdeps/m68k/m68020/mul_1.S b/sysdeps/m68k/m68020/mul_1.S new file mode 100644 index 0000000..f3e450e --- /dev/null +++ b/sysdeps/m68k/m68020/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/sysdeps/m68k/m68020/submul_1.S b/sysdeps/m68k/m68020/submul_1.S new file mode 100644 index 0000000..7522046 --- /dev/null +++ b/sysdeps/m68k/m68020/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/sysdeps/m68k/m68020/wordcopy.S b/sysdeps/m68k/m68020/wordcopy.S new file mode 100644 index 0000000..4fb1a45 --- /dev/null +++ b/sysdeps/m68k/m68020/wordcopy.S @@ -0,0 +1 @@ +/* Empty, not needed. */ diff --git a/sysdeps/m68k/memchr.S b/sysdeps/m68k/memchr.S new file mode 100644 index 0000000..fab65a9 --- /dev/null +++ b/sysdeps/m68k/memchr.S @@ -0,0 +1,232 @@ +/* memchr (str, ch, n) -- Return pointer to first occurrence of CH in the + first N bytes of STR. + For Motorola 68000. + Copyright (C) 1999, 2000, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@gnu.org>. + + 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 <sysdep.h> +#include "asm-syntax.h" + + TEXT +ENTRY(__memchr) + /* Save the callee-saved registers we use. */ + moveml R(d2)-R(d4),MEM_PREDEC(sp) + + /* Get string pointer, character and length. */ + movel MEM_DISP(sp,16),R(a0) + moveb MEM_DISP(sp,23),R(d0) + movel MEM_DISP(sp,24),R(d4) + + /* Check if at least four bytes left to search. */ + moveql #4,R(d1) + cmpl R(d1),R(d4) + bcs L(L6) + + /* Distribute the character to all bytes of a longword. */ + movel R(d0),R(d1) + lsll #8,R(d1) + moveb R(d0),R(d1) + movel R(d1),R(d0) + swap R(d0) + movew R(d1),R(d0) + + /* First search for the character one byte at a time until the + pointer is aligned to a longword boundary. */ + movel R(a0),R(d1) + andw #3,R(d1) + beq L(L1) + cmpb MEM(a0),R(d0) + beq L(L9) + addql #1,R(a0) + subql #1,R(d4) + beq L(L7) + + movel R(a0),R(d1) + andw #3,R(d1) + beq L(L1) + cmpb MEM(a0),R(d0) + beq L(L9) + addql #1,R(a0) + subql #1,R(d4) + beq L(L7) + + movel R(a0),R(d1) + andw #3,R(d1) + beq L(L1) + cmpb MEM(a0),R(d0) + beq L(L9) + addql #1,R(a0) + subql #1,R(d4) + beq L(L7) + +L(L1:) + /* Load the magic bits. Unlike the generic implementation we can + use the carry bit as the fourth hole. */ + movel #0xfefefeff,R(d3) + + /* We 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-31 is set, there will be a carry + into bit 32 (=carry flag), so all of the hole bits will + be changed. + + 3) But wait! Aren't we looking for C, not zero? + Good point. So what we do is XOR LONGWORD with a longword, + each of whose bytes is C. This turns each byte that is C + into a zero. */ + + /* Still at least 4 bytes to search? */ + subql #4,R(d4) + bcs L(L6) + +L(L2:) + /* Get the longword in question. */ + movel MEM_POSTINC(a0),R(d1) + /* XOR with the byte we search for. */ + eorl R(d0),R(d1) + + /* Add the magic value. We get carry bits reported for each byte + which is not C. */ + movel R(d3),R(d2) + addl R(d1),R(d2) + + /* Check the fourth carry bit before it is clobbered by the next + XOR. If it is not set we have a hit. */ + bcc L(L8) + + /* We are only interested in carry bits that change due to the + previous add, so remove original bits. */ + eorl R(d1),R(d2) + + /* Now test for the other three overflow bits. + Set all non-carry bits. */ + orl R(d3),R(d2) + /* Add 1 to get zero if all carry bits were set. */ + addql #1,R(d2) + + /* If we don't get zero then at least one byte of the word equals + C. */ + bne L(L8) + + /* Still at least 4 bytes to search? */ + subql #4,R(d4) + bcs L(L6) + + /* Get the longword in question. */ + movel MEM_POSTINC(a0),R(d1) + /* XOR with the byte we search for. */ + eorl R(d0),R(d1) + + /* Add the magic value. We get carry bits reported for each byte + which is not C. */ + movel R(d3),R(d2) + addl R(d1),R(d2) + + /* Check the fourth carry bit before it is clobbered by the next + XOR. If it is not set we have a hit. */ + bcc L(L8) + + /* We are only interested in carry bits that change due to the + previous add, so remove original bits */ + eorl R(d1),R(d2) + + /* Now test for the other three overflow bits. + Set all non-carry bits. */ + orl R(d3),R(d2) + /* Add 1 to get zero if all carry bits were set. */ + addql #1,R(d2) + + /* If we don't get zero then at least one byte of the word equals + C. */ + bne L(L8) + + /* Still at least 4 bytes to search? */ + subql #4,R(d4) + bcc L(L2) + +L(L6:) + /* Search one byte at a time in the remaining less than 4 bytes. */ + andw #3,R(d4) + beq L(L7) + cmpb MEM(a0),R(d0) + beq L(L9) + addql #1,R(a0) + + subqw #1,R(d4) + beq L(L7) + cmpb MEM(a0),R(d0) + beq L(L9) + addql #1,R(a0) + + subqw #1,R(d4) + beq L(L7) + cmpb MEM(a0),R(d0) + beq L(L9) + +L(L7:) + /* Return NULL. */ + clrl R(d0) + movel R(d0),R(a0) + moveml MEM_POSTINC(sp),R(d2)-R(d4) + rts + +L(L8:) + /* We have a hit. Check to see which byte it was. First + compensate for the autoincrement in the loop. */ + subql #4,R(a0) + + cmpb MEM(a0),R(d0) + beq L(L9) + addql #1,R(a0) + + cmpb MEM(a0),R(d0) + beq L(L9) + addql #1,R(a0) + + cmpb MEM(a0),R(d0) + beq L(L9) + addql #1,R(a0) + + /* Otherwise the fourth byte must equal C. */ +L(L9:) + movel R(a0),R(d0) + moveml MEM_POSTINC(sp),R(d2)-R(d4) + rts +END(__memchr) + +weak_alias (__memchr, memchr) +#if !__BOUNDED_POINTERS__ +weak_alias (__memchr, __ubp_memchr) +#endif +libc_hidden_builtin_def (memchr) diff --git a/sysdeps/m68k/memcopy.h b/sysdeps/m68k/memcopy.h new file mode 100644 index 0000000..0951eea --- /dev/null +++ b/sysdeps/m68k/memcopy.h @@ -0,0 +1,100 @@ +/* memcopy.h -- definitions for memory copy functions. Motorola 68020 version. + Copyright (C) 1991, 1997, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Torbjorn Granlund (tege@sics.se). + + 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 <sysdeps/generic/memcopy.h> + +#if defined(__mc68020__) || defined(mc68020) + +#undef OP_T_THRES +#define OP_T_THRES 16 + +/* WORD_COPY_FWD and WORD_COPY_BWD are not symmetric on the 68020, + because of its weird instruction overlap characteristics. */ + +#undef WORD_COPY_FWD +#define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes) \ + do \ + { \ + size_t __nwords = (nbytes) / sizeof (op_t); \ + size_t __nblocks = __nwords / 8 + 1; \ + dst_bp -= (8 - __nwords % 8) * sizeof (op_t); \ + src_bp -= (8 - __nwords % 8) * sizeof (op_t); \ + switch (__nwords % 8) \ + do \ + { \ + ((op_t *) dst_bp)[0] = ((op_t *) src_bp)[0]; \ + case 7: \ + ((op_t *) dst_bp)[1] = ((op_t *) src_bp)[1]; \ + case 6: \ + ((op_t *) dst_bp)[2] = ((op_t *) src_bp)[2]; \ + case 5: \ + ((op_t *) dst_bp)[3] = ((op_t *) src_bp)[3]; \ + case 4: \ + ((op_t *) dst_bp)[4] = ((op_t *) src_bp)[4]; \ + case 3: \ + ((op_t *) dst_bp)[5] = ((op_t *) src_bp)[5]; \ + case 2: \ + ((op_t *) dst_bp)[6] = ((op_t *) src_bp)[6]; \ + case 1: \ + ((op_t *) dst_bp)[7] = ((op_t *) src_bp)[7]; \ + case 0: \ + src_bp += 32; \ + dst_bp += 32; \ + __nblocks--; \ + } \ + while (__nblocks != 0); \ + (nbytes_left) = (nbytes) % sizeof (op_t); \ + } while (0) + +#undef WORD_COPY_BWD +#define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes) \ + do \ + { \ + size_t __nblocks = (nbytes) / 32 + 1; \ + op_t *__dst_ep = (op_t *) (dst_ep); \ + op_t *__src_ep = (op_t *) (src_ep); \ + switch ((nbytes) / sizeof (op_t) % 8) \ + do \ + { \ + *--__dst_ep = *--__src_ep; \ + case 7: \ + *--__dst_ep = *--__src_ep; \ + case 6: \ + *--__dst_ep = *--__src_ep; \ + case 5: \ + *--__dst_ep = *--__src_ep; \ + case 4: \ + *--__dst_ep = *--__src_ep; \ + case 3: \ + *--__dst_ep = *--__src_ep; \ + case 2: \ + *--__dst_ep = *--__src_ep; \ + case 1: \ + *--__dst_ep = *--__src_ep; \ + case 0: \ + __nblocks--; \ + } \ + while (__nblocks != 0); \ + (nbytes_left) = (nbytes) % sizeof (op_t); \ + (dst_ep) = (unsigned long) __dst_ep; \ + (src_ep) = (unsigned long) __src_ep; \ + } while (0) + +#endif diff --git a/sysdeps/m68k/memusage.h b/sysdeps/m68k/memusage.h new file mode 100644 index 0000000..bb22c0a --- /dev/null +++ b/sysdeps/m68k/memusage.h @@ -0,0 +1,22 @@ +/* Copyright (C) 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + + +#define GETSP() ({ register uintptr_t stack_ptr asm ("%sp"); stack_ptr; }) + +#include <sysdeps/generic/memusage.h> diff --git a/sysdeps/m68k/printf_fphex.c b/sysdeps/m68k/printf_fphex.c new file mode 100644 index 0000000..d021a09 --- /dev/null +++ b/sysdeps/m68k/printf_fphex.c @@ -0,0 +1,2 @@ +#define LONG_DOUBLE_DENORM_BIAS IEEE854_LONG_DOUBLE_BIAS +#include <sysdeps/ieee754/ldbl-96/printf_fphex.c> diff --git a/sysdeps/m68k/rawmemchr.S b/sysdeps/m68k/rawmemchr.S new file mode 100644 index 0000000..acd8f76 --- /dev/null +++ b/sysdeps/m68k/rawmemchr.S @@ -0,0 +1,180 @@ +/* rawmemchr (str, ch) -- Return pointer to first occurrence of CH in STR. + For Motorola 68000. + Copyright (C) 1999, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@gnu.org>. + + 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 <sysdep.h> +#include "asm-syntax.h" + + TEXT +ENTRY(__rawmemchr) + /* Save the callee-saved registers we use. */ + movel R(d2),MEM_PREDEC(sp) + movel R(d3),MEM_PREDEC(sp) + + /* Get string pointer and character. */ + movel MEM_DISP(sp,12),R(a0) + moveb MEM_DISP(sp,19),R(d0) + + /* Distribute the character to all bytes of a longword. */ + movel R(d0),R(d1) + lsll #8,R(d1) + moveb R(d0),R(d1) + movel R(d1),R(d0) + swap R(d0) + movew R(d1),R(d0) + + /* First search for the character one byte at a time until the + pointer is aligned to a longword boundary. */ + movel R(a0),R(d1) + andw #3,R(d1) + beq L(L1) + cmpb MEM(a0),R(d0) + beq L(L9) + addql #1,R(a0) + + movel R(a0),R(d1) + andw #3,R(d1) + beq L(L1) + cmpb MEM(a0),R(d0) + beq L(L9) + addql #1,R(a0) + + movel R(a0),R(d1) + andw #3,R(d1) + beq L(L1) + cmpb MEM(a0),R(d0) + beq L(L9) + addql #1,R(a0) + +L(L1:) + /* Load the magic bits. Unlike the generic implementation we can + use the carry bit as the fourth hole. */ + movel #0xfefefeff,R(d3) + + /* We 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-31 is set, there will be a carry + into bit 32 (=carry flag), so all of the hole bits will + be changed. + + 3) But wait! Aren't we looking for C, not zero? + Good point. So what we do is XOR LONGWORD with a longword, + each of whose bytes is C. This turns each byte that is C + into a zero. */ + +L(L2:) + /* Get the longword in question. */ + movel MEM_POSTINC(a0),R(d1) + /* XOR with the byte we search for. */ + eorl R(d0),R(d1) + + /* Add the magic value. We get carry bits reported for each byte + which is not C. */ + movel R(d3),R(d2) + addl R(d1),R(d2) + + /* Check the fourth carry bit before it is clobbered by the next + XOR. If it is not set we have a hit. */ + bcc L(L8) + + /* We are only interested in carry bits that change due to the + previous add, so remove original bits. */ + eorl R(d1),R(d2) + + /* Now test for the other three overflow bits. + Set all non-carry bits. */ + orl R(d3),R(d2) + /* Add 1 to get zero if all carry bits were set. */ + addql #1,R(d2) + + /* If we don't get zero then at least one byte of the word equals + C. */ + bne L(L8) + + /* Get the longword in question. */ + movel MEM_POSTINC(a0),R(d1) + /* XOR with the byte we search for. */ + eorl R(d0),R(d1) + + /* Add the magic value. We get carry bits reported for each byte + which is not C. */ + movel R(d3),R(d2) + addl R(d1),R(d2) + + /* Check the fourth carry bit before it is clobbered by the next + XOR. If it is not set we have a hit. */ + bcc L(L8) + + /* We are only interested in carry bits that change due to the + previous add, so remove original bits */ + eorl R(d1),R(d2) + + /* Now test for the other three overflow bits. + Set all non-carry bits. */ + orl R(d3),R(d2) + /* Add 1 to get zero if all carry bits were set. */ + addql #1,R(d2) + + /* If we don't get zero then at least one byte of the word equals + C. */ + beq L(L2) + +L(L8:) + /* We have a hit. Check to see which byte it was. First + compensate for the autoincrement in the loop. */ + subql #4,R(a0) + + cmpb MEM(a0),R(d0) + beq L(L9) + addql #1,R(a0) + + cmpb MEM(a0),R(d0) + beq L(L9) + addql #1,R(a0) + + cmpb MEM(a0),R(d0) + beq L(L9) + addql #1,R(a0) + + /* Otherwise the fourth byte must equal C. */ +L(L9:) + movel R(a0),R(d0) + movel MEM_POSTINC(sp),R(d3) + movel MEM_POSTINC(sp),R(d2) + rts +END(__rawmemchr) + +libc_hidden_def (__rawmemchr) +weak_alias (__rawmemchr, rawmemchr) diff --git a/sysdeps/m68k/rshift.S b/sysdeps/m68k/rshift.S new file mode 100644 index 0000000..5e6abce --- /dev/null +++ b/sysdeps/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/sysdeps/m68k/s_isinfl.c b/sysdeps/m68k/s_isinfl.c new file mode 100644 index 0000000..2502039 --- /dev/null +++ b/sysdeps/m68k/s_isinfl.c @@ -0,0 +1,42 @@ +/* Copyright (C) 1991, 1992, 1995, 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> +#include "ieee754.h" + +/* Return 0 if VALUE is finite or NaN, +1 if it + is +Infinity, -1 if it is -Infinity. */ +int +__isinfl (long double value) +{ + union ieee854_long_double u; + + u.d = value; + + /* An IEEE 854 infinity has an exponent with the + maximum possible value and a zero mantissa. + In Motorola's interpretation the integer bit is ignored. */ + if ((u.ieee.exponent & 0x7fff) == 0x7fff && + (u.ieee.mantissa0 & 0x7fffffff) == 0 && u.ieee.mantissa1 == 0) + return u.ieee.negative ? -1 : 1; + + return 0; +} + +hidden_def (__isinfl) +weak_alias (__isinfl, isinfl); diff --git a/sysdeps/m68k/s_isnanl.c b/sysdeps/m68k/s_isnanl.c new file mode 100644 index 0000000..999746f --- /dev/null +++ b/sysdeps/m68k/s_isnanl.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1991, 1992, 1995, 1997, 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <math.h> +#include "ieee754.h" + +/* Return nonzero if VALUE is not a number. */ +int +__isnanl (long double value) +{ + union ieee854_long_double u; + + u.d = value; + + /* IEEE 854 NaN's have the maximum possible + exponent and a nonzero mantissa. In Motorola's + interpretation the integer bit is ignored. */ + return ((u.ieee.exponent & 0x7fff) == 0x7fff && + ((u.ieee.mantissa0 & 0x7fffffff) != 0 || u.ieee.mantissa1 != 0)); +} + +hidden_def (__isnanl) +weak_alias (__isnanl, isnanl); diff --git a/sysdeps/m68k/setjmp.c b/sysdeps/m68k/setjmp.c new file mode 100644 index 0000000..8a6c3f9 --- /dev/null +++ b/sysdeps/m68k/setjmp.c @@ -0,0 +1,63 @@ +/* Copyright (C) 1991, 1992, 1994, 1997, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <setjmp.h> + +/* Save the current program position in ENV and return 0. */ +int +#if defined BSD_SETJMP +# undef setjmp +# define savemask 1 +setjmp (jmp_buf env) +#elif defined BSD__SETJMP +# undef _setjmp +# define savemask 0 +_setjmp (jmp_buf env) +#else +__sigsetjmp (jmp_buf env, int savemask) +#endif +{ + /* Save data registers D1 through D7. */ + asm volatile ("movem%.l %/d1-%/d7, %0" + : : "m" (env[0].__jmpbuf[0].__dregs[0])); + + /* Save return address in place of register A0. */ + env[0].__jmpbuf[0].__aregs[0] = ((void **) &env)[-1]; + + /* Save address registers A1 through A5. */ + asm volatile ("movem%.l %/a1-%/a5, %0" + : : "m" (env[0].__jmpbuf[0].__aregs[1])); + + /* Save caller's FP, not our own. */ + env[0].__jmpbuf[0].__fp = ((void **) &env)[-2]; + + /* Save caller's SP, not our own. */ + env[0].__jmpbuf[0].__sp = (void *) &env; + +#if defined __HAVE_68881__ || defined __HAVE_FPU__ + /* Save floating-point (68881) registers FP0 through FP7. */ + asm volatile ("fmovem%.x %/fp0-%/fp7, %0" + : : "m" (env[0].__jmpbuf[0].__fpregs[0])); +#endif + + /* Save the signal mask if requested. */ + return __sigjmp_save (env, savemask); +} +#if !defined BSD_SETJMP && !defined BSD__SETJMP +hidden_def (__sigsetjmp) +#endif diff --git a/sysdeps/m68k/stackinfo.h b/sysdeps/m68k/stackinfo.h new file mode 100644 index 0000000..66e5a17 --- /dev/null +++ b/sysdeps/m68k/stackinfo.h @@ -0,0 +1,28 @@ +/* Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +/* This file contains a bit of information about the stack allocation + of the processor. */ + +#ifndef _STACKINFO_H +#define _STACKINFO_H 1 + +/* On m68k the stack grows down. */ +#define _STACK_GROWS_DOWN 1 + +#endif /* stackinfo.h */ diff --git a/sysdeps/m68k/strchr.S b/sysdeps/m68k/strchr.S new file mode 100644 index 0000000..04626ff --- /dev/null +++ b/sysdeps/m68k/strchr.S @@ -0,0 +1,258 @@ +/* strchr (str, ch) -- Return pointer to first occurrence of CH in STR. + For Motorola 68000. + Copyright (C) 1999, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@gnu.org>. + + 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 <sysdep.h> +#include "asm-syntax.h" + + TEXT +ENTRY(strchr) + /* Save the callee-saved registers we use. */ + movel R(d2),MEM_PREDEC(sp) + movel R(d3),MEM_PREDEC(sp) + + /* Get string pointer and character. */ + movel MEM_DISP(sp,12),R(a0) + moveb MEM_DISP(sp,19),R(d0) + + /* Distribute the character to all bytes of a longword. */ + movel R(d0),R(d1) + lsll #8,R(d1) + moveb R(d0),R(d1) + movel R(d1),R(d0) + swap R(d0) + movew R(d1),R(d0) + + /* First search for the character one byte at a time until the + pointer is aligned to a longword boundary. */ + movel R(a0),R(d1) + andw #3,R(d1) + beq L(L1) + moveb MEM(a0),R(d1) + cmpb R(d0),R(d1) + beq L(L9) + tstb R(d1) + beq L(L3) + addql #1,R(a0) + + movel R(a0),R(d1) + andw #3,R(d1) + beq L(L1) + moveb MEM(a0),R(d1) + cmpb R(d0),R(d1) + beq L(L9) + tstb R(d1) + beq L(L3) + addql #1,R(a0) + + movel R(a0),R(d1) + andw #3,R(d1) + beq L(L1) + moveb MEM(a0),R(d1) + cmpb R(d0),R(d1) + beq L(L9) + tstb R(d1) + beq L(L3) + addql #1,R(a0) + +L(L1:) + /* Load the magic bits. Unlike the generic implementation we can + use the carry bit as the fourth hole. */ + movel #0xfefefeff,R(d3) + + /* We 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-31 is set, there will be a carry + into bit 32 (=carry flag), so all of the hole bits will + be changed. + + 3) But wait! Aren't we looking for C, not zero? + Good point. So what we do is XOR LONGWORD with a longword, + each of whose bytes is C. This turns each byte that is C + into a zero. */ + +L(L2:) + /* Get the longword in question. */ + movel MEM_POSTINC(a0),R(d1) + /* XOR with the byte we search for. */ + eorl R(d0),R(d1) + + /* Add the magic value. We get carry bits reported for each byte + which is not C. */ + movel R(d3),R(d2) + addl R(d1),R(d2) + + /* Check the fourth carry bit before it is clobbered by the next + XOR. If it is not set we have a hit. */ + bcc L(L8) + + /* We are only interested in carry bits that change due to the + previous add, so remove original bits. */ + eorl R(d1),R(d2) + + /* Now test for the other three overflow bits. + Set all non-carry bits. */ + orl R(d3),R(d2) + /* Add 1 to get zero if all carry bits were set. */ + addql #1,R(d2) + + /* If we don't get zero then at least one byte of the word equals + C. */ + bne L(L8) + + /* Next look for a NUL byte. + Restore original longword without reload. */ + eorl R(d0),R(d1) + /* Add the magic value. We get carry bits reported for each byte + which is not NUL. */ + movel R(d3),R(d2) + addl R(d1),R(d2) + + /* Check the fourth carry bit before it is clobbered by the next + XOR. If it is not set we have a hit, and return NULL. */ + bcc L(L3) + + /* We are only interested in carry bits that change due to the + previous add, so remove original bits. */ + eorl R(d1),R(d2) + + /* Now test for the other three overflow bits. + Set all non-carry bits. */ + orl R(d3),R(d2) + /* Add 1 to get zero if all carry bits were set. */ + addql #1,R(d2) + + /* If we don't get zero then at least one byte of the word was NUL + and we return NULL. Otherwise continue with the next longword. */ + bne L(L3) + + /* Get the longword in question. */ + movel MEM_POSTINC(a0),R(d1) + /* XOR with the byte we search for. */ + eorl R(d0),R(d1) + + /* Add the magic value. We get carry bits reported for each byte + which is not C. */ + movel R(d3),R(d2) + addl R(d1),R(d2) + + /* Check the fourth carry bit before it is clobbered by the next + XOR. If it is not set we have a hit. */ + bcc L(L8) + + /* We are only interested in carry bits that change due to the + previous add, so remove original bits */ + eorl R(d1),R(d2) + + /* Now test for the other three overflow bits. + Set all non-carry bits. */ + orl R(d3),R(d2) + /* Add 1 to get zero if all carry bits were set. */ + addql #1,R(d2) + + /* If we don't get zero then at least one byte of the word equals + C. */ + bne L(L8) + + /* Next look for a NUL byte. + Restore original longword without reload. */ + eorl R(d0),R(d1) + /* Add the magic value. We get carry bits reported for each byte + which is not NUL. */ + movel R(d3),R(d2) + addl R(d1),R(d2) + + /* Check the fourth carry bit before it is clobbered by the next + XOR. If it is not set we have a hit, and return NULL. */ + bcc L(L3) + + /* We are only interested in carry bits that change due to the + previous add, so remove original bits */ + eorl R(d1),R(d2) + + /* Now test for the other three overflow bits. + Set all non-carry bits. */ + orl R(d3),R(d2) + /* Add 1 to get zero if all carry bits were set. */ + addql #1,R(d2) + + /* If we don't get zero then at least one byte of the word was NUL + and we return NULL. Otherwise continue with the next longword. */ + beq L(L2) + +L(L3:) + /* Return NULL. */ + clrl R(d0) + movel R(d0),R(a0) + movel MEM_POSTINC(sp),R(d3) + movel MEM_POSTINC(sp),R(d2) + rts + +L(L8:) + /* We have a hit. Check to see which byte it was. First + compensate for the autoincrement in the loop. */ + subql #4,R(a0) + + moveb MEM(a0),R(d1) + cmpb R(d0),R(d1) + beq L(L9) + tstb R(d1) + beq L(L3) + addql #1,R(a0) + + moveb MEM(a0),R(d1) + cmpb R(d0),R(d1) + beq L(L9) + tstb R(d1) + beq L(L3) + addql #1,R(a0) + + moveb MEM(a0),R(d1) + cmpb R(d0),R(d1) + beq L(L9) + tstb R(d1) + beq L(L3) + addql #1,R(a0) + + /* Otherwise the fourth byte must equal C. */ +L(L9:) + movel R(a0),R(d0) + movel MEM_POSTINC(sp),R(d3) + movel MEM_POSTINC(sp),R(d2) + rts +END(strchr) + +weak_alias (strchr, index) +libc_hidden_builtin_def (strchr) diff --git a/sysdeps/m68k/strchrnul.S b/sysdeps/m68k/strchrnul.S new file mode 100644 index 0000000..3fee2b2 --- /dev/null +++ b/sysdeps/m68k/strchrnul.S @@ -0,0 +1,250 @@ +/* strchrnul (str, ch) -- Return pointer to first occurrence of CH in STR + or the final NUL byte. + For Motorola 68000. + Copyright (C) 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Schwab <schwab@gnu.org>. + + 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 <sysdep.h> +#include "asm-syntax.h" + + TEXT +ENTRY(__strchrnul) + /* Save the callee-saved registers we use. */ + movel R(d2),MEM_PREDEC(sp) + movel R(d3),MEM_PREDEC(sp) + + /* Get string pointer and character. */ + movel MEM_DISP(sp,12),R(a0) + moveb MEM_DISP(sp,19),R(d0) + + /* Distribute the character to all bytes of a longword. */ + movel R(d0),R(d1) + lsll #8,R(d1) + moveb R(d0),R(d1) + movel R(d1),R(d0) + swap R(d0) + movew R(d1),R(d0) + + /* First search for the character one byte at a time until the + pointer is aligned to a longword boundary. */ + movel R(a0),R(d1) + andw #3,R(d1) + beq L(L1) + moveb MEM(a0),R(d1) + cmpb R(d0),R(d1) + beq L(L9) + tstb R(d1) + beq L(L9) + addql #1,R(a0) + + movel R(a0),R(d1) + andw #3,R(d1) + beq L(L1) + moveb MEM(a0),R(d1) + cmpb R(d0),R(d1) + beq L(L9) + tstb R(d1) + beq L(L9) + addql #1,R(a0) + + movel R(a0),R(d1) + andw #3,R(d1) + beq L(L1) + moveb MEM(a0),R(d1) + cmpb R(d0),R(d1) + beq L(L9) + tstb R(d1) + beq L(L9) + addql #1,R(a0) + +L(L1:) + /* Load the magic bits. Unlike the generic implementation we can + use the carry bit as the fourth hole. */ + movel #0xfefefeff,R(d3) + + /* We 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-31 is set, there will be a carry + into bit 32 (=carry flag), so all of the hole bits will + be changed. + + 3) But wait! Aren't we looking for C, not zero? + Good point. So what we do is XOR LONGWORD with a longword, + each of whose bytes is C. This turns each byte that is C + into a zero. */ + +L(L2:) + /* Get the longword in question. */ + movel MEM_POSTINC(a0),R(d1) + /* XOR with the byte we search for. */ + eorl R(d0),R(d1) + + /* Add the magic value. We get carry bits reported for each byte + which is not C. */ + movel R(d3),R(d2) + addl R(d1),R(d2) + + /* Check the fourth carry bit before it is clobbered by the next + XOR. If it is not set we have a hit. */ + bcc L(L8) + + /* We are only interested in carry bits that change due to the + previous add, so remove original bits. */ + eorl R(d1),R(d2) + + /* Now test for the other three overflow bits. + Set all non-carry bits. */ + orl R(d3),R(d2) + /* Add 1 to get zero if all carry bits were set. */ + addql #1,R(d2) + + /* If we don't get zero then at least one byte of the word equals + C. */ + bne L(L8) + + /* Next look for a NUL byte. + Restore original longword without reload. */ + eorl R(d0),R(d1) + /* Add the magic value. We get carry bits reported for each byte + which is not NUL. */ + movel R(d3),R(d2) + addl R(d1),R(d2) + + /* Check the fourth carry bit before it is clobbered by the next + XOR. If it is not set we have a hit. */ + bcc L(L8) + + /* We are only interested in carry bits that change due to the + previous add, so remove original bits. */ + eorl R(d1),R(d2) + + /* Now test for the other three overflow bits. + Set all non-carry bits. */ + orl R(d3),R(d2) + /* Add 1 to get zero if all carry bits were set. */ + addql #1,R(d2) + + /* If we don't get zero then at least one byte of the word was + NUL. Otherwise continue with the next longword. */ + bne L(L8) + + /* Get the longword in question. */ + movel MEM_POSTINC(a0),R(d1) + /* XOR with the byte we search for. */ + eorl R(d0),R(d1) + + /* Add the magic value. We get carry bits reported for each byte + which is not C. */ + movel R(d3),R(d2) + addl R(d1),R(d2) + + /* Check the fourth carry bit before it is clobbered by the next + XOR. If it is not set we have a hit. */ + bcc L(L8) + + /* We are only interested in carry bits that change due to the + previous add, so remove original bits */ + eorl R(d1),R(d2) + + /* Now test for the other three overflow bits. + Set all non-carry bits. */ + orl R(d3),R(d2) + /* Add 1 to get zero if all carry bits were set. */ + addql #1,R(d2) + + /* If we don't get zero then at least one byte of the word equals + C. */ + bne L(L8) + + /* Next look for a NUL byte. + Restore original longword without reload. */ + eorl R(d0),R(d1) + /* Add the magic value. We get carry bits reported for each byte + which is not NUL. */ + movel R(d3),R(d2) + addl R(d1),R(d2) + + /* Check the fourth carry bit before it is clobbered by the next + XOR. If it is not set we have a hit. */ + bcc L(L8) + + /* We are only interested in carry bits that change due to the + previous add, so remove original bits */ + eorl R(d1),R(d2) + + /* Now test for the other three overflow bits. + Set all non-carry bits. */ + orl R(d3),R(d2) + /* Add 1 to get zero if all carry bits were set. */ + addql #1,R(d2) + + /* If we don't get zero then at least one byte of the word was + NUL. Otherwise continue with the next longword. */ + beq L(L2) + +L(L8:) + /* We have a hit. Check to see which byte it was. First + compensate for the autoincrement in the loop. */ + subql #4,R(a0) + + moveb MEM(a0),R(d1) + cmpb R(d0),R(d1) + beq L(L9) + tstb R(d1) + beq L(L9) + addql #1,R(a0) + + moveb MEM(a0),R(d1) + cmpb R(d0),R(d1) + beq L(L9) + tstb R(d1) + beq L(L9) + addql #1,R(a0) + + moveb MEM(a0),R(d1) + cmpb R(d0),R(d1) + beq L(L9) + tstb R(d1) + beq L(L9) + addql #1,R(a0) + + /* Otherwise the fourth byte must equal C or be NUL. */ +L(L9:) + movel R(a0),R(d0) + movel MEM_POSTINC(sp),R(d3) + movel MEM_POSTINC(sp),R(d2) + rts +END(__strchrnul) + +weak_alias (__strchrnul, strchrnul) diff --git a/sysdeps/m68k/strtold_l.c b/sysdeps/m68k/strtold_l.c new file mode 100644 index 0000000..481d992 --- /dev/null +++ b/sysdeps/m68k/strtold_l.c @@ -0,0 +1,2 @@ +#define DENORM_EXP (MIN_EXP - 1) +#include <sysdeps/ieee754/ldbl-96/strtold_l.c> diff --git a/sysdeps/m68k/sub_n.S b/sysdeps/m68k/sub_n.S new file mode 100644 index 0000000..5833dd2 --- /dev/null +++ b/sysdeps/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/sysdeps/m68k/sys/ucontext.h b/sysdeps/m68k/sys/ucontext.h new file mode 100644 index 0000000..857ed6b --- /dev/null +++ b/sysdeps/m68k/sys/ucontext.h @@ -0,0 +1,108 @@ +/* Copyright (C) 1997, 1999 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + +/* System V/m68k ABI compliant context switching support. */ + +#ifndef _SYS_UCONTEXT_H +#define _SYS_UCONTEXT_H 1 + +#include <features.h> +#include <signal.h> + +/* Type for general register. */ +typedef int greg_t; + +/* Number of general registers. */ +#define NGREG 18 + +/* Container for all general registers. */ +typedef greg_t gregset_t[NGREG]; + +/* Number of each register is the `gregset_t' array. */ +enum +{ + R_D0 = 0, +#define R_D0 R_D0 + R_D1 = 1, +#define R_D1 R_D1 + R_D2 = 2, +#define R_D2 R_D2 + R_D3 = 3, +#define R_D3 R_D3 + R_D4 = 4, +#define R_D4 R_D4 + R_D5 = 5, +#define R_D5 R_D5 + R_D6 = 6, +#define R_D6 R_D6 + R_D7 = 7, +#define R_D7 R_D7 + R_A0 = 8, +#define R_A0 R_A0 + R_A1 = 9, +#define R_A1 R_A1 + R_A2 = 10, +#define R_A2 R_A2 + R_A3 = 11, +#define R_A3 R_A3 + R_A4 = 12, +#define R_A4 R_A4 + R_A5 = 13, +#define R_A5 R_A5 + R_A6 = 14, +#define R_A6 R_A6 + R_A7 = 15, +#define R_A7 R_A7 + R_SP = 15, +#define R_SP R_SP + R_PC = 16, +#define R_PC R_PC + R_PS = 17 +#define R_PS R_PS +}; + +/* Structure to describe FPU registers. */ +typedef struct fpregset +{ + int f_pcr; + int f_psr; + int f_fpiaddr; + int f_fpregs[8][3]; +} fpregset_t; + +/* Context to describe whole processor state. */ +typedef struct +{ + int version; + gregset_t gregs; +} mcontext_t; + +#define MCONTEXT_VERSION 1 + +/* Userlevel context. */ +typedef struct ucontext +{ + unsigned long int uc_flags; + struct ucontext *uc_link; + __sigset_t uc_sigmask; + stack_t uc_stack; + mcontext_t uc_mcontext; + long int uc_filler[201]; +} ucontext_t; + +#endif /* sys/ucontext.h */ diff --git a/sysdeps/m68k/sysdep.h b/sysdeps/m68k/sysdep.h new file mode 100644 index 0000000..f492ff6 --- /dev/null +++ b/sysdeps/m68k/sysdep.h @@ -0,0 +1,100 @@ +/* Assembler macros for m68k. + Copyright (C) 1998, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 <sysdeps/generic/sysdep.h> + +#ifdef __ASSEMBLER__ + +/* Syntactic details of assembler. */ + +# ifdef HAVE_ELF + +/* ELF uses byte-counts for .align, most others use log2 of count of bytes. */ +# define ALIGNARG(log2) 1<<log2 +/* For ELF we need the `.type' directive to make shared libs work right. */ +# define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg +# define ASM_SIZE_DIRECTIVE(name) .size name,.-name + +/* In ELF C symbols are asm symbols. */ +# undef NO_UNDERSCORES +# define NO_UNDERSCORES + +# else + +# define ALIGNARG(log2) log2 +# define ASM_TYPE_DIRECTIVE(name,type) /* Nothing is specified. */ +# define ASM_SIZE_DIRECTIVE(name) /* Nothing is specified. */ + +# endif + + +/* Define an entry point visible from C. + + There is currently a bug in gdb which prevents us from specifying + incomplete stabs information. Fake some entries here which specify + the current source file. */ +# define ENTRY(name) \ + .globl C_SYMBOL_NAME(name); \ + ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function); \ + .align ALIGNARG(2); \ + C_LABEL(name) \ + CALL_MCOUNT + +# undef END +# define END(name) ASM_SIZE_DIRECTIVE(name) + + +/* If compiled for profiling, call `_mcount' at the start of each function. */ +# ifdef PROF +/* The mcount code relies on a normal frame pointer being on the stack + to locate our caller, so push one just for its benefit. */ +# define CALL_MCOUNT \ + move.l %fp, -(%sp); move.l %sp, %fp; \ + jbsr JUMPTARGET (mcount); \ + move.l (%sp)+, %fp; +# else +# define CALL_MCOUNT /* Do nothing. */ +# endif + +# ifdef NO_UNDERSCORES +/* Since C identifiers are not normally prefixed with an underscore + on this system, the asm identifier `syscall_error' intrudes on the + C name space. Make sure we use an innocuous name. */ +# define syscall_error __syscall_error +# define mcount _mcount +# endif + +# define PSEUDO(name, syscall_name, args) \ + .globl syscall_error; \ + ENTRY (name) \ + DO_CALL (syscall_name, args); \ + jcc JUMPTARGET(syscall_error) + +# undef PSEUDO_END +# define PSEUDO_END(name) \ + END (name) + +# undef JUMPTARGET +# ifdef PIC +# define JUMPTARGET(name) name##@PLTPC +# else +# define JUMPTARGET(name) name +# endif + +#endif /* __ASSEMBLER__ */ |