Re: [Qemu-devel] [PATCH 18/18] target/riscv: convert to TranslatorOps
On Sat, Apr 21, 2018 at 6:55 AM, Emilio G. Cotawrote: > Reviewed-by: Richard Henderson > Cc: Michael Clark > Cc: Palmer Dabbelt > Cc: Sagar Karandikar > Cc: Bastian Koppelmann > Signed-off-by: Emilio G. Cota > Reviewed-by: Michael Clark > --- > target/riscv/translate.c | 158 -- > - > 1 file changed, 80 insertions(+), 78 deletions(-) > > diff --git a/target/riscv/translate.c b/target/riscv/translate.c > index 18ec1a7..fc9c659 100644 > --- a/target/riscv/translate.c > +++ b/target/riscv/translate.c > @@ -1836,78 +1836,71 @@ static void decode_opc(CPURISCVState *env, > DisasContext *ctx) > } > } > > -void gen_intermediate_code(CPUState *cs, TranslationBlock *tb) > +static void riscv_tr_init_disas_context(DisasContextBase *dcbase, > CPUState *cs) > { > -CPURISCVState *env = cs->env_ptr; > -DisasContext ctx; > -target_ulong page_start; > -int num_insns; > -int max_insns; > - > -ctx.base.pc_first = tb->pc; > -ctx.base.pc_next = ctx.base.pc_first; > -/* once we have GDB, the rest of the translate.c implementation > should be > - ready for singlestep */ > -ctx.base.singlestep_enabled = cs->singlestep_enabled; > -ctx.base.tb = tb; > -ctx.base.is_jmp = DISAS_NEXT; > - > -page_start = ctx.base.pc_first & TARGET_PAGE_MASK; > -ctx.pc_succ_insn = ctx.base.pc_first; > -ctx.flags = tb->flags; > -ctx.mem_idx = tb->flags & TB_FLAGS_MMU_MASK; > -ctx.frm = -1; /* unknown rounding mode */ > - > -num_insns = 0; > -max_insns = tb_cflags(ctx.base.tb) & CF_COUNT_MASK; > -if (max_insns == 0) { > -max_insns = CF_COUNT_MASK; > -} > -if (max_insns > TCG_MAX_INSNS) { > -max_insns = TCG_MAX_INSNS; > -} > -gen_tb_start(tb); > +DisasContext *ctx = container_of(dcbase, DisasContext, base); > > -while (ctx.base.is_jmp == DISAS_NEXT) { > -tcg_gen_insn_start(ctx.base.pc_next); > -num_insns++; > +ctx->pc_succ_insn = ctx->base.pc_first; > +ctx->flags = ctx->base.tb->flags; > +ctx->mem_idx = ctx->base.tb->flags & TB_FLAGS_MMU_MASK; > +ctx->frm = -1; /* unknown rounding mode */ > +} > > -if (unlikely(cpu_breakpoint_test(cs, ctx.base.pc_next, BP_ANY))) > { > -tcg_gen_movi_tl(cpu_pc, ctx.base.pc_next); > -ctx.base.is_jmp = DISAS_NORETURN; > -gen_exception_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 > - the logic setting tb->size below does the right thing. */ > -ctx.base.pc_next += 4; > -goto done_generating; > -} > +static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu) > +{ > +} > > -if (num_insns == max_insns && (tb_cflags(ctx.base.tb) & > CF_LAST_IO)) { > -gen_io_start(); > -} > +static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) > +{ > +DisasContext *ctx = container_of(dcbase, DisasContext, base); > + > +tcg_gen_insn_start(ctx->base.pc_next); > +} > + > +static bool riscv_tr_breakpoint_check(DisasContextBase *dcbase, CPUState > *cpu, > + const CPUBreakpoint *bp) > +{ > +DisasContext *ctx = container_of(dcbase, DisasContext, base); > + > +tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); > +ctx->base.is_jmp = DISAS_NORETURN; > +gen_exception_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 > + the logic setting tb->size below does the right thing. */ > +ctx->base.pc_next += 4; > +return true; > +} > + > + > +static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState > *cpu) > +{ > +DisasContext *ctx = container_of(dcbase, DisasContext, base); > +CPURISCVState *env = cpu->env_ptr; > + > +ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next); > +decode_opc(env, ctx); > +ctx->base.pc_next = ctx->pc_succ_insn; > + > +if (ctx->base.is_jmp == DISAS_NEXT) { > +target_ulong page_start; > > -ctx.opcode = cpu_ldl_code(env, ctx.base.pc_next); > -decode_opc(env, ); > -ctx.base.pc_next = ctx.pc_succ_insn; > - > -if (ctx.base.is_jmp == DISAS_NEXT && > -(cs->singlestep_enabled || > - ctx.base.pc_next - page_start >= TARGET_PAGE_SIZE || > - tcg_op_buf_full() || > - num_insns >= max_insns || > - singlestep)) { > -ctx.base.is_jmp = DISAS_TOO_MANY; > +page_start =
[Qemu-devel] [PATCH 18/18] target/riscv: convert to TranslatorOps
Reviewed-by: Richard HendersonCc: Michael Clark Cc: Palmer Dabbelt Cc: Sagar Karandikar Cc: Bastian Koppelmann Signed-off-by: Emilio G. Cota --- target/riscv/translate.c | 158 --- 1 file changed, 80 insertions(+), 78 deletions(-) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 18ec1a7..fc9c659 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -1836,78 +1836,71 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx) } } -void gen_intermediate_code(CPUState *cs, TranslationBlock *tb) +static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) { -CPURISCVState *env = cs->env_ptr; -DisasContext ctx; -target_ulong page_start; -int num_insns; -int max_insns; - -ctx.base.pc_first = tb->pc; -ctx.base.pc_next = ctx.base.pc_first; -/* once we have GDB, the rest of the translate.c implementation should be - ready for singlestep */ -ctx.base.singlestep_enabled = cs->singlestep_enabled; -ctx.base.tb = tb; -ctx.base.is_jmp = DISAS_NEXT; - -page_start = ctx.base.pc_first & TARGET_PAGE_MASK; -ctx.pc_succ_insn = ctx.base.pc_first; -ctx.flags = tb->flags; -ctx.mem_idx = tb->flags & TB_FLAGS_MMU_MASK; -ctx.frm = -1; /* unknown rounding mode */ - -num_insns = 0; -max_insns = tb_cflags(ctx.base.tb) & CF_COUNT_MASK; -if (max_insns == 0) { -max_insns = CF_COUNT_MASK; -} -if (max_insns > TCG_MAX_INSNS) { -max_insns = TCG_MAX_INSNS; -} -gen_tb_start(tb); +DisasContext *ctx = container_of(dcbase, DisasContext, base); -while (ctx.base.is_jmp == DISAS_NEXT) { -tcg_gen_insn_start(ctx.base.pc_next); -num_insns++; +ctx->pc_succ_insn = ctx->base.pc_first; +ctx->flags = ctx->base.tb->flags; +ctx->mem_idx = ctx->base.tb->flags & TB_FLAGS_MMU_MASK; +ctx->frm = -1; /* unknown rounding mode */ +} -if (unlikely(cpu_breakpoint_test(cs, ctx.base.pc_next, BP_ANY))) { -tcg_gen_movi_tl(cpu_pc, ctx.base.pc_next); -ctx.base.is_jmp = DISAS_NORETURN; -gen_exception_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 - the logic setting tb->size below does the right thing. */ -ctx.base.pc_next += 4; -goto done_generating; -} +static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu) +{ +} -if (num_insns == max_insns && (tb_cflags(ctx.base.tb) & CF_LAST_IO)) { -gen_io_start(); -} +static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) +{ +DisasContext *ctx = container_of(dcbase, DisasContext, base); + +tcg_gen_insn_start(ctx->base.pc_next); +} + +static bool riscv_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu, + const CPUBreakpoint *bp) +{ +DisasContext *ctx = container_of(dcbase, DisasContext, base); + +tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); +ctx->base.is_jmp = DISAS_NORETURN; +gen_exception_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 + the logic setting tb->size below does the right thing. */ +ctx->base.pc_next += 4; +return true; +} + + +static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) +{ +DisasContext *ctx = container_of(dcbase, DisasContext, base); +CPURISCVState *env = cpu->env_ptr; + +ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next); +decode_opc(env, ctx); +ctx->base.pc_next = ctx->pc_succ_insn; + +if (ctx->base.is_jmp == DISAS_NEXT) { +target_ulong page_start; -ctx.opcode = cpu_ldl_code(env, ctx.base.pc_next); -decode_opc(env, ); -ctx.base.pc_next = ctx.pc_succ_insn; - -if (ctx.base.is_jmp == DISAS_NEXT && -(cs->singlestep_enabled || - ctx.base.pc_next - page_start >= TARGET_PAGE_SIZE || - tcg_op_buf_full() || - num_insns >= max_insns || - singlestep)) { -ctx.base.is_jmp = DISAS_TOO_MANY; +page_start = ctx->base.pc_first & TARGET_PAGE_MASK; +if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE) { +ctx->base.is_jmp = DISAS_TOO_MANY; } } -if (tb_cflags(ctx.base.tb) & CF_LAST_IO) { -gen_io_end(); -} -switch (ctx.base.is_jmp) { +} + +static void riscv_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) +{ +DisasContext *ctx