From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:43754) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TTdhG-0007oa-7w for qemu-devel@nongnu.org; Wed, 31 Oct 2012 15:11:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TTdhB-0001Rt-1k for qemu-devel@nongnu.org; Wed, 31 Oct 2012 15:11:26 -0400 Date: Wed, 31 Oct 2012 20:11:14 +0100 From: Aurelien Jarno Message-ID: <20121031191114.GA31495@ohm.aurel32.net> References: <508f1d02.8877310a.2b2a.3669SMTPIN_ADDED@mx.google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-15 Content-Disposition: inline In-Reply-To: Subject: Re: [Qemu-devel] [PATCH v2 1/3] tcg/arm: fix TLB access in qemu-ld/st ops List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Laurent Desnogues Cc: Peter Maydell , qemu-stable@nongnu.org, qemu-devel@nongnu.org, y@ohm.aurel32.net On Wed, Oct 31, 2012 at 02:54:38PM +0100, Laurent Desnogues wrote: > On Tue, Oct 30, 2012 at 1:18 AM, wrote: > > From: Aurelien Jarno > > > > The TCG arm backend considers likely that the offset to the TLB > > entries does not exceed 12 bits for mem_index = 0. In practice this is > > not true for at least the MIPS target. > > > > The current patch fixes that by loading the bits 23-12 with a separate > > instruction, and using loads with address writeback, independently of > > the value of mem_idx. In total this allow a 24-bit offset, which is a > > lot more than needed. > > > > Cc: Andrzej Zaborowski > > Cc: Peter Maydell > > Cc: qemu-stable@nongnu.org > > Signed-off-by: Aurelien Jarno > > --- > > tcg/arm/tcg-target.c | 77 +++++++++++++++++++++++++++----------------------- > > 1 file changed, 41 insertions(+), 36 deletions(-) > > > > diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c > > index e790bf0..03b1576 100644 > > --- a/tcg/arm/tcg-target.c > > +++ b/tcg/arm/tcg-target.c > > @@ -639,6 +639,22 @@ static inline void tcg_out_ld32_12(TCGContext *s, int cond, > > (rn << 16) | (rd << 12) | ((-im) & 0xfff)); > > } > > > > +/* Offset pre-increment with base writeback. */ > > +static inline void tcg_out_ld32_12wb(TCGContext *s, int cond, > > + int rd, int rn, tcg_target_long im) > > +{ > > + /* ldr with writeback and both register equals is UNPREDICTABLE */ > > + assert(rd != rn); > > + > > + if (im >= 0) { > > + tcg_out32(s, (cond << 28) | 0x05b00000 | > > + (rn << 16) | (rd << 12) | (im & 0xfff)); > > + } else { > > + tcg_out32(s, (cond << 28) | 0x05300000 | > > + (rn << 16) | (rd << 12) | ((-im) & 0xfff)); > > + } > > +} > > + > > static inline void tcg_out_st32_12(TCGContext *s, int cond, > > int rd, int rn, tcg_target_long im) > > { > > @@ -1071,7 +1087,7 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) > > { > > int addr_reg, data_reg, data_reg2, bswap; > > #ifdef CONFIG_SOFTMMU > > - int mem_index, s_bits; > > + int mem_index, s_bits, tlb_offset; > > TCGReg argreg; > > # if TARGET_LONG_BITS == 64 > > int addr_reg2; > > @@ -1111,19 +1127,15 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc) > > TCG_REG_R0, TCG_REG_R8, CPU_TLB_SIZE - 1); > > tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_AREG0, > > TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS)); > > - /* In the > > - * ldr r1 [r0, #(offsetof(CPUArchState, tlb_table[mem_index][0].addr_read))] > > - * below, the offset is likely to exceed 12 bits if mem_index != 0 and > > - * not exceed otherwise, so use an > > - * add r0, r0, #(mem_index * sizeof *CPUArchState.tlb_table) > > - * before. > > - */ > > - if (mem_index) > > + /* We assume that the offset is contained within 24 bits. */ > > + tlb_offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_read); > > + assert(tlb_offset & ~0xffffff == 0); > > + if (tlb_offset > 0xfff) { > > tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0, > > - (mem_index << (TLB_SHIFT & 1)) | > > - ((16 - (TLB_SHIFT >> 1)) << 8)); > > - tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R0, > > - offsetof(CPUArchState, tlb_table[0][0].addr_read)); > > + 0xa00 | (tlb_offset >> 12)); > > Isn't it 20 bits rather than 24 bits since the immediate is 8-bit right-rotated > by 20? > You are indeed correct. I'll send a new version of the patch soon. -- Aurelien Jarno GPG: 1024D/F1BCDB73 aurelien@aurel32.net http://www.aurel32.net