[SystemZ/z/OS] Add alias for XPLINK return

The XPLINK return `b 2(7)` has size 4 bytes, while the Linux return
`br 7` only has size 2 bytes. Thus a new alias is required to have correct
instruction byte count. It also fixes the conditional return code.

Reviewed By: uweigand

Differential Revision: https://reviews.llvm.org/D119437
This commit is contained in:
Kai Nacke 2022-02-11 10:24:50 -05:00
parent 48e1434a0a
commit ff99f3a5c0
8 changed files with 53 additions and 26 deletions

View File

@ -126,15 +126,18 @@ static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) {
SystemZMCInstLower Lower(MF->getContext(), *this);
const SystemZSubtarget *Subtarget = &MF->getSubtarget<SystemZSubtarget>();
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 @@ void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) {
.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())

View File

@ -674,6 +674,7 @@ bool SystemZInstrInfo::FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
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 @@ bool SystemZInstrInfo::PredicateInstruction(
.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) {

View File

@ -336,13 +336,25 @@ let isCall = 1, isTerminator = 1, isReturn = 1 in {
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 (bcr <cond>, %r14).
let isReturn = 1, isTerminator = 1, hasCtrlDep = 1, CCMaskFirst = 1, Uses = [CC] in
def CondReturn : Alias<2, (outs), (ins cond4:$valid, cond4:$R1), []>;
// A conditional return instruction (bc <cond>, 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), []>;
}
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 <cond>, %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 {

View File

@ -172,8 +172,8 @@ def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "(Call)?BAS(R)?(_XPLINK6
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

View File

@ -173,8 +173,8 @@ def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "(Call)?BAS(R)?(_XPLINK6
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

View File

@ -173,8 +173,8 @@ def : InstRW<[WLat1, FXa2, FXb, GroupAlone], (instregex "(Call)?BAS(R)?(_XPLINK6
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

View File

@ -151,8 +151,8 @@ def : InstRW<[WLat1, LSU, FXU2, GroupAlone], (instregex "(Call)?BAS(R)?(_XPLINK6
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

View File

@ -156,8 +156,8 @@ def : InstRW<[WLat1, FXU2, LSU, GroupAlone], (instregex "(Call)?BAS(R)?(_XPLINK6
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