mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-13 23:18:58 +00:00
Add General Dynamic TLS model for X86-64. Some parts looks really ugly (look for tlsaddr pattern),
but should work. Work is in progress, more models will follow git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50630 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
46bb007014
commit
6625eff8ec
@ -347,7 +347,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
|
||||
if (GV->hasExternalWeakLinkage())
|
||||
ExtWeakSymbols.insert(GV);
|
||||
|
||||
|
||||
int Offset = MO.getOffset();
|
||||
if (Offset > 0)
|
||||
O << "+" << Offset;
|
||||
@ -355,7 +355,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
|
||||
O << Offset;
|
||||
|
||||
if (isThreadLocal) {
|
||||
if (TM.getRelocationModel() == Reloc::PIC_)
|
||||
if (TM.getRelocationModel() == Reloc::PIC_ || Subtarget->is64Bit())
|
||||
O << "@TLSGD"; // general dynamic TLS model
|
||||
else
|
||||
if (GV->isDeclaration())
|
||||
|
@ -267,6 +267,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
|
||||
setOperationAction(ISD::JumpTable , MVT::i32 , Custom);
|
||||
setOperationAction(ISD::GlobalAddress , MVT::i32 , Custom);
|
||||
setOperationAction(ISD::GlobalTLSAddress, MVT::i32 , Custom);
|
||||
if (Subtarget->is64Bit())
|
||||
setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
|
||||
setOperationAction(ISD::ExternalSymbol , MVT::i32 , Custom);
|
||||
if (Subtarget->is64Bit()) {
|
||||
setOperationAction(ISD::ConstantPool , MVT::i64 , Custom);
|
||||
@ -4001,10 +4003,10 @@ X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Lower ISD::GlobalTLSAddress using the "general dynamic" model
|
||||
// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 32 bit
|
||||
static SDOperand
|
||||
LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
|
||||
const MVT::ValueType PtrVT) {
|
||||
LowerToTLSGeneralDynamicModel32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
|
||||
const MVT::ValueType PtrVT) {
|
||||
SDOperand InFlag;
|
||||
SDOperand Chain = DAG.getCopyToReg(DAG.getEntryNode(), X86::EBX,
|
||||
DAG.getNode(X86ISD::GlobalBaseReg,
|
||||
@ -4039,6 +4041,39 @@ LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
|
||||
return DAG.getCopyFromReg(Chain, X86::EAX, PtrVT, InFlag);
|
||||
}
|
||||
|
||||
// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit
|
||||
static SDOperand
|
||||
LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
|
||||
const MVT::ValueType PtrVT) {
|
||||
SDOperand InFlag, Chain;
|
||||
|
||||
// emit leaq symbol@TLSGD(%rip), %rdi
|
||||
SDVTList NodeTys = DAG.getVTList(PtrVT, MVT::Other, MVT::Flag);
|
||||
SDOperand TGA = DAG.getTargetGlobalAddress(GA->getGlobal(),
|
||||
GA->getValueType(0),
|
||||
GA->getOffset());
|
||||
SDOperand Ops[] = { DAG.getEntryNode(), TGA};
|
||||
SDOperand Result = DAG.getNode(X86ISD::TLSADDR, NodeTys, Ops, 2);
|
||||
Chain = Result.getValue(1);
|
||||
InFlag = Result.getValue(2);
|
||||
|
||||
// call ___tls_get_addr. This function receives its argument in
|
||||
// the register RDI.
|
||||
Chain = DAG.getCopyToReg(Chain, X86::RDI, Result, InFlag);
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
|
||||
SDOperand Ops1[] = { Chain,
|
||||
DAG.getTargetExternalSymbol("___tls_get_addr",
|
||||
PtrVT),
|
||||
DAG.getRegister(X86::RDI, PtrVT),
|
||||
InFlag };
|
||||
Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops1, 4);
|
||||
InFlag = Chain.getValue(1);
|
||||
|
||||
return DAG.getCopyFromReg(Chain, X86::RAX, PtrVT, InFlag);
|
||||
}
|
||||
|
||||
// Lower ISD::GlobalTLSAddress using the "initial exec" (for no-pic) or
|
||||
// "local exec" model.
|
||||
static SDOperand
|
||||
@ -4066,15 +4101,19 @@ SDOperand
|
||||
X86TargetLowering::LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG) {
|
||||
// TODO: implement the "local dynamic" model
|
||||
// TODO: implement the "initial exec"model for pic executables
|
||||
assert(!Subtarget->is64Bit() && Subtarget->isTargetELF() &&
|
||||
"TLS not implemented for non-ELF and 64-bit targets");
|
||||
assert(Subtarget->isTargetELF() &&
|
||||
"TLS not implemented for non-ELF targets");
|
||||
GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
|
||||
// If the relocation model is PIC, use the "General Dynamic" TLS Model,
|
||||
// otherwise use the "Local Exec"TLS Model
|
||||
if (getTargetMachine().getRelocationModel() == Reloc::PIC_)
|
||||
return LowerToTLSGeneralDynamicModel(GA, DAG, getPointerTy());
|
||||
else
|
||||
return LowerToTLSExecModel(GA, DAG, getPointerTy());
|
||||
if (Subtarget->is64Bit()) {
|
||||
return LowerToTLSGeneralDynamicModel64(GA, DAG, getPointerTy());
|
||||
} else {
|
||||
if (getTargetMachine().getRelocationModel() == Reloc::PIC_)
|
||||
return LowerToTLSGeneralDynamicModel32(GA, DAG, getPointerTy());
|
||||
else
|
||||
return LowerToTLSExecModel(GA, DAG, getPointerTy());
|
||||
}
|
||||
}
|
||||
|
||||
SDOperand
|
||||
|
@ -1102,6 +1102,13 @@ def MOV64ri64i32 : Ii32<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64i32imm:$src),
|
||||
"mov{l}\t{$src, ${dst:subreg32}|${dst:subreg32}, $src}",
|
||||
[(set GR64:$dst, i64immZExt32:$src)]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Thread Local Storage Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def TLS_addr64 : I<0, Pseudo, (outs GR64:$dst), (ins i64imm:$sym),
|
||||
".byte\t0x66; leaq\t${sym:mem}(%rip), $dst; .word\t0x6666; rex64",
|
||||
[(set GR64:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Atomic Instructions
|
||||
|
@ -109,7 +109,7 @@ def X86Wrapper : SDNode<"X86ISD::Wrapper", SDTX86Wrapper>;
|
||||
def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
|
||||
|
||||
def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
|
||||
[SDNPHasChain, SDNPInFlag, SDNPOutFlag]>;
|
||||
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
|
||||
def X86TLStp : SDNode<"X86ISD::THREAD_POINTER", SDT_X86TLSTP, []>;
|
||||
|
||||
def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
|
||||
@ -2500,12 +2500,12 @@ def MOV32_mr : I<0x89, MRMDestMem, (outs), (ins i32mem:$dst, GR32_:$src),
|
||||
//
|
||||
|
||||
let Uses = [EBX] in
|
||||
def TLS_addr : I<0, Pseudo, (outs GR32:$dst), (ins i32imm:$sym),
|
||||
"leal\t${sym:mem}(,%ebx,1), $dst",
|
||||
[(set GR32:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>;
|
||||
def TLS_addr32 : I<0, Pseudo, (outs GR32:$dst), (ins i32imm:$sym),
|
||||
"leal\t${sym:mem}(,%ebx,1), $dst",
|
||||
[(set GR32:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>;
|
||||
|
||||
let AddedComplexity = 10 in
|
||||
def TLS_gs_rr : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$src),
|
||||
def TLS_gs_rr : I<0, Pseudo, (outs GR32:$dst), (ins GR32:$src),
|
||||
"movl\t%gs:($src), $dst",
|
||||
[(set GR32:$dst, (load (add X86TLStp, GR32:$src)))]>;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user