VROUND, FSTCW and STMXCSR all have to perform the same conversion from
x86 rounding modes to softfloat constants. Since the ISA is consistent
on the meaning of the two-bit rounding modes, extract the common code
into a wrapper for set_float_rounding_mode.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/ops_sse.h | 60 +++---------------------------------
target/i386/tcg/fpu_helper.c | 60 +++++++++++++-----------------------
2 files changed, 25 insertions(+), 95 deletions(-)
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index a6a90a1817..6f3741b635 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -32,7 +32,8 @@
#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d)
#define ST1 ST(1)
-#define FPU_RC_MASK 0xc00
+#define FPU_RC_SHIFT 10
+#define FPU_RC_MASK (3 << FPU_RC_SHIFT)
#define FPU_RC_NEAR 0x000
#define FPU_RC_DOWN 0x400
#define FPU_RC_UP 0x800
@@ -685,28 +686,26 @@ uint32_t helper_fnstcw(CPUX86State *env)
return env->fpuc;
}
+static void set_x86_rounding_mode(unsigned mode, float_status *status)
+{
+ static FloatRoundMode x86_round_mode[4] = {
+ float_round_nearest_even,
+ float_round_down,
+ float_round_up,
+ float_round_to_zero
+ };
+ assert(mode < ARRAY_SIZE(x86_round_mode));
+ set_float_rounding_mode(x86_round_mode[mode], status);
+}