mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 17:23:56 -06:00
softfloat: Move minmax_flags to softfloat-parts.c.inc
Rename to parts$N_minmax. Combine 3 bool arguments to a bitmask. Introduce ftype_minmax functions as a common optimization point. Fold bfloat16 expansions into the same macro as the other types. Reviewed-by: David Hildenbrand <david@redhat.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
37c954a1b9
commit
e1c4667a9b
2 changed files with 152 additions and 126 deletions
|
@ -938,3 +938,83 @@ static void partsN(uint_to_float)(FloatPartsN *p, uint64_t a,
|
|||
p->frac_hi = a << shift;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Float min/max.
|
||||
*/
|
||||
static FloatPartsN *partsN(minmax)(FloatPartsN *a, FloatPartsN *b,
|
||||
float_status *s, int flags)
|
||||
{
|
||||
int ab_mask = float_cmask(a->cls) | float_cmask(b->cls);
|
||||
int a_exp, b_exp, cmp;
|
||||
|
||||
if (unlikely(ab_mask & float_cmask_anynan)) {
|
||||
/*
|
||||
* For minnum/maxnum, if one operand is a QNaN, and the other
|
||||
* operand is numerical, then return numerical argument.
|
||||
*/
|
||||
if ((flags & minmax_isnum)
|
||||
&& !(ab_mask & float_cmask_snan)
|
||||
&& (ab_mask & ~float_cmask_qnan)) {
|
||||
return is_nan(a->cls) ? b : a;
|
||||
}
|
||||
return parts_pick_nan(a, b, s);
|
||||
}
|
||||
|
||||
a_exp = a->exp;
|
||||
b_exp = b->exp;
|
||||
|
||||
if (unlikely(ab_mask != float_cmask_normal)) {
|
||||
switch (a->cls) {
|
||||
case float_class_normal:
|
||||
break;
|
||||
case float_class_inf:
|
||||
a_exp = INT16_MAX;
|
||||
break;
|
||||
case float_class_zero:
|
||||
a_exp = INT16_MIN;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
switch (b->cls) {
|
||||
case float_class_normal:
|
||||
break;
|
||||
case float_class_inf:
|
||||
b_exp = INT16_MAX;
|
||||
break;
|
||||
case float_class_zero:
|
||||
b_exp = INT16_MIN;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Compare magnitudes. */
|
||||
cmp = a_exp - b_exp;
|
||||
if (cmp == 0) {
|
||||
cmp = frac_cmp(a, b);
|
||||
}
|
||||
|
||||
/*
|
||||
* Take the sign into account.
|
||||
* For ismag, only do this if the magnitudes are equal.
|
||||
*/
|
||||
if (!(flags & minmax_ismag) || cmp == 0) {
|
||||
if (a->sign != b->sign) {
|
||||
/* For differing signs, the negative operand is less. */
|
||||
cmp = a->sign ? -1 : 1;
|
||||
} else if (a->sign) {
|
||||
/* For two negative operands, invert the magnitude comparison. */
|
||||
cmp = -cmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & minmax_ismin) {
|
||||
cmp = -cmp;
|
||||
}
|
||||
return cmp < 0 ? b : a;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue