[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC][PATCH v3 2/3] tcg: Add declarations and templates of
From: |
Yeongkyoon Lee |
Subject: |
[Qemu-devel] [RFC][PATCH v3 2/3] tcg: Add declarations and templates of extended MMU helpers |
Date: |
Sat, 14 Jul 2012 19:23:33 +0900 |
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" */
+ 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