Index: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h @@ -770,6 +770,15 @@ void insertSSPDeclarations(Module &M) const override; bool isFPImmLegal(const APFloat &Imm, EVT VT) const override; + + unsigned getJumpTableEncoding() const override; + bool isJumpTableRelative() const override; + SDValue getPICJumpTableRelocBase(SDValue Table, + SelectionDAG &DAG) const override; + const MCExpr *getPICJumpTableRelocBaseExpr(const MachineFunction *MF, + unsigned JTI, + MCContext &Ctx) const override; + private: struct ReuseLoadInfo { SDValue Ptr; Index: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp @@ -27,6 +27,7 @@ #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/SelectionDAG.h" @@ -2179,6 +2180,55 @@ return LowerLabelRef(CPIHi, CPILo, IsPIC, DAG); } +// For 64-bit PowerPC, prefer the more compact relative encodings. +// This trades 32 bits per jump table entry for one or two instructions +// on the jump site. +unsigned PPCTargetLowering::getJumpTableEncoding() const { + if (isJumpTableRelative()) + return MachineJumpTableInfo::EK_LabelDifference32; + + return TargetLowering::getJumpTableEncoding(); +} + +bool PPCTargetLowering::isJumpTableRelative() const { + if (Subtarget.isPPC64()) + return true; + return TargetLowering::isJumpTableRelative(); +} + +SDValue PPCTargetLowering::getPICJumpTableRelocBase(SDValue Table, + SelectionDAG &DAG) const { + if (!Subtarget.isPPC64()) + return TargetLowering::getPICJumpTableRelocBase(Table, DAG); + + switch (getTargetMachine().getCodeModel()) { + case CodeModel::Default: + case CodeModel::Small: + case CodeModel::Medium: + return TargetLowering::getPICJumpTableRelocBase(Table, DAG); + default: + return DAG.getNode(PPCISD::GlobalBaseReg, SDLoc(), + getPointerTy(DAG.getDataLayout())); + } +} + +const MCExpr * +PPCTargetLowering::getPICJumpTableRelocBaseExpr(const MachineFunction *MF, + unsigned JTI, + MCContext &Ctx) const { + if (!Subtarget.isPPC64()) + return TargetLowering::getPICJumpTableRelocBaseExpr(MF, JTI, Ctx); + + switch (getTargetMachine().getCodeModel()) { + case CodeModel::Default: + case CodeModel::Small: + case CodeModel::Medium: + return TargetLowering::getPICJumpTableRelocBaseExpr(MF, JTI, Ctx); + default: + return MCSymbolRefExpr::create(MF->getPICBaseSymbol(), Ctx); + } +} + SDValue PPCTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const { EVT PtrVT = Op.getValueType(); JumpTableSDNode *JT = cast(Op); Index: llvm/trunk/test/CodeGen/PowerPC/mcm-5.ll =================================================================== --- llvm/trunk/test/CodeGen/PowerPC/mcm-5.ll +++ llvm/trunk/test/CodeGen/PowerPC/mcm-5.ll @@ -1,5 +1,5 @@ ; RUN: llc -verify-machineinstrs -mcpu=pwr7 -code-model=medium <%s | FileCheck %s -; RUN: llc -verify-machineinstrs -mcpu=pwr7 -code-model=large <%s | FileCheck %s +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -code-model=large <%s | FileCheck -check-prefix=LARGE %s ; Test correct code generation for medium and large code model ; for loading the address of a jump table from the TOC. @@ -50,11 +50,30 @@ %5 = load i32, i32* %i.addr, align 4 ret i32 %5 } - ; CHECK-LABEL: test_jump_table: -; CHECK: addis [[REG1:[0-9]+]], 2, .LC[[TOCNUM:[0-9]+]]@toc@ha -; CHECK: ld [[REG2:[0-9]+]], .LC[[TOCNUM]]@toc@l([[REG1]]) -; CHECK: ldx {{[0-9]+}}, {{[0-9]+}}, [[REG2]] -; CHECK: .section .toc -; CHECK: .LC[[TOCNUM]]: -; CHECK: .tc {{[a-z0-9A-Z_.]+}}[TC],{{[a-z0-9A-Z_.]+}} +; CHECK-NOT: bl .L0$pb + +; CHECK: addis [[REG1:[0-9]+]], 2, .LC[[TOCNUM:[0-9]+]]@toc@ha +; CHECK: ld [[REG2:[0-9]+]], .LC[[TOCNUM]]@toc@l([[REG1]]) +; CHECK: lwax [[REG3:[0-9]+]], {{[0-9]+}}, [[REG2]] +; CHECK-NEXT: add [[REG4:[0-9]+]], [[REG3]], [[REG2]] +; CHECK-NEXT: mtctr [[REG4]] +; CHECK-NEXT: bctr + +; CHECK-LABEL: .LJTI0_0: +; CHECK-NEXT: .long .LBB0_{{[0-9]+}}-.LJTI0_0 + +; LARGE-LABEL: test_jump_table: +; LARGE: bl .L0$pb +; LARGE-NEXT: .L0$pb: +; LARGE: mflr [[REGBASE:[0-9]+]] + +; LARGE: addis [[REG1:[0-9]+]], 2, .LC[[TOCNUM:[0-9]+]]@toc@ha +; LARGE: ld [[REG2:[0-9]+]], .LC[[TOCNUM]]@toc@l([[REG1]]) +; LARGE: lwax [[REG3:[0-9]+]], {{[0-9]+}}, [[REG2]] +; LARGE-NEXT: add [[REG4:[0-9]+]], [[REG3]], [[REGBASE]] +; LARGE-NEXT: mtctr [[REG4]] +; LARGE-NEXT: bctr + +; LARGE-LABEL: .LJTI0_0: +; LARGE-NEXT: .long .LBB0_{{[0-9]+}}-.L0$pb