1 //===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/MC/MCAsmInfo.h" 11 #include "llvm/MC/MCContext.h" 12 #include "llvm/MC/MCStreamer.h" 13 #include "llvm/MC/MCExpr.h" 14 #include "llvm/MC/MCObjectWriter.h" 15 #include "llvm/MC/MCSymbol.h" 16 #include "llvm/Support/ErrorHandling.h" 17 #include "llvm/Support/raw_ostream.h" 18 #include "llvm/ADT/SmallString.h" 19 #include "llvm/ADT/Twine.h" 20 #include <cstdlib> 21 using namespace llvm; 22 23 MCStreamer::MCStreamer(MCContext &Ctx) : Context(Ctx), EmitEHFrame(true), 24 EmitDebugFrame(false), 25 CurrentW64UnwindInfo(0), 26 LastSymbol(0), 27 UniqueCodeBeginSuffix(0), 28 UniqueDataBeginSuffix(0) { 29 const MCSection *section = NULL; 30 SectionStack.push_back(std::make_pair(section, section)); 31 } 32 33 MCStreamer::~MCStreamer() { 34 for (unsigned i = 0; i < getNumW64UnwindInfos(); ++i) 35 delete W64UnwindInfos[i]; 36 } 37 38 const MCExpr *MCStreamer::BuildSymbolDiff(MCContext &Context, 39 const MCSymbol *A, 40 const MCSymbol *B) { 41 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; 42 const MCExpr *ARef = 43 MCSymbolRefExpr::Create(A, Variant, Context); 44 const MCExpr *BRef = 45 MCSymbolRefExpr::Create(B, Variant, Context); 46 const MCExpr *AddrDelta = 47 MCBinaryExpr::Create(MCBinaryExpr::Sub, ARef, BRef, Context); 48 return AddrDelta; 49 } 50 51 const MCExpr *MCStreamer::ForceExpAbs(const MCExpr* Expr) { 52 if (Context.getAsmInfo().hasAggressiveSymbolFolding() || 53 isa<MCSymbolRefExpr>(Expr)) 54 return Expr; 55 56 MCSymbol *ABS = Context.CreateTempSymbol(); 57 EmitAssignment(ABS, Expr); 58 return MCSymbolRefExpr::Create(ABS, Context); 59 } 60 61 raw_ostream &MCStreamer::GetCommentOS() { 62 // By default, discard comments. 63 return nulls(); 64 } 65 66 void MCStreamer::EmitDwarfSetLineAddr(int64_t LineDelta, 67 const MCSymbol *Label, int PointerSize) { 68 // emit the sequence to set the address 69 EmitIntValue(dwarf::DW_LNS_extended_op, 1); 70 EmitULEB128IntValue(PointerSize + 1); 71 EmitIntValue(dwarf::DW_LNE_set_address, 1); 72 EmitSymbolValue(Label, PointerSize); 73 74 // emit the sequence for the LineDelta (from 1) and a zero address delta. 75 MCDwarfLineAddr::Emit(this, LineDelta, 0); 76 } 77 78 /// EmitIntValue - Special case of EmitValue that avoids the client having to 79 /// pass in a MCExpr for constant integers. 80 void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size, 81 unsigned AddrSpace) { 82 assert(Size <= 8 && "Invalid size"); 83 assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) && 84 "Invalid size"); 85 char buf[8]; 86 const bool isLittleEndian = Context.getAsmInfo().isLittleEndian(); 87 for (unsigned i = 0; i != Size; ++i) { 88 unsigned index = isLittleEndian ? i : (Size - i - 1); 89 buf[i] = uint8_t(Value >> (index * 8)); 90 } 91 EmitBytes(StringRef(buf, Size), AddrSpace); 92 } 93 94 /// EmitULEB128Value - Special case of EmitULEB128Value that avoids the 95 /// client having to pass in a MCExpr for constant integers. 96 void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace, 97 unsigned Padding) { 98 SmallString<128> Tmp; 99 raw_svector_ostream OSE(Tmp); 100 MCObjectWriter::EncodeULEB128(Value, OSE, Padding); 101 EmitBytes(OSE.str(), AddrSpace); 102 } 103 104 /// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the 105 /// client having to pass in a MCExpr for constant integers. 106 void MCStreamer::EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace) { 107 SmallString<128> Tmp; 108 raw_svector_ostream OSE(Tmp); 109 MCObjectWriter::EncodeSLEB128(Value, OSE); 110 EmitBytes(OSE.str(), AddrSpace); 111 } 112 113 void MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size, 114 unsigned AddrSpace) { 115 const MCExpr *ABS = ForceExpAbs(Value); 116 EmitValue(ABS, Size, AddrSpace); 117 } 118 119 120 void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, 121 unsigned AddrSpace) { 122 EmitValueImpl(Value, Size, AddrSpace); 123 } 124 125 void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, 126 unsigned AddrSpace) { 127 EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size, 128 AddrSpace); 129 } 130 131 void MCStreamer::EmitGPRel64Value(const MCExpr *Value) { 132 report_fatal_error("unsupported directive in streamer"); 133 } 134 135 void MCStreamer::EmitGPRel32Value(const MCExpr *Value) { 136 report_fatal_error("unsupported directive in streamer"); 137 } 138 139 /// EmitFill - Emit NumBytes bytes worth of the value specified by 140 /// FillValue. This implements directives such as '.space'. 141 void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, 142 unsigned AddrSpace) { 143 const MCExpr *E = MCConstantExpr::Create(FillValue, getContext()); 144 for (uint64_t i = 0, e = NumBytes; i != e; ++i) 145 EmitValue(E, 1, AddrSpace); 146 } 147 148 bool MCStreamer::EmitDwarfFileDirective(unsigned FileNo, 149 StringRef Directory, 150 StringRef Filename) { 151 return getContext().GetDwarfFile(Directory, Filename, FileNo) == 0; 152 } 153 154 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 155 unsigned Column, unsigned Flags, 156 unsigned Isa, 157 unsigned Discriminator, 158 StringRef FileName) { 159 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa, 160 Discriminator); 161 } 162 163 MCDwarfFrameInfo *MCStreamer::getCurrentFrameInfo() { 164 if (FrameInfos.empty()) 165 return NULL; 166 return &FrameInfos.back(); 167 } 168 169 void MCStreamer::EnsureValidFrame() { 170 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 171 if (!CurFrame || CurFrame->End) 172 report_fatal_error("No open frame"); 173 } 174 175 void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, 176 MCSymbol *EHSymbol) { 177 } 178 179 void MCStreamer::EmitLabel(MCSymbol *Symbol) { 180 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); 181 assert(getCurrentSection() && "Cannot emit before setting section!"); 182 Symbol->setSection(*getCurrentSection()); 183 LastSymbol = Symbol; 184 } 185 186 void MCStreamer::EmitDataRegion() { 187 if (RegionIndicator == Data) return; 188 189 MCContext &Context = getContext(); 190 const MCAsmInfo &MAI = Context.getAsmInfo(); 191 if (!MAI.getSupportsDataRegions()) return; 192 193 // Generate a unique symbol name. 194 MCSymbol *NewSym = Context.GetOrCreateSymbol(MAI.getDataBeginLabelName() + 195 Twine(UniqueDataBeginSuffix++)); 196 EmitLabel(NewSym); 197 198 RegionIndicator = Data; 199 } 200 201 void MCStreamer::EmitCodeRegion() { 202 if (RegionIndicator == Code) return; 203 204 MCContext &Context = getContext(); 205 const MCAsmInfo &MAI = Context.getAsmInfo(); 206 if (!MAI.getSupportsDataRegions()) return; 207 208 // Generate a unique symbol name. 209 MCSymbol *NewSym = Context.GetOrCreateSymbol(MAI.getCodeBeginLabelName() + 210 Twine(UniqueCodeBeginSuffix++)); 211 EmitLabel(NewSym); 212 213 RegionIndicator = Code; 214 } 215 216 void MCStreamer::EmitJumpTable8Region() { 217 if (RegionIndicator == JumpTable8) return; 218 219 MCContext &Context = getContext(); 220 const MCAsmInfo &MAI = Context.getAsmInfo(); 221 if (!MAI.getSupportsDataRegions()) return; 222 223 // Generate a unique symbol name. 224 MCSymbol *NewSym = 225 Context.GetOrCreateSymbol(MAI.getJumpTable8BeginLabelName() + 226 Twine(UniqueDataBeginSuffix++)); 227 EmitLabel(NewSym); 228 229 RegionIndicator = JumpTable8; 230 } 231 232 void MCStreamer::EmitJumpTable16Region() { 233 if (RegionIndicator == JumpTable16) return; 234 235 MCContext &Context = getContext(); 236 const MCAsmInfo &MAI = Context.getAsmInfo(); 237 if (!MAI.getSupportsDataRegions()) return; 238 239 // Generate a unique symbol name. 240 MCSymbol *NewSym = 241 Context.GetOrCreateSymbol(MAI.getJumpTable16BeginLabelName() + 242 Twine(UniqueDataBeginSuffix++)); 243 EmitLabel(NewSym); 244 245 RegionIndicator = JumpTable16; 246 } 247 248 249 void MCStreamer::EmitJumpTable32Region() { 250 if (RegionIndicator == JumpTable32) return; 251 252 MCContext &Context = getContext(); 253 const MCAsmInfo &MAI = Context.getAsmInfo(); 254 if (!MAI.getSupportsDataRegions()) return; 255 256 // Generate a unique symbol name. 257 MCSymbol *NewSym = 258 Context.GetOrCreateSymbol(MAI.getJumpTable32BeginLabelName() + 259 Twine(UniqueDataBeginSuffix++)); 260 EmitLabel(NewSym); 261 262 RegionIndicator = JumpTable32; 263 } 264 265 void MCStreamer::EmitCompactUnwindEncoding(uint32_t CompactUnwindEncoding) { 266 EnsureValidFrame(); 267 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 268 CurFrame->CompactUnwindEncoding = CompactUnwindEncoding; 269 } 270 271 void MCStreamer::EmitCFISections(bool EH, bool Debug) { 272 assert(EH || Debug); 273 EmitEHFrame = EH; 274 EmitDebugFrame = Debug; 275 } 276 277 void MCStreamer::EmitCFIStartProc() { 278 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 279 if (CurFrame && !CurFrame->End) 280 report_fatal_error("Starting a frame before finishing the previous one!"); 281 282 MCDwarfFrameInfo Frame; 283 EmitCFIStartProcImpl(Frame); 284 285 FrameInfos.push_back(Frame); 286 RegionIndicator = Code; 287 } 288 289 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) { 290 } 291 292 void MCStreamer::RecordProcStart(MCDwarfFrameInfo &Frame) { 293 Frame.Function = LastSymbol; 294 // If the function is externally visible, we need to create a local 295 // symbol to avoid relocations. 296 StringRef Prefix = getContext().getAsmInfo().getPrivateGlobalPrefix(); 297 if (LastSymbol && LastSymbol->getName().startswith(Prefix)) { 298 Frame.Begin = LastSymbol; 299 } else { 300 Frame.Begin = getContext().CreateTempSymbol(); 301 EmitLabel(Frame.Begin); 302 } 303 } 304 305 void MCStreamer::EmitCFIEndProc() { 306 EnsureValidFrame(); 307 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 308 EmitCFIEndProcImpl(*CurFrame); 309 } 310 311 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { 312 } 313 314 void MCStreamer::RecordProcEnd(MCDwarfFrameInfo &Frame) { 315 Frame.End = getContext().CreateTempSymbol(); 316 EmitLabel(Frame.End); 317 } 318 319 void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { 320 EnsureValidFrame(); 321 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 322 MCSymbol *Label = getContext().CreateTempSymbol(); 323 EmitLabel(Label); 324 MachineLocation Dest(MachineLocation::VirtualFP); 325 MachineLocation Source(Register, -Offset); 326 MCCFIInstruction Instruction(Label, Dest, Source); 327 CurFrame->Instructions.push_back(Instruction); 328 } 329 330 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) { 331 EnsureValidFrame(); 332 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 333 MCSymbol *Label = getContext().CreateTempSymbol(); 334 EmitLabel(Label); 335 MachineLocation Dest(MachineLocation::VirtualFP); 336 MachineLocation Source(MachineLocation::VirtualFP, -Offset); 337 MCCFIInstruction Instruction(Label, Dest, Source); 338 CurFrame->Instructions.push_back(Instruction); 339 } 340 341 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { 342 EnsureValidFrame(); 343 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 344 MCSymbol *Label = getContext().CreateTempSymbol(); 345 EmitLabel(Label); 346 MachineLocation Dest(MachineLocation::VirtualFP); 347 MachineLocation Source(MachineLocation::VirtualFP, Adjustment); 348 MCCFIInstruction Instruction(MCCFIInstruction::RelMove, Label, Dest, Source); 349 CurFrame->Instructions.push_back(Instruction); 350 } 351 352 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) { 353 EnsureValidFrame(); 354 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 355 MCSymbol *Label = getContext().CreateTempSymbol(); 356 EmitLabel(Label); 357 MachineLocation Dest(Register); 358 MachineLocation Source(MachineLocation::VirtualFP); 359 MCCFIInstruction Instruction(Label, Dest, Source); 360 CurFrame->Instructions.push_back(Instruction); 361 } 362 363 void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { 364 EnsureValidFrame(); 365 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 366 MCSymbol *Label = getContext().CreateTempSymbol(); 367 EmitLabel(Label); 368 MachineLocation Dest(Register, Offset); 369 MachineLocation Source(Register, Offset); 370 MCCFIInstruction Instruction(Label, Dest, Source); 371 CurFrame->Instructions.push_back(Instruction); 372 } 373 374 void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) { 375 EnsureValidFrame(); 376 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 377 MCSymbol *Label = getContext().CreateTempSymbol(); 378 EmitLabel(Label); 379 MachineLocation Dest(Register, Offset); 380 MachineLocation Source(Register, Offset); 381 MCCFIInstruction Instruction(MCCFIInstruction::RelMove, Label, Dest, Source); 382 CurFrame->Instructions.push_back(Instruction); 383 } 384 385 void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym, 386 unsigned Encoding) { 387 EnsureValidFrame(); 388 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 389 CurFrame->Personality = Sym; 390 CurFrame->PersonalityEncoding = Encoding; 391 } 392 393 void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { 394 EnsureValidFrame(); 395 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 396 CurFrame->Lsda = Sym; 397 CurFrame->LsdaEncoding = Encoding; 398 } 399 400 void MCStreamer::EmitCFIRememberState() { 401 EnsureValidFrame(); 402 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 403 MCSymbol *Label = getContext().CreateTempSymbol(); 404 EmitLabel(Label); 405 MCCFIInstruction Instruction(MCCFIInstruction::RememberState, Label); 406 CurFrame->Instructions.push_back(Instruction); 407 } 408 409 void MCStreamer::EmitCFIRestoreState() { 410 // FIXME: Error if there is no matching cfi_remember_state. 411 EnsureValidFrame(); 412 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 413 MCSymbol *Label = getContext().CreateTempSymbol(); 414 EmitLabel(Label); 415 MCCFIInstruction Instruction(MCCFIInstruction::RestoreState, Label); 416 CurFrame->Instructions.push_back(Instruction); 417 } 418 419 void MCStreamer::EmitCFISameValue(int64_t Register) { 420 EnsureValidFrame(); 421 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 422 MCSymbol *Label = getContext().CreateTempSymbol(); 423 EmitLabel(Label); 424 MCCFIInstruction Instruction(MCCFIInstruction::SameValue, Label, Register); 425 CurFrame->Instructions.push_back(Instruction); 426 } 427 428 void MCStreamer::EmitCFIRestore(int64_t Register) { 429 EnsureValidFrame(); 430 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 431 MCSymbol *Label = getContext().CreateTempSymbol(); 432 EmitLabel(Label); 433 MCCFIInstruction Instruction(MCCFIInstruction::Restore, Label, Register); 434 CurFrame->Instructions.push_back(Instruction); 435 } 436 437 void MCStreamer::EmitCFIEscape(StringRef Values) { 438 EnsureValidFrame(); 439 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 440 MCSymbol *Label = getContext().CreateTempSymbol(); 441 EmitLabel(Label); 442 MCCFIInstruction Instruction(MCCFIInstruction::Escape, Label, Values); 443 CurFrame->Instructions.push_back(Instruction); 444 } 445 446 void MCStreamer::EmitCFISignalFrame() { 447 EnsureValidFrame(); 448 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 449 CurFrame->IsSignalFrame = true; 450 } 451 452 void MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) { 453 W64UnwindInfos.push_back(Frame); 454 CurrentW64UnwindInfo = W64UnwindInfos.back(); 455 } 456 457 void MCStreamer::EnsureValidW64UnwindInfo() { 458 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 459 if (!CurFrame || CurFrame->End) 460 report_fatal_error("No open Win64 EH frame function!"); 461 } 462 463 void MCStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) { 464 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 465 if (CurFrame && !CurFrame->End) 466 report_fatal_error("Starting a function before ending the previous one!"); 467 MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo; 468 Frame->Begin = getContext().CreateTempSymbol(); 469 Frame->Function = Symbol; 470 EmitLabel(Frame->Begin); 471 setCurrentW64UnwindInfo(Frame); 472 } 473 474 void MCStreamer::EmitWin64EHEndProc() { 475 EnsureValidW64UnwindInfo(); 476 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 477 if (CurFrame->ChainedParent) 478 report_fatal_error("Not all chained regions terminated!"); 479 CurFrame->End = getContext().CreateTempSymbol(); 480 EmitLabel(CurFrame->End); 481 } 482 483 void MCStreamer::EmitWin64EHStartChained() { 484 EnsureValidW64UnwindInfo(); 485 MCWin64EHUnwindInfo *Frame = new MCWin64EHUnwindInfo; 486 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 487 Frame->Begin = getContext().CreateTempSymbol(); 488 Frame->Function = CurFrame->Function; 489 Frame->ChainedParent = CurFrame; 490 EmitLabel(Frame->Begin); 491 setCurrentW64UnwindInfo(Frame); 492 } 493 494 void MCStreamer::EmitWin64EHEndChained() { 495 EnsureValidW64UnwindInfo(); 496 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 497 if (!CurFrame->ChainedParent) 498 report_fatal_error("End of a chained region outside a chained region!"); 499 CurFrame->End = getContext().CreateTempSymbol(); 500 EmitLabel(CurFrame->End); 501 CurrentW64UnwindInfo = CurFrame->ChainedParent; 502 } 503 504 void MCStreamer::EmitWin64EHHandler(const MCSymbol *Sym, bool Unwind, 505 bool Except) { 506 EnsureValidW64UnwindInfo(); 507 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 508 if (CurFrame->ChainedParent) 509 report_fatal_error("Chained unwind areas can't have handlers!"); 510 CurFrame->ExceptionHandler = Sym; 511 if (!Except && !Unwind) 512 report_fatal_error("Don't know what kind of handler this is!"); 513 if (Unwind) 514 CurFrame->HandlesUnwind = true; 515 if (Except) 516 CurFrame->HandlesExceptions = true; 517 } 518 519 void MCStreamer::EmitWin64EHHandlerData() { 520 EnsureValidW64UnwindInfo(); 521 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 522 if (CurFrame->ChainedParent) 523 report_fatal_error("Chained unwind areas can't have handlers!"); 524 } 525 526 void MCStreamer::EmitWin64EHPushReg(unsigned Register) { 527 EnsureValidW64UnwindInfo(); 528 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 529 MCSymbol *Label = getContext().CreateTempSymbol(); 530 MCWin64EHInstruction Inst(Win64EH::UOP_PushNonVol, Label, Register); 531 EmitLabel(Label); 532 CurFrame->Instructions.push_back(Inst); 533 } 534 535 void MCStreamer::EmitWin64EHSetFrame(unsigned Register, unsigned Offset) { 536 EnsureValidW64UnwindInfo(); 537 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 538 if (CurFrame->LastFrameInst >= 0) 539 report_fatal_error("Frame register and offset already specified!"); 540 if (Offset & 0x0F) 541 report_fatal_error("Misaligned frame pointer offset!"); 542 MCWin64EHInstruction Inst(Win64EH::UOP_SetFPReg, NULL, Register, Offset); 543 CurFrame->LastFrameInst = CurFrame->Instructions.size(); 544 CurFrame->Instructions.push_back(Inst); 545 } 546 547 void MCStreamer::EmitWin64EHAllocStack(unsigned Size) { 548 EnsureValidW64UnwindInfo(); 549 if (Size & 7) 550 report_fatal_error("Misaligned stack allocation!"); 551 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 552 MCSymbol *Label = getContext().CreateTempSymbol(); 553 MCWin64EHInstruction Inst(Label, Size); 554 EmitLabel(Label); 555 CurFrame->Instructions.push_back(Inst); 556 } 557 558 void MCStreamer::EmitWin64EHSaveReg(unsigned Register, unsigned Offset) { 559 EnsureValidW64UnwindInfo(); 560 if (Offset & 7) 561 report_fatal_error("Misaligned saved register offset!"); 562 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 563 MCSymbol *Label = getContext().CreateTempSymbol(); 564 MCWin64EHInstruction Inst( 565 Offset > 512*1024-8 ? Win64EH::UOP_SaveNonVolBig : Win64EH::UOP_SaveNonVol, 566 Label, Register, Offset); 567 EmitLabel(Label); 568 CurFrame->Instructions.push_back(Inst); 569 } 570 571 void MCStreamer::EmitWin64EHSaveXMM(unsigned Register, unsigned Offset) { 572 EnsureValidW64UnwindInfo(); 573 if (Offset & 0x0F) 574 report_fatal_error("Misaligned saved vector register offset!"); 575 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 576 MCSymbol *Label = getContext().CreateTempSymbol(); 577 MCWin64EHInstruction Inst( 578 Offset > 512*1024-16 ? Win64EH::UOP_SaveXMM128Big : Win64EH::UOP_SaveXMM128, 579 Label, Register, Offset); 580 EmitLabel(Label); 581 CurFrame->Instructions.push_back(Inst); 582 } 583 584 void MCStreamer::EmitWin64EHPushFrame(bool Code) { 585 EnsureValidW64UnwindInfo(); 586 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 587 if (CurFrame->Instructions.size() > 0) 588 report_fatal_error("If present, PushMachFrame must be the first UOP"); 589 MCSymbol *Label = getContext().CreateTempSymbol(); 590 MCWin64EHInstruction Inst(Win64EH::UOP_PushMachFrame, Label, Code); 591 EmitLabel(Label); 592 CurFrame->Instructions.push_back(Inst); 593 } 594 595 void MCStreamer::EmitWin64EHEndProlog() { 596 EnsureValidW64UnwindInfo(); 597 MCWin64EHUnwindInfo *CurFrame = CurrentW64UnwindInfo; 598 CurFrame->PrologEnd = getContext().CreateTempSymbol(); 599 EmitLabel(CurFrame->PrologEnd); 600 } 601 602 void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { 603 llvm_unreachable("This file format doesn't support this directive"); 604 } 605 606 void MCStreamer::EmitFnStart() { 607 errs() << "Not implemented yet\n"; 608 abort(); 609 } 610 611 void MCStreamer::EmitFnEnd() { 612 errs() << "Not implemented yet\n"; 613 abort(); 614 } 615 616 void MCStreamer::EmitCantUnwind() { 617 errs() << "Not implemented yet\n"; 618 abort(); 619 } 620 621 void MCStreamer::EmitHandlerData() { 622 errs() << "Not implemented yet\n"; 623 abort(); 624 } 625 626 void MCStreamer::EmitPersonality(const MCSymbol *Personality) { 627 errs() << "Not implemented yet\n"; 628 abort(); 629 } 630 631 void MCStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) { 632 errs() << "Not implemented yet\n"; 633 abort(); 634 } 635 636 void MCStreamer::EmitPad(int64_t Offset) { 637 errs() << "Not implemented yet\n"; 638 abort(); 639 } 640 641 void MCStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool) { 642 errs() << "Not implemented yet\n"; 643 abort(); 644 } 645 646 /// EmitRawText - If this file is backed by an assembly streamer, this dumps 647 /// the specified string in the output .s file. This capability is 648 /// indicated by the hasRawTextSupport() predicate. 649 void MCStreamer::EmitRawText(StringRef String) { 650 errs() << "EmitRawText called on an MCStreamer that doesn't support it, " 651 " something must not be fully mc'ized\n"; 652 abort(); 653 } 654 655 void MCStreamer::EmitRawText(const Twine &T) { 656 SmallString<128> Str; 657 T.toVector(Str); 658 EmitRawText(Str.str()); 659 } 660 661 void MCStreamer::EmitFrames(bool usingCFI) { 662 if (!getNumFrameInfos()) 663 return; 664 665 if (EmitEHFrame) 666 MCDwarfFrameEmitter::Emit(*this, usingCFI, true); 667 668 if (EmitDebugFrame) 669 MCDwarfFrameEmitter::Emit(*this, usingCFI, false); 670 } 671 672 void MCStreamer::EmitW64Tables() { 673 if (!getNumW64UnwindInfos()) 674 return; 675 676 MCWin64EHUnwindEmitter::Emit(*this); 677 } 678 679 void MCStreamer::Finish() { 680 if (!FrameInfos.empty() && !FrameInfos.back().End) 681 report_fatal_error("Unfinished frame!"); 682 683 FinishImpl(); 684 } 685