
BUG=None R=laforge@chromium.org,binji@chromium.org,sbc@chromium.org,rockot@chromium.org Review-Url: https://codereview.chromium.org/2875303003 Cr-Commit-Position: refs/heads/master@{#475662}
462 lines
26 KiB
HTML
462 lines
26 KiB
HTML
{{+bindTo:partials.standard_nacl_article}}
|
|
|
|
<b><font color="#cc0000">
|
|
NOTE:
|
|
Deprecation of the technologies described here has been announced
|
|
for platforms other than ChromeOS.<br/>
|
|
Please visit our
|
|
<a href="/native-client/migration">migration guide</a>
|
|
for details.
|
|
</font></b>
|
|
<hr/><section id="pnacl-bitcode-reference-manual">
|
|
<h1 id="pnacl-bitcode-reference-manual">PNaCl Bitcode Reference Manual</h1>
|
|
<div class="contents local" id="contents" style="display: none">
|
|
<ul class="small-gap">
|
|
<li><a class="reference internal" href="#introduction" id="id1">Introduction</a></li>
|
|
<li><p class="first"><a class="reference internal" href="#high-level-structure" id="id2">High Level Structure</a></p>
|
|
<ul class="small-gap">
|
|
<li><a class="reference internal" href="#data-model" id="id3">Data Model</a></li>
|
|
<li><a class="reference internal" href="#linkage-types" id="id4">Linkage Types</a></li>
|
|
<li><a class="reference internal" href="#calling-conventions" id="id5">Calling Conventions</a></li>
|
|
<li><a class="reference internal" href="#visibility-styles" id="id6">Visibility Styles</a></li>
|
|
<li><a class="reference internal" href="#global-variables" id="id7">Global Variables</a></li>
|
|
<li><a class="reference internal" href="#functions" id="id8">Functions</a></li>
|
|
<li><a class="reference internal" href="#aliases" id="id9">Aliases</a></li>
|
|
<li><a class="reference internal" href="#named-metadata" id="id10">Named Metadata</a></li>
|
|
<li><a class="reference internal" href="#module-level-inline-assembly" id="id11">Module-Level Inline Assembly</a></li>
|
|
<li><a class="reference internal" href="#volatile-memory-accesses" id="id12">Volatile Memory Accesses</a></li>
|
|
<li><a class="reference internal" href="#memory-model-for-concurrent-operations" id="id13">Memory Model for Concurrent Operations</a></li>
|
|
<li><a class="reference internal" href="#fast-math-flags" id="id14">Fast-Math Flags</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><p class="first"><a class="reference internal" href="#type-system" id="id15">Type System</a></p>
|
|
<ul class="small-gap">
|
|
<li><a class="reference internal" href="#scalar-types" id="id16">Scalar types</a></li>
|
|
<li><a class="reference internal" href="#vector-types" id="id17">Vector types</a></li>
|
|
<li><a class="reference internal" href="#array-and-struct-types" id="id18">Array and struct types</a></li>
|
|
<li><a class="reference internal" href="#pointer-types" id="id19">Pointer types</a></li>
|
|
<li><a class="reference internal" href="#undefined-values" id="id20">Undefined Values</a></li>
|
|
<li><a class="reference internal" href="#constant-expressions" id="id21">Constant Expressions</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><p class="first"><a class="reference internal" href="#other-values" id="id22">Other Values</a></p>
|
|
<ul class="small-gap">
|
|
<li><a class="reference internal" href="#metadata-nodes-and-metadata-strings" id="id23">Metadata Nodes and Metadata Strings</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a class="reference internal" href="#intrinsic-global-variables" id="id24">Intrinsic Global Variables</a></li>
|
|
<li><a class="reference internal" href="#errno-and-errors-in-arithmetic-instructions" id="id25">Errno and errors in arithmetic instructions</a></li>
|
|
<li><p class="first"><a class="reference internal" href="#instruction-reference" id="id26">Instruction Reference</a></p>
|
|
<ul class="small-gap">
|
|
<li><a class="reference internal" href="#list-of-allowed-instructions" id="id27">List of allowed instructions</a></li>
|
|
<li><a class="reference internal" href="#alloca" id="id28"><code>alloca</code></a></li>
|
|
</ul>
|
|
</li>
|
|
<li><p class="first"><a class="reference internal" href="#intrinsic-functions" id="id29">Intrinsic Functions</a></p>
|
|
<ul class="small-gap">
|
|
<li><a class="reference internal" href="#list-of-allowed-intrinsics" id="id30">List of allowed intrinsics</a></li>
|
|
<li><a class="reference internal" href="#thread-pointer-related-intrinsics" id="id31">Thread pointer related intrinsics</a></li>
|
|
<li><a class="reference internal" href="#setjmp-and-longjmp" id="id32">Setjmp and Longjmp</a></li>
|
|
<li><a class="reference internal" href="#atomic-intrinsics" id="id33">Atomic intrinsics</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
</div><h2 id="introduction">Introduction</h2>
|
|
<p>This document is a reference manual for the PNaCl bitcode format. It describes
|
|
the bitcode on a <em>semantic</em> level; the physical encoding level will be described
|
|
elsewhere. For the purpose of this document, the textual form of LLVM IR is
|
|
used to describe instructions and other bitcode constructs.</p>
|
|
<p>Since the PNaCl bitcode is based to a large extent on LLVM IR as of
|
|
version 3.3, many sections in this document point to a relevant section
|
|
of the LLVM language reference manual. Only the changes, restrictions
|
|
and variations specific to PNaCl are described—full semantic
|
|
descriptions are not duplicated from the LLVM reference manual.</p>
|
|
<h2 id="high-level-structure">High Level Structure</h2>
|
|
<p>A PNaCl portable executable (<strong>pexe</strong> in short) is a single LLVM IR module.</p>
|
|
<h3 id="data-model">Data Model</h3>
|
|
<p>The data model for PNaCl bitcode is fixed at little-endian ILP32: pointers are
|
|
32 bits in size. 64-bit integer types are also supported natively via the i64
|
|
type (for example, a front-end can generate these from the C/C++ type
|
|
<code>long long</code>).</p>
|
|
<p>Floating point support is fixed at IEEE 754 32-bit and 64-bit values (f32 and
|
|
f64, respectively).</p>
|
|
<h3 id="linkage-types"><span id="bitcode-linkagetypes"></span>Linkage Types</h3>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#linkage">LLVM LangRef: Linkage Types</a></p>
|
|
<p>The linkage types supported by PNaCl bitcode are <code>internal</code> and <code>external</code>.
|
|
A single function in the pexe, named <code>_start</code>, has the linkage type
|
|
<code>external</code>. All the other functions and globals have the linkage type
|
|
<code>internal</code>.</p>
|
|
<h3 id="calling-conventions">Calling Conventions</h3>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#callingconv">LLVM LangRef: Calling Conventions</a></p>
|
|
<p>The only calling convention supported by PNaCl bitcode is <code>ccc</code> - the C
|
|
calling convention.</p>
|
|
<h3 id="visibility-styles">Visibility Styles</h3>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#visibility-styles">LLVM LangRef: Visibility Styles</a></p>
|
|
<p>PNaCl bitcode does not support visibility styles.</p>
|
|
<h3 id="global-variables"><span id="bitcode-globalvariables"></span>Global Variables</h3>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#globalvars">LLVM LangRef: Global Variables</a></p>
|
|
<p>Restrictions on global variables:</p>
|
|
<ul class="small-gap">
|
|
<li>PNaCl bitcode does not support LLVM IR TLS models. See
|
|
<a class="reference internal" href="/native-client/reference/pnacl-c-cpp-language-support.html#language-support-threading"><em>Threading</em></a> for more details.</li>
|
|
<li>Restrictions on <a class="reference internal" href="#bitcode-linkagetypes"><em>linkage types</em></a>.</li>
|
|
<li>The <code>addrspace</code>, <code>section</code>, <code>unnamed_addr</code> and
|
|
<code>externally_initialized</code> attributes are not supported.</li>
|
|
</ul>
|
|
<p>Every global variable must have an initializer. Each initializer must be
|
|
either a <em>SimpleElement</em> or a <em>CompoundElement</em>, defined as follows.</p>
|
|
<p>A <em>SimpleElement</em> is one of the following:</p>
|
|
<ol class="arabic simple">
|
|
<li>An i8 array literal or <code>zeroinitializer</code>:</li>
|
|
</ol>
|
|
<pre>
|
|
[SIZE x i8] c"DATA"
|
|
[SIZE x i8] zeroinitializer
|
|
</pre>
|
|
<ol class="arabic simple" start="2">
|
|
<li>A reference to a <em>GlobalValue</em> (a function or global variable) with an
|
|
optional 32-bit byte offset added to it (the addend, which may be
|
|
negative):</li>
|
|
</ol>
|
|
<pre>
|
|
ptrtoint (TYPE* @GLOBAL to i32)
|
|
add (i32 ptrtoint (TYPE* @GLOBAL to i32), i32 ADDEND)
|
|
</pre>
|
|
<p>A <em>CompoundElement</em> is a unnamed, packed struct containing more than one
|
|
<em>SimpleElement</em>.</p>
|
|
<h3 id="functions">Functions</h3>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#functionstructure">LLVM LangRef: Functions</a></p>
|
|
<p>The restrictions on <a class="reference internal" href="#bitcode-linkagetypes"><em>linkage types</em></a>, calling
|
|
conventions and visibility styles apply to functions. In addition, the following
|
|
are not supported for functions:</p>
|
|
<ul class="small-gap">
|
|
<li>Function attributes (either for the the function itself, its parameters or its
|
|
return type).</li>
|
|
<li>Garbage collector name (<code>gc</code>).</li>
|
|
<li>Functions with a variable number of arguments (<em>vararg</em>).</li>
|
|
<li>Alignment (<code>align</code>).</li>
|
|
</ul>
|
|
<h3 id="aliases">Aliases</h3>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#aliases">LLVM LangRef: Aliases</a></p>
|
|
<p>PNaCl bitcode does not support aliases.</p>
|
|
<h3 id="named-metadata">Named Metadata</h3>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#namedmetadatastructure">LLVM LangRef: Named Metadata</a></p>
|
|
<p>While PNaCl bitcode has provisions for debugging metadata, it is not considered
|
|
part of the stable ABI. It exists for tool support and should not appear in
|
|
distributed pexes.</p>
|
|
<p>Other kinds of LLVM metadata are not supported.</p>
|
|
<h3 id="module-level-inline-assembly">Module-Level Inline Assembly</h3>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#moduleasm">LLVM LangRef: Module-Level Inline Assembly</a></p>
|
|
<p>PNaCl bitcode does not support inline assembly.</p>
|
|
<h3 id="volatile-memory-accesses">Volatile Memory Accesses</h3>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#volatile">LLVM LangRef: Volatile Memory Accesses</a></p>
|
|
<p>PNaCl bitcode does not support volatile memory accesses. The
|
|
<code>volatile</code> attribute on loads and stores is not supported. See the
|
|
<a class="reference internal" href="/native-client/reference/pnacl-c-cpp-language-support.html"><em>PNaCl C/C++ Language Support</em></a> for more details.</p>
|
|
<h3 id="memory-model-for-concurrent-operations">Memory Model for Concurrent Operations</h3>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#memmodel">LLVM LangRef: Memory Model for Concurrent Operations</a></p>
|
|
<p>See the <a class="reference internal" href="/native-client/reference/pnacl-c-cpp-language-support.html"><em>PNaCl C/C++ Language Support</em></a>
|
|
for details.</p>
|
|
<h3 id="fast-math-flags">Fast-Math Flags</h3>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#fastmath">LLVM LangRef: Fast-Math Flags</a></p>
|
|
<p>Fast-math mode is not currently supported by the PNaCl bitcode.</p>
|
|
<h2 id="type-system">Type System</h2>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#typesystem">LLVM LangRef: Type System</a></p>
|
|
<p>The LLVM types allowed in PNaCl bitcode are restricted, as follows:</p>
|
|
<h3 id="scalar-types">Scalar types</h3>
|
|
<ul class="small-gap">
|
|
<li><p class="first">The only scalar types allowed are integer, float (32-bit floating point),
|
|
double (64-bit floating point) and void.</p>
|
|
<ul class="small-gap">
|
|
<li>The only integer sizes allowed are i1, i8, i16, i32 and i64.</li>
|
|
<li>The only integer sizes allowed for function arguments and function return
|
|
values are i32 and i64.</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
<h3 id="vector-types">Vector types</h3>
|
|
<p>The only vector types allowed are:</p>
|
|
<ul class="small-gap">
|
|
<li>128-bit vectors integers of elements size i8, i16, i32.</li>
|
|
<li>128-bit vectors of float elements.</li>
|
|
<li>Vectors of i1 type with element counts corresponding to the allowed
|
|
element counts listed previously (their width is therefore not
|
|
128-bits).</li>
|
|
</ul>
|
|
<h3 id="array-and-struct-types">Array and struct types</h3>
|
|
<p>Array and struct types are only allowed in
|
|
<a class="reference internal" href="#bitcode-globalvariables"><em>global variable initializers</em></a>.</p>
|
|
<h3 id="pointer-types"><span id="bitcode-pointertypes"></span>Pointer types</h3>
|
|
<p>Only the following pointer types are allowed:</p>
|
|
<ul class="small-gap">
|
|
<li>Pointers to valid PNaCl bitcode scalar types, as specified above, except for
|
|
<code>i1</code>.</li>
|
|
<li>Pointers to valid PNaCl bitcode vector types, as specified above, except for
|
|
<code><? x i1></code>.</li>
|
|
<li>Pointers to functions.</li>
|
|
</ul>
|
|
<p>In addition, the address space for all pointers must be 0.</p>
|
|
<p>A pointer is <em>inherent</em> when it represents the return value of an <code>alloca</code>
|
|
instruction, or is an address of a global value.</p>
|
|
<p>A pointer is <em>normalized</em> if it’s either:</p>
|
|
<ul class="small-gap">
|
|
<li><em>inherent</em></li>
|
|
<li>Is the return value of a <code>bitcast</code> instruction.</li>
|
|
<li>Is the return value of a <code>inttoptr</code> instruction.</li>
|
|
</ul>
|
|
<h3 id="undefined-values">Undefined Values</h3>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#undefvalues">LLVM LangRef: Undefined Values</a></p>
|
|
<p><code>undef</code> is only allowed within functions, not in global variable initializers.</p>
|
|
<h3 id="constant-expressions">Constant Expressions</h3>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#constant-expressions">LLVM LangRef: Constant Expressions</a></p>
|
|
<p>Constant expressions are only allowed in
|
|
<a class="reference internal" href="#bitcode-globalvariables"><em>global variable initializers</em></a>.</p>
|
|
<h2 id="other-values">Other Values</h2>
|
|
<h3 id="metadata-nodes-and-metadata-strings">Metadata Nodes and Metadata Strings</h3>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#metadata">LLVM LangRef: Metadata Nodes and Metadata Strings</a></p>
|
|
<p>While PNaCl bitcode has provisions for debugging metadata, it is not considered
|
|
part of the stable ABI. It exists for tool support and should not appear in
|
|
distributed pexes.</p>
|
|
<p>Other kinds of LLVM metadata are not supported.</p>
|
|
<h2 id="intrinsic-global-variables">Intrinsic Global Variables</h2>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#intrinsic-global-variables">LLVM LangRef: Intrinsic Global Variables</a></p>
|
|
<p>PNaCl bitcode does not support intrinsic global variables.</p>
|
|
<h2 id="errno-and-errors-in-arithmetic-instructions"><span id="ir-and-errno"></span>Errno and errors in arithmetic instructions</h2>
|
|
<p>Some arithmetic instructions and intrinsics have the similar semantics to
|
|
libc math functions, but differ in the treatment of <code>errno</code>. While the
|
|
libc functions may set <code>errno</code> for domain errors, the instructions and
|
|
intrinsics do not. This is because the variable <code>errno</code> is not special
|
|
and is not required to be part of the program.</p>
|
|
<h2 id="instruction-reference">Instruction Reference</h2>
|
|
<h3 id="list-of-allowed-instructions">List of allowed instructions</h3>
|
|
<p>This is a list of LLVM instructions supported by PNaCl bitcode. Where
|
|
applicable, PNaCl-specific restrictions are provided.</p>
|
|
<p>The following attributes are disallowed for all instructions:</p>
|
|
<ul class="small-gap">
|
|
<li><code>nsw</code> and <code>nuw</code></li>
|
|
<li><code>exact</code></li>
|
|
</ul>
|
|
<p>Only the LLVM instructions listed here are supported by PNaCl bitcode.</p>
|
|
<ul class="small-gap">
|
|
<li><code>ret</code></li>
|
|
<li><code>br</code></li>
|
|
<li><p class="first"><code>switch</code></p>
|
|
<p>i1 values are disallowed for <code>switch</code>.</p>
|
|
</li>
|
|
<li><p class="first"><code>add</code>, <code>sub</code>, <code>mul</code>, <code>shl</code>, <code>udiv</code>, <code>sdiv</code>, <code>urem</code>, <code>srem</code>,
|
|
<code>lshr</code>, <code>ashr</code></p>
|
|
<p>These arithmetic operations are disallowed on values of type <code>i1</code>.</p>
|
|
<p>Integer division (<code>udiv</code>, <code>sdiv</code>, <code>urem</code>, <code>srem</code>) by zero is
|
|
guaranteed to trap in PNaCl bitcode.</p>
|
|
</li>
|
|
<li><code>and</code></li>
|
|
<li><code>or</code></li>
|
|
<li><code>xor</code></li>
|
|
<li><code>fadd</code></li>
|
|
<li><code>fsub</code></li>
|
|
<li><code>fmul</code></li>
|
|
<li><code>fdiv</code></li>
|
|
<li><p class="first"><code>frem</code></p>
|
|
<p>The frem instruction has the semantics of the libc fmod function for
|
|
computing the floating point remainder. If the numerator is infinity, or
|
|
denominator is zero, or either are NaN, then the result is NaN.
|
|
Unlike the libc fmod function, this does not set <code>errno</code> when the
|
|
result is NaN (see the <a class="reference internal" href="#ir-and-errno"><em>instructions and errno</em></a>
|
|
section).</p>
|
|
</li>
|
|
<li><p class="first"><code>alloca</code></p>
|
|
<p>See <a class="reference internal" href="#bitcode-allocainst"><em>alloca instructions</em></a>.</p>
|
|
</li>
|
|
<li><p class="first"><code>load</code>, <code>store</code></p>
|
|
<p>The pointer argument of these instructions must be a <em>normalized</em> pointer (see
|
|
<a class="reference internal" href="#bitcode-pointertypes"><em>pointer types</em></a>). The <code>volatile</code> and <code>atomic</code>
|
|
attributes are not supported. Loads and stores of the type <code>i1</code> and <code><? x
|
|
i1></code> are not supported.</p>
|
|
<p>These instructions must follow the following alignment restrictions:</p>
|
|
<ul class="small-gap">
|
|
<li>On integer memory accesses: <code>align 1</code>.</li>
|
|
<li>On <code>float</code> memory accesses: <code>align 1</code> or <code>align 4</code>.</li>
|
|
<li>On <code>double</code> memory accesses: <code>align 1</code> or <code>align 8</code>.</li>
|
|
<li>On vector memory accesses: alignment at the vector’s element width, for
|
|
example <code><4 x i32></code> must be <code>align 4</code>.</li>
|
|
</ul>
|
|
</li>
|
|
<li><code>trunc</code></li>
|
|
<li><code>zext</code></li>
|
|
<li><code>sext</code></li>
|
|
<li><code>fptrunc</code></li>
|
|
<li><code>fpext</code></li>
|
|
<li><code>fptoui</code></li>
|
|
<li><code>fptosi</code></li>
|
|
<li><code>uitofp</code></li>
|
|
<li><code>sitofp</code></li>
|
|
<li><p class="first"><code>ptrtoint</code></p>
|
|
<p>The pointer argument of a <code>ptrtoint</code> instruction must be a <em>normalized</em>
|
|
pointer (see <a class="reference internal" href="#bitcode-pointertypes"><em>pointer types</em></a>) and the integer
|
|
argument must be an i32.</p>
|
|
</li>
|
|
<li><p class="first"><code>inttoptr</code></p>
|
|
<p>The integer argument of a <code>inttoptr</code> instruction must be an i32.</p>
|
|
</li>
|
|
<li><p class="first"><code>bitcast</code></p>
|
|
<p>The pointer argument of a <code>bitcast</code> instruction must be a <em>inherent</em> pointer
|
|
(see <a class="reference internal" href="#bitcode-pointertypes"><em>pointer types</em></a>).</p>
|
|
</li>
|
|
<li><code>icmp</code></li>
|
|
<li><code>fcmp</code></li>
|
|
<li><code>phi</code></li>
|
|
<li><code>select</code></li>
|
|
<li><code>call</code></li>
|
|
<li><code>unreachable</code></li>
|
|
<li><code>insertelement</code></li>
|
|
<li><code>extractelement</code></li>
|
|
</ul>
|
|
<h3 id="alloca"><span id="bitcode-allocainst"></span><code>alloca</code></h3>
|
|
<p>The only allowed type for <code>alloca</code> instructions in PNaCl bitcode is i8. The
|
|
size argument must be an i32. For example:</p>
|
|
<pre>
|
|
%buf = alloca i8, i32 8, align 4
|
|
</pre>
|
|
<h2 id="intrinsic-functions">Intrinsic Functions</h2>
|
|
<p><a class="reference external" href="http://llvm.org/releases/3.3/docs/LangRef.html#intrinsics">LLVM LangRef: Intrinsic Functions</a></p>
|
|
<h3 id="list-of-allowed-intrinsics">List of allowed intrinsics</h3>
|
|
<p>The only intrinsics supported by PNaCl bitcode are the following.</p>
|
|
<ul class="small-gap">
|
|
<li><code>llvm.memcpy</code></li>
|
|
<li><code>llvm.memmove</code></li>
|
|
<li><p class="first"><code>llvm.memset</code></p>
|
|
<p>These intrinsics are only supported with an i32 <code>len</code> argument.</p>
|
|
</li>
|
|
<li><p class="first"><code>llvm.bswap</code></p>
|
|
<p>The overloaded <code>llvm.bswap</code> intrinsic is only supported with the following
|
|
argument types: i16, i32, i64 (the types supported by C-style GCC builtins).</p>
|
|
</li>
|
|
<li><code>llvm.ctlz</code></li>
|
|
<li><code>llvm.cttz</code></li>
|
|
<li><p class="first"><code>llvm.ctpop</code></p>
|
|
<p>The overloaded <code>llvm.ctlz</code>, <code>llvm.cttz</code>, and <code>llvm.ctpop</code> intrinsics
|
|
are only supported with the i32 and i64 argument types (the types
|
|
supported by C-style GCC builtins).</p>
|
|
</li>
|
|
<li><p class="first"><code>llvm.fabs</code></p>
|
|
<p>The overloaded <code>llvm.fabs</code> intrinsic is supported for float, double and
|
|
<code><4 x float></code> argument types. It returns the absolute value of
|
|
the argument. Some notable points: it returns <code>+0.0</code> when given <code>-0.0</code>,
|
|
<code>+inf</code> when given <code>-inf</code>, and a positive <code>NaN</code> when given any
|
|
signed <code>NaN</code>.</p>
|
|
<p>NOTE: This intrinsic was introduced in the pepper_42 SDK.</p>
|
|
</li>
|
|
<li><p class="first"><code>llvm.sqrt</code></p>
|
|
<p>The overloaded <code>llvm.sqrt</code> intrinsic is only supported for float
|
|
and double arguments types. This has the same semantics as the libc
|
|
sqrt function, returning <code>NaN</code> for values less than <code>-0.0</code>.
|
|
However, this does not set <code>errno</code> when the result is NaN (see the
|
|
<a class="reference internal" href="#ir-and-errno"><em>instructions and errno</em></a> section).</p>
|
|
</li>
|
|
<li><code>llvm.stacksave</code></li>
|
|
<li><p class="first"><code>llvm.stackrestore</code></p>
|
|
<p>These intrinsics are used to implement language features like scoped automatic
|
|
variable sized arrays in C99. <code>llvm.stacksave</code> returns a value that
|
|
represents the current state of the stack. This value may only be used as the
|
|
argument to <code>llvm.stackrestore</code>, which restores the stack to the given
|
|
state.</p>
|
|
</li>
|
|
<li><p class="first"><code>llvm.trap</code></p>
|
|
<p>This intrinsic is lowered to a target dependent trap instruction, which aborts
|
|
execution.</p>
|
|
</li>
|
|
<li><p class="first"><code>llvm.nacl.read.tp</code></p>
|
|
<p>See <a class="reference internal" href="#bitcode-threadpointerintrinsics"><em>thread pointer related intrinsics</em></a>.</p>
|
|
</li>
|
|
<li><code>llvm.nacl.longjmp</code></li>
|
|
<li><p class="first"><code>llvm.nacl.setjmp</code></p>
|
|
<p>See <a class="reference internal" href="#bitcode-setjmplongjmp"><em>Setjmp and Longjmp</em></a>.</p>
|
|
</li>
|
|
<li><code>llvm.nacl.atomic.store</code></li>
|
|
<li><code>llvm.nacl.atomic.load</code></li>
|
|
<li><code>llvm.nacl.atomic.rmw</code></li>
|
|
<li><code>llvm.nacl.atomic.cmpxchg</code></li>
|
|
<li><code>llvm.nacl.atomic.fence</code></li>
|
|
<li><code>llvm.nacl.atomic.fence.all</code></li>
|
|
<li><p class="first"><code>llvm.nacl.atomic.is.lock.free</code></p>
|
|
<p>See <a class="reference internal" href="#bitcode-atomicintrinsics"><em>atomic intrinsics</em></a>.</p>
|
|
</li>
|
|
</ul>
|
|
<h3 id="thread-pointer-related-intrinsics"><span id="bitcode-threadpointerintrinsics"></span>Thread pointer related intrinsics</h3>
|
|
<pre>
|
|
declare i8* @llvm.nacl.read.tp()
|
|
</pre>
|
|
<p>Returns a read-only thread pointer. The value is controlled by the embedding
|
|
sandbox’s runtime.</p>
|
|
<h3 id="setjmp-and-longjmp"><span id="bitcode-setjmplongjmp"></span>Setjmp and Longjmp</h3>
|
|
<pre>
|
|
declare void @llvm.nacl.longjmp(i8* %jmpbuf, i32)
|
|
declare i32 @llvm.nacl.setjmp(i8* %jmpbuf)
|
|
</pre>
|
|
<p>These intrinsics implement the semantics of C11 <code>setjmp</code> and <code>longjmp</code>. The
|
|
<code>jmpbuf</code> pointer must be 64-bit aligned and point to at least 1024 bytes of
|
|
allocated memory.</p>
|
|
<h3 id="atomic-intrinsics"><span id="bitcode-atomicintrinsics"></span>Atomic intrinsics</h3>
|
|
<pre>
|
|
declare iN @llvm.nacl.atomic.load.<size>(
|
|
iN* <source>, i32 <memory_order>)
|
|
declare void @llvm.nacl.atomic.store.<size>(
|
|
iN <operand>, iN* <destination>, i32 <memory_order>)
|
|
declare iN @llvm.nacl.atomic.rmw.<size>(
|
|
i32 <computation>, iN* <object>, iN <operand>, i32 <memory_order>)
|
|
declare iN @llvm.nacl.atomic.cmpxchg.<size>(
|
|
iN* <object>, iN <expected>, iN <desired>,
|
|
i32 <memory_order_success>, i32 <memory_order_failure>)
|
|
declare void @llvm.nacl.atomic.fence(i32 <memory_order>)
|
|
declare void @llvm.nacl.atomic.fence.all()
|
|
</pre>
|
|
<p>Each of these intrinsics is overloaded on the <code>iN</code> argument, which is
|
|
reflected through <code><size></code> in the overload’s name. Integral types of
|
|
8, 16, 32 and 64-bit width are supported for these arguments.</p>
|
|
<p>The <code>@llvm.nacl.atomic.rmw</code> intrinsic implements the following
|
|
read-modify-write operations, from the general and arithmetic sections
|
|
of the C11/C++11 standards:</p>
|
|
<blockquote>
|
|
<div><ul class="small-gap">
|
|
<li><code>add</code></li>
|
|
<li><code>sub</code></li>
|
|
<li><code>or</code></li>
|
|
<li><code>and</code></li>
|
|
<li><code>xor</code></li>
|
|
<li><code>exchange</code></li>
|
|
</ul>
|
|
</div></blockquote>
|
|
<p>For all of these read-modify-write operations, the returned value is
|
|
that at <code>object</code> before the computation. The <code>computation</code> argument
|
|
must be a compile-time constant.</p>
|
|
<p>All atomic intrinsics also support C11/C++11 memory orderings, which
|
|
must be compile-time constants.</p>
|
|
<p>Integer values for these computations and memory orderings are defined
|
|
in <code>"llvm/IR/NaClAtomicIntrinsics.h"</code>.</p>
|
|
<p>The <code>@llvm.nacl.atomic.fence.all</code> intrinsic is equivalent to the
|
|
<code>@llvm.nacl.atomic.fence</code> intrinsic with sequentially consistent
|
|
ordering and compiler barriers preventing most non-atomic memory
|
|
accesses from reordering around it.</p>
|
|
<aside class="note">
|
|
<blockquote>
|
|
<div>These intrinsics allow PNaCl to support C11/C++11 style atomic
|
|
operations as well as some legacy GCC-style <code>__sync_*</code> builtins
|
|
while remaining stable as the LLVM codebase changes. The user isn’t
|
|
expected to use these intrinsics directly.</div></blockquote>
|
|
|
|
</aside>
|
|
<pre>
|
|
declare i1 @llvm.nacl.atomic.is.lock.free(i32 <byte_size>, i8* <address>)
|
|
</pre>
|
|
<p>The <code>llvm.nacl.atomic.is.lock.free</code> intrinsic is designed to
|
|
determine at translation time whether atomic operations of a certain
|
|
<code>byte_size</code> (a compile-time constant), at a particular <code>address</code>,
|
|
are lock-free or not. This reflects the C11 <code>atomic_is_lock_free</code>
|
|
function from header <code><stdatomic.h></code> and the C++11 <code>is_lock_free</code>
|
|
member function in header <code><atomic></code>. It can be used through the
|
|
<code>__nacl_atomic_is_lock_free</code> builtin.</p>
|
|
</section>
|
|
|
|
{{/partials.standard_nacl_article}}
|