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