[Systemz/z/OS] Centralize emitting the call type information

With XPLINK, a no-op with information about the call type is emitted
after each call instruction. Centralizing it has the advantage that it is
easy to document all cases, and it makes it easier to extend it later
(e.g. dynamic stack allocation, 32 bit mode).
Also add a test checking the call types emitted so far.

Reviewed By: uweigand

Differential Revision: https://reviews.llvm.org/D119557
This commit is contained in:
Kai Nacke 2022-02-14 11:17:56 -05:00
parent 22bd65fbe7
commit 62ba528a68
3 changed files with 44 additions and 6 deletions

View File

@ -124,6 +124,18 @@ static MCInst lowerSubvectorStore(const MachineInstr *MI, unsigned Opcode) {
.addImm(0);
}
// The XPLINK ABI requires that a no-op encoding the call type is emitted after
// each call to a subroutine. This information can be used by the called
// function to determine its entry point, e.g. for generating a backtrace. The
// call type is encoded as a register number in the bcr instruction. See
// enumeration CallType for the possible values.
void SystemZAsmPrinter::emitCallInformation(CallType CT) {
EmitToStreamer(*OutStreamer,
MCInstBuilder(SystemZ::BCRAsm)
.addImm(0)
.addReg(SystemZMC::GR64Regs[static_cast<unsigned>(CT)]));
}
void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) {
SystemZMCInstLower Lower(MF->getContext(), *this);
MCInst LoweredMI;
@ -234,18 +246,14 @@ void SystemZAsmPrinter::emitInstruction(const MachineInstr *MI) {
.addReg(SystemZ::R7D)
.addExpr(Lower.getExpr(MI->getOperand(0),
MCSymbolRefExpr::VK_PLT)));
EmitToStreamer(
*OutStreamer,
MCInstBuilder(SystemZ::BCRAsm).addImm(0).addReg(SystemZ::R3D));
emitCallInformation(CallType::BRASL7);
return;
case SystemZ::CallBASR_XPLINK64:
EmitToStreamer(*OutStreamer, MCInstBuilder(SystemZ::BASR)
.addReg(SystemZ::R7D)
.addReg(MI->getOperand(0).getReg()));
EmitToStreamer(
*OutStreamer,
MCInstBuilder(SystemZ::BCRAsm).addImm(0).addReg(SystemZ::R0D));
emitCallInformation(CallType::BASR76);
return;
case SystemZ::CallBRASL:

View File

@ -33,6 +33,18 @@ private:
return static_cast<SystemZTargetStreamer *>(TS);
}
/// Call type information for XPLINK.
enum class CallType {
BASR76 = 0, // b'x000' == BASR r7,r6
BRAS7 = 1, // b'x001' == BRAS r7,ep
RESVD_2 = 2, // b'x010'
BRASL7 = 3, // b'x011' == BRASL r7,ep
RESVD_4 = 4, // b'x100'
RESVD_5 = 5, // b'x101'
BALR1415 = 6, // b'x110' == BALR r14,r15
BASR33 = 7, // b'x111' == BASR r3,r3
};
public:
SystemZAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
: AsmPrinter(TM, std::move(Streamer)), SM(*this) {}
@ -54,6 +66,7 @@ public:
void emitFunctionEntryLabel() override;
private:
void emitCallInformation(CallType CT);
void LowerFENTRY_CALL(const MachineInstr &MI, SystemZMCInstLower &MCIL);
void LowerSTACKMAP(const MachineInstr &MI);
void LowerPATCHPOINT(const MachineInstr &MI, SystemZMCInstLower &Lower);

View File

@ -0,0 +1,17 @@
; RUN: llc --mtriple=s390x-ibm-zos --show-mc-encoding < %s | FileCheck %s
define internal signext i32 @caller() {
entry:
ret i32 0
}
define hidden signext i32 @caller2() {
entry:
; CHECK-LABEL: caller2:
; CHECK: brasl 7, caller@PLT * encoding: [0xc0,0x75,A,A,A,A]
; CHECK-NEXT: * fixup A - offset: 2, value: caller@PLT+2, kind: FK_390_PC32DBL
; CHECK-NEXT: bcr 0, 3 * encoding: [0x07,0x03]
%call = call signext i32 @caller()
ret i32 %call
}