mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
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:
parent
4a4fdf3476
commit
ca0747917d
@ -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>;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user