aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--target-sparc/cpu.h3
-rw-r--r--target-sparc/translate.c15
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);