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 <r...@twiddle.net> --- tcg/ppc64/tcg-target.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) 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); } -- 1.8.3.1