Skip to content

UEFI backend for x86_64 #109320

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4096,7 +4096,8 @@ const MCExpr *AsmPrinter::lowerBlockAddressConstant(const BlockAddress &BA) {

/// GetCPISymbol - Return the symbol for the specified constant pool entry.
MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const {
if (getSubtargetInfo().getTargetTriple().isWindowsMSVCEnvironment()) {
if (getSubtargetInfo().getTargetTriple().isWindowsMSVCEnvironment() ||
getSubtargetInfo().getTargetTriple().isUEFI()) {
const MachineConstantPoolEntry &CPE =
MF->getConstantPool()->getConstants()[CPID];
if (!CPE.isMachineConstantPoolEntry()) {
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/IR/Mangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ void llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
bool NeedQuotes = GV->hasName() && !canBeUnquotedInDirective(GV->getName());
if (NeedQuotes)
OS << "\"";
if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment() ||
TT.isUEFI()) {
std::string Flag;
raw_string_ostream FlagOS(Flag);
Mangler.getNameWithPrefix(FlagOS, GV, false);
Expand All @@ -249,7 +250,7 @@ void llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
OS << "\"";

if (!GV->getValueType()->isFunctionTy()) {
if (TT.isWindowsMSVCEnvironment())
if (TT.isWindowsMSVCEnvironment() || TT.isUEFI())
OS << ",DATA";
else
OS << ",data";
Expand Down
4 changes: 1 addition & 3 deletions llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,16 +444,14 @@ static MCAsmInfo *createX86MCAsmInfo(const MCRegisterInfo &MRI,
// Force the use of an ELF container.
MAI = new X86ELFMCAsmInfo(TheTriple);
} else if (TheTriple.isWindowsMSVCEnvironment() ||
TheTriple.isWindowsCoreCLREnvironment()) {
TheTriple.isWindowsCoreCLREnvironment() || TheTriple.isUEFI()) {
if (Options.getAssemblyLanguage().equals_insensitive("masm"))
MAI = new X86MCAsmInfoMicrosoftMASM(TheTriple);
else
MAI = new X86MCAsmInfoMicrosoft(TheTriple);
} else if (TheTriple.isOSCygMing() ||
TheTriple.isWindowsItaniumEnvironment()) {
MAI = new X86MCAsmInfoGNUCOFF(TheTriple);
} else if (TheTriple.isUEFI()) {
MAI = new X86MCAsmInfoGNUCOFF(TheTriple);
} else {
// The default is ELF.
MAI = new X86ELFMCAsmInfo(TheTriple);
Expand Down
7 changes: 6 additions & 1 deletion llvm/lib/Target/X86/X86CallingConv.td
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ def RetCC_X86Common : CallingConv<[

// Long double types are always returned in FP0 (even with SSE),
// except on Win64.
CCIfNotSubtarget<"isTargetWin64()", CCIfType<[f80], CCAssignToReg<[FP0, FP1]>>>
CCIfNotSubtarget<"isTargetWindowsOrUEFI64()", CCIfType<[f80], CCAssignToReg<[FP0, FP1]>>>
]>;

// X86-32 C return-value convention.
Expand Down Expand Up @@ -495,6 +495,9 @@ def RetCC_X86_64 : CallingConv<[
// Mingw64 and native Win64 use Win64 CC
CCIfSubtarget<"isTargetWin64()", CCDelegateTo<RetCC_X86_Win64_C>>,

// UEFI64 uses Win64 CC
CCIfSubtarget<"isTargetUEFI64()", CCDelegateTo<RetCC_X86_Win64_C>>,

// Otherwise, drop to normal X86-64 CC
CCDelegateTo<RetCC_X86_64_C>
]>;
Expand Down Expand Up @@ -1084,6 +1087,8 @@ def CC_X86_64 : CallingConv<[

// Mingw64 and native Win64 use Win64 CC
CCIfSubtarget<"isTargetWin64()", CCDelegateTo<CC_X86_Win64_C>>,
// UEFI uses Win64 CC
CCIfSubtarget<"isTargetUEFI64()", CCDelegateTo<CC_X86_Win64_C>>,

// Otherwise, drop to normal X86-64 CC
CCDelegateTo<CC_X86_64_C>
Expand Down
14 changes: 7 additions & 7 deletions llvm/lib/Target/X86/X86ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
// FIXME - use subtarget debug flags
if (!Subtarget.isTargetDarwin() && !Subtarget.isTargetELF() &&
!Subtarget.isTargetCygMing() && !Subtarget.isTargetWin64() &&
!Subtarget.isTargetUEFI64() &&
TM.Options.ExceptionModel != ExceptionHandling::SjLj) {
setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
}
Expand Down Expand Up @@ -28087,7 +28088,6 @@ Register X86TargetLowering::getRegisterByName(const char* RegName, LLT VT,
.Case("r14", X86::R14)
.Case("r15", X86::R15)
.Default(0);

if (Reg == X86::EBP || Reg == X86::RBP) {
if (!TFI.hasFP(MF))
report_fatal_error("register " + StringRef(RegName) +
Expand Down Expand Up @@ -28131,7 +28131,7 @@ Register X86TargetLowering::getExceptionSelectorRegister(
}

bool X86TargetLowering::needsFixedCatchObjects() const {
return Subtarget.isTargetWin64();
return Subtarget.isTargetWin64() || Subtarget.isTargetUEFI64();
}

SDValue X86TargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const {
Expand Down Expand Up @@ -61613,8 +61613,8 @@ bool X86TargetLowering::hasStackProbeSymbol(const MachineFunction &MF) const {
/// Returns true if stack probing through inline assembly is requested.
bool X86TargetLowering::hasInlineStackProbe(const MachineFunction &MF) const {

// No inline stack probe for Windows, they have their own mechanism.
if (Subtarget.isOSWindows() ||
// No inline stack probe for Windows and UEFI, they have their own mechanism.
if (Subtarget.isOSWindowsOrUEFI() ||
MF.getFunction().hasFnAttribute("no-stack-arg-probe"))
return false;

Expand All @@ -61638,9 +61638,9 @@ X86TargetLowering::getStackProbeSymbolName(const MachineFunction &MF) const {
if (MF.getFunction().hasFnAttribute("probe-stack"))
return MF.getFunction().getFnAttribute("probe-stack").getValueAsString();

// Generally, if we aren't on Windows, the platform ABI does not include
// support for stack probes, so don't emit them.
if (!Subtarget.isOSWindows() || Subtarget.isTargetMachO() ||
// Generally, if we aren't on Windows or UEFI, the platform ABI does not
// include support for stack probes, so don't emit them.
if (!(Subtarget.isOSWindowsOrUEFI()) || Subtarget.isTargetMachO() ||
MF.getFunction().hasFnAttribute("no-stack-arg-probe"))
return "";

Expand Down
9 changes: 5 additions & 4 deletions llvm/lib/Target/X86/X86RegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -456,7 +457,7 @@ X86RegisterInfo::getCallPreservedMask(const MachineFunction &MF,
}
case CallingConv::X86_RegCall:
if (Is64Bit) {
if (IsWin64) {
if (IsWin64 || IsUEFI64) {
return (HasSSE ? CSR_Win64_RegCall_RegMask :
CSR_Win64_RegCall_NoSSE_RegMask);
} else {
Expand Down Expand Up @@ -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;
Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/Target/X86/X86RegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@ class X86RegisterInfo final : public X86GenRegisterInfo {
///
bool Is64Bit;

/// IsWin64 - Is the target on of win64 flavours
/// IsWin64 - Is the target one of win64 flavours
///
bool IsWin64;

/// IsUEFI64 - Is this UEFI 64 bit target
///
bool IsUEFI64;

/// SlotSize - Stack slot size in bytes.
///
unsigned SlotSize;
Expand Down
14 changes: 11 additions & 3 deletions llvm/lib/Target/X86/X86Subtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,11 +327,17 @@ class X86Subtarget final : public X86GenSubtargetInfo {

bool isTargetCygMing() const { return TargetTriple.isOSCygMing(); }

bool isOSWindows() const { return TargetTriple.isOSWindows(); }

bool isUEFI() const { return TargetTriple.isUEFI(); }

bool isOSWindows() const { return TargetTriple.isOSWindows(); }
bool isOSWindowsOrUEFI() const { return TargetTriple.isOSWindowsOrUEFI(); }

bool isTargetWindowsOrUEFI64() const {
return isTargetWin64() || isTargetUEFI64();
}

bool isOSWindowsOrUEFI() const { return isOSWindows() || isUEFI(); }
bool isTargetUEFI64() const { return Is64Bit && isUEFI(); }

bool isTargetWin64() const { return Is64Bit && isOSWindows(); }

Expand All @@ -348,8 +354,10 @@ class X86Subtarget final : public X86GenSubtargetInfo {

bool isCallingConvWin64(CallingConv::ID CC) const {
switch (CC) {
// On Win64, all these conventions just use the default convention.
// On Win64 and UEFI64, all these conventions just use the default
// convention.
case CallingConv::C:
return isTargetWin64() || isTargetUEFI64();
case CallingConv::Fast:
case CallingConv::Tail:
case CallingConv::Swift:
Expand Down
1 change: 1 addition & 0 deletions llvm/test/CodeGen/X86/mangle-question-mark.ll
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

; RUN: llc -mtriple i686-pc-win32 < %s | FileCheck %s --check-prefix=COFF
; RUN: llc -mtriple x86_64-pc-win32 < %s | FileCheck %s --check-prefix=COFF64
; RUN: llc -mtriple x86_64-unknown-uefi < %s | FileCheck %s --check-prefix=COFF64
; RUN: llc -mtriple i686-linux-gnu < %s | FileCheck %s --check-prefix=ELF
; RUN: llc -mtriple i686-apple-darwin < %s | FileCheck %s --check-prefix=MACHO

Expand Down
2 changes: 2 additions & 0 deletions llvm/test/CodeGen/X86/win32-preemption.ll
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
; RUN: -relocation-model=pic < %s | FileCheck --check-prefix=COFF %s
; RUN: llc -mtriple x86_64-pc-win32 \
; RUN: -relocation-model=dynamic-no-pic < %s | FileCheck --check-prefix=COFF %s
; RUN: llc -mtriple x86_64-unknown-uefi \
; RUN: -relocation-model=dynamic-no-pic < %s | FileCheck --check-prefix=COFF %s


; 32 bits
Expand Down