1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<div class="subsubsection-level-extent" id="Local-Register-Variables"> <div class="nav-panel"> <p> Previous: <a href="global-register-variables" accesskey="p" rel="prev">Defining Global Register Variables</a>, Up: <a href="explicit-register-variables" accesskey="u" rel="up">Variables in Specified Registers</a> [<a href="index#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="indices" title="Index" rel="index">Index</a>]</p> </div> <h1 class="subsubsection" id="Specifying-Registers-for-Local-Variables"><span>6.47.5.2 Specifying Registers for Local Variables<a class="copiable-link" href="#Specifying-Registers-for-Local-Variables"> ¶</a></span></h1> <p>You can define a local register variable and associate it with a specified register like this: </p> <div class="example smallexample"> <pre class="example-preformatted" data-language="cpp">register int *foo asm ("r12");</pre>
</div> <p>Here <code class="code">r12</code> is the name of the register that should be used. Note that this is the same syntax used for defining global register variables, but for a local variable the declaration appears within a function. The <code class="code">register</code> keyword is required, and cannot be combined with <code class="code">static</code>. The register name must be a valid register name for the target platform. </p> <p>Do not use type qualifiers such as <code class="code">const</code> and <code class="code">volatile</code>, as the outcome may be contrary to expectations. In particular, when the <code class="code">const</code> qualifier is used, the compiler may substitute the variable with its initializer in <code class="code">asm</code> statements, which may cause the corresponding operand to appear in a different register. </p> <p>As with global register variables, it is recommended that you choose a register that is normally saved and restored by function calls on your machine, so that calls to library routines will not clobber it. </p> <p>The only supported use for this feature is to specify registers for input and output operands when calling Extended <code class="code">asm</code> (see <a class="pxref" href="extended-asm">Extended Asm - Assembler Instructions with C Expression Operands</a>). This may be necessary if the constraints for a particular machine don’t provide sufficient control to select the desired register. To force an operand into a register, create a local variable and specify the register name after the variable’s declaration. Then use the local variable for the <code class="code">asm</code> operand and specify any constraint letter that matches the register: </p> <div class="example smallexample"> <pre class="example-preformatted" data-language="cpp">register int *p1 asm ("r0") = …;
register int *p2 asm ("r1") = …;
register int *result asm ("r0");
asm ("sysint" : "=r" (result) : "0" (p1), "r" (p2));</pre>
</div> <p><em class="emph">Warning:</em> In the above example, be aware that a register (for example <code class="code">r0</code>) can be call-clobbered by subsequent code, including function calls and library calls for arithmetic operators on other variables (for example the initialization of <code class="code">p2</code>). In this case, use temporary variables for expressions between the register assignments: </p> <div class="example smallexample"> <pre class="example-preformatted" data-language="cpp">int t1 = …;
register int *p1 asm ("r0") = …;
register int *p2 asm ("r1") = t1;
register int *result asm ("r0");
asm ("sysint" : "=r" (result) : "0" (p1), "r" (p2));</pre>
</div> <p>Defining a register variable does not reserve the register. Other than when invoking the Extended <code class="code">asm</code>, the contents of the specified register are not guaranteed. For this reason, the following uses are explicitly <em class="emph">not</em> supported. If they appear to work, it is only happenstance, and may stop working as intended due to (seemingly) unrelated changes in surrounding code, or even minor changes in the optimization of a future version of gcc: </p> <ul class="itemize mark-bullet"> <li>Passing parameters to or from Basic <code class="code">asm</code> </li>
<li>Passing parameters to or from Extended <code class="code">asm</code> without using input or output operands. </li>
<li>Passing parameters to or from routines written in assembler (or other languages) using non-standard calling conventions. </li>
</ul> <p>Some developers use Local Register Variables in an attempt to improve gcc’s allocation of registers, especially in large functions. In this case the register name is essentially a hint to the register allocator. While in some instances this can generate better code, improvements are subject to the whims of the allocator/optimizers. Since there are no guarantees that your improvements won’t be lost, this usage of Local Register Variables is discouraged. </p> <p>On the MIPS platform, there is related use for local register variables with slightly different characteristics (see <a data-manual="gccint" href="https://gcc.gnu.org/onlinedocs/gccint/MIPS-Coprocessors.html#MIPS-Coprocessors">Defining coprocessor specifics for MIPS targets</a> in GNU Compiler Collection (GCC) Internals). </p> </div> <div class="nav-panel"> <p> Previous: <a href="global-register-variables">Defining Global Register Variables</a>, Up: <a href="explicit-register-variables">Variables in Specified Registers</a> [<a href="index#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="indices" title="Index" rel="index">Index</a>]</p> </div><div class="_attribution">
<p class="_attribution-p">
© Free Software Foundation<br>Licensed under the GNU Free Documentation License, Version 1.3.<br>
<a href="https://gcc.gnu.org/onlinedocs/gcc-13.1.0/gcc/Local-Register-Variables.html" class="_attribution-link">https://gcc.gnu.org/onlinedocs/gcc-13.1.0/gcc/Local-Register-Variables.html</a>
</p>
</div>
|