diff options
author | Richard Henderson <rth@twiddle.net> | 2013-03-25 20:54:30 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2013-04-05 13:35:40 -0500 |
commit | a4924e8bb533fb537d82a463b6465d80adaea0f5 (patch) | |
tree | 79709e97e8328438f5e4f7221a8c142dfcb5718f /tcg/s390 | |
parent | a22971f99f4846a0947f35548b7f3f76159339f0 (diff) |
tcg-s390: Properly allocate a stack frame.
Set TCG_TARGET_CALL_STACK_OFFSET properly for the abi. Allocate the
standard TCG_STATIC_CALL_ARGS_SIZE. And while we're at it, allocate
space for CPU_TEMP_BUF_NLONGS.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'tcg/s390')
-rw-r--r-- | tcg/s390/tcg-target.c | 20 | ||||
-rw-r--r-- | tcg/s390/tcg-target.h | 2 |
2 files changed, 15 insertions, 7 deletions
diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c index 0132010f64..d91b894b1d 100644 --- a/tcg/s390/tcg-target.c +++ b/tcg/s390/tcg-target.c @@ -2302,17 +2302,24 @@ 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(CPUArchState, temp_buf), - CPU_TEMP_BUF_NLONGS * sizeof(long)); } static void tcg_target_qemu_prologue(TCGContext *s) { + tcg_target_long frame_size; + /* stmg %r6,%r15,48(%r15) (save registers) */ tcg_out_insn(s, RXY, STMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 48); - /* aghi %r15,-160 (stack frame) */ - tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -160); + /* aghi %r15,-frame_size */ + frame_size = TCG_TARGET_CALL_STACK_OFFSET; + frame_size += TCG_STATIC_CALL_ARGS_SIZE; + frame_size += CPU_TEMP_BUF_NLONGS * sizeof(long); + tcg_out_insn(s, RI, AGHI, TCG_REG_R15, -frame_size); + + tcg_set_frame(s, TCG_REG_CALL_STACK, + TCG_STATIC_CALL_ARGS_SIZE + TCG_TARGET_CALL_STACK_OFFSET, + CPU_TEMP_BUF_NLONGS * sizeof(long)); if (GUEST_BASE >= 0x80000) { tcg_out_movi(s, TCG_TYPE_PTR, TCG_GUEST_BASE_REG, GUEST_BASE); @@ -2325,8 +2332,9 @@ static void tcg_target_qemu_prologue(TCGContext *s) tb_ret_addr = s->code_ptr; - /* lmg %r6,%r15,208(%r15) (restore registers) */ - tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, 208); + /* lmg %r6,%r15,fs+48(%r15) (restore registers) */ + tcg_out_insn(s, RXY, LMG, TCG_REG_R6, TCG_REG_R15, TCG_REG_R15, + frame_size + 48); /* br %r14 (return) */ tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R14); diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h index 40211e68f1..c6d9e848a6 100644 --- a/tcg/s390/tcg-target.h +++ b/tcg/s390/tcg-target.h @@ -100,7 +100,7 @@ typedef enum TCGReg { /* used for function call generation */ #define TCG_REG_CALL_STACK TCG_REG_R15 #define TCG_TARGET_STACK_ALIGN 8 -#define TCG_TARGET_CALL_STACK_OFFSET 0 +#define TCG_TARGET_CALL_STACK_OFFSET 160 #define TCG_TARGET_EXTEND_ARGS 1 |