MCStreamer.cpp revision 8bca4106dfc2945723251db10e340183f3e372dd
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> 21using namespace llvm; 22 23MCStreamer::MCStreamer(MCContext &Ctx) : Context(Ctx) { 24 const MCSection *section = NULL; 25 SectionStack.push_back(std::make_pair(section, section)); 26} 27 28MCStreamer::~MCStreamer() { 29} 30 31raw_ostream &MCStreamer::GetCommentOS() { 32 // By default, discard comments. 33 return nulls(); 34} 35 36void MCStreamer::EmitDwarfSetLineAddr(int64_t LineDelta, 37 const MCSymbol *Label, int PointerSize) { 38 // emit the sequence to set the address 39 EmitIntValue(dwarf::DW_LNS_extended_op, 1); 40 EmitULEB128IntValue(PointerSize + 1); 41 EmitIntValue(dwarf::DW_LNE_set_address, 1); 42 EmitSymbolValue(Label, PointerSize); 43 44 // emit the sequence for the LineDelta (from 1) and a zero address delta. 45 MCDwarfLineAddr::Emit(this, LineDelta, 0); 46} 47 48/// EmitIntValue - Special case of EmitValue that avoids the client having to 49/// pass in a MCExpr for constant integers. 50void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size, 51 unsigned AddrSpace) { 52 assert(Size <= 8 && "Invalid size"); 53 assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) && 54 "Invalid size"); 55 char buf[8]; 56 // FIXME: Endianness assumption. 57 for (unsigned i = 0; i != Size; ++i) 58 buf[i] = uint8_t(Value >> (i * 8)); 59 EmitBytes(StringRef(buf, Size), AddrSpace); 60} 61 62/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the 63/// client having to pass in a MCExpr for constant integers. 64void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace) { 65 SmallString<32> Tmp; 66 raw_svector_ostream OSE(Tmp); 67 MCObjectWriter::EncodeULEB128(Value, OSE); 68 EmitBytes(OSE.str(), AddrSpace); 69} 70 71/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the 72/// client having to pass in a MCExpr for constant integers. 73void MCStreamer::EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace) { 74 SmallString<32> Tmp; 75 raw_svector_ostream OSE(Tmp); 76 MCObjectWriter::EncodeSLEB128(Value, OSE); 77 EmitBytes(OSE.str(), AddrSpace); 78} 79 80void MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size, 81 unsigned AddrSpace) { 82 if (getContext().getAsmInfo().hasAggressiveSymbolFolding()) { 83 EmitValue(Value, Size, AddrSpace); 84 return; 85 } 86 MCSymbol *ABS = getContext().CreateTempSymbol(); 87 EmitAssignment(ABS, Value); 88 EmitSymbolValue(ABS, Size, AddrSpace); 89} 90 91 92void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, 93 unsigned AddrSpace) { 94 EmitValueImpl(Value, Size, false, AddrSpace); 95} 96 97void MCStreamer::EmitPCRelValue(const MCExpr *Value, unsigned Size, 98 unsigned AddrSpace) { 99 EmitValueImpl(Value, Size, true, AddrSpace); 100} 101 102void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, 103 bool isPCRel, unsigned AddrSpace) { 104 EmitValueImpl(MCSymbolRefExpr::Create(Sym, getContext()), Size, isPCRel, 105 AddrSpace); 106} 107 108void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, 109 unsigned AddrSpace) { 110 EmitSymbolValue(Sym, Size, false, AddrSpace); 111} 112 113void MCStreamer::EmitPCRelSymbolValue(const MCSymbol *Sym, unsigned Size, 114 unsigned AddrSpace) { 115 EmitSymbolValue(Sym, Size, true, AddrSpace); 116} 117 118void MCStreamer::EmitGPRel32Value(const MCExpr *Value) { 119 report_fatal_error("unsupported directive in streamer"); 120} 121 122/// EmitFill - Emit NumBytes bytes worth of the value specified by 123/// FillValue. This implements directives such as '.space'. 124void MCStreamer::EmitFill(uint64_t NumBytes, uint8_t FillValue, 125 unsigned AddrSpace) { 126 const MCExpr *E = MCConstantExpr::Create(FillValue, getContext()); 127 for (uint64_t i = 0, e = NumBytes; i != e; ++i) 128 EmitValue(E, 1, AddrSpace); 129} 130 131bool MCStreamer::EmitDwarfFileDirective(unsigned FileNo, 132 StringRef Filename) { 133 return getContext().GetDwarfFile(Filename, FileNo) == 0; 134} 135 136void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, 137 unsigned Column, unsigned Flags, 138 unsigned Isa, 139 unsigned Discriminator, 140 StringRef FileName) { 141 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa, 142 Discriminator); 143} 144 145MCDwarfFrameInfo *MCStreamer::getCurrentFrameInfo() { 146 if (FrameInfos.empty()) 147 return NULL; 148 return &FrameInfos.back(); 149} 150 151void MCStreamer::EnsureValidFrame() { 152 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 153 if (!CurFrame || CurFrame->End) 154 report_fatal_error("No open frame"); 155} 156 157void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol, 158 MCSymbol *EHSymbol) { 159} 160 161void MCStreamer::EmitLabel(MCSymbol *Symbol) { 162 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); 163 assert(getCurrentSection() && "Cannot emit before setting section!"); 164 Symbol->setSection(*getCurrentSection()); 165 166 StringRef Prefix = getContext().getAsmInfo().getPrivateGlobalPrefix(); 167 if (!Symbol->getName().startswith(Prefix)) 168 LastNonPrivate = Symbol; 169} 170 171void MCStreamer::EmitCFIStartProc() { 172 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 173 if (CurFrame && !CurFrame->End) 174 report_fatal_error("Starting a frame before finishing the previous one!"); 175 MCDwarfFrameInfo Frame; 176 Frame.Begin = getContext().CreateTempSymbol(); 177 Frame.Function = LastNonPrivate; 178 EmitLabel(Frame.Begin); 179 FrameInfos.push_back(Frame); 180} 181 182void MCStreamer::EmitCFIEndProc() { 183 EnsureValidFrame(); 184 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 185 CurFrame->End = getContext().CreateTempSymbol(); 186 EmitLabel(CurFrame->End); 187} 188 189void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { 190 EnsureValidFrame(); 191 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 192 MCSymbol *Label = getContext().CreateTempSymbol(); 193 EmitLabel(Label); 194 MachineLocation Dest(MachineLocation::VirtualFP); 195 MachineLocation Source(Register, -Offset); 196 MCCFIInstruction Instruction(Label, Dest, Source); 197 CurFrame->Instructions.push_back(Instruction); 198} 199 200void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) { 201 EnsureValidFrame(); 202 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 203 MCSymbol *Label = getContext().CreateTempSymbol(); 204 EmitLabel(Label); 205 MachineLocation Dest(MachineLocation::VirtualFP); 206 MachineLocation Source(MachineLocation::VirtualFP, -Offset); 207 MCCFIInstruction Instruction(Label, Dest, Source); 208 CurFrame->Instructions.push_back(Instruction); 209} 210 211void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { 212 EnsureValidFrame(); 213 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 214 MCSymbol *Label = getContext().CreateTempSymbol(); 215 EmitLabel(Label); 216 MachineLocation Dest(MachineLocation::VirtualFP); 217 MachineLocation Source(MachineLocation::VirtualFP, Adjustment); 218 MCCFIInstruction Instruction(MCCFIInstruction::RelMove, Label, Dest, Source); 219 CurFrame->Instructions.push_back(Instruction); 220} 221 222void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) { 223 EnsureValidFrame(); 224 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 225 MCSymbol *Label = getContext().CreateTempSymbol(); 226 EmitLabel(Label); 227 MachineLocation Dest(Register); 228 MachineLocation Source(MachineLocation::VirtualFP); 229 MCCFIInstruction Instruction(Label, Dest, Source); 230 CurFrame->Instructions.push_back(Instruction); 231} 232 233void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { 234 EnsureValidFrame(); 235 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 236 MCSymbol *Label = getContext().CreateTempSymbol(); 237 EmitLabel(Label); 238 MachineLocation Dest(Register, Offset); 239 MachineLocation Source(Register, Offset); 240 MCCFIInstruction Instruction(Label, Dest, Source); 241 CurFrame->Instructions.push_back(Instruction); 242} 243 244void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) { 245 EnsureValidFrame(); 246 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 247 MCSymbol *Label = getContext().CreateTempSymbol(); 248 EmitLabel(Label); 249 MachineLocation Dest(Register, Offset); 250 MachineLocation Source(Register, Offset); 251 MCCFIInstruction Instruction(MCCFIInstruction::RelMove, Label, Dest, Source); 252 CurFrame->Instructions.push_back(Instruction); 253} 254 255void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym, 256 unsigned Encoding) { 257 EnsureValidFrame(); 258 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 259 CurFrame->Personality = Sym; 260 CurFrame->PersonalityEncoding = Encoding; 261} 262 263void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { 264 EnsureValidFrame(); 265 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 266 CurFrame->Lsda = Sym; 267 CurFrame->LsdaEncoding = Encoding; 268} 269 270void MCStreamer::EmitCFIRememberState() { 271 EnsureValidFrame(); 272 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 273 MCSymbol *Label = getContext().CreateTempSymbol(); 274 EmitLabel(Label); 275 MCCFIInstruction Instruction(MCCFIInstruction::Remember, Label); 276 CurFrame->Instructions.push_back(Instruction); 277} 278 279void MCStreamer::EmitCFIRestoreState() { 280 // FIXME: Error if there is no matching cfi_remember_state. 281 EnsureValidFrame(); 282 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 283 MCSymbol *Label = getContext().CreateTempSymbol(); 284 EmitLabel(Label); 285 MCCFIInstruction Instruction(MCCFIInstruction::Restore, Label); 286 CurFrame->Instructions.push_back(Instruction); 287} 288 289void MCStreamer::EmitCFISameValue(int64_t Register) { 290 EnsureValidFrame(); 291 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 292 MCSymbol *Label = getContext().CreateTempSymbol(); 293 EmitLabel(Label); 294 MCCFIInstruction Instruction(MCCFIInstruction::SameValue, Label, Register); 295 CurFrame->Instructions.push_back(Instruction); 296} 297 298void MCStreamer::EmitFnStart() { 299 errs() << "Not implemented yet\n"; 300 abort(); 301} 302 303void MCStreamer::EmitFnEnd() { 304 errs() << "Not implemented yet\n"; 305 abort(); 306} 307 308void MCStreamer::EmitCantUnwind() { 309 errs() << "Not implemented yet\n"; 310 abort(); 311} 312 313void MCStreamer::EmitHandlerData() { 314 errs() << "Not implemented yet\n"; 315 abort(); 316} 317 318void MCStreamer::EmitPersonality(const MCSymbol *Personality) { 319 errs() << "Not implemented yet\n"; 320 abort(); 321} 322 323void MCStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) { 324 errs() << "Not implemented yet\n"; 325 abort(); 326} 327 328void MCStreamer::EmitPad(int64_t Offset) { 329 errs() << "Not implemented yet\n"; 330 abort(); 331} 332 333void MCStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool) { 334 errs() << "Not implemented yet\n"; 335 abort(); 336} 337 338/// EmitRawText - If this file is backed by an assembly streamer, this dumps 339/// the specified string in the output .s file. This capability is 340/// indicated by the hasRawTextSupport() predicate. 341void MCStreamer::EmitRawText(StringRef String) { 342 errs() << "EmitRawText called on an MCStreamer that doesn't support it, " 343 " something must not be fully mc'ized\n"; 344 abort(); 345} 346 347void MCStreamer::EmitRawText(const Twine &T) { 348 SmallString<128> Str; 349 T.toVector(Str); 350 EmitRawText(Str.str()); 351} 352