From 8424432a87c784547e4510bca538eaedc312e40d Mon Sep 17 00:00:00 2001 From: Dan Bornstein Date: Wed, 17 Nov 2010 12:05:04 -0800 Subject: 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 --- opcode-gen/bytecode.txt | 5 ++- opcode-gen/opcode-gen | 108 +++++++++++++++++++++++++++++++++++++++--------- opcode-gen/regen-all | 1 + 3 files changed, 93 insertions(+), 21 deletions(-) (limited to 'opcode-gen') 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 -- cgit v1.2.3