This is the mail archive of the
mailing list for the GCC project.
Re: How to use a scratch register in "jump" pattern ?
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: stelian at popies dot net
- Cc: avr at gjlay dot de (Georg-Johann Lay), gcc at gnu dot org
- Date: Wed, 11 Mar 2009 15:33:28 +0100 (CET)
- Subject: 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