[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v12 04/27] target: [tcg] Add generic translation
From: |
Lluís Vilanova |
Subject: |
Re: [Qemu-devel] [PATCH v12 04/27] target: [tcg] Add generic translation framework |
Date: |
Tue, 11 Jul 2017 19:40:27 +0300 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/25.1 (gnu/linux) |
Richard Henderson writes:
> On 07/07/2017 01:56 AM, Lluís Vilanova wrote:
[...]
>> +
>> + /* Instruction counting */
>> + max_insns = db->tb->cflags & CF_COUNT_MASK;
>> + if (max_insns == 0) {
>> + max_insns = CF_COUNT_MASK;
>> + }
>> + if (max_insns > TCG_MAX_INSNS) {
>> + max_insns = TCG_MAX_INSNS;
>> + }
>> + if (db->singlestep_enabled || singlestep) {
>> + max_insns = 1;
>> + }
>> +
>> + /* Start translating */
>> + gen_tb_start(db->tb);
>> + ops->tb_start(db, cpu);
> As I mentioned, we need some way to modify max_insns before the loop start.
> (For the ultimate in max_insns modifying needs, see the sh4 patch set I posted
> this morning, wherein I may *extend* max_insns in order to force it to cover a
> region to be executed atomically within one TB, within the lock held by
> cpu_exec_step_atomic.)
> Based on that, I recommend
> DisasJumpType status;
> status = ops->tb_start(db, cpu, &max_insns);
> Because in my sh4 case, tb_start might itself decide that the only way to
> handle
> the code is to raise the EXCP_ATOMIC exception and try again within
> cpu_exec_step_atomic. Which means that we would not enter the while loop at
> all. Thus,
>> + while (true) {
> while (status == DISAS_NEXT) {
>> + db->num_insns++;
>> + ops->insn_start(db, cpu);
>> +
>> + /* Early exit before breakpoint checks */
> Better comment maybe? "The insn_start hook may request early exit..."
> And, indeed, perhaps
> status = ops->insn_start(db, cpu);
> if (unlikely(status != DISAS_NEXT)) {
> break;
> }
Since other hooks can set db->is_jmp and return values (breakpoint_check), I'll
stick with db->is_jmp instead. Then tb_start can return max_insns, and generic
code can refine it with checks like single-stepping.
>> + if (unlikely(db->is_jmp != DISAS_NEXT)) {
>> + break;
>> + }
>> +
>> + /* Pass breakpoint hits to target for further processing */
>> + if (unlikely(!QTAILQ_EMPTY(&cpu->breakpoints))) {
>> + CPUBreakpoint *bp;
>> + QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
>> + if (bp->pc == db->pc_next) {
>> + BreakpointCheckType bp_check =
>> + ops->breakpoint_check(db, cpu, bp);
>> + switch (bp_check) {
>> + case BC_MISS:
>> + /* Target ignored this breakpoint, go to next */
>> + break;
>> + case BC_HIT_INSN:
>> + /* Hit, keep translating */
>> + /*
>> + * TODO: if we're never going to have more than one
>> + * BP in a single address, we can simply use a
>> + * bool here.
>> + */
>> + goto done_breakpoints;
>> + case BC_HIT_TB:
>> + /* Hit, end TB */
>> + goto done_generating;
>> + default:
>> + g_assert_not_reached();
>> + }
>> + }
>> + }
>> + }
>> + done_breakpoints:
>> +
>> + /* Accept I/O on last instruction */
>> + if (db->num_insns == max_insns && (db->tb->cflags & CF_LAST_IO)) {
>> + gen_io_start();
>> + }
>> +
>> + /* Disassemble one instruction */
>> + db->pc_next = ops->translate_insn(db, cpu);
> I think it would be better to assign to pc_next within the hook. We don't use
> the value otherwise within the rest of the loop.
> But we do use is_jmp, immediately. So maybe better to follow the changes to
> tb_start and insn_start above.
As before, for consistency I prefer to set is_jmp instead of returning it on
hooks, since breakpoint_check() already has a return value and can set is_jmp.
Then, a future series adding tracing events to this loop uses db->pc_next in the
generic loop, so it is going to be used.
>> + }
>> +
>> + ops->tb_stop(db, cpu);
>> +
>> + if (db->tb->cflags & CF_LAST_IO) {
>> + gen_io_end();
>> + }
> You can't place this after tb_stop, as it'll never be executed. We will have
> for certain emitted the exit_tb for all paths by now.
> Just place it before tb_stop where it usually resides. In the case where some
> is_jmp value implies unreached code, and we're using icount, we'll accept the
> dead code. But in all other cases it will get executed.
Ok!
Thanks,
Lluis
[Qemu-devel] [PATCH v12 05/27] target/i386: [tcg] Port to DisasContextBase, Lluís Vilanova, 2017/07/07
[Qemu-devel] [PATCH v12 06/27] target/i386: [tcg] Port to init_disas_context, Lluís Vilanova, 2017/07/07