diff --git a/src/asm.rs b/src/asm.rs index e85684f..9ae1281 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -3,17 +3,23 @@ use crate::asm; /// A no-operation. Useful to prevent delay loops from being optimized away. +/// +/// Unlike [barrier], this does not prevent reordering of memory access. #[inline(always)] pub fn nop() { unsafe { - asm!("nop"); + // Do not use pure because prevent nop from being removed. + asm!("nop", options(nomem, nostack, preserves_flags)); } } /// A compiler fence, prevents instruction reordering. +/// +/// Unlike [nop], this does not emit machine code. #[inline(always)] pub fn barrier() { unsafe { - asm!(""); + // Do not use `nomem` and `readonly` because prevent preceding and subsequent memory accesses from being reordered. + asm!("", options(nostack, preserves_flags)); } } diff --git a/src/interrupt.rs b/src/interrupt.rs index d67bde9..f896464 100644 --- a/src/interrupt.rs +++ b/src/interrupt.rs @@ -10,7 +10,9 @@ pub fn disable() { match () { #[cfg(target_arch = "msp430")] () => unsafe { - asm!("dint {{ nop"); + // Do not use `nomem` and `readonly` because prevent subsequent memory accesses from being reordered before interrupts are disabled. + // Do not use `preserves_flags` because DINT modifies the GIE (global interrupt enable) bit of the status register. + asm!("dint {{ nop", options(nostack)); }, #[cfg(not(target_arch = "msp430"))] () => {} @@ -29,7 +31,9 @@ pub unsafe fn enable() { match () { #[cfg(target_arch = "msp430")] () => { - asm!("nop {{ eint {{ nop"); + // Do not use `nomem` and `readonly` because prevent preceding memory accesses from being reordered after interrupts are enabled. + // Do not use `preserves_flags` because EINT modifies the GIE (global interrupt enable) bit of the status register. + asm!("nop {{ eint {{ nop", options(nostack)); } #[cfg(not(target_arch = "msp430"))] () => {} diff --git a/src/register/pc.rs b/src/register/pc.rs index d84fe02..c1ae13f 100644 --- a/src/register/pc.rs +++ b/src/register/pc.rs @@ -7,7 +7,7 @@ use crate::asm; pub fn read() -> u16 { let r; unsafe { - asm!("mov R0, {0}", out(reg) r); + asm!("mov R0, {0}", out(reg) r, options(nomem, nostack, preserves_flags)); } r } diff --git a/src/register/sp.rs b/src/register/sp.rs index 9cc818e..49430ab 100644 --- a/src/register/sp.rs +++ b/src/register/sp.rs @@ -7,7 +7,7 @@ use crate::asm; pub fn read() -> u16 { let r; unsafe { - asm!("mov R1, {0}", out(reg) r); + asm!("mov R1, {0}", out(reg) r, options(nomem, nostack, preserves_flags)); } r } diff --git a/src/register/sr.rs b/src/register/sr.rs index 22a3471..58d4d8e 100644 --- a/src/register/sr.rs +++ b/src/register/sr.rs @@ -79,7 +79,7 @@ impl Sr { pub fn read() -> Sr { let r: u16; unsafe { - asm!("mov R2, {0}", out(reg) r); + asm!("mov R2, {0}", out(reg) r, options(nomem, nostack, preserves_flags)); } Sr { bits: r } }