From 7838cb58979eaaa071179d684603ceb5e451d0fb Mon Sep 17 00:00:00 2001 From: Juan Jose Garcia Ripoll Date: Mon, 1 Nov 2010 23:07:49 +0100 Subject: [PATCH] In OS X, inline fetestexcept() and feclearexcept(). --- src/h/impl/math_dispatch.h | 25 ++++++++++++++++++++ src/h/impl/math_fenv.h | 48 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 src/h/impl/math_fenv.h diff --git a/src/h/impl/math_dispatch.h b/src/h/impl/math_dispatch.h index 284684c19..8954c9b13 100644 --- a/src/h/impl/math_dispatch.h +++ b/src/h/impl/math_dispatch.h @@ -13,6 +13,11 @@ See file '../Copyright' for full details. */ +#ifndef ECL_MATH_DISPATCH_H +#define ECL_MATH_DISPATCH_H + +#include + typedef cl_object (*math_one_arg_fn)(cl_object); #ifdef ECL_LONG_FLOAT @@ -41,3 +46,23 @@ typedef cl_object (*math_one_arg_fn)(cl_object); ECL_MATHERR_TEST; \ return arg; \ } +#define MATH_DEF_DISPATCH1_NE(name,id,type,rational,single_float,double_float,long_float,complex) \ + static cl_object name##failed(cl_object x) { \ + FEwrong_type_only_arg(id, x, type); \ + } \ + static const math_one_arg_fn name##dispatch[t_complex+1]= { \ + name##failed, /* t_start */ \ + name##failed, /* t_list */ \ + name##failed, /* t_character */ \ + rational, rational, rational, /* t_fixnum, bignum, ratio */ \ + single_float, double_float, /* t_singlefloat, t_doublefloat */ \ + MATH_LONG_DOUBLE(long_float) /* t_longfloat, optional */ \ + complex }; \ + cl_object ecl_##name(cl_object arg) \ + { \ + int t = type_of(arg); \ + if (t > t_complex) name##failed(arg); \ + arg = name##dispatch[t](arg); \ + return arg; \ + } +#endif /* ECL_MATH_DISPATCH_H */ diff --git a/src/h/impl/math_fenv.h b/src/h/impl/math_fenv.h new file mode 100644 index 000000000..69d835dd4 --- /dev/null +++ b/src/h/impl/math_fenv.h @@ -0,0 +1,48 @@ +/* -*- mode: c; c-basic-offset: 4 -*- */ +/* + math_fenv.h -- inlined versions of fenv.h +*/ +/* + Copyright (c) 2010, Juan Jose Garcia Ripoll. + + ECL is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + See file '../Copyright' for full details. +*/ + +#if !defined(ECL_MATH_FENV_H) && defined(HAVE_FENV_H) +#define ECL_MATH_FENV_H + +#if defined(__APPLE__) && defined(__amd64__) +#define feclearexcept myfeclearexcept +static inline void myfeclearexcept(int flags) +{ + int aux; + int f = ~(0x3d); + __asm__ ( + "fnclex \n\t" + "stmxcsr %0\n\t" + "andl %1,%0\n\t" + "ldmxcsr %0\n\t" + : "=m"(aux) : "a"(f)); +} +#define fetestexcept myfetestexcept +static inline int myfetestexcept(cl_fixnum flags) +{ + cl_fixnum output = (flags & 0x3d); + int sw; + __asm__ ( + "fnstsw %0\n\t" + "movzwl %0,%%eax\n\t" + "stmxcsr %0\n\t" + "orl %0,%%eax\n\t" + "and %%rax,%1\n\t" + : "=m"(sw), "=d"(output) : "d"(output) : "%rax"); + return output; +} +#endif /* __APPLE__ && __amd64__ */ + +#endif /* !ECL_MATH_FENV_H && HAVE_FENV_H */