@@ -1544,6 +1544,9 @@ const char *SparcTargetLowering::getTargetNodeName(unsigned Opcode) const {
1544
1544
case SPISD::RET_FLAG: return " SPISD::RET_FLAG" ;
1545
1545
case SPISD::GLOBAL_BASE_REG: return " SPISD::GLOBAL_BASE_REG" ;
1546
1546
case SPISD::FLUSHW: return " SPISD::FLUSHW" ;
1547
+ case SPISD::TLS_ADD: return " SPISD::TLS_ADD" ;
1548
+ case SPISD::TLS_LD: return " SPISD::TLS_LD" ;
1549
+ case SPISD::TLS_CALL: return " SPISD::TLS_CALL" ;
1547
1550
}
1548
1551
}
1549
1552
@@ -1699,6 +1702,103 @@ SDValue SparcTargetLowering::LowerBlockAddress(SDValue Op,
1699
1702
return makeAddress (Op, DAG);
1700
1703
}
1701
1704
1705
+ SDValue SparcTargetLowering::LowerGlobalTLSAddress (SDValue Op,
1706
+ SelectionDAG &DAG) const {
1707
+
1708
+ GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
1709
+ SDLoc DL (GA);
1710
+ const GlobalValue *GV = GA->getGlobal ();
1711
+ EVT PtrVT = getPointerTy ();
1712
+
1713
+ TLSModel::Model model = getTargetMachine ().getTLSModel (GV);
1714
+
1715
+ if (model == TLSModel::GeneralDynamic || model == TLSModel::LocalDynamic) {
1716
+ unsigned HiTF = ((model == TLSModel::GeneralDynamic)? SPII::MO_TLS_GD_HI22
1717
+ : SPII::MO_TLS_LDM_HI22);
1718
+ unsigned LoTF = ((model == TLSModel::GeneralDynamic)? SPII::MO_TLS_GD_LO10
1719
+ : SPII::MO_TLS_LDM_LO10);
1720
+ unsigned addTF = ((model == TLSModel::GeneralDynamic)? SPII::MO_TLS_GD_ADD
1721
+ : SPII::MO_TLS_LDM_ADD);
1722
+ unsigned callTF = ((model == TLSModel::GeneralDynamic)? SPII::MO_TLS_GD_CALL
1723
+ : SPII::MO_TLS_LDM_CALL);
1724
+
1725
+ SDValue HiLo = makeHiLoPair (Op, HiTF, LoTF, DAG);
1726
+ SDValue Base = DAG.getNode (SPISD::GLOBAL_BASE_REG, DL, PtrVT);
1727
+ SDValue Argument = DAG.getNode (SPISD::TLS_ADD, DL, PtrVT, Base, HiLo,
1728
+ withTargetFlags (Op, addTF, DAG));
1729
+
1730
+ SDValue Chain = DAG.getEntryNode ();
1731
+ SDValue InFlag;
1732
+
1733
+ Chain = DAG.getCALLSEQ_START (Chain, DAG.getIntPtrConstant (1 , true ), DL);
1734
+ Chain = DAG.getCopyToReg (Chain, DL, SP::O0, Argument, InFlag);
1735
+ InFlag = Chain.getValue (1 );
1736
+ SDValue Callee = DAG.getTargetExternalSymbol (" __tls_get_addr" , PtrVT);
1737
+ SDValue Symbol = withTargetFlags (Op, callTF, DAG);
1738
+
1739
+ SDVTList NodeTys = DAG.getVTList (MVT::Other, MVT::Glue);
1740
+ SmallVector<SDValue, 4 > Ops;
1741
+ Ops.push_back (Chain);
1742
+ Ops.push_back (Callee);
1743
+ Ops.push_back (Symbol);
1744
+ Ops.push_back (DAG.getRegister (SP::O0, PtrVT));
1745
+ const uint32_t *Mask = getTargetMachine ()
1746
+ .getRegisterInfo ()->getCallPreservedMask (CallingConv::C);
1747
+ assert (Mask && " Missing call preserved mask for calling convention" );
1748
+ Ops.push_back (DAG.getRegisterMask (Mask));
1749
+ Ops.push_back (InFlag);
1750
+ Chain = DAG.getNode (SPISD::TLS_CALL, DL, NodeTys, &Ops[0 ], Ops.size ());
1751
+ InFlag = Chain.getValue (1 );
1752
+ Chain = DAG.getCALLSEQ_END (Chain, DAG.getIntPtrConstant (1 , true ),
1753
+ DAG.getIntPtrConstant (0 , true ), InFlag, DL);
1754
+ InFlag = Chain.getValue (1 );
1755
+ SDValue Ret = DAG.getCopyFromReg (Chain, DL, SP::O0, PtrVT, InFlag);
1756
+
1757
+ if (model != TLSModel::LocalDynamic)
1758
+ return Ret;
1759
+
1760
+ SDValue Hi = DAG.getNode (SPISD::Hi, DL, PtrVT,
1761
+ withTargetFlags (Op, SPII::MO_TLS_LDO_HIX22, DAG));
1762
+ SDValue Lo = DAG.getNode (SPISD::Lo, DL, PtrVT,
1763
+ withTargetFlags (Op, SPII::MO_TLS_LDO_LOX10, DAG));
1764
+ HiLo = DAG.getNode (ISD::XOR, DL, PtrVT, Hi, Lo);
1765
+ return DAG.getNode (SPISD::TLS_ADD, DL, PtrVT, Ret, HiLo,
1766
+ withTargetFlags (Op, SPII::MO_TLS_LDO_ADD, DAG));
1767
+ }
1768
+
1769
+ if (model == TLSModel::InitialExec) {
1770
+ unsigned ldTF = ((PtrVT == MVT::i64 )? SPII::MO_TLS_IE_LDX
1771
+ : SPII::MO_TLS_IE_LD);
1772
+
1773
+ SDValue Base = DAG.getNode (SPISD::GLOBAL_BASE_REG, DL, PtrVT);
1774
+
1775
+ // GLOBAL_BASE_REG codegen'ed with call. Inform MFI that this
1776
+ // function has calls.
1777
+ MachineFrameInfo *MFI = DAG.getMachineFunction ().getFrameInfo ();
1778
+ MFI->setHasCalls (true );
1779
+
1780
+ SDValue TGA = makeHiLoPair (Op,
1781
+ SPII::MO_TLS_IE_HI22, SPII::MO_TLS_IE_LO10, DAG);
1782
+ SDValue Ptr = DAG.getNode (ISD::ADD, DL, PtrVT, Base, TGA);
1783
+ SDValue Offset = DAG.getNode (SPISD::TLS_LD,
1784
+ DL, PtrVT, Ptr,
1785
+ withTargetFlags (Op, ldTF, DAG));
1786
+ return DAG.getNode (SPISD::TLS_ADD, DL, PtrVT,
1787
+ DAG.getRegister (SP::G7, PtrVT), Offset,
1788
+ withTargetFlags (Op, SPII::MO_TLS_IE_ADD, DAG));
1789
+ }
1790
+
1791
+ assert (model == TLSModel::LocalExec);
1792
+ SDValue Hi = DAG.getNode (SPISD::Hi, DL, PtrVT,
1793
+ withTargetFlags (Op, SPII::MO_TLS_LE_HIX22, DAG));
1794
+ SDValue Lo = DAG.getNode (SPISD::Lo, DL, PtrVT,
1795
+ withTargetFlags (Op, SPII::MO_TLS_LE_LOX10, DAG));
1796
+ SDValue Offset = DAG.getNode (ISD::XOR, DL, PtrVT, Hi, Lo);
1797
+
1798
+ return DAG.getNode (ISD::ADD, DL, PtrVT,
1799
+ DAG.getRegister (SP::G7, PtrVT), Offset);
1800
+ }
1801
+
1702
1802
SDValue
1703
1803
SparcTargetLowering::LowerF128_LibCallArg (SDValue Chain, ArgListTy &Args,
1704
1804
SDValue Arg, SDLoc DL,
@@ -2333,8 +2433,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const {
2333
2433
2334
2434
case ISD::RETURNADDR: return LowerRETURNADDR (Op, DAG, *this );
2335
2435
case ISD::FRAMEADDR: return LowerFRAMEADDR (Op, DAG);
2336
- case ISD::GlobalTLSAddress:
2337
- llvm_unreachable (" TLS not implemented for Sparc." );
2436
+ case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress (Op, DAG);
2338
2437
case ISD::GlobalAddress: return LowerGlobalAddress (Op, DAG);
2339
2438
case ISD::BlockAddress: return LowerBlockAddress (Op, DAG);
2340
2439
case ISD::ConstantPool: return LowerConstantPool (Op, DAG);
0 commit comments