diff options
29 files changed, 440 insertions, 325 deletions
diff --git a/include/llvm/CodeGen/BinaryObject.h b/include/llvm/CodeGen/BinaryObject.h index ce0c07af95..f8fce03c31 100644 --- a/include/llvm/CodeGen/BinaryObject.h +++ b/include/llvm/CodeGen/BinaryObject.h @@ -146,27 +146,27 @@ public: /// emitDWordLE - This callback is invoked when a 64-bit word needs to be /// written to the data stream in little-endian format. inline void emitDWordLE(uint64_t W) { - Data.push_back(unsigned(W >> 0) & 255); - Data.push_back(unsigned(W >> 8) & 255); - Data.push_back(unsigned(W >> 16) & 255); - Data.push_back(unsigned(W >> 24) & 255); - Data.push_back(unsigned(W >> 32) & 255); - Data.push_back(unsigned(W >> 40) & 255); - Data.push_back(unsigned(W >> 48) & 255); - Data.push_back(unsigned(W >> 56) & 255); + Data.push_back((W >> 0) & 255); + Data.push_back((W >> 8) & 255); + Data.push_back((W >> 16) & 255); + Data.push_back((W >> 24) & 255); + Data.push_back((W >> 32) & 255); + Data.push_back((W >> 40) & 255); + Data.push_back((W >> 48) & 255); + Data.push_back((W >> 56) & 255); } /// emitDWordBE - This callback is invoked when a 64-bit word needs to be /// written to the data stream in big-endian format. inline void emitDWordBE(uint64_t W) { - Data.push_back(unsigned(W >> 56) & 255); - Data.push_back(unsigned(W >> 48) & 255); - Data.push_back(unsigned(W >> 40) & 255); - Data.push_back(unsigned(W >> 32) & 255); - Data.push_back(unsigned(W >> 24) & 255); - Data.push_back(unsigned(W >> 16) & 255); - Data.push_back(unsigned(W >> 8) & 255); - Data.push_back(unsigned(W >> 0) & 255); + Data.push_back((W >> 56) & 255); + Data.push_back((W >> 48) & 255); + Data.push_back((W >> 40) & 255); + Data.push_back((W >> 32) & 255); + Data.push_back((W >> 24) & 255); + Data.push_back((W >> 16) & 255); + Data.push_back((W >> 8) & 255); + Data.push_back((W >> 0) & 255); } /// fixByte - This callback is invoked when a byte needs to be @@ -270,11 +270,11 @@ public: } /// emitAlignment - Pad the data to the specified alignment. - void emitAlignment(unsigned Alignment) { + void emitAlignment(unsigned Alignment, uint8_t fill = 0) { if (Alignment <= 1) return; unsigned PadSize = -Data.size() & (Alignment-1); for (unsigned i = 0; i<PadSize; ++i) - Data.push_back(0); + Data.push_back(fill); } /// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be diff --git a/include/llvm/CodeGen/FileWriters.h b/include/llvm/CodeGen/FileWriters.h index b3781e0c60..a913d21eb2 100644 --- a/include/llvm/CodeGen/FileWriters.h +++ b/include/llvm/CodeGen/FileWriters.h @@ -17,14 +17,14 @@ namespace llvm { class PassManagerBase; - class MachineCodeEmitter; + class ObjectCodeEmitter; class TargetMachine; class raw_ostream; - MachineCodeEmitter *AddELFWriter(PassManagerBase &FPM, raw_ostream &O, - TargetMachine &TM); - MachineCodeEmitter *AddMachOWriter(PassManagerBase &FPM, raw_ostream &O, - TargetMachine &TM); + ObjectCodeEmitter *AddELFWriter(PassManagerBase &FPM, raw_ostream &O, + TargetMachine &TM); + ObjectCodeEmitter *AddMachOWriter(PassManagerBase &FPM, raw_ostream &O, + TargetMachine &TM); } // end llvm namespace diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h index eb1ea2dc56..ece416c78d 100644 --- a/include/llvm/CodeGen/MachineCodeEmitter.h +++ b/include/llvm/CodeGen/MachineCodeEmitter.h @@ -74,24 +74,6 @@ public: /// false. /// virtual bool finishFunction(MachineFunction &F) = 0; - - /// startGVStub - This callback is invoked when the JIT needs the - /// address of a GV (e.g. function) that has not been code generated yet. - /// The StubSize specifies the total size required by the stub. - /// - virtual void startGVStub(const GlobalValue* GV, unsigned StubSize, - unsigned Alignment = 1) = 0; - - /// startGVStub - This callback is invoked when the JIT needs the address of a - /// GV (e.g. function) that has not been code generated yet. Buffer points to - /// memory already allocated for this stub. - /// - virtual void startGVStub(const GlobalValue* GV, void *Buffer, - unsigned StubSize) = 0; - - /// finishGVStub - This callback is invoked to terminate a GV stub. - /// - virtual void *finishGVStub(const GlobalValue* F) = 0; /// emitByte - This callback is invoked when a byte needs to be written to the /// output stream. @@ -288,14 +270,13 @@ public: /// getCurrentPCOffset - Return the offset from the start of the emitted /// buffer that we are currently writing to. - uintptr_t getCurrentPCOffset() const { + virtual uintptr_t getCurrentPCOffset() const { return CurBufferPtr-BufferBegin; } /// addRelocation - Whenever a relocatable address is needed, it should be /// noted with this interface. virtual void addRelocation(const MachineRelocation &MR) = 0; - /// FIXME: These should all be handled with relocations! diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 33fc45161a..21e778da40 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -29,6 +29,7 @@ class TargetLowering; class TargetFrameInfo; class MachineCodeEmitter; class JITCodeEmitter; +class ObjectCodeEmitter; class TargetRegisterInfo; class Module; class PassManagerBase; @@ -257,6 +258,16 @@ public: return true; } + /// addPassesToEmitFileFinish - If the passes to emit the specified file had + /// to be split up (e.g., to add an object writer pass), this method can be + /// used to finish up adding passes to emit the file, if necessary. + /// + virtual bool addPassesToEmitFileFinish(PassManagerBase &, + ObjectCodeEmitter *, + CodeGenOpt::Level) { + return true; + } + /// addPassesToEmitMachineCode - Add passes to the specified pass manager to /// get machine code emitted. This uses a MachineCodeEmitter object to handle /// actually outputting the machine code and resolving things like the address @@ -335,7 +346,15 @@ public: /// used to finish up adding passes to emit the file, if necessary. /// virtual bool addPassesToEmitFileFinish(PassManagerBase &PM, - JITCodeEmitter *MCE, + JITCodeEmitter *JCE, + CodeGenOpt::Level); + + /// addPassesToEmitFileFinish - If the passes to emit the specified file had + /// to be split up (e.g., to add an object writer pass), this method can be + /// used to finish up adding passes to emit the file, if necessary. + /// + virtual bool addPassesToEmitFileFinish(PassManagerBase &PM, + ObjectCodeEmitter *OCE, CodeGenOpt::Level); /// addPassesToEmitMachineCode - Add passes to the specified pass manager to @@ -432,6 +451,15 @@ public: return true; } + /// addSimpleCodeEmitter - This pass should be overridden by the target to add + /// a code emitter (without setting flags), if supported. If this is not + /// supported, 'true' should be returned. If DumpAsm is true, the generated + /// assembly is printed to cerr. + virtual bool addSimpleCodeEmitter(PassManagerBase &, CodeGenOpt::Level, + bool /*DumpAsm*/, ObjectCodeEmitter &) { + return true; + } + /// getEnableTailMergeDefault - the default setting for -enable-tail-merge /// on this target. User flag overrides. virtual bool getEnableTailMergeDefault() const { return true; } diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp index 9e91524552..53e4da5845 100644 --- a/lib/CodeGen/ELFWriter.cpp +++ b/lib/CodeGen/ELFWriter.cpp @@ -40,6 +40,8 @@ #include "llvm/CodeGen/BinaryObject.h" #include "llvm/CodeGen/FileWriters.h" #include "llvm/CodeGen/MachineCodeEmitter.h" +#include "llvm/CodeGen/ObjectCodeEmitter.h" +#include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/Target/TargetAsmInfo.h" #include "llvm/Target/TargetData.h" @@ -54,12 +56,12 @@ using namespace llvm; char ELFWriter::ID = 0; /// AddELFWriter - Concrete function to add the ELF writer to the function pass /// manager. -MachineCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM, +ObjectCodeEmitter *llvm::AddELFWriter(PassManagerBase &PM, raw_ostream &O, TargetMachine &TM) { ELFWriter *EW = new ELFWriter(O, TM); PM.add(EW); - return &EW->getMachineCodeEmitter(); + return (ObjectCodeEmitter*) &EW->getMachineCodeEmitter(); } //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index a163cac75b..196d7d9e1e 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -126,6 +126,23 @@ bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM, return false; // success! } +/// addPassesToEmitFileFinish - If the passes to emit the specified file had to +/// be split up (e.g., to add an object writer pass), this method can be used to +/// finish up adding passes to emit the file, if necessary. +bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM, + ObjectCodeEmitter *OCE, + CodeGenOpt::Level OptLevel) { + if (OCE) + addSimpleCodeEmitter(PM, OptLevel, PrintEmittedAsm, *OCE); + + PM.add(createGCInfoDeleter()); + + // Delete machine code for this function + PM.add(createMachineCodeDeleter()); + + return false; // success! +} + /// addPassesToEmitMachineCode - Add passes to the specified pass manager to /// get machine code emitted. This uses a MachineCodeEmitter object to handle /// actually outputting the machine code and resolving things like the address diff --git a/lib/CodeGen/MachO.h b/lib/CodeGen/MachO.h index bd9bd61e9e..76c869992c 100644 --- a/lib/CodeGen/MachO.h +++ b/lib/CodeGen/MachO.h @@ -17,6 +17,7 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/CodeGen/MachineRelocation.h" +#include "llvm/CodeGen/BinaryObject.h" #include "llvm/Target/TargetAsmInfo.h" #include <string> #include <vector> @@ -272,11 +273,10 @@ struct MachOSegment { /// turned into the SectionCommand in the load command for a particlar /// segment. -struct MachOSection { +struct MachOSection : public BinaryObject { std::string sectname; // name of this section, std::string segname; // segment this section goes in uint64_t addr; // memory address of this section - uint64_t size; // size in bytes of this section uint32_t offset; // file offset of this section uint32_t align; // section alignment (power of 2) uint32_t reloff; // file offset of relocation entries @@ -290,19 +290,10 @@ struct MachOSection { /// to the correct section. uint32_t Index; - /// SectionData - The actual data for this section which we are building - /// up for emission to the file. - DataBuffer SectionData; - /// RelocBuffer - A buffer to hold the mach-o relocations before we write /// them out at the appropriate location in the file. DataBuffer RelocBuffer; - /// Relocations - The relocations that we have encountered so far in this - /// section that we will need to convert to MachORelocation entries when - /// the file is written. - std::vector<MachineRelocation> Relocations; - // Constants for the section types (low 8 bits of flags field) // see <mach-o/loader.h> enum { S_REGULAR = 0, @@ -374,48 +365,49 @@ struct MachOSection { } MachOSection(const std::string &seg, const std::string §) - : sectname(sect), segname(seg), addr(0), size(0), offset(0), align(2), - reloff(0), nreloc(0), flags(0), reserved1(0), reserved2(0), + : BinaryObject(), sectname(sect), segname(seg), addr(0), offset(0), + align(2), reloff(0), nreloc(0), flags(0), reserved1(0), reserved2(0), reserved3(0) { } }; // end struct MachOSection - /// MachOSymTab - This struct contains information about the offsets and - /// size of symbol table information. - /// segment. - struct MachODySymTab { - uint32_t cmd; // LC_DYSYMTAB - uint32_t cmdsize; // sizeof( MachODySymTab ) - uint32_t ilocalsym; // index to local symbols - uint32_t nlocalsym; // number of local symbols - uint32_t iextdefsym; // index to externally defined symbols - uint32_t nextdefsym; // number of externally defined symbols - uint32_t iundefsym; // index to undefined symbols - uint32_t nundefsym; // number of undefined symbols - uint32_t tocoff; // file offset to table of contents - uint32_t ntoc; // number of entries in table of contents - uint32_t modtaboff; // file offset to module table - uint32_t nmodtab; // number of module table entries - uint32_t extrefsymoff; // offset to referenced symbol table - uint32_t nextrefsyms; // number of referenced symbol table entries - uint32_t indirectsymoff; // file offset to the indirect symbol table - uint32_t nindirectsyms; // number of indirect symbol table entries - uint32_t extreloff; // offset to external relocation entries - uint32_t nextrel; // number of external relocation entries - uint32_t locreloff; // offset to local relocation entries - uint32_t nlocrel; // number of local relocation entries +/// MachOSymTab - This struct contains information about the offsets and +/// size of symbol table information. +/// segment. +struct MachODySymTab { + uint32_t cmd; // LC_DYSYMTAB + uint32_t cmdsize; // sizeof(MachODySymTab) + uint32_t ilocalsym; // index to local symbols + uint32_t nlocalsym; // number of local symbols + uint32_t iextdefsym; // index to externally defined symbols + uint32_t nextdefsym; // number of externally defined symbols + uint32_t iundefsym; // index to undefined symbols + uint32_t nundefsym; // number of undefined symbols + uint32_t tocoff; // file offset to table of contents + uint32_t ntoc; // number of entries in table of contents + uint32_t modtaboff; // file offset to module table + uint32_t nmodtab; // number of module table entries + uint32_t extrefsymoff; // offset to referenced symbol table + uint32_t nextrefsyms; // number of referenced symbol table entries + uint32_t indirectsymoff; // file offset to the indirect symbol table + uint32_t nindirectsyms; // number of indirect symbol table entries + uint32_t extreloff; // offset to external relocation entries + uint32_t nextrel; // number of external relocation entries + uint32_t locreloff; // offset to local relocation entries + uint32_t nlocrel; // number of local relocation entries + + // Constants for the cmd field + // see <mach-o/loader.h> + enum { LC_DYSYMTAB = 0x0B // dynamic link-edit symbol table info + }; + + MachODySymTab() : cmd(LC_DYSYMTAB), cmdsize(20 * sizeof(uint32_t)), + ilocalsym(0), nlocalsym(0), iextdefsym(0), nextdefsym(0), + iundefsym(0), nundefsym(0), tocoff(0), ntoc(0), modtaboff(0), + nmodtab(0), extrefsymoff(0), nextrefsyms(0), indirectsymoff(0), + nindirectsyms(0), extreloff(0), nextrel(0), locreloff(0), nlocrel(0) { } - // Constants for the cmd field - // see <mach-o/loader.h> - enum { LC_DYSYMTAB = 0x0B // dynamic link-edit symbol table info - }; - - MachODySymTab() : cmd(LC_DYSYMTAB), cmdsize(20 * sizeof(uint32_t)), - ilocalsym(0), nlocalsym(0), iextdefsym(0), nextdefsym(0), - iundefsym(0), nundefsym(0), tocoff(0), ntoc(0), modtaboff(0), - nmodtab(0), extrefsymoff(0), nextrefsyms(0), indirectsymoff(0), - nindirectsyms(0), extreloff(0), nextrel(0), locreloff(0), nlocrel(0) { } - }; +}; // end struct MachODySymTab } // end namespace llvm diff --git a/lib/CodeGen/MachOCodeEmitter.cpp b/lib/CodeGen/MachOCodeEmitter.cpp index 02b02de9ec..52b5092367 100644 --- a/lib/CodeGen/MachOCodeEmitter.cpp +++ b/lib/CodeGen/MachOCodeEmitter.cpp @@ -16,6 +16,7 @@ #include "llvm/Target/TargetAsmInfo.h" #include "llvm/Support/Mangler.h" #include "llvm/Support/OutputBuffer.h" +#include <vector> //===----------------------------------------------------------------------===// // MachOCodeEmitter Implementation @@ -39,28 +40,18 @@ void MachOCodeEmitter::startFunction(MachineFunction &MF) { // Get the Mach-O Section that this function belongs in. MachOSection *MOS = MOW.getTextSection(); - // FIXME: better memory management - MOS->SectionData.reserve(4096); - BufferBegin = &MOS->SectionData[0]; - BufferEnd = BufferBegin + MOS->SectionData.capacity(); - // Upgrade the section alignment if required. if (MOS->align < Align) MOS->align = Align; - // Round the size up to the correct alignment for starting the new function. - if ((MOS->size & ((1 << Align) - 1)) != 0) { - MOS->size += (1 << Align); - MOS->size &= ~((1 << Align) - 1); - } + MOS->emitAlignment(Align); - // FIXME: Using MOS->size directly here instead of calculating it from the - // output buffer size (impossible because the code emitter deals only in raw - // bytes) forces us to manually synchronize size and write padding zero bytes - // to the output buffer for all non-text sections. For text sections, we do - // not synchonize the output buffer, and we just blow up if anyone tries to - // write non-code to it. An assert should probably be added to - // AddSymbolToSection to prevent calling it on the text section. - CurBufferPtr = BufferBegin + MOS->size; + // Create symbol for function entry + const GlobalValue *FuncV = MF.getFunction(); + MachOSym FnSym(FuncV, MOW.Mang->getValueName(FuncV), MOS->Index, TAI); + FnSym.n_value = getCurrentPCOffset(); + + // add it to the symtab. + MOW.SymbolTable.push_back(FnSym); } /// finishFunction - This callback is invoked after the function is completely @@ -71,15 +62,6 @@ bool MachOCodeEmitter::finishFunction(MachineFunction &MF) { // Get the Mach-O Section that this function belongs in. MachOSection *MOS = MOW.getTextSection(); - // Get a symbol for the function to add to the symbol table - // FIXME: it seems like we should call something like AddSymbolToSection - // in startFunction rather than changing the section size and symbol n_value - // here. - const GlobalValue *FuncV = MF.getFunction(); - MachOSym FnSym(FuncV, MOW.Mang->getValueName(FuncV), MOS->Index, TAI); - FnSym.n_value = MOS->size; - MOS->size = CurBufferPtr - BufferBegin; - // Emit constant pool to appropriate section(s) emitConstantPool(MF.getConstantPool()); @@ -112,12 +94,9 @@ bool MachOCodeEmitter::finishFunction(MachineFunction &MF) { } else { assert(0 && "Unhandled relocation type"); } - MOS->Relocations.push_back(MR); + MOS->addRelocation(MR); } Relocations.clear(); - - // Finally, add it to the symtab. - MOW.SymbolTable.push_back(FnSym); // Clear per-function data structures. CPLocations.clear(); @@ -151,13 +130,10 @@ void MachOCodeEmitter::emitConstantPool(MachineConstantPool *MCP) { unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty); MachOSection *Sec = MOW.getConstSection(CP[i].Val.ConstVal); - OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian); + OutputBuffer SecDataOut(Sec->getData(), is64Bit, isLittleEndian); - CPLocations.push_back(Sec->SectionData.size()); + CPLocations.push_back(Sec->size()); CPSections.push_back(Sec->Index); - - // FIXME: remove when we have unified size + output buffer - Sec->size += Size; // Allocate space in the section for the global. // FIXME: need alignment? @@ -165,14 +141,12 @@ void MachOCodeEmitter::emitConstantPool(MachineConstantPool *MCP) { for (unsigned j = 0; j < Size; ++j) SecDataOut.outbyte(0); - MOW.InitMem(CP[i].Val.ConstVal, &Sec->SectionData[0], CPLocations[i], - TM.getTargetData(), Sec->Relocations); + MachOWriter::InitMem(CP[i].Val.ConstVal, CPLocations[i], TM.getTargetData(), Sec); } } /// emitJumpTables - Emit all the jump tables for a given jump table info /// record to the appropriate section. - void MachOCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) { const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); if (JT.empty()) return; @@ -183,24 +157,21 @@ void MachOCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) { MachOSection *Sec = MOW.getJumpTableSection(); unsigned TextSecIndex = MOW.getTextSection()->Index; - OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian); + OutputBuffer SecDataOut(Sec->getData(), is64Bit, isLittleEndian); for (unsigned i = 0, e = JT.size(); i != e; ++i) { // For each jump table, record its offset from the start of the section, // reserve space for the relocations to the MBBs, and add the relocations. const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs; - JTLocations.push_back(Sec->SectionData.size()); + JTLocations.push_back(Sec->size()); for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) { - MachineRelocation MR(MOW.GetJTRelocation(Sec->SectionData.size(), - MBBs[mi])); + MachineRelocation MR(MOW.GetJTRelocation(Sec->size(), MBBs[mi])); MR.setResultPointer((void *)JTLocations[i]); MR.setConstantVal(TextSecIndex); - Sec->Relocations.push_back(MR); + Sec->addRelocation(MR); SecDataOut.outaddr(0); } } - // FIXME: remove when we have unified size + output buffer - Sec->size = Sec->SectionData.size(); } } // end namespace llvm diff --git a/lib/CodeGen/MachOCodeEmitter.h b/lib/CodeGen/MachOCodeEmitter.h index 0a6e4e4d19..c280706e48 100644 --- a/lib/CodeGen/MachOCodeEmitter.h +++ b/lib/CodeGen/MachOCodeEmitter.h @@ -11,15 +11,13 @@ #define MACHOCODEEMITTER_H #include "MachOWriter.h" -#include "llvm/CodeGen/MachineCodeEmitter.h" -#include <vector> namespace llvm { /// MachOCodeEmitter - This class is used by the MachOWriter to emit the code /// for functions to the Mach-O file. -class MachOCodeEmitter : public MachineCodeEmitter { +class MachOCodeEmitter : public ObjectCodeEmitter { MachOWriter &MOW; /// Target machine description. @@ -34,27 +32,12 @@ class MachOCodeEmitter : public MachineCodeEmitter { /// Relocations - These are the relocations that the function needs, as /// emitted. std::vector<MachineRelocation> Relocations; - - /// CPLocations - This is a map of constant pool indices to offsets from the - /// start of the section for that constant pool index. - std::vector<uintptr_t> CPLocations; - - /// CPSections - This is a map of constant pool indices to the MachOSection - /// containing the constant pool entry for that index. - std::vector<unsigned> CPSections; - - /// JTLocations - This is a map of jump table indices to offsets from the - /// start of the section for that jump table index. - std::vector<uintptr_t> JTLocations; - - /// MBBLocations - This vector is a mapping from MBB ID's to their address. - /// It is filled in by the StartMachineBasicBlock callback and queried by - /// the getMachineBasicBlockAddress callback. - std::vector<uintptr_t> MBBLocations; - + + std::map<uint64_t, uintptr_t> Labels; + public: - MachOCodeEmitter(MachOWriter &mow) : MOW(mow), TM(MOW.TM) - { + MachOCodeEmitter(MachOWriter &mow, MachOSection &mos) : + ObjectCodeEmitter(&mos), MOW(mow), TM(MOW.TM) { is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64; isLittleEndian = TM.getTargetData()->isLittleEndian(); TAI = TM.getTargetAsmInfo(); @@ -69,58 +52,17 @@ public: void emitConstantPool(MachineConstantPool *MCP); void emitJumpTables(MachineJumpTableInfo *MJTI); - - virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const { - assert(CPLocations.size() > Index && "CP not emitted!"); - return CPLocations[Index]; - } - virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const { - assert(JTLocations.size() > Index && "JT not emitted!"); - return JTLocations[Index]; - } - - virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) { - if (MBBLocations.size() <= (unsigned)MBB->getNumber()) - MBBLocations.resize((MBB->getNumber()+1)*2); - MBBLocations[MBB->getNumber()] = getCurrentPCOffset(); - } - virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { - assert(MBBLocations.size() > (unsigned)MBB->getNumber() && - MBBLocations[MBB->getNumber()] && "MBB not emitted!"); - return MBBLocations[MBB->getNumber()]; + virtual void emitLabel(uint64_t LabelID) { + Labels[LabelID] = getCurrentPCOffset(); } virtual uintptr_t getLabelAddress(uint64_t Label) const { - assert(0 && "get Label not implemented"); - abort(); - return 0; - } - - virtual void emitLabel(uint64_t LabelID) { - assert(0 && "emit Label not implemented"); - abort(); + return Labels.find(Label)->second; } virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { } - /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE! - virtual void startGVStub(const GlobalValue* F, unsigned StubSize, - unsigned Alignment = 1) { - assert(0 && "JIT specific function called!"); - abort(); - } - virtual void startGVStub(const GlobalValue* F, void *Buffer, - unsigned StubSize) { - assert(0 && "JIT specific function called!"); - abort(); - } - virtual void *finishGVStub(const GlobalValue* F) { - assert(0 && "JIT specific function called!"); - abort(); - return 0; - } - }; // end class MachOCodeEmitter } // end namespace llvm diff --git a/lib/CodeGen/MachOWriter.cpp b/lib/CodeGen/MachOWriter.cpp index 163df6994a..1dbbf15d9d 100644 --- a/lib/CodeGen/MachOWriter.cpp +++ b/lib/CodeGen/MachOWriter.cpp @@ -46,12 +46,12 @@ namespace llvm { /// AddMachOWriter - Concrete function to add the Mach-O writer to the function /// pass manager. -MachineCodeEmitter *AddMachOWriter(PassManagerBase &PM, +ObjectCodeEmitter *AddMachOWriter(PassManagerBase &PM, raw_ostream &O, TargetMachine &TM) { MachOWriter *MOW = new MachOWriter(O, TM); PM.add(MOW); - return &MOW->getMachineCodeEmitter(); + return MOW->getObjectCodeEmitter(); } //===----------------------------------------------------------------------===// @@ -60,8 +60,9 @@ MachineCodeEmitter *AddMachOWriter(PassManagerBase &PM, char MachOWriter::ID = 0; -MachOWriter::MachOWriter(raw_ostream &o, TargetMachine &tm) - : MachineFunctionPass(&ID), O(o), TM(tm) { +MachOWriter::MachOWriter(raw_ostream &o, TargetMachine &tm) + : MachineFunctionPass(&ID), O(o), TM(tm) + { is64Bit = TM.getTargetData()->getPointerSizeInBits() == 64; isLittleEndian = TM.getTargetData()->isLittleEndian(); @@ -69,11 +70,11 @@ MachOWriter::MachOWriter(raw_ostream &o, TargetMachine &tm) // Create the machine code emitter object for this target. - MCE = new MachOCodeEmitter(*this); + MachOCE = new MachOCodeEmitter(*this, *getTextSection(true)); } MachOWriter::~MachOWriter() { - delete MCE; + delete MachOCE; } bool MachOWriter::doInitialization(Module &M) { @@ -97,13 +98,13 @@ bool MachOWriter::runOnMachineFunction(MachineFunction &MF) { /// the Mach-O file to 'O'. bool MachOWriter::doFinalization(Module &M) { // FIXME: we don't handle debug info yet, we should probably do that. - - // Okay, the.text section has been completed, build the .data, .bss, and + // Okay, the.text section has been completed, build the .data, .bss, and // "common" sections next. + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) EmitGlobal(I); - + // Emit the header and load commands. EmitHeaderAndLoadCommands(); @@ -133,38 +134,32 @@ void MachOWri |