--- atomic_backup.rs	2018-07-10 00:29:48.000000000 +0800
+++ atomic.rs	2018-07-12 18:32:26.000000000 +0800
@@ -1556,15 +1556,9 @@
 }
 
 #[inline]
-unsafe fn atomic_store<T>(dst: *mut T, val: T, order: Ordering) {
-    match order {
-        Release => intrinsics::atomic_store_rel(dst, val),
-        Relaxed => intrinsics::atomic_store_relaxed(dst, val),
-        SeqCst => intrinsics::atomic_store(dst, val),
-        Acquire => panic!("there is no such thing as an acquire store"),
-        AcqRel => panic!("there is no such thing as an acquire/release store"),
-        __Nonexhaustive => panic!("invalid memory ordering"),
-    }
+unsafe fn atomic_store<T>(dst: *mut T, val: T, _order: Ordering) {
+    use ptr::write;
+    write(dst, val);
 }
 
 #[inline]
@@ -1580,15 +1574,22 @@
 }
 
 #[inline]
-unsafe fn atomic_swap<T>(dst: *mut T, val: T, order: Ordering) -> T {
-    match order {
-        Acquire => intrinsics::atomic_xchg_acq(dst, val),
-        Release => intrinsics::atomic_xchg_rel(dst, val),
-        AcqRel => intrinsics::atomic_xchg_acqrel(dst, val),
-        Relaxed => intrinsics::atomic_xchg_relaxed(dst, val),
-        SeqCst => intrinsics::atomic_xchg(dst, val),
-        __Nonexhaustive => panic!("invalid memory ordering"),
+unsafe fn atomic_swap<T>(dst: *mut T, val: T, _order: Ordering) -> T {
+    let sstatus: usize;
+    asm!("csrrs $0, 0x100, x0" : "=r"(sstatus) ::: "volatile");
+    // Disable interrupt: sstatus::clear_sie()
+    asm!("csrrc x0, 0x100, $0" :: "r"(1) :: "volatile");
+
+    use ptr::{read, write};
+    let ret = read(dst);
+    write(dst, val);
+
+    let sie = sstatus & 1 != 0;
+    if sie {
+        // Enable interrupt: sstatus::set_sie()
+        asm!("csrrs x0, 0x100, $0" :: "r"(1) :: "volatile");
     }
+    ret
 }
 
 /// Returns the previous value (like __sync_fetch_and_add).
@@ -1618,29 +1619,30 @@
 }
 
 #[inline]
-unsafe fn atomic_compare_exchange<T>(dst: *mut T,
+#[cfg(target_arch = "riscv")]
+unsafe fn atomic_compare_exchange<T: PartialEq>(dst: *mut T,
                                      old: T,
                                      new: T,
-                                     success: Ordering,
-                                     failure: Ordering)
+                                     _success: Ordering,
+                                     _failure: Ordering)
                                      -> Result<T, T> {
-    let (val, ok) = match (success, failure) {
-        (Acquire, Acquire) => intrinsics::atomic_cxchg_acq(dst, old, new),
-        (Release, Relaxed) => intrinsics::atomic_cxchg_rel(dst, old, new),
-        (AcqRel, Acquire) => intrinsics::atomic_cxchg_acqrel(dst, old, new),
-        (Relaxed, Relaxed) => intrinsics::atomic_cxchg_relaxed(dst, old, new),
-        (SeqCst, SeqCst) => intrinsics::atomic_cxchg(dst, old, new),
-        (Acquire, Relaxed) => intrinsics::atomic_cxchg_acq_failrelaxed(dst, old, new),
-        (AcqRel, Relaxed) => intrinsics::atomic_cxchg_acqrel_failrelaxed(dst, old, new),
-        (SeqCst, Relaxed) => intrinsics::atomic_cxchg_failrelaxed(dst, old, new),
-        (SeqCst, Acquire) => intrinsics::atomic_cxchg_failacq(dst, old, new),
-        (__Nonexhaustive, _) => panic!("invalid memory ordering"),
-        (_, __Nonexhaustive) => panic!("invalid memory ordering"),
-        (_, AcqRel) => panic!("there is no such thing as an acquire/release failure ordering"),
-        (_, Release) => panic!("there is no such thing as a release failure ordering"),
-        _ => panic!("a failure ordering can't be stronger than a success ordering"),
-    };
-    if ok { Ok(val) } else { Err(val) }
+    let sstatus: usize;
+    asm!("csrrs $0, 0x100, x0" : "=r"(sstatus) ::: "volatile");
+    // Disable interrupt: sstatus::clear_sie()
+    asm!("csrrc x0, 0x100, $0" :: "r"(1) :: "volatile");
+
+    use ptr::{read, write};
+    let ret = read(dst);
+    if ret == old {
+        write(dst, new);
+    }
+
+    let sie = sstatus & 1 != 0;
+    if sie {
+        // Enable interrupt: sstatus::set_sie()
+        asm!("csrrs x0, 0x100, $0" :: "r"(1) :: "volatile");
+    }
+    Ok(ret)
 }
 
 #[inline]
