From ee8ba9e4d8458b8bba5455a7ae704620c4f2ef4b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 16 Jul 2015 22:25:49 +0100 Subject: [PATCH 1/5] tcg/i386: Extend addresses for 32-bit guests Removing the ??? comment explaining why it (mostly) worked. Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson 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 ff4d9cfec7..887f22f675 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); From 6c0f0c0f124718650a8d682ba275044fc02f6fe2 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 15 Jul 2015 17:27:00 +0200 Subject: [PATCH 2/5] tcg/aarch64: add ext argument to tcg_out_insn_3310 The new argument lets you pick uxtw or uxtx mode for the offset register. For now, all callers pass TCG_TYPE_I64 so that uxtx is generated. The bits for uxtx are removed from I3312_TO_I3310. Reported-by: Leon Alrae Reviewed-by: Aurelien Jarno Signed-off-by: Paolo Bonzini Message-Id: <1436974021-28978-2-git-send-email-pbonzini@redhat.com> Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c | 41 +++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index fe44ad709c..d1c550886a 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -280,7 +280,7 @@ typedef enum { I3312_LDRSHX = 0x38000000 | LDST_LD_S_X << 22 | MO_16 << 30, I3312_LDRSWX = 0x38000000 | LDST_LD_S_X << 22 | MO_32 << 30, - I3312_TO_I3310 = 0x00206800, + I3312_TO_I3310 = 0x00200800, I3312_TO_I3313 = 0x01000000, /* Load/store register pair instructions. */ @@ -496,13 +496,14 @@ static void tcg_out_insn_3509(TCGContext *s, AArch64Insn insn, TCGType ext, } static void tcg_out_insn_3310(TCGContext *s, AArch64Insn insn, - TCGReg rd, TCGReg base, TCGReg regoff) + TCGReg rd, TCGReg base, TCGType ext, + TCGReg regoff) { /* Note the AArch64Insn constants above are for C3.3.12. Adjust. */ - tcg_out32(s, insn | I3312_TO_I3310 | regoff << 16 | base << 5 | rd); + tcg_out32(s, insn | I3312_TO_I3310 | regoff << 16 | + 0x4000 | ext << 13 | base << 5 | rd); } - static void tcg_out_insn_3312(TCGContext *s, AArch64Insn insn, TCGReg rd, TCGReg rn, intptr_t offset) { @@ -677,7 +678,7 @@ static void tcg_out_ldst(TCGContext *s, AArch64Insn insn, /* Worst-case scenario, move offset to temp register, use reg offset. */ tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP, offset); - tcg_out_ldst_r(s, insn, rd, rn, TCG_REG_TMP); + tcg_out_ldst_r(s, insn, rd, rn, TCG_TYPE_I64, TCG_REG_TMP); } static inline void tcg_out_mov(TCGContext *s, @@ -1111,48 +1112,49 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp memop, TCGType ext, TCGReg data_r, TCGReg addr_r, TCGReg off_r) { const TCGMemOp bswap = memop & MO_BSWAP; + const TCGType otype = TCG_TYPE_I64; switch (memop & MO_SSIZE) { case MO_UB: - tcg_out_ldst_r(s, I3312_LDRB, data_r, addr_r, off_r); + tcg_out_ldst_r(s, I3312_LDRB, data_r, addr_r, otype, off_r); break; case MO_SB: tcg_out_ldst_r(s, ext ? I3312_LDRSBX : I3312_LDRSBW, - data_r, addr_r, off_r); + data_r, addr_r, otype, off_r); break; case MO_UW: - tcg_out_ldst_r(s, I3312_LDRH, data_r, addr_r, off_r); + tcg_out_ldst_r(s, I3312_LDRH, data_r, addr_r, otype, off_r); if (bswap) { tcg_out_rev16(s, data_r, data_r); } break; case MO_SW: if (bswap) { - tcg_out_ldst_r(s, I3312_LDRH, data_r, addr_r, off_r); + tcg_out_ldst_r(s, I3312_LDRH, data_r, addr_r, otype, off_r); tcg_out_rev16(s, data_r, data_r); tcg_out_sxt(s, ext, MO_16, data_r, data_r); } else { - tcg_out_ldst_r(s, ext ? I3312_LDRSHX : I3312_LDRSHW, - data_r, addr_r, off_r); + tcg_out_ldst_r(s, (ext ? I3312_LDRSHX : I3312_LDRSHW), + data_r, addr_r, otype, off_r); } break; case MO_UL: - tcg_out_ldst_r(s, I3312_LDRW, data_r, addr_r, off_r); + tcg_out_ldst_r(s, I3312_LDRW, data_r, addr_r, otype, off_r); if (bswap) { tcg_out_rev32(s, data_r, data_r); } break; case MO_SL: if (bswap) { - tcg_out_ldst_r(s, I3312_LDRW, data_r, addr_r, off_r); + tcg_out_ldst_r(s, I3312_LDRW, data_r, addr_r, otype, off_r); tcg_out_rev32(s, data_r, data_r); tcg_out_sxt(s, TCG_TYPE_I64, MO_32, data_r, data_r); } else { - tcg_out_ldst_r(s, I3312_LDRSWX, data_r, addr_r, off_r); + tcg_out_ldst_r(s, I3312_LDRSWX, data_r, addr_r, otype, off_r); } break; case MO_Q: - tcg_out_ldst_r(s, I3312_LDRX, data_r, addr_r, off_r); + tcg_out_ldst_r(s, I3312_LDRX, data_r, addr_r, otype, off_r); if (bswap) { tcg_out_rev64(s, data_r, data_r); } @@ -1166,31 +1168,32 @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGMemOp memop, TCGReg data_r, TCGReg addr_r, TCGReg off_r) { const TCGMemOp bswap = memop & MO_BSWAP; + const TCGType otype = TCG_TYPE_I64; switch (memop & MO_SIZE) { case MO_8: - tcg_out_ldst_r(s, I3312_STRB, data_r, addr_r, off_r); + tcg_out_ldst_r(s, I3312_STRB, data_r, addr_r, otype, off_r); break; case MO_16: if (bswap && data_r != TCG_REG_XZR) { tcg_out_rev16(s, TCG_REG_TMP, data_r); data_r = TCG_REG_TMP; } - tcg_out_ldst_r(s, I3312_STRH, data_r, addr_r, off_r); + tcg_out_ldst_r(s, I3312_STRH, data_r, addr_r, otype, off_r); break; case MO_32: if (bswap && data_r != TCG_REG_XZR) { tcg_out_rev32(s, TCG_REG_TMP, data_r); data_r = TCG_REG_TMP; } - tcg_out_ldst_r(s, I3312_STRW, data_r, addr_r, off_r); + tcg_out_ldst_r(s, I3312_STRW, data_r, addr_r, otype, off_r); break; case MO_64: if (bswap && data_r != TCG_REG_XZR) { tcg_out_rev64(s, TCG_REG_TMP, data_r); data_r = TCG_REG_TMP; } - tcg_out_ldst_r(s, I3312_STRX, data_r, addr_r, off_r); + tcg_out_ldst_r(s, I3312_STRX, data_r, addr_r, otype, off_r); break; default: tcg_abort(); From ffc6372851d8631a9f9fa56ec613b3244dc635b9 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 15 Jul 2015 17:27:01 +0200 Subject: [PATCH 3/5] tcg/aarch64: use 32-bit offset for 32-bit user-mode emulation Thanks to the previous patch, it is now easy for tcg_out_qemu_ld and tcg_out_qemu_st to use a 32-bit zero extended offset. However, the guest base register x28 must be the base and addr_reg must be the index. Reported-by: Leon Alrae Reviewed-by: Aurelien Jarno Signed-off-by: Paolo Bonzini Message-Id: <1436974021-28978-3-git-send-email-pbonzini@redhat.com> Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index d1c550886a..4aca883b8e 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -1109,10 +1109,10 @@ static void tcg_out_tlb_read(TCGContext *s, TCGReg addr_reg, TCGMemOp s_bits, #endif /* CONFIG_SOFTMMU */ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp memop, TCGType ext, - TCGReg data_r, TCGReg addr_r, TCGReg off_r) + TCGReg data_r, TCGReg addr_r, + TCGType otype, TCGReg off_r) { const TCGMemOp bswap = memop & MO_BSWAP; - const TCGType otype = TCG_TYPE_I64; switch (memop & MO_SSIZE) { case MO_UB: @@ -1165,10 +1165,10 @@ static void tcg_out_qemu_ld_direct(TCGContext *s, TCGMemOp memop, TCGType ext, } static void tcg_out_qemu_st_direct(TCGContext *s, TCGMemOp memop, - TCGReg data_r, TCGReg addr_r, TCGReg off_r) + TCGReg data_r, TCGReg addr_r, + TCGType otype, TCGReg off_r) { const TCGMemOp bswap = memop & MO_BSWAP; - const TCGType otype = TCG_TYPE_I64; switch (memop & MO_SIZE) { case MO_8: @@ -1210,12 +1210,15 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, tcg_insn_unit *label_ptr; tcg_out_tlb_read(s, addr_reg, s_bits, &label_ptr, mem_index, 1); - tcg_out_qemu_ld_direct(s, memop, ext, data_reg, addr_reg, TCG_REG_X1); + tcg_out_qemu_ld_direct(s, memop, ext, data_reg, addr_reg, + TCG_TYPE_I64, TCG_REG_X1); add_qemu_ldst_label(s, true, oi, ext, data_reg, addr_reg, s->code_ptr, label_ptr); #else /* !CONFIG_SOFTMMU */ - tcg_out_qemu_ld_direct(s, memop, ext, data_reg, addr_reg, - GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR); + const TCGType otype = TARGET_LONG_BITS == 64 ? TCG_TYPE_I64 : TCG_TYPE_I32; + tcg_out_qemu_ld_direct(s, memop, ext, data_reg, + GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR, + otype, addr_reg); #endif /* CONFIG_SOFTMMU */ } @@ -1229,12 +1232,15 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, tcg_insn_unit *label_ptr; tcg_out_tlb_read(s, addr_reg, s_bits, &label_ptr, mem_index, 0); - tcg_out_qemu_st_direct(s, memop, data_reg, addr_reg, TCG_REG_X1); + tcg_out_qemu_st_direct(s, memop, data_reg, addr_reg, + TCG_TYPE_I64, TCG_REG_X1); add_qemu_ldst_label(s, false, oi, s_bits == MO_64, data_reg, addr_reg, s->code_ptr, label_ptr); #else /* !CONFIG_SOFTMMU */ - tcg_out_qemu_st_direct(s, memop, data_reg, addr_reg, - GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR); + const TCGType otype = TARGET_LONG_BITS == 64 ? TCG_TYPE_I64 : TCG_TYPE_I32; + tcg_out_qemu_st_direct(s, memop, data_reg, + GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR, + otype, addr_reg); #endif /* CONFIG_SOFTMMU */ } From 80adb8fcad4778376a11d394a9e01516819e2327 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 23 Jul 2015 18:04:52 -0400 Subject: [PATCH 4/5] tcg/aarch64: use 32-bit offset for 32-bit softmmu emulation Similar to the same fix for user-mode, except this instance occurs on the softmmu path. Again, the tlb addend must be the base register, while the guest address is the index. Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson --- tcg/aarch64/tcg-target.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c index 4aca883b8e..b7ec4f5ace 100644 --- a/tcg/aarch64/tcg-target.c +++ b/tcg/aarch64/tcg-target.c @@ -1204,18 +1204,18 @@ static void tcg_out_qemu_ld(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, TCGMemOpIdx oi, TCGType ext) { TCGMemOp memop = get_memop(oi); + const TCGType otype = TARGET_LONG_BITS == 64 ? TCG_TYPE_I64 : TCG_TYPE_I32; #ifdef CONFIG_SOFTMMU unsigned mem_index = get_mmuidx(oi); TCGMemOp s_bits = memop & MO_SIZE; tcg_insn_unit *label_ptr; tcg_out_tlb_read(s, addr_reg, s_bits, &label_ptr, mem_index, 1); - tcg_out_qemu_ld_direct(s, memop, ext, data_reg, addr_reg, - TCG_TYPE_I64, TCG_REG_X1); + tcg_out_qemu_ld_direct(s, memop, ext, data_reg, + TCG_REG_X1, otype, addr_reg); add_qemu_ldst_label(s, true, oi, ext, data_reg, addr_reg, s->code_ptr, label_ptr); #else /* !CONFIG_SOFTMMU */ - const TCGType otype = TARGET_LONG_BITS == 64 ? TCG_TYPE_I64 : TCG_TYPE_I32; tcg_out_qemu_ld_direct(s, memop, ext, data_reg, GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR, otype, addr_reg); @@ -1226,18 +1226,18 @@ static void tcg_out_qemu_st(TCGContext *s, TCGReg data_reg, TCGReg addr_reg, TCGMemOpIdx oi) { TCGMemOp memop = get_memop(oi); + const TCGType otype = TARGET_LONG_BITS == 64 ? TCG_TYPE_I64 : TCG_TYPE_I32; #ifdef CONFIG_SOFTMMU unsigned mem_index = get_mmuidx(oi); TCGMemOp s_bits = memop & MO_SIZE; tcg_insn_unit *label_ptr; tcg_out_tlb_read(s, addr_reg, s_bits, &label_ptr, mem_index, 0); - tcg_out_qemu_st_direct(s, memop, data_reg, addr_reg, - TCG_TYPE_I64, TCG_REG_X1); + tcg_out_qemu_st_direct(s, memop, data_reg, + TCG_REG_X1, otype, addr_reg); add_qemu_ldst_label(s, false, oi, s_bits == MO_64, data_reg, addr_reg, s->code_ptr, label_ptr); #else /* !CONFIG_SOFTMMU */ - const TCGType otype = TARGET_LONG_BITS == 64 ? TCG_TYPE_I64 : TCG_TYPE_I32; tcg_out_qemu_st_direct(s, memop, data_reg, GUEST_BASE ? TCG_REG_GUEST_BASE : TCG_REG_XZR, otype, addr_reg); From 961521261a3d600b0695b2e6d2b0f490076f7e90 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Fri, 10 Jul 2015 18:03:30 +0200 Subject: [PATCH 5/5] tcg/optimize: fix tcg_opt_gen_movi Due to a copy&paste, the new op value is tested against mov_i32 instead of movi_i32. The test is therefore always false. Fix that. Signed-off-by: Aurelien Jarno Message-Id: <1436544211-2769-1-git-send-email-aurelien@aurel32.net> Signed-off-by: Richard Henderson --- tcg/optimize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tcg/optimize.c b/tcg/optimize.c index 0f6f7008da..18283cfd7b 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -205,7 +205,7 @@ static void tcg_opt_gen_movi(TCGContext *s, TCGOp *op, TCGArg *args, temps[dst].state = TCG_TEMP_CONST; temps[dst].val = val; mask = val; - if (TCG_TARGET_REG_BITS > 32 && new_op == INDEX_op_mov_i32) { + if (TCG_TARGET_REG_BITS > 32 && new_op == INDEX_op_movi_i32) { /* High bits of the destination are now garbage. */ mask |= ~0xffffffffull; }