125 lines
4.1 KiB
C++
125 lines
4.1 KiB
C++
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_CODEGEN_CFIINSTBUILDER_H
|
|
#define LLVM_CODEGEN_CFIINSTBUILDER_H
|
|
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
#include "llvm/CodeGen/TargetInstrInfo.h"
|
|
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
|
#include "llvm/MC/MCDwarf.h"
|
|
|
|
namespace llvm {
|
|
|
|
/// Helper class for creating CFI instructions and inserting them into MIR.
|
|
class CFIInstBuilder {
|
|
MachineFunction &MF;
|
|
MachineBasicBlock &MBB;
|
|
MachineBasicBlock::iterator InsertPt;
|
|
|
|
/// MIFlag to set on a MachineInstr. Typically, FrameSetup or FrameDestroy.
|
|
MachineInstr::MIFlag MIFlag;
|
|
|
|
/// Selects DWARF register numbering: debug or exception handling. Should be
|
|
/// consistent with the choice of the ELF section (.debug_frame or .eh_frame)
|
|
/// where CFI will be encoded.
|
|
bool IsEH;
|
|
|
|
// Cache frequently used variables.
|
|
const TargetRegisterInfo &TRI;
|
|
const MCInstrDesc &CFIID;
|
|
const MIMetadata MIMD; // Default-initialized, no debug location desired.
|
|
|
|
public:
|
|
CFIInstBuilder(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsertPt,
|
|
MachineInstr::MIFlag MIFlag, bool IsEH = true)
|
|
: MF(*MBB.getParent()), MBB(MBB), MIFlag(MIFlag), IsEH(IsEH),
|
|
TRI(*MF.getSubtarget().getRegisterInfo()),
|
|
CFIID(MF.getSubtarget().getInstrInfo()->get(
|
|
TargetOpcode::CFI_INSTRUCTION)) {
|
|
setInsertPoint(InsertPt);
|
|
}
|
|
|
|
CFIInstBuilder(MachineBasicBlock *MBB, MachineInstr::MIFlag MIFlag,
|
|
bool IsEH = true)
|
|
: CFIInstBuilder(*MBB, MBB->end(), MIFlag, IsEH) {}
|
|
|
|
void setInsertPoint(MachineBasicBlock::iterator IP) { InsertPt = IP; }
|
|
|
|
void insertCFIInst(const MCCFIInstruction &CFIInst) const {
|
|
BuildMI(MBB, InsertPt, MIMD, CFIID)
|
|
.addCFIIndex(MF.addFrameInst(CFIInst))
|
|
.setMIFlag(MIFlag);
|
|
}
|
|
|
|
void buildDefCFA(MCRegister Reg, int64_t Offset) const {
|
|
insertCFIInst(MCCFIInstruction::cfiDefCfa(
|
|
nullptr, TRI.getDwarfRegNum(Reg, IsEH), Offset));
|
|
}
|
|
|
|
void buildDefCFARegister(MCRegister Reg) const {
|
|
insertCFIInst(MCCFIInstruction::createDefCfaRegister(
|
|
nullptr, TRI.getDwarfRegNum(Reg, IsEH)));
|
|
}
|
|
|
|
void buildDefCFAOffset(int64_t Offset, MCSymbol *Label = nullptr) const {
|
|
insertCFIInst(MCCFIInstruction::cfiDefCfaOffset(Label, Offset));
|
|
}
|
|
|
|
void buildAdjustCFAOffset(int64_t Adjustment) const {
|
|
insertCFIInst(MCCFIInstruction::createAdjustCfaOffset(nullptr, Adjustment));
|
|
}
|
|
|
|
void buildOffset(MCRegister Reg, int64_t Offset) const {
|
|
insertCFIInst(MCCFIInstruction::createOffset(
|
|
nullptr, TRI.getDwarfRegNum(Reg, IsEH), Offset));
|
|
}
|
|
|
|
void buildNegateRAState() const {
|
|
insertCFIInst(MCCFIInstruction::createNegateRAState(nullptr));
|
|
}
|
|
|
|
void buildNegateRAStateWithPC() const {
|
|
insertCFIInst(MCCFIInstruction::createNegateRAStateWithPC(nullptr));
|
|
}
|
|
|
|
void buildRegister(MCRegister Reg1, MCRegister Reg2) const {
|
|
insertCFIInst(MCCFIInstruction::createRegister(
|
|
nullptr, TRI.getDwarfRegNum(Reg1, IsEH),
|
|
TRI.getDwarfRegNum(Reg2, IsEH)));
|
|
}
|
|
|
|
void buildWindowSave() const {
|
|
insertCFIInst(MCCFIInstruction::createWindowSave(nullptr));
|
|
}
|
|
|
|
void buildRestore(MCRegister Reg) const {
|
|
insertCFIInst(MCCFIInstruction::createRestore(
|
|
nullptr, TRI.getDwarfRegNum(Reg, IsEH)));
|
|
}
|
|
|
|
void buildUndefined(MCRegister Reg) const {
|
|
insertCFIInst(MCCFIInstruction::createUndefined(
|
|
nullptr, TRI.getDwarfRegNum(Reg, IsEH)));
|
|
}
|
|
|
|
void buildSameValue(MCRegister Reg) const {
|
|
insertCFIInst(MCCFIInstruction::createSameValue(
|
|
nullptr, TRI.getDwarfRegNum(Reg, IsEH)));
|
|
}
|
|
|
|
void buildEscape(StringRef Bytes, StringRef Comment = "") const {
|
|
insertCFIInst(
|
|
MCCFIInstruction::createEscape(nullptr, Bytes, SMLoc(), Comment));
|
|
}
|
|
};
|
|
|
|
} // namespace llvm
|
|
|
|
#endif // LLVM_CODEGEN_CFIINSTBUILDER_H
|