linux-mips
[Top] [All Lists]

Re: [PATCH] fast path for rdhwr emulation for TLS

To: macro@linux-mips.org
Subject: Re: [PATCH] fast path for rdhwr emulation for TLS
From: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
Date: Sat, 08 Jul 2006 01:12:45 +0900 (JST)
Cc: linux-mips@linux-mips.org, ralf@linux-mips.org
In-reply-to: <Pine.LNX.4.64N.0607071607520.25285@blysk.ds.pg.gda.pl>
Original-recipient: rfc822;linux-mips@linux-mips.org
References: <20060708.000032.88471510.anemo@mba.ocn.ne.jp> <Pine.LNX.4.64N.0607071607520.25285@blysk.ds.pg.gda.pl>
Sender: linux-mips-bounce@linux-mips.org
On Fri, 7 Jul 2006 16:22:46 +0100 (BST), "Maciej W. Rozycki" 
<macro@linux-mips.org> wrote:
> > +   .align  5
> > +   LEAF(handle_ri)
> > +   .set    push
> > +   .set    noat
> > +   mfc0    k0, CP0_CAUSE
> > +   MFC0    k1, CP0_EPC
> > +   bltz    k0, handle_ri_slow      /* if delay slot */
> > +   lw      k0, (k1)
> 
>  For a VIVT I-cache this can result in a TLB exception.  TLB handlers are 
> not currently prepared for being called at the exception level.

Thanks, now I understand the problem.  Are there any good solutions?
Only I can think now is using handle_ri_slow for such CPUs.

>  Also I am fairly sure gas won't fill the branch delay slot above -- a 
> trivial rearrangement of code would save a cycle here (and this is a fast 
> path, so we do not want wasting time).

Well, here is a code compiled by binutils 2.17.  This version of gas
can put MFC0 on the delay slot.  But it might be better to use
noreorder by myself.

80012a80 <handle_ri>:
80012a80:       401a6800        mfc0    k0,c0_cause
80012a84:       0740fd2e        bltz    k0,80011f40 <handle_ri_slow>
80012a88:       401b7000        mfc0    k1,c0_epc
80012a8c:       8f7a0000        lw      k0,0(k1)
80012a90:       3c1b7c03        lui     k1,0x7c03
80012a94:       377be83b        ori     k1,k1,0xe83b
80012a98:       175bfd29        bne     k0,k1,80011f40 <handle_ri_slow>
80012a9c:       00000000        nop
80012aa0:       3c1b801b        lui     k1,0x801b
80012aa4:       8f7b4008        lw      k1,16392(k1)
80012aa8:       401a7000        mfc0    k0,c0_epc
80012aac:       275a0004        addiu   k0,k0,4
80012ab0:       409a7000        mtc0    k0,c0_epc
80012ab4:       377b1fff        ori     k1,k1,0x1fff
80012ab8:       3b7b1fff        xori    k1,k1,0x1fff
80012abc:       8f63000c        lw      v1,12(k1)
80012ac0:       42000018        eret

> > +   li      k1, 0x7c03e83b  /* rdhwr v1,$29 */
> > +   bne     k0, k1, handle_ri_slow  /* if not ours */
> > +   get_saved_sp    /* k1 := current_thread_info */
> > +   MFC0    k0, CP0_EPC
> > +   LONG_ADDIU      k0, 4
> 
>  I suggest moving MFC0 ahead of get_saved_sp to avoid a stall.  I would 
> fit in the branch delay slot nicely.

The MFC0 can not be moved.  SMP version of get_saved_sp uses k0 and
k1.  But of course I can use #ifdef CONFIG_SMP, but these assumption
makes the code a bit fragile.  Another performance vs. maintainance
cost issue...

---
Atsushi Nemoto

<Prev in Thread] Current Thread [Next in Thread>