@@ -2,15 +2,15 @@ use std::collections::HashMap;
22
33use cast:: u64;
44use quote:: Tokens ;
5- use svd:: { Device , Peripheral } ;
5+ use svd:: Peripheral ;
66use syn:: Ident ;
77
88use errors:: * ;
99use util:: { self , ToSanitizedUpperCase } ;
1010use Target ;
1111
1212/// Generates code for `src/interrupt.rs`
13- pub fn render ( device : & Device , target : & Target , peripherals : & [ Peripheral ] ) -> Result < Vec < Tokens > > {
13+ pub fn render ( target : & Target , peripherals : & [ Peripheral ] ) -> Result < Vec < Tokens > > {
1414 let interrupts = peripherals
1515 . iter ( )
1616 . flat_map ( |p| p. interrupt . iter ( ) )
@@ -20,6 +20,7 @@ pub fn render(device: &Device, target: &Target, peripherals: &[Peripheral]) -> R
2020 let mut interrupts = interrupts. into_iter ( ) . map ( |( _, v) | v) . collect :: < Vec < _ > > ( ) ;
2121 interrupts. sort_by_key ( |i| i. value ) ;
2222
23+ let mut root = vec ! [ ] ;
2324 let mut arms = vec ! [ ] ;
2425 let mut from_arms = vec ! [ ] ;
2526 let mut elements = vec ! [ ] ;
@@ -29,9 +30,6 @@ pub fn render(device: &Device, target: &Target, peripherals: &[Peripheral]) -> R
2930 // Current position in the vector table
3031 let mut pos = 0 ;
3132 let mut mod_items = vec ! [ ] ;
32- mod_items. push ( quote ! {
33- use bare_metal:: Nr ;
34- } ) ;
3533 for interrupt in & interrupts {
3634 while pos < interrupt. value {
3735 elements. push ( quote ! ( None ) ) ;
@@ -85,63 +83,17 @@ pub fn render(device: &Device, target: &Target, peripherals: &[Peripheral]) -> R
8583 let n = util:: unsuffixed ( u64 ( pos) ) ;
8684 match * target {
8785 Target :: CortexM => {
88- let is_armv6 = match device. cpu {
89- Some ( ref cpu) => cpu. name . starts_with ( "CM0" ) ,
90- None => true , // default to armv6 when the <cpu> section is missing
91- } ;
92-
93- if is_armv6 {
94- // Cortex-M0(+) are ARMv6 and don't have `b.w` (branch with 16 MB range). This
95- // can cause linker errors when the handler is too far away. Instead of a small
96- // inline assembly shim, we generate a function for those targets and let the
97- // compiler do the work (sacrificing a few bytes of code).
98- mod_items. push ( quote ! {
99- #[ cfg( feature = "rt" ) ]
100- extern "C" {
101- fn DEFAULT_HANDLER ( ) ;
102- }
103-
104- #[ cfg( feature = "rt" ) ]
105- #[ allow( non_snake_case) ]
106- #[ no_mangle]
107- pub unsafe extern "C" fn DH_TRAMPOLINE ( ) {
108- DEFAULT_HANDLER ( ) ;
109- }
110- } ) ;
111- } else {
112- mod_items. push ( quote ! {
113- #[ cfg( all( target_arch = "arm" , feature = "rt" ) ) ]
114- global_asm!( "
115- .thumb_func
116- DH_TRAMPOLINE:
117- b DEFAULT_HANDLER
118- " ) ;
119-
120- /// Hack to compile on x86
121- #[ cfg( all( target_arch = "x86_64" , feature = "rt" ) ) ]
122- global_asm!( "
123- DH_TRAMPOLINE:
124- jmp DEFAULT_HANDLER
125- " ) ;
126- } )
127- }
128-
129- mod_items. push ( quote ! {
130- #[ cfg( feature = "rt" ) ]
131- global_asm!( #aliases) ;
132-
86+ root. push ( quote ! {
13387 #[ cfg( feature = "rt" ) ]
13488 extern "C" {
13589 #( fn #names( ) ; ) *
13690 }
13791
138- #[ allow( private_no_mangle_statics) ]
13992 #[ cfg( feature = "rt" ) ]
14093 #[ doc( hidden) ]
14194 #[ link_section = ".vector_table.interrupts" ]
14295 #[ no_mangle]
143- #[ used]
144- pub static INTERRUPTS : [ Option <unsafe extern "C" fn ( ) >; #n] = [
96+ pub static __INTERRUPTS: [ Option <unsafe extern "C" fn ( ) >; #n] = [
14597 #( #elements, ) *
14698 ] ;
14799 } ) ;
@@ -178,106 +130,117 @@ pub fn render(device: &Device, target: &Target, peripherals: &[Peripheral]) -> R
178130 Target :: None => { }
179131 }
180132
181- mod_items . push ( quote ! {
133+ let interrupt_enum = quote ! {
182134 /// Enumeration of all the interrupts
183135 pub enum Interrupt {
184136 #( #variants) *
185137 }
186138
187- unsafe impl Nr for Interrupt {
139+ unsafe impl :: bare_metal :: Nr for Interrupt {
188140 #[ inline]
189141 fn nr( & self ) -> u8 {
190142 match * self {
191143 #( #arms) *
192144 }
193145 }
194146 }
147+ } ;
195148
196- use core:: convert:: TryFrom ;
149+ if * target == Target :: CortexM {
150+ root. push ( interrupt_enum) ;
151+ } else {
152+ mod_items. push ( quote ! {
153+ use core:: convert:: TryFrom ;
197154
198- #[ derive( Debug , Copy , Clone ) ]
199- pub struct TryFromInterruptError ( ( ) ) ;
155+ #[ derive( Debug , Copy , Clone ) ]
156+ pub struct TryFromInterruptError ( ( ) ) ;
200157
201- impl TryFrom <u8 > for Interrupt {
202- type Error = TryFromInterruptError ;
158+ impl TryFrom <u8 > for Interrupt {
159+ type Error = TryFromInterruptError ;
203160
204- #[ inline]
205- fn try_from( value: u8 ) -> Result <Self , Self :: Error > {
206- match value {
207- #( #from_arms) *
208- _ => Err ( TryFromInterruptError ( ( ) ) ) ,
161+ #[ inline]
162+ fn try_from( value: u8 ) -> Result <Self , Self :: Error > {
163+ match value {
164+ #( #from_arms) *
165+ _ => Err ( TryFromInterruptError ( ( ) ) ) ,
166+ }
209167 }
210168 }
211- }
212- } ) ;
169+ } ) ;
170+ }
213171
214172 if * target != Target :: None {
215173 let abi = match * target {
216174 Target :: Msp430 => "msp430-interrupt" ,
217175 _ => "C" ,
218176 } ;
219- mod_items. push ( quote ! {
220- #[ cfg( feature = "rt" ) ]
221- #[ macro_export]
222- macro_rules! interrupt {
223- ( $NAME : ident, $path: path, locals: {
224- $( $lvar: ident: $lty: ty = $lval: expr; ) *
225- } ) => {
226- #[ allow( non_snake_case) ]
227- mod $NAME {
228- pub struct Locals {
229- $(
230- pub $lvar: $lty,
231- ) *
232- }
233- }
234-
235- #[ allow( non_snake_case) ]
236- #[ no_mangle]
237- pub extern #abi fn $NAME ( ) {
238- // check that the handler exists
239- let _ = $crate :: interrupt:: Interrupt :: $NAME ;
240177
241- static mut LOCALS : self :: $NAME :: Locals =
242- self :: $NAME :: Locals {
178+ if * target != Target :: CortexM {
179+ mod_items. push ( quote ! {
180+ #[ cfg( feature = "rt" ) ]
181+ #[ macro_export]
182+ macro_rules! interrupt {
183+ ( $NAME : ident, $path: path, locals: {
184+ $( $lvar: ident: $lty: ty = $lval: expr; ) *
185+ } ) => {
186+ #[ allow( non_snake_case) ]
187+ mod $NAME {
188+ pub struct Locals {
243189 $(
244- $lvar: $lval ,
190+ pub $lvar: $lty ,
245191 ) *
246- } ;
192+ }
193+ }
247194
248- // type checking
249- let f: fn ( & mut self :: $NAME :: Locals ) = $path;
250- f( unsafe { & mut LOCALS } ) ;
251- }
252- } ;
253- ( $NAME : ident, $path: path) => {
254- #[ allow( non_snake_case) ]
255- #[ no_mangle]
256- pub extern #abi fn $NAME ( ) {
257- // check that the handler exists
258- let _ = $crate :: interrupt:: Interrupt :: $NAME ;
259-
260- // type checking
261- let f: fn ( ) = $path;
262- f( ) ;
195+ #[ allow( non_snake_case) ]
196+ #[ no_mangle]
197+ pub extern #abi fn $NAME ( ) {
198+ // check that the handler exists
199+ let _ = $crate :: interrupt:: Interrupt :: $NAME ;
200+
201+ static mut LOCALS : self :: $NAME :: Locals =
202+ self :: $NAME :: Locals {
203+ $(
204+ $lvar: $lval,
205+ ) *
206+ } ;
207+
208+ // type checking
209+ let f: fn ( & mut self :: $NAME :: Locals ) = $path;
210+ f( unsafe { & mut LOCALS } ) ;
211+ }
212+ } ;
213+ ( $NAME : ident, $path: path) => {
214+ #[ allow( non_snake_case) ]
215+ #[ no_mangle]
216+ pub extern #abi fn $NAME ( ) {
217+ // check that the handler exists
218+ let _ = $crate :: interrupt:: Interrupt :: $NAME ;
219+
220+ // type checking
221+ let f: fn ( ) = $path;
222+ f( ) ;
223+ }
263224 }
264225 }
265- }
266- } ) ;
226+ } ) ;
227+ }
267228 }
268229
269- let mut out = vec ! [ ] ;
270-
271230 if interrupts. len ( ) > 0 {
272- out. push ( quote ! {
273- pub use interrupt:: Interrupt ;
274-
231+ root. push ( quote ! {
275232 #[ doc( hidden) ]
276233 pub mod interrupt {
277234 #( #mod_items) *
278235 }
279236 } ) ;
237+
238+ if * target != Target :: CortexM {
239+ root. push ( quote ! {
240+ pub use interrupt:: Interrupt ;
241+ } ) ;
242+ }
280243 }
281244
282- Ok ( out )
245+ Ok ( root )
283246}
0 commit comments