summaryrefslogtreecommitdiffstats
path: root/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp')
-rw-r--r--lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp122
1 files changed, 78 insertions, 44 deletions
diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
index aae4607..d505d38 100644
--- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
+++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
@@ -32,6 +32,7 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
@@ -49,6 +50,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/SmallString.h"
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
@@ -57,27 +59,42 @@ namespace {
class PPCAsmPrinter : public AsmPrinter {
protected:
struct FnStubInfo {
- std::string Stub, LazyPtr, AnonSymbol;
+ MCSymbol *Stub, *LazyPtr, *AnonSymbol;
- FnStubInfo() {}
+ FnStubInfo() {
+ Stub = LazyPtr = AnonSymbol = 0;
+ }
- void Init(const GlobalValue *GV, Mangler *Mang) {
+ void Init(const GlobalValue *GV, Mangler *Mang, MCContext &Ctx) {
// Already initialized.
- if (!Stub.empty()) return;
- Stub = Mang->getMangledName(GV, "$stub", true);
- LazyPtr = Mang->getMangledName(GV, "$lazy_ptr", true);
- AnonSymbol = Mang->getMangledName(GV, "$stub$tmp", true);
+ if (Stub != 0) return;
+
+ // Get the names.
+ SmallString<128> TmpStr;
+ Mang->getNameWithPrefix(TmpStr, GV, true);
+ MakeSymbols(TmpStr, Ctx);
}
- void Init(const std::string &GV, Mangler *Mang) {
- // Already initialized.
- if (!Stub.empty()) return;
- Stub = Mang->makeNameProper(GV + "$stub",
- Mangler::Private);
- LazyPtr = Mang->makeNameProper(GV + "$lazy_ptr",
- Mangler::Private);
- AnonSymbol = Mang->makeNameProper(GV + "$stub$tmp",
- Mangler::Private);
+ void Init(StringRef GVName, Mangler *Mang, MCContext &Ctx) {
+ assert(!GVName.empty() && "external symbol name shouldn't be empty");
+ if (Stub != 0) return; // Already initialized.
+ // Get the names for the external symbol name.
+ SmallString<128> TmpStr;
+ Mang->getNameWithPrefix(TmpStr, GVName, Mangler::Private);
+ MakeSymbols(TmpStr, Ctx);
+ }
+
+ void MakeSymbols(SmallString<128> &TmpStr, MCContext &Ctx) {
+ TmpStr += "$stub";
+ Stub = Ctx.GetOrCreateSymbol(TmpStr.str());
+ TmpStr.erase(TmpStr.end()-5, TmpStr.end()); // Remove $stub
+
+ TmpStr += "$lazy_ptr";
+ LazyPtr = Ctx.GetOrCreateSymbol(TmpStr.str());
+ TmpStr.erase(TmpStr.end()-9, TmpStr.end()); // Remove $lazy_ptr
+
+ TmpStr += "$stub$tmp";
+ AnonSymbol = Ctx.GetOrCreateSymbol(TmpStr.str());
}
};
@@ -224,15 +241,17 @@ namespace {
if (GV->isDeclaration() || GV->isWeakForLinker()) {
// Dynamically-resolved functions need a stub for the function.
FnStubInfo &FnInfo = FnStubs[Mang->getMangledName(GV)];
- FnInfo.Init(GV, Mang);
- O << FnInfo.Stub;
+ FnInfo.Init(GV, Mang, OutContext);
+ FnInfo.Stub->print(O, MAI);
return;
}
}
if (MO.getType() == MachineOperand::MO_ExternalSymbol) {
- FnStubInfo &FnInfo =FnStubs[Mang->makeNameProper(MO.getSymbolName())];
- FnInfo.Init(MO.getSymbolName(), Mang);
- O << FnInfo.Stub;
+ SmallString<128> MangledName;
+ Mang->getNameWithPrefix(MangledName, MO.getSymbolName());
+ FnStubInfo &FnInfo = FnStubs[MangledName.str()];
+ FnInfo.Init(MO.getSymbolName(), Mang, OutContext);
+ FnInfo.Stub->print(O, MAI);
return;
}
}
@@ -550,50 +569,49 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
processDebugLoc(MI, true);
// Check for slwi/srwi mnemonics.
+ bool useSubstituteMnemonic = false;
if (MI->getOpcode() == PPC::RLWINM) {
- bool FoundMnemonic = false;
unsigned char SH = MI->getOperand(2).getImm();
unsigned char MB = MI->getOperand(3).getImm();
unsigned char ME = MI->getOperand(4).getImm();
if (SH <= 31 && MB == 0 && ME == (31-SH)) {
- O << "\tslwi "; FoundMnemonic = true;
+ O << "\tslwi "; useSubstituteMnemonic = true;
}
if (SH <= 31 && MB == (32-SH) && ME == 31) {
- O << "\tsrwi "; FoundMnemonic = true;
+ O << "\tsrwi "; useSubstituteMnemonic = true;
SH = 32-SH;
}
- if (FoundMnemonic) {
+ if (useSubstituteMnemonic) {
printOperand(MI, 0);
O << ", ";
printOperand(MI, 1);
- O << ", " << (unsigned int)SH << '\n';
- return;
+ O << ", " << (unsigned int)SH;
}
} else if (MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) {
if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
+ useSubstituteMnemonic = true;
O << "\tmr ";
printOperand(MI, 0);
O << ", ";
printOperand(MI, 1);
- O << '\n';
- return;
}
} else if (MI->getOpcode() == PPC::RLDICR) {
unsigned char SH = MI->getOperand(2).getImm();
unsigned char ME = MI->getOperand(3).getImm();
// rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
if (63-SH == ME) {
+ useSubstituteMnemonic = true;
O << "\tsldi ";
printOperand(MI, 0);
O << ", ";
printOperand(MI, 1);
- O << ", " << (unsigned int)SH << '\n';
- return;
+ O << ", " << (unsigned int)SH;
}
}
- printInstruction(MI);
-
+ if (!useSubstituteMnemonic)
+ printInstruction(MI);
+
if (VerboseAsm)
EmitComments(*MI);
O << '\n';
@@ -1038,27 +1056,38 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
MCSectionMachO::S_SYMBOL_STUBS |
MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
32, SectionKind::getText());
- for (StringMap<FnStubInfo>::iterator I = FnStubs.begin(), E = FnStubs.end();
+ for (StringMap<FnStubInfo>::iterator I = FnStubs.begin(), E = FnStubs.end();
I != E; ++I) {
OutStreamer.SwitchSection(StubSection);
EmitAlignment(4);
const FnStubInfo &Info = I->second;
- O << Info.Stub << ":\n";
+ Info.Stub->print(O, MAI);
+ O << ":\n";
O << "\t.indirect_symbol " << I->getKeyData() << '\n';
O << "\tmflr r0\n";
- O << "\tbcl 20,31," << Info.AnonSymbol << '\n';
- O << Info.AnonSymbol << ":\n";
+ O << "\tbcl 20,31,";
+ Info.AnonSymbol->print(O, MAI);
+ O << '\n';
+ Info.AnonSymbol->print(O, MAI);
+ O << ":\n";
O << "\tmflr r11\n";
- O << "\taddis r11,r11,ha16(" << Info.LazyPtr << "-" << Info.AnonSymbol;
+ O << "\taddis r11,r11,ha16(";
+ Info.LazyPtr->print(O, MAI);
+ O << '-';
+ Info.AnonSymbol->print(O, MAI);
O << ")\n";
O << "\tmtlr r0\n";
O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16(";
- O << Info.LazyPtr << "-" << Info.AnonSymbol << ")(r11)\n";
+ Info.LazyPtr->print(O, MAI);
+ O << '-';
+ Info.AnonSymbol->print(O, MAI);
+ O << ")(r11)\n";
O << "\tmtctr r12\n";
O << "\tbctr\n";
OutStreamer.SwitchSection(LSPSection);
- O << Info.LazyPtr << ":\n";
+ Info.LazyPtr->print(O, MAI);
+ O << ":\n";
O << "\t.indirect_symbol " << I->getKeyData() << '\n';
O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n";
}
@@ -1074,15 +1103,20 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
OutStreamer.SwitchSection(StubSection);
EmitAlignment(4);
const FnStubInfo &Info = I->second;
- O << Info.Stub << ":\n";
+ Info.Stub->print(O, MAI);
+ O << ":\n";
O << "\t.indirect_symbol " << I->getKeyData() << '\n';
- O << "\tlis r11,ha16(" << Info.LazyPtr << ")\n";
+ O << "\tlis r11,ha16(";
+ Info.LazyPtr->print(O, MAI);
+ O << ")\n";
O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16(";
- O << Info.LazyPtr << ")(r11)\n";
+ Info.LazyPtr->print(O, MAI);
+ O << ")(r11)\n";
O << "\tmtctr r12\n";
O << "\tbctr\n";
OutStreamer.SwitchSection(LSPSection);
- O << Info.LazyPtr << ":\n";
+ Info.LazyPtr->print(O, MAI);
+ O << ":\n";
O << "\t.indirect_symbol " << I->getKeyData() << '\n';
O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n";
}
OpenPOWER on IntegriCloud