aboutsummaryrefslogtreecommitdiff
path: root/accel/tcg/tb-jmp-cache.h
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-08-12 09:53:53 -0700
committerRichard Henderson <richard.henderson@linaro.org>2022-10-04 12:13:16 -0700
commit8ed558ec0cbcc29ecf490e93c54dd65d276e8e69 (patch)
treeff425842023c3c01ba85c1f5feef862ac6159fb0 /accel/tcg/tb-jmp-cache.h
parentfbf59aad178d98afe193fa872a2d880266a75269 (diff)
accel/tcg: Introduce TARGET_TB_PCREL
Prepare for targets to be able to produce TBs that can run in more than one virtual context. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'accel/tcg/tb-jmp-cache.h')
-rw-r--r--accel/tcg/tb-jmp-cache.h41
1 files changed, 41 insertions, 0 deletions
diff --git a/accel/tcg/tb-jmp-cache.h b/accel/tcg/tb-jmp-cache.h
index 2d8fbb1bfe..ff5ffc8fc2 100644
--- a/accel/tcg/tb-jmp-cache.h
+++ b/accel/tcg/tb-jmp-cache.h
@@ -14,11 +14,52 @@
/*
* Accessed in parallel; all accesses to 'tb' must be atomic.
+ * For TARGET_TB_PCREL, accesses to 'pc' must be protected by
+ * a load_acquire/store_release to 'tb'.
*/
struct CPUJumpCache {
struct {
TranslationBlock *tb;
+#if TARGET_TB_PCREL
+ target_ulong pc;
+#endif
} array[TB_JMP_CACHE_SIZE];
};
+static inline TranslationBlock *
+tb_jmp_cache_get_tb(CPUJumpCache *jc, uint32_t hash)
+{
+#if TARGET_TB_PCREL
+ /* Use acquire to ensure current load of pc from jc. */
+ return qatomic_load_acquire(&jc->array[hash].tb);
+#else
+ /* Use rcu_read to ensure current load of pc from *tb. */
+ return qatomic_rcu_read(&jc->array[hash].tb);
+#endif
+}
+
+static inline target_ulong
+tb_jmp_cache_get_pc(CPUJumpCache *jc, uint32_t hash, TranslationBlock *tb)
+{
+#if TARGET_TB_PCREL
+ return jc->array[hash].pc;
+#else
+ return tb_pc(tb);
+#endif
+}
+
+static inline void
+tb_jmp_cache_set(CPUJumpCache *jc, uint32_t hash,
+ TranslationBlock *tb, target_ulong pc)
+{
+#if TARGET_TB_PCREL
+ jc->array[hash].pc = pc;
+ /* Use store_release on tb to ensure pc is written first. */
+ qatomic_store_release(&jc->array[hash].tb, tb);
+#else
+ /* Use the pc value already stored in tb->pc. */
+ qatomic_set(&jc->array[hash].tb, tb);
+#endif
+}
+
#endif /* ACCEL_TCG_TB_JMP_CACHE_H */