aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/Mips/MipsCallingConv.td9
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp54
-rw-r--r--lib/Target/Mips/MipsISelLowering.h1
-rw-r--r--lib/Target/Mips/MipsSubtarget.h5
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