Skip to content

Commit a8994ef

Browse files
Use far-ranged jumps for DH_TRAMPOLINE
Fixes japaric/cortex-m-rtfm#42 Note that this will make all generated crates that target an armv6 device fail to compile unless they add a build script enabling the added `cfg`.
1 parent bab6f3e commit a8994ef

File tree

1 file changed

+42
-14
lines changed

1 file changed

+42
-14
lines changed

src/generate.rs

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub fn device(
8787
});
8888
}
8989

90-
::generate::interrupt(target, &d.peripherals, items);
90+
::generate::interrupt(d, target, &d.peripherals, items);
9191

9292
const CORE_PERIPHERALS: &[&str] = &[
9393
"CPUID",
@@ -173,6 +173,7 @@ pub fn device(
173173

174174
/// Generates code for `src/interrupt.rs`
175175
pub fn interrupt(
176+
device: &Device,
176177
target: &Target,
177178
peripherals: &[Peripheral],
178179
items: &mut Vec<Tokens>,
@@ -241,21 +242,48 @@ pub fn interrupt(
241242
let n = util::unsuffixed(u64(pos));
242243
match *target {
243244
Target::CortexM => {
244-
mod_items.push(quote! {
245-
#[cfg(all(target_arch = "arm", feature = "rt"))]
246-
global_asm!("
247-
.thumb_func
248-
DH_TRAMPOLINE:
249-
b DEFAULT_HANDLER
250-
");
245+
let is_armv6 = match device.cpu {
246+
Some(ref cpu) if cpu.name.starts_with("CM0") => true,
247+
_ => false,
248+
};
251249

252-
/// Hack to compile on x86
253-
#[cfg(all(target_arch = "x86_64", feature = "rt"))]
254-
global_asm!("
255-
DH_TRAMPOLINE:
256-
jmp DEFAULT_HANDLER
257-
");
250+
if is_armv6 {
251+
// Cortex-M0(+) are ARMv6 and don't have `b.w` (branch with 16 MB range). This
252+
// can cause linker errors when the handler is too far away. Instead of a small
253+
// inline assembly shim, we generate a function for those targets and let the
254+
// compiler do the work (sacrificing a few bytes of code).
255+
mod_items.push(quote! {
256+
#[cfg(feature = "rt")]
257+
extern "C" {
258+
fn DEFAULT_HANDLER();
259+
}
260+
261+
#[cfg(feature = "rt")]
262+
#[allow(non_snake_case)]
263+
#[no_mangle]
264+
pub unsafe extern "C" fn DH_TRAMPOLINE() {
265+
DEFAULT_HANDLER();
266+
}
267+
});
268+
} else {
269+
mod_items.push(quote! {
270+
#[cfg(all(target_arch = "arm", feature = "rt"))]
271+
global_asm!("
272+
.thumb_func
273+
DH_TRAMPOLINE:
274+
b DEFAULT_HANDLER
275+
");
276+
277+
/// Hack to compile on x86
278+
#[cfg(all(target_arch = "x86_64", feature = "rt"))]
279+
global_asm!("
280+
DH_TRAMPOLINE:
281+
jmp DEFAULT_HANDLER
282+
");
283+
})
284+
}
258285

286+
mod_items.push(quote! {
259287
#[cfg(feature = "rt")]
260288
global_asm!(#aliases);
261289

0 commit comments

Comments
 (0)