diff options
author | Shin-ichiro KAWASAKI <shinichiro.kawasaki.mg@hitachi.com> | 2009-08-31 16:25:42 +0900 |
---|---|---|
committer | Tony Sim <sim.chinyeow@renesas.com> | 2009-08-31 16:25:42 +0900 |
commit | d87945b4e706dbbacd71f6a3fd2e96162e970094 (patch) | |
tree | 9a4dab6605f3681e8e1e8c7aacf42b4e44e7fd4b /libm | |
parent | 90ec5f2a3f581927ffef55733e8d531890fdc90e (diff) | |
download | bionic-d87945b4e706dbbacd71f6a3fd2e96162e970094.zip bionic-d87945b4e706dbbacd71f6a3fd2e96162e970094.tar.gz bionic-d87945b4e706dbbacd71f6a3fd2e96162e970094.tar.bz2 |
added and modified libm to support SuperH architecture
Diffstat (limited to 'libm')
-rw-r--r-- | libm/Android.mk | 12 | ||||
-rw-r--r-- | libm/sh/_fpmath.h | 58 | ||||
-rw-r--r-- | libm/sh/fenv.c | 30 | ||||
-rw-r--r-- | libm/sh/fenv.h | 240 |
4 files changed, 339 insertions, 1 deletions
diff --git a/libm/Android.mk b/libm/Android.mk index 8f0c3b1..fa73aff 100644 --- a/libm/Android.mk +++ b/libm/Android.mk @@ -170,7 +170,17 @@ else libm_common_includes = $(LOCAL_PATH)/i386 $(LOCAL_PATH)/i387 else - $(error "Unknown architecture") + ifeq ($(TARGET_OS)-$(TARGET_ARCH),linux-sh) + libm_common_src_files += \ + sh/fenv.c \ + src/s_scalbln.c \ + src/s_scalbn.c \ + src/s_scalbnf.c + + libm_common_includes = $(LOCAL_PATH)/sh + else + $(error "Unknown architecture") + endif endif endif diff --git a/libm/sh/_fpmath.h b/libm/sh/_fpmath.h new file mode 100644 index 0000000..f75ec7b --- /dev/null +++ b/libm/sh/_fpmath.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2009 Android Open Source Project, All rights reserved. + * Derived from "bionic/libm/arm/_fpmath.h" + * Copyright (c) 2002, 2003 David Schultz <das@FreeBSD.ORG> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + */ + +/* + * Assumes that 'long double' on SH-linux is just an alias for 'double'. + */ +union IEEEl2bits { + long double e; + struct { +#if __BYTE_ORDER == __LITTLE_ENDIAN + unsigned int manl :32; + unsigned int manh :20; + unsigned int exp :11; + unsigned int sign :1; +#elif __BYTE_ORDER == __BIG_ENDIAN + unsigned int sign :1; + unsigned int exp :11; + unsigned int manh :20; + unsigned int manl :32; +#endif + } bits; +}; + +/* + * LDBL_NBIT is a mask indicating the position of the integer + * bit in a long double. But SH4 does not support it. + */ +#define LDBL_NBIT 0 +#define mask_nbit_l(u) ((void)0) + +#define LDBL_MANH_SIZE 20 +#define LDBL_MANL_SIZE 32 diff --git a/libm/sh/fenv.c b/libm/sh/fenv.c new file mode 100644 index 0000000..ca8f476 --- /dev/null +++ b/libm/sh/fenv.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2009 Android Open Source Project, All rights reserved. + * Derived from "bionic/libm/arm/fenv.c" + * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + */ + +long __fpscr_values[2] = { 0L, 0x80000L }; diff --git a/libm/sh/fenv.h b/libm/sh/fenv.h new file mode 100644 index 0000000..e872f47 --- /dev/null +++ b/libm/sh/fenv.h @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2009 Android Open Source Project, All rights reserved. + * Derived from "bionic/libm/arm/fenv.h" + * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include <stdio.h> +#include <sys/types.h> + +typedef uint32_t fenv_t; +typedef uint32_t fexcept_t; + +/* Exception flags */ +#define FE_INVALID 0x0010 +#define FE_DIVBYZERO 0x0008 +#define FE_OVERFLOW 0x0004 +#define FE_UNDERFLOW 0x0002 +#define FE_INEXACT 0x0001 +#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 /* not supporetd */ +#define FE_DOWNWARD 0x0003 /* not supporetd */ +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) + +/* bit shift for FPSCR mapping */ +#define _FPUE_CAUSE_SHIFT 12 +#define _FPUE_ENABLE_SHIFT 17 +#define _FPUE_FLAG_SHIFT 2 + +/* bit shifters */ +#define _FPUE_CAUSE(_EXCS) ((_EXCS) << _FPUE_CAUSE_SHIFT) +#define _FPUE_ENABLE(_EXCS) ((_EXCS) << _FPUE_ENABLE_SHIFT) +#define _FPUE_FLAG(_EXCS) ((_EXCS) << _FPUE_FLAG_SHIFT) + +#define _GET_FPUE_CAUSE(_FPUE) (((_FPUE) >> _FPUE_CAUSE_SHIFT) & FE_ALL_EXCEPT) +#define _GET_FPUE_ENABLE(_FPUE) (((_FPUE) >> _FPUE_ENABLE_SHIFT)& FE_ALL_EXCEPT) +#define _GET_FPUE_FLAG(_FPUE) (((_FPUE) >> _FPUE_FLAG_SHIFT) & FE_ALL_EXCEPT) + + +/* FPSCR register accessors */ +#ifdef __SH4_NOFPU__ +#define __read_fpscr(_ptr) +#define __write_fpscr(_val) +#else +#define __read_fpscr(_ptr) __asm __volatile("sts fpscr, %0" : "=r" (*(_ptr))) +#define __write_fpscr(_val) __asm __volatile("lds %0, fpscr" : : "r" (_val)) +#endif + + +/* functions for libm */ +static __inline int +feclearexcept(int __excepts) +{ + uint32_t __fpscr; + + __read_fpscr(&__fpscr); + __fpscr &= ~_FPUE_FLAG(__excepts); + __write_fpscr(__fpscr); + return (0); +} + +static __inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + uint32_t __fpscr; + + __read_fpscr(&__fpscr); + *__flagp = _GET_FPUE_FLAG(__fpscr) & __excepts; + return (0); +} + + +static __inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + uint32_t __fpscr; + + __read_fpscr(&__fpscr); + __fpscr &= ~_FPUE_FLAG(__excepts); + __fpscr |= ~_FPUE_FLAG(*__flagp & __excepts); + __write_fpscr(__fpscr); + return (0); +} + + +static __inline int +feraiseexcept(int __excepts) +{ + fexcept_t __ex = __excepts; + + fesetexceptflag(&__ex, __excepts); /* XXX */ + return (0); +} + + +static __inline int +fetestexcept(int __excepts) +{ + fexcept_t __ex; + + fegetexceptflag(&__ex, __excepts); + return (__ex); +} + + +static __inline int +fegetround(void) +{ + uint32_t __fpscr = 0; + + __read_fpscr(&__fpscr); + return (__fpscr & _ROUND_MASK); +} + +static __inline int +fesetround(int __round) +{ + uint32_t __fpscr = 0; + + if (__round == FE_UPWARD || __round == FE_DOWNWARD) { + fprintf(stderr, "libm superh : " + "upward/downward rounding not supporetd.\n"); + return -1; + } + + __read_fpscr(&__fpscr); + __fpscr &= ~_ROUND_MASK; + __fpscr |= (__round & _ROUND_MASK); + __write_fpscr(__fpscr); + return (0); +} + +static __inline int +fegetenv(fenv_t *__envp) +{ + __read_fpscr(__envp); + return (0); +} + +static __inline int +feholdexcept(fenv_t *__envp) +{ + uint32_t __fpscr; + + __read_fpscr(&__fpscr); + *__envp = __fpscr; + __fpscr &= ~_FPUE_FLAG(FE_ALL_EXCEPT); + __write_fpscr(__fpscr); + return (0); +} + + +static __inline int +fesetenv(const fenv_t *__envp) +{ + __write_fpscr(*__envp); + return (0); +} + + +static __inline int +feupdateenv(const fenv_t *__envp) +{ + uint32_t __fpscr; + + __read_fpscr(&__fpscr); + __write_fpscr(*__envp); + feraiseexcept(_GET_FPUE_FLAG(__fpscr)); + return (0); +} + +#if __BSD_VISIBLE + +static __inline int +feenableexcept(int __mask) +{ + uint32_t __old_fpscr, __new_fpscr; + + __read_fpscr(&__old_fpscr); + __new_fpscr = __old_fpscr | _FPUE_ENABLE(__mask & FE_ALL_EXCEPT); + __write_fpscr(__new_fpscr); + return (_GET_FPUE_ENABLE(__old_fpscr)); +} + +static __inline int +fedisableexcept(int __mask) +{ + uint32_t __old_fpscr, __new_fpscr; + + __read_fpscr(&__old_fpscr); + __new_fpscr = __old_fpscr & ~(_FPUE_ENABLE(__mask & FE_ALL_EXCEPT)); + __write_fpscr(__new_fpscr); + return (_GET_FPUE_ENABLE(__old_fpscr)); +} + +static __inline int +fegetexcept(void) +{ + uint32_t __fpscr; + + __read_fpscr(&__fpscr); + return (_GET_FPUE_ENABLE(__fpscr)); +} + +#endif /* __BSD_VISIBLE */ + + +#endif /* _FENV_H_ */ + |