diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2009-07-16 13:52:31 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2009-07-16 13:52:31 +0000 |
commit | 4ec3e5ffd10b23c3614cd9a766c2a3ec1fe62ba4 (patch) | |
tree | 6e44f751d4627f9f08b9afa8dc12de0d2a650d6b /lib/Target/SystemZ/SystemZISelLowering.cpp | |
parent | c7b71bede49dc1eae107c79a74b5c618c39506ac (diff) | |
download | llvm-4ec3e5ffd10b23c3614cd9a766c2a3ec1fe62ba4.tar.gz llvm-4ec3e5ffd10b23c3614cd9a766c2a3ec1fe62ba4.tar.bz2 llvm-4ec3e5ffd10b23c3614cd9a766c2a3ec1fe62ba4.tar.xz |
Conditional branches and comparisons
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75947 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/SystemZ/SystemZISelLowering.cpp')
-rw-r--r-- | lib/Target/SystemZ/SystemZISelLowering.cpp | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index 9cff6ea2f0..448f52160d 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -57,6 +57,10 @@ SystemZTargetLowering::SystemZTargetLowering(SystemZTargetMachine &tm) : setSchedulingPreference(SchedulingForLatency); setOperationAction(ISD::RET, MVT::Other, Custom); + + setOperationAction(ISD::BRCOND, MVT::Other, Expand); + setOperationAction(ISD::BR_CC, MVT::i32, Custom); + setOperationAction(ISD::BR_CC, MVT::i64, Custom); } SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { @@ -64,6 +68,7 @@ SDValue SystemZTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); case ISD::RET: return LowerRET(Op, DAG); case ISD::CALL: return LowerCALL(Op, DAG); + case ISD::BR_CC: return LowerBR_CC(Op, DAG); default: assert(0 && "unimplemented operand"); return SDValue(); @@ -406,10 +411,75 @@ SDValue SystemZTargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { return DAG.getNode(SystemZISD::RET_FLAG, dl, MVT::Other, Chain); } +SDValue SystemZTargetLowering::EmitCmp(SDValue LHS, SDValue RHS, + ISD::CondCode CC, SDValue &SystemZCC, + SelectionDAG &DAG) { + assert(!LHS.getValueType().isFloatingPoint() && "We don't handle FP yet"); + + // FIXME: Emit a test if RHS is zero + + bool isUnsigned = false; + SystemZCC::CondCodes TCC; + switch (CC) { + default: assert(0 && "Invalid integer condition!"); + case ISD::SETEQ: + TCC = SystemZCC::E; + break; + case ISD::SETNE: + TCC = SystemZCC::NE; + break; + case ISD::SETULE: + isUnsigned = true; // FALLTHROUGH + case ISD::SETLE: + TCC = SystemZCC::LE; + break; + case ISD::SETUGE: + isUnsigned = true; // FALLTHROUGH + case ISD::SETGE: + TCC = SystemZCC::HE; + break; + case ISD::SETUGT: + isUnsigned = true; + case ISD::SETGT: + TCC = SystemZCC::H; // FALLTHROUGH + break; + case ISD::SETULT: + isUnsigned = true; + case ISD::SETLT: // FALLTHROUGH + TCC = SystemZCC::L; + break; + } + + SystemZCC = DAG.getConstant(TCC, MVT::i32); + + DebugLoc dl = LHS.getDebugLoc(); + return DAG.getNode((isUnsigned ? SystemZISD::UCMP : SystemZISD::CMP), + dl, MVT::Flag, LHS, RHS); +} + + +SDValue SystemZTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) { + SDValue Chain = Op.getOperand(0); + ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); + SDValue LHS = Op.getOperand(2); + SDValue RHS = Op.getOperand(3); + SDValue Dest = Op.getOperand(4); + DebugLoc dl = Op.getDebugLoc(); + + SDValue SystemZCC; + SDValue Flag = EmitCmp(LHS, RHS, CC, SystemZCC, DAG); + return DAG.getNode(SystemZISD::BRCOND, dl, Op.getValueType(), + Chain, Dest, SystemZCC, Flag); +} + + const char *SystemZTargetLowering::getTargetNodeName(unsigned Opcode) const { switch (Opcode) { case SystemZISD::RET_FLAG: return "SystemZISD::RET_FLAG"; case SystemZISD::CALL: return "SystemZISD::CALL"; + case SystemZISD::BRCOND: return "SystemZISD::BRCOND"; + case SystemZISD::CMP: return "SystemZISD::CMP"; + case SystemZISD::UCMP: return "SystemZISD::UCMP"; default: return NULL; } } |