mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
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>
This commit is contained in:
parent
36802b6b1e
commit
5500b06cb5
3 changed files with 146 additions and 194 deletions
|
@ -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 */
|
||||
|
||||
#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); \
|
||||
}
|
||||
|
||||
float64 VFP_HELPER(uito, d)(uint32_t x, CPUState *env)
|
||||
{
|
||||
return uint32_to_float64(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); \
|
||||
}
|
||||
|
||||
float32 VFP_HELPER(sito, s)(uint32_t x, CPUState *env)
|
||||
{
|
||||
return int32_to_float32(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)
|
||||
|
||||
float64 VFP_HELPER(sito, d)(uint32_t x, CPUState *env)
|
||||
{
|
||||
return int32_to_float64(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)
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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, )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue