On Tue, Apr 03, 2007 at 02:12:14AM +0200, Aurelien Jarno wrote: > Hi, > > The current emulated SPARC FPU does not support deferred trap-queue. In > such cases the STDFQ instruction should generate an fp_exception trap > with the FTT field to sequence_error instead of the current > illegal_instruction trap. > > The attached patch fixes that. It also ensures that the qne bit of the > FSR register is always zero, ie that there is no deferred trap-queue > pending. >
I have just remarked that my patch breaks the user mode. Please find attached a new one to fix this problem. Bye, Aurelien -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [EMAIL PROTECTED] | [EMAIL PROTECTED] `- people.debian.org/~aurel32 | www.aurel32.net
diff -u -d -p -r1.32 cpu.h --- qemu.orig/target-sparc/cpu.h 1 Apr 2007 15:15:36 -0000 1.32 +++ qemu/target-sparc/cpu.h 5 Apr 2007 17:36:19 -0000 @@ -127,6 +127,7 @@ #define FSR_FTT_MASK (FSR_FTT2 | FSR_FTT1 | FSR_FTT0) #define FSR_FTT_IEEE_EXCP (1 << 14) #define FSR_FTT_UNIMPFPOP (3 << 14) +#define FSR_FTT_SEQ_ERROR (4 << 14) #define FSR_FTT_INVAL_FPR (6 << 14) #define FSR_FCC1 (1<<11) @@ -239,7 +240,7 @@ typedef struct CPUSPARCState { #else #define GET_FSR32(env) (env->fsr) #define PUT_FSR32(env, val) do { uint32_t _tmp = val; \ - env->fsr = (_tmp & 0xcfc1ffff) | (env->fsr & 0x000e0000); \ + env->fsr = (_tmp & 0xcfc1dfff) | (env->fsr & 0x000e0000); \ } while (0) #endif diff -u -d -p -r1.44 translate.c --- qemu.orig/target-sparc/translate.c 1 Apr 2007 16:23:36 -0000 1.44 +++ qemu/target-sparc/translate.c 5 Apr 2007 17:36:19 -0000 @@ -2602,8 +2602,14 @@ static void disas_sparc_insn(DisasContex gen_op_stfsr(); gen_op_ldst(stf); break; +#if !defined(CONFIG_USER_ONLY) case 0x26: /* stdfq */ - goto nfpu_insn; + if (!supervisor(dc)) + goto priv_insn; + if (gen_trap_ifnofpu(dc)) + goto jmp_insn; + goto nfq_insn; +#endif case 0x27: gen_op_load_fpr_DT0(DFPREG(rd)); gen_op_ldst(stdf); @@ -2665,6 +2671,11 @@ static void disas_sparc_insn(DisasContex gen_op_exception(TT_PRIV_INSN); dc->is_br = 1; return; + nfq_insn: + save_state(dc); + gen_op_fpexception_im(FSR_FTT_SEQ_ERROR); + dc->is_br = 1; + return; #endif nfpu_insn: save_state(dc);