summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp29
-rw-r--r--llvm/lib/MC/MCDwarf.cpp5
-rw-r--r--llvm/lib/MC/MCStreamer.cpp8
3 files changed, 42 insertions, 0 deletions
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index f9dbd5ad3f0..a6c4e282a2d 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -29,6 +29,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include <cctype>
@@ -210,6 +211,8 @@ public:
void EmitCFISameValue(int64_t Register) override;
void EmitCFIRelOffset(int64_t Register, int64_t Offset) override;
void EmitCFIAdjustCfaOffset(int64_t Adjustment) override;
+ void EmitCFIEscape(StringRef Values) override;
+ void EmitCFIGnuArgsSize(int64_t Size) override;
void EmitCFISignalFrame() override;
void EmitCFIUndefined(int64_t Register) override;
void EmitCFIRegister(int64_t Register1, int64_t Register2) override;
@@ -1010,6 +1013,32 @@ void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
EmitEOL();
}
+static void PrintCFIEscape(llvm::formatted_raw_ostream &OS, StringRef Values) {
+ OS << "\t.cfi_escape ";
+ if (!Values.empty()) {
+ size_t e = Values.size() - 1;
+ for (size_t i = 0; i < e; ++i)
+ OS << format("0x%02x", uint8_t(Values[i])) << ", ";
+ OS << format("0x%02x", uint8_t(Values[e]));
+ }
+}
+
+void MCAsmStreamer::EmitCFIEscape(StringRef Values) {
+ MCStreamer::EmitCFIEscape(Values);
+ PrintCFIEscape(OS, Values);
+ EmitEOL();
+}
+
+void MCAsmStreamer::EmitCFIGnuArgsSize(int64_t Size) {
+ MCStreamer::EmitCFIGnuArgsSize(Size);
+
+ uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size };
+ unsigned Len = encodeULEB128(Size, Buffer + 1) + 1;
+
+ PrintCFIEscape(OS, StringRef((const char *)&Buffer[0], Len));
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) {
MCStreamer::EmitCFIDefCfaRegister(Register);
OS << "\t.cfi_def_cfa_register ";
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index 58cf652b68f..e964032b9d2 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -1147,6 +1147,11 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer,
Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);
return;
}
+ case MCCFIInstruction::OpGnuArgsSize: {
+ Streamer.EmitIntValue(dwarf::DW_CFA_GNU_args_size, 1);
+ Streamer.EmitULEB128IntValue(Instr.getOffset());
+ return;
+ }
case MCCFIInstruction::OpEscape:
Streamer.EmitBytes(Instr.getValues());
return;
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 5d7685177b2..1ae1d51f2a3 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -359,6 +359,14 @@ void MCStreamer::EmitCFIEscape(StringRef Values) {
CurFrame->Instructions.push_back(Instruction);
}
+void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) {
+ MCSymbol *Label = EmitCFICommon();
+ MCCFIInstruction Instruction =
+ MCCFIInstruction::createGnuArgsSize(Label, Size);
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+ CurFrame->Instructions.push_back(Instruction);
+}
+
void MCStreamer::EmitCFISignalFrame() {
EnsureValidDwarfFrame();
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
OpenPOWER on IntegriCloud