[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