diff --git a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp index d08727724c0..87b0e5e379d 100644 --- a/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp +++ b/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp @@ -187,6 +187,9 @@ bool SystemZAsmPrinter::runOnMachineFunction(MachineFunction &MF) { if (TAI->hasDotTypeDotSizeDirective()) O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n'; + // Print out jump tables referenced by the function. + EmitJumpTableInfo(MF.getJumpTableInfo(), MF); + O.flush(); // We didn't modify anything @@ -228,6 +231,11 @@ void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, return; case MachineOperand::MO_MachineBasicBlock: printBasicBlockLabel(MO.getMBB()); + return; + case MachineOperand::MO_JumpTableIndex: + O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' + << MO.getIndex(); + return; case MachineOperand::MO_GlobalAddress: { const GlobalValue *GV = MO.getGlobal(); diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index 498aec8925f..e50dc4f7856 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -67,6 +67,7 @@ SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) : setOperationAction(ISD::BR_CC, MVT::i32, Custom); setOperationAction(ISD::BR_CC, MVT::i64, Custom); setOperationAction(ISD::GlobalAddress, MVT::i64, Custom); + setOperationAction(ISD::JumpTable, MVT::i64, Custom); // FIXME: Can we lower these 2 efficiently? setOperationAction(ISD::SETCC, MVT::i32, Expand); @@ -90,6 +91,7 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::BR_CC: return LowerBR_CC(Op, DAG); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); + case ISD::JumpTable: return LowerJumpTable(Op, DAG); default: assert(0 && "unimplemented operand"); return SDValue(); @@ -542,6 +544,15 @@ SDValue SystemZTargetLowering::LowerGlobalAddress(SDValue Op, } +SDValue SystemZTargetLowering::LowerJumpTable(SDValue Op, + SelectionDAG &DAG) { + DebugLoc dl = Op.getDebugLoc(); + JumpTableSDNode *JT = cast(Op); + SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy()); + + return DAG.getNode(SystemZISD::PCRelativeWrapper, dl, getPointerTy(), Result); +} + const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const { switch (Opcode) { case SystemZISD::RET_FLAG: return "SystemZISD::RET_FLAG"; diff --git a/lib/Target/SystemZ/SystemZISelLowering.h b/lib/Target/SystemZ/SystemZISelLowering.h index 22db9c7e3c2..78eb7315bf7 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.h +++ b/lib/Target/SystemZ/SystemZISelLowering.h @@ -70,6 +70,7 @@ namespace llvm { SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG); SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG); + SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG); SDValue LowerCCCArguments(SDValue Op, SelectionDAG &DAG); SDValue LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, unsigned CC); diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index 469fcfe6f01..688cb0ab748 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -96,13 +96,11 @@ let isReturn = 1, isTerminator = 1, isBarrier = 1, hasCtrlDep = 1 in { } let isBranch = 1, isTerminator = 1 in { - let isBarrier = 1 in + let isBarrier = 1 in { def JMP : Pseudo<(outs), (ins brtarget:$dst), "j\t{$dst}", [(br bb:$dst)]>; - let isBarrier = 1, isIndirectBranch = 1 in { - def JMPr : Pseudo<(outs), (ins GR64:$dst), "br\t{$dst}", [(brind GR64:$dst)]>; - // FIXME: displacement here is 12 bits - def JMPrri : Pseudo<(outs), (ins rriaddr:$dst), "b\t{$dst}", [(brind rriaddr:$dst)]>; + let isIndirectBranch = 1 in + def JMPr : Pseudo<(outs), (ins GR64:$dst), "br\t{$dst}", [(brind GR64:$dst)]>; } let Uses = [PSW] in { @@ -699,10 +697,17 @@ def UCMPZX64rm32 : Pseudo<(outs), (ins GR64:$src1, rriaddr:$src2), // Non-Instruction Patterns. //===----------------------------------------------------------------------===// +// JumpTable +def : Pat<(SystemZpcrelwrapper tjumptable:$src), (LA64rm tjumptable:$src)>; + // anyext def : Pat<(i64 (anyext GR32:$src)), (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GR32:$src, subreg_32bit)>; +// calls +def : Pat<(SystemZcall (i64 tglobaladdr:$dst)), (CALLi tglobaladdr:$dst)>; +def : Pat<(SystemZcall (i64 texternalsym:$dst)), (CALLi texternalsym:$dst)>; + //===----------------------------------------------------------------------===// // Peepholes. //===----------------------------------------------------------------------===// @@ -728,12 +733,6 @@ def : Pat<(extloadi64i8 rriaddr:$src), (MOVZX64rm8 rriaddr:$src)>; def : Pat<(extloadi64i16 rriaddr:$src), (MOVZX64rm16 rriaddr:$src)>; def : Pat<(extloadi64i32 rriaddr:$src), (MOVZX64rm32 rriaddr:$src)>; -// calls -def : Pat<(SystemZcall (i64 tglobaladdr:$dst)), - (CALLi tglobaladdr:$dst)>; -def : Pat<(SystemZcall (i64 texternalsym:$dst)), - (CALLi texternalsym:$dst)>; - // muls def : Pat<(mulhs GR32:$src1, GR32:$src2), (EXTRACT_SUBREG (MUL64rrP (INSERT_SUBREG (i64 (IMPLICIT_DEF)), diff --git a/test/CodeGen/SystemZ/09-Switches.ll b/test/CodeGen/SystemZ/09-Switches.ll new file mode 100644 index 00000000000..ff12d880798 --- /dev/null +++ b/test/CodeGen/SystemZ/09-Switches.ll @@ -0,0 +1,39 @@ +; RUN: llvm-as < %s | llc -march=systemz | grep larl + +define i32 @main(i32 %tmp158) { +entry: + switch i32 %tmp158, label %bb336 [ + i32 -2147483648, label %bb338 + i32 -2147483647, label %bb338 + i32 -2147483646, label %bb338 + i32 120, label %bb338 + i32 121, label %bb339 + i32 122, label %bb340 + i32 123, label %bb341 + i32 124, label %bb342 + i32 125, label %bb343 + i32 126, label %bb336 + i32 1024, label %bb338 + i32 0, label %bb338 + i32 1, label %bb338 + i32 2, label %bb338 + i32 3, label %bb338 + i32 4, label %bb338 + i32 5, label %bb338 + ] +bb336: + ret i32 10 +bb338: + ret i32 11 +bb339: + ret i32 12 +bb340: + ret i32 13 +bb341: + ret i32 14 +bb342: + ret i32 15 +bb343: + ret i32 18 + +}