mirror of
https://github.com/italicsjenga/gba.git
synced 2024-12-23 02:41:31 +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]
|
||||
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]
|
||||
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,
|
||||
|
|
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/instruction_inline >target/dump-instruction_inline.txt
|
||||
|
|
2
dump.sh
2
dump.sh
|
@ -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
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue