//
// The LLVM Compiler Infrastructure
//
-// This file was developed by Nate Begeman and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/OutputBuffer.h"
#include "llvm/Support/Streams.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <cstring>
using namespace llvm;
/// AddMachOWriter - Concrete function to add the Mach-O writer to the function
/// pass manager.
-MachineCodeEmitter *llvm::AddMachOWriter(FunctionPassManager &FPM,
- std::ostream &O,
+MachineCodeEmitter *llvm::AddMachOWriter(PassManagerBase &PM,
+ raw_ostream &O,
TargetMachine &TM) {
MachOWriter *MOW = new MachOWriter(O, TM);
- FPM.add(MOW);
+ PM.add(MOW);
return &MOW->getMachineCodeEmitter();
}
/// CPLocations - This is a map of constant pool indices to offsets from the
/// start of the section for that constant pool index.
- std::vector<intptr_t> CPLocations;
+ 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.
/// JTLocations - This is a map of jump table indices to offsets from the
/// start of the section for that jump table index.
- std::vector<intptr_t> JTLocations;
+ 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<intptr_t> MBBLocations;
+ std::vector<uintptr_t> MBBLocations;
public:
MachOCodeEmitter(MachOWriter &mow) : MOW(mow), TM(MOW.TM) {
void emitConstantPool(MachineConstantPool *MCP);
void emitJumpTables(MachineJumpTableInfo *MJTI);
- virtual intptr_t getConstantPoolEntryAddress(unsigned Index) const {
+ virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
assert(CPLocations.size() > Index && "CP not emitted!");
return CPLocations[Index];
}
- virtual intptr_t getJumpTableEntryAddress(unsigned Index) const {
+ virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
assert(JTLocations.size() > Index && "JT not emitted!");
return JTLocations[Index];
}
MBBLocations[MBB->getNumber()] = getCurrentPCOffset();
}
- virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
+ virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
MBBLocations[MBB->getNumber()] && "MBB not emitted!");
return MBBLocations[MBB->getNumber()];
}
+ 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();
+ }
+
+
+ virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
+
/// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
- virtual void startFunctionStub(unsigned StubSize, unsigned Alignment = 1) {
+ 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 *finishFunctionStub(const Function *F) {
+ virtual void *finishGVStub(const GlobalValue* F) {
assert(0 && "JIT specific function called!");
abort();
return 0;
if (CP.empty()) return;
// FIXME: handle PIC codegen
- bool isPIC = TM.getRelocationModel() == Reloc::PIC_;
- assert(!isPIC && "PIC codegen not yet handled for mach-o jump tables!");
+ assert(TM.getRelocationModel() != Reloc::PIC_ &&
+ "PIC codegen not yet handled for mach-o jump tables!");
// Although there is no strict necessity that I am aware of, we will do what
// gcc for OS X does and put each constant pool entry in a section of constant
// "giant object for PIC" optimization.
for (unsigned i = 0, e = CP.size(); i != e; ++i) {
const Type *Ty = CP[i].getType();
- unsigned Size = TM.getTargetData()->getTypeSize(Ty);
+ unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty);
MachOWriter::MachOSection *Sec = MOW.getConstSection(CP[i].Val.ConstVal);
OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian);
if (JT.empty()) return;
// FIXME: handle PIC codegen
- bool isPIC = TM.getRelocationModel() == Reloc::PIC_;
- assert(!isPIC && "PIC codegen not yet handled for mach-o jump tables!");
+ assert(TM.getRelocationModel() != Reloc::PIC_ &&
+ "PIC codegen not yet handled for mach-o jump tables!");
MachOWriter::MachOSection *Sec = MOW.getJumpTableSection();
unsigned TextSecIndex = MOW.getTextSection()->Index;
//===----------------------------------------------------------------------===//
char MachOWriter::ID = 0;
-MachOWriter::MachOWriter(std::ostream &o, TargetMachine &tm)
- : MachineFunctionPass((intptr_t)&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();
void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) {
const Type *Ty = GV->getType()->getElementType();
- unsigned Size = TM.getTargetData()->getTypeSize(Ty);
- unsigned Align = GV->getAlignment();
- if (Align == 0)
- Align = TM.getTargetData()->getPrefTypeAlignment(Ty);
-
+ unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty);
+ unsigned Align = TM.getTargetData()->getPreferredAlignment(GV);
+
// Reserve space in the .bss section for this symbol while maintaining the
// desired section alignment, which must be at least as much as required by
// this symbol.
SecDataOut.outbyte(0);
}
// Globals without external linkage apparently do not go in the symbol table.
- if (GV->getLinkage() != GlobalValue::InternalLinkage) {
+ if (!GV->hasLocalLinkage()) {
MachOSym Sym(GV, Mang->getValueName(GV), Sec->Index, TM);
Sym.n_value = Sec->size;
SymbolTable.push_back(Sym);
void MachOWriter::EmitGlobal(GlobalVariable *GV) {
const Type *Ty = GV->getType()->getElementType();
- unsigned Size = TM.getTargetData()->getTypeSize(Ty);
+ unsigned Size = TM.getTargetData()->getTypePaddedSize(Ty);
bool NoInit = !GV->hasInitializer();
// If this global has a zero initializer, it is part of the .bss or common
// If this global is part of the common block, add it now. Variables are
// part of the common block if they are zero initialized and allowed to be
// merged with other symbols.
- if (NoInit || GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) {
+ if (NoInit || GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
+ GV->hasCommonLinkage()) {
MachOSym ExtOrCommonSym(GV, Mang->getValueName(GV), MachOSym::NO_SECT,TM);
// For undefined (N_UNDF) external (N_EXT) types, n_value is the size in
// bytes of the symbol.
if (isa<UndefValue>(PC)) {
continue;
} else if (const ConstantVector *CP = dyn_cast<ConstantVector>(PC)) {
- unsigned ElementSize = TD->getTypeSize(CP->getType()->getElementType());
+ unsigned ElementSize =
+ TD->getTypePaddedSize(CP->getType()->getElementType());
for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
WorkList.push_back(CPair(CP->getOperand(i), PA+i*ElementSize));
} else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(PC)) {
abort();
break;
}
- } else if (PC->getType()->isFirstClassType()) {
+ } else if (PC->getType()->isSingleValueType()) {
unsigned char *ptr = (unsigned char *)PA;
switch (PC->getType()->getTypeID()) {
case Type::IntegerTyID: {
break;
}
case Type::FloatTyID: {
- uint32_t val = (uint32_t)*cast<ConstantFP>(PC)->
- getValueAPF().convertToAPInt().getRawData();
+ uint32_t val = cast<ConstantFP>(PC)->getValueAPF().bitcastToAPInt().
+ getZExtValue();
if (TD->isBigEndian())
val = ByteSwap_32(val);
ptr[0] = val;
break;
}
case Type::DoubleTyID: {
- uint64_t val = *cast<ConstantFP>(PC)->getValueAPF().convertToAPInt().
- getRawData();
+ uint64_t val = cast<ConstantFP>(PC)->getValueAPF().bitcastToAPInt().
+ getZExtValue();
if (TD->isBigEndian())
val = ByteSwap_64(val);
ptr[0] = val;
abort();
}
} else if (isa<ConstantAggregateZero>(PC)) {
- memset((void*)PA, 0, (size_t)TD->getTypeSize(PC->getType()));
+ memset((void*)PA, 0, (size_t)TD->getTypePaddedSize(PC->getType()));
} else if (const ConstantArray *CPA = dyn_cast<ConstantArray>(PC)) {
- unsigned ElementSize = TD->getTypeSize(CPA->getType()->getElementType());
+ unsigned ElementSize =
+ TD->getTypePaddedSize(CPA->getType()->getElementType());
for (unsigned i = 0, e = CPA->getNumOperands(); i != e; ++i)
WorkList.push_back(CPair(CPA->getOperand(i), PA+i*ElementSize));
} else if (const ConstantStruct *CPS = dyn_cast<ConstantStruct>(PC)) {
default:
assert(0 && "Unexpected linkage type!");
break;
- case GlobalValue::WeakLinkage:
- case GlobalValue::LinkOnceLinkage:
+ case GlobalValue::WeakAnyLinkage:
+ case GlobalValue::WeakODRLinkage:
+ case GlobalValue::LinkOnceAnyLinkage:
+ case GlobalValue::LinkOnceODRLinkage:
+ case GlobalValue::CommonLinkage:
assert(!isa<Function>(gv) && "Unexpected linkage type for Function!");
case GlobalValue::ExternalLinkage:
GVName = TAI->getGlobalPrefix() + name;
n_type |= GV->hasHiddenVisibility() ? N_PEXT : N_EXT;
break;
+ case GlobalValue::PrivateLinkage:
+ GVName = TAI->getPrivateGlobalPrefix() + name;
+ break;
case GlobalValue::InternalLinkage:
GVName = TAI->getGlobalPrefix() + name;
break;