mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-18 18:05:21 +00:00
Implement some <fenv.h> functions on systems that don't support them
yet. This includes Cygwin/x86. The code is derived from the GNU C Library.
This commit is contained in:
parent
a9928fe707
commit
ddcd7a8df8
110
SheepShaver/src/kpx_cpu/src/mathlib/ieeefp-i386.cpp
Executable file
110
SheepShaver/src/kpx_cpu/src/mathlib/ieeefp-i386.cpp
Executable file
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* ieeefp-i386.cpp - Access to FPU environment, x86 specific code
|
||||||
|
*
|
||||||
|
* Kheperix (C) 2003-2004 Gwenole Beauchesne
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CPU features
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* XXX: duplicate from cpu/ppc/ppc-dyngen.cpp! */
|
||||||
|
static uint32 cpu_features = 0;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
HWCAP_I386_CMOV = 1 << 15,
|
||||||
|
HWCAP_I386_MMX = 1 << 23,
|
||||||
|
HWCAP_I386_SSE = 1 << 25,
|
||||||
|
HWCAP_I386_SSE2 = 1 << 26,
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned int x86_cpuid(void)
|
||||||
|
{
|
||||||
|
int fl1, fl2;
|
||||||
|
|
||||||
|
/* See if we can use cpuid. On AMD64 we always can. */
|
||||||
|
__asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
|
||||||
|
"pushl %0; popfl; pushfl; popl %0; popfl"
|
||||||
|
: "=&r" (fl1), "=&r" (fl2)
|
||||||
|
: "i" (0x00200000));
|
||||||
|
if (((fl1 ^ fl2) & 0x00200000) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
/* Host supports cpuid. See if cpuid gives capabilities, try
|
||||||
|
CPUID(0). Preserve %ebx and %ecx; cpuid insn clobbers these, we
|
||||||
|
don't need their CPUID values here, and %ebx may be the PIC
|
||||||
|
register. */
|
||||||
|
__asm__ ("push %%ecx ; push %%ebx ; cpuid ; pop %%ebx ; pop %%ecx"
|
||||||
|
: "=a" (fl1) : "0" (0) : "edx", "cc");
|
||||||
|
if (fl1 == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
/* Invoke CPUID(1), return %edx; caller can examine bits to
|
||||||
|
determine what's supported. */
|
||||||
|
__asm__ ("push %%ecx ; push %%ebx ; cpuid ; pop %%ebx ; pop %%ecx" : "=d" (fl2) : "a" (1) : "cc");
|
||||||
|
|
||||||
|
return fl2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int has_cpu_features(int test_cpu_features)
|
||||||
|
{
|
||||||
|
static bool initted = false;
|
||||||
|
if (!initted) {
|
||||||
|
cpu_features = x86_cpuid();
|
||||||
|
initted = true;
|
||||||
|
}
|
||||||
|
return cpu_features & test_cpu_features;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rounding control
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Get current rounding direction
|
||||||
|
int fegetround(void)
|
||||||
|
{
|
||||||
|
unsigned short cw;
|
||||||
|
|
||||||
|
__asm__ __volatile__("fnstcw %0" : "=m" (*&cw));
|
||||||
|
|
||||||
|
return cw & 0xc00;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the rounding direction represented by ROUND
|
||||||
|
int fesetround(int round)
|
||||||
|
{
|
||||||
|
unsigned short cw;
|
||||||
|
|
||||||
|
if ((round & ~0xc00) != 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
__asm__ __volatile__("fnstcw %0" : "=m" (*&cw));
|
||||||
|
cw &= ~0xc00;
|
||||||
|
cw |= round;
|
||||||
|
__asm__ __volatile__("fldcw %0" : : "m" (*&cw));
|
||||||
|
|
||||||
|
if (has_cpu_features(HWCAP_I386_SSE) != 0) {
|
||||||
|
uint32 xcw;
|
||||||
|
__asm__ __volatile__("stmxcsr %0" : "=m" (*&xcw));
|
||||||
|
xcw &= ~0x6000;
|
||||||
|
xcw |= round << 3;
|
||||||
|
__asm__ __volatile__("ldmxcsr %0" : : "m" (*&xcw));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
52
SheepShaver/src/kpx_cpu/src/mathlib/ieeefp-i386.hpp
Executable file
52
SheepShaver/src/kpx_cpu/src/mathlib/ieeefp-i386.hpp
Executable file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* ieeefp-i386.hpp - Access to FPU environment, x86 specific code
|
||||||
|
*
|
||||||
|
* Kheperix (C) 2003-2004 Gwenole Beauchesne
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IEEEFP_FENV_I386_H
|
||||||
|
#define IEEEFP_FENV_I386_H
|
||||||
|
|
||||||
|
// Exceptions
|
||||||
|
enum {
|
||||||
|
FE_INVALID = 0x01,
|
||||||
|
#define FE_INVALID FE_INVALID
|
||||||
|
FE_DIVBYZERO = 0x04,
|
||||||
|
#define FE_DIVBYZERO FE_DIVBYZERO
|
||||||
|
FE_OVERFLOW = 0x08,
|
||||||
|
#define FE_OVERFLOW FE_OVERFLOW
|
||||||
|
FE_UNDERFLOW = 0x10,
|
||||||
|
#define FE_UNDERFLOW FE_UNDERFLOW
|
||||||
|
FE_INEXACT = 0x20
|
||||||
|
#define FE_INEXACT FE_INEXACT
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FE_ALL_EXCEPT (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
|
||||||
|
|
||||||
|
// Rounding modes
|
||||||
|
enum {
|
||||||
|
FE_TONEAREST = 0,
|
||||||
|
#define FE_TONEAREST FE_TONEAREST
|
||||||
|
FE_DOWNWARD = 0x400,
|
||||||
|
#define FE_DOWNWARD FE_DOWNWARD
|
||||||
|
FE_UPWARD = 0x800,
|
||||||
|
#define FE_UPWARD FE_UPWARD
|
||||||
|
FE_TOWARDZERO = 0xc00
|
||||||
|
#define FE_TOWARDZERO FE_TOWARDZERO
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* IEEEFP_FENV_I386_H */
|
29
SheepShaver/src/kpx_cpu/src/mathlib/ieeefp.cpp
Executable file
29
SheepShaver/src/kpx_cpu/src/mathlib/ieeefp.cpp
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* ieeefp.cpp - Access to FPU environment
|
||||||
|
*
|
||||||
|
* Kheperix (C) 2003-2004 Gwenole Beauchesne
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sysdeps.h"
|
||||||
|
|
||||||
|
#ifndef HAVE_FENV_H
|
||||||
|
#include "mathlib/ieeefp.hpp"
|
||||||
|
#if defined(__i386__)
|
||||||
|
#include "mathlib/ieeefp-i386.cpp"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
38
SheepShaver/src/kpx_cpu/src/mathlib/ieeefp.hpp
Executable file
38
SheepShaver/src/kpx_cpu/src/mathlib/ieeefp.hpp
Executable file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* ieeefp.hpp - Access to FPU environment
|
||||||
|
*
|
||||||
|
* Kheperix (C) 2003-2004 Gwenole Beauchesne
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IEEEFP_FENV_H
|
||||||
|
#define IEEEFP_FENV_H
|
||||||
|
|
||||||
|
#ifdef HAVE_FENV_H
|
||||||
|
#include <fenv.h>
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Arch-dependent definitions
|
||||||
|
#if defined(__i386__)
|
||||||
|
#include "mathlib/ieeefp-i386.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Rounding control
|
||||||
|
extern "C" int fegetround(void);
|
||||||
|
extern "C" int fesetround(int);
|
||||||
|
|
||||||
|
#endif /* FENV_H */
|
||||||
|
#endif /* IEEEFP_FENV_H */
|
Loading…
Reference in New Issue
Block a user