target/arm: Split out flags setting from vfp compares

Minimize the code within a macro by splitting out a helper function.
Use deposit32 instead of manual bit manipulation.

Backports commit 55a889456ef78f3f9b8eae9846c2f1453b1dd77b from qemu
This commit is contained in:
Richard Henderson 2019-02-15 17:59:32 -05:00 committed by Lioncash
parent 4e44043956
commit ca4bb1b4bc
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7

View File

@ -11945,31 +11945,40 @@ float64 VFP_HELPER(sqrt, d)(float64 a, CPUARMState *env)
return float64_sqrt(a, &env->vfp.fp_status);
}
static void softfloat_to_vfp_compare(CPUARMState *env, int cmp)
{
uint32_t flags;
switch (cmp) {
case float_relation_equal:
flags = 0x6;
break;
case float_relation_less:
flags = 0x8;
break;
case float_relation_greater:
flags = 0x2;
break;
case float_relation_unordered:
flags = 0x3;
break;
default:
g_assert_not_reached();
}
env->vfp.xregs[ARM_VFP_FPSCR] =
deposit32(env->vfp.xregs[ARM_VFP_FPSCR], 28, 4, flags);
}
/* XXX: check quiet/signaling case */
#define DO_VFP_cmp(p, type) \
void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \
{ \
uint32_t flags; \
switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
case 0: flags = 0x6; break; \
case -1: flags = 0x8; break; \
case 1: flags = 0x2; break; \
default: case 2: flags = 0x3; break; \
} \
env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
| (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
softfloat_to_vfp_compare(env, \
type ## _compare_quiet(a, b, &env->vfp.fp_status)); \
} \
void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \
{ \
uint32_t flags; \
switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
case 0: flags = 0x6; break; \
case -1: flags = 0x8; break; \
case 1: flags = 0x2; break; \
default: case 2: flags = 0x3; break; \
} \
env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
| (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
softfloat_to_vfp_compare(env, \
type ## _compare(a, b, &env->vfp.fp_status)); \
}
DO_VFP_cmp(s, float32)
DO_VFP_cmp(d, float64)