diff --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp --- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -126,15 +126,18 @@ void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) { SystemZMCInstLower Lower(MF->getContext(), *this); - const SystemZSubtarget *Subtarget = &MF->getSubtarget(); MCInst LoweredMI; switch (MI->getOpcode()) { case SystemZ::Return: - if (Subtarget->isTargetXPLINK64()) - LoweredMI = - MCInstBuilder(SystemZ::B).addReg(SystemZ::R7D).addImm(2).addReg(0); - else - LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D); + LoweredMI = MCInstBuilder(SystemZ::BR) + .addReg(SystemZ::R14D); + break; + + case SystemZ::Return_XPLINK: + LoweredMI = MCInstBuilder(SystemZ::B) + .addReg(SystemZ::R7D) + .addImm(2) + .addReg(0); break; case SystemZ::CondReturn: @@ -144,6 +147,15 @@ .addReg(SystemZ::R14D); break; + case SystemZ::CondReturn_XPLINK: + LoweredMI = MCInstBuilder(SystemZ::BC) + .addImm(MI->getOperand(0).getImm()) + .addImm(MI->getOperand(1).getImm()) + .addReg(SystemZ::R7D) + .addImm(2) + .addReg(0); + break; + case SystemZ::CRBReturn: LoweredMI = MCInstBuilder(SystemZ::CRB) .addReg(MI->getOperand(0).getReg()) diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp @@ -674,6 +674,7 @@ bool SystemZInstrInfo::isPredicable(const MachineInstr &MI) const { unsigned Opcode = MI.getOpcode(); if (Opcode == SystemZ::Return || + Opcode == SystemZ::Return_XPLINK || Opcode == SystemZ::Trap || Opcode == SystemZ::CallJG || Opcode == SystemZ::CallBR) @@ -731,11 +732,13 @@ .addReg(SystemZ::CC, RegState::Implicit); return true; } - if (Opcode == SystemZ::Return) { - MI.setDesc(get(SystemZ::CondReturn)); + if (Opcode == SystemZ::Return || Opcode == SystemZ::Return_XPLINK) { + MI.setDesc(get(Opcode == SystemZ::Return ? SystemZ::CondReturn + : SystemZ::CondReturn_XPLINK)); MachineInstrBuilder(*MI.getParent()->getParent(), MI) - .addImm(CCValid).addImm(CCMask) - .addReg(SystemZ::CC, RegState::Implicit); + .addImm(CCValid) + .addImm(CCMask) + .addReg(SystemZ::CC, RegState::Implicit); return true; } if (Opcode == SystemZ::CallJG) { diff --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td @@ -336,13 +336,25 @@ def CLGIBCall : Alias<6, (outs), (ins GR64:$R1, imm64zx8:$I2, cond4:$M3, ADDR64:$R4), []>; } -// A return instruction (br %r14) for ELF and (b 2 %r7) for XPLink. -let isReturn = 1, isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in - def Return : Alias<2, (outs), (ins), [(z_retflag)]>; +let Predicates = [IsTargetXPLINK64] in { + // A return instruction (b 2(%r7)). + let isReturn = 1, isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in + def Return_XPLINK : Alias<4, (outs), (ins), [(z_retflag)]>; + + // A conditional return instruction (bc , 2(%r7)). + let isReturn = 1, isTerminator = 1, hasCtrlDep = 1, CCMaskFirst = 1, Uses = [CC] in + def CondReturn_XPLINK : Alias<4, (outs), (ins cond4:$valid, cond4:$R1), []>; +} -// A conditional return instruction (bcr , %r14). -let isReturn = 1, isTerminator = 1, hasCtrlDep = 1, CCMaskFirst = 1, Uses = [CC] in - def CondReturn : Alias<2, (outs), (ins cond4:$valid, cond4:$R1), []>; +let Predicates = [IsTargetELF] in { + // A return instruction (br %r14). + let isReturn = 1, isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in + def Return : Alias<2, (outs), (ins), [(z_retflag)]>; + + // A conditional return instruction (bcr , %r14). + let isReturn = 1, isTerminator = 1, hasCtrlDep = 1, CCMaskFirst = 1, Uses = [CC] in + def CondReturn : Alias<2, (outs), (ins cond4:$valid, cond4:$R1), []>; +} // Fused compare and conditional returns. let isReturn = 1, isTerminator = 1, hasCtrlDep = 1 in { diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td --- a/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ13.td @@ -172,8 +172,8 @@ def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "TLS_(G|L)DCALL$")>; // Return -def : InstRW<[WLat1, FXb, EndGroup], (instregex "Return$")>; -def : InstRW<[WLat1, FXb, NormalGr], (instregex "CondReturn$")>; +def : InstRW<[WLat1, FXb, EndGroup], (instregex "Return(_XPLINK)?$")>; +def : InstRW<[WLat1, FXb, NormalGr], (instregex "CondReturn(_XPLINK)?$")>; //===----------------------------------------------------------------------===// // Move instructions diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ14.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ14.td --- a/llvm/lib/Target/SystemZ/SystemZScheduleZ14.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ14.td @@ -173,8 +173,8 @@ def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "TLS_(G|L)DCALL$")>; // Return -def : InstRW<[WLat1, FXb, EndGroup], (instregex "Return$")>; -def : InstRW<[WLat1, FXb, NormalGr], (instregex "CondReturn$")>; +def : InstRW<[WLat1, FXb, EndGroup], (instregex "Return(_XPLINK)?$")>; +def : InstRW<[WLat1, FXb, NormalGr], (instregex "CondReturn(_XPLINK)?$")>; //===----------------------------------------------------------------------===// // Move instructions diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ15.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ15.td --- a/llvm/lib/Target/SystemZ/SystemZScheduleZ15.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ15.td @@ -173,8 +173,8 @@ def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "TLS_(G|L)DCALL$")>; // Return -def : InstRW<[WLat1, FXb, EndGroup], (instregex "Return$")>; -def : InstRW<[WLat1, FXb, NormalGr], (instregex "CondReturn$")>; +def : InstRW<[WLat1, FXb, EndGroup], (instregex "Return(_XPLINK)?$")>; +def : InstRW<[WLat1, FXb, NormalGr], (instregex "CondReturn(_XPLINK)?$")>; //===----------------------------------------------------------------------===// // Move instructions diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td b/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td --- a/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZ196.td @@ -151,8 +151,8 @@ def : InstRW<[WLat1, LSU, FXU2, GroupAlone], (instregex "TLS_(G|L)DCALL$")>; // Return -def : InstRW<[WLat1, LSU, EndGroup], (instregex "Return$")>; -def : InstRW<[WLat1, LSU, EndGroup], (instregex "CondReturn$")>; +def : InstRW<[WLat1, LSU, EndGroup], (instregex "Return(_XPLINK)?$")>; +def : InstRW<[WLat1, LSU, EndGroup], (instregex "CondReturn(_XPLINK)?$")>; //===----------------------------------------------------------------------===// // Move instructions diff --git a/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td b/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td --- a/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td +++ b/llvm/lib/Target/SystemZ/SystemZScheduleZEC12.td @@ -156,8 +156,8 @@ def : InstRW<[WLat1, FXU2, LSU, GroupAlone], (instregex "TLS_(G|L)DCALL$")>; // Return -def : InstRW<[WLat1, LSU, EndGroup], (instregex "Return$")>; -def : InstRW<[WLat1, LSU, NormalGr], (instregex "CondReturn$")>; +def : InstRW<[WLat1, LSU, EndGroup], (instregex "Return(_XPLINK)?$")>; +def : InstRW<[WLat1, LSU, NormalGr], (instregex "CondReturn(_XPLINK)?$")>; //===----------------------------------------------------------------------===// // Move instructions