cleanup, make MIR inlining work in dev

This commit is contained in:
Lokathor 2022-12-01 19:13:31 -07:00
parent 6ba28c5347
commit 5de0f5e9f2
6 changed files with 16 additions and 168 deletions

View file

@ -6,4 +6,4 @@ build-std = ["core"]
[target.thumbv4t-none-eabi]
runner = "mgba-qt"
rustflags = ["-Clink-arg=-Tlinker_scripts/mono_boot.ld"]
rustflags = ["-Clink-arg=-Tlinker_scripts/mono_boot.ld", "--emit=mir"]

View file

@ -13,12 +13,18 @@ track_caller = []
[dependencies]
bitfrob = "0.2.3"
voladdress = { version = "1.2.1", features = ["experimental_volregion"] }
bracer = "0.1"
[profile.dev]
opt-level = 3
incremental = false
[profile.dev.package."*"]
debug-assertions = false
[profile.release]
codegen-units = 1
incremental = false
[package.metadata.docs.rs]
# The crate can only be built for targets that have thumb-interworking support,

View file

@ -1,3 +1,3 @@
cargo build --examples
cargo build --examples --verbose
arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std target/thumbv4t-none-eabi/debug/examples/hello >target/dump-hello.txt
arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std target/thumbv4t-none-eabi/debug/examples/instruction_inline >target/dump-instruction_inline.txt

View file

@ -1,4 +1,4 @@
#!/bin/sh
cargo build --examples
cargo build --examples --verbose
arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std target/thumbv4t-none-eabi/debug/examples/hello >target/dump-hello.txt
arm-none-eabi-objdump --headers --disassemble --demangle --architecture=armv4t --no-show-raw-insn -Mreg-names-std target/thumbv4t-none-eabi/debug/examples/instruction_inline >target/dump-instruction_inline.txt

View file

@ -8,12 +8,16 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! {
loop {}
}
//#[inline(always)]
#[instruction_set(arm::a32)]
fn make_3rd_bg_pal_entry_black() {
BG_PALETTE.index(3).write(Color::new());
let x: u16;
unsafe { core::arch::asm!("movs {}, #0", out(reg) x) };
BG_PALETTE.index(3).write(Color(x));
}
#[no_mangle]
#[instruction_set(arm::t32)]
extern "C" fn main() -> ! {
make_3rd_bg_pal_entry_black();
loop {}

View file

@ -18,169 +18,7 @@ use crate::{
mgba::MGBA_LOGGING_ENABLE_REQUEST,
mmio::{DMA3_SRC, IME, MGBA_LOG_ENABLE},
};
/// Builds an assembly string that puts the contained code in the section
/// specified.
///
/// ```txt
/// put_code_in_section!( ".example.section", {
/// "lines"
/// "go"
/// "here"
/// });
/// ```
macro_rules! put_code_in_section {
($section_name:expr, {
$($asm_line:expr),+ $(,)?
}) => {
concat!(
concat!(".section ", $section_name, "\n"),
$( concat!($asm_line, "\n") ),+ ,
concat!(".previous\n"),
)
}
}
/// Builds an assembly string wrapped in `.code 32` and `.code 16` as necessary
///
/// ```txt
/// emit_a32_code!{
/// "lines"
/// "go"
/// "here"
/// };
/// ```
#[cfg(target_feature = "thumb-mode")]
macro_rules! emit_a32_code {
($($asm_line:expr),+ $(,)?) => {
concat!(
concat!(".code 32\n"),
$( concat!($asm_line, "\n") ),+ ,
concat!(".code 16\n"),
)
}
}
/// Builds an assembly string wrapped in `.code 32` and `.code 16` as necessary
///
/// ```txt
/// emit_a32_code!{
/// "lines"
/// "go"
/// "here"
/// };
/// ```
#[cfg(not(target_feature = "thumb-mode"))]
macro_rules! emit_a32_code {
($($asm_line:expr),+ $(,)?) => {
concat!(
$( concat!($asm_line, "\n") ),+ ,
)
}
}
/// Builds an assembly string that pushes some regs, does the body, then pops
/// the regs.
///
/// The `reglist` expression should include the appropriate level of braces for
/// the enclosing assembly block (two for normal asm, or one for raw asm).
///
/// ```txt
/// with_pushed_registers!( "reglist", {
/// "lines"
/// "go"
/// "here"
/// });
/// ```
macro_rules! with_pushed_registers {
($reglist:expr, {
$($asm_line:expr),* $(,)?
}) => {
concat!(
concat!("push ", $reglist, "\n"),
$( concat!($asm_line, "\n") ),* ,
concat!("pop ", $reglist, "\n"),
)
}
}
/// Reads SPSR into the register named, does the block, and writes the same
/// register back to SPSR.
macro_rules! with_spsr_held_in {
($reg:literal {
$($asm_line:expr),* $(,)?
}) => {
concat!(
concat!("mrs ", $reg, ", SPSR\n"),
$( concat!($asm_line, "\n") ),* ,
concat!("msr SPSR, ", $reg, "\n"),
)
}
}
/// Sets `lr` to just after the `bx`, then uses `bx` with the given register.
///
/// This generates a label, so pick a `label_id` that won't interfere with any
/// nearby code.
macro_rules! adr_lr_then_bx_to {
(reg=$reg_name:expr, label_id=$label:expr) => {
concat!(
concat!("adr lr, ", $label, "f\n"),
concat!("bx ", $reg_name, "\n"),
concat!($label, ":\n"),
)
};
}
/// Expands to the asm line to set the control bits of CPSR.
///
/// * Can only be used in `a32`
/// * Only sets the control bits, all other bits (eg: flag bits) are unchanged.
///
/// Currently, not all possible patterns are covered by this macro, just the
/// patterns needed by this runtime when it was written. In general, any of the
/// five CPU modes can be combined with irq and fiq masking each being either
/// off or on. If a desired combination is missing just add it.
macro_rules! set_cpu_control {
// CPSR low bits are: `I F T MMMMM`, and T must always be left as 0.
// * 0b10011: Supervisor (SVC)
// * 0b11111: System (SYS)
(System, irq_masked: false, fiq_masked: false) => {
"msr CPSR_c, #0b00011111\n"
};
(Supervisor, irq_masked: true, fiq_masked: false) => {
"msr CPSR_c, #0b10010010\n"
};
}
/// Performs the appropriate test, then either runs the block or jumps past it,
/// depending on the test result.
///
/// Currently supports:
/// * `$reg == $op2`
/// * `$reg != $op2`
macro_rules! when {
($reg:literal == $op2:literal [label_id=$label:literal] {
$($asm_line:expr),* $(,)?
}) => {
concat!(
concat!("cmp ", $reg, ", ", $op2, "\n"),
concat!("bne ", $label, "f\n"),
$( concat!($asm_line, "\n") ),* ,
concat!($label, ":\n"),
)
};
($reg:literal != $op2:literal [label_id=$label:literal] {
$($asm_line:expr),* $(,)?
}) => {
concat!(
concat!("cmp ", $reg, ", ", $op2, "\n"),
concat!("beq ", $label, "f\n"),
$( concat!($asm_line, "\n") ),* ,
concat!($label, ":\n"),
)
};
}
use bracer::*;
/// The function pointer that the assembly runtime calls when an interrupt
/// occurs.
@ -296,7 +134,7 @@ unsafe extern "C" fn runtime_irq_handler() {
"ldr r1, ={RUST_IRQ_HANDLER}",
"ldr r1, [r1]",
when!("r1" != "#0" [label_id=9] {
with_spsr_held_in!("r2" {
with_spsr_held_in!("r2", {
set_cpu_control!(System, irq_masked: false, fiq_masked: false),
// Note(Lokathor): We are *SKIPPING* the part where we ensure that the