[llvm] r229652 - [SystemZ] Support all TLS access models - MC part
Ulrich Weigand
ulrich.weigand at de.ibm.com
Wed Feb 18 01:11:37 PST 2015
Author: uweigand
Date: Wed Feb 18 03:11:36 2015
New Revision: 229652
URL: http://llvm.org/viewvc/llvm-project?rev=229652&view=rev
Log:
[SystemZ] Support all TLS access models - MC part
The current SystemZ back-end only supports the local-exec TLS access model.
This patch adds all required MC support for the other TLS models, which
means in particular:
- Support additional relocation types for
Initial-exec model: R_390_TLS_IEENT
Local-dynamic-model: R_390_TLS_LDO32, R_390_TLS_LDO64,
R_390_TLS_LDM32, R_390_TLS_LDM64, R_390_TLS_LDCALL
General-dynamic model: R_390_TLS_GD32, R_390_TLS_GD64, R_390_TLS_GDCALL
- Support assembler syntax to generate additional relocations
for use with __tls_get_offset calls:
:tls_gdcall:
:tls_ldcall:
The patch also adds a new test to verify fixups and relocations,
and removes the (already unused) FK_390_PLT16DBL/FK_390_PLT32DBL
fixup kinds.
Added:
llvm/trunk/test/MC/SystemZ/fixups.s
Modified:
llvm/trunk/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
llvm/trunk/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp
llvm/trunk/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h
llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp
llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCFixups.h
llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp
llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td
llvm/trunk/lib/Target/SystemZ/SystemZOperands.td
Modified: llvm/trunk/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp?rev=229652&r1=229651&r2=229652&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp Wed Feb 18 03:11:36 2015
@@ -57,6 +57,7 @@ private:
KindReg,
KindAccessReg,
KindImm,
+ KindImmTLS,
KindMem
};
@@ -96,11 +97,19 @@ private:
const MCExpr *Length;
};
+ // Imm is an immediate operand, and Sym is an optional TLS symbol
+ // for use with a __tls_get_offset marker relocation.
+ struct ImmTLSOp {
+ const MCExpr *Imm;
+ const MCExpr *Sym;
+ };
+
union {
TokenOp Token;
RegOp Reg;
unsigned AccessReg;
const MCExpr *Imm;
+ ImmTLSOp ImmTLS;
MemOp Mem;
};
@@ -160,6 +169,14 @@ public:
Op->Mem.Length = Length;
return Op;
}
+ static std::unique_ptr<SystemZOperand>
+ createImmTLS(const MCExpr *Imm, const MCExpr *Sym,
+ SMLoc StartLoc, SMLoc EndLoc) {
+ auto Op = make_unique<SystemZOperand>(KindImmTLS, StartLoc, EndLoc);
+ Op->ImmTLS.Imm = Imm;
+ Op->ImmTLS.Sym = Sym;
+ return Op;
+ }
// Token operands
bool isToken() const override {
@@ -200,6 +217,11 @@ public:
return Imm;
}
+ // Immediate operands with optional TLS symbol.
+ bool isImmTLS() const {
+ return Kind == KindImmTLS;
+ }
+
// Memory operands.
bool isMem() const override {
return Kind == KindMem;
@@ -260,6 +282,13 @@ public:
addExpr(Inst, Mem.Disp);
addExpr(Inst, Mem.Length);
}
+ void addImmTLSOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 2 && "Invalid number of operands");
+ assert(Kind == KindImmTLS && "Invalid operand type");
+ addExpr(Inst, ImmTLS.Imm);
+ if (ImmTLS.Sym)
+ addExpr(Inst, ImmTLS.Sym);
+ }
// Used by the TableGen code to check for particular operand types.
bool isGR32() const { return isReg(GR32Reg); }
@@ -325,6 +354,9 @@ private:
const unsigned *Regs, RegisterKind RegKind,
MemoryKind MemKind);
+ OperandMatchResultTy parsePCRel(OperandVector &Operands, int64_t MinVal,
+ int64_t MaxVal, bool AllowTLS);
+
bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
public:
@@ -395,13 +427,17 @@ public:
return parseAddress(Operands, SystemZMC::GR64Regs, ADDR64Reg, BDLMem);
}
OperandMatchResultTy parseAccessReg(OperandVector &Operands);
- OperandMatchResultTy parsePCRel(OperandVector &Operands, int64_t MinVal,
- int64_t MaxVal);
OperandMatchResultTy parsePCRel16(OperandVector &Operands) {
- return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1);
+ return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, false);
}
OperandMatchResultTy parsePCRel32(OperandVector &Operands) {
- return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1);
+ return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, false);
+ }
+ OperandMatchResultTy parsePCRelTLS16(OperandVector &Operands) {
+ return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1, true);
+ }
+ OperandMatchResultTy parsePCRelTLS32(OperandVector &Operands) {
+ return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1, true);
}
};
} // end anonymous namespace
@@ -743,7 +779,7 @@ SystemZAsmParser::parseAccessReg(Operand
SystemZAsmParser::OperandMatchResultTy
SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal,
- int64_t MaxVal) {
+ int64_t MaxVal, bool AllowTLS) {
MCContext &Ctx = getContext();
MCStreamer &Out = getStreamer();
const MCExpr *Expr;
@@ -766,9 +802,54 @@ SystemZAsmParser::parsePCRel(OperandVect
Expr = Value == 0 ? Base : MCBinaryExpr::CreateAdd(Base, Expr, Ctx);
}
+ // Optionally match :tls_gdcall: or :tls_ldcall: followed by a TLS symbol.
+ const MCExpr *Sym = nullptr;
+ if (AllowTLS && getLexer().is(AsmToken::Colon)) {
+ Parser.Lex();
+
+ if (Parser.getTok().isNot(AsmToken::Identifier)) {
+ Error(Parser.getTok().getLoc(), "unexpected token");
+ return MatchOperand_ParseFail;
+ }
+
+ MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
+ StringRef Name = Parser.getTok().getString();
+ if (Name == "tls_gdcall")
+ Kind = MCSymbolRefExpr::VK_TLSGD;
+ else if (Name == "tls_ldcall")
+ Kind = MCSymbolRefExpr::VK_TLSLDM;
+ else {
+ Error(Parser.getTok().getLoc(), "unknown TLS tag");
+ return MatchOperand_ParseFail;
+ }
+ Parser.Lex();
+
+ if (Parser.getTok().isNot(AsmToken::Colon)) {
+ Error(Parser.getTok().getLoc(), "unexpected token");
+ return MatchOperand_ParseFail;
+ }
+ Parser.Lex();
+
+ if (Parser.getTok().isNot(AsmToken::Identifier)) {
+ Error(Parser.getTok().getLoc(), "unexpected token");
+ return MatchOperand_ParseFail;
+ }
+
+ StringRef Identifier = Parser.getTok().getString();
+ Sym = MCSymbolRefExpr::Create(Ctx.GetOrCreateSymbol(Identifier),
+ Kind, Ctx);
+ Parser.Lex();
+ }
+
SMLoc EndLoc =
SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
- Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
+
+ if (AllowTLS)
+ Operands.push_back(SystemZOperand::createImmTLS(Expr, Sym,
+ StartLoc, EndLoc));
+ else
+ Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
+
return MatchOperand_Success;
}
Modified: llvm/trunk/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp?rev=229652&r1=229651&r2=229652&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.cpp Wed Feb 18 03:11:36 2015
@@ -10,6 +10,7 @@
#include "SystemZInstPrinter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -124,6 +125,29 @@ void SystemZInstPrinter::printPCRelOpera
O << *MO.getExpr();
}
+void SystemZInstPrinter::printPCRelTLSOperand(const MCInst *MI, int OpNum,
+ raw_ostream &O) {
+ // Output the PC-relative operand.
+ printPCRelOperand(MI, OpNum, O);
+
+ // Output the TLS marker if present.
+ if ((unsigned)OpNum + 1 < MI->getNumOperands()) {
+ const MCOperand &MO = MI->getOperand(OpNum + 1);
+ const MCSymbolRefExpr &refExp = cast<MCSymbolRefExpr>(*MO.getExpr());
+ switch (refExp.getKind()) {
+ case MCSymbolRefExpr::VK_TLSGD:
+ O << ":tls_gdcall:";
+ break;
+ case MCSymbolRefExpr::VK_TLSLDM:
+ O << ":tls_ldcall:";
+ break;
+ default:
+ llvm_unreachable("Unexpected symbol kind");
+ }
+ O << refExp.getSymbol().getName();
+ }
+}
+
void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,
raw_ostream &O) {
printOperand(MI->getOperand(OpNum), O);
Modified: llvm/trunk/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h?rev=229652&r1=229651&r2=229652&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h (original)
+++ llvm/trunk/lib/Target/SystemZ/InstPrinter/SystemZInstPrinter.h Wed Feb 18 03:11:36 2015
@@ -56,6 +56,7 @@ private:
void printS32ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printU32ImmOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printPCRelOperand(const MCInst *MI, int OpNum, raw_ostream &O);
+ void printPCRelTLSOperand(const MCInst *MI, int OpNum, raw_ostream &O);
void printAccessRegOperand(const MCInst *MI, int OpNum, raw_ostream &O);
// Print the mnemonic for a condition-code mask ("ne", "lh", etc.)
Modified: llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp?rev=229652&r1=229651&r2=229652&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp Wed Feb 18 03:11:36 2015
@@ -27,9 +27,10 @@ static uint64_t extractBitsForFixup(MCFi
switch (unsigned(Kind)) {
case SystemZ::FK_390_PC16DBL:
case SystemZ::FK_390_PC32DBL:
- case SystemZ::FK_390_PLT16DBL:
- case SystemZ::FK_390_PLT32DBL:
return (int64_t)Value / 2;
+
+ case SystemZ::FK_390_TLS_CALL:
+ return 0;
}
llvm_unreachable("Unknown fixup kind!");
@@ -72,8 +73,7 @@ SystemZMCAsmBackend::getFixupKindInfo(MC
const static MCFixupKindInfo Infos[SystemZ::NumTargetFixupKinds] = {
{ "FK_390_PC16DBL", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
{ "FK_390_PC32DBL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
- { "FK_390_PLT16DBL", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
- { "FK_390_PLT32DBL", 0, 32, MCFixupKindInfo::FKF_IsPCRel }
+ { "FK_390_TLS_CALL", 0, 0, 0 }
};
if (Kind < FirstTargetFixupKind)
Modified: llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp?rev=229652&r1=229651&r2=229652&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp Wed Feb 18 03:11:36 2015
@@ -74,20 +74,36 @@ private:
// Operand OpNum of MI needs a PC-relative fixup of kind Kind at
// Offset bytes from the start of MI. Add the fixup to Fixups
// and return the in-place addend, which since we're a RELA target
- // is always 0.
+ // is always 0. If AllowTLS is true and optional operand OpNum + 1
+ // is present, also emit a TLS call fixup for it.
uint64_t getPCRelEncoding(const MCInst &MI, unsigned OpNum,
SmallVectorImpl<MCFixup> &Fixups,
- unsigned Kind, int64_t Offset) const;
+ unsigned Kind, int64_t Offset,
+ bool AllowTLS) const;
uint64_t getPC16DBLEncoding(const MCInst &MI, unsigned OpNum,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
- return getPCRelEncoding(MI, OpNum, Fixups, SystemZ::FK_390_PC16DBL, 2);
+ return getPCRelEncoding(MI, OpNum, Fixups,
+ SystemZ::FK_390_PC16DBL, 2, false);
}
uint64_t getPC32DBLEncoding(const MCInst &MI, unsigned OpNum,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
- return getPCRelEncoding(MI, OpNum, Fixups, SystemZ::FK_390_PC32DBL, 2);
+ return getPCRelEncoding(MI, OpNum, Fixups,
+ SystemZ::FK_390_PC32DBL, 2, false);
+ }
+ uint64_t getPC16DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ return getPCRelEncoding(MI, OpNum, Fixups,
+ SystemZ::FK_390_PC16DBL, 2, true);
+ }
+ uint64_t getPC32DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ return getPCRelEncoding(MI, OpNum, Fixups,
+ SystemZ::FK_390_PC32DBL, 2, true);
}
};
} // end anonymous namespace
@@ -181,7 +197,8 @@ getBDLAddr12Len8Encoding(const MCInst &M
uint64_t
SystemZMCCodeEmitter::getPCRelEncoding(const MCInst &MI, unsigned OpNum,
SmallVectorImpl<MCFixup> &Fixups,
- unsigned Kind, int64_t Offset) const {
+ unsigned Kind, int64_t Offset,
+ bool AllowTLS) const {
const MCOperand &MO = MI.getOperand(OpNum);
const MCExpr *Expr;
if (MO.isImm())
@@ -198,6 +215,13 @@ SystemZMCCodeEmitter::getPCRelEncoding(c
}
}
Fixups.push_back(MCFixup::Create(Offset, Expr, (MCFixupKind)Kind));
+
+ // Output the fixup for the TLS marker if present.
+ if (AllowTLS && OpNum + 1 < MI.getNumOperands()) {
+ const MCOperand &MOTLS = MI.getOperand(OpNum + 1);
+ Fixups.push_back(MCFixup::Create(0, MOTLS.getExpr(),
+ (MCFixupKind)SystemZ::FK_390_TLS_CALL));
+ }
return 0;
}
Modified: llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCFixups.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCFixups.h?rev=229652&r1=229651&r2=229652&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCFixups.h (original)
+++ llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCFixups.h Wed Feb 18 03:11:36 2015
@@ -18,8 +18,7 @@ enum FixupKind {
// These correspond directly to R_390_* relocations.
FK_390_PC16DBL = FirstTargetFixupKind,
FK_390_PC32DBL,
- FK_390_PLT16DBL,
- FK_390_PLT32DBL,
+ FK_390_TLS_CALL,
// Marker
LastTargetFixupKind,
Modified: llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp?rev=229652&r1=229651&r2=229652&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp Wed Feb 18 03:11:36 2015
@@ -55,8 +55,6 @@ static unsigned getPCRelReloc(unsigned K
case FK_Data_8: return ELF::R_390_PC64;
case SystemZ::FK_390_PC16DBL: return ELF::R_390_PC16DBL;
case SystemZ::FK_390_PC32DBL: return ELF::R_390_PC32DBL;
- case SystemZ::FK_390_PLT16DBL: return ELF::R_390_PLT16DBL;
- case SystemZ::FK_390_PLT32DBL: return ELF::R_390_PLT32DBL;
}
llvm_unreachable("Unsupported PC-relative address");
}
@@ -70,6 +68,35 @@ static unsigned getTLSLEReloc(unsigned K
llvm_unreachable("Unsupported absolute address");
}
+// Return the R_390_TLS_LDO* relocation type for MCFixupKind Kind.
+static unsigned getTLSLDOReloc(unsigned Kind) {
+ switch (Kind) {
+ case FK_Data_4: return ELF::R_390_TLS_LDO32;
+ case FK_Data_8: return ELF::R_390_TLS_LDO64;
+ }
+ llvm_unreachable("Unsupported absolute address");
+}
+
+// Return the R_390_TLS_LDM* relocation type for MCFixupKind Kind.
+static unsigned getTLSLDMReloc(unsigned Kind) {
+ switch (Kind) {
+ case FK_Data_4: return ELF::R_390_TLS_LDM32;
+ case FK_Data_8: return ELF::R_390_TLS_LDM64;
+ case SystemZ::FK_390_TLS_CALL: return ELF::R_390_TLS_LDCALL;
+ }
+ llvm_unreachable("Unsupported absolute address");
+}
+
+// Return the R_390_TLS_GD* relocation type for MCFixupKind Kind.
+static unsigned getTLSGDReloc(unsigned Kind) {
+ switch (Kind) {
+ case FK_Data_4: return ELF::R_390_TLS_GD32;
+ case FK_Data_8: return ELF::R_390_TLS_GD64;
+ case SystemZ::FK_390_TLS_CALL: return ELF::R_390_TLS_GDCALL;
+ }
+ llvm_unreachable("Unsupported absolute address");
+}
+
// Return the PLT relocation counterpart of MCFixupKind Kind.
static unsigned getPLTReloc(unsigned Kind) {
switch (Kind) {
@@ -94,6 +121,23 @@ unsigned SystemZObjectWriter::GetRelocTy
assert(!IsPCRel && "NTPOFF shouldn't be PC-relative");
return getTLSLEReloc(Kind);
+ case MCSymbolRefExpr::VK_INDNTPOFF:
+ if (IsPCRel && Kind == SystemZ::FK_390_PC32DBL)
+ return ELF::R_390_TLS_IEENT;
+ llvm_unreachable("Only PC-relative INDNTPOFF accesses are supported for now");
+
+ case MCSymbolRefExpr::VK_DTPOFF:
+ assert(!IsPCRel && "DTPOFF shouldn't be PC-relative");
+ return getTLSLDOReloc(Kind);
+
+ case MCSymbolRefExpr::VK_TLSLDM:
+ assert(!IsPCRel && "TLSLDM shouldn't be PC-relative");
+ return getTLSLDMReloc(Kind);
+
+ case MCSymbolRefExpr::VK_TLSGD:
+ assert(!IsPCRel && "TLSGD shouldn't be PC-relative");
+ return getTLSGDReloc(Kind);
+
case MCSymbolRefExpr::VK_GOT:
if (IsPCRel && Kind == SystemZ::FK_390_PC32DBL)
return ELF::R_390_GOTENT;
Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td?rev=229652&r1=229651&r2=229652&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td Wed Feb 18 03:11:36 2015
@@ -251,9 +251,10 @@ let isCall = 1, isTerminator = 1, isRetu
// Define the general form of the call instructions for the asm parser.
// These instructions don't hard-code %r14 as the return address register.
-def BRAS : InstRI<0xA75, (outs), (ins GR64:$R1, brtarget16:$I2),
+// Allow an optional TLS marker symbol to generate TLS call relocations.
+def BRAS : InstRI<0xA75, (outs), (ins GR64:$R1, brtarget16tls:$I2),
"bras\t$R1, $I2", []>;
-def BRASL : InstRIL<0xC05, (outs), (ins GR64:$R1, brtarget32:$I2),
+def BRASL : InstRIL<0xC05, (outs), (ins GR64:$R1, brtarget32tls:$I2),
"brasl\t$R1, $I2", []>;
def BASR : InstRR<0x0D, (outs), (ins GR64:$R1, ADDR64:$R2),
"basr\t$R1, $R2", []>;
Modified: llvm/trunk/lib/Target/SystemZ/SystemZOperands.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZOperands.td?rev=229652&r1=229651&r2=229652&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZOperands.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZOperands.td Wed Feb 18 03:11:36 2015
@@ -16,6 +16,11 @@ class ImmediateAsmOperand<string name>
let Name = name;
let RenderMethod = "addImmOperands";
}
+class ImmediateTLSAsmOperand<string name>
+ : AsmOperandClass {
+ let Name = name;
+ let RenderMethod = "addImmTLSOperands";
+}
// Constructs both a DAG pattern and instruction operand for an immediate
// of type VT. PRED returns true if a node is acceptable and XFORM returns
@@ -34,6 +39,11 @@ class PCRelAsmOperand<string size> : Imm
let PredicateMethod = "isImm";
let ParserMethod = "parsePCRel"##size;
}
+class PCRelTLSAsmOperand<string size>
+ : ImmediateTLSAsmOperand<"PCRelTLS"##size> {
+ let PredicateMethod = "isImmTLS";
+ let ParserMethod = "parsePCRelTLS"##size;
+}
// Constructs an operand for a PC-relative address with address type VT.
// ASMOP is the associated asm operand.
@@ -41,6 +51,10 @@ class PCRelOperand<ValueType vt, AsmOper
let PrintMethod = "printPCRelOperand";
let ParserMatchClass = asmop;
}
+class PCRelTLSOperand<ValueType vt, AsmOperandClass asmop> : Operand<vt> {
+ let PrintMethod = "printPCRelTLSOperand";
+ let ParserMatchClass = asmop;
+}
// Constructs both a DAG pattern and instruction operand for a PC-relative
// address with address size VT. SELF is the name of the operand and
@@ -370,6 +384,8 @@ def fpimmneg0 : PatLeaf<(fpimm), [{ retu
// PC-relative asm operands.
def PCRel16 : PCRelAsmOperand<"16">;
def PCRel32 : PCRelAsmOperand<"32">;
+def PCRelTLS16 : PCRelTLSAsmOperand<"16">;
+def PCRelTLS32 : PCRelTLSAsmOperand<"32">;
// PC-relative offsets of a basic block. The offset is sign-extended
// and multiplied by 2.
@@ -382,6 +398,20 @@ def brtarget32 : PCRelOperand<OtherVT, P
let DecoderMethod = "decodePC32DBLOperand";
}
+// Variants of brtarget16/32 with an optional additional TLS symbol.
+// These are used to annotate calls to __tls_get_offset.
+def tlssym : Operand<i64> { }
+def brtarget16tls : PCRelTLSOperand<OtherVT, PCRelTLS16> {
+ let MIOperandInfo = (ops brtarget16:$func, tlssym:$sym);
+ let EncoderMethod = "getPC16DBLTLSEncoding";
+ let DecoderMethod = "decodePC16DBLOperand";
+}
+def brtarget32tls : PCRelTLSOperand<OtherVT, PCRelTLS32> {
+ let MIOperandInfo = (ops brtarget32:$func, tlssym:$sym);
+ let EncoderMethod = "getPC32DBLTLSEncoding";
+ let DecoderMethod = "decodePC32DBLOperand";
+}
+
// A PC-relative offset of a global value. The offset is sign-extended
// and multiplied by 2.
def pcrel32 : PCRelAddress<i64, "pcrel32", PCRel32> {
Added: llvm/trunk/test/MC/SystemZ/fixups.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/SystemZ/fixups.s?rev=229652&view=auto
==============================================================================
--- llvm/trunk/test/MC/SystemZ/fixups.s (added)
+++ llvm/trunk/test/MC/SystemZ/fixups.s Wed Feb 18 03:11:36 2015
@@ -0,0 +1,119 @@
+
+# RUN: llvm-mc -triple s390x-unknown-unknown --show-encoding %s | FileCheck %s
+
+# RUN: llvm-mc -triple s390x-unknown-unknown -filetype=obj %s | \
+# RUN: llvm-readobj -r | FileCheck %s -check-prefix=CHECK-REL
+
+# CHECK: larl %r14, target # encoding: [0xc0,0xe0,A,A,A,A]
+# CHECK-NEXT: # fixup A - offset: 2, value: target+2, kind: FK_390_PC32DBL
+# CHECK-REL: 0x{{[0-9A-F]*2}} R_390_PC32DBL target 0x2
+ .align 16
+ larl %r14, target
+
+# CHECK: larl %r14, target at GOT # encoding: [0xc0,0xe0,A,A,A,A]
+# CHECK-NEXT: # fixup A - offset: 2, value: target at GOT+2, kind: FK_390_PC32DBL
+# CHECK-REL: 0x{{[0-9A-F]*2}} R_390_GOTENT target 0x2
+ .align 16
+ larl %r14, target at got
+
+# CHECK: larl %r14, target at INDNTPOFF # encoding: [0xc0,0xe0,A,A,A,A]
+# CHECK-NEXT: # fixup A - offset: 2, value: target at INDNTPOFF+2, kind: FK_390_PC32DBL
+# CHECK-REL: 0x{{[0-9A-F]*2}} R_390_TLS_IEENT target 0x2
+ .align 16
+ larl %r14, target at indntpoff
+
+# CHECK: brasl %r14, target # encoding: [0xc0,0xe5,A,A,A,A]
+# CHECK-NEXT: # fixup A - offset: 2, value: target+2, kind: FK_390_PC32DBL
+# CHECK-REL: 0x{{[0-9A-F]*2}} R_390_PC32DBL target 0x2
+ .align 16
+ brasl %r14, target
+
+# CHECK: brasl %r14, target at PLT # encoding: [0xc0,0xe5,A,A,A,A]
+# CHECK-NEXT: # fixup A - offset: 2, value: target at PLT+2, kind: FK_390_PC32DBL
+# CHECK-REL: 0x{{[0-9A-F]*2}} R_390_PLT32DBL target 0x2
+ .align 16
+ brasl %r14, target at plt
+
+# CHECK: brasl %r14, target at PLT:tls_gdcall:sym # encoding: [0xc0,0xe5,A,A,A,A]
+# CHECK-NEXT: # fixup A - offset: 2, value: target at PLT+2, kind: FK_390_PC32DBL
+# CHECK-NEXT: # fixup B - offset: 0, value: sym at TLSGD, kind: FK_390_TLS_CALL
+# CHECK-REL: 0x{{[0-9A-F]*0}} R_390_TLS_GDCALL sym 0x0
+# CHECK-REL: 0x{{[0-9A-F]*2}} R_390_PLT32DBL target 0x2
+ .align 16
+ brasl %r14, target at plt:tls_gdcall:sym
+
+# CHECK: brasl %r14, target at PLT:tls_ldcall:sym # encoding: [0xc0,0xe5,A,A,A,A]
+# CHECK-NEXT: # fixup A - offset: 2, value: target at PLT+2, kind: FK_390_PC32DBL
+# CHECK-NEXT: # fixup B - offset: 0, value: sym at TLSLDM, kind: FK_390_TLS_CALL
+# CHECK-REL: 0x{{[0-9A-F]*0}} R_390_TLS_LDCALL sym 0x0
+# CHECK-REL: 0x{{[0-9A-F]*2}} R_390_PLT32DBL target 0x2
+ .align 16
+ brasl %r14, target at plt:tls_ldcall:sym
+
+# CHECK: bras %r14, target # encoding: [0xa7,0xe5,A,A]
+# CHECK-NEXT: # fixup A - offset: 2, value: target+2, kind: FK_390_PC16DBL
+# CHECK-REL: 0x{{[0-9A-F]*2}} R_390_PC16DBL target 0x2
+ .align 16
+ bras %r14, target
+
+# CHECK: bras %r14, target at PLT # encoding: [0xa7,0xe5,A,A]
+# CHECK-NEXT: # fixup A - offset: 2, value: target at PLT+2, kind: FK_390_PC16DBL
+# CHECK-REL: 0x{{[0-9A-F]*2}} R_390_PLT16DBL target 0x2
+ .align 16
+ bras %r14, target at plt
+
+# CHECK: bras %r14, target at PLT:tls_gdcall:sym # encoding: [0xa7,0xe5,A,A]
+# CHECK-NEXT: # fixup A - offset: 2, value: target at PLT+2, kind: FK_390_PC16DBL
+# CHECK-NEXT: # fixup B - offset: 0, value: sym at TLSGD, kind: FK_390_TLS_CALL
+# CHECK-REL: 0x{{[0-9A-F]*0}} R_390_TLS_GDCALL sym 0x0
+# CHECK-REL: 0x{{[0-9A-F]*2}} R_390_PLT16DBL target 0x2
+ .align 16
+ bras %r14, target at plt:tls_gdcall:sym
+
+# CHECK: bras %r14, target at PLT:tls_ldcall:sym # encoding: [0xa7,0xe5,A,A]
+# CHECK-NEXT: # fixup A - offset: 2, value: target at PLT+2, kind: FK_390_PC16DBL
+# CHECK-NEXT: # fixup B - offset: 0, value: sym at TLSLDM, kind: FK_390_TLS_CALL
+# CHECK-REL: 0x{{[0-9A-F]*0}} R_390_TLS_LDCALL sym 0x0
+# CHECK-REL: 0x{{[0-9A-F]*2}} R_390_PLT16DBL target 0x2
+ .align 16
+ bras %r14, target at plt:tls_ldcall:sym
+
+
+# Data relocs
+# llvm-mc does not show any "encoding" string for data, so we just check the relocs
+
+# CHECK-REL: .rela.data
+ .data
+
+# CHECK-REL: 0x{{[0-9A-F]*0}} R_390_TLS_LE64 target 0x0
+ .align 16
+ .quad target at ntpoff
+
+# CHECK-REL: 0x{{[0-9A-F]*0}} R_390_TLS_LDO64 target 0x0
+ .align 16
+ .quad target at dtpoff
+
+# CHECK-REL: 0x{{[0-9A-F]*0}} R_390_TLS_LDM64 target 0x0
+ .align 16
+ .quad target at tlsldm
+
+# CHECK-REL: 0x{{[0-9A-F]*0}} R_390_TLS_GD64 target 0x0
+ .align 16
+ .quad target at tlsgd
+
+# CHECK-REL: 0x{{[0-9A-F]*0}} R_390_TLS_LE32 target 0x0
+ .align 16
+ .long target at ntpoff
+
+# CHECK-REL: 0x{{[0-9A-F]*0}} R_390_TLS_LDO32 target 0x0
+ .align 16
+ .long target at dtpoff
+
+# CHECK-REL: 0x{{[0-9A-F]*0}} R_390_TLS_LDM32 target 0x0
+ .align 16
+ .long target at tlsldm
+
+# CHECK-REL: 0x{{[0-9A-F]*0}} R_390_TLS_GD32 target 0x0
+ .align 16
+ .long target at tlsgd
+
More information about the llvm-commits
mailing list