summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libdex/OpCode.h639
-rwxr-xr-xopcode-gen/opcode-gen39
-rwxr-xr-xopcode-gen/regen-all4
3 files changed, 339 insertions, 343 deletions
diff --git a/libdex/OpCode.h b/libdex/OpCode.h
index b0886af1d..2ff73bc70 100644
--- a/libdex/OpCode.h
+++ b/libdex/OpCode.h
@@ -15,8 +15,13 @@
*/
/*
- * Dalvik opcode enumeration.
+ * Dalvik opcode information.
+ *
+ * IMPORTANT NOTE: The contents of this file are mostly generated
+ * automatically by the opcode-gen tool. Any edits to the generated
+ * sections will get wiped out the next time the tool is run.
*/
+
#ifndef _LIBDEX_OPCODE
#define _LIBDEX_OPCODE
@@ -28,9 +33,14 @@
* if you replace "OP_UNUSED_2D" and neglect to update a switch statement,
* the compiler will complain about an unknown value.
*
+ * Bytecode definition and generated code:
+ *
+ * - update bytecode.txt in the opcode-gen directory
+ * - run opcode-gen/regen-all; this will regenerate a number of tables,
+ * definitions, and declarations in the code, including the ones
+ * immediately below in this file.
+ *
* Opcode definitions and attributes:
- * - update the OpCode enum below
- * - update the "goto table" definition macro, DEFINE_GOTO_TABLE(), below
* - update the instruction info table generators and (if you changed an
* instruction format) instruction decoder in InstrUtils.c
* - update the instruction format list in InstrUtils.h, if necessary
@@ -60,12 +70,32 @@
* test 003-omnibus-opcodes will exercise most of the opcodes.
*/
+/* the highest opcode value of a valid Dalvik opcode, plus one */
+#define kNumDalvikInstructions 256
+
+/*
+ * Switch-statement signatures are a "NOP" followed by a code. (A true NOP
+ * is 0x0000.)
+ */
+#define kPackedSwitchSignature 0x0100
+#define kSparseSwitchSignature 0x0200
+#define kArrayDataSignature 0x0300
+
/*
- * Dalvik opcode list.
+ * Enumeration of all Dalvik opcodes, where the enumeration value
+ * associated with each is the corresponding opcode number as noted in
+ * the Dalvik bytecode spec.
+ *
+ * A note about the "breakpoint" opcode. This instruction is special,
+ * in that it should never be seen by anything but the debug
+ * interpreter. During debugging it takes the place of an arbitrary
+ * opcode, which means operations like "tell me the opcode width so I
+ * can find the next instruction" aren't possible. (This is
+ * correctable, but probably not useful.)
*/
typedef enum OpCode {
+ // BEGIN(libdex-opcode-enum); GENERATED AUTOMATICALLY BY opcode-gen
OP_NOP = 0x00,
-
OP_MOVE = 0x01,
OP_MOVE_FROM16 = 0x02,
OP_MOVE_16 = 0x03,
@@ -75,17 +105,14 @@ typedef enum OpCode {
OP_MOVE_OBJECT = 0x07,
OP_MOVE_OBJECT_FROM16 = 0x08,
OP_MOVE_OBJECT_16 = 0x09,
-
OP_MOVE_RESULT = 0x0a,
OP_MOVE_RESULT_WIDE = 0x0b,
OP_MOVE_RESULT_OBJECT = 0x0c,
OP_MOVE_EXCEPTION = 0x0d,
-
OP_RETURN_VOID = 0x0e,
OP_RETURN = 0x0f,
OP_RETURN_WIDE = 0x10,
OP_RETURN_OBJECT = 0x11,
-
OP_CONST_4 = 0x12,
OP_CONST_16 = 0x13,
OP_CONST = 0x14,
@@ -97,35 +124,27 @@ typedef enum OpCode {
OP_CONST_STRING = 0x1a,
OP_CONST_STRING_JUMBO = 0x1b,
OP_CONST_CLASS = 0x1c,
-
OP_MONITOR_ENTER = 0x1d,
OP_MONITOR_EXIT = 0x1e,
-
OP_CHECK_CAST = 0x1f,
OP_INSTANCE_OF = 0x20,
-
OP_ARRAY_LENGTH = 0x21,
-
OP_NEW_INSTANCE = 0x22,
OP_NEW_ARRAY = 0x23,
-
OP_FILLED_NEW_ARRAY = 0x24,
OP_FILLED_NEW_ARRAY_RANGE = 0x25,
OP_FILL_ARRAY_DATA = 0x26,
-
OP_THROW = 0x27,
OP_GOTO = 0x28,
OP_GOTO_16 = 0x29,
OP_GOTO_32 = 0x2a,
OP_PACKED_SWITCH = 0x2b,
OP_SPARSE_SWITCH = 0x2c,
-
OP_CMPL_FLOAT = 0x2d,
OP_CMPG_FLOAT = 0x2e,
OP_CMPL_DOUBLE = 0x2f,
OP_CMPG_DOUBLE = 0x30,
OP_CMP_LONG = 0x31,
-
OP_IF_EQ = 0x32,
OP_IF_NE = 0x33,
OP_IF_LT = 0x34,
@@ -138,14 +157,12 @@ typedef enum OpCode {
OP_IF_GEZ = 0x3b,
OP_IF_GTZ = 0x3c,
OP_IF_LEZ = 0x3d,
-
OP_UNUSED_3E = 0x3e,
OP_UNUSED_3F = 0x3f,
OP_UNUSED_40 = 0x40,
OP_UNUSED_41 = 0x41,
OP_UNUSED_42 = 0x42,
OP_UNUSED_43 = 0x43,
-
OP_AGET = 0x44,
OP_AGET_WIDE = 0x45,
OP_AGET_OBJECT = 0x46,
@@ -160,7 +177,6 @@ typedef enum OpCode {
OP_APUT_BYTE = 0x4f,
OP_APUT_CHAR = 0x50,
OP_APUT_SHORT = 0x51,
-
OP_IGET = 0x52,
OP_IGET_WIDE = 0x53,
OP_IGET_OBJECT = 0x54,
@@ -175,7 +191,6 @@ typedef enum OpCode {
OP_IPUT_BYTE = 0x5d,
OP_IPUT_CHAR = 0x5e,
OP_IPUT_SHORT = 0x5f,
-
OP_SGET = 0x60,
OP_SGET_WIDE = 0x61,
OP_SGET_OBJECT = 0x62,
@@ -190,24 +205,19 @@ typedef enum OpCode {
OP_SPUT_BYTE = 0x6b,
OP_SPUT_CHAR = 0x6c,
OP_SPUT_SHORT = 0x6d,
-
OP_INVOKE_VIRTUAL = 0x6e,
OP_INVOKE_SUPER = 0x6f,
OP_INVOKE_DIRECT = 0x70,
OP_INVOKE_STATIC = 0x71,
OP_INVOKE_INTERFACE = 0x72,
-
OP_UNUSED_73 = 0x73,
-
OP_INVOKE_VIRTUAL_RANGE = 0x74,
OP_INVOKE_SUPER_RANGE = 0x75,
OP_INVOKE_DIRECT_RANGE = 0x76,
OP_INVOKE_STATIC_RANGE = 0x77,
OP_INVOKE_INTERFACE_RANGE = 0x78,
-
OP_UNUSED_79 = 0x79,
OP_UNUSED_7A = 0x7a,
-
OP_NEG_INT = 0x7b,
OP_NOT_INT = 0x7c,
OP_NEG_LONG = 0x7d,
@@ -229,7 +239,6 @@ typedef enum OpCode {
OP_INT_TO_BYTE = 0x8d,
OP_INT_TO_CHAR = 0x8e,
OP_INT_TO_SHORT = 0x8f,
-
OP_ADD_INT = 0x90,
OP_SUB_INT = 0x91,
OP_MUL_INT = 0x92,
@@ -241,7 +250,6 @@ typedef enum OpCode {
OP_SHL_INT = 0x98,
OP_SHR_INT = 0x99,
OP_USHR_INT = 0x9a,
-
OP_ADD_LONG = 0x9b,
OP_SUB_LONG = 0x9c,
OP_MUL_LONG = 0x9d,
@@ -253,7 +261,6 @@ typedef enum OpCode {
OP_SHL_LONG = 0xa3,
OP_SHR_LONG = 0xa4,
OP_USHR_LONG = 0xa5,
-
OP_ADD_FLOAT = 0xa6,
OP_SUB_FLOAT = 0xa7,
OP_MUL_FLOAT = 0xa8,
@@ -264,7 +271,6 @@ typedef enum OpCode {
OP_MUL_DOUBLE = 0xad,
OP_DIV_DOUBLE = 0xae,
OP_REM_DOUBLE = 0xaf,
-
OP_ADD_INT_2ADDR = 0xb0,
OP_SUB_INT_2ADDR = 0xb1,
OP_MUL_INT_2ADDR = 0xb2,
@@ -276,7 +282,6 @@ typedef enum OpCode {
OP_SHL_INT_2ADDR = 0xb8,
OP_SHR_INT_2ADDR = 0xb9,
OP_USHR_INT_2ADDR = 0xba,
-
OP_ADD_LONG_2ADDR = 0xbb,
OP_SUB_LONG_2ADDR = 0xbc,
OP_MUL_LONG_2ADDR = 0xbd,
@@ -288,7 +293,6 @@ typedef enum OpCode {
OP_SHL_LONG_2ADDR = 0xc3,
OP_SHR_LONG_2ADDR = 0xc4,
OP_USHR_LONG_2ADDR = 0xc5,
-
OP_ADD_FLOAT_2ADDR = 0xc6,
OP_SUB_FLOAT_2ADDR = 0xc7,
OP_MUL_FLOAT_2ADDR = 0xc8,
@@ -299,16 +303,14 @@ typedef enum OpCode {
OP_MUL_DOUBLE_2ADDR = 0xcd,
OP_DIV_DOUBLE_2ADDR = 0xce,
OP_REM_DOUBLE_2ADDR = 0xcf,
-
OP_ADD_INT_LIT16 = 0xd0,
- OP_RSUB_INT = 0xd1, /* no _LIT16 suffix for this */
+ OP_RSUB_INT = 0xd1,
OP_MUL_INT_LIT16 = 0xd2,
OP_DIV_INT_LIT16 = 0xd3,
OP_REM_INT_LIT16 = 0xd4,
OP_AND_INT_LIT16 = 0xd5,
OP_OR_INT_LIT16 = 0xd6,
OP_XOR_INT_LIT16 = 0xd7,
-
OP_ADD_INT_LIT8 = 0xd8,
OP_RSUB_INT_LIT8 = 0xd9,
OP_MUL_INT_LIT8 = 0xda,
@@ -320,32 +322,19 @@ typedef enum OpCode {
OP_SHL_INT_LIT8 = 0xe0,
OP_SHR_INT_LIT8 = 0xe1,
OP_USHR_INT_LIT8 = 0xe2,
-
- /* verifier/optimizer output -- nothing below here is generated by "dx" */
OP_IGET_VOLATILE = 0xe3,
OP_IPUT_VOLATILE = 0xe4,
OP_SGET_VOLATILE = 0xe5,
OP_SPUT_VOLATILE = 0xe6,
OP_IGET_OBJECT_VOLATILE = 0xe7,
-
OP_IGET_WIDE_VOLATILE = 0xe8,
OP_IPUT_WIDE_VOLATILE = 0xe9,
OP_SGET_WIDE_VOLATILE = 0xea,
OP_SPUT_WIDE_VOLATILE = 0xeb,
-
- /*
- * The "breakpoint" instruction is special, in that it should never
- * be seen by anything but the debug interpreter. During debugging
- * it takes the place of an arbitrary opcode, which means operations
- * like "tell me the opcode width so I can find the next instruction"
- * aren't possible. (This is correctable, but probably not useful.)
- */
OP_BREAKPOINT = 0xec,
-
OP_THROW_VERIFICATION_ERROR = 0xed,
OP_EXECUTE_INLINE = 0xee,
OP_EXECUTE_INLINE_RANGE = 0xef,
-
OP_INVOKE_DIRECT_EMPTY = 0xf0,
OP_RETURN_VOID_BARRIER = 0xf1,
OP_IGET_QUICK = 0xf2,
@@ -354,7 +343,6 @@ typedef enum OpCode {
OP_IPUT_QUICK = 0xf5,
OP_IPUT_WIDE_QUICK = 0xf6,
OP_IPUT_OBJECT_QUICK = 0xf7,
-
OP_INVOKE_VIRTUAL_QUICK = 0xf8,
OP_INVOKE_VIRTUAL_QUICK_RANGE = 0xf9,
OP_INVOKE_SUPER_QUICK = 0xfa,
@@ -362,303 +350,274 @@ typedef enum OpCode {
OP_IPUT_OBJECT_VOLATILE = 0xfc,
OP_SGET_OBJECT_VOLATILE = 0xfd,
OP_SPUT_OBJECT_VOLATILE = 0xfe,
-
- OP_UNUSED_FF = 0xff, /* reserved for code expansion */
+ OP_UNUSED_FF = 0xff,
+ // END(libdex-opcode-enum)
} OpCode;
-#define kNumDalvikInstructions 256
-
-
/*
- * Switch-statement signatures are a "NOP" followed by a code. (A true NOP
- * is 0x0000.)
- */
-#define kPackedSwitchSignature 0x0100
-#define kSparseSwitchSignature 0x0200
-#define kArrayDataSignature 0x0300
-
-/*
- * Macro used to generate computed goto tables for the C interpreter.
- *
- * The labels here must match up with the labels in the interpreter
- * implementation. There is no direct connection between these and the
- * numeric definitions above, but if the two get out of sync strange things
- * will happen.
+ * Macro used to generate a computed goto table for use in implementing
+ * an interpreter in C.
*/
#define DEFINE_GOTO_TABLE(_name) \
- static const void* _name[kNumDalvikInstructions] = { \
- /* 00..0f */ \
- H(OP_NOP), \
- H(OP_MOVE), \
- H(OP_MOVE_FROM16), \
- H(OP_MOVE_16), \
- H(OP_MOVE_WIDE), \
- H(OP_MOVE_WIDE_FROM16), \
- H(OP_MOVE_WIDE_16), \
- H(OP_MOVE_OBJECT), \
- H(OP_MOVE_OBJECT_FROM16), \
- H(OP_MOVE_OBJECT_16), \
- H(OP_MOVE_RESULT), \
- H(OP_MOVE_RESULT_WIDE), \
- H(OP_MOVE_RESULT_OBJECT), \
- H(OP_MOVE_EXCEPTION), \
- H(OP_RETURN_VOID), \
- H(OP_RETURN), \
- /* 10..1f */ \
- H(OP_RETURN_WIDE), \
- H(OP_RETURN_OBJECT), \
- H(OP_CONST_4), \
- H(OP_CONST_16), \
- H(OP_CONST), \
- H(OP_CONST_HIGH16), \
- H(OP_CONST_WIDE_16), \
- H(OP_CONST_WIDE_32), \
- H(OP_CONST_WIDE), \
- H(OP_CONST_WIDE_HIGH16), \
- H(OP_CONST_STRING), \
- H(OP_CONST_STRING_JUMBO), \
- H(OP_CONST_CLASS), \
- H(OP_MONITOR_ENTER), \
- H(OP_MONITOR_EXIT), \
- H(OP_CHECK_CAST), \
- /* 20..2f */ \
- H(OP_INSTANCE_OF), \
- H(OP_ARRAY_LENGTH), \
- H(OP_NEW_INSTANCE), \
- H(OP_NEW_ARRAY), \
- H(OP_FILLED_NEW_ARRAY), \
- H(OP_FILLED_NEW_ARRAY_RANGE), \
- H(OP_FILL_ARRAY_DATA), \
- H(OP_THROW), \
- H(OP_GOTO), \
- H(OP_GOTO_16), \
- H(OP_GOTO_32), \
- H(OP_PACKED_SWITCH), \
- H(OP_SPARSE_SWITCH), \
- H(OP_CMPL_FLOAT), \
- H(OP_CMPG_FLOAT), \
- H(OP_CMPL_DOUBLE), \
- /* 30..3f */ \
- H(OP_CMPG_DOUBLE), \
- H(OP_CMP_LONG), \
- H(OP_IF_EQ), \
- H(OP_IF_NE), \
- H(OP_IF_LT), \
- H(OP_IF_GE), \
- H(OP_IF_GT), \
- H(OP_IF_LE), \
- H(OP_IF_EQZ), \
- H(OP_IF_NEZ), \
- H(OP_IF_LTZ), \
- H(OP_IF_GEZ), \
- H(OP_IF_GTZ), \
- H(OP_IF_LEZ), \
- H(OP_UNUSED_3E), \
- H(OP_UNUSED_3F), \
- /* 40..4f */ \
- H(OP_UNUSED_40), \
- H(OP_UNUSED_41), \
- H(OP_UNUSED_42), \
- H(OP_UNUSED_43), \
- H(OP_AGET), \
- H(OP_AGET_WIDE), \
- H(OP_AGET_OBJECT), \
- H(OP_AGET_BOOLEAN), \
- H(OP_AGET_BYTE), \
- H(OP_AGET_CHAR), \
- H(OP_AGET_SHORT), \
- H(OP_APUT), \
- H(OP_APUT_WIDE), \
- H(OP_APUT_OBJECT), \
- H(OP_APUT_BOOLEAN), \
- H(OP_APUT_BYTE), \
- /* 50..5f */ \
- H(OP_APUT_CHAR), \
- H(OP_APUT_SHORT), \
- H(OP_IGET), \
- H(OP_IGET_WIDE), \
- H(OP_IGET_OBJECT), \
- H(OP_IGET_BOOLEAN), \
- H(OP_IGET_BYTE), \
- H(OP_IGET_CHAR), \
- H(OP_IGET_SHORT), \
- H(OP_IPUT), \
- H(OP_IPUT_WIDE), \
- H(OP_IPUT_OBJECT), \
- H(OP_IPUT_BOOLEAN), \
- H(OP_IPUT_BYTE), \
- H(OP_IPUT_CHAR), \
- H(OP_IPUT_SHORT), \
- /* 60..6f */ \
- H(OP_SGET), \
- H(OP_SGET_WIDE), \
- H(OP_SGET_OBJECT), \
- H(OP_SGET_BOOLEAN), \
- H(OP_SGET_BYTE), \
- H(OP_SGET_CHAR), \
- H(OP_SGET_SHORT), \
- H(OP_SPUT), \
- H(OP_SPUT_WIDE), \
- H(OP_SPUT_OBJECT), \
- H(OP_SPUT_BOOLEAN), \
- H(OP_SPUT_BYTE), \
- H(OP_SPUT_CHAR), \
- H(OP_SPUT_SHORT), \
- H(OP_INVOKE_VIRTUAL), \
- H(OP_INVOKE_SUPER), \
- /* 70..7f */ \
- H(OP_INVOKE_DIRECT), \
- H(OP_INVOKE_STATIC), \
- H(OP_INVOKE_INTERFACE), \
- H(OP_UNUSED_73), \
- H(OP_INVOKE_VIRTUAL_RANGE), \
- H(OP_INVOKE_SUPER_RANGE), \
- H(OP_INVOKE_DIRECT_RANGE), \
- H(OP_INVOKE_STATIC_RANGE), \
- H(OP_INVOKE_INTERFACE_RANGE), \
- H(OP_UNUSED_79), \
- H(OP_UNUSED_7A), \
- H(OP_NEG_INT), \
- H(OP_NOT_INT), \
- H(OP_NEG_LONG), \
- H(OP_NOT_LONG), \
- H(OP_NEG_FLOAT), \
- /* 80..8f */ \
- H(OP_NEG_DOUBLE), \
- H(OP_INT_TO_LONG), \
- H(OP_INT_TO_FLOAT), \
- H(OP_INT_TO_DOUBLE), \
- H(OP_LONG_TO_INT), \
- H(OP_LONG_TO_FLOAT), \
- H(OP_LONG_TO_DOUBLE), \
- H(OP_FLOAT_TO_INT), \
- H(OP_FLOAT_TO_LONG), \
- H(OP_FLOAT_TO_DOUBLE), \
- H(OP_DOUBLE_TO_INT), \
- H(OP_DOUBLE_TO_LONG), \
- H(OP_DOUBLE_TO_FLOAT), \
- H(OP_INT_TO_BYTE), \
- H(OP_INT_TO_CHAR), \
- H(OP_INT_TO_SHORT), \
- /* 90..9f */ \
- H(OP_ADD_INT), \
- H(OP_SUB_INT), \
- H(OP_MUL_INT), \
- H(OP_DIV_INT), \
- H(OP_REM_INT), \
- H(OP_AND_INT), \
- H(OP_OR_INT), \
- H(OP_XOR_INT), \
- H(OP_SHL_INT), \
- H(OP_SHR_INT), \
- H(OP_USHR_INT), \
- H(OP_ADD_LONG), \
- H(OP_SUB_LONG), \
- H(OP_MUL_LONG), \
- H(OP_DIV_LONG), \
- H(OP_REM_LONG), \
- /* a0..af */ \
- H(OP_AND_LONG), \
- H(OP_OR_LONG), \
- H(OP_XOR_LONG), \
- H(OP_SHL_LONG), \
- H(OP_SHR_LONG), \
- H(OP_USHR_LONG), \
- H(OP_ADD_FLOAT), \
- H(OP_SUB_FLOAT), \
- H(OP_MUL_FLOAT), \
- H(OP_DIV_FLOAT), \
- H(OP_REM_FLOAT), \
- H(OP_ADD_DOUBLE), \
- H(OP_SUB_DOUBLE), \
- H(OP_MUL_DOUBLE), \
- H(OP_DIV_DOUBLE), \
- H(OP_REM_DOUBLE), \
- /* b0..bf */ \
- H(OP_ADD_INT_2ADDR), \
- H(OP_SUB_INT_2ADDR), \
- H(OP_MUL_INT_2ADDR), \
- H(OP_DIV_INT_2ADDR), \
- H(OP_REM_INT_2ADDR), \
- H(OP_AND_INT_2ADDR), \
- H(OP_OR_INT_2ADDR), \
- H(OP_XOR_INT_2ADDR), \
- H(OP_SHL_INT_2ADDR), \
- H(OP_SHR_INT_2ADDR), \
- H(OP_USHR_INT_2ADDR), \
- H(OP_ADD_LONG_2ADDR), \
- H(OP_SUB_LONG_2ADDR), \
- H(OP_MUL_LONG_2ADDR), \
- H(OP_DIV_LONG_2ADDR), \
- H(OP_REM_LONG_2ADDR), \
- /* c0..cf */ \
- H(OP_AND_LONG_2ADDR), \
- H(OP_OR_LONG_2ADDR), \
- H(OP_XOR_LONG_2ADDR), \
- H(OP_SHL_LONG_2ADDR), \
- H(OP_SHR_LONG_2ADDR), \
- H(OP_USHR_LONG_2ADDR), \
- H(OP_ADD_FLOAT_2ADDR), \
- H(OP_SUB_FLOAT_2ADDR), \
- H(OP_MUL_FLOAT_2ADDR), \
- H(OP_DIV_FLOAT_2ADDR), \
- H(OP_REM_FLOAT_2ADDR), \
- H(OP_ADD_DOUBLE_2ADDR), \
- H(OP_SUB_DOUBLE_2ADDR), \
- H(OP_MUL_DOUBLE_2ADDR), \
- H(OP_DIV_DOUBLE_2ADDR), \
- H(OP_REM_DOUBLE_2ADDR), \
- /* d0..df */ \
- H(OP_ADD_INT_LIT16), \
- H(OP_RSUB_INT), \
- H(OP_MUL_INT_LIT16), \
- H(OP_DIV_INT_LIT16), \
- H(OP_REM_INT_LIT16), \
- H(OP_AND_INT_LIT16), \
- H(OP_OR_INT_LIT16), \
- H(OP_XOR_INT_LIT16), \
- H(OP_ADD_INT_LIT8), \
- H(OP_RSUB_INT_LIT8), \
- H(OP_MUL_INT_LIT8), \
- H(OP_DIV_INT_LIT8), \
- H(OP_REM_INT_LIT8), \
- H(OP_AND_INT_LIT8), \
- H(OP_OR_INT_LIT8), \
- H(OP_XOR_INT_LIT8), \
- /* e0..ef */ \
- H(OP_SHL_INT_LIT8), \
- H(OP_SHR_INT_LIT8), \
- H(OP_USHR_INT_LIT8), \
- H(OP_IGET_VOLATILE), \
- H(OP_IPUT_VOLATILE), \
- H(OP_SGET_VOLATILE), \
- H(OP_SPUT_VOLATILE), \
- H(OP_IGET_OBJECT_VOLATILE), \
- H(OP_IGET_WIDE_VOLATILE), \
- H(OP_IPUT_WIDE_VOLATILE), \
- H(OP_SGET_WIDE_VOLATILE), \
- H(OP_SPUT_WIDE_VOLATILE), \
- H(OP_BREAKPOINT), \
- H(OP_THROW_VERIFICATION_ERROR), \
- H(OP_EXECUTE_INLINE), \
- H(OP_EXECUTE_INLINE_RANGE), \
- /* f0..ff */ \
- H(OP_INVOKE_DIRECT_EMPTY), \
- H(OP_RETURN_VOID_BARRIER), \
- H(OP_IGET_QUICK), \
- H(OP_IGET_WIDE_QUICK), \
- H(OP_IGET_OBJECT_QUICK), \
- H(OP_IPUT_QUICK), \
- H(OP_IPUT_WIDE_QUICK), \
- H(OP_IPUT_OBJECT_QUICK), \
- H(OP_INVOKE_VIRTUAL_QUICK), \
- H(OP_INVOKE_VIRTUAL_QUICK_RANGE), \
- H(OP_INVOKE_SUPER_QUICK), \
- H(OP_INVOKE_SUPER_QUICK_RANGE), \
- H(OP_IPUT_OBJECT_VOLATILE), \
- H(OP_SGET_OBJECT_VOLATILE), \
- H(OP_SPUT_OBJECT_VOLATILE), \
- H(OP_UNUSED_FF), \
+ static const void* _name[kNumDalvikInstructions] = { \
+ /* BEGIN(libdex-goto-table); GENERATED AUTOMATICALLY BY opcode-gen */ \
+ H(OP_NOP), \
+ H(OP_MOVE), \
+ H(OP_MOVE_FROM16), \
+ H(OP_MOVE_16), \
+ H(OP_MOVE_WIDE), \
+ H(OP_MOVE_WIDE_FROM16), \
+ H(OP_MOVE_WIDE_16), \
+ H(OP_MOVE_OBJECT), \
+ H(OP_MOVE_OBJECT_FROM16), \
+ H(OP_MOVE_OBJECT_16), \
+ H(OP_MOVE_RESULT), \
+ H(OP_MOVE_RESULT_WIDE), \
+ H(OP_MOVE_RESULT_OBJECT), \
+ H(OP_MOVE_EXCEPTION), \
+ H(OP_RETURN_VOID), \
+ H(OP_RETURN), \
+ H(OP_RETURN_WIDE), \
+ H(OP_RETURN_OBJECT), \
+ H(OP_CONST_4), \
+ H(OP_CONST_16), \
+ H(OP_CONST), \
+ H(OP_CONST_HIGH16), \
+ H(OP_CONST_WIDE_16), \
+ H(OP_CONST_WIDE_32), \
+ H(OP_CONST_WIDE), \
+ H(OP_CONST_WIDE_HIGH16), \
+ H(OP_CONST_STRING), \
+ H(OP_CONST_STRING_JUMBO), \
+ H(OP_CONST_CLASS), \
+ H(OP_MONITOR_ENTER), \
+ H(OP_MONITOR_EXIT), \
+ H(OP_CHECK_CAST), \
+ H(OP_INSTANCE_OF), \
+ H(OP_ARRAY_LENGTH), \
+ H(OP_NEW_INSTANCE), \
+ H(OP_NEW_ARRAY), \
+ H(OP_FILLED_NEW_ARRAY), \
+ H(OP_FILLED_NEW_ARRAY_RANGE), \
+ H(OP_FILL_ARRAY_DATA), \
+ H(OP_THROW), \
+ H(OP_GOTO), \
+ H(OP_GOTO_16), \
+ H(OP_GOTO_32), \
+ H(OP_PACKED_SWITCH), \
+ H(OP_SPARSE_SWITCH), \
+ H(OP_CMPL_FLOAT), \
+ H(OP_CMPG_FLOAT), \
+ H(OP_CMPL_DOUBLE), \
+ H(OP_CMPG_DOUBLE), \
+ H(OP_CMP_LONG), \
+ H(OP_IF_EQ), \
+ H(OP_IF_NE), \
+ H(OP_IF_LT), \
+ H(OP_IF_GE), \
+ H(OP_IF_GT), \
+ H(OP_IF_LE), \
+ H(OP_IF_EQZ), \
+ H(OP_IF_NEZ), \
+ H(OP_IF_LTZ), \
+ H(OP_IF_GEZ), \
+ H(OP_IF_GTZ), \
+ H(OP_IF_LEZ), \
+ H(OP_UNUSED_3E), \
+ H(OP_UNUSED_3F), \
+ H(OP_UNUSED_40), \
+ H(OP_UNUSED_41), \
+ H(OP_UNUSED_42), \
+ H(OP_UNUSED_43), \
+ H(OP_AGET), \
+ H(OP_AGET_WIDE), \
+ H(OP_AGET_OBJECT), \
+ H(OP_AGET_BOOLEAN), \
+ H(OP_AGET_BYTE), \
+ H(OP_AGET_CHAR), \
+ H(OP_AGET_SHORT), \
+ H(OP_APUT), \
+ H(OP_APUT_WIDE), \
+ H(OP_APUT_OBJECT), \
+ H(OP_APUT_BOOLEAN), \
+ H(OP_APUT_BYTE), \
+ H(OP_APUT_CHAR), \
+ H(OP_APUT_SHORT), \
+ H(OP_IGET), \
+ H(OP_IGET_WIDE), \
+ H(OP_IGET_OBJECT), \
+ H(OP_IGET_BOOLEAN), \
+ H(OP_IGET_BYTE), \
+ H(OP_IGET_CHAR), \
+ H(OP_IGET_SHORT), \
+ H(OP_IPUT), \
+ H(OP_IPUT_WIDE), \
+ H(OP_IPUT_OBJECT), \
+ H(OP_IPUT_BOOLEAN), \
+ H(OP_IPUT_BYTE), \
+ H(OP_IPUT_CHAR), \
+ H(OP_IPUT_SHORT), \
+ H(OP_SGET), \
+ H(OP_SGET_WIDE), \
+ H(OP_SGET_OBJECT), \
+ H(OP_SGET_BOOLEAN), \
+ H(OP_SGET_BYTE), \
+ H(OP_SGET_CHAR), \
+ H(OP_SGET_SHORT), \
+ H(OP_SPUT), \
+ H(OP_SPUT_WIDE), \
+ H(OP_SPUT_OBJECT), \
+ H(OP_SPUT_BOOLEAN), \
+ H(OP_SPUT_BYTE), \
+ H(OP_SPUT_CHAR), \
+ H(OP_SPUT_SHORT), \
+ H(OP_INVOKE_VIRTUAL), \
+ H(OP_INVOKE_SUPER), \
+ H(OP_INVOKE_DIRECT), \
+ H(OP_INVOKE_STATIC), \
+ H(OP_INVOKE_INTERFACE), \
+ H(OP_UNUSED_73), \
+ H(OP_INVOKE_VIRTUAL_RANGE), \
+ H(OP_INVOKE_SUPER_RANGE), \
+ H(OP_INVOKE_DIRECT_RANGE), \
+ H(OP_INVOKE_STATIC_RANGE), \
+ H(OP_INVOKE_INTERFACE_RANGE), \
+ H(OP_UNUSED_79), \
+ H(OP_UNUSED_7A), \
+ H(OP_NEG_INT), \
+ H(OP_NOT_INT), \
+ H(OP_NEG_LONG), \
+ H(OP_NOT_LONG), \
+ H(OP_NEG_FLOAT), \
+ H(OP_NEG_DOUBLE), \
+ H(OP_INT_TO_LONG), \
+ H(OP_INT_TO_FLOAT), \
+ H(OP_INT_TO_DOUBLE), \
+ H(OP_LONG_TO_INT), \
+ H(OP_LONG_TO_FLOAT), \
+ H(OP_LONG_TO_DOUBLE), \
+ H(OP_FLOAT_TO_INT), \
+ H(OP_FLOAT_TO_LONG), \
+ H(OP_FLOAT_TO_DOUBLE), \
+ H(OP_DOUBLE_TO_INT), \
+ H(OP_DOUBLE_TO_LONG), \
+ H(OP_DOUBLE_TO_FLOAT), \
+ H(OP_INT_TO_BYTE), \
+ H(OP_INT_TO_CHAR), \
+ H(OP_INT_TO_SHORT), \
+ H(OP_ADD_INT), \
+ H(OP_SUB_INT), \
+ H(OP_MUL_INT), \
+ H(OP_DIV_INT), \
+ H(OP_REM_INT), \
+ H(OP_AND_INT), \
+ H(OP_OR_INT), \
+ H(OP_XOR_INT), \
+ H(OP_SHL_INT), \
+ H(OP_SHR_INT), \
+ H(OP_USHR_INT), \
+ H(OP_ADD_LONG), \
+ H(OP_SUB_LONG), \
+ H(OP_MUL_LONG), \
+ H(OP_DIV_LONG), \
+ H(OP_REM_LONG), \
+ H(OP_AND_LONG), \
+ H(OP_OR_LONG), \
+ H(OP_XOR_LONG), \
+ H(OP_SHL_LONG), \
+ H(OP_SHR_LONG), \
+ H(OP_USHR_LONG), \
+ H(OP_ADD_FLOAT), \
+ H(OP_SUB_FLOAT), \
+ H(OP_MUL_FLOAT), \
+ H(OP_DIV_FLOAT), \
+ H(OP_REM_FLOAT), \
+ H(OP_ADD_DOUBLE), \
+ H(OP_SUB_DOUBLE), \
+ H(OP_MUL_DOUBLE), \
+ H(OP_DIV_DOUBLE), \
+ H(OP_REM_DOUBLE), \
+ H(OP_ADD_INT_2ADDR), \
+ H(OP_SUB_INT_2ADDR), \
+ H(OP_MUL_INT_2ADDR), \
+ H(OP_DIV_INT_2ADDR), \
+ H(OP_REM_INT_2ADDR), \
+ H(OP_AND_INT_2ADDR), \
+ H(OP_OR_INT_2ADDR), \
+ H(OP_XOR_INT_2ADDR), \
+ H(OP_SHL_INT_2ADDR), \
+ H(OP_SHR_INT_2ADDR), \
+ H(OP_USHR_INT_2ADDR), \
+ H(OP_ADD_LONG_2ADDR), \
+ H(OP_SUB_LONG_2ADDR), \
+ H(OP_MUL_LONG_2ADDR), \
+ H(OP_DIV_LONG_2ADDR), \
+ H(OP_REM_LONG_2ADDR), \
+ H(OP_AND_LONG_2ADDR), \
+ H(OP_OR_LONG_2ADDR), \
+ H(OP_XOR_LONG_2ADDR), \
+ H(OP_SHL_LONG_2ADDR), \
+ H(OP_SHR_LONG_2ADDR), \
+ H(OP_USHR_LONG_2ADDR), \
+ H(OP_ADD_FLOAT_2ADDR), \
+ H(OP_SUB_FLOAT_2ADDR), \
+ H(OP_MUL_FLOAT_2ADDR), \
+ H(OP_DIV_FLOAT_2ADDR), \
+ H(OP_REM_FLOAT_2ADDR), \
+ H(OP_ADD_DOUBLE_2ADDR), \
+ H(OP_SUB_DOUBLE_2ADDR), \
+ H(OP_MUL_DOUBLE_2ADDR), \
+ H(OP_DIV_DOUBLE_2ADDR), \
+ H(OP_REM_DOUBLE_2ADDR), \
+ H(OP_ADD_INT_LIT16), \
+ H(OP_RSUB_INT), \
+ H(OP_MUL_INT_LIT16), \
+ H(OP_DIV_INT_LIT16), \
+ H(OP_REM_INT_LIT16), \
+ H(OP_AND_INT_LIT16), \
+ H(OP_OR_INT_LIT16), \
+ H(OP_XOR_INT_LIT16), \
+ H(OP_ADD_INT_LIT8), \
+ H(OP_RSUB_INT_LIT8), \
+ H(OP_MUL_INT_LIT8), \
+ H(OP_DIV_INT_LIT8), \
+ H(OP_REM_INT_LIT8), \
+ H(OP_AND_INT_LIT8), \
+ H(OP_OR_INT_LIT8), \
+ H(OP_XOR_INT_LIT8), \
+ H(OP_SHL_INT_LIT8), \
+ H(OP_SHR_INT_LIT8), \
+ H(OP_USHR_INT_LIT8), \
+ H(OP_IGET_VOLATILE), \
+ H(OP_IPUT_VOLATILE), \
+ H(OP_SGET_VOLATILE), \
+ H(OP_SPUT_VOLATILE), \
+ H(OP_IGET_OBJECT_VOLATILE), \
+ H(OP_IGET_WIDE_VOLATILE), \
+ H(OP_IPUT_WIDE_VOLATILE), \
+ H(OP_SGET_WIDE_VOLATILE), \
+ H(OP_SPUT_WIDE_VOLATILE), \
+ H(OP_BREAKPOINT), \
+ H(OP_THROW_VERIFICATION_ERROR), \
+ H(OP_EXECUTE_INLINE), \
+ H(OP_EXECUTE_INLINE_RANGE), \
+ H(OP_INVOKE_DIRECT_EMPTY), \
+ H(OP_RETURN_VOID_BARRIER), \
+ H(OP_IGET_QUICK), \
+ H(OP_IGET_WIDE_QUICK), \
+ H(OP_IGET_OBJECT_QUICK), \
+ H(OP_IPUT_QUICK), \
+ H(OP_IPUT_WIDE_QUICK), \
+ H(OP_IPUT_OBJECT_QUICK), \
+ H(OP_INVOKE_VIRTUAL_QUICK), \
+ H(OP_INVOKE_VIRTUAL_QUICK_RANGE), \
+ H(OP_INVOKE_SUPER_QUICK), \
+ H(OP_INVOKE_SUPER_QUICK_RANGE), \
+ H(OP_IPUT_OBJECT_VOLATILE), \
+ H(OP_SGET_OBJECT_VOLATILE), \
+ H(OP_SPUT_OBJECT_VOLATILE), \
+ H(OP_UNUSED_FF), \
+ /* END(libdex-goto-table) */ \
};
#endif /*_LIBDEX_OPCODE*/
diff --git a/opcode-gen/opcode-gen b/opcode-gen/opcode-gen
index f57026815..7b2c36307 100755
--- a/opcode-gen/opcode-gen
+++ b/opcode-gen/opcode-gen
@@ -62,6 +62,7 @@ awk -v "bytecodeFile=$bytecodeFile" '
BEGIN {
MAX_OPCODE = 65535;
+ MAX_LIBDEX_OPCODE = 255; # TODO: Will not be true for long!
initIndexTypes();
initFlags();
if (readBytecodes()) exit 1;
@@ -137,6 +138,29 @@ consumeUntil != "" {
next;
}
+/BEGIN\(libdex-opcode-enum\)/ {
+ consumeUntil = "END(libdex-opcode-enum)";
+ print;
+
+ for (i = 0; i <= MAX_LIBDEX_OPCODE; i++) {
+ printf(" OP_%-28s = 0x%02x,\n", uppernameOrUnusedByte(i), i);
+ }
+
+ next;
+}
+
+/BEGIN\(libdex-goto-table\)/ {
+ consumeUntil = "END(libdex-goto-table)";
+ print;
+
+ for (i = 0; i <= MAX_LIBDEX_OPCODE; i++) {
+ content = sprintf(" H(OP_%s),", uppernameOrUnusedByte(i));
+ printf("%-78s\\\n", content);
+ }
+
+ next;
+}
+
{ print; }
# Read the bytecode description file.
@@ -369,6 +393,21 @@ function isUnused(idx, n) {
n = name[idx];
return (n == "") || (index(n, "unused") != 0);
}
+
+# Returns the uppercase 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 uppernameOrUnusedByte(idx, n) {
+ n = uppername[idx];
+ if ((n == "") || (i == 255)) {
+ return toupper(sprintf("UNUSED_%02x", idx));
+ }
+ return n;
+}
' "$file" > "$tmpfile"
cp "$tmpfile" "$file"
diff --git a/opcode-gen/regen-all b/opcode-gen/regen-all
index 790bf84e8..32330e86d 100755
--- a/opcode-gen/regen-all
+++ b/opcode-gen/regen-all
@@ -37,6 +37,4 @@ 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
-
-# Coming soon!
-# ${progdir}/opcode-gen libdex/OpCode.h
+${progdir}/opcode-gen libdex/OpCode.h