mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 16:33:28 +00:00
This patch improves the 64-bit PowerPC InitialExec TLS support by providing
for a wider range of GOT entries that can hold thread-relative offsets. This matches the behavior of GCC, which was not documented in the PPC64 TLS ABI. The ABI will be updated with the new code sequence. Former sequence: ld 9,x@got@tprel(2) add 9,9,x@tls New sequence: addis 9,2,x@got@tprel@ha ld 9,x@got@tprel@l(9) add 9,9,x@tls Note that a linker optimization exists to transform the new sequence into the shorter sequence when appropriate, by replacing the addis with a nop and modifying the base register and relocation type of the ld. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@170209 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
79c3742620
commit
b453e16855
@ -183,7 +183,8 @@ public:
|
|||||||
VK_PPC_DTPREL16_LO, // symbol@dtprel@l
|
VK_PPC_DTPREL16_LO, // symbol@dtprel@l
|
||||||
VK_PPC_TOC16_HA, // symbol@toc@ha
|
VK_PPC_TOC16_HA, // symbol@toc@ha
|
||||||
VK_PPC_TOC16_LO, // symbol@toc@l
|
VK_PPC_TOC16_LO, // symbol@toc@l
|
||||||
VK_PPC_GOT_TPREL16_DS, // symbol@got@tprel
|
VK_PPC_GOT_TPREL16_HA, // symbol@got@tprel@ha
|
||||||
|
VK_PPC_GOT_TPREL16_LO, // symbol@got@tprel@l
|
||||||
VK_PPC_TLS, // symbol@tls
|
VK_PPC_TLS, // symbol@tls
|
||||||
VK_PPC_GOT_TLSGD16_HA, // symbol@got@tlsgd@ha
|
VK_PPC_GOT_TLSGD16_HA, // symbol@got@tlsgd@ha
|
||||||
VK_PPC_GOT_TLSGD16_LO, // symbol@got@tlsgd@l
|
VK_PPC_GOT_TLSGD16_LO, // symbol@got@tlsgd@l
|
||||||
|
@ -484,7 +484,8 @@ enum {
|
|||||||
R_PPC64_GOT_TLSGD16_HA = 82,
|
R_PPC64_GOT_TLSGD16_HA = 82,
|
||||||
R_PPC64_GOT_TLSLD16_LO = 84,
|
R_PPC64_GOT_TLSLD16_LO = 84,
|
||||||
R_PPC64_GOT_TLSLD16_HA = 86,
|
R_PPC64_GOT_TLSLD16_HA = 86,
|
||||||
R_PPC64_GOT_TPREL16_DS = 87,
|
R_PPC64_GOT_TPREL16_LO_DS = 88,
|
||||||
|
R_PPC64_GOT_TPREL16_HA = 90,
|
||||||
R_PPC64_TLSGD = 107,
|
R_PPC64_TLSGD = 107,
|
||||||
R_PPC64_TLSLD = 108
|
R_PPC64_TLSLD = 108
|
||||||
};
|
};
|
||||||
|
@ -217,7 +217,8 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
|
|||||||
case VK_PPC_DTPREL16_LO: return "dtprel@l";
|
case VK_PPC_DTPREL16_LO: return "dtprel@l";
|
||||||
case VK_PPC_TOC16_HA: return "toc@ha";
|
case VK_PPC_TOC16_HA: return "toc@ha";
|
||||||
case VK_PPC_TOC16_LO: return "toc@l";
|
case VK_PPC_TOC16_LO: return "toc@l";
|
||||||
case VK_PPC_GOT_TPREL16_DS: return "got@tprel";
|
case VK_PPC_GOT_TPREL16_HA: return "got@tprel@ha";
|
||||||
|
case VK_PPC_GOT_TPREL16_LO: return "got@tprel@l";
|
||||||
case VK_PPC_TLS: return "tls";
|
case VK_PPC_TLS: return "tls";
|
||||||
case VK_PPC_GOT_TLSGD16_HA: return "got@tlsgd@ha";
|
case VK_PPC_GOT_TLSGD16_HA: return "got@tlsgd@ha";
|
||||||
case VK_PPC_GOT_TLSGD16_LO: return "got@tlsgd@l";
|
case VK_PPC_GOT_TLSGD16_LO: return "got@tlsgd@l";
|
||||||
|
@ -88,6 +88,9 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
|
|||||||
case MCSymbolRefExpr::VK_PPC_TOC16_HA:
|
case MCSymbolRefExpr::VK_PPC_TOC16_HA:
|
||||||
Type = ELF::R_PPC64_TOC16_HA;
|
Type = ELF::R_PPC64_TOC16_HA;
|
||||||
break;
|
break;
|
||||||
|
case MCSymbolRefExpr::VK_PPC_GOT_TPREL16_HA:
|
||||||
|
Type = ELF::R_PPC64_GOT_TPREL16_HA;
|
||||||
|
break;
|
||||||
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA:
|
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD16_HA:
|
||||||
Type = ELF::R_PPC64_GOT_TLSGD16_HA;
|
Type = ELF::R_PPC64_GOT_TLSGD16_HA;
|
||||||
break;
|
break;
|
||||||
@ -137,8 +140,8 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
|
|||||||
case MCSymbolRefExpr::VK_PPC_TOC16_LO:
|
case MCSymbolRefExpr::VK_PPC_TOC16_LO:
|
||||||
Type = ELF::R_PPC64_TOC16_LO_DS;
|
Type = ELF::R_PPC64_TOC16_LO_DS;
|
||||||
break;
|
break;
|
||||||
case MCSymbolRefExpr::VK_PPC_GOT_TPREL16_DS:
|
case MCSymbolRefExpr::VK_PPC_GOT_TPREL16_LO:
|
||||||
Type = ELF::R_PPC64_GOT_TPREL16_DS;
|
Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -63,8 +63,6 @@ public:
|
|||||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||||
unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
|
unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
|
||||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||||
unsigned getTLSOffsetEncoding(const MCInst &MI, unsigned OpNo,
|
|
||||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
|
||||||
unsigned getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
|
unsigned getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
|
||||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||||
unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
|
unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
|
||||||
@ -212,17 +210,6 @@ unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned PPCMCCodeEmitter::getTLSOffsetEncoding(const MCInst &MI, unsigned OpNo,
|
|
||||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
|
||||||
const MCOperand &MO = MI.getOperand(OpNo);
|
|
||||||
|
|
||||||
// Add a fixup for the GOT displacement to the TLS block offset.
|
|
||||||
Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
|
|
||||||
(MCFixupKind)PPC::fixup_ppc_toc16_ds));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
|
unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
|
||||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||||
const MCOperand &MO = MI.getOperand(OpNo);
|
const MCOperand &MO = MI.getOperand(OpNo);
|
||||||
|
@ -513,8 +513,24 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||||||
OutStreamer.EmitInstruction(TmpInst);
|
OutStreamer.EmitInstruction(TmpInst);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case PPC::LDgotTPREL: {
|
case PPC::ADDISgotTprelHA: {
|
||||||
// Transform %Xd = LDgotTPREL <ga:@sym>, %Xs
|
// Transform: %Xd = ADDISgotTprelHA %X2, <ga:@sym>
|
||||||
|
// Into: %Xd = ADDIS8 %X2, sym@got@tlsgd@ha
|
||||||
|
assert(Subtarget.isPPC64() && "Not supported for 32-bit PowerPC");
|
||||||
|
const MachineOperand &MO = MI->getOperand(2);
|
||||||
|
const GlobalValue *GValue = MO.getGlobal();
|
||||||
|
MCSymbol *MOSymbol = Mang->getSymbol(GValue);
|
||||||
|
const MCExpr *SymGotTprel =
|
||||||
|
MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL16_HA,
|
||||||
|
OutContext);
|
||||||
|
OutStreamer.EmitInstruction(MCInstBuilder(PPC::ADDIS8)
|
||||||
|
.addReg(MI->getOperand(0).getReg())
|
||||||
|
.addReg(PPC::X2)
|
||||||
|
.addExpr(SymGotTprel));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case PPC::LDgotTprelL: {
|
||||||
|
// Transform %Xd = LDgotTprelL <ga:@sym>, %Xs
|
||||||
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
|
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
|
||||||
|
|
||||||
// Change the opcode to LDrs, which is a form of LD with the offset
|
// Change the opcode to LDrs, which is a form of LD with the offset
|
||||||
@ -524,7 +540,7 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||||||
const GlobalValue *GValue = MO.getGlobal();
|
const GlobalValue *GValue = MO.getGlobal();
|
||||||
MCSymbol *MOSymbol = Mang->getSymbol(GValue);
|
MCSymbol *MOSymbol = Mang->getSymbol(GValue);
|
||||||
const MCExpr *Exp =
|
const MCExpr *Exp =
|
||||||
MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL16_DS,
|
MCSymbolRefExpr::Create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL16_LO,
|
||||||
OutContext);
|
OutContext);
|
||||||
TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
|
TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
|
||||||
OutStreamer.EmitInstruction(TmpInst);
|
OutStreamer.EmitInstruction(TmpInst);
|
||||||
|
@ -68,7 +68,6 @@ namespace {
|
|||||||
unsigned getLO16Encoding(const MachineInstr &MI, unsigned OpNo) const;
|
unsigned getLO16Encoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||||
unsigned getMemRIEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
unsigned getMemRIEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||||
unsigned getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
unsigned getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||||
unsigned getTLSOffsetEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
|
||||||
unsigned getTLSRegEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
unsigned getTLSRegEncoding(const MachineInstr &MI, unsigned OpNo) const;
|
||||||
|
|
||||||
const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
|
const char *getPassName() const { return "PowerPC Machine Code Emitter"; }
|
||||||
@ -245,13 +244,6 @@ unsigned PPCCodeEmitter::getMemRIXEncoding(const MachineInstr &MI,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned PPCCodeEmitter::getTLSOffsetEncoding(const MachineInstr &MI,
|
|
||||||
unsigned OpNo) const {
|
|
||||||
llvm_unreachable("TLS not supported on the old JIT.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned PPCCodeEmitter::getTLSRegEncoding(const MachineInstr &MI,
|
unsigned PPCCodeEmitter::getTLSRegEncoding(const MachineInstr &MI,
|
||||||
unsigned OpNo) const {
|
unsigned OpNo) const {
|
||||||
llvm_unreachable("TLS not supported on the old JIT.");
|
llvm_unreachable("TLS not supported on the old JIT.");
|
||||||
|
@ -578,7 +578,8 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
|
|||||||
case PPCISD::ADDIS_TOC_HA: return "PPCISD::ADDIS_TOC_HA";
|
case PPCISD::ADDIS_TOC_HA: return "PPCISD::ADDIS_TOC_HA";
|
||||||
case PPCISD::LD_TOC_L: return "PPCISD::LD_TOC_L";
|
case PPCISD::LD_TOC_L: return "PPCISD::LD_TOC_L";
|
||||||
case PPCISD::ADDI_TOC_L: return "PPCISD::ADDI_TOC_L";
|
case PPCISD::ADDI_TOC_L: return "PPCISD::ADDI_TOC_L";
|
||||||
case PPCISD::LD_GOT_TPREL: return "PPCISD::LD_GOT_TPREL";
|
case PPCISD::ADDIS_GOT_TPREL_HA: return "PPCISD::ADDIS_GOT_TPREL_HA";
|
||||||
|
case PPCISD::LD_GOT_TPREL_L: return "PPCISD::LD_GOT_TPREL_L";
|
||||||
case PPCISD::ADD_TLS: return "PPCISD::ADD_TLS";
|
case PPCISD::ADD_TLS: return "PPCISD::ADD_TLS";
|
||||||
case PPCISD::ADDIS_TLSGD_HA: return "PPCISD::ADDIS_TLSGD_HA";
|
case PPCISD::ADDIS_TLSGD_HA: return "PPCISD::ADDIS_TLSGD_HA";
|
||||||
case PPCISD::ADDI_TLSGD_L: return "PPCISD::ADDI_TLSGD_L";
|
case PPCISD::ADDI_TLSGD_L: return "PPCISD::ADDI_TLSGD_L";
|
||||||
@ -1353,8 +1354,10 @@ SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
|
|||||||
if (Model == TLSModel::InitialExec) {
|
if (Model == TLSModel::InitialExec) {
|
||||||
SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
|
SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0, 0);
|
||||||
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
|
SDValue GOTReg = DAG.getRegister(PPC::X2, MVT::i64);
|
||||||
SDValue TPOffset = DAG.getNode(PPCISD::LD_GOT_TPREL, dl,
|
SDValue TPOffsetHi = DAG.getNode(PPCISD::ADDIS_GOT_TPREL_HA, dl,
|
||||||
PtrVT, TGA, GOTReg);
|
PtrVT, GOTReg, TGA);
|
||||||
|
SDValue TPOffset = DAG.getNode(PPCISD::LD_GOT_TPREL_L, dl,
|
||||||
|
PtrVT, TGA, TPOffsetHi);
|
||||||
return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGA);
|
return DAG.getNode(PPCISD::ADD_TLS, dl, PtrVT, TPOffset, TGA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,11 +178,16 @@ namespace llvm {
|
|||||||
CR6SET,
|
CR6SET,
|
||||||
CR6UNSET,
|
CR6UNSET,
|
||||||
|
|
||||||
/// G8RC = LD_GOT_TPREL Symbol, G8RReg - Used by the initial-exec
|
/// G8RC = ADDIS_GOT_TPREL_HA %X2, Symbol - Used by the initial-exec
|
||||||
|
/// TLS model, produces an ADDIS8 instruction that adds the GOT
|
||||||
|
/// base to sym@got@tprel@ha.
|
||||||
|
ADDIS_GOT_TPREL_HA,
|
||||||
|
|
||||||
|
/// G8RC = LD_GOT_TPREL_L Symbol, G8RReg - Used by the initial-exec
|
||||||
/// TLS model, produces a LD instruction with base register G8RReg
|
/// TLS model, produces a LD instruction with base register G8RReg
|
||||||
/// and offset sym@got@tprel. The latter identifies the GOT entry
|
/// and offset sym@got@tprel@l. This completes the addition that
|
||||||
/// containing the offset of "sym" relative to the thread pointer.
|
/// finds the offset of "sym" relative to the thread pointer.
|
||||||
LD_GOT_TPREL,
|
LD_GOT_TPREL_L,
|
||||||
|
|
||||||
/// G8RC = ADD_TLS G8RReg, Symbol - Used by the initial-exec TLS
|
/// G8RC = ADD_TLS G8RReg, Symbol - Used by the initial-exec TLS
|
||||||
/// model, produces an ADD instruction that adds the contents of
|
/// model, produces an ADD instruction that adds the contents of
|
||||||
|
@ -37,9 +37,6 @@ def memrs : Operand<iPTR> { // memri where the immediate is a symbolLo64
|
|||||||
let EncoderMethod = "getMemRIXEncoding";
|
let EncoderMethod = "getMemRIXEncoding";
|
||||||
let MIOperandInfo = (ops symbolLo64:$off, ptr_rc:$reg);
|
let MIOperandInfo = (ops symbolLo64:$off, ptr_rc:$reg);
|
||||||
}
|
}
|
||||||
def tlsaddr : Operand<i64> {
|
|
||||||
let EncoderMethod = "getTLSOffsetEncoding";
|
|
||||||
}
|
|
||||||
def tlsreg : Operand<i64> {
|
def tlsreg : Operand<i64> {
|
||||||
let EncoderMethod = "getTLSRegEncoding";
|
let EncoderMethod = "getTLSRegEncoding";
|
||||||
}
|
}
|
||||||
@ -720,11 +717,17 @@ def ADDItocL: Pseudo<(outs G8RC:$rD), (ins G8RC:$reg, tocentry:$disp),
|
|||||||
(PPCaddiTocL G8RC:$reg, tglobaladdr:$disp))]>, isPPC64;
|
(PPCaddiTocL G8RC:$reg, tglobaladdr:$disp))]>, isPPC64;
|
||||||
|
|
||||||
// Support for thread-local storage.
|
// Support for thread-local storage.
|
||||||
def LDgotTPREL: Pseudo<(outs G8RC:$rD), (ins tlsaddr:$disp, G8RC:$reg),
|
def ADDISgotTprelHA: Pseudo<(outs G8RC:$rD), (ins G8RC:$reg, symbolHi64:$disp),
|
||||||
"#LDgotTPREL",
|
"#ADDISgotTprelHA",
|
||||||
[(set G8RC:$rD,
|
[(set G8RC:$rD,
|
||||||
(PPCldGotTprel tglobaltlsaddr:$disp, G8RC:$reg))]>,
|
(PPCaddisGotTprelHA G8RC:$reg,
|
||||||
isPPC64;
|
tglobaltlsaddr:$disp))]>,
|
||||||
|
isPPC64;
|
||||||
|
def LDgotTprelL: Pseudo<(outs G8RC:$rD), (ins symbolLo64:$disp, G8RC:$reg),
|
||||||
|
"#LDgotTprelL",
|
||||||
|
[(set G8RC:$rD,
|
||||||
|
(PPCldGotTprelL tglobaltlsaddr:$disp, G8RC:$reg))]>,
|
||||||
|
isPPC64;
|
||||||
def : Pat<(PPCaddTls G8RC:$in, tglobaltlsaddr:$g),
|
def : Pat<(PPCaddTls G8RC:$in, tglobaltlsaddr:$g),
|
||||||
(ADD8TLS G8RC:$in, tglobaltlsaddr:$g)>;
|
(ADD8TLS G8RC:$in, tglobaltlsaddr:$g)>;
|
||||||
def ADDIStlsgdHA: Pseudo<(outs G8RC:$rD), (ins G8RC:$reg, symbolHi64:$disp),
|
def ADDIStlsgdHA: Pseudo<(outs G8RC:$rD), (ins G8RC:$reg, symbolHi64:$disp),
|
||||||
|
@ -91,7 +91,9 @@ def PPCtoc_entry: SDNode<"PPCISD::TOC_ENTRY", SDTIntBinOp, [SDNPMayLoad]>;
|
|||||||
def PPCvmaddfp : SDNode<"PPCISD::VMADDFP", SDTFPTernaryOp, []>;
|
def PPCvmaddfp : SDNode<"PPCISD::VMADDFP", SDTFPTernaryOp, []>;
|
||||||
def PPCvnmsubfp : SDNode<"PPCISD::VNMSUBFP", SDTFPTernaryOp, []>;
|
def PPCvnmsubfp : SDNode<"PPCISD::VNMSUBFP", SDTFPTernaryOp, []>;
|
||||||
|
|
||||||
def PPCldGotTprel : SDNode<"PPCISD::LD_GOT_TPREL", SDTIntBinOp, [SDNPMayLoad]>;
|
def PPCaddisGotTprelHA : SDNode<"PPCISD::ADDIS_GOT_TPREL_HA", SDTIntBinOp>;
|
||||||
|
def PPCldGotTprelL : SDNode<"PPCISD::LD_GOT_TPREL_L", SDTIntBinOp,
|
||||||
|
[SDNPMayLoad]>;
|
||||||
def PPCaddTls : SDNode<"PPCISD::ADD_TLS", SDTIntBinOp, []>;
|
def PPCaddTls : SDNode<"PPCISD::ADD_TLS", SDTIntBinOp, []>;
|
||||||
def PPCaddisTlsgdHA : SDNode<"PPCISD::ADDIS_TLSGD_HA", SDTIntBinOp>;
|
def PPCaddisTlsgdHA : SDNode<"PPCISD::ADDIS_TLSGD_HA", SDTIntBinOp>;
|
||||||
def PPCaddiTlsgdL : SDNode<"PPCISD::ADDI_TLSGD_L", SDTIntBinOp>;
|
def PPCaddiTlsgdL : SDNode<"PPCISD::ADDI_TLSGD_L", SDTIntBinOp>;
|
||||||
|
@ -24,9 +24,13 @@ entry:
|
|||||||
; CHECK: Relocation 0
|
; CHECK: Relocation 0
|
||||||
; CHECK-NEXT: 'r_offset'
|
; CHECK-NEXT: 'r_offset'
|
||||||
; CHECK-NEXT: 'r_sym', 0x[[SYM1:[0-9a-f]+]]
|
; CHECK-NEXT: 'r_sym', 0x[[SYM1:[0-9a-f]+]]
|
||||||
; CHECK-NEXT: 'r_type', 0x00000057
|
; CHECK-NEXT: 'r_type', 0x0000005a
|
||||||
; CHECK: Relocation 1
|
; CHECK: Relocation 1
|
||||||
; CHECK-NEXT: 'r_offset'
|
; CHECK-NEXT: 'r_offset'
|
||||||
; CHECK-NEXT: 'r_sym', 0x[[SYM1]]
|
; CHECK-NEXT: 'r_sym', 0x[[SYM1]]
|
||||||
|
; CHECK-NEXT: 'r_type', 0x00000058
|
||||||
|
; CHECK: Relocation 2
|
||||||
|
; CHECK-NEXT: 'r_offset'
|
||||||
|
; CHECK-NEXT: 'r_sym', 0x[[SYM1]]
|
||||||
; CHECK-NEXT: 'r_type', 0x00000043
|
; CHECK-NEXT: 'r_type', 0x00000043
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ entry:
|
|||||||
ret i32 %0
|
ret i32 %0
|
||||||
}
|
}
|
||||||
|
|
||||||
; CHECK: ld [[REG:[0-9]+]], a@got@tprel(2)
|
; CHECK: addis [[REG1:[0-9]+]], 2, a@got@tprel@ha
|
||||||
; CHECK: add {{[0-9]+}}, [[REG]], a@tls
|
; CHECK: ld [[REG2:[0-9]+]], a@got@tprel@l([[REG1]])
|
||||||
|
; CHECK: add {{[0-9]+}}, [[REG2]], a@tls
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user