target-sparc: Use cpu_loop_exit_restore from helper_check_ieee_exceptions
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>
This commit is contained in:
		
							parent
							
								
									ba2397d1ca
								
							
						
					
					
						commit
						02c79d7885
					
				| 
						 | 
					@ -19,12 +19,13 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "qemu/osdep.h"
 | 
					#include "qemu/osdep.h"
 | 
				
			||||||
#include "cpu.h"
 | 
					#include "cpu.h"
 | 
				
			||||||
 | 
					#include "exec/exec-all.h"
 | 
				
			||||||
#include "exec/helper-proto.h"
 | 
					#include "exec/helper-proto.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define QT0 (env->qt0)
 | 
					#define QT0 (env->qt0)
 | 
				
			||||||
#define QT1 (env->qt1)
 | 
					#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 status = get_float_exception_flags(&env->fp_status);
 | 
				
			||||||
    target_ulong fsr = env->fsr;
 | 
					    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)) {
 | 
					        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
 | 
					            /* Unmasked exception, generate a trap.  Note that while
 | 
				
			||||||
               the helper is marked as NO_WG, we can get away with
 | 
					               the helper is marked as NO_WG, we can get away with
 | 
				
			||||||
               writing to cpu state along the exception path, since
 | 
					               writing to cpu state along the exception path, since
 | 
				
			||||||
               TCG generated code will never see the write.  */
 | 
					               TCG generated code will never see the write.  */
 | 
				
			||||||
            env->fsr = fsr | FSR_FTT_IEEE_EXCP;
 | 
					            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 {
 | 
					        } else {
 | 
				
			||||||
            /* Accumulate exceptions */
 | 
					            /* Accumulate exceptions */
 | 
				
			||||||
            fsr |= (fsr & FSR_CEXC_MASK) << 5;
 | 
					            fsr |= (fsr & FSR_CEXC_MASK) << 5;
 | 
				
			||||||
| 
						 | 
					@ -66,6 +70,11 @@ target_ulong helper_check_ieee_exceptions(CPUSPARCState *env)
 | 
				
			||||||
    return fsr;
 | 
					    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_HELPER(name, p) void helper_f##name##p(CPUSPARCState *env)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define F_BINOP(name)                                           \
 | 
					#define F_BINOP(name)                                           \
 | 
				
			||||||
| 
						 | 
					@ -262,7 +271,7 @@ void helper_fsqrtq(CPUSPARCState *env)
 | 
				
			||||||
            ret = glue(size, _compare_quiet)(reg1, reg2,                \
 | 
					            ret = glue(size, _compare_quiet)(reg1, reg2,                \
 | 
				
			||||||
                                             &env->fp_status);          \
 | 
					                                             &env->fp_status);          \
 | 
				
			||||||
        }                                                               \
 | 
					        }                                                               \
 | 
				
			||||||
        fsr = helper_check_ieee_exceptions(env);                        \
 | 
					        fsr = do_check_ieee_exceptions(env, GETPC());                   \
 | 
				
			||||||
        switch (ret) {                                                  \
 | 
					        switch (ret) {                                                  \
 | 
				
			||||||
        case float_relation_unordered:                                  \
 | 
					        case float_relation_unordered:                                  \
 | 
				
			||||||
            fsr |= (FSR_FCC1 | FSR_FCC0) << FS;                         \
 | 
					            fsr |= (FSR_FCC1 | FSR_FCC0) << FS;                         \
 | 
				
			||||||
| 
						 | 
					@ -293,7 +302,7 @@ void helper_fsqrtq(CPUSPARCState *env)
 | 
				
			||||||
            ret = glue(size, _compare_quiet)(src1, src2,                \
 | 
					            ret = glue(size, _compare_quiet)(src1, src2,                \
 | 
				
			||||||
                                             &env->fp_status);          \
 | 
					                                             &env->fp_status);          \
 | 
				
			||||||
        }                                                               \
 | 
					        }                                                               \
 | 
				
			||||||
        fsr = helper_check_ieee_exceptions(env);                        \
 | 
					        fsr = do_check_ieee_exceptions(env, GETPC());                   \
 | 
				
			||||||
        switch (ret) {                                                  \
 | 
					        switch (ret) {                                                  \
 | 
				
			||||||
        case float_relation_unordered:                                  \
 | 
					        case float_relation_unordered:                                  \
 | 
				
			||||||
            fsr |= (FSR_FCC1 | FSR_FCC0) << FS;                         \
 | 
					            fsr |= (FSR_FCC1 | FSR_FCC0) << FS;                         \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3464,7 +3464,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
 | 
				
			||||||
                rs1 = GET_FIELD(insn, 13, 17);
 | 
					                rs1 = GET_FIELD(insn, 13, 17);
 | 
				
			||||||
                rs2 = GET_FIELD(insn, 27, 31);
 | 
					                rs2 = GET_FIELD(insn, 27, 31);
 | 
				
			||||||
                xop = GET_FIELD(insn, 18, 26);
 | 
					                xop = GET_FIELD(insn, 18, 26);
 | 
				
			||||||
                save_state(dc);
 | 
					
 | 
				
			||||||
                switch (xop) {
 | 
					                switch (xop) {
 | 
				
			||||||
                case 0x1: /* fmovs */
 | 
					                case 0x1: /* fmovs */
 | 
				
			||||||
                    cpu_src1_32 = gen_load_fpr_F(dc, rs2);
 | 
					                    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);
 | 
					                rs1 = GET_FIELD(insn, 13, 17);
 | 
				
			||||||
                rs2 = GET_FIELD(insn, 27, 31);
 | 
					                rs2 = GET_FIELD(insn, 27, 31);
 | 
				
			||||||
                xop = GET_FIELD(insn, 18, 26);
 | 
					                xop = GET_FIELD(insn, 18, 26);
 | 
				
			||||||
                save_state(dc);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef TARGET_SPARC64
 | 
					#ifdef TARGET_SPARC64
 | 
				
			||||||
#define FMOVR(sz)                                                  \
 | 
					#define FMOVR(sz)                                                  \
 | 
				
			||||||
| 
						 | 
					@ -5276,7 +5275,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
 | 
				
			||||||
                if (gen_trap_ifnofpu(dc)) {
 | 
					                if (gen_trap_ifnofpu(dc)) {
 | 
				
			||||||
                    goto jmp_insn;
 | 
					                    goto jmp_insn;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                save_state(dc);
 | 
					 | 
				
			||||||
                switch (xop) {
 | 
					                switch (xop) {
 | 
				
			||||||
                case 0x20:      /* ldf, load fpreg */
 | 
					                case 0x20:      /* ldf, load fpreg */
 | 
				
			||||||
                    gen_address_mask(dc, cpu_addr);
 | 
					                    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)) {
 | 
					                if (gen_trap_ifnofpu(dc)) {
 | 
				
			||||||
                    goto jmp_insn;
 | 
					                    goto jmp_insn;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                save_state(dc);
 | 
					 | 
				
			||||||
                switch (xop) {
 | 
					                switch (xop) {
 | 
				
			||||||
                case 0x24: /* stf, store fpreg */
 | 
					                case 0x24: /* stf, store fpreg */
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
| 
						 | 
					@ -5449,7 +5446,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
 | 
				
			||||||
                    goto illegal_insn;
 | 
					                    goto illegal_insn;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else if (xop > 0x33 && xop < 0x3f) {
 | 
					            } else if (xop > 0x33 && xop < 0x3f) {
 | 
				
			||||||
                save_state(dc);
 | 
					 | 
				
			||||||
                switch (xop) {
 | 
					                switch (xop) {
 | 
				
			||||||
#ifdef TARGET_SPARC64
 | 
					#ifdef TARGET_SPARC64
 | 
				
			||||||
                case 0x34: /* V9 stfa */
 | 
					                case 0x34: /* V9 stfa */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue