mirror of
https://github.com/Motorhead1991/qemu.git
synced 2026-01-05 22:17:40 -07:00
accel/tcg: Perform aligned atomic reads in translator_ld
Perform aligned atomic reads in translator_ld, if possible. According to https://lore.kernel.org/qemu-devel/20240607101403.1109-1-jim.shu@sifive.com/ this is required for RISC-V Ziccif. Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
4ba597c138
commit
6a9dfe1984
1 changed files with 38 additions and 4 deletions
|
|
@ -265,12 +265,14 @@ static bool translator_ld(CPUArchState *env, DisasContextBase *db,
|
|||
|
||||
if (likely(((base ^ last) & TARGET_PAGE_MASK) == 0)) {
|
||||
/* Entire read is from the first page. */
|
||||
memcpy(dest, host + (pc - base), len);
|
||||
return true;
|
||||
goto do_read;
|
||||
}
|
||||
|
||||
if (unlikely(((base ^ pc) & TARGET_PAGE_MASK) == 0)) {
|
||||
/* Read begins on the first page and extends to the second. */
|
||||
/*
|
||||
* Read begins on the first page and extends to the second.
|
||||
* The unaligned read is never atomic.
|
||||
*/
|
||||
size_t len0 = -(pc | TARGET_PAGE_MASK);
|
||||
memcpy(dest, host + (pc - base), len0);
|
||||
pc += len0;
|
||||
|
|
@ -329,7 +331,39 @@ static bool translator_ld(CPUArchState *env, DisasContextBase *db,
|
|||
host = db->host_addr[1];
|
||||
}
|
||||
|
||||
memcpy(dest, host + (pc - base), len);
|
||||
do_read:
|
||||
/*
|
||||
* Assume aligned reads should be atomic, if possible.
|
||||
* We're not in a position to jump out with EXCP_ATOMIC.
|
||||
*/
|
||||
host += pc - base;
|
||||
switch (len) {
|
||||
case 2:
|
||||
if (QEMU_IS_ALIGNED(pc, 2)) {
|
||||
uint16_t t = qatomic_read((uint16_t *)host);
|
||||
stw_he_p(dest, t);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (QEMU_IS_ALIGNED(pc, 4)) {
|
||||
uint32_t t = qatomic_read((uint32_t *)host);
|
||||
stl_he_p(dest, t);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
#ifdef CONFIG_ATOMIC64
|
||||
case 8:
|
||||
if (QEMU_IS_ALIGNED(pc, 8)) {
|
||||
uint64_t t = qatomic_read__nocheck((uint64_t *)host);
|
||||
stq_he_p(dest, t);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
/* Unaligned or partial read from the second page is not atomic. */
|
||||
memcpy(dest, host, len);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue