On 16 Jun 2006 14:12:29 -0700, Ian Lance Taylor <[EMAIL PROTECTED]> wrote:
> > The RDHWR is executed _before_ evaluating the "arg" value.  For arg ==
> > 0 case, the RDHWR has no point but just a overhead.  Without -O2, the
> > RDHWR is executed _after_ the evaluation, so gcc's optimizer reorder
> > the RDHWR instruction.
> 
> The computation of the address of x was moved outside the
> conditional--that is, both the rdhwr and the addu moved.  You'll have
> to figure out why.  gcc shouldn't move instructions outside of a
> conditional unless they are cheap and don't trap.  This instruction
> doesn't trap, but it's not cheap.

AFAIK on all MIPS CPU the rdhwr generates an exception (trap).

I tried changing "unspec" to "unspec_volatile" in this definition:

(define_insn "tls_get_tp_<mode>"
  [(set (match_operand:P 0 "register_operand" "=v")
        (unspec:P [(const_int 0)]
                  UNSPEC_TLS_GET_TP))]
  "HAVE_AS_TLS && !TARGET_MIPS16"
  ".set\tpush\;.set\tmips32r2\t\;rdhwr\t%0,$29\;.set\tpop"
  [(set_attr "type" "unknown")
   (set_attr "mode" "<MODE>")])

With "unspec_volatile", gcc do not move the rdhwr before the branch.
But this change has bad side effects.  For example, if I incremented a
thread local variable, rdhwr is used twice (for load and store).

So I suppose we should tell gcc that rdhwr is not cheap.  But I do not
know how to describe such information in .md file...

---
Atsushi Nemoto

Reply via email to