1 ============================
2 PNaCl C/C++ Language Support
3 ============================
10 Source language support
11 =======================
13 The currently supported languages are C and C++. The PNaCl toolchain is
14 based on recent Clang, which fully supports C++11 and most of C11. A
15 detailed status of the language support is available `here
16 <http://clang.llvm.org/cxx_status.html>`_.
18 For information on using languages other than C/C++, see the :ref:`FAQ
19 section on other languages <other_languages>`.
21 As for the standard libraries, the PNaCl toolchain is currently based on
22 ``libc++``, and the ``newlib`` standard C library. ``libstdc++`` is also
23 supported but its use is discouraged; see :ref:`building_cpp_libraries`
29 Version information can be obtained:
31 * Clang/LLVM: run ``pnacl-clang -v``.
32 * ``newlib``: use the ``_NEWLIB_VERSION`` macro.
33 * ``libc++``: use the ``_LIBCPP_VERSION`` macro.
34 * ``libstdc++``: use the ``_GLIBCXX_VERSION`` macro.
36 Preprocessor definitions
37 ------------------------
39 When compiling C/C++ code, the PNaCl toolchain defines the ``__pnacl__``
40 macro. In addition, ``__native_client__`` is defined for compatibility
41 with other NaCl toolchains.
43 .. _memory_model_and_atomics:
45 Memory Model and Atomics
46 ========================
48 Memory Model for Concurrent Operations
49 --------------------------------------
51 The memory model offered by PNaCl relies on the same coding guidelines
52 as the C11/C++11 one: concurrent accesses must always occur through
53 atomic primitives (offered by `atomic intrinsics
54 <PNaClLangRef.html#atomicintrinsics>`_), and these accesses must always
55 occur with the same size for the same memory location. Visibility of
56 stores is provided on a happens-before basis that relates memory
57 locations to each other as the C11/C++11 standards do.
59 Non-atomic memory accesses may be reordered, separated, elided or fused
60 according to C and C++'s memory model before the pexe is created as well
61 as after its creation. Accessing atomic memory location through
62 non-atomic primitives is :ref:`Undefined Behavior <undefined_behavior>`.
64 As in C11/C++11 some atomic accesses may be implemented with locks on
65 certain platforms. The ``ATOMIC_*_LOCK_FREE`` macros will always be
66 ``1``, signifying that all types are sometimes lock-free. The
67 ``is_lock_free`` methods and ``atomic_is_lock_free`` will return the
68 current platform's implementation at translation time. These macros,
69 methods and functions are in the C11 header ``<stdatomic.h>`` and the
70 C++11 header ``<atomic>``.
72 The PNaCl toolchain supports concurrent memory accesses through legacy
73 GCC-style ``__sync_*`` builtins, as well as through C11/C++11 atomic
74 primitives and the underlying `GCCMM
75 <http://gcc.gnu.org/wiki/Atomic/GCCMM>`_ ``__atomic_*``
76 primitives. ``volatile`` memory accesses can also be used, though these
77 are discouraged. See `Volatile Memory Accesses`_.
79 PNaCl supports concurrency and parallelism with some restrictions:
81 * Threading is explicitly supported and has no restrictions over what
82 prevalent implementations offer. See `Threading`_.
84 * ``volatile`` and atomic operations are address-free (operations on the
85 same memory location via two different addresses work atomically), as
86 intended by the C11/C++11 standards. This is critical in supporting
87 synchronous "external modifications" such as mapping underlying memory
88 at multiple locations.
90 * Inter-process communication through shared memory is currently not
91 supported. See `Future Directions`_.
93 * Signal handling isn't supported, PNaCl therefore promotes all
94 primitives to cross-thread (instead of single-thread). This may change
95 at a later date. Note that using atomic operations which aren't
96 lock-free may lead to deadlocks when handling asynchronous
97 signals. See `Future Directions`_.
99 * Direct interaction with device memory isn't supported, and there is no
100 intent to support it. The embedding sandbox's runtime can offer APIs
101 to indirectly access devices.
103 Setting up the above mechanisms requires assistance from the embedding
104 sandbox's runtime (e.g. NaCl's Pepper APIs), but using them once setup
105 can be done through regular C/C++ code.
107 Atomic Memory Ordering Constraints
108 ----------------------------------
110 Atomics follow the same ordering constraints as in regular C11/C++11,
111 but all accesses are promoted to sequential consistency (the strongest
112 memory ordering) at pexe creation time. We plan to support more of the
113 C11/C++11 memory orderings in the future.
115 Some additional restrictions, following the C11/C++11 standards:
117 - Atomic accesses must at least be naturally aligned.
118 - Some accesses may not actually be atomic on certain platforms,
119 requiring an implementation that uses global locks.
120 - An atomic memory location must always be accessed with atomic
121 primitives, and these primitives must always be of the same bit size
123 - Not all memory orderings are valid for all atomic operations.
125 Volatile Memory Accesses
126 ------------------------
128 The C11/C++11 standards mandate that ``volatile`` accesses execute in
129 program order (but are not fences, so other memory operations can
130 reorder around them), are not necessarily atomic, and can’t be
131 elided. They can be separated into smaller width accesses.
133 Before any optimizations occur, the PNaCl toolchain transforms
134 ``volatile`` loads and stores into sequentially consistent ``volatile``
135 atomic loads and stores, and applies regular compiler optimizations
136 along the above guidelines. This orders ``volatiles`` according to the
137 atomic rules, and means that fences (including ``__sync_synchronize``)
138 act in a better-defined manner. Regular memory accesses still do not
139 have ordering guarantees with ``volatile`` and atomic accesses, though
140 the internal representation of ``__sync_synchronize`` attempts to
141 prevent reordering of memory accesses to objects which may escape.
143 Relaxed ordering could be used instead, but for the first release it is
144 more conservative to apply sequential consistency. Future releases may
145 change what happens at compile-time, but already-released pexes will
146 continue using sequential consistency.
148 The PNaCl toolchain also requires that ``volatile`` accesses be at least
149 naturally aligned, and tries to guarantee this alignment.
151 The above guarantees ease the support of legacy (i.e. non-C11/C++11)
152 code, and combined with builtin fences these programs can do meaningful
153 cross-thread communication without changing code. They also better
154 reflect the original code's intent and guarantee better portability.
156 .. _language_support_threading:
161 Threading is explicitly supported through C11/C++11's threading
162 libraries as well as POSIX threads.
164 Communication between threads should use atomic primitives as described
165 in `Memory Model and Atomics`_.
167 ``setjmp`` and ``longjmp``
168 ==========================
170 PNaCl and NaCl support ``setjmp`` and ``longjmp`` without any
171 restrictions beyond C's.
173 .. _exception_handling:
175 C++ Exception Handling
176 ======================
178 PNaCl currently supports C++ exception handling through ``setjmp()`` and
179 ``longjmp()``, which can be enabled with the ``--pnacl-exceptions=sjlj``
180 linker flag. Exceptions are disabled by default so that faster and
181 smaller code is generated, and ``throw`` statements are replaced with
182 calls to ``abort()``. The usual ``-fno-exceptions`` flag is also
183 supported. PNaCl will support full zero-cost exception handling in the
186 NaCl supports full zero-cost C++ exception handling.
191 Inline assembly isn't supported by PNaCl because it isn't portable. The
192 one current exception is the common compiler barrier idiom
193 ``asm("":::"memory")``, which gets transformed to a sequentially
194 consistent memory barrier (equivalent to ``__sync_synchronize()``). In
195 PNaCl this barrier is only guaranteed to order ``volatile`` and atomic
196 memory accesses, though in practice the implementation attempts to also
197 prevent reordering of memory accesses to objects which may escape.
199 PNaCl supports :ref:`Portable SIMD Vectors <portable_simd_vectors>`,
200 which are traditionally expressed through target-specific intrinsics or
203 NaCl supports a fairly wide subset of inline assembly through GCC's
204 inline assembly syntax, with the restriction that the sandboxing model
205 for the target architecture has to be respected.
207 .. _portable_simd_vectors:
209 Portable SIMD Vectors
210 =====================
212 SIMD vectors aren't part of the C/C++ standards and are traditionally
213 very hardware-specific. Portable Native Client offers a portable version
214 of SIMD vector datatypes and operations which map well to modern
215 architectures and offer performance which matches or approaches
216 hardware-specific uses.
218 SIMD vector support was added to Portable Native Client for version 37 of Chrome
219 and more features, including performance enhancements, have been added in
220 subsequent releases, see the :ref:`Release Notes <sdk-release-notes>` for more
223 Hand-Coding Vector Extensions
224 -----------------------------
226 The initial vector support in Portable Native Client adds `LLVM vectors
227 <http://clang.llvm.org/docs/LanguageExtensions.html#vectors-and-extended-vectors>`_
229 <http://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html>`_ since these
230 are well supported by different hardware platforms and don't require any
231 new compiler intrinsics.
233 Vector types can be used through the ``vector_size`` attribute:
237 #define VECTOR_BYTES 16
238 typedef int v4s __attribute__((vector_size(VECTOR_BYTES)));
242 c = a + b; /* c = {6,8,10,12} */
243 d = b >> a; /* d = {2,1,0,0} */
245 Vector comparisons are represented as a bitmask as wide as the compared
246 elements of all ``0`` or all ``1``:
250 typedef int v4s __attribute__((vector_size(16)));
252 v4s limit = {32,64,128,256};
253 v4s mask = in > limit;
258 Vector datatypes are currently expected to be 128-bit wide with one of the
259 following element types, and they're expected to be aligned to the underlying
260 element's bit width (loads and store will otherwise be broken up into scalar
261 accesses to prevent faults):
263 ============ ============ ================ ======================
264 Type Num Elements Vector Bit Width Expected Bit Alignment
265 ============ ============ ================ ======================
268 ``uint16_t`` 8 128 16
270 ``uint32_t`` 4 128 32
273 ============ ============ ================ ======================
275 64-bit integers and double-precision floating point will be supported in
276 a future release, as will 256-bit and 512-bit vectors.
278 Vector element bit width alignment can be stated explicitly (this is assumed by
279 PNaCl, but not necessarily by other compilers), and smaller alignments can also
284 typedef int v4s_element __attribute__((vector_size(16), aligned(4)));
285 typedef int v4s_unaligned __attribute__((vector_size(16), aligned(1)));
288 The following operators are supported on vectors:
290 +----------------------------------------------+
291 | unary ``+``, ``-`` |
292 +----------------------------------------------+
294 +----------------------------------------------+
295 | ``+``, ``-``, ``*``, ``/``, ``%`` |
296 +----------------------------------------------+
297 | ``&``, ``|``, ``^``, ``~`` |
298 +----------------------------------------------+
300 +----------------------------------------------+
301 | ``!``, ``&&``, ``||`` |
302 +----------------------------------------------+
303 | ``==``, ``!=``, ``>``, ``<``, ``>=``, ``<=`` |
304 +----------------------------------------------+
306 +----------------------------------------------+
308 C-style casts can be used to convert one vector type to another without
309 modifying the underlying bits. ``__builtin_convertvector`` can be used
310 to convert from one type to another provided both types have the same
311 number of elements, truncating when converting from floating-point to
316 typedef unsigned v4u __attribute__((vector_size(16)));
317 typedef float v4f __attribute__((vector_size(16)));
318 v4u a = {0x3f19999a,0x40000000,0x40490fdb,0x66ff0c30};
319 v4f b = (v4f) a; /* b = {0.6,2,3.14159,6.02214e+23} */
320 v4u c = __builtin_convertvector(b, v4u); /* c = {0,2,3,0} */
322 It is also possible to use array-style indexing into vectors to extract
323 individual elements using ``[]``.
327 typedef unsigned v4u __attribute__((vector_size(16)));
329 void print(const T v) {
330 for (size_t i = 0; i != sizeof(v) / sizeof(v[0]); ++i)
331 std::cout << v[i] << ' ';
332 std::cout << std::endl;
335 Vector shuffles (often called permutation or swizzle) operations are
336 supported through ``__builtin_shufflevector``. The builtin has two
337 vector arguments of the same element type, followed by a list of
338 constant integers that specify the element indices of the first two
339 vectors that should be extracted and returned in a new vector. These
340 element indices are numbered sequentially starting with the first
341 vector, continuing into the second vector. Thus, if ``vec1`` is a
342 4-element vector, index ``5`` would refer to the second element of
343 ``vec2``. An index of ``-1`` can be used to indicate that the
344 corresponding element in the returned vector is a don’t care and can be
345 optimized by the backend.
347 The result of ``__builtin_shufflevector`` is a vector with the same
348 element type as ``vec1`` / ``vec2`` but that has an element count equal
349 to the number of indices specified.
353 // identity operation - return 4-element vector v1.
354 __builtin_shufflevector(v1, v1, 0, 1, 2, 3)
356 // "Splat" element 0 of v1 into a 4-element result.
357 __builtin_shufflevector(v1, v1, 0, 0, 0, 0)
359 // Reverse 4-element vector v1.
360 __builtin_shufflevector(v1, v1, 3, 2, 1, 0)
362 // Concatenate every other element of 4-element vectors v1 and v2.
363 __builtin_shufflevector(v1, v2, 0, 2, 4, 6)
365 // Concatenate every other element of 8-element vectors v1 and v2.
366 __builtin_shufflevector(v1, v2, 0, 2, 4, 6, 8, 10, 12, 14)
368 // Shuffle v1 with some elements being undefined
369 __builtin_shufflevector(v1, v1, 3, -1, 1, -1)
371 One common use of ``__builtin_shufflevector`` is to perform
372 vector-scalar operations:
376 typedef int v4s __attribute__((vector_size(16)));
377 v4s shift_right_by(v4s shift_me, int shift_amount) {
378 v4s tmp = {shift_amount};
379 return shift_me >> __builtin_shuffle_vector(tmp, tmp, 0, 0, 0, 0);
385 Auto-vectorization is currently not enabled for Portable Native Client,
386 but will be in a future release.
391 The C and C++ languages expose some undefined behavior which is
392 discussed in :ref:`PNaCl Undefined Behavior <undefined_behavior>`.
397 PNaCl exposes 32-bit and 64-bit floating point operations which are
398 mostly IEEE-754 compliant. There are a few caveats:
400 * Some :ref:`floating-point behavior is currently left as undefined
401 <undefined_behavior_fp>`.
402 * The default rounding mode is round-to-nearest and other rounding modes
403 are currently not usable, which isn't IEEE-754 compliant. PNaCl could
404 support switching modes (the 4 modes exposed by C99 ``FLT_ROUNDS``
406 * Signaling ``NaN`` never fault.
407 * Fast-math optimizations are currently supported before *pexe* creation
408 time. A *pexe* loses all fast-math information when it is
409 created. Fast-math translation could be enabled at a later date,
410 potentially at a perf-function granularity. This wouldn't affect
411 already-existing *pexe*; it would be an opt-in feature.
413 * Fused-multiply-add have higher precision and often execute faster;
414 PNaCl currently disallows them in the *pexe* because they aren't
415 supported on all platforms and can't realistically be
416 emulated. PNaCl could (but currently doesn't) only generate them in
417 the backend if fast-math were specified and the hardware supports
419 * Transcendentals aren't exposed by PNaCl's ABI; they are part of the
420 math library that is included in the *pexe*. PNaCl could, but
421 currently doesn't, use hardware support if fast-math were provided
427 PNaCl supports computed ``goto``, a non-standard GCC extension to C used
428 by some interpreters, by lowering them to ``switch`` statements. The
429 resulting use of ``switch`` might not be as fast as the original
430 indirect branches. If you are compiling a program that has a
431 compile-time option for using computed ``goto``, it's possible that the
432 program will run faster with the option turned off (e.g., if the program
433 does extra work to take advantage of computed ``goto``).
435 NaCl supports computed ``goto`` without any transformation.
440 Inter-Process Communication
441 ---------------------------
443 Inter-process communication through shared memory is currently not
444 supported by PNaCl/NaCl. When implemented, it may be limited to
445 operations which are lock-free on the current platform (``is_lock_free``
446 methods). It will rely on the address-free properly discussed in `Memory
447 Model for Concurrent Operations`_.
449 POSIX-style Signal Handling
450 ---------------------------
452 POSIX-style signal handling really consists of two different features:
454 * **Hardware exception handling** (synchronous signals): The ability
455 to catch hardware exceptions (such as memory access faults and
456 division by zero) using a signal handler.
458 PNaCl currently doesn't support hardware exception handling.
460 NaCl supports hardware exception handling via the
461 ``<nacl/nacl_exception.h>`` interface.
463 * **Asynchronous interruption of threads** (asynchronous signals): The
464 ability to asynchronously interrupt the execution of a thread,
465 forcing the thread to run a signal handler.
467 A similar feature is **thread suspension**: The ability to
468 asynchronously suspend and resume a thread and inspect or modify its
469 execution state (such as register state).
471 Neither PNaCl nor NaCl currently support asynchronous interruption
472 or suspension of threads.
474 If PNaCl were to support either of these, the interaction of
475 ``volatile`` and atomics with same-thread signal handling would need
476 to be carefully detailed.