From 0f693a8a771c69996261219c7a8bd3b48aa6ab9f Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 6 Mar 2013 21:32:03 +0000 Subject: [PATCH] [mips] Custom-legalize BR_JT. In N64-static, GOT address is needed to compute the branch address. llvm-svn: 176580 --- llvm/lib/Target/Mips/MipsISelLowering.cpp | 33 ++++++++++++++++++++++++++- llvm/lib/Target/Mips/MipsISelLowering.h | 1 + llvm/test/CodeGen/Mips/2010-07-20-Switch.ll | 35 ++++++++++++++++------------- 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index dd569f6..a811005 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -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 { diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h index 4424521..02d7e2f 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.h +++ b/llvm/lib/Target/Mips/MipsISelLowering.h @@ -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; diff --git a/llvm/test/CodeGen/Mips/2010-07-20-Switch.ll b/llvm/test/CodeGen/Mips/2010-07-20-Switch.ll index 261fe9d..38d7b7e 100644 --- a/llvm/test/CodeGen/Mips/2010-07-20-Switch.ll +++ b/llvm/test/CodeGen/Mips/2010-07-20-Switch.ll @@ -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 -- 2.7.4