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.

Reply via email to