OSDN Git Service

Add the new instruction formats.
[android-x86/dalvik.git] / libdex / InstrUtils.h
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 /*
18  * Dalvik instruction utility functions.
19  */
20 #ifndef _LIBDEX_INSTRUTILS
21 #define _LIBDEX_INSTRUTILS
22
23 #include "DexFile.h"
24 #include "OpCode.h"
25
26 /*
27  * Dalvik-defined instruction formats.
28  *
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.)
32  *
33  * If you add or delete a format, you have to change some or all of:
34  *  - this enum
35  *  - the switch inside dexDecodeInstruction() in InstrUtils.c
36  *  - the switch inside dumpInstruction() in DexDump.c
37  *  - the switch inside dvmCompilerMIR2LIR() in CodegenDriver.c
38  */
39 typedef unsigned char InstructionFormat;
40 enum InstructionFormat {
41     kFmtUnknown = 0,
42     kFmt10x,        // op
43     kFmt12x,        // op vA, vB
44     kFmt11n,        // op vA, #+B
45     kFmt11x,        // op vAA
46     kFmt10t,        // op +AA
47     kFmt20bc,       // [opt] op AA, thing@BBBB
48     kFmt20t,        // op +AAAA
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
77 };
78
79 /*
80  * Different kinds of indexed reference, for formats that include such an
81  * indexed reference (e.g., 21c and 35c)
82  */
83 typedef unsigned char InstructionIndexType;
84 enum InstructionIndexType {
85     kIndexUnknown = 0,
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)
95 };
96
97 /*
98  * Holds the contents of a decoded instruction.
99  */
100 typedef struct DecodedInstruction {
101     u4      vA;
102     u4      vB;
103     u8      vB_wide;        /* for kFmt51l */
104     u4      vC;
105     u4      arg[5];         /* vC/D/E/F/G in invoke or filled-new-array */
106     OpCode  opCode;
107     InstructionIndexType indexType;
108 } DecodedInstruction;
109
110 /*
111  * Instruction width, a value in the range -3 to 5.
112  */
113 typedef signed char InstructionWidth;
114
115 /*
116  * Instruction flags, used by the verifier and JIT to determine where
117  * control can flow to next.  Expected to fit in 8 bits.
118  */
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
128 };
129
130 /*
131  * Struct that includes a pointer to each of the instruction information
132  * tables.
133  */
134 typedef struct InstructionInfoTables {
135     InstructionFormat*    formats;
136     InstructionIndexType* indexTypes;
137     InstructionFlags*     flags;
138     InstructionWidth*     widths;
139 } InstructionInfoTables;
140
141 /*
142  * Allocate and populate a 256-element array with instruction widths.  A
143  * width of zero means the entry does not exist.
144  */
145 InstructionWidth* dexCreateInstrWidthTable(void);
146
147 /*
148  * Return the width of the specified instruction, or 0 if not defined.
149  */
150 DEX_INLINE size_t dexGetInstrWidthAbs(const InstructionWidth* widths,
151     OpCode opCode)
152 {
153     //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
154
155     int val = widths[opCode];
156     if (val < 0)
157         val = -val;
158     /* XXX - the no-compare trick may be a cycle slower on ARM */
159     return val;
160 }
161
162 /*
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
165  * and array data.
166  */
167 size_t dexGetInstrOrTableWidthAbs(const InstructionWidth* widths,
168     const u2* insns);
169
170 /*
171  * Allocate and populate a 256-element array with instruction flags.
172  */
173 InstructionFlags* dexCreateInstrFlagsTable(void);
174
175 /*
176  * Returns the flags for the specified opcode.
177  */
178 DEX_INLINE int dexGetInstrFlags(const InstructionFlags* flags, OpCode opCode)
179 {
180     //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
181     return flags[opCode];
182 }
183
184 /*
185  * Allocate and populate a 256-element array with instruction formats.
186  */
187 InstructionFormat* dexCreateInstrFormatTable(void);
188
189 /*
190  * Return the instruction format for the specified opcode.
191  */
192 DEX_INLINE InstructionFormat dexGetInstrFormat(const InstructionFormat* fmts,
193     OpCode opCode)
194 {
195     //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
196     return fmts[opCode];
197 }
198
199 /*
200  * Allocate and populate an array with index types for all instructions.
201  * Used in conjunction with dexDecodeInstruction.
202  */
203 InstructionIndexType* dexCreateInstrIndexTypeTable(void);
204
205 /*
206  * Return the instruction index type for the specified opcode.
207  */
208 DEX_INLINE InstructionIndexType dexGetInstrIndexType(
209     const InstructionIndexType* types, OpCode opCode)
210 {
211     //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
212     return types[opCode];
213 }
214
215 /*
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.
219  */
220 int dexCreateInstructionInfoTables(InstructionInfoTables* info);
221
222 /*
223  * Free up the tables referred to by the given instruction info struct.
224  */
225 void dexFreeInstructionInfoTables(InstructionInfoTables* info);
226
227 /*
228  * Decode the instruction pointed to by "insns".
229  */
230 void dexDecodeInstruction(const InstructionInfoTables* info, const u2* insns,
231     DecodedInstruction* pDec);
232
233 #endif /*_LIBDEX_INSTRUTILS*/