-//===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output --------------------===//
+//===- lib/MC/MCAsmStreamer.cpp - Text Assembly Output ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#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>
+
using namespace llvm;
namespace {
void EmitCodeAlignment(unsigned ByteAlignment,
unsigned MaxBytesToEmit = 0) override;
- bool EmitValueToOffset(const MCExpr *Offset,
+ void emitValueToOffset(const MCExpr *Offset,
unsigned char Value = 0) override;
void EmitFileDirective(StringRef Filename) override;
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;
void EmitBundleLock(bool AlignToEnd) override;
void EmitBundleUnlock() override;
+ bool EmitRelocDirective(const MCExpr &Offset, StringRef Name,
+ const MCExpr *Expr, SMLoc Loc) override;
+
/// EmitRawText - If this file is backed by an assembly streamer, this dumps
/// the specified string in the output .s file. This capability is
/// indicated by the hasRawTextSupport() predicate.
void MCAsmStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
unsigned Minor, unsigned Update) {
switch (Kind) {
+ case MCVM_WatchOSVersionMin: OS << "\t.watchos_version_min"; break;
+ case MCVM_TvOSVersionMin: OS << "\t.tvos_version_min"; break;
case MCVM_IOSVersionMin: OS << "\t.ios_version_min"; break;
case MCVM_OSXVersionMin: OS << "\t.macosx_version_min"; break;
}
void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) {
- // Common symbols do not belong to any actual section.
- AssignSection(Symbol, nullptr);
-
OS << "\t.comm\t";
Symbol->print(OS, MAI);
OS << ',' << Size;
/// @param Size - The size of the common symbol.
void MCAsmStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlign) {
- // Common symbols do not belong to any actual section.
- AssignSection(Symbol, nullptr);
-
OS << "\t.lcomm\t";
Symbol->print(OS, MAI);
OS << ',' << Size;
void MCAsmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) {
if (Symbol)
- AssignSection(Symbol, Section);
+ AssignFragment(Symbol, &Section->getDummyFragment());
// Note: a .zerofill directive does not switch sections.
OS << ".zerofill ";
// e.g. _a.
void MCAsmStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) {
- AssignSection(Symbol, Section);
+ AssignFragment(Symbol, &Section->getDummyFragment());
assert(Symbol && "Symbol shouldn't be NULL!");
// Instead of using the Section we'll just use the shortcut.
OS << '"';
}
-
void MCAsmStreamer::EmitBytes(StringRef Data) {
assert(getCurrentSection().first &&
"Cannot emit contents before setting section!");
EmitEOL();
}
-
/// EmitFill - Emit NumBytes bytes worth of the value specified by
/// FillValue. This implements directives such as '.space'.
void MCAsmStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) {
1, MaxBytesToEmit);
}
-bool MCAsmStreamer::EmitValueToOffset(const MCExpr *Offset,
+void MCAsmStreamer::emitValueToOffset(const MCExpr *Offset,
unsigned char Value) {
// FIXME: Verify that Offset is associated with the current section.
OS << ".org ";
Offset->print(OS, MAI);
OS << ", " << (unsigned)Value;
EmitEOL();
- return false;
}
-
void MCAsmStreamer::EmitFileDirective(StringRef Filename) {
assert(MAI->hasSingleParameterDotFile());
OS << "\t.file\t";
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 ";
EmitEOL();
}
-void MCAsmStreamer::EmitWinCFIEndProlog(void) {
+void MCAsmStreamer::EmitWinCFIEndProlog() {
MCStreamer::EmitWinCFIEndProlog();
OS << "\t.seh_endprologue";
EmitEOL();
}
+bool MCAsmStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
+ const MCExpr *Expr, SMLoc) {
+ OS << "\t.reloc ";
+ Offset.print(OS, MAI);
+ OS << ", " << Name;
+ if (Expr) {
+ OS << ", ";
+ Expr->print(OS, MAI);
+ }
+ EmitEOL();
+ return false;
+}
+
/// EmitRawText - If this file is backed by an assembly streamer, this dumps
/// the specified string in the output .s file. This capability is
/// indicated by the hasRawTextSupport() predicate.