qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] qemu branching internal questions


From: Edgar E. Iglesias
Subject: Re: [Qemu-devel] qemu branching internal questions
Date: Fri, 7 Jan 2011 03:04:18 +0100
User-agent: Mutt/1.5.20 (2009-06-14)

On Thu, Jan 06, 2011 at 01:47:56PM -0500, Mike Frysinger wrote:
> On Wed, Jan 5, 2011 at 05:59, Edgar E. Iglesias wrote:
> > 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);
> >
> > 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.
> 
> thanks for the info ... my arch doesnt have to deal with crazy stuff
> like that.  it has fixed insn length (2 or 4 bytes) and no delayed
> branching.  so it should be somewhat like arm/i386 i think.
> 
> could you elaborate on the tcg_gen_goto_tb and tcg_gen_exit_tb stuff ?
>  i think i have all the other pieces squared away in my head now
> (labels/branches/conditions).  but i cant quite grasp the meaning of
> the arguments to the tb goto/exit points.

IIUC: 
Every TB can goto_tb to max two other different destinations. There are
two jump slots. tcg_gen_goto_tb takes a jump slot index as an arg,
0 or 1. These jumps will only take place if the TB's get chained,
you need to tcg_gen_exit_tb with (tb | index) for that to ever happen.
tcg_gen_exit_tb should be called with the ptr of the current tb OR:ed
with the index of the taken jump slot.

Chaining will allow TB's to run back to back after eachother, but note
that it will not happen the first time and also TB's can at any time
get unchained (e.g due to interrrupts).

If you tcg_gen_exit_tb(0), chaining will not happen and a new TB
will be looked up based on the CPU state (can still be a jump). A
bit slower but needed in some cases (for example if you change the
TB dependant CPU state dynamically + the other rules I mentioned in
the previous email).


> this x86_64 asm has direct correlations to my own ISA:
> .global _start
> _start:
>         mov $60, %rax
>         mov $6, %rcx
>         mov $0, %rbx
> 1:      add $1, %rbx
>         cmp %rcx, %rbx
>         jl 1b
>         int $0x80;
> basically i set the syscall number to __NR_exit, set the first
> argument to 0, and then increment it until the argument is 6.  then
> the program exits with status of 6.
> 
> the tcg ops that the branch generates are:
>  movi_i32 cc_op,$0x11
>  add_i64 tmp8,cc_dst,cc_src
>  brcond_i64 tmp8,cc_src,lt,$0x0
>  goto_tb $0x0
>  movi_i64 tmp4,$0x4000ce
>  st_i64 tmp4,env,$0x80
>  exit_tb $0x7fd7a475f088
>  set_label $0x0
>  goto_tb $0x1
>  movi_i64 tmp4,$0x4000c5
>  st_i64 tmp4,env,$0x80
>  exit_tb $0x7fd7a475f089
> 
> what meaning do the goto_tb arguments (0 and 1) have ?  the exit_tb
> args appear to be the actual tb pointers, but for some reason the
> second one is set to the pointer+1.  i guess this is significant ?

Yes, it let's the chaning machinery know which jump index should be
chained to the next tb.

You'll have to check the details in the code but I hope this gets
you going.

Cheers



reply via email to

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