[docs] Rewrite libc docs from reST to markdown (#208802)
Tracking issue: https://github.com/llvm/llvm-project/issues/201242 Migration guide docs: https://llvm.org/docs/SphinxQuickstartTemplate.html#markdown-migration-guidelines RFC: https://discourse.llvm.org/t/rfc-make-myst-markdown-the-llvm-docs-format-rip-rest/90840 This was prepared with rst2myst plus LLM-assisted cleanup. I paged through all the generated HTML looking for migration artifacts, and all of the differences I could find appear to be formatting error corrections. Please spot check my work and approve if it looks good.
This commit is contained in:
parent
7bb9626d5a
commit
821afb2ed8
30 changed files with 1806 additions and 2116 deletions
|
|
@ -1,19 +1,18 @@
|
|||
Architecture Support
|
||||
====================
|
||||
# Architecture Support
|
||||
|
||||
The currently continuously tested architectures are:
|
||||
|
||||
* aarch64
|
||||
* amdgpu
|
||||
* arm
|
||||
* nvptx
|
||||
* riscv32
|
||||
* riscv64
|
||||
* x86_64
|
||||
- aarch64
|
||||
- amdgpu
|
||||
- arm
|
||||
- nvptx
|
||||
- riscv32
|
||||
- riscv64
|
||||
- x86_64
|
||||
|
||||
i386 support is [in the works](https://github.com/llvm/llvm-project/issues/93709).
|
||||
|
||||
See "`Bringup on a New OS or Architecture <porting.html>`__" for more
|
||||
See {doc}`Bringup on a New OS or Architecture <porting>` for more
|
||||
information. Please do first file a bug in
|
||||
`our issue tracker <https://github.com/llvm/llvm-project/labels/libc>`__ before
|
||||
[our issue tracker](https://github.com/llvm/llvm-project/labels/libc) before
|
||||
starting a port that you plan to upstream.
|
||||
|
|
|
|||
|
|
@ -1,95 +1,89 @@
|
|||
.. _build_and_test:
|
||||
(build_and_test)=
|
||||
|
||||
=============================
|
||||
Building and Testing the libc
|
||||
=============================
|
||||
# Building and Testing the libc
|
||||
|
||||
Build modes
|
||||
===========
|
||||
## Build modes
|
||||
|
||||
The libc can be built and tested in two different modes:
|
||||
|
||||
#. **The overlay mode** - In this mode, one uses the static archive from LLVM's
|
||||
libc along with the system libc. See :ref:`overlay_mode` for more details
|
||||
1. **The overlay mode** - In this mode, one uses the static archive from LLVM's
|
||||
libc along with the system libc. See {ref}`overlay_mode` for more details
|
||||
on building and using the libc in this mode. You can only run the libc
|
||||
unittests in this mode. To run them, one simply does:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$> ninja check-libc
|
||||
```sh
|
||||
$> ninja check-libc
|
||||
```
|
||||
|
||||
Note that, unittests for only those functions which are part of the overlay
|
||||
static archive will be run with the above command.
|
||||
|
||||
#. **The full build mode** - In this mode, the libc is used as the only libc
|
||||
for the user's application. See :ref:`full_host_build` for more details on
|
||||
2. **The full build mode** - In this mode, the libc is used as the only libc
|
||||
for the user's application. See {ref}`full_host_build` for more details on
|
||||
building and using the libc in this mode. Once configured for a full libc
|
||||
build, you can run three kinds of tests:
|
||||
|
||||
#. Unit tests - You can run unittests by the command:
|
||||
1. Unit tests - You can run unittests by the command:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
$> ninja check-libc
|
||||
```
|
||||
|
||||
$> ninja check-libc
|
||||
2. Integration tests - You can run integration tests by the command:
|
||||
|
||||
#. Integration tests - You can run integration tests by the command:
|
||||
```sh
|
||||
$> ninja libc-integration-tests
|
||||
```
|
||||
|
||||
.. code-block:: sh
|
||||
3. Shared tests - You can run tests for shared, standalone components (like math primitives) without needing the full libc runtime by the command:
|
||||
|
||||
$> ninja libc-integration-tests
|
||||
```sh
|
||||
$> ninja libc-shared-tests
|
||||
```
|
||||
|
||||
#. Shared tests - You can run tests for shared, standalone components (like math primitives) without needing the full libc runtime by the command:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$> ninja libc-shared-tests
|
||||
|
||||
Building with VSCode
|
||||
====================
|
||||
## Building with VSCode
|
||||
|
||||
As a quickstart to using VSCode for development, install the cmake extension
|
||||
and put the following in your settings.json file:
|
||||
|
||||
.. code-block:: javascript
|
||||
```javascript
|
||||
{
|
||||
"cmake.sourceDirectory": "${workspaceFolder}/runtimes",
|
||||
"cmake.configureSettings": {
|
||||
"LLVM_ENABLE_RUNTIMES" : ["libc", "compiler-rt"],
|
||||
"LLVM_LIBC_FULL_BUILD" : true,
|
||||
"LLVM_ENABLE_SPHINX" : true,
|
||||
"LIBC_INCLUDE_DOCS" : true,
|
||||
"LLVM_LIBC_INCLUDE_SCUDO" : true,
|
||||
"COMPILER_RT_BUILD_SCUDO_STANDALONE_WITH_LLVM_LIBC": true,
|
||||
"COMPILER_RT_BUILD_GWP_ASAN" : false,
|
||||
"COMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED" : false,
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : true,
|
||||
"LIBC_CMAKE_VERBOSE_LOGGING" : true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{
|
||||
"cmake.sourceDirectory": "${workspaceFolder}/runtimes",
|
||||
"cmake.configureSettings": {
|
||||
"LLVM_ENABLE_RUNTIMES" : ["libc", "compiler-rt"],
|
||||
"LLVM_LIBC_FULL_BUILD" : true,
|
||||
"LLVM_ENABLE_SPHINX" : true,
|
||||
"LIBC_INCLUDE_DOCS" : true,
|
||||
"LLVM_LIBC_INCLUDE_SCUDO" : true,
|
||||
"COMPILER_RT_BUILD_SCUDO_STANDALONE_WITH_LLVM_LIBC": true,
|
||||
"COMPILER_RT_BUILD_GWP_ASAN" : false,
|
||||
"COMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED" : false,
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS" : true,
|
||||
"LIBC_CMAKE_VERBOSE_LOGGING" : true
|
||||
}
|
||||
}
|
||||
## Building with Bazel
|
||||
|
||||
Building with Bazel
|
||||
===================
|
||||
1. To build with Bazel, use the following command:
|
||||
|
||||
#. To build with Bazel, use the following command:
|
||||
```sh
|
||||
$> bazel build --config=generic_clang @llvm-project//libc/...
|
||||
```
|
||||
|
||||
.. code-block:: sh
|
||||
1. To run the unit tests with bazel, use the following command:
|
||||
|
||||
$> bazel build --config=generic_clang @llvm-project//libc/...
|
||||
```sh
|
||||
$> bazel test --config=generic_clang @llvm-project//libc/...
|
||||
```
|
||||
|
||||
#. To run the unit tests with bazel, use the following command:
|
||||
1. The bazel target layout of `libc` is located at: [utils/bazel/llvm-project-overlay/libc/BUILD.bazel](https://github.com/llvm/llvm-project/tree/main/utils/bazel/llvm-project-overlay/libc/BUILD.bazel).
|
||||
|
||||
.. code-block:: sh
|
||||
## Building in a container for a different architecture
|
||||
|
||||
$> bazel test --config=generic_clang @llvm-project//libc/...
|
||||
|
||||
#. The bazel target layout of `libc` is located at: `utils/bazel/llvm-project-overlay/libc/BUILD.bazel <https://github.com/llvm/llvm-project/tree/main/utils/bazel/llvm-project-overlay/libc/BUILD.bazel>`_.
|
||||
|
||||
Building in a container for a different architecture
|
||||
====================================================
|
||||
|
||||
`Podman <https://podman.io/>`_ can be used together with
|
||||
`QEMU <https://www.qemu.org/>`_ to run container images built for architectures
|
||||
[Podman](https://podman.io/) can be used together with
|
||||
[QEMU](https://www.qemu.org/) to run container images built for architectures
|
||||
other than the host's. This can be used to build and test the libc on other
|
||||
supported architectures for which you do not have access to hardware. It can
|
||||
also be used if the hardware is slower than emulation of its architecture on a
|
||||
|
|
@ -97,27 +91,26 @@ more powerful machine under a different architecture.
|
|||
|
||||
As an example, to build and test in a container for 32-bit Arm:
|
||||
|
||||
#. To install the necessary packages on Arch Linux:
|
||||
1. To install the necessary packages on Arch Linux:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
$> pacman -S podman qemu-user-static qemu-user-static-binfmt \
|
||||
qemu-system-arm
|
||||
```
|
||||
|
||||
$> pacman -S podman qemu-user-static qemu-user-static-binfmt \
|
||||
qemu-system-arm
|
||||
|
||||
#. To run Bash interactively in an Ubuntu 22.04 container for 32-bit Arm and
|
||||
2. To run Bash interactively in an Ubuntu 22.04 container for 32-bit Arm and
|
||||
bind-mount an existing checkout of llvm-project on the host:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
$> podman run -it \
|
||||
-v </host/path/to/llvm-project>:</container/path/to/llvm-project> \
|
||||
--arch arm docker.io/ubuntu:jammy bash
|
||||
```
|
||||
|
||||
$> podman run -it \
|
||||
-v </host/path/to/llvm-project>:</container/path/to/llvm-project> \
|
||||
--arch arm docker.io/ubuntu:jammy bash
|
||||
3. Install necessary packages, invoke CMake, build, and run tests.
|
||||
|
||||
#. Install necessary packages, invoke CMake, build, and run tests.
|
||||
|
||||
Building and Testing with an Emulator
|
||||
=====================================
|
||||
## Building and Testing with an Emulator
|
||||
|
||||
If you are cross-compiling the libc for a different architecture, you can use an emulator
|
||||
such as QEMU to run the tests directly on your host without a container. See
|
||||
:ref:`full_cross_build` for detailed instructions on configuring CMake to use an emulator.
|
||||
{ref}`full_cross_build` for detailed instructions on configuring CMake to use an emulator.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
.. _build_concepts:
|
||||
(build_concepts)=
|
||||
|
||||
==============
|
||||
Build Concepts
|
||||
==============
|
||||
# Build Concepts
|
||||
|
||||
Most people don't need to build their own C library — the one provided by their
|
||||
system works well. However, LLVM-libc's **Overlay Mode** can provide key updates
|
||||
|
|
@ -11,66 +9,58 @@ like faster or more consistent math functions for projects that need them.
|
|||
For those who do need a full C library, LLVM-libc supports several build
|
||||
configurations depending on your target environment and intended usage.
|
||||
|
||||
The Five Build Scenarios
|
||||
========================
|
||||
## The Five Build Scenarios
|
||||
|
||||
1. Overlay Mode (Augmenting the System Libc)
|
||||
--------------------------------------------
|
||||
### 1. Overlay Mode (Augmenting the System Libc)
|
||||
|
||||
In Overlay Mode, LLVM-libc functions are compiled alongside the host's existing
|
||||
system library (like ``glibc``). Only the functions explicitly implemented in
|
||||
LLVM-libc are used; the rest "fall back" to the system library. This is the
|
||||
In Overlay Mode, LLVM-libc functions are compiled alongside the host's existing
|
||||
system library (like `glibc`). Only the functions explicitly implemented in
|
||||
LLVM-libc are used; the rest "fall back" to the system library. This is the
|
||||
preferred method for most contributors as it is the fastest to build and test.
|
||||
|
||||
To configure for an overlay build, point CMake to the ``runtimes`` directory
|
||||
and set ``LLVM_LIBC_FULL_BUILD=OFF`` (which is the default). This will build a
|
||||
static archive named ``libllvmlibc.a``:
|
||||
To configure for an overlay build, point CMake to the `runtimes` directory
|
||||
and set `LLVM_LIBC_FULL_BUILD=OFF` (which is the default). This will build a
|
||||
static archive named `libllvmlibc.a`:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
cmake -S runtimes -B build -DLLVM_ENABLE_RUNTIMES="libc" \
|
||||
-DLLVM_LIBC_FULL_BUILD=OFF ...
|
||||
```
|
||||
|
||||
cmake -S runtimes -B build -DLLVM_ENABLE_RUNTIMES="libc" \
|
||||
-DLLVM_LIBC_FULL_BUILD=OFF ...
|
||||
### 2. Full Build Mode (Standalone Library)
|
||||
|
||||
2. Full Build Mode (Standalone Library)
|
||||
---------------------------------------
|
||||
|
||||
In Full Build Mode, LLVM-libc is a complete replacement for the system library.
|
||||
This is used to build standalone ``libc.a`` and ``libm.a`` (with separate CMake
|
||||
In Full Build Mode, LLVM-libc is a complete replacement for the system library.
|
||||
This is used to build standalone `libc.a` and `libm.a` (with separate CMake
|
||||
targets) for a new operating system or to generate a sysroot for a specific target.
|
||||
|
||||
To configure for a full build, set ``LLVM_LIBC_FULL_BUILD=ON``:
|
||||
To configure for a full build, set `LLVM_LIBC_FULL_BUILD=ON`:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
cmake -S runtimes -B build -DLLVM_ENABLE_RUNTIMES="libc;compiler-rt" \
|
||||
-DLLVM_LIBC_FULL_BUILD=ON ...
|
||||
```
|
||||
|
||||
cmake -S runtimes -B build -DLLVM_ENABLE_RUNTIMES="libc;compiler-rt" \
|
||||
-DLLVM_LIBC_FULL_BUILD=ON ...
|
||||
|
||||
3. Bootstrap Build
|
||||
------------------
|
||||
### 3. Bootstrap Build
|
||||
|
||||
A bootstrap build first builds the compiler (Clang) and other LLVM tools using
|
||||
the host compiler, and then uses that newly-built Clang to build the libc.
|
||||
This ensures you are using a matched toolchain where the compiler and
|
||||
the library are built for each other.
|
||||
|
||||
To configure a bootstrap build, you point CMake to the ``llvm`` directory:
|
||||
To configure a bootstrap build, you point CMake to the `llvm` directory:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
cmake -S llvm -B build -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_ENABLE_RUNTIMES="libc;compiler-rt" ...
|
||||
```
|
||||
|
||||
cmake -S llvm -B build -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_ENABLE_RUNTIMES="libc;compiler-rt" ...
|
||||
### 4. Cross-compiler Build (Targeting Other Architectures)
|
||||
|
||||
4. Cross-compiler Build (Targeting Other Architectures)
|
||||
-------------------------------------------------------
|
||||
|
||||
Used when you want to build LLVM-libc for a different architecture than you are
|
||||
currently running on (e.g., building on x86_64 for an aarch64 target).
|
||||
Used when you want to build LLVM-libc for a different architecture than you are
|
||||
currently running on (e.g., building on x86_64 for an aarch64 target).
|
||||
This requires a cross-compiler or a toolchain file.
|
||||
|
||||
5. Bootstrap Cross-compiler (New Environment)
|
||||
---------------------------------------------
|
||||
### 5. Bootstrap Cross-compiler (New Environment)
|
||||
|
||||
For users who are starting from scratch (e.g., with only Linux kernel headers)
|
||||
and want to generate a full C compiler and sysroot for their target. This is
|
||||
For users who are starting from scratch (e.g., with only Linux kernel headers)
|
||||
and want to generate a full C compiler and sysroot for their target. This is
|
||||
the most common path for those building entire environments to tinker in.
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,19 @@
|
|||
.. _compiler_support:
|
||||
(compiler_support)=
|
||||
|
||||
================
|
||||
Compiler Support
|
||||
================
|
||||
# Compiler Support
|
||||
|
||||
``LLVM libc`` compiles from both ``Clang`` and ``GCC`` but for maximum
|
||||
performance we recommend using ``Clang``.
|
||||
`LLVM libc` compiles from both `Clang` and `GCC` but for maximum
|
||||
performance we recommend using `Clang`.
|
||||
|
||||
Indeed, some memory function implementations rely on `compiler intrinsics`__
|
||||
that are not currently available in ``GCC``.
|
||||
Indeed, some memory function implementations rely on [compiler intrinsics](https://clang.llvm.org/docs/LanguageExtensions.html#guaranteed-inlined-copy)
|
||||
that are not currently available in `GCC`.
|
||||
As such we cannot guarantee optimal performance for these functions.
|
||||
|
||||
.. __: https://clang.llvm.org/docs/LanguageExtensions.html#guaranteed-inlined-copy
|
||||
For platforms where only `GCC` is natively available but maximum performance
|
||||
is required it is possible to bootstrap `Clang` with `GCC` and then use
|
||||
`Clang` to build the `libc` project.
|
||||
|
||||
For platforms where only ``GCC`` is natively available but maximum performance
|
||||
is required it is possible to bootstrap ``Clang`` with ``GCC`` and then use
|
||||
``Clang`` to build the '`libc``" project.
|
||||
## Minimum supported versions
|
||||
|
||||
Minimum supported versions
|
||||
==========================
|
||||
|
||||
- ``Clang 11``
|
||||
- ``GCC 12.2``
|
||||
- `Clang 11`
|
||||
- `GCC 12.2`
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ extensions += [
|
|||
"sphinx_reredirects",
|
||||
]
|
||||
|
||||
myst_enable_extensions += ["deflist"]
|
||||
|
||||
# General information about the project.
|
||||
project = "libc"
|
||||
copyright = "2011-%d, LLVM Project" % date.today().year
|
||||
|
|
@ -61,6 +63,10 @@ rst_prolog = """
|
|||
.. |check| replace:: :raw-html:`✅`
|
||||
"""
|
||||
|
||||
myst_substitutions = {
|
||||
"check": "\N{WHITE HEAVY CHECK MARK}",
|
||||
}
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
# default_role = None
|
||||
|
||||
|
|
|
|||
|
|
@ -1,46 +1,41 @@
|
|||
.. _contributing:
|
||||
(contributing)=
|
||||
|
||||
================================
|
||||
Contributing to the libc Project
|
||||
================================
|
||||
# Contributing to the libc Project
|
||||
|
||||
LLVM-libc is being developed as part of the LLVM project so contributions
|
||||
to the libc project should also follow the general LLVM
|
||||
`contribution guidelines <https://llvm.org/docs/Contributing.html>`_. Below is
|
||||
[contribution guidelines](https://llvm.org/docs/Contributing.html). Below is
|
||||
a list of open projects that one can start with:
|
||||
|
||||
#. **Beginner Bugs** - Help us tackle
|
||||
`good first issues <https://github.com/llvm/llvm-project/issues?q=is%3Aopen+is%3Aissue+label%3Alibc+label%3A%22good+first+issue%22>`__.
|
||||
1. **Beginner Bugs** - Help us tackle
|
||||
[good first issues](https://github.com/llvm/llvm-project/issues?q=is%3Aopen+is%3Aissue+label%3Alibc+label%3A%22good+first+issue%22).
|
||||
These bugs have been tagged with the github labels "libc" and "good first
|
||||
issue" by the team as potentially easier places to get started. Please do
|
||||
issue" by the team as potentially easier places to get started. Please do
|
||||
first check if the bug has an assignee; if so please find another unless
|
||||
there's been no movement on the issue from the assignee, in which place do
|
||||
ask if you can help take over.
|
||||
|
||||
#. **Cleanup code-style** - The libc project follows the general
|
||||
`LLVM style <https://llvm.org/docs/CodingStandards.html>`_ with specific
|
||||
conventions for naming (``snake_case`` for functions, ``CamelCase`` for
|
||||
types). See the :ref:`code_style` page for the authoritative reference.
|
||||
2. **Cleanup code-style** - The libc project follows the general
|
||||
[LLVM style](https://llvm.org/docs/CodingStandards.html) with specific
|
||||
conventions for naming (`snake_case` for functions, `CamelCase` for
|
||||
types). See the {doc}`code style <dev/code_style>` page for the
|
||||
authoritative reference.
|
||||
Mechanical projects to move parts following old styles to the current
|
||||
conventions are welcome.
|
||||
|
||||
#. **Implement Linux syscall wrappers** - A large portion of the POSIX API can
|
||||
3. **Implement Linux syscall wrappers** - A large portion of the POSIX API can
|
||||
be implemented as syscall wrappers on Linux. A good number have already been
|
||||
implemented but many more are yet to be implemented. So, a project of medium
|
||||
complexity would be to implement syscall wrappers which have not yet been
|
||||
implemented.
|
||||
|
||||
#. **Update the clang-tidy lint rules and use them in the build and/or CI** -
|
||||
The libc project has a set of clang-tidy checks (see :ref:`clang_tidy_checks`)
|
||||
4. **Update the clang-tidy lint rules and use them in the build and/or CI** -
|
||||
The libc project has a set of clang-tidy checks (see
|
||||
{ref}`clang-tidy checks <clang_tidy_checks>`)
|
||||
but they are not enabled by default. They can be enabled by configuring with
|
||||
``-DLLVM_LIBC_ENABLE_LINTING=ON`` (or by setting ``LLVM_LIBC_CLANG_TIDY``) and
|
||||
running the ``libc-lint`` build target. This project is about keeping the
|
||||
`-DLLVM_LIBC_ENABLE_LINTING=ON` (or by setting `LLVM_LIBC_CLANG_TIDY`) and
|
||||
running the `libc-lint` build target. This project is about keeping the
|
||||
checks up to date and reintegrating them into the build and CI.
|
||||
|
||||
#. **double and higher precision math functions** - These are under active
|
||||
5. **double and higher precision math functions** - These are under active
|
||||
development but you can take a shot at those not yet implemented. See
|
||||
:ref:`math` for more information.
|
||||
|
||||
#. **Contribute a new OS/Architecture port** - You can contribute a new
|
||||
operating system or target architecture port. See :ref:`porting` for more
|
||||
{ref}`math` for more information.
|
||||
6. **Contribute a new OS/Architecture port** - You can contribute a new
|
||||
operating system or target architecture port. See {ref}`porting` for more
|
||||
information.
|
||||
|
|
|
|||
|
|
@ -1,93 +1,86 @@
|
|||
.. _building_docs:
|
||||
(building_docs)=
|
||||
|
||||
==========================
|
||||
Building the Documentation
|
||||
==========================
|
||||
# Building the Documentation
|
||||
|
||||
This page explains how to build the LLVM-libc HTML documentation locally so
|
||||
you can preview changes before submitting a patch.
|
||||
|
||||
Prerequisites
|
||||
=============
|
||||
## Prerequisites
|
||||
|
||||
The LLVM documentation build uses `Sphinx <https://www.sphinx-doc.org/>`__.
|
||||
The LLVM documentation build uses [Sphinx](https://www.sphinx-doc.org/).
|
||||
The key packages required are:
|
||||
|
||||
* ``sphinx`` — the documentation generator
|
||||
* ``furo`` — the theme used by LLVM-libc
|
||||
* ``myst-parser`` — Markdown support alongside RST
|
||||
* ``sphinx-reredirects`` — handles page redirect entries in ``conf.py``
|
||||
- `sphinx` — the documentation generator
|
||||
- `furo` — the theme used by LLVM-libc
|
||||
- `myst-parser` — Markdown support alongside RST
|
||||
- `sphinx-reredirects` — handles page redirect entries in `conf.py`
|
||||
|
||||
**On Debian/Ubuntu**, all required packages are available via apt:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt-get install python3-sphinx python3-myst-parser \
|
||||
python3-sphinx-reredirects furo
|
||||
```bash
|
||||
sudo apt-get install python3-sphinx python3-myst-parser \
|
||||
python3-sphinx-reredirects furo
|
||||
```
|
||||
|
||||
**On other systems**, install everything from the shared requirements file:
|
||||
|
||||
.. code-block:: bash
|
||||
```bash
|
||||
pip install -r llvm/docs/requirements.txt
|
||||
```
|
||||
|
||||
pip install -r llvm/docs/requirements.txt
|
||||
|
||||
CMake Configuration
|
||||
===================
|
||||
## CMake Configuration
|
||||
|
||||
Enable the Sphinx documentation build by adding these flags to your CMake
|
||||
invocation:
|
||||
|
||||
.. code-block:: bash
|
||||
```bash
|
||||
cmake ../runtimes \
|
||||
-DLLVM_ENABLE_RUNTIMES="libc" \
|
||||
-DLLVM_ENABLE_SPHINX=ON \
|
||||
-DLIBC_INCLUDE_DOCS=ON \
|
||||
...
|
||||
```
|
||||
|
||||
cmake ../runtimes \
|
||||
-DLLVM_ENABLE_RUNTIMES="libc" \
|
||||
-DLLVM_ENABLE_SPHINX=ON \
|
||||
-DLIBC_INCLUDE_DOCS=ON \
|
||||
...
|
||||
|
||||
The ``LLVM_ENABLE_SPHINX=ON`` flag enables Sphinx globally for all LLVM
|
||||
subprojects. ``LIBC_INCLUDE_DOCS=ON`` is specific to libc and tells CMake to
|
||||
The `LLVM_ENABLE_SPHINX=ON` flag enables Sphinx globally for all LLVM
|
||||
subprojects. `LIBC_INCLUDE_DOCS=ON` is specific to libc and tells CMake to
|
||||
register the libc doc targets.
|
||||
|
||||
Building
|
||||
========
|
||||
## Building
|
||||
|
||||
Once configured, build the HTML docs with:
|
||||
|
||||
.. code-block:: bash
|
||||
```bash
|
||||
ninja docs-libc-html
|
||||
```
|
||||
|
||||
ninja docs-libc-html
|
||||
The output is written to `<build-dir>/tools/libc/docs/html/`. Open
|
||||
`index.html` in a browser to view the site.
|
||||
|
||||
The output is written to ``<build-dir>/tools/libc/docs/html/``. Open
|
||||
``index.html`` in a browser to view the site.
|
||||
## Header Status Pages (Auto-generated)
|
||||
|
||||
Header Status Pages (Auto-generated)
|
||||
=====================================
|
||||
The per-header implementation status pages under `docs/headers/` are
|
||||
**not** hand-written RST. They are generated at build time by
|
||||
`libc/utils/docgen/docgen.py`, which:
|
||||
|
||||
The per-header implementation status pages under ``docs/headers/`` are
|
||||
**not** hand-written RST. They are generated at build time by
|
||||
``libc/utils/docgen/docgen.py``, which:
|
||||
|
||||
1. Reads YAML function definitions from ``libc/src/<header>/*.yaml``.
|
||||
2. Scans ``libc/src/<header>/`` for ``.cpp`` implementation files.
|
||||
3. Checks ``libc/include/llvm-libc-macros/`` for macro ``#define`` entries.
|
||||
4. Emits an RST ``list-table`` showing each symbol's implementation status,
|
||||
1. Reads YAML function definitions from `libc/src/<header>/*.yaml`.
|
||||
2. Scans `libc/src/<header>/` for `.cpp` implementation files.
|
||||
3. Checks `libc/include/llvm-libc-macros/` for macro `#define` entries.
|
||||
4. Emits an RST `list-table` showing each symbol's implementation status,
|
||||
C standard section, and POSIX link.
|
||||
|
||||
If you add a new function and regenerate, these pages update automatically.
|
||||
Do **not** hand-edit the generated RST files in ``docs/headers/`` — your
|
||||
Do **not** hand-edit the generated RST files in `docs/headers/` — your
|
||||
changes will be overwritten the next time the docs are built.
|
||||
|
||||
Troubleshooting
|
||||
===============
|
||||
## Troubleshooting
|
||||
|
||||
``Extension error: Could not import extension myst_parser``
|
||||
On Debian/Ubuntu: ``sudo apt-get install python3-myst-parser``.
|
||||
Otherwise: ``pip install -r llvm/docs/requirements.txt``.
|
||||
`Extension error: Could not import extension myst_parser`
|
||||
: On Debian/Ubuntu: `sudo apt-get install python3-myst-parser`.
|
||||
Otherwise: `pip install -r llvm/docs/requirements.txt`.
|
||||
|
||||
``WARNING: document isn't included in any toctree``
|
||||
A new RST/Markdown file needs a ``toctree`` entry. Add it to the
|
||||
appropriate ``index.rst`` or its parent toctree.
|
||||
`WARNING: document isn't included in any toctree`
|
||||
: A new RST/Markdown file needs a `toctree` entry. Add it to the
|
||||
appropriate `index.rst` or its parent toctree.
|
||||
|
||||
``Extension error: No module named 'sphinx_reredirects'``
|
||||
Same fix: ``pip install -r llvm/docs/requirements.txt``.
|
||||
`Extension error: No module named 'sphinx_reredirects'`
|
||||
: Same fix: `pip install -r llvm/docs/requirements.txt`.
|
||||
|
|
|
|||
|
|
@ -1,351 +1,181 @@
|
|||
.. _builtin_compatibility:
|
||||
(builtin_compatibility)=
|
||||
|
||||
==============================
|
||||
GCC Compatibility of Builtins
|
||||
==============================
|
||||
# GCC Compatibility of Builtins
|
||||
|
||||
LLVM-libc is written with Clang as the reference compiler but is expected to
|
||||
build under GCC as well. Many headers reach for compiler intrinsics
|
||||
(``__builtin_*``) for fast paths and for IEEE-754 semantics. Not every
|
||||
``__builtin_*`` exists in every compiler. a large family is Clang-only,
|
||||
and several others were added in specific GCC releases. This page records
|
||||
build under GCC as well. Many headers reach for compiler intrinsics
|
||||
(`__builtin_*`) for fast paths and for IEEE-754 semantics. Not every
|
||||
`__builtin_*` exists in every compiler. a large family is Clang-only,
|
||||
and several others were added in specific GCC releases. This page records
|
||||
which builtins the libc code base references today and the minimum GCC
|
||||
basepoint that ships each one.
|
||||
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| Builtin | gcc-5 | gcc-6 | gcc-7 | gcc-8 | gcc-9 | gcc-10 | gcc-11 | gcc-12 | gcc-13 | gcc-14 | gcc-15 | gcc-16 | gcc-17 |
|
||||
+========================================+=========+=========+=========+=========+=========+=========+=========+=========+=========+=========+=========+=========+=========+
|
||||
| ``__builtin_aarch64_get_fpcr`` | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_aarch64_get_fpsr`` | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_aarch64_set_fpcr`` | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_aarch64_set_fpsr`` | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_aarch64_wsr64`` | | | | | | | | | | | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_abs`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_addc`` | | | | | | | | | | | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_addcb`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_addcl`` | | | | | | | | | | | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_addcll`` | | | | | | | | | | | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_addcs`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_add_overflow`` | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_addressof`` | | | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_align_down`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_align_up`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_alloca`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_amdgcn_ldexp`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_amdgcn_ldexpf`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_amdgcn_s_sendmsg`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_amdgcn_s_sleep`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_amdgcn_workitem_id_x`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_arm_get_fpscr`` | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_arm_isb`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_arm_set_fpscr`` | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_arm_wsr64`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_assume`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_assume_aligned`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_bcmp`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_bit_cast`` | | | | | | | | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_bswap16`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_bswap32`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_bswap64`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_ceil`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_ceilf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_clear_padding`` | | | | | | | | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_clz`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_clzg`` | | | | | | | | | | | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_clzl`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_clzll`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_clzs`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_complex`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_convertvector`` | | | | | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_copysign`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_copysignf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_copysignf16`` | | | | | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_ctz`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_ctzg`` | | | | | | | | | | | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_ctzl`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_ctzll`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_ctzs`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_elementwise_abs`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_elementwise_canonicalize`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_elementwise_ceil`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_elementwise_copysign`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_elementwise_floor`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_elementwise_fma`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_elementwise_fmod`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_elementwise_max`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_elementwise_min`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_elementwise_nearbyint`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_elementwise_rint`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_elementwise_round`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_elementwise_roundeven`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_elementwise_sqrt`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_elementwise_trunc`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_expect`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_fabs`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_fabsf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_fabsf16`` | | | | | | | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_floor`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_floorf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_flt_rounds`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_fma`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_fmaf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_fmax`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_fmaxf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_fmaxf16`` | | | | | | | | | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_fmin`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_fminf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_fminf16`` | | | | | | | | | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_fmod`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_fmodf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_fpclassify`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_frame_address`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_frexp`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_frexpf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_func`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_huge_val`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_huge_valf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_ia32_ldmxcsr`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_ia32_pause`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_ia32_stmxcsr`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_inff`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_is_aligned`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_is_constant_evaluated`` | | | | | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_isfinite`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_isinf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_isnan`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_isnormal`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_launder`` | | | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_ldexp`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_ldexpf`` | | | | | | | | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_masked_compress_store`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_masked_expand_load`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_masked_gather`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_masked_load`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_masked_scatter`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_masked_store`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_memcmp`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_memcmp_inline`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_memcpy`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_memcpy_inline`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_memmove`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_memset`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_memset_inline`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_mul_overflow`` | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_nanf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_nans`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_nansf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_nansl`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_nearbyint`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_nearbyintf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_nondeterministic_value`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_nontemporal_store`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_offsetof`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_popcount`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_popcountg`` | | | | | | | | | | | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_popcountl`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_popcountll`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_prefetch`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_readcyclecounter`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_readsteadycounter`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_reduce_add`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_reduce_and`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_reduce_max`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_reduce_min`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_reduce_mul`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_reduce_or`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_reduce_xor`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_remainder`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_remainderf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_return_address`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_rint`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_rintf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_round`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_roundeven`` | | | | | | | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_roundevenf`` | | | | | | | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_roundf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_sadd_overflow`` | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_shufflevector`` | | | | | | | | | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_signbit`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_snprintf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_sqrt`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_sqrtf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_strlen`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_subc`` | | | | | | | | | | | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_subcb`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_subcl`` | | | | | | | | | | | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_subcll`` | | | | | | | | | | | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_subcs`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_sub_overflow`` | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_trap`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_trunc`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_truncf`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_unreachable`` | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__builtin_vectorelements`` | | | | | | | | | | | | | |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| ``__has_builtin`` | | | | | | |check| | |check| | |check| | |check| | |check| | |check| | |check| | |check| |
|
||||
+----------------------------------------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+---------+
|
||||
| Builtin | gcc-5 | gcc-6 | gcc-7 | gcc-8 | gcc-9 | gcc-10 | gcc-11 | gcc-12 | gcc-13 | gcc-14 | gcc-15 | gcc-16 | gcc-17 |
|
||||
| ------------------------------------ | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- |
|
||||
| `__builtin_aarch64_get_fpcr` | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_aarch64_get_fpsr` | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_aarch64_set_fpcr` | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_aarch64_set_fpsr` | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_aarch64_wsr64` | | | | | | | | | | | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_abs` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_addc` | | | | | | | | | | | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_addcb` | | | | | | | | | | | | | |
|
||||
| `__builtin_addcl` | | | | | | | | | | | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_addcll` | | | | | | | | | | | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_addcs` | | | | | | | | | | | | | |
|
||||
| `__builtin_add_overflow` | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_addressof` | | | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_align_down` | | | | | | | | | | | | | |
|
||||
| `__builtin_align_up` | | | | | | | | | | | | | |
|
||||
| `__builtin_alloca` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_amdgcn_ldexp` | | | | | | | | | | | | | |
|
||||
| `__builtin_amdgcn_ldexpf` | | | | | | | | | | | | | |
|
||||
| `__builtin_amdgcn_s_sendmsg` | | | | | | | | | | | | | |
|
||||
| `__builtin_amdgcn_s_sleep` | | | | | | | | | | | | | |
|
||||
| `__builtin_amdgcn_workitem_id_x` | | | | | | | | | | | | | |
|
||||
| `__builtin_arm_get_fpscr` | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_arm_isb` | | | | | | | | | | | | | |
|
||||
| `__builtin_arm_set_fpscr` | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_arm_wsr64` | | | | | | | | | | | | | |
|
||||
| `__builtin_assume` | | | | | | | | | | | | | |
|
||||
| `__builtin_assume_aligned` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_bcmp` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_bit_cast` | | | | | | | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_bswap16` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_bswap32` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_bswap64` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_ceil` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_ceilf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_clear_padding` | | | | | | | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_clz` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_clzg` | | | | | | | | | | | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_clzl` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_clzll` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_clzs` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_complex` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_convertvector` | | | | | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_copysign` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_copysignf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_copysignf16` | | | | | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_ctz` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_ctzg` | | | | | | | | | | | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_ctzl` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_ctzll` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_ctzs` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_elementwise_abs` | | | | | | | | | | | | | |
|
||||
| `__builtin_elementwise_canonicalize` | | | | | | | | | | | | | |
|
||||
| `__builtin_elementwise_ceil` | | | | | | | | | | | | | |
|
||||
| `__builtin_elementwise_copysign` | | | | | | | | | | | | | |
|
||||
| `__builtin_elementwise_floor` | | | | | | | | | | | | | |
|
||||
| `__builtin_elementwise_fma` | | | | | | | | | | | | | |
|
||||
| `__builtin_elementwise_fmod` | | | | | | | | | | | | | |
|
||||
| `__builtin_elementwise_max` | | | | | | | | | | | | | |
|
||||
| `__builtin_elementwise_min` | | | | | | | | | | | | | |
|
||||
| `__builtin_elementwise_nearbyint` | | | | | | | | | | | | | |
|
||||
| `__builtin_elementwise_rint` | | | | | | | | | | | | | |
|
||||
| `__builtin_elementwise_round` | | | | | | | | | | | | | |
|
||||
| `__builtin_elementwise_roundeven` | | | | | | | | | | | | | |
|
||||
| `__builtin_elementwise_sqrt` | | | | | | | | | | | | | |
|
||||
| `__builtin_elementwise_trunc` | | | | | | | | | | | | | |
|
||||
| `__builtin_expect` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_fabs` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_fabsf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_fabsf16` | | | | | | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_floor` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_floorf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_flt_rounds` | | | | | | | | | | | | | |
|
||||
| `__builtin_fma` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_fmaf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_fmax` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_fmaxf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_fmaxf16` | | | | | | | | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_fmin` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_fminf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_fminf16` | | | | | | | | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_fmod` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_fmodf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_fpclassify` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_frame_address` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_frexp` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_frexpf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_func` | | | | | | | | | | | | | |
|
||||
| `__builtin_huge_val` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_huge_valf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_ia32_ldmxcsr` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_ia32_pause` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_ia32_stmxcsr` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_inff` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_is_aligned` | | | | | | | | | | | | | |
|
||||
| `__builtin_is_constant_evaluated` | | | | | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_isfinite` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_isinf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_isnan` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_isnormal` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_launder` | | | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_ldexp` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_ldexpf` | | | | | | | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_masked_compress_store` | | | | | | | | | | | | | |
|
||||
| `__builtin_masked_expand_load` | | | | | | | | | | | | | |
|
||||
| `__builtin_masked_gather` | | | | | | | | | | | | | |
|
||||
| `__builtin_masked_load` | | | | | | | | | | | | | |
|
||||
| `__builtin_masked_scatter` | | | | | | | | | | | | | |
|
||||
| `__builtin_masked_store` | | | | | | | | | | | | | |
|
||||
| `__builtin_memcmp` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_memcmp_inline` | | | | | | | | | | | | | |
|
||||
| `__builtin_memcpy` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_memcpy_inline` | | | | | | | | | | | | | |
|
||||
| `__builtin_memmove` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_memset` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_memset_inline` | | | | | | | | | | | | | |
|
||||
| `__builtin_mul_overflow` | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_nanf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_nans` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_nansf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_nansl` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_nearbyint` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_nearbyintf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_nondeterministic_value` | | | | | | | | | | | | | |
|
||||
| `__builtin_nontemporal_store` | | | | | | | | | | | | | |
|
||||
| `__builtin_offsetof` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_popcount` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_popcountg` | | | | | | | | | | | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_popcountl` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_popcountll` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_prefetch` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_readcyclecounter` | | | | | | | | | | | | | |
|
||||
| `__builtin_readsteadycounter` | | | | | | | | | | | | | |
|
||||
| `__builtin_reduce_add` | | | | | | | | | | | | | |
|
||||
| `__builtin_reduce_and` | | | | | | | | | | | | | |
|
||||
| `__builtin_reduce_max` | | | | | | | | | | | | | |
|
||||
| `__builtin_reduce_min` | | | | | | | | | | | | | |
|
||||
| `__builtin_reduce_mul` | | | | | | | | | | | | | |
|
||||
| `__builtin_reduce_or` | | | | | | | | | | | | | |
|
||||
| `__builtin_reduce_xor` | | | | | | | | | | | | | |
|
||||
| `__builtin_remainder` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_remainderf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_return_address` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_rint` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_rintf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_round` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_roundeven` | | | | | | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_roundevenf` | | | | | | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_roundf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_sadd_overflow` | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_shufflevector` | | | | | | | | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_signbit` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_snprintf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_sqrt` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_sqrtf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_strlen` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_subc` | | | | | | | | | | | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_subcb` | | | | | | | | | | | | | |
|
||||
| `__builtin_subcl` | | | | | | | | | | | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_subcll` | | | | | | | | | | | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_subcs` | | | | | | | | | | | | | |
|
||||
| `__builtin_sub_overflow` | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_trap` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_trunc` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_truncf` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_unreachable` | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
| `__builtin_vectorelements` | | | | | | | | | | | | | |
|
||||
| `__has_builtin` | | | | | | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} | {{ check }} |
|
||||
|
|
|
|||
|
|
@ -1,241 +1,235 @@
|
|||
.. _code_style:
|
||||
(code_style)=
|
||||
|
||||
===================
|
||||
The libc code style
|
||||
===================
|
||||
# The libc code style
|
||||
|
||||
Naming style
|
||||
============
|
||||
## Naming style
|
||||
|
||||
For the large part, the libc project follows the general `coding standards of
|
||||
the LLVM project <https://llvm.org/docs/CodingStandards.html>`_. The libc
|
||||
For the large part, the libc project follows the general [coding standards of
|
||||
the LLVM project](https://llvm.org/docs/CodingStandards.html). The libc
|
||||
project differs from that standard with respect to the naming style. The
|
||||
differences are as follows:
|
||||
|
||||
#. **Non-const variables** - This includes function arguments, struct and
|
||||
1. **Non-const variables** - This includes function arguments, struct and
|
||||
class data members, non-const globals and local variables. They all use the
|
||||
``snake_case`` style.
|
||||
#. **const and constexpr variables** - They use the capitalized
|
||||
``SNAKE_CASE`` irrespective of whether they are local or global.
|
||||
#. **Function and methods** - They use the ``snake_case`` style like the
|
||||
`snake_case` style.
|
||||
2. **const and constexpr variables** - They use the capitalized
|
||||
`SNAKE_CASE` irrespective of whether they are local or global.
|
||||
3. **Function and methods** - They use the `snake_case` style like the
|
||||
non-const variables.
|
||||
#. **Internal type names** - These are types which are internal to the libc
|
||||
implementation. They use the ``CaptilizedCamelCase`` style.
|
||||
#. **Public names** - These are the names as prescribed by the standards and
|
||||
4. **Internal type names** - These are types which are internal to the libc
|
||||
implementation. They use the `CaptilizedCamelCase` style.
|
||||
5. **Public names** - These are the names as prescribed by the standards and
|
||||
will follow the style as prescribed by the standards.
|
||||
|
||||
Macro style
|
||||
===========
|
||||
## Macro style
|
||||
|
||||
We define two kinds of macros:
|
||||
|
||||
#. **Build defined** macros are generated by `CMake` or `Bazel` and are passed
|
||||
down to the compiler with the ``-D`` command line flag. They start with the
|
||||
``LIBC_COPT_`` prefix. They are used to tune the behavior of the libc.
|
||||
1. **Build defined** macros are generated by `CMake` or `Bazel` and are passed
|
||||
down to the compiler with the `-D` command line flag. They start with the
|
||||
`LIBC_COPT_` prefix. They are used to tune the behavior of the libc.
|
||||
They either denote an action or define a constant.
|
||||
|
||||
#. **Code defined** macros are defined within the ``src/__support/macros``
|
||||
folder. They all start with the ``LIBC_`` prefix.
|
||||
2. **Code defined** macros are defined within the `src/__support/macros`
|
||||
folder. They all start with the `LIBC_` prefix.
|
||||
|
||||
* ``src/__support/macros/properties/`` - Build related properties like
|
||||
- `src/__support/macros/properties/` - Build related properties like
|
||||
target architecture or enabled CPU features defined by introspecting
|
||||
compiler defined preprocessor definitions.
|
||||
|
||||
* ``architectures.h`` - Target architecture properties.
|
||||
e.g., ``LIBC_TARGET_ARCH_IS_ARM``.
|
||||
* ``compiler.h`` - Host compiler properties.
|
||||
e.g., ``LIBC_COMPILER_IS_CLANG``.
|
||||
* ``cpu_features.h`` - Target cpu feature availability.
|
||||
e.g., ``LIBC_TARGET_CPU_HAS_AVX2``.
|
||||
* ``types.h`` - Type properties and availability.
|
||||
e.g., ``LIBC_TYPES_HAS_FLOAT128``.
|
||||
* ``os.h`` - Target os properties.
|
||||
e.g., ``LIBC_TARGET_OS_IS_LINUX``.
|
||||
- `architectures.h` - Target architecture properties.
|
||||
e.g., `LIBC_TARGET_ARCH_IS_ARM`.
|
||||
- `compiler.h` - Host compiler properties.
|
||||
e.g., `LIBC_COMPILER_IS_CLANG`.
|
||||
- `cpu_features.h` - Target cpu feature availability.
|
||||
e.g., `LIBC_TARGET_CPU_HAS_AVX2`.
|
||||
- `types.h` - Type properties and availability.
|
||||
e.g., `LIBC_TYPES_HAS_FLOAT128`.
|
||||
- `os.h` - Target os properties.
|
||||
e.g., `LIBC_TARGET_OS_IS_LINUX`.
|
||||
|
||||
* ``src/__support/macros/config.h`` - Important compiler and platform
|
||||
- `src/__support/macros/config.h` - Important compiler and platform
|
||||
features. Such macros can be used to produce portable code by
|
||||
parameterizing compilation based on the presence or lack of a given
|
||||
feature. e.g., ``LIBC_HAS_FEATURE``
|
||||
* ``src/__support/macros/attributes.h`` - Attributes for functions, types,
|
||||
and variables. e.g., ``LIBC_UNUSED``
|
||||
* ``src/__support/macros/optimization.h`` - Portable macros for performance
|
||||
optimization. e.g., ``LIBC_LIKELY``, ``LIBC_LOOP_NOUNROLL``
|
||||
feature. e.g., `LIBC_HAS_FEATURE`
|
||||
|
||||
Inline functions and variables defined in header files
|
||||
======================================================
|
||||
- `src/__support/macros/attributes.h` - Attributes for functions, types,
|
||||
and variables. e.g., `LIBC_UNUSED`
|
||||
|
||||
- `src/__support/macros/optimization.h` - Portable macros for performance
|
||||
optimization. e.g., `LIBC_LIKELY`, `LIBC_LOOP_NOUNROLL`
|
||||
|
||||
## Inline functions and variables defined in header files
|
||||
|
||||
When defining functions and variables inline in header files, we follow certain
|
||||
rules:
|
||||
|
||||
#. The functions should not be given file-static linkage. There can be class
|
||||
1. The functions should not be given file-static linkage. There can be class
|
||||
static methods defined inline however.
|
||||
#. Instead of using the ``inline`` keyword, functions should be tagged with the
|
||||
``LIBC_INLINE`` macro and variables should be tagged with the
|
||||
``LIBC_INLINE_VAR`` macro defined in ``src/__support/macros/attributes.h``.
|
||||
|
||||
2. Instead of using the `inline` keyword, functions should be tagged with the
|
||||
`LIBC_INLINE` macro and variables should be tagged with the
|
||||
`LIBC_INLINE_VAR` macro defined in `src/__support/macros/attributes.h`.
|
||||
For example:
|
||||
|
||||
.. code-block:: c++
|
||||
```c++
|
||||
LIBC_INLINE_VAR constexpr bool foo = true;
|
||||
|
||||
LIBC_INLINE_VAR constexpr bool foo = true;
|
||||
LIBC_INLINE ReturnType function_defined_inline(ArgType arg) {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
LIBC_INLINE ReturnType function_defined_inline(ArgType arg) {
|
||||
...
|
||||
}
|
||||
|
||||
#. The ``LIBC_INLINE`` tag should also be added to functions which have
|
||||
3. The `LIBC_INLINE` tag should also be added to functions which have
|
||||
definitions that are implicitly inline. Examples of such functions are
|
||||
class methods (static and non-static) defined inline and ``constexpr``
|
||||
class methods (static and non-static) defined inline and `constexpr`
|
||||
functions.
|
||||
|
||||
Setting ``errno`` from runtime code
|
||||
===================================
|
||||
## Setting `errno` from runtime code
|
||||
|
||||
Many libc functions set ``errno`` to indicate an error condition. If LLVM's libc
|
||||
is being used as the only libc, then the ``errno`` from LLVM's libc is affected.
|
||||
If LLVM's libc is being used in the :ref:`overlay_mode`, then the ``errno`` from
|
||||
Many libc functions set `errno` to indicate an error condition. If LLVM's libc
|
||||
is being used as the only libc, then the `errno` from LLVM's libc is affected.
|
||||
If LLVM's libc is being used in the {ref}`overlay_mode`, then the `errno` from
|
||||
the system libc is affected. When a libc function, which can potentially affect
|
||||
the ``errno``, is called from a unit test, we do not want the global ``errno``
|
||||
(as in, the ``errno`` of the process thread running the unit test) to be
|
||||
affected. If the global ``errno`` is affected, then the operation of the unit
|
||||
the `errno`, is called from a unit test, we do not want the global `errno`
|
||||
(as in, the `errno` of the process thread running the unit test) to be
|
||||
affected. If the global `errno` is affected, then the operation of the unit
|
||||
test infrastructure itself can be affected. To avoid perturbing the unit test
|
||||
infrastructure around the setting of ``errno``, the following rules are to be
|
||||
infrastructure around the setting of `errno`, the following rules are to be
|
||||
followed:
|
||||
|
||||
#. A special macro named ``libc_errno`` defined in ``src/__support/libc_errno.h``
|
||||
should be used when setting ``errno`` from libc runtime code. For example,
|
||||
code to set ``errno`` to ``EINVAL`` should be:
|
||||
1. A special macro named `libc_errno` defined in `src/__support/libc_errno.h`
|
||||
should be used when setting `errno` from libc runtime code. For example,
|
||||
code to set `errno` to `EINVAL` should be:
|
||||
|
||||
.. code-block:: c++
|
||||
```c++
|
||||
libc_errno = EINVAL;
|
||||
```
|
||||
|
||||
libc_errno = EINVAL;
|
||||
|
||||
#. ``errno`` should be set just before returning from the implementation of the
|
||||
2. `errno` should be set just before returning from the implementation of the
|
||||
public function. It should not be set from within helper functions. Helper
|
||||
functions should use idiomatic C++ constructs like
|
||||
`cpp::optional <https://github.com/llvm/llvm-project/blob/main/libc/src/__support/CPP/optional.h>`_
|
||||
[cpp::optional](https://github.com/llvm/llvm-project/blob/main/libc/src/__support/CPP/optional.h)
|
||||
and
|
||||
`ErrorOr <https://github.com/llvm/llvm-project/blob/main/libc/src/__support/error_or.h>`_
|
||||
[ErrorOr](https://github.com/llvm/llvm-project/blob/main/libc/src/__support/error_or.h)
|
||||
to return error values.
|
||||
|
||||
#. The header file ``src/__support/libc_errno.h`` is shipped as part of the target
|
||||
corresponding to the ``errno`` entrypoint ``libc.src.errno.errno``. We do
|
||||
not in general allow dependencies between entrypoints. However, the ``errno``
|
||||
3. The header file `src/__support/libc_errno.h` is shipped as part of the target
|
||||
corresponding to the `errno` entrypoint `libc.src.errno.errno`. We do
|
||||
not in general allow dependencies between entrypoints. However, the `errno`
|
||||
entrypoint is the only exceptional entrypoint on which other entrypoints
|
||||
should explicitly depend on if they set ``errno`` to indicate error
|
||||
should explicitly depend on if they set `errno` to indicate error
|
||||
conditions.
|
||||
|
||||
Assertions in libc runtime code
|
||||
===============================
|
||||
## Assertions in libc runtime code
|
||||
|
||||
The libc developers should, and are encouraged to, use assertions freely in
|
||||
the libc runtime code. However, the assertion should be listed via the macro
|
||||
``LIBC_ASSERT`` defined in ``src/__support/libc_assert.h``. This macro can be
|
||||
`LIBC_ASSERT` defined in `src/__support/libc_assert.h`. This macro can be
|
||||
used from anywhere in the libc runtime code. Internally, all it does is to
|
||||
print the assertion expression and exit. It does not implement the semantics
|
||||
of the standard ``assert`` macro. Hence, it can be used from any where in the
|
||||
of the standard `assert` macro. Hence, it can be used from any where in the
|
||||
libc runtime code without causing any recursive calls or chicken-and-egg
|
||||
situations.
|
||||
|
||||
Allocations in the libc runtime code
|
||||
====================================
|
||||
## Allocations in the libc runtime code
|
||||
|
||||
Some libc functions allocate memory. For example, the ``strdup`` function
|
||||
Some libc functions allocate memory. For example, the `strdup` function
|
||||
allocates new memory into which the input string is duplicated. Allocations
|
||||
are typically done by calling a function from the ``malloc`` family of
|
||||
are typically done by calling a function from the `malloc` family of
|
||||
functions. Such functions can fail and return an error value to indicate
|
||||
allocation failure. To conform to standards, the libc should handle
|
||||
allocation failures gracefully and surface the error conditions to the user
|
||||
code as appropriate. Since LLVM's libc is implemented in C++, we want
|
||||
allocations and deallocations to employ C++ operators ``new`` and ``delete``
|
||||
allocations and deallocations to employ C++ operators `new` and `delete`
|
||||
as they implicitly invoke constructors and destructors respectively. However,
|
||||
if we use the default ``new`` and ``delete`` operators, the libc will end up
|
||||
if we use the default `new` and `delete` operators, the libc will end up
|
||||
depending on the C++ runtime. To avoid such a dependence, and to handle
|
||||
allocation failures gracefully, we use special ``new`` and ``delete`` operators
|
||||
allocation failures gracefully, we use special `new` and `delete` operators
|
||||
defined in
|
||||
`src/__support/CPP/new.h <https://github.com/llvm/llvm-project/blob/main/libc/src/__support/CPP/new.h>`_.
|
||||
[`src/__support/CPP/new.h`](https://github.com/llvm/llvm-project/blob/main/libc/src/__support/CPP/new.h).
|
||||
Allocations and deallocations using these operators employ a pattern like
|
||||
this:
|
||||
|
||||
.. code-block:: c++
|
||||
```c++
|
||||
#include "src/__support/CPP/new.h"
|
||||
#include "src/__support/alloc-checker.h"
|
||||
|
||||
#include "src/__support/CPP/new.h"
|
||||
#include "src/__support/alloc-checker.h"
|
||||
...
|
||||
|
||||
...
|
||||
|
||||
LIBC_NAMESPACE::AllocChecker ac;
|
||||
auto *obj = new (ac) Type(...);
|
||||
if (!ac) {
|
||||
// handle allocator failure.
|
||||
}
|
||||
...
|
||||
delete obj;
|
||||
LIBC_NAMESPACE::AllocChecker ac;
|
||||
auto *obj = new (ac) Type(...);
|
||||
if (!ac) {
|
||||
// handle allocator failure.
|
||||
}
|
||||
...
|
||||
delete obj;
|
||||
```
|
||||
|
||||
The only exception to using the above pattern is if allocating using the
|
||||
``realloc`` function is of value. In such cases, prefer to use only the
|
||||
``malloc`` family of functions for allocations and deallocations. Allocation
|
||||
`realloc` function is of value. In such cases, prefer to use only the
|
||||
`malloc` family of functions for allocations and deallocations. Allocation
|
||||
failures will still need to be handled gracefully. Further, keep in mind that
|
||||
these functions do not call the constructors and destructors of the
|
||||
allocated/deallocated objects. So, use these functions carefully and only
|
||||
when it is absolutely clear that constructor and destructor invocation is
|
||||
not required.
|
||||
|
||||
Warnings in sources
|
||||
===================
|
||||
## Warnings in sources
|
||||
|
||||
We expect contributions to be free of warnings from the `minimum supported
|
||||
compiler versions`__ (and newer).
|
||||
We expect contributions to be free of warnings from the [minimum supported
|
||||
compiler versions](https://libc.llvm.org/compiler_support.html#minimum-supported-versions) (and newer).
|
||||
|
||||
.. __: https://libc.llvm.org/compiler_support.html#minimum-supported-versions
|
||||
|
||||
Header Inclusion Policy
|
||||
=======================
|
||||
## Header Inclusion Policy
|
||||
|
||||
Because llvm-libc supports
|
||||
`Overlay Mode <https://libc.llvm.org/overlay_mode.html>`__,
|
||||
`Full Host Build Mode <https://libc.llvm.org/full_host_build.html>`__ and
|
||||
`Full Cross Build Mode <https://libc.llvm.org/full_cross_build.html>`__ care
|
||||
must be taken when ``#include``'ing certain headers.
|
||||
[Overlay Mode](https://libc.llvm.org/overlay_mode.html),
|
||||
[Full Host Build Mode](https://libc.llvm.org/full_host_build.html) and
|
||||
[Full Cross Build Mode](https://libc.llvm.org/full_cross_build.html) care
|
||||
must be taken when `#include`'ing certain headers.
|
||||
|
||||
The ``include/`` directory contains public facing headers that users must
|
||||
The `include/` directory contains public facing headers that users must
|
||||
consume for fullbuild mode. As such, types defined here will have ABI
|
||||
implications as these definitions may differ from the underlying system for
|
||||
overlay mode and are NEVER appropriate to include in ``libc/src/`` without
|
||||
preprocessor guards for ``LLVM_LIBC_FULL_BUILD``.
|
||||
overlay mode and are NEVER appropriate to include in `libc/src/` without
|
||||
preprocessor guards for `LLVM_LIBC_FULL_BUILD`.
|
||||
|
||||
Consider the case where an implementation in ``libc/src/`` may wish to refer to
|
||||
a ``sigset_t``, what header should be included? ``<signal.h>``, ``<spawn.h>``,
|
||||
``<sys/select.h>``?
|
||||
Consider the case where an implementation in `libc/src/` may wish to refer to
|
||||
a `sigset_t`, what header should be included? `<signal.h>`, `<spawn.h>`,
|
||||
`<sys/select.h>`?
|
||||
|
||||
None of the above. Instead, code under ``src/`` should ``#include
|
||||
"hdr/types/sigset_t.h"`` which contains preprocessor guards on
|
||||
``LLVM_LIBC_FULL_BUILD`` to either include the public type (fullbuild mode) or
|
||||
None of the above. Instead, code under `src/` should `#include
|
||||
"hdr/types/sigset_t.h"` which contains preprocessor guards on
|
||||
`LLVM_LIBC_FULL_BUILD` to either include the public type (fullbuild mode) or
|
||||
the underlying system header (overlay mode).
|
||||
|
||||
Implementations in ``libc/src/`` should NOT be ``#include``'ing using ``<>`` or
|
||||
``"include/*``, except for these "proxy" headers that first check for
|
||||
``LLVM_LIBC_FULL_BUILD``.
|
||||
Implementations in `libc/src/` should NOT be `#include`'ing using `<>` or
|
||||
`"include/*`, except for these "proxy" headers that first check for
|
||||
`LLVM_LIBC_FULL_BUILD`.
|
||||
|
||||
These "proxy" headers are similarly used when referring to preprocessor
|
||||
defines. Code under ``libc/src/`` should ``#include`` a proxy header from
|
||||
``hdr/``, which contains a guard on ``LLVM_LIBC_FULL_BUILD`` to either include
|
||||
our header from ``libc/include/`` (fullbuild) or the corresponding underlying
|
||||
defines. Code under `libc/src/` should `#include` a proxy header from
|
||||
`hdr/`, which contains a guard on `LLVM_LIBC_FULL_BUILD` to either include
|
||||
our header from `libc/include/` (fullbuild) or the corresponding underlying
|
||||
system header (overlay).
|
||||
|
||||
Policy on Assembly sources
|
||||
==========================
|
||||
## Policy on Assembly sources
|
||||
|
||||
Coding in high level languages such as C++ provides benefits relative to low
|
||||
level languages like Assembly, such as:
|
||||
|
||||
* Improved safety
|
||||
* Compile time diagnostics
|
||||
* Instrumentation
|
||||
- Improved safety
|
||||
|
||||
* Code coverage
|
||||
* Profile collection
|
||||
* Sanitization
|
||||
* Automatic generation of debug info
|
||||
- Compile time diagnostics
|
||||
|
||||
- Instrumentation
|
||||
|
||||
- Code coverage
|
||||
- Profile collection
|
||||
|
||||
- Sanitization
|
||||
|
||||
- Automatic generation of debug info
|
||||
|
||||
While it's not impossible to have Assembly code that correctly provides all of
|
||||
the above, we do not wish to maintain such Assembly sources in llvm-libc.
|
||||
|
|
@ -263,8 +257,7 @@ maintainers. llvm-libc maintainers reserve the right to reject Assembly
|
|||
contributions that they feel could be better maintained if rewritten in C++,
|
||||
and to revisit this policy in the future.
|
||||
|
||||
LIBC_NAMESPACE_DECL
|
||||
===================
|
||||
## LIBC_NAMESPACE_DECL
|
||||
|
||||
llvm-libc provides a macro `LIBC_NAMESPACE` which contains internal implementations of
|
||||
libc functions and globals. This macro should only be used as an
|
||||
|
|
@ -274,50 +267,47 @@ instead use `LIBC_NAMESPACE_DECL` which declares `LIBC_NAMESPACE` with hidden vi
|
|||
|
||||
Example usage:
|
||||
|
||||
.. code-block:: c++
|
||||
```c++
|
||||
#include "src/__support/macros/config.h" // The macro is defined here.
|
||||
|
||||
#include "src/__support/macros/config.h" // The macro is defined here.
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
void new_function() {
|
||||
...
|
||||
}
|
||||
|
||||
void new_function() {
|
||||
...
|
||||
}
|
||||
|
||||
} // LIBC_NAMESPACE_DECL
|
||||
} // LIBC_NAMESPACE_DECL
|
||||
```
|
||||
|
||||
Having hidden visibility on the namespace ensures extern declarations in a given TU
|
||||
have known visibility and never generate GOT indirections. The attribute guarantees
|
||||
this independently of global compile options and build systems.
|
||||
|
||||
.. _clang_tidy_checks:
|
||||
(clang_tidy_checks)=
|
||||
|
||||
Static Analysis & Clang-Tidy
|
||||
=============================
|
||||
## Static Analysis & Clang-Tidy
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
### Configuration
|
||||
|
||||
LLVM libc uses layered ``.clang-tidy`` configuration files:
|
||||
LLVM libc uses layered `.clang-tidy` configuration files:
|
||||
|
||||
- ``libc/.clang-tidy``: baseline checks for the ``libc`` subtree (currently
|
||||
- `libc/.clang-tidy`: baseline checks for the `libc` subtree (currently
|
||||
focuses on identifier naming conventions).
|
||||
- ``libc/src/.clang-tidy``: adds LLVM-libc-specific checks (``llvmlibc-*``) for
|
||||
implementation code under ``libc/src`` and also enables
|
||||
``readability-identifier-naming`` and ``llvm-header-guard``. Diagnostics from
|
||||
``llvmlibc-*`` checks are treated as errors.
|
||||
- `libc/src/.clang-tidy`: adds LLVM-libc-specific checks (`llvmlibc-*`) for
|
||||
implementation code under `libc/src` and also enables
|
||||
`readability-identifier-naming` and `llvm-header-guard`. Diagnostics from
|
||||
`llvmlibc-*` checks are treated as errors.
|
||||
|
||||
LLVM-libc checks
|
||||
----------------
|
||||
### LLVM-libc checks
|
||||
|
||||
restrict-system-libc-headers
|
||||
----------------------------
|
||||
Check name: ``llvmlibc-restrict-system-libc-headers``.
|
||||
### restrict-system-libc-headers
|
||||
|
||||
Check name: `llvmlibc-restrict-system-libc-headers`.
|
||||
|
||||
One of libc-project's design goals is to use kernel headers and compiler
|
||||
provided headers to prevent code duplication on a per platform basis. This
|
||||
presents a problem when writing implementations since system libc headers are
|
||||
easy to include accidentally and we can't just use the ``-nostdinc`` flag.
|
||||
easy to include accidentally and we can't just use the `-nostdinc` flag.
|
||||
Improperly included system headers can introduce runtime errors because the C
|
||||
standard outlines function prototypes and behaviors but doesn't define
|
||||
underlying implementation details such as the layout of a struct.
|
||||
|
|
@ -325,87 +315,86 @@ underlying implementation details such as the layout of a struct.
|
|||
This check prevents accidental inclusion of system libc headers when writing a
|
||||
libc implementation.
|
||||
|
||||
.. code-block:: c++
|
||||
```c++
|
||||
#include <stdio.h> // Not allowed because it is part of system libc.
|
||||
#include <stddef.h> // Allowed because it is provided by the compiler.
|
||||
#include "internal/stdio.h" // Allowed because it is NOT part of system libc.
|
||||
```
|
||||
|
||||
#include <stdio.h> // Not allowed because it is part of system libc.
|
||||
#include <stddef.h> // Allowed because it is provided by the compiler.
|
||||
#include "internal/stdio.h" // Allowed because it is NOT part of system libc.
|
||||
### implementation-in-namespace
|
||||
|
||||
implementation-in-namespace
|
||||
---------------------------
|
||||
Check name: ``llvmlibc-implementation-in-namespace``.
|
||||
Check name: `llvmlibc-implementation-in-namespace`.
|
||||
|
||||
All LLVM-libc implementation constructs must be enclosed in the
|
||||
``LIBC_NAMESPACE_DECL`` namespace. See :ref:`code_style` for the full technical
|
||||
`LIBC_NAMESPACE_DECL` namespace. See {ref}`code_style` for the full technical
|
||||
rationale and macro definitions.
|
||||
|
||||
This check ensures that top-level declarations in a translation unit are
|
||||
enclosed within the ``LIBC_NAMESPACE_DECL`` namespace.
|
||||
enclosed within the `LIBC_NAMESPACE_DECL` namespace.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
// Correct: implementation inside the correct namespace.
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {}
|
||||
// Namespaces within LIBC_NAMESPACE namespace are allowed.
|
||||
namespace inner{
|
||||
int localVar = 0;
|
||||
}
|
||||
// Functions with C linkage are allowed.
|
||||
extern "C" void str_fuzz(){}
|
||||
}
|
||||
|
||||
// Incorrect: implementation not in a namespace.
|
||||
```c++
|
||||
// Correct: implementation inside the correct namespace.
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {}
|
||||
|
||||
// Incorrect: outer most namespace is not correct.
|
||||
namespace something_else {
|
||||
LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {}
|
||||
// Namespaces within LIBC_NAMESPACE namespace are allowed.
|
||||
namespace inner{
|
||||
int localVar = 0;
|
||||
}
|
||||
// Functions with C linkage are allowed.
|
||||
extern "C" void str_fuzz(){}
|
||||
}
|
||||
|
||||
callee-namespace
|
||||
----------------
|
||||
Check name: ``llvmlibc-callee-namespace``.
|
||||
// Incorrect: implementation not in a namespace.
|
||||
LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {}
|
||||
|
||||
// Incorrect: outer most namespace is not correct.
|
||||
namespace something_else {
|
||||
LLVM_LIBC_FUNCTION(char *, strcpy, (char *dest, const char *src)) {}
|
||||
}
|
||||
```
|
||||
|
||||
### callee-namespace
|
||||
|
||||
Check name: `llvmlibc-callee-namespace`.
|
||||
|
||||
LLVM-libc is distinct because it is designed to maintain interoperability with
|
||||
other libc libraries, including the one that lives on the system. This feature
|
||||
creates some uncertainty about which library a call resolves to especially when
|
||||
a public header with non-namespaced functions like ``string.h`` is included.
|
||||
a public header with non-namespaced functions like `string.h` is included.
|
||||
|
||||
This check ensures any function call resolves to a function within the
|
||||
LIBC_NAMESPACE namespace.
|
||||
|
||||
There are exceptions for the following functions:
|
||||
``__errno_location`` so that ``errno`` can be set;
|
||||
``malloc``, ``calloc``, ``realloc``, ``aligned_alloc``, and ``free`` since they
|
||||
`__errno_location` so that `errno` can be set;
|
||||
`malloc`, `calloc`, `realloc`, `aligned_alloc`, and `free` since they
|
||||
are always external and can be intercepted.
|
||||
|
||||
.. code-block:: c++
|
||||
```c++
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
// Disallow calls to the public versions with the LIBC_NAMESPACE.
|
||||
LIBC_NAMESPACE::strlen("hello");
|
||||
|
||||
// Disallow calls to the public versions with the LIBC_NAMESPACE.
|
||||
LIBC_NAMESPACE::strlen("hello");
|
||||
// Allow calls to compiler provided functions.
|
||||
(void)__builtin_abs(-1);
|
||||
|
||||
// Allow calls to compiler provided functions.
|
||||
(void)__builtin_abs(-1);
|
||||
// Disallow bare calls.
|
||||
strlen("world");
|
||||
|
||||
// Disallow bare calls.
|
||||
strlen("world");
|
||||
// Disallow calling into functions in the global namespace.
|
||||
::strlen("!");
|
||||
|
||||
// Disallow calling into functions in the global namespace.
|
||||
::strlen("!");
|
||||
// Allow calling into specific global functions (explained above).
|
||||
::malloc(10);
|
||||
|
||||
// Allow calling into specific global functions (explained above).
|
||||
::malloc(10);
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
```
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
### inline-function-decl
|
||||
|
||||
Check name: `llvmlibc-inline-function-decl`.
|
||||
|
||||
inline-function-decl
|
||||
--------------------
|
||||
Check name: ``llvmlibc-inline-function-decl``.
|
||||
|
||||
LLVM libc uses the ``LIBC_INLINE`` macro to tag inline function declarations in
|
||||
LLVM libc uses the `LIBC_INLINE` macro to tag inline function declarations in
|
||||
headers. This check enforces that any inline function declaration in a header
|
||||
begins with ``LIBC_INLINE`` and provides a fix-it to insert the macro.
|
||||
begins with `LIBC_INLINE` and provides a fix-it to insert the macro.
|
||||
|
|
|
|||
|
|
@ -1,144 +1,134 @@
|
|||
.. _configure_options:
|
||||
(configure_options)=
|
||||
|
||||
=================================
|
||||
Adding new libc configure options
|
||||
=================================
|
||||
# Adding new libc configure options
|
||||
|
||||
`There are a number of configure options <../configure.html>`_ which can be used
|
||||
{doc}`There are a number of configure options <../configure>` which can be used
|
||||
to configure the libc build. The config system is driven by a set of
|
||||
hierarchical JSON files. At the top of the hierarchy is a JSON file by name
|
||||
``config.json`` in the ``config`` directory. This JSON file lists the libc
|
||||
`config.json` in the `config` directory. This JSON file lists the libc
|
||||
options which affect all platforms. The default value for the option and a short
|
||||
description about it listed against each option. For example:
|
||||
|
||||
.. code-block:: json
|
||||
```json
|
||||
{
|
||||
"printf": {
|
||||
"LIBC_CONF_PRINTF_DISABLE_FLOAT": {
|
||||
"value": false,
|
||||
"doc": "Disable printing floating point values in printf and friends."
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{
|
||||
"printf": {
|
||||
"LIBC_CONF_PRINTF_DISABLE_FLOAT": {
|
||||
"value": false,
|
||||
"doc": "Disable printing floating point values in printf and friends."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
The above config indicates that the option ``LIBC_CONF_PRINTF_DISABLE_FLOAT``
|
||||
has a value of ``false``. A platform, say the baremetal platform, can choose
|
||||
to override this value in its ``config.json`` file in the ``config/baremetal``
|
||||
The above config indicates that the option `LIBC_CONF_PRINTF_DISABLE_FLOAT`
|
||||
has a value of `false`. A platform, say the baremetal platform, can choose
|
||||
to override this value in its `config.json` file in the `config/baremetal`
|
||||
directory with the following contents:
|
||||
|
||||
.. code-block:: json
|
||||
```json
|
||||
{
|
||||
"printf": {
|
||||
"LIBC_CONF_PRINTF_DISABLE_FLOAT": {
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
{
|
||||
"printf": {
|
||||
"LIBC_CONF_PRINTF_DISABLE_FLOAT": {
|
||||
"value": true
|
||||
}
|
||||
}
|
||||
}
|
||||
Here, the config for the baremetal platform overrides the common `false`
|
||||
value of the `LIBC_CONF_PRINTF_DISABLE_FLOAT` with the `true` value.
|
||||
|
||||
Here, the config for the baremetal platform overrides the common ``false``
|
||||
value of the ``LIBC_CONF_PRINTF_DISABLE_FLOAT`` with the ``true`` value.
|
||||
## Config JSON format
|
||||
|
||||
Config JSON format
|
||||
==================
|
||||
### Named tags
|
||||
|
||||
Named tags
|
||||
----------
|
||||
|
||||
As can be noted from the above examples, ``config.json`` files contains a
|
||||
As can be noted from the above examples, `config.json` files contains a
|
||||
top-level dictionary. The keys of this dictionary are the names of
|
||||
*grouping-tags*. A grouping-tag is nothing but a named tag to refer to a related
|
||||
group of libc options. In the above example, a tag named ``printf`` is used to
|
||||
group all libc options which affect the behavior of ``printf`` and friends.
|
||||
group of libc options. In the above example, a tag named `printf` is used to
|
||||
group all libc options which affect the behavior of `printf` and friends.
|
||||
|
||||
Tag values
|
||||
----------
|
||||
### Tag values
|
||||
|
||||
The value corresponding to each grouping tag is also a dictionary called the
|
||||
*option-dictionary*. The keys of the option-dictionary are the names of the libc
|
||||
options belonging to that grouping tag. For the ``printf`` tag in the above
|
||||
options belonging to that grouping tag. For the `printf` tag in the above
|
||||
example, the option-dictionary is:
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"LIBC_CONF_PRINTF_DISABLE_FLOAT": {
|
||||
"value": false,
|
||||
"doc":
|
||||
}
|
||||
}
|
||||
```json
|
||||
{
|
||||
"LIBC_CONF_PRINTF_DISABLE_FLOAT": {
|
||||
"value": false,
|
||||
"doc":
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The value corresponding to an option key in the option-dictionary is another
|
||||
dictionary with two keys: ``"value"`` and ``"doc"``. The ``"value"`` key has
|
||||
the value of the option listed against it, and the ``"doc"`` key has a short
|
||||
dictionary with two keys: `"value"` and `"doc"`. The `"value"` key has
|
||||
the value of the option listed against it, and the `"doc"` key has a short
|
||||
description of the option listed against it. Note that only the main config
|
||||
file ``config/config.json`` includes the ``"doc"`` key. Options which are of
|
||||
``ON``/``OFF`` kind take boolean values ``true``/``false``. Other types of
|
||||
file `config/config.json` includes the `"doc"` key. Options which are of
|
||||
`ON`/`OFF` kind take boolean values `true`/`false`. Other types of
|
||||
options can take an integral or string value as suitable for that option. In
|
||||
the above option-dictionary, the option-key ``LIBC_CONF_PRINTF_DISABLE_FLOAT``
|
||||
is of boolean type with value ``true``.
|
||||
the above option-dictionary, the option-key `LIBC_CONF_PRINTF_DISABLE_FLOAT`
|
||||
is of boolean type with value `true`.
|
||||
|
||||
Option name format
|
||||
------------------
|
||||
### Option name format
|
||||
|
||||
The option names, or the keys of a option-dictionary, have the following format:
|
||||
|
||||
.. code-block:: none
|
||||
```none
|
||||
LIBC_CONF_<UPPER_CASE_TAG_NAME>_<ACTION_INDICATING_THE_INTENDED_SEMANTICS>
|
||||
```
|
||||
|
||||
LIBC_CONF_<UPPER_CASE_TAG_NAME>_<ACTION_INDICATING_THE_INTENDED_SEMANTICS>
|
||||
|
||||
The option name used in the above examples, ``LIBC_CONF_PRINTF_DISABLE_FLOAT``
|
||||
The option name used in the above examples, `LIBC_CONF_PRINTF_DISABLE_FLOAT`
|
||||
to disable printing of floating point numbers, follows this format: It has the
|
||||
prefix ``LIBC_CONF_``, followed by the grouping-tag name ``PRINTF`` in upper
|
||||
prefix `LIBC_CONF_`, followed by the grouping-tag name `PRINTF` in upper
|
||||
case, followed by the action to disable floating point number printing
|
||||
``LIBC_CONF_PRINTF_DISABLE_FLOAT``.
|
||||
`LIBC_CONF_PRINTF_DISABLE_FLOAT`.
|
||||
|
||||
Mechanics of config application
|
||||
===============================
|
||||
## Mechanics of config application
|
||||
|
||||
Config reading
|
||||
--------------
|
||||
### Config reading
|
||||
|
||||
At libc config time, three different ``config.json`` files are read in the
|
||||
At libc config time, three different `config.json` files are read in the
|
||||
following order:
|
||||
|
||||
1. ``config/config.json``
|
||||
2. ``config/<platform or OS>/config.json`` if present.
|
||||
3. ``config/<platform or OS>/<target arch>/config.json`` if present.
|
||||
1. `config/config.json`
|
||||
2. `config/<platform or OS>/config.json` if present.
|
||||
3. `config/<platform or OS>/<target arch>/config.json` if present.
|
||||
|
||||
Each successive ``config.json`` file overrides the option values set by
|
||||
previously read ``config.json`` files. Likewise, a similarly named command line
|
||||
Each successive `config.json` file overrides the option values set by
|
||||
previously read `config.json` files. Likewise, a similarly named command line
|
||||
option to the cmake command will override the option values specified in all or
|
||||
any of these ``config.json`` files. That is, users will be able to override the
|
||||
any of these `config.json` files. That is, users will be able to override the
|
||||
config options from the command line.
|
||||
|
||||
Config application
|
||||
------------------
|
||||
### Config application
|
||||
|
||||
Local to the directory where an option group is relevant, suitable build logic
|
||||
should convert the CMake config options to appropriate compiler and/or linker
|
||||
flags. Those compile/link flags can be used in listing the affected targets as
|
||||
follows:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
add_object_library(
|
||||
...
|
||||
COMPILE_OPTIONS
|
||||
${common_printf_compile_options}
|
||||
... # Other compile options affecting this target irrespective of the
|
||||
# libc config options
|
||||
)
|
||||
```cmake
|
||||
add_object_library(
|
||||
...
|
||||
COMPILE_OPTIONS
|
||||
${common_printf_compile_options}
|
||||
... # Other compile options affecting this target irrespective of the
|
||||
# libc config options
|
||||
)
|
||||
```
|
||||
|
||||
Note that the above scheme is only an example and not a prescription.
|
||||
Developers should employ a scheme appropriate to the option being added.
|
||||
|
||||
Automatic doc update
|
||||
====================
|
||||
## Automatic doc update
|
||||
|
||||
The CMake configure step automatically generates the user document
|
||||
``doc/configure.rst``, which contains user information about the libc configure
|
||||
options, using the information in the main ``config/config.json`` file.
|
||||
An update to ``config/config.json`` will trigger reconfiguration by CMake, which
|
||||
in turn will regenerate the documentation in ``doc/configure.rst``.
|
||||
`doc/configure.rst`, which contains user information about the libc configure
|
||||
options, using the information in the main `config/config.json` file.
|
||||
An update to `config/config.json` will trigger reconfiguration by CMake, which
|
||||
in turn will regenerate the documentation in `doc/configure.rst`.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
.. _entrypoints:
|
||||
(entrypoints)=
|
||||
|
||||
========================
|
||||
Entrypoints in LLVM libc
|
||||
========================
|
||||
# Entrypoints in LLVM libc
|
||||
|
||||
A public function or a global variable provided by LLVM-libc is called an
|
||||
*entrypoint*. The notion of entrypoints is central to LLVM-libc's source layout,
|
||||
|
|
@ -10,107 +8,103 @@ build system, and configuration management. This document provides a technical
|
|||
reference for how entrypoints are defined, implemented, and integrated into
|
||||
the final library.
|
||||
|
||||
What is an Entrypoint?
|
||||
----------------------
|
||||
## What is an Entrypoint?
|
||||
|
||||
In a typical C library, all functions are part of a monolithic archive. In
|
||||
LLVM-libc, each function (e.g., ``malloc``, ``printf``, ``isalpha``) is treated
|
||||
LLVM-libc, each function (e.g., `malloc`, `printf`, `isalpha`) is treated
|
||||
as a discrete "entrypoint" unit. This allows for:
|
||||
|
||||
- **Granular build targets**: You can build just the objects you need.
|
||||
- **Configuration-driven selection**: Different operating systems and
|
||||
architectures can pick specific implementations for the same function.
|
||||
- **Support for multiple build modes**: Selectively replacing parts of a host's
|
||||
libc in :ref:`overlay_mode` or building a complete library in :ref:`full_host_build`.
|
||||
libc in {ref}`overlay_mode` or building a complete library in {ref}`full_host_build`.
|
||||
|
||||
The Lifecycle of an Entrypoint
|
||||
------------------------------
|
||||
## The Lifecycle of an Entrypoint
|
||||
|
||||
1. **Implementation**: The function is implemented in a ``.cpp`` file using
|
||||
1. **Implementation**: The function is implemented in a `.cpp` file using
|
||||
LLVM-libc's coding and implementation standards.
|
||||
2. **Registration**: The entrypoint is defined as a CMake target using the
|
||||
``add_entrypoint_object`` rule.
|
||||
3. **Configuration**: The target name is added to an ``entrypoints.txt`` file
|
||||
`add_entrypoint_object` rule.
|
||||
3. **Configuration**: The target name is added to an `entrypoints.txt` file
|
||||
to include it in a specific OS/Architecture configuration.
|
||||
|
||||
Implementation Standards
|
||||
------------------------
|
||||
## Implementation Standards
|
||||
|
||||
Implementations live in the ``src/`` directory, organized by the public header
|
||||
they belong to (e.g., ``src/ctype/isalpha.cpp`` for ``ctype.h``).
|
||||
Implementations live in the `src/` directory, organized by the public header
|
||||
they belong to (e.g., `src/ctype/isalpha.cpp` for `ctype.h`).
|
||||
|
||||
Header File Structure
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
### Header File Structure
|
||||
|
||||
Every entrypoint has an internal implementation header file (e.g.,
|
||||
``src/ctype/isalpha.h``). This header declares the function within the
|
||||
``LIBC_NAMESPACE_DECL`` namespace::
|
||||
`src/ctype/isalpha.h`). This header declares the function within the
|
||||
`LIBC_NAMESPACE_DECL` namespace:
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
int isalpha(int c);
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
```
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
int isalpha(int c);
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
```
|
||||
|
||||
Source File Structure
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
### Source File Structure
|
||||
|
||||
The implementation file (e.g., ``src/ctype/isalpha.cpp``) defines the function
|
||||
using the ``LLVM_LIBC_FUNCTION`` macro. This macro handles C-linkage and
|
||||
aliasing::
|
||||
The implementation file (e.g., `src/ctype/isalpha.cpp`) defines the function
|
||||
using the `LLVM_LIBC_FUNCTION` macro. This macro handles C-linkage and
|
||||
aliasing:
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
LLVM_LIBC_FUNCTION(int, isalpha, (int c)) {
|
||||
// ... implementation ...
|
||||
}
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
```
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
LLVM_LIBC_FUNCTION(int, isalpha, (int c)) {
|
||||
// ... implementation ...
|
||||
}
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
```
|
||||
|
||||
For more details on implementation conventions, see the
|
||||
:ref:`implementation_standard` page.
|
||||
{ref}`implementation_standard` page.
|
||||
|
||||
Registration: CMake Rules
|
||||
-------------------------
|
||||
## Registration: CMake Rules
|
||||
|
||||
Entrypoints are registered as CMake targets to make them available to the
|
||||
build system. These rules are usually defined in the ``CMakeLists.txt`` file
|
||||
build system. These rules are usually defined in the `CMakeLists.txt` file
|
||||
within the function's source directory.
|
||||
|
||||
``add_entrypoint_object``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
### `add_entrypoint_object`
|
||||
|
||||
This rule generates a single object file containing the implementation of the
|
||||
entrypoint.
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
add_entrypoint_object(
|
||||
isalpha
|
||||
SRCS isalpha.cpp
|
||||
HDRS isalpha.h
|
||||
DEPENDS
|
||||
.some_internal_dependency
|
||||
)
|
||||
```cmake
|
||||
add_entrypoint_object(
|
||||
isalpha
|
||||
SRCS isalpha.cpp
|
||||
HDRS isalpha.h
|
||||
DEPENDS
|
||||
.some_internal_dependency
|
||||
)
|
||||
```
|
||||
|
||||
For redirecting entrypoints (e.g., when one function is a simple alias for
|
||||
another), the ``REDIRECTED`` option can be specified to the rule.
|
||||
another), the `REDIRECTED` option can be specified to the rule.
|
||||
|
||||
``add_entrypoint_library``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
### `add_entrypoint_library`
|
||||
|
||||
Standard library files like ``libc.a`` and ``libm.a`` are produced by
|
||||
aggregating multiple entrypoint objects. The ``add_entrypoint_library`` target
|
||||
takes a list of ``add_entrypoint_object`` targets and produces a static library.
|
||||
Standard library files like `libc.a` and `libm.a` are produced by
|
||||
aggregating multiple entrypoint objects. The `add_entrypoint_library` target
|
||||
takes a list of `add_entrypoint_object` targets and produces a static library.
|
||||
|
||||
Configuration: ``entrypoints.txt``
|
||||
----------------------------------
|
||||
## Configuration: `entrypoints.txt`
|
||||
|
||||
The final selection of which entrypoints are included in a specific build is
|
||||
determined by ``entrypoints.txt`` files located in the ``libc/config`` tree.
|
||||
determined by `entrypoints.txt` files located in the `libc/config` tree.
|
||||
|
||||
- **Location**: Typically found in ``libc/config/<os>/entrypoints.txt`` or
|
||||
``libc/config/<os>/<arch>/entrypoints.txt``.
|
||||
- **Location**: Typically found in `libc/config/<os>/entrypoints.txt` or
|
||||
`libc/config/<os>/<arch>/entrypoints.txt`.
|
||||
- **Role**: This file acts as the "source of truth" for what is supported on a
|
||||
given platform. A typical bring-up procedure involves progressively adding
|
||||
targets to this file as they are implemented and tested.
|
||||
|
||||
If you are implementing a new entrypoint, you must add its target name to the
|
||||
relevant ``entrypoints.txt`` files for it to be included in the library build.
|
||||
For more details on platform configuration, see the :ref:`porting` guide.
|
||||
relevant `entrypoints.txt` files for it to be included in the library build.
|
||||
For more details on platform configuration, see the {ref}`porting` guide.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,14 @@
|
|||
.. _fuzzing:
|
||||
(fuzzing)=
|
||||
|
||||
Fuzzing for LLVM-libc functions
|
||||
===============================
|
||||
# Fuzzing for LLVM-libc functions
|
||||
|
||||
Fuzz tests are used to ensure quality and security of LLVM-libc implementations.
|
||||
All fuzz tests live under the directory named ``fuzzing``. Within this
|
||||
All fuzz tests live under the directory named `fuzzing`. Within this
|
||||
directory, the fuzz test for a libc function lives in the same nested directory
|
||||
as its implementation in the toplevel ``src`` directory. The build target
|
||||
``libc-fuzzer`` builds all of the enabled fuzz tests (but does not run them).
|
||||
as its implementation in the toplevel `src` directory. The build target
|
||||
`libc-fuzzer` builds all of the enabled fuzz tests (but does not run them).
|
||||
|
||||
Types of fuzz tests
|
||||
===================
|
||||
# Types of fuzz tests
|
||||
|
||||
As of this writing, there are two different kinds of fuzz tests. One kind are
|
||||
the traditional fuzz tests which test one function at a time and only that
|
||||
|
|
@ -18,3 +16,4 @@ particular function. The other kind of tests are what we call as the
|
|||
differential fuzz tests. These tests compare the behavior of LLVM libc
|
||||
implementations with the behavior of the corresponding functions from the system
|
||||
libc.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
.. _header_generation:
|
||||
(header_generation)=
|
||||
|
||||
Generating Public and Internal headers
|
||||
======================================
|
||||
# Generating Public and Internal headers
|
||||
|
||||
There are 3 main components of the Headergen. The first component are the YAML
|
||||
files that contain all the function header information and are separated by
|
||||
|
|
@ -13,24 +12,21 @@ specific components and then reserializes the components into the function
|
|||
header. The Python script also combines the generated header content with
|
||||
header definitions and extra macro and type inclusions from the .h.def file.
|
||||
|
||||
|
||||
Instructions
|
||||
------------
|
||||
## Instructions
|
||||
|
||||
Required Versions:
|
||||
- Python Version: 3.8
|
||||
- PyYAML Version: 5.1
|
||||
- Python Version: 3.8
|
||||
- PyYAML Version: 5.1
|
||||
|
||||
1. Keep full-build mode on when building, otherwise headers will not be
|
||||
generated.
|
||||
2. Once the build is complete, enter in the command line within the build
|
||||
directory ``ninja check-hdrgen`` to ensure that the integration tests are
|
||||
directory `ninja check-hdrgen` to ensure that the integration tests are
|
||||
passing.
|
||||
3. Then enter in the command line ``ninja libc`` to generate headers. Headers
|
||||
will be in ``build/projects/libc/include`` or ``build/libc/include`` in a
|
||||
3. Then enter in the command line `ninja libc` to generate headers. Headers
|
||||
will be in `build/projects/libc/include` or `build/libc/include` in a
|
||||
runtime build. Sys spec headers will be located in
|
||||
``build/projects/libc/include/sys``.
|
||||
|
||||
`build/projects/libc/include/sys`.
|
||||
|
||||
To add a function to the YAML files, you can either manually enter it in the
|
||||
YAML file corresponding to the header it belongs to or add it through the
|
||||
|
|
@ -42,18 +38,18 @@ To add through the command line:
|
|||
|
||||
2. Enter in the command line:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
python3 libc/utils/hdrgen/yaml_to_classes.py
|
||||
libc/include/[yaml_file.yaml] --add_function "<return_type>" <function_name> "<function_arg1, function_arg2>" <standard> <guard> <attribute>
|
||||
```none
|
||||
python3 libc/utils/hdrgen/yaml_to_classes.py
|
||||
libc/include/[yaml_file.yaml] --add_function "<return_type>" <function_name> "<function_arg1, function_arg2>" <standard> <guard> <attribute>
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
python3 libc/utils/hdrgen/yaml_to_classes.py
|
||||
libc/include/ctype.yaml --add_function "char" example_function
|
||||
"int, void, const void" stdc example_float example_attribute
|
||||
```none
|
||||
python3 libc/utils/hdrgen/yaml_to_classes.py
|
||||
libc/include/ctype.yaml --add_function "char" example_function
|
||||
"int, void, const void" stdc example_float example_attribute
|
||||
```
|
||||
|
||||
Keep in mind only the return_type and arguments have quotes around them. If
|
||||
you do not have any guards or attributes you may enter "null" for both.
|
||||
|
|
@ -63,37 +59,34 @@ To add through the command line:
|
|||
examine.
|
||||
|
||||
If you want to sort the functions alphabetically you can check out
|
||||
``libc/utils/hdrgen/hdrgen/yaml_functions_sorted.py``.
|
||||
`libc/utils/hdrgen/hdrgen/yaml_functions_sorted.py`.
|
||||
|
||||
|
||||
Testing
|
||||
-------
|
||||
## Testing
|
||||
|
||||
Headergen has an integration test that you may run once you have configured
|
||||
your CMake within the build directory. In the command line, enter the
|
||||
following: ``ninja check-hdrgen``. The integration test is one test that
|
||||
following: `ninja check-hdrgen`. The integration test is one test that
|
||||
ensures the process of YAML to classes to generate headers works properly. If
|
||||
there are any new additions on formatting headers, make sure the test is
|
||||
updated with the specific addition.
|
||||
|
||||
Integration Test can be found in: ``libc/utils/hdrgen/tests/test_integration.py``
|
||||
Integration Test can be found in: `libc/utils/hdrgen/tests/test_integration.py`
|
||||
|
||||
File to modify if adding something to formatting:
|
||||
``libc/utils/hdrgen/tests/expected_output/test_header.h``
|
||||
`libc/utils/hdrgen/tests/expected_output/test_header.h`
|
||||
|
||||
## Common Errors
|
||||
|
||||
Common Errors
|
||||
-------------
|
||||
1. Missing function specific component
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
"/llvm-project/libc/utils/hdrgen/hdrgen/yaml_to_classes.py", line 67, in yaml_to_classes function_data["return_type"]
|
||||
```none
|
||||
"/llvm-project/libc/utils/hdrgen/hdrgen/yaml_to_classes.py", line 67, in yaml_to_classes function_data["return_type"]
|
||||
```
|
||||
|
||||
If you receive this error or any error pertaining to
|
||||
``function_data[function_specific_component]`` while building the headers
|
||||
`function_data[function_specific_component]` while building the headers
|
||||
that means the function specific component is missing within the YAML files.
|
||||
Through the call stack, you will be able to find the header file which has
|
||||
the issue. Ensure there is no missing function specific component for that
|
||||
|
|
@ -103,38 +96,40 @@ Common Errors
|
|||
|
||||
Example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
CMake Error at:
|
||||
/llvm-project/libc/cmake/modules/LLVMLibCHeaderRules.cmake:86 (message):
|
||||
'add_gen_hdr' rule requires GEN_HDR to be specified.
|
||||
Call Stack (most recent call first):
|
||||
/llvm-project/libc/include/CMakeLists.txt:22 (add_gen_header)
|
||||
/llvm-project/libc/include/CMakeLists.txt:62 (add_header_macro)
|
||||
```none
|
||||
CMake Error at:
|
||||
/llvm-project/libc/cmake/modules/LLVMLibCHeaderRules.cmake:86 (message):
|
||||
'add_gen_hdr' rule requires GEN_HDR to be specified.
|
||||
Call Stack (most recent call first):
|
||||
/llvm-project/libc/include/CMakeLists.txt:22 (add_gen_header)
|
||||
/llvm-project/libc/include/CMakeLists.txt:62 (add_header_macro)
|
||||
```
|
||||
|
||||
If you receive this error, there is a missing YAML file, h_def file, or
|
||||
header name within the ``libc/include/CMakeLists.txt``. The last line in the
|
||||
header name within the `libc/include/CMakeLists.txt`. The last line in the
|
||||
error call stack will point to the header where there is a specific component
|
||||
missing. Ensure the correct style and required files are present:
|
||||
|
||||
| ``[header_name]``
|
||||
| ``[../libc/include/[yaml_file.yaml]``
|
||||
| ``[header_name.h]``
|
||||
| ``DEPENDS``
|
||||
| ``{Necessary Depend Files}``
|
||||
```none
|
||||
[header_name]
|
||||
[../libc/include/[yaml_file.yaml]
|
||||
[header_name.h]
|
||||
DEPENDS
|
||||
{Necessary Depend Files}
|
||||
```
|
||||
|
||||
3. Command line: expected arguments
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
usage: yaml_to_classes.py [-h] [--output_dir OUTPUT_DIR] [--h_def_file H_DEF_FILE]
|
||||
[--add_function RETURN_TYPE NAME ARGUMENTS STANDARDS GUARD ATTRIBUTES]
|
||||
[--e ENTRY_POINTS]
|
||||
yaml_file
|
||||
yaml_to_classes.py:
|
||||
error: argument --add_function: expected 6 arguments
|
||||
```none
|
||||
usage: yaml_to_classes.py [-h] [--output_dir OUTPUT_DIR] [--h_def_file H_DEF_FILE]
|
||||
[--add_function RETURN_TYPE NAME ARGUMENTS STANDARDS GUARD ATTRIBUTES]
|
||||
[--e ENTRY_POINTS]
|
||||
yaml_file
|
||||
yaml_to_classes.py:
|
||||
error: argument --add_function: expected 6 arguments
|
||||
```
|
||||
|
||||
In the process of adding a function, you may run into an issue where the
|
||||
command line is requiring more arguments than what you currently have. Ensure
|
||||
|
|
@ -145,15 +140,15 @@ Common Errors
|
|||
|
||||
Example:
|
||||
|
||||
.. code-block:: none
|
||||
```none
|
||||
File "/llvm-project/libc/utils/hdrgen/hdrgen/header.py", line 60, in __str__ for
|
||||
function in self.functions: AttributeError: 'HeaderFile' object has no
|
||||
attribute 'functions'
|
||||
```
|
||||
|
||||
File "/llvm-project/libc/utils/hdrgen/hdrgen/header.py", line 60, in __str__ for
|
||||
function in self.functions: AttributeError: 'HeaderFile' object has no
|
||||
attribute 'functions'
|
||||
|
||||
When running ``ninja libc`` in the build directory to generate headers you
|
||||
When running `ninja libc` in the build directory to generate headers you
|
||||
may receive the error above. Essentially this means that in
|
||||
``libc/utils/hdrgen/hdrgen/header.py`` there is a missing attribute named functions.
|
||||
`libc/utils/hdrgen/hdrgen/header.py` there is a missing attribute named functions.
|
||||
Make sure all function components are defined within this file and there are
|
||||
no missing functions to add these components.
|
||||
|
||||
|
|
@ -161,22 +156,22 @@ Common Errors
|
|||
|
||||
Example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
/llvm-project/build/projects/libc/include/sched.h:20:25: error: unknown type
|
||||
name 'size_t'; did you mean 'time_t'?
|
||||
20 | int_sched_getcpucount(size_t, const cpu_set_t*) __NOEXCEPT
|
||||
| ^
|
||||
/llvm-project/build/projects/libc/include/llvm-libc-types/time_t.h:15:24:
|
||||
note: 'time_t' declared here
|
||||
15 | typedef __INT64_TYPE__ time_t;
|
||||
| ^
|
||||
```none
|
||||
/llvm-project/build/projects/libc/include/sched.h:20:25: error: unknown type
|
||||
name 'size_t'; did you mean 'time_t'?
|
||||
20 | int_sched_getcpucount(size_t, const cpu_set_t*) __NOEXCEPT
|
||||
| ^
|
||||
/llvm-project/build/projects/libc/include/llvm-libc-types/time_t.h:15:24:
|
||||
note: 'time_t' declared here
|
||||
15 | typedef __INT64_TYPE__ time_t;
|
||||
| ^
|
||||
```
|
||||
|
||||
During the header generation process errors like the one above may occur
|
||||
because there are missing types for a specific header file. Check the YAML
|
||||
file corresponding to the header file and make sure all the necessary types
|
||||
that are being used are input into the types as well. Delete the specific
|
||||
header file from the build folder and re-run ``ninja libc`` to ensure the
|
||||
header file from the build folder and re-run `ninja libc` to ensure the
|
||||
types are being recognized.
|
||||
|
||||
6. Test Integration Errors
|
||||
|
|
@ -184,12 +179,12 @@ Common Errors
|
|||
Sometimes the integration test will fail but that
|
||||
still means the process is working unless the comparison between the output
|
||||
and expected_output is not showing. If that is the case make sure in
|
||||
``libc/utils/hdrgen/tests/test_integration.py`` there are no missing arguments
|
||||
`libc/utils/hdrgen/tests/test_integration.py` there are no missing arguments
|
||||
that run through the script.
|
||||
|
||||
If the integration tests are failing due to mismatching of lines or small
|
||||
errors in spacing that is nothing to worry about. If this is happening while
|
||||
you are making a new change to the formatting of the headers, then
|
||||
ensure the expected output file
|
||||
``libc/utils/hdrgen/tests/expected_output/test_header.h`` has the changes you
|
||||
`libc/utils/hdrgen/tests/expected_output/test_header.h` has the changes you
|
||||
are applying.
|
||||
|
|
|
|||
|
|
@ -1,80 +1,84 @@
|
|||
.. _implementation_standard:
|
||||
(implementation_standard)=
|
||||
|
||||
Convention for implementing entrypoints
|
||||
=======================================
|
||||
# Convention for implementing entrypoints
|
||||
|
||||
The implementations of LLVM-libc entrypoints live in the ``src/`` directory,
|
||||
The implementations of LLVM-libc entrypoints live in the `src/` directory,
|
||||
organized by the public header they belong to. Some entrypoints are platform-
|
||||
specific, and so their implementations are in a subdirectory with the name of
|
||||
the platform (e.g., ``stdio/linux/remove.cpp``).
|
||||
the platform (e.g., `stdio/linux/remove.cpp`).
|
||||
|
||||
For a complete overview of what an entrypoint is and how it is managed in the
|
||||
build system, see the :ref:`entrypoints` documentation.
|
||||
build system, see the {ref}`entrypoints` documentation.
|
||||
|
||||
|
||||
Implementation of entrypoints can span multiple ``.cpp`` and ``.h`` files, but
|
||||
Implementation of entrypoints can span multiple `.cpp` and `.h` files, but
|
||||
there will be at least one header file with name of the form
|
||||
``<entrypoint name>.h`` for every entrypoint. This header file is called the
|
||||
implementation header file. For the ``isalpha`` function, the path to the
|
||||
implementation header file is ``src/ctype/isalpha.h``.
|
||||
`<entrypoint name>.h` for every entrypoint. This header file is called the
|
||||
implementation header file. For the `isalpha` function, the path to the
|
||||
implementation header file is `src/ctype/isalpha.h`.
|
||||
|
||||
Implementation Header File Structure
|
||||
------------------------------------
|
||||
## Implementation Header File Structure
|
||||
|
||||
We will use the ``isalpha`` function from the public ``ctype.h`` header file as an
|
||||
example. The ``isalpha`` function will be declared in an internal header file
|
||||
``src/ctype/isalpha.h`` as follows::
|
||||
We will use the `isalpha` function from the public `ctype.h` header file as an
|
||||
example. The `isalpha` function will be declared in an internal header file
|
||||
`src/ctype/isalpha.h` as follows:
|
||||
|
||||
// --- isalpha.h --- //
|
||||
#ifndef LLVM_LIBC_SRC_CTYPE_ISALPHA_H
|
||||
#define LLVM_LIBC_SRC_CTYPE_ISALPHA_H
|
||||
```
|
||||
// --- isalpha.h --- //
|
||||
#ifndef LLVM_LIBC_SRC_CTYPE_ISALPHA_H
|
||||
#define LLVM_LIBC_SRC_CTYPE_ISALPHA_H
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
int isalpha(int c);
|
||||
int isalpha(int c);
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif LLVM_LIBC_SRC_CTYPE_ISALPHA_H
|
||||
#endif LLVM_LIBC_SRC_CTYPE_ISALPHA_H
|
||||
```
|
||||
|
||||
All LLVM-libc implementation constructs must be enclosed in the
|
||||
``LIBC_NAMESPACE_DECL`` namespace. See :ref:`code_style` for the full technical
|
||||
`LIBC_NAMESPACE_DECL` namespace. See {ref}`code_style` for the full technical
|
||||
rationale and macro definitions.
|
||||
|
||||
``.cpp`` File Structure
|
||||
-----------------------
|
||||
## `.cpp` File Structure
|
||||
|
||||
The main ``.cpp`` file is named ``<entrypoint name>.cpp`` and is usually in the
|
||||
The main `.cpp` file is named `<entrypoint name>.cpp` and is usually in the
|
||||
same folder as the header. It contains the signature of the entrypoint function,
|
||||
which must be defined with the ``LLVM_LIBC_FUNCTION`` macro. For example, the
|
||||
``isalpha`` function from ``ctype.h`` is defined as follows, in the file
|
||||
``src/ctype/isalpha.cpp``::
|
||||
which must be defined with the `LLVM_LIBC_FUNCTION` macro. For example, the
|
||||
`isalpha` function from `ctype.h` is defined as follows, in the file
|
||||
`src/ctype/isalpha.cpp`:
|
||||
|
||||
// --- isalpha.cpp --- //
|
||||
```
|
||||
// --- isalpha.cpp --- //
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LLVM_LIBC_FUNCTION(int, isalpha, (int c)) {
|
||||
// ... implementation goes here.
|
||||
}
|
||||
LLVM_LIBC_FUNCTION(int, isalpha, (int c)) {
|
||||
// ... implementation goes here.
|
||||
}
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
```
|
||||
|
||||
Notice the use of the macro ``LLVM_LIBC_FUNCTION``. This macro helps us define
|
||||
Notice the use of the macro `LLVM_LIBC_FUNCTION`. This macro helps us define
|
||||
a C alias symbol for the C++ implementation. For example, for a library build,
|
||||
the macro is defined as follows::
|
||||
the macro is defined as follows:
|
||||
|
||||
#define LLVM_LIBC_FUNCTION(type, name, arglist)
|
||||
LLVM_LIBC_FUNCTION_IMPL(type, name, arglist)
|
||||
#define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist)
|
||||
LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name)
|
||||
__##name##_impl__ __asm__(#name);
|
||||
decltype(LIBC_NAMESPACE::name) name [[gnu::alias(#name)]];
|
||||
type __##name##_impl__ arglist
|
||||
```
|
||||
#define LLVM_LIBC_FUNCTION(type, name, arglist)
|
||||
LLVM_LIBC_FUNCTION_IMPL(type, name, arglist)
|
||||
#define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist)
|
||||
LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name)
|
||||
__##name##_impl__ __asm__(#name);
|
||||
decltype(LIBC_NAMESPACE::name) name [[gnu::alias(#name)]];
|
||||
type __##name##_impl__ arglist
|
||||
```
|
||||
|
||||
The LLVM_LIBC_FUNCTION_ATTR macro is normally defined to nothing, but can be
|
||||
defined by vendors who want to set their own attributes.
|
||||
|
||||
When defining a variable, use the ``LLVM_LIBC_VARIABLE`` macro::
|
||||
When defining a variable, use the `LLVM_LIBC_VARIABLE` macro:
|
||||
|
||||
LLVM_LIBC_VARIABLE(char **, environ) = nullptr;
|
||||
```
|
||||
LLVM_LIBC_VARIABLE(char **, environ) = nullptr;
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,69 +1,59 @@
|
|||
.. _implementing_a_function:
|
||||
(implementing_a_function)=
|
||||
|
||||
===========================
|
||||
Implementing a New Function
|
||||
===========================
|
||||
# Implementing a New Function
|
||||
|
||||
This guide provides a step-by-step walkthrough for adding a new function to LLVM-libc.
|
||||
|
||||
Overview
|
||||
========
|
||||
## Overview
|
||||
|
||||
Adding a new function involves several steps, from updating the public specification to implementing and testing the code. Below is the standard checklist for contributors.
|
||||
|
||||
Step-by-Step Checklist
|
||||
======================
|
||||
## Step-by-Step Checklist
|
||||
|
||||
1. Header Entry
|
||||
---------------
|
||||
### 1. Header Entry
|
||||
|
||||
Update the standard YAML file that describes the public header to ensure the function is included in the generated public header.
|
||||
|
||||
* **File**: ``libc/include/<header>.yaml`` (or ``libc/include/sys/<header>.yaml`` for system headers)
|
||||
* Add the new function to the ``functions`` list.
|
||||
* Specify its name, return type, and arguments.
|
||||
* List the standards it complies with (e.g., ``stdc``, ``POSIX``).
|
||||
- **File**: `libc/include/<header>.yaml` (or `libc/include/sys/<header>.yaml` for system headers)
|
||||
- Add the new function to the `functions` list.
|
||||
- Specify its name, return type, and arguments.
|
||||
- List the standards it complies with (e.g., `stdc`, `POSIX`).
|
||||
|
||||
2. Header Declaration
|
||||
---------------------
|
||||
### 2. Header Declaration
|
||||
|
||||
Declare the function in the internal implementation header file. This file is used by other internal code.
|
||||
|
||||
* **File**: ``libc/src/<header>/<func>.h``
|
||||
* Follow the structure defined in :ref:`implementation_standard`.
|
||||
* Ensure the declaration is inside the ``LIBC_NAMESPACE_DECL`` namespace.
|
||||
- **File**: `libc/src/<header>/<func>.h`
|
||||
- Follow the structure defined in {ref}`implementation_standard`.
|
||||
- Ensure the declaration is inside the `LIBC_NAMESPACE_DECL` namespace.
|
||||
|
||||
3. Implementation
|
||||
-----------------
|
||||
### 3. Implementation
|
||||
|
||||
Write the actual code for the function.
|
||||
|
||||
* **File**: ``libc/src/<header>/<func>.cpp`` (or ``libc/src/<header>/<os>/<func>.cpp`` for platform-specific implementations)
|
||||
* Use the ``LLVM_LIBC_FUNCTION`` macro.
|
||||
* Refer to :ref:`code_style` for naming and layout conventions.
|
||||
- **File**: `libc/src/<header>/<func>.cpp` (or `libc/src/<header>/<os>/<func>.cpp` for platform-specific implementations)
|
||||
- Use the `LLVM_LIBC_FUNCTION` macro.
|
||||
- Refer to {ref}`code_style` for naming and layout conventions.
|
||||
|
||||
4. CMake Rule
|
||||
-------------
|
||||
### 4. CMake Rule
|
||||
|
||||
Add a CMake target for the new function so it can be compiled.
|
||||
|
||||
* **File**: ``libc/src/<header>/CMakeLists.txt``
|
||||
* Add an ``add_entrypoint_object`` rule for the new file.
|
||||
* List all internal dependencies correctly to ensure proper build order.
|
||||
- **File**: `libc/src/<header>/CMakeLists.txt`
|
||||
- Add an `add_entrypoint_object` rule for the new file.
|
||||
- List all internal dependencies correctly to ensure proper build order.
|
||||
|
||||
5. Platform Registration
|
||||
------------------------
|
||||
### 5. Platform Registration
|
||||
|
||||
Register the new entrypoint for the target platforms to include it in the build.
|
||||
|
||||
* **File**: ``libc/config/<os>/<arch>/entrypoints.txt``
|
||||
* Add the new function to the list of active entrypoints.
|
||||
- **File**: `libc/config/<os>/<arch>/entrypoints.txt`
|
||||
- Add the new function to the list of active entrypoints.
|
||||
|
||||
6. Testing
|
||||
----------
|
||||
### 6. Testing
|
||||
|
||||
Create tests to verify the implementation.
|
||||
|
||||
* **File**: ``libc/test/src/<header>/<func>_test.cpp``
|
||||
* Add corresponding tests using the internal testing framework.
|
||||
* Update the ``CMakeLists.txt`` in the test directory (``libc/test/src/<header>/CMakeLists.txt``) to include the new test target.
|
||||
- **File**: `libc/test/src/<header>/<func>_test.cpp`
|
||||
- Add corresponding tests using the internal testing framework.
|
||||
- Update the `CMakeLists.txt` in the test directory (`libc/test/src/<header>/CMakeLists.txt`) to include the new test target.
|
||||
|
|
|
|||
|
|
@ -1,25 +1,24 @@
|
|||
.. _developer_guides:
|
||||
(developer_guides)=
|
||||
|
||||
================
|
||||
Developer Guides
|
||||
================
|
||||
# Developer Guides
|
||||
|
||||
Navigate to the links below for information on the respective topics:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
```{toctree}
|
||||
:maxdepth: 1
|
||||
|
||||
building_docs
|
||||
code_style
|
||||
source_tree_layout
|
||||
entrypoints
|
||||
implementing_a_function
|
||||
config_options
|
||||
fuzzing
|
||||
header_generation
|
||||
implementation_standard
|
||||
undefined_behavior
|
||||
printf_behavior
|
||||
builtin_compatibility
|
||||
syscall_wrapper_refactor
|
||||
modular_format
|
||||
building_docs
|
||||
code_style
|
||||
source_tree_layout
|
||||
entrypoints
|
||||
implementing_a_function
|
||||
config_options
|
||||
fuzzing
|
||||
header_generation
|
||||
implementation_standard
|
||||
undefined_behavior
|
||||
printf_behavior
|
||||
builtin_compatibility
|
||||
syscall_wrapper_refactor
|
||||
modular_format
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
.. _modular_format:
|
||||
(modular_format)=
|
||||
|
||||
======================
|
||||
Modular format strings
|
||||
======================
|
||||
# Modular format strings
|
||||
|
||||
Introduction
|
||||
============
|
||||
## Introduction
|
||||
|
||||
Several C standard library functions (most notably, ``printf`` and ``scanf``),
|
||||
Several C standard library functions (most notably, `printf` and `scanf`),
|
||||
present a large amount of related features to the caller configured via a
|
||||
format string. This benefits code size at the caller, since format strings are
|
||||
typically quite dense, and the equivalent of many individual calls can be
|
||||
|
|
@ -21,9 +18,8 @@ involve large tables which may be wholly dead. However, due to the format
|
|||
string structure, this code is dead in a way previously invisible to the
|
||||
compiler.
|
||||
|
||||
To address this, an clang attribute was introduced: ``modular_format(<impl_fn>,
|
||||
<impl_name>, <aspects>...)``. This adds to the semantics of the existing
|
||||
``format`` attribute (which must also be present, if implicitly.) The first
|
||||
To address this, an clang attribute was introduced: `modular_format(<impl_fn>, <impl_name>, <aspects>...)`. This adds to the semantics of the existing
|
||||
`format` attribute (which must also be present, if implicitly.) The first
|
||||
argument is a symbol naming a modular version of the implementation; this
|
||||
version only weakly refers to "aspects" of the implementation that may not be
|
||||
necessary for certain format strings. The second argument is general
|
||||
|
|
@ -31,26 +27,25 @@ necessary for certain format strings. The second argument is general
|
|||
aspects of the format string. When the compiler sees that a given call only
|
||||
needs a fixed set of aspects of the implementation, it may redirect the call to
|
||||
the implementation function and emit a series of relocations to symbols named
|
||||
``<impl_name>_<aspect>``. These in turn bring the needed aspects of the call
|
||||
`<impl_name>_<aspect>`. These in turn bring the needed aspects of the call
|
||||
into the link. The default entrypoints fall the modular ones, except they bring
|
||||
in every possible implementation aspect.
|
||||
|
||||
Mechanism
|
||||
=========
|
||||
## Mechanism
|
||||
|
||||
This functionality is currently gated behind ``LIBC_COPT_PRINTF_MODULAR``. When
|
||||
set, the ``printf``-family functions gain modular variants, and the regular
|
||||
This functionality is currently gated behind `LIBC_COPT_PRINTF_MODULAR`. When
|
||||
set, the `printf`-family functions gain modular variants, and the regular
|
||||
variants are modified to call them and emit NONE relocations against all
|
||||
implementation aspects.
|
||||
implementation aspects.
|
||||
|
||||
The implementation aspects are defined in headers using the
|
||||
``LIBC_PRINTF_MODULE((<decl>), { <body> })`` macro. If
|
||||
``LIBC_COPT_PRINTF_MODULAR`` is not defined, then this macro makes these
|
||||
``LIBC_INLINE`` definitions as per usual. Otherwise, for normal usage, these
|
||||
`LIBC_PRINTF_MODULE((<decl>), { <body> })` macro. If
|
||||
`LIBC_COPT_PRINTF_MODULAR` is not defined, then this macro makes these
|
||||
`LIBC_INLINE` definitions as per usual. Otherwise, for normal usage, these
|
||||
become weak declarations, which causes any references to the module to become
|
||||
weak. The implementations are moved to a dedicated impl file for groups of
|
||||
modules. These define the aspect symbol and the module impls by defining
|
||||
``LIBC_PRINTF_DEFINE_MODULES`` before including the header. This causes the to
|
||||
`LIBC_PRINTF_DEFINE_MODULES` before including the header. This causes the to
|
||||
be brought into the link exactly when the aspect symbol is referenced.
|
||||
|
||||
Template functions present a special complication: the implementation must
|
||||
|
|
@ -58,7 +53,7 @@ instantiate them for any value that may be used. Since the purpose of the
|
|||
templates is to implement a fixed interface, the possible arguments should
|
||||
always be fixed and finite. Accordingly, libc contains def files to enumerate
|
||||
possible arguments and provide handling for each. Templates are instantiated in
|
||||
the headers whenever ``LIBC_PRINTF_DEFINE_MODULES`` is defined.
|
||||
the headers whenever `LIBC_PRINTF_DEFINE_MODULES` is defined.
|
||||
|
||||
libc and the compiler may understand different sets of aspect names, but their
|
||||
understanding of what an aspect name means must be identical. libc reports the
|
||||
|
|
|
|||
|
|
@ -1,11 +1,9 @@
|
|||
.. _printf_behavior:
|
||||
(printf_behavior)=
|
||||
|
||||
====================================
|
||||
Printf Behavior Under All Conditions
|
||||
====================================
|
||||
# Printf Behavior Under All Conditions
|
||||
|
||||
## Introduction:
|
||||
|
||||
Introduction:
|
||||
=============
|
||||
On the "defining undefined behavior" page, I said you should write down your
|
||||
decisions regarding undefined behavior in your functions. This is that document
|
||||
for my printf implementation.
|
||||
|
|
@ -26,102 +24,100 @@ share the same behavior.
|
|||
This document assumes familiarity with the definition of the printf function and
|
||||
is intended as a reference, not a replacement for the original standards.
|
||||
|
||||
--------------
|
||||
General Flags:
|
||||
--------------
|
||||
### General Flags:
|
||||
|
||||
These compile-time flags will change the behavior of LLVM-libc's printf when it
|
||||
is compiled. Combinations of flags that are incompatible will be marked.
|
||||
|
||||
LIBC_COPT_STDIO_USE_SYSTEM_FILE
|
||||
-------------------------------
|
||||
#### LIBC_COPT_STDIO_USE_SYSTEM_FILE
|
||||
|
||||
When set, this flag changes fprintf and printf to use the FILE API from the
|
||||
system's libc, instead of LLVM-libc's internal FILE API. This is set by default
|
||||
when LLVM-libc is built in overlay mode.
|
||||
|
||||
LIBC_COPT_PRINTF_DISABLE_INDEX_MODE
|
||||
-----------------------------------
|
||||
When set, this flag disables support for the POSIX "%n$" format, hereafter
|
||||
#### LIBC_COPT_PRINTF_DISABLE_INDEX_MODE
|
||||
|
||||
When set, this flag disables support for the POSIX "%n\$" format, hereafter
|
||||
referred to as "index mode"; conversions using the index mode format will be
|
||||
treated as invalid. This reduces code size.
|
||||
|
||||
LIBC_COPT_PRINTF_INDEX_ARR_LEN
|
||||
------------------------------
|
||||
#### LIBC_COPT_PRINTF_INDEX_ARR_LEN
|
||||
|
||||
This flag takes a positive integer value, defaulting to 128. This flag
|
||||
determines the number of entries the parser's type descriptor array has. This is
|
||||
used in index mode to avoid re-parsing the format string to determine types when
|
||||
an index lower than the previously specified one is requested. This has no
|
||||
effect when index mode is disabled.
|
||||
|
||||
LIBC_COPT_PRINTF_DISABLE_WRITE_INT
|
||||
----------------------------------
|
||||
#### LIBC_COPT_PRINTF_DISABLE_WRITE_INT
|
||||
|
||||
When set, this flag disables support for the C Standard "%n" conversion; any
|
||||
"%n" conversion will be treated as invalid. This is set by default to improve
|
||||
security.
|
||||
|
||||
LIBC_COPT_PRINTF_DISABLE_FLOAT
|
||||
------------------------------
|
||||
#### LIBC_COPT_PRINTF_DISABLE_FLOAT
|
||||
|
||||
When set, this flag disables support for floating point numbers and all their
|
||||
conversions (%a, %f, %e, %g); any floating point number conversion will be
|
||||
treated as invalid. This reduces code size.
|
||||
|
||||
LIBC_COPT_PRINTF_DISABLE_FIXED_POINT
|
||||
------------------------------------
|
||||
#### LIBC_COPT_PRINTF_DISABLE_FIXED_POINT
|
||||
|
||||
When set, this flag disables support for fixed point numbers and all their
|
||||
conversions (%r, %k); any fixed point number conversion will be treated as
|
||||
invalid. This reduces code size. This has no effect if the current compiler does
|
||||
not support fixed point numbers.
|
||||
|
||||
LIBC_COPT_PRINTF_DISABLE_WIDE
|
||||
-----------------------------
|
||||
#### LIBC_COPT_PRINTF_DISABLE_WIDE
|
||||
|
||||
When set, this flag disables support for wide characters (%lc and %ls). Any
|
||||
conversions will be ignored. This reduces code size. This will be set by default
|
||||
on windows platforms as current printf implementation does not support UTF-16 wide
|
||||
characters.
|
||||
|
||||
LIBC_COPT_PRINTF_DISABLE_BITINT
|
||||
-------------------------------
|
||||
#### LIBC_COPT_PRINTF_DISABLE_BITINT
|
||||
|
||||
When set, this flag disables the bit int length modifiers wNUM and wfNUM. The
|
||||
length modifiers will be treated as if they don't exist, so conversions using
|
||||
them will be treated as invalid. This reduces code size.
|
||||
|
||||
.. _printf_no_nullptr_checks:
|
||||
(printf_no_nullptr_checks)=
|
||||
|
||||
#### LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
|
||||
|
||||
LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
|
||||
----------------------------------
|
||||
When set, this flag disables the nullptr checks in %n and %s; passing a null
|
||||
pointer is undefined behavior. See :ref:`printf_conversion` for the behavior
|
||||
pointer is undefined behavior. See {ref}`printf_conversion` for the behavior
|
||||
when nullptr checks are enabled.
|
||||
|
||||
LIBC_COPT_PRINTF_CONV_ATLAS
|
||||
---------------------------
|
||||
#### LIBC_COPT_PRINTF_CONV_ATLAS
|
||||
|
||||
When set, this flag changes the include path for the "converter atlas" which is
|
||||
a header that includes all the files containing the conversion functions. This
|
||||
is not recommended to be set without careful consideration.
|
||||
|
||||
LIBC_COPT_PRINTF_HEX_LONG_DOUBLE
|
||||
--------------------------------
|
||||
#### LIBC_COPT_PRINTF_HEX_LONG_DOUBLE
|
||||
|
||||
When set, this flag replaces all decimal long double conversions (%Lf, %Le, %Lg)
|
||||
with hexadecimal long double conversions (%La). This will improve performance
|
||||
significantly, but may cause some tests to fail. This has no effect when float
|
||||
conversions are disabled.
|
||||
|
||||
LIBC_COPT_PRINTF_NO_CONVERT_FLOAT128
|
||||
------------------------------------
|
||||
When set, this flag disables support for __float128 conversions using the "Q"
|
||||
#### LIBC_COPT_PRINTF_NO_CONVERT_FLOAT128
|
||||
|
||||
When set, this flag disables support for `__float128` conversions using the "Q"
|
||||
length modifier (%Qa, %Qf, %Qe, %Qg). This flag has no effect on conversions
|
||||
using the "L" length modifier when long double is the same type as __float128.
|
||||
using the "L" length modifier when long double is the same type as `__float128`.
|
||||
This has little to no effect on performance or binary size.
|
||||
|
||||
--------------------------------
|
||||
Float Conversion Internal Flags:
|
||||
--------------------------------
|
||||
### Float Conversion Internal Flags:
|
||||
|
||||
The following floating point conversion flags are provided for reference, but
|
||||
are not recommended to be adjusted except by persons familiar with the Printf
|
||||
Ryu Algorithm. Additionally they have no effect when float conversions are
|
||||
disabled.
|
||||
|
||||
LIBC_COPT_FLOAT_TO_STR_NO_SPECIALIZE_LD
|
||||
---------------------------------------
|
||||
#### LIBC_COPT_FLOAT_TO_STR_NO_SPECIALIZE_LD
|
||||
|
||||
This flag disables the separate long double conversion implementation. It is
|
||||
not based on the Ryu algorithm, instead generating the digits by
|
||||
multiplying/dividing the written-out number by 10^9 to get blocks. It's
|
||||
|
|
@ -132,46 +128,44 @@ calls with large exponents. This is the default. This specialization overrides
|
|||
other flags, so this flag must be set for other flags to effect the long double
|
||||
behavior.
|
||||
|
||||
LIBC_COPT_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE
|
||||
-------------------------------------------------
|
||||
#### LIBC_COPT_FLOAT_TO_STR_USE_MEGA_LONG_DOUBLE_TABLE
|
||||
|
||||
When set, the float to string decimal conversion algorithm will use a larger
|
||||
table to accelerate long double conversions. This larger table is around 5MB of
|
||||
size when compiled. This flag also affects __float128 conversions.
|
||||
size when compiled. This flag also affects `__float128` conversions.
|
||||
|
||||
#### LIBC_COPT_FLOAT_TO_STR_USE_DYADIC_FLOAT
|
||||
|
||||
LIBC_COPT_FLOAT_TO_STR_USE_DYADIC_FLOAT
|
||||
---------------------------------------
|
||||
When set, the float to string decimal conversion algorithm will use dyadic
|
||||
floats instead of a table when performing floating point conversions. This
|
||||
results in ~50 digits of accuracy in the result, then zeroes for the remaining
|
||||
values. This may improve performance but may also cause some tests to fail. The
|
||||
flag ending in _LD is the same, but only applies to long double decimal
|
||||
flag ending in `_LD` is the same, but only applies to long double decimal
|
||||
conversions.
|
||||
|
||||
LIBC_COPT_FLOAT_TO_STR_USE_INT_CALC
|
||||
-----------------------------------
|
||||
#### LIBC_COPT_FLOAT_TO_STR_USE_INT_CALC
|
||||
|
||||
When set, the float to string decimal conversion algorithm will use wide
|
||||
integers instead of a table when performing floating point conversions. This
|
||||
gives the same results as the table, but is very slow at the extreme ends of
|
||||
the long double range.
|
||||
|
||||
LIBC_COPT_FLOAT_TO_STR_NO_TABLE
|
||||
-------------------------------
|
||||
#### LIBC_COPT_FLOAT_TO_STR_NO_TABLE
|
||||
|
||||
When set, the float to string decimal conversion algorithm will not use either
|
||||
the mega table or the normal table for any conversions. Instead it will set
|
||||
algorithmic constants to improve performance when using calculation algorithms.
|
||||
If this flag is set without any calculation algorithm flag set, an error will
|
||||
occur.
|
||||
|
||||
--------
|
||||
Parsing:
|
||||
--------
|
||||
### Parsing:
|
||||
|
||||
When printf encounters an invalid conversion specification, the entire
|
||||
conversion specification will be passed literally to the output string.
|
||||
As an example, printf("%Z") would display "%Z".
|
||||
|
||||
If an index mode conversion is requested for index "n" and there exists a number
|
||||
in [1,n) that does not have a conversion specified in the format string, then
|
||||
in `[1,n)` that does not have a conversion specified in the format string, then
|
||||
the conversion for index "n" is considered invalid.
|
||||
|
||||
If a non-index mode (also referred to as sequential mode) conversion is
|
||||
|
|
@ -187,29 +181,28 @@ treated as if it was "ll" (lowercase LL). For this purpose the list of integer
|
|||
conversions is d, i, u, o, x, X, b, B, n.
|
||||
|
||||
If a conversion specification ending in % has any options that consume arguments
|
||||
(e.g. "%*.*%") those arguments will be consumed as normal, but their values will
|
||||
(e.g. `"%*.*%"`) those arguments will be consumed as normal, but their values will
|
||||
be ignored.
|
||||
|
||||
If a conversion specification ends in a null byte ('\0') then it shall be
|
||||
If a conversion specification ends in a null byte ('0') then it shall be
|
||||
treated as an invalid conversion followed by a null byte.
|
||||
|
||||
If a number passed as a field width or precision value is out of range for an
|
||||
int, then it will be treated as the largest value in the int range
|
||||
(e.g. "%-999999999999.999999999999s" is the same as "%-2147483647.2147483647s").
|
||||
|
||||
If the field width is set to INT_MIN by using the '*' form,
|
||||
e.g. printf("%*d", INT_MIN, 1), it will be treated as INT_MAX, since -INT_MIN is
|
||||
If the field width is set to INT_MIN by using the `'*'` form,
|
||||
e.g. `printf("%*d", INT_MIN, 1)`, it will be treated as INT_MAX, since -INT_MIN is
|
||||
not representable as an int.
|
||||
|
||||
If a number passed as a bit width is less than or equal to zero, the conversion
|
||||
is considered invalid. If the provided bit width is larger than the width of
|
||||
uintmax_t, it will be clamped to the width of uintmax_t.
|
||||
|
||||
.. _printf_conversion:
|
||||
(printf_conversion)=
|
||||
|
||||
### Conversion
|
||||
|
||||
----------
|
||||
Conversion
|
||||
----------
|
||||
Any conversion specification that contains a flag or option that it does not
|
||||
have defined behavior for will ignore that flag or option (e.g. %.5c is the same
|
||||
as %c).
|
||||
|
|
@ -252,9 +245,9 @@ errno = 0 and alt form is specified, the conversion will be a string conversion
|
|||
on "0" for simplicity of implementation. This matches what other libcs
|
||||
implementing this feature have done.
|
||||
|
||||
If the compiler is detected as having support for __float128, "Q" is an accepted
|
||||
If the compiler is detected as having support for `__float128`, "Q" is an accepted
|
||||
length modifier for floating point conversions (%Qa, %Qf, %Qe, %Qg), unless
|
||||
disabled by LIBC_COPT_PRINTF_NO_CONVERT_FLOAT128. A conversion using the
|
||||
"Q" length modifier will be treated as invalid in any of the following
|
||||
conditions: __float128 is not supported, the "Q" length modifier is disabled, or
|
||||
conditions: `__float128` is not supported, the "Q" length modifier is disabled, or
|
||||
the conversion does not use a floating point format specifier.
|
||||
|
|
|
|||
|
|
@ -1,124 +1,112 @@
|
|||
.. _source_tree_layout:
|
||||
(source_tree_layout)=
|
||||
|
||||
============================
|
||||
LLVM-libc Source Tree Layout
|
||||
============================
|
||||
# LLVM-libc Source Tree Layout
|
||||
|
||||
At the top-level, LLVM-libc source tree is organized in to the following
|
||||
directories::
|
||||
directories:
|
||||
|
||||
+ libc
|
||||
- benchmarks
|
||||
- cmake
|
||||
- config
|
||||
- docs
|
||||
- examples
|
||||
- fuzzing
|
||||
- hdr
|
||||
- include
|
||||
- lib
|
||||
- src
|
||||
- startup
|
||||
- test
|
||||
- utils
|
||||
```
|
||||
+ libc
|
||||
- benchmarks
|
||||
- cmake
|
||||
- config
|
||||
- docs
|
||||
- examples
|
||||
- fuzzing
|
||||
- hdr
|
||||
- include
|
||||
- lib
|
||||
- src
|
||||
- startup
|
||||
- test
|
||||
- utils
|
||||
```
|
||||
|
||||
Each of these directories is explained briefly below.
|
||||
|
||||
The ``benchmarks`` directory
|
||||
----------------------------
|
||||
## The `benchmarks` directory
|
||||
|
||||
The ``benchmarks`` directory contains LLVM-libc's benchmarking utilities. These
|
||||
The `benchmarks` directory contains LLVM-libc's benchmarking utilities. These
|
||||
are mostly used for the memory functions.
|
||||
|
||||
The ``config`` directory
|
||||
------------------------
|
||||
## The `config` directory
|
||||
|
||||
The ``config`` directory contains the default configurations for the targets
|
||||
LLVM-libc supports. These are files in the ``config/<platform>/<architecture>/``
|
||||
subdirectory called ``entrypoints.txt``, ``exclude.txt``, ``headers.txt``, and
|
||||
``config.json``. These tell cmake which entrypoints are available, which
|
||||
The `config` directory contains the default configurations for the targets
|
||||
LLVM-libc supports. These are files in the `config/<platform>/<architecture>/`
|
||||
subdirectory called `entrypoints.txt`, `exclude.txt`, `headers.txt`, and
|
||||
`config.json`. These tell cmake which entrypoints are available, which
|
||||
entrypoints to exclude, which headers to generate, and what options to set for
|
||||
the current target respectively. There are also other platform specific files in
|
||||
the ``config/<platform>/`` subdirectory.
|
||||
the `config/<platform>/` subdirectory.
|
||||
|
||||
The ``cmake`` directory
|
||||
-----------------------
|
||||
## The `cmake` directory
|
||||
|
||||
The ``cmake`` directory contains the implementations of LLVM-libc's CMake build
|
||||
The `cmake` directory contains the implementations of LLVM-libc's CMake build
|
||||
rules.
|
||||
|
||||
The ``docs`` directory
|
||||
----------------------
|
||||
## The `docs` directory
|
||||
|
||||
The ``docs`` directory contains design docs and also informative documents like
|
||||
The `docs` directory contains design docs and also informative documents like
|
||||
this document on source layout.
|
||||
|
||||
The ``fuzzing`` directory
|
||||
-------------------------
|
||||
## The `fuzzing` directory
|
||||
|
||||
This directory contains fuzzing tests for the various components of LLVM-libc.
|
||||
The directory structure within this directory mirrors the directory structure
|
||||
of the top-level ``libc`` directory itself. For more details, see
|
||||
:doc:`fuzzing`.
|
||||
of the top-level `libc` directory itself. For more details, see
|
||||
{doc}`fuzzing`.
|
||||
|
||||
The ``hdr`` directory
|
||||
---------------------
|
||||
## The `hdr` directory
|
||||
|
||||
This directory contains proxy headers which are included from the files in the
|
||||
src directory. These proxy headers either include our internal type or macro
|
||||
definitions, or the system's type or macro definitions, depending on if we are
|
||||
in fullbuild or overlay mode.
|
||||
|
||||
The ``include`` directory
|
||||
-------------------------
|
||||
## The `include` directory
|
||||
|
||||
The ``include`` directory contains:
|
||||
The `include` directory contains:
|
||||
|
||||
1. ``*.h.def`` files - These files are used to construct the generated public
|
||||
1. `*.h.def` files - These files are used to construct the generated public
|
||||
header files.
|
||||
2. Self contained public header files - These are header files which are
|
||||
already in the form that get installed when LLVM-libc is installed on a
|
||||
user's computer. These are mostly in the ``llvm-libc-macros`` and
|
||||
``llvm-libc-types`` subdirectories.
|
||||
user's computer. These are mostly in the `llvm-libc-macros` and
|
||||
`llvm-libc-types` subdirectories.
|
||||
|
||||
The ``lib`` directory
|
||||
---------------------
|
||||
## The `lib` directory
|
||||
|
||||
This directory contains a ``CMakeLists.txt`` file listing the targets for the
|
||||
public libraries ``libc.a``, ``libm.a`` etc.
|
||||
This directory contains a `CMakeLists.txt` file listing the targets for the
|
||||
public libraries `libc.a`, `libm.a` etc.
|
||||
|
||||
The ``src`` directory
|
||||
---------------------
|
||||
## The `src` directory
|
||||
|
||||
This directory contains the implementations of the llvm-libc entrypoints. For
|
||||
more details on what an entrypoint is and how it is implemented, see the
|
||||
:ref:`entrypoints` documentation. It is further organized as follows:
|
||||
{ref}`entrypoints` documentation. It is further organized as follows:
|
||||
|
||||
1. There is a top-level CMakeLists.txt file.
|
||||
2. For every public header file provided by llvm-libc, there exists a
|
||||
corresponding directory in the ``src`` directory. The name of the directory
|
||||
corresponding directory in the `src` directory. The name of the directory
|
||||
is same as the base name of the header file. For example, the directory
|
||||
corresponding to the public ``math.h`` header file is named ``math``. The
|
||||
corresponding to the public `math.h` header file is named `math`. The
|
||||
implementation standard document explains more about the *header*
|
||||
directories.
|
||||
|
||||
The ``startup`` directory
|
||||
-------------------------
|
||||
## The `startup` directory
|
||||
|
||||
This directory contains the implementations of the application startup objects
|
||||
like ``crt1.o`` etc.
|
||||
like `crt1.o` etc.
|
||||
|
||||
The ``test`` directory
|
||||
----------------------
|
||||
## The `test` directory
|
||||
|
||||
This directory contains tests for the various components of LLVM-libc. The
|
||||
directory structure within this directory mirrors the directory structure of the
|
||||
toplevel ``libc`` directory itself. A test for, say the ``mmap`` function, lives
|
||||
in the directory ``test/src/sys/mman/`` as implementation of ``mmap`` lives in
|
||||
``src/sys/mman``.
|
||||
toplevel `libc` directory itself. A test for, say the `mmap` function, lives
|
||||
in the directory `test/src/sys/mman/` as implementation of `mmap` lives in
|
||||
`src/sys/mman`.
|
||||
|
||||
The ``utils`` directory
|
||||
-----------------------
|
||||
## The `utils` directory
|
||||
|
||||
This directory contains utilities used by other parts of the LLVM-libc system.
|
||||
See the `README` files in the subdirectories within this directory to learn
|
||||
|
|
|
|||
|
|
@ -1,71 +1,68 @@
|
|||
.. _syscall_wrapper_refactor:
|
||||
(syscall_wrapper_refactor)=
|
||||
|
||||
==============================
|
||||
Syscall Wrapper Refactoring
|
||||
==============================
|
||||
# Syscall Wrapper Refactoring
|
||||
|
||||
Purpose
|
||||
=======
|
||||
## Purpose
|
||||
|
||||
LLVM-libc is transitioning to a centralized system for Linux syscalls. The goal
|
||||
is to move all direct ``syscall_impl`` calls into a dedicated directory:
|
||||
``src/__support/OSUtil/linux/syscall_wrappers/``.
|
||||
is to move all direct `syscall_impl` calls into a dedicated directory:
|
||||
`src/__support/OSUtil/linux/syscall_wrappers/`.
|
||||
|
||||
This refactor provides several benefits:
|
||||
|
||||
* **Reusability**: Allows multiple entrypoints to share a single syscall
|
||||
- **Reusability**: Allows multiple entrypoints to share a single syscall
|
||||
implementation without public APIs depending on other public APIs.
|
||||
* **Type Safety**: Using ``ErrorOr<T>`` ensures that error conditions are
|
||||
- **Type Safety**: Using `ErrorOr<T>` ensures that error conditions are
|
||||
handled explicitly.
|
||||
* **Consistency**: Standardizes the conversion of syscall return values into
|
||||
- **Consistency**: Standardizes the conversion of syscall return values into
|
||||
errno-compatible objects.
|
||||
* **Maintainability**: Centralizes platform-specific syscall logic, making it
|
||||
- **Maintainability**: Centralizes platform-specific syscall logic, making it
|
||||
easier to audit and update.
|
||||
|
||||
The Pattern
|
||||
===========
|
||||
## The Pattern
|
||||
|
||||
Each syscall should have its own header-only library in the ``syscall_wrappers``
|
||||
directory. The wrapper function should return an ``ErrorOr<T>``. Wrappers live
|
||||
in the ``linux_syscalls`` namespace to make call sites self-documenting and to
|
||||
Each syscall should have its own header-only library in the `syscall_wrappers`
|
||||
directory. The wrapper function should return an `ErrorOr<T>`. Wrappers live
|
||||
in the `linux_syscalls` namespace to make call sites self-documenting and to
|
||||
clearly identify any leakage into OS-generic code.
|
||||
|
||||
Example Wrapper (``src/__support/OSUtil/linux/syscall_wrappers/read.h``):
|
||||
--------------------------------------------------------------------------
|
||||
### Example Wrapper (`src/__support/OSUtil/linux/syscall_wrappers/read.h`):
|
||||
|
||||
.. code-block:: c++
|
||||
```c++
|
||||
#include "hdr/types/ssize_t.h"
|
||||
#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/error_or.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include <sys/syscall.h> // For syscall numbers
|
||||
|
||||
#include "hdr/types/ssize_t.h"
|
||||
#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/error_or.h"
|
||||
#include "src/__support/macros/config.h"
|
||||
#include <sys/syscall.h> // For syscall numbers
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace linux_syscalls {
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
namespace linux_syscalls {
|
||||
LIBC_INLINE ErrorOr<ssize_t> read(int fd, void *buf, size_t count) {
|
||||
return syscall_checked<ssize_t>(SYS_read, fd, buf, count);
|
||||
}
|
||||
|
||||
LIBC_INLINE ErrorOr<ssize_t> read(int fd, void *buf, size_t count) {
|
||||
return syscall_checked<ssize_t>(SYS_read, fd, buf, count);
|
||||
}
|
||||
} // namespace linux_syscalls
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
```
|
||||
|
||||
} // namespace linux_syscalls
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
How to Migrate
|
||||
==============
|
||||
## How to Migrate
|
||||
|
||||
1. **Cleanup Existing Implementation**: If the syscall was previously
|
||||
implemented in ``OSUtil/linux/fcntl.cpp`` (or similar), remove the old
|
||||
implemented in `OSUtil/linux/fcntl.cpp` (or similar), remove the old
|
||||
implementation to replace it with the new wrapper.
|
||||
|
||||
2. **Create the Wrapper**: Add a new header file in
|
||||
``src/__support/OSUtil/linux/syscall_wrappers/``.
|
||||
3. **Update CMake**: Add a ``add_header_library`` target for the new wrapper in
|
||||
``src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt``.
|
||||
`src/__support/OSUtil/linux/syscall_wrappers/`.
|
||||
|
||||
3. **Update CMake**: Add a `add_header_library` target for the new wrapper in
|
||||
`src/__support/OSUtil/linux/syscall_wrappers/CMakeLists.txt`.
|
||||
|
||||
4. **Refactor Entrypoints**:
|
||||
|
||||
* Include the new wrapper header (e.g., ``read.h``).
|
||||
* Replace direct ``syscall_impl`` calls with
|
||||
``linux_syscalls::<function_name>``.
|
||||
* Update the entrypoint's ``DEPENDS`` in ``CMakeLists.txt`` to include the
|
||||
- Include the new wrapper header (e.g., `read.h`).
|
||||
- Replace direct `syscall_impl` calls with
|
||||
`linux_syscalls::<function_name>`.
|
||||
- Update the entrypoint's `DEPENDS` in `CMakeLists.txt` to include the
|
||||
new wrapper target.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
.. _undefined_behavior:
|
||||
(undefined_behavior)=
|
||||
|
||||
===========================
|
||||
Defining Undefined Behavior
|
||||
===========================
|
||||
# Defining Undefined Behavior
|
||||
|
||||
The C standard leaves behavior undefined or implementation defined in many
|
||||
places. Undefined behavior is behavior that the standards leave up to the
|
||||
|
|
@ -11,111 +9,109 @@ input, including inputs for which the result is undefined. This page provides
|
|||
examples of how these situations are handled in existing code, followed by
|
||||
guidelines to help determine the right approach for new situations.
|
||||
|
||||
Guidelines
|
||||
==========
|
||||
## Guidelines
|
||||
|
||||
Most undefined behavior is outside the scope of normal use. Follow these
|
||||
guidelines and the resulting code should behave predictably even in unexpected
|
||||
situations.
|
||||
|
||||
#. Follow the standards.
|
||||
#. If there is no standard, first ask yourself if this implementation is necessary (are there users who need this functionality?). If it truly is, then match existing implementations. Creating competing designs just causes confusion (see the history of qsort_r).
|
||||
#. Avoid giving an incorrect answer.
|
||||
#. In general, correct answer > correct answer (wrong format) > no answer > crash the program >>>>>>> incorrect answer.
|
||||
#. The C library is called frequently in performance critical situations, and so can't afford to do thorough error checking and correction.
|
||||
#. It also cannot give the incorrect answer for any reasonable input, since it is so foundational.
|
||||
#. This leaves crashing or address space corruption as a probable option for a libc function in an ambiguous state.
|
||||
#. Don't overcomplicate undefined situations.
|
||||
#. It's better to have a slightly confusing result for an undefined input than 100 extra lines of code that are never used for a well defined input.
|
||||
#. LLVM's libc is also used for embedded systems that care a lot about code size.
|
||||
#. Unreasonable inputs can have unreasonable outputs.
|
||||
#. Match other implementations when it makes sense.
|
||||
#. Every libc has to make these choices, and sometimes others have already found the right choice.
|
||||
#. Be careful, just because there is a consensus doesn't make that consensus right.
|
||||
#. LLVM's libc should be consistent with itself.
|
||||
#. Similar inputs to the same function should yield similar results, even when the inputs are undefined.
|
||||
#. The same input to similar functions should also yield similar results.
|
||||
#. The same input to the same function on different platforms should yield the same result, unless there's a specific reason not to (e.g. 64 bit long vs 32 bit long).
|
||||
#. Write down the decision.
|
||||
#. Every libc has to make a decision on how to handle undefined inputs. Users should be able to find what LLVM's libc does.
|
||||
#. While users shouldn't rely on undefined behavior, it shouldn't surprise them.
|
||||
1. Follow the standards.
|
||||
1. If there is no standard, first ask yourself if this implementation is necessary (are there users who need this functionality?). If it truly is, then match existing implementations. Creating competing designs just causes confusion (see the history of qsort_r).
|
||||
2. Avoid giving an incorrect answer.
|
||||
1. In general, correct answer > correct answer (wrong format) > no answer > crash the program >>>>>>> incorrect answer.
|
||||
2. The C library is called frequently in performance critical situations, and so can't afford to do thorough error checking and correction.
|
||||
3. It also cannot give the incorrect answer for any reasonable input, since it is so foundational.
|
||||
4. This leaves crashing or address space corruption as a probable option for a libc function in an ambiguous state.
|
||||
3. Don't overcomplicate undefined situations.
|
||||
1. It's better to have a slightly confusing result for an undefined input than 100 extra lines of code that are never used for a well defined input.
|
||||
2. LLVM's libc is also used for embedded systems that care a lot about code size.
|
||||
3. Unreasonable inputs can have unreasonable outputs.
|
||||
4. Match other implementations when it makes sense.
|
||||
1. Every libc has to make these choices, and sometimes others have already found the right choice.
|
||||
2. Be careful, just because there is a consensus doesn't make that consensus right.
|
||||
5. LLVM's libc should be consistent with itself.
|
||||
1. Similar inputs to the same function should yield similar results, even when the inputs are undefined.
|
||||
2. The same input to similar functions should also yield similar results.
|
||||
3. The same input to the same function on different platforms should yield the same result, unless there's a specific reason not to (e.g. 64 bit long vs 32 bit long).
|
||||
6. Write down the decision.
|
||||
1. Every libc has to make a decision on how to handle undefined inputs. Users should be able to find what LLVM's libc does.
|
||||
2. While users shouldn't rely on undefined behavior, it shouldn't surprise them.
|
||||
|
||||
Approaches
|
||||
==========
|
||||
## Approaches
|
||||
|
||||
### Matching Behavior Against Existing Implementations
|
||||
|
||||
Matching Behavior Against Existing Implementations
|
||||
--------------------------------------------------
|
||||
Existing implementations have already chosen how to handle undefined situations, and sometimes there are benefits to matching those decisions, such as in the case of atoi. The C Standard defines atoi as being equivalent to a call to strtol, with the result cast from long to int. The standard also clarifies that any input that cannot be represented as an int causes undefined behavior. For the strtol function, the standard instead defines inputs that cannot be represented in a long int as returning LONG_MAX or LONG_MIN, according to their sign. The decision of whether to cast the result from strtol or to handle integer overflow like strtol does is left to the implementation. LLVM's libc performs the raw cast, since the atoi function is fuzz tested against the implementation from glibc. By matching a known good implementation, LLVM's libc can more effectively be checked for correctness in this case.
|
||||
|
||||
Simplifying Handling Invalid Inputs
|
||||
-----------------------------------
|
||||
### Simplifying Handling Invalid Inputs
|
||||
|
||||
When handling invalid inputs, the output should be simple to code, and simple for the user to understand. An example of this is how the printf function handles invalid conversion specifiers. A conversion specifier is a segment of the format string that starts with a %. At the end of a conversion specifier is the character that determines the behavior for the conversion, called the conversion name. As an example, the conversion specifier %d has the conversion name of d which represents an integer conversion. If the conversion name is instead an invalid character such as ? then the behavior is undefined. When passed an invalid conversion specifier like %? LLVM's libc defines the output as the raw text of the conversion specifier. This simplifies the algorithm and makes the result obvious and predictable for the user.
|
||||
|
||||
Conforming to Existing Practice
|
||||
-------------------------------
|
||||
### Conforming to Existing Practice
|
||||
|
||||
There are some behaviors that are technically undefined, but are otherwise consistent across implementations, such as how printf handles length modifiers on inappropriate conversions. For each conversion name there is a list of length modifiers that can apply to it. If a length modifier is applied to a conversion specifier that it doesn't apply to, then the behavior is undefined. For most conversions, LLVM's libc ignores any length modifier that doesn't apply. As an example, a conversion of %hf would be read as an f float conversion with the h length modifier. The h length modifier doesn't apply to floating point conversions and so %hf is the same as %f. There is one exception, which is the L length modifier on integer conversions. Many libcs handle the L length modifier like the ll length modifier when applied to integer conversions, despite L only applying to float conversions in the standard. LLVM's libc follows this convention because it is a useful feature that is simple to implement and has a predictable outcome for the user.
|
||||
|
||||
Interpreting the Standard's Reasoning
|
||||
-------------------------------------
|
||||
Often the standard will imply an intended behavior through what it states is undefined, such as in the case of printf's handling of the %% conversion. The %% conversion is used to write a % character, since it's used as the start of a conversion specifier. The standard specifies that %% must be the complete conversion specifier, and any options would make the conversion undefined. The conversion specifier %10% can therefore be interpreted as a % conversion with a width of 10, but the standard implies that this is not necessary. By making the options undefined, the standard implies a desired behavior for %% with options. The implied behavior is to ignore all options and always print %. This still leaves the behavior of %*% ambiguous, since the star normally consumes an argument to be used as the width. Since % conversions ignore the width, it would be reasonable to not read the argument in this case, but it would add additional complexity to the parsing logic. For that reason, the implementation in LLVM's libc will consume an argument for %*%, although the value is ignored. Adding additional logic for unreasonable edge cases, such as this one, is unnecessary.
|
||||
### Interpreting the Standard's Reasoning
|
||||
|
||||
Often the standard will imply an intended behavior through what it states is undefined, such as in the case of printf's handling of the %% conversion. The %% conversion is used to write a % character, since it's used as the start of a conversion specifier. The standard specifies that %% must be the complete conversion specifier, and any options would make the conversion undefined. The conversion specifier %10% can therefore be interpreted as a % conversion with a width of 10, but the standard implies that this is not necessary. By making the options undefined, the standard implies a desired behavior for %% with options. The implied behavior is to ignore all options and always print %. This still leaves the behavior of `%*%` ambiguous, since the star normally consumes an argument to be used as the width. Since % conversions ignore the width, it would be reasonable to not read the argument in this case, but it would add additional complexity to the parsing logic. For that reason, the implementation in LLVM's libc will consume an argument for `%*%`, although the value is ignored. Adding additional logic for unreasonable edge cases, such as this one, is unnecessary.
|
||||
|
||||
### Ignoring Bug-For-Bug Compatibility
|
||||
|
||||
Ignoring Bug-For-Bug Compatibility
|
||||
----------------------------------
|
||||
Any long running implementations will have bugs and deviations from the standard. Hyrum's Law states that “all observable behaviors of your system will be depended on by somebody” which includes these bugs. An example of a long-standing bug is glibc's scanf float parsing behavior. The behavior is specifically defined in the standard, but it isn't adhered to by all libc implementations. There is a longstanding bug in glibc where it incorrectly parses the string 100er and this caused the C standard to add that specific example to the definition for scanf. The intended behavior is for scanf, when parsing a float, to parse the longest possibly valid prefix and then accept it if and only if that complete parsed value is a float. In the case of 100er the longest possibly valid prefix is 100e but the float parsed from that string is only 100. Since there is no number after the e it shouldn't be included in the float, so scanf should return a parsing error. For LLVM's libc it was decided to follow the standard, even though glibc's version is slightly simpler to implement and this edge case is rare. Following the standard must be the first priority, since that's the goal of the library. If there is no standard, then matching another implementation (even bug-for-bug) may be necessary, but before you implement an unstandardized function first consider if anyone will actually use it at all.
|
||||
|
||||
Design Decisions
|
||||
================
|
||||
## Design Decisions
|
||||
|
||||
### Resizable Tables for hsearch
|
||||
|
||||
Resizable Tables for hsearch
|
||||
----------------------------
|
||||
The POSIX.1 standard does not delineate the behavior consequent to invoking hsearch or hdestroy without prior initialization of the hash table via hcreate. Furthermore, the standard does not specify the outcomes of successive invocations of hsearch absent intervening hdestroy calls. Libraries such as MUSL and Glibc do not apply checks to these scenarios, potentially leading to memory corruption or leakage. Conversely, FreeBSD's libc and Bionic automatically initialize the hash table to a minimal size if it is found uninitialized, and proceeding to destroy the table only if initialization has occurred. This approach also avoids redundant table allocation if an initialized hash table is already present. Given that the hash table starts with a minimal size, resizing becomes necessary to accommodate additional user insertions. LLVM's libc mirrors the approach of FreeBSD's libc and Bionic, owing to its enhanced robustness and user-friendliness. Notably, such resizing behavior itself aligns with POSIX.1 standards, which explicitly permit implementations to modify the capacity of the hash table.
|
||||
|
||||
Path without Leading Slashs in shm_open
|
||||
----------------------------------------
|
||||
### Path without Leading Slashs in shm_open
|
||||
|
||||
POSIX.1 leaves that when the name of a shared memory object does not begin with a slash, the behavior is implementation defined. In such cases, the shm_open in LLVM libc is implemented to behave as if the name began with a slash.
|
||||
|
||||
Handling of NULL arguments to the 's' and 'n' format specifiers
|
||||
---------------------------------------------------------------
|
||||
The C standard does not specify behavior for ``printf("%s", NULL)`` or
|
||||
``printf("%n", NULL)``. For LLVM-libc, see
|
||||
:ref:`LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS <printf_no_nullptr_checks>` for details.
|
||||
### Handling of NULL arguments to the 's' and 'n' format specifiers
|
||||
|
||||
Unknown Math Rounding Direction
|
||||
-------------------------------
|
||||
The C23 standard states that if the value of the ``rnd`` argument of the
|
||||
``fromfp``, ``ufromfp``, ``fromfpx`` and ``ufromfpx`` functions is not equal to
|
||||
The C standard does not specify behavior for `printf("%s", NULL)` or
|
||||
`printf("%n", NULL)`. For LLVM-libc, see
|
||||
{ref}`LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS <printf_no_nullptr_checks>` for details.
|
||||
|
||||
### Unknown Math Rounding Direction
|
||||
|
||||
The C23 standard states that if the value of the `rnd` argument of the
|
||||
`fromfp`, `ufromfp`, `fromfpx` and `ufromfpx` functions is not equal to
|
||||
the value of a math rounding direction macro, the direction of rounding is
|
||||
unspecified. LLVM's libc chooses to use the ``FP_INT_TONEAREST`` rounding
|
||||
unspecified. LLVM's libc chooses to use the `FP_INT_TONEAREST` rounding
|
||||
direction in this case.
|
||||
|
||||
Non-const Constant Return Values
|
||||
--------------------------------
|
||||
Some libc functions, like ``dlerror()``, return ``char *`` instead of ``const char *`` and then tell the caller they promise not to modify this value. Any modification of this value is undefined behavior.
|
||||
### Non-const Constant Return Values
|
||||
|
||||
Unrecognized ``clockid_t`` values for ``pthread_rwlock_clock*`` APIs
|
||||
----------------------------------------------------------------------
|
||||
POSIX.1-2024 only demands support for ``CLOCK_REALTIME`` and ``CLOCK_MONOTONIC``. Currently,
|
||||
Some libc functions, like `dlerror()`, return `char *` instead of `const char *` and then tell the caller they promise not to modify this value. Any modification of this value is undefined behavior.
|
||||
|
||||
### Unrecognized `clockid_t` values for `pthread_rwlock_clock*` APIs
|
||||
|
||||
POSIX.1-2024 only demands support for `CLOCK_REALTIME` and `CLOCK_MONOTONIC`. Currently,
|
||||
as in LLVM libc, if other clock ids are used, they will be treated as monotonic clocks.
|
||||
|
||||
Invalid condition variable attributes for ``pthread_cond_init``
|
||||
---------------------------------------------------------------
|
||||
POSIX.1-2024 specifies that ``pthread_cond_init`` returns an error number on
|
||||
failure, but it does not specify the behavior when the provided
|
||||
``pthread_condattr_t`` contains an unsupported clock value or an unrecognized
|
||||
process-shared flag. LLVM's libc returns ``EINVAL`` for unsupported clock values
|
||||
and for process-shared flags other than ``PTHREAD_PROCESS_PRIVATE`` and
|
||||
``PTHREAD_PROCESS_SHARED``. This returns the error number directly and does not
|
||||
set ``errno``.
|
||||
### Invalid condition variable attributes for `pthread_cond_init`
|
||||
|
||||
POSIX.1-2024 specifies that `pthread_cond_init` returns an error number on
|
||||
failure, but it does not specify the behavior when the provided
|
||||
`pthread_condattr_t` contains an unsupported clock value or an unrecognized
|
||||
process-shared flag. LLVM's libc returns `EINVAL` for unsupported clock values
|
||||
and for process-shared flags other than `PTHREAD_PROCESS_PRIVATE` and
|
||||
`PTHREAD_PROCESS_SHARED`. This returns the error number directly and does not
|
||||
set `errno`.
|
||||
|
||||
### PThread SpinLock Destroy
|
||||
|
||||
PThread SpinLock Destroy
|
||||
------------------------
|
||||
POSIX.1 Issue 7 updates the spinlock destroy behavior description such that the return code for
|
||||
uninitialized spinlock and invalid spinlock is left undefined. We follow the recommendation as in
|
||||
POSIX.1-2024, where EINVAL is returned if the spinlock is invalid (here we only check for null pointers) or
|
||||
EBUSY is returned if the spinlock is currently locked. The lock is poisoned after a successful destroy. That is,
|
||||
subsequent operations on the lock object without any reinitialization will return EINVAL.
|
||||
|
||||
Strftime
|
||||
--------
|
||||
### Strftime
|
||||
|
||||
In the C Standard, it provides a list of modifiers, and the conversions these
|
||||
are valid on. It also says that a modifier on an unspecified conversion is
|
||||
undefined. For LLVM-libc, the conversion is treated as if the modifier isn't
|
||||
|
|
@ -151,8 +147,8 @@ Any conversion with a minimum width is padded with the padding character until i
|
|||
Modifiers are applied, then the result is padded if necessary.
|
||||
Any composite conversion will pass along all flags to the component conversions.
|
||||
|
||||
a64l and l64a
|
||||
-------------
|
||||
### a64l and l64a
|
||||
|
||||
These functions convert to and from a posix-specified base64 encoding. There are
|
||||
a few cases left undefined. For a64l, the behavior is undefined if the input
|
||||
pointer (s) is a null pointer. For LLVM-libc this will cause a null pointer
|
||||
|
|
@ -163,39 +159,39 @@ negative. For LLVM-libc, all inputs to l64a are treated as unsigned 32 bit ints.
|
|||
Additionally, the return of l64a is in a thread-local buffer that's overwritten
|
||||
on each call.
|
||||
|
||||
`inet_aton` and Non-Standard Binary Integers
|
||||
--------------------------------------------
|
||||
### `inet_aton` and Non-Standard Binary Integers
|
||||
|
||||
The current implementation of the `inet_aton` function utilizes the same code
|
||||
as `strtol` to parse IPv4 numbers-and-dots notations. This approach may permit
|
||||
the use of binary integers (prefixed with 0b), which is not supported by the
|
||||
standard.
|
||||
|
||||
`tdelete` on Non-existent Key
|
||||
------------------------------
|
||||
### `tdelete` on Non-existent Key
|
||||
|
||||
The return value of `tdelete` is unspecified if the key is not found in the tree.
|
||||
For LLVM-libc, `tdelete` returns bit-casted `uintptr_t`'s maximum value.
|
||||
|
||||
`twalk/twalk_r/tdestroy` with Null Function Pointer
|
||||
------------------------------------------------------
|
||||
The standard requires that ``twalk``, ``twalk_r``, and ``tdestroy``
|
||||
### `twalk/twalk_r/tdestroy` with Null Function Pointer
|
||||
|
||||
The standard requires that `twalk`, `twalk_r`, and `tdestroy`
|
||||
to be used with a valid function pointer. LLVM-libc follows the behavior of
|
||||
configured via the `LIBC_ADD_NULL_CHECKS` option.
|
||||
|
||||
Invalid Thread Joining Behavior
|
||||
------------------------------------------------------
|
||||
### Invalid Thread Joining Behavior
|
||||
|
||||
POSIX standard does not demand accurate deadlock detection and leaves
|
||||
repeated/concurrent joining as undefined behavior. In the following,
|
||||
repeated/concurrent joining as undefined behavior. In the following,
|
||||
we discuss the related behaviors explicitly.
|
||||
|
||||
Self joining is always rejected with ``EDEADLK``.
|
||||
Self joining is always rejected with `EDEADLK`.
|
||||
|
||||
At least one of the two threads in a mutual joining will detect the deadlock and
|
||||
return ``EDEADLK``. If joining requester gets ``EDEADLK``, the joining target is
|
||||
return `EDEADLK`. If joining requester gets `EDEADLK`, the joining target is
|
||||
recovered to joinable state. However, the joining target may already be waiting
|
||||
if it does not see ``EDEADLK``.
|
||||
if it does not see `EDEADLK`.
|
||||
|
||||
Cyclic joining with more than two threads is not detected.
|
||||
|
||||
Concurrent and repeated joinings on the same thread are faulty behaviors, because
|
||||
target thread's TLS may already be torn down. ``EINVAL`` may be returned if
|
||||
target thread's TLS may already be torn down. `EINVAL` may be returned if
|
||||
multiple joinings occur on the same thread but it is not guaranteed to observe.
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
.. _full_cross_build:
|
||||
(full_cross_build)=
|
||||
|
||||
================
|
||||
Full Cross Build
|
||||
================
|
||||
# Full Cross Build
|
||||
|
||||
.. note::
|
||||
Fullbuild requires running headergen, which is a python program that depends on
|
||||
pyyaml. The minimum versions are listed on the :ref:`header_generation`
|
||||
page, as well as additional information.
|
||||
:::{note}
|
||||
Fullbuild requires running headergen, which is a python program that depends on
|
||||
pyyaml. The minimum versions are listed on the {ref}`header_generation`
|
||||
page, as well as additional information.
|
||||
:::
|
||||
|
||||
In this document, we will present recipes to cross build the full libc. When we
|
||||
say *cross build* a full libc, we mean that we will build the full libc for a
|
||||
|
|
@ -19,21 +18,20 @@ There are two main recipes to cross build the full libc. Each one serves a
|
|||
different use case. Below is a short description of these recipes to help users
|
||||
pick the recipe that best suites their needs and contexts.
|
||||
|
||||
* **Standalone cross build** - Using this recipe one can build the libc using a
|
||||
- **Standalone cross build** - Using this recipe one can build the libc using a
|
||||
compiler of their choice. One should use this recipe if their compiler can
|
||||
build for the host as well as the target.
|
||||
* **Bootstrap cross build** - In this recipe, one will build the ``clang``
|
||||
- **Bootstrap cross build** - In this recipe, one will build the `clang`
|
||||
compiler and the libc build tools for the host first, and then use them to
|
||||
build the libc for the target. Unlike with the standalone build recipe, the
|
||||
user does not have explicitly build ``clang`` and other build tools.
|
||||
user does not have explicitly build `clang` and other build tools.
|
||||
They get built automatically before building the libc. One should use this
|
||||
recipe if they intend use the built ``clang`` and the libc as part of their
|
||||
recipe if they intend use the built `clang` and the libc as part of their
|
||||
toolchain for the target.
|
||||
|
||||
The following sections present the two recipes in detail.
|
||||
|
||||
Standalone cross build
|
||||
======================
|
||||
## Standalone cross build
|
||||
|
||||
In the *standalone crossbuild* recipe, the system compiler or a custom compiler
|
||||
of user's choice is used to build the libc. The necessary build tools for the
|
||||
|
|
@ -43,199 +41,191 @@ to explicitly build the build tools first and then build the libc. A point to
|
|||
keep in mind is that the compiler used should be capable of building for the
|
||||
host as well as the target.
|
||||
|
||||
.. note::
|
||||
Even though the LLVM libc provides its own complete C library implementation,
|
||||
compiling it for a Linux target still requires the Linux kernel API headers for
|
||||
that architecture. On Debian-based systems, these and other standard cross-compilation
|
||||
runtimes (like ``libgcc``) can be installed via packages like
|
||||
``gcc-riscv64-linux-gnu`` and ``linux-libc-dev-riscv64-cross`` (or similar for
|
||||
other architectures). You will need to point CMake to the kernel headers using
|
||||
``-DLIBC_KERNEL_HEADERS`` (e.g.,
|
||||
``-DLIBC_KERNEL_HEADERS=/usr/riscv64-linux-gnu/include``) so the libc build
|
||||
can find headers like ``asm/unistd.h``.
|
||||
:::{note}
|
||||
Even though the LLVM libc provides its own complete C library implementation,
|
||||
compiling it for a Linux target still requires the Linux kernel API headers for
|
||||
that architecture. On Debian-based systems, these and other standard cross-compilation
|
||||
runtimes (like `libgcc`) can be installed via packages like
|
||||
`gcc-riscv64-linux-gnu` and `linux-libc-dev-riscv64-cross` (or similar for
|
||||
other architectures). You will need to point CMake to the kernel headers using
|
||||
`-DLIBC_KERNEL_HEADERS` (e.g.,
|
||||
`-DLIBC_KERNEL_HEADERS=/usr/riscv64-linux-gnu/include`) so the libc build
|
||||
can find headers like `asm/unistd.h`.
|
||||
:::
|
||||
|
||||
CMake configure step
|
||||
--------------------
|
||||
### CMake configure step
|
||||
|
||||
First, set up the environment variables for your compiler and target:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
C_COMPILER=clang
|
||||
CXX_COMPILER=clang++
|
||||
TARGET_TRIPLE=aarch64-linux-gnu
|
||||
```sh
|
||||
C_COMPILER=clang
|
||||
CXX_COMPILER=clang++
|
||||
TARGET_TRIPLE=aarch64-linux-gnu
|
||||
```
|
||||
|
||||
Below is the CMake command to configure the standalone crossbuild of the libc.
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
cmake \
|
||||
-B build \
|
||||
-S runtimes \
|
||||
-G Ninja \
|
||||
-DLLVM_ENABLE_RUNTIMES=libc \
|
||||
-DCMAKE_C_COMPILER=$C_COMPILER \
|
||||
-DCMAKE_CXX_COMPILER=$CXX_COMPILER \
|
||||
-DCMAKE_C_COMPILER_TARGET=$TARGET_TRIPLE \
|
||||
-DCMAKE_CXX_COMPILER_TARGET=$TARGET_TRIPLE \
|
||||
-DLLVM_LIBC_FULL_BUILD=ON \
|
||||
-DLIBC_TARGET_TRIPLE=$TARGET_TRIPLE \
|
||||
-DCMAKE_BUILD_TYPE=<Release|Debug>
|
||||
```
|
||||
|
||||
cmake \
|
||||
-B build \
|
||||
-S runtimes \
|
||||
-G Ninja \
|
||||
-DLLVM_ENABLE_RUNTIMES=libc \
|
||||
-DCMAKE_C_COMPILER=$C_COMPILER \
|
||||
-DCMAKE_CXX_COMPILER=$CXX_COMPILER \
|
||||
-DCMAKE_C_COMPILER_TARGET=$TARGET_TRIPLE \
|
||||
-DCMAKE_CXX_COMPILER_TARGET=$TARGET_TRIPLE \
|
||||
-DLLVM_LIBC_FULL_BUILD=ON \
|
||||
-DLIBC_TARGET_TRIPLE=$TARGET_TRIPLE \
|
||||
-DCMAKE_BUILD_TYPE=<Release|Debug>
|
||||
We will go over the special options passed to the `cmake` command above.
|
||||
|
||||
We will go over the special options passed to the ``cmake`` command above.
|
||||
|
||||
* **Enabled Runtimes** - Since we want to build LLVM-libc, we list
|
||||
``libc`` as the enabled runtime.
|
||||
* **The full build option** - Since we want to build the full libc, we pass
|
||||
``-DLLVM_LIBC_FULL_BUILD=ON``.
|
||||
* **The target triple** - This is the target triple of the target for which
|
||||
- **Enabled Runtimes** - Since we want to build LLVM-libc, we list
|
||||
`libc` as the enabled runtime.
|
||||
- **The full build option** - Since we want to build the full libc, we pass
|
||||
`-DLLVM_LIBC_FULL_BUILD=ON`.
|
||||
- **The target triple** - This is the target triple of the target for which
|
||||
we are building the libc. For example, for a Linux 32-bit Arm target,
|
||||
one can specify it as ``arm-linux-eabi``.
|
||||
one can specify it as `arm-linux-eabi`.
|
||||
|
||||
Build step
|
||||
----------
|
||||
### Build step
|
||||
|
||||
After configuring the build with the above ``cmake`` command, one can build the
|
||||
After configuring the build with the above `cmake` command, one can build the
|
||||
the libc for the target with the following command:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
ninja -C build libc libm
|
||||
```
|
||||
|
||||
ninja -C build libc libm
|
||||
|
||||
The above ``ninja`` command will build the libc static archives ``libc.a`` and
|
||||
``libm.a`` for the target specified with ``-DLIBC_TARGET_TRIPLE`` in the CMake
|
||||
The above `ninja` command will build the libc static archives `libc.a` and
|
||||
`libm.a` for the target specified with `-DLIBC_TARGET_TRIPLE` in the CMake
|
||||
configure step.
|
||||
|
||||
Bootstrap cross build
|
||||
=====================
|
||||
## Bootstrap cross build
|
||||
|
||||
In this recipe, the clang compiler is built automatically before building
|
||||
the libc for the target.
|
||||
|
||||
CMake configure step
|
||||
--------------------
|
||||
### CMake configure step
|
||||
|
||||
First, set up the environment variables for your compiler and target:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
C_COMPILER=clang
|
||||
CXX_COMPILER=clang++
|
||||
TARGET_TRIPLE=aarch64-linux-gnu
|
||||
```sh
|
||||
C_COMPILER=clang
|
||||
CXX_COMPILER=clang++
|
||||
TARGET_TRIPLE=aarch64-linux-gnu
|
||||
```
|
||||
|
||||
Then, configure the CMake build for the bootstrap build:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
cmake \
|
||||
-B build \
|
||||
-S llvm \
|
||||
-G Ninja \
|
||||
-DCMAKE_C_COMPILER=$C_COMPILER \
|
||||
-DCMAKE_CXX_COMPILER=$CXX_COMPILER \
|
||||
-DLLVM_ENABLE_PROJECTS=clang \
|
||||
-DLLVM_ENABLE_RUNTIMES=libc \
|
||||
-DLLVM_LIBC_FULL_BUILD=ON \
|
||||
-DLLVM_RUNTIME_TARGETS=$TARGET_TRIPLE \
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
```sh
|
||||
cmake \
|
||||
-B build \
|
||||
-S llvm \
|
||||
-G Ninja \
|
||||
-DCMAKE_C_COMPILER=$C_COMPILER \
|
||||
-DCMAKE_CXX_COMPILER=$CXX_COMPILER \
|
||||
-DLLVM_ENABLE_PROJECTS=clang \
|
||||
-DLLVM_ENABLE_RUNTIMES=libc \
|
||||
-DLLVM_LIBC_FULL_BUILD=ON \
|
||||
-DLLVM_RUNTIME_TARGETS=$TARGET_TRIPLE \
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
```
|
||||
|
||||
Note how the above cmake command differs from the one used in the other recipe:
|
||||
|
||||
* ``clang`` is listed in ``-DLLVM_ENABLE_PROJECTS`` and ``libc`` is
|
||||
listed in ``-DLLVM_ENABLE_RUNTIMES``.
|
||||
* The CMake root source directory is ``llvm-project/llvm``.
|
||||
* The target triple is specified with ``-DLLVM_RUNTIME_TARGETS``.
|
||||
- `clang` is listed in `-DLLVM_ENABLE_PROJECTS` and `libc` is
|
||||
listed in `-DLLVM_ENABLE_RUNTIMES`.
|
||||
- The CMake root source directory is `llvm-project/llvm`.
|
||||
- The target triple is specified with `-DLLVM_RUNTIME_TARGETS`.
|
||||
|
||||
Build step
|
||||
----------
|
||||
### Build step
|
||||
|
||||
The build step is similar to the other recipe:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
ninja -C build libc
|
||||
```sh
|
||||
ninja -C build libc
|
||||
```
|
||||
|
||||
The above ninja command should build the libc static archives for the target
|
||||
specified with ``-DLLVM_RUNTIME_TARGETS``.
|
||||
specified with `-DLLVM_RUNTIME_TARGETS`.
|
||||
|
||||
Building for bare metal
|
||||
=======================
|
||||
## Building for bare metal
|
||||
|
||||
To build for bare metal, all one has to do is to specify the
|
||||
`system <https://clang.llvm.org/docs/CrossCompilation.html#target-triple>`_
|
||||
component of the target triple as ``none``. For example, to build for a
|
||||
[system](https://clang.llvm.org/docs/CrossCompilation.html#target-triple)
|
||||
component of the target triple as `none`. For example, to build for a
|
||||
32-bit arm target on bare metal, one can use a target triple like
|
||||
``arm-none-eabi``. Other than that, the libc for a bare metal target can be
|
||||
`arm-none-eabi`. Other than that, the libc for a bare metal target can be
|
||||
built using any of the three recipes described above.
|
||||
|
||||
Building for the GPU
|
||||
====================
|
||||
## Building for the GPU
|
||||
|
||||
To build for a GPU architecture, it should only be necessary to specify the
|
||||
target triple as one of the supported GPU targets. Currently, this is either
|
||||
``nvptx64-nvidia-cuda`` for NVIDIA GPUs or ``amdgcn-amd-amdhsa`` for AMD GPUs.
|
||||
More detailed information is provided in the :ref:`GPU
|
||||
documentation<libc_gpu_building>`.
|
||||
`nvptx64-nvidia-cuda` for NVIDIA GPUs or `amdgcn-amd-amdhsa` for AMD GPUs.
|
||||
More detailed information is provided in the {ref}`GPU
|
||||
documentation <libc_gpu_building>`.
|
||||
|
||||
Building and Testing with an Emulator
|
||||
=====================================
|
||||
## Building and Testing with an Emulator
|
||||
|
||||
If you are cross-compiling the libc for a different architecture, you can use an emulator
|
||||
such as QEMU to run the tests. For instance, to cross-compile for ``riscv64`` and run tests
|
||||
using ``qemu-riscv64``, you can use the standalone cross build recipe with a few additional CMake flags.
|
||||
such as QEMU to run the tests. For instance, to cross-compile for `riscv64` and run tests
|
||||
using `qemu-riscv64`, you can use the standalone cross build recipe with a few additional CMake flags.
|
||||
|
||||
CMake configure step
|
||||
--------------------
|
||||
### CMake configure step
|
||||
|
||||
Assuming your system compiler (e.g., ``clang++``) supports the RISC-V target,
|
||||
Assuming your system compiler (e.g., `clang++`) supports the RISC-V target,
|
||||
you can configure the build as follows:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
cmake \
|
||||
-B build \
|
||||
-S runtimes \
|
||||
-G Ninja \
|
||||
-DLLVM_ENABLE_RUNTIMES=libc \
|
||||
-DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_C_COMPILER_TARGET=riscv64-linux-gnu \
|
||||
-DCMAKE_CXX_COMPILER_TARGET=riscv64-linux-gnu \
|
||||
-DLLVM_LIBC_FULL_BUILD=ON \
|
||||
-DLIBC_TARGET_TRIPLE=riscv64-linux-gnu \
|
||||
-DLIBC_KERNEL_HEADERS=/usr/riscv64-linux-gnu/include \
|
||||
-DCMAKE_CROSSCOMPILING_EMULATOR=qemu-riscv64 \
|
||||
-DLLVM_ENABLE_LLD=ON \
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
```sh
|
||||
cmake \
|
||||
-B build \
|
||||
-S runtimes \
|
||||
-G Ninja \
|
||||
-DLLVM_ENABLE_RUNTIMES=libc \
|
||||
-DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_C_COMPILER_TARGET=riscv64-linux-gnu \
|
||||
-DCMAKE_CXX_COMPILER_TARGET=riscv64-linux-gnu \
|
||||
-DLLVM_LIBC_FULL_BUILD=ON \
|
||||
-DLIBC_TARGET_TRIPLE=riscv64-linux-gnu \
|
||||
-DLIBC_KERNEL_HEADERS=/usr/riscv64-linux-gnu/include \
|
||||
-DCMAKE_CROSSCOMPILING_EMULATOR=qemu-riscv64 \
|
||||
-DLLVM_ENABLE_LLD=ON \
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
```
|
||||
|
||||
The notable additions are:
|
||||
|
||||
* **The compiler target** - We set ``-DCMAKE_C_COMPILER_TARGET=riscv64-linux-gnu`` and ``-DCMAKE_CXX_COMPILER_TARGET=riscv64-linux-gnu`` to tell CMake to pass the correct ``--target`` flags to ``clang`` so that it cross-compiles rather than building for the host.
|
||||
* **The target triple** - We set ``-DLIBC_TARGET_TRIPLE=riscv64-linux-gnu``
|
||||
* **The kernel headers** - We set ``-DLIBC_KERNEL_HEADERS=/usr/riscv64-linux-gnu/include``
|
||||
to point to the target's Linux API headers (e.g. for ``asm/unistd.h``).
|
||||
* **The cross-compiling emulator** - We set ``-DCMAKE_CROSSCOMPILING_EMULATOR=qemu-riscv64``
|
||||
- **The compiler target** - We set `-DCMAKE_C_COMPILER_TARGET=riscv64-linux-gnu` and `-DCMAKE_CXX_COMPILER_TARGET=riscv64-linux-gnu` to tell CMake to pass the correct `--target` flags to `clang` so that it cross-compiles rather than building for the host.
|
||||
- **The target triple** - We set `-DLIBC_TARGET_TRIPLE=riscv64-linux-gnu`
|
||||
- **The kernel headers** - We set `-DLIBC_KERNEL_HEADERS=/usr/riscv64-linux-gnu/include`
|
||||
to point to the target's Linux API headers (e.g. for `asm/unistd.h`).
|
||||
- **The cross-compiling emulator** - We set `-DCMAKE_CROSSCOMPILING_EMULATOR=qemu-riscv64`
|
||||
to tell CMake how to execute the compiled unittests. Note that this requires that
|
||||
``qemu-riscv64`` is installed and available in your ``$PATH``.
|
||||
* **LLD Linker** - We set ``-DLLVM_ENABLE_LLD=ON`` to ensure the test suite is linked using ``lld``, which is necessary for cross-compilation.
|
||||
`qemu-riscv64` is installed and available in your `$PATH`.
|
||||
- **LLD Linker** - We set `-DLLVM_ENABLE_LLD=ON` to ensure the test suite is linked using `lld`, which is necessary for cross-compilation.
|
||||
|
||||
Build and Test step
|
||||
-------------------
|
||||
### Build and Test step
|
||||
|
||||
You can then build the libc using:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
ninja -C build libc
|
||||
```sh
|
||||
ninja -C build libc
|
||||
```
|
||||
|
||||
To run the tests for the cross-compiled libc, you must use the hermetic test
|
||||
suite, which is entirely self-hosted.
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
ninja -C build libc-hermetic-tests
|
||||
```
|
||||
|
||||
ninja -C build libc-hermetic-tests
|
||||
|
||||
.. note::
|
||||
The standard ``check-libc`` target relies on the target's system C++ and C library
|
||||
headers. Because these tests aren't hermetic, they are not expected to work for
|
||||
a standalone cross-compilation build.
|
||||
:::{note}
|
||||
The standard `check-libc` target relies on the target's system C++ and C library
|
||||
headers. Because these tests aren't hermetic, they are not expected to work for
|
||||
a standalone cross-compilation build.
|
||||
:::
|
||||
|
|
|
|||
|
|
@ -1,200 +1,200 @@
|
|||
.. _full_host_build:
|
||||
(full_host_build)=
|
||||
|
||||
===============
|
||||
Full Host Build
|
||||
===============
|
||||
# Full Host Build
|
||||
|
||||
.. note::
|
||||
Fullbuild requires running headergen, which is a python program that depends on
|
||||
pyyaml. The minimum versions are listed on the :ref:`header_generation`
|
||||
page, as well as additional information.
|
||||
:::{note}
|
||||
Fullbuild requires running headergen, which is a python program that depends on
|
||||
pyyaml. The minimum versions are listed on the {ref}`header_generation`
|
||||
page, as well as additional information.
|
||||
:::
|
||||
|
||||
Standard Building and Testing
|
||||
=============================
|
||||
## Standard Building and Testing
|
||||
|
||||
.. note::
|
||||
If your build fails with an error saying the compiler can't find
|
||||
``<asm/unistd.h>`` or similar then you're probably missing the symlink from
|
||||
``/usr/include/asm`` to ``/usr/include/<HOST TRIPLE>/asm``. Installing the
|
||||
``gcc-multilib`` package creates this symlink, or you can do it manually with
|
||||
this command:
|
||||
``sudo ln -s /usr/include/<HOST TRIPLE>/asm /usr/include/asm``
|
||||
(your host triple will probably be similar to ``x86_64-linux-gnu``)
|
||||
:::{note}
|
||||
If your build fails with an error saying the compiler can't find
|
||||
`<asm/unistd.h>` or similar then you're probably missing the symlink from
|
||||
`/usr/include/asm` to `/usr/include/<HOST TRIPLE>/asm`. Installing the
|
||||
`gcc-multilib` package creates this symlink, or you can do it manually with
|
||||
this command:
|
||||
|
||||
```sh
|
||||
sudo ln -s /usr/include/<HOST TRIPLE>/asm /usr/include/asm
|
||||
```
|
||||
|
||||
(your host triple will probably be similar to `x86_64-linux-gnu`)
|
||||
:::
|
||||
|
||||
For basic development, such as adding new functions or fixing bugs, you can build
|
||||
and test the libc directly without setting up a full sysroot. This approach
|
||||
is using the **runtimes build** (see :ref:`build_concepts` for more information)
|
||||
is using the **runtimes build** (see {ref}`build_concepts` for more information)
|
||||
and is faster and sufficient for most contributors.
|
||||
|
||||
To configure the build, create a build directory and run ``cmake``:
|
||||
To configure the build, create a build directory and run `cmake`:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
cmake \
|
||||
-B build \
|
||||
-S runtimes \
|
||||
-G Ninja \
|
||||
-DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DLLVM_ENABLE_RUNTIMES="libc;compiler-rt" \
|
||||
-DLLVM_LIBC_FULL_BUILD=ON \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DLLVM_LIBC_INCLUDE_SCUDO=ON \
|
||||
-DCOMPILER_RT_BUILD_SCUDO_STANDALONE_WITH_LLVM_LIBC=ON \
|
||||
-DCOMPILER_RT_BUILD_GWP_ASAN=OFF \
|
||||
-DCOMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED=OFF \
|
||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
|
||||
-DLLVM_ENABLE_SPHINX=ON -DLIBC_INCLUDE_DOCS=ON \
|
||||
-DLIBC_CMAKE_VERBOSE_LOGGING=ON
|
||||
```sh
|
||||
cmake \
|
||||
-B build \
|
||||
-S runtimes \
|
||||
-G Ninja \
|
||||
-DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DLLVM_ENABLE_RUNTIMES="libc;compiler-rt" \
|
||||
-DLLVM_LIBC_FULL_BUILD=ON \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DLLVM_LIBC_INCLUDE_SCUDO=ON \
|
||||
-DCOMPILER_RT_BUILD_SCUDO_STANDALONE_WITH_LLVM_LIBC=ON \
|
||||
-DCOMPILER_RT_BUILD_GWP_ASAN=OFF \
|
||||
-DCOMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED=OFF \
|
||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
|
||||
-DLLVM_ENABLE_SPHINX=ON -DLIBC_INCLUDE_DOCS=ON \
|
||||
-DLIBC_CMAKE_VERBOSE_LOGGING=ON
|
||||
```
|
||||
|
||||
After configuring the build, you can build the libc, math library, and run the
|
||||
tests with the following command:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
ninja -C build libc libm check-libc
|
||||
```sh
|
||||
ninja -C build libc libm check-libc
|
||||
```
|
||||
|
||||
To build just the generated headers (useful for troubleshooting):
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
ninja -C build generate-libc-headers
|
||||
```sh
|
||||
ninja -C build generate-libc-headers
|
||||
```
|
||||
|
||||
To run a specific unit test for a function, you can target it directly using its
|
||||
full name:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
ninja -C build libc.test.src.<HEADER>.<FUNCTION>_test.__unit__
|
||||
```
|
||||
|
||||
ninja -C build libc.test.src.<HEADER>.<FUNCTION>_test.__unit__
|
||||
For example, to run the test for `isalpha` in `ctype.h`:
|
||||
|
||||
For example, to run the test for ``isalpha`` in ``ctype.h``:
|
||||
```sh
|
||||
ninja -C build libc.test.src.ctype.isalpha_test.__unit__
|
||||
```
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
ninja -C build libc.test.src.ctype.isalpha_test.__unit__
|
||||
|
||||
Building Documentation
|
||||
======================
|
||||
## Building Documentation
|
||||
|
||||
If you have Sphinx installed, you can build the libc documentation locally. The
|
||||
build configuration above already includes the necessary flags
|
||||
(``-DLLVM_ENABLE_SPHINX=ON -DLIBC_INCLUDE_DOCS=ON``).
|
||||
(`-DLLVM_ENABLE_SPHINX=ON -DLIBC_INCLUDE_DOCS=ON`).
|
||||
|
||||
To generate the HTML documentation:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
ninja -C build docs-libc-html
|
||||
```
|
||||
|
||||
ninja -C build docs-libc-html
|
||||
|
||||
The generated documentation will be available in the ``docs/libc/html`` directory
|
||||
The generated documentation will be available in the `docs/libc/html` directory
|
||||
within your build folder.
|
||||
|
||||
Building a Simple Sysroot
|
||||
=========================
|
||||
## Building a Simple Sysroot
|
||||
|
||||
.. warning::
|
||||
The LLVM libc is missing many critical functions needed to build non-trivial applications. If you
|
||||
are not currently working on porting the libc, we recommend sticking with your system libc. However,
|
||||
ignoring warnings like this are how most of us got into this business. So: Speak friend and enter.
|
||||
:::{warning}
|
||||
The LLVM libc is missing many critical functions needed to build non-trivial applications. If you
|
||||
are not currently working on porting the libc, we recommend sticking with your system libc. However,
|
||||
ignoring warnings like this are how most of us got into this business. So: Speak friend and enter.
|
||||
:::
|
||||
|
||||
This document describes how to set up a simple sysroot and a compiler that uses it from
|
||||
scratch. These are not full cross-compilation instructions. We make a few
|
||||
assumptions:
|
||||
|
||||
* The host and target are the same architecture and OS. For example, building a Linux x86-64 libc on a Linux x86-64 host.
|
||||
* The host has a working and recent Clang toolchain. Clang 21 has been tested.
|
||||
* Your container is using Debian Testing or a derived distribution. Other distributions likely work but the package names and paths may differ.
|
||||
* You have root access to your machine to set up the compiler wrapper.
|
||||
- The host and target are the same architecture and OS. For example, building
|
||||
a Linux x86-64 libc on a Linux x86-64 host.
|
||||
- The host has a working and recent Clang toolchain. Clang 21 has been tested.
|
||||
- Your container is using Debian Testing or a derived distribution. Other
|
||||
distributions likely work but the package names and paths may differ.
|
||||
- You have root access to your machine to set up the compiler wrapper.
|
||||
|
||||
For more comprehensive instructions on setting up a sysroot, see the `official LLVM
|
||||
guide <https://llvm.org/docs/HowToCrossCompileLLVM.html#setting-up-a-sysroot>`_.
|
||||
For more comprehensive instructions on setting up a sysroot, see the [official LLVM
|
||||
guide](https://llvm.org/docs/HowToCrossCompileLLVM.html#setting-up-a-sysroot).
|
||||
|
||||
|
||||
Step 1: Preparation
|
||||
-------------------
|
||||
### Step 1: Preparation
|
||||
|
||||
First, set up the environment variables for your sysroot path and the major
|
||||
version of your host Clang.
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
SYSROOT=$(readlink -f ~/sysroot)
|
||||
```
|
||||
|
||||
SYSROOT=$(readlink -f ~/sysroot)
|
||||
|
||||
Step 2: Linux Headers
|
||||
---------------------
|
||||
### Step 2: Linux Headers
|
||||
|
||||
Next, install the Linux kernel headers into your sysroot. For this guide, we'll
|
||||
copy the headers from the host system's ``/usr/include`` directory. This
|
||||
includes ``linux``, ``asm-generic``, and the architecture-specific ``asm``
|
||||
copy the headers from the host system's `/usr/include` directory. This
|
||||
includes `linux`, `asm-generic`, and the architecture-specific `asm`
|
||||
headers.
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
# Create the include directory
|
||||
mkdir -p $SYSROOT/usr/include
|
||||
|
||||
# Create the include directory
|
||||
mkdir -p $SYSROOT/usr/include
|
||||
|
||||
# Copy the header directories
|
||||
cp -R /usr/include/linux $SYSROOT/usr/include/
|
||||
cp -R /usr/include/asm-generic $SYSROOT/usr/include/
|
||||
# Use -L to dereference the asm symlink and copy the actual files
|
||||
cp -R -L /usr/include/asm $SYSROOT/usr/include/
|
||||
# Copy the header directories
|
||||
cp -R /usr/include/linux $SYSROOT/usr/include/
|
||||
cp -R /usr/include/asm-generic $SYSROOT/usr/include/
|
||||
# Use -L to dereference the asm symlink and copy the actual files
|
||||
cp -R -L /usr/include/asm $SYSROOT/usr/include/
|
||||
```
|
||||
|
||||
If you instead want to build the headers from the kernel sources, you can run
|
||||
the following commands:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
# Create the include directory
|
||||
mkdir -p $SYSROOT/usr/include
|
||||
|
||||
# Create the include directory
|
||||
mkdir -p $SYSROOT/usr/include
|
||||
|
||||
git clone --depth=1 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git /tmp/linux
|
||||
make LLVM=1 INSTALL_HDR_PATH=$SYSROOT/usr -C /tmp/linux headers_install
|
||||
git clone --depth=1 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git /tmp/linux
|
||||
make LLVM=1 INSTALL_HDR_PATH=$SYSROOT/usr -C /tmp/linux headers_install
|
||||
```
|
||||
|
||||
The headers can be built to target non-host architectures by adding the
|
||||
``ARCH={arm|arm64|i386}`` to the above invocation of ``make``.
|
||||
`ARCH={arm|arm64|i386}` to the above invocation of `make`.
|
||||
|
||||
.. note::
|
||||
For a more production-ready sysroot, you would typically download a specific
|
||||
kernel version and install the headers using ``make headers_install``
|
||||
configured for the target architecture and installation path using the above
|
||||
instructions.
|
||||
:::{note}
|
||||
For a more production-ready sysroot, you would typically download a specific
|
||||
kernel version and install the headers using `make headers_install`
|
||||
configured for the target architecture and installation path using the above
|
||||
instructions.
|
||||
:::
|
||||
|
||||
Step 3: Build and Install Runtimes
|
||||
----------------------------------
|
||||
### Step 3: Build and Install Runtimes
|
||||
|
||||
Now, configure the build for LLVM libc and compiler-rt. We're using the
|
||||
**bootstrap build** (see :ref:`build_concepts`) because we need to build the
|
||||
full ``clang`` and then install the ``clang-resource-headers`` that provide
|
||||
``stdarg.h``, ``stddef.h`` and others.
|
||||
**bootstrap build** (see {ref}`build_concepts`) because we need to build the
|
||||
full `clang` and then install the `clang-resource-headers` that provide
|
||||
`stdarg.h`, `stddef.h` and others.
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
cmake \
|
||||
-S llvm \
|
||||
-B build-runtimes \
|
||||
-G Ninja \
|
||||
-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF \
|
||||
-DCMAKE_INSTALL_PREFIX=$SYSROOT/usr \
|
||||
-DLLVM_ENABLE_PROJECTS="clang" \
|
||||
-DLLVM_ENABLE_RUNTIMES="libc;compiler-rt" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DLLVM_LIBC_FULL_BUILD=ON \
|
||||
-DLIBC_INCLUDE_DOCS=OFF \
|
||||
-DLLVM_LIBC_INCLUDE_SCUDO=ON \
|
||||
-DCOMPILER_RT_BUILD_SCUDO_STANDALONE_WITH_LLVM_LIBC=ON \
|
||||
-DCOMPILER_RT_BUILD_GWP_ASAN=OFF \
|
||||
-DCOMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED=OFF \
|
||||
-DCOMPILER_RT_BUILD_BUILTINS:BOOL=TRUE \
|
||||
-DCOMPILER_RT_BUILD_CRT:BOOL=TRUE
|
||||
```sh
|
||||
cmake \
|
||||
-S llvm \
|
||||
-B build-runtimes \
|
||||
-G Ninja \
|
||||
-DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF \
|
||||
-DCMAKE_INSTALL_PREFIX=$SYSROOT/usr \
|
||||
-DLLVM_ENABLE_PROJECTS="clang" \
|
||||
-DLLVM_ENABLE_RUNTIMES="libc;compiler-rt" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DLLVM_LIBC_FULL_BUILD=ON \
|
||||
-DLIBC_INCLUDE_DOCS=OFF \
|
||||
-DLLVM_LIBC_INCLUDE_SCUDO=ON \
|
||||
-DCOMPILER_RT_BUILD_SCUDO_STANDALONE_WITH_LLVM_LIBC=ON \
|
||||
-DCOMPILER_RT_BUILD_GWP_ASAN=OFF \
|
||||
-DCOMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED=OFF \
|
||||
-DCOMPILER_RT_BUILD_BUILTINS:BOOL=TRUE \
|
||||
-DCOMPILER_RT_BUILD_CRT:BOOL=TRUE
|
||||
```
|
||||
|
||||
After configuring, build and install the necessary components:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
ninja -C build-runtimes install-clang-resource-headers install-libc install-compiler-rt install-builtins
|
||||
```
|
||||
|
||||
ninja -C build-runtimes install-clang-resource-headers install-libc install-compiler-rt install-builtins
|
||||
|
||||
Step 4: Configure the Compiler Wrapper
|
||||
--------------------------------------
|
||||
### Step 4: Configure the Compiler Wrapper
|
||||
|
||||
To make using the new toolchain easier, you can create a Clang configuration
|
||||
file. This allows you to avoid passing long command line arguments every time
|
||||
|
|
@ -202,52 +202,50 @@ you compile a program.
|
|||
|
||||
1. Identify the directory where your Clang binary is located:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
CLANG_DIR=$(dirname $(readlink -f /usr/bin/clang))
|
||||
```
|
||||
|
||||
CLANG_DIR=$(dirname $(readlink -f /usr/bin/clang))
|
||||
2. Create a symlink to `clang` named `llvm-libc-clang` in that directory:
|
||||
|
||||
2. Create a symlink to ``clang`` named ``llvm-libc-clang`` in that directory:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
sudo ln -sf $CLANG_DIR/clang /usr/bin/llvm-libc-clang
|
||||
```sh
|
||||
sudo ln -sf $CLANG_DIR/clang /usr/bin/llvm-libc-clang
|
||||
```
|
||||
|
||||
3. Create the configuration file in the same directory. Clang automatically looks
|
||||
for a file named ``<executable-name>.cfg`` in the same directory as the
|
||||
for a file named `<executable-name>.cfg` in the same directory as the
|
||||
executable. Use the following command to generate it with your environment
|
||||
variables:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
CLANG_VERSION=$(build-runtimes/bin/clang -dumpversion | cut -d. -f1)
|
||||
|
||||
CLANG_VERSION=$(build-runtimes/bin/clang -dumpversion | cut -d. -f1)
|
||||
cat <<EOF | sudo tee $CLANG_DIR/llvm-libc-clang.cfg
|
||||
--target=x86_64-unknown-linux-llvm
|
||||
--sysroot=$SYSROOT
|
||||
-resource-dir=$SYSROOT/usr/lib/clang/$CLANG_VERSION
|
||||
--rtlib=compiler-rt
|
||||
--unwindlib=none
|
||||
-static
|
||||
EOF
|
||||
```
|
||||
|
||||
cat <<EOF | sudo tee $CLANG_DIR/llvm-libc-clang.cfg
|
||||
--target=x86_64-unknown-linux-llvm
|
||||
--sysroot=$SYSROOT
|
||||
-resource-dir=$SYSROOT/usr/lib/clang/$CLANG_VERSION
|
||||
--rtlib=compiler-rt
|
||||
--unwindlib=none
|
||||
-static
|
||||
EOF
|
||||
|
||||
Step 5: Verification
|
||||
--------------------
|
||||
### Step 5: Verification
|
||||
|
||||
You can now use your newly built toolchain by running your wrapper.
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
// hello.c
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
printf("Hello, World!\n");
|
||||
return 0;
|
||||
}
|
||||
```c
|
||||
// hello.c
|
||||
#include <stdio.h>
|
||||
int main() {
|
||||
printf("Hello, World!\n");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
Compile and run the example:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
llvm-libc-clang hello.c
|
||||
./a.out
|
||||
|
||||
```sh
|
||||
llvm-libc-clang hello.c
|
||||
./a.out
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,99 +1,93 @@
|
|||
.. _getting_started:
|
||||
(getting_started)=
|
||||
|
||||
===============
|
||||
Getting Started
|
||||
===============
|
||||
# Getting Started
|
||||
|
||||
This guide provides a single, robust path for new users and contributors to
|
||||
build, test, and verify LLVM-libc. We use the **runtimes build** (see
|
||||
:ref:`build_concepts` for more information) because it is faster and sufficient
|
||||
This guide provides a single, robust path for new users and contributors to
|
||||
build, test, and verify LLVM-libc. We use the **runtimes build** (see
|
||||
{ref}`build_concepts` for more information) because it is faster and sufficient
|
||||
for most development tasks.
|
||||
|
||||
1. Install Dependencies
|
||||
=======================
|
||||
## 1. Install Dependencies
|
||||
|
||||
To build LLVM-libc, you will need a recent version of Clang (v15+) and basic
|
||||
build tools. On a Debian/Ubuntu-based system, you can install these using
|
||||
``apt-get``:
|
||||
To build LLVM-libc, you will need a recent version of Clang (v15+) and basic
|
||||
build tools. On a Debian/Ubuntu-based system, you can install these using
|
||||
`apt-get`:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
sudo apt-get update
|
||||
sudo apt-get install git cmake ninja-build clang gcc-multilib
|
||||
```
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install git cmake ninja-build clang gcc-multilib
|
||||
## 2. Clone and Configure
|
||||
|
||||
2. Clone and Configure
|
||||
======================
|
||||
|
||||
The following command clones the complete LLVM project and configures the
|
||||
build for LLVM-libc. We include ``compiler-rt`` to enable the Scudo memory
|
||||
The following command clones the complete LLVM project and configures the
|
||||
build for LLVM-libc. We include `compiler-rt` to enable the Scudo memory
|
||||
allocator.
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
git clone --depth=1 https://github.com/llvm/llvm-project.git
|
||||
cd llvm-project
|
||||
cmake -G Ninja -S runtimes -B build \
|
||||
-DLLVM_ENABLE_RUNTIMES="libc;compiler-rt" \
|
||||
-DLLVM_LIBC_FULL_BUILD=ON \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DLLVM_LIBC_INCLUDE_SCUDO=ON \
|
||||
-DCOMPILER_RT_BUILD_SCUDO_STANDALONE_WITH_LLVM_LIBC=ON \
|
||||
-DCOMPILER_RT_BUILD_GWP_ASAN=OFF \
|
||||
-DCOMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED=OFF \
|
||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
||||
```
|
||||
|
||||
git clone --depth=1 https://github.com/llvm/llvm-project.git
|
||||
cd llvm-project
|
||||
cmake -G Ninja -S runtimes -B build \
|
||||
-DLLVM_ENABLE_RUNTIMES="libc;compiler-rt" \
|
||||
-DLLVM_LIBC_FULL_BUILD=ON \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DCMAKE_C_COMPILER=clang \
|
||||
-DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DLLVM_LIBC_INCLUDE_SCUDO=ON \
|
||||
-DCOMPILER_RT_BUILD_SCUDO_STANDALONE_WITH_LLVM_LIBC=ON \
|
||||
-DCOMPILER_RT_BUILD_GWP_ASAN=OFF \
|
||||
-DCOMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED=OFF \
|
||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
||||
## 3. Build and Test
|
||||
|
||||
3. Build and Test
|
||||
=================
|
||||
|
||||
After configuring, you can build the library, the math library (libm), and
|
||||
After configuring, you can build the library, the math library (libm), and
|
||||
run all unit tests:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
ninja -C build libc libm check-libc
|
||||
```
|
||||
|
||||
ninja -C build libc libm check-libc
|
||||
To run a specific test, such as `isalpha` in `ctype.h`:
|
||||
|
||||
To run a specific test, such as ``isalpha`` in ``ctype.h``:
|
||||
```sh
|
||||
ninja -C build libc.test.src.ctype.isalpha_test.__unit__
|
||||
```
|
||||
|
||||
.. code-block:: sh
|
||||
## 4. Verify with Hello World
|
||||
|
||||
ninja -C build libc.test.src.ctype.isalpha_test.__unit__
|
||||
To verify your build, create a simple `hello.c` file:
|
||||
|
||||
4. Verify with Hello World
|
||||
==========================
|
||||
```c
|
||||
#include <stdio.h>
|
||||
|
||||
To verify your build, create a simple ``hello.c`` file:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("Hello world from LLVM-libc!\n");
|
||||
return 0;
|
||||
}
|
||||
int main() {
|
||||
printf("Hello world from LLVM-libc!\n");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
Compile it using the build artifacts:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
clang -nostdinc -nostdlib hello.c -o hello \
|
||||
-I build/libc/include \
|
||||
-I $(clang -print-resource-dir)/include \
|
||||
build/libc/startup/linux/crt1.o \
|
||||
build/libc/lib/libc.a \
|
||||
build/libc/lib/libm.a
|
||||
```sh
|
||||
clang -nostdinc -nostdlib hello.c -o hello \
|
||||
-I build/libc/include \
|
||||
-I $(clang -print-resource-dir)/include \
|
||||
build/libc/startup/linux/crt1.o \
|
||||
build/libc/lib/libc.a \
|
||||
build/libc/lib/libm.a
|
||||
```
|
||||
|
||||
Finally, run the executable:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
./hello
|
||||
# Output: Hello world from LLVM-libc!
|
||||
```
|
||||
|
||||
./hello
|
||||
# Output: Hello world from LLVM-libc!
|
||||
|
||||
This setup builds LLVM-libc as a standalone library using the
|
||||
recommended set of flags. From here, you can visit :ref:`full_host_build`
|
||||
for advanced sysroot setup, :ref:`overlay_mode` to learn about using
|
||||
LLVM-libc to augment your system's C library, or :ref:`build_concepts`
|
||||
This setup builds LLVM-libc as a standalone library using the
|
||||
recommended set of flags. From here, you can visit {ref}`full_host_build`
|
||||
for advanced sysroot setup, {ref}`overlay_mode` to learn about using
|
||||
LLVM-libc to augment your system's C library, or {ref}`build_concepts`
|
||||
to understand other build scenarios.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
.. _hand_in_hand:
|
||||
(hand_in_hand)=
|
||||
|
||||
============
|
||||
Hand-in-Hand
|
||||
============
|
||||
# Hand-in-Hand
|
||||
|
||||
Hand-in-Hand is the name of the mechanism that allows other LLVM projects to use
|
||||
LLVM-libc's internal C++ APIs instead of calling the public libc interface.
|
||||
|
|
@ -10,20 +8,21 @@ This is useful for cases where the C interface doesn't match the desired
|
|||
interface.
|
||||
|
||||
The original use case for the Hand-in-Hand interface was to let libc++ use
|
||||
LLVM-libc's string to float conversion internals. The libc interface (strtof)
|
||||
LLVM-libc's string to float conversion internals. The libc interface (`strtof`)
|
||||
takes a null terminated string with no maximum length while the libc++ interface
|
||||
(from_chars<float>) takes a string with a start and an end. If libc++ had used
|
||||
(`from_chars<float>`) takes a string with a start and an end. If libc++ had used
|
||||
the public interface it would have had to allocate a new null terminated string
|
||||
before calling strtof, but with Hand-in-Hand libc++ handles its own parsing
|
||||
before calling `strtof`, but with Hand-in-Hand libc++ handles its own parsing
|
||||
and then passes the parsed information to LLVM-libc's conversion code. This is
|
||||
better for performance and cuts down on code duplication in the LLVM repository.
|
||||
|
||||
Hand-in-Hand works by LLVM-libc exposing a set of headers in the /libc/shared/
|
||||
Hand-in-Hand works by LLVM-libc exposing a set of headers in the `/libc/shared/`
|
||||
directory. These headers make the interface more explicit and easier to
|
||||
maintain. The client library includes the shared headers by depending on the
|
||||
llvm-libc-common-utilities target which sets up the necessary includes and
|
||||
defines. The client library then includes "shared/<header>" to get the necessary
|
||||
components. All of the functions shared via Hand-in-Hand are header only.
|
||||
`llvm-libc-common-utilities` target which sets up the necessary includes and
|
||||
defines. The client library then includes `"shared/<header>"` to get the
|
||||
necessary components. All of the functions shared via Hand-in-Hand are header
|
||||
only.
|
||||
|
||||
The Hand-in-Hand interface is intended to be an internal implementation detail,
|
||||
and it has no guarantees of stability. When the internal LLVM-libc interface is
|
||||
|
|
@ -32,10 +31,12 @@ commit. This allows LLVM-libc to update their interface without breaking their
|
|||
users.
|
||||
|
||||
Current Hand-in-Hand users:
|
||||
Libc++ uses it for from_chars<float/double>
|
||||
OpenMP uses it for printf on GPUs
|
||||
[WIP] clang uses it for APFloat functions.
|
||||
|
||||
- Libc++ uses it for `from_chars<float/double>`.
|
||||
- OpenMP uses it for printf on GPUs.
|
||||
- [WIP] clang uses it for APFloat functions.
|
||||
|
||||
For more information check out the 2024 talk about the original Project:
|
||||
* `slides <https://llvm.org/devmtg/2024-10/slides/techtalk/Jones-DiBella-hand-in-hand.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=VAEO86YtTHA>`__
|
||||
|
||||
- [slides](https://llvm.org/devmtg/2024-10/slides/techtalk/Jones-DiBella-hand-in-hand.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=VAEO86YtTHA)
|
||||
|
|
|
|||
|
|
@ -1,112 +1,112 @@
|
|||
==================
|
||||
The LLVM C Library
|
||||
==================
|
||||
# The LLVM C Library
|
||||
|
||||
LLVM-libc is a from-scratch implementation of the C standard library, built as
|
||||
part of the LLVM project. It is designed to be **modular** (any piece can be
|
||||
part of the LLVM project. It is designed to be **modular** (any piece can be
|
||||
used independently), **multiplatform** (Linux, GPU, baremetal embedded, UEFI,
|
||||
macOS, Windows), and written in modern C++ for correctness, performance, and
|
||||
safety.
|
||||
|
||||
What Works Today
|
||||
================
|
||||
## What Works Today
|
||||
|
||||
LLVM-libc is **actively used in production** for a targeted set of use cases,
|
||||
though coverage is still growing and many programs that depend on the full C
|
||||
standard library (regex, locale, wide-character I/O, etc.) will not yet compile
|
||||
against it:
|
||||
|
||||
* **Static-linked Linux servers and containers** — used in production at Google
|
||||
- **Static-linked Linux servers and containers** — used in production at Google
|
||||
(servers and Pixel Buds) on x86-64 and AArch64.
|
||||
* **GPU compute (AMDGPU, NVPTX)** — libc functions available in GPU kernels
|
||||
via LLVM's offloading runtime. :doc:`GPU docs <gpu/index>`
|
||||
* **Baremetal embedded (ARM, RISC-V, AArch64)** — minimal footprint builds
|
||||
- **GPU compute (AMDGPU, NVPTX)** — libc functions available in GPU kernels
|
||||
via LLVM's offloading runtime. {doc}`GPU docs <gpu/index>`
|
||||
- **Baremetal embedded (ARM, RISC-V, AArch64)** — minimal footprint builds
|
||||
for microcontrollers and custom hardware.
|
||||
* **UEFI applications** — experimental support for firmware development.
|
||||
:doc:`UEFI docs <uefi/index>`
|
||||
* **LLVM ecosystem internals** — libc++ and the offloading runtime consume
|
||||
LLVM-libc directly via :doc:`Hand-in-Hand <hand_in_hand>`.
|
||||
* **Toolchain integrations** — pieces of LLVM-libc are used in Android Bionic,
|
||||
- **UEFI applications** — experimental support for firmware development.
|
||||
{doc}`UEFI docs <uefi/index>`
|
||||
- **LLVM ecosystem internals** — libc++ and the offloading runtime consume
|
||||
LLVM-libc directly via {doc}`Hand-in-Hand <hand_in_hand>`.
|
||||
- **Toolchain integrations** — pieces of LLVM-libc are used in Android Bionic,
|
||||
Fuchsia, Emscripten, and the ARM embedded toolchain.
|
||||
|
||||
Coverage is still growing. See the :doc:`implementation status <headers/index>`
|
||||
Coverage is still growing. See the {doc}`implementation status <headers/index>`
|
||||
pages for per-header detail, and the
|
||||
:doc:`platform support <platform_support>` page for OS/architecture coverage.
|
||||
{doc}`platform support <platform_support>` page for OS/architecture coverage.
|
||||
|
||||
Getting Started
|
||||
===============
|
||||
## Getting Started
|
||||
|
||||
If you are new to LLVM-libc, :doc:`getting_started` is the right first stop.
|
||||
If you are new to LLVM-libc, {doc}`getting_started` is the right first stop.
|
||||
It covers cloning, building, testing, and verifying your installation in one
|
||||
place.
|
||||
|
||||
Want to use LLVM-libc *alongside* your system libc instead of replacing it?
|
||||
See :doc:`overlay_mode`.
|
||||
See {doc}`overlay_mode`.
|
||||
|
||||
Get Involved
|
||||
============
|
||||
## Get Involved
|
||||
|
||||
LLVM-libc is an active project and welcomes contributors of all experience
|
||||
levels. See :doc:`contributing` to learn how to help.
|
||||
levels. See {doc}`contributing` to learn how to help.
|
||||
|
||||
* `Source code <https://github.com/llvm/llvm-project/tree/main/libc>`__
|
||||
* `Bug reports <https://github.com/llvm/llvm-project/labels/libc>`__
|
||||
* `Discourse <https://discourse.llvm.org/c/runtimes/libc>`__
|
||||
* `Discord <https://discord.com/channels/636084430946959380/636732994891284500>`__
|
||||
(`invite <https://discord.gg/xS7Z362>`__)
|
||||
* `Buildbot <https://lab.llvm.org/buildbot/#/builders?tags=libc>`__
|
||||
- [Source code](https://github.com/llvm/llvm-project/tree/main/libc)
|
||||
- [Bug reports](https://github.com/llvm/llvm-project/labels/libc)
|
||||
- [Discourse](https://discourse.llvm.org/c/runtimes/libc)
|
||||
- [Discord](https://discord.com/channels/636084430946959380/636732994891284500)
|
||||
([invite](https://discord.gg/xS7Z362))
|
||||
- [Buildbot](https://lab.llvm.org/buildbot/#/builders?tags=libc)
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
:caption: Using LLVM-libc
|
||||
```{toctree}
|
||||
:caption: Using LLVM-libc
|
||||
:hidden: true
|
||||
:maxdepth: 1
|
||||
|
||||
getting_started
|
||||
build_concepts
|
||||
overlay_mode
|
||||
full_host_build
|
||||
full_cross_build
|
||||
configure
|
||||
hand_in_hand
|
||||
getting_started
|
||||
build_concepts
|
||||
overlay_mode
|
||||
full_host_build
|
||||
full_cross_build
|
||||
configure
|
||||
hand_in_hand
|
||||
```
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
:caption: Platforms
|
||||
```{toctree}
|
||||
:caption: Platforms
|
||||
:hidden: true
|
||||
:maxdepth: 1
|
||||
|
||||
gpu/index.rst
|
||||
uefi/index.rst
|
||||
gpu/index
|
||||
uefi/index
|
||||
```
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
:caption: Implementation Status
|
||||
```{toctree}
|
||||
:caption: Implementation Status
|
||||
:hidden: true
|
||||
:maxdepth: 1
|
||||
|
||||
headers/index.rst
|
||||
arch_support
|
||||
platform_support
|
||||
compiler_support
|
||||
headers/index
|
||||
arch_support
|
||||
platform_support
|
||||
compiler_support
|
||||
```
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
:caption: Development
|
||||
```{toctree}
|
||||
:caption: Development
|
||||
:hidden: true
|
||||
:maxdepth: 1
|
||||
|
||||
contributing
|
||||
build_and_test
|
||||
dev/index.rst
|
||||
porting
|
||||
Maintainers
|
||||
contributing
|
||||
build_and_test
|
||||
dev/index
|
||||
porting
|
||||
Maintainers
|
||||
```
|
||||
|
||||
.. toctree::
|
||||
:hidden:
|
||||
:maxdepth: 1
|
||||
:caption: Links
|
||||
```{toctree}
|
||||
:caption: Links
|
||||
:hidden: true
|
||||
:maxdepth: 1
|
||||
|
||||
talks
|
||||
Source Code <https://github.com/llvm/llvm-project/tree/main/libc>
|
||||
Bug Reports <https://github.com/llvm/llvm-project/labels/libc>
|
||||
Discourse <https://discourse.llvm.org/c/runtimes/libc>
|
||||
Join the Discord <https://discord.gg/xS7Z362>
|
||||
Discord Channel <https://discord.com/channels/636084430946959380/636732994891284500>
|
||||
Buildbot <https://lab.llvm.org/buildbot/#/builders?tags=libc>
|
||||
talks
|
||||
Source Code <https://github.com/llvm/llvm-project/tree/main/libc>
|
||||
Bug Reports <https://github.com/llvm/llvm-project/labels/libc>
|
||||
Discourse <https://discourse.llvm.org/c/runtimes/libc>
|
||||
Join the Discord <https://discord.gg/xS7Z362>
|
||||
Discord Channel <https://discord.com/channels/636084430946959380/636732994891284500>
|
||||
Buildbot <https://lab.llvm.org/buildbot/#/builders?tags=libc>
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,68 +1,63 @@
|
|||
.. _overlay_mode:
|
||||
(overlay_mode)=
|
||||
|
||||
============
|
||||
Overlay Mode
|
||||
============
|
||||
# Overlay Mode
|
||||
|
||||
One can choose to use LLVM's libc in the overlay mode. In this mode, the link
|
||||
order semantics are exploited to pick symbols from ``libllvmlibc.a`` (if they
|
||||
are available in ``libllvmlibc.a``) and the rest are picked from the system
|
||||
order semantics are exploited to pick symbols from `libllvmlibc.a` (if they
|
||||
are available in `libllvmlibc.a`) and the rest are picked from the system
|
||||
libc. The user programs also have to use header files from the system libc.
|
||||
Naturally, only functions which do not depend on implementation specific ABI
|
||||
are included in ``libllvmlibc.a``. Examples of such functions are ``strlen``
|
||||
and ``round``. Functions like ``fopen`` and friends are not included as they
|
||||
depend on the implementation specific definition of the ``FILE`` data structure.
|
||||
are included in `libllvmlibc.a`. Examples of such functions are `strlen`
|
||||
and `round`. Functions like `fopen` and friends are not included as they
|
||||
depend on the implementation specific definition of the `FILE` data structure.
|
||||
|
||||
Building the libc in the overlay mode
|
||||
=====================================
|
||||
## Building the libc in the overlay mode
|
||||
|
||||
There are two different ways in which the libc can be built for use in the
|
||||
overlay mode. In both the ways, we build a static archive named
|
||||
``libllvmlibc.a``. We use a rather verbose name with a repeated ``lib`` to make
|
||||
it clear that it is not the system libc, which is typically named ``libc.a``.
|
||||
`libllvmlibc.a`. We use a rather verbose name with a repeated `lib` to make
|
||||
it clear that it is not the system libc, which is typically named `libc.a`.
|
||||
Also, if users choose to mix more than one libc with the system libc, then
|
||||
the name ``libllvmlibc.a`` makes it absolutely clear that it is the static
|
||||
the name `libllvmlibc.a` makes it absolutely clear that it is the static
|
||||
archive of LLVM's libc.
|
||||
|
||||
Building LLVM-libc as a standalone runtime
|
||||
------------------------------------------
|
||||
### Building LLVM-libc as a standalone runtime
|
||||
|
||||
We can treat the ``libc`` project like any other normal LLVM runtime library by
|
||||
We can treat the `libc` project like any other normal LLVM runtime library by
|
||||
building it with the following cmake command:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$> cd llvm-project # The llvm-project checkout
|
||||
$> mkdir build
|
||||
$> cd build
|
||||
$> cmake ../runtimes -G Ninja -DLLVM_ENABLE_RUNTIMES="libc" \
|
||||
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_BUILD_TYPE=<Debug|Release> \ # Select build type
|
||||
-DCMAKE_INSTALL_PREFIX=<Your prefix of choice> # Optional
|
||||
```sh
|
||||
$> cd llvm-project # The llvm-project checkout
|
||||
$> mkdir build
|
||||
$> cd build
|
||||
$> cmake ../runtimes -G Ninja -DLLVM_ENABLE_RUNTIMES="libc" \
|
||||
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_BUILD_TYPE=<Debug|Release> \ # Select build type
|
||||
-DCMAKE_INSTALL_PREFIX=<Your prefix of choice> # Optional
|
||||
```
|
||||
|
||||
Next, build the libc:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$> ninja libc
|
||||
```sh
|
||||
$> ninja libc
|
||||
```
|
||||
|
||||
Then, run the tests:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$> ninja check-libc
|
||||
```sh
|
||||
$> ninja check-libc
|
||||
```
|
||||
|
||||
The build step will build the static archive the in the directory
|
||||
``build/projects/libc/lib``. Notice that the above CMake configure step also
|
||||
`build/projects/libc/lib`. Notice that the above CMake configure step also
|
||||
specified an install prefix. This is optional, but it's used, then the following
|
||||
command will install the static archive to the install path:
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
$> ninja install-libc
|
||||
```
|
||||
|
||||
$> ninja install-libc
|
||||
|
||||
Building the static archive as part of the bootstrap build
|
||||
----------------------------------------------------------
|
||||
### Building the static archive as part of the bootstrap build
|
||||
|
||||
The bootstrap build is a build mode in which runtime components like libc++,
|
||||
libcxx-abi, libc etc. are built using the ToT clang. The idea is that this build
|
||||
|
|
@ -70,52 +65,47 @@ produces an in-sync toolchain of compiler + runtime libraries. This ensures that
|
|||
LLVM-libc has access to the latest clang features, which should provide the best
|
||||
performance possible.
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$> cmake ../llvm -G Ninja -DLLVM_ENABLE_PROJECTS="clang" \
|
||||
-DLLVM_ENABLE_RUNTIMES="libc" \ # libc is listed as runtime and not as a project
|
||||
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_BUILD_TYPE=<Debug|Release> \ # Select build type
|
||||
-DCMAKE_INSTALL_PREFIX=<Your prefix of choice> # Optional
|
||||
```sh
|
||||
$> cmake ../llvm -G Ninja -DLLVM_ENABLE_PROJECTS="clang" \
|
||||
-DLLVM_ENABLE_RUNTIMES="libc" \ # libc is listed as runtime and not as a project
|
||||
-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \
|
||||
-DCMAKE_BUILD_TYPE=<Debug|Release> \ # Select build type
|
||||
-DCMAKE_INSTALL_PREFIX=<Your prefix of choice> # Optional
|
||||
```
|
||||
|
||||
The build and install steps are the same as above, but the build step will take
|
||||
much longer since ``clang`` will be built before building ``libllvmlibc.a``.
|
||||
much longer since `clang` will be built before building `libllvmlibc.a`.
|
||||
|
||||
.. code-block:: sh
|
||||
```sh
|
||||
$> ninja libc
|
||||
$> ninja check-libc
|
||||
```
|
||||
|
||||
$> ninja libc
|
||||
$> ninja check-libc
|
||||
|
||||
Using the overlay static archive
|
||||
================================
|
||||
## Using the overlay static archive
|
||||
|
||||
Once built (and optionally installed), the overlay static archive can be linked
|
||||
to your binaries like any other static archive. For example, when building with
|
||||
``clang`` on Linux, one should follow a recipe like:
|
||||
`clang` on Linux, one should follow a recipe like:
|
||||
|
||||
```sh
|
||||
$> clang <other compiler and/or linker options> <file.o|c(pp)> \
|
||||
-L <path to the directory in which libllvmlibc.a is installed> \ # Optional
|
||||
-lllvmlibc
|
||||
```
|
||||
|
||||
.. code-block:: sh
|
||||
If you installed `libllvmlibc.a` in a standard linker lookup path, for example
|
||||
`/usr/local/lib` on Linux like systems, then specifying the path to the
|
||||
static archive using the `-L` option is not necessary.
|
||||
|
||||
$> clang <other compiler and/or linker options> <file.o|c(pp)> \
|
||||
-L <path to the directory in which libllvmlibc.a is installed> \ # Optional
|
||||
-lllvmlibc
|
||||
|
||||
If you installed ``libllvmlibc.a`` in a standard linker lookup path, for example
|
||||
``/usr/local/lib`` on Linux like systems, then specifying the path to the
|
||||
static archive using the ``-L`` option is not necessary.
|
||||
|
||||
Linking the static archive to other LLVM binaries
|
||||
-------------------------------------------------
|
||||
### Linking the static archive to other LLVM binaries
|
||||
|
||||
Since the libc and other LLVM binaries are developed in the same source tree,
|
||||
linking ``libllvmlibc.a`` to those LLVM binaries does not require any special
|
||||
linking `libllvmlibc.a` to those LLVM binaries does not require any special
|
||||
install step or explicitly passing any special linker flags/options. One can
|
||||
simply add ``llvmlibc`` as a link library to that binary's target. For example,
|
||||
if you want to link ``libllvmlibc.a`` to ``llvm-objcopy``, all you have to do
|
||||
simply add `llvmlibc` as a link library to that binary's target. For example,
|
||||
if you want to link `libllvmlibc.a` to `llvm-objcopy`, all you have to do
|
||||
is to add a CMake command as follows:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
target_link_libraries(llvm-objcopy PRIVATE llvmlibc)
|
||||
|
||||
|
||||
```cmake
|
||||
target_link_libraries(llvm-objcopy PRIVATE llvmlibc)
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,22 +1,21 @@
|
|||
Platform Support
|
||||
================
|
||||
# Platform Support
|
||||
|
||||
Development is currently mostly focused on Linux. MacOS and Windows has
|
||||
Development is currently mostly focused on Linux. MacOS and Windows has
|
||||
partial support, but has bitrot and isn't being tested continuously.
|
||||
|
||||
LLVM-libc is currently being integrated into Android and Fuchsia operating
|
||||
systems via `overlay mode <overlay_mode.html>`__.
|
||||
systems via {doc}`overlay mode <overlay_mode>`.
|
||||
|
||||
For Linux, we support kernel versions as listed on
|
||||
`kernel.org <https://kernel.org/>`_, including ``longterm`` (not past EOL
|
||||
date), ``stable``, and ``mainline`` versions. We actively adopt new features
|
||||
from ``linux-next``.
|
||||
[kernel.org](https://kernel.org/), including `longterm` (not past EOL
|
||||
date), `stable`, and `mainline` versions. We actively adopt new features
|
||||
from `linux-next`.
|
||||
|
||||
For Windows, we plan to support products within their lifecycle. Please refer to
|
||||
`Search Product and Services Lifecycle Information <https://learn.microsoft.com/en-us/lifecycle/products/?products=windows>`_ for more information.
|
||||
[Search Product and Services Lifecycle Information](https://learn.microsoft.com/en-us/lifecycle/products/?products=windows) for more information.
|
||||
|
||||
LLVM-libc does not guarantee backward compatibility with operating systems that
|
||||
have reached their EOL. Compatibility patches for obsolete operating systems
|
||||
will not be accepted.
|
||||
|
||||
For GPU, reference `our GPU docs <gpu/index.html>`__.
|
||||
For GPU, reference {doc}`our GPU docs <gpu/index>`.
|
||||
|
|
|
|||
|
|
@ -1,37 +1,36 @@
|
|||
.. _porting:
|
||||
(porting)=
|
||||
|
||||
=======================================
|
||||
Bringup on a New OS or Architecture
|
||||
=======================================
|
||||
# Bringup on a New OS or Architecture
|
||||
|
||||
Building the libc
|
||||
=================
|
||||
## Building the libc
|
||||
|
||||
An OS specific config directory
|
||||
-------------------------------
|
||||
### An OS specific config directory
|
||||
|
||||
If you are starting to bring up LLVM's libc on a new operating system, the first
|
||||
step is to add a directory for that OS in the ``libc/config`` directory. Both
|
||||
`Linux <https://github.com/llvm/llvm-project/tree/main/libc/config/linux>`_ and
|
||||
`Windows <https://github.com/llvm/llvm-project/tree/main/libc/config/windows>`_,
|
||||
step is to add a directory for that OS in the `libc/config` directory. Both
|
||||
[Linux](https://github.com/llvm/llvm-project/tree/main/libc/config/linux) and
|
||||
[Windows](https://github.com/llvm/llvm-project/tree/main/libc/config/windows),
|
||||
the two operating systems on which LLVM's libc is being actively developed,
|
||||
have their own config directory.
|
||||
|
||||
.. note:: Windows development is not as active as the development on Linux.
|
||||
There is a
|
||||
`Darwin <https://github.com/llvm/llvm-project/tree/main/libc/config/darwin>`_
|
||||
config also which is in a similar state as Windows.
|
||||
:::{note}
|
||||
Windows development is not as active as the development on Linux.
|
||||
There is a
|
||||
[Darwin](https://github.com/llvm/llvm-project/tree/main/libc/config/darwin)
|
||||
config also which is in a similar state as Windows.
|
||||
:::
|
||||
|
||||
.. note:: LLVM's libc is being brought up on the
|
||||
`Fuchsia <https://fuchsia.dev/>`_ operating system also. However, there is no
|
||||
config directory for Fuchsia as the bring up is being done in the Fuchsia
|
||||
source tree.
|
||||
:::{note}
|
||||
LLVM's libc is being brought up on the
|
||||
[Fuchsia](https://fuchsia.dev/) operating system also. However, there is no
|
||||
config directory for Fuchsia as the bring up is being done in the Fuchsia
|
||||
source tree.
|
||||
:::
|
||||
|
||||
Architecture Subdirectory
|
||||
-------------------------
|
||||
### Architecture Subdirectory
|
||||
|
||||
There are parts of the libc which are implemented differently for different
|
||||
architectures. The simplest example of this is the ``syscall`` function and
|
||||
architectures. The simplest example of this is the `syscall` function and
|
||||
its internal implementation - its Linux implementation differs for different
|
||||
architectures. Since a large part of the libc makes use of syscalls (or an
|
||||
equivalent on non-Linux like platforms), it might be simpler and convenient to
|
||||
|
|
@ -41,53 +40,47 @@ have to add a subdirectory (within the config directory of the operating
|
|||
system) for each target architecture, and list the relevant config information
|
||||
separately in those subdirectories. For example, for Linux, the x86_64 and
|
||||
aarch64 configs are in separate directories, named
|
||||
`x86_64 <https://github.com/llvm/llvm-project/tree/main/libc/config/linux/x86_64>`_
|
||||
and `aarch64 <https://github.com/llvm/llvm-project/tree/main/libc/config/linux/aarch64>`_.
|
||||
[x86_64](https://github.com/llvm/llvm-project/tree/main/libc/config/linux/x86_64)
|
||||
and [aarch64](https://github.com/llvm/llvm-project/tree/main/libc/config/linux/aarch64).
|
||||
The libc CMake machinery looks for subdirectories named after the target
|
||||
architecture.
|
||||
|
||||
The entrypoints.txt file
|
||||
------------------------
|
||||
### The entrypoints.txt file
|
||||
|
||||
The ``entrypoints.txt`` file lists the targets for the entrypoints to be
|
||||
The `entrypoints.txt` file lists the targets for the entrypoints to be
|
||||
included in the build for a specific platform. For more technical details on
|
||||
what entrypoints are and how they are registered as targets, see the
|
||||
:ref:`entrypoints` documentation.
|
||||
{ref}`entrypoints` documentation.
|
||||
|
||||
If you are doing an architecture specific bring-up, then an ``entrypoints.txt``
|
||||
If you are doing an architecture specific bring-up, then an `entrypoints.txt`
|
||||
file should be created in the architecture subdirectory for each architecture.
|
||||
Else, having a single ``entrypoints.txt`` in the operating system directory is
|
||||
Else, having a single `entrypoints.txt` in the operating system directory is
|
||||
sufficient.
|
||||
|
||||
A typical bring-up procedure will normally involve progressively adding targets
|
||||
to this file as they are implemented and tested.
|
||||
|
||||
|
||||
The headers.txt file
|
||||
--------------------
|
||||
### The headers.txt file
|
||||
|
||||
Another important piece of config information is listed in a file named
|
||||
``headers.txt``. It lists the targets for the set of public headers that are
|
||||
`headers.txt`. It lists the targets for the set of public headers that are
|
||||
provided by the libc. This is relevant only if the libc is to be used in the
|
||||
:ref:`full_host_build` on the target operating system and architecture. As with
|
||||
the ``entrypoints.txt`` file, one ``headers.txt`` file should be listed for
|
||||
{doc}`full_host_build` on the target operating system and architecture. As with
|
||||
the `entrypoints.txt` file, one `headers.txt` file should be listed for
|
||||
each individual target architecture if you are doing an architecture specific
|
||||
bring up. The Linux config has ``headers.txt`` file listed separately for the
|
||||
`aarch64 <https://github.com/llvm/llvm-project/tree/main/libc/config/linux/aarch64>`_
|
||||
bring up. The Linux config has `headers.txt` file listed separately for the
|
||||
[aarch64](https://github.com/llvm/llvm-project/tree/main/libc/config/linux/aarch64)
|
||||
config and the
|
||||
`x86_64 <https://github.com/llvm/llvm-project/tree/main/libc/config/linux/x86_64>`_
|
||||
[x86_64](https://github.com/llvm/llvm-project/tree/main/libc/config/linux/x86_64)
|
||||
config.
|
||||
|
||||
|
||||
Upstreaming
|
||||
===========
|
||||
## Upstreaming
|
||||
|
||||
Adding a target to the main LLVM-libc has some requirements to ensure that the
|
||||
targets stay in usable condition. LLVM-libc is under active development and
|
||||
without active maintenance targets will become stale and may be sunset.
|
||||
|
||||
Maintenance
|
||||
-----------
|
||||
### Maintenance
|
||||
|
||||
To add a target there must be one or more people whose responsibility it is to
|
||||
keep the target up to date or push it forwards if it's not complete. Those
|
||||
|
|
@ -96,28 +89,27 @@ good shape. This means fixing their target when it breaks, reviewing patches
|
|||
related to their target, and keeping the target's CI running.
|
||||
|
||||
Maintainers are listed in libc/maintainers.md and must follow
|
||||
`LLVM's maintainer policy <https://llvm.org/docs/DeveloperPolicy.html#maintainers>`_.
|
||||
[LLVM's maintainer policy](https://llvm.org/docs/DeveloperPolicy.html#maintainers).
|
||||
|
||||
CI builders
|
||||
-----------
|
||||
### CI builders
|
||||
|
||||
Every target needs at least one CI builder. These are used to check when the
|
||||
target breaks, and to help people who don't have access to the specific
|
||||
architecture fix their bugs. LLVM-libc has both presubmit CI on github
|
||||
and postsubmit CI on the `LLVM buildbot <https://lab.llvm.org/buildbot>`_. For
|
||||
and postsubmit CI on the [LLVM buildbot](https://lab.llvm.org/buildbot). For
|
||||
instructions on contributing a postsubmit buildbot read
|
||||
`the LLVM documentation <https://llvm.org/docs/HowToAddABuilder.html>`_ and for
|
||||
[the LLVM documentation](https://llvm.org/docs/HowToAddABuilder.html) and for
|
||||
presubmit tests read
|
||||
`the best practices <https://llvm.org/docs/CIBestPractices.html>`_
|
||||
[the best practices](https://llvm.org/docs/CIBestPractices.html)
|
||||
|
||||
The test configurations are at these links:
|
||||
* `Linux Postsubmit <https://github.com/llvm/llvm-zorg/blob/main/zorg/buildbot/builders/annotated/libc-linux.py>`_
|
||||
* `Windows Postsubmit <https://github.com/llvm/llvm-zorg/blob/main/zorg/buildbot/builders/annotated/libc-windows.py>`_
|
||||
* `Fullbuild Presubmit <https://github.com/llvm/llvm-project/blob/main/.github/workflows/libc-fullbuild-tests.yml>`_
|
||||
* `Overlay Presubmit <https://github.com/llvm/llvm-project/blob/main/.github/workflows/libc-overlay-tests.yml>`_
|
||||
|
||||
Sunsetting
|
||||
----------
|
||||
- [Linux Postsubmit](https://github.com/llvm/llvm-zorg/blob/main/zorg/buildbot/builders/annotated/libc-linux.py)
|
||||
- [Windows Postsubmit](https://github.com/llvm/llvm-zorg/blob/main/zorg/buildbot/builders/annotated/libc-windows.py)
|
||||
- [Fullbuild Presubmit](https://github.com/llvm/llvm-project/blob/main/.github/workflows/libc-fullbuild-tests.yml)
|
||||
- [Overlay Presubmit](https://github.com/llvm/llvm-project/blob/main/.github/workflows/libc-overlay-tests.yml)
|
||||
|
||||
### Sunsetting
|
||||
|
||||
Sunsetting is the process through which targets can be removed from LLVM-libc.
|
||||
If a target is broken or stale it may be sunset. It is the responsibility of the
|
||||
|
|
|
|||
|
|
@ -1,137 +1,133 @@
|
|||
=====
|
||||
Talks
|
||||
=====
|
||||
----
|
||||
2025
|
||||
----
|
||||
* From proprietary to fully open-source - Arm Toolchain's adoption of LLVM technology - Peter Smith
|
||||
# Talks
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2025-10/slides/keynotes/smith.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=I7S_Vsnkecg>`__
|
||||
## 2025
|
||||
|
||||
* How to test and evaluate LLVM libc on embedded applications - William Huynh
|
||||
- From proprietary to fully open-source - Arm Toolchain's adoption of LLVM technology - Peter Smith
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2025-10/slides/lightning_talks/huynh.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=Dta6nQLmCOY>`__
|
||||
- [slides](https://llvm.org/devmtg/2025-10/slides/keynotes/smith.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=I7S_Vsnkecg)
|
||||
|
||||
* Through the Compiler's Keyhole - Migrating to Clang Without Seeing the Source - Petr Hosek
|
||||
- How to test and evaluate LLVM libc on embedded applications - William Huynh
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2025-10/slides/technical_talks/hosek.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=CHbyo0Ux60o>`__
|
||||
- [slides](https://llvm.org/devmtg/2025-10/slides/lightning_talks/huynh.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=Dta6nQLmCOY)
|
||||
|
||||
* Building C++ compiler runtimes on demand - Why and how - Brook Moses
|
||||
- Through the Compiler's Keyhole - Migrating to Clang Without Seeing the Source - Petr Hosek
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2025-10/slides/technical_talks/moses.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=4oKegT4TWV0>`__
|
||||
- [slides](https://llvm.org/devmtg/2025-10/slides/technical_talks/hosek.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=CHbyo0Ux60o)
|
||||
|
||||
* LT-Uh-Oh - Adventures using LTO with libc - Paul Kirth, Daniel Thornburgh
|
||||
- Building C++ compiler runtimes on demand - Why and how - Brook Moses
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2025-10/slides/technical_talks/kirth_thornburgh.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=cG278WjmIFs>`__
|
||||
- [slides](https://llvm.org/devmtg/2025-10/slides/technical_talks/moses.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=4oKegT4TWV0)
|
||||
|
||||
* Climbing the ladder of Complete - LLVM libc past and future - Michael Jones
|
||||
- LT-Uh-Oh - Adventures using LTO with libc - Paul Kirth, Daniel Thornburgh
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2025-10/slides/technical_talks/jones.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=HtCMCL13Grg>`__
|
||||
- [slides](https://llvm.org/devmtg/2025-10/slides/technical_talks/kirth_thornburgh.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=cG278WjmIFs)
|
||||
|
||||
* Project Widen Your Char-izons - Adding wchar support to LLVM libc - Uzair Nawaz, Sriya Pratipati
|
||||
- Climbing the ladder of Complete - LLVM libc past and future - Michael Jones
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2025-10/slides/quick_talks/nawaz_pratipati.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=YjI9dum74uM>`__
|
||||
- [slides](https://llvm.org/devmtg/2025-10/slides/technical_talks/jones.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=HtCMCL13Grg)
|
||||
|
||||
* A problem left unsolved by Jean-Michel (RAIM 2025) - Paul Zimmermann, Tue Ly
|
||||
- Project Widen Your Char-izons - Adding wchar support to LLVM libc - Uzair Nawaz, Sriya Pratipati
|
||||
|
||||
* `slides <https://raim2025.sciencesconf.org/data/program/slides_paul_zimmermann.pdf>`__
|
||||
- [slides](https://llvm.org/devmtg/2025-10/slides/quick_talks/nawaz_pratipati.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=YjI9dum74uM)
|
||||
|
||||
* Bfloat16 in LLVM libc (GSoC 2025) - Krishna Pandey
|
||||
- A problem left unsolved by Jean-Michel (RAIM 2025) - Paul Zimmermann, Tue Ly
|
||||
|
||||
* `blog <https://blog.llvm.org/posts/2025-09-10-bfloat16-in-llvm-libc/>`__
|
||||
- [slides](https://raim2025.sciencesconf.org/data/program/slides_paul_zimmermann.pdf)
|
||||
|
||||
* Profiling and Testing Math Functions on GPUs (GSoC 2025) - Leandro A. L. Campos
|
||||
- Bfloat16 in LLVM libc (GSoC 2025) - Krishna Pandey
|
||||
|
||||
* `blog <https://blog.llvm.org/posts/2025-08-29-gsoc-profiling-and-testing-math-functions-on-gpus/>`__
|
||||
- [blog](https://blog.llvm.org/posts/2025-09-10-bfloat16-in-llvm-libc/)
|
||||
|
||||
* GPU-driven I/O with io_uring (GSoC 2025) - Rodrigo Ceccato
|
||||
- Profiling and Testing Math Functions on GPUs (GSoC 2025) - Leandro A. L. Campos
|
||||
|
||||
* `blog <https://blog.llvm.org/posts/2025-08-04-gpu-io-uring/>`__
|
||||
- [blog](https://blog.llvm.org/posts/2025-08-29-gsoc-profiling-and-testing-math-functions-on-gpus/)
|
||||
|
||||
* An introduction to building and using LLVM libc - Peter Smith
|
||||
- GPU-driven I/O with io_uring (GSoC 2025) - Rodrigo Ceccato
|
||||
|
||||
* `slides <https://fosdem.org/2025/events/attachments/fosdem-2025-5456-an-introduction-to-building-and-using-llvm-libc/slides/237989/Fosdem202_76Bilu2.pdf>`__
|
||||
* `video <https://fosdem.org/2025/schedule/event/fosdem-2025-5456-an-introduction-to-building-and-using-llvm-libc/>`__
|
||||
- [blog](https://blog.llvm.org/posts/2025-08-04-gpu-io-uring/)
|
||||
|
||||
----
|
||||
2024
|
||||
----
|
||||
* A C/C++ Toolchain for your GPU - Joseph Huber
|
||||
- An introduction to building and using LLVM libc - Peter Smith
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2024-10/slides/techtalk/Huber-A-CPlusPlus-Toolchain-for-Your-GPU.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=4TxGWis1mws>`__
|
||||
* `phoronix <https://www.phoronix.com/news/AMD-Standard-C-Code-GPUs>`__
|
||||
- [slides](https://fosdem.org/2025/events/attachments/fosdem-2025-5456-an-introduction-to-building-and-using-llvm-libc/slides/237989/Fosdem202_76Bilu2.pdf)
|
||||
- [video](https://fosdem.org/2025/schedule/event/fosdem-2025-5456-an-introduction-to-building-and-using-llvm-libc/)
|
||||
|
||||
* Modern Embedded Development with LLVM - Petr Hosek
|
||||
## 2024
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2024-10/slides/techtalk/Hosek-ModernEmbeddedDevelopment-with-LLVM.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=5hHQi-Uj34I>`__
|
||||
- A C/C++ Toolchain for your GPU - Joseph Huber
|
||||
|
||||
* Using llvm-libc in LLVM Embedded Toolchain for Arm - Peter Smith
|
||||
- [slides](https://llvm.org/devmtg/2024-10/slides/techtalk/Huber-A-CPlusPlus-Toolchain-for-Your-GPU.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=4TxGWis1mws)
|
||||
- [phoronix](https://www.phoronix.com/news/AMD-Standard-C-Code-GPUs)
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2024-10/slides/lightning/Smith-Using-llvm-libc.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=ctgkbaYwT_I>`__
|
||||
- Modern Embedded Development with LLVM - Petr Hosek
|
||||
|
||||
* RISC-V Support into LLVM libc - Challenges and Solutions for 32-bit and 64-bit - Mikhail R. Gadelha
|
||||
- [slides](https://llvm.org/devmtg/2024-10/slides/techtalk/Hosek-ModernEmbeddedDevelopment-with-LLVM.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=5hHQi-Uj34I)
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2024-10/slides/quicktalks/Gadelha-RISC-V-SupportIntoLLVM-libc.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=GytmaH64wFo>`__
|
||||
- Using llvm-libc in LLVM Embedded Toolchain for Arm - Peter Smith
|
||||
|
||||
* Project Hand-in-Hand - The beginning of a beautiful friendship - Michael Jones & Christopher Di Bella
|
||||
- [slides](https://llvm.org/devmtg/2024-10/slides/lightning/Smith-Using-llvm-libc.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=ctgkbaYwT_I)
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2024-10/slides/techtalk/Jones-DiBella-hand-in-hand.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=VAEO86YtTHA>`__
|
||||
- RISC-V Support into LLVM libc - Challenges and Solutions for 32-bit and 64-bit - Mikhail R. Gadelha
|
||||
|
||||
* LLVM libc math library - Current status and future directions - Tue Ly
|
||||
- [slides](https://llvm.org/devmtg/2024-10/slides/quicktalks/Gadelha-RISC-V-SupportIntoLLVM-libc.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=GytmaH64wFo)
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2024-10/slides/techtalk/Ly-LLVM-libc-math-library-CurrentStatus.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=-8zb8rHbvcQ>`__
|
||||
- Project Hand-in-Hand - The beginning of a beautiful friendship - Michael Jones & Christopher Di Bella
|
||||
|
||||
* Half-precision in LLVM libc - Nicolas Celik
|
||||
- [slides](https://llvm.org/devmtg/2024-10/slides/techtalk/Jones-DiBella-hand-in-hand.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=VAEO86YtTHA)
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2024-10/slides/studenttalks/Celik-Half-precision-in-LLVM-libc.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=H6aOFSVwSSM>`__
|
||||
* `blog <https://blog.llvm.org/posts/2024-08-31-half-precision-in-llvm-libc/>`__
|
||||
- LLVM libc math library - Current status and future directions - Tue Ly
|
||||
|
||||
----
|
||||
2023
|
||||
----
|
||||
* Math functions in LLVM libc or yet another correctly rounded libm - Tue Ly
|
||||
- [slides](https://llvm.org/devmtg/2024-10/slides/techtalk/Ly-LLVM-libc-math-library-CurrentStatus.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=-8zb8rHbvcQ)
|
||||
|
||||
* `slides <https://drive.google.com/file/d/1Gchrc3AXKXAWFI1nk8Y1x8UsoQSp8XjF/view>`__
|
||||
* `video <https://www.youtube.com/watch?v=kBSJqVWNQLY>`__
|
||||
- Half-precision in LLVM libc - Nicolas Celik
|
||||
|
||||
* The LLVM C Library for GPUs - Joseph Huber
|
||||
- [slides](https://llvm.org/devmtg/2024-10/slides/studenttalks/Celik-Half-precision-in-LLVM-libc.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=H6aOFSVwSSM)
|
||||
- [blog](https://blog.llvm.org/posts/2024-08-31-half-precision-in-llvm-libc/)
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2023-10/slides/techtalks/Huber-LibCforGPUs.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=_LLGc48GYHc>`__
|
||||
## 2023
|
||||
|
||||
* The Challenges of Implementing the C Standard Library in C++ - Sivachandra Reddy
|
||||
- Math functions in LLVM libc or yet another correctly rounded libm - Tue Ly
|
||||
|
||||
* `slides <https://github.com/boostcon/cppnow_presentations_2023/blob/main/cppnow_slides/The_Challenges_of_Implementing_the_C_Standard_Library_in_Cpp.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=cuVrWUGSIgM>`__
|
||||
- [slides](https://drive.google.com/file/d/1Gchrc3AXKXAWFI1nk8Y1x8UsoQSp8XjF/view)
|
||||
- [video](https://www.youtube.com/watch?v=kBSJqVWNQLY)
|
||||
|
||||
----
|
||||
2022
|
||||
----
|
||||
* Using LLVM's libc - Sivachandra Reddy, Michael Jones, Tue Ly
|
||||
- The LLVM C Library for GPUs - Joseph Huber
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2022-11/slides/Tutorial1-UsingLLVM-libc.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=OpY4lnpnbq4>`__
|
||||
- [slides](https://llvm.org/devmtg/2023-10/slides/techtalks/Huber-LibCforGPUs.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=_LLGc48GYHc)
|
||||
|
||||
* Using modern CPU instructions to improve LLVM's libc math library - Tue Ly
|
||||
- The Challenges of Implementing the C Standard Library in C++ - Sivachandra Reddy
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2022-11/slides/QuickTalk7-UsingModernCPUInstructionsToImproveLLVM-libcMathLib>`__
|
||||
* `video <https://www.youtube.com/watch?v=9bvdbdn0nMA>`__
|
||||
- [slides](https://github.com/boostcon/cppnow_presentations_2023/blob/main/cppnow_slides/The_Challenges_of_Implementing_the_C_Standard_Library_in_Cpp.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=cuVrWUGSIgM)
|
||||
|
||||
* Approximating at Scale: How strto float in LLVM’s libc is faster - Michael Jones
|
||||
## 2022
|
||||
|
||||
- Using LLVM's libc - Sivachandra Reddy, Michael Jones, Tue Ly
|
||||
|
||||
- [slides](https://llvm.org/devmtg/2022-11/slides/Tutorial1-UsingLLVM-libc.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=OpY4lnpnbq4)
|
||||
|
||||
- Using modern CPU instructions to improve LLVM's libc math library - Tue Ly
|
||||
|
||||
- [slides](https://llvm.org/devmtg/2022-11/slides/QuickTalk7-UsingModernCPUInstructionsToImproveLLVM-libcMathLib)
|
||||
- [video](https://www.youtube.com/watch?v=9bvdbdn0nMA)
|
||||
|
||||
- Approximating at Scale: How strto float in LLVM’s libc is faster - Michael Jones
|
||||
|
||||
- [slides](https://llvm.org/devmtg/2022-11/slides/QuickTalk3-ApproximatingatScale-StringToFloat.pdf)
|
||||
- [video](https://www.youtube.com/watch?v=s-UjbTV8p6g)
|
||||
|
||||
* `slides <https://llvm.org/devmtg/2022-11/slides/QuickTalk3-ApproximatingatScale-StringToFloat.pdf>`__
|
||||
* `video <https://www.youtube.com/watch?v=s-UjbTV8p6g>`__
|
||||
|
|
|
|||
Loading…
Reference in a new issue