#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetRegistry.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Mangler.h"
#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/FormattedStream.h"
#include <cctype>
using namespace llvm;
/// GVNonLazyPtrs - Keeps the set of GlobalValues that require
/// non-lazy-pointers for indirect access.
- StringSet<> GVNonLazyPtrs;
+ StringMap<std::string> GVNonLazyPtrs;
/// HiddenGVNonLazyPtrs - Keeps the set of GlobalValues with hidden
/// visibility that require non-lazy-pointers for indirect access.
- StringSet<> HiddenGVNonLazyPtrs;
-
+ StringMap<std::string> HiddenGVNonLazyPtrs;
+
+ struct FnStubInfo {
+ std::string Stub, LazyPtr, SLP, SCV;
+
+ FnStubInfo() {}
+
+ void Init(const GlobalValue *GV, Mangler *Mang) {
+ // Already initialized.
+ if (!Stub.empty()) return;
+ Stub = Mang->getMangledName(GV, "$stub", true);
+ LazyPtr = Mang->getMangledName(GV, "$lazy_ptr", true);
+ SLP = Mang->getMangledName(GV, "$slp", true);
+ SCV = Mang->getMangledName(GV, "$scv", true);
+ }
+
+ void Init(const std::string &GV, Mangler *Mang) {
+ // Already initialized.
+ if (!Stub.empty()) return;
+ Stub = Mang->makeNameProper(GV+"$stub", true);
+ LazyPtr = Mang->makeNameProper(GV+"$lazy_ptr", true);
+ SLP = Mang->makeNameProper(GV+"$slp", true);
+ SCV = Mang->makeNameProper(GV+"$scv", true);
+ }
+
+ };
+
/// FnStubs - Keeps the set of external function GlobalAddresses that the
/// asm printer should generate stubs for.
- StringSet<> FnStubs;
+ StringMap<FnStubInfo> FnStubs;
/// True if asm printer is printing a series of CONSTPOOL_ENTRY.
bool InCPMode;
public:
- explicit ARMAsmPrinter(raw_ostream &O, TargetMachine &TM,
+ explicit ARMAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
const TargetAsmInfo *T, bool V)
: AsmPrinter(O, TM, T, V), DW(0), AFI(NULL), MCP(NULL),
InCPMode(false) {
ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
GlobalValue *GV = ACPV->getGV();
- std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix();
- if (!GV)
- Name += ACPV->getSymbol();
+ std::string Name;
+
+
if (ACPV->isNonLazyPointer()) {
+ std::string SymName = Mang->getMangledName(GV);
+ Name = Mang->getMangledName(GV, "$non_lazy_ptr", true);
+
if (GV->hasHiddenVisibility())
- HiddenGVNonLazyPtrs.insert(Name);
+ HiddenGVNonLazyPtrs[SymName] = Name;
else
- GVNonLazyPtrs.insert(Name);
- printSuffixedName(Name, "$non_lazy_ptr");
+ GVNonLazyPtrs[SymName] = Name;
} else if (ACPV->isStub()) {
- FnStubs.insert(Name);
- printSuffixedName(Name, "$stub");
- } else
- O << Name;
+ if (GV) {
+ FnStubInfo &FnInfo = FnStubs[Mang->getMangledName(GV)];
+ FnInfo.Init(GV, Mang);
+ Name = FnInfo.Stub;
+ } else {
+ FnStubInfo &FnInfo = FnStubs[Mang->makeNameProper(ACPV->getSymbol())];
+ FnInfo.Init(ACPV->getSymbol(), Mang);
+ Name = FnInfo.Stub;
+ }
+ } else {
+ if (GV)
+ Name = Mang->getMangledName(GV);
+ else
+ Name = Mang->makeNameProper(ACPV->getSymbol());
+ }
+ O << Name;
+
+
+
if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
if (ACPV->getPCAdjustment() != 0) {
O << "-(" << TAI->getPrivateGlobalPrefix() << "PC"
// Print out labels for the function.
const Function *F = MF.getFunction();
switch (F->getLinkage()) {
- default: LLVM_UNREACHABLE("Unknown linkage type!");
+ default: llvm_unreachable("Unknown linkage type!");
case Function::PrivateLinkage:
case Function::InternalLinkage:
SwitchToTextSection("\t.text", F);
O << TRI->getAsmName(Reg);
}
} else
- LLVM_UNREACHABLE("not implemented");
+ llvm_unreachable("not implemented");
break;
}
case MachineOperand::MO_Immediate: {
case MachineOperand::MO_GlobalAddress: {
bool isCallOp = Modifier && !strcmp(Modifier, "call");
GlobalValue *GV = MO.getGlobal();
- std::string Name = Mang->getValueName(GV);
- bool isExt = (GV->isDeclaration() || GV->hasWeakLinkage() ||
- GV->hasLinkOnceLinkage());
+ std::string Name;
+ bool isExt = GV->isDeclaration() || GV->isWeakForLinker();
if (isExt && isCallOp && Subtarget->isTargetDarwin() &&
TM.getRelocationModel() != Reloc::Static) {
- printSuffixedName(Name, "$stub");
- FnStubs.insert(Name);
- } else
- O << Name;
+ FnStubInfo &FnInfo = FnStubs[Mang->getMangledName(GV)];
+ FnInfo.Init(GV, Mang);
+ Name = FnInfo.Stub;
+ } else {
+ Name = Mang->getMangledName(GV);
+ }
+
+ O << Name;
printOffset(MO.getOffset());
}
case MachineOperand::MO_ExternalSymbol: {
bool isCallOp = Modifier && !strcmp(Modifier, "call");
- std::string Name(TAI->getGlobalPrefix());
- Name += MO.getSymbolName();
+ std::string Name;
if (isCallOp && Subtarget->isTargetDarwin() &&
TM.getRelocationModel() != Reloc::Static) {
- printSuffixedName(Name, "$stub");
- FnStubs.insert(Name);
+ FnStubInfo &FnInfo = FnStubs[Mang->makeNameProper(MO.getSymbolName())];
+ FnInfo.Init(MO.getSymbolName(), Mang);
+ Name = FnInfo.Stub;
} else
- O << Name;
+ Name = Mang->makeNameProper(MO.getSymbolName());
+
+ O << Name;
if (isCallOp && Subtarget->isTargetELF() &&
TM.getRelocationModel() == Reloc::PIC_)
O << "(PLT)";
}
}
-static void printSOImm(raw_ostream &O, int64_t V, bool VerboseAsm,
+static void printSOImm(formatted_raw_ostream &O, int64_t V, bool VerboseAsm,
const TargetAsmInfo *TAI) {
// Break it up into two parts that make up a shifter immediate.
V = ARM_AM::getSOImmVal(V);
unsigned Mask = MI->getOperand(Op).getImm();
unsigned NumTZ = CountTrailingZeros_32(Mask);
assert(NumTZ <= 3 && "Invalid IT mask!");
- for (unsigned Pos = 3, e = NumTZ; Pos >= e; --Pos) {
+ for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
bool T = (Mask & (1 << Pos)) != 0;
if (T)
O << 't';
bool Result = AsmPrinter::doInitialization(M);
DW = getAnalysisIfAvailable<DwarfWriter>();
- // Thumb-2 instructions are supported only in unified assembler syntax mode.
- if (Subtarget->hasThumb2())
+ // Use unified assembler syntax mode for Thumb.
+ if (Subtarget->isThumb())
O << "\t.syntax unified\n";
// Emit ARM Build Attributes
/// PrintUnmangledNameSafely - Print out the printable characters in the name.
/// Don't print things like \\n or \\0.
-static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) {
+static void PrintUnmangledNameSafely(const Value *V, formatted_raw_ostream &OS) {
for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
Name != E; ++Name)
if (isprint(*Name))
return;
}
- std::string name = Mang->getValueName(GVar);
+ std::string name = Mang->getMangledName(GVar);
Constant *C = GVar->getInitializer();
if (isa<MDNode>(C) || isa<MDString>(C))
return;
case GlobalValue::InternalLinkage:
break;
default:
- LLVM_UNREACHABLE("Unknown linkage type!");
+ llvm_unreachable("Unknown linkage type!");
}
EmitAlignment(Align, GVar);
if (Subtarget->isTargetDarwin()) {
SwitchToDataSection("");
+ O << '\n';
// Output stubs for dynamically-linked functions
- for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
- i != e; ++i) {
+ for (StringMap<FnStubInfo>::iterator I = FnStubs.begin(), E = FnStubs.end();
+ I != E; ++I) {
+ const FnStubInfo &Info = I->second;
if (TM.getRelocationModel() == Reloc::PIC_)
SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs,"
"none,16", 0);
EmitAlignment(2);
O << "\t.code\t32\n";
- const char *p = i->getKeyData();
- printSuffixedName(p, "$stub");
- O << ":\n";
- O << "\t.indirect_symbol " << p << "\n";
- O << "\tldr ip, ";
- printSuffixedName(p, "$slp");
- O << "\n";
+ O << Info.Stub << ":\n";
+ O << "\t.indirect_symbol " << I->getKeyData() << '\n';
+ O << "\tldr ip, " << Info.SLP << '\n';
if (TM.getRelocationModel() == Reloc::PIC_) {
- printSuffixedName(p, "$scv");
- O << ":\n";
+ O << Info.SCV << ":\n";
O << "\tadd ip, pc, ip\n";
}
O << "\tldr pc, [ip, #0]\n";
- printSuffixedName(p, "$slp");
- O << ":\n";
- O << "\t.long\t";
- printSuffixedName(p, "$lazy_ptr");
- if (TM.getRelocationModel() == Reloc::PIC_) {
- O << "-(";
- printSuffixedName(p, "$scv");
- O << "+8)\n";
- } else
- O << "\n";
+ O << Info.SLP << ":\n";
+ O << "\t.long\t" << Info.LazyPtr;
+ if (TM.getRelocationModel() == Reloc::PIC_)
+ O << "-(" << Info.SCV << "+8)";
+ O << '\n';
+
SwitchToDataSection(".lazy_symbol_pointer", 0);
- printSuffixedName(p, "$lazy_ptr");
- O << ":\n";
- O << "\t.indirect_symbol " << p << "\n";
+ O << Info.LazyPtr << ":\n";
+ O << "\t.indirect_symbol " << I->getKeyData() << "\n";
O << "\t.long\tdyld_stub_binding_helper\n";
}
- O << "\n";
+ O << '\n';
// Output non-lazy-pointers for external and common global variables.
if (!GVNonLazyPtrs.empty()) {
SwitchToDataSection("\t.non_lazy_symbol_pointer", 0);
- for (StringSet<>::iterator i = GVNonLazyPtrs.begin(),
- e = GVNonLazyPtrs.end(); i != e; ++i) {
- const char *p = i->getKeyData();
- printSuffixedName(p, "$non_lazy_ptr");
- O << ":\n";
- O << "\t.indirect_symbol " << p << "\n";
+ for (StringMap<std::string>::iterator I = GVNonLazyPtrs.begin(),
+ E = GVNonLazyPtrs.end(); I != E; ++I) {
+ O << I->second << ":\n";
+ O << "\t.indirect_symbol " << I->getKeyData() << "\n";
O << "\t.long\t0\n";
}
}
if (!HiddenGVNonLazyPtrs.empty()) {
SwitchToSection(TAI->getDataSection());
- for (StringSet<>::iterator i = HiddenGVNonLazyPtrs.begin(),
- e = HiddenGVNonLazyPtrs.end(); i != e; ++i) {
- const char *p = i->getKeyData();
+ for (StringMap<std::string>::iterator I = HiddenGVNonLazyPtrs.begin(),
+ E = HiddenGVNonLazyPtrs.end(); I != E; ++I) {
EmitAlignment(2);
- printSuffixedName(p, "$non_lazy_ptr");
- O << ":\n";
- O << "\t.long " << p << "\n";
+ O << I->second << ":\n";
+ O << "\t.long " << I->getKeyData() << "\n";
}
}
/// using the given target machine description. This should work
/// regardless of whether the function is in SSA form.
///
-FunctionPass *llvm::createARMCodePrinterPass(raw_ostream &o,
- ARMBaseTargetMachine &tm,
+FunctionPass *llvm::createARMCodePrinterPass(formatted_raw_ostream &o,
+ TargetMachine &tm,
bool verbose) {
return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo(), verbose);
}
-namespace {
- static struct Register {
- Register() {
- ARMBaseTargetMachine::registerAsmPrinter(createARMCodePrinterPass);
- }
- } Registrator;
-}
-
// Force static initialization.
-extern "C" void LLVMInitializeARMAsmPrinter() { }
+extern "C" void LLVMInitializeARMAsmPrinter() {
+ extern Target TheARMTarget, TheThumbTarget;
+ TargetRegistry::RegisterAsmPrinter(TheARMTarget, createARMCodePrinterPass);
+ TargetRegistry::RegisterAsmPrinter(TheThumbTarget, createARMCodePrinterPass);
+}