From 2e505ecbc9c86078780394f88d8ff831cd514d3d Mon Sep 17 00:00:00 2001 From: Christopher Swenson Date: Fri, 22 Nov 2024 13:37:38 -0800 Subject: [PATCH] Compile with unaligned-scalar-mem feature (#29) This optimizes memory reads and writes so that they don't have to be aligned, as this is not required for our CPU. This saves abot 3 KB of instruction space in the runtime binary. The VeeR CPU also supports bit manipulation instructions, but we don't have complete support for those in the emulator, so I left that as a TODO. That saves a few hundred bytes more (for now). --- .cargo/config.toml | 6 +++++- xtask/src/apps_build.rs | 12 +++++++----- xtask/src/rom.rs | 7 ++++++- xtask/src/runtime_build.rs | 22 +++++++++++++--------- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/.cargo/config.toml b/.cargo/config.toml index 1db5b21..e22b703 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -4,4 +4,8 @@ xtask = "run --package xtask --" [target.riscv32imc-unknown-none-elf] -rustflags = ["-C", "panic=abort"] +rustflags = [ + "-C panic=abort", + "-C target-feature=+relax,+unaligned-scalar-mem", + "-C force-frame-pointers=no" +] diff --git a/xtask/src/apps_build.rs b/xtask/src/apps_build.rs index 540b5ea..57760c5 100644 --- a/xtask/src/apps_build.rs +++ b/xtask/src/apps_build.rs @@ -1,6 +1,6 @@ // Licensed under the Apache-2.0 license -use crate::runtime_build::{objcopy, target_binary, OBJCOPY_FLAGS}; +use crate::runtime_build::{objcopy, target_binary, OBJCOPY_FLAGS, RUSTFLAGS_COMMON}; use crate::tbf::TbfHeader; use crate::{DynError, PROJECT_ROOT, TARGET}; use std::process::Command; @@ -114,12 +114,14 @@ INCLUDE runtime/apps/app_layout.ld", ), )?; + let ld_flag = format!("-C link-arg=-T{}", layout_ld.display()); + let mut rustc_flags = Vec::from(RUSTFLAGS_COMMON); + rustc_flags.push(ld_flag.as_str()); + let rustc_flags = rustc_flags.join(" "); + let status = Command::new("cargo") .current_dir(&*PROJECT_ROOT) - .env( - "RUSTFLAGS", - format!("-C link-arg=-T{}", layout_ld.display()), - ) + .env("RUSTFLAGS", rustc_flags) .env("LIBTOCK_LINKER_FLASH", format!("0x{:x}", offset)) .env("LIBTOCK_LINKER_FLASH_LENGTH", "128K") .env("LIBTOCK_LINKER_RAM", "0x50000000") diff --git a/xtask/src/rom.rs b/xtask/src/rom.rs index 8550388..e6291a1 100644 --- a/xtask/src/rom.rs +++ b/xtask/src/rom.rs @@ -1,12 +1,17 @@ // Licensed under the Apache-2.0 license +use crate::runtime_build::RUSTFLAGS_COMMON; use crate::{runtime_build::objcopy, DynError, PROJECT_ROOT, TARGET}; use std::process::Command; pub fn rom_build() -> Result<(), DynError> { + let mut rustc_flags = Vec::from(RUSTFLAGS_COMMON); + rustc_flags.push("-C link-arg=-Trom/layout.ld"); + let rustc_flags = rustc_flags.join(" "); + let status = Command::new("cargo") .current_dir(&*PROJECT_ROOT) - .env("RUSTFLAGS", "-C link-arg=-Trom/layout.ld") + .env("RUSTFLAGS", rustc_flags) .args(["b", "-p", "rom", "--release", "--target", TARGET]) .status()?; if !status.success() { diff --git a/xtask/src/runtime_build.rs b/xtask/src/runtime_build.rs index 30f9296..6e47caa 100644 --- a/xtask/src/runtime_build.rs +++ b/xtask/src/runtime_build.rs @@ -19,6 +19,13 @@ const RAM_START: usize = 0x5000_0000; const RAM_SIZE: usize = 128 * 1024; const BSS_SIZE: usize = 5000; // this is approximate. Increase it is there are "sram" errors when linking +// TODO: Add +b/+zb* features when the emulator supports the extra bit manipulation instructions +// This saves several hundred bytes of instruction space, and the VeeR core supports them. +pub const RUSTFLAGS_COMMON: [&str; 2] = [ + "-C target-feature=+relax,+unaligned-scalar-mem", + "-C force-frame-pointers=no", +]; + pub fn target_binary(name: &str) -> PathBuf { PROJECT_ROOT .join("target") @@ -133,21 +140,18 @@ INCLUDE runtime/kernel_layout.ld // - `-C symbol-mangling-version=v0`: Opt-in to Rust v0 symbol mangling scheme. // See https://github.com/rust-lang/rust/issues/60705 and // https://github.com/tock/tock/issues/3529. - let rustc_flags = [ - format!("-C link-arg=-T{}", ld_file_path.display()).as_str(), + let ld_arg = format!("-C link-arg=-T{}", ld_file_path.display()); + let mut rustc_flags = Vec::from(RUSTFLAGS_COMMON); + rustc_flags.extend_from_slice(&[ + ld_arg.as_str(), "-C linker=rust-lld", "-C linker-flavor=ld.lld", "-C relocation-model=static", "-C link-arg=-nmagic", // don't page align sections, link against static libs "-C link-arg=-icf=all", // identical code folding "-C symbol-mangling-version=v0", - // RISC-V-specific flags. - "-C force-frame-pointers=no", - // Ensure relocations generated is eligible for linker relaxation. - // This provide huge space savings. - "-C target-feature=+relax", - ] - .join(" "); + ]); + let rustc_flags = rustc_flags.join(" "); // RUSTC_FLAGS_TOCK by default extends RUSTC_FLAGS with options that are global // to all Tock boards.