diff options
Diffstat (limited to 'llvm/lib/Target/PowerPC')
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp | 25 | ||||
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 32 | ||||
-rw-r--r-- | llvm/lib/Target/PowerPC/PPCInstrInfo.td | 6 |
5 files changed, 79 insertions, 14 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp index b34bf9a8a21..11c0ec008b5 100644 --- a/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -233,6 +233,8 @@ namespace { printOperand(MI, OpNo+1); } + virtual void printBasicBlockLabel(const MachineBasicBlock *MBB) const; + virtual bool runOnMachineFunction(MachineFunction &F) = 0; virtual bool doFinalization(Module &M) = 0; @@ -277,6 +279,8 @@ namespace { Data64bitsDirective = 0; // we can't emit a 64-bit unit AlignmentIsInBytes = false; // Alignment is by power of 2. ConstantPoolSection = "\t.const\t"; + // FIXME: Conditionalize jump table section based on PIC + JumpTableSection = ".const"; LCOMMDirective = "\t.lcomm\t"; StaticCtorsSection = ".mod_init_func"; StaticDtorsSection = ".mod_term_func"; @@ -373,13 +377,14 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) { abort(); return; - case MachineOperand::MO_MachineBasicBlock: { - MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); - O << PrivateGlobalPrefix << "BB" << getFunctionNumber() << "_" - << MBBOp->getNumber() << "\t; " << MBBOp->getBasicBlock()->getName(); + case MachineOperand::MO_MachineBasicBlock: + printBasicBlockLabel(MO.getMachineBasicBlock()); + return; + case MachineOperand::MO_JumpTableIndex: + O << PrivateGlobalPrefix << "JTI" << getFunctionNumber() + << '_' << MO.getJumpTableIndex(); + // FIXME: PIC relocation model return; - } - case MachineOperand::MO_ConstantPoolIndex: O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << '_' << MO.getConstantPoolIndex(); @@ -500,6 +505,11 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) { return; } +void PPCAsmPrinter::printBasicBlockLabel(const MachineBasicBlock *MBB) const { + O << PrivateGlobalPrefix << "BB" << getFunctionNumber() << "_" + << MBB->getNumber() << '\t' << CommentString + << MBB->getBasicBlock()->getName(); +} /// runOnMachineFunction - This uses the printMachineInstruction() /// method to print assembly for each instruction. @@ -514,6 +524,9 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) { // Print out constants referenced by the function EmitConstantPool(MF.getConstantPool()); + // Print out jump tables referenced by the function + EmitJumpTableInfo(MF.getJumpTableInfo()); + // Print out labels for the function. const Function *F = MF.getFunction(); switch (F->getLinkage()) { diff --git a/llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp b/llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp index 8d4e1b669a3..c7f2acbd77c 100644 --- a/llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -34,7 +34,7 @@ namespace { // Tracks which instruction references which BasicBlock std::vector<std::pair<MachineBasicBlock*, unsigned*> > BBRefs; // Tracks where each BasicBlock starts - std::map<MachineBasicBlock*, long> BBLocations; + std::map<MachineBasicBlock*, uint64_t> BBLocations; /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr /// @@ -91,8 +91,10 @@ bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) { "JIT relocation model must be set to static or default!"); MCE.startFunction(MF); MCE.emitConstantPool(MF.getConstantPool()); + MCE.initJumpTableInfo(MF.getJumpTableInfo()); for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) emitBasicBlock(*BB); + MCE.emitJumpTableInfo(MF.getJumpTableInfo(), BBLocations); MCE.finishFunction(MF); // Resolve branches to BasicBlocks for the entire function @@ -192,10 +194,13 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { } 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(); + } else if (MO.isConstantPoolIndex() || MO.isJumpTableIndex()) { + if (MO.isConstantPoolIndex()) + rv = MCE.getConstantPoolEntryAddress(MO.getConstantPoolIndex()); + else + rv = MCE.getJumpTableEntryAddress(MO.getJumpTableIndex()); + unsigned Opcode = MI.getOpcode(); - rv = MCE.getConstantPoolEntryAddress(index); if (Opcode == PPC::LIS || Opcode == PPC::ADDIS) { // lis wants hi16(addr) if ((short)rv < 0) rv += 1 << 16; @@ -206,7 +211,7 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { // These load opcodes want lo16(addr) rv &= 0xffff; } else { - assert(0 && "Unknown constant pool using instruction!"); + assert(0 && "Unknown constant pool or jump table using instruction!"); } } else { std::cerr << "ERROR: Unknown type of MachineOperand: " << MO << "\n"; diff --git a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index b699b92afb3..10f074f6ef1 100644 --- a/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -520,7 +520,8 @@ bool PPCDAGToDAGISel::SelectAddrImm(SDOperand N, SDOperand &Disp, && "Cannot handle constant offsets yet!"); Disp = N.getOperand(1).getOperand(0); // The global address. assert(Disp.getOpcode() == ISD::TargetGlobalAddress || - Disp.getOpcode() == ISD::TargetConstantPool); + Disp.getOpcode() == ISD::TargetConstantPool || + Disp.getOpcode() == ISD::TargetJumpTable); Base = N.getOperand(0); return true; // [&g+r] } @@ -661,7 +662,8 @@ bool PPCDAGToDAGISel::SelectAddrImmShift(SDOperand N, SDOperand &Disp, && "Cannot handle constant offsets yet!"); Disp = N.getOperand(1).getOperand(0); // The global address. assert(Disp.getOpcode() == ISD::TargetGlobalAddress || - Disp.getOpcode() == ISD::TargetConstantPool); + Disp.getOpcode() == ISD::TargetConstantPool || + Disp.getOpcode() == ISD::TargetJumpTable); Base = N.getOperand(0); return true; // [&g+r] } @@ -1241,6 +1243,15 @@ void PPCDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) { N->getOperand(4), Chain); return; } + case ISD::BRIND: { + SDOperand Chain, Target; + Select(Chain, N->getOperand(0)); + Select(Target,N->getOperand(1)); + Chain = SDOperand(CurDAG->getTargetNode(PPC::MTCTR, MVT::Other, Target, + Chain), 0); + Result = CurDAG->SelectNodeTo(N, PPC::BCTR, MVT::Other, Chain); + return; + } } SelectCode(Result, Op); diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 18404fcfef7..fac2806c120 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -123,6 +123,7 @@ PPCTargetLowering::PPCTargetLowering(TargetMachine &TM) // appropriate instructions to materialize the address. setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::ConstantPool, MVT::i32, Custom); + setOperationAction(ISD::JumpTable, MVT::i32, Custom); // RET must be custom lowered, to meet ABI requirements setOperationAction(ISD::RET , MVT::Other, Custom); @@ -605,6 +606,36 @@ static SDOperand LowerConstantPool(SDOperand Op, SelectionDAG &DAG) { return Lo; } +static SDOperand LowerJumpTable(SDOperand Op, SelectionDAG &DAG) { + JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); + SDOperand JTI = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32); + SDOperand Zero = DAG.getConstant(0, MVT::i32); + + const TargetMachine &TM = DAG.getTarget(); + + // If this is a non-darwin platform, we don't support non-static relo models + // yet. + if (TM.getRelocationModel() == Reloc::Static || + !TM.getSubtarget<PPCSubtarget>().isDarwin()) { + // Generate non-pic code that has direct accesses to the constant pool. + // The address of the global is just (hi(&g)+lo(&g)). + SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, JTI, Zero); + SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, JTI, Zero); + return DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); + } + + SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, JTI, Zero); + if (TM.getRelocationModel() == Reloc::PIC) { + // With PIC, the first instruction is actually "GR+hi(&G)". + Hi = DAG.getNode(ISD::ADD, MVT::i32, + DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi); + } + + SDOperand Lo = DAG.getNode(PPCISD::Lo, MVT::i32, JTI, Zero); + Lo = DAG.getNode(ISD::ADD, MVT::i32, Hi, Lo); + return Lo; +} + static SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) { GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op); GlobalValue *GV = GSDN->getGlobal(); @@ -1652,6 +1683,7 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { default: assert(0 && "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::JumpTable: return LowerJumpTable(Op, DAG); case ISD::SETCC: return LowerSETCC(Op, DAG); case ISD::VASTART: return LowerVASTART(Op, DAG, VarArgsFrameIndex); case ISD::RET: return LowerRET(Op, DAG); diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td index 449c3bd9cde..8333873f082 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -702,7 +702,7 @@ def MTCTR : XFXForm_7_ext<31, 467, 9, (ops GPRC:$rS), "mtctr $rS", SprMTSPR>, def MTLR : XFXForm_7_ext<31, 467, 8, (ops GPRC:$rS), "mtlr $rS", SprMTSPR>, PPC970_DGroup_First, PPC970_Unit_FXU; -def MFLR : XFXForm_1_ext<31, 339, 8, (ops GPRC:$rT), "mflr $rT", SprMFSPR>, +def MFLR : XFXForm_1_ext<31, 339, 8, (ops GPRC:$rT), "mflr $rT", SprMFSPR>, PPC970_DGroup_First, PPC970_Unit_FXU; // Move to/from VRSAVE: despite being a SPR, the VRSAVE register is renamed like @@ -1015,10 +1015,14 @@ def : Pat<(PPChi tglobaladdr:$in, 0), (LIS tglobaladdr:$in)>; def : Pat<(PPClo tglobaladdr:$in, 0), (LI tglobaladdr:$in)>; def : Pat<(PPChi tconstpool:$in, 0), (LIS tconstpool:$in)>; def : Pat<(PPClo tconstpool:$in, 0), (LI tconstpool:$in)>; +def : Pat<(PPChi tjumptable:$in, 0), (LIS tjumptable:$in)>; +def : Pat<(PPClo tjumptable:$in, 0), (LI tjumptable:$in)>; def : Pat<(add GPRC:$in, (PPChi tglobaladdr:$g, 0)), (ADDIS GPRC:$in, tglobaladdr:$g)>; def : Pat<(add GPRC:$in, (PPChi tconstpool:$g, 0)), (ADDIS GPRC:$in, tconstpool:$g)>; +def : Pat<(add GPRC:$in, (PPChi tjumptable:$g, 0)), + (ADDIS GPRC:$in, tjumptable:$g)>; // Fused negative multiply subtract, alternate pattern def : Pat<(fsub F8RC:$B, (fmul F8RC:$A, F8RC:$C)), |