rust/src/rustllvm
bors b7e5148bbd Auto merge of #38314 - japaric:do-not-delete-enable-llvm-backend, r=alexcrichton
initial SPARC support

### UPDATE

Can now compile `no_std` executables with:

```
$ cargo new --bin app && cd $_

$ edit Cargo.toml && tail -n2 $_
[dependencies]
core = { path = "/path/to/rust/src/libcore" }

$ edit src/main.rs && cat $_
#![feature(lang_items)]
#![no_std]
#![no_main]

#[no_mangle]
pub fn _start() -> ! {
    loop {}
}

#[lang = "panic_fmt"]
fn panic_fmt() -> ! {
    loop {}
}

$ edit sparc-none-elf.json && cat $_
{
  "arch": "sparc",
  "data-layout": "E-m:e-p:32:32-i64:64-f128:64-n32-S64",
  "executables": true,
  "llvm-target": "sparc",
  "os": "none",
  "panic-strategy": "abort",
  "target-endian": "big",
  "target-pointer-width": "32"
}

$ cargo rustc --target sparc-none-elf -- -C linker=sparc-unknown-elf-gcc -C link-args=-nostartfiles

$ file target/sparc-none-elf/debug/app
app: ELF 32-bit MSB executable, SPARC, version 1 (SYSV), statically linked, not stripped

$ sparc-unknown-elf-readelf -h target/sparc-none-elf/debug/app
ELF Header:
  Magic:   7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, big endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Sparc
  Version:                           0x1
  Entry point address:               0x10074
  Start of program headers:          52 (bytes into file)
  Start of section headers:          1188 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         2
  Size of section headers:           40 (bytes)
  Number of section headers:         14
  Section header string table index: 11

$ sparc-unknown-elf-objdump -Cd target/sparc-none-elf/debug/app

target/sparc-none-elf/debug/app:     file format elf32-sparc

Disassembly of section .text:

00010074 <_start>:
   10074:       9d e3 bf 98     save  %sp, -104, %sp
   10078:       10 80 00 02     b  10080 <_start+0xc>
   1007c:       01 00 00 00     nop
   10080:       10 80 00 02     b  10088 <_start+0x14>
   10084:       01 00 00 00     nop
   10088:       10 80 00 00     b  10088 <_start+0x14>
   1008c:       01 00 00 00     nop
```

---

Someone wants to attempt launching some Rust [into space](https://www.reddit.com/r/rust/comments/5h76oa/c_interop/) but their platform is based on the SPARCv8 architecture. Let's not block them by enabling LLVM's SPARC backend.

Something very important that they'll also need is the "cabi" stuff as they'll be embedding some Rust code into a bigger C application (i.e. heavy use of `extern "C"`). The question there is what name(s) should we use for "target_arch" as the "cabi" implementation [varies according to that parameter](https://github.com/rust-lang/rust/blob/1.13.0/src/librustc_trans/abi.rs#L498-L523).

AFAICT, SPARCv8 is a 32-bit architecture and SPARCv9 is a 64-bit architecture. And, LLVM uses `sparc`, `sparcv9` and `sparcel` for [the architecture triple](ac1c94226e/include/llvm/ADT/Triple.h (L67-L69)) so perhaps we should use `target_arch = "sparc"` (32-bit) and `target_arch = "sparcv9"` (64-bit) as well.

r? @alexcrichton This PR only enables this LLVM backend when rustbuild is used. Do I also need to implement this for the old Makefile-based build system? Or are all our nightlies now being generated using rustbuild?

cc @brson
2016-12-26 20:48:43 +00:00
..
ArchiveWrapper.cpp [LLVM 4.0] Explicitly call constructor of 'llvm::Error' 2016-12-11 22:44:19 +13:00
llvm-auto-clean-trigger touch src/rustllvm/llvm-auto-clean-trigger 2016-12-19 12:23:56 -05:00
PassWrapper.cpp printf type correctness 2016-12-07 17:09:34 +01:00
README audit LLVM C++ types in ArchiveWrapper and PassWrapper 2016-08-03 15:08:47 +03:00
rustllvm.h Fixed fastcall not applying inreg attributes to arguments like the C/C++ fastcall. 2016-12-21 21:44:40 +03:00
RustWrapper.cpp Fixed fastcall not applying inreg attributes to arguments like the C/C++ fastcall. 2016-12-21 21:44:40 +03:00

This directory currently contains some LLVM support code. This will generally
be sent upstream to LLVM in time; for now it lives here.

NOTE: the LLVM C++ ABI is subject to between-version breakage and must *never*
be exposed to Rust. To allow for easy auditing of that, all Rust-exposed types
must be typedef-ed as "LLVMXyz", or "LLVMRustXyz" if they were defined here.

Functions that return a failure status and leave the error in
the LLVM last error should return an LLVMRustResult rather than an
int or anything to avoid confusion.

When translating enums, add a single `Other` variant as the first
one to allow for new variants to be added. It should abort when used
as an input.

All other types must not be typedef-ed as such.