[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.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@229652 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ulrich Weigand
2015-02-18 09:11:36 +00:00
parent 582e77af02
commit ca1a3cf45b
10 changed files with 344 additions and 21 deletions

View File

@@ -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::printPCRelOperand(const MCInst *MI, int OpNum,
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);