]>
Commit | Line | Data |
---|---|---|
d75e02d6 | 1 | /* |
7adcbafe | 2 | * Copyright (C) 2005-2022 Free Software Foundation, Inc. |
d75e02d6 L |
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 | |
748086b7 | 6 | * Free Software Foundation; either version 3, or (at your option) any |
d75e02d6 L |
7 | * later version. |
8 | * | |
d75e02d6 L |
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 | * | |
748086b7 JJ |
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/>. | |
d75e02d6 L |
22 | */ |
23 | ||
61221141 | 24 | #ifndef _SOFT_FLOAT |
d75e02d6 L |
25 | #define MXCSR_DAZ (1 << 6) /* Enable denormals are zero mode */ |
26 | #define MXCSR_FTZ (1 << 15) /* Enable flush to zero mode */ | |
27 | ||
b3172cab UB |
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" | |
adb7b764 | 32 | |
9b789cc1 UB |
33 | __attribute__ ((target("fxsr,sse"))) |
34 | static void | |
69b3f75b | 35 | /* The i386 ABI only requires 4-byte stack alignment, so this is necessary |
02709c7f JH |
36 | to make sure the fxsave struct gets correct alignment. |
37 | See PR27537 and PR28621. */ | |
38 | __attribute__ ((force_align_arg_pointer)) | |
9b789cc1 UB |
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 | } | |
02709c7f | 80 | #endif |
9b789cc1 UB |
81 | |
82 | static void __attribute__((constructor)) | |
d75e02d6 L |
83 | set_fast_math (void) |
84 | { | |
85 | #ifndef __x86_64__ | |
d75e02d6 L |
86 | unsigned int eax, ebx, ecx, edx; |
87 | ||
b3172cab | 88 | if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) |
d75e02d6 L |
89 | return; |
90 | ||
b3172cab | 91 | if (edx & bit_SSE) |
9b789cc1 | 92 | set_fast_math_sse (edx); |
adb7b764 L |
93 | #else |
94 | unsigned int mxcsr = __builtin_ia32_stmxcsr (); | |
95 | mxcsr |= MXCSR_DAZ | MXCSR_FTZ; | |
96 | __builtin_ia32_ldmxcsr (mxcsr); | |
97 | #endif | |
d75e02d6 | 98 | } |
61221141 | 99 | #endif |