On Tue, Jan 04, 2011 at 02:43:11PM -0500, Mike Frysinger wrote:
> i've been working on a new architecture port, but i cant quite figure
> out some of the intricacies from reading the code.  i have all the
> simple stuff working for linux-user (register moves, immediate moves,
> loads, stores, syscall emulation) and want to move on to the next big
> piece -- code flow changes.
> 
> i cant quite figure out the difference between DISAS_TB_JUMP and
> DISAS_JUMP.  the exec-all.h header says one is for "only pc was
> modified dynamically" while the other is "only pc was modified
> statically".  is this referring to conditional vs unconditional jumps
> ?  or is this referring to direct vs indirect jumps ?
> conditional: if cc jump 1f;
> unconditional: jump 1f;
> direct: jump foo;
> indirect: P0 = [SP++]; jump (P0);

Hi Mike,

I think it's referering to the latter + some other rules but:
is_jmp is a port local var and the DISAS_XXX states are used in slightly
different ways by different ports depending on the needs. Some ports only
use some of the states. When branching, what really matters is how and when
you end the TB. You need to bring the runtime state up-to-date and end the
TB by potentially jumping to another one (tcg_gen_goto_tb) and by
exiting (tcg_gen_exit_tb).

To be able to jump directly between TB's you need to follow some rules:
Not jump across pages. Not jump from a TB that has modified it's TB
dependant CPU state in a dynamic way. Also the destination address must be
derived from data available at translation time, e.g not an indirect
register branch/jump. + I probably forgot something :). These rules
are related to the DISAS_XXX comments you were wondering about.

For some arch's branching is a fairly easy matter, for others it can be
quite complicated. Delayslots, MMU aborts, variable length ISA encoding
and other details can all come together to make things hairy. It's not
all 100% clear to me either so I hope I'm not missleading you here. If
so, someone will probably correct me.


> along these lines, when should i be using gen_new_label,
> gen_set_label, tcg_gen_brcond*, and tcg_gen_setcond* ?  should they
> only be used with conditional code ?

You can use these for translation of any insn, allthough typically they
are used for insns with conditional logic.


> or should unconditional jumps be generating labels too ?

No, that's not necessary.


> for conditional register assignments, i think i should be using these
> too.  so something like:
>   if CC R0 = R1;
> should turn into:
>   l = gen_new_label();
>   tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc, T, l);
>   tcg_gen_mov_tl(reg_dst, reg_src);
>   gen_set_label(l);
> and i dont need to flag this bit of code as a jump (e.g. DISAS_JUMP) ...

That's right.


> also, having gone through the ops already available in tcg-op.h, ive
> managed to decode what they do except for these:
> tcg_gen_{ld,st}{8,16,32}{u,s}
> i thought originally they were for handling load/store insns, but they
> didnt work for me, and then i found the tcg_gen_qemu_{ld,st}* ops.  so
> what is the point of these ones ?

tcg_gen_ld/st are for making loads/stores that do not operate on the guest
memory hierarchy. They operate on host memory and don't really have a
connection to guest load/stores. They can for example be used to bring
data to/from the CPU state into tcg variables to emulate some reg to reg
insn.

tcg_gen_qemu_ld/st are for emulating guest load/stores. These operate on
the guest memory hierarcy and may for example abort due to MMU related
aborts or the access may go to emulated I/O etc.

Cheers

Reply via email to