Index: lib/Target/NDS32/NDS32ISelLowering.h =================================================================== --- lib/Target/NDS32/NDS32ISelLowering.h +++ lib/Target/NDS32/NDS32ISelLowering.h @@ -79,6 +79,8 @@ SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; + /// getTargetNodeName - This method returns the name of a target specific /// DAG node. const char *getTargetNodeName(unsigned Opcode) const override; @@ -142,6 +144,10 @@ SDValue getTargetNode(BlockAddressSDNode *N, EVT Ty, SelectionDAG &DAG, unsigned Flag) const; + // Create a TargetJumpTable node. + SDValue getTargetNode(JumpTableSDNode *N, EVT Ty, SelectionDAG &DAG, + unsigned Flag) const; + typedef SmallVector, 8> RegsToPassVector; /// copyByValArg - Copy argument registers which were used to pass a byval Index: lib/Target/NDS32/NDS32ISelLowering.cpp =================================================================== --- lib/Target/NDS32/NDS32ISelLowering.cpp +++ lib/Target/NDS32/NDS32ISelLowering.cpp @@ -153,6 +153,7 @@ case ISD::VASTART: return LowerVASTART(Op, DAG); case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); + case ISD::JumpTable: return LowerJumpTable(Op, DAG); default: llvm_unreachable("unimplemented operand"); } @@ -213,6 +214,12 @@ return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, 0, Flag); } +SDValue NDS32TargetLowering::getTargetNode(JumpTableSDNode *N, EVT Ty, + SelectionDAG &DAG, + unsigned Flag) const { + return DAG.getTargetJumpTable(N->getIndex(), Ty, Flag); +} + SDValue NDS32TargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const { MachineFunction &MF = DAG.getMachineFunction(); @@ -289,6 +296,15 @@ return DAG.getCopyFromReg(DAG.getEntryNode(), dl, Reg, PtrVT); } +SDValue NDS32TargetLowering:: +LowerJumpTable(SDValue Op, SelectionDAG &DAG) const +{ + JumpTableSDNode *N = cast(Op); + EVT Ty = Op.getValueType(); + + return getAddrNonPIC(N, SDLoc(N), Ty, DAG); +} + //===----------------------------------------------------------------------===// // NDS32 Addressing Mode Support Index: lib/Target/NDS32/NDS32InstrInfo.td =================================================================== --- lib/Target/NDS32/NDS32InstrInfo.td +++ lib/Target/NDS32/NDS32InstrInfo.td @@ -573,6 +573,7 @@ def : Pat<(NDS32hi20 tglobaladdr:$in), (SETHI tglobaladdr:$in)>; def : Pat<(NDS32hi20 tblockaddress:$in), (SETHI tblockaddress:$in)>; def : Pat<(NDS32hi20 texternalsym:$in), (SETHI texternalsym:$in)>; +def : Pat<(NDS32hi20 tjumptable:$in), (SETHI tjumptable:$in)>; def : Pat<(or GPR:$hi, (NDS32lo12 tglobaladdr:$lo)), (ORI GPR:$hi, tglobaladdr:$lo)>; @@ -580,6 +581,8 @@ (ORI GPR:$hi, tblockaddress:$lo)>; def : Pat<(or GPR:$hi, (NDS32lo12 texternalsym:$lo)), (ORI GPR:$hi, texternalsym:$lo)>; +def : Pat<(or GPR:$hi, (NDS32lo12 tjumptable:$lo)), + (ORI GPR:$hi, tjumptable:$lo)>; // Arbitrary immediates def : Pat<(i32 imm:$imm), Index: test/CodeGen/NDS32/jumptable.ll =================================================================== --- /dev/null +++ test/CodeGen/NDS32/jumptable.ll @@ -0,0 +1,43 @@ +; RUN: llc < %s | FileCheck %s +target datalayout = "e-m:e-p:32:32-i64:64-a:0:32-n32-S64" +target triple = "nds32le---elf" + +; Function Attrs: norecurse nounwind readnone +define i32 @jumptable(i32 %a, i32 %b) local_unnamed_addr #0 { +entry: +; CHECK-LABEL: jumptable: +; CHECK: lw $r0, [$r2 + $r0 << 2] +; CHECK: jr5 $r0 + switch i32 %a, label %sw.epilog [ + i32 1, label %sw.bb + i32 2, label %return + i32 3, label %sw.bb2 + i32 4, label %sw.bb4 + ] + +sw.bb: ; preds = %entry + %mul = mul nsw i32 %b, %b + br label %return + +sw.bb2: ; preds = %entry + %mul3 = mul nsw i32 %b, 3 + br label %return + +sw.bb4: ; preds = %entry + %mul5 = mul nsw i32 %b, %b + %mul6 = mul nsw i32 %mul5, %b + br label %return + +sw.epilog: ; preds = %entry + br label %return + +return: ; preds = %entry, %sw.epilog, %sw.bb4, %sw.bb2, %sw.bb + %retval.0 = phi i32 [ 0, %sw.epilog ], [ %mul6, %sw.bb4 ], [ %mul3, %sw.bb2 ], [ %mul, %sw.bb ], [ %b, %entry ] + ret i32 %retval.0 +} + +; CHECK: .LJTI0_0: +; CHECK-NEXT: .long .LBB0_2 +; CHECK-NEXT: .long .LBB0_6 +; CHECK-NEXT: .long .LBB0_3 +; CHECK-NEXT: .long .LBB0_4