tcg: Add tlb_index and tlb_entry helpers

Isolate the computation of an index from an address into a
helper before we change that function.

Backports commit 383beda9cf32f795616c3b93f7d6154d70372d4b from qemu
This commit is contained in:
Richard Henderson 2018-10-23 15:02:42 -04:00 committed by Lioncash
parent dfb3954571
commit c911ea7128
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
4 changed files with 75 additions and 61 deletions

View file

@ -91,7 +91,6 @@ void tlb_flush(CPUState *cpu)
void tlb_flush_page(CPUState *cpu, target_ulong addr) void tlb_flush_page(CPUState *cpu, target_ulong addr)
{ {
CPUArchState *env = cpu->env_ptr; CPUArchState *env = cpu->env_ptr;
int i;
int mmu_idx; int mmu_idx;
tlb_debug("page :" TARGET_FMT_lx "\n", addr); tlb_debug("page :" TARGET_FMT_lx "\n", addr);
@ -107,9 +106,8 @@ void tlb_flush_page(CPUState *cpu, target_ulong addr)
} }
addr &= TARGET_PAGE_MASK; addr &= TARGET_PAGE_MASK;
i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) { for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
tlb_flush_entry(&env->tlb_table[mmu_idx][i], addr); tlb_flush_entry(tlb_entry(env, mmu_idx, addr), addr);
} }
/* check whether there are entries that need to be flushed in the vtlb */ /* check whether there are entries that need to be flushed in the vtlb */
@ -163,13 +161,11 @@ void tlb_reset_dirty(CPUState *cpu, ram_addr_t start1, ram_addr_t length)
void tlb_set_dirty(CPUState *cpu, target_ulong vaddr) void tlb_set_dirty(CPUState *cpu, target_ulong vaddr)
{ {
CPUArchState *env = cpu->env_ptr; CPUArchState *env = cpu->env_ptr;
int i;
int mmu_idx; int mmu_idx;
vaddr &= TARGET_PAGE_MASK; vaddr &= TARGET_PAGE_MASK;
i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) { for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
tlb_set_dirty1(&env->tlb_table[mmu_idx][i], vaddr); tlb_set_dirty1(tlb_entry(env, mmu_idx, vaddr), vaddr);
} }
for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) { for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
@ -306,7 +302,9 @@ static ram_addr_t qemu_ram_addr_from_host_nofail(struct uc_struct *uc, void *ptr
*/ */
tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr) tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
{ {
int mmu_idx, index; uintptr_t mmu_idx = cpu_mmu_index(env, true);
uintptr_t index = tlb_index(env, mmu_idx, addr);
CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
void *p; void *p;
MemoryRegion *mr; MemoryRegion *mr;
MemoryRegionSection *section; MemoryRegionSection *section;
@ -315,9 +313,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
CPUIOTLBEntry *iotlbentry; CPUIOTLBEntry *iotlbentry;
hwaddr physaddr, mr_offset; hwaddr physaddr, mr_offset;
index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); if (unlikely(!tlb_hit(entry->addr_code, addr))) {
mmu_idx = cpu_mmu_index(env, true);
if (unlikely(!tlb_hit(env->tlb_table[mmu_idx][index].addr_code, addr))) {
cpu_ldub_code(env, addr); cpu_ldub_code(env, addr);
//check for NX related error from softmmu //check for NX related error from softmmu
if (env->invalid_error == UC_ERR_FETCH_PROT) { if (env->invalid_error == UC_ERR_FETCH_PROT) {
@ -353,7 +349,7 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
env->invalid_error = UC_ERR_FETCH_UNMAPPED; env->invalid_error = UC_ERR_FETCH_UNMAPPED;
return RAM_ADDR_INVALID; return RAM_ADDR_INVALID;
} }
p = (void *)((uintptr_t)addr + env->tlb_table[mmu_idx][index].addend); p = (void *)((uintptr_t)addr + entry->addend);
ram_addr = qemu_ram_addr_from_host_nofail(cpu->uc, p); ram_addr = qemu_ram_addr_from_host_nofail(cpu->uc, p);
if (ram_addr == RAM_ADDR_INVALID) { if (ram_addr == RAM_ADDR_INVALID) {
env->invalid_addr = addr; env->invalid_addr = addr;
@ -569,10 +565,10 @@ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index,
void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx, void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
uintptr_t retaddr) uintptr_t retaddr)
{ {
int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); uintptr_t index = tlb_index(env, mmu_idx, addr);
target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write; CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
if (!tlb_hit(tlb_addr, addr)) { if (!tlb_hit(entry->addr_write, addr)) {
/* TLB entry is for a different page */ /* TLB entry is for a different page */
if (!VICTIM_TLB_HIT(addr_write, addr)) { if (!VICTIM_TLB_HIT(addr_write, addr)) {
tlb_fill(ENV_GET_CPU(env), addr, size, MMU_DATA_STORE, tlb_fill(ENV_GET_CPU(env), addr, size, MMU_DATA_STORE,
@ -587,8 +583,8 @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
TCGMemOpIdx oi, uintptr_t retaddr) TCGMemOpIdx oi, uintptr_t retaddr)
{ {
size_t mmu_idx = get_mmuidx(oi); size_t mmu_idx = get_mmuidx(oi);
size_t index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); uintptr_t index = tlb_index(env, mmu_idx, addr);
CPUTLBEntry *tlbe = &env->tlb_table[mmu_idx][index]; CPUTLBEntry *tlbe = tlb_entry(env, mmu_idx, addr);
target_ulong tlb_addr = tlbe->addr_write; target_ulong tlb_addr = tlbe->addr_write;
TCGMemOp mop = get_memop(oi); TCGMemOp mop = get_memop(oi);
int a_bits = get_alignment_bits(mop); int a_bits = get_alignment_bits(mop);

View file

@ -110,9 +110,10 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
TCGMemOpIdx oi, uintptr_t retaddr) TCGMemOpIdx oi, uintptr_t retaddr)
{ {
unsigned mmu_idx = get_mmuidx(oi); uintptr_t mmu_idx = get_mmuidx(oi);
int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); uintptr_t index = tlb_index(env, mmu_idx, addr);
target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
target_ulong tlb_addr = entry->ADDR_READ;
unsigned a_bits = get_alignment_bits(get_memop(oi)); unsigned a_bits = get_alignment_bits(get_memop(oi));
uintptr_t haddr; uintptr_t haddr;
DATA_TYPE res; DATA_TYPE res;
@ -224,7 +225,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, READ_ACCESS_TYPE, tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, READ_ACCESS_TYPE,
mmu_idx, retaddr); mmu_idx, retaddr);
} }
tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; tlb_addr = entry->ADDR_READ;
} }
/* Handle an IO access. */ /* Handle an IO access. */
@ -270,7 +271,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
goto _out; goto _out;
} }
haddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][index].addend); haddr = (uintptr_t)(addr + entry->addend);
#if DATA_SIZE == 1 #if DATA_SIZE == 1
res = glue(glue(ld, LSUFFIX), _p)((uint8_t *)haddr); res = glue(glue(ld, LSUFFIX), _p)((uint8_t *)haddr);
#else #else
@ -294,9 +295,10 @@ _out:
WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
TCGMemOpIdx oi, uintptr_t retaddr) TCGMemOpIdx oi, uintptr_t retaddr)
{ {
unsigned mmu_idx = get_mmuidx(oi); uintptr_t mmu_idx = get_mmuidx(oi);
int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); uintptr_t index = tlb_index(env, mmu_idx, addr);
target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
target_ulong tlb_addr = entry->ADDR_READ;
unsigned a_bits = get_alignment_bits(get_memop(oi)); unsigned a_bits = get_alignment_bits(get_memop(oi));
uintptr_t haddr; uintptr_t haddr;
DATA_TYPE res; DATA_TYPE res;
@ -408,7 +410,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, READ_ACCESS_TYPE, tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, READ_ACCESS_TYPE,
mmu_idx, retaddr); mmu_idx, retaddr);
} }
tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ; tlb_addr = entry->ADDR_READ;
} }
/* Handle an IO access. */ /* Handle an IO access. */
@ -453,7 +455,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
goto _out; goto _out;
} }
haddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][index].addend); haddr = (uintptr_t)(addr + entry->addend);
res = glue(glue(ld, LSUFFIX), _be_p)((uint8_t *)haddr); res = glue(glue(ld, LSUFFIX), _be_p)((uint8_t *)haddr);
_out: _out:
@ -503,9 +505,10 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
TCGMemOpIdx oi, uintptr_t retaddr) TCGMemOpIdx oi, uintptr_t retaddr)
{ {
unsigned mmu_idx = get_mmuidx(oi); uintptr_t mmu_idx = get_mmuidx(oi);
int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); uintptr_t index = tlb_index(env, mmu_idx, addr);
target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write; CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
target_ulong tlb_addr = entry->addr_write;
unsigned a_bits = get_alignment_bits(get_memop(oi)); unsigned a_bits = get_alignment_bits(get_memop(oi));
uintptr_t haddr; uintptr_t haddr;
struct hook *hook; struct hook *hook;
@ -577,7 +580,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE, tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE,
mmu_idx, retaddr); mmu_idx, retaddr);
} }
tlb_addr = env->tlb_table[mmu_idx][index].addr_write; tlb_addr = entry->addr_write;
} }
/* Handle an IO access. */ /* Handle an IO access. */
@ -606,16 +609,16 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
if (DATA_SIZE > 1 if (DATA_SIZE > 1
&& unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1 && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
>= TARGET_PAGE_SIZE)) { >= TARGET_PAGE_SIZE)) {
int i, index2; int i;
target_ulong page2, tlb_addr2; target_ulong page2;
CPUTLBEntry *entry2;
do_unaligned_access: do_unaligned_access:
/* Ensure the second page is in the TLB. Note that the first page /* Ensure the second page is in the TLB. Note that the first page
is already guaranteed to be filled, and that the second page is already guaranteed to be filled, and that the second page
cannot evict the first. */ cannot evict the first. */
page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK; page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK;
index2 = (page2 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); entry2 = tlb_entry(env, mmu_idx, page2);
tlb_addr2 = env->tlb_table[mmu_idx][index2].addr_write; if (!tlb_hit_page(entry2->addr_write, page2)
if (!tlb_hit_page(tlb_addr2, page2)
&& !VICTIM_TLB_HIT(addr_write, page2)) { && !VICTIM_TLB_HIT(addr_write, page2)) {
tlb_fill(ENV_GET_CPU(env), page2, DATA_SIZE, MMU_DATA_STORE, tlb_fill(ENV_GET_CPU(env), page2, DATA_SIZE, MMU_DATA_STORE,
mmu_idx, retaddr); mmu_idx, retaddr);
@ -635,7 +638,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
return; return;
} }
haddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][index].addend); haddr = (uintptr_t)(addr + entry->addend);
#if DATA_SIZE == 1 #if DATA_SIZE == 1
glue(glue(st, SUFFIX), _p)((uint8_t *)haddr, val); glue(glue(st, SUFFIX), _p)((uint8_t *)haddr, val);
#else #else
@ -647,9 +650,10 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val, void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
TCGMemOpIdx oi, uintptr_t retaddr) TCGMemOpIdx oi, uintptr_t retaddr)
{ {
unsigned mmu_idx = get_mmuidx(oi); uintptr_t mmu_idx = get_mmuidx(oi);
int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); uintptr_t index = tlb_index(env, mmu_idx, addr);
target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write; CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr);
target_ulong tlb_addr = entry->addr_write;
unsigned a_bits = get_alignment_bits(get_memop(oi)); unsigned a_bits = get_alignment_bits(get_memop(oi));
uintptr_t haddr; uintptr_t haddr;
struct hook *hook; struct hook *hook;
@ -721,7 +725,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE, tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE,
mmu_idx, retaddr); mmu_idx, retaddr);
} }
tlb_addr = env->tlb_table[mmu_idx][index].addr_write; tlb_addr = entry->addr_write;
} }
/* Handle an IO access. */ /* Handle an IO access. */
@ -750,16 +754,16 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
if (DATA_SIZE > 1 if (DATA_SIZE > 1
&& unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1 && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
>= TARGET_PAGE_SIZE)) { >= TARGET_PAGE_SIZE)) {
int i, index2; int i;
target_ulong page2, tlb_addr2; target_ulong page2;
CPUTLBEntry *entry2;
do_unaligned_access: do_unaligned_access:
/* Ensure the second page is in the TLB. Note that the first page /* Ensure the second page is in the TLB. Note that the first page
is already guaranteed to be filled, and that the second page is already guaranteed to be filled, and that the second page
cannot evict the first. */ cannot evict the first. */
page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK; page2 = (addr + DATA_SIZE) & TARGET_PAGE_MASK;
index2 = (page2 >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); entry2 = tlb_entry(env, mmu_idx, page2);
tlb_addr2 = env->tlb_table[mmu_idx][index2].addr_write; if (!tlb_hit_page(entry2->addr_write, page2)
if (!tlb_hit_page(tlb_addr2, page2)
&& !VICTIM_TLB_HIT(addr_write, page2)) { && !VICTIM_TLB_HIT(addr_write, page2)) {
tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE, tlb_fill(ENV_GET_CPU(env), addr, DATA_SIZE, MMU_DATA_STORE,
mmu_idx, retaddr); mmu_idx, retaddr);
@ -779,7 +783,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
return; return;
} }
haddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][index].addend); haddr = (uintptr_t)(addr + entry->addend);
glue(glue(st, SUFFIX), _be_p)((uint8_t *)haddr, val); glue(glue(st, SUFFIX), _be_p)((uint8_t *)haddr, val);
} }
#endif /* DATA_SIZE > 1 */ #endif /* DATA_SIZE > 1 */

View file

@ -163,6 +163,20 @@
/* The memory helpers for tcg-generated code need tcg_target_long etc. */ /* The memory helpers for tcg-generated code need tcg_target_long etc. */
#include "tcg.h" #include "tcg.h"
/* Find the TLB index corresponding to the mmu_idx + address pair. */
static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx,
target_ulong addr)
{
return (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
}
/* Find the TLB entry corresponding to the mmu_idx + address pair. */
static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx,
target_ulong addr)
{
return &env->tlb_table[mmu_idx][tlb_index(env, mmu_idx, addr)];
}
#define CPU_MMU_INDEX 0 #define CPU_MMU_INDEX 0
#define MEMSUFFIX MMU_MODE0_SUFFIX #define MEMSUFFIX MMU_MODE0_SUFFIX
#define DATA_SIZE 1 #define DATA_SIZE 1
@ -461,8 +475,7 @@ static inline void *tlb_vaddr_to_host(CPUArchState *env, target_ulong addr,
#if defined(CONFIG_USER_ONLY) #if defined(CONFIG_USER_ONLY)
return g2h(addr); return g2h(addr);
#else #else
int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); CPUTLBEntry *tlbentry = tlb_entry(env, mmu_idx, addr);
CPUTLBEntry *tlbentry = &env->tlb_table[mmu_idx][index];
target_ulong tlb_addr; target_ulong tlb_addr;
uintptr_t haddr; uintptr_t haddr;
@ -490,7 +503,7 @@ static inline void *tlb_vaddr_to_host(CPUArchState *env, target_ulong addr,
return NULL; return NULL;
} }
haddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][index].addend); haddr = (uintptr_t)(addr + tlbentry->addend);
return (void *)haddr; return (void *)haddr;
#endif /* defined(CONFIG_USER_ONLY) */ #endif /* defined(CONFIG_USER_ONLY) */
} }

View file

@ -76,22 +76,22 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
target_ulong ptr, target_ulong ptr,
uintptr_t retaddr) uintptr_t retaddr)
{ {
int page_index; CPUTLBEntry *entry;
RES_TYPE res; RES_TYPE res;
target_ulong addr; target_ulong addr;
int mmu_idx; int mmu_idx;
TCGMemOpIdx oi; TCGMemOpIdx oi;
addr = ptr; addr = ptr;
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = CPU_MMU_INDEX; mmu_idx = CPU_MMU_INDEX;
if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ != entry = tlb_entry(env, mmu_idx, addr);
if (unlikely(entry->ADDR_READ !=
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
oi = make_memop_idx(SHIFT, mmu_idx); oi = make_memop_idx(SHIFT, mmu_idx);
res = glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr, res = glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr,
oi, retaddr); oi, retaddr);
} else { } else {
uintptr_t hostaddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][page_index].addend); uintptr_t hostaddr = (uintptr_t)(addr + entry->addend);
res = glue(glue(ld, USUFFIX), _raw)(hostaddr); res = glue(glue(ld, USUFFIX), _raw)(hostaddr);
} }
return res; return res;
@ -109,21 +109,22 @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
target_ulong ptr, target_ulong ptr,
uintptr_t retaddr) uintptr_t retaddr)
{ {
int res, page_index; CPUTLBEntry *entry;
int res;
target_ulong addr; target_ulong addr;
int mmu_idx; int mmu_idx;
TCGMemOpIdx oi; TCGMemOpIdx oi;
addr = ptr; addr = ptr;
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = CPU_MMU_INDEX; mmu_idx = CPU_MMU_INDEX;
if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ != entry = tlb_entry(env, mmu_idx, addr);
if (unlikely(entry->ADDR_READ !=
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
oi = make_memop_idx(SHIFT, mmu_idx); oi = make_memop_idx(SHIFT, mmu_idx);
res = (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX), res = (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX),
MMUSUFFIX)(env, addr, oi, retaddr); MMUSUFFIX)(env, addr, oi, retaddr);
} else { } else {
uintptr_t hostaddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][page_index].addend); uintptr_t hostaddr = (uintptr_t)(addr + entry->addend);
res = glue(glue(lds, SUFFIX), _raw)(hostaddr); res = glue(glue(lds, SUFFIX), _raw)(hostaddr);
} }
return res; return res;
@ -144,21 +145,21 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
target_ulong ptr, target_ulong ptr,
RES_TYPE v, uintptr_t retaddr) RES_TYPE v, uintptr_t retaddr)
{ {
int page_index; CPUTLBEntry *entry;
target_ulong addr; target_ulong addr;
int mmu_idx; int mmu_idx;
TCGMemOpIdx oi; TCGMemOpIdx oi;
addr = ptr; addr = ptr;
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = CPU_MMU_INDEX; mmu_idx = CPU_MMU_INDEX;
if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write != entry = tlb_entry(env, mmu_idx, addr);
if (unlikely(entry->addr_write !=
(addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
oi = make_memop_idx(SHIFT, mmu_idx); oi = make_memop_idx(SHIFT, mmu_idx);
glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, oi, glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, oi,
retaddr); retaddr);
} else { } else {
uintptr_t hostaddr = (uintptr_t)(addr + env->tlb_table[mmu_idx][page_index].addend); uintptr_t hostaddr = (uintptr_t)(addr + entry->addend);
glue(glue(st, SUFFIX), _raw)(hostaddr, v); glue(glue(st, SUFFIX), _raw)(hostaddr, v);
} }
} }