//
//===----------------------------------------------------------------------===//
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/Support/ErrorHandling.h"
{
}
+MCObjectStreamer::MCObjectStreamer(MCContext &Context, TargetAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *Emitter_,
+ MCAssembler *_Assembler)
+ : MCStreamer(Context), Assembler(_Assembler), CurSectionData(0)
+{
+}
+
MCObjectStreamer::~MCObjectStreamer() {
delete &Assembler->getBackend();
delete &Assembler->getEmitter();
const MCExpr *MCObjectStreamer::AddValueSymbols(const MCExpr *Value) {
switch (Value->getKind()) {
- case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!");
+ case MCExpr::Target:
+ cast<MCTargetExpr>(Value)->AddValueSymbols(Assembler);
+ break;
+
case MCExpr::Constant:
break;
}
void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
- bool isPCRel, unsigned AddrSpace) {
+ unsigned AddrSpace) {
assert(AddrSpace == 0 && "Address space must be 0!");
MCDataFragment *DF = getOrCreateDataFragment();
return;
}
DF->addFixup(MCFixup::Create(DF->getContents().size(),
- AddValueSymbols(Value),
- MCFixup::getKindForSize(Size, isPCRel)));
+ Value,
+ MCFixup::getKindForSize(Size, false)));
DF->getContents().resize(DF->getContents().size() + Size, 0);
}
void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
- assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
- assert(CurSection && "Cannot emit before setting section!");
-
- Symbol->setSection(*CurSection);
+ MCStreamer::EmitLabel(Symbol);
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
SD.setOffset(F->getContents().size());
}
-void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value,
- unsigned AddrSpace) {
+void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) {
int64_t IntValue;
if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
- EmitULEB128IntValue(IntValue, AddrSpace);
+ EmitULEB128IntValue(IntValue);
return;
}
+ Value = ForceExpAbs(this, getContext(), Value);
new MCLEBFragment(*Value, false, getCurrentSectionData());
}
-void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value,
- unsigned AddrSpace) {
+void MCObjectStreamer::EmitSLEB128Value(const MCExpr *Value) {
int64_t IntValue;
if (Value->EvaluateAsAbsolute(IntValue, getAssembler())) {
- EmitSLEB128IntValue(IntValue, AddrSpace);
+ EmitSLEB128IntValue(IntValue);
return;
}
+ Value = ForceExpAbs(this, getContext(), Value);
new MCLEBFragment(*Value, true, getCurrentSectionData());
}
report_fatal_error("This file format doesn't support weak aliases.");
}
-void MCObjectStreamer::SwitchSection(const MCSection *Section) {
+void MCObjectStreamer::ChangeSection(const MCSection *Section) {
assert(Section && "Cannot switch to a null section!");
- // If already in this section, then this is a noop.
- if (Section == CurSection) return;
-
- PrevSection = CurSection;
- CurSection = Section;
CurSectionData = &getAssembler().getOrCreateSectionData(*Section);
}
void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
- raw_svector_ostream VecOS(IF->getCode());
+ SmallString<128> Code;
+ raw_svector_ostream VecOS(Code);
getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
+ VecOS.flush();
+ IF->getCode().append(Code.begin(), Code.end());
}
void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
return;
}
- MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
- const MCExpr *LabelRef =
- MCSymbolRefExpr::Create(Label, Variant, getContext());
- const MCExpr *LastLabelRef =
- MCSymbolRefExpr::Create(LastLabel, Variant, getContext());
- const MCExpr *AddrDelta =
- MCBinaryExpr::Create(MCBinaryExpr::Sub, LabelRef, LastLabelRef,
- getContext());
+ const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
int64_t Res;
if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
MCDwarfLineAddr::Emit(this, LineDelta, Res);
return;
}
+ AddrDelta = ForceExpAbs(this, getContext(), AddrDelta);
new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData());
}
+void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
+ const MCSymbol *Label) {
+ const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
+ int64_t Res;
+ if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
+ MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
+ return;
+ }
+ AddrDelta = ForceExpAbs(this, getContext(), AddrDelta);
+ new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData());
+}
+
void MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
unsigned char Value) {
- new MCOrgFragment(*Offset, Value, getCurrentSectionData());
+ int64_t Res;
+ if (Offset->EvaluateAsAbsolute(Res, getAssembler())) {
+ new MCOrgFragment(*Offset, Value, getCurrentSectionData());
+ return;
+ }
+
+ MCSymbol *CurrentPos = getContext().CreateTempSymbol();
+ EmitLabel(CurrentPos);
+ MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
+ const MCExpr *Ref =
+ MCSymbolRefExpr::Create(CurrentPos, Variant, getContext());
+ const MCExpr *Delta =
+ MCBinaryExpr::Create(MCBinaryExpr::Sub, Offset, Ref, getContext());
+
+ if (!Delta->EvaluateAsAbsolute(Res, getAssembler()))
+ report_fatal_error("expected assembly-time absolute expression");
+ EmitFill(Res, Value, 0);
}
void MCObjectStreamer::Finish() {