diff --git a/llvm/include/llvm/ADT/Triple.h b/llvm/include/llvm/ADT/Triple.h --- a/llvm/include/llvm/ADT/Triple.h +++ b/llvm/include/llvm/ADT/Triple.h @@ -142,6 +142,7 @@ ARMSubArch_v4t, AArch64SubArch_arm64e, + AArch64SubArch_arm64ec, KalimbaSubArch_v3, KalimbaSubArch_v4, @@ -583,6 +584,12 @@ (isOSWindows() && getEnvironment() == Triple::UnknownEnvironment); } + // Checks if we're using the Windows Arm64EC ABI. + bool isWindowsArm64EC() const { + return getArch() == Triple::aarch64 && + getSubArch() == Triple::AArch64SubArch_arm64ec; + } + bool isWindowsCoreCLREnvironment() const { return isOSWindows() && getEnvironment() == Triple::CoreCLR; } diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp --- a/llvm/lib/Support/Triple.cpp +++ b/llvm/lib/Support/Triple.cpp @@ -458,6 +458,7 @@ .Case("arm64", Triple::aarch64) .Case("arm64_32", Triple::aarch64_32) .Case("arm64e", Triple::aarch64) + .Case("arm64ec", Triple::aarch64) .Case("arm", Triple::arm) .Case("armeb", Triple::armeb) .Case("thumb", Triple::thumb) @@ -656,6 +657,9 @@ if (SubArchName == "arm64e") return Triple::AArch64SubArch_arm64e; + if (SubArchName == "arm64ec") + return Triple::AArch64SubArch_arm64ec; + if (SubArchName.startswith("spirv")) return StringSwitch(SubArchName) .EndsWith("v1.0", Triple::SPIRVSubArch_v10) diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -745,7 +745,7 @@ std::unique_ptr createObjectTargetWriter() const override { - return createAArch64WinCOFFObjectWriter(); + return createAArch64WinCOFFObjectWriter(TheTriple); } }; } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.h @@ -33,6 +33,7 @@ class MCTargetOptions; class MCTargetStreamer; class Target; +class Triple; MCCodeEmitter *createAArch64MCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx); @@ -52,7 +53,8 @@ createAArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype, bool IsILP32); -std::unique_ptr createAArch64WinCOFFObjectWriter(); +std::unique_ptr +createAArch64WinCOFFObjectWriter(const Triple &TheTriple); MCTargetStreamer *createAArch64AsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS, diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp @@ -30,8 +30,10 @@ class AArch64WinCOFFObjectWriter : public MCWinCOFFObjectTargetWriter { public: - AArch64WinCOFFObjectWriter() - : MCWinCOFFObjectTargetWriter(COFF::IMAGE_FILE_MACHINE_ARM64) {} + AArch64WinCOFFObjectWriter(const Triple &TheTriple) + : MCWinCOFFObjectTargetWriter(TheTriple.isWindowsArm64EC() + ? COFF::IMAGE_FILE_MACHINE_ARM64EC + : COFF::IMAGE_FILE_MACHINE_ARM64) {} ~AArch64WinCOFFObjectWriter() override = default; @@ -159,6 +161,7 @@ return true; } -std::unique_ptr llvm::createAArch64WinCOFFObjectWriter() { - return std::make_unique(); +std::unique_ptr +llvm::createAArch64WinCOFFObjectWriter(const Triple &TheTriple) { + return std::make_unique(TheTriple); } diff --git a/llvm/test/MC/AArch64/arm64ec.s b/llvm/test/MC/AArch64/arm64ec.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/arm64ec.s @@ -0,0 +1,4 @@ +// RUN: llvm-mc -triple arm64ec-pc-windows-msvc_arm64ec -filetype=obj %s -o - | llvm-objdump -d -r - | FileCheck %s +// CHECK: file format coff-arm64ec +// CHECK: add x0, x1, x2 +add x0, x1, x2