diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e7d1e75..f6298df7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,7 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 
 ## [Unreleased]
 
+## [v0.7.4] - 2021-12-31
+
 ### Added
+
 - Added support for additional DWT counters (#349)
     - CPI counter
     - Exception overhead counter
@@ -15,7 +18,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
     - Folded-instruction counter
 - Added `DWT.set_cycle_count` (#347).
 - Added support for the Cortex-M7 TCM and cache access control registers.
-  There is a feature `cm7` to enable access to these.
+  There is a feature `cm7` to enable access to these (#352).
+- Add derives for serde, Hash, and PartialOrd to VectActive behind feature
+  gates for host-platform use (#363).
+- Support host platforms besides x86_64 (#369).
+- Added `delay::Delay::with_source`, a constructor that lets you specify
+  the SysTick clock source (#374).
+
+### Fixed
+
+- Fix incorrect AIRCR PRIGROUP mask (#338, #339).
+- Fix nightly users of inline-asm breaking now that the asm macro is removed
+  from the prelude (#372).
 
 ### Deprecated
 
@@ -717,7 +731,8 @@ fn main() {
 - Functions to get the vector table
 - Wrappers over miscellaneous instructions like `bkpt`
 
-[Unreleased]: https://github.com/rust-embedded/cortex-m/compare/v0.7.3...HEAD
+[Unreleased]: https://github.com/rust-embedded/cortex-m/compare/v0.7.4...HEAD
+[v0.7.4]: https://github.com/rust-embedded/cortex-m/compare/v0.7.3...v0.7.4
 [v0.7.3]: https://github.com/rust-embedded/cortex-m/compare/v0.7.2...v0.7.3
 [v0.7.2]: https://github.com/rust-embedded/cortex-m/compare/v0.7.1...v0.7.2
 [v0.7.1]: https://github.com/rust-embedded/cortex-m/compare/v0.7.0...v0.7.1
diff --git a/Cargo.toml b/Cargo.toml
index 4769aba3..dcbd3bdb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,7 +11,7 @@ license = "MIT OR Apache-2.0"
 name = "cortex-m"
 readme = "README.md"
 repository = "https://github.com/rust-embedded/cortex-m"
-version = "0.7.3"
+version = "0.7.4"
 edition = "2018"
 links = "cortex-m"  # prevent multiple versions of this crate to be linked together
 
@@ -31,7 +31,7 @@ cm7 = []
 cm7-r0p1 = ["cm7"]
 inline-asm = []
 linker-plugin-lto = []
-std-map = []
+std = []
 
 [workspace]
 members = ["xtask", "cortex-m-semihosting", "panic-semihosting", "panic-itm"]
diff --git a/asm-toolchain b/asm-toolchain
index a36829b6..cc5dbb24 100644
--- a/asm-toolchain
+++ b/asm-toolchain
@@ -1 +1 @@
-nightly-2020-08-26
+nightly-2021-12-16
diff --git a/asm/inline.rs b/asm/inline.rs
index 5887bafb..bbc04d2b 100644
--- a/asm/inline.rs
+++ b/asm/inline.rs
@@ -6,17 +6,18 @@
 //! All of these functions should be blanket-`unsafe`. `cortex-m` provides safe wrappers where
 //! applicable.
 
+use core::arch::asm;
 use core::sync::atomic::{compiler_fence, Ordering};
 
 #[inline(always)]
 pub unsafe fn __bkpt() {
-    asm!("bkpt");
+    asm!("bkpt", options(nomem, nostack, preserves_flags));
 }
 
 #[inline(always)]
 pub unsafe fn __control_r() -> u32 {
     let r;
-    asm!("mrs {}, CONTROL", out(reg) r);
+    asm!("mrs {}, CONTROL", out(reg) r, options(nomem, nostack, preserves_flags));
     r
 }
 
@@ -27,7 +28,8 @@ pub unsafe fn __control_w(w: u32) {
     asm!(
         "msr CONTROL, {}",
         "isb",
-        in(reg) w
+        in(reg) w,
+        options(nomem, nostack, preserves_flags),
     );
 
     // Ensure memory accesses are not reordered around the CONTROL update.
@@ -36,7 +38,7 @@ pub unsafe fn __control_w(w: u32) {
 
 #[inline(always)]
 pub unsafe fn __cpsid() {
-    asm!("cpsid i");
+    asm!("cpsid i", options(nomem, nostack, preserves_flags));
 
     // Ensure no subsequent memory accesses are reordered to before interrupts are disabled.
     compiler_fence(Ordering::SeqCst);
@@ -47,7 +49,7 @@ pub unsafe fn __cpsie() {
     // Ensure no preceeding memory accesses are reordered to after interrupts are enabled.
     compiler_fence(Ordering::SeqCst);
 
-    asm!("cpsie i");
+    asm!("cpsie i", options(nomem, nostack, preserves_flags));
 }
 
 #[inline(always)]
@@ -62,48 +64,53 @@ pub unsafe fn __delay(cyc: u32) {
         "1:",
         "subs {}, #1",
         "bne 1b",
-        inout(reg) real_cyc => _
+        inout(reg) real_cyc => _,
+        options(nomem, nostack),
     );
 }
 
 #[inline(always)]
 pub unsafe fn __dmb() {
     compiler_fence(Ordering::SeqCst);
-    asm!("dmb");
+    asm!("dmb", options(nomem, nostack, preserves_flags));
     compiler_fence(Ordering::SeqCst);
 }
 
 #[inline(always)]
 pub unsafe fn __dsb() {
     compiler_fence(Ordering::SeqCst);
-    asm!("dsb");
+    asm!("dsb", options(nomem, nostack, preserves_flags));
     compiler_fence(Ordering::SeqCst);
 }
 
 #[inline(always)]
 pub unsafe fn __isb() {
     compiler_fence(Ordering::SeqCst);
-    asm!("isb");
+    asm!("isb", options(nomem, nostack, preserves_flags));
     compiler_fence(Ordering::SeqCst);
 }
 
 #[inline(always)]
 pub unsafe fn __msp_r() -> u32 {
     let r;
-    asm!("mrs {}, MSP", out(reg) r);
+    asm!("mrs {}, MSP", out(reg) r, options(nomem, nostack, preserves_flags));
     r
 }
 
 #[inline(always)]
 pub unsafe fn __msp_w(val: u32) {
-    asm!("msr MSP, {}", in(reg) val);
+    // Technically is writing to the stack pointer "not pushing any data to the stack"?
+    // In any event, if we don't set `nostack` here, this method is useless as the new
+    // stack value is immediately mutated by returning. Really this is just not a good
+    // method and its higher-level use is marked as deprecated in cortex-m.
+    asm!("msr MSP, {}", in(reg) val, options(nomem, nostack, preserves_flags));
 }
 
 // NOTE: No FFI shim, this requires inline asm.
 #[inline(always)]
 pub unsafe fn __apsr_r() -> u32 {
     let r;
-    asm!("mrs {}, APSR", out(reg) r);
+    asm!("mrs {}, APSR", out(reg) r, options(nomem, nostack, preserves_flags));
     r
 }
 
@@ -112,80 +119,82 @@ pub unsafe fn __nop() {
     // NOTE: This is a `pure` asm block, but applying that option allows the compiler to eliminate
     // the nop entirely (or to collapse multiple subsequent ones). Since the user probably wants N
     // nops when they call `nop` N times, let's not add that option.
-    asm!("nop");
+    asm!("nop", options(nomem, nostack, preserves_flags));
 }
 
 // NOTE: No FFI shim, this requires inline asm.
 #[inline(always)]
 pub unsafe fn __pc_r() -> u32 {
     let r;
-    asm!("mov {}, pc", out(reg) r);
+    asm!("mov {}, pc", out(reg) r, options(nomem, nostack, preserves_flags));
     r
 }
 
 // NOTE: No FFI shim, this requires inline asm.
 #[inline(always)]
 pub unsafe fn __pc_w(val: u32) {
-    asm!("mov pc, {}", in(reg) val);
+    asm!("mov pc, {}", in(reg) val, options(nomem, nostack, preserves_flags));
 }
 
 // NOTE: No FFI shim, this requires inline asm.
 #[inline(always)]
 pub unsafe fn __lr_r() -> u32 {
     let r;
-    asm!("mov {}, lr", out(reg) r);
+    asm!("mov {}, lr", out(reg) r, options(nomem, nostack, preserves_flags));
     r
 }
 
 // NOTE: No FFI shim, this requires inline asm.
 #[inline(always)]
 pub unsafe fn __lr_w(val: u32) {
-    asm!("mov lr, {}", in(reg) val);
+    asm!("mov lr, {}", in(reg) val, options(nomem, nostack, preserves_flags));
 }
 
 #[inline(always)]
 pub unsafe fn __primask_r() -> u32 {
     let r;
-    asm!("mrs {}, PRIMASK", out(reg) r);
+    asm!("mrs {}, PRIMASK", out(reg) r, options(nomem, nostack, preserves_flags));
     r
 }
 
 #[inline(always)]
 pub unsafe fn __psp_r() -> u32 {
     let r;
-    asm!("mrs {}, PSP", out(reg) r);
+    asm!("mrs {}, PSP", out(reg) r, options(nomem, nostack, preserves_flags));
     r
 }
 
 #[inline(always)]
 pub unsafe fn __psp_w(val: u32) {
-    asm!("msr PSP, {}", in(reg) val);
+    // See comment on __msp_w. Unlike MSP, there are legitimate use-cases for modifying PSP
+    // if MSP is currently being used as the stack pointer.
+    asm!("msr PSP, {}", in(reg) val, options(nomem, nostack, preserves_flags));
 }
 
 #[inline(always)]
 pub unsafe fn __sev() {
-    asm!("sev");
+    asm!("sev", options(nomem, nostack, preserves_flags));
 }
 
 #[inline(always)]
 pub unsafe fn __udf() -> ! {
-    asm!("udf #0", options(noreturn));
+    asm!("udf #0", options(noreturn, nomem, nostack, preserves_flags));
 }
 
 #[inline(always)]
 pub unsafe fn __wfe() {
-    asm!("wfe");
+    asm!("wfe", options(nomem, nostack, preserves_flags));
 }
 
 #[inline(always)]
 pub unsafe fn __wfi() {
-    asm!("wfi");
+    asm!("wfi", options(nomem, nostack, preserves_flags));
 }
 
 /// Semihosting syscall.
 #[inline(always)]
 pub unsafe fn __sh_syscall(mut nr: u32, arg: u32) -> u32 {
-    asm!("bkpt #0xab", inout("r0") nr, in("r1") arg);
+    asm!("bkpt #0xab", inout("r0") nr, in("r1") arg, options(nomem, nostack, preserves_flags));
     nr
 }
 
@@ -205,7 +214,7 @@ pub unsafe fn __bootstrap(msp: u32, rv: u32) -> ! {
         spsel = in(reg) 2,
         msp = in(reg) msp,
         rv = in(reg) rv,
-        options(noreturn),
+        options(noreturn, nomem, nostack),
     );
 }
 
@@ -214,29 +223,30 @@ pub unsafe fn __bootstrap(msp: u32, rv: u32) -> ! {
 pub use self::v7m::*;
 #[cfg(any(armv7m, armv8m_main))]
 mod v7m {
+    use core::arch::asm;
     use core::sync::atomic::{compiler_fence, Ordering};
 
     #[inline(always)]
     pub unsafe fn __basepri_max(val: u8) {
-        asm!("msr BASEPRI_MAX, {}", in(reg) val);
+        asm!("msr BASEPRI_MAX, {}", in(reg) val, options(nomem, nostack, preserves_flags));
     }
 
     #[inline(always)]
     pub unsafe fn __basepri_r() -> u8 {
         let r;
-        asm!("mrs {}, BASEPRI", out(reg) r);
+        asm!("mrs {}, BASEPRI", out(reg) r, options(nomem, nostack, preserves_flags));
         r
     }
 
     #[inline(always)]
     pub unsafe fn __basepri_w(val: u8) {
-        asm!("msr BASEPRI, {}", in(reg) val);
+        asm!("msr BASEPRI, {}", in(reg) val, options(nomem, nostack, preserves_flags));
     }
 
     #[inline(always)]
     pub unsafe fn __faultmask_r() -> u32 {
         let r;
-        asm!("mrs {}, FAULTMASK", out(reg) r);
+        asm!("mrs {}, FAULTMASK", out(reg) r, options(nomem, nostack, preserves_flags));
         r
     }
 
@@ -255,6 +265,7 @@ mod v7m {
             out(reg) _,
             out(reg) _,
             out(reg) _,
+            options(nostack),
         );
         compiler_fence(Ordering::SeqCst);
     }
@@ -274,6 +285,7 @@ mod v7m {
             out(reg) _,
             out(reg) _,
             out(reg) _,
+            options(nostack),
         );
         compiler_fence(Ordering::SeqCst);
     }
@@ -283,6 +295,8 @@ mod v7m {
 pub use self::v7em::*;
 #[cfg(armv7em)]
 mod v7em {
+    use core::arch::asm;
+
     #[inline(always)]
     pub unsafe fn __basepri_max_cm7_r0p1(val: u8) {
         asm!(
@@ -295,6 +309,7 @@ mod v7em {
             "cpsie i",
             in(reg) val,
             out(reg) _,
+            options(nomem, nostack, preserves_flags),
         );
     }
 
@@ -310,6 +325,7 @@ mod v7em {
             "cpsie i",
             in(reg) val,
             out(reg) _,
+            options(nomem, nostack, preserves_flags),
         );
     }
 }
@@ -319,45 +335,63 @@ pub use self::v8m::*;
 /// Baseline and Mainline.
 #[cfg(armv8m)]
 mod v8m {
+    use core::arch::asm;
+
     #[inline(always)]
     pub unsafe fn __tt(mut target: u32) -> u32 {
-        asm!("tt {target}, {target}", target = inout(reg) target);
+        asm!(
+            "tt {target}, {target}",
+            target = inout(reg) target,
+            options(nomem, nostack, preserves_flags),
+        );
         target
     }
 
     #[inline(always)]
     pub unsafe fn __ttt(mut target: u32) -> u32 {
-        asm!("ttt {target}, {target}", target = inout(reg) target);
+        asm!(
+            "ttt {target}, {target}",
+            target = inout(reg) target,
+            options(nomem, nostack, preserves_flags),
+        );
         target
     }
 
     #[inline(always)]
     pub unsafe fn __tta(mut target: u32) -> u32 {
-        asm!("tta {target}, {target}", target = inout(reg) target);
+        asm!(
+            "tta {target}, {target}",
+            target = inout(reg) target,
+            options(nomem, nostack, preserves_flags),
+        );
         target
     }
 
     #[inline(always)]
     pub unsafe fn __ttat(mut target: u32) -> u32 {
-        asm!("ttat {target}, {target}", target = inout(reg) target);
+        asm!(
+            "ttat {target}, {target}",
+            target = inout(reg) target,
+            options(nomem, nostack, preserves_flags),
+        );
         target
     }
 
     #[inline(always)]
     pub unsafe fn __msp_ns_r() -> u32 {
         let r;
-        asm!("mrs {}, MSP_NS", out(reg) r);
+        asm!("mrs {}, MSP_NS", out(reg) r, options(nomem, nostack, preserves_flags));
         r
     }
 
     #[inline(always)]
     pub unsafe fn __msp_ns_w(val: u32) {
-        asm!("msr MSP_NS, {}", in(reg) val);
+        asm!("msr MSP_NS, {}", in(reg) val, options(nomem, nostack, preserves_flags));
     }
 
     #[inline(always)]
     pub unsafe fn __bxns(val: u32) {
-        asm!("BXNS {}", in(reg) val);
+        asm!("BXNS {}", in(reg) val, options(nomem, nostack, preserves_flags));
     }
 }
 
@@ -366,28 +400,30 @@ pub use self::v8m_main::*;
 /// Mainline only.
 #[cfg(armv8m_main)]
 mod v8m_main {
+    use core::arch::asm;
+
     #[inline(always)]
     pub unsafe fn __msplim_r() -> u32 {
         let r;
-        asm!("mrs {}, MSPLIM", out(reg) r);
+        asm!("mrs {}, MSPLIM", out(reg) r, options(nomem, nostack, preserves_flags));
         r
     }
 
     #[inline(always)]
     pub unsafe fn __msplim_w(val: u32) {
-        asm!("msr MSPLIM, {}", in(reg) val);
+        asm!("msr MSPLIM, {}", in(reg) val, options(nomem, nostack, preserves_flags));
     }
 
     #[inline(always)]
     pub unsafe fn __psplim_r() -> u32 {
         let r;
-        asm!("mrs {}, PSPLIM", out(reg) r);
+        asm!("mrs {}, PSPLIM", out(reg) r, options(nomem, nostack, preserves_flags));
         r
     }
 
     #[inline(always)]
     pub unsafe fn __psplim_w(val: u32) {
-        asm!("msr PSPLIM, {}", in(reg) val);
+        asm!("msr PSPLIM, {}", in(reg) val, options(nomem, nostack, preserves_flags));
     }
 }
 
@@ -396,15 +432,17 @@ pub use self::fpu::*;
 /// All targets with FPU.
 #[cfg(has_fpu)]
 mod fpu {
+    use core::arch::asm;
+
     #[inline(always)]
     pub unsafe fn __fpscr_r() -> u32 {
         let r;
-        asm!("vmrs {}, fpscr", out(reg) r);
+        asm!("vmrs {}, fpscr", out(reg) r, options(nomem, nostack, preserves_flags));
         r
     }
 
     #[inline(always)]
     pub unsafe fn __fpscr_w(val: u32) {
-        asm!("vmsr fpscr, {}", in(reg) val);
+        asm!("vmsr fpscr, {}", in(reg) val, options(nomem, nostack));
     }
 }
diff --git a/asm/lib.rs b/asm/lib.rs
index fc8ddc8d..48f3dc21 100644
--- a/asm/lib.rs
+++ b/asm/lib.rs
@@ -34,6 +34,8 @@
 #![no_std]
 #![crate_type = "staticlib"]
 #![deny(warnings)]
+// Don't warn about feature(asm) being stable on Rust >= 1.59.0
+#![allow(stable_features)]
 
 mod inline;
 
diff --git a/bin/thumbv6m-none-eabi-lto.a b/bin/thumbv6m-none-eabi-lto.a
index 6136ec6b..a203d7ae 100644
Binary files a/bin/thumbv6m-none-eabi-lto.a and b/bin/thumbv6m-none-eabi-lto.a differ
diff --git a/bin/thumbv6m-none-eabi.a b/bin/thumbv6m-none-eabi.a
index c42f5791..9640a699 100644
Binary files a/bin/thumbv6m-none-eabi.a and b/bin/thumbv6m-none-eabi.a differ
diff --git a/bin/thumbv7em-none-eabi-lto.a b/bin/thumbv7em-none-eabi-lto.a
index c2c040a8..b34ac64f 100644
Binary files a/bin/thumbv7em-none-eabi-lto.a and b/bin/thumbv7em-none-eabi-lto.a differ
diff --git a/bin/thumbv7em-none-eabi.a b/bin/thumbv7em-none-eabi.a
index 660360f8..88acbddf 100644
Binary files a/bin/thumbv7em-none-eabi.a and b/bin/thumbv7em-none-eabi.a differ
diff --git a/bin/thumbv7em-none-eabihf-lto.a b/bin/thumbv7em-none-eabihf-lto.a
index eba19849..6de94bbf 100644
Binary files a/bin/thumbv7em-none-eabihf-lto.a and b/bin/thumbv7em-none-eabihf-lto.a differ
diff --git a/bin/thumbv7em-none-eabihf.a b/bin/thumbv7em-none-eabihf.a
index 1561fa40..cf91a7a5 100644
Binary files a/bin/thumbv7em-none-eabihf.a and b/bin/thumbv7em-none-eabihf.a differ
diff --git a/bin/thumbv7m-none-eabi-lto.a b/bin/thumbv7m-none-eabi-lto.a
index d964314e..7f677a93 100644
Binary files a/bin/thumbv7m-none-eabi-lto.a and b/bin/thumbv7m-none-eabi-lto.a differ
diff --git a/bin/thumbv7m-none-eabi.a b/bin/thumbv7m-none-eabi.a
index f541274d..ff4bf211 100644
Binary files a/bin/thumbv7m-none-eabi.a and b/bin/thumbv7m-none-eabi.a differ
diff --git a/bin/thumbv8m.base-none-eabi-lto.a b/bin/thumbv8m.base-none-eabi-lto.a
index 8a6ed42f..f62acafd 100644
Binary files a/bin/thumbv8m.base-none-eabi-lto.a and b/bin/thumbv8m.base-none-eabi-lto.a differ
diff --git a/bin/thumbv8m.base-none-eabi.a b/bin/thumbv8m.base-none-eabi.a
index 33cd9081..c0cc96c4 100644
Binary files a/bin/thumbv8m.base-none-eabi.a and b/bin/thumbv8m.base-none-eabi.a differ
diff --git a/bin/thumbv8m.main-none-eabi-lto.a b/bin/thumbv8m.main-none-eabi-lto.a
index 8e6ff0a9..1a515152 100644
Binary files a/bin/thumbv8m.main-none-eabi-lto.a and b/bin/thumbv8m.main-none-eabi-lto.a differ
diff --git a/bin/thumbv8m.main-none-eabi.a b/bin/thumbv8m.main-none-eabi.a
index 898fea70..d017a15b 100644
Binary files a/bin/thumbv8m.main-none-eabi.a and b/bin/thumbv8m.main-none-eabi.a differ
diff --git a/bin/thumbv8m.main-none-eabihf-lto.a b/bin/thumbv8m.main-none-eabihf-lto.a
index d9a636ab..fd3dc928 100644
Binary files a/bin/thumbv8m.main-none-eabihf-lto.a and b/bin/thumbv8m.main-none-eabihf-lto.a differ
diff --git a/bin/thumbv8m.main-none-eabihf.a b/bin/thumbv8m.main-none-eabihf.a
index b0513b75..223ff1df 100644
Binary files a/bin/thumbv8m.main-none-eabihf.a and b/bin/thumbv8m.main-none-eabihf.a differ
diff --git a/build.rs b/build.rs
index dc9b3a02..23ceebad 100644
--- a/build.rs
+++ b/build.rs
@@ -3,9 +3,14 @@ use std::{env, fs};
 
 fn main() {
     let target = env::var("TARGET").unwrap();
+    let host_triple = env::var("HOST").unwrap();
     let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
     let name = env::var("CARGO_PKG_NAME").unwrap();
 
+    if host_triple == target {
+        println!("cargo:rustc-cfg=native");
+    }
+
     if target.starts_with("thumb") {
         let suffix = if env::var_os("CARGO_FEATURE_LINKER_PLUGIN_LTO").is_some() {
             "-lto"
diff --git a/src/delay.rs b/src/delay.rs
index 8ed1fea0..66a63bf6 100644
--- a/src/delay.rs
+++ b/src/delay.rs
@@ -6,7 +6,7 @@ use embedded_hal::blocking::delay::{DelayMs, DelayUs};
 /// System timer (SysTick) as a delay provider.
 pub struct Delay {
     syst: SYST,
-    ahb_frequency: u32,
+    frequency: u32,
 }
 
 impl Delay {
@@ -14,13 +14,19 @@ impl Delay {
     ///
     /// `ahb_frequency` is a frequency of the AHB bus in Hz.
     #[inline]
-    pub fn new(mut syst: SYST, ahb_frequency: u32) -> Self {
-        syst.set_clock_source(SystClkSource::Core);
+    pub fn new(syst: SYST, ahb_frequency: u32) -> Self {
+        Self::with_source(syst, ahb_frequency, SystClkSource::Core)
+    }
 
-        Delay {
-            syst,
-            ahb_frequency,
-        }
+    /// Configures the system timer (SysTick) as a delay provider
+    /// with a clock source.
+    ///
+    /// `frequency` is the frequency of your `clock_source` in Hz.
+    #[inline]
+    pub fn with_source(mut syst: SYST, frequency: u32, clock_source: SystClkSource) -> Self {
+        syst.set_clock_source(clock_source);
+
+        Delay { syst, frequency }
     }
 
     /// Releases the system timer (SysTick) resource.
@@ -32,7 +38,7 @@ impl Delay {
     /// Delay using the Cortex-M systick for a certain duration, in µs.
     #[allow(clippy::missing_inline_in_public_items)]
     pub fn delay_us(&mut self, us: u32) {
-        let ticks = (u64::from(us)) * (u64::from(self.ahb_frequency)) / 1_000_000;
+        let ticks = (u64::from(us)) * (u64::from(self.frequency)) / 1_000_000;
 
         let full_cycles = ticks >> 24;
         if full_cycles > 0 {
diff --git a/src/lib.rs b/src/lib.rs
index 6a736924..beff6e8f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -76,6 +76,8 @@
 //  - A generated #[derive(Debug)] function (in which case the attribute needs
 //    to be applied to the struct).
 #![deny(clippy::missing_inline_in_public_items)]
+// Don't warn about feature(asm) being stable on Rust >= 1.59.0
+#![allow(stable_features)]
 
 extern crate bare_metal;
 extern crate volatile_register;
diff --git a/src/peripheral/icb.rs b/src/peripheral/icb.rs
index 9b29655a..e1de33b3 100644
--- a/src/peripheral/icb.rs
+++ b/src/peripheral/icb.rs
@@ -1,6 +1,6 @@
 //! Implementation Control Block
 
-#[cfg(any(armv7m, armv8m, target_arch = "x86_64"))]
+#[cfg(any(armv7m, armv8m, native))]
 use volatile_register::RO;
 use volatile_register::RW;
 
@@ -12,12 +12,12 @@ pub struct RegisterBlock {
     /// The bottom four bits of this register give the number of implemented
     /// interrupt lines, divided by 32. So a value of `0b0010` indicates 64
     /// interrupts.
-    #[cfg(any(armv7m, armv8m, target_arch = "x86_64"))]
+    #[cfg(any(armv7m, armv8m, native))]
     pub ictr: RO<u32>,
 
     /// The ICTR is not defined in the ARMv6-M Architecture Reference manual, so
     /// we replace it with this.
-    #[cfg(not(any(armv7m, armv8m, target_arch = "x86_64")))]
+    #[cfg(not(any(armv7m, armv8m, native)))]
     _reserved: u32,
 
     /// Auxiliary Control Register
diff --git a/src/peripheral/mod.rs b/src/peripheral/mod.rs
index 5c5e7ce6..37565537 100644
--- a/src/peripheral/mod.rs
+++ b/src/peripheral/mod.rs
@@ -71,8 +71,8 @@ pub mod dcb;
 pub mod dwt;
 #[cfg(not(armv6m))]
 pub mod fpb;
-// NOTE(target_arch) is for documentation purposes
-#[cfg(any(has_fpu, target_arch = "x86_64"))]
+// NOTE(native) is for documentation purposes
+#[cfg(any(has_fpu, native))]
 pub mod fpu;
 pub mod icb;
 #[cfg(all(not(armv6m), not(armv8m_base)))]
@@ -405,7 +405,7 @@ pub struct FPU {
 
 unsafe impl Send for FPU {}
 
-#[cfg(any(has_fpu, target_arch = "x86_64"))]
+#[cfg(any(has_fpu, native))]
 impl FPU {
     /// Pointer to the register block
     pub const PTR: *const fpu::RegisterBlock = 0xE000_EF30 as *const _;
@@ -417,7 +417,7 @@ impl FPU {
     }
 }
 
-#[cfg(any(has_fpu, target_arch = "x86_64"))]
+#[cfg(any(has_fpu, native))]
 impl ops::Deref for FPU {
     type Target = self::fpu::RegisterBlock;
 
diff --git a/src/peripheral/scb.rs b/src/peripheral/scb.rs
index 28cfca86..eeea0c5b 100644
--- a/src/peripheral/scb.rs
+++ b/src/peripheral/scb.rs
@@ -182,7 +182,7 @@ impl SCB {
             5 => VectActive::Exception(Exception::BusFault),
             #[cfg(not(armv6m))]
             6 => VectActive::Exception(Exception::UsageFault),
-            #[cfg(any(armv8m, target_arch = "x86_64"))]
+            #[cfg(any(armv8m, native))]
             7 => VectActive::Exception(Exception::SecureFault),
             11 => VectActive::Exception(Exception::SVCall),
             #[cfg(not(armv6m))]
@@ -197,7 +197,7 @@ impl SCB {
 /// Processor core exceptions (internal interrupts)
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-#[cfg_attr(feature = "std-map", derive(PartialOrd, Hash))]
+#[cfg_attr(feature = "std", derive(PartialOrd, Hash))]
 pub enum Exception {
     /// Non maskable interrupt
     NonMaskableInt,
@@ -218,7 +218,7 @@ pub enum Exception {
     UsageFault,
 
     /// Secure fault interrupt (only on ARMv8-M)
-    #[cfg(any(armv8m, target_arch = "x86_64"))]
+    #[cfg(any(armv8m, native))]
     SecureFault,
 
     /// SV call interrupt
@@ -250,7 +250,7 @@ impl Exception {
             Exception::BusFault => -11,
             #[cfg(not(armv6m))]
             Exception::UsageFault => -10,
-            #[cfg(any(armv8m, target_arch = "x86_64"))]
+            #[cfg(any(armv8m, native))]
             Exception::SecureFault => -9,
             Exception::SVCall => -5,
             #[cfg(not(armv6m))]
@@ -264,7 +264,7 @@ impl Exception {
 /// Active exception number
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
-#[cfg_attr(feature = "std-map", derive(PartialOrd, Hash))]
+#[cfg_attr(feature = "std", derive(PartialOrd, Hash))]
 pub enum VectActive {
     /// Thread mode
     ThreadMode,
@@ -293,7 +293,7 @@ impl VectActive {
             5 => VectActive::Exception(Exception::BusFault),
             #[cfg(not(armv6m))]
             6 => VectActive::Exception(Exception::UsageFault),
-            #[cfg(any(armv8m, target_arch = "x86_64"))]
+            #[cfg(any(armv8m, native))]
             7 => VectActive::Exception(Exception::SecureFault),
             11 => VectActive::Exception(Exception::SVCall),
             #[cfg(not(armv6m))]
@@ -934,7 +934,7 @@ pub enum SystemHandler {
     UsageFault = 6,
 
     /// Secure fault interrupt (only on ARMv8-M)
-    #[cfg(any(armv8m, target_arch = "x86_64"))]
+    #[cfg(any(armv8m, native))]
     SecureFault = 7,
 
     /// SV call interrupt
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index 8742f9b1..b5b5c5f4 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -11,5 +11,5 @@ harness = false
 
 [dependencies]
 ar = "0.8.0"
-cortex-m = { path = "../", features = ["serde", "std-map"] }
+cortex-m = { path = "../", features = ["serde", "std"] }
 serde_json = "1"