[PATCH 13/23] target/riscv: Use vext_ldst_us in vext_ldst_whole
Richard Henderson <[email protected]>
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <[email protected]> |
This eliminates the last use of probe_pages. Signed-off-by: Richard Henderson <[email protected]> --- target/riscv/tcg/vector_helper.c | 120 +------------------------------ 1 file changed, 3 insertions(+), 117 deletions(-) diff --git a/target/riscv/tcg/vector_helper.c b/target/riscv/tcg/vector_helper.c index abb1ebcb43..178ed32429 100644 --- a/target/riscv/tcg/vector_helper.c +++ b/target/riscv/tcg/vector_helper.c @@ -149,50 +149,6 @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz) return scale < 0 ? vlenb >> -scale : vlenb << scale; } -/* - * This function checks watchpoint before real load operation. - * - * In system mode, the TLB API probe_access is enough for watchpoint check. - * In user mode, there is no watchpoint support now. - * - * It will trigger an exception if there is no mapping in TLB - * and page table walk can't fill the TLB entry. Then the guest - * software can return here after process the exception or never return. - * - * This function can also be used when direct access to probe_access_flags is - * needed in order to access the flags. If a pointer to a flags operand is - * provided the function will call probe_access_flags instead, use nonfault - * and update host and flags. - */ -static void probe_pages(CPURISCVState *env, target_ulong addr, target_ulong len, - uintptr_t ra, MMUAccessType access_type, int mmu_index, - void **host, int *flags, bool nonfault) -{ - target_ulong pagelen = -(addr | TARGET_PAGE_MASK); - target_ulong curlen = MIN(pagelen, len); - - if (flags != NULL) { - *flags = probe_access_flags(env, adjust_addr(env, addr), curlen, - access_type, mmu_index, nonfault, host, ra); - } else { - probe_access(env, adjust_addr(env, addr), curlen, access_type, - mmu_index, ra); - } - - if (len > curlen) { - addr += curlen; - curlen = len - curlen; - if (flags != NULL) { - *flags |= probe_access_flags(env, adjust_addr(env, addr), curlen, - access_type, mmu_index, nonfault, - host, ra); - } else { - probe_access(env, adjust_addr(env, addr), curlen, access_type, - mmu_index, ra); - } - } -} - static inline void vext_set_elem_mask(void *v0, int index, uint8_t value) { @@ -436,33 +392,6 @@ vext_page_ldst_us_tlb(CPURISCVState *env, void *vd, target_ulong addr, } while (i < evl); } -static inline QEMU_ALWAYS_INLINE void -vext_page_ldst_us(CPURISCVState *env, void *vd, target_ulong addr, - uint32_t elems, uint32_t nf, uint32_t max_elems, - uint32_t log2_esz, bool is_load, int mmu_index, - vext_ldst_elem_fn_tlb *ldst_tlb, - vext_ldst_elem_fn_host *ldst_host, uintptr_t ra) -{ - void *host; - int flags; - uint32_t size = (elems * nf) << log2_esz; - uint32_t i = env->vstart; - MMUAccessType access_type = is_load ? MMU_DATA_LOAD : MMU_DATA_STORE; - - /* Check page permission/pmp/watchpoint/etc. */ - probe_pages(env, addr, size, ra, access_type, mmu_index, &host, &flags, - true); - - if (flags == 0) { - vext_page_ldst_us_host(vd, host, i, i + elems, nf, - log2_esz, max_elems, ldst_host); - env->vstart += elems; - } else { - vext_page_ldst_us_tlb(env, vd, addr, i, i + elems, nf, log2_esz, - max_elems, ldst_tlb, mmu_index, ra); - } -} - static void vext_test_alignment(CPURISCVState *env, vaddr addr, uint32_t esz, MMUAccessType access_type, int mmu_index, uintptr_t ra) @@ -1026,53 +955,10 @@ vext_ldst_whole(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc, vext_ldst_elem_fn_host *ldst_host, uint32_t log2_esz, uintptr_t ra, bool is_load) { - target_ulong page_split, elems, addr; - uint32_t nf = vext_nf(desc); - uint32_t vlenb = riscv_cpu_cfg(env)->vlenb; - uint32_t max_elems = vlenb >> log2_esz; - uint32_t evl = nf * max_elems; - uint32_t esz = 1 << log2_esz; - int mmu_index = riscv_env_mmu_index(env, false); - MMUAccessType access_type = is_load ? MMU_DATA_LOAD : MMU_DATA_STORE; + uint32_t evl = (riscv_cpu_cfg(env)->vlenb * vext_nf(desc)) >> log2_esz; - /* Calculate the page range of first page */ - addr = base + (env->vstart << log2_esz); - - /* Recognize alignment fault before memory protection fault. */ - vext_test_alignment(env, addr, esz, access_type, mmu_index, ra); - - page_split = -(addr | TARGET_PAGE_MASK); - /* Get number of elements */ - elems = page_split / esz; - if (unlikely(env->vstart + elems >= evl)) { - elems = evl - env->vstart; - } - - /* Load/store elements in the first page */ - if (likely(elems)) { - vext_page_ldst_us(env, vd, addr, elems, 1, max_elems, log2_esz, - is_load, mmu_index, ldst_tlb, ldst_host, ra); - } - - /* Load/store elements in the second page */ - if (unlikely(env->vstart < evl)) { - /* Cross page element */ - if (unlikely(page_split % esz)) { - addr = base + (env->vstart << log2_esz); - ldst_tlb(env, adjust_addr(env, addr), env->vstart, vd, ra); - env->vstart++; - } - - addr = base + (env->vstart << log2_esz); - /* Get number of elements of second page */ - elems = evl - env->vstart; - - /* Load/store elements in the second page */ - vext_page_ldst_us(env, vd, addr, elems, 1, max_elems, log2_esz, - is_load, mmu_index, ldst_tlb, ldst_host, ra); - } - - env->vstart = 0; + vext_ldst_us(vd, base, env, log2_esz, 1, evl, evl, false, + ldst_tlb, ldst_host, ra, is_load); } #define GEN_VEXT_LD_WHOLE(NAME, ETYPE, LOAD_FN_TLB, LOAD_FN_HOST) \ -- 2.43.0