summaryrefslogtreecommitdiff
path: root/lib/MC/MCAsmStreamer.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
commit044eb2f6afba375a914ac9d8024f8f5142bb912e (patch)
tree1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/MC/MCAsmStreamer.cpp
parenteb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff)
Notes
Diffstat (limited to 'lib/MC/MCAsmStreamer.cpp')
-rw-r--r--lib/MC/MCAsmStreamer.cpp197
1 files changed, 137 insertions, 60 deletions
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp
index 9e5553fa8d42..3357553cf19f 100644
--- a/lib/MC/MCAsmStreamer.cpp
+++ b/lib/MC/MCAsmStreamer.cpp
@@ -22,17 +22,14 @@
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCSymbolELF.h"
#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 "llvm/Support/SourceMgr.h"
#include <cctype>
using namespace llvm;
@@ -140,6 +137,8 @@ public:
void EmitDataRegion(MCDataRegionType Kind) override;
void EmitVersionMin(MCVersionMinType Kind, unsigned Major, unsigned Minor,
unsigned Update) override;
+ void EmitBuildVersion(unsigned Platform, unsigned Major, unsigned Minor,
+ unsigned Update) override;
void EmitThumbFunc(MCSymbol *Func) override;
void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
@@ -225,7 +224,9 @@ public:
StringRef FileName) override;
MCSymbol *getDwarfLineTableSymbol(unsigned CUID) override;
- bool EmitCVFileDirective(unsigned FileNo, StringRef Filename) override;
+ bool EmitCVFileDirective(unsigned FileNo, StringRef Filename,
+ ArrayRef<uint8_t> Checksum,
+ unsigned ChecksumKind) override;
bool EmitCVFuncIdDirective(unsigned FuncId) override;
bool EmitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc,
unsigned IAFile, unsigned IALine,
@@ -245,6 +246,8 @@ public:
StringRef FixedSizePortion) override;
void EmitCVStringTableDirective() override;
void EmitCVFileChecksumsDirective() override;
+ void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override;
+ void EmitCVFPOData(const MCSymbol *ProcSym, SMLoc L) override;
void EmitIdent(StringRef IdentString) override;
void EmitCFISections(bool EH, bool Debug) override;
@@ -256,6 +259,7 @@ public:
void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) override;
void EmitCFIRememberState() override;
void EmitCFIRestoreState() override;
+ void EmitCFIRestore(int64_t Register) override;
void EmitCFISameValue(int64_t Register) override;
void EmitCFIRelOffset(int64_t Register, int64_t Offset) override;
void EmitCFIAdjustCfaOffset(int64_t Adjustment) override;
@@ -265,21 +269,26 @@ public:
void EmitCFIUndefined(int64_t Register) override;
void EmitCFIRegister(int64_t Register1, int64_t Register2) override;
void EmitCFIWindowSave() override;
+ void EmitCFIReturnColumn(int64_t Register) override;
+
+ void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override;
+ void EmitWinCFIEndProc(SMLoc Loc) override;
+ void EmitWinCFIStartChained(SMLoc Loc) override;
+ void EmitWinCFIEndChained(SMLoc Loc) override;
+ void EmitWinCFIPushReg(unsigned Register, SMLoc Loc) override;
+ void EmitWinCFISetFrame(unsigned Register, unsigned Offset,
+ SMLoc Loc) override;
+ void EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) override;
+ void EmitWinCFISaveReg(unsigned Register, unsigned Offset,
+ SMLoc Loc) override;
+ void EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
+ SMLoc Loc) override;
+ void EmitWinCFIPushFrame(bool Code, SMLoc Loc) override;
+ void EmitWinCFIEndProlog(SMLoc Loc) override;
- void EmitWinCFIStartProc(const MCSymbol *Symbol) override;
- void EmitWinCFIEndProc() override;
- void EmitWinCFIStartChained() override;
- void EmitWinCFIEndChained() override;
- void EmitWinCFIPushReg(unsigned Register) override;
- void EmitWinCFISetFrame(unsigned Register, unsigned Offset) override;
- void EmitWinCFIAllocStack(unsigned Size) override;
- void EmitWinCFISaveReg(unsigned Register, unsigned Offset) override;
- void EmitWinCFISaveXMM(unsigned Register, unsigned Offset) override;
- void EmitWinCFIPushFrame(bool Code) override;
- void EmitWinCFIEndProlog() override;
-
- void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except) override;
- void EmitWinEHHandlerData() override;
+ void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
+ SMLoc Loc) override;
+ void EmitWinEHHandlerData(SMLoc Loc) override;
void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
bool PrintSchedInfo) override;
@@ -464,15 +473,39 @@ void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
EmitEOL();
}
-void MCAsmStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
+static const char *getVersionMinDirective(MCVersionMinType Type) {
+ switch (Type) {
+ case MCVM_WatchOSVersionMin: return ".watchos_version_min";
+ case MCVM_TvOSVersionMin: return ".tvos_version_min";
+ case MCVM_IOSVersionMin: return ".ios_version_min";
+ case MCVM_OSXVersionMin: return ".macosx_version_min";
+ }
+ llvm_unreachable("Invalid MC version min type");
+}
+
+void MCAsmStreamer::EmitVersionMin(MCVersionMinType Type, 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;
+ OS << '\t' << getVersionMinDirective(Type) << ' ' << Major << ", " << Minor;
+ if (Update)
+ OS << ", " << Update;
+ EmitEOL();
+}
+
+static const char *getPlatformName(MachO::PlatformType Type) {
+ switch (Type) {
+ case MachO::PLATFORM_MACOS: return "macos";
+ case MachO::PLATFORM_IOS: return "ios";
+ case MachO::PLATFORM_TVOS: return "tvos";
+ case MachO::PLATFORM_WATCHOS: return "watchos";
+ case MachO::PLATFORM_BRIDGEOS: return "bridgeos";
}
- OS << " " << Major << ", " << Minor;
+ llvm_unreachable("Invalid Mach-O platform type");
+}
+
+void MCAsmStreamer::EmitBuildVersion(unsigned Platform, unsigned Major,
+ unsigned Minor, unsigned Update) {
+ const char *PlatformName = getPlatformName((MachO::PlatformType)Platform);
+ OS << "\t.build_version " << PlatformName << ", " << Major << ", " << Minor;
if (Update)
OS << ", " << Update;
EmitEOL();
@@ -1119,13 +1152,25 @@ MCSymbol *MCAsmStreamer::getDwarfLineTableSymbol(unsigned CUID) {
return MCStreamer::getDwarfLineTableSymbol(0);
}
-bool MCAsmStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename) {
- if (!getContext().getCVContext().addFile(FileNo, Filename))
+bool MCAsmStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
+ ArrayRef<uint8_t> Checksum,
+ unsigned ChecksumKind) {
+ if (!getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
+ ChecksumKind))
return false;
OS << "\t.cv_file\t" << FileNo << ' ';
-
PrintQuotedString(Filename, OS);
+
+ if (!ChecksumKind) {
+ EmitEOL();
+ return true;
+ }
+
+ OS << ' ';
+ PrintQuotedString(toHex(Checksum), OS);
+ OS << ' ' << ChecksumKind;
+
EmitEOL();
return true;
}
@@ -1227,6 +1272,17 @@ void MCAsmStreamer::EmitCVFileChecksumsDirective() {
EmitEOL();
}
+void MCAsmStreamer::EmitCVFileChecksumOffsetDirective(unsigned FileNo) {
+ OS << "\t.cv_filechecksumoffset\t" << FileNo;
+ EmitEOL();
+}
+
+void MCAsmStreamer::EmitCVFPOData(const MCSymbol *ProcSym, SMLoc L) {
+ OS << "\t.cv_fpo_data\t";
+ ProcSym->print(OS, MAI);
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitIdent(StringRef IdentString) {
assert(MAI->hasIdentDirective() && ".ident directive not supported");
OS << "\t.ident\t";
@@ -1263,12 +1319,17 @@ void MCAsmStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
void MCAsmStreamer::EmitRegisterName(int64_t Register) {
if (!MAI->useDwarfRegNumForCFI()) {
+ // User .cfi_* directives can use arbitrary DWARF register numbers, not
+ // just ones that map to LLVM register numbers and have known names.
+ // Fall back to using the original number directly if no name is known.
const MCRegisterInfo *MRI = getContext().getRegisterInfo();
- unsigned LLVMRegister = MRI->getLLVMRegNum(Register, true);
- InstPrinter->printRegName(OS, LLVMRegister);
- } else {
- OS << Register;
+ int LLVMRegister = MRI->getLLVMRegNumFromEH(Register);
+ if (LLVMRegister != -1) {
+ InstPrinter->printRegName(OS, LLVMRegister);
+ return;
+ }
}
+ OS << Register;
}
void MCAsmStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
@@ -1353,6 +1414,13 @@ void MCAsmStreamer::EmitCFIRestoreState() {
EmitEOL();
}
+void MCAsmStreamer::EmitCFIRestore(int64_t Register) {
+ MCStreamer::EmitCFIRestore(Register);
+ OS << "\t.cfi_restore ";
+ EmitRegisterName(Register);
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitCFISameValue(int64_t Register) {
MCStreamer::EmitCFISameValue(Register);
OS << "\t.cfi_same_value ";
@@ -1398,38 +1466,44 @@ void MCAsmStreamer::EmitCFIWindowSave() {
EmitEOL();
}
-void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
- MCStreamer::EmitWinCFIStartProc(Symbol);
+void MCAsmStreamer::EmitCFIReturnColumn(int64_t Register) {
+ MCStreamer::EmitCFIReturnColumn(Register);
+ OS << "\t.cfi_return_column " << Register;
+ EmitEOL();
+}
+
+void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
+ MCStreamer::EmitWinCFIStartProc(Symbol, Loc);
OS << ".seh_proc ";
Symbol->print(OS, MAI);
EmitEOL();
}
-void MCAsmStreamer::EmitWinCFIEndProc() {
- MCStreamer::EmitWinCFIEndProc();
+void MCAsmStreamer::EmitWinCFIEndProc(SMLoc Loc) {
+ MCStreamer::EmitWinCFIEndProc(Loc);
OS << "\t.seh_endproc";
EmitEOL();
}
-void MCAsmStreamer::EmitWinCFIStartChained() {
- MCStreamer::EmitWinCFIStartChained();
+void MCAsmStreamer::EmitWinCFIStartChained(SMLoc Loc) {
+ MCStreamer::EmitWinCFIStartChained(Loc);
OS << "\t.seh_startchained";
EmitEOL();
}
-void MCAsmStreamer::EmitWinCFIEndChained() {
- MCStreamer::EmitWinCFIEndChained();
+void MCAsmStreamer::EmitWinCFIEndChained(SMLoc Loc) {
+ MCStreamer::EmitWinCFIEndChained(Loc);
OS << "\t.seh_endchained";
EmitEOL();
}
void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
- bool Except) {
- MCStreamer::EmitWinEHHandler(Sym, Unwind, Except);
+ bool Except, SMLoc Loc) {
+ MCStreamer::EmitWinEHHandler(Sym, Unwind, Except, Loc);
OS << "\t.seh_handler ";
Sym->print(OS, MAI);
@@ -1440,8 +1514,8 @@ void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
EmitEOL();
}
-void MCAsmStreamer::EmitWinEHHandlerData() {
- MCStreamer::EmitWinEHHandlerData();
+void MCAsmStreamer::EmitWinEHHandlerData(SMLoc Loc) {
+ MCStreamer::EmitWinEHHandlerData(Loc);
// Switch sections. Don't call SwitchSection directly, because that will
// cause the section switch to be visible in the emitted assembly.
@@ -1456,43 +1530,46 @@ void MCAsmStreamer::EmitWinEHHandlerData() {
EmitEOL();
}
-void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register) {
- MCStreamer::EmitWinCFIPushReg(Register);
+void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register, SMLoc Loc) {
+ MCStreamer::EmitWinCFIPushReg(Register, Loc);
OS << "\t.seh_pushreg " << Register;
EmitEOL();
}
-void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) {
- MCStreamer::EmitWinCFISetFrame(Register, Offset);
+void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset,
+ SMLoc Loc) {
+ MCStreamer::EmitWinCFISetFrame(Register, Offset, Loc);
OS << "\t.seh_setframe " << Register << ", " << Offset;
EmitEOL();
}
-void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size) {
- MCStreamer::EmitWinCFIAllocStack(Size);
+void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
+ MCStreamer::EmitWinCFIAllocStack(Size, Loc);
OS << "\t.seh_stackalloc " << Size;
EmitEOL();
}
-void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) {
- MCStreamer::EmitWinCFISaveReg(Register, Offset);
+void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset,
+ SMLoc Loc) {
+ MCStreamer::EmitWinCFISaveReg(Register, Offset, Loc);
OS << "\t.seh_savereg " << Register << ", " << Offset;
EmitEOL();
}
-void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) {
- MCStreamer::EmitWinCFISaveXMM(Register, Offset);
+void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
+ SMLoc Loc) {
+ MCStreamer::EmitWinCFISaveXMM(Register, Offset, Loc);
OS << "\t.seh_savexmm " << Register << ", " << Offset;
EmitEOL();
}
-void MCAsmStreamer::EmitWinCFIPushFrame(bool Code) {
- MCStreamer::EmitWinCFIPushFrame(Code);
+void MCAsmStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
+ MCStreamer::EmitWinCFIPushFrame(Code, Loc);
OS << "\t.seh_pushframe";
if (Code)
@@ -1500,8 +1577,8 @@ void MCAsmStreamer::EmitWinCFIPushFrame(bool Code) {
EmitEOL();
}
-void MCAsmStreamer::EmitWinCFIEndProlog() {
- MCStreamer::EmitWinCFIEndProlog();
+void MCAsmStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
+ MCStreamer::EmitWinCFIEndProlog(Loc);
OS << "\t.seh_endprologue";
EmitEOL();
@@ -1583,8 +1660,8 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst,
}
}
OS << "]";
- // If we are not going to add fixup or schedul comments after this point then
- // we have to end the current comment line with "\n".
+ // If we are not going to add fixup or schedule comments after this point
+ // then we have to end the current comment line with "\n".
if (Fixups.size() || !PrintSchedInfo)
OS << "\n";