summaryrefslogtreecommitdiffstats
path: root/opcode-gen
diff options
context:
space:
mode:
authorDan Bornstein <danfuzz@android.com>2010-11-17 12:05:04 -0800
committerDan Bornstein <danfuzz@android.com>2010-11-17 12:05:04 -0800
commit8424432a87c784547e4510bca538eaedc312e40d (patch)
treefd2adcb356418d6dc697ba5a8e1a1bb90eb1fde2 /opcode-gen
parentd03baafc41fe04167d0a8ba01d8cbc9bcbed8195 (diff)
downloadandroid_dalvik-8424432a87c784547e4510bca538eaedc312e40d.tar.gz
android_dalvik-8424432a87c784547e4510bca538eaedc312e40d.tar.bz2
android_dalvik-8424432a87c784547e4510bca538eaedc312e40d.zip
Generate the tables in InstrUtils.c...almost.
This patch adds code to opcode-gen to generate the opcode info tables currently built at vm start time, but they are left commented out for now. I wanted to separate the work of getting these tables generated from the work of getting those new tables hooked up, and this seemed like a reasonable way to cut through the larger effort. To be clear, I've already verified that the data in the new pregenerated tables matches what's in the status quo. Change-Id: Ie73dc6c6a5721e8f714f845c97b5338141995770
Diffstat (limited to 'opcode-gen')
-rw-r--r--opcode-gen/bytecode.txt5
-rwxr-xr-xopcode-gen/opcode-gen108
-rwxr-xr-xopcode-gen/regen-all1
3 files changed, 93 insertions, 21 deletions
diff --git a/opcode-gen/bytecode.txt b/opcode-gen/bytecode.txt
index 4462dac96..b24e6119a 100644
--- a/opcode-gen/bytecode.txt
+++ b/opcode-gen/bytecode.txt
@@ -41,7 +41,7 @@ format 22t
format 35c 3rc 5rc
# Optimized formats
-format 00x # not in spec; used for breakpoint
+format 00x # not in spec; used for undefined opcodes and breakpoint
format 20bc # not in spec; used for throw-verification-error
format 22cs
format 35mi
@@ -57,6 +57,7 @@ format 3rms
# y
# n
# index type; one of:
+# unknown -- used for undefined opcodes and breakpoint
# none
# varies
# type-ref
@@ -311,7 +312,7 @@ op e8 +iget-wide-volatile 22c y field-ref optimized|continue|thro
op e9 +iput-wide-volatile 22c n field-ref optimized|continue|throw
op ea +sget-wide-volatile 21c y field-ref optimized|continue|throw
op eb +sput-wide-volatile 21c n field-ref optimized|continue|throw
-op ec ^breakpoint 00x n none optimized|continue|throw
+op ec ^breakpoint 00x n unknown optimized
op ed ^throw-verification-error 20bc n varies optimized|throw
op ee +execute-inline 35mi n inline-method optimized|continue|throw
op ef +execute-inline/range 3rmi n inline-method optimized|continue|throw
diff --git a/opcode-gen/opcode-gen b/opcode-gen/opcode-gen
index 976a169ad..17560d107 100755
--- a/opcode-gen/opcode-gen
+++ b/opcode-gen/opcode-gen
@@ -172,8 +172,73 @@ consumeUntil != "" {
next;
}
+/BEGIN\(libdex-widths\)/ {
+ consumeUntil = "END(libdex-widths)";
+ print;
+
+ col = 1;
+ for (i = 0; i <= MAX_LIBDEX_OPCODE; i++) {
+ value = sprintf("%d,", isUnusedByte(i) ? 0 : width[i]);
+ col = colPrint(value, (i == MAX_LIBDEX_OPCODE), col, 16, 2, " ");
+ }
+
+ next;
+}
+
+/BEGIN\(libdex-flags\)/ {
+ consumeUntil = "END(libdex-flags)";
+ print;
+
+ for (i = 0; i <= MAX_LIBDEX_OPCODE; i++) {
+ value = flagsToC(isUnusedByte(i) ? 0 : flags[i]);
+ printf(" %s,\n", value);
+ }
+
+ next;
+}
+
+/BEGIN\(libdex-formats\)/ {
+ consumeUntil = "END(libdex-formats)";
+ print;
+
+ col = 1;
+ for (i = 0; i <= MAX_LIBDEX_OPCODE; i++) {
+ value = sprintf("kFmt%s,", isUnusedByte(i) ? "00x" : format[i]);
+ col = colPrint(value, (i == MAX_LIBDEX_OPCODE), col, 7, 9, " ");
+ }
+
+ next;
+}
+
+/BEGIN\(libdex-index-types\)/ {
+ consumeUntil = "END(libdex-index-types)";
+ print;
+
+ col = 1;
+ for (i = 0; i <= MAX_LIBDEX_OPCODE; i++) {
+ value = isUnusedByte(i) ? "unknown" : indexType[i];
+ value = sprintf("%s,", indexTypeValues[value]);
+ col = colPrint(value, (i == MAX_LIBDEX_OPCODE), col, 3, 19, " ");
+ }
+
+ next;
+}
+
{ print; }
+# Helper to print out an element in a multi-column fashion. It returns
+# the (one-based) column number that the next element will be printed
+# in.
+function colPrint(value, isLast, col, numCols, colWidth, linePrefix) {
+ isLast = (isLast || (col == numCols));
+ printf("%s%-*s%s",
+ (col == 1) ? linePrefix : " ",
+ isLast ? 1 : colWidth, value,
+ isLast ? "\n" : "");
+
+ return (col % numCols) + 1;
+}
+
# Read the bytecode description file.
function readBytecodes(i, parts, line, cmd, status, count) {
# locals: parts, line, cmd, status, count
@@ -230,14 +295,19 @@ function defineOpcode(line, count, parts, idx) {
flags[idx] = parts[6];
# Calculate derived values.
+
constName[idx] = toupper(name[idx]);
gsub("[---/]", "_", constName[idx]); # Dash and slash become underscore.
gsub("[+^]", "", constName[idx]); # Plus and caret are removed.
split(name[idx], parts, "/");
+
family[idx] = toupper(parts[1]);
gsub("-", "_", family[idx]); # Dash becomes underscore.
gsub("[+^]", "", family[idx]); # Plus and caret are removed.
+ split(format[idx], parts, ""); # Width is the first format char.
+ width[idx] = parts[1];
+
# This association is used when computing "next" opcodes.
familyFormat[family[idx],format[idx]] = idx;
@@ -398,39 +468,39 @@ function isOptimized(idx, parts, f) {
return 0;
}
-# Returns true if there is no definition for given opcode (by index).
+# Returns true if there is no definition for the given opcode (by index).
function isUnused(idx) {
return (name[idx] == "");
}
+# Returns true if there is no definition for the given opcode (by
+# index), taken as a single-byte opcode. The odd case for this
+# function is 255, which is the first extended (two-byte) opcode. For
+# the purposes of this function, it is considered unused. (This is
+# meant as a stop-gap measure for code that is not yet prepared to
+# deal with extended opcodes.)
+function isUnusedByte(idx) {
+ return (idx == 255) || (name[idx] == "");
+}
+
# Returns the constant name of the given single-byte opcode (by index)
# or the string "UNUSED_XX" (where XX is the index in hex) if the
-# opcode is unused. The odd case for this function is 255, which is
-# the first extended (two-byte) opcode. For the purposes of this
-# function, it is considered unused. (This is meant as a stop-gap
-# measure for code that is not yet prepared to deal with extended
-# opcodes.)
-function constNameOrUnusedByte(idx, n) {
- n = constName[idx];
- if ((n == "") || (i == 255)) {
+# opcode is unused. See isUnusedByte(), above, for more info.
+function constNameOrUnusedByte(idx) {
+ if (isUnusedByte(idx)) {
return toupper(sprintf("UNUSED_%02x", idx));
}
- return n;
+ return constName[idx];
}
# Returns the (human-oriented) name of the given single-byte opcode
# (by index) or the string "unused-xx" (where xx is the index in hex)
-# if the opcode is unused. The odd case for this function is 255,
-# which is the first extended (two-byte) opcode. For the purposes of
-# this function, it is considered unused. (This is meant as a stop-gap
-# measure for code that is not yet prepared to deal with extended
-# opcodes.)
-function nameOrUnusedByte(idx, n) {
- n = name[idx];
- if ((n == "") || (i == 255)) {
+# if the opcode is unused. See isUnusedByte(), above, for more info.
+function nameOrUnusedByte(idx) {
+ if (isUnusedByte(idx)) {
return sprintf("unused-%02x", idx);
}
- return n;
+ return name[idx];
}
' "$file" > "$tmpfile"
diff --git a/opcode-gen/regen-all b/opcode-gen/regen-all
index 4e5c38229..276893e7e 100755
--- a/opcode-gen/regen-all
+++ b/opcode-gen/regen-all
@@ -37,5 +37,6 @@ cd ".."
${progdir}/opcode-gen dx/src/com/android/dx/dex/code/DalvOps.java
${progdir}/opcode-gen dx/src/com/android/dx/dex/code/Dops.java
${progdir}/opcode-gen dx/src/com/android/dx/dex/code/RopToDop.java
+${progdir}/opcode-gen libdex/InstrUtils.c
${progdir}/opcode-gen libdex/OpCode.h
${progdir}/opcode-gen libdex/OpCodeNames.c