diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2011-05-19 14:46:19 +0100 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2011-05-23 22:39:36 +0200 |
commit | 5500b06cb5091c352a7ce6552da02c9e1958bf3b (patch) | |
tree | 5fd93bad4e53a0b6272215927e63937bcc7118c2 /target-arm/helper.c | |
parent | 36802b6b1ed7887aeae5d027f86a969400f8824a (diff) |
target-arm: Use correct float status for Neon int-float conversions
The Neon versions of int-float conversions must use the "standard FPSCR"
rather than the default FPSCR. Implement this by having the helper
functions take a pointer to the appropriate float_status value rather
than simply taking a pointer to the entire CPUState, and making
translate.c pass a pointer to vfp.fp_status or vfp.standard_fp_status
appropriately for whether the instruction being translated is Neon
or VFP.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
Diffstat (limited to 'target-arm/helper.c')
-rw-r--r-- | target-arm/helper.c | 132 |
1 files changed, 37 insertions, 95 deletions
diff --git a/target-arm/helper.c b/target-arm/helper.c index 05b3ccca2d..1cc492d8a3 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -2526,99 +2526,39 @@ DO_VFP_cmp(s, float32) DO_VFP_cmp(d, float64) #undef DO_VFP_cmp -/* Integer to float conversion. */ -float32 VFP_HELPER(uito, s)(uint32_t x, CPUState *env) -{ - return uint32_to_float32(x, &env->vfp.fp_status); -} +/* Integer to float and float to integer conversions */ -float64 VFP_HELPER(uito, d)(uint32_t x, CPUState *env) -{ - return uint32_to_float64(x, &env->vfp.fp_status); -} - -float32 VFP_HELPER(sito, s)(uint32_t x, CPUState *env) -{ - return int32_to_float32(x, &env->vfp.fp_status); -} - -float64 VFP_HELPER(sito, d)(uint32_t x, CPUState *env) -{ - return int32_to_float64(x, &env->vfp.fp_status); -} - -/* Float to integer conversion. */ -uint32_t VFP_HELPER(toui, s)(float32 x, CPUState *env) -{ - if (float32_is_any_nan(x)) { - float_raise(float_flag_invalid, &env->vfp.fp_status); - return 0; - } - return float32_to_uint32(x, &env->vfp.fp_status); -} - -uint32_t VFP_HELPER(toui, d)(float64 x, CPUState *env) -{ - if (float64_is_any_nan(x)) { - float_raise(float_flag_invalid, &env->vfp.fp_status); - return 0; - } - return float64_to_uint32(x, &env->vfp.fp_status); -} - -uint32_t VFP_HELPER(tosi, s)(float32 x, CPUState *env) -{ - if (float32_is_any_nan(x)) { - float_raise(float_flag_invalid, &env->vfp.fp_status); - return 0; - } - return float32_to_int32(x, &env->vfp.fp_status); -} - -uint32_t VFP_HELPER(tosi, d)(float64 x, CPUState *env) -{ - if (float64_is_any_nan(x)) { - float_raise(float_flag_invalid, &env->vfp.fp_status); - return 0; - } - return float64_to_int32(x, &env->vfp.fp_status); +#define CONV_ITOF(name, fsz, sign) \ + float##fsz HELPER(name)(uint32_t x, void *fpstp) \ +{ \ + float_status *fpst = fpstp; \ + return sign##int32_to_##float##fsz(x, fpst); \ } -uint32_t VFP_HELPER(touiz, s)(float32 x, CPUState *env) -{ - if (float32_is_any_nan(x)) { - float_raise(float_flag_invalid, &env->vfp.fp_status); - return 0; - } - return float32_to_uint32_round_to_zero(x, &env->vfp.fp_status); +#define CONV_FTOI(name, fsz, sign, round) \ +uint32_t HELPER(name)(float##fsz x, void *fpstp) \ +{ \ + float_status *fpst = fpstp; \ + if (float##fsz##_is_any_nan(x)) { \ + float_raise(float_flag_invalid, fpst); \ + return 0; \ + } \ + return float##fsz##_to_##sign##int32##round(x, fpst); \ } -uint32_t VFP_HELPER(touiz, d)(float64 x, CPUState *env) -{ - if (float64_is_any_nan(x)) { - float_raise(float_flag_invalid, &env->vfp.fp_status); - return 0; - } - return float64_to_uint32_round_to_zero(x, &env->vfp.fp_status); -} +#define FLOAT_CONVS(name, p, fsz, sign) \ +CONV_ITOF(vfp_##name##to##p, fsz, sign) \ +CONV_FTOI(vfp_to##name##p, fsz, sign, ) \ +CONV_FTOI(vfp_to##name##z##p, fsz, sign, _round_to_zero) -uint32_t VFP_HELPER(tosiz, s)(float32 x, CPUState *env) -{ - if (float32_is_any_nan(x)) { - float_raise(float_flag_invalid, &env->vfp.fp_status); - return 0; - } - return float32_to_int32_round_to_zero(x, &env->vfp.fp_status); -} +FLOAT_CONVS(si, s, 32, ) +FLOAT_CONVS(si, d, 64, ) +FLOAT_CONVS(ui, s, 32, u) +FLOAT_CONVS(ui, d, 64, u) -uint32_t VFP_HELPER(tosiz, d)(float64 x, CPUState *env) -{ - if (float64_is_any_nan(x)) { - float_raise(float_flag_invalid, &env->vfp.fp_status); - return 0; - } - return float64_to_int32_round_to_zero(x, &env->vfp.fp_status); -} +#undef CONV_ITOF +#undef CONV_FTOI +#undef FLOAT_CONVS /* floating point conversion */ float64 VFP_HELPER(fcvtd, s)(float32 x, CPUState *env) @@ -2641,23 +2581,25 @@ float32 VFP_HELPER(fcvts, d)(float64 x, CPUState *env) /* VFP3 fixed point conversion. */ #define VFP_CONV_FIX(name, p, fsz, itype, sign) \ -float##fsz VFP_HELPER(name##to, p)(uint##fsz##_t x, uint32_t shift, \ - CPUState *env) \ +float##fsz HELPER(vfp_##name##to##p)(uint##fsz##_t x, uint32_t shift, \ + void *fpstp) \ { \ + float_status *fpst = fpstp; \ float##fsz tmp; \ - tmp = sign##int32_to_##float##fsz ((itype##_t)x, &env->vfp.fp_status); \ - return float##fsz##_scalbn(tmp, -(int)shift, &env->vfp.fp_status); \ + tmp = sign##int32_to_##float##fsz((itype##_t)x, fpst); \ + return float##fsz##_scalbn(tmp, -(int)shift, fpst); \ } \ -uint##fsz##_t VFP_HELPER(to##name, p)(float##fsz x, uint32_t shift, \ - CPUState *env) \ +uint##fsz##_t HELPER(vfp_to##name##p)(float##fsz x, uint32_t shift, \ + void *fpstp) \ { \ + float_status *fpst = fpstp; \ float##fsz tmp; \ if (float##fsz##_is_any_nan(x)) { \ - float_raise(float_flag_invalid, &env->vfp.fp_status); \ + float_raise(float_flag_invalid, fpst); \ return 0; \ } \ - tmp = float##fsz##_scalbn(x, shift, &env->vfp.fp_status); \ - return float##fsz##_to_##itype##_round_to_zero(tmp, &env->vfp.fp_status); \ + tmp = float##fsz##_scalbn(x, shift, fpst); \ + return float##fsz##_to_##itype##_round_to_zero(tmp, fpst); \ } VFP_CONV_FIX(sh, d, 64, int16, ) |