mirror of https://github.com/xemu-project/xemu.git
softfloat: Split out parts_uncanon_normal
We will need to treat the non-normal cases of floatx80 specially, so split out the normal case that we can reuse. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
9261b245f0
commit
25fdedf0d3
|
@ -140,8 +140,8 @@ static void partsN(canonicalize)(FloatPartsN *p, float_status *status,
|
||||||
* fraction; these bits will be removed. The exponent will be biased
|
* fraction; these bits will be removed. The exponent will be biased
|
||||||
* by EXP_BIAS and must be bounded by [EXP_MAX-1, 0].
|
* by EXP_BIAS and must be bounded by [EXP_MAX-1, 0].
|
||||||
*/
|
*/
|
||||||
static void partsN(uncanon)(FloatPartsN *p, float_status *s,
|
static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s,
|
||||||
const FloatFmt *fmt)
|
const FloatFmt *fmt)
|
||||||
{
|
{
|
||||||
const int exp_max = fmt->exp_max;
|
const int exp_max = fmt->exp_max;
|
||||||
const int frac_shift = fmt->frac_shift;
|
const int frac_shift = fmt->frac_shift;
|
||||||
|
@ -150,33 +150,9 @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s,
|
||||||
const uint64_t round_mask = fmt->round_mask;
|
const uint64_t round_mask = fmt->round_mask;
|
||||||
const uint64_t roundeven_mask = fmt->roundeven_mask;
|
const uint64_t roundeven_mask = fmt->roundeven_mask;
|
||||||
uint64_t inc;
|
uint64_t inc;
|
||||||
bool overflow_norm;
|
bool overflow_norm = false;
|
||||||
int exp, flags = 0;
|
int exp, flags = 0;
|
||||||
|
|
||||||
if (unlikely(p->cls != float_class_normal)) {
|
|
||||||
switch (p->cls) {
|
|
||||||
case float_class_zero:
|
|
||||||
p->exp = 0;
|
|
||||||
frac_clear(p);
|
|
||||||
return;
|
|
||||||
case float_class_inf:
|
|
||||||
g_assert(!fmt->arm_althp);
|
|
||||||
p->exp = fmt->exp_max;
|
|
||||||
frac_clear(p);
|
|
||||||
return;
|
|
||||||
case float_class_qnan:
|
|
||||||
case float_class_snan:
|
|
||||||
g_assert(!fmt->arm_althp);
|
|
||||||
p->exp = fmt->exp_max;
|
|
||||||
frac_shr(p, fmt->frac_shift);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
g_assert_not_reached();
|
|
||||||
}
|
|
||||||
|
|
||||||
overflow_norm = false;
|
|
||||||
switch (s->float_rounding_mode) {
|
switch (s->float_rounding_mode) {
|
||||||
case float_round_nearest_even:
|
case float_round_nearest_even:
|
||||||
inc = ((p->frac_lo & roundeven_mask) != frac_lsbm1 ? frac_lsbm1 : 0);
|
inc = ((p->frac_lo & roundeven_mask) != frac_lsbm1 ? frac_lsbm1 : 0);
|
||||||
|
@ -284,6 +260,35 @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s,
|
||||||
float_raise(flags, s);
|
float_raise(flags, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void partsN(uncanon)(FloatPartsN *p, float_status *s,
|
||||||
|
const FloatFmt *fmt)
|
||||||
|
{
|
||||||
|
if (likely(p->cls == float_class_normal)) {
|
||||||
|
parts_uncanon_normal(p, s, fmt);
|
||||||
|
} else {
|
||||||
|
switch (p->cls) {
|
||||||
|
case float_class_zero:
|
||||||
|
p->exp = 0;
|
||||||
|
frac_clear(p);
|
||||||
|
return;
|
||||||
|
case float_class_inf:
|
||||||
|
g_assert(!fmt->arm_althp);
|
||||||
|
p->exp = fmt->exp_max;
|
||||||
|
frac_clear(p);
|
||||||
|
return;
|
||||||
|
case float_class_qnan:
|
||||||
|
case float_class_snan:
|
||||||
|
g_assert(!fmt->arm_althp);
|
||||||
|
p->exp = fmt->exp_max;
|
||||||
|
frac_shr(p, fmt->frac_shift);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the result of adding or subtracting the values of the
|
* Returns the result of adding or subtracting the values of the
|
||||||
* floating-point values `a' and `b'. The operation is performed
|
* floating-point values `a' and `b'. The operation is performed
|
||||||
|
|
|
@ -764,6 +764,14 @@ static void parts128_canonicalize(FloatParts128 *p, float_status *status,
|
||||||
#define parts_canonicalize(A, S, F) \
|
#define parts_canonicalize(A, S, F) \
|
||||||
PARTS_GENERIC_64_128(canonicalize, A)(A, S, F)
|
PARTS_GENERIC_64_128(canonicalize, A)(A, S, F)
|
||||||
|
|
||||||
|
static void parts64_uncanon_normal(FloatParts64 *p, float_status *status,
|
||||||
|
const FloatFmt *fmt);
|
||||||
|
static void parts128_uncanon_normal(FloatParts128 *p, float_status *status,
|
||||||
|
const FloatFmt *fmt);
|
||||||
|
|
||||||
|
#define parts_uncanon_normal(A, S, F) \
|
||||||
|
PARTS_GENERIC_64_128(uncanon_normal, A)(A, S, F)
|
||||||
|
|
||||||
static void parts64_uncanon(FloatParts64 *p, float_status *status,
|
static void parts64_uncanon(FloatParts64 *p, float_status *status,
|
||||||
const FloatFmt *fmt);
|
const FloatFmt *fmt);
|
||||||
static void parts128_uncanon(FloatParts128 *p, float_status *status,
|
static void parts128_uncanon(FloatParts128 *p, float_status *status,
|
||||||
|
|
Loading…
Reference in New Issue