2002-06-13 18:20:48 +08:00
|
|
|
#include <fenv.h>
|
2002-07-29 11:00:10 +08:00
|
|
|
#include <math.h>
|
2002-06-13 18:20:48 +08:00
|
|
|
|
2002-07-29 11:00:10 +08:00
|
|
|
long
|
|
|
|
lround (double x) {
|
|
|
|
long retval;
|
2002-06-13 18:20:48 +08:00
|
|
|
unsigned short saved_cw, _cw;
|
|
|
|
__asm__ (
|
2002-07-29 11:00:10 +08:00
|
|
|
"fnstcw %0;" : "=m" (saved_cw)
|
2002-06-13 18:20:48 +08:00
|
|
|
); /* save control word */
|
|
|
|
_cw = ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)
|
|
|
|
| (x > 0.0 ? FE_UPWARD : FE_DOWNWARD); /* round away from zero */
|
|
|
|
__asm__ (
|
2002-07-29 11:00:10 +08:00
|
|
|
"fldcw %0;" : : "m" (_cw)
|
2002-06-13 18:20:48 +08:00
|
|
|
); /* load the rounding control */
|
2002-07-29 11:00:10 +08:00
|
|
|
__asm__ __volatile__ (
|
|
|
|
"fistpll %0" : "=m" (retval) : "t" (x) : "st"
|
|
|
|
);
|
2002-06-13 18:20:48 +08:00
|
|
|
__asm__ (
|
2002-07-29 11:00:10 +08:00
|
|
|
"fldcw %0;" : : "m" (saved_cw)
|
2002-06-13 18:20:48 +08:00
|
|
|
); /* restore control word */
|
|
|
|
return retval;
|
|
|
|
}
|
2002-07-29 11:00:10 +08:00
|
|
|
|