diff options
Diffstat (limited to 'lib/Target/PowerPC')
-rw-r--r-- | lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp | 122 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 36 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCInstrInfo.td | 8 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCJITInfo.cpp | 2 | ||||
-rw-r--r-- | lib/Target/PowerPC/PPCMCAsmInfo.cpp | 1 | ||||
-rw-r--r-- | lib/Target/PowerPC/README.txt | 33 |
6 files changed, 133 insertions, 69 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"; } diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index e7334b5..32c1879 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 8fe151a..842f8ee 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 be6e51e..daf4ec6 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 c87879b..ee6deb5 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 f5e50fc..060d6a5 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. |