diff options
author | Petar Jovanovic <petarj@mips.com> | 2012-12-28 00:49:00 +0100 |
---|---|---|
committer | Petar Jovanovic <petarj@mips.com> | 2013-01-05 03:23:55 +0100 |
commit | b835840cf112a6178506d834b58aa625f59a8994 (patch) | |
tree | 98736b450f315db3c432ca046745930f60ebd803 | |
parent | b9f96a12aa2526fcb8459d6b68bf3279372d7eca (diff) |
[MIPS] Add support for nacl-expand-tls pass on MIPS.
Implementation of llvm.nacl.read.tp and support for nacl-expand-tls for MIPS.
Also, calculation of thread pointer is now aware of TLSUseCall flag.
Small fix (make T6, T7 and T8 unavailable as argument registers) for FastCC
added too.
BUG= https://code.google.com/p/nativeclient/issues/detail?id=2275
TEST= build nexe for MIPS32 target with nacl-expand-tls option.
Review URL: https://codereview.chromium.org/11695002
-rw-r--r-- | lib/Target/Mips/MipsCallingConv.td | 9 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 54 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.h | 1 | ||||
-rw-r--r-- | lib/Target/Mips/MipsSubtarget.h | 5 |
4 files changed, 50 insertions, 19 deletions
diff --git a/lib/Target/Mips/MipsCallingConv.td b/lib/Target/Mips/MipsCallingConv.td index 78cf140def..de3a855898 100644 --- a/lib/Target/Mips/MipsCallingConv.td +++ b/lib/Target/Mips/MipsCallingConv.td @@ -186,8 +186,13 @@ def CC_Mips_FastCC : CallingConv<[ // Integer arguments are passed in integer registers. All scratch registers, // except for AT, V0 and T9, are available to be used as argument registers. - CCIfType<[i32], CCAssignToReg<[A0, A1, A2, A3, T0, T1, T2, T3, T4, T5, T6, - T7, T8, V1]>>, + // @LOCALMOD-START + CCIfType<[i32], CCIfSubtarget<"isNotTargetNaCl()", + CCAssignToReg<[A0, A1, A2, A3, T0, T1, T2, T3, T4, T5, T6, T7, T8, V1]>>>, + // T6, T7 and T8 are reserved in NaCl and not available as argument registers. + CCIfType<[i32], CCIfSubtarget<"isTargetNaCl()", + CCAssignToReg<[A0, A1, A2, A3, T0, T1, T2, T3, T4, T5, V1]>>>, + // @LOCALMOD-END // f32 arguments are passed in single-precision floating pointer registers. CCIfType<[f32], CCAssignToReg<[F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index 2e7b144165..61e255ecdb 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -387,7 +387,12 @@ MipsTargetLowering(MipsTargetMachine &TM) setOperationAction(ISD::VACOPY, MVT::Other, Expand); setOperationAction(ISD::VAEND, MVT::Other, Expand); - setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom); + // @LOCALMOD-BEGIN + if (Subtarget->isTargetNaCl()) + setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); + else + setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom); + // @LOCALMOD-END setOperationAction(ISD::INTRINSIC_W_CHAIN, MVT::i64, Custom); // Use the default for now @@ -1875,6 +1880,30 @@ SDValue MipsTargetLowering::LowerNaClTpTdbOffset(SDValue Op, DAG.getConstant(0, Op.getValueType().getSimpleVT()), Op.getOperand(0)); } + +SDValue MipsTargetLowering:: +GetNaClThreadPointer(SelectionDAG &DAG, DebugLoc DL) const { + EVT PtrVT = getPointerTy(); + SDValue ThreadPointer; + if (llvm::TLSUseCall) { + unsigned PtrSize = PtrVT.getSizeInBits(); + IntegerType *PtrTy = Type::getIntNTy(*DAG.getContext(), PtrSize); + + SDValue TlsReadTp = DAG.getExternalSymbol("__nacl_read_tp", PtrVT); + + ArgListTy Args; + TargetLowering::CallLoweringInfo CLI( + DAG.getEntryNode(), PtrTy, false, false, false, false, 0, + CallingConv::C, /*isTailCall=*/false, /*doesNotRet=*/false, + /*isReturnValueUsed=*/true, TlsReadTp, Args, DAG, DL); + std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI); + ThreadPointer = CallResult.first; + } else { + ThreadPointer = DAG.getCopyFromReg(DAG.getEntryNode(), DL, + Mips::T8, PtrVT); + } + return ThreadPointer; +} // @LOCALMOD-END SDValue MipsTargetLowering:: @@ -1892,7 +1921,7 @@ LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const TLSModel::Model model = getTargetMachine().getTLSModel(GV); // @LOCALMOD-BEGIN - if (getTargetMachine().getSubtarget<MipsSubtarget>().isTargetNaCl()) { + if (Subtarget->isTargetNaCl()) { SDVTList VTs = DAG.getVTList(MVT::i32); SDValue TGAHi = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, 0, MipsII::MO_TPREL_HI); @@ -1902,20 +1931,9 @@ LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, TGALo); SDValue Offset = DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, Lo); - unsigned PtrSize = PtrVT.getSizeInBits(); - IntegerType *PtrTy = Type::getIntNTy(*DAG.getContext(), PtrSize); - - SDValue TlsReadTp = DAG.getExternalSymbol("__nacl_read_tp", PtrVT); - - ArgListTy Args; - TargetLowering::CallLoweringInfo CLI(DAG.getEntryNode(), PtrTy, - false, false, false, false, 0, CallingConv::C, - /*isTailCall=*/false, /*doesNotRet=*/false, - /*isReturnValueUsed=*/true, - TlsReadTp, Args, DAG, dl); - std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI); - - SDValue ThreadPointer = CallResult.first; + SDValue ThreadPointer = GetNaClThreadPointer(DAG, dl); + // tprel_hi and tprel_lo relocations expect that thread pointer is offset + // by 0x7000 from the start of the TLS data area. SDValue TPOffset = DAG.getConstant(0x7000, MVT::i32); SDValue ThreadPointer2 = DAG.getNode(ISD::ADD, dl, PtrVT, ThreadPointer, TPOffset); @@ -2508,6 +2526,10 @@ SDValue MipsTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, switch (cast<ConstantSDNode>(Op->getOperand(0))->getZExtValue()) { default: return SDValue(); + // @LOCALMOD-BEGIN + case Intrinsic::nacl_read_tp: + return GetNaClThreadPointer(DAG, Op->getDebugLoc()); + // @LOCALMOD-END case Intrinsic::mips_shilo: return LowerDSPIntr(Op, DAG, MipsISD::SHILO, true, true); case Intrinsic::mips_dpau_h_qbl: diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 0db15cf53f..b57dff2d39 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -307,6 +307,7 @@ namespace llvm { // @LOCALMOD-BEGIN SDValue LowerNaClTpTlsOffset(SDValue Op, SelectionDAG &DAG) const; SDValue LowerNaClTpTdbOffset(SDValue Op, SelectionDAG &DAG) const; + SDValue GetNaClThreadPointer(SelectionDAG &DAG, DebugLoc DL) const; // @LOCALMOD-END virtual SDValue diff --git a/lib/Target/Mips/MipsSubtarget.h b/lib/Target/Mips/MipsSubtarget.h index f8fd0490fa..44678daaa9 100644 --- a/lib/Target/Mips/MipsSubtarget.h +++ b/lib/Target/Mips/MipsSubtarget.h @@ -157,7 +157,10 @@ public: bool hasBitCount() const { return HasBitCount; } bool hasFPIdx() const { return HasFPIdx; } - bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } // @LOCALMOD + // @LOCALMOD-START + bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); } + bool isNotTargetNaCl() const { return !TargetTriple.isOSNaCl(); } + // @LOCALMOD-END }; } // End llvm namespace |