[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [RFC][PATCH v3 2/3] tcg: Add declarations and templates
From: |
Blue Swirl |
Subject: |
Re: [Qemu-devel] [RFC][PATCH v3 2/3] tcg: Add declarations and templates of extended MMU helpers |
Date: |
Sat, 14 Jul 2012 13:08:10 +0000 |
On Sat, Jul 14, 2012 at 10:23 AM, Yeongkyoon Lee
<address@hidden> wrote:
> Add declarations and templates of extended MMU helpers.
> An extended helper takes an additional argument of the host address accessing
> a guest memory which differs from the address of the call site to the helper
> because helper call sites locate at the end of a generated code block.
> ---
> softmmu_defs.h | 64
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
> softmmu_header.h | 31 +++++++++++++++++++++++++
> softmmu_template.h | 52 +++++++++++++++++++++++++++++++++++------
> 3 files changed, 139 insertions(+), 8 deletions(-)
>
> diff --git a/softmmu_defs.h b/softmmu_defs.h
> index 8d59f9d..505f6ba 100644
> --- a/softmmu_defs.h
> +++ b/softmmu_defs.h
> @@ -10,6 +10,8 @@
> #define SOFTMMU_DEFS_H
>
> #ifndef CONFIG_TCG_PASS_AREG0
> +
> +#ifndef CONFIG_QEMU_LDST_OPTIMIZATION
> uint8_t __ldb_mmu(target_ulong addr, int mmu_idx);
> void __stb_mmu(target_ulong addr, uint8_t val, int mmu_idx);
> uint16_t __ldw_mmu(target_ulong addr, int mmu_idx);
> @@ -28,6 +30,30 @@ void __stl_cmmu(target_ulong addr, uint32_t val, int
> mmu_idx);
> uint64_t __ldq_cmmu(target_ulong addr, int mmu_idx);
> void __stq_cmmu(target_ulong addr, uint64_t val, int mmu_idx);
> #else
> +/* Extended versions of MMU helpers for qemu_ld/st optimization.
> + The additional argument is a host code address accessing guest memory */
> +uint8_t ext_ldb_mmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stb_mmu(target_ulong addr, uint8_t val, int mmu_idx, uintptr_t ra);
> +uint16_t ext_ldw_mmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stw_mmu(target_ulong addr, uint16_t val, int mmu_idx, uintptr_t ra);
> +uint32_t ext_ldl_mmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stl_mmu(target_ulong addr, uint32_t val, int mmu_idx, uintptr_t ra);
> +uint64_t ext_ldq_mmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stq_mmu(target_ulong addr, uint64_t val, int mmu_idx, uintptr_t ra);
> +
> +uint8_t ext_ldb_cmmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stb_cmmu(target_ulong addr, uint8_t val, int mmu_idx, uintptr_t ra);
> +uint16_t ext_ldw_cmmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stw_cmmu(target_ulong addr, uint16_t val, int mmu_idx, uintptr_t
> ra);
> +uint32_t ext_ldl_cmmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stl_cmmu(target_ulong addr, uint32_t val, int mmu_idx, uintptr_t
> ra);
> +uint64_t ext_ldq_cmmu(target_ulong addr, int mmu_idx, uintptr_t ra);
> +void ext_stq_cmmu(target_ulong addr, uint64_t val, int mmu_idx, uintptr_t
> ra);
> +#endif /* !CONFIG_QEMU_LDST_OPTIMIZATION */
> +
> +#else
> +
> +#ifndef CONFIG_QEMU_LDST_OPTIMIZATION
> uint8_t helper_ldb_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
> void helper_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
> int mmu_idx);
> @@ -53,6 +79,44 @@ void helper_stl_cmmu(CPUArchState *env, target_ulong addr,
> uint32_t val,
> uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
> void helper_stq_cmmu(CPUArchState *env, target_ulong addr, uint64_t val,
> int mmu_idx);
> +#else
> +/* Extended versions of MMU helpers for qemu_ld/st optimization.
> + The additional argument is a host code address accessing guest memory */
> +uint8_t ext_helper_ldb_mmu(CPUArchState *env, target_ulong addr, int mmu_idx,
> + uintptr_t ra);
> +void ext_helper_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
> + int mmu_idx, uintptr_t ra);
> +uint16_t ext_helper_ldw_mmu(CPUArchState *env, target_ulong addr, int
> mmu_idx,
> + uintptr_t ra);
> +void ext_helper_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
> + int mmu_idx, uintptr_t ra);
> +uint32_t ext_helper_ldl_mmu(CPUArchState *env, target_ulong addr, int
> mmu_idx,
> + uintptr_t ra);
> +void ext_helper_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
> + int mmu_idx, uintptr_t ra);
> +uint64_t ext_helper_ldq_mmu(CPUArchState *env, target_ulong addr, int
> mmu_idx,
> + uintptr_t ra);
> +void ext_helper_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
> + int mmu_idx, uintptr_t ra);
> +
> +uint8_t ext_helper_ldb_cmmu(CPUArchState *env, target_ulong addr, int
> mmu_idx,
> + uintptr_t ra);
> +void ext_helper_stb_cmmu(CPUArchState *env, target_ulong addr, uint8_t val,
> + int mmu_idx, uintptr_t ra);
> +uint16_t ext_helper_ldw_cmmu(CPUArchState *env, target_ulong addr, int
> mmu_idx,
> + uintptr_t ra);
> +void ext_helper_stw_cmmu(CPUArchState *env, target_ulong addr, uint16_t val,
> + int mmu_idx, uintptr_t ra);
> +uint32_t ext_helper_ldl_cmmu(CPUArchState *env, target_ulong addr, int
> mmu_idx,
> + uintptr_t ra);
> +void ext_helper_stl_cmmu(CPUArchState *env, target_ulong addr, uint32_t val,
> + int mmu_idx, uintptr_t ra);
> +uint64_t ext_helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int
> mmu_idx,
> + uintptr_t ra);
> +void ext_helper_stq_cmmu(CPUArchState *env, target_ulong addr, uint64_t val,
> + int mmu_idx, uintptr_t ra);
> +#endif /* !CONFIG_QEMU_LDST_OPTIMIZATION */
> +
> #endif
>
> #endif
> diff --git a/softmmu_header.h b/softmmu_header.h
> index cf1aa38..07852c4 100644
> --- a/softmmu_header.h
> +++ b/softmmu_header.h
> @@ -82,12 +82,20 @@
> #define ENV_PARAM
> #define ENV_VAR
> #define CPU_PREFIX
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> +#define HELPER_PREFIX ext_
> +#else
> #define HELPER_PREFIX __
> +#endif /* CONFIG_QEMU_LDST_OPTIMIZATION */
> #else
> #define ENV_PARAM CPUArchState *env,
> #define ENV_VAR env,
> #define CPU_PREFIX cpu_
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> +#define HELPER_PREFIX ext_helper_
> +#else
> #define HELPER_PREFIX helper_
> +#endif /* CONFIG_QEMU_LDST_OPTIMIZATION */
> #endif
>
> /* generic load/store macros */
> @@ -106,9 +114,16 @@ glue(glue(glue(CPU_PREFIX, ld), USUFFIX),
> MEMSUFFIX)(ENV_PARAM
> mmu_idx = CPU_MMU_INDEX;
> if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
> (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> + /* XXX: This macro branching is due to checkpatch.pl which
> + doesn't allow "#define RET_VAR , (uintptr_t)NULL" */
Just do it, checkpatch.pl is not infallible.
> + res = glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
> + MMUSUFFIX)(ENV_VAR addr, mmu_idx, (uintptr_t)NULL);
> +#else
> res = glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_VAR
> addr,
>
> mmu_idx);
> +#endif /* CONFIG_QEMU_LDST_OPTIMIZATION */
> } else {
> uintptr_t hostaddr = addr +
> env->tlb_table[mmu_idx][page_index].addend;
> res = glue(glue(ld, USUFFIX), _raw)(hostaddr);
> @@ -130,8 +145,16 @@ glue(glue(glue(CPU_PREFIX, lds), SUFFIX),
> MEMSUFFIX)(ENV_PARAM
> mmu_idx = CPU_MMU_INDEX;
> if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
> (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> + /* XXX: This macro branching is due to checkpatch.pl which
> + doesn't allow "#define RET_VAR , (uintptr_t)NULL" */
> + res = (DATA_STYPE)glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
> + MMUSUFFIX)(ENV_VAR addr, mmu_idx,
> + (uintptr_t)NULL);
> +#else
> res = (DATA_STYPE)glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
> MMUSUFFIX)(ENV_VAR addr, mmu_idx);
> +#endif /* CONFIG_QEMU_LDST_OPTIMIZATION */
> } else {
> uintptr_t hostaddr = addr +
> env->tlb_table[mmu_idx][page_index].addend;
> res = glue(glue(lds, SUFFIX), _raw)(hostaddr);
> @@ -157,8 +180,16 @@ glue(glue(glue(CPU_PREFIX, st), SUFFIX),
> MEMSUFFIX)(ENV_PARAM target_ulong ptr,
> mmu_idx = CPU_MMU_INDEX;
> if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
> (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> + /* XXX: This macro branching is due to checkpatch.pl which
> + doesn't allow "#define RET_VAR , (uintptr_t)NULL" */
> + glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_VAR addr,
> v,
> + mmu_idx,
> +
> (uintptr_t)NULL);
> +#else
> glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_VAR addr,
> v,
> mmu_idx);
> +#endif /* CONFIG_QEMU_LDST_OPTIMIZATION */
> } else {
> uintptr_t hostaddr = addr +
> env->tlb_table[mmu_idx][page_index].addend;
> glue(glue(st, SUFFIX), _raw)(hostaddr, v);
> diff --git a/softmmu_template.h b/softmmu_template.h
> index b8bd700..5096c63 100644
> --- a/softmmu_template.h
> +++ b/softmmu_template.h
> @@ -66,6 +66,21 @@
> #define HELPER_PREFIX helper_
> #endif
>
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> +#undef HELPER_PREFIX
> +/* Redefine helper prefix */
> +#ifndef CONFIG_TCG_PASS_AREG0
> +#define HELPER_PREFIX ext_
> +#else
> +#define HELPER_PREFIX ext_helper_
> +#endif
> +/* An extended MMU helper takes one more argument which is
> + a host address of generated code accessing guest memory */
> +#define GET_RET_ADDR() ra
> +#else
> +#define GET_RET_ADDR() GETPC()
> +#endif /* CONFIG_QEMU_LDST_OPTIMIZATION */
> +
> static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_PARAM
> target_ulong addr,
> int mmu_idx,
> @@ -103,10 +118,20 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(ENV_PARAM
> }
>
> /* handle all cases except unaligned access which span two pages */
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> +/* XXX: This macro branching is due to checkpatch.pl which doesn't allow
> + "#define RET_PARAM , uintptr_r ra" */
> +DATA_TYPE
> +glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
> + target_ulong addr,
> + int mmu_idx,
> + uintptr_t ra)
> +#else
> DATA_TYPE
> glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
> target_ulong addr,
> int mmu_idx)
> +#endif /* CONFIG_QEMU_LDST_OPTIMIZATION */
> {
> DATA_TYPE res;
> int index;
> @@ -124,13 +149,13 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
> MMUSUFFIX)(ENV_PARAM
> /* IO access */
> if ((addr & (DATA_SIZE - 1)) != 0)
> goto do_unaligned_access;
> - retaddr = GETPC();
> + retaddr = GET_RET_ADDR();
> ioaddr = env->iotlb[mmu_idx][index];
> res = glue(io_read, SUFFIX)(ENV_VAR ioaddr, addr, retaddr);
> } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >=
> TARGET_PAGE_SIZE) {
> /* slow unaligned access (it spans two pages or IO) */
> do_unaligned_access:
> - retaddr = GETPC();
> + retaddr = GET_RET_ADDR();
> #ifdef ALIGNED_ONLY
> do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx,
> retaddr);
> #endif
> @@ -141,7 +166,7 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
> MMUSUFFIX)(ENV_PARAM
> uintptr_t addend;
> #ifdef ALIGNED_ONLY
> if ((addr & (DATA_SIZE - 1)) != 0) {
> - retaddr = GETPC();
> + retaddr = GET_RET_ADDR();
> do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx,
> retaddr);
> }
> #endif
> @@ -151,7 +176,7 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
> MMUSUFFIX)(ENV_PARAM
> }
> } else {
> /* the page is not in the TLB : fill it */
> - retaddr = GETPC();
> + retaddr = GET_RET_ADDR();
> #ifdef ALIGNED_ONLY
> if ((addr & (DATA_SIZE - 1)) != 0)
> do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx,
> retaddr);
> @@ -253,10 +278,20 @@ static inline void glue(io_write, SUFFIX)(ENV_PARAM
> #endif /* SHIFT > 2 */
> }
>
> +#ifdef CONFIG_QEMU_LDST_OPTIMIZATION
> +/* XXX: This macro branching is due to checkpatch.pl which doesn't allow
> + "#define RET_PARAM , uintptr_t ra" */
> +void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
> + target_ulong
> addr,
> + DATA_TYPE val,
> + int mmu_idx,
> + uintptr_t ra)
> +#else
> void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
> target_ulong
> addr,
> DATA_TYPE val,
> int mmu_idx)
> +#endif /* CONFIG_QEMU_LDST_OPTIMIZATION */
> {
> target_phys_addr_t ioaddr;
> target_ulong tlb_addr;
> @@ -271,12 +306,12 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX),
> MMUSUFFIX)(ENV_PARAM
> /* IO access */
> if ((addr & (DATA_SIZE - 1)) != 0)
> goto do_unaligned_access;
> - retaddr = GETPC();
> + retaddr = GET_RET_ADDR();
> ioaddr = env->iotlb[mmu_idx][index];
> glue(io_write, SUFFIX)(ENV_VAR ioaddr, val, addr, retaddr);
> } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >=
> TARGET_PAGE_SIZE) {
> do_unaligned_access:
> - retaddr = GETPC();
> + retaddr = GET_RET_ADDR();
> #ifdef ALIGNED_ONLY
> do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr);
> #endif
> @@ -287,7 +322,7 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX),
> MMUSUFFIX)(ENV_PARAM
> uintptr_t addend;
> #ifdef ALIGNED_ONLY
> if ((addr & (DATA_SIZE - 1)) != 0) {
> - retaddr = GETPC();
> + retaddr = GET_RET_ADDR();
> do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr);
> }
> #endif
> @@ -297,7 +332,7 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX),
> MMUSUFFIX)(ENV_PARAM
> }
> } else {
> /* the page is not in the TLB : fill it */
> - retaddr = GETPC();
> + retaddr = GET_RET_ADDR();
> #ifdef ALIGNED_ONLY
> if ((addr & (DATA_SIZE - 1)) != 0)
> do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr);
> @@ -370,3 +405,4 @@ static void glue(glue(slow_st, SUFFIX),
> MMUSUFFIX)(ENV_PARAM
> #undef ENV_VAR
> #undef CPU_PREFIX
> #undef HELPER_PREFIX
> +#undef GET_RET_ADDR
> --
> 1.7.4.1
>