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.