diff --git a/Cargo.lock b/Cargo.lock
index cf5425a5a89..00351c12410 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6332,9 +6332,9 @@ dependencies = [
 
 [[package]]
 name = "windows-bindgen"
-version = "0.55.0"
+version = "0.56.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "073ff8a486ebad239d557809d2cd5fe5e04ee1de29e09c6cd83fb0bae19b8a4c"
+checksum = "a28e3ea6330cf17fdcdce8bf08d0549ce93769dca9bedc6c39c36c8c0e17db46"
 dependencies = [
  "proc-macro2",
  "rayon",
@@ -6355,9 +6355,9 @@ dependencies = [
 
 [[package]]
 name = "windows-metadata"
-version = "0.55.0"
+version = "0.56.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b602635050172a1fc57a35040d4d225baefc6098fefd97094919921d95961a7d"
+checksum = "3993f7827fff10c454e3a24847075598c7c08108304b8b07943c2c73d78f3b34"
 
 [[package]]
 name = "windows-sys"
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index 0619000364b..d4a3e39cef7 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -415,6 +415,7 @@ impl<'a> LlvmArchiveBuilder<'a> {
                 members.as_ptr() as *const &_,
                 true,
                 kind,
+                self.sess.target.arch == "arm64ec",
             );
             let ret = if r.into_result().is_err() {
                 let err = llvm::LLVMRustGetLastError();
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 5509baaa3e9..83158f6f1d5 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2303,6 +2303,7 @@ extern "C" {
         Members: *const &RustArchiveMember<'_>,
         WriteSymbtab: bool,
         Kind: ArchiveKind,
+        isEC: bool,
     ) -> LLVMRustResult;
     pub fn LLVMRustArchiveMemberNew<'a>(
         Filename: *const c_char,
diff --git a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
index 64e6c18092f..8871f410e36 100644
--- a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
@@ -175,7 +175,7 @@ extern "C" void LLVMRustArchiveMemberFree(LLVMRustArchiveMemberRef Member) {
 extern "C" LLVMRustResult
 LLVMRustWriteArchive(char *Dst, size_t NumMembers,
                      const LLVMRustArchiveMemberRef *NewMembers,
-                     bool WriteSymbtab, LLVMRustArchiveKind RustKind) {
+                     bool WriteSymbtab, LLVMRustArchiveKind RustKind, bool isEC) {
 
   std::vector<NewArchiveMember> Members;
   auto Kind = fromRust(RustKind);
@@ -207,7 +207,7 @@ LLVMRustWriteArchive(char *Dst, size_t NumMembers,
   auto Result = writeArchive(Dst, Members, WriteSymbtab, Kind, true, false);
 #else
   auto SymtabMode = WriteSymbtab ? SymtabWritingMode::NormalSymtab : SymtabWritingMode::NoSymtab;
-  auto Result = writeArchive(Dst, Members, SymtabMode, Kind, true, false);
+  auto Result = writeArchive(Dst, Members, SymtabMode, Kind, true, false, nullptr, isEC);
 #endif
   if (!Result)
     return LLVMRustResult::Success;
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index b27d0db4619..6e2d88c6b83 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -237,7 +237,7 @@ pub fn spin_loop() {
         crate::arch::riscv64::pause();
     }
 
-    #[cfg(target_arch = "aarch64")]
+    #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]
     {
         // SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets.
         unsafe { crate::arch::aarch64::__isb(crate::arch::aarch64::SY) };
diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs
index a6d07fd1984..353de8c5c57 100644
--- a/library/panic_abort/src/lib.rs
+++ b/library/panic_abort/src/lib.rs
@@ -8,6 +8,7 @@
 #![doc(issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")]
 #![panic_runtime]
 #![allow(unused_features)]
+#![feature(asm_experimental_arch)]
 #![feature(core_intrinsics)]
 #![feature(panic_runtime)]
 #![feature(std_internals)]
@@ -78,7 +79,7 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn PanicPayload) -> u32 {
                         core::arch::asm!("int $$0x29", in("ecx") FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
                     } else if #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))] {
                         core::arch::asm!(".inst 0xDEFB", in("r0") FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
-                    } else if #[cfg(target_arch = "aarch64")] {
+                    } else if #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] {
                         core::arch::asm!("brk 0xF003", in("x0") FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
                     } else {
                         core::intrinsics::abort();
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index d152626d86a..241a443fab9 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -277,6 +277,7 @@
 #![feature(allocator_internals)]
 #![feature(allow_internal_unsafe)]
 #![feature(allow_internal_unstable)]
+#![feature(asm_experimental_arch)]
 #![feature(c_unwind)]
 #![feature(cfg_sanitizer_cfi)]
 #![feature(cfg_target_thread_local)]
diff --git a/library/std/src/sys/pal/common/alloc.rs b/library/std/src/sys/pal/common/alloc.rs
index 8cf9ef68047..598b6db71f5 100644
--- a/library/std/src/sys/pal/common/alloc.rs
+++ b/library/std/src/sys/pal/common/alloc.rs
@@ -23,6 +23,7 @@ pub const MIN_ALIGN: usize = 8;
 #[cfg(any(
     target_arch = "x86_64",
     target_arch = "aarch64",
+    target_arch = "arm64ec",
     target_arch = "loongarch64",
     target_arch = "mips64",
     target_arch = "mips64r6",
diff --git a/library/std/src/sys/pal/windows/c/windows_sys.rs b/library/std/src/sys/pal/windows/c/windows_sys.rs
index d180122d735..1da8871ae44 100644
--- a/library/std/src/sys/pal/windows/c/windows_sys.rs
+++ b/library/std/src/sys/pal/windows/c/windows_sys.rs
@@ -1,4 +1,4 @@
-// Bindings generated by `windows-bindgen` 0.55.0
+// Bindings generated by `windows-bindgen` 0.56.0
 
 #![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]
 #[link(name = "advapi32")]
@@ -345,7 +345,7 @@ extern "system" {
 }
 #[link(name = "kernel32")]
 extern "system" {
-    pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME) -> ();
+    pub fn GetSystemTimePreciseAsFileTime(lpsystemtimeasfiletime: *mut FILETIME);
 }
 #[link(name = "kernel32")]
 extern "system" {
@@ -1018,7 +1018,7 @@ impl Clone for CONTEXT_0_0 {
     }
 }
 #[repr(C)]
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
 pub struct CONTEXT {
     pub P1Home: u64,
     pub P2Home: u64,
@@ -1067,30 +1067,30 @@ pub struct CONTEXT {
     pub LastExceptionToRip: u64,
     pub LastExceptionFromRip: u64,
 }
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
 impl Copy for CONTEXT {}
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
 impl Clone for CONTEXT {
     fn clone(&self) -> Self {
         *self
     }
 }
 #[repr(C)]
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
 pub union CONTEXT_0 {
     pub FltSave: XSAVE_FORMAT,
     pub Anonymous: CONTEXT_0_0,
 }
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
 impl Copy for CONTEXT_0 {}
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
 impl Clone for CONTEXT_0 {
     fn clone(&self) -> Self {
         *self
     }
 }
 #[repr(C)]
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
 pub struct CONTEXT_0_0 {
     pub Header: [M128A; 2],
     pub Legacy: [M128A; 8],
@@ -1111,9 +1111,9 @@ pub struct CONTEXT_0_0 {
     pub Xmm14: M128A,
     pub Xmm15: M128A,
 }
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
 impl Copy for CONTEXT_0_0 {}
-#[cfg(target_arch = "x86_64")]
+#[cfg(any(target_arch = "arm64ec", target_arch = "x86_64"))]
 impl Clone for CONTEXT_0_0 {
     fn clone(&self) -> Self {
         *self
@@ -3339,7 +3339,7 @@ pub const FILE_WRITE_EA: FILE_ACCESS_RIGHTS = 16u32;
 pub const FILE_WRITE_THROUGH: NTCREATEFILE_CREATE_OPTIONS = 2u32;
 pub const FIONBIO: i32 = -2147195266i32;
 #[repr(C)]
-#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
 pub struct FLOATING_SAVE_AREA {
     pub ControlWord: u32,
     pub StatusWord: u32,
@@ -3351,9 +3351,9 @@ pub struct FLOATING_SAVE_AREA {
     pub RegisterArea: [u8; 80],
     pub Cr0NpxState: u32,
 }
-#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
 impl Copy for FLOATING_SAVE_AREA {}
-#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
 impl Clone for FLOATING_SAVE_AREA {
     fn clone(&self) -> Self {
         *self
@@ -4106,7 +4106,7 @@ impl Clone for WSABUF {
     }
 }
 #[repr(C)]
-#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
 pub struct WSADATA {
     pub wVersion: u16,
     pub wHighVersion: u16,
@@ -4116,9 +4116,9 @@ pub struct WSADATA {
     pub szDescription: [i8; 257],
     pub szSystemStatus: [i8; 129],
 }
-#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
 impl Copy for WSADATA {}
-#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
 impl Clone for WSADATA {
     fn clone(&self) -> Self {
         *self
@@ -4286,7 +4286,7 @@ pub const WSA_SECURE_HOST_NOT_FOUND: WSA_ERROR = 11032i32;
 pub const WSA_WAIT_EVENT_0: WSA_ERROR = 0i32;
 pub const WSA_WAIT_IO_COMPLETION: WSA_ERROR = 192i32;
 #[repr(C)]
-#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
 pub struct XSAVE_FORMAT {
     pub ControlWord: u16,
     pub StatusWord: u16,
@@ -4305,9 +4305,9 @@ pub struct XSAVE_FORMAT {
     pub XmmRegisters: [M128A; 16],
     pub Reserved4: [u8; 96],
 }
-#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
 impl Copy for XSAVE_FORMAT {}
-#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
+#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_arch = "x86_64"))]
 impl Clone for XSAVE_FORMAT {
     fn clone(&self) -> Self {
         *self
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index a734c2bd4c7..b49585599cb 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -332,7 +332,7 @@ pub fn abort_internal() -> ! {
                 core::arch::asm!("int $$0x29", in("ecx") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
             } else if #[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))] {
                 core::arch::asm!(".inst 0xDEFB", in("r0") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
-            } else if #[cfg(target_arch = "aarch64")] {
+            } else if #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] {
                 core::arch::asm!("brk 0xF003", in("x0") c::FAST_FAIL_FATAL_APP_EXIT, options(noreturn, nostack));
             } else {
                 core::intrinsics::abort();
diff --git a/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md b/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md
index 1bb2c677b08..9fd0ac49881 100644
--- a/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md
+++ b/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md
@@ -11,48 +11,69 @@ applications on AArch64 Windows 11. See <https://learn.microsoft.com/en-us/windo
 
 ## Requirements
 
-Target only supports cross-compilation, `core` and `alloc` are supported but
-`std` is not.
-
 Builds Arm64EC static and dynamic libraries and executables which can be run on
 AArch64 Windows 11 devices. Arm64EC static libraries can also be linked into
 Arm64X dynamic libraries and executables.
 
-Uses `arm64ec` as its `target_arch` - code built for Arm64EC must be compatible
-with x86_64 code (e.g., same structure layouts, function signatures, etc.) but
-use AArch64 intrinsics.
+Only supported backend is LLVM 18 or above:
+* 18.1.0 added initial support for Arm64EC.
+* 18.1.2 fixed import library generation (required for `raw-dylib` support).
+* 18.1.4 fixed linking issue for some intrinsics implemented in
+  `compiler_builtins`.
 
-Only supported backend is LLVM 18 (or above).
+### Reusing code from other architectures - x86_64 or AArch64?
+
+Arm64EC uses `arm64ec` as its `target_arch`, but it is possible to reuse
+existing architecture-specific code in most cases. The best mental model for
+deciding which architecture to reuse is to is to think of Arm64EC as an x86_64
+process that happens to use the AArch64 instruction set (with some caveats) and
+has a completely custom ABI.
+
+To put this in practice:
+* Arm64EC interacts with the operating system, other processes and other DLLs as
+  x86_64.
+  - For example, [in `backtrace`](https://github.com/rust-lang/backtrace-rs/commit/ef39a7d7da58b4cae8c8f3fc67a8300fd8d2d0d9)
+    we use the x86_64 versions of `CONTEXT` and `RtlVirtualUnwind`.
+  - If you are configuring a search path to find DLLs (e.g., to load plugins or
+    addons into your application), you should use the same path as the x86_64
+    version of your application, not the AArch64 path (since Arm64EC (i.e.,
+    x86_64) processes cannot load native AArch64 DLLs).
+* Arm64EC uses AArch64 intrinsics.
+  - For example, <https://github.com/rust-lang/portable-simd/commit/ca4033f49b1f6019561b8b161b4097b4a07f2e1b>
+    and <https://github.com/rust-lang/stdarch/commit/166ef7ba22b6a1d908d4b29a36e68ceca324808a>.
+* Assembly for AArch64 might be reusable for Arm64EC, but there are many
+  caveats. For full details see [Microsoft's documentation on the Arm64EC ABI](https://learn.microsoft.com/en-us/windows/arm/arm64ec-abi)
+  but in brief:
+  - Arm64EC uses a subset of AArch64 registers.
+  - Arm64EC uses a different name mangling scheme than AArch64.
+  - Arm64EC requires entry and exit thunks be generated for some functions.
+  - Indirect calls must be done via a call checker.
+  - Control Flow Guard and stack checks use different functions than AArch64.
 
 ## Building the target
 
 You can build Rust with support for the targets by adding it to the `target`
-list in `config.toml` and disabling `std`:
+list in `config.toml`:
 
 ```toml
 [build]
 target = [ "arm64ec-pc-windows-msvc" ]
-
-[target.arm64ec-pc-windows-msvc]
-no-std = true
 ```
 
 ## Building Rust programs
 
 Rust does not yet ship pre-compiled artifacts for this target. To compile for
 this target, you will either need to build Rust with the target enabled (see
-"Building the target" above), or build your own copy of `core` by using
-`build-std` or similar.
+"Building the target" above), or build your own copy using `build-std` or
+similar.
 
 ## Testing
 
 Tests can be run on AArch64 Windows 11 devices.
 
-Since this is a `no_std` target, the Rust test suite is not supported.
-
 ## Cross-compilation toolchains and C code
 
-C code can be built using the Arm64-targetting MSVC toolchain.
+C code can be built using the Arm64-targetting MSVC or Clang toolchain.
 
 To compile:
 
diff --git a/src/tools/generate-windows-sys/Cargo.toml b/src/tools/generate-windows-sys/Cargo.toml
index 9ea26defdc4..8b971d6efe7 100644
--- a/src/tools/generate-windows-sys/Cargo.toml
+++ b/src/tools/generate-windows-sys/Cargo.toml
@@ -4,4 +4,4 @@ version = "0.1.0"
 edition = "2021"
 
 [dependencies.windows-bindgen]
-version = "0.55.0"
+version = "0.56.0"