mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-12 13:30:51 +00:00
reimplement elf TLS support in terms of addressing modes, eliminating SegmentBaseAddress.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114529 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
33d60d5e56
commit
f93b90c5df
@ -190,8 +190,7 @@ namespace {
|
|||||||
SDNode *SelectAtomic64(SDNode *Node, unsigned Opc);
|
SDNode *SelectAtomic64(SDNode *Node, unsigned Opc);
|
||||||
SDNode *SelectAtomicLoadAdd(SDNode *Node, EVT NVT);
|
SDNode *SelectAtomicLoadAdd(SDNode *Node, EVT NVT);
|
||||||
|
|
||||||
bool MatchSegmentBaseAddress(SDValue N, X86ISelAddressMode &AM);
|
bool MatchLoadInAddress(LoadSDNode *N, X86ISelAddressMode &AM);
|
||||||
bool MatchLoad(SDValue N, X86ISelAddressMode &AM);
|
|
||||||
bool MatchWrapper(SDValue N, X86ISelAddressMode &AM);
|
bool MatchWrapper(SDValue N, X86ISelAddressMode &AM);
|
||||||
bool MatchAddress(SDValue N, X86ISelAddressMode &AM);
|
bool MatchAddress(SDValue N, X86ISelAddressMode &AM);
|
||||||
bool MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
|
bool MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
|
||||||
@ -544,29 +543,27 @@ void X86DAGToDAGISel::EmitFunctionEntryCode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool X86DAGToDAGISel::MatchSegmentBaseAddress(SDValue N,
|
bool X86DAGToDAGISel::MatchLoadInAddress(LoadSDNode *N, X86ISelAddressMode &AM){
|
||||||
X86ISelAddressMode &AM) {
|
SDValue Address = N->getOperand(1);
|
||||||
assert(N.getOpcode() == X86ISD::SegmentBaseAddress);
|
|
||||||
SDValue Segment = N.getOperand(0);
|
// load gs:0 -> GS segment register.
|
||||||
|
// load fs:0 -> FS segment register.
|
||||||
if (AM.Segment.getNode() == 0) {
|
//
|
||||||
AM.Segment = Segment;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool X86DAGToDAGISel::MatchLoad(SDValue N, X86ISelAddressMode &AM) {
|
|
||||||
// This optimization is valid because the GNU TLS model defines that
|
// This optimization is valid because the GNU TLS model defines that
|
||||||
// gs:0 (or fs:0 on X86-64) contains its own address.
|
// gs:0 (or fs:0 on X86-64) contains its own address.
|
||||||
// For more information see http://people.redhat.com/drepper/tls.pdf
|
// For more information see http://people.redhat.com/drepper/tls.pdf
|
||||||
|
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Address))
|
||||||
SDValue Address = N.getOperand(1);
|
if (C->getSExtValue() == 0 && AM.Segment.getNode() == 0 &&
|
||||||
if (Address.getOpcode() == X86ISD::SegmentBaseAddress &&
|
Subtarget->isTargetELF())
|
||||||
!MatchSegmentBaseAddress(Address, AM))
|
switch (N->getPointerInfo().getAddrSpace()) {
|
||||||
return false;
|
case 256:
|
||||||
|
AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
|
||||||
|
return false;
|
||||||
|
case 257:
|
||||||
|
AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,11 +748,6 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case X86ISD::SegmentBaseAddress:
|
|
||||||
if (!MatchSegmentBaseAddress(N, AM))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case X86ISD::Wrapper:
|
case X86ISD::Wrapper:
|
||||||
case X86ISD::WrapperRIP:
|
case X86ISD::WrapperRIP:
|
||||||
if (!MatchWrapper(N, AM))
|
if (!MatchWrapper(N, AM))
|
||||||
@ -763,7 +755,7 @@ bool X86DAGToDAGISel::MatchAddressRecursively(SDValue N, X86ISelAddressMode &AM,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ISD::LOAD:
|
case ISD::LOAD:
|
||||||
if (!MatchLoad(N, AM))
|
if (!MatchLoadInAddress(cast<LoadSDNode>(N), AM))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1151,6 +1143,22 @@ bool X86DAGToDAGISel::SelectAddr(SDNode *Parent, SDValue N, SDValue &Base,
|
|||||||
SDValue &Scale, SDValue &Index,
|
SDValue &Scale, SDValue &Index,
|
||||||
SDValue &Disp, SDValue &Segment) {
|
SDValue &Disp, SDValue &Segment) {
|
||||||
X86ISelAddressMode AM;
|
X86ISelAddressMode AM;
|
||||||
|
|
||||||
|
if (Parent &&
|
||||||
|
// This list of opcodes are all the nodes that have an "addr:$ptr" operand
|
||||||
|
// that are not a MemSDNode, and thus don't have proper addrspace info.
|
||||||
|
Parent->getOpcode() != ISD::PREFETCH &&
|
||||||
|
Parent->getOpcode() != ISD::INTRINSIC_W_CHAIN && // unaligned loads, fixme
|
||||||
|
Parent->getOpcode() != ISD::INTRINSIC_VOID) { // nontemporal stores.
|
||||||
|
unsigned AddrSpace =
|
||||||
|
cast<MemSDNode>(Parent)->getPointerInfo().getAddrSpace();
|
||||||
|
// AddrSpace 256 -> GS, 257 -> FS.
|
||||||
|
if (AddrSpace == 256)
|
||||||
|
AM.Segment = CurDAG->getRegister(X86::GS, MVT::i16);
|
||||||
|
if (AddrSpace == 257)
|
||||||
|
AM.Segment = CurDAG->getRegister(X86::FS, MVT::i16);
|
||||||
|
}
|
||||||
|
|
||||||
if (MatchAddress(N, AM))
|
if (MatchAddress(N, AM))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1163,22 +1171,6 @@ bool X86DAGToDAGISel::SelectAddr(SDNode *Parent, SDValue N, SDValue &Base,
|
|||||||
if (!AM.IndexReg.getNode())
|
if (!AM.IndexReg.getNode())
|
||||||
AM.IndexReg = CurDAG->getRegister(0, VT);
|
AM.IndexReg = CurDAG->getRegister(0, VT);
|
||||||
|
|
||||||
if (Parent &&
|
|
||||||
// This list of opcodes are all the nodes that have an "addr:$ptr" operand
|
|
||||||
// that are not a MemSDNode, and thus don't have proper addrspace info.
|
|
||||||
Parent->getOpcode() != ISD::PREFETCH &&
|
|
||||||
Parent->getOpcode() != ISD::INTRINSIC_W_CHAIN && // unaligned loads, fixme
|
|
||||||
Parent->getOpcode() != ISD::INTRINSIC_VOID) { // nontemporal stores.
|
|
||||||
unsigned AddrSpace =
|
|
||||||
cast<MemSDNode>(Parent)->getPointerInfo().getAddrSpace();
|
|
||||||
// AddrSpace 256 -> GS, 257 -> FS.
|
|
||||||
if (AddrSpace == 256)
|
|
||||||
AM.Segment = CurDAG->getRegister(X86::GS, VT);
|
|
||||||
if (AddrSpace == 257)
|
|
||||||
AM.Segment = CurDAG->getRegister(X86::FS, VT);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
getAddressOperands(AM, Base, Scale, Index, Disp, Segment);
|
getAddressOperands(AM, Base, Scale, Index, Disp, Segment);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -6150,14 +6150,14 @@ static SDValue LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
|
|||||||
const EVT PtrVT, TLSModel::Model model,
|
const EVT PtrVT, TLSModel::Model model,
|
||||||
bool is64Bit) {
|
bool is64Bit) {
|
||||||
DebugLoc dl = GA->getDebugLoc();
|
DebugLoc dl = GA->getDebugLoc();
|
||||||
// Get the Thread Pointer
|
|
||||||
SDValue Base = DAG.getNode(X86ISD::SegmentBaseAddress,
|
// Get the Thread Pointer, which is %gs:0 (32-bit) or %fs:0 (64-bit).
|
||||||
DebugLoc(), PtrVT,
|
Value *Ptr = Constant::getNullValue(Type::getInt8PtrTy(*DAG.getContext(),
|
||||||
DAG.getRegister(is64Bit? X86::FS : X86::GS,
|
is64Bit ? 257 : 256));
|
||||||
MVT::i32));
|
|
||||||
|
|
||||||
SDValue ThreadPointer = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Base,
|
SDValue ThreadPointer = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(),
|
||||||
MachinePointerInfo(), false, false, 0);
|
DAG.getIntPtrConstant(0),
|
||||||
|
MachinePointerInfo(Ptr), false, false, 0);
|
||||||
|
|
||||||
unsigned char OperandFlags = 0;
|
unsigned char OperandFlags = 0;
|
||||||
// Most TLS accesses are not RIP relative, even on x86-64. One exception is
|
// Most TLS accesses are not RIP relative, even on x86-64. One exception is
|
||||||
@ -8845,7 +8845,6 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
|||||||
case X86ISD::FRCP: return "X86ISD::FRCP";
|
case X86ISD::FRCP: return "X86ISD::FRCP";
|
||||||
case X86ISD::TLSADDR: return "X86ISD::TLSADDR";
|
case X86ISD::TLSADDR: return "X86ISD::TLSADDR";
|
||||||
case X86ISD::TLSCALL: return "X86ISD::TLSCALL";
|
case X86ISD::TLSCALL: return "X86ISD::TLSCALL";
|
||||||
case X86ISD::SegmentBaseAddress: return "X86ISD::SegmentBaseAddress";
|
|
||||||
case X86ISD::EH_RETURN: return "X86ISD::EH_RETURN";
|
case X86ISD::EH_RETURN: return "X86ISD::EH_RETURN";
|
||||||
case X86ISD::TC_RETURN: return "X86ISD::TC_RETURN";
|
case X86ISD::TC_RETURN: return "X86ISD::TC_RETURN";
|
||||||
case X86ISD::FNSTCW16m: return "X86ISD::FNSTCW16m";
|
case X86ISD::FNSTCW16m: return "X86ISD::FNSTCW16m";
|
||||||
|
@ -172,9 +172,6 @@ namespace llvm {
|
|||||||
// thunk at the address from an earlier relocation.
|
// thunk at the address from an earlier relocation.
|
||||||
TLSCALL,
|
TLSCALL,
|
||||||
|
|
||||||
// SegmentBaseAddress - The address segment:0
|
|
||||||
SegmentBaseAddress,
|
|
||||||
|
|
||||||
// EH_RETURN - Exception Handling helpers.
|
// EH_RETURN - Exception Handling helpers.
|
||||||
EH_RETURN,
|
EH_RETURN,
|
||||||
|
|
||||||
|
@ -74,8 +74,6 @@ def SDT_X86TLSADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
|
|||||||
|
|
||||||
def SDT_X86TLSCALL : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
|
def SDT_X86TLSCALL : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
|
||||||
|
|
||||||
def SDT_X86SegmentBaseAddress : SDTypeProfile<1, 1, [SDTCisPtrTy<0>]>;
|
|
||||||
|
|
||||||
def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
|
def SDT_X86EHRET : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
|
||||||
|
|
||||||
def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
|
def SDT_X86TCRET : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;
|
||||||
@ -169,8 +167,6 @@ def X86WrapperRIP : SDNode<"X86ISD::WrapperRIP", SDTX86Wrapper>;
|
|||||||
|
|
||||||
def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
|
def X86tlsaddr : SDNode<"X86ISD::TLSADDR", SDT_X86TLSADDR,
|
||||||
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
|
[SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
|
||||||
def X86SegmentBaseAddress : SDNode<"X86ISD::SegmentBaseAddress",
|
|
||||||
SDT_X86SegmentBaseAddress, []>;
|
|
||||||
|
|
||||||
def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
|
def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
|
||||||
[SDNPHasChain]>;
|
[SDNPHasChain]>;
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
@i = external hidden thread_local global i32
|
@i = external hidden thread_local global i32
|
||||||
|
|
||||||
define i32 @f() {
|
define i32 @f() nounwind {
|
||||||
entry:
|
entry:
|
||||||
%tmp1 = load i32* @i
|
%tmp1 = load i32* @i
|
||||||
ret i32 %tmp1
|
ret i32 %tmp1
|
||||||
|
Loading…
Reference in New Issue
Block a user