Hello,
I have a question about ARM PC-relative load instructions in softmmu
execution, and how the PC is constant-folded at JIT compilation time
into a TB.
I have observed in translate.c the following code:
/* Set a variable to the value of a CPU register. */
static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
{
if (reg == 15) {
uint32_t addr;
if (s->thumb)
addr = (long)s->pc + 2;
else
addr = (long)s->pc + 4;
tcg_gen_movi_i32(var, addr);
} else {
tcg_gen_mov_i32(var, cpu_R[reg]);
}
}
This constant folds the value of the PC into the TCG mov for (potential)
use by a memory operation, but it is my understanding that this will be
the *virtual* PC.
It is also my understanding that since TBs are physically indexed in the
TB cache, they aren't invalidated when the guest page tables change.
So, my question is, how can a TB for a particular block containing a
constant folded *virtual* PC work, if the MMU mappings change and a
different virtual address is used to access the same physical address?
E.g. assume we have an instruction such as: ldr r0, [pc, #8]
If this is compiled in a block that begins at virtual address 0x10000,
then the load will be emitted as a constant load from address 0x10008
(and will be subject to the usual TLB lookup code). But, if the MMU
mappings change, and the block is entered from virtual address 0x20000
(because 0x20000 now points to the same physical page), then the load
will be incorrect, as it would still be accessing address 0x10000, but
should actually be accessing address 0x20008.
Have I made any incorrect assumptions, or is there something else going
on that I'm not aware of?
Thanks in advance for any information you can give me,
Tom
--
Kindest Regards,
Tom Spink
University of Edinburgh
The University of Edinburgh is a charitable body, registered in
Scotland, with registration number SC005336.