1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

An initial description of the compact unwind encoding.

llvm-svn: 135955
This commit is contained in:
Bill Wendling 2011-07-25 20:19:48 +00:00
parent 5897422319
commit 27bbd5aa2f

View File

@ -1805,7 +1805,115 @@ $ llc -regalloc=pbqp file.bc -o pbqp.s;
<h3>
<a name="proepicode">Prolog/Epilog Code Insertion</a>
</h3>
<div><p>To Be Written</p></div>
<!-- _______________________________________________________________________ -->
<h4>
<a name="compact_unwind">Compact Unwind</a>
</h4>
<div>
<p>Unwinding out of a function is done virually via DWARF encodings. These
encodings exist in two forms: a Common Information Entry (CIE) and a Frame
Description Entry (FDE). These two tables contain the information necessary
for the unwinder to restore the state of the computer to before the function
was called. However, the tables themselves are rather large. LLVM can use a
"compact unwind" encoding to represent the virtual unwinding.</p>
<p>The compact unwind encoding is a 32-bit value, which is encoded in an
architecture-specific way. It specifies which registers to restore and from
where, and how to unwind out of the funciton. When the linker creates a final
linked image, it will create a <code>__TEXT,__unwind_info</code>
section. This section is a small and fast way for the runtime to access
unwind info for any given function. If we emit compact unwind info for the
function, that compact unwind info will be encoded in
the <code>__TEXT,__unwind_info</code> section. If we emit DWARF unwind info,
the <code>__TEXT,__unwind_info</code> section will contain the offset of the
FDE in the <code>__TEXT,__eh_frame</code> section in the final linked
image.</p>
<p>For X86, there are three modes for the compact unwind encoding:</p>
<ul>
<dt><i>Function with a Frame Pointer (<code>EBP</code> or <code>RBP</code>)</i></dt>
<dd><p><code>EBP/RBP</code>-based frame, where <code>EBP/RBP</code> is pushed
onto the stack immediately after the return address,
then <code>ESP/RSP</code> is moved to <code>EBP/RBP</code>. Thus to
unwind, <code>ESP/RSP</code> is restored with the
current <code>EBP/RBP</code> value, then <code>EBP/RBP</code> is restored
by popping the stack, and the return is done by popping the stack once
more into the PC. All non-volatile registers that need to be restored must
have been saved in a small range on the stack that
starts <code>EBP-4</code> to <code>EBP-1020</code> (<code>RBP-8</code>
to <code>RBP-1020</code>). The offset (divided by 4) is encoded in bits
16-23 (mask: <code>0x00FF0000</code>). The registers saved are encoded in
bits 0-14 (mask: <code>0x00007FFF</code>) as five 3-bit entries from the
following table:</p>
<table border="1" cellspacing="0">
<tr>
<th>Compact Number</th>
<th>i386 Register</th>
<th>x86-64 Regiser</th>
</tr>
<tr>
<td>1</td>
<td><code>EBX</code></td>
<td><code>RBX</code></td>
</tr>
<tr>
<td>2</td>
<td><code>ECX</code></td>
<td><code>R12</code></td>
</tr>
<tr>
<td>3</td>
<td><code>EDX</code></td>
<td><code>R13</code></td>
</tr>
<tr>
<td>4</td>
<td><code>EDI</code></td>
<td><code>R14</code></td>
</tr>
<tr>
<td>5</td>
<td><code>ESI</code></td>
<td><code>R15</code></td>
</tr>
<tr>
<td>6</td>
<td><code>EBP</code></td>
<td><code>RBP</code></td>
</tr>
</table>
</dd>
<dt><i>Frameless with a Small Constant Stack Size (EBP or RBP is not used as a frame pointer)</i></dt>
<dd><p>To return, a constant (encoded in the compact unwind encoding) is added
to the <code>ESP/RSP</code>. Then the return is done by popping the stack
into the PC. All non-volatile registers that need to be restored must have
been saved on the stack immediately after the return address. The stack
size (divided by 4) is encoded in bits 16-23
(mask: <code>0x00FF0000</code>). There is a maximum stack size of 1024
bytes. The number of registers saved is encoded in bits 9-12
(mask: <code>0x00001C00</code>). Bits 0-9 (mask:
<code>0x000003FF</code>) contain which registers were saved and their
order. (See the <code>encodeCompactUnwindRegistersWithoutFrame()</code>
function in <code>lib/Target/X86FrameLowering.cpp</code> for the encoding
algorithm.)</p></dd>
<dt><i>Frameless with a Large Constant Stack Size (EBP or RBP is not used as a frame pointer)</i></dt>
<dd><p>This case is like the "Frameless with a Small Constant Stack Size"
case, but the stack size is too larget to encode in the compact unwind
encoding. Instead it requires that the function contains "<code>subl
$nnnnnn, %esp</code>" in its prolog. The compact encoding contains the
offset to the <code>$nnnnnn</code> value in the funciton in bits 9-12
(mask: <code>0x00001C00</code>).</p></dd>
</ul>
</div>
<!-- ======================================================================= -->
<h3>
<a name="latemco">Late Machine Code Optimizations</a>