diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index f8b06bf2e9762..9e9fab1e6a502 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -926,7 +926,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
     let os = &sess.target.target.target_os;
     let env = &sess.target.target.target_env;
     let vendor = &sess.target.target.target_vendor;
-    let max_atomic_width = sess.target.target.options.max_atomic_width;
+    let max_atomic_width = sess.target.target.max_atomic_width();
 
     let fam = if let Some(ref fam) = sess.target.target.options.target_family {
         intern(fam)
diff --git a/src/librustc_back/target/aarch64_apple_ios.rs b/src/librustc_back/target/aarch64_apple_ios.rs
index 660ed0ac7b843..0d85d1ad90ad0 100644
--- a/src/librustc_back/target/aarch64_apple_ios.rs
+++ b/src/librustc_back/target/aarch64_apple_ios.rs
@@ -25,7 +25,7 @@ pub fn target() -> TargetResult {
         options: TargetOptions {
             features: "+neon,+fp-armv8,+cyclone".to_string(),
             eliminate_frame_pointer: false,
-            max_atomic_width: 128,
+            max_atomic_width: Some(128),
             .. base
         },
     })
diff --git a/src/librustc_back/target/aarch64_linux_android.rs b/src/librustc_back/target/aarch64_linux_android.rs
index 7f54dab5b5385..8440ed1c4d198 100644
--- a/src/librustc_back/target/aarch64_linux_android.rs
+++ b/src/librustc_back/target/aarch64_linux_android.rs
@@ -12,7 +12,7 @@ use target::{Target, TargetResult};
 
 pub fn target() -> TargetResult {
     let mut base = super::android_base::opts();
-    base.max_atomic_width = 128;
+    base.max_atomic_width = Some(128);
     // As documented in http://developer.android.com/ndk/guides/cpu-features.html
     // the neon (ASIMD) and FP must exist on all android aarch64 targets.
     base.features = "+neon,+fp-armv8".to_string();
diff --git a/src/librustc_back/target/aarch64_unknown_linux_gnu.rs b/src/librustc_back/target/aarch64_unknown_linux_gnu.rs
index cca965f9d4ff1..bb5376ff3ef04 100644
--- a/src/librustc_back/target/aarch64_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/aarch64_unknown_linux_gnu.rs
@@ -12,7 +12,7 @@ use target::{Target, TargetResult};
 
 pub fn target() -> TargetResult {
     let mut base = super::linux_base::opts();
-    base.max_atomic_width = 128;
+    base.max_atomic_width = Some(128);
     Ok(Target {
         llvm_target: "aarch64-unknown-linux-gnu".to_string(),
         target_endian: "little".to_string(),
diff --git a/src/librustc_back/target/arm_linux_androideabi.rs b/src/librustc_back/target/arm_linux_androideabi.rs
index f3a18b13c6783..e1906610441f1 100644
--- a/src/librustc_back/target/arm_linux_androideabi.rs
+++ b/src/librustc_back/target/arm_linux_androideabi.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::android_base::opts();
     base.features = "+v7,+vfp3,+d16".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
 
     Ok(Target {
         llvm_target: "arm-linux-androideabi".to_string(),
diff --git a/src/librustc_back/target/arm_unknown_linux_gnueabi.rs b/src/librustc_back/target/arm_unknown_linux_gnueabi.rs
index e666a8460e5ea..7c6da341da632 100644
--- a/src/librustc_back/target/arm_unknown_linux_gnueabi.rs
+++ b/src/librustc_back/target/arm_unknown_linux_gnueabi.rs
@@ -12,7 +12,7 @@ use target::{Target, TargetOptions, TargetResult};
 
 pub fn target() -> TargetResult {
     let mut base = super::linux_base::opts();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     Ok(Target {
         llvm_target: "arm-unknown-linux-gnueabi".to_string(),
         target_endian: "little".to_string(),
diff --git a/src/librustc_back/target/arm_unknown_linux_gnueabihf.rs b/src/librustc_back/target/arm_unknown_linux_gnueabihf.rs
index d65c89abc2064..45f8f722059e2 100644
--- a/src/librustc_back/target/arm_unknown_linux_gnueabihf.rs
+++ b/src/librustc_back/target/arm_unknown_linux_gnueabihf.rs
@@ -12,7 +12,7 @@ use target::{Target, TargetOptions, TargetResult};
 
 pub fn target() -> TargetResult {
     let mut base = super::linux_base::opts();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     Ok(Target {
         llvm_target: "arm-unknown-linux-gnueabihf".to_string(),
         target_endian: "little".to_string(),
diff --git a/src/librustc_back/target/arm_unknown_linux_musleabi.rs b/src/librustc_back/target/arm_unknown_linux_musleabi.rs
index 028c91eadaeb3..547afb3e8e580 100644
--- a/src/librustc_back/target/arm_unknown_linux_musleabi.rs
+++ b/src/librustc_back/target/arm_unknown_linux_musleabi.rs
@@ -16,7 +16,7 @@ pub fn target() -> TargetResult {
     // Most of these settings are copied from the arm_unknown_linux_gnueabi
     // target.
     base.features = "+v6".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     Ok(Target {
         // It's important we use "gnueabi" and not "musleabi" here. LLVM uses it
         // to determine the calling convention and float ABI, and it doesn't
diff --git a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs
index c7dda186f4258..7e9996dea983c 100644
--- a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs
+++ b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs
@@ -16,7 +16,7 @@ pub fn target() -> TargetResult {
     // Most of these settings are copied from the arm_unknown_linux_gnueabihf
     // target.
     base.features = "+v6,+vfp2".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     Ok(Target {
         // It's important we use "gnueabihf" and not "musleabihf" here. LLVM
         // uses it to determine the calling convention and float ABI, and it
diff --git a/src/librustc_back/target/armv7_apple_ios.rs b/src/librustc_back/target/armv7_apple_ios.rs
index 71533a09b1672..2bef25327a438 100644
--- a/src/librustc_back/target/armv7_apple_ios.rs
+++ b/src/librustc_back/target/armv7_apple_ios.rs
@@ -24,7 +24,7 @@ pub fn target() -> TargetResult {
         target_vendor: "apple".to_string(),
         options: TargetOptions {
             features: "+v7,+vfp3,+neon".to_string(),
-            max_atomic_width: 64,
+            max_atomic_width: Some(64),
             .. base
         }
     })
diff --git a/src/librustc_back/target/armv7_linux_androideabi.rs b/src/librustc_back/target/armv7_linux_androideabi.rs
index 1c59262e04198..21ad18223dbc7 100644
--- a/src/librustc_back/target/armv7_linux_androideabi.rs
+++ b/src/librustc_back/target/armv7_linux_androideabi.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::android_base::opts();
     base.features = "+v7,+thumb2,+vfp3,+d16".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
 
     Ok(Target {
         llvm_target: "armv7-none-linux-android".to_string(),
diff --git a/src/librustc_back/target/armv7_unknown_linux_gnueabihf.rs b/src/librustc_back/target/armv7_unknown_linux_gnueabihf.rs
index 7e0306a03e2f6..1abf8b0b69a2a 100644
--- a/src/librustc_back/target/armv7_unknown_linux_gnueabihf.rs
+++ b/src/librustc_back/target/armv7_unknown_linux_gnueabihf.rs
@@ -26,7 +26,7 @@ pub fn target() -> TargetResult {
             // Info about features at https://wiki.debian.org/ArmHardFloatPort
             features: "+v7,+vfp3,+d16,+thumb2".to_string(),
             cpu: "generic".to_string(),
-            max_atomic_width: 64,
+            max_atomic_width: Some(64),
             .. base
         }
     })
diff --git a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs
index e40704e5d4997..efed7963c95e6 100644
--- a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs
+++ b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs
@@ -17,7 +17,7 @@ pub fn target() -> TargetResult {
     // target.
     base.features = "+v7,+vfp3,+neon".to_string();
     base.cpu = "cortex-a8".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     Ok(Target {
         // It's important we use "gnueabihf" and not "musleabihf" here. LLVM
         // uses it to determine the calling convention and float ABI, and LLVM
diff --git a/src/librustc_back/target/armv7s_apple_ios.rs b/src/librustc_back/target/armv7s_apple_ios.rs
index f24b9969910ef..0b3ebf1294bd0 100644
--- a/src/librustc_back/target/armv7s_apple_ios.rs
+++ b/src/librustc_back/target/armv7s_apple_ios.rs
@@ -24,7 +24,7 @@ pub fn target() -> TargetResult {
         target_vendor: "apple".to_string(),
         options: TargetOptions {
             features: "+v7,+vfp4,+neon".to_string(),
-            max_atomic_width: 64,
+            max_atomic_width: Some(64),
             .. base
         }
     })
diff --git a/src/librustc_back/target/asmjs_unknown_emscripten.rs b/src/librustc_back/target/asmjs_unknown_emscripten.rs
index 667f7cf2c214a..d86a9b093272e 100644
--- a/src/librustc_back/target/asmjs_unknown_emscripten.rs
+++ b/src/librustc_back/target/asmjs_unknown_emscripten.rs
@@ -21,7 +21,7 @@ pub fn target() -> Result<Target, String> {
         linker_is_gnu: true,
         allow_asm: false,
         obj_is_bitcode: true,
-        max_atomic_width: 32,
+        max_atomic_width: Some(32),
         post_link_args: vec!["-s".to_string(), "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()],
         .. Default::default()
     };
diff --git a/src/librustc_back/target/i386_apple_ios.rs b/src/librustc_back/target/i386_apple_ios.rs
index 94146fe9d9885..319ada4f8e17c 100644
--- a/src/librustc_back/target/i386_apple_ios.rs
+++ b/src/librustc_back/target/i386_apple_ios.rs
@@ -23,7 +23,7 @@ pub fn target() -> TargetResult {
         target_env: "".to_string(),
         target_vendor: "apple".to_string(),
         options: TargetOptions {
-            max_atomic_width: 64,
+            max_atomic_width: Some(64),
             .. base
         }
     })
diff --git a/src/librustc_back/target/i686_apple_darwin.rs b/src/librustc_back/target/i686_apple_darwin.rs
index 4876a3489d470..d3b09d9a0f112 100644
--- a/src/librustc_back/target/i686_apple_darwin.rs
+++ b/src/librustc_back/target/i686_apple_darwin.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::apple_base::opts();
     base.cpu = "yonah".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     base.pre_link_args.push("-m32".to_string());
 
     Ok(Target {
diff --git a/src/librustc_back/target/i686_linux_android.rs b/src/librustc_back/target/i686_linux_android.rs
index 1de629238a13c..a2c007d496960 100644
--- a/src/librustc_back/target/i686_linux_android.rs
+++ b/src/librustc_back/target/i686_linux_android.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::android_base::opts();
 
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
 
     // http://developer.android.com/ndk/guides/abis.html#x86
     base.cpu = "pentiumpro".to_string();
diff --git a/src/librustc_back/target/i686_pc_windows_gnu.rs b/src/librustc_back/target/i686_pc_windows_gnu.rs
index 2c19b8109c362..0c2c5433e6c41 100644
--- a/src/librustc_back/target/i686_pc_windows_gnu.rs
+++ b/src/librustc_back/target/i686_pc_windows_gnu.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::windows_base::opts();
     base.cpu = "pentium4".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
 
     // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
     // space available to x86 Windows binaries on x86_64.
diff --git a/src/librustc_back/target/i686_pc_windows_msvc.rs b/src/librustc_back/target/i686_pc_windows_msvc.rs
index cb02fcc308c2d..2290d2057f130 100644
--- a/src/librustc_back/target/i686_pc_windows_msvc.rs
+++ b/src/librustc_back/target/i686_pc_windows_msvc.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::windows_msvc_base::opts();
     base.cpu = "pentium4".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
 
     // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
     // space available to x86 Windows binaries on x86_64.
diff --git a/src/librustc_back/target/i686_unknown_dragonfly.rs b/src/librustc_back/target/i686_unknown_dragonfly.rs
index f96ec004b481e..d8f8431e66e7f 100644
--- a/src/librustc_back/target/i686_unknown_dragonfly.rs
+++ b/src/librustc_back/target/i686_unknown_dragonfly.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::dragonfly_base::opts();
     base.cpu = "pentium4".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     base.pre_link_args.push("-m32".to_string());
 
     Ok(Target {
diff --git a/src/librustc_back/target/i686_unknown_freebsd.rs b/src/librustc_back/target/i686_unknown_freebsd.rs
index 3489ecfe614d9..ddbc74f25c9cd 100644
--- a/src/librustc_back/target/i686_unknown_freebsd.rs
+++ b/src/librustc_back/target/i686_unknown_freebsd.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::freebsd_base::opts();
     base.cpu = "pentium4".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     base.pre_link_args.push("-m32".to_string());
 
     Ok(Target {
diff --git a/src/librustc_back/target/i686_unknown_haiku.rs b/src/librustc_back/target/i686_unknown_haiku.rs
index 862016704f47c..9078206c9e069 100644
--- a/src/librustc_back/target/i686_unknown_haiku.rs
+++ b/src/librustc_back/target/i686_unknown_haiku.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::haiku_base::opts();
     base.cpu = "pentium4".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     base.pre_link_args.push("-m32".to_string());
 
     Ok(Target {
diff --git a/src/librustc_back/target/i686_unknown_linux_gnu.rs b/src/librustc_back/target/i686_unknown_linux_gnu.rs
index f2e865c015e35..bf9c28b0c10e5 100644
--- a/src/librustc_back/target/i686_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/i686_unknown_linux_gnu.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::linux_base::opts();
     base.cpu = "pentium4".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     base.pre_link_args.push("-m32".to_string());
 
     Ok(Target {
diff --git a/src/librustc_back/target/i686_unknown_linux_musl.rs b/src/librustc_back/target/i686_unknown_linux_musl.rs
index a0a8de46e2f59..3d563fa6e5d97 100644
--- a/src/librustc_back/target/i686_unknown_linux_musl.rs
+++ b/src/librustc_back/target/i686_unknown_linux_musl.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::linux_musl_base::opts();
     base.cpu = "pentium4".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     base.pre_link_args.push("-m32".to_string());
     base.pre_link_args.push("-Wl,-melf_i386".to_string());
 
diff --git a/src/librustc_back/target/le32_unknown_nacl.rs b/src/librustc_back/target/le32_unknown_nacl.rs
index 9ba6591f587c4..a98a33feb5e9d 100644
--- a/src/librustc_back/target/le32_unknown_nacl.rs
+++ b/src/librustc_back/target/le32_unknown_nacl.rs
@@ -24,7 +24,7 @@ pub fn target() -> TargetResult {
         exe_suffix: ".pexe".to_string(),
         linker_is_gnu: true,
         allow_asm: false,
-        max_atomic_width: 32,
+        max_atomic_width: Some(32),
         .. Default::default()
     };
     Ok(Target {
diff --git a/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs b/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs
index 7e45b32065360..9f0b6fcc4364c 100644
--- a/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs
+++ b/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs
@@ -24,7 +24,7 @@ pub fn target() -> TargetResult {
             // NOTE(mips64r2) matches C toolchain
             cpu: "mips64r2".to_string(),
             features: "+mips64r2".to_string(),
-            max_atomic_width: 64,
+            max_atomic_width: Some(64),
             ..super::linux_base::opts()
         },
     })
diff --git a/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs b/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs
index 338a5da1e1d1d..9c4531c5b2124 100644
--- a/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs
+++ b/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs
@@ -24,7 +24,7 @@ pub fn target() -> TargetResult {
             // NOTE(mips64r2) matches C toolchain
             cpu: "mips64r2".to_string(),
             features: "+mips64r2".to_string(),
-            max_atomic_width: 64,
+            max_atomic_width: Some(64),
             ..super::linux_base::opts()
         },
     })
diff --git a/src/librustc_back/target/mips_unknown_linux_gnu.rs b/src/librustc_back/target/mips_unknown_linux_gnu.rs
index ab967f6b40fbe..e744dce2bb4a1 100644
--- a/src/librustc_back/target/mips_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/mips_unknown_linux_gnu.rs
@@ -23,7 +23,7 @@ pub fn target() -> TargetResult {
         options: TargetOptions {
             cpu: "mips32r2".to_string(),
             features: "+mips32r2".to_string(),
-            max_atomic_width: 32,
+            max_atomic_width: Some(32),
             ..super::linux_base::opts()
         },
     })
diff --git a/src/librustc_back/target/mips_unknown_linux_musl.rs b/src/librustc_back/target/mips_unknown_linux_musl.rs
index 4a69bce53bc97..4254c1b83e319 100644
--- a/src/librustc_back/target/mips_unknown_linux_musl.rs
+++ b/src/librustc_back/target/mips_unknown_linux_musl.rs
@@ -23,7 +23,7 @@ pub fn target() -> TargetResult {
         options: TargetOptions {
             cpu: "mips32r2".to_string(),
             features: "+mips32r2,+soft-float".to_string(),
-            max_atomic_width: 32,
+            max_atomic_width: Some(32),
             ..super::linux_base::opts()
         }
     })
diff --git a/src/librustc_back/target/mips_unknown_linux_uclibc.rs b/src/librustc_back/target/mips_unknown_linux_uclibc.rs
index 529bd310391cd..e6b2672a8e393 100644
--- a/src/librustc_back/target/mips_unknown_linux_uclibc.rs
+++ b/src/librustc_back/target/mips_unknown_linux_uclibc.rs
@@ -23,7 +23,7 @@ pub fn target() -> TargetResult {
         options: TargetOptions {
             cpu: "mips32r2".to_string(),
             features: "+mips32r2,+soft-float".to_string(),
-            max_atomic_width: 32,
+            max_atomic_width: Some(32),
             ..super::linux_base::opts()
         },
     })
diff --git a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs b/src/librustc_back/target/mipsel_unknown_linux_gnu.rs
index b66fb62cd591e..4949055861e57 100644
--- a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/mipsel_unknown_linux_gnu.rs
@@ -24,7 +24,7 @@ pub fn target() -> TargetResult {
         options: TargetOptions {
             cpu: "mips32".to_string(),
             features: "+mips32".to_string(),
-            max_atomic_width: 32,
+            max_atomic_width: Some(32),
             ..super::linux_base::opts()
         },
     })
diff --git a/src/librustc_back/target/mipsel_unknown_linux_musl.rs b/src/librustc_back/target/mipsel_unknown_linux_musl.rs
index a0524e5e76389..f282ac7e88b88 100644
--- a/src/librustc_back/target/mipsel_unknown_linux_musl.rs
+++ b/src/librustc_back/target/mipsel_unknown_linux_musl.rs
@@ -23,7 +23,7 @@ pub fn target() -> TargetResult {
         options: TargetOptions {
             cpu: "mips32".to_string(),
             features: "+mips32,+soft-float".to_string(),
-            max_atomic_width: 32,
+            max_atomic_width: Some(32),
             ..super::linux_base::opts()
         }
     })
diff --git a/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs b/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs
index 1040a0fbe1724..0f9b562068f51 100644
--- a/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs
+++ b/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs
@@ -24,7 +24,7 @@ pub fn target() -> TargetResult {
         options: TargetOptions {
             cpu: "mips32".to_string(),
             features: "+mips32,+soft-float".to_string(),
-            max_atomic_width: 32,
+            max_atomic_width: Some(32),
             ..super::linux_base::opts()
         },
     })
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index 4404af1970e77..1843fc581f1c2 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -66,11 +66,12 @@ mod netbsd_base;
 mod solaris_base;
 mod windows_base;
 mod windows_msvc_base;
+mod thumb_base;
 
 pub type TargetResult = Result<Target, String>;
 
 macro_rules! supported_targets {
-    ( $(($triple:expr, $module:ident)),+ ) => (
+    ( $(($triple:expr, $module:ident),)+ ) => (
         $(mod $module;)*
 
         /// List of supported targets
@@ -191,7 +192,12 @@ supported_targets! {
 
     ("le32-unknown-nacl", le32_unknown_nacl),
     ("asmjs-unknown-emscripten", asmjs_unknown_emscripten),
-    ("wasm32-unknown-emscripten", wasm32_unknown_emscripten)
+    ("wasm32-unknown-emscripten", wasm32_unknown_emscripten),
+
+    ("thumbv6m-none-eabi", thumbv6m_none_eabi),
+    ("thumbv7m-none-eabi", thumbv7m_none_eabi),
+    ("thumbv7em-none-eabi", thumbv7em_none_eabi),
+    ("thumbv7em-none-eabihf", thumbv7em_none_eabihf),
 }
 
 /// Everything `rustc` knows about how to compile for a specific target.
@@ -347,9 +353,8 @@ pub struct TargetOptions {
     // will 'just work'.
     pub obj_is_bitcode: bool,
 
-    /// Maximum integer size in bits that this target can perform atomic
-    /// operations on.
-    pub max_atomic_width: u64,
+    /// Don't use this field; instead use the `.max_atomic_width()` method.
+    pub max_atomic_width: Option<u64>,
 
     /// Panic strategy: "unwind" or "abort"
     pub panic_strategy: PanicStrategy,
@@ -401,7 +406,7 @@ impl Default for TargetOptions {
             allow_asm: true,
             has_elf_tls: false,
             obj_is_bitcode: false,
-            max_atomic_width: 0,
+            max_atomic_width: None,
             panic_strategy: PanicStrategy::Unwind,
         }
     }
@@ -422,6 +427,12 @@ impl Target {
         }
     }
 
+    /// Maximum integer size in bits that this target can perform atomic
+    /// operations on.
+    pub fn max_atomic_width(&self) -> u64 {
+        self.options.max_atomic_width.unwrap_or(self.target_pointer_width.parse().unwrap())
+    }
+
     /// Load a target descriptor from a JSON object.
     pub fn from_json(obj: Json) -> TargetResult {
         // While ugly, this code must remain this way to retain
@@ -460,9 +471,6 @@ impl Target {
             options: Default::default(),
         };
 
-        // Default max-atomic-width to target-pointer-width
-        base.options.max_atomic_width = base.target_pointer_width.parse().unwrap();
-
         macro_rules! key {
             ($key_name:ident) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
@@ -475,11 +483,11 @@ impl Target {
                     .map(|o| o.as_boolean()
                          .map(|s| base.options.$key_name = s));
             } );
-            ($key_name:ident, u64) => ( {
+            ($key_name:ident, Option<u64>) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
                 obj.find(&name[..])
                     .map(|o| o.as_u64()
-                         .map(|s| base.options.$key_name = s));
+                         .map(|s| base.options.$key_name = Some(s)));
             } );
             ($key_name:ident, PanicStrategy) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
@@ -553,7 +561,7 @@ impl Target {
         key!(exe_allocation_crate);
         key!(has_elf_tls, bool);
         key!(obj_is_bitcode, bool);
-        key!(max_atomic_width, u64);
+        key!(max_atomic_width, Option<u64>);
         try!(key!(panic_strategy, PanicStrategy));
 
         Ok(base)
diff --git a/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs b/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs
index 1c04e763417c4..333bfad4a2683 100644
--- a/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs
@@ -14,7 +14,7 @@ pub fn target() -> TargetResult {
     let mut base = super::linux_base::opts();
     base.cpu = "ppc64".to_string();
     base.pre_link_args.push("-m64".to_string());
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
 
     Ok(Target {
         llvm_target: "powerpc64-unknown-linux-gnu".to_string(),
diff --git a/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs b/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs
index 906e28d2f20cb..e75da133314a4 100644
--- a/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs
@@ -14,7 +14,7 @@ pub fn target() -> TargetResult {
     let mut base = super::linux_base::opts();
     base.cpu = "ppc64le".to_string();
     base.pre_link_args.push("-m64".to_string());
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
 
     Ok(Target {
         llvm_target: "powerpc64le-unknown-linux-gnu".to_string(),
diff --git a/src/librustc_back/target/powerpc_unknown_linux_gnu.rs b/src/librustc_back/target/powerpc_unknown_linux_gnu.rs
index aebf9cd68717d..45d28dd031f7e 100644
--- a/src/librustc_back/target/powerpc_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/powerpc_unknown_linux_gnu.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::linux_base::opts();
     base.pre_link_args.push("-m32".to_string());
-    base.max_atomic_width = 32;
+    base.max_atomic_width = Some(32);
 
     Ok(Target {
         llvm_target: "powerpc-unknown-linux-gnu".to_string(),
diff --git a/src/librustc_back/target/s390x_unknown_linux_gnu.rs b/src/librustc_back/target/s390x_unknown_linux_gnu.rs
index 79f2d290e3760..6e2dd6cd67c93 100644
--- a/src/librustc_back/target/s390x_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/s390x_unknown_linux_gnu.rs
@@ -18,7 +18,7 @@ pub fn target() -> TargetResult {
     // cabi_s390x.rs are for now hard-coded to assume the no-vector ABI.
     // Pass the -vector feature string to LLVM to respect this assumption.
     base.features = "-vector".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
 
     Ok(Target {
         llvm_target: "s390x-unknown-linux-gnu".to_string(),
diff --git a/src/librustc_back/target/thumb_base.rs b/src/librustc_back/target/thumb_base.rs
new file mode 100644
index 0000000000000..b612261dfbf36
--- /dev/null
+++ b/src/librustc_back/target/thumb_base.rs
@@ -0,0 +1,57 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// These 4 `thumbv*` targets cover the ARM Cortex-M family of processors which are widely used in
+// microcontrollers. Namely, all these processors:
+//
+// - Cortex-M0
+// - Cortex-M0+
+// - Cortex-M1
+// - Cortex-M3
+// - Cortex-M4(F)
+// - Cortex-M7(F)
+//
+// We have opted for 4 targets instead of one target per processor (e.g. `cortex-m0`, `cortex-m3`,
+// etc) because the differences between some processors like the cortex-m0 and cortex-m1 are almost
+// non-existent from the POV of codegen so it doesn't make sense to have separate targets for them.
+// And if differences exist between two processors under the same target, rustc flags can be used to
+// optimize for one processor or the other.
+//
+// Also, we have not chosen a single target (`arm-none-eabi`) like GCC does because this makes
+// difficult to integrate Rust code and C code. Targeting the Cortex-M4 requires different gcc flags
+// than the ones you would use for the Cortex-M0 and with a single target it'd be impossible to
+// differentiate one processor from the other.
+//
+// About arm vs thumb in the name. The Cortex-M devices only support the Thumb instruction set,
+// which is more compact (higher code density), and not the ARM instruction set. That's why LLVM
+// triples use thumb instead of arm. We follow suit because having thumb in the name let us
+// differentiate these targets from our other `arm(v7)-*-*-gnueabi(hf)` targets in the context of
+// build scripts / gcc flags.
+
+use PanicStrategy;
+use std::default::Default;
+use target::TargetOptions;
+
+pub fn opts() -> TargetOptions {
+    // See rust-lang/rfcs#1645 for a discussion about these defaults
+    TargetOptions {
+        executables: true,
+        // In 99%+ of cases, we want to use the `arm-none-eabi-gcc` compiler (there aren't many
+        // options around)
+        linker: "arm-none-eabi-gcc".to_string(),
+        // Because these devices have very little resources having an unwinder is too onerous so we
+        // default to "abort" because the "unwind" strategy is very rare.
+        panic_strategy: PanicStrategy::Abort,
+        // Similarly, one almost always never wants to use relocatable code because of the extra
+        // costs it involves.
+        relocation_model: "static".to_string(),
+        .. Default::default()
+    }
+}
diff --git a/src/librustc_back/target/thumbv6m_none_eabi.rs b/src/librustc_back/target/thumbv6m_none_eabi.rs
new file mode 100644
index 0000000000000..6c22f98538459
--- /dev/null
+++ b/src/librustc_back/target/thumbv6m_none_eabi.rs
@@ -0,0 +1,36 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Targets the Cortex-M0, Cortex-M0+ and Cortex-M1 processors (ARMv6-M architecture)
+
+use target::{Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    Ok(Target {
+        llvm_target: "thumbv6m-none-eabi".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+        arch: "arm".to_string(),
+        target_os: "none".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "".to_string(),
+
+        options: TargetOptions {
+            // The ARMv6-M architecture doesn't support unaligned loads/stores so we disable them
+            // with +strict-align.
+            features: "+strict-align".to_string(),
+            // There are no atomic instructions available in the instruction set of the ARMv6-M
+            // architecture
+            max_atomic_width: Some(0),
+            .. super::thumb_base::opts()
+        }
+    })
+}
diff --git a/src/librustc_back/target/thumbv7em_none_eabi.rs b/src/librustc_back/target/thumbv7em_none_eabi.rs
new file mode 100644
index 0000000000000..ddad4e3624f3c
--- /dev/null
+++ b/src/librustc_back/target/thumbv7em_none_eabi.rs
@@ -0,0 +1,40 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Targets the Cortex-M4 and Cortex-M7 processors (ARMv7E-M)
+//
+// This target assumes that the device doesn't have a FPU (Floating Point Unit) and lowers all the
+// floating point operations to software routines (intrinsics).
+//
+// As such, this target uses the "soft" calling convention (ABI) where floating point values are
+// passed to/from subroutines via general purpose registers (R0, R1, etc.).
+//
+// To opt-in to hardware accelerated floating point operations, you can use, for example,
+// `-C target-feature=+vfp4` or `-C target-cpu=cortex-m4`.
+
+use target::{Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    Ok(Target {
+        llvm_target: "thumbv7em-none-eabi".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+        arch: "arm".to_string(),
+        target_os: "none".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "".to_string(),
+
+        options: TargetOptions {
+            max_atomic_width: Some(32),
+            .. super::thumb_base::opts()
+        },
+    })
+}
diff --git a/src/librustc_back/target/thumbv7em_none_eabihf.rs b/src/librustc_back/target/thumbv7em_none_eabihf.rs
new file mode 100644
index 0000000000000..a9fac48e8e5ac
--- /dev/null
+++ b/src/librustc_back/target/thumbv7em_none_eabihf.rs
@@ -0,0 +1,49 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Targets the Cortex-M4F and Cortex-M7F processors (ARMv7E-M)
+//
+// This target assumes that the device does have a FPU (Floating Point Unit) and lowers all (single
+// precision) floating point operations to hardware instructions.
+//
+// Additionally, this target uses the "hard" floating convention (ABI) where floating point values
+// are passed to/from subroutines via FPU registers (S0, S1, D0, D1, etc.).
+//
+// To opt into double precision hardware support, use the `-C target-feature=-fp-only-sp` flag.
+
+use target::{Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    Ok(Target {
+        llvm_target: "thumbv7em-none-eabihf".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+        arch: "arm".to_string(),
+        target_os: "none".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "".to_string(),
+
+        options: TargetOptions {
+            // `+vfp4` is the lowest common denominator between the Cortex-M4 (vfp4-16) and the
+            // Cortex-M7 (vfp5)
+            // `+d16` both the Cortex-M4 and the Cortex-M7 only have 16 double-precision registers
+            // available
+            // `+fp-only-sp` The Cortex-M4 only supports single precision floating point operations
+            // whereas in the Cortex-M7 double precision is optional
+            //
+            // Reference:
+            // ARMv7-M Architecture Reference Manual - A2.5 The optional floating-point extension
+            features: "+vfp4,+d16,+fp-only-sp".to_string(),
+            max_atomic_width: Some(32),
+            .. super::thumb_base::opts()
+        }
+    })
+}
diff --git a/src/librustc_back/target/thumbv7m_none_eabi.rs b/src/librustc_back/target/thumbv7m_none_eabi.rs
new file mode 100644
index 0000000000000..ed61dd0459b4d
--- /dev/null
+++ b/src/librustc_back/target/thumbv7m_none_eabi.rs
@@ -0,0 +1,31 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Targets the Cortex-M3 processor (ARMv7-M)
+
+use target::{Target, TargetOptions, TargetResult};
+
+pub fn target() -> TargetResult {
+    Ok(Target {
+        llvm_target: "thumbv7m-none-eabi".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "32".to_string(),
+        data_layout: "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
+        arch: "arm".to_string(),
+        target_os: "none".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "".to_string(),
+
+        options: TargetOptions {
+            max_atomic_width: Some(32),
+            .. super::thumb_base::opts()
+        },
+    })
+}
diff --git a/src/librustc_back/target/wasm32_unknown_emscripten.rs b/src/librustc_back/target/wasm32_unknown_emscripten.rs
index 2923f2eb92e45..77ab4fcae7008 100644
--- a/src/librustc_back/target/wasm32_unknown_emscripten.rs
+++ b/src/librustc_back/target/wasm32_unknown_emscripten.rs
@@ -23,7 +23,7 @@ pub fn target() -> Result<Target, String> {
         linker_is_gnu: true,
         allow_asm: false,
         obj_is_bitcode: true,
-        max_atomic_width: 32,
+        max_atomic_width: Some(32),
         post_link_args: vec!["-s".to_string(), "BINARYEN=1".to_string(),
                              "-s".to_string(), "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()],
         .. Default::default()
diff --git a/src/librustc_back/target/x86_64_apple_darwin.rs b/src/librustc_back/target/x86_64_apple_darwin.rs
index 65e4b1400fcf8..b3c1561dbcc0b 100644
--- a/src/librustc_back/target/x86_64_apple_darwin.rs
+++ b/src/librustc_back/target/x86_64_apple_darwin.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::apple_base::opts();
     base.cpu = "core2".to_string();
-    base.max_atomic_width = 128; // core2 support cmpxchg16b
+    base.max_atomic_width = Some(128); // core2 support cmpxchg16b
     base.eliminate_frame_pointer = false;
     base.pre_link_args.push("-m64".to_string());
 
diff --git a/src/librustc_back/target/x86_64_apple_ios.rs b/src/librustc_back/target/x86_64_apple_ios.rs
index 3b8b636b6dc66..7a58bb34ce7f6 100644
--- a/src/librustc_back/target/x86_64_apple_ios.rs
+++ b/src/librustc_back/target/x86_64_apple_ios.rs
@@ -23,7 +23,7 @@ pub fn target() -> TargetResult {
         target_env: "".to_string(),
         target_vendor: "apple".to_string(),
         options: TargetOptions {
-            max_atomic_width: 64,
+            max_atomic_width: Some(64),
             .. base
         }
     })
diff --git a/src/librustc_back/target/x86_64_pc_windows_gnu.rs b/src/librustc_back/target/x86_64_pc_windows_gnu.rs
index 086e0e6bf4fe7..321585cd65eb3 100644
--- a/src/librustc_back/target/x86_64_pc_windows_gnu.rs
+++ b/src/librustc_back/target/x86_64_pc_windows_gnu.rs
@@ -14,7 +14,7 @@ pub fn target() -> TargetResult {
     let mut base = super::windows_base::opts();
     base.cpu = "x86-64".to_string();
     base.pre_link_args.push("-m64".to_string());
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
 
     Ok(Target {
         llvm_target: "x86_64-pc-windows-gnu".to_string(),
diff --git a/src/librustc_back/target/x86_64_pc_windows_msvc.rs b/src/librustc_back/target/x86_64_pc_windows_msvc.rs
index 064f06e9b31d6..ea8909d213e80 100644
--- a/src/librustc_back/target/x86_64_pc_windows_msvc.rs
+++ b/src/librustc_back/target/x86_64_pc_windows_msvc.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::windows_msvc_base::opts();
     base.cpu = "x86-64".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
 
     Ok(Target {
         llvm_target: "x86_64-pc-windows-msvc".to_string(),
diff --git a/src/librustc_back/target/x86_64_rumprun_netbsd.rs b/src/librustc_back/target/x86_64_rumprun_netbsd.rs
index fd6578c2a2a0a..3313721439696 100644
--- a/src/librustc_back/target/x86_64_rumprun_netbsd.rs
+++ b/src/librustc_back/target/x86_64_rumprun_netbsd.rs
@@ -16,7 +16,7 @@ pub fn target() -> TargetResult {
     base.pre_link_args.push("-m64".to_string());
     base.linker = "x86_64-rumprun-netbsd-gcc".to_string();
     base.ar = "x86_64-rumprun-netbsd-ar".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
 
     base.dynamic_linking = false;
     base.has_rpath = false;
diff --git a/src/librustc_back/target/x86_64_sun_solaris.rs b/src/librustc_back/target/x86_64_sun_solaris.rs
index 2a1feb937f742..8e4fd94e7bce4 100644
--- a/src/librustc_back/target/x86_64_sun_solaris.rs
+++ b/src/librustc_back/target/x86_64_sun_solaris.rs
@@ -14,7 +14,7 @@ pub fn target() -> TargetResult {
     let mut base = super::solaris_base::opts();
     base.pre_link_args.push("-m64".to_string());
     base.cpu = "x86-64".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
 
     Ok(Target {
         llvm_target: "x86_64-pc-solaris".to_string(),
diff --git a/src/librustc_back/target/x86_64_unknown_bitrig.rs b/src/librustc_back/target/x86_64_unknown_bitrig.rs
index 3820965589815..eda16c29466b5 100644
--- a/src/librustc_back/target/x86_64_unknown_bitrig.rs
+++ b/src/librustc_back/target/x86_64_unknown_bitrig.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::bitrig_base::opts();
     base.cpu = "x86-64".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     base.pre_link_args.push("-m64".to_string());
 
     Ok(Target {
diff --git a/src/librustc_back/target/x86_64_unknown_dragonfly.rs b/src/librustc_back/target/x86_64_unknown_dragonfly.rs
index 7e40d49b870ad..194efb8fc2322 100644
--- a/src/librustc_back/target/x86_64_unknown_dragonfly.rs
+++ b/src/librustc_back/target/x86_64_unknown_dragonfly.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::dragonfly_base::opts();
     base.cpu = "x86-64".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     base.pre_link_args.push("-m64".to_string());
 
     Ok(Target {
diff --git a/src/librustc_back/target/x86_64_unknown_freebsd.rs b/src/librustc_back/target/x86_64_unknown_freebsd.rs
index f38cdd4bec55f..b127bee163b86 100644
--- a/src/librustc_back/target/x86_64_unknown_freebsd.rs
+++ b/src/librustc_back/target/x86_64_unknown_freebsd.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::freebsd_base::opts();
     base.cpu = "x86-64".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     base.pre_link_args.push("-m64".to_string());
 
     Ok(Target {
diff --git a/src/librustc_back/target/x86_64_unknown_haiku.rs b/src/librustc_back/target/x86_64_unknown_haiku.rs
index 171e88cee50c4..7cf0599037c1e 100644
--- a/src/librustc_back/target/x86_64_unknown_haiku.rs
+++ b/src/librustc_back/target/x86_64_unknown_haiku.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::haiku_base::opts();
     base.cpu = "x86-64".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     base.pre_link_args.push("-m64".to_string());
 
     Ok(Target {
diff --git a/src/librustc_back/target/x86_64_unknown_linux_gnu.rs b/src/librustc_back/target/x86_64_unknown_linux_gnu.rs
index ef81d397a8f1e..f95bcb556e57f 100644
--- a/src/librustc_back/target/x86_64_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/x86_64_unknown_linux_gnu.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::linux_base::opts();
     base.cpu = "x86-64".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     base.pre_link_args.push("-m64".to_string());
 
     Ok(Target {
diff --git a/src/librustc_back/target/x86_64_unknown_linux_musl.rs b/src/librustc_back/target/x86_64_unknown_linux_musl.rs
index 4bad7754b3907..c3bf9dcca6ee4 100644
--- a/src/librustc_back/target/x86_64_unknown_linux_musl.rs
+++ b/src/librustc_back/target/x86_64_unknown_linux_musl.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::linux_musl_base::opts();
     base.cpu = "x86-64".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     base.pre_link_args.push("-m64".to_string());
 
     Ok(Target {
diff --git a/src/librustc_back/target/x86_64_unknown_netbsd.rs b/src/librustc_back/target/x86_64_unknown_netbsd.rs
index 2d0b1e2a9330b..87a7c184644d5 100644
--- a/src/librustc_back/target/x86_64_unknown_netbsd.rs
+++ b/src/librustc_back/target/x86_64_unknown_netbsd.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::netbsd_base::opts();
     base.cpu = "x86-64".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     base.pre_link_args.push("-m64".to_string());
 
     Ok(Target {
diff --git a/src/librustc_back/target/x86_64_unknown_openbsd.rs b/src/librustc_back/target/x86_64_unknown_openbsd.rs
index 339dbd591a02e..e9d645b0d38f2 100644
--- a/src/librustc_back/target/x86_64_unknown_openbsd.rs
+++ b/src/librustc_back/target/x86_64_unknown_openbsd.rs
@@ -13,7 +13,7 @@ use target::{Target, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::openbsd_base::opts();
     base.cpu = "x86-64".to_string();
-    base.max_atomic_width = 64;
+    base.max_atomic_width = Some(64);
     base.pre_link_args.push("-m64".to_string());
 
     Ok(Target {
diff --git a/src/test/run-make/target-without-atomics/Makefile b/src/test/run-make/target-without-atomics/Makefile
new file mode 100644
index 0000000000000..48c53a5651114
--- /dev/null
+++ b/src/test/run-make/target-without-atomics/Makefile
@@ -0,0 +1,5 @@
+-include ../tools.mk
+
+# The target used below doesn't support atomic operations. Verify that's the case
+all:
+	$(RUSTC) --print cfg --target thumbv6m-none-eabi | grep -qv target_has_atomic