From 2497e6391f8df05926fe17b5cf08dad61c4797d2 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Thu, 21 Jul 2005 20:44:43 +0000 Subject: [PATCH] Support building non-PIC Remove the LoadHiAddr pseudo-instruction. Optimization of stores to and loads from statics. Force JIT to use new non-PIC codepaths. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22494 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPC.h | 3 + lib/Target/PowerPC/PPC32ISelSimple.cpp | 4 +- lib/Target/PowerPC/PPC64ISelPattern.cpp | 10 +- lib/Target/PowerPC/PPCAsmPrinter.cpp | 42 +++++-- lib/Target/PowerPC/PPCCodeEmitter.cpp | 65 ++++++----- lib/Target/PowerPC/PPCISelPattern.cpp | 142 ++++++++++++++---------- lib/Target/PowerPC/PPCInstrInfo.td | 24 ++-- lib/Target/PowerPC/PPCTargetMachine.cpp | 12 +- 8 files changed, 179 insertions(+), 123 deletions(-) diff --git a/lib/Target/PowerPC/PPC.h b/lib/Target/PowerPC/PPC.h index 944b1f588d1..2761910670d 100644 --- a/lib/Target/PowerPC/PPC.h +++ b/lib/Target/PowerPC/PPC.h @@ -28,6 +28,9 @@ FunctionPass *createPPC32ISelPattern(TargetMachine &TM); FunctionPass *createPPC64ISelPattern(TargetMachine &TM); FunctionPass *createDarwinAsmPrinter(std::ostream &OS, TargetMachine &TM); FunctionPass *createAIXAsmPrinter(std::ostream &OS, TargetMachine &TM); + +extern bool GPOPT; +extern bool PICEnabled; } // end namespace llvm; // GCC #defines PPC on Linux but we use it as our namespace name diff --git a/lib/Target/PowerPC/PPC32ISelSimple.cpp b/lib/Target/PowerPC/PPC32ISelSimple.cpp index 065262c10d5..aabee952499 100644 --- a/lib/Target/PowerPC/PPC32ISelSimple.cpp +++ b/lib/Target/PowerPC/PPC32ISelSimple.cpp @@ -685,7 +685,7 @@ void PPC32ISel::copyConstantToRegister(MachineBasicBlock *MBB, unsigned Reg1 = makeAnotherReg(Type::IntTy); unsigned Opcode = (Ty == Type::FloatTy) ? PPC::LFS : PPC::LFD; // Move value at base + distance into return reg - BuildMI(*MBB, IP, PPC::LOADHiAddr, 2, Reg1) + BuildMI(*MBB, IP, PPC::ADDIS, 2, Reg1) .addReg(getGlobalBaseReg()).addConstantPoolIndex(CPI); BuildMI(*MBB, IP, Opcode, 2, R).addConstantPoolIndex(CPI).addReg(Reg1); } else if (isa(C)) { @@ -696,7 +696,7 @@ void PPC32ISel::copyConstantToRegister(MachineBasicBlock *MBB, unsigned TmpReg = makeAnotherReg(GV->getType()); // Move value at base + distance into return reg - BuildMI(*MBB, IP, PPC::LOADHiAddr, 2, TmpReg) + BuildMI(*MBB, IP, PPC::ADDIS, 2, TmpReg) .addReg(getGlobalBaseReg()).addGlobalAddress(GV); if (GV->hasWeakLinkage() || GV->isExternal()) { diff --git a/lib/Target/PowerPC/PPC64ISelPattern.cpp b/lib/Target/PowerPC/PPC64ISelPattern.cpp index 98e69e9cc46..854ccf024f8 100644 --- a/lib/Target/PowerPC/PPC64ISelPattern.cpp +++ b/lib/Target/PowerPC/PPC64ISelPattern.cpp @@ -563,7 +563,7 @@ unsigned ISel::getConstDouble(double doubleVal, unsigned Result=0) { MachineConstantPool *CP = BB->getParent()->getConstantPool(); ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, doubleVal); unsigned CPI = CP->getConstantPoolIndex(CFP); - BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg()) + BuildMI(BB, PPC::ADDIS, 2, Tmp1).addReg(getGlobalBaseReg()) .addConstantPoolIndex(CPI); BuildMI(BB, PPC::LFD, 2, Result).addConstantPoolIndex(CPI).addReg(Tmp1); return Result; @@ -909,7 +909,7 @@ unsigned ISel::SelectExprFP(SDOperand N, unsigned Result) // Load constant fp value unsigned Tmp4 = MakeReg(MVT::i32); unsigned TmpL = MakeReg(MVT::i32); - BuildMI(BB, PPC::LOADHiAddr, 2, Tmp4).addReg(getGlobalBaseReg()) + BuildMI(BB, PPC::ADDIS, 2, Tmp4).addReg(getGlobalBaseReg()) .addConstantPoolIndex(CPI); BuildMI(BB, PPC::LFD, 2, ConstF).addConstantPoolIndex(CPI).addReg(Tmp4); // Store the hi & low halves of the fp value, currently in int regs @@ -1002,7 +1002,7 @@ unsigned ISel::SelectExpr(SDOperand N) { case ISD::ConstantPool: Tmp1 = cast(N)->getIndex(); Tmp2 = MakeReg(MVT::i64); - BuildMI(BB, PPC::LOADHiAddr, 2, Tmp2).addReg(getGlobalBaseReg()) + BuildMI(BB, PPC::ADDIS, 2, Tmp2).addReg(getGlobalBaseReg()) .addConstantPoolIndex(Tmp1); BuildMI(BB, PPC::LA, 2, Result).addReg(Tmp2).addConstantPoolIndex(Tmp1); return Result; @@ -1015,7 +1015,7 @@ unsigned ISel::SelectExpr(SDOperand N) { case ISD::GlobalAddress: { GlobalValue *GV = cast(N)->getGlobal(); Tmp1 = MakeReg(MVT::i64); - BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg()) + BuildMI(BB, PPC::ADDIS, 2, Tmp1).addReg(getGlobalBaseReg()) .addGlobalAddress(GV); if (GV->hasWeakLinkage() || GV->isExternal()) { BuildMI(BB, PPC::LD, 2, Result).addGlobalAddress(GV).addReg(Tmp1); @@ -1057,7 +1057,7 @@ unsigned ISel::SelectExpr(SDOperand N) { if (ConstantPoolSDNode *CP = dyn_cast(Address)) { Tmp1 = MakeReg(MVT::i64); int CPI = CP->getIndex(); - BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg()) + BuildMI(BB, PPC::ADDIS, 2, Tmp1).addReg(getGlobalBaseReg()) .addConstantPoolIndex(CPI); BuildMI(BB, Opc, 2, Result).addConstantPoolIndex(CPI).addReg(Tmp1); } diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index 992446e76f7..a3d89a39966 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -135,21 +135,28 @@ namespace { } void printSymbolHi(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT) { - O << "ha16("; - printOp(MI->getOperand(OpNo)); - O << "-\"L0000" << LabelNumber << "$pb\")"; + if (MI->getOperand(OpNo).isImmediate()) { + printS16ImmOperand(MI, OpNo, VT); + } else { + O << "ha16("; + printOp(MI->getOperand(OpNo)); + if (PICEnabled) + O << "-\"L0000" << LabelNumber << "$pb\")"; + else + O << ')'; + } } void printSymbolLo(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT) { - // FIXME: Because LFS, LFD, and LWZ can be used either with a s16imm or - // a lo16 of a global or constant pool operand, we must handle both here. - // this isn't a great design, but it works for now. if (MI->getOperand(OpNo).isImmediate()) { - O << (short)MI->getOperand(OpNo).getImmedValue(); + printS16ImmOperand(MI, OpNo, VT); } else { O << "lo16("; printOp(MI->getOperand(OpNo)); - O << "-\"L0000" << LabelNumber << "$pb\")"; + if (PICEnabled) + O << "-\"L0000" << LabelNumber << "$pb\")"; + else + O << ')'; } } void printcrbit(const MachineInstr *MI, unsigned OpNo, @@ -428,9 +435,7 @@ void DarwinAsmPrinter::printConstantPool(MachineConstantPool *MCP) { } bool DarwinAsmPrinter::doInitialization(Module &M) { - // FIXME: implment subtargets for PowerPC and pick this up from there. - O << "\t.machine ppc970\n"; - + if (GPOPT) O << "\t.machine ppc970\n"; AsmPrinter::doInitialization(M); return false; } @@ -504,6 +509,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) { for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); i != e; ++i) { + if (PICEnabled) { O << ".data\n"; O << ".section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32\n"; emitAlignment(2); @@ -523,6 +529,20 @@ bool DarwinAsmPrinter::doFinalization(Module &M) { O << "L" << *i << "$lazy_ptr:\n"; O << "\t.indirect_symbol " << *i << "\n"; O << "\t.long dyld_stub_binding_helper\n"; + } else { + O << "\t.section __TEXT,__symbol_stub1,symbol_stubs,pure_instructions,16\n"; + emitAlignment(4); + O << "L" << *i << "$stub:\n"; + O << "\t.indirect_symbol " << *i << "\n"; + O << "\tlis r11,ha16(L" << *i << "$lazy_ptr)\n"; + O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr)(r11)\n"; + O << "\tmtctr r12\n"; + O << "\tbctr\n"; + O << "\t.lazy_symbol_pointer\n"; + O << "L" << *i << "$lazy_ptr:\n"; + O << "\t.indirect_symbol " << *i << "\n"; + O << "\t.long dyld_stub_binding_helper\n"; + } } O << "\n"; diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index 0b945ab1a11..227d5ba8469 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -28,10 +28,6 @@ namespace { TargetMachine &TM; MachineCodeEmitter &MCE; - /// MovePCtoLROffset - When/if we see a MovePCtoLR instruction, we record - /// its address in the function into this pointer. - void *MovePCtoLROffset; - // Tracks which instruction references which BasicBlock std::vector > BBRefs; // Tracks where each BasicBlock starts @@ -87,7 +83,6 @@ bool PPC32TargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM, } bool PPC32CodeEmitter::runOnMachineFunction(MachineFunction &MF) { - MovePCtoLROffset = 0; MCE.startFunction(MF); MCE.emitConstantPool(MF.getConstantPool()); for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) @@ -120,6 +115,7 @@ bool PPC32CodeEmitter::runOnMachineFunction(MachineFunction &MF) { } void PPC32CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { + assert(!PICEnabled && "CodeEmitter does not support PIC!"); BBLocations[&MBB] = MCE.getCurrentPCValue(); for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){ MachineInstr &MI = *I; @@ -131,10 +127,7 @@ void PPC32CodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { case PPC::IMPLICIT_DEF: break; // pseudo opcode, no side effects case PPC::MovePCtoLR: - assert(MovePCtoLROffset == 0 && - "Multiple MovePCtoLR instructions in the function?"); - MovePCtoLROffset = (void*)(intptr_t)MCE.getCurrentPCValue(); - emitWord(0x48000005); // bl 1 + assert(0 && "CodeEmitter does not support MovePCtoLR instruction"); break; } } @@ -200,55 +193,59 @@ int PPC32CodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { MO.getGlobal()->hasWeakLinkage() || MO.getGlobal()->isExternal(); unsigned Reloc = 0; - int Offset = 0; if (MI.getOpcode() == PPC::CALLpcrel) Reloc = PPC::reloc_pcrel_bx; else { - assert(MovePCtoLROffset && "MovePCtoLR not seen yet?"); - Offset = -((intptr_t)MovePCtoLROffset+4); - - if (MI.getOpcode() == PPC::LOADHiAddr) { + switch (MI.getOpcode()) { + default: MI.dump(); assert(0 && "Unknown instruction for relocation!"); + case PPC::LIS: if (isExternal) Reloc = PPC::reloc_absolute_ptr_high; // Pointer to stub - else + else Reloc = PPC::reloc_absolute_high; // Pointer to symbol - - } else if (MI.getOpcode() == PPC::LA) { + break; + case PPC::LA: assert(!isExternal && "Something in the ISEL changed\n"); - Reloc = PPC::reloc_absolute_low; - } else if (MI.getOpcode() == PPC::LWZ) { - Reloc = PPC::reloc_absolute_ptr_low; - - assert(isExternal && "Something in the ISEL changed\n"); - } else { - // These don't show up for global value references AFAIK, only for - // constant pool refs: PPC::LFS, PPC::LFD - assert(0 && "Unknown instruction for relocation!"); + break; + case PPC::LBZ: + case PPC::LHA: + case PPC::LHZ: + case PPC::LWZ: + case PPC::LFS: + case PPC::LFD: + case PPC::STB: + case PPC::STH: + case PPC::STW: + case PPC::STFS: + case PPC::STFD: + if (isExternal) + Reloc = PPC::reloc_absolute_ptr_low; + else + Reloc = PPC::reloc_absolute_low; + break; } } if (MO.isGlobalAddress()) MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(), - Reloc, MO.getGlobal(), Offset)); + Reloc, MO.getGlobal(), 0)); else MCE.addRelocation(MachineRelocation(MCE.getCurrentPCOffset(), - Reloc, MO.getSymbolName(), Offset)); + Reloc, MO.getSymbolName(), 0)); } else if (MO.isMachineBasicBlock()) { unsigned* CurrPC = (unsigned*)(intptr_t)MCE.getCurrentPCValue(); BBRefs.push_back(std::make_pair(MO.getMachineBasicBlock(), CurrPC)); } else if (MO.isConstantPoolIndex()) { unsigned index = MO.getConstantPoolIndex(); - assert(MovePCtoLROffset && "MovePCtoLR not seen yet?"); - rv = MCE.getConstantPoolEntryAddress(index) - (intptr_t)MovePCtoLROffset-4; - unsigned Opcode = MI.getOpcode(); - if (Opcode == PPC::LOADHiAddr) { - // LoadHiAddr wants hi16(addr - &MovePCtoLR) + rv = MCE.getConstantPoolEntryAddress(index); + if (Opcode == PPC::LIS) { + // lis wants hi16(addr) if ((short)rv < 0) rv += 1 << 16; rv >>= 16; } else if (Opcode == PPC::LWZ || Opcode == PPC::LA || Opcode == PPC::LFS || Opcode == PPC::LFD) { - // These load opcodes want lo16(addr - &MovePCtoLR) + // These load opcodes want lo16(addr) rv &= 0xffff; } else { assert(0 && "Unknown constant pool using instruction!"); diff --git a/lib/Target/PowerPC/PPCISelPattern.cpp b/lib/Target/PowerPC/PPCISelPattern.cpp index 19ef823ad61..09ccd6ae975 100644 --- a/lib/Target/PowerPC/PPCISelPattern.cpp +++ b/lib/Target/PowerPC/PPCISelPattern.cpp @@ -35,11 +35,6 @@ #include using namespace llvm; -// FIXME: temporary. -#include "llvm/Support/CommandLine.h" -static cl::opt EnableGPOPT("enable-gpopt", cl::Hidden, - cl::desc("Enable optimizations for GP cpus")); - //===----------------------------------------------------------------------===// // PPC32TargetLowering - PPC32 Implementation of the TargetLowering interface namespace { @@ -78,7 +73,7 @@ namespace { setOperationAction(ISD::SREM , MVT::f32, Expand); // If we're enabling GP optimizations, use hardware square root - if (!EnableGPOPT) { + if (!GPOPT) { setOperationAction(ISD::FSQRT, MVT::f64, Expand); setOperationAction(ISD::FSQRT, MVT::f32, Expand); } @@ -959,8 +954,11 @@ unsigned ISel::getConstDouble(double doubleVal, unsigned Result=0) { MachineConstantPool *CP = BB->getParent()->getConstantPool(); ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, doubleVal); unsigned CPI = CP->getConstantPoolIndex(CFP); - BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg()) - .addConstantPoolIndex(CPI); + if (PICEnabled) + BuildMI(BB, PPC::ADDIS, 2, Tmp1).addReg(getGlobalBaseReg()) + .addConstantPoolIndex(CPI); + else + BuildMI(BB, PPC::LIS, 1, Tmp1).addConstantPoolIndex(CPI); BuildMI(BB, PPC::LFD, 2, Result).addConstantPoolIndex(CPI).addReg(Tmp1); return Result; } @@ -970,7 +968,7 @@ unsigned ISel::getConstDouble(double doubleVal, unsigned Result=0) { void ISel::MoveCRtoGPR(unsigned CCReg, bool Inv, unsigned Idx, unsigned Result){ unsigned IntCR = MakeReg(MVT::i32); BuildMI(BB, PPC::MCRF, 1, PPC::CR7).addReg(CCReg); - BuildMI(BB, EnableGPOPT ? PPC::MFOCRF : PPC::MFCR, 1, IntCR).addReg(PPC::CR7); + BuildMI(BB, GPOPT ? PPC::MFOCRF : PPC::MFCR, 1, IntCR).addReg(PPC::CR7); if (Inv) { unsigned Tmp1 = MakeReg(MVT::i32); BuildMI(BB, PPC::RLWINM, 4, Tmp1).addReg(IntCR).addImm(32-(3-Idx)) @@ -1359,8 +1357,11 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { case ISD::ConstantPool: Tmp1 = cast(N)->getIndex(); Tmp2 = MakeReg(MVT::i32); - BuildMI(BB, PPC::LOADHiAddr, 2, Tmp2).addReg(getGlobalBaseReg()) - .addConstantPoolIndex(Tmp1); + if (PICEnabled) + BuildMI(BB, PPC::ADDIS, 2, Tmp2).addReg(getGlobalBaseReg()) + .addConstantPoolIndex(Tmp1); + else + BuildMI(BB, PPC::LIS, 1, Tmp2).addConstantPoolIndex(Tmp1); BuildMI(BB, PPC::LA, 2, Result).addReg(Tmp2).addConstantPoolIndex(Tmp1); return Result; @@ -1372,8 +1373,11 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { case ISD::GlobalAddress: { GlobalValue *GV = cast(N)->getGlobal(); Tmp1 = MakeReg(MVT::i32); - BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg()) - .addGlobalAddress(GV); + if (PICEnabled) + BuildMI(BB, PPC::ADDIS, 2, Tmp1).addReg(getGlobalBaseReg()) + .addGlobalAddress(GV); + else + BuildMI(BB, PPC::LIS, 2, Tmp1).addGlobalAddress(GV); if (GV->hasWeakLinkage() || GV->isExternal()) { BuildMI(BB, PPC::LWZ, 2, Result).addGlobalAddress(GV).addReg(Tmp1); } else { @@ -1413,13 +1417,29 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { if (ConstantPoolSDNode *CP = dyn_cast(Address)) { Tmp1 = MakeReg(MVT::i32); int CPI = CP->getIndex(); - BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg()) - .addConstantPoolIndex(CPI); + if (PICEnabled) + BuildMI(BB, PPC::ADDIS, 2, Tmp1).addReg(getGlobalBaseReg()) + .addConstantPoolIndex(CPI); + else + BuildMI(BB, PPC::LIS, 1, Tmp1).addConstantPoolIndex(CPI); BuildMI(BB, Opc, 2, Result).addConstantPoolIndex(CPI).addReg(Tmp1); - } - else if(Address.getOpcode() == ISD::FrameIndex) { + } else if (Address.getOpcode() == ISD::FrameIndex) { Tmp1 = cast(Address)->getIndex(); addFrameReference(BuildMI(BB, Opc, 2, Result), (int)Tmp1); + } else if(GlobalAddressSDNode *GN = dyn_cast(Address)){ + GlobalValue *GV = GN->getGlobal(); + Tmp1 = MakeReg(MVT::i32); + if (PICEnabled) + BuildMI(BB, PPC::ADDIS, 2, Tmp1).addReg(getGlobalBaseReg()) + .addGlobalAddress(GV); + else + BuildMI(BB, PPC::LIS, 2, Tmp1).addGlobalAddress(GV); + if (GV->hasWeakLinkage() || GV->isExternal()) { + Tmp2 = MakeReg(MVT::i32); + BuildMI(BB, PPC::LWZ, 2, Tmp2).addGlobalAddress(GV).addReg(Tmp1); + Tmp1 = Tmp2; + } + BuildMI(BB, Opc, 2, Result).addGlobalAddress(GV).addReg(Tmp1); } else { int offset; bool idx = SelectAddr(Address, Tmp1, offset); @@ -2344,7 +2364,7 @@ unsigned ISel::SelectExpr(SDOperand N, bool Recording) { } void ISel::Select(SDOperand N) { - unsigned Tmp1, Tmp2, Opc; + unsigned Tmp1, Tmp2, Tmp3, Opc; unsigned opcode = N.getOpcode(); if (!ExprMap.insert(std::make_pair(N, 1)).second) @@ -2432,49 +2452,59 @@ void ISel::Select(SDOperand N) { BuildMI(BB, PPC::BLR, 0); // Just emit a 'ret' instruction return; case ISD::TRUNCSTORE: - case ISD::STORE: - { - SDOperand Chain = N.getOperand(0); - SDOperand Value = N.getOperand(1); - SDOperand Address = N.getOperand(2); - Select(Chain); + case ISD::STORE: { + SDOperand Chain = N.getOperand(0); + SDOperand Value = N.getOperand(1); + SDOperand Address = N.getOperand(2); + Select(Chain); - Tmp1 = SelectExpr(Value); //value + Tmp1 = SelectExpr(Value); //value - if (opcode == ISD::STORE) { - switch(Value.getValueType()) { - default: assert(0 && "unknown Type in store"); - case MVT::i32: Opc = PPC::STW; break; - case MVT::f64: Opc = PPC::STFD; break; - case MVT::f32: Opc = PPC::STFS; break; - } - } else { //ISD::TRUNCSTORE - switch(cast(Node->getOperand(4))->getVT()) { - default: assert(0 && "unknown Type in store"); - case MVT::i1: - case MVT::i8: Opc = PPC::STB; break; - case MVT::i16: Opc = PPC::STH; break; - } + if (opcode == ISD::STORE) { + switch(Value.getValueType()) { + default: assert(0 && "unknown Type in store"); + case MVT::i32: Opc = PPC::STW; break; + case MVT::f64: Opc = PPC::STFD; break; + case MVT::f32: Opc = PPC::STFS; break; } - - if(Address.getOpcode() == ISD::FrameIndex) - { - Tmp2 = cast(Address)->getIndex(); - addFrameReference(BuildMI(BB, Opc, 3).addReg(Tmp1), (int)Tmp2); + } else { //ISD::TRUNCSTORE + switch(cast(Node->getOperand(4))->getVT()) { + default: assert(0 && "unknown Type in store"); + case MVT::i1: + case MVT::i8: Opc = PPC::STB; break; + case MVT::i16: Opc = PPC::STH; break; } - else - { - int offset; - bool idx = SelectAddr(Address, Tmp2, offset); - if (idx) { - Opc = IndexedOpForOp(Opc); - BuildMI(BB, Opc, 3).addReg(Tmp1).addReg(Tmp2).addReg(offset); - } else { - BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2); - } - } - return; } + + if(Address.getOpcode() == ISD::FrameIndex) { + Tmp2 = cast(Address)->getIndex(); + addFrameReference(BuildMI(BB, Opc, 3).addReg(Tmp1), (int)Tmp2); + } else if(GlobalAddressSDNode *GN = dyn_cast(Address)){ + GlobalValue *GV = GN->getGlobal(); + Tmp2 = MakeReg(MVT::i32); + if (PICEnabled) + BuildMI(BB, PPC::ADDIS, 2, Tmp2).addReg(getGlobalBaseReg()) + .addGlobalAddress(GV); + else + BuildMI(BB, PPC::LIS, 2, Tmp2).addGlobalAddress(GV); + if (GV->hasWeakLinkage() || GV->isExternal()) { + Tmp3 = MakeReg(MVT::i32); + BuildMI(BB, PPC::LWZ, 2, Tmp3).addGlobalAddress(GV).addReg(Tmp2); + Tmp2 = Tmp3; + } + BuildMI(BB, Opc, 3).addReg(Tmp1).addGlobalAddress(GV).addReg(Tmp2); + } else { + int offset; + bool idx = SelectAddr(Address, Tmp2, offset); + if (idx) { + Opc = IndexedOpForOp(Opc); + BuildMI(BB, Opc, 3).addReg(Tmp1).addReg(Tmp2).addReg(offset); + } else { + BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2); + } + } + return; + } case ISD::EXTLOAD: case ISD::SEXTLOAD: case ISD::ZEXTLOAD: diff --git a/lib/Target/PowerPC/PPCInstrInfo.td b/lib/Target/PowerPC/PPCInstrInfo.td index 087440149bc..1e7c7a57fb1 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.td +++ b/lib/Target/PowerPC/PPCInstrInfo.td @@ -108,17 +108,17 @@ let isCall = 1, // register and an immediate are of this type. // let isLoad = 1 in { -def LBZ : DForm_1<34, (ops GPRC:$rD, s16imm:$disp, GPRC:$rA), +def LBZ : DForm_1<34, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), "lbz $rD, $disp($rA)">; -def LHA : DForm_1<42, (ops GPRC:$rD, s16imm:$disp, GPRC:$rA), +def LHA : DForm_1<42, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), "lha $rD, $disp($rA)">; -def LHZ : DForm_1<40, (ops GPRC:$rD, s16imm:$disp, GPRC:$rA), +def LHZ : DForm_1<40, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), "lhz $rD, $disp($rA)">; def LMW : DForm_1<46, (ops GPRC:$rD, s16imm:$disp, GPRC:$rA), "lmw $rD, $disp($rA)">; def LWZ : DForm_1<32, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), "lwz $rD, $disp($rA)">; -def LWZU : DForm_1<35, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), +def LWZU : DForm_1<35, (ops GPRC:$rD, s16imm:$disp, GPRC:$rA), "lwzu $rD, $disp($rA)">; } def ADDI : DForm_2<14, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), @@ -127,28 +127,26 @@ def ADDIC : DForm_2<12, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), "addic $rD, $rA, $imm">; def ADDICo : DForm_2<13, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), "addic. $rD, $rA, $imm">; -def ADDIS : DForm_2<15, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), +def ADDIS : DForm_2<15, (ops GPRC:$rD, GPRC:$rA, symbolHi:$imm), "addis $rD, $rA, $imm">; def LA : DForm_2<14, (ops GPRC:$rD, GPRC:$rA, symbolLo:$sym), "la $rD, $sym($rA)">; -def LOADHiAddr : DForm_2<15, (ops GPRC:$rD, GPRC:$rA, symbolHi:$sym), - "addis $rD, $rA, $sym">; def MULLI : DForm_2< 7, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), "mulli $rD, $rA, $imm">; def SUBFIC : DForm_2< 8, (ops GPRC:$rD, GPRC:$rA, s16imm:$imm), "subfic $rD, $rA, $imm">; def LI : DForm_2_r0<14, (ops GPRC:$rD, s16imm:$imm), "li $rD, $imm">; -def LIS : DForm_2_r0<15, (ops GPRC:$rD, s16imm:$imm), +def LIS : DForm_2_r0<15, (ops GPRC:$rD, symbolHi:$imm), "lis $rD, $imm">; let isStore = 1 in { def STMW : DForm_3<47, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA), "stmw $rS, $disp($rA)">; -def STB : DForm_3<38, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA), +def STB : DForm_3<38, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA), "stb $rS, $disp($rA)">; -def STH : DForm_3<44, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA), +def STH : DForm_3<44, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA), "sth $rS, $disp($rA)">; -def STW : DForm_3<36, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA), +def STW : DForm_3<36, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA), "stw $rS, $disp($rA)">; def STWU : DForm_3<37, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA), "stwu $rS, $disp($rA)">; @@ -185,9 +183,9 @@ def LFD : DForm_8<50, (ops GPRC:$rD, symbolLo:$disp, GPRC:$rA), "lfd $rD, $disp($rA)">; } let isStore = 1 in { -def STFS : DForm_9<52, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA), +def STFS : DForm_9<52, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA), "stfs $rS, $disp($rA)">; -def STFD : DForm_9<54, (ops GPRC:$rS, s16imm:$disp, GPRC:$rA), +def STFD : DForm_9<54, (ops GPRC:$rS, symbolLo:$disp, GPRC:$rA), "stfd $rS, $disp($rA)">; } diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp index d2a9781d5d7..74acf45fe96 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -29,6 +29,8 @@ #include using namespace llvm; +bool llvm::GPOPT = false; + namespace llvm { cl::opt AIX("aix", cl::desc("Generate AIX/xcoff instead of Darwin/MachO"), @@ -36,6 +38,9 @@ namespace llvm { cl::opt EnablePPCLSR("enable-lsr-for-ppc", cl::desc("Enable LSR for PPC (beta)"), cl::Hidden); + cl::opt EnableGPOPT("enable-gpopt", cl::Hidden, + cl::location(GPOPT), + cl::desc("Enable optimizations for GP cpus")); } namespace { @@ -127,8 +132,11 @@ bool PowerPCTargetMachine::addPassesToEmitFile(PassManager &PM, } void PowerPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) { - bool LP64 = (0 != dynamic_cast(&TM)); + // The JIT does not support or need PIC. + PICEnabled = false; + bool LP64 = (0 != dynamic_cast(&TM)); + if (EnablePPCLSR) { PM.add(createLoopStrengthReducePass()); PM.add(createCFGSimplificationPass()); @@ -170,7 +178,7 @@ void PowerPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) { /// PPC32TargetMachine::PPC32TargetMachine(const Module &M, IntrinsicLowering *IL) : PowerPCTargetMachine(PPC32ID, IL, - TargetData(PPC32ID,false,4,4,8,4,4,4,2,1,1), + TargetData(PPC32ID,false,4,4,4,4,4,4,2,1,1), PowerPCFrameInfo(*this, false)), JITInfo(*this) {} /// PPC64TargetMachine ctor - Create a LP64 architecture model