aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2005-07-21 20:44:43 +0000
committerNate Begeman <natebegeman@mac.com>2005-07-21 20:44:43 +0000
commit2497e6391f8df05926fe17b5cf08dad61c4797d2 (patch)
treefcd77e313058c02770557562cfd34229137702bc
parent2130c0893041718f6d5c2bf3df4ba0ddce9adb08 (diff)
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
-rw-r--r--lib/Target/PowerPC/PPC.h3
-rw-r--r--lib/Target/PowerPC/PPC32ISelSimple.cpp4
-rw-r--r--lib/Target/PowerPC/PPC64ISelPattern.cpp10
-rw-r--r--lib/Target/PowerPC/PPCAsmPrinter.cpp42
-rw-r--r--lib/Target/PowerPC/PPCCodeEmitter.cpp65
-rw-r--r--lib/Target/PowerPC/PPCISelPattern.cpp142
-rw-r--r--lib/Target/PowerPC/PPCInstrInfo.td24
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.cpp12
8 files changed, 179 insertions, 123 deletions
diff --git a/lib/Target/PowerPC/PPC.h b/lib/Target/PowerPC/PPC.h
index 944b1f588d..2761910670 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 065262c10d..aabee95249 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<ConstantPointerNull>(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 98e69e9cc4..854ccf024f 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<ConstantPoolSDNode>(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<GlobalAddressSDNode>(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<ConstantPoolSDNode>(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 992446e76f..a3d89a3996 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<std::string>::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 0b945ab1a1..227d5ba846 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<std::pair<MachineBasicBlock*, unsigned*> > 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 19ef823ad6..09ccd6ae97 100644
--- a/lib/Target/PowerPC/PPCISelPattern.cpp
+++ b/lib/Target/PowerPC/PPCISelPattern.cpp
@@ -35,11 +35,6 @@
#include <algorithm>
using namespace llvm;
-// FIXME: temporary.
-#include "llvm/Support/CommandLine.h"
-static cl::opt<bool> 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<ConstantPoolSDNode>(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<GlobalAddressSDNode>(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<ConstantPoolSDNode>(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<FrameIndexSDNode>(Address)->getIndex();
addFrameReference(BuildMI(BB, Opc, 2, Result), (int)Tmp1);
+ } else if(GlobalAddressSDNode *GN = dyn_cast<GlobalAddressSDNode>(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);
-
- 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<VTSDNode>(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;
- }
- }
+ case ISD::STORE: {
+ SDOperand Chain = N.getOperand(0);
+ SDOperand Value = N.getOperand(1);
+ SDOperand Address = N.getOperand(2);
+ Select(Chain);
- if(Address.getOpcode() == ISD::FrameIndex)
- {
- Tmp2 = cast<FrameIndexSDNode>(Address)->getIndex();
- addFrameReference(BuildMI(BB, Opc, 3).addReg(Tmp1), (int)Tmp2);
+ 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<VTSDNode>(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(Address.getOpcode() == ISD::FrameIndex) {
+ Tmp2 = cast<FrameIndexSDNode>(Address)->getIndex();
+ addFrameReference(BuildMI(BB, Opc, 3).addReg(Tmp1), (int)Tmp2);
+ } else if(GlobalAddressSDNode *GN = dyn_cast<GlobalAddressSDNode>(Address)){
+ GlobalValue *GV = GN->getGlobal();
+ Tmp2 = MakeReg(MVT::i32);
+ if (PICEnabled)
+ BuildMI(BB, PPC::ADDIS, 2, Tmp2).addReg(getGlobalBaseReg())
+ .addGlobalAddress(GV);
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);
- }
+ 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;
}
+ 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 087440149b..1e7c7a57fb 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 d2a9781d5d..74acf45fe9 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -29,6 +29,8 @@
#include <iostream>
using namespace llvm;
+bool llvm::GPOPT = false;
+
namespace llvm {
cl::opt<bool> AIX("aix",
cl::desc("Generate AIX/xcoff instead of Darwin/MachO"),
@@ -36,6 +38,9 @@ namespace llvm {
cl::opt<bool> EnablePPCLSR("enable-lsr-for-ppc",
cl::desc("Enable LSR for PPC (beta)"),
cl::Hidden);
+ cl::opt<bool, true> 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<PPC64TargetMachine *>(&TM));
+ // The JIT does not support or need PIC.
+ PICEnabled = false;
+ bool LP64 = (0 != dynamic_cast<PPC64TargetMachine *>(&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