diff --git a/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs b/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs
new file mode 100644
index 00000000000..1b7161fbb85
--- /dev/null
+++ b/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs
@@ -0,0 +1,26 @@
+use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelroLevel, Target, TargetOptions};
+
+const LINKER_SCRIPT: &str = include_str!("./aarch64_nintendo_switch_freestanding_linker_script.ld");
+
+/// A base target for Nintendo Switch devices using a pure LLVM toolchain.
+pub fn target() -> Target {
+    Target {
+        llvm_target: "aarch64-unknown-none".into(),
+        pointer_width: 64,
+        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(),
+        arch: "aarch64".into(),
+        options: TargetOptions {
+            linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
+            linker: Some("rust-lld".into()),
+            link_script: Some(LINKER_SCRIPT.into()),
+            os: "horizon".into(),
+            max_atomic_width: Some(128),
+            panic_strategy: PanicStrategy::Abort,
+            position_independent_executables: true,
+            dynamic_linking: true,
+            executables: true,
+            relro_level: RelroLevel::Off,
+            ..Default::default()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding_linker_script.ld b/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding_linker_script.ld
new file mode 100644
index 00000000000..f3441e65937
--- /dev/null
+++ b/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding_linker_script.ld
@@ -0,0 +1,78 @@
+OUTPUT_FORMAT(elf64-littleaarch64)
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+
+PHDRS
+{
+  text PT_LOAD FLAGS(5);
+  rodata PT_LOAD FLAGS(4);
+  data PT_LOAD FLAGS(6);
+  bss PT_LOAD FLAGS(6);
+  dynamic PT_DYNAMIC;
+}
+
+SECTIONS
+{
+  . = 0;
+
+  .text : ALIGN(0x1000) {
+    HIDDEN(__text_start = .);
+    KEEP(*(.text.jmp))
+
+    . = 0x80;
+
+    *(.text .text.*)
+    *(.plt .plt.*)
+  }
+
+  /* Read-only sections */
+
+  . = ALIGN(0x1000);
+
+  .module_name : { *(.module_name) } :rodata
+
+  .rodata : { *(.rodata .rodata.*) } :rodata
+  .hash : { *(.hash) }
+  .dynsym : { *(.dynsym .dynsym.*) }
+  .dynstr : { *(.dynstr .dynstr.*) }
+  .rela.dyn : { *(.rela.dyn) }
+
+  .eh_frame : {
+    HIDDEN(__eh_frame_start = .);
+    *(.eh_frame .eh_frame.*)
+    HIDDEN(__eh_frame_end = .);
+  }
+
+  .eh_frame_hdr : {
+    HIDDEN(__eh_frame_hdr_start = .);
+    *(.eh_frame_hdr .eh_frame_hdr.*)
+    HIDDEN(__eh_frame_hdr_end = .);
+  }
+
+  /* Read-write sections */
+
+   . = ALIGN(0x1000);
+
+  .data : {
+    *(.data .data.*)
+    *(.got .got.*)
+    *(.got.plt .got.plt.*)
+  } :data
+
+  .dynamic : {
+    HIDDEN(__dynamic_start = .);
+    *(.dynamic)
+  }
+
+  /* BSS section */
+
+  . = ALIGN(0x1000);
+
+  .bss : {
+    HIDDEN(__bss_start = .);
+    *(.bss .bss.*)
+    *(COMMON)
+    . = ALIGN(8);
+    HIDDEN(__bss_end = .);
+  } :bss
+}
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index ef49fc8e968..1a6bb4a2eaf 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1035,6 +1035,8 @@ supported_targets! {
 
     ("armv6k-nintendo-3ds", armv6k_nintendo_3ds),
 
+    ("aarch64-nintendo-switch-freestanding", aarch64_nintendo_switch_freestanding),
+
     ("armv7-unknown-linux-uclibceabi", armv7_unknown_linux_uclibceabi),
     ("armv7-unknown-linux-uclibceabihf", armv7_unknown_linux_uclibceabihf),
 
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 62dd9a6b365..ea0f78e2a6b 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -411,7 +411,7 @@ pub struct Target {
 impl Target {
     pub fn from_triple(triple: &str) -> Self {
         let mut target: Self = Default::default();
-        if triple.contains("-none") || triple.contains("nvptx") {
+        if triple.contains("-none") || triple.contains("nvptx") || triple.contains("switch") {
             target.no_std = true;
         }
         target
diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs
index c5d62a8810a..1895e290148 100644
--- a/src/bootstrap/util.rs
+++ b/src/bootstrap/util.rs
@@ -298,7 +298,8 @@ pub fn use_host_linker(target: TargetSelection) -> bool {
         || target.contains("nvptx")
         || target.contains("fortanix")
         || target.contains("fuchsia")
-        || target.contains("bpf"))
+        || target.contains("bpf")
+        || target.contains("switch"))
 }
 
 pub fn is_valid_test_suite_arg<'a, P: AsRef<Path>>(
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 87dc5138539..f6348b2bddc 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -17,6 +17,7 @@
     - [Template for Target-specific Documentation](platform-support/TEMPLATE.md)
     - [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md)
     - [\*-apple-watchos\*](platform-support/apple-watchos.md)
+    - [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md)
     - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md)
     - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md)
     - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index eb985803266..7a03238f13d 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -209,6 +209,7 @@ target | std | host | notes
 `aarch64-apple-tvos` | * |  | ARM64 tvOS
 [`aarch64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ |  | ARM64 Apple WatchOS Simulator
 [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ |  | ARM64 SOLID with TOPPERS/ASP3
+[`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * |  | ARM64 Nintendo Switch, Horizon
 [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
 `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD
 `aarch64-unknown-hermit` | ✓ |  | ARM64 HermitCore
diff --git a/src/doc/rustc/src/platform-support/aarch64-nintendo-switch-freestanding.md b/src/doc/rustc/src/platform-support/aarch64-nintendo-switch-freestanding.md
new file mode 100644
index 00000000000..308e1fe2f92
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/aarch64-nintendo-switch-freestanding.md
@@ -0,0 +1,49 @@
+# aarch64-nintendo-switch-freestanding
+
+**Tier: 3**
+
+Nintendo Switch with pure-Rust toolchain.
+
+## Designated Developers
+
+* [@leo60228](https://github.com/leo60228)
+* [@jam1garner](https://github.com/jam1garner)
+
+## Requirements
+
+This target is cross-compiled.
+It has no special requirements for the host.
+
+## Building
+
+The target can be built by enabling it for a `rustc` build:
+
+```toml
+[build]
+build-stage = 1
+target = ["aarch64-nintendo-switch-freestanding"]
+```
+
+## Cross-compilation
+
+This target can be cross-compiled from any host.
+
+## Testing
+
+Currently there is no support to run the rustc test suite for this target.
+
+## Building Rust programs
+
+If `rustc` has support for that target and the library artifacts are available,
+then Rust programs can be built for that target:
+
+```text
+rustc --target aarch64-nintendo-switch-freestanding your-code.rs
+```
+
+To generate binaries in the NRO format that can be easily run on-device, you
+can use [cargo-nx](https://github.com/aarch64-switch-rs/cargo-nx):
+
+```text
+cargo nx --triple=aarch64-nintendo-switch-freestanding
+```