target-alpha: Fix float32_to_s vs zero exponent.

There was a bug in float32_to_s that incorrectly mapped a zero exponent
to 0x38.  This meant 0.0f != 0.  At the same time, fix a generic type
punning bug in helper_memory_to_s and helper_s_to_memory.

Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
Richard Henderson 2009-12-13 17:50:46 -08:00 committed by Aurelien Jarno
parent 68bd052ee1
commit d0af544555
1 changed files with 32 additions and 12 deletions

View File

@ -625,37 +625,57 @@ uint64_t helper_sqrtg (uint64_t a)
/* S floating (single) */
/* Taken from linux/arch/alpha/kernel/traps.c, s_mem_to_reg. */
static inline uint64_t float32_to_s_int(uint32_t fi)
{
uint32_t frac = fi & 0x7fffff;
uint32_t sign = fi >> 31;
uint32_t exp_msb = (fi >> 30) & 1;
uint32_t exp_low = (fi >> 23) & 0x7f;
uint32_t exp;
exp = (exp_msb << 10) | exp_low;
if (exp_msb) {
if (exp_low == 0x7f)
exp = 0x7ff;
} else {
if (exp_low != 0x00)
exp |= 0x380;
}
return (((uint64_t)sign << 63)
| ((uint64_t)exp << 52)
| ((uint64_t)frac << 29));
}
static inline uint64_t float32_to_s(float32 fa)
{
CPU_FloatU a;
uint64_t r;
a.f = fa;
return float32_to_s_int(a.l);
}
r = (((uint64_t)(a.l & 0xc0000000)) << 32) | (((uint64_t)(a.l & 0x3fffffff)) << 29);
if (((a.l & 0x7f800000) != 0x7f800000) && (!(a.l & 0x40000000)))
r |= 0x7ll << 59;
return r;
static inline uint32_t s_to_float32_int(uint64_t a)
{
return ((a >> 32) & 0xc0000000) | ((a >> 29) & 0x3fffffff);
}
static inline float32 s_to_float32(uint64_t a)
{
CPU_FloatU r;
r.l = ((a >> 32) & 0xc0000000) | ((a >> 29) & 0x3fffffff);
r.l = s_to_float32_int(a);
return r.f;
}
uint32_t helper_s_to_memory (uint64_t a)
{
/* Memory format is the same as float32 */
float32 fa = s_to_float32(a);
return *(uint32_t*)(&fa);
return s_to_float32_int(a);
}
uint64_t helper_memory_to_s (uint32_t a)
{
/* Memory format is the same as float32 */
return float32_to_s(*(float32*)(&a));
return float32_to_s_int(a);
}
uint64_t helper_adds (uint64_t a, uint64_t b)