75#if defined(_MSC_VER) && !defined(_WIN64)
76# define HAVE__CONTROLFP_S
79#if defined(HAVE__CONTROLFP_S) && !defined(__x86_64__)
84# define XPFPA_HAVE_CW 1
85# define XPFPA_CW_DATATYPE \
88# define XPFPA_STORE_CW(vptr) do { \
89 _controlfp_s((unsigned int *)(vptr), 0, 0); \
92# define XPFPA_RESTORE_CW(vptr) do { \
93 unsigned int _xpfpa_fpu_cw; \
94 _controlfp_s(&_xpfpa_fpu_cw, *((unsigned int *)(vptr)), _MCW_PC); \
97# define XPFPA_DECLARE \
98 unsigned int _xpfpa_fpu_oldcw, _xpfpa_fpu_cw;
100# define XPFPA_SWITCH_DOUBLE() do { \
101 _controlfp_s(&_xpfpa_fpu_cw, 0, 0); \
102 _xpfpa_fpu_oldcw = _xpfpa_fpu_cw; \
103 _controlfp_s(&_xpfpa_fpu_cw, _PC_53, _MCW_PC); \
105# define XPFPA_SWITCH_SINGLE() do { \
106 _controlfp_s(&_xpfpa_fpu_cw, 0, 0); \
107 _xpfpa_fpu_oldcw = _xpfpa_fpu_cw; \
108 _controlfp_s(&_xpfpa_fpu_cw, _PC_24, _MCW_PC); \
112# define XPFPA_SWITCH_DOUBLE_EXTENDED() do { \
113 _controlfp_s(&_xpfpa_fpu_cw, 0, 0); \
114 _xpfpa_fpu_oldcw = _xpfpa_fpu_cw; \
115 _controlfp_s(&_xpfpa_fpu_cw, _PC_64, _MCW_PC); \
117# define XPFPA_RESTORE() \
118 _controlfp_s(&_xpfpa_fpu_cw, _xpfpa_fpu_oldcw, _MCW_PC)
123# define XPFPA_RETURN_DOUBLE(val) \
125 double _xpfpa_result = (val); \
127 return _xpfpa_result; \
129# define XPFPA_RETURN_SINGLE(val) \
131 float _xpfpa_result = (val); \
133 return _xpfpa_result; \
136# define XPFPA_RETURN_DOUBLE_EXTENDED(val) \
138 long double _xpfpa_result = (val); \
140 return _xpfpa_result; \
143#elif defined(HAVE__CONTROLFP) && !defined(__x86_64__)
148# define XPFPA_DECLARE \
149 unsigned int _xpfpa_fpu_oldcw;
151# define XPFPA_HAVE_CW 1
152# define XPFPA_CW_DATATYPE \
155# define XPFPA_STORE_CW(vptr) do { \
156 *((unsigned int *)(vptr)) = _controlfp(0, 0); \
159# define XPFPA_RESTORE_CW(vptr) do { \
160 _controlfp(*((unsigned int *)(vptr)), _MCW_PC); \
163# define XPFPA_SWITCH_DOUBLE() do { \
164 _xpfpa_fpu_oldcw = _controlfp(0, 0); \
165 _controlfp(_PC_53, _MCW_PC); \
167# define XPFPA_SWITCH_SINGLE() do { \
168 _xpfpa_fpu_oldcw = _controlfp(0, 0); \
169 _controlfp(_PC_24, _MCW_PC); \
172# define XPFPA_SWITCH_DOUBLE_EXTENDED() do { \
173 _xpfpa_fpu_oldcw = _controlfp(0, 0); \
174 _controlfp(_PC_64, _MCW_PC); \
176# define XPFPA_RESTORE() \
177 _controlfp(_xpfpa_fpu_oldcw, _MCW_PC)
182# define XPFPA_RETURN_DOUBLE(val) \
184 double _xpfpa_result = (val); \
186 return _xpfpa_result; \
188# define XPFPA_RETURN_SINGLE(val) \
190 float _xpfpa_result = (val); \
192 return _xpfpa_result; \
195# define XPFPA_RETURN_DOUBLE_EXTENDED(val) \
197 long double _xpfpa_result = (val); \
199 return _xpfpa_result; \
202#elif defined(HAVE__FPU_SETCW) && !defined(__x86_64__)
205# include <fpu_control.h>
207# define XPFPA_DECLARE \
208 fpu_control_t _xpfpa_fpu_oldcw, _xpfpa_fpu_cw;
210# define XPFPA_HAVE_CW 1
211# define XPFPA_CW_DATATYPE \
214# define XPFPA_STORE_CW(vptr) do { \
215 _FPU_GETCW((*((fpu_control_t *)(vptr)))); \
218# define XPFPA_RESTORE_CW(vptr) do { \
219 _FPU_SETCW((*((fpu_control_t *)(vptr)))); \
222# define XPFPA_SWITCH_DOUBLE() do { \
223 _FPU_GETCW(_xpfpa_fpu_oldcw); \
224 _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~_FPU_EXTENDED & ~_FPU_SINGLE) | _FPU_DOUBLE; \
225 _FPU_SETCW(_xpfpa_fpu_cw); \
227# define XPFPA_SWITCH_SINGLE() do { \
228 _FPU_GETCW(_xpfpa_fpu_oldcw); \
229 _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~_FPU_EXTENDED & ~_FPU_DOUBLE) | _FPU_SINGLE; \
230 _FPU_SETCW(_xpfpa_fpu_cw); \
232# define XPFPA_SWITCH_DOUBLE_EXTENDED() do { \
233 _FPU_GETCW(_xpfpa_fpu_oldcw); \
234 _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~_FPU_SINGLE & ~_FPU_DOUBLE) | _FPU_EXTENDED; \
235 _FPU_SETCW(_xpfpa_fpu_cw); \
237# define XPFPA_RESTORE() \
238 _FPU_SETCW(_xpfpa_fpu_oldcw)
242# define XPFPA_RETURN_DOUBLE(val) \
244 volatile double _xpfpa_result = (val); \
246 return _xpfpa_result; \
248# define XPFPA_RETURN_SINGLE(val) \
250 volatile float _xpfpa_result = (val); \
252 return _xpfpa_result; \
254# define XPFPA_RETURN_DOUBLE_EXTENDED(val) \
256 volatile long double _xpfpa_result = (val); \
258 return _xpfpa_result; \
261#elif defined(HAVE_FPSETPREC) && !defined(__x86_64__)
264# include <machine/ieeefp.h>
266# define XPFPA_DECLARE \
267 fp_prec_t _xpfpa_fpu_oldprec;
269# define XPFPA_HAVE_CW 1
270# define XPFPA_CW_DATATYPE \
273# define XPFPA_STORE_CW(vptr) do { \
274 *((fp_prec_t *)(vptr)) = fpgetprec(); \
277# define XPFPA_RESTORE_CW(vptr) do { \
278 fpsetprec(*((fp_prec_t *)(vptr))); \
281# define XPFPA_SWITCH_DOUBLE() do { \
282 _xpfpa_fpu_oldprec = fpgetprec(); \
285# define XPFPA_SWITCH_SINGLE() do { \
286 _xpfpa_fpu_oldprec = fpgetprec(); \
289# define XPFPA_SWITCH_DOUBLE_EXTENDED() do { \
290 _xpfpa_fpu_oldprec = fpgetprec(); \
293# define XPFPA_RESTORE() \
294 fpsetprec(_xpfpa_fpu_oldprec)
298# define XPFPA_RETURN_DOUBLE(val) \
300 volatile double _xpfpa_result = (val); \
302 return _xpfpa_result; \
304# define XPFPA_RETURN_SINGLE(val) \
306 volatile float _xpfpa_result = (val); \
308 return _xpfpa_result; \
310# define XPFPA_RETURN_DOUBLE_EXTENDED(val) \
312 volatile long double _xpfpa_result = (val); \
314 return _xpfpa_result; \
317#elif defined(HAVE_FPU_INLINE_ASM_X86) && !defined(__x86_64__)
341# define XPFPA_DECLARE \
342 unsigned int _xpfpa_fpu_oldcw, _xpfpa_fpu_cw;
344# define XPFPA_HAVE_CW 1
345# define XPFPA_CW_DATATYPE \
348# define XPFPA_STORE_CW(vptr) do { \
349 __asm__ __volatile__ ("fnstcw %0" : "=m" (*((unsigned int *)(vptr)))); \
352# define XPFPA_RESTORE_CW(vptr) do { \
353 __asm__ __volatile__ ("fldcw %0" : : "m" (*((unsigned int *)(vptr)))); \
356# define XPFPA_SWITCH_DOUBLE() do { \
357 __asm__ __volatile__ ("fnstcw %0" : "=m" (*&_xpfpa_fpu_oldcw)); \
358 _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~0x100) | 0x200; \
359 __asm__ __volatile__ ("fldcw %0" : : "m" (*&_xpfpa_fpu_cw)); \
361# define XPFPA_SWITCH_SINGLE() do { \
362 __asm__ __volatile__ ("fnstcw %0" : "=m" (*&_xpfpa_fpu_oldcw)); \
363 _xpfpa_fpu_cw = (_xpfpa_fpu_oldcw & ~0x300); \
364 __asm__ __volatile__ ("fldcw %0" : : "m" (*&_xpfpa_fpu_cw)); \
366# define XPFPA_SWITCH_DOUBLE_EXTENDED() do { \
367 __asm__ __volatile__ ("fnstcw %0" : "=m" (*&_xpfpa_fpu_oldcw)); \
368 _xpfpa_fpu_cw = _xpfpa_fpu_oldcw | 0x300; \
369 __asm__ __volatile__ ("fldcw %0" : : "m" (*&_xpfpa_fpu_cw)); \
371# define XPFPA_RESTORE() \
372 __asm__ __volatile__ ("fldcw %0" : : "m" (*&_xpfpa_fpu_oldcw))
376# define XPFPA_RETURN_DOUBLE(val) \
378 volatile double _xpfpa_result = (val); \
380 return _xpfpa_result; \
382# define XPFPA_RETURN_SINGLE(val) \
384 volatile float _xpfpa_result = (val); \
386 return _xpfpa_result; \
388# define XPFPA_RETURN_DOUBLE_EXTENDED(val) \
390 volatile long double _xpfpa_result = (val); \
392 return _xpfpa_result; \
402# define XPFPA_DECLARE
403# define XPFPA_HAVE_CW 0
404# define XPFPA_CW_DATATYPE unsigned int
405# define XPFPA_STORE_CW(variable)
406# define XPFPA_RESTORE_CW(variable)
407# define XPFPA_SWITCH_DOUBLE()
408# define XPFPA_SWITCH_SINGLE()
409# define XPFPA_SWITCH_DOUBLE_EXTENDED()
410# define XPFPA_RESTORE()
411# define XPFPA_RETURN_DOUBLE(val) return (val)
412# define XPFPA_RETURN_SINGLE(val) return (val)
413# define XPFPA_RETURN_DOUBLE_EXTENDED(val) return (val)
ZEND_API void zend_shutdown_fpu(void)
ZEND_API void zend_init_fpu(void)
ZEND_API void zend_ensure_fpu_mode(void)