* [Qemu-devel] TCG on i386 can't generate qemu_st64 for 32-bit target
@ 2008-02-26 19:55 Blue Swirl
2008-02-26 22:05 ` [Qemu-devel] " Fabrice Bellard
0 siblings, 1 reply; 2+ messages in thread
From: Blue Swirl @ 2008-02-26 19:55 UTC (permalink / raw)
To: Fabrice Bellard; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 1134 bytes --]
Hi,
There is a problem with the Sparc32 target on i386 host. Store double
word op (std) cannot be generated and TCG just aborts. It looks like
the registers are so few on i386 that TCG can't find registers for the
qemu_st64 call. The problem does not appear on x86_64 host, or for
Sparc64 target (stx/ldx) on i386, or with 64-bit load (ldd) on Sparc32
target.
The attached patch would work around the problem, but I agree that
it's ugly and it would bring back one instance of T2 use. I also tried
preallocating a 64-bit register but that didn't help.
I suppose instead the following piece (tcg/i386/tcg-target.c:737)
could be modified to lower the pressure for registers but I'm not that
familiar with x86 assembly.
#if TARGET_LONG_BITS == 32
if (opc == 3) {
tcg_out_mov(s, TCG_REG_EDX, data_reg);
tcg_out_mov(s, TCG_REG_ECX, data_reg2);
tcg_out8(s, 0x6a); /* push Ib */
tcg_out8(s, mem_index);
tcg_out8(s, 0xe8);
tcg_out32(s, (tcg_target_long)qemu_st_helpers[s_bits] -
(tcg_target_long)s->code_ptr - 4);
tcg_out_addi(s, TCG_REG_ESP, 4);
} else {
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: std_fix_i386.diff --]
[-- Type: text/x-diff; name=std_fix_i386.diff, Size: 2172 bytes --]
Index: qemu/target-sparc/translate.c
===================================================================
--- qemu.orig/target-sparc/translate.c 2008-02-26 19:48:38.000000000 +0000
+++ qemu/target-sparc/translate.c 2008-02-26 19:48:38.000000000 +0000
@@ -192,6 +192,9 @@
#endif
#ifndef CONFIG_USER_ONLY
+#ifdef __i386__
+OP_LD_TABLE(std);
+#endif /* __i386__ */
OP_LD_TABLE(stf);
OP_LD_TABLE(stdf);
OP_LD_TABLE(ldf);
@@ -231,6 +234,13 @@
gen_movl_reg_TN(reg, cpu_T[1]);
}
+#ifdef __i386__
+static inline void gen_movl_reg_T2(int reg)
+{
+ gen_movl_reg_TN(reg, cpu_T[2]);
+}
+
+#endif /* __i386__ */
static inline void gen_movl_TN_reg(int reg, TCGv tn)
{
if (reg == 0)
@@ -3275,6 +3285,7 @@
case 0x7: /* store double word */
if (rd & 1)
goto illegal_insn;
+#ifndef __i386__
else {
TCGv r_dword, r_low;
@@ -3286,6 +3297,12 @@
r_low);
tcg_gen_qemu_st64(r_dword, cpu_T[0], dc->mem_idx);
}
+#else /* __i386__ */
+ gen_op_check_align_T0_7();
+ flush_T2(dc);
+ gen_movl_reg_T2(rd + 1);
+ gen_op_ldst(std);
+#endif /* __i386__ */
break;
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
case 0x14: /* store word alternate */
Index: qemu/target-sparc/op_mem.h
===================================================================
--- qemu.orig/target-sparc/op_mem.h 2008-02-26 19:48:38.000000000 +0000
+++ qemu/target-sparc/op_mem.h 2008-02-26 19:48:38.000000000 +0000
@@ -4,6 +4,16 @@
#define ADDR(x) (x)
#endif
+#ifdef __i386__
+/*** Integer store ***/
+void OPPROTO glue(op_std, MEMSUFFIX)(void)
+{
+ uint64_t tmp = ((uint64_t)T1 << 32) | (uint64_t)(T2 & 0xffffffff);
+
+ glue(stq, MEMSUFFIX)(ADDR(T0), tmp);
+}
+
+#endif /* __i386__ */
/*** Floating-point store ***/
void OPPROTO glue(op_stf, MEMSUFFIX) (void)
{
^ permalink raw reply [flat|nested] 2+ messages in thread
* [Qemu-devel] Re: TCG on i386 can't generate qemu_st64 for 32-bit target
2008-02-26 19:55 [Qemu-devel] TCG on i386 can't generate qemu_st64 for 32-bit target Blue Swirl
@ 2008-02-26 22:05 ` Fabrice Bellard
0 siblings, 0 replies; 2+ messages in thread
From: Fabrice Bellard @ 2008-02-26 22:05 UTC (permalink / raw)
To: Blue Swirl; +Cc: qemu-devel
Blue Swirl wrote:
> Hi,
>
> There is a problem with the Sparc32 target on i386 host. Store double
> word op (std) cannot be generated and TCG just aborts. It looks like
> the registers are so few on i386 that TCG can't find registers for the
> qemu_st64 call. The problem does not appear on x86_64 host, or for
> Sparc64 target (stx/ldx) on i386, or with 64-bit load (ldd) on Sparc32
> target.
>
> The attached patch would work around the problem, but I agree that
> it's ugly and it would bring back one instance of T2 use. I also tried
> preallocating a 64-bit register but that didn't help.
>
> I suppose instead the following piece (tcg/i386/tcg-target.c:737)
> could be modified to lower the pressure for registers but I'm not that
> familiar with x86 assembly.
> [...]
There are not enough free registers because of the legacy 3 cpu_T[n]
fixed registers. Once you have no helpers using cpu_T[n] implicitely, it
will be possible to allocate cpu_T[n] as normal temporaries and to free
the associated fixed registers.
Before that your solution is acceptable. Another hack would be to force
the 'r_dword' variable to be stored in cpu_T[1] and cpu_T[2], but TCG
gives no clean way to do it.
Fabrice.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2008-02-26 22:06 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-02-26 19:55 [Qemu-devel] TCG on i386 can't generate qemu_st64 for 32-bit target Blue Swirl
2008-02-26 22:05 ` [Qemu-devel] " Fabrice Bellard
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).