[Libre-soc-dev] New instruction

Jacob Lifshay programmerjake at gmail.com
Tue Mar 2 19:45:05 GMT 2021


On Tue, Mar 2, 2021, 10:23 Luke Kenneth Casson Leighton <lkcl at lkcl.net>
wrote:

> On Tuesday, March 2, 2021, Jacob Lifshay <programmerjake at gmail.com> wrote:
>
> > no... it turns into a single shift and mask operation at the HW
> > level...such is the fate of division by a constant power of 2.
>
> v = fmod(v, 1LL << 32);
>
> ah wheww.
>
> a subtract on the exponent, looping minus 32 each time.  that's tolerable.
>  still absolutely dreadful, mind.
>

umm...that's still waay less efficient than can be done with a shift:

https://gcc.godbolt.org/z/4KPxxh

int32_t js_cvt(double v) {
    union {
        double f;
        uint64_t i;
    } u;
    u.f = v;
    const uint64_t EXPONENT_FIELD = 0x7FF0'0000'0000'0000ULL;
    const int EXPONENT_BIAS = 0x3FF;
    const int EXPONENT_MAX = 0x7FF;
    const int MANTISSA_FIELD_WIDTH = 52;
    const uint64_t MANTISSA_FIELD = (1ULL << MANTISSA_FIELD_WIDTH) - 1;
    int exponent = (u.i & EXPONENT_FIELD) >> MANTISSA_FIELD_WIDTH;
    if(exponent == EXPONENT_MAX) // inf, -inf, or nan
        return 0;
    uint64_t mantissa = (u.i & MANTISSA_FIELD) | (1ULL <<
MANTISSA_FIELD_WIDTH);
    int mantissa_shift = exponent - EXPONENT_BIAS - MANTISSA_FIELD_WIDTH;
    if(mantissa_shift <= -64) // shift all bits out, leaving only zeros
        return 0;
    if(mantissa_shift >= 64) // shift all bits out, leaving only zeros
        return 0;
    if(mantissa_shift < 0)
        mantissa >>= -mantissa_shift;
    else
        mantissa <<= mantissa_shift;
    if(v < 0)
        mantissa = -mantissa;
    return (int32_t)mantissa; // wrap to int32_t
}

Jacob


More information about the Libre-soc-dev mailing list