@@ -11,13 +11,13 @@ use core::sync::atomic::{compiler_fence, Ordering};
1111
1212#[ inline( always) ]
1313pub unsafe fn __bkpt ( ) {
14- asm ! ( "bkpt" , options( nostack) ) ;
14+ asm ! ( "bkpt" , options( nomem , nostack, preserves_flags ) ) ;
1515}
1616
1717#[ inline( always) ]
1818pub unsafe fn __control_r ( ) -> u32 {
1919 let r;
20- asm ! ( "mrs {}, CONTROL" , out( reg) r) ;
20+ asm ! ( "mrs {}, CONTROL" , out( reg) r, options ( nomem , nostack , preserves_flags ) ) ;
2121 r
2222}
2323
@@ -28,7 +28,8 @@ pub unsafe fn __control_w(w: u32) {
2828 asm ! (
2929 "msr CONTROL, {}" ,
3030 "isb" ,
31- in( reg) w
31+ in( reg) w,
32+ options( nomem, nostack, preserves_flags) ,
3233 ) ;
3334
3435 // Ensure memory accesses are not reordered around the CONTROL update.
@@ -37,7 +38,7 @@ pub unsafe fn __control_w(w: u32) {
3738
3839#[ inline( always) ]
3940pub unsafe fn __cpsid ( ) {
40- asm ! ( "cpsid i" ) ;
41+ asm ! ( "cpsid i" , options ( nomem , nostack , preserves_flags ) ) ;
4142
4243 // Ensure no subsequent memory accesses are reordered to before interrupts are disabled.
4344 compiler_fence ( Ordering :: SeqCst ) ;
@@ -48,7 +49,7 @@ pub unsafe fn __cpsie() {
4849 // Ensure no preceeding memory accesses are reordered to after interrupts are enabled.
4950 compiler_fence ( Ordering :: SeqCst ) ;
5051
51- asm ! ( "cpsie i" ) ;
52+ asm ! ( "cpsie i" , options ( nomem , nostack , preserves_flags ) ) ;
5253}
5354
5455#[ inline( always) ]
@@ -63,48 +64,53 @@ pub unsafe fn __delay(cyc: u32) {
6364 "1:" ,
6465 "subs {}, #1" ,
6566 "bne 1b" ,
66- inout( reg) real_cyc => _
67+ inout( reg) real_cyc => _,
68+ options( nomem, nostack) ,
6769 ) ;
6870}
6971
7072#[ inline( always) ]
7173pub unsafe fn __dmb ( ) {
7274 compiler_fence ( Ordering :: SeqCst ) ;
73- asm ! ( "dmb" ) ;
75+ asm ! ( "dmb" , options ( nomem , nostack , preserves_flags ) ) ;
7476 compiler_fence ( Ordering :: SeqCst ) ;
7577}
7678
7779#[ inline( always) ]
7880pub unsafe fn __dsb ( ) {
7981 compiler_fence ( Ordering :: SeqCst ) ;
80- asm ! ( "dsb" ) ;
82+ asm ! ( "dsb" , options ( nomem , nostack , preserves_flags ) ) ;
8183 compiler_fence ( Ordering :: SeqCst ) ;
8284}
8385
8486#[ inline( always) ]
8587pub unsafe fn __isb ( ) {
8688 compiler_fence ( Ordering :: SeqCst ) ;
87- asm ! ( "isb" ) ;
89+ asm ! ( "isb" , options ( nomem , nostack , preserves_flags ) ) ;
8890 compiler_fence ( Ordering :: SeqCst ) ;
8991}
9092
9193#[ inline( always) ]
9294pub unsafe fn __msp_r ( ) -> u32 {
9395 let r;
94- asm ! ( "mrs {}, MSP" , out( reg) r) ;
96+ asm ! ( "mrs {}, MSP" , out( reg) r, options ( nomem , nostack , preserves_flags ) ) ;
9597 r
9698}
9799
98100#[ inline( always) ]
99101pub unsafe fn __msp_w ( val : u32 ) {
100- asm ! ( "msr MSP, {}" , in( reg) val) ;
102+ // Technically is writing to the stack pointer "not pushing any data to the stack"?
103+ // In any event, if we don't set `nostack` here, this method is useless as the new
104+ // stack value is immediately mutated by returning. Really this is just not a good
105+ // method and its higher-level use is marked as deprecated in cortex-m.
106+ asm ! ( "msr MSP, {}" , in( reg) val, options( nomem, nostack, preserves_flags) ) ;
101107}
102108
103109// NOTE: No FFI shim, this requires inline asm.
104110#[ inline( always) ]
105111pub unsafe fn __apsr_r ( ) -> u32 {
106112 let r;
107- asm ! ( "mrs {}, APSR" , out( reg) r) ;
113+ asm ! ( "mrs {}, APSR" , out( reg) r, options ( nomem , nostack , preserves_flags ) ) ;
108114 r
109115}
110116
@@ -113,80 +119,82 @@ pub unsafe fn __nop() {
113119 // NOTE: This is a `pure` asm block, but applying that option allows the compiler to eliminate
114120 // the nop entirely (or to collapse multiple subsequent ones). Since the user probably wants N
115121 // nops when they call `nop` N times, let's not add that option.
116- asm ! ( "nop" ) ;
122+ asm ! ( "nop" , options ( nomem , nostack , preserves_flags ) ) ;
117123}
118124
119125// NOTE: No FFI shim, this requires inline asm.
120126#[ inline( always) ]
121127pub unsafe fn __pc_r ( ) -> u32 {
122128 let r;
123- asm ! ( "mov {}, pc" , out( reg) r) ;
129+ asm ! ( "mov {}, pc" , out( reg) r, options ( nomem , nostack , preserves_flags ) ) ;
124130 r
125131}
126132
127133// NOTE: No FFI shim, this requires inline asm.
128134#[ inline( always) ]
129135pub unsafe fn __pc_w ( val : u32 ) {
130- asm ! ( "mov pc, {}" , in( reg) val) ;
136+ asm ! ( "mov pc, {}" , in( reg) val, options ( nomem , nostack , preserves_flags ) ) ;
131137}
132138
133139// NOTE: No FFI shim, this requires inline asm.
134140#[ inline( always) ]
135141pub unsafe fn __lr_r ( ) -> u32 {
136142 let r;
137- asm ! ( "mov {}, lr" , out( reg) r) ;
143+ asm ! ( "mov {}, lr" , out( reg) r, options ( nomem , nostack , preserves_flags ) ) ;
138144 r
139145}
140146
141147// NOTE: No FFI shim, this requires inline asm.
142148#[ inline( always) ]
143149pub unsafe fn __lr_w ( val : u32 ) {
144- asm ! ( "mov lr, {}" , in( reg) val) ;
150+ asm ! ( "mov lr, {}" , in( reg) val, options ( nomem , nostack , preserves_flags ) ) ;
145151}
146152
147153#[ inline( always) ]
148154pub unsafe fn __primask_r ( ) -> u32 {
149155 let r;
150- asm ! ( "mrs {}, PRIMASK" , out( reg) r) ;
156+ asm ! ( "mrs {}, PRIMASK" , out( reg) r, options ( nomem , nostack , preserves_flags ) ) ;
151157 r
152158}
153159
154160#[ inline( always) ]
155161pub unsafe fn __psp_r ( ) -> u32 {
156162 let r;
157- asm ! ( "mrs {}, PSP" , out( reg) r) ;
163+ asm ! ( "mrs {}, PSP" , out( reg) r, options ( nomem , nostack , preserves_flags ) ) ;
158164 r
159165}
160166
161167#[ inline( always) ]
162168pub unsafe fn __psp_w ( val : u32 ) {
163- asm ! ( "msr PSP, {}" , in( reg) val) ;
169+ // See comment on __msp_w. Unlike MSP, there are legitimate use-cases for modifying PSP
170+ // if MSP is currently being used as the stack pointer.
171+ asm ! ( "msr PSP, {}" , in( reg) val, options( nomem, nostack, preserves_flags) ) ;
164172}
165173
166174#[ inline( always) ]
167175pub unsafe fn __sev ( ) {
168- asm ! ( "sev" ) ;
176+ asm ! ( "sev" , options ( nomem , nostack , preserves_flags ) ) ;
169177}
170178
171179#[ inline( always) ]
172180pub unsafe fn __udf ( ) -> ! {
173- asm ! ( "udf #0" , options( noreturn) ) ;
181+ asm ! ( "udf #0" , options( noreturn, nomem , nostack , preserves_flags ) ) ;
174182}
175183
176184#[ inline( always) ]
177185pub unsafe fn __wfe ( ) {
178- asm ! ( "wfe" ) ;
186+ asm ! ( "wfe" , options ( nomem , nostack , preserves_flags ) ) ;
179187}
180188
181189#[ inline( always) ]
182190pub unsafe fn __wfi ( ) {
183- asm ! ( "wfi" ) ;
191+ asm ! ( "wfi" , options ( nomem , nostack , preserves_flags ) ) ;
184192}
185193
186194/// Semihosting syscall.
187195#[ inline( always) ]
188196pub unsafe fn __sh_syscall ( mut nr : u32 , arg : u32 ) -> u32 {
189- asm ! ( "bkpt #0xab" , inout( "r0" ) nr, in( "r1" ) arg) ;
197+ asm ! ( "bkpt #0xab" , inout( "r0" ) nr, in( "r1" ) arg, options ( nomem , nostack , preserves_flags ) ) ;
190198 nr
191199}
192200
@@ -206,7 +214,7 @@ pub unsafe fn __bootstrap(msp: u32, rv: u32) -> ! {
206214 spsel = in( reg) 2 ,
207215 msp = in( reg) msp,
208216 rv = in( reg) rv,
209- options( noreturn) ,
217+ options( noreturn, nomem , nostack ) ,
210218 ) ;
211219}
212220
@@ -220,25 +228,25 @@ mod v7m {
220228
221229 #[ inline( always) ]
222230 pub unsafe fn __basepri_max ( val : u8 ) {
223- asm ! ( "msr BASEPRI_MAX, {}" , in( reg) val) ;
231+ asm ! ( "msr BASEPRI_MAX, {}" , in( reg) val, options ( nomem , nostack , preserves_flags ) ) ;
224232 }
225233
226234 #[ inline( always) ]
227235 pub unsafe fn __basepri_r ( ) -> u8 {
228236 let r;
229- asm ! ( "mrs {}, BASEPRI" , out( reg) r) ;
237+ asm ! ( "mrs {}, BASEPRI" , out( reg) r, options ( nomem , nostack , preserves_flags ) ) ;
230238 r
231239 }
232240
233241 #[ inline( always) ]
234242 pub unsafe fn __basepri_w ( val : u8 ) {
235- asm ! ( "msr BASEPRI, {}" , in( reg) val) ;
243+ asm ! ( "msr BASEPRI, {}" , in( reg) val, options ( nomem , nostack , preserves_flags ) ) ;
236244 }
237245
238246 #[ inline( always) ]
239247 pub unsafe fn __faultmask_r ( ) -> u32 {
240248 let r;
241- asm ! ( "mrs {}, FAULTMASK" , out( reg) r) ;
249+ asm ! ( "mrs {}, FAULTMASK" , out( reg) r, options ( nomem , nostack , preserves_flags ) ) ;
242250 r
243251 }
244252
@@ -257,6 +265,7 @@ mod v7m {
257265 out( reg) _,
258266 out( reg) _,
259267 out( reg) _,
268+ options( nostack) ,
260269 ) ;
261270 compiler_fence ( Ordering :: SeqCst ) ;
262271 }
@@ -276,6 +285,7 @@ mod v7m {
276285 out( reg) _,
277286 out( reg) _,
278287 out( reg) _,
288+ options( nostack) ,
279289 ) ;
280290 compiler_fence ( Ordering :: SeqCst ) ;
281291 }
@@ -299,6 +309,7 @@ mod v7em {
299309 "cpsie i" ,
300310 in( reg) val,
301311 out( reg) _,
312+ options( nomem, nostack, preserves_flags) ,
302313 ) ;
303314 }
304315
@@ -314,6 +325,7 @@ mod v7em {
314325 "cpsie i" ,
315326 in( reg) val,
316327 out( reg) _,
328+ options( nomem, nostack, preserves_flags) ,
317329 ) ;
318330 }
319331}
@@ -327,43 +339,59 @@ mod v8m {
327339
328340 #[ inline( always) ]
329341 pub unsafe fn __tt ( mut target : u32 ) -> u32 {
330- asm ! ( "tt {target}, {target}" , target = inout( reg) target) ;
342+ asm ! (
343+ "tt {target}, {target}" ,
344+ target = inout( reg) target,
345+ options( nomem, nostack, preserves_flags) ,
346+ ) ;
331347 target
332348 }
333349
334350 #[ inline( always) ]
335351 pub unsafe fn __ttt ( mut target : u32 ) -> u32 {
336- asm ! ( "ttt {target}, {target}" , target = inout( reg) target) ;
352+ asm ! (
353+ "ttt {target}, {target}" ,
354+ target = inout( reg) target,
355+ options( nomem, nostack, preserves_flags) ,
356+ ) ;
337357 target
338358 }
339359
340360 #[ inline( always) ]
341361 pub unsafe fn __tta ( mut target : u32 ) -> u32 {
342- asm ! ( "tta {target}, {target}" , target = inout( reg) target) ;
362+ asm ! (
363+ "tta {target}, {target}" ,
364+ target = inout( reg) target,
365+ options( nomem, nostack, preserves_flags) ,
366+ ) ;
343367 target
344368 }
345369
346370 #[ inline( always) ]
347371 pub unsafe fn __ttat ( mut target : u32 ) -> u32 {
348- asm ! ( "ttat {target}, {target}" , target = inout( reg) target) ;
372+ asm ! (
373+ "ttat {target}, {target}" ,
374+ target = inout( reg) target,
375+ options( nomem, nostack, preserves_flags) ,
376+ ) ;
349377 target
350378 }
351379
352380 #[ inline( always) ]
353381 pub unsafe fn __msp_ns_r ( ) -> u32 {
354382 let r;
355- asm ! ( "mrs {}, MSP_NS" , out( reg) r) ;
383+ asm ! ( "mrs {}, MSP_NS" , out( reg) r, options ( nomem , nostack , preserves_flags ) ) ;
356384 r
357385 }
358386
359387 #[ inline( always) ]
360388 pub unsafe fn __msp_ns_w ( val : u32 ) {
361- asm ! ( "msr MSP_NS, {}" , in( reg) val) ;
389+ asm ! ( "msr MSP_NS, {}" , in( reg) val, options ( nomem , nostack , preserves_flags ) ) ;
362390 }
363391
364392 #[ inline( always) ]
365393 pub unsafe fn __bxns ( val : u32 ) {
366- asm ! ( "BXNS {}" , in( reg) val) ;
394+ asm ! ( "BXNS {}" , in( reg) val, options ( nomem , nostack , preserves_flags ) ) ;
367395 }
368396}
369397
@@ -377,25 +405,25 @@ mod v8m_main {
377405 #[ inline( always) ]
378406 pub unsafe fn __msplim_r ( ) -> u32 {
379407 let r;
380- asm ! ( "mrs {}, MSPLIM" , out( reg) r) ;
408+ asm ! ( "mrs {}, MSPLIM" , out( reg) r, options ( nomem , nostack , preserves_flags ) ) ;
381409 r
382410 }
383411
384412 #[ inline( always) ]
385413 pub unsafe fn __msplim_w ( val : u32 ) {
386- asm ! ( "msr MSPLIM, {}" , in( reg) val) ;
414+ asm ! ( "msr MSPLIM, {}" , in( reg) val, options ( nomem , nostack , preserves_flags ) ) ;
387415 }
388416
389417 #[ inline( always) ]
390418 pub unsafe fn __psplim_r ( ) -> u32 {
391419 let r;
392- asm ! ( "mrs {}, PSPLIM" , out( reg) r) ;
420+ asm ! ( "mrs {}, PSPLIM" , out( reg) r, options ( nomem , nostack , preserves_flags ) ) ;
393421 r
394422 }
395423
396424 #[ inline( always) ]
397425 pub unsafe fn __psplim_w ( val : u32 ) {
398- asm ! ( "msr PSPLIM, {}" , in( reg) val) ;
426+ asm ! ( "msr PSPLIM, {}" , in( reg) val, options ( nomem , nostack , preserves_flags ) ) ;
399427 }
400428}
401429
@@ -409,12 +437,12 @@ mod fpu {
409437 #[ inline( always) ]
410438 pub unsafe fn __fpscr_r ( ) -> u32 {
411439 let r;
412- asm ! ( "vmrs {}, fpscr" , out( reg) r) ;
440+ asm ! ( "vmrs {}, fpscr" , out( reg) r, options ( nomem , nostack , preserves_flags ) ) ;
413441 r
414442 }
415443
416444 #[ inline( always) ]
417445 pub unsafe fn __fpscr_w ( val : u32 ) {
418- asm ! ( "vmsr fpscr, {}" , in( reg) val) ;
446+ asm ! ( "vmsr fpscr, {}" , in( reg) val, options ( nomem , nostack ) ) ;
419447 }
420448}
0 commit comments