This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How to use a scratch register in "jump" pattern ?

Stelian Pop wrote:

> Ok, so I ended up with (omitting the jump lengths for now):
> (define_insn "*jump"
>   [(set (pc)
>         (label_ref (match_operand 0 "" "")))
>    (clobber (match_scratch:QI 1 "=&r"))]
>   ""
>   {
>         return "ldih %1,hi(%l0)\n\t\n\tldil %1,lo(%l0)\n\tijmp (%1)";
>   }
> )
> (define_expand "jump"
>   [(parallel [(set (pc) (label_ref (match_operand 0 "" "")))
>               (clobber (match_scratch:QI 1 ""))])]
>   ""
>   ""
> )
> It doesn't work. It causes a loop somewhere in gcc. I can get a gdb
> trace if needed.

Yes, this does not work.  Jumps are special; the CFG logic makes
a lot of assumptions how jump patterns look.

The s390 back-end has the same requirement that short branches can
be done directly, while long branches need to go via a register.

We've solved this by representing branches using the "normal" direct
jump patterns throughout, and then replacing long branches by
indirect jump patterns during machine-dependent reorg.

Because it is not known at reload time whether or not branches are
long, we cannot allocate registers for long branches dynamically.
The s390 back-end globally reserves a register for the purpose of
holding the target of long branches (well, the register is also 
used as "link register" for calls).

Have a look at the s390_split_branches implementation in s390.c ...


  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]