[optimizing] Add basic PackedSwitch support

Add HPackedSwitch, and generate it from the builder.  Code generators
convert this to a series of compare/branch tests.  Better implementation
in the code generators as a real jump table will follow as separate CLs.

Change-Id: If14736fa4d62809b6ae95280148c55682e856911
Signed-off-by: Mark Mendell <mark.p.mendell@intel.com>
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 8dd31be..52f6e23 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -1056,6 +1056,7 @@
   M(NullConstant, Instruction)                                          \
   M(NullCheck, Instruction)                                             \
   M(Or, BinaryOperation)                                                \
+  M(PackedSwitch, Instruction)                                          \
   M(ParallelMove, Instruction)                                          \
   M(ParameterValue, Instruction)                                        \
   M(Phi, Instruction)                                                   \
@@ -2402,6 +2403,38 @@
   DISALLOW_COPY_AND_ASSIGN(HCurrentMethod);
 };
 
+// PackedSwitch (jump table). A block ending with a PackedSwitch instruction will
+// have one successor for each entry in the switch table, and the final successor
+// will be the block containing the next Dex opcode.
+class HPackedSwitch : public HTemplateInstruction<1> {
+ public:
+  HPackedSwitch(int32_t start_value, int32_t num_entries, HInstruction* input,
+                uint32_t dex_pc = kNoDexPc)
+    : HTemplateInstruction(SideEffects::None(), dex_pc),
+      start_value_(start_value),
+      num_entries_(num_entries) {
+    SetRawInputAt(0, input);
+  }
+
+  bool IsControlFlow() const OVERRIDE { return true; }
+
+  int32_t GetStartValue() const { return start_value_; }
+
+  int32_t GetNumEntries() const { return num_entries_; }
+
+  HBasicBlock* GetDefaultBlock() const {
+    // Last entry is the default block.
+    return GetBlock()->GetSuccessor(num_entries_);
+  }
+  DECLARE_INSTRUCTION(PackedSwitch);
+
+ private:
+  int32_t start_value_;
+  int32_t num_entries_;
+
+  DISALLOW_COPY_AND_ASSIGN(HPackedSwitch);
+};
+
 class HUnaryOperation : public HExpression<1> {
  public:
   HUnaryOperation(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc)