forked from OSchip/llvm-project
[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:
parent
48e1434a0a
commit
ff99f3a5c0
|
@ -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())
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue