target-sparc: Use cpu_loop_exit_restore from helper_check_ieee_exceptions
authorRichard Henderson <rth@twiddle.net>
Wed, 9 Sep 2015 18:34:28 +0000 (11:34 -0700)
committerRichard Henderson <rth@twiddle.net>
Tue, 12 Jul 2016 18:02:58 +0000 (11:02 -0700)
This avoids needing to save state before every FP operation.

Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Richard Henderson <rth@twiddle.net>
target-sparc/fop_helper.c
target-sparc/translate.c

index cdc58ea7a6fe9e72a12110e03345edf8b80e58c6..c7fb176e4c5ef1dc9d6a9383e99f3ba209f2454f 100644 (file)
 
 #include "qemu/osdep.h"
 #include "cpu.h"
+#include "exec/exec-all.h"
 #include "exec/helper-proto.h"
 
 #define QT0 (env->qt0)
 #define QT1 (env->qt1)
 
-target_ulong helper_check_ieee_exceptions(CPUSPARCState *env)
+static target_ulong do_check_ieee_exceptions(CPUSPARCState *env, uintptr_t ra)
 {
     target_ulong status = get_float_exception_flags(&env->fp_status);
     target_ulong fsr = env->fsr;
@@ -51,12 +52,15 @@ target_ulong helper_check_ieee_exceptions(CPUSPARCState *env)
         }
 
         if ((fsr & FSR_CEXC_MASK) & ((fsr & FSR_TEM_MASK) >> 23)) {
+            CPUState *cs = CPU(sparc_env_get_cpu(env));
+
             /* Unmasked exception, generate a trap.  Note that while
                the helper is marked as NO_WG, we can get away with
                writing to cpu state along the exception path, since
                TCG generated code will never see the write.  */
             env->fsr = fsr | FSR_FTT_IEEE_EXCP;
-            helper_raise_exception(env, TT_FP_EXCP);
+            cs->exception_index = TT_FP_EXCP;
+            cpu_loop_exit_restore(cs, ra);
         } else {
             /* Accumulate exceptions */
             fsr |= (fsr & FSR_CEXC_MASK) << 5;
@@ -66,6 +70,11 @@ target_ulong helper_check_ieee_exceptions(CPUSPARCState *env)
     return fsr;
 }
 
+target_ulong helper_check_ieee_exceptions(CPUSPARCState *env)
+{
+    return do_check_ieee_exceptions(env, GETPC());
+}
+
 #define F_HELPER(name, p) void helper_f##name##p(CPUSPARCState *env)
 
 #define F_BINOP(name)                                           \
@@ -262,7 +271,7 @@ void helper_fsqrtq(CPUSPARCState *env)
             ret = glue(size, _compare_quiet)(reg1, reg2,                \
                                              &env->fp_status);          \
         }                                                               \
-        fsr = helper_check_ieee_exceptions(env);                        \
+        fsr = do_check_ieee_exceptions(env, GETPC());                   \
         switch (ret) {                                                  \
         case float_relation_unordered:                                  \
             fsr |= (FSR_FCC1 | FSR_FCC0) << FS;                         \
@@ -293,7 +302,7 @@ void helper_fsqrtq(CPUSPARCState *env)
             ret = glue(size, _compare_quiet)(src1, src2,                \
                                              &env->fp_status);          \
         }                                                               \
-        fsr = helper_check_ieee_exceptions(env);                        \
+        fsr = do_check_ieee_exceptions(env, GETPC());                   \
         switch (ret) {                                                  \
         case float_relation_unordered:                                  \
             fsr |= (FSR_FCC1 | FSR_FCC0) << FS;                         \
index dea1b5f8e3c0c8e52e007d58f15a901f3847b17e..590a58df94729f9c0e92e9a0ef51b0e436028e34 100644 (file)
@@ -3464,7 +3464,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 rs1 = GET_FIELD(insn, 13, 17);
                 rs2 = GET_FIELD(insn, 27, 31);
                 xop = GET_FIELD(insn, 18, 26);
-                save_state(dc);
+
                 switch (xop) {
                 case 0x1: /* fmovs */
                     cpu_src1_32 = gen_load_fpr_F(dc, rs2);
@@ -3639,7 +3639,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 rs1 = GET_FIELD(insn, 13, 17);
                 rs2 = GET_FIELD(insn, 27, 31);
                 xop = GET_FIELD(insn, 18, 26);
-                save_state(dc);
 
 #ifdef TARGET_SPARC64
 #define FMOVR(sz)                                                  \
@@ -5276,7 +5275,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 if (gen_trap_ifnofpu(dc)) {
                     goto jmp_insn;
                 }
-                save_state(dc);
                 switch (xop) {
                 case 0x20:      /* ldf, load fpreg */
                     gen_address_mask(dc, cpu_addr);
@@ -5390,7 +5388,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 if (gen_trap_ifnofpu(dc)) {
                     goto jmp_insn;
                 }
-                save_state(dc);
                 switch (xop) {
                 case 0x24: /* stf, store fpreg */
                     {
@@ -5449,7 +5446,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     goto illegal_insn;
                 }
             } else if (xop > 0x33 && xop < 0x3f) {
-                save_state(dc);
                 switch (xop) {
 #ifdef TARGET_SPARC64
                 case 0x34: /* V9 stfa */