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