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
38 typedef unsigned char InstructionFormat;
39 enum InstructionFormat {
43 kFmt11n, // op vA, #+B
46 kFmt20bc, // op AA, thing@BBBB
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
76 * Holds the contents of a decoded instruction.
78 typedef struct DecodedInstruction {
81 u8 vB_wide; /* for kFmt51l */
83 u4 arg[5]; /* vC/D/E/F/G in invoke or filled-new-array */
88 * Instruction width, a value in the range -3 to 5.
90 typedef signed char InstructionWidth;
93 * Instruction flags, used by the verifier and JIT to determine where
94 * control can flow to next. Expected to fit in 8 bits.
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
109 * Allocate and populate a 256-element array with instruction widths. A
110 * width of zero means the entry does not exist.
112 InstructionWidth* dexCreateInstrWidthTable(void);
114 #if 0 // no longer used
116 * Returns the width of the specified instruction, or 0 if not defined.
117 * Optimized instructions use negative values.
119 DEX_INLINE int dexGetInstrWidth(const InstructionWidth* widths, OpCode opCode)
121 // assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
122 return widths[opCode];
127 * Return the width of the specified instruction, or 0 if not defined.
129 DEX_INLINE int dexGetInstrWidthAbs(const InstructionWidth* widths,OpCode opCode)
131 //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
133 int val = widths[opCode];
136 /* XXX - the no-compare trick may be a cycle slower on ARM */
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
145 int dexGetInstrOrTableWidthAbs(const InstructionWidth* widths, const u2* insns);
149 * Allocate and populate a 256-element array with instruction flags.
151 InstructionFlags* dexCreateInstrFlagsTable(void);
154 * Returns the flags for the specified opcode.
156 DEX_INLINE int dexGetInstrFlags(const InstructionFlags* flags, OpCode opCode)
158 //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
159 return flags[opCode];
164 * Allocate and populate a 256-element array with instruction formats.
166 InstructionFormat* dexCreateInstrFormatTable(void);
169 * Return the instruction format for the specified opcode.
171 DEX_INLINE InstructionFormat dexGetInstrFormat(const InstructionFormat* fmts,
174 //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
179 * Decode the instruction pointed to by "insns".
181 void dexDecodeInstruction(const InstructionFormat* fmts, const u2* insns,
182 DecodedInstruction* pDec);
184 #endif /*_LIBDEX_INSTRUTILS*/