Skip to content

Commit aee2106

Browse files
committed
Adjust stack alignment to 4-byte for E base ISAs
1 parent ef18149 commit aee2106

File tree

4 files changed

+22
-14
lines changed

4 files changed

+22
-14
lines changed

riscv-rt/CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
99

1010
### Changed
1111

12-
- Limit rustc cfg flags to `riscvi`, `riscve`, `riscvm`, `riscvf`, and `riscvd`.
12+
- Limit rustc cfg flags to `riscvi`, `riscvm`, `riscvf`, and `riscvd`.
1313
- Temporary use of `RISCV_RT_LLVM_ARCH_PATCH` environment variable to include the
1414
temporary patch required for avoid LLVM spurious errors.
1515
- `riscv-rt` now use the `RISCV_RT_BASE_ISA` environment variable to configure the behavior

riscv-rt/build.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use riscv_target_parser::RiscvTarget;
44
use std::{env, fs, io, path::PathBuf};
55

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

99
fn add_linker_script(arch_width: u32) -> io::Result<()> {
1010
// Read the file to a string and replace all occurrences of ${ARCH_WIDTH} with the arch width

riscv-rt/macros/src/lib.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -383,21 +383,21 @@ impl RiscvArch {
383383
}
384384
}
385385

386-
fn width(&self) -> usize {
386+
const fn width(&self) -> usize {
387387
match self {
388388
Self::Rv32I | Self::Rv32E => 4,
389389
Self::Rv64I | Self::Rv64E => 8,
390390
}
391391
}
392392

393-
fn store(&self) -> &str {
393+
const fn store(&self) -> &str {
394394
match self {
395395
Self::Rv32I | Self::Rv32E => "sw",
396396
Self::Rv64I | Self::Rv64E => "sd",
397397
}
398398
}
399399

400-
fn load(&self) -> &str {
400+
const fn load(&self) -> &str {
401401
match self {
402402
Self::Rv32I | Self::Rv32E => "lw",
403403
Self::Rv64I | Self::Rv64E => "ld",
@@ -410,10 +410,21 @@ impl RiscvArch {
410410
"ra", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "a0", "a1", "a2", "a3", "a4", "a5",
411411
"a6", "a7",
412412
],
413-
Self::Rv32E => vec![
414-
"ra", "t0", "t1", "t2", "a0", "a1", "a2", "a3", "a4", "a5", "_r0", "_r1",
415-
],
416-
Self::Rv64E => vec!["ra", "t0", "t1", "t2", "a0", "a1", "a2", "a3", "a4", "a5"],
413+
Self::Rv32E | Self::Rv64E => {
414+
vec!["ra", "t0", "t1", "t2", "a0", "a1", "a2", "a3", "a4", "a5"]
415+
}
416+
}
417+
}
418+
419+
/// Standard RISC-V ABI requires the stack to be 16-byte aligned.
420+
/// However, in LLVM, for RV32E and RV64E, the stack must be 4-byte aligned
421+
/// to be compatible with the implementation of ilp32e in GCC
422+
///
423+
/// Related: https://llvm.org/docs/RISCVUsage.html
424+
const fn byte_alignment(&self) -> usize {
425+
match self {
426+
Self::Rv32E | Self::Rv64E => 4,
427+
_ => 16,
417428
}
418429
}
419430
}
@@ -474,8 +485,9 @@ pub fn weak_start_trap(_input: TokenStream) -> TokenStream {
474485

475486
let width = arch.width();
476487
let trap_size = arch.trap_frame().len();
488+
let byte_alignment = arch.byte_alignment();
477489
// ensure we do not break that sp is 16-byte aligned
478-
if (trap_size * width) % 16 != 0 {
490+
if (trap_size * width) % byte_alignment != 0 {
479491
return parse::Error::new(Span::call_site(), "Trap frame size must be 16-byte aligned")
480492
.to_compile_error()
481493
.into();

riscv-rt/src/lib.rs

-4
Original file line numberDiff line numberDiff line change
@@ -600,10 +600,6 @@ pub struct TrapFrame {
600600
#[cfg(riscvi)]
601601
/// `x17`: argument register `a7`. Used to pass the eighth argument to a function.
602602
pub a7: usize,
603-
#[cfg(all(target_arch = "riscv32", not(riscvi), riscve))]
604-
_reserved0: usize,
605-
#[cfg(all(target_arch = "riscv32", not(riscvi), riscve))]
606-
_reserved1: usize,
607603
}
608604

609605
/// Trap entry point rust (_start_trap_rust)

0 commit comments

Comments
 (0)