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