gcl-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gcl-devel] [Maxima] Out of range floating point number determinatio


From: Camm Maguire
Subject: Re: [Gcl-devel] [Maxima] Out of range floating point number determination
Date: Mon, 27 Aug 2012 13:40:51 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux)

Greetings!

Raymond Toy <address@hidden> writes:

> On Fri, Aug 24, 2012 at 2:57 PM, Camm Maguire <address@hidden> wrote:
>
>     What is the canonical way to detect if the sse instructions are
>     supported on the running cpu?  Or does one not bother these days?
>
> You check the cpuid bits.  I always do this with some inline assembly.
>

OK, this seems to work:

#define install_excepts()                                               \
  ({unsigned _m;                                                        \
    __asm__ __volatile__ ("fnstcw %0" : "=m" (_m));                     \
    _m|=FE_ALL_EXCEPT;                                                  \
    _m&=~excepts;                                                       \
    __asm__ __volatile__ ("fldcw %0" : : "m" (_m));                     \
    __asm__ __volatile__ ("movl $1,%%eax\n\tcpuid\n\tmovl %%edx,%0" : "=m" 
(_m)); \
    if (bit(_m,25)) {                                                   \
      __asm__ __volatile__ ("stmxcsr %0" : "=m" (_m));                  \
      _m|=FE_ALL_EXCEPT<<7;                                             \
      _m&=~(excepts<<7);                                                \
      __asm__ __volatile__ ("ldmxcsr %0" : : "m" (_m));                 \
    }                                                                   \
    excepts;})


The ppc instructions appear in this example:

#define fegetenv_register() \
        ({ fenv_t env; asm volatile ("mffs %0" : "=f" (env)); env; })

/* Equivalent to fesetenv, but takes a fenv_t instead of a pointer.  */
#define fesetenv_register(env) \
        do { \
          double d = (env); \
          if(GLRO(dl_hwcap) & PPC_FEATURE_HAS_DFP) \
            asm volatile (".machine push; " \
                          ".machine \"power6\"; " \
                          "mtfsf 0xff,%0,1,0; " \
                          ".machine pop" : : "f" (d)); \
          else \
            asm volatile ("mtfsf 0xff,%0" : : "f" (d)); \
        } while(0)

which imply also that a runtime cpu capability determination needs be
made for "DFP".  Do you happen to know how to do this?

The sparc assembly appears to vary only with wordsize:

#if __WORDSIZE == 64
# define __fenv_stfsr(X)   __asm__ ("stx %%fsr,%0" : "=m" (X))
# define __fenv_ldfsr(X)   __asm__ __volatile__ ("ldx %0,%%fsr" : : "m" (X))
#else
# define __fenv_stfsr(X)   __asm__ ("st %%fsr,%0" : "=m" (X))
# define __fenv_ldfsr(X)   __asm__ __volatile__ ("ld %0,%%fsr" : : "m" (X))
#endif

Does this match your understanding?

The GCL strategy I'm working on will be

glibc -> feenablexcept
x86/amd64   -> assembly above  (covers mingw, mac intel and generic bsd)
ppc         -> assembly to be written (old mac)
sparc       -> assembly to be written (solaris)

Any important targets left out?

Take care,
-- 
Camm Maguire                                        address@hidden
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah



reply via email to

[Prev in Thread] Current Thread [Next in Thread]