[RISCV] Support assembling %tls_{ie,gd}_pcrel_hi modifiers
This patch adds support for parsing and assembling the %tls_ie_pcrel_hi
and %tls_gd_pcrel_hi modifiers.
Differential Revision: https://reviews.llvm.org/D55342
llvm-svn: 358994
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index a7580c5..c6b633a 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -552,11 +552,15 @@
if (!IsConstantImm) {
IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
- VK == RISCVMCExpr::VK_RISCV_GOT_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_GOT_HI ||
+ VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
+ VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI);
}
}
@@ -910,8 +914,9 @@
case Match_InvalidUImm20AUIPC:
return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 20) - 1,
- "operand must be a symbol with a %pcrel_hi/%got_pcrel_hi modifier "
- "or an integer in the range");
+ "operand must be a symbol with a "
+ "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
+ "an integer in the range");
case Match_InvalidSImm21Lsb0JAL:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index c57eb73..633ff84 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -34,6 +34,8 @@
default:
break;
case RISCV::fixup_riscv_got_hi20:
+ case RISCV::fixup_riscv_tls_got_hi20:
+ case RISCV::fixup_riscv_tls_gd_hi20:
return true;
case RISCV::fixup_riscv_pcrel_lo12_i:
case RISCV::fixup_riscv_pcrel_lo12_s:
@@ -51,6 +53,8 @@
llvm_unreachable("Unexpected fixup kind for pcrel_lo12");
break;
case RISCV::fixup_riscv_got_hi20:
+ case RISCV::fixup_riscv_tls_got_hi20:
+ case RISCV::fixup_riscv_tls_gd_hi20:
ShouldForce = true;
break;
case RISCV::fixup_riscv_pcrel_hi20:
@@ -179,6 +183,8 @@
default:
llvm_unreachable("Unknown fixup kind!");
case RISCV::fixup_riscv_got_hi20:
+ case RISCV::fixup_riscv_tls_got_hi20:
+ case RISCV::fixup_riscv_tls_gd_hi20:
llvm_unreachable("Relocation should be unconditionally forced\n");
case FK_Data_1:
case FK_Data_2:
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
index f16bd4e..254249c 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
@@ -109,6 +109,8 @@
{ "fixup_riscv_tprel_lo12_i", 20, 12, 0 },
{ "fixup_riscv_tprel_lo12_s", 0, 32, 0 },
{ "fixup_riscv_tprel_add", 0, 0, 0 },
+ { "fixup_riscv_tls_got_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
+ { "fixup_riscv_tls_gd_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_riscv_jal", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_riscv_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_riscv_rvc_jump", 2, 11, MCFixupKindInfo::FKF_IsPCRel },
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
index e649776..c910f2c 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp
@@ -93,6 +93,10 @@
return ELF::R_RISCV_TPREL_LO12_S;
case RISCV::fixup_riscv_tprel_add:
return ELF::R_RISCV_TPREL_ADD;
+ case RISCV::fixup_riscv_tls_got_hi20:
+ 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_jal:
return ELF::R_RISCV_JAL;
case RISCV::fixup_riscv_branch:
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
index e33183e..6c79333 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVFixupKinds.h
@@ -49,6 +49,12 @@
// fixup_riscv_tprel_add - A fixup corresponding to %tprel_add(foo) for the
// add_tls instruction. Used to provide a hint to the linker.
fixup_riscv_tprel_add,
+ // fixup_riscv_tls_got_hi20 - 20-bit fixup corresponding to
+ // tls_ie_pcrel_hi(foo) for instructions like auipc
+ fixup_riscv_tls_got_hi20,
+ // fixup_riscv_tls_gd_hi20 - 20-bit fixup corresponding to
+ // tls_gd_pcrel_hi(foo) for instructions like auipc
+ fixup_riscv_tls_gd_hi20,
// fixup_riscv_jal - 20-bit fixup for symbol references in the jal
// instruction
fixup_riscv_jal,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
index f1248e5..32e9f4e 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCCodeEmitter.cpp
@@ -307,6 +307,12 @@
FixupKind = RISCV::fixup_riscv_tprel_hi20;
RelaxCandidate = true;
break;
+ case RISCVMCExpr::VK_RISCV_TLS_GOT_HI:
+ FixupKind = RISCV::fixup_riscv_tls_got_hi20;
+ break;
+ case RISCVMCExpr::VK_RISCV_TLS_GD_HI:
+ FixupKind = RISCV::fixup_riscv_tls_gd_hi20;
+ break;
case RISCVMCExpr::VK_RISCV_CALL:
FixupKind = RISCV::fixup_riscv_call;
RelaxCandidate = true;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
index 6ccabee..ae25ec8 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
@@ -78,6 +78,8 @@
default:
continue;
case RISCV::fixup_riscv_got_hi20:
+ case RISCV::fixup_riscv_tls_got_hi20:
+ case RISCV::fixup_riscv_tls_gd_hi20:
case RISCV::fixup_riscv_pcrel_hi20:
return &F;
}
@@ -166,6 +168,8 @@
case VK_RISCV_TPREL_LO:
case VK_RISCV_TPREL_HI:
case VK_RISCV_TPREL_ADD:
+ case VK_RISCV_TLS_GOT_HI:
+ case VK_RISCV_TLS_GD_HI:
return false;
}
}
@@ -187,6 +191,8 @@
.Case("tprel_lo", VK_RISCV_TPREL_LO)
.Case("tprel_hi", VK_RISCV_TPREL_HI)
.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)
.Default(VK_RISCV_Invalid);
}
@@ -210,6 +216,10 @@
return "tprel_hi";
case VK_RISCV_TPREL_ADD:
return "tprel_add";
+ case VK_RISCV_TLS_GOT_HI:
+ return "tls_ie_pcrel_hi";
+ case VK_RISCV_TLS_GD_HI:
+ return "tls_gd_pcrel_hi";
}
}
@@ -247,6 +257,8 @@
default:
return;
case VK_RISCV_TPREL_HI:
+ case VK_RISCV_TLS_GOT_HI:
+ case VK_RISCV_TLS_GD_HI:
break;
}
@@ -259,6 +271,7 @@
if (Kind == VK_RISCV_PCREL_HI || Kind == VK_RISCV_PCREL_LO ||
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_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 5846811..b5a292d 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
@@ -32,6 +32,8 @@
VK_RISCV_TPREL_LO,
VK_RISCV_TPREL_HI,
VK_RISCV_TPREL_ADD,
+ VK_RISCV_TLS_GOT_HI,
+ VK_RISCV_TLS_GD_HI,
VK_RISCV_CALL,
VK_RISCV_CALL_PLT,
VK_RISCV_Invalid