From: "Alex Bennée" <alex.bennee@linaro.org>
To: qemu-devel@nongnu.org
Cc: "Peter Crosthwaite" <crosthwaite.peter@gmail.com>,
claudio.fontana@huawei.com, a.rigo@virtualopensystems.com,
"Paolo Bonzini" <pbonzini@redhat.com>,
jani.kokkonen@huawei.com, "Alex Bennée" <alex.bennee@linaro.org>,
"Richard Henderson" <rth@twiddle.net>
Subject: [Qemu-devel] [RFC PATCH 1/2] softmmu_template: add smmu_helper, convert VICTIM_TLB_HIT
Date: Fri, 8 Jan 2016 15:53:13 +0000 [thread overview]
Message-ID: <1452268394-31252-2-git-send-email-alex.bennee@linaro.org> (raw)
In-Reply-To: <1452268394-31252-1-git-send-email-alex.bennee@linaro.org>
This lays the ground work for a re-factoring of the softmmu template
code. The patch introduces inline "smmu_helper" functions where
common (or almost common) code can be placed. Arguments that the
compiler picks up as constant can then be used to eliminate legs of code
in the inline fragments.
There is a minor wrinkle that we need to use a unique name for each
inline fragment as the template is included multiple times. For this the
smmu_helper macro does the appropriate glue magic.
I've tested the result with no change to functionality. Comparing the
the objdump of cputlb.o shows minimal changes in probe_write and
everything else is identical.
TODO: explain probe_write changes
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
---
softmmu_template.h | 75 +++++++++++++++++++++++++++++++++---------------------
1 file changed, 46 insertions(+), 29 deletions(-)
diff --git a/softmmu_template.h b/softmmu_template.h
index 6803890..0074bd7 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -116,30 +116,47 @@
# define helper_te_st_name helper_le_st_name
#endif
-/* macro to check the victim tlb */
-#define VICTIM_TLB_HIT(ty) \
-({ \
- /* we are about to do a page table walk. our last hope is the \
- * victim tlb. try to refill from the victim tlb before walking the \
- * page table. */ \
- int vidx; \
- CPUIOTLBEntry tmpiotlb; \
- CPUTLBEntry tmptlb; \
- for (vidx = CPU_VTLB_SIZE-1; vidx >= 0; --vidx) { \
- if (env->tlb_v_table[mmu_idx][vidx].ty == (addr & TARGET_PAGE_MASK)) {\
- /* found entry in victim tlb, swap tlb and iotlb */ \
- tmptlb = env->tlb_table[mmu_idx][index]; \
- env->tlb_table[mmu_idx][index] = env->tlb_v_table[mmu_idx][vidx]; \
- env->tlb_v_table[mmu_idx][vidx] = tmptlb; \
- tmpiotlb = env->iotlb[mmu_idx][index]; \
- env->iotlb[mmu_idx][index] = env->iotlb_v[mmu_idx][vidx]; \
- env->iotlb_v[mmu_idx][vidx] = tmpiotlb; \
- break; \
- } \
- } \
- /* return true when there is a vtlb hit, i.e. vidx >=0 */ \
- vidx >= 0; \
-})
+/* Inline helper functions for SoftMMU
+ *
+ * These functions help reduce code duplication in the various main
+ * helper functions. Constant arguments (like endian state) will allow
+ * the compiler to skip code which is never called in a given inline.
+ */
+
+#define smmu_helper(name) glue(glue(glue(_smmu_helper_, SUFFIX), MMUSUFFIX),name)
+
+static inline int smmu_helper(victim_tlb_hit) (const bool is_read, CPUArchState *env,
+ unsigned mmu_idx, int index,
+ target_ulong addr)
+{
+ /* we are about to do a page table walk. our last hope is the
+ * victim tlb. try to refill from the victim tlb before walking the
+ * page table. */
+ int vidx;
+ CPUIOTLBEntry tmpiotlb;
+ CPUTLBEntry tmptlb;
+ for (vidx = CPU_VTLB_SIZE-1; vidx >= 0; --vidx) {
+ bool match;
+ if (is_read) {
+ match = env->tlb_v_table[mmu_idx][vidx].ADDR_READ == (addr & TARGET_PAGE_MASK);
+ } else {
+ match = env->tlb_v_table[mmu_idx][vidx].addr_write == (addr & TARGET_PAGE_MASK);
+ }
+
+ if (match) {
+ /* found entry in victim tlb, swap tlb and iotlb */
+ tmptlb = env->tlb_table[mmu_idx][index];
+ env->tlb_table[mmu_idx][index] = env->tlb_v_table[mmu_idx][vidx];
+ env->tlb_v_table[mmu_idx][vidx] = tmptlb;
+ tmpiotlb = env->iotlb[mmu_idx][index];
+ env->iotlb[mmu_idx][index] = env->iotlb_v[mmu_idx][vidx];
+ env->iotlb_v[mmu_idx][vidx] = tmpiotlb;
+ break;
+ }
+ }
+ /* return true when there is a vtlb hit, i.e. vidx >=0 */
+ return vidx >= 0;
+}
#ifndef SOFTMMU_CODE_ACCESS
static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
@@ -185,7 +202,7 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
mmu_idx, retaddr);
}
- if (!VICTIM_TLB_HIT(ADDR_READ)) {
+ if (!smmu_helper(victim_tlb_hit)(true, env, mmu_idx, index, addr)) {
tlb_fill(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
mmu_idx, retaddr);
}
@@ -269,7 +286,7 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
cpu_unaligned_access(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
mmu_idx, retaddr);
}
- if (!VICTIM_TLB_HIT(ADDR_READ)) {
+ if (!smmu_helper(victim_tlb_hit)(true, env, mmu_idx, index, addr)) {
tlb_fill(ENV_GET_CPU(env), addr, READ_ACCESS_TYPE,
mmu_idx, retaddr);
}
@@ -389,7 +406,7 @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
mmu_idx, retaddr);
}
- if (!VICTIM_TLB_HIT(addr_write)) {
+ if (!smmu_helper(victim_tlb_hit)(false, env, mmu_idx, index, addr)) {
tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr);
}
tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
@@ -469,7 +486,7 @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
cpu_unaligned_access(ENV_GET_CPU(env), addr, MMU_DATA_STORE,
mmu_idx, retaddr);
}
- if (!VICTIM_TLB_HIT(addr_write)) {
+ if (!smmu_helper(victim_tlb_hit)(false, env, mmu_idx, index, addr)) {
tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr);
}
tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
@@ -542,7 +559,7 @@ void probe_write(CPUArchState *env, target_ulong addr, int mmu_idx,
if ((addr & TARGET_PAGE_MASK)
!= (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
/* TLB entry is for a different page */
- if (!VICTIM_TLB_HIT(addr_write)) {
+ if (!smmu_helper(victim_tlb_hit)(false, env, mmu_idx, index, addr)) {
tlb_fill(ENV_GET_CPU(env), addr, MMU_DATA_STORE, mmu_idx, retaddr);
}
}
--
2.6.4
next prev parent reply other threads:[~2016-01-08 15:53 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-08 15:53 [Qemu-devel] [RFC PATCH 0/2] Attempt to clean-up softmmu templates Alex Bennée
2016-01-08 15:53 ` Alex Bennée [this message]
2016-01-08 15:53 ` [Qemu-devel] [RFC PATCH 2/2] softmmu: simplify helper_*_st_name with smmu_helper(do_unl_store) Alex Bennée
2016-01-19 15:53 ` alvise rigo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1452268394-31252-2-git-send-email-alex.bennee@linaro.org \
--to=alex.bennee@linaro.org \
--cc=a.rigo@virtualopensystems.com \
--cc=claudio.fontana@huawei.com \
--cc=crosthwaite.peter@gmail.com \
--cc=jani.kokkonen@huawei.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).