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 ...
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
[email protected]