aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/fpu_modes.h
blob: e8858ad9ef2663110ea7a212a5e669c36b9f0dbc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#ifndef FPU_MODES_H
#define FPU_MODES_H

#ifdef HAVE_FENV_H
#include <fenv.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef struct FPUCtl {
#if defined(__GNUC__) && defined(HAVE_SSE)
    unsigned int sse_state;
#elif defined(HAVE___CONTROL87_2)
    unsigned int state;
    unsigned int sse_state;
#elif defined(HAVE__CONTROLFP)
    unsigned int state;
#endif
} FPUCtl;
void SetMixerFPUMode(FPUCtl *ctl);
void RestoreFPUMode(const FPUCtl *ctl);

#ifdef __GNUC__
/* Use an alternate macro set with GCC to avoid accidental continue or break
 * statements within the mixer mode.
 */
#define START_MIXER_MODE() __extension__({ FPUCtl _oldMode; SetMixerFPUMode(&_oldMode)
#define END_MIXER_MODE() RestoreFPUMode(&_oldMode); })
#else
#define START_MIXER_MODE() do { FPUCtl _oldMode; SetMixerFPUMode(&_oldMode)
#define END_MIXER_MODE() RestoreFPUMode(&_oldMode); } while(0)
#endif
#define LEAVE_MIXER_MODE() RestoreFPUMode(&_oldMode)

#ifdef __cplusplus
} // extern "C"
#endif

#endif /* FPU_MODES_H */