mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-12-23 16:55:35 +00:00
tcg: Merge GETPC and GETRA
The return address argument to the softmmu template helpers was confused. In the legacy case, we wanted to indicate that there is no return address, and so passed in NULL. However, we then immediately subtracted GETPC_ADJ from NULL, resulting in a non-zero value, indicating the presence of an (invalid) return address. Push the GETPC_ADJ subtraction down to the only point it's required: immediately before use within cpu_restore_state_from_tb, after all NULL pointer checks have been completed. This makes GETPC and GETRA identical. Remove GETRA as the lesser used macro, replacing all uses with GETPC. Backports commit 01ecaf438b1eb46abe23392c8ce5b7628b0c8cf5 from qemu
This commit is contained in:
parent
91f5cf0417
commit
66d79ac959
|
@ -532,10 +532,8 @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
|
||||||
#undef MMUSUFFIX
|
#undef MMUSUFFIX
|
||||||
|
|
||||||
#define MMUSUFFIX _cmmu
|
#define MMUSUFFIX _cmmu
|
||||||
#undef GETPC_ADJ
|
#undef GETPC
|
||||||
#define GETPC_ADJ 0
|
#define GETPC() ((uintptr_t)0)
|
||||||
#undef GETRA
|
|
||||||
#define GETRA() ((uintptr_t)0)
|
|
||||||
#define SOFTMMU_CODE_ACCESS
|
#define SOFTMMU_CODE_ACCESS
|
||||||
|
|
||||||
#define SHIFT 0
|
#define SHIFT 0
|
||||||
|
|
|
@ -351,16 +351,15 @@ static inline void tb_add_jump(TranslationBlock *tb, int n,
|
||||||
tb_next->jmp_list_first = (uintptr_t)tb | n;
|
tb_next->jmp_list_first = (uintptr_t)tb | n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GETRA is the true target of the return instruction that we'll execute,
|
/* GETPC is the true target of the return instruction that we'll execute. */
|
||||||
defined here for simplicity of defining the follow-up macros. */
|
|
||||||
#if defined(CONFIG_TCG_INTERPRETER)
|
#if defined(CONFIG_TCG_INTERPRETER)
|
||||||
extern uintptr_t tci_tb_ptr;
|
extern uintptr_t tci_tb_ptr;
|
||||||
# define GETRA() tci_tb_ptr
|
# define GETPC() tci_tb_ptr
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
# define GETRA() (uintptr_t)_ReturnAddress()
|
# define GETPC() (uintptr_t)_ReturnAddress()
|
||||||
#else
|
#else
|
||||||
# define GETRA() \
|
# define GETPC() \
|
||||||
((uintptr_t)__builtin_extract_return_addr(__builtin_return_address(0)))
|
((uintptr_t)__builtin_extract_return_addr(__builtin_return_address(0)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -377,8 +376,6 @@ extern uintptr_t tci_tb_ptr;
|
||||||
# define GETPC_ADJ 2
|
# define GETPC_ADJ 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GETPC() (GETRA() - GETPC_ADJ)
|
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
|
|
||||||
void phys_mem_set_alloc(void *(*alloc)(size_t, uint64_t *align));
|
void phys_mem_set_alloc(void *(*alloc)(size_t, uint64_t *align));
|
||||||
|
|
|
@ -250,9 +250,6 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust the given return address. */
|
|
||||||
retaddr -= GETPC_ADJ;
|
|
||||||
|
|
||||||
if (addr & ((1 << a_bits) - 1)) {
|
if (addr & ((1 << a_bits) - 1)) {
|
||||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||||
mmu_idx, retaddr);
|
mmu_idx, retaddr);
|
||||||
|
@ -302,10 +299,8 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
|
||||||
do_unaligned_access:
|
do_unaligned_access:
|
||||||
addr1 = addr & ~(DATA_SIZE - 1);
|
addr1 = addr & ~(DATA_SIZE - 1);
|
||||||
addr2 = addr1 + DATA_SIZE;
|
addr2 = addr1 + DATA_SIZE;
|
||||||
/* Note the adjustment at the beginning of the function.
|
res1 = helper_le_ld_name(env, addr1, oi, retaddr);
|
||||||
Undo that for the recursion. */
|
res2 = helper_le_ld_name(env, addr2, oi, retaddr);
|
||||||
res1 = helper_le_ld_name(env, addr1, oi, retaddr + GETPC_ADJ);
|
|
||||||
res2 = helper_le_ld_name(env, addr2, oi, retaddr + GETPC_ADJ);
|
|
||||||
shift = (addr & (DATA_SIZE - 1)) * 8;
|
shift = (addr & (DATA_SIZE - 1)) * 8;
|
||||||
|
|
||||||
/* Little-endian combine. */
|
/* Little-endian combine. */
|
||||||
|
@ -440,9 +435,6 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust the given return address. */
|
|
||||||
retaddr -= GETPC_ADJ;
|
|
||||||
|
|
||||||
if (addr & ((1 << a_bits) - 1)) {
|
if (addr & ((1 << a_bits) - 1)) {
|
||||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
|
||||||
mmu_idx, retaddr);
|
mmu_idx, retaddr);
|
||||||
|
@ -491,10 +483,8 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
|
||||||
do_unaligned_access:
|
do_unaligned_access:
|
||||||
addr1 = addr & ~(DATA_SIZE - 1);
|
addr1 = addr & ~(DATA_SIZE - 1);
|
||||||
addr2 = addr1 + DATA_SIZE;
|
addr2 = addr1 + DATA_SIZE;
|
||||||
/* Note the adjustment at the beginning of the function.
|
res1 = helper_be_ld_name(env, addr1, oi, retaddr);
|
||||||
Undo that for the recursion. */
|
res2 = helper_be_ld_name(env, addr2, oi, retaddr);
|
||||||
res1 = helper_be_ld_name(env, addr1, oi, retaddr + GETPC_ADJ);
|
|
||||||
res2 = helper_be_ld_name(env, addr2, oi, retaddr + GETPC_ADJ);
|
|
||||||
shift = (addr & (DATA_SIZE - 1)) * 8;
|
shift = (addr & (DATA_SIZE - 1)) * 8;
|
||||||
|
|
||||||
/* Big-endian combine. */
|
/* Big-endian combine. */
|
||||||
|
@ -627,9 +617,6 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust the given return address. */
|
|
||||||
retaddr -= GETPC_ADJ;
|
|
||||||
|
|
||||||
if (addr & ((1 << a_bits) - 1)) {
|
if (addr & ((1 << a_bits) - 1)) {
|
||||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
|
cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
|
||||||
mmu_idx, retaddr);
|
mmu_idx, retaddr);
|
||||||
|
@ -691,10 +678,8 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
for (i = 0; i < DATA_SIZE; ++i) {
|
for (i = 0; i < DATA_SIZE; ++i) {
|
||||||
/* Little-endian extract. */
|
/* Little-endian extract. */
|
||||||
uint8_t val8 = (uint8_t)(val >> (i * 8));
|
uint8_t val8 = (uint8_t)(val >> (i * 8));
|
||||||
/* Note the adjustment at the beginning of the function.
|
|
||||||
Undo that for the recursion. */
|
|
||||||
glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
|
glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
|
||||||
oi, retaddr + GETPC_ADJ);
|
oi, retaddr);
|
||||||
if (env->invalid_error != UC_ERR_OK)
|
if (env->invalid_error != UC_ERR_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -776,9 +761,6 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust the given return address. */
|
|
||||||
retaddr -= GETPC_ADJ;
|
|
||||||
|
|
||||||
if (addr & ((1 << a_bits) - 1)) {
|
if (addr & ((1 << a_bits) - 1)) {
|
||||||
cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
|
cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
|
||||||
mmu_idx, retaddr);
|
mmu_idx, retaddr);
|
||||||
|
@ -840,10 +822,8 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
|
||||||
for (i = 0; i < DATA_SIZE; ++i) {
|
for (i = 0; i < DATA_SIZE; ++i) {
|
||||||
/* Big-endian extract. */
|
/* Big-endian extract. */
|
||||||
uint8_t val8 = (uint8_t)(val >> (((DATA_SIZE - 1) * 8) - (i * 8)));
|
uint8_t val8 = (uint8_t)(val >> (((DATA_SIZE - 1) * 8) - (i * 8)));
|
||||||
/* Note the adjustment at the beginning of the function.
|
|
||||||
Undo that for the recursion. */
|
|
||||||
glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
|
glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
|
||||||
oi, retaddr + GETPC_ADJ);
|
oi, retaddr);
|
||||||
if (env->invalid_error != UC_ERR_OK)
|
if (env->invalid_error != UC_ERR_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7569,12 +7569,12 @@ void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
|
||||||
* this purpose use the actual register value passed to us
|
* this purpose use the actual register value passed to us
|
||||||
* so that we get the fault address right.
|
* so that we get the fault address right.
|
||||||
*/
|
*/
|
||||||
helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETRA());
|
helper_ret_stb_mmu(env, vaddr_in, 0, oi, GETPC());
|
||||||
/* Now we can populate the other TLB entries, if any */
|
/* Now we can populate the other TLB entries, if any */
|
||||||
for (i = 0; i < maxidx; i++) {
|
for (i = 0; i < maxidx; i++) {
|
||||||
uint64_t va = vaddr + TARGET_PAGE_SIZE * i;
|
uint64_t va = vaddr + TARGET_PAGE_SIZE * i;
|
||||||
if (va != (vaddr_in & TARGET_PAGE_MASK)) {
|
if (va != (vaddr_in & TARGET_PAGE_MASK)) {
|
||||||
helper_ret_stb_mmu(env, va, 0, oi, GETRA());
|
helper_ret_stb_mmu(env, va, 0, oi, GETPC());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7591,7 +7591,7 @@ void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
|
||||||
* bounce buffer was in use
|
* bounce buffer was in use
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < blocklen; i++) {
|
for (i = 0; i < blocklen; i++) {
|
||||||
helper_ret_stb_mmu(env, vaddr + i, 0, oi, GETRA());
|
helper_ret_stb_mmu(env, vaddr + i, 0, oi, GETPC());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -4135,17 +4135,17 @@ void helper_msa_st_ ## TYPE(CPUMIPSState *env, uint32_t wd, \
|
||||||
int mmu_idx = cpu_mmu_index(env, false); \
|
int mmu_idx = cpu_mmu_index(env, false); \
|
||||||
int i; \
|
int i; \
|
||||||
MEMOP_IDX(DF) \
|
MEMOP_IDX(DF) \
|
||||||
ensure_writable_pages(env, addr, mmu_idx, GETRA()); \
|
ensure_writable_pages(env, addr, mmu_idx, GETPC()); \
|
||||||
for (i = 0; i < DF_ELEMENTS(DF); i++) { \
|
for (i = 0; i < DF_ELEMENTS(DF); i++) { \
|
||||||
ST_INSN(env, addr + (i << DF), pwd->TYPE[i], ##__VA_ARGS__); \
|
ST_INSN(env, addr + (i << DF), pwd->TYPE[i], ##__VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
MSA_ST_DF(DF_BYTE, b, helper_ret_stb_mmu, oi, GETRA())
|
MSA_ST_DF(DF_BYTE, b, helper_ret_stb_mmu, oi, GETPC())
|
||||||
MSA_ST_DF(DF_HALF, h, helper_ret_stw_mmu, oi, GETRA())
|
MSA_ST_DF(DF_HALF, h, helper_ret_stw_mmu, oi, GETPC())
|
||||||
MSA_ST_DF(DF_WORD, w, helper_ret_stl_mmu, oi, GETRA())
|
MSA_ST_DF(DF_WORD, w, helper_ret_stl_mmu, oi, GETPC())
|
||||||
MSA_ST_DF(DF_DOUBLE, d, helper_ret_stq_mmu, oi, GETRA())
|
MSA_ST_DF(DF_DOUBLE, d, helper_ret_stq_mmu, oi, GETPC())
|
||||||
#else
|
#else
|
||||||
MSA_ST_DF(DF_BYTE, b, cpu_stb_data)
|
MSA_ST_DF(DF_BYTE, b, cpu_stb_data)
|
||||||
MSA_ST_DF(DF_HALF, h, cpu_stw_data)
|
MSA_ST_DF(DF_HALF, h, cpu_stw_data)
|
||||||
|
@ -4155,10 +4155,10 @@ MSA_ST_DF(DF_DOUBLE, d, cpu_stq_data)
|
||||||
|
|
||||||
|
|
||||||
#if !defined(CONFIG_USER_ONLY)
|
#if !defined(CONFIG_USER_ONLY)
|
||||||
MSA_LD_DF(DF_BYTE, b, helper_ret_ldub_mmu, oi, GETRA())
|
MSA_LD_DF(DF_BYTE, b, helper_ret_ldub_mmu, oi, GETPC())
|
||||||
MSA_LD_DF(DF_HALF, h, helper_ret_lduw_mmu, oi, GETRA())
|
MSA_LD_DF(DF_HALF, h, helper_ret_lduw_mmu, oi, GETPC())
|
||||||
MSA_LD_DF(DF_WORD, w, helper_ret_ldul_mmu, oi, GETRA())
|
MSA_LD_DF(DF_WORD, w, helper_ret_ldul_mmu, oi, GETPC())
|
||||||
MSA_LD_DF(DF_DOUBLE, d, helper_ret_ldq_mmu, oi, GETRA())
|
MSA_LD_DF(DF_DOUBLE, d, helper_ret_ldq_mmu, oi, GETPC())
|
||||||
#else
|
#else
|
||||||
MSA_LD_DF(DF_BYTE, b, cpu_ldub_data)
|
MSA_LD_DF(DF_BYTE, b, cpu_ldub_data)
|
||||||
MSA_LD_DF(DF_HALF, h, cpu_lduw_data)
|
MSA_LD_DF(DF_HALF, h, cpu_lduw_data)
|
||||||
|
|
|
@ -251,6 +251,8 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
|
||||||
int64_t ti = profile_getclock();
|
int64_t ti = profile_getclock();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
searched_pc -= GETPC_ADJ;
|
||||||
|
|
||||||
if (searched_pc < host_pc) {
|
if (searched_pc < host_pc) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue