MCStreamer.cpp revision ed708f9c1facb9928ef2f79503e7030c8f25b00d
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::EmitLabel(MCSymbol *Symbol) { 158 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); 159 assert(getCurrentSection() && "Cannot emit before setting section!"); 160 Symbol->setSection(*getCurrentSection()); 161 162 StringRef Prefix = getContext().getAsmInfo().getPrivateGlobalPrefix(); 163 if (!Symbol->getName().startswith(Prefix)) 164 LastNonPrivate = Symbol; 165} 166 167void MCStreamer::EmitCFIStartProc() { 168 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 169 if (CurFrame && !CurFrame->End) 170 report_fatal_error("Starting a frame before finishing the previous one!"); 171 MCDwarfFrameInfo Frame; 172 Frame.Begin = getContext().CreateTempSymbol(); 173 Frame.Function = LastNonPrivate; 174 EmitLabel(Frame.Begin); 175 FrameInfos.push_back(Frame); 176} 177 178void MCStreamer::EmitCFIEndProc() { 179 EnsureValidFrame(); 180 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 181 CurFrame->End = getContext().CreateTempSymbol(); 182 EmitLabel(CurFrame->End); 183} 184 185void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) { 186 EnsureValidFrame(); 187 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 188 MCSymbol *Label = getContext().CreateTempSymbol(); 189 EmitLabel(Label); 190 MachineLocation Dest(MachineLocation::VirtualFP); 191 MachineLocation Source(Register, -Offset); 192 MCCFIInstruction Instruction(Label, Dest, Source); 193 CurFrame->Instructions.push_back(Instruction); 194} 195 196void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) { 197 EnsureValidFrame(); 198 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 199 MCSymbol *Label = getContext().CreateTempSymbol(); 200 EmitLabel(Label); 201 MachineLocation Dest(MachineLocation::VirtualFP); 202 MachineLocation Source(MachineLocation::VirtualFP, -Offset); 203 MCCFIInstruction Instruction(Label, Dest, Source); 204 CurFrame->Instructions.push_back(Instruction); 205} 206 207void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) { 208 EnsureValidFrame(); 209 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 210 MCSymbol *Label = getContext().CreateTempSymbol(); 211 EmitLabel(Label); 212 MachineLocation Dest(MachineLocation::VirtualFP); 213 MachineLocation Source(MachineLocation::VirtualFP, Adjustment); 214 MCCFIInstruction Instruction(MCCFIInstruction::RelMove, Label, Dest, Source); 215 CurFrame->Instructions.push_back(Instruction); 216} 217 218void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) { 219 EnsureValidFrame(); 220 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 221 MCSymbol *Label = getContext().CreateTempSymbol(); 222 EmitLabel(Label); 223 MachineLocation Dest(Register); 224 MachineLocation Source(MachineLocation::VirtualFP); 225 MCCFIInstruction Instruction(Label, Dest, Source); 226 CurFrame->Instructions.push_back(Instruction); 227} 228 229void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) { 230 EnsureValidFrame(); 231 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 232 MCSymbol *Label = getContext().CreateTempSymbol(); 233 EmitLabel(Label); 234 MachineLocation Dest(Register, Offset); 235 MachineLocation Source(Register, Offset); 236 MCCFIInstruction Instruction(Label, Dest, Source); 237 CurFrame->Instructions.push_back(Instruction); 238} 239 240void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) { 241 EnsureValidFrame(); 242 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 243 MCSymbol *Label = getContext().CreateTempSymbol(); 244 EmitLabel(Label); 245 MachineLocation Dest(Register, Offset); 246 MachineLocation Source(Register, Offset); 247 MCCFIInstruction Instruction(MCCFIInstruction::RelMove, Label, Dest, Source); 248 CurFrame->Instructions.push_back(Instruction); 249} 250 251void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym, 252 unsigned Encoding) { 253 EnsureValidFrame(); 254 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 255 CurFrame->Personality = Sym; 256 CurFrame->PersonalityEncoding = Encoding; 257} 258 259void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { 260 EnsureValidFrame(); 261 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 262 CurFrame->Lsda = Sym; 263 CurFrame->LsdaEncoding = Encoding; 264} 265 266void MCStreamer::EmitCFIRememberState() { 267 EnsureValidFrame(); 268 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 269 MCSymbol *Label = getContext().CreateTempSymbol(); 270 EmitLabel(Label); 271 MCCFIInstruction Instruction(MCCFIInstruction::Remember, Label); 272 CurFrame->Instructions.push_back(Instruction); 273} 274 275void MCStreamer::EmitCFIRestoreState() { 276 // FIXME: Error if there is no matching cfi_remember_state. 277 EnsureValidFrame(); 278 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 279 MCSymbol *Label = getContext().CreateTempSymbol(); 280 EmitLabel(Label); 281 MCCFIInstruction Instruction(MCCFIInstruction::Restore, Label); 282 CurFrame->Instructions.push_back(Instruction); 283} 284 285void MCStreamer::EmitCFISameValue(int64_t Register) { 286 EnsureValidFrame(); 287 MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); 288 MCSymbol *Label = getContext().CreateTempSymbol(); 289 EmitLabel(Label); 290 MCCFIInstruction Instruction(MCCFIInstruction::SameValue, Label, Register); 291 CurFrame->Instructions.push_back(Instruction); 292} 293 294void MCStreamer::EmitFnStart() { 295 errs() << "Not implemented yet\n"; 296 abort(); 297} 298 299void MCStreamer::EmitFnEnd() { 300 errs() << "Not implemented yet\n"; 301 abort(); 302} 303 304void MCStreamer::EmitCantUnwind() { 305 errs() << "Not implemented yet\n"; 306 abort(); 307} 308 309void MCStreamer::EmitHandlerData() { 310 errs() << "Not implemented yet\n"; 311 abort(); 312} 313 314void MCStreamer::EmitPersonality(const MCSymbol *Personality) { 315 errs() << "Not implemented yet\n"; 316 abort(); 317} 318 319void MCStreamer::EmitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset) { 320 errs() << "Not implemented yet\n"; 321 abort(); 322} 323 324void MCStreamer::EmitPad(int64_t Offset) { 325 errs() << "Not implemented yet\n"; 326 abort(); 327} 328 329void MCStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, bool) { 330 errs() << "Not implemented yet\n"; 331 abort(); 332} 333 334/// EmitRawText - If this file is backed by an assembly streamer, this dumps 335/// the specified string in the output .s file. This capability is 336/// indicated by the hasRawTextSupport() predicate. 337void MCStreamer::EmitRawText(StringRef String) { 338 errs() << "EmitRawText called on an MCStreamer that doesn't support it, " 339 " something must not be fully mc'ized\n"; 340 abort(); 341} 342 343void MCStreamer::EmitRawText(const Twine &T) { 344 SmallString<128> Str; 345 T.toVector(Str); 346 EmitRawText(Str.str()); 347} 348