Added more helper functions for binary instructions emulating
[oota-llvm.git] / lib / VMCore / iOperators.cpp
index bc37df5cb7f1bb03fde0d477c41ff4d3384ed2cc..c9053298336dd09af6eb70263ca4bd42f3c3727f 100644 (file)
@@ -1,27 +1,12 @@
-//===-- iOperators.cpp - Implement the Binary & Unary Operators --*- C++ -*--=//
+//===-- iOperators.cpp - Implement binary Operators ------------*- C++ -*--===//
 //
-// This file implements the nontrivial binary & unary operator instructions.
+// This file implements the nontrivial binary operator instructions.
 //
 //===----------------------------------------------------------------------===//
 
 #include "llvm/iOperators.h"
 #include "llvm/Type.h"
-using std::cerr;
-
-//===----------------------------------------------------------------------===//
-//                              UnaryOperator Class
-//===----------------------------------------------------------------------===//
-
-UnaryOperator *UnaryOperator::create(UnaryOps Op, Value *Source,
-                                     const std::string &Name) {
-  switch (Op) {
-  case Not:  return new GenericUnaryInst(Op, Source, Name);
-  default:
-    cerr << "Don't know how to Create UnaryOperator " << Op << "\n";
-    return 0;
-  }
-}
-
+#include "llvm/Constants.h"
 
 //===----------------------------------------------------------------------===//
 //                             BinaryOperator Class
@@ -40,6 +25,83 @@ BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2,
   }
 }
 
+BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name) {
+  return new GenericBinaryInst(Instruction::Sub,
+                               Constant::getNullValue(Op->getType()), Op, Name);
+}
+
+BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name) {
+  return new GenericBinaryInst(Instruction::Xor, Op,
+                               ConstantIntegral::getAllOnesValue(Op->getType()),
+                               Name);
+}
+
+
+// isConstantZero - Helper function for several functions below
+inline bool isConstantZero(const Value* V) {
+  return isa<Constant>(V) && dyn_cast<Constant>(V)->isNullValue();
+}
+
+// isConstantAllOnes - Helper function for several functions below
+inline bool isConstantAllOnes(const Value* V) {
+  return (isa<ConstantIntegral>(V) &&
+          dyn_cast<ConstantIntegral>(V)->isAllOnesValue());
+}
+
+bool BinaryOperator::isNeg(const Value *V) {
+  if (const BinaryOperator* Bop = dyn_cast<BinaryOperator>(V))
+    return (Bop->getOpcode() == Instruction::Sub &&
+            isConstantZero(Bop->getOperand(0)));
+  return false;
+}
+
+bool BinaryOperator::isNot(const Value *V) {
+  if (const BinaryOperator* Bop = dyn_cast<BinaryOperator>(V))
+    return (Bop->getOpcode() == Instruction::Xor &&
+            (isConstantAllOnes(Bop->getOperand(1)) ||
+             isConstantAllOnes(Bop->getOperand(0))));
+  return false;
+}
+
+// getNegArg -- Helper function for getNegArgument operations.
+// Note: This function requires that Bop is a Neg operation.
+// 
+inline Value* getNegArg(BinaryOperator* Bop) {
+  assert(BinaryOperator::isNeg(Bop));
+  return Bop->getOperand(1);
+}
+
+// getNotArg -- Helper function for getNotArgument operations.
+// Note: This function requires that Bop is a Not operation.
+// 
+inline Value* getNotArg(BinaryOperator* Bop) {
+  assert(Bop->getOpcode() == Instruction::Xor);
+  Value* notArg   = Bop->getOperand(0);
+  Value* constArg = Bop->getOperand(1);
+  if (! isConstantAllOnes(constArg)) {
+    assert(isConstantAllOnes(notArg));
+    notArg = constArg;
+  }
+  return notArg;
+}
+
+const Value* BinaryOperator::getNegArgument(const BinaryOperator* Bop) {
+  return getNegArg((BinaryOperator*) Bop);
+}
+
+Value* BinaryOperator::getNegArgument(BinaryOperator* Bop) {
+  return getNegArg(Bop);
+}
+
+const Value* BinaryOperator::getNotArgument(const BinaryOperator* Bop) {
+  return getNotArg((BinaryOperator*) Bop);
+}
+
+Value* BinaryOperator::getNotArgument(BinaryOperator* Bop) {
+  return getNotArg(Bop);
+}
+
+
 // swapOperands - Exchange the two operands to this instruction.  This
 // instruction is safe to use on any binary instruction and does not
 // modify the semantics of the instruction.  If the instruction is