[llvm-commits] [llvm] r135955 - /llvm/trunk/docs/CodeGenerator.html

Bill Wendling isanbard at gmail.com
Mon Jul 25 13:19:48 PDT 2011


Author: void
Date: Mon Jul 25 15:19:48 2011
New Revision: 135955

URL: http://llvm.org/viewvc/llvm-project?rev=135955&view=rev
Log:
An initial description of the compact unwind encoding.

Modified:
    llvm/trunk/docs/CodeGenerator.html

Modified: llvm/trunk/docs/CodeGenerator.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CodeGenerator.html?rev=135955&r1=135954&r2=135955&view=diff
==============================================================================
--- llvm/trunk/docs/CodeGenerator.html (original)
+++ llvm/trunk/docs/CodeGenerator.html Mon Jul 25 15:19:48 2011
@@ -1805,7 +1805,115 @@
 <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>





More information about the llvm-commits mailing list