diff options
Diffstat (limited to 'lib/VMCore/iSwitch.cpp')
-rw-r--r-- | lib/VMCore/iSwitch.cpp | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/lib/VMCore/iSwitch.cpp b/lib/VMCore/iSwitch.cpp new file mode 100644 index 0000000000..2a1eec2639 --- /dev/null +++ b/lib/VMCore/iSwitch.cpp @@ -0,0 +1,81 @@ +//===-- iSwitch.cpp - Implement the Switch instruction -----------*- C++ -*--=// +// +// This file implements the Switch instruction... +// +//===----------------------------------------------------------------------===// + +#include "llvm/iTerminators.h" +#include "llvm/BasicBlock.h" +#ifndef NDEBUG +#include "llvm/Type.h" +#endif + +SwitchInst::SwitchInst(Value *V, BasicBlock *DefV) + : TerminatorInst(Instruction::Switch), + DefaultDest(DefV, this), Val(V, this) { + assert(Val && DefV); +} + +SwitchInst::SwitchInst(const SwitchInst &SI) + : TerminatorInst(Instruction::Switch), DefaultDest(SI.DefaultDest), + Val(SI.Val) { + + for (dest_const_iterator I = SI.Destinations.begin(), + end = SI.Destinations.end(); I != end; ++I) + Destinations.push_back(dest_value(ConstPoolUse(I->first, this), + BasicBlockUse(I->second, this))); +} + + +void SwitchInst::dest_push_back(ConstPoolVal *OnVal, BasicBlock *Dest) { + Destinations.push_back(dest_value(ConstPoolUse(OnVal, this), + BasicBlockUse(Dest, this))); +} + +void SwitchInst::dropAllReferences() { + Val = 0; + DefaultDest = 0; + Destinations.clear(); +} + +const BasicBlock *SwitchInst::getSuccessor(unsigned idx) const { + if (idx == 0) return DefaultDest; + if (idx > Destinations.size()) return 0; + return Destinations[idx-1].second; +} + +unsigned SwitchInst::getNumOperands() const { + return 2+Destinations.size(); +} + +const Value *SwitchInst::getOperand(unsigned i) const { + if (i == 0) return Val; + else if (i == 1) return DefaultDest; + + unsigned slot = (i-2) >> 1; + if (slot >= Destinations.size()) return 0; + + if (i & 1) return Destinations[slot].second; + return Destinations[slot].first; +} + +bool SwitchInst::setOperand(unsigned i, Value *V) { + if (i == 0) { Val = V; return true; } + else if (i == 1) { + assert(V->getType() == Type::LabelTy); + DefaultDest = (BasicBlock*)V; + return true; + } + + unsigned slot = (i-2) >> 1; + if (slot >= Destinations.size()) return 0; + + if (i & 1) { + assert(V->getType() == Type::LabelTy); + Destinations[slot].second = (BasicBlock*)V; + } else { + // TODO: assert constant + Destinations[slot].first = (ConstPoolVal*)V; + } + return true; +} |