aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-01-15 15:37:28 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-01-15 15:37:28 +0000
commit829000e035f46f2a227a5466e4e427a2f3cc00a9 (patch)
treebe5a687969f682edded4aa6f13594ffd9aa9030e /lib/Target/PowerPC
parent1e7804dbd25b8dbf534c850355d70ad215206f4b (diff)
downloadsrc-829000e035f46f2a227a5466e4e427a2f3cc00a9.tar.gz
src-829000e035f46f2a227a5466e4e427a2f3cc00a9.zip
Update LLVM to 93512.
Notes
Notes: svn path=/vendor/llvm/dist/; revision=202375
Diffstat (limited to 'lib/Target/PowerPC')
-rw-r--r--lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp122
-rw-r--r--lib/Target/PowerPC/PPCISelDAGToDAG.cpp36
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.td8
-rw-r--r--lib/Target/PowerPC/PPCJITInfo.cpp2
-rw-r--r--lib/Target/PowerPC/PPCMCAsmInfo.cpp1
-rw-r--r--lib/Target/PowerPC/README.txt33
6 files changed, 133 insertions, 69 deletions
diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
index aae4607f43dd..d505d381306d 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";
}
diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
index e7334b54d473..32c1879cf713 100644
--- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
+++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
@@ -95,7 +95,7 @@ namespace {
// Select - Convert the specified operand from a target-independent to a
// target-specific node if it hasn't already been changed.
- SDNode *Select(SDValue Op);
+ SDNode *Select(SDNode *N);
SDNode *SelectBitfieldInsert(SDNode *N);
@@ -105,7 +105,7 @@ namespace {
/// SelectAddrImm - Returns true if the address N can be represented by
/// a base register plus a signed 16-bit displacement [r+imm].
- bool SelectAddrImm(SDValue Op, SDValue N, SDValue &Disp,
+ bool SelectAddrImm(SDNode *Op, SDValue N, SDValue &Disp,
SDValue &Base) {
return PPCLowering.SelectAddressRegImm(N, Disp, Base, *CurDAG);
}
@@ -113,7 +113,7 @@ namespace {
/// SelectAddrImmOffs - Return true if the operand is valid for a preinc
/// immediate field. Because preinc imms have already been validated, just
/// accept it.
- bool SelectAddrImmOffs(SDValue Op, SDValue N, SDValue &Out) const {
+ bool SelectAddrImmOffs(SDNode *Op, SDValue N, SDValue &Out) const {
Out = N;
return true;
}
@@ -121,14 +121,14 @@ namespace {
/// SelectAddrIdx - Given the specified addressed, check to see if it can be
/// represented as an indexed [r+r] operation. Returns false if it can
/// be represented by [r+imm], which are preferred.
- bool SelectAddrIdx(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectAddrIdx(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Index) {
return PPCLowering.SelectAddressRegReg(N, Base, Index, *CurDAG);
}
/// SelectAddrIdxOnly - Given the specified addressed, force it to be
/// represented as an indexed [r+r] operation.
- bool SelectAddrIdxOnly(SDValue Op, SDValue N, SDValue &Base,
+ bool SelectAddrIdxOnly(SDNode *Op, SDValue N, SDValue &Base,
SDValue &Index) {
return PPCLowering.SelectAddressRegRegOnly(N, Base, Index, *CurDAG);
}
@@ -136,7 +136,7 @@ namespace {
/// SelectAddrImmShift - Returns true if the address N can be represented by
/// a base register plus a signed 14-bit displacement [r+imm*4]. Suitable
/// for use by STD and friends.
- bool SelectAddrImmShift(SDValue Op, SDValue N, SDValue &Disp,
+ bool SelectAddrImmShift(SDNode *Op, SDValue N, SDValue &Disp,
SDValue &Base) {
return PPCLowering.SelectAddressRegImmShift(N, Disp, Base, *CurDAG);
}
@@ -180,7 +180,7 @@ namespace {
#include "PPCGenDAGISel.inc"
private:
- SDNode *SelectSETCC(SDValue Op);
+ SDNode *SelectSETCC(SDNode *N);
};
}
@@ -635,8 +635,7 @@ static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool &Invert, int &Other) {
return 0;
}
-SDNode *PPCDAGToDAGISel::SelectSETCC(SDValue Op) {
- SDNode *N = Op.getNode();
+SDNode *PPCDAGToDAGISel::SelectSETCC(SDNode *N) {
DebugLoc dl = N->getDebugLoc();
unsigned Imm;
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
@@ -756,9 +755,8 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDValue Op) {
// Select - Convert the specified operand from a target-independent to a
// target-specific node if it hasn't already been changed.
-SDNode *PPCDAGToDAGISel::Select(SDValue Op) {
- SDNode *N = Op.getNode();
- DebugLoc dl = Op.getDebugLoc();
+SDNode *PPCDAGToDAGISel::Select(SDNode *N) {
+ DebugLoc dl = N->getDebugLoc();
if (N->isMachineOpcode())
return NULL; // Already selected.
@@ -841,18 +839,18 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) {
}
case ISD::SETCC:
- return SelectSETCC(Op);
+ return SelectSETCC(N);
case PPCISD::GlobalBaseReg:
return getGlobalBaseReg();
case ISD::FrameIndex: {
int FI = cast<FrameIndexSDNode>(N)->getIndex();
- SDValue TFI = CurDAG->getTargetFrameIndex(FI, Op.getValueType());
- unsigned Opc = Op.getValueType() == MVT::i32 ? PPC::ADDI : PPC::ADDI8;
+ SDValue TFI = CurDAG->getTargetFrameIndex(FI, N->getValueType(0));
+ unsigned Opc = N->getValueType(0) == MVT::i32 ? PPC::ADDI : PPC::ADDI8;
if (N->hasOneUse())
- return CurDAG->SelectNodeTo(N, Opc, Op.getValueType(), TFI,
+ return CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), TFI,
getSmallIPtrImm(0));
- return CurDAG->getMachineNode(Opc, dl, Op.getValueType(), TFI,
+ return CurDAG->getMachineNode(Opc, dl, N->getValueType(0), TFI,
getSmallIPtrImm(0));
}
@@ -899,7 +897,7 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) {
case ISD::LOAD: {
// Handle preincrement loads.
- LoadSDNode *LD = cast<LoadSDNode>(Op);
+ LoadSDNode *LD = cast<LoadSDNode>(N);
EVT LoadedVT = LD->getMemoryVT();
// Normal loads are handled by code generated from the .td file.
@@ -1092,7 +1090,7 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) {
}
}
- return SelectCode(Op);
+ return SelectCode(N);
}
diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td
index 8fe151ad229a..842f8ee08977 100644
--- a/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/lib/Target/PowerPC/PPCInstrInfo.td
@@ -430,9 +430,7 @@ let isCall = 1, PPC970_Unit = 7,
F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13,
V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19,
LR,CTR,
- CR0,CR1,CR5,CR6,CR7,
- CR0LT,CR0GT,CR0EQ,CR0UN,CR1LT,CR1GT,CR1EQ,CR1UN,CR5LT,CR5GT,CR5EQ,
- CR5UN,CR6LT,CR6GT,CR6EQ,CR6UN,CR7LT,CR7GT,CR7EQ,CR7UN,CARRY] in {
+ CR0,CR1,CR5,CR6,CR7,CARRY] in {
// Convenient aliases for call instructions
let Uses = [RM] in {
def BL_Darwin : IForm<18, 0, 1,
@@ -457,9 +455,7 @@ let isCall = 1, PPC970_Unit = 7,
F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13,
V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19,
LR,CTR,
- CR0,CR1,CR5,CR6,CR7,
- CR0LT,CR0GT,CR0EQ,CR0UN,CR1LT,CR1GT,CR1EQ,CR1UN,CR5LT,CR5GT,CR5EQ,
- CR5UN,CR6LT,CR6GT,CR6EQ,CR6UN,CR7LT,CR7GT,CR7EQ,CR7UN,CARRY] in {
+ CR0,CR1,CR5,CR6,CR7,CARRY] in {
// Convenient aliases for call instructions
let Uses = [RM] in {
def BL_SVR4 : IForm<18, 0, 1,
diff --git a/lib/Target/PowerPC/PPCJITInfo.cpp b/lib/Target/PowerPC/PPCJITInfo.cpp
index be6e51e0ddb4..daf4ec6d012a 100644
--- a/lib/Target/PowerPC/PPCJITInfo.cpp
+++ b/lib/Target/PowerPC/PPCJITInfo.cpp
@@ -308,6 +308,7 @@ extern "C" void *PPCCompilationCallbackC(unsigned *StubCallAddrPlus4,
// Rewrite the stub with an unconditional branch to the target, for any users
// who took the address of the stub.
EmitBranchToAt((intptr_t)StubCallAddr, (intptr_t)Target, false, is64Bit);
+ sys::Memory::InvalidateInstructionCache(StubCallAddr, 7*4);
// Put the address of the target function to call and the address to return to
// after calling the target function in a place that is easy to get on the
@@ -441,4 +442,5 @@ void PPCJITInfo::relocate(void *Function, MachineRelocation *MR,
void PPCJITInfo::replaceMachineCodeForFunction(void *Old, void *New) {
EmitBranchToAt((intptr_t)Old, (intptr_t)New, false, is64Bit);
+ sys::Memory::InvalidateInstructionCache(Old, 7*4);
}
diff --git a/lib/Target/PowerPC/PPCMCAsmInfo.cpp b/lib/Target/PowerPC/PPCMCAsmInfo.cpp
index c87879b2a332..ee6deb5c5090 100644
--- a/lib/Target/PowerPC/PPCMCAsmInfo.cpp
+++ b/lib/Target/PowerPC/PPCMCAsmInfo.cpp
@@ -22,6 +22,7 @@ PPCMCAsmInfoDarwin::PPCMCAsmInfoDarwin(bool is64Bit) {
if (!is64Bit)
Data64bitsDirective = 0; // We can't emit a 64-bit unit in PPC32 mode.
AssemblerDialect = 1; // New-Style mnemonics.
+ SupportsDebugInformation= true; // Debug information.
}
PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) {
diff --git a/lib/Target/PowerPC/README.txt b/lib/Target/PowerPC/README.txt
index f5e50fc808a8..060d6a5c5c2b 100644
--- a/lib/Target/PowerPC/README.txt
+++ b/lib/Target/PowerPC/README.txt
@@ -7,6 +7,39 @@ TODO:
===-------------------------------------------------------------------------===
+On PPC64, this:
+
+long f2 (long x) { return 0xfffffff000000000UL; }
+long f3 (long x) { return 0x1ffffffffUL; }
+
+could compile into:
+
+_f2:
+ li r3,-1
+ rldicr r3,r3,0,27
+ blr
+_f3:
+ li r3,-1
+ rldicl r3,r3,0,31
+ blr
+
+we produce:
+
+_f2:
+ lis r2, 4095
+ ori r2, r2, 65535
+ sldi r3, r2, 36
+ blr
+_f3:
+ li r2, 1
+ sldi r2, r2, 32
+ oris r2, r2, 65535
+ ori r3, r2, 65535
+ blr
+
+
+===-------------------------------------------------------------------------===
+
Support 'update' load/store instructions. These are cracked on the G5, but are
still a codesize win.