This commit is contained in:
gbeauche 2005-12-04 15:53:55 +00:00
parent bdcf8efe2e
commit b17b4d7584
4 changed files with 237 additions and 237 deletions

View File

@ -1,111 +1,111 @@
/* /*
* ieeefp-i386.cpp - Access to FPU environment, x86 specific code * ieeefp-i386.cpp - Access to FPU environment, x86 specific code
* Code largely derived from GNU libc * Code largely derived from GNU libc
* *
* Kheperix (C) 2003-2005 Gwenole Beauchesne * Kheperix (C) 2003-2005 Gwenole Beauchesne
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
/* /*
* CPU features * CPU features
*/ */
/* XXX: duplicate from cpu/ppc/ppc-dyngen.cpp! */ /* XXX: duplicate from cpu/ppc/ppc-dyngen.cpp! */
static uint32 cpu_features = 0; static uint32 cpu_features = 0;
enum { enum {
HWCAP_I386_CMOV = 1 << 15, HWCAP_I386_CMOV = 1 << 15,
HWCAP_I386_MMX = 1 << 23, HWCAP_I386_MMX = 1 << 23,
HWCAP_I386_SSE = 1 << 25, HWCAP_I386_SSE = 1 << 25,
HWCAP_I386_SSE2 = 1 << 26, HWCAP_I386_SSE2 = 1 << 26,
}; };
static unsigned int x86_cpuid(void) static unsigned int x86_cpuid(void)
{ {
int fl1, fl2; int fl1, fl2;
/* See if we can use cpuid. On AMD64 we always can. */ /* See if we can use cpuid. On AMD64 we always can. */
__asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;" __asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
"pushl %0; popfl; pushfl; popl %0; popfl" "pushl %0; popfl; pushfl; popl %0; popfl"
: "=&r" (fl1), "=&r" (fl2) : "=&r" (fl1), "=&r" (fl2)
: "i" (0x00200000)); : "i" (0x00200000));
if (((fl1 ^ fl2) & 0x00200000) == 0) if (((fl1 ^ fl2) & 0x00200000) == 0)
return (0); return (0);
/* Host supports cpuid. See if cpuid gives capabilities, try /* Host supports cpuid. See if cpuid gives capabilities, try
CPUID(0). Preserve %ebx and %ecx; cpuid insn clobbers these, we CPUID(0). Preserve %ebx and %ecx; cpuid insn clobbers these, we
don't need their CPUID values here, and %ebx may be the PIC don't need their CPUID values here, and %ebx may be the PIC
register. */ register. */
__asm__ ("push %%ecx ; push %%ebx ; cpuid ; pop %%ebx ; pop %%ecx" __asm__ ("push %%ecx ; push %%ebx ; cpuid ; pop %%ebx ; pop %%ecx"
: "=a" (fl1) : "0" (0) : "edx", "cc"); : "=a" (fl1) : "0" (0) : "edx", "cc");
if (fl1 == 0) if (fl1 == 0)
return (0); return (0);
/* Invoke CPUID(1), return %edx; caller can examine bits to /* Invoke CPUID(1), return %edx; caller can examine bits to
determine what's supported. */ determine what's supported. */
__asm__ ("push %%ecx ; push %%ebx ; cpuid ; pop %%ebx ; pop %%ecx" : "=d" (fl2) : "a" (1) : "cc"); __asm__ ("push %%ecx ; push %%ebx ; cpuid ; pop %%ebx ; pop %%ecx" : "=d" (fl2) : "a" (1) : "cc");
return fl2; return fl2;
} }
static inline int has_cpu_features(int test_cpu_features) static inline int has_cpu_features(int test_cpu_features)
{ {
static bool initted = false; static bool initted = false;
if (!initted) { if (!initted) {
cpu_features = x86_cpuid(); cpu_features = x86_cpuid();
initted = true; initted = true;
} }
return cpu_features & test_cpu_features; return cpu_features & test_cpu_features;
} }
/* /*
* Rounding control * Rounding control
*/ */
// Get current rounding direction // Get current rounding direction
int fegetround(void) int fegetround(void)
{ {
unsigned short cw; unsigned short cw;
__asm__ __volatile__("fnstcw %0" : "=m" (*&cw)); __asm__ __volatile__("fnstcw %0" : "=m" (*&cw));
return cw & 0xc00; return cw & 0xc00;
} }
// Set the rounding direction represented by ROUND // Set the rounding direction represented by ROUND
int fesetround(int round) int fesetround(int round)
{ {
unsigned short cw; unsigned short cw;
if ((round & ~0xc00) != 0) if ((round & ~0xc00) != 0)
return 1; return 1;
__asm__ __volatile__("fnstcw %0" : "=m" (*&cw)); __asm__ __volatile__("fnstcw %0" : "=m" (*&cw));
cw &= ~0xc00; cw &= ~0xc00;
cw |= round; cw |= round;
__asm__ __volatile__("fldcw %0" : : "m" (*&cw)); __asm__ __volatile__("fldcw %0" : : "m" (*&cw));
if (has_cpu_features(HWCAP_I386_SSE) != 0) { if (has_cpu_features(HWCAP_I386_SSE) != 0) {
uint32 xcw; uint32 xcw;
__asm__ __volatile__("stmxcsr %0" : "=m" (*&xcw)); __asm__ __volatile__("stmxcsr %0" : "=m" (*&xcw));
xcw &= ~0x6000; xcw &= ~0x6000;
xcw |= round << 3; xcw |= round << 3;
__asm__ __volatile__("ldmxcsr %0" : : "m" (*&xcw)); __asm__ __volatile__("ldmxcsr %0" : : "m" (*&xcw));
} }
return 0; return 0;
} }

View File

@ -1,58 +1,58 @@
/* /*
* ieeefp-i386.hpp - IEEE754 Floating-Point Math library, x86 specific code * ieeefp-i386.hpp - IEEE754 Floating-Point Math library, x86 specific code
* *
* Kheperix (C) 2003-2005 Gwenole Beauchesne * Kheperix (C) 2003-2005 Gwenole Beauchesne
* Code derived from the GNU C Library * Code derived from the GNU C Library
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#ifndef IEEEFP_I386_H #ifndef IEEEFP_I386_H
#define IEEEFP_I386_H #define IEEEFP_I386_H
// 7.6 Floating-point environment <fenv.h> // 7.6 Floating-point environment <fenv.h>
#ifndef HAVE_FENV_H #ifndef HAVE_FENV_H
// Exceptions // Exceptions
enum { enum {
FE_INVALID = 0x01, FE_INVALID = 0x01,
#define FE_INVALID FE_INVALID #define FE_INVALID FE_INVALID
FE_DIVBYZERO = 0x04, FE_DIVBYZERO = 0x04,
#define FE_DIVBYZERO FE_DIVBYZERO #define FE_DIVBYZERO FE_DIVBYZERO
FE_OVERFLOW = 0x08, FE_OVERFLOW = 0x08,
#define FE_OVERFLOW FE_OVERFLOW #define FE_OVERFLOW FE_OVERFLOW
FE_UNDERFLOW = 0x10, FE_UNDERFLOW = 0x10,
#define FE_UNDERFLOW FE_UNDERFLOW #define FE_UNDERFLOW FE_UNDERFLOW
FE_INEXACT = 0x20 FE_INEXACT = 0x20
#define FE_INEXACT FE_INEXACT #define FE_INEXACT FE_INEXACT
}; };
#define FE_ALL_EXCEPT (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) #define FE_ALL_EXCEPT (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
// Rounding modes // Rounding modes
enum { enum {
FE_TONEAREST = 0, FE_TONEAREST = 0,
#define FE_TONEAREST FE_TONEAREST #define FE_TONEAREST FE_TONEAREST
FE_DOWNWARD = 0x400, FE_DOWNWARD = 0x400,
#define FE_DOWNWARD FE_DOWNWARD #define FE_DOWNWARD FE_DOWNWARD
FE_UPWARD = 0x800, FE_UPWARD = 0x800,
#define FE_UPWARD FE_UPWARD #define FE_UPWARD FE_UPWARD
FE_TOWARDZERO = 0xc00 FE_TOWARDZERO = 0xc00
#define FE_TOWARDZERO FE_TOWARDZERO #define FE_TOWARDZERO FE_TOWARDZERO
}; };
#endif #endif
#endif /* IEEEFP_I386_H */ #endif /* IEEEFP_I386_H */

View File

@ -1,29 +1,29 @@
/* /*
* ieeefp.cpp - Access to FPU environment * ieeefp.cpp - Access to FPU environment
* *
* Kheperix (C) 2003-2005 Gwenole Beauchesne * Kheperix (C) 2003-2005 Gwenole Beauchesne
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "sysdeps.h" #include "sysdeps.h"
#ifndef HAVE_FENV_H #ifndef HAVE_FENV_H
#include "mathlib/ieeefp.hpp" #include "mathlib/ieeefp.hpp"
#if defined(__i386__) #if defined(__i386__)
#include "mathlib/ieeefp-i386.cpp" #include "mathlib/ieeefp-i386.cpp"
#endif #endif
#endif #endif

View File

@ -1,39 +1,39 @@
/* /*
* ieeefp.hpp - IEEE754 Floating-Point Math library * ieeefp.hpp - IEEE754 Floating-Point Math library
* *
* Kheperix (C) 2003-2005 Gwenole Beauchesne * Kheperix (C) 2003-2005 Gwenole Beauchesne
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#ifndef IEEEFP_H #ifndef IEEEFP_H
#define IEEEFP_H #define IEEEFP_H
// Arch-dependent definitions // Arch-dependent definitions
#if defined(__i386__) #if defined(__i386__)
#include "mathlib/ieeefp-i386.hpp" #include "mathlib/ieeefp-i386.hpp"
#endif #endif
#ifdef HAVE_FENV_H #ifdef HAVE_FENV_H
#include <fenv.h> #include <fenv.h>
#else #else
// Rounding control // Rounding control
extern "C" int fegetround(void); extern "C" int fegetround(void);
extern "C" int fesetround(int); extern "C" int fesetround(int);
#endif /* FENV_H */ #endif /* FENV_H */
#endif /* IEEEFP_H */ #endif /* IEEEFP_H */