target/arm: Simplify sve mte checking

Now that mte_check1 and mte_checkN have been merged, we can
merge sve_cont_ldst_mte_check1 and sve_cont_ldst_mte_checkN.

Which means that we can eliminate the function pointer into
sve_ldN_r and sve_stN_r, calling sve_cont_ldst_mte_check directly.

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20210416183106.1516563-9-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Richard Henderson 2021-04-16 11:31:05 -07:00 committed by Peter Maydell
parent d304d280b3
commit 4c3310c73f
1 changed files with 26 additions and 58 deletions

View File

@ -4382,13 +4382,9 @@ static void sve_cont_ldst_watchpoints(SVEContLdSt *info, CPUARMState *env,
#endif #endif
} }
typedef uint64_t mte_check_fn(CPUARMState *, uint32_t, uint64_t, uintptr_t); static void sve_cont_ldst_mte_check(SVEContLdSt *info, CPUARMState *env,
uint64_t *vg, target_ulong addr, int esize,
static inline QEMU_ALWAYS_INLINE int msize, uint32_t mtedesc, uintptr_t ra)
void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
uint64_t *vg, target_ulong addr, int esize,
int msize, uint32_t mtedesc, uintptr_t ra,
mte_check_fn *check)
{ {
intptr_t mem_off, reg_off, reg_last; intptr_t mem_off, reg_off, reg_last;
@ -4405,7 +4401,7 @@ void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
uint64_t pg = vg[reg_off >> 6]; uint64_t pg = vg[reg_off >> 6];
do { do {
if ((pg >> (reg_off & 63)) & 1) { if ((pg >> (reg_off & 63)) & 1) {
check(env, mtedesc, addr, ra); mte_check(env, mtedesc, addr, ra);
} }
reg_off += esize; reg_off += esize;
mem_off += msize; mem_off += msize;
@ -4422,7 +4418,7 @@ void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
uint64_t pg = vg[reg_off >> 6]; uint64_t pg = vg[reg_off >> 6];
do { do {
if ((pg >> (reg_off & 63)) & 1) { if ((pg >> (reg_off & 63)) & 1) {
check(env, mtedesc, addr, ra); mte_check(env, mtedesc, addr, ra);
} }
reg_off += esize; reg_off += esize;
mem_off += msize; mem_off += msize;
@ -4431,30 +4427,6 @@ void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
} }
} }
typedef void sve_cont_ldst_mte_check_fn(SVEContLdSt *info, CPUARMState *env,
uint64_t *vg, target_ulong addr,
int esize, int msize, uint32_t mtedesc,
uintptr_t ra);
static void sve_cont_ldst_mte_check1(SVEContLdSt *info, CPUARMState *env,
uint64_t *vg, target_ulong addr,
int esize, int msize, uint32_t mtedesc,
uintptr_t ra)
{
sve_cont_ldst_mte_check_int(info, env, vg, addr, esize, msize,
mtedesc, ra, mte_check);
}
static void sve_cont_ldst_mte_checkN(SVEContLdSt *info, CPUARMState *env,
uint64_t *vg, target_ulong addr,
int esize, int msize, uint32_t mtedesc,
uintptr_t ra)
{
sve_cont_ldst_mte_check_int(info, env, vg, addr, esize, msize,
mtedesc, ra, mte_check);
}
/* /*
* Common helper for all contiguous 1,2,3,4-register predicated stores. * Common helper for all contiguous 1,2,3,4-register predicated stores.
*/ */
@ -4463,8 +4435,7 @@ void sve_ldN_r(CPUARMState *env, uint64_t *vg, const target_ulong addr,
uint32_t desc, const uintptr_t retaddr, uint32_t desc, const uintptr_t retaddr,
const int esz, const int msz, const int N, uint32_t mtedesc, const int esz, const int msz, const int N, uint32_t mtedesc,
sve_ldst1_host_fn *host_fn, sve_ldst1_host_fn *host_fn,
sve_ldst1_tlb_fn *tlb_fn, sve_ldst1_tlb_fn *tlb_fn)
sve_cont_ldst_mte_check_fn *mte_check_fn)
{ {
const unsigned rd = simd_data(desc); const unsigned rd = simd_data(desc);
const intptr_t reg_max = simd_oprsz(desc); const intptr_t reg_max = simd_oprsz(desc);
@ -4493,9 +4464,9 @@ void sve_ldN_r(CPUARMState *env, uint64_t *vg, const target_ulong addr,
* Handle mte checks for all active elements. * Handle mte checks for all active elements.
* Since TBI must be set for MTE, !mtedesc => !mte_active. * Since TBI must be set for MTE, !mtedesc => !mte_active.
*/ */
if (mte_check_fn && mtedesc) { if (mtedesc) {
mte_check_fn(&info, env, vg, addr, 1 << esz, N << msz, sve_cont_ldst_mte_check(&info, env, vg, addr, 1 << esz, N << msz,
mtedesc, retaddr); mtedesc, retaddr);
} }
flags = info.page[0].flags | info.page[1].flags; flags = info.page[0].flags | info.page[1].flags;
@ -4621,8 +4592,7 @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
mtedesc = 0; mtedesc = 0;
} }
sve_ldN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn, sve_ldN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn);
N == 1 ? sve_cont_ldst_mte_check1 : sve_cont_ldst_mte_checkN);
} }
#define DO_LD1_1(NAME, ESZ) \ #define DO_LD1_1(NAME, ESZ) \
@ -4630,7 +4600,7 @@ void HELPER(sve_##NAME##_r)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \
{ \ { \
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, MO_8, 1, 0, \ sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, MO_8, 1, 0, \
sve_##NAME##_host, sve_##NAME##_tlb, NULL); \ sve_##NAME##_host, sve_##NAME##_tlb); \
} \ } \
void HELPER(sve_##NAME##_r_mte)(CPUARMState *env, void *vg, \ void HELPER(sve_##NAME##_r_mte)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \
@ -4644,22 +4614,22 @@ void HELPER(sve_##NAME##_le_r)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \
{ \ { \
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, 0, \ sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, 0, \
sve_##NAME##_le_host, sve_##NAME##_le_tlb, NULL); \ sve_##NAME##_le_host, sve_##NAME##_le_tlb); \
} \ } \
void HELPER(sve_##NAME##_be_r)(CPUARMState *env, void *vg, \ void HELPER(sve_##NAME##_be_r)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \
{ \ { \
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, 0, \ sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, 0, \
sve_##NAME##_be_host, sve_##NAME##_be_tlb, NULL); \ sve_##NAME##_be_host, sve_##NAME##_be_tlb); \
} \ } \
void HELPER(sve_##NAME##_le_r_mte)(CPUARMState *env, void *vg, \ void HELPER(sve_##NAME##_le_r_mte)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \
{ \ { \
sve_ldN_r_mte(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, \ sve_ldN_r_mte(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, \
sve_##NAME##_le_host, sve_##NAME##_le_tlb); \ sve_##NAME##_le_host, sve_##NAME##_le_tlb); \
} \ } \
void HELPER(sve_##NAME##_be_r_mte)(CPUARMState *env, void *vg, \ void HELPER(sve_##NAME##_be_r_mte)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \
{ \ { \
sve_ldN_r_mte(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, \ sve_ldN_r_mte(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, \
sve_##NAME##_be_host, sve_##NAME##_be_tlb); \ sve_##NAME##_be_host, sve_##NAME##_be_tlb); \
@ -4693,7 +4663,7 @@ void HELPER(sve_ld##N##bb_r)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \
{ \ { \
sve_ldN_r(env, vg, addr, desc, GETPC(), MO_8, MO_8, N, 0, \ sve_ldN_r(env, vg, addr, desc, GETPC(), MO_8, MO_8, N, 0, \
sve_ld1bb_host, sve_ld1bb_tlb, NULL); \ sve_ld1bb_host, sve_ld1bb_tlb); \
} \ } \
void HELPER(sve_ld##N##bb_r_mte)(CPUARMState *env, void *vg, \ void HELPER(sve_ld##N##bb_r_mte)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \
@ -4707,13 +4677,13 @@ void HELPER(sve_ld##N##SUFF##_le_r)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \
{ \ { \
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, ESZ, N, 0, \ sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, ESZ, N, 0, \
sve_ld1##SUFF##_le_host, sve_ld1##SUFF##_le_tlb, NULL); \ sve_ld1##SUFF##_le_host, sve_ld1##SUFF##_le_tlb); \
} \ } \
void HELPER(sve_ld##N##SUFF##_be_r)(CPUARMState *env, void *vg, \ void HELPER(sve_ld##N##SUFF##_be_r)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \
{ \ { \
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, ESZ, N, 0, \ sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, ESZ, N, 0, \
sve_ld1##SUFF##_be_host, sve_ld1##SUFF##_be_tlb, NULL); \ sve_ld1##SUFF##_be_host, sve_ld1##SUFF##_be_tlb); \
} \ } \
void HELPER(sve_ld##N##SUFF##_le_r_mte)(CPUARMState *env, void *vg, \ void HELPER(sve_ld##N##SUFF##_le_r_mte)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \
@ -5090,8 +5060,7 @@ void sve_stN_r(CPUARMState *env, uint64_t *vg, target_ulong addr,
uint32_t desc, const uintptr_t retaddr, uint32_t desc, const uintptr_t retaddr,
const int esz, const int msz, const int N, uint32_t mtedesc, const int esz, const int msz, const int N, uint32_t mtedesc,
sve_ldst1_host_fn *host_fn, sve_ldst1_host_fn *host_fn,
sve_ldst1_tlb_fn *tlb_fn, sve_ldst1_tlb_fn *tlb_fn)
sve_cont_ldst_mte_check_fn *mte_check_fn)
{ {
const unsigned rd = simd_data(desc); const unsigned rd = simd_data(desc);
const intptr_t reg_max = simd_oprsz(desc); const intptr_t reg_max = simd_oprsz(desc);
@ -5117,9 +5086,9 @@ void sve_stN_r(CPUARMState *env, uint64_t *vg, target_ulong addr,
* Handle mte checks for all active elements. * Handle mte checks for all active elements.
* Since TBI must be set for MTE, !mtedesc => !mte_active. * Since TBI must be set for MTE, !mtedesc => !mte_active.
*/ */
if (mte_check_fn && mtedesc) { if (mtedesc) {
mte_check_fn(&info, env, vg, addr, 1 << esz, N << msz, sve_cont_ldst_mte_check(&info, env, vg, addr, 1 << esz, N << msz,
mtedesc, retaddr); mtedesc, retaddr);
} }
flags = info.page[0].flags | info.page[1].flags; flags = info.page[0].flags | info.page[1].flags;
@ -5233,8 +5202,7 @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
mtedesc = 0; mtedesc = 0;
} }
sve_stN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn, sve_stN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn);
N == 1 ? sve_cont_ldst_mte_check1 : sve_cont_ldst_mte_checkN);
} }
#define DO_STN_1(N, NAME, ESZ) \ #define DO_STN_1(N, NAME, ESZ) \
@ -5242,7 +5210,7 @@ void HELPER(sve_st##N##NAME##_r)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \
{ \ { \
sve_stN_r(env, vg, addr, desc, GETPC(), ESZ, MO_8, N, 0, \ sve_stN_r(env, vg, addr, desc, GETPC(), ESZ, MO_8, N, 0, \
sve_st1##NAME##_host, sve_st1##NAME##_tlb, NULL); \ sve_st1##NAME##_host, sve_st1##NAME##_tlb); \
} \ } \
void HELPER(sve_st##N##NAME##_r_mte)(CPUARMState *env, void *vg, \ void HELPER(sve_st##N##NAME##_r_mte)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \
@ -5256,13 +5224,13 @@ void HELPER(sve_st##N##NAME##_le_r)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \
{ \ { \
sve_stN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, N, 0, \ sve_stN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, N, 0, \
sve_st1##NAME##_le_host, sve_st1##NAME##_le_tlb, NULL); \ sve_st1##NAME##_le_host, sve_st1##NAME##_le_tlb); \
} \ } \
void HELPER(sve_st##N##NAME##_be_r)(CPUARMState *env, void *vg, \ void HELPER(sve_st##N##NAME##_be_r)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \
{ \ { \
sve_stN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, N, 0, \ sve_stN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, N, 0, \
sve_st1##NAME##_be_host, sve_st1##NAME##_be_tlb, NULL); \ sve_st1##NAME##_be_host, sve_st1##NAME##_be_tlb); \
} \ } \
void HELPER(sve_st##N##NAME##_le_r_mte)(CPUARMState *env, void *vg, \ void HELPER(sve_st##N##NAME##_le_r_mte)(CPUARMState *env, void *vg, \
target_ulong addr, uint32_t desc) \ target_ulong addr, uint32_t desc) \