mirror of
https://github.com/xemu-project/xemu.git
synced 2025-01-19 18:35:15 +00:00
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:
parent
68bd052ee1
commit
d0af544555
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user