Bug? flow_find_cross_jump deletes USE insns ...

Ulrich Weigand Ulrich.Weigand@de.ibm.com
Wed Jan 16 11:27:00 GMT 2002


Jan Hubicka wrote:

>I see, then you need PLT for each libcall.  On the i386 if the call is
direct
>(function symbolic address is known at compilation time), it goes to PLT
and
>needs GOT, unless it is static function where IP relative addressing is
used.
>In case it is indirect, it do use address of final function, so it does
not
>need GOT.

Oops, I just noticed I forgot CC's on this mail I sent to Richard,
which shows the call patterns we are using:

>Ah, I see.  This can't really happen on s390 because we are using
>different UNSPEC's to distiguish between the GOT slot containing the
>address of foo (as used for function pointer comparisons) and the PLT
>slot of foo (used for direct calls).
>
>The first will expand (assuming small GOT) to something like
>
> (set (reg <addr>)
>      (mem (plus (reg <got-pointer>)
>                 (const (unspec [(symbol_ref ("foo"))] 110)))))
>
> (call (mem (reg <addr>))
>
>while the second will expand to (basically)
>
> (set (reg <addr>)
>      (const (unspec [(symbol_ref ("foo"))] 113)))
>
> (call (mem (plus (reg <addr>) (reg <literal-pool-base>)))
>
>where the first set is actually a load from the literal pool.
>
>Unspec 110 denotes the offset from the base of the GOT to the
>GOT slot for the function, while unspec 113 denotes the offset
>from the current function's literal pool base to the PLT slot
>of the called function.

So we only really have one call instruction, which implements
'call an effective address'.  We are using this instruction in
different ways:

 - Non-PIC direct calls:
   Load target address (from literal pool) into any
   address register <addr>;
   call <addr>

 - PIC direct calls to static functions:
   Load 'target address' - 'literal pool base' (from pool) into <addr>;
   call <addr>+<literal-pool-base-reg>

 - PIC direct calls to extern functions:
   Load 'PLT stub address' - 'literal pool base' into <addr>
   call <addr>+<literal-pool-base-reg>

 - Indirect calls:
   Load target function pointer into <addr>
   call <addr>

If a function pointer is to be loaded, we have these options:

 - Load function pointer (non-PIC):
   Load target address from literal pool

 - Load function pointer to static function (PIC):
   Load 'target address' - 'literal pool base'; add literal-pool-base-reg.

 - Load function pointer to extern function (PIC with small GOT):
   Dereference <got-register> + <GOT slot offset for function> to
   load address from GOT.

 - Load function pointer to extern function (PIC with big GOT)
   Load <GOT slot offset> from literal pool into <addr>;
   Dereference <got-register> + <addr> to load address from GOT

This should be quite similar to what i386 does, we just have to
adapt the implementation a bit to the different instruction set.
(No PC-relative calls, no addresses as immediate constants.)


Mit freundlichen Gruessen / Best Regards

Ulrich Weigand

--
  Dr. Ulrich Weigand
  Linux for S/390 Design & Development
  IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
  Phone: +49-7031/16-3727   ---   Email: Ulrich.Weigand@de.ibm.com



More information about the Gcc mailing list