about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-07-13 12:25:10 +0000
committerbors <bors@rust-lang.org>2021-07-13 12:25:10 +0000
commitca99e3eb3adf61573b11d859ce2b9ff7db48ccd4 (patch)
tree4358d504c5ce2e1fe670ae4d3bbebc74a03d5f48
parent5aff6dd07a562a2cba3c57fc3460a72acb6bef46 (diff)
parentc3fbafddc06fda5f282790c9c16378d7786cbe03 (diff)
downloadrust-ca99e3eb3adf61573b11d859ce2b9ff7db48ccd4.tar.gz
rust-ca99e3eb3adf61573b11d859ce2b9ff7db48ccd4.zip
Auto merge of #86922 - joshtriplett:target-abi, r=oli-obk
target abi

Implement cfg(target_abi) (RFC 2992)

Add an `abi` field to `TargetOptions`, defaulting to "". Support using
`cfg(target_abi = "...")` for conditional compilation on that field.

Gated by `feature(cfg_target_abi)`.

Add a test for `target_abi`, and a test for the feature gate.

Add `target_abi` to tidy as a platform-specific cfg.

Update targets to use `target_abi`

All eabi targets have `target_abi = "eabi".`
All eabihf targets have `target_abi = "eabihf"`.
`armv6_unknown_freebsd` and `armv7_unknown_freebsd` have `target_abi = "eabihf"`.
All abi64 targets have `target_abi = "abi64"`.
All ilp32 targets have `target_abi = "ilp32"`.
All softfloat targets have `target_abi = "softfloat"`.
All *-uwp-windows-* targets have `target_abi = "uwp"`.
All spe targets have `target_abi = "spe"`.
All macabi targets have `target_abi = "macabi"`.
aarch64-apple-ios-sim has `target_abi = "sim"`.
`x86_64-fortanix-unknown-sgx` has `target_abi = "fortanix"`.
`x86_64-unknown-linux-gnux32` has `target_abi = "x32"`.

Add FIXME entries for targets for which existing values need to change
once `cfg_target_abi` becomes stable. (All of them are tier 3 targets.)

Add a test for `target_abi` in `--print cfg`.
-rw-r--r--compiler/rustc_feature/src/active.rs3
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs1
-rw-r--r--compiler/rustc_session/src/config.rs4
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs7
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs1
-rw-r--r--compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs1
-rw-r--r--compiler/rustc_target/src/spec/apple_sdk_base.rs10
-rw-r--r--compiler/rustc_target/src/spec/arm_linux_androideabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs1
-rw-r--r--compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs1
-rw-r--r--compiler/rustc_target/src/spec/armebv7r_none_eabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv5te_unknown_linux_uclibceabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/armv7_linux_androideabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv7a_none_eabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv7a_none_eabihf.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv7r_none_eabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/armv7r_none_eabihf.rs1
-rw-r--r--compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs1
-rw-r--r--compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs7
-rw-r--r--compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs1
-rw-r--r--compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs2
-rw-r--r--compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs1
-rw-r--r--compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs1
-rw-r--r--compiler/rustc_target/src/spec/mod.rs6
-rw-r--r--compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs7
-rw-r--r--compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs1
-rw-r--r--compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs6
-rw-r--r--compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs1
-rw-r--r--compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs6
-rw-r--r--compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs1
-rw-r--r--compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs1
-rw-r--r--compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs1
-rw-r--r--compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs6
-rw-r--r--compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs1
-rw-r--r--compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs1
-rw-r--r--compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs1
-rw-r--r--compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs1
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs1
-rw-r--r--src/test/run-make-fulldeps/print-cfg/Makefile2
-rw-r--r--src/test/ui/cfg/cfg-target-abi.rs10
-rw-r--r--src/test/ui/feature-gates/feature-gate-cfg-target-abi.rs11
-rw-r--r--src/test/ui/feature-gates/feature-gate-cfg-target-abi.stderr39
-rw-r--r--src/tools/tidy/src/pal.rs1
62 files changed, 170 insertions, 8 deletions
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 9eaf4693811..ede510b6936 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -684,6 +684,9 @@ declare_features! (
     /// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns.
     (active, more_qualified_paths, "1.54.0", Some(86935), None),
 
+    /// Allows `cfg(target_abi = "...")`.
+    (active, cfg_target_abi, "1.55.0", Some(80970), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 24a5a007ded..77d8f0f920c 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -23,6 +23,7 @@ pub type GatedCfg = (Symbol, Symbol, GateFn);
 /// `cfg(...)`'s that are feature gated.
 const GATED_CFGS: &[GatedCfg] = &[
     // (name in cfg, feature, function to check if the feature is enabled)
+    (sym::target_abi, sym::cfg_target_abi, cfg_fn!(cfg_target_abi)),
     (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
     (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
     (sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 88eaa7fe329..b444f66258a 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -805,6 +805,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
     let wordsz = sess.target.pointer_width.to_string();
     let os = &sess.target.os;
     let env = &sess.target.env;
+    let abi = &sess.target.abi;
     let vendor = &sess.target.vendor;
     let min_atomic_width = sess.target.min_atomic_width();
     let max_atomic_width = sess.target.max_atomic_width();
@@ -814,7 +815,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
     });
 
     let mut ret = FxHashSet::default();
-    ret.reserve(6); // the minimum number of insertions
+    ret.reserve(7); // the minimum number of insertions
     // Target bindings.
     ret.insert((sym::target_os, Some(Symbol::intern(os))));
     for fam in &sess.target.families {
@@ -829,6 +830,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
     ret.insert((sym::target_endian, Some(Symbol::intern(end.as_str()))));
     ret.insert((sym::target_pointer_width, Some(Symbol::intern(&wordsz))));
     ret.insert((sym::target_env, Some(Symbol::intern(env))));
+    ret.insert((sym::target_abi, Some(Symbol::intern(abi))));
     ret.insert((sym::target_vendor, Some(Symbol::intern(vendor))));
     if sess.target.has_elf_tls {
         ret.insert((sym::target_thread_local, None));
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 9a78d1ac0be..07f22159f96 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -354,6 +354,7 @@ symbols! {
         cfg_eval,
         cfg_panic,
         cfg_sanitize,
+        cfg_target_abi,
         cfg_target_feature,
         cfg_target_has_atomic,
         cfg_target_thread_local,
@@ -1203,6 +1204,7 @@ symbols! {
         sync,
         sync_trait,
         t32,
+        target_abi,
         target_arch,
         target_endian,
         target_env,
diff --git a/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs
index c1adc963425..e05360ea45c 100644
--- a/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs
+++ b/compiler/rustc_target/src/spec/aarch64_be_unknown_linux_gnu_ilp32.rs
@@ -10,6 +10,11 @@ pub fn target() -> Target {
         pointer_width: 32,
         data_layout: "E-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
-        options: TargetOptions { mcount: "\u{1}_mcount".to_string(), endian: Endian::Big, ..base },
+        options: TargetOptions {
+            abi: "ilp32".to_string(),
+            mcount: "\u{1}_mcount".to_string(),
+            endian: Endian::Big,
+            ..base
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs
index e2618447f28..8522405f61f 100644
--- a/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_gnu_ilp32.rs
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
         arch: "aarch64".to_string(),
         options: TargetOptions {
+            abi: "ilp32".to_string(),
             max_atomic_width: Some(128),
             mcount: "\u{1}_mcount".to_string(),
             ..super::linux_gnu_base::opts()
diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs
index 482db0c5342..fa93ca80549 100644
--- a/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs
+++ b/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs
@@ -10,6 +10,7 @@ use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, Target, TargetOp
 
 pub fn target() -> Target {
     let opts = TargetOptions {
+        abi: "softfloat".to_string(),
         linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
         linker: Some("rust-lld".to_owned()),
         features: "+strict-align,-neon,-fp-armv8".to_string(),
diff --git a/compiler/rustc_target/src/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs
index e7f7bb343d0..39bc699eef0 100644
--- a/compiler/rustc_target/src/spec/apple_sdk_base.rs
+++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs
@@ -14,6 +14,15 @@ pub enum Arch {
     Arm64_sim,
 }
 
+fn target_abi(arch: Arch) -> String {
+    match arch {
+        Armv7 | Armv7s | Arm64 | I386 | X86_64 => "",
+        X86_64_macabi | Arm64_macabi => "macabi",
+        Arm64_sim => "sim",
+    }
+    .to_string()
+}
+
 fn target_cpu(arch: Arch) -> String {
     match arch {
         Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher
@@ -39,6 +48,7 @@ fn link_env_remove(arch: Arch) -> Vec<String> {
 
 pub fn opts(os: &str, arch: Arch) -> TargetOptions {
     TargetOptions {
+        abi: target_abi(arch),
         cpu: target_cpu(arch),
         dynamic_linking: false,
         executables: true,
diff --git a/compiler/rustc_target/src/spec/arm_linux_androideabi.rs b/compiler/rustc_target/src/spec/arm_linux_androideabi.rs
index f2430830afc..9b5366c576e 100644
--- a/compiler/rustc_target/src/spec/arm_linux_androideabi.rs
+++ b/compiler/rustc_target/src/spec/arm_linux_androideabi.rs
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             // https://developer.android.com/ndk/guides/abis.html#armeabi
             features: "+strict-align,+v5te".to_string(),
             max_atomic_width: Some(32),
diff --git a/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs
index 225db0032a8..442f56d4fb5 100644
--- a/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabi.rs
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+strict-align,+v6".to_string(),
             max_atomic_width: Some(64),
             mcount: "\u{1}__gnu_mcount_nc".to_string(),
diff --git a/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs
index 33703195ee7..2c12a71e29f 100644
--- a/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs
+++ b/compiler/rustc_target/src/spec/arm_unknown_linux_gnueabihf.rs
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             features: "+strict-align,+v6,+vfp2,-d32".to_string(),
             max_atomic_width: Some(64),
             mcount: "\u{1}__gnu_mcount_nc".to_string(),
diff --git a/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs
index 850844993f9..d187dfd9189 100644
--- a/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs
+++ b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabi.rs
@@ -10,6 +10,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             // Most of these settings are copied from the arm_unknown_linux_gnueabi
             // target.
             features: "+strict-align,+v6".to_string(),
diff --git a/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs
index ff69c462e8e..3d72734f5fa 100644
--- a/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/arm_unknown_linux_musleabihf.rs
@@ -10,6 +10,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             // Most of these settings are copied from the arm_unknown_linux_gnueabihf
             // target.
             features: "+strict-align,+v6,+vfp2,-d32".to_string(),
diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs
index 547f48c5d3b..c98a12cfc49 100644
--- a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs
@@ -11,6 +11,7 @@ pub fn target() -> Target {
         data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             endian: Endian::Big,
             linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
             executables: true,
diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs
index f4f61e87ab9..292635403fb 100644
--- a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs
@@ -11,6 +11,7 @@ pub fn target() -> Target {
         data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             endian: Endian::Big,
             linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
             executables: true,
diff --git a/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs
index 8a289fee781..f1b193a384f 100644
--- a/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/armv4t_unknown_linux_gnueabi.rs
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+soft-float,+strict-align".to_string(),
             // Atomic operations provided by compiler-builtins
             max_atomic_width: Some(32),
diff --git a/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs
index 177ab453b04..a6c4f2304c2 100644
--- a/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/armv5te_unknown_linux_gnueabi.rs
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+soft-float,+strict-align".to_string(),
             // Atomic operations provided by compiler-builtins
             max_atomic_width: Some(32),
diff --git a/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs
index 1f084443bd9..de2a350e231 100644
--- a/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs
+++ b/compiler/rustc_target/src/spec/armv5te_unknown_linux_musleabi.rs
@@ -11,6 +11,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+soft-float,+strict-align".to_string(),
             // Atomic operations provided by compiler-builtins
             max_atomic_width: Some(32),
diff --git a/compiler/rustc_target/src/spec/armv5te_unknown_linux_uclibceabi.rs b/compiler/rustc_target/src/spec/armv5te_unknown_linux_uclibceabi.rs
index 4e5b714bded..91b4bd27caa 100644
--- a/compiler/rustc_target/src/spec/armv5te_unknown_linux_uclibceabi.rs
+++ b/compiler/rustc_target/src/spec/armv5te_unknown_linux_uclibceabi.rs
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+soft-float,+strict-align".to_string(),
             // Atomic operations provided by compiler-builtins
             max_atomic_width: Some(32),
diff --git a/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs b/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs
index 08fc51e8a8b..ee2f8f6238b 100644
--- a/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/armv6_unknown_freebsd.rs
@@ -7,6 +7,8 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
+            // FIXME: change env to "gnu" when cfg_target_abi becomes stable
             env: "gnueabihf".to_string(),
             features: "+v6,+vfp2,-d32".to_string(),
             max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs
index b109aa1e1ab..b046819d4d7 100644
--- a/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv6_unknown_netbsd_eabihf.rs
@@ -7,6 +7,8 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
+            // FIXME: remove env when cfg_target_abi becomes stable
             env: "eabihf".to_string(),
             features: "+v6,+vfp2,-d32".to_string(),
             max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs
index 821080ec07d..55956f3bad4 100644
--- a/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs
+++ b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs
@@ -17,6 +17,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+v7,+thumb-mode,+thumb2,+vfp3,-d32,-neon".to_string(),
             max_atomic_width: Some(64),
             ..base
diff --git a/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs b/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs
index 190d3bb691a..fbfb1c27681 100644
--- a/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_freebsd.rs
@@ -7,6 +7,8 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
+            // FIXME: change env to "gnu" when cfg_target_abi becomes stable
             env: "gnueabihf".to_string(),
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs
index 088a8cf7534..0a3b8033dd1 100644
--- a/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabi.rs
@@ -10,6 +10,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+v7,+thumb2,+soft-float,-neon".to_string(),
             max_atomic_width: Some(64),
             mcount: "\u{1}__gnu_mcount_nc".to_string(),
diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs
index 521053ec2d3..662b81cae3e 100644
--- a/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_gnueabihf.rs
@@ -10,6 +10,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             // Info about features at https://wiki.debian.org/ArmHardFloatPort
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs
index 0ee2c3e45e0..c0fd1de17cf 100644
--- a/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabi.rs
@@ -16,6 +16,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
 
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+v7,+thumb2,+soft-float,-neon".to_string(),
             max_atomic_width: Some(64),
             mcount: "\u{1}mcount".to_string(),
diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs
index a6ce382c7a6..67ff7999dea 100644
--- a/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_musleabihf.rs
@@ -15,6 +15,7 @@ pub fn target() -> Target {
         // Most of these settings are copied from the armv7_unknown_linux_gnueabihf
         // target.
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
             mcount: "\u{1}mcount".to_string(),
diff --git a/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs b/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs
index e509dcaddaa..60a552b018d 100644
--- a/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7_unknown_netbsd_eabihf.rs
@@ -7,6 +7,8 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
+            // FIXME: remove env when cfg_target_abi becomes stable
             env: "eabihf".to_string(),
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs b/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs
index 0aabf2fe486..27d404b101f 100644
--- a/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7_wrs_vxworks_eabihf.rs
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             // Info about features at https://wiki.debian.org/ArmHardFloatPort
             features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
             max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs
index bd703ee3e45..8bff60e9ed9 100644
--- a/compiler/rustc_target/src/spec/armv7a_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs
@@ -18,6 +18,7 @@ use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, Target, TargetOp
 
 pub fn target() -> Target {
     let opts = TargetOptions {
+        abi: "eabi".to_string(),
         linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
         linker: Some("rust-lld".to_owned()),
         features: "+v7,+thumb2,+soft-float,-neon,+strict-align".to_string(),
diff --git a/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs
index ad86ae1cedc..ea2751e375e 100644
--- a/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs
@@ -9,6 +9,7 @@ use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, Target, TargetOp
 
 pub fn target() -> Target {
     let opts = TargetOptions {
+        abi: "eabihf".to_string(),
         linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
         linker: Some("rust-lld".to_owned()),
         features: "+v7,+vfp3,-d32,+thumb2,-neon,+strict-align".to_string(),
diff --git a/compiler/rustc_target/src/spec/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs
index c07d6adc37e..c6955428055 100644
--- a/compiler/rustc_target/src/spec/armv7r_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs
@@ -11,6 +11,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
 
         options: TargetOptions {
+            abi: "eabi".to_string(),
             linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
             executables: true,
             linker: Some("rust-lld".to_owned()),
diff --git a/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs
index fbf2f8e9b72..50c37021b74 100644
--- a/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs
@@ -11,6 +11,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
 
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
             executables: true,
             linker: Some("rust-lld".to_owned()),
diff --git a/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs
index 53398539ac2..161a27ab689 100644
--- a/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/mips64_unknown_linux_gnuabi64.rs
@@ -8,6 +8,7 @@ pub fn target() -> Target {
         data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
         arch: "mips64".to_string(),
         options: TargetOptions {
+            abi: "abi64".to_string(),
             endian: Endian::Big,
             // NOTE(mips64r2) matches C toolchain
             cpu: "mips64r2".to_string(),
diff --git a/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs
index 329fbd22721..a8984645698 100644
--- a/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs
+++ b/compiler/rustc_target/src/spec/mips64_unknown_linux_muslabi64.rs
@@ -12,6 +12,11 @@ pub fn target() -> Target {
         pointer_width: 64,
         data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
         arch: "mips64".to_string(),
-        options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base },
+        options: TargetOptions {
+            abi: "abi64".to_string(),
+            endian: Endian::Big,
+            mcount: "_mcount".to_string(),
+            ..base
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs
index d767705b045..2f58560d450 100644
--- a/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
         arch: "mips64".to_string(),
         options: TargetOptions {
+            abi: "abi64".to_string(),
             // NOTE(mips64r2) matches C toolchain
             cpu: "mips64r2".to_string(),
             features: "+mips64r2".to_string(),
diff --git a/compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs
index 766ed69df4b..01c34bc3992 100644
--- a/compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs
+++ b/compiler/rustc_target/src/spec/mips64el_unknown_linux_muslabi64.rs
@@ -11,6 +11,6 @@ pub fn target() -> Target {
         pointer_width: 64,
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
         arch: "mips64".to_string(),
-        options: TargetOptions { mcount: "_mcount".to_string(), ..base },
+        options: TargetOptions { abi: "abi64".to_string(), mcount: "_mcount".to_string(), ..base },
     }
 }
diff --git a/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs
index 3bf837fbb41..80a155a4865 100644
--- a/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/mipsisa64r6_unknown_linux_gnuabi64.rs
@@ -8,6 +8,7 @@ pub fn target() -> Target {
         data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
         arch: "mips64".to_string(),
         options: TargetOptions {
+            abi: "abi64".to_string(),
             endian: Endian::Big,
             // NOTE(mips64r6) matches C toolchain
             cpu: "mips64r6".to_string(),
diff --git a/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs b/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs
index 589d7acba68..58f9862715f 100644
--- a/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs
+++ b/compiler/rustc_target/src/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs
@@ -7,6 +7,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
         arch: "mips64".to_string(),
         options: TargetOptions {
+            abi: "abi64".to_string(),
             // NOTE(mips64r6) matches C toolchain
             cpu: "mips64r6".to_string(),
             features: "+mips64r6".to_string(),
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 0a5f8c17c63..aa7dbeb16f2 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1025,6 +1025,9 @@ pub struct TargetOptions {
     pub os: String,
     /// Environment name to use for conditional compilation (`target_env`). Defaults to "".
     pub env: String,
+    /// ABI name to distinguish multiple ABIs on the same OS and architecture. For instance, `"eabi"`
+    /// or `"eabihf"`. Defaults to "".
+    pub abi: String,
     /// Vendor name to use for conditional compilation (`target_vendor`). Defaults to "unknown".
     pub vendor: String,
     /// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed
@@ -1342,6 +1345,7 @@ impl Default for TargetOptions {
             c_int_width: "32".to_string(),
             os: "none".to_string(),
             env: String::new(),
+            abi: String::new(),
             vendor: "unknown".to_string(),
             linker_flavor: LinkerFlavor::Gcc,
             linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.to_string()),
@@ -1919,6 +1923,7 @@ impl Target {
         key!(c_int_width = "target-c-int-width");
         key!(os);
         key!(env);
+        key!(abi);
         key!(vendor);
         key!(linker_flavor, LinkerFlavor)?;
         key!(linker, optional);
@@ -2152,6 +2157,7 @@ impl ToJson for Target {
         target_option_val!(c_int_width, "target-c-int-width");
         target_option_val!(os);
         target_option_val!(env);
+        target_option_val!(abi);
         target_option_val!(vendor);
         target_option_val!(linker_flavor);
         target_option_val!(linker);
diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs
index 8d8f746f97f..362d8a104e4 100644
--- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs
+++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs
@@ -11,6 +11,11 @@ pub fn target() -> Target {
         pointer_width: 32,
         data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(),
         arch: "powerpc".to_string(),
-        options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base },
+        options: TargetOptions {
+            abi: "spe".to_string(),
+            endian: Endian::Big,
+            mcount: "_mcount".to_string(),
+            ..base
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs
index 215f1a36227..a2b85f7dd86 100644
--- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs
+++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs
@@ -13,6 +13,7 @@ pub fn target() -> Target {
         data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(),
         arch: "powerpc".to_string(),
         options: TargetOptions {
+            abi: "spe".to_string(),
             endian: Endian::Big,
             // feature msync would disable instruction 'fsync' which is not supported by fsl_p1p2
             features: "+secure-plt,+msync".to_string(),
diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs
index f996009f830..f86efd5d0f4 100644
--- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs
@@ -26,6 +26,7 @@ pub fn target() -> Target {
          */
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             linker_flavor: LinkerFlavor::Ld,
             linker: Some("arm-none-eabi-ld".to_string()),
 
diff --git a/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs
index 11c8bf46348..40e3281060f 100644
--- a/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv6m_none_eabi.rs
@@ -10,6 +10,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
 
         options: TargetOptions {
+            abi: "eabi".to_string(),
             // The ARMv6-M architecture doesn't support unaligned loads/stores so we disable them
             // with +strict-align.
             features: "+strict-align".to_string(),
diff --git a/compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs
index 141eb7e78b9..107474a86bb 100644
--- a/compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv7em_none_eabi.rs
@@ -18,6 +18,10 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
 
-        options: TargetOptions { max_atomic_width: Some(32), ..super::thumb_base::opts() },
+        options: TargetOptions {
+            abi: "eabi".to_string(),
+            max_atomic_width: Some(32),
+            ..super::thumb_base::opts()
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs b/compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs
index f5bd054f859..65fc0db6528 100644
--- a/compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/thumbv7em_none_eabihf.rs
@@ -18,6 +18,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
 
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             // `+vfp4` is the lowest common denominator between the Cortex-M4 (vfp4-16) and the
             // Cortex-M7 (vfp5)
             // `-d32` both the Cortex-M4 and the Cortex-M7 only have 16 double-precision registers
diff --git a/compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs
index 7af28cd9c9f..ff939348c35 100644
--- a/compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv7m_none_eabi.rs
@@ -9,6 +9,10 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
 
-        options: TargetOptions { max_atomic_width: Some(32), ..super::thumb_base::opts() },
+        options: TargetOptions {
+            abi: "eabi".to_string(),
+            max_atomic_width: Some(32),
+            ..super::thumb_base::opts()
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs
index 14020b88695..fcb7b5d718c 100644
--- a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs
@@ -17,6 +17,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabi".to_string(),
             features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
             max_atomic_width: Some(64),
             ..base
diff --git a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs
index 4042d539416..9d34d9ac874 100644
--- a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs
+++ b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_gnueabihf.rs
@@ -13,6 +13,7 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             // Info about features at https://wiki.debian.org/ArmHardFloatPort
             features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
             max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs
index 318b864a9cf..4e339cbd6be 100644
--- a/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/thumbv7neon_unknown_linux_musleabihf.rs
@@ -19,6 +19,7 @@ pub fn target() -> Target {
         // Most of these settings are copied from the thumbv7neon_unknown_linux_gnueabihf
         // target.
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
             max_atomic_width: Some(64),
             mcount: "\u{1}mcount".to_string(),
diff --git a/compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs
index a2200bc64e7..ef0f52d2199 100644
--- a/compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv8m_base_none_eabi.rs
@@ -10,6 +10,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
 
         options: TargetOptions {
+            abi: "eabi".to_string(),
             // ARMv8-M baseline doesn't support unaligned loads/stores so we disable them
             // with +strict-align.
             features: "+strict-align".to_string(),
diff --git a/compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs
index 67cdbab4860..dbd184debcb 100644
--- a/compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs
+++ b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabi.rs
@@ -10,6 +10,10 @@ pub fn target() -> Target {
         data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
         arch: "arm".to_string(),
 
-        options: TargetOptions { max_atomic_width: Some(32), ..super::thumb_base::opts() },
+        options: TargetOptions {
+            abi: "eabi".to_string(),
+            max_atomic_width: Some(32),
+            ..super::thumb_base::opts()
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs
index 49748f5ec6d..3caf705421c 100644
--- a/compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/thumbv8m_main_none_eabihf.rs
@@ -11,6 +11,7 @@ pub fn target() -> Target {
         arch: "arm".to_string(),
 
         options: TargetOptions {
+            abi: "eabihf".to_string(),
             // If the Floating Point extension is implemented in the Cortex-M33
             // processor, the Cortex-M33 Technical Reference Manual states that
             // the FPU uses the FPv5 architecture, single-precision instructions
diff --git a/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs b/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs
index 67d1be399b3..86df816f10d 100644
--- a/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs
+++ b/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs
@@ -25,6 +25,7 @@ pub fn opts() -> TargetOptions {
     late_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), mingw_libs);
 
     TargetOptions {
+        abi: "uwp".to_string(),
         vendor: "uwp".to_string(),
         executables: false,
         limit_rdylib_exports: false,
diff --git a/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs b/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs
index b3fa5c22f98..7b56b468c28 100644
--- a/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs
+++ b/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs
@@ -3,6 +3,7 @@ use crate::spec::{LinkerFlavor, LldFlavor, TargetOptions};
 pub fn opts() -> TargetOptions {
     let mut opts = super::windows_msvc_base::opts();
 
+    opts.abi = "uwp".to_string();
     opts.vendor = "uwp".to_string();
     let pre_link_args_msvc = vec!["/APPCONTAINER".to_string(), "mincore.lib".to_string()];
     opts.pre_link_args.entry(LinkerFlavor::Msvc).or_default().extend(pre_link_args_msvc.clone());
diff --git a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs
index 06eb33d8d82..59cd56ebcd5 100644
--- a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs
+++ b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs
@@ -55,6 +55,7 @@ pub fn target() -> Target {
         os: "unknown".into(),
         env: "sgx".into(),
         vendor: "fortanix".into(),
+        abi: "fortanix".into(),
         linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
         executables: true,
         linker: Some("rust-lld".to_owned()),
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs
index 7b77ad668cd..1ffaa9b78c8 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs
@@ -3,6 +3,7 @@ use crate::spec::{LinkerFlavor, StackProbeType, Target};
 pub fn target() -> Target {
     let mut base = super::linux_gnu_base::opts();
     base.cpu = "x86-64".to_string();
+    base.abi = "x32".to_string();
     base.max_atomic_width = Some(64);
     base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mx32".to_string());
     // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
diff --git a/src/test/run-make-fulldeps/print-cfg/Makefile b/src/test/run-make-fulldeps/print-cfg/Makefile
index 08303a46d19..013bf3baca4 100644
--- a/src/test/run-make-fulldeps/print-cfg/Makefile
+++ b/src/test/run-make-fulldeps/print-cfg/Makefile
@@ -6,6 +6,8 @@ all: default
 	$(RUSTC) --target i686-pc-windows-msvc --print cfg | $(CGREP) msvc
 	$(RUSTC) --target i686-apple-darwin --print cfg | $(CGREP) macos
 	$(RUSTC) --target i686-unknown-linux-gnu --print cfg | $(CGREP) gnu
+	$(RUSTC) --target arm-unknown-linux-gnueabihf --print cfg | $(CGREP) target_abi=
+	$(RUSTC) --target arm-unknown-linux-gnueabihf --print cfg | $(CGREP) eabihf
 
 ifdef IS_WINDOWS
 default:
diff --git a/src/test/ui/cfg/cfg-target-abi.rs b/src/test/ui/cfg/cfg-target-abi.rs
new file mode 100644
index 00000000000..acc570fc843
--- /dev/null
+++ b/src/test/ui/cfg/cfg-target-abi.rs
@@ -0,0 +1,10 @@
+// run-pass
+#![feature(cfg_target_abi)]
+
+#[cfg(target_abi = "eabihf")]
+pub fn main() {
+}
+
+#[cfg(not(target_abi = "eabihf"))]
+pub fn main() {
+}
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-target-abi.rs b/src/test/ui/feature-gates/feature-gate-cfg-target-abi.rs
new file mode 100644
index 00000000000..f2651493980
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-cfg-target-abi.rs
@@ -0,0 +1,11 @@
+#[cfg(target_abi = "x")] //~ ERROR `cfg(target_abi)` is experimental
+#[cfg_attr(target_abi = "x", x)] //~ ERROR `cfg(target_abi)` is experimental
+struct Foo(u64, u64);
+
+#[cfg(not(any(all(target_abi = "x"))))] //~ ERROR `cfg(target_abi)` is experimental
+fn foo() {}
+
+fn main() {
+    cfg!(target_abi = "x");
+    //~^ ERROR `cfg(target_abi)` is experimental and subject to change
+}
diff --git a/src/test/ui/feature-gates/feature-gate-cfg-target-abi.stderr b/src/test/ui/feature-gates/feature-gate-cfg-target-abi.stderr
new file mode 100644
index 00000000000..ed8cbcbe4f0
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-cfg-target-abi.stderr
@@ -0,0 +1,39 @@
+error[E0658]: `cfg(target_abi)` is experimental and subject to change
+  --> $DIR/feature-gate-cfg-target-abi.rs:2:12
+   |
+LL | #[cfg_attr(target_abi = "x", x)]
+   |            ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
+   = help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
+
+error[E0658]: `cfg(target_abi)` is experimental and subject to change
+  --> $DIR/feature-gate-cfg-target-abi.rs:1:7
+   |
+LL | #[cfg(target_abi = "x")]
+   |       ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
+   = help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
+
+error[E0658]: `cfg(target_abi)` is experimental and subject to change
+  --> $DIR/feature-gate-cfg-target-abi.rs:5:19
+   |
+LL | #[cfg(not(any(all(target_abi = "x"))))]
+   |                   ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
+   = help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
+
+error[E0658]: `cfg(target_abi)` is experimental and subject to change
+  --> $DIR/feature-gate-cfg-target-abi.rs:9:10
+   |
+LL |     cfg!(target_abi = "x");
+   |          ^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
+   = help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index 31cdc6865a4..24a10018779 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -122,6 +122,7 @@ fn check_cfgs(
 
         let contains_platform_specific_cfg = cfg.contains("target_os")
             || cfg.contains("target_env")
+            || cfg.contains("target_abi")
             || cfg.contains("target_vendor")
             || cfg.contains("unix")
             || cfg.contains("windows");