956d7d5bdba38f23ceb219447d735483027abe94
[oota-llvm.git] / lib / VMCore / iOperators.cpp
1 //===-- iOperators.cpp - Implement binary Operators ------------*- C++ -*--===//
2 //
3 // This file implements the nontrivial binary operator instructions.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "llvm/iOperators.h"
8 #include "llvm/Type.h"
9 #include "llvm/Constants.h"
10 #include "llvm/BasicBlock.h"
11
12 //===----------------------------------------------------------------------===//
13 //                             BinaryOperator Class
14 //===----------------------------------------------------------------------===//
15
16 BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, 
17                                const Type *Ty, const std::string &Name,
18                                Instruction *InsertBefore)
19   : Instruction(Ty, iType, Name, InsertBefore) {
20   Operands.reserve(2);
21   Operands.push_back(Use(S1, this));
22   Operands.push_back(Use(S2, this));
23   assert(Operands[0] && Operands[1] && 
24          Operands[0]->getType() == Operands[1]->getType());
25 }
26
27
28
29
30 BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2,
31                                        const std::string &Name,
32                                        Instruction *InsertBefore) {
33   assert(S1->getType() == S2->getType() &&
34          "Cannot create binary operator with two operands of differing type!");
35   switch (Op) {
36   // Binary comparison operators...
37   case SetLT: case SetGT: case SetLE:
38   case SetGE: case SetEQ: case SetNE:
39     return new SetCondInst(Op, S1, S2, Name, InsertBefore);
40
41   default:
42     return new BinaryOperator(Op, S1, S2, S1->getType(), Name, InsertBefore);
43   }
44 }
45
46 BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name,
47                                           Instruction *InsertBefore) {
48   return new BinaryOperator(Instruction::Sub,
49                             Constant::getNullValue(Op->getType()), Op,
50                             Op->getType(), Name, InsertBefore);
51 }
52
53 BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name,
54                                           Instruction *InsertBefore) {
55   return new BinaryOperator(Instruction::Xor, Op,
56                             ConstantIntegral::getAllOnesValue(Op->getType()),
57                             Op->getType(), Name, InsertBefore);
58 }
59
60
61 // isConstantAllOnes - Helper function for several functions below
62 static inline bool isConstantAllOnes(const Value *V) {
63   return isa<ConstantIntegral>(V) &&cast<ConstantIntegral>(V)->isAllOnesValue();
64 }
65
66 bool BinaryOperator::isNeg(const Value *V) {
67   if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(V))
68     return Bop->getOpcode() == Instruction::Sub &&
69       isa<Constant>(Bop->getOperand(0)) && cast<Constant>(V)->isNullValue();
70   return false;
71 }
72
73 bool BinaryOperator::isNot(const Value *V) {
74   if (const BinaryOperator *Bop = dyn_cast<BinaryOperator>(V))
75     return (Bop->getOpcode() == Instruction::Xor &&
76             (isConstantAllOnes(Bop->getOperand(1)) ||
77              isConstantAllOnes(Bop->getOperand(0))));
78   return false;
79 }
80
81 Value *BinaryOperator::getNegArgument(BinaryOperator *Bop) {
82   assert(isNeg(Bop) && "getNegArgument from non-'neg' instruction!");
83   return Bop->getOperand(1);
84 }
85
86 const Value *BinaryOperator::getNegArgument(const BinaryOperator *Bop) {
87   return getNegArgument((BinaryOperator*)Bop);
88 }
89
90 Value *BinaryOperator::getNotArgument(BinaryOperator *Bop) {
91   assert(isNot(Bop) && "getNotArgument on non-'not' instruction!");
92   Value *Op0 = Bop->getOperand(0);
93   Value *Op1 = Bop->getOperand(1);
94   if (isConstantAllOnes(Op0)) return Op1;
95
96   assert(isConstantAllOnes(Op1));
97   return Op0;
98 }
99
100 const Value *BinaryOperator::getNotArgument(const BinaryOperator *Bop) {
101   return getNotArgument((BinaryOperator*)Bop);
102 }
103
104
105 // swapOperands - Exchange the two operands to this instruction.  This
106 // instruction is safe to use on any binary instruction and does not
107 // modify the semantics of the instruction.  If the instruction is
108 // order dependant (SetLT f.e.) the opcode is changed.
109 //
110 bool BinaryOperator::swapOperands() {
111   if (SetCondInst *SCI = dyn_cast<SetCondInst>(this)) {
112     iType = SCI->getSwappedCondition();
113     std::swap(Operands[0], Operands[1]);
114     return false;
115   }
116
117   switch (getOpcode()) {
118     // Instructions that don't need opcode modification
119   case Add: case Mul:
120   case And: case Xor:
121   case Or:
122     // Error on the side of caution
123   default:
124     return true;
125   }
126   std::swap(Operands[0], Operands[1]);
127   return false;
128 }
129
130
131 //===----------------------------------------------------------------------===//
132 //                             SetCondInst Class
133 //===----------------------------------------------------------------------===//
134
135 SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2, 
136                          const std::string &Name, Instruction *InsertBefore)
137   : BinaryOperator(Opcode, S1, S2, Type::BoolTy, Name, InsertBefore) {
138
139   // Make sure it's a valid type... getInverseCondition will assert out if not.
140   assert(getInverseCondition(Opcode));
141 }
142
143 // getInverseCondition - Return the inverse of the current condition opcode.
144 // For example seteq -> setne, setgt -> setle, setlt -> setge, etc...
145 //
146 Instruction::BinaryOps SetCondInst::getInverseCondition(BinaryOps Opcode) {
147   switch (Opcode) {
148   default:
149     assert(0 && "Unknown setcc opcode!");
150   case SetEQ: return SetNE;
151   case SetNE: return SetEQ;
152   case SetGT: return SetLE;
153   case SetLT: return SetGE;
154   case SetGE: return SetLT;
155   case SetLE: return SetGT;
156   }
157 }
158
159 // getSwappedCondition - Return the condition opcode that would be the result
160 // of exchanging the two operands of the setcc instruction without changing
161 // the result produced.  Thus, seteq->seteq, setle->setge, setlt->setgt, etc.
162 //
163 Instruction::BinaryOps SetCondInst::getSwappedCondition(BinaryOps Opcode) {
164   switch (Opcode) {
165   default: assert(0 && "Unknown setcc instruction!");
166   case SetEQ: case SetNE: return Opcode;
167   case SetGT: return SetLT;
168   case SetLT: return SetGT;
169   case SetGE: return SetLE;
170   case SetLE: return SetGE;
171   }
172 }