1195098Sed//===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===// 2195098Sed// 3195098Sed// The LLVM Compiler Infrastructure 4195098Sed// 5195098Sed// This file is distributed under the University of Illinois Open Source 6195098Sed// License. See LICENSE.TXT for details. 7195098Sed// 8195098Sed//===----------------------------------------------------------------------===// 9195098Sed 10249423Sdim#include "llvm/MC/MCStreamer.h" 11249423Sdim#include "llvm/ADT/SmallString.h" 12249423Sdim#include "llvm/ADT/Twine.h" 13263508Sdim#include "llvm/MC/MCAsmBackend.h" 14218893Sdim#include "llvm/MC/MCAsmInfo.h" 15218893Sdim#include "llvm/MC/MCContext.h" 16202878Srdivacky#include "llvm/MC/MCExpr.h" 17218893Sdim#include "llvm/MC/MCObjectWriter.h" 18221345Sdim#include "llvm/MC/MCSymbol.h" 19218893Sdim#include "llvm/Support/ErrorHandling.h" 20249423Sdim#include "llvm/Support/LEB128.h" 21202878Srdivacky#include "llvm/Support/raw_ostream.h" 22206274Srdivacky#include <cstdlib> 23195098Sedusing namespace llvm; 24195098Sed 25263508Sdim// Pin the vtables to this file. 26263508SdimMCTargetStreamer::~MCTargetStreamer() {} 27263508Sdimvoid ARMTargetStreamer::anchor() {} 28263508Sdim 29263508SdimMCStreamer::MCStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer) 30263508Sdim : Context(Ctx), TargetStreamer(TargetStreamer), EmitEHFrame(true), 31263508Sdim EmitDebugFrame(false), CurrentW64UnwindInfo(0), LastSymbol(0), 32263508Sdim AutoInitSections(false) { 33251662Sdim SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>()); 34263508Sdim if (TargetStreamer) 35263508Sdim TargetStreamer->setStreamer(this); 36195098Sed} 37195098Sed 38195098SedMCStreamer::~MCStreamer() { 39223017Sdim for (unsigned i = 0; i < getNumW64UnwindInfos(); ++i) 40223017Sdim delete W64UnwindInfos[i]; 41195098Sed} 42202878Srdivacky 43249423Sdimvoid MCStreamer::reset() { 44249423Sdim for (unsigned i = 0; i < getNumW64UnwindInfos(); ++i) 45249423Sdim delete W64UnwindInfos[i]; 46251662Sdim W64UnwindInfos.clear(); 47249423Sdim EmitEHFrame = true; 48249423Sdim EmitDebugFrame = false; 49249423Sdim CurrentW64UnwindInfo = 0; 50249423Sdim LastSymbol = 0; 51249423Sdim SectionStack.clear(); 52251662Sdim SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>()); 53249423Sdim} 54249423Sdim 55221345Sdimconst MCExpr *MCStreamer::BuildSymbolDiff(MCContext &Context, 56221345Sdim const MCSymbol *A, 57221345Sdim const MCSymbol *B) { 58221345Sdim MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 59221345Sdim const MCExpr *ARef = 60221345Sdim MCSymbolRefExpr::Create(A, Variant, Context); 61221345Sdim const MCExpr *BRef = 62221345Sdim MCSymbolRefExpr::Create(B, Variant, Context); 63221345Sdim const MCExpr *AddrDelta = 64221345Sdim MCBinaryExpr::Create(MCBinaryExpr::Sub, ARef, BRef, Context); 65221345Sdim return AddrDelta; 66221345Sdim} 67221345Sdim 68223017Sdimconst MCExpr *MCStreamer::ForceExpAbs(const MCExpr* Expr) { 69263508Sdim if (Context.getAsmInfo()->hasAggressiveSymbolFolding() || 70223017Sdim isa<MCSymbolRefExpr>(Expr)) 71223017Sdim return Expr; 72221345Sdim 73223017Sdim MCSymbol *ABS = Context.CreateTempSymbol(); 74223017Sdim EmitAssignment(ABS, Expr); 75223017Sdim return MCSymbolRefExpr::Create(ABS, Context); 76221345Sdim} 77221345Sdim 78202878Srdivackyraw_ostream &MCStreamer::GetCommentOS() { 79202878Srdivacky // By default, discard comments. 80202878Srdivacky return nulls(); 81202878Srdivacky} 82202878Srdivacky 83263508Sdimvoid MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) { 84263508Sdim for (std::vector<MCDwarfFrameInfo>::iterator I = FrameInfos.begin(), 85263508Sdim E = FrameInfos.end(); I != E; ++I) 86263508Sdim I->CompactUnwindEncoding = 87263508Sdim (MAB ? MAB->generateCompactUnwindEncoding(I->Instructions) : 0); 88263508Sdim} 89263508Sdim 90218893Sdimvoid MCStreamer::EmitDwarfSetLineAddr(int64_t LineDelta, 91218893Sdim const MCSymbol *Label, int PointerSize) { 92218893Sdim // emit the sequence to set the address 93218893Sdim EmitIntValue(dwarf::DW_LNS_extended_op, 1); 94218893Sdim EmitULEB128IntValue(PointerSize + 1); 95218893Sdim EmitIntValue(dwarf::DW_LNE_set_address, 1); 96218893Sdim EmitSymbolValue(Label, PointerSize); 97202878Srdivacky 98218893Sdim // emit the sequence for the LineDelta (from 1) and a zero address delta. 99218893Sdim MCDwarfLineAddr::Emit(this, LineDelta, 0); 100218893Sdim} 101218893Sdim 102202878Srdivacky/// EmitIntValue - Special case of EmitValue that avoids the client having to 103202878Srdivacky/// pass in a MCExpr for constant integers. 104263508Sdimvoid MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) { 105218893Sdim assert(Size <= 8 && "Invalid size"); 106218893Sdim assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) && 107218893Sdim "Invalid size"); 108218893Sdim char buf[8]; 109263508Sdim const bool isLittleEndian = Context.getAsmInfo()->isLittleEndian(); 110223017Sdim for (unsigned i = 0; i != Size; ++i) { 111223017Sdim unsigned index = isLittleEndian ? i : (Size - i - 1); 112223017Sdim buf[i] = uint8_t(Value >> (index * 8)); 113223017Sdim } 114263508Sdim EmitBytes(StringRef(buf, Size)); 115202878Srdivacky} 116202878Srdivacky 117218893Sdim/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the 118218893Sdim/// client having to pass in a MCExpr for constant integers. 119263508Sdimvoid MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned Padding) { 120234353Sdim SmallString<128> Tmp; 121218893Sdim raw_svector_ostream OSE(Tmp); 122239462Sdim encodeULEB128(Value, OSE, Padding); 123263508Sdim EmitBytes(OSE.str()); 124218893Sdim} 125218893Sdim 126218893Sdim/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the 127218893Sdim/// client having to pass in a MCExpr for constant integers. 128263508Sdimvoid MCStreamer::EmitSLEB128IntValue(int64_t Value) { 129234353Sdim SmallString<128> Tmp; 130218893Sdim raw_svector_ostream OSE(Tmp); 131239462Sdim encodeSLEB128(Value, OSE); 132263508Sdim EmitBytes(OSE.str()); 133218893Sdim} 134218893Sdim 135263508Sdimvoid MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size) { 136223017Sdim const MCExpr *ABS = ForceExpAbs(Value); 137263508Sdim EmitValue(ABS, Size); 138218893Sdim} 139218893Sdim 140218893Sdim 141263508Sdimvoid MCStreamer::EmitValue(const MCExpr *Value, unsigned Size) { 142263508Sdim EmitValueImpl(Value, Size); 143218893Sdim} 144218893Sdim 145263508Sdimvoid MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size) { 146263508Sdim EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size); 147218893Sdim} 148218893Sdim 149234353Sdimvoid MCStreamer::EmitGPRel64Value(const MCExpr *Value) { 150234353Sdim report_fatal_error("unsupported directive in streamer"); 151234353Sdim} 152234353Sdim 153218893Sdimvoid MCStreamer::EmitGPRel32Value(const MCExpr *Value) { 154218893Sdim report_fatal_error("unsupported directive in streamer"); 155218893Sdim} 156218893Sdim 157202878Srdivacky/// EmitFill - Emit NumBytes bytes worth of the value specified by 158202878Srdivacky/// FillValue. This implements directives such as '.space'. 159263508Sdimvoid MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue) { 160202878Srdivacky const MCExpr *E = MCConstantExpr::Create(FillValue, getContext()); 161202878Srdivacky for (uint64_t i = 0, e = NumBytes; i != e; ++i) 162263508Sdim EmitValue(E, 1); 163202878Srdivacky} 164206274Srdivacky 165263508Sdim/// The implementation in this class just redirects to EmitFill. 166263508Sdimvoid MCStreamer::EmitZeros(uint64_t NumBytes) { 167263508Sdim EmitFill(NumBytes, 0); 168263508Sdim} 169263508Sdim 170218893Sdimbool MCStreamer::EmitDwarfFileDirective(unsigned FileNo, 171234353Sdim StringRef Directory, 172249423Sdim StringRef Filename, unsigned CUID) { 173249423Sdim return getContext().GetDwarfFile(Directory, Filename, FileNo, CUID) == 0; 174218893Sdim} 175218893Sdim 176218893Sdimvoid MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 177218893Sdim unsigned Column, unsigned Flags, 178218893Sdim unsigned Isa, 179221345Sdim unsigned Discriminator, 180221345Sdim StringRef FileName) { 181218893Sdim getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa, 182218893Sdim Discriminator); 183218893Sdim} 184218893Sdim 185218893SdimMCDwarfFrameInfo *MCStreamer::getCurrentFrameInfo() { 186218893Sdim if (FrameInfos.empty()) 187249423Sdim return 0; 188218893Sdim return &FrameInfos.back(); 189218893Sdim} 190218893Sdim 191218893Sdimvoid MCStreamer::EnsureValidFrame() { 192218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 193218893Sdim if (!CurFrame || CurFrame->End) 194218893Sdim report_fatal_error("No open frame"); 195218893Sdim} 196218893Sdim 197221345Sdimvoid MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, 198221345Sdim MCSymbol *EHSymbol) { 199221345Sdim} 200221345Sdim 201263508Sdimvoid MCStreamer::AssignSection(MCSymbol *Symbol, const MCSection *Section) { 202263508Sdim if (Section) 203263508Sdim Symbol->setSection(*Section); 204263508Sdim else 205263508Sdim Symbol->setUndefined(); 206263508Sdim 207263508Sdim // As we emit symbols into a section, track the order so that they can 208263508Sdim // be sorted upon later. Zero is reserved to mean 'unemitted'. 209263508Sdim SymbolOrdering[Symbol] = 1 + SymbolOrdering.size(); 210263508Sdim} 211263508Sdim 212221345Sdimvoid MCStreamer::EmitLabel(MCSymbol *Symbol) { 213221345Sdim assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); 214251662Sdim assert(getCurrentSection().first && "Cannot emit before setting section!"); 215263508Sdim AssignSection(Symbol, getCurrentSection().first); 216226633Sdim LastSymbol = Symbol; 217226633Sdim} 218221345Sdim 219249423Sdimvoid MCStreamer::EmitDebugLabel(MCSymbol *Symbol) { 220249423Sdim assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); 221251662Sdim assert(getCurrentSection().first && "Cannot emit before setting section!"); 222263508Sdim AssignSection(Symbol, getCurrentSection().first); 223249423Sdim LastSymbol = Symbol; 224249423Sdim} 225249423Sdim 226226633Sdimvoid MCStreamer::EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding) { 227226633Sdim EnsureValidFrame(); 228226633Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 229226633Sdim CurFrame->CompactUnwindEncoding = CompactUnwindEncoding; 230226633Sdim} 231226633Sdim 232223017Sdimvoid MCStreamer::EmitCFISections(bool EH, bool Debug) { 233223017Sdim assert(EH || Debug); 234223017Sdim EmitEHFrame = EH; 235223017Sdim EmitDebugFrame = Debug; 236223017Sdim} 237223017Sdim 238221345Sdimvoid MCStreamer::EmitCFIStartProc() { 239218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 240221345Sdim if (CurFrame && !CurFrame->End) 241218893Sdim report_fatal_error("Starting a frame before finishing the previous one!"); 242226633Sdim 243218893Sdim MCDwarfFrameInfo Frame; 244234353Sdim EmitCFIStartProcImpl(Frame); 245234353Sdim 246234353Sdim FrameInfos.push_back(Frame); 247234353Sdim} 248234353Sdim 249234353Sdimvoid MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 250234353Sdim} 251234353Sdim 252234353Sdimvoid MCStreamer::RecordProcStart(MCDwarfFrameInfo &Frame) { 253226633Sdim Frame.Function = LastSymbol; 254226633Sdim // If the function is externally visible, we need to create a local 255226633Sdim // symbol to avoid relocations. 256263508Sdim StringRef Prefix = getContext().getAsmInfo()->getPrivateGlobalPrefix(); 257226633Sdim if (LastSymbol && LastSymbol->getName().startswith(Prefix)) { 258226633Sdim Frame.Begin = LastSymbol; 259226633Sdim } else { 260226633Sdim Frame.Begin = getContext().CreateTempSymbol(); 261226633Sdim EmitLabel(Frame.Begin); 262226633Sdim } 263218893Sdim} 264218893Sdim 265221345Sdimvoid MCStreamer::EmitCFIEndProc() { 266218893Sdim EnsureValidFrame(); 267218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 268234353Sdim EmitCFIEndProcImpl(*CurFrame); 269218893Sdim} 270218893Sdim 271234353Sdimvoid MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { 272234353Sdim} 273234353Sdim 274234353Sdimvoid MCStreamer::RecordProcEnd(MCDwarfFrameInfo &Frame) { 275234353Sdim Frame.End = getContext().CreateTempSymbol(); 276234353Sdim EmitLabel(Frame.End); 277234353Sdim} 278234353Sdim 279249423SdimMCSymbol *MCStreamer::EmitCFICommon() { 280218893Sdim EnsureValidFrame(); 281218893Sdim MCSymbol *Label = getContext().CreateTempSymbol(); 282218893Sdim EmitLabel(Label); 283249423Sdim return Label; 284249423Sdim} 285249423Sdim 286249423Sdimvoid MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { 287249423Sdim MCSymbol *Label = EmitCFICommon(); 288249423Sdim MCCFIInstruction Instruction = 289249423Sdim MCCFIInstruction::createDefCfa(Label, Register, Offset); 290249423Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 291218893Sdim CurFrame->Instructions.push_back(Instruction); 292218893Sdim} 293218893Sdim 294221345Sdimvoid MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) { 295249423Sdim MCSymbol *Label = EmitCFICommon(); 296249423Sdim MCCFIInstruction Instruction = 297249423Sdim MCCFIInstruction::createDefCfaOffset(Label, Offset); 298218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 299218893Sdim CurFrame->Instructions.push_back(Instruction); 300218893Sdim} 301218893Sdim 302221345Sdimvoid MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { 303249423Sdim MCSymbol *Label = EmitCFICommon(); 304249423Sdim MCCFIInstruction Instruction = 305249423Sdim MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment); 306218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 307221345Sdim CurFrame->Instructions.push_back(Instruction); 308221345Sdim} 309221345Sdim 310221345Sdimvoid MCStreamer::EmitCFIDefCfaRegister(int64_t Register) { 311249423Sdim MCSymbol *Label = EmitCFICommon(); 312249423Sdim MCCFIInstruction Instruction = 313249423Sdim MCCFIInstruction::createDefCfaRegister(Label, Register); 314221345Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 315218893Sdim CurFrame->Instructions.push_back(Instruction); 316218893Sdim} 317218893Sdim 318221345Sdimvoid MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { 319249423Sdim MCSymbol *Label = EmitCFICommon(); 320249423Sdim MCCFIInstruction Instruction = 321249423Sdim MCCFIInstruction::createOffset(Label, Register, Offset); 322218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 323218893Sdim CurFrame->Instructions.push_back(Instruction); 324218893Sdim} 325218893Sdim 326221345Sdimvoid MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) { 327249423Sdim MCSymbol *Label = EmitCFICommon(); 328249423Sdim MCCFIInstruction Instruction = 329249423Sdim MCCFIInstruction::createRelOffset(Label, Register, Offset); 330221345Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 331221345Sdim CurFrame->Instructions.push_back(Instruction); 332221345Sdim} 333221345Sdim 334221345Sdimvoid MCStreamer::EmitCFIPersonality(const MCSymbol *Sym, 335218893Sdim unsigned Encoding) { 336218893Sdim EnsureValidFrame(); 337218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 338218893Sdim CurFrame->Personality = Sym; 339218893Sdim CurFrame->PersonalityEncoding = Encoding; 340218893Sdim} 341218893Sdim 342221345Sdimvoid MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { 343218893Sdim EnsureValidFrame(); 344218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 345218893Sdim CurFrame->Lsda = Sym; 346218893Sdim CurFrame->LsdaEncoding = Encoding; 347218893Sdim} 348218893Sdim 349221345Sdimvoid MCStreamer::EmitCFIRememberState() { 350249423Sdim MCSymbol *Label = EmitCFICommon(); 351249423Sdim MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label); 352218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 353218893Sdim CurFrame->Instructions.push_back(Instruction); 354218893Sdim} 355218893Sdim 356221345Sdimvoid MCStreamer::EmitCFIRestoreState() { 357218893Sdim // FIXME: Error if there is no matching cfi_remember_state. 358249423Sdim MCSymbol *Label = EmitCFICommon(); 359249423Sdim MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label); 360218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 361218893Sdim CurFrame->Instructions.push_back(Instruction); 362218893Sdim} 363218893Sdim 364221345Sdimvoid MCStreamer::EmitCFISameValue(int64_t Register) { 365249423Sdim MCSymbol *Label = EmitCFICommon(); 366249423Sdim MCCFIInstruction Instruction = 367249423Sdim MCCFIInstruction::createSameValue(Label, Register); 368221345Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 369221345Sdim CurFrame->Instructions.push_back(Instruction); 370221345Sdim} 371221345Sdim 372234353Sdimvoid MCStreamer::EmitCFIRestore(int64_t Register) { 373249423Sdim MCSymbol *Label = EmitCFICommon(); 374249423Sdim MCCFIInstruction Instruction = 375249423Sdim MCCFIInstruction::createRestore(Label, Register); 376234353Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 377234353Sdim CurFrame->Instructions.push_back(Instruction); 378234353Sdim} 379234353Sdim 380234353Sdimvoid MCStreamer::EmitCFIEscape(StringRef Values) { 381249423Sdim MCSymbol *Label = EmitCFICommon(); 382249423Sdim MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values); 383234353Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 384234353Sdim CurFrame->Instructions.push_back(Instruction); 385234353Sdim} 386234353Sdim 387234353Sdimvoid MCStreamer::EmitCFISignalFrame() { 388234353Sdim EnsureValidFrame(); 389234353Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 390234353Sdim CurFrame->IsSignalFrame = true; 391234353Sdim} 392234353Sdim 393249423Sdimvoid MCStreamer::EmitCFIUndefined(int64_t Register) { 394249423Sdim MCSymbol *Label = EmitCFICommon(); 395249423Sdim MCCFIInstruction Instruction = 396249423Sdim MCCFIInstruction::createUndefined(Label, Register); 397249423Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 398249423Sdim CurFrame->Instructions.push_back(Instruction); 399249423Sdim} 400249423Sdim 401249423Sdimvoid MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) { 402249423Sdim MCSymbol *Label = EmitCFICommon(); 403249423Sdim MCCFIInstruction Instruction = 404249423Sdim MCCFIInstruction::createRegister(Label, Register1, Register2); 405249423Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 406249423Sdim CurFrame->Instructions.push_back(Instruction); 407249423Sdim} 408249423Sdim 409263508Sdimvoid MCStreamer::EmitCFIWindowSave() { 410263508Sdim MCSymbol *Label = EmitCFICommon(); 411263508Sdim MCCFIInstruction Instruction = 412263508Sdim MCCFIInstruction::createWindowSave(Label); 413263508Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 414263508Sdim CurFrame->Instructions.push_back(Instruction); 415263508Sdim} 416263508Sdim 417223017Sdimvoid MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) { 418223017Sdim W64UnwindInfos.push_back(Frame); 419223017Sdim CurrentW64UnwindInfo = W64UnwindInfos.back(); 420223017Sdim} 421223017Sdim 422223017Sdimvoid MCStreamer::EnsureValidW64UnwindInfo() { 423223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 424223017Sdim if (!CurFrame || CurFrame->End) 425223017Sdim report_fatal_error("No open Win64 EH frame function!"); 426223017Sdim} 427223017Sdim 428223017Sdimvoid MCStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) { 429223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 430223017Sdim if (CurFrame && !CurFrame->End) 431223017Sdim report_fatal_error("Starting a function before ending the previous one!"); 432223017Sdim MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo; 433223017Sdim Frame->Begin = getContext().CreateTempSymbol(); 434223017Sdim Frame->Function = Symbol; 435223017Sdim EmitLabel(Frame->Begin); 436223017Sdim setCurrentW64UnwindInfo(Frame); 437223017Sdim} 438223017Sdim 439223017Sdimvoid MCStreamer::EmitWin64EHEndProc() { 440223017Sdim EnsureValidW64UnwindInfo(); 441223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 442223017Sdim if (CurFrame->ChainedParent) 443223017Sdim report_fatal_error("Not all chained regions terminated!"); 444223017Sdim CurFrame->End = getContext().CreateTempSymbol(); 445223017Sdim EmitLabel(CurFrame->End); 446223017Sdim} 447223017Sdim 448223017Sdimvoid MCStreamer::EmitWin64EHStartChained() { 449223017Sdim EnsureValidW64UnwindInfo(); 450223017Sdim MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo; 451223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 452223017Sdim Frame->Begin = getContext().CreateTempSymbol(); 453223017Sdim Frame->Function = CurFrame->Function; 454223017Sdim Frame->ChainedParent = CurFrame; 455223017Sdim EmitLabel(Frame->Begin); 456223017Sdim setCurrentW64UnwindInfo(Frame); 457223017Sdim} 458223017Sdim 459223017Sdimvoid MCStreamer::EmitWin64EHEndChained() { 460223017Sdim EnsureValidW64UnwindInfo(); 461223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 462223017Sdim if (!CurFrame->ChainedParent) 463223017Sdim report_fatal_error("End of a chained region outside a chained region!"); 464223017Sdim CurFrame->End = getContext().CreateTempSymbol(); 465223017Sdim EmitLabel(CurFrame->End); 466223017Sdim CurrentW64UnwindInfo = CurFrame->ChainedParent; 467223017Sdim} 468223017Sdim 469223017Sdimvoid MCStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, 470223017Sdim bool Except) { 471223017Sdim EnsureValidW64UnwindInfo(); 472223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 473223017Sdim if (CurFrame->ChainedParent) 474223017Sdim report_fatal_error("Chained unwind areas can't have handlers!"); 475223017Sdim CurFrame->ExceptionHandler = Sym; 476223017Sdim if (!Except && !Unwind) 477223017Sdim report_fatal_error("Don't know what kind of handler this is!"); 478223017Sdim if (Unwind) 479223017Sdim CurFrame->HandlesUnwind = true; 480223017Sdim if (Except) 481223017Sdim CurFrame->HandlesExceptions = true; 482223017Sdim} 483223017Sdim 484223017Sdimvoid MCStreamer::EmitWin64EHHandlerData() { 485223017Sdim EnsureValidW64UnwindInfo(); 486223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 487223017Sdim if (CurFrame->ChainedParent) 488223017Sdim report_fatal_error("Chained unwind areas can't have handlers!"); 489223017Sdim} 490223017Sdim 491223017Sdimvoid MCStreamer::EmitWin64EHPushReg(unsigned Register) { 492223017Sdim EnsureValidW64UnwindInfo(); 493223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 494223017Sdim MCSymbol *Label = getContext().CreateTempSymbol(); 495223017Sdim MCWin64EHInstruction Inst(Win64EH::UOP_PushNonVol, Label, Register); 496223017Sdim EmitLabel(Label); 497223017Sdim CurFrame->Instructions.push_back(Inst); 498223017Sdim} 499223017Sdim 500223017Sdimvoid MCStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) { 501223017Sdim EnsureValidW64UnwindInfo(); 502223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 503223017Sdim if (CurFrame->LastFrameInst >= 0) 504223017Sdim report_fatal_error("Frame register and offset already specified!"); 505223017Sdim if (Offset & 0x0F) 506223017Sdim report_fatal_error("Misaligned frame pointer offset!"); 507263508Sdim MCSymbol *Label = getContext().CreateTempSymbol(); 508263508Sdim MCWin64EHInstruction Inst(Win64EH::UOP_SetFPReg, Label, Register, Offset); 509263508Sdim EmitLabel(Label); 510223017Sdim CurFrame->LastFrameInst = CurFrame->Instructions.size(); 511223017Sdim CurFrame->Instructions.push_back(Inst); 512223017Sdim} 513223017Sdim 514223017Sdimvoid MCStreamer::EmitWin64EHAllocStack(unsigned Size) { 515223017Sdim EnsureValidW64UnwindInfo(); 516223017Sdim if (Size & 7) 517223017Sdim report_fatal_error("Misaligned stack allocation!"); 518223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 519223017Sdim MCSymbol *Label = getContext().CreateTempSymbol(); 520223017Sdim MCWin64EHInstruction Inst(Label, Size); 521223017Sdim EmitLabel(Label); 522223017Sdim CurFrame->Instructions.push_back(Inst); 523223017Sdim} 524223017Sdim 525223017Sdimvoid MCStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) { 526223017Sdim EnsureValidW64UnwindInfo(); 527223017Sdim if (Offset & 7) 528223017Sdim report_fatal_error("Misaligned saved register offset!"); 529223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 530223017Sdim MCSymbol *Label = getContext().CreateTempSymbol(); 531223017Sdim MCWin64EHInstruction Inst( 532223017Sdim Offset > 512*1024-8 ? Win64EH::UOP_SaveNonVolBig : Win64EH::UOP_SaveNonVol, 533223017Sdim Label, Register, Offset); 534223017Sdim EmitLabel(Label); 535223017Sdim CurFrame->Instructions.push_back(Inst); 536223017Sdim} 537223017Sdim 538223017Sdimvoid MCStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) { 539223017Sdim EnsureValidW64UnwindInfo(); 540223017Sdim if (Offset & 0x0F) 541223017Sdim report_fatal_error("Misaligned saved vector register offset!"); 542223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 543223017Sdim MCSymbol *Label = getContext().CreateTempSymbol(); 544223017Sdim MCWin64EHInstruction Inst( 545223017Sdim Offset > 512*1024-16 ? Win64EH::UOP_SaveXMM128Big : Win64EH::UOP_SaveXMM128, 546223017Sdim Label, Register, Offset); 547223017Sdim EmitLabel(Label); 548223017Sdim CurFrame->Instructions.push_back(Inst); 549223017Sdim} 550223017Sdim 551223017Sdimvoid MCStreamer::EmitWin64EHPushFrame(bool Code) { 552223017Sdim EnsureValidW64UnwindInfo(); 553223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 554223017Sdim if (CurFrame->Instructions.size() > 0) 555223017Sdim report_fatal_error("If present, PushMachFrame must be the first UOP"); 556223017Sdim MCSymbol *Label = getContext().CreateTempSymbol(); 557223017Sdim MCWin64EHInstruction Inst(Win64EH::UOP_PushMachFrame, Label, Code); 558223017Sdim EmitLabel(Label); 559223017Sdim CurFrame->Instructions.push_back(Inst); 560223017Sdim} 561223017Sdim 562223017Sdimvoid MCStreamer::EmitWin64EHEndProlog() { 563223017Sdim EnsureValidW64UnwindInfo(); 564223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 565223017Sdim CurFrame->PrologEnd = getContext().CreateTempSymbol(); 566223017Sdim EmitLabel(CurFrame->PrologEnd); 567223017Sdim} 568223017Sdim 569234353Sdimvoid MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { 570234353Sdim llvm_unreachable("This file format doesn't support this directive"); 571234353Sdim} 572234353Sdim 573208599Srdivacky/// EmitRawText - If this file is backed by an assembly streamer, this dumps 574206274Srdivacky/// the specified string in the output .s file. This capability is 575206274Srdivacky/// indicated by the hasRawTextSupport() predicate. 576263508Sdimvoid MCStreamer::EmitRawTextImpl(StringRef String) { 577206274Srdivacky errs() << "EmitRawText called on an MCStreamer that doesn't support it, " 578206274Srdivacky " something must not be fully mc'ized\n"; 579206274Srdivacky abort(); 580206274Srdivacky} 581206274Srdivacky 582206274Srdivackyvoid MCStreamer::EmitRawText(const Twine &T) { 583206274Srdivacky SmallString<128> Str; 584263508Sdim EmitRawTextImpl(T.toStringRef(Str)); 585206274Srdivacky} 586223017Sdim 587263508Sdimvoid MCStreamer::EmitFrames(MCAsmBackend *MAB, bool usingCFI) { 588223017Sdim if (!getNumFrameInfos()) 589223017Sdim return; 590223017Sdim 591223017Sdim if (EmitEHFrame) 592263508Sdim MCDwarfFrameEmitter::Emit(*this, MAB, usingCFI, true); 593223017Sdim 594223017Sdim if (EmitDebugFrame) 595263508Sdim MCDwarfFrameEmitter::Emit(*this, MAB, usingCFI, false); 596223017Sdim} 597223017Sdim 598223017Sdimvoid MCStreamer::EmitW64Tables() { 599223017Sdim if (!getNumW64UnwindInfos()) 600223017Sdim return; 601223017Sdim 602223017Sdim MCWin64EHUnwindEmitter::Emit(*this); 603223017Sdim} 604234353Sdim 605234353Sdimvoid MCStreamer::Finish() { 606234353Sdim if (!FrameInfos.empty() && !FrameInfos.back().End) 607234353Sdim report_fatal_error("Unfinished frame!"); 608234353Sdim 609234353Sdim FinishImpl(); 610234353Sdim} 611249423Sdim 612249423SdimMCSymbolData &MCStreamer::getOrCreateSymbolData(MCSymbol *Symbol) { 613249423Sdim report_fatal_error("Not supported!"); 614249423Sdim return *(static_cast<MCSymbolData*>(0)); 615249423Sdim} 616