Implement 64-bit support for thread local storage handling.

- Modify lowering of global TLS address nodes.
- Modify isel of ThreadPointer.
- Wrap target global TLS address nodes that are operands of loads with WrapperPIC. 
- Remove Mips-specific DAG nodes TlsGd, TprelHi and TprelLo, which can be
  substituted with other existing nodes.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146175 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Akira Hatanaka 2011-12-08 20:34:32 +00:00
parent 4a4fdf3476
commit ca0747917d
5 changed files with 51 additions and 55 deletions

View File

@ -266,11 +266,13 @@ def : Pat<(MipsHi tglobaladdr:$in), (LUi64 tglobaladdr:$in)>;
def : Pat<(MipsHi tblockaddress:$in), (LUi64 tblockaddress:$in)>;
def : Pat<(MipsHi tjumptable:$in), (LUi64 tjumptable:$in)>;
def : Pat<(MipsHi tconstpool:$in), (LUi64 tconstpool:$in)>;
def : Pat<(MipsHi tglobaltlsaddr:$in), (LUi64 tglobaltlsaddr:$in)>;
def : Pat<(MipsLo tglobaladdr:$in), (DADDiu ZERO_64, tglobaladdr:$in)>;
def : Pat<(MipsLo tblockaddress:$in), (DADDiu ZERO_64, tblockaddress:$in)>;
def : Pat<(MipsLo tjumptable:$in), (DADDiu ZERO_64, tjumptable:$in)>;
def : Pat<(MipsLo tconstpool:$in), (DADDiu ZERO_64, tconstpool:$in)>;
def : Pat<(MipsLo tglobaltlsaddr:$in), (DADDiu ZERO_64, tglobaltlsaddr:$in)>;
def : Pat<(add CPU64Regs:$hi, (MipsLo tglobaladdr:$lo)),
(DADDiu CPU64Regs:$hi, tglobaladdr:$lo)>;
@ -280,12 +282,15 @@ def : Pat<(add CPU64Regs:$hi, (MipsLo tjumptable:$lo)),
(DADDiu CPU64Regs:$hi, tjumptable:$lo)>;
def : Pat<(add CPU64Regs:$hi, (MipsLo tconstpool:$lo)),
(DADDiu CPU64Regs:$hi, tconstpool:$lo)>;
def : Pat<(add CPU64Regs:$hi, (MipsLo tglobaltlsaddr:$lo)),
(DADDiu CPU64Regs:$hi, tglobaltlsaddr:$lo)>;
def : WrapperPICPat<tglobaladdr, DADDiu, GP_64>;
def : WrapperPICPat<tconstpool, DADDiu, GP_64>;
def : WrapperPICPat<texternalsym, DADDiu, GP_64>;
def : WrapperPICPat<tblockaddress, DADDiu, GP_64>;
def : WrapperPICPat<tjumptable, DADDiu, GP_64>;
def : WrapperPICPat<tglobaltlsaddr, DADDiu, GP_64>;
defm : BrcondPats<CPU64Regs, BEQ64, BNE64, SLT64, SLTu64, SLTi64, SLTiu64,
ZERO_64>;

View File

@ -121,21 +121,16 @@ SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) {
}
// on PIC code Load GA
if (TM.getRelocationModel() == Reloc::PIC_) {
if (Addr.getOpcode() == MipsISD::WrapperPIC) {
Base = CurDAG->getRegister(GPReg, ValTy);
Offset = Addr.getOperand(0);
return true;
}
} else {
if (Addr.getOpcode() == MipsISD::WrapperPIC) {
Base = CurDAG->getRegister(GPReg, ValTy);
Offset = Addr.getOperand(0);
return true;
}
if (TM.getRelocationModel() != Reloc::PIC_) {
if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
Addr.getOpcode() == ISD::TargetGlobalAddress))
return false;
else if (Addr.getOpcode() == ISD::TargetGlobalTLSAddress) {
Base = CurDAG->getRegister(GPReg, ValTy);
Offset = Addr;
return true;
}
}
// Addresses of the form FI+const or FI|const
@ -309,13 +304,24 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
}
case MipsISD::ThreadPointer: {
unsigned SrcReg = Mips::HWR29;
unsigned DestReg = Mips::V1;
SDNode *Rdhwr = CurDAG->getMachineNode(Mips::RDHWR, Node->getDebugLoc(),
Node->getValueType(0), CurDAG->getRegister(SrcReg, MVT::i32));
EVT PtrVT = TLI.getPointerTy();
unsigned RdhwrOpc, SrcReg, DestReg;
if (PtrVT == MVT::i32) {
RdhwrOpc = Mips::RDHWR;
SrcReg = Mips::HWR29;
DestReg = Mips::V1;
} else {
RdhwrOpc = Mips::RDHWR64;
SrcReg = Mips::HWR29_64;
DestReg = Mips::V1_64;
}
SDNode *Rdhwr = CurDAG->getMachineNode(RdhwrOpc, Node->getDebugLoc(),
Node->getValueType(0), CurDAG->getRegister(SrcReg, PtrVT));
SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, DestReg,
SDValue(Rdhwr, 0));
SDValue ResNode = CurDAG->getCopyFromReg(Chain, dl, DestReg, MVT::i32);
SDValue ResNode = CurDAG->getCopyFromReg(Chain, dl, DestReg, PtrVT);
ReplaceUses(SDValue(Node, 0), ResNode);
return ResNode.getNode();
}

View File

@ -54,9 +54,6 @@ const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {
case MipsISD::Hi: return "MipsISD::Hi";
case MipsISD::Lo: return "MipsISD::Lo";
case MipsISD::GPRel: return "MipsISD::GPRel";
case MipsISD::TlsGd: return "MipsISD::TlsGd";
case MipsISD::TprelHi: return "MipsISD::TprelHi";
case MipsISD::TprelLo: return "MipsISD::TprelLo";
case MipsISD::ThreadPointer: return "MipsISD::ThreadPointer";
case MipsISD::Ret: return "MipsISD::Ret";
case MipsISD::FPBrcond: return "MipsISD::FPBrcond";
@ -129,6 +126,7 @@ MipsTargetLowering(MipsTargetMachine &TM)
setOperationAction(ISD::BlockAddress, MVT::i32, Custom);
setOperationAction(ISD::BlockAddress, MVT::i64, Custom);
setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
setOperationAction(ISD::JumpTable, MVT::i32, Custom);
setOperationAction(ISD::JumpTable, MVT::i64, Custom);
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
@ -1549,23 +1547,22 @@ LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
// General Dynamic TLS Model
SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32,
SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT,
0, MipsII::MO_TLSGD);
SDValue Tlsgd = DAG.getNode(MipsISD::TlsGd, dl, MVT::i32, TGA);
SDValue GP = DAG.getRegister(Mips::GP, MVT::i32);
SDValue Argument = DAG.getNode(ISD::ADD, dl, MVT::i32, GP, Tlsgd);
SDValue Argument = DAG.getNode(MipsISD::WrapperPIC, dl, PtrVT, TGA);
ArgListTy Args;
ArgListEntry Entry;
Entry.Node = Argument;
Entry.Ty = (Type *) Type::getInt32Ty(*DAG.getContext());
unsigned PtrSize = PtrVT.getSizeInBits();
IntegerType *PtrTy = Type::getIntNTy(*DAG.getContext(), PtrSize);
Entry.Ty = PtrTy;
Args.push_back(Entry);
std::pair<SDValue, SDValue> CallResult =
LowerCallTo(DAG.getEntryNode(),
(Type *) Type::getInt32Ty(*DAG.getContext()),
false, false, false, false, 0, CallingConv::C, false, true,
DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG,
dl);
LowerCallTo(DAG.getEntryNode(), PtrTy,
false, false, false, false, 0, CallingConv::C, false, true,
DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG,
dl);
return CallResult.first;
}
@ -1573,21 +1570,21 @@ LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const
SDValue Offset;
if (GV->isDeclaration()) {
// Initial Exec TLS Model
SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0,
SDValue TGA = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
MipsII::MO_GOTTPREL);
Offset = DAG.getLoad(MVT::i32, dl,
TGA = DAG.getNode(MipsISD::WrapperPIC, dl, PtrVT, TGA);
Offset = DAG.getLoad(PtrVT, dl,
DAG.getEntryNode(), TGA, MachinePointerInfo(),
false, false, false, 0);
} else {
// Local Exec TLS Model
SDVTList VTs = DAG.getVTList(MVT::i32);
SDValue TGAHi = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0,
SDValue TGAHi = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
MipsII::MO_TPREL_HI);
SDValue TGALo = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0,
SDValue TGALo = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
MipsII::MO_TPREL_LO);
SDValue Hi = DAG.getNode(MipsISD::TprelHi, dl, VTs, &TGAHi, 1);
SDValue Lo = DAG.getNode(MipsISD::TprelLo, dl, MVT::i32, TGALo);
Offset = DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, Lo);
SDValue Hi = DAG.getNode(MipsISD::Hi, dl, PtrVT, TGAHi);
SDValue Lo = DAG.getNode(MipsISD::Lo, dl, PtrVT, TGALo);
Offset = DAG.getNode(ISD::ADD, dl, PtrVT, Hi, Lo);
}
SDValue ThreadPointer = DAG.getNode(MipsISD::ThreadPointer, dl, PtrVT);

View File

@ -40,13 +40,6 @@ namespace llvm {
// Handle gp_rel (small data/bss sections) relocation.
GPRel,
// General Dynamic TLS
TlsGd,
// Local Exec TLS
TprelHi,
TprelLo,
// Thread Pointer
ThreadPointer,

View File

@ -942,11 +942,13 @@ def : Pat<(MipsHi tglobaladdr:$in), (LUi tglobaladdr:$in)>;
def : Pat<(MipsHi tblockaddress:$in), (LUi tblockaddress:$in)>;
def : Pat<(MipsHi tjumptable:$in), (LUi tjumptable:$in)>;
def : Pat<(MipsHi tconstpool:$in), (LUi tconstpool:$in)>;
def : Pat<(MipsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
def : Pat<(MipsLo tglobaladdr:$in), (ADDiu ZERO, tglobaladdr:$in)>;
def : Pat<(MipsLo tblockaddress:$in), (ADDiu ZERO, tblockaddress:$in)>;
def : Pat<(MipsLo tjumptable:$in), (ADDiu ZERO, tjumptable:$in)>;
def : Pat<(MipsLo tconstpool:$in), (ADDiu ZERO, tconstpool:$in)>;
def : Pat<(MipsLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
def : Pat<(add CPURegs:$hi, (MipsLo tglobaladdr:$lo)),
(ADDiu CPURegs:$hi, tglobaladdr:$lo)>;
@ -956,6 +958,8 @@ def : Pat<(add CPURegs:$hi, (MipsLo tjumptable:$lo)),
(ADDiu CPURegs:$hi, tjumptable:$lo)>;
def : Pat<(add CPURegs:$hi, (MipsLo tconstpool:$lo)),
(ADDiu CPURegs:$hi, tconstpool:$lo)>;
def : Pat<(add CPURegs:$hi, (MipsLo tglobaltlsaddr:$lo)),
(ADDiu CPURegs:$hi, tglobaltlsaddr:$lo)>;
// gp_rel relocs
def : Pat<(add CPURegs:$gp, (MipsGPRel tglobaladdr:$in)),
@ -963,16 +967,6 @@ def : Pat<(add CPURegs:$gp, (MipsGPRel tglobaladdr:$in)),
def : Pat<(add CPURegs:$gp, (MipsGPRel tconstpool:$in)),
(ADDiu CPURegs:$gp, tconstpool:$in)>;
// tlsgd
def : Pat<(add CPURegs:$gp, (MipsTlsGd tglobaltlsaddr:$in)),
(ADDiu CPURegs:$gp, tglobaltlsaddr:$in)>;
// tprel hi/lo
def : Pat<(MipsTprelHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>;
def : Pat<(MipsTprelLo tglobaltlsaddr:$in), (ADDiu ZERO, tglobaltlsaddr:$in)>;
def : Pat<(add CPURegs:$hi, (MipsTprelLo tglobaltlsaddr:$lo)),
(ADDiu CPURegs:$hi, tglobaltlsaddr:$lo)>;
// wrapper_pic
class WrapperPICPat<SDNode node, Instruction ADDiuOp, Register GPReg>:
Pat<(MipsWrapperPIC node:$in),
@ -983,6 +977,7 @@ def : WrapperPICPat<tconstpool, ADDiu, GP>;
def : WrapperPICPat<texternalsym, ADDiu, GP>;
def : WrapperPICPat<tblockaddress, ADDiu, GP>;
def : WrapperPICPat<tjumptable, ADDiu, GP>;
def : WrapperPICPat<tglobaltlsaddr, ADDiu, GP>;
// Mips does not have "not", so we expand our way
def : Pat<(not CPURegs:$in),