mirror of https://gitee.com/openkylin/qemu.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
|
||||
* by EXP_BIAS and must be bounded by [EXP_MAX-1, 0].
|
||||
*/
|
||||
static void partsN(uncanon)(FloatPartsN *p, float_status *s,
|
||||
const FloatFmt *fmt)
|
||||
static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s,
|
||||
const FloatFmt *fmt)
|
||||
{
|
||||
const int exp_max = fmt->exp_max;
|
||||
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 roundeven_mask = fmt->roundeven_mask;
|
||||
uint64_t inc;
|
||||
bool overflow_norm;
|
||||
bool overflow_norm = false;
|
||||
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) {
|
||||
case float_round_nearest_even:
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
* 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) \
|
||||
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,
|
||||
const FloatFmt *fmt);
|
||||
static void parts128_uncanon(FloatParts128 *p, float_status *status,
|
||||
|
|
Loading…
Reference in New Issue