Commit abe66f70 authored by Peter Maydell's avatar Peter Maydell
Browse files

target-arm: Ignore most exceptions from scalbn when doing fixpoint conversion



The VFP fixed point conversion helpers first call float_scalbn and
then convert the result to an integer. This scalbn operation may
set floating point exception flags for:
 * overflow & inexact (if it overflows to infinity)
 * input denormal squashed to zero
 * output denormal squashed to zero
Of these, we only care about the input-denormal flag, since
the output of the whole scale-and-convert operation will be
an integer (so squashed-output-denormal and overflow don't
apply). Suppress the others by saving the pre-scalb exception
flags and only copying across a potential input-denormal flag.
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Reviewed-by: default avatarRichard Henderson <rth@twiddle.net>
parent 16d5b3ca
...@@ -3986,18 +3986,27 @@ float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \ ...@@ -3986,18 +3986,27 @@ float##fsz HELPER(vfp_##name##to##p)(uint##isz##_t x, uint32_t shift, \
return float##fsz##_scalbn(tmp, -(int)shift, fpst); \ return float##fsz##_scalbn(tmp, -(int)shift, fpst); \
} }
/* Notice that we want only input-denormal exception flags from the
* scalbn operation: the other possible flags (overflow+inexact if
* we overflow to infinity, output-denormal) aren't correct for the
* complete scale-and-convert operation.
*/
#define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, round) \ #define VFP_CONV_FLOAT_FIX_ROUND(name, p, fsz, isz, itype, round) \
uint##isz##_t HELPER(vfp_to##name##p##round)(float##fsz x, \ uint##isz##_t HELPER(vfp_to##name##p##round)(float##fsz x, \
uint32_t shift, \ uint32_t shift, \
void *fpstp) \ void *fpstp) \
{ \ { \
float_status *fpst = fpstp; \ float_status *fpst = fpstp; \
int old_exc_flags = get_float_exception_flags(fpst); \
float##fsz tmp; \ float##fsz tmp; \
if (float##fsz##_is_any_nan(x)) { \ if (float##fsz##_is_any_nan(x)) { \
float_raise(float_flag_invalid, fpst); \ float_raise(float_flag_invalid, fpst); \
return 0; \ return 0; \
} \ } \
tmp = float##fsz##_scalbn(x, shift, fpst); \ tmp = float##fsz##_scalbn(x, shift, fpst); \
old_exc_flags |= get_float_exception_flags(fpst) \
& float_flag_input_denormal; \
set_float_exception_flags(old_exc_flags, fpst); \
return float##fsz##_to_##itype##round(tmp, fpst); \ return float##fsz##_to_##itype##round(tmp, fpst); \
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment