diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index f7aec73644921..a0b65399da2c5 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -128,7 +128,7 @@ pub fn spin_loop() {
         #[cfg(target_arch = "aarch64")]
         {
             // SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets.
-            unsafe { crate::arch::aarch64::__yield() };
+            unsafe { crate::arch::aarch64::__isb(crate::arch::aarch64::SY) };
         }
         #[cfg(target_arch = "arm")]
         {
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 7f57d476aa9fb..b3c67b84da617 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -6,43 +6,38 @@
     }
 </style>
 
-Support for different platforms are organized into three tiers, each with a
-different set of guarantees. For more information on the policies for targets
-at each tier, see the [Target Tier Policy](target-tier-policy.md).
+Support for different platforms ("targets") are organized into three tiers,
+each with a different set of guarantees. For more information on the policies
+for targets at each tier, see the [Target Tier Policy](target-tier-policy.md).
 
-Platforms are identified by their "target triple" which is the string to
-inform the compiler what kind of output should be produced. The columns in the
-tables below have the following meanings:
+Targets are identified by their "target triple" which is the string to inform
+the compiler what kind of output should be produced.
 
-* std:
-    * ✓ indicates the full standard library is available.
-    * \* indicates the target only supports [`no_std`] development.
-    * ? indicates the standard library support is unknown or a work-in-progress.
-* host: A ✓ indicates that `rustc` and `cargo` can run on the host platform.
+## Tier 1 with Host Tools
 
-[`no_std`]: https://rust-embedded.github.io/book/intro/no-std.html
-
-## Tier 1
+Tier 1 targets can be thought of as "guaranteed to work". The Rust project
+builds official binary releases for each tier 1 target, and automated testing
+ensures that each tier 1 target builds and passes tests after each change.
 
-Tier 1 platforms can be thought of as "guaranteed to work".
-Specifically they will each satisfy the following requirements:
+Tier 1 targets with host tools additionally support running tools like `rustc`
+and `cargo` natively on the target, and automated testing ensures that tests
+pass for the host tools as well. This allows the target to be used as a
+development platform, not just a compilation target. For the full requirements,
+see [Tier 1 with Host Tools](target-tier-policy.md#tier-1-with-host-tools) in
+the Target Tier Policy.
 
-* Official binary releases are provided for the platform.
-* Automated testing is set up to run tests for the platform.
-* Landing changes to the `rust-lang/rust` repository's master branch is gated
-  on tests passing.
-* Documentation for how to use and how to build the platform is available.
+All tier 1 targets with host tools support the full standard library.
 
-target | std | host | notes
--------|-----|------|-------
-`aarch64-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (kernel 4.2, glibc 2.17+) [^missing-stack-probes]
-`i686-pc-windows-gnu` | ✓ | ✓ | 32-bit MinGW (Windows 7+)
-`i686-pc-windows-msvc` | ✓ | ✓ | 32-bit MSVC (Windows 7+)
-`i686-unknown-linux-gnu` | ✓ | ✓ | 32-bit Linux (kernel 2.6.32+, glibc 2.11+)
-`x86_64-apple-darwin` | ✓ | ✓ | 64-bit macOS (10.7+, Lion+)
-`x86_64-pc-windows-gnu` | ✓ | ✓ | 64-bit MinGW (Windows 7+)
-`x86_64-pc-windows-msvc` | ✓ | ✓ | 64-bit MSVC (Windows 7+)
-`x86_64-unknown-linux-gnu` | ✓ | ✓ | 64-bit Linux (kernel 2.6.32+, glibc 2.11+)
+target | notes
+-------|-------
+`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.2, glibc 2.17+) [^missing-stack-probes]
+`i686-pc-windows-gnu` | 32-bit MinGW (Windows 7+)
+`i686-pc-windows-msvc` | 32-bit MSVC (Windows 7+)
+`i686-unknown-linux-gnu` | 32-bit Linux (kernel 2.6.32+, glibc 2.11+)
+`x86_64-apple-darwin` | 64-bit macOS (10.7+, Lion+)
+`x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 7+)
+`x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 7+)
+`x86_64-unknown-linux-gnu` | 64-bit Linux (kernel 2.6.32+, glibc 2.11+)
 
 [^missing-stack-probes]: Stack probes support is missing on
   `aarch64-unknown-linux-gnu`, but it's planned to be implemented in the near
@@ -50,105 +45,153 @@ target | std | host | notes
 
 [77071]: https://github.com/rust-lang/rust/issues/77071
 
+## Tier 1
+
+Tier 1 targets can be thought of as "guaranteed to work". The Rust project
+builds official binary releases for each tier 1 target, and automated testing
+ensures that each tier 1 target builds and passes tests after each change. For
+the full requirements, see [Tier 1 target
+policy](target-tier-policy.md#tier-1-target-policy) in the Target Tier Policy.
+
+At this time, all Tier 1 targets are [Tier 1 with Host
+Tools](#tier-1-with-host-tools).
+
+## Tier 2 with Host Tools
+
+Tier 2 targets can be thought of as "guaranteed to build". The Rust project
+builds official binary releases for each tier 2 target, and automated builds
+ensure that each tier 2 target builds after each change. Automated tests are
+not always run so it's not guaranteed to produce a working build, but tier 2
+targets often work to quite a good degree and patches are always welcome!
+
+Tier 2 targets with host tools additionally support running tools like `rustc`
+and `cargo` natively on the target, and automated builds ensure that the host
+tools build as well. This allows the target to be used as a development
+platform, not just a compilation target. For the full requirements, see [Tier 2
+with Host Tools](target-tier-policy.md#tier-2-with-host-tools) in the Target
+Tier Policy.
+
+All tier 2 targets with host tools support the full standard library.
+
+target | notes
+-------|-------
+`aarch64-apple-darwin` | ARM64 macOS (11.0+, Big Sur+)
+`aarch64-pc-windows-msvc` | ARM64 Windows MSVC
+`aarch64-unknown-linux-musl` | ARM64 Linux with MUSL
+`arm-unknown-linux-gnueabi` | ARMv6 Linux (kernel 3.2, glibc 2.17)
+`arm-unknown-linux-gnueabihf` | ARMv6 Linux, hardfloat (kernel 3.2, glibc 2.17)
+`armv7-unknown-linux-gnueabihf` | ARMv7 Linux, hardfloat (kernel 3.2, glibc 2.17)
+`mips-unknown-linux-gnu` | MIPS Linux (kernel 4.4, glibc 2.23)
+`mips64-unknown-linux-gnuabi64` | MIPS64 Linux, n64 ABI (kernel 4.4, glibc 2.23)
+`mips64el-unknown-linux-gnuabi64` | MIPS64 (LE) Linux, n64 ABI (kernel 4.4, glibc 2.23)
+`mipsel-unknown-linux-gnu` | MIPS (LE) Linux (kernel 4.4, glibc 2.23)
+`powerpc-unknown-linux-gnu` | PowerPC Linux (kernel 2.6.32, glibc 2.11)
+`powerpc64-unknown-linux-gnu` | PPC64 Linux (kernel 2.6.32, glibc 2.11)
+`powerpc64le-unknown-linux-gnu` | PPC64LE Linux (kernel 3.10, glibc 2.17)
+`riscv64gc-unknown-linux-gnu` | RISC-V Linux (kernel 4.20, glibc 2.29)
+`s390x-unknown-linux-gnu` | S390x Linux (kernel 2.6.32, glibc 2.11)
+`x86_64-unknown-freebsd` | 64-bit FreeBSD
+`x86_64-unknown-illumos` | illumos
+`x86_64-unknown-linux-musl` | 64-bit Linux with MUSL
+`x86_64-unknown-netbsd` | NetBSD/amd64
+
 ## Tier 2
 
-Tier 2 platforms can be thought of as "guaranteed to build". Automated tests
-are not run so it's not guaranteed to produce a working build, but platforms
-often work to quite a good degree and patches are always welcome!
-Specifically, these platforms are required to have each of the following:
+Tier 2 targets can be thought of as "guaranteed to build". The Rust project
+builds official binary releases for each tier 2 target, and automated builds
+ensure that each tier 2 target builds after each change. Automated tests are
+not always run so it's not guaranteed to produce a working build, but tier 2
+targets often work to quite a good degree and patches are always welcome! For
+the full requirements, see [Tier 2 target
+policy](target-tier-policy.md#tier-2-target-policy) in the Target Tier Policy.
 
-* Official binary releases are provided for the platform.
-* Automated building is set up, but may not be running tests.
-* Landing changes to the `rust-lang/rust` repository's master branch is gated on
-    platforms **building**. For some platforms only the standard library is
-    compiled, but for others `rustc` and `cargo` are too.
+The `std` column in the table below has the following meanings:
 
-target | std | host | notes
--------|-----|------|-------
-`aarch64-apple-darwin` | ✓ | ✓ | ARM64 macOS (11.0+, Big Sur+)
-`aarch64-apple-ios` | ✓ |  | ARM64 iOS
-`aarch64-fuchsia` | ✓ |  | ARM64 Fuchsia
-`aarch64-linux-android` | ✓ |  | ARM64 Android
-`aarch64-pc-windows-msvc` | ✓ | ✓ | ARM64 Windows MSVC
-`aarch64-unknown-linux-musl` | ✓ | ✓ | ARM64 Linux with MUSL
-`aarch64-unknown-none` | * |  | Bare ARM64, hardfloat
-`aarch64-unknown-none-softfloat` | * |  | Bare ARM64, softfloat
-`arm-linux-androideabi` | ✓ |  | ARMv7 Android
-`arm-unknown-linux-gnueabi` | ✓ | ✓ | ARMv6 Linux (kernel 3.2, glibc 2.17)
-`arm-unknown-linux-gnueabihf` | ✓ | ✓ | ARMv6 Linux, hardfloat (kernel 3.2, glibc 2.17)
-`arm-unknown-linux-musleabi` | ✓ |  | ARMv6 Linux with MUSL
-`arm-unknown-linux-musleabihf` | ✓ |  | ARMv6 Linux with MUSL, hardfloat
-`armebv7r-none-eabi` | * |  | Bare ARMv7-R, Big Endian
-`armebv7r-none-eabihf` | * |  | Bare ARMv7-R, Big Endian, hardfloat
-`armv5te-unknown-linux-gnueabi` | ✓ |  | ARMv5TE Linux (kernel 4.4, glibc 2.23)
-`armv5te-unknown-linux-musleabi` | ✓ |  | ARMv5TE Linux with MUSL
-`armv7-linux-androideabi` | ✓ |  | ARMv7a Android
-`armv7a-none-eabi` | * |  | Bare ARMv7-A
-`armv7r-none-eabi` | * |  | Bare ARMv7-R
-`armv7r-none-eabihf` | * |  | Bare ARMv7-R, hardfloat
-`armv7-unknown-linux-gnueabi` | ✓ |   | ARMv7 Linux (kernel 4.15, glibc 2.27)
-`armv7-unknown-linux-gnueabihf` | ✓ | ✓ | ARMv7 Linux, hardfloat (kernel 3.2, glibc 2.17)
-`armv7-unknown-linux-musleabi` | ✓ |   | ARMv7 Linux, MUSL
-`armv7-unknown-linux-musleabihf` | ✓ |  | ARMv7 Linux with MUSL
-`asmjs-unknown-emscripten` | ✓ |  | asm.js via Emscripten
-`i586-pc-windows-msvc` | ✓ |  | 32-bit Windows w/o SSE
-`i586-unknown-linux-gnu` | ✓ |  | 32-bit Linux w/o SSE (kernel 4.4, glibc 2.23)
-`i586-unknown-linux-musl` | ✓ |  | 32-bit Linux w/o SSE, MUSL
-`i686-linux-android` | ✓ |  | 32-bit x86 Android
-`i686-unknown-freebsd` | ✓ |  | 32-bit FreeBSD
-`i686-unknown-linux-musl` | ✓ |  | 32-bit Linux with MUSL
-`mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23)
-`mips-unknown-linux-musl` | ✓ |  | MIPS Linux with MUSL
-`mips64-unknown-linux-gnuabi64` | ✓ | ✓ | MIPS64 Linux, n64 ABI (kernel 4.4, glibc 2.23)
-`mips64-unknown-linux-muslabi64` | ✓ |  | MIPS64 Linux, n64 ABI, MUSL
-`mips64el-unknown-linux-gnuabi64` | ✓ | ✓ | MIPS64 (LE) Linux, n64 ABI (kernel 4.4, glibc 2.23)
-`mips64el-unknown-linux-muslabi64` | ✓ |  | MIPS64 (LE) Linux, n64 ABI, MUSL
-`mipsel-unknown-linux-gnu` | ✓ | ✓ | MIPS (LE) Linux (kernel 4.4, glibc 2.23)
-`mipsel-unknown-linux-musl` | ✓ |  | MIPS (LE) Linux with MUSL
-`nvptx64-nvidia-cuda` | ✓ |  | --emit=asm generates PTX code that [runs on NVIDIA GPUs]
-`powerpc-unknown-linux-gnu` | ✓ | ✓ | PowerPC Linux (kernel 2.6.32, glibc 2.11)
-`powerpc64-unknown-linux-gnu` | ✓ | ✓ | PPC64 Linux (kernel 2.6.32, glibc 2.11)
-`powerpc64le-unknown-linux-gnu` | ✓ | ✓ | PPC64LE Linux (kernel 3.10, glibc 2.17)
-`riscv32i-unknown-none-elf` | * |  | Bare RISC-V (RV32I ISA)
-`riscv32imac-unknown-none-elf` | * |  | Bare RISC-V (RV32IMAC ISA)
-`riscv32imc-unknown-none-elf` | * |  | Bare RISC-V (RV32IMC ISA)
-`riscv64gc-unknown-linux-gnu` | ✓ | ✓ | RISC-V Linux (kernel 4.20, glibc 2.29)
-`riscv64gc-unknown-none-elf` | * |  | Bare RISC-V (RV64IMAFDC ISA)
-`riscv64imac-unknown-none-elf` | * |  | Bare RISC-V (RV64IMAC ISA)
-`s390x-unknown-linux-gnu` | ✓ | ✓ | S390x Linux (kernel 2.6.32, glibc 2.11)
-`sparc64-unknown-linux-gnu` | ✓ |  | SPARC Linux (kernel 4.4, glibc 2.23)
-`sparcv9-sun-solaris` | ✓ |  | SPARC Solaris 10/11, illumos
-`thumbv6m-none-eabi` | * |  | Bare Cortex-M0, M0+, M1
-`thumbv7em-none-eabi` | * |  | Bare Cortex-M4, M7
-`thumbv7em-none-eabihf` | * |  | Bare Cortex-M4F, M7F, FPU, hardfloat
-`thumbv7m-none-eabi` | * |  | Bare Cortex-M3
-`thumbv7neon-linux-androideabi` | ✓ |  | Thumb2-mode ARMv7a Android with NEON
-`thumbv7neon-unknown-linux-gnueabihf` | ✓ |  | Thumb2-mode ARMv7a Linux with NEON (kernel 4.4, glibc 2.23)
-`thumbv8m.base-none-eabi` | * |  | ARMv8-M Baseline
-`thumbv8m.main-none-eabi` | * |  | ARMv8-M Mainline
-`thumbv8m.main-none-eabihf` | * |  | ARMv8-M Mainline, hardfloat
-`wasm32-unknown-emscripten` | ✓ |  | WebAssembly via Emscripten
-`wasm32-unknown-unknown` | ✓ |  | WebAssembly
-`wasm32-wasi` | ✓ |  | WebAssembly with WASI
-`x86_64-apple-ios` | ✓ |  | 64-bit x86 iOS
-`x86_64-fortanix-unknown-sgx` | ✓ |  | [Fortanix ABI] for 64-bit Intel SGX
-`x86_64-fuchsia` | ✓ |  | 64-bit Fuchsia
-`x86_64-linux-android` | ✓ |  | 64-bit x86 Android
-`x86_64-pc-solaris` | ✓ |  | 64-bit Solaris 10/11, illumos
-`x86_64-unknown-freebsd` | ✓ | ✓ | 64-bit FreeBSD
-`x86_64-unknown-illumos` | ✓ | ✓ | illumos
-`x86_64-unknown-linux-gnux32` | ✓ |  | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27)
-`x86_64-unknown-linux-musl` | ✓ | ✓ | 64-bit Linux with MUSL
-`x86_64-unknown-netbsd` | ✓ | ✓ | NetBSD/amd64
-`x86_64-unknown-redox` | ✓ |  | Redox OS
+* ✓ indicates the full standard library is available.
+* \* indicates the target only supports [`no_std`] development.
+
+[`no_std`]: https://rust-embedded.github.io/book/intro/no-std.html
+
+target | std | notes
+-------|-----|-------
+`aarch64-apple-ios` | ✓ | ARM64 iOS
+`aarch64-fuchsia` | ✓ | ARM64 Fuchsia
+`aarch64-linux-android` | ✓ | ARM64 Android
+`aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat
+`aarch64-unknown-none` | * | Bare ARM64, hardfloat
+`arm-linux-androideabi` | ✓ | ARMv7 Android
+`arm-unknown-linux-musleabi` | ✓ | ARMv6 Linux with MUSL
+`arm-unknown-linux-musleabihf` | ✓ | ARMv6 Linux with MUSL, hardfloat
+`armebv7r-none-eabi` | * | Bare ARMv7-R, Big Endian
+`armebv7r-none-eabihf` | * | Bare ARMv7-R, Big Endian, hardfloat
+`armv5te-unknown-linux-gnueabi` | ✓ | ARMv5TE Linux (kernel 4.4, glibc 2.23)
+`armv5te-unknown-linux-musleabi` | ✓ | ARMv5TE Linux with MUSL
+`armv7-linux-androideabi` | ✓ | ARMv7a Android
+`armv7-unknown-linux-gnueabi` | ✓ |ARMv7 Linux (kernel 4.15, glibc 2.27)
+`armv7-unknown-linux-musleabi` | ✓ |ARMv7 Linux, MUSL
+`armv7-unknown-linux-musleabihf` | ✓ | ARMv7 Linux with MUSL
+`armv7a-none-eabi` | * | Bare ARMv7-A
+`armv7r-none-eabi` | * | Bare ARMv7-R
+`armv7r-none-eabihf` | * | Bare ARMv7-R, hardfloat
+`asmjs-unknown-emscripten` | ✓ | asm.js via Emscripten
+`i586-pc-windows-msvc` | ✓ | 32-bit Windows w/o SSE
+`i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 4.4, glibc 2.23)
+`i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, MUSL
+`i686-linux-android` | ✓ | 32-bit x86 Android
+`i686-unknown-freebsd` | ✓ | 32-bit FreeBSD
+`i686-unknown-linux-musl` | ✓ | 32-bit Linux with MUSL
+`mips-unknown-linux-musl` | ✓ | MIPS Linux with MUSL
+`mips64-unknown-linux-muslabi64` | ✓ | MIPS64 Linux, n64 ABI, MUSL
+`mips64el-unknown-linux-muslabi64` | ✓ | MIPS64 (LE) Linux, n64 ABI, MUSL
+`mipsel-unknown-linux-musl` | ✓ | MIPS (LE) Linux with MUSL
+`nvptx64-nvidia-cuda` | ✓ | --emit=asm generates PTX code that [runs on NVIDIA GPUs]
+`riscv32i-unknown-none-elf` | * | Bare RISC-V (RV32I ISA)
+`riscv32imac-unknown-none-elf` | * | Bare RISC-V (RV32IMAC ISA)
+`riscv32imc-unknown-none-elf` | * | Bare RISC-V (RV32IMC ISA)
+`riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA)
+`riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA)
+`sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4, glibc 2.23)
+`sparcv9-sun-solaris` | ✓ | SPARC Solaris 10/11, illumos
+`thumbv6m-none-eabi` | * | Bare Cortex-M0, M0+, M1
+`thumbv7em-none-eabi` | * | Bare Cortex-M4, M7
+`thumbv7em-none-eabihf` | * | Bare Cortex-M4F, M7F, FPU, hardfloat
+`thumbv7m-none-eabi` | * | Bare Cortex-M3
+`thumbv7neon-linux-androideabi` | ✓ | Thumb2-mode ARMv7a Android with NEON
+`thumbv7neon-unknown-linux-gnueabihf` | ✓ | Thumb2-mode ARMv7a Linux with NEON (kernel 4.4, glibc 2.23)
+`thumbv8m.base-none-eabi` | * | ARMv8-M Baseline
+`thumbv8m.main-none-eabi` | * | ARMv8-M Mainline
+`thumbv8m.main-none-eabihf` | * | ARMv8-M Mainline, hardfloat
+`wasm32-unknown-emscripten` | ✓ | WebAssembly via Emscripten
+`wasm32-unknown-unknown` | ✓ | WebAssembly
+`wasm32-wasi` | ✓ | WebAssembly with WASI
+`x86_64-apple-ios` | ✓ | 64-bit x86 iOS
+`x86_64-fortanix-unknown-sgx` | ✓ | [Fortanix ABI] for 64-bit Intel SGX
+`x86_64-fuchsia` | ✓ | 64-bit Fuchsia
+`x86_64-linux-android` | ✓ | 64-bit x86 Android
+`x86_64-pc-solaris` | ✓ | 64-bit Solaris 10/11, illumos
+`x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27)
+`x86_64-unknown-redox` | ✓ | Redox OS
 
 [Fortanix ABI]: https://edp.fortanix.com/
 
 ## Tier 3
 
-Tier 3 platforms are those which the Rust codebase has support for, but which
-are not built or tested automatically, and may not work. Official builds are
-not available.
+Tier 3 targets are those which the Rust codebase has support for, but which the
+Rust project does not build or test automatically, so they may or may not work.
+Official builds are not available. For the full requirements, see [Tier 3
+target policy](target-tier-policy.md#tier-3-target-policy) in the Target Tier
+Policy.
+
+The `std` column in the table below has the following meanings:
+
+* ✓ indicates the full standard library is available.
+* \* indicates the target only supports [`no_std`] development.
+* ? indicates the standard library support is unknown or a work-in-progress.
+
+[`no_std`]: https://rust-embedded.github.io/book/intro/no-std.html
+
+The `host` column indicates whether the codebase includes support for building
+host tools.
 
 target | std | host | notes
 -------|-----|------|-------
@@ -163,8 +206,8 @@ target | std | host | notes
 `aarch64-unknown-redox` | ? |  | ARM64 Redox OS
 `aarch64-uwp-windows-msvc` | ? |  |
 `aarch64-wrs-vxworks` | ? |  |
-`aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian)
 `aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI)
+`aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian)
 `armv4t-unknown-linux-gnueabi` | ? |  |
 `armv5te-unknown-linux-uclibceabi` | ? |  | ARMv5TE Linux with uClibc
 `armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD
@@ -175,22 +218,22 @@ target | std | host | notes
 `armv7-wrs-vxworks-eabihf` | ? |  |
 `armv7a-none-eabihf` | * | | ARM Cortex-A, hardfloat
 `armv7s-apple-ios` | ✓ |  |
-`avr-unknown-gnu-atmega328` | ✗ |  | AVR. Requires `-Z build-std=core`
+`avr-unknown-gnu-atmega328` | * |  | AVR. Requires `-Z build-std=core`
 `hexagon-unknown-linux-musl` | ? |  |
 `i386-apple-ios` | ✓ |  | 32-bit x86 iOS
 `i686-apple-darwin` | ✓ | ✓ | 32-bit macOS (10.7+, Lion+)
 `i686-pc-windows-msvc` | ✓ |  | 32-bit Windows XP support
-`i686-unknown-uefi` | * |  | 32-bit UEFI
 `i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku
 `i686-unknown-netbsd` | ✓ | ✓ | NetBSD/i386 with SSE2
 `i686-unknown-openbsd` | ✓ | ✓ | 32-bit OpenBSD
+`i686-unknown-uefi` | * |  | 32-bit UEFI
 `i686-uwp-windows-gnu` | ? |  |
 `i686-uwp-windows-msvc` | ? |  |
 `i686-wrs-vxworks` | ? |  |
 `mips-unknown-linux-uclibc` | ✓ |  | MIPS Linux with uClibc
+`mipsel-sony-psp` | * |  | MIPS (LE) Sony PlayStation Portable (PSP)
 `mipsel-unknown-linux-uclibc` | ✓ |  | MIPS (LE) Linux with uClibc
 `mipsel-unknown-none` | * |  | Bare MIPS (LE) softfloat
-`mipsel-sony-psp` | * |  | MIPS (LE) Sony PlayStation Portable (PSP)
 `mipsisa32r6-unknown-linux-gnu` | ? |  |
 `mipsisa32r6el-unknown-linux-gnu` | ? |  |
 `mipsisa64r6-unknown-linux-gnuabi64` | ? |  |
@@ -200,34 +243,34 @@ target | std | host | notes
 `powerpc-unknown-linux-musl` | ? |  |
 `powerpc-unknown-netbsd` | ✓ | ✓ |
 `powerpc-unknown-openbsd` | ? |  |
-`powerpc-wrs-vxworks` | ? |  |
 `powerpc-wrs-vxworks-spe` | ? |  |
+`powerpc-wrs-vxworks` | ? |  |
 `powerpc64-unknown-freebsd` | ✓ | ✓ | PPC64 FreeBSD (ELFv1 and ELFv2)
 `powerpc64-unknown-linux-musl` | ? |  |
 `powerpc64-wrs-vxworks` | ? |  |
 `powerpc64le-unknown-linux-musl` | ? |  |
-`riscv64gc-unknown-linux-musl` |   |   | RISC-V Linux (kernel 4.20, musl 1.2.0)
 `riscv32gc-unknown-linux-gnu` |   |   | RISC-V Linux (kernel 5.4, glibc 2.33)
 `riscv32gc-unknown-linux-musl` |   |   | RISC-V Linux (kernel 5.4, musl + RISCV32 support patches)
+`riscv64gc-unknown-linux-musl` |   |   | RISC-V Linux (kernel 4.20, musl 1.2.0)
 `s390x-unknown-linux-musl` |  |  | S390x Linux (kernel 2.6.32, MUSL)
 `sparc-unknown-linux-gnu` | ✓ |  | 32-bit SPARC Linux
 `sparc64-unknown-netbsd` | ✓ | ✓ | NetBSD/sparc64
 `sparc64-unknown-openbsd` | ? |  |
+`thumbv4t-none-eabi` | * |  | ARMv4T T32
 `thumbv7a-pc-windows-msvc` | ? |  |
 `thumbv7a-uwp-windows-msvc` | ✓ |  |
 `thumbv7neon-unknown-linux-musleabihf` | ? |  | Thumb2-mode ARMv7a Linux with NEON, MUSL
-`thumbv4t-none-eabi` | * |  | ARMv4T T32
 `wasm64-unknown-unknown` | * |  | WebAssembly
 `x86_64-apple-ios-macabi` | ✓ |  | Apple Catalyst on x86_64
 `x86_64-apple-tvos` | * | | x86 64-bit tvOS
-`x86_64-unknown-none-linuxkernel` | * |  | Linux kernel modules
-`x86_64-sun-solaris` | ? |  | Deprecated target for 64-bit Solaris 10/11, illumos
 `x86_64-pc-windows-msvc` | ✓ |  | 64-bit Windows XP support
+`x86_64-sun-solaris` | ? |  | Deprecated target for 64-bit Solaris 10/11, illumos
 `x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD
 `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku
 `x86_64-unknown-hermit` | ? |  |
-`x86_64-unknown-none-hermitkernel` | ? |  | HermitCore kernel
 `x86_64-unknown-l4re-uclibc` | ? |  |
+`x86_64-unknown-none-hermitkernel` | ? |  | HermitCore kernel
+`x86_64-unknown-none-linuxkernel` | * |  | Linux kernel modules
 `x86_64-unknown-openbsd` | ✓ | ✓ | 64-bit OpenBSD
 `x86_64-unknown-uefi` | * |  | 64-bit UEFI
 `x86_64-uwp-windows-gnu` | ✓ |  |
diff --git a/src/doc/rustc/src/target-tier-policy.md b/src/doc/rustc/src/target-tier-policy.md
index 463f56099f6e9..a2cb03519160e 100644
--- a/src/doc/rustc/src/target-tier-policy.md
+++ b/src/doc/rustc/src/target-tier-policy.md
@@ -1,5 +1,16 @@
 # Target Tier Policy
 
+## Table of Contents
+
+* [General](#general)
+* [Tier 3 target policy](#tier-3-target-policy)
+* [Tier 2 target policy](#tier-2-target-policy)
+  * [Tier 2 with host tools](#tier-2-with-host-tools)
+* [Tier 1 target policy](#tier-1-target-policy)
+  * [Tier 1 with host tools](#tier-1-with-host-tools)
+
+## General
+
 Rust provides three tiers of target support:
 
 - Rust provides no guarantees about tier 3 targets; they exist in the codebase,
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 5e47144588b3f..c6c429a3510e8 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -4,6 +4,7 @@ use std::fmt;
 use std::hash::{Hash, Hasher};
 use std::iter::FromIterator;
 use std::lazy::SyncOnceCell as OnceCell;
+use std::path::PathBuf;
 use std::rc::Rc;
 use std::sync::Arc;
 use std::{slice, vec};
@@ -90,6 +91,58 @@ impl ExternalCrate {
         tcx.crate_name(self.crate_num)
     }
 
+    crate fn src_root(&self, tcx: TyCtxt<'_>) -> PathBuf {
+        match self.src(tcx) {
+            FileName::Real(ref p) => match p.local_path().parent() {
+                Some(p) => p.to_path_buf(),
+                None => PathBuf::new(),
+            },
+            _ => PathBuf::new(),
+        }
+    }
+
+    /// Attempts to find where an external crate is located, given that we're
+    /// rendering in to the specified source destination.
+    crate fn location(
+        &self,
+        extern_url: Option<&str>,
+        dst: &std::path::Path,
+        tcx: TyCtxt<'_>,
+    ) -> ExternalLocation {
+        use ExternalLocation::*;
+
+        fn to_remote(url: impl ToString) -> ExternalLocation {
+            let mut url = url.to_string();
+            if !url.ends_with('/') {
+                url.push('/');
+            }
+            Remote(url)
+        }
+
+        // See if there's documentation generated into the local directory
+        // WARNING: since rustdoc creates these directories as it generates documentation, this check is only accurate before rendering starts.
+        // Make sure to call `location()` by that time.
+        let local_location = dst.join(&*self.name(tcx).as_str());
+        if local_location.is_dir() {
+            return Local;
+        }
+
+        if let Some(url) = extern_url {
+            return to_remote(url);
+        }
+
+        // Failing that, see if there's an attribute specifying where to find this
+        // external crate
+        let did = DefId { krate: self.crate_num, index: CRATE_DEF_INDEX };
+        tcx.get_attrs(did)
+            .lists(sym::doc)
+            .filter(|a| a.has_name(sym::html_root_url))
+            .filter_map(|a| a.value_str())
+            .map(to_remote)
+            .next()
+            .unwrap_or(Unknown) // Well, at least we tried.
+    }
+
     crate fn keywords(&self, tcx: TyCtxt<'_>) -> ThinVec<(DefId, Symbol)> {
         let root = self.def_id();
 
@@ -381,7 +434,7 @@ impl Item {
                         let relative_to = &cx.current;
                         if let Some(ref fragment) = *fragment {
                             let url = match cx.cache().extern_locations.get(&self.def_id.krate) {
-                                Some(&(_, _, ExternalLocation::Local)) => {
+                                Some(ExternalLocation::Local) => {
                                     if relative_to[0] == "std" {
                                         let depth = relative_to.len() - 1;
                                         "../".repeat(depth)
@@ -390,10 +443,10 @@ impl Item {
                                         format!("{}std/", "../".repeat(depth))
                                     }
                                 }
-                                Some(&(_, _, ExternalLocation::Remote(ref s))) => {
+                                Some(ExternalLocation::Remote(ref s)) => {
                                     format!("{}/std/", s.trim_end_matches('/'))
                                 }
-                                Some(&(_, _, ExternalLocation::Unknown)) | None => format!(
+                                Some(ExternalLocation::Unknown) | None => format!(
                                     "https://doc.rust-lang.org/{}/std/",
                                     crate::doc_rust_lang_org_channel(),
                                 ),
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 8f8bca64e1497..8723e47586ee4 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -1,21 +1,19 @@
 use std::collections::BTreeMap;
 use std::mem;
-use std::path::{Path, PathBuf};
+use std::path::Path;
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
 use rustc_middle::middle::privacy::AccessLevels;
 use rustc_middle::ty::TyCtxt;
-use rustc_span::source_map::FileName;
 use rustc_span::symbol::sym;
-use rustc_span::Symbol;
 
 use crate::clean::{self, GetDefId};
 use crate::fold::DocFolder;
 use crate::formats::item_type::ItemType;
 use crate::formats::Impl;
 use crate::html::markdown::short_markdown_summary;
-use crate::html::render::cache::{extern_location, get_index_search_type, ExternalLocation};
+use crate::html::render::cache::{get_index_search_type, ExternalLocation};
 use crate::html::render::IndexItem;
 
 /// This cache is used to store information about the [`clean::Crate`] being
@@ -72,7 +70,7 @@ crate struct Cache {
     crate implementors: FxHashMap<DefId, Vec<Impl>>,
 
     /// Cache of where external crate documentation can be found.
-    crate extern_locations: FxHashMap<CrateNum, (Symbol, PathBuf, ExternalLocation)>,
+    crate extern_locations: FxHashMap<CrateNum, ExternalLocation>,
 
     /// Cache of where documentation for primitives can be found.
     crate primitive_locations: FxHashMap<clean::PrimitiveType, DefId>,
@@ -155,21 +153,10 @@ impl Cache {
         // Cache where all our extern crates are located
         // FIXME: this part is specific to HTML so it'd be nice to remove it from the common code
         for &(n, ref e) in &krate.externs {
-            let src_root = match e.src(tcx) {
-                FileName::Real(ref p) => match p.local_path().parent() {
-                    Some(p) => p.to_path_buf(),
-                    None => PathBuf::new(),
-                },
-                _ => PathBuf::new(),
-            };
             let name = e.name(tcx);
             let extern_url = extern_html_root_urls.get(&*name.as_str()).map(|u| &**u);
             let did = DefId { krate: n, index: CRATE_DEF_INDEX };
-            self.extern_locations.insert(
-                n,
-                (name, src_root, extern_location(e, extern_url, tcx.get_attrs(did), &dst, tcx)),
-            );
-
+            self.extern_locations.insert(n, e.location(extern_url, &dst, tcx));
             self.external_paths.insert(did, (vec![name.to_string()], ItemType::Module));
         }
 
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 45412f55c1572..f211a5acf5ea5 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -16,7 +16,7 @@ use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::{DefId, CRATE_DEF_INDEX};
 use rustc_target::spec::abi::Abi;
 
-use crate::clean::{self, utils::find_nearest_parent_module, PrimitiveType};
+use crate::clean::{self, utils::find_nearest_parent_module, ExternalCrate, PrimitiveType};
 use crate::formats::item_type::ItemType;
 use crate::html::escape::Escape;
 use crate::html::render::cache::ExternalLocation;
@@ -465,14 +465,14 @@ crate fn href(did: DefId, cx: &Context<'_>) -> Option<(String, ItemType, Vec<Str
                 fqp,
                 shortty,
                 match cache.extern_locations[&did.krate] {
-                    (.., ExternalLocation::Remote(ref s)) => {
+                    ExternalLocation::Remote(ref s) => {
                         let s = s.trim_end_matches('/');
                         let mut s = vec![&s[..]];
                         s.extend(module_fqp[..].iter().map(String::as_str));
                         s
                     }
-                    (.., ExternalLocation::Local) => href_relative_parts(module_fqp, relative_to),
-                    (.., ExternalLocation::Unknown) => return None,
+                    ExternalLocation::Local => href_relative_parts(module_fqp, relative_to),
+                    ExternalLocation::Unknown => return None,
                 },
             )
         }
@@ -578,12 +578,14 @@ fn primitive_link(
             Some(&def_id) => {
                 let cname_str;
                 let loc = match m.extern_locations[&def_id.krate] {
-                    (ref cname, _, ExternalLocation::Remote(ref s)) => {
-                        cname_str = cname.as_str();
+                    ExternalLocation::Remote(ref s) => {
+                        cname_str =
+                            ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()).as_str();
                         Some(vec![s.trim_end_matches('/'), &cname_str[..]])
                     }
-                    (ref cname, _, ExternalLocation::Local) => {
-                        cname_str = cname.as_str();
+                    ExternalLocation::Local => {
+                        cname_str =
+                            ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()).as_str();
                         Some(if cx.current.first().map(|x| &x[..]) == Some(&cname_str[..]) {
                             iter::repeat("..").take(cx.current.len() - 1).collect()
                         } else {
@@ -591,7 +593,7 @@ fn primitive_link(
                             iter::repeat("..").take(cx.current.len()).chain(cname).collect()
                         })
                     }
-                    (.., ExternalLocation::Unknown) => None,
+                    ExternalLocation::Unknown => None,
                 };
                 if let Some(loc) = loc {
                     write!(
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index f4296a04e5921..27a8065afb6d2 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -1,15 +1,13 @@
 use std::collections::BTreeMap;
-use std::path::Path;
 
-use rustc_ast::ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_middle::ty::TyCtxt;
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::Symbol;
 use serde::ser::{Serialize, SerializeStruct, Serializer};
 
 use crate::clean;
 use crate::clean::types::{
-    AttributesExt, FnDecl, FnRetTy, GenericBound, Generics, GetDefId, Type, WherePredicate,
+    FnDecl, FnRetTy, GenericBound, Generics, GetDefId, Type, WherePredicate,
 };
 use crate::formats::cache::Cache;
 use crate::formats::item_type::ItemType;
@@ -26,47 +24,6 @@ crate enum ExternalLocation {
     Unknown,
 }
 
-/// Attempts to find where an external crate is located, given that we're
-/// rendering in to the specified source destination.
-crate fn extern_location(
-    e: &clean::ExternalCrate,
-    extern_url: Option<&str>,
-    ast_attrs: &[ast::Attribute],
-    dst: &Path,
-    tcx: TyCtxt<'_>,
-) -> ExternalLocation {
-    use ExternalLocation::*;
-    // See if there's documentation generated into the local directory
-    let local_location = dst.join(&*e.name(tcx).as_str());
-    if local_location.is_dir() {
-        return Local;
-    }
-
-    if let Some(url) = extern_url {
-        let mut url = url.to_string();
-        if !url.ends_with('/') {
-            url.push('/');
-        }
-        return Remote(url);
-    }
-
-    // Failing that, see if there's an attribute specifying where to find this
-    // external crate
-    ast_attrs
-        .lists(sym::doc)
-        .filter(|a| a.has_name(sym::html_root_url))
-        .filter_map(|a| a.value_str())
-        .map(|url| {
-            let mut url = url.to_string();
-            if !url.ends_with('/') {
-                url.push('/')
-            }
-            Remote(url)
-        })
-        .next()
-        .unwrap_or(Unknown) // Well, at least we tried.
-}
-
 /// Builds the search index from the collected metadata
 crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<'tcx>) -> String {
     let mut defid_to_pathid = FxHashMap::default();
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 4c8ba0e7b496e..293c0a40fa799 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -18,7 +18,7 @@ use super::print_item::{full_path, item_path, print_item};
 use super::write_shared::write_shared;
 use super::{print_sidebar, settings, AllTypes, NameDoc, StylePath, BASIC_KEYWORDS};
 
-use crate::clean;
+use crate::clean::{self, ExternalCrate};
 use crate::config::RenderOptions;
 use crate::docfs::{DocFS, PathError};
 use crate::error::Error;
@@ -304,12 +304,16 @@ impl<'tcx> Context<'tcx> {
             }
         } else {
             let (krate, src_root) = match *self.cache.extern_locations.get(&cnum)? {
-                (name, ref src, ExternalLocation::Local) => (name, src),
-                (name, ref src, ExternalLocation::Remote(ref s)) => {
+                ExternalLocation::Local => {
+                    let e = ExternalCrate { crate_num: cnum };
+                    (e.name(self.tcx()), e.src_root(self.tcx()))
+                }
+                ExternalLocation::Remote(ref s) => {
                     root = s.to_string();
-                    (name, src)
+                    let e = ExternalCrate { crate_num: cnum };
+                    (e.name(self.tcx()), e.src_root(self.tcx()))
                 }
-                (_, _, ExternalLocation::Unknown) => return None,
+                ExternalLocation::Unknown => return None,
             };
 
             sources::clean_path(&src_root, file, false, |component| {
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 95b18490641ff..e81eaca8f0e40 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -1490,27 +1490,42 @@ function hideThemeButtonState() {
     searchState.setup();
 }());
 
-function copy_path(but) {
-    var parent = but.parentElement;
-    var path = [];
+(function () {
+    var reset_button_timeout = null;
 
-    onEach(parent.childNodes, function(child) {
-        if (child.tagName === 'A') {
-            path.push(child.textContent);
-        }
-    });
+    window.copy_path = function(but) {
+        var parent = but.parentElement;
+        var path = [];
 
-    var el = document.createElement('textarea');
-    el.value = 'use ' + path.join('::') + ';';
-    el.setAttribute('readonly', '');
-    // To not make it appear on the screen.
-    el.style.position = 'absolute';
-    el.style.left = '-9999px';
+        onEach(parent.childNodes, function(child) {
+            if (child.tagName === 'A') {
+                path.push(child.textContent);
+            }
+        });
 
-    document.body.appendChild(el);
-    el.select();
-    document.execCommand('copy');
-    document.body.removeChild(el);
+        var el = document.createElement('textarea');
+        el.value = 'use ' + path.join('::') + ';';
+        el.setAttribute('readonly', '');
+        // To not make it appear on the screen.
+        el.style.position = 'absolute';
+        el.style.left = '-9999px';
 
-    but.textContent = '✓';
-}
+        document.body.appendChild(el);
+        el.select();
+        document.execCommand('copy');
+        document.body.removeChild(el);
+
+        but.textContent = '✓';
+
+        if (reset_button_timeout !== null) {
+            window.clearTimeout(reset_button_timeout);
+        }
+
+        function reset_button() {
+            but.textContent = '⎘';
+            reset_button_timeout = null;
+        }
+
+        reset_button_timeout = window.setTimeout(reset_button, 1000);
+    };
+}());
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index 96ea4b6c3b8c1..ae4d1be3ec2b8 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -17,7 +17,7 @@ use rustc_session::Session;
 
 use rustdoc_json_types as types;
 
-use crate::clean;
+use crate::clean::{self, ExternalCrate};
 use crate::config::RenderOptions;
 use crate::error::Error;
 use crate::formats::cache::Cache;
@@ -218,12 +218,13 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
                 .cache
                 .extern_locations
                 .iter()
-                .map(|(k, v)| {
+                .map(|(crate_num, external_location)| {
+                    let e = ExternalCrate { crate_num: *crate_num };
                     (
-                        k.as_u32(),
+                        crate_num.as_u32(),
                         types::ExternalCrate {
-                            name: v.0.to_string(),
-                            html_root_url: match &v.2 {
+                            name: e.name(self.tcx).to_string(),
+                            html_root_url: match external_location {
                                 ExternalLocation::Remote(s) => Some(s.clone()),
                                 _ => None,
                             },
diff --git a/src/test/ui/or-patterns/macro-pat.rs b/src/test/ui/or-patterns/macro-pat.rs
index 8c581b630dece..20d8f84c24743 100644
--- a/src/test/ui/or-patterns/macro-pat.rs
+++ b/src/test/ui/or-patterns/macro-pat.rs
@@ -1,10 +1,9 @@
 // run-pass
 // edition:2021
-// ignore-test
-// FIXME(mark-i-m): enable this test again when 2021 machinery is available
 
 use Foo::*;
 
+#[allow(dead_code)]
 #[derive(Eq, PartialEq, Debug)]
 enum Foo {
     A(u64),
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs b/src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs
index f0ce7597aeed1..c0d148d92042f 100644
--- a/src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass-2021.rs
@@ -1,9 +1,7 @@
 // Tests that :pat in macros in edition 2021 allows top-level or-patterns.
 
 // run-pass
-// ignore-test
 // edition:2021
-// FIXME(mark-i-m): unignore when 2021 machinery is in place.
 
 macro_rules! accept_pat {
     ($p:pat) => {};
diff --git a/src/tools/miri b/src/tools/miri
index 5faf5a5ca059f..41f3fe64317a6 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit 5faf5a5ca059f6eb067fc86e47480f5668ac6e8c
+Subproject commit 41f3fe64317a6ef144d2ac33e4e5870d894d6038