1 /* 2 * Copyright (C) 2005-2015 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 #endif 33 34 static void __attribute__((constructor)) 35 #ifndef __x86_64__ 36 /* The i386 ABI only requires 4-byte stack alignment, so this is necessary 37 to make sure the fxsave struct gets correct alignment. 38 See PR27537 and PR28621. */ 39 __attribute__ ((force_align_arg_pointer)) 40 #endif 41 set_fast_math (void) 42 { 43 #ifndef __x86_64__ 44 unsigned int eax, ebx, ecx, edx; 45 46 if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) 47 return; 48 49 if (edx & bit_SSE) 50 { 51 unsigned int mxcsr; 52 53 if (edx & bit_FXSAVE) 54 { 55 /* Check if DAZ is available. */ 56 struct 57 { 58 unsigned short cwd; 59 unsigned short swd; 60 unsigned short twd; 61 unsigned short fop; 62 unsigned int fip; 63 unsigned int fcs; 64 unsigned int foo; 65 unsigned int fos; 66 unsigned int mxcsr; 67 unsigned int mxcsr_mask; 68 unsigned int st_space[32]; 69 unsigned int xmm_space[32]; 70 unsigned int padding[56]; 71 } __attribute__ ((aligned (16))) fxsave; 72 73 /* This is necessary since some implementations of FXSAVE 74 do not modify reserved areas within the image. */ 75 fxsave.mxcsr_mask = 0; 76 77 __builtin_ia32_fxsave (&fxsave); 78 79 mxcsr = fxsave.mxcsr; 80 81 if (fxsave.mxcsr_mask & MXCSR_DAZ) 82 mxcsr |= MXCSR_DAZ; 83 } 84 else 85 mxcsr = __builtin_ia32_stmxcsr (); 86 87 mxcsr |= MXCSR_FTZ; 88 __builtin_ia32_ldmxcsr (mxcsr); 89 } 90 #else 91 unsigned int mxcsr = __builtin_ia32_stmxcsr (); 92 mxcsr |= MXCSR_DAZ | MXCSR_FTZ; 93 __builtin_ia32_ldmxcsr (mxcsr); 94 #endif 95 } 96 #endif 97