fpu: Add rebias bool, value and operation
Added the possibility of recalculating a result if it overflows or underflows, if the result overflow and the rebias bool is true then the intermediate result should have 3/4 of the total range subtracted from the exponent. The same for underflow but it should be added to the exponent of the intermediate number instead. Signed-off-by: Lucas Mateus Castro (alqotel) <lucas.araujo@eldorado.org.br> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20220805141522.412864-2-lucas.araujo@eldorado.org.br> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
This commit is contained in:
parent
0bf4d77e59
commit
c40da5c6fb
@ -214,18 +214,35 @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s,
|
|||||||
p->frac_lo &= ~round_mask;
|
p->frac_lo &= ~round_mask;
|
||||||
}
|
}
|
||||||
} else if (unlikely(exp >= exp_max)) {
|
} else if (unlikely(exp >= exp_max)) {
|
||||||
flags |= float_flag_overflow | float_flag_inexact;
|
flags |= float_flag_overflow;
|
||||||
if (overflow_norm) {
|
if (s->rebias_overflow) {
|
||||||
|
exp -= fmt->exp_re_bias;
|
||||||
|
} else if (overflow_norm) {
|
||||||
|
flags |= float_flag_inexact;
|
||||||
exp = exp_max - 1;
|
exp = exp_max - 1;
|
||||||
frac_allones(p);
|
frac_allones(p);
|
||||||
p->frac_lo &= ~round_mask;
|
p->frac_lo &= ~round_mask;
|
||||||
} else {
|
} else {
|
||||||
|
flags |= float_flag_inexact;
|
||||||
p->cls = float_class_inf;
|
p->cls = float_class_inf;
|
||||||
exp = exp_max;
|
exp = exp_max;
|
||||||
frac_clear(p);
|
frac_clear(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
frac_shr(p, frac_shift);
|
frac_shr(p, frac_shift);
|
||||||
|
} else if (unlikely(s->rebias_underflow)) {
|
||||||
|
flags |= float_flag_underflow;
|
||||||
|
exp += fmt->exp_re_bias;
|
||||||
|
if (p->frac_lo & round_mask) {
|
||||||
|
flags |= float_flag_inexact;
|
||||||
|
if (frac_addi(p, p, inc)) {
|
||||||
|
frac_shr(p, 1);
|
||||||
|
p->frac_hi |= DECOMPOSED_IMPLICIT_BIT;
|
||||||
|
exp++;
|
||||||
|
}
|
||||||
|
p->frac_lo &= ~round_mask;
|
||||||
|
}
|
||||||
|
frac_shr(p, frac_shift);
|
||||||
} else if (s->flush_to_zero) {
|
} else if (s->flush_to_zero) {
|
||||||
flags |= float_flag_output_denormal;
|
flags |= float_flag_output_denormal;
|
||||||
p->cls = float_class_zero;
|
p->cls = float_class_zero;
|
||||||
|
@ -521,6 +521,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
int exp_size;
|
int exp_size;
|
||||||
int exp_bias;
|
int exp_bias;
|
||||||
|
int exp_re_bias;
|
||||||
int exp_max;
|
int exp_max;
|
||||||
int frac_size;
|
int frac_size;
|
||||||
int frac_shift;
|
int frac_shift;
|
||||||
@ -532,6 +533,7 @@ typedef struct {
|
|||||||
#define FLOAT_PARAMS_(E) \
|
#define FLOAT_PARAMS_(E) \
|
||||||
.exp_size = E, \
|
.exp_size = E, \
|
||||||
.exp_bias = ((1 << E) - 1) >> 1, \
|
.exp_bias = ((1 << E) - 1) >> 1, \
|
||||||
|
.exp_re_bias = (1 << (E - 1)) + (1 << (E - 2)), \
|
||||||
.exp_max = (1 << E) - 1
|
.exp_max = (1 << E) - 1
|
||||||
|
|
||||||
#define FLOAT_PARAMS(E, F) \
|
#define FLOAT_PARAMS(E, F) \
|
||||||
|
@ -195,6 +195,10 @@ typedef struct float_status {
|
|||||||
bool snan_bit_is_one;
|
bool snan_bit_is_one;
|
||||||
bool use_first_nan;
|
bool use_first_nan;
|
||||||
bool no_signaling_nans;
|
bool no_signaling_nans;
|
||||||
|
/* should overflowed results subtract re_bias to its exponent? */
|
||||||
|
bool rebias_overflow;
|
||||||
|
/* should underflowed results add re_bias to its exponent? */
|
||||||
|
bool rebias_underflow;
|
||||||
} float_status;
|
} float_status;
|
||||||
|
|
||||||
#endif /* SOFTFLOAT_TYPES_H */
|
#endif /* SOFTFLOAT_TYPES_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user