Be more prepared for InstrUtils code generation.

This patch removes "unconditional" as a flag (related change coming soon
to the vm code), and it prevents the dx codegen paths from doing anything
with optimized opcodes.

Change-Id: I0391d69d7956a564f3019f54d69a5522b8984ca0
diff --git a/dx/etc/bytecode.txt b/dx/etc/bytecode.txt
index 2d39272..ce68f58 100644
--- a/dx/etc/bytecode.txt
+++ b/dx/etc/bytecode.txt
@@ -61,7 +61,6 @@
 #     branch        -- might branch to an address
 #     continue      -- might continue to the next address in sequence
 #     switch        -- is a switch
-#     unconditional -- is an unconditional branch
 #     throw         -- might throw an exception
 #     return        -- is a return from method
 #     invoke        -- is a method invoke
@@ -106,9 +105,9 @@
 op   25 filled-new-array/range 3rc  n type-ref      continue|throw
 op   26 fill-array-data        31t  n none          continue
 op   27 throw                  11x  n none          throw
-op   28 goto                   10t  n none          branch|unconditional
-op   29 goto/16                20t  n none          branch|unconditional
-op   2a goto/32                30t  n none          branch|unconditional
+op   28 goto                   10t  n none          branch
+op   29 goto/16                20t  n none          branch
+op   2a goto/32                30t  n none          branch
 op   2b packed-switch          31t  n none          continue|switch
 op   2c sparse-switch          31t  n none          continue|switch
 op   2d cmpl-float             23x  y none          continue
diff --git a/dx/etc/opcode-gen b/dx/etc/opcode-gen
index 216097a..24e6d8a 100755
--- a/dx/etc/opcode-gen
+++ b/dx/etc/opcode-gen
@@ -20,11 +20,11 @@
 # generate code inside the given <file>, based on the directives found
 # in that file:
 #
-#     opcodes:       static final ints for each opcode
-#     dops:          static final objects for each opcode
-#     dops-init:     initialization code for the "dops"
+#     opcodes:       static final ints for each opcode (no optimized ops)
+#     dops:          static final objects for each opcode (no optimized ops)
+#     dops-init:     initialization code for the "dops" (no optimized ops)
 #     first-opcodes: a comment indicating which opcodes are at the head
-#                    position of instruction fitting chains
+#                    position of instruction fitting chains (no optimized ops)
 
 file="$1"
 tmpfile="/tmp/$$.txt"
@@ -80,7 +80,7 @@
     print;
 
     for (i = 0; i <= MAX_OPCODE; i++) {
-        if (hex[i] == "") continue;
+        if (isUnused(i) || isOptimized(i)) continue;
         printf("    public static final int %s = 0x%s;\n",
                uppername[i], hex[i]);
     }
@@ -93,6 +93,7 @@
     print;
 
     for (i = 0; i <= MAX_OPCODE; i++) {
+        if (isUnused(i) || isOptimized(i)) continue;
         if (isFirst[i] == "true") {
             printf("    //     DalvOps.%s\n", uppername[i]);
         }
@@ -106,9 +107,7 @@
     print;
 
     for (i = 0; i <= MAX_OPCODE; i++) {
-        if ((hex[i] == "") || (index(name[i], "unused") != 0)) {
-            continue;
-        }
+        if (isUnused(i) || isOptimized(i)) continue;
 
         nextOp = nextOpcode[i];
         nextOp = (nextOp == -1) ? "NO_NEXT" : uppername[nextOp];
@@ -129,12 +128,7 @@
     print;
 
     for (i = 0; i <= MAX_OPCODE; i++) {
-        if ((hex[i] == "") || (index(name[i], "unused") != 0)) {
-            continue;
-        }
-        if (index(name[i], "unused") != 0) {
-            continue;
-        }
+        if (isUnused(i) || isOptimized(i)) continue;
         printf("        set(%s);\n", uppername[i]);
     }
 
@@ -325,11 +319,11 @@
     flagValues["branch"]        = "kInstrCanBranch";
     flagValues["continue"]      = "kInstrCanContinue";
     flagValues["switch"]        = "kInstrCanSwitch";
-    flagValues["unconditional"] = "kInstrUnconditional";
     flagValues["throw"]         = "kInstrCanThrow";
     flagValues["return"]        = "kInstrCanReturn";
     flagValues["invoke"]        = "kInstrInvoke";
-    flagValues["optimized"]     = "kInstrOptimized";
+    flagValues["optimized"]     = "0"; # Not represented in C output
+    flagValues["0"]             = "0";
 }
 
 # Translate the given flags into the equivalent C expression. Returns
@@ -337,14 +331,16 @@
 function flagsToC(f, parts, result, i) {
     # locals: parts, result, i
     count = split(f, parts, /\|/); # Split input at pipe characters.
+    result = "0";
 
     for (i = 1; i <= count; i++) {
         f = flagValues[parts[i]];
         if (f == "") {
             printf("bogus flag: %s\n", f);
             return ""; # Bogus flag name.
-        }
-        if (i == 1) {
+        } else if (f == "0") {
+            # Nothing to append for this case.
+        } else if (result == "0") {
             result = f;
         } else {
             result = result "|" f;
@@ -353,6 +349,25 @@
 
     return result;
 }
+
+# Returns true if the given opcode (by index) is an "optimized" opcode.
+function isOptimized(idx, parts, f) {
+    # locals: parts, f
+    split(flags[idx], parts, /\|/); # Split flags[idx] at pipes.
+    for (f in parts) {
+        if (parts[f] == "optimized") return 1;
+    }
+    return 0;
+}
+
+# Returns true if the given opcode (by index) is unused. This is true either
+# if there is no definition at all for the opcode or if there is a definition
+# and the name contains the string "unused".
+function isUnused(idx, n) {
+    # locals: n
+    n = name[idx];
+    return (n == "") || (index(n, "unused") != 0);
+}
 ' "$file" > "$tmpfile"
 
 cp "$tmpfile" "$file"