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