(root)/
gcc-13.2.0/
libgcc/
config/
i386/
crtfastmath.c
       1  /*
       2   * Copyright (C) 2005-2023 Free Software Foundation, Inc.
       3   *
       4   * This file is free software; you can redistribute it and/or modify it
       5   * under the terms of the GNU General Public License as published by the
       6   * Free Software Foundation; either version 3, or (at your option) any
       7   * later version.
       8   * 
       9   * This file is distributed in the hope that it will be useful, but
      10   * WITHOUT ANY WARRANTY; without even the implied warranty of
      11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12   * General Public License for more details.
      13   * 
      14   * Under Section 7 of GPL version 3, you are granted additional
      15   * permissions described in the GCC Runtime Library Exception, version
      16   * 3.1, as published by the Free Software Foundation.
      17   *
      18   * You should have received a copy of the GNU General Public License and
      19   * a copy of the GCC Runtime Library Exception along with this program;
      20   * see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      21   * <http://www.gnu.org/licenses/>.
      22   */
      23  
      24  #ifndef _SOFT_FLOAT
      25  #define MXCSR_DAZ (1 << 6)	/* Enable denormals are zero mode */
      26  #define MXCSR_FTZ (1 << 15)	/* Enable flush to zero mode */
      27  
      28  #ifndef __x86_64__
      29  /* All 64-bit targets have SSE and DAZ;
      30     only check them explicitly for 32-bit ones. */
      31  #include "cpuid.h"
      32  
      33  __attribute__ ((target("fxsr,sse")))
      34  static void
      35  /* The i386 ABI only requires 4-byte stack alignment, so this is necessary
      36     to make sure the fxsave struct gets correct alignment.
      37     See PR27537 and PR28621.  */
      38  __attribute__ ((force_align_arg_pointer))
      39  set_fast_math_sse (unsigned int edx)
      40  {
      41    unsigned int mxcsr;
      42    
      43    if (edx & bit_FXSAVE)
      44      {
      45        /* Check if DAZ is available.  */
      46        struct
      47        {
      48  	unsigned short cwd;
      49  	unsigned short swd;
      50  	unsigned short twd;
      51  	unsigned short fop;
      52  	unsigned int fip;
      53  	unsigned int fcs;
      54  	unsigned int foo;
      55  	unsigned int fos;
      56  	unsigned int mxcsr;
      57  	unsigned int mxcsr_mask;
      58  	unsigned int st_space[32];
      59  	unsigned int xmm_space[32];
      60  	unsigned int padding[56];
      61        } __attribute__ ((aligned (16))) fxsave;
      62  
      63        /* This is necessary since some implementations of FXSAVE
      64  	 do not modify reserved areas within the image.  */
      65        fxsave.mxcsr_mask = 0;
      66  
      67        __builtin_ia32_fxsave (&fxsave);
      68  
      69        mxcsr = fxsave.mxcsr;
      70  
      71        if (fxsave.mxcsr_mask & MXCSR_DAZ)
      72  	mxcsr |= MXCSR_DAZ;
      73      }
      74    else
      75      mxcsr = __builtin_ia32_stmxcsr ();
      76  
      77    mxcsr |= MXCSR_FTZ;
      78    __builtin_ia32_ldmxcsr (mxcsr);
      79  }
      80  #endif
      81  
      82  static void __attribute__((constructor))
      83  set_fast_math (void)
      84  {
      85  #ifndef __x86_64__
      86    unsigned int eax, ebx, ecx, edx;
      87  
      88    if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx))
      89      return;
      90  
      91    if (edx & bit_SSE)
      92      set_fast_math_sse (edx);
      93  #else
      94    unsigned int mxcsr = __builtin_ia32_stmxcsr ();
      95    mxcsr |= MXCSR_DAZ | MXCSR_FTZ;
      96    __builtin_ia32_ldmxcsr (mxcsr);
      97  #endif
      98  }
      99  #endif