aboutsummaryrefslogtreecommitdiffstats
path: root/target-mips/translate.c
diff options
context:
space:
mode:
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-05-18 11:55:54 +0000
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2007-05-18 11:55:54 +0000
commitfd4a04ebb220b1ada72275297fc12cb85e89bbfb (patch)
treedd328471d4edb0b260bd2c0f8d85142465fcd365 /target-mips/translate.c
parent34ae7b51f54a5d58d30e31a92f8ece02973de50b (diff)
- Move FPU exception handling into helper functions, since they are big.
- Fix FP-conditional branches. - Check FPU register mode at runtime, not translation time, as the F64 status bit can change. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2828 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-mips/translate.c')
-rw-r--r--target-mips/translate.c176
1 files changed, 75 insertions, 101 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 66e9def85..57e5777cc 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -491,7 +491,7 @@ FGEN32(gen_op_load_fpr_WTH2, gen_op_load_fpr_WTH2_fpr);
FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
#define FOP_CONDS(type, fmt) \
-static GenOpFunc1 * cond ## type ## _ ## fmt ## _table[16] = { \
+static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = { \
gen_op_cmp ## type ## _ ## fmt ## _f, \
gen_op_cmp ## type ## _ ## fmt ## _un, \
gen_op_cmp ## type ## _ ## fmt ## _eq, \
@@ -511,7 +511,7 @@ static GenOpFunc1 * cond ## type ## _ ## fmt ## _table[16] = { \
}; \
static inline void gen_cmp ## type ## _ ## fmt(int n, long cc) \
{ \
- cond ## type ## _ ## fmt ## _table[n](cc); \
+ gen_op_cmp ## type ## _ ## fmt ## _table[n](cc); \
}
FOP_CONDS(, d)
@@ -525,11 +525,10 @@ typedef struct DisasContext {
struct TranslationBlock *tb;
target_ulong pc, saved_pc;
uint32_t opcode;
- uint32_t fp_status, saved_fp_status;
+ uint32_t fp_status;
/* Routine used to access memory */
int mem_idx;
uint32_t hflags, saved_hflags;
- uint32_t CP0_Status;
int bstate;
target_ulong btarget;
} DisasContext;
@@ -628,11 +627,21 @@ static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
}
}
-static inline void save_fpu_state (DisasContext *ctx)
+static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
{
- if (ctx->fp_status != ctx->saved_fp_status) {
- gen_op_save_fp_status(ctx->fp_status);
- ctx->saved_fp_status = ctx->fp_status;
+ ctx->saved_hflags = ctx->hflags;
+ switch (ctx->hflags & MIPS_HFLAG_BMASK) {
+ case MIPS_HFLAG_BR:
+ gen_op_restore_breg_target();
+ break;
+ case MIPS_HFLAG_B:
+ ctx->btarget = env->btarget;
+ break;
+ case MIPS_HFLAG_BC:
+ case MIPS_HFLAG_BL:
+ ctx->btarget = env->btarget;
+ gen_op_restore_bcond();
+ break;
}
}
@@ -4293,20 +4302,20 @@ static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
gen_op_save_bcond();
break;
case OPC_BC1FANY2:
- gen_op_bc1fany2(cc);
- opn = "bc1fany2";
+ gen_op_bc1any2f(cc);
+ opn = "bc1any2f";
goto not_likely;
case OPC_BC1TANY2:
- gen_op_bc1tany2(cc);
- opn = "bc1tany2";
+ gen_op_bc1any2t(cc);
+ opn = "bc1any2t";
goto not_likely;
case OPC_BC1FANY4:
- gen_op_bc1fany4(cc);
- opn = "bc1fany4";
+ gen_op_bc1any4f(cc);
+ opn = "bc1any4f";
goto not_likely;
case OPC_BC1TANY4:
- gen_op_bc1tany4(cc);
- opn = "bc1tany4";
+ gen_op_bc1any4t(cc);
+ opn = "bc1any4t";
not_likely:
ctx->hflags |= MIPS_HFLAG_BC;
gen_op_set_bcond();
@@ -4323,27 +4332,6 @@ static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
/* Coprocessor 1 (FPU) */
-/* verify if floating point register is valid; an operation is not defined
- * if bit 0 of any register specification is set and the FR bit in the
- * Status register equals zero, since the register numbers specify an
- * even-odd pair of adjacent coprocessor general registers. When the FR bit
- * in the Status register equals one, both even and odd register numbers
- * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
- *
- * Multiple 64 bit wide registers can be checked by calling
- * CHECK_FR(ctx, freg1 | freg2 | ... | fregN);
- *
- * FIXME: This is broken for R2, it needs to be checked at runtime, not
- * at translation time.
- */
-#define CHECK_FR(ctx, freg) do { \
- if (!((ctx)->CP0_Status & (1 << CP0St_FR)) && ((freg) & 1)) { \
- MIPS_INVAL("FPU mode"); \
- generate_exception (ctx, EXCP_RI); \
- return; \
- } \
- } while(0)
-
#define FOP(func, fmt) (((fmt) << 21) | (func))
static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
@@ -4388,14 +4376,14 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
opn = "dmtc1";
break;
case OPC_MFHC1:
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(WTH0, fs);
gen_op_mfhc1();
GEN_STORE_TN_REG(rt, T0);
opn = "mfhc1";
break;
case OPC_MTHC1:
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_REG_TN(T0, rt);
gen_op_mthc1();
GEN_STORE_FTN_FREG(fs, WTH0);
@@ -4546,28 +4534,28 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "neg.s";
break;
case FOP(8, 16):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(WT0, fs);
gen_op_float_roundl_s();
GEN_STORE_FTN_FREG(fd, DT2);
opn = "round.l.s";
break;
case FOP(9, 16):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(WT0, fs);
gen_op_float_truncl_s();
GEN_STORE_FTN_FREG(fd, DT2);
opn = "trunc.l.s";
break;
case FOP(10, 16):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(WT0, fs);
gen_op_float_ceill_s();
GEN_STORE_FTN_FREG(fd, DT2);
opn = "ceil.l.s";
break;
case FOP(11, 16):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(WT0, fs);
gen_op_float_floorl_s();
GEN_STORE_FTN_FREG(fd, DT2);
@@ -4622,7 +4610,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "movn.s";
break;
case FOP(33, 16):
- CHECK_FR(ctx, fd);
+ gen_op_cp1_registers(fd);
GEN_LOAD_FREG_FTN(WT0, fs);
gen_op_float_cvtd_s();
GEN_STORE_FTN_FREG(fd, DT2);
@@ -4635,14 +4623,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "cvt.w.s";
break;
case FOP(37, 16):
- CHECK_FR(ctx, fs | fd);
+ gen_op_cp1_registers(fs | fd);
GEN_LOAD_FREG_FTN(WT0, fs);
gen_op_float_cvtl_s();
GEN_STORE_FTN_FREG(fd, DT2);
opn = "cvt.l.s";
break;
case FOP(38, 16):
- CHECK_FR(ctx, fs | ft | fd);
+ gen_op_cp1_registers(fs | ft | fd);
GEN_LOAD_FREG_FTN(WT1, fs);
GEN_LOAD_FREG_FTN(WT0, ft);
gen_op_float_cvtps_s();
@@ -4676,7 +4664,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
}
break;
case FOP(0, 17):
- CHECK_FR(ctx, fs | ft | fd);
+ gen_op_cp1_registers(fs | ft | fd);
GEN_LOAD_FREG_FTN(DT0, fs);
GEN_LOAD_FREG_FTN(DT1, ft);
gen_op_float_add_d();
@@ -4685,7 +4673,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
optype = BINOP;
break;
case FOP(1, 17):
- CHECK_FR(ctx, fs | ft | fd);
+ gen_op_cp1_registers(fs | ft | fd);
GEN_LOAD_FREG_FTN(DT0, fs);
GEN_LOAD_FREG_FTN(DT1, ft);
gen_op_float_sub_d();
@@ -4694,7 +4682,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
optype = BINOP;
break;
case FOP(2, 17):
- CHECK_FR(ctx, fs | ft | fd);
+ gen_op_cp1_registers(fs | ft | fd);
GEN_LOAD_FREG_FTN(DT0, fs);
GEN_LOAD_FREG_FTN(DT1, ft);
gen_op_float_mul_d();
@@ -4703,7 +4691,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
optype = BINOP;
break;
case FOP(3, 17):
- CHECK_FR(ctx, fs | ft | fd);
+ gen_op_cp1_registers(fs | ft | fd);
GEN_LOAD_FREG_FTN(DT0, fs);
GEN_LOAD_FREG_FTN(DT1, ft);
gen_op_float_div_d();
@@ -4712,84 +4700,84 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
optype = BINOP;
break;
case FOP(4, 17):
- CHECK_FR(ctx, fs | fd);
+ gen_op_cp1_registers(fs | fd);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_sqrt_d();
GEN_STORE_FTN_FREG(fd, DT2);
opn = "sqrt.d";
break;
case FOP(5, 17):
- CHECK_FR(ctx, fs | fd);
+ gen_op_cp1_registers(fs | fd);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_abs_d();
GEN_STORE_FTN_FREG(fd, DT2);
opn = "abs.d";
break;
case FOP(6, 17):
- CHECK_FR(ctx, fs | fd);
+ gen_op_cp1_registers(fs | fd);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_mov_d();
GEN_STORE_FTN_FREG(fd, DT2);
opn = "mov.d";
break;
case FOP(7, 17):
- CHECK_FR(ctx, fs | fd);
+ gen_op_cp1_registers(fs | fd);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_chs_d();
GEN_STORE_FTN_FREG(fd, DT2);
opn = "neg.d";
break;
case FOP(8, 17):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_roundl_d();
GEN_STORE_FTN_FREG(fd, DT2);
opn = "round.l.d";
break;
case FOP(9, 17):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_truncl_d();
GEN_STORE_FTN_FREG(fd, DT2);
opn = "trunc.l.d";
break;
case FOP(10, 17):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_ceill_d();
GEN_STORE_FTN_FREG(fd, DT2);
opn = "ceil.l.d";
break;
case FOP(11, 17):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_floorl_d();
GEN_STORE_FTN_FREG(fd, DT2);
opn = "floor.l.d";
break;
case FOP(12, 17):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_roundw_d();
GEN_STORE_FTN_FREG(fd, WT2);
opn = "round.w.d";
break;
case FOP(13, 17):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_truncw_d();
GEN_STORE_FTN_FREG(fd, WT2);
opn = "trunc.w.d";
break;
case FOP(14, 17):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_ceilw_d();
GEN_STORE_FTN_FREG(fd, WT2);
opn = "ceil.w.d";
break;
case FOP(15, 17):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_floorw_d();
GEN_STORE_FTN_FREG(fd, WT2);
@@ -4835,7 +4823,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
case FOP(61, 17):
case FOP(62, 17):
case FOP(63, 17):
- CHECK_FR(ctx, fs | ft);
+ gen_op_cp1_registers(fs | ft);
GEN_LOAD_FREG_FTN(DT0, fs);
GEN_LOAD_FREG_FTN(DT1, ft);
if (ctx->opcode & (1 << 6)) {
@@ -4847,21 +4835,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
}
break;
case FOP(32, 17):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_cvts_d();
GEN_STORE_FTN_FREG(fd, WT2);
opn = "cvt.s.d";
break;
case FOP(36, 17):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_cvtw_d();
GEN_STORE_FTN_FREG(fd, WT2);
opn = "cvt.w.d";
break;
case FOP(37, 17):
- CHECK_FR(ctx, fs | fd);
+ gen_op_cp1_registers(fs | fd);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_cvtl_d();
GEN_STORE_FTN_FREG(fd, DT2);
@@ -4874,21 +4862,21 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "cvt.s.w";
break;
case FOP(33, 20):
- CHECK_FR(ctx, fd);
+ gen_op_cp1_registers(fd);
GEN_LOAD_FREG_FTN(WT0, fs);
gen_op_float_cvtd_w();
GEN_STORE_FTN_FREG(fd, DT2);
opn = "cvt.d.w";
break;
case FOP(32, 21):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_cvts_l();
GEN_STORE_FTN_FREG(fd, WT2);
opn = "cvt.s.l";
break;
case FOP(33, 21):
- CHECK_FR(ctx, fs | fd);
+ gen_op_cp1_registers(fs | fd);
GEN_LOAD_FREG_FTN(DT0, fs);
gen_op_float_cvtd_l();
GEN_STORE_FTN_FREG(fd, DT2);
@@ -4896,7 +4884,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
break;
case FOP(38, 20):
case FOP(38, 21):
- CHECK_FR(ctx, fs | fd);
+ gen_op_cp1_registers(fs | fd);
GEN_LOAD_FREG_FTN(WT0, fs);
GEN_LOAD_FREG_FTN(WTH0, fs);
gen_op_float_cvtps_pw();
@@ -4905,7 +4893,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "cvt.ps.pw";
break;
case FOP(0, 22):
- CHECK_FR(ctx, fs | ft | fd);
+ gen_op_cp1_registers(fs | ft | fd);
GEN_LOAD_FREG_FTN(WT0, fs);
GEN_LOAD_FREG_FTN(WTH0, fs);
GEN_LOAD_FREG_FTN(WT1, ft);
@@ -4916,7 +4904,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "add.ps";
break;
case FOP(1, 22):
- CHECK_FR(ctx, fs | ft | fd);
+ gen_op_cp1_registers(fs | ft | fd);
GEN_LOAD_FREG_FTN(WT0, fs);
GEN_LOAD_FREG_FTN(WTH0, fs);
GEN_LOAD_FREG_FTN(WT1, ft);
@@ -4927,7 +4915,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "sub.ps";
break;
case FOP(2, 22):
- CHECK_FR(ctx, fs | ft | fd);
+ gen_op_cp1_registers(fs | ft | fd);
GEN_LOAD_FREG_FTN(WT0, fs);
GEN_LOAD_FREG_FTN(WTH0, fs);
GEN_LOAD_FREG_FTN(WT1, ft);
@@ -4938,7 +4926,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "mul.ps";
break;
case FOP(5, 22):
- CHECK_FR(ctx, fs | fd);
+ gen_op_cp1_registers(fs | fd);
GEN_LOAD_FREG_FTN(WT0, fs);
GEN_LOAD_FREG_FTN(WTH0, fs);
gen_op_float_abs_ps();
@@ -4947,7 +4935,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "abs.ps";
break;
case FOP(6, 22):
- CHECK_FR(ctx, fs | fd);
+ gen_op_cp1_registers(fs | fd);
GEN_LOAD_FREG_FTN(WT0, fs);
GEN_LOAD_FREG_FTN(WTH0, fs);
gen_op_float_mov_ps();
@@ -4956,7 +4944,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "mov.ps";
break;
case FOP(7, 22):
- CHECK_FR(ctx, fs | fd);
+ gen_op_cp1_registers(fs | fd);
GEN_LOAD_FREG_FTN(WT0, fs);
GEN_LOAD_FREG_FTN(WTH0, fs);
gen_op_float_chs_ps();
@@ -4998,7 +4986,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "movn.ps";
break;
case FOP(24, 22):
- CHECK_FR(ctx, fs | fd | ft);
+ gen_op_cp1_registers(fs | fd | ft);
GEN_LOAD_FREG_FTN(WT0, fs);
GEN_LOAD_FREG_FTN(WTH0, fs);
GEN_LOAD_FREG_FTN(WT1, ft);
@@ -5009,14 +4997,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "addr.ps";
break;
case FOP(32, 22):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(WTH0, fs);
gen_op_float_cvts_pu();
GEN_STORE_FTN_FREG(fd, WT2);
opn = "cvt.s.pu";
break;
case FOP(36, 22):
- CHECK_FR(ctx, fs | fd);
+ gen_op_cp1_registers(fs | fd);
GEN_LOAD_FREG_FTN(WT0, fs);
GEN_LOAD_FREG_FTN(WTH0, fs);
gen_op_float_cvtpw_ps();
@@ -5025,14 +5013,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "cvt.pw.ps";
break;
case FOP(40, 22):
- CHECK_FR(ctx, fs);
+ gen_op_cp1_registers(fs);
GEN_LOAD_FREG_FTN(WT0, fs);
gen_op_float_cvts_pl();
GEN_STORE_FTN_FREG(fd, WT2);
opn = "cvt.s.pl";
break;
case FOP(44, 22):
- CHECK_FR(ctx, fs | ft | fd);
+ gen_op_cp1_registers(fs | ft | fd);
GEN_LOAD_FREG_FTN(WT0, fs);
GEN_LOAD_FREG_FTN(WT1, ft);
gen_op_float_pll_ps();
@@ -5040,7 +5028,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "pll.ps";
break;
case FOP(45, 22):
- CHECK_FR(ctx, fs | ft | fd);
+ gen_op_cp1_registers(fs | ft | fd);
GEN_LOAD_FREG_FTN(WT0, fs);
GEN_LOAD_FREG_FTN(WTH1, ft);
gen_op_float_plu_ps();
@@ -5048,7 +5036,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "plu.ps";
break;
case FOP(46, 22):
- CHECK_FR(ctx, fs | ft | fd);
+ gen_op_cp1_registers(fs | ft | fd);
GEN_LOAD_FREG_FTN(WTH0, fs);
GEN_LOAD_FREG_FTN(WT1, ft);
gen_op_float_pul_ps();
@@ -5056,7 +5044,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
opn = "pul.ps";
break;
case FOP(47, 22):
- CHECK_FR(ctx, fs | ft | fd);
+ gen_op_cp1_registers(fs | ft | fd);
GEN_LOAD_FREG_FTN(WTH0, fs);
GEN_LOAD_FREG_FTN(WTH1, ft);
gen_op_float_puu_ps();
@@ -5079,7 +5067,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
case FOP(61, 22):
case FOP(62, 22):
case FOP(63, 22):
- CHECK_FR(ctx, fs | ft);
+ gen_op_cp1_registers(fs | ft);
GEN_LOAD_FREG_FTN(WT0, fs);
GEN_LOAD_FREG_FTN(WTH0, fs);
GEN_LOAD_FREG_FTN(WT1, ft);
@@ -5166,7 +5154,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
const char *opn = "flt3_arith";
/* All of those work only on 64bit FPUs. */
- CHECK_FR(ctx, fd | fr | fs | ft);
+ gen_op_cp1_registers(fd | fr | fs | ft);
switch (opc) {
case OPC_ALNV_PS:
GEN_LOAD_REG_TN(T0, fr);
@@ -5874,26 +5862,12 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
ctx.bstate = BS_NONE;
/* Restore delay slot state from the tb context. */
ctx.hflags = tb->flags;
- ctx.saved_hflags = ctx.hflags;
- switch (ctx.hflags & MIPS_HFLAG_BMASK) {
- case MIPS_HFLAG_BR:
- gen_op_restore_breg_target();
- break;
- case MIPS_HFLAG_B:
- ctx.btarget = env->btarget;
- break;
- case MIPS_HFLAG_BC:
- case MIPS_HFLAG_BL:
- ctx.btarget = env->btarget;
- gen_op_restore_bcond();
- break;
- }
+ restore_cpu_state(env, &ctx);
#if defined(CONFIG_USER_ONLY)
ctx.mem_idx = 0;
#else
ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
#endif
- ctx.CP0_Status = env->CP0_Status;
#ifdef DEBUG_DISAS
if (loglevel & CPU_LOG_TB_CPU) {
fprintf(logfile, "------------------------------------------------\n");