Skip to content

Commit

Permalink
Adjust stack alignment to 4-byte for E base ISAs
Browse files Browse the repository at this point in the history
  • Loading branch information
romancardenas committed Dec 4, 2024
1 parent ef18149 commit aee2106
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 14 deletions.
2 changes: 1 addition & 1 deletion riscv-rt/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Changed

- Limit rustc cfg flags to `riscvi`, `riscve`, `riscvm`, `riscvf`, and `riscvd`.
- Limit rustc cfg flags to `riscvi`, `riscvm`, `riscvf`, and `riscvd`.
- Temporary use of `RISCV_RT_LLVM_ARCH_PATCH` environment variable to include the
temporary patch required for avoid LLVM spurious errors.
- `riscv-rt` now use the `RISCV_RT_BASE_ISA` environment variable to configure the behavior
Expand Down
2 changes: 1 addition & 1 deletion riscv-rt/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use riscv_target_parser::RiscvTarget;
use std::{env, fs, io, path::PathBuf};

// List of all possible RISC-V configurations to check for in risv-rt
const RISCV_CFG: [&str; 5] = ["riscvi", "riscve", "riscvm", "riscvf", "riscvd"];
const RISCV_CFG: [&str; 4] = ["riscvi", "riscvm", "riscvf", "riscvd"];

fn add_linker_script(arch_width: u32) -> io::Result<()> {
// Read the file to a string and replace all occurrences of ${ARCH_WIDTH} with the arch width
Expand Down
28 changes: 20 additions & 8 deletions riscv-rt/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,21 +383,21 @@ impl RiscvArch {
}
}

fn width(&self) -> usize {
const fn width(&self) -> usize {
match self {
Self::Rv32I | Self::Rv32E => 4,
Self::Rv64I | Self::Rv64E => 8,
}
}

fn store(&self) -> &str {
const fn store(&self) -> &str {
match self {
Self::Rv32I | Self::Rv32E => "sw",
Self::Rv64I | Self::Rv64E => "sd",
}
}

fn load(&self) -> &str {
const fn load(&self) -> &str {
match self {
Self::Rv32I | Self::Rv32E => "lw",
Self::Rv64I | Self::Rv64E => "ld",
Expand All @@ -410,10 +410,21 @@ impl RiscvArch {
"ra", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "a0", "a1", "a2", "a3", "a4", "a5",
"a6", "a7",
],
Self::Rv32E => vec![
"ra", "t0", "t1", "t2", "a0", "a1", "a2", "a3", "a4", "a5", "_r0", "_r1",
],
Self::Rv64E => vec!["ra", "t0", "t1", "t2", "a0", "a1", "a2", "a3", "a4", "a5"],
Self::Rv32E | Self::Rv64E => {
vec!["ra", "t0", "t1", "t2", "a0", "a1", "a2", "a3", "a4", "a5"]
}
}
}

/// Standard RISC-V ABI requires the stack to be 16-byte aligned.
/// However, in LLVM, for RV32E and RV64E, the stack must be 4-byte aligned
/// to be compatible with the implementation of ilp32e in GCC
///
/// Related: https://llvm.org/docs/RISCVUsage.html
const fn byte_alignment(&self) -> usize {
match self {
Self::Rv32E | Self::Rv64E => 4,
_ => 16,
}
}
}
Expand Down Expand Up @@ -474,8 +485,9 @@ pub fn weak_start_trap(_input: TokenStream) -> TokenStream {

let width = arch.width();
let trap_size = arch.trap_frame().len();
let byte_alignment = arch.byte_alignment();
// ensure we do not break that sp is 16-byte aligned
if (trap_size * width) % 16 != 0 {
if (trap_size * width) % byte_alignment != 0 {
return parse::Error::new(Span::call_site(), "Trap frame size must be 16-byte aligned")
.to_compile_error()
.into();
Expand Down
4 changes: 0 additions & 4 deletions riscv-rt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,10 +600,6 @@ pub struct TrapFrame {
#[cfg(riscvi)]
/// `x17`: argument register `a7`. Used to pass the eighth argument to a function.
pub a7: usize,
#[cfg(all(target_arch = "riscv32", not(riscvi), riscve))]
_reserved0: usize,
#[cfg(all(target_arch = "riscv32", not(riscvi), riscve))]
_reserved1: usize,
}

/// Trap entry point rust (_start_trap_rust)
Expand Down

0 comments on commit aee2106

Please sign in to comment.