Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / doc / reference / pnacl-c-cpp-language-support.rst
1 ============================
2 PNaCl C/C++ Language Support
3 ============================
4
5 .. contents::
6    :local:
7    :backlinks: none
8    :depth: 3
9
10 Source language support
11 =======================
12
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>`_.
17
18 For information on using languages other than C/C++, see the :ref:`FAQ
19 section on other languages <other_languages>`.
20
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`
24 for more details.
25
26 Versions
27 --------
28
29 Version information can be obtained:
30
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.
35
36 Preprocessor definitions
37 ------------------------
38
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.
42
43 .. _memory_model_and_atomics:
44
45 Memory Model and Atomics
46 ========================
47
48 Memory Model for Concurrent Operations
49 --------------------------------------
50
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.
58
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>`.
63
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>``.
71
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`_.
78
79 PNaCl supports concurrency and parallelism with some restrictions:
80
81 * Threading is explicitly supported and has no restrictions over what
82   prevalent implementations offer. See `Threading`_.
83
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.
89
90 * Inter-process communication through shared memory is currently not
91   supported. See `Future Directions`_.
92
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`_.
98
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.
102
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.
106
107 Atomic Memory Ordering Constraints
108 ----------------------------------
109
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.
114
115 Some additional restrictions, following the C11/C++11 standards:
116
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
122   for that location.
123 - Not all memory orderings are valid for all atomic operations.
124
125 Volatile Memory Accesses
126 ------------------------
127
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.
132
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.
142
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.
147
148 The PNaCl toolchain also requires that ``volatile`` accesses be at least
149 naturally aligned, and tries to guarantee this alignment.
150
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.
155
156 .. _language_support_threading:
157
158 Threading
159 =========
160
161 Threading is explicitly supported through C11/C++11's threading
162 libraries as well as POSIX threads.
163
164 Communication between threads should use atomic primitives as described
165 in `Memory Model and Atomics`_.
166
167 ``setjmp`` and ``longjmp``
168 ==========================
169
170 PNaCl and NaCl support ``setjmp`` and ``longjmp`` without any
171 restrictions beyond C's.
172
173 .. _exception_handling:
174
175 C++ Exception Handling
176 ======================
177
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
184 future.
185
186 NaCl supports full zero-cost C++ exception handling.
187
188 Inline Assembly
189 ===============
190
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.
198
199 PNaCl supports :ref:`Portable SIMD Vectors <portable_simd_vectors>`,
200 which are traditionally expressed through target-specific intrinsics or
201 inline assembly.
202
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.
206
207 .. _portable_simd_vectors:
208
209 Portable SIMD Vectors
210 =====================
211
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.
217
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
221 details.
222
223 Hand-Coding Vector Extensions
224 -----------------------------
225
226 The initial vector support in Portable Native Client adds `LLVM vectors
227 <http://clang.llvm.org/docs/LanguageExtensions.html#vectors-and-extended-vectors>`_
228 and `GCC 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.
232
233 Vector types can be used through the ``vector_size`` attribute:
234
235 .. naclcode::
236
237   #define VECTOR_BYTES 16
238   typedef int v4s __attribute__((vector_size(VECTOR_BYTES)));
239   v4s a = {1,2,3,4};
240   v4s b = {5,6,7,8};
241   v4s c, d, e;
242   c = a + b;  /* c = {6,8,10,12} */
243   d = b >> a; /* d = {2,1,0,0} */
244
245 Vector comparisons are represented as a bitmask as wide as the compared
246 elements of all ``0`` or all ``1``:
247
248 .. naclcode::
249
250   typedef int v4s __attribute__((vector_size(16)));
251   v4s snip(v4s in) {
252     v4s limit = {32,64,128,256};
253     v4s mask = in > limit;
254     v4s ret = in & mask;
255     return ret;
256   }
257
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):
262
263 ============  ============  ================ ======================
264 Type          Num Elements  Vector Bit Width Expected Bit Alignment
265 ============  ============  ================ ======================
266 ``uint8_t``   16            128              8
267 ``int8_t``    16            128              8
268 ``uint16_t``  8             128              16
269 ``int16_t``   8             128              16
270 ``uint32_t``  4             128              32
271 ``int32_t``   4             128              32
272 ``float``     4             128              32
273 ============  ============  ================ ======================
274
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.
277
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
280 be specified:
281
282 .. naclcode::
283
284   typedef int v4s_element   __attribute__((vector_size(16), aligned(4)));
285   typedef int v4s_unaligned __attribute__((vector_size(16), aligned(1)));
286
287
288 The following operators are supported on vectors:
289
290 +----------------------------------------------+
291 | unary ``+``, ``-``                           |
292 +----------------------------------------------+
293 | ``++``, ``--``                               |
294 +----------------------------------------------+
295 | ``+``, ``-``, ``*``, ``/``, ``%``            |
296 +----------------------------------------------+
297 | ``&``, ``|``, ``^``, ``~``                   |
298 +----------------------------------------------+
299 | ``>>``, ``<<``                               |
300 +----------------------------------------------+
301 | ``!``, ``&&``, ``||``                        |
302 +----------------------------------------------+
303 | ``==``, ``!=``, ``>``, ``<``, ``>=``, ``<=`` |
304 +----------------------------------------------+
305 | ``=``                                        |
306 +----------------------------------------------+
307
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
312 integer.
313
314 .. naclcode::
315
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} */
321
322 It is also possible to use array-style indexing into vectors to extract
323 individual elements using ``[]``.
324
325 .. naclcode::
326
327   typedef unsigned v4u __attribute__((vector_size(16)));
328   template<typename T>
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;
333   }
334
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.
346
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.
350
351 .. naclcode::
352
353   // identity operation - return 4-element vector v1.
354   __builtin_shufflevector(v1, v1, 0, 1, 2, 3)
355
356   // "Splat" element 0 of v1 into a 4-element result.
357   __builtin_shufflevector(v1, v1, 0, 0, 0, 0)
358
359   // Reverse 4-element vector v1.
360   __builtin_shufflevector(v1, v1, 3, 2, 1, 0)
361
362   // Concatenate every other element of 4-element vectors v1 and v2.
363   __builtin_shufflevector(v1, v2, 0, 2, 4, 6)
364
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)
367
368   // Shuffle v1 with some elements being undefined
369   __builtin_shufflevector(v1, v1, 3, -1, 1, -1)
370
371 One common use of ``__builtin_shufflevector`` is to perform
372 vector-scalar operations:
373
374 .. naclcode::
375
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);
380   }
381
382 Auto-Vectorization
383 ------------------
384
385 Auto-vectorization is currently not enabled for Portable Native Client,
386 but will be in a future release.
387
388 Undefined Behavior
389 ==================
390
391 The C and C++ languages expose some undefined behavior which is
392 discussed in :ref:`PNaCl Undefined Behavior <undefined_behavior>`.
393
394 Floating-Point
395 ==============
396
397 PNaCl exposes 32-bit and 64-bit floating point operations which are
398 mostly IEEE-754 compliant. There are a few caveats:
399
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``
405   macros).
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.
412
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
418     the operation.
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
422     in the *pexe*.
423
424 Computed ``goto``
425 =================
426
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``).
434
435 NaCl supports computed ``goto`` without any transformation.
436
437 Future Directions
438 =================
439
440 Inter-Process Communication
441 ---------------------------
442
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`_.
448
449 POSIX-style Signal Handling
450 ---------------------------
451
452 POSIX-style signal handling really consists of two different features:
453
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.
457
458   PNaCl currently doesn't support hardware exception handling.
459
460   NaCl supports hardware exception handling via the
461   ``<nacl/nacl_exception.h>`` interface.
462
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.
466
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).
470
471   Neither PNaCl nor NaCl currently support asynchronous interruption
472   or suspension of threads.
473
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.