Hi Stefano....

I'll try to share what I know about TCG......

On Thu, Dec 16, 2010 at 22:20, Stefano Bonifazi
<stefboombas...@gmail.com> wrote:
> Actually as a student, I've never developed even a simple classic emulator
> myself,

you're not alone...trust me...... :)

>but in my idea it should follow this flow:
> 1) Fetch target instruction
>  i.e. PC(0x532652) : 0x104265 (I am just inventing)
> 2) Decode
>  Opcode 0x10 :  ADD,  R1: 0x42, R2: 0x65
> 3) Look up instruction function table:
>  switch(opcode)
>  case add :
>   add(R1, R2)
>  break;
> 4) Execution
>  void add(int R1, int R2)
>  { env->reg[R1] = env->reg[R1] + env[R2];}

You're right. Basically, we're taught that emulation is like big giant
"swith..case" with lots of condition. And that's exactly what Bochs
does AFAIK...

The pros of this approach is instruction could be simulated as precise
as possible and we could have more precise control about
timing...however the cons is... as we saw that big case
branching...cache miss could likely happen (in host machine I mean)
and pipeline stalls might happen more.

By doing what Qemu does, be it using the old dyngen or new TCG, we try
to maintain "execution fluidity" by interpreting instruction as less
as possible and strings together  the already translated blocks ...
And don't forget that Qemu sometimes does things like lazy flags
update, somewhat simple dead code elimination and so on. More like
tiny compiler...right?

> Now all of that would be compiled offline for the host machine and at
> runtime the host macine would just execute the binary host code for the
> instruction  "env->reg[R1] = env->reg[R1] + env[R2];" (its host binary
> translation)
>
> My big doubt is, how can I execute that new binary? .. Shall TCG put it in
> some memory location, and then make the process branch to that address (and
> then back) ?
> I really can't see how that happens in the code :(
>
> in cpu-exec.c : cpu_exec_nocache i find:
>
>> /* execute the generated code */
>>    next_tb = tcg_qemu_tb_exec(tb->tc_ptr);
>
> and in cpu-exec.c : cpu_exec
>
>> /* execute the generated code */
>>
>>                    next_tb = tcg_qemu_tb_exec(tc_ptr);
>
> so I thought tcg_qemu_tb_exec "function" should do the work of executing the
> translated binary in the host.
> But then I found out it is just a define in tcg.h:
>
>> #define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void
>> *))code_gen_prologue)(tb_ptr)
>
> and again in exec.c
>
>> uint8_t code_gen_prologue[1024] code_gen_section;
>
> Maybe I have some problems with that C syntax, but I really don't understand
> what happens there.. how the execution happens!

With my limited C knowledge, I saw that as a instruction jump (to
tb_ptr). The "code_gen_prologue" seems to me like a cast..... casting
each opcode in tb_ptr as uint8_t.... with maximum length=1024

I hope that's the right interpretation...I must admit Qemu is full of
gcc and C tricks here and there...


-- 
regards,

Mulyadi Santosa
Freelance Linux trainer and consultant

blog: the-hydra.blogspot.com
training: mulyaditraining.blogspot.com

Reply via email to