Skip to content

Commit

Permalink
Get rid of inline assembly
Browse files Browse the repository at this point in the history
  • Loading branch information
Disasm committed Jan 26, 2019
1 parent 6729dee commit 19251b8
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 99 deletions.
89 changes: 89 additions & 0 deletions asm.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
Entry point of all programs (_start).

It initializes DWARF call frame information, the stack pointer, the
frame pointer (needed for closures to work in start_rust) and the global
pointer. Then it calls _start_rust.
*/

.section .init, "ax"
.global _start

_start:
.cfi_startproc
.cfi_undefined ra

// .option push
// .option norelax
lui gp, %hi(__global_pointer$)
addi gp, gp, %lo(__global_pointer$)
// .option pop

lui sp, %hi(_stack_start)
addi sp, sp, %lo(_stack_start)

add s0, sp, zero

jal zero, _start_rust

.cfi_endproc


/*
Trap entry point (_start_trap)

Saves caller saved registers ra, t0..6, a0..7, calls _start_trap_rust,
restores caller saved registers and then returns.
*/
.section .trap, "ax"
.align 4
.global _start_trap

_start_trap:
addi sp, sp, -16*4

sw ra, 0*4(sp)
sw t0, 1*4(sp)
sw t1, 2*4(sp)
sw t2, 3*4(sp)
sw t3, 4*4(sp)
sw t4, 5*4(sp)
sw t5, 6*4(sp)
sw t6, 7*4(sp)
sw a0, 8*4(sp)
sw a1, 9*4(sp)
sw a2, 10*4(sp)
sw a3, 11*4(sp)
sw a4, 12*4(sp)
sw a5, 13*4(sp)
sw a6, 14*4(sp)
sw a7, 15*4(sp)

jal ra, _start_trap_rust

lw ra, 0*4(sp)
lw t0, 1*4(sp)
lw t1, 2*4(sp)
lw t2, 3*4(sp)
lw t3, 4*4(sp)
lw t4, 5*4(sp)
lw t5, 6*4(sp)
lw t6, 7*4(sp)
lw a0, 8*4(sp)
lw a1, 9*4(sp)
lw a2, 10*4(sp)
lw a3, 11*4(sp)
lw a4, 12*4(sp)
lw a5, 13*4(sp)
lw a6, 14*4(sp)
lw a7, 15*4(sp)

addi sp, sp, 16*4
mret


/* Make sure there is an abort when linking */
.section .init
.globl abort
abort:
jal zero, _start
14 changes: 14 additions & 0 deletions assemble.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

set -euxo pipefail

crate=riscv-rt

# remove existing blobs because otherwise this will append object files to the old blobs
rm -f bin/*.a

riscv64-unknown-elf-gcc -c -mabi=ilp32 -march=rv32imac asm.S -o bin/$crate.o
ar crs bin/riscv32imac-unknown-none-elf.a bin/$crate.o
cp bin/riscv32imac-unknown-none-elf.a bin/riscv32imc-unknown-none-elf.a

rm bin/$crate.o
Binary file added bin/riscv32imac-unknown-none-elf.a
Binary file not shown.
Binary file added bin/riscv32imc-unknown-none-elf.a
Binary file not shown.
21 changes: 17 additions & 4 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
// NOTE: Adapted from cortex-m/build.rs
use std::env;
use std::fs::File;
use std::fs;
use std::io::Write;
use std::path::PathBuf;

fn main() {
let target = env::var("TARGET").unwrap();
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let name = env::var("CARGO_PKG_NAME").unwrap();

if target.starts_with("riscv") {
fs::copy(
format!("bin/{}.a", target),
out_dir.join(format!("lib{}.a", name)),
).unwrap();

println!("cargo:rustc-link-lib=static={}", name);
println!("cargo:rustc-link-search={}", out_dir.display());
}

// Put the linker script somewhere the linker can find it
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
File::create(out.join("link.x"))
fs::File::create(out_dir.join("link.x"))
.unwrap()
.write_all(include_bytes!("link.x"))
.unwrap();
println!("cargo:rustc-link-search={}", out.display());
println!("cargo:rustc-link-search={}", out_dir.display());

println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=link.x");
Expand Down
21 changes: 21 additions & 0 deletions check-blobs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash

# Checks that the blobs are up to date with the committed assembly files

set -euxo pipefail

for lib in $(ls bin/*.a); do
filename=$(basename $lib)
riscv64-unknown-elf-objdump -Cd $lib > bin/${filename%.a}.before
done

./assemble.sh

for lib in $(ls bin/*.a); do
filename=$(basename $lib)
riscv64-unknown-elf-objdump -Cd $lib > bin/${filename%.a}.after
done

for cksum in $(ls bin/*.after); do
diff -u $cksum ${cksum%.after}.before
done
95 changes: 0 additions & 95 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,8 @@
#![no_std]
#![deny(missing_docs)]
#![deny(warnings)]
#![feature(asm)]
#![feature(compiler_builtins_lib)]
#![feature(const_fn)]
#![feature(global_asm)]
#![feature(linkage)]

extern crate riscv;
Expand All @@ -192,36 +190,6 @@ extern "C" {
}


/// Entry point of all programs (_start).
///
/// It initializes DWARF call frame information, the stack pointer, the
/// frame pointer (needed for closures to work in start_rust) and the global
/// pointer. Then it calls _start_rust.
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
global_asm!(r#"
.section .init, "ax"
.globl _start
_start:
.cfi_startproc
.cfi_undefined ra
// .option push
// .option norelax
lui gp, %hi(__global_pointer$)
addi gp, gp, %lo(__global_pointer$)
// .option pop
lui sp, %hi(_stack_start)
addi sp, sp, %lo(_stack_start)
add s0, sp, zero
jal zero, _start_rust
.cfi_endproc
"#);


/// Rust entry point (_start_rust)
///
/// Zeros bss section, initializes data section and calls main. This function
Expand Down Expand Up @@ -275,60 +243,6 @@ macro_rules! entry {
}


/// Trap entry point (_start_trap)
///
/// Saves caller saved registers ra, t0..6, a0..7, calls _start_trap_rust,
/// restores caller saved registers and then returns.
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
global_asm!(r#"
.section .trap, "ax"
.align 4
.global _start_trap
_start_trap:
addi sp, sp, -16*4
sw ra, 0*4(sp)
sw t0, 1*4(sp)
sw t1, 2*4(sp)
sw t2, 3*4(sp)
sw t3, 4*4(sp)
sw t4, 5*4(sp)
sw t5, 6*4(sp)
sw t6, 7*4(sp)
sw a0, 8*4(sp)
sw a1, 9*4(sp)
sw a2, 10*4(sp)
sw a3, 11*4(sp)
sw a4, 12*4(sp)
sw a5, 13*4(sp)
sw a6, 14*4(sp)
sw a7, 15*4(sp)
jal ra, _start_trap_rust
lw ra, 0*4(sp)
lw t0, 1*4(sp)
lw t1, 2*4(sp)
lw t2, 3*4(sp)
lw t3, 4*4(sp)
lw t4, 5*4(sp)
lw t5, 6*4(sp)
lw t6, 7*4(sp)
lw a0, 8*4(sp)
lw a1, 9*4(sp)
lw a2, 10*4(sp)
lw a3, 11*4(sp)
lw a4, 12*4(sp)
lw a5, 13*4(sp)
lw a6, 14*4(sp)
lw a7, 15*4(sp)
addi sp, sp, 16*4
mret
"#);


/// Trap entry point rust (_start_trap_rust)
///
/// mcause is read to determine the cause of the trap. XLEN-1 bit indicates
Expand All @@ -351,12 +265,3 @@ pub extern "C" fn start_trap_rust() {
#[no_mangle]
#[linkage = "weak"]
pub fn trap_handler(_: mcause::Trap) {}

// Make sure there is an abort when linking
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
global_asm!(r#"
.section .init
.globl abort
abort:
jal zero, _start
"#);

0 comments on commit 19251b8

Please sign in to comment.