summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2013-03-13 15:24:33 -0700
committerAurelien Jarno <aurelien@aurel32.net>2013-04-27 02:16:45 +0200
commitdf5e0ef711cdd2ebfd4bdf420bfde17aa28df8b1 (patch)
tree9f1983ab5d8ab04ade16f4695c4d7285b0d8c285 /include
parent302fdde73f88fd958acfa18b670eed092eab21a0 (diff)
downloadqemu-df5e0ef711cdd2ebfd4bdf420bfde17aa28df8b1.tar.gz
tcg-arm: Convert to CONFIG_QEMU_LDST_OPTIMIZATION
Move the slow path out of line, as the TODO's mention. This allows the fast path to be unconditional, which can speed up the fast path as well, depending on the core. Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'include')
-rw-r--r--include/exec/exec-all.h17
1 files changed, 17 insertions, 0 deletions
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index e856191e40..6362074e9c 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -338,6 +338,23 @@ extern uintptr_t tci_tb_ptr;
# elif defined (_ARCH_PPC) && !defined (_ARCH_PPC64)
# define GETRA() ((uintptr_t)__builtin_return_address(0))
# define GETPC_LDST() ((uintptr_t) ((*(int32_t *)(GETRA() - 4)) - 1))
+# elif defined(__arm__)
+/* We define two insns between the return address and the branch back to
+ straight-line. Find and decode that branch insn. */
+# define GETRA() ((uintptr_t)__builtin_return_address(0))
+# define GETPC_LDST() tcg_getpc_ldst(GETRA())
+static inline uintptr_t tcg_getpc_ldst(uintptr_t ra)
+{
+ int32_t b;
+ ra += 8; /* skip the two insns */
+ b = *(int32_t *)ra; /* load the branch insn */
+ b = (b << 8) >> (8 - 2); /* extract the displacement */
+ ra += 8; /* branches are relative to pc+8 */
+ ra += b; /* apply the displacement */
+ ra -= 4; /* return a pointer into the current opcode,
+ not the start of the next opcode */
+ return ra;
+}
# else
# error "CONFIG_QEMU_LDST_OPTIMIZATION needs GETPC_LDST() implementation!"
# endif