diff options
Diffstat (limited to 'lib/MC/MCAsmStreamer.cpp')
| -rw-r--r-- | lib/MC/MCAsmStreamer.cpp | 197 | 
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"; | 
