diff options
Diffstat (limited to 'tcg')
| -rw-r--r-- | tcg/arm/tcg-target.c | 19 | ||||
| -rw-r--r-- | tcg/hppa/tcg-target.c | 8 | ||||
| -rw-r--r-- | tcg/i386/tcg-target.c | 32 | ||||
| -rw-r--r-- | tcg/ia64/tcg-target.c | 7 | ||||
| -rw-r--r-- | tcg/mips/tcg-target.c | 10 | ||||
| -rw-r--r-- | tcg/ppc/tcg-target.c | 8 | ||||
| -rw-r--r-- | tcg/ppc64/tcg-target.c | 8 | ||||
| -rw-r--r-- | tcg/s390/tcg-target.c | 7 | ||||
| -rw-r--r-- | tcg/sparc/tcg-target.c | 9 | ||||
| -rw-r--r-- | tcg/tcg.c | 22 | ||||
| -rw-r--r-- | tcg/tcg.h | 7 |
11 files changed, 84 insertions, 53 deletions
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c index fb858d8634..93eb0f1a45 100644 --- a/tcg/arm/tcg-target.c +++ b/tcg/arm/tcg-target.c @@ -1804,6 +1804,8 @@ static void tcg_target_init(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC); tcg_add_target_add_op_defs(arm_op_defs); + tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf), + CPU_TEMP_BUF_NLONGS * sizeof(long)); } static inline void tcg_out_ld(TCGContext *s, TCGType type, int arg, @@ -1846,15 +1848,18 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type, static void tcg_target_qemu_prologue(TCGContext *s) { - /* There is no need to save r7, it is used to store the address - of the env structure and is not modified by GCC. */ + /* Calling convention requires us to save r4-r11 and lr; + * save also r12 to maintain stack 8-alignment. + */ + + /* stmdb sp!, { r4 - r12, lr } */ + tcg_out32(s, (COND_AL << 28) | 0x092d5ff0); - /* stmdb sp!, { r4 - r6, r8 - r11, lr } */ - tcg_out32(s, (COND_AL << 28) | 0x092d4f70); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); - tcg_out_bx(s, COND_AL, TCG_REG_R0); + tcg_out_bx(s, COND_AL, tcg_target_call_iarg_regs[1]); tb_ret_addr = s->code_ptr; - /* ldmia sp!, { r4 - r6, r8 - r11, pc } */ - tcg_out32(s, (COND_AL << 28) | 0x08bd8f70); + /* ldmia sp!, { r4 - r12, pc } */ + tcg_out32(s, (COND_AL << 28) | 0x08bd9ff0); } diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c index 7f4653e342..79bca630c5 100644 --- a/tcg/hppa/tcg-target.c +++ b/tcg/hppa/tcg-target.c @@ -1596,7 +1596,7 @@ static int tcg_target_callee_save_regs[] = { TCG_REG_R14, TCG_REG_R15, TCG_REG_R16, - /* R17 is the global env, so no need to save. */ + TCG_REG_R17, /* R17 is the global env. */ TCG_REG_R18 }; @@ -1635,8 +1635,10 @@ static void tcg_target_qemu_prologue(TCGContext *s) } #endif + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); + /* Jump to TB, and adjust R18 to be the return address. */ - tcg_out32(s, INSN_BLE_SR4 | INSN_R2(TCG_REG_R26)); + tcg_out32(s, INSN_BLE_SR4 | INSN_R2(tcg_target_call_iarg_regs[1])); tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R18, TCG_REG_R31); /* Restore callee saved registers. */ @@ -1680,4 +1682,6 @@ static void tcg_target_init(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_REG_R31); /* ble link reg */ tcg_add_target_add_op_defs(hppa_op_defs); + tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf), + CPU_TEMP_BUF_NLONGS * sizeof(long)); } diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c index bb19a950bf..7529677fe2 100644 --- a/tcg/i386/tcg-target.c +++ b/tcg/i386/tcg-target.c @@ -1398,7 +1398,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, /* Pop and discard. This is 2 bytes smaller than the add. */ tcg_out_pop(s, TCG_REG_ECX); } else if (stack_adjust != 0) { - tcg_out_addi(s, TCG_REG_ESP, stack_adjust); + tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust); } /* label2: */ @@ -1901,10 +1901,10 @@ static int tcg_target_callee_save_regs[] = { TCG_REG_RBX, TCG_REG_R12, TCG_REG_R13, - /* TCG_REG_R14, */ /* Currently used for the global env. */ + TCG_REG_R14, /* Currently used for the global env. */ TCG_REG_R15, #else - /* TCG_REG_EBP, */ /* Currently used for the global env. */ + TCG_REG_EBP, /* Currently used for the global env. */ TCG_REG_EBX, TCG_REG_ESI, TCG_REG_EDI, @@ -1918,28 +1918,34 @@ static void tcg_target_qemu_prologue(TCGContext *s) /* TB prologue */ - /* Save all callee saved registers. */ - for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { - tcg_out_push(s, tcg_target_callee_save_regs[i]); - } - - /* Reserve some stack space. */ + /* Reserve some stack space, also for TCG temps. */ push_size = 1 + ARRAY_SIZE(tcg_target_callee_save_regs); push_size *= TCG_TARGET_REG_BITS / 8; - frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE; + frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE + + CPU_TEMP_BUF_NLONGS * sizeof(long); frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) & ~(TCG_TARGET_STACK_ALIGN - 1); stack_addend = frame_size - push_size; + tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE, + CPU_TEMP_BUF_NLONGS * sizeof(long)); + + /* Save all callee saved registers. */ + for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { + tcg_out_push(s, tcg_target_callee_save_regs[i]); + } + tcg_out_addi(s, TCG_REG_ESP, -stack_addend); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); + /* jmp *tb. */ - tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[0]); + tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[1]); /* TB epilogue */ tb_ret_addr = s->code_ptr; - tcg_out_addi(s, TCG_REG_ESP, stack_addend); + tcg_out_addi(s, TCG_REG_CALL_STACK, stack_addend); for (i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) { tcg_out_pop(s, tcg_target_callee_save_regs[i]); @@ -1976,7 +1982,7 @@ static void tcg_target_init(TCGContext *s) } tcg_regset_clear(s->reserved_regs); - tcg_regset_set_reg(s->reserved_regs, TCG_REG_ESP); + tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK); tcg_add_target_add_op_defs(x86_op_defs); } diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c index 8dac7f72fd..6386a5bf27 100644 --- a/tcg/ia64/tcg-target.c +++ b/tcg/ia64/tcg-target.c @@ -2292,7 +2292,7 @@ static void tcg_target_qemu_prologue(TCGContext *s) tcg_opc_m34(TCG_REG_P0, OPC_ALLOC_M34, TCG_REG_R33, 32, 24, 0), tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21, - TCG_REG_B6, TCG_REG_R32, 0), + TCG_REG_B6, TCG_REG_R33, 0), tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22, TCG_REG_R32, TCG_REG_B0)); @@ -2308,7 +2308,8 @@ static void tcg_target_qemu_prologue(TCGContext *s) } tcg_out_bundle(s, miB, - tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0), + tcg_opc_m48(TCG_REG_P0, OPC_MOV_I21, + TCG_REG_AREG0, TCG_REG_R32, 0), tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4, TCG_REG_R12, -frame_size, TCG_REG_R12), tcg_opc_b4 (TCG_REG_P0, OPC_BR_SPTK_MANY_B4, TCG_REG_B6)); @@ -2387,4 +2388,6 @@ static void tcg_target_init(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_REG_R6); tcg_add_target_add_op_defs(ia64_op_defs); + tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf), + CPU_TEMP_BUF_NLONGS * sizeof(long)); } diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index e04b0dc32f..12ff9d5259 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -1452,9 +1452,7 @@ static const TCGTargetOpDef mips_op_defs[] = { }; static int tcg_target_callee_save_regs[] = { -#if 0 /* used for the global env (TCG_AREG0), so no need to save */ - TCG_REG_S0, -#endif + TCG_REG_S0, /* used for the global env (TCG_AREG0) */ TCG_REG_S1, TCG_REG_S2, TCG_REG_S3, @@ -1486,8 +1484,8 @@ static void tcg_target_qemu_prologue(TCGContext *s) } /* Call generated code */ - tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_A0, 0); - tcg_out_nop(s); + tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1]), 0); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); tb_ret_addr = s->code_ptr; /* TB epilogue */ @@ -1530,4 +1528,6 @@ static void tcg_target_init(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP); /* stack pointer */ tcg_add_target_add_op_defs(mips_op_defs); + tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf), + CPU_TEMP_BUF_NLONGS * sizeof(long)); } diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c index 7970268e5a..dde4e18570 100644 --- a/tcg/ppc/tcg-target.c +++ b/tcg/ppc/tcg-target.c @@ -160,8 +160,7 @@ static const int tcg_target_callee_save_regs[] = { TCG_REG_R24, TCG_REG_R25, TCG_REG_R26, - /* TCG_REG_R27, */ /* currently used for the global env, so no - need to save */ + TCG_REG_R27, /* currently used for the global env */ TCG_REG_R28, TCG_REG_R29, TCG_REG_R30, @@ -939,7 +938,8 @@ static void tcg_target_qemu_prologue (TCGContext *s) } #endif - tcg_out32 (s, MTSPR | RS (3) | CTR); + 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_out32 (s, BCCTR | BO_ALWAYS); tb_ret_addr = s->code_ptr; @@ -1919,4 +1919,6 @@ static void tcg_target_init(TCGContext *s) #endif tcg_add_target_add_op_defs(ppc_op_defs); + tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf), + CPU_TEMP_BUF_NLONGS * sizeof(long)); } diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c index ebbee343fd..32184387e5 100644 --- a/tcg/ppc64/tcg-target.c +++ b/tcg/ppc64/tcg-target.c @@ -151,8 +151,7 @@ static const int tcg_target_callee_save_regs[] = { TCG_REG_R24, TCG_REG_R25, TCG_REG_R26, - /* TCG_REG_R27, */ /* currently used for the global env, so no - need to save */ + TCG_REG_R27, /* currently used for the global env */ TCG_REG_R28, TCG_REG_R29, TCG_REG_R30, @@ -905,7 +904,8 @@ static void tcg_target_qemu_prologue (TCGContext *s) } #endif - tcg_out32 (s, MTSPR | RS (3) | CTR); + 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_out32 (s, BCCTR | BO_ALWAYS); /* Epilogue */ @@ -1696,4 +1696,6 @@ static void tcg_target_init (TCGContext *s) tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13); tcg_add_target_add_op_defs (ppc_op_defs); + tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf), + CPU_TEMP_BUF_NLONGS * sizeof(long)); } diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c index 450fcabd70..2fc5646400 100644 --- a/tcg/s390/tcg-target.c +++ b/tcg/s390/tcg-target.c @@ -2291,6 +2291,8 @@ static void tcg_target_init(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK); tcg_add_target_add_op_defs(s390_op_defs); + tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf), + CPU_TEMP_BUF_NLONGS * sizeof(long)); } static void tcg_target_qemu_prologue(TCGContext *s) @@ -2306,8 +2308,9 @@ static void tcg_target_qemu_prologue(TCGContext *s) tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG); } - /* br %r2 (go to TB) */ - tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R2); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]); + /* br %r3 (go to TB) */ + tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]); tb_ret_addr = s->code_ptr; diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c index 5f1353adf8..ac76e1198d 100644 --- a/tcg/sparc/tcg-target.c +++ b/tcg/sparc/tcg-target.c @@ -693,11 +693,14 @@ static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret, /* Generate global QEMU prologue and epilogue code */ static void tcg_target_qemu_prologue(TCGContext *s) { + tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_CALL_STACK_OFFSET, + CPU_TEMP_BUF_NLONGS * (int)sizeof(long)); tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) | - INSN_IMM13(-TCG_TARGET_STACK_MINFRAME)); - tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I0) | + INSN_IMM13(-(TCG_TARGET_STACK_MINFRAME + + CPU_TEMP_BUF_NLONGS * (int)sizeof(long)))); + tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I1) | INSN_RS2(TCG_REG_G0)); - tcg_out_nop(s); + tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_I0); } #if defined(CONFIG_SOFTMMU) diff --git a/tcg/tcg.c b/tcg/tcg.c index 184c208980..c05413baa4 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -54,7 +54,6 @@ instructions */ #define NO_CPU_IO_DEFS #include "cpu.h" -#include "exec-all.h" #include "tcg-op.h" #include "elf.h" @@ -1440,13 +1439,19 @@ static void temp_allocate_frame(TCGContext *s, int temp) { TCGTemp *ts; ts = &s->temps[temp]; - s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1); - if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end) +#ifndef __sparc_v9__ /* Sparc64 stack is accessed with offset of 2047 */ + s->current_frame_offset = (s->current_frame_offset + + (tcg_target_long)sizeof(tcg_target_long) - 1) & + ~(sizeof(tcg_target_long) - 1); +#endif + if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) > + s->frame_end) { tcg_abort(); + } ts->mem_offset = s->current_frame_offset; ts->mem_reg = s->frame_reg; ts->mem_allocated = 1; - s->current_frame_offset += sizeof(tcg_target_long); + s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long); } /* free register 'reg' by spilling the corresponding temporary if necessary */ @@ -1842,13 +1847,14 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, nb_regs = nb_params; /* assign stack slots first */ - /* XXX: preallocate call stack */ call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long); call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & ~(TCG_TARGET_STACK_ALIGN - 1); allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE); if (allocate_args) { - tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size)); + /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed, + preallocate call stack */ + tcg_abort(); } stack_offset = TCG_TARGET_CALL_STACK_OFFSET; @@ -1967,10 +1973,6 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def, } tcg_out_op(s, opc, &func_arg, &const_func_arg); - - if (allocate_args) { - tcg_out_addi(s, TCG_REG_CALL_STACK, STACK_DIR(call_stack_size)); - } /* assign output registers and emit moves if needed */ for(i = 0; i < nb_oargs; i++) { diff --git a/tcg/tcg.h b/tcg/tcg.h index 3647390c5f..a2dd8b892a 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -515,8 +515,9 @@ TCGv_i64 tcg_const_local_i64(int64_t val); extern uint8_t code_gen_prologue[]; #if defined(_ARCH_PPC) && !defined(_ARCH_PPC64) -#define tcg_qemu_tb_exec(tb_ptr) \ - ((long REGPARM __attribute__ ((longcall)) (*)(void *))code_gen_prologue)(tb_ptr) +#define tcg_qemu_tb_exec(env, tb_ptr) \ + ((long REGPARM __attribute__ ((longcall)) (*)(void *, void *))code_gen_prologue)(env, tb_ptr) #else -#define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void *))code_gen_prologue)(tb_ptr) +#define tcg_qemu_tb_exec(env, tb_ptr) \ + ((long REGPARM (*)(void *, void *))code_gen_prologue)(env, tb_ptr) #endif |