Got it.
Thanks for the explanation

Sent from my cell phone, please ignore typos

On Mon, Jun 3, 2019, 6:31 PM Richard Henderson <richard.hender...@linaro.org>
wrote:

> On 6/1/19 10:44 PM, Michael Rolnik wrote:
> > Hi Richard.
> >
> > these instructions are not branches or jumps they all do skip.
>
> Of course they're not all branches.  I used the example of a branch to
> show a
> situation in which your translation is wrong.
>
> > however, if you think it's important I change it, I will, just show me an
> > example or explain.
>
> Ok, let's take HPPA as a very similar example.
>
> Many HPPA instructions may "nullify" the next instruction.  The language is
> different, but it's the same thing as the AVR "skip".
>
> Now, I spent quite a bit of effort in target/hppa using conditional move
> instructions to implement this.  But you need not go that far.
>
> Now, AVR is differs from HPPA in that there is a nullify bit as part of the
> process state.  Since AVR does not have this, we will need to keep the
> "skip"
> state entirely internal to the qemu implementation.
>
> I suggest:
>
> (1) Add "bool skipping;" to CPUAVRState.
>
> Because TranslationBlocks can be ended at any instruction boundary, we need
> some way to preserve the skipping state across TB's.
>
> (2) Include "skipping" into the flags for cpu_get_tb_cpu_state,
> TB_FLAGS_SKIPPING.
>
> (3) Include "skipping" into the computation of cpu_interrupts_enabled.
>
> Because "skipping" is not part of the architectural state of the CPU, we
> cannot
> allow an interrupt to come between the two instructions.  Therefore, while
> "skipping" is true, disable interrupts.
>
> (4) Within the instructions that skip the next, issue the branch but
> record the
> label as DisasContext->skip_label.  This will allow the main loop (and
> other
> instructions) know that skipping is active.
>
> (5a) In gen_intermediate_code, if TB_FLAGS_SKIPPING, decode but do not
> translate the insn, then clear TB_FLAGS_SKIPPING and store 0 into
> env->skipping.
>
> (5b) In gen_intermediate_code, if !TB_FLAGS_SKIPPING, copy
> DisasContext->skip_label into a local variable, this_skip_label and zero.
>
> We need to prepare for skip of skip, so do not allow the label of the first
> skip to be clobbered by the label of the second skip.
>
> (5c) After translate(), if this_skip_label is non-null, emit the label.
>
> (6) Reverse the sense of your conditional branches.
>
> Currently you generate
>
>   brcond(xxx, yyy, zzz, true_label);
>   goto npc
> true_label:
>   goto true_pc
>
> which is fine until we have skip labels.  We now want to emit
>
>   brcond(!xxx, yyy, zzz, false_label);
>   goto true_pc
> false_label:
> skip_label:
>   goto npc
>
> which you can do by issuing only the branch, goto, label, and then setting
> ctx->bstate to BS_STOP, so that the skip_label is emitted by the main
> loop, and
> the goto npc is also issued by the main loop.
>
> (7) At the end of the loop in gen_intermedite_code, if
> DisasContext->skip_label
> is non-null, then we ended the TB with a skipping instruction and we need
> to
> preserve that within env.
>
>     TCGLabel *finish = NULL;
>
>     if (ctx.skip_label) {
>         finish = gen_new_label();
>     }
>
>     if (tb->cflags & CF_LAST_IO) {
>     ...
>
>
>     if (ctx.skip_label) {
>         TCGv_i32 one;
>
>         gen_set_label(ctx.skip_label);
>         one = tcg_const_i32(1);
>         tcg_gen_st8_i32(one, cpu_env, offsetof(CPUAVRState, skipping));
>         tcg_temp_free_i32(one);
>         tcg_gen_br(finish);
>     }
>
>  done_generating:
>    gen_tb_end(tb, num_insns);
>
>
> r~
>

Reply via email to