Patchwork [for-next,11/15] tcg-ppc64: Setup TCG_REG_TB

login
register
mail settings
Submitter Richard Henderson
Date Aug. 5, 2013, 6:28 p.m.
Message ID <1375727330-30515-12-git-send-email-rth@twiddle.net>
Download mbox | patch
Permalink /patch/264743/
State New
Headers show

Comments

Richard Henderson - Aug. 5, 2013, 6:28 p.m.
A handy value "near" the rest of the program's dynamic allocation.
We'll be able to use this value for constant address generation,
cross-TB references, and in the further future, constant pool refs.

Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 tcg/ppc64/tcg-target.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

Patch

diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index f69bc8f..e01d8bc 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -55,10 +55,15 @@  static bool have_isa_2_06;
 #define HAVE_ISEL      0
 #endif
 
+/* Our local "toc" points to the beginning of the TB, making it easy to
+   form addresses in the memory range "near" the TB.  Unlike the real TOC,
+   put this in a call-saved register so we don't have to reload it.  */
+#define TCG_REG_TB  TCG_REG_R30
+
 #ifdef CONFIG_USE_GUEST_BASE
-#define TCG_GUEST_BASE_REG 30
+#define TCG_GUEST_BASE_REG  TCG_REG_R29
 #else
-#define TCG_GUEST_BASE_REG 0
+#define TCG_GUEST_BASE_REG  0
 #endif
 
 #ifndef NDEBUG
@@ -1097,8 +1102,9 @@  static void tcg_target_qemu_prologue (TCGContext *s)
     }
 #endif
 
-    tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
     tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR);
+    tcg_out_mov(s, TCG_TYPE_PTR, TCG_REG_TB, tcg_target_call_iarg_regs[1]);
     tcg_out32 (s, BCCTR | BO_ALWAYS);
 
     /* Epilogue */
@@ -1457,13 +1463,19 @@  static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
             tcg_abort();
         } else {
             /* Indirect jump method. */
-            tcg_out_mem_long(s, LD, LDX, TCG_REG_R0, TCG_REG_R0,
+            tcg_out_mem_long(s, LD, LDX, TCG_REG_TB, TCG_REG_R0,
                              (tcg_target_long)(s->tb_next + args[0]));
-            tcg_out32(s, MTSPR | RS(TCG_REG_R0) | CTR);
+            tcg_out32(s, MTSPR | RS(TCG_REG_TB) | CTR);
             tcg_out32(s, BCCTR | BO_ALWAYS);
         }
         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
+
+        /* In the initial unset chain case, we fall thru.  Which means
+           that we need to reset the TCG_REG_TB register to our current.  */
+        tcg_out_mem_long(s, ADDI, ADD, TCG_REG_TB, TCG_REG_TB,
+                         s->code_buf - s->code_ptr);
         break;
+
     case INDEX_op_br:
         {
             TCGLabel *l = &s->labels[args[0]];
@@ -2174,6 +2186,7 @@  static void tcg_target_init (TCGContext *s)
     tcg_regset_set_reg (s->reserved_regs, TCG_REG_R11); /* ??? */
 #endif
     tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13); /* thread pointer */
+    tcg_regset_set_reg (s->reserved_regs, TCG_REG_TB); /* tcg tb pointer */
 
     tcg_add_target_add_op_defs (ppc_op_defs);
 }