1 //===- lib/MC/MCAsmStreamer.cpp - Text Assembly 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/MCStreamer.h" 11 12 #include "llvm/MC/MCContext.h" 13 #include "llvm/MC/MCInst.h" 14 #include "llvm/MC/MCSection.h" 15 #include "llvm/MC/MCSymbol.h" 16 #include "llvm/MC/MCValue.h" 17 #include "llvm/Support/ErrorHandling.h" 18 #include "llvm/Support/raw_ostream.h" 19 20 using namespace llvm; 21 22 namespace { 23 24 class MCAsmStreamer : public MCStreamer { 25 raw_ostream &OS; 26 27 MCSection *CurSection; 28 29 public: 30 MCAsmStreamer(MCContext &Context, raw_ostream &_OS) 31 : MCStreamer(Context), OS(_OS), CurSection(0) {} 32 ~MCAsmStreamer() {} 33 34 /// @name MCStreamer Interface 35 /// @{ 36 37 virtual void SwitchSection(MCSection *Section); 38 39 virtual void EmitLabel(MCSymbol *Symbol); 40 41 virtual void EmitAssemblerFlag(AssemblerFlag Flag); 42 43 virtual void EmitAssignment(MCSymbol *Symbol, const MCValue &Value, 44 bool MakeAbsolute = false); 45 46 virtual void EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute); 47 48 virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); 49 50 virtual void EmitLocalSymbol(MCSymbol *Symbol, const MCValue &Value); 51 52 virtual void EmitCommonSymbol(MCSymbol *Symbol, unsigned Size, 53 unsigned Pow2Alignment, bool IsLocal); 54 55 virtual void EmitZerofill(MCSection *Section, MCSymbol *Symbol = NULL, 56 unsigned Size = 0, unsigned Pow2Alignment = 0); 57 58 virtual void EmitBytes(const StringRef &Data); 59 60 virtual void EmitValue(const MCValue &Value, unsigned Size); 61 62 virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, 63 unsigned ValueSize = 1, 64 unsigned MaxBytesToEmit = 0); 65 66 virtual void EmitValueToOffset(const MCValue &Offset, 67 unsigned char Value = 0); 68 69 virtual void EmitInstruction(const MCInst &Inst); 70 71 virtual void Finish(); 72 73 /// @} 74 }; 75 76 } 77 78 /// NeedsQuoting - Return true if the string \arg Str needs quoting, i.e., it 79 /// does not match [a-zA-Z_.][a-zA-Z0-9_.]*. 80 // 81 // FIXME: This could be more permissive, do we care? 82 static inline bool NeedsQuoting(const StringRef &Str) { 83 if (Str.empty()) 84 return true; 85 86 // Check that first character is in [a-zA-Z_.]. 87 if (!((Str[0] >= 'a' && Str[0] <= 'z') || 88 (Str[0] >= 'A' && Str[0] <= 'Z') || 89 (Str[0] == '_' || Str[0] == '.'))) 90 return true; 91 92 // Check subsequent characters are in [a-zA-Z0-9_.]. 93 for (unsigned i = 1, e = Str.size(); i != e; ++i) 94 if (!((Str[i] >= 'a' && Str[i] <= 'z') || 95 (Str[i] >= 'A' && Str[i] <= 'Z') || 96 (Str[i] >= '0' && Str[i] <= '9') || 97 (Str[i] == '_' || Str[i] == '.'))) 98 return true; 99 100 return false; 101 } 102 103 /// Allow printing sections directly to a raw_ostream with proper quoting. 104 static inline raw_ostream &operator<<(raw_ostream &os, const MCSection *S) { 105 if (NeedsQuoting(S->getName())) 106 return os << '"' << S->getName() << '"'; 107 return os << S->getName(); 108 } 109 110 /// Allow printing symbols directly to a raw_ostream with proper quoting. 111 static inline raw_ostream &operator<<(raw_ostream &os, const MCSymbol *S) { 112 if (NeedsQuoting(S->getName())) 113 return os << '"' << S->getName() << '"'; 114 return os << S->getName(); 115 } 116 117 /// Allow printing values directly to a raw_ostream. 118 static inline raw_ostream &operator<<(raw_ostream &os, const MCValue &Value) { 119 if (Value.getSymA()) { 120 os << Value.getSymA(); 121 if (Value.getSymB()) 122 os << " - " << Value.getSymB(); 123 if (Value.getConstant()) 124 os << " + " << Value.getConstant(); 125 } else { 126 assert(!Value.getSymB() && "Invalid machine code value!"); 127 os << Value.getConstant(); 128 } 129 130 return os; 131 } 132 133 static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) { 134 assert(Bytes && "Invalid size!"); 135 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8)); 136 } 137 138 static inline MCValue truncateToSize(const MCValue &Value, unsigned Bytes) { 139 return MCValue::get(Value.getSymA(), Value.getSymB(), 140 truncateToSize(Value.getConstant(), Bytes)); 141 } 142 143 void MCAsmStreamer::SwitchSection(MCSection *Section) { 144 if (Section != CurSection) { 145 CurSection = Section; 146 147 // FIXME: Really we would like the segment, flags, etc. to be separate 148 // values instead of embedded in the name. Not all assemblers understand all 149 // this stuff though. 150 OS << ".section " << Section << "\n"; 151 } 152 } 153 154 void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) { 155 assert(Symbol->getSection() == 0 && "Cannot emit a symbol twice!"); 156 assert(CurSection && "Cannot emit before setting section!"); 157 assert(!getContext().GetSymbolValue(Symbol) && 158 "Cannot emit symbol which was directly assigned to!"); 159 160 OS << Symbol << ":\n"; 161 Symbol->setSection(CurSection); 162 Symbol->setExternal(false); 163 } 164 165 void MCAsmStreamer::EmitAssemblerFlag(AssemblerFlag Flag) { 166 switch (Flag) { 167 case SubsectionsViaSymbols: OS << ".subsections_via_symbols"; break; 168 } 169 OS << '\n'; 170 } 171 172 void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCValue &Value, 173 bool MakeAbsolute) { 174 assert(!Symbol->getSection() && "Cannot assign to a label!"); 175 176 if (MakeAbsolute) { 177 OS << ".set " << Symbol << ", " << Value << '\n'; 178 } else { 179 OS << Symbol << " = " << Value << '\n'; 180 } 181 182 getContext().SetSymbolValue(Symbol, Value); 183 } 184 185 void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, 186 SymbolAttr Attribute) { 187 switch (Attribute) { 188 case Global: OS << ".globl"; break; 189 case Hidden: OS << ".hidden"; break; 190 case IndirectSymbol: OS << ".indirect_symbol"; break; 191 case Internal: OS << ".internal"; break; 192 case LazyReference: OS << ".lazy_reference"; break; 193 case NoDeadStrip: OS << ".no_dead_strip"; break; 194 case PrivateExtern: OS << ".private_extern"; break; 195 case Protected: OS << ".protected"; break; 196 case Reference: OS << ".reference"; break; 197 case Weak: OS << ".weak"; break; 198 case WeakDefinition: OS << ".weak_definition"; break; 199 case WeakReference: OS << ".weak_reference"; break; 200 } 201 202 OS << ' ' << Symbol << '\n'; 203 } 204 205 void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { 206 OS << ".desc" << ' ' << Symbol << ',' << DescValue << '\n'; 207 } 208 209 void MCAsmStreamer::EmitLocalSymbol(MCSymbol *Symbol, const MCValue &Value) { 210 OS << ".lsym" << ' ' << Symbol << ',' << Value << '\n'; 211 } 212 213 void MCAsmStreamer::EmitCommonSymbol(MCSymbol *Symbol, unsigned Size, 214 unsigned Pow2Alignment, bool IsLocal) { 215 if (IsLocal) 216 OS << ".lcomm"; 217 else 218 OS << ".comm"; 219 OS << ' ' << Symbol << ',' << Size; 220 if (Pow2Alignment != 0) 221 OS << ',' << Pow2Alignment; 222 OS << '\n'; 223 } 224 225 void MCAsmStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol, 226 unsigned Size, unsigned Pow2Alignment) { 227 // Note: a .zerofill directive does not switch sections 228 // FIXME: Really we would like the segment and section names as well as the 229 // section type to be separate values instead of embedded in the name. Not 230 // all assemblers understand all this stuff though. 231 OS << ".zerofill " << Section; 232 if (Symbol != NULL) { 233 OS << ',' << Symbol << ',' << Size; 234 if (Pow2Alignment != 0) 235 OS << ',' << Pow2Alignment; 236 } 237 OS << '\n'; 238 } 239 240 void MCAsmStreamer::EmitBytes(const StringRef &Data) { 241 assert(CurSection && "Cannot emit contents before setting section!"); 242 for (unsigned i = 0, e = Data.size(); i != e; ++i) 243 OS << ".byte " << (unsigned) Data[i] << '\n'; 244 } 245 246 void MCAsmStreamer::EmitValue(const MCValue &Value, unsigned Size) { 247 assert(CurSection && "Cannot emit contents before setting section!"); 248 // Need target hooks to know how to print this. 249 switch (Size) { 250 default: 251 llvm_unreachable("Invalid size for machine code value!"); 252 case 1: OS << ".byte"; break; 253 case 2: OS << ".short"; break; 254 case 4: OS << ".long"; break; 255 case 8: OS << ".quad"; break; 256 } 257 258 OS << ' ' << truncateToSize(Value, Size) << '\n'; 259 } 260 261 void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, 262 unsigned ValueSize, 263 unsigned MaxBytesToEmit) { 264 // Some assemblers don't support .balign, so we always emit as .p2align if 265 // this is a power of two. Otherwise we assume the client knows the target 266 // supports .balign and use that. 267 unsigned Pow2 = Log2_32(ByteAlignment); 268 bool IsPow2 = (1U << Pow2) == ByteAlignment; 269 270 switch (ValueSize) { 271 default: 272 llvm_unreachable("Invalid size for machine code value!"); 273 case 8: 274 llvm_unreachable("Unsupported alignment size!"); 275 case 1: OS << (IsPow2 ? ".p2align" : ".balign"); break; 276 case 2: OS << (IsPow2 ? ".p2alignw" : ".balignw"); break; 277 case 4: OS << (IsPow2 ? ".p2alignl" : ".balignl"); break; 278 } 279 280 OS << ' ' << (IsPow2 ? Pow2 : ByteAlignment); 281 282 OS << ", " << truncateToSize(Value, ValueSize); 283 if (MaxBytesToEmit) 284 OS << ", " << MaxBytesToEmit; 285 OS << '\n'; 286 } 287 288 void MCAsmStreamer::EmitValueToOffset(const MCValue &Offset, 289 unsigned char Value) { 290 // FIXME: Verify that Offset is associated with the current section. 291 OS << ".org " << Offset << ", " << (unsigned) Value << '\n'; 292 } 293 294 static raw_ostream &operator<<(raw_ostream &OS, const MCOperand &Op) { 295 if (Op.isReg()) 296 return OS << "reg:" << Op.getReg(); 297 if (Op.isImm()) 298 return OS << "imm:" << Op.getImm(); 299 if (Op.isMBBLabel()) 300 return OS << "mbblabel:(" 301 << Op.getMBBLabelFunction() << ", " << Op.getMBBLabelBlock(); 302 assert(Op.isMCValue() && "Invalid operand!"); 303 return OS << "val:" << Op.getMCValue(); 304 } 305 306 void MCAsmStreamer::EmitInstruction(const MCInst &Inst) { 307 assert(CurSection && "Cannot emit contents before setting section!"); 308 // FIXME: Implement proper printing. 309 OS << "MCInst(" 310 << "opcode=" << Inst.getOpcode() << ", " 311 << "operands=["; 312 for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) { 313 if (i) 314 OS << ", "; 315 OS << Inst.getOperand(i); 316 } 317 OS << "])\n"; 318 } 319 320 void MCAsmStreamer::Finish() { 321 OS.flush(); 322 } 323 324 MCStreamer *llvm::createAsmStreamer(MCContext &Context, raw_ostream &OS) { 325 return new MCAsmStreamer(Context, OS); 326 } 327