qemu-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]