@ -4086,7 +4086,9 @@ xml:id="dbdoclet.50655240_pgfId-1156194">
protocol requirements for external function calls, and
protocol requirements for external function calls, and
<xref linkend="dbdoclet.50655241_LocalProtocols" /> summarizes the
<xref linkend="dbdoclet.50655241_LocalProtocols" /> summarizes the
protocol requirements for local function calls. Each entry in these
protocol requirements for local function calls. Each entry in these
tables is further described in the referenced section.
tables is further described in the referenced section. A program may
contain any combination of the function call protocols in these
tables.
<note><para>Note that
<note><para>Note that
this ABI does not define protocols where the caller does not use
this ABI does not define protocols where the caller does not use
a TOC pointer, but does preserve r2. It is most efficient when
a TOC pointer, but does preserve r2. It is most efficient when
@ -7899,16 +7901,8 @@ nop</programlisting>
address of the called function to be in r12 when a cross-module function
address of the called function to be in r12 when a cross-module function
call is made.</para>
call is made.</para>
<figure xml:id="dbdoclet.50655240_95364">
<table frame="all" pgwide="1" revisionflag="changed"
<title>Indirect Function Call (Absolute Medium Model)</title>
xml:id="dbdoclet.50655240_95364">
<mediaobject>
<imageobject>
<imagedata fileref="figures/fig2-33.png" format="PNG"
scalefit="1" width="100%" />
</imageobject>
</mediaobject>
</figure>
<!-- table frame="all" pgwide="1" xml:id="dbdoclet.50655240_95364">
<title>Indirect Function Call (Absolute Medium Model)</title>
<title>Indirect Function Call (Absolute Medium Model)</title>
<tgroup cols="2">
<tgroup cols="2">
<colspec colname="c1" colwidth="30*" />
<colspec colname="c1" colwidth="30*" />
@ -7937,7 +7931,9 @@ ptrfunc = function;
(*ptrfunc)( );
(*ptrfunc) ( );
</programlisting>
</programlisting>
@ -7946,34 +7942,27 @@ ptrfunc = function;
<programlisting>
<programlisting>
.section .text
.section .text
lis r11,ptrfunc@ha
lis r11,ptrfunc@ha
lis r9,function@ha
lis r9,function@ha
ld r9,function@l(r9)
ld r9,function@l(r9)
std r9,ptrfunc@l(r11)
std r9,ptrfunc@l(r11)
lis r12,ptrfunc@ha
ld r12,ptrfunc@l(r12)
lis r12,ptrfunc@ha
mtctr r12
ld r12,ptrfunc@l(r12)
mtctr r12
bctrl</programlisting>
bctrl</programlisting>
</entry>
</entry>
</row>
</row>
</tbody>
</tbody>
</tgroup>
</tgroup>
</table -->
</table>
<para>
<para>
<xref linkend="dbdoclet.50655240_16744" /> shows how to make an indirect
<xref linkend="dbdoclet.50655240_16744" /> shows how to make an indirect
function call using small-model position-independent code.
function call using small-model position-independent code.
</para>
</para>
<figure xml:id="dbdoclet.50655240_16744">
<table frame="all" pgwide="1" revisionflag="changed"
<title>Small-Model Position-Independent Indirect Function Call</title>
xml:id="dbdoclet.50655240_16744">
<mediaobject>
<imageobject>
<imagedata fileref="figures/fig2-34.png" format="PNG"
scalefit="1" width="100%" />
</imageobject>
</mediaobject>
</figure>
<!--table frame="all" pgwide="1" xml:id="dbdoclet.50655240_16744">
<title>Small-Model Position-Independent Indirect Function Call</title>
<title>Small-Model Position-Independent Indirect Function Call</title>
<tgroup cols="2">
<tgroup cols="2">
<colspec colname="c1" colwidth="30*" />
<colspec colname="c1" colwidth="30*" />
@ -8002,9 +7991,8 @@ extern void (*ptrfunc) ( );
ptrfunc = function;
ptrfunc = function;
...
(*ptrfunc) ( );
(*ptrfunc) ( );
@ -8015,39 +8003,95 @@ ptrfunc = function;
.section .text
.section .text
/* TOC pointer is in r2 */
/* TOC pointer is in r2 */
ld r9,ptrfunc@got(r2)
ld r9,ptrfunc@got(r2)
ld r0,function@got(r2)
ld r0,function@got(r2)
std r0,0(r9)
std r0,0(r9)
...
ld r9,ptrfunc@got(r2)
ld r9,ptrfunc@got(r2)
ld r12,0(r9)
ld r12,0(r9)
mtctr r12
mtctr r12
std r2,24(r1)
std r2,24(r1)
bctrl
bctrl
ld r2,24(r1)</programlisting>
ld r2,24(r1)</programlisting>
</entry>
</entry>
</row>
</row>
</tbody>
</tbody>
</tgroup>
</tgroup>
</table -->
</table>
<para>
<para>
<xref linkend="dbdoclet.50655240_95225" /> shows how to make an indirect
<xref linkend="dbdoclet.50655240_95225" /> shows how to make an indirect
function call using large-model position-independent code.
function call using large-model position-independent code.
</para>
</para>
<figure xml:id="dbdoclet.50655240_95225">
<table frame="all" pgwide="1" revisionflag="changed"
xml:id="dbdoclet.50655240_95225">
<title>Large-Model Position-Independent Indirect Function Call</title>
<title>Large-Model Position-Independent Indirect Function Call</title>
<mediaobject>
<tgroup cols="2">
<imageobject>
<colspec colname="c1" colwidth="30*" />
<imagedata fileref="figures/fig2-35.png" format="PNG"
<colspec colname="c2" colwidth="70*" />
scalefit="1" width="100%" />
<thead>
</imageobject>
<row>
</mediaobject>
<entry>
</figure>
<para>
<emphasis role="bold">C Code</emphasis>
</para>
</entry>
<entry>
<para>
<emphasis role="bold">Assembly Code</emphasis>
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<programlisting>extern void function( );
extern void (*ptrfunc) ( );
ptrfunc = function;
(*ptrfunc) ( );
</programlisting>
</entry>
<entry>
<programlisting>
.section .text
/* TOC pointer is in r2 */
addis r9,r2,ptrfunc@got@ha
ld r9,ptrfunc@got@l(r9)
addis r12,r2,function@got@ha
ld r12,function@got@l(r12)
std r12,0(r9)
addis r9,r2,ptrfunc@got@ha
ld r9,ptrfunc@got@l(r9)
ld r12,0(r9)
std r2,24(r1)
mtctr r12
bctrl
ld r2,24(r1)</programlisting>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para revisionflag="added">
<para revisionflag="added">
<xref linkend="dbdoclet.50655240_PCRelPICIndirect" /> shows how to
<xref linkend="dbdoclet.50655240_PCRelPICIndirect" /> shows how to
make an indirect function call using PC-relative addressing in a
make an indirect function call using PC-relative addressing in a
function that does not preserve r2. [TBD: Formatting]
function that does not preserve r2.
</para>
</para>
<table frame="all" pgwide="1" revisionflag="added"
<table frame="all" pgwide="1" revisionflag="added"
xml:id="dbdoclet.50655240_PCRelPICIndirect">
xml:id="dbdoclet.50655240_PCRelPICIndirect">
@ -8114,24 +8158,21 @@ bctrl</programlisting>
use the same r2 value. This scheme avoids having a compiler generate an
use the same r2 value. This scheme avoids having a compiler generate an
overconservative r2 save and restore around every external call.</para>
overconservative r2 save and restore around every external call.</para>
<para revisionflag="added">
<para revisionflag="added">
There are two cases where the caller should not provide a nop after
There are two cases where the caller need not provide a nop after
the bl instruction performing a call:
the bl instruction performing a call:
<itemizedlist spacing="compact">
<itemizedlist spacing="compact">
<listitem><para>When the caller is not guaranteed to preserve r2 (see
<listitem><para>When the bl instruction is marked with an
<xref linkend="dbdoclet.50655241_95185" />); or</para></listitem>
R_PPC64_REL24_NOTOC relocation (see
<xref linkend="dbdoclet.50655241_90220" />); or</para></listitem>
<listitem><para>When the callee is in the same compilation unit and
<listitem><para>When the callee is in the same compilation unit and
is guaranteed to preserve r2.</para></listitem>
is guaranteed to preserve r2.</para></listitem>
</itemizedlist>
</itemizedlist>
In the first case, the bl instruction must be marked with an
R_PPC64_REL24_NOTOC relocation. See <xref
linkend="dbdoclet.50655241_90220" />.
</para>
</para>
<para>For calls to functions resolved at runtime, the linker must
<para>For calls to functions resolved at runtime, the linker must
generate stub code to load the function address from the PLT.</para>
generate stub code to load the function address from the PLT.</para>
<para>The stub code also must save r2 to 24(r1) unless
<para>The stub code also must save r2 to 24(r1) unless
<phrase revisionflag="added">either the call is marked with an
<phrase revisionflag="added">either the call is marked with an
R_PPC64_REL24_NOTOC relocation as above, or</phrase>
R_PPC64_REL24_NOTOC relocation, or</phrase> the call is marked
the call is marked
with an R_PPC64_TOCSAVE relocation that points to a nop provided in the
with an R_PPC64_TOCSAVE relocation that points to a nop provided in the
caller's prologue. In <phrase revisionflag="changed">either</phrase>
caller's prologue. In <phrase revisionflag="changed">either</phrase>
case, the stub code can omit the r2 save.
case, the stub code can omit the r2 save.
@ -8165,20 +8206,12 @@ bl target
<xref linkend="dbdoclet.50655240_66111" /> shows the model for branch
<xref linkend="dbdoclet.50655240_66111" /> shows the model for branch
instructions.</para>
instructions.</para>
<figure xml:id="dbdoclet.50655240_66111">
<table frame="all" pgwide="1" revisionflag="changed"
<title>Branch Instruction Model</title>
xml:id="dbdoclet.50655240_66111">
<mediaobject>
<imageobject>
<imagedata fileref="figures/fig2-36.png" format="PNG"
scalefit="1" width="100%" />
</imageobject>
</mediaobject>
</figure>
<!--table frame="all" pgwide="1" xml:id="dbdoclet.50655240_66111">
<title>Branch Instruction Model</title>
<title>Branch Instruction Model</title>
<tgroup cols="2">
<tgroup cols="2">
<colspec colname="c1" colwidth="50*" />
<colspec colname="c1" colwidth="30*" />
<colspec colname="c2" colwidth="50*" />
<colspec colname="c2" colwidth="70*" />
<thead>
<thead>
<row>
<row>
<entry>
<entry>
@ -8203,12 +8236,12 @@ goto label;</programlisting>
<entry>
<entry>
<programlisting>.L01:
<programlisting>.L01:
...
...
b .L01</programlisting>
b .L01</programlisting>
</entry>
</entry>
</row>
</row>
</tbody>
</tbody>
</tgroup>
</tgroup>
</table-->
</table>
<para>Selecting one of multiple branches is accomplished in C with switch
<para>Selecting one of multiple branches is accomplished in C with switch
statements. An address table is used by the compiler to implement the
statements. An address table is used by the compiler to implement the
switch statement selections in cases where the case labels satisfy
switch statement selections in cases where the case labels satisfy
@ -8232,17 +8265,8 @@ b .L01</programlisting>
application) loaded into the low or high address range, absolute
application) loaded into the low or high address range, absolute
addressing of a branch table yields the best performance.</para>
addressing of a branch table yields the best performance.</para>
<figure>
<table frame="all" pgwide="1" revisionflag="changed"
<title>Absolute Switch Code (Within) for static modules located in low
xml:id="dbdoclet.50655240_AbsSwitch">
or high 2 GB of address space</title>
<mediaobject>
<imageobject>
<imagedata fileref="figures/fig2-37.png" format="PNG"
scalefit="1" width="100%" />
</imageobject>
</mediaobject>
</figure>
<!--table frame="all" pgwide="1">
<title>Absolute Switch Code (Within) for static modules located in low
<title>Absolute Switch Code (Within) for static modules located in low
or high 2 GB of address space</title>
or high 2 GB of address space</title>
<tgroup cols="2">
<tgroup cols="2">
@ -8265,7 +8289,7 @@ b .L01</programlisting>
<tbody>
<tbody>
<row>
<row>
<entry>
<entry>
<programlisting>switch(j)
<programlisting>switch (j)
{
{
case 0:
case 0:
...
...
@ -8278,45 +8302,37 @@ default:
}
}
</programlisting>
</programlisting>
</entry>
</entry>
<entry>
<entry>
<programlisting>cmplwi r12, 4
<programlisting>cmplwi r12,4
bge .Ldefault
bge .Ldefault
slwi r12, 2
slwi r12,2
addis r12, r12, .Ltab@ha
addis r12,r12,.Ltab@ha
lwa r12, .Ltab@l(r12)
lwa r12,.Ltab@l(r12)
mtctr r12
mtctr r12
bctr
bctr
.rodata
.rodata
.Ltab:
.Ltab:
.long .Lcase0
.long .Lcase0
.long .Lcase1
.long .Lcase1
.long .Ldefault
.long .Ldefault
.long .Lcase3
.long .Lcase3
.text</programlisting>
.text</programlisting>
</entry>
</entry>
</row>
</row>
</tbody>
</tbody>
</tgroup>
</tgroup>
</table-->
</table>
<note>
<note>
<para>A faster variant of this code may be used to locate branch
<para>A faster variant of this code may be used to locate branch
targets in the bottom 2 GB of the address space in conjunction with the
targets in the bottom 2 GB of the address space in conjunction with the
lwz instruction in place of the lwa instruction.</para>
lwz instruction in place of the lwa instruction.</para>
</note>
</note>
<figure>
<table frame="all" pgwide="1" revisionflag="changed"
<title>Absolute Switch Code (Beyond) for static modules beyond the top
xml:id="dbdoclet.50655240_AbsSwitchBeyond">
or bottom 2 GB of the address space</title>
<mediaobject>
<imageobject>
<imagedata fileref="figures/fig2-38.png" format="PNG"
scalefit="1" width="100%" />
</imageobject>
</mediaobject>
</figure>
<!--table frame="all" pgwide="1">
<title>Absolute Switch Code (Beyond) for static modules beyond the top
<title>Absolute Switch Code (Beyond) for static modules beyond the top
or bottom 2 GB of the address space</title>
or bottom 2 GB of the address space</title>
<tgroup cols="2">
<tgroup cols="2">
@ -8339,7 +8355,7 @@ bctr
<tbody>
<tbody>
<row>
<row>
<entry>
<entry>
<programlisting>switch(j)
<programlisting>switch (j)
{
{
case 0:
case 0:
...
...
@ -8352,28 +8368,29 @@ default:
}
}
</programlisting>
</programlisting>
</entry>
</entry>
<entry>
<entry>
<programlisting>cmplwi r12, 4
<programlisting>cmplwi r12,4
bge .Ldefault
bge .Ldefault
slwi r12, 2
slwi r12,2
addis r12, r12, .Ltab@ha
addis r12,r12,.Ltab@ha
ld r12, .Ltab@l(r12)
ld r12,.Ltab@l(r12)
mtctr r12
mtctr r12
bctr
bctr
.rodata
.rodata
.Ltab:
.Ltab:
.quad .Lcase0
.long .Lcase0
.quad .Lcase1
.long .Lcase1
.quad .Ldefault
.long .Ldefault
.quad .Lcase3
.long .Lcase3
.text</programlisting>
.text</programlisting>
</entry>
</entry>
</row>
</row>
</tbody>
</tbody>
</tgroup>
</tgroup>
</table -->
</table>
<para>For position-independent code targeted at being dynamically loaded
<para>For position-independent code targeted at being dynamically loaded
to different address ranges as DSO, the preferred code pattern uses
to different address ranges as DSO, the preferred code pattern uses
TOC-relative addressing by taking advantage of the fact that the TOC
TOC-relative addressing by taking advantage of the fact that the TOC
@ -8381,19 +8398,10 @@ bctr
relative offsets from the start address of the branch table ensures
relative offsets from the start address of the branch table ensures
position-independence when code is loaded at different addresses.</para>
position-independence when code is loaded at different addresses.</para>
<table frame="all" pgwide="1" revisionflag="changed"
<figure>
xml:id="dbdoclet.50655240_SwitchPicMed">
<title>Position-Independent Switch Code for Small/Medium Models
<title>Position-Independent Switch Code for Small/Medium Models
(preferred, with TOC-relative addressing)</title>
(preferred, with TOC-relative addressing)</title>
<mediaobject>
<imageobject>
<imagedata fileref="figures/fig2-39.png" format="PNG"
scalefit="1" width="100%" />
</imageobject>
</mediaobject>
</figure>
<!--table frame="all" pgwide="1">
<title>Position-Independent Switch Code for Small/Medium Models</title>
<tgroup cols="2">
<tgroup cols="2">
<colspec colname="c1" colwidth="30*" />
<colspec colname="c1" colwidth="30*" />
<colspec colname="c2" colwidth="70*" />
<colspec colname="c2" colwidth="70*" />
@ -8414,7 +8422,7 @@ bctr
<tbody>
<tbody>
<row>
<row>
<entry>
<entry>
<programlisting>switch(j)
<programlisting>switch (j)
{
{
case 0:
case 0:
...
...
@ -8427,28 +8435,29 @@ default:
}
}
</programlisting>
</programlisting>
</entry>
</entry>
<entry>
<entry>
<programlisting>cmplwi r12, 4
<programlisting>cmplwi r12,4
bge .Ldefault
bge .Ldefault
addis r10,r2,(.Ltab-.TOC.)@ha
addis r10,r2,(.Ltab-.TOC.)@ha
addi r10,r10,(.Ltab-.TOC.)@l
addi r10,r10,(.Ltab-.TOC.)@l
slwi r12,2
slwi r12,2
lwax r8,r10,r12
lwax r8,r10,r12
add r10,r8,r10
add r10,r8,r10
mtctr r10
mtctr r10
bctr
bctr
.Ltab:
.Ltab:
.word (.Lcase0-.Ltab)
.word (.Lcase0-.Ltab)
.word (.Lcase1-.Ltab)
.word (.Lcase1-.Ltab)
.word (.Ldefault-.Ltab)
.word (.Ldefault-.Ltab)
.word (.Lcase3-.Ltab)</programlisting>
.word (.Lcase3-.Ltab)</programlisting>
</entry>
</entry>
</row>
</row>
</tbody>
</tbody>
</tgroup>
</tgroup>
</table-->
</table>
<para>For position-independent code targeted at being dynamically loaded
<para>For position-independent code targeted at being dynamically loaded
to different address ranges as a DSO or a position-independent executable
to different address ranges as a DSO or a position-independent executable
(PIE), the preferred code pattern uses TOC-indirect addresses for code
(PIE), the preferred code pattern uses TOC-indirect addresses for code
@ -8457,17 +8466,8 @@ bctr
table ensures position independence when code is loaded at different
table ensures position independence when code is loaded at different
addresses.</para>
addresses.</para>
<figure>
<table frame="all" pgwide="1" revisionflag="changed"
<title>Position-Independent Switch Code for All Models (alternate, with
xml:id="dbdoclet.50655240_SwitchGotAll">
GOT-indirect addressing)</title>
<mediaobject>
<imageobject>
<imagedata fileref="figures/fig2-40.png" format="PNG"
scalefit="1" width="100%" />
</imageobject>
</mediaobject>
</figure>
<!--table frame="all" pgwide="1">
<title>Position-Independent Switch Code for All Models (alternate, with
<title>Position-Independent Switch Code for All Models (alternate, with
GOT-indirect addressing)</title>
GOT-indirect addressing)</title>
<tgroup cols="2">
<tgroup cols="2">
@ -8490,7 +8490,7 @@ bctr
<tbody>
<tbody>
<row>
<row>
<entry>
<entry>
<programlisting>switch(j)
<programlisting>switch (j)
{
{
case 0:
case 0:
...
...
@ -8503,28 +8503,29 @@ default:
}
}
</programlisting>
</programlisting>
</entry>
</entry>
<entry>
<entry>
<programlisting>cmplwi r12, 4
<programlisting>cmplwi r12,4
bge .Ldefault
bge .Ldefault
addis r10,r2,.Ltab@got@ha
addis r10,r2,.Ltab@got@ha
ld r10,.Ltab@got@l(r10)
ld r10,r10,.Ltab@got@l(r10)
slwi r12,2
slwi r12,2
lwax r8,r10,r8
lwax r8,r10,r12
add r10,r8,r12
add r10,r8,r10
mtctr r10
mtctr r10
bctr
bctr
.Ltab:
.Ltab:
.word (.Lcase0-.Ltab)
.word (.Lcase0-.Ltab)
.word (.Lcase1-.Ltab)
.word (.Lcase1-.Ltab)
.word (.Ldefault-.Ltab)
.word (.Ldefault-.Ltab)
.word (.Lcase3-.Ltab)</programlisting>
.word (.Lcase3-.Ltab)</programlisting>
</entry>
</entry>
</row>
</row>
</tbody>
</tbody>
</tgroup>
</tgroup>
</table-->
</table>
<para>
<para>
<xref linkend="dbdoclet.50655240_11405" /> shows how, in the medium code
<xref linkend="dbdoclet.50655240_11405" /> shows how, in the medium code
model, PIC code can be used to avoid using the lwa instruction, which may
model, PIC code can be used to avoid using the lwa instruction, which may
@ -8549,7 +8550,7 @@ f1:
</figure>
</figure>
<para revisionflag="added">
<para revisionflag="added">
<xref linkend="dbdoclet.50655240_PCRelSwitch" /> shows a switch
<xref linkend="dbdoclet.50655240_PCRelSwitch" /> shows a switch
implementation for PC-relative compilation units. [TBD: Formatting]
implementation for PC-relative compilation units.
</para>
</para>
<table frame="all" pgwide="1" xml:id="dbdoclet.50655240_PCRelSwitch"
<table frame="all" pgwide="1" xml:id="dbdoclet.50655240_PCRelSwitch"
revisionflag="added">
revisionflag="added">
@ -8589,6 +8590,7 @@ default:
}
}
</programlisting>
</programlisting>
</entry>
</entry>
<entry>
<entry>