mirror of
https://github.com/italicsjenga/gba.git
synced 2024-12-23 10:51:30 +11:00
cleanup, make MIR inlining work in dev
This commit is contained in:
parent
6ba28c5347
commit
5de0f5e9f2
|
@ -6,4 +6,4 @@ build-std = ["core"]
|
||||||
|
|
||||||
[target.thumbv4t-none-eabi]
|
[target.thumbv4t-none-eabi]
|
||||||
runner = "mgba-qt"
|
runner = "mgba-qt"
|
||||||
rustflags = ["-Clink-arg=-Tlinker_scripts/mono_boot.ld"]
|
rustflags = ["-Clink-arg=-Tlinker_scripts/mono_boot.ld", "--emit=mir"]
|
||||||
|
|
|
@ -13,12 +13,18 @@ track_caller = []
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitfrob = "0.2.3"
|
bitfrob = "0.2.3"
|
||||||
voladdress = { version = "1.2.1", features = ["experimental_volregion"] }
|
voladdress = { version = "1.2.1", features = ["experimental_volregion"] }
|
||||||
|
bracer = "0.1"
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
incremental = false
|
||||||
|
|
||||||
|
[profile.dev.package."*"]
|
||||||
|
debug-assertions = false
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
incremental = false
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
# The crate can only be built for targets that have thumb-interworking support,
|
# The crate can only be built for targets that have thumb-interworking support,
|
||||||
|
|
2
dump.bat
2
dump.bat
|
@ -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/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
|
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
|
||||||
|
|
2
dump.sh
2
dump.sh
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/sh
|
#!/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/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
|
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
|
||||||
|
|
|
@ -8,12 +8,16 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! {
|
||||||
loop {}
|
loop {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#[inline(always)]
|
||||||
#[instruction_set(arm::a32)]
|
#[instruction_set(arm::a32)]
|
||||||
fn make_3rd_bg_pal_entry_black() {
|
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]
|
#[no_mangle]
|
||||||
|
#[instruction_set(arm::t32)]
|
||||||
extern "C" fn main() -> ! {
|
extern "C" fn main() -> ! {
|
||||||
make_3rd_bg_pal_entry_black();
|
make_3rd_bg_pal_entry_black();
|
||||||
loop {}
|
loop {}
|
||||||
|
|
|
@ -18,169 +18,7 @@ use crate::{
|
||||||
mgba::MGBA_LOGGING_ENABLE_REQUEST,
|
mgba::MGBA_LOGGING_ENABLE_REQUEST,
|
||||||
mmio::{DMA3_SRC, IME, MGBA_LOG_ENABLE},
|
mmio::{DMA3_SRC, IME, MGBA_LOG_ENABLE},
|
||||||
};
|
};
|
||||||
|
use bracer::*;
|
||||||
/// 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"),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The function pointer that the assembly runtime calls when an interrupt
|
/// The function pointer that the assembly runtime calls when an interrupt
|
||||||
/// occurs.
|
/// occurs.
|
||||||
|
@ -296,7 +134,7 @@ unsafe extern "C" fn runtime_irq_handler() {
|
||||||
"ldr r1, ={RUST_IRQ_HANDLER}",
|
"ldr r1, ={RUST_IRQ_HANDLER}",
|
||||||
"ldr r1, [r1]",
|
"ldr r1, [r1]",
|
||||||
when!("r1" != "#0" [label_id=9] {
|
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),
|
set_cpu_control!(System, irq_masked: false, fiq_masked: false),
|
||||||
|
|
||||||
// Note(Lokathor): We are *SKIPPING* the part where we ensure that the
|
// Note(Lokathor): We are *SKIPPING* the part where we ensure that the
|
||||||
|
|
Loading…
Reference in a new issue