diff options
-rw-r--r-- | target-sparc/cpu.h | 3 | ||||
-rw-r--r-- | target-sparc/translate.c | 15 |
2 files changed, 16 insertions, 2 deletions
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 3279cfdea3..7233b8b141 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -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 --git a/target-sparc/translate.c b/target-sparc/translate.c index 53a3a674c6..cb11b928f6 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -2602,8 +2602,14 @@ static void disas_sparc_insn(DisasContext * dc) 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); @@ -2675,6 +2681,13 @@ static void disas_sparc_insn(DisasContext * dc) gen_op_fpexception_im(FSR_FTT_UNIMPFPOP); dc->is_br = 1; return; +#if !defined(CONFIG_USER_ONLY) + nfq_insn: + save_state(dc); + gen_op_fpexception_im(FSR_FTT_SEQ_ERROR); + dc->is_br = 1; + return; +#endif #ifndef TARGET_SPARC64 ncp_insn: save_state(dc); |