diff options
author | Richard Henderson <rth@twiddle.net> | 2013-03-13 15:24:33 -0700 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2013-04-27 02:16:45 +0200 |
commit | df5e0ef711cdd2ebfd4bdf420bfde17aa28df8b1 (patch) | |
tree | 9f1983ab5d8ab04ade16f4695c4d7285b0d8c285 /include | |
parent | 302fdde73f88fd958acfa18b670eed092eab21a0 (diff) |
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.h | 17 |
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 |