</li>
<li><a href="#typesystem">Type System</a>
<ol>
+ <li><a href="#t_classifications">Type Classifications</a></li>
<li><a href="#t_primitive">Primitive Types</a>
<ol>
- <li><a href="#t_classifications">Type Classifications</a></li>
+ <li><a href="#t_floating">Floating Point Types</a></li>
+ <li><a href="#t_void">Void Type</a></li>
+ <li><a href="#t_label">Label Type</a></li>
</ol>
</li>
<li><a href="#t_derived">Derived Types</a>
<ol>
+ <li><a href="#t_integer">Integer Type</a></li>
<li><a href="#t_array">Array Type</a></li>
<li><a href="#t_function">Function Type</a></li>
<li><a href="#t_pointer">Pointer Type</a></li>
<li><a href="#i_select">'<tt>select</tt>' Instruction</a></li>
<li><a href="#i_call">'<tt>call</tt>' Instruction</a></li>
<li><a href="#i_va_arg">'<tt>va_arg</tt>' Instruction</a></li>
+ <li><a href="#i_getresult">'<tt>getresult</tt>' Instruction</a></li>
</ol>
</li>
</ol>
<li><a href="#int_it">'<tt>llvm.init.trampoline</tt>' Intrinsic</a></li>
</ol>
</li>
+ <li><a href="#int_atomics">Atomic intrinsics</a>
+ <ol>
+ <li><a href="#int_memory_barrier"><tt>llvm.memory_barrier</tt></a></li>
+ <li><a href="#int_atomic_lcs"><tt>llvm.atomic.lcs</tt></a></li>
+ <li><a href="#int_atomic_las"><tt>llvm.atomic.las</tt></a></li>
+ <li><a href="#int_atomic_swap"><tt>llvm.atomic.swap</tt></a></li>
+ </ol>
+ </li>
<li><a href="#int_general">General intrinsics</a>
<ol>
<li><a href="#int_var_annotation">
<tt>llvm.var.annotation</tt>' Intrinsic</a></li>
- </ol>
- <ol>
<li><a href="#int_annotation">
<tt>llvm.annotation.*</tt>' Intrinsic</a></li>
+ <li><a href="#int_trap">
+ <tt>llvm.trap</tt>' Intrinsic</a></li>
</ol>
</li>
</ol>
<p>A global variable may be declared to reside in a target-specifc numbered
address space. For targets that support them, address spaces may affect how
optimizations are performed and/or what target instructions are used to access
-the variable. The default address space is zero.</p>
+the variable. The default address space is zero. The address space qualifier
+must precede any other attributes.</p>
<p>LLVM allows an explicit section to be specified for globals. If the target
supports it, it will emit globals to the section specified.</p>
</div>
<div class="doc_text">
<p>Aliases act as "second name" for the aliasee value (which can be either
- function or global variable or bitcast of global value). Aliases may have an
- optional <a href="#linkage">linkage type</a>, and an
+ function, global variable, another alias or bitcast of global value). Aliases
+ may have an optional <a href="#linkage">linkage type</a>, and an
optional <a href="#visibility">visibility style</a>.</p>
<h5>Syntax:</h5>
<dt><tt>zeroext</tt></dt>
<dd>This indicates that the parameter should be zero extended just before
a call to this function.</dd>
+
<dt><tt>signext</tt></dt>
<dd>This indicates that the parameter should be sign extended just before
a call to this function.</dd>
+
<dt><tt>inreg</tt></dt>
<dd>This indicates that the parameter should be placed in register (if
possible) during assembling function call. Support for this attribute is
target-specific</dd>
+
+ <dt><tt>byval</tt></dt>
+ <dd>This indicates that the pointer parameter should really be passed by
+ value to the function. The attribute implies that a hidden copy of the
+ pointee is made between the caller and the callee, so the callee is unable
+ to modify the value in the callee. This attribute is only valid on llvm
+ pointer arguments. It is generally used to pass structs and arrays by
+ value, but is also valid on scalars (even though this is silly).</dd>
+
<dt><tt>sret</tt></dt>
- <dd>This indicates that the parameter specifies the address of a structure
- that is the return value of the function in the source program.</dd>
+ <dd>This indicates that the pointer parameter specifies the address of a
+ structure that is the return value of the function in the source program.
+ Loads and stores to the structure are assumed not to trap.
+ May only be applied to the first parameter.</dd>
+
<dt><tt>noalias</tt></dt>
- <dd>This indicates that the parameter not alias any other object or any
- other "noalias" objects during the function call.
+ <dd>This indicates that the parameter does not alias any global or any other
+ parameter. The caller is responsible for ensuring that this is the case,
+ usually by placing the value in a stack allocation.</dd>
+
<dt><tt>noreturn</tt></dt>
<dd>This function attribute indicates that the function never returns. This
indicates to LLVM that every call to this function should be treated as if
an <tt>unreachable</tt> instruction immediately followed the call.</dd>
+
<dt><tt>nounwind</tt></dt>
- <dd>This function attribute indicates that the function type does not use
- the unwind instruction and does not allow stack unwinding to propagate
- through it.</dd>
+ <dd>This function attribute indicates that no exceptions unwind out of the
+ function. Usually this is because the function makes no use of exceptions,
+ but it may also be that the function catches any exceptions thrown when
+ executing it.</dd>
+
<dt><tt>nest</tt></dt>
<dd>This indicates that the parameter can be excised using the
<a href="#int_trampoline">trampoline intrinsics</a>.</dd>
</div>
<!-- ======================================================================= -->
-<div class="doc_subsection"> <a name="t_primitive">Primitive Types</a> </div>
-<div class="doc_text">
-<p>The primitive types are the fundamental building blocks of the LLVM
-system. The current set of primitive types is as follows:</p>
-
-<table class="layout">
- <tr class="layout">
- <td class="left">
- <table>
- <tbody>
- <tr><th>Type</th><th>Description</th></tr>
- <tr><td><tt><a name="t_void">void</a></tt></td><td>No value</td></tr>
- <tr><td><tt>label</tt></td><td>Branch destination</td></tr>
- </tbody>
- </table>
- </td>
- <td class="right">
- <table>
- <tbody>
- <tr><th>Type</th><th>Description</th></tr>
- <tr><td><tt>float</tt></td><td>32-bit floating point value</td></tr>
- <tr><td><tt>double</tt></td><td>64-bit floating point value</td></tr>
- </tbody>
- </table>
- </td>
- </tr>
-</table>
-</div>
-
-<!-- _______________________________________________________________________ -->
-<div class="doc_subsubsection"> <a name="t_classifications">Type
+<div class="doc_subsection"> <a name="t_classifications">Type
Classifications</a> </div>
<div class="doc_text">
-<p>These different primitive types fall into a few useful
+<p>The types fall into a few useful
classifications:</p>
<table border="1" cellspacing="0" cellpadding="4">
<tbody>
<tr><th>Classification</th><th>Types</th></tr>
<tr>
- <td><a name="t_integer">integer</a></td>
+ <td><a href="#t_integer">integer</a></td>
<td><tt>i1, i2, i3, ... i8, ... i16, ... i32, ... i64, ... </tt></td>
</tr>
<tr>
- <td><a name="t_floating">floating point</a></td>
- <td><tt>float, double</tt></td>
+ <td><a href="#t_floating">floating point</a></td>
+ <td><tt>float, double, x86_fp80, fp128, ppc_fp128</tt></td>
</tr>
<tr>
<td><a name="t_firstclass">first class</a></td>
- <td><tt>i1, ..., float, double, <br/>
- <a href="#t_pointer">pointer</a>,<a href="#t_vector">vector</a></tt>
+ <td><a href="#t_integer">integer</a>,
+ <a href="#t_floating">floating point</a>,
+ <a href="#t_pointer">pointer</a>,
+ <a href="#t_vector">vector</a>
</td>
</tr>
+ <tr>
+ <td><a href="#t_primitive">primitive</a></td>
+ <td><a href="#t_label">label</a>,
+ <a href="#t_void">void</a>,
+ <a href="#t_integer">integer</a>,
+ <a href="#t_floating">floating point</a>.</td>
+ </tr>
+ <tr>
+ <td><a href="#t_derived">derived</a></td>
+ <td><a href="#t_integer">integer</a>,
+ <a href="#t_array">array</a>,
+ <a href="#t_function">function</a>,
+ <a href="#t_pointer">pointer</a>,
+ <a href="#t_struct">structure</a>,
+ <a href="#t_pstruct">packed structure</a>,
+ <a href="#t_vector">vector</a>,
+ <a href="#t_opaque">opaque</a>.
+ </tr>
</tbody>
</table>
manipulated either by pointer or by component.</p>
</div>
+<!-- ======================================================================= -->
+<div class="doc_subsection"> <a name="t_primitive">Primitive Types</a> </div>
+
+<div class="doc_text">
+<p>The primitive types are the fundamental building blocks of the LLVM
+system.</p>
+
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection"> <a name="t_floating">Floating Point Types</a> </div>
+
+<div class="doc_text">
+ <table>
+ <tbody>
+ <tr><th>Type</th><th>Description</th></tr>
+ <tr><td><tt>float</tt></td><td>32-bit floating point value</td></tr>
+ <tr><td><tt>double</tt></td><td>64-bit floating point value</td></tr>
+ <tr><td><tt>fp128</tt></td><td>128-bit floating point value (112-bit mantissa)</td></tr>
+ <tr><td><tt>x86_fp80</tt></td><td>80-bit floating point value (X87)</td></tr>
+ <tr><td><tt>ppc_fp128</tt></td><td>128-bit floating point value (two 64-bits)</td></tr>
+ </tbody>
+ </table>
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection"> <a name="t_void">Void Type</a> </div>
+
+<div class="doc_text">
+<h5>Overview:</h5>
+<p>The void type does not represent any value and has no size.</p>
+
+<h5>Syntax:</h5>
+
+<pre>
+ void
+</pre>
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection"> <a name="t_label">Label Type</a> </div>
+
+<div class="doc_text">
+<h5>Overview:</h5>
+<p>The label type represents code labels.</p>
+
+<h5>Syntax:</h5>
+
+<pre>
+ label
+</pre>
+</div>
+
+
<!-- ======================================================================= -->
<div class="doc_subsection"> <a name="t_derived">Derived Types</a> </div>
<h5>Examples:</h5>
<table class="layout">
- <tr class="layout">
- <td class="left">
- <tt>i1</tt><br/>
- <tt>i4</tt><br/>
- <tt>i8</tt><br/>
- <tt>i16</tt><br/>
- <tt>i32</tt><br/>
- <tt>i42</tt><br/>
- <tt>i64</tt><br/>
- <tt>i1942652</tt><br/>
- </td>
- <td class="left">
- A boolean integer of 1 bit<br/>
- A nibble sized integer of 4 bits.<br/>
- A byte sized integer of 8 bits.<br/>
- A half word sized integer of 16 bits.<br/>
- A word sized integer of 32 bits.<br/>
- An integer whose bit width is the answer. <br/>
- A double word sized integer of 64 bits.<br/>
- A really big integer of over 1 million bits.<br/>
- </td>
+ <tbody>
+ <tr>
+ <td><tt>i1</tt></td>
+ <td>a single-bit integer.</td>
+ </tr><tr>
+ <td><tt>i32</tt></td>
+ <td>a 32-bit integer.</td>
+ </tr><tr>
+ <td><tt>i1942652</tt></td>
+ <td>a really big integer of over 1 million bits.</td>
</tr>
+ </tbody>
</table>
</div>
<h5>Examples:</h5>
<table class="layout">
<tr class="layout">
- <td class="left">
- <tt>[40 x i32 ]</tt><br/>
- <tt>[41 x i32 ]</tt><br/>
- <tt>[40 x i8]</tt><br/>
- </td>
- <td class="left">
- Array of 40 32-bit integer values.<br/>
- Array of 41 32-bit integer values.<br/>
- Array of 40 8-bit integer values.<br/>
- </td>
+ <td class="left"><tt>[40 x i32]</tt></td>
+ <td class="left">Array of 40 32-bit integer values.</td>
+ </tr>
+ <tr class="layout">
+ <td class="left"><tt>[41 x i32]</tt></td>
+ <td class="left">Array of 41 32-bit integer values.</td>
+ </tr>
+ <tr class="layout">
+ <td class="left"><tt>[4 x i8]</tt></td>
+ <td class="left">Array of 4 8-bit integer values.</td>
</tr>
</table>
<p>Here are some examples of multidimensional arrays:</p>
<table class="layout">
<tr class="layout">
- <td class="left">
- <tt>[3 x [4 x i32]]</tt><br/>
- <tt>[12 x [10 x float]]</tt><br/>
- <tt>[2 x [3 x [4 x i16]]]</tt><br/>
- </td>
- <td class="left">
- 3x4 array of 32-bit integer values.<br/>
- 12x10 array of single precision floating point values.<br/>
- 2x3x4 array of 16-bit integer values.<br/>
- </td>
+ <td class="left"><tt>[3 x [4 x i32]]</tt></td>
+ <td class="left">3x4 array of 32-bit integer values.</td>
+ </tr>
+ <tr class="layout">
+ <td class="left"><tt>[12 x [10 x float]]</tt></td>
+ <td class="left">12x10 array of single precision floating point values.</td>
+ </tr>
+ <tr class="layout">
+ <td class="left"><tt>[2 x [3 x [4 x i16]]]</tt></td>
+ <td class="left">2x3x4 array of 16-bit integer values.</td>
</tr>
</table>
<div class="doc_text">
<h5>Overview:</h5>
<p>The function type can be thought of as a function signature. It
-consists of a return type and a list of formal parameter types.
-Function types are usually used to build virtual function tables
+consists of a return type and a list of formal parameter types. The
+return type of a function type is a scalar type or a struct type. If the
+return type is a struct type then all struct elements must be of first
+class types. Function types are usually used to build virtual function tables
(which are structures of pointers to functions), for indirect function
calls, and when defining a function.</p>
-<p>
-The return type of a function type cannot be an aggregate type.
-</p>
+
<h5>Syntax:</h5>
-<pre> <returntype> (<parameter list>)<br></pre>
+<pre> <returntype list> (<parameter list>)<br></pre>
<p>...where '<tt><parameter list></tt>' is a comma-separated list of type
specifiers. Optionally, the parameter list may include a type <tt>...</tt>,
which indicates that the function takes a variable number of arguments.
Variable argument functions can access their arguments with the <a
- href="#int_varargs">variable argument handling intrinsic</a> functions.</p>
+ href="#int_varargs">variable argument handling intrinsic</a> functions.
+'<tt><returntype list></tt>' is a comma-separated list of
+<a href="#t_firstclass">first class</a> type specifiers.</p>
<h5>Examples:</h5>
<table class="layout">
<tr class="layout">
which returns an integer. This is the signature for <tt>printf</tt> in
LLVM.
</td>
+ </tr><tr class="layout">
+ <td class="left"><tt>{i32, i32} (i32)</tt></td>
+ <td class="left">A function taking an <tt>i32></tt>, returning two
+ <tt> i32 </tt> values as an aggregate of type <tt>{ i32, i32 }</tt>
+ </td>
</tr>
</table>
<td class="left"><tt>< { i32, i32, i32 } ></tt></td>
<td class="left">A triple of three <tt>i32</tt> values</td>
</tr><tr class="layout">
- <td class="left"><tt>< { float, i32 (i32) * } ></tt></td>
+ <td class="left"><tt>< { float, i32 (i32)* } ></tt></td>
<td class="left">A pair, where the first element is a <tt>float</tt> and the
second element is a <a href="#t_pointer">pointer</a> to a
<a href="#t_function">function</a> that takes an <tt>i32</tt>, returning
<h5>Examples:</h5>
<table class="layout">
<tr class="layout">
- <td class="left">
- <tt>[4x i32]*</tt><br/>
- <tt>i32 (i32 *) *</tt><br/>
- <tt>i32 addrspace(5)*</tt><br/>
- </td>
- <td class="left">
- A <a href="#t_pointer">pointer</a> to <a href="#t_array">array</a> of
- four <tt>i32</tt> values<br/>
- A <a href="#t_pointer">pointer</a> to a <a
+ <td class="left"><tt>[4x i32]*</tt></td>
+ <td class="left">A <a href="#t_pointer">pointer</a> to <a
+ href="#t_array">array</a> of four <tt>i32</tt> values.</td>
+ </tr>
+ <tr class="layout">
+ <td class="left"><tt>i32 (i32 *) *</tt></td>
+ <td class="left"> A <a href="#t_pointer">pointer</a> to a <a
href="#t_function">function</a> that takes an <tt>i32*</tt>, returning an
- <tt>i32</tt>.<br/>
- A <a href="#t_pointer">pointer</a> to an <tt>i32</tt> value that resides
- in address space 5.<br/>
- </td>
+ <tt>i32</tt>.</td>
+ </tr>
+ <tr class="layout">
+ <td class="left"><tt>i32 addrspace(5)*</tt></td>
+ <td class="left">A <a href="#t_pointer">pointer</a> to an <tt>i32</tt> value
+ that resides in address space #5.</td>
</tr>
</table>
</div>
<table class="layout">
<tr class="layout">
- <td class="left">
- <tt><4 x i32></tt><br/>
- <tt><8 x float></tt><br/>
- <tt><2 x i64></tt><br/>
- </td>
- <td class="left">
- Vector of 4 32-bit integer values.<br/>
- Vector of 8 floating-point values.<br/>
- Vector of 2 64-bit integer values.<br/>
- </td>
+ <td class="left"><tt><4 x i32></tt></td>
+ <td class="left">Vector of 4 32-bit integer values.</td>
+ </tr>
+ <tr class="layout">
+ <td class="left"><tt><8 x float></tt></td>
+ <td class="left">Vector of 8 32-bit floating-point values.</td>
+ </tr>
+ <tr class="layout">
+ <td class="left"><tt><2 x i64></tt></td>
+ <td class="left">Vector of 2 64-bit integer values.</td>
</tr>
</table>
</div>
<table class="layout">
<tr class="layout">
- <td class="left">
- <tt>opaque</tt>
- </td>
- <td class="left">
- An opaque type.<br/>
- </td>
+ <td class="left"><tt>opaque</tt></td>
+ <td class="left">An opaque type.</td>
</tr>
</table>
</div>
<dd>Structure constants are represented with notation similar to structure
type definitions (a comma separated list of elements, surrounded by braces
- (<tt>{}</tt>)). For example: "<tt>{ i32 4, float 17.0, i32* %G }</tt>",
- where "<tt>%G</tt>" is declared as "<tt>@G = external global i32</tt>". Structure constants
+ (<tt>{}</tt>)). For example: "<tt>{ i32 4, float 17.0, i32* @G }</tt>",
+ where "<tt>@G</tt>" is declared as "<tt>@G = external global i32</tt>". Structure constants
must have <a href="#t_struct">structure type</a>, and the number and
types of elements must match those specified by the type.
</dd>
<h5>Syntax:</h5>
<pre> ret <type> <value> <i>; Return a value from a non-void function</i>
ret void <i>; Return from void function</i>
+ ret <type> <value>, <type> <value> <i>; Return two values from a non-void function </i>
</pre>
<h5>Overview:</h5>
<p>The '<tt>ret</tt>' instruction is used to return control flow (and a
returns a value and then causes control flow, and one that just causes
control flow to occur.</p>
<h5>Arguments:</h5>
-<p>The '<tt>ret</tt>' instruction may return any '<a
- href="#t_firstclass">first class</a>' type. Notice that a function is
-not <a href="#wellformed">well formed</a> if there exists a '<tt>ret</tt>'
-instruction inside of the function that returns a value that does not
-match the return type of the function.</p>
+<p>The '<tt>ret</tt>' instruction may return one or multiple values. The
+type of each return value must be a '<a href="#t_firstclass">first class</a>'
+ type. Note that a function is not <a href="#wellformed">well formed</a>
+if there exists a '<tt>ret</tt>' instruction inside of the function that
+returns values that do not match the return type of the function.</p>
<h5>Semantics:</h5>
<p>When the '<tt>ret</tt>' instruction is executed, control flow
returns back to the calling function's context. If the caller is a "<a
href="#i_invoke"><tt>invoke</tt></a>" instruction, execution continues
at the beginning of the "normal" destination block. If the instruction
returns a value, that value shall set the call or invoke instruction's
-return value.</p>
+return value. If the instruction returns multiple values then these
+values can only be accessed through a '<a href="#i_getresult"><tt>getresult</tt>
+</a>' instruction.</p>
<h5>Example:</h5>
<pre> ret i32 5 <i>; Return an integer value of 5</i>
ret void <i>; Return from a void function</i>
+ ret i32 4, i8 2 <i>; Return two values 4 and 2 </i>
</pre>
</div>
<!-- _______________________________________________________________________ -->
<h5>Syntax:</h5>
<pre>
- <result> = invoke [<a href="#callingconv">cconv</a>] <ptr to function ty> %<function ptr val>(<function args>)
+ <result> = invoke [<a href="#callingconv">cconv</a>] <ptr to function ty> <function ptr val>(<function args>)
to label <normal label> unwind label <exception label>
</pre>
"<tt><a href="#i_ret">ret</a></tt>" instruction, control flow will return to the
"normal" label. If the callee (or any indirect callees) returns with the "<a
href="#i_unwind"><tt>unwind</tt></a>" instruction, control is interrupted and
-continued at the dynamically nearest "exception" label.</p>
+continued at the dynamically nearest "exception" label. If the callee function
+returns multiple values then individual return values are only accessible through
+a '<tt><a href="#i_getresult">getresult</a></tt>' instruction.</p>
<h5>Arguments:</h5>
<h5>Example:</h5>
<pre>
- %retval = invoke i32 %Test(i32 15) to label %Continue
+ %retval = invoke i32 @Test(i32 15) to label %Continue
unwind label %TestCleanup <i>; {i32}:retval set</i>
- %retval = invoke <a href="#callingconv">coldcc</a> i32 %Test(i32 15) to label %Continue
+ %retval = invoke <a href="#callingconv">coldcc</a> i32 %Testfnptr(i32 15) to label %Continue
unwind label %TestCleanup <i>; {i32}:retval set</i>
</pre>
</div>
<h5>Semantics:</h5>
<p>The value produced is the integer or floating point sum of the two
operands.</p>
+<p>If an integer sum has unsigned overflow, the result returned is the
+mathematical result modulo 2<sup>n</sup>, where n is the bit width of
+the result.</p>
+<p>Because LLVM integers use a two's complement representation, this
+instruction is appropriate for both signed and unsigned integers.</p>
<h5>Example:</h5>
<pre> <result> = add i32 4, %var <i>; yields {i32}:result = 4 + %var</i>
</pre>
<h5>Semantics:</h5>
<p>The value produced is the integer or floating point difference of
the two operands.</p>
+<p>If an integer difference has unsigned overflow, the result returned is the
+mathematical result modulo 2<sup>n</sup>, where n is the bit width of
+the result.</p>
+<p>Because LLVM integers use a two's complement representation, this
+instruction is appropriate for both signed and unsigned integers.</p>
<h5>Example:</h5>
<pre>
<result> = sub i32 4, %var <i>; yields {i32}:result = 4 - %var</i>
<h5>Semantics:</h5>
<p>The value produced is the integer or floating point product of the
two operands.</p>
-<p>Because the operands are the same width, the result of an integer
-multiplication is the same whether the operands should be deemed unsigned or
-signed.</p>
+<p>If the result of an integer multiplication has unsigned overflow,
+the result returned is the mathematical result modulo
+2<sup>n</sup>, where n is the bit width of the result.</p>
+<p>Because LLVM integers use a two's complement representation, and the
+result is the same width as the operands, this instruction returns the
+correct result for both signed and unsigned integers. If a full product
+(e.g. <tt>i32</tt>x<tt>i32</tt>-><tt>i64</tt>) is needed, the operands
+should be sign-extended or zero-extended as appropriate to the
+width of the full product.</p>
<h5>Example:</h5>
<pre> <result> = mul i32 4, %var <i>; yields {i32}:result = 4 * %var</i>
</pre>
types. This instruction can also take <a href="#t_vector">vector</a> versions
of the values in which case the elements must be integers.</p>
<h5>Semantics:</h5>
-<p>The value produced is the unsigned integer quotient of the two operands. This
-instruction always performs an unsigned division operation, regardless of
-whether the arguments are unsigned or not.</p>
+<p>The value produced is the unsigned integer quotient of the two operands.</p>
+<p>Note that unsigned integer division and signed integer division are distinct
+operations; for signed integer division, use '<tt>sdiv</tt>'.</p>
+<p>Division by zero leads to undefined behavior.</p>
<h5>Example:</h5>
<pre> <result> = udiv i32 4, %var <i>; yields {i32}:result = 4 / %var</i>
</pre>
types. This instruction can also take <a href="#t_vector">vector</a> versions
of the values in which case the elements must be integers.</p>
<h5>Semantics:</h5>
-<p>The value produced is the signed integer quotient of the two operands. This
-instruction always performs a signed division operation, regardless of whether
-the arguments are signed or not.</p>
+<p>The value produced is the signed integer quotient of the two operands.</p>
+<p>Note that signed integer division and unsigned integer division are distinct
+operations; for unsigned integer division, use '<tt>udiv</tt>'.</p>
+<p>Division by zero leads to undefined behavior. Overflow also leads to
+undefined behavior; this is a rare case, but can occur, for example,
+by doing a 32-bit division of -2147483648 by -1.</p>
<h5>Example:</h5>
<pre> <result> = sdiv i32 4, %var <i>; yields {i32}:result = 4 / %var</i>
</pre>
<p>This instruction returns the unsigned integer <i>remainder</i> of a division.
This instruction always performs an unsigned division to get the remainder,
regardless of whether the arguments are unsigned or not.</p>
+<p>Note that unsigned integer remainder and signed integer remainder are
+distinct operations; for signed integer remainder, use '<tt>srem</tt>'.</p>
+<p>Taking the remainder of a division by zero leads to undefined behavior.</p>
<h5>Example:</h5>
<pre> <result> = urem i32 4, %var <i>; yields {i32}:result = 4 % %var</i>
</pre>
signed division of its two operands. This instruction can also take
<a href="#t_vector">vector</a> versions of the values in which case
the elements must be integers.</p>
-</p>
+
<h5>Arguments:</h5>
<p>The two arguments to the '<tt>srem</tt>' instruction must be
<a href="#t_integer">integer</a> values. Both arguments must have identical
Math Forum</a>. For a table of how this is implemented in various languages,
please see <a href="http://en.wikipedia.org/wiki/Modulo_operation">
Wikipedia: modulo operation</a>.</p>
+<p>Note that signed integer remainder and unsigned integer remainder are
+distinct operations; for unsigned integer remainder, use '<tt>urem</tt>'.</p>
+<p>Taking the remainder of a division by zero leads to undefined behavior.
+Overflow also leads to undefined behavior; this is a rare case, but can occur,
+for example, by taking the remainder of a 32-bit division of -2147483648 by -1.
+(The remainder doesn't actually overflow, but this rule lets srem be
+implemented using instructions that return both the result of the division
+and the remainder.)</p>
<h5>Example:</h5>
<pre> <result> = srem i32 4, %var <i>; yields {i32}:result = 4 % %var</i>
</pre>
<h5>Overview:</h5>
<p>The '<tt>malloc</tt>' instruction allocates memory from the system
-heap and returns a pointer to it.</p>
+heap and returns a pointer to it. The object is always allocated in the generic
+address space (address space zero).</p>
<h5>Arguments:</h5>
<tt>sizeof(<type>)*NumElements</tt>
bytes of memory from the operating system and returns a pointer of the
appropriate type to the program. If "NumElements" is specified, it is the
-number of elements allocated. If an alignment is specified, the value result
-of the allocation is guaranteed to be aligned to at least that boundary. If
-not specified, or if zero, the target can choose to align the allocation on any
-convenient boundary.</p>
+number of elements allocated, otherwise "NumElements" is defaulted to be one.
+If an alignment is specified, the value result of the allocation is guaranteed to
+be aligned to at least that boundary. If not specified, or if zero, the target can
+choose to align the allocation on any convenient boundary.</p>
<p>'<tt>type</tt>' must be a sized type.</p>
<p>The '<tt>alloca</tt>' instruction allocates memory on the stack frame of the
currently executing function, to be automatically released when this function
-returns to its caller.</p>
+returns to its caller. The object is always allocated in the generic address
+space (address space zero).</p>
<h5>Arguments:</h5>
<p>The '<tt>alloca</tt>' instruction allocates <tt>sizeof(<type>)*NumElements</tt>
bytes of memory on the runtime stack, returning a pointer of the
-appropriate type to the program. If "NumElements" is specified, it is the
-number of elements allocated. If an alignment is specified, the value result
-of the allocation is guaranteed to be aligned to at least that boundary. If
-not specified, or if zero, the target can choose to align the allocation on any
-convenient boundary.</p>
+appropriate type to the program. If "NumElements" is specified, it is the
+number of elements allocated, otherwise "NumElements" is defaulted to be one.
+If an alignment is specified, the value result of the allocation is guaranteed
+to be aligned to at least that boundary. If not specified, or if zero, the target
+can choose to align the allocation on any convenient boundary.</p>
<p>'<tt>type</tt>' may be any sized type.</p>
the number or order of execution of this <tt>load</tt> with other
volatile <tt>load</tt> and <tt><a href="#i_store">store</a></tt>
instructions. </p>
+<p>
+The optional "align" argument specifies the alignment of the operation
+(that is, the alignment of the memory address). A value of 0 or an
+omitted "align" argument means that the operation has the preferential
+alignment for the target. It is the responsibility of the code emitter
+to ensure that the alignment information is correct. Overestimating
+the alignment results in an undefined behavior. Underestimating the
+alignment may produce less efficient code. An alignment of 1 is always
+safe.
+</p>
<h5>Semantics:</h5>
<p>The location of memory pointed to is loaded.</p>
<h5>Examples:</h5>
optimizer is not allowed to modify the number or order of execution of
this <tt>store</tt> with other volatile <tt>load</tt> and <tt><a
href="#i_store">store</a></tt> instructions.</p>
+<p>
+The optional "align" argument specifies the alignment of the operation
+(that is, the alignment of the memory address). A value of 0 or an
+omitted "align" argument means that the operation has the preferential
+alignment for the target. It is the responsibility of the code emitter
+to ensure that the alignment information is correct. Overestimating
+the alignment results in an undefined behavior. Underestimating the
+alignment may produce less efficient code. An alignment of 1 is always
+safe.
+</p>
<h5>Semantics:</h5>
<p>The contents of memory are updated to contain '<tt><value></tt>'
at the location specified by the '<tt><pointer></tt>' operand.</p>
the specified values. Upon a '<tt><a href="#i_ret">ret</a></tt>'
instruction in the called function, control flow continues with the
instruction after the function call, and the return value of the
-function is bound to the result argument. This is a simpler case of
-the <a href="#i_invoke">invoke</a> instruction.</p>
+function is bound to the result argument. If the callee returns multiple
+values then the return values of the function are only accessible through
+the '<tt><a href="#i_getresult">getresult</a></tt>' instruction.</p>
<h5>Example:</h5>
<pre>
%retval = call i32 @test(i32 %argc)
- call i32 (i8 *, ...)* @printf(i8 * %msg, i32 12, i8 42);
- %X = tail call i32 @foo()
- %Y = tail call <a href="#callingconv">fastcc</a> i32 @foo()
- %Z = call void %foo(i8 97 signext)
+ call i32 (i8 *, ...)* @printf(i8 * %msg, i32 12, i8 42) <i>; yields i32</i>
+ %X = tail call i32 @foo() <i>; yields i32</i>
+ %Y = tail call <a href="#callingconv">fastcc</a> i32 @foo() <i>; yields i32</i>
+ call void %foo(i8 97 signext)
+
+ %struct.A = type { i32, i8 }
+ %r = call %struct.A @foo() <i>; yields { 32, i8 }</i>
+ %gr = getresult %struct.A %r, 0 <i>; yields i32</i>
+ %gr1 = getresult %struct.A %r, 1 <i>; yields i8</i>
</pre>
</div>
</div>
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+ <a name="i_getresult">'<tt>getresult</tt>' Instruction</a>
+</div>
+
+<div class="doc_text">
+
+<h5>Syntax:</h5>
+<pre>
+ <resultval> = getresult <type> <retval>, <index>
+</pre>
+
+<h5>Overview:</h5>
+
+<p> The '<tt>getresult</tt>' instruction is used to extract individual values
+from a '<tt><a href="#i_call">call</a></tt>'
+or '<tt><a href="#i_invoke">invoke</a></tt>' instruction that returns multiple
+results.</p>
+
+<h5>Arguments:</h5>
+
+<p>The '<tt>getresult</tt>' instruction takes a call or invoke value as its
+first argument. The value must have <a href="#t_struct">structure type</a>.
+The second argument is an unsigned index value which must be in range for
+the number of values returned by the call.</p>
+
+<h5>Semantics:</h5>
+
+<p>The '<tt>getresult</tt>' instruction extracts the element identified by
+'<tt>index</tt>' from the aggregate value.</p>
+
+<h5>Example:</h5>
+
+<pre>
+ %struct.A = type { i32, i8 }
+
+ %r = call %struct.A @foo()
+ %gr = getresult %struct.A %r, 0 <i>; yields i32:%gr</i>
+ %gr1 = getresult %struct.A %r, 1 <i>; yields i8:%gr1</i>
+ add i32 %gr, 42
+ add i8 %gr1, 41
+</pre>
+
+</div>
+
<!-- *********************************************************************** -->
<div class="doc_section"> <a name="intrinsics">Intrinsic Functions</a> </div>
<!-- *********************************************************************** -->
intrinsics to make use of the LLVM garbage collectors. For more details, see <a
href="GarbageCollection.html">Accurate Garbage Collection with LLVM</a>.
</p>
+
+<p>The garbage collection intrinsics only operate on objects in the generic
+ address space (address space zero).</p>
+
</div>
<!-- _______________________________________________________________________ -->
<p>At runtime, a call to this intrinsics stores a null pointer into the "ptrloc"
location. At compile-time, the code generator generates information to allow
-the runtime to find the pointer at GC safe points.
-</p>
+the runtime to find the pointer at GC safe points. The '<tt>llvm.gcroot</tt>'
+intrinsic may only be used in a function which <a href="#gc">specifies a GC
+algorithm</a>.</p>
</div>
<p>The '<tt>llvm.gcread</tt>' intrinsic has the same semantics as a load
instruction, but may be replaced with substantially more complex code by the
-garbage collector runtime, as needed.</p>
+garbage collector runtime, as needed. The '<tt>llvm.gcread</tt>' intrinsic
+may only be used in a function which <a href="#gc">specifies a GC
+algorithm</a>.</p>
</div>
<p>The '<tt>llvm.gcwrite</tt>' intrinsic has the same semantics as a store
instruction, but may be replaced with substantially more complex code by the
-garbage collector runtime, as needed.</p>
+garbage collector runtime, as needed. The '<tt>llvm.gcwrite</tt>' intrinsic
+may only be used in a function which <a href="#gc">specifies a GC
+algorithm</a>.</p>
</div>
<p>
The '<tt>llvm.memmove.*</tt>' intrinsics move a block of memory from the source
location to the destination location. It is similar to the
-'<tt>llvm.memcmp</tt>' intrinsic but allows the two memory locations to overlap.
+'<tt>llvm.memcpy</tt>' intrinsic but allows the two memory locations to overlap.
</p>
<p>
The '<tt>llvm.sqrt</tt>' intrinsics return the sqrt of the specified operand,
returning the same value as the libm '<tt>sqrt</tt>' functions would. Unlike
<tt>sqrt</tt> in libm, however, <tt>llvm.sqrt</tt> has undefined behavior for
-negative numbers (which allows for better optimization).
+negative numbers other than -0.0 (which allows for better optimization, because
+there is no need to worry about errno being set). <tt>llvm.sqrt(-0.0)</tt> is
+defined to return -0.0 like IEEE sqrt.
</p>
<h5>Arguments:</h5>
</p>
</div>
+<!-- ======================================================================= -->
+<div class="doc_subsection">
+ <a name="int_atomics">Atomic Operations and Synchronization Intrinsics</a>
+</div>
+
+<div class="doc_text">
+<p>
+ These intrinsic functions expand the "universal IR" of LLVM to represent
+ hardware constructs for atomic operations and memory synchronization. This
+ provides an interface to the hardware, not an interface to the programmer. It
+ is aimed at a low enough level to allow any programming models or APIs which
+ need atomic behaviors to map cleanly onto it. It is also modeled primarily on
+ hardware behavior. Just as hardware provides a "universal IR" for source
+ languages, it also provides a starting point for developing a "universal"
+ atomic operation and synchronization IR.
+</p>
+<p>
+ These do <em>not</em> form an API such as high-level threading libraries,
+ software transaction memory systems, atomic primitives, and intrinsic
+ functions as found in BSD, GNU libc, atomic_ops, APR, and other system and
+ application libraries. The hardware interface provided by LLVM should allow
+ a clean implementation of all of these APIs and parallel programming models.
+ No one model or paradigm should be selected above others unless the hardware
+ itself ubiquitously does so.
+
+</p>
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+ <a name="int_memory_barrier">'<tt>llvm.memory.barrier</tt>' Intrinsic</a>
+</div>
+<div class="doc_text">
+<h5>Syntax:</h5>
+<pre>
+declare void @llvm.memory.barrier( i1 <ll>, i1 <ls>, i1 <sl>, i1 <ss>,
+i1 <device> )
+
+</pre>
+<h5>Overview:</h5>
+<p>
+ The <tt>llvm.memory.barrier</tt> intrinsic guarantees ordering between
+ specific pairs of memory access types.
+</p>
+<h5>Arguments:</h5>
+<p>
+ The <tt>llvm.memory.barrier</tt> intrinsic requires five boolean arguments.
+ The first four arguments enables a specific barrier as listed below. The fith
+ argument specifies that the barrier applies to io or device or uncached memory.
+
+</p>
+ <ul>
+ <li><tt>ll</tt>: load-load barrier</li>
+ <li><tt>ls</tt>: load-store barrier</li>
+ <li><tt>sl</tt>: store-load barrier</li>
+ <li><tt>ss</tt>: store-store barrier</li>
+ <li><tt>device</tt>: barrier applies to device and uncached memory also.
+ </ul>
+<h5>Semantics:</h5>
+<p>
+ This intrinsic causes the system to enforce some ordering constraints upon
+ the loads and stores of the program. This barrier does not indicate
+ <em>when</em> any events will occur, it only enforces an <em>order</em> in
+ which they occur. For any of the specified pairs of load and store operations
+ (f.ex. load-load, or store-load), all of the first operations preceding the
+ barrier will complete before any of the second operations succeeding the
+ barrier begin. Specifically the semantics for each pairing is as follows:
+</p>
+ <ul>
+ <li><tt>ll</tt>: All loads before the barrier must complete before any load
+ after the barrier begins.</li>
+
+ <li><tt>ls</tt>: All loads before the barrier must complete before any
+ store after the barrier begins.</li>
+ <li><tt>ss</tt>: All stores before the barrier must complete before any
+ store after the barrier begins.</li>
+ <li><tt>sl</tt>: All stores before the barrier must complete before any
+ load after the barrier begins.</li>
+ </ul>
+<p>
+ These semantics are applied with a logical "and" behavior when more than one
+ is enabled in a single memory barrier intrinsic.
+</p>
+<p>
+ Backends may implement stronger barriers than those requested when they do not
+ support as fine grained a barrier as requested. Some architectures do not
+ need all types of barriers and on such architectures, these become noops.
+</p>
+<h5>Example:</h5>
+<pre>
+%ptr = malloc i32
+ store i32 4, %ptr
+
+%result1 = load i32* %ptr <i>; yields {i32}:result1 = 4</i>
+ call void @llvm.memory.barrier( i1 false, i1 true, i1 false, i1 false )
+ <i>; guarantee the above finishes</i>
+ store i32 8, %ptr <i>; before this begins</i>
+</pre>
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+ <a name="int_atomic_lcs">'<tt>llvm.atomic.lcs.*</tt>' Intrinsic</a>
+</div>
+<div class="doc_text">
+<h5>Syntax:</h5>
+<p>
+ This is an overloaded intrinsic. You can use <tt>llvm.atomic.lcs</tt> on any
+ integer bit width. Not all targets support all bit widths however.</p>
+
+<pre>
+declare i8 @llvm.atomic.lcs.i8( i8* <ptr>, i8 <cmp>, i8 <val> )
+declare i16 @llvm.atomic.lcs.i16( i16* <ptr>, i16 <cmp>, i16 <val> )
+declare i32 @llvm.atomic.lcs.i32( i32* <ptr>, i32 <cmp>, i32 <val> )
+declare i64 @llvm.atomic.lcs.i64( i64* <ptr>, i64 <cmp>, i64 <val> )
+
+</pre>
+<h5>Overview:</h5>
+<p>
+ This loads a value in memory and compares it to a given value. If they are
+ equal, it stores a new value into the memory.
+</p>
+<h5>Arguments:</h5>
+<p>
+ The <tt>llvm.atomic.lcs</tt> intrinsic takes three arguments. The result as
+ well as both <tt>cmp</tt> and <tt>val</tt> must be integer values with the
+ same bit width. The <tt>ptr</tt> argument must be a pointer to a value of
+ this integer type. While any bit width integer may be used, targets may only
+ lower representations they support in hardware.
+
+</p>
+<h5>Semantics:</h5>
+<p>
+ This entire intrinsic must be executed atomically. It first loads the value
+ in memory pointed to by <tt>ptr</tt> and compares it with the value
+ <tt>cmp</tt>. If they are equal, <tt>val</tt> is stored into the memory. The
+ loaded value is yielded in all cases. This provides the equivalent of an
+ atomic compare-and-swap operation within the SSA framework.
+</p>
+<h5>Examples:</h5>
+
+<pre>
+%ptr = malloc i32
+ store i32 4, %ptr
+
+%val1 = add i32 4, 4
+%result1 = call i32 @llvm.atomic.lcs.i32( i32* %ptr, i32 4, %val1 )
+ <i>; yields {i32}:result1 = 4</i>
+%stored1 = icmp eq i32 %result1, 4 <i>; yields {i1}:stored1 = true</i>
+%memval1 = load i32* %ptr <i>; yields {i32}:memval1 = 8</i>
+
+%val2 = add i32 1, 1
+%result2 = call i32 @llvm.atomic.lcs.i32( i32* %ptr, i32 5, %val2 )
+ <i>; yields {i32}:result2 = 8</i>
+%stored2 = icmp eq i32 %result2, 5 <i>; yields {i1}:stored2 = false</i>
+
+%memval2 = load i32* %ptr <i>; yields {i32}:memval2 = 8</i>
+</pre>
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+ <a name="int_atomic_swap">'<tt>llvm.atomic.swap.*</tt>' Intrinsic</a>
+</div>
+<div class="doc_text">
+<h5>Syntax:</h5>
+
+<p>
+ This is an overloaded intrinsic. You can use <tt>llvm.atomic.swap</tt> on any
+ integer bit width. Not all targets support all bit widths however.</p>
+<pre>
+declare i8 @llvm.atomic.swap.i8( i8* <ptr>, i8 <val> )
+declare i16 @llvm.atomic.swap.i16( i16* <ptr>, i16 <val> )
+declare i32 @llvm.atomic.swap.i32( i32* <ptr>, i32 <val> )
+declare i64 @llvm.atomic.swap.i64( i64* <ptr>, i64 <val> )
+
+</pre>
+<h5>Overview:</h5>
+<p>
+ This intrinsic loads the value stored in memory at <tt>ptr</tt> and yields
+ the value from memory. It then stores the value in <tt>val</tt> in the memory
+ at <tt>ptr</tt>.
+</p>
+<h5>Arguments:</h5>
+
+<p>
+ The <tt>llvm.atomic.ls</tt> intrinsic takes two arguments. Both the
+ <tt>val</tt> argument and the result must be integers of the same bit width.
+ The first argument, <tt>ptr</tt>, must be a pointer to a value of this
+ integer type. The targets may only lower integer representations they
+ support.
+</p>
+<h5>Semantics:</h5>
+<p>
+ This intrinsic loads the value pointed to by <tt>ptr</tt>, yields it, and
+ stores <tt>val</tt> back into <tt>ptr</tt> atomically. This provides the
+ equivalent of an atomic swap operation within the SSA framework.
+
+</p>
+<h5>Examples:</h5>
+<pre>
+%ptr = malloc i32
+ store i32 4, %ptr
+
+%val1 = add i32 4, 4
+%result1 = call i32 @llvm.atomic.swap.i32( i32* %ptr, i32 %val1 )
+ <i>; yields {i32}:result1 = 4</i>
+%stored1 = icmp eq i32 %result1, 4 <i>; yields {i1}:stored1 = true</i>
+%memval1 = load i32* %ptr <i>; yields {i32}:memval1 = 8</i>
+
+%val2 = add i32 1, 1
+%result2 = call i32 @llvm.atomic.swap.i32( i32* %ptr, i32 %val2 )
+ <i>; yields {i32}:result2 = 8</i>
+
+%stored2 = icmp eq i32 %result2, 8 <i>; yields {i1}:stored2 = true</i>
+%memval2 = load i32* %ptr <i>; yields {i32}:memval2 = 2</i>
+</pre>
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+ <a name="int_atomic_las">'<tt>llvm.atomic.las.*</tt>' Intrinsic</a>
+
+</div>
+<div class="doc_text">
+<h5>Syntax:</h5>
+<p>
+ This is an overloaded intrinsic. You can use <tt>llvm.atomic.las</tt> on any
+ integer bit width. Not all targets support all bit widths however.</p>
+<pre>
+declare i8 @llvm.atomic.las.i8.( i8* <ptr>, i8 <delta> )
+declare i16 @llvm.atomic.las.i16.( i16* <ptr>, i16 <delta> )
+declare i32 @llvm.atomic.las.i32.( i32* <ptr>, i32 <delta> )
+declare i64 @llvm.atomic.las.i64.( i64* <ptr>, i64 <delta> )
+
+</pre>
+<h5>Overview:</h5>
+<p>
+ This intrinsic adds <tt>delta</tt> to the value stored in memory at
+ <tt>ptr</tt>. It yields the original value at <tt>ptr</tt>.
+</p>
+<h5>Arguments:</h5>
+<p>
+
+ The intrinsic takes two arguments, the first a pointer to an integer value
+ and the second an integer value. The result is also an integer value. These
+ integer types can have any bit width, but they must all have the same bit
+ width. The targets may only lower integer representations they support.
+</p>
+<h5>Semantics:</h5>
+<p>
+ This intrinsic does a series of operations atomically. It first loads the
+ value stored at <tt>ptr</tt>. It then adds <tt>delta</tt>, stores the result
+ to <tt>ptr</tt>. It yields the original value stored at <tt>ptr</tt>.
+</p>
+
+<h5>Examples:</h5>
+<pre>
+%ptr = malloc i32
+ store i32 4, %ptr
+%result1 = call i32 @llvm.atomic.las.i32( i32* %ptr, i32 4 )
+ <i>; yields {i32}:result1 = 4</i>
+%result2 = call i32 @llvm.atomic.las.i32( i32* %ptr, i32 2 )
+ <i>; yields {i32}:result2 = 8</i>
+%result3 = call i32 @llvm.atomic.las.i32( i32* %ptr, i32 5 )
+ <i>; yields {i32}:result3 = 10</i>
+%memval = load i32* %ptr <i>; yields {i32}:memval1 = 15</i>
+</pre>
+</div>
+
+
<!-- ======================================================================= -->
<div class="doc_subsection">
<a name="int_general">General Intrinsics</a>
<h5>Semantics:</h5>
<p>
-This intrinsic allows annotation of local variables with arbitrary strings.
+This intrinsic allows annotation of local variables with arbitrary strings.
This can be useful for special purpose optimizations that want to look for these
- annotations. These have no other defined use, they are ignored by code
- generation and optimization.
+annotations. These have no other defined use, they are ignored by code
+generation and optimization.
+</p>
</div>
<!-- _______________________________________________________________________ -->
are ignored by code generation and optimization.
</div>
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+ <a name="int_trap">'<tt>llvm.trap</tt>' Intrinsic</a>
+</div>
+
+<div class="doc_text">
+
+<h5>Syntax:</h5>
+<pre>
+ declare void @llvm.trap()
+</pre>
+
+<h5>Overview:</h5>
+
+<p>
+The '<tt>llvm.trap</tt>' intrinsic
+</p>
+
+<h5>Arguments:</h5>
+
+<p>
+None
+</p>
+
+<h5>Semantics:</h5>
+
+<p>
+This intrinsics is lowered to the target dependent trap instruction. If the
+target does not have a trap instruction, this intrinsic will be lowered to the
+call of the abort() function.
+</p>
+</div>
+
<!-- *********************************************************************** -->
<hr>
<address>
<a href="http://jigsaw.w3.org/css-validator/check/referer"><img
src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!"></a>
<a href="http://validator.w3.org/check/referer"><img
- src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!" /></a>
+ src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01!"></a>
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
Last modified: $Date$
</address>
+
</body>
</html>