aboutsummaryrefslogtreecommitdiff
path: root/tcg/i386
diff options
context:
space:
mode:
authorStefan Weil <sw@weilnetz.de>2012-04-12 20:46:32 +0200
committerStefan Weil <sw@weilnetz.de>2012-04-15 21:25:15 +0200
commit8d918718edcd6753aa12be96b71d1bd4fb6ed7cd (patch)
tree2ae5bafab006a9cf024a336654c30aed7a684e4b /tcg/i386
parentc170cb66490aa20bfc8d2c2421481dd9195dbb8b (diff)
tcg/i386: Add support for w64 ABI
w64 uses the registers rcx, rdx, r8 and r9 for function arguments, so it needs a different declaration of tcg_target_call_iarg_regs. rax, rcx, rdx, r8, r9, r10 and r11 may be changed by function calls. rbx, rbp, rdi, rsi, r12, r13, r14 and r15 remain unchanged by function calls. Reviewed-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Stefan Weil <sw@weilnetz.de>
Diffstat (limited to 'tcg/i386')
-rw-r--r--tcg/i386/tcg-target.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 79545e31c2..da17bba39d 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -63,10 +63,15 @@ static const int tcg_target_reg_alloc_order[] = {
static const int tcg_target_call_iarg_regs[] = {
#if TCG_TARGET_REG_BITS == 64
+#if defined(_WIN64)
+ TCG_REG_RCX,
+ TCG_REG_RDX,
+#else
TCG_REG_RDI,
TCG_REG_RSI,
TCG_REG_RDX,
TCG_REG_RCX,
+#endif
TCG_REG_R8,
TCG_REG_R9,
#else
@@ -176,10 +181,10 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
ct->ct |= TCG_CT_REG;
if (TCG_TARGET_REG_BITS == 64) {
tcg_regset_set32(ct->u.regs, 0, 0xffff);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_RSI);
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_RDI);
+ tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[0]);
+ tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[1]);
#ifdef CONFIG_TCG_PASS_AREG0
- tcg_regset_reset_reg(ct->u.regs, TCG_REG_RDX);
+ tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[2]);
#endif
} else {
tcg_regset_set32(ct->u.regs, 0, 0xff);
@@ -1300,9 +1305,12 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
use the ADDR32 prefix. For now, do nothing. */
if (offset != GUEST_BASE) {
- tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_RDI, GUEST_BASE);
- tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_RDI, base);
- base = TCG_REG_RDI, offset = 0;
+ tcg_out_movi(s, TCG_TYPE_I64,
+ tcg_target_call_iarg_regs[0], GUEST_BASE);
+ tgen_arithr(s, ARITH_ADD + P_REXW,
+ tcg_target_call_iarg_regs[0], base);
+ base = tcg_target_call_iarg_regs[0];
+ offset = 0;
}
}
@@ -1434,8 +1442,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
#endif
#else
tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
- TCG_REG_RSI, data_reg);
- tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RDX, mem_index);
+ tcg_target_call_iarg_regs[1], data_reg);
+ tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2], mem_index);
stack_adjust = 0;
#ifdef CONFIG_TCG_PASS_AREG0
/* XXX/FIXME: suboptimal */
@@ -1474,9 +1482,12 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
use the ADDR32 prefix. For now, do nothing. */
if (offset != GUEST_BASE) {
- tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_RDI, GUEST_BASE);
- tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_RDI, base);
- base = TCG_REG_RDI, offset = 0;
+ tcg_out_movi(s, TCG_TYPE_I64,
+ tcg_target_call_iarg_regs[0], GUEST_BASE);
+ tgen_arithr(s, ARITH_ADD + P_REXW,
+ tcg_target_call_iarg_regs[0], base);
+ base = tcg_target_call_iarg_regs[0];
+ offset = 0;
}
}
@@ -1977,6 +1988,10 @@ static int tcg_target_callee_save_regs[] = {
#if TCG_TARGET_REG_BITS == 64
TCG_REG_RBP,
TCG_REG_RBX,
+#if defined(_WIN64)
+ TCG_REG_RDI,
+ TCG_REG_RSI,
+#endif
TCG_REG_R12,
TCG_REG_R13,
TCG_REG_R14, /* Currently used for the global env. */
@@ -2064,8 +2079,10 @@ static void tcg_target_init(TCGContext *s)
tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX);
tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX);
if (TCG_TARGET_REG_BITS == 64) {
+#if !defined(_WIN64)
tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RDI);
tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RSI);
+#endif
tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);