diff options
-rw-r--r-- | libdl/libdl.c | 4 | ||||
-rw-r--r-- | libm/Android.mk | 25 | ||||
-rw-r--r-- | libm/mips/Makefile.inc | 3 | ||||
-rw-r--r-- | libm/mips/_fpmath.h | 56 | ||||
-rw-r--r-- | libm/mips/fenv.c | 35 | ||||
-rw-r--r-- | libm/mips/fenv.h | 218 | ||||
-rw-r--r-- | libthread_db/libthread_db.c | 11 |
7 files changed, 342 insertions, 10 deletions
diff --git a/libdl/libdl.c b/libdl/libdl.c index 872c0c9..1d51c37 100644 --- a/libdl/libdl.c +++ b/libdl/libdl.c @@ -26,11 +26,11 @@ int dlclose(void *handle) { return 0; } #ifdef __arm__ void *dl_unwind_find_exidx(void *pc, int *pcount) { return 0; } -#elif defined(__i386__) || defined(__sh__) +#elif defined(__i386__) || defined(__sh__) || defined(__mips__) /* we munge the cb definition so we don't have to include any headers here. * It won't affect anything since these are just symbols anyway */ int dl_iterate_phdr(int (*cb)(void *info, void *size, void *data), void *data) { return 0; } #else -#error Unsupported architecture. Only arm and x86 are supported. +#error Unsupported architecture. Only mips, arm and x86 are supported. #endif diff --git a/libm/Android.mk b/libm/Android.mk index 57e4d4c..07cb7db 100644 --- a/libm/Android.mk +++ b/libm/Android.mk @@ -152,6 +152,7 @@ libm_common_src_files:= \ src/s_isnan.c \ src/s_modf.c +libm_common_cflags := ifeq ($(TARGET_ARCH),arm) libm_common_src_files += \ @@ -162,21 +163,29 @@ ifeq ($(TARGET_ARCH),arm) src/s_scalbnf.c libm_common_includes = $(LOCAL_PATH)/arm +endif -else - ifeq ($(TARGET_OS)-$(TARGET_ARCH),linux-x86) - libm_common_src_files += \ +ifeq ($(TARGET_OS)-$(TARGET_ARCH),linux-x86) + libm_common_src_files += \ i387/fenv.c \ i387/s_scalbnl.S \ i387/s_scalbn.S \ i387/s_scalbnf.S - libm_common_includes = $(LOCAL_PATH)/i386 $(LOCAL_PATH)/i387 - else - $(error "Unknown architecture") - endif + libm_common_includes = $(LOCAL_PATH)/i386 $(LOCAL_PATH)/i387 endif +ifeq ($(TARGET_ARCH),mips) + libm_common_src_files += \ + mips/fenv.c \ + src/e_ldexpf.c \ + src/s_scalbln.c \ + src/s_scalbn.c \ + src/s_scalbnf.c + libm_common_includes = $(LOCAL_PATH)/mips + # Need to build *rint* functions + libm_common_cflags += -fno-builtin-rintf -fno-builtin-rint +endif # libm.a # ======================================================== @@ -188,6 +197,7 @@ LOCAL_SRC_FILES := \ LOCAL_ARM_MODE := arm LOCAL_C_INCLUDES += $(libm_common_includes) +LOCAL_CFLAGS := $(libm_common_cflags) LOCAL_MODULE:= libm @@ -206,6 +216,7 @@ LOCAL_SRC_FILES := \ LOCAL_ARM_MODE := arm LOCAL_C_INCLUDES += $(libm_common_includes) +LOCAL_CFLAGS := $(libm_common_cflags) LOCAL_MODULE:= libm diff --git a/libm/mips/Makefile.inc b/libm/mips/Makefile.inc new file mode 100644 index 0000000..9bbfaa1 --- /dev/null +++ b/libm/mips/Makefile.inc @@ -0,0 +1,3 @@ +# $FreeBSD: src/lib/msun/mips/Makefile.inc,v 1.1 2008/04/26 12:20:29 imp Exp $ + +LDBL_PREC = 53 diff --git a/libm/mips/_fpmath.h b/libm/mips/_fpmath.h new file mode 100644 index 0000000..cb6e8c0 --- /dev/null +++ b/libm/mips/_fpmath.h @@ -0,0 +1,56 @@ +/*- + * 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: src/lib/libc/mips/_fpmath.h,v 1.1 2008/04/26 12:07:59 imp Exp $ + */ + +union IEEEl2bits { + long double e; + struct { +#ifndef __MIPSEB__ + 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) diff --git a/libm/mips/fenv.c b/libm/mips/fenv.c new file mode 100644 index 0000000..b5f52da --- /dev/null +++ b/libm/mips/fenv.c @@ -0,0 +1,35 @@ +/*- + * 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: src/lib/msun/mips/fenv.c,v 1.1 2008/04/26 12:20:29 imp Exp $ + */ + +#include <fenv.h> + +/* + * 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; diff --git a/libm/mips/fenv.h b/libm/mips/fenv.h new file mode 100644 index 0000000..061a696 --- /dev/null +++ b/libm/mips/fenv.h @@ -0,0 +1,218 @@ +/*- + * 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: src/lib/msun/mips/fenv.h,v 1.1 2008/04/26 12:20:29 imp Exp $ + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include <sys/_types.h> + +typedef __uint32_t fenv_t; +typedef __uint32_t fexcept_t; + +/* Exception flags */ +#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) +/* __BEGIN_DECLS */ + +/* 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 _FPUSW_SHIFT 16 +#define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT) + +#ifdef ARM_HARD_FLOAT +#define __rfs(__fpsr) __asm __volatile("rfs %0" : "=r" (*(__fpsr))) +#define __wfs(__fpsr) __asm __volatile("wfs %0" : : "r" (__fpsr)) +#else +#define __rfs(__fpsr) +#define __wfs(__fpsr) +#endif + +static __inline int +feclearexcept(int __excepts) +{ + fexcept_t __fpsr; + + __rfs(&__fpsr); + __fpsr &= ~__excepts; + __wfs(__fpsr); + return (0); +} + +static __inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fpsr; + + __rfs(&__fpsr); + *__flagp = __fpsr & __excepts; + return (0); +} + +static __inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fpsr; + + __rfs(&__fpsr); + __fpsr &= ~__excepts; + __fpsr |= *__flagp & __excepts; + __wfs(__fpsr); + 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 __fpsr; + + __rfs(&__fpsr); + return (__fpsr & __excepts); +} + +static __inline int +fegetround(void) +{ + + /* + * Apparently, the rounding mode is specified as part of the + * instruction format on ARM, so the dynamic rounding mode is + * indeterminate. Some FPUs may differ. + */ + return (-1); +} + +static __inline int +fesetround(int __round) +{ + + return (-1); +} + +static __inline int +fegetenv(fenv_t *__envp) +{ + + __rfs(__envp); + return (0); +} + +static __inline int +feholdexcept(fenv_t *__envp) +{ + fenv_t __env; + + __rfs(&__env); + *__envp = __env; + __env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); + __wfs(__env); + return (0); +} + +static __inline int +fesetenv(const fenv_t *__envp) +{ + + __wfs(*__envp); + return (0); +} + +static __inline int +feupdateenv(const fenv_t *__envp) +{ + fexcept_t __fpsr; + + __rfs(&__fpsr); + __wfs(*__envp); + feraiseexcept(__fpsr & FE_ALL_EXCEPT); + return (0); +} + +#if __BSD_VISIBLE + +static __inline int +feenableexcept(int __mask) +{ + fenv_t __old_fpsr, __new_fpsr; + + __rfs(&__old_fpsr); + __new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT; + __wfs(__new_fpsr); + return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); +} + +static __inline int +fedisableexcept(int __mask) +{ + fenv_t __old_fpsr, __new_fpsr; + + __rfs(&__old_fpsr); + __new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); + __wfs(__new_fpsr); + return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); +} + +static __inline int +fegetexcept(void) +{ + fenv_t __fpsr; + + __rfs(&__fpsr); + return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT); +} + +#endif /* __BSD_VISIBLE */ + +/* __END_DECLS */ + +#endif /* !_FENV_H_ */ + diff --git a/libthread_db/libthread_db.c b/libthread_db/libthread_db.c index 86e1cf4..e749377 100644 --- a/libthread_db/libthread_db.c +++ b/libthread_db/libthread_db.c @@ -99,7 +99,7 @@ _event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr) gEventMsgHandle.tid = gEventMsgHandle.pid; return 0x42; } -#else +#elif defined(__arm__) pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)60 /* r15/pc */, NULL); if (pc == bkpt_addr) { @@ -109,6 +109,15 @@ _event_getmsg_helper(td_thrhandle_t const * handle, void * bkpt_addr) gEventMsgHandle.tid = gEventMsgHandle.pid; return 0x42; } +#elif defined(__mips__) + pc = (void *)ptrace(PTRACE_PEEKUSR, handle->tid, (void *)(64*4) /* pc */, NULL); + if (pc == bkpt_addr) { + // The hook function takes the id of the new thread as it's first param, + // so grab it from a0 + gEventMsgHandle.pid = ptrace(PTRACE_PEEKUSR, handle->tid, (void *)(4*4) /* a0 */, NULL); + gEventMsgHandle.tid = gEventMsgHandle.pid; + return 0x42; + } #endif return 0; } |