summary refs log tree commit diff stats
path: root/include/exec/softmmu_template.h
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2013-08-27 10:22:54 -0700
committerRichard Henderson <rth@twiddle.net>2013-09-02 09:08:30 -0700
commit0f842f8a246f2b5b51a11c13f933bf7a90ae8e96 (patch)
tree2dd695c689fb49d15fe28f2792fde11dba5be55e /include/exec/softmmu_template.h
parentc72b26ec92eb93a92852ab1d23acb5a945de5062 (diff)
downloadfocaccia-qemu-0f842f8a246f2b5b51a11c13f933bf7a90ae8e96.tar.gz
focaccia-qemu-0f842f8a246f2b5b51a11c13f933bf7a90ae8e96.zip
exec: Reorganize the GETRA/GETPC macros
Always define GETRA; use __builtin_extract_return_addr, rather than
having a special case for s390.  Split GETPC_ADJ out of GETPC; use 2
universally, rather than having a special case for arm.

Rename GETPC_LDST to GETRA_LDST to indicate that it does not
contain the GETPC_ADJ value.  Likewise with GETPC_EXT to GETRA_EXT.

Perform the GETPC_ADJ adjustment inside helper_ret_ld/st.  This will
allow backends to pass along the "true" return address rather than
the massaged GETPC value.  In the meantime, double application of
GETPC_ADJ does not hurt, since the call insn in all ISAs is at least
4 bytes long.

Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'include/exec/softmmu_template.h')
-rw-r--r--include/exec/softmmu_template.h24
1 files changed, 17 insertions, 7 deletions
diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h
index eaca9e1035..2fc6ea3235 100644
--- a/include/exec/softmmu_template.h
+++ b/include/exec/softmmu_template.h
@@ -86,6 +86,9 @@ glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
     target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
     uintptr_t haddr;
 
+    /* Adjust the given return address.  */
+    retaddr -= GETPC_ADJ;
+
     /* If the TLB entry is for a different page, reload and try again.  */
     if ((addr & TARGET_PAGE_MASK)
          != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
@@ -121,10 +124,12 @@ glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
 #endif
         addr1 = addr & ~(DATA_SIZE - 1);
         addr2 = addr1 + DATA_SIZE;
-        res1 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr1,
-                                                            mmu_idx, retaddr);
-        res2 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr2,
-                                                            mmu_idx, retaddr);
+        /* Note the adjustment at the beginning of the function.
+           Undo that for the recursion.  */
+        res1 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)
+            (env, addr1, mmu_idx, retaddr + GETPC_ADJ);
+        res2 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)
+            (env, addr2, mmu_idx, retaddr + GETPC_ADJ);
         shift = (addr & (DATA_SIZE - 1)) * 8;
 #ifdef TARGET_WORDS_BIGENDIAN
         res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
@@ -150,7 +155,7 @@ glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
                                          int mmu_idx)
 {
     return glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx,
-                                                        GETPC_EXT());
+                                                        GETRA_EXT());
 }
 
 #ifndef SOFTMMU_CODE_ACCESS
@@ -182,6 +187,9 @@ glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
     target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
     uintptr_t haddr;
 
+    /* Adjust the given return address.  */
+    retaddr -= GETPC_ADJ;
+
     /* If the TLB entry is for a different page, reload and try again.  */
     if ((addr & TARGET_PAGE_MASK)
         != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
@@ -223,8 +231,10 @@ glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
 #else
             uint8_t val8 = val >> (i * 8);
 #endif
+            /* Note the adjustment at the beginning of the function.
+               Undo that for the recursion.  */
             glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
-                                            mmu_idx, retaddr);
+                                            mmu_idx, retaddr + GETPC_ADJ);
         }
         return;
     }
@@ -245,7 +255,7 @@ glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
                                          DATA_TYPE val, int mmu_idx)
 {
     glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, val, mmu_idx,
-                                                 GETPC_EXT());
+                                                 GETRA_EXT());
 }
 
 #endif /* !defined(SOFTMMU_CODE_ACCESS) */