mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 00:03:54 -06:00
target/arm: Split out load/store primitives to sve_ldst_internal.h
Begin creation of sve_ldst_internal.h by moving the primitives that access host and tlb memory. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20220607203306.657998-14-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
5ef3cc5636
commit
d1ce862602
2 changed files with 128 additions and 106 deletions
|
@ -21,12 +21,12 @@
|
|||
#include "cpu.h"
|
||||
#include "internals.h"
|
||||
#include "exec/exec-all.h"
|
||||
#include "exec/cpu_ldst.h"
|
||||
#include "exec/helper-proto.h"
|
||||
#include "tcg/tcg-gvec-desc.h"
|
||||
#include "fpu/softfloat.h"
|
||||
#include "tcg/tcg.h"
|
||||
#include "vec_internal.h"
|
||||
#include "sve_ldst_internal.h"
|
||||
|
||||
|
||||
/* Return a value for NZCV as per the ARM PredTest pseudofunction.
|
||||
|
@ -5301,111 +5301,6 @@ void HELPER(sve_fcmla_zpzzz_d)(void *vd, void *vn, void *vm, void *va,
|
|||
* Load contiguous data, protected by a governing predicate.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Load one element into @vd + @reg_off from @host.
|
||||
* The controlling predicate is known to be true.
|
||||
*/
|
||||
typedef void sve_ldst1_host_fn(void *vd, intptr_t reg_off, void *host);
|
||||
|
||||
/*
|
||||
* Load one element into @vd + @reg_off from (@env, @vaddr, @ra).
|
||||
* The controlling predicate is known to be true.
|
||||
*/
|
||||
typedef void sve_ldst1_tlb_fn(CPUARMState *env, void *vd, intptr_t reg_off,
|
||||
target_ulong vaddr, uintptr_t retaddr);
|
||||
|
||||
/*
|
||||
* Generate the above primitives.
|
||||
*/
|
||||
|
||||
#define DO_LD_HOST(NAME, H, TYPEE, TYPEM, HOST) \
|
||||
static void sve_##NAME##_host(void *vd, intptr_t reg_off, void *host) \
|
||||
{ \
|
||||
TYPEM val = HOST(host); \
|
||||
*(TYPEE *)(vd + H(reg_off)) = val; \
|
||||
}
|
||||
|
||||
#define DO_ST_HOST(NAME, H, TYPEE, TYPEM, HOST) \
|
||||
static void sve_##NAME##_host(void *vd, intptr_t reg_off, void *host) \
|
||||
{ HOST(host, (TYPEM)*(TYPEE *)(vd + H(reg_off))); }
|
||||
|
||||
#define DO_LD_TLB(NAME, H, TYPEE, TYPEM, TLB) \
|
||||
static void sve_##NAME##_tlb(CPUARMState *env, void *vd, intptr_t reg_off, \
|
||||
target_ulong addr, uintptr_t ra) \
|
||||
{ \
|
||||
*(TYPEE *)(vd + H(reg_off)) = \
|
||||
(TYPEM)TLB(env, useronly_clean_ptr(addr), ra); \
|
||||
}
|
||||
|
||||
#define DO_ST_TLB(NAME, H, TYPEE, TYPEM, TLB) \
|
||||
static void sve_##NAME##_tlb(CPUARMState *env, void *vd, intptr_t reg_off, \
|
||||
target_ulong addr, uintptr_t ra) \
|
||||
{ \
|
||||
TLB(env, useronly_clean_ptr(addr), \
|
||||
(TYPEM)*(TYPEE *)(vd + H(reg_off)), ra); \
|
||||
}
|
||||
|
||||
#define DO_LD_PRIM_1(NAME, H, TE, TM) \
|
||||
DO_LD_HOST(NAME, H, TE, TM, ldub_p) \
|
||||
DO_LD_TLB(NAME, H, TE, TM, cpu_ldub_data_ra)
|
||||
|
||||
DO_LD_PRIM_1(ld1bb, H1, uint8_t, uint8_t)
|
||||
DO_LD_PRIM_1(ld1bhu, H1_2, uint16_t, uint8_t)
|
||||
DO_LD_PRIM_1(ld1bhs, H1_2, uint16_t, int8_t)
|
||||
DO_LD_PRIM_1(ld1bsu, H1_4, uint32_t, uint8_t)
|
||||
DO_LD_PRIM_1(ld1bss, H1_4, uint32_t, int8_t)
|
||||
DO_LD_PRIM_1(ld1bdu, H1_8, uint64_t, uint8_t)
|
||||
DO_LD_PRIM_1(ld1bds, H1_8, uint64_t, int8_t)
|
||||
|
||||
#define DO_ST_PRIM_1(NAME, H, TE, TM) \
|
||||
DO_ST_HOST(st1##NAME, H, TE, TM, stb_p) \
|
||||
DO_ST_TLB(st1##NAME, H, TE, TM, cpu_stb_data_ra)
|
||||
|
||||
DO_ST_PRIM_1(bb, H1, uint8_t, uint8_t)
|
||||
DO_ST_PRIM_1(bh, H1_2, uint16_t, uint8_t)
|
||||
DO_ST_PRIM_1(bs, H1_4, uint32_t, uint8_t)
|
||||
DO_ST_PRIM_1(bd, H1_8, uint64_t, uint8_t)
|
||||
|
||||
#define DO_LD_PRIM_2(NAME, H, TE, TM, LD) \
|
||||
DO_LD_HOST(ld1##NAME##_be, H, TE, TM, LD##_be_p) \
|
||||
DO_LD_HOST(ld1##NAME##_le, H, TE, TM, LD##_le_p) \
|
||||
DO_LD_TLB(ld1##NAME##_be, H, TE, TM, cpu_##LD##_be_data_ra) \
|
||||
DO_LD_TLB(ld1##NAME##_le, H, TE, TM, cpu_##LD##_le_data_ra)
|
||||
|
||||
#define DO_ST_PRIM_2(NAME, H, TE, TM, ST) \
|
||||
DO_ST_HOST(st1##NAME##_be, H, TE, TM, ST##_be_p) \
|
||||
DO_ST_HOST(st1##NAME##_le, H, TE, TM, ST##_le_p) \
|
||||
DO_ST_TLB(st1##NAME##_be, H, TE, TM, cpu_##ST##_be_data_ra) \
|
||||
DO_ST_TLB(st1##NAME##_le, H, TE, TM, cpu_##ST##_le_data_ra)
|
||||
|
||||
DO_LD_PRIM_2(hh, H1_2, uint16_t, uint16_t, lduw)
|
||||
DO_LD_PRIM_2(hsu, H1_4, uint32_t, uint16_t, lduw)
|
||||
DO_LD_PRIM_2(hss, H1_4, uint32_t, int16_t, lduw)
|
||||
DO_LD_PRIM_2(hdu, H1_8, uint64_t, uint16_t, lduw)
|
||||
DO_LD_PRIM_2(hds, H1_8, uint64_t, int16_t, lduw)
|
||||
|
||||
DO_ST_PRIM_2(hh, H1_2, uint16_t, uint16_t, stw)
|
||||
DO_ST_PRIM_2(hs, H1_4, uint32_t, uint16_t, stw)
|
||||
DO_ST_PRIM_2(hd, H1_8, uint64_t, uint16_t, stw)
|
||||
|
||||
DO_LD_PRIM_2(ss, H1_4, uint32_t, uint32_t, ldl)
|
||||
DO_LD_PRIM_2(sdu, H1_8, uint64_t, uint32_t, ldl)
|
||||
DO_LD_PRIM_2(sds, H1_8, uint64_t, int32_t, ldl)
|
||||
|
||||
DO_ST_PRIM_2(ss, H1_4, uint32_t, uint32_t, stl)
|
||||
DO_ST_PRIM_2(sd, H1_8, uint64_t, uint32_t, stl)
|
||||
|
||||
DO_LD_PRIM_2(dd, H1_8, uint64_t, uint64_t, ldq)
|
||||
DO_ST_PRIM_2(dd, H1_8, uint64_t, uint64_t, stq)
|
||||
|
||||
#undef DO_LD_TLB
|
||||
#undef DO_ST_TLB
|
||||
#undef DO_LD_HOST
|
||||
#undef DO_LD_PRIM_1
|
||||
#undef DO_ST_PRIM_1
|
||||
#undef DO_LD_PRIM_2
|
||||
#undef DO_ST_PRIM_2
|
||||
|
||||
/*
|
||||
* Skip through a sequence of inactive elements in the guarding predicate @vg,
|
||||
* beginning at @reg_off bounded by @reg_max. Return the offset of the active
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue