<li><a href="#int_memset">'<tt>llvm.memset.*</tt>' Intrinsic</a></li>
<li><a href="#int_sqrt">'<tt>llvm.sqrt.*</tt>' Intrinsic</a></li>
<li><a href="#int_powi">'<tt>llvm.powi.*</tt>' Intrinsic</a></li>
+ <li><a href="#int_sin">'<tt>llvm.sin.*</tt>' Intrinsic</a></li>
+ <li><a href="#int_cos">'<tt>llvm.cos.*</tt>' Intrinsic</a></li>
+ <li><a href="#int_pow">'<tt>llvm.pow.*</tt>' Intrinsic</a></li>
</ol>
</li>
<li><a href="#int_manip">Bit Manipulation Intrinsics</a>
</li>
<li><a href="#int_debugger">Debugger intrinsics</a></li>
<li><a href="#int_eh">Exception Handling intrinsics</a></li>
- <li><a href="#int_atomics">Atomic Operations and Synchronization Intrinsics</a>
- <ol>
- <li><a href="#int_lcs">'<tt>llvm.atomic.lcs.*</tt>' Intrinsic</a></li>
- <li><a href="#int_ls">'<tt>llvm.atomic.ls.*</tt>' Intrinsic</a></li>
- <li><a href="#int_las">'<tt>llvm.atomic.las.*</tt>' Intrinsic</a></li>
- <li><a href="#int_lss">'<tt>llvm.atomic.lss.*</tt>' Intrinsic</a></li>
- <li><a href="#int_memory_barrier">'<tt>llvm.memory.barrier</tt>' Intrinsic</a></li>
- </ol>
- </li>
<li><a href="#int_trampoline">Trampoline Intrinsic</a>
<ol>
<li><a href="#int_it">'<tt>llvm.init.trampoline</tt>' Intrinsic</a></li>
<h5>Overview:</h5>
<p>Opaque types are used to represent unknown types in the system. This
-corresponds (for example) to the C notion of a foward declared structure type.
+corresponds (for example) to the C notion of a forward declared structure type.
In LLVM, opaque types can eventually be resolved to any type (not just a
structure type).</p>
<h5>Arguments:</h5>
<p>The two arguments to the '<tt>urem</tt>' instruction must be
<a href="#t_integer">integer</a> values. Both arguments must have identical
-types.</p>
+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>This instruction returns the unsigned integer <i>remainder</i> of a division.
This instruction always performs an unsigned division to get the remainder,
</pre>
<h5>Overview:</h5>
<p>The '<tt>srem</tt>' instruction returns the remainder from the
-signed division of its two operands.</p>
+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
<h5>Arguments:</h5>
<p>The two arguments to the '<tt>frem</tt>' instruction must be
<a href="#t_floating">floating point</a> values. Both arguments must have
-identical types.</p>
+identical types. This instruction can also take <a href="#t_vector">vector</a>
+versions of floating point values.</p>
<h5>Semantics:</h5>
<p>This instruction returns the <i>remainder</i> of a division.</p>
<h5>Example:</h5>
<h5>Syntax:</h5>
<pre> <result> = shl <ty> <var1>, <var2> <i>; yields {ty}:result</i>
</pre>
+
<h5>Overview:</h5>
+
<p>The '<tt>shl</tt>' instruction returns the first operand shifted to
the left a specified number of bits.</p>
+
<h5>Arguments:</h5>
+
<p>Both arguments to the '<tt>shl</tt>' instruction must be the same <a
href="#t_integer">integer</a> type.</p>
+
<h5>Semantics:</h5>
-<p>The value produced is <tt>var1</tt> * 2<sup><tt>var2</tt></sup>.</p>
+
+<p>The value produced is <tt>var1</tt> * 2<sup><tt>var2</tt></sup>. If
+<tt>var2</tt> is (statically or dynamically) equal to or larger than the number
+of bits in <tt>var1</tt>, the result is undefined.</p>
+
<h5>Example:</h5><pre>
<result> = shl i32 4, %var <i>; yields {i32}: 4 << %var</i>
<result> = shl i32 4, 2 <i>; yields {i32}: 16</i>
<result> = shl i32 1, 10 <i>; yields {i32}: 1024</i>
+ <result> = shl i32 1, 32 <i>; undefined</i>
</pre>
</div>
<!-- _______________________________________________________________________ -->
<a href="#t_integer">integer</a> type.</p>
<h5>Semantics:</h5>
+
<p>This instruction always performs a logical shift right operation. The most
significant bits of the result will be filled with zero bits after the
-shift.</p>
+shift. If <tt>var2</tt> is (statically or dynamically) equal to or larger than
+the number of bits in <tt>var1</tt>, the result is undefined.</p>
<h5>Example:</h5>
<pre>
<result> = lshr i32 4, 2 <i>; yields {i32}:result = 1</i>
<result> = lshr i8 4, 3 <i>; yields {i8}:result = 0</i>
<result> = lshr i8 -2, 1 <i>; yields {i8}:result = 0x7FFFFFFF </i>
+ <result> = lshr i32 1, 32 <i>; undefined</i>
</pre>
</div>
<h5>Semantics:</h5>
<p>This instruction always performs an arithmetic shift right operation,
The most significant bits of the result will be filled with the sign bit
-of <tt>var1</tt>.</p>
+of <tt>var1</tt>. If <tt>var2</tt> is (statically or dynamically) equal to or
+larger than the number of bits in <tt>var1</tt>, the result is undefined.
+</p>
<h5>Example:</h5>
<pre>
<result> = ashr i32 4, 2 <i>; yields {i32}:result = 1</i>
<result> = ashr i8 4, 3 <i>; yields {i8}:result = 0</i>
<result> = ashr i8 -2, 1 <i>; yields {i8}:result = -1</i>
+ <result> = ashr i32 1, 32 <i>; undefined</i>
</pre>
</div>
at the location specified by the '<tt><pointer></tt>' operand.</p>
<h5>Example:</h5>
<pre> %ptr = <a href="#i_alloca">alloca</a> i32 <i>; yields {i32*}:ptr</i>
- <a
- href="#i_store">store</a> i32 3, i32* %ptr <i>; yields {void}</i>
- %val = load i32* %ptr <i>; yields {i32}:val = i32 3</i>
+ store i32 3, i32* %ptr <i>; yields {void}</i>
+ %val = <a href="#i_load">load</a> i32* %ptr <i>; yields {i32}:val = i32 3</i>
</pre>
</div>
<div class="doc_text">
<h5>Syntax:</h5>
+<p>This is an overloaded intrinsic. You can use <tt>llvm.sqrt</tt> on any
+floating point or vector of floating point type. Not all targets support all
+types however.
<pre>
- declare float @llvm.sqrt.f32(float %Val)
- declare double @llvm.sqrt.f64(double %Val)
+ declare float @llvm.sqrt.f32(float %Val)
+ declare double @llvm.sqrt.f64(double %Val)
+ declare x86_fp80 @llvm.sqrt.f80(x86_fp80 %Val)
+ declare fp128 @llvm.sqrt.f128(fp128 %Val)
+ declare ppc_fp128 @llvm.sqrt.ppcf128(ppc_fp128 %Val)
</pre>
<h5>Overview:</h5>
<p>
The '<tt>llvm.sqrt</tt>' intrinsics return the sqrt of the specified operand,
-returning the same value as the libm '<tt>sqrt</tt>' function would. Unlike
+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).
</p>
<div class="doc_text">
<h5>Syntax:</h5>
+<p>This is an overloaded intrinsic. You can use <tt>llvm.powi</tt> on any
+floating point or vector of floating point type. Not all targets support all
+types however.
<pre>
- declare float @llvm.powi.f32(float %Val, i32 %power)
- declare double @llvm.powi.f64(double %Val, i32 %power)
+ declare float @llvm.powi.f32(float %Val, i32 %power)
+ declare double @llvm.powi.f64(double %Val, i32 %power)
+ declare x86_fp80 @llvm.powi.f80(x86_fp80 %Val, i32 %power)
+ declare fp128 @llvm.powi.f128(fp128 %Val, i32 %power)
+ declare ppc_fp128 @llvm.powi.ppcf128(ppc_fp128 %Val, i32 %power)
</pre>
<h5>Overview:</h5>
<p>
The '<tt>llvm.powi.*</tt>' intrinsics return the first operand raised to the
specified (positive or negative) power. The order of evaluation of
-multiplications is not defined.
+multiplications is not defined. When a vector of floating point type is
+used, the second argument remains a scalar integer value.
</p>
<h5>Arguments:</h5>
unspecified sequence of rounding operations.</p>
</div>
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+ <a name="int_sin">'<tt>llvm.sin.*</tt>' Intrinsic</a>
+</div>
+
+<div class="doc_text">
+
+<h5>Syntax:</h5>
+<p>This is an overloaded intrinsic. You can use <tt>llvm.sin</tt> on any
+floating point or vector of floating point type. Not all targets support all
+types however.
+<pre>
+ declare float @llvm.sin.f32(float %Val)
+ declare double @llvm.sin.f64(double %Val)
+ declare x86_fp80 @llvm.sin.f80(x86_fp80 %Val)
+ declare fp128 @llvm.sin.f128(fp128 %Val)
+ declare ppc_fp128 @llvm.sin.ppcf128(ppc_fp128 %Val)
+</pre>
+
+<h5>Overview:</h5>
+
+<p>
+The '<tt>llvm.sin.*</tt>' intrinsics return the sine of the operand.
+</p>
+
+<h5>Arguments:</h5>
+
+<p>
+The argument and return value are floating point numbers of the same type.
+</p>
+
+<h5>Semantics:</h5>
+
+<p>
+This function returns the sine of the specified operand, returning the
+same values as the libm <tt>sin</tt> functions would, and handles error
+conditions in the same way.</p>
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+ <a name="int_cos">'<tt>llvm.cos.*</tt>' Intrinsic</a>
+</div>
+
+<div class="doc_text">
+
+<h5>Syntax:</h5>
+<p>This is an overloaded intrinsic. You can use <tt>llvm.cos</tt> on any
+floating point or vector of floating point type. Not all targets support all
+types however.
+<pre>
+ declare float @llvm.cos.f32(float %Val)
+ declare double @llvm.cos.f64(double %Val)
+ declare x86_fp80 @llvm.cos.f80(x86_fp80 %Val)
+ declare fp128 @llvm.cos.f128(fp128 %Val)
+ declare ppc_fp128 @llvm.cos.ppcf128(ppc_fp128 %Val)
+</pre>
+
+<h5>Overview:</h5>
+
+<p>
+The '<tt>llvm.cos.*</tt>' intrinsics return the cosine of the operand.
+</p>
+
+<h5>Arguments:</h5>
+
+<p>
+The argument and return value are floating point numbers of the same type.
+</p>
+
+<h5>Semantics:</h5>
+
+<p>
+This function returns the cosine of the specified operand, returning the
+same values as the libm <tt>cos</tt> functions would, and handles error
+conditions in the same way.</p>
+</div>
+
+<!-- _______________________________________________________________________ -->
+<div class="doc_subsubsection">
+ <a name="int_pow">'<tt>llvm.pow.*</tt>' Intrinsic</a>
+</div>
+
+<div class="doc_text">
+
+<h5>Syntax:</h5>
+<p>This is an overloaded intrinsic. You can use <tt>llvm.pow</tt> on any
+floating point or vector of floating point type. Not all targets support all
+types however.
+<pre>
+ declare float @llvm.pow.f32(float %Val, float %Power)
+ declare double @llvm.pow.f64(double %Val, double %Power)
+ declare x86_fp80 @llvm.pow.f80(x86_fp80 %Val, x86_fp80 %Power)
+ declare fp128 @llvm.pow.f128(fp128 %Val, fp128 %Power)
+ declare ppc_fp128 @llvm.pow.ppcf128(ppc_fp128 %Val, ppc_fp128 Power)
+</pre>
+
+<h5>Overview:</h5>
+
+<p>
+The '<tt>llvm.pow.*</tt>' intrinsics return the first operand raised to the
+specified (positive or negative) power.
+</p>
+
+<h5>Arguments:</h5>
+
+<p>
+The second argument is a floating point power, and the first is a value to
+raise to that power.
+</p>
+
+<h5>Semantics:</h5>
+
+<p>
+This function returns the first value raised to the second power,
+returning the
+same values as the libm <tt>pow</tt> functions would, and handles error
+conditions in the same way.</p>
+</div>
+
<!-- ======================================================================= -->
<div class="doc_subsection">
Handling</a> document. </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_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.i8p.i8.i8( i8* <ptr>, i8 <cmp>, i8 <val> )
-declare i16 @llvm.atomic.lcs.i16.i16p.i16.i16( i16* <ptr>, i16 <cmp>, i16 <val> )
-declare i32 @llvm.atomic.lcs.i32.i32p.i32.i32( i32* <ptr>, i32 <cmp>, i32 <val> )
-declare i64 @llvm.atomic.lcs.i64.i64p.i64.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* %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* %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_ls">'<tt>llvm.atomic.ls.*</tt>' Intrinsic</a>
-</div>
-<div class="doc_text">
-<h5>Syntax:</h5>
-<p>
- This is an overloaded intrinsic. You can use <tt>llvm.atomic.ls</tt> on any
- integer bit width. Not all targets support all bit widths however.</p>
-<pre>
-declare i8 @llvm.atomic.ls.i8.i8p.i8( i8* <ptr>, i8 <val> )
-declare i16 @llvm.atomic.ls.i16.i16p.i16( i16* <ptr>, i16 <val> )
-declare i32 @llvm.atomic.ls.i32.i32p.i32( i32* <ptr>, i32 <val> )
-declare i64 @llvm.atomic.ls.i64.i64p.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.ls( 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.ls( 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_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.i8p.i8( i8* <ptr>, i8 <delta> )
-declare i16 @llvm.atomic.las.i16.i16p.i16( i16* <ptr>, i16 <delta> )
-declare i32 @llvm.atomic.las.i32.i32p.i32( i32* <ptr>, i32 <delta> )
-declare i64 @llvm.atomic.las.i64.i64p.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* %ptr, i32 4 )
- <i>; yields {i32}:result1 = 4</i>
-%result2 = call i32 @llvm.atomic.las( i32* %ptr, i32 2 )
- <i>; yields {i32}:result2 = 8</i>
-%result3 = call i32 @llvm.atomic.las( 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_subsubsection">
- <a name="int_lss">'<tt>llvm.atomic.lss.*</tt>' Intrinsic</a>
-</div>
-<div class="doc_text">
-<h5>Syntax:</h5>
-<p>
- This is an overloaded intrinsic. You can use <tt>llvm.atomic.lss</tt> on any
- integer bit width. Not all targets support all bit widths however.</p>
-<pre>
-declare i8 @llvm.atomic.lss.i8.i8.i8( i8* <ptr>, i8 <delta> )
-declare i16 @llvm.atomic.lss.i16.i16.i16( i16* <ptr>, i16 <delta> )
-declare i32 @llvm.atomic.lss.i32.i32.i32( i32* <ptr>, i32 <delta> )
-declare i64 @llvm.atomic.lss.i64.i64.i64( i64* <ptr>, i64 <delta> )
-</pre>
-<h5>Overview:</h5>
-<p>
- This intrinsic subtracts <tt>delta</tt> from 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 subtracts <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 32, %ptr
-%result1 = call i32 @llvm.atomic.lss( i32* %ptr, i32 4 )
- <i>; yields {i32}:result1 = 32</i>
-%result2 = call i32 @llvm.atomic.lss( i32* %ptr, i32 2 )
- <i>; yields {i32}:result2 = 28</i>
-%result3 = call i32 @llvm.atomic.lss( i32* %ptr, i32 5 )
- <i>; yields {i32}:result3 = 26</i>
-%memval = load i32* %ptr <i>; yields {i32}:memval1 = 21</i>
-</pre>
-</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> )
-</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 four boolean arguments.
- Each argument enables a specific barrier as listed below.
-</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>
- </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>
-<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_subsection">
<a name="int_trampoline">Trampoline Intrinsic</a>
<p>
For example, if the function is
<tt>i32 f(i8* nest %c, i32 %x, i32 %y)</tt> then the resulting function
- pointer has signature <tt>i32 (i32, i32)*</tt>. It can be created as follows:
+ pointer has signature <tt>i32 (i32, i32)*</tt>. It can be created as follows:</p>
<pre>
%tramp = alloca [10 x i8], align 4 ; size and alignment only correct for X86
%tramp1 = getelementptr [10 x i8]* %tramp, i32 0, i32 0
%p = call i8* @llvm.init.trampoline( i8* %tramp1, i8* bitcast (i32 (i8* nest , i32, i32)* @f to i8*), i8* %nval )
%fp = bitcast i8* %p to i32 (i32, i32)*
</pre>
- The call <tt>%val = call i32 %fp( i32 %x, i32 %y )</tt> is then equivalent to
- <tt>%val = call i32 %f( i8* %nval, i32 %x, i32 %y )</tt>.
-</p>
+ <p>The call <tt>%val = call i32 %fp( i32 %x, i32 %y )</tt> is then equivalent
+ to <tt>%val = call i32 %f( i8* %nval, i32 %x, i32 %y )</tt>.</p>
</div>
<!-- _______________________________________________________________________ -->