d9f069ab4f
libstdc++-v3: * configure.host: Remove solaris2.9 handling. Change os_include_dir to os/solaris/solaris2.10. * acinclude.m4 (ac_has_gthreads): Remove solaris2.9* handling. * crossconfig.m4: Remove *-solaris2.9 handling, simplify. * configure: Regenerate. * config/abi/post/solaris2.9: Remove. * config/os/solaris/solaris2.9: Rename to ... * config/os/solaris/solaris2.10: ... this. * config/os/solaris/solaris2.10/os_defines.h (CLOCK_MONOTONIC): Remove. * doc/xml/manual/configure.xml (--enable-libstdcxx-threads): Remove Solaris 9 reference. * doc/html/manual/configure.html: Regenerate. * testsuite/27_io/basic_istream/extractors_arithmetic/char/12.cc: Remove *-*-solaris2.9 xfail. * testsuite/27_io/basic_istream/extractors_arithmetic/wchar_t/12.cc: Likewise. * testsuite/ext/enc_filebuf/char/13598.cc: Remove *-*-solaris2.9 xfail. libjava: * configure.ac (THREADLIBS, THREADSPEC): Remove *-*-solaris2.9 handling. * configure: Regenerate. libgfortran: * config/fpu-387.h [__sun__ && __svr4__]: Remove SSE execution check. libgcc: * config/i386/crtfastmath.c (set_fast_math): Remove SSE execution check. * config/i386/sol2-unwind.h (x86_fallback_frame_state): Remove Solaris 9 single-threaded support. * config/sparc/sol2-unwind.h (sparc64_is_sighandler): Remove Solaris 9 single-threaded support. Add call_user_handler code sequences. (sparc_is_sighandler): Likewise. libcpp: * lex.c: Remove Solaris 9 reference. gcc/testsuite: * gcc.c-torture/compile/pr28865.c: Remove dg-xfail-if. * gcc.dg/c99-stdint-6.c: Remove dg-options for *-*-solaris2.9. * gcc.dg/lto/20090210_0.c: Remove dg-extra-ld-options for *-*-solaris2.9. * gcc.dg/torture/pr47917.c: Remove dg-options for *-*-solaris2.9. * gcc.target/i386/pr22076.c: Remove i?86-*-solaris2.9 handling from dg-options. * gcc.target/i386/pr22152.c: Remove i?86-*-solaris2.9 handling from dg-additional-options. * gcc.target/i386/vect8-ret.c: Remove i?86-*-solaris2.9 handling from dg-options. * gcc.dg/vect/tree-vect.h (check_vect): Remove Solaris 9 SSE2 execution check. * gcc.target/i386/sse-os-support.h [__sun__ && __svr4__] (sigill_hdlr): Remove. (sse_os_support) [__sun__ && __svr4__]: Remove SSE execution check. * gfortran.dg/erf_3.F90: Remove sparc*-*-solaris2.9* handling. * gfortran.dg/fmt_en.f90: Remove i?86-*-solaris2.9* handling. * gfortran.dg/round_4.f90: Remove *-*-solaris2.9* handling. * lib/target-supports.exp (add_options_for_tls): Remove *-*-solaris2.9* handling. gcc: * config.gcc (enable_obsolete): Remove *-*-solaris2.9*. (*-*-solaris2.[0-9] | *-*-solaris2.[0-9].*): Mark unsupported. (*-*-solaris2*): Simplify. (i[34567]86-*-solaris2* | x86_64-*-solaris2.1[0-9]*): Likewise. (i[34567]86-*-solaris2* | x86_64-*-solaris2.1[0-9]*): Remove *-*-solaris2.9* handling. * configure.ac (gcc_cv_as_hidden): Remove test for Solaris 9/x86 as bug. (gcc_cv_ld_hidden): Remove *-*-solaris2.9* handling. (ld_tls_support): Remove i?86-*-solaris2.9, sparc*-*-solaris2.9 handling, simplify. (gcc_cv_as_gstabs_flag): Remove workaround for Solaris 9/x86 as bug. * configure: Regenerate. * config/i386/sol2-9.h: Remove. * doc/install.texi (Specific, i?86-*-solaris2.9): Remove. (Specific, *-*-solaris2*): Mention Solaris 9 support removal. Remove Solaris 9 references. fixincludes: * inclhack.def (math_exception): Bypass on *-*-solaris2.1[0-9]*. (solaris_int_types): Remove. (solaris_longjmp_noreturn): Remove. (solaris_mutex_init_2): Remove. (solaris_once_init_2): Remove. (solaris_sys_va_list): Remove. * fixincl.x: Regenerate. * tests/base/iso/setjmp_iso.h: Remove. * tests/base/pthread.h [SOLARIS_MUTEX_INIT_2_CHECK]: Remove. [SOLARIS_ONCE_INIT_1_CHECK]: Remove wrapping done by solaris_once_init_2. [SOLARIS_ONCE_INIT_2_CHECK]: Remove. * tests/base/sys/int_types.h: Remove. * tests/base/sys/va_list.h: Remove. contrib: * config-list.mk (LIST): Remove sparc-sun-solaris2.9, i686-solaris2.9. From-SVN: r209621
216 lines
5.2 KiB
C
216 lines
5.2 KiB
C
/* FPU-related code for x86 and x86_64 processors.
|
|
Copyright (C) 2005-2014 Free Software Foundation, Inc.
|
|
Contributed by Francois-Xavier Coudert <coudert@clipper.ens.fr>
|
|
|
|
This file is part of the GNU Fortran 95 runtime library (libgfortran).
|
|
|
|
Libgfortran 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 3 of the License, or (at your option) any later version.
|
|
|
|
Libgfortran 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.
|
|
|
|
Under Section 7 of GPL version 3, you are granted additional
|
|
permissions described in the GCC Runtime Library Exception, version
|
|
3.1, as published by the Free Software Foundation.
|
|
|
|
You should have received a copy of the GNU General Public License and
|
|
a copy of the GCC Runtime Library Exception along with this program;
|
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
#ifndef __SSE_MATH__
|
|
#include "cpuid.h"
|
|
#endif
|
|
|
|
static int
|
|
has_sse (void)
|
|
{
|
|
#ifndef __SSE_MATH__
|
|
unsigned int eax, ebx, ecx, edx;
|
|
|
|
if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
|
|
return 0;
|
|
|
|
return edx & bit_SSE;
|
|
#else
|
|
return 1;
|
|
#endif
|
|
}
|
|
|
|
/* i387 exceptions -- see linux <fpu_control.h> header file for details. */
|
|
#define _FPU_MASK_IM 0x01
|
|
#define _FPU_MASK_DM 0x02
|
|
#define _FPU_MASK_ZM 0x04
|
|
#define _FPU_MASK_OM 0x08
|
|
#define _FPU_MASK_UM 0x10
|
|
#define _FPU_MASK_PM 0x20
|
|
#define _FPU_MASK_ALL 0x3f
|
|
|
|
#define _FPU_EX_ALL 0x3f
|
|
|
|
/* i387 rounding modes. */
|
|
|
|
#define _FPU_RC_NEAREST 0x0
|
|
#define _FPU_RC_DOWN 0x1
|
|
#define _FPU_RC_UP 0x2
|
|
#define _FPU_RC_ZERO 0x3
|
|
|
|
#define _FPU_RC_MASK 0x3
|
|
|
|
|
|
void
|
|
set_fpu (void)
|
|
{
|
|
int excepts = 0;
|
|
unsigned short cw;
|
|
|
|
__asm__ __volatile__ ("fstcw\t%0" : "=m" (cw));
|
|
|
|
if (options.fpe & GFC_FPE_INVALID) excepts |= _FPU_MASK_IM;
|
|
if (options.fpe & GFC_FPE_DENORMAL) excepts |= _FPU_MASK_DM;
|
|
if (options.fpe & GFC_FPE_ZERO) excepts |= _FPU_MASK_ZM;
|
|
if (options.fpe & GFC_FPE_OVERFLOW) excepts |= _FPU_MASK_OM;
|
|
if (options.fpe & GFC_FPE_UNDERFLOW) excepts |= _FPU_MASK_UM;
|
|
if (options.fpe & GFC_FPE_INEXACT) excepts |= _FPU_MASK_PM;
|
|
|
|
cw |= _FPU_MASK_ALL;
|
|
cw &= ~excepts;
|
|
|
|
__asm__ __volatile__ ("fnclex\n\tfldcw\t%0" : : "m" (cw));
|
|
|
|
if (has_sse())
|
|
{
|
|
unsigned int cw_sse;
|
|
|
|
__asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw_sse));
|
|
|
|
/* The SSE exception masks are shifted by 7 bits. */
|
|
cw_sse |= _FPU_MASK_ALL << 7;
|
|
cw_sse &= ~(excepts << 7);
|
|
|
|
/* Clear stalled exception flags. */
|
|
cw_sse &= ~_FPU_EX_ALL;
|
|
|
|
__asm__ __volatile__ ("%vldmxcsr\t%0" : : "m" (cw_sse));
|
|
}
|
|
}
|
|
|
|
int
|
|
get_fpu_except_flags (void)
|
|
{
|
|
unsigned short cw;
|
|
int excepts;
|
|
int result = 0;
|
|
|
|
__asm__ __volatile__ ("fnstsw\t%0" : "=a" (cw));
|
|
excepts = cw;
|
|
|
|
if (has_sse())
|
|
{
|
|
unsigned int cw_sse;
|
|
|
|
__asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw_sse));
|
|
excepts |= cw_sse;
|
|
}
|
|
|
|
excepts &= _FPU_EX_ALL;
|
|
|
|
if (excepts & _FPU_MASK_IM) result |= GFC_FPE_INVALID;
|
|
if (excepts & _FPU_MASK_DM) result |= GFC_FPE_DENORMAL;
|
|
if (excepts & _FPU_MASK_ZM) result |= GFC_FPE_ZERO;
|
|
if (excepts & _FPU_MASK_OM) result |= GFC_FPE_OVERFLOW;
|
|
if (excepts & _FPU_MASK_UM) result |= GFC_FPE_UNDERFLOW;
|
|
if (excepts & _FPU_MASK_PM) result |= GFC_FPE_INEXACT;
|
|
|
|
return result;
|
|
}
|
|
|
|
void
|
|
set_fpu_rounding_mode (int round)
|
|
{
|
|
int round_mode;
|
|
unsigned short cw;
|
|
|
|
switch (round)
|
|
{
|
|
case GFC_FPE_TONEAREST:
|
|
round_mode = _FPU_RC_NEAREST;
|
|
break;
|
|
case GFC_FPE_UPWARD:
|
|
round_mode = _FPU_RC_UP;
|
|
break;
|
|
case GFC_FPE_DOWNWARD:
|
|
round_mode = _FPU_RC_DOWN;
|
|
break;
|
|
case GFC_FPE_TOWARDZERO:
|
|
round_mode = _FPU_RC_ZERO;
|
|
break;
|
|
default:
|
|
return; /* Should be unreachable. */
|
|
}
|
|
|
|
__asm__ __volatile__ ("fnstcw\t%0" : "=m" (cw));
|
|
|
|
/* The x87 round control bits are shifted by 10 bits. */
|
|
cw &= ~(_FPU_RC_MASK << 10);
|
|
cw |= round_mode << 10;
|
|
|
|
__asm__ __volatile__ ("fldcw\t%0" : : "m" (cw));
|
|
|
|
if (has_sse())
|
|
{
|
|
unsigned int cw_sse;
|
|
|
|
__asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw_sse));
|
|
|
|
/* The SSE round control bits are shifted by 13 bits. */
|
|
cw_sse &= ~(_FPU_RC_MASK << 13);
|
|
cw_sse |= round_mode << 13;
|
|
|
|
__asm__ __volatile__ ("%vldmxcsr\t%0" : : "m" (cw_sse));
|
|
}
|
|
}
|
|
|
|
int
|
|
get_fpu_rounding_mode (void)
|
|
{
|
|
int round_mode;
|
|
|
|
#ifdef __SSE_MATH__
|
|
unsigned int cw;
|
|
|
|
__asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw));
|
|
|
|
/* The SSE round control bits are shifted by 13 bits. */
|
|
round_mode = cw >> 13;
|
|
#else
|
|
unsigned short cw;
|
|
|
|
__asm__ __volatile__ ("fnstcw\t%0" : "=m" (cw));
|
|
|
|
/* The x87 round control bits are shifted by 10 bits. */
|
|
round_mode = cw >> 10;
|
|
#endif
|
|
|
|
round_mode &= _FPU_RC_MASK;
|
|
|
|
switch (round_mode)
|
|
{
|
|
case _FPU_RC_NEAREST:
|
|
return GFC_FPE_TONEAREST;
|
|
case _FPU_RC_UP:
|
|
return GFC_FPE_UPWARD;
|
|
case _FPU_RC_DOWN:
|
|
return GFC_FPE_DOWNWARD;
|
|
case _FPU_RC_ZERO:
|
|
return GFC_FPE_TOWARDZERO;
|
|
default:
|
|
return GFC_FPE_INVALID; /* Should be unreachable. */
|
|
}
|
|
}
|