Commit d359d1a0 authored by Lennert Buytenhek's avatar Lennert Buytenhek Committed by Russell King

[ARM PATCH] 2178/1: mnfd (move negated) emulation is busted on big-

 endian

Patch from Lennert Buytenhek

When you issue the mnfd opcode to negate a double, nwfpe is supposed
to flip the most significant bit of your double, which is the sign
bit.  However, on big endian systems, it ended up flipping the most
significant bit of the least significant sub-u32, which is one of the
mantissa bits.

On my system this was manifesting itself as sed regression tests
failing, and ntpd/ntpdate consistently adjusting the system clock
into the wrong direction.

In pretty much all of NWFPE, doubles are stored in u64s and
manipulations on those doubles are done by using u64 bitops.  But
for negation and fabs() it was poking into one of the sub-u32s
directly instead of XORing the u64 with 0x8000000000000000 resp.
ANDing with 0x7fffffffffffffff.

Since on big-endian, 'native u64 order' means that the most
significant byte (containing bits 63-56) is kept at the lowest
byte address, the sign bit is the MSB of the first sub-u32,
instead of the MSB of the second one as is the case on little
endian.

Signed-off-by: Lennert Buytenhek 
parent 76394d1d
......@@ -75,7 +75,11 @@ static float64 float64_mnf(float64 rFm)
union float64_components u;
u.f64 = rFm;
#ifdef __ARMEB__
u.i[0] ^= 0x80000000;
#else
u.i[1] ^= 0x80000000;
#endif
return u.f64;
}
......@@ -85,7 +89,11 @@ static float64 float64_abs(float64 rFm)
union float64_components u;
u.f64 = rFm;
#ifdef __ARMEB__
u.i[0] &= 0x7fffffff;
#else
u.i[1] &= 0x7fffffff;
#endif
return u.f64;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment