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 {
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) {