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