CodeReader visitor dispatch now uses OpcodeInfo.

This gets rid of the per-opcode Instruction array and just does a
simple switch. If it turns out that the switch has poor performance,
we can push the visitor abstraction down into IndexType.

The big change to OpcodeInfo is to make every Info instance always
have a non-null IndexType, exactly so it could be reliably switch()ed
on without having to do an explicit null check.

Change-Id: Iee8289f8766ce41c5043eec7212b2133ec71e682
diff --git a/dx/src/com/android/dx/io/CodeReader.java b/dx/src/com/android/dx/io/CodeReader.java
index 45f8ca2..ca8fe6f 100644
--- a/dx/src/com/android/dx/io/CodeReader.java
+++ b/dx/src/com/android/dx/io/CodeReader.java
@@ -17,350 +17,62 @@
 package com.android.dx.io;
 
 import com.android.dx.dex.DexException;
-import com.android.dx.util.Hex;
 
 /**
  * Walks through a block of code and calls visitor call backs.
  */
 public final class CodeReader {
-
-    private final Instruction[] instructions = new Instruction[] {
-            // 0x00...0x0f
-            new Instruction("nop"),
-            new Instruction("move vA, vB"),
-            new Instruction("move/from vAA, vBBBB"),
-            new Instruction("move/16 vAAAA, vBBBB"),
-            new Instruction("move-wide, vA, vB"),
-            new Instruction("move-wide/from16 vAA, vBBBB"),
-            new Instruction("move-wide/from16 vAAAA, vBBBB"),
-            new Instruction("move-object vA, vB"),
-            new Instruction("move-object/from16 vAA, vBBBB"),
-            new Instruction("move-object/16 vAAAA, vBBBB"),
-            new Instruction("move-result vAA"),
-            new Instruction("move-result-wide vAA"),
-            new Instruction("move-result-object vAA"),
-            new Instruction("move-exception vAA"),
-            new Instruction("return void"),
-            new Instruction("return vAA"),
-
-            // 0x10...0x1f
-            new Instruction("return-wide vAA"),
-            new Instruction("return-object vAA"),
-            new Instruction("const/4 vA, #+B"),
-            new Instruction("const/16 vAA, #+BBBB"),
-            new Instruction("const vAA, #+BBBBBBBB"),
-            new Instruction("const/high16 vAA, #+BBBB0000"),
-            new Instruction("const-wide/16 vAA, #+BBBB"),
-            new Instruction("const-wide/32 vAA, #+BBBBBBBB"),
-            new Instruction("const-wide vAA, #+BBBBBBBBBBBBBBBB"),
-            new Instruction("const-wide/high16 vAA, #+BBBB000000000000"),
-            new Instruction("const-string vAA, string@BBBB"),
-            new Instruction("const-string/jumbo vAA, string@BBBBBBBB"),
-            new Instruction("const-class vAA, type@BBBB"),
-            new Instruction("monitor-enter vAA"),
-            new Instruction("monitor-exit vAA"),
-            new Instruction("check-cast vAA type@BBBB"),
-
-            // 0x20...0x2f
-            new Instruction("instance-of vA, vB, type@CCCC"),
-            new Instruction("array-length vA, vB"),
-            new Instruction("new-instance vAA, type@BBBB"),
-            new Instruction("new-array vA, vB, type@CCCC"),
-            new Instruction("filled-new-array {vD, vE, vF, vG, vA}, type@CCCC"),
-            new Instruction("filled-new-array/range {vCCCC..vNNNN}, type@BBBB"),
-            new Instruction("fill-array-data vAA, +BBBBBBBB"),
-            new Instruction("throw vAA"),
-            new Instruction("goto +AA"),
-            new Instruction("goto/16 +AAAA"),
-            new Instruction("goto/32 +AAAAAAAA"),
-            new Instruction("packed-switch vAA, +BBBBBBBB"),
-            new Instruction("sparse-switch vAA, +BBBBBBBB"),
-            new Instruction("cmpl-float vAA, vBB, vCC"),
-            new Instruction("cmpg-float vAA, vBB, vCC"),
-            new Instruction("cmpl-double vAA, vBB, vCC"),
-
-            // 0x30...0x3f
-            new Instruction("cmpg-double vAA, vBB, vCC"),
-            new Instruction("cmp-long vAA, vBB, vCC"),
-            new Instruction("if-eq vA, vB, +CCCC"),
-            new Instruction("if-ne vA, vB, +CCCC"),
-            new Instruction("if-lt vA, vB, +CCCC"),
-            new Instruction("if-ge vA, vB, +CCCC"),
-            new Instruction("if-gt vA, vB, +CCCC"),
-            new Instruction("if-le vA, vB, +CCCC"),
-            new Instruction("if-eqz vAA, +BBBB"),
-            new Instruction("if-nez vAA, +BBBB"),
-            new Instruction("if-ltz vAA, +BBBB"),
-            new Instruction("if-gez vAA, +BBBB"),
-            new Instruction("if-gtz vAA, +BBBB"),
-            new Instruction("if-lez vAA, +BBBB"),
-            new UnusedInstruction(),
-            new UnusedInstruction(),
-
-            // 0x40...0x4f
-            new UnusedInstruction(),
-            new UnusedInstruction(),
-            new UnusedInstruction(),
-            new UnusedInstruction(),
-            new Instruction("aget vAA, vBB, vCC"),
-            new Instruction("aget-wide vAA, vBB, vCC"),
-            new Instruction("aget-object vAA, vBB, vCC"),
-            new Instruction("aget-boolean vAA, vBB, vCC"),
-            new Instruction("aget-byte vAA, vBB, vCC"),
-            new Instruction("aget-char vAA, vBB, vCC"),
-            new Instruction("aget-short vAA, vBB, vCC"),
-            new Instruction("aput vAA, vBB, vCC"),
-            new Instruction("aput-wide vAA, vBB, vCC"),
-            new Instruction("aput-object vAA, vBB, vCC"),
-            new Instruction("aput-boolean vAA, vBB, vCC"),
-            new Instruction("aput-byte vAA, vBB, vCC"),
-
-            // 0x50...0x5f
-            new Instruction("aput-char vAA, vBB, vCC"),
-            new Instruction("aput-short vAA, vBB, vCC"),
-            new Instruction("iget vA, vB, field@CCCC"),
-            new Instruction("iget-wide vA, vB, field@CCCC"),
-            new Instruction("iget-object vA, vB, field@CCCC"),
-            new Instruction("iget-boolean vA, vB, field@CCCC"),
-            new Instruction("iget-byte vA, vB, field@CCCC"),
-            new Instruction("iget-char vA, vB, field@CCCC"),
-            new Instruction("iget-short vA, vB, field@CCCC"),
-            new Instruction("iput vA, vB, field@CCCC"),
-            new Instruction("iput-wide vA, vB, field@CCCC"),
-            new Instruction("iput-object vA, vB, field@CCCC"),
-            new Instruction("iput-boolean vA, vB, field@CCCC"),
-            new Instruction("iput-byte vA, vB, field@CCCC"),
-            new Instruction("iput-char vA, vB, field@CCCC"),
-            new Instruction("iput-short vA, vB, field@CCCC"),
-
-            // 0x60...0x6f
-            new Instruction("sget vAA, field@BBBB"),
-            new Instruction("sget-wide vAA, field@BBBB"),
-            new Instruction("sget-object vAA, field@BBBB"),
-            new Instruction("sget-boolean vAA, field@BBBB"),
-            new Instruction("sget-byte vAA, field@BBBB"),
-            new Instruction("sget-char vAA, field@BBBB"),
-            new Instruction("sget-short vAA, field@BBBB"),
-            new Instruction("sput vAA, field@BBBB"),
-            new Instruction("sput-wide vAA, field@BBBB"),
-            new Instruction("sput-object vAA, field@BBBB"),
-            new Instruction("sput-boolean vAA, field@BBBB"),
-            new Instruction("sput-byte vAA, field@BBBB"),
-            new Instruction("sput-char vAA, field@BBBB"),
-            new Instruction("sput-short vAA, field@BBBB"),
-            new Instruction("invoke-virtual {vD, vE, vF, vG, vA}, meth@CCCC"),
-            new Instruction("invoke-super {vD, vE, vF, vG, vA}, meth@CCCC"),
-
-            // 0x70...0x7f
-            new Instruction("invoke-direct {vD, vE, vF, vG, vA}, meth@CCCC"),
-            new Instruction("invoke-static {vD, vE, vF, vG, vA}, meth@CCCC"),
-            new Instruction("invoke-interface {vD, vE, vF, vG, vA}, meth@CCCC"),
-            new UnusedInstruction(),
-            new Instruction("invoke-virtual/range {vCCCC..vNNNN}, meth@BBBB"),
-            new Instruction("invoke-super/range {vCCCC..vNNNN}, meth@BBBB"),
-            new Instruction("invoke-direct/range {vCCCC..vNNNN}, meth@BBBB"),
-            new Instruction("invoke-static/range {vCCCC..vNNNN}, meth@BBBB"),
-            new Instruction("invoke-interface/range {vCCCC..vNNNN}, meth@BBBB"),
-            new UnusedInstruction(),
-            new UnusedInstruction(),
-            new Instruction("neg-int vA, vB"),
-            new Instruction("not-int vA, vB"),
-            new Instruction("neg-long vA, vB"),
-            new Instruction("not-long vA, vB"),
-            new Instruction("neg-float vA, vB"),
-
-            // 0x80...0x8f
-            new Instruction("neg-double vA, vB"),
-            new Instruction("int-to-long vA, vB"),
-            new Instruction("int-to-float vA, vB"),
-            new Instruction("int-to-double vA, vB"),
-            new Instruction("long-to-int vA, vB"),
-            new Instruction("long-to-float vA, vB"),
-            new Instruction("long-to-double vA, vB"),
-            new Instruction("float-to-int vA, vB"),
-            new Instruction("float-to-long vA, vB"),
-            new Instruction("float-to-double vA, vB"),
-            new Instruction("double-to-int vA, vB"),
-            new Instruction("double-to-long vA, vB"),
-            new Instruction("double-to-float vA, vB"),
-            new Instruction("int-to-byte vA, vB"),
-            new Instruction("int-to-char vA, vB"),
-            new Instruction("int-to-short vA, vB"),
-
-            // 0x90...0x9f
-            new Instruction("add-int vAA, vBB, vCC"),
-            new Instruction("sub-int vAA, vBB, vCC"),
-            new Instruction("mul-int vAA, vBB, vCC"),
-            new Instruction("div-int vAA, vBB, vCC"),
-            new Instruction("rem-int vAA, vBB, vCC"),
-            new Instruction("and-int vAA, vBB, vCC"),
-            new Instruction("or-int vAA, vBB, vCC"),
-            new Instruction("xor-int vAA, vBB, vCC"),
-            new Instruction("shl-int vAA, vBB, vCC"),
-            new Instruction("shr-int vAA, vBB, vCC"),
-            new Instruction("ushr-int vAA, vBB, vCC"),
-            new Instruction("add-long vAA, vBB, vCC"),
-            new Instruction("sub-long vAA, vBB, vCC"),
-            new Instruction("mul-long vAA, vBB, vCC"),
-            new Instruction("div-long vAA, vBB, vCC"),
-            new Instruction("rem-long vAA, vBB, vCC"),
-
-            // 0xa0...0xaf
-            new Instruction("and-long vAA, vBB, vCC"),
-            new Instruction("or-long vAA, vBB, vCC"),
-            new Instruction("xor-long vAA, vBB, vCC"),
-            new Instruction("shl-long vAA, vBB, vCC"),
-            new Instruction("shr-long vAA, vBB, vCC"),
-            new Instruction("ushr-long vAA, vBB, vCC"),
-            new Instruction("add-float vAA, vBB, vCC"),
-            new Instruction("sub-float vAA, vBB, vCC"),
-            new Instruction("mul-float vAA, vBB, vCC"),
-            new Instruction("div-float vAA, vBB, vCC"),
-            new Instruction("rem-float vAA, vBB, vCC"),
-            new Instruction("add-double vAA, vBB, vCC"),
-            new Instruction("sub-double vAA, vBB, vCC"),
-            new Instruction("mul-double vAA, vBB, vCC"),
-            new Instruction("div-double vAA, vBB, vCC"),
-            new Instruction("rem-double vAA, vBB, vCC"),
-
-            // 0xb0..0xbf
-            new Instruction("add-int/2addr vA, vB"),
-            new Instruction("sub-int/2addr vA, vB"),
-            new Instruction("mul-int/2addr vA, vB"),
-            new Instruction("div-int/2addr vA, vB"),
-            new Instruction("rem-int/2addr vA, vB"),
-            new Instruction("and-int/2addr vA, vB"),
-            new Instruction("or-int/2addr vA, vB"),
-            new Instruction("xor-int/2addr vA, vB"),
-            new Instruction("shl-int/2addr vA, vB"),
-            new Instruction("shr-int/2addr vA, vB"),
-            new Instruction("ushr-int/2addr vA, vB"),
-            new Instruction("add-long/2addr vA, vB"),
-            new Instruction("sub-long/2addr vA, vB"),
-            new Instruction("mul-long/2addr vA, vB"),
-            new Instruction("div-long/2addr vA, vB"),
-            new Instruction("rem-long/2addr vA, vB"),
-
-            // 0xc0...0xcf
-            new Instruction("and-long/2addr vA, vB"),
-            new Instruction("or-long/2addr vA, vB"),
-            new Instruction("xor-long/2addr vA, vB"),
-            new Instruction("shl-long/2addr vA, vB"),
-            new Instruction("shr-long/2addr vA, vB"),
-            new Instruction("ushr-long/2addr vA, vB"),
-            new Instruction("add-float/2addr vA, vB"),
-            new Instruction("sub-float/2addr vA, vB"),
-            new Instruction("mul-float/2addr vA, vB"),
-            new Instruction("div-float/2addr vA, vB"),
-            new Instruction("rem-float/2addr vA, vB"),
-            new Instruction("add-double/2addr vA, vB"),
-            new Instruction("sub-double/2addr vA, vB"),
-            new Instruction("mul-double/2addr vA, vB"),
-            new Instruction("div-double/2addr vA, vB"),
-            new Instruction("rem-double/2addr vA, vB"),
-
-            // 0xd0...0xdf
-            new Instruction("add-int/lit16 vA, vB, #+CCCC"),
-            new Instruction("rsub-int (reverse subtract) vA, vB, #+CCCC"),
-            new Instruction("mul-int/lit16 vA, vB, #+CCCC"),
-            new Instruction("div-int/lit16 vA, vB, #+CCCC"),
-            new Instruction("rem-int/lit16 vA, vB, #+CCCC"),
-            new Instruction("and-int/lit16 vA, vB, #+CCCC"),
-            new Instruction("or-int/lit16 vA, vB, #+CCCC"),
-            new Instruction("xor-int/lit16 vA, vB, #+CCCC"),
-            new Instruction("add-int/lit8 vAA, vBB, #+CC"),
-            new Instruction("rsub-int/lit8 vAA, vBB, #+CC"),
-            new Instruction("mul-int/lit8 vAA, vBB, #+CC"),
-            new Instruction("div-int/lit8 vAA, vBB, #+CC"),
-            new Instruction("rem-int/lit8 vAA, vBB, #+CC"),
-            new Instruction("and-int/lit8 vAA, vBB, #+CC"),
-            new Instruction("or-int/lit8 vAA, vBB, #+CC"),
-            new Instruction("xor-int/lit8 vAA, vBB, #+CC"),
-
-            // 0xe0...0xef
-            new Instruction("shl-int/lit8 vAA, vBB, #+CC"),
-            new Instruction("shr-int/lit8 vAA, vBB, #+CC"),
-            new Instruction("ushr-int/lit8 vAA, vBB, #+CC"),
-    };
+    private Visitor fallbackVisitor = null;
+    private Visitor stringVisitor = null;
+    private Visitor typeVisitor = null;
+    private Visitor fieldVisitor = null;
+    private Visitor methodVisitor = null;
 
     /**
      * Sets {@code visitor} as the visitor for all instructions.
      */
     public void setAllVisitors(Visitor visitor) {
-        for (Instruction instruction : instructions) {
-            instruction.setVisitor(null, visitor);
-        }
+        fallbackVisitor = visitor;
+        stringVisitor = visitor;
+        typeVisitor = visitor;
+        fieldVisitor = visitor;
+        methodVisitor = visitor;
+    }
+
+    /**
+     * Sets {@code visitor} as the visitor for all instructions not
+     * otherwise handled.
+     */
+    public void setFallbackVisitor(Visitor visitor) {
+        fallbackVisitor = visitor;
     }
 
     /**
      * Sets {@code visitor} as the visitor for all string instructions.
      */
     public void setStringVisitor(Visitor visitor) {
-        instructions[0x1a].setVisitor("const-string vAA, string@BBBB", visitor);
-        instructions[0x1b].setVisitor("const-string/jumbo vAA, string@BBBBBBBB", visitor);
+        stringVisitor = visitor;
     }
 
     /**
      * Sets {@code visitor} as the visitor for all type instructions.
      */
     public void setTypeVisitor(Visitor visitor) {
-        instructions[0x1c].setVisitor("const-class vAA, type@BBBB", visitor);
-        instructions[0x1f].setVisitor("check-cast vAA type@BBBB", visitor);
-        instructions[0x20].setVisitor("instance-of vA, vB, type@CCCC", visitor);
-        instructions[0x22].setVisitor("new-instance vAA, type@BBBB", visitor);
-        instructions[0x23].setVisitor("new-array vA, vB, type@CCCC", visitor);
-        instructions[0x24].setVisitor("filled-new-array {vD, vE, vF, vG, vA}, type@CCCC", visitor);
-        instructions[0x25].setVisitor("filled-new-array/range {vCCCC..vNNNN}, type@BBBB", visitor);
+        typeVisitor = visitor;
     }
 
     /**
      * Sets {@code visitor} as the visitor for all field instructions.
      */
     public void setFieldVisitor(Visitor visitor) {
-        instructions[0x52].setVisitor("iget vA, vB, field@CCCC", visitor);
-        instructions[0x53].setVisitor("iget-wide vA, vB, field@CCCC", visitor);
-        instructions[0x54].setVisitor("iget-object vA, vB, field@CCCC", visitor);
-        instructions[0x55].setVisitor("iget-boolean vA, vB, field@CCCC", visitor);
-        instructions[0x56].setVisitor("iget-byte vA, vB, field@CCCC", visitor);
-        instructions[0x57].setVisitor("iget-char vA, vB, field@CCCC", visitor);
-        instructions[0x58].setVisitor("iget-short vA, vB, field@CCCC", visitor);
-        instructions[0x59].setVisitor("iput vA, vB, field@CCCC", visitor);
-        instructions[0x5a].setVisitor("iput-wide vA, vB, field@CCCC", visitor);
-        instructions[0x5b].setVisitor("iput-object vA, vB, field@CCCC", visitor);
-        instructions[0x5c].setVisitor("iput-boolean vA, vB, field@CCCC", visitor);
-        instructions[0x5d].setVisitor("iput-byte vA, vB, field@CCCC", visitor);
-        instructions[0x5e].setVisitor("iput-char vA, vB, field@CCCC", visitor);
-        instructions[0x5f].setVisitor("iput-short vA, vB, field@CCCC", visitor);
-        instructions[0x60].setVisitor("sget vAA, field@BBBB", visitor);
-        instructions[0x61].setVisitor("sget-wide vAA, field@BBBB", visitor);
-        instructions[0x62].setVisitor("sget-object vAA, field@BBBB", visitor);
-        instructions[0x63].setVisitor("sget-boolean vAA, field@BBBB", visitor);
-        instructions[0x64].setVisitor("sget-byte vAA, field@BBBB", visitor);
-        instructions[0x65].setVisitor("sget-char vAA, field@BBBB", visitor);
-        instructions[0x66].setVisitor("sget-short vAA, field@BBBB", visitor);
-        instructions[0x67].setVisitor("sput vAA, field@BBBB", visitor);
-        instructions[0x68].setVisitor("sput-wide vAA, field@BBBB", visitor);
-        instructions[0x69].setVisitor("sput-object vAA, field@BBBB", visitor);
-        instructions[0x6a].setVisitor("sput-boolean vAA, field@BBBB", visitor);
-        instructions[0x6b].setVisitor("sput-byte vAA, field@BBBB", visitor);
-        instructions[0x6c].setVisitor("sput-char vAA, field@BBBB", visitor);
-        instructions[0x6d].setVisitor("sput-short vAA, field@BBBB", visitor);
+        fieldVisitor = visitor;
     }
 
     /**
      * Sets {@code visitor} as the visitor for all method instructions.
      */
     public void setMethodVisitor(Visitor visitor) {
-        instructions[0x6e].setVisitor("invoke-virtual {vD, vE, vF, vG, vA}, meth@CCCC", visitor);
-        instructions[0x6f].setVisitor("invoke-super {vD, vE, vF, vG, vA}, meth@CCCC", visitor);
-        instructions[0x70].setVisitor("invoke-direct {vD, vE, vF, vG, vA}, meth@CCCC", visitor);
-        instructions[0x71].setVisitor("invoke-static {vD, vE, vF, vG, vA}, meth@CCCC", visitor);
-        instructions[0x72].setVisitor("invoke-interface {vD, vE, vF, vG, vA}, meth@CCCC", visitor);
-        instructions[0x74].setVisitor("invoke-virtual/range {vCCCC..vNNNN}, meth@BBBB", visitor);
-        instructions[0x75].setVisitor("invoke-super/range {vCCCC..vNNNN}, meth@BBBB", visitor);
-        instructions[0x76].setVisitor("invoke-direct/range {vCCCC..vNNNN}, meth@BBBB", visitor);
-        instructions[0x77].setVisitor("invoke-static/range {vCCCC..vNNNN}, meth@BBBB", visitor);
-        instructions[0x78].setVisitor("invoke-interface/range {vCCCC..vNNNN}, meth@BBBB", visitor);
+        methodVisitor = visitor;
     }
 
     public void visitAll(DecodedInstruction[] decodedInstructions)
@@ -368,16 +80,12 @@
         int size = decodedInstructions.length;
 
         for (int i = 0; i < size; i++) {
-            DecodedInstruction di = decodedInstructions[i];
-            if (di == null) {
+            DecodedInstruction one = decodedInstructions[i];
+            if (one == null) {
                 continue;
             }
 
-            Instruction instruction = instructions[di.getOpcode()];
-            Visitor visitor = instruction.visitor;
-            if (visitor != null) {
-                visitor.visit(decodedInstructions, di);
-            }
+            callVisit(decodedInstructions, one);
         }
     }
 
@@ -387,41 +95,26 @@
         visitAll(decodedInstructions);
     }
 
-    public static class Instruction {
-        private final String name;
-        private Visitor visitor;
+    private void callVisit(DecodedInstruction[] all, DecodedInstruction one) {
+        Visitor visitor = null;
 
-        private Instruction(String name) {
-            this.name = name;
+        switch (OpcodeInfo.getIndexType(one.getOpcode())) {
+            case STRING_REF: visitor = stringVisitor; break;
+            case TYPE_REF:   visitor = typeVisitor;   break;
+            case FIELD_REF:  visitor = fieldVisitor;  break;
+            case METHOD_REF: visitor = methodVisitor; break;
         }
 
-        public String getName() {
-            return name;
+        if (visitor == null) {
+            visitor = fallbackVisitor;
         }
 
-        /**
-         * Sets the visitor to be notified when this instruction is encountered,
-         * or null if this instruction has no visitor.
-         */
-        public void setVisitor(String name, Visitor visitor) {
-            if ((name != null) && !this.name.equals(name)) {
-                throw new IllegalArgumentException("Expected " + this.name + " but was " + name);
-            }
-            this.visitor = visitor;
-        }
-
-        @Override public String toString() {
-            return name;
+        if (visitor != null) {
+            visitor.visit(all, one);
         }
     }
 
     public interface Visitor {
         void visit(DecodedInstruction[] all, DecodedInstruction one);
     }
-
-    private static class UnusedInstruction extends Instruction {
-        UnusedInstruction() {
-            super("unused");
-        }
-    }
 }
diff --git a/dx/src/com/android/dx/io/IndexType.java b/dx/src/com/android/dx/io/IndexType.java
index 2d5c370..bbddfa8 100644
--- a/dx/src/com/android/dx/io/IndexType.java
+++ b/dx/src/com/android/dx/io/IndexType.java
@@ -20,6 +20,12 @@
  * The various types that an index in a Dalvik instruction might refer to.
  */
 public enum IndexType {
+    /** "Unknown." Used for undefined opcodes. */
+    UNKNOWN,
+
+    /** no index used */
+    NONE,
+
     /** "It depends." Used for {@code throw-verification-error}. */
     VARIES,
 
diff --git a/dx/src/com/android/dx/io/OpcodeInfo.java b/dx/src/com/android/dx/io/OpcodeInfo.java
index d645207..e75791f 100644
--- a/dx/src/com/android/dx/io/OpcodeInfo.java
+++ b/dx/src/com/android/dx/io/OpcodeInfo.java
@@ -38,126 +38,129 @@
      */
     public static final Info SPECIAL_FORMAT =
         new Info(Opcodes.SPECIAL_FORMAT, "<special>",
-                InstructionCodec.FORMAT_00X, null);
+                InstructionCodec.FORMAT_00X, IndexType.NONE);
 
     // TODO: These payload opcodes should be generated by opcode-gen.
 
     public static final Info PACKED_SWITCH_PAYLOAD =
         new Info(Opcodes.PACKED_SWITCH_PAYLOAD, "packed-switch-payload",
-                InstructionCodec.FORMAT_PACKED_SWITCH_PAYLOAD, null);
+                InstructionCodec.FORMAT_PACKED_SWITCH_PAYLOAD,
+                IndexType.NONE);
 
     public static final Info SPARSE_SWITCH_PAYLOAD =
         new Info(Opcodes.SPARSE_SWITCH_PAYLOAD, "sparse-switch-payload",
-                InstructionCodec.FORMAT_SPARSE_SWITCH_PAYLOAD, null);
+                InstructionCodec.FORMAT_SPARSE_SWITCH_PAYLOAD,
+                IndexType.NONE);
 
     public static final Info FILL_ARRAY_DATA_PAYLOAD =
         new Info(Opcodes.FILL_ARRAY_DATA_PAYLOAD, "fill-array-data-payload",
-                InstructionCodec.FORMAT_FILL_ARRAY_DATA_PAYLOAD, null);
+                InstructionCodec.FORMAT_FILL_ARRAY_DATA_PAYLOAD,
+                IndexType.NONE);
 
     // BEGIN(opcode-info-defs); GENERATED AUTOMATICALLY BY opcode-gen
     public static final Info NOP =
         new Info(Opcodes.NOP, "nop",
-            InstructionCodec.FORMAT_10X, null);
+            InstructionCodec.FORMAT_10X, IndexType.NONE);
 
     public static final Info MOVE =
         new Info(Opcodes.MOVE, "move",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info MOVE_FROM16 =
         new Info(Opcodes.MOVE_FROM16, "move/from16",
-            InstructionCodec.FORMAT_22X, null);
+            InstructionCodec.FORMAT_22X, IndexType.NONE);
 
     public static final Info MOVE_16 =
         new Info(Opcodes.MOVE_16, "move/16",
-            InstructionCodec.FORMAT_32X, null);
+            InstructionCodec.FORMAT_32X, IndexType.NONE);
 
     public static final Info MOVE_WIDE =
         new Info(Opcodes.MOVE_WIDE, "move-wide",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info MOVE_WIDE_FROM16 =
         new Info(Opcodes.MOVE_WIDE_FROM16, "move-wide/from16",
-            InstructionCodec.FORMAT_22X, null);
+            InstructionCodec.FORMAT_22X, IndexType.NONE);
 
     public static final Info MOVE_WIDE_16 =
         new Info(Opcodes.MOVE_WIDE_16, "move-wide/16",
-            InstructionCodec.FORMAT_32X, null);
+            InstructionCodec.FORMAT_32X, IndexType.NONE);
 
     public static final Info MOVE_OBJECT =
         new Info(Opcodes.MOVE_OBJECT, "move-object",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info MOVE_OBJECT_FROM16 =
         new Info(Opcodes.MOVE_OBJECT_FROM16, "move-object/from16",
-            InstructionCodec.FORMAT_22X, null);
+            InstructionCodec.FORMAT_22X, IndexType.NONE);
 
     public static final Info MOVE_OBJECT_16 =
         new Info(Opcodes.MOVE_OBJECT_16, "move-object/16",
-            InstructionCodec.FORMAT_32X, null);
+            InstructionCodec.FORMAT_32X, IndexType.NONE);
 
     public static final Info MOVE_RESULT =
         new Info(Opcodes.MOVE_RESULT, "move-result",
-            InstructionCodec.FORMAT_11X, null);
+            InstructionCodec.FORMAT_11X, IndexType.NONE);
 
     public static final Info MOVE_RESULT_WIDE =
         new Info(Opcodes.MOVE_RESULT_WIDE, "move-result-wide",
-            InstructionCodec.FORMAT_11X, null);
+            InstructionCodec.FORMAT_11X, IndexType.NONE);
 
     public static final Info MOVE_RESULT_OBJECT =
         new Info(Opcodes.MOVE_RESULT_OBJECT, "move-result-object",
-            InstructionCodec.FORMAT_11X, null);
+            InstructionCodec.FORMAT_11X, IndexType.NONE);
 
     public static final Info MOVE_EXCEPTION =
         new Info(Opcodes.MOVE_EXCEPTION, "move-exception",
-            InstructionCodec.FORMAT_11X, null);
+            InstructionCodec.FORMAT_11X, IndexType.NONE);
 
     public static final Info RETURN_VOID =
         new Info(Opcodes.RETURN_VOID, "return-void",
-            InstructionCodec.FORMAT_10X, null);
+            InstructionCodec.FORMAT_10X, IndexType.NONE);
 
     public static final Info RETURN =
         new Info(Opcodes.RETURN, "return",
-            InstructionCodec.FORMAT_11X, null);
+            InstructionCodec.FORMAT_11X, IndexType.NONE);
 
     public static final Info RETURN_WIDE =
         new Info(Opcodes.RETURN_WIDE, "return-wide",
-            InstructionCodec.FORMAT_11X, null);
+            InstructionCodec.FORMAT_11X, IndexType.NONE);
 
     public static final Info RETURN_OBJECT =
         new Info(Opcodes.RETURN_OBJECT, "return-object",
-            InstructionCodec.FORMAT_11X, null);
+            InstructionCodec.FORMAT_11X, IndexType.NONE);
 
     public static final Info CONST_4 =
         new Info(Opcodes.CONST_4, "const/4",
-            InstructionCodec.FORMAT_11N, null);
+            InstructionCodec.FORMAT_11N, IndexType.NONE);
 
     public static final Info CONST_16 =
         new Info(Opcodes.CONST_16, "const/16",
-            InstructionCodec.FORMAT_21S, null);
+            InstructionCodec.FORMAT_21S, IndexType.NONE);
 
     public static final Info CONST =
         new Info(Opcodes.CONST, "const",
-            InstructionCodec.FORMAT_31I, null);
+            InstructionCodec.FORMAT_31I, IndexType.NONE);
 
     public static final Info CONST_HIGH16 =
         new Info(Opcodes.CONST_HIGH16, "const/high16",
-            InstructionCodec.FORMAT_21H, null);
+            InstructionCodec.FORMAT_21H, IndexType.NONE);
 
     public static final Info CONST_WIDE_16 =
         new Info(Opcodes.CONST_WIDE_16, "const-wide/16",
-            InstructionCodec.FORMAT_21S, null);
+            InstructionCodec.FORMAT_21S, IndexType.NONE);
 
     public static final Info CONST_WIDE_32 =
         new Info(Opcodes.CONST_WIDE_32, "const-wide/32",
-            InstructionCodec.FORMAT_31I, null);
+            InstructionCodec.FORMAT_31I, IndexType.NONE);
 
     public static final Info CONST_WIDE =
         new Info(Opcodes.CONST_WIDE, "const-wide",
-            InstructionCodec.FORMAT_51L, null);
+            InstructionCodec.FORMAT_51L, IndexType.NONE);
 
     public static final Info CONST_WIDE_HIGH16 =
         new Info(Opcodes.CONST_WIDE_HIGH16, "const-wide/high16",
-            InstructionCodec.FORMAT_21H, null);
+            InstructionCodec.FORMAT_21H, IndexType.NONE);
 
     public static final Info CONST_STRING =
         new Info(Opcodes.CONST_STRING, "const-string",
@@ -173,11 +176,11 @@
 
     public static final Info MONITOR_ENTER =
         new Info(Opcodes.MONITOR_ENTER, "monitor-enter",
-            InstructionCodec.FORMAT_11X, null);
+            InstructionCodec.FORMAT_11X, IndexType.NONE);
 
     public static final Info MONITOR_EXIT =
         new Info(Opcodes.MONITOR_EXIT, "monitor-exit",
-            InstructionCodec.FORMAT_11X, null);
+            InstructionCodec.FORMAT_11X, IndexType.NONE);
 
     public static final Info CHECK_CAST =
         new Info(Opcodes.CHECK_CAST, "check-cast",
@@ -189,7 +192,7 @@
 
     public static final Info ARRAY_LENGTH =
         new Info(Opcodes.ARRAY_LENGTH, "array-length",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info NEW_INSTANCE =
         new Info(Opcodes.NEW_INSTANCE, "new-instance",
@@ -209,155 +212,155 @@
 
     public static final Info FILL_ARRAY_DATA =
         new Info(Opcodes.FILL_ARRAY_DATA, "fill-array-data",
-            InstructionCodec.FORMAT_31T, null);
+            InstructionCodec.FORMAT_31T, IndexType.NONE);
 
     public static final Info THROW =
         new Info(Opcodes.THROW, "throw",
-            InstructionCodec.FORMAT_11X, null);
+            InstructionCodec.FORMAT_11X, IndexType.NONE);
 
     public static final Info GOTO =
         new Info(Opcodes.GOTO, "goto",
-            InstructionCodec.FORMAT_10T, null);
+            InstructionCodec.FORMAT_10T, IndexType.NONE);
 
     public static final Info GOTO_16 =
         new Info(Opcodes.GOTO_16, "goto/16",
-            InstructionCodec.FORMAT_20T, null);
+            InstructionCodec.FORMAT_20T, IndexType.NONE);
 
     public static final Info GOTO_32 =
         new Info(Opcodes.GOTO_32, "goto/32",
-            InstructionCodec.FORMAT_30T, null);
+            InstructionCodec.FORMAT_30T, IndexType.NONE);
 
     public static final Info PACKED_SWITCH =
         new Info(Opcodes.PACKED_SWITCH, "packed-switch",
-            InstructionCodec.FORMAT_31T, null);
+            InstructionCodec.FORMAT_31T, IndexType.NONE);
 
     public static final Info SPARSE_SWITCH =
         new Info(Opcodes.SPARSE_SWITCH, "sparse-switch",
-            InstructionCodec.FORMAT_31T, null);
+            InstructionCodec.FORMAT_31T, IndexType.NONE);
 
     public static final Info CMPL_FLOAT =
         new Info(Opcodes.CMPL_FLOAT, "cmpl-float",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info CMPG_FLOAT =
         new Info(Opcodes.CMPG_FLOAT, "cmpg-float",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info CMPL_DOUBLE =
         new Info(Opcodes.CMPL_DOUBLE, "cmpl-double",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info CMPG_DOUBLE =
         new Info(Opcodes.CMPG_DOUBLE, "cmpg-double",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info CMP_LONG =
         new Info(Opcodes.CMP_LONG, "cmp-long",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info IF_EQ =
         new Info(Opcodes.IF_EQ, "if-eq",
-            InstructionCodec.FORMAT_22T, null);
+            InstructionCodec.FORMAT_22T, IndexType.NONE);
 
     public static final Info IF_NE =
         new Info(Opcodes.IF_NE, "if-ne",
-            InstructionCodec.FORMAT_22T, null);
+            InstructionCodec.FORMAT_22T, IndexType.NONE);
 
     public static final Info IF_LT =
         new Info(Opcodes.IF_LT, "if-lt",
-            InstructionCodec.FORMAT_22T, null);
+            InstructionCodec.FORMAT_22T, IndexType.NONE);
 
     public static final Info IF_GE =
         new Info(Opcodes.IF_GE, "if-ge",
-            InstructionCodec.FORMAT_22T, null);
+            InstructionCodec.FORMAT_22T, IndexType.NONE);
 
     public static final Info IF_GT =
         new Info(Opcodes.IF_GT, "if-gt",
-            InstructionCodec.FORMAT_22T, null);
+            InstructionCodec.FORMAT_22T, IndexType.NONE);
 
     public static final Info IF_LE =
         new Info(Opcodes.IF_LE, "if-le",
-            InstructionCodec.FORMAT_22T, null);
+            InstructionCodec.FORMAT_22T, IndexType.NONE);
 
     public static final Info IF_EQZ =
         new Info(Opcodes.IF_EQZ, "if-eqz",
-            InstructionCodec.FORMAT_21T, null);
+            InstructionCodec.FORMAT_21T, IndexType.NONE);
 
     public static final Info IF_NEZ =
         new Info(Opcodes.IF_NEZ, "if-nez",
-            InstructionCodec.FORMAT_21T, null);
+            InstructionCodec.FORMAT_21T, IndexType.NONE);
 
     public static final Info IF_LTZ =
         new Info(Opcodes.IF_LTZ, "if-ltz",
-            InstructionCodec.FORMAT_21T, null);
+            InstructionCodec.FORMAT_21T, IndexType.NONE);
 
     public static final Info IF_GEZ =
         new Info(Opcodes.IF_GEZ, "if-gez",
-            InstructionCodec.FORMAT_21T, null);
+            InstructionCodec.FORMAT_21T, IndexType.NONE);
 
     public static final Info IF_GTZ =
         new Info(Opcodes.IF_GTZ, "if-gtz",
-            InstructionCodec.FORMAT_21T, null);
+            InstructionCodec.FORMAT_21T, IndexType.NONE);
 
     public static final Info IF_LEZ =
         new Info(Opcodes.IF_LEZ, "if-lez",
-            InstructionCodec.FORMAT_21T, null);
+            InstructionCodec.FORMAT_21T, IndexType.NONE);
 
     public static final Info AGET =
         new Info(Opcodes.AGET, "aget",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info AGET_WIDE =
         new Info(Opcodes.AGET_WIDE, "aget-wide",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info AGET_OBJECT =
         new Info(Opcodes.AGET_OBJECT, "aget-object",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info AGET_BOOLEAN =
         new Info(Opcodes.AGET_BOOLEAN, "aget-boolean",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info AGET_BYTE =
         new Info(Opcodes.AGET_BYTE, "aget-byte",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info AGET_CHAR =
         new Info(Opcodes.AGET_CHAR, "aget-char",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info AGET_SHORT =
         new Info(Opcodes.AGET_SHORT, "aget-short",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info APUT =
         new Info(Opcodes.APUT, "aput",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info APUT_WIDE =
         new Info(Opcodes.APUT_WIDE, "aput-wide",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info APUT_OBJECT =
         new Info(Opcodes.APUT_OBJECT, "aput-object",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info APUT_BOOLEAN =
         new Info(Opcodes.APUT_BOOLEAN, "aput-boolean",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info APUT_BYTE =
         new Info(Opcodes.APUT_BYTE, "aput-byte",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info APUT_CHAR =
         new Info(Opcodes.APUT_CHAR, "aput-char",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info APUT_SHORT =
         new Info(Opcodes.APUT_SHORT, "aput-short",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info IGET =
         new Info(Opcodes.IGET, "iget",
@@ -513,419 +516,419 @@
 
     public static final Info NEG_INT =
         new Info(Opcodes.NEG_INT, "neg-int",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info NOT_INT =
         new Info(Opcodes.NOT_INT, "not-int",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info NEG_LONG =
         new Info(Opcodes.NEG_LONG, "neg-long",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info NOT_LONG =
         new Info(Opcodes.NOT_LONG, "not-long",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info NEG_FLOAT =
         new Info(Opcodes.NEG_FLOAT, "neg-float",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info NEG_DOUBLE =
         new Info(Opcodes.NEG_DOUBLE, "neg-double",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info INT_TO_LONG =
         new Info(Opcodes.INT_TO_LONG, "int-to-long",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info INT_TO_FLOAT =
         new Info(Opcodes.INT_TO_FLOAT, "int-to-float",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info INT_TO_DOUBLE =
         new Info(Opcodes.INT_TO_DOUBLE, "int-to-double",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info LONG_TO_INT =
         new Info(Opcodes.LONG_TO_INT, "long-to-int",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info LONG_TO_FLOAT =
         new Info(Opcodes.LONG_TO_FLOAT, "long-to-float",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info LONG_TO_DOUBLE =
         new Info(Opcodes.LONG_TO_DOUBLE, "long-to-double",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info FLOAT_TO_INT =
         new Info(Opcodes.FLOAT_TO_INT, "float-to-int",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info FLOAT_TO_LONG =
         new Info(Opcodes.FLOAT_TO_LONG, "float-to-long",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info FLOAT_TO_DOUBLE =
         new Info(Opcodes.FLOAT_TO_DOUBLE, "float-to-double",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info DOUBLE_TO_INT =
         new Info(Opcodes.DOUBLE_TO_INT, "double-to-int",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info DOUBLE_TO_LONG =
         new Info(Opcodes.DOUBLE_TO_LONG, "double-to-long",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info DOUBLE_TO_FLOAT =
         new Info(Opcodes.DOUBLE_TO_FLOAT, "double-to-float",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info INT_TO_BYTE =
         new Info(Opcodes.INT_TO_BYTE, "int-to-byte",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info INT_TO_CHAR =
         new Info(Opcodes.INT_TO_CHAR, "int-to-char",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info INT_TO_SHORT =
         new Info(Opcodes.INT_TO_SHORT, "int-to-short",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info ADD_INT =
         new Info(Opcodes.ADD_INT, "add-int",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info SUB_INT =
         new Info(Opcodes.SUB_INT, "sub-int",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info MUL_INT =
         new Info(Opcodes.MUL_INT, "mul-int",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info DIV_INT =
         new Info(Opcodes.DIV_INT, "div-int",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info REM_INT =
         new Info(Opcodes.REM_INT, "rem-int",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info AND_INT =
         new Info(Opcodes.AND_INT, "and-int",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info OR_INT =
         new Info(Opcodes.OR_INT, "or-int",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info XOR_INT =
         new Info(Opcodes.XOR_INT, "xor-int",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info SHL_INT =
         new Info(Opcodes.SHL_INT, "shl-int",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info SHR_INT =
         new Info(Opcodes.SHR_INT, "shr-int",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info USHR_INT =
         new Info(Opcodes.USHR_INT, "ushr-int",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info ADD_LONG =
         new Info(Opcodes.ADD_LONG, "add-long",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info SUB_LONG =
         new Info(Opcodes.SUB_LONG, "sub-long",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info MUL_LONG =
         new Info(Opcodes.MUL_LONG, "mul-long",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info DIV_LONG =
         new Info(Opcodes.DIV_LONG, "div-long",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info REM_LONG =
         new Info(Opcodes.REM_LONG, "rem-long",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info AND_LONG =
         new Info(Opcodes.AND_LONG, "and-long",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info OR_LONG =
         new Info(Opcodes.OR_LONG, "or-long",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info XOR_LONG =
         new Info(Opcodes.XOR_LONG, "xor-long",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info SHL_LONG =
         new Info(Opcodes.SHL_LONG, "shl-long",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info SHR_LONG =
         new Info(Opcodes.SHR_LONG, "shr-long",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info USHR_LONG =
         new Info(Opcodes.USHR_LONG, "ushr-long",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info ADD_FLOAT =
         new Info(Opcodes.ADD_FLOAT, "add-float",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info SUB_FLOAT =
         new Info(Opcodes.SUB_FLOAT, "sub-float",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info MUL_FLOAT =
         new Info(Opcodes.MUL_FLOAT, "mul-float",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info DIV_FLOAT =
         new Info(Opcodes.DIV_FLOAT, "div-float",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info REM_FLOAT =
         new Info(Opcodes.REM_FLOAT, "rem-float",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info ADD_DOUBLE =
         new Info(Opcodes.ADD_DOUBLE, "add-double",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info SUB_DOUBLE =
         new Info(Opcodes.SUB_DOUBLE, "sub-double",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info MUL_DOUBLE =
         new Info(Opcodes.MUL_DOUBLE, "mul-double",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info DIV_DOUBLE =
         new Info(Opcodes.DIV_DOUBLE, "div-double",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info REM_DOUBLE =
         new Info(Opcodes.REM_DOUBLE, "rem-double",
-            InstructionCodec.FORMAT_23X, null);
+            InstructionCodec.FORMAT_23X, IndexType.NONE);
 
     public static final Info ADD_INT_2ADDR =
         new Info(Opcodes.ADD_INT_2ADDR, "add-int/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info SUB_INT_2ADDR =
         new Info(Opcodes.SUB_INT_2ADDR, "sub-int/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info MUL_INT_2ADDR =
         new Info(Opcodes.MUL_INT_2ADDR, "mul-int/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info DIV_INT_2ADDR =
         new Info(Opcodes.DIV_INT_2ADDR, "div-int/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info REM_INT_2ADDR =
         new Info(Opcodes.REM_INT_2ADDR, "rem-int/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info AND_INT_2ADDR =
         new Info(Opcodes.AND_INT_2ADDR, "and-int/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info OR_INT_2ADDR =
         new Info(Opcodes.OR_INT_2ADDR, "or-int/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info XOR_INT_2ADDR =
         new Info(Opcodes.XOR_INT_2ADDR, "xor-int/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info SHL_INT_2ADDR =
         new Info(Opcodes.SHL_INT_2ADDR, "shl-int/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info SHR_INT_2ADDR =
         new Info(Opcodes.SHR_INT_2ADDR, "shr-int/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info USHR_INT_2ADDR =
         new Info(Opcodes.USHR_INT_2ADDR, "ushr-int/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info ADD_LONG_2ADDR =
         new Info(Opcodes.ADD_LONG_2ADDR, "add-long/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info SUB_LONG_2ADDR =
         new Info(Opcodes.SUB_LONG_2ADDR, "sub-long/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info MUL_LONG_2ADDR =
         new Info(Opcodes.MUL_LONG_2ADDR, "mul-long/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info DIV_LONG_2ADDR =
         new Info(Opcodes.DIV_LONG_2ADDR, "div-long/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info REM_LONG_2ADDR =
         new Info(Opcodes.REM_LONG_2ADDR, "rem-long/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info AND_LONG_2ADDR =
         new Info(Opcodes.AND_LONG_2ADDR, "and-long/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info OR_LONG_2ADDR =
         new Info(Opcodes.OR_LONG_2ADDR, "or-long/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info XOR_LONG_2ADDR =
         new Info(Opcodes.XOR_LONG_2ADDR, "xor-long/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info SHL_LONG_2ADDR =
         new Info(Opcodes.SHL_LONG_2ADDR, "shl-long/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info SHR_LONG_2ADDR =
         new Info(Opcodes.SHR_LONG_2ADDR, "shr-long/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info USHR_LONG_2ADDR =
         new Info(Opcodes.USHR_LONG_2ADDR, "ushr-long/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info ADD_FLOAT_2ADDR =
         new Info(Opcodes.ADD_FLOAT_2ADDR, "add-float/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info SUB_FLOAT_2ADDR =
         new Info(Opcodes.SUB_FLOAT_2ADDR, "sub-float/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info MUL_FLOAT_2ADDR =
         new Info(Opcodes.MUL_FLOAT_2ADDR, "mul-float/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info DIV_FLOAT_2ADDR =
         new Info(Opcodes.DIV_FLOAT_2ADDR, "div-float/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info REM_FLOAT_2ADDR =
         new Info(Opcodes.REM_FLOAT_2ADDR, "rem-float/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info ADD_DOUBLE_2ADDR =
         new Info(Opcodes.ADD_DOUBLE_2ADDR, "add-double/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info SUB_DOUBLE_2ADDR =
         new Info(Opcodes.SUB_DOUBLE_2ADDR, "sub-double/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info MUL_DOUBLE_2ADDR =
         new Info(Opcodes.MUL_DOUBLE_2ADDR, "mul-double/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info DIV_DOUBLE_2ADDR =
         new Info(Opcodes.DIV_DOUBLE_2ADDR, "div-double/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info REM_DOUBLE_2ADDR =
         new Info(Opcodes.REM_DOUBLE_2ADDR, "rem-double/2addr",
-            InstructionCodec.FORMAT_12X, null);
+            InstructionCodec.FORMAT_12X, IndexType.NONE);
 
     public static final Info ADD_INT_LIT16 =
         new Info(Opcodes.ADD_INT_LIT16, "add-int/lit16",
-            InstructionCodec.FORMAT_22S, null);
+            InstructionCodec.FORMAT_22S, IndexType.NONE);
 
     public static final Info RSUB_INT =
         new Info(Opcodes.RSUB_INT, "rsub-int",
-            InstructionCodec.FORMAT_22S, null);
+            InstructionCodec.FORMAT_22S, IndexType.NONE);
 
     public static final Info MUL_INT_LIT16 =
         new Info(Opcodes.MUL_INT_LIT16, "mul-int/lit16",
-            InstructionCodec.FORMAT_22S, null);
+            InstructionCodec.FORMAT_22S, IndexType.NONE);
 
     public static final Info DIV_INT_LIT16 =
         new Info(Opcodes.DIV_INT_LIT16, "div-int/lit16",
-            InstructionCodec.FORMAT_22S, null);
+            InstructionCodec.FORMAT_22S, IndexType.NONE);
 
     public static final Info REM_INT_LIT16 =
         new Info(Opcodes.REM_INT_LIT16, "rem-int/lit16",
-            InstructionCodec.FORMAT_22S, null);
+            InstructionCodec.FORMAT_22S, IndexType.NONE);
 
     public static final Info AND_INT_LIT16 =
         new Info(Opcodes.AND_INT_LIT16, "and-int/lit16",
-            InstructionCodec.FORMAT_22S, null);
+            InstructionCodec.FORMAT_22S, IndexType.NONE);
 
     public static final Info OR_INT_LIT16 =
         new Info(Opcodes.OR_INT_LIT16, "or-int/lit16",
-            InstructionCodec.FORMAT_22S, null);
+            InstructionCodec.FORMAT_22S, IndexType.NONE);
 
     public static final Info XOR_INT_LIT16 =
         new Info(Opcodes.XOR_INT_LIT16, "xor-int/lit16",
-            InstructionCodec.FORMAT_22S, null);
+            InstructionCodec.FORMAT_22S, IndexType.NONE);
 
     public static final Info ADD_INT_LIT8 =
         new Info(Opcodes.ADD_INT_LIT8, "add-int/lit8",
-            InstructionCodec.FORMAT_22B, null);
+            InstructionCodec.FORMAT_22B, IndexType.NONE);
 
     public static final Info RSUB_INT_LIT8 =
         new Info(Opcodes.RSUB_INT_LIT8, "rsub-int/lit8",
-            InstructionCodec.FORMAT_22B, null);
+            InstructionCodec.FORMAT_22B, IndexType.NONE);
 
     public static final Info MUL_INT_LIT8 =
         new Info(Opcodes.MUL_INT_LIT8, "mul-int/lit8",
-            InstructionCodec.FORMAT_22B, null);
+            InstructionCodec.FORMAT_22B, IndexType.NONE);
 
     public static final Info DIV_INT_LIT8 =
         new Info(Opcodes.DIV_INT_LIT8, "div-int/lit8",
-            InstructionCodec.FORMAT_22B, null);
+            InstructionCodec.FORMAT_22B, IndexType.NONE);
 
     public static final Info REM_INT_LIT8 =
         new Info(Opcodes.REM_INT_LIT8, "rem-int/lit8",
-            InstructionCodec.FORMAT_22B, null);
+            InstructionCodec.FORMAT_22B, IndexType.NONE);
 
     public static final Info AND_INT_LIT8 =
         new Info(Opcodes.AND_INT_LIT8, "and-int/lit8",
-            InstructionCodec.FORMAT_22B, null);
+            InstructionCodec.FORMAT_22B, IndexType.NONE);
 
     public static final Info OR_INT_LIT8 =
         new Info(Opcodes.OR_INT_LIT8, "or-int/lit8",
-            InstructionCodec.FORMAT_22B, null);
+            InstructionCodec.FORMAT_22B, IndexType.NONE);
 
     public static final Info XOR_INT_LIT8 =
         new Info(Opcodes.XOR_INT_LIT8, "xor-int/lit8",
-            InstructionCodec.FORMAT_22B, null);
+            InstructionCodec.FORMAT_22B, IndexType.NONE);
 
     public static final Info SHL_INT_LIT8 =
         new Info(Opcodes.SHL_INT_LIT8, "shl-int/lit8",
-            InstructionCodec.FORMAT_22B, null);
+            InstructionCodec.FORMAT_22B, IndexType.NONE);
 
     public static final Info SHR_INT_LIT8 =
         new Info(Opcodes.SHR_INT_LIT8, "shr-int/lit8",
-            InstructionCodec.FORMAT_22B, null);
+            InstructionCodec.FORMAT_22B, IndexType.NONE);
 
     public static final Info USHR_INT_LIT8 =
         new Info(Opcodes.USHR_INT_LIT8, "ushr-int/lit8",
-            InstructionCodec.FORMAT_22B, null);
+            InstructionCodec.FORMAT_22B, IndexType.NONE);
 
     public static final Info CONST_CLASS_JUMBO =
         new Info(Opcodes.CONST_CLASS_JUMBO, "const-class/jumbo",
diff --git a/opcode-gen/opcode-gen.awk b/opcode-gen/opcode-gen.awk
index 2f1a830..0e0ff6c 100644
--- a/opcode-gen/opcode-gen.awk
+++ b/opcode-gen/opcode-gen.awk
@@ -108,18 +108,12 @@
     for (i = 0; i <= MAX_OPCODE; i++) {
         if (isUnused(i) || isOptimized(i)) continue;
 
-        itype = indexType[i];
-        if ((itype == "none") || (itype == "unknown")) {
-            itype = "null";
-        } else {
-            itype = toupper(itype);
-            gsub(/-/, "_", itype);
-            itype = "IndexType." itype;
-        }
+        itype = toupper(indexType[i]);
+        gsub(/-/, "_", itype);
 
         printf("    public static final Info %s =\n" \
                "        new Info(Opcodes.%s, \"%s\",\n" \
-               "            InstructionCodec.FORMAT_%s, %s);\n\n", \
+               "            InstructionCodec.FORMAT_%s, IndexType.%s);\n\n", \
                constName[i], constName[i], name[i], toupper(format[i]), itype);
     }
 }