On Sun, 2 Oct 2022 at 10:22, BitFriends <commandspide...@gmail.com> wrote: > I now came up with this code: > > TCGv_i64 res = 0; > TCGv_i64 addr = (TCGv_i64)(env->regs[R_EDI]); > > tcg_gen_qemu_ld_i64(res, addr, 0, MO_LEUQ); > > env->regs[R_EAX] = (target_ulong)res;
This is wrong, because you cannot read or write env->regs[] at translate time. The "translate time" vs "run time" distinction in a JIT is critical to understand: * translate time is when we read guest instructions, and output TCG ops. We do this once, the first time we encounter a particular piece of guest code. At this point you cannot directly access the state of the guest CPU. This is because the exact value of EDI will be *different* each time the generated code is run. * run time is when we are actually emulating the guest CPU, by executing the code built from the TCG ops. At run time the CPU state is known and can be updated. You should look at how existing instructions in the x86 translator generate code to read and write registers -- you will see that they use cpu_regs[], which is an array of TCGv which correspond to the CPU registers (so they can say "generate code which will read EDI"), and they never use env->regs[] (which would be "read EDI right now"). More generally, "read guest memory and get the result into a guest CPU register" is a common thing in existing x86 instructions. So find how we implement one of those existing insns that's similar to what you want, and see how that is handled. (NB: so far you haven't said why your custom instruction would be any different from a normal load instruction that x86 already has...) thanks -- PMM