diff --git a/llvm/lib/Target/X86/X86CallingConv.td b/llvm/lib/Target/X86/X86CallingConv.td index 0d087e057a2bd..215906d9df8b3 100644 --- a/llvm/lib/Target/X86/X86CallingConv.td +++ b/llvm/lib/Target/X86/X86CallingConv.td @@ -283,8 +283,10 @@ def RetCC_X86Common : CallingConv<[ CCAssignToReg<[ZMM0,ZMM1,ZMM2,ZMM3]>>, // Long double types are always returned in FP0 (even with SSE), - // except on Win64. - CCIfNotSubtarget<"isTargetWin64()", CCIfType<[f80], CCAssignToReg<[FP0, FP1]>>> + // except on Win64 and UEFI64. + CCIfNotSubtarget<"isTargetWin64()", + CCIfNotSubtarget<"isTargetUEFI64()", + CCIfType<[f80], CCAssignToReg<[FP0, FP1]>>>> ]>; // X86-32 C return-value convention. @@ -495,6 +497,9 @@ def RetCC_X86_64 : CallingConv<[ // Mingw64 and native Win64 use Win64 CC CCIfSubtarget<"isTargetWin64()", CCDelegateTo>, + // UEFI64 uses Win64 CC + CCIfSubtarget<"isTargetUEFI64()", CCDelegateTo>, + // Otherwise, drop to normal X86-64 CC CCDelegateTo ]>; @@ -1085,6 +1090,9 @@ def CC_X86_64 : CallingConv<[ // Mingw64 and native Win64 use Win64 CC CCIfSubtarget<"isTargetWin64()", CCDelegateTo>, + // UEFI uses Win64 CC + CCIfSubtarget<"isTargetUEFI64()", CCDelegateTo>, + // Otherwise, drop to normal X86-64 CC CCDelegateTo ]>; diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp index 29242c7059d5f..ef58c7619b243 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp @@ -60,6 +60,7 @@ X86RegisterInfo::X86RegisterInfo(const Triple &TT) // Cache some information. Is64Bit = TT.isArch64Bit(); IsWin64 = Is64Bit && TT.isOSWindows(); + IsUEFI64 = Is64Bit && TT.isUEFI(); // Use a callee-saved register as the base pointer. These registers must // not conflict with any ABI requirements. For example, in 32-bit mode PIC @@ -227,7 +228,7 @@ X86RegisterInfo::getPointerRegClass(const MachineFunction &MF, const TargetRegisterClass * X86RegisterInfo::getGPRsForTailCall(const MachineFunction &MF) const { const Function &F = MF.getFunction(); - if (IsWin64 || (F.getCallingConv() == CallingConv::Win64)) + if (IsWin64 || IsUEFI64 || (F.getCallingConv() == CallingConv::Win64)) return &X86::GR64_TCW64RegClass; else if (Is64Bit) return &X86::GR64_TCRegClass; @@ -389,7 +390,7 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { return IsWin64 ? CSR_Win64_SwiftError_SaveList : CSR_64_SwiftError_SaveList; - if (IsWin64) + if (IsWin64 || IsUEFI64) return HasSSE ? CSR_Win64_SaveList : CSR_Win64_NoSSE_SaveList; if (CallsEHReturn) return CSR_64EHRet_SaveList; @@ -514,7 +515,7 @@ X86RegisterInfo::getCallPreservedMask(const MachineFunction &MF, if (IsSwiftCC) return IsWin64 ? CSR_Win64_SwiftError_RegMask : CSR_64_SwiftError_RegMask; - return IsWin64 ? CSR_Win64_RegMask : CSR_64_RegMask; + return (IsWin64 || IsUEFI64) ? CSR_Win64_RegMask : CSR_64_RegMask; } return CSR_32_RegMask; diff --git a/llvm/lib/Target/X86/X86RegisterInfo.h b/llvm/lib/Target/X86/X86RegisterInfo.h index b3c03e8f2bc22..13a5fbf16e981 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.h +++ b/llvm/lib/Target/X86/X86RegisterInfo.h @@ -31,6 +31,10 @@ class X86RegisterInfo final : public X86GenRegisterInfo { /// bool IsWin64; + /// IsUEFI64 - Is UEFI 64 bit target. + /// + bool IsUEFI64; + /// SlotSize - Stack slot size in bytes. /// unsigned SlotSize; diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index e0dd3565605b9..a0b182d3f4c9b 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -352,6 +352,7 @@ class X86Subtarget final : public X86GenSubtargetInfo { switch (CC) { // On Win64, all these conventions just use the default convention. case CallingConv::C: + return isTargetWin64() || isTargetUEFI64(); case CallingConv::Fast: case CallingConv::Tail: case CallingConv::Swift: