9ecaf5ccec
The softfloat function floatx80_round_to_int incorrectly handles the case of a pseudo-denormal where only the high bit of the significand is set, ignoring that bit (treating the number as an exact zero) rather than treating the number as an alternative representation of +/- 2^-16382 (which may round to +/- 1 depending on the rounding mode) as hardware does. Fix this check (simplifying the code in the process). Signed-off-by: Joseph Myers <joseph@codesourcery.com> Message-Id: <alpine.DEB.2.21.2005042339420.22972@digraph.polyomino.org.uk> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
39 lines
948 B
C
39 lines
948 B
C
/* Test pseudo-denormal operations. */
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
|
|
union u {
|
|
struct { uint64_t sig; uint16_t sign_exp; } s;
|
|
long double ld;
|
|
};
|
|
|
|
volatile union u ld_pseudo_m16382 = { .s = { UINT64_C(1) << 63, 0 } };
|
|
|
|
volatile long double ld_res;
|
|
|
|
int main(void)
|
|
{
|
|
short cw;
|
|
int ret = 0;
|
|
ld_res = ld_pseudo_m16382.ld + ld_pseudo_m16382.ld;
|
|
if (ld_res != 0x1p-16381L) {
|
|
printf("FAIL: pseudo-denormal add\n");
|
|
ret = 1;
|
|
}
|
|
if (ld_pseudo_m16382.ld != 0x1p-16382L) {
|
|
printf("FAIL: pseudo-denormal compare\n");
|
|
ret = 1;
|
|
}
|
|
/* Set round-upward. */
|
|
__asm__ volatile ("fnstcw %0" : "=m" (cw));
|
|
cw = (cw & ~0xc00) | 0x800;
|
|
__asm__ volatile ("fldcw %0" : : "m" (cw));
|
|
__asm__ ("frndint" : "=t" (ld_res) : "0" (ld_pseudo_m16382.ld));
|
|
if (ld_res != 1.0L) {
|
|
printf("FAIL: pseudo-denormal round-to-integer\n");
|
|
ret = 1;
|
|
}
|
|
return ret;
|
|
}
|