http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55372
--- Comment #1 from stevenbaker94 at rocketmail dot com 2013-05-01 10:16:56 UTC --- This version handles negative numbers as well: static inline float _fpos(const float f) { union { float f; uint32_t i; } x; x.f = f; uint32_t r; float f_out; asm ("lui %0, %1" : "=d" (r) : "K" (x.i >> 16)); asm ("mtc1 %1, %0" : "=f" (f_out) : "d" (r)); return f_out; } static inline float _fneg(const float f) { union { float f; uint32_t i; } x; x.f = f; uint32_t r; float f_out; asm ("lui %0, %1" : "=d" (r) : "K" (0x8000 ^ (x.i >> 16))); asm ("mtc1 %1, %0" : "=f" (f_out) : "d" (r)); return f_out; } static inline float f(const float f) { return f >= 0 ? _fpos(f) : _fneg(-f); } Actually, it doesn't always discard fractional bits. It works for e.g. f(0.25) as well, since the floating-point representation still only has 0s in the lower 16 bits.