fenv_inlines.h revision 25c28e83beb90e7c80452a7c818c5e6f73a07dc8
/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
*/
/*
* Copyright 2011, Richard Lowe
*/
#ifndef _FENV_INLINES_H
#define _FENV_INLINES_H
#ifdef __GNUC__
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__x86)
/*
* Floating point Control Word and Status Word
* Definition should actually be shared with x86
* (much of this 'amd64' code can be, in fact.)
*/
union fp_cwsw {
struct {
} words;
};
extern __inline__ void
__fenv_getcwsw(unsigned int *value)
{
"fstsw %0\n\t"
"fstcw %1\n\t"
}
extern __inline__ void
__fenv_setcwsw(const unsigned int *value)
{
short fenv[16];
"fstenv %0\n\t"
"movw %4,%1\n\t"
"movw %3,%2\n\t"
"fldenv %0\n\t"
"fwait\n\t"
/* For practical purposes, we clobber the whole FPU */
: "cc", "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)",
"st(6)", "st(7)");
}
extern __inline__ void
__fenv_getmxcsr(unsigned int *value)
{
}
extern __inline__ void
__fenv_setmxcsr(const unsigned int *value)
{
}
extern __inline__ long double
f2xm1(long double x)
{
long double ret;
return (ret);
}
extern __inline__ long double
fyl2x(long double y, long double x)
{
long double ret;
: "=t" (ret)
: "0" (x), "u" (y)
: "st(1)", "cc");
return (ret);
}
extern __inline__ long double
fptan(long double x)
{
/*
* fptan pushes 1.0 then the result on completion, so we want to pop
* the FP stack twice, so we need a dummy value into which to pop it.
*/
long double ret;
long double dummy;
: "0" (x)
: "cc");
return (ret);
}
extern __inline__ long double
fpatan(long double x, long double y)
{
long double ret;
: "=t" (ret)
: "0" (y), "u" (x)
: "st(1)", "cc");
return (ret);
}
extern __inline__ long double
fxtract(long double x)
{
return (x);
}
extern __inline__ long double
{
return (div);
}
extern __inline__ long double
{
return (div);
}
extern __inline__ long double
fyl2xp1(long double y, long double x)
{
long double ret;
: "=t" (ret)
: "0" (x), "u" (y)
: "st(1)", "cc");
return (ret);
}
extern __inline__ long double
fsqrt(long double x)
{
return (x);
}
extern __inline__ long double
fsincos(long double x)
{
long double dummy;
return (x);
}
extern __inline__ long double
frndint(long double x)
{
return (x);
}
extern __inline__ long double
fscale(long double x, long double y)
{
long double ret;
return (ret);
}
extern __inline__ long double
fsin(long double x)
{
return (x);
}
extern __inline__ long double
fcos(long double x)
{
return (x);
}
extern __inline__ void
{
"cmpeqss %2, %1\n\t"
"movss %1, %0"
: "x" (*f2)
: "cc");
}
extern __inline__ void
{
"cmpltss %2, %1\n\t"
"movss %1, %0"
: "x" (*f2)
: "cc");
}
extern __inline__ void
{
"cmpless %2, %1\n\t"
"movss %1, %0"
: "x" (*f2)
: "cc");
}
extern __inline__ void
{
"cmpunordss %2, %1\n\t"
"movss %1, %0"
: "x" (*f2)
: "cc");
}
extern __inline__ void
{
"minss %2, %1\n\t"
"movss %1, %0"
: "x" (*f2));
}
extern __inline__ void
{
"maxss %2, %1\n\t"
"movss %1, %0"
: "x" (*f2));
}
extern __inline__ void
{
"addss %2, %1\n\t"
"movss %1, %0"
: "x" (*f2));
}
extern __inline__ void
{
"subss %2, %1\n\t"
"movss %1, %0"
: "x" (*f2));
}
extern __inline__ void
{
"mulss %2, %1\n\t"
"movss %1, %0"
: "x" (*f2));
}
extern __inline__ void
{
"divss %2, %1\n\t"
"movss %1, %0"
: "x" (*f2));
}
extern __inline__ void
{
double tmp;
"sqrtss %2, %1\n\t"
"movss %1, %0"
: "m" (*f1));
}
extern __inline__ void
{
}
extern __inline__ void
{
}
extern __inline__ void
{
double tmp;
"cvtss2sd %2, %1\n\t"
"movsd %1, %0"
: "m" (*f1));
}
extern __inline__ void
{
double tmp;
"cvtsi2ss %2, %1\n\t"
"movss %1, %0"
: "m" (*i1));
}
extern __inline__ void
{
int tmp;
"cvttss2si %2, %1\n\t"
"movl %1, %0"
: "m" (*f1));
}
extern __inline__ void
{
int tmp;
"cvtss2si %2, %1\n\t"
"movl %1, %0"
: "m" (*f1));
}
#if defined(__amd64)
extern __inline__ void
{
double tmp;
"cvtsi2ssq %2, %1\n\t"
"movss %1, %0"
: "m" (*ll1));
}
extern __inline__ void
{
"cvttss2siq %2, %1\n\t"
"movq %1, %0"
: "m" (*f1));
}
extern __inline__ void
{
"cvtss2siq %2, %1\n\t"
"movq %1, %0"
: "m" (*f1));
}
#endif
extern __inline__ void
{
"cmpeqsd %2,%1\n\t"
"movsd %1,%0"
: "x" (*d2));
}
extern __inline__ void
{
"cmpltsd %2,%1\n\t"
"movsd %1,%0"
: "x" (*d2));
}
extern __inline__ void
{
"cmplesd %2,%1\n\t"
"movsd %1,%0"
: "x" (*d2));
}
extern __inline__ void
{
"cmpunordsd %2,%1\n\t"
"movsd %1,%0"
: "x" (*d2));
}
extern __inline__ void
{
"minsd %2,%1\n\t"
"movsd %1,%0"
: "x" (*d2));
}
extern __inline__ void
{
"maxsd %2,%1\n\t"
"movsd %1,%0"
: "x" (*d2));
}
extern __inline__ void
{
"addsd %2,%1\n\t"
"movsd %1,%0"
: "x" (*d2));
}
extern __inline__ void
{
"subsd %2,%1\n\t"
"movsd %1,%0"
: "x" (*d2));
}
extern __inline__ void
{
"mulsd %2,%1\n\t"
"movsd %1,%0"
: "x" (*d2));
}
extern __inline__ void
{
"divsd %2,%1\n\t"
"movsd %1,%0"
: "x" (*d2));
}
extern __inline__ void
{
double tmp;
"sqrtsd %2, %1\n\t"
"movsd %1, %0"
: "m" (*d1));
}
extern __inline__ void
{
}
extern __inline__ void
{
}
extern __inline__ void
{
double tmp;
"cvtsd2ss %2,%1\n\t"
"movss %1,%0"
: "m" (*d1));
}
extern __inline__ void
{
double tmp;
"cvtsi2sd %2,%1\n\t"
"movsd %1,%0"
: "m" (*i1));
}
extern __inline__ void
{
int tmp;
"cvttsd2si %2,%1\n\t"
"movl %1,%0"
: "m" (*d1));
}
extern __inline__ void
{
int tmp;
"cvtsd2si %2,%1\n\t"
"movl %1,%0"
: "m" (*d1));
}
#if defined(__amd64)
extern __inline__ void
{
double tmp;
"cvtsi2sdq %2,%1\n\t"
"movsd %1,%0"
: "m" (*ll1));
}
extern __inline__ void
{
"cvttsd2siq %2,%1\n\t"
"movq %1,%0"
: "m" (*d1));
}
extern __inline__ void
{
"cvtsd2siq %2,%1\n\t"
"movq %1,%0"
: "m" (*d1));
}
#endif
extern __inline__ void
__fenv_getfsr(unsigned long *l)
{
#if defined(__sparcv9)
"stx %%fsr,%0\n\t"
#else
"st %%fsr,%0\n\t"
#endif
: "=m" (*l));
}
extern __inline__ void
__fenv_setfsr(const unsigned long *l)
{
#if defined(__sparcv9)
"ldx %0,%%fsr\n\t"
#else
"ld %0,%%fsr\n\t"
#endif
: : "m" (*l) : "cc");
}
extern __inline__ void
__fenv_getfsr32(unsigned int *l)
{
}
extern __inline__ void
__fenv_setfsr32(const unsigned int *l)
{
}
#else
#error "GCC FENV inlines not implemented for this platform"
#endif
#ifdef __cplusplus
}
#endif
#endif /* __GNUC__ */
#endif /* _FENV_INLINES_H */