@@ -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`
175175pub 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