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" 13218893Sdim#include "llvm/MC/MCAsmInfo.h" 14218893Sdim#include "llvm/MC/MCContext.h" 15202878Srdivacky#include "llvm/MC/MCExpr.h" 16218893Sdim#include "llvm/MC/MCObjectWriter.h" 17221345Sdim#include "llvm/MC/MCSymbol.h" 18218893Sdim#include "llvm/Support/ErrorHandling.h" 19249423Sdim#include "llvm/Support/LEB128.h" 20202878Srdivacky#include "llvm/Support/raw_ostream.h" 21206274Srdivacky#include <cstdlib> 22195098Sedusing namespace llvm; 23195098Sed 24249423SdimMCStreamer::MCStreamer(StreamerKind Kind, MCContext &Ctx) 25249423Sdim : Kind(Kind), Context(Ctx), EmitEHFrame(true), EmitDebugFrame(false), 26249423Sdim CurrentW64UnwindInfo(0), LastSymbol(0), AutoInitSections(false) { 27251662Sdim SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>()); 28195098Sed} 29195098Sed 30195098SedMCStreamer::~MCStreamer() { 31223017Sdim for (unsigned i = 0; i < getNumW64UnwindInfos(); ++i) 32223017Sdim delete W64UnwindInfos[i]; 33195098Sed} 34202878Srdivacky 35249423Sdimvoid MCStreamer::reset() { 36249423Sdim for (unsigned i = 0; i < getNumW64UnwindInfos(); ++i) 37249423Sdim delete W64UnwindInfos[i]; 38251662Sdim W64UnwindInfos.clear(); 39249423Sdim EmitEHFrame = true; 40249423Sdim EmitDebugFrame = false; 41249423Sdim CurrentW64UnwindInfo = 0; 42249423Sdim LastSymbol = 0; 43249423Sdim SectionStack.clear(); 44251662Sdim SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>()); 45249423Sdim} 46249423Sdim 47221345Sdimconst MCExpr *MCStreamer::BuildSymbolDiff(MCContext &Context, 48221345Sdim const MCSymbol *A, 49221345Sdim const MCSymbol *B) { 50221345Sdim MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 51221345Sdim const MCExpr *ARef = 52221345Sdim MCSymbolRefExpr::Create(A, Variant, Context); 53221345Sdim const MCExpr *BRef = 54221345Sdim MCSymbolRefExpr::Create(B, Variant, Context); 55221345Sdim const MCExpr *AddrDelta = 56221345Sdim MCBinaryExpr::Create(MCBinaryExpr::Sub, ARef, BRef, Context); 57221345Sdim return AddrDelta; 58221345Sdim} 59221345Sdim 60223017Sdimconst MCExpr *MCStreamer::ForceExpAbs(const MCExpr* Expr) { 61223017Sdim if (Context.getAsmInfo().hasAggressiveSymbolFolding() || 62223017Sdim isa<MCSymbolRefExpr>(Expr)) 63223017Sdim return Expr; 64221345Sdim 65223017Sdim MCSymbol *ABS = Context.CreateTempSymbol(); 66223017Sdim EmitAssignment(ABS, Expr); 67223017Sdim return MCSymbolRefExpr::Create(ABS, Context); 68221345Sdim} 69221345Sdim 70202878Srdivackyraw_ostream &MCStreamer::GetCommentOS() { 71202878Srdivacky // By default, discard comments. 72202878Srdivacky return nulls(); 73202878Srdivacky} 74202878Srdivacky 75218893Sdimvoid MCStreamer::EmitDwarfSetLineAddr(int64_t LineDelta, 76218893Sdim const MCSymbol *Label, int PointerSize) { 77218893Sdim // emit the sequence to set the address 78218893Sdim EmitIntValue(dwarf::DW_LNS_extended_op, 1); 79218893Sdim EmitULEB128IntValue(PointerSize + 1); 80218893Sdim EmitIntValue(dwarf::DW_LNE_set_address, 1); 81218893Sdim EmitSymbolValue(Label, PointerSize); 82202878Srdivacky 83218893Sdim // emit the sequence for the LineDelta (from 1) and a zero address delta. 84218893Sdim MCDwarfLineAddr::Emit(this, LineDelta, 0); 85218893Sdim} 86218893Sdim 87202878Srdivacky/// EmitIntValue - Special case of EmitValue that avoids the client having to 88202878Srdivacky/// pass in a MCExpr for constant integers. 89202878Srdivackyvoid MCStreamer::EmitIntValue(uint64_t Value, unsigned Size, 90202878Srdivacky unsigned AddrSpace) { 91218893Sdim assert(Size <= 8 && "Invalid size"); 92218893Sdim assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) && 93218893Sdim "Invalid size"); 94218893Sdim char buf[8]; 95224145Sdim const bool isLittleEndian = Context.getAsmInfo().isLittleEndian(); 96223017Sdim for (unsigned i = 0; i != Size; ++i) { 97223017Sdim unsigned index = isLittleEndian ? i : (Size - i - 1); 98223017Sdim buf[i] = uint8_t(Value >> (index * 8)); 99223017Sdim } 100218893Sdim EmitBytes(StringRef(buf, Size), AddrSpace); 101202878Srdivacky} 102202878Srdivacky 103218893Sdim/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the 104218893Sdim/// client having to pass in a MCExpr for constant integers. 105249423Sdimvoid MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned Padding, 106249423Sdim unsigned AddrSpace) { 107234353Sdim SmallString<128> Tmp; 108218893Sdim raw_svector_ostream OSE(Tmp); 109239462Sdim encodeULEB128(Value, OSE, Padding); 110218893Sdim EmitBytes(OSE.str(), AddrSpace); 111218893Sdim} 112218893Sdim 113218893Sdim/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the 114218893Sdim/// client having to pass in a MCExpr for constant integers. 115218893Sdimvoid MCStreamer::EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace) { 116234353Sdim SmallString<128> Tmp; 117218893Sdim raw_svector_ostream OSE(Tmp); 118239462Sdim encodeSLEB128(Value, OSE); 119218893Sdim EmitBytes(OSE.str(), AddrSpace); 120218893Sdim} 121218893Sdim 122218893Sdimvoid MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size, 123218893Sdim unsigned AddrSpace) { 124223017Sdim const MCExpr *ABS = ForceExpAbs(Value); 125223017Sdim EmitValue(ABS, Size, AddrSpace); 126218893Sdim} 127218893Sdim 128218893Sdim 129218893Sdimvoid MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, 130218893Sdim unsigned AddrSpace) { 131221345Sdim EmitValueImpl(Value, Size, AddrSpace); 132218893Sdim} 133218893Sdim 134204961Srdivackyvoid MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, 135221345Sdim unsigned AddrSpace) { 136221345Sdim EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size, 137218893Sdim AddrSpace); 138218893Sdim} 139218893Sdim 140234353Sdimvoid MCStreamer::EmitGPRel64Value(const MCExpr *Value) { 141234353Sdim report_fatal_error("unsupported directive in streamer"); 142234353Sdim} 143234353Sdim 144218893Sdimvoid MCStreamer::EmitGPRel32Value(const MCExpr *Value) { 145218893Sdim report_fatal_error("unsupported directive in streamer"); 146218893Sdim} 147218893Sdim 148202878Srdivacky/// EmitFill - Emit NumBytes bytes worth of the value specified by 149202878Srdivacky/// FillValue. This implements directives such as '.space'. 150202878Srdivackyvoid MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, 151202878Srdivacky unsigned AddrSpace) { 152202878Srdivacky const MCExpr *E = MCConstantExpr::Create(FillValue, getContext()); 153202878Srdivacky for (uint64_t i = 0, e = NumBytes; i != e; ++i) 154202878Srdivacky EmitValue(E, 1, AddrSpace); 155202878Srdivacky} 156206274Srdivacky 157218893Sdimbool MCStreamer::EmitDwarfFileDirective(unsigned FileNo, 158234353Sdim StringRef Directory, 159249423Sdim StringRef Filename, unsigned CUID) { 160249423Sdim return getContext().GetDwarfFile(Directory, Filename, FileNo, CUID) == 0; 161218893Sdim} 162218893Sdim 163218893Sdimvoid MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 164218893Sdim unsigned Column, unsigned Flags, 165218893Sdim unsigned Isa, 166221345Sdim unsigned Discriminator, 167221345Sdim StringRef FileName) { 168218893Sdim getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa, 169218893Sdim Discriminator); 170218893Sdim} 171218893Sdim 172218893SdimMCDwarfFrameInfo *MCStreamer::getCurrentFrameInfo() { 173218893Sdim if (FrameInfos.empty()) 174249423Sdim return 0; 175218893Sdim return &FrameInfos.back(); 176218893Sdim} 177218893Sdim 178218893Sdimvoid MCStreamer::EnsureValidFrame() { 179218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 180218893Sdim if (!CurFrame || CurFrame->End) 181218893Sdim report_fatal_error("No open frame"); 182218893Sdim} 183218893Sdim 184221345Sdimvoid MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, 185221345Sdim MCSymbol *EHSymbol) { 186221345Sdim} 187221345Sdim 188221345Sdimvoid MCStreamer::EmitLabel(MCSymbol *Symbol) { 189221345Sdim assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); 190251662Sdim assert(getCurrentSection().first && "Cannot emit before setting section!"); 191251662Sdim Symbol->setSection(*getCurrentSection().first); 192226633Sdim LastSymbol = Symbol; 193226633Sdim} 194221345Sdim 195249423Sdimvoid MCStreamer::EmitDebugLabel(MCSymbol *Symbol) { 196249423Sdim assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); 197251662Sdim assert(getCurrentSection().first && "Cannot emit before setting section!"); 198251662Sdim Symbol->setSection(*getCurrentSection().first); 199249423Sdim LastSymbol = Symbol; 200249423Sdim} 201249423Sdim 202226633Sdimvoid MCStreamer::EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding) { 203226633Sdim EnsureValidFrame(); 204226633Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 205226633Sdim CurFrame->CompactUnwindEncoding = CompactUnwindEncoding; 206226633Sdim} 207226633Sdim 208223017Sdimvoid MCStreamer::EmitCFISections(bool EH, bool Debug) { 209223017Sdim assert(EH || Debug); 210223017Sdim EmitEHFrame = EH; 211223017Sdim EmitDebugFrame = Debug; 212223017Sdim} 213223017Sdim 214221345Sdimvoid MCStreamer::EmitCFIStartProc() { 215218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 216221345Sdim if (CurFrame && !CurFrame->End) 217218893Sdim report_fatal_error("Starting a frame before finishing the previous one!"); 218226633Sdim 219218893Sdim MCDwarfFrameInfo Frame; 220234353Sdim EmitCFIStartProcImpl(Frame); 221234353Sdim 222234353Sdim FrameInfos.push_back(Frame); 223234353Sdim} 224234353Sdim 225234353Sdimvoid MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 226234353Sdim} 227234353Sdim 228234353Sdimvoid MCStreamer::RecordProcStart(MCDwarfFrameInfo &Frame) { 229226633Sdim Frame.Function = LastSymbol; 230226633Sdim // If the function is externally visible, we need to create a local 231226633Sdim // symbol to avoid relocations. 232226633Sdim StringRef Prefix = getContext().getAsmInfo().getPrivateGlobalPrefix(); 233226633Sdim if (LastSymbol && LastSymbol->getName().startswith(Prefix)) { 234226633Sdim Frame.Begin = LastSymbol; 235226633Sdim } else { 236226633Sdim Frame.Begin = getContext().CreateTempSymbol(); 237226633Sdim EmitLabel(Frame.Begin); 238226633Sdim } 239218893Sdim} 240218893Sdim 241221345Sdimvoid MCStreamer::EmitCFIEndProc() { 242218893Sdim EnsureValidFrame(); 243218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 244234353Sdim EmitCFIEndProcImpl(*CurFrame); 245218893Sdim} 246218893Sdim 247234353Sdimvoid MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { 248234353Sdim} 249234353Sdim 250234353Sdimvoid MCStreamer::RecordProcEnd(MCDwarfFrameInfo &Frame) { 251234353Sdim Frame.End = getContext().CreateTempSymbol(); 252234353Sdim EmitLabel(Frame.End); 253234353Sdim} 254234353Sdim 255249423SdimMCSymbol *MCStreamer::EmitCFICommon() { 256218893Sdim EnsureValidFrame(); 257218893Sdim MCSymbol *Label = getContext().CreateTempSymbol(); 258218893Sdim EmitLabel(Label); 259249423Sdim return Label; 260249423Sdim} 261249423Sdim 262249423Sdimvoid MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { 263249423Sdim MCSymbol *Label = EmitCFICommon(); 264249423Sdim MCCFIInstruction Instruction = 265249423Sdim MCCFIInstruction::createDefCfa(Label, Register, Offset); 266249423Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 267218893Sdim CurFrame->Instructions.push_back(Instruction); 268218893Sdim} 269218893Sdim 270221345Sdimvoid MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) { 271249423Sdim MCSymbol *Label = EmitCFICommon(); 272249423Sdim MCCFIInstruction Instruction = 273249423Sdim MCCFIInstruction::createDefCfaOffset(Label, Offset); 274218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 275218893Sdim CurFrame->Instructions.push_back(Instruction); 276218893Sdim} 277218893Sdim 278221345Sdimvoid MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { 279249423Sdim MCSymbol *Label = EmitCFICommon(); 280249423Sdim MCCFIInstruction Instruction = 281249423Sdim MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment); 282218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 283221345Sdim CurFrame->Instructions.push_back(Instruction); 284221345Sdim} 285221345Sdim 286221345Sdimvoid MCStreamer::EmitCFIDefCfaRegister(int64_t Register) { 287249423Sdim MCSymbol *Label = EmitCFICommon(); 288249423Sdim MCCFIInstruction Instruction = 289249423Sdim MCCFIInstruction::createDefCfaRegister(Label, Register); 290221345Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 291218893Sdim CurFrame->Instructions.push_back(Instruction); 292218893Sdim} 293218893Sdim 294221345Sdimvoid MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { 295249423Sdim MCSymbol *Label = EmitCFICommon(); 296249423Sdim MCCFIInstruction Instruction = 297249423Sdim MCCFIInstruction::createOffset(Label, Register, Offset); 298218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 299218893Sdim CurFrame->Instructions.push_back(Instruction); 300218893Sdim} 301218893Sdim 302221345Sdimvoid MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) { 303249423Sdim MCSymbol *Label = EmitCFICommon(); 304249423Sdim MCCFIInstruction Instruction = 305249423Sdim MCCFIInstruction::createRelOffset(Label, Register, Offset); 306221345Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 307221345Sdim CurFrame->Instructions.push_back(Instruction); 308221345Sdim} 309221345Sdim 310221345Sdimvoid MCStreamer::EmitCFIPersonality(const MCSymbol *Sym, 311218893Sdim unsigned Encoding) { 312218893Sdim EnsureValidFrame(); 313218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 314218893Sdim CurFrame->Personality = Sym; 315218893Sdim CurFrame->PersonalityEncoding = Encoding; 316218893Sdim} 317218893Sdim 318221345Sdimvoid MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { 319218893Sdim EnsureValidFrame(); 320218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 321218893Sdim CurFrame->Lsda = Sym; 322218893Sdim CurFrame->LsdaEncoding = Encoding; 323218893Sdim} 324218893Sdim 325221345Sdimvoid MCStreamer::EmitCFIRememberState() { 326249423Sdim MCSymbol *Label = EmitCFICommon(); 327249423Sdim MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label); 328218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 329218893Sdim CurFrame->Instructions.push_back(Instruction); 330218893Sdim} 331218893Sdim 332221345Sdimvoid MCStreamer::EmitCFIRestoreState() { 333218893Sdim // FIXME: Error if there is no matching cfi_remember_state. 334249423Sdim MCSymbol *Label = EmitCFICommon(); 335249423Sdim MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label); 336218893Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 337218893Sdim CurFrame->Instructions.push_back(Instruction); 338218893Sdim} 339218893Sdim 340221345Sdimvoid MCStreamer::EmitCFISameValue(int64_t Register) { 341249423Sdim MCSymbol *Label = EmitCFICommon(); 342249423Sdim MCCFIInstruction Instruction = 343249423Sdim MCCFIInstruction::createSameValue(Label, Register); 344221345Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 345221345Sdim CurFrame->Instructions.push_back(Instruction); 346221345Sdim} 347221345Sdim 348234353Sdimvoid MCStreamer::EmitCFIRestore(int64_t Register) { 349249423Sdim MCSymbol *Label = EmitCFICommon(); 350249423Sdim MCCFIInstruction Instruction = 351249423Sdim MCCFIInstruction::createRestore(Label, Register); 352234353Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 353234353Sdim CurFrame->Instructions.push_back(Instruction); 354234353Sdim} 355234353Sdim 356234353Sdimvoid MCStreamer::EmitCFIEscape(StringRef Values) { 357249423Sdim MCSymbol *Label = EmitCFICommon(); 358249423Sdim MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values); 359234353Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 360234353Sdim CurFrame->Instructions.push_back(Instruction); 361234353Sdim} 362234353Sdim 363234353Sdimvoid MCStreamer::EmitCFISignalFrame() { 364234353Sdim EnsureValidFrame(); 365234353Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 366234353Sdim CurFrame->IsSignalFrame = true; 367234353Sdim} 368234353Sdim 369249423Sdimvoid MCStreamer::EmitCFIUndefined(int64_t Register) { 370249423Sdim MCSymbol *Label = EmitCFICommon(); 371249423Sdim MCCFIInstruction Instruction = 372249423Sdim MCCFIInstruction::createUndefined(Label, Register); 373249423Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 374249423Sdim CurFrame->Instructions.push_back(Instruction); 375249423Sdim} 376249423Sdim 377249423Sdimvoid MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) { 378249423Sdim MCSymbol *Label = EmitCFICommon(); 379249423Sdim MCCFIInstruction Instruction = 380249423Sdim MCCFIInstruction::createRegister(Label, Register1, Register2); 381249423Sdim MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 382249423Sdim CurFrame->Instructions.push_back(Instruction); 383249423Sdim} 384249423Sdim 385223017Sdimvoid MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) { 386223017Sdim W64UnwindInfos.push_back(Frame); 387223017Sdim CurrentW64UnwindInfo = W64UnwindInfos.back(); 388223017Sdim} 389223017Sdim 390223017Sdimvoid MCStreamer::EnsureValidW64UnwindInfo() { 391223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 392223017Sdim if (!CurFrame || CurFrame->End) 393223017Sdim report_fatal_error("No open Win64 EH frame function!"); 394223017Sdim} 395223017Sdim 396223017Sdimvoid MCStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) { 397223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 398223017Sdim if (CurFrame && !CurFrame->End) 399223017Sdim report_fatal_error("Starting a function before ending the previous one!"); 400223017Sdim MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo; 401223017Sdim Frame->Begin = getContext().CreateTempSymbol(); 402223017Sdim Frame->Function = Symbol; 403223017Sdim EmitLabel(Frame->Begin); 404223017Sdim setCurrentW64UnwindInfo(Frame); 405223017Sdim} 406223017Sdim 407223017Sdimvoid MCStreamer::EmitWin64EHEndProc() { 408223017Sdim EnsureValidW64UnwindInfo(); 409223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 410223017Sdim if (CurFrame->ChainedParent) 411223017Sdim report_fatal_error("Not all chained regions terminated!"); 412223017Sdim CurFrame->End = getContext().CreateTempSymbol(); 413223017Sdim EmitLabel(CurFrame->End); 414223017Sdim} 415223017Sdim 416223017Sdimvoid MCStreamer::EmitWin64EHStartChained() { 417223017Sdim EnsureValidW64UnwindInfo(); 418223017Sdim MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo; 419223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 420223017Sdim Frame->Begin = getContext().CreateTempSymbol(); 421223017Sdim Frame->Function = CurFrame->Function; 422223017Sdim Frame->ChainedParent = CurFrame; 423223017Sdim EmitLabel(Frame->Begin); 424223017Sdim setCurrentW64UnwindInfo(Frame); 425223017Sdim} 426223017Sdim 427223017Sdimvoid MCStreamer::EmitWin64EHEndChained() { 428223017Sdim EnsureValidW64UnwindInfo(); 429223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 430223017Sdim if (!CurFrame->ChainedParent) 431223017Sdim report_fatal_error("End of a chained region outside a chained region!"); 432223017Sdim CurFrame->End = getContext().CreateTempSymbol(); 433223017Sdim EmitLabel(CurFrame->End); 434223017Sdim CurrentW64UnwindInfo = CurFrame->ChainedParent; 435223017Sdim} 436223017Sdim 437223017Sdimvoid MCStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, 438223017Sdim bool Except) { 439223017Sdim EnsureValidW64UnwindInfo(); 440223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 441223017Sdim if (CurFrame->ChainedParent) 442223017Sdim report_fatal_error("Chained unwind areas can't have handlers!"); 443223017Sdim CurFrame->ExceptionHandler = Sym; 444223017Sdim if (!Except && !Unwind) 445223017Sdim report_fatal_error("Don't know what kind of handler this is!"); 446223017Sdim if (Unwind) 447223017Sdim CurFrame->HandlesUnwind = true; 448223017Sdim if (Except) 449223017Sdim CurFrame->HandlesExceptions = true; 450223017Sdim} 451223017Sdim 452223017Sdimvoid MCStreamer::EmitWin64EHHandlerData() { 453223017Sdim EnsureValidW64UnwindInfo(); 454223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 455223017Sdim if (CurFrame->ChainedParent) 456223017Sdim report_fatal_error("Chained unwind areas can't have handlers!"); 457223017Sdim} 458223017Sdim 459223017Sdimvoid MCStreamer::EmitWin64EHPushReg(unsigned Register) { 460223017Sdim EnsureValidW64UnwindInfo(); 461223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 462223017Sdim MCSymbol *Label = getContext().CreateTempSymbol(); 463223017Sdim MCWin64EHInstruction Inst(Win64EH::UOP_PushNonVol, Label, Register); 464223017Sdim EmitLabel(Label); 465223017Sdim CurFrame->Instructions.push_back(Inst); 466223017Sdim} 467223017Sdim 468223017Sdimvoid MCStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) { 469223017Sdim EnsureValidW64UnwindInfo(); 470223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 471223017Sdim if (CurFrame->LastFrameInst >= 0) 472223017Sdim report_fatal_error("Frame register and offset already specified!"); 473223017Sdim if (Offset & 0x0F) 474223017Sdim report_fatal_error("Misaligned frame pointer offset!"); 475249423Sdim MCWin64EHInstruction Inst(Win64EH::UOP_SetFPReg, 0, Register, Offset); 476223017Sdim CurFrame->LastFrameInst = CurFrame->Instructions.size(); 477223017Sdim CurFrame->Instructions.push_back(Inst); 478223017Sdim} 479223017Sdim 480223017Sdimvoid MCStreamer::EmitWin64EHAllocStack(unsigned Size) { 481223017Sdim EnsureValidW64UnwindInfo(); 482223017Sdim if (Size & 7) 483223017Sdim report_fatal_error("Misaligned stack allocation!"); 484223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 485223017Sdim MCSymbol *Label = getContext().CreateTempSymbol(); 486223017Sdim MCWin64EHInstruction Inst(Label, Size); 487223017Sdim EmitLabel(Label); 488223017Sdim CurFrame->Instructions.push_back(Inst); 489223017Sdim} 490223017Sdim 491223017Sdimvoid MCStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) { 492223017Sdim EnsureValidW64UnwindInfo(); 493223017Sdim if (Offset & 7) 494223017Sdim report_fatal_error("Misaligned saved register offset!"); 495223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 496223017Sdim MCSymbol *Label = getContext().CreateTempSymbol(); 497223017Sdim MCWin64EHInstruction Inst( 498223017Sdim Offset > 512*1024-8 ? Win64EH::UOP_SaveNonVolBig : Win64EH::UOP_SaveNonVol, 499223017Sdim Label, Register, Offset); 500223017Sdim EmitLabel(Label); 501223017Sdim CurFrame->Instructions.push_back(Inst); 502223017Sdim} 503223017Sdim 504223017Sdimvoid MCStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) { 505223017Sdim EnsureValidW64UnwindInfo(); 506223017Sdim if (Offset & 0x0F) 507223017Sdim report_fatal_error("Misaligned saved vector register offset!"); 508223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 509223017Sdim MCSymbol *Label = getContext().CreateTempSymbol(); 510223017Sdim MCWin64EHInstruction Inst( 511223017Sdim Offset > 512*1024-16 ? Win64EH::UOP_SaveXMM128Big : Win64EH::UOP_SaveXMM128, 512223017Sdim Label, Register, Offset); 513223017Sdim EmitLabel(Label); 514223017Sdim CurFrame->Instructions.push_back(Inst); 515223017Sdim} 516223017Sdim 517223017Sdimvoid MCStreamer::EmitWin64EHPushFrame(bool Code) { 518223017Sdim EnsureValidW64UnwindInfo(); 519223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 520223017Sdim if (CurFrame->Instructions.size() > 0) 521223017Sdim report_fatal_error("If present, PushMachFrame must be the first UOP"); 522223017Sdim MCSymbol *Label = getContext().CreateTempSymbol(); 523223017Sdim MCWin64EHInstruction Inst(Win64EH::UOP_PushMachFrame, Label, Code); 524223017Sdim EmitLabel(Label); 525223017Sdim CurFrame->Instructions.push_back(Inst); 526223017Sdim} 527223017Sdim 528223017Sdimvoid MCStreamer::EmitWin64EHEndProlog() { 529223017Sdim EnsureValidW64UnwindInfo(); 530223017Sdim MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 531223017Sdim CurFrame->PrologEnd = getContext().CreateTempSymbol(); 532223017Sdim EmitLabel(CurFrame->PrologEnd); 533223017Sdim} 534223017Sdim 535234353Sdimvoid MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { 536234353Sdim llvm_unreachable("This file format doesn't support this directive"); 537234353Sdim} 538234353Sdim 539221345Sdimvoid MCStreamer::EmitFnStart() { 540221345Sdim errs() << "Not implemented yet\n"; 541221345Sdim abort(); 542221345Sdim} 543221345Sdim 544221345Sdimvoid MCStreamer::EmitFnEnd() { 545221345Sdim errs() << "Not implemented yet\n"; 546221345Sdim abort(); 547221345Sdim} 548221345Sdim 549221345Sdimvoid MCStreamer::EmitCantUnwind() { 550221345Sdim errs() << "Not implemented yet\n"; 551221345Sdim abort(); 552221345Sdim} 553221345Sdim 554221345Sdimvoid MCStreamer::EmitHandlerData() { 555221345Sdim errs() << "Not implemented yet\n"; 556221345Sdim abort(); 557221345Sdim} 558221345Sdim 559221345Sdimvoid MCStreamer::EmitPersonality(const MCSymbol *Personality) { 560221345Sdim errs() << "Not implemented yet\n"; 561221345Sdim abort(); 562221345Sdim} 563221345Sdim 564221345Sdimvoid MCStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) { 565221345Sdim errs() << "Not implemented yet\n"; 566221345Sdim abort(); 567221345Sdim} 568221345Sdim 569221345Sdimvoid MCStreamer::EmitPad(int64_t Offset) { 570221345Sdim errs() << "Not implemented yet\n"; 571221345Sdim abort(); 572221345Sdim} 573221345Sdim 574221345Sdimvoid MCStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool) { 575221345Sdim errs() << "Not implemented yet\n"; 576221345Sdim abort(); 577221345Sdim} 578221345Sdim 579243830Sdimvoid MCStreamer::EmitTCEntry(const MCSymbol &S) { 580243830Sdim llvm_unreachable("Unsupported method"); 581243830Sdim} 582243830Sdim 583208599Srdivacky/// EmitRawText - If this file is backed by an assembly streamer, this dumps 584206274Srdivacky/// the specified string in the output .s file. This capability is 585206274Srdivacky/// indicated by the hasRawTextSupport() predicate. 586206274Srdivackyvoid MCStreamer::EmitRawText(StringRef String) { 587206274Srdivacky errs() << "EmitRawText called on an MCStreamer that doesn't support it, " 588206274Srdivacky " something must not be fully mc'ized\n"; 589206274Srdivacky abort(); 590206274Srdivacky} 591206274Srdivacky 592206274Srdivackyvoid MCStreamer::EmitRawText(const Twine &T) { 593206274Srdivacky SmallString<128> Str; 594206274Srdivacky T.toVector(Str); 595206274Srdivacky EmitRawText(Str.str()); 596206274Srdivacky} 597223017Sdim 598223017Sdimvoid MCStreamer::EmitFrames(bool usingCFI) { 599223017Sdim if (!getNumFrameInfos()) 600223017Sdim return; 601223017Sdim 602223017Sdim if (EmitEHFrame) 603223017Sdim MCDwarfFrameEmitter::Emit(*this, usingCFI, true); 604223017Sdim 605223017Sdim if (EmitDebugFrame) 606223017Sdim MCDwarfFrameEmitter::Emit(*this, usingCFI, false); 607223017Sdim} 608223017Sdim 609223017Sdimvoid MCStreamer::EmitW64Tables() { 610223017Sdim if (!getNumW64UnwindInfos()) 611223017Sdim return; 612223017Sdim 613223017Sdim MCWin64EHUnwindEmitter::Emit(*this); 614223017Sdim} 615234353Sdim 616234353Sdimvoid MCStreamer::Finish() { 617234353Sdim if (!FrameInfos.empty() && !FrameInfos.back().End) 618234353Sdim report_fatal_error("Unfinished frame!"); 619234353Sdim 620234353Sdim FinishImpl(); 621234353Sdim} 622249423Sdim 623249423SdimMCSymbolData &MCStreamer::getOrCreateSymbolData(MCSymbol *Symbol) { 624249423Sdim report_fatal_error("Not supported!"); 625249423Sdim return *(static_cast<MCSymbolData*>(0)); 626249423Sdim} 627