forked from OSchip/llvm-project
[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:
parent
22bd65fbe7
commit
62ba528a68
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue