OSDN Git Service

am 41c2b663: am 805800d7: Merge "Up the version to 1.3.0." into kraken
[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  */
38 typedef unsigned char InstructionFormat;
39 enum InstructionFormat {
40     kFmtUnknown = 0,
41     kFmt10x,        // op
42     kFmt12x,        // op vA, vB
43     kFmt11n,        // op vA, #+B
44     kFmt11x,        // op vAA
45     kFmt10t,        // op +AA
46     kFmt20bc,       // op AA, thing@BBBB
47     kFmt20t,        // op +AAAA
48     kFmt22x,        // op vAA, vBBBB
49     kFmt21t,        // op vAA, +BBBB
50     kFmt21s,        // op vAA, #+BBBB
51     kFmt21h,        // op vAA, #+BBBB00000[00000000]
52     kFmt21c,        // op vAA, thing@BBBB
53     kFmt23x,        // op vAA, vBB, vCC
54     kFmt22b,        // op vAA, vBB, #+CC
55     kFmt22t,        // op vA, vB, +CCCC
56     kFmt22s,        // op vA, vB, #+CCCC
57     kFmt22c,        // op vA, vB, thing@CCCC
58     kFmt22cs,       // [opt] op vA, vB, field offset CCCC
59     kFmt32x,        // op vAAAA, vBBBB
60     kFmt30t,        // op +AAAAAAAA
61     kFmt31t,        // op vAA, +BBBBBBBB
62     kFmt31i,        // op vAA, #+BBBBBBBB
63     kFmt31c,        // op vAA, thing@BBBBBBBB
64     kFmt35c,        // op {vC, vD, vE, vF, vG}, thing@BBBB (B: count, A: vG)
65     kFmt35ms,       // [opt] invoke-virtual+super
66     kFmt35fs,       // [opt] invoke-interface
67     kFmt3rc,        // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
68     kFmt3rms,       // [opt] invoke-virtual+super/range
69     kFmt3rfs,       // [opt] invoke-interface/range
70     kFmt3inline,    // [opt] inline invoke
71     kFmt3rinline,   // [opt] inline invoke/range
72     kFmt51l,        // op vAA, #+BBBBBBBBBBBBBBBB
73 };
74
75 /*
76  * Holds the contents of a decoded instruction.
77  */
78 typedef struct DecodedInstruction {
79     u4      vA;
80     u4      vB;
81     u8      vB_wide;        /* for kFmt51l */
82     u4      vC;
83     u4      arg[5];         /* vC/D/E/F/G in invoke or filled-new-array */
84     OpCode  opCode;
85 } DecodedInstruction;
86
87 /*
88  * Instruction width, a value in the range -3 to 5.
89  */
90 typedef signed char InstructionWidth;
91
92 /*
93  * Instruction flags, used by the verifier and JIT to determine where
94  * control can flow to next.  Expected to fit in 8 bits.
95  */
96 typedef unsigned char InstructionFlags;
97 enum InstructionFlags {
98     kInstrCanBranch     = 1,        // conditional or unconditional branch
99     kInstrCanContinue   = 1 << 1,   // flow can continue to next statement
100     kInstrCanSwitch     = 1 << 2,   // switch statement
101     kInstrCanThrow      = 1 << 3,   // could cause an exception to be thrown
102     kInstrCanReturn     = 1 << 4,   // returns, no additional statements
103     kInstrInvoke        = 1 << 5,   // a flavor of invoke
104     kInstrUnconditional = 1 << 6,   // unconditional branch
105 };
106
107
108 /*
109  * Allocate and populate a 256-element array with instruction widths.  A
110  * width of zero means the entry does not exist.
111  */
112 InstructionWidth* dexCreateInstrWidthTable(void);
113
114 #if 0       // no longer used
115 /*
116  * Returns the width of the specified instruction, or 0 if not defined.
117  * Optimized instructions use negative values.
118  */
119 DEX_INLINE int dexGetInstrWidth(const InstructionWidth* widths, OpCode opCode)
120 {
121    // assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
122     return widths[opCode];
123 }
124 #endif
125
126 /*
127  * Return the width of the specified instruction, or 0 if not defined.
128  */
129 DEX_INLINE int dexGetInstrWidthAbs(const InstructionWidth* widths,OpCode opCode)
130 {
131     //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
132
133     int val = widths[opCode];
134     if (val < 0)
135         val = -val;
136     /* XXX - the no-compare trick may be a cycle slower on ARM */
137     return val;
138 }
139
140 /*
141  * Return the width of the specified instruction, or 0 if not defined.  Also
142  * works for special OP_NOP entries, including switch statement data tables
143  * and array data.
144  */
145 int dexGetInstrOrTableWidthAbs(const InstructionWidth* widths, const u2* insns);
146
147
148 /*
149  * Allocate and populate a 256-element array with instruction flags.
150  */
151 InstructionFlags* dexCreateInstrFlagsTable(void);
152
153 /*
154  * Returns the flags for the specified opcode.
155  */
156 DEX_INLINE int dexGetInstrFlags(const InstructionFlags* flags, OpCode opCode)
157 {
158     //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
159     return flags[opCode];
160 }
161
162
163 /*
164  * Allocate and populate a 256-element array with instruction formats.
165  */
166 InstructionFormat* dexCreateInstrFormatTable(void);
167
168 /*
169  * Return the instruction format for the specified opcode.
170  */
171 DEX_INLINE InstructionFormat dexGetInstrFormat(const InstructionFormat* fmts,
172     OpCode opCode)
173 {
174     //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
175     return fmts[opCode];
176 }
177
178 /*
179  * Decode the instruction pointed to by "insns".
180  */
181 void dexDecodeInstruction(const InstructionFormat* fmts, const u2* insns,
182     DecodedInstruction* pDec);
183
184 #endif /*_LIBDEX_INSTRUTILS*/