Skip to content

Commit 093146f

Browse files
authored
Using asm and global_asm from core::arch module. (#157)
* Using asm and global_asm from core::arch module. * Commenting out some broken code with higher registers.
1 parent 42e2836 commit 093146f

File tree

6 files changed

+75
-65
lines changed

6 files changed

+75
-65
lines changed

src/bios.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#[allow(unused)]
1212
use crate::prelude::*;
1313

14+
use core::arch::asm;
15+
1416
/// (`swi 0x00`) Performs a "soft reset" of the device.
1517
///
1618
/// Loads `r14` based on the `u8` value at `0x0300_7FFA`:

src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![no_std]
2-
#![feature(asm, global_asm, isa_attribute)]
2+
#![feature(isa_attribute)]
33

44
//! This crate helps you write GBA ROMs.
55
//!
@@ -31,11 +31,11 @@ pub mod prelude {
3131
#[cfg(target_arch = "arm")]
3232
pub use crate::mmio_addresses::*;
3333
#[cfg(target_arch = "arm")]
34+
pub use crate::random::*;
35+
#[cfg(target_arch = "arm")]
3436
pub use crate::save::*;
3537
#[cfg(target_arch = "arm")]
3638
pub use crate::sync::*;
37-
#[cfg(target_arch = "arm")]
38-
pub use crate::random::*;
3939
}
4040

4141
pub mod mmio_types;

src/mmio_addresses/mode3.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::prelude::Color;
22

3+
use core::arch::asm;
34
use voladdress::*;
45

56
pub const WIDTH: usize = 240;

src/save/asm_utils.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
//! WRAM. Both flash media and battery-backed SRAM require reads to be
33
//! performed via code in WRAM and cannot be accessed by DMA.
44
5-
#![cfg_attr(not(target_arch = "arm"), allow(unused_variables, non_snake_case))]
5+
use core::arch::global_asm;
66

7+
#[cfg_attr(not(target_arch = "arm"), allow(unused_variables, non_snake_case))]
78
#[cfg(target_arch = "arm")]
89
global_asm!(include_str!("asm_routines.s"));
910

src/sync.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
33
use crate::prelude::*;
44

5+
use core::arch::asm;
6+
57
mod locks;
68
mod statics;
79

src/sync/statics.rs

Lines changed: 65 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use crate::sync::with_irqs_disabled;
44
use core::{
5+
arch::asm,
56
cell::UnsafeCell,
67
mem::{align_of, size_of, MaybeUninit},
78
ptr,
@@ -20,8 +21,10 @@ unsafe fn transfer<T: Copy>(dst: *mut T, src: *const T) {
2021
// We can do an 4-byte aligned transfer up to 16 bytes.
2122
transfer_align4_thumb(dst, src);
2223
} else if size <= 36 && align % 4 == 0 {
23-
// We can do the same up to 36 bytes, but we need to switch to ARM.
24-
transfer_align4_arm(dst, src);
24+
// // We can do the same up to 36 bytes, but we need to switch to ARM.
25+
// transfer_align4_arm(dst, src);
26+
// TODO(rust-console/gba#158) Cannot optimize larger transfers for now.
27+
with_irqs_disabled(|| ptr::write_volatile(dst, ptr::read_volatile(src)));
2528
} else if size <= 2 && align % 2 == 0 {
2629
// We can do a 2-byte aligned transfer up to 2 bytes.
2730
asm!(
@@ -82,65 +85,66 @@ unsafe fn transfer_align4_thumb<T: Copy>(mut dst: *mut T, mut src: *const T) {
8285
}
8386
}
8487

85-
#[cfg(target_arch = "arm")]
86-
#[instruction_set(arm::a32)]
87-
#[allow(unused_assignments)]
88-
unsafe fn transfer_align4_arm<T: Copy>(mut dst: *mut T, mut src: *const T) {
89-
let size = size_of::<T>();
90-
if size <= 16 {
91-
unimplemented!("This should be done via transfer_thumb.");
92-
} else if size <= 20 {
93-
// Starting at size == 20, we have to switch to ARM due to lack of
94-
// accessible registers in THUMB mode.
95-
asm!(
96-
"ldmia {0}!, {{r2-r5,r8}}",
97-
"stmia {1}!, {{r2-r5,r8}}",
98-
inout(reg) src, inout(reg) dst,
99-
out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _,
100-
)
101-
} else if size <= 24 {
102-
asm!(
103-
"push {{r9}}",
104-
"ldmia {0}!, {{r2-r5,r8-r9}}",
105-
"stmia {1}!, {{r2-r5,r8-r9}}",
106-
"pop {{r9}}",
107-
inout(reg) src, inout(reg) dst,
108-
out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _,
109-
)
110-
} else if size <= 28 {
111-
asm!(
112-
"push {{r9}}",
113-
"ldmia {0}!, {{r2-r5,r8-r10}}",
114-
"stmia {1}!, {{r2-r5,r8-r10}}",
115-
"pop {{r9}}",
116-
inout(reg) src, inout(reg) dst,
117-
out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _,
118-
out("r10") _,
119-
)
120-
} else if size <= 32 {
121-
asm!(
122-
"push {{r9}}",
123-
"ldmia {0}!, {{r2-r5,r8-r10,r12}}",
124-
"stmia {1}!, {{r2-r5,r8-r10,r12}}",
125-
"pop {{r9}}",
126-
inout(reg) src, inout(reg) dst,
127-
out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _,
128-
out("r10") _, out("r12") _,
129-
)
130-
} else if size <= 36 {
131-
asm!(
132-
"push {{r9}}",
133-
"ldmia {0}!, {{r2-r5,r8-r10,r12,r14}}",
134-
"stmia {1}!, {{r2-r5,r8-r10,r12,r14}}",
135-
"pop {{r9}}",
136-
inout(reg) src, inout(reg) dst,
137-
out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _,
138-
out("r10") _, out("r12") _, out("r14") _,
139-
)
140-
} else {
141-
unimplemented!("Copy too large for use of ldmia/stmia.");
142-
}
143-
}
88+
// TODO(rust-console/gba#158) Un-comment out this fn when we can use higher registers.
89+
// #[cfg(target_arch = "arm")]
90+
// #[instruction_set(arm::a32)]
91+
// #[allow(unused_assignments)]
92+
// unsafe fn transfer_align4_arm<T: Copy>(mut dst: *mut T, mut src: *const T) {
93+
// let size = size_of::<T>();
94+
// if size <= 16 {
95+
// unimplemented!("This should be done via transfer_thumb.");
96+
// } else if size <= 20 {
97+
// // Starting at size == 20, we have to switch to ARM due to lack of
98+
// // accessible registers in THUMB mode.
99+
// asm!(
100+
// "ldmia {0}!, {{r2-r5,r8}}",
101+
// "stmia {1}!, {{r2-r5,r8}}",
102+
// inout(reg) src, inout(reg) dst,
103+
// out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _,
104+
// )
105+
// } else if size <= 24 {
106+
// asm!(
107+
// "push {{r9}}",
108+
// "ldmia {0}!, {{r2-r5,r8-r9}}",
109+
// "stmia {1}!, {{r2-r5,r8-r9}}",
110+
// "pop {{r9}}",
111+
// inout(reg) src, inout(reg) dst,
112+
// out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _,
113+
// )
114+
// } else if size <= 28 {
115+
// asm!(
116+
// "push {{r9}}",
117+
// "ldmia {0}!, {{r2-r5,r8-r10}}",
118+
// "stmia {1}!, {{r2-r5,r8-r10}}",
119+
// "pop {{r9}}",
120+
// inout(reg) src, inout(reg) dst,
121+
// out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _,
122+
// out("r10") _,
123+
// )
124+
// } else if size <= 32 {
125+
// asm!(
126+
// "push {{r9}}",
127+
// "ldmia {0}!, {{r2-r5,r8-r10,r12}}",
128+
// "stmia {1}!, {{r2-r5,r8-r10,r12}}",
129+
// "pop {{r9}}",
130+
// inout(reg) src, inout(reg) dst,
131+
// out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _,
132+
// out("r10") _, out("r12") _,
133+
// )
134+
// } else if size <= 36 {
135+
// asm!(
136+
// "push {{r9}}",
137+
// "ldmia {0}!, {{r2-r5,r8-r10,r12,r14}}",
138+
// "stmia {1}!, {{r2-r5,r8-r10,r12,r14}}",
139+
// "pop {{r9}}",
140+
// inout(reg) src, inout(reg) dst,
141+
// out("r2") _, out("r3") _, out("r4") _, out("r5") _, out("r8") _,
142+
// out("r10") _, out("r12") _, out("r14") _,
143+
// )
144+
// } else {
145+
// unimplemented!("Copy too large for use of ldmia/stmia.");
146+
// }
147+
// }
144148

145149
/// The internal function for swapping the current value of a [`Static`] with
146150
/// another value.

0 commit comments

Comments
 (0)