qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC 14/14] tcg-aarch64: Pass return address to load/store


From: Richard Henderson
Subject: [Qemu-devel] [RFC 14/14] tcg-aarch64: Pass return address to load/store helpers directly.
Date: Mon, 12 Aug 2013 11:44:55 -0700

Signed-off-by: Richard Henderson <address@hidden>
---
 include/exec/exec-all.h  | 16 +----------
 tcg/aarch64/tcg-target.c | 69 ++++++++++++++++++++++++++----------------------
 2 files changed, 39 insertions(+), 46 deletions(-)

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index b3402a1..10e680d 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -325,7 +325,7 @@ extern uintptr_t tci_tb_ptr;
    (5) post-process (e.g. stack adjust)
    (6) jump to corresponding code of the next of fast path
  */
-# if defined(__i386__) || defined(__x86_64__)
+# if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
 #  define GETRA() ((uintptr_t)__builtin_return_address(0))
 /* The return address argument for ldst is passed directly.  */
 #  define GETPC_LDST()  (abort(), 0)
@@ -334,20 +334,6 @@ extern uintptr_t tci_tb_ptr;
 #  define GETPC_LDST() ((uintptr_t) ((*(int32_t *)(GETRA() - 4)) - 1))
 # elif defined(__arm__)
 #  define GETPC_EXT()  GETPC()
-# elif defined(__aarch64__)
-#  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 += 4;                    /* skip one instruction */
-    b = *(int32_t *)ra;         /* load the branch insn */
-    b = (b << 6) >> (6 - 2);    /* extract the displacement */
-    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
diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index a03da58..52c1be4 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -301,9 +301,6 @@ typedef enum {
     /* PC relative addressing instructions */
     INSN_ADR   = 0x10000000,
     INSN_ADRP  = 0x90000000,
-
-    /* System instructions */
-    INSN_NOP   = 0xd503201f,
 } AArch64Insn;
 
 typedef enum {
@@ -522,6 +519,12 @@ static inline void tcg_out_movwi(TCGContext *s, 
AArch64Insn insn,
     tcg_out32(s, insn | ext | shift << 17 | value << 5 | rd);
 }
 
+static inline void tcg_out_fmt_adr(TCGContext *s, AArch64Insn insn,
+                                   TCGReg rd, tcg_target_long diff)
+{
+    tcg_out32(s, insn | rd | (diff & 3) << 29 | (diff & 0x1ffffc) << (5 - 2));
+}
+
 static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
                          tcg_target_long value)
 {
@@ -562,10 +565,7 @@ static void tcg_out_movi(TCGContext *s, TCGType type, 
TCGReg rd,
        often when loading pointers to QEMU's data structures.  */
     valid = (value >> 12) - ((intptr_t)s->code_ptr >> 12);
     if (valid == sextract64(valid, 0, 21)) {
-        insn  = INSN_ADRP | rd;
-        insn |= (valid & 3) << 29;
-        insn |= (valid & 0x1ffffc) << (5 - 2);
-        tcg_out32(s, insn);
+        tcg_out_fmt_adr(s, INSN_ADRP, rd, valid);
         if (value & 0xfff) {
             tcg_out_aimm(s, INSN_ADDI, ext, rd, rd, value & 0xfff);
         }
@@ -985,32 +985,40 @@ static void tcg_out_addi(TCGContext *s, AArch64Ext ext, 
TCGReg rd, TCGReg rn,
     }
 }
 
-static inline void tcg_out_nop(TCGContext *s)
-{
-    tcg_out32(s, INSN_NOP);
-}
-
 #ifdef CONFIG_SOFTMMU
 #include "exec/softmmu_defs.h"
 
-/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
-   int mmu_idx) */
+/* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
+ *                                     int mmu_idx, uintptr_t ra)
+ */
 static const void * const qemu_ld_helpers[4] = {
-    helper_ldb_mmu,
-    helper_ldw_mmu,
-    helper_ldl_mmu,
-    helper_ldq_mmu,
+    helper_ret_ldb_mmu,
+    helper_ret_ldw_mmu,
+    helper_ret_ldl_mmu,
+    helper_ret_ldq_mmu,
 };
 
-/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
-   uintxx_t val, int mmu_idx) */
+/* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
+ *                                     uintxx_t val, int mmu_idx, uintptr_t ra)
+ */
 static const void * const qemu_st_helpers[4] = {
-    helper_stb_mmu,
-    helper_stw_mmu,
-    helper_stl_mmu,
-    helper_stq_mmu,
+    helper_ret_stb_mmu,
+    helper_ret_stw_mmu,
+    helper_ret_stl_mmu,
+    helper_ret_stq_mmu,
 };
 
+static inline void tcg_out_adr(TCGContext *s, TCGReg rd, tcg_target_long addr)
+{
+    tcg_out_fmt_adr(s, INSN_ADR, rd, addr - (tcg_target_long)s->code_ptr);
+}
+
+/* See the GETPC definition in include/exec/exec-all.h.  */
+static inline uintptr_t do_getpc(uint8_t *raddr)
+{
+    return (uintptr_t)raddr - 1;
+}
+
 static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *lb)
 {
     int opc = lb->opc;
@@ -1021,9 +1029,9 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, 
TCGLabelQemuLdst *lb)
     tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_X0, TCG_AREG0);
     tcg_out_mov(s, TCG_TYPE_TL, TCG_REG_X1, lb->addrlo_reg);
     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X2, lb->mem_index);
-    tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP,
-                 (tcg_target_long)qemu_ld_helpers[s_bits]);
-    tcg_out_callr(s, TCG_REG_TMP);
+    tcg_out_adr(s, TCG_REG_X3, do_getpc(lb->raddr));
+
+    tcg_out_call(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
 
     if (opc & 0x04) {
         tcg_out_sxt(s, E64, s_bits, lb->datalo_reg, TCG_REG_X0);
@@ -1046,11 +1054,10 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, 
TCGLabelQemuLdst *lb)
     tcg_out_mov(s, s_bits == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32,
                 TCG_REG_X2, lb->datalo_reg);
     tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_X3, lb->mem_index);
-    tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP,
-                 (tcg_target_long)qemu_st_helpers[s_bits]);
-    tcg_out_callr(s, TCG_REG_TMP);
+    tcg_out_adr(s, TCG_REG_X4, do_getpc(lb->raddr));
+
+    tcg_out_call(s, (tcg_target_long)qemu_st_helpers[s_bits]);
 
-    tcg_out_nop(s);
     tcg_out_goto(s, (tcg_target_long)lb->raddr);
 }
 
-- 
1.8.3.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]