| {{+bindTo:partials.standard_nacl_article}} |
| |
| <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}} |