From 6f602de3b68cc63d12554ad6ae3c98a4c436c32d Mon Sep 17 00:00:00 2001
From: Rafael Espindola <rafael.espindola@gmail.com>
Date: Thu, 24 Aug 2006 16:13:15 +0000
Subject: [PATCH] create a generic bcond instruction that has a conditional
 code argument

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29856 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Target/ARM/ARM.h               | 14 ++++++++++++++
 lib/Target/ARM/ARMAsmPrinter.cpp   |  3 ++-
 lib/Target/ARM/ARMISelDAGToDAG.cpp | 13 ++++++++++---
 lib/Target/ARM/ARMInstrInfo.td     | 12 ++++++++----
 4 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/lib/Target/ARM/ARM.h b/lib/Target/ARM/ARM.h
index 167d71eab67..1f0a240f75e 100644
--- a/lib/Target/ARM/ARM.h
+++ b/lib/Target/ARM/ARM.h
@@ -20,6 +20,20 @@
 #include <cassert>
 
 namespace llvm {
+  // Enums corresponding to ARM condition codes
+  namespace ARMCC {
+    enum CondCodes {
+      NE
+    };
+  }
+
+  static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
+    switch (CC) {
+    default: assert(0 && "Unknown condition code");
+    case ARMCC::NE:  return "ne";
+    }
+  }
+
   class FunctionPass;
   class TargetMachine;
 
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp
index dbd9bd88598..bd123963f75 100644
--- a/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -201,7 +201,8 @@ void ARMAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
 }
 
 void ARMAsmPrinter::printCCOperand(const MachineInstr *MI, int opNum) {
-  assert(0 && "not implemented");
+  int CC = (int)MI->getOperand(opNum).getImmedValue();
+  O << ARMCondCodeToString((ARMCC::CondCodes)CC);
 }
 
 bool ARMAsmPrinter::doInitialization(Module &M) {
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index eea794fcd94..ee8786dc516 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -79,6 +79,14 @@ namespace llvm {
   }
 }
 
+/// DAGCCToARMCC - Convert a DAG integer condition code to an ARM CC
+static ARMCC::CondCodes DAGCCToARMCC(ISD::CondCode CC) {
+  switch (CC) {
+  default: assert(0 && "Unknown condition code!");
+  case ISD::SETNE:  return ARMCC::NE;
+  }
+}
+
 const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
   switch (Opcode) {
   default: return 0;
@@ -322,11 +330,10 @@ static SDOperand LowerBR_CC(SDOperand Op, SelectionDAG &DAG) {
   SDOperand    LHS = Op.getOperand(2);
   SDOperand    RHS = Op.getOperand(3);
   SDOperand   Dest = Op.getOperand(4);
-
-  assert(CC == ISD::SETNE);
+  SDOperand  ARMCC = DAG.getConstant(DAGCCToARMCC(CC), MVT::i32);
 
   SDOperand Cmp = DAG.getNode(ARMISD::CMP, MVT::Flag, LHS, RHS);
-  return DAG.getNode(ARMISD::BR, MVT::Other, Chain, Dest, Cmp);
+  return DAG.getNode(ARMISD::BR, MVT::Other, Chain, Dest, ARMCC, Cmp);
 }
 
 SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index a28ec77031b..2485b100431 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -39,6 +39,10 @@ class InstARM<dag ops, string asmstr, list<dag> pattern> : Instruction {
 
 def brtarget : Operand<OtherVT>;
 
+// Operand for printing out a condition code.
+let PrintMethod = "printCCOperand" in
+  def CCOp : Operand<i32>;
+
 def SDT_ARMCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
 def callseq_start  : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeq,
     		             [SDNPHasChain, SDNPOutFlag]>;
@@ -52,7 +56,7 @@ def retflag        : SDNode<"ARMISD::RET_FLAG", SDTRet,
 	                   [SDNPHasChain, SDNPOptInFlag]>;
 def armselect      : SDNode<"ARMISD::SELECT", SDTIntBinOp, [SDNPInFlag, SDNPOutFlag]>;
 
-def SDTarmbr       : SDTypeProfile<0, 1, [SDTCisVT<0, OtherVT>]>;
+def SDTarmbr       : SDTypeProfile<0, 2, [SDTCisVT<0, OtherVT>, SDTCisVT<1, i32>]>;
 def armbr          : SDNode<"ARMISD::BR", SDTarmbr, [SDNPHasChain, SDNPInFlag]>;
 
 def SDTVoidBinOp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
@@ -112,9 +116,9 @@ let isTwoAddress = 1 in {
 		         [(set IntRegs:$dst, (armselect IntRegs:$true, IntRegs:$false))]>;
 }
 
-def bne    : InstARM<(ops brtarget:$dst),
-		     "bne $dst",
-		     [(armbr bb:$dst)]>;
+def bcond      : InstARM<(ops brtarget:$dst, CCOp:$cc),
+		         "b$cc $dst",
+		         [(armbr bb:$dst, imm:$cc)]>;
 
 def cmp      : InstARM<(ops IntRegs:$a, IntRegs:$b),
 	               "cmp $a, $b",