-<!-- _______________________________________________________________________ -->
-<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>
-</div>
-
-<div class="doc_text">
-<p>
- This intrinsic makes it possible to excise one parameter, marked with
- the <tt>nest</tt> attribute, from a function. The result is a callable
- function pointer lacking the nest parameter - the caller does not need
- to provide a value for it. Instead, the value to use is stored in
- advance in a "trampoline", a block of memory usually allocated
- on the stack, which also contains code to splice the nest value into the
- argument list. This is used to implement the GCC nested function address
- extension.
-</p>
-<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:
-<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>
-</div>
-
-<!-- _______________________________________________________________________ -->
-<div class="doc_subsubsection">
- <a name="int_it">'<tt>llvm.init.trampoline</tt>' Intrinsic</a>
-</div>
-<div class="doc_text">
-<h5>Syntax:</h5>
-<pre>
-declare i8* @llvm.init.trampoline(i8* <tramp>, i8* <func>, i8* <nval>)
-</pre>
-<h5>Overview:</h5>
-<p>
- This fills the memory pointed to by <tt>tramp</tt> with code
- and returns a function pointer suitable for executing it.
-</p>
-<h5>Arguments:</h5>
-<p>
- The <tt>llvm.init.trampoline</tt> intrinsic takes three arguments, all
- pointers. The <tt>tramp</tt> argument must point to a sufficiently large
- and sufficiently aligned block of memory; this memory is written to by the
- intrinsic. Note that the size and the alignment are target-specific - LLVM
- currently provides no portable way of determining them, so a front-end that
- generates this intrinsic needs to have some target-specific knowledge.
- The <tt>func</tt> argument must hold a function bitcast to an <tt>i8*</tt>.
-</p>
-<h5>Semantics:</h5>
-<p>
- The block of memory pointed to by <tt>tramp</tt> is filled with target
- dependent code, turning it into a function. A pointer to this function is
- returned, but needs to be bitcast to an
- <a href="#int_trampoline">appropriate function pointer type</a>
- before being called. The new function's signature is the same as that of
- <tt>func</tt> with any arguments marked with the <tt>nest</tt> attribute
- removed. At most one such <tt>nest</tt> argument is allowed, and it must be
- of pointer type. Calling the new function is equivalent to calling
- <tt>func</tt> with the same argument list, but with <tt>nval</tt> used for the
- missing <tt>nest</tt> argument. If, after calling
- <tt>llvm.init.trampoline</tt>, the memory pointed to by <tt>tramp</tt> is
- modified, then the effect of any later call to the returned function pointer is
- undefined.
-</p>
-</div>