Skip to content

Commit 7e1548f

Browse files
committed
Add nomem, nostack and preserves_flags options to appropriate asm calls.
1 parent 587bf1d commit 7e1548f

15 files changed

+71
-43
lines changed

asm/inline.rs

+71-43
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ use core::sync::atomic::{compiler_fence, Ordering};
1111

1212
#[inline(always)]
1313
pub unsafe fn __bkpt() {
14-
asm!("bkpt", options(nostack));
14+
asm!("bkpt", options(nomem, nostack, preserves_flags));
1515
}
1616

1717
#[inline(always)]
1818
pub 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)]
3940
pub 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)]
7173
pub 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)]
7880
pub 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)]
8587
pub 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)]
9294
pub 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)]
99101
pub 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)]
105111
pub 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)]
121127
pub 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)]
129135
pub 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)]
135141
pub 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)]
143149
pub 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)]
148154
pub 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)]
155161
pub 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)]
162168
pub 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)]
167175
pub unsafe fn __sev() {
168-
asm!("sev");
176+
asm!("sev", options(nomem, nostack, preserves_flags));
169177
}
170178

171179
#[inline(always)]
172180
pub unsafe fn __udf() -> ! {
173-
asm!("udf #0", options(noreturn));
181+
asm!("udf #0", options(noreturn, nomem, nostack, preserves_flags));
174182
}
175183

176184
#[inline(always)]
177185
pub unsafe fn __wfe() {
178-
asm!("wfe");
186+
asm!("wfe", options(nomem, nostack, preserves_flags));
179187
}
180188

181189
#[inline(always)]
182190
pub unsafe fn __wfi() {
183-
asm!("wfi");
191+
asm!("wfi", options(nomem, nostack, preserves_flags));
184192
}
185193

186194
/// Semihosting syscall.
187195
#[inline(always)]
188196
pub 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
}

bin/thumbv6m-none-eabi-lto.a

-592 Bytes
Binary file not shown.

bin/thumbv6m-none-eabi.a

-1.73 KB
Binary file not shown.

bin/thumbv7em-none-eabi-lto.a

-648 Bytes
Binary file not shown.

bin/thumbv7em-none-eabi.a

-2.14 KB
Binary file not shown.

bin/thumbv7em-none-eabihf-lto.a

-788 Bytes
Binary file not shown.

bin/thumbv7em-none-eabihf.a

-2.29 KB
Binary file not shown.

bin/thumbv7m-none-eabi-lto.a

-664 Bytes
Binary file not shown.

bin/thumbv7m-none-eabi.a

-2.07 KB
Binary file not shown.

bin/thumbv8m.base-none-eabi-lto.a

-776 Bytes
Binary file not shown.

bin/thumbv8m.base-none-eabi.a

-2.04 KB
Binary file not shown.

bin/thumbv8m.main-none-eabi-lto.a

-880 Bytes
Binary file not shown.

bin/thumbv8m.main-none-eabi.a

-2.66 KB
Binary file not shown.

bin/thumbv8m.main-none-eabihf-lto.a

-1020 Bytes
Binary file not shown.

bin/thumbv8m.main-none-eabihf.a

-2.81 KB
Binary file not shown.

0 commit comments

Comments
 (0)