2 * Copyright (C) 2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * Dalvik instruction utility functions.
20 #ifndef _LIBDEX_INSTRUTILS
21 #define _LIBDEX_INSTRUTILS
27 * Dalvik-defined instruction formats.
29 * (This defines InstructionFormat as an unsigned char to reduce the size
30 * of the table. This isn't necessary with some compilers, which use an
31 * integer width appropriate for the number of enum values.)
33 * If you add or delete a format, you have to change some or all of:
35 * - the switch inside dexDecodeInstruction() in InstrUtils.c
36 * - the switch inside dumpInstruction() in DexDump.c
37 * - the switch inside dvmCompilerMIR2LIR() in CodegenDriver.c
39 typedef unsigned char InstructionFormat;
40 enum InstructionFormat {
44 kFmt11n, // op vA, #+B
47 kFmt20bc, // [opt] op AA, thing@BBBB
49 kFmt22x, // op vAA, vBBBB
50 kFmt21t, // op vAA, +BBBB
51 kFmt21s, // op vAA, #+BBBB
52 kFmt21h, // op vAA, #+BBBB00000[00000000]
53 kFmt21c, // op vAA, thing@BBBB
54 kFmt23x, // op vAA, vBB, vCC
55 kFmt22b, // op vAA, vBB, #+CC
56 kFmt22t, // op vA, vB, +CCCC
57 kFmt22s, // op vA, vB, #+CCCC
58 kFmt22c, // op vA, vB, thing@CCCC
59 kFmt22cs, // [opt] op vA, vB, field offset CCCC
60 kFmt30t, // op +AAAAAAAA
61 kFmt32x, // op vAAAA, vBBBB
62 kFmt31i, // op vAA, #+BBBBBBBB
63 kFmt31t, // op vAA, +BBBBBBBB
64 kFmt31c, // op vAA, string@BBBBBBBB
65 kFmt35c, // op {vC,vD,vE,vF,vG}, thing@BBBB
66 kFmt35ms, // [opt] invoke-virtual+super
67 kFmt3rc, // op {vCCCC .. v(CCCC+AA-1)}, thing@BBBB
68 kFmt3rms, // [opt] invoke-virtual+super/range
69 kFmt51l, // op vAA, #+BBBBBBBBBBBBBBBB
70 kFmt35mi, // [opt] inline invoke
71 kFmt3rmi, // [opt] inline invoke/range
72 kFmt33x, // exop vAA, vBB, vCCCC
73 kFmt32s, // exop vAA, vBB, #+CCCC
74 kFmt41c, // exop vAAAA, thing@BBBBBBBB
75 kFmt52c, // exop vAAAA, vBBBB, thing@CCCCCCCC
76 kFmt5rc, // exop {vCCCC .. v(CCCC+AAAA-1)}, thing@BBBBBBBB
80 * Different kinds of indexed reference, for formats that include such an
81 * indexed reference (e.g., 21c and 35c)
83 typedef unsigned char InstructionIndexType;
84 enum InstructionIndexType {
86 kIndexNone, // has no index
87 kIndexVaries, // "It depends." Used for throw-verification-error
88 kIndexClassRef, // class reference index
89 kIndexStringRef, // string reference index
90 kIndexMethodRef, // method reference index
91 kIndexFieldRef, // field reference index
92 kIndexInlineMethod, // inline method index (for inline linked methods)
93 kIndexVtableOffset, // vtable offset (for static linked methods)
94 kIndexFieldOffset // field offset (for static linked fields)
98 * Holds the contents of a decoded instruction.
100 typedef struct DecodedInstruction {
103 u8 vB_wide; /* for kFmt51l */
105 u4 arg[5]; /* vC/D/E/F/G in invoke or filled-new-array */
107 InstructionIndexType indexType;
108 } DecodedInstruction;
111 * Instruction width, a value in the range -3 to 5.
113 typedef signed char InstructionWidth;
116 * Instruction flags, used by the verifier and JIT to determine where
117 * control can flow to next. Expected to fit in 8 bits.
119 typedef unsigned char InstructionFlags;
120 enum InstructionFlags {
121 kInstrCanBranch = 1, // conditional or unconditional branch
122 kInstrCanContinue = 1 << 1, // flow can continue to next statement
123 kInstrCanSwitch = 1 << 2, // switch statement
124 kInstrCanThrow = 1 << 3, // could cause an exception to be thrown
125 kInstrCanReturn = 1 << 4, // returns, no additional statements
126 kInstrInvoke = 1 << 5, // a flavor of invoke
127 kInstrUnconditional = 1 << 6, // unconditional branch
131 * Struct that includes a pointer to each of the instruction information
134 typedef struct InstructionInfoTables {
135 InstructionFormat* formats;
136 InstructionIndexType* indexTypes;
137 InstructionFlags* flags;
138 InstructionWidth* widths;
139 } InstructionInfoTables;
142 * Allocate and populate a 256-element array with instruction widths. A
143 * width of zero means the entry does not exist.
145 InstructionWidth* dexCreateInstrWidthTable(void);
148 * Return the width of the specified instruction, or 0 if not defined.
150 DEX_INLINE size_t dexGetInstrWidthAbs(const InstructionWidth* widths,
153 //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
155 int val = widths[opCode];
158 /* XXX - the no-compare trick may be a cycle slower on ARM */
163 * Return the width of the specified instruction, or 0 if not defined. Also
164 * works for special OP_NOP entries, including switch statement data tables
167 size_t dexGetInstrOrTableWidthAbs(const InstructionWidth* widths,
171 * Allocate and populate a 256-element array with instruction flags.
173 InstructionFlags* dexCreateInstrFlagsTable(void);
176 * Returns the flags for the specified opcode.
178 DEX_INLINE int dexGetInstrFlags(const InstructionFlags* flags, OpCode opCode)
180 //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
181 return flags[opCode];
185 * Allocate and populate a 256-element array with instruction formats.
187 InstructionFormat* dexCreateInstrFormatTable(void);
190 * Return the instruction format for the specified opcode.
192 DEX_INLINE InstructionFormat dexGetInstrFormat(const InstructionFormat* fmts,
195 //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
200 * Allocate and populate an array with index types for all instructions.
201 * Used in conjunction with dexDecodeInstruction.
203 InstructionIndexType* dexCreateInstrIndexTypeTable(void);
206 * Return the instruction index type for the specified opcode.
208 DEX_INLINE InstructionIndexType dexGetInstrIndexType(
209 const InstructionIndexType* types, OpCode opCode)
211 //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
212 return types[opCode];
216 * Construct all of the instruction info tables, storing references to
217 * them into the given struct. This returns 0 on success or non-zero on
218 * failure. If this fails, then no net allocation will have occurred.
220 int dexCreateInstructionInfoTables(InstructionInfoTables* info);
223 * Free up the tables referred to by the given instruction info struct.
225 void dexFreeInstructionInfoTables(InstructionInfoTables* info);
228 * Decode the instruction pointed to by "insns".
230 void dexDecodeInstruction(const InstructionInfoTables* info, const u2* insns,
231 DecodedInstruction* pDec);
233 #endif /*_LIBDEX_INSTRUTILS*/