1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[mips] Custom-legalize BR_JT.

In N64-static, GOT address is needed to compute the branch address.

llvm-svn: 176580
This commit is contained in:
Akira Hatanaka 2013-03-06 21:32:03 +00:00
parent 55af24b5b9
commit 46c323ab23
3 changed files with 53 additions and 16 deletions

View File

@ -331,6 +331,7 @@ MipsTargetLowering(MipsTargetMachine &TM)
AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32);
// Mips Custom Operations
setOperationAction(ISD::BR_JT, MVT::Other, Custom);
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
setOperationAction(ISD::BlockAddress, MVT::i32, Custom);
setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
@ -396,7 +397,6 @@ MipsTargetLowering(MipsTargetMachine &TM)
setOperationAction(ISD::UREM, MVT::i64, Expand);
// Operations not directly supported by Mips.
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
setOperationAction(ISD::BR_CC, MVT::Other, Expand);
setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
@ -1039,6 +1039,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const
{
switch (Op.getOpcode())
{
case ISD::BR_JT: return LowerBR_JT(Op, DAG);
case ISD::BRCOND: return LowerBRCOND(Op, DAG);
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
@ -2166,6 +2167,36 @@ MipsTargetLowering::EmitAtomicCmpSwapPartword(MachineInstr *MI,
//===----------------------------------------------------------------------===//
// Misc Lower Operation implementation
//===----------------------------------------------------------------------===//
SDValue MipsTargetLowering::LowerBR_JT(SDValue Op, SelectionDAG &DAG) const {
SDValue Chain = Op.getOperand(0);
SDValue Table = Op.getOperand(1);
SDValue Index = Op.getOperand(2);
DebugLoc DL = Op.getDebugLoc();
EVT PTy = getPointerTy();
unsigned EntrySize =
DAG.getMachineFunction().getJumpTableInfo()->getEntrySize(*getDataLayout());
Index = DAG.getNode(ISD::MUL, DL, PTy, Index,
DAG.getConstant(EntrySize, PTy));
SDValue Addr = DAG.getNode(ISD::ADD, DL, PTy, Index, Table);
EVT MemVT = EVT::getIntegerVT(*DAG.getContext(), EntrySize * 8);
Addr = DAG.getExtLoad(ISD::SEXTLOAD, DL, PTy, Chain, Addr,
MachinePointerInfo::getJumpTable(), MemVT, false, false,
0);
Chain = Addr.getValue(1);
if ((getTargetMachine().getRelocationModel() == Reloc::PIC_) || IsN64) {
// For PIC, the sequence is:
// BRIND(load(Jumptable + index) + RelocBase)
// RelocBase can be JumpTable, GOT or some sort of global base.
Addr = DAG.getNode(ISD::ADD, DL, PTy, Addr,
getPICJumpTableRelocBase(Table, DAG));
}
return DAG.getNode(ISD::BRIND, DL, MVT::Other, Chain, Addr);
}
SDValue MipsTargetLowering::
LowerBRCOND(SDValue Op, SelectionDAG &DAG) const
{

View File

@ -292,6 +292,7 @@ namespace llvm {
const SDNode *CallNode, const Type *RetTy) const;
// Lower Operand specifics
SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;

View File

@ -1,6 +1,11 @@
; RUN: llc < %s -march=mips -relocation-model=static | FileCheck %s -check-prefix=STATIC-O32
; RUN: llc < %s -march=mips -relocation-model=pic | FileCheck %s -check-prefix=PIC-O32
; RUN: llc < %s -march=mips64 -relocation-model=pic -mcpu=mips64 -mattr=n64 | FileCheck %s -check-prefix=PIC-N64
; RUN: llc < %s -march=mips -relocation-model=static | \
; RUN: FileCheck %s -check-prefix=STATIC-O32
; RUN: llc < %s -march=mips -relocation-model=pic | \
; RUN: FileCheck %s -check-prefix=PIC-O32
; RUN: llc < %s -march=mips64 -relocation-model=pic -mcpu=mips64 | \
; RUN: FileCheck %s -check-prefix=N64
; RUN: llc < %s -march=mips64 -relocation-model=static -mcpu=mips64 | \
; RUN: FileCheck %s -check-prefix=N64
define i32 @main() nounwind readnone {
entry:
@ -17,12 +22,12 @@ entry:
; PIC-O32: lw $[[R4:[0-9]+]], %lo($JTI0_0)($[[R2]])
; PIC-O32: addu $[[R5:[0-9]+]], $[[R4:[0-9]+]]
; PIC-O32: jr $[[R5]]
; PIC-N64: dsll $[[R0:[0-9]+]], ${{[0-9]+}}, 3
; PIC-N64: ld $[[R1:[0-9]+]], %got_page($JTI0_0)
; PIC-N64: daddu $[[R2:[0-9]+]], $[[R0:[0-9]+]], $[[R1]]
; PIC-N64: ld $[[R4:[0-9]+]], %got_ofst($JTI0_0)($[[R2]])
; PIC-N64: daddu $[[R5:[0-9]+]], $[[R4:[0-9]+]]
; PIC-N64: jr $[[R5]]
; N64: dsll $[[R0:[0-9]+]], ${{[0-9]+}}, 3
; N64: ld $[[R1:[0-9]+]], %got_page($JTI0_0)
; N64: daddu $[[R2:[0-9]+]], $[[R0:[0-9]+]], $[[R1]]
; N64: ld $[[R4:[0-9]+]], %got_ofst($JTI0_0)($[[R2]])
; N64: daddu $[[R5:[0-9]+]], $[[R4:[0-9]+]]
; N64: jr $[[R5]]
switch i32 %0, label %bb4 [
i32 0, label %bb5
i32 1, label %bb1
@ -58,10 +63,10 @@ bb5: ; preds = %entry
; PIC-O32: .gpword
; PIC-O32: .gpword
; PIC-O32: .gpword
; PIC-N64: .align 3
; PIC-N64: $JTI0_0:
; PIC-N64: .gpdword
; PIC-N64: .gpdword
; PIC-N64: .gpdword
; PIC-N64: .gpdword
; N64: .align 3
; N64: $JTI0_0:
; N64: .gpdword
; N64: .gpdword
; N64: .gpdword
; N64: .gpdword