Compare commits

...

31 Commits

Author SHA1 Message Date
Lephenixnoir 9828d2e3f2
meta: update build instructions 2022-08-21 11:55:28 +02:00
Lephenixnoir 65aaba96e1
install: trim the set of installed headers (and libm.a)
This is because all of these headers are included in direct style with
no subfolder so we need them to be in a quite public `include/` folder.
The Makefile installs in `include/openlibm/` but this only works with
extra `-I` flags that are quite annoying to enforce.

With this change, the only OpenLibm headers that are installed are named
`openlibm_*.h`, which is sufficient in terms of namespacing.

Also add a symlink libm.a -> libopenlibm.a.
2022-08-19 16:02:05 +02:00
Lephenixnoir feba6242e4
fenv: avoid internal includes in user-facing headers
A future cleanup will drastically reduce the set of headers being installed,
and we don't want to install internal headers in particular.
2022-08-19 16:02:05 +02:00
Lephenixnoir 63c74a4b92
also update make settings on GiteaPC
Follow-up to 39ede78797.
2021-05-25 21:45:51 +02:00
Lephenixnoir e67d553764
make: do not compile the static archive with -fPIC
No idea why it is enabled in the static version.
2021-05-21 14:22:02 +02:00
Lephenixnoir 08f772e6ab
fenv: provide environment primitives 2021-05-21 14:21:51 +02:00
Lephenixnoir 1cf5a91b46
make: add the sh3eb folder to the clean target 2021-05-21 14:07:39 +02:00
Lephenixnoir 8afd538dc8
add missing weak references for long double functions
This ensures that all standard long double functions are defined when
building with 64-bit long double.
2021-05-20 23:30:25 +02:00
Lephenixnoir 39ede78797
README: update make command due to toolchain changes 2021-05-20 23:30:25 +02:00
Lephenixnoir 668336366e
merge from upstream, updated to 0.7.5 2021-05-20 21:31:25 +02:00
Lephenixnoir d241d4f77a
fix aliases not using underscore prefixes in assembler code
long double functions, that are identical to double functions, usually
define themselves as weak references to their double counterpart.
However, the piece of assembler written for that produces

  .equ <name>l, <name>

but on SuperH C-exported symbols have leading underscores. This commit
adds an SH3 exception to use instead

  .equ _<name>l, _<name>

which fixes a number of long double functions.
2021-05-20 21:27:38 +02:00
Lephenixnoir 07a9090c98
add CMake instructions in the README 2021-05-02 15:07:48 +02:00
Elliot Saba f052f42bb3
Merge pull request #228 from JuliaMath/aa/hypotl
Fix incorrect results in `hypotl` near underflow
2021-02-17 09:04:36 -08:00
Steven G. Kargl 711654eeab
Fix incorrect results in `hypotl` near underflow
Fixes #224.
2021-02-10 12:44:19 -08:00
Viral B. Shah aeab19f47e Fix for #211
Co-authored by: @kargl
2021-02-08 09:39:30 -05:00
Viral B. Shah 5449705906
Merge pull request #227 from JuliaMath/vs/powf
Fix #211
2021-02-06 18:25:12 -05:00
Viral B. Shah 98f87135b0 Fix #211
Patched by importing latest msun version
2021-02-06 18:10:09 -05:00
Viral B. Shah 6a85b33182
Merge pull request #225 from JuliaMath/vs/strict_assign
Restore STRICT_ASSIGN on FreeBSD as suggested in #215
2021-02-06 18:09:23 -05:00
Viral B. Shah 40dac9dd77 Restore STRICT_ASSIGN on FreeBSD as suggested in #215
Co-authored-by: @kargl
2021-02-06 17:27:15 -05:00
Viral B. Shah 2d10c90c77
Merge pull request #218 from jcestibariz/fix-wasm32
Fix compilation errors on wasm32
2021-02-06 11:55:26 -05:00
Elliot Saba 5d70ac564c
Merge pull request #221 from maleadt/tb/static_fenv 2021-02-02 11:43:04 -08:00
Tim Besard 63aa8757f3 Make fenv methods static on additional platforms. 2021-02-01 13:48:31 +01:00
Lephenixnoir 22428cc5d2
add support for quick build with GiteaPC 2021-01-25 17:57:54 +01:00
JC Estibariz 9152b0d1b0 Fix compilation errors on wasm32 2020-12-01 13:17:32 -05:00
Elliot Saba 3cb804556f
Merge pull request #217 from epsilon-0/master
don't alter toolchain vars if already provided
2020-11-30 09:25:02 -08:00
Lephenixnoir 69b3140a0d
sh3eb: add new README file 2020-10-24 15:11:01 +02:00
Lephenixnoir 998328ebc0
sh3eb: move older README 2020-10-24 14:02:38 +02:00
Lephenixnoir 44c1cbb8eb
sh3eb: add suport for the sh3eb softfp platform 2020-10-24 13:55:39 +02:00
Lephenixnoir 89b463b811
sh3eb: only retain the softfp option of the MIPS fenv.h 2020-10-24 13:42:09 +02:00
Lephenixnoir 1b364a5edf
sh3eb: copy files from the MIPS softfp fenv.h 2020-10-24 13:42:09 +02:00
Aisha Tammy eb21e8abd1
don't alter toolchain vars if already provided 2020-10-23 15:36:23 +00:00
39 changed files with 710 additions and 71 deletions

4
.gitignore vendored
View File

@ -5,3 +5,7 @@
*.so*
*.dylib*
*.pc
# GiteaPC config files
giteapc-config-*.make
giteapc-config.make

View File

@ -10,41 +10,40 @@ VERSION = 0.7.0
SOMAJOR = 3
SOMINOR = 0
DESTDIR =
prefix = /usr/local
bindir = $(prefix)/bin
libdir = $(prefix)/lib
includedir = $(prefix)/include
prefix ?= /usr/local
bindir ?= $(prefix)/bin
libdir ?= $(prefix)/lib
includedir ?= $(prefix)/include
ifeq ($(OS), FreeBSD)
pkgconfigdir = $(prefix)/libdata/pkgconfig
pkgconfigdir ?= $(prefix)/libdata/pkgconfig
else
pkgconfigdir = $(libdir)/pkgconfig
pkgconfigdir ?= $(libdir)/pkgconfig
endif
USEGCC = 1
USECLANG = 0
USEGCC ?= 1
USECLANG ?= 0
ifneq (,$(findstring $(OS),Darwin FreeBSD OpenBSD))
USEGCC = 0
USECLANG = 1
USEGCC ?= 0
USECLANG ?= 1
endif
AR = $(TOOLPREFIX)ar
ifeq ($(ARCH),wasm32)
CC = clang-8
USEGCC = 0
CFLAGS_add += -fno-builtin -fno-strict-aliasing
USECLANG = 1
TOOLPREFIX = llvm-
endif
AR ?= $(TOOLPREFIX)ar
ifeq ($(USECLANG),1)
USEGCC = 0
USEGCC ?= 0
CC = clang
CFLAGS_add += -fno-builtin -fno-strict-aliasing
endif
ifeq ($(USEGCC),1)
CC = $(TOOLPREFIX)gcc
CC ?= $(TOOLPREFIX)gcc
CFLAGS_add += -fno-gnu89-inline -fno-builtin
endif
@ -106,7 +105,9 @@ else
SHLIB_EXT = so
SONAME_FLAG = -soname
endif
ifneq ($(ARCH),sh3eb)
CFLAGS_add += -fPIC
endif
shlibdir = $(libdir)
endif
@ -131,6 +132,10 @@ ifeq ($(ARCH),wasm32)
CFLAGS_arch += -ffreestanding -nostdlib -nostdinc --target=wasm32-unknown-unknown
endif
ifeq ($(ARCH),sh3eb)
CFLAGS_arch += -ffreestanding -nostdlib -m3 -mb
endif
# Add our "arch"-related FLAGS in. We separate arch-related flags out so that
# we can conveniently get at them for targets that don't want the rest of
# *FLAGS_add, such as the testing Makefile targets

View File

@ -53,7 +53,7 @@ endif
OLM_LIBS := libopenlibm.a
ifneq ($(ARCH), wasm32)
ifeq ($(filter wasm32 sh3eb,$(ARCH)),)
OLM_LIBS += libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT)
endif
@ -80,7 +80,7 @@ test/test-float: libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT)
$(MAKE) -C test test-float
clean:
rm -f aarch64/*.o amd64/*.o arm/*.o bsdsrc/*.o i387/*.o ld80/*.o ld128/*.o src/*.o powerpc/*.o mips/*.o s390/*.o
rm -f aarch64/*.o amd64/*.o arm/*.o bsdsrc/*.o i387/*.o ld80/*.o ld128/*.o src/*.o powerpc/*.o mips/*.o s390/*.o sh3eb/*.o
rm -f libopenlibm.a libopenlibm.*$(SHLIB_EXT)*
$(MAKE) -C test clean
@ -93,6 +93,9 @@ install-static: libopenlibm.a
mkdir -p $(DESTDIR)$(libdir)
cp -RpP -f libopenlibm.a $(DESTDIR)$(libdir)/
install-static-superh: install-static
ln -sf libopenlibm.a $(DESTDIR)$(libdir)/libm.a
install-shared: libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT)
mkdir -p $(DESTDIR)$(shlibdir)
cp -RpP -f libopenlibm.*$(SHLIB_EXT)* $(DESTDIR)$(shlibdir)/
@ -106,4 +109,15 @@ install-headers:
cp -RpP -f include/*.h $(DESTDIR)$(includedir)/openlibm
cp -RpP -f src/*.h $(DESTDIR)$(includedir)/openlibm
install: install-static install-shared install-pkgconfig install-headers
install-headers-superh:
mkdir -p $(DESTDIR)$(includedir)
cp -RpP -f \
include/openlibm.h \
include/openlibm_complex.h \
include/openlibm_defs.h \
include/openlibm_fenv.h \
include/openlibm_fenv_sh3eb.h \
include/openlibm_math.h \
$(DESTDIR)$(includedir)
install: install-static install-shared install-pkgconfig

38
README-OpenLibm.md Normal file
View File

@ -0,0 +1,38 @@
# OpenLibm
[![Travis](https://travis-ci.org/JuliaMath/openlibm.svg?branch=master)](https://travis-ci.org/JuliaMath/openlibm)
[![AppVeyor](https://ci.appveyor.com/api/projects/status/sia04r4089rr19uc/branch/master?svg=true)](https://ci.appveyor.com/project/ararslan/openlibm-19152/branch/master)
[OpenLibm](https://openlibm.org/) is an effort to have a high quality, portable, standalone
C mathematical library ([`libm`](http://en.wikipedia.org/wiki/libm)).
It can be used standalone in applications and programming language
implementations.
The project was born out of a need to have a good `libm` for the
[Julia programming language](http://www.julialang.org) that worked
consistently across compilers and operating systems, and in 32-bit and
64-bit environments.
## Platform support
OpenLibm builds on Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD, and
DragonFly BSD. It builds with both GCC and clang. Although largely
tested and widely used on the x86 and x86-64 architectures, OpenLibm
also supports arm, aarch64, ppc64le, mips, wasm32, and s390(x).
## Build instructions
1. Use GNU Make to build OpenLibm. This is `make` on most systems, but `gmake` on BSDs.
2. Use `make USEGCC=1` to build with GCC. This is the default on
Linux and Windows.
3. Use `make USECLANG=1` to build with clang. This is the default on OS X, FreeBSD,
and OpenBSD.
4. Use `make ARCH=wasm32` to build the wasm32 library with clang. Requires clang-8.
5. Architectures are auto-detected. Use `make ARCH=i386` to force a
build for i386. Other supported architectures are i486, i586, and
i686. GCC 4.8 is the minimum requirement for correct codegen on
older 32-bit architectures.
## Acknowledgements
PowerPC support for openlibm was graciously sponsored by IBM.

View File

@ -1,38 +1,60 @@
# OpenLibm
# Soft-FP sh3eb port of OpenLibm
[![Travis](https://travis-ci.org/JuliaMath/openlibm.svg?branch=master)](https://travis-ci.org/JuliaMath/openlibm)
[![AppVeyor](https://ci.appveyor.com/api/projects/status/sia04r4089rr19uc/branch/master?svg=true)](https://ci.appveyor.com/project/ararslan/openlibm-19152/branch/master)
This is a fork of [OpenLibm](https://github.com/JuliaMath/openlibm) with support for the sh3eb architecture, intended for add-in programming on SuperH CASIO calculators.
[OpenLibm](https://openlibm.org/) is an effort to have a high quality, portable, standalone
C mathematical library ([`libm`](http://en.wikipedia.org/wiki/libm)).
It can be used standalone in applications and programming language
implementations.
## Installing with GiteaPC
The project was born out of a need to have a good `libm` for the
[Julia programming language](http://www.julialang.org) that worked
consistently across compilers and operating systems, and in 32-bit and
64-bit environments.
This library can be installed automatically as part of the fxSDK with [GiteaPC](https://gitea.planet-casio.com/Lephenixnoir/GiteaPC):
## Platform support
```bash
% giteapc install Lephenixnoir/OpenLibm
```
OpenLibm builds on Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD, and
DragonFly BSD. It builds with both GCC and clang. Although largely
tested and widely used on the x86 and x86-64 architectures, OpenLibm
also supports arm, aarch64, ppc64le, mips, wasm32, and s390(x).
## Building manually
## Build instructions
You will need a GCC toolchain built with `--target=sh3eb-elf`, such as the [`sh-elf-gcc`](https://gitea.planet-casio.com/Lephenixnoir/sh-elf-gcc) commonly used on Planète Casio.
1. Use GNU Make to build OpenLibm. This is `make` on most systems, but `gmake` on BSDs.
2. Use `make USEGCC=1` to build with GCC. This is the default on
Linux and Windows.
3. Use `make USECLANG=1` to build with clang. This is the default on OS X, FreeBSD,
and OpenBSD.
4. Use `make ARCH=wasm32` to build the wasm32 library with clang. Requires clang-8.
5. Architectures are auto-detected. Use `make ARCH=i386` to force a
build for i386. Other supported architectures are i486, i586, and
i686. GCC 4.8 is the minimum requirement for correct codegen on
older 32-bit architectures.
You can install directly in the internal folder of your compiler, or somewhere else if you have a more detailed setup.
## Acknowledgements
```bash
# Example 1: Use the compiler's internal folder
% COMPILER_DIR="$(sh-elf-gcc --print-file-name=.)"
% LIBDIR="$COMPILER_DIR"
% INCDIR="$COMPILER_DIR/include"
# Example 2: Using the fxSDK's custom setup
% LIBDIR="$(fxsdk path lib)"
% INCDIR="$(fxsdk path include)"
```
PowerPC support for openlibm was graciously sponsored by IBM.
You can then build and install the static library and the headers.
```bash
% make USEGCC=1 TOOLPREFIX=sh-elf- AR=sh-elf-ar CC=sh-elf-gcc \
libdir="$LIBDIR" includedir="$INCDIR" \
install-static-superh install-headers-superh
```
The `-superh` targets differ from the the normal targets in the following ways:
* `install-static-superh` also creates a symlink `libm.a -> libopenlibm.a`.
* `install-headers-superh` installs directly in `$LIBDIR` instead of `$LIBDIR/openlibm` since OpenLibm headers reference each other without that prefix and enforcing the correct `-I` in every project is quite painful. In addition, it skips internal and non-SuperH headers.
## Using the library
Include the headers `<openlibm_complex.h>`, `<openlibm_fenv.h>` and `<openlibm_math.h>`. Or, if you are using a suitable libc like [fxlibc](https://gitea.planet-casio.com/Vhex-Kernel-Core/fxlibc/), include directly the standard headers `<complex.h>`, `<fenv.h>` and `<math.h>`.
Link with `-lm`. In a Makefile, update your `LDFLAGS`:
```
LDFLAGS += -lm
```
In CMake, use [`target_link_libraries()`](https://cmake.org/cmake/help/latest/command/target_link_libraries.html):
```cmake
target_link_libraries(<TARGET> PUBLIC -lm)
```
## README and Licensing
See the original README file in [README-OpenLibm.md](README-OpenLibm.md). OpenLibm contains code covered by various licenses, see [LICENSE.md](LICENSE.md).

View File

@ -26,7 +26,6 @@
* $FreeBSD: src/lib/msun/arm/fenv.c,v 1.3 2011/10/16 05:37:56 das Exp $
*/
#define __fenv_static
#include <openlibm_fenv.h>
#ifdef __GNUC_GNU_INLINE__

View File

@ -38,6 +38,7 @@
* acknowledged.
*/
#include <float.h>
#include <openlibm_math.h>
#include "mathimpl.h"
@ -312,3 +313,7 @@ neg_gam(x)
if (sgn < 0) y = -y;
return (M_PI / (y*z));
}
#if (LDBL_MANT_DIG == 53)
openlibm_weak_reference(tgamma, tgammal);
#endif

24
giteapc.make Normal file
View File

@ -0,0 +1,24 @@
# giteapc: version=1 depends=Lephenixnoir/fxsdk,Lephenixnoir/sh-elf-gcc
-include giteapc-config.make
# Use the fxSDK's default paths unless specified otherwise on the command line
LIBDIR ?= $(shell fxsdk path lib)
INCDIR ?= $(shell fxsdk path include)
FLAGS := USEGCC=1 TOOLPREFIX=sh-elf- CC=sh-elf-gcc AR=sh-elf-ar \
libdir="$(LIBDIR)" includedir="$(INCDIR)"
configure:
@ true
build:
@ make $(FLAGS)
install:
@ make $(FLAGS) install-static-superh install-headers-superh
uninstall:
@ echo "uninstall not supported for OpenLibm, skipping"
.PHONY: configure build install uninstall

View File

@ -14,6 +14,8 @@
#include <openlibm_fenv_mips.h>
#elif defined(__s390__)
#include <openlibm_fenv_s390.h>
#elif defined(__sh3__)
#include <openlibm_fenv_sh3eb.h>
#else
#error "Unsupported platform"
#endif

View File

@ -0,0 +1,98 @@
/*-
* Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _FENV_H_
#define _FENV_H_
#include <stdint.h>
#ifndef __fenv_static
#define __fenv_static static
#endif
typedef uint32_t fenv_t;
typedef uint32_t fexcept_t;
/* Exception flags */
#define _FPUSW_SHIFT 16
#define FE_INVALID 0x0001
#define FE_DIVBYZERO 0x0002
#define FE_OVERFLOW 0x0004
#define FE_UNDERFLOW 0x0008
#define FE_INEXACT 0x0010
#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \
FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
/* Rounding modes */
#define FE_TONEAREST 0x0000
#define FE_TOWARDZERO 0x0001
#define FE_UPWARD 0x0002
#define FE_DOWNWARD 0x0003
#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \
FE_UPWARD | FE_TOWARDZERO)
#ifdef __cplusplus
extern "C" {
#endif
/* Default floating-point environment */
extern const fenv_t __fe_dfl_env;
#define FE_DFL_ENV (&__fe_dfl_env)
/* We need to be able to map status flag positions to mask flag positions */
#define _ENABLE_SHIFT 5
#define _ENABLE_MASK (FE_ALL_EXCEPT << _ENABLE_SHIFT)
int feclearexcept(int __excepts);
int fegetexceptflag(fexcept_t *__flagp, int __excepts);
int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
int feraiseexcept(int __excepts);
int fetestexcept(int __excepts);
int fegetround(void);
int fesetround(int __round);
int fegetenv(fenv_t *__envp);
int feholdexcept(fenv_t *__envp);
int fesetenv(const fenv_t *__envp);
int feupdateenv(const fenv_t *__envp);
#if __BSD_VISIBLE
/* We currently provide no external definitions of the functions below. */
int feenableexcept(int __mask);
int fedisableexcept(int __mask);
int fegetexcept(void);
#endif /* __BSD_VISIBLE */
#ifdef __cplusplus
}
#endif
#endif /* !_FENV_H_ */

View File

@ -304,6 +304,7 @@ OLM_DLLEXPORT double trunc(double);
* BSD math library entry points
*/
#if __BSD_VISIBLE
OLM_DLLEXPORT int isinff(float) __pure2;
OLM_DLLEXPORT int isnanf(float) __pure2;
/*

View File

@ -26,7 +26,6 @@
* $FreeBSD$
*/
#define __fenv_static
#include <openlibm_fenv.h>
#ifdef __GNUC_GNU_INLINE__

1
sh3eb/Make.files Normal file
View File

@ -0,0 +1 @@
$(CUR_SRCS) = fenv.c

2
sh3eb/assert.h Normal file
View File

@ -0,0 +1,2 @@
#pragma once
#define assert(b)

7
sh3eb/ctype.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
static int isxdigit(int c)
{
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') ||
(c >= 'a' && c <= 'f');
}

183
sh3eb/fenv-softfloat.h Normal file
View File

@ -0,0 +1,183 @@
/*-
* Copyright (c) 2004-2011 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _FENV_H_
#error "This file is meant to be included only by <fenv.h>."
#endif
/*
* This file implements the functionality of <fenv.h> on platforms that
* lack an FPU and use softfloat in libc for floating point. To use it,
* you must write an <fenv.h> that provides the following:
*
* - a typedef for fenv_t, which may be an integer or struct type
* - a typedef for fexcept_t (XXX This file assumes fexcept_t is a
* simple integer type containing the exception mask.)
* - definitions of FE_* constants for the five exceptions and four
* rounding modes in IEEE 754, as described in fenv(3)
* - a definition, and the corresponding external symbol, for FE_DFL_ENV
* - a macro __set_env(env, flags, mask, rnd), which sets the given fenv_t
* from the exception flags, mask, and rounding mode
* - macros __env_flags(env), __env_mask(env), and __env_round(env), which
* extract fields from an fenv_t
* - a definition of __fenv_static
*
* If the architecture supports an optional FPU, it's recommended that you
* define fenv_t and fexcept_t to match the hardware ABI. Otherwise, it
* doesn't matter how you define them.
*/
extern int __softfloat_float_exception_flags;
extern int __softfloat_float_exception_mask;
extern int __softfloat_float_rounding_mode;
__fenv_static inline int
feclearexcept(int __excepts)
{
__softfloat_float_exception_flags &= ~__excepts;
return (0);
}
__fenv_static inline int
fegetexceptflag(fexcept_t *__flagp, int __excepts)
{
*__flagp = __softfloat_float_exception_flags & __excepts;
return (0);
}
__fenv_static inline int
fesetexceptflag(const fexcept_t *__flagp, int __excepts)
{
__softfloat_float_exception_flags &= ~__excepts;
__softfloat_float_exception_flags |= *__flagp & __excepts;
return (0);
}
__fenv_static inline int
feraiseexcept(int __excepts)
{
__softfloat_float_exception_flags |= __excepts;
return (0);
}
__fenv_static inline int
fetestexcept(int __excepts)
{
return (__softfloat_float_exception_flags & __excepts);
}
__fenv_static inline int
fegetround(void)
{
return (__softfloat_float_rounding_mode);
}
__fenv_static inline int
fesetround(int __round)
{
__softfloat_float_rounding_mode = __round;
return (0);
}
__fenv_static inline int
fegetenv(fenv_t *__envp)
{
__set_env(*__envp, __softfloat_float_exception_flags,
__softfloat_float_exception_mask, __softfloat_float_rounding_mode);
return (0);
}
__fenv_static inline int
feholdexcept(fenv_t *__envp)
{
fenv_t __env;
fegetenv(__envp);
__softfloat_float_exception_flags = 0;
__softfloat_float_exception_mask = 0;
return (0);
}
__fenv_static inline int
fesetenv(const fenv_t *__envp)
{
__softfloat_float_exception_flags = __env_flags(*__envp);
__softfloat_float_exception_mask = __env_mask(*__envp);
__softfloat_float_rounding_mode = __env_round(*__envp);
return (0);
}
__fenv_static inline int
feupdateenv(const fenv_t *__envp)
{
int __oflags = __softfloat_float_exception_flags;
fesetenv(__envp);
feraiseexcept(__oflags);
return (0);
}
#if __BSD_VISIBLE
/* We currently provide no external definitions of the functions below. */
__fenv_static inline int
feenableexcept(int __mask)
{
int __omask = __softfloat_float_exception_mask;
__softfloat_float_exception_mask |= __mask;
return (__omask);
}
__fenv_static inline int
fedisableexcept(int __mask)
{
int __omask = __softfloat_float_exception_mask;
__softfloat_float_exception_mask &= ~__mask;
return (__omask);
}
__fenv_static inline int
fegetexcept(void)
{
return (__softfloat_float_exception_mask);
}
#endif /* __BSD_VISIBLE */

71
sh3eb/fenv.c Normal file
View File

@ -0,0 +1,71 @@
/*-
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#define __fenv_static
#include "openlibm_fenv.h"
#include <float.h>
#ifdef __GNUC_GNU_INLINE__
#error "This file must be compiled with C99 'inline' semantics"
#endif
/*
* Hopefully the system ID byte is immutable, so it's valid to use
* this as a default environment.
*/
const fenv_t __fe_dfl_env = 0;
int __softfloat_float_exception_flags = 0;
int __softfloat_float_exception_mask = 0;
int __softfloat_float_rounding_mode = FLT_ROUNDS;
#define __set_env(env, flags, mask, rnd) env = ((flags) \
| (mask)<<_FPUSW_SHIFT \
| (rnd) << 24)
#define __env_flags(env) ((env) & FE_ALL_EXCEPT)
#define __env_mask(env) (((env) >> _FPUSW_SHIFT) \
& FE_ALL_EXCEPT)
#define __env_round(env) (((env) >> 24) & _ROUND_MASK)
#include "fenv-softfloat.h"
extern inline int feclearexcept(int __excepts);
extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts);
extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
extern inline int feraiseexcept(int __excepts);
extern inline int fetestexcept(int __excepts);
extern inline int fegetround(void);
extern inline int fesetround(int __round);
extern inline int fegetenv(fenv_t *__envp);
extern inline int feholdexcept(fenv_t *__envp);
extern inline int fesetenv(const fenv_t *__envp);
extern inline int feupdateenv(const fenv_t *__envp);
extern inline int feenableexcept(int __mask);
extern inline int fedisableexcept(int __mask);
extern inline int fegetexcept(void);

4
sh3eb/string.h Normal file
View File

@ -0,0 +1,4 @@
#pragma once
#include <stddef.h>
void *memset(void *mem, int fill, size_t size);

View File

@ -34,9 +34,15 @@
#else
#ifdef __ELF__
#ifdef __STDC__
#if defined(__sh3__)
#define openlibm_weak_reference(sym,alias) \
__asm__(".weak _" #alias); \
__asm__(".equ _" #alias ", _" #sym)
#else
#define openlibm_weak_reference(sym,alias) \
__asm__(".weak " #alias); \
__asm__(".equ " #alias ", " #sym)
#endif /* __sh3__ */
#ifdef __warn_references
#define openlibm_warn_references(sym,msg) __warn_references(sym,msg)
#else

View File

@ -29,6 +29,7 @@
* acosh(NaN) is NaN without signal.
*/
#include <float.h>
#include <openlibm_math.h>
#include "math_private.h"
@ -61,3 +62,7 @@ __ieee754_acosh(double x)
return log1p(t+sqrt(2.0*t+t*t));
}
}
#if (LDBL_MANT_DIG == 53)
openlibm_weak_reference(acosh, acoshl);
#endif

View File

@ -33,6 +33,7 @@
*
*/
#include <float.h>
#include <openlibm_math.h>
#include "math_private.h"
@ -61,3 +62,7 @@ __ieee754_atanh(double x)
t = 0.5*log1p((x+x)/(one-x));
if(hx>=0) return t; else return -t;
}
#if (LDBL_MANT_DIG == 53)
openlibm_weak_reference(atanh, atanhl);
#endif

View File

@ -35,6 +35,7 @@
* only cosh(0)=1 is exact for finite x.
*/
#include <float.h>
#include <openlibm_math.h>
#include "math_private.h"
@ -78,3 +79,7 @@ __ieee754_cosh(double x)
/* |x| > overflowthresold, cosh(x) overflow */
return huge*huge;
}
#if (LDBL_MANT_DIG == 53)
openlibm_weak_reference(cosh, coshl);
#endif

View File

@ -165,3 +165,7 @@ __ieee754_exp(double x) /* default IEEE double exp */
return y*twopk*twom1000;
}
}
#if (LDBL_MANT_DIG == 53)
openlibm_weak_reference(exp, expl);
#endif

View File

@ -82,7 +82,7 @@ hypotl(long double x, long double y)
man_t manh, manl;
GET_LDBL_MAN(manh,manl,b);
if((manh|manl)==0) return a;
t1=0;
t1=1;
SET_HIGH_WORD(t1,ESW(MAX_EXP-2)); /* t1=2^(MAX_EXP-2) */
b *= t1;
a *= t1;

View File

@ -65,6 +65,7 @@
* to produce the hexadecimal values shown.
*/
#include <float.h>
#include <openlibm_math.h>
#include "math_private.h"
@ -139,3 +140,7 @@ __ieee754_log(double x)
return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
}
}
#if (LDBL_MANT_DIG == 53)
openlibm_weak_reference(log, logl);
#endif

View File

@ -22,6 +22,7 @@
* in not-quite-routine extra precision.
*/
#include <float.h>
#include <openlibm_math.h>
#include "math_private.h"
@ -86,3 +87,7 @@ __ieee754_log10(double x)
return val_lo + val_hi;
}
#if (LDBL_MANT_DIG == 53)
openlibm_weak_reference(log10, log10l);
#endif

View File

@ -24,6 +24,7 @@
* in not-quite-routine extra precision.
*/
#include <float.h>
#include <openlibm_math.h>
#include "math_private.h"
@ -109,3 +110,7 @@ __ieee754_log2(double x)
return val_lo + val_hi;
}
#if (LDBL_MANT_DIG == 53)
openlibm_weak_reference(log2, log2l);
#endif

View File

@ -57,6 +57,7 @@
* to produce the hexadecimal values shown.
*/
#include <float.h>
#include <openlibm_math.h>
#include "math_private.h"
@ -310,3 +311,7 @@ __ieee754_pow(double x, double y)
else SET_HIGH_WORD(z,j);
return s*z;
}
#if (LDBL_MANT_DIG == 53)
openlibm_weak_reference(pow, powl);
#endif

View File

@ -25,6 +25,9 @@ bp[] = {1.0, 1.5,},
dp_h[] = { 0.0, 5.84960938e-01,}, /* 0x3f15c000 */
dp_l[] = { 0.0, 1.56322085e-06,}, /* 0x35d1cfdc */
zero = 0.0,
half = 0.5,
qrtr = 0.25,
thrd = 3.33333343e-01, /* 0x3eaaaaab */
one = 1.0,
two = 2.0,
two24 = 16777216.0, /* 0x4b800000 */
@ -74,7 +77,7 @@ __ieee754_powf(float x, float y)
/* y!=zero: result is NaN if either arg is NaN */
if(ix > 0x7f800000 ||
iy > 0x7f800000)
return (x+0.0F)+(y+0.0F);
return nan_mix(x, y);
/* determine if y is an odd int when x < 0
* yisint = 0 ... y is not an integer
@ -103,15 +106,10 @@ __ieee754_powf(float x, float y)
if(iy==0x3f800000) { /* y is +-1 */
if(hy<0) return one/x; else return x;
}
if(hy==0x40000000) return x*x; /* y is 2 */
if(hy==0x40400000) return x*x*x; /* y is 3 */
if(hy==0x40800000) { /* y is 4 */
u = x*x;
return u*u;
}
if(hy==0x3f000000) { /* y is 0.5 */
if(hy==0x40000000) return x*x; /* y is 2 */
if(hy==0x3f000000) { /* y is 0.5 */
if(hx>=0) /* x >= +0 */
return __ieee754_sqrtf(x);
return __ieee754_sqrtf(x);
}
ax = fabsf(x);
@ -139,12 +137,12 @@ __ieee754_powf(float x, float y)
/* |y| is huge */
if(iy>0x4d000000) { /* if |y| > 2**27 */
/* over/underflow if x is not close to one */
if(ix<0x3f7ffff8) return (hy<0)? sn*huge*huge:sn*tiny*tiny;
if(ix<0x3f7ffff7) return (hy<0)? sn*huge*huge:sn*tiny*tiny;
if(ix>0x3f800007) return (hy>0)? sn*huge*huge:sn*tiny*tiny;
/* now |1-x| is tiny <= 2**-20, suffice to compute
log(x) by x-x^2/2+x^3/3-x^4/4 */
t = ax-1; /* t has 20 trailing zeros */
w = (t*t)*((float)0.5-t*((float)0.333333333333-t*(float)0.25));
w = (t*t)*(half-t*(thrd-t*qrtr));
u = ivln2_h*t; /* ivln2_h has 16 sig. bits */
v = t*ivln2_l-w*ivln2;
t1 = u+v;
@ -183,10 +181,10 @@ __ieee754_powf(float x, float y)
r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
r += s_l*(s_h+s);
s2 = s_h*s_h;
t_h = (float)3.0+s2+r;
t_h = 3+s2+r;
GET_FLOAT_WORD(is,t_h);
SET_FLOAT_WORD(t_h,is&0xfffff000);
t_l = r-((t_h-(float)3.0)-s2);
t_l = r-((t_h-3)-s2);
/* u+v = s*(1+...) */
u = s_h*t_h;
v = s_l*t_h+t_l*s;
@ -198,7 +196,7 @@ __ieee754_powf(float x, float y)
z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
z_l = cp_l*p_h+p_l*cp+dp_l[k];
/* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
t = (float)n;
t = n;
t1 = (((z_h+z_l)+dp_h[k])+t);
GET_FLOAT_WORD(is,t1);
SET_FLOAT_WORD(t1,is&0xfffff000);

View File

@ -32,6 +32,7 @@
* only sinh(0)=0 is exact for finite x.
*/
#include <float.h>
#include <openlibm_math.h>
#include "math_private.h"
@ -72,3 +73,7 @@ __ieee754_sinh(double x)
/* |x| > overflowthresold, sinh(x) overflow */
return x*shuge;
}
#if (LDBL_MANT_DIG == 53)
openlibm_weak_reference(sinh, sinhl);
#endif

View File

@ -43,6 +43,8 @@
#include "mips_fpmath.h"
#elif defined(__s390__)
#include "s390_fpmath.h"
#elif defined(__sh3__)
#include "sh3eb_fpmath.h"
#endif
/* Definitions provided directly by GCC and Clang. */

View File

@ -203,10 +203,9 @@ do { \
} while (0)
//VBS
#ifndef __FreeBSD__
#define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval))
/* VBS
#else
#ifdef FLT_EVAL_METHOD
// Attempt to get strict C99 semantics for assignment with non-C99 compilers.
#if FLT_EVAL_METHOD == 0 || __GNUC__ == 0
@ -215,7 +214,7 @@ do { \
#define STRICT_ASSIGN(type, lval, rval) do { \
volatile type __lval; \
\
if (sizeof(type) >= sizeof(double)) \
if (sizeof(type) >= sizeof(long double)) \
(lval) = (rval); \
else { \
__lval = (rval); \
@ -224,13 +223,31 @@ do { \
} while (0)
#endif
#endif
*/
#endif
/*
* Common routine to process the arguments to nan(), nanf(), and nanl().
*/
void __scan_nan(u_int32_t *__words, int __num_words, const char *__s);
/*
* Mix 1 or 2 NaNs. First add 0 to each arg. This normally just turns
* signaling NaNs into quiet NaNs by setting a quiet bit. We do this
* because we want to never return a signaling NaN, and also because we
* don't want the quiet bit to affect the result. Then mix the converted
* args using addition. The result is typically the arg whose mantissa
* bits (considered as in integer) are largest.
*
* Technical complications: the result in bits might depend on the precision
* and/or on compiler optimizations, especially when different register sets
* are used for different precisions. Try to make the result not depend on
* at least the precision by always doing the main mixing step in long double
* precision. Try to reduce dependencies on optimizations by adding the
* the 0's in different precisions (unless everything is in long double
* precision).
*/
#define nan_mix(x, y) (((x) + 0.0L) + ((y) + 0))
#ifdef __GNUCLIKE_ASM
/* Asm versions of some functions. */

View File

@ -24,6 +24,7 @@
* := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2)))
*/
#include <float.h>
#include <openlibm_math.h>
#include "math_private.h"
@ -55,3 +56,7 @@ asinh(double x)
}
if(hx>0) return w; else return -w;
}
#if (LDBL_MANT_DIG == 53)
openlibm_weak_reference(asinh, asinhl);
#endif

View File

@ -107,6 +107,7 @@
* erfc/erf(NaN) is NaN
*/
#include <float.h>
#include <openlibm_math.h>
#include "math_private.h"
@ -299,3 +300,8 @@ erfc(double x)
if(hx>0) return tiny*tiny; else return two-tiny;
}
}
#if (LDBL_MANT_DIG == 53)
openlibm_weak_reference(erf, erfl);
openlibm_weak_reference(erfc, erfcl);
#endif

View File

@ -215,3 +215,7 @@ expm1(double x)
}
return y;
}
#if (LDBL_MANT_DIG == 53)
openlibm_weak_reference(expm1, expm1l);
#endif

View File

@ -173,3 +173,7 @@ log1p(double x)
if(k==0) return f-(hfsq-s*(hfsq+R)); else
return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f);
}
#if (LDBL_MANT_DIG == 53)
openlibm_weak_reference(log1p, log1pl);
#endif

View File

@ -37,6 +37,7 @@
* only tanh(0)=0 is exact for finite argument.
*/
#include <float.h>
#include <openlibm_math.h>
#include "math_private.h"
@ -76,3 +77,7 @@ tanh(double x)
}
return (jx>=0)? z: -z;
}
#if (LDBL_MANT_DIG == 53)
openlibm_weak_reference(tanh, tanhl);
#endif

57
src/sh3eb_fpmath.h Normal file
View File

@ -0,0 +1,57 @@
/*-
* Copyright (c) 2002, 2003 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
union IEEEl2bits {
long double e;
struct {
#ifndef __BIG_ENDIAN__
unsigned int manl :32;
unsigned int manh :20;
unsigned int exp :11;
unsigned int sign :1;
#else
unsigned int sign :1;
unsigned int exp :11;
unsigned int manh :20;
unsigned int manl :32;
#endif
} bits;
};
#define LDBL_NBIT 0
#define mask_nbit_l(u) ((void)0)
#define LDBL_IMPLICIT_NBIT
#define LDBL_MANH_SIZE 20
#define LDBL_MANL_SIZE 32
#define LDBL_TO_ARRAY32(u, a) do { \
(a)[0] = (uint32_t)(u).bits.manl; \
(a)[1] = (uint32_t)(u).bits.manh; \
} while(0)

12
test/test-211.c Normal file
View File

@ -0,0 +1,12 @@
#include <stdio.h>
#include <math.h>
#include <assert.h>
int
main()
{
float x = 0xd.65874p-4f;
float y = 4.0f;
float z = powf (x, y);
assert(z==0x1.f74424p-2);
}