[llvm] [RISCV] Support Global Dynamic TLSDESC in the RISC-V backend (PR #77515)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 9 11:17:54 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mc
Author: Paul Kirth (ilovepi)
<details>
<summary>Changes</summary>
This patch adds basic TLSDESC support for the global dynamic case in the
RISC-V backend by adding new relocation types for TLSDESC, as prescribed
in https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/373.
We also add a new pseudo instruction to simplify code generation.
Possible improvements for the local dynamic case will be addressed in separate
patches.
The current implementation is only enabled when passing the
-riscv-enable-tlsdesc flag.
---
Patch is 37.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/77515.diff
19 Files Affected:
- (modified) llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def (+4)
- (modified) llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp (+54-9)
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp (+10)
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h (+5-1)
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp (+15)
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h (+6)
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp (+47)
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp (+18)
- (modified) llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h (+4)
- (modified) llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp (+12)
- (modified) llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp (+51)
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+21-1)
- (modified) llvm/lib/Target/RISCV/RISCVISelLowering.h (+1)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.cpp (+5-1)
- (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.td (+29)
- (modified) llvm/lib/Target/RISCV/RISCVTargetMachine.cpp (+5)
- (modified) llvm/test/CodeGen/RISCV/tls-models.ll (+102)
- (modified) llvm/test/MC/RISCV/relocations.s (+21)
- (added) llvm/test/MC/RISCV/tlsdesc.s (+44)
``````````diff
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
index c7fd6490041cd1..687605f8a9b913 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
@@ -57,3 +57,7 @@ ELF_RELOC(R_RISCV_IRELATIVE, 58)
ELF_RELOC(R_RISCV_PLT32, 59)
ELF_RELOC(R_RISCV_SET_ULEB128, 60)
ELF_RELOC(R_RISCV_SUB_ULEB128, 61)
+ELF_RELOC(R_RISCV_TLSDESC_HI20, 62)
+ELF_RELOC(R_RISCV_TLSDESC_LOAD_LO12, 63)
+ELF_RELOC(R_RISCV_TLSDESC_ADD_LO12, 64)
+ELF_RELOC(R_RISCV_TLSDESC_CALL, 65)
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index d616aaeddf4114..a7eb22d8a3ef6f 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -169,6 +169,12 @@ class RISCVAsmParser : public MCTargetAsmParser {
// 'add' is an overloaded mnemonic.
bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands);
+ // Checks that a PseudoTLSDESCCall is using x5/t0 in its output operand.
+ // Enforcing this using a restricted register class for the output
+ // operand of PseudoTLSDESCCall results in a poor diagnostic due to the fact
+ // 'jalr' is an overloaded mnemonic.
+ bool checkPseudoTLSDESCCall(MCInst &Inst, OperandVector &Operands);
+
// Check instruction constraints.
bool validateInstruction(MCInst &Inst, OperandVector &Operands);
@@ -541,6 +547,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
VK == RISCVMCExpr::VK_RISCV_TPREL_ADD;
}
+ bool isTLSDESCCallSymbol() const {
+ int64_t Imm;
+ RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+ // Must be of 'immediate' type but not a constant.
+ if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
+ return false;
+ return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
+ VK == RISCVMCExpr::VK_RISCV_TLSDESC_CALL;
+ }
+
bool isCSRSystemRegister() const { return isSystemRegister(); }
bool isVTypeImm(unsigned N) const {
@@ -593,7 +609,10 @@ struct RISCVOperand final : public MCParsedAsmOperand {
if (!isImm())
return false;
bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
- if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO)
+ if (VK == RISCVMCExpr::VK_RISCV_LO ||
+ VK == RISCVMCExpr::VK_RISCV_PCREL_LO ||
+ VK == RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO ||
+ VK == RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO)
return true;
// Given only Imm, ensuring that the actually specified constant is either
// a signed or unsigned 64-bit number is unfortunately impossible.
@@ -846,7 +865,9 @@ struct RISCVOperand final : public MCParsedAsmOperand {
return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) ||
VK == RISCVMCExpr::VK_RISCV_LO ||
VK == RISCVMCExpr::VK_RISCV_PCREL_LO ||
- VK == RISCVMCExpr::VK_RISCV_TPREL_LO);
+ VK == RISCVMCExpr::VK_RISCV_TPREL_LO ||
+ VK == RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO ||
+ VK == RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO);
}
bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
@@ -903,14 +924,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
- VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI);
- } else {
- return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
- VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
- VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
- VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
- VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI);
+ VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI ||
+ VK == RISCVMCExpr::VK_RISCV_TLSDESC_HI);
}
+
+ return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
+ VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
+ VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
+ VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
+ VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI ||
+ VK == RISCVMCExpr::VK_RISCV_TLSDESC_HI);
}
bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); }
@@ -1544,6 +1567,11 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier");
}
+ case Match_InvalidTLSDESCCallSymbol: {
+ SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
+ return Error(ErrorLoc,
+ "operand must be a symbol with %tlsdesc_call modifier");
+ }
case Match_InvalidRTZArg: {
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
return Error(ErrorLoc, "operand must be 'rtz' floating-point rounding mode");
@@ -3270,6 +3298,19 @@ bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
return false;
}
+bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
+ OperandVector &Operands) {
+ assert(Inst.getOpcode() == RISCV::PseudoTLSDESCCall && "Invalid instruction");
+ assert(Inst.getOperand(0).isReg() && "Unexpected operand kind");
+ if (Inst.getOperand(0).getReg() != RISCV::X5) {
+ SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
+ return Error(ErrorLoc, "the output operand must be t0/x5 when using "
+ "%tlsdesc_call modifier");
+ }
+
+ return false;
+}
+
std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp() const {
return RISCVOperand::createReg(RISCV::NoRegister, llvm::SMLoc(),
llvm::SMLoc());
@@ -3526,6 +3567,10 @@ bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
if (checkPseudoAddTPRel(Inst, Operands))
return true;
break;
+ case RISCV::PseudoTLSDESCCall:
+ if (checkPseudoTLSDESCCall(Inst, Operands))
+ return true;
+ break;
case RISCV::PseudoSEXT_B:
emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/8, IDLoc, Out);
return false;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index 7ce08eabdeb61d..bd49875c9591d0 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -86,6 +86,12 @@ RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{"fixup_riscv_call_plt", 0, 64, MCFixupKindInfo::FKF_IsPCRel},
{"fixup_riscv_relax", 0, 0, 0},
{"fixup_riscv_align", 0, 0, 0},
+
+ {"fixup_riscv_tlsdesc_hi20", 12, 20,
+ MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget},
+ {"fixup_riscv_tlsdesc_load_lo12", 20, 12, 0},
+ {"fixup_riscv_tlsdesc_add_lo12", 20, 12, 0},
+ {"fixup_riscv_tlsdesc_call", 0, 0, 0},
};
static_assert((std::size(Infos)) == RISCV::NumTargetFixupKinds,
"Not all fixup kinds added to Infos array");
@@ -126,6 +132,7 @@ bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
case RISCV::fixup_riscv_got_hi20:
case RISCV::fixup_riscv_tls_got_hi20:
case RISCV::fixup_riscv_tls_gd_hi20:
+ case RISCV::fixup_riscv_tlsdesc_hi20:
return true;
}
@@ -411,6 +418,7 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case RISCV::fixup_riscv_got_hi20:
case RISCV::fixup_riscv_tls_got_hi20:
case RISCV::fixup_riscv_tls_gd_hi20:
+ case RISCV::fixup_riscv_tlsdesc_hi20:
llvm_unreachable("Relocation should be unconditionally forced\n");
case FK_Data_1:
case FK_Data_2:
@@ -421,6 +429,7 @@ static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
case RISCV::fixup_riscv_lo12_i:
case RISCV::fixup_riscv_pcrel_lo12_i:
case RISCV::fixup_riscv_tprel_lo12_i:
+ case RISCV::fixup_riscv_tlsdesc_load_lo12:
return Value & 0xfff;
case RISCV::fixup_riscv_12_i:
if (!isInt<12>(Value)) {
@@ -524,6 +533,7 @@ bool RISCVAsmBackend::evaluateTargetFixup(
switch (Fixup.getTargetKind()) {
default:
llvm_unreachable("Unexpected fixup kind!");
+ case RISCV::fixup_riscv_tlsdesc_hi20:
case RISCV::fixup_riscv_pcrel_hi20:
AUIPCFixup = &Fixup;
AUIPCDF = DF;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 433e2e6f80bd68..d7f7859ce4399b 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -264,11 +264,15 @@ enum {
MO_TPREL_ADD = 10,
MO_TLS_GOT_HI = 11,
MO_TLS_GD_HI = 12,
+ MO_TLSDESC_HI = 13,
+ MO_TLSDESC_LOAD_LO = 14,
+ MO_TLSDESC_ADD_LO = 15,
+ MO_TLSDESC_CALL = 16,
// Used to differentiate between target-specific "direct" flags and "bitmask"
// flags. A machine operand can only have one "direct" flag, but can have
// multiple "bitmask" flags.
- MO_DIRECT_FLAG_MASK = 15
+ MO_DIRECT_FLAG_MASK = 31
};
} // namespace RISCVII
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
index 0799267eaf7c76..bf73b82eaea880 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
@@ -77,6 +77,14 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
return ELF::R_RISCV_TLS_GOT_HI20;
case RISCV::fixup_riscv_tls_gd_hi20:
return ELF::R_RISCV_TLS_GD_HI20;
+ case RISCV::fixup_riscv_tlsdesc_hi20:
+ return ELF::R_RISCV_TLSDESC_HI20;
+ case RISCV::fixup_riscv_tlsdesc_load_lo12:
+ return ELF::R_RISCV_TLSDESC_LOAD_LO12;
+ case RISCV::fixup_riscv_tlsdesc_add_lo12:
+ return ELF::R_RISCV_TLSDESC_ADD_LO12;
+ case RISCV::fixup_riscv_tlsdesc_call:
+ return ELF::R_RISCV_TLSDESC_CALL;
case RISCV::fixup_riscv_jal:
return ELF::R_RISCV_JAL;
case RISCV::fixup_riscv_branch:
@@ -96,6 +104,13 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
default:
Ctx.reportError(Fixup.getLoc(), "unsupported relocation type");
return ELF::R_RISCV_NONE;
+ case RISCV::fixup_riscv_tlsdesc_load_lo12:
+ return ELF::R_RISCV_TLSDESC_LOAD_LO12;
+ case RISCV::fixup_riscv_tlsdesc_add_lo12:
+ return ELF::R_RISCV_TLSDESC_ADD_LO12;
+ case RISCV::fixup_riscv_tlsdesc_call:
+ return ELF::R_RISCV_TLSDESC_CALL;
+
case FK_Data_1:
Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported");
return ELF::R_RISCV_NONE;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
index 74bd9398a9ef6b..821372d3d39a63 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
@@ -71,6 +71,12 @@ enum Fixups {
// Used to generate an R_RISCV_ALIGN relocation, which indicates the linker
// should fixup the alignment after linker relaxation.
fixup_riscv_align,
+ // Fixups indicating a TLS descriptor code sequence, corresponding to auipc,
+ // lw/ld, addi, and jalr, respectively.
+ fixup_riscv_tlsdesc_hi20,
+ fixup_riscv_tlsdesc_load_lo12,
+ fixup_riscv_tlsdesc_add_lo12,
+ fixup_riscv_tlsdesc_call,
// Used as a sentinel, must be the last
fixup_riscv_invalid,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index 82fed50bce753a..2b603e974e68e1 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -57,6 +57,10 @@ class RISCVMCCodeEmitter : public MCCodeEmitter {
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+ void expandTLSDESCCall(const MCInst &MI, SmallVectorImpl<char> &CB,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
void expandAddTPRel(const MCInst &MI, SmallVectorImpl<char> &CB,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
@@ -154,6 +158,32 @@ void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI,
support::endian::write(CB, Binary, llvm::endianness::little);
}
+void RISCVMCCodeEmitter::expandTLSDESCCall(const MCInst &MI,
+ SmallVectorImpl<char> &CB,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ MCOperand SrcSymbol = MI.getOperand(3);
+ assert(SrcSymbol.isExpr() &&
+ "Expected expression as first input to TLSDESCCALL");
+ const RISCVMCExpr *Expr = dyn_cast<RISCVMCExpr>(SrcSymbol.getExpr());
+ MCRegister Link = MI.getOperand(0).getReg();
+ MCRegister Dest = MI.getOperand(1).getReg();
+ MCRegister Imm = MI.getOperand(2).getImm();
+ Fixups.push_back(MCFixup::create(
+ 0, Expr, MCFixupKind(RISCV::fixup_riscv_tlsdesc_call), MI.getLoc()));
+ // Emit fixup_riscv_relax for jalr where the relax feature is enabled.
+ if (STI.hasFeature(RISCV::FeatureRelax)) {
+ const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx);
+ Fixups.push_back(MCFixup::create(
+ 0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax), MI.getLoc()));
+ }
+ MCInst Call =
+ MCInstBuilder(RISCV::JALR).addReg(Link).addReg(Dest).addImm(Imm);
+
+ uint32_t Binary = getBinaryCodeForInstr(Call, Fixups, STI);
+ support::endian::write(CB, Binary, llvm::endianness::little);
+}
+
// Expand PseudoAddTPRel to a simple ADD with the correct relocation.
void RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI,
SmallVectorImpl<char> &CB,
@@ -303,6 +333,10 @@ void RISCVMCCodeEmitter::encodeInstruction(const MCInst &MI,
expandLongCondBr(MI, CB, Fixups, STI);
MCNumEmitted += 2;
return;
+ case RISCV::PseudoTLSDESCCall:
+ expandTLSDESCCall(MI, CB, Fixups, STI);
+ MCNumEmitted += 1;
+ return;
}
switch (Size) {
@@ -445,6 +479,19 @@ unsigned RISCVMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNo,
FixupKind = RISCV::fixup_riscv_call_plt;
RelaxCandidate = true;
break;
+ case RISCVMCExpr::VK_RISCV_TLSDESC_HI:
+ FixupKind = RISCV::fixup_riscv_tlsdesc_hi20;
+ break;
+ case RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO:
+ FixupKind = RISCV::fixup_riscv_tlsdesc_load_lo12;
+ break;
+ case RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO:
+ FixupKind = RISCV::fixup_riscv_tlsdesc_add_lo12;
+ break;
+ case RISCVMCExpr::VK_RISCV_TLSDESC_CALL:
+ FixupKind = RISCV::fixup_riscv_tlsdesc_call;
+ RelaxCandidate = true;
+ break;
}
} else if ((Kind == MCExpr::SymbolRef &&
cast<MCSymbolRefExpr>(Expr)->getKind() ==
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
index 64ddae61b1bc15..254a9a4bc0ef0b 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
@@ -79,6 +79,7 @@ const MCFixup *RISCVMCExpr::getPCRelHiFixup(const MCFragment **DFOut) const {
case RISCV::fixup_riscv_tls_got_hi20:
case RISCV::fixup_riscv_tls_gd_hi20:
case RISCV::fixup_riscv_pcrel_hi20:
+ case RISCV::fixup_riscv_tlsdesc_hi20:
if (DFOut)
*DFOut = DF;
return &F;
@@ -119,6 +120,10 @@ RISCVMCExpr::VariantKind RISCVMCExpr::getVariantKindForName(StringRef name) {
.Case("tprel_add", VK_RISCV_TPREL_ADD)
.Case("tls_ie_pcrel_hi", VK_RISCV_TLS_GOT_HI)
.Case("tls_gd_pcrel_hi", VK_RISCV_TLS_GD_HI)
+ .Case("tlsdesc_hi", VK_RISCV_TLSDESC_HI)
+ .Case("tlsdesc_load_lo", VK_RISCV_TLSDESC_LOAD_LO)
+ .Case("tlsdesc_add_lo", VK_RISCV_TLSDESC_ADD_LO)
+ .Case("tlsdesc_call", VK_RISCV_TLSDESC_CALL)
.Default(VK_RISCV_Invalid);
}
@@ -145,6 +150,14 @@ StringRef RISCVMCExpr::getVariantKindName(VariantKind Kind) {
return "tprel_add";
case VK_RISCV_TLS_GOT_HI:
return "tls_ie_pcrel_hi";
+ case VK_RISCV_TLSDESC_HI:
+ return "tlsdesc_hi";
+ case VK_RISCV_TLSDESC_LOAD_LO:
+ return "tlsdesc_load_lo";
+ case VK_RISCV_TLSDESC_ADD_LO:
+ return "tlsdesc_add_lo";
+ case VK_RISCV_TLSDESC_CALL:
+ return "tlsdesc_call";
case VK_RISCV_TLS_GD_HI:
return "tls_gd_pcrel_hi";
case VK_RISCV_CALL:
@@ -193,6 +206,9 @@ void RISCVMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
case VK_RISCV_TPREL_HI:
case VK_RISCV_TLS_GOT_HI:
case VK_RISCV_TLS_GD_HI:
+ case VK_RISCV_TLSDESC_HI:
+ case VK_RISCV_TLSDESC_ADD_LO:
+ case VK_RISCV_TLSDESC_LOAD_LO:
break;
}
@@ -206,6 +222,8 @@ bool RISCVMCExpr::evaluateAsConstant(int64_t &Res) const {
Kind == VK_RISCV_GOT_HI || Kind == VK_RISCV_TPREL_HI ||
Kind == VK_RISCV_TPREL_LO || Kind == VK_RISCV_TPREL_ADD ||
Kind == VK_RISCV_TLS_GOT_HI || Kind == VK_RISCV_TLS_GD_HI ||
+ Kind == VK_RISCV_TLSDESC_HI || Kind == VK_RISCV_TLSDESC_LOAD_LO ||
+ Kind == VK_RISCV_TLSDESC_ADD_LO || Kind == VK_RISCV_TLSDESC_CALL ||
Kind == VK_RISCV_CALL || Kind == VK_RISCV_CALL_PLT)
return false;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
index ee83bf0208ef46..fcc4c5c439645a 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
@@ -37,6 +37,10 @@ class RISCVMCExpr : public MCTargetExpr {
VK_RISCV_CALL,
VK_RISCV_CALL_PLT,
VK_RISCV_32_PCREL,
+ VK_RISCV_TLSDESC_HI,
+ VK_RISCV_TLSDESC_LOAD_LO,
+ VK_RISCV_TLSDESC_ADD_LO,
+ VK_RISCV_TLSDESC_CALL,
VK_RISCV_Invalid // Must be the last item
};
diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
index f2bd5118fc0717..8f6cf5a948b722 100644
--- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
+++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
@@ -779,6 +779,18 @@ static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym,
case RISCVII::MO_TLS_GD_HI:
Kind = RISCVMCExpr::VK_RISCV_TLS_GD_HI;
break;
+ case RISCVII::MO_TLSDESC_HI:
+ Kind = RISCVMCExpr::VK_RISCV_TLSDESC_HI;
+ break;
+ case RISCVII::MO_TLSDESC_LOAD_LO:
+ Kind = RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO;
+ break;
+ case RISCVII::MO_TLSDESC_ADD_LO:
+ Kind = RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO;
+ break;
+ case RISCVII::MO_TLSDESC_CALL:
+ Kind = RISCVMCExpr::VK_RISCV_TLSDESC_CALL;
+ break;
}
const MCExpr *ME =
diff --git a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
index 103a2e2da7b9fb..8e2b68f25e6f85 100644
--- a/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp
@@ -419,6 +419,10 @@ class RISCVPreRAExpandPseudo : public MachineFunctionPass {
bool expandLoadTLSGDAddress(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI,
MachineBasicBlock::iterator &NextMBBI);
+ bool expandLoadTLSDescAddress(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ MachineBasicBlock::iterator &NextMBBI);
+
#ifndef NDEBUG
unsigned getInstSizeInBytes(const MachineFunction &MF) const {
unsigned Size = 0;
@@ -477,6 +481,8 @@ bool RISCVPreRAExpandPseudo::expandMI(MachineBasicBlock &MBB,
return expandLoadTLSIEAddress(MBB, MBBI, NextMBBI);
case RISCV::PseudoLA_TLS_GD:
return expandLoadTLSGDAddress(MBB, MBBI, NextMBBI);
+ case RISCV::PseudoLA_TL...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/77515
More information about the llvm-commits
mailing list