diff options
Diffstat (limited to 'lib/Target/PowerPC')
31 files changed, 1620 insertions, 1357 deletions
diff --git a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp index 7f1673c..a0fba86 100644 --- a/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp @@ -24,7 +24,6 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" -#include "llvm/MDNode.h" #include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/DwarfWriter.h" @@ -32,16 +31,22 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCSectionMachO.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Target/TargetLoweringObjectFile.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/Target/TargetRegistry.h" #include "llvm/Support/Mangler.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetOptions.h" +#include "llvm/Support/FormattedStream.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSet.h" @@ -52,13 +57,40 @@ STATISTIC(EmittedInsts, "Number of machine instrs printed"); namespace { class VISIBILITY_HIDDEN PPCAsmPrinter : public AsmPrinter { protected: - StringSet<> FnStubs, GVStubs, HiddenGVStubs; + struct FnStubInfo { + std::string Stub, LazyPtr, AnonSymbol; + + 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); + AnonSymbol = Mang->getMangledName(GV, "$stub$tmp", true); + } + + 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); + } + }; + + StringMap<FnStubInfo> FnStubs; + StringMap<std::string> GVStubs, HiddenGVStubs, TOC; const PPCSubtarget &Subtarget; + uint64_t LabelID; public: - explicit PPCAsmPrinter(raw_ostream &O, TargetMachine &TM, - const TargetAsmInfo *T, bool V) + explicit PPCAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM, + const MCAsmInfo *T, bool V) : AsmPrinter(O, TM, T, V), - Subtarget(TM.getSubtarget<PPCSubtarget>()) {} + Subtarget(TM.getSubtarget<PPCSubtarget>()), LabelID(0) {} virtual const char *getPassName() const { return "PowerPC Assembly Printer"; @@ -70,7 +102,7 @@ namespace { unsigned enumRegToMachineReg(unsigned enumReg) { switch (enumReg) { - default: assert(0 && "Unhandled register!"); break; + default: llvm_unreachable("Unhandled register!"); case PPC::CR0: return 0; case PPC::CR1: return 1; case PPC::CR2: return 2; @@ -80,14 +112,16 @@ namespace { case PPC::CR6: return 6; case PPC::CR7: return 7; } - abort(); + llvm_unreachable(0); } /// printInstruction - This method is automatically generated by tablegen /// from the instruction set description. This method returns true if the /// machine instruction was sufficiently described to print it, otherwise it /// returns false. - bool printInstruction(const MachineInstr *MI); + void printInstruction(const MachineInstr *MI); + static const char *getRegisterName(unsigned RegNo); + void printMachineInstruction(const MachineInstr *MI); void printOp(const MachineOperand &MO); @@ -117,7 +151,7 @@ namespace { return; } - const char *RegName = TM.getRegisterInfo()->get(RegNo).AsmName; + const char *RegName = getRegisterName(RegNo); // Linux assembler (Others?) does not take register mnemonics. // FIXME - What about special registers used in mfspr/mtspr? if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName); @@ -190,16 +224,16 @@ namespace { GlobalValue *GV = MO.getGlobal(); if (GV->isDeclaration() || GV->isWeakForLinker()) { // Dynamically-resolved functions need a stub for the function. - std::string Name = Mang->getValueName(GV); - FnStubs.insert(Name); - printSuffixedName(Name, "$stub"); + FnStubInfo &FnInfo = FnStubs[Mang->getMangledName(GV)]; + FnInfo.Init(GV, Mang); + O << FnInfo.Stub; return; } } if (MO.getType() == MachineOperand::MO_ExternalSymbol) { - std::string Name(TAI->getGlobalPrefix()); Name += MO.getSymbolName(); - FnStubs.insert(Name); - printSuffixedName(Name, "$stub"); + FnStubInfo &FnInfo =FnStubs[Mang->makeNameProper(MO.getSymbolName())]; + FnInfo.Init(MO.getSymbolName(), Mang); + O << FnInfo.Stub; return; } } @@ -281,20 +315,39 @@ namespace { printOperand(MI, OpNo+1); } + void printTOCEntryLabel(const MachineInstr *MI, unsigned OpNo) { + const MachineOperand &MO = MI->getOperand(OpNo); + + assert(MO.getType() == MachineOperand::MO_GlobalAddress); + + GlobalValue *GV = MO.getGlobal(); + + std::string Name = Mang->getMangledName(GV); + + // Map symbol -> label of TOC entry. + if (TOC.count(Name) == 0) { + std::string Label; + Label += MAI->getPrivateGlobalPrefix(); + Label += "C"; + Label += utostr(LabelID++); + + TOC[Name] = Label; + } + + O << TOC[Name] << "@toc"; + } + void printPredicateOperand(const MachineInstr *MI, unsigned OpNo, const char *Modifier); virtual bool runOnMachineFunction(MachineFunction &F) = 0; - virtual bool doFinalization(Module &M) = 0; - - virtual void EmitExternalGlobal(const GlobalVariable *GV); }; /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux class VISIBILITY_HIDDEN PPCLinuxAsmPrinter : public PPCAsmPrinter { public: - explicit PPCLinuxAsmPrinter(raw_ostream &O, PPCTargetMachine &TM, - const TargetAsmInfo *T, bool V) + explicit PPCLinuxAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM, + const MCAsmInfo *T, bool V) : PPCAsmPrinter(O, TM, T, V){} virtual const char *getPassName() const { @@ -311,16 +364,16 @@ namespace { PPCAsmPrinter::getAnalysisUsage(AU); } - void printModuleLevelGV(const GlobalVariable* GVar); + void PrintGlobalVariable(const GlobalVariable *GVar); }; /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac /// OS X class VISIBILITY_HIDDEN PPCDarwinAsmPrinter : public PPCAsmPrinter { - raw_ostream &OS; + formatted_raw_ostream &OS; public: - explicit PPCDarwinAsmPrinter(raw_ostream &O, PPCTargetMachine &TM, - const TargetAsmInfo *T, bool V) + explicit PPCDarwinAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM, + const MCAsmInfo *T, bool V) : PPCAsmPrinter(O, TM, T, V), OS(O) {} virtual const char *getPassName() const { @@ -328,8 +381,8 @@ namespace { } bool runOnMachineFunction(MachineFunction &F); - bool doInitialization(Module &M); bool doFinalization(Module &M); + void EmitStartOfAsmFile(Module &M); void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); @@ -338,7 +391,7 @@ namespace { PPCAsmPrinter::getAnalysisUsage(AU); } - void printModuleLevelGV(const GlobalVariable* GVar); + void PrintGlobalVariable(const GlobalVariable *GVar); }; } // end of anonymous namespace @@ -348,54 +401,52 @@ namespace { void PPCAsmPrinter::printOp(const MachineOperand &MO) { switch (MO.getType()) { case MachineOperand::MO_Immediate: - cerr << "printOp() does not handle immediate values\n"; - abort(); - return; + llvm_unreachable("printOp() does not handle immediate values"); case MachineOperand::MO_MachineBasicBlock: - printBasicBlockLabel(MO.getMBB()); + GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI); return; case MachineOperand::MO_JumpTableIndex: - O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() + O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << MO.getIndex(); // FIXME: PIC relocation model return; case MachineOperand::MO_ConstantPoolIndex: - O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() + O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' << MO.getIndex(); return; - case MachineOperand::MO_ExternalSymbol: + case MachineOperand::MO_ExternalSymbol: { // Computing the address of an external symbol, not calling it. + std::string Name(MAI->getGlobalPrefix()); + Name += MO.getSymbolName(); + if (TM.getRelocationModel() != Reloc::Static) { - std::string Name(TAI->getGlobalPrefix()); Name += MO.getSymbolName(); - GVStubs.insert(Name); - printSuffixedName(Name, "$non_lazy_ptr"); - return; + GVStubs[Name] = Name+"$non_lazy_ptr"; + Name += "$non_lazy_ptr"; } - O << TAI->getGlobalPrefix() << MO.getSymbolName(); + O << Name; return; + } case MachineOperand::MO_GlobalAddress: { // Computing the address of a global symbol, not calling it. GlobalValue *GV = MO.getGlobal(); - std::string Name = Mang->getValueName(GV); + std::string Name; // External or weakly linked global variables need non-lazily-resolved stubs - if (TM.getRelocationModel() != Reloc::Static) { - if (GV->isDeclaration() || GV->isWeakForLinker()) { - if (GV->hasHiddenVisibility()) { - if (GV->isDeclaration() || GV->hasCommonLinkage() || - GV->hasAvailableExternallyLinkage()) { - HiddenGVStubs.insert(Name); - printSuffixedName(Name, "$non_lazy_ptr"); - } else { - O << Name; - } - } else { - GVStubs.insert(Name); - printSuffixedName(Name, "$non_lazy_ptr"); - } - return; + if (TM.getRelocationModel() != Reloc::Static && + (GV->isDeclaration() || GV->isWeakForLinker())) { + if (!GV->hasHiddenVisibility()) { + Name = Mang->getMangledName(GV, "$non_lazy_ptr", true); + GVStubs[Mang->getMangledName(GV)] = Name; + } else if (GV->isDeclaration() || GV->hasCommonLinkage() || + GV->hasAvailableExternallyLinkage()) { + Name = Mang->getMangledName(GV, "$non_lazy_ptr", true); + HiddenGVStubs[Mang->getMangledName(GV)] = Name; + } else { + Name = Mang->getMangledName(GV); } + } else { + Name = Mang->getMangledName(GV); } O << Name; @@ -409,22 +460,6 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) { } } -/// EmitExternalGlobal - In this case we need to use the indirect symbol. -/// -void PPCAsmPrinter::EmitExternalGlobal(const GlobalVariable *GV) { - std::string Name; - getGlobalLinkName(GV, Name); - if (TM.getRelocationModel() != Reloc::Static) { - if (GV->hasHiddenVisibility()) - HiddenGVStubs.insert(Name); - else - GVStubs.insert(Name); - printSuffixedName(Name, "$non_lazy_ptr"); - return; - } - O << Name; -} - /// PrintAsmOperand - Print out an operand for an inline asm expression. /// bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, @@ -461,15 +496,19 @@ bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, return false; } +// At the moment, all inline asm memory operands are a single register. +// In any case, the output of this routine should always be just one +// assembler operand. + bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode) { if (ExtraCode && ExtraCode[0]) return true; // Unknown modifier. - if (MI->getOperand(OpNo).isReg()) - printMemRegReg(MI, OpNo); - else - printMemRegImm(MI, OpNo); + assert (MI->getOperand(OpNo).isReg()); + O << "0("; + printOperand(MI, OpNo); + O << ")"; return false; } @@ -505,6 +544,8 @@ void PPCAsmPrinter::printPredicateOperand(const MachineInstr *MI, unsigned OpNo, /// void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) { ++EmittedInsts; + + processDebugLoc(MI, true); // Check for slwi/srwi mnemonics. if (MI->getOpcode() == PPC::RLWINM) { @@ -549,12 +590,13 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) { } } - if (printInstruction(MI)) - return; // Printer was automatically generated + printInstruction(MI); + + if (VerboseAsm && !MI->getDebugLoc().isUnknown()) + EmitComments(*MI); + O << '\n'; - assert(0 && "Unhandled instruction in asm writer!"); - abort(); - return; + processDebugLoc(MI, false); } /// runOnMachineFunction - This uses the printMachineInstruction() @@ -571,10 +613,10 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) { // Print out labels for the function. const Function *F = MF.getFunction(); - SwitchToSection(TAI->SectionForGlobal(F)); + OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM)); switch (F->getLinkage()) { - default: assert(0 && "Unknown linkage type!"); + default: llvm_unreachable("Unknown linkage type!"); case Function::PrivateLinkage: case Function::InternalLinkage: // Symbols default to internal. break; @@ -582,6 +624,7 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) { O << "\t.global\t" << CurrentFnName << '\n' << "\t.type\t" << CurrentFnName << ", @function\n"; break; + case Function::LinkerPrivateLinkage: case Function::WeakAnyLinkage: case Function::WeakODRLinkage: case Function::LinkOnceAnyLinkage: @@ -594,7 +637,19 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) { printVisibility(CurrentFnName, F->getVisibility()); EmitAlignment(MF.getAlignment(), F); - O << CurrentFnName << ":\n"; + + if (Subtarget.isPPC64()) { + // Emit an official procedure descriptor. + // FIXME 64-bit SVR4: Use MCSection here? + O << "\t.section\t\".opd\",\"aw\"\n"; + O << "\t.align 3\n"; + O << CurrentFnName << ":\n"; + O << "\t.quad .L." << CurrentFnName << ",.TOC.@tocbase\n"; + O << "\t.previous\n"; + O << ".L." << CurrentFnName << ":\n"; + } else { + O << CurrentFnName << ":\n"; + } // Emit pre-function debug information. DW->BeginFunction(&MF); @@ -604,8 +659,7 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) { I != E; ++I) { // Print a label for the basic block. if (I != MF.begin()) { - printBasicBlockLabel(I, true, true); - O << '\n'; + EmitBasicBlockStart(I); } for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); II != E; ++II) { @@ -619,27 +673,16 @@ bool PPCLinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) { // Print out jump tables referenced by the function. EmitJumpTableInfo(MF.getJumpTableInfo(), MF); - SwitchToSection(TAI->SectionForGlobal(F)); + OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM)); // Emit post-function debug information. DW->EndFunction(&MF); - O.flush(); - // We didn't modify anything. return false; } -/// 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) { - for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen(); - Name != E; ++Name) - if (isprint(*Name)) - OS << *Name; -} - -void PPCLinuxAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { +void PPCLinuxAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) { const TargetData *TD = TM.getTargetData(); if (!GVar->hasInitializer()) @@ -649,18 +692,17 @@ void PPCLinuxAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { if (EmitSpecialLLVMGlobal(GVar)) return; - std::string name = Mang->getValueName(GVar); + std::string name = Mang->getMangledName(GVar); printVisibility(name, GVar->getVisibility()); Constant *C = GVar->getInitializer(); - if (isa<MDNode>(C) || isa<MDString>(C)) - return; const Type *Type = C->getType(); unsigned Size = TD->getTypeAllocSize(Type); unsigned Align = TD->getPreferredAlignmentLog(GVar); - SwitchToSection(TAI->SectionForGlobal(GVar)); + OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GVar, Mang, + TM)); if (C->isNullValue() && /* FIXME: Verify correct */ !GVar->hasSection() && @@ -674,13 +716,13 @@ void PPCLinuxAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { O << name << ":\n"; O << "\t.zero " << Size << '\n'; } else if (GVar->hasLocalLinkage()) { - O << TAI->getLCOMMDirective() << name << ',' << Size; + O << MAI->getLCOMMDirective() << name << ',' << Size; } else { O << ".comm " << name << ',' << Size; } if (VerboseAsm) { - O << "\t\t" << TAI->getCommentString() << " '"; - PrintUnmangledNameSafely(GVar, O); + O << "\t\t" << MAI->getCommentString() << " '"; + WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); O << "'"; } O << '\n'; @@ -693,6 +735,7 @@ void PPCLinuxAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { case GlobalValue::WeakAnyLinkage: case GlobalValue::WeakODRLinkage: case GlobalValue::CommonLinkage: + case GlobalValue::LinkerPrivateLinkage: O << "\t.global " << name << '\n' << "\t.type " << name << ", @object\n" << "\t.weak " << name << '\n'; @@ -709,15 +752,14 @@ void PPCLinuxAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { case GlobalValue::PrivateLinkage: break; default: - cerr << "Unknown linkage type!"; - abort(); + llvm_unreachable("Unknown linkage type!"); } EmitAlignment(Align, GVar); O << name << ":"; if (VerboseAsm) { - O << "\t\t\t\t" << TAI->getCommentString() << " '"; - PrintUnmangledNameSafely(GVar, O); + O << "\t\t\t\t" << MAI->getCommentString() << " '"; + WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); O << "'"; } O << '\n'; @@ -727,10 +769,20 @@ void PPCLinuxAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { } bool PPCLinuxAsmPrinter::doFinalization(Module &M) { - // Print out module-level global variables here. - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) - printModuleLevelGV(I); + const TargetData *TD = TM.getTargetData(); + + bool isPPC64 = TD->getPointerSizeInBits() == 64; + + if (isPPC64 && !TOC.empty()) { + // FIXME 64-bit SVR4: Use MCSection here? + O << "\t.section\t\".toc\",\"aw\"\n"; + + for (StringMap<std::string>::iterator I = TOC.begin(), E = TOC.end(); + I != E; ++I) { + O << I->second << ":\n"; + O << "\t.tc " << I->getKeyData() << "[TC]," << I->getKeyData() << '\n'; + } + } return AsmPrinter::doFinalization(M); } @@ -749,10 +801,10 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) { // Print out labels for the function. const Function *F = MF.getFunction(); - SwitchToSection(TAI->SectionForGlobal(F)); + OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM)); switch (F->getLinkage()) { - default: assert(0 && "Unknown linkage type!"); + default: llvm_unreachable("Unknown linkage type!"); case Function::PrivateLinkage: case Function::InternalLinkage: // Symbols default to internal. break; @@ -763,6 +815,7 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) { case Function::WeakODRLinkage: case Function::LinkOnceAnyLinkage: case Function::LinkOnceODRLinkage: + case Function::LinkerPrivateLinkage: O << "\t.globl\t" << CurrentFnName << '\n'; O << "\t.weak_definition\t" << CurrentFnName << '\n'; break; @@ -789,8 +842,7 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) { I != E; ++I) { // Print a label for the basic block. if (I != MF.begin()) { - printBasicBlockLabel(I, true, true, VerboseAsm); - O << '\n'; + EmitBasicBlockStart(I); } for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); II != IE; ++II) { @@ -810,7 +862,7 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) { } -bool PPCDarwinAsmPrinter::doInitialization(Module &M) { +void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) { static const char *const CPUDirectives[] = { "", "ppc", @@ -833,26 +885,28 @@ bool PPCDarwinAsmPrinter::doInitialization(Module &M) { assert(Directive <= PPC::DIR_64 && "Directive out of range."); O << "\t.machine " << CPUDirectives[Directive] << '\n'; - bool Result = AsmPrinter::doInitialization(M); - assert(MMI); - // Prime text sections so they are adjacent. This reduces the likelihood a // large data or debug section causes a branch to exceed 16M limit. - SwitchToTextSection("\t.section __TEXT,__textcoal_nt,coalesced," - "pure_instructions"); + TargetLoweringObjectFileMachO &TLOFMacho = + static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering()); + OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); if (TM.getRelocationModel() == Reloc::PIC_) { - SwitchToTextSection("\t.section __TEXT,__picsymbolstub1,symbol_stubs," - "pure_instructions,32"); + OutStreamer.SwitchSection( + TLOFMacho.getMachOSection("__TEXT", "__picsymbolstub1", + MCSectionMachO::S_SYMBOL_STUBS | + MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, + 32, SectionKind::getText())); } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { - SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs," - "pure_instructions,16"); + OutStreamer.SwitchSection( + TLOFMacho.getMachOSection("__TEXT","__symbol_stub1", + MCSectionMachO::S_SYMBOL_STUBS | + MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, + 16, SectionKind::getText())); } - SwitchToSection(TAI->getTextSection()); - - return Result; + OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); } -void PPCDarwinAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { +void PPCDarwinAsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) { const TargetData *TD = TM.getTargetData(); if (!GVar->hasInitializer()) @@ -869,8 +923,7 @@ void PPCDarwinAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { return; } - std::string name = Mang->getValueName(GVar); - + std::string name = Mang->getMangledName(GVar); printVisibility(name, GVar->getVisibility()); Constant *C = GVar->getInitializer(); @@ -878,13 +931,17 @@ void PPCDarwinAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { unsigned Size = TD->getTypeAllocSize(Type); unsigned Align = TD->getPreferredAlignmentLog(GVar); - SwitchToSection(TAI->SectionForGlobal(GVar)); + const MCSection *TheSection = + getObjFileLowering().SectionForGlobal(GVar, Mang, TM); + OutStreamer.SwitchSection(TheSection); + /// FIXME: Drive this off the section! if (C->isNullValue() && /* FIXME: Verify correct */ !GVar->hasSection() && (GVar->hasLocalLinkage() || GVar->hasExternalLinkage() || GVar->isWeakForLinker()) && - TAI->SectionKindForGlobal(GVar) != SectionKind::RODataMergeStr) { + // Don't put things that should go in the cstring section into "comm". + !TheSection->getKind().isMergeableCString()) { if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. if (GVar->hasExternalLinkage()) { @@ -892,15 +949,15 @@ void PPCDarwinAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { O << "\t.zerofill __DATA, __common, " << name << ", " << Size << ", " << Align; } else if (GVar->hasLocalLinkage()) { - O << TAI->getLCOMMDirective() << name << ',' << Size << ',' << Align; + O << MAI->getLCOMMDirective() << name << ',' << Size << ',' << Align; } else if (!GVar->hasCommonLinkage()) { O << "\t.globl " << name << '\n' - << TAI->getWeakDefDirective() << name << '\n'; + << MAI->getWeakDefDirective() << name << '\n'; EmitAlignment(Align, GVar); O << name << ":"; if (VerboseAsm) { - O << "\t\t\t\t" << TAI->getCommentString() << " "; - PrintUnmangledNameSafely(GVar, O); + O << "\t\t\t\t" << MAI->getCommentString() << " "; + WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); } O << '\n'; EmitGlobalConstant(C); @@ -912,8 +969,8 @@ void PPCDarwinAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { O << ',' << Align; } if (VerboseAsm) { - O << "\t\t" << TAI->getCommentString() << " '"; - PrintUnmangledNameSafely(GVar, O); + O << "\t\t" << MAI->getCommentString() << " '"; + WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); O << "'"; } O << '\n'; @@ -926,6 +983,7 @@ void PPCDarwinAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { case GlobalValue::WeakAnyLinkage: case GlobalValue::WeakODRLinkage: case GlobalValue::CommonLinkage: + case GlobalValue::LinkerPrivateLinkage: O << "\t.globl " << name << '\n' << "\t.weak_definition " << name << '\n'; break; @@ -940,15 +998,14 @@ void PPCDarwinAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { case GlobalValue::PrivateLinkage: break; default: - cerr << "Unknown linkage type!"; - abort(); + llvm_unreachable("Unknown linkage type!"); } EmitAlignment(Align, GVar); O << name << ":"; if (VerboseAsm) { - O << "\t\t\t\t" << TAI->getCommentString() << " '"; - PrintUnmangledNameSafely(GVar, O); + O << "\t\t\t\t" << MAI->getCommentString() << " '"; + WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent()); O << "'"; } O << '\n'; @@ -960,141 +1017,110 @@ void PPCDarwinAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { bool PPCDarwinAsmPrinter::doFinalization(Module &M) { const TargetData *TD = TM.getTargetData(); - // Print out module-level global variables here. - for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) - printModuleLevelGV(I); - bool isPPC64 = TD->getPointerSizeInBits() == 64; + // Darwin/PPC always uses mach-o. + TargetLoweringObjectFileMachO &TLOFMacho = + static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering()); + + + const MCSection *LSPSection = 0; + if (!FnStubs.empty()) // .lazy_symbol_pointer + LSPSection = TLOFMacho.getLazySymbolPointerSection(); + + // Output stubs for dynamically-linked functions - if (TM.getRelocationModel() == Reloc::PIC_) { - for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end(); - i != e; ++i) { - SwitchToTextSection("\t.section __TEXT,__picsymbolstub1,symbol_stubs," - "pure_instructions,32"); + if (TM.getRelocationModel() == Reloc::PIC_ && !FnStubs.empty()) { + const MCSection *StubSection = + TLOFMacho.getMachOSection("__TEXT", "__picsymbolstub1", + MCSectionMachO::S_SYMBOL_STUBS | + MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, + 32, SectionKind::getText()); + for (StringMap<FnStubInfo>::iterator I = FnStubs.begin(), E = FnStubs.end(); + I != E; ++I) { + OutStreamer.SwitchSection(StubSection); EmitAlignment(4); - const char *p = i->getKeyData(); - bool hasQuote = p[0]=='\"'; - printSuffixedName(p, "$stub"); - O << ":\n"; - O << "\t.indirect_symbol " << p << '\n'; + const FnStubInfo &Info = I->second; + O << Info.Stub << ":\n"; + O << "\t.indirect_symbol " << I->getKeyData() << '\n'; O << "\tmflr r0\n"; - O << "\tbcl 20,31,"; - if (hasQuote) - O << "\"L0$" << &p[1]; - else - O << "L0$" << p; - O << '\n'; - if (hasQuote) - O << "\"L0$" << &p[1]; - else - O << "L0$" << p; - O << ":\n"; + O << "\tbcl 20,31," << Info.AnonSymbol << '\n'; + O << Info.AnonSymbol << ":\n"; O << "\tmflr r11\n"; - O << "\taddis r11,r11,ha16("; - printSuffixedName(p, "$lazy_ptr"); - O << "-"; - if (hasQuote) - O << "\"L0$" << &p[1]; - else - O << "L0$" << p; + O << "\taddis r11,r11,ha16(" << Info.LazyPtr << "-" << Info.AnonSymbol; O << ")\n"; O << "\tmtlr r0\n"; - if (isPPC64) - O << "\tldu r12,lo16("; - else - O << "\tlwzu r12,lo16("; - printSuffixedName(p, "$lazy_ptr"); - O << "-"; - if (hasQuote) - O << "\"L0$" << &p[1]; - else - O << "L0$" << p; - O << ")(r11)\n"; + O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16("; + O << Info.LazyPtr << "-" << Info.AnonSymbol << ")(r11)\n"; O << "\tmtctr r12\n"; O << "\tbctr\n"; - SwitchToDataSection(".lazy_symbol_pointer"); - printSuffixedName(p, "$lazy_ptr"); - O << ":\n"; - O << "\t.indirect_symbol " << p << '\n'; - if (isPPC64) - O << "\t.quad dyld_stub_binding_helper\n"; - else - O << "\t.long dyld_stub_binding_helper\n"; + + OutStreamer.SwitchSection(LSPSection); + O << Info.LazyPtr << ":\n"; + O << "\t.indirect_symbol " << I->getKeyData() << '\n'; + O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n"; } - } else { - for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end(); - i != e; ++i) { - SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs," - "pure_instructions,16"); + } else if (!FnStubs.empty()) { + const MCSection *StubSection = + TLOFMacho.getMachOSection("__TEXT","__symbol_stub1", + MCSectionMachO::S_SYMBOL_STUBS | + MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, + 16, SectionKind::getText()); + + for (StringMap<FnStubInfo>::iterator I = FnStubs.begin(), E = FnStubs.end(); + I != E; ++I) { + OutStreamer.SwitchSection(StubSection); EmitAlignment(4); - const char *p = i->getKeyData(); - printSuffixedName(p, "$stub"); - O << ":\n"; - O << "\t.indirect_symbol " << p << '\n'; - O << "\tlis r11,ha16("; - printSuffixedName(p, "$lazy_ptr"); - O << ")\n"; - if (isPPC64) - O << "\tldu r12,lo16("; - else - O << "\tlwzu r12,lo16("; - printSuffixedName(p, "$lazy_ptr"); - O << ")(r11)\n"; + const FnStubInfo &Info = I->second; + O << Info.Stub << ":\n"; + O << "\t.indirect_symbol " << I->getKeyData() << '\n'; + O << "\tlis r11,ha16(" << Info.LazyPtr << ")\n"; + O << (isPPC64 ? "\tldu" : "\tlwzu") << " r12,lo16("; + O << Info.LazyPtr << ")(r11)\n"; O << "\tmtctr r12\n"; O << "\tbctr\n"; - SwitchToDataSection(".lazy_symbol_pointer"); - printSuffixedName(p, "$lazy_ptr"); - O << ":\n"; - O << "\t.indirect_symbol " << p << '\n'; - if (isPPC64) - O << "\t.quad dyld_stub_binding_helper\n"; - else - O << "\t.long dyld_stub_binding_helper\n"; + OutStreamer.SwitchSection(LSPSection); + O << Info.LazyPtr << ":\n"; + O << "\t.indirect_symbol " << I->getKeyData() << '\n'; + O << (isPPC64 ? "\t.quad" : "\t.long") << " dyld_stub_binding_helper\n"; } } O << '\n'; - if (TAI->doesSupportExceptionHandling() && MMI) { + if (MAI->doesSupportExceptionHandling() && MMI) { // Add the (possibly multiple) personalities to the set of global values. // Only referenced functions get into the Personalities list. const std::vector<Function *> &Personalities = MMI->getPersonalities(); for (std::vector<Function *>::const_iterator I = Personalities.begin(), - E = Personalities.end(); I != E; ++I) - if (*I) GVStubs.insert("_" + (*I)->getName()); + E = Personalities.end(); I != E; ++I) { + if (*I) + GVStubs[Mang->getMangledName(*I)] = + Mang->getMangledName(*I, "$non_lazy_ptr", true); + } } - // Output stubs for external and common global variables. + // Output macho stubs for external and common global variables. if (!GVStubs.empty()) { - SwitchToDataSection(".non_lazy_symbol_pointer"); - for (StringSet<>::iterator i = GVStubs.begin(), e = GVStubs.end(); - i != e; ++i) { - std::string p = i->getKeyData(); - printSuffixedName(p, "$non_lazy_ptr"); - O << ":\n"; - O << "\t.indirect_symbol " << p << '\n'; - if (isPPC64) - O << "\t.quad\t0\n"; - else - O << "\t.long\t0\n"; + // Switch with ".non_lazy_symbol_pointer" directive. + OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); + EmitAlignment(isPPC64 ? 3 : 2); + + for (StringMap<std::string>::iterator I = GVStubs.begin(), + E = GVStubs.end(); I != E; ++I) { + O << I->second << ":\n"; + O << "\t.indirect_symbol " << I->getKeyData() << '\n'; + O << (isPPC64 ? "\t.quad\t0\n" : "\t.long\t0\n"); } } if (!HiddenGVStubs.empty()) { - SwitchToSection(TAI->getDataSection()); - for (StringSet<>::iterator i = HiddenGVStubs.begin(), e = HiddenGVStubs.end(); - i != e; ++i) { - std::string p = i->getKeyData(); - EmitAlignment(isPPC64 ? 3 : 2); - printSuffixedName(p, "$non_lazy_ptr"); - O << ":\n"; - if (isPPC64) - O << "\t.quad\t"; - else - O << "\t.long\t"; - O << p << '\n'; + OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); + EmitAlignment(isPPC64 ? 3 : 2); + for (StringMap<std::string>::iterator I = HiddenGVStubs.begin(), + E = HiddenGVStubs.end(); I != E; ++I) { + O << I->second << ":\n"; + O << (isPPC64 ? "\t.quad\t" : "\t.long\t") << I->getKeyData() << '\n'; } } @@ -1114,28 +1140,19 @@ bool PPCDarwinAsmPrinter::doFinalization(Module &M) { /// for a MachineFunction to the given output stream, in a format that the /// Darwin assembler can deal with. /// -FunctionPass *llvm::createPPCAsmPrinterPass(raw_ostream &o, - PPCTargetMachine &tm, - bool verbose) { +static AsmPrinter *createPPCAsmPrinterPass(formatted_raw_ostream &o, + TargetMachine &tm, + const MCAsmInfo *tai, + bool verbose) { const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>(); - if (Subtarget->isDarwin()) { - return new PPCDarwinAsmPrinter(o, tm, tm.getTargetAsmInfo(), verbose); - } else { - return new PPCLinuxAsmPrinter(o, tm, tm.getTargetAsmInfo(), verbose); - } -} - -namespace { - static struct Register { - Register() { - PPCTargetMachine::registerAsmPrinter(createPPCAsmPrinterPass); - } - } Registrator; + if (Subtarget->isDarwin()) + return new PPCDarwinAsmPrinter(o, tm, tai, verbose); + return new PPCLinuxAsmPrinter(o, tm, tai, verbose); } -extern "C" int PowerPCAsmPrinterForceLink; -int PowerPCAsmPrinterForceLink = 0; - // Force static initialization. -extern "C" void LLVMInitializePowerPCAsmPrinter() { } +extern "C" void LLVMInitializePowerPCAsmPrinter() { + TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass); + TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass); +} diff --git a/lib/Target/PowerPC/CMakeLists.txt b/lib/Target/PowerPC/CMakeLists.txt index a6479d8..bdd6d36 100644 --- a/lib/Target/PowerPC/CMakeLists.txt +++ b/lib/Target/PowerPC/CMakeLists.txt @@ -20,10 +20,10 @@ add_llvm_target(PowerPCCodeGen PPCISelLowering.cpp PPCJITInfo.cpp PPCMachOWriterInfo.cpp + PPCMCAsmInfo.cpp PPCPredicates.cpp PPCRegisterInfo.cpp PPCSubtarget.cpp - PPCTargetAsmInfo.cpp PPCTargetMachine.cpp ) diff --git a/lib/Target/PowerPC/Makefile b/lib/Target/PowerPC/Makefile index db68897..4015d4a 100644 --- a/lib/Target/PowerPC/Makefile +++ b/lib/Target/PowerPC/Makefile @@ -17,6 +17,6 @@ BUILT_SOURCES = PPCGenInstrNames.inc PPCGenRegisterNames.inc \ PPCGenInstrInfo.inc PPCGenDAGISel.inc \ PPCGenSubtarget.inc PPCGenCallingConv.inc -DIRS = AsmPrinter +DIRS = AsmPrinter TargetInfo include $(LEVEL)/Makefile.common diff --git a/lib/Target/PowerPC/PPC.h b/lib/Target/PowerPC/PPC.h index f6c3469..7b98268 100644 --- a/lib/Target/PowerPC/PPC.h +++ b/lib/Target/PowerPC/PPC.h @@ -24,16 +24,21 @@ namespace llvm { class PPCTargetMachine; class FunctionPass; class MachineCodeEmitter; - class raw_ostream; + class ObjectCodeEmitter; + class formatted_raw_ostream; FunctionPass *createPPCBranchSelectionPass(); FunctionPass *createPPCISelDag(PPCTargetMachine &TM); -FunctionPass *createPPCAsmPrinterPass(raw_ostream &OS, PPCTargetMachine &TM, - bool Verbose); FunctionPass *createPPCCodeEmitterPass(PPCTargetMachine &TM, MachineCodeEmitter &MCE); FunctionPass *createPPCJITCodeEmitterPass(PPCTargetMachine &TM, - JITCodeEmitter &MCE); + JITCodeEmitter &MCE); +FunctionPass *createPPCObjectCodeEmitterPass(PPCTargetMachine &TM, + ObjectCodeEmitter &OCE); + +extern Target ThePPC32Target; +extern Target ThePPC64Target; + } // end namespace llvm; // Defines symbolic names for PowerPC registers. This defines a mapping from diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index cd6018d..0675293 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -19,12 +19,15 @@ #include "llvm/PassManager.h" #include "llvm/CodeGen/MachineCodeEmitter.h" #include "llvm/CodeGen/JITCodeEmitter.h" +#include "llvm/CodeGen/ObjectCodeEmitter.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/Passes.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetOptions.h" using namespace llvm; @@ -55,8 +58,7 @@ namespace { template <class CodeEmitter> class VISIBILITY_HIDDEN Emitter : public MachineFunctionPass, - public PPCCodeEmitter - { + public PPCCodeEmitter { TargetMachine &TM; CodeEmitter &MCE; @@ -88,9 +90,10 @@ namespace { template <class CodeEmitter> char Emitter<CodeEmitter>::ID = 0; } - + /// createPPCCodeEmitterPass - Return a pass that emits the collected PPC code /// to the specified MCE object. + FunctionPass *llvm::createPPCCodeEmitterPass(PPCTargetMachine &TM, MachineCodeEmitter &MCE) { return new Emitter<MachineCodeEmitter>(TM, MCE); @@ -101,6 +104,11 @@ FunctionPass *llvm::createPPCJITCodeEmitterPass(PPCTargetMachine &TM, return new Emitter<JITCodeEmitter>(TM, JCE); } +FunctionPass *llvm::createPPCObjectCodeEmitterPass(PPCTargetMachine &TM, + ObjectCodeEmitter &OCE) { + return new Emitter<ObjectCodeEmitter>(TM, OCE); +} + template <class CodeEmitter> bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) { assert((MF.getTarget().getRelocationModel() != Reloc::Default || @@ -121,9 +129,10 @@ bool Emitter<CodeEmitter>::runOnMachineFunction(MachineFunction &MF) { template <class CodeEmitter> void Emitter<CodeEmitter>::emitBasicBlock(MachineBasicBlock &MBB) { MCE.StartMachineBasicBlock(&MBB); - + for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){ const MachineInstr &MI = *I; + MCE.processDebugLoc(MI.getDebugLoc(), true); switch (MI.getOpcode()) { default: MCE.emitWordBE(getBinaryCodeForInstr(MI)); @@ -133,6 +142,7 @@ void Emitter<CodeEmitter>::emitBasicBlock(MachineBasicBlock &MBB) { MCE.emitLabel(MI.getOperand(0).getImm()); break; case TargetInstrInfo::IMPLICIT_DEF: + case TargetInstrInfo::KILL: break; // pseudo opcode, no side effects case PPC::MovePCtoLR: case PPC::MovePCtoLR8: @@ -141,6 +151,7 @@ void Emitter<CodeEmitter>::emitBasicBlock(MachineBasicBlock &MBB) { MCE.emitWordBE(0x48000005); // bl 1 break; } + MCE.processDebugLoc(MI.getDebugLoc(), false); } } @@ -172,7 +183,7 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI, assert(MovePCtoLROffset && "MovePCtoLR not seen yet?"); } switch (MI.getOpcode()) { - default: MI.dump(); assert(0 && "Unknown instruction for relocation!"); + default: MI.dump(); llvm_unreachable("Unknown instruction for relocation!"); case PPC::LIS: case PPC::LIS8: case PPC::ADDIS: @@ -193,7 +204,7 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI, case PPC::LWZ8: case PPC::LFS: case PPC::LFD: - + // Stores. case PPC::STB: case PPC::STB8: @@ -214,7 +225,7 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI, break; } } - + MachineRelocation R; if (MO.isGlobal()) { R = MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc, @@ -231,7 +242,7 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI, R = MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), Reloc, MO.getIndex(), 0); } - + // If in PIC mode, we need to encode the negated address of the // 'movepctolr' into the unrelocated field. After relocation, we'll have // &gv-&movepctolr-4 in the imm field. Once &movepctolr is added to the imm @@ -242,7 +253,7 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI, R.setConstantVal(-(intptr_t)MovePCtoLROffset - 4); } MCE.addRelocation(R); - + } else if (MO.isMBB()) { unsigned Reloc = 0; unsigned Opcode = MI.getOpcode(); @@ -252,15 +263,17 @@ unsigned PPCCodeEmitter::getMachineOpValue(const MachineInstr &MI, Reloc = PPC::reloc_pcrel_bx; else // BCC instruction Reloc = PPC::reloc_pcrel_bcx; + MCE.addRelocation(MachineRelocation::getBB(MCE.getCurrentPCOffset(), Reloc, MO.getMBB())); } else { - cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; - abort(); +#ifndef NDEBUG + errs() << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; +#endif + llvm_unreachable(0); } return rv; } #include "PPCGenCodeEmitter.inc" - diff --git a/lib/Target/PowerPC/PPCFrameInfo.h b/lib/Target/PowerPC/PPCFrameInfo.h index 770a560..65f113e 100644 --- a/lib/Target/PowerPC/PPCFrameInfo.h +++ b/lib/Target/PowerPC/PPCFrameInfo.h @@ -31,33 +31,32 @@ public: /// getReturnSaveOffset - Return the previous frame offset to save the /// return address. - static unsigned getReturnSaveOffset(bool LP64, bool isDarwinABI) { + static unsigned getReturnSaveOffset(bool isPPC64, bool isDarwinABI) { if (isDarwinABI) - return LP64 ? 16 : 8; + return isPPC64 ? 16 : 8; // SVR4 ABI: - return 4; + return isPPC64 ? 16 : 4; } /// getFramePointerSaveOffset - Return the previous frame offset to save the /// frame pointer. - static unsigned getFramePointerSaveOffset(bool LP64, bool isDarwinABI) { + static unsigned getFramePointerSaveOffset(bool isPPC64, bool isDarwinABI) { // For the Darwin ABI: // Use the TOC save slot in the PowerPC linkage area for saving the frame // pointer (if needed.) LLVM does not generate code that uses the TOC (R2 // is treated as a caller saved register.) if (isDarwinABI) - return LP64 ? 40 : 20; + return isPPC64 ? 40 : 20; - // SVR4 ABI: - // Save it right before the link register + // SVR4 ABI: First slot in the general register save area. return -4U; } /// getLinkageSize - Return the size of the PowerPC ABI linkage area. /// - static unsigned getLinkageSize(bool LP64, bool isDarwinABI) { - if (isDarwinABI) - return 6 * (LP64 ? 8 : 4); + static unsigned getLinkageSize(bool isPPC64, bool isDarwinABI) { + if (isDarwinABI || isPPC64) + return 6 * (isPPC64 ? 8 : 4); // SVR4 ABI: return 8; @@ -65,118 +64,222 @@ public: /// getMinCallArgumentsSize - Return the size of the minium PowerPC ABI /// argument area. - static unsigned getMinCallArgumentsSize(bool LP64, bool isDarwinABI) { - // For the Darwin ABI: + static unsigned getMinCallArgumentsSize(bool isPPC64, bool isDarwinABI) { + // For the Darwin ABI / 64-bit SVR4 ABI: // The prolog code of the callee may store up to 8 GPR argument registers to // the stack, allowing va_start to index over them in memory if its varargs. // Because we cannot tell if this is needed on the caller side, we have to // conservatively assume that it is needed. As such, make sure we have at // least enough stack space for the caller to store the 8 GPRs. - if (isDarwinABI) - return 8 * (LP64 ? 8 : 4); + if (isDarwinABI || isPPC64) + return 8 * (isPPC64 ? 8 : 4); - // SVR4 ABI: + // 32-bit SVR4 ABI: // There is no default stack allocated for the 8 first GPR arguments. return 0; } /// getMinCallFrameSize - Return the minimum size a call frame can be using /// the PowerPC ABI. - static unsigned getMinCallFrameSize(bool LP64, bool isDarwinABI) { + static unsigned getMinCallFrameSize(bool isPPC64, bool isDarwinABI) { // The call frame needs to be at least big enough for linkage and 8 args. - return getLinkageSize(LP64, isDarwinABI) + - getMinCallArgumentsSize(LP64, isDarwinABI); + return getLinkageSize(isPPC64, isDarwinABI) + + getMinCallArgumentsSize(isPPC64, isDarwinABI); } // With the SVR4 ABI, callee-saved registers have fixed offsets on the stack. - const std::pair<unsigned, int> * + const SpillSlot * getCalleeSavedSpillSlots(unsigned &NumEntries) const { // Early exit if not using the SVR4 ABI. if (!TM.getSubtarget<PPCSubtarget>().isSVR4ABI()) { NumEntries = 0; return 0; } - - static const std::pair<unsigned, int> Offsets[] = { + + static const SpillSlot Offsets[] = { // Floating-point register save area offsets. - std::pair<unsigned, int>(PPC::F31, -8), - std::pair<unsigned, int>(PPC::F30, -16), - std::pair<unsigned, int>(PPC::F29, -24), - std::pair<unsigned, int>(PPC::F28, -32), - std::pair<unsigned, int>(PPC::F27, -40), - std::pair<unsigned, int>(PPC::F26, -48), - std::pair<unsigned, int>(PPC::F25, -56), - std::pair<unsigned, int>(PPC::F24, -64), - std::pair<unsigned, int>(PPC::F23, -72), - std::pair<unsigned, int>(PPC::F22, -80), - std::pair<unsigned, int>(PPC::F21, -88), - std::pair<unsigned, int>(PPC::F20, -96), - std::pair<unsigned, int>(PPC::F19, -104), - std::pair<unsigned, int>(PPC::F18, -112), - std::pair<unsigned, int>(PPC::F17, -120), - std::pair<unsigned, int>(PPC::F16, -128), - std::pair<unsigned, int>(PPC::F15, -136), - std::pair<unsigned, int>(PPC::F14, -144), - + {PPC::F31, -8}, + {PPC::F30, -16}, + {PPC::F29, -24}, + {PPC::F28, -32}, + {PPC::F27, -40}, + {PPC::F26, -48}, + {PPC::F25, -56}, + {PPC::F24, -64}, + {PPC::F23, -72}, + {PPC::F22, -80}, + {PPC::F21, -88}, + {PPC::F20, -96}, + {PPC::F19, -104}, + {PPC::F18, -112}, + {PPC::F17, -120}, + {PPC::F16, -128}, + {PPC::F15, -136}, + {PPC::F14, -144}, + // General register save area offsets. - std::pair<unsigned, int>(PPC::R31, -4), - std::pair<unsigned, int>(PPC::R30, -8), - std::pair<unsigned, int>(PPC::R29, -12), - std::pair<unsigned, int>(PPC::R28, -16), - std::pair<unsigned, int>(PPC::R27, -20), - std::pair<unsigned, int>(PPC::R26, -24), - std::pair<unsigned, int>(PPC::R25, -28), - std::pair<unsigned, int>(PPC::R24, -32), - std::pair<unsigned, int>(PPC::R23, -36), - std::pair<unsigned, int>(PPC::R22, -40), - std::pair<unsigned, int>(PPC::R21, -44), - std::pair<unsigned, int>(PPC::R20, -48), - std::pair<unsigned, int>(PPC::R19, -52), - std::pair<unsigned, int>(PPC::R18, -56), - std::pair<unsigned, int>(PPC::R17, -60), - std::pair<unsigned, int>(PPC::R16, -64), - std::pair<unsigned, int>(PPC::R15, -68), - std::pair<unsigned, int>(PPC::R14, -72), + {PPC::R31, -4}, + {PPC::R30, -8}, + {PPC::R29, -12}, + {PPC::R28, -16}, + {PPC::R27, -20}, + {PPC::R26, -24}, + {PPC::R25, -28}, + {PPC::R24, -32}, + {PPC::R23, -36}, + {PPC::R22, -40}, + {PPC::R21, -44}, + {PPC::R20, -48}, + {PPC::R19, -52}, + {PPC::R18, -56}, + {PPC::R17, -60}, + {PPC::R16, -64}, + {PPC::R15, -68}, + {PPC::R14, -72}, // CR save area offset. // FIXME SVR4: Disable CR save area for now. -// std::pair<unsigned, int>(PPC::CR2, -4), -// std::pair<unsigned, int>(PPC::CR3, -4), -// std::pair<unsigned, int>(PPC::CR4, -4), -// std::pair<unsigned, int>(PPC::CR2LT, -4), -// std::pair<unsigned, int>(PPC::CR2GT, -4), -// std::pair<unsigned, int>(PPC::CR2EQ, -4), -// std::pair<unsigned, int>(PPC::CR2UN, -4), -// std::pair<unsigned, int>(PPC::CR3LT, -4), -// std::pair<unsigned, int>(PPC::CR3GT, -4), -// std::pair<unsigned, int>(PPC::CR3EQ, -4), -// std::pair<unsigned, int>(PPC::CR3UN, -4), -// std::pair<unsigned, int>(PPC::CR4LT, -4), -// std::pair<unsigned, int>(PPC::CR4GT, -4), -// std::pair<unsigned, int>(PPC::CR4EQ, -4), -// std::pair<unsigned, int>(PPC::CR4UN, -4), +// {PPC::CR2, -4}, +// {PPC::CR3, -4}, +// {PPC::CR4, -4}, +// {PPC::CR2LT, -4}, +// {PPC::CR2GT, -4}, +// {PPC::CR2EQ, -4}, +// {PPC::CR2UN, -4}, +// {PPC::CR3LT, -4}, +// {PPC::CR3GT, -4}, +// {PPC::CR3EQ, -4}, +// {PPC::CR3UN, -4}, +// {PPC::CR4LT, -4}, +// {PPC::CR4GT, -4}, +// {PPC::CR4EQ, -4}, +// {PPC::CR4UN, -4}, // VRSAVE save area offset. - std::pair<unsigned, int>(PPC::VRSAVE, -4), - + {PPC::VRSAVE, -4}, + // Vector register save area - std::pair<unsigned, int>(PPC::V31, -16), - std::pair<unsigned, int>(PPC::V30, -32), - std::pair<unsigned, int>(PPC::V29, -48), - std::pair<unsigned, int>(PPC::V28, -64), - std::pair<unsigned, int>(PPC::V27, -80), - std::pair<unsigned, int>(PPC::V26, -96), - std::pair<unsigned, int>(PPC::V25, -112), - std::pair<unsigned, int>(PPC::V24, -128), - std::pair<unsigned, int>(PPC::V23, -144), - std::pair<unsigned, int>(PPC::V22, -160), - std::pair<unsigned, int>(PPC::V21, -176), - std::pair<unsigned, int>(PPC::V20, -192) + {PPC::V31, -16}, + {PPC::V30, -32}, + {PPC::V29, -48}, + {PPC::V28, -64}, + {PPC::V27, -80}, + {PPC::V26, -96}, + {PPC::V25, -112}, + {PPC::V24, -128}, + {PPC::V23, -144}, + {PPC::V22, -160}, + {PPC::V21, -176}, + {PPC::V20, -192} }; - - NumEntries = array_lengthof(Offsets); - - return Offsets; + + static const SpillSlot Offsets64[] = { + // Floating-point register save area offsets. + {PPC::F31, -8}, + {PPC::F30, -16}, + {PPC::F29, -24}, + {PPC::F28, -32}, + {PPC::F27, -40}, + {PPC::F26, -48}, + {PPC::F25, -56}, + {PPC::F24, -64}, + {PPC::F23, -72}, + {PPC::F22, -80}, + {PPC::F21, -88}, + {PPC::F20, -96}, + {PPC::F19, -104}, + {PPC::F18, -112}, + {PPC::F17, -120}, + {PPC::F16, -128}, + {PPC::F15, -136}, + {PPC::F14, -144}, + + // General register save area offsets. + // FIXME 64-bit SVR4: Are 32-bit registers actually allocated in 64-bit + // mode? + {PPC::R31, -4}, + {PPC::R30, -12}, + {PPC::R29, -20}, + {PPC::R28, -28}, + {PPC::R27, -36}, + {PPC::R26, -44}, + {PPC::R25, -52}, + {PPC::R24, -60}, + {PPC::R23, -68}, + {PPC::R22, -76}, + {PPC::R21, -84}, + {PPC::R20, -92}, + {PPC::R19, -100}, + {PPC::R18, -108}, + {PPC::R17, -116}, + {PPC::R16, -124}, + {PPC::R15, -132}, + {PPC::R14, -140}, + + {PPC::X31, -8}, + {PPC::X30, -16}, + {PPC::X29, -24}, + {PPC::X28, -32}, + {PPC::X27, -40}, + {PPC::X26, -48}, + {PPC::X25, -56}, + {PPC::X24, -64}, + {PPC::X23, -72}, + {PPC::X22, -80}, + {PPC::X21, -88}, + {PPC::X20, -96}, + {PPC::X19, -104}, + {PPC::X18, -112}, + {PPC::X17, -120}, + {PPC::X16, -128}, + {PPC::X15, -136}, + {PPC::X14, -144}, + + // CR save area offset. + // FIXME SVR4: Disable CR save area for now. +// {PPC::CR2, -4}, +// {PPC::CR3, -4}, +// {PPC::CR4, -4}, +// {PPC::CR2LT, -4}, +// {PPC::CR2GT, -4}, +// {PPC::CR2EQ, -4}, +// {PPC::CR2UN, -4}, +// {PPC::CR3LT, -4}, +// {PPC::CR3GT, -4}, +// {PPC::CR3EQ, -4}, +// {PPC::CR3UN, -4}, +// {PPC::CR4LT, -4}, +// {PPC::CR4GT, -4}, +// {PPC::CR4EQ, -4}, +// {PPC::CR4UN, -4}, + + // VRSAVE save area offset. + {PPC::VRSAVE, -4}, + + // Vector register save area + {PPC::V31, -16}, + {PPC::V30, -32}, + {PPC::V29, -48}, + {PPC::V28, -64}, + {PPC::V27, -80}, + {PPC::V26, -96}, + {PPC::V25, -112}, + {PPC::V24, -128}, + {PPC::V23, -144}, + {PPC::V22, -160}, + {PPC::V21, -176}, + {PPC::V20, -192} + }; + + if (TM.getSubtarget<PPCSubtarget>().isPPC64()) { + NumEntries = array_lengthof(Offsets64); + + return Offsets64; + } else { + NumEntries = array_lengthof(Offsets); + + return Offsets; + } } }; diff --git a/lib/Target/PowerPC/PPCHazardRecognizers.cpp b/lib/Target/PowerPC/PPCHazardRecognizers.cpp index ec3e757..6af7e0f 100644 --- a/lib/Target/PowerPC/PPCHazardRecognizers.cpp +++ b/lib/Target/PowerPC/PPCHazardRecognizers.cpp @@ -17,6 +17,8 @@ #include "PPCInstrInfo.h" #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -51,7 +53,7 @@ PPCHazardRecognizer970::PPCHazardRecognizer970(const TargetInstrInfo &tii) } void PPCHazardRecognizer970::EndDispatchGroup() { - DOUT << "=== Start of dispatch group\n"; + DEBUG(errs() << "=== Start of dispatch group\n"); NumIssued = 0; // Structural hazard info. @@ -141,7 +143,7 @@ getHazardType(SUnit *SU) { return Hazard; switch (InstrType) { - default: assert(0 && "Unknown instruction type!"); + default: llvm_unreachable("Unknown instruction type!"); case PPCII::PPC970_FXU: case PPCII::PPC970_LSU: case PPCII::PPC970_FPU: @@ -167,7 +169,7 @@ getHazardType(SUnit *SU) { if (isLoad && NumStores) { unsigned LoadSize; switch (Opcode) { - default: assert(0 && "Unknown load!"); + default: llvm_unreachable("Unknown load!"); case PPC::LBZ: case PPC::LBZU: case PPC::LBZX: case PPC::LBZ8: case PPC::LBZU8: @@ -235,7 +237,7 @@ void PPCHazardRecognizer970::EmitInstruction(SUnit *SU) { if (isStore) { unsigned ThisStoreSize; switch (Opcode) { - default: assert(0 && "Unknown store instruction!"); + default: llvm_unreachable("Unknown store instruction!"); case PPC::STB: case PPC::STB8: case PPC::STBU: case PPC::STBU8: case PPC::STBX: case PPC::STBX8: diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 823e316..8fa6a66 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -20,6 +20,7 @@ #include "PPCHazardRecognizers.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionAnalysis.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/SelectionDAGISel.h" @@ -31,6 +32,8 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; namespace { @@ -49,17 +52,12 @@ namespace { PPCLowering(*TM.getTargetLowering()), PPCSubTarget(*TM.getSubtargetImpl()) {} - virtual bool runOnFunction(Function &Fn) { - // Do not codegen any 'available_externally' functions at all, they have - // definitions outside the translation unit. - if (Fn.hasAvailableExternallyLinkage()) - return false; - + virtual bool runOnMachineFunction(MachineFunction &MF) { // Make sure we re-emit a set of the global base reg if necessary GlobalBaseReg = 0; - SelectionDAGISel::runOnFunction(Fn); + SelectionDAGISel::runOnMachineFunction(MF); - InsertVRSaveCode(Fn); + InsertVRSaveCode(MF); return true; } @@ -145,30 +143,14 @@ namespace { } /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for - /// inline asm expressions. - virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, + /// inline asm expressions. It is always correct to compute the value into + /// a register. The case of adding a (possibly relocatable) constant to a + /// register can be improved, but it is wrong to substitute Reg+Reg for + /// Reg in an asm, because the load or store opcode would have to change. + virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, std::vector<SDValue> &OutOps) { - SDValue Op0, Op1; - switch (ConstraintCode) { - default: return true; - case 'm': // memory - if (!SelectAddrIdx(Op, Op, Op0, Op1)) - SelectAddrImm(Op, Op, Op0, Op1); - break; - case 'o': // offsetable - if (!SelectAddrImm(Op, Op, Op0, Op1)) { - Op0 = Op; - Op1 = getSmallIPtrImm(0); - } - break; - case 'v': // not offsetable - SelectAddrIdxOnly(Op, Op, Op0, Op1); - break; - } - - OutOps.push_back(Op0); - OutOps.push_back(Op1); + OutOps.push_back(Op); return false; } @@ -179,7 +161,7 @@ namespace { /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. virtual void InstructionSelect(); - void InsertVRSaveCode(Function &Fn); + void InsertVRSaveCode(MachineFunction &MF); virtual const char *getPassName() const { return "PowerPC DAG->DAG Pattern Instruction Selection"; @@ -216,13 +198,12 @@ void PPCDAGToDAGISel::InstructionSelect() { /// InsertVRSaveCode - Once the entire function has been instruction selected, /// all virtual registers are created and all machine instructions are built, /// check to see if we need to save/restore VRSAVE. If so, do it. -void PPCDAGToDAGISel::InsertVRSaveCode(Function &F) { +void PPCDAGToDAGISel::InsertVRSaveCode(MachineFunction &Fn) { // Check to see if this function uses vector registers, which means we have to // save and restore the VRSAVE register and update it with the regs we use. // // In this case, there will be virtual registers of vector type type created // by the scheduler. Detect them now. - MachineFunction &Fn = MachineFunction::get(&F); bool HasVectorVReg = false; for (unsigned i = TargetRegisterInfo::FirstVirtualRegister, e = RegInfo->getLastVirtReg()+1; i != e; ++i) @@ -285,7 +266,7 @@ SDNode *PPCDAGToDAGISel::getGlobalBaseReg() { if (!GlobalBaseReg) { const TargetInstrInfo &TII = *TM.getInstrInfo(); // Insert the set of GlobalBaseReg into the first MBB of the function - MachineBasicBlock &FirstMBB = BB->getParent()->front(); + MachineBasicBlock &FirstMBB = MF->front(); MachineBasicBlock::iterator MBBI = FirstMBB.begin(); DebugLoc dl = DebugLoc::getUnknownLoc(); @@ -488,7 +469,7 @@ SDNode *PPCDAGToDAGISel::SelectBitfieldInsert(SDNode *N) { SH &= 31; SDValue Ops[] = { Tmp3, Op1, getI32Imm(SH), getI32Imm(MB), getI32Imm(ME) }; - return CurDAG->getTargetNode(PPC::RLWIMI, dl, MVT::i32, Ops, 5); + return CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32, Ops, 5); } } return 0; @@ -507,12 +488,12 @@ SDValue PPCDAGToDAGISel::SelectCC(SDValue LHS, SDValue RHS, if (isInt32Immediate(RHS, Imm)) { // SETEQ/SETNE comparison with 16-bit immediate, fold it. if (isUInt16(Imm)) - return SDValue(CurDAG->getTargetNode(PPC::CMPLWI, dl, MVT::i32, LHS, - getI32Imm(Imm & 0xFFFF)), 0); + return SDValue(CurDAG->getMachineNode(PPC::CMPLWI, dl, MVT::i32, LHS, + getI32Imm(Imm & 0xFFFF)), 0); // If this is a 16-bit signed immediate, fold it. if (isInt16((int)Imm)) - return SDValue(CurDAG->getTargetNode(PPC::CMPWI, dl, MVT::i32, LHS, - getI32Imm(Imm & 0xFFFF)), 0); + return SDValue(CurDAG->getMachineNode(PPC::CMPWI, dl, MVT::i32, LHS, + getI32Imm(Imm & 0xFFFF)), 0); // For non-equality comparisons, the default code would materialize the // constant, then compare against it, like this: @@ -523,22 +504,22 @@ SDValue PPCDAGToDAGISel::SelectCC(SDValue LHS, SDValue RHS, // xoris r0,r3,0x1234 // cmplwi cr0,r0,0x5678 // beq cr0,L6 - SDValue Xor(CurDAG->getTargetNode(PPC::XORIS, dl, MVT::i32, LHS, - getI32Imm(Imm >> 16)), 0); - return SDValue(CurDAG->getTargetNode(PPC::CMPLWI, dl, MVT::i32, Xor, - getI32Imm(Imm & 0xFFFF)), 0); + SDValue Xor(CurDAG->getMachineNode(PPC::XORIS, dl, MVT::i32, LHS, + getI32Imm(Imm >> 16)), 0); + return SDValue(CurDAG->getMachineNode(PPC::CMPLWI, dl, MVT::i32, Xor, + getI32Imm(Imm & 0xFFFF)), 0); } Opc = PPC::CMPLW; } else if (ISD::isUnsignedIntSetCC(CC)) { if (isInt32Immediate(RHS, Imm) && isUInt16(Imm)) - return SDValue(CurDAG->getTargetNode(PPC::CMPLWI, dl, MVT::i32, LHS, - getI32Imm(Imm & 0xFFFF)), 0); + return SDValue(CurDAG->getMachineNode(PPC::CMPLWI, dl, MVT::i32, LHS, + getI32Imm(Imm & 0xFFFF)), 0); Opc = PPC::CMPLW; } else { short SImm; if (isIntS16Immediate(RHS, SImm)) - return SDValue(CurDAG->getTargetNode(PPC::CMPWI, dl, MVT::i32, LHS, - getI32Imm((int)SImm & 0xFFFF)), + return SDValue(CurDAG->getMachineNode(PPC::CMPWI, dl, MVT::i32, LHS, + getI32Imm((int)SImm & 0xFFFF)), 0); Opc = PPC::CMPW; } @@ -548,12 +529,12 @@ SDValue PPCDAGToDAGISel::SelectCC(SDValue LHS, SDValue RHS, if (isInt64Immediate(RHS.getNode(), Imm)) { // SETEQ/SETNE comparison with 16-bit immediate, fold it. if (isUInt16(Imm)) - return SDValue(CurDAG->getTargetNode(PPC::CMPLDI, dl, MVT::i64, LHS, - getI32Imm(Imm & 0xFFFF)), 0); + return SDValue(CurDAG->getMachineNode(PPC::CMPLDI, dl, MVT::i64, LHS, + getI32Imm(Imm & 0xFFFF)), 0); // If this is a 16-bit signed immediate, fold it. if (isInt16(Imm)) - return SDValue(CurDAG->getTargetNode(PPC::CMPDI, dl, MVT::i64, LHS, - getI32Imm(Imm & 0xFFFF)), 0); + return SDValue(CurDAG->getMachineNode(PPC::CMPDI, dl, MVT::i64, LHS, + getI32Imm(Imm & 0xFFFF)), 0); // For non-equality comparisons, the default code would materialize the // constant, then compare against it, like this: @@ -565,23 +546,23 @@ SDValue PPCDAGToDAGISel::SelectCC(SDValue LHS, SDValue RHS, // cmpldi cr0,r0,0x5678 // beq cr0,L6 if (isUInt32(Imm)) { - SDValue Xor(CurDAG->getTargetNode(PPC::XORIS8, dl, MVT::i64, LHS, - getI64Imm(Imm >> 16)), 0); - return SDValue(CurDAG->getTargetNode(PPC::CMPLDI, dl, MVT::i64, Xor, - getI64Imm(Imm & 0xFFFF)), 0); + SDValue Xor(CurDAG->getMachineNode(PPC::XORIS8, dl, MVT::i64, LHS, + getI64Imm(Imm >> 16)), 0); + return SDValue(CurDAG->getMachineNode(PPC::CMPLDI, dl, MVT::i64, Xor, + getI64Imm(Imm & 0xFFFF)), 0); } } Opc = PPC::CMPLD; } else if (ISD::isUnsignedIntSetCC(CC)) { if (isInt64Immediate(RHS.getNode(), Imm) && isUInt16(Imm)) - return SDValue(CurDAG->getTargetNode(PPC::CMPLDI, dl, MVT::i64, LHS, - getI64Imm(Imm & 0xFFFF)), 0); + return SDValue(CurDAG->getMachineNode(PPC::CMPLDI, dl, MVT::i64, LHS, + getI64Imm(Imm & 0xFFFF)), 0); Opc = PPC::CMPLD; } else { short SImm; if (isIntS16Immediate(RHS, SImm)) - return SDValue(CurDAG->getTargetNode(PPC::CMPDI, dl, MVT::i64, LHS, - getI64Imm(SImm & 0xFFFF)), + return SDValue(CurDAG->getMachineNode(PPC::CMPDI, dl, MVT::i64, LHS, + getI64Imm(SImm & 0xFFFF)), 0); Opc = PPC::CMPD; } @@ -591,7 +572,7 @@ SDValue PPCDAGToDAGISel::SelectCC(SDValue LHS, SDValue RHS, assert(LHS.getValueType() == MVT::f64 && "Unknown vt!"); Opc = PPC::FCMPUD; } - return SDValue(CurDAG->getTargetNode(Opc, dl, MVT::i32, LHS, RHS), 0); + return SDValue(CurDAG->getMachineNode(Opc, dl, MVT::i32, LHS, RHS), 0); } static PPC::Predicate getPredicateForSetCC(ISD::CondCode CC) { @@ -600,8 +581,8 @@ static PPC::Predicate getPredicateForSetCC(ISD::CondCode CC) { case ISD::SETONE: case ISD::SETOLE: case ISD::SETOGE: - assert(0 && "Should be lowered by legalize!"); - default: assert(0 && "Unknown condition!"); abort(); + llvm_unreachable("Should be lowered by legalize!"); + default: llvm_unreachable("Unknown condition!"); case ISD::SETOEQ: case ISD::SETEQ: return PPC::PRED_EQ; case ISD::SETUNE: @@ -632,7 +613,7 @@ static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool &Invert, int &Other) { Invert = false; Other = -1; switch (CC) { - default: assert(0 && "Unknown condition!"); abort(); + default: llvm_unreachable("Unknown condition!"); case ISD::SETOLT: case ISD::SETLT: return 0; // Bit #0 = SETOLT case ISD::SETOGT: @@ -651,7 +632,7 @@ static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool &Invert, int &Other) { case ISD::SETOGE: case ISD::SETOLE: case ISD::SETONE: - assert(0 && "Invalid branch code: should be expanded by legalize"); + llvm_unreachable("Invalid branch code: should be expanded by legalize"); // These are invalid for floating point. Assume integer. case ISD::SETULT: return 0; case ISD::SETUGT: return 1; @@ -673,14 +654,14 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDValue Op) { switch (CC) { default: break; case ISD::SETEQ: { - Op = SDValue(CurDAG->getTargetNode(PPC::CNTLZW, dl, MVT::i32, Op), 0); + Op = SDValue(CurDAG->getMachineNode(PPC::CNTLZW, dl, MVT::i32, Op), 0); SDValue Ops[] = { Op, getI32Imm(27), getI32Imm(5), getI32Imm(31) }; return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops, 4); } case ISD::SETNE: { SDValue AD = - SDValue(CurDAG->getTargetNode(PPC::ADDIC, dl, MVT::i32, MVT::Flag, - Op, getI32Imm(~0U)), 0); + SDValue(CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Flag, + Op, getI32Imm(~0U)), 0); return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1)); } @@ -690,8 +671,8 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDValue Op) { } case ISD::SETGT: { SDValue T = - SDValue(CurDAG->getTargetNode(PPC::NEG, dl, MVT::i32, Op), 0); - T = SDValue(CurDAG->getTargetNode(PPC::ANDC, dl, MVT::i32, T, Op), 0); + SDValue(CurDAG->getMachineNode(PPC::NEG, dl, MVT::i32, Op), 0); + T = SDValue(CurDAG->getMachineNode(PPC::ANDC, dl, MVT::i32, T, Op), 0); SDValue Ops[] = { T, getI32Imm(1), getI32Imm(31), getI32Imm(31) }; return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops, 4); } @@ -701,31 +682,31 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDValue Op) { switch (CC) { default: break; case ISD::SETEQ: - Op = SDValue(CurDAG->getTargetNode(PPC::ADDIC, dl, MVT::i32, MVT::Flag, - Op, getI32Imm(1)), 0); + Op = SDValue(CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Flag, + Op, getI32Imm(1)), 0); return CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32, - SDValue(CurDAG->getTargetNode(PPC::LI, dl, - MVT::i32, - getI32Imm(0)), 0), + SDValue(CurDAG->getMachineNode(PPC::LI, dl, + MVT::i32, + getI32Imm(0)), 0), Op.getValue(1)); case ISD::SETNE: { - Op = SDValue(CurDAG->getTargetNode(PPC::NOR, dl, MVT::i32, Op, Op), 0); - SDNode *AD = CurDAG->getTargetNode(PPC::ADDIC, dl, MVT::i32, MVT::Flag, - Op, getI32Imm(~0U)); + Op = SDValue(CurDAG->getMachineNode(PPC::NOR, dl, MVT::i32, Op, Op), 0); + SDNode *AD = CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Flag, + Op, getI32Imm(~0U)); return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, SDValue(AD, 0), Op, SDValue(AD, 1)); } case ISD::SETLT: { - SDValue AD = SDValue(CurDAG->getTargetNode(PPC::ADDI, dl, MVT::i32, Op, - getI32Imm(1)), 0); - SDValue AN = SDValue(CurDAG->getTargetNode(PPC::AND, dl, MVT::i32, AD, - Op), 0); + SDValue AD = SDValue(CurDAG->getMachineNode(PPC::ADDI, dl, MVT::i32, Op, + getI32Imm(1)), 0); + SDValue AN = SDValue(CurDAG->getMachineNode(PPC::AND, dl, MVT::i32, AD, + Op), 0); SDValue Ops[] = { AN, getI32Imm(1), getI32Imm(31), getI32Imm(31) }; return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Ops, 4); } case ISD::SETGT: { SDValue Ops[] = { Op, getI32Imm(1), getI32Imm(31), getI32Imm(31) }; - Op = SDValue(CurDAG->getTargetNode(PPC::RLWINM, dl, MVT::i32, Ops, 4), + Op = SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, Ops, 4), 0); return CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Op, getI32Imm(1)); @@ -748,10 +729,10 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDValue Op) { InFlag).getValue(1); if (PPCSubTarget.isGigaProcessor() && OtherCondIdx == -1) - IntCR = SDValue(CurDAG->getTargetNode(PPC::MFOCRF, dl, MVT::i32, CR7Reg, - CCReg), 0); + IntCR = SDValue(CurDAG->getMachineNode(PPC::MFOCRF, dl, MVT::i32, CR7Reg, + CCReg), 0); else - IntCR = SDValue(CurDAG->getTargetNode(PPC::MFCR, dl, MVT::i32, CCReg), 0); + IntCR = SDValue(CurDAG->getMachineNode(PPC::MFCR, dl, MVT::i32, CCReg), 0); SDValue Ops[] = { IntCR, getI32Imm((32-(3-Idx)) & 31), getI32Imm(31), getI32Imm(31) }; @@ -760,7 +741,7 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDValue Op) { // Get the specified bit. SDValue Tmp = - SDValue(CurDAG->getTargetNode(PPC::RLWINM, dl, MVT::i32, Ops, 4), 0); + SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, Ops, 4), 0); if (Inv) { assert(OtherCondIdx == -1 && "Can't have split plus negation"); return CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1)); @@ -772,7 +753,7 @@ SDNode *PPCDAGToDAGISel::SelectSETCC(SDValue Op) { // Get the other bit of the comparison. Ops[1] = getI32Imm((32-(3-OtherCondIdx)) & 31); SDValue OtherCond = - SDValue(CurDAG->getTargetNode(PPC::RLWINM, dl, MVT::i32, Ops, 4), 0); + SDValue(CurDAG->getMachineNode(PPC::RLWINM, dl, MVT::i32, Ops, 4), 0); return CurDAG->SelectNodeTo(N, PPC::OR, MVT::i32, Tmp, OtherCond); } @@ -825,17 +806,17 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) { // Simple value. if (isInt16(Imm)) { // Just the Lo bits. - Result = CurDAG->getTargetNode(PPC::LI8, dl, MVT::i64, getI32Imm(Lo)); + Result = CurDAG->getMachineNode(PPC::LI8, dl, MVT::i64, getI32Imm(Lo)); } else if (Lo) { // Handle the Hi bits. unsigned OpC = Hi ? PPC::LIS8 : PPC::LI8; - Result = CurDAG->getTargetNode(OpC, dl, MVT::i64, getI32Imm(Hi)); + Result = CurDAG->getMachineNode(OpC, dl, MVT::i64, getI32Imm(Hi)); // And Lo bits. - Result = CurDAG->getTargetNode(PPC::ORI8, dl, MVT::i64, - SDValue(Result, 0), getI32Imm(Lo)); + Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, + SDValue(Result, 0), getI32Imm(Lo)); } else { // Just the Hi bits. - Result = CurDAG->getTargetNode(PPC::LIS8, dl, MVT::i64, getI32Imm(Hi)); + Result = CurDAG->getMachineNode(PPC::LIS8, dl, MVT::i64, getI32Imm(Hi)); } // If no shift, we're done. @@ -843,19 +824,20 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) { // Shift for next step if the upper 32-bits were not zero. if (Imm) { - Result = CurDAG->getTargetNode(PPC::RLDICR, dl, MVT::i64, - SDValue(Result, 0), - getI32Imm(Shift), getI32Imm(63 - Shift)); + Result = CurDAG->getMachineNode(PPC::RLDICR, dl, MVT::i64, + SDValue(Result, 0), + getI32Imm(Shift), + getI32Imm(63 - Shift)); } // Add in the last bits as required. if ((Hi = (Remainder >> 16) & 0xFFFF)) { - Result = CurDAG->getTargetNode(PPC::ORIS8, dl, MVT::i64, - SDValue(Result, 0), getI32Imm(Hi)); + Result = CurDAG->getMachineNode(PPC::ORIS8, dl, MVT::i64, + SDValue(Result, 0), getI32Imm(Hi)); } if ((Lo = Remainder & 0xFFFF)) { - Result = CurDAG->getTargetNode(PPC::ORI8, dl, MVT::i64, - SDValue(Result, 0), getI32Imm(Lo)); + Result = CurDAG->getMachineNode(PPC::ORI8, dl, MVT::i64, + SDValue(Result, 0), getI32Imm(Lo)); } return Result; @@ -875,18 +857,18 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) { if (N->hasOneUse()) return CurDAG->SelectNodeTo(N, Opc, Op.getValueType(), TFI, getSmallIPtrImm(0)); - return CurDAG->getTargetNode(Opc, dl, Op.getValueType(), TFI, - getSmallIPtrImm(0)); + return CurDAG->getMachineNode(Opc, dl, Op.getValueType(), TFI, + getSmallIPtrImm(0)); } case PPCISD::MFCR: { SDValue InFlag = N->getOperand(1); // Use MFOCRF if supported. if (PPCSubTarget.isGigaProcessor()) - return CurDAG->getTargetNode(PPC::MFOCRF, dl, MVT::i32, - N->getOperand(0), InFlag); + return CurDAG->getMachineNode(PPC::MFOCRF, dl, MVT::i32, + N->getOperand(0), InFlag); else - return CurDAG->getTargetNode(PPC::MFCR, dl, MVT::i32, InFlag); + return CurDAG->getMachineNode(PPC::MFCR, dl, MVT::i32, InFlag); } case ISD::SDIV: { @@ -900,17 +882,17 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) { SDValue N0 = N->getOperand(0); if ((signed)Imm > 0 && isPowerOf2_32(Imm)) { SDNode *Op = - CurDAG->getTargetNode(PPC::SRAWI, dl, MVT::i32, MVT::Flag, - N0, getI32Imm(Log2_32(Imm))); + CurDAG->getMachineNode(PPC::SRAWI, dl, MVT::i32, MVT::Flag, + N0, getI32Imm(Log2_32(Imm))); return CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32, SDValue(Op, 0), SDValue(Op, 1)); } else if ((signed)Imm < 0 && isPowerOf2_32(-Imm)) { SDNode *Op = - CurDAG->getTargetNode(PPC::SRAWI, dl, MVT::i32, MVT::Flag, - N0, getI32Imm(Log2_32(-Imm))); + CurDAG->getMachineNode(PPC::SRAWI, dl, MVT::i32, MVT::Flag, + N0, getI32Imm(Log2_32(-Imm))); SDValue PT = - SDValue(CurDAG->getTargetNode(PPC::ADDZE, dl, MVT::i32, - SDValue(Op, 0), SDValue(Op, 1)), + SDValue(CurDAG->getMachineNode(PPC::ADDZE, dl, MVT::i32, + SDValue(Op, 0), SDValue(Op, 1)), 0); return CurDAG->SelectNodeTo(N, PPC::NEG, MVT::i32, PT); } @@ -923,7 +905,7 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) { case ISD::LOAD: { // Handle preincrement loads. LoadSDNode *LD = cast<LoadSDNode>(Op); - MVT LoadedVT = LD->getMemoryVT(); + EVT LoadedVT = LD->getMemoryVT(); // Normal loads are handled by code generated from the .td file. if (LD->getAddressingMode() != ISD::PRE_INC) @@ -938,8 +920,8 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) { if (LD->getValueType(0) != MVT::i64) { // Handle PPC32 integer and normal FP loads. assert((!isSExt || LoadedVT == MVT::i16) && "Invalid sext update load"); - switch (LoadedVT.getSimpleVT()) { - default: assert(0 && "Invalid PPC load type!"); + switch (LoadedVT.getSimpleVT().SimpleTy) { + default: llvm_unreachable("Invalid PPC load type!"); case MVT::f64: Opcode = PPC::LFDU; break; case MVT::f32: Opcode = PPC::LFSU; break; case MVT::i32: Opcode = PPC::LWZU; break; @@ -950,8 +932,8 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) { } else { assert(LD->getValueType(0) == MVT::i64 && "Unknown load result type!"); assert((!isSExt || LoadedVT == MVT::i16) && "Invalid sext update load"); - switch (LoadedVT.getSimpleVT()) { - default: assert(0 && "Invalid PPC load type!"); + switch (LoadedVT.getSimpleVT().SimpleTy) { + default: llvm_unreachable("Invalid PPC load type!"); case MVT::i64: Opcode = PPC::LDU; break; case MVT::i32: Opcode = PPC::LWZU8; break; case MVT::i16: Opcode = isSExt ? PPC::LHAU8 : PPC::LHZU8; break; @@ -964,11 +946,11 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) { SDValue Base = LD->getBasePtr(); SDValue Ops[] = { Offset, Base, Chain }; // FIXME: PPC64 - return CurDAG->getTargetNode(Opcode, dl, LD->getValueType(0), - PPCLowering.getPointerTy(), - MVT::Other, Ops, 3); + return CurDAG->getMachineNode(Opcode, dl, LD->getValueType(0), + PPCLowering.getPointerTy(), + MVT::Other, Ops, 3); } else { - assert(0 && "R+R preindex loads not supported yet!"); + llvm_unreachable("R+R preindex loads not supported yet!"); } } @@ -1008,7 +990,7 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) { SDValue Ops[] = { N->getOperand(0).getOperand(0), N->getOperand(0).getOperand(1), getI32Imm(0), getI32Imm(MB),getI32Imm(ME) }; - return CurDAG->getTargetNode(PPC::RLWIMI, dl, MVT::i32, Ops, 5); + return CurDAG->getMachineNode(PPC::RLWIMI, dl, MVT::i32, Ops, 5); } } @@ -1058,8 +1040,8 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) { // FIXME: Implement this optzn for PPC64. N->getValueType(0) == MVT::i32) { SDNode *Tmp = - CurDAG->getTargetNode(PPC::ADDIC, dl, MVT::i32, MVT::Flag, - N->getOperand(0), getI32Imm(~0U)); + CurDAG->getMachineNode(PPC::ADDIC, dl, MVT::i32, MVT::Flag, + N->getOperand(0), getI32Imm(~0U)); return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, SDValue(Tmp, 0), N->getOperand(0), SDValue(Tmp, 1)); @@ -1109,51 +1091,10 @@ SDNode *PPCDAGToDAGISel::Select(SDValue Op) { SDValue Chain = N->getOperand(0); SDValue Target = N->getOperand(1); unsigned Opc = Target.getValueType() == MVT::i32 ? PPC::MTCTR : PPC::MTCTR8; - Chain = SDValue(CurDAG->getTargetNode(Opc, dl, MVT::Other, Target, - Chain), 0); + Chain = SDValue(CurDAG->getMachineNode(Opc, dl, MVT::Other, Target, + Chain), 0); return CurDAG->SelectNodeTo(N, PPC::BCTR, MVT::Other, Chain); } - case ISD::DECLARE: { - SDValue Chain = N->getOperand(0); - SDValue N1 = N->getOperand(1); - SDValue N2 = N->getOperand(2); - FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(N1); - - // FIXME: We need to handle this for VLAs. - if (!FINode) { - ReplaceUses(Op.getValue(0), Chain); - return NULL; - } - - if (N2.getOpcode() == ISD::ADD) { - if (N2.getOperand(0).getOpcode() == ISD::ADD && - N2.getOperand(0).getOperand(0).getOpcode() == PPCISD::GlobalBaseReg && - N2.getOperand(0).getOperand(1).getOpcode() == PPCISD::Hi && - N2.getOperand(1).getOpcode() == PPCISD::Lo) - N2 = N2.getOperand(0).getOperand(1).getOperand(0); - else if (N2.getOperand(0).getOpcode() == ISD::ADD && - N2.getOperand(0).getOperand(0).getOpcode() == PPCISD::GlobalBaseReg && - N2.getOperand(0).getOperand(1).getOpcode() == PPCISD::Lo && - N2.getOperand(1).getOpcode() == PPCISD::Hi) - N2 = N2.getOperand(0).getOperand(1).getOperand(0); - else if (N2.getOperand(0).getOpcode() == PPCISD::Hi && - N2.getOperand(1).getOpcode() == PPCISD::Lo) - N2 = N2.getOperand(0).getOperand(0); - } - - // If we don't have a global address here, the debug info is mangled, just - // drop it. - if (!isa<GlobalAddressSDNode>(N2)) { - ReplaceUses(Op.getValue(0), Chain); - return NULL; - } - int FI = cast<FrameIndexSDNode>(N1)->getIndex(); - GlobalValue *GV = cast<GlobalAddressSDNode>(N2)->getGlobal(); - SDValue Tmp1 = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy()); - SDValue Tmp2 = CurDAG->getTargetGlobalAddress(GV, TLI.getPointerTy()); - return CurDAG->SelectNodeTo(N, TargetInstrInfo::DECLARE, - MVT::Other, Tmp1, Tmp2, Chain); - } } return SelectCode(Op); diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 1c6b287..3920b38 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -31,21 +31,24 @@ #include "llvm/Intrinsics.h" #include "llvm/Support/MathExtras.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/DerivedTypes.h" using namespace llvm; -static bool CC_PPC_SVR4_Custom_Dummy(unsigned &ValNo, MVT &ValVT, MVT &LocVT, +static bool CC_PPC_SVR4_Custom_Dummy(unsigned &ValNo, EVT &ValVT, EVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State); -static bool CC_PPC_SVR4_Custom_AlignArgRegs(unsigned &ValNo, MVT &ValVT, - MVT &LocVT, +static bool CC_PPC_SVR4_Custom_AlignArgRegs(unsigned &ValNo, EVT &ValVT, + EVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State); -static bool CC_PPC_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT, - MVT &LocVT, +static bool CC_PPC_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, EVT &ValVT, + EVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State); @@ -54,8 +57,15 @@ static cl::opt<bool> EnablePPCPreinc("enable-ppc-preinc", cl::desc("enable preincrement load/store generation on PPC (experimental)"), cl::Hidden); +static TargetLoweringObjectFile *CreateTLOF(const PPCTargetMachine &TM) { + if (TM.getSubtargetImpl()->isDarwin()) + return new TargetLoweringObjectFileMachO(); + return new TargetLoweringObjectFileELF(); +} + + PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM) - : TargetLowering(TM), PPCSubTarget(*TM.getSubtargetImpl()) { + : TargetLowering(TM, CreateTLOF(TM)), PPCSubTarget(*TM.getSubtargetImpl()) { setPow2DivIsCheap(); @@ -193,9 +203,6 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM) setOperationAction(ISD::ConstantPool, MVT::i64, Custom); setOperationAction(ISD::JumpTable, MVT::i64, Custom); - // RET must be custom lowered, to meet ABI requirements. - setOperationAction(ISD::RET , MVT::Other, Custom); - // TRAP is legal. setOperationAction(ISD::TRAP, MVT::Other, Legal); @@ -205,8 +212,9 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM) // VASTART needs to be custom lowered to use the VarArgsFrameIndex setOperationAction(ISD::VASTART , MVT::Other, Custom); - // VAARG is custom lowered with the SVR4 ABI - if (TM.getSubtarget<PPCSubtarget>().isSVR4ABI()) + // VAARG is custom lowered with the 32-bit SVR4 ABI. + if ( TM.getSubtarget<PPCSubtarget>().isSVR4ABI() + && !TM.getSubtarget<PPCSubtarget>().isPPC64()) setOperationAction(ISD::VAARG, MVT::Other, Custom); else setOperationAction(ISD::VAARG, MVT::Other, Expand); @@ -276,7 +284,7 @@ PPCTargetLowering::PPCTargetLowering(PPCTargetMachine &TM) // will selectively turn on ones that can be effectively codegen'd. for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE; i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) { - MVT VT = (MVT::SimpleValueType)i; + MVT::SimpleValueType VT = (MVT::SimpleValueType)i; // add/sub are legal for all supported vector VT's. setOperationAction(ISD::ADD , VT, Legal); @@ -412,6 +420,7 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const { case PPCISD::VPERM: return "PPCISD::VPERM"; case PPCISD::Hi: return "PPCISD::Hi"; case PPCISD::Lo: return "PPCISD::Lo"; + case PPCISD::TOC_ENTRY: return "PPCISD::TOC_ENTRY"; case PPCISD::DYNALLOC: return "PPCISD::DYNALLOC"; case PPCISD::GlobalBaseReg: return "PPCISD::GlobalBaseReg"; case PPCISD::SRL: return "PPCISD::SRL"; @@ -421,6 +430,7 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const { case PPCISD::STD_32: return "PPCISD::STD_32"; case PPCISD::CALL_SVR4: return "PPCISD::CALL_SVR4"; case PPCISD::CALL_Darwin: return "PPCISD::CALL_Darwin"; + case PPCISD::NOP: return "PPCISD::NOP"; case PPCISD::MTCTR: return "PPCISD::MTCTR"; case PPCISD::BCTRL_Darwin: return "PPCISD::BCTRL_Darwin"; case PPCISD::BCTRL_SVR4: return "PPCISD::BCTRL_SVR4"; @@ -438,12 +448,11 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const { case PPCISD::MTFSB1: return "PPCISD::MTFSB1"; case PPCISD::FADDRTZ: return "PPCISD::FADDRTZ"; case PPCISD::MTFSF: return "PPCISD::MTFSF"; - case PPCISD::TAILCALL: return "PPCISD::TAILCALL"; case PPCISD::TC_RETURN: return "PPCISD::TC_RETURN"; } } -MVT PPCTargetLowering::getSetCCResultType(MVT VT) const { +MVT::SimpleValueType PPCTargetLowering::getSetCCResultType(EVT VT) const { return MVT::i32; } @@ -900,7 +909,7 @@ bool PPCTargetLowering::SelectAddressRegImm(SDValue N, SDValue &Disp, Base = DAG.getTargetConstant((Addr - (signed short)Addr) >> 16, MVT::i32); unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8; - Base = SDValue(DAG.getTargetNode(Opc, dl, CN->getValueType(0), Base), 0); + Base = SDValue(DAG.getMachineNode(Opc, dl, CN->getValueType(0), Base), 0); return true; } } @@ -1012,7 +1021,7 @@ bool PPCTargetLowering::SelectAddressRegImmShift(SDValue N, SDValue &Disp, Disp = DAG.getTargetConstant((short)Addr >> 2, MVT::i32); Base = DAG.getTargetConstant((Addr-(signed short)Addr) >> 16, MVT::i32); unsigned Opc = CN->getValueType(0) == MVT::i32 ? PPC::LIS : PPC::LIS8; - Base = SDValue(DAG.getTargetNode(Opc, dl, CN->getValueType(0), Base),0); + Base = SDValue(DAG.getMachineNode(Opc, dl, CN->getValueType(0), Base),0); return true; } } @@ -1038,7 +1047,7 @@ bool PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base, if (!EnablePPCPreinc) return false; SDValue Ptr; - MVT VT; + EVT VT; if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) { Ptr = LD->getBasePtr(); VT = LD->getMemoryVT(); @@ -1086,7 +1095,7 @@ bool PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue PPCTargetLowering::LowerConstantPool(SDValue Op, SelectionDAG &DAG) { - MVT PtrVT = Op.getValueType(); + EVT PtrVT = Op.getValueType(); ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); Constant *C = CP->getConstVal(); SDValue CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment()); @@ -1120,7 +1129,7 @@ SDValue PPCTargetLowering::LowerConstantPool(SDValue Op, } SDValue PPCTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) { - MVT PtrVT = Op.getValueType(); + EVT PtrVT = Op.getValueType(); JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT); SDValue Zero = DAG.getConstant(0, PtrVT); @@ -1154,13 +1163,13 @@ SDValue PPCTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) { SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) { - assert(0 && "TLS not implemented for PPC."); + llvm_unreachable("TLS not implemented for PPC."); return SDValue(); // Not reached } SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) { - MVT PtrVT = Op.getValueType(); + EVT PtrVT = Op.getValueType(); GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op); GlobalValue *GV = GSDN->getGlobal(); SDValue GA = DAG.getTargetGlobalAddress(GV, PtrVT, GSDN->getOffset()); @@ -1170,6 +1179,13 @@ SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op, const TargetMachine &TM = DAG.getTarget(); + // 64-bit SVR4 ABI code is always position-independent. + // The actual address of the GlobalValue is stored in the TOC. + if (PPCSubTarget.isSVR4ABI() && PPCSubTarget.isPPC64()) { + return DAG.getNode(PPCISD::TOC_ENTRY, dl, MVT::i64, GA, + DAG.getRegister(PPC::X2, MVT::i64)); + } + SDValue Hi = DAG.getNode(PPCISD::Hi, dl, PtrVT, GA, Zero); SDValue Lo = DAG.getNode(PPCISD::Lo, dl, PtrVT, GA, Zero); @@ -1191,7 +1207,7 @@ SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op, Lo = DAG.getNode(ISD::ADD, dl, PtrVT, Hi, Lo); - if (!TM.getSubtarget<PPCSubtarget>().hasLazyResolverStub(GV)) + if (!TM.getSubtarget<PPCSubtarget>().hasLazyResolverStub(GV, TM)) return Lo; // If the global is weak or external, we have to go through the lazy @@ -1208,7 +1224,7 @@ SDValue PPCTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) { // fold the new nodes. if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) { if (C->isNullValue() && CC == ISD::SETEQ) { - MVT VT = Op.getOperand(0).getValueType(); + EVT VT = Op.getOperand(0).getValueType(); SDValue Zext = Op.getOperand(0); if (VT.bitsLT(MVT::i32)) { VT = MVT::i32; @@ -1232,9 +1248,9 @@ SDValue PPCTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) { // condition register, reading it back out, and masking the correct bit. The // normal approach here uses sub to do this instead of xor. Using xor exposes // the result to other bit-twiddling opportunities. - MVT LHSVT = Op.getOperand(0).getValueType(); + EVT LHSVT = Op.getOperand(0).getValueType(); if (LHSVT.isInteger() && (CC == ISD::SETEQ || CC == ISD::SETNE)) { - MVT VT = Op.getValueType(); + EVT VT = Op.getValueType(); SDValue Sub = DAG.getNode(ISD::XOR, dl, LHSVT, Op.getOperand(0), Op.getOperand(1)); return DAG.getSetCC(dl, VT, Sub, DAG.getConstant(0, LHSVT), CC); @@ -1249,7 +1265,7 @@ SDValue PPCTargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG, unsigned VarArgsNumFPR, const PPCSubtarget &Subtarget) { - assert(0 && "VAARG not yet implemented for the SVR4 ABI!"); + llvm_unreachable("VAARG not yet implemented for the SVR4 ABI!"); return SDValue(); // Not reached } @@ -1260,10 +1276,11 @@ SDValue PPCTargetLowering::LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) { SDValue Nest = Op.getOperand(3); // 'nest' parameter value DebugLoc dl = Op.getDebugLoc(); - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = (PtrVT == MVT::i64); const Type *IntPtrTy = - DAG.getTargetLoweringInfo().getTargetData()->getIntPtrType(); + DAG.getTargetLoweringInfo().getTargetData()->getIntPtrType( + *DAG.getContext()); TargetLowering::ArgListTy Args; TargetLowering::ArgListEntry Entry; @@ -1281,8 +1298,9 @@ SDValue PPCTargetLowering::LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) { // Lower to a call to __trampoline_setup(Trmp, TrampSize, FPtr, ctx_reg) std::pair<SDValue, SDValue> CallResult = - LowerCallTo(Chain, Op.getValueType().getTypeForMVT(), false, false, - false, false, 0, CallingConv::C, false, + LowerCallTo(Chain, Op.getValueType().getTypeForEVT(*DAG.getContext()), + false, false, false, false, 0, CallingConv::C, false, + /*isReturnValueUsed=*/true, DAG.getExternalSymbol("__trampoline_setup", PtrVT), Args, DAG, dl); @@ -1300,16 +1318,16 @@ SDValue PPCTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget) { DebugLoc dl = Op.getDebugLoc(); - if (Subtarget.isDarwinABI()) { + if (Subtarget.isDarwinABI() || Subtarget.isPPC64()) { // vastart just stores the address of the VarArgsFrameIndex slot into the // memory location argument. - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); SDValue FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT); const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0); } - // For the SVR4 ABI we follow the layout of the va_list struct. + // For the 32-bit SVR4 ABI we follow the layout of the va_list struct. // We suppose the given va_list is already allocated. // // typedef struct { @@ -1338,7 +1356,7 @@ SDValue PPCTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG, SDValue ArgFPR = DAG.getConstant(VarArgsNumFPR, MVT::i32); - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); SDValue StackOffsetFI = DAG.getFrameIndex(VarArgsStackOffset, PtrVT); SDValue FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT); @@ -1380,15 +1398,15 @@ SDValue PPCTargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG, #include "PPCGenCallingConv.inc" -static bool CC_PPC_SVR4_Custom_Dummy(unsigned &ValNo, MVT &ValVT, MVT &LocVT, +static bool CC_PPC_SVR4_Custom_Dummy(unsigned &ValNo, EVT &ValVT, EVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State) { return true; } -static bool CC_PPC_SVR4_Custom_AlignArgRegs(unsigned &ValNo, MVT &ValVT, - MVT &LocVT, +static bool CC_PPC_SVR4_Custom_AlignArgRegs(unsigned &ValNo, EVT &ValVT, + EVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State) { @@ -1414,8 +1432,8 @@ static bool CC_PPC_SVR4_Custom_AlignArgRegs(unsigned &ValNo, MVT &ValVT, return false; } -static bool CC_PPC_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT, - MVT &LocVT, +static bool CC_PPC_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, EVT &ValVT, + EVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State) { @@ -1442,29 +1460,20 @@ static bool CC_PPC_SVR4_Custom_AlignFPArgRegs(unsigned &ValNo, MVT &ValVT, } /// GetFPR - Get the set of FP registers that should be allocated for arguments, -/// depending on which subtarget is selected. -static const unsigned *GetFPR(const PPCSubtarget &Subtarget) { - if (Subtarget.isDarwinABI()) { - static const unsigned FPR[] = { - PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, - PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 - }; - return FPR; - } - - +/// on Darwin. +static const unsigned *GetFPR() { static const unsigned FPR[] = { PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, - PPC::F8 + PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 }; + return FPR; } /// CalculateStackSlotSize - Calculates the size reserved for this argument on /// the stack. -static unsigned CalculateStackSlotSize(SDValue Arg, ISD::ArgFlagsTy Flags, +static unsigned CalculateStackSlotSize(EVT ArgVT, ISD::ArgFlagsTy Flags, unsigned PtrByteSize) { - MVT ArgVT = Arg.getValueType(); unsigned ArgSize = ArgVT.getSizeInBits()/8; if (Flags.isByVal()) ArgSize = Flags.getByValSize(); @@ -1474,14 +1483,31 @@ static unsigned CalculateStackSlotSize(SDValue Arg, ISD::ArgFlagsTy Flags, } SDValue -PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, - SelectionDAG &DAG, - int &VarArgsFrameIndex, - int &VarArgsStackOffset, - unsigned &VarArgsNumGPR, - unsigned &VarArgsNumFPR, - const PPCSubtarget &Subtarget) { - // SVR4 ABI Stack Frame Layout: +PPCTargetLowering::LowerFormalArguments(SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + if (PPCSubTarget.isSVR4ABI() && !PPCSubTarget.isPPC64()) { + return LowerFormalArguments_SVR4(Chain, CallConv, isVarArg, Ins, + dl, DAG, InVals); + } else { + return LowerFormalArguments_Darwin(Chain, CallConv, isVarArg, Ins, + dl, DAG, InVals); + } +} + +SDValue +PPCTargetLowering::LowerFormalArguments_SVR4( + SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + + // 32-bit SVR4 ABI Stack Frame Layout: // +-----------------------------------+ // +--> | Back chain | // | +-----------------------------------+ @@ -1512,25 +1538,21 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); - SmallVector<SDValue, 8> ArgValues; - SDValue Root = Op.getOperand(0); - bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; - DebugLoc dl = Op.getDebugLoc(); - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); // Potential tail calls could cause overwriting of argument stack slots. - unsigned CC = MF.getFunction()->getCallingConv(); - bool isImmutable = !(PerformTailCallOpt && (CC==CallingConv::Fast)); + bool isImmutable = !(PerformTailCallOpt && (CallConv==CallingConv::Fast)); unsigned PtrByteSize = 4; // Assign locations to all of the incoming arguments. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs, + *DAG.getContext()); // Reserve space for the linkage area on the stack. CCInfo.AllocateStack(PPCFrameInfo::getLinkageSize(false, false), PtrByteSize); - CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_PPC_SVR4); + CCInfo.AnalyzeFormalArguments(Ins, CC_PPC_SVR4); for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; @@ -1538,11 +1560,11 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, // Arguments stored in registers. if (VA.isRegLoc()) { TargetRegisterClass *RC; - MVT ValVT = VA.getValVT(); + EVT ValVT = VA.getValVT(); - switch (ValVT.getSimpleVT()) { + switch (ValVT.getSimpleVT().SimpleTy) { default: - assert(0 && "ValVT not supported by FORMAL_ARGUMENTS Lowering"); + llvm_unreachable("ValVT not supported by formal arguments Lowering"); case MVT::i32: RC = PPC::GPRCRegisterClass; break; @@ -1562,9 +1584,9 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, // Transform the arguments stored in physical registers into virtual ones. unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC); - SDValue ArgValue = DAG.getCopyFromReg(Root, dl, Reg, ValVT); + SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, ValVT); - ArgValues.push_back(ArgValue); + InVals.push_back(ArgValue); } else { // Argument stored in memory. assert(VA.isMemLoc()); @@ -1575,7 +1597,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, // Create load nodes to retrieve arguments from the stack. SDValue FIN = DAG.getFrameIndex(FI, PtrVT); - ArgValues.push_back(DAG.getLoad(VA.getValVT(), dl, Root, FIN, NULL, 0)); + InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0)); } } @@ -1583,12 +1605,13 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, // Aggregates passed by value are stored in the local variable space of the // caller's stack frame, right above the parameter list area. SmallVector<CCValAssign, 16> ByValArgLocs; - CCState CCByValInfo(CC, isVarArg, getTargetMachine(), ByValArgLocs); + CCState CCByValInfo(CallConv, isVarArg, getTargetMachine(), + ByValArgLocs, *DAG.getContext()); // Reserve stack space for the allocations in CCInfo. CCByValInfo.AllocateStack(CCInfo.getNextStackOffset(), PtrByteSize); - CCByValInfo.AnalyzeFormalArguments(Op.getNode(), CC_PPC_SVR4_ByVal); + CCByValInfo.AnalyzeFormalArguments(Ins, CC_PPC_SVR4_ByVal); // Area that is at least reserved in the caller of this function. unsigned MinReservedArea = CCByValInfo.getNextStackOffset(); @@ -1632,7 +1655,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, // Make room for NumGPArgRegs and NumFPArgRegs. int Depth = NumGPArgRegs * PtrVT.getSizeInBits()/8 + - NumFPArgRegs * MVT(MVT::f64).getSizeInBits()/8; + NumFPArgRegs * EVT(MVT::f64).getSizeInBits()/8; VarArgsStackOffset = MFI->CreateFixedObject(PtrVT.getSizeInBits()/8, CCInfo.getNextStackOffset()); @@ -1645,7 +1668,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, unsigned GPRIndex = 0; for (; GPRIndex != VarArgsNumGPR; ++GPRIndex) { SDValue Val = DAG.getRegister(GPArgRegs[GPRIndex], PtrVT); - SDValue Store = DAG.getStore(Root, dl, Val, FIN, NULL, 0); + SDValue Store = DAG.getStore(Chain, dl, Val, FIN, NULL, 0); MemOps.push_back(Store); // Increment the address by four for the next argument to store SDValue PtrOff = DAG.getConstant(PtrVT.getSizeInBits()/8, PtrVT); @@ -1658,7 +1681,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, for (; GPRIndex != NumGPArgRegs; ++GPRIndex) { unsigned VReg = MF.addLiveIn(GPArgRegs[GPRIndex], &PPC::GPRCRegClass); - SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, PtrVT); + SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0); MemOps.push_back(Store); // Increment the address by four for the next argument to store @@ -1666,18 +1689,18 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, FIN = DAG.getNode(ISD::ADD, dl, PtrOff.getValueType(), FIN, PtrOff); } - // FIXME SVR4: We only need to save FP argument registers if CR bit 6 is - // set. + // FIXME 32-bit SVR4: We only need to save FP argument registers if CR bit 6 + // is set. // The double arguments are stored to the VarArgsFrameIndex // on the stack. unsigned FPRIndex = 0; for (FPRIndex = 0; FPRIndex != VarArgsNumFPR; ++FPRIndex) { SDValue Val = DAG.getRegister(FPArgRegs[FPRIndex], MVT::f64); - SDValue Store = DAG.getStore(Root, dl, Val, FIN, NULL, 0); + SDValue Store = DAG.getStore(Chain, dl, Val, FIN, NULL, 0); MemOps.push_back(Store); // Increment the address by eight for the next argument to store - SDValue PtrOff = DAG.getConstant(MVT(MVT::f64).getSizeInBits()/8, + SDValue PtrOff = DAG.getConstant(EVT(MVT::f64).getSizeInBits()/8, PtrVT); FIN = DAG.getNode(ISD::ADD, dl, PtrOff.getValueType(), FIN, PtrOff); } @@ -1685,47 +1708,40 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, for (; FPRIndex != NumFPArgRegs; ++FPRIndex) { unsigned VReg = MF.addLiveIn(FPArgRegs[FPRIndex], &PPC::F8RCRegClass); - SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, MVT::f64); + SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::f64); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0); MemOps.push_back(Store); // Increment the address by eight for the next argument to store - SDValue PtrOff = DAG.getConstant(MVT(MVT::f64).getSizeInBits()/8, + SDValue PtrOff = DAG.getConstant(EVT(MVT::f64).getSizeInBits()/8, PtrVT); FIN = DAG.getNode(ISD::ADD, dl, PtrOff.getValueType(), FIN, PtrOff); } } if (!MemOps.empty()) - Root = DAG.getNode(ISD::TokenFactor, dl, - MVT::Other, &MemOps[0], MemOps.size()); + Chain = DAG.getNode(ISD::TokenFactor, dl, + MVT::Other, &MemOps[0], MemOps.size()); - - ArgValues.push_back(Root); - - // Return the new list of results. - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); + return Chain; } SDValue -PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, - SelectionDAG &DAG, - int &VarArgsFrameIndex, - const PPCSubtarget &Subtarget) { +PPCTargetLowering::LowerFormalArguments_Darwin( + SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { // TODO: add description of PPC stack frame format, or at least some docs. // MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); - SmallVector<SDValue, 8> ArgValues; - SDValue Root = Op.getOperand(0); - bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; - DebugLoc dl = Op.getDebugLoc(); - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; // Potential tail calls could cause overwriting of argument stack slots. - unsigned CC = MF.getFunction()->getCallingConv(); - bool isImmutable = !(PerformTailCallOpt && (CC==CallingConv::Fast)); + bool isImmutable = !(PerformTailCallOpt && (CallConv==CallingConv::Fast)); unsigned PtrByteSize = isPPC64 ? 8 : 4; unsigned ArgOffset = PPCFrameInfo::getLinkageSize(isPPC64, true); @@ -1741,7 +1757,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, PPC::X7, PPC::X8, PPC::X9, PPC::X10, }; - static const unsigned *FPR = GetFPR(Subtarget); + static const unsigned *FPR = GetFPR(); static const unsigned VR[] = { PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8, @@ -1765,12 +1781,11 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, // entire point of the following loop. unsigned VecArgOffset = ArgOffset; if (!isVarArg && !isPPC64) { - for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues()-1; ArgNo != e; + for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) { - MVT ObjectVT = Op.getValue(ArgNo).getValueType(); + EVT ObjectVT = Ins[ArgNo].VT; unsigned ObjSize = ObjectVT.getSizeInBits()/8; - ISD::ArgFlagsTy Flags = - cast<ARG_FLAGSSDNode>(Op.getOperand(ArgNo+3))->getArgFlags(); + ISD::ArgFlagsTy Flags = Ins[ArgNo].Flags; if (Flags.isByVal()) { // ObjSize is the true size, ArgSize rounded up to multiple of regs. @@ -1781,8 +1796,8 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, continue; } - switch(ObjectVT.getSimpleVT()) { - default: assert(0 && "Unhandled argument type!"); + switch(ObjectVT.getSimpleVT().SimpleTy) { + default: llvm_unreachable("Unhandled argument type!"); case MVT::i32: case MVT::f32: VecArgOffset += isPPC64 ? 8 : 4; @@ -1811,15 +1826,13 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, SmallVector<SDValue, 8> MemOps; unsigned nAltivecParamsAtEnd = 0; - for (unsigned ArgNo = 0, e = Op.getNode()->getNumValues() - 1; - ArgNo != e; ++ArgNo) { + for (unsigned ArgNo = 0, e = Ins.size(); ArgNo != e; ++ArgNo) { SDValue ArgVal; bool needsLoad = false; - MVT ObjectVT = Op.getValue(ArgNo).getValueType(); + EVT ObjectVT = Ins[ArgNo].VT; unsigned ObjSize = ObjectVT.getSizeInBits()/8; unsigned ArgSize = ObjSize; - ISD::ArgFlagsTy Flags = - cast<ARG_FLAGSSDNode>(Op.getOperand(ArgNo+3))->getArgFlags(); + ISD::ArgFlagsTy Flags = Ins[ArgNo].Flags; unsigned CurArgOffset = ArgOffset; @@ -1828,13 +1841,13 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, ObjectVT==MVT::v8i16 || ObjectVT==MVT::v16i8) { if (isVarArg || isPPC64) { MinReservedArea = ((MinReservedArea+15)/16)*16; - MinReservedArea += CalculateStackSlotSize(Op.getValue(ArgNo), + MinReservedArea += CalculateStackSlotSize(ObjectVT, Flags, PtrByteSize); } else nAltivecParamsAtEnd++; } else // Calculate min reserved area. - MinReservedArea += CalculateStackSlotSize(Op.getValue(ArgNo), + MinReservedArea += CalculateStackSlotSize(Ins[ArgNo].VT, Flags, PtrByteSize); @@ -1852,11 +1865,11 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, // The value of the object is its address. int FI = MFI->CreateFixedObject(ObjSize, CurArgOffset); SDValue FIN = DAG.getFrameIndex(FI, PtrVT); - ArgValues.push_back(FIN); + InVals.push_back(FIN); if (ObjSize==1 || ObjSize==2) { if (GPR_idx != Num_GPR_Regs) { unsigned VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass); - SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, PtrVT); + SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT); SDValue Store = DAG.getTruncStore(Val.getValue(1), dl, Val, FIN, NULL, 0, ObjSize==1 ? MVT::i8 : MVT::i16 ); MemOps.push_back(Store); @@ -1875,7 +1888,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, unsigned VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass); int FI = MFI->CreateFixedObject(PtrByteSize, ArgOffset); SDValue FIN = DAG.getFrameIndex(FI, PtrVT); - SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, PtrVT); + SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0); MemOps.push_back(Store); ++GPR_idx; @@ -1888,13 +1901,13 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, continue; } - switch (ObjectVT.getSimpleVT()) { - default: assert(0 && "Unhandled argument type!"); + switch (ObjectVT.getSimpleVT().SimpleTy) { + default: llvm_unreachable("Unhandled argument type!"); case MVT::i32: if (!isPPC64) { if (GPR_idx != Num_GPR_Regs) { unsigned VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass); - ArgVal = DAG.getCopyFromReg(Root, dl, VReg, MVT::i32); + ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); ++GPR_idx; } else { needsLoad = true; @@ -1908,7 +1921,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, case MVT::i64: // PPC64 if (GPR_idx != Num_GPR_Regs) { unsigned VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::G8RCRegClass); - ArgVal = DAG.getCopyFromReg(Root, dl, VReg, MVT::i64); + ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i64); if (ObjectVT == MVT::i32) { // PPC64 passes i8, i16, and i32 values in i64 registers. Promote @@ -1949,7 +1962,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, else VReg = MF.addLiveIn(FPR[FPR_idx], &PPC::F8RCRegClass); - ArgVal = DAG.getCopyFromReg(Root, dl, VReg, ObjectVT); + ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, ObjectVT); ++FPR_idx; } else { needsLoad = true; @@ -1966,7 +1979,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, // except in varargs functions. if (VR_idx != Num_VR_Regs) { unsigned VReg = MF.addLiveIn(VR[VR_idx], &PPC::VRRCRegClass); - ArgVal = DAG.getCopyFromReg(Root, dl, VReg, ObjectVT); + ArgVal = DAG.getCopyFromReg(Chain, dl, VReg, ObjectVT); if (isVarArg) { while ((ArgOffset % 16) != 0) { ArgOffset += PtrByteSize; @@ -1974,7 +1987,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, GPR_idx++; } ArgOffset += 16; - GPR_idx = std::min(GPR_idx+4, Num_GPR_Regs); + GPR_idx = std::min(GPR_idx+4, Num_GPR_Regs); // FIXME correct for ppc64? } ++VR_idx; } else { @@ -2000,10 +2013,10 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, CurArgOffset + (ArgSize - ObjSize), isImmutable); SDValue FIN = DAG.getFrameIndex(FI, PtrVT); - ArgVal = DAG.getLoad(ObjectVT, dl, Root, FIN, NULL, 0); + ArgVal = DAG.getLoad(ObjectVT, dl, Chain, FIN, NULL, 0); } - ArgValues.push_back(ArgVal); + InVals.push_back(ArgVal); } // Set the size that is at least reserved in caller of this function. Tail @@ -2045,7 +2058,7 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, else VReg = MF.addLiveIn(GPR[GPR_idx], &PPC::GPRCRegClass); - SDValue Val = DAG.getCopyFromReg(Root, dl, VReg, PtrVT); + SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, PtrVT); SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0); MemOps.push_back(Store); // Increment the address by four for the next argument to store @@ -2055,14 +2068,10 @@ PPCTargetLowering::LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, } if (!MemOps.empty()) - Root = DAG.getNode(ISD::TokenFactor, dl, - MVT::Other, &MemOps[0], MemOps.size()); - - ArgValues.push_back(Root); + Chain = DAG.getNode(ISD::TokenFactor, dl, + MVT::Other, &MemOps[0], MemOps.size()); - // Return the new list of results. - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()); + return Chain; } /// CalculateParameterAndLinkageAreaSize - Get the size of the paramter plus @@ -2072,13 +2081,14 @@ CalculateParameterAndLinkageAreaSize(SelectionDAG &DAG, bool isPPC64, bool isVarArg, unsigned CC, - CallSDNode *TheCall, + const SmallVectorImpl<ISD::OutputArg> + &Outs, unsigned &nAltivecParamsAtEnd) { // Count how many bytes are to be pushed on the stack, including the linkage // area, and parameter passing area. We start with 24/48 bytes, which is // prereserved space for [SP][CR][LR][3 x unused]. unsigned NumBytes = PPCFrameInfo::getLinkageSize(isPPC64, true); - unsigned NumOps = TheCall->getNumArgs(); + unsigned NumOps = Outs.size(); unsigned PtrByteSize = isPPC64 ? 8 : 4; // Add up all the space actually used. @@ -2089,9 +2099,9 @@ CalculateParameterAndLinkageAreaSize(SelectionDAG &DAG, // 16-byte aligned. nAltivecParamsAtEnd = 0; for (unsigned i = 0; i != NumOps; ++i) { - SDValue Arg = TheCall->getArg(i); - ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); - MVT ArgVT = Arg.getValueType(); + SDValue Arg = Outs[i].Val; + ISD::ArgFlagsTy Flags = Outs[i].Flags; + EVT ArgVT = Arg.getValueType(); // Varargs Altivec parameters are padded to a 16 byte boundary. if (ArgVT==MVT::v4f32 || ArgVT==MVT::v4i32 || ArgVT==MVT::v8i16 || ArgVT==MVT::v16i8) { @@ -2104,7 +2114,7 @@ CalculateParameterAndLinkageAreaSize(SelectionDAG &DAG, // Varargs and 64-bit Altivec parameters are padded to 16 byte boundary. NumBytes = ((NumBytes+15)/16)*16; } - NumBytes += CalculateStackSlotSize(Arg, Flags, PtrByteSize); + NumBytes += CalculateStackSlotSize(ArgVT, Flags, PtrByteSize); } // Allow for Altivec parameters at the end, if needed. @@ -2149,40 +2159,37 @@ static int CalculateTailCallSPDiff(SelectionDAG& DAG, bool IsTailCall, return SPDiff; } -/// IsEligibleForTailCallElimination - Check to see whether the next instruction -/// following the call is a return. A function is eligible if caller/callee -/// calling conventions match, currently only fastcc supports tail calls, and -/// the function CALL is immediatly followed by a RET. +/// IsEligibleForTailCallOptimization - Check whether the call is eligible +/// for tail call optimization. Targets which want to do tail call +/// optimization should implement this function. bool -PPCTargetLowering::IsEligibleForTailCallOptimization(CallSDNode *TheCall, - SDValue Ret, +PPCTargetLowering::IsEligibleForTailCallOptimization(SDValue Callee, + CallingConv::ID CalleeCC, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const { // Variable argument functions are not supported. - if (!PerformTailCallOpt || TheCall->isVarArg()) + if (isVarArg) return false; - if (CheckTailCallReturnConstraints(TheCall, Ret)) { - MachineFunction &MF = DAG.getMachineFunction(); - unsigned CallerCC = MF.getFunction()->getCallingConv(); - unsigned CalleeCC = TheCall->getCallingConv(); - if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC) { - // Functions containing by val parameters are not supported. - for (unsigned i = 0; i != TheCall->getNumArgs(); i++) { - ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); - if (Flags.isByVal()) return false; - } + MachineFunction &MF = DAG.getMachineFunction(); + CallingConv::ID CallerCC = MF.getFunction()->getCallingConv(); + if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC) { + // Functions containing by val parameters are not supported. + for (unsigned i = 0; i != Ins.size(); i++) { + ISD::ArgFlagsTy Flags = Ins[i].Flags; + if (Flags.isByVal()) return false; + } - SDValue Callee = TheCall->getCallee(); - // Non PIC/GOT tail calls are supported. - if (getTargetMachine().getRelocationModel() != Reloc::PIC_) - return true; + // Non PIC/GOT tail calls are supported. + if (getTargetMachine().getRelocationModel() != Reloc::PIC_) + return true; - // At the moment we can only do local tail calls (in same module, hidden - // or protected) if we are generating PIC. - if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) - return G->getGlobal()->hasHiddenVisibility() - || G->getGlobal()->hasProtectedVisibility(); - } + // At the moment we can only do local tail calls (in same module, hidden + // or protected) if we are generating PIC. + if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) + return G->getGlobal()->hasHiddenVisibility() + || G->getGlobal()->hasProtectedVisibility(); } return false; @@ -2251,13 +2258,13 @@ static SDValue EmitTailCallStoreFPAndRetAddr(SelectionDAG &DAG, isDarwinABI); int NewRetAddr = MF.getFrameInfo()->CreateFixedObject(SlotSize, NewRetAddrLoc); - MVT VT = isPPC64 ? MVT::i64 : MVT::i32; + EVT VT = isPPC64 ? MVT::i64 : MVT::i32; SDValue NewRetAddrFrIdx = DAG.getFrameIndex(NewRetAddr, VT); Chain = DAG.getStore(Chain, dl, OldRetAddr, NewRetAddrFrIdx, PseudoSourceValue::getFixedStack(NewRetAddr), 0); - // When using the SVR4 ABI there is no need to move the FP stack slot - // as the FP is never overwritten. + // When using the 32/64-bit SVR4 ABI there is no need to move the FP stack + // slot as the FP is never overwritten. if (isDarwinABI) { int NewFPLoc = SPDiff + PPCFrameInfo::getFramePointerSaveOffset(isPPC64, isDarwinABI); @@ -2279,7 +2286,7 @@ CalculateTailCallArgDest(SelectionDAG &DAG, MachineFunction &MF, bool isPPC64, int Offset = ArgOffset + SPDiff; uint32_t OpSize = (Arg.getValueType().getSizeInBits()+7)/8; int FI = MF.getFrameInfo()->CreateFixedObject(OpSize, Offset); - MVT VT = isPPC64 ? MVT::i64 : MVT::i32; + EVT VT = isPPC64 ? MVT::i64 : MVT::i32; SDValue FIN = DAG.getFrameIndex(FI, VT); TailCallArgumentInfo Info; Info.Arg = Arg; @@ -2300,13 +2307,13 @@ SDValue PPCTargetLowering::EmitTailCallLoadFPAndRetAddr(SelectionDAG & DAG, DebugLoc dl) { if (SPDiff) { // Load the LR and FP stack slot for later adjusting. - MVT VT = PPCSubTarget.isPPC64() ? MVT::i64 : MVT::i32; + EVT VT = PPCSubTarget.isPPC64() ? MVT::i64 : MVT::i32; LROpOut = getReturnAddrFrameIndex(DAG); LROpOut = DAG.getLoad(VT, dl, Chain, LROpOut, NULL, 0); Chain = SDValue(LROpOut.getNode(), 1); - // When using the SVR4 ABI there is no need to load the FP stack slot - // as the FP is never overwritten. + // When using the 32/64-bit SVR4 ABI there is no need to load the FP stack + // slot as the FP is never overwritten. if (isDarwinABI) { FPOpOut = getFramePointerFrameIndex(DAG); FPOpOut = DAG.getLoad(VT, dl, Chain, FPOpOut, NULL, 0); @@ -2340,7 +2347,7 @@ LowerMemOpCallTo(SelectionDAG &DAG, MachineFunction &MF, SDValue Chain, bool isVector, SmallVector<SDValue, 8> &MemOpChains, SmallVector<TailCallArgumentInfo, 8>& TailCallArguments, DebugLoc dl) { - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); if (!isTailCall) { if (isVector) { SDValue StackPtr; @@ -2389,9 +2396,9 @@ static unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag, SDValue &Chain, DebugLoc dl, int SPDiff, bool isTailCall, SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass, - SmallVector<SDValue, 8> &Ops, std::vector<MVT> &NodeTys, + SmallVector<SDValue, 8> &Ops, std::vector<EVT> &NodeTys, bool isSVR4ABI) { - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); NodeTys.push_back(MVT::Other); // Returns a chain NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. @@ -2444,102 +2451,145 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag, return CallOpc; } -static SDValue LowerCallReturn(SDValue Op, SelectionDAG &DAG, TargetMachine &TM, - CallSDNode *TheCall, SDValue Chain, - SDValue InFlag) { - bool isVarArg = TheCall->isVarArg(); - DebugLoc dl = TheCall->getDebugLoc(); - SmallVector<SDValue, 16> ResultVals; +SDValue +PPCTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + SmallVector<CCValAssign, 16> RVLocs; - unsigned CallerCC = DAG.getMachineFunction().getFunction()->getCallingConv(); - CCState CCRetInfo(CallerCC, isVarArg, TM, RVLocs); - CCRetInfo.AnalyzeCallResult(TheCall, RetCC_PPC); + CCState CCRetInfo(CallConv, isVarArg, getTargetMachine(), + RVLocs, *DAG.getContext()); + CCRetInfo.AnalyzeCallResult(Ins, RetCC_PPC); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) { CCValAssign &VA = RVLocs[i]; - MVT VT = VA.getValVT(); + EVT VT = VA.getValVT(); assert(VA.isRegLoc() && "Can only return in registers!"); Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VT, InFlag).getValue(1); - ResultVals.push_back(Chain.getValue(0)); + InVals.push_back(Chain.getValue(0)); InFlag = Chain.getValue(2); } - // If the function returns void, just return the chain. - if (RVLocs.empty()) - return Chain; - - // Otherwise, merge everything together with a MERGE_VALUES node. - ResultVals.push_back(Chain); - SDValue Res = DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(), - &ResultVals[0], ResultVals.size()); - return Res.getValue(Op.getResNo()); + return Chain; } -static -SDValue FinishCall(SelectionDAG &DAG, CallSDNode *TheCall, TargetMachine &TM, - SmallVector<std::pair<unsigned, SDValue>, 8> &RegsToPass, - SDValue Op, SDValue InFlag, SDValue Chain, SDValue &Callee, - int SPDiff, unsigned NumBytes) { - unsigned CC = TheCall->getCallingConv(); - DebugLoc dl = TheCall->getDebugLoc(); - bool isTailCall = TheCall->isTailCall() - && CC == CallingConv::Fast && PerformTailCallOpt; - - std::vector<MVT> NodeTys; +SDValue +PPCTargetLowering::FinishCall(CallingConv::ID CallConv, DebugLoc dl, + bool isTailCall, bool isVarArg, + SelectionDAG &DAG, + SmallVector<std::pair<unsigned, SDValue>, 8> + &RegsToPass, + SDValue InFlag, SDValue Chain, + SDValue &Callee, + int SPDiff, unsigned NumBytes, + const SmallVectorImpl<ISD::InputArg> &Ins, + SmallVectorImpl<SDValue> &InVals) { + std::vector<EVT> NodeTys; SmallVector<SDValue, 8> Ops; unsigned CallOpc = PrepareCall(DAG, Callee, InFlag, Chain, dl, SPDiff, isTailCall, RegsToPass, Ops, NodeTys, - TM.getSubtarget<PPCSubtarget>().isSVR4ABI()); + PPCSubTarget.isSVR4ABI()); // When performing tail call optimization the callee pops its arguments off // the stack. Account for this here so these bytes can be pushed back on in // PPCRegisterInfo::eliminateCallFramePseudoInstr. int BytesCalleePops = - (CC==CallingConv::Fast && PerformTailCallOpt) ? NumBytes : 0; + (CallConv==CallingConv::Fast && PerformTailCallOpt) ? NumBytes : 0; if (InFlag.getNode()) Ops.push_back(InFlag); // Emit tail call. if (isTailCall) { - assert(InFlag.getNode() && - "Flag must be set. Depend on flag being set in LowerRET"); - Chain = DAG.getNode(PPCISD::TAILCALL, dl, - TheCall->getVTList(), &Ops[0], Ops.size()); - return SDValue(Chain.getNode(), Op.getResNo()); + // If this is the first return lowered for this function, add the regs + // to the liveout set for the function. + if (DAG.getMachineFunction().getRegInfo().liveout_empty()) { + SmallVector<CCValAssign, 16> RVLocs; + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), RVLocs, + *DAG.getContext()); + CCInfo.AnalyzeCallResult(Ins, RetCC_PPC); + for (unsigned i = 0; i != RVLocs.size(); ++i) + DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); + } + + assert(((Callee.getOpcode() == ISD::Register && + cast<RegisterSDNode>(Callee)->getReg() == PPC::CTR) || + Callee.getOpcode() == ISD::TargetExternalSymbol || + Callee.getOpcode() == ISD::TargetGlobalAddress || + isa<ConstantSDNode>(Callee)) && + "Expecting an global address, external symbol, absolute value or register"); + + return DAG.getNode(PPCISD::TC_RETURN, dl, MVT::Other, &Ops[0], Ops.size()); } Chain = DAG.getNode(CallOpc, dl, NodeTys, &Ops[0], Ops.size()); InFlag = Chain.getValue(1); + // Add a NOP immediately after the branch instruction when using the 64-bit + // SVR4 ABI. At link time, if caller and callee are in a different module and + // thus have a different TOC, the call will be replaced with a call to a stub + // function which saves the current TOC, loads the TOC of the callee and + // branches to the callee. The NOP will be replaced with a load instruction + // which restores the TOC of the caller from the TOC save slot of the current + // stack frame. If caller and callee belong to the same module (and have the + // same TOC), the NOP will remain unchanged. + if (!isTailCall && PPCSubTarget.isSVR4ABI()&& PPCSubTarget.isPPC64()) { + // Insert NOP. + InFlag = DAG.getNode(PPCISD::NOP, dl, MVT::Flag, InFlag); + } + Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true), DAG.getIntPtrConstant(BytesCalleePops, true), InFlag); - if (TheCall->getValueType(0) != MVT::Other) + if (!Ins.empty()) InFlag = Chain.getValue(1); - return LowerCallReturn(Op, DAG, TM, TheCall, Chain, InFlag); + return LowerCallResult(Chain, InFlag, CallConv, isVarArg, + Ins, dl, DAG, InVals); +} + +SDValue +PPCTargetLowering::LowerCall(SDValue Chain, SDValue Callee, + CallingConv::ID CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + if (PPCSubTarget.isSVR4ABI() && !PPCSubTarget.isPPC64()) { + return LowerCall_SVR4(Chain, Callee, CallConv, isVarArg, + isTailCall, Outs, Ins, + dl, DAG, InVals); + } else { + return LowerCall_Darwin(Chain, Callee, CallConv, isVarArg, + isTailCall, Outs, Ins, + dl, DAG, InVals); + } } -SDValue PPCTargetLowering::LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, - const PPCSubtarget &Subtarget, - TargetMachine &TM) { - // See PPCTargetLowering::LowerFORMAL_ARGUMENTS_SVR4() for a description - // of the SVR4 ABI stack frame layout. - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - SDValue Chain = TheCall->getChain(); - bool isVarArg = TheCall->isVarArg(); - unsigned CC = TheCall->getCallingConv(); - assert((CC == CallingConv::C || - CC == CallingConv::Fast) && "Unknown calling convention!"); - bool isTailCall = TheCall->isTailCall() - && CC == CallingConv::Fast && PerformTailCallOpt; - SDValue Callee = TheCall->getCallee(); - DebugLoc dl = TheCall->getDebugLoc(); - - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); +SDValue +PPCTargetLowering::LowerCall_SVR4(SDValue Chain, SDValue Callee, + CallingConv::ID CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + // See PPCTargetLowering::LowerFormalArguments_SVR4() for a description + // of the 32-bit SVR4 ABI stack frame layout. + + assert((!isTailCall || + (CallConv == CallingConv::Fast && PerformTailCallOpt)) && + "IsEligibleForTailCallOptimization missed a case!"); + + assert((CallConv == CallingConv::C || + CallConv == CallingConv::Fast) && "Unknown calling convention!"); + + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); unsigned PtrByteSize = 4; MachineFunction &MF = DAG.getMachineFunction(); @@ -2549,7 +2599,7 @@ SDValue PPCTargetLowering::LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, // and restoring the callers stack pointer in this functions epilog. This is // done because by tail calling the called function might overwrite the value // in this function's (MF) stack pointer stack slot 0(SP). - if (PerformTailCallOpt && CC==CallingConv::Fast) + if (PerformTailCallOpt && CallConv==CallingConv::Fast) MF.getInfo<PPCFunctionInfo>()->setHasFastCall(); // Count how many bytes are to be pushed on the stack, including the linkage @@ -2558,7 +2608,8 @@ SDValue PPCTargetLowering::LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, // Assign locations to all of the outgoing arguments. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); // Reserve space for the linkage area on the stack. CCInfo.AllocateStack(PPCFrameInfo::getLinkageSize(false, false), PtrByteSize); @@ -2567,15 +2618,14 @@ SDValue PPCTargetLowering::LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, // Handle fixed and variable vector arguments differently. // Fixed vector arguments go into registers as long as registers are // available. Variable vector arguments always go into memory. - unsigned NumArgs = TheCall->getNumArgs(); - unsigned NumFixedArgs = TheCall->getNumFixedArgs(); + unsigned NumArgs = Outs.size(); for (unsigned i = 0; i != NumArgs; ++i) { - MVT ArgVT = TheCall->getArg(i).getValueType(); - ISD::ArgFlagsTy ArgFlags = TheCall->getArgFlags(i); + EVT ArgVT = Outs[i].Val.getValueType(); + ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; bool Result; - if (i < NumFixedArgs) { + if (Outs[i].IsFixed) { Result = CC_PPC_SVR4(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, CCInfo); } else { @@ -2584,24 +2634,27 @@ SDValue PPCTargetLowering::LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, } if (Result) { - cerr << "Call operand #" << i << " has unhandled type " - << ArgVT.getMVTString() << "\n"; - abort(); +#ifndef NDEBUG + errs() << "Call operand #" << i << " has unhandled type " + << ArgVT.getEVTString() << "\n"; +#endif + llvm_unreachable(0); } } } else { // All arguments are treated the same. - CCInfo.AnalyzeCallOperands(TheCall, CC_PPC_SVR4); + CCInfo.AnalyzeCallOperands(Outs, CC_PPC_SVR4); } // Assign locations to all of the outgoing aggregate by value arguments. SmallVector<CCValAssign, 16> ByValArgLocs; - CCState CCByValInfo(CC, isVarArg, getTargetMachine(), ByValArgLocs); + CCState CCByValInfo(CallConv, isVarArg, getTargetMachine(), ByValArgLocs, + *DAG.getContext()); // Reserve stack space for the allocations in CCInfo. CCByValInfo.AllocateStack(CCInfo.getNextStackOffset(), PtrByteSize); - CCByValInfo.AnalyzeCallOperands(TheCall, CC_PPC_SVR4_ByVal); + CCByValInfo.AnalyzeCallOperands(Outs, CC_PPC_SVR4_ByVal); // Size of the linkage area, parameter list area and the part of the local // space variable where copies of aggregates which are passed by value are @@ -2637,8 +2690,8 @@ SDValue PPCTargetLowering::LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, i != e; ++i) { CCValAssign &VA = ArgLocs[i]; - SDValue Arg = TheCall->getArg(i); - ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); + SDValue Arg = Outs[i].Val; + ISD::ArgFlagsTy Flags = Outs[i].Flags; if (Flags.isByVal()) { // Argument is an aggregate which is passed by value, thus we need to @@ -2712,7 +2765,7 @@ SDValue PPCTargetLowering::LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, // Set CR6 to true if this is a vararg call. if (isVarArg) { - SDValue SetCR(DAG.getTargetNode(PPC::CRSET, dl, MVT::i32), 0); + SDValue SetCR(DAG.getMachineNode(PPC::CRSET, dl, MVT::i32), 0); Chain = DAG.getCopyToReg(Chain, dl, PPC::CR1EQ, SetCR, InFlag); InFlag = Chain.getValue(1); } @@ -2722,24 +2775,23 @@ SDValue PPCTargetLowering::LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, false, TailCallArguments); } - return FinishCall(DAG, TheCall, TM, RegsToPass, Op, InFlag, Chain, Callee, - SPDiff, NumBytes); + return FinishCall(CallConv, dl, isTailCall, isVarArg, DAG, + RegsToPass, InFlag, Chain, Callee, SPDiff, NumBytes, + Ins, InVals); } -SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, - const PPCSubtarget &Subtarget, - TargetMachine &TM) { - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - SDValue Chain = TheCall->getChain(); - bool isVarArg = TheCall->isVarArg(); - unsigned CC = TheCall->getCallingConv(); - bool isTailCall = TheCall->isTailCall() - && CC == CallingConv::Fast && PerformTailCallOpt; - SDValue Callee = TheCall->getCallee(); - unsigned NumOps = TheCall->getNumArgs(); - DebugLoc dl = TheCall->getDebugLoc(); - - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); +SDValue +PPCTargetLowering::LowerCall_Darwin(SDValue Chain, SDValue Callee, + CallingConv::ID CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + + unsigned NumOps = Outs.size(); + + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; unsigned PtrByteSize = isPPC64 ? 8 : 4; @@ -2750,7 +2802,7 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, // and restoring the callers stack pointer in this functions epilog. This is // done because by tail calling the called function might overwrite the value // in this function's (MF) stack pointer stack slot 0(SP). - if (PerformTailCallOpt && CC==CallingConv::Fast) + if (PerformTailCallOpt && CallConv==CallingConv::Fast) MF.getInfo<PPCFunctionInfo>()->setHasFastCall(); unsigned nAltivecParamsAtEnd = 0; @@ -2759,13 +2811,19 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, // area, and parameter passing area. We start with 24/48 bytes, which is // prereserved space for [SP][CR][LR][3 x unused]. unsigned NumBytes = - CalculateParameterAndLinkageAreaSize(DAG, isPPC64, isVarArg, CC, TheCall, + CalculateParameterAndLinkageAreaSize(DAG, isPPC64, isVarArg, CallConv, + Outs, nAltivecParamsAtEnd); // Calculate by how many bytes the stack has to be adjusted in case of tail // call optimization. int SPDiff = CalculateTailCallSPDiff(DAG, isTailCall, NumBytes); + // To protect arguments on the stack from being clobbered in a tail call, + // force all the loads to happen before doing any other lowering. + if (isTailCall) + Chain = DAG.getStackArgumentTokenFactor(Chain); + // Adjust the stack pointer for the new arguments... // These operations are automatically eliminated by the prolog/epilog pass Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true)); @@ -2801,7 +2859,7 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, PPC::X3, PPC::X4, PPC::X5, PPC::X6, PPC::X7, PPC::X8, PPC::X9, PPC::X10, }; - static const unsigned *FPR = GetFPR(Subtarget); + static const unsigned *FPR = GetFPR(); static const unsigned VR[] = { PPC::V2, PPC::V3, PPC::V4, PPC::V5, PPC::V6, PPC::V7, PPC::V8, @@ -2818,9 +2876,8 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, SmallVector<SDValue, 8> MemOpChains; for (unsigned i = 0; i != NumOps; ++i) { - bool inMem = false; - SDValue Arg = TheCall->getArg(i); - ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i); + SDValue Arg = Outs[i].Val; + ISD::ArgFlagsTy Flags = Outs[i].Flags; // PtrOff will be used to store the current argument to the stack if a // register cannot be found for it. @@ -2843,7 +2900,7 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, if (Size==1 || Size==2) { // Very small objects are passed right-justified. // Everything else is passed left-justified. - MVT VT = (Size==1) ? MVT::i8 : MVT::i16; + EVT VT = (Size==1) ? MVT::i8 : MVT::i16; if (GPR_idx != NumGPRs) { SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, PtrVT, Chain, Arg, NULL, 0, VT); @@ -2895,8 +2952,8 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, continue; } - switch (Arg.getValueType().getSimpleVT()) { - default: assert(0 && "Unexpected ValueType for argument!"); + switch (Arg.getValueType().getSimpleVT().SimpleTy) { + default: llvm_unreachable("Unexpected ValueType for argument!"); case MVT::i32: case MVT::i64: if (GPR_idx != NumGPRs) { @@ -2905,7 +2962,6 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, LowerMemOpCallTo(DAG, MF, Chain, Arg, PtrOff, SPDiff, ArgOffset, isPPC64, isTailCall, false, MemOpChains, TailCallArguments, dl); - inMem = true; } ArgOffset += PtrByteSize; break; @@ -2945,7 +3001,6 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, LowerMemOpCallTo(DAG, MF, Chain, Arg, PtrOff, SPDiff, ArgOffset, isPPC64, isTailCall, false, MemOpChains, TailCallArguments, dl); - inMem = true; } if (isPPC64) ArgOffset += 8; @@ -3017,8 +3072,8 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, ArgOffset = ((ArgOffset+15)/16)*16; ArgOffset += 12*16; for (unsigned i = 0; i != NumOps; ++i) { - SDValue Arg = TheCall->getArg(i); - MVT ArgType = Arg.getValueType(); + SDValue Arg = Outs[i].Val; + EVT ArgType = Arg.getValueType(); if (ArgType==MVT::v4f32 || ArgType==MVT::v4i32 || ArgType==MVT::v8i16 || ArgType==MVT::v16i8) { if (++j > NumVRs) { @@ -3051,18 +3106,21 @@ SDValue PPCTargetLowering::LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, FPOp, true, TailCallArguments); } - return FinishCall(DAG, TheCall, TM, RegsToPass, Op, InFlag, Chain, Callee, - SPDiff, NumBytes); + return FinishCall(CallConv, dl, isTailCall, isVarArg, DAG, + RegsToPass, InFlag, Chain, Callee, SPDiff, NumBytes, + Ins, InVals); } -SDValue PPCTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG, - TargetMachine &TM) { +SDValue +PPCTargetLowering::LowerReturn(SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + SmallVector<CCValAssign, 16> RVLocs; - unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); - bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); - DebugLoc dl = Op.getDebugLoc(); - CCState CCInfo(CC, isVarArg, TM, RVLocs); - CCInfo.AnalyzeReturn(Op.getNode(), RetCC_PPC); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + RVLocs, *DAG.getContext()); + CCInfo.AnalyzeReturn(Outs, RetCC_PPC); // If this is the first return lowered for this function, add the regs to the // liveout set for the function. @@ -3071,37 +3129,6 @@ SDValue PPCTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG, DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } - SDValue Chain = Op.getOperand(0); - - Chain = GetPossiblePreceedingTailCall(Chain, PPCISD::TAILCALL); - if (Chain.getOpcode() == PPCISD::TAILCALL) { - SDValue TailCall = Chain; - SDValue TargetAddress = TailCall.getOperand(1); - SDValue StackAdjustment = TailCall.getOperand(2); - - assert(((TargetAddress.getOpcode() == ISD::Register && - cast<RegisterSDNode>(TargetAddress)->getReg() == PPC::CTR) || - TargetAddress.getOpcode() == ISD::TargetExternalSymbol || - TargetAddress.getOpcode() == ISD::TargetGlobalAddress || - isa<ConstantSDNode>(TargetAddress)) && - "Expecting an global address, external symbol, absolute value or register"); - - assert(StackAdjustment.getOpcode() == ISD::Constant && - "Expecting a const value"); - - SmallVector<SDValue,8> Operands; - Operands.push_back(Chain.getOperand(0)); - Operands.push_back(TargetAddress); - Operands.push_back(StackAdjustment); - // Copy registers used by the call. Last operand is a flag so it is not - // copied. - for (unsigned i=3; i < TailCall.getNumOperands()-1; i++) { - Operands.push_back(Chain.getOperand(i)); - } - return DAG.getNode(PPCISD::TC_RETURN, dl, MVT::Other, &Operands[0], - Operands.size()); - } - SDValue Flag; // Copy the result values into the output registers. @@ -3109,7 +3136,7 @@ SDValue PPCTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG, CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), - Op.getOperand(i*2+1), Flag); + Outs[i].Val, Flag); Flag = Chain.getValue(1); } @@ -3125,7 +3152,7 @@ SDValue PPCTargetLowering::LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG, DebugLoc dl = Op.getDebugLoc(); // Get the corect type for pointers. - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); // Construct the stack pointer operand. bool IsPPC64 = Subtarget.isPPC64(); @@ -3153,7 +3180,7 @@ PPCTargetLowering::getReturnAddrFrameIndex(SelectionDAG & DAG) const { MachineFunction &MF = DAG.getMachineFunction(); bool IsPPC64 = PPCSubTarget.isPPC64(); bool isDarwinABI = PPCSubTarget.isDarwinABI(); - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); // Get current frame pointer save index. The users of this index will be // primarily DYNALLOC instructions. @@ -3177,7 +3204,7 @@ PPCTargetLowering::getFramePointerFrameIndex(SelectionDAG & DAG) const { MachineFunction &MF = DAG.getMachineFunction(); bool IsPPC64 = PPCSubTarget.isPPC64(); bool isDarwinABI = PPCSubTarget.isDarwinABI(); - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); // Get current frame pointer save index. The users of this index will be // primarily DYNALLOC instructions. @@ -3207,7 +3234,7 @@ SDValue PPCTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op, DebugLoc dl = Op.getDebugLoc(); // Get the corect type for pointers. - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); // Negate the size. SDValue NegSize = DAG.getNode(ISD::SUB, dl, PtrVT, DAG.getConstant(0, PtrVT), Size); @@ -3232,8 +3259,8 @@ SDValue PPCTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) { // Cannot handle SETEQ/SETNE. if (CC == ISD::SETEQ || CC == ISD::SETNE) return Op; - MVT ResVT = Op.getValueType(); - MVT CmpVT = Op.getOperand(0).getValueType(); + EVT ResVT = Op.getValueType(); + EVT CmpVT = Op.getOperand(0).getValueType(); SDValue LHS = Op.getOperand(0), RHS = Op.getOperand(1); SDValue TV = Op.getOperand(2), FV = Op.getOperand(3); DebugLoc dl = Op.getDebugLoc(); @@ -3302,8 +3329,8 @@ SDValue PPCTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG, Src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Src); SDValue Tmp; - switch (Op.getValueType().getSimpleVT()) { - default: assert(0 && "Unhandled FP_TO_INT type in custom expander!"); + switch (Op.getValueType().getSimpleVT().SimpleTy) { + default: llvm_unreachable("Unhandled FP_TO_INT type in custom expander!"); case MVT::i32: Tmp = DAG.getNode(Op.getOpcode()==ISD::FP_TO_SINT ? PPCISD::FCTIWZ : PPCISD::FCTIDZ, @@ -3350,20 +3377,23 @@ SDValue PPCTargetLowering::LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) { // 64-bit registers. In particular, sign extend the input value into the // 64-bit register with extsw, store the WHOLE 64-bit value into the stack // then lfd it and fcfid it. - MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo(); + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo *FrameInfo = MF.getFrameInfo(); int FrameIdx = FrameInfo->CreateStackObject(8, 8); - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); SDValue FIdx = DAG.getFrameIndex(FrameIdx, PtrVT); SDValue Ext64 = DAG.getNode(PPCISD::EXTSW_32, dl, MVT::i32, Op.getOperand(0)); // STD the extended value into the stack slot. - MachineMemOperand MO(PseudoSourceValue::getFixedStack(FrameIdx), - MachineMemOperand::MOStore, 0, 8, 8); - SDValue Store = DAG.getNode(PPCISD::STD_32, dl, MVT::Other, - DAG.getEntryNode(), Ext64, FIdx, - DAG.getMemOperand(MO)); + MachineMemOperand *MMO = + MF.getMachineMemOperand(PseudoSourceValue::getFixedStack(FrameIdx), + MachineMemOperand::MOStore, 0, 8, 8); + SDValue Ops[] = { DAG.getEntryNode(), Ext64, FIdx }; + SDValue Store = + DAG.getMemIntrinsicNode(PPCISD::STD_32, dl, DAG.getVTList(MVT::Other), + Ops, 4, MVT::i64, MMO); // Load the value as a double. SDValue Ld = DAG.getLoad(MVT::f64, dl, Store, FIdx, NULL, 0); @@ -3396,9 +3426,9 @@ SDValue PPCTargetLowering::LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG) { */ MachineFunction &MF = DAG.getMachineFunction(); - MVT VT = Op.getValueType(); - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); - std::vector<MVT> NodeTys; + EVT VT = Op.getValueType(); + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + std::vector<EVT> NodeTys; SDValue MFFSreg, InFlag; // Save FP Control Word to register @@ -3437,7 +3467,7 @@ SDValue PPCTargetLowering::LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG) { } SDValue PPCTargetLowering::LowerSHL_PARTS(SDValue Op, SelectionDAG &DAG) { - MVT VT = Op.getValueType(); + EVT VT = Op.getValueType(); unsigned BitWidth = VT.getSizeInBits(); DebugLoc dl = Op.getDebugLoc(); assert(Op.getNumOperands() == 3 && @@ -3449,7 +3479,7 @@ SDValue PPCTargetLowering::LowerSHL_PARTS(SDValue Op, SelectionDAG &DAG) { SDValue Lo = Op.getOperand(0); SDValue Hi = Op.getOperand(1); SDValue Amt = Op.getOperand(2); - MVT AmtVT = Amt.getValueType(); + EVT AmtVT = Amt.getValueType(); SDValue Tmp1 = DAG.getNode(ISD::SUB, dl, AmtVT, DAG.getConstant(BitWidth, AmtVT), Amt); @@ -3466,7 +3496,7 @@ SDValue PPCTargetLowering::LowerSHL_PARTS(SDValue Op, SelectionDAG &DAG) { } SDValue PPCTargetLowering::LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG) { - MVT VT = Op.getValueType(); + EVT VT = Op.getValueType(); DebugLoc dl = Op.getDebugLoc(); unsigned BitWidth = VT.getSizeInBits(); assert(Op.getNumOperands() == 3 && @@ -3478,7 +3508,7 @@ SDValue PPCTargetLowering::LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG) { SDValue Lo = Op.getOperand(0); SDValue Hi = Op.getOperand(1); SDValue Amt = Op.getOperand(2); - MVT AmtVT = Amt.getValueType(); + EVT AmtVT = Amt.getValueType(); SDValue Tmp1 = DAG.getNode(ISD::SUB, dl, AmtVT, DAG.getConstant(BitWidth, AmtVT), Amt); @@ -3496,7 +3526,7 @@ SDValue PPCTargetLowering::LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG) { SDValue PPCTargetLowering::LowerSRA_PARTS(SDValue Op, SelectionDAG &DAG) { DebugLoc dl = Op.getDebugLoc(); - MVT VT = Op.getValueType(); + EVT VT = Op.getValueType(); unsigned BitWidth = VT.getSizeInBits(); assert(Op.getNumOperands() == 3 && VT == Op.getOperand(1).getValueType() && @@ -3506,7 +3536,7 @@ SDValue PPCTargetLowering::LowerSRA_PARTS(SDValue Op, SelectionDAG &DAG) { SDValue Lo = Op.getOperand(0); SDValue Hi = Op.getOperand(1); SDValue Amt = Op.getOperand(2); - MVT AmtVT = Amt.getValueType(); + EVT AmtVT = Amt.getValueType(); SDValue Tmp1 = DAG.getNode(ISD::SUB, dl, AmtVT, DAG.getConstant(BitWidth, AmtVT), Amt); @@ -3529,21 +3559,21 @@ SDValue PPCTargetLowering::LowerSRA_PARTS(SDValue Op, SelectionDAG &DAG) { /// BuildSplatI - Build a canonical splati of Val with an element size of /// SplatSize. Cast the result to VT. -static SDValue BuildSplatI(int Val, unsigned SplatSize, MVT VT, +static SDValue BuildSplatI(int Val, unsigned SplatSize, EVT VT, SelectionDAG &DAG, DebugLoc dl) { assert(Val >= -16 && Val <= 15 && "vsplti is out of range!"); - static const MVT VTys[] = { // canonical VT to use for each size. + static const EVT VTys[] = { // canonical VT to use for each size. MVT::v16i8, MVT::v8i16, MVT::Other, MVT::v4i32 }; - MVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1]; + EVT ReqVT = VT != MVT::Other ? VT : VTys[SplatSize-1]; // Force vspltis[hw] -1 to vspltisb -1 to canonicalize. if (Val == -1) SplatSize = 1; - MVT CanonicalVT = VTys[SplatSize-1]; + EVT CanonicalVT = VTys[SplatSize-1]; // Build a canonical splat for this value. SDValue Elt = DAG.getConstant(Val, MVT::i32); @@ -3558,7 +3588,7 @@ static SDValue BuildSplatI(int Val, unsigned SplatSize, MVT VT, /// specified intrinsic ID. static SDValue BuildIntrinsicOp(unsigned IID, SDValue LHS, SDValue RHS, SelectionDAG &DAG, DebugLoc dl, - MVT DestVT = MVT::Other) { + EVT DestVT = MVT::Other) { if (DestVT == MVT::Other) DestVT = LHS.getValueType(); return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, DestVT, DAG.getConstant(IID, MVT::i32), LHS, RHS); @@ -3568,7 +3598,7 @@ static SDValue BuildIntrinsicOp(unsigned IID, SDValue LHS, SDValue RHS, /// specified intrinsic ID. static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op0, SDValue Op1, SDValue Op2, SelectionDAG &DAG, - DebugLoc dl, MVT DestVT = MVT::Other) { + DebugLoc dl, EVT DestVT = MVT::Other) { if (DestVT == MVT::Other) DestVT = Op0.getValueType(); return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, dl, DestVT, DAG.getConstant(IID, MVT::i32), Op0, Op1, Op2); @@ -3578,7 +3608,7 @@ static SDValue BuildIntrinsicOp(unsigned IID, SDValue Op0, SDValue Op1, /// BuildVSLDOI - Return a VECTOR_SHUFFLE that is a vsldoi of the specified /// amount. The result has the specified value type. static SDValue BuildVSLDOI(SDValue LHS, SDValue RHS, unsigned Amt, - MVT VT, SelectionDAG &DAG, DebugLoc dl) { + EVT VT, SelectionDAG &DAG, DebugLoc dl) { // Force LHS/RHS to be the right type. LHS = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v16i8, LHS); RHS = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v16i8, RHS); @@ -3789,7 +3819,7 @@ static SDValue GeneratePerfectShuffle(unsigned PFEntry, SDValue LHS, int ShufIdxs[16]; switch (OpNum) { - default: assert(0 && "Unknown i32 permute!"); + default: llvm_unreachable("Unknown i32 permute!"); case OP_VMRGHW: ShufIdxs[ 0] = 0; ShufIdxs[ 1] = 1; ShufIdxs[ 2] = 2; ShufIdxs[ 3] = 3; ShufIdxs[ 4] = 16; ShufIdxs[ 5] = 17; ShufIdxs[ 6] = 18; ShufIdxs[ 7] = 19; @@ -3825,7 +3855,7 @@ static SDValue GeneratePerfectShuffle(unsigned PFEntry, SDValue LHS, case OP_VSLDOI12: return BuildVSLDOI(OpLHS, OpRHS, 12, OpLHS.getValueType(), DAG, dl); } - MVT VT = OpLHS.getValueType(); + EVT VT = OpLHS.getValueType(); OpLHS = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v16i8, OpLHS); OpRHS = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::v16i8, OpRHS); SDValue T = DAG.getVectorShuffle(MVT::v16i8, dl, OpLHS, OpRHS, ShufIdxs); @@ -3842,7 +3872,7 @@ SDValue PPCTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op, SDValue V1 = Op.getOperand(0); SDValue V2 = Op.getOperand(1); ShuffleVectorSDNode *SVOp = cast<ShuffleVectorSDNode>(Op); - MVT VT = Op.getValueType(); + EVT VT = Op.getValueType(); // Cases that are handled by instructions that take permute immediates // (such as vsplt*) should be left as VECTOR_SHUFFLE nodes so they can be @@ -3939,7 +3969,7 @@ SDValue PPCTargetLowering::LowerVECTOR_SHUFFLE(SDValue Op, // The SHUFFLE_VECTOR mask is almost exactly what we want for vperm, except // that it is in input element units, not in bytes. Convert now. - MVT EltVT = V1.getValueType().getVectorElementType(); + EVT EltVT = V1.getValueType().getVectorElementType(); unsigned BytesPerElement = EltVT.getSizeInBits()/8; SmallVector<SDValue, 16> ResultMask; @@ -4026,7 +4056,7 @@ SDValue PPCTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, Op.getOperand(3), // RHS DAG.getConstant(CompareOpc, MVT::i32) }; - std::vector<MVT> VTs; + std::vector<EVT> VTs; VTs.push_back(Op.getOperand(2).getValueType()); VTs.push_back(MVT::Flag); SDValue CompNode = DAG.getNode(PPCISD::VCMPo, dl, VTs, Ops, 3); @@ -4076,7 +4106,7 @@ SDValue PPCTargetLowering::LowerSCALAR_TO_VECTOR(SDValue Op, // Create a stack slot that is 16-byte aligned. MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo(); int FrameIdx = FrameInfo->CreateStackObject(16, 16); - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); SDValue FIdx = DAG.getFrameIndex(FrameIdx, PtrVT); // Store the input value into Value#0 of the stack slot. @@ -4141,8 +4171,7 @@ SDValue PPCTargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) { } return DAG.getVectorShuffle(MVT::v16i8, dl, EvenParts, OddParts, Ops); } else { - assert(0 && "Unknown mul to lower!"); - abort(); + llvm_unreachable("Unknown mul to lower!"); } } @@ -4150,7 +4179,7 @@ SDValue PPCTargetLowering::LowerMUL(SDValue Op, SelectionDAG &DAG) { /// SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { - default: assert(0 && "Wasn't expecting to be able to lower this!"); + default: llvm_unreachable("Wasn't expecting to be able to lower this!"); case ISD::ConstantPool: return LowerConstantPool(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); @@ -4165,24 +4194,6 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { return LowerVAARG(Op, DAG, VarArgsFrameIndex, VarArgsStackOffset, VarArgsNumGPR, VarArgsNumFPR, PPCSubTarget); - case ISD::FORMAL_ARGUMENTS: - if (PPCSubTarget.isSVR4ABI()) { - return LowerFORMAL_ARGUMENTS_SVR4(Op, DAG, VarArgsFrameIndex, - VarArgsStackOffset, VarArgsNumGPR, - VarArgsNumFPR, PPCSubTarget); - } else { - return LowerFORMAL_ARGUMENTS_Darwin(Op, DAG, VarArgsFrameIndex, - PPCSubTarget); - } - - case ISD::CALL: - if (PPCSubTarget.isSVR4ABI()) { - return LowerCALL_SVR4(Op, DAG, PPCSubTarget, getTargetMachine()); - } else { - return LowerCALL_Darwin(Op, DAG, PPCSubTarget, getTargetMachine()); - } - - case ISD::RET: return LowerRET(Op, DAG, getTargetMachine()); case ISD::STACKRESTORE: return LowerSTACKRESTORE(Op, DAG, PPCSubTarget); case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG, PPCSubTarget); @@ -4234,7 +4245,7 @@ void PPCTargetLowering::ReplaceNodeResults(SDNode *N, // This sequence changes FPSCR to do round-to-zero, adds the two halves // of the long double, and puts FPSCR back the way it was. We do not // actually model FPSCR. - std::vector<MVT> NodeTys; + std::vector<EVT> NodeTys; SDValue Ops[4], Result, MFFSreg, InFlag, FPreg; NodeTys.push_back(MVT::f64); // Return register @@ -4480,7 +4491,8 @@ PPCTargetLowering::EmitPartwordAtomicBinary(MachineInstr *MI, MachineBasicBlock * PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *BB) const { + MachineBasicBlock *BB, + DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const { const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); // To "insert" these instructions we actually have to insert their @@ -4516,9 +4528,18 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, .addImm(SelectPred).addReg(MI->getOperand(1).getReg()).addMBB(sinkMBB); F->insert(It, copy0MBB); F->insert(It, sinkMBB); - // Update machine-CFG edges by transferring all successors of the current + // Update machine-CFG edges by first adding all successors of the current // block to the new block which will contain the Phi node for the select. - sinkMBB->transferSuccessors(BB); + // Also inform sdisel of the edge changes. + for (MachineBasicBlock::succ_iterator I = BB->succ_begin(), + E = BB->succ_end(); I != E; ++I) { + EM->insert(std::make_pair(*I, sinkMBB)); + sinkMBB->addSuccessor(*I); + } + // Next, remove all successors of the current block, and add the true + // and fallthrough blocks as its successors. + while (!BB->succ_empty()) + BB->removeSuccessor(BB->succ_begin()); // Next, add the true and fallthrough blocks as its successors. BB->addSuccessor(copy0MBB); BB->addSuccessor(sinkMBB); @@ -4812,7 +4833,7 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, BB = exitMBB; BuildMI(BB, dl, TII->get(PPC::SRW),dest).addReg(TmpReg).addReg(ShiftReg); } else { - assert(0 && "Unexpected instr type to insert"); + llvm_unreachable("Unexpected instr type to insert"); } F->DeleteMachineInstr(MI); // The pseudo instruction is gone now. @@ -4903,7 +4924,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, } // Turn STORE (BSWAP) -> sthbrx/stwbrx. - if (N->getOperand(1).getOpcode() == ISD::BSWAP && + if (cast<StoreSDNode>(N)->isUnindexed() && + N->getOperand(1).getOpcode() == ISD::BSWAP && N->getOperand(1).getNode()->hasOneUse() && (N->getOperand(1).getValueType() == MVT::i32 || N->getOperand(1).getValueType() == MVT::i16)) { @@ -4912,9 +4934,15 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, if (BSwapOp.getValueType() == MVT::i16) BSwapOp = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i32, BSwapOp); - return DAG.getNode(PPCISD::STBRX, dl, MVT::Other, N->getOperand(0), - BSwapOp, N->getOperand(2), N->getOperand(3), - DAG.getValueType(N->getOperand(1).getValueType())); + SDValue Ops[] = { + N->getOperand(0), BSwapOp, N->getOperand(2), + DAG.getValueType(N->getOperand(1).getValueType()) + }; + return + DAG.getMemIntrinsicNode(PPCISD::STBRX, dl, DAG.getVTList(MVT::Other), + Ops, array_lengthof(Ops), + cast<StoreSDNode>(N)->getMemoryVT(), + cast<StoreSDNode>(N)->getMemOperand()); } break; case ISD::BSWAP: @@ -4925,17 +4953,15 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, SDValue Load = N->getOperand(0); LoadSDNode *LD = cast<LoadSDNode>(Load); // Create the byte-swapping load. - std::vector<MVT> VTs; - VTs.push_back(MVT::i32); - VTs.push_back(MVT::Other); - SDValue MO = DAG.getMemOperand(LD->getMemOperand()); SDValue Ops[] = { LD->getChain(), // Chain LD->getBasePtr(), // Ptr - MO, // MemOperand DAG.getValueType(N->getValueType(0)) // VT }; - SDValue BSLoad = DAG.getNode(PPCISD::LBRX, dl, VTs, Ops, 4); + SDValue BSLoad = + DAG.getMemIntrinsicNode(PPCISD::LBRX, dl, + DAG.getVTList(MVT::i32, MVT::Other), Ops, 3, + LD->getMemoryVT(), LD->getMemOperand()); // If this is an i16 load, insert the truncate. SDValue ResVal = BSLoad; @@ -5035,7 +5061,7 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, bool BranchOnWhenPredTrue = (CC == ISD::SETEQ) ^ (Val == 0); // Create the PPCISD altivec 'dot' comparison node. - std::vector<MVT> VTs; + std::vector<EVT> VTs; SDValue Ops[] = { LHS.getOperand(2), // LHS of compare LHS.getOperand(3), // RHS of compare @@ -5090,7 +5116,7 @@ void PPCTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op, default: break; case PPCISD::LBRX: { // lhbrx is known to have the top bits cleared out. - if (cast<VTSDNode>(Op.getOperand(3))->getVT() == MVT::i16) + if (cast<VTSDNode>(Op.getOperand(2))->getVT() == MVT::i16) KnownZero = 0xFFFF0000; break; } @@ -5138,7 +5164,7 @@ PPCTargetLowering::getConstraintType(const std::string &Constraint) const { std::pair<unsigned, const TargetRegisterClass*> PPCTargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint, - MVT VT) const { + EVT VT) const { if (Constraint.size() == 1) { // GCC RS6000 Constraint Letters switch (Constraint[0]) { @@ -5187,7 +5213,7 @@ void PPCTargetLowering::LowerAsmOperandForConstraint(SDValue Op, char Letter, if (!CST) return; // Must be an immediate to match. unsigned Value = CST->getZExtValue(); switch (Letter) { - default: assert(0 && "Unknown constraint letter!"); + default: llvm_unreachable("Unknown constraint letter!"); case 'I': // "I" is a signed 16-bit constant. if ((short)Value == (int)Value) Result = DAG.getTargetConstant(Value, Op.getValueType()); @@ -5304,7 +5330,7 @@ SDValue PPCTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) { if (cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() > 0) return SDValue(); - MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); + EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = PtrVT == MVT::i64; MachineFunction &MF = DAG.getMachineFunction(); @@ -5326,7 +5352,7 @@ PPCTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const { return false; } -MVT PPCTargetLowering::getOptimalMemOpType(uint64_t Size, unsigned Align, +EVT PPCTargetLowering::getOptimalMemOpType(uint64_t Size, unsigned Align, bool isSrcConst, bool isSrcStr, SelectionDAG &DAG) const { if (this->PPCSubTarget.isPPC64()) { diff --git a/lib/Target/PowerPC/PPCISelLowering.h b/lib/Target/PowerPC/PPCISelLowering.h index 962bbb1..ac72d87 100644 --- a/lib/Target/PowerPC/PPCISelLowering.h +++ b/lib/Target/PowerPC/PPCISelLowering.h @@ -41,8 +41,7 @@ namespace llvm { FCTIDZ, FCTIWZ, /// STFIWX - The STFIWX instruction. The first operand is an input token - /// chain, then an f64 value to store, then an address to store it to, - /// then a SRCVALUE for the address. + /// chain, then an f64 value to store, then an address to store it to. STFIWX, // VMADDFP, VNMSUBFP - The VMADDFP and VNMSUBFP instructions, taking @@ -60,6 +59,8 @@ namespace llvm { /// though these are usually folded into other nodes. Hi, Lo, + TOC_ENTRY, + /// OPRC, CHAIN = DYNALLOC(CHAIN, NEGSIZE, FRAME_INDEX) /// This instruction is lowered in PPCRegisterInfo::eliminateFrameIndex to /// compute an allocation on the stack. @@ -78,12 +79,12 @@ namespace llvm { /// registers. EXTSW_32, - /// STD_32 - This is the STD instruction for use with "32-bit" registers. - STD_32, - /// CALL - A direct function call. CALL_Darwin, CALL_SVR4, + /// NOP - Special NOP which follows 64-bit SVR4 calls. + NOP, + /// CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a /// MTCTR instruction. MTCTR, @@ -119,18 +120,6 @@ namespace llvm { /// an optional input flag argument. COND_BRANCH, - /// CHAIN = STBRX CHAIN, GPRC, Ptr, SRCVALUE, Type - This is a - /// byte-swapping store instruction. It byte-swaps the low "Type" bits of - /// the GPRC input, then stores it through Ptr. Type can be either i16 or - /// i32. - STBRX, - - /// GPRC, CHAIN = LBRX CHAIN, Ptr, SRCVALUE, Type - This is a - /// byte-swapping load instruction. It loads "Type" bits, byte swaps it, - /// then puts it in the bottom bits of the GPRC. TYPE can be either i16 - /// or i32. - LBRX, - // The following 5 instructions are used only as part of the // long double-to-int conversion sequence. @@ -160,14 +149,27 @@ namespace llvm { /// indexed. This is used to implement atomic operations. STCX, - /// TAILCALL - Indicates a tail call should be taken. - TAILCALL, /// TC_RETURN - A tail call return. /// operand #0 chain /// operand #1 callee (register or absolute) /// operand #2 stack adjustment /// operand #3 optional in flag - TC_RETURN + TC_RETURN, + + /// STD_32 - This is the STD instruction for use with "32-bit" registers. + STD_32 = ISD::FIRST_TARGET_MEMORY_OPCODE, + + /// CHAIN = STBRX CHAIN, GPRC, Ptr, Type - This is a + /// byte-swapping store instruction. It byte-swaps the low "Type" bits of + /// the GPRC input, then stores it through Ptr. Type can be either i16 or + /// i32. + STBRX, + + /// GPRC, CHAIN = LBRX CHAIN, Ptr, Type - This is a + /// byte-swapping load instruction. It loads "Type" bits, byte swaps it, + /// then puts it in the bottom bits of the GPRC. TYPE can be either i16 + /// or i32. + LBRX }; } @@ -232,7 +234,7 @@ namespace llvm { virtual const char *getTargetNodeName(unsigned Opcode) const; /// getSetCCResultType - Return the ISD::SETCC ValueType - virtual MVT getSetCCResultType(MVT VT) const; + virtual MVT::SimpleValueType getSetCCResultType(EVT VT) const; /// getPreIndexedAddressParts - returns true by value, base pointer and /// offset pointer and addressing mode by reference if the node's address @@ -286,7 +288,8 @@ namespace llvm { unsigned Depth = 0) const; virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *MBB) const; + MachineBasicBlock *MBB, + DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const; MachineBasicBlock *EmitAtomicBinary(MachineInstr *MI, MachineBasicBlock *MBB, bool is64Bit, unsigned BinOpcode) const; @@ -297,7 +300,7 @@ namespace llvm { ConstraintType getConstraintType(const std::string &Constraint) const; std::pair<unsigned, const TargetRegisterClass*> getRegForInlineAsmConstraint(const std::string &Constraint, - MVT VT) const; + EVT VT) const; /// getByValTypeAlignment - Return the desired alignment for ByVal aggregate /// function arguments in the caller parameter area. This is the actual @@ -327,16 +330,16 @@ namespace llvm { /// the offset of the target addressing mode. virtual bool isLegalAddressImmediate(GlobalValue *GV) const; - /// IsEligibleForTailCallOptimization - Check whether the call is eligible - /// for tail call optimization. Target which want to do tail call - /// optimization should implement this function. - virtual bool IsEligibleForTailCallOptimization(CallSDNode *TheCall, - SDValue Ret, - SelectionDAG &DAG) const; + virtual bool + IsEligibleForTailCallOptimization(SDValue Callee, + CallingConv::ID CalleeCC, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + SelectionDAG& DAG) const; virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const; - virtual MVT getOptimalMemOpType(uint64_t Size, unsigned Align, + virtual EVT getOptimalMemOpType(uint64_t Size, unsigned Align, bool isSrcConst, bool isSrcStr, SelectionDAG &DAG) const; @@ -370,20 +373,6 @@ namespace llvm { SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG, int VarArgsFrameIndex, int VarArgsStackOffset, unsigned VarArgsNumGPR, unsigned VarArgsNumFPR, const PPCSubtarget &Subtarget); - SDValue LowerFORMAL_ARGUMENTS_SVR4(SDValue Op, SelectionDAG &DAG, - int &VarArgsFrameIndex, - int &VarArgsStackOffset, - unsigned &VarArgsNumGPR, - unsigned &VarArgsNumFPR, - const PPCSubtarget &Subtarget); - SDValue LowerFORMAL_ARGUMENTS_Darwin(SDValue Op, SelectionDAG &DAG, - int &VarArgsFrameIndex, - const PPCSubtarget &Subtarget); - SDValue LowerCALL_Darwin(SDValue Op, SelectionDAG &DAG, - const PPCSubtarget &Subtarget, TargetMachine &TM); - SDValue LowerCALL_SVR4(SDValue Op, SelectionDAG &DAG, - const PPCSubtarget &Subtarget, TargetMachine &TM); - SDValue LowerRET(SDValue Op, SelectionDAG &DAG, TargetMachine &TM); SDValue LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG, const PPCSubtarget &Subtarget); SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG, @@ -400,6 +389,71 @@ namespace llvm { SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG); SDValue LowerSCALAR_TO_VECTOR(SDValue Op, SelectionDAG &DAG); SDValue LowerMUL(SDValue Op, SelectionDAG &DAG); + + SDValue LowerCallResult(SDValue Chain, SDValue InFlag, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + SDValue FinishCall(CallingConv::ID CallConv, DebugLoc dl, bool isTailCall, + bool isVarArg, + SelectionDAG &DAG, + SmallVector<std::pair<unsigned, SDValue>, 8> + &RegsToPass, + SDValue InFlag, SDValue Chain, + SDValue &Callee, + int SPDiff, unsigned NumBytes, + const SmallVectorImpl<ISD::InputArg> &Ins, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerFormalArguments(SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerCall(SDValue Chain, SDValue Callee, + CallingConv::ID CallConv, bool isVarArg, bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerReturn(SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); + + SDValue + LowerFormalArguments_Darwin(SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + SDValue + LowerFormalArguments_SVR4(SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + SDValue + LowerCall_Darwin(SDValue Chain, SDValue Callee, + CallingConv::ID CallConv, bool isVarArg, bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + SDValue + LowerCall_SVR4(SDValue Chain, SDValue Callee, + CallingConv::ID CallConv, bool isVarArg, bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); }; } diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td index 3823e53..0f68fb9 100644 --- a/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/lib/Target/PowerPC/PPCInstr64Bit.td @@ -68,7 +68,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, LR8,CTR8, - CR0,CR1,CR5,CR6,CR7] in { + CR0,CR1,CR5,CR6,CR7,CARRY] in { // Convenient aliases for call instructions let Uses = [RM] in { def BL8_Darwin : IForm<18, 0, 1, @@ -94,7 +94,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, LR8,CTR8, - CR0,CR1,CR5,CR6,CR7] in { + CR0,CR1,CR5,CR6,CR7,CARRY] in { // Convenient aliases for call instructions let Uses = [RM] in { def BL8_ELF : IForm<18, 0, 1, @@ -123,6 +123,8 @@ def : Pat<(PPCcall_SVR4 (i64 tglobaladdr:$dst)), (BL8_ELF tglobaladdr:$dst)>; def : Pat<(PPCcall_SVR4 (i64 texternalsym:$dst)), (BL8_ELF texternalsym:$dst)>; +def : Pat<(PPCnop), + (NOP)>; // Atomic operations let usesCustomDAGSchedInserter = 1 in { @@ -327,14 +329,15 @@ def ADD8 : XOForm_1<31, 266, 0, (outs G8RC:$rT), (ins G8RC:$rA, G8RC:$rB), "add $rT, $rA, $rB", IntGeneral, [(set G8RC:$rT, (add G8RC:$rA, G8RC:$rB))]>; +let Defs = [CARRY] in { def ADDC8 : XOForm_1<31, 10, 0, (outs G8RC:$rT), (ins G8RC:$rA, G8RC:$rB), "addc $rT, $rA, $rB", IntGeneral, [(set G8RC:$rT, (addc G8RC:$rA, G8RC:$rB))]>, PPC970_DGroup_Cracked; -def ADDE8 : XOForm_1<31, 138, 0, (outs G8RC:$rT), (ins G8RC:$rA, G8RC:$rB), - "adde $rT, $rA, $rB", IntGeneral, - [(set G8RC:$rT, (adde G8RC:$rA, G8RC:$rB))]>; - +def ADDIC8 : DForm_2<12, (outs G8RC:$rD), (ins G8RC:$rA, s16imm64:$imm), + "addic $rD, $rA, $imm", IntGeneral, + [(set G8RC:$rD, (addc G8RC:$rA, immSExt16:$imm))]>; +} def ADDI8 : DForm_2<14, (outs G8RC:$rD), (ins G8RC:$rA, s16imm64:$imm), "addi $rD, $rA, $imm", IntGeneral, [(set G8RC:$rD, (add G8RC:$rA, immSExt16:$imm))]>; @@ -342,36 +345,41 @@ def ADDIS8 : DForm_2<15, (outs G8RC:$rD), (ins G8RC:$rA, symbolHi64:$imm), "addis $rD, $rA, $imm", IntGeneral, [(set G8RC:$rD, (add G8RC:$rA, imm16ShiftedSExt:$imm))]>; +let Defs = [CARRY] in { def SUBFIC8: DForm_2< 8, (outs G8RC:$rD), (ins G8RC:$rA, s16imm64:$imm), "subfic $rD, $rA, $imm", IntGeneral, [(set G8RC:$rD, (subc immSExt16:$imm, G8RC:$rA))]>; -def SUBF8 : XOForm_1<31, 40, 0, (outs G8RC:$rT), (ins G8RC:$rA, G8RC:$rB), - "subf $rT, $rA, $rB", IntGeneral, - [(set G8RC:$rT, (sub G8RC:$rB, G8RC:$rA))]>; def SUBFC8 : XOForm_1<31, 8, 0, (outs G8RC:$rT), (ins G8RC:$rA, G8RC:$rB), "subfc $rT, $rA, $rB", IntGeneral, [(set G8RC:$rT, (subc G8RC:$rB, G8RC:$rA))]>, PPC970_DGroup_Cracked; - -def SUBFE8 : XOForm_1<31, 136, 0, (outs G8RC:$rT), (ins G8RC:$rA, G8RC:$rB), - "subfe $rT, $rA, $rB", IntGeneral, - [(set G8RC:$rT, (sube G8RC:$rB, G8RC:$rA))]>; +} +def SUBF8 : XOForm_1<31, 40, 0, (outs G8RC:$rT), (ins G8RC:$rA, G8RC:$rB), + "subf $rT, $rA, $rB", IntGeneral, + [(set G8RC:$rT, (sub G8RC:$rB, G8RC:$rA))]>; +def NEG8 : XOForm_3<31, 104, 0, (outs G8RC:$rT), (ins G8RC:$rA), + "neg $rT, $rA", IntGeneral, + [(set G8RC:$rT, (ineg G8RC:$rA))]>; +let Uses = [CARRY], Defs = [CARRY] in { +def ADDE8 : XOForm_1<31, 138, 0, (outs G8RC:$rT), (ins G8RC:$rA, G8RC:$rB), + "adde $rT, $rA, $rB", IntGeneral, + [(set G8RC:$rT, (adde G8RC:$rA, G8RC:$rB))]>; def ADDME8 : XOForm_3<31, 234, 0, (outs G8RC:$rT), (ins G8RC:$rA), "addme $rT, $rA", IntGeneral, [(set G8RC:$rT, (adde G8RC:$rA, immAllOnes))]>; def ADDZE8 : XOForm_3<31, 202, 0, (outs G8RC:$rT), (ins G8RC:$rA), "addze $rT, $rA", IntGeneral, [(set G8RC:$rT, (adde G8RC:$rA, 0))]>; -def NEG8 : XOForm_3<31, 104, 0, (outs G8RC:$rT), (ins G8RC:$rA), - "neg $rT, $rA", IntGeneral, - [(set G8RC:$rT, (ineg G8RC:$rA))]>; +def SUBFE8 : XOForm_1<31, 136, 0, (outs G8RC:$rT), (ins G8RC:$rA, G8RC:$rB), + "subfe $rT, $rA, $rB", IntGeneral, + [(set G8RC:$rT, (sube G8RC:$rB, G8RC:$rA))]>; def SUBFME8 : XOForm_3<31, 232, 0, (outs G8RC:$rT), (ins G8RC:$rA), "subfme $rT, $rA", IntGeneral, [(set G8RC:$rT, (sube immAllOnes, G8RC:$rA))]>; def SUBFZE8 : XOForm_3<31, 200, 0, (outs G8RC:$rT), (ins G8RC:$rA), "subfze $rT, $rA", IntGeneral, [(set G8RC:$rT, (sube 0, G8RC:$rA))]>; - +} def MULHD : XOForm_1<31, 73, 0, (outs G8RC:$rT), (ins G8RC:$rA, G8RC:$rB), @@ -396,9 +404,11 @@ def SLD : XForm_6<31, 27, (outs G8RC:$rA), (ins G8RC:$rS, GPRC:$rB), def SRD : XForm_6<31, 539, (outs G8RC:$rA), (ins G8RC:$rS, GPRC:$rB), "srd $rA, $rS, $rB", IntRotateD, [(set G8RC:$rA, (PPCsrl G8RC:$rS, GPRC:$rB))]>, isPPC64; +let Defs = [CARRY] in { def SRAD : XForm_6<31, 794, (outs G8RC:$rA), (ins G8RC:$rS, GPRC:$rB), "srad $rA, $rS, $rB", IntRotateD, [(set G8RC:$rA, (PPCsra G8RC:$rS, GPRC:$rB))]>, isPPC64; +} def EXTSB8 : XForm_11<31, 954, (outs G8RC:$rA), (ins G8RC:$rS), "extsb $rA, $rS", IntGeneral, @@ -418,9 +428,11 @@ def EXTSW_32_64 : XForm_11<31, 986, (outs G8RC:$rA), (ins GPRC:$rS), "extsw $rA, $rS", IntGeneral, [(set G8RC:$rA, (sext GPRC:$rS))]>, isPPC64; +let Defs = [CARRY] in { def SRADI : XSForm_1<31, 413, (outs G8RC:$rA), (ins G8RC:$rS, u6imm:$SH), "sradi $rA, $rS, $SH", IntRotateD, [(set G8RC:$rA, (sra G8RC:$rS, (i32 imm:$SH)))]>, isPPC64; +} def CNTLZD : XForm_11<31, 58, (outs G8RC:$rA), (ins G8RC:$rS), "cntlzd $rA, $rS", IntGeneral, [(set G8RC:$rA, (ctlz G8RC:$rS))]>; @@ -543,6 +555,10 @@ let canFoldAsLoad = 1, PPC970_Unit = 2 in { def LD : DSForm_1<58, 0, (outs G8RC:$rD), (ins memrix:$src), "ld $rD, $src", LdStLD, [(set G8RC:$rD, (load ixaddr:$src))]>, isPPC64; +def LDtoc: DSForm_1<58, 0, (outs G8RC:$rD), (ins tocentry:$disp, G8RC:$reg), + "ld $rD, $disp($reg)", LdStLD, + [(set G8RC:$rD, + (PPCtoc_entry tglobaladdr:$disp, G8RC:$reg))]>, isPPC64; def LDX : XForm_1<31, 21, (outs G8RC:$rD), (ins memrr:$src), "ldx $rD, $src", LdStLD, [(set G8RC:$rD, (load xaddr:$src))]>, isPPC64; diff --git a/lib/Target/PowerPC/PPCInstrBuilder.h b/lib/Target/PowerPC/PPCInstrBuilder.h index 1de6911..b424d11 100644 --- a/lib/Target/PowerPC/PPCInstrBuilder.h +++ b/lib/Target/PowerPC/PPCInstrBuilder.h @@ -29,7 +29,7 @@ namespace llvm { /// reference has base register as the FrameIndex offset until it is resolved. /// This allows a constant offset to be specified as well... /// -inline const MachineInstrBuilder& +static inline const MachineInstrBuilder& addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset = 0, bool mem = true) { if (mem) diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index 87c612a..0083598 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -20,7 +20,9 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/MC/MCAsmInfo.h" using namespace llvm; extern cl::opt<bool> EnablePPC32RS; // FIXME (64-bit): See PPCRegisterInfo.cpp. @@ -485,8 +487,7 @@ PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, .addReg(PPC::R0) .addReg(PPC::R0)); } else { - assert(0 && "Unknown regclass!"); - abort(); + llvm_unreachable("Unknown regclass!"); } return false; @@ -509,45 +510,6 @@ PPCInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, MBB.insert(MI, NewMIs[i]); } -void PPCInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, - bool isKill, - SmallVectorImpl<MachineOperand> &Addr, - const TargetRegisterClass *RC, - SmallVectorImpl<MachineInstr*> &NewMIs) const{ - if (Addr[0].isFI()) { - if (StoreRegToStackSlot(MF, SrcReg, isKill, - Addr[0].getIndex(), RC, NewMIs)) { - PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); - FuncInfo->setSpillsCR(); - } - - return; - } - - DebugLoc DL = DebugLoc::getUnknownLoc(); - unsigned Opc = 0; - if (RC == PPC::GPRCRegisterClass) { - Opc = PPC::STW; - } else if (RC == PPC::G8RCRegisterClass) { - Opc = PPC::STD; - } else if (RC == PPC::F8RCRegisterClass) { - Opc = PPC::STFD; - } else if (RC == PPC::F4RCRegisterClass) { - Opc = PPC::STFS; - } else if (RC == PPC::VRRCRegisterClass) { - Opc = PPC::STVX; - } else { - assert(0 && "Unknown regclass!"); - abort(); - } - MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc)) - .addReg(SrcReg, getKillRegState(isKill)); - for (unsigned i = 0, e = Addr.size(); i != e; ++i) - MIB.addOperand(Addr[i]); - NewMIs.push_back(MIB); - return; -} - void PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, unsigned DestReg, int FrameIdx, @@ -634,8 +596,7 @@ PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, NewMIs.push_back(BuildMI(MF, DL, get(PPC::LVX),DestReg).addReg(PPC::R0) .addReg(PPC::R0)); } else { - assert(0 && "Unknown regclass!"); - abort(); + llvm_unreachable("Unknown regclass!"); } } @@ -653,41 +614,6 @@ PPCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, MBB.insert(MI, NewMIs[i]); } -void PPCInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, - SmallVectorImpl<MachineOperand> &Addr, - const TargetRegisterClass *RC, - SmallVectorImpl<MachineInstr*> &NewMIs)const{ - if (Addr[0].isFI()) { - LoadRegFromStackSlot(MF, DebugLoc::getUnknownLoc(), - DestReg, Addr[0].getIndex(), RC, NewMIs); - return; - } - - unsigned Opc = 0; - if (RC == PPC::GPRCRegisterClass) { - assert(DestReg != PPC::LR && "Can't handle this yet!"); - Opc = PPC::LWZ; - } else if (RC == PPC::G8RCRegisterClass) { - assert(DestReg != PPC::LR8 && "Can't handle this yet!"); - Opc = PPC::LD; - } else if (RC == PPC::F8RCRegisterClass) { - Opc = PPC::LFD; - } else if (RC == PPC::F4RCRegisterClass) { - Opc = PPC::LFS; - } else if (RC == PPC::VRRCRegisterClass) { - Opc = PPC::LVX; - } else { - assert(0 && "Unknown regclass!"); - abort(); - } - DebugLoc DL = DebugLoc::getUnknownLoc(); - MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg); - for (unsigned i = 0, e = Addr.size(); i != e; ++i) - MIB.addOperand(Addr[i]); - NewMIs.push_back(MIB); - return; -} - /// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into /// copy instructions, turning them into load/store instructions. MachineInstr *PPCInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, @@ -842,7 +768,7 @@ unsigned PPCInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { case PPC::INLINEASM: { // Inline Asm: Variable size. const MachineFunction *MF = MI->getParent()->getParent(); const char *AsmStr = MI->getOperand(0).getSymbolName(); - return MF->getTarget().getTargetAsmInfo()->getInlineAsmLength(AsmStr); + return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo()); } case PPC::DBG_LABEL: case PPC::EH_LABEL: diff --git a/lib/Target/PowerPC/PPCInstrInfo.h b/lib/Target/PowerPC/PPCInstrInfo.h index 492634c..bb0dc15a 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.h +++ b/lib/Target/PowerPC/PPCInstrInfo.h @@ -121,20 +121,10 @@ public: unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const; - virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill, - SmallVectorImpl<MachineOperand> &Addr, - const TargetRegisterClass *RC, - SmallVectorImpl<MachineInstr*> &NewMIs) const; - virtual void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC) const; - - virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg, - SmallVectorImpl<MachineOperand> &Addr, - const TargetRegisterClass *RC, - SmallVectorImpl<MachineInstr*> &NewMIs) const; /// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into /// copy instructions, turning them into load/store instructions. diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 7af59a2..dc5db6f 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -35,11 +35,11 @@ def SDT_PPCcondbr : SDTypeProfile<0, 3, [ SDTCisVT<0, i32>, SDTCisVT<2, OtherVT> ]>; -def SDT_PPClbrx : SDTypeProfile<1, 3, [ - SDTCisVT<0, i32>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT> +def SDT_PPClbrx : SDTypeProfile<1, 2, [ + SDTCisVT<0, i32>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT> ]>; -def SDT_PPCstbrx : SDTypeProfile<0, 4, [ - SDTCisVT<0, i32>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>, SDTCisVT<3, OtherVT> +def SDT_PPCstbrx : SDTypeProfile<0, 3, [ + SDTCisVT<0, i32>, SDTCisPtrTy<1>, SDTCisVT<2, OtherVT> ]>; def SDT_PPClarx : SDTypeProfile<1, 1, [ @@ -53,6 +53,8 @@ def SDT_PPCTC_ret : SDTypeProfile<0, 2, [ SDTCisPtrTy<0>, SDTCisVT<1, i32> ]>; +def SDT_PPCnop : SDTypeProfile<0, 0, []>; + //===----------------------------------------------------------------------===// // PowerPC specific DAG Nodes. // @@ -85,6 +87,7 @@ def PPCfsel : SDNode<"PPCISD::FSEL", def PPChi : SDNode<"PPCISD::Hi", SDTIntBinOp, []>; def PPClo : SDNode<"PPCISD::Lo", SDTIntBinOp, []>; +def PPCtoc_entry: SDNode<"PPCISD::TOC_ENTRY", SDTIntBinOp, [SDNPMayLoad]>; def PPCvmaddfp : SDNode<"PPCISD::VMADDFP", SDTFPTernaryOp, []>; def PPCvnmsubfp : SDNode<"PPCISD::VNMSUBFP", SDTFPTernaryOp, []>; @@ -111,6 +114,7 @@ def PPCcall_Darwin : SDNode<"PPCISD::CALL_Darwin", SDT_PPCCall, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; def PPCcall_SVR4 : SDNode<"PPCISD::CALL_SVR4", SDT_PPCCall, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; +def PPCnop : SDNode<"PPCISD::NOP", SDT_PPCnop, [SDNPInFlag, SDNPOutFlag]>; def PPCmtctr : SDNode<"PPCISD::MTCTR", SDT_PPCCall, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; def PPCbctrl_Darwin : SDNode<"PPCISD::BCTRL_Darwin", SDTNone, @@ -125,9 +129,6 @@ def retflag : SDNode<"PPCISD::RET_FLAG", SDTNone, def PPCtc_return : SDNode<"PPCISD::TC_RETURN", SDT_PPCTC_ret, [SDNPHasChain, SDNPOptInFlag]>; -def PPCtailcall : SDNode<"PPCISD::TAILCALL", SDT_PPCCall, - [SDNPHasChain, SDNPOutFlag, SDNPOptInFlag]>; - def PPCvcmp : SDNode<"PPCISD::VCMP" , SDT_PPCvcmp, []>; def PPCvcmp_o : SDNode<"PPCISD::VCMPo", SDT_PPCvcmp, [SDNPOutFlag]>; @@ -309,6 +310,10 @@ def memrix : Operand<iPTR> { // memri where the imm is shifted 2 bits. let PrintMethod = "printMemRegImmShifted"; let MIOperandInfo = (ops i32imm:$imm, ptr_rc:$reg); } +def tocentry : Operand<iPTR> { + let PrintMethod = "printTOCEntryLabel"; + let MIOperandInfo = (ops i32imm:$imm); +} // PowerPC Predicate operand. 20 = (0<<5)|20 = always, CR0 is a dummy reg // that doesn't matter. @@ -421,7 +426,7 @@ let isCall = 1, PPC970_Unit = 7, 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] in { + CR5UN,CR6LT,CR6GT,CR6EQ,CR6UN,CR7LT,CR7GT,CR7EQ,CR7UN,CARRY] in { // Convenient aliases for call instructions let Uses = [RM] in { def BL_Darwin : IForm<18, 0, 1, @@ -448,7 +453,7 @@ let isCall = 1, PPC970_Unit = 7, 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] in { + CR5UN,CR6LT,CR6GT,CR6EQ,CR6UN,CR7LT,CR7GT,CR7EQ,CR7UN,CARRY] in { // Convenient aliases for call instructions let Uses = [RM] in { def BL_SVR4 : IForm<18, 0, 1, @@ -736,10 +741,10 @@ def LWZX : XForm_1<31, 23, (outs GPRC:$rD), (ins memrr:$src), def LHBRX : XForm_1<31, 790, (outs GPRC:$rD), (ins memrr:$src), "lhbrx $rD, $src", LdStGeneral, - [(set GPRC:$rD, (PPClbrx xoaddr:$src, srcvalue:$sv, i16))]>; + [(set GPRC:$rD, (PPClbrx xoaddr:$src, i16))]>; def LWBRX : XForm_1<31, 534, (outs GPRC:$rD), (ins memrr:$src), "lwbrx $rD, $src", LdStGeneral, - [(set GPRC:$rD, (PPClbrx xoaddr:$src, srcvalue:$sv, i32))]>; + [(set GPRC:$rD, (PPClbrx xoaddr:$src, i32))]>; def LFSX : XForm_25<31, 535, (outs F4RC:$frD), (ins memrr:$src), "lfsx $frD, $src", LdStLFDU, @@ -832,11 +837,11 @@ def STWUX : XForm_8<31, 183, (outs), (ins GPRC:$rS, GPRC:$rA, GPRC:$rB), } def STHBRX: XForm_8<31, 918, (outs), (ins GPRC:$rS, memrr:$dst), "sthbrx $rS, $dst", LdStGeneral, - [(PPCstbrx GPRC:$rS, xoaddr:$dst, srcvalue:$dummy, i16)]>, + [(PPCstbrx GPRC:$rS, xoaddr:$dst, i16)]>, PPC970_DGroup_Cracked; def STWBRX: XForm_8<31, 662, (outs), (ins GPRC:$rS, memrr:$dst), "stwbrx $rS, $dst", LdStGeneral, - [(PPCstbrx GPRC:$rS, xoaddr:$dst, srcvalue:$dummy, i32)]>, + [(PPCstbrx GPRC:$rS, xoaddr:$dst, i32)]>, PPC970_DGroup_Cracked; def STFIWX: XForm_28<31, 983, (outs), (ins F8RC:$frS, memrr:$dst), @@ -864,6 +869,7 @@ let PPC970_Unit = 1 in { // FXU Operations. def ADDI : DForm_2<14, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), "addi $rD, $rA, $imm", IntGeneral, [(set GPRC:$rD, (add GPRC:$rA, immSExt16:$imm))]>; +let Defs = [CARRY] in { def ADDIC : DForm_2<12, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), "addic $rD, $rA, $imm", IntGeneral, [(set GPRC:$rD, (addc GPRC:$rA, immSExt16:$imm))]>, @@ -871,6 +877,7 @@ def ADDIC : DForm_2<12, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), def ADDICo : DForm_2<13, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), "addic. $rD, $rA, $imm", IntGeneral, []>; +} def ADDIS : DForm_2<15, (outs GPRC:$rD), (ins GPRC:$rA, symbolHi:$imm), "addis $rD, $rA, $imm", IntGeneral, [(set GPRC:$rD, (add GPRC:$rA, imm16ShiftedSExt:$imm))]>; @@ -881,9 +888,11 @@ def LA : DForm_2<14, (outs GPRC:$rD), (ins GPRC:$rA, symbolLo:$sym), def MULLI : DForm_2< 7, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), "mulli $rD, $rA, $imm", IntMulLI, [(set GPRC:$rD, (mul GPRC:$rA, immSExt16:$imm))]>; +let Defs = [CARRY] in { def SUBFIC : DForm_2< 8, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm), "subfic $rD, $rA, $imm", IntGeneral, [(set GPRC:$rD, (subc immSExt16:$imm, GPRC:$rA))]>; +} let isReMaterializable = 1 in { def LI : DForm_2_r0<14, (outs GPRC:$rD), (ins symbolLo:$imm), @@ -956,15 +965,19 @@ def SLW : XForm_6<31, 24, (outs GPRC:$rA), (ins GPRC:$rS, GPRC:$rB), def SRW : XForm_6<31, 536, (outs GPRC:$rA), (ins GPRC:$rS, GPRC:$rB), "srw $rA, $rS, $rB", IntGeneral, [(set GPRC:$rA, (PPCsrl GPRC:$rS, GPRC:$rB))]>; +let Defs = [CARRY] in { def SRAW : XForm_6<31, 792, (outs GPRC:$rA), (ins GPRC:$rS, GPRC:$rB), "sraw $rA, $rS, $rB", IntShift, [(set GPRC:$rA, (PPCsra GPRC:$rS, GPRC:$rB))]>; } +} let PPC970_Unit = 1 in { // FXU Operations. +let Defs = [CARRY] in { def SRAWI : XForm_10<31, 824, (outs GPRC:$rA), (ins GPRC:$rS, u5imm:$SH), "srawi $rA, $rS, $SH", IntShift, [(set GPRC:$rA, (sra GPRC:$rS, (i32 imm:$SH)))]>; +} def CNTLZW : XForm_11<31, 26, (outs GPRC:$rA), (ins GPRC:$rS), "cntlzw $rA, $rS", IntGeneral, [(set GPRC:$rA, (ctlz GPRC:$rS))]>; @@ -1159,13 +1172,12 @@ let PPC970_Unit = 1 in { // FXU Operations. def ADD4 : XOForm_1<31, 266, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), "add $rT, $rA, $rB", IntGeneral, [(set GPRC:$rT, (add GPRC:$rA, GPRC:$rB))]>; +let Defs = [CARRY] in { def ADDC : XOForm_1<31, 10, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), "addc $rT, $rA, $rB", IntGeneral, [(set GPRC:$rT, (addc GPRC:$rA, GPRC:$rB))]>, PPC970_DGroup_Cracked; -def ADDE : XOForm_1<31, 138, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), - "adde $rT, $rA, $rB", IntGeneral, - [(set GPRC:$rT, (adde GPRC:$rA, GPRC:$rB))]>; +} def DIVW : XOForm_1<31, 491, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), "divw $rT, $rA, $rB", IntDivW, [(set GPRC:$rT, (sdiv GPRC:$rA, GPRC:$rB))]>, @@ -1186,22 +1198,28 @@ def MULLW : XOForm_1<31, 235, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), def SUBF : XOForm_1<31, 40, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), "subf $rT, $rA, $rB", IntGeneral, [(set GPRC:$rT, (sub GPRC:$rB, GPRC:$rA))]>; +let Defs = [CARRY] in { def SUBFC : XOForm_1<31, 8, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), "subfc $rT, $rA, $rB", IntGeneral, [(set GPRC:$rT, (subc GPRC:$rB, GPRC:$rA))]>, PPC970_DGroup_Cracked; -def SUBFE : XOForm_1<31, 136, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), - "subfe $rT, $rA, $rB", IntGeneral, - [(set GPRC:$rT, (sube GPRC:$rB, GPRC:$rA))]>; +} +def NEG : XOForm_3<31, 104, 0, (outs GPRC:$rT), (ins GPRC:$rA), + "neg $rT, $rA", IntGeneral, + [(set GPRC:$rT, (ineg GPRC:$rA))]>; +let Uses = [CARRY], Defs = [CARRY] in { +def ADDE : XOForm_1<31, 138, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), + "adde $rT, $rA, $rB", IntGeneral, + [(set GPRC:$rT, (adde GPRC:$rA, GPRC:$rB))]>; def ADDME : XOForm_3<31, 234, 0, (outs GPRC:$rT), (ins GPRC:$rA), "addme $rT, $rA", IntGeneral, [(set GPRC:$rT, (adde GPRC:$rA, immAllOnes))]>; def ADDZE : XOForm_3<31, 202, 0, (outs GPRC:$rT), (ins GPRC:$rA), "addze $rT, $rA", IntGeneral, [(set GPRC:$rT, (adde GPRC:$rA, 0))]>; -def NEG : XOForm_3<31, 104, 0, (outs GPRC:$rT), (ins GPRC:$rA), - "neg $rT, $rA", IntGeneral, - [(set GPRC:$rT, (ineg GPRC:$rA))]>; +def SUBFE : XOForm_1<31, 136, 0, (outs GPRC:$rT), (ins GPRC:$rA, GPRC:$rB), + "subfe $rT, $rA, $rB", IntGeneral, + [(set GPRC:$rT, (sube GPRC:$rB, GPRC:$rA))]>; def SUBFME : XOForm_3<31, 232, 0, (outs GPRC:$rT), (ins GPRC:$rA), "subfme $rT, $rA", IntGeneral, [(set GPRC:$rT, (sube immAllOnes, GPRC:$rA))]>; @@ -1209,6 +1227,7 @@ def SUBFZE : XOForm_3<31, 200, 0, (outs GPRC:$rT), (ins GPRC:$rA), "subfze $rT, $rA", IntGeneral, [(set GPRC:$rT, (sube 0, GPRC:$rA))]>; } +} // A-Form instructions. Most of the instructions executed in the FPU are of // this type. diff --git a/lib/Target/PowerPC/PPCJITInfo.cpp b/lib/Target/PowerPC/PPCJITInfo.cpp index 7486d74..ef25d92 100644 --- a/lib/Target/PowerPC/PPCJITInfo.cpp +++ b/lib/Target/PowerPC/PPCJITInfo.cpp @@ -18,6 +18,8 @@ #include "llvm/Function.h" #include "llvm/System/Memory.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; static TargetJITInfo::JITCompilerFn JITCompilerFunction; @@ -197,8 +199,7 @@ asm( ); #else void PPC32CompilationCallback() { - assert(0 && "This is not a power pc, you can't execute this!"); - abort(); + llvm_unreachable("This is not a power pc, you can't execute this!"); } #endif @@ -264,8 +265,7 @@ asm( ); #else void PPC64CompilationCallback() { - assert(0 && "This is not a power pc, you can't execute this!"); - abort(); + llvm_unreachable("This is not a power pc, you can't execute this!"); } #endif @@ -383,7 +383,7 @@ void PPCJITInfo::relocate(void *Function, MachineRelocation *MR, unsigned *RelocPos = (unsigned*)Function + MR->getMachineCodeOffset()/4; intptr_t ResultPtr = (intptr_t)MR->getResultPointer(); switch ((PPC::RelocationType)MR->getRelocationType()) { - default: assert(0 && "Unknown relocation type!"); + default: llvm_unreachable("Unknown relocation type!"); case PPC::reloc_pcrel_bx: // PC-relative relocation for b and bl instructions. ResultPtr = (ResultPtr-(intptr_t)RelocPos) >> 2; diff --git a/lib/Target/PowerPC/PPCMCAsmInfo.cpp b/lib/Target/PowerPC/PPCMCAsmInfo.cpp new file mode 100644 index 0000000..c87879b --- /dev/null +++ b/lib/Target/PowerPC/PPCMCAsmInfo.cpp @@ -0,0 +1,58 @@ +//===-- PPCMCAsmInfo.cpp - PPC asm properties -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declarations of the MCAsmInfoDarwin properties. +// +//===----------------------------------------------------------------------===// + +#include "PPCMCAsmInfo.h" +using namespace llvm; + +PPCMCAsmInfoDarwin::PPCMCAsmInfoDarwin(bool is64Bit) { + PCSymbol = "."; + CommentString = ";"; + ExceptionsType = ExceptionHandling::Dwarf; + + if (!is64Bit) + Data64bitsDirective = 0; // We can't emit a 64-bit unit in PPC32 mode. + AssemblerDialect = 1; // New-Style mnemonics. +} + +PPCLinuxMCAsmInfo::PPCLinuxMCAsmInfo(bool is64Bit) { + CommentString = "#"; + GlobalPrefix = ""; + PrivateGlobalPrefix = ".L"; + UsedDirective = "\t# .no_dead_strip\t"; + WeakRefDirective = "\t.weak\t"; + + // Uses '.section' before '.bss' directive + UsesELFSectionDirectiveForBSS = true; + + // Debug Information + AbsoluteDebugSectionOffsets = true; + SupportsDebugInformation = true; + + PCSymbol = "."; + + // Set up DWARF directives + HasLEB128 = true; // Target asm supports leb128 directives (little-endian) + + // Exceptions handling + if (!is64Bit) + ExceptionsType = ExceptionHandling::Dwarf; + AbsoluteEHSectionOffsets = false; + + ZeroDirective = "\t.space\t"; + SetDirective = "\t.set"; + Data64bitsDirective = is64Bit ? "\t.quad\t" : 0; + AlignmentIsInBytes = false; + LCOMMDirective = "\t.lcomm\t"; + AssemblerDialect = 0; // Old-Style mnemonics. +} + diff --git a/lib/Target/PowerPC/PPCMCAsmInfo.h b/lib/Target/PowerPC/PPCMCAsmInfo.h new file mode 100644 index 0000000..96ae6fb --- /dev/null +++ b/lib/Target/PowerPC/PPCMCAsmInfo.h @@ -0,0 +1,31 @@ +//=====-- PPCMCAsmInfo.h - PPC asm properties -----------------*- C++ -*--====// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the MCAsmInfoDarwin class. +// +//===----------------------------------------------------------------------===// + +#ifndef PPCTARGETASMINFO_H +#define PPCTARGETASMINFO_H + +#include "llvm/MC/MCAsmInfoDarwin.h" + +namespace llvm { + + struct PPCMCAsmInfoDarwin : public MCAsmInfoDarwin { + explicit PPCMCAsmInfoDarwin(bool is64Bit); + }; + + struct PPCLinuxMCAsmInfo : public MCAsmInfo { + explicit PPCLinuxMCAsmInfo(bool is64Bit); + }; + +} // namespace llvm + +#endif diff --git a/lib/Target/PowerPC/PPCMachOWriterInfo.cpp b/lib/Target/PowerPC/PPCMachOWriterInfo.cpp index 3bfa6d7..4c14454 100644 --- a/lib/Target/PowerPC/PPCMachOWriterInfo.cpp +++ b/lib/Target/PowerPC/PPCMachOWriterInfo.cpp @@ -16,6 +16,7 @@ #include "PPCTargetMachine.h" #include "llvm/CodeGen/MachORelocation.h" #include "llvm/Support/OutputBuffer.h" +#include "llvm/Support/ErrorHandling.h" #include <cstdio> using namespace llvm; @@ -46,9 +47,9 @@ unsigned PPCMachOWriterInfo::GetTargetRelocation(MachineRelocation &MR, Addr = (uintptr_t)MR.getResultPointer() + ToAddr; switch ((PPC::RelocationType)MR.getRelocationType()) { - default: assert(0 && "Unknown PPC relocation type!"); + default: llvm_unreachable("Unknown PPC relocation type!"); case PPC::reloc_absolute_low_ix: - assert(0 && "Unhandled PPC relocation type!"); + llvm_unreachable("Unhandled PPC relocation type!"); break; case PPC::reloc_vanilla: { diff --git a/lib/Target/PowerPC/PPCPredicates.cpp b/lib/Target/PowerPC/PPCPredicates.cpp index 08a2812..12bb0a1 100644 --- a/lib/Target/PowerPC/PPCPredicates.cpp +++ b/lib/Target/PowerPC/PPCPredicates.cpp @@ -12,12 +12,13 @@ //===----------------------------------------------------------------------===// #include "PPCPredicates.h" +#include "llvm/Support/ErrorHandling.h" #include <cassert> using namespace llvm; PPC::Predicate PPC::InvertPredicate(PPC::Predicate Opcode) { switch (Opcode) { - default: assert(0 && "Unknown PPC branch opcode!"); + default: llvm_unreachable("Unknown PPC branch opcode!"); case PPC::PRED_EQ: return PPC::PRED_NE; case PPC::PRED_NE: return PPC::PRED_EQ; case PPC::PRED_LT: return PPC::PRED_GE; diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp index 97b1c57..cf5c7c0 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -37,7 +37,9 @@ #include "llvm/Target/TargetOptions.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" #include <cstdlib> @@ -111,8 +113,7 @@ unsigned PPCRegisterInfo::getRegisterNumbering(unsigned RegEnum) { case R30: case X30: case F30: case V30: case CR7EQ: return 30; case R31: case X31: case F31: case V31: case CR7UN: return 31; default: - cerr << "Unhandled reg in PPCRegisterInfo::getRegisterNumbering!\n"; - abort(); + llvm_unreachable("Unhandled reg in PPCRegisterInfo::getRegisterNumbering!"); } } @@ -139,11 +140,11 @@ PPCRegisterInfo::PPCRegisterInfo(const PPCSubtarget &ST, /// getPointerRegClass - Return the register class to use to hold pointers. /// This is used for addressing modes. -const TargetRegisterClass *PPCRegisterInfo::getPointerRegClass() const { +const TargetRegisterClass * +PPCRegisterInfo::getPointerRegClass(unsigned Kind) const { if (Subtarget.isPPC64()) return &PPC::G8RCRegClass; - else - return &PPC::GPRCRegClass; + return &PPC::GPRCRegClass; } const unsigned* @@ -173,7 +174,8 @@ PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { PPC::LR, 0 }; - + + // 32-bit SVR4 calling convention. static const unsigned SVR4_CalleeSavedRegs[] = { PPC::R14, PPC::R15, PPC::R16, PPC::R17, PPC::R18, PPC::R19, @@ -199,7 +201,7 @@ PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { PPC::CR3LT, PPC::CR3GT, PPC::CR3EQ, PPC::CR3UN, PPC::CR4LT, PPC::CR4GT, PPC::CR4EQ, PPC::CR4UN, - PPC::LR, 0 + 0 }; // 64-bit Darwin calling convention. static const unsigned Darwin64_CalleeSavedRegs[] = { @@ -226,12 +228,41 @@ PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { PPC::LR8, 0 }; + + // 64-bit SVR4 calling convention. + static const unsigned SVR4_64_CalleeSavedRegs[] = { + PPC::X14, PPC::X15, + PPC::X16, PPC::X17, PPC::X18, PPC::X19, + PPC::X20, PPC::X21, PPC::X22, PPC::X23, + PPC::X24, PPC::X25, PPC::X26, PPC::X27, + PPC::X28, PPC::X29, PPC::X30, PPC::X31, + + PPC::F14, PPC::F15, PPC::F16, PPC::F17, + PPC::F18, PPC::F19, PPC::F20, PPC::F21, + PPC::F22, PPC::F23, PPC::F24, PPC::F25, + PPC::F26, PPC::F27, PPC::F28, PPC::F29, + PPC::F30, PPC::F31, + + PPC::CR2, PPC::CR3, PPC::CR4, + + PPC::VRSAVE, + + PPC::V20, PPC::V21, PPC::V22, PPC::V23, + PPC::V24, PPC::V25, PPC::V26, PPC::V27, + PPC::V28, PPC::V29, PPC::V30, PPC::V31, + + PPC::CR2LT, PPC::CR2GT, PPC::CR2EQ, PPC::CR2UN, + PPC::CR3LT, PPC::CR3GT, PPC::CR3EQ, PPC::CR3UN, + PPC::CR4LT, PPC::CR4GT, PPC::CR4EQ, PPC::CR4UN, + + 0 + }; if (Subtarget.isDarwinABI()) return Subtarget.isPPC64() ? Darwin64_CalleeSavedRegs : Darwin32_CalleeSavedRegs; - - return SVR4_CalleeSavedRegs; + + return Subtarget.isPPC64() ? SVR4_64_CalleeSavedRegs : SVR4_CalleeSavedRegs; } const TargetRegisterClass* const* @@ -266,6 +297,7 @@ PPCRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { &PPC::GPRCRegClass, 0 }; + // 32-bit SVR4 calling convention. static const TargetRegisterClass * const SVR4_CalleeSavedRegClasses[] = { &PPC::GPRCRegClass,&PPC::GPRCRegClass, &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass, @@ -294,7 +326,7 @@ PPCRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { &PPC::CRBITRCRegClass,&PPC::CRBITRCRegClass,&PPC::CRBITRCRegClass, &PPC::CRBITRCRegClass, - &PPC::GPRCRegClass, 0 + 0 }; // 64-bit Darwin calling convention. @@ -326,12 +358,45 @@ PPCRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { &PPC::G8RCRegClass, 0 }; + + // 64-bit SVR4 calling convention. + static const TargetRegisterClass * const SVR4_64_CalleeSavedRegClasses[] = { + &PPC::G8RCRegClass,&PPC::G8RCRegClass, + &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, + &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, + &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, + &PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass,&PPC::G8RCRegClass, + + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass, + &PPC::F8RCRegClass,&PPC::F8RCRegClass, + + &PPC::CRRCRegClass,&PPC::CRRCRegClass,&PPC::CRRCRegClass, + + &PPC::VRSAVERCRegClass, + + &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass, + &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass, + &PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass, + + &PPC::CRBITRCRegClass,&PPC::CRBITRCRegClass,&PPC::CRBITRCRegClass, + &PPC::CRBITRCRegClass, + &PPC::CRBITRCRegClass,&PPC::CRBITRCRegClass,&PPC::CRBITRCRegClass, + &PPC::CRBITRCRegClass, + &PPC::CRBITRCRegClass,&PPC::CRBITRCRegClass,&PPC::CRBITRCRegClass, + &PPC::CRBITRCRegClass, + + 0 + }; if (Subtarget.isDarwinABI()) return Subtarget.isPPC64() ? Darwin64_CalleeSavedRegClasses : Darwin32_CalleeSavedRegClasses; - return SVR4_CalleeSavedRegClasses; + return Subtarget.isPPC64() ? SVR4_64_CalleeSavedRegClasses + : SVR4_CalleeSavedRegClasses; } // needsFP - Return true if the specified function should have a dedicated frame @@ -363,9 +428,9 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const { Reserved.set(PPC::R13); // Small Data Area pointer register } - // On PPC64, r13 is the thread pointer. Never allocate this register. Note - // that this is over conservative, as it also prevents allocation of R31 when - // the FP is not needed. + // On PPC64, r13 is the thread pointer. Never allocate this register. + // Note that this is over conservative, as it also prevents allocation of R31 + // when the FP is not needed. if (Subtarget.isPPC64()) { Reserved.set(PPC::R13); Reserved.set(PPC::R31); @@ -377,6 +442,11 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const { Reserved.set(PPC::X1); Reserved.set(PPC::X13); Reserved.set(PPC::X31); + + // The 64-bit SVR4 ABI reserves r2 for the TOC pointer. + if (Subtarget.isSVR4ABI()) { + Reserved.set(PPC::X2); + } } if (needsFP(MF)) @@ -457,7 +527,7 @@ static unsigned findScratchRegister(MachineBasicBlock::iterator II, RegScavenger *RS, const TargetRegisterClass *RC, int SPAdj) { assert(RS && "Register scavenging must be on"); - unsigned Reg = RS->FindUnusedReg(RC, true); + unsigned Reg = RS->FindUnusedReg(RC); // FIXME: move ARM callee-saved reg scan to target independent code, then // search for already spilled CS register here. if (Reg == 0) @@ -629,8 +699,10 @@ void PPCRegisterInfo::lowerCRSpilling(MachineBasicBlock::iterator II, MBB.erase(II); } -void PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, RegScavenger *RS) const { +unsigned +PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, + int SPAdj, int *Value, + RegScavenger *RS) const { assert(SPAdj == 0 && "Unexpected"); // Get the instruction. @@ -669,14 +741,14 @@ void PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, if (FPSI && FrameIndex == FPSI && (OpC == PPC::DYNALLOC || OpC == PPC::DYNALLOC8)) { lowerDynamicAlloc(II, SPAdj, RS); - return; + return 0; } // Special case for pseudo-op SPILL_CR. if (EnableRegisterScavenging) // FIXME (64-bit): Enable by default. if (OpC == PPC::SPILL_CR) { lowerCRSpilling(II, FrameIndex, SPAdj, RS); - return; + return 0; } // Replace the FrameIndex with base register with GPR1 (SP) or GPR31 (FP). @@ -718,7 +790,7 @@ void PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, if (isIXAddr) Offset >>= 2; // The actual encoded value has the low two bits zero. MI.getOperand(OffsetOperandNo).ChangeToImmediate(Offset); - return; + return 0; } // The offset doesn't fit into a single register, scavenge one to build the @@ -758,6 +830,7 @@ void PPCRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, unsigned StackReg = MI.getOperand(FIOperandNo).getReg(); MI.getOperand(OperandBase).ChangeToRegister(StackReg, false); MI.getOperand(OperandBase + 1).ChangeToRegister(SReg, false); + return 0; } /// VRRegNo - Map from a numbered VR register to its enum value. @@ -910,7 +983,7 @@ void PPCRegisterInfo::determineFrameLayout(MachineFunction &MF) const { // don't have a frame pointer, calls, or dynamic alloca then we do not need // to adjust the stack pointer (we fit in the Red Zone). bool DisableRedZone = MF.getFunction()->hasFnAttr(Attribute::NoRedZone); - // FIXME SVR4 The SVR4 ABI has no red zone. + // FIXME SVR4 The 32-bit SVR4 ABI has no red zone. if (!DisableRedZone && FrameSize <= 224 && // Fits in red zone. !MFI->hasVarSizedObjects() && // No dynamic alloca. @@ -1005,7 +1078,7 @@ PPCRegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) if (!Subtarget.isSVR4ABI()) { return; } - + // Get callee saved register information. MachineFrameInfo *FFI = MF.getFrameInfo(); const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo(); @@ -1016,16 +1089,19 @@ PPCRegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) } unsigned MinGPR = PPC::R31; + unsigned MinG8R = PPC::X31; unsigned MinFPR = PPC::F31; unsigned MinVR = PPC::V31; bool HasGPSaveArea = false; + bool HasG8SaveArea = false; bool HasFPSaveArea = false; bool HasCRSaveArea = false; bool HasVRSAVESaveArea = false; bool HasVRSaveArea = false; SmallVector<CalleeSavedInfo, 18> GPRegs; + SmallVector<CalleeSavedInfo, 18> G8Regs; SmallVector<CalleeSavedInfo, 18> FPRegs; SmallVector<CalleeSavedInfo, 18> VRegs; @@ -1041,6 +1117,14 @@ PPCRegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) if (Reg < MinGPR) { MinGPR = Reg; } + } else if (RC == PPC::G8RCRegisterClass) { + HasG8SaveArea = true; + + G8Regs.push_back(CSI[i]); + + if (Reg < MinG8R) { + MinG8R = Reg; + } } else if (RC == PPC::F8RCRegisterClass) { HasFPSaveArea = true; @@ -1064,7 +1148,7 @@ PPCRegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) MinVR = Reg; } } else { - assert(0 && "Unknown RegisterClass!"); + llvm_unreachable("Unknown RegisterClass!"); } } @@ -1103,7 +1187,7 @@ PPCRegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) // General register save area starts right below the Floating-point // register save area. - if (HasGPSaveArea) { + if (HasGPSaveArea || HasG8SaveArea) { // Move general register save area spill slots down, taking into account // the size of the Floating-point register save area. for (unsigned i = 0, e = GPRegs.size(); i != e; ++i) { @@ -1112,7 +1196,22 @@ PPCRegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); } - LowerBound -= (31 - getRegisterNumbering(MinGPR) + 1) * 4; + // Move general register save area spill slots down, taking into account + // the size of the Floating-point register save area. + for (unsigned i = 0, e = G8Regs.size(); i != e; ++i) { + int FI = G8Regs[i].getFrameIdx(); + + FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI)); + } + + unsigned MinReg = std::min<unsigned>(getRegisterNumbering(MinGPR), + getRegisterNumbering(MinG8R)); + + if (Subtarget.isPPC64()) { + LowerBound -= (31 - MinReg + 1) * 8; + } else { + LowerBound -= (31 - MinReg + 1) * 4; + } } // The CR save area is below the general register save area. diff --git a/lib/Target/PowerPC/PPCRegisterInfo.h b/lib/Target/PowerPC/PPCRegisterInfo.h index ddaefdd..1689bc2 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.h +++ b/lib/Target/PowerPC/PPCRegisterInfo.h @@ -37,7 +37,7 @@ public: /// getPointerRegClass - Return the register class to use to hold pointers. /// This is used for addressing modes. - virtual const TargetRegisterClass *getPointerRegClass() const; + virtual const TargetRegisterClass *getPointerRegClass(unsigned Kind=0) const; /// Code Generation virtual methods... const unsigned *getCalleeSavedRegs(const MachineFunction* MF = 0) const; @@ -66,8 +66,9 @@ public: int SPAdj, RegScavenger *RS) const; void lowerCRSpilling(MachineBasicBlock::iterator II, unsigned FrameIndex, int SPAdj, RegScavenger *RS) const; - void eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, RegScavenger *RS = NULL) const; + unsigned eliminateFrameIndex(MachineBasicBlock::iterator II, + int SPAdj, int *Value = NULL, + RegScavenger *RS = NULL) const; /// determineFrameLayout - Determine the size of the frame and maximum call /// frame size. diff --git a/lib/Target/PowerPC/PPCRegisterInfo.td b/lib/Target/PowerPC/PPCRegisterInfo.td index bac8e3a..049e893 100644 --- a/lib/Target/PowerPC/PPCRegisterInfo.td +++ b/lib/Target/PowerPC/PPCRegisterInfo.td @@ -255,6 +255,11 @@ def CTR8 : SPR<9, "ctr">, DwarfRegNum<[66]>; // VRsave register def VRSAVE: SPR<256, "VRsave">, DwarfRegNum<[107]>; +// Carry bit. In the architecture this is really bit 0 of the XER register +// (which really is SPR register 1); this is the only bit interesting to a +// compiler. +def CARRY: SPR<1, "ca">, DwarfRegNum<[0]>; + // FP rounding mode: bits 30 and 31 of the FP status and control register // This is not allocated as a normal register; it appears only in // Uses and Defs. The ABI says it needs to be preserved by a function, @@ -280,7 +285,8 @@ def GPRC : RegisterClass<"PPC", [i32], 32, let MethodBodies = [{ GPRCClass::iterator GPRCClass::allocation_order_begin(const MachineFunction &MF) const { - // In Linux, r2 is reserved for the OS. + // 32-bit SVR4 ABI: r2 is reserved for the OS. + // 64-bit SVR4 ABI: r2 is reserved for the TOC pointer. if (!MF.getTarget().getSubtarget<PPCSubtarget>().isDarwin()) return begin()+1; @@ -291,7 +297,7 @@ def GPRC : RegisterClass<"PPC", [i32], 32, // On PPC64, r13 is the thread pointer. Never allocate this register. // Note that this is overconservative, as it also prevents allocation of // R31 when the FP is not needed. - // When using the SVR4 ABI, r13 is reserved for the Small Data Area + // When using the 32-bit SVR4 ABI, r13 is reserved for the Small Data Area // pointer. const PPCSubtarget &Subtarget = MF.getTarget().getSubtarget<PPCSubtarget>(); @@ -318,6 +324,10 @@ def G8RC : RegisterClass<"PPC", [i64], 64, let MethodBodies = [{ G8RCClass::iterator G8RCClass::allocation_order_begin(const MachineFunction &MF) const { + // 64-bit SVR4 ABI: r2 is reserved for the TOC pointer. + if (!MF.getTarget().getSubtarget<PPCSubtarget>().isDarwin()) + return begin()+1; + return begin(); } G8RCClass::iterator @@ -372,4 +382,6 @@ def CRRC : RegisterClass<"PPC", [i32], 32, [CR0, CR1, CR5, CR6, CR7, CR2, def CTRRC : RegisterClass<"PPC", [i32], 32, [CTR]>; def CTRRC8 : RegisterClass<"PPC", [i64], 64, [CTR8]>; def VRSAVERC : RegisterClass<"PPC", [i32], 32, [VRSAVE]>; - +def CARRYRC : RegisterClass<"PPC", [i32], 32, [CARRY]> { + let CopyCost = -1; +} diff --git a/lib/Target/PowerPC/PPCSubtarget.cpp b/lib/Target/PowerPC/PPCSubtarget.cpp index 425d8e6..f75e781 100644 --- a/lib/Target/PowerPC/PPCSubtarget.cpp +++ b/lib/Target/PowerPC/PPCSubtarget.cpp @@ -13,7 +13,7 @@ #include "PPCSubtarget.h" #include "PPC.h" -#include "llvm/Module.h" +#include "llvm/GlobalValue.h" #include "llvm/Target/TargetMachine.h" #include "PPCGenSubtarget.inc" #include <cstdlib> @@ -57,10 +57,9 @@ static const char *GetCurrentPowerPCCPU() { #endif -PPCSubtarget::PPCSubtarget(const TargetMachine &tm, const Module &M, - const std::string &FS, bool is64Bit) - : TM(tm) - , StackAlignment(16) +PPCSubtarget::PPCSubtarget(const std::string &TT, const std::string &FS, + bool is64Bit) + : StackAlignment(16) , DarwinDirective(PPC::DIR_NONE) , IsGigaProcessor(false) , Has64BitSupport(false) @@ -95,7 +94,6 @@ PPCSubtarget::PPCSubtarget(const TargetMachine &tm, const Module &M, // Set the boolean corresponding to the current target triple, or the default // if one cannot be determined, to true. - const std::string &TT = M.getTargetTriple(); if (TT.length() > 7) { // Determine which version of darwin this is. size_t DarwinPos = TT.find("-darwin"); @@ -105,24 +103,11 @@ PPCSubtarget::PPCSubtarget(const TargetMachine &tm, const Module &M, else DarwinVers = 8; // Minimum supported darwin is Tiger. } - } else if (TT.empty()) { - // Try to autosense the subtarget from the host compiler. -#if defined(__APPLE__) -#if __APPLE_CC__ > 5400 - DarwinVers = 9; // GCC 5400+ is Leopard. -#else - DarwinVers = 8; // Minimum supported darwin is Tiger. -#endif -#endif } // Set up darwin-specific properties. - if (isDarwin()) { + if (isDarwin()) HasLazyResolverStubs = true; - AsmFlavor = NewMnemonic; - } else { - AsmFlavor = OldMnemonic; - } } /// SetJITMode - This is called to inform the subtarget info that we are @@ -138,7 +123,8 @@ void PPCSubtarget::SetJITMode() { /// hasLazyResolverStub - Return true if accesses to the specified global have /// to go through a dyld lazy resolution stub. This means that an extra load /// is required to get the address of the global. -bool PPCSubtarget::hasLazyResolverStub(const GlobalValue *GV) const { +bool PPCSubtarget::hasLazyResolverStub(const GlobalValue *GV, + const TargetMachine &TM) const { // We never hae stubs if HasLazyResolverStubs=false or if in static mode. if (!HasLazyResolverStubs || TM.getRelocationModel() == Reloc::Static) return false; diff --git a/lib/Target/PowerPC/PPCSubtarget.h b/lib/Target/PowerPC/PPCSubtarget.h index f633cc6..02c8ad7 100644 --- a/lib/Target/PowerPC/PPCSubtarget.h +++ b/lib/Target/PowerPC/PPCSubtarget.h @@ -39,18 +39,11 @@ namespace PPC { }; } -class Module; class GlobalValue; class TargetMachine; class PPCSubtarget : public TargetSubtarget { -public: - enum AsmWriterFlavorTy { - OldMnemonic, NewMnemonic, Unset - }; protected: - const TargetMachine &TM; - /// stackAlignment - The minimum alignment known to hold of the stack frame on /// entry to the function and which must be maintained by every function. unsigned StackAlignment; @@ -61,9 +54,6 @@ protected: /// Which cpu directive was used. unsigned DarwinDirective; - /// AsmFlavor - Which PPC asm dialect to use. - AsmWriterFlavorTy AsmFlavor; - /// Used by the ISel to turn in optimizations for POWER4-derived architectures bool IsGigaProcessor; bool Has64BitSupport; @@ -79,10 +69,9 @@ protected: unsigned char DarwinVers; // Is any darwin-ppc platform. public: /// This constructor initializes the data members to match that - /// of the specified module. + /// of the specified triple. /// - PPCSubtarget(const TargetMachine &TM, const Module &M, - const std::string &FS, bool is64Bit); + PPCSubtarget(const std::string &TT, const std::string &FS, bool is64Bit); /// ParseSubtargetFeatures - Parses features string setting specified /// subtarget options. Definition of function is auto generated by tblgen. @@ -132,7 +121,8 @@ public: /// hasLazyResolverStub - Return true if accesses to the specified global have /// to go through a dyld lazy resolution stub. This means that an extra load /// is required to get the address of the global. - bool hasLazyResolverStub(const GlobalValue *GV) const; + bool hasLazyResolverStub(const GlobalValue *GV, + const TargetMachine &TM) const; // Specific obvious features. bool hasFSQRT() const { return HasFSQRT; } @@ -148,12 +138,9 @@ public: /// getDarwinVers - Return the darwin version number, 8 = tiger, 9 = leopard. unsigned getDarwinVers() const { return DarwinVers; } - bool isDarwinABI() const { return isDarwin() || IsPPC64; } - bool isSVR4ABI() const { return !isDarwin() && !IsPPC64; } + bool isDarwinABI() const { return isDarwin(); } + bool isSVR4ABI() const { return !isDarwin(); } - unsigned getAsmFlavor() const { - return AsmFlavor != Unset ? unsigned(AsmFlavor) : 0; - } }; } // End llvm namespace diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp index e9073d6..3371954 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -12,96 +12,38 @@ //===----------------------------------------------------------------------===// #include "PPC.h" -#include "PPCTargetAsmInfo.h" +#include "PPCMCAsmInfo.h" #include "PPCTargetMachine.h" -#include "llvm/Module.h" #include "llvm/PassManager.h" -#include "llvm/Target/TargetMachineRegistry.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetRegistry.h" +#include "llvm/Support/FormattedStream.h" using namespace llvm; -/// PowerPCTargetMachineModule - Note that this is used on hosts that -/// cannot link in a library unless there are references into the -/// library. In particular, it seems that it is not possible to get -/// things to work on Win32 without this. Though it is unused, do not -/// remove it. -extern "C" int PowerPCTargetMachineModule; -int PowerPCTargetMachineModule = 0; - -// Register the targets -static RegisterTarget<PPC32TargetMachine> -X("ppc32", "PowerPC 32"); -static RegisterTarget<PPC64TargetMachine> -Y("ppc64", "PowerPC 64"); - -// Force static initialization. -extern "C" void LLVMInitializePowerPCTarget() { } - -// No assembler printer by default -PPCTargetMachine::AsmPrinterCtorFn PPCTargetMachine::AsmPrinterCtor = 0; - -const TargetAsmInfo *PPCTargetMachine::createTargetAsmInfo() const { - if (Subtarget.isDarwin()) - return new PPCDarwinTargetAsmInfo(*this); - else - return new PPCLinuxTargetAsmInfo(*this); -} - -unsigned PPC32TargetMachine::getJITMatchQuality() { -#if defined(__POWERPC__) || defined (__ppc__) || defined(_POWER) || defined(__PPC__) - if (sizeof(void*) == 4) - return 10; -#endif - return 0; -} -unsigned PPC64TargetMachine::getJITMatchQuality() { -#if defined(__POWERPC__) || defined (__ppc__) || defined(_POWER) || defined(__PPC__) - if (sizeof(void*) == 8) - return 10; -#endif - return 0; -} - -unsigned PPC32TargetMachine::getModuleMatchQuality(const Module &M) { - // We strongly match "powerpc-*". - std::string TT = M.getTargetTriple(); - if (TT.size() >= 8 && std::string(TT.begin(), TT.begin()+8) == "powerpc-") - return 20; - - // If the target triple is something non-powerpc, we don't match. - if (!TT.empty()) return 0; +static const MCAsmInfo *createMCAsmInfo(const Target &T, + const StringRef &TT) { + Triple TheTriple(TT); + bool isPPC64 = TheTriple.getArch() == Triple::ppc64; + if (TheTriple.getOS() == Triple::Darwin) + return new PPCMCAsmInfoDarwin(isPPC64); + return new PPCLinuxMCAsmInfo(isPPC64); - if (M.getEndianness() == Module::BigEndian && - M.getPointerSize() == Module::Pointer32) - return 10; // Weak match - else if (M.getEndianness() != Module::AnyEndianness || - M.getPointerSize() != Module::AnyPointerSize) - return 0; // Match for some other target - - return getJITMatchQuality()/2; } -unsigned PPC64TargetMachine::getModuleMatchQuality(const Module &M) { - // We strongly match "powerpc64-*". - std::string TT = M.getTargetTriple(); - if (TT.size() >= 10 && std::string(TT.begin(), TT.begin()+10) == "powerpc64-") - return 20; - - if (M.getEndianness() == Module::BigEndian && - M.getPointerSize() == Module::Pointer64) - return 10; // Weak match - else if (M.getEndianness() != Module::AnyEndianness || - M.getPointerSize() != Module::AnyPointerSize) - return 0; // Match for some other target +extern "C" void LLVMInitializePowerPCTarget() { + // Register the targets + RegisterTargetMachine<PPC32TargetMachine> A(ThePPC32Target); + RegisterTargetMachine<PPC64TargetMachine> B(ThePPC64Target); - return getJITMatchQuality()/2; + RegisterAsmInfoFn C(ThePPC32Target, createMCAsmInfo); + RegisterAsmInfoFn D(ThePPC64Target, createMCAsmInfo); } -PPCTargetMachine::PPCTargetMachine(const Module &M, const std::string &FS, - bool is64Bit) - : Subtarget(*this, M, FS, is64Bit), +PPCTargetMachine::PPCTargetMachine(const Target &T, const std::string &TT, + const std::string &FS, bool is64Bit) + : LLVMTargetMachine(T, TT), + Subtarget(TT, FS, is64Bit), DataLayout(Subtarget.getTargetDataString()), InstrInfo(*this), FrameInfo(*this, is64Bit), JITInfo(*this, is64Bit), TLInfo(*this), InstrItins(Subtarget.getInstrItineraryData()), MachOWriterInfo(*this) { @@ -118,13 +60,15 @@ PPCTargetMachine::PPCTargetMachine(const Module &M, const std::string &FS, /// groups, which typically degrades performance. bool PPCTargetMachine::getEnableTailMergeDefault() const { return false; } -PPC32TargetMachine::PPC32TargetMachine(const Module &M, const std::string &FS) - : PPCTargetMachine(M, FS, false) { +PPC32TargetMachine::PPC32TargetMachine(const Target &T, const std::string &TT, + const std::string &FS) + : PPCTargetMachine(T, TT, FS, false) { } -PPC64TargetMachine::PPC64TargetMachine(const Module &M, const std::string &FS) - : PPCTargetMachine(M, FS, true) { +PPC64TargetMachine::PPC64TargetMachine(const Target &T, const std::string &TT, + const std::string &FS) + : PPCTargetMachine(T, TT, FS, true) { } @@ -146,20 +90,36 @@ bool PPCTargetMachine::addPreEmitPass(PassManagerBase &PM, return false; } -bool PPCTargetMachine::addAssemblyEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool Verbose, - raw_ostream &Out) { - assert(AsmPrinterCtor && "AsmPrinter was not linked in"); - if (AsmPrinterCtor) - PM.add(AsmPrinterCtor(Out, *this, Verbose)); +bool PPCTargetMachine::addCodeEmitter(PassManagerBase &PM, + CodeGenOpt::Level OptLevel, + MachineCodeEmitter &MCE) { + // The JIT should use the static relocation model in ppc32 mode, PIC in ppc64. + // FIXME: This should be moved to TargetJITInfo!! + if (Subtarget.isPPC64()) { + // We use PIC codegen in ppc64 mode, because otherwise we'd have to use many + // instructions to materialize arbitrary global variable + function + + // constant pool addresses. + setRelocationModel(Reloc::PIC_); + // Temporary workaround for the inability of PPC64 JIT to handle jump + // tables. + DisableJumpTables = true; + } else { + setRelocationModel(Reloc::Static); + } + + // Inform the subtarget that we are in JIT mode. FIXME: does this break macho + // writing? + Subtarget.SetJITMode(); + + // Machine code emitter pass for PowerPC. + PM.add(createPPCCodeEmitterPass(*this, MCE)); return false; } bool PPCTargetMachine::addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, MachineCodeEmitter &MCE) { + JITCodeEmitter &JCE) { // The JIT should use the static relocation model in ppc32 mode, PIC in ppc64. // FIXME: This should be moved to TargetJITInfo!! if (Subtarget.isPPC64()) { @@ -179,19 +139,14 @@ bool PPCTargetMachine::addCodeEmitter(PassManagerBase &PM, Subtarget.SetJITMode(); // Machine code emitter pass for PowerPC. - PM.add(createPPCCodeEmitterPass(*this, MCE)); - if (DumpAsm) { - assert(AsmPrinterCtor && "AsmPrinter was not linked in"); - if (AsmPrinterCtor) - PM.add(AsmPrinterCtor(errs(), *this, true)); - } + PM.add(createPPCJITCodeEmitterPass(*this, JCE)); return false; } bool PPCTargetMachine::addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, JITCodeEmitter &JCE) { + ObjectCodeEmitter &OCE) { // The JIT should use the static relocation model in ppc32 mode, PIC in ppc64. // FIXME: This should be moved to TargetJITInfo!! if (Subtarget.isPPC64()) { @@ -211,43 +166,33 @@ bool PPCTargetMachine::addCodeEmitter(PassManagerBase &PM, Subtarget.SetJITMode(); // Machine code emitter pass for PowerPC. - PM.add(createPPCJITCodeEmitterPass(*this, JCE)); - if (DumpAsm) { - assert(AsmPrinterCtor && "AsmPrinter was not linked in"); - if (AsmPrinterCtor) - PM.add(AsmPrinterCtor(errs(), *this, true)); - } + PM.add(createPPCObjectCodeEmitterPass(*this, OCE)); return false; } bool PPCTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, MachineCodeEmitter &MCE) { // Machine code emitter pass for PowerPC. PM.add(createPPCCodeEmitterPass(*this, MCE)); - if (DumpAsm) { - assert(AsmPrinterCtor && "AsmPrinter was not linked in"); - if (AsmPrinterCtor) - PM.add(AsmPrinterCtor(errs(), *this, true)); - } - return false; } bool PPCTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, JITCodeEmitter &JCE) { // Machine code emitter pass for PowerPC. PM.add(createPPCJITCodeEmitterPass(*this, JCE)); - if (DumpAsm) { - assert(AsmPrinterCtor && "AsmPrinter was not linked in"); - if (AsmPrinterCtor) - PM.add(AsmPrinterCtor(errs(), *this, true)); - } + return false; +} +bool PPCTargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, + CodeGenOpt::Level OptLevel, + ObjectCodeEmitter &OCE) { + // Machine code emitter pass for PowerPC. + PM.add(createPPCObjectCodeEmitterPass(*this, OCE)); return false; } + diff --git a/lib/Target/PowerPC/PPCTargetMachine.h b/lib/Target/PowerPC/PPCTargetMachine.h index c693bf4..3399ac8 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.h +++ b/lib/Target/PowerPC/PPCTargetMachine.h @@ -39,18 +39,9 @@ class PPCTargetMachine : public LLVMTargetMachine { InstrItineraryData InstrItins; PPCMachOWriterInfo MachOWriterInfo; -protected: - virtual const TargetAsmInfo *createTargetAsmInfo() const; - - // To avoid having target depend on the asmprinter stuff libraries, asmprinter - // set this functions to ctor pointer at startup time if they are linked in. - typedef FunctionPass *(*AsmPrinterCtorFn)(raw_ostream &o, - PPCTargetMachine &tm, - bool verbose); - static AsmPrinterCtorFn AsmPrinterCtor; - public: - PPCTargetMachine(const Module &M, const std::string &FS, bool is64Bit); + PPCTargetMachine(const Target &T, const std::string &TT, + const std::string &FS, bool is64Bit); virtual const PPCInstrInfo *getInstrInfo() const { return &InstrInfo; } virtual const PPCFrameInfo *getFrameInfo() const { return &FrameInfo; } @@ -71,26 +62,24 @@ public: return &MachOWriterInfo; } - static void registerAsmPrinter(AsmPrinterCtorFn F) { - AsmPrinterCtor = F; - } - // Pass Pipeline Configuration virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel); virtual bool addPreEmitPass(PassManagerBase &PM, CodeGenOpt::Level OptLevel); - virtual bool addAssemblyEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool Verbose, raw_ostream &Out); virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, MachineCodeEmitter &MCE); + MachineCodeEmitter &MCE); + virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, + JITCodeEmitter &JCE); virtual bool addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, JITCodeEmitter &JCE); + ObjectCodeEmitter &OCE); virtual bool addSimpleCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, MachineCodeEmitter &MCE); + MachineCodeEmitter &MCE); virtual bool addSimpleCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, JITCodeEmitter &JCE); + JITCodeEmitter &JCE); + virtual bool addSimpleCodeEmitter(PassManagerBase &PM, + CodeGenOpt::Level OptLevel, + ObjectCodeEmitter &OCE); virtual bool getEnableTailMergeDefault() const; }; @@ -98,20 +87,16 @@ public: /// class PPC32TargetMachine : public PPCTargetMachine { public: - PPC32TargetMachine(const Module &M, const std::string &FS); - - static unsigned getJITMatchQuality(); - static unsigned getModuleMatchQuality(const Module &M); + PPC32TargetMachine(const Target &T, const std::string &TT, + const std::string &FS); }; /// PPC64TargetMachine - PowerPC 64-bit target machine. /// class PPC64TargetMachine : public PPCTargetMachine { public: - PPC64TargetMachine(const Module &M, const std::string &FS); - - static unsigned getJITMatchQuality(); - static unsigned getModuleMatchQuality(const Module &M); + PPC64TargetMachine(const Target &T, const std::string &TT, + const std::string &FS); }; } // end namespace llvm diff --git a/lib/Target/PowerPC/README.txt b/lib/Target/PowerPC/README.txt index 6e9e6c7..f5e50fc 100644 --- a/lib/Target/PowerPC/README.txt +++ b/lib/Target/PowerPC/README.txt @@ -149,7 +149,7 @@ http://gcc.gnu.org/ml/gcc-patches/2006-02/msg00133.html Implement Newton-Rhapson method for improving estimate instructions to the correct accuracy, and implementing divide as multiply by reciprocal when it has -more than one use. Itanium will want this too. +more than one use. Itanium would want this too. ===-------------------------------------------------------------------------=== diff --git a/lib/Target/PowerPC/TargetInfo/CMakeLists.txt b/lib/Target/PowerPC/TargetInfo/CMakeLists.txt new file mode 100644 index 0000000..058d599 --- /dev/null +++ b/lib/Target/PowerPC/TargetInfo/CMakeLists.txt @@ -0,0 +1,7 @@ +include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. ) + +add_llvm_library(LLVMPowerPCInfo + PowerPCTargetInfo.cpp + ) + +add_dependencies(LLVMPowerPCInfo PowerPCCodeGenTable_gen) diff --git a/lib/Target/PowerPC/TargetInfo/Makefile b/lib/Target/PowerPC/TargetInfo/Makefile new file mode 100644 index 0000000..a101aa4 --- /dev/null +++ b/lib/Target/PowerPC/TargetInfo/Makefile @@ -0,0 +1,15 @@ +##===- lib/Target/PowerPC/TargetInfo/Makefile --------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LEVEL = ../../../.. +LIBRARYNAME = LLVMPowerPCInfo + +# Hack: we need to include 'main' target directory to grab private headers +CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. + +include $(LEVEL)/Makefile.common diff --git a/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp b/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp new file mode 100644 index 0000000..ad607d0 --- /dev/null +++ b/lib/Target/PowerPC/TargetInfo/PowerPCTargetInfo.cpp @@ -0,0 +1,23 @@ +//===-- PowerPCTargetInfo.cpp - PowerPC Target Implementation -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "PPC.h" +#include "llvm/Module.h" +#include "llvm/Target/TargetRegistry.h" +using namespace llvm; + +Target llvm::ThePPC32Target, llvm::ThePPC64Target; + +extern "C" void LLVMInitializePowerPCTargetInfo() { + RegisterTarget<Triple::ppc, /*HasJIT=*/true> + X(ThePPC32Target, "ppc32", "PowerPC 32"); + + RegisterTarget<Triple::ppc64, /*HasJIT=*/true> + Y(ThePPC64Target, "ppc64", "PowerPC 64"); +} |