Skip to content

Commit

Permalink
target/microblaze: Store "current" iflags in insn_start
Browse files Browse the repository at this point in the history
This data is available during exception unwinding, thus
we can restore it from there directly, rather than saving
it during the TB.  Thus we may remove the t_sync_flags()
calls in the load/store operations.

Note that these calls were missing from the other places
where runtime exceptions may be raised, such as idiv and
the floating point operations.

Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
rth7680 committed Sep 1, 2020
1 parent 5318223 commit 683a247
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 11 deletions.
2 changes: 2 additions & 0 deletions target/microblaze/cpu.h
Expand Up @@ -228,6 +228,8 @@ typedef struct CPUMBState CPUMBState;
#define STREAM_CONTROL (1 << 3)
#define STREAM_NONBLOCK (1 << 4)

#define TARGET_INSN_START_EXTRA_WORDS 1

struct CPUMBState {
uint32_t btaken;
uint32_t btarget;
Expand Down
24 changes: 13 additions & 11 deletions target/microblaze/translate.c
Expand Up @@ -58,6 +58,9 @@ typedef struct DisasContext {
DisasContextBase base;
MicroBlazeCPU *cpu;

/* TCG op of the current insn_start. */
TCGOp *insn_start;

TCGv_i32 r0;
bool r0_set;

Expand All @@ -71,7 +74,7 @@ typedef struct DisasContext {

unsigned int cpustate_changed;
unsigned int delayed_branch;
unsigned int tb_flags, synced_flags; /* tb dependent flags. */
unsigned int tb_flags;
unsigned int clear_imm;
int mem_index;

Expand All @@ -96,12 +99,11 @@ static int typeb_imm(DisasContext *dc, int x)
/* Include the auto-generated decoder. */
#include "decode-insns.c.inc"

static inline void t_sync_flags(DisasContext *dc)
static void t_sync_flags(DisasContext *dc)
{
/* Synch the tb dependent flags between translator and runtime. */
if (dc->tb_flags != dc->synced_flags) {
tcg_gen_movi_i32(cpu_iflags, dc->tb_flags);
dc->synced_flags = dc->tb_flags;
if ((dc->tb_flags ^ dc->base.tb->flags) & ~MSR_TB_MASK) {
tcg_gen_movi_i32(cpu_iflags, dc->tb_flags & ~MSR_TB_MASK);
}
}

Expand Down Expand Up @@ -770,7 +772,6 @@ static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop,
}
}

t_sync_flags(dc);
sync_jmpstate(dc);

/*
Expand Down Expand Up @@ -893,7 +894,6 @@ static bool trans_lwx(DisasContext *dc, arg_typea *arg)
/* lwx does not throw unaligned access errors, so force alignment */
tcg_gen_andi_tl(addr, addr, ~3);

t_sync_flags(dc);
sync_jmpstate(dc);

tcg_gen_qemu_ld_i32(cpu_res_val, addr, dc->mem_index, MO_TEUL);
Expand Down Expand Up @@ -929,7 +929,6 @@ static bool do_store(DisasContext *dc, int rd, TCGv addr, MemOp mop,
}
}

t_sync_flags(dc);
sync_jmpstate(dc);

tcg_gen_qemu_st_i32(reg_for_read(dc, rd), addr, mem_index, mop);
Expand Down Expand Up @@ -1046,7 +1045,6 @@ static bool trans_swx(DisasContext *dc, arg_typea *arg)
TCGLabel *swx_fail = gen_new_label();
TCGv_i32 tval;

t_sync_flags(dc);
sync_jmpstate(dc);

/* swx does not throw unaligned access errors, so force alignment */
Expand Down Expand Up @@ -1655,7 +1653,7 @@ static void mb_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
int bound;

dc->cpu = cpu;
dc->synced_flags = dc->tb_flags = dc->base.tb->flags;
dc->tb_flags = dc->base.tb->flags;
dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
dc->jmp = dc->delayed_branch ? JMP_INDIRECT : JMP_NOJMP;
dc->cpustate_changed = 0;
Expand All @@ -1675,7 +1673,10 @@ static void mb_tr_tb_start(DisasContextBase *dcb, CPUState *cs)

static void mb_tr_insn_start(DisasContextBase *dcb, CPUState *cs)
{
tcg_gen_insn_start(dcb->pc_next);
DisasContext *dc = container_of(dcb, DisasContext, base);

tcg_gen_insn_start(dc->base.pc_next, dc->tb_flags & ~MSR_TB_MASK);
dc->insn_start = tcg_last_op();
}

static bool mb_tr_breakpoint_check(DisasContextBase *dcb, CPUState *cs,
Expand Down Expand Up @@ -1917,4 +1918,5 @@ void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb,
target_ulong *data)
{
env->pc = data[0];
env->iflags = data[1];
}

0 comments on commit 683a247

Please sign in to comment.