aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2011-07-25 20:19:48 +0000
committerBill Wendling <isanbard@gmail.com>2011-07-25 20:19:48 +0000
commit66bc5c602aec3a8bfd826699847fc936f7aa9acd (patch)
treee74ba0c0fd833056fc3ed43d8e6e3d36f9d388da
parent54134708f5debe1631f9ea9b232f78758a2151e4 (diff)
downloadexternal_llvm-66bc5c602aec3a8bfd826699847fc936f7aa9acd.zip
external_llvm-66bc5c602aec3a8bfd826699847fc936f7aa9acd.tar.gz
external_llvm-66bc5c602aec3a8bfd826699847fc936f7aa9acd.tar.bz2
An initial description of the compact unwind encoding.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135955 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--docs/CodeGenerator.html110
1 files changed, 109 insertions, 1 deletions
diff --git a/docs/CodeGenerator.html b/docs/CodeGenerator.html
index 44b835d..1d03cbd 100644
--- a/docs/CodeGenerator.html
+++ b/docs/CodeGenerator.html
@@ -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>