@@ -216,6 +216,8 @@ SystemZTargetLowering::SystemZTargetLowering(const TargetMachine &TM,
216216 setOperationAction (ISD::ATOMIC_LOAD_UMAX, MVT::i32 , Custom);
217217 setOperationAction (ISD::ATOMIC_CMP_SWAP, MVT::i32 , Custom);
218218
219+ setOperationAction (ISD::ATOMIC_FENCE, MVT::Other, Custom);
220+
219221 // z10 has instructions for signed but not unsigned FP conversion.
220222 // Handle unsigned 32-bit types as signed 64-bit types.
221223 if (!Subtarget.hasFPExtension ()) {
@@ -987,9 +989,11 @@ LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
987989}
988990
989991static bool canUseSiblingCall (const CCState &ArgCCInfo,
990- SmallVectorImpl<CCValAssign> &ArgLocs) {
992+ SmallVectorImpl<CCValAssign> &ArgLocs,
993+ SmallVectorImpl<ISD::OutputArg> &Outs) {
991994 // Punt if there are any indirect or stack arguments, or if the call
992- // needs the call-saved argument register R6.
995+ // needs the callee-saved argument register R6, or if the call uses
996+ // the callee-saved register arguments SwiftSelf and SwiftError.
993997 for (unsigned I = 0 , E = ArgLocs.size (); I != E; ++I) {
994998 CCValAssign &VA = ArgLocs[I];
995999 if (VA.getLocInfo () == CCValAssign::Indirect)
@@ -999,6 +1003,8 @@ static bool canUseSiblingCall(const CCState &ArgCCInfo,
9991003 unsigned Reg = VA.getLocReg ();
10001004 if (Reg == SystemZ::R6H || Reg == SystemZ::R6L || Reg == SystemZ::R6D)
10011005 return false ;
1006+ if (Outs[I].Flags .isSwiftSelf () || Outs[I].Flags .isSwiftError ())
1007+ return false ;
10021008 }
10031009 return true ;
10041010}
@@ -1032,7 +1038,7 @@ SystemZTargetLowering::LowerCall(CallLoweringInfo &CLI,
10321038
10331039 // We don't support GuaranteedTailCallOpt, only automatically-detected
10341040 // sibling calls.
1035- if (IsTailCall && !canUseSiblingCall (ArgCCInfo, ArgLocs))
1041+ if (IsTailCall && !canUseSiblingCall (ArgCCInfo, ArgLocs, Outs ))
10361042 IsTailCall = false ;
10371043
10381044 // Get a count of how many bytes are to be pushed on the stack.
@@ -1849,7 +1855,7 @@ static unsigned getTestUnderMaskCond(unsigned BitSize, unsigned CCMask,
18491855 if (CCMask == SystemZ::CCMASK_CMP_NE)
18501856 return SystemZ::CCMASK_TM_SOME_1;
18511857 }
1852- if (EffectivelyUnsigned && CmpVal <= Low) {
1858+ if (EffectivelyUnsigned && CmpVal > 0 && CmpVal <= Low) {
18531859 if (CCMask == SystemZ::CCMASK_CMP_LT)
18541860 return SystemZ::CCMASK_TM_ALL_0;
18551861 if (CCMask == SystemZ::CCMASK_CMP_GE)
@@ -2640,6 +2646,57 @@ SDValue SystemZTargetLowering::lowerConstantPool(ConstantPoolSDNode *CP,
26402646 return DAG.getNode (SystemZISD::PCREL_WRAPPER, DL, PtrVT, Result);
26412647}
26422648
2649+ SDValue SystemZTargetLowering::lowerFRAMEADDR (SDValue Op,
2650+ SelectionDAG &DAG) const {
2651+ MachineFunction &MF = DAG.getMachineFunction ();
2652+ MachineFrameInfo *MFI = MF.getFrameInfo ();
2653+ MFI->setFrameAddressIsTaken (true );
2654+
2655+ SDLoc DL (Op);
2656+ unsigned Depth = cast<ConstantSDNode>(Op.getOperand (0 ))->getZExtValue ();
2657+ EVT PtrVT = getPointerTy (DAG.getDataLayout ());
2658+
2659+ // If the back chain frame index has not been allocated yet, do so.
2660+ SystemZMachineFunctionInfo *FI = MF.getInfo <SystemZMachineFunctionInfo>();
2661+ int BackChainIdx = FI->getFramePointerSaveIndex ();
2662+ if (!BackChainIdx) {
2663+ // By definition, the frame address is the address of the back chain.
2664+ BackChainIdx = MFI->CreateFixedObject (8 , -SystemZMC::CallFrameSize, false );
2665+ FI->setFramePointerSaveIndex (BackChainIdx);
2666+ }
2667+ SDValue BackChain = DAG.getFrameIndex (BackChainIdx, PtrVT);
2668+
2669+ // FIXME The frontend should detect this case.
2670+ if (Depth > 0 ) {
2671+ report_fatal_error (" Unsupported stack frame traversal count" );
2672+ }
2673+
2674+ return BackChain;
2675+ }
2676+
2677+ SDValue SystemZTargetLowering::lowerRETURNADDR (SDValue Op,
2678+ SelectionDAG &DAG) const {
2679+ MachineFunction &MF = DAG.getMachineFunction ();
2680+ MachineFrameInfo *MFI = MF.getFrameInfo ();
2681+ MFI->setReturnAddressIsTaken (true );
2682+
2683+ if (verifyReturnAddressArgumentIsConstant (Op, DAG))
2684+ return SDValue ();
2685+
2686+ SDLoc DL (Op);
2687+ unsigned Depth = cast<ConstantSDNode>(Op.getOperand (0 ))->getZExtValue ();
2688+ EVT PtrVT = getPointerTy (DAG.getDataLayout ());
2689+
2690+ // FIXME The frontend should detect this case.
2691+ if (Depth > 0 ) {
2692+ report_fatal_error (" Unsupported stack frame traversal count" );
2693+ }
2694+
2695+ // Return R14D, which has the return address. Mark it an implicit live-in.
2696+ unsigned LinkReg = MF.addLiveIn (SystemZ::R14D, &SystemZ::GR64BitRegClass);
2697+ return DAG.getCopyFromReg (DAG.getEntryNode (), DL, LinkReg, PtrVT);
2698+ }
2699+
26432700SDValue SystemZTargetLowering::lowerBITCAST (SDValue Op,
26442701 SelectionDAG &DAG) const {
26452702 SDLoc DL (Op);
@@ -3031,6 +3088,25 @@ SDValue SystemZTargetLowering::lowerCTPOP(SDValue Op,
30313088 return Op;
30323089}
30333090
3091+ SDValue SystemZTargetLowering::lowerATOMIC_FENCE (SDValue Op,
3092+ SelectionDAG &DAG) const {
3093+ SDLoc DL (Op);
3094+ AtomicOrdering FenceOrdering = static_cast <AtomicOrdering>(
3095+ cast<ConstantSDNode>(Op.getOperand (1 ))->getZExtValue ());
3096+ SynchronizationScope FenceScope = static_cast <SynchronizationScope>(
3097+ cast<ConstantSDNode>(Op.getOperand (2 ))->getZExtValue ());
3098+
3099+ // The only fence that needs an instruction is a sequentially-consistent
3100+ // cross-thread fence.
3101+ if (FenceOrdering == SequentiallyConsistent && FenceScope == CrossThread) {
3102+ return SDValue (DAG.getMachineNode (SystemZ::Serialize, DL, MVT::Other,
3103+ Op.getOperand (0 )), 0 );
3104+ }
3105+
3106+ // MEMBARRIER is a compiler barrier; it codegens to a no-op.
3107+ return DAG.getNode (SystemZISD::MEMBARRIER, DL, MVT::Other, Op.getOperand (0 ));
3108+ }
3109+
30343110// Op is an atomic load. Lower it into a normal volatile load.
30353111SDValue SystemZTargetLowering::lowerATOMIC_LOAD (SDValue Op,
30363112 SelectionDAG &DAG) const {
@@ -4312,6 +4388,10 @@ SDValue SystemZTargetLowering::lowerShift(SDValue Op, SelectionDAG &DAG,
43124388SDValue SystemZTargetLowering::LowerOperation (SDValue Op,
43134389 SelectionDAG &DAG) const {
43144390 switch (Op.getOpcode ()) {
4391+ case ISD::FRAMEADDR:
4392+ return lowerFRAMEADDR (Op, DAG);
4393+ case ISD::RETURNADDR:
4394+ return lowerRETURNADDR (Op, DAG);
43154395 case ISD::BR_CC:
43164396 return lowerBR_CC (Op, DAG);
43174397 case ISD::SELECT_CC:
@@ -4354,6 +4434,8 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op,
43544434 case ISD::CTTZ_ZERO_UNDEF:
43554435 return DAG.getNode (ISD::CTTZ, SDLoc (Op),
43564436 Op.getValueType (), Op.getOperand (0 ));
4437+ case ISD::ATOMIC_FENCE:
4438+ return lowerATOMIC_FENCE (Op, DAG);
43574439 case ISD::ATOMIC_SWAP:
43584440 return lowerATOMIC_LOAD_OP (Op, DAG, SystemZISD::ATOMIC_SWAPW);
43594441 case ISD::ATOMIC_STORE:
@@ -4457,6 +4539,7 @@ const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const {
44574539 OPCODE (SEARCH_STRING);
44584540 OPCODE (IPM);
44594541 OPCODE (SERIALIZE);
4542+ OPCODE (MEMBARRIER);
44604543 OPCODE (TBEGIN);
44614544 OPCODE (TBEGIN_NOFLOAT);
44624545 OPCODE (TEND);
@@ -5218,6 +5301,7 @@ SystemZTargetLowering::emitAtomicLoadMinMax(MachineInstr *MI,
52185301MachineBasicBlock *
52195302SystemZTargetLowering::emitAtomicCmpSwapW (MachineInstr *MI,
52205303 MachineBasicBlock *MBB) const {
5304+
52215305 MachineFunction &MF = *MBB->getParent ();
52225306 const SystemZInstrInfo *TII =
52235307 static_cast <const SystemZInstrInfo *>(Subtarget.getInstrInfo ());
0 commit comments