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;
(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<SDNode node, Instruction ADDiuOp, RegisterClass RC>:
Mips16Pat<(MipsWrapper RC:$gp, node:$in),
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)),
(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;
(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;
(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;
(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;
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";
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);
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);
}
// 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,
// 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>;
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)>;
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;
; 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)