From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org
Subject: [Qemu-devel] [PULL for-2.4 1/5] tcg/i386: Extend addresses for 32-bit guests
Date: Thu, 23 Jul 2015 20:44:00 -0700 [thread overview]
Message-ID: <1437709444-541-2-git-send-email-rth@twiddle.net> (raw)
In-Reply-To: <1437709444-541-1-git-send-email-rth@twiddle.net>
Removing the ??? comment explaining why it (mostly) worked.
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Message-Id: <1437081950-7206-2-git-send-email-rth@twiddle.net>
---
tcg/i386/tcg-target.c | 114 +++++++++++++++++++++++++++++++-------------------
1 file changed, 72 insertions(+), 42 deletions(-)
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index ff4d9cf..887f22f 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1434,8 +1434,8 @@ static inline void setup_guest_base_seg(void) { }
#endif /* SOFTMMU */
static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
- TCGReg base, intptr_t ofs, int seg,
- TCGMemOp memop)
+ TCGReg base, int index, intptr_t ofs,
+ int seg, TCGMemOp memop)
{
const TCGMemOp real_bswap = memop & MO_BSWAP;
TCGMemOp bswap = real_bswap;
@@ -1448,13 +1448,16 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
switch (memop & MO_SSIZE) {
case MO_UB:
- tcg_out_modrm_offset(s, OPC_MOVZBL + seg, datalo, base, ofs);
+ tcg_out_modrm_sib_offset(s, OPC_MOVZBL + seg, datalo,
+ base, index, 0, ofs);
break;
case MO_SB:
- tcg_out_modrm_offset(s, OPC_MOVSBL + P_REXW + seg, datalo, base, ofs);
+ tcg_out_modrm_sib_offset(s, OPC_MOVSBL + P_REXW + seg, datalo,
+ base, index, 0, ofs);
break;
case MO_UW:
- tcg_out_modrm_offset(s, OPC_MOVZWL + seg, datalo, base, ofs);
+ tcg_out_modrm_sib_offset(s, OPC_MOVZWL + seg, datalo,
+ base, index, 0, ofs);
if (real_bswap) {
tcg_out_rolw_8(s, datalo);
}
@@ -1462,20 +1465,21 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
case MO_SW:
if (real_bswap) {
if (have_movbe) {
- tcg_out_modrm_offset(s, OPC_MOVBE_GyMy + P_DATA16 + seg,
- datalo, base, ofs);
+ tcg_out_modrm_sib_offset(s, OPC_MOVBE_GyMy + P_DATA16 + seg,
+ datalo, base, index, 0, ofs);
} else {
- tcg_out_modrm_offset(s, OPC_MOVZWL + seg, datalo, base, ofs);
+ tcg_out_modrm_sib_offset(s, OPC_MOVZWL + seg, datalo,
+ base, index, 0, ofs);
tcg_out_rolw_8(s, datalo);
}
tcg_out_modrm(s, OPC_MOVSWL + P_REXW, datalo, datalo);
} else {
- tcg_out_modrm_offset(s, OPC_MOVSWL + P_REXW + seg,
- datalo, base, ofs);
+ tcg_out_modrm_sib_offset(s, OPC_MOVSWL + P_REXW + seg,
+ datalo, base, index, 0, ofs);
}
break;
case MO_UL:
- tcg_out_modrm_offset(s, movop + seg, datalo, base, ofs);
+ tcg_out_modrm_sib_offset(s, movop + seg, datalo, base, index, 0, ofs);
if (bswap) {
tcg_out_bswap32(s, datalo);
}
@@ -1483,19 +1487,22 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
#if TCG_TARGET_REG_BITS == 64
case MO_SL:
if (real_bswap) {
- tcg_out_modrm_offset(s, movop + seg, datalo, base, ofs);
+ tcg_out_modrm_sib_offset(s, movop + seg, datalo,
+ base, index, 0, ofs);
if (bswap) {
tcg_out_bswap32(s, datalo);
}
tcg_out_ext32s(s, datalo, datalo);
} else {
- tcg_out_modrm_offset(s, OPC_MOVSLQ + seg, datalo, base, ofs);
+ tcg_out_modrm_sib_offset(s, OPC_MOVSLQ + seg, datalo,
+ base, index, 0, ofs);
}
break;
#endif
case MO_Q:
if (TCG_TARGET_REG_BITS == 64) {
- tcg_out_modrm_offset(s, movop + P_REXW + seg, datalo, base, ofs);
+ tcg_out_modrm_sib_offset(s, movop + P_REXW + seg, datalo,
+ base, index, 0, ofs);
if (bswap) {
tcg_out_bswap64(s, datalo);
}
@@ -1506,11 +1513,15 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGReg datalo, TCGReg datahi,
datahi = t;
}
if (base != datalo) {
- tcg_out_modrm_offset(s, movop + seg, datalo, base, ofs);
- tcg_out_modrm_offset(s, movop + seg, datahi, base, ofs + 4);
+ tcg_out_modrm_sib_offset(s, movop + seg, datalo,
+ base, index, 0, ofs);
+ tcg_out_modrm_sib_offset(s, movop + seg, datahi,
+ base, index, 0, ofs + 4);
} else {
- tcg_out_modrm_offset(s, movop + seg, datahi, base, ofs + 4);
- tcg_out_modrm_offset(s, movop + seg, datalo, base, ofs);
+ tcg_out_modrm_sib_offset(s, movop + seg, datahi,
+ base, index, 0, ofs + 4);
+ tcg_out_modrm_sib_offset(s, movop + seg, datalo,
+ base, index, 0, ofs);
}
if (bswap) {
tcg_out_bswap32(s, datalo);
@@ -1553,7 +1564,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
label_ptr, offsetof(CPUTLBEntry, addr_read));
/* TLB Hit. */
- tcg_out_qemu_ld_direct(s, datalo, datahi, TCG_REG_L1, 0, 0, opc);
+ tcg_out_qemu_ld_direct(s, datalo, datahi, TCG_REG_L1, -1, 0, 0, opc);
/* Record the current context of a load into ldst label */
add_qemu_ldst_label(s, true, oi, datalo, datahi, addrlo, addrhi,
@@ -1562,24 +1573,33 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is64)
{
int32_t offset = GUEST_BASE;
TCGReg base = addrlo;
+ int index = -1;
int seg = 0;
- /* ??? We assume all operations have left us with register contents
- that are zero extended. So far this appears to be true. If we
- want to enforce this, we can either do an explicit zero-extension
- here, or (if GUEST_BASE == 0, or a segment register is in use)
- use the ADDR32 prefix. For now, do nothing. */
- if (GUEST_BASE && guest_base_flags) {
+ /* For a 32-bit guest, the high 32 bits may contain garbage.
+ We can do this with the ADDR32 prefix if we're not using
+ a guest base, or when using segmentation. Otherwise we
+ need to zero-extend manually. */
+ if (GUEST_BASE == 0 || guest_base_flags) {
seg = guest_base_flags;
offset = 0;
- } else if (TCG_TARGET_REG_BITS == 64 && offset != GUEST_BASE) {
- tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_L1, GUEST_BASE);
- tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_L1, base);
- base = TCG_REG_L1;
- offset = 0;
+ if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
+ seg |= P_ADDR32;
+ }
+ } else if (TCG_TARGET_REG_BITS == 64) {
+ if (TARGET_LONG_BITS == 32) {
+ tcg_out_ext32u(s, TCG_REG_L0, base);
+ base = TCG_REG_L0;
+ }
+ if (offset != GUEST_BASE) {
+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_L1, GUEST_BASE);
+ index = TCG_REG_L1;
+ offset = 0;
+ }
}
- tcg_out_qemu_ld_direct(s, datalo, datahi, base, offset, seg, opc);
+ tcg_out_qemu_ld_direct(s, datalo, datahi,
+ base, index, offset, seg, opc);
}
#endif
}
@@ -1697,19 +1717,29 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is64)
TCGReg base = addrlo;
int seg = 0;
- /* ??? We assume all operations have left us with register contents
- that are zero extended. So far this appears to be true. If we
- want to enforce this, we can either do an explicit zero-extension
- here, or (if GUEST_BASE == 0, or a segment register is in use)
- use the ADDR32 prefix. For now, do nothing. */
- if (GUEST_BASE && guest_base_flags) {
+ /* See comment in tcg_out_qemu_ld re zero-extension of addrlo. */
+ if (GUEST_BASE == 0 || guest_base_flags) {
seg = guest_base_flags;
offset = 0;
- } else if (TCG_TARGET_REG_BITS == 64 && offset != GUEST_BASE) {
- tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_L1, GUEST_BASE);
- tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_L1, base);
- base = TCG_REG_L1;
- offset = 0;
+ if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
+ seg |= P_ADDR32;
+ }
+ } else if (TCG_TARGET_REG_BITS == 64) {
+ /* ??? Note that we can't use the same SIB addressing scheme
+ as for loads, since we require L0 free for bswap. */
+ if (offset != GUEST_BASE) {
+ if (TARGET_LONG_BITS == 32) {
+ tcg_out_ext32u(s, TCG_REG_L0, base);
+ base = TCG_REG_L0;
+ }
+ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_L1, GUEST_BASE);
+ tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_L1, base);
+ base = TCG_REG_L1;
+ offset = 0;
+ } else if (TARGET_LONG_BITS == 32) {
+ tcg_out_ext32u(s, TCG_REG_L1, base);
+ base = TCG_REG_L1;
+ }
}
tcg_out_qemu_st_direct(s, datalo, datahi, base, offset, seg, opc);
--
2.4.3
next prev parent reply other threads:[~2015-07-24 3:44 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-24 3:43 [Qemu-devel] [PULL for-2.4 0/5] tcg fixes Richard Henderson
2015-07-24 3:44 ` Richard Henderson [this message]
2015-07-24 3:44 ` [Qemu-devel] [PULL for-2.4 2/5] tcg/aarch64: add ext argument to tcg_out_insn_3310 Richard Henderson
2015-07-24 3:44 ` [Qemu-devel] [PULL for-2.4 3/5] tcg/aarch64: use 32-bit offset for 32-bit user-mode emulation Richard Henderson
2015-07-24 3:44 ` [Qemu-devel] [PULL for-2.4 4/5] tcg/aarch64: use 32-bit offset for 32-bit softmmu emulation Richard Henderson
2015-07-24 3:44 ` [Qemu-devel] [PULL for-2.4 5/5] tcg/optimize: fix tcg_opt_gen_movi Richard Henderson
2015-07-24 11:09 ` [Qemu-devel] [PULL for-2.4 0/5] tcg fixes Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1437709444-541-2-git-send-email-rth@twiddle.net \
--to=rth@twiddle.net \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).