MCAsmStreamer.cpp (195098) | MCAsmStreamer.cpp (195340) |
---|---|
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" | 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" |
|
13#include "llvm/MC/MCSection.h" 14#include "llvm/MC/MCSymbol.h" 15#include "llvm/MC/MCValue.h" 16#include "llvm/Support/raw_ostream.h" 17using namespace llvm; 18 19namespace { 20 21 class MCAsmStreamer : public MCStreamer { 22 raw_ostream &OS; 23 24 MCSection *CurSection; 25 26 public: 27 MCAsmStreamer(MCContext &Context, raw_ostream &_OS) | 14#include "llvm/MC/MCSection.h" 15#include "llvm/MC/MCSymbol.h" 16#include "llvm/MC/MCValue.h" 17#include "llvm/Support/raw_ostream.h" 18using namespace llvm; 19 20namespace { 21 22 class MCAsmStreamer : public MCStreamer { 23 raw_ostream &OS; 24 25 MCSection *CurSection; 26 27 public: 28 MCAsmStreamer(MCContext &Context, raw_ostream &_OS) |
28 : MCStreamer(Context), OS(_OS) {} | 29 : MCStreamer(Context), OS(_OS), CurSection(0) {} |
29 ~MCAsmStreamer() {} 30 31 /// @name MCStreamer Interface 32 /// @{ 33 34 virtual void SwitchSection(MCSection *Section); 35 36 virtual void EmitLabel(MCSymbol *Symbol); --- 24 unchanged lines hidden (view full) --- 61} 62 63/// Allow printing values directly to a raw_ostream. 64static inline raw_ostream &operator<<(raw_ostream &os, const MCValue &Value) { 65 if (Value.getSymA()) { 66 os << Value.getSymA()->getName(); 67 if (Value.getSymB()) 68 os << " - " << Value.getSymB()->getName(); | 30 ~MCAsmStreamer() {} 31 32 /// @name MCStreamer Interface 33 /// @{ 34 35 virtual void SwitchSection(MCSection *Section); 36 37 virtual void EmitLabel(MCSymbol *Symbol); --- 24 unchanged lines hidden (view full) --- 62} 63 64/// Allow printing values directly to a raw_ostream. 65static inline raw_ostream &operator<<(raw_ostream &os, const MCValue &Value) { 66 if (Value.getSymA()) { 67 os << Value.getSymA()->getName(); 68 if (Value.getSymB()) 69 os << " - " << Value.getSymB()->getName(); |
69 if (Value.getCst()) 70 os << " + " << Value.getCst(); | 70 if (Value.getConstant()) 71 os << " + " << Value.getConstant(); |
71 } else { 72 assert(!Value.getSymB() && "Invalid machine code value!"); | 72 } else { 73 assert(!Value.getSymB() && "Invalid machine code value!"); |
73 os << Value.getCst(); | 74 os << Value.getConstant(); |
74 } 75 76 return os; 77} 78 79static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) { 80 assert(Bytes && "Invalid size!"); 81 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8)); 82} 83 84static inline MCValue truncateToSize(const MCValue &Value, unsigned Bytes) { 85 return MCValue::get(Value.getSymA(), Value.getSymB(), | 75 } 76 77 return os; 78} 79 80static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) { 81 assert(Bytes && "Invalid size!"); 82 return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8)); 83} 84 85static inline MCValue truncateToSize(const MCValue &Value, unsigned Bytes) { 86 return MCValue::get(Value.getSymA(), Value.getSymB(), |
86 truncateToSize(Value.getCst(), Bytes)); | 87 truncateToSize(Value.getConstant(), Bytes)); |
87} 88 89void MCAsmStreamer::SwitchSection(MCSection *Section) { 90 if (Section != CurSection) { 91 CurSection = Section; 92 93 // FIXME: Really we would like the segment, flags, etc. to be separate 94 // values instead of embedded in the name. Not all assemblers understand all --- 5 unchanged lines hidden (view full) --- 100void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) { 101 assert(Symbol->getSection() == 0 && "Cannot emit a symbol twice!"); 102 assert(CurSection && "Cannot emit before setting section!"); 103 assert(!getContext().GetSymbolValue(Symbol) && 104 "Cannot emit symbol which was directly assigned to!"); 105 106 OS << Symbol->getName() << ":\n"; 107 Symbol->setSection(CurSection); | 88} 89 90void MCAsmStreamer::SwitchSection(MCSection *Section) { 91 if (Section != CurSection) { 92 CurSection = Section; 93 94 // FIXME: Really we would like the segment, flags, etc. to be separate 95 // values instead of embedded in the name. Not all assemblers understand all --- 5 unchanged lines hidden (view full) --- 101void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) { 102 assert(Symbol->getSection() == 0 && "Cannot emit a symbol twice!"); 103 assert(CurSection && "Cannot emit before setting section!"); 104 assert(!getContext().GetSymbolValue(Symbol) && 105 "Cannot emit symbol which was directly assigned to!"); 106 107 OS << Symbol->getName() << ":\n"; 108 Symbol->setSection(CurSection); |
109 Symbol->setExternal(false); |
|
108} 109 110void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCValue &Value, 111 bool MakeAbsolute) { 112 assert(!Symbol->getSection() && "Cannot assign to a label!"); 113 114 if (MakeAbsolute) { 115 OS << ".set " << Symbol->getName() << ", " << Value << '\n'; --- 43 unchanged lines hidden (view full) --- 159 } 160 161 OS << ' ' << truncateToSize(Value, Size) << '\n'; 162} 163 164void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, 165 unsigned ValueSize, 166 unsigned MaxBytesToEmit) { | 110} 111 112void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCValue &Value, 113 bool MakeAbsolute) { 114 assert(!Symbol->getSection() && "Cannot assign to a label!"); 115 116 if (MakeAbsolute) { 117 OS << ".set " << Symbol->getName() << ", " << Value << '\n'; --- 43 unchanged lines hidden (view full) --- 161 } 162 163 OS << ' ' << truncateToSize(Value, Size) << '\n'; 164} 165 166void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, 167 unsigned ValueSize, 168 unsigned MaxBytesToEmit) { |
169 // Some assemblers don't support .balign, so we always emit as .p2align if 170 // this is a power of two. Otherwise we assume the client knows the target 171 // supports .balign and use that. |
|
167 unsigned Pow2 = Log2_32(ByteAlignment); | 172 unsigned Pow2 = Log2_32(ByteAlignment); |
168 assert((1U << Pow2) == ByteAlignment && "Invalid alignment!"); | 173 bool IsPow2 = (1U << Pow2) == ByteAlignment; |
169 170 switch (ValueSize) { 171 default: 172 assert(0 && "Invalid size for machine code value!"); 173 case 8: 174 assert(0 && "Unsupported alignment size!"); | 174 175 switch (ValueSize) { 176 default: 177 assert(0 && "Invalid size for machine code value!"); 178 case 8: 179 assert(0 && "Unsupported alignment size!"); |
175 case 1: OS << ".p2align"; break; 176 case 2: OS << ".p2alignw"; break; 177 case 4: OS << ".p2alignl"; break; | 180 case 1: OS << (IsPow2 ? ".p2align" : ".balign"); break; 181 case 2: OS << (IsPow2 ? ".p2alignw" : ".balignw"); break; 182 case 4: OS << (IsPow2 ? ".p2alignl" : ".balignl"); break; |
178 } 179 | 183 } 184 |
180 OS << ' ' << Pow2; | 185 OS << ' ' << (IsPow2 ? Pow2 : ByteAlignment); |
181 182 OS << ", " << truncateToSize(Value, ValueSize); 183 if (MaxBytesToEmit) 184 OS << ", " << MaxBytesToEmit; 185 OS << '\n'; 186} 187 188void MCAsmStreamer::EmitValueToOffset(const MCValue &Offset, 189 unsigned char Value) { 190 // FIXME: Verify that Offset is associated with the current section. 191 OS << ".org " << Offset << ", " << (unsigned) Value << '\n'; 192} 193 | 186 187 OS << ", " << truncateToSize(Value, ValueSize); 188 if (MaxBytesToEmit) 189 OS << ", " << MaxBytesToEmit; 190 OS << '\n'; 191} 192 193void MCAsmStreamer::EmitValueToOffset(const MCValue &Offset, 194 unsigned char Value) { 195 // FIXME: Verify that Offset is associated with the current section. 196 OS << ".org " << Offset << ", " << (unsigned) Value << '\n'; 197} 198 |
199static raw_ostream &operator<<(raw_ostream &OS, const MCOperand &Op) { 200 if (Op.isReg()) 201 return OS << "reg:" << Op.getReg(); 202 if (Op.isImm()) 203 return OS << "imm:" << Op.getImm(); 204 if (Op.isMBBLabel()) 205 return OS << "mbblabel:(" 206 << Op.getMBBLabelFunction() << ", " << Op.getMBBLabelBlock(); 207 assert(Op.isMCValue() && "Invalid operand!"); 208 return OS << "val:" << Op.getMCValue(); 209} 210 |
|
194void MCAsmStreamer::EmitInstruction(const MCInst &Inst) { 195 assert(CurSection && "Cannot emit contents before setting section!"); | 211void MCAsmStreamer::EmitInstruction(const MCInst &Inst) { 212 assert(CurSection && "Cannot emit contents before setting section!"); |
196 // FIXME: Implement. 197 OS << "# FIXME: Implement instruction printing!\n"; | 213 // FIXME: Implement proper printing. 214 OS << "MCInst(" 215 << "opcode=" << Inst.getOpcode() << ", " 216 << "operands=["; 217 for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i) { 218 if (i) 219 OS << ", "; 220 OS << Inst.getOperand(i); 221 } 222 OS << "])\n"; |
198} 199 200void MCAsmStreamer::Finish() { 201 OS.flush(); 202} 203 204MCStreamer *llvm::createAsmStreamer(MCContext &Context, raw_ostream &OS) { 205 return new MCAsmStreamer(Context, OS); 206} | 223} 224 225void MCAsmStreamer::Finish() { 226 OS.flush(); 227} 228 229MCStreamer *llvm::createAsmStreamer(MCContext &Context, raw_ostream &OS) { 230 return new MCAsmStreamer(Context, OS); 231} |