[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 24/25] target-openrisc: Generate goto_tb for direct
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 24/25] target-openrisc: Generate goto_tb for direct branches |
Date: |
Mon, 13 Jun 2016 16:58:24 -0700 |
Signed-off-by: Richard Henderson <address@hidden>
---
target-openrisc/translate.c | 348 ++++++++++++++++++++++----------------------
1 file changed, 173 insertions(+), 175 deletions(-)
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index cb9267d..4d29d22 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -39,14 +39,22 @@
#define LOG_DIS(str, ...) \
qemu_log_mask(OPENRISC_DISAS, "%08x: " str, dc->pc, ## __VA_ARGS__)
+typedef enum {
+ JMP_NONE,
+ JMP_EXCP,
+ JMP_VAR,
+ JMP_DIRECT,
+} JmpStatus;
+
typedef struct DisasContext {
TranslationBlock *tb;
target_ulong pc;
- uint32_t is_jmp;
uint32_t mem_idx;
uint32_t tb_flags;
- uint32_t delayed_branch;
+ bool dflag;
bool singlestep_enabled;
+ JmpStatus jmp_type;
+ target_ulong jmp_dest[2];
} DisasContext;
static TCGv_env cpu_env;
@@ -114,37 +122,33 @@ void openrisc_translate_init(void)
cpu_R0 = cpu_R[0];
}
-static void gen_exception(DisasContext *dc, unsigned int excp)
+static void gen_exception_1(unsigned int excp)
{
TCGv_i32 tmp = tcg_const_i32(excp);
gen_helper_exception(cpu_env, tmp);
tcg_temp_free_i32(tmp);
}
-static void gen_illegal_exception(DisasContext *dc)
+static JmpStatus gen_exception(DisasContext *dc, unsigned int excp)
{
tcg_gen_movi_tl(cpu_pc, dc->pc);
- gen_exception(dc, EXCP_ILLEGAL);
- dc->is_jmp = DISAS_UPDATE;
+ gen_exception_1(excp);
+ return JMP_EXCP;
}
-#define check_ob64s(dc) \
- do { \
- gen_illegal_exception(dc); \
- return; \
- } while (0)
+static JmpStatus gen_illegal_exception(DisasContext *dc)
+{
+ return gen_exception(dc, EXCP_ILLEGAL);
+}
-#define check_of64s(dc) \
- do { \
- gen_illegal_exception(dc); \
- return; \
- } while (0)
+#define check_ob64s(dc) \
+ do { return gen_illegal_exception(dc); } while (0)
-#define check_ov64s(dc) \
- do { \
- gen_illegal_exception(dc); \
- return; \
- } while (0)
+#define check_of64s(dc) \
+ do { return gen_illegal_exception(dc); } while (0)
+
+#define check_ov64s(dc) \
+ do { return gen_illegal_exception(dc); } while (0)
/* We're about to write to REG. On the off-chance that the user is
writing to R0, re-instate the architectural register. */
@@ -171,34 +175,33 @@ static inline bool use_goto_tb(DisasContext *dc,
target_ulong dest)
static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
{
if (use_goto_tb(dc, dest)) {
- tcg_gen_movi_tl(cpu_pc, dest);
tcg_gen_goto_tb(n);
+ tcg_gen_movi_tl(cpu_pc, dest);
tcg_gen_exit_tb((uintptr_t)dc->tb + n);
} else {
tcg_gen_movi_tl(cpu_pc, dest);
- if (dc->singlestep_enabled) {
- gen_exception(dc, EXCP_DEBUG);
- }
tcg_gen_exit_tb(0);
}
}
-static void gen_jump(DisasContext *dc, int32_t n26, uint32_t reg, uint32_t op0)
+static JmpStatus gen_jump(DisasContext *dc, int32_t n26,
+ uint32_t reg, uint32_t op0)
{
target_ulong tmp_pc = dc->pc + n26 * 4;
switch (op0) {
- case 0x00: /* l.j */
- tcg_gen_movi_tl(jmp_pc, tmp_pc);
- break;
case 0x01: /* l.jal */
tcg_gen_movi_tl(cpu_R[9], dc->pc + 8);
/* Optimize jal being used to load the PC for PIC. */
if (tmp_pc == dc->pc + 8) {
- return;
+ return JMP_NONE;
}
- tcg_gen_movi_tl(jmp_pc, tmp_pc);
+ /* fallthru */
+ case 0x00: /* l.j */
+ dc->jmp_dest[0] = tmp_pc;
+ dc->jmp_type = JMP_DIRECT;
break;
+
case 0x03: /* l.bnf */
case 0x04: /* l.bf */
{
@@ -212,21 +215,27 @@ static void gen_jump(DisasContext *dc, int32_t n26,
uint32_t reg, uint32_t op0)
tcg_temp_free(t_next);
tcg_temp_free(t_true);
tcg_temp_free(t_zero);
+
+ dc->jmp_type = JMP_VAR;
}
break;
+
case 0x11: /* l.jr */
tcg_gen_mov_tl(jmp_pc, cpu_R[reg]);
+ dc->jmp_type = JMP_VAR;
break;
case 0x12: /* l.jalr */
- tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8));
tcg_gen_mov_tl(jmp_pc, cpu_R[reg]);
+ tcg_gen_movi_tl(cpu_R[9], (dc->pc + 8));
+ dc->jmp_type = JMP_VAR;
break;
+
default:
- gen_illegal_exception(dc);
- break;
+ return gen_illegal_exception(dc);
}
- dc->delayed_branch = 2;
+ dc->dflag = true;
+ return JMP_NONE;
}
static void gen_ove_cy(DisasContext *dc)
@@ -509,9 +518,7 @@ static void gen_swa(DisasContext *dc, TCGv rb, TCGv ra,
int32_t ofs)
tcg_gen_st32_tl(rb, cpu_env, offsetof(CPUOpenRISCState, lock_st_value));
- tcg_gen_movi_tl(cpu_pc, dc->pc);
gen_exception(dc, EXCP_SWA);
- dc->is_jmp = DISAS_UPDATE;
#else
TCGv ea, val;
TCGLabel *lab_fail, *lab_done;
@@ -540,7 +547,7 @@ static void gen_swa(DisasContext *dc, TCGv rb, TCGv ra,
int32_t ofs)
#endif
}
-static void dec_calc(DisasContext *dc, uint32_t insn)
+static JmpStatus dec_calc(DisasContext *dc, uint32_t insn)
{
uint32_t op0, op1, op2;
uint32_t ra, rb, rd;
@@ -557,51 +564,53 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
case 0x0: /* l.add */
LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb);
gen_add(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
- return;
+ break;
case 0x1: /* l.addc */
LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb);
gen_addc(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
- return;
+ break;
case 0x2: /* l.sub */
LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb);
gen_sub(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
- return;
+ break;
case 0x3: /* l.and */
LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
- return;
+ break;
case 0x4: /* l.or */
LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
- return;
+ break;
case 0x5: /* l.xor */
LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
- return;
+ break;
case 0x8:
switch (op2) {
case 0: /* l.sll */
LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
- return;
+ break;
case 1: /* l.srl */
LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
- return;
+ break;
case 2: /* l.sra */
LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
- return;
+ break;
case 3: /* l.ror */
LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb);
tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);
- return;
+ break;
+ default:
+ return gen_illegal_exception(dc);
}
break;
@@ -610,19 +619,21 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
case 0: /* l.exths */
LOG_DIS("l.exths r%d, r%d\n", rd, ra);
tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]);
- return;
+ break;
case 1: /* l.extbs */
LOG_DIS("l.extbs r%d, r%d\n", rd, ra);
tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]);
- return;
+ break;
case 2: /* l.exthz */
LOG_DIS("l.exthz r%d, r%d\n", rd, ra);
tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]);
- return;
+ break;
case 3: /* l.extbz */
LOG_DIS("l.extbz r%d, r%d\n", rd, ra);
tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]);
- return;
+ break;
+ default:
+ return gen_illegal_exception(dc);
}
break;
@@ -631,11 +642,13 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
case 0: /* l.extws */
LOG_DIS("l.extws r%d, r%d\n", rd, ra);
tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]);
- return;
+ break;
case 1: /* l.extwz */
LOG_DIS("l.extwz r%d, r%d\n", rd, ra);
tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]);
- return;
+ break;
+ default:
+ return gen_illegal_exception(dc);
}
break;
@@ -647,12 +660,15 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
cpu_R[ra], cpu_R[rb]);
tcg_temp_free(zero);
}
- return;
+ break;
case 0xf: /* l.ff1 */
LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb);
gen_helper_ff1(cpu_R[rd], cpu_R[ra]);
- return;
+ break;
+
+ default:
+ return gen_illegal_exception(dc);
}
break;
@@ -661,19 +677,18 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
case 0xf: /* l.fl1 */
LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb);
gen_helper_fl1(cpu_R[rd], cpu_R[ra]);
- return;
+ break;
+ default:
+ return gen_illegal_exception(dc);
}
break;
- case 2:
- break;
-
case 3:
switch (op0) {
case 0x6: /* l.mul */
LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb);
gen_mul(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
- return;
+ break;
case 0x7: /* l.muld */
LOG_DIS("l.muld r%d, r%d\n", ra, rb);
@@ -683,29 +698,35 @@ static void dec_calc(DisasContext *dc, uint32_t insn)
case 0x9: /* l.div */
LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);
gen_div(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
- return;
+ break;
case 0xa: /* l.divu */
LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);
gen_divu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
- return;
+ break;
case 0xb: /* l.mulu */
LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);
gen_mulu(dc, cpu_R[rd], cpu_R[ra], cpu_R[rb]);
- return;
+ break;
case 0xc: /* l.muldu */
LOG_DIS("l.muldu r%d, r%d\n", ra, rb);
gen_muldu(dc, cpu_R[ra], cpu_R[rb]);
- return;
+ break;
+
+ default:
+ return gen_illegal_exception(dc);
}
break;
+
+ default:
+ return gen_illegal_exception(dc);
}
- gen_illegal_exception(dc);
+ return JMP_NONE;
}
-static void dec_misc(DisasContext *dc, uint32_t insn)
+static JmpStatus dec_misc(DisasContext *dc, uint32_t insn)
{
uint32_t op0, op1;
uint32_t ra, rb, rd;
@@ -761,10 +782,8 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
case 0x01: /* l.nop */
LOG_DIS("l.nop %d\n", I16);
break;
-
default:
- gen_illegal_exception(dc);
- break;
+ return gen_illegal_exception(dc);
}
break;
@@ -787,19 +806,15 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
case 0x09: /* l.rfe */
LOG_DIS("l.rfe\n");
- {
#if defined(CONFIG_USER_ONLY)
- return;
+ return gen_illegal_exception(dc);
#else
- if (dc->mem_idx == MMU_USER_IDX) {
- gen_illegal_exception(dc);
- return;
- }
- gen_helper_rfe(cpu_env);
- dc->is_jmp = DISAS_UPDATE;
-#endif
+ if (dc->mem_idx == MMU_USER_IDX) {
+ return gen_illegal_exception(dc);
}
- break;
+ gen_helper_rfe(cpu_env);
+ return JMP_VAR;
+#endif
case 0x1b: /* l.lwa */
LOG_DIS("l.lwa r%d, r%d, %d\n", rd, ra, I16);
@@ -971,12 +986,12 @@ static void dec_misc(DisasContext *dc, uint32_t insn)
break;
default:
- gen_illegal_exception(dc);
- break;
+ return gen_illegal_exception(dc);
}
+ return JMP_NONE;
}
-static void dec_mac(DisasContext *dc, uint32_t insn)
+static JmpStatus dec_mac(DisasContext *dc, uint32_t insn)
{
uint32_t op0;
uint32_t ra, rb;
@@ -1006,12 +1021,12 @@ static void dec_mac(DisasContext *dc, uint32_t insn)
break;
default:
- gen_illegal_exception(dc);
- break;
- }
+ return gen_illegal_exception(dc);
+ }
+ return JMP_NONE;
}
-static void dec_logic(DisasContext *dc, uint32_t insn)
+static JmpStatus dec_logic(DisasContext *dc, uint32_t insn)
{
uint32_t op0;
uint32_t rd, ra, L6, S6;
@@ -1044,12 +1059,12 @@ static void dec_logic(DisasContext *dc, uint32_t insn)
break;
default:
- gen_illegal_exception(dc);
- break;
+ return gen_illegal_exception(dc);
}
+ return JMP_NONE;
}
-static void dec_M(DisasContext *dc, uint32_t insn)
+static JmpStatus dec_M(DisasContext *dc, uint32_t insn)
{
uint32_t op0;
uint32_t rd;
@@ -1072,12 +1087,12 @@ static void dec_M(DisasContext *dc, uint32_t insn)
break;
default:
- gen_illegal_exception(dc);
- break;
+ return gen_illegal_exception(dc);
}
+ return JMP_NONE;
}
-static void dec_comp(DisasContext *dc, uint32_t insn)
+static JmpStatus dec_comp(DisasContext *dc, uint32_t insn)
{
uint32_t op0;
uint32_t ra, rb;
@@ -1142,12 +1157,12 @@ static void dec_comp(DisasContext *dc, uint32_t insn)
break;
default:
- gen_illegal_exception(dc);
- break;
+ return gen_illegal_exception(dc);
}
+ return JMP_NONE;
}
-static void dec_compi(DisasContext *dc, uint32_t insn)
+static JmpStatus dec_compi(DisasContext *dc, uint32_t insn)
{
uint32_t op0;
uint32_t ra;
@@ -1209,12 +1224,12 @@ static void dec_compi(DisasContext *dc, uint32_t insn)
break;
default:
- gen_illegal_exception(dc);
- break;
+ return gen_illegal_exception(dc);
}
+ return JMP_NONE;
}
-static void dec_sys(DisasContext *dc, uint32_t insn)
+static JmpStatus dec_sys(DisasContext *dc, uint32_t insn)
{
uint32_t op0;
uint32_t K16;
@@ -1225,14 +1240,11 @@ static void dec_sys(DisasContext *dc, uint32_t insn)
switch (op0) {
case 0x000: /* l.sys */
LOG_DIS("l.sys %d\n", K16);
- tcg_gen_movi_tl(cpu_pc, dc->pc);
gen_exception(dc, EXCP_SYSCALL);
- dc->is_jmp = DISAS_UPDATE;
break;
case 0x100: /* l.trap */
LOG_DIS("l.trap %d\n", K16);
- tcg_gen_movi_tl(cpu_pc, dc->pc);
gen_exception(dc, EXCP_TRAP);
break;
@@ -1249,12 +1261,12 @@ static void dec_sys(DisasContext *dc, uint32_t insn)
break;
default:
- gen_illegal_exception(dc);
- break;
+ return gen_illegal_exception(dc);
}
+ return JMP_NONE;
}
-static void dec_float(DisasContext *dc, uint32_t insn)
+static JmpStatus dec_float(DisasContext *dc, uint32_t insn)
{
uint32_t op0;
uint32_t ra, rb, rd;
@@ -1469,12 +1481,12 @@ static void dec_float(DisasContext *dc, uint32_t insn)
#endif
default:
- gen_illegal_exception(dc);
- break;
+ return gen_illegal_exception(dc);
}
+ return JMP_NONE;
}
-static void disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu)
+static JmpStatus disas_openrisc_insn(DisasContext *dc, OpenRISCCPU *cpu)
{
uint32_t op0;
uint32_t insn;
@@ -1483,40 +1495,23 @@ static void disas_openrisc_insn(DisasContext *dc,
OpenRISCCPU *cpu)
switch (op0) {
case 0x06:
- dec_M(dc, insn);
- break;
-
+ return dec_M(dc, insn);
case 0x08:
- dec_sys(dc, insn);
- break;
-
+ return dec_sys(dc, insn);
case 0x2e:
- dec_logic(dc, insn);
- break;
-
+ return dec_logic(dc, insn);
case 0x2f:
- dec_compi(dc, insn);
- break;
-
+ return dec_compi(dc, insn);
case 0x31:
- dec_mac(dc, insn);
- break;
-
+ return dec_mac(dc, insn);
case 0x32:
- dec_float(dc, insn);
- break;
-
+ return dec_float(dc, insn);
case 0x38:
- dec_calc(dc, insn);
- break;
-
+ return dec_calc(dc, insn);
case 0x39:
- dec_comp(dc, insn);
- break;
-
+ return dec_comp(dc, insn);
default:
- dec_misc(dc, insn);
- break;
+ return dec_misc(dc, insn);
}
}
@@ -1529,16 +1524,17 @@ void gen_intermediate_code(CPUOpenRISCState *env,
struct TranslationBlock *tb)
uint32_t next_page_start;
int num_insns;
int max_insns;
+ JmpStatus exit;
pc_start = tb->pc;
dc->tb = tb;
- dc->is_jmp = DISAS_NEXT;
dc->pc = pc_start;
dc->mem_idx = cpu_mmu_index(&cpu->env, false);
dc->tb_flags = tb->flags;
- dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0;
+ dc->dflag = (dc->tb_flags & TB_FLAGS_DFLAG) != 0;
dc->singlestep_enabled = cs->singlestep_enabled;
+ dc->jmp_type = JMP_VAR;
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
qemu_log("IN: %s\n", lookup_symbol(pc_start));
@@ -1566,14 +1562,12 @@ void gen_intermediate_code(CPUOpenRISCState *env,
struct TranslationBlock *tb)
}
do {
- tcg_gen_insn_start(dc->pc, (dc->delayed_branch ? 1 : 0)
- | (num_insns ? 2 : 0));
+ tcg_gen_insn_start(dc->pc, dc->dflag | (num_insns ? 2 : 0));
num_insns++;
if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
tcg_gen_movi_tl(cpu_pc, dc->pc);
- gen_exception(dc, EXCP_DEBUG);
- dc->is_jmp = DISAS_UPDATE;
+ exit = gen_exception(dc, EXCP_DEBUG);
/* The address covered by the breakpoint must be included in
[tb->pc, tb->pc + tb->size) in order to for it to be
properly cleared -- thus we increment the PC here so that
@@ -1585,20 +1579,19 @@ void gen_intermediate_code(CPUOpenRISCState *env,
struct TranslationBlock *tb)
if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
gen_io_start();
}
- disas_openrisc_insn(dc, cpu);
- dc->pc = dc->pc + 4;
-
- /* delay slot */
- if (dc->delayed_branch) {
- dc->delayed_branch--;
- if (!dc->delayed_branch) {
- tcg_gen_mov_tl(cpu_pc, jmp_pc);
- tcg_gen_discard_tl(jmp_pc);
- dc->is_jmp = DISAS_UPDATE;
- break;
+
+ if (dc->dflag) {
+ /* In delay slot. We will exit next. */
+ exit = disas_openrisc_insn(dc, cpu);
+ dc->dflag = false;
+ if (exit != JMP_EXCP) {
+ exit = dc->jmp_type;
}
+ } else {
+ exit = disas_openrisc_insn(dc, cpu);
}
- } while (!dc->is_jmp
+ dc->pc += 4;
+ } while (exit == JMP_NONE
&& !tcg_op_buf_full()
&& !cs->singlestep_enabled
&& !singlestep
@@ -1609,34 +1602,39 @@ void gen_intermediate_code(CPUOpenRISCState *env,
struct TranslationBlock *tb)
gen_io_end();
}
- if ((dc->tb_flags & TB_FLAGS_DFLAG ? 1 : 0) != (dc->delayed_branch != 0)) {
- tcg_gen_movi_i32(cpu_dflag, dc->delayed_branch != 0);
+ if (dc->dflag != !!(dc->tb_flags & TB_FLAGS_DFLAG)) {
+ tcg_gen_movi_i32(cpu_dflag, dc->dflag);
}
-
tcg_gen_movi_tl(cpu_ppc, dc->pc - 4);
- if (dc->is_jmp == DISAS_NEXT) {
- dc->is_jmp = DISAS_UPDATE;
+
+ switch (exit) {
+ case JMP_NONE:
tcg_gen_movi_tl(cpu_pc, dc->pc);
- }
- if (unlikely(cs->singlestep_enabled)) {
- gen_exception(dc, EXCP_DEBUG);
- } else {
- switch (dc->is_jmp) {
- case DISAS_NEXT:
- gen_goto_tb(dc, 0, dc->pc);
- break;
- default:
- case DISAS_JUMP:
- break;
- case DISAS_UPDATE:
- /* indicate that the hash table must be used
- to find the next TB */
+ if (unlikely(cs->singlestep_enabled)) {
+ gen_exception_1(EXCP_DEBUG);
+ } else {
tcg_gen_exit_tb(0);
- break;
- case DISAS_TB_JUMP:
- /* nothing more to generate */
- break;
}
+ break;
+ case JMP_VAR:
+ tcg_gen_mov_tl(cpu_pc, jmp_pc);
+ tcg_gen_discard_tl(jmp_pc);
+ if (unlikely(cs->singlestep_enabled)) {
+ gen_exception_1(EXCP_DEBUG);
+ } else {
+ tcg_gen_exit_tb(0);
+ }
+ break;
+ case JMP_DIRECT:
+ if (unlikely(cs->singlestep_enabled)) {
+ tcg_gen_movi_tl(cpu_pc, dc->jmp_dest[0]);
+ gen_exception_1(EXCP_DEBUG);
+ } else {
+ gen_goto_tb(dc, 0, dc->jmp_dest[0]);
+ }
+ break;
+ case JMP_EXCP:
+ break;
}
gen_tb_end(tb, num_insns);
--
2.5.5
- [Qemu-devel] [PATCH 14/25] target-openrisc: Implement muld, muldu, macu, msbu, (continued)
- [Qemu-devel] [PATCH 14/25] target-openrisc: Implement muld, muldu, macu, msbu, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 19/25] target-openrisc: Tidy ppc/npc implementation, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 09/25] target-openrisc: Implement ff1 and fl1 for 64-bit, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 21/25] target-openrisc: Tidy insn dumping, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 16/25] target-openrisc: Write back result before FPE exception, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 18/25] target-openrisc: Implement l.adrp, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 20/25] target-openrisc: Optimize l.jal to next, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 10/25] target-openrisc: Represent MACHI:MACLO as a single unit, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 17/25] target-openrisc: Implement lwa, swa, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 15/25] target-openrisc: Fix madd, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 24/25] target-openrisc: Generate goto_tb for direct branches,
Richard Henderson <=
- [Qemu-devel] [PATCH 25/25] target-openrisc: Generate goto_tb for conditional branches, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 22/25] target-openrisc: Tidy handling of delayed branches, Richard Henderson, 2016/06/13
- [Qemu-devel] [PATCH 23/25] target-openrisc: Optimize for r0 being zero, Richard Henderson, 2016/06/13