Index: llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td +++ llvm/trunk/lib/Target/Mips/MicroMipsInstrInfo.td @@ -1172,6 +1172,9 @@ def : MipsPat<(MipsGotHi texternalsym:$in), (LUi_MM texternalsym:$in)>, ISA_MICROMIPS; +def : MipsPat<(MipsTlsHi tglobaltlsaddr:$in), (LUi_MM tglobaltlsaddr:$in)>, + ISA_MICROMIPS; + // gp_rel relocs def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)), (ADDiu_MM GPR32:$gp, tglobaladdr:$in)>, ISA_MICROMIPS; Index: llvm/trunk/lib/Target/Mips/Mips16InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/Mips16InstrInfo.td +++ llvm/trunk/lib/Target/Mips/Mips16InstrInfo.td @@ -1858,11 +1858,12 @@ (SllX16 (LiRxImmX16 tglobaladdr:$in), 16)>; def : Mips16Pat<(MipsHi tjumptable:$in), (SllX16 (LiRxImmX16 tjumptable:$in), 16)>; -def : Mips16Pat<(MipsHi tglobaltlsaddr:$in), - (SllX16 (LiRxImmX16 tglobaltlsaddr:$in), 16)>; def : Mips16Pat<(MipsLo tblockaddress:$in), (LiRxImmX16 tblockaddress:$in)>; +def : Mips16Pat<(MipsTlsHi tglobaltlsaddr:$in), + (SllX16 (LiRxImmX16 tglobaltlsaddr:$in), 16)>; + // wrapper_pic class Wrapper16Pat: Mips16Pat<(MipsWrapper RC:$gp, node:$in), Index: llvm/trunk/lib/Target/Mips/Mips64InstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/Mips64InstrInfo.td +++ llvm/trunk/lib/Target/Mips/Mips64InstrInfo.td @@ -629,6 +629,9 @@ def : MipsPat<(MipsGotHi texternalsym:$in), (LUi64 texternalsym:$in)>, ISA_MIPS3, GPR_64; +def : MipsPat<(MipsTlsHi tglobaltlsaddr:$in), (LUi64 tglobaltlsaddr:$in)>, + ISA_MIPS3, GPR_64; + // highest/higher/hi/lo relocs let AdditionalPredicates = [NotInMicroMips] in { def : MipsPat<(MipsJmpLink (i64 texternalsym:$dst)), @@ -641,8 +644,6 @@ (LUi64 tjumptable:$in)>, ISA_MIPS3, GPR_64, SYM_64; def : MipsPat<(MipsHighest (i64 tconstpool:$in)), (LUi64 tconstpool:$in)>, ISA_MIPS3, GPR_64, SYM_64; - def : MipsPat<(MipsHighest (i64 tglobaltlsaddr:$in)), - (LUi64 tglobaltlsaddr:$in)>, ISA_MIPS3, GPR_64, SYM_64; def : MipsPat<(MipsHighest (i64 texternalsym:$in)), (LUi64 texternalsym:$in)>, ISA_MIPS3, GPR_64, SYM_64; @@ -654,9 +655,6 @@ (DADDiu ZERO_64, tjumptable:$in)>, ISA_MIPS3, GPR_64, SYM_64; def : MipsPat<(MipsHigher (i64 tconstpool:$in)), (DADDiu ZERO_64, tconstpool:$in)>, ISA_MIPS3, GPR_64, SYM_64; - def : MipsPat<(MipsHigher (i64 tglobaltlsaddr:$in)), - (DADDiu ZERO_64, tglobaltlsaddr:$in)>, ISA_MIPS3, GPR_64, - SYM_64; def : MipsPat<(MipsHigher (i64 texternalsym:$in)), (DADDiu ZERO_64, texternalsym:$in)>, ISA_MIPS3, GPR_64, SYM_64; @@ -669,9 +667,6 @@ (DADDiu GPR64:$hi, tjumptable:$lo)>, ISA_MIPS3, GPR_64, SYM_64; def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tconstpool:$lo))), (DADDiu GPR64:$hi, tconstpool:$lo)>, ISA_MIPS3, GPR_64, SYM_64; - def : MipsPat<(add GPR64:$hi, (MipsHigher (i64 tglobaltlsaddr:$lo))), - (DADDiu GPR64:$hi, tglobaltlsaddr:$lo)>, ISA_MIPS3, GPR_64, - SYM_64; def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tglobaladdr:$lo))), (DADDiu GPR64:$hi, tglobaladdr:$lo)>, ISA_MIPS3, GPR_64, SYM_64; @@ -682,9 +677,6 @@ (DADDiu GPR64:$hi, tjumptable:$lo)>, ISA_MIPS3, GPR_64, SYM_64; def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tconstpool:$lo))), (DADDiu GPR64:$hi, tconstpool:$lo)>, ISA_MIPS3, GPR_64, SYM_64; - def : MipsPat<(add GPR64:$hi, (MipsHi (i64 tglobaltlsaddr:$lo))), - (DADDiu GPR64:$hi, tglobaltlsaddr:$lo)>, ISA_MIPS3, GPR_64, - SYM_64; def : MipsPat<(add GPR64:$hi, (MipsLo (i64 tglobaladdr:$lo))), (DADDiu GPR64:$hi, tglobaladdr:$lo)>, ISA_MIPS3, GPR_64, SYM_64; Index: llvm/trunk/lib/Target/Mips/MipsISelLowering.h =================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.h +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.h @@ -84,6 +84,9 @@ // Get the High 16 bits from a 32 bit immediate for accessing the GOT. GotHi, + // Get the High 16 bits from a 32-bit immediate for accessing TLS. + TlsHi, + // Handle gp_rel (small data/bss sections) relocation. GPRel, Index: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp @@ -189,6 +189,7 @@ case MipsISD::Hi: return "MipsISD::Hi"; case MipsISD::Lo: return "MipsISD::Lo"; case MipsISD::GotHi: return "MipsISD::GotHi"; + case MipsISD::TlsHi: return "MipsISD::TlsHi"; case MipsISD::GPRel: return "MipsISD::GPRel"; case MipsISD::ThreadPointer: return "MipsISD::ThreadPointer"; case MipsISD::Ret: return "MipsISD::Ret"; @@ -2040,7 +2041,7 @@ SDValue TGAHi = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, MipsII::MO_DTPREL_HI); - SDValue Hi = DAG.getNode(MipsISD::Hi, DL, PtrVT, TGAHi); + SDValue Hi = DAG.getNode(MipsISD::TlsHi, DL, PtrVT, TGAHi); SDValue TGALo = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, MipsII::MO_DTPREL_LO); SDValue Lo = DAG.getNode(MipsISD::Lo, DL, PtrVT, TGALo); @@ -2064,7 +2065,7 @@ MipsII::MO_TPREL_HI); SDValue TGALo = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, MipsII::MO_TPREL_LO); - SDValue Hi = DAG.getNode(MipsISD::Hi, DL, PtrVT, TGAHi); + SDValue Hi = DAG.getNode(MipsISD::TlsHi, DL, PtrVT, TGAHi); SDValue Lo = DAG.getNode(MipsISD::Lo, DL, PtrVT, TGALo); Offset = DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo); } Index: llvm/trunk/lib/Target/Mips/MipsInstrInfo.td =================================================================== --- llvm/trunk/lib/Target/Mips/MipsInstrInfo.td +++ llvm/trunk/lib/Target/Mips/MipsInstrInfo.td @@ -73,12 +73,8 @@ // Hi node for accessing the GOT. def MipsGotHi : SDNode<"MipsISD::GotHi", SDTIntUnaryOp>; -// TlsGd node is used to handle General Dynamic TLS -def MipsTlsGd : SDNode<"MipsISD::TlsGd", SDTIntUnaryOp>; - -// TprelHi and TprelLo nodes are used to handle Local Exec TLS -def MipsTprelHi : SDNode<"MipsISD::TprelHi", SDTIntUnaryOp>; -def MipsTprelLo : SDNode<"MipsISD::TprelLo", SDTIntUnaryOp>; +// Hi node for handling TLS offsets +def MipsTlsHi : SDNode<"MipsISD::TlsHi", SDTIntUnaryOp>; // Thread pointer def MipsThreadPointer: SDNode<"MipsISD::ThreadPointer", SDT_MipsThreadPointer>; @@ -3074,7 +3070,6 @@ def : MipsPat<(MipsHi tblockaddress:$in), (Lui tblockaddress:$in)>; def : MipsPat<(MipsHi tjumptable:$in), (Lui tjumptable:$in)>; def : MipsPat<(MipsHi tconstpool:$in), (Lui tconstpool:$in)>; - def : MipsPat<(MipsHi tglobaltlsaddr:$in), (Lui tglobaltlsaddr:$in)>; def : MipsPat<(MipsHi texternalsym:$in), (Lui texternalsym:$in)>; def : MipsPat<(MipsLo tglobaladdr:$in), (Addiu ZeroReg, tglobaladdr:$in)>; @@ -3109,6 +3104,9 @@ def : MipsPat<(MipsGotHi texternalsym:$in), (LUi texternalsym:$in)>, ISA_MIPS1; + def : MipsPat<(MipsTlsHi tglobaltlsaddr:$in), (LUi tglobaltlsaddr:$in)>, + ISA_MIPS1; + // gp_rel relocs def : MipsPat<(add GPR32:$gp, (MipsGPRel tglobaladdr:$in)), (ADDiu GPR32:$gp, tglobaladdr:$in)>, ISA_MIPS1, ABI_NOT_N64; Index: llvm/trunk/test/CodeGen/Mips/tls.ll =================================================================== --- llvm/trunk/test/CodeGen/Mips/tls.ll +++ llvm/trunk/test/CodeGen/Mips/tls.ll @@ -137,10 +137,11 @@ ; PIC64: daddiu $4, $[[R1]], %tlsldm(f3.i) ; PIC64: ld $25, %call16(__tls_get_addr)($[[R1]]) ; PIC64: jalr $25 -; PIC64: daddiu $[[R0:[0-9]+]], $2, %dtprel_hi(f3.i) -; PIC64: lw $[[R1:[0-9]+]], %dtprel_lo(f3.i)($[[R0]]) -; PIC64: addiu $[[R1]], $[[R1]], 1 -; PIC64: sw $[[R1]], %dtprel_lo(f3.i)($[[R0]]) +; PIC64: lui $[[R0:[0-9]+]], %dtprel_hi(f3.i) +; PIC64: daddu $[[R1:[0-9]+]], $[[R0]], $2 +; PIC64: lw $[[R2:[0-9]+]], %dtprel_lo(f3.i)($[[R1]]) +; PIC64: addiu $[[R2]], $[[R2]], 1 +; PIC64: sw $[[R2]], %dtprel_lo(f3.i)($[[R1]]) ; MM-LABEL: f3: ; MM: addiu $4, ${{[a-z0-9]+}}, %tlsldm(f3.i)