Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new target #118

Closed
wants to merge 7 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -1972,9 +1972,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"

[[package]]
name = "libc"
version = "0.2.116"
version = "0.2.120"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "565dbd88872dbe4cc8a46e527f26483c1d1f7afa6b884a3bd6cd893d4f98da74"
checksum = "ad5c14e80759d0939d013e6ca49930e59fc53dd8e5009132f76240c179380c09"
dependencies = [
"rustc-std-workspace-core",
]
138 changes: 122 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,110 @@
# The Rust Programming Language
# The Rust Programming Language for Espressif chips

This fork enables projects to be built for the Xtensa-based ESP32, ESP32-SXX and ESP8266 using [Espressif's llvm fork](https://github.com/espressif/llvm-project). (RiscV chips like ESP32-CXX are already supported in stock Rust.)

Moreover, this fork enables Rust STD support (networking, threads, and filesystem) for all chips in the ESP32 family (Xtensa and RiscV), by optionally linking with the ESP-IDF framework.

The [esp-rs](https://github.com/esp-rs) organization has been formed to develop runtime, pac and hal crates for the Espressif chips (bare-metal as well as ESP-IDF based).

Join in on the discussion: https://matrix.to/#/#esp-rs:matrix.org!

## Installation

Espressif offers [pre-built binaries of this fork](https://github.com/espressif/rust-esp32-example/blob/main/docs/rust-on-xtensa.md). Follow the instructions for your operating system.

## Building
Install [Rustup](https://rustup.rs/).

Build using these steps:
```sh
$ git clone https://github.com/esp-rs/rust
$ cd rust
$ git checkout esp
$ ./configure --experimental-targets=Xtensa
$ ./x.py build --stage 2
```

* **NOTE 1**: Building might take **close to an hour**
* **NOTE 2**: Make sure you are using the `esp` GIT branch of the fork (the default)
* **NOTE 3**: Do NOT rename the directory ('rust') where you've cloned the Rust fork. It must be 'rust' or you might have strange issues later on when using it. You can however place it anywhere in your file tree

### Fix toolchain vendor/ directory, so that building STD with Cargo does work

(Assuming you are still in the rust/ directory):

```sh
$ mkdir vendor
$ cd vendor
$ ln -s ../library/rustc-std-workspace-alloc/ rustc-std-workspace-alloc
$ ln -s ../library/rustc-std-workspace-core/ rustc-std-workspace-core
$ ln -s ../library/rustc-std-workspace-std/ rustc-std-workspace-std
```

Make Rustup aware of the newly built compiler:

```sh
$ rustup toolchain link esp ~/<...>/rust/build/x86_64-unknown-linux-gnu/stage2
```

Enable the new compiler in Rustup:

```sh
$ rustup target add esp
```

Check the compiler:
```sh
$ rustc --print target-list
```

At the end of the printed list of targets you should see:
```
...
xtensa-esp32-none-elf
xtensa-esp8266-none-elf
xtensa-none-elf
```

## Building LLVM clang

You'll need the custom LLVM clang based on the Espressif LLVM fork for Rust STD support. Build as follows:
```sh
$ git clone https://github.com/espressif/llvm-project
$ cd llvm-project
$ mkdir build
$ cd build
$ cmake -G Ninja -DLLVM_ENABLE_PROJECTS='clang' -DCMAKE_BUILD_TYPE=Release ../llvm
$ cmake --build .
$ export PATH=`pwd`/bin:$PATH
```

Check that you have the custom clang on your path:
```sh
$ which clang
$ which llvm-config
```

The above should output locations pointing at your custom-built clang toolchain.

* **NOTE 1**: Building LLVM clang might take **even longer** time than building the Rustc toolchain
* **NOTE 2**: You might want to make the PATH modification step from above permanent. Please make sure that the custom Clang compiler is the first on your PATH so that it takes precedence over any clang compiler you might have installed using your distro / OS

## Updating this fork

The patch set can be found [here](https://github.com/MabezDev/rust-xtensa-patches). Checkout from upstream/master, apply the patches on at a time using `git am -3 < path/to/patch.patch`, fixing any conflicts if necessary (remember to PR the changes back to the patches [repo]((https://github.com/MabezDev/rust-xtensa-patches))). Once it builds submit a PR against this repo with the branch name `esp-update-$DATE`.

If the llvm submodule needs to be updated, the following should work:

```bash
git submodule set-url src/llvm-project https://github.com/espressif/llvm-project
git submodule set-branch -b $BRANCH_NAME src/llvm-project
git submodule update --init --recursive --remote src/llvm-project
```

Once accepted, the new branch will be renamed `esp-target`, hence making it the default.
Don't worry about the README changes, I will port those across once I accept the PR.

---

This is the main source code repository for [Rust]. It contains the compiler,
standard library, and documentation.
@@ -54,7 +160,7 @@ by running it with the `--help` flag or reading the [rustc dev guide][rustcguide
* `g++` 5.1 or later or `clang++` 3.5 or later
* `python` 3 or 2.7
* GNU `make` 3.81 or later
* `cmake` 3.13.4 or later
* `cmake` 3.4.3 or later
* `ninja`
* `curl`
* `git`
@@ -64,8 +170,8 @@ by running it with the `--help` flag or reading the [rustc dev guide][rustcguide
2. Clone the [source] with `git`:

```sh
git clone https://github.com/rust-lang/rust.git
cd rust
$ git clone https://github.com/rust-lang/rust.git
$ cd rust
```

[source]: https://github.com/rust-lang/rust
@@ -77,7 +183,7 @@ by running it with the `--help` flag or reading the [rustc dev guide][rustcguide
Copy the default `config.toml.example` to `config.toml` to get started.

```sh
cp config.toml.example config.toml
$ cp config.toml.example config.toml
```

If you plan to use `x.py install` to create an installation, it is recommended
@@ -88,7 +194,7 @@ by running it with the `--help` flag or reading the [rustc dev guide][rustcguide
4. Build and install:

```sh
./x.py build && ./x.py install
$ ./x.py build && ./x.py install
```

When complete, `./x.py install` will place several programs into
@@ -113,7 +219,7 @@ build.

[MSYS2][msys2] can be used to easily build Rust on Windows:

[msys2]: https://www.msys2.org/
[msys2]: https://msys2.github.io/

1. Grab the latest [MSYS2 installer][msys2] and go through the installer.

@@ -126,15 +232,15 @@ build.

```sh
# Update package mirrors (may be needed if you have a fresh install of MSYS2)
pacman -Sy pacman-mirrors
$ pacman -Sy pacman-mirrors

# Install build tools needed for Rust. If you're building a 32-bit compiler,
# then replace "x86_64" below with "i686". If you've already got git, python,
# or CMake installed and in PATH you can remove them from this list. Note
# that it is important that you do **not** use the 'python2', 'cmake' and 'ninja'
# packages from the 'msys2' subsystem. The build has historically been known
# to fail with these packages.
pacman -S git \
$ pacman -S git \
make \
diffutils \
tar \
@@ -147,7 +253,7 @@ build.
4. Navigate to Rust's source code (or clone it), then build it:

```sh
./x.py build && ./x.py install
$ ./x.py build && ./x.py install
```

#### MSVC
@@ -165,7 +271,7 @@ With these dependencies installed, you can build the compiler in a `cmd.exe`
shell with:

```sh
python x.py build
> python x.py build
```

Currently, building Rust only works with some known versions of Visual Studio. If
@@ -174,8 +280,8 @@ you may need to force rustbuild to use an older version. This can be done
by manually calling the appropriate vcvars file before running the bootstrap.

```batch
CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
python x.py build
> CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
> python x.py build
```

#### Specifying an ABI
@@ -201,8 +307,8 @@ While it's not the recommended build system, this project also provides a
configure script and makefile (the latter of which just invokes `x.py`).

```sh
./configure
make && sudo make install
$ ./configure
$ make && sudo make install
```

When using the configure script, the generated `config.mk` file may override the
@@ -214,7 +320,7 @@ When using the configure script, the generated `config.mk` file may override the
If you’d like to build the documentation, it’s almost the same:

```sh
./x.py doc
$ ./x.py doc
```

The generated documentation will appear under `doc` in the `build` directory for
8 changes: 8 additions & 0 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
@@ -231,6 +231,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
InlineAsmArch::S390x => {}
InlineAsmArch::SpirV => {}
InlineAsmArch::Wasm32 | InlineAsmArch::Wasm64 => {}
InlineAsmArch::Xtensa => {}
InlineAsmArch::Bpf => {}
InlineAsmArch::Msp430 => {
constraints.push("~{sr}".to_string());
@@ -574,6 +575,9 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg,
) => unreachable!("clobber-only"),
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r",
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::freg) => "f",
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::breg) => "b",
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w",
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg) => "r",
@@ -627,6 +631,7 @@ fn modifier_to_llvm(
InlineAsmRegClass::Mips(_) => None,
InlineAsmRegClass::Nvptx(_) => None,
InlineAsmRegClass::PowerPC(_) => None,
InlineAsmRegClass::Xtensa(_) => None,
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg)
| InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => None,
InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => {
@@ -730,6 +735,9 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
unreachable!("clobber-only")
}
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::reg) => cx.type_i32(),
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::freg) => cx.type_f32(),
InlineAsmRegClass::Xtensa(XtensaInlineAsmRegClass::breg) => cx.type_i1(),
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(),
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(),
InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg) => cx.type_i8(),
31 changes: 31 additions & 0 deletions compiler/rustc_codegen_ssa/src/target_features.rs
Original file line number Diff line number Diff line change
@@ -225,6 +225,35 @@ const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
("nontrapping-fptoint", Some(sym::wasm_target_feature)),
];

const XTENSA_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
("fp", Some(sym::xtensa_target_feature)),
("windowed", Some(sym::xtensa_target_feature)),
("bool", Some(sym::xtensa_target_feature)),
("loop", Some(sym::xtensa_target_feature)),
("sext", Some(sym::xtensa_target_feature)),
("nsa", Some(sym::xtensa_target_feature)),
("mul32", Some(sym::xtensa_target_feature)),
("mul32high", Some(sym::xtensa_target_feature)),
("div32", Some(sym::xtensa_target_feature)),
("mac16", Some(sym::xtensa_target_feature)),
("dfpaccel", Some(sym::xtensa_target_feature)),
("s32c1i", Some(sym::xtensa_target_feature)),
("threadptr", Some(sym::xtensa_target_feature)),
("extendedl32r", Some(sym::xtensa_target_feature)),
("atomctl", Some(sym::xtensa_target_feature)),
("memctl", Some(sym::xtensa_target_feature)),
("debug", Some(sym::xtensa_target_feature)),
("exception", Some(sym::xtensa_target_feature)),
("highpriinterrupts", Some(sym::xtensa_target_feature)),
("coprocessor", Some(sym::xtensa_target_feature)),
("interrupt", Some(sym::xtensa_target_feature)),
("rvector", Some(sym::xtensa_target_feature)),
("timerint", Some(sym::xtensa_target_feature)),
("prid", Some(sym::xtensa_target_feature)),
("regprotect", Some(sym::xtensa_target_feature)),
("miscsr", Some(sym::xtensa_target_feature)),
];

const BPF_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[("alu32", Some(sym::bpf_target_feature))];

/// When rustdoc is running, provide a list of all known features so that all their respective
@@ -241,6 +270,7 @@ pub fn all_known_features() -> impl Iterator<Item = (&'static str, Option<Symbol
.chain(MIPS_ALLOWED_FEATURES.iter())
.chain(RISCV_ALLOWED_FEATURES.iter())
.chain(WASM_ALLOWED_FEATURES.iter())
.chain(XTENSA_ALLOWED_FEATURES.iter())
.chain(BPF_ALLOWED_FEATURES.iter())
.cloned()
}
@@ -255,6 +285,7 @@ pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Opt
"powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES,
"riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES,
"wasm32" | "wasm64" => WASM_ALLOWED_FEATURES,
"xtensa" => XTENSA_ALLOWED_FEATURES,
"bpf" => BPF_ALLOWED_FEATURES,
_ => &[],
}
Loading