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
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
@@ -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()) {
5 changes: 3 additions & 2 deletions llvm/lib/IR/Mangler.cpp
Original file line number Diff line number Diff line change
@@ -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);
@@ -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";
4 changes: 1 addition & 3 deletions llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
Original file line number Diff line number Diff line change
@@ -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);
7 changes: 6 additions & 1 deletion llvm/lib/Target/X86/X86CallingConv.td
Original file line number Diff line number Diff line change
@@ -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.
@@ -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>
]>;
@@ -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>
14 changes: 7 additions & 7 deletions llvm/lib/Target/X86/X86ISelLowering.cpp
Original file line number Diff line number Diff line change
@@ -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);
}
@@ -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) +
@@ -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 {
@@ -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;

@@ -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 "";

9 changes: 5 additions & 4 deletions llvm/lib/Target/X86/X86RegisterInfo.cpp
Original file line number Diff line number Diff line change
@@ -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;
@@ -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 {
@@ -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;
6 changes: 5 additions & 1 deletion llvm/lib/Target/X86/X86RegisterInfo.h
Original file line number Diff line number Diff line change
@@ -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;
14 changes: 11 additions & 3 deletions llvm/lib/Target/X86/X86Subtarget.h
Original file line number Diff line number Diff line change
@@ -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(); }

@@ -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:
1 change: 1 addition & 0 deletions llvm/test/CodeGen/X86/mangle-question-mark.ll
Original file line number Diff line number Diff line change
@@ -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

2 changes: 2 additions & 0 deletions llvm/test/CodeGen/X86/win32-preemption.ll
Original file line number Diff line number Diff line change
@@ -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