From: Daniel Dunbar Date: Wed, 26 May 2010 20:37:00 +0000 (+0000) Subject: MC/Mach-O: Factor out EmitInstTo{Fragment,Data} for emitting MCInst's as MCInstFragme... X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=2ac0c453b2de1029f35d9ccb933c1ef303be00a2;p=oota-llvm.git MC/Mach-O: Factor out EmitInstTo{Fragment,Data} for emitting MCInst's as MCInstFragments or appending onto an MCDataFragment. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104735 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 6c738aa4a85..2f23ae310ee 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -60,6 +60,9 @@ private: return DF; } + void EmitInstToFragment(const MCInst &Inst); + void EmitInstToData(const MCInst &Inst); + public: MCMachOStreamer(MCContext &Context, TargetAsmBackend &TAB, raw_ostream &_OS, MCCodeEmitter *_Emitter) @@ -140,14 +143,14 @@ public: unsigned MaxBytesToEmit = 0); virtual void EmitValueToOffset(const MCExpr *Offset, unsigned char Value = 0); - + virtual void EmitFileDirective(StringRef Filename) { report_fatal_error("unsupported directive: '.file'"); } virtual void EmitDwarfFileDirective(unsigned FileNo, StringRef Filename) { report_fatal_error("unsupported directive: '.file'"); } - + virtual void EmitInstruction(const MCInst &Inst); virtual void Finish(); @@ -158,7 +161,7 @@ public: void MCMachOStreamer::SwitchSection(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; @@ -200,7 +203,7 @@ void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) { // FIXME: Cleanup this code, these bits should be emitted based on semantic // properties, not on the order of definition, etc. SD.setFlags(SD.getFlags() & ~SF_ReferenceTypeMask); - + Symbol->setSection(*CurSection); } @@ -308,7 +311,7 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { // Encode the 'desc' value into the lowest implementation defined bits. - assert(DescValue == (DescValue & SF_DescFlagsMask) && + assert(DescValue == (DescValue & SF_DescFlagsMask) && "Invalid .desc value!"); Assembler.getOrCreateSymbolData(*Symbol).setFlags(DescValue&SF_DescFlagsMask); } @@ -417,16 +420,26 @@ void MCMachOStreamer::EmitValueToOffset(const MCExpr *Offset, F->setAtom(CurrentAtomMap.lookup(CurSectionData)); } -void MCMachOStreamer::EmitInstruction(const MCInst &Inst) { - // Scan for values. - for (unsigned i = Inst.getNumOperands(); i--; ) - if (Inst.getOperand(i).isExpr()) - AddValueSymbols(Inst.getOperand(i).getExpr()); +void MCMachOStreamer::EmitInstToFragment(const MCInst &Inst) { + MCInstFragment *IF = new MCInstFragment(Inst, CurSectionData); + IF->setAtom(CurrentAtomMap.lookup(CurSectionData)); - CurSectionData->setHasInstructions(true); + // Add the fixups and data. + // + // FIXME: Revisit this design decision when relaxation is done, we may be + // able to get away with not storing any extra data in the MCInst. + SmallVector Fixups; + SmallString<256> Code; + raw_svector_ostream VecOS(Code); + Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups); + VecOS.flush(); + + IF->getCode() = Code; + IF->getFixups() = Fixups; +} - // FIXME-PERF: Common case is that we don't need to relax, encode directly - // onto the data fragments buffers. +void MCMachOStreamer::EmitInstToData(const MCInst &Inst) { + MCDataFragment *DF = getOrCreateDataFragment(); SmallVector Fixups; SmallString<256> Code; @@ -434,6 +447,22 @@ void MCMachOStreamer::EmitInstruction(const MCInst &Inst) { Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups); VecOS.flush(); + // Add the fixups and data. + for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { + Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); + DF->addFixup(Fixups[i]); + } + DF->getContents().append(Code.begin(), Code.end()); +} + +void MCMachOStreamer::EmitInstruction(const MCInst &Inst) { + // Scan for values. + for (unsigned i = Inst.getNumOperands(); i--; ) + if (Inst.getOperand(i).isExpr()) + AddValueSymbols(Inst.getOperand(i).getExpr()); + + CurSectionData->setHasInstructions(true); + // See if we might need to relax this instruction, if so it needs its own // fragment. // @@ -447,27 +476,10 @@ void MCMachOStreamer::EmitInstruction(const MCInst &Inst) { // total knowledge about undefined symbols at that point). Even now, though, // we can do a decent job, especially on Darwin where scattering means that we // are going to often know that we can never fully resolve a fixup. - if (Assembler.getBackend().MayNeedRelaxation(Inst)) { - MCInstFragment *IF = new MCInstFragment(Inst, CurSectionData); - IF->setAtom(CurrentAtomMap.lookup(CurSectionData)); - - // Add the fixups and data. - // - // FIXME: Revisit this design decision when relaxation is done, we may be - // able to get away with not storing any extra data in the MCInst. - IF->getCode() = Code; - IF->getFixups() = Fixups; - - return; - } - - // Add the fixups and data. - MCDataFragment *DF = getOrCreateDataFragment(); - for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { - Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); - DF->addFixup(Fixups[i]); - } - DF->getContents().append(Code.begin(), Code.end()); + if (Assembler.getBackend().MayNeedRelaxation(Inst)) + EmitInstToFragment(Inst); + else + EmitInstToData(Inst); } void MCMachOStreamer::Finish() {