summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/AArch64/AArch64.td5
-rw-r--r--llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp17
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstrInfo.cpp3
-rw-r--r--llvm/lib/Target/AArch64/AArch64MCInstLower.cpp2
-rw-r--r--llvm/lib/Target/AArch64/AArch64Subtarget.cpp7
-rw-r--r--llvm/lib/Target/AArch64/AArch64Subtarget.h1
-rw-r--r--llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h8
7 files changed, 42 insertions, 1 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index 57e4b329ded..c55fc24105f 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -355,6 +355,11 @@ def FeatureETE : SubtargetFeature<"ete", "HasETE",
def FeatureTME : SubtargetFeature<"tme", "HasTME",
"true", "Enable Transactional Memory Extension" >;
+def FeatureTaggedGlobals : SubtargetFeature<"tagged-globals",
+ "AllowTaggedGlobals",
+ "true", "Use an instruction sequence for taking the address of a global "
+ "that allows a memory tag in the upper address bits">;
+
//===----------------------------------------------------------------------===//
// Architectures.
//
diff --git a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
index 210c10eb184..ea90cb8236d 100644
--- a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
@@ -539,6 +539,23 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ADRP), DstReg)
.add(MI.getOperand(1));
+ if (MI.getOperand(1).getTargetFlags() & AArch64II::MO_TAGGED) {
+ // MO_TAGGED on the page indicates a tagged address. Set the tag now.
+ // We do so by creating a MOVK that sets bits 48-63 of the register to
+ // (global address + 0x100000000 - PC) >> 48. This assumes that we're in
+ // the small code model so we can assume a binary size of <= 4GB, which
+ // makes the untagged PC relative offset positive. The binary must also be
+ // loaded into address range [0, 2^48). Both of these properties need to
+ // be ensured at runtime when using tagged addresses.
+ auto Tag = MI.getOperand(1);
+ Tag.setTargetFlags(AArch64II::MO_PREL | AArch64II::MO_G3);
+ Tag.setOffset(0x100000000);
+ BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::MOVKXi), DstReg)
+ .addReg(DstReg)
+ .add(Tag)
+ .addImm(48);
+ }
+
MachineInstrBuilder MIB2 =
BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::ADDXri))
.add(MI.getOperand(0))
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index 4edd25b46c3..5d7385c4e70 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -4739,7 +4739,8 @@ AArch64InstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
{MO_COFFSTUB, "aarch64-coffstub"},
{MO_GOT, "aarch64-got"}, {MO_NC, "aarch64-nc"},
{MO_S, "aarch64-s"}, {MO_TLS, "aarch64-tls"},
- {MO_DLLIMPORT, "aarch64-dllimport"}};
+ {MO_DLLIMPORT, "aarch64-dllimport"},
+ {MO_PREL, "aarch64-prel"}};
return makeArrayRef(TargetFlags);
}
diff --git a/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp b/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp
index e7d4a2789a2..afd5ae6bcbf 100644
--- a/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MCInstLower.cpp
@@ -148,6 +148,8 @@ MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO,
RefFlags |= AArch64MCExpr::VK_TLSDESC;
break;
}
+ } else if (MO.getTargetFlags() & AArch64II::MO_PREL) {
+ RefFlags |= AArch64MCExpr::VK_PREL;
} else {
// No modifier means this is a generic reference, classified as absolute for
// the cases where it matters (:abs_g0: etc).
diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.cpp b/llvm/lib/Target/AArch64/AArch64Subtarget.cpp
index 6a45b4e57d7..fb82b264706 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.cpp
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.cpp
@@ -229,6 +229,13 @@ AArch64Subtarget::ClassifyGlobalReference(const GlobalValue *GV,
GV->hasExternalWeakLinkage())
return AArch64II::MO_GOT;
+ // References to tagged globals are marked with MO_NC | MO_TAGGED to indicate
+ // that their nominal addresses are tagged and outside of the code model. In
+ // AArch64ExpandPseudo::expandMI we emit an additional instruction to set the
+ // tag if necessary based on MO_TAGGED.
+ if (AllowTaggedGlobals && !isa<FunctionType>(GV->getValueType()))
+ return AArch64II::MO_NC | AArch64II::MO_TAGGED;
+
return AArch64II::MO_NO_FLAG;
}
diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h
index 3bd1ad0e60f..bf976b0abc2 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.h
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h
@@ -191,6 +191,7 @@ protected:
bool UseEL1ForTP = false;
bool UseEL2ForTP = false;
bool UseEL3ForTP = false;
+ bool AllowTaggedGlobals = false;
uint8_t MaxInterleaveFactor = 2;
uint8_t VectorInsertExtractBaseCost = 3;
uint16_t CacheLineSize = 0;
diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
index e5e2fc2cb0d..0545329a583 100644
--- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
+++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h
@@ -627,6 +627,14 @@ namespace AArch64II {
/// MO_S - Indicates that the bits of the symbol operand represented by
/// MO_G0 etc are signed.
MO_S = 0x100,
+
+ /// MO_PREL - Indicates that the bits of the symbol operand represented by
+ /// MO_G0 etc are PC relative.
+ MO_PREL = 0x200,
+
+ /// MO_TAGGED - With MO_PAGE, indicates that the page includes a memory tag
+ /// in bits 56-63.
+ MO_TAGGED = 0x400,
};
} // end namespace AArch64II
OpenPOWER on IntegriCloud