[mips][ias] Support .dtprel[d]word and .tprel[d]word directives
Assembler directives .dtprelword, .dtpreldword, .tprelword, and
.tpreldword generates relocations R_MIPS_TLS_DTPREL32, R_MIPS_TLS_DTPREL64,
R_MIPS_TLS_TPREL32, and R_MIPS_TLS_TPREL64 respectively.
The main motivation for this patch is to be able to write test cases
for checking correctness of the LLD linker's behaviour.
Differential Revision: https://reviews.llvm.org/D23669
llvm-svn: 279439
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index f6c0e04..58ae3aa 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -292,6 +292,10 @@
bool parseDataDirective(unsigned Size, SMLoc L);
bool parseDirectiveGpWord();
bool parseDirectiveGpDWord();
+ bool parseDirectiveDtpRelWord();
+ bool parseDirectiveDtpRelDWord();
+ bool parseDirectiveTpRelWord();
+ bool parseDirectiveTpRelDWord();
bool parseDirectiveModule();
bool parseDirectiveModuleFP();
bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
@@ -5749,7 +5753,79 @@
getParser().getStreamer().EmitGPRel64Value(Value);
if (getLexer().isNot(AsmToken::EndOfStatement))
- return Error(getLexer().getLoc(),
+ return Error(getLexer().getLoc(),
+ "unexpected token, expected end of statement");
+ Parser.Lex(); // Eat EndOfStatement token.
+ return false;
+}
+
+/// parseDirectiveDtpRelWord
+/// ::= .dtprelword tls_sym
+bool MipsAsmParser::parseDirectiveDtpRelWord() {
+ MCAsmParser &Parser = getParser();
+ const MCExpr *Value;
+ // EmitDTPRel32Value requires an expression, so we are using base class
+ // method to evaluate the expression.
+ if (getParser().parseExpression(Value))
+ return true;
+ getParser().getStreamer().EmitDTPRel32Value(Value);
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return Error(getLexer().getLoc(),
+ "unexpected token, expected end of statement");
+ Parser.Lex(); // Eat EndOfStatement token.
+ return false;
+}
+
+/// parseDirectiveDtpRelDWord
+/// ::= .dtpreldword tls_sym
+bool MipsAsmParser::parseDirectiveDtpRelDWord() {
+ MCAsmParser &Parser = getParser();
+ const MCExpr *Value;
+ // EmitDTPRel64Value requires an expression, so we are using base class
+ // method to evaluate the expression.
+ if (getParser().parseExpression(Value))
+ return true;
+ getParser().getStreamer().EmitDTPRel64Value(Value);
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return Error(getLexer().getLoc(),
+ "unexpected token, expected end of statement");
+ Parser.Lex(); // Eat EndOfStatement token.
+ return false;
+}
+
+/// parseDirectiveTpRelWord
+/// ::= .tprelword tls_sym
+bool MipsAsmParser::parseDirectiveTpRelWord() {
+ MCAsmParser &Parser = getParser();
+ const MCExpr *Value;
+ // EmitTPRel32Value requires an expression, so we are using base class
+ // method to evaluate the expression.
+ if (getParser().parseExpression(Value))
+ return true;
+ getParser().getStreamer().EmitTPRel32Value(Value);
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return Error(getLexer().getLoc(),
+ "unexpected token, expected end of statement");
+ Parser.Lex(); // Eat EndOfStatement token.
+ return false;
+}
+
+/// parseDirectiveTpRelDWord
+/// ::= .tpreldword tls_sym
+bool MipsAsmParser::parseDirectiveTpRelDWord() {
+ MCAsmParser &Parser = getParser();
+ const MCExpr *Value;
+ // EmitTPRel64Value requires an expression, so we are using base class
+ // method to evaluate the expression.
+ if (getParser().parseExpression(Value))
+ return true;
+ getParser().getStreamer().EmitTPRel64Value(Value);
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return Error(getLexer().getLoc(),
"unexpected token, expected end of statement");
Parser.Lex(); // Eat EndOfStatement token.
return false;
@@ -6304,6 +6380,26 @@
return false;
}
+ if (IDVal == ".dtprelword") {
+ parseDirectiveDtpRelWord();
+ return false;
+ }
+
+ if (IDVal == ".dtpreldword") {
+ parseDirectiveDtpRelDWord();
+ return false;
+ }
+
+ if (IDVal == ".tprelword") {
+ parseDirectiveTpRelWord();
+ return false;
+ }
+
+ if (IDVal == ".tpreldword") {
+ parseDirectiveTpRelDWord();
+ return false;
+ }
+
if (IDVal == ".word") {
parseDataDirective(4, DirectiveID.getLoc());
return false;
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
index 3ee0cd9..38b11f7 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp
@@ -59,6 +59,10 @@
case Mips::fixup_MIPS_PCLO16:
Value &= 0xffff;
break;
+ case FK_DTPRel_4:
+ case FK_DTPRel_8:
+ case FK_TPRel_4:
+ case FK_TPRel_8:
case FK_GPRel_4:
case FK_Data_4:
case FK_Data_8:
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
index 47ce021c..0bfd469 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
@@ -270,6 +270,14 @@
case Mips::fixup_Mips_64:
case FK_Data_8:
return ELF::R_MIPS_64;
+ case FK_DTPRel_4:
+ return ELF::R_MIPS_TLS_DTPREL32;
+ case FK_DTPRel_8:
+ return ELF::R_MIPS_TLS_DTPREL64;
+ case FK_TPRel_4:
+ return ELF::R_MIPS_TLS_TPREL32;
+ case FK_TPRel_8:
+ return ELF::R_MIPS_TLS_TPREL64;
case FK_GPRel_4:
if (isN64()) {
unsigned Type = (unsigned)ELF::R_MIPS_NONE;
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
index 2c01f91..5a394fe8 100644
--- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
+++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCAsmInfo.cpp
@@ -45,6 +45,10 @@
ZeroDirective = "\t.space\t";
GPRel32Directive = "\t.gpword\t";
GPRel64Directive = "\t.gpdword\t";
+ DTPRel32Directive = "\t.dtprelword\t";
+ DTPRel64Directive = "\t.dtpreldword\t";
+ TPRel32Directive = "\t.tprelword\t";
+ TPRel64Directive = "\t.tpreldword\t";
UseAssignmentForEHBegin = true;
SupportsDebugInformation = true;
ExceptionsType = ExceptionHandling::DwarfCFI;