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](
|
||
|---|---|---|
| .. | ||
| ArchiveWrapper.cpp | ||
| llvm-auto-clean-trigger | ||
| PassWrapper.cpp | ||
| README | ||
| rustllvm.h | ||
| RustWrapper.cpp | ||
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.