https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114659

--- Comment #15 from Alexander Monakov <amonakov at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #14)
> (In reply to Alexander Monakov from comment #13)
> > fldt does not convert (otherwise there's no way to spill/reload x87
> > registers).
> 
> Doesn't it still misbehave say on pseudo denormals, pseudo infinities,
> pseudo normals, pseudo NaNs etc.?

That would be surprising to me. I tried the following test and it passed:

#include <assert.h>
#include <stdio.h>
#include <string.h>

static union {
        struct {
                long long mant;
                short signexp;
        } i;
        long double ld;
} inp[] = {
        {{ 0x7fffffffffffffff, 32767 }}, // pseudo-QNaN, max payload
        {{ 0x4000000000000000, 32767 }}, // pseudo-QNaN, min payload
        {{ 0x3fffffffffffffff, 32767 }}, // pseudo-SNaN, max payload
        {{ 0x0000000000000001, 32767 }}, // pseudo-SNaN, min payload
        {{ 0x0000000000000000, 32767 }}, // pseudo-Inf
        {{ 0x7fffffffffffffff, 32766 }}, // max unnormal
        {{ 0x0000000000000001, 1 }},     // min unnormal
        {{ 0xffffffffffffffff, 0 }},     // max pseudo-denormal
        {{ 0x8000000000000001, 0 }},     // min pseudo-denormal
        // as above, with sign bit set
        {{ 0x7fffffffffffffff, 0x8000 | 32767 }},
        {{ 0x4000000000000000, 0x8000 | 32767 }},
        {{ 0x3fffffffffffffff, 0x8000 | 32767 }},
        {{ 0x0000000000000001, 0x8000 | 32767 }},
        {{ 0x0000000000000000, 0x8000 | 32767 }},
        {{ 0x7fffffffffffffff, 0x8000 | 32766 }},
        {{ 0x0000000000000001, 0x8000 | 1 }},
        {{ 0xffffffffffffffff, 0x8000 | 0 }},
        {{ 0x8000000000000001, 0x8000 | 0 }},
};

static long double out[sizeof inp / sizeof *inp];

int main()
{
        for (int i = 0; i < sizeof inp / sizeof *inp; i++) {
                long double t = inp[i].ld;
                asm("" : "+t"(t));
                out[i] = t;
        }
        assert(!memcmp(out, inp, sizeof inp));
}


> And even if not, it still contains padding bits, as it loads 10 bytes rather
> than 12 or 16 it occupies in memory.

Yes, it would be wrong to copy a, say, __int128 using fldt/fstp.

Reply via email to