Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 92 additions & 2 deletions llvm/include/llvm/MC/MCDwarf.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define LLVM_MC_MCDWARF_H

#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
Expand Down Expand Up @@ -514,6 +515,9 @@ class MCCFIInstruction {
OpRestoreState,
OpOffset,
OpLLVMDefAspaceCfa,
OpLLVMDefCfaRegScalableOffset,
OpLLVMRegAtScalableOffsetFromCfa,
OpLLVMRegAtScalableOffsetFromReg,
OpDefCfaRegister,
OpDefCfaOffset,
OpDefCfa,
Expand Down Expand Up @@ -547,6 +551,17 @@ class MCCFIInstruction {
unsigned Register;
unsigned Register2;
} RR;
struct {
unsigned Register;
int64_t ScalableOffset;
int64_t FixedOffset;
} ROO;
struct {
unsigned Register;
unsigned Register2;
int64_t ScalableOffset;
int64_t FixedOffset;
} RROO;
MCSymbol *CfiLabel;
} U;
OpType Operation;
Expand Down Expand Up @@ -579,6 +594,22 @@ class MCCFIInstruction {
U.CfiLabel = CfiLabel;
}

MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, int64_t ScalableOffset,
int64_t FixedOffset, SMLoc Loc, StringRef Comment = "")
: Label(L), Operation(Op), Loc(Loc), Comment(Comment) {
assert(Operation == OpLLVMDefCfaRegScalableOffset ||
Operation == OpLLVMRegAtScalableOffsetFromCfa);
U.ROO = {R, ScalableOffset, FixedOffset};
}

MCCFIInstruction(OpType Op, MCSymbol *L, unsigned R, unsigned R2,
int64_t ScalableOffset, int64_t FixedOffset, SMLoc Loc,
StringRef Comment = "")
: Label(L), Operation(Op), Loc(Loc), Comment(Comment) {
assert(Op == OpLLVMRegAtScalableOffsetFromReg);
U.RROO = {R, R2, ScalableOffset, FixedOffset};
}

public:
/// .cfi_def_cfa defines a rule for computing CFA as: take address from
/// Register and add Offset to it.
Expand Down Expand Up @@ -644,6 +675,41 @@ class MCCFIInstruction {
return MCCFIInstruction(OpRegister, L, Register1, Register2, Loc);
}

/// Create the new rule for calculating cfa: deref(Reg + ScalableOffset * x +
/// FixedOffset) where x is the runtime constant. This is a "pseudo" CFI
/// instruction - each target has to lower it into standard cfi directives.
static MCCFIInstruction
createLLVMDefCfaRegScalableOffset(MCSymbol *L, unsigned Reg,
int64_t ScalableOffset, int64_t FixedOffset,
SMLoc Loc = {}, StringRef Comment = "") {
return MCCFIInstruction(OpLLVMDefCfaRegScalableOffset, L, Reg,
ScalableOffset, FixedOffset, Loc, Comment);
}

/// Create the new rule for calculating the previous value (before the call)
/// of callee-saved register Reg: deref(cfa + ScalableOffset * x +
/// FixedOffset) where x is the runtime constant. This is a "pseudo" CFI
/// instruction - each target has to lower it into standard cfi directives.
static MCCFIInstruction createLLVMRegAtScalableOffsetFromCfa(
MCSymbol *L, unsigned Reg, int64_t ScalableOffset, int64_t FixedOffset,
SMLoc Loc = {}, StringRef Comment = "") {
return MCCFIInstruction(OpLLVMRegAtScalableOffsetFromCfa, L, Reg,
ScalableOffset, FixedOffset, Loc, Comment);
}

static MCCFIInstruction createLLVMRegAtScalableOffsetFromReg(
MCSymbol *L, unsigned Reg, unsigned Reg2, int64_t ScalableOffset,
int64_t FixedOffset, SMLoc Loc = {}, StringRef Comment = "") {
return MCCFIInstruction(OpLLVMRegAtScalableOffsetFromReg, L, Reg, Reg2,
ScalableOffset, FixedOffset, Loc, Comment);
}

/// Create the expression (FrameRegister + Offset) and write it to CFAExpr
static void createRegOffsetExpression(unsigned Reg, unsigned FrameReg,
int64_t ScalableOffset,
int64_t FixedOffset,
SmallString<64> &CFAExpr);

/// .cfi_window_save SPARC register window is saved.
static MCCFIInstruction createWindowSave(MCSymbol *L, SMLoc Loc = {}) {
return MCCFIInstruction(OpWindowSave, L, 0, INT64_C(0), Loc);
Expand Down Expand Up @@ -725,6 +791,10 @@ class MCCFIInstruction {
return U.RR.Register;
if (Operation == OpLLVMDefAspaceCfa)
return U.RIA.Register;
if (Operation == OpLLVMRegAtScalableOffsetFromCfa)
return U.ROO.Register;
if (Operation == OpLLVMRegAtScalableOffsetFromReg)
return U.RROO.Register;
assert(Operation == OpDefCfa || Operation == OpOffset ||
Operation == OpRestore || Operation == OpUndefined ||
Operation == OpSameValue || Operation == OpDefCfaRegister ||
Expand All @@ -733,8 +803,12 @@ class MCCFIInstruction {
}

unsigned getRegister2() const {
assert(Operation == OpRegister);
return U.RR.Register2;
if (Operation == OpRegister)
return U.RR.Register2;
if (Operation == OpLLVMDefCfaRegScalableOffset)
return U.ROO.Register;
assert(Operation == OpLLVMRegAtScalableOffsetFromReg);
return U.RROO.Register2;
}

unsigned getAddressSpace() const {
Expand All @@ -752,6 +826,22 @@ class MCCFIInstruction {
return U.RI.Offset;
}

int64_t getScalableOffset() const {
if (Operation == OpLLVMRegAtScalableOffsetFromReg)
return U.RROO.ScalableOffset;
assert(Operation == OpLLVMDefCfaRegScalableOffset ||
Operation == OpLLVMRegAtScalableOffsetFromCfa);
return U.ROO.ScalableOffset;
}

int64_t getFixedOffset() const {
if (Operation == OpLLVMRegAtScalableOffsetFromReg)
return U.RROO.FixedOffset;
assert(Operation == OpLLVMDefCfaRegScalableOffset ||
Operation == OpLLVMRegAtScalableOffsetFromCfa);
return U.ROO.FixedOffset;
}

MCSymbol *getCfiLabel() const {
assert(Operation == OpLabel);
return U.CfiLabel;
Expand Down
19 changes: 19 additions & 0 deletions llvm/include/llvm/MC/MCStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,25 @@ class LLVM_ABI MCTargetStreamer {
MCStreamer &getStreamer() { return Streamer; }
MCContext &getContext();

virtual void emitCFILLVMDefCfaRegScalableOffset(unsigned Register,
int64_t ScalableOffset,
int64_t FixedOffset,
SMLoc Loc = {}) {
llvm_unreachable("Not implemented!");
}
virtual void emitCFILLVMRegAtScalableOffsetFromCfa(unsigned Register,
int64_t ScalableOffset,
int64_t FixedOffset,
SMLoc Loc = {}) {
llvm_unreachable("Not implemented!");
}
virtual void emitCFILLVMRegAtScalableOffsetFromReg(unsigned Register,
unsigned Register2,
int64_t ScalableOffset,
int64_t FixedOffset,
SMLoc Loc = {}) {
llvm_unreachable("Not implemented!");
}
// Allow a target to add behavior to the EmitLabel of MCStreamer.
virtual void emitLabel(MCSymbol *Symbol);
// Allow a target to add behavior to the emitAssignment of MCStreamer.
Expand Down
18 changes: 18 additions & 0 deletions llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,24 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
OutStreamer->emitCFILLVMDefAspaceCfa(Inst.getRegister(), Inst.getOffset(),
Inst.getAddressSpace(), Loc);
break;
case MCCFIInstruction::OpLLVMDefCfaRegScalableOffset:
OutStreamer->AddComment(Inst.getComment());
OutStreamer->getTargetStreamer()->emitCFILLVMDefCfaRegScalableOffset(
Inst.getRegister2(), Inst.getScalableOffset(), Inst.getFixedOffset(),
Loc);
break;
case MCCFIInstruction::OpLLVMRegAtScalableOffsetFromCfa:
OutStreamer->AddComment(Inst.getComment());
OutStreamer->getTargetStreamer()->emitCFILLVMRegAtScalableOffsetFromCfa(
Inst.getRegister(), Inst.getScalableOffset(), Inst.getFixedOffset(),
Loc);
break;
case MCCFIInstruction::OpLLVMRegAtScalableOffsetFromReg:
OutStreamer->AddComment(Inst.getComment());
OutStreamer->getTargetStreamer()->emitCFILLVMRegAtScalableOffsetFromReg(
Inst.getRegister(), Inst.getRegister2(), Inst.getScalableOffset(),
Inst.getFixedOffset(), Loc);
break;
case MCCFIInstruction::OpOffset:
OutStreamer->emitCFIOffset(Inst.getRegister(), Inst.getOffset(), Loc);
break;
Expand Down
Loading
Loading