diff options
author | Bill Wendling <isanbard@gmail.com> | 2011-07-25 20:19:48 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2011-07-25 20:19:48 +0000 |
commit | 66bc5c602aec3a8bfd826699847fc936f7aa9acd (patch) | |
tree | e74ba0c0fd833056fc3ed43d8e6e3d36f9d388da /docs/CodeGenerator.html | |
parent | 54134708f5debe1631f9ea9b232f78758a2151e4 (diff) |
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
Diffstat (limited to 'docs/CodeGenerator.html')
-rw-r--r-- | docs/CodeGenerator.html | 110 |
1 files changed, 109 insertions, 1 deletions
diff --git a/docs/CodeGenerator.html b/docs/CodeGenerator.html index 44b835d858..1d03cbdf1a 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> |