aboutsummaryrefslogtreecommitdiff
path: root/target/sparc/fop_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/sparc/fop_helper.c')
-rw-r--r--target/sparc/fop_helper.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/target/sparc/fop_helper.c b/target/sparc/fop_helper.c
index 0b30665..29fd166 100644
--- a/target/sparc/fop_helper.c
+++ b/target/sparc/fop_helper.c
@@ -19,7 +19,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
-#include "exec/exec-all.h"
#include "exec/helper-proto.h"
#include "fpu/softfloat.h"
@@ -344,17 +343,17 @@ Int128 helper_fsqrtq(CPUSPARCState *env, Int128 src)
}
float32 helper_fmadds(CPUSPARCState *env, float32 s1,
- float32 s2, float32 s3, uint32_t op)
+ float32 s2, float32 s3, int32_t sc, uint32_t op)
{
- float32 ret = float32_muladd(s1, s2, s3, op, &env->fp_status);
+ float32 ret = float32_muladd_scalbn(s1, s2, s3, sc, op, &env->fp_status);
check_ieee_exceptions(env, GETPC());
return ret;
}
float64 helper_fmaddd(CPUSPARCState *env, float64 s1,
- float64 s2, float64 s3, uint32_t op)
+ float64 s2, float64 s3, int32_t sc, uint32_t op)
{
- float64 ret = float64_muladd(s1, s2, s3, op, &env->fp_status);
+ float64 ret = float64_muladd_scalbn(s1, s2, s3, sc, op, &env->fp_status);
check_ieee_exceptions(env, GETPC());
return ret;
}
@@ -446,7 +445,6 @@ static uint32_t finish_fcmp(CPUSPARCState *env, FloatRelation r, uintptr_t ra)
case float_relation_greater:
return 2;
case float_relation_unordered:
- env->fsr |= FSR_NVA;
return 3;
}
g_assert_not_reached();
@@ -490,14 +488,17 @@ uint32_t helper_fcmpeq(CPUSPARCState *env, Int128 src1, Int128 src2)
return finish_fcmp(env, r, GETPC());
}
-uint32_t helper_flcmps(float32 src1, float32 src2)
+uint32_t helper_flcmps(CPUSPARCState *env, float32 src1, float32 src2)
{
/*
* FLCMP never raises an exception nor modifies any FSR fields.
* Perform the comparison with a dummy fp environment.
*/
- float_status discard = { };
- FloatRelation r = float32_compare_quiet(src1, src2, &discard);
+ float_status discard = env->fp_status;
+ FloatRelation r;
+
+ set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
+ r = float32_compare_quiet(src1, src2, &discard);
switch (r) {
case float_relation_equal:
@@ -515,10 +516,13 @@ uint32_t helper_flcmps(float32 src1, float32 src2)
g_assert_not_reached();
}
-uint32_t helper_flcmpd(float64 src1, float64 src2)
+uint32_t helper_flcmpd(CPUSPARCState *env, float64 src1, float64 src2)
{
- float_status discard = { };
- FloatRelation r = float64_compare_quiet(src1, src2, &discard);
+ float_status discard = env->fp_status;
+ FloatRelation r;
+
+ set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
+ r = float64_compare_quiet(src1, src2, &discard);
switch (r) {
case float_relation_equal:
@@ -545,6 +549,8 @@ target_ulong cpu_get_fsr(CPUSPARCState *env)
fsr |= (uint64_t)env->fcc[1] << FSR_FCC1_SHIFT;
fsr |= (uint64_t)env->fcc[2] << FSR_FCC2_SHIFT;
fsr |= (uint64_t)env->fcc[3] << FSR_FCC3_SHIFT;
+#elif !defined(CONFIG_USER_ONLY)
+ fsr |= env->fsr_qne;
#endif
/* VER is kept completely separate until re-assembly. */
@@ -591,6 +597,8 @@ void cpu_put_fsr(CPUSPARCState *env, target_ulong fsr)
env->fcc[1] = extract64(fsr, FSR_FCC1_SHIFT, 2);
env->fcc[2] = extract64(fsr, FSR_FCC2_SHIFT, 2);
env->fcc[3] = extract64(fsr, FSR_FCC3_SHIFT, 2);
+#elif !defined(CONFIG_USER_ONLY)
+ env->fsr_qne = fsr & FSR_QNE;
#endif
set_fsr_nonsplit(env, fsr);